Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt93
-rw-r--r--build_files/cmake/config/blender_lite.cmake1
-rw-r--r--build_files/cmake/macros.cmake47
-rw-r--r--build_files/scons/tools/Blender.py4
-rw-r--r--build_files/scons/tools/btools.py2
-rw-r--r--doc/python_api/examples/bpy.app.handlers.1.py2
-rw-r--r--doc/python_api/examples/bpy.app.handlers.py5
-rw-r--r--extern/CMakeLists.txt4
-rw-r--r--extern/SConscript3
-rw-r--r--extern/libmv/CMakeLists.txt215
-rw-r--r--extern/libmv/ChangeLog312
-rw-r--r--extern/libmv/SConscript62
-rwxr-xr-xextern/libmv/bundle.sh263
-rw-r--r--extern/libmv/files.txt141
-rw-r--r--extern/libmv/libmv-capi.cpp770
-rw-r--r--extern/libmv/libmv-capi.h128
-rw-r--r--extern/libmv/libmv/base/id_generator.h37
-rw-r--r--extern/libmv/libmv/base/scoped_ptr.h60
-rw-r--r--extern/libmv/libmv/base/vector.h172
-rw-r--r--extern/libmv/libmv/base/vector_utils.h34
-rw-r--r--extern/libmv/libmv/image/array_nd.cc108
-rw-r--r--extern/libmv/libmv/image/array_nd.h473
-rw-r--r--extern/libmv/libmv/image/convolve.cc305
-rw-r--r--extern/libmv/libmv/image/convolve.h93
-rw-r--r--extern/libmv/libmv/image/image.h158
-rw-r--r--extern/libmv/libmv/image/sample.h103
-rw-r--r--extern/libmv/libmv/image/tuple.h90
-rw-r--r--extern/libmv/libmv/logging/logging.h31
-rw-r--r--extern/libmv/libmv/multiview/conditioning.cc99
-rw-r--r--extern/libmv/libmv/multiview/conditioning.h60
-rw-r--r--extern/libmv/libmv/multiview/euclidean_resection.cc663
-rw-r--r--extern/libmv/libmv/multiview/euclidean_resection.h124
-rw-r--r--extern/libmv/libmv/multiview/fundamental.cc391
-rw-r--r--extern/libmv/libmv/multiview/fundamental.h144
-rw-r--r--extern/libmv/libmv/multiview/nviewtriangulation.h80
-rw-r--r--extern/libmv/libmv/multiview/projection.cc221
-rw-r--r--extern/libmv/libmv/multiview/projection.h231
-rw-r--r--extern/libmv/libmv/multiview/resection.h62
-rw-r--r--extern/libmv/libmv/multiview/triangulation.cc49
-rw-r--r--extern/libmv/libmv/multiview/triangulation.h38
-rw-r--r--extern/libmv/libmv/numeric/dogleg.h261
-rw-r--r--extern/libmv/libmv/numeric/function_derivative.h107
-rw-r--r--extern/libmv/libmv/numeric/levenberg_marquardt.h183
-rw-r--r--extern/libmv/libmv/numeric/numeric.cc136
-rw-r--r--extern/libmv/libmv/numeric/numeric.h479
-rw-r--r--extern/libmv/libmv/numeric/poly.cc23
-rw-r--r--extern/libmv/libmv/numeric/poly.h123
-rw-r--r--extern/libmv/libmv/simple_pipeline/bundle.cc184
-rw-r--r--extern/libmv/libmv/simple_pipeline/bundle.h72
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc351
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.h152
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.cc184
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.h95
-rw-r--r--extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc218
-rw-r--r--extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h74
-rw-r--r--extern/libmv/libmv/simple_pipeline/intersect.cc205
-rw-r--r--extern/libmv/libmv/simple_pipeline/intersect.h77
-rw-r--r--extern/libmv/libmv/simple_pipeline/pipeline.cc317
-rw-r--r--extern/libmv/libmv/simple_pipeline/pipeline.h95
-rw-r--r--extern/libmv/libmv/simple_pipeline/reconstruction.cc191
-rw-r--r--extern/libmv/libmv/simple_pipeline/reconstruction.h217
-rw-r--r--extern/libmv/libmv/simple_pipeline/resect.cc271
-rw-r--r--extern/libmv/libmv/simple_pipeline/resect.h86
-rw-r--r--extern/libmv/libmv/simple_pipeline/tracks.cc159
-rw-r--r--extern/libmv/libmv/simple_pipeline/tracks.h119
-rw-r--r--extern/libmv/libmv/tracking/klt_region_tracker.cc132
-rw-r--r--extern/libmv/libmv/tracking/klt_region_tracker.h55
-rw-r--r--extern/libmv/libmv/tracking/pyramid_region_tracker.cc80
-rw-r--r--extern/libmv/libmv/tracking/pyramid_region_tracker.h46
-rw-r--r--extern/libmv/libmv/tracking/region_tracker.h48
-rw-r--r--extern/libmv/libmv/tracking/retrack_region_tracker.cc47
-rw-r--r--extern/libmv/libmv/tracking/retrack_region_tracker.h48
-rw-r--r--extern/libmv/libmv/tracking/sad.cc174
-rw-r--r--extern/libmv/libmv/tracking/sad.h109
-rw-r--r--extern/libmv/libmv/tracking/trklt_region_tracker.cc135
-rw-r--r--extern/libmv/libmv/tracking/trklt_region_tracker.h65
-rwxr-xr-xextern/libmv/mkfiles.sh4
-rw-r--r--extern/libmv/patches/bundle_tweaks.patch122
-rw-r--r--extern/libmv/patches/config_mac.patch13
-rw-r--r--extern/libmv/patches/detect.patch181
-rw-r--r--extern/libmv/patches/fast.patch24
-rw-r--r--extern/libmv/patches/function_derivative.patch21
-rw-r--r--extern/libmv/patches/high_distortion_crash_fix.patch21
-rw-r--r--extern/libmv/patches/levenberg_marquardt.patch71
-rw-r--r--extern/libmv/patches/mingw.patch171
-rw-r--r--extern/libmv/patches/msvc2010.patch12
-rw-r--r--extern/libmv/patches/overscan.patch182
-rw-r--r--extern/libmv/patches/scaled_distortion.patch261
-rw-r--r--extern/libmv/patches/series13
-rw-r--r--extern/libmv/patches/snrptinf_fix.patch15
-rw-r--r--extern/libmv/patches/v3d_verbosity.patch12
-rw-r--r--extern/libmv/third_party/fast/LICENSE30
-rw-r--r--extern/libmv/third_party/fast/README31
-rw-r--r--extern/libmv/third_party/fast/README.libmv9
-rw-r--r--extern/libmv/third_party/fast/fast.c71
-rw-r--r--extern/libmv/third_party/fast/fast.h39
-rw-r--r--extern/libmv/third_party/fast/fast_10.c4666
-rw-r--r--extern/libmv/third_party/fast/fast_11.c3910
-rw-r--r--extern/libmv/third_party/fast/fast_12.c3134
-rw-r--r--extern/libmv/third_party/fast/fast_9.c5910
-rw-r--r--extern/libmv/third_party/fast/nonmax.c117
-rw-r--r--extern/libmv/third_party/gflags/README.libmv14
-rw-r--r--extern/libmv/third_party/gflags/config.h110
-rw-r--r--extern/libmv/third_party/gflags/gflags.cc1971
-rw-r--r--extern/libmv/third_party/gflags/gflags.h589
-rw-r--r--extern/libmv/third_party/gflags/gflags_completions.cc765
-rw-r--r--extern/libmv/third_party/gflags/gflags_completions.h121
-rw-r--r--extern/libmv/third_party/gflags/gflags_reporting.cc446
-rw-r--r--extern/libmv/third_party/gflags/mutex.h349
-rw-r--r--extern/libmv/third_party/glog/AUTHORS2
-rw-r--r--extern/libmv/third_party/glog/COPYING65
-rw-r--r--extern/libmv/third_party/glog/ChangeLog59
-rw-r--r--extern/libmv/third_party/glog/NEWS0
-rw-r--r--extern/libmv/third_party/glog/README5
-rw-r--r--extern/libmv/third_party/glog/README.libmv38
-rw-r--r--extern/libmv/third_party/glog/src/base/commandlineflags.h132
-rw-r--r--extern/libmv/third_party/glog/src/base/googleinit.h51
-rw-r--r--extern/libmv/third_party/glog/src/base/mutex.h325
-rw-r--r--extern/libmv/third_party/glog/src/config.h13
-rw-r--r--extern/libmv/third_party/glog/src/config_linux.h164
-rw-r--r--extern/libmv/third_party/glog/src/config_mac.h159
-rw-r--r--extern/libmv/third_party/glog/src/demangle.cc1231
-rw-r--r--extern/libmv/third_party/glog/src/demangle.h84
-rw-r--r--extern/libmv/third_party/glog/src/glog/log_severity.h84
-rw-r--r--extern/libmv/third_party/glog/src/glog/logging.h1507
-rw-r--r--extern/libmv/third_party/glog/src/glog/raw_logging.h185
-rw-r--r--extern/libmv/third_party/glog/src/glog/vlog_is_on.h129
-rw-r--r--extern/libmv/third_party/glog/src/logging.cc1783
-rw-r--r--extern/libmv/third_party/glog/src/raw_logging.cc172
-rw-r--r--extern/libmv/third_party/glog/src/signalhandler.cc348
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace.h60
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace_generic-inl.h59
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h87
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h130
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace_x86-inl.h139
-rw-r--r--extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h105
-rw-r--r--extern/libmv/third_party/glog/src/symbolize.cc681
-rw-r--r--extern/libmv/third_party/glog/src/symbolize.h116
-rw-r--r--extern/libmv/third_party/glog/src/utilities.cc335
-rw-r--r--extern/libmv/third_party/glog/src/utilities.h224
-rw-r--r--extern/libmv/third_party/glog/src/vlog_is_on.cc249
-rw-r--r--extern/libmv/third_party/glog/src/windows/config.h136
-rw-r--r--extern/libmv/third_party/glog/src/windows/glog/log_severity.h88
-rw-r--r--extern/libmv/third_party/glog/src/windows/glog/logging.h1524
-rw-r--r--extern/libmv/third_party/glog/src/windows/glog/raw_logging.h189
-rw-r--r--extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h133
-rw-r--r--extern/libmv/third_party/glog/src/windows/port.cc64
-rw-r--r--extern/libmv/third_party/glog/src/windows/port.h170
-rwxr-xr-xextern/libmv/third_party/glog/src/windows/preprocess.sh118
-rw-r--r--extern/libmv/third_party/ldl/CMakeLists.txt5
-rw-r--r--extern/libmv/third_party/ldl/Doc/ChangeLog39
-rw-r--r--extern/libmv/third_party/ldl/Doc/lesser.txt504
-rw-r--r--extern/libmv/third_party/ldl/Include/ldl.h104
-rw-r--r--extern/libmv/third_party/ldl/README.libmv10
-rw-r--r--extern/libmv/third_party/ldl/README.txt136
-rw-r--r--extern/libmv/third_party/ldl/Source/ldl.c507
-rw-r--r--extern/libmv/third_party/msinttypes/README.libmv5
-rw-r--r--extern/libmv/third_party/msinttypes/inttypes.h305
-rw-r--r--extern/libmv/third_party/msinttypes/stdint.h247
-rw-r--r--extern/libmv/third_party/ssba/COPYING.TXT165
-rw-r--r--extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h204
-rw-r--r--extern/libmv/third_party/ssba/Geometry/v3d_distortion.h97
-rw-r--r--extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp365
-rw-r--r--extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h346
-rw-r--r--extern/libmv/third_party/ssba/Math/v3d_linear.h923
-rw-r--r--extern/libmv/third_party/ssba/Math/v3d_linear_utils.h391
-rw-r--r--extern/libmv/third_party/ssba/Math/v3d_mathutilities.h59
-rw-r--r--extern/libmv/third_party/ssba/Math/v3d_optimization.cpp955
-rw-r--r--extern/libmv/third_party/ssba/Math/v3d_optimization.h273
-rw-r--r--extern/libmv/third_party/ssba/README.TXT92
-rwxr-xr-xextern/libmv/third_party/ssba/README.libmv23
-rw-r--r--release/datafiles/blender_icons.pngbin214916 -> 216116 bytes
-rw-r--r--release/scripts/modules/bpy/ops.py4
-rw-r--r--release/scripts/modules/bpy_extras/keyconfig_utils.py4
-rw-r--r--release/scripts/modules/bpyml_ui.py6
-rw-r--r--release/scripts/presets/tracking_camera/Blender.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_1100D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_1D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_1DS.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_500D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_550D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_5D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_600D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_60D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Canon_7D.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D300S.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D3100.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D35.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D5000.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D5100.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D7000.py10
-rw-r--r--release/scripts/presets/tracking_camera/Nikon_D90.py10
-rw-r--r--release/scripts/presets/tracking_camera/Red_Epic.py10
-rw-r--r--release/scripts/presets/tracking_camera/Red_One_2K.py10
-rw-r--r--release/scripts/presets/tracking_camera/Red_One_3K.py10
-rw-r--r--release/scripts/presets/tracking_camera/Red_One_4K.py10
-rw-r--r--release/scripts/presets/tracking_track_color/default.py5
-rw-r--r--release/scripts/presets/tracking_track_color/far_plane.py5
-rw-r--r--release/scripts/presets/tracking_track_color/near_plane.py5
-rw-r--r--release/scripts/startup/bl_operators/__init__.py1
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py3
-rw-r--r--release/scripts/startup/bl_operators/presets.py41
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py18
-rw-r--r--release/scripts/startup/bl_ui/__init__.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lamp.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py20
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py1
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py2
-rw-r--r--release/scripts/startup/bl_ui/space_image.py14
-rw-r--r--release/scripts/startup/bl_ui/space_time.py1
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py8
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py8
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py48
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py14
-rw-r--r--source/blender/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h3
-rw-r--r--source/blender/blenkernel/BKE_library.h2
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h70
-rw-r--r--source/blender/blenkernel/BKE_node.h7
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/BKE_texture.h7
-rw-r--r--source/blender/blenkernel/BKE_tracking.h145
-rw-r--r--source/blender/blenkernel/CMakeLists.txt11
-rw-r--r--source/blender/blenkernel/SConscript4
-rw-r--r--source/blender/blenkernel/intern/armature.c35
-rw-r--r--source/blender/blenkernel/intern/constraint.c208
-rw-r--r--source/blender/blenkernel/intern/context.c12
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c82
-rw-r--r--source/blender/blenkernel/intern/idcode.c1
-rw-r--r--source/blender/blenkernel/intern/library.c11
-rw-r--r--source/blender/blenkernel/intern/movieclip.c1026
-rw-r--r--source/blender/blenkernel/intern/node.c4
-rw-r--r--source/blender/blenkernel/intern/object.c84
-rw-r--r--source/blender/blenkernel/intern/texture.c94
-rw-r--r--source/blender/blenkernel/intern/tracking.c2206
-rw-r--r--source/blender/blenlib/BLI_threads.h3
-rw-r--r--source/blender/blenlib/intern/bpath.c2
-rw-r--r--source/blender/blenlib/intern/threads.c11
-rw-r--r--source/blender/blenloader/intern/readblenentry.c6
-rw-r--r--source/blender/blenloader/intern/readfile.c233
-rw-r--r--source/blender/blenloader/intern/readfile.h3
-rw-r--r--source/blender/blenloader/intern/writefile.c39
-rw-r--r--source/blender/editors/CMakeLists.txt1
-rw-r--r--source/blender/editors/SConscript1
-rw-r--r--source/blender/editors/datafiles/blender_icons.png.c13473
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c3
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c56
-rw-r--r--source/blender/editors/include/ED_clip.h64
-rw-r--r--source/blender/editors/include/ED_space_api.h1
-rw-r--r--source/blender/editors/include/ED_transform.h1
-rw-r--r--source/blender/editors/include/ED_view3d.h2
-rw-r--r--source/blender/editors/include/UI_icons.h6
-rw-r--r--source/blender/editors/include/UI_interface.h46
-rw-r--r--source/blender/editors/include/UI_resources.h13
-rw-r--r--source/blender/editors/interface/interface_draw.c109
-rw-r--r--source/blender/editors/interface/interface_handlers.c98
-rw-r--r--source/blender/editors/interface/interface_intern.h7
-rw-r--r--source/blender/editors/interface/interface_regions.c9
-rw-r--r--source/blender/editors/interface/interface_templates.c8
-rw-r--r--source/blender/editors/interface/interface_widgets.c46
-rw-r--r--source/blender/editors/interface/resources.c75
-rw-r--r--source/blender/editors/object/object_constraint.c20
-rw-r--r--source/blender/editors/screen/area.c1
-rw-r--r--source/blender/editors/screen/screen_edit.c3
-rw-r--r--source/blender/editors/screen/screen_ops.c15
-rw-r--r--source/blender/editors/space_api/spacetypes.c3
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c5
-rw-r--r--source/blender/editors/space_clip/CMakeLists.txt56
-rw-r--r--source/blender/editors/space_clip/SConscript9
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c436
-rw-r--r--source/blender/editors/space_clip/clip_draw.c1325
-rw-r--r--source/blender/editors/space_clip/clip_editor.c310
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c255
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c356
-rw-r--r--source/blender/editors/space_clip/clip_intern.h144
-rw-r--r--source/blender/editors/space_clip/clip_ops.c1004
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c244
-rw-r--r--source/blender/editors/space_clip/clip_utils.c219
-rw-r--r--source/blender/editors/space_clip/space_clip.c949
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c2941
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_node/drawnode.c75
-rw-r--r--source/blender/editors/space_node/node_buttons.c37
-rw-r--r--source/blender/editors/space_node/node_draw.c5
-rw-r--r--source/blender/editors/space_node/node_edit.c8
-rw-r--r--source/blender/editors/space_node/node_header.c48
-rw-r--r--source/blender/editors/space_node/node_templates.c636
-rw-r--r--source/blender/editors/space_view3d/drawobject.c234
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c62
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c32
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c45
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c41
-rw-r--r--source/blender/editors/transform/transform.c46
-rw-r--r--source/blender/editors/transform/transform.h4
-rw-r--r--source/blender/editors/transform/transform_conversions.c246
-rw-r--r--source/blender/editors/transform/transform_generics.c45
-rw-r--r--source/blender/editors/transform/transform_ops.c5
-rw-r--r--source/blender/editors/util/CMakeLists.txt1
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c6
-rw-r--r--source/blender/makesdna/DNA_ID.h1
-rw-r--r--source/blender/makesdna/DNA_action_types.h4
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h29
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h3
-rw-r--r--source/blender/makesdna/DNA_movieclip_types.h126
-rw-r--r--source/blender/makesdna/DNA_scene_types.h5
-rw-r--r--source/blender/makesdna/DNA_space_types.h60
-rw-r--r--source/blender/makesdna/DNA_texture_types.h22
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h217
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h6
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h23
-rw-r--r--source/blender/makesdna/intern/makesdna.c4
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt2
-rw-r--r--source/blender/makesrna/intern/makesrna.c2
-rw-r--r--source/blender/makesrna/intern/rna_ID.c2
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c72
-rw-r--r--source/blender/makesrna/intern/rna_internal.h3
-rw-r--r--source/blender/makesrna/intern/rna_main.c7
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c54
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c278
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c133
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c27
-rw-r--r--source/blender/makesrna/intern/rna_screen.c5
-rw-r--r--source/blender/makesrna/intern/rna_space.c308
-rw-r--r--source/blender/makesrna/intern/rna_texture.c176
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c764
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c42
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c109
-rw-r--r--source/blender/nodes/CMakeLists.txt4
-rw-r--r--source/blender/nodes/NOD_composite.h4
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c31
-rw-r--r--source/blender/nodes/composite/node_composite_util.h10
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c51
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mapValue.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_movieclip.c157
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_moviedistortion.c135
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_normalize.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_scale.c21
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_stabilize2d.c79
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_transform.c142
-rw-r--r--source/blender/nodes/intern/node_socket.c2
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c20
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c2
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c14
-rw-r--r--source/blender/windowmanager/WM_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c2
-rw-r--r--source/blenderplayer/CMakeLists.txt6
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c8
-rw-r--r--source/creator/CMakeLists.txt22
-rw-r--r--source/creator/creator.c12
367 files changed, 76304 insertions, 7115 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c48c8936240..dd3781f41e5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -202,6 +202,9 @@ option(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF)
option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON)
option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON)
+# Camera/motion tracking
+option(WITH_LIBMV "Enable libmv structure from motion library" 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)
@@ -488,6 +491,36 @@ if(UNIX AND NOT APPLE)
endif()
endif()
+ if(WITH_BOOST)
+ set(BOOST "/usr" CACHE PATH "Boost Directory")
+
+ if(NOT BOOST_CUSTOM)
+ set(BOOST_ROOT ${BOOST})
+ set(Boost_USE_MULTITHREADED ON)
+ find_package(Boost 1.34 REQUIRED COMPONENTS filesystem regex system thread)
+ endif()
+
+ set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
+ set(BOOST_LIBRARIES ${Boost_LIBRARIES})
+ set(BOOST_LIBPATH ${Boost_LIBRARY_DIRS})
+ set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+ endif()
+
+ if(WITH_OPENIMAGEIO)
+ set(OPENIMAGEIO "/usr" CACHE PATH "OpenImageIO Directory")
+
+ set(OPENIMAGEIO_ROOT_DIR ${OPENIMAGEIO})
+ find_package(OpenImageIO REQUIRED)
+
+ set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES} ${BOOST_LIBRARIES})
+ set(OPENIMAGEIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
+ set(OPENIMAGEIO_DEFINITIONS)
+
+ if(NOT OPENIMAGEIO_FOUND)
+ set(WITH_OPENIMAGEIO OFF)
+ endif()
+ endif()
+
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
@@ -774,6 +807,28 @@ elseif(WIN32)
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
endif()
+ if(WITH_BOOST)
+ set(BOOST ${LIBDIR}/boost)
+ set(BOOST_INCLUDE_DIR ${BOOST}/include)
+ set(BOOST_POSTFIX "vc90-mt-s-1_47.lib")
+ set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_47.lib")
+ set(BOOST_LIBRARIES
+ optimized libboost_date_time-${BOOST_POSTFIX} libboost_filesystem-${BOOST_POSTFIX}
+ libboost_regex-${BOOST_POSTFIX} libboost_system-${BOOST_POSTFIX} libboost_thread-${BOOST_POSTFIX}
+ debug libboost_date_time-${BOOST_DEBUG_POSTFIX} libboost_filesystem-${BOOST_DEBUG_POSTFIX}
+ libboost_regex-${BOOST_DEBUG_POSTFIX} libboost_system-${BOOST_DEBUG_POSTFIX} libboost_thread-${BOOST_DEBUG_POSTFIX})
+ set(BOOST_LIBPATH ${BOOST}/lib)
+ set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+ endif()
+
+ if(WITH_OPENIMAGEIO)
+ set(OPENIMAGEIO ${LIBDIR}/openimageio)
+ set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+ set(OPENIMAGEIO_LIBRARIES OpenImageIO)
+ set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
+ set(OPENIMAGEIO_DEFINITIONS)
+ endif()
+
set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
# MSVC only, Mingw doesnt need
@@ -884,6 +939,28 @@ elseif(WIN32)
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
endif()
+ if(WITH_BOOST)
+ set(BOOST ${LIBDIR}/boost)
+ set(BOOST_INCLUDE_DIR ${BOOST}/include)
+ set(BOOST_POSTFIX "vc90-mt-s-1_46_1")
+ set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_46_1")
+ set(BOOST_LIBRARIES
+ optimized libboost_date_time-${BOOST_POSTFIX} libboost_filesystem-${BOOST_POSTFIX}
+ libboost_regex-${BOOST_POSTFIX} libboost_system-${BOOST_POSTFIX} libboost_thread-${BOOST_POSTFIX}
+ debug libboost_date_time-${BOOST_DEBUG_POSTFIX} libboost_filesystem-${BOOST_DEBUG_POSTFIX}
+ libboost_regex-${BOOST_DEBUG_POSTFIX} libboost_system-${BOOST_DEBUG_POSTFIX} libboost_thread-${BOOST_DEBUG_POSTFIX})
+ set(BOOST_LIBPATH ${BOOST}/lib)
+ set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+ endif()
+
+ if(WITH_OPENIMAGEIO)
+ set(OPENIMAGEIO ${LIBDIR}/openimageio)
+ set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+ set(OPENIMAGEIO_LIBRARIES OpenImageIO)
+ set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
+ set(OPENIMAGEIO_DEFINITIONS)
+ endif()
+
set(PLATFORM_LINKFLAGS "--stack,2097152")
endif()
@@ -1087,6 +1164,22 @@ elseif(APPLE)
# linker needs "-weak_framework 3DconnexionClient"
endif()
+ if(WITH_BOOST)
+ set(BOOST ${LIBDIR}/boost)
+ set(BOOST_INCLUDE_DIR ${BOOST}/include)
+ set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt)
+ set(BOOST_LIBPATH ${BOOST}/lib)
+ set(BOOST_DEFINITIONS)
+ endif()
+
+ if(WITH_OPENIMAGEIO)
+ set(OPENIMAGEIO ${LIBDIR}/openimageio)
+ set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+ set(OPENIMAGEIO_LIBRARIES OpenImageIO ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES})
+ set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib ${JPEG_LIBPATH} ${PNG_LIBPATH} ${TIFF_LIBPATH} ${OPENEXR_LIBPATH} ${ZLIB_LIBPATH})
+ set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD")
+ endif()
+
set(EXETYPE MACOSX_BUNDLE)
set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index 6791028a888..0da28a943eb 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -13,6 +13,7 @@ set(WITH_BULLET OFF CACHE FORCE BOOL)
set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
set(WITH_FFTW3 OFF CACHE FORCE BOOL)
+set(WITH_LIBMV 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)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 10f89797754..c9a04f87148 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -165,6 +165,12 @@ macro(SETUP_LIBDIRS)
if(WITH_IMAGE_TIFF)
link_directories(${TIFF_LIBPATH})
endif()
+ if(WITH_BOOST)
+ link_directories(${BOOST_LIBPATH})
+ endif()
+ if(WITH_OPENIMAGEIO)
+ link_directories(${OPENIMAGEIO_LIBPATH})
+ endif()
if(WITH_IMAGE_OPENJPEG AND UNIX AND NOT APPLE)
link_directories(${OPENJPEG_LIBPATH})
endif()
@@ -259,6 +265,12 @@ macro(setup_liblinks
if(WITH_IMAGE_TIFF)
target_link_libraries(${target} ${TIFF_LIBRARY})
endif()
+ if(WITH_OPENIMAGEIO)
+ target_link_libraries(${target} ${OPENIMAGEIO_LIBRARIES})
+ endif()
+ if(WITH_BOOST)
+ target_link_libraries(${target} ${BOOST_LIBRARIES})
+ endif()
if(WITH_IMAGE_OPENEXR)
if(WIN32 AND NOT UNIX)
file_list_suffix(OPENEXR_LIBRARIES_DEBUG "${OPENEXR_LIBRARIES}" "_d")
@@ -618,3 +630,38 @@ macro(blender_project_hack_post)
endif()
endmacro()
+
+# pair of macros to allow libraries to be specify files to install, but to
+# only install them at the end so the directories don't get cleared with
+# the files in them. used by cycles to install addon.
+macro(delayed_install
+ base
+ files
+ destination)
+
+ foreach(f ${files})
+ set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f})
+ set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination})
+ endforeach()
+endmacro()
+
+# note this is a function instead of a macro so that ${BUILD_TYPE} in targetdir
+# does not get expanded in calling but is preserved
+function(delayed_do_install
+ targetdir)
+
+ get_property(files GLOBAL PROPERTY DELAYED_INSTALL_FILES)
+ get_property(destinations GLOBAL PROPERTY DELAYED_INSTALL_DESTINATIONS)
+
+ if(files)
+ list(LENGTH files n)
+ math(EXPR n "${n}-1")
+
+ foreach(i RANGE ${n})
+ list(GET files ${i} f)
+ list(GET destinations ${i} d)
+ install(FILES ${f} DESTINATION ${targetdir}/${d})
+ endforeach()
+ endif()
+endfunction()
+
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 44f9a4c8062..ba15f1c1c09 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -329,6 +329,10 @@ def creator(env):
if env['WITH_BF_SDL']:
defs.append('WITH_SDL')
+ if env['WITH_BF_LIBMV']:
+ incs.append('#/extern/libmv')
+ defs.append('WITH_LIBMV')
+
if env['WITH_BF_PYTHON']:
incs.append('#/source/blender/python')
defs.append('WITH_PYTHON')
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 68054fe485e..5c78dc646bb 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -515,6 +515,8 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)),
(BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)),
+ (BoolVariable('WITH_BF_LIBMV', 'Enable libmv structure from motion library', True)),
+
('BF_X264_CONFIG', 'configuration flags for x264', ''),
('BF_XVIDCORE_CONFIG', 'configuration flags for xvidcore', ''),
# (BoolVariable('WITH_BF_DOCS', 'Generate API documentation', False)),
diff --git a/doc/python_api/examples/bpy.app.handlers.1.py b/doc/python_api/examples/bpy.app.handlers.1.py
index a6591f6b83f..48fdb95d793 100644
--- a/doc/python_api/examples/bpy.app.handlers.1.py
+++ b/doc/python_api/examples/bpy.app.handlers.1.py
@@ -15,6 +15,6 @@ from bpy.app.handlers import persistent
@persistent
def load_handler(dummy):
- print("Load Handler:", bpy.data.filepath)
+ print("Load Handler:", bpy.data.filepath)
bpy.app.handlers.load_post.append(load_handler)
diff --git a/doc/python_api/examples/bpy.app.handlers.py b/doc/python_api/examples/bpy.app.handlers.py
index 7c176063b7c..57b209e15f0 100644
--- a/doc/python_api/examples/bpy.app.handlers.py
+++ b/doc/python_api/examples/bpy.app.handlers.py
@@ -6,7 +6,8 @@ This script shows the most simple example of adding a handler.
import bpy
+
def my_handler(scene):
- print("Frame Change", scene.frame_current)
+ print("Frame Change", scene.frame_current)
-bpy.app.handlers.frame_change_pre.append(my_handler) \ No newline at end of file
+bpy.app.handlers.frame_change_pre.append(my_handler)
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 321ebc11985..a5dd3b16860 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -63,3 +63,7 @@ endif()
if(WITH_LZMA)
add_subdirectory(lzma)
endif()
+
+if(WITH_LIBMV)
+ add_subdirectory(libmv)
+endif()
diff --git a/extern/SConscript b/extern/SConscript
index f363d75d068..031471a8a01 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -28,3 +28,6 @@ if env['WITH_BF_LZO']:
if env['WITH_BF_LZMA']:
SConscript(['lzma/SConscript'])
+
+if env['WITH_BF_LIBMV']:
+ SConscript(['libmv/SConscript'])
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
new file mode 100644
index 00000000000..333791e28eb
--- /dev/null
+++ b/extern/libmv/CMakeLists.txt
@@ -0,0 +1,215 @@
+# ***** 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) 2011, Blender Foundation
+# All rights reserved.
+#
+# Contributor(s): Blender Foundation,
+# Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ ../Eigen3
+ third_party/ssba
+ third_party/ldl/Include
+ ../colamd/Include
+)
+
+set(INC_SYS
+ ${PNG_INCLUDE_DIR}
+ ${ZLIB_INCLUDE_DIRS}
+)
+
+set(SRC
+ libmv-capi.cpp
+ libmv/numeric/numeric.cc
+ libmv/numeric/poly.cc
+ libmv/simple_pipeline/reconstruction.cc
+ libmv/simple_pipeline/resect.cc
+ libmv/simple_pipeline/intersect.cc
+ libmv/simple_pipeline/initialize_reconstruction.cc
+ libmv/simple_pipeline/camera_intrinsics.cc
+ libmv/simple_pipeline/pipeline.cc
+ libmv/simple_pipeline/detect.cc
+ libmv/simple_pipeline/tracks.cc
+ libmv/simple_pipeline/bundle.cc
+ libmv/image/convolve.cc
+ libmv/image/array_nd.cc
+ libmv/tracking/pyramid_region_tracker.cc
+ libmv/tracking/sad.cc
+ libmv/tracking/trklt_region_tracker.cc
+ libmv/tracking/klt_region_tracker.cc
+ libmv/tracking/retrack_region_tracker.cc
+ libmv/multiview/projection.cc
+ libmv/multiview/conditioning.cc
+ libmv/multiview/fundamental.cc
+ libmv/multiview/euclidean_resection.cc
+ libmv/multiview/triangulation.cc
+
+ third_party/ssba/Geometry/v3d_metricbundle.cpp
+ third_party/ssba/Math/v3d_optimization.cpp
+ third_party/gflags/gflags.cc
+ third_party/gflags/gflags_reporting.cc
+ third_party/gflags/gflags_completions.cc
+ third_party/fast/fast_9.c
+ third_party/fast/fast_10.c
+ third_party/fast/fast_11.c
+ third_party/fast/fast_12.c
+ third_party/fast/fast.c
+ third_party/fast/nonmax.c
+ third_party/ldl/Source/ldl.c
+
+ libmv-capi.h
+ libmv/logging/logging.h
+ libmv/numeric/dogleg.h
+ libmv/numeric/levenberg_marquardt.h
+ libmv/numeric/poly.h
+ libmv/numeric/function_derivative.h
+ libmv/numeric/numeric.h
+ libmv/simple_pipeline/resect.h
+ libmv/simple_pipeline/reconstruction.h
+ libmv/simple_pipeline/camera_intrinsics.h
+ libmv/simple_pipeline/tracks.h
+ libmv/simple_pipeline/detect.h
+ libmv/simple_pipeline/pipeline.h
+ 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/sample.h
+ libmv/image/image.h
+ libmv/tracking/region_tracker.h
+ libmv/tracking/retrack_region_tracker.h
+ libmv/tracking/sad.h
+ libmv/tracking/pyramid_region_tracker.h
+ libmv/tracking/trklt_region_tracker.h
+ 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/nviewtriangulation.h
+ libmv/multiview/resection.h
+ libmv/multiview/euclidean_resection.h
+ libmv/multiview/triangulation.h
+ libmv/multiview/projection.h
+ libmv/multiview/fundamental.h
+ libmv/multiview/conditioning.h
+
+ third_party/ssba/Geometry/v3d_metricbundle.h
+ third_party/ssba/Geometry/v3d_cameramatrix.h
+ third_party/ssba/Geometry/v3d_distortion.h
+ 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/gflags/gflags_completions.h
+ third_party/gflags/mutex.h
+ third_party/gflags/config.h
+ third_party/gflags/gflags.h
+ third_party/fast/fast.h
+ third_party/ldl/Include/ldl.h
+ third_party/msinttypes/stdint.h
+ third_party/msinttypes/inttypes.h
+)
+
+if(WIN32)
+ list(APPEND SRC
+ third_party/glog/src/logging.cc
+ third_party/glog/src/raw_logging.cc
+ third_party/glog/src/utilities.cc
+ third_party/glog/src/vlog_is_on.cc
+ third_party/glog/src/windows/port.cc
+
+ third_party/glog/src/utilities.h
+ third_party/glog/src/stacktrace_generic-inl.h
+ third_party/glog/src/stacktrace.h
+ third_party/glog/src/stacktrace_x86_64-inl.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/stacktrace_powerpc-inl.h
+ third_party/glog/src/stacktrace_x86-inl.h
+ third_party/glog/src/config.h
+ third_party/glog/src/stacktrace_libunwind-inl.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/port.h
+ third_party/glog/src/windows/config.h
+ )
+
+ list(APPEND INC
+ third_party/glog/src/windows
+ )
+
+ if(NOT MINGW)
+ list(APPEND INC
+ third_party/msinttypes
+ )
+ endif()
+
+ if(MSVC)
+ set(MSVC_OFLAGS O1 O2 Ox)
+ foreach(FLAG )
+ string(REPLACE "" "Od" CMAKE_CXX_FLAGS_RELEASE "")
+ string(REPLACE "" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "")
+ endforeach()
+ endif()
+else(WIN32)
+ list(APPEND SRC
+ third_party/glog/src/utilities.cc
+ third_party/glog/src/symbolize.cc
+ third_party/glog/src/vlog_is_on.cc
+ third_party/glog/src/signalhandler.cc
+ third_party/glog/src/logging.cc
+ third_party/glog/src/demangle.cc
+ third_party/glog/src/raw_logging.cc
+
+ third_party/glog/src/utilities.h
+ third_party/glog/src/stacktrace_generic-inl.h
+ third_party/glog/src/config_mac.h
+ third_party/glog/src/stacktrace.h
+ third_party/glog/src/stacktrace_x86_64-inl.h
+ 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/stacktrace_powerpc-inl.h
+ third_party/glog/src/stacktrace_x86-inl.h
+ 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/config_linux.h
+ )
+
+ list(APPEND INC
+ third_party/glog/src
+ )
+endif()
+
+add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=)
+
+blender_add_lib(extern_libmv "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
new file mode 100644
index 00000000000..7e10abfead6
--- /dev/null
+++ b/extern/libmv/ChangeLog
@@ -0,0 +1,312 @@
+commit 531c79bf95fddaaa70707d1abcd4fdafda16bbf0
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Sat Aug 20 00:00:42 2011 +0200
+
+ Display warped pattern in marker preview.
+
+commit bb5c27e671b6f8eb56ddf490f0795d59bede591b
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 18:37:48 2011 +0200
+
+ Fix CMake build.
+
+commit 2ac7281ff6b9545b425dd84fb03bf9c5c98b4de2
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 17:34:45 2011 +0200
+
+ Avoid symbol shadowing.
+
+commit 2a7c3de4acc60e0433b4952f69e30528dbafe0d2
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 17:22:47 2011 +0200
+
+ Better dragging behavior when hitting borders.
+
+commit a14eb3953c9521b2e08ff9ddd45b33ff1f8aeafb
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 17:12:12 2011 +0200
+
+ Update marker preview to new affine tracking.
+
+commit 5299ea67043459eda147950e589c2d327a8fbced
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 16:05:54 2011 +0200
+
+ sqrt takes double precision.
+
+commit 9f9221ce151d788c49b48f6f293ab2e2f8813978
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 16:04:37 2011 +0200
+
+ MSVC compatibility: heap allocate pattern, explicit float cast.
+
+commit 702658d2f8616964a6eeb3743fd85e97ac7ff09d
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 14:59:24 2011 +0200
+
+ Expose regularization parameters (areaPenalty and conditionPenalty) in API.
+
+commit 3e84ae5fbac10451d4935418f6281a90cedace11
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 14:19:27 2011 +0200
+
+ Add LaplaceFilter.
+ Add regularization in affine SAD Tracker (keep constant area and good condition number).
+ UI: Better track display (+enable line antialiasing).
+
+commit 6d26d9a8ccc4ce009fbf253898fea8864dd5001a
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 10:25:26 2011 +0200
+
+ Add optimization for integer pixel search.
+ Allows more agressive settings for affine coordinate descent.
+
+commit 70ceae81c0ab561b07e640ecb9933f0a902b57cd
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 19 00:02:12 2011 +0200
+
+ Document coordinate descent method in affine SAD matcher.
+ Add heuristic to prevent high distortions.
+
+commit 75520f4bc4ccbb272a1b4149d3b8d05a90f7f896
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Aug 18 23:14:17 2011 +0200
+
+ Fix affine iteration.
+
+commit 4e8e0aa6018e3eb2fbebdad7f1cbd6c909d26e79
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Aug 18 23:03:26 2011 +0200
+
+ Handle rotations.
+
+commit 3ce41cf3c1b5c136a61d8f4c63ccae3cafbdb8da
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Aug 18 22:24:47 2011 +0200
+
+ Slow brute-force affine diamond search implementation.
+
+commit 1c4acd03e030c1c50dc6fc36c419c72ea69a0713
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Aug 18 20:51:43 2011 +0200
+
+ Fix detect.cc.
+
+commit ec18cc5ea9ae2e641075a847e82d0aacb8415ad8
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Aug 18 17:45:37 2011 +0200
+
+ Compute and return Pearson product-moment correlation coefficient between reference and matched pattern.
+
+commit 21d4245c63a01bfc736192d55baf10983e7c9ec7
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Aug 18 16:18:44 2011 +0200
+
+ UI and API support for affine tracking.
+
+commit a4876d8c40dcde615b44009c38c49e9a1b1d4698
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Aug 17 20:26:01 2011 +0200
+
+ Hack to make sad.cc compile with MSVC on system without support for the SSE instruction set.
+
+commit 0de723dfce5bbe44dbd19be8cd6dd6e9b03b7924
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Aug 17 20:10:46 2011 +0200
+
+ Fix slow path (for computers without SSE2).
+ Heap allocate scores in detect.cc
+
+commit 65a9d496f81e8b37eae39a4063957b8be9a4e6f0
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Aug 17 19:25:17 2011 +0200
+
+ Fix compilation on OSX.
+
+commit d22720e618456329388d2c107422c3b371657cba
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Aug 17 14:14:45 2011 +0200
+
+ Improve Detect and SAD Tracker API and documentation.
+
+commit 5d6cd4ad365b061901bad40695b51d568487a0cf
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Aug 17 11:57:29 2011 +0200
+
+ MSVC support fixes.
+
+commit 50f0323173c6deebd6aaf9c126f0b51b2a79c3c1
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 23:21:37 2011 +0200
+
+ Detector can detect features similar to a given pattern.
+
+commit 5734cc27bbf84c2b6edcfcc1ea736798e12d5820
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 22:53:54 2011 +0200
+
+ Ensure SAD Tracker is C compatible.
+ Update Detect API documentation.
+
+commit 701c42842574064fea992f8822e3899cb9066108
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 21:56:42 2011 +0200
+
+ Remove FAST detector.
+ Add Moravec detector.
+ This detector is more suited to tracking since it try to choose patterns which are unlikely to drift by computing SAD with neighbouring patches.
+ It could be improved to better avoid edges.
+
+commit 9bdf93e13fc880c78b6f34397da673388c16040e
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 21:55:08 2011 +0200
+
+ Fix Qt Tracker GL to work with AMD drivers.
+
+commit 81613ee0cc94b315f333c9632b18b95d426aad05
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 21:54:12 2011 +0200
+
+ Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv.
+
+commit a1d9a8fa8b01ef7cf2a79b3b891633fc333fc9cf
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 21:24:51 2011 +0200
+
+ Fix SAD tracker. Pattern was transposed by affine pattern sampler.
+
+commit c3b794da2e7fd23f2fbdf90dbd71de0e6b3bc811
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 16 21:19:02 2011 +0200
+
+ Fix SAD tracker. Pattern was transposed by affine pattern sampler.
+
+commit a9b61bf3356f27174cdd983f562f99c3a6a2cc35
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Sun Aug 14 09:56:51 2011 +0200
+
+ Clarify CameraIntrinsics documentation.
+ Edit CameraInstrinsics test to fail.
+
+commit 10bdad9ad2cea2603896263cde5a5339169a9af0
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 12 21:05:32 2011 +0200
+
+ Fix out of bound access in warp bilinear sampling.
+
+commit dd9a418db021a28af2c1198d5e5b9e68fe048a03
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 12 19:14:36 2011 +0200
+
+ Fix compilation with -funsigned-char.
+
+commit bd1a268ede39b67f2ba4b360f6fc693419e7cd7f
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Aug 12 18:39:27 2011 +0200
+
+ CameraIntrinsics fixes.
+
+commit ae513b39fb779632f96ceff7c1e014fb8e68702a
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 19:38:58 2011 +0200
+
+ Remove stray QDebug include.
+
+commit 1e58f55078ce6009a885be30ae0316aec6ed8239
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 14:16:31 2011 +0200
+
+ Make API future-proof (for an eventual affine or planar tracker).
+
+commit c2af303e7bf0dddcb02937323ac5846b1801e6cc
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 11:13:29 2011 +0200
+
+ Remove reconstruction breaking debug code.
+
+commit 8792a633e5c5f1c1f12e164b9e8897ca0790ac59
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 10:49:18 2011 +0200
+
+ Remove getchar()s.
+
+commit 63a9bdee0cbd1197e0315d01c27bfc2361bd5656
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 10:35:07 2011 +0200
+
+ Adapt patch to new PipelineRoutines code generation strategy.
+
+commit 096ff1a4070f7212c50fb0a4b2feec7ca9d97158
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 09:54:12 2011 +0200
+
+ Merge max_image and max_track fix from tomato.
+
+commit d8450cd3c37278a397482cd36b1e2419f154cfb9
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Tue Aug 9 09:38:49 2011 +0200
+
+ Synchronize tree with Tomato: Merge patch for better resection, keep deprecated KLT tracker.
+
+commit e9b2dca920cf9575c15150a4988634b00e343a41
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Mon Aug 8 17:07:08 2011 +0200
+
+ Fixes, Documentation.
+
+commit 4fc1c57a2d92442808ac4a3676e6d9a25a51e310
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Sun Aug 7 14:35:08 2011 +0200
+
+ Improve tracker resilience by penalizing large motion vectors.
+
+commit cc8e7e8e08cd91f75c080a0091461ca9fe969664
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Sun Aug 7 09:28:09 2011 +0200
+
+ Leverage SSE2 SAD instruction for 16x speed improvement in integer pixel search resulting in ~1ms per marker for 16x16 pattern on 128x128 region.
+
+commit f362ab4999a768370fca57552464b459eb9fbddc
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Sun Aug 7 09:06:04 2011 +0200
+
+ Improve SAD Tracker subpixel precision (avoid drift even when adapting at each frame).
+
+commit fce7a214c561b5f5f0e17115c31fb48814bde2db
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Sat Aug 6 21:57:06 2011 +0200
+
+ Track using simple Sum of Absolute Differences matching.
+ This method is simpler, more robust, faster and accurate.
+
+commit 620a7a35d9a2818bf6e9dbf5d11debda4be6bc26
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Fri Jul 29 12:35:57 2011 +0200
+
+ Add Intersect unit test.
+
+commit a2bf58fa57be11215eb17ff7f7de58f97d480ec3
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Thu Jul 28 11:08:06 2011 +0200
+
+ Remove tests depending on dead code.
+ Fix CameraIntrinsics test.
+ Add Intersect and Resect tests.
+
+commit 19bddee10b4879c8cd2238ccdf5b8f7620cf8384
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Jul 27 12:07:21 2011 +0200
+
+ Image Distortion: Fixes and more testing.
+
+commit 0454d97da328fb0eda8c6c50511ac31864a6d3d6
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Jul 27 10:32:37 2011 +0200
+
+ Test float image distortion.
+
+commit 8db01595a8721f766d85931a8d92b780461d8741
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date: Wed Jul 27 10:27:07 2011 +0200
+
+ Image Distortion: Bilinear sampling, Optimization, Instantiate all variants (Distort/Undistort, float/ubyte, 1-4 channels).
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
new file mode 100644
index 00000000000..60705e913f7
--- /dev/null
+++ b/extern/libmv/SConscript
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+import sys
+import os
+
+Import('env')
+
+defs = []
+
+cflags_libmv = Split(env['CFLAGS'])
+ccflags_libmv = Split(env['CCFLAGS'])
+cxxflags_libmv = Split(env['CXXFLAGS'])
+
+defs.append('V3DLIB_ENABLE_SUITESPARSE')
+defs.append('GOOGLE_GLOG_DLL_DECL=')
+
+src = env.Glob("*.cpp")
+src += env.Glob('libmv/image/*.cc')
+src += env.Glob('libmv/multiview/*.cc')
+src += env.Glob('libmv/numeric/*.cc')
+src += env.Glob('libmv/simple_pipeline/*.cc')
+src += env.Glob('libmv/tracking/*.cc')
+src += env.Glob('third_party/fast/*.c')
+src += env.Glob('third_party/gflags/*.cc')
+src += env.Glob('third_party/ldl/Source/*.c')
+src += env.Glob('third_party/ssba/Geometry/*.cpp')
+src += env.Glob('third_party/ssba/Math/*.cpp')
+
+incs = '. ../Eigen3'
+incs += ' ' + env['BF_PNG_INC']
+incs += ' ' + env['BF_ZLIB_INC']
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog'
+ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ incs += ' ./third_party/msinttypes'
+
+ src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
+ src += ['./third_party/glog/src/windows/port.cc']
+
+ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ cflags_libmv.append('/Od')
+ ccflags_libmv.append('/Od')
+ cxxflags_libmv.append('/Od')
+
+ if not env['BF_DEBUG']:
+ 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'])
+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'])
+
+incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
+
+env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
new file mode 100755
index 00000000000..690f78df387
--- /dev/null
+++ b/extern/libmv/bundle.sh
@@ -0,0 +1,263 @@
+#!/bin/sh
+
+#BRANCH="keir"
+BRANCH="Matthias-Fauconneau"
+
+if [ -d ./.svn ]; then
+ echo "This script is supposed to work only when using git-svn"
+ exit 1
+fi
+
+repo="git://github.com/${BRANCH}/libmv.git"
+tmp=`mktemp -d`
+
+git clone $repo $tmp/libmv
+
+#git --git-dir $tmp/libmv/.git --work-tree $tmp/libmv log --since="1 month ago" > ChangeLog
+git --git-dir $tmp/libmv/.git --work-tree $tmp/libmv log -n 50 > ChangeLog
+
+for p in `cat ./patches/series`; do
+ echo "Applying patch $p..."
+ cat ./patches/$p | patch -d $tmp/libmv -p1
+done
+
+rm -rf libmv
+rm -rf third_party
+
+cat "files.txt" | while f=`line`; do
+ mkdir -p `dirname $f`
+ cp $tmp/libmv/src/$f $f
+done
+
+rm -rf $tmp
+
+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/'`
+
+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_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/'`
+
+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`
+src=""
+win_src=""
+for x in $src_dir $src_third_dir; do
+ t=""
+
+ if test `echo "$x" | grep -c glog ` -eq 1; then
+ continue;
+ fi
+
+ if stat $x/*.cpp > /dev/null 2>&1; then
+ t="src += env.Glob('`echo $x'/*.cpp'`')"
+ fi
+
+ if stat $x/*.c > /dev/null 2>&1; then
+ if [ -z "$t" ]; then
+ t="src += env.Glob('`echo $x'/*.c'`')"
+ else
+ t="$t + env.Glob('`echo $x'/*.c'`')"
+ fi
+ fi
+
+ if stat $x/*.cc > /dev/null 2>&1; then
+ if [ -z "$t" ]; then
+ t="src += env.Glob('`echo $x'/*.cc'`')"
+ else
+ t="$t + env.Glob('`echo $x'/*.cc'`')"
+ fi
+ fi
+
+ if test `echo $x | grep -c windows ` -eq 0; then
+ if [ -z "$src" ]; then
+ src=$t
+ else
+ src=`echo "$src\n$t"`
+ fi
+ else
+ if [ -z "$win_src" ]; then
+ win_src=`echo " $t"`
+ else
+ win_src=`echo "$win_src\n $t"`
+ fi
+ fi
+done
+
+cat > CMakeLists.txt << EOF
+# \$Id\$
+# ***** 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) 2011, Blender Foundation
+# All rights reserved.
+#
+# Contributor(s): Blender Foundation,
+# Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ ../Eigen3
+ ./third_party/ssba
+ ./third_party/ldl/Include
+ ../colamd/Include
+)
+
+set(INC_SYS
+ ${PNG_INCLUDE_DIR}
+ ${ZLIB_INCLUDE_DIRS}
+)
+
+set(SRC
+ libmv-capi.cpp
+${sources}
+
+${third_sources}
+
+ libmv-capi.h
+${headers}
+
+${third_headers}
+)
+
+IF(WIN32)
+ list(APPEND SRC
+ third_party/glog/src/logging.cc
+ third_party/glog/src/raw_logging.cc
+ third_party/glog/src/utilities.cc
+ third_party/glog/src/vlog_is_on.cc
+ third_party/glog/src/windows/port.cc
+
+ third_party/glog/src/utilities.h
+ third_party/glog/src/stacktrace_generic-inl.h
+ third_party/glog/src/stacktrace.h
+ third_party/glog/src/stacktrace_x86_64-inl.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/stacktrace_powerpc-inl.h
+ third_party/glog/src/stacktrace_x86-inl.h
+ third_party/glog/src/config.h
+ third_party/glog/src/stacktrace_libunwind-inl.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/port.h
+ third_party/glog/src/windows/config.h
+ )
+
+ list(APPEND INC
+ ./third_party/glog/src/windows
+ )
+
+ IF(NOT MINGW)
+ list(APPEND INC
+ ./third_party/msinttypes
+ )
+ ENDIF(MINGW)
+
+ list(APPEND INC
+ ./third_party/glog/src/windows
+ ./third_party/msinttypes
+ )
+
+ 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)
+ list(APPEND SRC
+${third_glog_sources}
+
+${third_glog_headers}
+ )
+
+ list(APPEND INC
+ ./third_party/glog/src
+ )
+ENDIF(WIN32)
+
+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
+import sys
+import os
+
+Import('env')
+
+defs = []
+
+cflags_libmv = Split(env['CFLAGS'])
+ccflags_libmv = Split(env['CCFLAGS'])
+cxxflags_libmv = Split(env['CXXFLAGS'])
+
+defs.append('V3DLIB_ENABLE_SUITESPARSE')
+defs.append('GOOGLE_GLOG_DLL_DECL=')
+
+src = env.Glob("*.cpp")
+$src
+
+incs = '. ../Eigen3'
+incs += ' ' + env['BF_PNG_INC']
+incs += ' ' + env['BF_ZLIB_INC']
+
+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}
+ src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
+ src += ['./third_party/glog/src/windows/port.cc']
+
+ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ cflags_libmv.append('/Od')
+ ccflags_libmv.append('/Od')
+ cxxflags_libmv.append('/Od')
+
+ if not env['BF_DEBUG']:
+ 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'])
+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'])
+
+incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
+
+env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
+EOF
diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt
new file mode 100644
index 00000000000..fe6be5d0b20
--- /dev/null
+++ b/extern/libmv/files.txt
@@ -0,0 +1,141 @@
+libmv/logging/logging.h
+libmv/numeric/dogleg.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/simple_pipeline/camera_intrinsics.h
+libmv/simple_pipeline/intersect.cc
+libmv/simple_pipeline/initialize_reconstruction.cc
+libmv/simple_pipeline/camera_intrinsics.cc
+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/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/tracking/pyramid_region_tracker.cc
+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.h
+libmv/tracking/sad.h
+libmv/tracking/pyramid_region_tracker.h
+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.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/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/src/config_mac.h
+third_party/glog/src/vlog_is_on.cc
+third_party/glog/src/signalhandler.cc
+third_party/glog/src/stacktrace.h
+third_party/glog/src/stacktrace_x86_64-inl.h
+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/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/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/msinttypes/inttypes.h
+third_party/msinttypes/README.libmv
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
new file mode 100644
index 00000000000..2e007bb47b2
--- /dev/null
+++ b/extern/libmv/libmv-capi.cpp
@@ -0,0 +1,770 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* define this to generate PNG images with content of search areas
+ tracking between which failed */
+#undef DUMP_FAILURE
+
+#include "libmv-capi.h"
+
+#include "glog/logging.h"
+#include "Math/v3d_optimization.h"
+
+#include "libmv/tracking/klt_region_tracker.h"
+#include "libmv/tracking/trklt_region_tracker.h"
+#include "libmv/tracking/pyramid_region_tracker.h"
+
+#include "libmv/tracking/sad.h"
+
+#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/initialize_reconstruction.h"
+#include "libmv/simple_pipeline/bundle.h"
+#include "libmv/simple_pipeline/detect.h"
+#include "libmv/simple_pipeline/pipeline.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+
+#include <stdlib.h>
+
+#ifdef DUMP_FAILURE
+# include <png.h>
+#endif
+
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
+#define DEFAULT_WINDOW_HALFSIZE 5
+
+typedef struct libmv_RegionTracker {
+ libmv::TrkltRegionTracker *trklt_region_tracker;
+ libmv::RegionTracker *region_tracker;
+} libmv_RegionTracker;
+
+typedef struct libmv_Reconstruction {
+ libmv::EuclideanReconstruction reconstruction;
+
+ /* used for per-track average error calculation after reconstruction */
+ libmv::Tracks tracks;
+ libmv::CameraIntrinsics intrinsics;
+
+ double error;
+} libmv_Reconstruction;
+
+typedef struct libmv_Features {
+ int count, margin;
+ libmv::Feature *features;
+} libmv_Features;
+
+/* ************ Logging ************ */
+
+void libmv_initLogging(const char *argv0)
+{
+ google::InitGoogleLogging(argv0);
+ google::SetCommandLineOption("logtostderr", "1");
+ google::SetCommandLineOption("v", "0");
+ google::SetCommandLineOption("stderrthreshold", "7");
+ google::SetCommandLineOption("minloglevel", "7");
+ V3D::optimizerVerbosenessLevel = 0;
+}
+
+void libmv_startDebugLogging(void)
+{
+ google::SetCommandLineOption("logtostderr", "1");
+ google::SetCommandLineOption("v", "0");
+ google::SetCommandLineOption("stderrthreshold", "1");
+ google::SetCommandLineOption("minloglevel", "0");
+ V3D::optimizerVerbosenessLevel = 1;
+}
+
+void libmv_setLoggingVerbosity(int verbosity)
+{
+ char val[10];
+ snprintf(val, sizeof(val), "%d", verbosity);
+
+ google::SetCommandLineOption("v", val);
+ V3D::optimizerVerbosenessLevel = verbosity;
+}
+
+/* ************ RegionTracker ************ */
+
+libmv_RegionTracker *libmv_regionTrackerNew(int max_iterations, int pyramid_level)
+{
+ libmv::TrkltRegionTracker *trklt_region_tracker = new libmv::TrkltRegionTracker;
+
+ trklt_region_tracker->half_window_size = DEFAULT_WINDOW_HALFSIZE;
+ trklt_region_tracker->max_iterations = max_iterations;
+ trklt_region_tracker->min_determinant = 1e-4;
+
+ libmv::PyramidRegionTracker *region_tracker =
+ new libmv::PyramidRegionTracker(trklt_region_tracker, pyramid_level);
+
+ libmv_RegionTracker *configured_region_tracker = new libmv_RegionTracker;
+ configured_region_tracker->trklt_region_tracker = trklt_region_tracker;
+ configured_region_tracker->region_tracker = region_tracker;
+
+ return configured_region_tracker;
+}
+
+static void floatBufToImage(const float *buf, int width, int height, libmv::FloatImage *image)
+{
+ int x, y, a = 0;
+
+ image->resize(height, width);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ (*image)(y, x, 0) = buf[a++];
+ }
+ }
+}
+
+#ifdef DUMP_FAILURE
+void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name)
+{
+ png_infop info_ptr;
+ png_structp png_ptr;
+ FILE *fp = fopen(file_name, "wb");
+
+ if (!fp)
+ return;
+
+ /* Initialize stuff */
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info_ptr = png_create_info_struct(png_ptr);
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ /* write header */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return;
+ }
+
+ png_set_IHDR(png_ptr, info_ptr, width, height,
+ depth, color_type, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_write_info(png_ptr, info_ptr);
+
+ /* write bytes */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return;
+ }
+
+ png_write_image(png_ptr, row_pointers);
+
+ /* end write */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return;
+ }
+
+ png_write_end(png_ptr, NULL);
+
+ fclose(fp);
+}
+
+static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
+{
+ int x, y;
+ png_bytep *row_pointers;
+
+ row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*image.Height());
+
+ for (y = 0; y < image.Height(); y++) {
+ row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*image.Width());
+
+ for (x = 0; x < image.Width(); x++) {
+ if (x0 == x && y0 == y) {
+ row_pointers[y][x*4+0]= 255;
+ row_pointers[y][x*4+1]= 0;
+ row_pointers[y][x*4+2]= 0;
+ row_pointers[y][x*4+3]= 255;
+ }
+ else {
+ float pixel = image(y, x, 0);
+ row_pointers[y][x*4+0]= pixel*255;
+ row_pointers[y][x*4+1]= pixel*255;
+ row_pointers[y][x*4+2]= pixel*255;
+ row_pointers[y][x*4+3]= 255;
+ }
+ }
+ }
+
+ {
+ static int a= 0;
+ char buf[128];
+ snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
+ savePNGImage(row_pointers, image.Width(), image.Height(), 8, PNG_COLOR_TYPE_RGBA, buf);
+ }
+
+ for (y = 0; y < image.Height(); y++) {
+ free(row_pointers[y]);
+ }
+ free(row_pointers);
+}
+
+static void saveBytesImage(char *prefix, unsigned char *data, int width, int height)
+{
+ int x, y;
+ png_bytep *row_pointers;
+
+ row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*height);
+
+ for (y = 0; y < height; y++) {
+ row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*width);
+
+ for (x = 0; x < width; x++) {
+ char pixel = data[width*y+x];
+ row_pointers[y][x*4+0]= pixel;
+ row_pointers[y][x*4+1]= pixel;
+ row_pointers[y][x*4+2]= pixel;
+ row_pointers[y][x*4+3]= 255;
+ }
+ }
+
+ {
+ static int a= 0;
+ char buf[128];
+ snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
+ savePNGImage(row_pointers, width, height, 8, PNG_COLOR_TYPE_RGBA, buf);
+ }
+
+ for (y = 0; y < height; y++) {
+ free(row_pointers[y]);
+ }
+ free(row_pointers);
+}
+#endif
+
+int libmv_regionTrackerTrack(libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2,
+ int width, int height, int half_window_size,
+ double x1, double y1, double *x2, double *y2)
+{
+ libmv::RegionTracker *region_tracker;
+ libmv::TrkltRegionTracker *trklt_region_tracker;
+ libmv::FloatImage old_patch, new_patch;
+
+ trklt_region_tracker = libmv_tracker->trklt_region_tracker;
+ region_tracker = libmv_tracker->region_tracker;
+
+ trklt_region_tracker->half_window_size = half_window_size;
+
+ floatBufToImage(ima1, width, height, &old_patch);
+ floatBufToImage(ima2, width, height, &new_patch);
+
+#ifndef DUMP_FAILURE
+ return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
+#else
+ {
+ double sx2 = *x2, sy2 = *y2;
+ int result = region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
+
+ if (!result) {
+ saveImage("old_patch", old_patch, x1, y1);
+ saveImage("new_patch", new_patch, sx2, sy2);
+ }
+
+ return result;
+ }
+#endif
+}
+
+void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker)
+{
+ delete libmv_tracker->region_tracker;
+ delete libmv_tracker;
+}
+
+/* ************ Tracks ************ */
+
+void libmv_SADSamplePattern(unsigned char *image, int stride,
+ float warp[3][2], unsigned char *pattern)
+{
+ libmv::mat32 mat32;
+
+ memcpy(mat32.data, warp, sizeof(float)*3*2);
+
+ libmv::SamplePattern(image, stride, mat32, pattern, 16);
+}
+
+float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image, int stride,
+ int width, int height, float warp[3][2])
+{
+ float result;
+ libmv::mat32 mat32;
+
+ memcpy(mat32.data, warp, sizeof(float)*3*2);
+
+ result = libmv::Track(pattern, warped, 16, image, stride, width, height, &mat32, 16, 16);
+
+ memcpy(warp, mat32.data, sizeof(float)*3*2);
+
+ return result;
+}
+
+/* ************ Tracks ************ */
+
+libmv_Tracks *libmv_tracksNew(void)
+{
+ libmv::Tracks *libmv_tracks = new libmv::Tracks();
+
+ return (libmv_Tracks *)libmv_tracks;
+}
+
+void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y)
+{
+ ((libmv::Tracks*)libmv_tracks)->Insert(image, track, x, y);
+}
+
+void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
+{
+ delete (libmv::Tracks*)libmv_tracks;
+}
+
+/* ************ Reconstruction solver ************ */
+
+libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyframe1, int keyframe2,
+ double focal_length, double principal_x, double principal_y, double k1, double k2, double k3)
+{
+ /* Invert the camera intrinsics. */
+ libmv::vector<libmv::Marker> markers = ((libmv::Tracks*)tracks)->AllMarkers();
+ libmv_Reconstruction *libmv_reconstruction = new libmv_Reconstruction();
+ libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+ libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+
+ intrinsics->SetFocalLength(focal_length, focal_length);
+ intrinsics->SetPrincipalPoint(principal_x, principal_y);
+ intrinsics->SetRadialDistortion(k1, k2, k3);
+
+ if(focal_length) {
+ /* do a lens undistortion if focal length is non-zero only */
+ for (int i = 0; i < markers.size(); ++i) {
+ intrinsics->InvertIntrinsics(markers[i].x,
+ markers[i].y,
+ &(markers[i].x),
+ &(markers[i].y));
+ }
+ }
+
+ libmv::Tracks normalized_tracks(markers);
+
+ libmv::vector<libmv::Marker> keyframe_markers =
+ normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
+
+ libmv::EuclideanReconstructTwoFrames(keyframe_markers, reconstruction);
+ libmv::EuclideanBundle(normalized_tracks, reconstruction);
+ libmv::EuclideanCompleteReconstruction(normalized_tracks, reconstruction);
+
+ libmv_reconstruction->tracks = *(libmv::Tracks *)tracks;
+ libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics);
+
+ return (libmv_Reconstruction *)libmv_reconstruction;
+}
+
+int libmv_reporojectionPointForTrack(libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
+{
+ libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+ libmv::EuclideanPoint *point = reconstruction->PointForTrack(track);
+
+ if(point) {
+ pos[0] = point->X[0];
+ pos[1] = point->X[2];
+ pos[2] = point->X[1];
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static libmv::Marker ProjectMarker(const libmv::EuclideanPoint &point, const libmv::EuclideanCamera &camera,
+ const libmv::CameraIntrinsics &intrinsics) {
+ libmv::Vec3 projected = camera.R * point.X + camera.t;
+ projected /= projected(2);
+
+ libmv::Marker reprojected_marker;
+ intrinsics.ApplyIntrinsics(projected(0), projected(1), &reprojected_marker.x, &reprojected_marker.y);
+
+ reprojected_marker.image = camera.image;
+ reprojected_marker.track = point.track;
+
+ return reprojected_marker;
+}
+
+double libmv_reporojectionErrorForTrack(libmv_Reconstruction *libmv_reconstruction, int track)
+{
+ libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+ libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+ libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersForTrack(track);
+
+ int num_reprojected = 0;
+ double total_error = 0.0;
+
+ for (int i = 0; i < markers.size(); ++i) {
+ const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
+ const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+
+ if (!camera || !point) {
+ continue;
+ }
+
+ num_reprojected++;
+
+ libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
+ double ex = reprojected_marker.x - markers[i].x;
+ double ey = reprojected_marker.y - markers[i].y;
+
+ total_error += sqrt(ex*ex + ey*ey);
+ }
+
+ return total_error / num_reprojected;
+}
+
+double libmv_reporojectionErrorForImage(libmv_Reconstruction *libmv_reconstruction, int image)
+{
+ libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+ libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+ libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersInImage(image);
+ const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image);
+ int num_reprojected = 0;
+ double total_error = 0.0;
+
+ if (!camera)
+ return 0;
+
+ for (int i = 0; i < markers.size(); ++i) {
+ const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+
+ if (!point) {
+ continue;
+ }
+
+ num_reprojected++;
+
+ libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
+ double ex = reprojected_marker.x - markers[i].x;
+ double ey = reprojected_marker.y - markers[i].y;
+
+ total_error += sqrt(ex*ex + ey*ey);
+ }
+
+ return total_error / num_reprojected;
+}
+
+int libmv_reporojectionCameraForImage(libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4])
+{
+ libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+ libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image);
+
+ if(camera) {
+ for (int j = 0; j < 3; ++j) {
+ for (int k = 0; k < 3; ++k) {
+ int l = k;
+
+ if (k == 1) l = 2;
+ else if (k == 2) l = 1;
+
+ if (j == 2) mat[j][l] = -camera->R(j,k);
+ else mat[j][l] = camera->R(j,k);
+ }
+ mat[j][3]= 0.0;
+ }
+
+ libmv::Vec3 optical_center = -camera->R.transpose() * camera->t;
+
+ mat[3][0] = optical_center(0);
+ mat[3][1] = optical_center(2);
+ mat[3][2] = optical_center(1);
+
+ mat[3][3]= 1.0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+double libmv_reprojectionError(libmv_Reconstruction *libmv_reconstruction)
+{
+ return libmv_reconstruction->error;
+}
+
+void libmv_destroyReconstruction(libmv_Reconstruction *libmv_reconstruction)
+{
+ delete libmv_reconstruction;
+}
+
+/* ************ feature detector ************ */
+
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+ int margin, int min_trackness, int min_distance)
+{
+ libmv::Feature *features = NULL;
+ std::vector<libmv::Feature> v;
+ libmv_Features *libmv_features = new libmv_Features();
+ int i= 0, count;
+
+ if(margin) {
+ data += margin*stride+margin;
+ width -= 2*margin;
+ height -= 2*margin;
+ }
+
+ v = libmv::DetectFAST(data, width, height, stride, min_trackness, min_distance);
+
+ count = v.size();
+
+ if(count) {
+ features= new libmv::Feature[count];
+
+ for(std::vector<libmv::Feature>::iterator it = v.begin(); it != v.end(); it++) {
+ features[i++]= *it;
+ }
+ }
+
+ libmv_features->features = features;
+ libmv_features->count = count;
+ libmv_features->margin = margin;
+
+ return (libmv_Features *)libmv_features;
+}
+
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
+ int margin, int count, int min_distance)
+{
+ libmv::Feature *features = NULL;
+ libmv_Features *libmv_features = new libmv_Features;
+
+ if(count) {
+ if(margin) {
+ data += margin*stride+margin;
+ width -= 2*margin;
+ height -= 2*margin;
+ }
+
+ features = new libmv::Feature[count];
+ libmv::DetectMORAVEC(data, stride, width, height, features, &count, min_distance, NULL);
+ }
+
+ libmv_features->count = count;
+ libmv_features->margin = margin;
+ libmv_features->features = features;
+
+ return libmv_features;
+}
+
+int libmv_countFeatures(struct libmv_Features *libmv_features)
+{
+ return libmv_features->count;
+}
+
+void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size)
+{
+ libmv::Feature feature= libmv_features->features[number];
+
+ *x = feature.x + libmv_features->margin;
+ *y = feature.y + libmv_features->margin;
+ *score = feature.score;
+ *size = feature.size;
+}
+
+void libmv_destroyFeatures(struct libmv_Features *libmv_features)
+{
+ if(libmv_features->features)
+ delete [] libmv_features->features;
+
+ delete libmv_features;
+}
+
+/* ************ camera intrinsics ************ */
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y,
+ double k1, double k2, double k3, int width, int height)
+{
+ libmv::CameraIntrinsics *intrinsics= new libmv::CameraIntrinsics();
+
+ intrinsics->SetFocalLength(focal_length, focal_length);
+ intrinsics->SetPrincipalPoint(principal_x, principal_y);
+ intrinsics->SetRadialDistortion(k1, k2, k3);
+ intrinsics->SetImageSize(width, height);
+
+ return (struct libmv_CameraIntrinsics *) intrinsics;
+}
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics)
+{
+ libmv::CameraIntrinsics *orig_intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+ libmv::CameraIntrinsics *new_intrinsics= new libmv::CameraIntrinsics(*orig_intrinsics);
+
+ return (struct libmv_CameraIntrinsics *) new_intrinsics;
+}
+
+void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics)
+{
+ libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+ delete intrinsics;
+}
+
+void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
+ double principal_x, double principal_y, double k1, double k2, double k3, int width, int height)
+{
+ libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+ if (intrinsics->focal_length() != focal_length)
+ intrinsics->SetFocalLength(focal_length, focal_length);
+
+ if (intrinsics->principal_point_x() != principal_x || intrinsics->principal_point_y() != principal_y)
+ intrinsics->SetFocalLength(focal_length, focal_length);
+
+ if (intrinsics->k1() != k1 || intrinsics->k2() != k2 || intrinsics->k3() != k3)
+ intrinsics->SetRadialDistortion(k1, k2, k3);
+
+ if (intrinsics->image_width() != width || intrinsics->image_height() != height)
+ intrinsics->SetImageSize(width, height);
+}
+
+void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+ intrinsics->Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+ intrinsics->Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+ intrinsics->Distort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+ intrinsics->Distort(src, dst, width, height, overscan, channels);
+}
+
+/* ************ distortion ************ */
+
+void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics intrinsics;
+
+ intrinsics.SetFocalLength(focal_length, focal_length);
+ intrinsics.SetPrincipalPoint(principal_x, principal_y);
+ intrinsics.SetRadialDistortion(k1, k2, k3);
+
+ intrinsics.Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ float *src, float *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics intrinsics;
+
+ intrinsics.SetFocalLength(focal_length, focal_length);
+ intrinsics.SetPrincipalPoint(principal_x, principal_y);
+ intrinsics.SetRadialDistortion(k1, k2, k3);
+
+ intrinsics.Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics intrinsics;
+
+ intrinsics.SetFocalLength(focal_length, focal_length);
+ intrinsics.SetPrincipalPoint(principal_x, principal_y);
+ intrinsics.SetRadialDistortion(k1, k2, k3);
+
+ intrinsics.Distort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ float *src, float *dst, int width, int height, float overscan, int channels)
+{
+ libmv::CameraIntrinsics intrinsics;
+
+ intrinsics.SetFocalLength(focal_length, focal_length);
+ intrinsics.SetPrincipalPoint(principal_x, principal_y);
+ intrinsics.SetRadialDistortion(k1, k2, k3);
+
+ intrinsics.Distort(src, dst, width, height, overscan, channels);
+}
+
+/* ************ utils ************ */
+
+void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ double x, double y, double *x1, double *y1)
+{
+ libmv::CameraIntrinsics intrinsics;
+
+ intrinsics.SetFocalLength(focal_length, focal_length);
+ intrinsics.SetPrincipalPoint(principal_x, principal_y);
+ intrinsics.SetRadialDistortion(k1, k2, k3);
+
+ if(focal_length) {
+ /* do a lens undistortion if focal length is non-zero only */
+
+ intrinsics.ApplyIntrinsics(x, y, x1, y1);
+ }
+}
+
+void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ double x, double y, double *x1, double *y1)
+{
+ libmv::CameraIntrinsics intrinsics;
+
+ intrinsics.SetFocalLength(focal_length, focal_length);
+ intrinsics.SetPrincipalPoint(principal_x, principal_y);
+ intrinsics.SetRadialDistortion(k1, k2, k3);
+
+ if(focal_length) {
+ /* do a lens distortion if focal length is non-zero only */
+
+ intrinsics.InvertIntrinsics(x, y, x1, y1);
+ }
+}
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
new file mode 100644
index 00000000000..b71a66b73a6
--- /dev/null
+++ b/extern/libmv/libmv-capi.h
@@ -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.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_H
+#define LIBMV_C_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct libmv_RegionTracker;
+struct libmv_Tracks;
+struct libmv_Reconstruction;
+struct libmv_Features;
+struct libmv_CameraIntrinsics;
+
+/* Logging */
+void libmv_initLogging(const char *argv0);
+void libmv_startDebugLogging(void);
+void libmv_setLoggingVerbosity(int verbosity);
+
+/* RegionTracker */
+struct libmv_RegionTracker *libmv_regionTrackerNew(int max_iterations, int pyramid_level);
+int libmv_regionTrackerTrack(struct libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2,
+ int width, int height, int half_window_size,
+ double x1, double y1, double *x2, double *y2);
+void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
+
+/* SAD Tracker */
+void libmv_SADSamplePattern(unsigned char *image, int stride,
+ float warp[3][2], unsigned char *pattern);
+float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image,
+ int stride, int width, int height, float warp[3][2]);
+
+/* Tracks */
+struct libmv_Tracks *libmv_tracksNew(void);
+void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y);
+void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks);
+
+/* Reconstruction solver */
+struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2,
+ double focal_length, double principal_x, double principal_y, double k1, double k2, double k3);
+int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]);
+double libmv_reporojectionErrorForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track);
+double libmv_reporojectionErrorForImage(struct libmv_Reconstruction *libmv_reconstruction, int image);
+int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4]);
+double libmv_reprojectionError(struct libmv_Reconstruction *libmv_reconstruction);
+void libmv_destroyReconstruction(struct libmv_Reconstruction *libmv_reconstruction);
+
+/* feature detector */
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+ int margin, int min_trackness, int min_distance);
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
+ int margin, int count, int min_distance);
+int libmv_countFeatures(struct libmv_Features *libmv_features);
+void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size);
+void libmv_destroyFeatures(struct libmv_Features *libmv_features);
+
+/* camera intrinsics */
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y,
+ double k1, double k2, double k3, int width, int height);
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics);
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics);
+
+void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics);
+
+void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
+ double principal_x, double principal_y, double k1, double k2, double k3, int width, int height);
+
+void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels);
+
+void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height, float overscan, int channels);
+
+void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels);
+
+void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+ float *src, float *dst, int width, int height, float overscan, int channels);
+
+/* dsitortion */
+void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ unsigned char *src, unsigned char *dst, int width, int height, int channels);
+void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ float *src, float *dst, int width, int height, int channels);
+
+void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ unsigned char *src, unsigned char *dst, int width, int height, int channels);
+void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ float *src, float *dst, int width, int height, int channels);
+
+/* utils */
+void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ double x, double y, double *x1, double *y1);
+void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+ double x, double y, double *x1, double *y1);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_H
diff --git a/extern/libmv/libmv/base/id_generator.h b/extern/libmv/libmv/base/id_generator.h
new file mode 100644
index 00000000000..bf1eafd218e
--- /dev/null
+++ b/extern/libmv/libmv/base/id_generator.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_ID_GENERATOR_H
+#define LIBMV_ID_GENERATOR_H
+
+namespace libmv {
+
+template <typename ID>
+class IdGenerator {
+ public:
+ IdGenerator() : next_(0) {}
+ ID Generate() { return next_++; }
+ private:
+ ID next_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_ID_GENERATOR_H
diff --git a/extern/libmv/libmv/base/scoped_ptr.h b/extern/libmv/libmv/base/scoped_ptr.h
new file mode 100644
index 00000000000..f1e89eb5625
--- /dev/null
+++ b/extern/libmv/libmv/base/scoped_ptr.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_BASE_SCOPED_PTR_H
+#define LIBMV_BASE_SCOPED_PTR_H
+
+namespace libmv {
+
+/**
+ * A handle for a heap-allocated resource that should be freed when it goes out
+ * of scope. This looks similar to the one found in TR1.
+ */
+template<typename T>
+class scoped_ptr {
+ public:
+ scoped_ptr(T *resource) : resource_(resource) {}
+ ~scoped_ptr() { reset(0); }
+
+ T *get() const { return resource_; }
+ T *operator->() const { return resource_; }
+ T &operator*() const { return *resource_; }
+
+ void reset(T *new_resource) {
+ if (sizeof(T)) {
+ delete resource_;
+ }
+ resource_ = new_resource;
+ }
+
+ T *release() {
+ T *released_resource = resource_;
+ resource_ = 0;
+ return released_resource;
+ }
+
+ private:
+ // No copying allowed.
+ T *resource_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_BASE_SCOPED_PTR_H
diff --git a/extern/libmv/libmv/base/vector.h b/extern/libmv/libmv/base/vector.h
new file mode 100644
index 00000000000..9dc48676629
--- /dev/null
+++ b/extern/libmv/libmv/base/vector.h
@@ -0,0 +1,172 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Get an aligned vector implementation. Must be included before <vector>. The
+// Eigen guys went through some trouble to make a portable override for the
+// fixed size vector types.
+
+#ifndef LIBMV_BASE_VECTOR_H
+#define LIBMV_BASE_VECTOR_H
+
+#include <cstring>
+#include <new>
+
+#include <Eigen/Core>
+
+namespace libmv {
+
+// A simple container class, which guarantees 16 byte alignment needed for most
+// vectorization. Don't use this container for classes that cannot be copied
+// via memcpy.
+// FIXME: this class has some issues:
+// - doesn't support iterators.
+// - impede compatibility with code using STL.
+// - the STL already provide support for custom allocators
+// it could be replaced with a simple
+// template <T> class vector : std::vector<T, aligned_allocator> {} declaration
+// provided it doesn't break code relying on libmv::vector specific behavior
+template <typename T,
+ typename Allocator = Eigen::aligned_allocator<T> >
+class vector {
+ public:
+ ~vector() { clear(); }
+
+ vector() { init(); }
+ vector(int size) { init(); resize(size); }
+ vector(int size, const T & val) {
+ init();
+ resize(size);
+ std::fill(data_, data_+size_, val); }
+
+ // Copy constructor and assignment.
+ vector(const vector<T, Allocator> &rhs) {
+ init();
+ copy(rhs);
+ }
+ vector<T, Allocator> &operator=(const vector<T, Allocator> &rhs) {
+ if (&rhs != this) {
+ copy(rhs);
+ }
+ return *this;
+ }
+
+ /// Swaps the contents of two vectors in constant time.
+ void swap(vector<T, Allocator> &other) {
+ std::swap(allocator_, other.allocator_);
+ std::swap(size_, other.size_);
+ std::swap(capacity_, other.capacity_);
+ std::swap(data_, other.data_);
+ }
+
+ T *data() const { return data_; }
+ int size() const { return size_; }
+ int capacity() const { return capacity_; }
+ const T& back() const { return data_[size_ - 1]; }
+ T& back() { return data_[size_ - 1]; }
+ const T& front() const { return data_[0]; }
+ T& front() { return data_[0]; }
+ const T& operator[](int n) const { return data_[n]; }
+ T& operator[](int n) { return data_[n]; }
+ const T * begin() const { return data_; }
+ const T * end() const { return data_+size_; }
+ T * begin() { return data_; }
+ T * end() { return data_+size_; }
+
+ void resize(size_t size) {
+ reserve(size);
+ if (size > size_) {
+ construct(size_, size);
+ } else if (size < size_) {
+ destruct(size, size_);
+ }
+ size_ = size;
+ }
+
+
+
+ void push_back(const T &value) {
+ if (size_ == capacity_) {
+ reserve(size_ ? 2 * size_ : 1);
+ }
+ new (&data_[size_++]) T(value);
+ }
+
+ void pop_back() {
+ resize(size_ - 1);
+ }
+
+ void clear() {
+ destruct(0, size_);
+ deallocate();
+ init();
+ }
+
+ void reserve(unsigned int size) {
+ if (size > size_) {
+ T *data = static_cast<T *>(allocate(size));
+ memcpy(data, data_, sizeof(*data)*size_);
+ allocator_.deallocate(data_, capacity_);
+ data_ = data;
+ capacity_ = size;
+ }
+ }
+
+ private:
+ void construct(int start, int end) {
+ for (int i = start; i < end; ++i) {
+ new (&data_[i]) T;
+ }
+ }
+ void destruct(int start, int end) {
+ for (int i = start; i < end; ++i) {
+ data_[i].~T();
+ }
+ }
+ void init() {
+ size_ = 0;
+ data_ = 0;
+ capacity_ = 0;
+ }
+
+ void *allocate(int size) {
+ return size ? allocator_.allocate(size) : 0;
+ }
+
+ void deallocate() {
+ allocator_.deallocate(data_, size_);
+ data_ = 0;
+ }
+
+ void copy(const vector<T, Allocator> &rhs) {
+ resize(rhs.size());
+ for (int i = 0; i < rhs.size(); ++i) {
+ (*this)[i] = rhs[i];
+ }
+ }
+
+ Allocator allocator_;
+ size_t size_;
+ size_t capacity_;
+ T *data_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_BASE_VECTOR_H
diff --git a/extern/libmv/libmv/base/vector_utils.h b/extern/libmv/libmv/base/vector_utils.h
new file mode 100644
index 00000000000..7a0c3ba24f5
--- /dev/null
+++ b/extern/libmv/libmv/base/vector_utils.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+
+#ifndef LIBMV_BASE_VECTOR_UTILS_H_
+#define LIBMV_BASE_VECTOR_UTILS_H_
+
+/// Delete the contents of a container.
+template <class Array>
+void DeleteElements(Array *array) {
+ for (int i = 0; i < array->size(); ++i) {
+ delete (*array)[i];
+ }
+ array->clear();
+}
+
+#endif // LIBMV_BASE_VECTOR_UTILS_H_
diff --git a/extern/libmv/libmv/image/array_nd.cc b/extern/libmv/libmv/image/array_nd.cc
new file mode 100644
index 00000000000..3a77e3e4881
--- /dev/null
+++ b/extern/libmv/libmv/image/array_nd.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/image/image.h"
+#include <iostream>
+#include <cmath>
+
+namespace libmv {
+
+void FloatArrayToScaledByteArray(const Array3Df &float_array,
+ Array3Du *byte_array,
+ bool automatic_range_detection
+ ) {
+ byte_array->ResizeLike(float_array);
+ float minval = HUGE_VAL;
+ float maxval = -HUGE_VAL;
+ if (automatic_range_detection) {
+ for (int i = 0; i < float_array.Height(); ++i) {
+ for (int j = 0; j < float_array.Width(); ++j) {
+ for (int k = 0; k < float_array.Depth(); ++k) {
+ minval = std::min(minval, float_array(i,j,k));
+ maxval = std::max(maxval, float_array(i,j,k));
+ }
+ }
+ }
+ } else {
+ minval = 0;
+ maxval = 1;
+ }
+ for (int i = 0; i < float_array.Height(); ++i) {
+ for (int j = 0; j < float_array.Width(); ++j) {
+ for (int k = 0; k < float_array.Depth(); ++k) {
+ float unscaled = (float_array(i,j,k) - minval) / (maxval - minval);
+ (*byte_array)(i,j,k) = (unsigned char)(255 * unscaled);
+ }
+ }
+ }
+}
+
+void ByteArrayToScaledFloatArray(const Array3Du &byte_array,
+ Array3Df *float_array) {
+ float_array->ResizeLike(byte_array);
+ for (int i = 0; i < byte_array.Height(); ++i) {
+ for (int j = 0; j < byte_array.Width(); ++j) {
+ for (int k = 0; k < byte_array.Depth(); ++k) {
+ (*float_array)(i,j,k) = float(byte_array(i,j,k)) / 255.0f;
+ }
+ }
+ }
+}
+
+void SplitChannels(const Array3Df &input,
+ Array3Df *channel0,
+ Array3Df *channel1,
+ Array3Df *channel2) {
+ assert(input.Depth() >= 3);
+ channel0->Resize(input.Height(), input.Width());
+ channel1->Resize(input.Height(), input.Width());
+ channel2->Resize(input.Height(), input.Width());
+ for (int row = 0; row < input.Height(); ++row) {
+ for (int column = 0; column < input.Width(); ++column) {
+ (*channel0)(row, column) = input(row, column, 0);
+ (*channel1)(row, column) = input(row, column, 1);
+ (*channel2)(row, column) = input(row, column, 2);
+ }
+ }
+}
+
+void PrintArray(const Array3Df &array) {
+ using namespace std;
+
+ printf("[\n");
+ for (int r = 0; r < array.Height(); ++r) {
+ printf("[");
+ for (int c = 0; c < array.Width(); ++c) {
+ if (array.Depth() == 1) {
+ printf("%11f, ", array(r, c));
+ } else {
+ printf("[");
+ for (int k = 0; k < array.Depth(); ++k) {
+ printf("%11f, ", array(r, c, k));
+ }
+ printf("],");
+ }
+ }
+ printf("],\n");
+ }
+ printf("]\n");
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/image/array_nd.h b/extern/libmv/libmv/image/array_nd.h
new file mode 100644
index 00000000000..6d7570cda9b
--- /dev/null
+++ b/extern/libmv/libmv/image/array_nd.h
@@ -0,0 +1,473 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_IMAGE_ARRAY_ND_H
+#define LIBMV_IMAGE_ARRAY_ND_H
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+
+#include "libmv/image/tuple.h"
+
+namespace libmv {
+
+class BaseArray {};
+
+/// A multidimensional array class.
+template <typename T, int N>
+class ArrayND : public BaseArray {
+ public:
+ typedef T Scalar;
+
+ /// Type for the multidimensional indices.
+ typedef Tuple<int, N> Index;
+
+ /// Create an empty array.
+ ArrayND() : data_(NULL), own_data(true) { Resize(Index(0)); }
+
+ /// Create an array with the specified shape.
+ ArrayND(const Index &shape) : data_(NULL), own_data(true) { Resize(shape); }
+
+ /// Create an array with the specified shape.
+ ArrayND(int *shape) : data_(NULL), own_data(true) { Resize(shape); }
+
+ /// Copy constructor.
+ ArrayND(const ArrayND<T, N> &b) : data_(NULL), own_data(true) {
+ ResizeLike(b);
+ std::memcpy(Data(), b.Data(), sizeof(T) * Size());
+ }
+
+ ArrayND(int s0) : data_(NULL), own_data(true) { Resize(s0); }
+ ArrayND(int s0, int s1) : data_(NULL), own_data(true) { Resize(s0, s1); }
+ ArrayND(int s0, int s1, int s2) : data_(NULL), own_data(true) { Resize(s0, s1, s2); }
+
+ ArrayND(T* data, int s0, int s1, int s2) : data_(data), own_data(false) { Resize(s0, s1, s2); }
+
+ /// Destructor deletes pixel data.
+ ~ArrayND() {
+ delete [] data_;
+ }
+
+ /// Assignation copies pixel data.
+ ArrayND &operator=(const ArrayND<T, N> &b) {
+ assert(this != &b);
+ ResizeLike(b);
+ std::memcpy(Data(), b.Data(), sizeof(T) * Size());
+ return *this;
+ }
+
+ const Index &Shapes() const {
+ return shape_;
+ }
+
+ const Index &Strides() const {
+ return strides_;
+ }
+
+ /// Create an array of shape s.
+ void Resize(const Index &new_shape) {
+ if (data_ != NULL && shape_ == new_shape) {
+ // Don't bother realloacting if the shapes match.
+ return;
+ }
+ shape_.Reset(new_shape);
+ strides_(N - 1) = 1;
+ for (int i = N - 1; i > 0; --i) {
+ strides_(i - 1) = strides_(i) * shape_(i);
+ }
+ if(own_data) {
+ delete [] data_;
+ data_ = NULL;
+ if (Size() > 0) {
+ data_ = new T[Size()];
+ }
+ }
+ }
+
+ template<typename D>
+ void ResizeLike(const ArrayND<D,N> &other) {
+ Resize(other.Shape());
+ }
+
+ /// Resizes the array to shape s. All data is lost.
+ void Resize(const int *new_shape_array) {
+ Resize(Index(new_shape_array));
+ }
+
+ /// Resize a 1D array to length s0.
+ void Resize(int s0) {
+ assert(N == 1);
+ int shape[] = {s0};
+ Resize(shape);
+ }
+
+ /// Resize a 2D array to shape (s0,s1).
+ void Resize(int s0, int s1) {
+ int shape[N] = {s0, s1};
+ for (int i = 2; i < N; ++i) {
+ shape[i] = 1;
+ }
+ Resize(shape);
+ }
+
+ // Match Eigen2's API.
+ void resize(int rows, int cols) {
+ Resize(rows, cols);
+ }
+
+ /// Resize a 3D array to shape (s0,s1,s2).
+ void Resize(int s0, int s1, int s2) {
+ assert(N == 3);
+ int shape[] = {s0,s1,s2};
+ Resize(shape);
+ }
+
+ template<typename D>
+ void CopyFrom(const ArrayND<D,N> &other) {
+ ResizeLike(other);
+ T *data = Data();
+ const D *other_data = other.Data();
+ for (int i = 0; i < Size(); ++i) {
+ data[i] = T(other_data[i]);
+ }
+ }
+
+ void Fill(T value) {
+ for (int i = 0; i < Size(); ++i) {
+ Data()[i] = value;
+ }
+ }
+
+ // Match Eigen's API.
+ void fill(T value) {
+ for (int i = 0; i < Size(); ++i) {
+ Data()[i] = value;
+ }
+ }
+
+ /// Return a tuple containing the length of each axis.
+ const Index &Shape() const {
+ return shape_;
+ }
+
+ /// Return the length of an axis.
+ int Shape(int axis) const {
+ return shape_(axis);
+ }
+
+ /// Return the distance between neighboring elements along axis.
+ int Stride(int axis) const {
+ return strides_(axis);
+ }
+
+ /// Return the number of elements of the array.
+ int Size() const {
+ int size = 1;
+ for (int i = 0; i < N; ++i)
+ size *= Shape(i);
+ return size;
+ }
+
+ /// Return the total amount of memory used by the array.
+ int MemorySizeInBytes() const {
+ return sizeof(*this) + Size() * sizeof(T);
+ }
+
+ /// Pointer to the first element of the array.
+ T *Data() { return data_; }
+
+ /// Constant pointer to the first element of the array.
+ const T *Data() const { return data_; }
+
+ /// Distance between the first element and the element at position index.
+ int Offset(const Index &index) const {
+ int offset = 0;
+ for (int i = 0; i < N; ++i)
+ offset += index(i) * Stride(i);
+ return offset;
+ }
+
+ /// 1D specialization.
+ int Offset(int i0) const {
+ assert(N == 1);
+ return i0 * Stride(0);
+ }
+
+ /// 2D specialization.
+ int Offset(int i0, int i1) const {
+ assert(N == 2);
+ return i0 * Stride(0) + i1 * Stride(1);
+ }
+
+ /// 3D specialization.
+ int Offset(int i0, int i1, int i2) const {
+ assert(N == 3);
+ return i0 * Stride(0) + i1 * Stride(1) + i2 * Stride(2);
+ }
+
+ /// Return a reference to the element at position index.
+ T &operator()(const Index &index) {
+ // TODO(pau) Boundary checking in debug mode.
+ return *( Data() + Offset(index) );
+ }
+
+ /// 1D specialization.
+ T &operator()(int i0) {
+ return *( Data() + Offset(i0) );
+ }
+
+ /// 2D specialization.
+ T &operator()(int i0, int i1) {
+ assert(0 <= i0 && i0 < Shape(0));
+ assert(0 <= i1 && i1 < Shape(1));
+ return *( Data() + Offset(i0,i1) );
+ }
+
+ /// 3D specialization.
+ T &operator()(int i0, int i1, int i2) {
+ assert(0 <= i0 && i0 < Shape(0));
+ assert(0 <= i1 && i1 < Shape(1));
+ assert(0 <= i2 && i2 < Shape(2));
+ return *( Data() + Offset(i0,i1,i2) );
+ }
+
+ /// Return a constant reference to the element at position index.
+ const T &operator()(const Index &index) const {
+ return *( Data() + Offset(index) );
+ }
+
+ /// 1D specialization.
+ const T &operator()(int i0) const {
+ return *( Data() + Offset(i0) );
+ }
+
+ /// 2D specialization.
+ const T &operator()(int i0, int i1) const {
+ assert(0 <= i0 && i0 < Shape(0));
+ assert(0 <= i1 && i1 < Shape(1));
+ return *( Data() + Offset(i0,i1) );
+ }
+
+ /// 3D specialization.
+ const T &operator()(int i0, int i1, int i2) const {
+ return *( Data() + Offset(i0,i1,i2) );
+ }
+
+ /// True if index is inside array.
+ bool Contains(const Index &index) const {
+ for (int i = 0; i < N; ++i)
+ if (index(i) < 0 || index(i) >= Shape(i))
+ return false;
+ return true;
+ }
+
+ /// 1D specialization.
+ bool Contains(int i0) const {
+ return 0 <= i0 && i0 < Shape(0);
+ }
+
+ /// 2D specialization.
+ bool Contains(int i0, int i1) const {
+ return 0 <= i0 && i0 < Shape(0)
+ && 0 <= i1 && i1 < Shape(1);
+ }
+
+ /// 3D specialization.
+ bool Contains(int i0, int i1, int i2) const {
+ return 0 <= i0 && i0 < Shape(0)
+ && 0 <= i1 && i1 < Shape(1)
+ && 0 <= i2 && i2 < Shape(2);
+ }
+
+ bool operator==(const ArrayND<T, N> &other) const {
+ if (shape_ != other.shape_) return false;
+ if (strides_ != other.strides_) return false;
+ for (int i = 0; i < Size(); ++i) {
+ if (this->Data()[i] != other.Data()[i])
+ return false;
+ }
+ return true;
+ }
+
+ bool operator!=(const ArrayND<T, N> &other) const {
+ return !(*this == other);
+ }
+
+ ArrayND<T, N> operator*(const ArrayND<T, N> &other) const {
+ assert(Shape() = other.Shape());
+ ArrayND<T, N> res;
+ res.ResizeLike(*this);
+ for (int i = 0; i < res.Size(); ++i) {
+ res.Data()[i] = Data()[i] * other.Data()[i];
+ }
+ return res;
+ }
+
+ protected:
+ /// The number of element in each dimension.
+ Index shape_;
+
+ /// How to jump to neighbors in each dimension.
+ Index strides_;
+
+ /// Pointer to the first element of the array.
+ T *data_;
+
+ /// Flag if this Array either own or reference the data
+ bool own_data;
+};
+
+/// 3D array (row, column, channel).
+template <typename T>
+class Array3D : public ArrayND<T, 3> {
+ typedef ArrayND<T, 3> Base;
+ public:
+ Array3D()
+ : Base() {
+ }
+ Array3D(int height, int width, int depth=1)
+ : Base(height, width, depth) {
+ }
+ Array3D(T* data, int height, int width, int depth=1)
+ : Base(data, height, width, depth) {
+ }
+
+ void Resize(int height, int width, int depth=1) {
+ Base::Resize(height, width, depth);
+ }
+
+ int Height() const {
+ return Base::Shape(0);
+ }
+ int Width() const {
+ return Base::Shape(1);
+ }
+ int Depth() const {
+ return Base::Shape(2);
+ }
+
+ // Match Eigen2's API so that Array3D's and Mat*'s can work together via
+ // template magic.
+ int rows() const { return Height(); }
+ int cols() const { return Width(); }
+ int depth() const { return Depth(); }
+
+ int Get_Step() const { return Width()*Depth(); }
+
+ /// Enable accessing with 2 indices for grayscale images.
+ T &operator()(int i0, int i1, int i2 = 0) {
+ assert(0 <= i0 && i0 < Height());
+ assert(0 <= i1 && i1 < Width());
+ return Base::operator()(i0,i1,i2);
+ }
+ const T &operator()(int i0, int i1, int i2 = 0) const {
+ assert(0 <= i0 && i0 < Height());
+ assert(0 <= i1 && i1 < Width());
+ return Base::operator()(i0,i1,i2);
+ }
+};
+
+typedef Array3D<unsigned char> Array3Du;
+typedef Array3D<unsigned int> Array3Dui;
+typedef Array3D<int> Array3Di;
+typedef Array3D<float> Array3Df;
+typedef Array3D<short> Array3Ds;
+
+void SplitChannels(const Array3Df &input,
+ Array3Df *channel0,
+ Array3Df *channel1,
+ Array3Df *channel2);
+
+void PrintArray(const Array3Df &array);
+
+/** Convert a float array into a byte array by scaling values by 255* (max-min).
+ * where max and min are automatically detected
+ * (if automatic_range_detection = true)
+ * \note and TODO this automatic detection only works when the image contains
+ * at least one pixel of both bounds.
+ **/
+void FloatArrayToScaledByteArray(const Array3Df &float_array,
+ Array3Du *byte_array,
+ bool automatic_range_detection = false);
+
+//! Convert a byte array into a float array by dividing values by 255.
+void ByteArrayToScaledFloatArray(const Array3Du &byte_array,
+ Array3Df *float_array);
+
+template <typename AArrayType, typename BArrayType, typename CArrayType>
+void MultiplyElements( const AArrayType &a,
+ const BArrayType &b,
+ CArrayType *c ) {
+ // This function does an element-wise multiply between
+ // the two Arrays A and B, and stores the result in C.
+ // A and B must have the same dimensions.
+ assert( a.Shape() == b.Shape() );
+ c->ResizeLike(a);
+
+ // To perform the multiplcation, a "current" index into the N-dimensions of
+ // the A and B matrix specifies which elements are being multiplied.
+ typename CArrayType::Index index;
+
+ // The index starts at the maximum value for each dimension
+ const typename CArrayType::Index& cShape = c->Shape();
+ for ( int i = 0; i < CArrayType::Index::SIZE; ++i )
+ index(i) = cShape(i) - 1;
+
+ // After each multiplication, the highest-dimensional index is reduced.
+ // if this reduces it less than zero, it resets to its maximum value
+ // and decrements the index of the next lower dimension.
+ // This ripple-action continues until the entire new array has been
+ // calculated, indicated by dimension zero having a negative index.
+ while ( index(0) >= 0 ) {
+ (*c)(index) = a(index) * b(index);
+
+ int dimension = CArrayType::Index::SIZE - 1;
+ index(dimension) = index(dimension) - 1;
+ while ( dimension > 0 && index(dimension) < 0 ) {
+ index(dimension) = cShape(dimension) - 1;
+ index(dimension - 1) = index(dimension - 1) - 1;
+ --dimension;
+ }
+ }
+}
+
+template <typename TA, typename TB, typename TC>
+void MultiplyElements(const ArrayND<TA, 3> &a,
+ const ArrayND<TB, 3> &b,
+ ArrayND<TC, 3> *c) {
+ // Specialization for N==3
+ c->ResizeLike(a);
+ assert(a.Shape(0) == b.Shape(0));
+ assert(a.Shape(1) == b.Shape(1));
+ assert(a.Shape(2) == b.Shape(2));
+ for (int i = 0; i < a.Shape(0); ++i) {
+ for (int j = 0; j < a.Shape(1); ++j) {
+ for (int k = 0; k < a.Shape(2); ++k) {
+ (*c)(i, j, k) = TC(a(i, j, k) * b(i, j, k));
+ }
+ }
+ }
+}
+
+
+} // namespace libmv
+
+#endif // LIBMV_IMAGE_ARRAY_ND_H
diff --git a/extern/libmv/libmv/image/convolve.cc b/extern/libmv/libmv/image/convolve.cc
new file mode 100644
index 00000000000..be73a1a3263
--- /dev/null
+++ b/extern/libmv/libmv/image/convolve.cc
@@ -0,0 +1,305 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <cmath>
+
+#include "libmv/image/image.h"
+#include "libmv/image/convolve.h"
+
+namespace libmv {
+
+// Compute a Gaussian kernel and derivative, such that you can take the
+// derivative of an image by convolving with the kernel horizontally then the
+// derivative vertically to get (eg) the y derivative.
+void ComputeGaussianKernel(double sigma, Vec *kernel, Vec *derivative) {
+ assert(sigma >= 0.0);
+
+ // 0.004 implies a 3 pixel kernel with 1 pixel sigma.
+ const float truncation_factor = 0.004f;
+
+ // Calculate the kernel size based on sigma such that it is odd.
+ float precisehalfwidth = GaussianInversePositive(truncation_factor, sigma);
+ int width = lround(2*precisehalfwidth);
+ if (width % 2 == 0) {
+ width++;
+ }
+ // Calculate the gaussian kernel and its derivative.
+ kernel->resize(width);
+ derivative->resize(width);
+ kernel->setZero();
+ derivative->setZero();
+ int halfwidth = width / 2;
+ for (int i = -halfwidth; i <= halfwidth; ++i) {
+ (*kernel)(i + halfwidth) = Gaussian(i, sigma);
+ (*derivative)(i + halfwidth) = GaussianDerivative(i, sigma);
+ }
+ // Since images should not get brighter or darker, normalize.
+ NormalizeL1(kernel);
+
+ // Normalize the derivative differently. See
+ // www.cs.duke.edu/courses/spring03/cps296.1/handouts/Image%20Processing.pdf
+ double factor = 0.;
+ for (int i = -halfwidth; i <= halfwidth; ++i) {
+ factor -= i*(*derivative)(i+halfwidth);
+ }
+ *derivative /= factor;
+}
+
+template <int size, bool vertical>
+void FastConvolve(const Vec &kernel, int width, int height,
+ const float* src, int src_stride, int src_line_stride,
+ float* dst, int dst_stride) {
+ double coefficients[2 * size + 1];
+ for (int k = 0; k < 2 * size + 1; ++k) {
+ coefficients[k] = kernel(2 * size - k);
+ }
+ // Fast path: if the kernel has a certain size, use the constant sized loops.
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ double sum = 0;
+ for (int k = -size; k <= size; ++k) {
+ if (vertical) {
+ if (y + k >= 0 && y + k < height) {
+ sum += src[k * src_line_stride] * coefficients[k + size];
+ }
+ } else {
+ if (x + k >= 0 && x + k < width) {
+ sum += src[k * src_stride] * coefficients[k + size];
+ }
+ }
+ }
+ dst[0] = static_cast<float>(sum);
+ src += src_stride;
+ dst += dst_stride;
+ }
+ }
+}
+
+template<bool vertical>
+void Convolve(const Array3Df &in,
+ const Vec &kernel,
+ Array3Df *out_pointer,
+ int plane) {
+ int width = in.Width();
+ int height = in.Height();
+ Array3Df &out = *out_pointer;
+ if (plane == -1) {
+ out.ResizeLike(in);
+ plane = 0;
+ }
+
+ assert(kernel.size() % 2 == 1);
+ assert(&in != out_pointer);
+
+ int src_line_stride = in.Stride(0);
+ int src_stride = in.Stride(1);
+ int dst_stride = out.Stride(1);
+ const float* src = in.Data();
+ float* dst = out.Data() + plane;
+
+ // Use a dispatch table to make most convolutions used in practice use the
+ // fast path.
+ int half_width = kernel.size() / 2;
+ switch (half_width) {
+#define static_convolution( size ) case size: \
+ FastConvolve<size, vertical>(kernel, width, height, src, src_stride, \
+ src_line_stride, dst, dst_stride); break;
+ static_convolution(1)
+ static_convolution(2)
+ static_convolution(3)
+ static_convolution(4)
+ static_convolution(5)
+ static_convolution(6)
+ static_convolution(7)
+#undef static_convolution
+ default:
+ int dynamic_size = kernel.size() / 2;
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ double sum = 0;
+ // Slow path: this loop cannot be unrolled.
+ for (int k = -dynamic_size; k <= dynamic_size; ++k) {
+ if(vertical) {
+ if (y + k >= 0 && y + k < height) {
+ sum += src[k * src_line_stride] * kernel(2 * dynamic_size - (k + dynamic_size));
+ }
+ } else {
+ if (x + k >= 0 && x + k < width) {
+ sum += src[k * src_stride] * kernel(2 * dynamic_size - (k + dynamic_size));
+ }
+ }
+ }
+ dst[0] = static_cast<float>(sum);
+ src += src_stride;
+ dst += dst_stride;
+ }
+ }
+ }
+}
+
+void ConvolveHorizontal(const Array3Df &in,
+ const Vec &kernel,
+ Array3Df *out_pointer,
+ int plane) {
+ Convolve<false>(in, kernel, out_pointer, plane);
+}
+
+void ConvolveVertical(const Array3Df &in,
+ const Vec &kernel,
+ Array3Df *out_pointer,
+ int plane) {
+ Convolve<true>(in, kernel, out_pointer, plane);
+}
+
+void ConvolveGaussian(const Array3Df &in,
+ double sigma,
+ Array3Df *out_pointer) {
+ Vec kernel, derivative;
+ ComputeGaussianKernel(sigma, &kernel, &derivative);
+
+ Array3Df tmp;
+ ConvolveVertical(in, kernel, &tmp);
+ ConvolveHorizontal(tmp, kernel, out_pointer);
+}
+
+void BlurredImageAndDerivatives(const Array3Df &in,
+ double sigma,
+ Array3Df *blurred_image,
+ Array3Df *gradient_x,
+ Array3Df *gradient_y) {
+ Vec kernel, derivative;
+ ComputeGaussianKernel(sigma, &kernel, &derivative);
+ Array3Df tmp;
+
+ // Compute convolved image.
+ ConvolveVertical(in, kernel, &tmp);
+ ConvolveHorizontal(tmp, kernel, blurred_image);
+
+ // Compute first derivative in x (reusing vertical convolution above).
+ ConvolveHorizontal(tmp, derivative, gradient_x);
+
+ // Compute first derivative in y.
+ ConvolveHorizontal(in, kernel, &tmp);
+ ConvolveVertical(tmp, derivative, gradient_y);
+}
+
+// Compute the gaussian blur of an image and the derivatives of the blurred
+// image, and store the results in three channels. Since the blurred value and
+// gradients are closer in memory, this leads to better performance if all
+// three values are needed at the same time.
+void BlurredImageAndDerivativesChannels(const Array3Df &in,
+ double sigma,
+ Array3Df *blurred_and_gradxy) {
+ assert(in.Depth() == 1);
+
+ Vec kernel, derivative;
+ ComputeGaussianKernel(sigma, &kernel, &derivative);
+
+ // Compute convolved image.
+ Array3Df tmp;
+ ConvolveVertical(in, kernel, &tmp);
+ blurred_and_gradxy->Resize(in.Height(), in.Width(), 3);
+ ConvolveHorizontal(tmp, kernel, blurred_and_gradxy, 0);
+
+ // Compute first derivative in x.
+ ConvolveHorizontal(tmp, derivative, blurred_and_gradxy, 1);
+
+ // Compute first derivative in y.
+ ConvolveHorizontal(in, kernel, &tmp);
+ ConvolveVertical(tmp, derivative, blurred_and_gradxy, 2);
+}
+
+void BoxFilterHorizontal(const Array3Df &in,
+ int window_size,
+ Array3Df *out_pointer) {
+ Array3Df &out = *out_pointer;
+ out.ResizeLike(in);
+ int half_width = (window_size - 1) / 2;
+
+ for (int k = 0; k < in.Depth(); ++k) {
+ for (int i=0; i<in.Height(); ++i) {
+ float sum = 0;
+ // Init sum.
+ for (int j=0; j<half_width; ++j) {
+ sum += in(i, j, k);
+ }
+ // Fill left border.
+ for (int j=0; j < half_width + 1; ++j) {
+ sum += in(i, j + half_width, k);
+ out(i, j, k) = sum;
+ }
+ // Fill interior.
+ for (int j = half_width + 1; j<in.Width()-half_width; ++j) {
+ sum -= in(i, j - half_width - 1, k);
+ sum += in(i, j + half_width, k);
+ out(i, j, k) = sum;
+ }
+ // Fill right border.
+ for (int j = in.Width() - half_width; j<in.Width(); ++j) {
+ sum -= in(i, j - half_width - 1, k);
+ out(i, j, k) = sum;
+ }
+ }
+ }
+}
+
+void BoxFilterVertical(const Array3Df &in,
+ int window_size,
+ Array3Df *out_pointer) {
+ Array3Df &out = *out_pointer;
+ out.ResizeLike(in);
+ int half_width = (window_size - 1) / 2;
+
+ for (int k = 0; k < in.Depth(); ++k) {
+ for (int j = 0; j < in.Width(); ++j) {
+ float sum = 0;
+ // Init sum.
+ for (int i=0; i<half_width; ++i) {
+ sum += in(i, j, k);
+ }
+ // Fill left border.
+ for (int i=0; i < half_width + 1; ++i) {
+ sum += in(i + half_width, j, k);
+ out(i, j, k) = sum;
+ }
+ // Fill interior.
+ for (int i = half_width + 1; i<in.Height()-half_width; ++i) {
+ sum -= in(i - half_width - 1, j, k);
+ sum += in(i + half_width, j, k);
+ out(i, j, k) = sum;
+ }
+ // Fill right border.
+ for (int i = in.Height() - half_width; i<in.Height(); ++i) {
+ sum -= in(i - half_width - 1, j, k);
+ out(i, j, k) = sum;
+ }
+ }
+ }
+}
+
+void BoxFilter(const Array3Df &in,
+ int box_width,
+ Array3Df *out) {
+ Array3Df tmp;
+ BoxFilterHorizontal(in, box_width, &tmp);
+ BoxFilterVertical(tmp, box_width, out);
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/image/convolve.h b/extern/libmv/libmv/image/convolve.h
new file mode 100644
index 00000000000..c6c995fd674
--- /dev/null
+++ b/extern/libmv/libmv/image/convolve.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2007, 2008, 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_IMAGE_CONVOLVE_H_
+#define LIBMV_IMAGE_CONVOLVE_H_
+
+#include "libmv/image/image.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+// TODO(keir): Find a better place for these functions. gaussian.h in numeric?
+
+// Zero mean Gaussian.
+inline double Gaussian(double x, double sigma) {
+ return 1/sqrt(2*M_PI*sigma*sigma) * exp(-(x*x/2/sigma/sigma));
+}
+// 2D gaussian (zero mean)
+// (9) in http://mathworld.wolfram.com/GaussianFunction.html
+inline double Gaussian2D(double x, double y, double sigma) {
+ return 1.0/(2.0*M_PI*sigma*sigma) * exp( -(x*x+y*y)/(2.0*sigma*sigma));
+}
+inline double GaussianDerivative(double x, double sigma) {
+ return -x / sigma / sigma * Gaussian(x, sigma);
+}
+// Solve the inverse of the Gaussian for positive x.
+inline double GaussianInversePositive(double y, double sigma) {
+ return sqrt(-2 * sigma * sigma * log(y * sigma * sqrt(2*M_PI)));
+}
+
+void ComputeGaussianKernel(double sigma, Vec *kernel, Vec *derivative);
+void ConvolveHorizontal(const FloatImage &in,
+ const Vec &kernel,
+ FloatImage *out_pointer,
+ int plane = -1);
+void ConvolveVertical(const FloatImage &in,
+ const Vec &kernel,
+ FloatImage *out_pointer,
+ int plane = -1);
+void ConvolveGaussian(const FloatImage &in,
+ double sigma,
+ FloatImage *out_pointer);
+
+void ImageDerivatives(const FloatImage &in,
+ double sigma,
+ FloatImage *gradient_x,
+ FloatImage *gradient_y);
+
+void BlurredImageAndDerivatives(const FloatImage &in,
+ double sigma,
+ FloatImage *blurred_image,
+ FloatImage *gradient_x,
+ FloatImage *gradient_y);
+
+// Blur and take the gradients of an image, storing the results inside the
+// three channels of blurred_and_gradxy.
+void BlurredImageAndDerivativesChannels(const FloatImage &in,
+ double sigma,
+ FloatImage *blurred_and_gradxy);
+
+void BoxFilterHorizontal(const FloatImage &in,
+ int window_size,
+ FloatImage *out_pointer);
+
+void BoxFilterVertical(const FloatImage &in,
+ int window_size,
+ FloatImage *out_pointer);
+
+void BoxFilter(const FloatImage &in,
+ int box_width,
+ FloatImage *out);
+
+} // namespace libmv
+
+#endif // LIBMV_IMAGE_CONVOLVE_H_
+
diff --git a/extern/libmv/libmv/image/image.h b/extern/libmv/libmv/image/image.h
new file mode 100644
index 00000000000..d158b0e0397
--- /dev/null
+++ b/extern/libmv/libmv/image/image.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_IMAGE_IMAGE_H
+#define LIBMV_IMAGE_IMAGE_H
+
+#include <cmath>
+
+#include "libmv/image/array_nd.h"
+
+namespace libmv {
+
+typedef Array3Du ByteImage; // For backwards compatibility.
+typedef Array3Df FloatImage;
+
+// Type added only to manage special 2D array for feature detection
+typedef Array3Di IntImage;
+typedef Array3Ds ShortImage;
+
+// An image class that is a thin wrapper around Array3D's of various types.
+// TODO(keir): Decide if we should add reference counting semantics... Maybe it
+// is the best solution after all.
+class Image {
+ public:
+
+ // Create an image from an array. The image takes ownership of the array.
+ Image(Array3Du *array) : array_type_(BYTE), array_(array) {}
+ Image(Array3Df *array) : array_type_(FLOAT), array_(array) {}
+
+ Image(const Image &img): array_type_(NONE), array_(NULL) {
+ *this = img;
+ }
+
+ // Underlying data type.
+ enum DataType {
+ NONE,
+ BYTE,
+ FLOAT,
+ INT,
+ SHORT,
+ };
+
+ // Size in bytes that the image takes in memory.
+ int MemorySizeInBytes() {
+ int size;
+ switch (array_type_)
+ {
+ case BYTE:
+ size = reinterpret_cast<Array3Du *>(array_)->MemorySizeInBytes();
+ break;
+ case FLOAT:
+ size = reinterpret_cast<Array3Df *>(array_)->MemorySizeInBytes();
+ break;
+ case INT:
+ size = reinterpret_cast<Array3Di *>(array_)->MemorySizeInBytes();
+ break;
+ case SHORT:
+ size = reinterpret_cast<Array3Ds *>(array_)->MemorySizeInBytes();
+ break;
+ default :
+ size = 0;
+ assert(0);
+ }
+ size += sizeof(*this);
+ return size;
+ }
+
+ ~Image() {
+ switch (array_type_)
+ {
+ case BYTE:
+ delete reinterpret_cast<Array3Du *>(array_);
+
+ break;
+ case FLOAT:
+ delete reinterpret_cast<Array3Df *>(array_);
+
+ break;
+ case INT:
+ delete reinterpret_cast<Array3Di *>(array_);
+
+ break;
+ case SHORT:
+ delete reinterpret_cast<Array3Ds *>(array_);
+
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ Image& operator= (const Image& f) {
+ if (this != &f) {
+ array_type_ = f.array_type_;
+ switch (array_type_)
+ {
+ case BYTE:
+ delete reinterpret_cast<Array3Du *>(array_);
+ array_ = new Array3Du( *(Array3Du *)f.array_);
+ break;
+ case FLOAT:
+ delete reinterpret_cast<Array3Df *>(array_);
+ array_ = new Array3Df( *(Array3Df *)f.array_);
+ break;
+ case INT:
+ delete reinterpret_cast<Array3Di *>(array_);
+ array_ = new Array3Di( *(Array3Di *)f.array_);
+ break;
+ case SHORT:
+ delete reinterpret_cast<Array3Ds *>(array_);
+ array_ = new Array3Ds( *(Array3Ds *)f.array_);
+ break;
+ default:
+ assert(0);
+ }
+ }
+ return *this;
+ }
+
+ Array3Du *AsArray3Du() const {
+ if (array_type_ == BYTE) {
+ return reinterpret_cast<Array3Du *>(array_);
+ }
+ return NULL;
+ }
+
+ Array3Df *AsArray3Df() const {
+ if (array_type_ == FLOAT) {
+ return reinterpret_cast<Array3Df *>(array_);
+ }
+ return NULL;
+ }
+
+ private:
+ DataType array_type_;
+ BaseArray *array_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_IMAGE_IMAGE_IMAGE_H
diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h
new file mode 100644
index 00000000000..cd361231b58
--- /dev/null
+++ b/extern/libmv/libmv/image/sample.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_IMAGE_SAMPLE_H_
+#define LIBMV_IMAGE_SAMPLE_H_
+
+#include "libmv/image/image.h"
+
+namespace libmv {
+
+/// Nearest neighbor interpolation.
+template<typename T>
+inline T SampleNearest(const Array3D<T> &image,
+ float y, float x, int v = 0) {
+ const int i = int(round(y));
+ const int j = int(round(x));
+ return image(i, j, v);
+}
+
+static inline void LinearInitAxis(float fx, int width,
+ int *x1, int *x2,
+ float *dx1, float *dx2) {
+ const int ix = int(fx);
+ if (ix < 0) {
+ *x1 = 0;
+ *x2 = 0;
+ *dx1 = 1;
+ *dx2 = 0;
+ } else if (ix > width-2) {
+ *x1 = width-1;
+ *x2 = width-1;
+ *dx1 = 1;
+ *dx2 = 0;
+ } else {
+ *x1 = ix;
+ *x2 = *x1 + 1;
+ *dx1 = *x2 - fx;
+ *dx2 = 1 - *dx1;
+ }
+}
+
+/// Linear interpolation.
+template<typename T>
+inline T SampleLinear(const Array3D<T> &image, float y, float x, int v = 0) {
+ int x1, y1, x2, y2;
+ float dx1, dy1, dx2, dy2;
+
+ LinearInitAxis(y, image.Height(), &y1, &y2, &dy1, &dy2);
+ LinearInitAxis(x, image.Width(), &x1, &x2, &dx1, &dx2);
+
+ const T im11 = image(y1, x1, v);
+ const T im12 = image(y1, x2, v);
+ const T im21 = image(y2, x1, v);
+ const T im22 = image(y2, x2, v);
+
+ return T(dy1 * ( dx1 * im11 + dx2 * im12 ) +
+ dy2 * ( dx1 * im21 + dx2 * im22 ));
+}
+
+// Downsample all channels by 2. If the image has odd width or height, the last
+// row or column is ignored.
+// FIXME(MatthiasF): this implementation shouldn't be in an interface file
+inline void DownsampleChannelsBy2(const Array3Df &in, Array3Df *out) {
+ int height = in.Height() / 2;
+ int width = in.Width() / 2;
+ int depth = in.Depth();
+
+ out->Resize(height, width, depth);
+
+ // 2x2 box filter downsampling.
+ for (int r = 0; r < height; ++r) {
+ for (int c = 0; c < width; ++c) {
+ for (int k = 0; k < depth; ++k) {
+ (*out)(r, c, k) = (in(2 * r, 2 * c, k) +
+ in(2 * r + 1, 2 * c, k) +
+ in(2 * r, 2 * c + 1, k) +
+ in(2 * r + 1, 2 * c + 1, k)) / 4.0f;
+ }
+ }
+ }
+
+}
+
+} // namespace libmv
+
+#endif // LIBMV_IMAGE_SAMPLE_H_
diff --git a/extern/libmv/libmv/image/tuple.h b/extern/libmv/libmv/image/tuple.h
new file mode 100644
index 00000000000..79acc9579d0
--- /dev/null
+++ b/extern/libmv/libmv/image/tuple.h
@@ -0,0 +1,90 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_IMAGE_TUPLE_H
+#define LIBMV_IMAGE_TUPLE_H
+
+#include <algorithm>
+
+namespace libmv {
+
+// A vector of elements with fixed lenght and deep copy semantics.
+template <typename T, int N>
+class Tuple {
+ public:
+ enum { SIZE = N };
+ Tuple() {}
+ Tuple(T initial_value) { Reset(initial_value); }
+
+ template <typename D>
+ Tuple(D *values) { Reset(values); }
+
+ template <typename D>
+ Tuple(const Tuple<D,N> &b) { Reset(b); }
+
+ template <typename D>
+ Tuple& operator=(const Tuple<D,N>& b) {
+ Reset(b);
+ return *this;
+ }
+
+ template <typename D>
+ void Reset(const Tuple<D, N>& b) { Reset(b.Data()); }
+
+ template <typename D>
+ void Reset(D *values) {
+ for(int i=0;i<N;i++) {
+ data_[i] = T(values[i]);
+ }
+ }
+
+ // Set all tuple values to the same thing.
+ void Reset(T value) {
+ for(int i=0;i<N;i++) {
+ data_[i] = value;
+ }
+ }
+
+ // Pointer to the first element.
+ T *Data() { return &data_[0]; }
+ const T *Data() const { return &data_[0]; }
+
+ T &operator()(int i) { return data_[i]; }
+ const T &operator()(int i) const { return data_[i]; }
+
+ bool operator==(const Tuple<T, N> &other) const {
+ for (int i = 0; i < N; ++i) {
+ if ((*this)(i) != other(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ bool operator!=(const Tuple<T, N> &other) const {
+ return !(*this == other);
+ }
+
+ private:
+ T data_[N];
+};
+
+} // namespace libmv
+
+#endif // LIBMV_IMAGE_TUPLE_H
diff --git a/extern/libmv/libmv/logging/logging.h b/extern/libmv/libmv/logging/logging.h
new file mode 100644
index 00000000000..af86c4baa42
--- /dev/null
+++ b/extern/libmv/libmv/logging/logging.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2007, 2008, 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_LOGGING_LOGGING_H
+#define LIBMV_LOGGING_LOGGING_H
+
+#include "glog/logging.h"
+
+#define LG LOG(INFO)
+#define V0 LOG(INFO)
+#define V1 LOG(INFO)
+#define V2 LOG(INFO)
+
+#endif // LIBMV_LOGGING_LOGGING_H
diff --git a/extern/libmv/libmv/multiview/conditioning.cc b/extern/libmv/libmv/multiview/conditioning.cc
new file mode 100644
index 00000000000..20e3a88e6cb
--- /dev/null
+++ b/extern/libmv/libmv/multiview/conditioning.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2010 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/multiview/conditioning.h"
+#include "libmv/multiview/projection.h"
+
+namespace libmv {
+
+// HZ 4.4.4 pag.109: Point conditioning (non isotropic)
+void PreconditionerFromPoints(const Mat &points, Mat3 *T) {
+ Vec mean, variance;
+ MeanAndVarianceAlongRows(points, &mean, &variance);
+
+ double xfactor = sqrt(2.0 / variance(0));
+ double yfactor = sqrt(2.0 / variance(1));
+
+ // If variance is equal to 0.0 set scaling factor to identity.
+ // -> Else it will provide nan value (because division by 0).
+ if (variance(0) < 1e-8)
+ xfactor = mean(0) = 1.0;
+ if (variance(1) < 1e-8)
+ yfactor = mean(1) = 1.0;
+
+ *T << xfactor, 0, -xfactor * mean(0),
+ 0, yfactor, -yfactor * mean(1),
+ 0, 0, 1;
+}
+// HZ 4.4.4 pag.107: Point conditioning (isotropic)
+void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T) {
+ Vec mean, variance;
+ MeanAndVarianceAlongRows(points, &mean, &variance);
+
+ double var_norm = variance.norm();
+ double factor = sqrt(2.0 / var_norm);
+
+ // If variance is equal to 0.0 set scaling factor to identity.
+ // -> Else it will provide nan value (because division by 0).
+ if (var_norm < 1e-8) {
+ factor = 1.0;
+ mean.setOnes();
+ }
+
+ *T << factor, 0, -factor * mean(0),
+ 0, factor, -factor * mean(1),
+ 0, 0, 1;
+}
+
+void ApplyTransformationToPoints(const Mat &points,
+ const Mat3 &T,
+ Mat *transformed_points) {
+ int n = points.cols();
+ transformed_points->resize(2,n);
+ Mat3X p(3, n);
+ EuclideanToHomogeneous(points, &p);
+ p = T * p;
+ HomogeneousToEuclidean(p, transformed_points);
+}
+
+void NormalizePoints(const Mat &points,
+ Mat *normalized_points,
+ Mat3 *T) {
+ PreconditionerFromPoints(points, T);
+ ApplyTransformationToPoints(points, *T, normalized_points);
+}
+
+void NormalizeIsotropicPoints(const Mat &points,
+ Mat *normalized_points,
+ Mat3 *T) {
+ IsotropicPreconditionerFromPoints(points, T);
+ ApplyTransformationToPoints(points, *T, normalized_points);
+}
+
+// Denormalize the results. See HZ page 109.
+void UnnormalizerT::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) {
+ *H = T2.transpose() * (*H) * T1;
+}
+
+void UnnormalizerI::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) {
+ *H = T2.inverse() * (*H) * T1;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/conditioning.h b/extern/libmv/libmv/multiview/conditioning.h
new file mode 100644
index 00000000000..181d7485374
--- /dev/null
+++ b/extern/libmv/libmv/multiview/conditioning.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2010 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_CONDITIONNING_H_
+#define LIBMV_MULTIVIEW_CONDITIONNING_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+// Point conditioning (non isotropic)
+void PreconditionerFromPoints(const Mat &points, Mat3 *T);
+// Point conditioning (isotropic)
+void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T);
+
+void ApplyTransformationToPoints(const Mat &points,
+ const Mat3 &T,
+ Mat *transformed_points);
+
+void NormalizePoints(const Mat &points,
+ Mat *normalized_points,
+ Mat3 *T);
+
+void NormalizeIsotropicPoints(const Mat &points,
+ Mat *normalized_points,
+ Mat3 *T);
+
+/// Use inverse for unnormalize
+struct UnnormalizerI {
+ // Denormalize the results. See HZ page 109.
+ static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H);
+};
+
+/// Use transpose for unnormalize
+struct UnnormalizerT {
+ // Denormalize the results. See HZ page 109.
+ static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H);
+};
+
+} //namespace libmv
+
+
+#endif // LIBMV_MULTIVIEW_CONDITIONNING_H_
diff --git a/extern/libmv/libmv/multiview/euclidean_resection.cc b/extern/libmv/libmv/multiview/euclidean_resection.cc
new file mode 100644
index 00000000000..92862515d7e
--- /dev/null
+++ b/extern/libmv/libmv/multiview/euclidean_resection.cc
@@ -0,0 +1,663 @@
+// Copyright (c) 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <cmath>
+#include <limits>
+
+#include <Eigen/SVD>
+#include <Eigen/Geometry>
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/euclidean_resection.h"
+#include "libmv/multiview/projection.h"
+
+namespace libmv {
+namespace euclidean_resection {
+
+typedef unsigned int uint;
+
+bool EuclideanResection(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R, Vec3 *t,
+ ResectionMethod method) {
+ switch (method) {
+ case RESECTION_ANSAR_DANIILIDIS:
+ EuclideanResectionAnsarDaniilidis(x_camera, X_world, R, t);
+ break;
+ case RESECTION_EPNP:
+ return EuclideanResectionEPnP(x_camera, X_world, R, t);
+ break;
+ default:
+ LOG(FATAL) << "Unknown resection method.";
+ }
+ return false;
+}
+
+bool EuclideanResection(const Mat &x_image,
+ const Mat3X &X_world,
+ const Mat3 &K,
+ Mat3 *R, Vec3 *t,
+ ResectionMethod method) {
+ CHECK(x_image.rows() == 2 || x_image.rows() == 3)
+ << "Invalid size for x_image: "
+ << x_image.rows() << "x" << x_image.cols();
+
+ Mat2X x_camera;
+ if (x_image.rows() == 2) {
+ EuclideanToNormalizedCamera(x_image, K, &x_camera);
+ } else if (x_image.rows() == 3) {
+ HomogeneousToNormalizedCamera(x_image, K, &x_camera);
+ }
+ return EuclideanResection(x_camera, X_world, R, t, method);
+}
+
+void AbsoluteOrientation(const Mat3X &X,
+ const Mat3X &Xp,
+ Mat3 *R,
+ Vec3 *t) {
+ int num_points = X.cols();
+ Vec3 C = X.rowwise().sum() / num_points; // Centroid of X.
+ Vec3 Cp = Xp.rowwise().sum() / num_points; // Centroid of Xp.
+
+ // Normalize the two point sets.
+ Mat3X Xn(3, num_points), Xpn(3, num_points);
+ for( int i = 0; i < num_points; ++i ){
+ Xn.col(i) = X.col(i) - C;
+ Xpn.col(i) = Xp.col(i) - Cp;
+ }
+
+ // Construct the N matrix (pg. 635).
+ double Sxx = Xn.row(0).dot(Xpn.row(0));
+ double Syy = Xn.row(1).dot(Xpn.row(1));
+ double Szz = Xn.row(2).dot(Xpn.row(2));
+ double Sxy = Xn.row(0).dot(Xpn.row(1));
+ double Syx = Xn.row(1).dot(Xpn.row(0));
+ double Sxz = Xn.row(0).dot(Xpn.row(2));
+ double Szx = Xn.row(2).dot(Xpn.row(0));
+ double Syz = Xn.row(1).dot(Xpn.row(2));
+ double Szy = Xn.row(2).dot(Xpn.row(1));
+
+ Mat4 N;
+ N << Sxx + Syy + Szz, Syz - Szy, Szx - Sxz, Sxy - Syx,
+ Syz - Szy, Sxx - Syy - Szz, Sxy + Syx, Szx + Sxz,
+ Szx - Sxz, Sxy + Syx, -Sxx + Syy - Szz, Syz + Szy,
+ Sxy - Syx, Szx + Sxz, Syz + Szy, -Sxx - Syy + Szz;
+
+ // Find the unit quaternion q that maximizes qNq. It is the eigenvector
+ // corresponding to the lagest eigenvalue.
+ Vec4 q = N.jacobiSvd(Eigen::ComputeFullU).matrixU().col(0);
+
+ // Retrieve the 3x3 rotation matrix.
+ Vec4 qq = q.array() * q.array();
+ double q0q1 = q(0) * q(1);
+ double q0q2 = q(0) * q(2);
+ double q0q3 = q(0) * q(3);
+ double q1q2 = q(1) * q(2);
+ double q1q3 = q(1) * q(3);
+ double q2q3 = q(2) * q(3);
+
+ (*R) << qq(0) + qq(1) - qq(2) - qq(3),
+ 2 * (q1q2 - q0q3),
+ 2 * (q1q3 + q0q2),
+ 2 * (q1q2+ q0q3),
+ qq(0) - qq(1) + qq(2) - qq(3),
+ 2 * (q2q3 - q0q1),
+ 2 * (q1q3 - q0q2),
+ 2 * (q2q3 + q0q1),
+ qq(0) - qq(1) - qq(2) + qq(3);
+
+ // Fix the handedness of the R matrix.
+ if (R->determinant() < 0) {
+ R->row(2) = -R->row(2);
+ }
+ // Compute the final translation.
+ *t = Cp - *R * C;
+}
+
+// Convert i and j indices of the original variables into their quadratic
+// permutation single index. It follows that t_ij = t_ji.
+static int IJToPointIndex(int i, int j, int num_points) {
+ // Always make sure that j is bigger than i. This handles t_ij = t_ji.
+ if (j < i) {
+ std::swap(i, j);
+ }
+ int idx;
+ int num_permutation_rows = num_points * (num_points - 1) / 2;
+
+ // All t_ii's are located at the end of the t vector after all t_ij's.
+ if (j == i) {
+ idx = num_permutation_rows + i;
+ } else {
+ int offset = (num_points - i - 1) * (num_points - i) / 2;
+ idx = (num_permutation_rows - offset + j - i - 1);
+ }
+ return idx;
+};
+
+// Convert i and j indexes of the solution for lambda to their linear indexes.
+static int IJToIndex(int i, int j, int num_lambda) {
+ if (j < i) {
+ std::swap(i, j);
+ }
+ int A = num_lambda * (num_lambda + 1) / 2;
+ int B = num_lambda - i;
+ int C = B * (B + 1) / 2;
+ int idx = A - C + j - i;
+ return idx;
+};
+
+static int Sign(double value) {
+ return (value < 0) ? -1 : 1;
+};
+
+// Organizes a square matrix into a single row constraint on the elements of
+// Lambda to create the constraints in equation (5) in "Linear Pose Estimation
+// from Points or Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no.
+// 5.
+static Vec MatrixToConstraint(const Mat &A,
+ int num_k_columns,
+ int num_lambda) {
+ Vec C(num_k_columns);
+ C.setZero();
+ int idx = 0;
+ for (int i = 0; i < num_lambda; ++i) {
+ for( int j = i; j < num_lambda; ++j) {
+ C(idx) = A(i, j);
+ if (i != j){
+ C(idx) += A(j, i);
+ }
+ ++ idx;
+ }
+ }
+ return C;
+}
+
+// Normalizes the columns of vectors.
+static void NormalizeColumnVectors(Mat3X *vectors) {
+ int num_columns = vectors->cols();
+ for (int i = 0; i < num_columns; ++i){
+ vectors->col(i).normalize();
+ }
+}
+
+void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R,
+ Vec3 *t) {
+ CHECK(x_camera.cols() == X_world.cols());
+ CHECK(x_camera.cols() > 3);
+
+ int num_points = x_camera.cols();
+
+ // Copy the normalized camera coords into 3 vectors and normalize them so
+ // that they are unit vectors from the camera center.
+ Mat3X x_camera_unit(3, num_points);
+ x_camera_unit.block(0, 0, 2, num_points) = x_camera;
+ x_camera_unit.row(2).setOnes();
+ NormalizeColumnVectors(&x_camera_unit);
+
+ int num_m_rows = num_points * (num_points - 1) / 2;
+ int num_tt_variables = num_points * (num_points + 1) / 2;
+ int num_m_columns = num_tt_variables + 1;
+ Mat M(num_m_columns, num_m_columns);
+ M.setZero();
+ Matu ij_index(num_tt_variables, 2);
+
+ // Create the constraint equations for the t_ij variables (7) and arrange
+ // them into the M matrix (8). Also store the initial (i, j) indices.
+ int row=0;
+ for (int i = 0; i < num_points; ++i) {
+ for (int j = i+1; j < num_points; ++j) {
+ M(row, row) = -2 * x_camera_unit.col(i).dot(x_camera_unit.col(j));
+ M(row, num_m_rows + i) = x_camera_unit.col(i).dot(x_camera_unit.col(i));
+ M(row, num_m_rows + j) = x_camera_unit.col(j).dot(x_camera_unit.col(j));
+ Vec3 Xdiff = X_world.col(i) - X_world.col(j);
+ double center_to_point_distance = Xdiff.norm();
+ M(row, num_m_columns - 1) =
+ - center_to_point_distance * center_to_point_distance;
+ ij_index(row, 0) = i;
+ ij_index(row, 1) = j;
+ ++row;
+ }
+ ij_index(i + num_m_rows, 0) = i;
+ ij_index(i + num_m_rows, 1) = i;
+ }
+
+ int num_lambda = num_points + 1; // Dimension of the null space of M.
+ Mat V = M.jacobiSvd(Eigen::ComputeFullV).matrixV().block(0,
+ num_m_rows,
+ num_m_columns,
+ num_lambda);
+
+ // TODO(vess): The number of constraint equations in K (num_k_rows) must be
+ // (num_points + 1) * (num_points + 2)/2. This creates a performance issue
+ // for more than 4 points. It is fine for 4 points at the moment with 18
+ // instead of 15 equations.
+ int num_k_rows = num_m_rows + num_points *
+ (num_points*(num_points-1)/2 - num_points+1);
+ int num_k_columns = num_lambda * (num_lambda + 1) / 2;
+ Mat K(num_k_rows, num_k_columns);
+ K.setZero();
+
+ // Construct the first part of the K matrix corresponding to (t_ii, t_jk) for
+ // i != j.
+ int counter_k_row = 0;
+ for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) {
+ for (int idx2 = 0; idx2 < num_m_rows; ++idx2) {
+
+ unsigned int i = ij_index(idx1, 0);
+ unsigned int j = ij_index(idx2, 0);
+ unsigned int k = ij_index(idx2, 1);
+
+ if( i != j && i != k ){
+ int idx3 = IJToPointIndex(i, j, num_points);
+ int idx4 = IJToPointIndex(i, k, num_points);
+
+ K.row(counter_k_row) =
+ MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)-
+ V.row(idx3).transpose() * V.row(idx4),
+ num_k_columns,
+ num_lambda);
+ ++counter_k_row;
+ }
+ }
+ }
+
+ // Construct the second part of the K matrix corresponding to (t_ii,t_jk) for
+ // j==k.
+ for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) {
+ for (int idx2 = idx1 + 1; idx2 < num_tt_variables; ++idx2) {
+ unsigned int i = ij_index(idx1, 0);
+ unsigned int j = ij_index(idx2, 0);
+ unsigned int k = ij_index(idx2, 1);
+
+ int idx3 = IJToPointIndex(i, j, num_points);
+ int idx4 = IJToPointIndex(i, k, num_points);
+
+ K.row(counter_k_row) =
+ MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)-
+ V.row(idx3).transpose() * V.row(idx4),
+ num_k_columns,
+ num_lambda);
+ ++counter_k_row;
+ }
+ }
+ Vec L_sq = K.jacobiSvd(Eigen::ComputeFullV).matrixV().col(num_k_columns - 1);
+
+ // Pivot on the largest element for numerical stability. Afterwards recover
+ // the sign of the lambda solution.
+ double max_L_sq_value = fabs(L_sq(IJToIndex(0, 0, num_lambda)));
+ int max_L_sq_index = 1;
+ for (int i = 1; i < num_lambda; ++i) {
+ double abs_sq_value = fabs(L_sq(IJToIndex(i, i, num_lambda)));
+ if (max_L_sq_value < abs_sq_value) {
+ max_L_sq_value = abs_sq_value;
+ max_L_sq_index = i;
+ }
+ }
+ // Ensure positiveness of the largest value corresponding to lambda_ii.
+ L_sq = L_sq * Sign(L_sq(IJToIndex(max_L_sq_index,
+ max_L_sq_index,
+ num_lambda)));
+
+
+ Vec L(num_lambda);
+ L(max_L_sq_index) = sqrt(L_sq(IJToIndex(max_L_sq_index,
+ max_L_sq_index,
+ num_lambda)));
+
+ for (int i = 0; i < num_lambda; ++i) {
+ if (i != max_L_sq_index) {
+ L(i) = L_sq(IJToIndex(max_L_sq_index, i, num_lambda)) / L(max_L_sq_index);
+ }
+ }
+
+ // Correct the scale using the fact that the last constraint is equal to 1.
+ L = L / (V.row(num_m_columns - 1).dot(L));
+ Vec X = V * L;
+
+ // Recover the distances from the camera center to the 3D points Q.
+ Vec d(num_points);
+ d.setZero();
+ for (int c_point = num_m_rows; c_point < num_tt_variables; ++c_point) {
+ d(c_point - num_m_rows) = sqrt(X(c_point));
+ }
+
+ // Create the 3D points in the camera system.
+ Mat X_cam(3, num_points);
+ for (int c_point = 0; c_point < num_points; ++c_point ) {
+ X_cam.col(c_point) = d(c_point) * x_camera_unit.col(c_point);
+ }
+ // Recover the camera translation and rotation.
+ AbsoluteOrientation(X_world, X_cam, R, t);
+}
+
+// Selects 4 virtual control points using mean and PCA.
+void SelectControlPoints(const Mat3X &X_world,
+ Mat *X_centered,
+ Mat34 *X_control_points) {
+ size_t num_points = X_world.cols();
+
+ // The first virtual control point, C0, is the centroid.
+ Vec mean, variance;
+ MeanAndVarianceAlongRows(X_world, &mean, &variance);
+ X_control_points->col(0) = mean;
+
+ // Computes PCA
+ X_centered->resize (3, num_points);
+ for (size_t c = 0; c < num_points; c++) {
+ X_centered->col(c) = X_world.col (c) - mean;
+ }
+ Mat3 X_centered_sq = (*X_centered) * X_centered->transpose();
+ Eigen::JacobiSVD<Mat3> X_centered_sq_svd(X_centered_sq, Eigen::ComputeFullU);
+ Vec3 w = X_centered_sq_svd.singularValues();
+ Mat3 u = X_centered_sq_svd.matrixU();
+ for (size_t c = 0; c < 3; c++) {
+ double k = sqrt (w (c) / num_points);
+ X_control_points->col (c + 1) = mean + k * u.col (c);
+ }
+}
+
+// Computes the barycentric coordinates for all real points
+void ComputeBarycentricCoordinates(const Mat3X &X_world_centered,
+ const Mat34 &X_control_points,
+ Mat4X *alphas) {
+ size_t num_points = X_world_centered.cols();
+ Mat3 C2 ;
+ for (size_t c = 1; c < 4; c++) {
+ C2.col(c-1) = X_control_points.col(c) - X_control_points.col(0);
+ }
+
+ Mat3 C2inv = C2.inverse();
+ Mat3X a = C2inv * X_world_centered;
+
+ alphas->resize(4, num_points);
+ alphas->setZero();
+ alphas->block(1, 0, 3, num_points) = a;
+ for (size_t c = 0; c < num_points; c++) {
+ (*alphas)(0, c) = 1.0 - alphas->col(c).sum();
+ }
+}
+
+// Estimates the coordinates of all real points in the camera coordinate frame
+void ComputePointsCoordinatesInCameraFrame(
+ const Mat4X &alphas,
+ const Vec4 &betas,
+ const Eigen::Matrix<double, 12, 12> &U,
+ Mat3X *X_camera) {
+ size_t num_points = alphas.cols();
+
+ // Estimates the control points in the camera reference frame.
+ Mat34 C2b; C2b.setZero();
+ for (size_t cu = 0; cu < 4; cu++) {
+ for (size_t c = 0; c < 4; c++) {
+ C2b.col(c) += betas(cu) * U.block(11 - cu, c * 3, 1, 3).transpose();
+ }
+ }
+
+ // Estimates the 3D points in the camera reference frame
+ X_camera->resize(3, num_points);
+ for (size_t c = 0; c < num_points; c++) {
+ X_camera->col(c) = C2b * alphas.col(c);
+ }
+
+ // Check the sign of the z coordinate of the points (should be positive)
+ uint num_z_neg = 0;
+ for (size_t i = 0; i < X_camera->cols(); ++i) {
+ if ((*X_camera)(2,i) < 0) {
+ num_z_neg++;
+ }
+ }
+
+ // If more than 50% of z are negative, we change the signs
+ if (num_z_neg > 0.5 * X_camera->cols()) {
+ C2b = -C2b;
+ *X_camera = -(*X_camera);
+ }
+}
+
+bool EuclideanResectionEPnP(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R, Vec3 *t) {
+ CHECK(x_camera.cols() == X_world.cols());
+ CHECK(x_camera.cols() > 3);
+ size_t num_points = X_world.cols();
+
+ // Select the control points.
+ Mat34 X_control_points;
+ Mat X_centered;
+ SelectControlPoints(X_world, &X_centered, &X_control_points);
+
+ // Compute the barycentric coordinates.
+ Mat4X alphas(4, num_points);
+ ComputeBarycentricCoordinates(X_centered, X_control_points, &alphas);
+
+ // Estimates the M matrix with the barycentric coordinates
+ Mat M(2 * num_points, 12);
+ Eigen::Matrix<double, 2, 12> sub_M;
+ for (size_t c = 0; c < num_points; c++) {
+ double a0 = alphas(0, c);
+ double a1 = alphas(1, c);
+ double a2 = alphas(2, c);
+ double a3 = alphas(3, c);
+ double ui = x_camera(0, c);
+ double vi = x_camera(1, c);
+ M.block(2*c, 0, 2, 12) << a0, 0,
+ a0*(-ui), a1, 0,
+ a1*(-ui), a2, 0,
+ a2*(-ui), a3, 0,
+ a3*(-ui), 0,
+ a0, a0*(-vi), 0,
+ a1, a1*(-vi), 0,
+ a2, a2*(-vi), 0,
+ a3, a3*(-vi);
+ }
+
+ // TODO(julien): Avoid the transpose by rewriting the u2.block() calls.
+ Eigen::JacobiSVD<Mat> MtMsvd(M.transpose()*M, Eigen::ComputeFullU);
+ Eigen::Matrix<double, 12, 12> u2 = MtMsvd.matrixU().transpose();
+
+ // Estimate the L matrix.
+ Eigen::Matrix<double, 6, 3> dv1;
+ Eigen::Matrix<double, 6, 3> dv2;
+ Eigen::Matrix<double, 6, 3> dv3;
+ Eigen::Matrix<double, 6, 3> dv4;
+
+ dv1.row(0) = u2.block(11, 0, 1, 3) - u2.block(11, 3, 1, 3);
+ dv1.row(1) = u2.block(11, 0, 1, 3) - u2.block(11, 6, 1, 3);
+ dv1.row(2) = u2.block(11, 0, 1, 3) - u2.block(11, 9, 1, 3);
+ dv1.row(3) = u2.block(11, 3, 1, 3) - u2.block(11, 6, 1, 3);
+ dv1.row(4) = u2.block(11, 3, 1, 3) - u2.block(11, 9, 1, 3);
+ dv1.row(5) = u2.block(11, 6, 1, 3) - u2.block(11, 9, 1, 3);
+ dv2.row(0) = u2.block(10, 0, 1, 3) - u2.block(10, 3, 1, 3);
+ dv2.row(1) = u2.block(10, 0, 1, 3) - u2.block(10, 6, 1, 3);
+ dv2.row(2) = u2.block(10, 0, 1, 3) - u2.block(10, 9, 1, 3);
+ dv2.row(3) = u2.block(10, 3, 1, 3) - u2.block(10, 6, 1, 3);
+ dv2.row(4) = u2.block(10, 3, 1, 3) - u2.block(10, 9, 1, 3);
+ dv2.row(5) = u2.block(10, 6, 1, 3) - u2.block(10, 9, 1, 3);
+ dv3.row(0) = u2.block( 9, 0, 1, 3) - u2.block( 9, 3, 1, 3);
+ dv3.row(1) = u2.block( 9, 0, 1, 3) - u2.block( 9, 6, 1, 3);
+ dv3.row(2) = u2.block( 9, 0, 1, 3) - u2.block( 9, 9, 1, 3);
+ dv3.row(3) = u2.block( 9, 3, 1, 3) - u2.block( 9, 6, 1, 3);
+ dv3.row(4) = u2.block( 9, 3, 1, 3) - u2.block( 9, 9, 1, 3);
+ dv3.row(5) = u2.block( 9, 6, 1, 3) - u2.block( 9, 9, 1, 3);
+ dv4.row(0) = u2.block( 8, 0, 1, 3) - u2.block( 8, 3, 1, 3);
+ dv4.row(1) = u2.block( 8, 0, 1, 3) - u2.block( 8, 6, 1, 3);
+ dv4.row(2) = u2.block( 8, 0, 1, 3) - u2.block( 8, 9, 1, 3);
+ dv4.row(3) = u2.block( 8, 3, 1, 3) - u2.block( 8, 6, 1, 3);
+ dv4.row(4) = u2.block( 8, 3, 1, 3) - u2.block( 8, 9, 1, 3);
+ dv4.row(5) = u2.block( 8, 6, 1, 3) - u2.block( 8, 9, 1, 3);
+
+ Eigen::Matrix<double, 6, 10> L;
+ for (size_t r = 0; r < 6; r++) {
+ L.row(r) << dv1.row(r).dot(dv1.row(r)),
+ 2.0 * dv1.row(r).dot(dv2.row(r)),
+ dv2.row(r).dot(dv2.row(r)),
+ 2.0 * dv1.row(r).dot(dv3.row(r)),
+ 2.0 * dv2.row(r).dot(dv3.row(r)),
+ dv3.row(r).dot(dv3.row(r)),
+ 2.0 * dv1.row(r).dot(dv4.row(r)),
+ 2.0 * dv2.row(r).dot(dv4.row(r)),
+ 2.0 * dv3.row(r).dot(dv4.row(r)),
+ dv4.row(r).dot(dv4.row(r));
+ }
+ Vec6 rho;
+ rho << (X_control_points.col(0) - X_control_points.col(1)).squaredNorm(),
+ (X_control_points.col(0) - X_control_points.col(2)).squaredNorm(),
+ (X_control_points.col(0) - X_control_points.col(3)).squaredNorm(),
+ (X_control_points.col(1) - X_control_points.col(2)).squaredNorm(),
+ (X_control_points.col(1) - X_control_points.col(3)).squaredNorm(),
+ (X_control_points.col(2) - X_control_points.col(3)).squaredNorm();
+
+ // There are three possible solutions based on the three approximations of L
+ // (betas). Below, each one is solved for then the best one is chosen.
+ Mat3X X_camera;
+ Mat3 K; K.setIdentity();
+ vector<Mat3> Rs(3);
+ vector<Vec3> ts(3);
+ Vec rmse(3);
+
+ // TODO(julien): Document where the "1e-3" magical constant comes from below.
+
+ // Find the first possible solution for R, t corresponding to:
+ // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
+ // Betas_approx_1 = [b00 b01 b02 b03]
+ Vec4 betas = Vec4::Zero();
+ Eigen::Matrix<double, 6, 4> l_6x4;
+ for (size_t r = 0; r < 6; r++) {
+ l_6x4.row(r) << L(r, 0), L(r, 1), L(r, 3), L(r, 6);
+ }
+ Eigen::JacobiSVD<Mat> svd_of_l4(l_6x4,
+ Eigen::ComputeFullU | Eigen::ComputeFullV);
+ Vec4 b4 = svd_of_l4.solve(rho);
+ if ((l_6x4 * b4).isApprox(rho, 1e-3)) {
+ if (b4(0) < 0) {
+ b4 = -b4;
+ }
+ b4(0) = std::sqrt(b4(0));
+ betas << b4(0), b4(1) / b4(0), b4(2) / b4(0), b4(3) / b4(0);
+ ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera);
+ AbsoluteOrientation(X_world, X_camera, &Rs[0], &ts[0]);
+ rmse(0) = RootMeanSquareError(x_camera, X_world, K, Rs[0], ts[0]);
+ } else {
+ LOG(ERROR) << "First approximation of beta not good enough.";
+ ts[0].setZero();
+ rmse(0) = std::numeric_limits<double>::max();
+ }
+
+ // Find the second possible solution for R, t corresponding to:
+ // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
+ // Betas_approx_2 = [b00 b01 b11]
+ betas.setZero();
+ Eigen::Matrix<double, 6, 3> l_6x3;
+ l_6x3 = L.block(0, 0, 6, 3);
+ Eigen::JacobiSVD<Mat> svdOfL3(l_6x3,
+ Eigen::ComputeFullU | Eigen::ComputeFullV);
+ Vec3 b3 = svdOfL3.solve(rho);
+ VLOG(2) << " rho = " << rho;
+ VLOG(2) << " l_6x3 * b3 = " << l_6x3 * b3;
+ if ((l_6x3 * b3).isApprox(rho, 1e-3)) {
+ if (b3(0) < 0) {
+ betas(0) = std::sqrt(-b3(0));
+ betas(1) = (b3(2) < 0) ? std::sqrt(-b3(2)) : 0;
+ } else {
+ betas(0) = std::sqrt(b3(0));
+ betas(1) = (b3(2) > 0) ? std::sqrt(b3(2)) : 0;
+ }
+ if (b3(1) < 0) {
+ betas(0) = -betas(0);
+ }
+ betas(2) = 0;
+ betas(3) = 0;
+ ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera);
+ AbsoluteOrientation(X_world, X_camera, &Rs[1], &ts[1]);
+ rmse(1) = RootMeanSquareError(x_camera, X_world, K, Rs[1], ts[1]);
+ } else {
+ LOG(ERROR) << "Second approximation of beta not good enough.";
+ ts[1].setZero();
+ rmse(1) = std::numeric_limits<double>::max();
+ }
+
+ // Find the third possible solution for R, t corresponding to:
+ // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
+ // Betas_approx_3 = [b00 b01 b11 b02 b12]
+ betas.setZero();
+ Eigen::Matrix<double, 6, 5> l_6x5;
+ l_6x5 = L.block(0, 0, 6, 5);
+ Eigen::JacobiSVD<Mat> svdOfL5(l_6x5,
+ Eigen::ComputeFullU | Eigen::ComputeFullV);
+ Vec5 b5 = svdOfL5.solve(rho);
+ if ((l_6x5 * b5).isApprox(rho, 1e-3)) {
+ if (b5(0) < 0) {
+ betas(0) = std::sqrt(-b5(0));
+ if (b5(2) < 0) {
+ betas(1) = std::sqrt(-b5(2));
+ } else {
+ b5(2) = 0;
+ }
+ } else {
+ betas(0) = std::sqrt(b5(0));
+ if (b5(2) > 0) {
+ betas(1) = std::sqrt(b5(2));
+ } else {
+ b5(2) = 0;
+ }
+ }
+ if (b5(1) < 0) {
+ betas(0) = -betas(0);
+ }
+ betas(2) = b5(3) / betas(0);
+ betas(3) = 0;
+ ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera);
+ AbsoluteOrientation(X_world, X_camera, &Rs[2], &ts[2]);
+ rmse(2) = RootMeanSquareError(x_camera, X_world, K, Rs[2], ts[2]);
+ } else {
+ LOG(ERROR) << "Third approximation of beta not good enough.";
+ ts[2].setZero();
+ rmse(2) = std::numeric_limits<double>::max();
+ }
+
+ // Finally, with all three solutions, select the (R, t) with the best RMSE.
+ VLOG(2) << "RMSE for solution 0: " << rmse(0);
+ VLOG(2) << "RMSE for solution 1: " << rmse(0);
+ VLOG(2) << "RMSE for solution 2: " << rmse(0);
+ size_t n = 0;
+ if (rmse(1) < rmse(0)) {
+ n = 1;
+ }
+ if (rmse(2) < rmse(n)) {
+ n = 2;
+ }
+ if (rmse(n) == std::numeric_limits<double>::max()) {
+ LOG(ERROR) << "All three possibilities failed. Reporting failure.";
+ return false;
+ }
+
+ VLOG(1) << "RMSE for best solution #" << n << ": " << rmse(n);
+ *R = Rs[n];
+ *t = ts[n];
+
+ // TODO(julien): Improve the solutions with non-linear refinement.
+ return true;
+}
+
+} // namespace resection
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/euclidean_resection.h b/extern/libmv/libmv/multiview/euclidean_resection.h
new file mode 100644
index 00000000000..08fa3d90bd3
--- /dev/null
+++ b/extern/libmv/libmv/multiview/euclidean_resection.h
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_
+#define LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/multiview/projection.h"
+
+namespace libmv {
+namespace euclidean_resection {
+
+enum ResectionMethod {
+ RESECTION_ANSAR_DANIILIDIS,
+ RESECTION_EPNP,
+};
+
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera
+ * from 4 or more 3D points and their normalized images.
+ *
+ * \param x_camera Image points in normalized camera coordinates e.g. x_camera
+ * = inv(K) * x_image.
+ * \param X_world 3D points in the world coordinate system
+ * \param R Solution for the camera rotation matrix
+ * \param t Solution for the camera translation vector
+ * \param method The resection method to use.
+ */
+bool EuclideanResection(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R, Vec3 *t,
+ ResectionMethod method = RESECTION_EPNP);
+
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera
+ * from 4 or more 3D points and their images.
+ *
+ * \param x_image Image points in non-normalized image coordinates. The
+ * coordates are laid out one per row. The matrix can be Nx2
+ * or Nx3 for euclidean or homogenous 2D coordinates.
+ * \param X_world 3D points in the world coordinate system
+ * \param K Intrinsic parameters camera matrix
+ * \param R Solution for the camera rotation matrix
+ * \param t Solution for the camera translation vector
+ * \param method Resection method
+ */
+bool EuclideanResection(const Mat &x_image,
+ const Mat3X &X_world,
+ const Mat3 &K,
+ Mat3 *R, Vec3 *t,
+ ResectionMethod method = RESECTION_EPNP);
+
+/**
+ * The absolute orientation algorithm recovers the transformation between a set
+ * of 3D points, X and Xp such that:
+ *
+ * Xp = R*X + t
+ *
+ * The recovery of the absolute orientation is implemented after this article:
+ * Horn, Hilden, "Closed-form solution of absolute orientation using
+ * orthonormal matrices"
+ */
+void AbsoluteOrientation(const Mat3X &X,
+ const Mat3X &Xp,
+ Mat3 *R,
+ Vec3 *t);
+
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or
+ * more 3D points and their images.
+ *
+ * \param x_camera Image points in normalized camera coordinates, e.g.
+ * x_camera=inv(K)*x_image
+ * \param X_world 3D points in the world coordinate system
+ * \param R Solution for the camera rotation matrix
+ * \param t Solution for the camera translation vector
+ *
+ * This is the algorithm described in: "Linear Pose Estimation from Points or
+ * Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no. 5.
+ */
+void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R, Vec3 *t);
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or
+ * more 3D points and their images.
+ *
+ * \param x_camera Image points in normalized camera coordinates,
+ * e.g. x_camera = inv(K) * x_image
+ * \param X_world 3D points in the world coordinate system
+ * \param R Solution for the camera rotation matrix
+ * \param t Solution for the camera translation vector
+ *
+ * This is the algorithm described in:
+ * "{EP$n$P: An Accurate $O(n)$ Solution to the P$n$P Problem", by V. Lepetit
+ * and F. Moreno-Noguer and P. Fua, IJCV 2009. vol. 81, no. 2
+ * \note: the non-linear optimization is not implemented here.
+ */
+bool EuclideanResectionEPnP(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R, Vec3 *t);
+
+} // namespace euclidean_resection
+} // namespace libmv
+
+
+#endif /* LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ */
diff --git a/extern/libmv/libmv/multiview/fundamental.cc b/extern/libmv/libmv/multiview/fundamental.cc
new file mode 100644
index 00000000000..7a6b4a08439
--- /dev/null
+++ b/extern/libmv/libmv/multiview/fundamental.cc
@@ -0,0 +1,391 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/logging/logging.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/poly.h"
+#include "libmv/multiview/conditioning.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/multiview/triangulation.h"
+#include "libmv/multiview/fundamental.h"
+
+namespace libmv {
+
+void EliminateRow(const Mat34 &P, int row, Mat *X) {
+ X->resize(2, 4);
+
+ int first_row = (row + 1) % 3;
+ int second_row = (row + 2) % 3;
+
+ for (int i = 0; i < 4; ++i) {
+ (*X)(0, i) = P(first_row, i);
+ (*X)(1, i) = P(second_row, i);
+ }
+}
+
+void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2) {
+ *P1 << Mat3::Identity(), Vec3::Zero();
+ Vec3 e2;
+ Mat3 Ft = F.transpose();
+ Nullspace(&Ft, &e2);
+ *P2 << CrossProductMatrix(e2) * F, e2;
+}
+
+// Addapted from vgg_F_from_P.
+void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F) {
+ Mat X[3];
+ Mat Y[3];
+ Mat XY;
+
+ for (int i = 0; i < 3; ++i) {
+ EliminateRow(P1, i, X + i);
+ EliminateRow(P2, i, Y + i);
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ VerticalStack(X[j], Y[i], &XY);
+ (*F)(i, j) = XY.determinant();
+ }
+ }
+}
+
+// HZ 11.1 pag.279 (x1 = x, x2 = x')
+// http://www.cs.unc.edu/~marc/tutorial/node54.html
+double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F) {
+ DCHECK_EQ(x1.rows(), 2);
+ DCHECK_GE(x1.cols(), 8);
+ DCHECK_EQ(x1.rows(), x2.rows());
+ DCHECK_EQ(x1.cols(), x2.cols());
+
+ int n = x1.cols();
+ Mat A(n, 9);
+ for (int i = 0; i < n; ++i) {
+ A(i, 0) = x2(0, i) * x1(0, i);
+ A(i, 1) = x2(0, i) * x1(1, i);
+ A(i, 2) = x2(0, i);
+ A(i, 3) = x2(1, i) * x1(0, i);
+ A(i, 4) = x2(1, i) * x1(1, i);
+ A(i, 5) = x2(1, i);
+ A(i, 6) = x1(0, i);
+ A(i, 7) = x1(1, i);
+ A(i, 8) = 1;
+ }
+
+ Vec9 f;
+ double smaller_singular_value = Nullspace(&A, &f);
+ *F = Map<RMat3>(f.data());
+ return smaller_singular_value;
+}
+
+// HZ 11.1.1 pag.280
+void EnforceFundamentalRank2Constraint(Mat3 *F) {
+ Eigen::JacobiSVD<Mat3> USV(*F, Eigen::ComputeFullU | Eigen::ComputeFullV);
+ Vec3 d = USV.singularValues();
+ d(2) = 0.0;
+ *F = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose();
+}
+
+// HZ 11.2 pag.281 (x1 = x, x2 = x')
+double NormalizedEightPointSolver(const Mat &x1,
+ const Mat &x2,
+ Mat3 *F) {
+ DCHECK_EQ(x1.rows(), 2);
+ DCHECK_GE(x1.cols(), 8);
+ DCHECK_EQ(x1.rows(), x2.rows());
+ DCHECK_EQ(x1.cols(), x2.cols());
+
+ // Normalize the data.
+ Mat3 T1, T2;
+ PreconditionerFromPoints(x1, &T1);
+ PreconditionerFromPoints(x2, &T2);
+ Mat x1_normalized, x2_normalized;
+ ApplyTransformationToPoints(x1, T1, &x1_normalized);
+ ApplyTransformationToPoints(x2, T2, &x2_normalized);
+
+ // Estimate the fundamental matrix.
+ double smaller_singular_value =
+ EightPointSolver(x1_normalized, x2_normalized, F);
+ EnforceFundamentalRank2Constraint(F);
+
+ // Denormalize the fundamental matrix.
+ *F = T2.transpose() * (*F) * T1;
+
+ return smaller_singular_value;
+}
+
+// Seven-point algorithm.
+// http://www.cs.unc.edu/~marc/tutorial/node55.html
+double FundamentalFrom7CorrespondencesLinear(const Mat &x1,
+ const Mat &x2,
+ std::vector<Mat3> *F) {
+ DCHECK_EQ(x1.rows(), 2);
+ DCHECK_EQ(x1.cols(), 7);
+ DCHECK_EQ(x1.rows(), x2.rows());
+ DCHECK_EQ(x2.cols(), x2.cols());
+
+ // Build a 9 x n matrix from point matches, where each row is equivalent to
+ // the equation x'T*F*x = 0 for a single correspondence pair (x', x). The
+ // domain of the matrix is a 9 element vector corresponding to F. The
+ // nullspace should be rank two; the two dimensions correspond to the set of
+ // F matrices satisfying the epipolar geometry.
+ Matrix<double, 7, 9> A;
+ for (int ii = 0; ii < 7; ++ii) {
+ A(ii, 0) = x1(0, ii) * x2(0, ii); // 0 represents x coords,
+ A(ii, 1) = x1(1, ii) * x2(0, ii); // 1 represents y coords.
+ A(ii, 2) = x2(0, ii);
+ A(ii, 3) = x1(0, ii) * x2(1, ii);
+ A(ii, 4) = x1(1, ii) * x2(1, ii);
+ A(ii, 5) = x2(1, ii);
+ A(ii, 6) = x1(0, ii);
+ A(ii, 7) = x1(1, ii);
+ A(ii, 8) = 1.0;
+ }
+
+ // Find the two F matrices in the nullspace of A.
+ Vec9 f1, f2;
+ double s = Nullspace2(&A, &f1, &f2);
+ Mat3 F1 = Map<RMat3>(f1.data());
+ Mat3 F2 = Map<RMat3>(f2.data());
+
+ // Then, use the condition det(F) = 0 to determine F. In other words, solve
+ // det(F1 + a*F2) = 0 for a.
+ double a = F1(0, 0), j = F2(0, 0),
+ b = F1(0, 1), k = F2(0, 1),
+ c = F1(0, 2), l = F2(0, 2),
+ d = F1(1, 0), m = F2(1, 0),
+ e = F1(1, 1), n = F2(1, 1),
+ f = F1(1, 2), o = F2(1, 2),
+ g = F1(2, 0), p = F2(2, 0),
+ h = F1(2, 1), q = F2(2, 1),
+ i = F1(2, 2), r = F2(2, 2);
+
+ // Run fundamental_7point_coeffs.py to get the below coefficients.
+ // The coefficients are in ascending powers of alpha, i.e. P[N]*x^N.
+ double P[4] = {
+ a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g,
+ a*e*r + a*i*n + b*f*p + b*g*o + c*d*q + c*h*m + d*h*l + e*i*j + f*g*k -
+ a*f*q - a*h*o - b*d*r - b*i*m - c*e*p - c*g*n - d*i*k - e*g*l - f*h*j,
+ a*n*r + b*o*p + c*m*q + d*l*q + e*j*r + f*k*p + g*k*o + h*l*m + i*j*n -
+ a*o*q - b*m*r - c*n*p - d*k*r - e*l*p - f*j*q - g*l*n - h*j*o - i*k*m,
+ j*n*r + k*o*p + l*m*q - j*o*q - k*m*r - l*n*p,
+ };
+
+ // Solve for the roots of P[3]*x^3 + P[2]*x^2 + P[1]*x + P[0] = 0.
+ double roots[3];
+ int num_roots = SolveCubicPolynomial(P, roots);
+
+ // Build the fundamental matrix for each solution.
+ for (int kk = 0; kk < num_roots; ++kk) {
+ F->push_back(F1 + roots[kk] * F2);
+ }
+ return s;
+}
+
+double FundamentalFromCorrespondences7Point(const Mat &x1,
+ const Mat &x2,
+ std::vector<Mat3> *F) {
+ DCHECK_EQ(x1.rows(), 2);
+ DCHECK_GE(x1.cols(), 7);
+ DCHECK_EQ(x1.rows(), x2.rows());
+ DCHECK_EQ(x1.cols(), x2.cols());
+
+ // Normalize the data.
+ Mat3 T1, T2;
+ PreconditionerFromPoints(x1, &T1);
+ PreconditionerFromPoints(x2, &T2);
+ Mat x1_normalized, x2_normalized;
+ ApplyTransformationToPoints(x1, T1, &x1_normalized);
+ ApplyTransformationToPoints(x2, T2, &x2_normalized);
+
+ // Estimate the fundamental matrix.
+ double smaller_singular_value =
+ FundamentalFrom7CorrespondencesLinear(x1_normalized, x2_normalized, &(*F));
+
+ for (int k = 0; k < F->size(); ++k) {
+ Mat3 & Fmat = (*F)[k];
+ // Denormalize the fundamental matrix.
+ Fmat = T2.transpose() * Fmat * T1;
+ }
+ return smaller_singular_value;
+}
+
+void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized) {
+ *F_normalized = F / FrobeniusNorm(F);
+ if ((*F_normalized)(2, 2) < 0) {
+ *F_normalized *= -1;
+ }
+}
+
+double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) {
+ Vec3 x(x1(0), x1(1), 1.0);
+ Vec3 y(x2(0), x2(1), 1.0);
+
+ Vec3 F_x = F * x;
+ Vec3 Ft_y = F.transpose() * y;
+ double y_F_x = y.dot(F_x);
+
+ return Square(y_F_x) / ( F_x.head<2>().squaredNorm()
+ + Ft_y.head<2>().squaredNorm());
+}
+
+double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) {
+ Vec3 x(x1(0), x1(1), 1.0);
+ Vec3 y(x2(0), x2(1), 1.0);
+
+ Vec3 F_x = F * x;
+ Vec3 Ft_y = F.transpose() * y;
+ double y_F_x = y.dot(F_x);
+
+ return Square(y_F_x) * ( 1 / F_x.head<2>().squaredNorm()
+ + 1 / Ft_y.head<2>().squaredNorm());
+}
+
+// HZ 9.6 pag 257 (formula 9.12)
+void EssentialFromFundamental(const Mat3 &F,
+ const Mat3 &K1,
+ const Mat3 &K2,
+ Mat3 *E) {
+ *E = K2.transpose() * F * K1;
+}
+
+// HZ 9.6 pag 257 (formula 9.12)
+// Or http://ai.stanford.edu/~birch/projective/node20.html
+void FundamentalFromEssential(const Mat3 &E,
+ const Mat3 &K1,
+ const Mat3 &K2,
+ Mat3 *F) {
+ *F = K2.inverse().transpose() * E * K1.inverse();
+}
+
+void RelativeCameraMotion(const Mat3 &R1,
+ const Vec3 &t1,
+ const Mat3 &R2,
+ const Vec3 &t2,
+ Mat3 *R,
+ Vec3 *t) {
+ *R = R2 * R1.transpose();
+ *t = t2 - (*R) * t1;
+}
+
+// HZ 9.6 pag 257
+void EssentialFromRt(const Mat3 &R1,
+ const Vec3 &t1,
+ const Mat3 &R2,
+ const Vec3 &t2,
+ Mat3 *E) {
+ Mat3 R;
+ Vec3 t;
+ RelativeCameraMotion(R1, t1, R2, t2, &R, &t);
+ Mat3 Tx = CrossProductMatrix(t);
+ *E = Tx * R;
+}
+
+// HZ 9.6 pag 259 (Result 9.19)
+void MotionFromEssential(const Mat3 &E,
+ std::vector<Mat3> *Rs,
+ std::vector<Vec3> *ts) {
+ Eigen::JacobiSVD<Mat3> USV(E, Eigen::ComputeFullU | Eigen::ComputeFullV);
+ Mat3 U = USV.matrixU();
+ Vec3 d = USV.singularValues();
+ Mat3 Vt = USV.matrixV().transpose();
+
+ // Last column of U is undetermined since d = (a a 0).
+ if (U.determinant() < 0) {
+ U.col(2) *= -1;
+ }
+ // Last row of Vt is undetermined since d = (a a 0).
+ if (Vt.determinant() < 0) {
+ Vt.row(2) *= -1;
+ }
+
+ Mat3 W;
+ W << 0, -1, 0,
+ 1, 0, 0,
+ 0, 0, 1;
+
+ Mat3 U_W_Vt = U * W * Vt;
+ Mat3 U_Wt_Vt = U * W.transpose() * Vt;
+
+ Rs->resize(4);
+ (*Rs)[0] = U_W_Vt;
+ (*Rs)[1] = U_W_Vt;
+ (*Rs)[2] = U_Wt_Vt;
+ (*Rs)[3] = U_Wt_Vt;
+
+ ts->resize(4);
+ (*ts)[0] = U.col(2);
+ (*ts)[1] = -U.col(2);
+ (*ts)[2] = U.col(2);
+ (*ts)[3] = -U.col(2);
+}
+
+int MotionFromEssentialChooseSolution(const std::vector<Mat3> &Rs,
+ const std::vector<Vec3> &ts,
+ const Mat3 &K1,
+ const Vec2 &x1,
+ const Mat3 &K2,
+ const Vec2 &x2) {
+ DCHECK_EQ(4, Rs.size());
+ DCHECK_EQ(4, ts.size());
+
+ Mat34 P1, P2;
+ Mat3 R1;
+ Vec3 t1;
+ R1.setIdentity();
+ t1.setZero();
+ P_From_KRt(K1, R1, t1, &P1);
+ for (int i = 0; i < 4; ++i) {
+ const Mat3 &R2 = Rs[i];
+ const Vec3 &t2 = ts[i];
+ P_From_KRt(K2, R2, t2, &P2);
+ Vec3 X;
+ TriangulateDLT(P1, x1, P2, x2, &X);
+ double d1 = Depth(R1, t1, X);
+ double d2 = Depth(R2, t2, X);
+ // Test if point is front to the two cameras.
+ if (d1 > 0 && d2 > 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool MotionFromEssentialAndCorrespondence(const Mat3 &E,
+ const Mat3 &K1,
+ const Vec2 &x1,
+ const Mat3 &K2,
+ const Vec2 &x2,
+ Mat3 *R,
+ Vec3 *t) {
+ std::vector<Mat3> Rs;
+ std::vector<Vec3> ts;
+ MotionFromEssential(E, &Rs, &ts);
+ int solution = MotionFromEssentialChooseSolution(Rs, ts, K1, x1, K2, x2);
+ if (solution >= 0) {
+ *R = Rs[solution];
+ *t = ts[solution];
+ return true;
+ } else {
+ return false;
+ }
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/fundamental.h b/extern/libmv/libmv/multiview/fundamental.h
new file mode 100644
index 00000000000..3f4a3b7b211
--- /dev/null
+++ b/extern/libmv/libmv/multiview/fundamental.h
@@ -0,0 +1,144 @@
+// Copyright (c) 2007, 2008, 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_FUNDAMENTAL_H_
+#define LIBMV_MULTIVIEW_FUNDAMENTAL_H_
+
+#include <vector>
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2);
+void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F);
+
+/**
+ * The normalized 8-point fundamental matrix solver.
+ */
+double NormalizedEightPointSolver(const Mat &x1,
+ const Mat &x2,
+ Mat3 *F);
+
+/**
+ * 7 points (minimal case, points coordinates must be normalized before):
+ */
+double FundamentalFrom7CorrespondencesLinear(const Mat &x1,
+ const Mat &x2,
+ std::vector<Mat3> *F);
+
+/**
+ * 7 points (points coordinates must be in image space):
+ */
+double FundamentalFromCorrespondences7Point(const Mat &x1,
+ const Mat &x2,
+ std::vector<Mat3> *F);
+
+/**
+ * 8 points (points coordinates must be in image space):
+ */
+double NormalizedEightPointSolver(const Mat &x1,
+ const Mat &x2,
+ Mat3 *F);
+
+/**
+ * Fundamental matrix utility function:
+ */
+void EnforceFundamentalRank2Constraint(Mat3 *F);
+
+void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized);
+
+/**
+ * Approximate squared reprojection errror.
+ *
+ * See page 287 of HZ equation 11.9. This avoids triangulating the point,
+ * relying only on the entries in F.
+ */
+double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2);
+
+/**
+ * Calculates the sum of the distances from the points to the epipolar lines.
+ *
+ * See page 288 of HZ equation 11.10.
+ */
+double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2);
+
+/**
+ * Compute the relative camera motion between two cameras.
+ *
+ * Given the motion parameters of two cameras, computes the motion parameters
+ * of the second one assuming the first one to be at the origin.
+ * If T1 and T2 are the camera motions, the computed relative motion is
+ * T = T2 T1^{-1}
+ */
+void RelativeCameraMotion(const Mat3 &R1,
+ const Vec3 &t1,
+ const Mat3 &R2,
+ const Vec3 &t2,
+ Mat3 *R,
+ Vec3 *t);
+
+void EssentialFromFundamental(const Mat3 &F,
+ const Mat3 &K1,
+ const Mat3 &K2,
+ Mat3 *E);
+
+void FundamentalFromEssential(const Mat3 &E,
+ const Mat3 &K1,
+ const Mat3 &K2,
+ Mat3 *F);
+
+void EssentialFromRt(const Mat3 &R1,
+ const Vec3 &t1,
+ const Mat3 &R2,
+ const Vec3 &t2,
+ Mat3 *E);
+
+void MotionFromEssential(const Mat3 &E,
+ std::vector<Mat3> *Rs,
+ std::vector<Vec3> *ts);
+
+/**
+ * Choose one of the four possible motion solutions from an essential matrix.
+ *
+ * Decides the right solution by checking that the triangulation of a match
+ * x1--x2 lies in front of the cameras. See HZ 9.6 pag 259 (9.6.3 Geometrical
+ * interpretation of the 4 solutions)
+ *
+ * \return index of the right solution or -1 if no solution.
+ */
+int MotionFromEssentialChooseSolution(const std::vector<Mat3> &Rs,
+ const std::vector<Vec3> &ts,
+ const Mat3 &K1,
+ const Vec2 &x1,
+ const Mat3 &K2,
+ const Vec2 &x2);
+
+bool MotionFromEssentialAndCorrespondence(const Mat3 &E,
+ const Mat3 &K1,
+ const Vec2 &x1,
+ const Mat3 &K2,
+ const Vec2 &x2,
+ Mat3 *R,
+ Vec3 *t);
+
+} // namespace libmv
+
+#endif // LIBMV_MULTIVIEW_FUNDAMENTAL_H_
diff --git a/extern/libmv/libmv/multiview/nviewtriangulation.h b/extern/libmv/libmv/multiview/nviewtriangulation.h
new file mode 100644
index 00000000000..b4f521f185d
--- /dev/null
+++ b/extern/libmv/libmv/multiview/nviewtriangulation.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Compute a 3D position of a point from several images of it. In particular,
+// compute the projective point X in R^4 such that x = PX.
+//
+// Algorithm is the standard DLT; for derivation see appendix of Keir's thesis.
+
+#ifndef LIBMV_MULTIVIEW_NVIEWTRIANGULATION_H
+#define LIBMV_MULTIVIEW_NVIEWTRIANGULATION_H
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+// x's are 2D coordinates (x,y,1) in each image; Ps are projective cameras. The
+// output, X, is a homogeneous four vectors.
+template<typename T>
+void NViewTriangulate(const Matrix<T, 2, Dynamic> &x,
+ const vector<Matrix<T, 3, 4> > &Ps,
+ Matrix<T, 4, 1> *X) {
+ int nviews = x.cols();
+ assert(nviews == Ps.size());
+
+ Matrix<T, Dynamic, Dynamic> design(3*nviews, 4 + nviews);
+ design.setConstant(0.0);
+ for (int i = 0; i < nviews; i++) {
+ design.template block<3, 4>(3*i, 0) = -Ps[i];
+ design(3*i + 0, 4 + i) = x(0, i);
+ design(3*i + 1, 4 + i) = x(1, i);
+ design(3*i + 2, 4 + i) = 1.0;
+ }
+ Matrix<T, Dynamic, 1> X_and_alphas;
+ Nullspace(&design, &X_and_alphas);
+ X->resize(4);
+ *X = X_and_alphas.head(4);
+}
+
+// x's are 2D coordinates (x,y,1) in each image; Ps are projective cameras. The
+// output, X, is a homogeneous four vectors.
+// This method uses the algebraic distance approximation.
+// Note that this method works better when the 2D points are normalized
+// with an isotopic normalization.
+template<typename T>
+void NViewTriangulateAlgebraic(const Matrix<T, 2, Dynamic> &x,
+ const vector<Matrix<T, 3, 4> > &Ps,
+ Matrix<T, 4, 1> *X) {
+ int nviews = x.cols();
+ assert(nviews == Ps.size());
+
+ Matrix<T, Dynamic, 4> design(2*nviews, 4);
+ for (int i = 0; i < nviews; i++) {
+ design.template block<2, 4>(2*i, 0) = SkewMatMinimal(x.col(i)) * Ps[i];
+ }
+ X->resize(4);
+ Nullspace(&design, X);
+}
+
+} // namespace libmv
+
+#endif // LIBMV_MULTIVIEW_RESECTION_H
diff --git a/extern/libmv/libmv/multiview/projection.cc b/extern/libmv/libmv/multiview/projection.cc
new file mode 100644
index 00000000000..a7d1a058e9c
--- /dev/null
+++ b/extern/libmv/libmv/multiview/projection.cc
@@ -0,0 +1,221 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/multiview/projection.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P) {
+ P->block<3, 3>(0, 0) = R;
+ P->col(3) = t;
+ (*P) = K * (*P);
+}
+
+void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) {
+ // Decompose using the RQ decomposition HZ A4.1.1 pag.579.
+ Mat3 K = P.block(0, 0, 3, 3);
+
+ Mat3 Q;
+ Q.setIdentity();
+
+ // Set K(2,1) to zero.
+ if (K(2, 1) != 0) {
+ double c = -K(2,2);
+ double s = K(2,1);
+ double l = sqrt(c * c + s * s);
+ c /= l; s /= l;
+ Mat3 Qx;
+ Qx << 1, 0, 0,
+ 0, c, -s,
+ 0, s, c;
+ K = K * Qx;
+ Q = Qx.transpose() * Q;
+ }
+ // Set K(2,0) to zero.
+ if (K(2, 0) != 0) {
+ double c = K(2, 2);
+ double s = K(2, 0);
+ double l = sqrt(c * c + s * s);
+ c /= l; s /= l;
+ Mat3 Qy;
+ Qy << c, 0, s,
+ 0, 1, 0,
+ -s, 0, c;
+ K = K * Qy;
+ Q = Qy.transpose() * Q;
+ }
+ // Set K(1,0) to zero.
+ if (K(1, 0) != 0) {
+ double c = -K(1, 1);
+ double s = K(1, 0);
+ double l = sqrt(c * c + s * s);
+ c /= l; s /= l;
+ Mat3 Qz;
+ Qz << c,-s, 0,
+ s, c, 0,
+ 0, 0, 1;
+ K = K * Qz;
+ Q = Qz.transpose() * Q;
+ }
+
+ Mat3 R = Q;
+
+ // Ensure that the diagonal is positive.
+ // TODO(pau) Change this to ensure that:
+ // - K(0,0) > 0
+ // - K(2,2) = 1
+ // - det(R) = 1
+ if (K(2,2) < 0) {
+ K = -K;
+ R = -R;
+ }
+ if (K(1,1) < 0) {
+ Mat3 S;
+ S << 1, 0, 0,
+ 0,-1, 0,
+ 0, 0, 1;
+ K = K * S;
+ R = S * R;
+ }
+ if (K(0,0) < 0) {
+ Mat3 S;
+ S << -1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1;
+ K = K * S;
+ R = S * R;
+ }
+
+ // Compute translation.
+ Vec p(3);
+ p << P(0,3), P(1,3), P(2,3);
+ // TODO(pau) This sould be done by a SolveLinearSystem(A, b, &x) call.
+ // TODO(keir) use the eigen LU solver syntax...
+ Vec3 t = K.inverse() * p;
+
+ // scale K so that K(2,2) = 1
+ K = K / K(2,2);
+
+ *Kp = K;
+ *Rp = R;
+ *tp = t;
+}
+
+void ProjectionShiftPrincipalPoint(const Mat34 &P,
+ const Vec2 &principal_point,
+ const Vec2 &principal_point_new,
+ Mat34 *P_new) {
+ Mat3 T;
+ T << 1, 0, principal_point_new(0) - principal_point(0),
+ 0, 1, principal_point_new(1) - principal_point(1),
+ 0, 0, 1;
+ *P_new = T * P;
+}
+
+void ProjectionChangeAspectRatio(const Mat34 &P,
+ const Vec2 &principal_point,
+ double aspect_ratio,
+ double aspect_ratio_new,
+ Mat34 *P_new) {
+ Mat3 T;
+ T << 1, 0, 0,
+ 0, aspect_ratio_new / aspect_ratio, 0,
+ 0, 0, 1;
+ Mat34 P_temp;
+
+ ProjectionShiftPrincipalPoint(P, principal_point, Vec2(0,0), &P_temp);
+ P_temp = T * P_temp;
+ ProjectionShiftPrincipalPoint(P_temp, Vec2(0,0), principal_point, P_new);
+}
+
+void HomogeneousToEuclidean(const Mat &H, Mat *X) {
+ int d = H.rows() - 1;
+ int n = H.cols();
+ X->resize(d, n);
+ for (size_t i = 0; i < n; ++i) {
+ double h = H(d, i);
+ for (int j = 0; j < d; ++j) {
+ (*X)(j, i) = H(j, i) / h;
+ }
+ }
+}
+
+void HomogeneousToEuclidean(const Mat3X &h, Mat2X *e) {
+ e->resize(2, h.cols());
+ e->row(0) = h.row(0).array() / h.row(2).array();
+ e->row(1) = h.row(1).array() / h.row(2).array();
+}
+void HomogeneousToEuclidean(const Mat4X &h, Mat3X *e) {
+ e->resize(3, h.cols());
+ e->row(0) = h.row(0).array() / h.row(3).array();
+ e->row(1) = h.row(1).array() / h.row(3).array();
+ e->row(2) = h.row(2).array() / h.row(3).array();
+}
+
+void HomogeneousToEuclidean(const Vec3 &H, Vec2 *X) {
+ double w = H(2);
+ *X << H(0) / w, H(1) / w;
+}
+
+void HomogeneousToEuclidean(const Vec4 &H, Vec3 *X) {
+ double w = H(3);
+ *X << H(0) / w, H(1) / w, H(2) / w;
+}
+
+void EuclideanToHomogeneous(const Mat &X, Mat *H) {
+ int d = X.rows();
+ int n = X.cols();
+ H->resize(d + 1, n);
+ H->block(0, 0, d, n) = X;
+ H->row(d).setOnes();
+}
+
+void EuclideanToHomogeneous(const Vec2 &X, Vec3 *H) {
+ *H << X(0), X(1), 1;
+}
+
+void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H) {
+ *H << X(0), X(1), X(2), 1;
+}
+
+// TODO(julien) Call conditioning.h/ApplyTransformationToPoints ?
+void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n) {
+ Mat3X x_image_h;
+ EuclideanToHomogeneous(x, &x_image_h);
+ Mat3X x_camera_h = K.inverse() * x_image_h;
+ HomogeneousToEuclidean(x_camera_h, n);
+}
+
+void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n) {
+ Mat3X x_camera_h = K.inverse() * x;
+ HomogeneousToEuclidean(x_camera_h, n);
+}
+
+double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X) {
+ return (R*X)(2) + t(2);
+}
+
+double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X) {
+ Vec3 Xe = X.head<3>() / X(3);
+ return Depth(R, t, Xe);
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/projection.h b/extern/libmv/libmv/multiview/projection.h
new file mode 100644
index 00000000000..bc353b64c08
--- /dev/null
+++ b/extern/libmv/libmv/multiview/projection.h
@@ -0,0 +1,231 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_PROJECTION_H_
+#define LIBMV_MULTIVIEW_PROJECTION_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P);
+void KRt_From_P(const Mat34 &P, Mat3 *K, Mat3 *R, Vec3 *t);
+
+// Applies a change of basis to the image coordinates of the projection matrix
+// so that the principal point becomes principal_point_new.
+void ProjectionShiftPrincipalPoint(const Mat34 &P,
+ const Vec2 &principal_point,
+ const Vec2 &principal_point_new,
+ Mat34 *P_new);
+
+// Applies a change of basis to the image coordinates of the projection matrix
+// so that the aspect ratio becomes aspect_ratio_new. This is done by
+// stretching the y axis. The aspect ratio is defined as the quotient between
+// the focal length of the y and the x axis.
+void ProjectionChangeAspectRatio(const Mat34 &P,
+ const Vec2 &principal_point,
+ double aspect_ratio,
+ double aspect_ratio_new,
+ Mat34 *P_new);
+
+void HomogeneousToEuclidean(const Mat &H, Mat *X);
+void HomogeneousToEuclidean(const Mat3X &h, Mat2X *e);
+void HomogeneousToEuclidean(const Mat4X &h, Mat3X *e);
+void HomogeneousToEuclidean(const Vec3 &H, Vec2 *X);
+void HomogeneousToEuclidean(const Vec4 &H, Vec3 *X);
+inline Vec2 HomogeneousToEuclidean(const Vec3 &h) {
+ return h.head<2>() / h(2);
+}
+inline Vec3 HomogeneousToEuclidean(const Vec4 &h) {
+ return h.head<3>() / h(3);
+}
+inline Mat2X HomogeneousToEuclidean(const Mat3X &h) {
+ Mat2X e(2, h.cols());
+ e.row(0) = h.row(0).array() / h.row(2).array();
+ e.row(1) = h.row(1).array() / h.row(2).array();
+ return e;
+}
+
+void EuclideanToHomogeneous(const Mat &X, Mat *H);
+inline Mat3X EuclideanToHomogeneous(const Mat2X &x) {
+ Mat3X h(3, x.cols());
+ h.block(0, 0, 2, x.cols()) = x;
+ h.row(2).setOnes();
+ return h;
+}
+inline void EuclideanToHomogeneous(const Mat2X &x, Mat3X *h) {
+ h->resize(3, x.cols());
+ h->block(0, 0, 2, x.cols()) = x;
+ h->row(2).setOnes();
+}
+inline Mat4X EuclideanToHomogeneous(const Mat3X &x) {
+ Mat4X h(4, x.cols());
+ h.block(0, 0, 3, x.cols()) = x;
+ h.row(3).setOnes();
+ return h;
+}
+inline void EuclideanToHomogeneous(const Mat3X &x, Mat4X *h) {
+ h->resize(4, x.cols());
+ h->block(0, 0, 3, x.cols()) = x;
+ h->row(3).setOnes();
+}
+void EuclideanToHomogeneous(const Vec2 &X, Vec3 *H);
+void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H);
+inline Vec3 EuclideanToHomogeneous(const Vec2 &x) {
+ return Vec3(x(0), x(1), 1);
+}
+inline Vec4 EuclideanToHomogeneous(const Vec3 &x) {
+ return Vec4(x(0), x(1), x(2), 1);
+}
+// Conversion from image coordinates to normalized camera coordinates
+void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n);
+void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n);
+
+inline Vec2 Project(const Mat34 &P, const Vec3 &X) {
+ Vec4 HX;
+ HX << X, 1.0;
+ Vec3 hx = P * HX;
+ return hx.head<2>() / hx(2);
+}
+
+inline void Project(const Mat34 &P, const Vec4 &X, Vec3 *x) {
+ *x = P * X;
+}
+
+inline void Project(const Mat34 &P, const Vec4 &X, Vec2 *x) {
+ Vec3 hx = P * X;
+ *x = hx.head<2>() / hx(2);
+}
+
+inline void Project(const Mat34 &P, const Vec3 &X, Vec3 *x) {
+ Vec4 HX;
+ HX << X, 1.0;
+ Project(P, HX, x);
+}
+
+inline void Project(const Mat34 &P, const Vec3 &X, Vec2 *x) {
+ Vec3 hx;
+ Project(P, X, x);
+ *x = hx.head<2>() / hx(2);
+}
+
+inline void Project(const Mat34 &P, const Mat4X &X, Mat2X *x) {
+ x->resize(2, X.cols());
+ for (int c = 0; c < X.cols(); ++c) {
+ Vec3 hx = P * X.col(c);
+ x->col(c) = hx.head<2>() / hx(2);
+ }
+}
+
+inline Mat2X Project(const Mat34 &P, const Mat4X &X) {
+ Mat2X x;
+ Project(P, X, &x);
+ return x;
+}
+
+inline void Project(const Mat34 &P, const Mat3X &X, Mat2X *x) {
+ x->resize(2, X.cols());
+ for (int c = 0; c < X.cols(); ++c) {
+ Vec4 HX;
+ HX << X.col(c), 1.0;
+ Vec3 hx = P * HX;
+ x->col(c) = hx.head<2>() / hx(2);
+ }
+}
+
+inline void Project(const Mat34 &P, const Mat3X &X, const Vecu &ids, Mat2X *x) {
+ x->resize(2, ids.size());
+ Vec4 HX;
+ Vec3 hx;
+ for (int c = 0; c < ids.size(); ++c) {
+ HX << X.col(ids[c]), 1.0;
+ hx = P * HX;
+ x->col(c) = hx.head<2>() / hx(2);
+ }
+}
+
+inline Mat2X Project(const Mat34 &P, const Mat3X &X) {
+ Mat2X x(2, X.cols());
+ Project(P, X, &x);
+ return x;
+}
+
+inline Mat2X Project(const Mat34 &P, const Mat3X &X, const Vecu &ids) {
+ Mat2X x(2, ids.size());
+ Project(P, X, ids, &x);
+ return x;
+}
+
+double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X);
+double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X);
+
+/**
+* Returns true if the homogenious 3D point X is in front of
+* the camera P.
+*/
+inline bool isInFrontOfCamera(const Mat34 &P, const Vec4 &X){
+ double condition_1 = P.row(2).dot(X) * X[3];
+ double condition_2 = X[2] * X[3];
+ if( condition_1 > 0 && condition_2 > 0 )
+ return true;
+ else
+ return false;
+}
+
+inline bool isInFrontOfCamera(const Mat34 &P, const Vec3 &X){
+ Vec4 X_homo;
+ X_homo.segment<3>(0) = X;
+ X_homo(3) = 1;
+ return isInFrontOfCamera( P, X_homo);
+}
+
+/**
+* Transforms a 2D point from pixel image coordinates to a 2D point in
+* normalized image coordinates.
+*/
+inline Vec2 ImageToNormImageCoordinates(Mat3 &Kinverse, Vec2 &x){
+ Vec3 x_h = Kinverse*EuclideanToHomogeneous(x);
+ return HomogeneousToEuclidean( x_h );
+}
+
+/// Estimates the root mean square error (2D)
+inline double RootMeanSquareError(const Mat2X &x_image,
+ const Mat4X &X_world,
+ const Mat34 &P) {
+ size_t num_points = x_image.cols();
+ Mat2X dx = Project(P, X_world) - x_image;
+ return dx.norm() / num_points;
+}
+
+/// Estimates the root mean square error (2D)
+inline double RootMeanSquareError(const Mat2X &x_image,
+ const Mat3X &X_world,
+ const Mat3 &K,
+ const Mat3 &R,
+ const Vec3 &t) {
+ Mat34 P;
+ P_From_KRt(K, R, t, &P);
+ size_t num_points = x_image.cols();
+ Mat2X dx = Project(P, X_world) - x_image;
+ return dx.norm() / num_points;
+}
+} // namespace libmv
+
+#endif // LIBMV_MULTIVIEW_PROJECTION_H_
diff --git a/extern/libmv/libmv/multiview/resection.h b/extern/libmv/libmv/multiview/resection.h
new file mode 100644
index 00000000000..e4623899147
--- /dev/null
+++ b/extern/libmv/libmv/multiview/resection.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Compute the projection matrix from a set of 3D points X and their
+// projections x = PX in 2D. This is useful if a point cloud is reconstructed.
+//
+// Algorithm is the standard DLT as described in Hartley & Zisserman, page 179.
+
+#ifndef LIBMV_MULTIVIEW_RESECTION_H
+#define LIBMV_MULTIVIEW_RESECTION_H
+
+#include "libmv/logging/logging.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+namespace resection {
+
+// x's are 2D image coordinates, (x,y,1), and X's are homogeneous four vectors.
+template<typename T>
+void Resection(const Matrix<T, 2, Dynamic> &x,
+ const Matrix<T, 4, Dynamic> &X,
+ Matrix<T, 3, 4> *P) {
+ int N = x.cols();
+ assert(X.cols() == N);
+
+ Matrix<T, Dynamic, 12> design(2*N, 12);
+ design.setZero();
+ for (int i = 0; i < N; i++) {
+ T xi = x(0, i);
+ T yi = x(1, i);
+ // See equation (7.2) on page 179 of H&Z.
+ design.template block<1,4>(2*i, 4) = -X.col(i).transpose();
+ design.template block<1,4>(2*i, 8) = yi*X.col(i).transpose();
+ design.template block<1,4>(2*i + 1, 0) = X.col(i).transpose();
+ design.template block<1,4>(2*i + 1, 8) = -xi*X.col(i).transpose();
+ }
+ Matrix<T, 12, 1> p;
+ Nullspace(&design, &p);
+ reshape(p, 3, 4, P);
+}
+
+} // namespace resection
+} // namespace libmv
+
+#endif // LIBMV_MULTIVIEW_RESECTION_H
diff --git a/extern/libmv/libmv/multiview/triangulation.cc b/extern/libmv/libmv/multiview/triangulation.cc
new file mode 100644
index 00000000000..b9d38cef936
--- /dev/null
+++ b/extern/libmv/libmv/multiview/triangulation.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/multiview/triangulation.h"
+
+namespace libmv {
+
+// HZ 12.2 pag.312
+void TriangulateDLT(const Mat34 &P1, const Vec2 &x1,
+ const Mat34 &P2, const Vec2 &x2,
+ Vec4 *X_homogeneous) {
+ Mat4 design;
+ for (int i = 0; i < 4; ++i) {
+ design(0,i) = x1(0) * P1(2,i) - P1(0,i);
+ design(1,i) = x1(1) * P1(2,i) - P1(1,i);
+ design(2,i) = x2(0) * P2(2,i) - P2(0,i);
+ design(3,i) = x2(1) * P2(2,i) - P2(1,i);
+ }
+ Nullspace(&design, X_homogeneous);
+}
+
+void TriangulateDLT(const Mat34 &P1, const Vec2 &x1,
+ const Mat34 &P2, const Vec2 &x2,
+ Vec3 *X_euclidean) {
+ Vec4 X_homogeneous;
+ TriangulateDLT(P1, x1, P2, x2, &X_homogeneous);
+ HomogeneousToEuclidean(X_homogeneous, X_euclidean);
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/triangulation.h b/extern/libmv/libmv/multiview/triangulation.h
new file mode 100644
index 00000000000..c35774d9e1b
--- /dev/null
+++ b/extern/libmv/libmv/multiview/triangulation.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_MULTIVIEW_TRIANGULATION_H_
+#define LIBMV_MULTIVIEW_TRIANGULATION_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+void TriangulateDLT(const Mat34 &P1, const Vec2 &x1,
+ const Mat34 &P2, const Vec2 &x2,
+ Vec4 *X_homogeneous);
+
+void TriangulateDLT(const Mat34 &P1, const Vec2 &x1,
+ const Mat34 &P2, const Vec2 &x2,
+ Vec3 *X_euclidean);
+
+} // namespace libmv
+
+#endif // LIBMV_MULTIVIEW_TRIANGULATION_H_
diff --git a/extern/libmv/libmv/numeric/dogleg.h b/extern/libmv/libmv/numeric/dogleg.h
new file mode 100644
index 00000000000..f05882c1191
--- /dev/null
+++ b/extern/libmv/libmv/numeric/dogleg.h
@@ -0,0 +1,261 @@
+// Copyright (c) 2007, 2008, 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// A simple implementation of Powell's dogleg nonlinear minimization.
+//
+// [1] K. Madsen, H. Nielsen, O. Tingleoff. Methods for Non-linear Least
+// Squares Problems.
+// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
+//
+// TODO(keir): Cite the Lourakis' dogleg paper.
+
+#ifndef LIBMV_NUMERIC_DOGLEG_H
+#define LIBMV_NUMERIC_DOGLEG_H
+
+#include <cmath>
+#include <cstdio>
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/function_derivative.h"
+#include "libmv/logging/logging.h"
+
+namespace libmv {
+
+template<typename Function,
+ typename Jacobian = NumericJacobian<Function>,
+ typename Solver = Eigen::PartialPivLU<
+ Matrix<typename Function::FMatrixType::RealScalar,
+ Function::XMatrixType::RowsAtCompileTime,
+ Function::XMatrixType::RowsAtCompileTime> > >
+class Dogleg {
+ public:
+ typedef typename Function::XMatrixType::RealScalar Scalar;
+ typedef typename Function::FMatrixType FVec;
+ typedef typename Function::XMatrixType Parameters;
+ typedef Matrix<typename Function::FMatrixType::RealScalar,
+ Function::FMatrixType::RowsAtCompileTime,
+ Function::XMatrixType::RowsAtCompileTime> JMatrixType;
+ typedef Matrix<typename JMatrixType::RealScalar,
+ JMatrixType::ColsAtCompileTime,
+ JMatrixType::ColsAtCompileTime> AMatrixType;
+
+ enum Status {
+ RUNNING,
+ GRADIENT_TOO_SMALL, // eps > max(J'*f(x))
+ RELATIVE_STEP_SIZE_TOO_SMALL, // eps > ||dx|| / ||x||
+ TRUST_REGION_TOO_SMALL, // eps > radius / ||x||
+ ERROR_TOO_SMALL, // eps > ||f(x)||
+ HIT_MAX_ITERATIONS,
+ };
+
+ enum Step {
+ DOGLEG,
+ GAUSS_NEWTON,
+ STEEPEST_DESCENT,
+ };
+
+ Dogleg(const Function &f)
+ : f_(f), df_(f) {}
+
+ struct SolverParameters {
+ SolverParameters()
+ : gradient_threshold(1e-16),
+ relative_step_threshold(1e-16),
+ error_threshold(1e-16),
+ initial_trust_radius(1e0),
+ max_iterations(500) {}
+ Scalar gradient_threshold; // eps > max(J'*f(x))
+ Scalar relative_step_threshold; // eps > ||dx|| / ||x||
+ Scalar error_threshold; // eps > ||f(x)||
+ Scalar initial_trust_radius; // Initial u for solving normal equations.
+ int max_iterations; // Maximum number of solver iterations.
+ };
+
+ struct Results {
+ Scalar error_magnitude; // ||f(x)||
+ Scalar gradient_magnitude; // ||J'f(x)||
+ int iterations;
+ Status status;
+ };
+
+ Status Update(const Parameters &x, const SolverParameters &params,
+ JMatrixType *J, AMatrixType *A, FVec *error, Parameters *g) {
+ *J = df_(x);
+ // TODO(keir): In the case of m = n, avoid computing A and just do J^-1 directly.
+ *A = (*J).transpose() * (*J);
+ *error = f_(x);
+ *g = (*J).transpose() * *error;
+ if (g->array().abs().maxCoeff() < params.gradient_threshold) {
+ return GRADIENT_TOO_SMALL;
+ } else if (error->array().abs().maxCoeff() < params.error_threshold) {
+ return ERROR_TOO_SMALL;
+ }
+ return RUNNING;
+ }
+
+ Step SolveDoglegDirection(const Parameters &dx_sd,
+ const Parameters &dx_gn,
+ Scalar radius,
+ Scalar alpha,
+ Parameters *dx_dl,
+ Scalar *beta) {
+ Parameters a, b_minus_a;
+ // Solve for Dogleg step dx_dl.
+ if (dx_gn.norm() < radius) {
+ *dx_dl = dx_gn;
+ return GAUSS_NEWTON;
+
+ } else if (alpha * dx_sd.norm() > radius) {
+ *dx_dl = (radius / dx_sd.norm()) * dx_sd;
+ return STEEPEST_DESCENT;
+
+ } else {
+ Parameters a = alpha * dx_sd;
+ const Parameters &b = dx_gn;
+ b_minus_a = a - b;
+ Scalar Mbma2 = b_minus_a.squaredNorm();
+ Scalar Ma2 = a.squaredNorm();
+ Scalar c = a.dot(b_minus_a);
+ Scalar radius2 = radius*radius;
+ if (c <= 0) {
+ *beta = (-c + sqrt(c*c + Mbma2*(radius2 - Ma2)))/(Mbma2);
+ } else {
+ *beta = (radius2 - Ma2) /
+ (c + sqrt(c*c + Mbma2*(radius2 - Ma2)));
+ }
+ *dx_dl = alpha * dx_sd + (*beta) * (dx_gn - alpha*dx_sd);
+ return DOGLEG;
+ }
+ }
+
+ Results minimize(Parameters *x_and_min) {
+ SolverParameters params;
+ return minimize(params, x_and_min);
+ }
+
+ Results minimize(const SolverParameters &params, Parameters *x_and_min) {
+ Parameters &x = *x_and_min;
+ JMatrixType J;
+ AMatrixType A;
+ FVec error;
+ Parameters g;
+
+ Results results;
+ results.status = Update(x, params, &J, &A, &error, &g);
+
+ Scalar radius = params.initial_trust_radius;
+ bool x_updated = true;
+
+ Parameters x_new;
+ Parameters dx_sd; // Steepest descent step.
+ Parameters dx_dl; // Dogleg step.
+ Parameters dx_gn; // Gauss-Newton step.
+ printf("iteration ||f(x)|| max(g) radius\n");
+ int i = 0;
+ for (; results.status == RUNNING && i < params.max_iterations; ++i) {
+ printf("%9d %12g %12g %12g",
+ i, f_(x).norm(), g.array().abs().maxCoeff(), radius);
+
+ //LG << "iteration: " << i;
+ //LG << "||f(x)||: " << f_(x).norm();
+ //LG << "max(g): " << g.cwise().abs().maxCoeff();
+ //LG << "radius: " << radius;
+ // Eqn 3.19 from [1]
+ Scalar alpha = g.squaredNorm() / (J*g).squaredNorm();
+
+ // Solve for steepest descent direction dx_sd.
+ dx_sd = -g;
+
+ // Solve for Gauss-Newton direction dx_gn.
+ if (x_updated) {
+ // TODO(keir): See Appendix B of [1] for discussion of when A is
+ // singular and there are many solutions. Solving that involves the SVD
+ // and is slower, but should still work.
+ Solver solver(A);
+ dx_gn = solver.solve(-g);
+ if (!(A * dx_gn).isApprox(-g)) {
+ LOG(ERROR) << "Failed to solve normal eqns. TODO: Solve via SVD.";
+ return results;
+ }
+ x_updated = false;
+ }
+
+ // Solve for dogleg direction dx_dl.
+ Scalar beta = 0;
+ Step step = SolveDoglegDirection(dx_sd, dx_gn, radius, alpha,
+ &dx_dl, &beta);
+
+ Scalar e3 = params.relative_step_threshold;
+ if (dx_dl.norm() < e3*(x.norm() + e3)) {
+ results.status = RELATIVE_STEP_SIZE_TOO_SMALL;
+ break;
+ }
+
+ x_new = x + dx_dl;
+ Scalar actual = f_(x).squaredNorm() - f_(x_new).squaredNorm();
+ Scalar predicted = 0;
+ if (step == GAUSS_NEWTON) {
+ predicted = f_(x).squaredNorm();
+ } else if (step == STEEPEST_DESCENT) {
+ predicted = radius * (2*alpha*g.norm() - radius) / 2 / alpha;
+ } else if (step == DOGLEG) {
+ predicted = 0.5 * alpha * (1-beta)*(1-beta)*g.squaredNorm() +
+ beta*(2-beta)*f_(x).squaredNorm();
+ }
+ Scalar rho = actual / predicted;
+
+ if (step == GAUSS_NEWTON) printf(" GAUSS");
+ if (step == STEEPEST_DESCENT) printf(" STEE");
+ if (step == DOGLEG) printf(" DOGL");
+
+ printf(" %12g %12g %12g\n", rho, actual, predicted);
+
+ if (rho > 0) {
+ // Accept update because the linear model is a good fit.
+ x = x_new;
+ results.status = Update(x, params, &J, &A, &error, &g);
+ x_updated = true;
+ }
+ if (rho > 0.75) {
+ radius = std::max(radius, 3*dx_dl.norm());
+ } else if (rho < 0.25) {
+ radius /= 2;
+ if (radius < e3 * (x.norm() + e3)) {
+ results.status = TRUST_REGION_TOO_SMALL;
+ }
+ }
+ }
+ if (results.status == RUNNING) {
+ results.status = HIT_MAX_ITERATIONS;
+ }
+ results.error_magnitude = error.norm();
+ results.gradient_magnitude = g.norm();
+ results.iterations = i;
+ return results;
+ }
+
+ private:
+ const Function &f_;
+ Jacobian df_;
+};
+
+} // namespace mv
+
+#endif // LIBMV_NUMERIC_DOGLEG_H
diff --git a/extern/libmv/libmv/numeric/function_derivative.h b/extern/libmv/libmv/numeric/function_derivative.h
new file mode 100644
index 00000000000..d7bc437b2e0
--- /dev/null
+++ b/extern/libmv/libmv/numeric/function_derivative.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2007, 2008, 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_NUMERIC_DERIVATIVE_H
+#define LIBMV_NUMERIC_DERIVATIVE_H
+
+#include <cmath>
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/logging/logging.h"
+
+namespace libmv {
+
+// Numeric derivative of a function.
+// TODO(keir): Consider adding a quadratic approximation.
+
+enum NumericJacobianMode {
+ CENTRAL,
+ FORWARD,
+};
+
+template<typename Function, NumericJacobianMode mode=CENTRAL>
+class NumericJacobian {
+ public:
+ typedef typename Function::XMatrixType Parameters;
+ typedef typename Function::XMatrixType::RealScalar XScalar;
+ typedef typename Function::FMatrixType FMatrixType;
+ typedef Matrix<typename Function::FMatrixType::RealScalar,
+ Function::FMatrixType::RowsAtCompileTime,
+ Function::XMatrixType::RowsAtCompileTime>
+ JMatrixType;
+
+ NumericJacobian(const Function &f) : f_(f) {}
+
+ // TODO(keir): Perhaps passing the jacobian back by value is not a good idea.
+ JMatrixType operator()(const Parameters &x) {
+ // Empirically determined constant.
+ Parameters eps = x.array().abs() * XScalar(1e-5);
+ // To handle cases where a paremeter is exactly zero, instead use the mean
+ // eps for the other dimensions.
+ XScalar mean_eps = eps.sum() / eps.rows();
+ if (mean_eps == XScalar(0)) {
+ // TODO(keir): Do something better here.
+ mean_eps = 1e-8; // ~sqrt(machine precision).
+ }
+ // TODO(keir): Elimininate this needless function evaluation for the
+ // central difference case.
+ FMatrixType fx = f_(x);
+ const int rows = fx.rows();
+ const int cols = x.rows();
+ JMatrixType jacobian(rows, cols);
+ Parameters x_plus_delta = x;
+ for (int c = 0; c < cols; ++c) {
+ if (eps(c) == XScalar(0)) {
+ eps(c) = mean_eps;
+ }
+ x_plus_delta(c) = x(c) + eps(c);
+ jacobian.col(c) = f_(x_plus_delta);
+
+ XScalar one_over_h = 1 / eps(c);
+ if (mode == CENTRAL) {
+ x_plus_delta(c) = x(c) - eps(c);
+ jacobian.col(c) -= f_(x_plus_delta);
+ one_over_h /= 2;
+ } else {
+ jacobian.col(c) -= fx;
+ }
+ x_plus_delta(c) = x(c);
+ jacobian.col(c) = jacobian.col(c) * one_over_h;
+ }
+ return jacobian;
+ }
+ private:
+ const Function &f_;
+};
+
+template<typename Function, typename Jacobian>
+bool CheckJacobian(const Function &f, const typename Function::XMatrixType &x) {
+ Jacobian j_analytic(f);
+ NumericJacobian<Function> j_numeric(f);
+
+ typename NumericJacobian<Function>::JMatrixType J_numeric = j_numeric(x);
+ typename NumericJacobian<Function>::JMatrixType J_analytic = j_analytic(x);
+ LG << J_numeric - J_analytic;
+ return true;
+}
+
+} // namespace libmv
+
+#endif // LIBMV_NUMERIC_DERIVATIVE_H
diff --git a/extern/libmv/libmv/numeric/levenberg_marquardt.h b/extern/libmv/libmv/numeric/levenberg_marquardt.h
new file mode 100644
index 00000000000..4473b72f156
--- /dev/null
+++ b/extern/libmv/libmv/numeric/levenberg_marquardt.h
@@ -0,0 +1,183 @@
+// Copyright (c) 2007, 2008, 2009 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// A simple implementation of levenberg marquardt.
+//
+// [1] K. Madsen, H. Nielsen, O. Tingleoff. Methods for Non-linear Least
+// Squares Problems.
+// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
+//
+// TODO(keir): Cite the Lourakis' dogleg paper.
+
+#ifndef LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H
+#define LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H
+
+#include <cmath>
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/function_derivative.h"
+#include "libmv/logging/logging.h"
+
+namespace libmv {
+
+template<typename Function,
+ typename Jacobian = NumericJacobian<Function>,
+ typename Solver = Eigen::PartialPivLU<
+ Matrix<typename Function::FMatrixType::RealScalar,
+ Function::XMatrixType::RowsAtCompileTime,
+ Function::XMatrixType::RowsAtCompileTime> > >
+class LevenbergMarquardt {
+ public:
+ typedef typename Function::XMatrixType::RealScalar Scalar;
+ typedef typename Function::FMatrixType FVec;
+ typedef typename Function::XMatrixType Parameters;
+ typedef Matrix<typename Function::FMatrixType::RealScalar,
+ Function::FMatrixType::RowsAtCompileTime,
+ Function::XMatrixType::RowsAtCompileTime> JMatrixType;
+ typedef Matrix<typename JMatrixType::RealScalar,
+ JMatrixType::ColsAtCompileTime,
+ JMatrixType::ColsAtCompileTime> AMatrixType;
+
+ // TODO(keir): Some of these knobs can be derived from each other and
+ // removed, instead of requiring the user to set them.
+ enum Status {
+ RUNNING,
+ GRADIENT_TOO_SMALL, // eps > max(J'*f(x))
+ RELATIVE_STEP_SIZE_TOO_SMALL, // eps > ||dx|| / ||x||
+ ERROR_TOO_SMALL, // eps > ||f(x)||
+ HIT_MAX_ITERATIONS,
+ };
+
+ LevenbergMarquardt(const Function &f)
+ : f_(f), df_(f) {}
+
+ struct SolverParameters {
+ SolverParameters()
+ : gradient_threshold(1e-16),
+ relative_step_threshold(1e-16),
+ error_threshold(1e-16),
+ initial_scale_factor(1e-3),
+ max_iterations(100) {}
+ Scalar gradient_threshold; // eps > max(J'*f(x))
+ Scalar relative_step_threshold; // eps > ||dx|| / ||x||
+ Scalar error_threshold; // eps > ||f(x)||
+ Scalar initial_scale_factor; // Initial u for solving normal equations.
+ int max_iterations; // Maximum number of solver iterations.
+ };
+
+ struct Results {
+ Scalar error_magnitude; // ||f(x)||
+ Scalar gradient_magnitude; // ||J'f(x)||
+ int iterations;
+ Status status;
+ };
+
+ Status Update(const Parameters &x, const SolverParameters &params,
+ JMatrixType *J, AMatrixType *A, FVec *error, Parameters *g) {
+ *J = df_(x);
+ *A = (*J).transpose() * (*J);
+ *error = -f_(x);
+ *g = (*J).transpose() * *error;
+ if (g->array().abs().maxCoeff() < params.gradient_threshold) {
+ return GRADIENT_TOO_SMALL;
+ } else if (error->norm() < params.error_threshold) {
+ return ERROR_TOO_SMALL;
+ }
+ return RUNNING;
+ }
+
+ Results minimize(Parameters *x_and_min) {
+ SolverParameters params;
+ minimize(params, x_and_min);
+ }
+
+ Results minimize(const SolverParameters &params, Parameters *x_and_min) {
+ Parameters &x = *x_and_min;
+ JMatrixType J;
+ AMatrixType A;
+ FVec error;
+ Parameters g;
+
+ Results results;
+ results.status = Update(x, params, &J, &A, &error, &g);
+
+ Scalar u = Scalar(params.initial_scale_factor*A.diagonal().maxCoeff());
+ Scalar v = 2;
+
+ Parameters dx, x_new;
+ int i;
+ for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) {
+ VLOG(1) << "iteration: " << i;
+ VLOG(1) << "||f(x)||: " << f_(x).norm();
+ VLOG(1) << "max(g): " << g.array().abs().maxCoeff();
+ VLOG(1) << "u: " << u;
+ VLOG(1) << "v: " << v;
+
+ AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols());
+ Solver solver(A_augmented);
+ dx = solver.solve(g);
+ bool solved = (A_augmented * dx).isApprox(g);
+ if (!solved) {
+ LOG(ERROR) << "Failed to solve";
+ }
+ if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) {
+ results.status = RELATIVE_STEP_SIZE_TOO_SMALL;
+ break;
+ }
+ if (solved) {
+ x_new = x + dx;
+ // Rho is the ratio of the actual reduction in error to the reduction
+ // in error that would be obtained if the problem was linear.
+ // See [1] for details.
+ Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm())
+ / dx.dot(u*dx + g));
+ if (rho > 0) {
+ // Accept the Gauss-Newton step because the linear model fits well.
+ x = x_new;
+ results.status = Update(x, params, &J, &A, &error, &g);
+ Scalar tmp = Scalar(2*rho-1);
+ u = u*std::max(1/3., 1 - (tmp*tmp*tmp));
+ v = 2;
+ continue;
+ }
+ }
+ // Reject the update because either the normal equations failed to solve
+ // or the local linear model was not good (rho < 0). Instead, increase u
+ // to move closer to gradient descent.
+ u *= v;
+ v *= 2;
+ }
+ if (results.status == RUNNING) {
+ results.status = HIT_MAX_ITERATIONS;
+ }
+ results.error_magnitude = error.norm();
+ results.gradient_magnitude = g.norm();
+ results.iterations = i;
+ return results;
+ }
+
+ private:
+ const Function &f_;
+ Jacobian df_;
+};
+
+} // namespace mv
+
+#endif // LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H
diff --git a/extern/libmv/libmv/numeric/numeric.cc b/extern/libmv/libmv/numeric/numeric.cc
new file mode 100644
index 00000000000..0ca3a64e4f4
--- /dev/null
+++ b/extern/libmv/libmv/numeric/numeric.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+Mat3 RotationAroundX(double angle) {
+ double c, s;
+ sincos(angle, &s, &c);
+ Mat3 R;
+ R << 1, 0, 0,
+ 0, c, -s,
+ 0, s, c;
+ return R;
+}
+
+Mat3 RotationAroundY(double angle) {
+ double c, s;
+ sincos(angle, &s, &c);
+ Mat3 R;
+ R << c, 0, s,
+ 0, 1, 0,
+ -s, 0, c;
+ return R;
+}
+
+Mat3 RotationAroundZ(double angle) {
+ double c, s;
+ sincos(angle, &s, &c);
+ Mat3 R;
+ R << c, -s, 0,
+ s, c, 0,
+ 0, 0, 1;
+ return R;
+}
+
+
+Mat3 RotationRodrigues(const Vec3 &axis) {
+ double theta = axis.norm();
+ Vec3 w = axis / theta;
+ Mat3 W = CrossProductMatrix(w);
+
+ return Mat3::Identity() + sin(theta) * W + (1 - cos(theta)) * W * W;
+}
+
+
+Mat3 LookAt(Vec3 center) {
+ Vec3 zc = center.normalized();
+ Vec3 xc = Vec3::UnitY().cross(zc).normalized();
+ Vec3 yc = zc.cross(xc);
+ Mat3 R;
+ R.row(0) = xc;
+ R.row(1) = yc;
+ R.row(2) = zc;
+ return R;
+}
+
+Mat3 CrossProductMatrix(const Vec3 &x) {
+ Mat3 X;
+ X << 0, -x(2), x(1),
+ x(2), 0, -x(0),
+ -x(1), x(0), 0;
+ return X;
+}
+
+void MeanAndVarianceAlongRows(const Mat &A,
+ Vec *mean_pointer,
+ Vec *variance_pointer) {
+ Vec &mean = *mean_pointer;
+ Vec &variance = *variance_pointer;
+ int n = A.rows();
+ int m = A.cols();
+ mean.resize(n);
+ variance.resize(n);
+
+ for (int i = 0; i < n; ++i) {
+ mean(i) = 0;
+ variance(i) = 0;
+ for (int j = 0; j < m; ++j) {
+ double x = A(i, j);
+ mean(i) += x;
+ variance(i) += x * x;
+ }
+ }
+
+ mean /= m;
+ for (int i = 0; i < n; ++i) {
+ variance(i) = variance(i) / m - Square(mean(i));
+ }
+}
+
+void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked) {
+ assert(left.rows() == left.rows());
+ int n = left.rows();
+ int m1 = left.cols();
+ int m2 = right.cols();
+
+ stacked->resize(n, m1 + m2);
+ stacked->block(0, 0, n, m1) = left;
+ stacked->block(0, m1, n, m2) = right;
+}
+
+void MatrixColumn(const Mat &A, int i, Vec2 *v) {
+ assert(A.rows() == 2);
+ *v << A(0,i), A(1,i);
+}
+void MatrixColumn(const Mat &A, int i, Vec3 *v) {
+ assert(A.rows() == 3);
+ *v << A(0,i), A(1,i), A(2,i);
+}
+void MatrixColumn(const Mat &A, int i, Vec4 *v) {
+ assert(A.rows() == 4);
+ *v << A(0,i), A(1,i), A(2,i), A(3,i);
+}
+
+} // namespace libmv
+
diff --git a/extern/libmv/libmv/numeric/numeric.h b/extern/libmv/libmv/numeric/numeric.h
new file mode 100644
index 00000000000..21e0f067446
--- /dev/null
+++ b/extern/libmv/libmv/numeric/numeric.h
@@ -0,0 +1,479 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Matrix and vector classes, based on Eigen2.
+//
+// Avoid using Eigen2 classes directly; instead typedef them here.
+
+#ifndef LIBMV_NUMERIC_NUMERIC_H
+#define LIBMV_NUMERIC_NUMERIC_H
+
+#include <Eigen/Cholesky>
+#include <Eigen/Core>
+#include <Eigen/Eigenvalues>
+#include <Eigen/Geometry>
+#include <Eigen/LU>
+#include <Eigen/QR>
+#include <Eigen/SVD>
+
+#if _WIN32 || __APPLE__
+ void static sincos (double x, double *sinx, double *cosx) {
+ *sinx = sin(x);
+ *cosx = cos(x);
+ }
+#endif //_WIN32 || __APPLE__
+
+#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__)
+ inline long lround(double d) {
+ return (long)(d>0 ? d+0.5 : ceil(d-0.5));
+ }
+ inline int round(double d) {
+ return (d>0) ? int(d+0.5) : int(d-0.5);
+ }
+ typedef unsigned int uint;
+#endif //_WIN32
+
+namespace libmv {
+
+typedef Eigen::MatrixXd Mat;
+typedef Eigen::VectorXd Vec;
+
+typedef Eigen::MatrixXf Matf;
+typedef Eigen::VectorXf Vecf;
+
+typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic> Matu;
+typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, 1> Vecu;
+typedef Eigen::Matrix<unsigned int, 2, 1> Vec2u;
+
+typedef Eigen::Matrix<double, 2, 2> Mat2;
+typedef Eigen::Matrix<double, 2, 3> Mat23;
+typedef Eigen::Matrix<double, 3, 3> Mat3;
+typedef Eigen::Matrix<double, 3, 4> Mat34;
+typedef Eigen::Matrix<double, 3, 5> Mat35;
+typedef Eigen::Matrix<double, 4, 1> Mat41;
+typedef Eigen::Matrix<double, 4, 3> Mat43;
+typedef Eigen::Matrix<double, 4, 4> Mat4;
+typedef Eigen::Matrix<double, 4, 6> Mat46;
+typedef Eigen::Matrix<float, 2, 2> Mat2f;
+typedef Eigen::Matrix<float, 2, 3> Mat23f;
+typedef Eigen::Matrix<float, 3, 3> Mat3f;
+typedef Eigen::Matrix<float, 3, 4> Mat34f;
+typedef Eigen::Matrix<float, 3, 5> Mat35f;
+typedef Eigen::Matrix<float, 4, 3> Mat43f;
+typedef Eigen::Matrix<float, 4, 4> Mat4f;
+typedef Eigen::Matrix<float, 4, 6> Mat46f;
+
+typedef Eigen::Matrix<double, 3, 3, Eigen::RowMajor> RMat3;
+typedef Eigen::Matrix<double, 4, 4, Eigen::RowMajor> RMat4;
+
+typedef Eigen::Matrix<double, 2, Eigen::Dynamic> Mat2X;
+typedef Eigen::Matrix<double, 3, Eigen::Dynamic> Mat3X;
+typedef Eigen::Matrix<double, 4, Eigen::Dynamic> Mat4X;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 2> MatX2;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 3> MatX3;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 4> MatX4;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 5> MatX5;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 6> MatX6;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 7> MatX7;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 8> MatX8;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 9> MatX9;
+typedef Eigen::Matrix<double, Eigen::Dynamic,15> MatX15;
+typedef Eigen::Matrix<double, Eigen::Dynamic,16> MatX16;
+
+typedef Eigen::Vector2d Vec2;
+typedef Eigen::Vector3d Vec3;
+typedef Eigen::Vector4d Vec4;
+typedef Eigen::Matrix<double, 5, 1> Vec5;
+typedef Eigen::Matrix<double, 6, 1> Vec6;
+typedef Eigen::Matrix<double, 7, 1> Vec7;
+typedef Eigen::Matrix<double, 8, 1> Vec8;
+typedef Eigen::Matrix<double, 9, 1> Vec9;
+typedef Eigen::Matrix<double, 10, 1> Vec10;
+typedef Eigen::Matrix<double, 11, 1> Vec11;
+typedef Eigen::Matrix<double, 12, 1> Vec12;
+typedef Eigen::Matrix<double, 13, 1> Vec13;
+typedef Eigen::Matrix<double, 14, 1> Vec14;
+typedef Eigen::Matrix<double, 15, 1> Vec15;
+typedef Eigen::Matrix<double, 16, 1> Vec16;
+typedef Eigen::Matrix<double, 17, 1> Vec17;
+typedef Eigen::Matrix<double, 18, 1> Vec18;
+typedef Eigen::Matrix<double, 19, 1> Vec19;
+typedef Eigen::Matrix<double, 20, 1> Vec20;
+
+typedef Eigen::Vector2f Vec2f;
+typedef Eigen::Vector3f Vec3f;
+typedef Eigen::Vector4f Vec4f;
+
+typedef Eigen::VectorXi VecXi;
+
+typedef Eigen::Vector2i Vec2i;
+typedef Eigen::Vector3i Vec3i;
+typedef Eigen::Vector4i Vec4i;
+
+typedef Eigen::Matrix<float,
+ Eigen::Dynamic,
+ Eigen::Dynamic,
+ Eigen::RowMajor> RMatf;
+
+typedef Eigen::NumTraits<double> EigenDouble;
+
+using Eigen::Map;
+using Eigen::Dynamic;
+using Eigen::Matrix;
+
+// Find U, s, and VT such that
+//
+// A = U * diag(s) * VT
+//
+template <typename TMat, typename TVec>
+inline void SVD(TMat *A, Vec *s, Mat *U, Mat *VT) {
+ assert(0);
+}
+
+// Solve the linear system Ax = 0 via SVD. Store the solution in x, such that
+// ||x|| = 1.0. Return the singluar value corresponding to the solution.
+// Destroys A and resizes x if necessary.
+// TODO(maclean): Take the SVD of the transpose instead of this zero padding.
+template <typename TMat, typename TVec>
+double Nullspace(TMat *A, TVec *nullspace) {
+ Eigen::JacobiSVD<TMat> svd(*A, Eigen::ComputeFullV);
+ (*nullspace) = svd.matrixV().col(A->cols()-1);
+ if (A->rows() >= A->cols())
+ return svd.singularValues()(A->cols()-1);
+ else
+ return 0.0;
+}
+
+// Solve the linear system Ax = 0 via SVD. Finds two solutions, x1 and x2, such
+// that x1 is the best solution and x2 is the next best solution (in the L2
+// norm sense). Store the solution in x1 and x2, such that ||x|| = 1.0. Return
+// the singluar value corresponding to the solution x1. Destroys A and resizes
+// x if necessary.
+template <typename TMat, typename TVec1, typename TVec2>
+double Nullspace2(TMat *A, TVec1 *x1, TVec2 *x2) {
+ Eigen::JacobiSVD<TMat> svd(*A, Eigen::ComputeFullV);
+ *x1 = svd.matrixV().col(A->cols() - 1);
+ *x2 = svd.matrixV().col(A->cols() - 2);
+ if (A->rows() >= A->cols())
+ return svd.singularValues()(A->cols()-1);
+ else
+ return 0.0;
+}
+
+// In place transpose for square matrices.
+template<class TA>
+inline void TransposeInPlace(TA *A) {
+ *A = A->transpose().eval();
+}
+
+template<typename TVec>
+inline double NormL1(const TVec &x) {
+ return x.array().abs().sum();
+}
+
+template<typename TVec>
+inline double NormL2(const TVec &x) {
+ return x.norm();
+}
+
+template<typename TVec>
+inline double NormLInfinity(const TVec &x) {
+ return x.array().abs().maxCoeff();
+}
+
+template<typename TVec>
+inline double DistanceL1(const TVec &x, const TVec &y) {
+ return (x - y).array().abs().sum();
+}
+
+template<typename TVec>
+inline double DistanceL2(const TVec &x, const TVec &y) {
+ return (x - y).norm();
+}
+template<typename TVec>
+inline double DistanceLInfinity(const TVec &x, const TVec &y) {
+ return (x - y).array().abs().maxCoeff();
+}
+
+// Normalize a vector with the L1 norm, and return the norm before it was
+// normalized.
+template<typename TVec>
+inline double NormalizeL1(TVec *x) {
+ double norm = NormL1(*x);
+ *x /= norm;
+ return norm;
+}
+
+// Normalize a vector with the L2 norm, and return the norm before it was
+// normalized.
+template<typename TVec>
+inline double NormalizeL2(TVec *x) {
+ double norm = NormL2(*x);
+ *x /= norm;
+ return norm;
+}
+
+// Normalize a vector with the L^Infinity norm, and return the norm before it
+// was normalized.
+template<typename TVec>
+inline double NormalizeLInfinity(TVec *x) {
+ double norm = NormLInfinity(*x);
+ *x /= norm;
+ return norm;
+}
+
+// Return the square of a number.
+template<typename T>
+inline T Square(T x) {
+ return x * x;
+}
+
+Mat3 RotationAroundX(double angle);
+Mat3 RotationAroundY(double angle);
+Mat3 RotationAroundZ(double angle);
+
+// Returns the rotation matrix of a rotation of angle |axis| around axis.
+// This is computed using the Rodrigues formula, see:
+// http://mathworld.wolfram.com/RodriguesRotationFormula.html
+Mat3 RotationRodrigues(const Vec3 &axis);
+
+// Make a rotation matrix such that center becomes the direction of the
+// positive z-axis, and y is oriented close to up.
+Mat3 LookAt(Vec3 center);
+
+// Return a diagonal matrix from a vector containg the diagonal values.
+template <typename TVec>
+inline Mat Diag(const TVec &x) {
+ return x.asDiagonal();
+}
+
+template<typename TMat>
+inline double FrobeniusNorm(const TMat &A) {
+ return sqrt(A.array().abs2().sum());
+}
+
+template<typename TMat>
+inline double FrobeniusDistance(const TMat &A, const TMat &B) {
+ return FrobeniusNorm(A - B);
+}
+
+inline Vec3 CrossProduct(const Vec3 &x, const Vec3 &y) {
+ return x.cross(y);
+}
+
+Mat3 CrossProductMatrix(const Vec3 &x);
+
+void MeanAndVarianceAlongRows(const Mat &A,
+ Vec *mean_pointer,
+ Vec *variance_pointer);
+
+#if _WIN32
+ // TODO(bomboze): un-#if this for both platforms once tested under Windows
+ /* This solution was extensively discussed here http://forum.kde.org/viewtopic.php?f=74&t=61940 */
+ #define SUM_OR_DYNAMIC(x,y) (x==Eigen::Dynamic||y==Eigen::Dynamic)?Eigen::Dynamic:(x+y)
+
+ template<typename Derived1, typename Derived2>
+ struct hstack_return {
+ typedef typename Derived1::Scalar Scalar;
+ enum {
+ RowsAtCompileTime = Derived1::RowsAtCompileTime,
+ ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, Derived2::ColsAtCompileTime),
+ Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0,
+ MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, Derived2::MaxColsAtCompileTime)
+ };
+ typedef Eigen::Matrix<Scalar,
+ RowsAtCompileTime,
+ ColsAtCompileTime,
+ Options,
+ MaxRowsAtCompileTime,
+ MaxColsAtCompileTime> type;
+ };
+
+ template<typename Derived1, typename Derived2>
+ typename hstack_return<Derived1,Derived2>::type
+ HStack (const Eigen::MatrixBase<Derived1>& lhs, const Eigen::MatrixBase<Derived2>& rhs) {
+ typename hstack_return<Derived1,Derived2>::type res;
+ res.resize(lhs.rows(), lhs.cols()+rhs.cols());
+ res << lhs, rhs;
+ return res;
+ };
+
+
+ template<typename Derived1, typename Derived2>
+ struct vstack_return {
+ typedef typename Derived1::Scalar Scalar;
+ enum {
+ RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime, Derived2::RowsAtCompileTime),
+ ColsAtCompileTime = Derived1::ColsAtCompileTime,
+ Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0,
+ MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime, Derived2::MaxRowsAtCompileTime),
+ MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime
+ };
+ typedef Eigen::Matrix<Scalar,
+ RowsAtCompileTime,
+ ColsAtCompileTime,
+ Options,
+ MaxRowsAtCompileTime,
+ MaxColsAtCompileTime> type;
+ };
+
+ template<typename Derived1, typename Derived2>
+ typename vstack_return<Derived1,Derived2>::type
+ VStack (const Eigen::MatrixBase<Derived1>& lhs, const Eigen::MatrixBase<Derived2>& rhs) {
+ typename vstack_return<Derived1,Derived2>::type res;
+ res.resize(lhs.rows()+rhs.rows(), lhs.cols());
+ res << lhs, rhs;
+ return res;
+ };
+
+
+#else //_WIN32
+
+ // Since it is not possible to typedef privately here, use a macro.
+ // Always take dynamic columns if either side is dynamic.
+ #define COLS \
+ ((ColsLeft == Eigen::Dynamic || ColsRight == Eigen::Dynamic) \
+ ? Eigen::Dynamic : (ColsLeft + ColsRight))
+
+ // Same as above, except that prefer fixed size if either is fixed.
+ #define ROWS \
+ ((RowsLeft == Eigen::Dynamic && RowsRight == Eigen::Dynamic) \
+ ? Eigen::Dynamic \
+ : ((RowsLeft == Eigen::Dynamic) \
+ ? RowsRight \
+ : RowsLeft \
+ ) \
+ )
+
+ // TODO(keir): Add a static assert if both rows are at compiletime.
+ template<typename T, int RowsLeft, int RowsRight, int ColsLeft, int ColsRight>
+ Eigen::Matrix<T, ROWS, COLS>
+ HStack(const Eigen::Matrix<T, RowsLeft, ColsLeft> &left,
+ const Eigen::Matrix<T, RowsRight, ColsRight> &right) {
+ assert(left.rows() == right.rows());
+ int n = left.rows();
+ int m1 = left.cols();
+ int m2 = right.cols();
+
+ Eigen::Matrix<T, ROWS, COLS> stacked(n, m1 + m2);
+ stacked.block(0, 0, n, m1) = left;
+ stacked.block(0, m1, n, m2) = right;
+ return stacked;
+ }
+
+ // Reuse the above macros by swapping the order of Rows and Cols. Nasty, but
+ // the duplication is worse.
+ // TODO(keir): Add a static assert if both rows are at compiletime.
+ // TODO(keir): Mail eigen list about making this work for general expressions
+ // rather than only matrix types.
+ template<typename T, int RowsLeft, int RowsRight, int ColsLeft, int ColsRight>
+ Eigen::Matrix<T, COLS, ROWS>
+ VStack(const Eigen::Matrix<T, ColsLeft, RowsLeft> &top,
+ const Eigen::Matrix<T, ColsRight, RowsRight> &bottom) {
+ assert(top.cols() == bottom.cols());
+ int n1 = top.rows();
+ int n2 = bottom.rows();
+ int m = top.cols();
+
+ Eigen::Matrix<T, COLS, ROWS> stacked(n1 + n2, m);
+ stacked.block(0, 0, n1, m) = top;
+ stacked.block(n1, 0, n2, m) = bottom;
+ return stacked;
+ }
+ #undef COLS
+ #undef ROWS
+#endif //_WIN32
+
+
+
+void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked);
+
+template<typename TTop, typename TBot, typename TStacked>
+void VerticalStack(const TTop &top, const TBot &bottom, TStacked *stacked) {
+ assert(top.cols() == bottom.cols());
+ int n1 = top.rows();
+ int n2 = bottom.rows();
+ int m = top.cols();
+
+ stacked->resize(n1 + n2, m);
+ stacked->block(0, 0, n1, m) = top;
+ stacked->block(n1, 0, n2, m) = bottom;
+}
+
+void MatrixColumn(const Mat &A, int i, Vec2 *v);
+void MatrixColumn(const Mat &A, int i, Vec3 *v);
+void MatrixColumn(const Mat &A, int i, Vec4 *v);
+
+template <typename TMat, typename TCols>
+TMat ExtractColumns(const TMat &A, const TCols &columns) {
+ TMat compressed(A.rows(), columns.size());
+ for (int i = 0; i < columns.size(); ++i) {
+ compressed.col(i) = A.col(columns[i]);
+ }
+ return compressed;
+}
+
+template <typename TMat, typename TDest>
+void reshape(const TMat &a, int rows, int cols, TDest *b) {
+ assert(a.rows()*a.cols() == rows*cols);
+ b->resize(rows, cols);
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ (*b)(i, j) = a[cols*i + j];
+ }
+ }
+}
+
+inline bool isnan(double i) {
+#ifdef WIN32
+ return _isnan(i) > 0;
+#else
+ return std::isnan(i);
+#endif
+}
+
+/// Ceil function that has the same behaviour for positive
+/// and negative values
+template <typename FloatType>
+FloatType ceil0(const FloatType& value) {
+ FloatType result = std::ceil( std::fabs( value ) );
+ return (value < 0.0) ? -result : result;
+}
+
+/// Returns the skew anti-symmetric matrix of a vector
+inline Mat3 SkewMat(const Vec3 &x) {
+ Mat3 skew;
+ skew << 0 , -x(2), x(1),
+ x(2), 0 , -x(0),
+ -x(1), x(0), 0;
+ return skew;
+}
+/// Returns the skew anti-symmetric matrix of a vector with only
+/// the first two (independent) lines
+inline Mat23 SkewMatMinimal(const Vec2 &x) {
+ Mat23 skew;
+ skew << 0,-1, x(1),
+ 1, 0, -x(0);
+ return skew;
+}
+} // namespace libmv
+
+#endif // LIBMV_NUMERIC_NUMERIC_H
diff --git a/extern/libmv/libmv/numeric/poly.cc b/extern/libmv/libmv/numeric/poly.cc
new file mode 100644
index 00000000000..d96e3c104c7
--- /dev/null
+++ b/extern/libmv/libmv/numeric/poly.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Routines for solving polynomials.
+
+// TODO(keir): Add a solver for degree > 3 polynomials.
diff --git a/extern/libmv/libmv/numeric/poly.h b/extern/libmv/libmv/numeric/poly.h
new file mode 100644
index 00000000000..cb1d65b32c4
--- /dev/null
+++ b/extern/libmv/libmv/numeric/poly.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2007, 2008 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_NUMERIC_POLY_H_
+#define LIBMV_NUMERIC_POLY_H_
+
+#include <cmath>
+#include <stdio.h>
+
+namespace libmv {
+
+// Solve the cubic polynomial
+//
+// x^3 + a*x^2 + b*x + c = 0
+//
+// The number of roots (from zero to three) is returned. If the number of roots
+// is less than three, then higher numbered x's are not changed. For example,
+// if there are 2 roots, only x0 and x1 are set.
+//
+// The GSL cubic solver was used as a reference for this routine.
+template<typename Real>
+int SolveCubicPolynomial(Real a, Real b, Real c,
+ Real *x0, Real *x1, Real *x2) {
+ Real q = a * a - 3 * b;
+ Real r = 2 * a * a * a - 9 * a * b + 27 * c;
+
+ Real Q = q / 9;
+ Real R = r / 54;
+
+ Real Q3 = Q * Q * Q;
+ Real R2 = R * R;
+
+ Real CR2 = 729 * r * r;
+ Real CQ3 = 2916 * q * q * q;
+
+ if (R == 0 && Q == 0) {
+ // Tripple root in one place.
+ *x0 = *x1 = *x2 = -a / 3 ;
+ return 3;
+
+ } else if (CR2 == CQ3) {
+ // This test is actually R2 == Q3, written in a form suitable for exact
+ // computation with integers.
+ //
+ // Due to finite precision some double roots may be missed, and considered
+ // to be a pair of complex roots z = x +/- epsilon i close to the real
+ // axis.
+ Real sqrtQ = sqrt (Q);
+ if (R > 0) {
+ *x0 = -2 * sqrtQ - a / 3;
+ *x1 = sqrtQ - a / 3;
+ *x2 = sqrtQ - a / 3;
+ } else {
+ *x0 = -sqrtQ - a / 3;
+ *x1 = -sqrtQ - a / 3;
+ *x2 = 2 * sqrtQ - a / 3;
+ }
+ return 3;
+
+ } else if (CR2 < CQ3) {
+ // This case is equivalent to R2 < Q3.
+ Real sqrtQ = sqrt (Q);
+ Real sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
+ Real theta = acos (R / sqrtQ3);
+ Real norm = -2 * sqrtQ;
+ *x0 = norm * cos (theta / 3) - a / 3;
+ *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3;
+ *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3;
+
+ // Put the roots in ascending order.
+ if (*x0 > *x1) {
+ std::swap(*x0, *x1);
+ }
+ if (*x1 > *x2) {
+ std::swap(*x1, *x2);
+ if (*x0 > *x1) {
+ std::swap(*x0, *x1);
+ }
+ }
+ return 3;
+ }
+ Real sgnR = (R >= 0 ? 1 : -1);
+ Real A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0);
+ Real B = Q / A ;
+ *x0 = A + B - a / 3;
+ return 1;
+}
+
+// The coefficients are in ascending powers, i.e. coeffs[N]*x^N.
+template<typename Real>
+int SolveCubicPolynomial(const Real *coeffs, Real *solutions) {
+ if (coeffs[0] == 0.0) {
+ // TODO(keir): This is a quadratic not a cubic. Implement a quadratic
+ // solver!
+ return 0;
+ }
+ Real a = coeffs[2] / coeffs[3];
+ Real b = coeffs[1] / coeffs[3];
+ Real c = coeffs[0] / coeffs[3];
+ return SolveCubicPolynomial(a, b, c,
+ solutions + 0,
+ solutions + 1,
+ solutions + 2);
+}
+} // namespace libmv
+#endif // LIBMV_NUMERIC_POLY_H_
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc
new file mode 100644
index 00000000000..cb8822dcf44
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/bundle.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#define V3DLIB_ENABLE_SUITESPARSE 1
+
+#include <map>
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/fundamental.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+#include "libmv/simple_pipeline/tracks.h"
+#include "third_party/ssba/Geometry/v3d_cameramatrix.h"
+#include "third_party/ssba/Geometry/v3d_metricbundle.h"
+#include "third_party/ssba/Math/v3d_linear.h"
+#include "third_party/ssba/Math/v3d_linear_utils.h"
+
+namespace libmv {
+
+void EuclideanBundle(const Tracks &tracks,
+ EuclideanReconstruction *reconstruction) {
+ vector<Marker> markers = tracks.AllMarkers();
+
+ // "index" in this context is the index that V3D's optimizer will see. The
+ // V3D index must be dense in that the cameras are numbered 0...n-1, which is
+ // not the case for the "image" numbering that arises from the tracks
+ // structure. The complicated mapping is necessary to convert between the two
+ // representations.
+ std::map<EuclideanCamera *, int> camera_to_index;
+ std::map<EuclideanPoint *, int> point_to_index;
+ vector<EuclideanCamera *> index_to_camera;
+ vector<EuclideanPoint *> index_to_point;
+ int num_cameras = 0;
+ int num_points = 0;
+ for (int i = 0; i < markers.size(); ++i) {
+ const Marker &marker = markers[i];
+ EuclideanCamera *camera = reconstruction->CameraForImage(marker.image);
+ EuclideanPoint *point = reconstruction->PointForTrack(marker.track);
+ if (camera && point) {
+ if (camera_to_index.find(camera) == camera_to_index.end()) {
+ camera_to_index[camera] = num_cameras;
+ index_to_camera.push_back(camera);
+ num_cameras++;
+ }
+ if (point_to_index.find(point) == point_to_index.end()) {
+ point_to_index[point] = num_points;
+ index_to_point.push_back(point);
+ num_points++;
+ }
+ }
+ }
+
+ // Make a V3D identity matrix, needed in a few places for K, since this
+ // assumes a calibrated setup.
+ V3D::Matrix3x3d identity3x3;
+ identity3x3[0][0] = 1.0;
+ identity3x3[0][1] = 0.0;
+ identity3x3[0][2] = 0.0;
+ identity3x3[1][0] = 0.0;
+ identity3x3[1][1] = 1.0;
+ identity3x3[1][2] = 0.0;
+ identity3x3[2][0] = 0.0;
+ identity3x3[2][1] = 0.0;
+ identity3x3[2][2] = 1.0;
+
+ // Convert libmv's cameras to V3D's cameras.
+ std::vector<V3D::CameraMatrix> v3d_cameras(index_to_camera.size());
+ for (int k = 0; k < index_to_camera.size(); ++k) {
+ V3D::Matrix3x3d R;
+ V3D::Vector3d t;
+
+ // Libmv's rotation matrix type.
+ const Mat3 &R_libmv = index_to_camera[k]->R;
+ const Vec3 &t_libmv = index_to_camera[k]->t;
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ R[i][j] = R_libmv(i, j);
+ }
+ t[i] = t_libmv(i);
+ }
+ v3d_cameras[k].setIntrinsic(identity3x3);
+ v3d_cameras[k].setRotation(R);
+ v3d_cameras[k].setTranslation(t);
+ }
+ LG << "Number of cameras: " << index_to_camera.size();
+
+ // Convert libmv's points to V3D's points.
+ std::vector<V3D::Vector3d> v3d_points(index_to_point.size());
+ for (int i = 0; i < index_to_point.size(); i++) {
+ v3d_points[i][0] = index_to_point[i]->X(0);
+ v3d_points[i][1] = index_to_point[i]->X(1);
+ v3d_points[i][2] = index_to_point[i]->X(2);
+ }
+ LG << "Number of points: " << index_to_point.size();
+
+ // Convert libmv's measurements to v3d measurements.
+ int num_residuals = 0;
+ std::vector<V3D::Vector2d> v3d_measurements;
+ std::vector<int> v3d_camera_for_measurement;
+ std::vector<int> v3d_point_for_measurement;
+ for (int i = 0; i < markers.size(); ++i) {
+ EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
+ EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+ if (!camera || !point) {
+ continue;
+ }
+ V3D::Vector2d v3d_point;
+ v3d_point[0] = markers[i].x;
+ v3d_point[1] = markers[i].y;
+ v3d_measurements.push_back(v3d_point);
+ v3d_camera_for_measurement.push_back(camera_to_index[camera]);
+ v3d_point_for_measurement.push_back(point_to_index[point]);
+ num_residuals++;
+ }
+ LG << "Number of residuals: " << num_residuals;
+
+ // This is calibrated reconstruction, so use zero distortion.
+ V3D::StdDistortionFunction v3d_distortion;
+ v3d_distortion.k1 = 0;
+ v3d_distortion.k2 = 0;
+ v3d_distortion.p1 = 0;
+ v3d_distortion.p2 = 0;
+
+ // Finally, run the bundle adjustment.
+ double const inlierThreshold = 500000.0;
+ V3D::CommonInternalsMetricBundleOptimizer opt(V3D::FULL_BUNDLE_METRIC,
+ inlierThreshold,
+ identity3x3,
+ v3d_distortion,
+ v3d_cameras,
+ v3d_points,
+ v3d_measurements,
+ v3d_camera_for_measurement,
+ v3d_point_for_measurement);
+ opt.maxIterations = 50;
+ opt.minimize();
+ LG << "Bundle status: " << opt.status;
+
+ // Convert V3D's cameras back to libmv's cameras.
+ for (int k = 0; k < num_cameras; k++) {
+ V3D::Matrix3x4d const Rt = v3d_cameras[k].getOrientation();
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ index_to_camera[k]->R(i, j) = Rt[i][j];
+ }
+ index_to_camera[k]->t(i) = Rt[i][3];
+ }
+ }
+
+ // Convert V3D's points back to libmv's points.
+ for (int k = 0; k < num_points; k++) {
+ for (int i = 0; i < 3; ++i) {
+ index_to_point[k]->X(i) = v3d_points[k][i];
+ }
+ }
+}
+
+void ProjectiveBundle(const Tracks & /*tracks*/,
+ ProjectiveReconstruction * /*reconstruction*/) {
+ // TODO(keir): Implement this! This can't work until we have a better bundler
+ // than SSBA, since SSBA has no support for projective bundling.
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.h b/extern/libmv/libmv/simple_pipeline/bundle.h
new file mode 100644
index 00000000000..c7fb2a79607
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/bundle.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_BUNDLE_H
+#define LIBMV_SIMPLE_PIPELINE_BUNDLE_H
+
+namespace libmv {
+
+class EuclideanReconstruction;
+class ProjectiveReconstruction;
+class Tracks;
+
+/*!
+ Refine camera poses and 3D coordinates using bundle adjustment.
+
+ This routine adjusts all cameras and points in \a *reconstruction. This
+ assumes a full observation for reconstructed tracks; this implies that if
+ there is a reconstructed 3D point (a bundle) for a track, then all markers
+ for that track will be included in the minimization. \a tracks should
+ contain markers used in the initial reconstruction.
+
+ The cameras and bundles (3D points) are refined in-place.
+
+ \note This assumes an outlier-free set of markers.
+ \note This assumes a calibrated reconstruction, e.g. the markers are
+ already corrected for camera intrinsics and radial distortion.
+
+ \sa EuclideanResect, EuclideanIntersect, EuclideanReconstructTwoFrames
+*/
+void EuclideanBundle(const Tracks &tracks,
+ EuclideanReconstruction *reconstruction);
+
+/*!
+ Refine camera poses and 3D coordinates using bundle adjustment.
+
+ This routine adjusts all cameras and points in \a *reconstruction. This
+ assumes a full observation for reconstructed tracks; this implies that if
+ there is a reconstructed 3D point (a bundle) for a track, then all markers
+ for that track will be included in the minimization. \a tracks should
+ contain markers used in the initial reconstruction.
+
+ The cameras and bundles (homogeneous 3D points) are refined in-place.
+
+ \note This assumes an outlier-free set of markers.
+ \note This assumes that radial distortion is already corrected for, but
+ does not assume that that other intrinsics are.
+
+ \sa ProjectiveResect, ProjectiveIntersect, ProjectiveReconstructTwoFrames
+*/
+void ProjectiveBundle(const Tracks &tracks,
+ ProjectiveReconstruction *reconstruction);
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_BUNDLE_H
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
new file mode 100644
index 00000000000..366129dd3d2
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
@@ -0,0 +1,351 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+
+namespace libmv {
+
+struct Offset {
+ signed char ix, iy;
+ unsigned char fx,fy;
+};
+
+struct Grid {
+ struct Offset *offset;
+ int width, height;
+ double overscan;
+};
+
+static struct Grid *copyGrid(struct Grid *from)
+{
+ struct Grid *to = NULL;
+
+ if (from) {
+ to = new Grid;
+
+ to->width = from->width;
+ to->height = from->height;
+ to->overscan = from->overscan;
+
+ to->offset = new Offset[to->width*to->height];
+ memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height);
+ }
+
+ return to;
+}
+
+CameraIntrinsics::CameraIntrinsics()
+ : K_(Mat3::Identity()),
+ image_width_(0),
+ image_height_(0),
+ k1_(0),
+ k2_(0),
+ k3_(0),
+ p1_(0),
+ p2_(0),
+ distort_(0),
+ undistort_(0) {}
+
+CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from)
+ : K_(from.K_),
+ image_width_(from.image_width_),
+ image_height_(from.image_height_),
+ k1_(from.k1_),
+ k2_(from.k2_),
+ k3_(from.k3_),
+ p1_(from.p1_),
+ p2_(from.p2_)
+{
+ distort_ = copyGrid(from.distort_);
+ undistort_ = copyGrid(from.undistort_);
+}
+
+CameraIntrinsics::~CameraIntrinsics() {
+ FreeLookupGrid();
+}
+
+/// Set the entire calibration matrix at once.
+void CameraIntrinsics::SetK(const Mat3 new_k) {
+ K_ = new_k;
+ FreeLookupGrid();
+}
+
+/// Set both x and y focal length in pixels.
+void CameraIntrinsics::SetFocalLength(double focal_x, double focal_y) {
+ K_(0, 0) = focal_x;
+ K_(1, 1) = focal_y;
+ FreeLookupGrid();
+}
+
+void CameraIntrinsics::SetPrincipalPoint(double cx, double cy) {
+ K_(0, 2) = cx;
+ K_(1, 2) = cy;
+ FreeLookupGrid();
+}
+
+void CameraIntrinsics::SetImageSize(int width, int height) {
+ image_width_ = width;
+ image_height_ = height;
+ FreeLookupGrid();
+}
+
+void CameraIntrinsics::SetRadialDistortion(double k1, double k2, double k3) {
+ k1_ = k1;
+ k2_ = k2;
+ k3_ = k3;
+ FreeLookupGrid();
+}
+
+void CameraIntrinsics::SetTangentialDistortion(double p1, double p2) {
+ p1_ = p1;
+ p2_ = p2;
+ FreeLookupGrid();
+}
+
+void CameraIntrinsics::ApplyIntrinsics(double normalized_x,
+ double normalized_y,
+ double *image_x,
+ double *image_y) const {
+ double x = normalized_x;
+ double y = normalized_y;
+
+ // Apply distortion to the normalized points to get (xd, yd).
+ double r2 = x*x + y*y;
+ double r4 = r2 * r2;
+ double r6 = r4 * r2;
+ double r_coeff = (1 + k1_*r2 + k2_*r4 + k3_*r6);
+ double xd = x * r_coeff + 2*p1_*x*y + p2_*(r2 + 2*x*x);
+ double yd = y * r_coeff + 2*p2_*x*y + p1_*(r2 + 2*y*y);
+
+ // Apply focal length and principal point to get the final image coordinates.
+ *image_x = focal_length_x() * xd + principal_point_x();
+ *image_y = focal_length_y() * yd + principal_point_y();
+}
+
+struct InvertIntrinsicsCostFunction {
+ public:
+ typedef Vec2 FMatrixType;
+ typedef Vec2 XMatrixType;
+
+ InvertIntrinsicsCostFunction(const CameraIntrinsics &intrinsics,
+ double image_x, double image_y)
+ : intrinsics(intrinsics), x(image_x), y(image_y) {}
+
+ Vec2 operator()(const Vec2 &u) const {
+ double xx, yy;
+ intrinsics.ApplyIntrinsics(u(0), u(1), &xx, &yy);
+ Vec2 fx;
+ fx << (xx - x), (yy - y);
+ return fx;
+ }
+ const CameraIntrinsics &intrinsics;
+ double x, y;
+};
+
+void CameraIntrinsics::InvertIntrinsics(double image_x,
+ double image_y,
+ double *normalized_x,
+ double *normalized_y) const {
+ // Compute the initial guess. For a camera with no distortion, this will also
+ // be the final answer; the LM iteration will terminate immediately.
+ Vec2 normalized;
+ normalized(0) = (image_x - principal_point_x()) / focal_length_x();
+ normalized(1) = (image_y - principal_point_y()) / focal_length_y();
+
+ typedef LevenbergMarquardt<InvertIntrinsicsCostFunction> Solver;
+
+ InvertIntrinsicsCostFunction intrinsics_cost(*this, image_x, image_y);
+ Solver::SolverParameters params;
+ Solver solver(intrinsics_cost);
+
+ /*Solver::Results results =*/ solver.minimize(params, &normalized);
+
+ // TODO(keir): Better error handling.
+
+ *normalized_x = normalized(0);
+ *normalized_y = normalized(1);
+}
+
+// TODO(MatthiasF): downsample lookup
+template<typename WarpFunction>
+void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, double overscan) {
+ double w = (double)width / (1 + overscan);
+ double h = (double)height / (1 + overscan);
+ double aspx = (double)w / image_width_;
+ double aspy = (double)h / image_height_;
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ double src_x = (x - 0.5 * overscan * w) / aspx, src_y = (y - 0.5 * overscan * h) / aspy;
+ double warp_x, warp_y;
+ WarpFunction(this,src_x,src_y,&warp_x,&warp_y);
+ warp_x = warp_x*aspx + 0.5 * overscan * w;
+ warp_y = warp_y*aspy + 0.5 * overscan * h;
+ int ix = int(warp_x), iy = int(warp_y);
+ int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256);
+ if(fx == 256) { fx=0; ix++; }
+ if(fy == 256) { fy=0; iy++; }
+ // Use nearest border pixel
+ if( ix < 0 ) { ix = 0, fx = 0; }
+ if( iy < 0 ) { iy = 0, fy = 0; }
+ if( ix >= width-2 ) ix = width-2;
+ if( iy >= height-2 ) iy = height-2;
+ if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) {
+ Offset offset = { ix-x, iy-y, fx, fy };
+ grid->offset[y*width+x] = offset;
+ } else {
+ Offset offset = { 0, 0, 0, 0 };
+ grid->offset[y*width+x] = offset;
+ }
+ }
+ }
+}
+
+// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
+template<typename T,int N>
+static void Warp(const Grid* grid, const T* src, T* dst,
+ int width, int height) {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ Offset offset = grid->offset[y*width+x];
+ const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N];
+ for (int i = 0; i < N; i++) {
+ dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy)
+ +(s[width*N+i] * (256-offset.fx) + s[width*N+N+i] * offset.fx) * offset.fy) / (256*256);
+ }
+ }
+ }
+}
+
+void CameraIntrinsics::FreeLookupGrid() {
+ if(distort_) {
+ delete distort_->offset;
+ delete distort_;
+ distort_ = NULL;
+ }
+
+ if(undistort_) {
+ delete undistort_->offset;
+ delete undistort_;
+ undistort_ = NULL;
+ }
+}
+
+// FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method.
+struct ApplyIntrinsicsFunction {
+ ApplyIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y,
+ double *warp_x, double *warp_y) {
+ intrinsics->ApplyIntrinsics(
+ (x-intrinsics->principal_point_x())/intrinsics->focal_length_x(),
+ (y-intrinsics->principal_point_y())/intrinsics->focal_length_y(),
+ warp_x, warp_y);
+ }
+};
+struct InvertIntrinsicsFunction {
+ InvertIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y,
+ double *warp_x, double *warp_y) {
+ intrinsics->InvertIntrinsics(x,y,warp_x,warp_y);
+ *warp_x = *warp_x*intrinsics->focal_length_x()+intrinsics->principal_point_x();
+ *warp_y = *warp_y*intrinsics->focal_length_y()+intrinsics->principal_point_y();
+ }
+};
+
+void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double overscan)
+{
+ if(distort_) {
+ if(distort_->width != width || distort_->height != height || distort_->overscan != overscan) {
+ delete [] distort_->offset;
+ distort_->offset = NULL;
+ }
+ } else {
+ distort_ = new Grid;
+ distort_->offset = NULL;
+ }
+
+ if(!distort_->offset) {
+ distort_->offset = new Offset[width*height];
+ ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height,overscan);
+ }
+
+ distort_->width = width;
+ distort_->height = height;
+ distort_->overscan = overscan;
+}
+
+void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double overscan)
+{
+ if(undistort_) {
+ if(undistort_->width != width || undistort_->height != height || undistort_->overscan != overscan) {
+ delete [] undistort_->offset;
+ undistort_->offset = NULL;
+ }
+ } else {
+ undistort_ = new Grid;
+ undistort_->offset = NULL;
+ }
+
+ if(!undistort_->offset) {
+ undistort_->offset = new Offset[width*height];
+ ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height,overscan);
+ }
+
+ undistort_->width = width;
+ undistort_->height = height;
+ undistort_->overscan = overscan;
+}
+
+void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, double overscan, int channels) {
+ CheckDistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<float,1>(distort_,src,dst,width,height);
+ else if(channels==2) Warp<float,2>(distort_,src,dst,width,height);
+ else if(channels==3) Warp<float,3>(distort_,src,dst,width,height);
+ else if(channels==4) Warp<float,4>(distort_,src,dst,width,height);
+ //else assert("channels must be between 1 and 4");
+}
+
+void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) {
+ CheckDistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height);
+ else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height);
+ else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height);
+ else if(channels==4) Warp<unsigned char,4>(distort_,src,dst,width,height);
+ //else assert("channels must be between 1 and 4");
+}
+
+void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, double overscan, int channels) {
+ CheckUndistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<float,1>(undistort_,src,dst,width,height);
+ else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height);
+ else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height);
+ else if(channels==4) Warp<float,4>(undistort_,src,dst,width,height);
+ //else assert("channels must be between 1 and 4");
+}
+
+void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) {
+ CheckUndistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height);
+ else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height);
+ else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height);
+ else if(channels==4) Warp<unsigned char,4>(undistort_,src,dst,width,height);
+ //else assert("channels must be between 1 and 4");
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
new file mode 100644
index 00000000000..f4bf903c36c
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
@@ -0,0 +1,152 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
+#define LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
+
+#include <Eigen/Core>
+typedef Eigen::Matrix<double, 3, 3> Mat3;
+
+namespace libmv {
+
+struct Grid;
+
+class CameraIntrinsics {
+ public:
+ CameraIntrinsics();
+ CameraIntrinsics(const CameraIntrinsics &from);
+ ~CameraIntrinsics();
+
+ const Mat3 &K() const { return K_; }
+ // FIXME(MatthiasF): these should be CamelCase methods
+ double focal_length() const { return K_(0, 0); }
+ double focal_length_x() const { return K_(0, 0); }
+ double focal_length_y() const { return K_(1, 1); }
+ double principal_point_x() const { return K_(0, 2); }
+ double principal_point_y() const { return K_(1, 2); }
+ int image_width() const { return image_width_; }
+ int image_height() const { return image_height_; }
+ double k1() const { return k1_; }
+ double k2() const { return k2_; }
+ double k3() const { return k3_; }
+ double p1() const { return p1_; }
+ double p2() const { return p2_; }
+
+ /// Set the entire calibration matrix at once.
+ void SetK(const Mat3 new_k);
+
+ /// Set both x and y focal length in pixels.
+ void SetFocalLength(double focal_x, double focal_y);
+
+ void SetPrincipalPoint(double cx, double cy);
+
+ void SetImageSize(int width, int height);
+
+ void SetRadialDistortion(double k1, double k2, double k3 = 0);
+
+ void SetTangentialDistortion(double p1, double p2);
+
+ /*!
+ Apply camera intrinsics to the normalized point to get image coordinates.
+
+ This applies the lens distortion to a point which is in normalized
+ camera coordinates (i.e. the principal point is at (0, 0)) to get image
+ coordinates in pixels.
+ */
+ void ApplyIntrinsics(double normalized_x, double normalized_y,
+ double *image_x, double *image_y) const;
+
+ /*!
+ Invert camera intrinsics on the image point to get normalized coordinates.
+
+ This reverses the effect of lens distortion on a point which is in image
+ coordinates to get normalized camera coordinates.
+ */
+ void InvertIntrinsics(double image_x, double image_y,
+ double *normalized_x, double *normalized_y) const;
+
+ /*!
+ Distort an image using the current camera instrinsics
+
+ The distorted image is computed in \a dst using samples from \a src.
+ both buffers should be \a width x \a height x \a channels sized.
+
+ \note This is the reference implementation using floating point images.
+ */
+ void Distort(const float* src, float* dst,
+ int width, int height, double overscan, int channels);
+ /*!
+ Distort an image using the current camera instrinsics
+
+ The distorted image is computed in \a dst using samples from \a src.
+ both buffers should be \a width x \a height x \a channels sized.
+
+ \note This version is much faster.
+ */
+ void Distort(const unsigned char* src, unsigned char* dst,
+ int width, int height, double overscan, int channels);
+ /*!
+ Undistort an image using the current camera instrinsics
+
+ The undistorted image is computed in \a dst using samples from \a src.
+ both buffers should be \a width x \a height x \a channels sized.
+
+ \note This is the reference implementation using floating point images.
+ */
+ void Undistort(const float* src, float* dst,
+ int width, int height, double overscan, int channels);
+ /*!
+ Undistort an image using the current camera instrinsics
+
+ The undistorted image is computed in \a dst using samples from \a src.
+ both buffers should be \a width x \a height x \a channels sized.
+
+ \note This version is much faster.
+ */
+ void Undistort(const unsigned char* src, unsigned char* dst,
+ int width, int height, double overscan, int channels);
+
+ private:
+ template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height, double overscan);
+ void CheckUndistortLookupGrid(int width, int height, double overscan);
+ void CheckDistortLookupGrid(int width, int height, double overscan);
+ void FreeLookupGrid();
+
+ // The traditional intrinsics matrix from x = K[R|t]X.
+ Mat3 K_;
+
+ // This is the size of the image. This is necessary to, for example, handle
+ // the case of processing a scaled image.
+ int image_width_;
+ int image_height_;
+
+ // OpenCV's distortion model with third order polynomial radial distortion
+ // terms and second order tangential distortion. The distortion is applied to
+ // the normalized coordinates before the focal length, which makes them
+ // independent of image size.
+ double k1_, k2_, k3_, p1_, p2_;
+
+ struct Grid *distort_;
+ struct Grid *undistort_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_
diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc
new file mode 100644
index 00000000000..8ac42ab0aba
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/detect.cc
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (c) 2011 libmv authors.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to
+** deal in the Software without restriction, including without limitation the
+** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+** sell copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+** IN THE SOFTWARE.
+**
+****************************************************************************/
+
+#include "libmv/simple_pipeline/detect.h"
+#include <third_party/fast/fast.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+namespace libmv {
+
+typedef unsigned int uint;
+
+int featurecmp(const void *a_v, const void *b_v)
+{
+ Feature *a = (Feature*)a_v;
+ Feature *b = (Feature*)b_v;
+
+ return b->score - a->score;
+}
+
+std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride,
+ int min_trackness, int min_distance) {
+ std::vector<Feature> features;
+ // TODO(MatthiasF): Support targetting a feature count (binary search trackness)
+ int num_features;
+ xy* all = fast9_detect(data, width, height,
+ stride, min_trackness, &num_features);
+ if(num_features == 0) {
+ free(all);
+ return features;
+ }
+ int* scores = fast9_score(data, stride, all, num_features, min_trackness);
+ // TODO: merge with close feature suppression
+ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features);
+ free(all);
+ // Remove too close features
+ // TODO(MatthiasF): A resolution independent parameter would be better than distance
+ // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing)
+ // FIXME(MatthiasF): this method will not necessarily give all maximum markers
+ if(num_features) {
+ Feature *all_features = new Feature[num_features];
+
+ for(int i = 0; i < num_features; ++i) {
+ Feature a = { nonmax[i].x, nonmax[i].y, scores[i], 0 };
+ all_features[i] = a;
+ }
+
+ qsort((void *)all_features, num_features, sizeof(Feature), featurecmp);
+
+ features.reserve(num_features);
+
+ int prev_score = all_features[0].score;
+ for(int i = 0; i < num_features; ++i) {
+ bool ok = true;
+ Feature a = all_features[i];
+ if(a.score>prev_score)
+ abort();
+ prev_score = a.score;
+
+ // compare each feature against filtered set
+ for(int j = 0; j < features.size(); j++) {
+ Feature& b = features[j];
+ if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) {
+ // already a nearby feature
+ ok = false;
+ break;
+ }
+ }
+
+ if(ok) {
+ // add the new feature
+ features.push_back(a);
+ }
+ }
+
+ delete [] all_features;
+ }
+ free(scores);
+ free(nonmax);
+ return features;
+}
+
+#ifdef __SSE2__
+static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) {
+ __m128i a = _mm_setzero_si128();
+ for(int i = 0; i < 16; i++) {
+ a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(imageA+i*strideA)),
+ _mm_loadu_si128((__m128i*)(imageB+i*strideB))));
+ }
+ return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4);
+}
+#else
+static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) {
+ uint sad=0;
+ for(int i = 0; i < 16; i++) {
+ for(int j = 0; j < 16; j++) {
+ sad += abs((int)imageA[i*strideA+j] - imageB[i*strideB+j]);
+ }
+ }
+ return sad;
+}
+#endif
+
+void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
+ unsigned short histogram[256];
+ memset(histogram,0,sizeof(histogram));
+ ubyte* scores = new ubyte[width*height];
+ memset(scores,0,width*height);
+ const int r = 1; //radius for self similarity comparison
+ for(int y=distance; y<height-distance; y++) {
+ for(int x=distance; x<width-distance; x++) {
+ ubyte* s = &image[y*stride+x];
+ int score = // low self-similarity with overlapping patterns //OPTI: load pattern once
+ SAD(s, s-r*stride-r, stride, stride)+SAD(s, s-r*stride, stride, stride)+SAD(s, s-r*stride+r, stride, stride)+
+ SAD(s, s -r, stride, stride)+ SAD(s, s +r, stride, stride)+
+ SAD(s, s+r*stride-r, stride, stride)+SAD(s, s+r*stride, stride, stride)+SAD(s, s+r*stride+r, stride, stride);
+ score /= 256; // normalize
+ if(pattern) score -= SAD(s, pattern, stride, 16); // find only features similar to pattern
+ if(score<=16) continue; // filter very self-similar features
+ score -= 16; // translate to score/histogram values
+ if(score>255) score=255; // clip
+ ubyte* c = &scores[y*width+x];
+ for(int i=-distance; i<0; i++) {
+ for(int j=-distance; j<distance; j++) {
+ int s = c[i*width+j];
+ if(s == 0) continue;
+ if(s >= score) goto nonmax;
+ c[i*width+j]=0, histogram[s]--;
+ }
+ }
+ for(int i=0, j=-distance; j<0; j++) {
+ int s = c[i*width+j];
+ if(s == 0) continue;
+ if(s >= score) goto nonmax;
+ c[i*width+j]=0, histogram[s]--;
+ }
+ c[0] = score, histogram[score]++;
+ nonmax:;
+ }
+ }
+ int min=255, total=0;
+ for(; min>0; min--) {
+ int h = histogram[min];
+ if(total+h > *count) break;
+ total += h;
+ }
+ int i=0;
+ for(int y=16; y<height-16; y++) {
+ for(int x=16; x<width-16; x++) {
+ int s = scores[y*width+x];
+ Feature f = { x+8, y+8, s, 16 };
+ if(s>min) detected[i++] = f;
+ }
+ }
+ *count = i;
+ delete[] scores;
+}
+
+}
diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h
new file mode 100644
index 00000000000..bbe7aed784c
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/detect.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (c) 2011 libmv authors.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to
+** deal in the Software without restriction, including without limitation the
+** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+** sell copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+** IN THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
+#define LIBMV_SIMPLE_PIPELINE_DETECT_H_
+
+#include <vector>
+
+namespace libmv {
+
+typedef unsigned char ubyte;
+
+/*!
+ A Feature is the 2D location of a detected feature in an image.
+
+ \a x, \a y is the position of the feature in pixels from the top left corner.
+ \a score is an estimate of how well the feature will be tracked.
+ \a size can be used as an initial pattern size to track the feature.
+
+ \sa Detect
+*/
+struct Feature {
+ /// Position in pixels (from top-left corner)
+ /// \note libmv might eventually support subpixel precision.
+ float x, y;
+ /// Trackness of the feature
+ float score;
+ /// Size of the feature in pixels
+ float size;
+};
+
+/*!
+ Detect features in an image.
+
+ You need to input a single channel 8-bit image using pointer to image \a data,
+ \a width, \a height and \a stride (i.e bytes per line).
+
+ You can tweak the count of detected features using \a min_trackness, which is
+ the minimum score to add a feature, and \a min_distance which is the minimal
+ distance accepted between two featuress.
+
+ \note You can binary search over \a min_trackness to get a given feature count.
+
+ \note a way to get an uniform distribution of a given feature count is:
+ \a min_distance = \a width * \a height / desired_feature_count ^ 2
+
+ \return All detected feartures matching given parameters
+*/
+std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height,
+ int stride, int min_trackness = 128,
+ int min_distance = 120);
+
+/*!
+ Detect features in an image.
+
+ \a image is a single channel 8-bit image of size \a width x \a height
+
+ \a detected is an array with space to hold \a *count features.
+ \a *count is the maximum count to detect on input and the actual
+ detected count on output.
+
+ \a distance is the minimal distance between detected features.
+
+ if \a pattern is null all good features will be found.
+ if \a pattern is not null only features similar to \a pattern will be found.
+
+ \note \a You can crop the image (to avoid detecting markers near the borders) without copying:
+ image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY;
+*/
+void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
+
+}
+
+#endif
diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
new file mode 100644
index 00000000000..0597f09f728
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc
@@ -0,0 +1,218 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/fundamental.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+#include "libmv/simple_pipeline/tracks.h"
+
+namespace libmv {
+namespace {
+
+void CoordinatesForMarkersInImage(const vector<Marker> &markers,
+ int image,
+ Mat *coordinates) {
+ vector<Vec2> coords;
+ for (int i = 0; i < markers.size(); ++i) {
+ const Marker &marker = markers[i];
+ if (markers[i].image == image) {
+ coords.push_back(Vec2(marker.x, marker.y));
+ }
+ }
+ coordinates->resize(2, coords.size());
+ for (int i = 0; i < coords.size(); i++) {
+ coordinates->col(i) = coords[i];
+ }
+}
+
+void GetImagesInMarkers(const vector<Marker> &markers,
+ int *image1, int *image2) {
+ if (markers.size() < 2) {
+ return;
+ }
+ *image1 = markers[0].image;
+ for (int i = 1; i < markers.size(); ++i) {
+ if (markers[i].image != *image1) {
+ *image2 = markers[i].image;
+ return;
+ }
+ }
+ *image2 = -1;
+ LOG(FATAL) << "Only one image in the markers.";
+}
+
+} // namespace
+
+bool EuclideanReconstructTwoFrames(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction) {
+ if (markers.size() < 16) {
+ return false;
+ }
+
+ int image1, image2;
+ GetImagesInMarkers(markers, &image1, &image2);
+
+ Mat x1, x2;
+ CoordinatesForMarkersInImage(markers, image1, &x1);
+ CoordinatesForMarkersInImage(markers, image2, &x2);
+
+ Mat3 F;
+ NormalizedEightPointSolver(x1, x2, &F);
+
+ // The F matrix should be an E matrix, but squash it just to be sure.
+ Eigen::JacobiSVD<Mat3> svd(F, Eigen::ComputeFullU | Eigen::ComputeFullV);
+
+ // See Hartley & Zisserman page 294, result 11.1, which shows how to get the
+ // closest essential matrix to a matrix that is "almost" an essential matrix.
+ double a = svd.singularValues()(0);
+ double b = svd.singularValues()(1);
+ double s = (a + b) / 2.0;
+ LG << "Initial reconstruction's rotation is non-euclidean by "
+ << (((a - b) / std::max(a, b)) * 100) << "%; singular values:"
+ << svd.singularValues().transpose();
+
+ Vec3 diag;
+ diag << s, s, 0;
+ Mat3 E = svd.matrixU() * diag.asDiagonal() * svd.matrixV().transpose();
+
+ // Recover motion between the two images. Since this function assumes a
+ // calibrated camera, use the identity for K.
+ Mat3 R;
+ Vec3 t;
+ Mat3 K = Mat3::Identity();
+ if (!MotionFromEssentialAndCorrespondence(E,
+ K, x1.col(0),
+ K, x2.col(0),
+ &R, &t)) {
+ return false;
+ }
+
+ // Image 1 gets the reference frame, image 2 gets the relative motion.
+ reconstruction->InsertCamera(image1, Mat3::Identity(), Vec3::Zero());
+ reconstruction->InsertCamera(image2, R, t);
+
+ LG << "From two frame reconstruction got:\nR:\n" << R
+ << "\nt:" << t.transpose();
+ return true;
+}
+
+namespace {
+
+Mat3 DecodeF(const Vec9 &encoded_F) {
+ // Decode F and force it to be rank 2.
+ Map<const Mat3> full_rank_F(encoded_F.data(), 3, 3);
+ Eigen::JacobiSVD<Mat3> svd(full_rank_F, Eigen::ComputeFullU | Eigen::ComputeFullV);
+ Vec3 diagonal = svd.singularValues();
+ diagonal(2) = 0;
+ Mat3 F = svd.matrixU() * diagonal.asDiagonal() * svd.matrixV().transpose();
+ return F;
+}
+
+// This is the stupidest way to refine F known to mankind, since it requires
+// doing a full SVD of F at each iteration. This uses sampson error.
+struct FundamentalSampsonCostFunction {
+ public:
+ typedef Vec FMatrixType;
+ typedef Vec9 XMatrixType;
+
+ // Assumes markers are ordered by track.
+ FundamentalSampsonCostFunction(const vector<Marker> &markers)
+ : markers(markers) {}
+
+ Vec operator()(const Vec9 &encoded_F) const {
+ // Decode F and force it to be rank 2.
+ Mat3 F = DecodeF(encoded_F);
+
+ Vec residuals(markers.size() / 2);
+ residuals.setZero();
+ for (int i = 0; i < markers.size() / 2; ++i) {
+ const Marker &marker1 = markers[2*i + 0];
+ const Marker &marker2 = markers[2*i + 1];
+ CHECK_EQ(marker1.track, marker2.track);
+ Vec2 x1(marker1.x, marker1.y);
+ Vec2 x2(marker2.x, marker2.y);
+
+ residuals[i] = SampsonDistance(F, x1, x2);
+ }
+ return residuals;
+ }
+ const vector<Marker> &markers;
+};
+
+} // namespace
+
+bool ProjectiveReconstructTwoFrames(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction) {
+ if (markers.size() < 16) {
+ return false;
+ }
+
+ int image1, image2;
+ GetImagesInMarkers(markers, &image1, &image2);
+
+ Mat x1, x2;
+ CoordinatesForMarkersInImage(markers, image1, &x1);
+ CoordinatesForMarkersInImage(markers, image2, &x2);
+
+ Mat3 F;
+ NormalizedEightPointSolver(x1, x2, &F);
+
+ // XXX Verify sampson distance.
+#if 0
+ // Refine the resulting projection fundamental matrix using Sampson's
+ // approximation of geometric error. This avoids having to do a full bundle
+ // at the cost of some accuracy.
+ //
+ // TODO(keir): After switching to a better bundling library, use a proper
+ // full bundle adjust here instead of this lame bundle adjustment.
+ typedef LevenbergMarquardt<FundamentalSampsonCostFunction> Solver;
+
+ FundamentalSampsonCostFunction fundamental_cost(markers);
+
+ // Pack the initial P matrix into a size-12 vector..
+ Vec9 encoded_F = Map<Vec9>(F.data(), 3, 3);
+
+ Solver solver(fundamental_cost);
+
+ Solver::SolverParameters params;
+ Solver::Results results = solver.minimize(params, &encoded_F);
+ // TODO(keir): Check results to ensure clean termination.
+
+ // Recover F from the minimization.
+ F = DecodeF(encoded_F);
+#endif
+
+ // Image 1 gets P = [I|0], image 2 gets arbitrary P.
+ Mat34 P1 = Mat34::Zero();
+ P1.block<3, 3>(0, 0) = Mat3::Identity();
+ Mat34 P2;
+ ProjectionsFromFundamental(F, &P1, &P2);
+
+ reconstruction->InsertCamera(image1, P1);
+ reconstruction->InsertCamera(image2, P2);
+
+ LG << "From two frame reconstruction got P2:\n" << P2;
+ return true;
+}
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h
new file mode 100644
index 00000000000..f512c9a3439
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H
+#define LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H
+
+#include "libmv/base/vector.h"
+
+namespace libmv {
+
+struct Marker;
+class EuclideanReconstruction;
+class ProjectiveReconstruction;
+
+/*!
+ Initialize the \link EuclideanReconstruction reconstruction \endlink using
+ two frames.
+
+ \a markers should contain all \l Marker markers \endlink belonging to
+ tracks visible in both frames. The pose estimation of the camera for
+ these frames will be inserted into \a *reconstruction.
+
+ \note The two frames need to have both enough parallax and enough common tracks
+ for accurate reconstruction. At least 8 tracks are suggested.
+ \note The origin of the coordinate system is defined to be the camera of
+ the first keyframe.
+ \note This assumes a calibrated reconstruction, e.g. the markers are
+ already corrected for camera intrinsics and radial distortion.
+ \note This assumes an outlier-free set of markers.
+
+ \sa EuclideanResect, EuclideanIntersect, EuclideanBundle
+*/
+bool EuclideanReconstructTwoFrames(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction);
+
+/*!
+ Initialize the \link ProjectiveReconstruction reconstruction \endlink using
+ two frames.
+
+ \a markers should contain all \l Marker markers \endlink belonging to
+ tracks visible in both frames. An estimate of the projection matrices for
+ the two frames will get added to the reconstruction.
+
+ \note The two frames need to have both enough parallax and enough common tracks
+ for accurate reconstruction. At least 8 tracks are suggested.
+ \note The origin of the coordinate system is defined to be the camera of
+ the first keyframe.
+ \note This assumes the markers are already corrected for radial distortion.
+ \note This assumes an outlier-free set of markers.
+
+ \sa ProjectiveResect, ProjectiveIntersect, ProjectiveBundle
+*/
+bool ProjectiveReconstructTwoFrames(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction);
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H
diff --git a/extern/libmv/libmv/simple_pipeline/intersect.cc b/extern/libmv/libmv/simple_pipeline/intersect.cc
new file mode 100644
index 00000000000..b1518e04651
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/intersect.cc
@@ -0,0 +1,205 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/multiview/triangulation.h"
+#include "libmv/multiview/nviewtriangulation.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+#include "libmv/simple_pipeline/tracks.h"
+
+namespace libmv {
+
+namespace {
+
+struct EuclideanIntersectCostFunction {
+ public:
+ typedef Vec FMatrixType;
+ typedef Vec3 XMatrixType;
+
+ EuclideanIntersectCostFunction(const vector<Marker> &markers,
+ const EuclideanReconstruction &reconstruction)
+ : markers(markers),
+ reconstruction(reconstruction) {}
+
+ Vec operator()(const Vec3 &X) const {
+ Vec residuals(2 * markers.size());
+ residuals.setZero();
+ for (int i = 0; i < markers.size(); ++i) {
+ const EuclideanCamera &camera =
+ *reconstruction.CameraForImage(markers[i].image);
+ Vec3 projected = camera.R * X + camera.t;
+ projected /= projected(2);
+ residuals[2*i + 0] = projected(0) - markers[i].x;
+ residuals[2*i + 1] = projected(1) - markers[i].y;
+ }
+ return residuals;
+ }
+ const vector<Marker> &markers;
+ const EuclideanReconstruction &reconstruction;
+};
+
+} // namespace
+
+bool EuclideanIntersect(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction) {
+ if (markers.size() < 2) {
+ return false;
+ }
+
+ // Compute projective camera matrices for the cameras the intersection is
+ // going to use.
+ Mat3 K = Mat3::Identity();
+ vector<Mat34> cameras;
+ Mat34 P;
+ for (int i = 0; i < markers.size(); ++i) {
+ EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
+ P_From_KRt(K, camera->R, camera->t, &P);
+ cameras.push_back(P);
+ }
+
+ // Stack the 2D coordinates together as required by NViewTriangulate.
+ Mat2X points(2, markers.size());
+ for (int i = 0; i < markers.size(); ++i) {
+ points(0, i) = markers[i].x;
+ points(1, i) = markers[i].y;
+ }
+
+ Vec4 Xp;
+ LG << "Intersecting with " << markers.size() << " markers.";
+ NViewTriangulateAlgebraic(points, cameras, &Xp);
+
+ // Get euclidean version of the homogeneous point.
+ Xp /= Xp(3);
+ Vec3 X = Xp.head<3>();
+
+ typedef LevenbergMarquardt<EuclideanIntersectCostFunction> Solver;
+
+ EuclideanIntersectCostFunction triangulate_cost(markers, *reconstruction);
+ Solver::SolverParameters params;
+ Solver solver(triangulate_cost);
+
+ Solver::Results results = solver.minimize(params, &X);
+
+ // Try projecting the point; make sure it's in front of everyone.
+ for (int i = 0; i < cameras.size(); ++i) {
+ const EuclideanCamera &camera =
+ *reconstruction->CameraForImage(markers[i].image);
+ Vec3 x = camera.R * X + camera.t;
+ if (x(2) < 0) {
+ LOG(ERROR) << "POINT BEHIND CAMERA " << markers[i].image
+ << ": " << x.transpose();
+ }
+ }
+
+ Vec3 point = X.head<3>();
+ reconstruction->InsertPoint(markers[0].track, point);
+
+ // TODO(keir): Add proper error checking.
+ return true;
+}
+
+namespace {
+
+struct ProjectiveIntersectCostFunction {
+ public:
+ typedef Vec FMatrixType;
+ typedef Vec4 XMatrixType;
+
+ ProjectiveIntersectCostFunction(
+ const vector<Marker> &markers,
+ const ProjectiveReconstruction &reconstruction)
+ : markers(markers), reconstruction(reconstruction) {}
+
+ Vec operator()(const Vec4 &X) const {
+ Vec residuals(2 * markers.size());
+ residuals.setZero();
+ for (int i = 0; i < markers.size(); ++i) {
+ const ProjectiveCamera &camera =
+ *reconstruction.CameraForImage(markers[i].image);
+ Vec3 projected = camera.P * X;
+ projected /= projected(2);
+ residuals[2*i + 0] = projected(0) - markers[i].x;
+ residuals[2*i + 1] = projected(1) - markers[i].y;
+ }
+ return residuals;
+ }
+ const vector<Marker> &markers;
+ const ProjectiveReconstruction &reconstruction;
+};
+
+} // namespace
+
+bool ProjectiveIntersect(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction) {
+ if (markers.size() < 2) {
+ return false;
+ }
+
+ // Get the cameras to use for the intersection.
+ vector<Mat34> cameras;
+ for (int i = 0; i < markers.size(); ++i) {
+ ProjectiveCamera *camera = reconstruction->CameraForImage(markers[i].image);
+ cameras.push_back(camera->P);
+ }
+
+ // Stack the 2D coordinates together as required by NViewTriangulate.
+ Mat2X points(2, markers.size());
+ for (int i = 0; i < markers.size(); ++i) {
+ points(0, i) = markers[i].x;
+ points(1, i) = markers[i].y;
+ }
+
+ Vec4 X;
+ LG << "Intersecting with " << markers.size() << " markers.";
+ NViewTriangulateAlgebraic(points, cameras, &X);
+ X /= X(3);
+
+ typedef LevenbergMarquardt<ProjectiveIntersectCostFunction> Solver;
+
+ ProjectiveIntersectCostFunction triangulate_cost(markers, *reconstruction);
+ Solver::SolverParameters params;
+ Solver solver(triangulate_cost);
+
+ Solver::Results results = solver.minimize(params, &X);
+ (void) results; // TODO(keir): Ensure results are good.
+
+ // Try projecting the point; make sure it's in front of everyone.
+ for (int i = 0; i < cameras.size(); ++i) {
+ const ProjectiveCamera &camera =
+ *reconstruction->CameraForImage(markers[i].image);
+ Vec3 x = camera.P * X;
+ if (x(2) < 0) {
+ LOG(ERROR) << "POINT BEHIND CAMERA " << markers[i].image
+ << ": " << x.transpose();
+ }
+ }
+
+ reconstruction->InsertPoint(markers[0].track, X);
+
+ // TODO(keir): Add proper error checking.
+ return true;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/intersect.h b/extern/libmv/libmv/simple_pipeline/intersect.h
new file mode 100644
index 00000000000..edbf4a0335b
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/intersect.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_INTERSECT_H
+#define LIBMV_SIMPLE_PIPELINE_INTERSECT_H
+
+#include "libmv/base/vector.h"
+#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+
+namespace libmv {
+
+/*!
+ Estimate the 3D coordinates of a track by intersecting rays from images.
+
+ This takes a set of markers, where each marker is for the same track but
+ different images, and reconstructs the 3D position of that track. Each of
+ the frames for which there is a marker for that track must have a
+ corresponding reconstructed camera in \a *reconstruction.
+
+ \a markers should contain all \l Marker markers \endlink belonging to
+ tracks visible in all frames.
+ \a reconstruction should contain the cameras for all frames.
+ The new \l Point points \endlink will be inserted in \a reconstruction.
+
+ \note This assumes a calibrated reconstruction, e.g. the markers are
+ already corrected for camera intrinsics and radial distortion.
+ \note This assumes an outlier-free set of markers.
+
+ \sa EuclideanResect
+*/
+bool EuclideanIntersect(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction);
+
+/*!
+ Estimate the homogeneous coordinates of a track by intersecting rays.
+
+ This takes a set of markers, where each marker is for the same track but
+ different images, and reconstructs the homogeneous 3D position of that
+ track. Each of the frames for which there is a marker for that track must
+ have a corresponding reconstructed camera in \a *reconstruction.
+
+ \a markers should contain all \l Marker markers \endlink belonging to
+ tracks visible in all frames.
+ \a reconstruction should contain the cameras for all frames.
+ The new \l Point points \endlink will be inserted in \a reconstruction.
+
+ \note This assumes that radial distortion is already corrected for, but
+ does not assume that e.g. focal length and principal point are
+ accounted for.
+ \note This assumes an outlier-free set of markers.
+
+ \sa Resect
+*/
+bool ProjectiveIntersect(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction);
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_INTERSECT_H
diff --git a/extern/libmv/libmv/simple_pipeline/pipeline.cc b/extern/libmv/libmv/simple_pipeline/pipeline.cc
new file mode 100644
index 00000000000..818c24cb5e7
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/pipeline.cc
@@ -0,0 +1,317 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <cstdio>
+
+#include "libmv/logging/logging.h"
+#include "libmv/simple_pipeline/bundle.h"
+#include "libmv/simple_pipeline/intersect.h"
+#include "libmv/simple_pipeline/resect.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
+namespace libmv {
+namespace {
+
+// These are "strategy" classes which make it possible to use the same code for
+// both projective and euclidean reconstruction.
+// FIXME(MatthiasF): OOP would achieve the same goal while avoiding
+// template bloat and making interface changes much easier.
+struct EuclideanPipelineRoutines {
+ typedef EuclideanReconstruction Reconstruction;
+ typedef EuclideanCamera Camera;
+ typedef EuclideanPoint Point;
+
+ static void Bundle(const Tracks &tracks,
+ EuclideanReconstruction *reconstruction) {
+ EuclideanBundle(tracks, reconstruction);
+ }
+
+ static bool Resect(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction, bool final_pass) {
+ return EuclideanResect(markers, reconstruction, final_pass);
+ }
+
+ static bool Intersect(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction) {
+ return EuclideanIntersect(markers, reconstruction);
+ }
+
+ static Marker ProjectMarker(const EuclideanPoint &point,
+ const EuclideanCamera &camera,
+ const CameraIntrinsics &intrinsics) {
+ Vec3 projected = camera.R * point.X + camera.t;
+ projected /= projected(2);
+
+ Marker reprojected_marker;
+ intrinsics.ApplyIntrinsics(projected(0),
+ projected(1),
+ &reprojected_marker.x,
+ &reprojected_marker.y);
+
+ reprojected_marker.image = camera.image;
+ reprojected_marker.track = point.track;
+ return reprojected_marker;
+ }
+};
+
+struct ProjectivePipelineRoutines {
+ typedef ProjectiveReconstruction Reconstruction;
+ typedef ProjectiveCamera Camera;
+ typedef ProjectivePoint Point;
+
+ static void Bundle(const Tracks &tracks,
+ ProjectiveReconstruction *reconstruction) {
+ ProjectiveBundle(tracks, reconstruction);
+ }
+
+ static bool Resect(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction, bool final_pass) {
+ return ProjectiveResect(markers, reconstruction);
+ }
+
+ static bool Intersect(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction) {
+ return ProjectiveIntersect(markers, reconstruction);
+ }
+
+ static Marker ProjectMarker(const ProjectivePoint &point,
+ const ProjectiveCamera &camera,
+ const CameraIntrinsics &intrinsics) {
+ Vec3 projected = camera.P * point.X;
+ projected /= projected(2);
+
+ Marker reprojected_marker;
+ intrinsics.ApplyIntrinsics(projected(0),
+ projected(1),
+ &reprojected_marker.x,
+ &reprojected_marker.y);
+
+ reprojected_marker.image = camera.image;
+ reprojected_marker.track = point.track;
+ return reprojected_marker;
+ }
+};
+
+} // namespace
+
+template<typename PipelineRoutines>
+void InternalCompleteReconstruction(
+ const Tracks &tracks,
+ typename PipelineRoutines::Reconstruction *reconstruction) {
+ int max_track = tracks.MaxTrack();
+ int max_image = tracks.MaxImage();
+ int num_resects = -1;
+ int num_intersects = -1;
+ LG << "Max track: " << max_track;
+ LG << "Max image: " << max_image;
+ LG << "Number of markers: " << tracks.NumMarkers();
+ while (num_resects != 0 || num_intersects != 0) {
+ // Do all possible intersections.
+ num_intersects = 0;
+ for (int track = 0; track <= max_track; ++track) {
+ if (reconstruction->PointForTrack(track)) {
+ LG << "Skipping point: " << track;
+ continue;
+ }
+ vector<Marker> all_markers = tracks.MarkersForTrack(track);
+ LG << "Got " << all_markers.size() << " markers for track " << track;
+
+ vector<Marker> reconstructed_markers;
+ for (int i = 0; i < all_markers.size(); ++i) {
+ if (reconstruction->CameraForImage(all_markers[i].image)) {
+ reconstructed_markers.push_back(all_markers[i]);
+ }
+ }
+ LG << "Got " << reconstructed_markers.size()
+ << " reconstructed markers for track " << track;
+ if (reconstructed_markers.size() >= 2) {
+ PipelineRoutines::Intersect(reconstructed_markers, reconstruction);
+ num_intersects++;
+ LG << "Ran Intersect() for track " << track;
+ }
+ }
+ if (num_intersects) {
+ PipelineRoutines::Bundle(tracks, reconstruction);
+ LG << "Ran Bundle() after intersections.";
+ }
+ LG << "Did " << num_intersects << " intersects.";
+
+ // Do all possible resections.
+ num_resects = 0;
+ for (int image = 0; image <= max_image; ++image) {
+ if (reconstruction->CameraForImage(image)) {
+ LG << "Skipping frame: " << image;
+ continue;
+ }
+ vector<Marker> all_markers = tracks.MarkersInImage(image);
+ LG << "Got " << all_markers.size() << " markers for image " << image;
+
+ vector<Marker> reconstructed_markers;
+ for (int i = 0; i < all_markers.size(); ++i) {
+ if (reconstruction->PointForTrack(all_markers[i].track)) {
+ reconstructed_markers.push_back(all_markers[i]);
+ }
+ }
+ LG << "Got " << reconstructed_markers.size()
+ << " reconstructed markers for image " << image;
+ if (reconstructed_markers.size() >= 5) {
+ if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, false)) {
+ num_resects++;
+ LG << "Ran Resect() for image " << image;
+ } else {
+ LG << "Failed Resect() for image " << image;
+ }
+ }
+ }
+ if (num_resects) {
+ PipelineRoutines::Bundle(tracks, reconstruction);
+ }
+ LG << "Did " << num_resects << " resects.";
+ }
+
+ // One last pass...
+ num_resects = 0;
+ for (int image = 0; image <= max_image; ++image) {
+ if (reconstruction->CameraForImage(image)) {
+ LG << "Skipping frame: " << image;
+ continue;
+ }
+ vector<Marker> all_markers = tracks.MarkersInImage(image);
+
+ vector<Marker> reconstructed_markers;
+ for (int i = 0; i < all_markers.size(); ++i) {
+ if (reconstruction->PointForTrack(all_markers[i].track)) {
+ reconstructed_markers.push_back(all_markers[i]);
+ }
+ }
+ if (reconstructed_markers.size() >= 5) {
+ if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, true)) {
+ num_resects++;
+ LG << "Ran Resect() for image " << image;
+ } else {
+ LG << "Failed Resect() for image " << image;
+ }
+ }
+ }
+ if (num_resects) {
+ PipelineRoutines::Bundle(tracks, reconstruction);
+ }
+}
+
+template<typename PipelineRoutines>
+double InternalReprojectionError(const Tracks &image_tracks,
+ const typename PipelineRoutines::Reconstruction &reconstruction,
+ const CameraIntrinsics &intrinsics) {
+ int num_skipped = 0;
+ int num_reprojected = 0;
+ double total_error = 0.0;
+ vector<Marker> markers = image_tracks.AllMarkers();
+ for (int i = 0; i < markers.size(); ++i) {
+ const typename PipelineRoutines::Camera *camera =
+ reconstruction.CameraForImage(markers[i].image);
+ const typename PipelineRoutines::Point *point =
+ reconstruction.PointForTrack(markers[i].track);
+ if (!camera || !point) {
+ num_skipped++;
+ continue;
+ }
+ num_reprojected++;
+
+ Marker reprojected_marker =
+ PipelineRoutines::ProjectMarker(*point, *camera, intrinsics);
+ double ex = reprojected_marker.x - markers[i].x;
+ double ey = reprojected_marker.y - markers[i].y;
+
+ const int N = 100;
+ char line[N];
+ snprintf(line, N,
+ "image %-3d track %-3d "
+ "x %7.1f y %7.1f "
+ "rx %7.1f ry %7.1f "
+ "ex %7.1f ey %7.1f"
+ " e %7.1f",
+ markers[i].image,
+ markers[i].track,
+ markers[i].x,
+ markers[i].y,
+ reprojected_marker.x,
+ reprojected_marker.y,
+ ex,
+ ey,
+ sqrt(ex*ex + ey*ey));
+ //LG << line;
+ total_error += sqrt(ex*ex + ey*ey);
+ }
+ LG << "Skipped " << num_skipped << " markers.";
+ LG << "Reprojected " << num_reprojected << " markers.";
+ LG << "Total error: " << total_error;
+ LG << "Average error: " << (total_error / num_reprojected) << " [pixels].";
+ return total_error / num_reprojected;
+}
+
+double EuclideanReprojectionError(const Tracks &image_tracks,
+ const EuclideanReconstruction &reconstruction,
+ const CameraIntrinsics &intrinsics) {
+ return InternalReprojectionError<EuclideanPipelineRoutines>(image_tracks,
+ reconstruction,
+ intrinsics);
+}
+
+double ProjectiveReprojectionError(
+ const Tracks &image_tracks,
+ const ProjectiveReconstruction &reconstruction,
+ const CameraIntrinsics &intrinsics) {
+ return InternalReprojectionError<ProjectivePipelineRoutines>(image_tracks,
+ reconstruction,
+ intrinsics);
+}
+
+void EuclideanCompleteReconstruction(const Tracks &tracks,
+ EuclideanReconstruction *reconstruction) {
+ InternalCompleteReconstruction<EuclideanPipelineRoutines>(tracks,
+ reconstruction);
+}
+
+void ProjectiveCompleteReconstruction(const Tracks &tracks,
+ ProjectiveReconstruction *reconstruction) {
+ InternalCompleteReconstruction<ProjectivePipelineRoutines>(tracks,
+ reconstruction);
+}
+
+void InvertIntrinsicsForTracks(const Tracks &raw_tracks,
+ const CameraIntrinsics &camera_intrinsics,
+ Tracks *calibrated_tracks) {
+ vector<Marker> markers = raw_tracks.AllMarkers();
+ for (int i = 0; i < markers.size(); ++i) {
+ camera_intrinsics.InvertIntrinsics(markers[i].x,
+ markers[i].y,
+ &(markers[i].x),
+ &(markers[i].y));
+ }
+ *calibrated_tracks = Tracks(markers);
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/pipeline.h b/extern/libmv/libmv/simple_pipeline/pipeline.h
new file mode 100644
index 00000000000..b7dfcb7993a
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/pipeline.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_PIPELINE_H_
+#define LIBMV_SIMPLE_PIPELINE_PIPELINE_H_
+
+#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+
+namespace libmv {
+
+/*!
+ Estimate camera poses and scene 3D coordinates for all frames and tracks.
+
+ This method should be used once there is an initial reconstruction in
+ place, for example by reconstructing from two frames that have a sufficient
+ baseline and number of tracks in common. This function iteratively
+ triangulates points that are visible by cameras that have their pose
+ estimated, then resections (i.e. estimates the pose) of cameras that are
+ not estimated yet that can see triangulated points. This process is
+ repeated until all points and cameras are estimated. Periodically, bundle
+ adjustment is run to ensure a quality reconstruction.
+
+ \a tracks should contain markers used in the reconstruction.
+ \a reconstruction should contain at least some 3D points or some estimated
+ cameras. The minimum number of cameras is two (with no 3D points) and the
+ minimum number of 3D points (with no estimated cameras) is 5.
+
+ \sa EuclideanResect, EuclideanIntersect, EuclideanBundle
+*/
+void EuclideanCompleteReconstruction(const Tracks &tracks,
+ EuclideanReconstruction *reconstruction);
+
+/*!
+ Estimate camera matrices and homogeneous 3D coordinates for all frames and
+ tracks.
+
+ This method should be used once there is an initial reconstruction in
+ place, for example by reconstructing from two frames that have a sufficient
+ baseline and number of tracks in common. This function iteratively
+ triangulates points that are visible by cameras that have their pose
+ estimated, then resections (i.e. estimates the pose) of cameras that are
+ not estimated yet that can see triangulated points. This process is
+ repeated until all points and cameras are estimated. Periodically, bundle
+ adjustment is run to ensure a quality reconstruction.
+
+ \a tracks should contain markers used in the reconstruction.
+ \a reconstruction should contain at least some 3D points or some estimated
+ cameras. The minimum number of cameras is two (with no 3D points) and the
+ minimum number of 3D points (with no estimated cameras) is 5.
+
+ \sa ProjectiveResect, ProjectiveIntersect, ProjectiveBundle
+*/
+void ProjectiveCompleteReconstruction(const Tracks &tracks,
+ ProjectiveReconstruction *reconstruction);
+
+
+class CameraIntrinsics;
+
+// TODO(keir): Decide if we want these in the public API, and if so, what the
+// appropriate include file is.
+
+double EuclideanReprojectionError(const Tracks &image_tracks,
+ const EuclideanReconstruction &reconstruction,
+ const CameraIntrinsics &intrinsics);
+
+double ProjectiveReprojectionError(
+ const Tracks &image_tracks,
+ const ProjectiveReconstruction &reconstruction,
+ const CameraIntrinsics &intrinsics);
+
+void InvertIntrinsicsForTracks(const Tracks &raw_tracks,
+ const CameraIntrinsics &camera_intrinsics,
+ Tracks *calibrated_tracks);
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_PIPELINE_H_
diff --git a/extern/libmv/libmv/simple_pipeline/reconstruction.cc b/extern/libmv/libmv/simple_pipeline/reconstruction.cc
new file mode 100644
index 00000000000..65e5dd27d5d
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/reconstruction.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/simple_pipeline/reconstruction.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/logging/logging.h"
+
+namespace libmv {
+
+EuclideanReconstruction::EuclideanReconstruction() {}
+EuclideanReconstruction::EuclideanReconstruction(
+ const EuclideanReconstruction &other) {
+ cameras_ = other.cameras_;
+ points_ = other.points_;
+}
+
+EuclideanReconstruction &EuclideanReconstruction::operator=(
+ const EuclideanReconstruction &other) {
+ if (&other != this) {
+ cameras_ = other.cameras_;
+ points_ = other.points_;
+ }
+ return *this;
+}
+
+void EuclideanReconstruction::InsertCamera(int image,
+ const Mat3 &R,
+ const Vec3 &t) {
+ LG << "InsertCamera " << image << ":\nR:\n"<< R << "\nt:\n" << t;
+ if (image >= cameras_.size()) {
+ cameras_.resize(image + 1);
+ }
+ cameras_[image].image = image;
+ cameras_[image].R = R;
+ cameras_[image].t = t;
+}
+
+void EuclideanReconstruction::InsertPoint(int track, const Vec3 &X) {
+ LG << "InsertPoint " << track << ":\n" << X;
+ if (track >= points_.size()) {
+ points_.resize(track + 1);
+ }
+ points_[track].track = track;
+ points_[track].X = X;
+}
+
+EuclideanCamera *EuclideanReconstruction::CameraForImage(int image) {
+ return const_cast<EuclideanCamera *>(
+ static_cast<const EuclideanReconstruction *>(
+ this)->CameraForImage(image));
+}
+
+const EuclideanCamera *EuclideanReconstruction::CameraForImage(
+ int image) const {
+ if (image < 0 || image >= cameras_.size()) {
+ return NULL;
+ }
+ const EuclideanCamera *camera = &cameras_[image];
+ if (camera->image == -1) {
+ return NULL;
+ }
+ return camera;
+}
+
+vector<EuclideanCamera> EuclideanReconstruction::AllCameras() const {
+ vector<EuclideanCamera> cameras;
+ for (int i = 0; i < cameras_.size(); ++i) {
+ if (cameras_[i].image != -1) {
+ cameras.push_back(cameras_[i]);
+ }
+ }
+ return cameras;
+}
+
+EuclideanPoint *EuclideanReconstruction::PointForTrack(int track) {
+ return const_cast<EuclideanPoint *>(
+ static_cast<const EuclideanReconstruction *>(this)->PointForTrack(track));
+}
+
+const EuclideanPoint *EuclideanReconstruction::PointForTrack(int track) const {
+ if (track < 0 || track >= points_.size()) {
+ return NULL;
+ }
+ const EuclideanPoint *point = &points_[track];
+ if (point->track == -1) {
+ return NULL;
+ }
+ return point;
+}
+
+vector<EuclideanPoint> EuclideanReconstruction::AllPoints() const {
+ vector<EuclideanPoint> points;
+ for (int i = 0; i < points_.size(); ++i) {
+ if (points_[i].track != -1) {
+ points.push_back(points_[i]);
+ }
+ }
+ return points;
+}
+
+void ProjectiveReconstruction::InsertCamera(int image,
+ const Mat34 &P) {
+ LG << "InsertCamera " << image << ":\nP:\n"<< P;
+ if (image >= cameras_.size()) {
+ cameras_.resize(image + 1);
+ }
+ cameras_[image].image = image;
+ cameras_[image].P = P;
+}
+
+void ProjectiveReconstruction::InsertPoint(int track, const Vec4 &X) {
+ LG << "InsertPoint " << track << ":\n" << X;
+ if (track >= points_.size()) {
+ points_.resize(track + 1);
+ }
+ points_[track].track = track;
+ points_[track].X = X;
+}
+
+ProjectiveCamera *ProjectiveReconstruction::CameraForImage(int image) {
+ return const_cast<ProjectiveCamera *>(
+ static_cast<const ProjectiveReconstruction *>(
+ this)->CameraForImage(image));
+}
+
+const ProjectiveCamera *ProjectiveReconstruction::CameraForImage(
+ int image) const {
+ if (image < 0 || image >= cameras_.size()) {
+ return NULL;
+ }
+ const ProjectiveCamera *camera = &cameras_[image];
+ if (camera->image == -1) {
+ return NULL;
+ }
+ return camera;
+}
+
+vector<ProjectiveCamera> ProjectiveReconstruction::AllCameras() const {
+ vector<ProjectiveCamera> cameras;
+ for (int i = 0; i < cameras_.size(); ++i) {
+ if (cameras_[i].image != -1) {
+ cameras.push_back(cameras_[i]);
+ }
+ }
+ return cameras;
+}
+
+ProjectivePoint *ProjectiveReconstruction::PointForTrack(int track) {
+ return const_cast<ProjectivePoint *>(
+ static_cast<const ProjectiveReconstruction *>(this)->PointForTrack(track));
+}
+
+const ProjectivePoint *ProjectiveReconstruction::PointForTrack(int track) const {
+ if (track < 0 || track >= points_.size()) {
+ return NULL;
+ }
+ const ProjectivePoint *point = &points_[track];
+ if (point->track == -1) {
+ return NULL;
+ }
+ return point;
+}
+
+vector<ProjectivePoint> ProjectiveReconstruction::AllPoints() const {
+ vector<ProjectivePoint> points;
+ for (int i = 0; i < points_.size(); ++i) {
+ if (points_[i].track != -1) {
+ points.push_back(points_[i]);
+ }
+ }
+ return points;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/reconstruction.h b/extern/libmv/libmv/simple_pipeline/reconstruction.h
new file mode 100644
index 00000000000..947a0636476
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/reconstruction.h
@@ -0,0 +1,217 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_
+#define LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_
+
+#include "libmv/base/vector.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+/*!
+ A EuclideanCamera is the location and rotation of the camera viewing \a image.
+
+ \a image identify which image from \l Tracks this camera represents.
+ \a R is a 3x3 matrix representing the rotation of the camera.
+ \a t is a translation vector representing its positions.
+
+ \sa Reconstruction
+*/
+struct EuclideanCamera {
+ EuclideanCamera() : image(-1) {}
+ EuclideanCamera(const EuclideanCamera &c) : image(c.image), R(c.R), t(c.t) {}
+
+ int image;
+ Mat3 R;
+ Vec3 t;
+};
+
+/*!
+ A Point is the 3D location of a track.
+
+ \a track identify which track from \l Tracks this point corresponds to.
+ \a X represents the 3D position of the track.
+
+ \sa Reconstruction
+*/
+struct EuclideanPoint {
+ EuclideanPoint() : track(-1) {}
+ EuclideanPoint(const EuclideanPoint &p) : track(p.track), X(p.X) {}
+ int track;
+ Vec3 X;
+};
+
+/*!
+ The EuclideanReconstruction class stores \link EuclideanCamera cameras
+ \endlink and \link EuclideanPoint points \endlink.
+
+ The EuclideanReconstruction container is intended as the store of 3D
+ reconstruction data to be used with the MultiView API.
+
+ The container has lookups to query a \a EuclideanCamera from an \a image or
+ a \a EuclideanPoint from a \a track.
+
+ \sa Camera, Point
+*/
+class EuclideanReconstruction {
+ public:
+ // Default constructor starts with no cameras.
+ EuclideanReconstruction();
+
+ /// Copy constructor.
+ EuclideanReconstruction(const EuclideanReconstruction &other);
+
+ EuclideanReconstruction &operator=(const EuclideanReconstruction &other);
+
+ /*!
+ Insert a camera into the set. If there is already a camera for the given
+ \a image, the existing camera is replaced. If there is no camera for the
+ given \a image, a new one is added.
+
+ \a image is the key used to retrieve the cameras with the other methods
+ in this class.
+
+ \note You should use the same \a image identifier as in \l Tracks.
+ */
+ void InsertCamera(int image, const Mat3 &R, const Vec3 &t);
+
+ /*!
+ Insert a point into the reconstruction. If there is already a point for
+ the given \a track, the existing point is replaced. If there is no point
+ for the given \a track, a new one is added.
+
+ \a track is the key used to retrieve the points with the
+ other methods in this class.
+
+ \note You should use the same \a track identifier as in \l Tracks.
+ */
+ void InsertPoint(int track, const Vec3 &X);
+
+ /// Returns a pointer to the camera corresponding to \a image.
+ EuclideanCamera *CameraForImage(int image);
+ const EuclideanCamera *CameraForImage(int image) const;
+
+ /// Returns all cameras.
+ vector<EuclideanCamera> AllCameras() const;
+
+ /// Returns a pointer to the point corresponding to \a track.
+ EuclideanPoint *PointForTrack(int track);
+ const EuclideanPoint *PointForTrack(int track) const;
+
+ /// Returns all points.
+ vector<EuclideanPoint> AllPoints() const;
+
+ private:
+ vector<EuclideanCamera> cameras_;
+ vector<EuclideanPoint> points_;
+};
+
+/*!
+ A ProjectiveCamera is the projection matrix for the camera of \a image.
+
+ \a image identify which image from \l Tracks this camera represents.
+ \a P is the 3x4 projection matrix.
+
+ \sa ProjectiveReconstruction
+*/
+struct ProjectiveCamera {
+ ProjectiveCamera() : image(-1) {}
+ ProjectiveCamera(const ProjectiveCamera &c) : image(c.image), P(c.P) {}
+
+ int image;
+ Mat34 P;
+};
+
+/*!
+ A Point is the 3D location of a track.
+
+ \a track identifies which track from \l Tracks this point corresponds to.
+ \a X is the homogeneous 3D position of the track.
+
+ \sa Reconstruction
+*/
+struct ProjectivePoint {
+ ProjectivePoint() : track(-1) {}
+ ProjectivePoint(const ProjectivePoint &p) : track(p.track), X(p.X) {}
+ int track;
+ Vec4 X;
+};
+
+/*!
+ The ProjectiveReconstruction class stores \link ProjectiveCamera cameras
+ \endlink and \link ProjectivePoint points \endlink.
+
+ The ProjectiveReconstruction container is intended as the store of 3D
+ reconstruction data to be used with the MultiView API.
+
+ The container has lookups to query a \a ProjectiveCamera from an \a image or
+ a \a ProjectivePoint from a \a track.
+
+ \sa Camera, Point
+*/
+class ProjectiveReconstruction {
+ public:
+ /*!
+ Insert a camera into the set. If there is already a camera for the given
+ \a image, the existing camera is replaced. If there is no camera for the
+ given \a image, a new one is added.
+
+ \a image is the key used to retrieve the cameras with the other methods
+ in this class.
+
+ \note You should use the same \a image identifier as in \l Tracks.
+ */
+ void InsertCamera(int image, const Mat34 &P);
+
+ /*!
+ Insert a point into the reconstruction. If there is already a point for
+ the given \a track, the existing point is replaced. If there is no point
+ for the given \a track, a new one is added.
+
+ \a track is the key used to retrieve the points with the
+ other methods in this class.
+
+ \note You should use the same \a track identifier as in \l Tracks.
+ */
+ void InsertPoint(int track, const Vec4 &X);
+
+ /// Returns a pointer to the camera corresponding to \a image.
+ ProjectiveCamera *CameraForImage(int image);
+ const ProjectiveCamera *CameraForImage(int image) const;
+
+ /// Returns all cameras.
+ vector<ProjectiveCamera> AllCameras() const;
+
+ /// Returns a pointer to the point corresponding to \a track.
+ ProjectivePoint *PointForTrack(int track);
+ const ProjectivePoint *PointForTrack(int track) const;
+
+ /// Returns all points.
+ vector<ProjectivePoint> AllPoints() const;
+
+ private:
+ vector<ProjectiveCamera> cameras_;
+ vector<ProjectivePoint> points_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_
diff --git a/extern/libmv/libmv/simple_pipeline/resect.cc b/extern/libmv/libmv/simple_pipeline/resect.cc
new file mode 100644
index 00000000000..6e71c3c7206
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/resect.cc
@@ -0,0 +1,271 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <cstdio>
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/euclidean_resection.h"
+#include "libmv/multiview/resection.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/levenberg_marquardt.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+#include "libmv/simple_pipeline/tracks.h"
+
+namespace libmv {
+namespace {
+
+Mat2X PointMatrixFromMarkers(const vector<Marker> &markers) {
+ Mat2X points(2, markers.size());
+ for (int i = 0; i < markers.size(); ++i) {
+ points(0, i) = markers[i].x;
+ points(1, i) = markers[i].y;
+ }
+ return points;
+}
+
+Mat3 RotationFromEulerVector(Vec3 euler_vector) {
+ double theta = euler_vector.norm();
+ if (theta == 0.0) {
+ return Mat3::Identity();
+ }
+ Vec3 w = euler_vector / theta;
+ Mat3 w_hat = CrossProductMatrix(w);
+ return Mat3::Identity() + w_hat*sin(theta) + w_hat*w_hat*(1 - cos(theta));
+}
+
+// Uses an incremental rotation:
+//
+// x = R' * R * X + t;
+//
+// to avoid issues with the rotation representation. R' is derived from a
+// euler vector encoding the rotation in 3 parameters; the direction is the
+// axis to rotate around and the magnitude is the amount of the rotation.
+struct EuclideanResectCostFunction {
+ public:
+ typedef Vec FMatrixType;
+ typedef Vec6 XMatrixType;
+
+ EuclideanResectCostFunction(const vector<Marker> &markers,
+ const EuclideanReconstruction &reconstruction,
+ const Mat3 initial_R)
+ : markers(markers),
+ reconstruction(reconstruction),
+ initial_R(initial_R) {}
+
+ // dRt has dR (delta R) encoded as a euler vector in the first 3 parameters,
+ // followed by t in the next 3 parameters.
+ Vec operator()(const Vec6 &dRt) const {
+ // Unpack R, t from dRt.
+ Mat3 R = RotationFromEulerVector(dRt.head<3>()) * initial_R;
+ Vec3 t = dRt.tail<3>();
+
+ // Compute the reprojection error for each coordinate.
+ Vec residuals(2 * markers.size());
+ residuals.setZero();
+ for (int i = 0; i < markers.size(); ++i) {
+ const EuclideanPoint &point =
+ *reconstruction.PointForTrack(markers[i].track);
+ Vec3 projected = R * point.X + t;
+ projected /= projected(2);
+ residuals[2*i + 0] = projected(0) - markers[i].x;
+ residuals[2*i + 1] = projected(1) - markers[i].y;
+ }
+ return residuals;
+ }
+
+ const vector<Marker> &markers;
+ const EuclideanReconstruction &reconstruction;
+ const Mat3 &initial_R;
+};
+
+} // namespace
+
+bool EuclideanResect(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction, bool final_pass) {
+ if (markers.size() < 5) {
+ return false;
+ }
+ Mat2X points_2d = PointMatrixFromMarkers(markers);
+ Mat3X points_3d(3, markers.size());
+ for (int i = 0; i < markers.size(); i++) {
+ points_3d.col(i) = reconstruction->PointForTrack(markers[i].track)->X;
+ }
+ LG << "Points for resect:\n" << points_2d;
+
+ Mat3 R;
+ Vec3 t;
+ if (0 || !euclidean_resection::EuclideanResection(points_2d, points_3d, &R, &t)) {
+ // printf("Resection for image %d failed\n", markers[0].image);
+ LG << "Resection for image " << markers[0].image << " failed;"
+ << " trying fallback projective resection.";
+ if (!final_pass) return false;
+ // Euclidean resection failed. Fall back to projective resection, which is
+ // less reliable but better conditioned when there are many points.
+ Mat34 P;
+ Mat4X points_3d_homogeneous(4, markers.size());
+ for (int i = 0; i < markers.size(); i++) {
+ points_3d_homogeneous.col(i).head<3>() = points_3d.col(i);
+ points_3d_homogeneous(3, i) = 1.0;
+ }
+ resection::Resection(points_2d, points_3d_homogeneous, &P);
+ if ((P * points_3d_homogeneous.col(0))(2) < 0) {
+ LG << "Point behind camera; switch sign.";
+ P = -P;
+ }
+
+ Mat3 ignored;
+ KRt_From_P(P, &ignored, &R, &t);
+
+ // The R matrix should be a rotation, but don't rely on it.
+ Eigen::JacobiSVD<Mat3> svd(R, Eigen::ComputeFullU | Eigen::ComputeFullV);
+
+ LG << "Resection rotation is: " << svd.singularValues().transpose();
+ LG << "Determinant is: " << R.determinant();
+
+ // Correct to make R a rotation.
+ R = svd.matrixU() * svd.matrixV().transpose();
+
+ Vec3 xx = R * points_3d.col(0) + t;
+ if (xx(2) < 0.0) {
+ LG << "Final point is still behind camera...";
+ }
+ // XXX Need to check if error is horrible and fail here too in that case.
+ }
+
+ // Refine the result.
+ typedef LevenbergMarquardt<EuclideanResectCostFunction> Solver;
+
+ // Give the cost our initial guess for R.
+ EuclideanResectCostFunction resect_cost(markers, *reconstruction, R);
+
+ // Encode the initial parameters: start with zero delta rotation, and the
+ // guess for t obtained from resection.
+ Vec6 dRt = Vec6::Zero();
+ dRt.tail<3>() = t;
+
+ Solver solver(resect_cost);
+
+ Solver::SolverParameters params;
+ Solver::Results results = solver.minimize(params, &dRt);
+ LG << "LM found incremental rotation: " << dRt.head<3>().transpose();
+ // TODO(keir): Check results to ensure clean termination.
+
+ // Unpack the rotation and translation.
+ R = RotationFromEulerVector(dRt.head<3>()) * R;
+ t = dRt.tail<3>();
+
+ LG << "Resection for image " << markers[0].image << " got:\n"
+ << "R:\n" << R << "\nt:\n" << t;
+ reconstruction->InsertCamera(markers[0].image, R, t);
+ return true;
+}
+
+namespace {
+
+// Directly parameterize the projection matrix, P, which is a 12 parameter
+// homogeneous entry. In theory P should be parameterized with only 11
+// parametetrs, but in practice it works fine to let the extra degree of
+// freedom drift.
+struct ProjectiveResectCostFunction {
+ public:
+ typedef Vec FMatrixType;
+ typedef Vec12 XMatrixType;
+
+ ProjectiveResectCostFunction(const vector<Marker> &markers,
+ const ProjectiveReconstruction &reconstruction)
+ : markers(markers),
+ reconstruction(reconstruction) {}
+
+ Vec operator()(const Vec12 &vector_P) const {
+ // Unpack P from vector_P.
+ Map<const Mat34> P(vector_P.data(), 3, 4);
+
+ // Compute the reprojection error for each coordinate.
+ Vec residuals(2 * markers.size());
+ residuals.setZero();
+ for (int i = 0; i < markers.size(); ++i) {
+ const ProjectivePoint &point =
+ *reconstruction.PointForTrack(markers[i].track);
+ Vec3 projected = P * point.X;
+ projected /= projected(2);
+ residuals[2*i + 0] = projected(0) - markers[i].x;
+ residuals[2*i + 1] = projected(1) - markers[i].y;
+ }
+ return residuals;
+ }
+
+ const vector<Marker> &markers;
+ const ProjectiveReconstruction &reconstruction;
+};
+
+} // namespace
+
+bool ProjectiveResect(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction) {
+ if (markers.size() < 5) {
+ return false;
+ }
+
+ // Stack the homogeneous 3D points as the columns of a matrix.
+ Mat2X points_2d = PointMatrixFromMarkers(markers);
+ Mat4X points_3d_homogeneous(4, markers.size());
+ for (int i = 0; i < markers.size(); i++) {
+ points_3d_homogeneous.col(i) =
+ reconstruction->PointForTrack(markers[i].track)->X;
+ }
+ LG << "Points for resect:\n" << points_2d;
+
+ // Resection the point.
+ Mat34 P;
+ resection::Resection(points_2d, points_3d_homogeneous, &P);
+
+ // Flip the sign of P if necessary to keep the point in front of the camera.
+ if ((P * points_3d_homogeneous.col(0))(2) < 0) {
+ LG << "Point behind camera; switch sign.";
+ P = -P;
+ }
+
+ // TODO(keir): Check if error is horrible and fail in that case.
+
+ // Refine the resulting projection matrix using geometric error.
+ typedef LevenbergMarquardt<ProjectiveResectCostFunction> Solver;
+
+ ProjectiveResectCostFunction resect_cost(markers, *reconstruction);
+
+ // Pack the initial P matrix into a size-12 vector..
+ Vec12 vector_P = Map<Vec12>(P.data());
+
+ Solver solver(resect_cost);
+
+ Solver::SolverParameters params;
+ Solver::Results results = solver.minimize(params, &vector_P);
+ // TODO(keir): Check results to ensure clean termination.
+
+ // Unpack the projection matrix.
+ P = Map<Mat34>(vector_P.data(), 3, 4);
+
+ LG << "Resection for image " << markers[0].image << " got:\n"
+ << "P:\n" << P;
+ reconstruction->InsertCamera(markers[0].image, P);
+ return true;
+}
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/resect.h b/extern/libmv/libmv/simple_pipeline/resect.h
new file mode 100644
index 00000000000..f8b5b9f68ee
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/resect.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_RESECT_H
+#define LIBMV_SIMPLE_PIPELINE_RESECT_H
+
+#include "libmv/base/vector.h"
+#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/reconstruction.h"
+
+namespace libmv {
+
+/*!
+ Estimate the Euclidean pose of a camera from 2D to 3D correspondences.
+
+ This takes a set of markers visible in one frame (which is the one to
+ resection), such that the markers are also reconstructed in 3D in the
+ reconstruction object, and solves for the pose and orientation of the
+ camera for that frame.
+
+ \a markers should contain \l Marker markers \endlink belonging to tracks
+ visible in the one frame to be resectioned. Each of the tracks associated
+ with the markers must have a corresponding reconstructed 3D position in the
+ \a *reconstruction object.
+
+ \a *reconstruction should contain the 3D points associated with the tracks
+ for the markers present in \a markers.
+
+ \note This assumes a calibrated reconstruction, e.g. the markers are
+ already corrected for camera intrinsics and radial distortion.
+ \note This assumes an outlier-free set of markers.
+
+ \return True if the resection was successful, false otherwise.
+
+ \sa EuclideanIntersect, EuclideanReconstructTwoFrames
+*/
+bool EuclideanResect(const vector<Marker> &markers,
+ EuclideanReconstruction *reconstruction, bool final_pass);
+
+/*!
+ Estimate the projective pose of a camera from 2D to 3D correspondences.
+
+ This takes a set of markers visible in one frame (which is the one to
+ resection), such that the markers are also reconstructed in a projective
+ frame in the reconstruction object, and solves for the projective matrix of
+ the camera for that frame.
+
+ \a markers should contain \l Marker markers \endlink belonging to tracks
+ visible in the one frame to be resectioned. Each of the tracks associated
+ with the markers must have a corresponding reconstructed homogeneous 3D
+ position in the \a *reconstruction object.
+
+ \a *reconstruction should contain the homogeneous 3D points associated with
+ the tracks for the markers present in \a markers.
+
+ \note This assumes radial distortion has already been corrected, but
+ otherwise works for uncalibrated sequences.
+ \note This assumes an outlier-free set of markers.
+
+ \return True if the resection was successful, false otherwise.
+
+ \sa ProjectiveIntersect, ProjectiveReconstructTwoFrames
+*/
+bool ProjectiveResect(const vector<Marker> &markers,
+ ProjectiveReconstruction *reconstruction);
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_RESECT_H
diff --git a/extern/libmv/libmv/simple_pipeline/tracks.cc b/extern/libmv/libmv/simple_pipeline/tracks.cc
new file mode 100644
index 00000000000..3fb8ddbe513
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/tracks.cc
@@ -0,0 +1,159 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <algorithm>
+#include <vector>
+#include <iterator>
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/simple_pipeline/tracks.h"
+
+namespace libmv {
+
+Tracks::Tracks(const Tracks &other) {
+ markers_ = other.markers_;
+}
+
+Tracks::Tracks(const vector<Marker> &markers) : markers_(markers) {}
+
+void Tracks::Insert(int image, int track, double x, double y) {
+ // TODO(keir): Wow, this is quadratic for repeated insertions. Fix this by
+ // adding a smarter data structure like a set<>.
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].image == image &&
+ markers_[i].track == track) {
+ markers_[i].x = x;
+ markers_[i].y = y;
+ return;
+ }
+ }
+ Marker marker = { image, track, x, y };
+ markers_.push_back(marker);
+}
+
+vector<Marker> Tracks::AllMarkers() const {
+ return markers_;
+}
+
+vector<Marker> Tracks::MarkersInImage(int image) const {
+ vector<Marker> markers;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (image == markers_[i].image) {
+ markers.push_back(markers_[i]);
+ }
+ }
+ return markers;
+}
+
+vector<Marker> Tracks::MarkersForTrack(int track) const {
+ vector<Marker> markers;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (track == markers_[i].track) {
+ markers.push_back(markers_[i]);
+ }
+ }
+ return markers;
+}
+
+vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, int image2) const {
+ std::vector<int> image1_tracks;
+ std::vector<int> image2_tracks;
+
+ for (int i = 0; i < markers_.size(); ++i) {
+ int image = markers_[i].image;
+ if (image == image1) {
+ image1_tracks.push_back(markers_[i].track);
+ } else if (image == image2) {
+ image2_tracks.push_back(markers_[i].track);
+ }
+ }
+
+ std::sort(image1_tracks.begin(), image1_tracks.end());
+ std::sort(image2_tracks.begin(), image2_tracks.end());
+
+ std::vector<int> intersection;
+ std::set_intersection(image1_tracks.begin(), image1_tracks.end(),
+ image2_tracks.begin(), image2_tracks.end(),
+ std::back_inserter(intersection));
+
+ vector<Marker> markers;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if ((markers_[i].image == image1 || markers_[i].image == image2) &&
+ std::binary_search(intersection.begin(),intersection.end(),
+ markers_[i].track)) {
+ markers.push_back(markers_[i]);
+ }
+ }
+ return markers;
+}
+
+Marker Tracks::MarkerInImageForTrack(int image, int track) const {
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].image == image && markers_[i].track == track) {
+ return markers_[i];
+ }
+ }
+ Marker null = { -1, -1, -1, -1 };
+ return null;
+}
+
+void Tracks::RemoveMarkersForTrack(int track) {
+ int size = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].track != track) {
+ markers_[size++] = markers_[i];
+ }
+ }
+ markers_.resize(size);
+}
+
+void Tracks::RemoveMarker(int image, int track) {
+ int size = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].image != image || markers_[i].track != track) {
+ markers_[size++] = markers_[i];
+ }
+ }
+ markers_.resize(size);
+}
+
+int Tracks::MaxImage() const {
+ // TODO(MatthiasF): maintain a max_image_ member (updated on Insert)
+ int max_image = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ max_image = std::max(markers_[i].image, max_image);
+ }
+ return max_image;
+}
+
+int Tracks::MaxTrack() const {
+ // TODO(MatthiasF): maintain a max_track_ member (updated on Insert)
+ int max_track = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ max_track = std::max(markers_[i].track, max_track);
+ }
+ return max_track;
+}
+
+int Tracks::NumMarkers() const {
+ return markers_.size();
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/tracks.h b/extern/libmv/libmv/simple_pipeline/tracks.h
new file mode 100644
index 00000000000..739c3c4f243
--- /dev/null
+++ b/extern/libmv/libmv/simple_pipeline/tracks.h
@@ -0,0 +1,119 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_TRACKS_H_
+#define LIBMV_SIMPLE_PIPELINE_TRACKS_H_
+
+#include "libmv/base/vector.h"
+
+namespace libmv {
+
+/*!
+ A Marker is the 2D location of a tracked point in an image.
+
+ \a x, \a y is the position of the marker in pixels from the top left corner
+ in the image identified by \a image. All markers for to the same target
+ form a track identified by a common \a track number.
+
+ \note Markers are typically aggregated with the help of the \l Tracks class.
+
+ \sa Tracks
+*/
+struct Marker {
+ int image;
+ int track;
+ double x, y;
+};
+
+/*!
+ The Tracks class stores \link Marker reconstruction markers \endlink.
+
+ The Tracks container is intended as the store of correspondences between
+ images, which must get created before any 3D reconstruction can take place.
+
+ The container has several fast lookups for queries typically needed for
+ structure from motion algorithms, such as \l MarkersForTracksInBothImages().
+
+ \sa Marker
+*/
+class Tracks {
+ public:
+ Tracks() {}
+
+ // Copy constructor for a tracks object.
+ Tracks(const Tracks &other);
+
+ /// Construct a new tracks object using the given markers to start.
+ Tracks(const vector<Marker> &markers);
+
+ /*!
+ Inserts a marker into the set. If there is already a marker for the given
+ \a image and \a track, the existing marker is replaced. If there is no
+ marker for the given \a image and \a track, a new one is added.
+
+ \a image and \a track are the keys used to retrieve the markers with the
+ other methods in this class.
+
+ \note To get an identifier for a new track, use \l MaxTrack() + 1.
+ */
+ void Insert(int image, int track, double x, double y);
+
+ /// Returns all the markers.
+ vector<Marker> AllMarkers() const;
+
+ /// Returns all the markers belonging to a track.
+ vector<Marker> MarkersForTrack(int track) const;
+
+ /// Returns all the markers visible in \a image.
+ vector<Marker> MarkersInImage(int image) const;
+
+ /*!
+ Returns the markers in \a image1 and \a image2 which have a common track.
+
+ This is not the same as the union of the markers in \a image1 and \a
+ image2; each marker is for a track that appears in both images.
+ */
+ vector<Marker> MarkersForTracksInBothImages(int image1, int image2) const;
+
+ /// Returns the marker in \a image belonging to \a track.
+ Marker MarkerInImageForTrack(int image, int track) const;
+
+ /// Removes all the markers belonging to \a track.
+ void RemoveMarkersForTrack(int track);
+
+ /// Removes the marker in \a image belonging to \a track.
+ void RemoveMarker(int image, int track);
+
+ /// Returns the maximum image identifier used.
+ int MaxImage() const;
+
+ /// Returns the maximum track identifier used.
+ int MaxTrack() const;
+
+ /// Returns the number of markers.
+ int NumMarkers() const;
+
+ private:
+ vector<Marker> markers_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_
diff --git a/extern/libmv/libmv/tracking/klt_region_tracker.cc b/extern/libmv/libmv/tracking/klt_region_tracker.cc
new file mode 100644
index 00000000000..299077be155
--- /dev/null
+++ b/extern/libmv/libmv/tracking/klt_region_tracker.cc
@@ -0,0 +1,132 @@
+// Copyright (c) 2007, 2008, 2009, 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/logging/logging.h"
+#include "libmv/tracking/klt_region_tracker.h"
+#include "libmv/image/image.h"
+#include "libmv/image/convolve.h"
+#include "libmv/image/sample.h"
+
+namespace libmv {
+
+// Compute the gradient matrix noted by Z and the error vector e. See Good
+// Features to Track.
+//
+// TODO(keir): The calls to SampleLinear() do boundary checking that should
+// instead happen outside the loop. Since this is the innermost loop, the extra
+// bounds checking hurts performance.
+static void ComputeTrackingEquation(const Array3Df &image_and_gradient1,
+ const Array3Df &image_and_gradient2,
+ double x1, double y1,
+ double x2, double y2,
+ int half_width,
+ float *gxx,
+ float *gxy,
+ float *gyy,
+ float *ex,
+ float *ey) {
+ *gxx = *gxy = *gyy = 0;
+ *ex = *ey = 0;
+ for (int r = -half_width; r <= half_width; ++r) {
+ for (int c = -half_width; c <= half_width; ++c) {
+ float xx1 = x1 + c;
+ float yy1 = y1 + r;
+ float xx2 = x2 + c;
+ float yy2 = y2 + r;
+ float I = SampleLinear(image_and_gradient1, yy1, xx1, 0);
+ float J = SampleLinear(image_and_gradient2, yy2, xx2, 0);
+ float gx = SampleLinear(image_and_gradient2, yy2, xx2, 1);
+ float gy = SampleLinear(image_and_gradient2, yy2, xx2, 2);
+ *gxx += gx * gx;
+ *gxy += gx * gy;
+ *gyy += gy * gy;
+ *ex += (I - J) * gx;
+ *ey += (I - J) * gy;
+ }
+ }
+}
+
+// Solve the tracking equation
+//
+// [gxx gxy] [dx] = [ex]
+// [gxy gyy] [dy] = [ey]
+//
+// for dx and dy. Borrowed from Stan Birchfield's KLT implementation.
+static bool SolveTrackingEquation(float gxx, float gxy, float gyy,
+ float ex, float ey,
+ float min_determinant,
+ float *dx, float *dy) {
+ float det = gxx * gyy - gxy * gxy;
+ if (det < min_determinant) {
+ *dx = 0;
+ *dy = 0;
+ return false;
+ }
+ *dx = (gyy * ex - gxy * ey) / det;
+ *dy = (gxx * ey - gxy * ex) / det;
+ return true;
+}
+
+bool KltRegionTracker::Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const {
+ Array3Df image_and_gradient1;
+ Array3Df image_and_gradient2;
+ BlurredImageAndDerivativesChannels(image1, sigma, &image_and_gradient1);
+ BlurredImageAndDerivativesChannels(image2, sigma, &image_and_gradient2);
+
+ int i;
+ float dx = 0, dy = 0;
+ for (i = 0; i < max_iterations; ++i) {
+ // Compute gradient matrix and error vector.
+ float gxx, gxy, gyy, ex, ey;
+ ComputeTrackingEquation(image_and_gradient1,
+ image_and_gradient2,
+ x1, y1,
+ *x2, *y2,
+ half_window_size,
+ &gxx, &gxy, &gyy, &ex, &ey);
+
+ // Solve the linear system for the best update to x2 and y2.
+ if (!SolveTrackingEquation(gxx, gxy, gyy, ex, ey, min_determinant,
+ &dx, &dy)) {
+ // The determinant, which indicates the trackiness of the point, is too
+ // small, so fail out.
+ LG << "Determinant too small; failing tracking.";
+ return false;
+ }
+
+ // Update the position with the solved displacement.
+ *x2 += dx;
+ *y2 += dy;
+
+ // If the update is small, then we probably found the target.
+ if (dx * dx + dy * dy < min_update_squared_distance) {
+ LG << "Successful track in " << i << " iterations.";
+ return true;
+ }
+ }
+ // Getting here means we hit max iterations, so tracking failed.
+ LG << "Too many iterations.";
+ return false;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/klt_region_tracker.h b/extern/libmv/libmv/tracking/klt_region_tracker.h
new file mode 100644
index 00000000000..2b2d8a9a49d
--- /dev/null
+++ b/extern/libmv/libmv/tracking/klt_region_tracker.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2007, 2008, 2009, 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_REGION_TRACKING_KLT_REGION_TRACKER_H_
+#define LIBMV_REGION_TRACKING_KLT_REGION_TRACKER_H_
+
+#include "libmv/image/image.h"
+#include "libmv/tracking/region_tracker.h"
+
+namespace libmv {
+
+struct KltRegionTracker : public RegionTracker {
+ KltRegionTracker()
+ : half_window_size(4),
+ max_iterations(16),
+ min_determinant(1e-6),
+ min_update_squared_distance(1e-6),
+ sigma(0.9) {}
+
+ virtual ~KltRegionTracker() {}
+
+ // Tracker interface.
+ virtual bool Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const;
+
+ // No point in creating getters or setters.
+ int half_window_size;
+ int max_iterations;
+ double min_determinant;
+ double min_update_squared_distance;
+ double sigma;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_REGION_TRACKING_KLT_REGION_TRACKER_H_
diff --git a/extern/libmv/libmv/tracking/pyramid_region_tracker.cc b/extern/libmv/libmv/tracking/pyramid_region_tracker.cc
new file mode 100644
index 00000000000..58f42b26d7c
--- /dev/null
+++ b/extern/libmv/libmv/tracking/pyramid_region_tracker.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2007, 2008, 2009, 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <vector>
+
+#include "libmv/image/convolve.h"
+#include "libmv/image/image.h"
+#include "libmv/image/sample.h"
+#include "libmv/logging/logging.h"
+#include "libmv/tracking/pyramid_region_tracker.h"
+
+namespace libmv {
+
+static void MakePyramid(const FloatImage &image, int num_levels,
+ std::vector<FloatImage> *pyramid) {
+ pyramid->resize(num_levels);
+ (*pyramid)[0] = image;
+ for (int i = 1; i < num_levels; ++i) {
+ DownsampleChannelsBy2((*pyramid)[i - 1], &(*pyramid)[i]);
+ }
+}
+
+bool PyramidRegionTracker::Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const {
+ // Shrink the guessed x and y location to match the coarsest level + 1 (which
+ // when gets corrected in the loop).
+ *x2 /= pow(2., num_levels_);
+ *y2 /= pow(2., num_levels_);
+
+ // Create all the levels of the pyramid, since tracking has to happen from
+ // the coarsest to finest levels, which means holding on to all levels of the
+ // pyraid at once.
+ std::vector<FloatImage> pyramid1(num_levels_);
+ std::vector<FloatImage> pyramid2(num_levels_);
+ MakePyramid(image1, num_levels_, &pyramid1);
+ MakePyramid(image2, num_levels_, &pyramid2);
+
+ for (int i = num_levels_ - 1; i >= 0; --i) {
+ // Position in the first image at pyramid level i.
+ double xx = x1 / pow(2., i);
+ double yy = y1 / pow(2., i);
+
+ // Guess the new tracked position is where the last level tracked to.
+ *x2 *= 2;
+ *y2 *= 2;
+
+ // Track the point on this level with the base tracker.
+ bool succeeded = tracker_->Track(pyramid1[i], pyramid2[i], xx, yy, x2, y2);
+
+ if (i == 0 && !succeeded) {
+ // Only fail on the highest-resolution level, because a failure on a
+ // coarse level does not mean failure at a lower level (consider
+ // out-of-bounds conditions).
+ LG << "Finest level of pyramid tracking failed; failing.";
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/pyramid_region_tracker.h b/extern/libmv/libmv/tracking/pyramid_region_tracker.h
new file mode 100644
index 00000000000..1f9675469f4
--- /dev/null
+++ b/extern/libmv/libmv/tracking/pyramid_region_tracker.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_CORRESPONDENCE_PYRAMID_TRACKER_H_
+#define LIBMV_CORRESPONDENCE_PYRAMID_TRACKER_H_
+
+#include "libmv/image/image.h"
+#include "libmv/base/scoped_ptr.h"
+#include "libmv/tracking/region_tracker.h"
+
+namespace libmv {
+
+class PyramidRegionTracker : public RegionTracker {
+ public:
+ PyramidRegionTracker(RegionTracker *tracker, int num_levels)
+ : tracker_(tracker), num_levels_(num_levels) {}
+
+ virtual bool Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const;
+ private:
+ scoped_ptr<RegionTracker> tracker_;
+ int num_levels_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_CORRESPONDENCE_PYRAMID_TRACKER_H_
diff --git a/extern/libmv/libmv/tracking/region_tracker.h b/extern/libmv/libmv/tracking/region_tracker.h
new file mode 100644
index 00000000000..4f7574df1a3
--- /dev/null
+++ b/extern/libmv/libmv/tracking/region_tracker.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_TRACKING_TRACKER_H_
+#define LIBMV_TRACKING_TRACKER_H_
+
+#include "libmv/image/image.h"
+
+namespace libmv {
+
+class RegionTracker {
+ public:
+ RegionTracker() {}
+ virtual ~RegionTracker() {}
+
+ /*!
+ Track a point from \a image1 to \a image2.
+
+ \a x2, \a y2 should start out as a best guess for the position in \a
+ image2. If no guess is available, (\a x1, \a y1) is a good start. Returns
+ true on success, false otherwise
+ */
+ virtual bool Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const = 0;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_CORRESPONDENCE_TRACKER_H_
diff --git a/extern/libmv/libmv/tracking/retrack_region_tracker.cc b/extern/libmv/libmv/tracking/retrack_region_tracker.cc
new file mode 100644
index 00000000000..b3230b1b173
--- /dev/null
+++ b/extern/libmv/libmv/tracking/retrack_region_tracker.cc
@@ -0,0 +1,47 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include <cmath>
+#include <vector>
+
+#include "libmv/tracking/retrack_region_tracker.h"
+
+namespace libmv {
+
+bool RetrackRegionTracker::Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const {
+ // Track forward, getting x2 and y2.
+ if (!tracker_->Track(image1, image2, x1, y1, x2, y2)) {
+ return false;
+ }
+ // Now track x2 and y2 backward, to get xx1 and yy1 which, if the track is
+ // good, should match x1 and y1 (but may not if the track is bad).
+ double xx1 = *x2, yy1 = *x2;
+ if (!tracker_->Track(image2, image1, *x2, *y2, &xx1, &yy1)) {
+ return false;
+ }
+ double dx = xx1 - x1;
+ double dy = yy1 - y1;
+ return sqrt(dx * dx + dy * dy) < tolerance_;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/retrack_region_tracker.h b/extern/libmv/libmv/tracking/retrack_region_tracker.h
new file mode 100644
index 00000000000..ab05f320834
--- /dev/null
+++ b/extern/libmv/libmv/tracking/retrack_region_tracker.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_TRACKING_RETRACK_REGION_TRACKER_H_
+#define LIBMV_TRACKING_RETRACK_REGION_TRACKER_H_
+
+#include "libmv/image/image.h"
+#include "libmv/base/scoped_ptr.h"
+#include "libmv/tracking/region_tracker.h"
+
+namespace libmv {
+
+// A region tracker that tries tracking backwards and forwards, rejecting a
+// track that doesn't track backwards to the starting point.
+class RetrackRegionTracker : public RegionTracker {
+ public:
+ RetrackRegionTracker(RegionTracker *tracker, double tolerance)
+ : tracker_(tracker), tolerance_(tolerance) {}
+
+ virtual bool Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const;
+ private:
+ scoped_ptr<RegionTracker> tracker_;
+ double tolerance_;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_TRACKING_RETRACK_REGION_TRACKER_H_
diff --git a/extern/libmv/libmv/tracking/sad.cc b/extern/libmv/libmv/tracking/sad.cc
new file mode 100644
index 00000000000..9b446bb4c35
--- /dev/null
+++ b/extern/libmv/libmv/tracking/sad.cc
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (c) 2011 libmv authors.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to
+** deal in the Software without restriction, including without limitation the
+** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+** sell copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+** IN THE SOFTWARE.
+**
+****************************************************************************/
+
+#include "libmv/tracking/sad.h"
+#include <stdlib.h>
+#include <math.h>
+
+namespace libmv {
+
+void LaplaceFilter(ubyte* src, ubyte* dst, int width, int height, int strength) {
+ for(int y=1; y<height-1; y++) for(int x=1; x<width-1; x++) {
+ const ubyte* s = &src[y*width+x];
+ int l = 128 +
+ s[-width-1] + s[-width] + s[-width+1] +
+ s[1] - 8*s[0] + s[1] +
+ s[ width-1] + s[ width] + s[ width+1] ;
+ int d = ((256-strength)*s[0] + strength*l) / 256;
+ if(d < 0) d=0;
+ if(d > 255) d=255;
+ dst[y*width+x] = d;
+ }
+}
+
+struct vec2 {
+ float x,y;
+ inline vec2(float x, float y):x(x),y(y){}
+};
+inline vec2 operator*(mat32 m, vec2 v) {
+ return vec2(v.x*m(0,0)+v.y*m(0,1)+m(0,2),v.x*m(1,0)+v.y*m(1,1)+m(1,2));
+}
+
+//! fixed point bilinear sample with precision k
+template <int k> inline int sample(const ubyte* image,int stride, int x, int y, int u, int v) {
+ const ubyte* s = &image[y*stride+x];
+ return ((s[ 0] * (k-u) + s[ 1] * u) * (k-v)
+ + (s[stride] * (k-u) + s[stride+1] * u) * ( v) ) / (k*k);
+}
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+int lround(float x) { return _mm_cvtss_si32(_mm_set_ss(x)); }
+#elif defined(_MSC_VER)
+int lround(float x) { return x+0.5; }
+#endif
+
+//TODO(MatthiasF): SSE optimization
+void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int size) {
+ const int k = 256;
+ for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) {
+ vec2 p = warp*vec2(j-size/2,i-size/2);
+ int fx = lround(p.x*k), fy = lround(p.y*k);
+ int ix = fx/k, iy = fy/k;
+ int u = fx%k, v = fy%k;
+ pattern[i*size+j] = sample<k>(image,stride,ix,iy,u,v);
+ }
+}
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+static uint SAD(const ubyte* pattern, const ubyte* image, int stride, int size) {
+ __m128i a = _mm_setzero_si128();
+ for(int i = 0; i < size; i++) {
+ for(int j = 0; j < size/16; j++) {
+ a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(pattern+i*size+j*16)),
+ _mm_loadu_si128((__m128i*)(image+i*stride+j*16))));
+ }
+ }
+ return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4);
+}
+#else
+static uint SAD(const ubyte* pattern, const ubyte* image, int stride, int size) {
+ uint sad=0;
+ for(int i = 0; i < size; i++) {
+ for(int j = 0; j < size; j++) {
+ sad += abs((int)pattern[i*size+j] - image[i*stride+j]);
+ }
+ }
+ return sad;
+}
+#endif
+
+float sq(float x) { return x*x; }
+float Track(ubyte* reference, ubyte* warped, int size, ubyte* image, int stride, int w, int h, mat32* warp, float areaPenalty, float conditionPenalty) {
+ mat32 m=*warp;
+ uint min=-1;
+
+ // exhaustive search integer pixel translation
+ int ix = m(0,2), iy = m(1,2);
+ for(int y = size/2; y < h-size/2; y++) {
+ for(int x = size/2; x < w-size/2; x++) {
+ m(0,2) = x, m(1,2) = y;
+ uint sad = SAD(warped,&image[(y-size/2)*stride+(x-size/2)],stride,size);
+ // TODO: using chroma could help disambiguate some cases
+ if(sad < min) {
+ min = sad;
+ ix = x, iy = y;
+ }
+ }
+ }
+ m(0,2) = ix, m(1,2) = iy;
+ min=-1; //reset score since direct warped search match too well (but the wrong pattern).
+
+ // 6D coordinate descent to find affine transform
+ ubyte* match = new ubyte[size*size];
+ float step = 0.5;
+ for(int p = 0; p < 8; p++) { //foreach precision level
+ for(int i = 0; i < 2; i++) { // iterate twice per precision level
+ //TODO: other sweep pattern might converge better
+ for(int d=0; d < 6; d++) { // iterate dimension sequentially (cyclic descent)
+ for(float e = -step; e <= step; e+=step) { //solve subproblem (evaluate only along one coordinate)
+ mat32 t = m;
+ t.data[d] += e;
+ //TODO: better performance would also allow a more exhaustive search
+ SamplePattern(image,stride,t,match,size);
+ uint sad = SAD(reference,match,size,size);
+ // regularization: keep constant area and good condition
+ float area = t(0,0)*t(1,1)-t(0,1)*t(1,0);
+ float x = sq(t(0,0))+sq(t(0,1)), y = sq(t(1,0))+sq(t(1,1));
+ float condition = x>y ? x/y : y/x;
+ sad += size*size*( areaPenalty*sq(area-1) + conditionPenalty*sq(condition-1) );
+ if(sad < min) {
+ min = sad;
+ m = t;
+ }
+ }
+ }
+ }
+ step /= 2;
+ }
+ *warp = m;
+
+ // Compute Pearson product-moment correlation coefficient
+ uint sX=0,sY=0,sXX=0,sYY=0,sXY=0;
+ SamplePattern(image,stride,m,match,size);
+ SAD(reference,match,size,size);
+ for(int i = 0; i < size; i++) {
+ for(int j = 0; j < size; j++) {
+ int x = reference[i*size+j];
+ int y = match[i*size+j];
+ sX += x;
+ sY += y;
+ sXX += x*x;
+ sYY += y*y;
+ sXY += x*y;
+ }
+ }
+ delete[] match;
+ const int N = size*size;
+ sX /= N, sY /= N, sXX /= N, sYY /= N, sXY /= N;
+ return (sXY-sX*sY)/sqrt(double((sXX-sX*sX)*(sYY-sY*sY)));
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/sad.h b/extern/libmv/libmv/tracking/sad.h
new file mode 100644
index 00000000000..9fe323b74c4
--- /dev/null
+++ b/extern/libmv/libmv/tracking/sad.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (c) 2011 libmv authors.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to
+** deal in the Software without restriction, including without limitation the
+** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+** sell copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+** IN THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef LIBMV_TRACKING_SAD_H_
+#define LIBMV_TRACKING_SAD_H_
+
+#ifdef __cplusplus
+namespace libmv {
+#endif
+
+typedef unsigned char ubyte;
+typedef unsigned int uint;
+
+/*!
+ Convolve \a src into \a dst with the discrete laplacian operator.
+
+ \a src and \a dst should be \a width x \a height images.
+ \a strength is an interpolation coefficient (0-256) between original image and the laplacian.
+
+ \note Make sure the search region is filtered with the same strength as the pattern.
+*/
+void LaplaceFilter(ubyte* src, ubyte* dst, int width, int height, int strength);
+
+/// Affine transformation matrix in column major order.
+struct mat32 {
+ float data[3*2];
+#ifdef __cplusplus
+ inline mat32(int d=1) { for(int i=0;i<3*2;i++) data[i]=0; if(d!=0) for(int i=0;i<2;i++) m(i,i)=d; }
+ inline float m(int i, int j) const { return data[j*2+i]; }
+ inline float& m(int i, int j) { return data[j*2+i]; }
+ inline float operator()(int i, int j) const { return m(i,j); }
+ inline float& operator()(int i, int j) { return m(i,j); }
+ inline operator bool() const { for (int i=0; i<3*2; i++) if(data[i]!=0) return true; return false; }
+#endif
+};
+
+/*!
+ Sample \a pattern from \a image.
+
+ \a warp is the transformation to apply to \a image when sampling the \a pattern.
+*/
+void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int size);
+
+/*!
+ Track \a pattern in \a image.
+
+ This template matcher computes the
+ \link http://en.wikipedia.org/wiki/Sum_of_absolute_differences Sum of Absolute Differences (SAD) \endlink
+ for each integer pixel position in the search region and then iteratively
+ refine subpixel position using a square search.
+ A similar method is used for motion estimation in video encoders.
+
+ \a reference is the pattern to track.
+ \a warped is a warped version of reference for fast unsampled integer search.
+ Best is to directly extract an already warped pattern from previous frame.
+ The \a size of the patterns should be aligned to 16.
+ \a image is a reference to the region to search.
+ \a stride is size of \a image lines.
+
+ On input, \a warp is the predicted affine transformation (e.g from previous frame)
+ On return, \a warp is the affine transformation which best match the reference \a pattern
+
+ \a areaPenalty and conditionPenalty control the regularization and need to be tweaked depending on the motion.
+ Setting them to 0 will allow any transformation (including unrealistic distortions and scaling).
+ Good values are between 0-32. 16 can be used as a realistic default.
+ areaPenalty control scaling (decrease to allow pull/zoom, increase to allow only 2D rotation).
+ a large conditionPenalty avoid a large ratio between the largest and smallest axices.
+ It need to be decreased for non-2D rotation (when pattern appears to scale along an axis).
+
+ \return Pearson product-moment correlation coefficient between reference and matched pattern.
+ This measure of the linear dependence between the patterns
+ ranges from −1 (negative correlation) to 1 (positive correlation).
+ A value of 0 implies that there is no linear correlation between the variables.
+
+ \note To track affine features:
+ - Sample reference pattern using estimated (e.g previous frame) warp.
+ -
+ \note \a stride allow you to reference your search region instead of copying.
+ \note For a 16x speedup, compile this tracker with SSE2 support.
+*/
+float Track(ubyte* reference, ubyte* warped, int size, ubyte* image, int stride, int width, int height, mat32* warp,
+ float areaPenalty, float conditionPenalty);
+
+#ifdef __cplusplus
+} // namespace libmv
+#endif
+
+#endif // LIBMV_TRACKING_SAD_H_
diff --git a/extern/libmv/libmv/tracking/trklt_region_tracker.cc b/extern/libmv/libmv/tracking/trklt_region_tracker.cc
new file mode 100644
index 00000000000..94319fcb7d3
--- /dev/null
+++ b/extern/libmv/libmv/tracking/trklt_region_tracker.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/tracking/trklt_region_tracker.h"
+
+#include "libmv/logging/logging.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/image/image.h"
+#include "libmv/image/convolve.h"
+#include "libmv/image/sample.h"
+
+namespace libmv {
+
+// Computes U and e from the Ud = e equation (number 14) from the paper.
+static void ComputeTrackingEquation(const Array3Df &image_and_gradient1,
+ const Array3Df &image_and_gradient2,
+ double x1, double y1,
+ double x2, double y2,
+ int half_width,
+ double lambda,
+ Mat2f *U,
+ Vec2f *e) {
+ Mat2f A, B, C, D;
+ A = B = C = D = Mat2f::Zero();
+
+ Vec2f R, S, V, W;
+ R = S = V = W = Vec2f::Zero();
+
+ for (int r = -half_width; r <= half_width; ++r) {
+ for (int c = -half_width; c <= half_width; ++c) {
+ float xx1 = x1 + c;
+ float yy1 = y1 + r;
+ float xx2 = x2 + c;
+ float yy2 = y2 + r;
+
+ float I = SampleLinear(image_and_gradient1, yy1, xx1, 0);
+ float J = SampleLinear(image_and_gradient2, yy2, xx2, 0);
+
+ Vec2f gI, gJ;
+ gI << SampleLinear(image_and_gradient1, yy1, xx1, 1),
+ SampleLinear(image_and_gradient1, yy1, xx1, 2);
+ gJ << SampleLinear(image_and_gradient2, yy2, xx2, 1),
+ SampleLinear(image_and_gradient2, yy2, xx2, 2);
+
+ // Equation 15 from the paper.
+ A += gI * gI.transpose();
+ B += gI * gJ.transpose();
+ C += gJ * gJ.transpose();
+ R += I * gI;
+ S += J * gI;
+ V += I * gJ;
+ W += J * gJ;
+ }
+ }
+
+ // In the paper they show a D matrix, but it is just B transpose, so use that
+ // instead of explicitly computing D.
+ Mat2f Di = B.transpose().inverse();
+
+ // Equation 14 from the paper.
+ *U = A*Di*C + lambda*Di*C - 0.5*B;
+ *e = (A + lambda*Mat2f::Identity())*Di*(V - W) + 0.5*(S - R);
+}
+
+bool TrkltRegionTracker::Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const {
+ Array3Df image_and_gradient1;
+ Array3Df image_and_gradient2;
+ BlurredImageAndDerivativesChannels(image1, sigma, &image_and_gradient1);
+ BlurredImageAndDerivativesChannels(image2, sigma, &image_and_gradient2);
+
+ int i;
+ Vec2f d = Vec2f::Zero();
+ for (i = 0; i < max_iterations; ++i) {
+ // Compute gradient matrix and error vector.
+ Mat2f U;
+ Vec2f e;
+ ComputeTrackingEquation(image_and_gradient1,
+ image_and_gradient2,
+ x1, y1,
+ *x2, *y2,
+ half_window_size,
+ lambda,
+ &U, &e);
+
+ // Solve the linear system for the best update to x2 and y2.
+ d = U.lu().solve(e);
+
+ // Update the position with the solved displacement.
+ *x2 += d[0];
+ *y2 += d[1];
+
+ // Check for the quality of the solution, but not until having already
+ // updated the position with our best estimate. The reason to do the update
+ // anyway is that the user already knows the position is bad, so we may as
+ // well try our best.
+ float determinant = U.determinant();
+ if (fabs(determinant) < min_determinant) {
+ // The determinant, which indicates the trackiness of the point, is too
+ // small, so fail out.
+ LG << "Determinant " << determinant << " is too small; failing tracking.";
+ return false;
+ }
+
+ // If the update is small, then we probably found the target.
+ if (d.squaredNorm() < min_update_squared_distance) {
+ LG << "Successful track in " << i << " iterations.";
+ return true;
+ }
+ }
+ // Getting here means we hit max iterations, so tracking failed.
+ LG << "Too many iterations; max is set to " << max_iterations << ".";
+ return false;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/trklt_region_tracker.h b/extern/libmv/libmv/tracking/trklt_region_tracker.h
new file mode 100644
index 00000000000..5046e0f069d
--- /dev/null
+++ b/extern/libmv/libmv/tracking/trklt_region_tracker.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_REGION_TRACKING_TRKLT_REGION_TRACKER_H_
+#define LIBMV_REGION_TRACKING_TRKLT_REGION_TRACKER_H_
+
+#include "libmv/image/image.h"
+#include "libmv/tracking/region_tracker.h"
+
+namespace libmv {
+
+// An improved KLT algorithm that enforces that the tracking is time-reversible
+// [1]. This is not the same as the "symmetric" KLT that is sometimes used.
+// Anecdotally, this tracks much more consistently than vanilla KLT.
+//
+// [1] H. Wu, R. Chellappa, and A. Sankaranarayanan and S. Kevin Zhou. Robust
+// visual tracking using the time-reversibility constraint. International
+// Conference on Computer Vision (ICCV), Rio de Janeiro, October 2007.
+//
+struct TrkltRegionTracker : public RegionTracker {
+ TrkltRegionTracker()
+ : half_window_size(4),
+ max_iterations(100),
+ min_determinant(1e-6),
+ min_update_squared_distance(1e-6),
+ sigma(0.9),
+ lambda(0.05) {}
+
+ virtual ~TrkltRegionTracker() {}
+
+ // Tracker interface.
+ virtual bool Track(const FloatImage &image1,
+ const FloatImage &image2,
+ double x1, double y1,
+ double *x2, double *y2) const;
+
+ // No point in creating getters or setters.
+ int half_window_size;
+ int max_iterations;
+ double min_determinant;
+ double min_update_squared_distance;
+ double sigma;
+ double lambda;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_REGION_TRACKING_TRKLT_REGION_TRACKER_H_
diff --git a/extern/libmv/mkfiles.sh b/extern/libmv/mkfiles.sh
new file mode 100755
index 00000000000..6618f2849ea
--- /dev/null
+++ b/extern/libmv/mkfiles.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+find ./libmv/ -type f | sed -r 's/^\.\///' > files.txt
+find ./third_party/ -type f | sed -r 's/^\.\///' >> files.txt
diff --git a/extern/libmv/patches/bundle_tweaks.patch b/extern/libmv/patches/bundle_tweaks.patch
new file mode 100644
index 00000000000..f7b06b0a2dd
--- /dev/null
+++ b/extern/libmv/patches/bundle_tweaks.patch
@@ -0,0 +1,122 @@
+diff --git a/src/libmv/logging/logging.h b/src/libmv/logging/logging.h
+index 067da52..af86c4b 100644
+--- a/src/libmv/logging/logging.h
++++ b/src/libmv/logging/logging.h
+@@ -21,7 +21,7 @@
+ #ifndef LIBMV_LOGGING_LOGGING_H
+ #define LIBMV_LOGGING_LOGGING_H
+
+-#include "third_party/glog/src/glog/logging.h"
++#include "glog/logging.h"
+
+ #define LG LOG(INFO)
+ #define V0 LOG(INFO)
+diff --git a/src/third_party/glog/src/glog/logging.h b/src/third_party/glog/src/glog/logging.h
+index 57615ef..a58d478 100644
+--- a/src/third_party/glog/src/glog/logging.h
++++ b/src/third_party/glog/src/glog/logging.h
+@@ -33,6 +33,7 @@
+ // Pretty much everybody needs to #include this file so that they can
+ // log various happenings.
+ //
++
+ #ifndef _LOGGING_H_
+ #define _LOGGING_H_
+
+diff --git a/src/third_party/glog/src/logging.cc b/src/third_party/glog/src/logging.cc
+index 868898f..1bb3867 100644
+--- a/src/third_party/glog/src/logging.cc
++++ b/src/third_party/glog/src/logging.cc
+@@ -58,8 +58,8 @@
+ #include <errno.h> // for errno
+ #include <sstream>
+ #include "base/commandlineflags.h" // to get the program name
+-#include "glog/logging.h"
+-#include "glog/raw_logging.h"
++#include <glog/logging.h>
++#include <glog/raw_logging.h>
+ #include "base/googleinit.h"
+
+ #ifdef HAVE_STACKTRACE
+@@ -1232,7 +1232,9 @@ void LogMessage::RecordCrashReason(
+ }
+
+ static void logging_fail() {
+-#if defined(_DEBUG) && defined(_MSC_VER)
++// #if defined(_DEBUG) && defined(_MSC_VER)
++// doesn't work for my laptop (sergey)
++#if 0
+ // When debugging on windows, avoid the obnoxious dialog and make
+ // it possible to continue past a LOG(FATAL) in the debugger
+ _asm int 3
+diff --git a/src/third_party/glog/src/raw_logging.cc b/src/third_party/glog/src/raw_logging.cc
+index 50c6a71..b179a1e 100644
+--- a/src/third_party/glog/src/raw_logging.cc
++++ b/src/third_party/glog/src/raw_logging.cc
+@@ -42,8 +42,8 @@
+ #include <fcntl.h> // for open()
+ #include <time.h>
+ #include "config.h"
+-#include "glog/logging.h" // To pick up flag settings etc.
+-#include "glog/raw_logging.h"
++#include <glog/logging.h> // To pick up flag settings etc.
++#include <glog/raw_logging.h>
+ #include "base/commandlineflags.h"
+
+ #ifdef HAVE_STACKTRACE
+diff --git a/src/third_party/glog/src/utilities.h b/src/third_party/glog/src/utilities.h
+index ee54f94..2d4e99e 100644
+--- a/src/third_party/glog/src/utilities.h
++++ b/src/third_party/glog/src/utilities.h
+@@ -79,7 +79,7 @@
+ #endif
+
+ #include "config.h"
+-#include "glog/logging.h"
++#include <glog/logging.h>
+
+ // There are three different ways we can try to get the stack trace:
+ //
+diff --git a/src/third_party/glog/src/vlog_is_on.cc b/src/third_party/glog/src/vlog_is_on.cc
+index ee0e412..ed88514 100644
+--- a/src/third_party/glog/src/vlog_is_on.cc
++++ b/src/third_party/glog/src/vlog_is_on.cc
+@@ -40,8 +40,8 @@
+ #include <cstdio>
+ #include <string>
+ #include "base/commandlineflags.h"
+-#include "glog/logging.h"
+-#include "glog/raw_logging.h"
++#include <glog/logging.h>
++#include <glog/raw_logging.h>
+ #include "base/googleinit.h"
+
+ // glog doesn't have annotation
+diff --git a/src/third_party/glog/src/windows/config.h b/src/third_party/glog/src/windows/config.h
+index 114762e..682a1b9 100755
+--- a/src/third_party/glog/src/windows/config.h
++++ b/src/third_party/glog/src/windows/config.h
+@@ -19,7 +19,7 @@
+ #undef HAVE_LIBUNWIND_H
+
+ /* define if you have google gflags library */
+-#undef HAVE_LIB_GFLAGS
++#define HAVE_LIB_GFLAGS 1
+
+ /* define if you have libunwind */
+ #undef HAVE_LIB_UNWIND
+diff --git a/src/third_party/glog/src/windows/glog/logging.h b/src/third_party/glog/src/windows/glog/logging.h
+index 7a6df74..de51586 100755
+--- a/src/third_party/glog/src/windows/glog/logging.h
++++ b/src/third_party/glog/src/windows/glog/logging.h
+@@ -82,8 +82,8 @@
+ #include <inttypes.h> // a third place for uint16_t or u_int16_t
+ #endif
+
+-#if 0
+-#include <gflags/gflags.h>
++#if 1
++#include "third_party/gflags/gflags.h"
+ #endif
+
+ namespace google {
diff --git a/extern/libmv/patches/config_mac.patch b/extern/libmv/patches/config_mac.patch
new file mode 100644
index 00000000000..5a880155bfa
--- /dev/null
+++ b/extern/libmv/patches/config_mac.patch
@@ -0,0 +1,13 @@
+diff --git a/src/third_party/glog/src/config_mac.h b/src/third_party/glog/src/config_mac.h
+index a45575b..5f953d1 100644
+--- a/src/third_party/glog/src/config_mac.h
++++ b/src/third_party/glog/src/config_mac.h
+@@ -131,7 +131,7 @@
+ #define PACKAGE_VERSION "0.3.1"
+
+ /* How to access the PC from a struct ucontext */
+-#define PC_FROM_UCONTEXT uc_mcontext->__ss.__rip
++#undef PC_FROM_UCONTEXT
+
+ /* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
diff --git a/extern/libmv/patches/detect.patch b/extern/libmv/patches/detect.patch
new file mode 100644
index 00000000000..36fea8427db
--- /dev/null
+++ b/extern/libmv/patches/detect.patch
@@ -0,0 +1,181 @@
+diff --git a/src/libmv/simple_pipeline/detect.cc b/src/libmv/simple_pipeline/detect.cc
+index 6fc0cdd..8ac42ab 100644
+--- a/src/libmv/simple_pipeline/detect.cc
++++ b/src/libmv/simple_pipeline/detect.cc
+@@ -23,15 +23,89 @@
+ ****************************************************************************/
+
+ #include "libmv/simple_pipeline/detect.h"
++#include <third_party/fast/fast.h>
+ #include <stdlib.h>
+-#include <string.h>
++#include <memory.h>
++
++#ifdef __SSE2__
++#include <emmintrin.h>
++#endif
+
+ namespace libmv {
+
+ typedef unsigned int uint;
+
++int featurecmp(const void *a_v, const void *b_v)
++{
++ Feature *a = (Feature*)a_v;
++ Feature *b = (Feature*)b_v;
++
++ return b->score - a->score;
++}
++
++std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride,
++ int min_trackness, int min_distance) {
++ std::vector<Feature> features;
++ // TODO(MatthiasF): Support targetting a feature count (binary search trackness)
++ int num_features;
++ xy* all = fast9_detect(data, width, height,
++ stride, min_trackness, &num_features);
++ if(num_features == 0) {
++ free(all);
++ return features;
++ }
++ int* scores = fast9_score(data, stride, all, num_features, min_trackness);
++ // TODO: merge with close feature suppression
++ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features);
++ free(all);
++ // Remove too close features
++ // TODO(MatthiasF): A resolution independent parameter would be better than distance
++ // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing)
++ // FIXME(MatthiasF): this method will not necessarily give all maximum markers
++ if(num_features) {
++ Feature *all_features = new Feature[num_features];
++
++ for(int i = 0; i < num_features; ++i) {
++ Feature a = { nonmax[i].x, nonmax[i].y, scores[i], 0 };
++ all_features[i] = a;
++ }
++
++ qsort((void *)all_features, num_features, sizeof(Feature), featurecmp);
++
++ features.reserve(num_features);
++
++ int prev_score = all_features[0].score;
++ for(int i = 0; i < num_features; ++i) {
++ bool ok = true;
++ Feature a = all_features[i];
++ if(a.score>prev_score)
++ abort();
++ prev_score = a.score;
++
++ // compare each feature against filtered set
++ for(int j = 0; j < features.size(); j++) {
++ Feature& b = features[j];
++ if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) {
++ // already a nearby feature
++ ok = false;
++ break;
++ }
++ }
++
++ if(ok) {
++ // add the new feature
++ features.push_back(a);
++ }
++ }
++
++ delete [] all_features;
++ }
++ free(scores);
++ free(nonmax);
++ return features;
++}
++
+ #ifdef __SSE2__
+-#include <emmintrin.h>
+ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) {
+ __m128i a = _mm_setzero_si128();
+ for(int i = 0; i < 16; i++) {
+@@ -52,7 +126,7 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid
+ }
+ #endif
+
+-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
++void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
+ unsigned short histogram[256];
+ memset(histogram,0,sizeof(histogram));
+ ubyte* scores = new ubyte[width*height];
+diff --git a/src/libmv/simple_pipeline/detect.h b/src/libmv/simple_pipeline/detect.h
+index 23b239b..bbe7aed 100644
+--- a/src/libmv/simple_pipeline/detect.h
++++ b/src/libmv/simple_pipeline/detect.h
+@@ -25,27 +25,52 @@
+ #ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
+ #define LIBMV_SIMPLE_PIPELINE_DETECT_H_
+
+-#ifdef __cplusplus
++#include <vector>
++
+ namespace libmv {
+-#endif
+
+ typedef unsigned char ubyte;
+
+ /*!
+- \a Feature is the 2D location of a detected feature in an image.
++ A Feature is the 2D location of a detected feature in an image.
+
+- \a x, \a y is the position of the center in pixels (from image top-left).
+- \a score is an estimate of how well the pattern will be tracked.
+- \a size can be used as an initial size to track the pattern.
++ \a x, \a y is the position of the feature in pixels from the top left corner.
++ \a score is an estimate of how well the feature will be tracked.
++ \a size can be used as an initial pattern size to track the feature.
+
+ \sa Detect
+ */
+ struct Feature {
++ /// Position in pixels (from top-left corner)
++ /// \note libmv might eventually support subpixel precision.
+ float x, y;
++ /// Trackness of the feature
+ float score;
++ /// Size of the feature in pixels
+ float size;
+ };
+- //radius for non maximal suppression
++
++/*!
++ Detect features in an image.
++
++ You need to input a single channel 8-bit image using pointer to image \a data,
++ \a width, \a height and \a stride (i.e bytes per line).
++
++ You can tweak the count of detected features using \a min_trackness, which is
++ the minimum score to add a feature, and \a min_distance which is the minimal
++ distance accepted between two featuress.
++
++ \note You can binary search over \a min_trackness to get a given feature count.
++
++ \note a way to get an uniform distribution of a given feature count is:
++ \a min_distance = \a width * \a height / desired_feature_count ^ 2
++
++ \return All detected feartures matching given parameters
++*/
++std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height,
++ int stride, int min_trackness = 128,
++ int min_distance = 120);
++
+ /*!
+ Detect features in an image.
+
+@@ -63,10 +88,8 @@ struct Feature {
+ \note \a You can crop the image (to avoid detecting markers near the borders) without copying:
+ image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY;
+ */
+-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
++void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
+
+-#ifdef __cplusplus
+ }
+-#endif
+
+ #endif
diff --git a/extern/libmv/patches/fast.patch b/extern/libmv/patches/fast.patch
new file mode 100644
index 00000000000..8e0aeb7e721
--- /dev/null
+++ b/extern/libmv/patches/fast.patch
@@ -0,0 +1,24 @@
+diff --git a/src/third_party/fast/fast.h b/src/third_party/fast/fast.h
+index 2b3825a..06fa90e 100644
+--- a/src/third_party/fast/fast.h
++++ b/src/third_party/fast/fast.h
+@@ -1,6 +1,10 @@
+ #ifndef FAST_H
+ #define FAST_H
+
++#ifdef __cplusplus
++extern "C" {
++#endif
++
+ typedef struct { int x, y; } xy;
+ typedef unsigned char byte;
+
+@@ -28,4 +32,8 @@ xy* fast12_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b
+ xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax);
+
+
++#ifdef __cplusplus
++}
++#endif
++
+ #endif
diff --git a/extern/libmv/patches/function_derivative.patch b/extern/libmv/patches/function_derivative.patch
new file mode 100644
index 00000000000..be7ccfc911a
--- /dev/null
+++ b/extern/libmv/patches/function_derivative.patch
@@ -0,0 +1,21 @@
+diff --git a/src/libmv/numeric/function_derivative.h b/src/libmv/numeric/function_derivative.h
+index 0075d23..d7bc437 100644
+--- a/src/libmv/numeric/function_derivative.h
++++ b/src/libmv/numeric/function_derivative.h
+@@ -24,6 +24,7 @@
+ #include <cmath>
+
+ #include "libmv/numeric/numeric.h"
++#include "libmv/logging/logging.h"
+
+ namespace libmv {
+
+@@ -97,7 +98,7 @@ bool CheckJacobian(const Function &f, const typename Function::XMatrixType &x) {
+
+ typename NumericJacobian<Function>::JMatrixType J_numeric = j_numeric(x);
+ typename NumericJacobian<Function>::JMatrixType J_analytic = j_analytic(x);
+- //LG << J_numeric - J_analytic;
++ LG << J_numeric - J_analytic;
+ return true;
+ }
+
diff --git a/extern/libmv/patches/high_distortion_crash_fix.patch b/extern/libmv/patches/high_distortion_crash_fix.patch
new file mode 100644
index 00000000000..54ab66fa27c
--- /dev/null
+++ b/extern/libmv/patches/high_distortion_crash_fix.patch
@@ -0,0 +1,21 @@
+diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc
+index 4e88e1f..f9888ff 100644
+--- a/src/libmv/simple_pipeline/camera_intrinsics.cc
++++ b/src/libmv/simple_pipeline/camera_intrinsics.cc
+@@ -160,9 +160,13 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
+ if( iy < 0 ) { iy = 0, fy = 0; }
+ if( ix >= width-2 ) ix = width-2;
+ if( iy >= height-2 ) iy = height-2;
+- //assert( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 );
+- Offset offset = { ix-x, iy-y, fx, fy };
+- grid[y*width+x] = offset;
++ if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) {
++ Offset offset = { ix-x, iy-y, fx, fy };
++ grid[y*width+x] = offset;
++ } else {
++ Offset offset = { 0, 0, 0, 0 };
++ grid[y*width+x] = offset;
++ }
+ }
+ }
+ }
diff --git a/extern/libmv/patches/levenberg_marquardt.patch b/extern/libmv/patches/levenberg_marquardt.patch
new file mode 100644
index 00000000000..49ef82d73d2
--- /dev/null
+++ b/extern/libmv/patches/levenberg_marquardt.patch
@@ -0,0 +1,71 @@
+diff --git a/src/libmv/numeric/levenberg_marquardt.h b/src/libmv/numeric/levenberg_marquardt.h
+index 6a54f66..4473b72 100644
+--- a/src/libmv/numeric/levenberg_marquardt.h
++++ b/src/libmv/numeric/levenberg_marquardt.h
+@@ -33,6 +33,7 @@
+
+ #include "libmv/numeric/numeric.h"
+ #include "libmv/numeric/function_derivative.h"
++#include "libmv/logging/logging.h"
+
+ namespace libmv {
+
+@@ -123,26 +124,40 @@ class LevenbergMarquardt {
+ Parameters dx, x_new;
+ int i;
+ for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) {
+- if (dx.norm() <= params.relative_step_threshold * x.norm()) {
++ VLOG(1) << "iteration: " << i;
++ VLOG(1) << "||f(x)||: " << f_(x).norm();
++ VLOG(1) << "max(g): " << g.array().abs().maxCoeff();
++ VLOG(1) << "u: " << u;
++ VLOG(1) << "v: " << v;
++
++ AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols());
++ Solver solver(A_augmented);
++ dx = solver.solve(g);
++ bool solved = (A_augmented * dx).isApprox(g);
++ if (!solved) {
++ LOG(ERROR) << "Failed to solve";
++ }
++ if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) {
+ results.status = RELATIVE_STEP_SIZE_TOO_SMALL;
+ break;
+- }
+- x_new = x + dx;
+- // Rho is the ratio of the actual reduction in error to the reduction
+- // in error that would be obtained if the problem was linear.
+- // See [1] for details.
+- Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm())
+- / dx.dot(u*dx + g));
+- if (rho > 0) {
+- // Accept the Gauss-Newton step because the linear model fits well.
+- x = x_new;
+- results.status = Update(x, params, &J, &A, &error, &g);
+- Scalar tmp = Scalar(2*rho-1);
+- u = u*std::max(1/3., 1 - (tmp*tmp*tmp));
+- v = 2;
+- continue;
+- }
+-
++ }
++ if (solved) {
++ x_new = x + dx;
++ // Rho is the ratio of the actual reduction in error to the reduction
++ // in error that would be obtained if the problem was linear.
++ // See [1] for details.
++ Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm())
++ / dx.dot(u*dx + g));
++ if (rho > 0) {
++ // Accept the Gauss-Newton step because the linear model fits well.
++ x = x_new;
++ results.status = Update(x, params, &J, &A, &error, &g);
++ Scalar tmp = Scalar(2*rho-1);
++ u = u*std::max(1/3., 1 - (tmp*tmp*tmp));
++ v = 2;
++ continue;
++ }
++ }
+ // Reject the update because either the normal equations failed to solve
+ // or the local linear model was not good (rho < 0). Instead, increase u
+ // to move closer to gradient descent.
diff --git a/extern/libmv/patches/mingw.patch b/extern/libmv/patches/mingw.patch
new file mode 100644
index 00000000000..029e7d7f979
--- /dev/null
+++ b/extern/libmv/patches/mingw.patch
@@ -0,0 +1,171 @@
+diff --git a/src/libmv/multiview/euclidean_resection.cc b/src/libmv/multiview/euclidean_resection.cc
+index 6d918a1..9286251 100644
+--- a/src/libmv/multiview/euclidean_resection.cc
++++ b/src/libmv/multiview/euclidean_resection.cc
+@@ -32,6 +32,8 @@
+ namespace libmv {
+ namespace euclidean_resection {
+
++typedef unsigned int uint;
++
+ bool EuclideanResection(const Mat2X &x_camera,
+ const Mat3X &X_world,
+ Mat3 *R, Vec3 *t,
+diff --git a/src/libmv/numeric/numeric.h b/src/libmv/numeric/numeric.h
+index f39d126..21e0f06 100644
+--- a/src/libmv/numeric/numeric.h
++++ b/src/libmv/numeric/numeric.h
+@@ -40,7 +40,7 @@
+ }
+ #endif //_WIN32 || __APPLE__
+
+-#if _WIN32
++#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__)
+ inline long lround(double d) {
+ return (long)(d>0 ? d+0.5 : ceil(d-0.5));
+ }
+diff --git a/src/third_party/glog/src/config.h b/src/third_party/glog/src/config.h
+index ed8d56e..06ed686 100644
+--- a/src/third_party/glog/src/config.h
++++ b/src/third_party/glog/src/config.h
+@@ -4,6 +4,8 @@
+ /* Namespace for Google classes */
+ #ifdef __APPLE__
+ #include "config_mac.h"
++#elif __MINGW32__
++ #include "windows/config.h"
+ #elif __GNUC__
+ #include "config_linux.h"
+ #elif _MSC_VER
+diff --git a/src/third_party/glog/src/utilities.h b/src/third_party/glog/src/utilities.h
+index ee54f94..c4ae256 100644
+--- a/src/third_party/glog/src/utilities.h
++++ b/src/third_party/glog/src/utilities.h
+@@ -101,7 +101,9 @@
+ // correctly when GetStackTrace() is called with max_depth == 0.
+ // Some code may do that.
+
+-#if defined(HAVE_LIB_UNWIND)
++#if __MINGW32__
++# undef STACKTRACE_H
++#elif defined(HAVE_LIB_UNWIND)
+ # define STACKTRACE_H "stacktrace_libunwind-inl.h"
+ #elif !defined(NO_FRAME_POINTER)
+ # if defined(__i386__) && __GNUC__ >= 2
+diff --git a/src/third_party/glog/src/windows/glog/logging.h b/src/third_party/glog/src/windows/glog/logging.h
+index 7a6df74..4257375 100755
+--- a/src/third_party/glog/src/windows/glog/logging.h
++++ b/src/third_party/glog/src/windows/glog/logging.h
+@@ -59,7 +59,7 @@
+
+ // Annoying stuff for windows -- makes sure clients can import these functions
+ #ifndef GOOGLE_GLOG_DLL_DECL
+-# if defined(_WIN32) && !defined(__CYGWIN__)
++# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
+ # define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+ # else
+ # define GOOGLE_GLOG_DLL_DECL
+@@ -86,6 +86,15 @@
+ #include <gflags/gflags.h>
+ #endif
+
++#ifdef __MINGW32__
++# include <stdlib.h>
++# include <unistd.h>
++# include <stdint.h> // the normal place uint16_t is defined
++# include <sys/types.h> // the normal place u_int16_t is defined
++# include <inttypes.h> // a third place for uint16_t or u_int16_t
++# define _exit(x) exit(x)
++#endif
++
+ namespace google {
+
+ #if 0 // the C99 format
+@@ -98,11 +107,16 @@ typedef int32_t int32;
+ typedef u_int32_t uint32;
+ typedef int64_t int64;
+ typedef u_int64_t uint64;
+-#elif 1 // the windows (vc7) format
++#elif defined(_MSC_VER)
+ typedef __int32 int32;
+ typedef unsigned __int32 uint32;
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
++#elif defined(__MINGW32__)
++typedef int32_t int32;
++typedef uint32_t uint32;
++typedef int64_t int64;
++typedef uint64_t uint64;
+ #else
+ #error Do not know how to define a 32-bit integer quantity on your system
+ #endif
+diff --git a/src/third_party/glog/src/windows/port.h b/src/third_party/glog/src/windows/port.h
+index d093bf5..d507812 100755
+--- a/src/third_party/glog/src/windows/port.h
++++ b/src/third_party/glog/src/windows/port.h
+@@ -59,14 +59,16 @@
+ * used by both C and C++ code, so we put all the C++ together.
+ */
+
+-/* 4244: otherwise we get problems when substracting two size_t's to an int
+- * 4251: it's complaining about a private struct I've chosen not to dllexport
+- * 4355: we use this in a constructor, but we do it safely
+- * 4715: for some reason VC++ stopped realizing you can't return after abort()
+- * 4800: we know we're casting ints/char*'s to bools, and we're ok with that
+- * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
+- */
+-#pragma warning(disable:4244 4251 4355 4715 4800 4996)
++#if _MSC_VER
++ /* 4244: otherwise we get problems when substracting two size_t's to an int
++ * 4251: it's complaining about a private struct I've chosen not to dllexport
++ * 4355: we use this in a constructor, but we do it safely
++ * 4715: for some reason VC++ stopped realizing you can't return after abort()
++ * 4800: we know we're casting ints/char*'s to bools, and we're ok with that
++ * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
++ */
++# pragma warning(disable:4244 4251 4355 4715 4800 4996)
++#endif
+
+ /* file I/O */
+ #define PATH_MAX 1024
+@@ -108,7 +110,9 @@ extern int snprintf(char *str, size_t size,
+ extern int safe_vsnprintf(char *str, size_t size,
+ const char *format, va_list ap);
+ #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
++#if !defined(__MINGW32__)
+ #define va_copy(dst, src) (dst) = (src)
++#endif
+
+ /* Windows doesn't support specifying the number of buckets as a
+ * hash_map constructor arg, so we leave this blank.
+@@ -130,13 +134,30 @@ enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
+ #define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2))
+
+ inline struct tm* localtime_r(const time_t* timep, struct tm* result) {
++#if __MINGW32__
++ struct tm *local_result;
++ local_result = localtime (timep);
++
++ if (local_result == NULL || result == NULL)
++ return NULL;
++
++ memcpy (result, local_result, sizeof (result));
++
++ return result;
++#else
+ localtime_s(result, timep);
+ return result;
++#endif
+ }
+
+ inline char* strerror_r(int errnum, char* buf, size_t buflen) {
++#if __MINGW32__
++ strncpy(buf, "Not implemented yet", buflen);
++ return buf;
++#else
+ strerror_s(buf, buflen, errnum);
+ return buf;
++#endif
+ }
+
+ #ifndef __cplusplus
diff --git a/extern/libmv/patches/msvc2010.patch b/extern/libmv/patches/msvc2010.patch
new file mode 100644
index 00000000000..c090b070628
--- /dev/null
+++ b/extern/libmv/patches/msvc2010.patch
@@ -0,0 +1,12 @@
+diff --git a/src/libmv/simple_pipeline/tracks.cc b/src/libmv/simple_pipeline/tracks.cc
+index 0e2a1b6..3fb8ddb 100644
+--- a/src/libmv/simple_pipeline/tracks.cc
++++ b/src/libmv/simple_pipeline/tracks.cc
+@@ -20,6 +20,7 @@
+
+ #include <algorithm>
+ #include <vector>
++#include <iterator>
+
+ #include "libmv/numeric/numeric.h"
+ #include "libmv/simple_pipeline/tracks.h"
diff --git a/extern/libmv/patches/overscan.patch b/extern/libmv/patches/overscan.patch
new file mode 100644
index 00000000000..c68f36804ec
--- /dev/null
+++ b/extern/libmv/patches/overscan.patch
@@ -0,0 +1,182 @@
+diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc
+index 110a16d..366129d 100644
+--- a/src/libmv/simple_pipeline/camera_intrinsics.cc
++++ b/src/libmv/simple_pipeline/camera_intrinsics.cc
+@@ -31,6 +31,7 @@ struct Offset {
+ struct Grid {
+ struct Offset *offset;
+ int width, height;
++ double overscan;
+ };
+
+ static struct Grid *copyGrid(struct Grid *from)
+@@ -42,6 +43,7 @@ static struct Grid *copyGrid(struct Grid *from)
+
+ to->width = from->width;
+ to->height = from->height;
++ to->overscan = from->overscan;
+
+ to->offset = new Offset[to->width*to->height];
+ memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height);
+@@ -184,17 +186,19 @@ void CameraIntrinsics::InvertIntrinsics(double image_x,
+
+ // TODO(MatthiasF): downsample lookup
+ template<typename WarpFunction>
+-void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height) {
+- double aspx = (double)width / image_width_;
+- double aspy = (double)height / image_height_;
++void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, double overscan) {
++ double w = (double)width / (1 + overscan);
++ double h = (double)height / (1 + overscan);
++ double aspx = (double)w / image_width_;
++ double aspy = (double)h / image_height_;
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+- double src_x = x / aspx, src_y = y / aspy;
++ double src_x = (x - 0.5 * overscan * w) / aspx, src_y = (y - 0.5 * overscan * h) / aspy;
+ double warp_x, warp_y;
+ WarpFunction(this,src_x,src_y,&warp_x,&warp_y);
+- warp_x = warp_x*aspx;
+- warp_y = warp_y*aspy;
++ warp_x = warp_x*aspx + 0.5 * overscan * w;
++ warp_y = warp_y*aspy + 0.5 * overscan * h;
+ int ix = int(warp_x), iy = int(warp_y);
+ int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256);
+ if(fx == 256) { fx=0; ix++; }
+@@ -264,10 +268,10 @@ struct InvertIntrinsicsFunction {
+ }
+ };
+
+-void CameraIntrinsics::CheckDistortLookupGrid(int width, int height)
++void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double overscan)
+ {
+ if(distort_) {
+- if(distort_->width != width || distort_->height != height) {
++ if(distort_->width != width || distort_->height != height || distort_->overscan != overscan) {
+ delete [] distort_->offset;
+ distort_->offset = NULL;
+ }
+@@ -278,17 +282,18 @@ void CameraIntrinsics::CheckDistortLookupGrid(int width, int height)
+
+ if(!distort_->offset) {
+ distort_->offset = new Offset[width*height];
+- ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
++ ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height,overscan);
+ }
+
+ distort_->width = width;
+ distort_->height = height;
++ distort_->overscan = overscan;
+ }
+
+-void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height)
++void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double overscan)
+ {
+ if(undistort_) {
+- if(undistort_->width != width || undistort_->height != height) {
++ if(undistort_->width != width || undistort_->height != height || undistort_->overscan != overscan) {
+ delete [] undistort_->offset;
+ undistort_->offset = NULL;
+ }
+@@ -299,15 +304,16 @@ void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height)
+
+ if(!undistort_->offset) {
+ undistort_->offset = new Offset[width*height];
+- ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
++ ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height,overscan);
+ }
+
+ undistort_->width = width;
+ undistort_->height = height;
++ undistort_->overscan = overscan;
+ }
+
+-void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
+- CheckDistortLookupGrid(width, height);
++void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, double overscan, int channels) {
++ CheckDistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<float,1>(distort_,src,dst,width,height);
+ else if(channels==2) Warp<float,2>(distort_,src,dst,width,height);
+ else if(channels==3) Warp<float,3>(distort_,src,dst,width,height);
+@@ -315,8 +321,8 @@ void CameraIntrinsics::Distort(const float* src, float* dst, int width, int heig
+ //else assert("channels must be between 1 and 4");
+ }
+
+-void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
+- CheckDistortLookupGrid(width, height);
++void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) {
++ CheckDistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height);
+ else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height);
+ else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height);
+@@ -324,8 +330,8 @@ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int
+ //else assert("channels must be between 1 and 4");
+ }
+
+-void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, int channels) {
+- CheckUndistortLookupGrid(width, height);
++void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, double overscan, int channels) {
++ CheckUndistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<float,1>(undistort_,src,dst,width,height);
+ else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height);
+ else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height);
+@@ -333,8 +339,8 @@ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int he
+ //else assert("channels must be between 1 and 4");
+ }
+
+-void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
+- CheckUndistortLookupGrid(width, height);
++void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) {
++ CheckUndistortLookupGrid(width, height, overscan);
+ if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height);
+ else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height);
+ else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height);
+diff --git a/src/libmv/simple_pipeline/camera_intrinsics.h b/src/libmv/simple_pipeline/camera_intrinsics.h
+index f525571..f4bf903 100644
+--- a/src/libmv/simple_pipeline/camera_intrinsics.h
++++ b/src/libmv/simple_pipeline/camera_intrinsics.h
+@@ -91,7 +91,7 @@ class CameraIntrinsics {
+ \note This is the reference implementation using floating point images.
+ */
+ void Distort(const float* src, float* dst,
+- int width, int height, int channels);
++ int width, int height, double overscan, int channels);
+ /*!
+ Distort an image using the current camera instrinsics
+
+@@ -101,7 +101,7 @@ class CameraIntrinsics {
+ \note This version is much faster.
+ */
+ void Distort(const unsigned char* src, unsigned char* dst,
+- int width, int height, int channels);
++ int width, int height, double overscan, int channels);
+ /*!
+ Undistort an image using the current camera instrinsics
+
+@@ -111,7 +111,7 @@ class CameraIntrinsics {
+ \note This is the reference implementation using floating point images.
+ */
+ void Undistort(const float* src, float* dst,
+- int width, int height, int channels);
++ int width, int height, double overscan, int channels);
+ /*!
+ Undistort an image using the current camera instrinsics
+
+@@ -121,12 +121,12 @@ class CameraIntrinsics {
+ \note This version is much faster.
+ */
+ void Undistort(const unsigned char* src, unsigned char* dst,
+- int width, int height, int channels);
++ int width, int height, double overscan, int channels);
+
+ private:
+- template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height);
+- void CheckUndistortLookupGrid(int width, int height);
+- void CheckDistortLookupGrid(int width, int height);
++ template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height, double overscan);
++ void CheckUndistortLookupGrid(int width, int height, double overscan);
++ void CheckDistortLookupGrid(int width, int height, double overscan);
+ void FreeLookupGrid();
+
+ // The traditional intrinsics matrix from x = K[R|t]X.
diff --git a/extern/libmv/patches/scaled_distortion.patch b/extern/libmv/patches/scaled_distortion.patch
new file mode 100644
index 00000000000..2da832931d1
--- /dev/null
+++ b/extern/libmv/patches/scaled_distortion.patch
@@ -0,0 +1,261 @@
+diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc
+index f9888ff..110a16d 100644
+--- a/src/libmv/simple_pipeline/camera_intrinsics.cc
++++ b/src/libmv/simple_pipeline/camera_intrinsics.cc
+@@ -23,7 +23,32 @@
+
+ namespace libmv {
+
+-struct Offset { signed char ix,iy; unsigned char fx,fy; };
++struct Offset {
++ signed char ix, iy;
++ unsigned char fx,fy;
++};
++
++struct Grid {
++ struct Offset *offset;
++ int width, height;
++};
++
++static struct Grid *copyGrid(struct Grid *from)
++{
++ struct Grid *to = NULL;
++
++ if (from) {
++ to = new Grid;
++
++ to->width = from->width;
++ to->height = from->height;
++
++ to->offset = new Offset[to->width*to->height];
++ memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height);
++ }
++
++ return to;
++}
+
+ CameraIntrinsics::CameraIntrinsics()
+ : K_(Mat3::Identity()),
+@@ -37,9 +62,22 @@ CameraIntrinsics::CameraIntrinsics()
+ distort_(0),
+ undistort_(0) {}
+
++CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from)
++ : K_(from.K_),
++ image_width_(from.image_width_),
++ image_height_(from.image_height_),
++ k1_(from.k1_),
++ k2_(from.k2_),
++ k3_(from.k3_),
++ p1_(from.p1_),
++ p2_(from.p2_)
++{
++ distort_ = copyGrid(from.distort_);
++ undistort_ = copyGrid(from.undistort_);
++}
++
+ CameraIntrinsics::~CameraIntrinsics() {
+- if(distort_) delete[] distort_;
+- if(undistort_) delete[] undistort_;
++ FreeLookupGrid();
+ }
+
+ /// Set the entire calibration matrix at once.
+@@ -146,11 +184,17 @@ void CameraIntrinsics::InvertIntrinsics(double image_x,
+
+ // TODO(MatthiasF): downsample lookup
+ template<typename WarpFunction>
+-void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
++void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height) {
++ double aspx = (double)width / image_width_;
++ double aspy = (double)height / image_height_;
++
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
++ double src_x = x / aspx, src_y = y / aspy;
+ double warp_x, warp_y;
+- WarpFunction(this,x,y,&warp_x,&warp_y);
++ WarpFunction(this,src_x,src_y,&warp_x,&warp_y);
++ warp_x = warp_x*aspx;
++ warp_y = warp_y*aspy;
+ int ix = int(warp_x), iy = int(warp_y);
+ int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256);
+ if(fx == 256) { fx=0; ix++; }
+@@ -162,10 +206,10 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
+ if( iy >= height-2 ) iy = height-2;
+ if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) {
+ Offset offset = { ix-x, iy-y, fx, fy };
+- grid[y*width+x] = offset;
++ grid->offset[y*width+x] = offset;
+ } else {
+ Offset offset = { 0, 0, 0, 0 };
+- grid[y*width+x] = offset;
++ grid->offset[y*width+x] = offset;
+ }
+ }
+ }
+@@ -173,11 +217,11 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) {
+
+ // TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
+ template<typename T,int N>
+-static void Warp(const Offset* grid, const T* src, T* dst,
++static void Warp(const Grid* grid, const T* src, T* dst,
+ int width, int height) {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+- Offset offset = grid[y*width+x];
++ Offset offset = grid->offset[y*width+x];
+ const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N];
+ for (int i = 0; i < N; i++) {
+ dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy)
+@@ -188,8 +232,17 @@ static void Warp(const Offset* grid, const T* src, T* dst,
+ }
+
+ void CameraIntrinsics::FreeLookupGrid() {
+- if(distort_) delete distort_, distort_=0;
+- if(undistort_) delete undistort_, undistort_=0;
++ if(distort_) {
++ delete distort_->offset;
++ delete distort_;
++ distort_ = NULL;
++ }
++
++ if(undistort_) {
++ delete undistort_->offset;
++ delete undistort_;
++ undistort_ = NULL;
++ }
+ }
+
+ // FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method.
+@@ -211,11 +264,50 @@ struct InvertIntrinsicsFunction {
+ }
+ };
+
+-void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
+- if(!distort_) {
+- distort_ = new Offset[width*height];
+- ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
++void CameraIntrinsics::CheckDistortLookupGrid(int width, int height)
++{
++ if(distort_) {
++ if(distort_->width != width || distort_->height != height) {
++ delete [] distort_->offset;
++ distort_->offset = NULL;
++ }
++ } else {
++ distort_ = new Grid;
++ distort_->offset = NULL;
++ }
++
++ if(!distort_->offset) {
++ distort_->offset = new Offset[width*height];
++ ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
+ }
++
++ distort_->width = width;
++ distort_->height = height;
++}
++
++void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height)
++{
++ if(undistort_) {
++ if(undistort_->width != width || undistort_->height != height) {
++ delete [] undistort_->offset;
++ undistort_->offset = NULL;
++ }
++ } else {
++ undistort_ = new Grid;
++ undistort_->offset = NULL;
++ }
++
++ if(!undistort_->offset) {
++ undistort_->offset = new Offset[width*height];
++ ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
++ }
++
++ undistort_->width = width;
++ undistort_->height = height;
++}
++
++void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) {
++ CheckDistortLookupGrid(width, height);
+ if(channels==1) Warp<float,1>(distort_,src,dst,width,height);
+ else if(channels==2) Warp<float,2>(distort_,src,dst,width,height);
+ else if(channels==3) Warp<float,3>(distort_,src,dst,width,height);
+@@ -224,10 +316,7 @@ void CameraIntrinsics::Distort(const float* src, float* dst, int width, int heig
+ }
+
+ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
+- if(!distort_) {
+- distort_ = new Offset[width*height];
+- ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height);
+- }
++ CheckDistortLookupGrid(width, height);
+ if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height);
+ else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height);
+ else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height);
+@@ -236,10 +325,7 @@ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int
+ }
+
+ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, int channels) {
+- if(!undistort_) {
+- undistort_ = new Offset[width*height];
+- ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
+- }
++ CheckUndistortLookupGrid(width, height);
+ if(channels==1) Warp<float,1>(undistort_,src,dst,width,height);
+ else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height);
+ else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height);
+@@ -248,10 +334,7 @@ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int he
+ }
+
+ void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) {
+- if(!undistort_) {
+- undistort_ = new Offset[width*height];
+- ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height);
+- }
++ CheckUndistortLookupGrid(width, height);
+ if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height);
+ else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height);
+ else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height);
+diff --git a/src/libmv/simple_pipeline/camera_intrinsics.h b/src/libmv/simple_pipeline/camera_intrinsics.h
+index 29bc8a1..f525571 100644
+--- a/src/libmv/simple_pipeline/camera_intrinsics.h
++++ b/src/libmv/simple_pipeline/camera_intrinsics.h
+@@ -26,11 +26,12 @@ typedef Eigen::Matrix<double, 3, 3> Mat3;
+
+ namespace libmv {
+
+-struct Offset;
++struct Grid;
+
+ class CameraIntrinsics {
+ public:
+ CameraIntrinsics();
++ CameraIntrinsics(const CameraIntrinsics &from);
+ ~CameraIntrinsics();
+
+ const Mat3 &K() const { return K_; }
+@@ -123,7 +124,9 @@ class CameraIntrinsics {
+ int width, int height, int channels);
+
+ private:
+- template<typename WarpFunction> void ComputeLookupGrid(Offset* grid, int width, int height);
++ template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height);
++ void CheckUndistortLookupGrid(int width, int height);
++ void CheckDistortLookupGrid(int width, int height);
+ void FreeLookupGrid();
+
+ // The traditional intrinsics matrix from x = K[R|t]X.
+@@ -140,8 +143,8 @@ class CameraIntrinsics {
+ // independent of image size.
+ double k1_, k2_, k3_, p1_, p2_;
+
+- Offset* distort_;
+- Offset* undistort_;
++ struct Grid *distort_;
++ struct Grid *undistort_;
+ };
+
+ } // namespace libmv
diff --git a/extern/libmv/patches/series b/extern/libmv/patches/series
new file mode 100644
index 00000000000..00a52c1cfaa
--- /dev/null
+++ b/extern/libmv/patches/series
@@ -0,0 +1,13 @@
+v3d_verbosity.patch
+snrptinf_fix.patch
+bundle_tweaks.patch
+fast.patch
+config_mac.patch
+levenberg_marquardt.patch
+function_derivative.patch
+high_distortion_crash_fix.patch
+mingw.patch
+msvc2010.patch
+scaled_distortion.patch
+overscan.patch
+detect.patch
diff --git a/extern/libmv/patches/snrptinf_fix.patch b/extern/libmv/patches/snrptinf_fix.patch
new file mode 100644
index 00000000000..e886a671de0
--- /dev/null
+++ b/extern/libmv/patches/snrptinf_fix.patch
@@ -0,0 +1,15 @@
+diff --git a/src/libmv/simple_pipeline/pipeline.cc b/src/libmv/simple_pipeline/pipeline.cc
+index 652d70c..25cd2c2 100644
+--- a/src/libmv/simple_pipeline/pipeline.cc
++++ b/src/libmv/simple_pipeline/pipeline.cc
+@@ -28,6 +28,10 @@
+ #include "libmv/simple_pipeline/tracks.h"
+ #include "libmv/simple_pipeline/camera_intrinsics.h"
+
++#ifdef _MSC_VER
++# define snprintf _snprintf
++#endif
++
+ namespace libmv {
+
+ void CompleteReconstruction(const Tracks &tracks,
diff --git a/extern/libmv/patches/v3d_verbosity.patch b/extern/libmv/patches/v3d_verbosity.patch
new file mode 100644
index 00000000000..a54f3dc44be
--- /dev/null
+++ b/extern/libmv/patches/v3d_verbosity.patch
@@ -0,0 +1,12 @@
+diff --git a/src/libmv/simple_pipeline/bundle.cc b/src/libmv/simple_pipeline/bundle.cc
+index 310660d..f819603 100644
+--- a/src/libmv/simple_pipeline/bundle.cc
++++ b/src/libmv/simple_pipeline/bundle.cc
+@@ -141,7 +141,6 @@ void Bundle(const Tracks &tracks, Reconstruction *reconstruction) {
+ v3d_distortion.p2 = 0;
+
+ // Finally, run the bundle adjustment.
+- V3D::optimizerVerbosenessLevel = 1;
+ double const inlierThreshold = 500000.0;
+ V3D::CommonInternalsMetricBundleOptimizer opt(V3D::FULL_BUNDLE_METRIC,
+ inlierThreshold,
diff --git a/extern/libmv/third_party/fast/LICENSE b/extern/libmv/third_party/fast/LICENSE
new file mode 100644
index 00000000000..f347008d6ef
--- /dev/null
+++ b/extern/libmv/third_party/fast/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2006, 2008 Edward Rosten
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+
+ *Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ *Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ *Neither the name of the University of Cambridge nor the names of
+ its contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/extern/libmv/third_party/fast/README b/extern/libmv/third_party/fast/README
new file mode 100644
index 00000000000..77017078d08
--- /dev/null
+++ b/extern/libmv/third_party/fast/README
@@ -0,0 +1,31 @@
+FAST feature detectors in C Version 2.0
+---------------------------------------
+
+The files are valid C and C++ code, and have no special requirements for
+compiling, and they do not depend on any libraries. Just compile them along with
+the rest of your project.
+
+To use the functions, #include "fast.h"
+
+The corner detectors have the following prototype (where X is 9, 10, 11 or 12):
+
+xy* fastX_detect_nonmax(const unsigned char * data, int xsize, int ysize, int stride, int threshold, int* numcorners)
+
+Where xy is the following simple struct typedef:
+
+typedef struct
+{
+ int x, y;
+} xy;
+
+The image is passed in as a block of data and dimensions, and the list of
+corners is returned as an array of xy structs, and an integer (numcorners)
+with the number of corners returned. The data can be deallocated with free().
+Nonmaximal suppression is performed on the corners. Note that the stride
+is the number of bytes between rows. If your image has no padding, then this
+is the same as xsize.
+
+The detection, scoring and nonmaximal suppression are available as individual
+functions. To see how to use the individual functions, see fast.c
+
+
diff --git a/extern/libmv/third_party/fast/README.libmv b/extern/libmv/third_party/fast/README.libmv
new file mode 100644
index 00000000000..2110976dd14
--- /dev/null
+++ b/extern/libmv/third_party/fast/README.libmv
@@ -0,0 +1,9 @@
+Project: FAST (FAST Corner Detection)
+URL: http://mi.eng.cam.ac.uk/~er258/work/fast-C-src/
+License: BSD
+Upstream version: 2.1, released 12-Jan-2009
+
+Local modifications:
+- Created CMakeLists.txt for CMake build.
+- Update CMakeLists to be sure that the library is a compatible with C++ linkage.
+- Update CMakeLists to not include fast.h to compile fast library with VS2005.
diff --git a/extern/libmv/third_party/fast/fast.c b/extern/libmv/third_party/fast/fast.c
new file mode 100644
index 00000000000..c675f0af883
--- /dev/null
+++ b/extern/libmv/third_party/fast/fast.c
@@ -0,0 +1,71 @@
+#include <stdlib.h>
+#include "fast.h"
+
+
+xy* fast9_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ xy* corners;
+ int num_corners;
+ int* scores;
+ xy* nonmax;
+
+ corners = fast9_detect(im, xsize, ysize, stride, b, &num_corners);
+ scores = fast9_score(im, stride, corners, num_corners, b);
+ nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);
+
+ free(corners);
+ free(scores);
+
+ return nonmax;
+}
+
+xy* fast10_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ xy* corners;
+ int num_corners;
+ int* scores;
+ xy* nonmax;
+
+ corners = fast10_detect(im, xsize, ysize, stride, b, &num_corners);
+ scores = fast10_score(im, stride, corners, num_corners, b);
+ nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);
+
+ free(corners);
+ free(scores);
+
+ return nonmax;
+}
+
+xy* fast11_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ xy* corners;
+ int num_corners;
+ int* scores;
+ xy* nonmax;
+
+ corners = fast11_detect(im, xsize, ysize, stride, b, &num_corners);
+ scores = fast11_score(im, stride, corners, num_corners, b);
+ nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);
+
+ free(corners);
+ free(scores);
+
+ return nonmax;
+}
+
+xy* fast12_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ xy* corners;
+ int num_corners;
+ int* scores;
+ xy* nonmax;
+
+ corners = fast12_detect(im, xsize, ysize, stride, b, &num_corners);
+ scores = fast12_score(im, stride, corners, num_corners, b);
+ nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners);
+
+ free(corners);
+ free(scores);
+
+ return nonmax;
+}
diff --git a/extern/libmv/third_party/fast/fast.h b/extern/libmv/third_party/fast/fast.h
new file mode 100644
index 00000000000..06fa90ec98c
--- /dev/null
+++ b/extern/libmv/third_party/fast/fast.h
@@ -0,0 +1,39 @@
+#ifndef FAST_H
+#define FAST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct { int x, y; } xy;
+typedef unsigned char byte;
+
+int fast9_corner_score(const byte* p, const int pixel[], int bstart);
+int fast10_corner_score(const byte* p, const int pixel[], int bstart);
+int fast11_corner_score(const byte* p, const int pixel[], int bstart);
+int fast12_corner_score(const byte* p, const int pixel[], int bstart);
+
+xy* fast9_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+xy* fast10_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+xy* fast11_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+xy* fast12_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+
+int* fast9_score(const byte* i, int stride, xy* corners, int num_corners, int b);
+int* fast10_score(const byte* i, int stride, xy* corners, int num_corners, int b);
+int* fast11_score(const byte* i, int stride, xy* corners, int num_corners, int b);
+int* fast12_score(const byte* i, int stride, xy* corners, int num_corners, int b);
+
+
+xy* fast9_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+xy* fast10_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+xy* fast11_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+xy* fast12_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners);
+
+xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/extern/libmv/third_party/fast/fast_10.c b/extern/libmv/third_party/fast/fast_10.c
new file mode 100644
index 00000000000..3af63869478
--- /dev/null
+++ b/extern/libmv/third_party/fast/fast_10.c
@@ -0,0 +1,4666 @@
+/*This is mechanically generated code*/
+#include <stdlib.h>
+
+typedef struct { int x, y; } xy;
+typedef unsigned char byte;
+
+int fast10_corner_score(const byte* p, const int pixel[], int bstart)
+{
+ int bmin = bstart;
+ int bmax = 255;
+ int b = (bmax + bmin)/2;
+
+ /*Compute the score using binary search*/
+ for(;;)
+ {
+ int cb = *p + b;
+ int c_b= *p - b;
+
+
+ if( p[pixel[0]] > cb)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[12]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[15]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[0]] < c_b)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[15]] < c_b)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[1]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[1]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+
+ is_a_corner:
+ bmin=b;
+ goto end_if;
+
+ is_not_a_corner:
+ bmax=b;
+ goto end_if;
+
+ end_if:
+
+ if(bmin == bmax - 1 || bmin == bmax)
+ return bmin;
+ b = (bmin + bmax) / 2;
+ }
+}
+
+static void make_offsets(int pixel[], int row_stride)
+{
+ pixel[0] = 0 + row_stride * 3;
+ pixel[1] = 1 + row_stride * 3;
+ pixel[2] = 2 + row_stride * 2;
+ pixel[3] = 3 + row_stride * 1;
+ pixel[4] = 3 + row_stride * 0;
+ pixel[5] = 3 + row_stride * -1;
+ pixel[6] = 2 + row_stride * -2;
+ pixel[7] = 1 + row_stride * -3;
+ pixel[8] = 0 + row_stride * -3;
+ pixel[9] = -1 + row_stride * -3;
+ pixel[10] = -2 + row_stride * -2;
+ pixel[11] = -3 + row_stride * -1;
+ pixel[12] = -3 + row_stride * 0;
+ pixel[13] = -3 + row_stride * 1;
+ pixel[14] = -2 + row_stride * 2;
+ pixel[15] = -1 + row_stride * 3;
+}
+
+
+
+int* fast10_score(const byte* i, int stride, xy* corners, int num_corners, int b)
+{
+ int* scores = (int*)malloc(sizeof(int)* num_corners);
+ int n;
+
+ int pixel[16];
+ make_offsets(pixel, stride);
+
+ for(n=0; n < num_corners; n++)
+ scores[n] = fast10_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b);
+
+ return scores;
+}
+
+
+xy* fast10_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ int num_corners=0;
+ xy* ret_corners;
+ int rsize=512;
+ int pixel[16];
+ int x, y;
+
+ ret_corners = (xy*)malloc(sizeof(xy)*rsize);
+ make_offsets(pixel, stride);
+
+ for(y=3; y < ysize - 3; y++)
+ for(x=3; x < xsize - 3; x++)
+ {
+ const byte* p = im + y*stride + x;
+
+ int cb = *p + b;
+ int c_b= *p - b;
+ if(p[pixel[0]] > cb)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[12]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[15]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[0]] < c_b)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[15]] < c_b)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[1]] > cb)
+ {}
+ else
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[1]] < c_b)
+ {}
+ else
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ if(num_corners == rsize)
+ {
+ rsize*=2;
+ ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize);
+ }
+
+ ret_corners[num_corners].x = x;
+ ret_corners[num_corners].y = y;
+ num_corners++;
+ }
+
+ *ret_num_corners = num_corners;
+ return ret_corners;
+
+}
+
+
diff --git a/extern/libmv/third_party/fast/fast_11.c b/extern/libmv/third_party/fast/fast_11.c
new file mode 100644
index 00000000000..b4af4309521
--- /dev/null
+++ b/extern/libmv/third_party/fast/fast_11.c
@@ -0,0 +1,3910 @@
+/*This is mechanically generated code*/
+#include <stdlib.h>
+
+typedef struct { int x, y; } xy;
+typedef unsigned char byte;
+
+int fast11_corner_score(const byte* p, const int pixel[], int bstart)
+{
+ int bmin = bstart;
+ int bmax = 255;
+ int b = (bmax + bmin)/2;
+
+ /*Compute the score using binary search*/
+ for(;;)
+ {
+ int cb = *p + b;
+ int c_b= *p - b;
+
+
+ if( p[pixel[0]] > cb)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[15]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[0]] < c_b)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[15]] < c_b)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[1]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[1]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+
+ is_a_corner:
+ bmin=b;
+ goto end_if;
+
+ is_not_a_corner:
+ bmax=b;
+ goto end_if;
+
+ end_if:
+
+ if(bmin == bmax - 1 || bmin == bmax)
+ return bmin;
+ b = (bmin + bmax) / 2;
+ }
+}
+
+static void make_offsets(int pixel[], int row_stride)
+{
+ pixel[0] = 0 + row_stride * 3;
+ pixel[1] = 1 + row_stride * 3;
+ pixel[2] = 2 + row_stride * 2;
+ pixel[3] = 3 + row_stride * 1;
+ pixel[4] = 3 + row_stride * 0;
+ pixel[5] = 3 + row_stride * -1;
+ pixel[6] = 2 + row_stride * -2;
+ pixel[7] = 1 + row_stride * -3;
+ pixel[8] = 0 + row_stride * -3;
+ pixel[9] = -1 + row_stride * -3;
+ pixel[10] = -2 + row_stride * -2;
+ pixel[11] = -3 + row_stride * -1;
+ pixel[12] = -3 + row_stride * 0;
+ pixel[13] = -3 + row_stride * 1;
+ pixel[14] = -2 + row_stride * 2;
+ pixel[15] = -1 + row_stride * 3;
+}
+
+
+
+int* fast11_score(const byte* i, int stride, xy* corners, int num_corners, int b)
+{
+ int* scores = (int*)malloc(sizeof(int)* num_corners);
+ int n;
+
+ int pixel[16];
+ make_offsets(pixel, stride);
+
+ for(n=0; n < num_corners; n++)
+ scores[n] = fast11_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b);
+
+ return scores;
+}
+
+
+xy* fast11_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ int num_corners=0;
+ xy* ret_corners;
+ int rsize=512;
+ int pixel[16];
+ int x, y;
+
+ ret_corners = (xy*)malloc(sizeof(xy)*rsize);
+ make_offsets(pixel, stride);
+
+ for(y=3; y < ysize - 3; y++)
+ for(x=3; x < xsize - 3; x++)
+ {
+ const byte* p = im + y*stride + x;
+
+ int cb = *p + b;
+ int c_b= *p - b;
+ if(p[pixel[0]] > cb)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[15]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[0]] < c_b)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[15]] < c_b)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[1]] > cb)
+ {}
+ else
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[1]] < c_b)
+ {}
+ else
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ if(num_corners == rsize)
+ {
+ rsize*=2;
+ ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize);
+ }
+
+ ret_corners[num_corners].x = x;
+ ret_corners[num_corners].y = y;
+ num_corners++;
+ }
+
+ *ret_num_corners = num_corners;
+ return ret_corners;
+
+}
+
+
diff --git a/extern/libmv/third_party/fast/fast_12.c b/extern/libmv/third_party/fast/fast_12.c
new file mode 100644
index 00000000000..f73f68dd043
--- /dev/null
+++ b/extern/libmv/third_party/fast/fast_12.c
@@ -0,0 +1,3134 @@
+/*This is mechanically generated code*/
+#include <stdlib.h>
+
+typedef struct { int x, y; } xy;
+typedef unsigned char byte;
+
+int fast12_corner_score(const byte* p, const int pixel[], int bstart)
+{
+ int bmin = bstart;
+ int bmax = 255;
+ int b = (bmax + bmin)/2;
+
+ /*Compute the score using binary search*/
+ for(;;)
+ {
+ int cb = *p + b;
+ int c_b= *p - b;
+
+
+ if( p[pixel[0]] > cb)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[15]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[0]] < c_b)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[15]] < c_b)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[1]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[1]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+
+ is_a_corner:
+ bmin=b;
+ goto end_if;
+
+ is_not_a_corner:
+ bmax=b;
+ goto end_if;
+
+ end_if:
+
+ if(bmin == bmax - 1 || bmin == bmax)
+ return bmin;
+ b = (bmin + bmax) / 2;
+ }
+}
+
+static void make_offsets(int pixel[], int row_stride)
+{
+ pixel[0] = 0 + row_stride * 3;
+ pixel[1] = 1 + row_stride * 3;
+ pixel[2] = 2 + row_stride * 2;
+ pixel[3] = 3 + row_stride * 1;
+ pixel[4] = 3 + row_stride * 0;
+ pixel[5] = 3 + row_stride * -1;
+ pixel[6] = 2 + row_stride * -2;
+ pixel[7] = 1 + row_stride * -3;
+ pixel[8] = 0 + row_stride * -3;
+ pixel[9] = -1 + row_stride * -3;
+ pixel[10] = -2 + row_stride * -2;
+ pixel[11] = -3 + row_stride * -1;
+ pixel[12] = -3 + row_stride * 0;
+ pixel[13] = -3 + row_stride * 1;
+ pixel[14] = -2 + row_stride * 2;
+ pixel[15] = -1 + row_stride * 3;
+}
+
+
+
+int* fast12_score(const byte* i, int stride, xy* corners, int num_corners, int b)
+{
+ int* scores = (int*)malloc(sizeof(int)* num_corners);
+ int n;
+
+ int pixel[16];
+ make_offsets(pixel, stride);
+
+ for(n=0; n < num_corners; n++)
+ scores[n] = fast12_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b);
+
+ return scores;
+}
+
+
+xy* fast12_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ int num_corners=0;
+ xy* ret_corners;
+ int rsize=512;
+ int pixel[16];
+ int x, y;
+
+ ret_corners = (xy*)malloc(sizeof(xy)*rsize);
+ make_offsets(pixel, stride);
+
+ for(y=3; y < ysize - 3; y++)
+ for(x=3; x < xsize - 3; x++)
+ {
+ const byte* p = im + y*stride + x;
+
+ int cb = *p + b;
+ int c_b= *p - b;
+ if(p[pixel[0]] > cb)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[15]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[0]] < c_b)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[15]] < c_b)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[1]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[1]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ if(num_corners == rsize)
+ {
+ rsize*=2;
+ ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize);
+ }
+
+ ret_corners[num_corners].x = x;
+ ret_corners[num_corners].y = y;
+ num_corners++;
+ }
+
+ *ret_num_corners = num_corners;
+ return ret_corners;
+
+}
+
+
diff --git a/extern/libmv/third_party/fast/fast_9.c b/extern/libmv/third_party/fast/fast_9.c
new file mode 100644
index 00000000000..6d33daeffbb
--- /dev/null
+++ b/extern/libmv/third_party/fast/fast_9.c
@@ -0,0 +1,5910 @@
+/*This is mechanically generated code*/
+#include <stdlib.h>
+
+typedef struct { int x, y; } xy;
+typedef unsigned char byte;
+
+int fast9_corner_score(const byte* p, const int pixel[], int bstart)
+{
+ int bmin = bstart;
+ int bmax = 255;
+ int b = (bmax + bmin)/2;
+
+ /*Compute the score using binary search*/
+ for(;;)
+ {
+ int cb = *p + b;
+ int c_b= *p - b;
+
+
+ if( p[pixel[0]] > cb)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[15]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[13]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[13]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[12]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[12]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[6]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[13]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[0]] < c_b)
+ if( p[pixel[1]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[1]] < c_b)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[13]] < c_b)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[6]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[15]] < c_b)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[6]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[9]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[8]] > cb)
+ if( p[pixel[7]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[10]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[7]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[7]] > cb)
+ if( p[pixel[8]] > cb)
+ if( p[pixel[9]] > cb)
+ if( p[pixel[6]] > cb)
+ if( p[pixel[5]] > cb)
+ if( p[pixel[4]] > cb)
+ if( p[pixel[3]] > cb)
+ if( p[pixel[2]] > cb)
+ if( p[pixel[1]] > cb)
+ goto is_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] > cb)
+ if( p[pixel[11]] > cb)
+ if( p[pixel[12]] > cb)
+ if( p[pixel[13]] > cb)
+ if( p[pixel[14]] > cb)
+ if( p[pixel[15]] > cb)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else if( p[pixel[7]] < c_b)
+ if( p[pixel[8]] < c_b)
+ if( p[pixel[9]] < c_b)
+ if( p[pixel[6]] < c_b)
+ if( p[pixel[5]] < c_b)
+ if( p[pixel[4]] < c_b)
+ if( p[pixel[3]] < c_b)
+ if( p[pixel[2]] < c_b)
+ if( p[pixel[1]] < c_b)
+ goto is_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ if( p[pixel[10]] < c_b)
+ if( p[pixel[11]] < c_b)
+ if( p[pixel[12]] < c_b)
+ if( p[pixel[13]] < c_b)
+ if( p[pixel[14]] < c_b)
+ if( p[pixel[15]] < c_b)
+ goto is_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+ else
+ goto is_not_a_corner;
+
+ is_a_corner:
+ bmin=b;
+ goto end_if;
+
+ is_not_a_corner:
+ bmax=b;
+ goto end_if;
+
+ end_if:
+
+ if(bmin == bmax - 1 || bmin == bmax)
+ return bmin;
+ b = (bmin + bmax) / 2;
+ }
+}
+
+static void make_offsets(int pixel[], int row_stride)
+{
+ pixel[0] = 0 + row_stride * 3;
+ pixel[1] = 1 + row_stride * 3;
+ pixel[2] = 2 + row_stride * 2;
+ pixel[3] = 3 + row_stride * 1;
+ pixel[4] = 3 + row_stride * 0;
+ pixel[5] = 3 + row_stride * -1;
+ pixel[6] = 2 + row_stride * -2;
+ pixel[7] = 1 + row_stride * -3;
+ pixel[8] = 0 + row_stride * -3;
+ pixel[9] = -1 + row_stride * -3;
+ pixel[10] = -2 + row_stride * -2;
+ pixel[11] = -3 + row_stride * -1;
+ pixel[12] = -3 + row_stride * 0;
+ pixel[13] = -3 + row_stride * 1;
+ pixel[14] = -2 + row_stride * 2;
+ pixel[15] = -1 + row_stride * 3;
+}
+
+
+
+int* fast9_score(const byte* i, int stride, xy* corners, int num_corners, int b)
+{
+ int* scores = (int*)malloc(sizeof(int)* num_corners);
+ int n;
+
+ int pixel[16];
+ make_offsets(pixel, stride);
+
+ for(n=0; n < num_corners; n++)
+ scores[n] = fast9_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b);
+
+ return scores;
+}
+
+
+xy* fast9_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners)
+{
+ int num_corners=0;
+ xy* ret_corners;
+ int rsize=512;
+ int pixel[16];
+ int x, y;
+
+ ret_corners = (xy*)malloc(sizeof(xy)*rsize);
+ make_offsets(pixel, stride);
+
+ for(y=3; y < ysize - 3; y++)
+ for(x=3; x < xsize - 3; x++)
+ {
+ const byte* p = im + y*stride + x;
+
+ int cb = *p + b;
+ int c_b= *p - b;
+ if(p[pixel[0]] > cb)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[15]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else if(p[pixel[13]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[13]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[12]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[12]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[6]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[13]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ {}
+ else
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ {}
+ else
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ {}
+ else
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ {}
+ else
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[0]] < c_b)
+ if(p[pixel[1]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[1]] < c_b)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[13]] < c_b)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[6]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[15]] < c_b)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[6]] > cb)
+ {}
+ else
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ {}
+ else
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ {}
+ else
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[9]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ {}
+ else
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[8]] > cb)
+ if(p[pixel[7]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[10]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ {}
+ else
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[7]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[7]] > cb)
+ if(p[pixel[8]] > cb)
+ if(p[pixel[9]] > cb)
+ if(p[pixel[6]] > cb)
+ if(p[pixel[5]] > cb)
+ if(p[pixel[4]] > cb)
+ if(p[pixel[3]] > cb)
+ if(p[pixel[2]] > cb)
+ if(p[pixel[1]] > cb)
+ {}
+ else
+ if(p[pixel[10]] > cb)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] > cb)
+ if(p[pixel[11]] > cb)
+ if(p[pixel[12]] > cb)
+ if(p[pixel[13]] > cb)
+ if(p[pixel[14]] > cb)
+ if(p[pixel[15]] > cb)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else if(p[pixel[7]] < c_b)
+ if(p[pixel[8]] < c_b)
+ if(p[pixel[9]] < c_b)
+ if(p[pixel[6]] < c_b)
+ if(p[pixel[5]] < c_b)
+ if(p[pixel[4]] < c_b)
+ if(p[pixel[3]] < c_b)
+ if(p[pixel[2]] < c_b)
+ if(p[pixel[1]] < c_b)
+ {}
+ else
+ if(p[pixel[10]] < c_b)
+ {}
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ if(p[pixel[10]] < c_b)
+ if(p[pixel[11]] < c_b)
+ if(p[pixel[12]] < c_b)
+ if(p[pixel[13]] < c_b)
+ if(p[pixel[14]] < c_b)
+ if(p[pixel[15]] < c_b)
+ {}
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ else
+ continue;
+ if(num_corners == rsize)
+ {
+ rsize*=2;
+ ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize);
+ }
+ ret_corners[num_corners].x = x;
+ ret_corners[num_corners].y = y;
+ num_corners++;
+
+ }
+
+ *ret_num_corners = num_corners;
+ return ret_corners;
+
+}
+
+
diff --git a/extern/libmv/third_party/fast/nonmax.c b/extern/libmv/third_party/fast/nonmax.c
new file mode 100644
index 00000000000..6ed0f580906
--- /dev/null
+++ b/extern/libmv/third_party/fast/nonmax.c
@@ -0,0 +1,117 @@
+#include <stdlib.h>
+#include "fast.h"
+
+
+#define Compare(X, Y) ((X)>=(Y))
+
+xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax)
+{
+ int num_nonmax=0;
+ int last_row;
+ int* row_start;
+ int i, j;
+ xy* ret_nonmax;
+ const int sz = (int)num_corners;
+
+ /*Point above points (roughly) to the pixel above the one of interest, if there
+ is a feature there.*/
+ int point_above = 0;
+ int point_below = 0;
+
+
+ if(num_corners < 1)
+ {
+ *ret_num_nonmax = 0;
+ return 0;
+ }
+
+ ret_nonmax = (xy*)malloc(num_corners * sizeof(xy));
+
+ /* Find where each row begins
+ (the corners are output in raster scan order). A beginning of -1 signifies
+ that there are no corners on that row. */
+ last_row = corners[num_corners-1].y;
+ row_start = (int*)malloc((last_row+1)*sizeof(int));
+
+ for(i=0; i < last_row+1; i++)
+ row_start[i] = -1;
+
+ {
+ int prev_row = -1;
+ for(i=0; i< num_corners; i++)
+ if(corners[i].y != prev_row)
+ {
+ row_start[corners[i].y] = i;
+ prev_row = corners[i].y;
+ }
+ }
+
+
+
+ for(i=0; i < sz; i++)
+ {
+ int score = scores[i];
+ xy pos = corners[i];
+
+ /*Check left */
+ if(i > 0)
+ if(corners[i-1].x == pos.x-1 && corners[i-1].y == pos.y && Compare(scores[i-1], score))
+ continue;
+
+ /*Check right*/
+ if(i < (sz - 1))
+ if(corners[i+1].x == pos.x+1 && corners[i+1].y == pos.y && Compare(scores[i+1], score))
+ continue;
+
+ /*Check above (if there is a valid row above)*/
+ if(pos.y != 0 && row_start[pos.y - 1] != -1)
+ {
+ /*Make sure that current point_above is one
+ row above.*/
+ if(corners[point_above].y < pos.y - 1)
+ point_above = row_start[pos.y-1];
+
+ /*Make point_above point to the first of the pixels above the current point,
+ if it exists.*/
+ for(; corners[point_above].y < pos.y && corners[point_above].x < pos.x - 1; point_above++)
+ {}
+
+
+ for(j=point_above; corners[j].y < pos.y && corners[j].x <= pos.x + 1; j++)
+ {
+ int x = corners[j].x;
+ if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Compare(scores[j], score))
+ goto cont;
+ }
+
+ }
+
+ /*Check below (if there is anything below)*/
+ if(pos.y != last_row && row_start[pos.y + 1] != -1 && point_below < sz) /*Nothing below*/
+ {
+ if(corners[point_below].y < pos.y + 1)
+ point_below = row_start[pos.y+1];
+
+ /* Make point below point to one of the pixels belowthe current point, if it
+ exists.*/
+ for(; point_below < sz && corners[point_below].y == pos.y+1 && corners[point_below].x < pos.x - 1; point_below++)
+ {}
+
+ for(j=point_below; j < sz && corners[j].y == pos.y+1 && corners[j].x <= pos.x + 1; j++)
+ {
+ int x = corners[j].x;
+ if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Compare(scores[j],score))
+ goto cont;
+ }
+ }
+
+ ret_nonmax[num_nonmax++] = corners[i];
+ cont:
+ ;
+ }
+
+ free(row_start);
+ *ret_num_nonmax = num_nonmax;
+ return ret_nonmax;
+}
+
diff --git a/extern/libmv/third_party/gflags/README.libmv b/extern/libmv/third_party/gflags/README.libmv
new file mode 100644
index 00000000000..f2bdef6563e
--- /dev/null
+++ b/extern/libmv/third_party/gflags/README.libmv
@@ -0,0 +1,14 @@
+Project: Google Flags
+URL: http://code.google.com/p/google-gflags/
+License: New BSD
+Upstream version: 1.5
+Local modifications:
+
+- Flattened the tree and only included files needed for libmv. This involved
+ changing some of the includes to point to the current directory instead of a
+ nested gflags directory.
+
+- Added a poor-man's version of upstream's port.cc/h to make gflags compile on
+ windows. This isn't sufficient but is a stopgap for now.
+
+ TODO(keir): Import and use gflags for Windows from upstream.
diff --git a/extern/libmv/third_party/gflags/config.h b/extern/libmv/third_party/gflags/config.h
new file mode 100644
index 00000000000..ca2c1276c44
--- /dev/null
+++ b/extern/libmv/third_party/gflags/config.h
@@ -0,0 +1,110 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Always the empty-string on non-windows systems. On windows, should be
+ "__declspec(dllexport)". This way, when we compile the dll, we export our
+ functions/classes. It's safe to define this here because config.h is only
+ used internally, to compile the DLL, and every DLL source file #includes
+ "config.h" before anything else. */
+#define GFLAGS_DLL_DECL /**/
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE ::google
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if you have the `putenv' function. */
+#define HAVE_PUTENV 1
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoq' function. */
+#define HAVE_STRTOQ 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* define if your compiler has __attribute__ */
+#define HAVE___ATTRIBUTE__ 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "gflags"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "opensource@google.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "gflags"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "gflags 1.5"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "gflags"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.5"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* the namespace where STL code like vector<> is defined */
+#define STL_NAMESPACE std
+
+/* Version number of package */
+#define VERSION "1.5"
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
diff --git a/extern/libmv/third_party/gflags/gflags.cc b/extern/libmv/third_party/gflags/gflags.cc
new file mode 100644
index 00000000000..34fe95dac59
--- /dev/null
+++ b/extern/libmv/third_party/gflags/gflags.cc
@@ -0,0 +1,1971 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Ray Sidney
+// Revamped and reorganized by Craig Silverstein
+//
+// This file contains the implementation of all our command line flags
+// stuff. Here's how everything fits together
+//
+// * FlagRegistry owns CommandLineFlags owns FlagValue.
+// * FlagSaver holds a FlagRegistry (saves it at construct time,
+// restores it at destroy time).
+// * CommandLineFlagParser lives outside that hierarchy, but works on
+// CommandLineFlags (modifying the FlagValues).
+// * Free functions like SetCommandLineOption() work via one of the
+// above (such as CommandLineFlagParser).
+//
+// In more detail:
+//
+// -- The main classes that hold flag data:
+//
+// FlagValue holds the current value of a flag. It's
+// pseudo-templatized: every operation on a FlagValue is typed. It
+// also deals with storage-lifetime issues (so flag values don't go
+// away in a destructor), which is why we need a whole class to hold a
+// variable's value.
+//
+// CommandLineFlag is all the information about a single command-line
+// flag. It has a FlagValue for the flag's current value, but also
+// the flag's name, type, etc.
+//
+// FlagRegistry is a collection of CommandLineFlags. There's the
+// global registry, which is where flags defined via DEFINE_foo()
+// live. But it's possible to define your own flag, manually, in a
+// different registry you create. (In practice, multiple registries
+// are used only by FlagSaver).
+//
+// A given FlagValue is owned by exactly one CommandLineFlag. A given
+// CommandLineFlag is owned by exactly one FlagRegistry. FlagRegistry
+// has a lock; any operation that writes to a FlagValue or
+// CommandLineFlag owned by that registry must acquire the
+// FlagRegistry lock before doing so.
+//
+// --- Some other classes and free functions:
+//
+// CommandLineFlagInfo is a client-exposed version of CommandLineFlag.
+// Once it's instantiated, it has no dependencies or relationships
+// with any other part of this file.
+//
+// FlagRegisterer is the helper class used by the DEFINE_* macros to
+// allow work to be done at global initialization time.
+//
+// CommandLineFlagParser is the class that reads from the commandline
+// and instantiates flag values based on that. It needs to poke into
+// the innards of the FlagValue->CommandLineFlag->FlagRegistry class
+// hierarchy to do that. It's careful to acquire the FlagRegistry
+// lock before doing any writing or other non-const actions.
+//
+// GetCommandLineOption is just a hook into registry routines to
+// retrieve a flag based on its name. SetCommandLineOption, on the
+// other hand, hooks into CommandLineFlagParser. Other API functions
+// are, similarly, mostly hooks into the functionality described above.
+
+#include "config.h"
+// This comes first to ensure we define __STDC_FORMAT_MACROS in time.
+#ifdef HAVE_INTTYPES_H
+#ifndef __STDC_FORMAT_MACROS
+# define __STDC_FORMAT_MACROS 1 // gcc requires this to get PRId64, etc.
+#endif
+#include <inttypes.h>
+#endif // HAVE_INTTYPES_H
+#include <stdio.h> // for snprintf
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdarg.h> // For va_list and related operations
+#include <string.h>
+#include <assert.h>
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif // HAVE_FNMATCH_H
+#include <string>
+#include <map>
+#include <vector>
+#include <utility> // for pair<>
+#include <algorithm>
+#include "gflags.h"
+#include "mutex.h"
+
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+// Work properly if either strtoll or strtoq is on this system
+#ifdef HAVE_STRTOLL
+# define strtoint64 strtoll
+# define strtouint64 strtoull
+#elif HAVE_STRTOQ
+# define strtoint64 strtoq
+# define strtouint64 strtouq
+#else
+// Neither strtoll nor strtoq are defined. I hope strtol works!
+# define strtoint64 strtol
+# define strtouint64 strtoul
+#endif
+
+// If we have inttypes.h, it will have defined PRId32/etc for us. If
+// not, take our best guess.
+#ifndef PRId32
+# define PRId32 "d"
+#endif
+#ifndef PRId64
+# define PRId64 "lld"
+#endif
+#ifndef PRIu64
+# define PRIu64 "llu"
+#endif
+
+// Windows is missing random bits like strcasecmp, strtoll, strtoull, and
+// snprintf in the usual locations. Put them somewhere sensible.
+//
+// TODO(keir): Get the upstream Windows port and use that instead.
+#ifdef _MSC_VER
+# define snprintf _snprintf
+# undef strtoint64
+# define strtoint64 _strtoi64
+# undef strtouint64
+# define strtouint64 _strtoui64
+# define strcasecmp _stricmp
+#endif
+
+typedef signed char int8;
+typedef unsigned char uint8;
+
+// Special flags, type 1: the 'recursive' flags. They set another flag's val.
+DEFINE_string(flagfile, "",
+ "load flags from file");
+DEFINE_string(fromenv, "",
+ "set flags from the environment"
+ " [use 'export FLAGS_flag1=value']");
+DEFINE_string(tryfromenv, "",
+ "set flags from the environment if present");
+
+// Special flags, type 2: the 'parsing' flags. They modify how we parse.
+DEFINE_string(undefok, "",
+ "comma-separated list of flag names that it is okay to specify "
+ "on the command line even if the program does not define a flag "
+ "with that name. IMPORTANT: flags in this list that have "
+ "arguments MUST use the flag=value format");
+
+_START_GOOGLE_NAMESPACE_
+
+using std::map;
+using std::pair;
+using std::sort;
+using std::string;
+using std::vector;
+
+// The help message indicating that the commandline flag has been
+// 'stripped'. It will not show up when doing "-help" and its
+// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
+// before including gflags/gflags.h.
+
+// This is used by this file, and also in commandlineflags_reporting.cc
+const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
+
+// This is used by the unittest to test error-exit code
+void GFLAGS_DLL_DECL (*commandlineflags_exitfunc)(int) = &exit; // from stdlib.h
+
+namespace {
+
+// There are also 'reporting' flags, in commandlineflags_reporting.cc.
+
+static const char kError[] = "ERROR: ";
+
+// Indicates that undefined options are to be ignored.
+// Enables deferred processing of flags in dynamically loaded libraries.
+static bool allow_command_line_reparsing = false;
+
+static bool logging_is_probably_set_up = false;
+
+// This is a 'prototype' validate-function. 'Real' validate
+// functions, take a flag-value as an argument: ValidateFn(bool) or
+// ValidateFn(uint64). However, for easier storage, we strip off this
+// argument and then restore it when actually calling the function on
+// a flag value.
+typedef bool (*ValidateFnProto)();
+
+// Whether we should die when reporting an error.
+enum DieWhenReporting { DIE, DO_NOT_DIE };
+
+// Report Error and exit if requested.
+static void ReportError(DieWhenReporting should_die, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ if (should_die == DIE)
+ commandlineflags_exitfunc(1); // almost certainly exit()
+}
+
+
+// --------------------------------------------------------------------
+// FlagValue
+// This represent the value a single flag might have. The major
+// functionality is to convert from a string to an object of a
+// given type, and back. Thread-compatible.
+// --------------------------------------------------------------------
+
+class CommandLineFlag;
+class FlagValue {
+ public:
+ FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value);
+ ~FlagValue();
+
+ bool ParseFrom(const char* spec);
+ string ToString() const;
+
+ private:
+ friend class CommandLineFlag; // for many things, including Validate()
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // calls New()
+ friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map
+ template <typename T> friend T GetFromEnv(const char*, const char*, T);
+ friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
+ const char*, string*); // for New(), CopyFrom()
+
+ enum ValueType {
+ FV_BOOL = 0,
+ FV_INT32 = 1,
+ FV_INT64 = 2,
+ FV_UINT64 = 3,
+ FV_DOUBLE = 4,
+ FV_STRING = 5,
+ FV_MAX_INDEX = 5,
+ };
+ const char* TypeName() const;
+ bool Equal(const FlagValue& x) const;
+ FlagValue* New() const; // creates a new one with default value
+ void CopyFrom(const FlagValue& x);
+ int ValueSize() const;
+
+ // Calls the given validate-fn on value_buffer_, and returns
+ // whatever it returns. But first casts validate_fn_proto to a
+ // function that takes our value as an argument (eg void
+ // (*validate_fn)(bool) for a bool flag).
+ bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
+
+ void* value_buffer_; // points to the buffer holding our data
+ int8 type_; // how to interpret value_
+ bool owns_value_; // whether to free value on destruct
+
+ FlagValue(const FlagValue&); // no copying!
+ void operator=(const FlagValue&);
+};
+
+
+// This could be a templated method of FlagValue, but doing so adds to the
+// size of the .o. Since there's no type-safety here anyway, macro is ok.
+#define VALUE_AS(type) *reinterpret_cast<type*>(value_buffer_)
+#define OTHER_VALUE_AS(fv, type) *reinterpret_cast<type*>(fv.value_buffer_)
+#define SET_VALUE_AS(type, value) VALUE_AS(type) = (value)
+
+FlagValue::FlagValue(void* valbuf, const char* type,
+ bool transfer_ownership_of_value)
+ : value_buffer_(valbuf),
+ owns_value_(transfer_ownership_of_value) {
+ for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
+ if (!strcmp(type, TypeName())) {
+ break;
+ }
+ }
+ assert(type_ <= FV_MAX_INDEX); // Unknown typename
+}
+
+FlagValue::~FlagValue() {
+ if (!owns_value_) {
+ return;
+ }
+ switch (type_) {
+ case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break;
+ case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break;
+ case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break;
+ case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break;
+ case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break;
+ case FV_STRING: delete reinterpret_cast<string*>(value_buffer_); break;
+ }
+}
+
+bool FlagValue::ParseFrom(const char* value) {
+ if (type_ == FV_BOOL) {
+ const char* kTrue[] = { "1", "t", "true", "y", "yes" };
+ const char* kFalse[] = { "0", "f", "false", "n", "no" };
+ for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
+ if (strcasecmp(value, kTrue[i]) == 0) {
+ SET_VALUE_AS(bool, true);
+ return true;
+ } else if (strcasecmp(value, kFalse[i]) == 0) {
+ SET_VALUE_AS(bool, false);
+ return true;
+ }
+ }
+ return false; // didn't match a legal input
+
+ } else if (type_ == FV_STRING) {
+ SET_VALUE_AS(string, value);
+ return true;
+ }
+
+ // OK, it's likely to be numeric, and we'll be using a strtoXXX method.
+ if (value[0] == '\0') // empty-string is only allowed for string type.
+ return false;
+ char* end;
+ // Leading 0x puts us in base 16. But leading 0 does not put us in base 8!
+ // It caused too many bugs when we had that behavior.
+ int base = 10; // by default
+ if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
+ base = 16;
+ errno = 0;
+
+ switch (type_) {
+ case FV_INT32: {
+ const int64 r = strtoint64(value, &end, base);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ if (static_cast<int32>(r) != r) // worked, but number out of range
+ return false;
+ SET_VALUE_AS(int32, static_cast<int32>(r));
+ return true;
+ }
+ case FV_INT64: {
+ const int64 r = strtoint64(value, &end, base);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ SET_VALUE_AS(int64, r);
+ return true;
+ }
+ case FV_UINT64: {
+ while (*value == ' ') value++;
+ if (*value == '-') return false; // negative number
+ const uint64 r = strtouint64(value, &end, base);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ SET_VALUE_AS(uint64, r);
+ return true;
+ }
+ case FV_DOUBLE: {
+ const double r = strtod(value, &end);
+ if (errno || end != value + strlen(value)) return false; // bad parse
+ SET_VALUE_AS(double, r);
+ return true;
+ }
+ default: {
+ assert(false); // unknown type
+ return false;
+ }
+ }
+}
+
+string FlagValue::ToString() const {
+ char intbuf[64]; // enough to hold even the biggest number
+ switch (type_) {
+ case FV_BOOL:
+ return VALUE_AS(bool) ? "true" : "false";
+ case FV_INT32:
+ snprintf(intbuf, sizeof(intbuf), "%"PRId32, VALUE_AS(int32));
+ return intbuf;
+ case FV_INT64:
+ snprintf(intbuf, sizeof(intbuf), "%"PRId64, VALUE_AS(int64));
+ return intbuf;
+ case FV_UINT64:
+ snprintf(intbuf, sizeof(intbuf), "%"PRIu64, VALUE_AS(uint64));
+ return intbuf;
+ case FV_DOUBLE:
+ snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
+ return intbuf;
+ case FV_STRING:
+ return VALUE_AS(string);
+ default:
+ assert(false);
+ return ""; // unknown type
+ }
+}
+
+bool FlagValue::Validate(const char* flagname,
+ ValidateFnProto validate_fn_proto) const {
+ switch (type_) {
+ case FV_BOOL:
+ return reinterpret_cast<bool (*)(const char*, bool)>(
+ validate_fn_proto)(flagname, VALUE_AS(bool));
+ case FV_INT32:
+ return reinterpret_cast<bool (*)(const char*, int32)>(
+ validate_fn_proto)(flagname, VALUE_AS(int32));
+ case FV_INT64:
+ return reinterpret_cast<bool (*)(const char*, int64)>(
+ validate_fn_proto)(flagname, VALUE_AS(int64));
+ case FV_UINT64:
+ return reinterpret_cast<bool (*)(const char*, uint64)>(
+ validate_fn_proto)(flagname, VALUE_AS(uint64));
+ case FV_DOUBLE:
+ return reinterpret_cast<bool (*)(const char*, double)>(
+ validate_fn_proto)(flagname, VALUE_AS(double));
+ case FV_STRING:
+ return reinterpret_cast<bool (*)(const char*, const string&)>(
+ validate_fn_proto)(flagname, VALUE_AS(string));
+ default:
+ assert(false); // unknown type
+ return false;
+ }
+}
+
+const char* FlagValue::TypeName() const {
+ static const char types[] =
+ "bool\0xx"
+ "int32\0x"
+ "int64\0x"
+ "uint64\0"
+ "double\0"
+ "string";
+ if (type_ > FV_MAX_INDEX) {
+ assert(false);
+ return "";
+ }
+ // Directly indexing the strigns in the 'types' string, each of them
+ // is 7 bytes long.
+ return &types[type_ * 7];
+}
+
+bool FlagValue::Equal(const FlagValue& x) const {
+ if (type_ != x.type_)
+ return false;
+ switch (type_) {
+ case FV_BOOL: return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool);
+ case FV_INT32: return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32);
+ case FV_INT64: return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64);
+ case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
+ case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
+ case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string);
+ default: assert(false); return false; // unknown type
+ }
+}
+
+FlagValue* FlagValue::New() const {
+ const char *type = TypeName();
+ switch (type_) {
+ case FV_BOOL: return new FlagValue(new bool(false), type, true);
+ case FV_INT32: return new FlagValue(new int32(0), type, true);
+ case FV_INT64: return new FlagValue(new int64(0), type, true);
+ case FV_UINT64: return new FlagValue(new uint64(0), type, true);
+ case FV_DOUBLE: return new FlagValue(new double(0.0), type, true);
+ case FV_STRING: return new FlagValue(new string, type, true);
+ default: assert(false); return NULL; // unknown type
+ }
+}
+
+void FlagValue::CopyFrom(const FlagValue& x) {
+ assert(type_ == x.type_);
+ switch (type_) {
+ case FV_BOOL: SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool)); break;
+ case FV_INT32: SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32)); break;
+ case FV_INT64: SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64)); break;
+ case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64)); break;
+ case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double)); break;
+ case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string)); break;
+ default: assert(false); // unknown type
+ }
+}
+
+int FlagValue::ValueSize() const {
+ if (type_ > FV_MAX_INDEX) {
+ assert(false); // unknown type
+ return 0;
+ }
+ static const uint8 valuesize[] = {
+ sizeof(bool),
+ sizeof(int32),
+ sizeof(int64),
+ sizeof(uint64),
+ sizeof(double),
+ sizeof(string),
+ };
+ return valuesize[type_];
+}
+
+// --------------------------------------------------------------------
+// CommandLineFlag
+// This represents a single flag, including its name, description,
+// default value, and current value. Mostly this serves as a
+// struct, though it also knows how to register itself.
+// All CommandLineFlags are owned by a (exactly one)
+// FlagRegistry. If you wish to modify fields in this class, you
+// should acquire the FlagRegistry lock for the registry that owns
+// this flag.
+// --------------------------------------------------------------------
+
+class CommandLineFlag {
+ public:
+ // Note: we take over memory-ownership of current_val and default_val.
+ CommandLineFlag(const char* name, const char* help, const char* filename,
+ FlagValue* current_val, FlagValue* default_val);
+ ~CommandLineFlag();
+
+ const char* name() const { return name_; }
+ const char* help() const { return help_; }
+ const char* filename() const { return file_; }
+ const char* CleanFileName() const; // nixes irrelevant prefix such as homedir
+ string current_value() const { return current_->ToString(); }
+ string default_value() const { return defvalue_->ToString(); }
+ const char* type_name() const { return defvalue_->TypeName(); }
+ ValidateFnProto validate_function() const { return validate_fn_proto_; }
+
+ void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
+
+ // If validate_fn_proto_ is non-NULL, calls it on value, returns result.
+ bool Validate(const FlagValue& value) const;
+ bool ValidateCurrent() const { return Validate(*current_); }
+
+ private:
+ // for SetFlagLocked() and setting flags_by_ptr_
+ friend class FlagRegistry;
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // for cloning the values
+ // set validate_fn
+ friend bool AddFlagValidator(const void*, ValidateFnProto);
+
+ // This copies all the non-const members: modified, processed, defvalue, etc.
+ void CopyFrom(const CommandLineFlag& src);
+
+ void UpdateModifiedBit();
+
+ const char* const name_; // Flag name
+ const char* const help_; // Help message
+ const char* const file_; // Which file did this come from?
+ bool modified_; // Set after default assignment?
+ FlagValue* defvalue_; // Default value for flag
+ FlagValue* current_; // Current value for flag
+ // This is a casted, 'generic' version of validate_fn, which actually
+ // takes a flag-value as an arg (void (*validate_fn)(bool), say).
+ // When we pass this to current_->Validate(), it will cast it back to
+ // the proper type. This may be NULL to mean we have no validate_fn.
+ ValidateFnProto validate_fn_proto_;
+
+ CommandLineFlag(const CommandLineFlag&); // no copying!
+ void operator=(const CommandLineFlag&);
+};
+
+CommandLineFlag::CommandLineFlag(const char* name, const char* help,
+ const char* filename,
+ FlagValue* current_val, FlagValue* default_val)
+ : name_(name), help_(help), file_(filename), modified_(false),
+ defvalue_(default_val), current_(current_val), validate_fn_proto_(NULL) {
+}
+
+CommandLineFlag::~CommandLineFlag() {
+ delete current_;
+ delete defvalue_;
+}
+
+const char* CommandLineFlag::CleanFileName() const {
+ // Compute top-level directory & file that this appears in
+ // search full path backwards.
+ // Stop going backwards at kRootDir; and skip by the first slash.
+ static const char kRootDir[] = ""; // can set this to root directory,
+ // e.g. "myproject"
+
+ if (sizeof(kRootDir)-1 == 0) // no prefix to strip
+ return filename();
+
+ const char* clean_name = filename() + strlen(filename()) - 1;
+ while ( clean_name > filename() ) {
+ if (*clean_name == PATH_SEPARATOR) {
+ if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) {
+ // ".../myproject/base/logging.cc" ==> "base/logging.cc"
+ clean_name += sizeof(kRootDir)-1; // past "/myproject/"
+ break;
+ }
+ }
+ --clean_name;
+ }
+ while ( *clean_name == PATH_SEPARATOR ) ++clean_name; // Skip any slashes
+ return clean_name;
+}
+
+void CommandLineFlag::FillCommandLineFlagInfo(
+ CommandLineFlagInfo* result) {
+ result->name = name();
+ result->type = type_name();
+ result->description = help();
+ result->current_value = current_value();
+ result->default_value = default_value();
+ result->filename = CleanFileName();
+ UpdateModifiedBit();
+ result->is_default = !modified_;
+ result->has_validator_fn = validate_function() != NULL;
+}
+
+void CommandLineFlag::UpdateModifiedBit() {
+ // Update the "modified" bit in case somebody bypassed the
+ // Flags API and wrote directly through the FLAGS_name variable.
+ if (!modified_ && !current_->Equal(*defvalue_)) {
+ modified_ = true;
+ }
+}
+
+void CommandLineFlag::CopyFrom(const CommandLineFlag& src) {
+ // Note we only copy the non-const members; others are fixed at construct time
+ if (modified_ != src.modified_) modified_ = src.modified_;
+ if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_);
+ if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_);
+ if (validate_fn_proto_ != src.validate_fn_proto_)
+ validate_fn_proto_ = src.validate_fn_proto_;
+}
+
+bool CommandLineFlag::Validate(const FlagValue& value) const {
+ if (validate_function() == NULL)
+ return true;
+ else
+ return value.Validate(name(), validate_function());
+}
+
+
+// --------------------------------------------------------------------
+// FlagRegistry
+// A FlagRegistry singleton object holds all flag objects indexed
+// by their names so that if you know a flag's name (as a C
+// string), you can access or set it. If the function is named
+// FooLocked(), you must own the registry lock before calling
+// the function; otherwise, you should *not* hold the lock, and
+// the function will acquire it itself if needed.
+// --------------------------------------------------------------------
+
+struct StringCmp { // Used by the FlagRegistry map class to compare char*'s
+ bool operator() (const char* s1, const char* s2) const {
+ return (strcmp(s1, s2) < 0);
+ }
+};
+
+class FlagRegistry {
+ public:
+ FlagRegistry() { }
+ ~FlagRegistry() {
+ for (FlagMap::iterator p = flags_.begin(), e = flags_.end(); p != e; ++p) {
+ CommandLineFlag* flag = p->second;
+ delete flag;
+ }
+ }
+
+ static void DeleteGlobalRegistry() {
+ delete global_registry_;
+ global_registry_ = NULL;
+ }
+
+ void Lock() { lock_.Lock(); }
+ void Unlock() { lock_.Unlock(); }
+
+ // Store a flag in this registry. Takes ownership of the given pointer.
+ void RegisterFlag(CommandLineFlag* flag);
+
+ // Returns the flag object for the specified name, or NULL if not found.
+ CommandLineFlag* FindFlagLocked(const char* name);
+
+ // Returns the flag object whose current-value is stored at flag_ptr.
+ // That is, for whom current_->value_buffer_ == flag_ptr
+ CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr);
+
+ // A fancier form of FindFlag that works correctly if name is of the
+ // form flag=value. In that case, we set key to point to flag, and
+ // modify v to point to the value (if present), and return the flag
+ // with the given name. If the flag does not exist, returns NULL
+ // and sets error_message.
+ CommandLineFlag* SplitArgumentLocked(const char* argument,
+ string* key, const char** v,
+ string* error_message);
+
+ // Set the value of a flag. If the flag was successfully set to
+ // value, set msg to indicate the new flag-value, and return true.
+ // Otherwise, set msg to indicate the error, leave flag unchanged,
+ // and return false. msg can be NULL.
+ bool SetFlagLocked(CommandLineFlag* flag, const char* value,
+ FlagSettingMode set_mode, string* msg);
+
+ static FlagRegistry* GlobalRegistry(); // returns a singleton registry
+
+ private:
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them
+ friend class CommandLineFlagParser; // for ValidateAllFlags
+ friend void GOOGLE_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
+
+ // The map from name to flag, for FindFlagLocked().
+ typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
+ typedef FlagMap::iterator FlagIterator;
+ typedef FlagMap::const_iterator FlagConstIterator;
+ FlagMap flags_;
+
+ // The map from current-value pointer to flag, fo FindFlagViaPtrLocked().
+ typedef map<const void*, CommandLineFlag*> FlagPtrMap;
+ FlagPtrMap flags_by_ptr_;
+
+ Mutex lock_;
+
+ static FlagRegistry* global_registry_; // a singleton registry
+ static Mutex global_registry_lock_; // guards creation of global_registry_
+
+ // Disallow
+ FlagRegistry(const FlagRegistry&);
+ FlagRegistry& operator=(const FlagRegistry&);
+};
+
+FlagRegistry* FlagRegistry::global_registry_ = NULL;
+Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED);
+
+FlagRegistry* FlagRegistry::GlobalRegistry() {
+ MutexLock acquire_lock(&global_registry_lock_);
+ if (!global_registry_) {
+ global_registry_ = new FlagRegistry;
+ }
+ return global_registry_;
+}
+
+void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
+ Lock();
+ pair<FlagIterator, bool> ins =
+ flags_.insert(pair<const char*, CommandLineFlag*>(flag->name(), flag));
+ if (ins.second == false) { // means the name was already in the map
+ if (strcmp(ins.first->second->filename(), flag->filename()) != 0) {
+ ReportError(DIE, "ERROR: flag '%s' was defined more than once "
+ "(in files '%s' and '%s').\n",
+ flag->name(),
+ ins.first->second->filename(),
+ flag->filename());
+ } else {
+ ReportError(DIE, "ERROR: something wrong with flag '%s' in file '%s'. "
+ "One possibility: file '%s' is being linked both statically "
+ "and dynamically into this executable.\n",
+ flag->name(),
+ flag->filename(), flag->filename());
+ }
+ }
+ // Also add to the flags_by_ptr_ map.
+ flags_by_ptr_[flag->current_->value_buffer_] = flag;
+ Unlock();
+}
+
+CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) {
+ FlagConstIterator i = flags_.find(name);
+ if (i == flags_.end()) {
+ return NULL;
+ } else {
+ return i->second;
+ }
+}
+
+CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) {
+ FlagPtrMap::const_iterator i = flags_by_ptr_.find(flag_ptr);
+ if (i == flags_by_ptr_.end()) {
+ return NULL;
+ } else {
+ return i->second;
+ }
+}
+
+CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
+ string* key,
+ const char** v,
+ string* error_message) {
+ // Find the flag object for this option
+ const char* flag_name;
+ const char* value = strchr(arg, '=');
+ if (value == NULL) {
+ key->assign(arg);
+ *v = NULL;
+ } else {
+ // Strip out the "=value" portion from arg
+ key->assign(arg, value-arg);
+ *v = ++value; // advance past the '='
+ }
+ flag_name = key->c_str();
+
+ CommandLineFlag* flag = FindFlagLocked(flag_name);
+
+ if (flag == NULL) {
+ // If we can't find the flag-name, then we should return an error.
+ // The one exception is if 1) the flag-name is 'nox', 2) there
+ // exists a flag named 'x', and 3) 'x' is a boolean flag.
+ // In that case, we want to return flag 'x'.
+ if (!(flag_name[0] == 'n' && flag_name[1] == 'o')) {
+ // flag-name is not 'nox', so we're not in the exception case.
+ *error_message = (string(kError) +
+ "unknown command line flag '" + *key + "'\n");
+ return NULL;
+ }
+ flag = FindFlagLocked(flag_name+2);
+ if (flag == NULL) {
+ // No flag named 'x' exists, so we're not in the exception case.
+ *error_message = (string(kError) +
+ "unknown command line flag '" + *key + "'\n");
+ return NULL;
+ }
+ if (strcmp(flag->type_name(), "bool") != 0) {
+ // 'x' exists but is not boolean, so we're not in the exception case.
+ *error_message = (string(kError) +
+ "boolean value (" + *key + ") specified for " +
+ flag->type_name() + " command line flag\n");
+ return NULL;
+ }
+ // We're in the exception case!
+ // Make up a fake value to replace the "no" we stripped out
+ key->assign(flag_name+2); // the name without the "no"
+ *v = "0";
+ }
+
+ // Assign a value if this is a boolean flag
+ if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) {
+ *v = "1"; // the --nox case was already handled, so this is the --x case
+ }
+
+ return flag;
+}
+
+bool TryParseLocked(const CommandLineFlag* flag, FlagValue* flag_value,
+ const char* value, string* msg) {
+ // Use tenative_value, not flag_value, until we know value is valid.
+ FlagValue* tentative_value = flag_value->New();
+ if (!tentative_value->ParseFrom(value)) {
+ if (msg) {
+ *msg += (string(kError) + "illegal value '" + value +
+ + "' specified for " + flag->type_name() + " flag '"
+ + flag->name() + "'\n");
+ }
+ delete tentative_value;
+ return false;
+ } else if (!flag->Validate(*tentative_value)) {
+ if (msg) {
+ *msg += (string(kError) + "failed validation of new value "
+ + "'" + tentative_value->ToString() + "' for flag '" +
+ + flag->name() + "'\n");
+ }
+ delete tentative_value;
+ return false;
+ } else {
+ flag_value->CopyFrom(*tentative_value);
+ if (msg) {
+ *msg += (string(flag->name()) + " set to " + flag_value->ToString()
+ + "\n");
+ }
+ delete tentative_value;
+ return true;
+ }
+}
+
+bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag,
+ const char* value,
+ FlagSettingMode set_mode,
+ string* msg) {
+ flag->UpdateModifiedBit();
+ switch (set_mode) {
+ case SET_FLAGS_VALUE: {
+ // set or modify the flag's value
+ if (!TryParseLocked(flag, flag->current_, value, msg))
+ return false;
+ flag->modified_ = true;
+ break;
+ }
+ case SET_FLAG_IF_DEFAULT: {
+ // set the flag's value, but only if it hasn't been set by someone else
+ if (!flag->modified_) {
+ if (!TryParseLocked(flag, flag->current_, value, msg))
+ return false;
+ flag->modified_ = true;
+ } else {
+ *msg = string(flag->name()) + " set to " + flag->current_value();
+ }
+ break;
+ }
+ case SET_FLAGS_DEFAULT: {
+ // modify the flag's default-value
+ if (!TryParseLocked(flag, flag->defvalue_, value, msg))
+ return false;
+ if (!flag->modified_) {
+ // Need to set both defvalue *and* current, in this case
+ TryParseLocked(flag, flag->current_, value, NULL);
+ }
+ break;
+ }
+ default: {
+ // unknown set_mode
+ assert(false);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+class FlagRegistryLock {
+ public:
+ explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
+ ~FlagRegistryLock() { fr_->Unlock(); }
+ private:
+ FlagRegistry *const fr_;
+};
+
+// --------------------------------------------------------------------
+// CommandLineFlagParser
+// Parsing is done in two stages. In the first, we go through
+// argv. For every flag-like arg we can make sense of, we parse
+// it and set the appropriate FLAGS_* variable. For every flag-
+// like arg we can't make sense of, we store it in a vector,
+// along with an explanation of the trouble. In stage 2, we
+// handle the 'reporting' flags like --help and --mpm_version.
+// (This is via a call to HandleCommandLineHelpFlags(), in
+// gflags_reporting.cc.)
+// An optional stage 3 prints out the error messages.
+// This is a bit of a simplification. For instance, --flagfile
+// is handled as soon as it's seen in stage 1, not in stage 2.
+// --------------------------------------------------------------------
+
+class CommandLineFlagParser {
+ public:
+ // The argument is the flag-registry to register the parsed flags in
+ explicit CommandLineFlagParser(FlagRegistry* reg) : registry_(reg) {}
+ ~CommandLineFlagParser() {}
+
+ // Stage 1: Every time this is called, it reads all flags in argv.
+ // However, it ignores all flags that have been successfully set
+ // before. Typically this is only called once, so this 'reparsing'
+ // behavior isn't important. It can be useful when trying to
+ // reparse after loading a dll, though.
+ uint32 ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags);
+
+ // Stage 2: print reporting info and exit, if requested.
+ // In gflags_reporting.cc:HandleCommandLineHelpFlags().
+
+ // Stage 3: validate all the commandline flags that have validators
+ // registered.
+ void ValidateAllFlags();
+
+ // Stage 4: report any errors and return true if any were found.
+ bool ReportErrors();
+
+ // Set a particular command line option. "newval" is a string
+ // describing the new value that the option has been set to. If
+ // option_name does not specify a valid option name, or value is not
+ // a valid value for option_name, newval is empty. Does recursive
+ // processing for --flagfile and --fromenv. Returns the new value
+ // if everything went ok, or empty-string if not. (Actually, the
+ // return-string could hold many flag/value pairs due to --flagfile.)
+ // NB: Must have called registry_->Lock() before calling this function.
+ string ProcessSingleOptionLocked(CommandLineFlag* flag,
+ const char* value,
+ FlagSettingMode set_mode);
+
+ // Set a whole batch of command line options as specified by contentdata,
+ // which is in flagfile format (and probably has been read from a flagfile).
+ // Returns the new value if everything went ok, or empty-string if
+ // not. (Actually, the return-string could hold many flag/value
+ // pairs due to --flagfile.)
+ // NB: Must have called registry_->Lock() before calling this function.
+ string ProcessOptionsFromStringLocked(const string& contentdata,
+ FlagSettingMode set_mode);
+
+ // These are the 'recursive' flags, defined at the top of this file.
+ // Whenever we see these flags on the commandline, we must take action.
+ // These are called by ProcessSingleOptionLocked and, similarly, return
+ // new values if everything went ok, or the empty-string if not.
+ string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode);
+ // diff fromenv/tryfromenv
+ string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode,
+ bool errors_are_fatal);
+
+ private:
+ FlagRegistry* const registry_;
+ map<string, string> error_flags_; // map from name to error message
+ // This could be a set<string>, but we reuse the map to minimize the .o size
+ map<string, string> undefined_names_; // --[flag] name was not registered
+};
+
+
+// Parse a list of (comma-separated) flags.
+static void ParseFlagList(const char* value, vector<string>* flags) {
+ for (const char *p = value; p && *p; value = p) {
+ p = strchr(value, ',');
+ int len;
+ if (p) {
+ len = static_cast<int>(p - value);
+ p++;
+ } else {
+ len = static_cast<int>(strlen(value));
+ }
+
+ if (len == 0)
+ ReportError(DIE, "ERROR: empty flaglist entry\n");
+ if (value[0] == '-')
+ ReportError(DIE, "ERROR: flag \"%*s\" begins with '-'\n", len, value);
+
+ flags->push_back(string(value, len));
+ }
+}
+
+// Snarf an entire file into a C++ string. This is just so that we
+// can do all the I/O in one place and not worry about it everywhere.
+// Plus, it's convenient to have the whole file contents at hand.
+// Adds a newline at the end of the file.
+#define PFATAL(s) do { perror(s); commandlineflags_exitfunc(1); } while (0)
+
+static string ReadFileIntoString(const char* filename) {
+ const int kBufSize = 8092;
+ char buffer[kBufSize];
+ string s;
+ FILE* fp = fopen(filename, "r");
+ if (!fp) PFATAL(filename);
+ size_t n;
+ while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
+ if (ferror(fp)) PFATAL(filename);
+ s.append(buffer, n);
+ }
+ fclose(fp);
+ return s;
+}
+
+uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
+ bool remove_flags) {
+ const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR); // nix path
+ program_name = (program_name == NULL ? (*argv)[0] : program_name+1);
+
+ int first_nonopt = *argc; // for non-options moved to the end
+
+ registry_->Lock();
+ for (int i = 1; i < first_nonopt; i++) {
+ char* arg = (*argv)[i];
+
+ // Like getopt(), we permute non-option flags to be at the end.
+ if (arg[0] != '-' || // must be a program argument
+ (arg[0] == '-' && arg[1] == '\0')) { // "-" is an argument, not a flag
+ memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i]));
+ (*argv)[*argc-1] = arg; // we go last
+ first_nonopt--; // we've been pushed onto the stack
+ i--; // to undo the i++ in the loop
+ continue;
+ }
+
+ if (arg[0] == '-') arg++; // allow leading '-'
+ if (arg[0] == '-') arg++; // or leading '--'
+
+ // -- alone means what it does for GNU: stop options parsing
+ if (*arg == '\0') {
+ first_nonopt = i+1;
+ break;
+ }
+
+ // Find the flag object for this option
+ string key;
+ const char* value;
+ string error_message;
+ CommandLineFlag* flag = registry_->SplitArgumentLocked(arg, &key, &value,
+ &error_message);
+ if (flag == NULL) {
+ undefined_names_[key] = ""; // value isn't actually used
+ error_flags_[key] = error_message;
+ continue;
+ }
+
+ if (value == NULL) {
+ // Boolean options are always assigned a value by SplitArgumentLocked()
+ assert(strcmp(flag->type_name(), "bool") != 0);
+ if (i+1 >= first_nonopt) {
+ // This flag needs a value, but there is nothing available
+ error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
+ + " is missing its argument");
+ if (flag->help() && flag->help()[0] > '\001') {
+ // Be useful in case we have a non-stripped description.
+ error_flags_[key] += string("; flag description: ") + flag->help();
+ }
+ error_flags_[key] += "\n";
+ break; // we treat this as an unrecoverable error
+ } else {
+ value = (*argv)[++i]; // read next arg for value
+
+ // Heuristic to detect the case where someone treats a string arg
+ // like a bool:
+ // --my_string_var --foo=bar
+ // We look for a flag of string type, whose value begins with a
+ // dash, and where the flag-name and value are separated by a
+ // space rather than an '='.
+ // To avoid false positives, we also require the word "true"
+ // or "false" in the help string. Without this, a valid usage
+ // "-lat -30.5" would trigger the warning. The common cases we
+ // want to solve talk about true and false as values.
+ if (value[0] == '-'
+ && strcmp(flag->type_name(), "string") == 0
+ && (strstr(flag->help(), "true")
+ || strstr(flag->help(), "false"))) {
+ fprintf(stderr, "Did you really mean to set flag '%s'"
+ " to the value '%s'?\n",
+ flag->name(), value);
+ }
+ }
+ }
+
+ // TODO(csilvers): only set a flag if we hadn't set it before here
+ ProcessSingleOptionLocked(flag, value, SET_FLAGS_VALUE);
+ }
+ registry_->Unlock();
+
+ if (remove_flags) { // Fix up argc and argv by removing command line flags
+ (*argv)[first_nonopt-1] = (*argv)[0];
+ (*argv) += (first_nonopt-1);
+ (*argc) -= (first_nonopt-1);
+ first_nonopt = 1; // because we still don't count argv[0]
+ }
+
+ logging_is_probably_set_up = true; // because we've parsed --logdir, etc.
+
+ return first_nonopt;
+}
+
+string CommandLineFlagParser::ProcessFlagfileLocked(const string& flagval,
+ FlagSettingMode set_mode) {
+ if (flagval.empty())
+ return "";
+
+ string msg;
+ vector<string> filename_list;
+ ParseFlagList(flagval.c_str(), &filename_list); // take a list of filenames
+ for (size_t i = 0; i < filename_list.size(); ++i) {
+ const char* file = filename_list[i].c_str();
+ msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode);
+ }
+ return msg;
+}
+
+string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
+ FlagSettingMode set_mode,
+ bool errors_are_fatal) {
+ if (flagval.empty())
+ return "";
+
+ string msg;
+ vector<string> flaglist;
+ ParseFlagList(flagval.c_str(), &flaglist);
+
+ for (size_t i = 0; i < flaglist.size(); ++i) {
+ const char* flagname = flaglist[i].c_str();
+ CommandLineFlag* flag = registry_->FindFlagLocked(flagname);
+ if (flag == NULL) {
+ error_flags_[flagname] = (string(kError) + "unknown command line flag"
+ + " '" + flagname + "'"
+ + " (via --fromenv or --tryfromenv)\n");
+ undefined_names_[flagname] = "";
+ continue;
+ }
+
+ const string envname = string("FLAGS_") + string(flagname);
+ const char* envval = getenv(envname.c_str());
+ if (!envval) {
+ if (errors_are_fatal) {
+ error_flags_[flagname] = (string(kError) + envname +
+ " not found in environment\n");
+ }
+ continue;
+ }
+
+ // Avoid infinite recursion.
+ if ((strcmp(envval, "fromenv") == 0) ||
+ (strcmp(envval, "tryfromenv") == 0)) {
+ error_flags_[flagname] = (string(kError) + "infinite recursion on " +
+ "environment flag '" + envval + "'\n");
+ continue;
+ }
+
+ msg += ProcessSingleOptionLocked(flag, envval, set_mode);
+ }
+ return msg;
+}
+
+string CommandLineFlagParser::ProcessSingleOptionLocked(
+ CommandLineFlag* flag, const char* value, FlagSettingMode set_mode) {
+ string msg;
+ if (value && !registry_->SetFlagLocked(flag, value, set_mode, &msg)) {
+ error_flags_[flag->name()] = msg;
+ return "";
+ }
+
+ // The recursive flags, --flagfile and --fromenv and --tryfromenv,
+ // must be dealt with as soon as they're seen. They will emit
+ // messages of their own.
+ if (strcmp(flag->name(), "flagfile") == 0) {
+ msg += ProcessFlagfileLocked(FLAGS_flagfile, set_mode);
+
+ } else if (strcmp(flag->name(), "fromenv") == 0) {
+ // last arg indicates envval-not-found is fatal (unlike in --tryfromenv)
+ msg += ProcessFromenvLocked(FLAGS_fromenv, set_mode, true);
+
+ } else if (strcmp(flag->name(), "tryfromenv") == 0) {
+ msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false);
+ }
+
+ return msg;
+}
+
+void CommandLineFlagParser::ValidateAllFlags() {
+ FlagRegistryLock frl(registry_);
+ for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin();
+ i != registry_->flags_.end(); ++i) {
+ if (!i->second->ValidateCurrent()) {
+ // only set a message if one isn't already there. (If there's
+ // an error message, our job is done, even if it's not exactly
+ // the same error.)
+ if (error_flags_[i->second->name()].empty())
+ error_flags_[i->second->name()] =
+ string(kError) + "--" + i->second->name() +
+ " must be set on the commandline"
+ " (default value fails validation)\n";
+ }
+ }
+}
+
+bool CommandLineFlagParser::ReportErrors() {
+ // error_flags_ indicates errors we saw while parsing.
+ // But we ignore undefined-names if ok'ed by --undef_ok
+ if (!FLAGS_undefok.empty()) {
+ vector<string> flaglist;
+ ParseFlagList(FLAGS_undefok.c_str(), &flaglist);
+ for (size_t i = 0; i < flaglist.size(); ++i) {
+ // We also deal with --no<flag>, in case the flagname was boolean
+ const string no_version = string("no") + flaglist[i];
+ if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) {
+ error_flags_[flaglist[i]] = ""; // clear the error message
+ } else if (undefined_names_.find(no_version) != undefined_names_.end()) {
+ error_flags_[no_version] = "";
+ }
+ }
+ }
+ // Likewise, if they decided to allow reparsing, all undefined-names
+ // are ok; we just silently ignore them now, and hope that a future
+ // parse will pick them up somehow.
+ if (allow_command_line_reparsing) {
+ for (map<string, string>::const_iterator it = undefined_names_.begin();
+ it != undefined_names_.end(); ++it)
+ error_flags_[it->first] = ""; // clear the error message
+ }
+
+ bool found_error = false;
+ string error_message;
+ for (map<string, string>::const_iterator it = error_flags_.begin();
+ it != error_flags_.end(); ++it) {
+ if (!it->second.empty()) {
+ error_message.append(it->second.data(), it->second.size());
+ found_error = true;
+ }
+ }
+ if (found_error)
+ ReportError(DO_NOT_DIE, "%s", error_message.c_str());
+ return found_error;
+}
+
+string CommandLineFlagParser::ProcessOptionsFromStringLocked(
+ const string& contentdata, FlagSettingMode set_mode) {
+ string retval;
+ const char* flagfile_contents = contentdata.c_str();
+ bool flags_are_relevant = true; // set to false when filenames don't match
+ bool in_filename_section = false;
+
+ const char* line_end = flagfile_contents;
+ // We read this file a line at a time.
+ for (; line_end; flagfile_contents = line_end + 1) {
+ while (*flagfile_contents && isspace(*flagfile_contents))
+ ++flagfile_contents;
+ line_end = strchr(flagfile_contents, '\n');
+ size_t len = line_end ? static_cast<size_t>(line_end - flagfile_contents)
+ : strlen(flagfile_contents);
+ string line(flagfile_contents, len);
+
+ // Each line can be one of four things:
+ // 1) A comment line -- we skip it
+ // 2) An empty line -- we skip it
+ // 3) A list of filenames -- starts a new filenames+flags section
+ // 4) A --flag=value line -- apply if previous filenames match
+ if (line.empty() || line[0] == '#') {
+ // comment or empty line; just ignore
+
+ } else if (line[0] == '-') { // flag
+ in_filename_section = false; // instead, it was a flag-line
+ if (!flags_are_relevant) // skip this flag; applies to someone else
+ continue;
+
+ const char* name_and_val = line.c_str() + 1; // skip the leading -
+ if (*name_and_val == '-')
+ name_and_val++; // skip second - too
+ string key;
+ const char* value;
+ string error_message;
+ CommandLineFlag* flag = registry_->SplitArgumentLocked(name_and_val,
+ &key, &value,
+ &error_message);
+ // By API, errors parsing flagfile lines are silently ignored.
+ if (flag == NULL) {
+ // "WARNING: flagname '" + key + "' not found\n"
+ } else if (value == NULL) {
+ // "WARNING: flagname '" + key + "' missing a value\n"
+ } else {
+ retval += ProcessSingleOptionLocked(flag, value, set_mode);
+ }
+
+ } else { // a filename!
+ if (!in_filename_section) { // start over: assume filenames don't match
+ in_filename_section = true;
+ flags_are_relevant = false;
+ }
+
+ // Split the line up at spaces into glob-patterns
+ const char* space = line.c_str(); // just has to be non-NULL
+ for (const char* word = line.c_str(); *space; word = space+1) {
+ if (flags_are_relevant) // we can stop as soon as we match
+ break;
+ space = strchr(word, ' ');
+ if (space == NULL)
+ space = word + strlen(word);
+ const string glob(word, space - word);
+ // We try matching both against the full argv0 and basename(argv0)
+#ifdef HAVE_FNMATCH_H
+ if (fnmatch(glob.c_str(),
+ ProgramInvocationName(),
+ FNM_PATHNAME) == 0 ||
+ fnmatch(glob.c_str(),
+ ProgramInvocationShortName(),
+ FNM_PATHNAME) == 0) {
+#else // !HAVE_FNMATCH_H
+ if ((glob == ProgramInvocationName()) ||
+ (glob == ProgramInvocationShortName())) {
+#endif // HAVE_FNMATCH_H
+ flags_are_relevant = true;
+ }
+ }
+ }
+ }
+ return retval;
+}
+
+// --------------------------------------------------------------------
+// GetFromEnv()
+// AddFlagValidator()
+// These are helper functions for routines like BoolFromEnv() and
+// RegisterFlagValidator, defined below. They're defined here so
+// they can live in the unnamed namespace (which makes friendship
+// declarations for these classes possible).
+// --------------------------------------------------------------------
+
+template<typename T>
+T GetFromEnv(const char *varname, const char* type, T dflt) {
+ const char* const valstr = getenv(varname);
+ if (!valstr)
+ return dflt;
+ FlagValue ifv(new T, type, true);
+ if (!ifv.ParseFrom(valstr))
+ ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
+ varname, valstr);
+ return OTHER_VALUE_AS(ifv, T);
+}
+
+bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
+ // We want a lock around this routine, in case two threads try to
+ // add a validator (hopefully the same one!) at once. We could use
+ // our own thread, but we need to loook at the registry anyway, so
+ // we just steal that one.
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ // First, find the flag whose current-flag storage is 'flag'.
+ // This is the CommandLineFlag whose current_->value_buffer_ == flag
+ CommandLineFlag* flag = registry->FindFlagViaPtrLocked(flag_ptr);
+ if (!flag) {
+ // WARNING << "Ignoring RegisterValidateFunction() for flag pointer "
+ // << flag_ptr << ": no flag found at that address";
+ return false;
+ } else if (validate_fn_proto == flag->validate_function()) {
+ return true; // ok to register the same function over and over again
+ } else if (validate_fn_proto != NULL && flag->validate_function() != NULL) {
+ // WARNING << "Ignoring RegisterValidateFunction() for flag '"
+ // << flag->name() << "': validate-fn already registered";
+ return false;
+ } else {
+ flag->validate_fn_proto_ = validate_fn_proto;
+ return true;
+ }
+}
+
+} // end unnamed namespaces
+
+
+// Now define the functions that are exported via the .h file
+
+// --------------------------------------------------------------------
+// FlagRegisterer
+// This class exists merely to have a global constructor (the
+// kind that runs before main(), that goes an initializes each
+// flag that's been declared. Note that it's very important we
+// don't have a destructor that deletes flag_, because that would
+// cause us to delete current_storage/defvalue_storage as well,
+// which can cause a crash if anything tries to access the flag
+// values in a global destructor.
+// --------------------------------------------------------------------
+
+FlagRegisterer::FlagRegisterer(const char* name, const char* type,
+ const char* help, const char* filename,
+ void* current_storage, void* defvalue_storage) {
+ if (help == NULL)
+ help = "";
+ // FlagValue expects the type-name to not include any namespace
+ // components, so we get rid of those, if any.
+ if (strchr(type, ':'))
+ type = strrchr(type, ':') + 1;
+ FlagValue* current = new FlagValue(current_storage, type, false);
+ FlagValue* defvalue = new FlagValue(defvalue_storage, type, false);
+ // Importantly, flag_ will never be deleted, so storage is always good.
+ CommandLineFlag* flag = new CommandLineFlag(name, help, filename,
+ current, defvalue);
+ FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry
+}
+
+// --------------------------------------------------------------------
+// GetAllFlags()
+// The main way the FlagRegistry class exposes its data. This
+// returns, as strings, all the info about all the flags in
+// the main registry, sorted first by filename they are defined
+// in, and then by flagname.
+// --------------------------------------------------------------------
+
+struct FilenameFlagnameCmp {
+ bool operator()(const CommandLineFlagInfo& a,
+ const CommandLineFlagInfo& b) const {
+ int cmp = strcmp(a.filename.c_str(), b.filename.c_str());
+ if (cmp == 0)
+ cmp = strcmp(a.name.c_str(), b.name.c_str()); // secondary sort key
+ return cmp < 0;
+ }
+};
+
+void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) {
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ registry->Lock();
+ for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
+ i != registry->flags_.end(); ++i) {
+ CommandLineFlagInfo fi;
+ i->second->FillCommandLineFlagInfo(&fi);
+ OUTPUT->push_back(fi);
+ }
+ registry->Unlock();
+ // Now sort the flags, first by filename they occur in, then alphabetically
+ sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameCmp());
+}
+
+// --------------------------------------------------------------------
+// SetArgv()
+// GetArgvs()
+// GetArgv()
+// GetArgv0()
+// ProgramInvocationName()
+// ProgramInvocationShortName()
+// SetUsageMessage()
+// ProgramUsage()
+// Functions to set and get argv. Typically the setter is called
+// by ParseCommandLineFlags. Also can get the ProgramUsage string,
+// set by SetUsageMessage.
+// --------------------------------------------------------------------
+
+// These values are not protected by a Mutex because they are normally
+// set only once during program startup.
+static const char* argv0 = "UNKNOWN"; // just the program name
+static const char* cmdline = ""; // the entire command-line
+static vector<string> argvs;
+static uint32 argv_sum = 0;
+static const char* program_usage = NULL;
+
+void SetArgv(int argc, const char** argv) {
+ static bool called_set_argv = false;
+ if (called_set_argv) // we already have an argv for you
+ return;
+
+ called_set_argv = true;
+
+ assert(argc > 0); // every program has at least a progname
+ argv0 = strdup(argv[0]); // small memory leak, but fn only called once
+ assert(argv0);
+
+ string cmdline_string; // easier than doing strcats
+ for (int i = 0; i < argc; i++) {
+ if (i != 0) {
+ cmdline_string += " ";
+ }
+ cmdline_string += argv[i];
+ argvs.push_back(argv[i]);
+ }
+ cmdline = strdup(cmdline_string.c_str()); // another small memory leak
+ assert(cmdline);
+
+ // Compute a simple sum of all the chars in argv
+ for (const char* c = cmdline; *c; c++)
+ argv_sum += *c;
+}
+
+const vector<string>& GetArgvs() { return argvs; }
+const char* GetArgv() { return cmdline; }
+const char* GetArgv0() { return argv0; }
+uint32 GetArgvSum() { return argv_sum; }
+const char* ProgramInvocationName() { // like the GNU libc fn
+ return GetArgv0();
+}
+const char* ProgramInvocationShortName() { // like the GNU libc fn
+ const char* slash = strrchr(argv0, '/');
+#ifdef OS_WINDOWS
+ if (!slash) slash = strrchr(argv0, '\\');
+#endif
+ return slash ? slash + 1 : argv0;
+}
+
+void SetUsageMessage(const string& usage) {
+ if (program_usage != NULL)
+ ReportError(DIE, "ERROR: SetUsageMessage() called twice\n");
+ program_usage = strdup(usage.c_str()); // small memory leak
+}
+
+const char* ProgramUsage() {
+ if (program_usage) {
+ return program_usage;
+ }
+ return "Warning: SetUsageMessage() never called";
+}
+
+// --------------------------------------------------------------------
+// GetCommandLineOption()
+// GetCommandLineFlagInfo()
+// GetCommandLineFlagInfoOrDie()
+// SetCommandLineOption()
+// SetCommandLineOptionWithMode()
+// The programmatic way to set a flag's value, using a string
+// for its name rather than the variable itself (that is,
+// SetCommandLineOption("foo", x) rather than FLAGS_foo = x).
+// There's also a bit more flexibility here due to the various
+// set-modes, but typically these are used when you only have
+// that flag's name as a string, perhaps at runtime.
+// All of these work on the default, global registry.
+// For GetCommandLineOption, return false if no such flag
+// is known, true otherwise. We clear "value" if a suitable
+// flag is found.
+// --------------------------------------------------------------------
+
+
+bool GetCommandLineOption(const char* name, string* value) {
+ if (NULL == name)
+ return false;
+ assert(value);
+
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ CommandLineFlag* flag = registry->FindFlagLocked(name);
+ if (flag == NULL) {
+ return false;
+ } else {
+ *value = flag->current_value();
+ return true;
+ }
+}
+
+bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT) {
+ if (NULL == name) return false;
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ CommandLineFlag* flag = registry->FindFlagLocked(name);
+ if (flag == NULL) {
+ return false;
+ } else {
+ assert(OUTPUT);
+ flag->FillCommandLineFlagInfo(OUTPUT);
+ return true;
+ }
+}
+
+CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) {
+ CommandLineFlagInfo info;
+ if (!GetCommandLineFlagInfo(name, &info)) {
+ fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exist\n", name);
+ commandlineflags_exitfunc(1); // almost certainly exit()
+ }
+ return info;
+}
+
+string SetCommandLineOptionWithMode(const char* name, const char* value,
+ FlagSettingMode set_mode) {
+ string result;
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagRegistryLock frl(registry);
+ CommandLineFlag* flag = registry->FindFlagLocked(name);
+ if (flag) {
+ CommandLineFlagParser parser(registry);
+ result = parser.ProcessSingleOptionLocked(flag, value, set_mode);
+ if (!result.empty()) { // in the error case, we've already logged
+ // You could consider logging this change, if you wanted to know it:
+ //fprintf(stderr, "%sFLAGS_%s\n",
+ // (set_mode == SET_FLAGS_DEFAULT ? "default value of " : ""),
+ // result);
+ }
+ }
+ // The API of this function is that we return empty string on error
+ return result;
+}
+
+string SetCommandLineOption(const char* name, const char* value) {
+ return SetCommandLineOptionWithMode(name, value, SET_FLAGS_VALUE);
+}
+
+// --------------------------------------------------------------------
+// FlagSaver
+// FlagSaverImpl
+// This class stores the states of all flags at construct time,
+// and restores all flags to that state at destruct time.
+// Its major implementation challenge is that it never modifies
+// pointers in the 'main' registry, so global FLAG_* vars always
+// point to the right place.
+// --------------------------------------------------------------------
+
+class FlagSaverImpl {
+ public:
+ // Constructs an empty FlagSaverImpl object.
+ explicit FlagSaverImpl(FlagRegistry* main_registry)
+ : main_registry_(main_registry) { }
+ ~FlagSaverImpl() {
+ // reclaim memory from each of our CommandLineFlags
+ vector<CommandLineFlag*>::const_iterator it;
+ for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it)
+ delete *it;
+ }
+
+ // Saves the flag states from the flag registry into this object.
+ // It's an error to call this more than once.
+ // Must be called when the registry mutex is not held.
+ void SaveFromRegistry() {
+ FlagRegistryLock frl(main_registry_);
+ assert(backup_registry_.empty()); // call only once!
+ for (FlagRegistry::FlagConstIterator it = main_registry_->flags_.begin();
+ it != main_registry_->flags_.end();
+ ++it) {
+ const CommandLineFlag* main = it->second;
+ // Sets up all the const variables in backup correctly
+ CommandLineFlag* backup = new CommandLineFlag(
+ main->name(), main->help(), main->filename(),
+ main->current_->New(), main->defvalue_->New());
+ // Sets up all the non-const variables in backup correctly
+ backup->CopyFrom(*main);
+ backup_registry_.push_back(backup); // add it to a convenient list
+ }
+ }
+
+ // Restores the saved flag states into the flag registry. We
+ // assume no flags were added or deleted from the registry since
+ // the SaveFromRegistry; if they were, that's trouble! Must be
+ // called when the registry mutex is not held.
+ void RestoreToRegistry() {
+ FlagRegistryLock frl(main_registry_);
+ vector<CommandLineFlag*>::const_iterator it;
+ for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) {
+ CommandLineFlag* main = main_registry_->FindFlagLocked((*it)->name());
+ if (main != NULL) { // if NULL, flag got deleted from registry(!)
+ main->CopyFrom(**it);
+ }
+ }
+ }
+
+ private:
+ FlagRegistry* const main_registry_;
+ vector<CommandLineFlag*> backup_registry_;
+
+ FlagSaverImpl(const FlagSaverImpl&); // no copying!
+ void operator=(const FlagSaverImpl&);
+};
+
+FlagSaver::FlagSaver()
+ : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
+ impl_->SaveFromRegistry();
+}
+
+FlagSaver::~FlagSaver() {
+ impl_->RestoreToRegistry();
+ delete impl_;
+}
+
+
+// --------------------------------------------------------------------
+// CommandlineFlagsIntoString()
+// ReadFlagsFromString()
+// AppendFlagsIntoFile()
+// ReadFromFlagsFile()
+// These are mostly-deprecated routines that stick the
+// commandline flags into a file/string and read them back
+// out again. I can see a use for CommandlineFlagsIntoString,
+// for creating a flagfile, but the rest don't seem that useful
+// -- some, I think, are a poor-man's attempt at FlagSaver --
+// and are included only until we can delete them from callers.
+// Note they don't save --flagfile flags (though they do save
+// the result of having called the flagfile, of course).
+// --------------------------------------------------------------------
+
+static string TheseCommandlineFlagsIntoString(
+ const vector<CommandLineFlagInfo>& flags) {
+ vector<CommandLineFlagInfo>::const_iterator i;
+
+ size_t retval_space = 0;
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ // An (over)estimate of how much space it will take to print this flag
+ retval_space += i->name.length() + i->current_value.length() + 5;
+ }
+
+ string retval;
+ retval.reserve(retval_space);
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ retval += "--";
+ retval += i->name;
+ retval += "=";
+ retval += i->current_value;
+ retval += "\n";
+ }
+ return retval;
+}
+
+string CommandlineFlagsIntoString() {
+ vector<CommandLineFlagInfo> sorted_flags;
+ GetAllFlags(&sorted_flags);
+ return TheseCommandlineFlagsIntoString(sorted_flags);
+}
+
+bool ReadFlagsFromString(const string& flagfilecontents,
+ const char* /*prog_name*/, // TODO(csilvers): nix this
+ bool errors_are_fatal) {
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ FlagSaverImpl saved_states(registry);
+ saved_states.SaveFromRegistry();
+
+ CommandLineFlagParser parser(registry);
+ registry->Lock();
+ parser.ProcessOptionsFromStringLocked(flagfilecontents, SET_FLAGS_VALUE);
+ registry->Unlock();
+ // Should we handle --help and such when reading flags from a string? Sure.
+ HandleCommandLineHelpFlags();
+ if (parser.ReportErrors()) {
+ // Error. Restore all global flags to their previous values.
+ if (errors_are_fatal)
+ commandlineflags_exitfunc(1); // almost certainly exit()
+ saved_states.RestoreToRegistry();
+ return false;
+ }
+ return true;
+}
+
+// TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
+bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
+ FILE *fp = fopen(filename.c_str(), "a");
+ if (!fp) {
+ return false;
+ }
+
+ if (prog_name)
+ fprintf(fp, "%s\n", prog_name);
+
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags);
+ // But we don't want --flagfile, which leads to weird recursion issues
+ vector<CommandLineFlagInfo>::iterator i;
+ for (i = flags.begin(); i != flags.end(); ++i) {
+ if (strcmp(i->name.c_str(), "flagfile") == 0) {
+ flags.erase(i);
+ break;
+ }
+ }
+ fprintf(fp, "%s", TheseCommandlineFlagsIntoString(flags).c_str());
+
+ fclose(fp);
+ return true;
+}
+
+bool ReadFromFlagsFile(const string& filename, const char* prog_name,
+ bool errors_are_fatal) {
+ return ReadFlagsFromString(ReadFileIntoString(filename.c_str()),
+ prog_name, errors_are_fatal);
+}
+
+
+// --------------------------------------------------------------------
+// BoolFromEnv()
+// Int32FromEnv()
+// Int64FromEnv()
+// Uint64FromEnv()
+// DoubleFromEnv()
+// StringFromEnv()
+// Reads the value from the environment and returns it.
+// We use an FlagValue to make the parsing easy.
+// Example usage:
+// DEFINE_bool(myflag, BoolFromEnv("MYFLAG_DEFAULT", false), "whatever");
+// --------------------------------------------------------------------
+
+bool BoolFromEnv(const char *v, bool dflt) {
+ return GetFromEnv(v, "bool", dflt);
+}
+int32 Int32FromEnv(const char *v, int32 dflt) {
+ return GetFromEnv(v, "int32", dflt);
+}
+int64 Int64FromEnv(const char *v, int64 dflt) {
+ return GetFromEnv(v, "int64", dflt);
+}
+uint64 Uint64FromEnv(const char *v, uint64 dflt) {
+ return GetFromEnv(v, "uint64", dflt);
+}
+double DoubleFromEnv(const char *v, double dflt) {
+ return GetFromEnv(v, "double", dflt);
+}
+const char *StringFromEnv(const char *varname, const char *dflt) {
+ const char* const val = getenv(varname);
+ return val ? val : dflt;
+}
+
+
+// --------------------------------------------------------------------
+// RegisterFlagValidator()
+// RegisterFlagValidator() is the function that clients use to
+// 'decorate' a flag with a validation function. Once this is
+// done, every time the flag is set (including when the flag
+// is parsed from argv), the validator-function is called.
+// These functions return true if the validator was added
+// successfully, or false if not: the flag already has a validator,
+// (only one allowed per flag), the 1st arg isn't a flag, etc.
+// This function is not thread-safe.
+// --------------------------------------------------------------------
+
+bool RegisterFlagValidator(const bool* flag,
+ bool (*validate_fn)(const char*, bool)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const int32* flag,
+ bool (*validate_fn)(const char*, int32)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const int64* flag,
+ bool (*validate_fn)(const char*, int64)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const uint64* flag,
+ bool (*validate_fn)(const char*, uint64)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const double* flag,
+ bool (*validate_fn)(const char*, double)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const string* flag,
+ bool (*validate_fn)(const char*, const string&)) {
+ return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+
+
+// --------------------------------------------------------------------
+// ParseCommandLineFlags()
+// ParseCommandLineNonHelpFlags()
+// HandleCommandLineHelpFlags()
+// This is the main function called from main(), to actually
+// parse the commandline. It modifies argc and argv as described
+// at the top of gflags.h. You can also divide this
+// function into two parts, if you want to do work between
+// the parsing of the flags and the printing of any help output.
+// --------------------------------------------------------------------
+
+static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv,
+ bool remove_flags, bool do_report) {
+ SetArgv(*argc, const_cast<const char**>(*argv)); // save it for later
+
+ FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+ CommandLineFlagParser parser(registry);
+
+ // When we parse the commandline flags, we'll handle --flagfile,
+ // --tryfromenv, etc. as we see them (since flag-evaluation order
+ // may be important). But sometimes apps set FLAGS_tryfromenv/etc.
+ // manually before calling ParseCommandLineFlags. We want to evaluate
+ // those too, as if they were the first flags on the commandline.
+ registry->Lock();
+ parser.ProcessFlagfileLocked(FLAGS_flagfile, SET_FLAGS_VALUE);
+ // Last arg here indicates whether flag-not-found is a fatal error or not
+ parser.ProcessFromenvLocked(FLAGS_fromenv, SET_FLAGS_VALUE, true);
+ parser.ProcessFromenvLocked(FLAGS_tryfromenv, SET_FLAGS_VALUE, false);
+ registry->Unlock();
+
+ // Now get the flags specified on the commandline
+ const int r = parser.ParseNewCommandLineFlags(argc, argv, remove_flags);
+
+ if (do_report)
+ HandleCommandLineHelpFlags(); // may cause us to exit on --help, etc.
+
+ // See if any of the unset flags fail their validation checks
+ parser.ValidateAllFlags();
+
+ if (parser.ReportErrors()) // may cause us to exit on illegal flags
+ commandlineflags_exitfunc(1); // almost certainly exit()
+ return r;
+}
+
+uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags) {
+ return ParseCommandLineFlagsInternal(argc, argv, remove_flags, true);
+}
+
+uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv,
+ bool remove_flags) {
+ return ParseCommandLineFlagsInternal(argc, argv, remove_flags, false);
+}
+
+// --------------------------------------------------------------------
+// AllowCommandLineReparsing()
+// ReparseCommandLineNonHelpFlags()
+// This is most useful for shared libraries. The idea is if
+// a flag is defined in a shared library that is dlopen'ed
+// sometime after main(), you can ParseCommandLineFlags before
+// the dlopen, then ReparseCommandLineNonHelpFlags() after the
+// dlopen, to get the new flags. But you have to explicitly
+// Allow() it; otherwise, you get the normal default behavior
+// of unrecognized flags calling a fatal error.
+// TODO(csilvers): this isn't used. Just delete it?
+// --------------------------------------------------------------------
+
+void AllowCommandLineReparsing() {
+ allow_command_line_reparsing = true;
+}
+
+uint32 ReparseCommandLineNonHelpFlags() {
+ // We make a copy of argc and argv to pass in
+ const vector<string>& argvs = GetArgvs();
+ int tmp_argc = static_cast<int>(argvs.size());
+ char** tmp_argv = new char* [tmp_argc + 1];
+ for (int i = 0; i < tmp_argc; ++i)
+ tmp_argv[i] = strdup(argvs[i].c_str()); // TODO(csilvers): don't dup
+
+ const int retval = ParseCommandLineNonHelpFlags(&tmp_argc, &tmp_argv, false);
+
+ for (int i = 0; i < tmp_argc; ++i)
+ free(tmp_argv[i]);
+ delete[] tmp_argv;
+
+ return retval;
+}
+
+void ShutDownCommandLineFlags() {
+ FlagRegistry::DeleteGlobalRegistry();
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/gflags/gflags.h b/extern/libmv/third_party/gflags/gflags.h
new file mode 100644
index 00000000000..cefbd62ae51
--- /dev/null
+++ b/extern/libmv/third_party/gflags/gflags.h
@@ -0,0 +1,589 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Ray Sidney
+// Revamped and reorganized by Craig Silverstein
+//
+// This is the file that should be included by any file which declares
+// or defines a command line flag or wants to parse command line flags
+// or print a program usage message (which will include information about
+// flags). Executive summary, in the form of an example foo.cc file:
+//
+// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
+// #include "validators.h" // hypothetical file defining ValidateIsFile()
+//
+// DEFINE_int32(end, 1000, "The last record to read");
+//
+// DEFINE_string(filename, "my_file.txt", "The file to read");
+// // Crash if the specified file does not exist.
+// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
+// &ValidateIsFile);
+//
+// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
+//
+// void MyFunc() {
+// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
+// }
+//
+// Then, at the command-line:
+// ./foo --noverbose --start=5 --end=100
+//
+// For more details, see
+// doc/gflags.html
+//
+// --- A note about thread-safety:
+//
+// We describe many functions in this routine as being thread-hostile,
+// thread-compatible, or thread-safe. Here are the meanings we use:
+//
+// thread-safe: it is safe for multiple threads to call this routine
+// (or, when referring to a class, methods of this class)
+// concurrently.
+// thread-hostile: it is not safe for multiple threads to call this
+// routine (or methods of this class) concurrently. In gflags,
+// most thread-hostile routines are intended to be called early in,
+// or even before, main() -- that is, before threads are spawned.
+// thread-compatible: it is safe for multiple threads to read from
+// this variable (when applied to variables), or to call const
+// methods of this class (when applied to classes), as long as no
+// other thread is writing to the variable or calling non-const
+// methods of this class.
+
+#ifndef GOOGLE_GFLAGS_H_
+#define GOOGLE_GFLAGS_H_
+
+#include <string>
+#include <vector>
+
+// We care a lot about number of bits things take up. Unfortunately,
+// systems define their bit-specific ints in a lot of different ways.
+// We use our own way, and have a typedef to get there.
+// Note: these commands below may look like "#if 1" or "#if 0", but
+// that's because they were constructed that way at ./configure time.
+// Look at gflags.h.in to see how they're calculated (based on your config).
+#if 1
+#include <stdint.h> // the normal place uint16_t is defined
+#endif
+#if 1
+#include <sys/types.h> // the normal place u_int16_t is defined
+#endif
+#if 1
+#include <inttypes.h> // a third place for uint16_t or u_int16_t
+#endif
+
+namespace google {
+
+#if 1 // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 1 // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 0 // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+
+// --------------------------------------------------------------------
+// To actually define a flag in a file, use DEFINE_bool,
+// DEFINE_string, etc. at the bottom of this file. You may also find
+// it useful to register a validator with the flag. This ensures that
+// when the flag is parsed from the commandline, or is later set via
+// SetCommandLineOption, we call the validation function. It is _not_
+// called when you assign the value to the flag directly using the = operator.
+//
+// The validation function should return true if the flag value is valid, and
+// false otherwise. If the function returns false for the new setting of the
+// flag, the flag will retain its current value. If it returns false for the
+// default value, ParseCommandLineFlags() will die.
+//
+// This function is safe to call at global construct time (as in the
+// example below).
+//
+// Example use:
+// static bool ValidatePort(const char* flagname, int32 value) {
+// if (value > 0 && value < 32768) // value is ok
+// return true;
+// printf("Invalid value for --%s: %d\n", flagname, (int)value);
+// return false;
+// }
+// DEFINE_int32(port, 0, "What port to listen on");
+// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
+
+// Returns true if successfully registered, false if not (because the
+// first argument doesn't point to a command-line flag, or because a
+// validator is already registered for this flag).
+bool RegisterFlagValidator(const bool* flag,
+ bool (*validate_fn)(const char*, bool));
+bool RegisterFlagValidator(const int32* flag,
+ bool (*validate_fn)(const char*, int32));
+bool RegisterFlagValidator(const int64* flag,
+ bool (*validate_fn)(const char*, int64));
+bool RegisterFlagValidator(const uint64* flag,
+ bool (*validate_fn)(const char*, uint64));
+bool RegisterFlagValidator(const double* flag,
+ bool (*validate_fn)(const char*, double));
+bool RegisterFlagValidator(const std::string* flag,
+ bool (*validate_fn)(const char*, const std::string&));
+
+
+// --------------------------------------------------------------------
+// These methods are the best way to get access to info about the
+// list of commandline flags. Note that these routines are pretty slow.
+// GetAllFlags: mostly-complete info about the list, sorted by file.
+// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
+// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
+//
+// In addition to accessing flags, you can also access argv[0] (the program
+// name) and argv (the entire commandline), which we sock away a copy of.
+// These variables are static, so you should only set them once.
+
+struct CommandLineFlagInfo {
+ std::string name; // the name of the flag
+ std::string type; // the type of the flag: int32, etc
+ std::string description; // the "help text" associated with the flag
+ std::string current_value; // the current value, as a string
+ std::string default_value; // the default value, as a string
+ std::string filename; // 'cleaned' version of filename holding the flag
+ bool has_validator_fn; // true if RegisterFlagValidator called on flag
+ bool is_default; // true if the flag has the default value and
+ // has not been set explicitly from the cmdline
+ // or via SetCommandLineOption
+};
+
+// Using this inside of a validator is a recipe for a deadlock.
+// TODO(wojtekm) Fix locking when validators are running, to make it safe to
+// call validators during ParseAllFlags.
+// Also make sure then to uncomment the corresponding unit test in
+// commandlineflags_unittest.sh
+extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+// These two are actually defined in commandlineflags_reporting.cc.
+extern void ShowUsageWithFlags(const char *argv0); // what --help does
+extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetArgv(int argc, const char** argv);
+// The following functions are thread-safe as long as SetArgv() is
+// only called before any threads start.
+extern const std::vector<std::string>& GetArgvs(); // all of argv as a vector
+extern const char* GetArgv(); // all of argv as a string
+extern const char* GetArgv0(); // only argv0
+extern uint32 GetArgvSum(); // simple checksum of argv
+extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
+extern const char* ProgramInvocationShortName(); // basename(argv0)
+// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
+// called before any threads start.
+extern const char* ProgramUsage(); // string set by SetUsageMessage()
+
+
+// --------------------------------------------------------------------
+// Normally you access commandline flags by just saying "if (FLAGS_foo)"
+// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
+// commonly, via the DEFINE_foo macro). But if you need a bit more
+// control, we have programmatic ways to get/set the flags as well.
+// These programmatic ways to access flags are thread-safe, but direct
+// access is only thread-compatible.
+
+// Return true iff the flagname was found.
+// OUTPUT is set to the flag's value, or unchanged if we return false.
+extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+
+// Return true iff the flagname was found. OUTPUT is set to the flag's
+// CommandLineFlagInfo or unchanged if we return false.
+extern bool GetCommandLineFlagInfo(const char* name,
+ CommandLineFlagInfo* OUTPUT);
+
+// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
+// Example usage, to check if a flag's value is currently the default value:
+// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
+extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+
+enum FlagSettingMode {
+ // update the flag's value (can call this multiple times).
+ SET_FLAGS_VALUE,
+ // update the flag's value, but *only if* it has not yet been updated
+ // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
+ SET_FLAG_IF_DEFAULT,
+ // set the flag's default value to this. If the flag has not yet updated
+ // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
+ // change the flag's current value to the new default value as well.
+ SET_FLAGS_DEFAULT
+};
+
+// Set a particular flag ("command line option"). Returns a string
+// describing the new value that the option has been set to. The
+// return value API is not well-specified, so basically just depend on
+// it to be empty if the setting failed for some reason -- the name is
+// not a valid flag name, or the value is not a valid value -- and
+// non-empty else.
+
+// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
+extern std::string SetCommandLineOption(const char* name, const char* value);
+extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
+ FlagSettingMode set_mode);
+
+
+// --------------------------------------------------------------------
+// Saves the states (value, default value, whether the user has set
+// the flag, registered validators, etc) of all flags, and restores
+// them when the FlagSaver is destroyed. This is very useful in
+// tests, say, when you want to let your tests change the flags, but
+// make sure that they get reverted to the original states when your
+// test is complete.
+//
+// Example usage:
+// void TestFoo() {
+// FlagSaver s1;
+// FLAG_foo = false;
+// FLAG_bar = "some value";
+//
+// // test happens here. You can return at any time
+// // without worrying about restoring the FLAG values.
+// }
+//
+// Note: This class is marked with __attribute__((unused)) because all the
+// work is done in the constructor and destructor, so in the standard
+// usage example above, the compiler would complain that it's an
+// unused variable.
+//
+// This class is thread-safe.
+
+class FlagSaver {
+ public:
+ FlagSaver();
+ ~FlagSaver();
+
+ private:
+ class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
+
+ FlagSaver(const FlagSaver&); // no copying!
+ void operator=(const FlagSaver&);
+}
+#ifndef _MSC_VER
+__attribute__ ((unused))
+#endif
+;
+
+// --------------------------------------------------------------------
+// Some deprecated or hopefully-soon-to-be-deprecated functions.
+
+// This is often used for logging. TODO(csilvers): figure out a better way
+extern std::string CommandlineFlagsIntoString();
+// Usually where this is used, a FlagSaver should be used instead.
+extern bool ReadFlagsFromString(const std::string& flagfilecontents,
+ const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+// These let you manually implement --flagfile functionality.
+// DEPRECATED.
+extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern bool SaveCommandFlags(); // actually defined in google.cc !
+extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
+
+
+// --------------------------------------------------------------------
+// Useful routines for initializing flags from the environment.
+// In each case, if 'varname' does not exist in the environment
+// return defval. If 'varname' does exist but is not valid
+// (e.g., not a number for an int32 flag), abort with an error.
+// Otherwise, return the value. NOTE: for booleans, for true use
+// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
+
+extern bool BoolFromEnv(const char *varname, bool defval);
+extern int32 Int32FromEnv(const char *varname, int32 defval);
+extern int64 Int64FromEnv(const char *varname, int64 defval);
+extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern double DoubleFromEnv(const char *varname, double defval);
+extern const char *StringFromEnv(const char *varname, const char *defval);
+
+
+// --------------------------------------------------------------------
+// The next two functions parse commandlineflags from main():
+
+// Set the "usage" message for this program. For example:
+// string usage("This program does nothing. Sample usage:\n");
+// usage += argv[0] + " <uselessarg1> <uselessarg2>";
+// SetUsageMessage(usage);
+// Do not include commandline flags in the usage: we do that for you!
+// Thread-hostile; meant to be called before any threads are spawned.
+extern void SetUsageMessage(const std::string& usage);
+
+// Looks for flags in argv and parses them. Rearranges argv to put
+// flags first, or removes them entirely if remove_flags is true.
+// If a flag is defined more than once in the command line or flag
+// file, the last definition is used. Returns the index (into argv)
+// of the first non-flag argument.
+// See top-of-file for more details on this function.
+#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
+extern uint32 ParseCommandLineFlags(int *argc, char*** argv,
+ bool remove_flags);
+#endif
+
+
+// Calls to ParseCommandLineNonHelpFlags and then to
+// HandleCommandLineHelpFlags can be used instead of a call to
+// ParseCommandLineFlags during initialization, in order to allow for
+// changing default values for some FLAGS (via
+// e.g. SetCommandLineOptionWithMode calls) between the time of
+// command line parsing and the time of dumping help information for
+// the flags as a result of command line parsing. If a flag is
+// defined more than once in the command line or flag file, the last
+// definition is used. Returns the index (into argv) of the first
+// non-flag argument. (If remove_flags is true, will always return 1.)
+extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
+ bool remove_flags);
+// This is actually defined in commandlineflags_reporting.cc.
+// This function is misnamed (it also handles --version, etc.), but
+// it's too late to change that now. :-(
+extern void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc
+
+// Allow command line reparsing. Disables the error normally
+// generated when an unknown flag is found, since it may be found in a
+// later parse. Thread-hostile; meant to be called before any threads
+// are spawned.
+extern void AllowCommandLineReparsing();
+
+// Reparse the flags that have not yet been recognized. Only flags
+// registered since the last parse will be recognized. Any flag value
+// must be provided as part of the argument using "=", not as a
+// separate command line argument that follows the flag argument.
+// Intended for handling flags from dynamically loaded libraries,
+// since their flags are not registered until they are loaded.
+// Returns the index (into the original argv) of the first non-flag
+// argument. (If remove_flags is true, will always return 1.)
+extern uint32 ReparseCommandLineNonHelpFlags();
+
+// Clean up memory allocated by flags. This is only needed to reduce
+// the quantity of "potentially leaked" reports emitted by memory
+// debugging tools such as valgrind. It is not required for normal
+// operation, or for the perftools heap-checker. It must only be called
+// when the process is about to exit, and all threads that might
+// access flags are quiescent. Referencing flags after this is called
+// will have unexpected consequences. This is not safe to run when
+// multiple threads might be running: the function is thread-hostile.
+extern void ShutDownCommandLineFlags();
+
+
+// --------------------------------------------------------------------
+// Now come the command line flag declaration/definition macros that
+// will actually be used. They're kind of hairy. A major reason
+// for this is initialization: we want people to be able to access
+// variables in global constructors and have that not crash, even if
+// their global constructor runs before the global constructor here.
+// (Obviously, we can't guarantee the flags will have the correct
+// default value in that case, but at least accessing them is safe.)
+// The only way to do that is have flags point to a static buffer.
+// So we make one, using a union to ensure proper alignment, and
+// then use placement-new to actually set up the flag with the
+// correct default value. In the same vein, we have to worry about
+// flag access in global destructors, so FlagRegisterer has to be
+// careful never to destroy the flag-values it constructs.
+//
+// Note that when we define a flag variable FLAGS_<name>, we also
+// preemptively define a junk variable, FLAGS_no<name>. This is to
+// cause a link-time error if someone tries to define 2 flags with
+// names like "logging" and "nologging". We do this because a bool
+// flag FLAG can be set from the command line to true with a "-FLAG"
+// argument, and to false with a "-noFLAG" argument, and so this can
+// potentially avert confusion.
+//
+// We also put flags into their own namespace. It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly. The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the current
+// namespace. The net result is to force people to use DECLARE to get
+// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// or some such instead. We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want, and
+// make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+
+class FlagRegisterer {
+ public:
+ FlagRegisterer(const char* name, const char* type,
+ const char* help, const char* filename,
+ void* current_storage, void* defvalue_storage);
+};
+
+extern bool FlagsTypeWarn(const char *name);
+
+// If your application #defines STRIP_FLAG_HELP to a non-zero value
+// before #including this file, we remove the help message from the
+// binary file. This can reduce the size of the resulting binary
+// somewhat, and may also be useful for security reasons.
+
+extern const char kStrippedFlagHelp[];
+
+}
+
+#ifndef SWIG // In swig, ignore the main flag declarations
+
+#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
+// Need this construct to avoid the 'defined but not used' warning.
+#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : ::google::kStrippedFlagHelp)
+#else
+#define MAYBE_STRIPPED_HELP(txt) txt
+#endif
+
+// Each command-line flag has two variables associated with it: one
+// with the current value, and one with the default value. However,
+// we have a third variable, which is where value is assigned; it's a
+// constant. This guarantees that FLAG_##value is initialized at
+// static initialization time (e.g. before program-start) rather than
+// than global construction time (which is after program-start but
+// before main), at least when 'value' is a compile-time constant. We
+// use a small trick for the "default value" variable, and call it
+// FLAGS_no<name>. This serves the second purpose of assuring a
+// compile error if someone tries to define a flag named no<name>
+// which is illegal (--foo and --nofoo both affect the "foo" flag).
+#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
+ namespace fL##shorttype { \
+ static const type FLAGS_nono##name = value; \
+ type FLAGS_##name = FLAGS_nono##name; \
+ type FLAGS_no##name = FLAGS_nono##name; \
+ static ::google::FlagRegisterer o_##name( \
+ #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
+ &FLAGS_##name, &FLAGS_no##name); \
+ } \
+ using fL##shorttype::FLAGS_##name
+
+#define DECLARE_VARIABLE(type, shorttype, name) \
+ namespace fL##shorttype { \
+ extern type FLAGS_##name; \
+ } \
+ using fL##shorttype::FLAGS_##name
+
+// For DEFINE_bool, we want to do the extra check that the passed-in
+// value is actually a bool, and not a string or something that can be
+// coerced to a bool. These declarations (no definition needed!) will
+// help us do that, and never evaluate From, which is important.
+// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
+// that the compiler have different sizes for bool & double. Since
+// this is not guaranteed by the standard, we check it with a
+// compile-time assert (msg[-1] will give a compile-time error).
+namespace fLB {
+struct CompileAssert {};
+typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
+ (sizeof(double) != sizeof(bool)) ? 1 : -1];
+template<typename From> double IsBoolFlag(const From& from);
+bool IsBoolFlag(bool from);
+} // namespace fLB
+
+#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name)
+#define DEFINE_bool(name, val, txt) \
+ namespace fLB { \
+ typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
+ (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \
+ } \
+ DEFINE_VARIABLE(bool, B, name, val, txt)
+
+#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32, I, name)
+#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32, I, name, val, txt)
+
+#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64, I64, name)
+#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64, I64, name, val, txt)
+
+#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64, U64, name)
+#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64, U64, name, val, txt)
+
+#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name)
+#define DEFINE_double(name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt)
+
+// Strings are trickier, because they're not a POD, so we can't
+// construct them at static-initialization time (instead they get
+// constructed at global-constructor time, which is much later). To
+// try to avoid crashes in that case, we use a char buffer to store
+// the string, which we can static-initialize, and then placement-new
+// into it later. It's not perfect, but the best we can do.
+
+namespace fLS {
+// The meaning of "string" might be different between now and when the
+// macros below get invoked (e.g., if someone is experimenting with
+// other string implementations that get defined after this file is
+// included). Save the current meaning now and use it in the macros.
+typedef std::string clstring;
+
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const char *value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ const clstring &value) {
+ return new(stringspot) clstring(value);
+}
+inline clstring* dont_pass0toDEFINE_string(char *stringspot,
+ int value);
+} // namespace fLS
+
+#define DECLARE_string(name) namespace fLS { extern ::fLS::clstring& FLAGS_##name; } \
+ using fLS::FLAGS_##name
+
+// We need to define a var named FLAGS_no##name so people don't define
+// --string and --nostring. And we need a temporary place to put val
+// so we don't have to evaluate it twice. Two great needs that go
+// great together!
+// The weird 'using' + 'extern' inside the fLS namespace is to work around
+// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
+// http://code.google.com/p/google-gflags/issues/detail?id=20
+#define DEFINE_string(name, val, txt) \
+ namespace fLS { \
+ using ::fLS::clstring; \
+ static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
+ clstring* const FLAGS_no##name = ::fLS:: \
+ dont_pass0toDEFINE_string(s_##name[0].s, \
+ val); \
+ static ::google::FlagRegisterer o_##name( \
+ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
+ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
+ extern clstring& FLAGS_##name; \
+ using fLS::FLAGS_##name; \
+ clstring& FLAGS_##name = *FLAGS_no##name; \
+ } \
+ using fLS::FLAGS_##name
+
+#endif // SWIG
+
+#endif // GOOGLE_GFLAGS_H_
diff --git a/extern/libmv/third_party/gflags/gflags_completions.cc b/extern/libmv/third_party/gflags/gflags_completions.cc
new file mode 100644
index 00000000000..a129611d8a1
--- /dev/null
+++ b/extern/libmv/third_party/gflags/gflags_completions.cc
@@ -0,0 +1,765 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: Dave Nicponski
+//
+// Bash-style command line flag completion for C++ binaries
+//
+// This module implements bash-style completions. It achieves this
+// goal in the following broad chunks:
+//
+// 1) Take a to-be-completed word, and examine it for search hints
+// 2) Identify all potentially matching flags
+// 2a) If there are no matching flags, do nothing.
+// 2b) If all matching flags share a common prefix longer than the
+// completion word, output just that matching prefix
+// 3) Categorize those flags to produce a rough ordering of relevence.
+// 4) Potentially trim the set of flags returned to a smaller number
+// that bash is happier with
+// 5) Output the matching flags in groups ordered by relevence.
+// 5a) Force bash to place most-relevent groups at the top of the list
+// 5b) Trim most flag's descriptions to fit on a single terminal line
+
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> // for strlen
+
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "gflags.h"
+
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+DEFINE_string(tab_completion_word, "",
+ "If non-empty, HandleCommandLineCompletions() will hijack the "
+ "process and attempt to do bash-style command line flag "
+ "completion on this value.");
+DEFINE_int32(tab_completion_columns, 80,
+ "Number of columns to use in output for tab completion");
+
+_START_GOOGLE_NAMESPACE_
+
+namespace {
+
+using std::set;
+using std::string;
+using std::vector;
+
+// Function prototypes and Type forward declarations. Code may be
+// more easily understood if it is roughly ordered according to
+// control flow, rather than by C's "declare before use" ordering
+struct CompletionOptions;
+struct NotableFlags;
+
+// The entry point if flag completion is to be used.
+static void PrintFlagCompletionInfo(void);
+
+
+// 1) Examine search word
+static void CanonicalizeCursorWordAndSearchOptions(
+ const string &cursor_word,
+ string *canonical_search_token,
+ CompletionOptions *options);
+
+static bool RemoveTrailingChar(string *str, char c);
+
+
+// 2) Find all matches
+static void FindMatchingFlags(
+ const vector<CommandLineFlagInfo> &all_flags,
+ const CompletionOptions &options,
+ const string &match_token,
+ set<const CommandLineFlagInfo *> *all_matches,
+ string *longest_common_prefix);
+
+static bool DoesSingleFlagMatch(
+ const CommandLineFlagInfo &flag,
+ const CompletionOptions &options,
+ const string &match_token);
+
+
+// 3) Categorize matches
+static void CategorizeAllMatchingFlags(
+ const set<const CommandLineFlagInfo *> &all_matches,
+ const string &search_token,
+ const string &module,
+ const string &package_dir,
+ NotableFlags *notable_flags);
+
+static void TryFindModuleAndPackageDir(
+ const vector<CommandLineFlagInfo> all_flags,
+ string *module,
+ string *package_dir);
+
+
+// 4) Decide which flags to use
+static void FinalizeCompletionOutput(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ CompletionOptions *options,
+ NotableFlags *notable_flags,
+ vector<string> *completions);
+
+static void RetrieveUnusedFlags(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ const NotableFlags &notable_flags,
+ set<const CommandLineFlagInfo *> *unused_flags);
+
+
+// 5) Output matches
+static void OutputSingleGroupWithLimit(
+ const set<const CommandLineFlagInfo *> &group,
+ const string &line_indentation,
+ const string &header,
+ const string &footer,
+ bool long_output_format,
+ int *remaining_line_limit,
+ size_t *completion_elements_added,
+ vector<string> *completions);
+
+// (helpers for #5)
+static string GetShortFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info);
+
+static string GetLongFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info);
+
+
+//
+// Useful types
+
+// Try to deduce the intentions behind this completion attempt. Return the
+// canonical search term in 'canonical_search_token'. Binary search options
+// are returned in the various booleans, which should all have intuitive
+// semantics, possibly except:
+// - return_all_matching_flags: Generally, we'll trim the number of
+// returned candidates to some small number, showing those that are
+// most likely to be useful first. If this is set, however, the user
+// really does want us to return every single flag as an option.
+// - force_no_update: Any time we output lines, all of which share a
+// common prefix, bash will 'helpfully' not even bother to show the
+// output, instead changing the current word to be that common prefix.
+// If it's clear this shouldn't happen, we'll set this boolean
+struct CompletionOptions {
+ bool flag_name_substring_search;
+ bool flag_location_substring_search;
+ bool flag_description_substring_search;
+ bool return_all_matching_flags;
+ bool force_no_update;
+};
+
+// Notable flags are flags that are special or preferred for some
+// reason. For example, flags that are defined in the binary's module
+// are expected to be much more relevent than flags defined in some
+// other random location. These sets are specified roughly in precedence
+// order. Once a flag is placed in one of these 'higher' sets, it won't
+// be placed in any of the 'lower' sets.
+struct NotableFlags {
+ typedef set<const CommandLineFlagInfo *> FlagSet;
+ FlagSet perfect_match_flag;
+ FlagSet module_flags; // Found in module file
+ FlagSet package_flags; // Found in same directory as module file
+ FlagSet most_common_flags; // One of the XXX most commonly supplied flags
+ FlagSet subpackage_flags; // Found in subdirectories of package
+};
+
+
+//
+// Tab completion implementation - entry point
+static void PrintFlagCompletionInfo(void) {
+ string cursor_word = FLAGS_tab_completion_word;
+ string canonical_token;
+ CompletionOptions options = { };
+ CanonicalizeCursorWordAndSearchOptions(
+ cursor_word,
+ &canonical_token,
+ &options);
+
+ //VLOG(1) << "Identified canonical_token: '" << canonical_token << "'";
+
+ vector<CommandLineFlagInfo> all_flags;
+ set<const CommandLineFlagInfo *> matching_flags;
+ GetAllFlags(&all_flags);
+ //VLOG(2) << "Found " << all_flags.size() << " flags overall";
+
+ string longest_common_prefix;
+ FindMatchingFlags(
+ all_flags,
+ options,
+ canonical_token,
+ &matching_flags,
+ &longest_common_prefix);
+ //VLOG(1) << "Identified " << matching_flags.size() << " matching flags";
+ //VLOG(1) << "Identified " << longest_common_prefix
+ // << " as longest common prefix.";
+ if (longest_common_prefix.size() > canonical_token.size()) {
+ // There's actually a shared common prefix to all matching flags,
+ // so may as well output that and quit quickly.
+ //VLOG(1) << "The common prefix '" << longest_common_prefix
+ // << "' was longer than the token '" << canonical_token
+ // << "'. Returning just this prefix for completion.";
+ fprintf(stdout, "--%s", longest_common_prefix.c_str());
+ return;
+ }
+ if (matching_flags.empty()) {
+ //VLOG(1) << "There were no matching flags, returning nothing.";
+ return;
+ }
+
+ string module;
+ string package_dir;
+ TryFindModuleAndPackageDir(all_flags, &module, &package_dir);
+ //VLOG(1) << "Identified module: '" << module << "'";
+ //VLOG(1) << "Identified package_dir: '" << package_dir << "'";
+
+ NotableFlags notable_flags;
+ CategorizeAllMatchingFlags(
+ matching_flags,
+ canonical_token,
+ module,
+ package_dir,
+ &notable_flags);
+ //VLOG(2) << "Categorized matching flags:";
+ //VLOG(2) << " perfect_match: " << notable_flags.perfect_match_flag.size();
+ //VLOG(2) << " module: " << notable_flags.module_flags.size();
+ //VLOG(2) << " package: " << notable_flags.package_flags.size();
+ //VLOG(2) << " most common: " << notable_flags.most_common_flags.size();
+ //VLOG(2) << " subpackage: " << notable_flags.subpackage_flags.size();
+
+ vector<string> completions;
+ FinalizeCompletionOutput(
+ matching_flags,
+ &options,
+ &notable_flags,
+ &completions);
+
+ if (options.force_no_update)
+ completions.push_back("~");
+
+ //VLOG(1) << "Finalized with " << completions.size()
+ // << " chosen completions";
+
+ for (vector<string>::const_iterator it = completions.begin();
+ it != completions.end();
+ ++it) {
+ //VLOG(9) << " Completion entry: '" << *it << "'";
+ fprintf(stdout, "%s\n", it->c_str());
+ }
+}
+
+
+// 1) Examine search word (and helper method)
+static void CanonicalizeCursorWordAndSearchOptions(
+ const string &cursor_word,
+ string *canonical_search_token,
+ CompletionOptions *options) {
+ *canonical_search_token = cursor_word;
+ if (canonical_search_token->empty()) return;
+
+ // Get rid of leading quotes and dashes in the search term
+ if ((*canonical_search_token)[0] == '"')
+ *canonical_search_token = canonical_search_token->substr(1);
+ while ((*canonical_search_token)[0] == '-')
+ *canonical_search_token = canonical_search_token->substr(1);
+
+ options->flag_name_substring_search = false;
+ options->flag_location_substring_search = false;
+ options->flag_description_substring_search = false;
+ options->return_all_matching_flags = false;
+ options->force_no_update = false;
+
+ // Look for all search options we can deduce now. Do this by walking
+ // backwards through the term, looking for up to three '?' and up to
+ // one '+' as suffixed characters. Consume them if found, and remove
+ // them from the canonical search token.
+ int found_question_marks = 0;
+ int found_plusses = 0;
+ while (true) {
+ if (found_question_marks < 3 &&
+ RemoveTrailingChar(canonical_search_token, '?')) {
+ ++found_question_marks;
+ continue;
+ }
+ if (found_plusses < 1 &&
+ RemoveTrailingChar(canonical_search_token, '+')) {
+ ++found_plusses;
+ continue;
+ }
+ break;
+ }
+
+ switch (found_question_marks) { // all fallthroughs
+ case 3: options->flag_description_substring_search = true;
+ case 2: options->flag_location_substring_search = true;
+ case 1: options->flag_name_substring_search = true;
+ };
+
+ options->return_all_matching_flags = (found_plusses > 0);
+}
+
+// Returns true if a char was removed
+static bool RemoveTrailingChar(string *str, char c) {
+ if (str->empty()) return false;
+ if ((*str)[str->size() - 1] == c) {
+ *str = str->substr(0, str->size() - 1);
+ return true;
+ }
+ return false;
+}
+
+
+// 2) Find all matches (and helper methods)
+static void FindMatchingFlags(
+ const vector<CommandLineFlagInfo> &all_flags,
+ const CompletionOptions &options,
+ const string &match_token,
+ set<const CommandLineFlagInfo *> *all_matches,
+ string *longest_common_prefix) {
+ all_matches->clear();
+ bool first_match = true;
+ for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
+ it != all_flags.end();
+ ++it) {
+ if (DoesSingleFlagMatch(*it, options, match_token)) {
+ all_matches->insert(&*it);
+ if (first_match) {
+ first_match = false;
+ *longest_common_prefix = it->name;
+ } else {
+ if (longest_common_prefix->empty() || it->name.empty()) {
+ longest_common_prefix->clear();
+ continue;
+ }
+ string::size_type pos = 0;
+ while (pos < longest_common_prefix->size() &&
+ pos < it->name.size() &&
+ (*longest_common_prefix)[pos] == it->name[pos])
+ ++pos;
+ longest_common_prefix->erase(pos);
+ }
+ }
+ }
+}
+
+// Given the set of all flags, the parsed match options, and the
+// canonical search token, produce the set of all candidate matching
+// flags for subsequent analysis or filtering.
+static bool DoesSingleFlagMatch(
+ const CommandLineFlagInfo &flag,
+ const CompletionOptions &options,
+ const string &match_token) {
+ // Is there a prefix match?
+ string::size_type pos = flag.name.find(match_token);
+ if (pos == 0) return true;
+
+ // Is there a substring match if we want it?
+ if (options.flag_name_substring_search &&
+ pos != string::npos)
+ return true;
+
+ // Is there a location match if we want it?
+ if (options.flag_location_substring_search &&
+ flag.filename.find(match_token) != string::npos)
+ return true;
+
+ // TODO(daven): All searches should probably be case-insensitive
+ // (especially this one...)
+ if (options.flag_description_substring_search &&
+ flag.description.find(match_token) != string::npos)
+ return true;
+
+ return false;
+}
+
+// 3) Categorize matches (and helper method)
+
+// Given a set of matching flags, categorize them by
+// likely relevence to this specific binary
+static void CategorizeAllMatchingFlags(
+ const set<const CommandLineFlagInfo *> &all_matches,
+ const string &search_token,
+ const string &module, // empty if we couldn't find any
+ const string &package_dir, // empty if we couldn't find any
+ NotableFlags *notable_flags) {
+ notable_flags->perfect_match_flag.clear();
+ notable_flags->module_flags.clear();
+ notable_flags->package_flags.clear();
+ notable_flags->most_common_flags.clear();
+ notable_flags->subpackage_flags.clear();
+
+ for (set<const CommandLineFlagInfo *>::const_iterator it =
+ all_matches.begin();
+ it != all_matches.end();
+ ++it) {
+ //VLOG(2) << "Examining match '" << (*it)->name << "'";
+ //VLOG(7) << " filename: '" << (*it)->filename << "'";
+ string::size_type pos = string::npos;
+ if (!package_dir.empty())
+ pos = (*it)->filename.find(package_dir);
+ string::size_type slash = string::npos;
+ if (pos != string::npos) // candidate for package or subpackage match
+ slash = (*it)->filename.find(
+ PATH_SEPARATOR,
+ pos + package_dir.size() + 1);
+
+ if ((*it)->name == search_token) {
+ // Exact match on some flag's name
+ notable_flags->perfect_match_flag.insert(*it);
+ //VLOG(3) << "Result: perfect match";
+ } else if (!module.empty() && (*it)->filename == module) {
+ // Exact match on module filename
+ notable_flags->module_flags.insert(*it);
+ //VLOG(3) << "Result: module match";
+ } else if (!package_dir.empty() &&
+ pos != string::npos && slash == string::npos) {
+ // In the package, since there was no slash after the package portion
+ notable_flags->package_flags.insert(*it);
+ //VLOG(3) << "Result: package match";
+ } else if (false) {
+ // In the list of the XXX most commonly supplied flags overall
+ // TODO(daven): Compile this list.
+ //VLOG(3) << "Result: most-common match";
+ } else if (!package_dir.empty() &&
+ pos != string::npos && slash != string::npos) {
+ // In a subdirectory of the package
+ notable_flags->subpackage_flags.insert(*it);
+ //VLOG(3) << "Result: subpackage match";
+ }
+
+ //VLOG(3) << "Result: not special match";
+ }
+}
+
+static void PushNameWithSuffix(vector<string>* suffixes, const char* suffix) {
+ string s("/");
+ s += ProgramInvocationShortName();
+ s += suffix;
+ suffixes->push_back(s);
+}
+
+static void TryFindModuleAndPackageDir(
+ const vector<CommandLineFlagInfo> all_flags,
+ string *module,
+ string *package_dir) {
+ module->clear();
+ package_dir->clear();
+
+ vector<string> suffixes;
+ // TODO(daven): There's some inherant ambiguity here - multiple directories
+ // could share the same trailing folder and file structure (and even worse,
+ // same file names), causing us to be unsure as to which of the two is the
+ // actual package for this binary. In this case, we'll arbitrarily choose.
+ PushNameWithSuffix(&suffixes, ".");
+ PushNameWithSuffix(&suffixes, "-main.");
+ PushNameWithSuffix(&suffixes, "_main.");
+ // These four are new but probably merited?
+ PushNameWithSuffix(&suffixes, "-test.");
+ PushNameWithSuffix(&suffixes, "_test.");
+ PushNameWithSuffix(&suffixes, "-unittest.");
+ PushNameWithSuffix(&suffixes, "_unittest.");
+
+ for (vector<CommandLineFlagInfo>::const_iterator it = all_flags.begin();
+ it != all_flags.end();
+ ++it) {
+ for (vector<string>::const_iterator suffix = suffixes.begin();
+ suffix != suffixes.end();
+ ++suffix) {
+ // TODO(daven): Make sure the match is near the end of the string
+ if (it->filename.find(*suffix) != string::npos) {
+ *module = it->filename;
+ string::size_type sep = it->filename.rfind(PATH_SEPARATOR);
+ *package_dir = it->filename.substr(0, (sep == string::npos) ? 0 : sep);
+ return;
+ }
+ }
+ }
+}
+
+// Can't specialize template type on a locally defined type. Silly C++...
+struct DisplayInfoGroup {
+ const char* header;
+ const char* footer;
+ set<const CommandLineFlagInfo *> *group;
+
+ int SizeInLines() const {
+ int size_in_lines = static_cast<int>(group->size()) + 1;
+ if (strlen(header) > 0) {
+ size_in_lines++;
+ }
+ if (strlen(footer) > 0) {
+ size_in_lines++;
+ }
+ return size_in_lines;
+ }
+};
+
+// 4) Finalize and trim output flag set
+static void FinalizeCompletionOutput(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ CompletionOptions *options,
+ NotableFlags *notable_flags,
+ vector<string> *completions) {
+
+ // We want to output lines in groups. Each group needs to be indented
+ // the same to keep its lines together. Unless otherwise required,
+ // only 99 lines should be output to prevent bash from harassing the
+ // user.
+
+ // First, figure out which output groups we'll actually use. For each
+ // nonempty group, there will be ~3 lines of header & footer, plus all
+ // output lines themselves.
+ int max_desired_lines = // "999999 flags should be enough for anyone. -dave"
+ (options->return_all_matching_flags ? 999999 : 98);
+ int lines_so_far = 0;
+
+ vector<DisplayInfoGroup> output_groups;
+ bool perfect_match_found = false;
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->perfect_match_flag.empty()) {
+ perfect_match_found = true;
+ DisplayInfoGroup group =
+ { "",
+ "==========",
+ &notable_flags->perfect_match_flag };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->module_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Matching module flags *-",
+ "===========================",
+ &notable_flags->module_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->package_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Matching package flags *-",
+ "============================",
+ &notable_flags->package_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->most_common_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Commonly used flags *-",
+ "=========================",
+ &notable_flags->most_common_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ if (lines_so_far < max_desired_lines &&
+ !notable_flags->subpackage_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Matching sub-package flags *-",
+ "================================",
+ &notable_flags->subpackage_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+
+ set<const CommandLineFlagInfo *> obscure_flags; // flags not notable
+ if (lines_so_far < max_desired_lines) {
+ RetrieveUnusedFlags(matching_flags, *notable_flags, &obscure_flags);
+ if (!obscure_flags.empty()) {
+ DisplayInfoGroup group = {
+ "-* Other flags *-",
+ "",
+ &obscure_flags };
+ lines_so_far += group.SizeInLines();
+ output_groups.push_back(group);
+ }
+ }
+
+ // Second, go through each of the chosen output groups and output
+ // as many of those flags as we can, while remaining below our limit
+ int remaining_lines = max_desired_lines;
+ size_t completions_output = 0;
+ int indent = static_cast<int>(output_groups.size()) - 1;
+ for (vector<DisplayInfoGroup>::const_iterator it =
+ output_groups.begin();
+ it != output_groups.end();
+ ++it, --indent) {
+ OutputSingleGroupWithLimit(
+ *it->group, // group
+ string(indent, ' '), // line indentation
+ string(it->header), // header
+ string(it->footer), // footer
+ perfect_match_found, // long format
+ &remaining_lines, // line limit - reduces this by number printed
+ &completions_output, // completions (not lines) added
+ completions); // produced completions
+ perfect_match_found = false;
+ }
+
+ if (completions_output != matching_flags.size()) {
+ options->force_no_update = false;
+ completions->push_back("~ (Remaining flags hidden) ~");
+ } else {
+ options->force_no_update = true;
+ }
+}
+
+static void RetrieveUnusedFlags(
+ const set<const CommandLineFlagInfo *> &matching_flags,
+ const NotableFlags &notable_flags,
+ set<const CommandLineFlagInfo *> *unused_flags) {
+ // Remove from 'matching_flags' set all members of the sets of
+ // flags we've already printed (specifically, those in notable_flags)
+ for (set<const CommandLineFlagInfo *>::const_iterator it =
+ matching_flags.begin();
+ it != matching_flags.end();
+ ++it) {
+ if (notable_flags.perfect_match_flag.count(*it) ||
+ notable_flags.module_flags.count(*it) ||
+ notable_flags.package_flags.count(*it) ||
+ notable_flags.most_common_flags.count(*it) ||
+ notable_flags.subpackage_flags.count(*it))
+ continue;
+ unused_flags->insert(*it);
+ }
+}
+
+// 5) Output matches (and helper methods)
+
+static void OutputSingleGroupWithLimit(
+ const set<const CommandLineFlagInfo *> &group,
+ const string &line_indentation,
+ const string &header,
+ const string &footer,
+ bool long_output_format,
+ int *remaining_line_limit,
+ size_t *completion_elements_output,
+ vector<string> *completions) {
+ if (group.empty()) return;
+ if (!header.empty()) {
+ if (*remaining_line_limit < 2) return;
+ *remaining_line_limit -= 2;
+ completions->push_back(line_indentation + header);
+ completions->push_back(line_indentation + string(header.size(), '-'));
+ }
+ for (set<const CommandLineFlagInfo *>::const_iterator it = group.begin();
+ it != group.end() && *remaining_line_limit > 0;
+ ++it) {
+ --*remaining_line_limit;
+ ++*completion_elements_output;
+ completions->push_back(
+ (long_output_format
+ ? GetLongFlagLine(line_indentation, **it)
+ : GetShortFlagLine(line_indentation, **it)));
+ }
+ if (!footer.empty()) {
+ if (*remaining_line_limit < 1) return;
+ --*remaining_line_limit;
+ completions->push_back(line_indentation + footer);
+ }
+}
+
+static string GetShortFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info) {
+ string prefix =
+ line_indentation + "--" + info.name + " [" +
+ (info.type == "string" ?
+ ("'" + info.default_value + "'") :
+ info.default_value)
+ + "] ";
+ int remainder =
+ FLAGS_tab_completion_columns - static_cast<int>(prefix.size());
+ string suffix;
+ if (remainder > 0)
+ suffix =
+ (static_cast<int>(info.description.size()) > remainder ?
+ (info.description.substr(0, remainder - 3) + "...").c_str() :
+ info.description.c_str());
+ return prefix + suffix;
+}
+
+static string GetLongFlagLine(
+ const string &line_indentation,
+ const CommandLineFlagInfo &info) {
+
+ string output = DescribeOneFlag(info);
+
+ // Replace '-' with '--', and remove trailing newline before appending
+ // the module definition location.
+ string old_flagname = "-" + info.name;
+ output.replace(
+ output.find(old_flagname),
+ old_flagname.size(),
+ "-" + old_flagname);
+ // Stick a newline and indentation in front of the type and default
+ // portions of DescribeOneFlag()s description
+ static const char kNewlineWithIndent[] = "\n ";
+ output.replace(output.find(" type:"), 1, string(kNewlineWithIndent));
+ output.replace(output.find(" default:"), 1, string(kNewlineWithIndent));
+ output = line_indentation + " Details for '--" + info.name + "':\n" +
+ output + " defined: " + info.filename;
+
+ // Eliminate any doubled newlines that crept in. Specifically, if
+ // DescribeOneFlag() decided to break the line just before "type"
+ // or "default", we don't want to introduce an extra blank line
+ static const string line_of_spaces(FLAGS_tab_completion_columns, ' ');
+ static const char kDoubledNewlines[] = "\n \n";
+ for (string::size_type newlines = output.find(kDoubledNewlines);
+ newlines != string::npos;
+ newlines = output.find(kDoubledNewlines))
+ // Replace each 'doubled newline' with a single newline
+ output.replace(newlines, sizeof(kDoubledNewlines) - 1, string("\n"));
+
+ for (string::size_type newline = output.find('\n');
+ newline != string::npos;
+ newline = output.find('\n')) {
+ int newline_pos = static_cast<int>(newline) % FLAGS_tab_completion_columns;
+ int missing_spaces = FLAGS_tab_completion_columns - newline_pos;
+ output.replace(newline, 1, line_of_spaces, 1, missing_spaces);
+ }
+ return output;
+}
+} // anonymous
+
+void HandleCommandLineCompletions(void) {
+ if (FLAGS_tab_completion_word.empty()) return;
+ PrintFlagCompletionInfo();
+ exit(0);
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/gflags/gflags_completions.h b/extern/libmv/third_party/gflags/gflags_completions.h
new file mode 100644
index 00000000000..9d9ce7a5f75
--- /dev/null
+++ b/extern/libmv/third_party/gflags/gflags_completions.h
@@ -0,0 +1,121 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: Dave Nicponski
+//
+// Implement helpful bash-style command line flag completions
+//
+// ** Functional API:
+// HandleCommandLineCompletions() should be called early during
+// program startup, but after command line flag code has been
+// initialized, such as the beginning of HandleCommandLineHelpFlags().
+// It checks the value of the flag --tab_completion_word. If this
+// flag is empty, nothing happens here. If it contains a string,
+// however, then HandleCommandLineCompletions() will hijack the
+// process, attempting to identify the intention behind this
+// completion. Regardless of the outcome of this deduction, the
+// process will be terminated, similar to --helpshort flag
+// handling.
+//
+// ** Overview of Bash completions:
+// Bash can be told to programatically determine completions for the
+// current 'cursor word'. It does this by (in this case) invoking a
+// command with some additional arguments identifying the command
+// being executed, the word being completed, and the previous word
+// (if any). Bash then expects a sequence of output lines to be
+// printed to stdout. If these lines all contain a common prefix
+// longer than the cursor word, bash will replace the cursor word
+// with that common prefix, and display nothing. If there isn't such
+// a common prefix, bash will display the lines in pages using 'more'.
+//
+// ** Strategy taken for command line completions:
+// If we can deduce either the exact flag intended, or a common flag
+// prefix, we'll output exactly that. Otherwise, if information
+// must be displayed to the user, we'll take the opportunity to add
+// some helpful information beyond just the flag name (specifically,
+// we'll include the default flag value and as much of the flag's
+// description as can fit on a single terminal line width, as specified
+// by the flag --tab_completion_columns). Furthermore, we'll try to
+// make bash order the output such that the most useful or relevent
+// flags are the most likely to be shown at the top.
+//
+// ** Additional features:
+// To assist in finding that one really useful flag, substring matching
+// was implemented. Before pressing a <TAB> to get completion for the
+// current word, you can append one or more '?' to the flag to do
+// substring matching. Here's the semantics:
+// --foo<TAB> Show me all flags with names prefixed by 'foo'
+// --foo?<TAB> Show me all flags with 'foo' somewhere in the name
+// --foo??<TAB> Same as prior case, but also search in module
+// definition path for 'foo'
+// --foo???<TAB> Same as prior case, but also search in flag
+// descriptions for 'foo'
+// Finally, we'll trim the output to a relatively small number of
+// flags to keep bash quiet about the verbosity of output. If one
+// really wanted to see all possible matches, appending a '+' to the
+// search word will force the exhaustive list of matches to be printed.
+//
+// ** How to have bash accept completions from a binary:
+// Bash requires that it be informed about each command that programmatic
+// completion should be enabled for. Example addition to a .bashrc
+// file would be (your path to gflags_completions.sh file may differ):
+
+/*
+$ complete -o bashdefault -o default -o nospace -C \
+ '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
+ time env binary_name another_binary [...]
+*/
+
+// This would allow the following to work:
+// $ /path/to/binary_name --vmodule<TAB>
+// Or:
+// $ ./bin/path/another_binary --gfs_u<TAB>
+// (etc)
+//
+// Sadly, it appears that bash gives no easy way to force this behavior for
+// all commands. That's where the "time" in the above example comes in.
+// If you haven't specifically added a command to the list of completion
+// supported commands, you can still get completions by prefixing the
+// entire command with "env".
+// $ env /some/brand/new/binary --vmod<TAB>
+// Assuming that "binary" is a newly compiled binary, this should still
+// produce the expected completion output.
+
+
+#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_
+#define GOOGLE_GFLAGS_COMPLETIONS_H_
+
+namespace google {
+
+void HandleCommandLineCompletions(void);
+
+}
+
+#endif // GOOGLE_GFLAGS_COMPLETIONS_H_
diff --git a/extern/libmv/third_party/gflags/gflags_reporting.cc b/extern/libmv/third_party/gflags/gflags_reporting.cc
new file mode 100644
index 00000000000..fa3024d974e
--- /dev/null
+++ b/extern/libmv/third_party/gflags/gflags_reporting.cc
@@ -0,0 +1,446 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Ray Sidney
+// Revamped and reorganized by Craig Silverstein
+//
+// This file contains code for handling the 'reporting' flags. These
+// are flags that, when present, cause the program to report some
+// information and then exit. --help and --version are the canonical
+// reporting flags, but we also have flags like --helpxml, etc.
+//
+// There's only one function that's meant to be called externally:
+// HandleCommandLineHelpFlags(). (Well, actually, ShowUsageWithFlags(),
+// ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called
+// externally too, but there's little need for it.) These are all
+// declared in the main commandlineflags.h header file.
+//
+// HandleCommandLineHelpFlags() will check what 'reporting' flags have
+// been defined, if any -- the "help" part of the function name is a
+// bit misleading -- and do the relevant reporting. It should be
+// called after all flag-values have been assigned, that is, after
+// parsing the command-line.
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <string>
+#include <vector>
+#include "gflags.h"
+#include "gflags_completions.h"
+
+#ifndef PATH_SEPARATOR
+#define PATH_SEPARATOR '/'
+#endif
+
+// The 'reporting' flags. They all call exit().
+DEFINE_bool(help, false,
+ "show help on all flags [tip: all flags can have two dashes]");
+DEFINE_bool(helpfull, false,
+ "show help on all flags -- same as -help");
+DEFINE_bool(helpshort, false,
+ "show help on only the main module for this program");
+DEFINE_string(helpon, "",
+ "show help on the modules named by this flag value");
+DEFINE_string(helpmatch, "",
+ "show help on modules whose name contains the specified substr");
+DEFINE_bool(helppackage, false,
+ "show help on all modules in the main package");
+DEFINE_bool(helpxml, false,
+ "produce an xml version of help");
+DEFINE_bool(version, false,
+ "show version and build info and exit");
+
+_START_GOOGLE_NAMESPACE_
+
+using std::string;
+using std::vector;
+
+// --------------------------------------------------------------------
+// DescribeOneFlag()
+// DescribeOneFlagInXML()
+// Routines that pretty-print info about a flag. These use
+// a CommandLineFlagInfo, which is the way the commandlineflags
+// API exposes static info about a flag.
+// --------------------------------------------------------------------
+
+static const int kLineLength = 80;
+
+static void AddString(const string& s,
+ string* final_string, int* chars_in_line) {
+ const int slen = static_cast<int>(s.length());
+ if (*chars_in_line + 1 + slen >= kLineLength) { // < 80 chars/line
+ *final_string += "\n ";
+ *chars_in_line = 6;
+ } else {
+ *final_string += " ";
+ *chars_in_line += 1;
+ }
+ *final_string += s;
+ *chars_in_line += slen;
+}
+
+static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag,
+ const string& text, bool current) {
+ const char* c_string = (current ? flag.current_value.c_str() :
+ flag.default_value.c_str());
+ if (strcmp(flag.type.c_str(), "string") == 0) { // add quotes for strings
+ return text + ": \"" + c_string + "\"";
+ } else {
+ return text + ": " + c_string;
+ }
+}
+
+// Create a descriptive string for a flag.
+// Goes to some trouble to make pretty line breaks.
+string DescribeOneFlag(const CommandLineFlagInfo& flag) {
+ string main_part = (string(" -") + flag.name +
+ " (" + flag.description + ')');
+ const char* c_string = main_part.c_str();
+ int chars_left = static_cast<int>(main_part.length());
+ string final_string = "";
+ int chars_in_line = 0; // how many chars in current line so far?
+ while (1) {
+ assert(chars_left == strlen(c_string)); // Unless there's a \0 in there?
+ const char* newline = strchr(c_string, '\n');
+ if (newline == NULL && chars_in_line+chars_left < kLineLength) {
+ // The whole remainder of the string fits on this line
+ final_string += c_string;
+ chars_in_line += chars_left;
+ break;
+ }
+ if (newline != NULL && newline - c_string < kLineLength - chars_in_line) {
+ int n = static_cast<int>(newline - c_string);
+ final_string.append(c_string, n);
+ chars_left -= n + 1;
+ c_string += n + 1;
+ } else {
+ // Find the last whitespace on this 80-char line
+ int whitespace = kLineLength-chars_in_line-1; // < 80 chars/line
+ while ( whitespace > 0 && !isspace(c_string[whitespace]) ) {
+ --whitespace;
+ }
+ if (whitespace <= 0) {
+ // Couldn't find any whitespace to make a line break. Just dump the
+ // rest out!
+ final_string += c_string;
+ chars_in_line = kLineLength; // next part gets its own line for sure!
+ break;
+ }
+ final_string += string(c_string, whitespace);
+ chars_in_line += whitespace;
+ while (isspace(c_string[whitespace])) ++whitespace;
+ c_string += whitespace;
+ chars_left -= whitespace;
+ }
+ if (*c_string == '\0')
+ break;
+ final_string += "\n ";
+ chars_in_line = 6;
+ }
+
+ // Append data type
+ AddString(string("type: ") + flag.type, &final_string, &chars_in_line);
+ // The listed default value will be the actual default from the flag
+ // definition in the originating source file, unless the value has
+ // subsequently been modified using SetCommandLineOptionWithMode() with mode
+ // SET_FLAGS_DEFAULT, or by setting FLAGS_foo = bar before initializing.
+ AddString(PrintStringFlagsWithQuotes(flag, "default", false), &final_string,
+ &chars_in_line);
+ if (!flag.is_default) {
+ AddString(PrintStringFlagsWithQuotes(flag, "currently", true),
+ &final_string, &chars_in_line);
+ }
+
+ final_string += '\n';
+ return final_string;
+}
+
+// Simple routine to xml-escape a string: escape & and < only.
+static string XMLText(const string& txt) {
+ string ans = txt;
+ for (string::size_type pos = 0; (pos = ans.find("&", pos)) != string::npos; )
+ ans.replace(pos++, 1, "&amp;");
+ for (string::size_type pos = 0; (pos = ans.find("<", pos)) != string::npos; )
+ ans.replace(pos++, 1, "&lt;");
+ return ans;
+}
+
+static void AddXMLTag(string* r, const char* tag, const string& txt) {
+ *r += ('<');
+ *r += (tag);
+ *r += ('>');
+ *r += (XMLText(txt));
+ *r += ("</");
+ *r += (tag);
+ *r += ('>');
+}
+
+static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) {
+ // The file and flagname could have been attributes, but default
+ // and meaning need to avoid attribute normalization. This way it
+ // can be parsed by simple programs, in addition to xml parsers.
+ string r("<flag>");
+ AddXMLTag(&r, "file", flag.filename);
+ AddXMLTag(&r, "name", flag.name);
+ AddXMLTag(&r, "meaning", flag.description);
+ AddXMLTag(&r, "default", flag.default_value);
+ AddXMLTag(&r, "current", flag.current_value);
+ AddXMLTag(&r, "type", flag.type);
+ r += "</flag>";
+ return r;
+}
+
+// --------------------------------------------------------------------
+// ShowUsageWithFlags()
+// ShowUsageWithFlagsRestrict()
+// ShowXMLOfFlags()
+// These routines variously expose the registry's list of flag
+// values. ShowUsage*() prints the flag-value information
+// to stdout in a user-readable format (that's what --help uses).
+// The Restrict() version limits what flags are shown.
+// ShowXMLOfFlags() prints the flag-value information to stdout
+// in a machine-readable format. In all cases, the flags are
+// sorted: first by filename they are defined in, then by flagname.
+// --------------------------------------------------------------------
+
+static const char* Basename(const char* filename) {
+ const char* sep = strrchr(filename, PATH_SEPARATOR);
+ return sep ? sep + 1 : filename;
+}
+
+static string Dirname(const string& filename) {
+ string::size_type sep = filename.rfind(PATH_SEPARATOR);
+ return filename.substr(0, (sep == string::npos) ? 0 : sep);
+}
+
+// Test whether a filename contains at least one of the substrings.
+static bool FileMatchesSubstring(const string& filename,
+ const vector<string>& substrings) {
+ for (vector<string>::const_iterator target = substrings.begin();
+ target != substrings.end();
+ ++target) {
+ if (strstr(filename.c_str(), target->c_str()) != NULL)
+ return true;
+ // If the substring starts with a '/', that means that we want
+ // the string to be at the beginning of a directory component.
+ // That should match the first directory component as well, so
+ // we allow '/foo' to match a filename of 'foo'.
+ if (!target->empty() && (*target)[0] == '/' &&
+ strncmp(filename.c_str(), target->c_str() + 1,
+ strlen(target->c_str() + 1)) == 0)
+ return true;
+ }
+ return false;
+}
+
+// Show help for every filename which matches any of the target substrings.
+// If substrings is empty, shows help for every file. If a flag's help message
+// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1' before
+// including gflags/gflags.h), then this flag will not be displayed by
+// '--help' and its variants.
+static void ShowUsageWithFlagsMatching(const char *argv0,
+ const vector<string> &substrings) {
+ fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage());
+
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags); // flags are sorted by filename, then flagname
+
+ string last_filename; // so we know when we're at a new file
+ bool first_directory = true; // controls blank lines between dirs
+ bool found_match = false; // stays false iff no dir matches restrict
+ for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
+ flag != flags.end();
+ ++flag) {
+ if (substrings.empty() ||
+ FileMatchesSubstring(flag->filename, substrings)) {
+ // If the flag has been stripped, pretend that it doesn't exist.
+ if (flag->description == kStrippedFlagHelp) continue;
+ found_match = true; // this flag passed the match!
+ if (flag->filename != last_filename) { // new file
+ if (Dirname(flag->filename) != Dirname(last_filename)) { // new dir!
+ if (!first_directory)
+ fprintf(stdout, "\n\n"); // put blank lines between directories
+ first_directory = false;
+ }
+ fprintf(stdout, "\n Flags from %s:\n", flag->filename.c_str());
+ last_filename = flag->filename;
+ }
+ // Now print this flag
+ fprintf(stdout, "%s", DescribeOneFlag(*flag).c_str());
+ }
+ }
+ if (!found_match && !substrings.empty()) {
+ fprintf(stdout, "\n No modules matched: use -help\n");
+ }
+}
+
+void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict) {
+ vector<string> substrings;
+ if (restrict != NULL && *restrict != '\0') {
+ substrings.push_back(restrict);
+ }
+ ShowUsageWithFlagsMatching(argv0, substrings);
+}
+
+void ShowUsageWithFlags(const char *argv0) {
+ ShowUsageWithFlagsRestrict(argv0, "");
+}
+
+// Convert the help, program, and usage to xml.
+static void ShowXMLOfFlags(const char *prog_name) {
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags); // flags are sorted: by filename, then flagname
+
+ // XML. There is no corresponding schema yet
+ fprintf(stdout, "<?xml version=\"1.0\"?>\n");
+ // The document
+ fprintf(stdout, "<AllFlags>\n");
+ // the program name and usage
+ fprintf(stdout, "<program>%s</program>\n",
+ XMLText(Basename(prog_name)).c_str());
+ fprintf(stdout, "<usage>%s</usage>\n",
+ XMLText(ProgramUsage()).c_str());
+ // All the flags
+ for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
+ flag != flags.end();
+ ++flag) {
+ if (flag->description != kStrippedFlagHelp)
+ fprintf(stdout, "%s\n", DescribeOneFlagInXML(*flag).c_str());
+ }
+ // The end of the document
+ fprintf(stdout, "</AllFlags>\n");
+}
+
+// --------------------------------------------------------------------
+// ShowVersion()
+// Called upon --version. Prints build-related info.
+// --------------------------------------------------------------------
+
+static void ShowVersion() {
+ fprintf(stdout, "%s\n", ProgramInvocationShortName());
+ // TODO: add other stuff, like a timestamp, who built it, what
+ // target they built, etc.
+
+# if !defined(NDEBUG)
+ fprintf(stdout, "Debug build (NDEBUG not #defined)\n");
+# endif
+}
+
+static void AppendPrognameStrings(vector<string>* substrings,
+ const char* progname) {
+ string r("/");
+ r += progname;
+ substrings->push_back(r + ".");
+ substrings->push_back(r + "-main.");
+ substrings->push_back(r + "_main.");
+}
+
+// --------------------------------------------------------------------
+// HandleCommandLineHelpFlags()
+// Checks all the 'reporting' commandline flags to see if any
+// have been set. If so, handles them appropriately. Note
+// that all of them, by definition, cause the program to exit
+// if they trigger.
+// --------------------------------------------------------------------
+
+void HandleCommandLineHelpFlags() {
+ const char* progname = ProgramInvocationShortName();
+ extern void (*commandlineflags_exitfunc)(int); // in gflags.cc
+
+ HandleCommandLineCompletions();
+
+ vector<string> substrings;
+ AppendPrognameStrings(&substrings, progname);
+
+ if (FLAGS_helpshort) {
+ // show only flags related to this binary:
+ // E.g. for fileutil.cc, want flags containing ... "/fileutil." cc
+ ShowUsageWithFlagsMatching(progname, substrings);
+ commandlineflags_exitfunc(1); // almost certainly exit()
+
+ } else if (FLAGS_help || FLAGS_helpfull) {
+ // show all options
+ ShowUsageWithFlagsRestrict(progname, ""); // empty restrict
+ commandlineflags_exitfunc(1);
+
+ } else if (!FLAGS_helpon.empty()) {
+ string restrict = "/" + FLAGS_helpon + ".";
+ ShowUsageWithFlagsRestrict(progname, restrict.c_str());
+ commandlineflags_exitfunc(1);
+
+ } else if (!FLAGS_helpmatch.empty()) {
+ ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str());
+ commandlineflags_exitfunc(1);
+
+ } else if (FLAGS_helppackage) {
+ // Shows help for all files in the same directory as main(). We
+ // don't want to resort to looking at dirname(progname), because
+ // the user can pick progname, and it may not relate to the file
+ // where main() resides. So instead, we search the flags for a
+ // filename like "/progname.cc", and take the dirname of that.
+ vector<CommandLineFlagInfo> flags;
+ GetAllFlags(&flags);
+ string last_package;
+ for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin();
+ flag != flags.end();
+ ++flag) {
+ if (!FileMatchesSubstring(flag->filename, substrings))
+ continue;
+ const string package = Dirname(flag->filename) + "/";
+ if (package != last_package) {
+ ShowUsageWithFlagsRestrict(progname, package.c_str());
+ if (!last_package.empty()) { // means this isn't our first pkg
+ fprintf(stderr, "WARNING: Multiple packages contain a file=%s\n",
+ progname);
+ }
+ last_package = package;
+ }
+ }
+ if (last_package.empty()) { // never found a package to print
+ fprintf(stderr, "WARNING: Unable to find a package for file=%s\n",
+ progname);
+ }
+ commandlineflags_exitfunc(1);
+
+ } else if (FLAGS_helpxml) {
+ ShowXMLOfFlags(progname);
+ commandlineflags_exitfunc(1);
+
+ } else if (FLAGS_version) {
+ ShowVersion();
+ // Unlike help, we may be asking for version in a script, so return 0
+ commandlineflags_exitfunc(0);
+ }
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/gflags/mutex.h b/extern/libmv/third_party/gflags/mutex.h
new file mode 100644
index 00000000000..6e1e8976b6d
--- /dev/null
+++ b/extern/libmv/third_party/gflags/mutex.h
@@ -0,0 +1,349 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: Craig Silverstein.
+//
+// A simple mutex wrapper, supporting locks and read-write locks.
+// You should assume the locks are *not* re-entrant.
+//
+// To use: you should define the following macros in your configure.ac:
+// ACX_PTHREAD
+// AC_RWLOCK
+// The latter is defined in ../autoconf.
+//
+// This class is meant to be internal-only and should be wrapped by an
+// internal namespace. Before you use this module, please give the
+// name of your internal namespace for this module. Or, if you want
+// to expose it, you'll want to move it to the Google namespace. We
+// cannot put this class in global namespace because there can be some
+// problems when we have multiple versions of Mutex in each shared object.
+//
+// NOTE: by default, we have #ifdef'ed out the TryLock() method.
+// This is for two reasons:
+// 1) TryLock() under Windows is a bit annoying (it requires a
+// #define to be defined very early).
+// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG
+// mode.
+// If you need TryLock(), and either these two caveats are not a
+// problem for you, or you're willing to work around them, then
+// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs
+// in the code below.
+//
+// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:
+// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html
+// Because of that, we might as well use windows locks for
+// cygwin. They seem to be more reliable than the cygwin pthreads layer.
+//
+// TRICKY IMPLEMENTATION NOTE:
+// This class is designed to be safe to use during
+// dynamic-initialization -- that is, by global constructors that are
+// run before main() starts. The issue in this case is that
+// dynamic-initialization happens in an unpredictable order, and it
+// could be that someone else's dynamic initializer could call a
+// function that tries to acquire this mutex -- but that all happens
+// before this mutex's constructor has run. (This can happen even if
+// the mutex and the function that uses the mutex are in the same .cc
+// file.) Basically, because Mutex does non-trivial work in its
+// constructor, it's not, in the naive implementation, safe to use
+// before dynamic initialization has run on it.
+//
+// The solution used here is to pair the actual mutex primitive with a
+// bool that is set to true when the mutex is dynamically initialized.
+// (Before that it's false.) Then we modify all mutex routines to
+// look at the bool, and not try to lock/unlock until the bool makes
+// it to true (which happens after the Mutex constructor has run.)
+//
+// This works because before main() starts -- particularly, during
+// dynamic initialization -- there are no threads, so a) it's ok that
+// the mutex operations are a no-op, since we don't need locking then
+// anyway; and b) we can be quite confident our bool won't change
+// state between a call to Lock() and a call to Unlock() (that would
+// require a global constructor in one translation unit to call Lock()
+// and another global constructor in another translation unit to call
+// Unlock() later, which is pretty perverse).
+//
+// That said, it's tricky, and can conceivably fail; it's safest to
+// avoid trying to acquire a mutex in a global constructor, if you
+// can. One way it can fail is that a really smart compiler might
+// initialize the bool to true at static-initialization time (too
+// early) rather than at dynamic-initialization time. To discourage
+// that, we set is_safe_ to true in code (not the constructor
+// colon-initializer) and set it to true via a function that always
+// evaluates to true, but that the compiler can't know always
+// evaluates to true. This should be good enough.
+//
+// A related issue is code that could try to access the mutex
+// after it's been destroyed in the global destructors (because
+// the Mutex global destructor runs before some other global
+// destructor, that tries to acquire the mutex). The way we
+// deal with this is by taking a constructor arg that global
+// mutexes should pass in, that causes the destructor to do no
+// work. We still depend on the compiler not doing anything
+// weird to a Mutex's memory after it is destroyed, but for a
+// static global variable, that's pretty safe.
+
+#ifndef GOOGLE_MUTEX_H_
+#define GOOGLE_MUTEX_H_
+
+#include "config.h" // to figure out pthreads support
+
+#if defined(NO_THREADS)
+ typedef int MutexType; // to keep a lock-count
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+# define WIN32_LEAN_AND_MEAN // We only need minimal includes
+# ifdef GMUTEX_TRYLOCK
+ // We need Windows NT or later for TryEnterCriticalSection(). If you
+ // don't need that functionality, you can remove these _WIN32_WINNT
+ // lines, and change TryLock() to assert(0) or something.
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0400
+# endif
+# endif
+# include <windows.h>
+ typedef CRITICAL_SECTION MutexType;
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+ // Needed for pthread_rwlock_*. If it causes problems, you could take it
+ // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
+ // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
+ // for locking there.)
+# ifdef __linux__
+# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
+# endif
+# include <pthread.h>
+ typedef pthread_rwlock_t MutexType;
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+ typedef pthread_mutex_t MutexType;
+#else
+# error Need to implement mutex.h for your architecture, or #define NO_THREADS
+#endif
+
+#include <assert.h>
+#include <stdlib.h> // for abort()
+
+#define MUTEX_NAMESPACE gflags_mutex_namespace
+
+namespace MUTEX_NAMESPACE {
+
+class Mutex {
+ public:
+ // This is used for the single-arg constructor
+ enum LinkerInitialized { LINKER_INITIALIZED };
+
+ // Create a Mutex that is not held by anybody. This constructor is
+ // typically used for Mutexes allocated on the heap or the stack.
+ inline Mutex();
+ // This constructor should be used for global, static Mutex objects.
+ // It inhibits work being done by the destructor, which makes it
+ // safer for code that tries to acqiure this mutex in their global
+ // destructor.
+ inline Mutex(LinkerInitialized);
+
+ // Destructor
+ inline ~Mutex();
+
+ inline void Lock(); // Block if needed until free then acquire exclusively
+ inline void Unlock(); // Release a lock acquired via Lock()
+#ifdef GMUTEX_TRYLOCK
+ inline bool TryLock(); // If free, Lock() and return true, else return false
+#endif
+ // Note that on systems that don't support read-write locks, these may
+ // be implemented as synonyms to Lock() and Unlock(). So you can use
+ // these for efficiency, but don't use them anyplace where being able
+ // to do shared reads is necessary to avoid deadlock.
+ inline void ReaderLock(); // Block until free or shared then acquire a share
+ inline void ReaderUnlock(); // Release a read share of this Mutex
+ inline void WriterLock() { Lock(); } // Acquire an exclusive lock
+ inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
+
+ private:
+ MutexType mutex_;
+ // We want to make sure that the compiler sets is_safe_ to true only
+ // when we tell it to, and never makes assumptions is_safe_ is
+ // always true. volatile is the most reliable way to do that.
+ volatile bool is_safe_;
+ // This indicates which constructor was called.
+ bool destroy_;
+
+ inline void SetIsSafe() { is_safe_ = true; }
+
+ // Catch the error of writing Mutex when intending MutexLock.
+ Mutex(Mutex* /*ignored*/) {}
+ // Disallow "evil" constructors
+ Mutex(const Mutex&);
+ void operator=(const Mutex&);
+};
+
+// Now the implementation of Mutex for various systems
+#if defined(NO_THREADS)
+
+// When we don't have threads, we can be either reading or writing,
+// but not both. We can have lots of readers at once (in no-threads
+// mode, that's most likely to happen in recursive function calls),
+// but only one writer. We represent this by having mutex_ be -1 when
+// writing and a number > 0 when reading (and 0 when no lock is held).
+//
+// In debug mode, we assert these invariants, while in non-debug mode
+// we do nothing, for efficiency. That's why everything is in an
+// assert.
+
+Mutex::Mutex() : mutex_(0) { }
+Mutex::Mutex(Mutex::LinkerInitialized) : mutex_(0) { }
+Mutex::~Mutex() { assert(mutex_ == 0); }
+void Mutex::Lock() { assert(--mutex_ == -1); }
+void Mutex::Unlock() { assert(mutex_++ == -1); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; }
+#endif
+void Mutex::ReaderLock() { assert(++mutex_ > 0); }
+void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
+
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+
+Mutex::Mutex() : destroy_(true) {
+ InitializeCriticalSection(&mutex_);
+ SetIsSafe();
+}
+Mutex::Mutex(LinkerInitialized) : destroy_(false) {
+ InitializeCriticalSection(&mutex_);
+ SetIsSafe();
+}
+Mutex::~Mutex() { if (destroy_) DeleteCriticalSection(&mutex_); }
+void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); }
+void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ TryEnterCriticalSection(&mutex_) != 0 : true; }
+#endif
+void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
+void Mutex::ReaderUnlock() { Unlock(); }
+
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+
+#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
+ if (is_safe_ && fncall(&mutex_) != 0) abort(); \
+} while (0)
+
+Mutex::Mutex() : destroy_(true) {
+ SetIsSafe();
+ if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
+ SetIsSafe();
+ if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ pthread_rwlock_trywrlock(&mutex_) == 0 : true; }
+#endif
+void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); }
+void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#undef SAFE_PTHREAD
+
+#elif defined(HAVE_PTHREAD)
+
+#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
+ if (is_safe_ && fncall(&mutex_) != 0) abort(); \
+} while (0)
+
+Mutex::Mutex() : destroy_(true) {
+ SetIsSafe();
+ if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {
+ SetIsSafe();
+ if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ pthread_mutex_trylock(&mutex_) == 0 : true; }
+#endif
+void Mutex::ReaderLock() { Lock(); }
+void Mutex::ReaderUnlock() { Unlock(); }
+#undef SAFE_PTHREAD
+
+#endif
+
+// --------------------------------------------------------------------------
+// Some helper classes
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class MutexLock {
+ public:
+ explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
+ ~MutexLock() { mu_->Unlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ MutexLock(const MutexLock&);
+ void operator=(const MutexLock&);
+};
+
+// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
+class ReaderMutexLock {
+ public:
+ explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
+ ~ReaderMutexLock() { mu_->ReaderUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ ReaderMutexLock(const ReaderMutexLock&);
+ void operator=(const ReaderMutexLock&);
+};
+
+class WriterMutexLock {
+ public:
+ explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
+ ~WriterMutexLock() { mu_->WriterUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ WriterMutexLock(const WriterMutexLock&);
+ void operator=(const WriterMutexLock&);
+};
+
+// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
+#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
+#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
+#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
+
+} // namespace MUTEX_NAMESPACE
+
+using namespace MUTEX_NAMESPACE;
+
+#undef MUTEX_NAMESPACE
+
+#endif /* #define GOOGLE_MUTEX_H__ */
diff --git a/extern/libmv/third_party/glog/AUTHORS b/extern/libmv/third_party/glog/AUTHORS
new file mode 100644
index 00000000000..ee92be88dcf
--- /dev/null
+++ b/extern/libmv/third_party/glog/AUTHORS
@@ -0,0 +1,2 @@
+opensource@google.com
+
diff --git a/extern/libmv/third_party/glog/COPYING b/extern/libmv/third_party/glog/COPYING
new file mode 100644
index 00000000000..38396b580b3
--- /dev/null
+++ b/extern/libmv/third_party/glog/COPYING
@@ -0,0 +1,65 @@
+Copyright (c) 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+A function gettimeofday in utilities.cc is based on
+
+http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd
+
+The license of this code is:
+
+Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/extern/libmv/third_party/glog/ChangeLog b/extern/libmv/third_party/glog/ChangeLog
new file mode 100644
index 00000000000..350fee921e3
--- /dev/null
+++ b/extern/libmv/third_party/glog/ChangeLog
@@ -0,0 +1,59 @@
+2010-06-15 Google Inc. <opensource@google.com>
+
+ * google-glog: version 0.3.1
+ * GLOG_* environment variables now work even when gflags is installed.
+ * Snow leopard support.
+ * Now we can build and test from out side tree.
+ * Add DCHECK_NOTNULL.
+ * Add ShutdownGoogleLogging to close syslog (thanks DGunchev)
+ * Fix --enable-frame-pointers option (thanks kazuki.ohta)
+ * Fix libunwind detection (thanks giantchen)
+
+2009-07-30 Google Inc. <opensource@google.com>
+
+ * google-glog: version 0.3.0
+ * Fix a deadlock happened when user uses glog with recent gflags.
+ * Suppress several unnecessary warnings (thanks keir).
+ * NetBSD and OpenBSD support.
+ * Use Win32API GetComputeNameA properly (thanks magila).
+ * Fix user name detection for Windows (thanks ademin).
+ * Fix several minor bugs.
+
+2009-04-10 Google Inc. <opensource@google.com>
+ * google-glog: version 0.2.1
+ * Fix timestamps of VC++ version.
+ * Add pkg-config support (thanks Tomasz)
+ * Fix build problem when building with gtest (thanks Michael)
+ * Add --with-gflags option for configure (thanks Michael)
+ * Fixes for GCC 4.4 (thanks John)
+
+2009-01-23 Google Inc. <opensource@google.com>
+ * google-glog: version 0.2
+ * Add initial Windows VC++ support.
+ * Google testing/mocking frameworks integration.
+ * Link pthread library automatically.
+ * Flush logs in signal handlers.
+ * Add macros LOG_TO_STRING, LOG_AT_LEVEL, DVLOG, and LOG_TO_SINK_ONLY.
+ * Log microseconds.
+ * Add --log_backtrace_at option.
+ * Fix some minor bugs.
+
+2008-11-18 Google Inc. <opensource@google.com>
+ * google-glog: version 0.1.2
+ * Add InstallFailureSignalHandler(). (satorux)
+ * Re-organize the way to produce stacktraces.
+ * Don't define unnecessary macro DISALLOW_EVIL_CONSTRUCTORS.
+
+2008-10-15 Google Inc. <opensource@google.com>
+ * google-glog: version 0.1.1
+ * Support symbolize for MacOSX 10.5.
+ * BUG FIX: --vmodule didn't work with gflags.
+ * BUG FIX: symbolize_unittest failed with GCC 4.3.
+ * Several fixes on the document.
+
+2008-10-07 Google Inc. <opensource@google.com>
+
+ * google-glog: initial release:
+ The glog package contains a library that implements application-level
+ logging. This library provides logging APIs based on C++-style
+ streams and various helper macros.
diff --git a/extern/libmv/third_party/glog/NEWS b/extern/libmv/third_party/glog/NEWS
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/extern/libmv/third_party/glog/NEWS
diff --git a/extern/libmv/third_party/glog/README b/extern/libmv/third_party/glog/README
new file mode 100644
index 00000000000..77efd37505a
--- /dev/null
+++ b/extern/libmv/third_party/glog/README
@@ -0,0 +1,5 @@
+This repository contains a C++ implementation of the Google logging
+module. Documentation for the implementation is in doc/.
+
+See INSTALL for (generic) installation instructions for C++: basically
+ ./configure && make && make install
diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv
new file mode 100644
index 00000000000..8f1243b2430
--- /dev/null
+++ b/extern/libmv/third_party/glog/README.libmv
@@ -0,0 +1,38 @@
+Project: Google Logging
+URL: http://code.google.com/p/google-glog/
+License: New BSD
+Upstream version: 0.3.1
+Local modifications:
+
+Upgrading Notes
+* Had to change #include <gflags/gflags.h> to #include "gflags/gflags.h"
+* Make sure to copy over a config_YOUR_PLATFORM.h and put it in config.h
+
+Old changes which got obsoleted (maybe?) by 0.3.1 merge:
+* The config_linux.h is generated by configure on Keir's Ubuntu 9.04 desktop.
+* Commented out some struct ::tm weirdness causing compile failures on
+ ubuntu 8.10 and 9.04.
+* Switched several initializers to memset instead of = {}.
+* Changed some includes pointing to gflags. Not sure why the regular inclusion
+ didn't work.
+* Added some compile flags to silence various warnings, allowing us to keep the
+ differences between upstream small.
+* Don't redefine _XOPEN_SOURCE.
+* Added "google::" to GetReferenceableValue in CHECK_OP_LOG.
+* Add virtual destructor to Thread in googletest.h.
+* Update windows/glog/log_severity to build with QT library that include WinGDI
+ (It cause a double definition of ERROR variable).
+
+Old changes which got obsoleted (maybe?) by 0.2.1 merge:
+* Added #ifndef / def REG_EIP; not sure what that is.
+* Added (void) arg stuff to prevent unused variable warnings.
+* Added google:: namespace prefix to GetReferencableValue
+* Added assignments for several functions marked with no_ignore_return, where
+ the return value was ignored.
+* Commented out the unused function DumpPCAndSymbol() in utilities.cc to silent
+ gcc on the mac
+
+TODO(keir): Remove any obsoleted changes above if they are not necessary after
+testing on more platforms.
+
+WARNING: Mac port not updated for 0.2.1
diff --git a/extern/libmv/third_party/glog/src/base/commandlineflags.h b/extern/libmv/third_party/glog/src/base/commandlineflags.h
new file mode 100644
index 00000000000..6c529ccd847
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/base/commandlineflags.h
@@ -0,0 +1,132 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// This file is a compatibility layer that defines Google's version of
+// command line flags that are used for configuration.
+//
+// We put flags into their own namespace. It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly. The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the
+// current namespace. The net result is to force people to use
+// DECLARE to get access to a flag, rather than saying
+// extern bool FLAGS_logtostderr;
+// or some such instead. We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want,
+// and make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+#ifndef BASE_COMMANDLINEFLAGS_H__
+#define BASE_COMMANDLINEFLAGS_H__
+
+#include "config.h"
+#include <string>
+#include <string.h> // for memchr
+#include <stdlib.h> // for getenv
+
+#ifdef HAVE_LIB_GFLAGS
+
+#include "third_party/gflags/gflags.h"
+
+#else
+
+#include "glog/logging.h"
+
+#define DECLARE_VARIABLE(type, name, tn) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
+ extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+#define DEFINE_VARIABLE(type, name, value, meaning, tn) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
+ GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \
+ char FLAGS_no##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+
+// bool specialization
+#define DECLARE_bool(name) \
+ DECLARE_VARIABLE(bool, name, bool)
+#define DEFINE_bool(name, value, meaning) \
+ DEFINE_VARIABLE(bool, name, value, meaning, bool)
+
+// int32 specialization
+#define DECLARE_int32(name) \
+ DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, name, int32)
+#define DEFINE_int32(name, value, meaning) \
+ DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, name, value, meaning, int32)
+
+// Special case for string, because we have to specify the namespace
+// std::string, which doesn't play nicely with our FLAG__namespace hackery.
+#define DECLARE_string(name) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
+ extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+#define DEFINE_string(name, value, meaning) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
+ GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name(value); \
+ char FLAGS_no##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+
+#endif // HAVE_LIB_GFLAGS
+
+// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we
+// have GLOG_* environ variables even if we have gflags installed.
+//
+// If both an environment variable and a flag are specified, the value
+// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the
+// verbosity will be 1, not 0.
+
+#define GLOG_DEFINE_bool(name, value, meaning) \
+ DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning)
+
+#define GLOG_DEFINE_int32(name, value, meaning) \
+ DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning)
+
+#define GLOG_DEFINE_string(name, value, meaning) \
+ DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning)
+
+// These macros (could be functions, but I don't want to bother with a .cc
+// file), make it easier to initialize flags from the environment.
+
+#define EnvToString(envname, dflt) \
+ (!getenv(envname) ? (dflt) : getenv(envname))
+
+#define EnvToBool(envname, dflt) \
+ (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL)
+
+#define EnvToInt(envname, dflt) \
+ (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))
+
+#endif // BASE_COMMANDLINEFLAGS_H__
diff --git a/extern/libmv/third_party/glog/src/base/googleinit.h b/extern/libmv/third_party/glog/src/base/googleinit.h
new file mode 100644
index 00000000000..c907308e852
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/base/googleinit.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Jacob Hoffman-Andrews
+
+#ifndef _GOOGLEINIT_H
+#define _GOOGLEINIT_H
+
+class GoogleInitializer {
+ public:
+ typedef void (*void_function)(void);
+ GoogleInitializer(const char* name, void_function f) {
+ f();
+ }
+};
+
+#define REGISTER_MODULE_INITIALIZER(name, body) \
+ namespace { \
+ static void google_init_module_##name () { body; } \
+ GoogleInitializer google_initializer_module_##name(#name, \
+ google_init_module_##name); \
+ }
+
+#endif /* _GOOGLEINIT_H */
diff --git a/extern/libmv/third_party/glog/src/base/mutex.h b/extern/libmv/third_party/glog/src/base/mutex.h
new file mode 100644
index 00000000000..7ba88cb5a63
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/base/mutex.h
@@ -0,0 +1,325 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: Craig Silverstein.
+//
+// A simple mutex wrapper, supporting locks and read-write locks.
+// You should assume the locks are *not* re-entrant.
+//
+// To use: you should define the following macros in your configure.ac:
+// ACX_PTHREAD
+// AC_RWLOCK
+// The latter is defined in ../autoconf.
+//
+// This class is meant to be internal-only and should be wrapped by an
+// internal namespace. Before you use this module, please give the
+// name of your internal namespace for this module. Or, if you want
+// to expose it, you'll want to move it to the Google namespace. We
+// cannot put this class in global namespace because there can be some
+// problems when we have multiple versions of Mutex in each shared object.
+//
+// NOTE: by default, we have #ifdef'ed out the TryLock() method.
+// This is for two reasons:
+// 1) TryLock() under Windows is a bit annoying (it requires a
+// #define to be defined very early).
+// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG
+// mode.
+// If you need TryLock(), and either these two caveats are not a
+// problem for you, or you're willing to work around them, then
+// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs
+// in the code below.
+//
+// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:
+// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html
+// Because of that, we might as well use windows locks for
+// cygwin. They seem to be more reliable than the cygwin pthreads layer.
+//
+// TRICKY IMPLEMENTATION NOTE:
+// This class is designed to be safe to use during
+// dynamic-initialization -- that is, by global constructors that are
+// run before main() starts. The issue in this case is that
+// dynamic-initialization happens in an unpredictable order, and it
+// could be that someone else's dynamic initializer could call a
+// function that tries to acquire this mutex -- but that all happens
+// before this mutex's constructor has run. (This can happen even if
+// the mutex and the function that uses the mutex are in the same .cc
+// file.) Basically, because Mutex does non-trivial work in its
+// constructor, it's not, in the naive implementation, safe to use
+// before dynamic initialization has run on it.
+//
+// The solution used here is to pair the actual mutex primitive with a
+// bool that is set to true when the mutex is dynamically initialized.
+// (Before that it's false.) Then we modify all mutex routines to
+// look at the bool, and not try to lock/unlock until the bool makes
+// it to true (which happens after the Mutex constructor has run.)
+//
+// This works because before main() starts -- particularly, during
+// dynamic initialization -- there are no threads, so a) it's ok that
+// the mutex operations are a no-op, since we don't need locking then
+// anyway; and b) we can be quite confident our bool won't change
+// state between a call to Lock() and a call to Unlock() (that would
+// require a global constructor in one translation unit to call Lock()
+// and another global constructor in another translation unit to call
+// Unlock() later, which is pretty perverse).
+//
+// That said, it's tricky, and can conceivably fail; it's safest to
+// avoid trying to acquire a mutex in a global constructor, if you
+// can. One way it can fail is that a really smart compiler might
+// initialize the bool to true at static-initialization time (too
+// early) rather than at dynamic-initialization time. To discourage
+// that, we set is_safe_ to true in code (not the constructor
+// colon-initializer) and set it to true via a function that always
+// evaluates to true, but that the compiler can't know always
+// evaluates to true. This should be good enough.
+
+#ifndef GOOGLE_MUTEX_H_
+#define GOOGLE_MUTEX_H_
+
+#include "config.h" // to figure out pthreads support
+
+#if defined(NO_THREADS)
+ typedef int MutexType; // to keep a lock-count
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+# define WIN32_LEAN_AND_MEAN // We only need minimal includes
+# ifdef GMUTEX_TRYLOCK
+ // We need Windows NT or later for TryEnterCriticalSection(). If you
+ // don't need that functionality, you can remove these _WIN32_WINNT
+ // lines, and change TryLock() to assert(0) or something.
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0400
+# endif
+# endif
+// To avoid macro definition of ERROR.
+# define NOGDI
+// To avoid macro definition of min/max.
+# define NOMINMAX
+# include <windows.h>
+ typedef CRITICAL_SECTION MutexType;
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+ // Needed for pthread_rwlock_*. If it causes problems, you could take it
+ // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
+ // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
+ // for locking there.)
+# ifdef __linux__
+# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
+# endif
+# include <pthread.h>
+ typedef pthread_rwlock_t MutexType;
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+ typedef pthread_mutex_t MutexType;
+#else
+# error Need to implement mutex.h for your architecture, or #define NO_THREADS
+#endif
+
+// We need to include these header files after defining _XOPEN_SOURCE
+// as they may define the _XOPEN_SOURCE macro.
+#include <assert.h>
+#include <stdlib.h> // for abort()
+
+#define MUTEX_NAMESPACE glog_internal_namespace_
+
+namespace MUTEX_NAMESPACE {
+
+class Mutex {
+ public:
+ // Create a Mutex that is not held by anybody. This constructor is
+ // typically used for Mutexes allocated on the heap or the stack.
+ // See below for a recommendation for constructing global Mutex
+ // objects.
+ inline Mutex();
+
+ // Destructor
+ inline ~Mutex();
+
+ inline void Lock(); // Block if needed until free then acquire exclusively
+ inline void Unlock(); // Release a lock acquired via Lock()
+#ifdef GMUTEX_TRYLOCK
+ inline bool TryLock(); // If free, Lock() and return true, else return false
+#endif
+ // Note that on systems that don't support read-write locks, these may
+ // be implemented as synonyms to Lock() and Unlock(). So you can use
+ // these for efficiency, but don't use them anyplace where being able
+ // to do shared reads is necessary to avoid deadlock.
+ inline void ReaderLock(); // Block until free or shared then acquire a share
+ inline void ReaderUnlock(); // Release a read share of this Mutex
+ inline void WriterLock() { Lock(); } // Acquire an exclusive lock
+ inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
+
+ // TODO(hamaji): Do nothing, implement correctly.
+ inline void AssertHeld() {}
+
+ private:
+ MutexType mutex_;
+ // We want to make sure that the compiler sets is_safe_ to true only
+ // when we tell it to, and never makes assumptions is_safe_ is
+ // always true. volatile is the most reliable way to do that.
+ volatile bool is_safe_;
+
+ inline void SetIsSafe() { is_safe_ = true; }
+
+ // Catch the error of writing Mutex when intending MutexLock.
+ Mutex(Mutex* /*ignored*/) {}
+ // Disallow "evil" constructors
+ Mutex(const Mutex&);
+ void operator=(const Mutex&);
+};
+
+// Now the implementation of Mutex for various systems
+#if defined(NO_THREADS)
+
+// When we don't have threads, we can be either reading or writing,
+// but not both. We can have lots of readers at once (in no-threads
+// mode, that's most likely to happen in recursive function calls),
+// but only one writer. We represent this by having mutex_ be -1 when
+// writing and a number > 0 when reading (and 0 when no lock is held).
+//
+// In debug mode, we assert these invariants, while in non-debug mode
+// we do nothing, for efficiency. That's why everything is in an
+// assert.
+
+Mutex::Mutex() : mutex_(0) { }
+Mutex::~Mutex() { assert(mutex_ == 0); }
+void Mutex::Lock() { assert(--mutex_ == -1); }
+void Mutex::Unlock() { assert(mutex_++ == -1); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; }
+#endif
+void Mutex::ReaderLock() { assert(++mutex_ > 0); }
+void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
+
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+
+Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); }
+Mutex::~Mutex() { DeleteCriticalSection(&mutex_); }
+void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); }
+void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ TryEnterCriticalSection(&mutex_) != 0 : true; }
+#endif
+void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
+void Mutex::ReaderUnlock() { Unlock(); }
+
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+
+#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
+ if (is_safe_ && fncall(&mutex_) != 0) abort(); \
+} while (0)
+
+Mutex::Mutex() {
+ SetIsSafe();
+ if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ pthread_rwlock_trywrlock(&mutex_) == 0 :
+ true; }
+#endif
+void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); }
+void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#undef SAFE_PTHREAD
+
+#elif defined(HAVE_PTHREAD)
+
+#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \
+ if (is_safe_ && fncall(&mutex_) != 0) abort(); \
+} while (0)
+
+Mutex::Mutex() {
+ SetIsSafe();
+ if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock() { return is_safe_ ?
+ pthread_mutex_trylock(&mutex_) == 0 : true; }
+#endif
+void Mutex::ReaderLock() { Lock(); }
+void Mutex::ReaderUnlock() { Unlock(); }
+#undef SAFE_PTHREAD
+
+#endif
+
+// --------------------------------------------------------------------------
+// Some helper classes
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class MutexLock {
+ public:
+ explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
+ ~MutexLock() { mu_->Unlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ MutexLock(const MutexLock&);
+ void operator=(const MutexLock&);
+};
+
+// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
+class ReaderMutexLock {
+ public:
+ explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
+ ~ReaderMutexLock() { mu_->ReaderUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ ReaderMutexLock(const ReaderMutexLock&);
+ void operator=(const ReaderMutexLock&);
+};
+
+class WriterMutexLock {
+ public:
+ explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
+ ~WriterMutexLock() { mu_->WriterUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ WriterMutexLock(const WriterMutexLock&);
+ void operator=(const WriterMutexLock&);
+};
+
+// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
+#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
+#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
+#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
+
+} // namespace MUTEX_NAMESPACE
+
+using namespace MUTEX_NAMESPACE;
+
+#undef MUTEX_NAMESPACE
+
+#endif /* #define GOOGLE_MUTEX_H__ */
diff --git a/extern/libmv/third_party/glog/src/config.h b/extern/libmv/third_party/glog/src/config.h
new file mode 100644
index 00000000000..06ed686f87c
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/config.h
@@ -0,0 +1,13 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Namespace for Google classes */
+#ifdef __APPLE__
+ #include "config_mac.h"
+#elif __MINGW32__
+ #include "windows/config.h"
+#elif __GNUC__
+ #include "config_linux.h"
+#elif _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
new file mode 100644
index 00000000000..df6956c9ecf
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/config_linux.h
@@ -0,0 +1,164 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE google
+
+/* Define if you have the `dladdr' function */
+/* #undef HAVE_DLADDR */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#define HAVE_EXECINFO_H 1
+
+/* Define if you have the `fcntl' function */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <glob.h> header file. */
+#define HAVE_GLOB_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the <libunwind.h> header file. */
+/* #undef HAVE_LIBUNWIND_H */
+
+/* define if you have google gflags library */
+#define HAVE_LIB_GFLAGS 1
+
+/* define if you have google gmock library */
+/* #undef HAVE_LIB_GMOCK */
+
+/* define if you have google gtest library */
+/* #undef HAVE_LIB_GTEST */
+
+/* define if you have libunwind */
+/* #undef HAVE_LIB_UNWIND */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* define if the compiler implements pthread_rwlock_* */
+#define HAVE_RWLOCK 1
+
+/* Define if you have the `sigaltstack' function */
+#define HAVE_SIGALTSTACK 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <syscall.h> header file. */
+#define HAVE_SYSCALL_H 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#define HAVE_SYS_SYSCALL_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/ucontext.h> header file. */
+#define HAVE_SYS_UCONTEXT_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <ucontext.h> header file. */
+#define HAVE_UCONTEXT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* define if the compiler supports using expression for operator */
+#define HAVE_USING_OPERATOR 1
+
+/* define if your compiler has __attribute__ */
+#define HAVE___ATTRIBUTE__ 1
+
+/* define if your compiler has __builtin_expect */
+#define HAVE___BUILTIN_EXPECT 1
+
+/* define if your compiler has __sync_val_compare_and_swap */
+/* #undef HAVE___SYNC_VAL_COMPARE_AND_SWAP */
+
+/* Name of package */
+#define PACKAGE "glog"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "opensource@google.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "glog"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "glog 0.3.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "glog"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.3.1"
+
+/* How to access the PC from a struct ucontext */
+#if defined(_M_X64) || defined(__amd64__)
+ #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP]
+#else
+ #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP]
+#endif
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* The size of `void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 8
+
+/* Define to 1 if you have the ANSI C header files. */
+/* #undef STDC_HEADERS */
+
+#define STDC_HEADERS 1
+/* the namespace where STL code like vector<> is defined */
+#define STL_NAMESPACE std
+
+/* location of source code */
+#define TEST_SRC_DIR "."
+
+/* Version number of package */
+#define VERSION "0.3.1"
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
diff --git a/extern/libmv/third_party/glog/src/config_mac.h b/extern/libmv/third_party/glog/src/config_mac.h
new file mode 100644
index 00000000000..5f953d17ba9
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/config_mac.h
@@ -0,0 +1,159 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE google
+
+/* Define if you have the `dladdr' function */
+#define HAVE_DLADDR 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#define HAVE_EXECINFO_H 1
+
+/* Define if you have the `fcntl' function */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <glob.h> header file. */
+#define HAVE_GLOB_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the <libunwind.h> header file. */
+#define HAVE_LIBUNWIND_H 1
+
+/* define if you have google gflags library */
+#define HAVE_LIB_GFLAGS 1
+
+/* define if you have google gmock library */
+/* #undef HAVE_LIB_GMOCK */
+
+/* define if you have google gtest library */
+//#define HAVE_LIB_GTEST 1
+
+/* define if you have libunwind */
+/* #undef HAVE_LIB_UNWIND */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* define if the compiler implements pthread_rwlock_* */
+#define HAVE_RWLOCK 1
+
+/* Define if you have the `sigaltstack' function */
+#define HAVE_SIGALTSTACK 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <syscall.h> header file. */
+/* #undef HAVE_SYSCALL_H */
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#define HAVE_SYS_SYSCALL_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/ucontext.h> header file. */
+#define HAVE_SYS_UCONTEXT_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <ucontext.h> header file. */
+/* #undef HAVE_UCONTEXT_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* define if the compiler supports using expression for operator */
+#define HAVE_USING_OPERATOR 1
+
+/* define if your compiler has __attribute__ */
+#define HAVE___ATTRIBUTE__ 1
+
+/* define if your compiler has __builtin_expect */
+#define HAVE___BUILTIN_EXPECT 1
+
+/* define if your compiler has __sync_val_compare_and_swap */
+/* #undef HAVE___SYNC_VAL_COMPARE_AND_SWAP */
+
+/* Name of package */
+#define PACKAGE "glog"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "opensource@google.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "glog"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "glog 0.3.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "glog"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.3.1"
+
+/* How to access the PC from a struct ucontext */
+#undef PC_FROM_UCONTEXT
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* The size of `void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 8
+
+/* Define to 1 if you have the ANSI C header files. */
+/* #undef STDC_HEADERS */
+
+/* the namespace where STL code like vector<> is defined */
+#define STL_NAMESPACE std
+
+/* location of source code */
+#define TEST_SRC_DIR "."
+
+/* Version number of package */
+#define VERSION "0.3.1"
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
diff --git a/extern/libmv/third_party/glog/src/demangle.cc b/extern/libmv/third_party/glog/src/demangle.cc
new file mode 100644
index 00000000000..46556bf3c13
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/demangle.cc
@@ -0,0 +1,1231 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+
+#include <stdio.h> // for NULL
+#include "demangle.h"
+
+_START_GOOGLE_NAMESPACE_
+
+typedef struct {
+ const char *abbrev;
+ const char *real_name;
+} AbbrevPair;
+
+// List of operators from Itanium C++ ABI.
+static const AbbrevPair kOperatorList[] = {
+ { "nw", "new" },
+ { "na", "new[]" },
+ { "dl", "delete" },
+ { "da", "delete[]" },
+ { "ps", "+" },
+ { "ng", "-" },
+ { "ad", "&" },
+ { "de", "*" },
+ { "co", "~" },
+ { "pl", "+" },
+ { "mi", "-" },
+ { "ml", "*" },
+ { "dv", "/" },
+ { "rm", "%" },
+ { "an", "&" },
+ { "or", "|" },
+ { "eo", "^" },
+ { "aS", "=" },
+ { "pL", "+=" },
+ { "mI", "-=" },
+ { "mL", "*=" },
+ { "dV", "/=" },
+ { "rM", "%=" },
+ { "aN", "&=" },
+ { "oR", "|=" },
+ { "eO", "^=" },
+ { "ls", "<<" },
+ { "rs", ">>" },
+ { "lS", "<<=" },
+ { "rS", ">>=" },
+ { "eq", "==" },
+ { "ne", "!=" },
+ { "lt", "<" },
+ { "gt", ">" },
+ { "le", "<=" },
+ { "ge", ">=" },
+ { "nt", "!" },
+ { "aa", "&&" },
+ { "oo", "||" },
+ { "pp", "++" },
+ { "mm", "--" },
+ { "cm", "," },
+ { "pm", "->*" },
+ { "pt", "->" },
+ { "cl", "()" },
+ { "ix", "[]" },
+ { "qu", "?" },
+ { "st", "sizeof" },
+ { "sz", "sizeof" },
+ { NULL, NULL },
+};
+
+// List of builtin types from Itanium C++ ABI.
+static const AbbrevPair kBuiltinTypeList[] = {
+ { "v", "void" },
+ { "w", "wchar_t" },
+ { "b", "bool" },
+ { "c", "char" },
+ { "a", "signed char" },
+ { "h", "unsigned char" },
+ { "s", "short" },
+ { "t", "unsigned short" },
+ { "i", "int" },
+ { "j", "unsigned int" },
+ { "l", "long" },
+ { "m", "unsigned long" },
+ { "x", "long long" },
+ { "y", "unsigned long long" },
+ { "n", "__int128" },
+ { "o", "unsigned __int128" },
+ { "f", "float" },
+ { "d", "double" },
+ { "e", "long double" },
+ { "g", "__float128" },
+ { "z", "ellipsis" },
+ { NULL, NULL }
+};
+
+// List of substitutions Itanium C++ ABI.
+static const AbbrevPair kSubstitutionList[] = {
+ { "St", "" },
+ { "Sa", "allocator" },
+ { "Sb", "basic_string" },
+ // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
+ { "Ss", "string"},
+ // std::basic_istream<char, std::char_traits<char> >
+ { "Si", "istream" },
+ // std::basic_ostream<char, std::char_traits<char> >
+ { "So", "ostream" },
+ // std::basic_iostream<char, std::char_traits<char> >
+ { "Sd", "iostream" },
+ { NULL, NULL }
+};
+
+// State needed for demangling.
+typedef struct {
+ const char *mangled_cur; // Cursor of mangled name.
+ const char *mangled_end; // End of mangled name.
+ char *out_cur; // Cursor of output string.
+ const char *out_begin; // Beginning of output string.
+ const char *out_end; // End of output string.
+ const char *prev_name; // For constructors/destructors.
+ int prev_name_length; // For constructors/destructors.
+ int nest_level; // For nested names.
+ int number; // Remember the previous number.
+ bool append; // Append flag.
+ bool overflowed; // True if output gets overflowed.
+} State;
+
+// We don't use strlen() in libc since it's not guaranteed to be async
+// signal safe.
+static size_t StrLen(const char *str) {
+ size_t len = 0;
+ while (*str != '\0') {
+ ++str;
+ ++len;
+ }
+ return len;
+}
+
+// Returns true if "str" has "prefix" as a prefix.
+static bool StrPrefix(const char *str, const char *prefix) {
+ size_t i = 0;
+ while (str[i] != '\0' && prefix[i] != '\0' &&
+ str[i] == prefix[i]) {
+ ++i;
+ }
+ return prefix[i] == '\0'; // Consumed everything in "prefix".
+}
+
+static void InitState(State *state, const char *mangled,
+ char *out, int out_size) {
+ state->mangled_cur = mangled;
+ state->mangled_end = mangled + StrLen(mangled);
+ state->out_cur = out;
+ state->out_begin = out;
+ state->out_end = out + out_size;
+ state->prev_name = NULL;
+ state->prev_name_length = -1;
+ state->nest_level = -1;
+ state->number = -1;
+ state->append = true;
+ state->overflowed = false;
+}
+
+// Calculates the remaining length of the mangled name.
+static int RemainingLength(State *state) {
+ return state->mangled_end - state->mangled_cur;
+}
+
+// Returns true and advances "mangled_cur" if we find "c" at
+// "mangled_cur" position.
+static bool ParseChar(State *state, const char c) {
+ if (RemainingLength(state) >= 1 && *state->mangled_cur == c) {
+ ++state->mangled_cur;
+ return true;
+ }
+ return false;
+}
+
+// Returns true and advances "mangled_cur" if we find "two_chars" at
+// "mangled_cur" position.
+static bool ParseTwoChar(State *state, const char *two_chars) {
+ if (RemainingLength(state) >= 2 &&
+ state->mangled_cur[0] == two_chars[0] &&
+ state->mangled_cur[1] == two_chars[1]) {
+ state->mangled_cur += 2;
+ return true;
+ }
+ return false;
+}
+
+// Returns true and advances "mangled_cur" if we find any character in
+// "char_class" at "mangled_cur" position.
+static bool ParseCharClass(State *state, const char *char_class) {
+ if (state->mangled_cur == state->mangled_end) {
+ return false;
+ }
+ const char *p = char_class;
+ for (; *p != '\0'; ++p) {
+ if (*state->mangled_cur == *p) {
+ state->mangled_cur += 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+// This function is used for handling an optional non-terminal.
+static bool Optional(bool status) {
+ return true;
+}
+
+// This function is used for handling <non-terminal>+ syntax.
+typedef bool (*ParseFunc)(State *);
+static bool OneOrMore(ParseFunc parse_func, State *state) {
+ if (parse_func(state)) {
+ while (parse_func(state)) {
+ }
+ return true;
+ }
+ return false;
+}
+
+// Append "str" at "out_cur". If there is an overflow, "overflowed"
+// is set to true for later use. The output string is ensured to
+// always terminate with '\0' as long as there is no overflow.
+static void Append(State *state, const char * const str, const int length) {
+ int i;
+ for (i = 0; i < length; ++i) {
+ if (state->out_cur + 1 < state->out_end) { // +1 for '\0'
+ *state->out_cur = str[i];
+ ++state->out_cur;
+ } else {
+ state->overflowed = true;
+ break;
+ }
+ }
+ if (!state->overflowed) {
+ *state->out_cur = '\0'; // Terminate it with '\0'
+ }
+}
+
+// We don't use equivalents in libc to avoid locale issues.
+static bool IsLower(char c) {
+ return c >= 'a' && c <= 'z';
+}
+
+static bool IsAlpha(char c) {
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+}
+
+// Append "str" with some tweaks, iff "append" state is true.
+// Returns true so that it can be placed in "if" conditions.
+static void MaybeAppendWithLength(State *state, const char * const str,
+ const int length) {
+ if (state->append && length > 0) {
+ // Append a space if the output buffer ends with '<' and "str"
+ // starts with '<' to avoid <<<.
+ if (str[0] == '<' && state->out_begin < state->out_cur &&
+ state->out_cur[-1] == '<') {
+ Append(state, " ", 1);
+ }
+ // Remember the last identifier name for ctors/dtors.
+ if (IsAlpha(str[0]) || str[0] == '_') {
+ state->prev_name = state->out_cur;
+ state->prev_name_length = length;
+ }
+ Append(state, str, length);
+ }
+}
+
+// A convenient wrapper arount MaybeAppendWithLength().
+static bool MaybeAppend(State *state, const char * const str) {
+ if (state->append) {
+ int length = StrLen(str);
+ MaybeAppendWithLength(state, str, length);
+ }
+ return true;
+}
+
+// This function is used for handling nested names.
+static bool EnterNestedName(State *state) {
+ state->nest_level = 0;
+ return true;
+}
+
+// This function is used for handling nested names.
+static bool LeaveNestedName(State *state, int prev_value) {
+ state->nest_level = prev_value;
+ return true;
+}
+
+// Disable the append mode not to print function parameters, etc.
+static bool DisableAppend(State *state) {
+ state->append = false;
+ return true;
+}
+
+// Restore the append mode to the previous state.
+static bool RestoreAppend(State *state, bool prev_value) {
+ state->append = prev_value;
+ return true;
+}
+
+// Increase the nest level for nested names.
+static void MaybeIncreaseNestLevel(State *state) {
+ if (state->nest_level > -1) {
+ ++state->nest_level;
+ }
+}
+
+// Appends :: for nested names if necessary.
+static void MaybeAppendSeparator(State *state) {
+ if (state->nest_level >= 1) {
+ MaybeAppend(state, "::");
+ }
+}
+
+// Cancel the last separator if necessary.
+static void MaybeCancelLastSeparator(State *state) {
+ if (state->nest_level >= 1 && state->append &&
+ state->out_begin <= state->out_cur - 2) {
+ state->out_cur -= 2;
+ *state->out_cur = '\0';
+ }
+}
+
+// Returns true if identifier pointed by "mangled_cur" is anonymous
+// namespace.
+static bool IdentifierIsAnonymousNamespace(State *state) {
+ const char anon_prefix[] = "_GLOBAL__N_";
+ return (state->number > sizeof(anon_prefix) - 1 && // Should be longer.
+ StrPrefix(state->mangled_cur, anon_prefix));
+}
+
+// Forward declarations of our parsing functions.
+static bool ParseMangledName(State *state);
+static bool ParseEncoding(State *state);
+static bool ParseName(State *state);
+static bool ParseUnscopedName(State *state);
+static bool ParseUnscopedTemplateName(State *state);
+static bool ParseNestedName(State *state);
+static bool ParsePrefix(State *state);
+static bool ParseUnqualifiedName(State *state);
+static bool ParseSourceName(State *state);
+static bool ParseLocalSourceName(State *state);
+static bool ParseNumber(State *state);
+static bool ParseFloatNumber(State *state);
+static bool ParseSeqId(State *state);
+static bool ParseIdentifier(State *state);
+static bool ParseOperatorName(State *state);
+static bool ParseSpecialName(State *state);
+static bool ParseCallOffset(State *state);
+static bool ParseNVOffset(State *state);
+static bool ParseVOffset(State *state);
+static bool ParseCtorDtorName(State *state);
+static bool ParseType(State *state);
+static bool ParseCVQualifiers(State *state);
+static bool ParseBuiltinType(State *state);
+static bool ParseFunctionType(State *state);
+static bool ParseBareFunctionType(State *state);
+static bool ParseClassEnumType(State *state);
+static bool ParseArrayType(State *state);
+static bool ParsePointerToMemberType(State *state);
+static bool ParseTemplateParam(State *state);
+static bool ParseTemplateTemplateParam(State *state);
+static bool ParseTemplateArgs(State *state);
+static bool ParseTemplateArg(State *state);
+static bool ParseExpression(State *state);
+static bool ParseExprPrimary(State *state);
+static bool ParseLocalName(State *state);
+static bool ParseDiscriminator(State *state);
+static bool ParseSubstitution(State *state);
+
+// Implementation note: the following code is a straightforward
+// translation of the Itanium C++ ABI defined in BNF with a couple of
+// exceptions.
+//
+// - Support GNU extensions not defined in the Itanium C++ ABI
+// - <prefix> and <template-prefix> are combined to avoid infinite loop
+// - Reorder patterns to shorten the code
+// - Reorder patterns to give greedier functions precedence
+// We'll mark "Less greedy than" for these cases in the code
+//
+// Each parsing function changes the state and returns true on
+// success. Otherwise, don't change the state and returns false. To
+// ensure that the state isn't changed in the latter case, we save the
+// original state before we call more than one parsing functions
+// consecutively with &&, and restore the state if unsuccessful. See
+// ParseEncoding() as an example of this convention. We follow the
+// convention throughout the code.
+//
+// Originally we tried to do demangling without following the full ABI
+// syntax but it turned out we needed to follow the full syntax to
+// parse complicated cases like nested template arguments. Note that
+// implementing a full-fledged demangler isn't trivial (libiberty's
+// cp-demangle.c has +4300 lines).
+//
+// Note that (foo) in <(foo) ...> is a modifier to be ignored.
+//
+// Reference:
+// - Itanium C++ ABI
+// <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
+
+// <mangled-name> ::= _Z <encoding>
+static bool ParseMangledName(State *state) {
+ if (ParseTwoChar(state, "_Z") && ParseEncoding(state)) {
+ // Append trailing version suffix if any.
+ // ex. _Z3foo@@GLIBCXX_3.4
+ if (state->mangled_cur < state->mangled_end &&
+ state->mangled_cur[0] == '@') {
+ MaybeAppend(state, state->mangled_cur);
+ state->mangled_cur = state->mangled_end;
+ }
+ return true;
+ }
+ return false;
+}
+
+// <encoding> ::= <(function) name> <bare-function-type>
+// ::= <(data) name>
+// ::= <special-name>
+static bool ParseEncoding(State *state) {
+ State copy = *state;
+ if (ParseName(state) && ParseBareFunctionType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseName(state) || ParseSpecialName(state)) {
+ return true;
+ }
+ return false;
+}
+
+// <name> ::= <nested-name>
+// ::= <unscoped-template-name> <template-args>
+// ::= <unscoped-name>
+// ::= <local-name>
+static bool ParseName(State *state) {
+ if (ParseNestedName(state) || ParseLocalName(state)) {
+ return true;
+ }
+
+ State copy = *state;
+ if (ParseUnscopedTemplateName(state) &&
+ ParseTemplateArgs(state)) {
+ return true;
+ }
+ *state = copy;
+
+ // Less greedy than <unscoped-template-name> <template-args>.
+ if (ParseUnscopedName(state)) {
+ return true;
+ }
+ return false;
+}
+
+// <unscoped-name> ::= <unqualified-name>
+// ::= St <unqualified-name>
+static bool ParseUnscopedName(State *state) {
+ if (ParseUnqualifiedName(state)) {
+ return true;
+ }
+
+ State copy = *state;
+ if (ParseTwoChar(state, "St") &&
+ MaybeAppend(state, "std::") &&
+ ParseUnqualifiedName(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <unscoped-template-name> ::= <unscoped-name>
+// ::= <substitution>
+static bool ParseUnscopedTemplateName(State *state) {
+ return ParseUnscopedName(state) || ParseSubstitution(state);
+}
+
+// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
+// ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+static bool ParseNestedName(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'N') &&
+ EnterNestedName(state) &&
+ Optional(ParseCVQualifiers(state)) &&
+ ParsePrefix(state) &&
+ LeaveNestedName(state, copy.nest_level) &&
+ ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// This part is tricky. If we literally translate them to code, we'll
+// end up infinite loop. Hence we merge them to avoid the case.
+//
+// <prefix> ::= <prefix> <unqualified-name>
+// ::= <template-prefix> <template-args>
+// ::= <template-param>
+// ::= <substitution>
+// ::= # empty
+// <template-prefix> ::= <prefix> <(template) unqualified-name>
+// ::= <template-param>
+// ::= <substitution>
+static bool ParsePrefix(State *state) {
+ bool has_something = false;
+ while (true) {
+ MaybeAppendSeparator(state);
+ if (ParseTemplateParam(state) ||
+ ParseSubstitution(state) ||
+ ParseUnscopedName(state)) {
+ has_something = true;
+ MaybeIncreaseNestLevel(state);
+ continue;
+ }
+ MaybeCancelLastSeparator(state);
+ if (has_something && ParseTemplateArgs(state)) {
+ return ParsePrefix(state);
+ } else {
+ break;
+ }
+ }
+ return true;
+}
+
+// <unqualified-name> ::= <operator-name>
+// ::= <ctor-dtor-name>
+// ::= <source-name>
+// ::= <local-source-name>
+static bool ParseUnqualifiedName(State *state) {
+ return (ParseOperatorName(state) ||
+ ParseCtorDtorName(state) ||
+ ParseSourceName(state) ||
+ ParseLocalSourceName(state));
+}
+
+// <source-name> ::= <positive length number> <identifier>
+static bool ParseSourceName(State *state) {
+ State copy = *state;
+ if (ParseNumber(state) && ParseIdentifier(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <local-source-name> ::= L <source-name> [<discriminator>]
+//
+// References:
+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
+// http://gcc.gnu.org/viewcvs?view=rev&revision=124467
+static bool ParseLocalSourceName(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'L') && ParseSourceName(state) &&
+ Optional(ParseDiscriminator(state))) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <number> ::= [n] <non-negative decimal integer>
+static bool ParseNumber(State *state) {
+ int sign = 1;
+ if (ParseChar(state, 'n')) {
+ sign = -1;
+ }
+ const char *p = state->mangled_cur;
+ int number = 0;
+ for (;p < state->mangled_end; ++p) {
+ if ((*p >= '0' && *p <= '9')) {
+ number = number * 10 + (*p - '0');
+ } else {
+ break;
+ }
+ }
+ if (p != state->mangled_cur) { // Conversion succeeded.
+ state->mangled_cur = p;
+ state->number = number * sign;
+ return true;
+ }
+ return false;
+}
+
+// Floating-point literals are encoded using a fixed-length lowercase
+// hexadecimal string.
+static bool ParseFloatNumber(State *state) {
+ const char *p = state->mangled_cur;
+ int number = 0;
+ for (;p < state->mangled_end; ++p) {
+ if ((*p >= '0' && *p <= '9')) {
+ number = number * 16 + (*p - '0');
+ } else if (*p >= 'a' && *p <= 'f') {
+ number = number * 16 + (*p - 'a' + 10);
+ } else {
+ break;
+ }
+ }
+ if (p != state->mangled_cur) { // Conversion succeeded.
+ state->mangled_cur = p;
+ state->number = number;
+ return true;
+ }
+ return false;
+}
+
+// The <seq-id> is a sequence number in base 36,
+// using digits and upper case letters
+static bool ParseSeqId(State *state) {
+ const char *p = state->mangled_cur;
+ int number = 0;
+ for (;p < state->mangled_end; ++p) {
+ if ((*p >= '0' && *p <= '9')) {
+ number = number * 36 + (*p - '0');
+ } else if (*p >= 'A' && *p <= 'Z') {
+ number = number * 36 + (*p - 'A' + 10);
+ } else {
+ break;
+ }
+ }
+ if (p != state->mangled_cur) { // Conversion succeeded.
+ state->mangled_cur = p;
+ state->number = number;
+ return true;
+ }
+ return false;
+}
+
+// <identifier> ::= <unqualified source code identifier>
+static bool ParseIdentifier(State *state) {
+ if (state->number == -1 ||
+ RemainingLength(state) < state->number) {
+ return false;
+ }
+ if (IdentifierIsAnonymousNamespace(state)) {
+ MaybeAppend(state, "(anonymous namespace)");
+ } else {
+ MaybeAppendWithLength(state, state->mangled_cur, state->number);
+ }
+ state->mangled_cur += state->number;
+ state->number = -1; // Reset the number.
+ return true;
+}
+
+// <operator-name> ::= nw, and other two letters cases
+// ::= cv <type> # (cast)
+// ::= v <digit> <source-name> # vendor extended operator
+static bool ParseOperatorName(State *state) {
+ if (RemainingLength(state) < 2) {
+ return false;
+ }
+ // First check with "cv" (cast) case.
+ State copy = *state;
+ if (ParseTwoChar(state, "cv") &&
+ MaybeAppend(state, "operator ") &&
+ EnterNestedName(state) &&
+ ParseType(state) &&
+ LeaveNestedName(state, copy.nest_level)) {
+ return true;
+ }
+ *state = copy;
+
+ // Then vendor extended operators.
+ if (ParseChar(state, 'v') && ParseCharClass(state, "0123456789") &&
+ ParseSourceName(state)) {
+ return true;
+ }
+ *state = copy;
+
+ // Other operator names should start with a lower alphabet followed
+ // by a lower/upper alphabet.
+ if (!(IsLower(state->mangled_cur[0]) &&
+ IsAlpha(state->mangled_cur[1]))) {
+ return false;
+ }
+ // We may want to perform a binary search if we really need speed.
+ const AbbrevPair *p;
+ for (p = kOperatorList; p->abbrev != NULL; ++p) {
+ if (state->mangled_cur[0] == p->abbrev[0] &&
+ state->mangled_cur[1] == p->abbrev[1]) {
+ MaybeAppend(state, "operator");
+ if (IsLower(*p->real_name)) { // new, delete, etc.
+ MaybeAppend(state, " ");
+ }
+ MaybeAppend(state, p->real_name);
+ state->mangled_cur += 2;
+ return true;
+ }
+ }
+ return false;
+}
+
+// <special-name> ::= TV <type>
+// ::= TT <type>
+// ::= TI <type>
+// ::= TS <type>
+// ::= Tc <call-offset> <call-offset> <(base) encoding>
+// ::= GV <(object) name>
+// ::= T <call-offset> <(base) encoding>
+// G++ extensions:
+// ::= TC <type> <(offset) number> _ <(base) type>
+// ::= TF <type>
+// ::= TJ <type>
+// ::= GR <name>
+// ::= GA <encoding>
+// ::= Th <call-offset> <(base) encoding>
+// ::= Tv <call-offset> <(base) encoding>
+//
+// Note: we don't care much about them since they don't appear in
+// stack traces. The are special data.
+static bool ParseSpecialName(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'T') &&
+ ParseCharClass(state, "VTIS") &&
+ ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "Tc") && ParseCallOffset(state) &&
+ ParseCallOffset(state) && ParseEncoding(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "GV") &&
+ ParseName(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'T') && ParseCallOffset(state) &&
+ ParseEncoding(state)) {
+ return true;
+ }
+ *state = copy;
+
+ // G++ extensions
+ if (ParseTwoChar(state, "TC") && ParseType(state) &&
+ ParseNumber(state) && ParseChar(state, '_') &&
+ DisableAppend(state) &&
+ ParseType(state)) {
+ RestoreAppend(state, copy.append);
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'T') && ParseCharClass(state, "FJ") &&
+ ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "GR") && ParseName(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "GA") && ParseEncoding(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'T') && ParseCharClass(state, "hv") &&
+ ParseCallOffset(state) && ParseEncoding(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <call-offset> ::= h <nv-offset> _
+// ::= v <v-offset> _
+static bool ParseCallOffset(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'h') &&
+ ParseNVOffset(state) && ParseChar(state, '_')) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'v') &&
+ ParseVOffset(state) && ParseChar(state, '_')) {
+ return true;
+ }
+ *state = copy;
+
+ return false;
+}
+
+// <nv-offset> ::= <(offset) number>
+static bool ParseNVOffset(State *state) {
+ return ParseNumber(state);
+}
+
+// <v-offset> ::= <(offset) number> _ <(virtual offset) number>
+static bool ParseVOffset(State *state) {
+ State copy = *state;
+ if (ParseNumber(state) && ParseChar(state, '_') &&
+ ParseNumber(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <ctor-dtor-name> ::= C1 | C2 | C3
+// ::= D0 | D1 | D2
+static bool ParseCtorDtorName(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'C') &&
+ ParseCharClass(state, "123")) {
+ const char * const prev_name = state->prev_name;
+ const int prev_name_length = state->prev_name_length;
+ MaybeAppendWithLength(state, prev_name, prev_name_length);
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'D') &&
+ ParseCharClass(state, "012")) {
+ const char * const prev_name = state->prev_name;
+ const int prev_name_length = state->prev_name_length;
+ MaybeAppend(state, "~");
+ MaybeAppendWithLength(state, prev_name, prev_name_length);
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <type> ::= <CV-qualifiers> <type>
+// ::= P <type>
+// ::= R <type>
+// ::= C <type>
+// ::= G <type>
+// ::= U <source-name> <type>
+// ::= <builtin-type>
+// ::= <function-type>
+// ::= <class-enum-type>
+// ::= <array-type>
+// ::= <pointer-to-member-type>
+// ::= <template-template-param> <template-args>
+// ::= <template-param>
+// ::= <substitution>
+static bool ParseType(State *state) {
+ // We should check CV-qualifers, and PRGC things first.
+ State copy = *state;
+ if (ParseCVQualifiers(state) && ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseCharClass(state, "PRCG") && ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'U') && ParseSourceName(state) &&
+ ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseBuiltinType(state) ||
+ ParseFunctionType(state) ||
+ ParseClassEnumType(state) ||
+ ParseArrayType(state) ||
+ ParsePointerToMemberType(state) ||
+ ParseSubstitution(state)) {
+ return true;
+ }
+
+ if (ParseTemplateTemplateParam(state) &&
+ ParseTemplateArgs(state)) {
+ return true;
+ }
+ *state = copy;
+
+ // Less greedy than <template-template-param> <template-args>.
+ if (ParseTemplateParam(state)) {
+ return true;
+ }
+
+ return false;
+}
+
+// <CV-qualifiers> ::= [r] [V] [K]
+// We don't allow empty <CV-qualifiers> to avoid infinite loop in
+// ParseType().
+static bool ParseCVQualifiers(State *state) {
+ int num_cv_qualifiers = 0;
+ num_cv_qualifiers += ParseChar(state, 'r');
+ num_cv_qualifiers += ParseChar(state, 'V');
+ num_cv_qualifiers += ParseChar(state, 'K');
+ return num_cv_qualifiers > 0;
+}
+
+// <builtin-type> ::= v, etc.
+// ::= u <source-name>
+static bool ParseBuiltinType(State *state) {
+ const AbbrevPair *p;
+ for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) {
+ if (state->mangled_cur[0] == p->abbrev[0]) {
+ MaybeAppend(state, p->real_name);
+ ++state->mangled_cur;
+ return true;
+ }
+ }
+
+ State copy = *state;
+ if (ParseChar(state, 'u') && ParseSourceName(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <function-type> ::= F [Y] <bare-function-type> E
+static bool ParseFunctionType(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'F') && Optional(ParseChar(state, 'Y')) &&
+ ParseBareFunctionType(state) && ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <bare-function-type> ::= <(signature) type>+
+static bool ParseBareFunctionType(State *state) {
+ State copy = *state;
+ DisableAppend(state);
+ if (OneOrMore(ParseType, state)) {
+ RestoreAppend(state, copy.append);
+ MaybeAppend(state, "()");
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <class-enum-type> ::= <name>
+static bool ParseClassEnumType(State *state) {
+ return ParseName(state);
+}
+
+// <array-type> ::= A <(positive dimension) number> _ <(element) type>
+// ::= A [<(dimension) expression>] _ <(element) type>
+static bool ParseArrayType(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'A') && ParseNumber(state) &&
+ ParseChar(state, '_') && ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'A') && Optional(ParseExpression(state)) &&
+ ParseChar(state, '_') && ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <pointer-to-member-type> ::= M <(class) type> <(member) type>
+static bool ParsePointerToMemberType(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'M') && ParseType(state) &&
+ ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <template-param> ::= T_
+// ::= T <parameter-2 non-negative number> _
+static bool ParseTemplateParam(State *state) {
+ if (ParseTwoChar(state, "T_")) {
+ MaybeAppend(state, "?"); // We don't support template substitutions.
+ return true;
+ }
+
+ State copy = *state;
+ if (ParseChar(state, 'T') && ParseNumber(state) &&
+ ParseChar(state, '_')) {
+ MaybeAppend(state, "?"); // We don't support template substitutions.
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+
+// <template-template-param> ::= <template-param>
+// ::= <substitution>
+static bool ParseTemplateTemplateParam(State *state) {
+ return (ParseTemplateParam(state) ||
+ ParseSubstitution(state));
+}
+
+// <template-args> ::= I <template-arg>+ E
+static bool ParseTemplateArgs(State *state) {
+ State copy = *state;
+ DisableAppend(state);
+ if (ParseChar(state, 'I') &&
+ OneOrMore(ParseTemplateArg, state) &&
+ ParseChar(state, 'E')) {
+ RestoreAppend(state, copy.append);
+ MaybeAppend(state, "<>");
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <template-arg> ::= <type>
+// ::= <expr-primary>
+// ::= X <expression> E
+static bool ParseTemplateArg(State *state) {
+ if (ParseType(state) ||
+ ParseExprPrimary(state)) {
+ return true;
+ }
+
+ State copy = *state;
+ if (ParseChar(state, 'X') && ParseExpression(state) &&
+ ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <expression> ::= <template-param>
+// ::= <expr-primary>
+// ::= <unary operator-name> <expression>
+// ::= <binary operator-name> <expression> <expression>
+// ::= <trinary operator-name> <expression> <expression>
+// <expression>
+// ::= st <type>
+// ::= sr <type> <unqualified-name> <template-args>
+// ::= sr <type> <unqualified-name>
+static bool ParseExpression(State *state) {
+ if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
+ return true;
+ }
+
+ State copy = *state;
+ if (ParseOperatorName(state) &&
+ ParseExpression(state) &&
+ ParseExpression(state) &&
+ ParseExpression(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseOperatorName(state) &&
+ ParseExpression(state) &&
+ ParseExpression(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseOperatorName(state) &&
+ ParseExpression(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "st") && ParseType(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "sr") && ParseType(state) &&
+ ParseUnqualifiedName(state) &&
+ ParseTemplateArgs(state)) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "sr") && ParseType(state) &&
+ ParseUnqualifiedName(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <expr-primary> ::= L <type> <(value) number> E
+// ::= L <type> <(value) float> E
+// ::= L <mangled-name> E
+// // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
+// ::= LZ <encoding> E
+static bool ParseExprPrimary(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'L') && ParseType(state) &&
+ ParseNumber(state) &&
+ ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'L') && ParseType(state) &&
+ ParseFloatNumber(state) &&
+ ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'L') && ParseMangledName(state) &&
+ ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseTwoChar(state, "LZ") && ParseEncoding(state) &&
+ ParseChar(state, 'E')) {
+ return true;
+ }
+ *state = copy;
+
+ return false;
+}
+
+// <local-name> := Z <(function) encoding> E <(entity) name>
+// [<discriminator>]
+// := Z <(function) encoding> E s [<discriminator>]
+static bool ParseLocalName(State *state) {
+ State copy = *state;
+ if (ParseChar(state, 'Z') && ParseEncoding(state) &&
+ ParseChar(state, 'E') && MaybeAppend(state, "::") &&
+ ParseName(state) && Optional(ParseDiscriminator(state))) {
+ return true;
+ }
+ *state = copy;
+
+ if (ParseChar(state, 'Z') && ParseEncoding(state) &&
+ ParseTwoChar(state, "Es") && Optional(ParseDiscriminator(state))) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <discriminator> := _ <(non-negative) number>
+static bool ParseDiscriminator(State *state) {
+ State copy = *state;
+ if (ParseChar(state, '_') && ParseNumber(state)) {
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <substitution> ::= S_
+// ::= S <seq-id> _
+// ::= St, etc.
+static bool ParseSubstitution(State *state) {
+ if (ParseTwoChar(state, "S_")) {
+ MaybeAppend(state, "?"); // We don't support substitutions.
+ return true;
+ }
+
+ State copy = *state;
+ if (ParseChar(state, 'S') && ParseSeqId(state) &&
+ ParseChar(state, '_')) {
+ MaybeAppend(state, "?"); // We don't support substitutions.
+ return true;
+ }
+ *state = copy;
+
+ // Expand abbreviations like "St" => "std".
+ if (ParseChar(state, 'S')) {
+ const AbbrevPair *p;
+ for (p = kSubstitutionList; p->abbrev != NULL; ++p) {
+ if (state->mangled_cur[0] == p->abbrev[1]) {
+ MaybeAppend(state, "std");
+ if (p->real_name[0] != '\0') {
+ MaybeAppend(state, "::");
+ MaybeAppend(state, p->real_name);
+ }
+ state->mangled_cur += 1;
+ return true;
+ }
+ }
+ }
+ *state = copy;
+ return false;
+}
+
+// The demangler entry point.
+bool Demangle(const char *mangled, char *out, int out_size) {
+ State state;
+ InitState(&state, mangled, out, out_size);
+ return (ParseMangledName(&state) &&
+ state.overflowed == false &&
+ RemainingLength(&state) == 0);
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/demangle.h b/extern/libmv/third_party/glog/src/demangle.h
new file mode 100644
index 00000000000..9c7591527c0
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/demangle.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// An async-signal-safe and thread-safe demangler for Itanium C++ ABI
+// (aka G++ V3 ABI).
+
+// The demangler is implemented to be used in async signal handlers to
+// symbolize stack traces. We cannot use libstdc++'s
+// abi::__cxa_demangle() in such signal handlers since it's not async
+// signal safe (it uses malloc() internally).
+//
+// Note that this demangler doesn't support full demangling. More
+// specifically, it doesn't print types of function parameters and
+// types of template arguments. It just skips them. However, it's
+// still very useful to extract basic information such as class,
+// function, constructor, destructor, and operator names.
+//
+// See the implementation note in demangle.cc if you are interested.
+//
+// Example:
+//
+// | Mangled Name | The Demangler | abi::__cxa_demangle()
+// |---------------|---------------|-----------------------
+// | _Z1fv | f() | f()
+// | _Z1fi | f() | f(int)
+// | _Z3foo3bar | foo() | foo(bar)
+// | _Z1fIiEvi | f<>() | void f<int>(int)
+// | _ZN1N1fE | N::f | N::f
+// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar()
+// | _Zrm1XS_" | operator%() | operator%(X, X)
+// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo()
+// | _Z1fSs | f() | f(std::basic_string<char,
+// | | | std::char_traits<char>,
+// | | | std::allocator<char> >)
+//
+// See the unit test for more examples.
+//
+// Note: we might want to write demanglers for ABIs other than Itanium
+// C++ ABI in the future.
+//
+
+#ifndef BASE_DEMANGLE_H_
+#define BASE_DEMANGLE_H_
+
+#include "config.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Demangle "mangled". On success, return true and write the
+// demangled symbol name to "out". Otherwise, return false.
+// "out" is modified even if demangling is unsuccessful.
+bool Demangle(const char *mangled, char *out, int out_size);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif // BASE_DEMANGLE_H_
diff --git a/extern/libmv/third_party/glog/src/glog/log_severity.h b/extern/libmv/third_party/glog/src/glog/log_severity.h
new file mode 100644
index 00000000000..17805fbadd4
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/glog/log_severity.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef BASE_LOG_SEVERITY_H__
+#define BASE_LOG_SEVERITY_H__
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// Variables of type LogSeverity are widely taken to lie in the range
+// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if
+// you ever need to change their values or add a new severity.
+typedef int LogSeverity;
+
+const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4;
+
+// DFATAL is FATAL in debug mode, ERROR in normal mode
+#ifdef NDEBUG
+#define DFATAL_LEVEL ERROR
+#else
+#define DFATAL_LEVEL FATAL
+#endif
+
+extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES];
+
+// NDEBUG usage helpers related to (RAW_)DCHECK:
+//
+// DEBUG_MODE is for small !NDEBUG uses like
+// if (DEBUG_MODE) foo.CheckThatFoo();
+// instead of substantially more verbose
+// #ifndef NDEBUG
+// foo.CheckThatFoo();
+// #endif
+//
+// IF_DEBUG_MODE is for small !NDEBUG uses like
+// IF_DEBUG_MODE( string error; )
+// DCHECK(Foo(&error)) << error;
+// instead of substantially more verbose
+// #ifndef NDEBUG
+// string error;
+// DCHECK(Foo(&error)) << error;
+// #endif
+//
+#ifdef NDEBUG
+enum { DEBUG_MODE = 0 };
+#define IF_DEBUG_MODE(x)
+#else
+enum { DEBUG_MODE = 1 };
+#define IF_DEBUG_MODE(x) x
+#endif
+
+#endif // BASE_LOG_SEVERITY_H__
diff --git a/extern/libmv/third_party/glog/src/glog/logging.h b/extern/libmv/third_party/glog/src/glog/logging.h
new file mode 100644
index 00000000000..a58d478ab17
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/glog/logging.h
@@ -0,0 +1,1507 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney
+//
+// This file contains #include information about logging-related stuff.
+// Pretty much everybody needs to #include this file so that they can
+// log various happenings.
+//
+
+#ifndef _LOGGING_H_
+#define _LOGGING_H_
+
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <string>
+#if 1
+# include <unistd.h>
+#endif
+#ifdef __DEPRECATED
+// Make GCC quiet.
+# undef __DEPRECATED
+# include <strstream>
+# define __DEPRECATED
+#else
+# include <strstream>
+#endif
+#include <vector>
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// We care a lot about number of bits things take up. Unfortunately,
+// systems define their bit-specific ints in a lot of different ways.
+// We use our own way, and have a typedef to get there.
+// Note: these commands below may look like "#if 1" or "#if 0", but
+// that's because they were constructed that way at ./configure time.
+// Look at logging.h.in to see how they're calculated (based on your config).
+#if 1
+#include <stdint.h> // the normal place uint16_t is defined
+#endif
+#if 1
+#include <sys/types.h> // the normal place u_int16_t is defined
+#endif
+#if 1
+#include <inttypes.h> // a third place for uint16_t or u_int16_t
+#endif
+
+#if 1
+#include "third_party/gflags/gflags.h"
+#endif
+
+namespace google {
+
+#if 1 // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 1 // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 0 // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+
+}
+
+// The global value of GOOGLE_STRIP_LOG. All the messages logged to
+// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed.
+// If it can be determined at compile time that the message will not be
+// printed, the statement will be compiled out.
+//
+// Example: to strip out all INFO and WARNING messages, use the value
+// of 2 below. To make an exception for WARNING messages from a single
+// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including
+// base/logging.h
+#ifndef GOOGLE_STRIP_LOG
+#define GOOGLE_STRIP_LOG 0
+#endif
+
+// GCC can be told that a certain branch is not likely to be taken (for
+// instance, a CHECK failure), and use that information in static analysis.
+// Giving it this information can help it optimize for the common case in
+// the absence of better information (ie. -fprofile-arcs).
+//
+#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
+#if 1
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
+#else
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
+#endif
+#endif
+
+// Make a bunch of macros for logging. The way to log things is to stream
+// things to LOG(<a particular severity level>). E.g.,
+//
+// LOG(INFO) << "Found " << num_cookies << " cookies";
+//
+// You can capture log messages in a string, rather than reporting them
+// immediately:
+//
+// vector<string> errors;
+// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num;
+//
+// This pushes back the new error onto 'errors'; if given a NULL pointer,
+// it reports the error via LOG(ERROR).
+//
+// You can also do conditional logging:
+//
+// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// You can also do occasional logging (log every n'th occurrence of an
+// event):
+//
+// LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";
+//
+// The above will cause log messages to be output on the 1st, 11th, 21st, ...
+// times it is executed. Note that the special COUNTER value is used to
+// identify which repetition is happening.
+//
+// You can also do occasional conditional logging (log every n'th
+// occurrence of an event, when condition is satisfied):
+//
+// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER
+// << "th big cookie";
+//
+// You can log messages the first N times your code executes a line. E.g.
+//
+// LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie";
+//
+// Outputs log messages for the first 20 times it is executed.
+//
+// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available.
+// These log to syslog as well as to the normal logs. If you use these at
+// all, you need to be aware that syslog can drastically reduce performance,
+// especially if it is configured for remote logging! Don't use these
+// unless you fully understand this and have a concrete need to use them.
+// Even then, try to minimize your use of them.
+//
+// There are also "debug mode" logging macros like the ones above:
+//
+// DLOG(INFO) << "Found cookies";
+//
+// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";
+//
+// All "debug mode" logging is compiled away to nothing for non-debug mode
+// compiles.
+//
+// We also have
+//
+// LOG_ASSERT(assertion);
+// DLOG_ASSERT(assertion);
+//
+// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
+//
+// There are "verbose level" logging macros. They look like
+//
+// VLOG(1) << "I'm printed when you run the program with --v=1 or more";
+// VLOG(2) << "I'm printed when you run the program with --v=2 or more";
+//
+// These always log at the INFO log level (when they log at all).
+// The verbose logging can also be turned on module-by-module. For instance,
+// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
+// will cause:
+// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc}
+// b. VLOG(1) and lower messages to be printed from file.{h,cc}
+// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs"
+// d. VLOG(0) and lower messages to be printed from elsewhere
+//
+// The wildcarding functionality shown by (c) supports both '*' (match
+// 0 or more characters) and '?' (match any single character) wildcards.
+//
+// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
+//
+// if (VLOG_IS_ON(2)) {
+// // do some logging preparation and logging
+// // that can't be accomplished with just VLOG(2) << ...;
+// }
+//
+// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level"
+// condition macros for sample cases, when some extra computation and
+// preparation for logs is not needed.
+// VLOG_IF(1, (size > 1024))
+// << "I'm printed when size is more than 1024 and when you run the "
+// "program with --v=1 or more";
+// VLOG_EVERY_N(1, 10)
+// << "I'm printed every 10th occurrence, and when you run the program "
+// "with --v=1 or more. Present occurence is " << COUNTER;
+// VLOG_IF_EVERY_N(1, (size > 1024), 10)
+// << "I'm printed on every 10th occurence of case when size is more "
+// " than 1024, when you run the program with --v=1 or more. ";
+// "Present occurence is " << COUNTER;
+//
+// The supported severity levels for macros that allow you to specify one
+// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
+// Note that messages of a given severity are logged not only in the
+// logfile for that severity, but also in all logfiles of lower severity.
+// E.g., a message of severity FATAL will be logged to the logfiles of
+// severity FATAL, ERROR, WARNING, and INFO.
+//
+// There is also the special severity of DFATAL, which logs FATAL in
+// debug mode, ERROR in normal mode.
+//
+// Very important: logging a message at the FATAL severity level causes
+// the program to terminate (after the message is logged).
+//
+// Unless otherwise specified, logs will be written to the filename
+// "<program name>.<hostname>.<user name>.log.<severity level>.", followed
+// by the date, time, and pid (you can't prevent the date, time, and pid
+// from being in the filename).
+//
+// The logging code takes two flags:
+// --v=# set the verbose level
+// --logtostderr log all the messages to stderr instead of to logfiles
+
+// LOG LINE PREFIX FORMAT
+//
+// Log lines have this form:
+//
+// Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
+//
+// where the fields are defined as follows:
+//
+// L A single character, representing the log level
+// (eg 'I' for INFO)
+// mm The month (zero padded; ie May is '05')
+// dd The day (zero padded)
+// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
+// threadid The space-padded thread ID as returned by GetTID()
+// (this matches the PID on Linux)
+// file The file name
+// line The line number
+// msg The user-supplied message
+//
+// Example:
+//
+// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog
+// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395
+//
+// NOTE: although the microseconds are useful for comparing events on
+// a single machine, clocks on different machines may not be well
+// synchronized. Hence, use caution when comparing the low bits of
+// timestamps from different machines.
+
+#ifndef DECLARE_VARIABLE
+#define MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#define DECLARE_VARIABLE(type, name, tn) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
+ extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+
+// bool specialization
+#define DECLARE_bool(name) \
+ DECLARE_VARIABLE(bool, name, bool)
+
+// int32 specialization
+#define DECLARE_int32(name) \
+ DECLARE_VARIABLE(google::int32, name, int32)
+
+// Special case for string, because we have to specify the namespace
+// std::string, which doesn't play nicely with our FLAG__namespace hackery.
+#define DECLARE_string(name) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
+ extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+#endif
+
+// Set whether log messages go to stderr instead of logfiles
+DECLARE_bool(logtostderr);
+
+// Set whether log messages go to stderr in addition to logfiles.
+DECLARE_bool(alsologtostderr);
+
+// Log messages at a level >= this flag are automatically sent to
+// stderr in addition to log files.
+DECLARE_int32(stderrthreshold);
+
+// Set whether the log prefix should be prepended to each line of output.
+DECLARE_bool(log_prefix);
+
+// Log messages at a level <= this flag are buffered.
+// Log messages at a higher level are flushed immediately.
+DECLARE_int32(logbuflevel);
+
+// Sets the maximum number of seconds which logs may be buffered for.
+DECLARE_int32(logbufsecs);
+
+// Log suppression level: messages logged at a lower level than this
+// are suppressed.
+DECLARE_int32(minloglevel);
+
+// If specified, logfiles are written into this directory instead of the
+// default logging directory.
+DECLARE_string(log_dir);
+
+// Sets the path of the directory into which to put additional links
+// to the log files.
+DECLARE_string(log_link);
+
+DECLARE_int32(v); // in vlog_is_on.cc
+
+// Sets the maximum log file size (in MB).
+DECLARE_int32(max_log_size);
+
+// Sets whether to avoid logging to the disk if the disk is full.
+DECLARE_bool(stop_logging_if_full_disk);
+
+#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef DECLARE_VARIABLE
+#undef DECLARE_bool
+#undef DECLARE_int32
+#undef DECLARE_string
+#endif
+
+// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
+// security reasons. See LOG(severtiy) below.
+
+// A few definitions of macros that don't generate much code. Since
+// LOG(INFO) and its ilk are used all over our code, it's
+// better to have compact code for these operations.
+
+#if GOOGLE_STRIP_LOG == 0
+#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \
+ __FILE__, __LINE__)
+#define LOG_TO_STRING_INFO(message) google::LogMessage( \
+ __FILE__, __LINE__, google::INFO, message)
+#else
+#define COMPACT_GOOGLE_LOG_INFO google::NullStream()
+#define LOG_TO_STRING_INFO(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 1
+#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \
+ __FILE__, __LINE__, google::WARNING)
+#define LOG_TO_STRING_WARNING(message) google::LogMessage( \
+ __FILE__, __LINE__, google::WARNING, message)
+#else
+#define COMPACT_GOOGLE_LOG_WARNING google::NullStream()
+#define LOG_TO_STRING_WARNING(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 2
+#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \
+ __FILE__, __LINE__, google::ERROR)
+#define LOG_TO_STRING_ERROR(message) google::LogMessage( \
+ __FILE__, __LINE__, google::ERROR, message)
+#else
+#define COMPACT_GOOGLE_LOG_ERROR google::NullStream()
+#define LOG_TO_STRING_ERROR(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \
+ __FILE__, __LINE__)
+#define LOG_TO_STRING_FATAL(message) google::LogMessage( \
+ __FILE__, __LINE__, google::FATAL, message)
+#else
+#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal()
+#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal()
+#endif
+
+// For DFATAL, we want to use LogMessage (as opposed to
+// LogMessageFatal), to be consistent with the original behavior.
+#ifdef NDEBUG
+#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
+#elif GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \
+ __FILE__, __LINE__, google::FATAL)
+#else
+#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal()
+#endif
+
+#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::INFO, counter, &google::LogMessage::SendToLog)
+#define SYSLOG_INFO(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::INFO, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_WARNING(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_WARNING(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_ERROR(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_ERROR(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_FATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_FATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_DFATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_DFATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
+// A very useful logging macro to log windows errors:
+#define LOG_SYSRESULT(result) \
+ if (FAILED(result)) { \
+ LPTSTR message = NULL; \
+ LPTSTR msg = reinterpret_cast<LPTSTR>(&message); \
+ DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
+ FORMAT_MESSAGE_FROM_SYSTEM, \
+ 0, result, 0, msg, 100, NULL); \
+ if (message_length > 0) { \
+ google::LogMessage(__FILE__, __LINE__, ERROR, 0, \
+ &google::LogMessage::SendToLog).stream() << message; \
+ LocalFree(message); \
+ } \
+ }
+#endif
+
+// We use the preprocessor's merging operator, "##", so that, e.g.,
+// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny
+// subtle difference between ostream member streaming functions (e.g.,
+// ostream::operator<<(int) and ostream non-member streaming functions
+// (e.g., ::operator<<(ostream&, string&): it turns out that it's
+// impossible to stream something like a string directly to an unnamed
+// ostream. We employ a neat hack by calling the stream() member
+// function of LogMessage which seems to avoid the problem.
+#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
+#define SYSLOG(severity) SYSLOG_ ## severity(0).stream()
+
+namespace google {
+
+// They need the definitions of integer types.
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Initialize google's logging library. You will see the program name
+// specified by argv0 in log outputs.
+GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0);
+
+// Shutdown google's logging library.
+GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging();
+
+// Install a function which will be called after LOG(FATAL).
+GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)());
+
+class LogSink; // defined below
+
+// If a non-NULL sink pointer is given, we push this message to that sink.
+// For LOG_TO_SINK we then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and passing/storing them
+// somewhere more specific than the global log of the process.
+// Argument types:
+// LogSink* sink;
+// LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+#define LOG_TO_SINK(sink, severity) \
+ google::LogMessage( \
+ __FILE__, __LINE__, \
+ google::severity, \
+ static_cast<google::LogSink*>(sink), true).stream()
+#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \
+ google::LogMessage( \
+ __FILE__, __LINE__, \
+ google::severity, \
+ static_cast<google::LogSink*>(sink), false).stream()
+
+// If a non-NULL string pointer is given, we write this message to that string.
+// We then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and storing them somewhere more
+// specific than the global log of the process.
+// Argument types:
+// string* message;
+// LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+// NOTE: LOG(severity) expands to LogMessage().stream() for the specified
+// severity.
+#define LOG_TO_STRING(severity, message) \
+ LOG_TO_STRING_##severity(static_cast<string*>(message)).stream()
+
+// If a non-NULL pointer is given, we push the message onto the end
+// of a vector of strings; otherwise, we report it with LOG(severity).
+// This is handy for capturing messages and perhaps passing them back
+// to the caller, rather than reporting them immediately.
+// Argument types:
+// LogSeverity severity;
+// vector<string> *outvec;
+// The cast is to disambiguate NULL arguments.
+#define LOG_STRING(severity, outvec) \
+ LOG_TO_STRING_##severity(static_cast<vector<string>*>(outvec)).stream()
+
+#define LOG_IF(severity, condition) \
+ !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+#define SYSLOG_IF(severity, condition) \
+ !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity)
+
+#define LOG_ASSERT(condition) \
+ LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+#define SYSLOG_ASSERT(condition) \
+ SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+
+// CHECK dies with a fatal error if condition is not true. It is *not*
+// controlled by NDEBUG, so the check will be executed regardless of
+// compilation mode. Therefore, it is safe to do things like:
+// CHECK(fp->Write(x) == 4)
+#define CHECK(condition) \
+ LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+ << "Check failed: " #condition " "
+
+// A container for a string pointer which can be evaluated to a bool -
+// true iff the pointer is NULL.
+struct CheckOpString {
+ CheckOpString(std::string* str) : str_(str) { }
+ // No destructor: if str_ is non-NULL, we're about to LOG(FATAL),
+ // so there's no point in cleaning up str_.
+ operator bool() const {
+ return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL);
+ }
+ std::string* str_;
+};
+
+// Function is overloaded for integral types to allow static const
+// integrals declared in classes and not defined to be used as arguments to
+// CHECK* macros. It's not encouraged though.
+template <class T>
+inline const T& GetReferenceableValue(const T& t) { return t; }
+inline char GetReferenceableValue(char t) { return t; }
+inline unsigned char GetReferenceableValue(unsigned char t) { return t; }
+inline signed char GetReferenceableValue(signed char t) { return t; }
+inline short GetReferenceableValue(short t) { return t; }
+inline unsigned short GetReferenceableValue(unsigned short t) { return t; }
+inline int GetReferenceableValue(int t) { return t; }
+inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
+inline long GetReferenceableValue(long t) { return t; }
+inline unsigned long GetReferenceableValue(unsigned long t) { return t; }
+inline long long GetReferenceableValue(long long t) { return t; }
+inline unsigned long long GetReferenceableValue(unsigned long long t) {
+ return t;
+}
+
+// This is a dummy class to define the following operator.
+struct DummyClassToDefineOperator {};
+
+}
+
+// Define global operator<< to declare using ::operator<<.
+// This declaration will allow use to use CHECK macros for user
+// defined classes which have operator<< (e.g., stl_logging.h).
+inline std::ostream& operator<<(
+ std::ostream& out, const google::DummyClassToDefineOperator&) {
+ return out;
+}
+
+namespace google {
+
+// Build the error message string.
+template<class t1, class t2>
+std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
+ // It means that we cannot use stl_logging if compiler doesn't
+ // support using expression for operator.
+ // TODO(hamaji): Figure out a way to fix.
+#if 1
+ using ::operator<<;
+#endif
+ std::strstream ss;
+ ss << names << " (" << v1 << " vs. " << v2 << ")";
+ return new std::string(ss.str(), ss.pcount());
+}
+
+// Helper functions for CHECK_OP macro.
+// The (int, int) specialization works around the issue that the compiler
+// will not instantiate the template version of the function on values of
+// unnamed enum type - see comment below.
+#define DEFINE_CHECK_OP_IMPL(name, op) \
+ template <class t1, class t2> \
+ inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
+ const char* names) { \
+ if (v1 op v2) return NULL; \
+ else return MakeCheckOpString(v1, v2, names); \
+ } \
+ inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
+ return Check##name##Impl<int, int>(v1, v2, names); \
+ }
+
+// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h
+// provides its own #defines for the simpler names EQ, NE, LE, etc.
+// This happens if, for example, those are used as token names in a
+// yacc grammar.
+DEFINE_CHECK_OP_IMPL(_EQ, ==)
+DEFINE_CHECK_OP_IMPL(_NE, !=)
+DEFINE_CHECK_OP_IMPL(_LE, <=)
+DEFINE_CHECK_OP_IMPL(_LT, < )
+DEFINE_CHECK_OP_IMPL(_GE, >=)
+DEFINE_CHECK_OP_IMPL(_GT, > )
+#undef DEFINE_CHECK_OP_IMPL
+
+// Helper macro for binary operators.
+// Don't use this macro directly in your code, use CHECK_EQ et al below.
+
+#if defined(STATIC_ANALYSIS)
+// Only for static analysis tool to know that it is equivalent to assert
+#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2))
+#elif !defined(NDEBUG)
+// In debug mode, avoid constructing CheckOpStrings if possible,
+// to reduce the overhead of CHECK statments by 2x.
+// Real DCHECK-heavy tests have seen 1.5x speedups.
+
+// The meaning of "string" might be different between now and
+// when this macro gets invoked (e.g., if someone is experimenting
+// with other string implementations that get defined after this
+// file is included). Save the current meaning now and use it
+// in the macro.
+typedef std::string _Check_string;
+#define CHECK_OP_LOG(name, op, val1, val2, log) \
+ while (google::_Check_string* _result = \
+ google::Check##name##Impl( \
+ google::GetReferenceableValue(val1), \
+ google::GetReferenceableValue(val2), \
+ #val1 " " #op " " #val2)) \
+ log(__FILE__, __LINE__, \
+ google::CheckOpString(_result)).stream()
+#else
+// In optimized mode, use CheckOpString to hint to compiler that
+// the while condition is unlikely.
+#define CHECK_OP_LOG(name, op, val1, val2, log) \
+ while (google::CheckOpString _result = \
+ google::Check##name##Impl( \
+ google::GetReferenceableValue(val1), \
+ google::GetReferenceableValue(val2), \
+ #val1 " " #op " " #val2)) \
+ log(__FILE__, __LINE__, _result).stream()
+#endif // STATIC_ANALYSIS, !NDEBUG
+
+#if GOOGLE_STRIP_LOG <= 3
+#define CHECK_OP(name, op, val1, val2) \
+ CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal)
+#else
+#define CHECK_OP(name, op, val1, val2) \
+ CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal)
+#endif // STRIP_LOG <= 3
+
+// Equality/Inequality checks - compare two values, and log a FATAL message
+// including the two values when the result is not as expected. The values
+// must have operator<<(ostream, ...) defined.
+//
+// You may append to the error message like so:
+// CHECK_NE(1, 2) << ": The world must be ending!";
+//
+// We are very careful to ensure that each argument is evaluated exactly
+// once, and that anything which is legal to pass as a function argument is
+// legal here. In particular, the arguments may be temporary expressions
+// which will end up being destroyed at the end of the apparent statement,
+// for example:
+// CHECK_EQ(string("abc")[1], 'b');
+//
+// WARNING: These don't compile correctly if one of the arguments is a pointer
+// and the other is NULL. To work around this, simply static_cast NULL to the
+// type of the desired pointer.
+
+#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2)
+#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2)
+#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2)
+#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2)
+#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2)
+#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2)
+
+// Check that the input is non NULL. This very useful in constructor
+// initializer lists.
+
+#define CHECK_NOTNULL(val) \
+ google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
+
+// Helper functions for string comparisons.
+// To avoid bloat, the definitions are in logging.cc.
+#define DECLARE_CHECK_STROP_IMPL(func, expected) \
+ GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \
+ const char* s1, const char* s2, const char* names);
+DECLARE_CHECK_STROP_IMPL(strcmp, true)
+DECLARE_CHECK_STROP_IMPL(strcmp, false)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
+#undef DECLARE_CHECK_STROP_IMPL
+
+// Helper macro for string comparisons.
+// Don't use this macro directly in your code, use CHECK_STREQ et al below.
+#define CHECK_STROP(func, op, expected, s1, s2) \
+ while (google::CheckOpString _result = \
+ google::Check##func##expected##Impl((s1), (s2), \
+ #s1 " " #op " " #s2)) \
+ LOG(FATAL) << *_result.str_
+
+
+// String (char*) equality/inequality checks.
+// CASE versions are case-insensitive.
+//
+// Note that "s1" and "s2" may be temporary strings which are destroyed
+// by the compiler at the end of the current "full expression"
+// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())).
+
+#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2)
+#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2)
+#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2)
+
+#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0])))
+#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0])))
+
+#define CHECK_DOUBLE_EQ(val1, val2) \
+ do { \
+ CHECK_LE((val1), (val2)+0.000000000000001L); \
+ CHECK_GE((val1), (val2)-0.000000000000001L); \
+ } while (0)
+
+#define CHECK_NEAR(val1, val2, margin) \
+ do { \
+ CHECK_LE((val1), (val2)+(margin)); \
+ CHECK_GE((val1), (val2)-(margin)); \
+ } while (0)
+
+// perror()..googly style!
+//
+// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and
+// CHECK equivalents with the addition that they postpend a description
+// of the current state of errno to their output lines.
+
+#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream()
+
+#define GOOGLE_PLOG(severity, counter) \
+ google::ErrnoLogMessage( \
+ __FILE__, __LINE__, google::severity, counter, \
+ &google::LogMessage::SendToLog)
+
+#define PLOG_IF(severity, condition) \
+ !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity)
+
+// A CHECK() macro that postpends errno if the condition is false. E.g.
+//
+// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... }
+#define PCHECK(condition) \
+ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+ << "Check failed: " #condition " "
+
+// A CHECK() macro that lets you assert the success of a function that
+// returns -1 and sets errno in case of an error. E.g.
+//
+// CHECK_ERR(mkdir(path, 0700));
+//
+// or
+//
+// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename;
+#define CHECK_ERR(invocation) \
+PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \
+ << #invocation
+
+// Use macro expansion to create, for each use of LOG_EVERY_N(), static
+// variables with the __LINE__ expansion as part of the variable name.
+#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line)
+#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line
+
+#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
+#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
+
+#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+ ++LOG_OCCURRENCES; \
+ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+ if (LOG_OCCURRENCES_MOD_N == 1) \
+ google::LogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+ ++LOG_OCCURRENCES; \
+ if (condition && \
+ ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \
+ google::LogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+ ++LOG_OCCURRENCES; \
+ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+ if (LOG_OCCURRENCES_MOD_N == 1) \
+ google::ErrnoLogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0; \
+ if (LOG_OCCURRENCES <= n) \
+ ++LOG_OCCURRENCES; \
+ if (LOG_OCCURRENCES <= n) \
+ google::LogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+namespace glog_internal_namespace_ {
+template <bool>
+struct CompileAssert {
+};
+struct CrashReason;
+} // namespace glog_internal_namespace_
+
+#define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \
+ typedef google::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
+
+#define LOG_EVERY_N(severity, n) \
+ GOOGLE_GLOG_COMPILE_ASSERT(google::severity < \
+ google::NUM_SEVERITIES, \
+ INVALID_REQUESTED_LOG_SEVERITY); \
+ SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog)
+
+#define SYSLOG_EVERY_N(severity, n) \
+ SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog)
+
+#define PLOG_EVERY_N(severity, n) \
+ SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog)
+
+#define LOG_FIRST_N(severity, n) \
+ SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog)
+
+#define LOG_IF_EVERY_N(severity, condition, n) \
+ SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog)
+
+// We want the special COUNTER value available for LOG_EVERY_X()'ed messages
+enum PRIVATE_Counter {COUNTER};
+
+
+// Plus some debug-logging macros that get compiled to nothing for production
+
+#ifndef NDEBUG
+
+#define DLOG(severity) LOG(severity)
+#define DVLOG(verboselevel) VLOG(verboselevel)
+#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
+#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+ LOG_IF_EVERY_N(severity, condition, n)
+#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
+
+// debug-only checking. not executed in NDEBUG mode.
+#define DCHECK(condition) CHECK(condition)
+#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
+#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
+#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
+#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
+#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
+#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
+#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
+#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
+#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
+#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
+#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
+
+#else // NDEBUG
+
+#define DLOG(severity) \
+ true ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DVLOG(verboselevel) \
+ (true || !VLOG_IS_ON(verboselevel)) ?\
+ (void) 0 : google::LogMessageVoidify() & LOG(INFO)
+
+#define DLOG_IF(severity, condition) \
+ (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_EVERY_N(severity, n) \
+ true ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+ (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_ASSERT(condition) \
+ true ? (void) 0 : LOG_ASSERT(condition)
+
+#define DCHECK(condition) \
+ while (false) \
+ CHECK(condition)
+
+#define DCHECK_EQ(val1, val2) \
+ while (false) \
+ CHECK_EQ(val1, val2)
+
+#define DCHECK_NE(val1, val2) \
+ while (false) \
+ CHECK_NE(val1, val2)
+
+#define DCHECK_LE(val1, val2) \
+ while (false) \
+ CHECK_LE(val1, val2)
+
+#define DCHECK_LT(val1, val2) \
+ while (false) \
+ CHECK_LT(val1, val2)
+
+#define DCHECK_GE(val1, val2) \
+ while (false) \
+ CHECK_GE(val1, val2)
+
+#define DCHECK_GT(val1, val2) \
+ while (false) \
+ CHECK_GT(val1, val2)
+
+#define DCHECK_NOTNULL(val) (val)
+
+#define DCHECK_STREQ(str1, str2) \
+ while (false) \
+ CHECK_STREQ(str1, str2)
+
+#define DCHECK_STRCASEEQ(str1, str2) \
+ while (false) \
+ CHECK_STRCASEEQ(str1, str2)
+
+#define DCHECK_STRNE(str1, str2) \
+ while (false) \
+ CHECK_STRNE(str1, str2)
+
+#define DCHECK_STRCASENE(str1, str2) \
+ while (false) \
+ CHECK_STRCASENE(str1, str2)
+
+
+#endif // NDEBUG
+
+// Log only in verbose mode.
+
+#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
+
+#define VLOG_IF(verboselevel, condition) \
+ LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
+
+#define VLOG_EVERY_N(verboselevel, n) \
+ LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n)
+
+#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
+ LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
+
+//
+// This class more or less represents a particular log message. You
+// create an instance of LogMessage and then stream stuff to it.
+// When you finish streaming to it, ~LogMessage is called and the
+// full message gets streamed to the appropriate destination.
+//
+// You shouldn't actually use LogMessage's constructor to log things,
+// though. You should use the LOG() macro (and variants thereof)
+// above.
+class GOOGLE_GLOG_DLL_DECL LogMessage {
+public:
+ enum {
+ // Passing kNoLogPrefix for the line number disables the
+ // log-message prefix. Useful for using the LogMessage
+ // infrastructure as a printing utility. See also the --log_prefix
+ // flag for controlling the log-message prefix on an
+ // application-wide basis.
+ kNoLogPrefix = -1
+ };
+
+ // LogStream inherit from non-DLL-exported class (std::ostrstream)
+ // and VC++ produces a warning for this situation.
+ // However, MSDN says "C4275 can be ignored in Microsoft Visual C++
+ // 2005 if you are deriving from a type in the Standard C++ Library"
+ // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
+ // Let's just ignore the warning.
+#ifdef _MSC_VER
+# pragma warning(disable: 4275)
+#endif
+ class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream {
+#ifdef _MSC_VER
+# pragma warning(default: 4275)
+#endif
+ public:
+ LogStream(char *buf, int len, int ctr)
+ : ostrstream(buf, len),
+ ctr_(ctr) {
+ self_ = this;
+ }
+
+ int ctr() const { return ctr_; }
+ void set_ctr(int ctr) { ctr_ = ctr; }
+ LogStream* self() const { return self_; }
+
+ private:
+ int ctr_; // Counter hack (for the LOG_EVERY_X() macro)
+ LogStream *self_; // Consistency check hack
+ };
+
+public:
+ // icc 8 requires this typedef to avoid an internal compiler error.
+ typedef void (LogMessage::*SendMethod)();
+
+ LogMessage(const char* file, int line, LogSeverity severity, int ctr,
+ SendMethod send_method);
+
+ // Two special constructors that generate reduced amounts of code at
+ // LOG call sites for common cases.
+
+ // Used for LOG(INFO): Implied are:
+ // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog.
+ //
+ // Using this constructor instead of the more complex constructor above
+ // saves 19 bytes per call site.
+ LogMessage(const char* file, int line);
+
+ // Used for LOG(severity) where severity != INFO. Implied
+ // are: ctr = 0, send_method = &LogMessage::SendToLog
+ //
+ // Using this constructor instead of the more complex constructor above
+ // saves 17 bytes per call site.
+ LogMessage(const char* file, int line, LogSeverity severity);
+
+ // Constructor to log this message to a specified sink (if not NULL).
+ // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if
+ // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise.
+ LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink,
+ bool also_send_to_log);
+
+ // Constructor where we also give a vector<string> pointer
+ // for storing the messages (if the pointer is not NULL).
+ // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog.
+ LogMessage(const char* file, int line, LogSeverity severity,
+ std::vector<std::string>* outvec);
+
+ // Constructor where we also give a string pointer for storing the
+ // message (if the pointer is not NULL). Implied are: ctr = 0,
+ // send_method = &LogMessage::WriteToStringAndLog.
+ LogMessage(const char* file, int line, LogSeverity severity,
+ std::string* message);
+
+ // A special constructor used for check failures
+ LogMessage(const char* file, int line, const CheckOpString& result);
+
+ ~LogMessage();
+
+ // Flush a buffered message to the sink set in the constructor. Always
+ // called by the destructor, it may also be called from elsewhere if
+ // needed. Only the first call is actioned; any later ones are ignored.
+ void Flush();
+
+ // An arbitrary limit on the length of a single log message. This
+ // is so that streaming can be done more efficiently.
+ static const size_t kMaxLogMessageLen;
+
+ // Theses should not be called directly outside of logging.*,
+ // only passed as SendMethod arguments to other LogMessage methods:
+ void SendToLog(); // Actually dispatch to the logs
+ void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs
+
+ // Call abort() or similar to perform LOG(FATAL) crash.
+ static void Fail() __attribute__ ((noreturn));
+
+ std::ostream& stream() { return *(data_->stream_); }
+
+ int preserved_errno() const { return data_->preserved_errno_; }
+
+ // Must be called without the log_mutex held. (L < log_mutex)
+ static int64 num_messages(int severity);
+
+private:
+ // Fully internal SendMethod cases:
+ void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs
+ void SendToSink(); // Send to sink if provided, do nothing otherwise.
+
+ // Write to string if provided and dispatch to the logs.
+ void WriteToStringAndLog();
+
+ void SaveOrSendToLog(); // Save to stringvec if provided, else to logs
+
+ void Init(const char* file, int line, LogSeverity severity,
+ void (LogMessage::*send_method)());
+
+ // Used to fill in crash information during LOG(FATAL) failures.
+ void RecordCrashReason(glog_internal_namespace_::CrashReason* reason);
+
+ // Counts of messages sent at each priority:
+ static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex
+
+ // We keep the data in a separate struct so that each instance of
+ // LogMessage uses less stack space.
+ struct GOOGLE_GLOG_DLL_DECL LogMessageData {
+ LogMessageData() {};
+
+ int preserved_errno_; // preserved errno
+ char* buf_;
+ char* message_text_; // Complete message text (points to selected buffer)
+ LogStream* stream_alloc_;
+ LogStream* stream_;
+ char severity_; // What level is this LogMessage logged at?
+ int line_; // line number where logging call is.
+ void (LogMessage::*send_method_)(); // Call this in destructor to send
+ union { // At most one of these is used: union to keep the size low.
+ LogSink* sink_; // NULL or sink to send message to
+ std::vector<std::string>* outvec_; // NULL or vector to push message onto
+ std::string* message_; // NULL or string to write message into
+ };
+ time_t timestamp_; // Time of creation of LogMessage
+ struct ::tm tm_time_; // Time of creation of LogMessage
+ size_t num_prefix_chars_; // # of chars of prefix in this message
+ size_t num_chars_to_log_; // # of chars of msg to send to log
+ size_t num_chars_to_syslog_; // # of chars of msg to send to syslog
+ const char* basename_; // basename of file that called LOG
+ const char* fullname_; // fullname of file that called LOG
+ bool has_been_flushed_; // false => data has not been flushed
+ bool first_fatal_; // true => this was first fatal msg
+
+ ~LogMessageData();
+ private:
+ LogMessageData(const LogMessageData&);
+ void operator=(const LogMessageData&);
+ };
+
+ static LogMessageData fatal_msg_data_exclusive_;
+ static LogMessageData fatal_msg_data_shared_;
+
+ LogMessageData* allocated_;
+ LogMessageData* data_;
+
+ friend class LogDestination;
+
+ LogMessage(const LogMessage&);
+ void operator=(const LogMessage&);
+};
+
+// This class happens to be thread-hostile because all instances share
+// a single data buffer, but since it can only be created just before
+// the process dies, we don't worry so much.
+class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage {
+ public:
+ LogMessageFatal(const char* file, int line);
+ LogMessageFatal(const char* file, int line, const CheckOpString& result);
+ ~LogMessageFatal() __attribute__ ((noreturn));
+};
+
+// A non-macro interface to the log facility; (useful
+// when the logging level is not a compile-time constant).
+inline void LogAtLevel(int const severity, std::string const &msg) {
+ LogMessage(__FILE__, __LINE__, severity).stream() << msg;
+}
+
+// A macro alternative of LogAtLevel. New code may want to use this
+// version since there are two advantages: 1. this version outputs the
+// file name and the line number where this macro is put like other
+// LOG macros, 2. this macro can be used as C++ stream.
+#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream()
+
+// A small helper for CHECK_NOTNULL().
+template <typename T>
+T* CheckNotNull(const char *file, int line, const char *names, T* t) {
+ if (t == NULL) {
+ LogMessageFatal(file, line, new std::string(names));
+ }
+ return t;
+}
+
+// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
+// only works if ostream is a LogStream. If the ostream is not a
+// LogStream you'll get an assert saying as much at runtime.
+GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os,
+ const PRIVATE_Counter&);
+
+
+// Derived class for PLOG*() above.
+class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage {
+ public:
+
+ ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr,
+ void (LogMessage::*send_method)());
+
+ // Postpends ": strerror(errno) [errno]".
+ ~ErrnoLogMessage();
+
+ private:
+ ErrnoLogMessage(const ErrnoLogMessage&);
+ void operator=(const ErrnoLogMessage&);
+};
+
+
+// This class is used to explicitly ignore values in the conditional
+// logging macros. This avoids compiler warnings like "value computed
+// is not used" and "statement has no effect".
+
+class GOOGLE_GLOG_DLL_DECL LogMessageVoidify {
+ public:
+ LogMessageVoidify() { }
+ // This has to be an operator with a precedence lower than << but
+ // higher than ?:
+ void operator&(std::ostream&) { }
+};
+
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level. Thread-safe.
+GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity);
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level. Thread-hostile because it ignores
+// locking -- used for catastrophic failures.
+GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity);
+
+//
+// Set the destination to which a particular severity level of log
+// messages is sent. If base_filename is "", it means "don't log this
+// severity". Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity,
+ const char* base_filename);
+
+//
+// Set the basename of the symlink to the latest log file at a given
+// severity. If symlink_basename is empty, do not make a symlink. If
+// you don't call this function, the symlink basename is the
+// invocation name of the program. Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity,
+ const char* symlink_basename);
+
+//
+// Used to send logs to some other kind of destination
+// Users should subclass LogSink and override send to do whatever they want.
+// Implementations must be thread-safe because a shared instance will
+// be called from whichever thread ran the LOG(XXX) line.
+class GOOGLE_GLOG_DLL_DECL LogSink {
+ public:
+ virtual ~LogSink();
+
+ // Sink's logging logic (message_len is such as to exclude '\n' at the end).
+ // This method can't use LOG() or CHECK() as logging system mutex(s) are held
+ // during this call.
+ virtual void send(LogSeverity severity, const char* full_filename,
+ const char* base_filename, int line,
+ const struct ::tm* tm_time,
+ const char* message, size_t message_len) = 0;
+
+ // Redefine this to implement waiting for
+ // the sink's logging logic to complete.
+ // It will be called after each send() returns,
+ // but before that LogMessage exits or crashes.
+ // By default this function does nothing.
+ // Using this function one can implement complex logic for send()
+ // that itself involves logging; and do all this w/o causing deadlocks and
+ // inconsistent rearrangement of log messages.
+ // E.g. if a LogSink has thread-specific actions, the send() method
+ // can simply add the message to a queue and wake up another thread that
+ // handles real logging while itself making some LOG() calls;
+ // WaitTillSent() can be implemented to wait for that logic to complete.
+ // See our unittest for an example.
+ virtual void WaitTillSent();
+
+ // Returns the normal text output of the log message.
+ // Can be useful to implement send().
+ static std::string ToString(LogSeverity severity, const char* file, int line,
+ const struct ::tm* tm_time,
+ const char* message, size_t message_len);
+};
+
+// Add or remove a LogSink as a consumer of logging data. Thread-safe.
+GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination);
+GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination);
+
+//
+// Specify an "extension" added to the filename specified via
+// SetLogDestination. This applies to all severity levels. It's
+// often used to append the port we're listening on to the logfile
+// name. Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension(
+ const char* filename_extension);
+
+//
+// Make it so that all log messages of at least a particular severity
+// are logged to stderr (in addition to logging to the usual log
+// file(s)). Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity);
+
+//
+// Make it so that all log messages go only to stderr. Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void LogToStderr();
+
+//
+// Make it so that all log messages of at least a particular severity are
+// logged via email to a list of addresses (in addition to logging to the
+// usual log file(s)). The list of addresses is just a string containing
+// the email addresses to send to (separated by spaces, say). Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity,
+ const char* addresses);
+
+// A simple function that sends email. dest is a commma-separated
+// list of addressess. Thread-safe.
+GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest,
+ const char *subject, const char *body);
+
+GOOGLE_GLOG_DLL_DECL const std::vector<std::string>& GetLoggingDirectories();
+
+// For tests only: Clear the internal [cached] list of logging directories to
+// force a refresh the next time GetLoggingDirectories is called.
+// Thread-hostile.
+void TestOnly_ClearLoggingDirectoriesList();
+
+// Returns a set of existing temporary directories, which will be a
+// subset of the directories returned by GetLogginDirectories().
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories(
+ std::vector<std::string>* list);
+
+// Print any fatal message again -- useful to call from signal handler
+// so that the last thing in the output is the fatal message.
+// Thread-hostile, but a race is unlikely.
+GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage();
+
+// Truncate a log file that may be the append-only output of multiple
+// processes and hence can't simply be renamed/reopened (typically a
+// stdout/stderr). If the file "path" is > "limit" bytes, copy the
+// last "keep" bytes to offset 0 and truncate the rest. Since we could
+// be racing with other writers, this approach has the potential to
+// lose very small amounts of data. For security, only follow symlinks
+// if the path is /proc/self/fd/*
+GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path,
+ int64 limit, int64 keep);
+
+// Truncate stdout and stderr if they are over the value specified by
+// --max_log_size; keep the final 1MB. This function has the same
+// race condition as TruncateLogFile.
+GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr();
+
+// Return the string representation of the provided LogSeverity level.
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity);
+
+// ---------------------------------------------------------------------
+// Implementation details that are not useful to most clients
+// ---------------------------------------------------------------------
+
+// A Logger is the interface used by logging modules to emit entries
+// to a log. A typical implementation will dump formatted data to a
+// sequence of files. We also provide interfaces that will forward
+// the data to another thread so that the invoker never blocks.
+// Implementations should be thread-safe since the logging system
+// will write to them from multiple threads.
+
+namespace base {
+
+class GOOGLE_GLOG_DLL_DECL Logger {
+ public:
+ virtual ~Logger();
+
+ // Writes "message[0,message_len-1]" corresponding to an event that
+ // occurred at "timestamp". If "force_flush" is true, the log file
+ // is flushed immediately.
+ //
+ // The input message has already been formatted as deemed
+ // appropriate by the higher level logging facility. For example,
+ // textual log messages already contain timestamps, and the
+ // file:linenumber header.
+ virtual void Write(bool force_flush,
+ time_t timestamp,
+ const char* message,
+ int message_len) = 0;
+
+ // Flush any buffered messages
+ virtual void Flush() = 0;
+
+ // Get the current LOG file size.
+ // The returned value is approximate since some
+ // logged data may not have been flushed to disk yet.
+ virtual uint32 LogSize() = 0;
+};
+
+// Get the logger for the specified severity level. The logger
+// remains the property of the logging module and should not be
+// deleted by the caller. Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level);
+
+// Set the logger for the specified severity level. The logger
+// becomes the property of the logging module and should not
+// be deleted by the caller. Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
+
+}
+
+// glibc has traditionally implemented two incompatible versions of
+// strerror_r(). There is a poorly defined convention for picking the
+// version that we want, but it is not clear whether it even works with
+// all versions of glibc.
+// So, instead, we provide this wrapper that automatically detects the
+// version that is in use, and then implements POSIX semantics.
+// N.B. In addition to what POSIX says, we also guarantee that "buf" will
+// be set to an empty string, if this function failed. This means, in most
+// cases, you do not need to check the error code and you can directly
+// use the value of "buf". It will never have an undefined value.
+GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
+
+
+// A class for which we define operator<<, which does nothing.
+class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
+ public:
+ // Initialize the LogStream so the messages can be written somewhere
+ // (they'll never be actually displayed). This will be needed if a
+ // NullStream& is implicitly converted to LogStream&, in which case
+ // the overloaded NullStream::operator<< will not be invoked.
+ NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
+ NullStream(const char* /*file*/, int /*line*/,
+ const CheckOpString& /*result*/) :
+ LogMessage::LogStream(message_buffer_, 1, 0) { }
+ NullStream &stream() { return *this; }
+ private:
+ // A very short buffer for messages (which we discard anyway). This
+ // will be needed if NullStream& converted to LogStream& (e.g. as a
+ // result of a conditional expression).
+ char message_buffer_[2];
+};
+
+// Do nothing. This operator is inline, allowing the message to be
+// compiled away. The message will not be compiled away if we do
+// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
+// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
+// converted to LogStream and the message will be computed and then
+// quietly discarded.
+template<class T>
+inline NullStream& operator<<(NullStream &str, const T &value) { return str; }
+
+// Similar to NullStream, but aborts the program (without stack
+// trace), like LogMessageFatal.
+class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream {
+ public:
+ NullStreamFatal() { }
+ NullStreamFatal(const char* file, int line, const CheckOpString& result) :
+ NullStream(file, line, result) { }
+ __attribute__ ((noreturn)) ~NullStreamFatal() { _exit(1); }
+};
+
+// Install a signal handler that will dump signal information and a stack
+// trace when the program crashes on certain signals. We'll install the
+// signal handler for the following signals.
+//
+// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM.
+//
+// By default, the signal handler will write the failure dump to the
+// standard error. You can customize the destination by installing your
+// own writer function by InstallFailureWriter() below.
+//
+// Note on threading:
+//
+// The function should be called before threads are created, if you want
+// to use the failure signal handler for all threads. The stack trace
+// will be shown only for the thread that receives the signal. In other
+// words, stack traces of other threads won't be shown.
+GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler();
+
+// Installs a function that is used for writing the failure dump. "data"
+// is the pointer to the beginning of a message to be written, and "size"
+// is the size of the message. You should not expect the data is
+// terminated with '\0'.
+GOOGLE_GLOG_DLL_DECL void InstallFailureWriter(
+ void (*writer)(const char* data, int size));
+
+}
+
+#endif // _LOGGING_H_
diff --git a/extern/libmv/third_party/glog/src/glog/raw_logging.h b/extern/libmv/third_party/glog/src/glog/raw_logging.h
new file mode 100644
index 00000000000..9e9b3772f3b
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/glog/raw_logging.h
@@ -0,0 +1,185 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// Thread-safe logging routines that do not allocate any memory or
+// acquire any locks, and can therefore be used by low-level memory
+// allocation and synchronization code.
+
+#ifndef BASE_RAW_LOGGING_H_
+#define BASE_RAW_LOGGING_H_
+
+#include <time.h>
+
+namespace google {
+
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// This is similar to LOG(severity) << format... and VLOG(level) << format..,
+// but
+// * it is to be used ONLY by low-level modules that can't use normal LOG()
+// * it is desiged to be a low-level logger that does not allocate any
+// memory and does not need any locks, hence:
+// * it logs straight and ONLY to STDERR w/o buffering
+// * it uses an explicit format and arguments list
+// * it will silently chop off really long message strings
+// Usage example:
+// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
+// RAW_VLOG(3, "status is %i", status);
+// These will print an almost standard log lines like this to stderr only:
+// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
+// I0821 211317 file.cc:142] RAW: status is 20
+#define RAW_LOG(severity, ...) \
+ do { \
+ switch (google::severity) { \
+ case 0: \
+ RAW_LOG_INFO(__VA_ARGS__); \
+ break; \
+ case 1: \
+ RAW_LOG_WARNING(__VA_ARGS__); \
+ break; \
+ case 2: \
+ RAW_LOG_ERROR(__VA_ARGS__); \
+ break; \
+ case 3: \
+ RAW_LOG_FATAL(__VA_ARGS__); \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+
+// The following STRIP_LOG testing is performed in the header file so that it's
+// possible to completely compile out the logging code and the log messages.
+#if STRIP_LOG == 0
+#define RAW_VLOG(verboselevel, ...) \
+ do { \
+ if (VLOG_IS_ON(verboselevel)) { \
+ RAW_LOG_INFO(__VA_ARGS__); \
+ } \
+ } while (0)
+#else
+#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG == 0
+#define RAW_LOG_INFO(...) google::RawLog__(google::INFO, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG <= 1
+#define RAW_LOG_WARNING(...) google::RawLog__(google::WARNING, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 1
+
+#if STRIP_LOG <= 2
+#define RAW_LOG_ERROR(...) google::RawLog__(google::ERROR, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 2
+
+#if STRIP_LOG <= 3
+#define RAW_LOG_FATAL(...) google::RawLog__(google::FATAL, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_FATAL(...) \
+ do { \
+ google::RawLogStub__(0, __VA_ARGS__); \
+ exit(1); \
+ } while (0)
+#endif // STRIP_LOG <= 3
+
+// Similar to CHECK(condition) << message,
+// but for low-level modules: we use only RAW_LOG that does not allocate memory.
+// We do not want to provide args list here to encourage this usage:
+// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
+// so that the args are not computed when not needed.
+#define RAW_CHECK(condition, message) \
+ do { \
+ if (!(condition)) { \
+ RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
+ } \
+ } while (0)
+
+// Debug versions of RAW_LOG and RAW_CHECK
+#ifndef NDEBUG
+
+#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
+
+#else // NDEBUG
+
+#define RAW_DLOG(severity, ...) \
+ while (false) \
+ RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) \
+ while (false) \
+ RAW_CHECK(condition, message)
+
+#endif // NDEBUG
+
+// Stub log function used to work around for unused variable warnings when
+// building with STRIP_LOG > 0.
+static inline void RawLogStub__(int ignored, ...) {
+}
+
+// Helper function to implement RAW_LOG and RAW_VLOG
+// Logs format... at "severity" level, reporting it
+// as called from file:line.
+// This does not allocate memory or acquire locks.
+GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
+ const char* file,
+ int line,
+ const char* format, ...)
+ __attribute__((__format__ (__printf__, 4, 5)));
+
+// Hack to propagate time information into this module so that
+// this module does not have to directly call localtime_r(),
+// which could allocate memory.
+GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs);
+
+}
+
+#endif // BASE_RAW_LOGGING_H_
diff --git a/extern/libmv/third_party/glog/src/glog/vlog_is_on.h b/extern/libmv/third_party/glog/src/glog/vlog_is_on.h
new file mode 100644
index 00000000000..02b0b867097
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/glog/vlog_is_on.h
@@ -0,0 +1,129 @@
+// Copyright (c) 1999, 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney and many others
+//
+// Defines the VLOG_IS_ON macro that controls the variable-verbosity
+// conditional logging.
+//
+// It's used by VLOG and VLOG_IF in logging.h
+// and by RAW_VLOG in raw_logging.h to trigger the logging.
+//
+// It can also be used directly e.g. like this:
+// if (VLOG_IS_ON(2)) {
+// // do some logging preparation and logging
+// // that can't be accomplished e.g. via just VLOG(2) << ...;
+// }
+//
+// The truth value that VLOG_IS_ON(level) returns is determined by
+// the three verbosity level flags:
+// --v=<n> Gives the default maximal active V-logging level;
+// 0 is the default.
+// Normally positive values are used for V-logging levels.
+// --vmodule=<str> Gives the per-module maximal V-logging levels to override
+// the value given by --v.
+// E.g. "my_module=2,foo*=3" would change the logging level
+// for all code in source files "my_module.*" and "foo*.*"
+// ("-inl" suffixes are also disregarded for this matching).
+//
+// SetVLOGLevel helper function is provided to do limited dynamic control over
+// V-logging by overriding the per-module settings given via --vmodule flag.
+//
+// CAVEAT: --vmodule functionality is not available in non gcc compilers.
+//
+
+#ifndef BASE_VLOG_IS_ON_H_
+#define BASE_VLOG_IS_ON_H_
+
+#include "glog/log_severity.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+#if defined(__GNUC__)
+// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
+// (Normally) the first time every VLOG_IS_ON(n) site is hit,
+// we determine what variable will dynamically control logging at this site:
+// it's either FLAGS_v or an appropriate internal variable
+// matching the current source file that represents results of
+// parsing of --vmodule flag and/or SetVLOGLevel calls.
+#define VLOG_IS_ON(verboselevel) \
+ __extension__ \
+ ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \
+ google::int32 verbose_level__ = (verboselevel); \
+ (*vlocal__ >= verbose_level__) && \
+ ((vlocal__ != &google::kLogSiteUninitialized) || \
+ (google::InitVLOG3__(&vlocal__, &FLAGS_v, \
+ __FILE__, verbose_level__))); })
+#else
+// GNU extensions not available, so we do not support --vmodule.
+// Dynamic value of FLAGS_v always controls the logging level.
+#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
+#endif
+
+// Set VLOG(_IS_ON) level for module_pattern to log_level.
+// This lets us dynamically control what is normally set by the --vmodule flag.
+// Returns the level that previously applied to module_pattern.
+// NOTE: To change the log level for VLOG(_IS_ON) sites
+// that have already executed after/during InitGoogleLogging,
+// one needs to supply the exact --vmodule pattern that applied to them.
+// (If no --vmodule pattern applied to them
+// the value of FLAGS_v will continue to control them.)
+extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
+ int log_level);
+
+// Various declarations needed for VLOG_IS_ON above: =========================
+
+// Special value used to indicate that a VLOG_IS_ON site has not been
+// initialized. We make this a large value, so the common-case check
+// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
+// passes in such cases and InitVLOG3__ is then triggered.
+extern google::int32 kLogSiteUninitialized;
+
+// Helper routine which determines the logging info for a particalur VLOG site.
+// site_flag is the address of the site-local pointer to the controlling
+// verbosity level
+// site_default is the default to use for *site_flag
+// fname is the current source file name
+// verbose_level is the argument to VLOG_IS_ON
+// We will return the return value for VLOG_IS_ON
+// and if possible set *site_flag appropriately.
+extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
+ google::int32** site_flag,
+ google::int32* site_default,
+ const char* fname,
+ google::int32 verbose_level);
+
+#endif // BASE_VLOG_IS_ON_H_
diff --git a/extern/libmv/third_party/glog/src/logging.cc b/extern/libmv/third_party/glog/src/logging.cc
new file mode 100644
index 00000000000..1bb3867aa10
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/logging.cc
@@ -0,0 +1,1783 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite()
+
+#include "utilities.h"
+
+#include <assert.h>
+#include <iomanip>
+#include <string>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h> // For _exit.
+#endif
+#include <climits>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h> // For uname.
+#endif
+#include <fcntl.h>
+#include <cstdio>
+#include <iostream>
+#include <stdarg.h>
+#include <stdlib.h>
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#endif
+#include <vector>
+#include <errno.h> // for errno
+#include <sstream>
+#include "base/commandlineflags.h" // to get the program name
+#include <glog/logging.h>
+#include <glog/raw_logging.h>
+#include "base/googleinit.h"
+
+#ifdef HAVE_STACKTRACE
+# include "stacktrace.h"
+#endif
+
+using std::string;
+using std::vector;
+using std::ostrstream;
+using std::setw;
+using std::setfill;
+using std::hex;
+using std::dec;
+using std::min;
+using std::ostream;
+using std::ostringstream;
+using std::strstream;
+
+// There is no thread annotation support.
+#define EXCLUSIVE_LOCKS_REQUIRED(mu)
+
+static bool BoolFromEnv(const char *varname, bool defval) {
+ const char* const valstr = getenv(varname);
+ if (!valstr) {
+ return defval;
+ }
+ return memchr("tTyY1\0", valstr[0], 6) != NULL;
+}
+
+GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false),
+ "log messages go to stderr instead of logfiles");
+GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
+ "log messages go to stderr in addition to logfiles");
+#ifdef OS_LINUX
+GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. "
+ "Logs can grow very quickly and they are rarely read before they "
+ "need to be evicted from memory. Instead, drop them from memory "
+ "as soon as they are flushed to disk.");
+_START_GOOGLE_NAMESPACE_
+namespace logging {
+static const int64 kPageSize = getpagesize();
+}
+_END_GOOGLE_NAMESPACE_
+#endif
+
+// By default, errors (including fatal errors) get logged to stderr as
+// well as the file.
+//
+// The default is ERROR instead of FATAL so that users can see problems
+// when they run a program without having to look in another file.
+DEFINE_int32(stderrthreshold,
+ GOOGLE_NAMESPACE::ERROR,
+ "log messages at or above this level are copied to stderr in "
+ "addition to logfiles. This flag obsoletes --alsologtostderr.");
+
+GLOG_DEFINE_string(alsologtoemail, "",
+ "log messages go to these email addresses "
+ "in addition to logfiles");
+GLOG_DEFINE_bool(log_prefix, true,
+ "Prepend the log prefix to the start of each log line");
+GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't "
+ "actually get logged anywhere");
+GLOG_DEFINE_int32(logbuflevel, 0,
+ "Buffer log messages logged at this level or lower"
+ " (-1 means don't buffer; 0 means buffer INFO only;"
+ " ...)");
+GLOG_DEFINE_int32(logbufsecs, 30,
+ "Buffer log messages for at most this many seconds");
+GLOG_DEFINE_int32(logemaillevel, 999,
+ "Email log messages logged at this level or higher"
+ " (0 means email all; 3 means email FATAL only;"
+ " ...)");
+GLOG_DEFINE_string(logmailer, "/bin/mail",
+ "Mailer used to send logging email");
+
+// Compute the default value for --log_dir
+static const char* DefaultLogDir() {
+ const char* env;
+ env = getenv("GOOGLE_LOG_DIR");
+ if (env != NULL && env[0] != '\0') {
+ return env;
+ }
+ env = getenv("TEST_TMPDIR");
+ if (env != NULL && env[0] != '\0') {
+ return env;
+ }
+ return "";
+}
+
+GLOG_DEFINE_string(log_dir, DefaultLogDir(),
+ "If specified, logfiles are written into this directory instead "
+ "of the default logging directory.");
+GLOG_DEFINE_string(log_link, "", "Put additional links to the log "
+ "files in this directory");
+
+GLOG_DEFINE_int32(max_log_size, 1800,
+ "approx. maximum log file size (in MB). A value of 0 will "
+ "be silently overridden to 1.");
+
+GLOG_DEFINE_bool(stop_logging_if_full_disk, false,
+ "Stop attempting to log to disk if the disk is full.");
+
+GLOG_DEFINE_string(log_backtrace_at, "",
+ "Emit a backtrace when logging at file:linenum.");
+
+// TODO(hamaji): consider windows
+#define PATH_SEPARATOR '/'
+
+static void GetHostName(string* hostname) {
+#if defined(HAVE_SYS_UTSNAME_H)
+ struct utsname buf;
+ if (0 != uname(&buf)) {
+ // ensure null termination on failure
+ *buf.nodename = '\0';
+ }
+ *hostname = buf.nodename;
+#elif defined(OS_WINDOWS)
+ char buf[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD len = MAX_COMPUTERNAME_LENGTH + 1;
+ if (GetComputerNameA(buf, &len)) {
+ *hostname = buf;
+ } else {
+ hostname->clear();
+ }
+#else
+# warning There is no way to retrieve the host name.
+ *hostname = "(unknown)";
+#endif
+}
+
+_START_GOOGLE_NAMESPACE_
+
+// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0
+static int32 MaxLogSize() {
+ return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1);
+}
+
+// A mutex that allows only one thread to log at a time, to keep things from
+// getting jumbled. Some other very uncommon logging operations (like
+// changing the destination file for log messages of a given severity) also
+// lock this mutex. Please be sure that anybody who might possibly need to
+// lock it does so.
+static Mutex log_mutex;
+
+// Number of messages sent at each severity. Under log_mutex.
+int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0};
+
+// Globally disable log writing (if disk is full)
+static bool stop_writing = false;
+
+const char*const LogSeverityNames[NUM_SEVERITIES] = {
+ "INFO", "WARNING", "ERROR", "FATAL"
+};
+
+// Has the user called SetExitOnDFatal(true)?
+static bool exit_on_dfatal = true;
+
+const char* GetLogSeverityName(LogSeverity severity) {
+ return LogSeverityNames[severity];
+}
+
+static bool SendEmailInternal(const char*dest, const char *subject,
+ const char*body, bool use_logging);
+
+base::Logger::~Logger() {
+}
+
+namespace {
+
+// Encapsulates all file-system related state
+class LogFileObject : public base::Logger {
+ public:
+ LogFileObject(LogSeverity severity, const char* base_filename);
+ ~LogFileObject();
+
+ virtual void Write(bool force_flush, // Should we force a flush here?
+ time_t timestamp, // Timestamp for this entry
+ const char* message,
+ int message_len);
+
+ // Configuration options
+ void SetBasename(const char* basename);
+ void SetExtension(const char* ext);
+ void SetSymlinkBasename(const char* symlink_basename);
+
+ // Normal flushing routine
+ virtual void Flush();
+
+ // It is the actual file length for the system loggers,
+ // i.e., INFO, ERROR, etc.
+ virtual uint32 LogSize() {
+ MutexLock l(&lock_);
+ return file_length_;
+ }
+
+ // Internal flush routine. Exposed so that FlushLogFilesUnsafe()
+ // can avoid grabbing a lock. Usually Flush() calls it after
+ // acquiring lock_.
+ void FlushUnlocked();
+
+ private:
+ static const uint32 kRolloverAttemptFrequency = 0x20;
+
+ Mutex lock_;
+ bool base_filename_selected_;
+ string base_filename_;
+ string symlink_basename_;
+ string filename_extension_; // option users can specify (eg to add port#)
+ FILE* file_;
+ LogSeverity severity_;
+ uint32 bytes_since_flush_;
+ uint32 file_length_;
+ unsigned int rollover_attempt_;
+ int64 next_flush_time_; // cycle count at which to flush log
+
+ // Actually create a logfile using the value of base_filename_ and the
+ // supplied argument time_pid_string
+ // REQUIRES: lock_ is held
+ bool CreateLogfile(const char* time_pid_string);
+};
+
+} // namespace
+
+class LogDestination {
+ public:
+ friend class LogMessage;
+ friend void ReprintFatalMessage();
+ friend base::Logger* base::GetLogger(LogSeverity);
+ friend void base::SetLogger(LogSeverity, base::Logger*);
+
+ // These methods are just forwarded to by their global versions.
+ static void SetLogDestination(LogSeverity severity,
+ const char* base_filename);
+ static void SetLogSymlink(LogSeverity severity,
+ const char* symlink_basename);
+ static void AddLogSink(LogSink *destination);
+ static void RemoveLogSink(LogSink *destination);
+ static void SetLogFilenameExtension(const char* filename_extension);
+ static void SetStderrLogging(LogSeverity min_severity);
+ static void SetEmailLogging(LogSeverity min_severity, const char* addresses);
+ static void LogToStderr();
+ // Flush all log files that are at least at the given severity level
+ static void FlushLogFiles(int min_severity);
+ static void FlushLogFilesUnsafe(int min_severity);
+
+ // we set the maximum size of our packet to be 1400, the logic being
+ // to prevent fragmentation.
+ // Really this number is arbitrary.
+ static const int kNetworkBytes = 1400;
+
+ static const string& hostname();
+ private:
+
+ LogDestination(LogSeverity severity, const char* base_filename);
+ ~LogDestination() { }
+
+ // Take a log message of a particular severity and log it to stderr
+ // iff it's of a high enough severity to deserve it.
+ static void MaybeLogToStderr(LogSeverity severity, const char* message,
+ size_t len);
+
+ // Take a log message of a particular severity and log it to email
+ // iff it's of a high enough severity to deserve it.
+ static void MaybeLogToEmail(LogSeverity severity, const char* message,
+ size_t len);
+ // Take a log message of a particular severity and log it to a file
+ // iff the base filename is not "" (which means "don't log to me")
+ static void MaybeLogToLogfile(LogSeverity severity,
+ time_t timestamp,
+ const char* message, size_t len);
+ // Take a log message of a particular severity and log it to the file
+ // for that severity and also for all files with severity less than
+ // this severity.
+ static void LogToAllLogfiles(LogSeverity severity,
+ time_t timestamp,
+ const char* message, size_t len);
+
+ // Send logging info to all registered sinks.
+ static void LogToSinks(LogSeverity severity,
+ const char *full_filename,
+ const char *base_filename,
+ int line,
+ const struct ::tm* tm_time,
+ const char* message,
+ size_t message_len);
+
+ // Wait for all registered sinks via WaitTillSent
+ // including the optional one in "data".
+ static void WaitForSinks(LogMessage::LogMessageData* data);
+
+ static LogDestination* log_destination(LogSeverity severity);
+
+ LogFileObject fileobject_;
+ base::Logger* logger_; // Either &fileobject_, or wrapper around it
+
+ static LogDestination* log_destinations_[NUM_SEVERITIES];
+ static LogSeverity email_logging_severity_;
+ static string addresses_;
+ static string hostname_;
+
+ // arbitrary global logging destinations.
+ static vector<LogSink*>* sinks_;
+
+ // Protects the vector sinks_,
+ // but not the LogSink objects its elements reference.
+ static Mutex sink_mutex_;
+
+ // Disallow
+ LogDestination(const LogDestination&);
+ LogDestination& operator=(const LogDestination&);
+};
+
+// Errors do not get logged to email by default.
+LogSeverity LogDestination::email_logging_severity_ = 99999;
+
+string LogDestination::addresses_;
+string LogDestination::hostname_;
+
+vector<LogSink*>* LogDestination::sinks_ = NULL;
+Mutex LogDestination::sink_mutex_;
+
+/* static */
+const string& LogDestination::hostname() {
+ if (hostname_.empty()) {
+ GetHostName(&hostname_);
+ if (hostname_.empty()) {
+ hostname_ = "(unknown)";
+ }
+ }
+ return hostname_;
+}
+
+LogDestination::LogDestination(LogSeverity severity,
+ const char* base_filename)
+ : fileobject_(severity, base_filename),
+ logger_(&fileobject_) {
+}
+
+inline void LogDestination::FlushLogFilesUnsafe(int min_severity) {
+ // assume we have the log_mutex or we simply don't care
+ // about it
+ for (int i = min_severity; i < NUM_SEVERITIES; i++) {
+ LogDestination* log = log_destination(i);
+ if (log != NULL) {
+ // Flush the base fileobject_ logger directly instead of going
+ // through any wrappers to reduce chance of deadlock.
+ log->fileobject_.FlushUnlocked();
+ }
+ }
+}
+
+inline void LogDestination::FlushLogFiles(int min_severity) {
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&log_mutex);
+ for (int i = min_severity; i < NUM_SEVERITIES; i++) {
+ LogDestination* log = log_destination(i);
+ if (log != NULL) {
+ log->logger_->Flush();
+ }
+ }
+}
+
+inline void LogDestination::SetLogDestination(LogSeverity severity,
+ const char* base_filename) {
+ assert(severity >= 0 && severity < NUM_SEVERITIES);
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&log_mutex);
+ log_destination(severity)->fileobject_.SetBasename(base_filename);
+}
+
+inline void LogDestination::SetLogSymlink(LogSeverity severity,
+ const char* symlink_basename) {
+ CHECK_GE(severity, 0);
+ CHECK_LT(severity, NUM_SEVERITIES);
+ MutexLock l(&log_mutex);
+ log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename);
+}
+
+inline void LogDestination::AddLogSink(LogSink *destination) {
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&sink_mutex_);
+ if (!sinks_) sinks_ = new vector<LogSink*>;
+ sinks_->push_back(destination);
+}
+
+inline void LogDestination::RemoveLogSink(LogSink *destination) {
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&sink_mutex_);
+ // This doesn't keep the sinks in order, but who cares?
+ if (sinks_) {
+ for (int i = sinks_->size() - 1; i >= 0; i--) {
+ if ((*sinks_)[i] == destination) {
+ (*sinks_)[i] = (*sinks_)[sinks_->size() - 1];
+ sinks_->pop_back();
+ break;
+ }
+ }
+ }
+}
+
+inline void LogDestination::SetLogFilenameExtension(const char* ext) {
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&log_mutex);
+ for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) {
+ log_destination(severity)->fileobject_.SetExtension(ext);
+ }
+}
+
+inline void LogDestination::SetStderrLogging(LogSeverity min_severity) {
+ assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&log_mutex);
+ FLAGS_stderrthreshold = min_severity;
+}
+
+inline void LogDestination::LogToStderr() {
+ // *Don't* put this stuff in a mutex lock, since SetStderrLogging &
+ // SetLogDestination already do the locking!
+ SetStderrLogging(0); // thus everything is "also" logged to stderr
+ for ( int i = 0; i < NUM_SEVERITIES; ++i ) {
+ SetLogDestination(i, ""); // "" turns off logging to a logfile
+ }
+}
+
+inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
+ const char* addresses) {
+ assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // all this stuff.
+ MutexLock l(&log_mutex);
+ LogDestination::email_logging_severity_ = min_severity;
+ LogDestination::addresses_ = addresses;
+}
+
+static void WriteToStderr(const char* message, size_t len) {
+ // Avoid using cerr from this module since we may get called during
+ // exit code, and cerr may be partially or fully destroyed by then.
+ write(STDERR_FILENO, message, len);
+}
+
+inline void LogDestination::MaybeLogToStderr(LogSeverity severity,
+ const char* message, size_t len) {
+ if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) {
+ WriteToStderr(message, len);
+#ifdef OS_WINDOWS
+ // On Windows, also output to the debugger
+ ::OutputDebugStringA(string(message,len).c_str());
+#endif
+ }
+}
+
+
+inline void LogDestination::MaybeLogToEmail(LogSeverity severity,
+ const char* message, size_t len) {
+ if (severity >= email_logging_severity_ ||
+ severity >= FLAGS_logemaillevel) {
+ string to(FLAGS_alsologtoemail);
+ if (!addresses_.empty()) {
+ if (!to.empty()) {
+ to += ",";
+ }
+ to += addresses_;
+ }
+ const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " +
+ glog_internal_namespace_::ProgramInvocationShortName());
+ string body(hostname());
+ body += "\n\n";
+ body.append(message, len);
+
+ // should NOT use SendEmail(). The caller of this function holds the
+ // log_mutex and SendEmail() calls LOG/VLOG which will block trying to
+ // acquire the log_mutex object. Use SendEmailInternal() and set
+ // use_logging to false.
+ SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false);
+ }
+}
+
+
+inline void LogDestination::MaybeLogToLogfile(LogSeverity severity,
+ time_t timestamp,
+ const char* message,
+ size_t len) {
+ const bool should_flush = severity > FLAGS_logbuflevel;
+ LogDestination* destination = log_destination(severity);
+ destination->logger_->Write(should_flush, timestamp, message, len);
+}
+
+inline void LogDestination::LogToAllLogfiles(LogSeverity severity,
+ time_t timestamp,
+ const char* message,
+ size_t len) {
+
+ if ( FLAGS_logtostderr ) // global flag: never log to file
+ WriteToStderr(message, len);
+ else
+ for (int i = severity; i >= 0; --i)
+ LogDestination::MaybeLogToLogfile(i, timestamp, message, len);
+
+}
+
+inline void LogDestination::LogToSinks(LogSeverity severity,
+ const char *full_filename,
+ const char *base_filename,
+ int line,
+ const struct ::tm* tm_time,
+ const char* message,
+ size_t message_len) {
+ ReaderMutexLock l(&sink_mutex_);
+ if (sinks_) {
+ for (int i = sinks_->size() - 1; i >= 0; i--) {
+ (*sinks_)[i]->send(severity, full_filename, base_filename,
+ line, tm_time, message, message_len);
+ }
+ }
+}
+
+inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) {
+ ReaderMutexLock l(&sink_mutex_);
+ if (sinks_) {
+ for (int i = sinks_->size() - 1; i >= 0; i--) {
+ (*sinks_)[i]->WaitTillSent();
+ }
+ }
+ const bool send_to_sink =
+ (data->send_method_ == &LogMessage::SendToSink) ||
+ (data->send_method_ == &LogMessage::SendToSinkAndLog);
+ if (send_to_sink && data->sink_ != NULL) {
+ data->sink_->WaitTillSent();
+ }
+}
+
+LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES];
+
+inline LogDestination* LogDestination::log_destination(LogSeverity severity) {
+ assert(severity >=0 && severity < NUM_SEVERITIES);
+ if (!log_destinations_[severity]) {
+ log_destinations_[severity] = new LogDestination(severity, NULL);
+ }
+ return log_destinations_[severity];
+}
+
+namespace {
+
+LogFileObject::LogFileObject(LogSeverity severity,
+ const char* base_filename)
+ : base_filename_selected_(base_filename != NULL),
+ base_filename_((base_filename != NULL) ? base_filename : ""),
+ symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
+ filename_extension_(),
+ file_(NULL),
+ severity_(severity),
+ bytes_since_flush_(0),
+ file_length_(0),
+ rollover_attempt_(kRolloverAttemptFrequency-1),
+ next_flush_time_(0) {
+ assert(severity >= 0);
+ assert(severity < NUM_SEVERITIES);
+}
+
+LogFileObject::~LogFileObject() {
+ MutexLock l(&lock_);
+ if (file_ != NULL) {
+ fclose(file_);
+ file_ = NULL;
+ }
+}
+
+void LogFileObject::SetBasename(const char* basename) {
+ MutexLock l(&lock_);
+ base_filename_selected_ = true;
+ if (base_filename_ != basename) {
+ // Get rid of old log file since we are changing names
+ if (file_ != NULL) {
+ fclose(file_);
+ file_ = NULL;
+ rollover_attempt_ = kRolloverAttemptFrequency-1;
+ }
+ base_filename_ = basename;
+ }
+}
+
+void LogFileObject::SetExtension(const char* ext) {
+ MutexLock l(&lock_);
+ if (filename_extension_ != ext) {
+ // Get rid of old log file since we are changing names
+ if (file_ != NULL) {
+ fclose(file_);
+ file_ = NULL;
+ rollover_attempt_ = kRolloverAttemptFrequency-1;
+ }
+ filename_extension_ = ext;
+ }
+}
+
+void LogFileObject::SetSymlinkBasename(const char* symlink_basename) {
+ MutexLock l(&lock_);
+ symlink_basename_ = symlink_basename;
+}
+
+void LogFileObject::Flush() {
+ MutexLock l(&lock_);
+ FlushUnlocked();
+}
+
+void LogFileObject::FlushUnlocked(){
+ if (file_ != NULL) {
+ fflush(file_);
+ bytes_since_flush_ = 0;
+ }
+ // Figure out when we are due for another flush.
+ const int64 next = (FLAGS_logbufsecs
+ * static_cast<int64>(1000000)); // in usec
+ next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
+}
+
+bool LogFileObject::CreateLogfile(const char* time_pid_string) {
+ string string_filename = base_filename_+filename_extension_+
+ time_pid_string;
+ const char* filename = string_filename.c_str();
+ int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664);
+ if (fd == -1) return false;
+#ifdef HAVE_FCNTL
+ // Mark the file close-on-exec. We don't really care if this fails
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+ file_ = fdopen(fd, "a"); // Make a FILE*.
+ if (file_ == NULL) { // Man, we're screwed!
+ close(fd);
+ unlink(filename); // Erase the half-baked evidence: an unusable log file
+ return false;
+ }
+
+ // We try to create a symlink called <program_name>.<severity>,
+ // which is easier to use. (Every time we create a new logfile,
+ // we destroy the old symlink and create a new one, so it always
+ // points to the latest logfile.) If it fails, we're sad but it's
+ // no error.
+ if (!symlink_basename_.empty()) {
+ // take directory from filename
+ const char* slash = strrchr(filename, PATH_SEPARATOR);
+ const string linkname =
+ symlink_basename_ + '.' + LogSeverityNames[severity_];
+ string linkpath;
+ if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname
+ linkpath += linkname;
+ unlink(linkpath.c_str()); // delete old one if it exists
+
+ // We must have unistd.h.
+#ifdef HAVE_UNISTD_H
+ // Make the symlink be relative (in the same dir) so that if the
+ // entire log directory gets relocated the link is still valid.
+ const char *linkdest = slash ? (slash + 1) : filename;
+ symlink(linkdest, linkpath.c_str()); // silently ignore failures
+
+ // Make an additional link to the log file in a place specified by
+ // FLAGS_log_link, if indicated
+ if (!FLAGS_log_link.empty()) {
+ linkpath = FLAGS_log_link + "/" + linkname;
+ unlink(linkpath.c_str()); // delete old one if it exists
+ symlink(filename, linkpath.c_str()); // silently ignore failures
+ }
+#endif
+ }
+
+ return true; // Everything worked
+}
+
+void LogFileObject::Write(bool force_flush,
+ time_t timestamp,
+ const char* message,
+ int message_len) {
+ MutexLock l(&lock_);
+
+ // We don't log if the base_name_ is "" (which means "don't write")
+ if (base_filename_selected_ && base_filename_.empty()) {
+ return;
+ }
+
+ if (static_cast<int>(file_length_ >> 20) >= MaxLogSize()) {
+ if (file_ != NULL) fclose(file_);
+ file_ = NULL;
+ file_length_ = bytes_since_flush_ = 0;
+ rollover_attempt_ = kRolloverAttemptFrequency-1;
+ }
+
+ // If there's no destination file, make one before outputting
+ if (file_ == NULL) {
+ // Try to rollover the log file every 32 log messages. The only time
+ // this could matter would be when we have trouble creating the log
+ // file. If that happens, we'll lose lots of log messages, of course!
+ if (++rollover_attempt_ != kRolloverAttemptFrequency) return;
+ rollover_attempt_ = 0;
+
+ struct ::tm tm_time;
+ localtime_r(&timestamp, &tm_time);
+
+ // The logfile's filename will have the date/time & pid in it
+ char time_pid_string[256]; // More than enough chars for time, pid, \0
+ ostrstream time_pid_stream(time_pid_string, sizeof(time_pid_string));
+ time_pid_stream.fill('0');
+ time_pid_stream << 1900+tm_time.tm_year
+ << setw(2) << 1+tm_time.tm_mon
+ << setw(2) << tm_time.tm_mday
+ << '-'
+ << setw(2) << tm_time.tm_hour
+ << setw(2) << tm_time.tm_min
+ << setw(2) << tm_time.tm_sec
+ << '.'
+ << GetMainThreadPid()
+ << '\0';
+
+ if (base_filename_selected_) {
+ if (!CreateLogfile(time_pid_string)) {
+ perror("Could not create log file");
+ fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", time_pid_string);
+ return;
+ }
+ } else {
+ // If no base filename for logs of this severity has been set, use a
+ // default base filename of
+ // "<program name>.<hostname>.<user name>.log.<severity level>.". So
+ // logfiles will have names like
+ // webserver.examplehost.root.log.INFO.19990817-150000.4354, where
+ // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00),
+ // and 4354 is the pid of the logging process. The date & time reflect
+ // when the file was created for output.
+ //
+ // Where does the file get put? Successively try the directories
+ // "/tmp", and "."
+ string stripped_filename(
+ glog_internal_namespace_::ProgramInvocationShortName());
+ string hostname;
+ GetHostName(&hostname);
+
+ string uidname = MyUserName();
+ // We should not call CHECK() here because this function can be
+ // called after holding on to log_mutex. We don't want to
+ // attempt to hold on to the same mutex, and get into a
+ // deadlock. Simply use a name like invalid-user.
+ if (uidname.empty()) uidname = "invalid-user";
+
+ stripped_filename = stripped_filename+'.'+hostname+'.'
+ +uidname+".log."
+ +LogSeverityNames[severity_]+'.';
+ // We're going to (potentially) try to put logs in several different dirs
+ const vector<string> & log_dirs = GetLoggingDirectories();
+
+ // Go through the list of dirs, and try to create the log file in each
+ // until we succeed or run out of options
+ bool success = false;
+ for (vector<string>::const_iterator dir = log_dirs.begin();
+ dir != log_dirs.end();
+ ++dir) {
+ base_filename_ = *dir + "/" + stripped_filename;
+ if ( CreateLogfile(time_pid_string) ) {
+ success = true;
+ break;
+ }
+ }
+ // If we never succeeded, we have to give up
+ if ( success == false ) {
+ perror("Could not create logging file");
+ fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", time_pid_string);
+ return;
+ }
+ }
+
+ // Write a header message into the log file
+ char file_header_string[512]; // Enough chars for time and binary info
+ ostrstream file_header_stream(file_header_string,
+ sizeof(file_header_string));
+ file_header_stream.fill('0');
+ file_header_stream << "Log file created at: "
+ << 1900+tm_time.tm_year << '/'
+ << setw(2) << 1+tm_time.tm_mon << '/'
+ << setw(2) << tm_time.tm_mday
+ << ' '
+ << setw(2) << tm_time.tm_hour << ':'
+ << setw(2) << tm_time.tm_min << ':'
+ << setw(2) << tm_time.tm_sec << '\n'
+ << "Running on machine: "
+ << LogDestination::hostname() << '\n'
+ << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu "
+ << "threadid file:line] msg" << '\n'
+ << '\0';
+ int header_len = strlen(file_header_string);
+ fwrite(file_header_string, 1, header_len, file_);
+ file_length_ += header_len;
+ bytes_since_flush_ += header_len;
+ }
+
+ // Write to LOG file
+ if ( !stop_writing ) {
+ // fwrite() doesn't return an error when the disk is full, for
+ // messages that are less than 4096 bytes. When the disk is full,
+ // it returns the message length for messages that are less than
+ // 4096 bytes. fwrite() returns 4096 for message lengths that are
+ // greater than 4096, thereby indicating an error.
+ errno = 0;
+ fwrite(message, 1, message_len, file_);
+ if ( FLAGS_stop_logging_if_full_disk &&
+ errno == ENOSPC ) { // disk full, stop writing to disk
+ stop_writing = true; // until the disk is
+ return;
+ } else {
+ file_length_ += message_len;
+ bytes_since_flush_ += message_len;
+ }
+ } else {
+ if ( CycleClock_Now() >= next_flush_time_ )
+ stop_writing = false; // check to see if disk has free space.
+ return; // no need to flush
+ }
+
+ // See important msgs *now*. Also, flush logs at least every 10^6 chars,
+ // or every "FLAGS_logbufsecs" seconds.
+ if ( force_flush ||
+ (bytes_since_flush_ >= 1000000) ||
+ (CycleClock_Now() >= next_flush_time_) ) {
+ FlushUnlocked();
+#ifdef OS_LINUX
+ if (FLAGS_drop_log_memory) {
+ if (file_length_ >= logging::kPageSize) {
+ // don't evict the most recent page
+ uint32 len = file_length_ & ~(logging::kPageSize - 1);
+ posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED);
+ }
+ }
+#endif
+ }
+}
+
+} // namespace
+
+// An arbitrary limit on the length of a single log message. This
+// is so that streaming can be done more efficiently.
+const size_t LogMessage::kMaxLogMessageLen = 30000;
+
+// Static log data space to avoid alloc failures in a LOG(FATAL)
+//
+// Since multiple threads may call LOG(FATAL), and we want to preserve
+// the data from the first call, we allocate two sets of space. One
+// for exclusive use by the first thread, and one for shared use by
+// all other threads.
+static Mutex fatal_msg_lock;
+static CrashReason crash_reason;
+static bool fatal_msg_exclusive = true;
+static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1];
+static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1];
+static LogMessage::LogStream fatal_msg_stream_exclusive(
+ fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0);
+static LogMessage::LogStream fatal_msg_stream_shared(
+ fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0);
+LogMessage::LogMessageData LogMessage::fatal_msg_data_exclusive_;
+LogMessage::LogMessageData LogMessage::fatal_msg_data_shared_;
+
+LogMessage::LogMessageData::~LogMessageData() {
+ delete[] buf_;
+ delete stream_alloc_;
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+ int ctr, void (LogMessage::*send_method)()) {
+ Init(file, line, severity, send_method);
+ data_->stream_->set_ctr(ctr);
+}
+
+LogMessage::LogMessage(const char* file, int line,
+ const CheckOpString& result) {
+ Init(file, line, FATAL, &LogMessage::SendToLog);
+ stream() << "Check failed: " << (*result.str_) << " ";
+}
+
+LogMessage::LogMessage(const char* file, int line) {
+ Init(file, line, INFO, &LogMessage::SendToLog);
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity) {
+ Init(file, line, severity, &LogMessage::SendToLog);
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+ LogSink* sink, bool also_send_to_log) {
+ Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
+ &LogMessage::SendToSink);
+ data_->sink_ = sink; // override Init()'s setting to NULL
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+ vector<string> *outvec) {
+ Init(file, line, severity, &LogMessage::SaveOrSendToLog);
+ data_->outvec_ = outvec; // override Init()'s setting to NULL
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+ string *message) {
+ Init(file, line, severity, &LogMessage::WriteToStringAndLog);
+ data_->message_ = message; // override Init()'s setting to NULL
+}
+
+void LogMessage::Init(const char* file,
+ int line,
+ LogSeverity severity,
+ void (LogMessage::*send_method)()) {
+ allocated_ = NULL;
+ if (severity != FATAL || !exit_on_dfatal) {
+ allocated_ = new LogMessageData();
+ data_ = allocated_;
+ data_->buf_ = new char[kMaxLogMessageLen+1];
+ data_->message_text_ = data_->buf_;
+ data_->stream_alloc_ =
+ new LogStream(data_->message_text_, kMaxLogMessageLen, 0);
+ data_->stream_ = data_->stream_alloc_;
+ data_->first_fatal_ = false;
+ } else {
+ MutexLock l(&fatal_msg_lock);
+ if (fatal_msg_exclusive) {
+ fatal_msg_exclusive = false;
+ data_ = &fatal_msg_data_exclusive_;
+ data_->message_text_ = fatal_msg_buf_exclusive;
+ data_->stream_ = &fatal_msg_stream_exclusive;
+ data_->first_fatal_ = true;
+ } else {
+ data_ = &fatal_msg_data_shared_;
+ data_->message_text_ = fatal_msg_buf_shared;
+ data_->stream_ = &fatal_msg_stream_shared;
+ data_->first_fatal_ = false;
+ }
+ data_->stream_alloc_ = NULL;
+ }
+
+ stream().fill('0');
+ data_->preserved_errno_ = errno;
+ data_->severity_ = severity;
+ data_->line_ = line;
+ data_->send_method_ = send_method;
+ data_->sink_ = NULL;
+ data_->outvec_ = NULL;
+ WallTime now = WallTime_Now();
+ data_->timestamp_ = static_cast<time_t>(now);
+ localtime_r(&data_->timestamp_, &data_->tm_time_);
+ int usecs = static_cast<int>((now - data_->timestamp_) * 1000000);
+ RawLog__SetLastTime(data_->tm_time_, usecs);
+
+ data_->num_chars_to_log_ = 0;
+ data_->num_chars_to_syslog_ = 0;
+ data_->basename_ = const_basename(file);
+ data_->fullname_ = file;
+ data_->has_been_flushed_ = false;
+
+ // If specified, prepend a prefix to each line. For example:
+ // I1018 160715 f5d4fbb0 logging.cc:1153]
+ // (log level, GMT month, date, time, thread_id, file basename, line)
+ // We exclude the thread_id for the default thread.
+ if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
+ stream() << LogSeverityNames[severity][0]
+ << setw(2) << 1+data_->tm_time_.tm_mon
+ << setw(2) << data_->tm_time_.tm_mday
+ << ' '
+ << setw(2) << data_->tm_time_.tm_hour << ':'
+ << setw(2) << data_->tm_time_.tm_min << ':'
+ << setw(2) << data_->tm_time_.tm_sec << "."
+ << setw(6) << usecs
+ << ' '
+ << setfill(' ') << setw(5)
+ << static_cast<unsigned int>(GetTID()) << setfill('0')
+ << ' '
+ << data_->basename_ << ':' << data_->line_ << "] ";
+ }
+ data_->num_prefix_chars_ = data_->stream_->pcount();
+
+ if (!FLAGS_log_backtrace_at.empty()) {
+ char fileline[128];
+ snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line);
+#ifdef HAVE_STACKTRACE
+ if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) {
+ string stacktrace;
+ DumpStackTraceToString(&stacktrace);
+ stream() << " (stacktrace:\n" << stacktrace << ") ";
+ }
+#endif
+ }
+}
+
+LogMessage::~LogMessage() {
+ Flush();
+ delete allocated_;
+}
+
+// Flush buffered message, called by the destructor, or any other function
+// that needs to synchronize the log.
+void LogMessage::Flush() {
+ if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel)
+ return;
+
+ data_->num_chars_to_log_ = data_->stream_->pcount();
+ data_->num_chars_to_syslog_ =
+ data_->num_chars_to_log_ - data_->num_prefix_chars_;
+
+ // Do we need to add a \n to the end of this message?
+ bool append_newline =
+ (data_->message_text_[data_->num_chars_to_log_-1] != '\n');
+ char original_final_char = '\0';
+
+ // If we do need to add a \n, we'll do it by violating the memory of the
+ // ostrstream buffer. This is quick, and we'll make sure to undo our
+ // modification before anything else is done with the ostrstream. It
+ // would be preferable not to do things this way, but it seems to be
+ // the best way to deal with this.
+ if (append_newline) {
+ original_final_char = data_->message_text_[data_->num_chars_to_log_];
+ data_->message_text_[data_->num_chars_to_log_++] = '\n';
+ }
+
+ // Prevent any subtle race conditions by wrapping a mutex lock around
+ // the actual logging action per se.
+ {
+ MutexLock l(&log_mutex);
+ (this->*(data_->send_method_))();
+ ++num_messages_[static_cast<int>(data_->severity_)];
+ }
+ LogDestination::WaitForSinks(data_);
+
+ if (append_newline) {
+ // Fix the ostrstream back how it was before we screwed with it.
+ // It's 99.44% certain that we don't need to worry about doing this.
+ data_->message_text_[data_->num_chars_to_log_-1] = original_final_char;
+ }
+
+ // If errno was already set before we enter the logging call, we'll
+ // set it back to that value when we return from the logging call.
+ // It happens often that we log an error message after a syscall
+ // failure, which can potentially set the errno to some other
+ // values. We would like to preserve the original errno.
+ if (data_->preserved_errno_ != 0) {
+ errno = data_->preserved_errno_;
+ }
+
+ // Note that this message is now safely logged. If we're asked to flush
+ // again, as a result of destruction, say, we'll do nothing on future calls.
+ data_->has_been_flushed_ = true;
+}
+
+// Copy of first FATAL log message so that we can print it out again
+// after all the stack traces. To preserve legacy behavior, we don't
+// use fatal_msg_buf_exclusive.
+static time_t fatal_time;
+static char fatal_message[256];
+
+void ReprintFatalMessage() {
+ if (fatal_message[0]) {
+ const int n = strlen(fatal_message);
+ if (!FLAGS_logtostderr) {
+ // Also write to stderr
+ WriteToStderr(fatal_message, n);
+ }
+ LogDestination::LogToAllLogfiles(ERROR, fatal_time, fatal_message, n);
+ }
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+ static bool already_warned_before_initgoogle = false;
+
+ log_mutex.AssertHeld();
+
+ RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+ data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+
+ // Messages of a given severity get logged to lower severity logs, too
+
+ if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) {
+ const char w[] = "WARNING: Logging before InitGoogleLogging() is "
+ "written to STDERR\n";
+ WriteToStderr(w, strlen(w));
+ already_warned_before_initgoogle = true;
+ }
+
+ // global flag: never log to file if set. Also -- don't log to a
+ // file if we haven't parsed the command line flags to get the
+ // program name.
+ if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) {
+ WriteToStderr(data_->message_text_, data_->num_chars_to_log_);
+
+ // this could be protected by a flag if necessary.
+ LogDestination::LogToSinks(data_->severity_,
+ data_->fullname_, data_->basename_,
+ data_->line_, &data_->tm_time_,
+ data_->message_text_ + data_->num_prefix_chars_,
+ (data_->num_chars_to_log_ -
+ data_->num_prefix_chars_ - 1));
+ } else {
+
+ // log this message to all log files of severity <= severity_
+ LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_,
+ data_->message_text_,
+ data_->num_chars_to_log_);
+
+ LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_,
+ data_->num_chars_to_log_);
+ LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_,
+ data_->num_chars_to_log_);
+ LogDestination::LogToSinks(data_->severity_,
+ data_->fullname_, data_->basename_,
+ data_->line_, &data_->tm_time_,
+ data_->message_text_ + data_->num_prefix_chars_,
+ (data_->num_chars_to_log_
+ - data_->num_prefix_chars_ - 1));
+ // NOTE: -1 removes trailing \n
+ }
+
+ // If we log a FATAL message, flush all the log destinations, then toss
+ // a signal for others to catch. We leave the logs in a state that
+ // someone else can use them (as long as they flush afterwards)
+ if (data_->severity_ == FATAL && exit_on_dfatal) {
+ if (data_->first_fatal_) {
+ // Store crash information so that it is accessible from within signal
+ // handlers that may be invoked later.
+ RecordCrashReason(&crash_reason);
+ SetCrashReason(&crash_reason);
+
+ // Store shortened fatal message for other logs and GWQ status
+ const int copy = min<int>(data_->num_chars_to_log_,
+ sizeof(fatal_message)-1);
+ memcpy(fatal_message, data_->message_text_, copy);
+ fatal_message[copy] = '\0';
+ fatal_time = data_->timestamp_;
+ }
+
+ if (!FLAGS_logtostderr) {
+ for (int i = 0; i < NUM_SEVERITIES; ++i) {
+ if ( LogDestination::log_destinations_[i] )
+ LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0);
+ }
+ }
+
+ // release the lock that our caller (directly or indirectly)
+ // LogMessage::~LogMessage() grabbed so that signal handlers
+ // can use the logging facility. Alternately, we could add
+ // an entire unsafe logging interface to bypass locking
+ // for signal handlers but this seems simpler.
+ log_mutex.Unlock();
+ LogDestination::WaitForSinks(data_);
+
+ const char* message = "*** Check failure stack trace: ***\n";
+ write(STDERR_FILENO, message, strlen(message));
+ Fail();
+ }
+}
+
+void LogMessage::RecordCrashReason(
+ glog_internal_namespace_::CrashReason* reason) {
+ reason->filename = fatal_msg_data_exclusive_.fullname_;
+ reason->line_number = fatal_msg_data_exclusive_.line_;
+ reason->message = fatal_msg_buf_exclusive +
+ fatal_msg_data_exclusive_.num_prefix_chars_;
+#ifdef HAVE_STACKTRACE
+ // Retrieve the stack trace, omitting the logging frames that got us here.
+ reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4);
+#else
+ reason->depth = 0;
+#endif
+}
+
+static void logging_fail() {
+// #if defined(_DEBUG) && defined(_MSC_VER)
+// doesn't work for my laptop (sergey)
+#if 0
+ // When debugging on windows, avoid the obnoxious dialog and make
+ // it possible to continue past a LOG(FATAL) in the debugger
+ _asm int 3
+#else
+ abort();
+#endif
+}
+
+#ifdef HAVE___ATTRIBUTE__
+GOOGLE_GLOG_DLL_DECL
+void (*g_logging_fail_func)() __attribute__((noreturn)) = &logging_fail;
+#else
+GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)() = &logging_fail;
+#endif
+
+void InstallFailureFunction(void (*fail_func)()) {
+ g_logging_fail_func = fail_func;
+}
+
+void LogMessage::Fail() {
+ g_logging_fail_func();
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+ if (data_->sink_ != NULL) {
+ RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+ data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+ data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
+ data_->line_, &data_->tm_time_,
+ data_->message_text_ + data_->num_prefix_chars_,
+ (data_->num_chars_to_log_ -
+ data_->num_prefix_chars_ - 1));
+ }
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+ SendToSink();
+ SendToLog();
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+ if (data_->outvec_ != NULL) {
+ RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+ data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+ // Omit prefix of message and trailing newline when recording in outvec_.
+ const char *start = data_->message_text_ + data_->num_prefix_chars_;
+ int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
+ data_->outvec_->push_back(string(start, len));
+ } else {
+ SendToLog();
+ }
+}
+
+void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+ if (data_->message_ != NULL) {
+ RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+ data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+ // Omit prefix of message and trailing newline when writing to message_.
+ const char *start = data_->message_text_ + data_->num_prefix_chars_;
+ int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
+ data_->message_->assign(start, len);
+ }
+ SendToLog();
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToSyslogAndLog() {
+#ifdef HAVE_SYSLOG_H
+ // Before any calls to syslog(), make a single call to openlog()
+ static bool openlog_already_called = false;
+ if (!openlog_already_called) {
+ openlog(glog_internal_namespace_::ProgramInvocationShortName(),
+ LOG_CONS | LOG_NDELAY | LOG_PID,
+ LOG_USER);
+ openlog_already_called = true;
+ }
+
+ // This array maps Google severity levels to syslog levels
+ const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
+ syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s",
+ int(data_->num_chars_to_syslog_),
+ data_->message_text_ + data_->num_prefix_chars_);
+ SendToLog();
+#else
+ LOG(ERROR) << "No syslog support: message=" << data_->message_text_;
+#endif
+}
+
+base::Logger* base::GetLogger(LogSeverity severity) {
+ MutexLock l(&log_mutex);
+ return LogDestination::log_destination(severity)->logger_;
+}
+
+void base::SetLogger(LogSeverity severity, base::Logger* logger) {
+ MutexLock l(&log_mutex);
+ LogDestination::log_destination(severity)->logger_ = logger;
+}
+
+// L < log_mutex. Acquires and releases mutex_.
+int64 LogMessage::num_messages(int severity) {
+ MutexLock l(&log_mutex);
+ return num_messages_[severity];
+}
+
+// Output the COUNTER value. This is only valid if ostream is a
+// LogStream.
+ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
+ LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os);
+ CHECK(log == log->self());
+ os << log->ctr();
+ return os;
+}
+
+ErrnoLogMessage::ErrnoLogMessage(const char* file, int line,
+ LogSeverity severity, int ctr,
+ void (LogMessage::*send_method)())
+ : LogMessage(file, line, severity, ctr, send_method) {
+}
+
+ErrnoLogMessage::~ErrnoLogMessage() {
+ // Don't access errno directly because it may have been altered
+ // while streaming the message.
+ char buf[100];
+ posix_strerror_r(preserved_errno(), buf, sizeof(buf));
+ stream() << ": " << buf << " [" << preserved_errno() << "]";
+}
+
+void FlushLogFiles(LogSeverity min_severity) {
+ LogDestination::FlushLogFiles(min_severity);
+}
+
+void FlushLogFilesUnsafe(LogSeverity min_severity) {
+ LogDestination::FlushLogFilesUnsafe(min_severity);
+}
+
+void SetLogDestination(LogSeverity severity, const char* base_filename) {
+ LogDestination::SetLogDestination(severity, base_filename);
+}
+
+void SetLogSymlink(LogSeverity severity, const char* symlink_basename) {
+ LogDestination::SetLogSymlink(severity, symlink_basename);
+}
+
+LogSink::~LogSink() {
+}
+
+void LogSink::WaitTillSent() {
+ // noop default
+}
+
+string LogSink::ToString(LogSeverity severity, const char* file, int line,
+ const struct ::tm* tm_time,
+ const char* message, size_t message_len) {
+ ostringstream stream(string(message, message_len));
+ stream.fill('0');
+
+ // FIXME(jrvb): Updating this to use the correct value for usecs
+ // requires changing the signature for both this method and
+ // LogSink::send(). This change needs to be done in a separate CL
+ // so subclasses of LogSink can be updated at the same time.
+ int usecs = 0;
+
+ stream << LogSeverityNames[severity][0]
+ << setw(2) << 1+tm_time->tm_mon
+ << setw(2) << tm_time->tm_mday
+ << ' '
+ << setw(2) << tm_time->tm_hour << ':'
+ << setw(2) << tm_time->tm_min << ':'
+ << setw(2) << tm_time->tm_sec << '.'
+ << setw(6) << usecs
+ << ' '
+ << setfill(' ') << setw(5) << GetTID() << setfill('0')
+ << ' '
+ << file << ':' << line << "] ";
+
+ stream << string(message, message_len);
+ return stream.str();
+}
+
+void AddLogSink(LogSink *destination) {
+ LogDestination::AddLogSink(destination);
+}
+
+void RemoveLogSink(LogSink *destination) {
+ LogDestination::RemoveLogSink(destination);
+}
+
+void SetLogFilenameExtension(const char* ext) {
+ LogDestination::SetLogFilenameExtension(ext);
+}
+
+void SetStderrLogging(LogSeverity min_severity) {
+ LogDestination::SetStderrLogging(min_severity);
+}
+
+void SetEmailLogging(LogSeverity min_severity, const char* addresses) {
+ LogDestination::SetEmailLogging(min_severity, addresses);
+}
+
+void LogToStderr() {
+ LogDestination::LogToStderr();
+}
+
+namespace base {
+namespace internal {
+
+bool GetExitOnDFatal() {
+ MutexLock l(&log_mutex);
+ return exit_on_dfatal;
+}
+
+// Determines whether we exit the program for a LOG(DFATAL) message in
+// debug mode. It does this by skipping the call to Fail/FailQuietly.
+// This is intended for testing only.
+//
+// This can have some effects on LOG(FATAL) as well. Failure messages
+// are always allocated (rather than sharing a buffer), the crash
+// reason is not recorded, the "gwq" status message is not updated,
+// and the stack trace is not recorded. The LOG(FATAL) *will* still
+// exit the program. Since this function is used only in testing,
+// these differences are acceptable.
+void SetExitOnDFatal(bool value) {
+ MutexLock l(&log_mutex);
+ exit_on_dfatal = value;
+}
+
+} // namespace internal
+} // namespace base
+
+// use_logging controls whether the logging functions LOG/VLOG are used
+// to log errors. It should be set to false when the caller holds the
+// log_mutex.
+static bool SendEmailInternal(const char*dest, const char *subject,
+ const char*body, bool use_logging) {
+ if (dest && *dest) {
+ if ( use_logging ) {
+ VLOG(1) << "Trying to send TITLE:" << subject
+ << " BODY:" << body << " to " << dest;
+ } else {
+ fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n",
+ subject, body, dest);
+ }
+
+ string cmd =
+ FLAGS_logmailer + " -s\"" + subject + "\" " + dest;
+ FILE* pipe = popen(cmd.c_str(), "w");
+ if (pipe != NULL) {
+ // Add the body if we have one
+ if (body)
+ fwrite(body, sizeof(char), strlen(body), pipe);
+ bool ok = pclose(pipe) != -1;
+ if ( !ok ) {
+ if ( use_logging ) {
+ char buf[100];
+ posix_strerror_r(errno, buf, sizeof(buf));
+ LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf;
+ } else {
+ char buf[100];
+ posix_strerror_r(errno, buf, sizeof(buf));
+ fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf);
+ }
+ }
+ return ok;
+ } else {
+ if ( use_logging ) {
+ LOG(ERROR) << "Unable to send mail to " << dest;
+ } else {
+ fprintf(stderr, "Unable to send mail to %s\n", dest);
+ }
+ }
+ }
+ return false;
+}
+
+bool SendEmail(const char*dest, const char *subject, const char*body){
+ return SendEmailInternal(dest, subject, body, true);
+}
+
+static void GetTempDirectories(vector<string>* list) {
+ list->clear();
+#ifdef OS_WINDOWS
+ // On windows we'll try to find a directory in this order:
+ // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is)
+ // C:/TMP/
+ // C:/TEMP/
+ // C:/WINDOWS/ or C:/WINNT/
+ // .
+ char tmp[MAX_PATH];
+ if (GetTempPathA(MAX_PATH, tmp))
+ list->push_back(tmp);
+ list->push_back("C:\\tmp\\");
+ list->push_back("C:\\temp\\");
+#else
+ // Directories, in order of preference. If we find a dir that
+ // exists, we stop adding other less-preferred dirs
+ const char * candidates[] = {
+ // Non-null only during unittest/regtest
+ getenv("TEST_TMPDIR"),
+
+ // Explicitly-supplied temp dirs
+ getenv("TMPDIR"), getenv("TMP"),
+
+ // If all else fails
+ "/tmp",
+ };
+
+ for (int i = 0; i < ARRAYSIZE(candidates); i++) {
+ const char *d = candidates[i];
+ if (!d) continue; // Empty env var
+
+ // Make sure we don't surprise anyone who's expecting a '/'
+ string dstr = d;
+ if (dstr[dstr.size() - 1] != '/') {
+ dstr += "/";
+ }
+ list->push_back(dstr);
+
+ struct stat statbuf;
+ if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) {
+ // We found a dir that exists - we're done.
+ return;
+ }
+ }
+
+#endif
+}
+
+static vector<string>* logging_directories_list;
+
+const vector<string>& GetLoggingDirectories() {
+ // Not strictly thread-safe but we're called early in InitGoogle().
+ if (logging_directories_list == NULL) {
+ logging_directories_list = new vector<string>;
+
+ if ( !FLAGS_log_dir.empty() ) {
+ // A dir was specified, we should use it
+ logging_directories_list->push_back(FLAGS_log_dir.c_str());
+ } else {
+ GetTempDirectories(logging_directories_list);
+#ifdef OS_WINDOWS
+ char tmp[MAX_PATH];
+ if (GetWindowsDirectoryA(tmp, MAX_PATH))
+ logging_directories_list->push_back(tmp);
+ logging_directories_list->push_back(".\\");
+#else
+ logging_directories_list->push_back("./");
+#endif
+ }
+ }
+ return *logging_directories_list;
+}
+
+void TestOnly_ClearLoggingDirectoriesList() {
+ fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
+ "called from test code.\n");
+ delete logging_directories_list;
+ logging_directories_list = NULL;
+}
+
+void GetExistingTempDirectories(vector<string>* list) {
+ GetTempDirectories(list);
+ vector<string>::iterator i_dir = list->begin();
+ while( i_dir != list->end() ) {
+ // zero arg to access means test for existence; no constant
+ // defined on windows
+ if ( access(i_dir->c_str(), 0) ) {
+ i_dir = list->erase(i_dir);
+ } else {
+ ++i_dir;
+ }
+ }
+}
+
+void TruncateLogFile(const char *path, int64 limit, int64 keep) {
+#ifdef HAVE_UNISTD_H
+ struct stat statbuf;
+ const int kCopyBlockSize = 8 << 10;
+ char copybuf[kCopyBlockSize];
+ int64 read_offset, write_offset;
+ // Don't follow symlinks unless they're our own fd symlinks in /proc
+ int flags = O_RDWR;
+ const char *procfd_prefix = "/proc/self/fd/";
+ if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW;
+
+ int fd = open(path, flags);
+ if (fd == -1) {
+ if (errno == EFBIG) {
+ // The log file in question has got too big for us to open. The
+ // real fix for this would be to compile logging.cc (or probably
+ // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's
+ // rather scary.
+ // Instead just truncate the file to something we can manage
+ if (truncate(path, 0) == -1) {
+ PLOG(ERROR) << "Unable to truncate " << path;
+ } else {
+ LOG(ERROR) << "Truncated " << path << " due to EFBIG error";
+ }
+ } else {
+ PLOG(ERROR) << "Unable to open " << path;
+ }
+ return;
+ }
+
+ if (fstat(fd, &statbuf) == -1) {
+ PLOG(ERROR) << "Unable to fstat()";
+ goto out_close_fd;
+ }
+
+ // See if the path refers to a regular file bigger than the
+ // specified limit
+ if (!S_ISREG(statbuf.st_mode)) goto out_close_fd;
+ if (statbuf.st_size <= limit) goto out_close_fd;
+ if (statbuf.st_size <= keep) goto out_close_fd;
+
+ // This log file is too large - we need to truncate it
+ LOG(INFO) << "Truncating " << path << " to " << keep << " bytes";
+
+ // Copy the last "keep" bytes of the file to the beginning of the file
+ read_offset = statbuf.st_size - keep;
+ write_offset = 0;
+ int bytesin, bytesout;
+ while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) {
+ bytesout = pwrite(fd, copybuf, bytesin, write_offset);
+ if (bytesout == -1) {
+ PLOG(ERROR) << "Unable to write to " << path;
+ break;
+ } else if (bytesout != bytesin) {
+ LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout;
+ }
+ read_offset += bytesin;
+ write_offset += bytesout;
+ }
+ if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path;
+
+ // Truncate the remainder of the file. If someone else writes to the
+ // end of the file after our last read() above, we lose their latest
+ // data. Too bad ...
+ if (ftruncate(fd, write_offset) == -1) {
+ PLOG(ERROR) << "Unable to truncate " << path;
+ }
+
+ out_close_fd:
+ close(fd);
+#else
+ LOG(ERROR) << "No log truncation support.";
+#endif
+}
+
+void TruncateStdoutStderr() {
+#ifdef HAVE_UNISTD_H
+ int64 limit = MaxLogSize() << 20;
+ int64 keep = 1 << 20;
+ TruncateLogFile("/proc/self/fd/1", limit, keep);
+ TruncateLogFile("/proc/self/fd/2", limit, keep);
+#else
+ LOG(ERROR) << "No log truncation support.";
+#endif
+}
+
+
+// Helper functions for string comparisons.
+#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
+ string* Check##func##expected##Impl(const char* s1, const char* s2, \
+ const char* names) { \
+ bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
+ if (equal == expected) return NULL; \
+ else { \
+ strstream ss; \
+ if (!s1) s1 = ""; \
+ if (!s2) s2 = ""; \
+ ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
+ return new string(ss.str(), ss.pcount()); \
+ } \
+ }
+DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
+DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
+DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
+DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
+#undef DEFINE_CHECK_STROP_IMPL
+
+int posix_strerror_r(int err, char *buf, size_t len) {
+ // Sanity check input parameters
+ if (buf == NULL || len <= 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Reset buf and errno, and try calling whatever version of strerror_r()
+ // is implemented by glibc
+ buf[0] = '\000';
+ int old_errno = errno;
+ errno = 0;
+ char *rc = reinterpret_cast<char *>(strerror_r(err, buf, len));
+
+ // Both versions set errno on failure
+ if (errno) {
+ // Should already be there, but better safe than sorry
+ buf[0] = '\000';
+ return -1;
+ }
+ errno = old_errno;
+
+ // POSIX is vague about whether the string will be terminated, although
+ // is indirectly implies that typically ERANGE will be returned, instead
+ // of truncating the string. This is different from the GNU implementation.
+ // We play it safe by always terminating the string explicitly.
+ buf[len-1] = '\000';
+
+ // If the function succeeded, we can use its exit code to determine the
+ // semantics implemented by glibc
+ if (!rc) {
+ return 0;
+ } else {
+ // GNU semantics detected
+ if (rc == buf) {
+ return 0;
+ } else {
+ buf[0] = '\000';
+#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
+ if (reinterpret_cast<intptr_t>(rc) < sys_nerr) {
+ // This means an error on MacOSX or FreeBSD.
+ return -1;
+ }
+#endif
+ strncat(buf, rc, len-1);
+ return 0;
+ }
+ }
+}
+
+LogMessageFatal::LogMessageFatal(const char* file, int line) :
+ LogMessage(file, line, FATAL) {}
+
+LogMessageFatal::LogMessageFatal(const char* file, int line,
+ const CheckOpString& result) :
+ LogMessage(file, line, result) {}
+
+LogMessageFatal::~LogMessageFatal() {
+ Flush();
+ LogMessage::Fail();
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/raw_logging.cc b/extern/libmv/third_party/glog/src/raw_logging.cc
new file mode 100644
index 00000000000..b179a1eded4
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/raw_logging.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// logging_unittest.cc covers the functionality herein
+
+#include "utilities.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h> // for close() and write()
+#endif
+#include <fcntl.h> // for open()
+#include <time.h>
+#include "config.h"
+#include <glog/logging.h> // To pick up flag settings etc.
+#include <glog/raw_logging.h>
+#include "base/commandlineflags.h"
+
+#ifdef HAVE_STACKTRACE
+# include "stacktrace.h"
+#endif
+
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h> // for syscall()
+#elif defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h> // for syscall()
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)
+# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len)
+#else
+ // Not so safe, but what can you do?
+# define safe_write(fd, s, len) write(fd, s, len)
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Data for RawLog__ below. We simply pick up the latest
+// time data created by a normal log message to avoid calling
+// localtime_r which can allocate memory.
+static struct ::tm last_tm_time_for_raw_log;
+static int last_usecs_for_raw_log;
+
+void RawLog__SetLastTime(const struct ::tm& t, int usecs) {
+ memcpy(&last_tm_time_for_raw_log, &t, sizeof(last_tm_time_for_raw_log));
+ last_usecs_for_raw_log = usecs;
+}
+
+// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
+// that invoke malloc() and getenv() that might acquire some locks.
+// If this becomes a problem we should reimplement a subset of vsnprintf
+// that does not need locks and malloc.
+
+// Helper for RawLog__ below.
+// *DoRawLog writes to *buf of *size and move them past the written portion.
+// It returns true iff there was no overflow or error.
+static bool DoRawLog(char** buf, int* size, const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ int n = vsnprintf(*buf, *size, format, ap);
+ va_end(ap);
+ if (n < 0 || n > *size) return false;
+ *size -= n;
+ *buf += n;
+ return true;
+}
+
+// Helper for RawLog__ below.
+inline static bool VADoRawLog(char** buf, int* size,
+ const char* format, va_list ap) {
+ int n = vsnprintf(*buf, *size, format, ap);
+ if (n < 0 || n > *size) return false;
+ *size -= n;
+ *buf += n;
+ return true;
+}
+
+static const int kLogBufSize = 3000;
+static bool crashed = false;
+static CrashReason crash_reason;
+static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0'
+
+void RawLog__(LogSeverity severity, const char* file, int line,
+ const char* format, ...) {
+ if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold ||
+ FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) {
+ return; // this stderr log message is suppressed
+ }
+ // can't call localtime_r here: it can allocate
+ struct ::tm& t = last_tm_time_for_raw_log;
+ char buffer[kLogBufSize];
+ char* buf = buffer;
+ int size = sizeof(buffer);
+
+ // NOTE: this format should match the specification in base/logging.h
+ DoRawLog(&buf, &size, "%c%02d%02d %02d:%02d:%02d.%06d %5u %s:%d] RAW: ",
+ LogSeverityNames[severity][0],
+ 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
+ last_usecs_for_raw_log,
+ static_cast<unsigned int>(GetTID()),
+ const_basename(const_cast<char *>(file)), line);
+
+ // Record the position and size of the buffer after the prefix
+ const char* msg_start = buf;
+ const int msg_size = size;
+
+ va_list ap;
+ va_start(ap, format);
+ bool no_chop = VADoRawLog(&buf, &size, format, ap);
+ va_end(ap);
+ if (no_chop) {
+ DoRawLog(&buf, &size, "\n");
+ } else {
+ DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n");
+ }
+ // We make a raw syscall to write directly to the stderr file descriptor,
+ // avoiding FILE buffering (to avoid invoking malloc()), and bypassing
+ // libc (to side-step any libc interception).
+ // We write just once to avoid races with other invocations of RawLog__.
+ safe_write(STDERR_FILENO, buffer, strlen(buffer));
+ if (severity == FATAL) {
+ if (!sync_val_compare_and_swap(&crashed, false, true)) {
+ crash_reason.filename = file;
+ crash_reason.line_number = line;
+ memcpy(crash_buf, msg_start, msg_size); // Don't include prefix
+ crash_reason.message = crash_buf;
+#ifdef HAVE_STACKTRACE
+ crash_reason.depth =
+ GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1);
+#else
+ crash_reason.depth = 0;
+#endif
+ SetCrashReason(&crash_reason);
+ }
+ LogMessage::Fail(); // abort()
+ }
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/signalhandler.cc b/extern/libmv/third_party/glog/src/signalhandler.cc
new file mode 100644
index 00000000000..9fc91b3390d
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/signalhandler.cc
@@ -0,0 +1,348 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// Implementation of InstallFailureSignalHandler().
+
+#include "utilities.h"
+#include "stacktrace.h"
+#include "symbolize.h"
+#include "glog/logging.h"
+
+#include <signal.h>
+#include <time.h>
+#ifdef HAVE_UCONTEXT_H
+# include <ucontext.h>
+#endif
+#ifdef HAVE_SYS_UCONTEXT_H
+# include <sys/ucontext.h>
+#endif
+#include <algorithm>
+
+_START_GOOGLE_NAMESPACE_
+
+namespace {
+
+// We'll install the failure signal handler for these signals. We could
+// use strsignal() to get signal names, but we don't use it to avoid
+// introducing yet another #ifdef complication.
+//
+// The list should be synced with the comment in signalhandler.h.
+const struct {
+ int number;
+ const char *name;
+} kFailureSignals[] = {
+ { SIGSEGV, "SIGSEGV" },
+ { SIGILL, "SIGILL" },
+ { SIGFPE, "SIGFPE" },
+ { SIGABRT, "SIGABRT" },
+ { SIGBUS, "SIGBUS" },
+ { SIGTERM, "SIGTERM" },
+};
+
+// Returns the program counter from signal context, NULL if unknown.
+void* GetPC(void* ucontext_in_void) {
+#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
+ if (ucontext_in_void != NULL) {
+ ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
+ return (void*)context->PC_FROM_UCONTEXT;
+ }
+#endif
+ return NULL;
+}
+
+// The class is used for formatting error messages. We don't use printf()
+// as it's not async signal safe.
+class MinimalFormatter {
+ public:
+ MinimalFormatter(char *buffer, int size)
+ : buffer_(buffer),
+ cursor_(buffer),
+ end_(buffer + size) {
+ }
+
+ // Returns the number of bytes written in the buffer.
+ int num_bytes_written() const { return cursor_ - buffer_; }
+
+ // Appends string from "str" and updates the internal cursor.
+ void AppendString(const char* str) {
+ int i = 0;
+ while (str[i] != '\0' && cursor_ + i < end_) {
+ cursor_[i] = str[i];
+ ++i;
+ }
+ cursor_ += i;
+ }
+
+ // Formats "number" in "radix" and updates the internal cursor.
+ // Lowercase letters are used for 'a' - 'z'.
+ void AppendUint64(uint64 number, int radix) {
+ int i = 0;
+ while (cursor_ + i < end_) {
+ const int tmp = number % radix;
+ number /= radix;
+ cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10);
+ ++i;
+ if (number == 0) {
+ break;
+ }
+ }
+ // Reverse the bytes written.
+ std::reverse(cursor_, cursor_ + i);
+ cursor_ += i;
+ }
+
+ // Formats "number" as hexadecimal number, and updates the internal
+ // cursor. Padding will be added in front if needed.
+ void AppendHexWithPadding(uint64 number, int width) {
+ char* start = cursor_;
+ AppendString("0x");
+ AppendUint64(number, 16);
+ // Move to right and add padding in front if needed.
+ if (cursor_ < start + width) {
+ const int64 delta = start + width - cursor_;
+ std::copy(start, cursor_, start + delta);
+ std::fill(start, start + delta, ' ');
+ cursor_ = start + width;
+ }
+ }
+
+ private:
+ char *buffer_;
+ char *cursor_;
+ const char * const end_;
+};
+
+// Writes the given data with the size to the standard error.
+void WriteToStderr(const char* data, int size) {
+ write(STDERR_FILENO, data, size);
+}
+
+// The writer function can be changed by InstallFailureWriter().
+void (*g_failure_writer)(const char* data, int size) = WriteToStderr;
+
+// Dumps time information. We don't dump human-readable time information
+// as localtime() is not guaranteed to be async signal safe.
+void DumpTimeInfo() {
+ time_t time_in_sec = time(NULL);
+ char buf[256]; // Big enough for time info.
+ MinimalFormatter formatter(buf, sizeof(buf));
+ formatter.AppendString("*** Aborted at ");
+ formatter.AppendUint64(time_in_sec, 10);
+ formatter.AppendString(" (unix time)");
+ formatter.AppendString(" try \"date -d @");
+ formatter.AppendUint64(time_in_sec, 10);
+ formatter.AppendString("\" if you are using GNU date ***\n");
+ g_failure_writer(buf, formatter.num_bytes_written());
+}
+
+// Dumps information about the signal to STDERR.
+void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
+ // Get the signal name.
+ const char* signal_name = NULL;
+ for (int i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
+ if (signal_number == kFailureSignals[i].number) {
+ signal_name = kFailureSignals[i].name;
+ }
+ }
+
+ char buf[256]; // Big enough for signal info.
+ MinimalFormatter formatter(buf, sizeof(buf));
+
+ formatter.AppendString("*** ");
+ if (signal_name) {
+ formatter.AppendString(signal_name);
+ } else {
+ // Use the signal number if the name is unknown. The signal name
+ // should be known, but just in case.
+ formatter.AppendString("Signal ");
+ formatter.AppendUint64(signal_number, 10);
+ }
+ formatter.AppendString(" (@0x");
+ formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16);
+ formatter.AppendString(")");
+ formatter.AppendString(" received by PID ");
+ formatter.AppendUint64(getpid(), 10);
+ formatter.AppendString(" (TID 0x");
+ // We assume pthread_t is an integral number or a pointer, rather
+ // than a complex struct. In some environments, pthread_self()
+ // returns an uint64 but in some other environments pthread_self()
+ // returns a pointer. Hence we use C-style cast here, rather than
+ // reinterpret/static_cast, to support both types of environments.
+ formatter.AppendUint64((uintptr_t)pthread_self(), 16);
+ formatter.AppendString(") ");
+ // Only linux has the PID of the signal sender in si_pid.
+#ifdef OS_LINUX
+ formatter.AppendString("from PID ");
+ formatter.AppendUint64(siginfo->si_pid, 10);
+ formatter.AppendString("; ");
+#endif
+ formatter.AppendString("stack trace: ***\n");
+ g_failure_writer(buf, formatter.num_bytes_written());
+}
+
+// Dumps information about the stack frame to STDERR.
+void DumpStackFrameInfo(const char* prefix, void* pc) {
+ // Get the symbol name.
+ const char *symbol = "(unknown)";
+ char symbolized[1024]; // Big enough for a sane symbol.
+ // Symbolizes the previous address of pc because pc may be in the
+ // next function.
+ if (Symbolize(reinterpret_cast<char *>(pc) - 1,
+ symbolized, sizeof(symbolized))) {
+ symbol = symbolized;
+ }
+
+ char buf[1024]; // Big enough for stack frame info.
+ MinimalFormatter formatter(buf, sizeof(buf));
+
+ formatter.AppendString(prefix);
+ formatter.AppendString("@ ");
+ const int width = 2 * sizeof(void*) + 2; // + 2 for "0x".
+ formatter.AppendHexWithPadding(reinterpret_cast<uintptr_t>(pc), width);
+ formatter.AppendString(" ");
+ formatter.AppendString(symbol);
+ formatter.AppendString("\n");
+ g_failure_writer(buf, formatter.num_bytes_written());
+}
+
+// Invoke the default signal handler.
+void InvokeDefaultSignalHandler(int signal_number) {
+ struct sigaction sig_action;
+ memset(&sig_action, 0, sizeof(sig_action));
+ sigemptyset(&sig_action.sa_mask);
+ sig_action.sa_handler = SIG_DFL;
+ sigaction(signal_number, &sig_action, NULL);
+ kill(getpid(), signal_number);
+}
+
+// This variable is used for protecting FailureSignalHandler() from
+// dumping stuff while another thread is doing it. Our policy is to let
+// the first thread dump stuff and let other threads wait.
+// See also comments in FailureSignalHandler().
+static pthread_t* g_entered_thread_id_pointer = NULL;
+
+// Dumps signal and stack frame information, and invokes the default
+// signal handler once our job is done.
+void FailureSignalHandler(int signal_number,
+ siginfo_t *signal_info,
+ void *ucontext) {
+ // First check if we've already entered the function. We use an atomic
+ // compare and swap operation for platforms that support it. For other
+ // platforms, we use a naive method that could lead to a subtle race.
+
+ // We assume pthread_self() is async signal safe, though it's not
+ // officially guaranteed.
+ pthread_t my_thread_id = pthread_self();
+ // NOTE: We could simply use pthread_t rather than pthread_t* for this,
+ // if pthread_self() is guaranteed to return non-zero value for thread
+ // ids, but there is no such guarantee. We need to distinguish if the
+ // old value (value returned from __sync_val_compare_and_swap) is
+ // different from the original value (in this case NULL).
+ pthread_t* old_thread_id_pointer =
+ glog_internal_namespace_::sync_val_compare_and_swap(
+ &g_entered_thread_id_pointer,
+ static_cast<pthread_t*>(NULL),
+ &my_thread_id);
+ if (old_thread_id_pointer != NULL) {
+ // We've already entered the signal handler. What should we do?
+ if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
+ // It looks the current thread is reentering the signal handler.
+ // Something must be going wrong (maybe we are reentering by another
+ // type of signal?). Kill ourself by the default signal handler.
+ InvokeDefaultSignalHandler(signal_number);
+ }
+ // Another thread is dumping stuff. Let's wait until that thread
+ // finishes the job and kills the process.
+ while (true) {
+ sleep(1);
+ }
+ }
+ // This is the first time we enter the signal handler. We are going to
+ // do some interesting stuff from here.
+ // TODO(satorux): We might want to set timeout here using alarm(), but
+ // mixing alarm() and sleep() can be a bad idea.
+
+ // First dump time info.
+ DumpTimeInfo();
+
+ // Get the program counter from ucontext.
+ void *pc = GetPC(ucontext);
+ DumpStackFrameInfo("PC: ", pc);
+
+#ifdef HAVE_STACKTRACE
+ // Get the stack traces.
+ void *stack[32];
+ // +1 to exclude this function.
+ const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1);
+ DumpSignalInfo(signal_number, signal_info);
+ // Dump the stack traces.
+ for (int i = 0; i < depth; ++i) {
+ DumpStackFrameInfo(" ", stack[i]);
+ }
+#endif
+
+ // *** TRANSITION ***
+ //
+ // BEFORE this point, all code must be async-termination-safe!
+ // (See WARNING above.)
+ //
+ // AFTER this point, we do unsafe things, like using LOG()!
+ // The process could be terminated or hung at any time. We try to
+ // do more useful things first and riskier things later.
+
+ // Flush the logs before we do anything in case 'anything'
+ // causes problems.
+ FlushLogFilesUnsafe(0);
+
+ // Kill ourself by the default signal handler.
+ InvokeDefaultSignalHandler(signal_number);
+}
+
+} // namespace
+
+void InstallFailureSignalHandler() {
+ // Build the sigaction struct.
+ struct sigaction sig_action;
+ memset(&sig_action, 0, sizeof(sig_action));
+ sigemptyset(&sig_action.sa_mask);
+ sig_action.sa_flags |= SA_SIGINFO;
+ sig_action.sa_sigaction = &FailureSignalHandler;
+
+ for (int i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
+ CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL));
+ }
+}
+
+void InstallFailureWriter(void (*writer)(const char* data, int size)) {
+ g_failure_writer = writer;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/stacktrace.h b/extern/libmv/third_party/glog/src/stacktrace.h
new file mode 100644
index 00000000000..8c3e8fe8f8d
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/stacktrace.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Routines to extract the current stack trace. These functions are
+// thread-safe.
+
+#ifndef BASE_STACKTRACE_H_
+#define BASE_STACKTRACE_H_
+
+#include "config.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// This is similar to the GetStackFrames routine, except that it returns
+// the stack trace only, and not the stack frame sizes as well.
+// Example:
+// main() { foo(); }
+// foo() { bar(); }
+// bar() {
+// void* result[10];
+// int depth = GetStackFrames(result, 10, 1);
+// }
+//
+// This produces:
+// result[0] foo
+// result[1] main
+// .... ...
+//
+// "result" must not be NULL.
+extern int GetStackTrace(void** result, int max_depth, int skip_count);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif // BASE_STACKTRACE_H_
diff --git a/extern/libmv/third_party/glog/src/stacktrace_generic-inl.h b/extern/libmv/third_party/glog/src/stacktrace_generic-inl.h
new file mode 100644
index 00000000000..fad81d3e3f4
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/stacktrace_generic-inl.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Portable implementation - just use glibc
+//
+// Note: The glibc implementation may cause a call to malloc.
+// This can cause a deadlock in HeapProfiler.
+#include <execinfo.h>
+#include <string.h>
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+ static const int kStackLength = 64;
+ void * stack[kStackLength];
+ int size;
+
+ size = backtrace(stack, kStackLength);
+ skip_count++; // we want to skip the current frame as well
+ int result_count = size - skip_count;
+ if (result_count < 0)
+ result_count = 0;
+ if (result_count > max_depth)
+ result_count = max_depth;
+ for (int i = 0; i < result_count; i++)
+ result[i] = stack[i + skip_count];
+
+ return result_count;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h
new file mode 100644
index 00000000000..0dc14c6506e
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2005 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Arun Sharma
+//
+// Produce stack trace using libunwind
+
+#include "utilities.h"
+
+extern "C" {
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+}
+#include "glog/raw_logging.h"
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Sometimes, we can try to get a stack trace from within a stack
+// trace, because libunwind can call mmap (maybe indirectly via an
+// internal mmap based memory allocator), and that mmap gets trapped
+// and causes a stack-trace request. If were to try to honor that
+// recursive request, we'd end up with infinite recursion or deadlock.
+// Luckily, it's safe to ignore those subsequent traces. In such
+// cases, we return 0 to indicate the situation.
+static bool g_now_entering = false;
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+ void *ip;
+ int n = 0;
+ unw_cursor_t cursor;
+ unw_context_t uc;
+
+ if (sync_val_compare_and_swap(&g_now_entering, false, true)) {
+ return 0;
+ }
+
+ unw_getcontext(&uc);
+ RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
+ skip_count++; // Do not include the "GetStackTrace" frame
+
+ while (n < max_depth) {
+ int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
+ if (ret < 0)
+ break;
+ if (skip_count > 0) {
+ skip_count--;
+ } else {
+ result[n++] = ip;
+ }
+ ret = unw_step(&cursor);
+ if (ret <= 0)
+ break;
+ }
+
+ g_now_entering = false;
+ return n;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h b/extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h
new file mode 100644
index 00000000000..1090ddedbc7
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Craig Silverstein
+//
+// Produce stack trace. I'm guessing (hoping!) the code is much like
+// for x86. For apple machines, at least, it seems to be; see
+// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html
+// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
+// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
+
+#include <stdio.h>
+#include <stdint.h> // for uintptr_t
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Given a pointer to a stack frame, locate and return the calling
+// stackframe, or return NULL if no stackframe can be found. Perform sanity
+// checks (the strictness of which is controlled by the boolean parameter
+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
+template<bool STRICT_UNWINDING>
+static void **NextStackFrame(void **old_sp) {
+ void **new_sp = (void **) *old_sp;
+
+ // Check that the transition from frame pointer old_sp to frame
+ // pointer new_sp isn't clearly bogus
+ if (STRICT_UNWINDING) {
+ // With the stack growing downwards, older stack frame must be
+ // at a greater address that the current one.
+ if (new_sp <= old_sp) return NULL;
+ // Assume stack frames larger than 100,000 bytes are bogus.
+ if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
+ } else {
+ // In the non-strict mode, allow discontiguous stack frames.
+ // (alternate-signal-stacks for example).
+ if (new_sp == old_sp) return NULL;
+ // And allow frames upto about 1MB.
+ if ((new_sp > old_sp)
+ && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
+ }
+ if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
+ return new_sp;
+}
+
+// This ensures that GetStackTrace stes up the Link Register properly.
+void StacktracePowerPCDummyFunction() __attribute__((noinline));
+void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+ void **sp;
+ // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
+ // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a
+ // different asm syntax. I don't know quite the best way to discriminate
+ // systems using the old as from the new one; I've gone with __APPLE__.
+#ifdef __APPLE__
+ __asm__ volatile ("mr %0,r1" : "=r" (sp));
+#else
+ __asm__ volatile ("mr %0,1" : "=r" (sp));
+#endif
+
+ // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
+ // entry that holds the return address of the subroutine call (what
+ // instruction we run after our function finishes). This is the
+ // same as the stack-pointer of our parent routine, which is what we
+ // want here. While the compiler will always(?) set up LR for
+ // subroutine calls, it may not for leaf functions (such as this one).
+ // This routine forces the compiler (at least gcc) to push it anyway.
+ StacktracePowerPCDummyFunction();
+
+ // The LR save area is used by the callee, so the top entry is bogus.
+ skip_count++;
+
+ int n = 0;
+ while (sp && n < max_depth) {
+ if (skip_count > 0) {
+ skip_count--;
+ } else {
+ // PowerPC has 3 main ABIs, which say where in the stack the
+ // Link Register is. For DARWIN and AIX (used by apple and
+ // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc),
+ // it's in sp[1].
+#if defined(_CALL_AIX) || defined(_CALL_DARWIN)
+ result[n++] = *(sp+2);
+#elif defined(_CALL_SYSV)
+ result[n++] = *(sp+1);
+#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))
+ // This check is in case the compiler doesn't define _CALL_AIX/etc.
+ result[n++] = *(sp+2);
+#elif defined(__linux)
+ // This check is in case the compiler doesn't define _CALL_SYSV.
+ result[n++] = *(sp+1);
+#else
+#error Need to specify the PPC ABI for your archiecture.
+#endif
+ }
+ // Use strict unwinding rules.
+ sp = NextStackFrame<true>(sp);
+ }
+ return n;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/stacktrace_x86-inl.h b/extern/libmv/third_party/glog/src/stacktrace_x86-inl.h
new file mode 100644
index 00000000000..cfd31f783e3
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/stacktrace_x86-inl.h
@@ -0,0 +1,139 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Produce stack trace
+
+#include <stdint.h> // for uintptr_t
+
+#include "utilities.h" // for OS_* macros
+
+#if !defined(OS_WINDOWS)
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+#include <stdio.h> // for NULL
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Given a pointer to a stack frame, locate and return the calling
+// stackframe, or return NULL if no stackframe can be found. Perform sanity
+// checks (the strictness of which is controlled by the boolean parameter
+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
+template<bool STRICT_UNWINDING>
+static void **NextStackFrame(void **old_sp) {
+ void **new_sp = (void **) *old_sp;
+
+ // Check that the transition from frame pointer old_sp to frame
+ // pointer new_sp isn't clearly bogus
+ if (STRICT_UNWINDING) {
+ // With the stack growing downwards, older stack frame must be
+ // at a greater address that the current one.
+ if (new_sp <= old_sp) return NULL;
+ // Assume stack frames larger than 100,000 bytes are bogus.
+ if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
+ } else {
+ // In the non-strict mode, allow discontiguous stack frames.
+ // (alternate-signal-stacks for example).
+ if (new_sp == old_sp) return NULL;
+ // And allow frames upto about 1MB.
+ if ((new_sp > old_sp)
+ && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
+ }
+ if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
+#ifdef __i386__
+ // On 64-bit machines, the stack pointer can be very close to
+ // 0xffffffff, so we explicitly check for a pointer into the
+ // last two pages in the address space
+ if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
+#endif
+#if !defined(OS_WINDOWS)
+ if (!STRICT_UNWINDING) {
+ // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test
+ // on AMD-based machines with VDSO-enabled kernels.
+ // Make an extra sanity check to insure new_sp is readable.
+ // Note: NextStackFrame<false>() is only called while the program
+ // is already on its last leg, so it's ok to be slow here.
+ static int page_size = getpagesize();
+ void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));
+ if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1)
+ return NULL;
+ }
+#endif
+ return new_sp;
+}
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+ void **sp;
+#ifdef __i386__
+ // Stack frame format:
+ // sp[0] pointer to previous frame
+ // sp[1] caller address
+ // sp[2] first argument
+ // ...
+ sp = (void **)&result - 2;
+#endif
+
+#ifdef __x86_64__
+ // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8
+ unsigned long rbp;
+ // Move the value of the register %rbp into the local variable rbp.
+ // We need 'volatile' to prevent this instruction from getting moved
+ // around during optimization to before function prologue is done.
+ // An alternative way to achieve this
+ // would be (before this __asm__ instruction) to call Noop() defined as
+ // static void Noop() __attribute__ ((noinline)); // prevent inlining
+ // static void Noop() { asm(""); } // prevent optimizing-away
+ __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
+ // Arguments are passed in registers on x86-64, so we can't just
+ // offset from &result
+ sp = (void **) rbp;
+#endif
+
+ int n = 0;
+ while (sp && n < max_depth) {
+ if (*(sp+1) == (void *)0) {
+ // In 64-bit code, we often see a frame that
+ // points to itself and has a return address of 0.
+ break;
+ }
+ if (skip_count > 0) {
+ skip_count--;
+ } else {
+ result[n++] = *(sp+1);
+ }
+ // Use strict unwinding rules.
+ sp = NextStackFrame<true>(sp);
+ }
+ return n;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h b/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h
new file mode 100644
index 00000000000..f7d1dca85bc
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2005 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Arun Sharma
+//
+// Produce stack trace using libgcc
+
+extern "C" {
+#include <stdlib.h> // for NULL
+#include <unwind.h> // ABI defined unwinder
+}
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+typedef struct {
+ void **result;
+ int max_depth;
+ int skip_count;
+ int count;
+} trace_arg_t;
+
+
+// Workaround for the malloc() in _Unwind_Backtrace() issue.
+static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) {
+ return _URC_NO_REASON;
+}
+
+
+// This code is not considered ready to run until
+// static initializers run so that we are guaranteed
+// that any malloc-related initialization is done.
+static bool ready_to_run = false;
+class StackTraceInit {
+ public:
+ StackTraceInit() {
+ // Extra call to force initialization
+ _Unwind_Backtrace(nop_backtrace, NULL);
+ ready_to_run = true;
+ }
+};
+
+static StackTraceInit module_initializer; // Force initialization
+
+static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
+ trace_arg_t *targ = (trace_arg_t *) opq;
+
+ if (targ->skip_count > 0) {
+ targ->skip_count--;
+ } else {
+ targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);
+ }
+
+ if (targ->count == targ->max_depth)
+ return _URC_END_OF_STACK;
+
+ return _URC_NO_REASON;
+}
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+ if (!ready_to_run)
+ return 0;
+
+ trace_arg_t targ;
+
+ skip_count += 1; // Do not include the "GetStackTrace" frame
+
+ targ.result = result;
+ targ.max_depth = max_depth;
+ targ.skip_count = skip_count;
+ targ.count = 0;
+
+ _Unwind_Backtrace(GetOneFrame, &targ);
+
+ return targ.count;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/symbolize.cc b/extern/libmv/third_party/glog/src/symbolize.cc
new file mode 100644
index 00000000000..3465de6c6fe
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/symbolize.cc
@@ -0,0 +1,681 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+// Stack-footprint reduction work done by Raksit Ashok
+//
+// Implementation note:
+//
+// We don't use heaps but only use stacks. We want to reduce the
+// stack consumption so that the symbolizer can run on small stacks.
+//
+// Here are some numbers collected with GCC 4.1.0 on x86:
+// - sizeof(Elf32_Sym) = 16
+// - sizeof(Elf32_Shdr) = 40
+// - sizeof(Elf64_Sym) = 24
+// - sizeof(Elf64_Shdr) = 64
+//
+// This implementation is intended to be async-signal-safe but uses
+// some functions which are not guaranteed to be so, such as memchr()
+// and memmove(). We assume they are async-signal-safe.
+//
+
+#include "utilities.h"
+
+#if defined(HAVE_SYMBOLIZE)
+
+#include <limits>
+
+#include "symbolize.h"
+#include "demangle.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// We don't use assert() since it's not guaranteed to be
+// async-signal-safe. Instead we define a minimal assertion
+// macro. So far, we don't need pretty printing for __FILE__, etc.
+
+// A wrapper for abort() to make it callable in ? :.
+static int AssertFail() {
+ abort();
+ return 0; // Should not reach.
+}
+
+#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
+
+static SymbolizeCallback g_symbolize_callback = NULL;
+void InstallSymbolizeCallback(SymbolizeCallback callback) {
+ g_symbolize_callback = callback;
+}
+
+// This function wraps the Demangle function to provide an interface
+// where the input symbol is demangled in-place.
+// To keep stack consumption low, we would like this function to not
+// get inlined.
+static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) {
+ char demangled[256]; // Big enough for sane demangled symbols.
+ if (Demangle(out, demangled, sizeof(demangled))) {
+ // Demangling succeeded. Copy to out if the space allows.
+ int len = strlen(demangled);
+ if (len + 1 <= out_size) { // +1 for '\0'.
+ SAFE_ASSERT(len < sizeof(demangled));
+ memmove(out, demangled, len + 1);
+ }
+ }
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#if defined(__ELF__)
+
+#include <dlfcn.h>
+#include <elf.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <link.h> // For ElfW() macro.
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "symbolize.h"
+#include "config.h"
+#include "glog/raw_logging.h"
+
+// Re-runs fn until it doesn't cause EINTR.
+#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
+
+_START_GOOGLE_NAMESPACE_
+
+// Read up to "count" bytes from file descriptor "fd" into the buffer
+// starting at "buf" while handling short reads and EINTR. On
+// success, return the number of bytes read. Otherwise, return -1.
+static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {
+ SAFE_ASSERT(fd >= 0);
+ SAFE_ASSERT(count >= 0 && count <= std::numeric_limits<ssize_t>::max());
+ char *buf0 = reinterpret_cast<char *>(buf);
+ ssize_t num_bytes = 0;
+ while (num_bytes < count) {
+ ssize_t len;
+ NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes));
+ if (len < 0) { // There was an error other than EINTR.
+ return -1;
+ }
+ if (len == 0) { // Reached EOF.
+ break;
+ }
+ num_bytes += len;
+ }
+ SAFE_ASSERT(num_bytes <= count);
+ return num_bytes;
+}
+
+// Read up to "count" bytes from "offset" in the file pointed by file
+// descriptor "fd" into the buffer starting at "buf". On success,
+// return the number of bytes read. Otherwise, return -1.
+static ssize_t ReadFromOffset(const int fd, void *buf,
+ const size_t count, const off_t offset) {
+ off_t off = lseek(fd, offset, SEEK_SET);
+ if (off == (off_t)-1) {
+ return -1;
+ }
+ return ReadPersistent(fd, buf, count);
+}
+
+// Try reading exactly "count" bytes from "offset" bytes in a file
+// pointed by "fd" into the buffer starting at "buf" while handling
+// short reads and EINTR. On success, return true. Otherwise, return
+// false.
+static bool ReadFromOffsetExact(const int fd, void *buf,
+ const size_t count, const off_t offset) {
+ ssize_t len = ReadFromOffset(fd, buf, count, offset);
+ return len == count;
+}
+
+// Returns elf_header.e_type if the file pointed by fd is an ELF binary.
+static int FileGetElfType(const int fd) {
+ ElfW(Ehdr) elf_header;
+ if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+ return -1;
+ }
+ if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) {
+ return -1;
+ }
+ return elf_header.e_type;
+}
+
+// Read the section headers in the given ELF binary, and if a section
+// of the specified type is found, set the output to this section header
+// and return true. Otherwise, return false.
+// To keep stack consumption low, we would like this function to not get
+// inlined.
+static ATTRIBUTE_NOINLINE bool
+GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const off_t sh_offset,
+ ElfW(Word) type, ElfW(Shdr) *out) {
+ // Read at most 16 section headers at a time to save read calls.
+ ElfW(Shdr) buf[16];
+ for (int i = 0; i < sh_num;) {
+ const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]);
+ const ssize_t num_bytes_to_read =
+ (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf);
+ const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read,
+ sh_offset + i * sizeof(buf[0]));
+ SAFE_ASSERT(len % sizeof(buf[0]) == 0);
+ const ssize_t num_headers_in_buf = len / sizeof(buf[0]);
+ SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0]));
+ for (int j = 0; j < num_headers_in_buf; ++j) {
+ if (buf[j].sh_type == type) {
+ *out = buf[j];
+ return true;
+ }
+ }
+ i += num_headers_in_buf;
+ }
+ return false;
+}
+
+// There is no particular reason to limit section name to 63 characters,
+// but there has (as yet) been no need for anything longer either.
+const int kMaxSectionNameLen = 64;
+
+// name_len should include terminating '\0'.
+bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
+ ElfW(Shdr) *out) {
+ ElfW(Ehdr) elf_header;
+ if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+ return false;
+ }
+
+ ElfW(Shdr) shstrtab;
+ off_t shstrtab_offset = (elf_header.e_shoff +
+ elf_header.e_shentsize * elf_header.e_shstrndx);
+ if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
+ return false;
+ }
+
+ for (int i = 0; i < elf_header.e_shnum; ++i) {
+ off_t section_header_offset = (elf_header.e_shoff +
+ elf_header.e_shentsize * i);
+ if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) {
+ return false;
+ }
+ char header_name[kMaxSectionNameLen];
+ if (sizeof(header_name) < name_len) {
+ RAW_LOG(WARNING, "Section name '%s' is too long (%"PRIuS"); "
+ "section will not be found (even if present).", name, name_len);
+ // No point in even trying.
+ return false;
+ }
+ off_t name_offset = shstrtab.sh_offset + out->sh_name;
+ ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset);
+ if (n_read == -1) {
+ return false;
+ } else if (n_read != name_len) {
+ // Short read -- name could be at end of file.
+ continue;
+ }
+ if (memcmp(header_name, name, name_len) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Read a symbol table and look for the symbol containing the
+// pc. Iterate over symbols in a symbol table and look for the symbol
+// containing "pc". On success, return true and write the symbol name
+// to out. Otherwise, return false.
+// To keep stack consumption low, we would like this function to not get
+// inlined.
+static ATTRIBUTE_NOINLINE bool
+FindSymbol(uint64_t pc, const int fd, char *out, int out_size,
+ uint64_t symbol_offset, const ElfW(Shdr) *strtab,
+ const ElfW(Shdr) *symtab) {
+ if (symtab == NULL) {
+ return false;
+ }
+ const int num_symbols = symtab->sh_size / symtab->sh_entsize;
+ for (int i = 0; i < num_symbols;) {
+ off_t offset = symtab->sh_offset + i * symtab->sh_entsize;
+
+ // If we are reading Elf64_Sym's, we want to limit this array to
+ // 32 elements (to keep stack consumption low), otherwise we can
+ // have a 64 element Elf32_Sym array.
+#if __WORDSIZE == 64
+#define NUM_SYMBOLS 32
+#else
+#define NUM_SYMBOLS 64
+#endif
+
+ // Read at most NUM_SYMBOLS symbols at once to save read() calls.
+ ElfW(Sym) buf[NUM_SYMBOLS];
+ const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf), offset);
+ SAFE_ASSERT(len % sizeof(buf[0]) == 0);
+ const ssize_t num_symbols_in_buf = len / sizeof(buf[0]);
+ SAFE_ASSERT(num_symbols_in_buf <= sizeof(buf)/sizeof(buf[0]));
+ for (int j = 0; j < num_symbols_in_buf; ++j) {
+ const ElfW(Sym)& symbol = buf[j];
+ uint64_t start_address = symbol.st_value;
+ start_address += symbol_offset;
+ uint64_t end_address = start_address + symbol.st_size;
+ if (symbol.st_value != 0 && // Skip null value symbols.
+ symbol.st_shndx != 0 && // Skip undefined symbols.
+ start_address <= pc && pc < end_address) {
+ ssize_t len1 = ReadFromOffset(fd, out, out_size,
+ strtab->sh_offset + symbol.st_name);
+ if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) {
+ return false;
+ }
+ return true; // Obtained the symbol name.
+ }
+ }
+ i += num_symbols_in_buf;
+ }
+ return false;
+}
+
+// Get the symbol name of "pc" from the file pointed by "fd". Process
+// both regular and dynamic symbol tables if necessary. On success,
+// write the symbol name to "out" and return true. Otherwise, return
+// false.
+static bool GetSymbolFromObjectFile(const int fd, uint64_t pc,
+ char *out, int out_size,
+ uint64_t map_start_address) {
+ // Read the ELF header.
+ ElfW(Ehdr) elf_header;
+ if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+ return false;
+ }
+
+ uint64_t symbol_offset = 0;
+ if (elf_header.e_type == ET_DYN) { // DSO needs offset adjustment.
+ symbol_offset = map_start_address;
+ }
+
+ ElfW(Shdr) symtab, strtab;
+
+ // Consult a regular symbol table first.
+ if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+ SHT_SYMTAB, &symtab)) {
+ return false;
+ }
+ if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+ symtab.sh_link * sizeof(symtab))) {
+ return false;
+ }
+ if (FindSymbol(pc, fd, out, out_size, symbol_offset,
+ &strtab, &symtab)) {
+ return true; // Found the symbol in a regular symbol table.
+ }
+
+ // If the symbol is not found, then consult a dynamic symbol table.
+ if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+ SHT_DYNSYM, &symtab)) {
+ return false;
+ }
+ if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+ symtab.sh_link * sizeof(symtab))) {
+ return false;
+ }
+ if (FindSymbol(pc, fd, out, out_size, symbol_offset,
+ &strtab, &symtab)) {
+ return true; // Found the symbol in a dynamic symbol table.
+ }
+
+ return false;
+}
+
+namespace {
+// Thin wrapper around a file descriptor so that the file descriptor
+// gets closed for sure.
+struct FileDescriptor {
+ const int fd_;
+ explicit FileDescriptor(int fd) : fd_(fd) {}
+ ~FileDescriptor() {
+ if (fd_ >= 0) {
+ NO_INTR(close(fd_));
+ }
+ }
+ int get() { return fd_; }
+
+ private:
+ explicit FileDescriptor(const FileDescriptor&);
+ void operator=(const FileDescriptor&);
+};
+
+// Helper class for reading lines from file.
+//
+// Note: we don't use ProcMapsIterator since the object is big (it has
+// a 5k array member) and uses async-unsafe functions such as sscanf()
+// and snprintf().
+class LineReader {
+ public:
+ explicit LineReader(int fd, char *buf, int buf_len) : fd_(fd),
+ buf_(buf), buf_len_(buf_len), bol_(buf), eol_(buf), eod_(buf) {
+ }
+
+ // Read '\n'-terminated line from file. On success, modify "bol"
+ // and "eol", then return true. Otherwise, return false.
+ //
+ // Note: if the last line doesn't end with '\n', the line will be
+ // dropped. It's an intentional behavior to make the code simple.
+ bool ReadLine(const char **bol, const char **eol) {
+ if (BufferIsEmpty()) { // First time.
+ const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_);
+ if (num_bytes <= 0) { // EOF or error.
+ return false;
+ }
+ eod_ = buf_ + num_bytes;
+ bol_ = buf_;
+ } else {
+ bol_ = eol_ + 1; // Advance to the next line in the buffer.
+ SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_".
+ if (!HasCompleteLine()) {
+ const int incomplete_line_length = eod_ - bol_;
+ // Move the trailing incomplete line to the beginning.
+ memmove(buf_, bol_, incomplete_line_length);
+ // Read text from file and append it.
+ char * const append_pos = buf_ + incomplete_line_length;
+ const int capacity_left = buf_len_ - incomplete_line_length;
+ const ssize_t num_bytes = ReadPersistent(fd_, append_pos,
+ capacity_left);
+ if (num_bytes <= 0) { // EOF or error.
+ return false;
+ }
+ eod_ = append_pos + num_bytes;
+ bol_ = buf_;
+ }
+ }
+ eol_ = FindLineFeed();
+ if (eol_ == NULL) { // '\n' not found. Malformed line.
+ return false;
+ }
+ *eol_ = '\0'; // Replace '\n' with '\0'.
+
+ *bol = bol_;
+ *eol = eol_;
+ return true;
+ }
+
+ // Beginning of line.
+ const char *bol() {
+ return bol_;
+ }
+
+ // End of line.
+ const char *eol() {
+ return eol_;
+ }
+
+ private:
+ explicit LineReader(const LineReader&);
+ void operator=(const LineReader&);
+
+ char *FindLineFeed() {
+ return reinterpret_cast<char *>(memchr(bol_, '\n', eod_ - bol_));
+ }
+
+ bool BufferIsEmpty() {
+ return buf_ == eod_;
+ }
+
+ bool HasCompleteLine() {
+ return !BufferIsEmpty() && FindLineFeed() != NULL;
+ }
+
+ const int fd_;
+ char * const buf_;
+ const int buf_len_;
+ char *bol_;
+ char *eol_;
+ const char *eod_; // End of data in "buf_".
+};
+} // namespace
+
+// Place the hex number read from "start" into "*hex". The pointer to
+// the first non-hex character or "end" is returned.
+static char *GetHex(const char *start, const char *end, uint64_t *hex) {
+ *hex = 0;
+ const char *p;
+ for (p = start; p < end; ++p) {
+ int ch = *p;
+ if ((ch >= '0' && ch <= '9') ||
+ (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
+ *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9);
+ } else { // Encountered the first non-hex character.
+ break;
+ }
+ }
+ SAFE_ASSERT(p <= end);
+ return const_cast<char *>(p);
+}
+
+// Search for the object file (from /proc/self/maps) that contains
+// the specified pc. If found, open this file and return the file handle,
+// and also set start_address to the start address of where this object
+// file is mapped to in memory. Otherwise, return -1.
+static ATTRIBUTE_NOINLINE int
+OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
+ uint64_t &start_address) {
+ int object_fd;
+
+ // Open /proc/self/maps.
+ int maps_fd;
+ NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY));
+ FileDescriptor wrapped_maps_fd(maps_fd);
+ if (wrapped_maps_fd.get() < 0) {
+ return -1;
+ }
+
+ // Iterate over maps and look for the map containing the pc. Then
+ // look into the symbol tables inside.
+ char buf[1024]; // Big enough for line of sane /proc/self/maps
+ LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf));
+ while (true) {
+ const char *cursor;
+ const char *eol;
+ if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line.
+ return -1;
+ }
+
+ // Start parsing line in /proc/self/maps. Here is an example:
+ //
+ // 08048000-0804c000 r-xp 00000000 08:01 2142121 /bin/cat
+ //
+ // We want start address (08048000), end address (0804c000), flags
+ // (r-xp) and file name (/bin/cat).
+
+ // Read start address.
+ cursor = GetHex(cursor, eol, &start_address);
+ if (cursor == eol || *cursor != '-') {
+ return -1; // Malformed line.
+ }
+ ++cursor; // Skip '-'.
+
+ // Read end address.
+ uint64_t end_address;
+ cursor = GetHex(cursor, eol, &end_address);
+ if (cursor == eol || *cursor != ' ') {
+ return -1; // Malformed line.
+ }
+ ++cursor; // Skip ' '.
+
+ // Check start and end addresses.
+ if (!(start_address <= pc && pc < end_address)) {
+ continue; // We skip this map. PC isn't in this map.
+ }
+
+ // Read flags. Skip flags until we encounter a space or eol.
+ const char * const flags_start = cursor;
+ while (cursor < eol && *cursor != ' ') {
+ ++cursor;
+ }
+ // We expect at least four letters for flags (ex. "r-xp").
+ if (cursor == eol || cursor < flags_start + 4) {
+ return -1; // Malformed line.
+ }
+
+ // Check flags. We are only interested in "r-x" maps.
+ if (memcmp(flags_start, "r-x", 3) != 0) { // Not a "r-x" map.
+ continue; // We skip this map.
+ }
+ ++cursor; // Skip ' '.
+
+ // Skip to file name. "cursor" now points to file offset. We need to
+ // skip at least three spaces for file offset, dev, and inode.
+ int num_spaces = 0;
+ while (cursor < eol) {
+ if (*cursor == ' ') {
+ ++num_spaces;
+ } else if (num_spaces >= 3) {
+ // The first non-space character after skipping three spaces
+ // is the beginning of the file name.
+ break;
+ }
+ ++cursor;
+ }
+ if (cursor == eol) {
+ return -1; // Malformed line.
+ }
+
+ // Finally, "cursor" now points to file name of our interest.
+ NO_INTR(object_fd = open(cursor, O_RDONLY));
+ if (object_fd < 0) {
+ return -1;
+ }
+ return object_fd;
+ }
+}
+
+// The implementation of our symbolization routine. If it
+// successfully finds the symbol containing "pc" and obtains the
+// symbol name, returns true and write the symbol name to "out".
+// Otherwise, returns false. If Callback function is installed via
+// InstallSymbolizeCallback(), the function is also called in this function,
+// and "out" is used as its output.
+// To keep stack consumption low, we would like this function to not
+// get inlined.
+static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
+ int out_size) {
+ uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
+ uint64_t start_address = 0;
+
+ int object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0,
+ start_address);
+ if (object_fd == -1) {
+ return false;
+ }
+ FileDescriptor wrapped_object_fd(object_fd);
+ int elf_type = FileGetElfType(wrapped_object_fd.get());
+ if (elf_type == -1) {
+ return false;
+ }
+ if (g_symbolize_callback) {
+ // Run the call back if it's installed.
+ // Note: relocation (and much of the rest of this code) will be
+ // wrong for prelinked shared libraries and PIE executables.
+ uint64 relocation = (elf_type == ET_DYN) ? start_address : 0;
+ int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
+ pc, out, out_size,
+ relocation);
+ if (num_bytes_written > 0) {
+ out += num_bytes_written;
+ out_size -= num_bytes_written;
+ }
+ }
+ if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0,
+ out, out_size, start_address)) {
+ return false;
+ }
+
+ // Symbolization succeeded. Now we try to demangle the symbol.
+ DemangleInplace(out, out_size);
+ return true;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#elif defined(OS_MACOSX) && defined(HAVE_DLADDR)
+
+#include <dlfcn.h>
+#include <string.h>
+
+_START_GOOGLE_NAMESPACE_
+
+static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
+ int out_size) {
+ Dl_info info;
+ if (dladdr(pc, &info)) {
+ if (strlen(info.dli_sname) < out_size) {
+ strcpy(out, info.dli_sname);
+ // Symbolization succeeded. Now we try to demangle the symbol.
+ DemangleInplace(out, out_size);
+ return true;
+ }
+ }
+ return false;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#else
+# error BUG: HAVE_SYMBOLIZE was wrongly set
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+bool Symbolize(void *pc, char *out, int out_size) {
+ SAFE_ASSERT(out_size >= 0);
+ return SymbolizeAndDemangle(pc, out, out_size);
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#else /* HAVE_SYMBOLIZE */
+
+#include <assert.h>
+
+#include "config.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// TODO: Support other environments.
+bool Symbolize(void *pc, char *out, int out_size) {
+ assert(0);
+ return false;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#endif
diff --git a/extern/libmv/third_party/glog/src/symbolize.h b/extern/libmv/third_party/glog/src/symbolize.h
new file mode 100644
index 00000000000..1ebe4dd94a2
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/symbolize.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// This library provides Symbolize() function that symbolizes program
+// counters to their corresponding symbol names on linux platforms.
+// This library has a minimal implementation of an ELF symbol table
+// reader (i.e. it doesn't depend on libelf, etc.).
+//
+// The algorithm used in Symbolize() is as follows.
+//
+// 1. Go through a list of maps in /proc/self/maps and find the map
+// containing the program counter.
+//
+// 2. Open the mapped file and find a regular symbol table inside.
+// Iterate over symbols in the symbol table and look for the symbol
+// containing the program counter. If such a symbol is found,
+// obtain the symbol name, and demangle the symbol if possible.
+// If the symbol isn't found in the regular symbol table (binary is
+// stripped), try the same thing with a dynamic symbol table.
+//
+// Note that Symbolize() is originally implemented to be used in
+// FailureSignalHandler() in base/google.cc. Hence it doesn't use
+// malloc() and other unsafe operations. It should be both
+// thread-safe and async-signal-safe.
+
+#ifndef BASE_SYMBOLIZE_H_
+#define BASE_SYMBOLIZE_H_
+
+#include "utilities.h"
+#include "config.h"
+#include "glog/logging.h"
+
+#ifdef HAVE_SYMBOLIZE
+
+#if defined(__ELF__) // defined by gcc on Linux
+#include <elf.h>
+#include <link.h> // For ElfW() macro.
+
+// If there is no ElfW macro, let's define it by ourself.
+#ifndef ElfW
+# if SIZEOF_VOID_P == 4
+# define ElfW(type) Elf32_##type
+# elif SIZEOF_VOID_P == 8
+# define ElfW(type) Elf64_##type
+# else
+# error "Unknown sizeof(void *)"
+# endif
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Gets the section header for the given name, if it exists. Returns true on
+// success. Otherwise, returns false.
+bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
+ ElfW(Shdr) *out);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif /* __ELF__ */
+
+_START_GOOGLE_NAMESPACE_
+
+// Installs a callback function, which will be called right before a symbol name
+// is printed. The callback is intended to be used for showing a file name and a
+// line number preceding a symbol name.
+// "fd" is a file descriptor of the object file containing the program
+// counter "pc". The callback function should write output to "out"
+// and return the size of the output written. On error, the callback
+// function should return -1.
+typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size,
+ uint64 relocation);
+void InstallSymbolizeCallback(SymbolizeCallback callback);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Symbolizes a program counter. On success, returns true and write the
+// symbol name to "out". The symbol name is demangled if possible
+// (supports symbols generated by GCC 3.x or newer). Otherwise,
+// returns false.
+bool Symbolize(void *pc, char *out, int out_size);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif // BASE_SYMBOLIZE_H_
diff --git a/extern/libmv/third_party/glog/src/utilities.cc b/extern/libmv/third_party/glog/src/utilities.cc
new file mode 100644
index 00000000000..e97d4f237ec
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/utilities.cc
@@ -0,0 +1,335 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+
+#include "utilities.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <signal.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h> // for syscall()
+#elif defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h> // for syscall()
+#endif
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#endif
+
+#include "base/googleinit.h"
+
+using std::string;
+
+_START_GOOGLE_NAMESPACE_
+
+static const char* g_program_invocation_short_name = NULL;
+static pthread_t g_main_thread_id;
+
+_END_GOOGLE_NAMESPACE_
+
+// The following APIs are all internal.
+#ifdef HAVE_STACKTRACE
+
+#include "stacktrace.h"
+#include "symbolize.h"
+#include "base/commandlineflags.h"
+
+GLOG_DEFINE_bool(symbolize_stacktrace, true,
+ "Symbolize the stack trace in the tombstone");
+
+_START_GOOGLE_NAMESPACE_
+
+typedef void DebugWriter(const char*, void*);
+
+// The %p field width for printf() functions is two characters per byte.
+// For some environments, add two extra bytes for the leading "0x".
+static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);
+
+static void DebugWriteToStderr(const char* data, void *unused) {
+ // This one is signal-safe.
+ write(STDERR_FILENO, data, strlen(data));
+}
+
+void DebugWriteToString(const char* data, void *arg) {
+ reinterpret_cast<string*>(arg)->append(data);
+}
+
+#ifdef HAVE_SYMBOLIZE
+// Print a program counter and its symbol name.
+static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc,
+ const char * const prefix) {
+ char tmp[1024];
+ const char *symbol = "(unknown)";
+ // Symbolizes the previous address of pc because pc may be in the
+ // next function. The overrun happens when the function ends with
+ // a call to a function annotated noreturn (e.g. CHECK).
+ if (Symbolize(reinterpret_cast<char *>(pc) - 1, tmp, sizeof(tmp))) {
+ symbol = tmp;
+ }
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%s@ %*p %s\n",
+ prefix, kPrintfPointerFieldWidth, pc, symbol);
+ writerfn(buf, arg);
+}
+#endif
+
+static void DumpPC(DebugWriter *writerfn, void *arg, void *pc,
+ const char * const prefix) {
+ char buf[100];
+ snprintf(buf, sizeof(buf), "%s@ %*p\n",
+ prefix, kPrintfPointerFieldWidth, pc);
+ writerfn(buf, arg);
+}
+
+// Dump current stack trace as directed by writerfn
+static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
+ // Print stack trace
+ void* stack[32];
+ int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1);
+ for (int i = 0; i < depth; i++) {
+#if defined(HAVE_SYMBOLIZE)
+ if (FLAGS_symbolize_stacktrace) {
+ DumpPCAndSymbol(writerfn, arg, stack[i], " ");
+ } else {
+ DumpPC(writerfn, arg, stack[i], " ");
+ }
+#else
+ DumpPC(writerfn, arg, stack[i], " ");
+#endif
+ }
+}
+
+static void DumpStackTraceAndExit() {
+ DumpStackTrace(1, DebugWriteToStderr, NULL);
+
+ // Set the default signal handler for SIGABRT, to avoid invoking our
+ // own signal handler installed by InstallFailedSignalHandler().
+ struct sigaction sig_action;
+ memset(&sig_action, 0, sizeof(sig_action));
+ sigemptyset(&sig_action.sa_mask);
+ sig_action.sa_handler = SIG_DFL;
+ sigaction(SIGABRT, &sig_action, NULL);
+
+ abort();
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#endif // HAVE_STACKTRACE
+
+_START_GOOGLE_NAMESPACE_
+
+namespace glog_internal_namespace_ {
+
+const char* ProgramInvocationShortName() {
+ if (g_program_invocation_short_name != NULL) {
+ return g_program_invocation_short_name;
+ } else {
+ // TODO(hamaji): Use /proc/self/cmdline and so?
+ return "UNKNOWN";
+ }
+}
+
+bool IsGoogleLoggingInitialized() {
+ return g_program_invocation_short_name != NULL;
+}
+
+bool is_default_thread() {
+ if (g_program_invocation_short_name == NULL) {
+ // InitGoogleLogging() not yet called, so unlikely to be in a different
+ // thread
+ return true;
+ } else {
+ return pthread_equal(pthread_self(), g_main_thread_id);
+ }
+}
+
+#ifdef OS_WINDOWS
+struct timeval {
+ long tv_sec, tv_usec;
+};
+
+// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd
+// See COPYING for copyright information.
+static int gettimeofday(struct timeval *tv, void* tz) {
+#define EPOCHFILETIME (116444736000000000ULL)
+ FILETIME ft;
+ LARGE_INTEGER li;
+ uint64 tt;
+
+ GetSystemTimeAsFileTime(&ft);
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ tt = (li.QuadPart - EPOCHFILETIME) / 10;
+ tv->tv_sec = tt / 1000000;
+ tv->tv_usec = tt % 1000000;
+
+ return 0;
+}
+#endif
+
+int64 CycleClock_Now() {
+ // TODO(hamaji): temporary impementation - it might be too slow.
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
+}
+
+int64 UsecToCycles(int64 usec) {
+ return usec;
+}
+
+WallTime WallTime_Now() {
+ // Now, cycle clock is retuning microseconds since the epoch.
+ return CycleClock_Now() * 0.000001;
+}
+
+static int32 g_main_thread_pid = getpid();
+int32 GetMainThreadPid() {
+ return g_main_thread_pid;
+}
+
+pid_t GetTID() {
+ // On Linux and FreeBSD, we try to use gettid().
+#if defined OS_LINUX || defined OS_FREEBSD || defined OS_MACOSX
+#ifndef __NR_gettid
+#ifdef OS_MACOSX
+#define __NR_gettid SYS_gettid
+#elif ! defined __i386__
+#error "Must define __NR_gettid for non-x86 platforms"
+#else
+#define __NR_gettid 224
+#endif
+#endif
+ static bool lacks_gettid = false;
+ if (!lacks_gettid) {
+ pid_t tid = syscall(__NR_gettid);
+ if (tid != -1) {
+ return tid;
+ }
+ // Technically, this variable has to be volatile, but there is a small
+ // performance penalty in accessing volatile variables and there should
+ // not be any serious adverse effect if a thread does not immediately see
+ // the value change to "true".
+ lacks_gettid = true;
+ }
+#endif // OS_LINUX || OS_FREEBSD
+
+ // If gettid() could not be used, we use one of the following.
+#if defined OS_LINUX
+ return getpid(); // Linux: getpid returns thread ID when gettid is absent
+#elif defined OS_WINDOWS || defined OS_CYGWIN
+ return GetCurrentThreadId();
+#else
+ // If none of the techniques above worked, we use pthread_self().
+ return (pid_t)(uintptr_t)pthread_self();
+#endif
+}
+
+const char* const_basename(const char* filepath) {
+ const char* base = strrchr(filepath, '/');
+#ifdef OS_WINDOWS // Look for either path separator in Windows
+ if (!base)
+ base = strrchr(filepath, '\\');
+#endif
+ return base ? (base+1) : filepath;
+}
+
+static string g_my_user_name;
+const string& MyUserName() {
+ return g_my_user_name;
+}
+static void MyUserNameInitializer() {
+ // TODO(hamaji): Probably this is not portable.
+#if defined(OS_WINDOWS)
+ const char* user = getenv("USERNAME");
+#else
+ const char* user = getenv("USER");
+#endif
+ if (user != NULL) {
+ g_my_user_name = user;
+ } else {
+ g_my_user_name = "invalid-user";
+ }
+}
+REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer());
+
+#ifdef HAVE_STACKTRACE
+void DumpStackTraceToString(string* stacktrace) {
+ DumpStackTrace(1, DebugWriteToString, stacktrace);
+}
+#endif
+
+// We use an atomic operation to prevent problems with calling CrashReason
+// from inside the Mutex implementation (potentially through RAW_CHECK).
+static const CrashReason* g_reason = 0;
+
+void SetCrashReason(const CrashReason* r) {
+ sync_val_compare_and_swap(&g_reason,
+ reinterpret_cast<const CrashReason*>(0),
+ r);
+}
+
+} // namespace glog_internal_namespace_
+
+void InitGoogleLogging(const char* argv0) {
+ CHECK(!IsGoogleLoggingInitialized())
+ << "You called InitGoogleLogging() twice!";
+ const char* slash = strrchr(argv0, '/');
+#ifdef OS_WINDOWS
+ if (!slash) slash = strrchr(argv0, '\\');
+#endif
+ g_program_invocation_short_name = slash ? slash + 1 : argv0;
+ g_main_thread_id = pthread_self();
+
+#ifdef HAVE_STACKTRACE
+ InstallFailureFunction(&DumpStackTraceAndExit);
+#endif
+}
+
+void ShutdownGoogleLogging() {
+ CHECK(IsGoogleLoggingInitialized())
+ << "You called ShutdownGoogleLogging() without InitGoogleLogging() first!";
+#ifdef HAVE_SYSLOG_H
+ closelog();
+#endif
+}
+
+_END_GOOGLE_NAMESPACE_
+
+// Make an implementation of stacktrace compiled.
+#ifdef STACKTRACE_H
+# include STACKTRACE_H
+#endif
diff --git a/extern/libmv/third_party/glog/src/utilities.h b/extern/libmv/third_party/glog/src/utilities.h
new file mode 100644
index 00000000000..5c841a0b90b
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/utilities.h
@@ -0,0 +1,224 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+//
+// Define utilties for glog internal usage.
+
+#ifndef UTILITIES_H__
+#define UTILITIES_H__
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+# define OS_WINDOWS
+#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
+# define OS_CYGWIN
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+# define OS_LINUX
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define OS_MACOSX
+#elif defined(__FreeBSD__)
+# define OS_FREEBSD
+#elif defined(__NetBSD__)
+# define OS_NETBSD
+#elif defined(__OpenBSD__)
+# define OS_OPENBSD
+#else
+// TODO(hamaji): Add other platforms.
+#endif
+
+// printf macros for size_t, in the style of inttypes.h
+#ifdef _LP64
+#define __PRIS_PREFIX "z"
+#else
+#define __PRIS_PREFIX
+#endif
+
+// Use these macros after a % in a printf format string
+// to get correct 32/64 bit behavior, like this:
+// size_t size = records.size();
+// printf("%"PRIuS"\n", size);
+
+#define PRIdS __PRIS_PREFIX "d"
+#define PRIxS __PRIS_PREFIX "x"
+#define PRIuS __PRIS_PREFIX "u"
+#define PRIXS __PRIS_PREFIX "X"
+#define PRIoS __PRIS_PREFIX "o"
+
+#include "base/mutex.h" // This must go first so we get _XOPEN_SOURCE
+
+#include <string>
+
+#if defined(OS_WINDOWS)
+# include "port.h"
+#endif
+
+#include "config.h"
+#include <glog/logging.h>
+
+// There are three different ways we can try to get the stack trace:
+//
+// 1) The libunwind library. This is still in development, and as a
+// separate library adds a new dependency, but doesn't need a frame
+// pointer. It also doesn't call malloc.
+//
+// 2) Our hand-coded stack-unwinder. This depends on a certain stack
+// layout, which is used by gcc (and those systems using a
+// gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
+// It uses the frame pointer to do its work.
+//
+// 3) The gdb unwinder -- also the one used by the c++ exception code.
+// It's obviously well-tested, but has a fatal flaw: it can call
+// malloc() from the unwinder. This is a problem because we're
+// trying to use the unwinder to instrument malloc().
+//
+// Note: if you add a new implementation here, make sure it works
+// correctly when GetStackTrace() is called with max_depth == 0.
+// Some code may do that.
+
+#if __MINGW32__
+# undef STACKTRACE_H
+#elif defined(HAVE_LIB_UNWIND)
+# define STACKTRACE_H "stacktrace_libunwind-inl.h"
+#elif !defined(NO_FRAME_POINTER)
+# if defined(__i386__) && __GNUC__ >= 2
+# define STACKTRACE_H "stacktrace_x86-inl.h"
+# elif defined(__x86_64__) && __GNUC__ >= 2
+# define STACKTRACE_H "stacktrace_x86_64-inl.h"
+# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
+# define STACKTRACE_H "stacktrace_powerpc-inl.h"
+# endif
+#endif
+
+#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H)
+# define STACKTRACE_H "stacktrace_generic-inl.h"
+#endif
+
+#if defined(STACKTRACE_H)
+# define HAVE_STACKTRACE
+#endif
+
+// defined by gcc
+#if defined(__ELF__) && defined(OS_LINUX)
+# define HAVE_SYMBOLIZE
+#elif defined(OS_MACOSX) && defined(HAVE_DLADDR)
+// Use dladdr to symbolize.
+# define HAVE_SYMBOLIZE
+#endif
+
+#ifndef ARRAYSIZE
+// There is a better way, but this is good enough for our purpose.
+# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+namespace glog_internal_namespace_ {
+
+#ifdef HAVE___ATTRIBUTE__
+# define ATTRIBUTE_NOINLINE __attribute__ ((noinline))
+# define HAVE_ATTRIBUTE_NOINLINE
+#else
+# define ATTRIBUTE_NOINLINE
+#endif
+
+const char* ProgramInvocationShortName();
+
+bool IsGoogleLoggingInitialized();
+
+bool is_default_thread();
+
+int64 CycleClock_Now();
+
+int64 UsecToCycles(int64 usec);
+
+typedef double WallTime;
+WallTime WallTime_Now();
+
+int32 GetMainThreadPid();
+
+pid_t GetTID();
+
+const std::string& MyUserName();
+
+// Get the part of filepath after the last path separator.
+// (Doesn't modify filepath, contrary to basename() in libgen.h.)
+const char* const_basename(const char* filepath);
+
+// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
+// defined, we try the CPU specific logics (we only support x86 and
+// x86_64 for now) first, then use a naive implementation, which has a
+// race condition.
+template<typename T>
+inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
+#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
+ return __sync_val_compare_and_swap(ptr, oldval, newval);
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ T ret;
+ __asm__ __volatile__("lock; cmpxchg %1, (%2);"
+ :"=a"(ret)
+ // GCC may produces %sil or %dil for
+ // constraint "r", but some of apple's gas
+ // dosn't know the 8 bit registers.
+ // We use "q" to avoid these registers.
+ :"q"(newval), "q"(ptr), "a"(oldval)
+ :"memory", "cc");
+ return ret;
+#else
+ T ret = *ptr;
+ if (ret == oldval) {
+ *ptr = newval;
+ }
+ return ret;
+#endif
+}
+
+void DumpStackTraceToString(std::string* stacktrace);
+
+struct CrashReason {
+ CrashReason() : filename(0), line_number(0), message(0), depth(0) {}
+
+ const char* filename;
+ int line_number;
+ const char* message;
+
+ // We'll also store a bit of stack trace context at the time of crash as
+ // it may not be available later on.
+ void* stack[32];
+ int depth;
+};
+
+void SetCrashReason(const CrashReason* r);
+
+} // namespace glog_internal_namespace_
+
+_END_GOOGLE_NAMESPACE_
+
+using namespace GOOGLE_NAMESPACE::glog_internal_namespace_;
+
+#endif // UTILITIES_H__
diff --git a/extern/libmv/third_party/glog/src/vlog_is_on.cc b/extern/libmv/third_party/glog/src/vlog_is_on.cc
new file mode 100644
index 00000000000..ed88514dce5
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/vlog_is_on.cc
@@ -0,0 +1,249 @@
+// Copyright (c) 1999, 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney and many others
+//
+// Broken out from logging.cc by Soren Lassen
+// logging_unittest.cc covers the functionality herein
+
+#include "utilities.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cstdio>
+#include <string>
+#include "base/commandlineflags.h"
+#include <glog/logging.h>
+#include <glog/raw_logging.h>
+#include "base/googleinit.h"
+
+// glog doesn't have annotation
+#define ANNOTATE_BENIGN_RACE(address, description)
+
+using std::string;
+
+GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this."
+" Overridable by --vmodule.");
+
+GLOG_DEFINE_string(vmodule, "", "per-module verbose level."
+" Argument is a comma-separated list of <module name>=<log level>."
+" <module name> is a glob pattern, matched against the filename base"
+" (that is, name ignoring .cc/.h./-inl.h)."
+" <log level> overrides any value given by --v.");
+
+_START_GOOGLE_NAMESPACE_
+
+namespace glog_internal_namespace_ {
+
+// Implementation of fnmatch that does not need 0-termination
+// of arguments and does not allocate any memory,
+// but we only support "*" and "?" wildcards, not the "[...]" patterns.
+// It's not a static function for the unittest.
+GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern,
+ size_t patt_len,
+ const char* str,
+ size_t str_len) {
+ int p = 0;
+ int s = 0;
+ while (1) {
+ if (p == patt_len && s == str_len) return true;
+ if (p == patt_len) return false;
+ if (s == str_len) return p+1 == patt_len && pattern[p] == '*';
+ if (pattern[p] == str[s] || pattern[p] == '?') {
+ p += 1;
+ s += 1;
+ continue;
+ }
+ if (pattern[p] == '*') {
+ if (p+1 == patt_len) return true;
+ do {
+ if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) {
+ return true;
+ }
+ s += 1;
+ } while (s != str_len);
+ return false;
+ }
+ return false;
+ }
+}
+
+} // namespace glog_internal_namespace_
+
+using glog_internal_namespace_::SafeFNMatch_;
+
+int32 kLogSiteUninitialized = 1000;
+
+// List of per-module log levels from FLAGS_vmodule.
+// Once created each element is never deleted/modified
+// except for the vlog_level: other threads will read VModuleInfo blobs
+// w/o locks and we'll store pointers to vlog_level at VLOG locations
+// that will never go away.
+// We can't use an STL struct here as we wouldn't know
+// when it's safe to delete/update it: other threads need to use it w/o locks.
+struct VModuleInfo {
+ string module_pattern;
+ mutable int32 vlog_level; // Conceptually this is an AtomicWord, but it's
+ // too much work to use AtomicWord type here
+ // w/o much actual benefit.
+ const VModuleInfo* next;
+};
+
+// This protects the following global variables.
+static Mutex vmodule_lock;
+// Pointer to head of the VModuleInfo list.
+// It's a map from module pattern to logging level for those module(s).
+static VModuleInfo* vmodule_list = 0;
+// Boolean initialization flag.
+static bool inited_vmodule = false;
+
+// L >= vmodule_lock.
+static void VLOG2Initializer() {
+ vmodule_lock.AssertHeld();
+ // Can now parse --vmodule flag and initialize mapping of module-specific
+ // logging levels.
+ inited_vmodule = false;
+ const char* vmodule = FLAGS_vmodule.c_str();
+ const char* sep;
+ VModuleInfo* head = NULL;
+ VModuleInfo* tail = NULL;
+ while ((sep = strchr(vmodule, '=')) != NULL) {
+ string pattern(vmodule, sep - vmodule);
+ int module_level;
+ if (sscanf(sep, "=%d", &module_level) == 1) {
+ VModuleInfo* info = new VModuleInfo;
+ info->module_pattern = pattern;
+ info->vlog_level = module_level;
+ if (head) tail->next = info;
+ else head = info;
+ tail = info;
+ }
+ // Skip past this entry
+ vmodule = strchr(sep, ',');
+ if (vmodule == NULL) break;
+ vmodule++; // Skip past ","
+ }
+ if (head) { // Put them into the list at the head:
+ tail->next = vmodule_list;
+ vmodule_list = head;
+ }
+ inited_vmodule = true;
+}
+
+// This can be called very early, so we use SpinLock and RAW_VLOG here.
+int SetVLOGLevel(const char* module_pattern, int log_level) {
+ int result = FLAGS_v;
+ int const pattern_len = strlen(module_pattern);
+ bool found = false;
+ MutexLock l(&vmodule_lock); // protect whole read-modify-write
+ for (const VModuleInfo* info = vmodule_list;
+ info != NULL; info = info->next) {
+ if (info->module_pattern == module_pattern) {
+ if (!found) {
+ result = info->vlog_level;
+ found = true;
+ }
+ info->vlog_level = log_level;
+ } else if (!found &&
+ SafeFNMatch_(info->module_pattern.c_str(),
+ info->module_pattern.size(),
+ module_pattern, pattern_len)) {
+ result = info->vlog_level;
+ found = true;
+ }
+ }
+ if (!found) {
+ VModuleInfo* info = new VModuleInfo;
+ info->module_pattern = module_pattern;
+ info->vlog_level = log_level;
+ info->next = vmodule_list;
+ vmodule_list = info;
+ }
+ RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level);
+ return result;
+}
+
+// NOTE: Individual VLOG statements cache the integer log level pointers.
+// NOTE: This function must not allocate memory or require any locks.
+bool InitVLOG3__(int32** site_flag, int32* site_default,
+ const char* fname, int32 verbose_level) {
+ MutexLock l(&vmodule_lock);
+ bool read_vmodule_flag = inited_vmodule;
+ if (!read_vmodule_flag) {
+ VLOG2Initializer();
+ }
+
+ // protect the errno global in case someone writes:
+ // VLOG(..) << "The last error was " << strerror(errno)
+ int old_errno = errno;
+
+ // site_default normally points to FLAGS_v
+ int32* site_flag_value = site_default;
+
+ // Get basename for file
+ const char* base = strrchr(fname, '/');
+ base = base ? (base+1) : fname;
+ const char* base_end = strchr(base, '.');
+ size_t base_length = base_end ? (base_end - base) : strlen(base);
+
+ // Trim out trailing "-inl" if any
+ if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
+ base_length -= 4;
+ }
+
+ // TODO: Trim out _unittest suffix? Perhaps it is better to have
+ // the extra control and just leave it there.
+
+ // find target in vector of modules, replace site_flag_value with
+ // a module-specific verbose level, if any.
+ for (const VModuleInfo* info = vmodule_list;
+ info != NULL; info = info->next) {
+ if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
+ base, base_length)) {
+ site_flag_value = &info->vlog_level;
+ // value at info->vlog_level is now what controls
+ // the VLOG at the caller site forever
+ break;
+ }
+ }
+
+ // Cache the vlog value pointer if --vmodule flag has been parsed.
+ ANNOTATE_BENIGN_RACE(site_flag,
+ "*site_flag may be written by several threads,"
+ " but the value will be the same");
+ if (read_vmodule_flag) *site_flag = site_flag_value;
+
+ // restore the errno in case something recoverable went wrong during
+ // the initialization of the VLOG mechanism (see above note "protect the..")
+ errno = old_errno;
+ return *site_flag_value >= verbose_level;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/extern/libmv/third_party/glog/src/windows/config.h b/extern/libmv/third_party/glog/src/windows/config.h
new file mode 100644
index 00000000000..682a1b9309d
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/config.h
@@ -0,0 +1,136 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE google
+
+/* Define if you have the `dladdr' function */
+#undef HAVE_DLADDR
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <libunwind.h> header file. */
+#undef HAVE_LIBUNWIND_H
+
+/* define if you have google gflags library */
+#define HAVE_LIB_GFLAGS 1
+
+/* define if you have libunwind */
+#undef HAVE_LIB_UNWIND
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* define if the compiler implements pthread_rwlock_* */
+#undef HAVE_RWLOCK
+
+/* Define if you have the `sigaltstack' function */
+#undef HAVE_SIGALTSTACK
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <syscall.h> header file. */
+#undef HAVE_SYSCALL_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#undef HAVE_SYS_SYSCALL_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <ucontext.h> header file. */
+#undef HAVE_UCONTEXT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* define if the compiler supports using expression for operator */
+#undef HAVE_USING_OPERATOR
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* define if your compiler has __builtin_expect */
+#undef HAVE___BUILTIN_EXPECT
+
+/* define if your compiler has __sync_val_compare_and_swap */
+#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* How to access the PC from a struct ucontext */
+#undef PC_FROM_UCONTEXT
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* the namespace where STL code like vector<> is defined */
+#undef STL_NAMESPACE
+
+/* Version number of package */
+#undef VERSION
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
+
+/* Always the empty-string on non-windows systems. On windows, should be
+ "__declspec(dllexport)". This way, when we compile the dll, we export our
+ functions/classes. It's safe to define this here because config.h is only
+ used internally, to compile the DLL, and every DLL source file #includes
+ "config.h" before anything else. */
+#ifndef GOOGLE_GLOG_DLL_DECL
+# define GOOGLE_GLOG_IS_A_DLL 1 /* not set if you're statically linking */
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllexport)
+# define GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
+#endif
diff --git a/extern/libmv/third_party/glog/src/windows/glog/log_severity.h b/extern/libmv/third_party/glog/src/windows/glog/log_severity.h
new file mode 100644
index 00000000000..5e7d09effb2
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/glog/log_severity.h
@@ -0,0 +1,88 @@
+// This file is automatically generated from src/glog/log_severity.h
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef BASE_LOG_SEVERITY_H__
+#define BASE_LOG_SEVERITY_H__
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// Variables of type LogSeverity are widely taken to lie in the range
+// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if
+// you ever need to change their values or add a new severity.
+typedef int LogSeverity;
+
+const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4;
+
+// DFATAL is FATAL in debug mode, ERROR in normal mode
+#ifdef NDEBUG
+#define DFATAL_LEVEL ERROR
+#else
+#define DFATAL_LEVEL FATAL
+#endif
+
+extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES];
+
+// NDEBUG usage helpers related to (RAW_)DCHECK:
+//
+// DEBUG_MODE is for small !NDEBUG uses like
+// if (DEBUG_MODE) foo.CheckThatFoo();
+// instead of substantially more verbose
+// #ifndef NDEBUG
+// foo.CheckThatFoo();
+// #endif
+//
+// IF_DEBUG_MODE is for small !NDEBUG uses like
+// IF_DEBUG_MODE( string error; )
+// DCHECK(Foo(&error)) << error;
+// instead of substantially more verbose
+// #ifndef NDEBUG
+// string error;
+// DCHECK(Foo(&error)) << error;
+// #endif
+//
+#ifdef NDEBUG
+enum { DEBUG_MODE = 0 };
+#define IF_DEBUG_MODE(x)
+#else
+enum { DEBUG_MODE = 1 };
+#define IF_DEBUG_MODE(x) x
+#endif
+
+#endif // BASE_LOG_SEVERITY_H__
diff --git a/extern/libmv/third_party/glog/src/windows/glog/logging.h b/extern/libmv/third_party/glog/src/windows/glog/logging.h
new file mode 100644
index 00000000000..2f41681edbe
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/glog/logging.h
@@ -0,0 +1,1524 @@
+// This file is automatically generated from src/glog/logging.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney
+//
+// This file contains #include information about logging-related stuff.
+// Pretty much everybody needs to #include this file so that they can
+// log various happenings.
+//
+#ifndef _LOGGING_H_
+#define _LOGGING_H_
+
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <string>
+#if 0
+# include <unistd.h>
+#endif
+#ifdef __DEPRECATED
+// Make GCC quiet.
+# undef __DEPRECATED
+# include <strstream>
+# define __DEPRECATED
+#else
+# include <strstream>
+#endif
+#include <vector>
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// We care a lot about number of bits things take up. Unfortunately,
+// systems define their bit-specific ints in a lot of different ways.
+// We use our own way, and have a typedef to get there.
+// Note: these commands below may look like "#if 1" or "#if 0", but
+// that's because they were constructed that way at ./configure time.
+// Look at logging.h.in to see how they're calculated (based on your config).
+#if 0
+#include <stdint.h> // the normal place uint16_t is defined
+#endif
+#if 0
+#include <sys/types.h> // the normal place u_int16_t is defined
+#endif
+#if 0
+#include <inttypes.h> // a third place for uint16_t or u_int16_t
+#endif
+
+#if 1
+#include "third_party/gflags/gflags.h"
+#endif
+
+#ifdef __MINGW32__
+# include <stdlib.h>
+# include <unistd.h>
+# include <stdint.h> // the normal place uint16_t is defined
+# include <sys/types.h> // the normal place u_int16_t is defined
+# include <inttypes.h> // a third place for uint16_t or u_int16_t
+# define _exit(x) exit(x)
+#endif
+
+namespace google {
+
+#if 0 // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 0 // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif defined(_MSC_VER)
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#elif defined(__MINGW32__)
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+
+}
+
+// The global value of GOOGLE_STRIP_LOG. All the messages logged to
+// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed.
+// If it can be determined at compile time that the message will not be
+// printed, the statement will be compiled out.
+//
+// Example: to strip out all INFO and WARNING messages, use the value
+// of 2 below. To make an exception for WARNING messages from a single
+// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including
+// base/logging.h
+#ifndef GOOGLE_STRIP_LOG
+#define GOOGLE_STRIP_LOG 0
+#endif
+
+// GCC can be told that a certain branch is not likely to be taken (for
+// instance, a CHECK failure), and use that information in static analysis.
+// Giving it this information can help it optimize for the common case in
+// the absence of better information (ie. -fprofile-arcs).
+//
+#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
+#if 0
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
+#else
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
+#endif
+#endif
+
+// Make a bunch of macros for logging. The way to log things is to stream
+// things to LOG(<a particular severity level>). E.g.,
+//
+// LOG(INFO) << "Found " << num_cookies << " cookies";
+//
+// You can capture log messages in a string, rather than reporting them
+// immediately:
+//
+// vector<string> errors;
+// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num;
+//
+// This pushes back the new error onto 'errors'; if given a NULL pointer,
+// it reports the error via LOG(ERROR).
+//
+// You can also do conditional logging:
+//
+// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// You can also do occasional logging (log every n'th occurrence of an
+// event):
+//
+// LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";
+//
+// The above will cause log messages to be output on the 1st, 11th, 21st, ...
+// times it is executed. Note that the special COUNTER value is used to
+// identify which repetition is happening.
+//
+// You can also do occasional conditional logging (log every n'th
+// occurrence of an event, when condition is satisfied):
+//
+// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER
+// << "th big cookie";
+//
+// You can log messages the first N times your code executes a line. E.g.
+//
+// LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie";
+//
+// Outputs log messages for the first 20 times it is executed.
+//
+// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available.
+// These log to syslog as well as to the normal logs. If you use these at
+// all, you need to be aware that syslog can drastically reduce performance,
+// especially if it is configured for remote logging! Don't use these
+// unless you fully understand this and have a concrete need to use them.
+// Even then, try to minimize your use of them.
+//
+// There are also "debug mode" logging macros like the ones above:
+//
+// DLOG(INFO) << "Found cookies";
+//
+// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";
+//
+// All "debug mode" logging is compiled away to nothing for non-debug mode
+// compiles.
+//
+// We also have
+//
+// LOG_ASSERT(assertion);
+// DLOG_ASSERT(assertion);
+//
+// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
+//
+// There are "verbose level" logging macros. They look like
+//
+// VLOG(1) << "I'm printed when you run the program with --v=1 or more";
+// VLOG(2) << "I'm printed when you run the program with --v=2 or more";
+//
+// These always log at the INFO log level (when they log at all).
+// The verbose logging can also be turned on module-by-module. For instance,
+// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
+// will cause:
+// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc}
+// b. VLOG(1) and lower messages to be printed from file.{h,cc}
+// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs"
+// d. VLOG(0) and lower messages to be printed from elsewhere
+//
+// The wildcarding functionality shown by (c) supports both '*' (match
+// 0 or more characters) and '?' (match any single character) wildcards.
+//
+// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
+//
+// if (VLOG_IS_ON(2)) {
+// // do some logging preparation and logging
+// // that can't be accomplished with just VLOG(2) << ...;
+// }
+//
+// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level"
+// condition macros for sample cases, when some extra computation and
+// preparation for logs is not needed.
+// VLOG_IF(1, (size > 1024))
+// << "I'm printed when size is more than 1024 and when you run the "
+// "program with --v=1 or more";
+// VLOG_EVERY_N(1, 10)
+// << "I'm printed every 10th occurrence, and when you run the program "
+// "with --v=1 or more. Present occurence is " << COUNTER;
+// VLOG_IF_EVERY_N(1, (size > 1024), 10)
+// << "I'm printed on every 10th occurence of case when size is more "
+// " than 1024, when you run the program with --v=1 or more. ";
+// "Present occurence is " << COUNTER;
+//
+// The supported severity levels for macros that allow you to specify one
+// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
+// Note that messages of a given severity are logged not only in the
+// logfile for that severity, but also in all logfiles of lower severity.
+// E.g., a message of severity FATAL will be logged to the logfiles of
+// severity FATAL, ERROR, WARNING, and INFO.
+//
+// There is also the special severity of DFATAL, which logs FATAL in
+// debug mode, ERROR in normal mode.
+//
+// Very important: logging a message at the FATAL severity level causes
+// the program to terminate (after the message is logged).
+//
+// Unless otherwise specified, logs will be written to the filename
+// "<program name>.<hostname>.<user name>.log.<severity level>.", followed
+// by the date, time, and pid (you can't prevent the date, time, and pid
+// from being in the filename).
+//
+// The logging code takes two flags:
+// --v=# set the verbose level
+// --logtostderr log all the messages to stderr instead of to logfiles
+
+// LOG LINE PREFIX FORMAT
+//
+// Log lines have this form:
+//
+// Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
+//
+// where the fields are defined as follows:
+//
+// L A single character, representing the log level
+// (eg 'I' for INFO)
+// mm The month (zero padded; ie May is '05')
+// dd The day (zero padded)
+// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
+// threadid The space-padded thread ID as returned by GetTID()
+// (this matches the PID on Linux)
+// file The file name
+// line The line number
+// msg The user-supplied message
+//
+// Example:
+//
+// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog
+// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395
+//
+// NOTE: although the microseconds are useful for comparing events on
+// a single machine, clocks on different machines may not be well
+// synchronized. Hence, use caution when comparing the low bits of
+// timestamps from different machines.
+
+#ifndef DECLARE_VARIABLE
+#define MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#define DECLARE_VARIABLE(type, name, tn) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \
+ extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name
+
+// bool specialization
+#define DECLARE_bool(name) \
+ DECLARE_VARIABLE(bool, name, bool)
+
+// int32 specialization
+#define DECLARE_int32(name) \
+ DECLARE_VARIABLE(google::int32, name, int32)
+
+// Special case for string, because we have to specify the namespace
+// std::string, which doesn't play nicely with our FLAG__namespace hackery.
+#define DECLARE_string(name) \
+ namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \
+ extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \
+ } \
+ using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+#endif
+
+// Set whether log messages go to stderr instead of logfiles
+DECLARE_bool(logtostderr);
+
+// Set whether log messages go to stderr in addition to logfiles.
+DECLARE_bool(alsologtostderr);
+
+// Log messages at a level >= this flag are automatically sent to
+// stderr in addition to log files.
+DECLARE_int32(stderrthreshold);
+
+// Set whether the log prefix should be prepended to each line of output.
+DECLARE_bool(log_prefix);
+
+// Log messages at a level <= this flag are buffered.
+// Log messages at a higher level are flushed immediately.
+DECLARE_int32(logbuflevel);
+
+// Sets the maximum number of seconds which logs may be buffered for.
+DECLARE_int32(logbufsecs);
+
+// Log suppression level: messages logged at a lower level than this
+// are suppressed.
+DECLARE_int32(minloglevel);
+
+// If specified, logfiles are written into this directory instead of the
+// default logging directory.
+DECLARE_string(log_dir);
+
+// Sets the path of the directory into which to put additional links
+// to the log files.
+DECLARE_string(log_link);
+
+DECLARE_int32(v); // in vlog_is_on.cc
+
+// Sets the maximum log file size (in MB).
+DECLARE_int32(max_log_size);
+
+// Sets whether to avoid logging to the disk if the disk is full.
+DECLARE_bool(stop_logging_if_full_disk);
+
+#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef DECLARE_VARIABLE
+#undef DECLARE_bool
+#undef DECLARE_int32
+#undef DECLARE_string
+#endif
+
+// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
+// security reasons. See LOG(severtiy) below.
+
+// A few definitions of macros that don't generate much code. Since
+// LOG(INFO) and its ilk are used all over our code, it's
+// better to have compact code for these operations.
+
+#if GOOGLE_STRIP_LOG == 0
+#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \
+ __FILE__, __LINE__)
+#define LOG_TO_STRING_INFO(message) google::LogMessage( \
+ __FILE__, __LINE__, google::INFO, message)
+#else
+#define COMPACT_GOOGLE_LOG_INFO google::NullStream()
+#define LOG_TO_STRING_INFO(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 1
+#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \
+ __FILE__, __LINE__, google::WARNING)
+#define LOG_TO_STRING_WARNING(message) google::LogMessage( \
+ __FILE__, __LINE__, google::WARNING, message)
+#else
+#define COMPACT_GOOGLE_LOG_WARNING google::NullStream()
+#define LOG_TO_STRING_WARNING(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 2
+#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \
+ __FILE__, __LINE__, google::ERROR)
+#define LOG_TO_STRING_ERROR(message) google::LogMessage( \
+ __FILE__, __LINE__, google::ERROR, message)
+#else
+#define COMPACT_GOOGLE_LOG_ERROR google::NullStream()
+#define LOG_TO_STRING_ERROR(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \
+ __FILE__, __LINE__)
+#define LOG_TO_STRING_FATAL(message) google::LogMessage( \
+ __FILE__, __LINE__, google::FATAL, message)
+#else
+#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal()
+#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal()
+#endif
+
+// For DFATAL, we want to use LogMessage (as opposed to
+// LogMessageFatal), to be consistent with the original behavior.
+#ifdef NDEBUG
+#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
+#elif GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \
+ __FILE__, __LINE__, google::FATAL)
+#else
+#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal()
+#endif
+
+#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::INFO, counter, &google::LogMessage::SendToLog)
+#define SYSLOG_INFO(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::INFO, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_WARNING(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_WARNING(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_ERROR(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_ERROR(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_FATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_FATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_DFATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \
+ &google::LogMessage::SendToLog)
+#define SYSLOG_DFATAL(counter) \
+ google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \
+ &google::LogMessage::SendToSyslogAndLog)
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
+// A very useful logging macro to log windows errors:
+#define LOG_SYSRESULT(result) \
+ if (FAILED(result)) { \
+ LPTSTR message = NULL; \
+ LPTSTR msg = reinterpret_cast<LPTSTR>(&message); \
+ DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
+ FORMAT_MESSAGE_FROM_SYSTEM, \
+ 0, result, 0, msg, 100, NULL); \
+ if (message_length > 0) { \
+ google::LogMessage(__FILE__, __LINE__, ERROR, 0, \
+ &google::LogMessage::SendToLog).stream() << message; \
+ LocalFree(message); \
+ } \
+ }
+#endif
+
+// We use the preprocessor's merging operator, "##", so that, e.g.,
+// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny
+// subtle difference between ostream member streaming functions (e.g.,
+// ostream::operator<<(int) and ostream non-member streaming functions
+// (e.g., ::operator<<(ostream&, string&): it turns out that it's
+// impossible to stream something like a string directly to an unnamed
+// ostream. We employ a neat hack by calling the stream() member
+// function of LogMessage which seems to avoid the problem.
+#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
+#define SYSLOG(severity) SYSLOG_ ## severity(0).stream()
+
+namespace google {
+
+// They need the definitions of integer types.
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Initialize google's logging library. You will see the program name
+// specified by argv0 in log outputs.
+GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0);
+
+// Shutdown google's logging library.
+GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging();
+
+// Install a function which will be called after LOG(FATAL).
+GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)());
+
+class LogSink; // defined below
+
+// If a non-NULL sink pointer is given, we push this message to that sink.
+// For LOG_TO_SINK we then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and passing/storing them
+// somewhere more specific than the global log of the process.
+// Argument types:
+// LogSink* sink;
+// LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+#define LOG_TO_SINK(sink, severity) \
+ google::LogMessage( \
+ __FILE__, __LINE__, \
+ google::severity, \
+ static_cast<google::LogSink*>(sink), true).stream()
+#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \
+ google::LogMessage( \
+ __FILE__, __LINE__, \
+ google::severity, \
+ static_cast<google::LogSink*>(sink), false).stream()
+
+// If a non-NULL string pointer is given, we write this message to that string.
+// We then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and storing them somewhere more
+// specific than the global log of the process.
+// Argument types:
+// string* message;
+// LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+// NOTE: LOG(severity) expands to LogMessage().stream() for the specified
+// severity.
+#define LOG_TO_STRING(severity, message) \
+ LOG_TO_STRING_##severity(static_cast<string*>(message)).stream()
+
+// If a non-NULL pointer is given, we push the message onto the end
+// of a vector of strings; otherwise, we report it with LOG(severity).
+// This is handy for capturing messages and perhaps passing them back
+// to the caller, rather than reporting them immediately.
+// Argument types:
+// LogSeverity severity;
+// vector<string> *outvec;
+// The cast is to disambiguate NULL arguments.
+#define LOG_STRING(severity, outvec) \
+ LOG_TO_STRING_##severity(static_cast<vector<string>*>(outvec)).stream()
+
+#define LOG_IF(severity, condition) \
+ !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+#define SYSLOG_IF(severity, condition) \
+ !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity)
+
+#define LOG_ASSERT(condition) \
+ LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+#define SYSLOG_ASSERT(condition) \
+ SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+
+// CHECK dies with a fatal error if condition is not true. It is *not*
+// controlled by NDEBUG, so the check will be executed regardless of
+// compilation mode. Therefore, it is safe to do things like:
+// CHECK(fp->Write(x) == 4)
+#define CHECK(condition) \
+ LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+ << "Check failed: " #condition " "
+
+// A container for a string pointer which can be evaluated to a bool -
+// true iff the pointer is NULL.
+struct CheckOpString {
+ CheckOpString(std::string* str) : str_(str) { }
+ // No destructor: if str_ is non-NULL, we're about to LOG(FATAL),
+ // so there's no point in cleaning up str_.
+ operator bool() const {
+ return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL);
+ }
+ std::string* str_;
+};
+
+// Function is overloaded for integral types to allow static const
+// integrals declared in classes and not defined to be used as arguments to
+// CHECK* macros. It's not encouraged though.
+template <class T>
+inline const T& GetReferenceableValue(const T& t) { return t; }
+inline char GetReferenceableValue(char t) { return t; }
+inline unsigned char GetReferenceableValue(unsigned char t) { return t; }
+inline signed char GetReferenceableValue(signed char t) { return t; }
+inline short GetReferenceableValue(short t) { return t; }
+inline unsigned short GetReferenceableValue(unsigned short t) { return t; }
+inline int GetReferenceableValue(int t) { return t; }
+inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
+inline long GetReferenceableValue(long t) { return t; }
+inline unsigned long GetReferenceableValue(unsigned long t) { return t; }
+inline long long GetReferenceableValue(long long t) { return t; }
+inline unsigned long long GetReferenceableValue(unsigned long long t) {
+ return t;
+}
+
+// This is a dummy class to define the following operator.
+struct DummyClassToDefineOperator {};
+
+}
+
+// Define global operator<< to declare using ::operator<<.
+// This declaration will allow use to use CHECK macros for user
+// defined classes which have operator<< (e.g., stl_logging.h).
+inline std::ostream& operator<<(
+ std::ostream& out, const google::DummyClassToDefineOperator&) {
+ return out;
+}
+
+namespace google {
+
+// Build the error message string.
+template<class t1, class t2>
+std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
+ // It means that we cannot use stl_logging if compiler doesn't
+ // support using expression for operator.
+ // TODO(hamaji): Figure out a way to fix.
+#if 1
+ using ::operator<<;
+#endif
+ std::strstream ss;
+ ss << names << " (" << v1 << " vs. " << v2 << ")";
+ return new std::string(ss.str(), ss.pcount());
+}
+
+// Helper functions for CHECK_OP macro.
+// The (int, int) specialization works around the issue that the compiler
+// will not instantiate the template version of the function on values of
+// unnamed enum type - see comment below.
+#define DEFINE_CHECK_OP_IMPL(name, op) \
+ template <class t1, class t2> \
+ inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
+ const char* names) { \
+ if (v1 op v2) return NULL; \
+ else return MakeCheckOpString(v1, v2, names); \
+ } \
+ inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
+ return Check##name##Impl<int, int>(v1, v2, names); \
+ }
+
+// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h
+// provides its own #defines for the simpler names EQ, NE, LE, etc.
+// This happens if, for example, those are used as token names in a
+// yacc grammar.
+DEFINE_CHECK_OP_IMPL(_EQ, ==)
+DEFINE_CHECK_OP_IMPL(_NE, !=)
+DEFINE_CHECK_OP_IMPL(_LE, <=)
+DEFINE_CHECK_OP_IMPL(_LT, < )
+DEFINE_CHECK_OP_IMPL(_GE, >=)
+DEFINE_CHECK_OP_IMPL(_GT, > )
+#undef DEFINE_CHECK_OP_IMPL
+
+// Helper macro for binary operators.
+// Don't use this macro directly in your code, use CHECK_EQ et al below.
+
+#if defined(STATIC_ANALYSIS)
+// Only for static analysis tool to know that it is equivalent to assert
+#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2))
+#elif !defined(NDEBUG)
+// In debug mode, avoid constructing CheckOpStrings if possible,
+// to reduce the overhead of CHECK statments by 2x.
+// Real DCHECK-heavy tests have seen 1.5x speedups.
+
+// The meaning of "string" might be different between now and
+// when this macro gets invoked (e.g., if someone is experimenting
+// with other string implementations that get defined after this
+// file is included). Save the current meaning now and use it
+// in the macro.
+typedef std::string _Check_string;
+#define CHECK_OP_LOG(name, op, val1, val2, log) \
+ while (google::_Check_string* _result = \
+ google::Check##name##Impl( \
+ google::GetReferenceableValue(val1), \
+ google::GetReferenceableValue(val2), \
+ #val1 " " #op " " #val2)) \
+ log(__FILE__, __LINE__, \
+ google::CheckOpString(_result)).stream()
+#else
+// In optimized mode, use CheckOpString to hint to compiler that
+// the while condition is unlikely.
+#define CHECK_OP_LOG(name, op, val1, val2, log) \
+ while (google::CheckOpString _result = \
+ google::Check##name##Impl( \
+ google::GetReferenceableValue(val1), \
+ google::GetReferenceableValue(val2), \
+ #val1 " " #op " " #val2)) \
+ log(__FILE__, __LINE__, _result).stream()
+#endif // STATIC_ANALYSIS, !NDEBUG
+
+#if GOOGLE_STRIP_LOG <= 3
+#define CHECK_OP(name, op, val1, val2) \
+ CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal)
+#else
+#define CHECK_OP(name, op, val1, val2) \
+ CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal)
+#endif // STRIP_LOG <= 3
+
+// Equality/Inequality checks - compare two values, and log a FATAL message
+// including the two values when the result is not as expected. The values
+// must have operator<<(ostream, ...) defined.
+//
+// You may append to the error message like so:
+// CHECK_NE(1, 2) << ": The world must be ending!";
+//
+// We are very careful to ensure that each argument is evaluated exactly
+// once, and that anything which is legal to pass as a function argument is
+// legal here. In particular, the arguments may be temporary expressions
+// which will end up being destroyed at the end of the apparent statement,
+// for example:
+// CHECK_EQ(string("abc")[1], 'b');
+//
+// WARNING: These don't compile correctly if one of the arguments is a pointer
+// and the other is NULL. To work around this, simply static_cast NULL to the
+// type of the desired pointer.
+
+#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2)
+#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2)
+#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2)
+#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2)
+#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2)
+#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2)
+
+// Check that the input is non NULL. This very useful in constructor
+// initializer lists.
+
+#define CHECK_NOTNULL(val) \
+ google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
+
+// Helper functions for string comparisons.
+// To avoid bloat, the definitions are in logging.cc.
+#define DECLARE_CHECK_STROP_IMPL(func, expected) \
+ GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \
+ const char* s1, const char* s2, const char* names);
+DECLARE_CHECK_STROP_IMPL(strcmp, true)
+DECLARE_CHECK_STROP_IMPL(strcmp, false)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
+#undef DECLARE_CHECK_STROP_IMPL
+
+// Helper macro for string comparisons.
+// Don't use this macro directly in your code, use CHECK_STREQ et al below.
+#define CHECK_STROP(func, op, expected, s1, s2) \
+ while (google::CheckOpString _result = \
+ google::Check##func##expected##Impl((s1), (s2), \
+ #s1 " " #op " " #s2)) \
+ LOG(FATAL) << *_result.str_
+
+
+// String (char*) equality/inequality checks.
+// CASE versions are case-insensitive.
+//
+// Note that "s1" and "s2" may be temporary strings which are destroyed
+// by the compiler at the end of the current "full expression"
+// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())).
+
+#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2)
+#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2)
+#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2)
+
+#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0])))
+#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0])))
+
+#define CHECK_DOUBLE_EQ(val1, val2) \
+ do { \
+ CHECK_LE((val1), (val2)+0.000000000000001L); \
+ CHECK_GE((val1), (val2)-0.000000000000001L); \
+ } while (0)
+
+#define CHECK_NEAR(val1, val2, margin) \
+ do { \
+ CHECK_LE((val1), (val2)+(margin)); \
+ CHECK_GE((val1), (val2)-(margin)); \
+ } while (0)
+
+// perror()..googly style!
+//
+// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and
+// CHECK equivalents with the addition that they postpend a description
+// of the current state of errno to their output lines.
+
+#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream()
+
+#define GOOGLE_PLOG(severity, counter) \
+ google::ErrnoLogMessage( \
+ __FILE__, __LINE__, google::severity, counter, \
+ &google::LogMessage::SendToLog)
+
+#define PLOG_IF(severity, condition) \
+ !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity)
+
+// A CHECK() macro that postpends errno if the condition is false. E.g.
+//
+// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... }
+#define PCHECK(condition) \
+ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+ << "Check failed: " #condition " "
+
+// A CHECK() macro that lets you assert the success of a function that
+// returns -1 and sets errno in case of an error. E.g.
+//
+// CHECK_ERR(mkdir(path, 0700));
+//
+// or
+//
+// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename;
+#define CHECK_ERR(invocation) \
+PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \
+ << #invocation
+
+// Use macro expansion to create, for each use of LOG_EVERY_N(), static
+// variables with the __LINE__ expansion as part of the variable name.
+#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line)
+#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line
+
+#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
+#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
+
+#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+ ++LOG_OCCURRENCES; \
+ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+ if (LOG_OCCURRENCES_MOD_N == 1) \
+ google::LogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+ ++LOG_OCCURRENCES; \
+ if (condition && \
+ ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \
+ google::LogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+ ++LOG_OCCURRENCES; \
+ if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+ if (LOG_OCCURRENCES_MOD_N == 1) \
+ google::ErrnoLogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
+ static int LOG_OCCURRENCES = 0; \
+ if (LOG_OCCURRENCES <= n) \
+ ++LOG_OCCURRENCES; \
+ if (LOG_OCCURRENCES <= n) \
+ google::LogMessage( \
+ __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \
+ &what_to_do).stream()
+
+namespace glog_internal_namespace_ {
+template <bool>
+struct CompileAssert {
+};
+struct CrashReason;
+} // namespace glog_internal_namespace_
+
+#define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \
+ typedef google::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
+
+#define LOG_EVERY_N(severity, n) \
+ GOOGLE_GLOG_COMPILE_ASSERT(google::severity < \
+ google::NUM_SEVERITIES, \
+ INVALID_REQUESTED_LOG_SEVERITY); \
+ SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog)
+
+#define SYSLOG_EVERY_N(severity, n) \
+ SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog)
+
+#define PLOG_EVERY_N(severity, n) \
+ SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog)
+
+#define LOG_FIRST_N(severity, n) \
+ SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog)
+
+#define LOG_IF_EVERY_N(severity, condition, n) \
+ SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog)
+
+// We want the special COUNTER value available for LOG_EVERY_X()'ed messages
+enum PRIVATE_Counter {COUNTER};
+
+
+// Plus some debug-logging macros that get compiled to nothing for production
+
+#ifndef NDEBUG
+
+#define DLOG(severity) LOG(severity)
+#define DVLOG(verboselevel) VLOG(verboselevel)
+#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
+#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+ LOG_IF_EVERY_N(severity, condition, n)
+#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
+
+// debug-only checking. not executed in NDEBUG mode.
+#define DCHECK(condition) CHECK(condition)
+#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
+#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
+#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
+#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
+#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
+#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
+#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
+#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
+#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
+#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
+#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
+
+#else // NDEBUG
+
+#define DLOG(severity) \
+ true ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DVLOG(verboselevel) \
+ (true || !VLOG_IS_ON(verboselevel)) ?\
+ (void) 0 : google::LogMessageVoidify() & LOG(INFO)
+
+#define DLOG_IF(severity, condition) \
+ (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_EVERY_N(severity, n) \
+ true ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+ (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_ASSERT(condition) \
+ true ? (void) 0 : LOG_ASSERT(condition)
+
+#define DCHECK(condition) \
+ while (false) \
+ CHECK(condition)
+
+#define DCHECK_EQ(val1, val2) \
+ while (false) \
+ CHECK_EQ(val1, val2)
+
+#define DCHECK_NE(val1, val2) \
+ while (false) \
+ CHECK_NE(val1, val2)
+
+#define DCHECK_LE(val1, val2) \
+ while (false) \
+ CHECK_LE(val1, val2)
+
+#define DCHECK_LT(val1, val2) \
+ while (false) \
+ CHECK_LT(val1, val2)
+
+#define DCHECK_GE(val1, val2) \
+ while (false) \
+ CHECK_GE(val1, val2)
+
+#define DCHECK_GT(val1, val2) \
+ while (false) \
+ CHECK_GT(val1, val2)
+
+#define DCHECK_NOTNULL(val) (val)
+
+#define DCHECK_STREQ(str1, str2) \
+ while (false) \
+ CHECK_STREQ(str1, str2)
+
+#define DCHECK_STRCASEEQ(str1, str2) \
+ while (false) \
+ CHECK_STRCASEEQ(str1, str2)
+
+#define DCHECK_STRNE(str1, str2) \
+ while (false) \
+ CHECK_STRNE(str1, str2)
+
+#define DCHECK_STRCASENE(str1, str2) \
+ while (false) \
+ CHECK_STRCASENE(str1, str2)
+
+
+#endif // NDEBUG
+
+// Log only in verbose mode.
+
+#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
+
+#define VLOG_IF(verboselevel, condition) \
+ LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
+
+#define VLOG_EVERY_N(verboselevel, n) \
+ LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n)
+
+#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
+ LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
+
+//
+// This class more or less represents a particular log message. You
+// create an instance of LogMessage and then stream stuff to it.
+// When you finish streaming to it, ~LogMessage is called and the
+// full message gets streamed to the appropriate destination.
+//
+// You shouldn't actually use LogMessage's constructor to log things,
+// though. You should use the LOG() macro (and variants thereof)
+// above.
+class GOOGLE_GLOG_DLL_DECL LogMessage {
+public:
+ enum {
+ // Passing kNoLogPrefix for the line number disables the
+ // log-message prefix. Useful for using the LogMessage
+ // infrastructure as a printing utility. See also the --log_prefix
+ // flag for controlling the log-message prefix on an
+ // application-wide basis.
+ kNoLogPrefix = -1
+ };
+
+ // LogStream inherit from non-DLL-exported class (std::ostrstream)
+ // and VC++ produces a warning for this situation.
+ // However, MSDN says "C4275 can be ignored in Microsoft Visual C++
+ // 2005 if you are deriving from a type in the Standard C++ Library"
+ // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
+ // Let's just ignore the warning.
+#ifdef _MSC_VER
+# pragma warning(disable: 4275)
+#endif
+ class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream {
+#ifdef _MSC_VER
+# pragma warning(default: 4275)
+#endif
+ public:
+ LogStream(char *buf, int len, int ctr)
+ : ostrstream(buf, len),
+ ctr_(ctr) {
+ self_ = this;
+ }
+
+ int ctr() const { return ctr_; }
+ void set_ctr(int ctr) { ctr_ = ctr; }
+ LogStream* self() const { return self_; }
+
+ private:
+ int ctr_; // Counter hack (for the LOG_EVERY_X() macro)
+ LogStream *self_; // Consistency check hack
+ };
+
+public:
+ // icc 8 requires this typedef to avoid an internal compiler error.
+ typedef void (LogMessage::*SendMethod)();
+
+ LogMessage(const char* file, int line, LogSeverity severity, int ctr,
+ SendMethod send_method);
+
+ // Two special constructors that generate reduced amounts of code at
+ // LOG call sites for common cases.
+
+ // Used for LOG(INFO): Implied are:
+ // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog.
+ //
+ // Using this constructor instead of the more complex constructor above
+ // saves 19 bytes per call site.
+ LogMessage(const char* file, int line);
+
+ // Used for LOG(severity) where severity != INFO. Implied
+ // are: ctr = 0, send_method = &LogMessage::SendToLog
+ //
+ // Using this constructor instead of the more complex constructor above
+ // saves 17 bytes per call site.
+ LogMessage(const char* file, int line, LogSeverity severity);
+
+ // Constructor to log this message to a specified sink (if not NULL).
+ // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if
+ // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise.
+ LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink,
+ bool also_send_to_log);
+
+ // Constructor where we also give a vector<string> pointer
+ // for storing the messages (if the pointer is not NULL).
+ // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog.
+ LogMessage(const char* file, int line, LogSeverity severity,
+ std::vector<std::string>* outvec);
+
+ // Constructor where we also give a string pointer for storing the
+ // message (if the pointer is not NULL). Implied are: ctr = 0,
+ // send_method = &LogMessage::WriteToStringAndLog.
+ LogMessage(const char* file, int line, LogSeverity severity,
+ std::string* message);
+
+ // A special constructor used for check failures
+ LogMessage(const char* file, int line, const CheckOpString& result);
+
+ ~LogMessage();
+
+ // Flush a buffered message to the sink set in the constructor. Always
+ // called by the destructor, it may also be called from elsewhere if
+ // needed. Only the first call is actioned; any later ones are ignored.
+ void Flush();
+
+ // An arbitrary limit on the length of a single log message. This
+ // is so that streaming can be done more efficiently.
+ static const size_t kMaxLogMessageLen;
+
+ // Theses should not be called directly outside of logging.*,
+ // only passed as SendMethod arguments to other LogMessage methods:
+ void SendToLog(); // Actually dispatch to the logs
+ void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs
+
+ // Call abort() or similar to perform LOG(FATAL) crash.
+ static void Fail() ;
+
+ std::ostream& stream() { return *(data_->stream_); }
+
+ int preserved_errno() const { return data_->preserved_errno_; }
+
+ // Must be called without the log_mutex held. (L < log_mutex)
+ static int64 num_messages(int severity);
+
+private:
+ // Fully internal SendMethod cases:
+ void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs
+ void SendToSink(); // Send to sink if provided, do nothing otherwise.
+
+ // Write to string if provided and dispatch to the logs.
+ void WriteToStringAndLog();
+
+ void SaveOrSendToLog(); // Save to stringvec if provided, else to logs
+
+ void Init(const char* file, int line, LogSeverity severity,
+ void (LogMessage::*send_method)());
+
+ // Used to fill in crash information during LOG(FATAL) failures.
+ void RecordCrashReason(glog_internal_namespace_::CrashReason* reason);
+
+ // Counts of messages sent at each priority:
+ static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex
+
+ // We keep the data in a separate struct so that each instance of
+ // LogMessage uses less stack space.
+ struct GOOGLE_GLOG_DLL_DECL LogMessageData {
+ LogMessageData() {};
+
+ int preserved_errno_; // preserved errno
+ char* buf_;
+ char* message_text_; // Complete message text (points to selected buffer)
+ LogStream* stream_alloc_;
+ LogStream* stream_;
+ char severity_; // What level is this LogMessage logged at?
+ int line_; // line number where logging call is.
+ void (LogMessage::*send_method_)(); // Call this in destructor to send
+ union { // At most one of these is used: union to keep the size low.
+ LogSink* sink_; // NULL or sink to send message to
+ std::vector<std::string>* outvec_; // NULL or vector to push message onto
+ std::string* message_; // NULL or string to write message into
+ };
+ time_t timestamp_; // Time of creation of LogMessage
+ struct ::tm tm_time_; // Time of creation of LogMessage
+ size_t num_prefix_chars_; // # of chars of prefix in this message
+ size_t num_chars_to_log_; // # of chars of msg to send to log
+ size_t num_chars_to_syslog_; // # of chars of msg to send to syslog
+ const char* basename_; // basename of file that called LOG
+ const char* fullname_; // fullname of file that called LOG
+ bool has_been_flushed_; // false => data has not been flushed
+ bool first_fatal_; // true => this was first fatal msg
+
+ ~LogMessageData();
+ private:
+ LogMessageData(const LogMessageData&);
+ void operator=(const LogMessageData&);
+ };
+
+ static LogMessageData fatal_msg_data_exclusive_;
+ static LogMessageData fatal_msg_data_shared_;
+
+ LogMessageData* allocated_;
+ LogMessageData* data_;
+
+ friend class LogDestination;
+
+ LogMessage(const LogMessage&);
+ void operator=(const LogMessage&);
+};
+
+// This class happens to be thread-hostile because all instances share
+// a single data buffer, but since it can only be created just before
+// the process dies, we don't worry so much.
+class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage {
+ public:
+ LogMessageFatal(const char* file, int line);
+ LogMessageFatal(const char* file, int line, const CheckOpString& result);
+ ~LogMessageFatal() ;
+};
+
+// A non-macro interface to the log facility; (useful
+// when the logging level is not a compile-time constant).
+inline void LogAtLevel(int const severity, std::string const &msg) {
+ LogMessage(__FILE__, __LINE__, severity).stream() << msg;
+}
+
+// A macro alternative of LogAtLevel. New code may want to use this
+// version since there are two advantages: 1. this version outputs the
+// file name and the line number where this macro is put like other
+// LOG macros, 2. this macro can be used as C++ stream.
+#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream()
+
+// A small helper for CHECK_NOTNULL().
+template <typename T>
+T* CheckNotNull(const char *file, int line, const char *names, T* t) {
+ if (t == NULL) {
+ LogMessageFatal(file, line, new std::string(names));
+ }
+ return t;
+}
+
+// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
+// only works if ostream is a LogStream. If the ostream is not a
+// LogStream you'll get an assert saying as much at runtime.
+GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os,
+ const PRIVATE_Counter&);
+
+
+// Derived class for PLOG*() above.
+class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage {
+ public:
+
+ ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr,
+ void (LogMessage::*send_method)());
+
+ // Postpends ": strerror(errno) [errno]".
+ ~ErrnoLogMessage();
+
+ private:
+ ErrnoLogMessage(const ErrnoLogMessage&);
+ void operator=(const ErrnoLogMessage&);
+};
+
+
+// This class is used to explicitly ignore values in the conditional
+// logging macros. This avoids compiler warnings like "value computed
+// is not used" and "statement has no effect".
+
+class GOOGLE_GLOG_DLL_DECL LogMessageVoidify {
+ public:
+ LogMessageVoidify() { }
+ // This has to be an operator with a precedence lower than << but
+ // higher than ?:
+ void operator&(std::ostream&) { }
+};
+
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level. Thread-safe.
+GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity);
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level. Thread-hostile because it ignores
+// locking -- used for catastrophic failures.
+GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity);
+
+//
+// Set the destination to which a particular severity level of log
+// messages is sent. If base_filename is "", it means "don't log this
+// severity". Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity,
+ const char* base_filename);
+
+//
+// Set the basename of the symlink to the latest log file at a given
+// severity. If symlink_basename is empty, do not make a symlink. If
+// you don't call this function, the symlink basename is the
+// invocation name of the program. Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity,
+ const char* symlink_basename);
+
+//
+// Used to send logs to some other kind of destination
+// Users should subclass LogSink and override send to do whatever they want.
+// Implementations must be thread-safe because a shared instance will
+// be called from whichever thread ran the LOG(XXX) line.
+class GOOGLE_GLOG_DLL_DECL LogSink {
+ public:
+ virtual ~LogSink();
+
+ // Sink's logging logic (message_len is such as to exclude '\n' at the end).
+ // This method can't use LOG() or CHECK() as logging system mutex(s) are held
+ // during this call.
+ virtual void send(LogSeverity severity, const char* full_filename,
+ const char* base_filename, int line,
+ const struct ::tm* tm_time,
+ const char* message, size_t message_len) = 0;
+
+ // Redefine this to implement waiting for
+ // the sink's logging logic to complete.
+ // It will be called after each send() returns,
+ // but before that LogMessage exits or crashes.
+ // By default this function does nothing.
+ // Using this function one can implement complex logic for send()
+ // that itself involves logging; and do all this w/o causing deadlocks and
+ // inconsistent rearrangement of log messages.
+ // E.g. if a LogSink has thread-specific actions, the send() method
+ // can simply add the message to a queue and wake up another thread that
+ // handles real logging while itself making some LOG() calls;
+ // WaitTillSent() can be implemented to wait for that logic to complete.
+ // See our unittest for an example.
+ virtual void WaitTillSent();
+
+ // Returns the normal text output of the log message.
+ // Can be useful to implement send().
+ static std::string ToString(LogSeverity severity, const char* file, int line,
+ const struct ::tm* tm_time,
+ const char* message, size_t message_len);
+};
+
+// Add or remove a LogSink as a consumer of logging data. Thread-safe.
+GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination);
+GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination);
+
+//
+// Specify an "extension" added to the filename specified via
+// SetLogDestination. This applies to all severity levels. It's
+// often used to append the port we're listening on to the logfile
+// name. Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension(
+ const char* filename_extension);
+
+//
+// Make it so that all log messages of at least a particular severity
+// are logged to stderr (in addition to logging to the usual log
+// file(s)). Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity);
+
+//
+// Make it so that all log messages go only to stderr. Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void LogToStderr();
+
+//
+// Make it so that all log messages of at least a particular severity are
+// logged via email to a list of addresses (in addition to logging to the
+// usual log file(s)). The list of addresses is just a string containing
+// the email addresses to send to (separated by spaces, say). Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity,
+ const char* addresses);
+
+// A simple function that sends email. dest is a commma-separated
+// list of addressess. Thread-safe.
+GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest,
+ const char *subject, const char *body);
+
+GOOGLE_GLOG_DLL_DECL const std::vector<std::string>& GetLoggingDirectories();
+
+// For tests only: Clear the internal [cached] list of logging directories to
+// force a refresh the next time GetLoggingDirectories is called.
+// Thread-hostile.
+void TestOnly_ClearLoggingDirectoriesList();
+
+// Returns a set of existing temporary directories, which will be a
+// subset of the directories returned by GetLogginDirectories().
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories(
+ std::vector<std::string>* list);
+
+// Print any fatal message again -- useful to call from signal handler
+// so that the last thing in the output is the fatal message.
+// Thread-hostile, but a race is unlikely.
+GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage();
+
+// Truncate a log file that may be the append-only output of multiple
+// processes and hence can't simply be renamed/reopened (typically a
+// stdout/stderr). If the file "path" is > "limit" bytes, copy the
+// last "keep" bytes to offset 0 and truncate the rest. Since we could
+// be racing with other writers, this approach has the potential to
+// lose very small amounts of data. For security, only follow symlinks
+// if the path is /proc/self/fd/*
+GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path,
+ int64 limit, int64 keep);
+
+// Truncate stdout and stderr if they are over the value specified by
+// --max_log_size; keep the final 1MB. This function has the same
+// race condition as TruncateLogFile.
+GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr();
+
+// Return the string representation of the provided LogSeverity level.
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity);
+
+// ---------------------------------------------------------------------
+// Implementation details that are not useful to most clients
+// ---------------------------------------------------------------------
+
+// A Logger is the interface used by logging modules to emit entries
+// to a log. A typical implementation will dump formatted data to a
+// sequence of files. We also provide interfaces that will forward
+// the data to another thread so that the invoker never blocks.
+// Implementations should be thread-safe since the logging system
+// will write to them from multiple threads.
+
+namespace base {
+
+class GOOGLE_GLOG_DLL_DECL Logger {
+ public:
+ virtual ~Logger();
+
+ // Writes "message[0,message_len-1]" corresponding to an event that
+ // occurred at "timestamp". If "force_flush" is true, the log file
+ // is flushed immediately.
+ //
+ // The input message has already been formatted as deemed
+ // appropriate by the higher level logging facility. For example,
+ // textual log messages already contain timestamps, and the
+ // file:linenumber header.
+ virtual void Write(bool force_flush,
+ time_t timestamp,
+ const char* message,
+ int message_len) = 0;
+
+ // Flush any buffered messages
+ virtual void Flush() = 0;
+
+ // Get the current LOG file size.
+ // The returned value is approximate since some
+ // logged data may not have been flushed to disk yet.
+ virtual uint32 LogSize() = 0;
+};
+
+// Get the logger for the specified severity level. The logger
+// remains the property of the logging module and should not be
+// deleted by the caller. Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level);
+
+// Set the logger for the specified severity level. The logger
+// becomes the property of the logging module and should not
+// be deleted by the caller. Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
+
+}
+
+// glibc has traditionally implemented two incompatible versions of
+// strerror_r(). There is a poorly defined convention for picking the
+// version that we want, but it is not clear whether it even works with
+// all versions of glibc.
+// So, instead, we provide this wrapper that automatically detects the
+// version that is in use, and then implements POSIX semantics.
+// N.B. In addition to what POSIX says, we also guarantee that "buf" will
+// be set to an empty string, if this function failed. This means, in most
+// cases, you do not need to check the error code and you can directly
+// use the value of "buf". It will never have an undefined value.
+GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
+
+
+// A class for which we define operator<<, which does nothing.
+class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
+ public:
+ // Initialize the LogStream so the messages can be written somewhere
+ // (they'll never be actually displayed). This will be needed if a
+ // NullStream& is implicitly converted to LogStream&, in which case
+ // the overloaded NullStream::operator<< will not be invoked.
+ NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
+ NullStream(const char* /*file*/, int /*line*/,
+ const CheckOpString& /*result*/) :
+ LogMessage::LogStream(message_buffer_, 1, 0) { }
+ NullStream &stream() { return *this; }
+ private:
+ // A very short buffer for messages (which we discard anyway). This
+ // will be needed if NullStream& converted to LogStream& (e.g. as a
+ // result of a conditional expression).
+ char message_buffer_[2];
+};
+
+// Do nothing. This operator is inline, allowing the message to be
+// compiled away. The message will not be compiled away if we do
+// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
+// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
+// converted to LogStream and the message will be computed and then
+// quietly discarded.
+template<class T>
+inline NullStream& operator<<(NullStream &str, const T &value) { return str; }
+
+// Similar to NullStream, but aborts the program (without stack
+// trace), like LogMessageFatal.
+class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream {
+ public:
+ NullStreamFatal() { }
+ NullStreamFatal(const char* file, int line, const CheckOpString& result) :
+ NullStream(file, line, result) { }
+ ~NullStreamFatal() { _exit(1); }
+};
+
+// Install a signal handler that will dump signal information and a stack
+// trace when the program crashes on certain signals. We'll install the
+// signal handler for the following signals.
+//
+// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM.
+//
+// By default, the signal handler will write the failure dump to the
+// standard error. You can customize the destination by installing your
+// own writer function by InstallFailureWriter() below.
+//
+// Note on threading:
+//
+// The function should be called before threads are created, if you want
+// to use the failure signal handler for all threads. The stack trace
+// will be shown only for the thread that receives the signal. In other
+// words, stack traces of other threads won't be shown.
+GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler();
+
+// Installs a function that is used for writing the failure dump. "data"
+// is the pointer to the beginning of a message to be written, and "size"
+// is the size of the message. You should not expect the data is
+// terminated with '\0'.
+GOOGLE_GLOG_DLL_DECL void InstallFailureWriter(
+ void (*writer)(const char* data, int size));
+
+}
+
+#endif // _LOGGING_H_
diff --git a/extern/libmv/third_party/glog/src/windows/glog/raw_logging.h b/extern/libmv/third_party/glog/src/windows/glog/raw_logging.h
new file mode 100644
index 00000000000..c81e67bf99c
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/glog/raw_logging.h
@@ -0,0 +1,189 @@
+// This file is automatically generated from src/glog/raw_logging.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// Thread-safe logging routines that do not allocate any memory or
+// acquire any locks, and can therefore be used by low-level memory
+// allocation and synchronization code.
+
+#ifndef BASE_RAW_LOGGING_H_
+#define BASE_RAW_LOGGING_H_
+
+#include <time.h>
+
+namespace google {
+
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// This is similar to LOG(severity) << format... and VLOG(level) << format..,
+// but
+// * it is to be used ONLY by low-level modules that can't use normal LOG()
+// * it is desiged to be a low-level logger that does not allocate any
+// memory and does not need any locks, hence:
+// * it logs straight and ONLY to STDERR w/o buffering
+// * it uses an explicit format and arguments list
+// * it will silently chop off really long message strings
+// Usage example:
+// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
+// RAW_VLOG(3, "status is %i", status);
+// These will print an almost standard log lines like this to stderr only:
+// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
+// I0821 211317 file.cc:142] RAW: status is 20
+#define RAW_LOG(severity, ...) \
+ do { \
+ switch (google::severity) { \
+ case 0: \
+ RAW_LOG_INFO(__VA_ARGS__); \
+ break; \
+ case 1: \
+ RAW_LOG_WARNING(__VA_ARGS__); \
+ break; \
+ case 2: \
+ RAW_LOG_ERROR(__VA_ARGS__); \
+ break; \
+ case 3: \
+ RAW_LOG_FATAL(__VA_ARGS__); \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+
+// The following STRIP_LOG testing is performed in the header file so that it's
+// possible to completely compile out the logging code and the log messages.
+#if STRIP_LOG == 0
+#define RAW_VLOG(verboselevel, ...) \
+ do { \
+ if (VLOG_IS_ON(verboselevel)) { \
+ RAW_LOG_INFO(__VA_ARGS__); \
+ } \
+ } while (0)
+#else
+#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG == 0
+#define RAW_LOG_INFO(...) google::RawLog__(google::INFO, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG <= 1
+#define RAW_LOG_WARNING(...) google::RawLog__(google::WARNING, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 1
+
+#if STRIP_LOG <= 2
+#define RAW_LOG_ERROR(...) google::RawLog__(google::ERROR, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 2
+
+#if STRIP_LOG <= 3
+#define RAW_LOG_FATAL(...) google::RawLog__(google::FATAL, \
+ __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_FATAL(...) \
+ do { \
+ google::RawLogStub__(0, __VA_ARGS__); \
+ exit(1); \
+ } while (0)
+#endif // STRIP_LOG <= 3
+
+// Similar to CHECK(condition) << message,
+// but for low-level modules: we use only RAW_LOG that does not allocate memory.
+// We do not want to provide args list here to encourage this usage:
+// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
+// so that the args are not computed when not needed.
+#define RAW_CHECK(condition, message) \
+ do { \
+ if (!(condition)) { \
+ RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
+ } \
+ } while (0)
+
+// Debug versions of RAW_LOG and RAW_CHECK
+#ifndef NDEBUG
+
+#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
+
+#else // NDEBUG
+
+#define RAW_DLOG(severity, ...) \
+ while (false) \
+ RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) \
+ while (false) \
+ RAW_CHECK(condition, message)
+
+#endif // NDEBUG
+
+// Stub log function used to work around for unused variable warnings when
+// building with STRIP_LOG > 0.
+static inline void RawLogStub__(int ignored, ...) {
+}
+
+// Helper function to implement RAW_LOG and RAW_VLOG
+// Logs format... at "severity" level, reporting it
+// as called from file:line.
+// This does not allocate memory or acquire locks.
+GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
+ const char* file,
+ int line,
+ const char* format, ...)
+ ;
+
+// Hack to propagate time information into this module so that
+// this module does not have to directly call localtime_r(),
+// which could allocate memory.
+GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs);
+
+}
+
+#endif // BASE_RAW_LOGGING_H_
diff --git a/extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h b/extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h
new file mode 100644
index 00000000000..409a4011b38
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h
@@ -0,0 +1,133 @@
+// This file is automatically generated from src/glog/vlog_is_on.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 1999, 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney and many others
+//
+// Defines the VLOG_IS_ON macro that controls the variable-verbosity
+// conditional logging.
+//
+// It's used by VLOG and VLOG_IF in logging.h
+// and by RAW_VLOG in raw_logging.h to trigger the logging.
+//
+// It can also be used directly e.g. like this:
+// if (VLOG_IS_ON(2)) {
+// // do some logging preparation and logging
+// // that can't be accomplished e.g. via just VLOG(2) << ...;
+// }
+//
+// The truth value that VLOG_IS_ON(level) returns is determined by
+// the three verbosity level flags:
+// --v=<n> Gives the default maximal active V-logging level;
+// 0 is the default.
+// Normally positive values are used for V-logging levels.
+// --vmodule=<str> Gives the per-module maximal V-logging levels to override
+// the value given by --v.
+// E.g. "my_module=2,foo*=3" would change the logging level
+// for all code in source files "my_module.*" and "foo*.*"
+// ("-inl" suffixes are also disregarded for this matching).
+//
+// SetVLOGLevel helper function is provided to do limited dynamic control over
+// V-logging by overriding the per-module settings given via --vmodule flag.
+//
+// CAVEAT: --vmodule functionality is not available in non gcc compilers.
+//
+
+#ifndef BASE_VLOG_IS_ON_H_
+#define BASE_VLOG_IS_ON_H_
+
+#include "glog/log_severity.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
+# else
+# define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+#if defined(__GNUC__)
+// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
+// (Normally) the first time every VLOG_IS_ON(n) site is hit,
+// we determine what variable will dynamically control logging at this site:
+// it's either FLAGS_v or an appropriate internal variable
+// matching the current source file that represents results of
+// parsing of --vmodule flag and/or SetVLOGLevel calls.
+#define VLOG_IS_ON(verboselevel) \
+ __extension__ \
+ ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \
+ google::int32 verbose_level__ = (verboselevel); \
+ (*vlocal__ >= verbose_level__) && \
+ ((vlocal__ != &google::kLogSiteUninitialized) || \
+ (google::InitVLOG3__(&vlocal__, &FLAGS_v, \
+ __FILE__, verbose_level__))); })
+#else
+// GNU extensions not available, so we do not support --vmodule.
+// Dynamic value of FLAGS_v always controls the logging level.
+#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
+#endif
+
+// Set VLOG(_IS_ON) level for module_pattern to log_level.
+// This lets us dynamically control what is normally set by the --vmodule flag.
+// Returns the level that previously applied to module_pattern.
+// NOTE: To change the log level for VLOG(_IS_ON) sites
+// that have already executed after/during InitGoogleLogging,
+// one needs to supply the exact --vmodule pattern that applied to them.
+// (If no --vmodule pattern applied to them
+// the value of FLAGS_v will continue to control them.)
+extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
+ int log_level);
+
+// Various declarations needed for VLOG_IS_ON above: =========================
+
+// Special value used to indicate that a VLOG_IS_ON site has not been
+// initialized. We make this a large value, so the common-case check
+// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
+// passes in such cases and InitVLOG3__ is then triggered.
+extern google::int32 kLogSiteUninitialized;
+
+// Helper routine which determines the logging info for a particalur VLOG site.
+// site_flag is the address of the site-local pointer to the controlling
+// verbosity level
+// site_default is the default to use for *site_flag
+// fname is the current source file name
+// verbose_level is the argument to VLOG_IS_ON
+// We will return the return value for VLOG_IS_ON
+// and if possible set *site_flag appropriately.
+extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
+ google::int32** site_flag,
+ google::int32* site_default,
+ const char* fname,
+ google::int32 verbose_level);
+
+#endif // BASE_VLOG_IS_ON_H_
diff --git a/extern/libmv/third_party/glog/src/windows/port.cc b/extern/libmv/third_party/glog/src/windows/port.cc
new file mode 100644
index 00000000000..bfa6e70afbb
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/port.cc
@@ -0,0 +1,64 @@
+/* Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ * Copied from google-perftools and modified by Shinichiro Hamaji
+ */
+
+#ifndef _WIN32
+# error You should only be including windows/port.cc in a windows environment!
+#endif
+
+#include "config.h"
+#include <stdarg.h> // for va_list, va_start, va_end
+#include <string.h> // for strstr()
+#include <assert.h>
+#include <string>
+#include <vector>
+#include "port.h"
+
+using std::string;
+using std::vector;
+
+// These call the windows _vsnprintf, but always NUL-terminate.
+int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
+ if (size == 0) // not even room for a \0?
+ return -1; // not what C99 says to do, but what windows does
+ str[size-1] = '\0';
+ return _vsnprintf(str, size-1, format, ap);
+}
+
+int snprintf(char *str, size_t size, const char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ const int r = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return r;
+}
diff --git a/extern/libmv/third_party/glog/src/windows/port.h b/extern/libmv/third_party/glog/src/windows/port.h
new file mode 100644
index 00000000000..d5078120009
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/port.h
@@ -0,0 +1,170 @@
+/* Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ * Copied from google-perftools and modified by Shinichiro Hamaji
+ *
+ * These are some portability typedefs and defines to make it a bit
+ * easier to compile this code under VC++.
+ *
+ * Several of these are taken from glib:
+ * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
+ */
+
+#ifndef CTEMPLATE_WINDOWS_PORT_H_
+#define CTEMPLATE_WINDOWS_PORT_H_
+
+#include "config.h"
+
+#ifdef _WIN32
+
+#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
+#include <windows.h>
+#include <winsock.h> /* for gethostname */
+#include <io.h> /* because we so often use open/close/etc */
+#include <direct.h> /* for _getcwd() */
+#include <process.h> /* for _getpid() */
+#include <stdio.h> /* read in vsnprintf decl. before redifining it */
+#include <stdarg.h> /* template_dictionary.cc uses va_copy */
+#include <string.h> /* for _strnicmp(), strerror_s() */
+#include <time.h> /* for localtime_s() */
+/* Note: the C++ #includes are all together at the bottom. This file is
+ * used by both C and C++ code, so we put all the C++ together.
+ */
+
+#if _MSC_VER
+ /* 4244: otherwise we get problems when substracting two size_t's to an int
+ * 4251: it's complaining about a private struct I've chosen not to dllexport
+ * 4355: we use this in a constructor, but we do it safely
+ * 4715: for some reason VC++ stopped realizing you can't return after abort()
+ * 4800: we know we're casting ints/char*'s to bools, and we're ok with that
+ * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
+ */
+# pragma warning(disable:4244 4251 4355 4715 4800 4996)
+#endif
+
+/* file I/O */
+#define PATH_MAX 1024
+#define access _access
+#define getcwd _getcwd
+#define open _open
+#define read _read
+#define write _write
+#define lseek _lseek
+#define close _close
+#define popen _popen
+#define pclose _pclose
+#define R_OK 04 /* read-only (for access()) */
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#ifndef __MINGW32__
+enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
+#endif
+#define S_IRUSR S_IREAD
+#define S_IWUSR S_IWRITE
+
+/* Not quite as lightweight as a hard-link, but more than good enough for us. */
+#define link(oldpath, newpath) CopyFileA(oldpath, newpath, false)
+
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+
+/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */
+#define hash hash_compare
+
+/* Sleep is in ms, on windows */
+#define sleep(secs) Sleep((secs) * 1000)
+
+/* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
+ * because they don't always NUL-terminate. :-( We also can't use the
+ * name vsnprintf, since windows defines that (but not snprintf (!)).
+ */
+extern int snprintf(char *str, size_t size,
+ const char *format, ...);
+extern int safe_vsnprintf(char *str, size_t size,
+ const char *format, va_list ap);
+#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
+#if !defined(__MINGW32__)
+#define va_copy(dst, src) (dst) = (src)
+#endif
+
+/* Windows doesn't support specifying the number of buckets as a
+ * hash_map constructor arg, so we leave this blank.
+ */
+#define CTEMPLATE_SMALL_HASHTABLE
+
+#define DEFAULT_TEMPLATE_ROOTDIR ".."
+
+// ----------------------------------- SYSTEM/PROCESS
+typedef int pid_t;
+#define getpid _getpid
+
+// ----------------------------------- THREADS
+typedef DWORD pthread_t;
+typedef DWORD pthread_key_t;
+typedef LONG pthread_once_t;
+enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
+#define pthread_self GetCurrentThreadId
+#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2))
+
+inline struct tm* localtime_r(const time_t* timep, struct tm* result) {
+#if __MINGW32__
+ struct tm *local_result;
+ local_result = localtime (timep);
+
+ if (local_result == NULL || result == NULL)
+ return NULL;
+
+ memcpy (result, local_result, sizeof (result));
+
+ return result;
+#else
+ localtime_s(result, timep);
+ return result;
+#endif
+}
+
+inline char* strerror_r(int errnum, char* buf, size_t buflen) {
+#if __MINGW32__
+ strncpy(buf, "Not implemented yet", buflen);
+ return buf;
+#else
+ strerror_s(buf, buflen, errnum);
+ return buf;
+#endif
+}
+
+#ifndef __cplusplus
+/* I don't see how to get inlining for C code in MSVC. Ah well. */
+#define inline
+#endif
+
+#endif /* _WIN32 */
+
+#endif /* CTEMPLATE_WINDOWS_PORT_H_ */
diff --git a/extern/libmv/third_party/glog/src/windows/preprocess.sh b/extern/libmv/third_party/glog/src/windows/preprocess.sh
new file mode 100755
index 00000000000..ea4352e8e3a
--- /dev/null
+++ b/extern/libmv/third_party/glog/src/windows/preprocess.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+# Copyright (c) 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# ---
+# Author: Craig Silverstein
+# Copied from google-perftools and modified by Shinichiro Hamaji
+#
+# This script is meant to be run at distribution-generation time, for
+# instance by autogen.sh. It does some of the work configure would
+# normally do, for windows systems. In particular, it expands all the
+# @...@ variables found in .in files, and puts them here, in the windows
+# directory.
+#
+# This script should be run before any new release.
+
+if [ -z "$1" ]; then
+ echo "USAGE: $0 <src/ directory>"
+ exit 1
+fi
+
+DLLDEF_MACRO_NAME="GLOG_DLL_DECL"
+
+# The text we put in every .h files we create. As a courtesy, we'll
+# include a helpful comment for windows users as to how to use
+# GLOG_DLL_DECL. Apparently sed expands \n into a newline. Good!
+DLLDEF_DEFINES="\
+// NOTE: if you are statically linking the template library into your binary\n\
+// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\
+// as a compiler flag in your project file to turn off the dllimports.\n\
+#ifndef $DLLDEF_MACRO_NAME\n\
+# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\
+#endif"
+
+# Read all the windows config info into variables
+# In order for the 'set' to take, this requires putting all in a subshell.
+(
+ while read define varname value; do
+ [ "$define" != "#define" ] && continue
+ eval "$varname='$value'"
+ done
+
+ # Process all the .in files in the "glog" subdirectory
+ mkdir -p "$1/windows/glog"
+ for file in `echo "$1"/glog/*.in`; do
+ echo "Processing $file"
+ outfile="$1/windows/glog/`basename $file .in`"
+
+ echo "\
+// This file is automatically generated from $file
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+" > "$outfile"
+ # Besides replacing @...@, we also need to turn on dllimport
+ # We also need to replace hash by hash_compare (annoying we hard-code :-( )
+ sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \
+ -e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \
+ -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \
+ -e "s!@ac_cv_cxx_hash_namespace@!$HASH_NAMESPACE!g" \
+ -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \
+ -e "s!@ac_cv_have_stdint_h@!0!g" \
+ -e "s!@ac_cv_have_systypes_h@!0!g" \
+ -e "s!@ac_cv_have_inttypes_h@!0!g" \
+ -e "s!@ac_cv_have_unistd_h@!0!g" \
+ -e "s!@ac_cv_have_uint16_t@!0!g" \
+ -e "s!@ac_cv_have_u_int16_t@!0!g" \
+ -e "s!@ac_cv_have___uint16@!1!g" \
+ -e "s!@ac_cv_have_libgflags@!0!g" \
+ -e "s!@ac_cv_have___builtin_expect@!0!g" \
+ -e "s!@ac_cv_cxx_using_operator@!1!g" \
+ -e "s!@ac_cv___attribute___noreturn@!!g" \
+ -e "s!@ac_cv___attribute___printf_4_5@!!g" \
+ -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \
+ -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \
+ -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \
+ -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \
+ -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \
+ -e "s!\\bhash\\b!hash_compare!g" \
+ "$file" >> "$outfile"
+ done
+) < "$1/windows/config.h"
+
+# log_severity.h isn't a .in file.
+echo "\
+// This file is automatically generated from $1/glog/log_severity.h
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+" > "$1/windows/glog/log_severity.h"
+cat "$1/glog/log_severity.h" >> "$1/windows/glog/log_severity.h"
+
+echo "DONE"
diff --git a/extern/libmv/third_party/ldl/CMakeLists.txt b/extern/libmv/third_party/ldl/CMakeLists.txt
new file mode 100644
index 00000000000..db2d40e2612
--- /dev/null
+++ b/extern/libmv/third_party/ldl/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(../ufconfig)
+include_directories(Include)
+add_library(ldl Source/ldl.c)
+
+LIBMV_INSTALL_THIRD_PARTY_LIB(ldl)
diff --git a/extern/libmv/third_party/ldl/Doc/ChangeLog b/extern/libmv/third_party/ldl/Doc/ChangeLog
new file mode 100644
index 00000000000..48c322d3e77
--- /dev/null
+++ b/extern/libmv/third_party/ldl/Doc/ChangeLog
@@ -0,0 +1,39 @@
+May 31, 2007: version 2.0.0
+
+ * C-callable 64-bit version added
+
+ * ported to 64-bit MATLAB
+
+ * subdirectories added (Source/, Include/, Lib/, Demo/, Doc/, MATLAB/)
+
+Dec 12, 2006: version 1.3.4
+
+ * minor MATLAB cleanup
+
+Sept 11, 2006: version 1.3.1
+
+ * The ldl m-file renamed to ldlsparse, to avoid name conflict with the
+ new MATLAB ldl function (in MATLAB 7.3).
+
+Apr 30, 2006: version 1.3
+
+ * requires AMD v2.0. ldlmain.c demo program modified, since AMD can now
+ handle jumbled matrices. Minor change to Makefile.
+
+Aug 30, 2005:
+
+ * Makefile changed to use ../UFconfig/UFconfig.mk. License changed to
+ GNU LGPL.
+
+July 4, 2005:
+
+ * user guide added. Since no changes to the code were made,
+ the version number (1.1) and code release date (Apr 22, 2005)
+ were left unchanged.
+
+Apr. 22, 2005: LDL v1.1 released.
+
+ * No real changes were made. The code was revised so
+ that each routine fits on a single page in the documentation.
+
+Dec 31, 2003: LDL v1.0 released.
diff --git a/extern/libmv/third_party/ldl/Doc/lesser.txt b/extern/libmv/third_party/ldl/Doc/lesser.txt
new file mode 100644
index 00000000000..8add30ad590
--- /dev/null
+++ b/extern/libmv/third_party/ldl/Doc/lesser.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/extern/libmv/third_party/ldl/Include/ldl.h b/extern/libmv/third_party/ldl/Include/ldl.h
new file mode 100644
index 00000000000..5840be322f7
--- /dev/null
+++ b/extern/libmv/third_party/ldl/Include/ldl.h
@@ -0,0 +1,104 @@
+/* ========================================================================== */
+/* === ldl.h: include file for the LDL package ============================= */
+/* ========================================================================== */
+
+/* LDL Copyright (c) Timothy A Davis,
+ * University of Florida. All Rights Reserved. See README for the License.
+ */
+
+#include "UFconfig.h"
+
+#ifdef LDL_LONG
+#define LDL_int UF_long
+#define LDL_ID UF_long_id
+
+#define LDL_symbolic ldl_l_symbolic
+#define LDL_numeric ldl_l_numeric
+#define LDL_lsolve ldl_l_lsolve
+#define LDL_dsolve ldl_l_dsolve
+#define LDL_ltsolve ldl_l_ltsolve
+#define LDL_perm ldl_l_perm
+#define LDL_permt ldl_l_permt
+#define LDL_valid_perm ldl_l_valid_perm
+#define LDL_valid_matrix ldl_l_valid_matrix
+
+#else
+#define LDL_int int
+#define LDL_ID "%d"
+
+#define LDL_symbolic ldl_symbolic
+#define LDL_numeric ldl_numeric
+#define LDL_lsolve ldl_lsolve
+#define LDL_dsolve ldl_dsolve
+#define LDL_ltsolve ldl_ltsolve
+#define LDL_perm ldl_perm
+#define LDL_permt ldl_permt
+#define LDL_valid_perm ldl_valid_perm
+#define LDL_valid_matrix ldl_valid_matrix
+
+#endif
+
+/* ========================================================================== */
+/* === int version ========================================================== */
+/* ========================================================================== */
+
+void ldl_symbolic (int n, int Ap [ ], int Ai [ ], int Lp [ ],
+ int Parent [ ], int Lnz [ ], int Flag [ ], int P [ ], int Pinv [ ]) ;
+
+int ldl_numeric (int n, int Ap [ ], int Ai [ ], double Ax [ ],
+ int Lp [ ], int Parent [ ], int Lnz [ ], int Li [ ], double Lx [ ],
+ double D [ ], double Y [ ], int Pattern [ ], int Flag [ ],
+ int P [ ], int Pinv [ ]) ;
+
+void ldl_lsolve (int n, double X [ ], int Lp [ ], int Li [ ],
+ double Lx [ ]) ;
+
+void ldl_dsolve (int n, double X [ ], double D [ ]) ;
+
+void ldl_ltsolve (int n, double X [ ], int Lp [ ], int Li [ ],
+ double Lx [ ]) ;
+
+void ldl_perm (int n, double X [ ], double B [ ], int P [ ]) ;
+void ldl_permt (int n, double X [ ], double B [ ], int P [ ]) ;
+
+int ldl_valid_perm (int n, int P [ ], int Flag [ ]) ;
+int ldl_valid_matrix ( int n, int Ap [ ], int Ai [ ]) ;
+
+/* ========================================================================== */
+/* === long version ========================================================= */
+/* ========================================================================== */
+
+void ldl_l_symbolic (UF_long n, UF_long Ap [ ], UF_long Ai [ ], UF_long Lp [ ],
+ UF_long Parent [ ], UF_long Lnz [ ], UF_long Flag [ ], UF_long P [ ],
+ UF_long Pinv [ ]) ;
+
+UF_long ldl_l_numeric (UF_long n, UF_long Ap [ ], UF_long Ai [ ], double Ax [ ],
+ UF_long Lp [ ], UF_long Parent [ ], UF_long Lnz [ ], UF_long Li [ ],
+ double Lx [ ], double D [ ], double Y [ ], UF_long Pattern [ ],
+ UF_long Flag [ ], UF_long P [ ], UF_long Pinv [ ]) ;
+
+void ldl_l_lsolve (UF_long n, double X [ ], UF_long Lp [ ], UF_long Li [ ],
+ double Lx [ ]) ;
+
+void ldl_l_dsolve (UF_long n, double X [ ], double D [ ]) ;
+
+void ldl_l_ltsolve (UF_long n, double X [ ], UF_long Lp [ ], UF_long Li [ ],
+ double Lx [ ]) ;
+
+void ldl_l_perm (UF_long n, double X [ ], double B [ ], UF_long P [ ]) ;
+void ldl_l_permt (UF_long n, double X [ ], double B [ ], UF_long P [ ]) ;
+
+UF_long ldl_l_valid_perm (UF_long n, UF_long P [ ], UF_long Flag [ ]) ;
+UF_long ldl_l_valid_matrix ( UF_long n, UF_long Ap [ ], UF_long Ai [ ]) ;
+
+/* ========================================================================== */
+/* === LDL version ========================================================== */
+/* ========================================================================== */
+
+#define LDL_DATE "Nov 1, 2007"
+#define LDL_VERSION_CODE(main,sub) ((main) * 1000 + (sub))
+#define LDL_MAIN_VERSION 2
+#define LDL_SUB_VERSION 0
+#define LDL_SUBSUB_VERSION 1
+#define LDL_VERSION LDL_VERSION_CODE(LDL_MAIN_VERSION,LDL_SUB_VERSION)
+
diff --git a/extern/libmv/third_party/ldl/README.libmv b/extern/libmv/third_party/ldl/README.libmv
new file mode 100644
index 00000000000..64ece48a390
--- /dev/null
+++ b/extern/libmv/third_party/ldl/README.libmv
@@ -0,0 +1,10 @@
+Project: LDL
+URL: http://www.cise.ufl.edu/research/sparse/ldl/
+License: LGPL2.1
+Upstream version: 2.0.1 (despite the ChangeLog saying 2.0.0)
+
+Local modifications:
+
+ * Deleted everything except ldl.c, ldl.h, the license, the ChangeLog, and the
+ README.
+
diff --git a/extern/libmv/third_party/ldl/README.txt b/extern/libmv/third_party/ldl/README.txt
new file mode 100644
index 00000000000..7be8dd1f001
--- /dev/null
+++ b/extern/libmv/third_party/ldl/README.txt
@@ -0,0 +1,136 @@
+LDL Version 2.0: a sparse LDL' factorization and solve package.
+ Written in C, with both a C and MATLAB mexFunction interface.
+
+These routines are not terrifically fast (they do not use dense matrix kernels),
+but the code is very short and concise. The purpose is to illustrate the
+algorithms in a very concise and readable manner, primarily for educational
+purposes. Although the code is very concise, this package is slightly faster
+than the built-in sparse Cholesky factorization in MATLAB 6.5 (chol), when
+using the same input permutation.
+
+Requires UFconfig, in the ../UFconfig directory relative to this directory.
+
+Quick start (Unix, or Windows with Cygwin):
+
+ To compile, test, and install LDL, you may wish to first obtain a copy of
+ AMD v2.0 from http://www.cise.ufl.edu/research/sparse, and place it in the
+ ../AMD directory, relative to this directory. Next, type "make", which
+ will compile the LDL library and three demo main programs (one of which
+ requires AMD). It will also compile the LDL MATLAB mexFunction (if you
+ have MATLAB). Typing "make clean" will remove non-essential files.
+ AMD v2.0 or later is required. Its use is optional.
+
+Quick start (for MATLAB users);
+
+ To compile, test, and install the LDL mexFunctions (ldlsparse and
+ ldlsymbol), start MATLAB in this directory and type ldl_install.
+ This works on any system supported by MATLAB.
+
+--------------------------------------------------------------------------------
+
+LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved.
+
+LDL License:
+
+ Your use or distribution of LDL or any modified version of
+ LDL implies that you agree to this License.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+ Permission is hereby granted to use or copy this program under the
+ terms of the GNU LGPL, provided that the Copyright, this License,
+ and the Availability of the original version is retained on all copies.
+ User documentation of any code that uses this code or any modified
+ version of this code must cite the Copyright, this License, the
+ Availability note, and "Used by permission." Permission to modify
+ the code and to distribute modified code is granted, provided the
+ Copyright, this License, and the Availability note are retained,
+ and a notice that the code was modified is included.
+
+Availability:
+
+ http://www.cise.ufl.edu/research/sparse/ldl
+
+Acknowledgements:
+
+ This work was supported by the National Science Foundation, under
+ grant CCR-0203270.
+
+ Portions of this work were done while on sabbatical at Stanford University
+ and Lawrence Berkeley National Laboratory (with funding from the SciDAC
+ program). I would like to thank Gene Golub, Esmond Ng, and Horst Simon
+ for making this sabbatical possible. I would like to thank Pete Stewart
+ for his comments on a draft of this software and paper.
+
+--------------------------------------------------------------------------------
+Files and directories in this distribution:
+--------------------------------------------------------------------------------
+
+ Documentation, and compiling:
+
+ README.txt this file
+ Makefile for compiling LDL
+ ChangeLog changes since V1.0 (Dec 31, 2003)
+ License license
+ lesser.txt the GNU LGPL license
+
+ ldl_userguide.pdf user guide in PDF
+ ldl_userguide.ps user guide in postscript
+ ldl_userguide.tex user guide in Latex
+ ldl.bib bibliography for user guide
+
+ The LDL library itself:
+
+ ldl.c the C-callable routines
+ ldl.h include file for any code that calls LDL
+
+ A simple C main program that demonstrates how to use LDL:
+
+ ldlsimple.c a stand-alone C program, uses the basic features of LDL
+ ldlsimple.out output of ldlsimple
+
+ ldllsimple.c long integer version of ldlsimple.c
+
+ Demo C program, for testing LDL and providing an example of its use
+
+ ldlmain.c a stand-alone C main program that uses and tests LDL
+ Matrix a directory containing matrices used by ldlmain.c
+ ldlmain.out output of ldlmain
+ ldlamd.out output of ldlamd (ldlmain.c compiled with AMD)
+ ldllamd.out output of ldllamd (ldlmain.c compiled with AMD, long)
+
+ MATLAB-related, not required for use in a regular C program
+
+ Contents.m a list of the MATLAB-callable routines
+ ldl.m MATLAB help file for the LDL mexFunction
+ ldldemo.m MATLAB demo of how to use the LDL mexFunction
+ ldldemo.out diary output of ldldemo
+ ldltest.m to test the LDL mexFunction
+ ldltest.out diary output of ldltest
+ ldlmex.c the LDL mexFunction for MATLAB
+ ldlrow.m the numerical algorithm that LDL is based on
+ ldlmain2.m compiles and runs ldlmain.c as a MATLAB mexFunction
+ ldlmain2.out output of ldlmain2.m
+ ldlsymbolmex.c symbolic factorization using LDL (see SYMBFACT, ETREE)
+ ldlsymbol.m help file for the LDLSYMBOL mexFunction
+
+ ldl_install.m compile, install, and test LDL functions
+ ldl_make.m compile LDL (ldlsparse and ldlsymbol)
+
+ ldlsparse.m help for ldlsparse
+
+See ldl.c for a description of how to use the code from a C program. Type
+"help ldl" in MATLAB for information on how to use LDL in a MATLAB program.
diff --git a/extern/libmv/third_party/ldl/Source/ldl.c b/extern/libmv/third_party/ldl/Source/ldl.c
new file mode 100644
index 00000000000..a9b35c846ef
--- /dev/null
+++ b/extern/libmv/third_party/ldl/Source/ldl.c
@@ -0,0 +1,507 @@
+/* ========================================================================== */
+/* === ldl.c: sparse LDL' factorization and solve package =================== */
+/* ========================================================================== */
+
+/* LDL: a simple set of routines for sparse LDL' factorization. These routines
+ * are not terrifically fast (they do not use dense matrix kernels), but the
+ * code is very short. The purpose is to illustrate the algorithms in a very
+ * concise manner, primarily for educational purposes. Although the code is
+ * very concise, this package is slightly faster than the built-in sparse
+ * Cholesky factorization in MATLAB 7.0 (chol), when using the same input
+ * permutation.
+ *
+ * The routines compute the LDL' factorization of a real sparse symmetric
+ * matrix A (or PAP' if a permutation P is supplied), and solve upper
+ * and lower triangular systems with the resulting L and D factors. If A is
+ * positive definite then the factorization will be accurate. A can be
+ * indefinite (with negative values on the diagonal D), but in this case no
+ * guarantee of accuracy is provided, since no numeric pivoting is performed.
+ *
+ * The n-by-n sparse matrix A is in compressed-column form. The nonzero values
+ * in column j are stored in Ax [Ap [j] ... Ap [j+1]-1], with corresponding row
+ * indices in Ai [Ap [j] ... Ap [j+1]-1]. Ap [0] = 0 is required, and thus
+ * nz = Ap [n] is the number of nonzeros in A. Ap is an int array of size n+1.
+ * The int array Ai and the double array Ax are of size nz. This data structure
+ * is identical to the one used by MATLAB, except for the following
+ * generalizations. The row indices in each column of A need not be in any
+ * particular order, although they must be in the range 0 to n-1. Duplicate
+ * entries can be present; any duplicates are summed. That is, if row index i
+ * appears twice in a column j, then the value of A (i,j) is the sum of the two
+ * entries. The data structure used here for the input matrix A is more
+ * flexible than MATLAB's, which requires sorted columns with no duplicate
+ * entries.
+ *
+ * Only the diagonal and upper triangular part of A (or PAP' if a permutation
+ * P is provided) is accessed. The lower triangular parts of the matrix A or
+ * PAP' can be present, but they are ignored.
+ *
+ * The optional input permutation is provided as an array P of length n. If
+ * P [k] = j, the row and column j of A is the kth row and column of PAP'.
+ * If P is present then the factorization is LDL' = PAP' or L*D*L' = A(P,P) in
+ * 0-based MATLAB notation. If P is not present (a null pointer) then no
+ * permutation is performed, and the factorization is LDL' = A.
+ *
+ * The lower triangular matrix L is stored in the same compressed-column
+ * form (an int Lp array of size n+1, an int Li array of size Lp [n], and a
+ * double array Lx of the same size as Li). It has a unit diagonal, which is
+ * not stored. The row indices in each column of L are always returned in
+ * ascending order, with no duplicate entries. This format is compatible with
+ * MATLAB, except that it would be more convenient for MATLAB to include the
+ * unit diagonal of L. Doing so here would add additional complexity to the
+ * code, and is thus omitted in the interest of keeping this code short and
+ * readable.
+ *
+ * The elimination tree is held in the Parent [0..n-1] array. It is normally
+ * not required by the user, but it is required by ldl_numeric. The diagonal
+ * matrix D is held as an array D [0..n-1] of size n.
+ *
+ * --------------------
+ * C-callable routines:
+ * --------------------
+ *
+ * ldl_symbolic: Given the pattern of A, computes the Lp and Parent arrays
+ * required by ldl_numeric. Takes time proportional to the number of
+ * nonzeros in L. Computes the inverse Pinv of P if P is provided.
+ * Also returns Lnz, the count of nonzeros in each column of L below
+ * the diagonal (this is not required by ldl_numeric).
+ * ldl_numeric: Given the pattern and numerical values of A, the Lp array,
+ * the Parent array, and P and Pinv if applicable, computes the
+ * pattern and numerical values of L and D.
+ * ldl_lsolve: Solves Lx=b for a dense vector b.
+ * ldl_dsolve: Solves Dx=b for a dense vector b.
+ * ldl_ltsolve: Solves L'x=b for a dense vector b.
+ * ldl_perm: Computes x=Pb for a dense vector b.
+ * ldl_permt: Computes x=P'b for a dense vector b.
+ * ldl_valid_perm: checks the validity of a permutation vector
+ * ldl_valid_matrix: checks the validity of the sparse matrix A
+ *
+ * ----------------------------
+ * Limitations of this package:
+ * ----------------------------
+ *
+ * In the interest of keeping this code simple and readable, ldl_symbolic and
+ * ldl_numeric assume their inputs are valid. You can check your own inputs
+ * prior to calling these routines with the ldl_valid_perm and ldl_valid_matrix
+ * routines. Except for the two ldl_valid_* routines, no routine checks to see
+ * if the array arguments are present (non-NULL). Like all C routines, no
+ * routine can determine if the arrays are long enough and don't overlap.
+ *
+ * The ldl_numeric does check the numerical factorization, however. It returns
+ * n if the factorization is successful. If D (k,k) is zero, then k is
+ * returned, and L is only partially computed.
+ *
+ * No pivoting to control fill-in is performed, which is often critical for
+ * obtaining good performance. I recommend that you compute the permutation P
+ * using AMD or SYMAMD (approximate minimum degree ordering routines), or an
+ * appropriate graph-partitioning based ordering. See the ldldemo.m routine for
+ * an example in MATLAB, and the ldlmain.c stand-alone C program for examples of
+ * how to find P. Routines for manipulating compressed-column matrices are
+ * available in UMFPACK. AMD, SYMAMD, UMFPACK, and this LDL package are all
+ * available at http://www.cise.ufl.edu/research/sparse.
+ *
+ * -------------------------
+ * Possible simplifications:
+ * -------------------------
+ *
+ * These routines could be made even simpler with a few additional assumptions.
+ * If no input permutation were performed, the caller would have to permute the
+ * matrix first, but the computation of Pinv, and the use of P and Pinv could be
+ * removed. If only the diagonal and upper triangular part of A or PAP' are
+ * present, then the tests in the "if (i < k)" statement in ldl_symbolic and
+ * "if (i <= k)" in ldl_numeric, are always true, and could be removed (i can
+ * equal k in ldl_symbolic, but then the body of the if statement would
+ * correctly do no work since Flag [k] == k). If we could assume that no
+ * duplicate entries are present, then the statement Y [i] += Ax [p] could be
+ * replaced with Y [i] = Ax [p] in ldl_numeric.
+ *
+ * --------------------------
+ * Description of the method:
+ * --------------------------
+ *
+ * LDL computes the symbolic factorization by finding the pattern of L one row
+ * at a time. It does this based on the following theory. Consider a sparse
+ * system Lx=b, where L, x, and b, are all sparse, and where L comes from a
+ * Cholesky (or LDL') factorization. The elimination tree (etree) of L is
+ * defined as follows. The parent of node j is the smallest k > j such that
+ * L (k,j) is nonzero. Node j has no parent if column j of L is completely zero
+ * below the diagonal (j is a root of the etree in this case). The nonzero
+ * pattern of x is the union of the paths from each node i to the root, for
+ * each nonzero b (i). To compute the numerical solution to Lx=b, we can
+ * traverse the columns of L corresponding to nonzero values of x. This
+ * traversal does not need to be done in the order 0 to n-1. It can be done in
+ * any "topological" order, such that x (i) is computed before x (j) if i is a
+ * descendant of j in the elimination tree.
+ *
+ * The row-form of the LDL' factorization is shown in the MATLAB function
+ * ldlrow.m in this LDL package. Note that row k of L is found via a sparse
+ * triangular solve of L (1:k-1, 1:k-1) \ A (1:k-1, k), to use 1-based MATLAB
+ * notation. Thus, we can start with the nonzero pattern of the kth column of
+ * A (above the diagonal), follow the paths up to the root of the etree of the
+ * (k-1)-by-(k-1) leading submatrix of L, and obtain the pattern of the kth row
+ * of L. Note that we only need the leading (k-1)-by-(k-1) submatrix of L to
+ * do this. The elimination tree can be constructed as we go.
+ *
+ * The symbolic factorization does the same thing, except that it discards the
+ * pattern of L as it is computed. It simply counts the number of nonzeros in
+ * each column of L and then constructs the Lp index array when it's done. The
+ * symbolic factorization does not need to do this in topological order.
+ * Compare ldl_symbolic with the first part of ldl_numeric, and note that the
+ * while (len > 0) loop is not present in ldl_symbolic.
+ *
+ * LDL Version 1.3, Copyright (c) 2006 by Timothy A Davis,
+ * University of Florida. All Rights Reserved. Developed while on sabbatical
+ * at Stanford University and Lawrence Berkeley National Laboratory. Refer to
+ * the README file for the License. Available at
+ * http://www.cise.ufl.edu/research/sparse.
+ */
+
+#include "ldl.h"
+
+/* ========================================================================== */
+/* === ldl_symbolic ========================================================= */
+/* ========================================================================== */
+
+/* The input to this routine is a sparse matrix A, stored in column form, and
+ * an optional permutation P. The output is the elimination tree
+ * and the number of nonzeros in each column of L. Parent [i] = k if k is the
+ * parent of i in the tree. The Parent array is required by ldl_numeric.
+ * Lnz [k] gives the number of nonzeros in the kth column of L, excluding the
+ * diagonal.
+ *
+ * One workspace vector (Flag) of size n is required.
+ *
+ * If P is NULL, then it is ignored. The factorization will be LDL' = A.
+ * Pinv is not computed. In this case, neither P nor Pinv are required by
+ * ldl_numeric.
+ *
+ * If P is not NULL, then it is assumed to be a valid permutation. If
+ * row and column j of A is the kth pivot, the P [k] = j. The factorization
+ * will be LDL' = PAP', or A (p,p) in MATLAB notation. The inverse permutation
+ * Pinv is computed, where Pinv [j] = k if P [k] = j. In this case, both P
+ * and Pinv are required as inputs to ldl_numeric.
+ *
+ * The floating-point operation count of the subsequent call to ldl_numeric
+ * is not returned, but could be computed after ldl_symbolic is done. It is
+ * the sum of (Lnz [k]) * (Lnz [k] + 2) for k = 0 to n-1.
+ */
+
+void LDL_symbolic
+(
+ LDL_int n, /* A and L are n-by-n, where n >= 0 */
+ LDL_int Ap [ ], /* input of size n+1, not modified */
+ LDL_int Ai [ ], /* input of size nz=Ap[n], not modified */
+ LDL_int Lp [ ], /* output of size n+1, not defined on input */
+ LDL_int Parent [ ], /* output of size n, not defined on input */
+ LDL_int Lnz [ ], /* output of size n, not defined on input */
+ LDL_int Flag [ ], /* workspace of size n, not defn. on input or output */
+ LDL_int P [ ], /* optional input of size n */
+ LDL_int Pinv [ ] /* optional output of size n (used if P is not NULL) */
+)
+{
+ LDL_int i, k, p, kk, p2 ;
+ if (P)
+ {
+ /* If P is present then compute Pinv, the inverse of P */
+ for (k = 0 ; k < n ; k++)
+ {
+ Pinv [P [k]] = k ;
+ }
+ }
+ for (k = 0 ; k < n ; k++)
+ {
+ /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */
+ Parent [k] = -1 ; /* parent of k is not yet known */
+ Flag [k] = k ; /* mark node k as visited */
+ Lnz [k] = 0 ; /* count of nonzeros in column k of L */
+ kk = (P) ? (P [k]) : (k) ; /* kth original, or permuted, column */
+ p2 = Ap [kk+1] ;
+ for (p = Ap [kk] ; p < p2 ; p++)
+ {
+ /* A (i,k) is nonzero (original or permuted A) */
+ i = (Pinv) ? (Pinv [Ai [p]]) : (Ai [p]) ;
+ if (i < k)
+ {
+ /* follow path from i to root of etree, stop at flagged node */
+ for ( ; Flag [i] != k ; i = Parent [i])
+ {
+ /* find parent of i if not yet determined */
+ if (Parent [i] == -1) Parent [i] = k ;
+ Lnz [i]++ ; /* L (k,i) is nonzero */
+ Flag [i] = k ; /* mark i as visited */
+ }
+ }
+ }
+ }
+ /* construct Lp index array from Lnz column counts */
+ Lp [0] = 0 ;
+ for (k = 0 ; k < n ; k++)
+ {
+ Lp [k+1] = Lp [k] + Lnz [k] ;
+ }
+}
+
+
+/* ========================================================================== */
+/* === ldl_numeric ========================================================== */
+/* ========================================================================== */
+
+/* Given a sparse matrix A (the arguments n, Ap, Ai, and Ax) and its symbolic
+ * analysis (Lp and Parent, and optionally P and Pinv), compute the numeric LDL'
+ * factorization of A or PAP'. The outputs of this routine are arguments Li,
+ * Lx, and D. It also requires three size-n workspaces (Y, Pattern, and Flag).
+ */
+
+LDL_int LDL_numeric /* returns n if successful, k if D (k,k) is zero */
+(
+ LDL_int n, /* A and L are n-by-n, where n >= 0 */
+ LDL_int Ap [ ], /* input of size n+1, not modified */
+ LDL_int Ai [ ], /* input of size nz=Ap[n], not modified */
+ double Ax [ ], /* input of size nz=Ap[n], not modified */
+ LDL_int Lp [ ], /* input of size n+1, not modified */
+ LDL_int Parent [ ], /* input of size n, not modified */
+ LDL_int Lnz [ ], /* output of size n, not defn. on input */
+ LDL_int Li [ ], /* output of size lnz=Lp[n], not defined on input */
+ double Lx [ ], /* output of size lnz=Lp[n], not defined on input */
+ double D [ ], /* output of size n, not defined on input */
+ double Y [ ], /* workspace of size n, not defn. on input or output */
+ LDL_int Pattern [ ],/* workspace of size n, not defn. on input or output */
+ LDL_int Flag [ ], /* workspace of size n, not defn. on input or output */
+ LDL_int P [ ], /* optional input of size n */
+ LDL_int Pinv [ ] /* optional input of size n */
+)
+{
+ double yi, l_ki ;
+ LDL_int i, k, p, kk, p2, len, top ;
+ for (k = 0 ; k < n ; k++)
+ {
+ /* compute nonzero Pattern of kth row of L, in topological order */
+ Y [k] = 0.0 ; /* Y(0:k) is now all zero */
+ top = n ; /* stack for pattern is empty */
+ Flag [k] = k ; /* mark node k as visited */
+ Lnz [k] = 0 ; /* count of nonzeros in column k of L */
+ kk = (P) ? (P [k]) : (k) ; /* kth original, or permuted, column */
+ p2 = Ap [kk+1] ;
+ for (p = Ap [kk] ; p < p2 ; p++)
+ {
+ i = (Pinv) ? (Pinv [Ai [p]]) : (Ai [p]) ; /* get A(i,k) */
+ if (i <= k)
+ {
+ Y [i] += Ax [p] ; /* scatter A(i,k) into Y (sum duplicates) */
+ for (len = 0 ; Flag [i] != k ; i = Parent [i])
+ {
+ Pattern [len++] = i ; /* L(k,i) is nonzero */
+ Flag [i] = k ; /* mark i as visited */
+ }
+ while (len > 0) Pattern [--top] = Pattern [--len] ;
+ }
+ }
+ /* compute numerical values kth row of L (a sparse triangular solve) */
+ D [k] = Y [k] ; /* get D(k,k) and clear Y(k) */
+ Y [k] = 0.0 ;
+ for ( ; top < n ; top++)
+ {
+ i = Pattern [top] ; /* Pattern [top:n-1] is pattern of L(:,k) */
+ yi = Y [i] ; /* get and clear Y(i) */
+ Y [i] = 0.0 ;
+ p2 = Lp [i] + Lnz [i] ;
+ for (p = Lp [i] ; p < p2 ; p++)
+ {
+ Y [Li [p]] -= Lx [p] * yi ;
+ }
+ l_ki = yi / D [i] ; /* the nonzero entry L(k,i) */
+ D [k] -= l_ki * yi ;
+ Li [p] = k ; /* store L(k,i) in column form of L */
+ Lx [p] = l_ki ;
+ Lnz [i]++ ; /* increment count of nonzeros in col i */
+ }
+ if (D [k] == 0.0) return (k) ; /* failure, D(k,k) is zero */
+ }
+ return (n) ; /* success, diagonal of D is all nonzero */
+}
+
+
+/* ========================================================================== */
+/* === ldl_lsolve: solve Lx=b ============================================== */
+/* ========================================================================== */
+
+void LDL_lsolve
+(
+ LDL_int n, /* L is n-by-n, where n >= 0 */
+ double X [ ], /* size n. right-hand-side on input, soln. on output */
+ LDL_int Lp [ ], /* input of size n+1, not modified */
+ LDL_int Li [ ], /* input of size lnz=Lp[n], not modified */
+ double Lx [ ] /* input of size lnz=Lp[n], not modified */
+)
+{
+ LDL_int j, p, p2 ;
+ for (j = 0 ; j < n ; j++)
+ {
+ p2 = Lp [j+1] ;
+ for (p = Lp [j] ; p < p2 ; p++)
+ {
+ X [Li [p]] -= Lx [p] * X [j] ;
+ }
+ }
+}
+
+
+/* ========================================================================== */
+/* === ldl_dsolve: solve Dx=b ============================================== */
+/* ========================================================================== */
+
+void LDL_dsolve
+(
+ LDL_int n, /* D is n-by-n, where n >= 0 */
+ double X [ ], /* size n. right-hand-side on input, soln. on output */
+ double D [ ] /* input of size n, not modified */
+)
+{
+ LDL_int j ;
+ for (j = 0 ; j < n ; j++)
+ {
+ X [j] /= D [j] ;
+ }
+}
+
+
+/* ========================================================================== */
+/* === ldl_ltsolve: solve L'x=b ============================================ */
+/* ========================================================================== */
+
+void LDL_ltsolve
+(
+ LDL_int n, /* L is n-by-n, where n >= 0 */
+ double X [ ], /* size n. right-hand-side on input, soln. on output */
+ LDL_int Lp [ ], /* input of size n+1, not modified */
+ LDL_int Li [ ], /* input of size lnz=Lp[n], not modified */
+ double Lx [ ] /* input of size lnz=Lp[n], not modified */
+)
+{
+ int j, p, p2 ;
+ for (j = n-1 ; j >= 0 ; j--)
+ {
+ p2 = Lp [j+1] ;
+ for (p = Lp [j] ; p < p2 ; p++)
+ {
+ X [j] -= Lx [p] * X [Li [p]] ;
+ }
+ }
+}
+
+
+/* ========================================================================== */
+/* === ldl_perm: permute a vector, x=Pb ===================================== */
+/* ========================================================================== */
+
+void LDL_perm
+(
+ LDL_int n, /* size of X, B, and P */
+ double X [ ], /* output of size n. */
+ double B [ ], /* input of size n. */
+ LDL_int P [ ] /* input permutation array of size n. */
+)
+{
+ LDL_int j ;
+ for (j = 0 ; j < n ; j++)
+ {
+ X [j] = B [P [j]] ;
+ }
+}
+
+
+/* ========================================================================== */
+/* === ldl_permt: permute a vector, x=P'b =================================== */
+/* ========================================================================== */
+
+void LDL_permt
+(
+ LDL_int n, /* size of X, B, and P */
+ double X [ ], /* output of size n. */
+ double B [ ], /* input of size n. */
+ LDL_int P [ ] /* input permutation array of size n. */
+)
+{
+ LDL_int j ;
+ for (j = 0 ; j < n ; j++)
+ {
+ X [P [j]] = B [j] ;
+ }
+}
+
+
+/* ========================================================================== */
+/* === ldl_valid_perm: check if a permutation vector is valid =============== */
+/* ========================================================================== */
+
+LDL_int LDL_valid_perm /* returns 1 if valid, 0 otherwise */
+(
+ LDL_int n,
+ LDL_int P [ ], /* input of size n, a permutation of 0:n-1 */
+ LDL_int Flag [ ] /* workspace of size n */
+)
+{
+ LDL_int j, k ;
+ if (n < 0 || !Flag)
+ {
+ return (0) ; /* n must be >= 0, and Flag must be present */
+ }
+ if (!P)
+ {
+ return (1) ; /* If NULL, P is assumed to be the identity perm. */
+ }
+ for (j = 0 ; j < n ; j++)
+ {
+ Flag [j] = 0 ; /* clear the Flag array */
+ }
+ for (k = 0 ; k < n ; k++)
+ {
+ j = P [k] ;
+ if (j < 0 || j >= n || Flag [j] != 0)
+ {
+ return (0) ; /* P is not valid */
+ }
+ Flag [j] = 1 ;
+ }
+ return (1) ; /* P is valid */
+}
+
+
+/* ========================================================================== */
+/* === ldl_valid_matrix: check if a sparse matrix is valid ================== */
+/* ========================================================================== */
+
+/* This routine checks to see if a sparse matrix A is valid for input to
+ * ldl_symbolic and ldl_numeric. It returns 1 if the matrix is valid, 0
+ * otherwise. A is in sparse column form. The numerical values in column j
+ * are stored in Ax [Ap [j] ... Ap [j+1]-1], with row indices in
+ * Ai [Ap [j] ... Ap [j+1]-1]. The Ax array is not checked.
+ */
+
+LDL_int LDL_valid_matrix
+(
+ LDL_int n,
+ LDL_int Ap [ ],
+ LDL_int Ai [ ]
+)
+{
+ LDL_int j, p ;
+ if (n < 0 || !Ap || !Ai || Ap [0] != 0)
+ {
+ return (0) ; /* n must be >= 0, and Ap and Ai must be present */
+ }
+ for (j = 0 ; j < n ; j++)
+ {
+ if (Ap [j] > Ap [j+1])
+ {
+ return (0) ; /* Ap must be monotonically nondecreasing */
+ }
+ }
+ for (p = 0 ; p < Ap [n] ; p++)
+ {
+ if (Ai [p] < 0 || Ai [p] >= n)
+ {
+ return (0) ; /* row indices must be in the range 0 to n-1 */
+ }
+ }
+ return (1) ; /* matrix is valid */
+}
diff --git a/extern/libmv/third_party/msinttypes/README.libmv b/extern/libmv/third_party/msinttypes/README.libmv
new file mode 100644
index 00000000000..423f599b4ad
--- /dev/null
+++ b/extern/libmv/third_party/msinttypes/README.libmv
@@ -0,0 +1,5 @@
+Project: msinttypes
+URL: http://code.google.com/p/msinttypes/
+License: New BSD License
+Upstream version: r24
+Local modifications: None.
diff --git a/extern/libmv/third_party/msinttypes/inttypes.h b/extern/libmv/third_party/msinttypes/inttypes.h
new file mode 100644
index 00000000000..0e8af69cb07
--- /dev/null
+++ b/extern/libmv/third_party/msinttypes/inttypes.h
@@ -0,0 +1,305 @@
+// ISO C9x compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <stdint.h>
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIdLEAST8 "d"
+#define PRIiLEAST8 "i"
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+
+#define PRId16 "hd"
+#define PRIi16 "hi"
+#define PRIdLEAST16 "hd"
+#define PRIiLEAST16 "hi"
+#define PRIdFAST16 "hd"
+#define PRIiFAST16 "hi"
+
+#define PRId32 "I32d"
+#define PRIi32 "I32i"
+#define PRIdLEAST32 "I32d"
+#define PRIiLEAST32 "I32i"
+#define PRIdFAST32 "I32d"
+#define PRIiFAST32 "I32i"
+
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIdLEAST64 "I64d"
+#define PRIiLEAST64 "I64i"
+#define PRIdFAST64 "I64d"
+#define PRIiFAST64 "I64i"
+
+#define PRIdMAX "I64d"
+#define PRIiMAX "I64i"
+
+#define PRIdPTR "Id"
+#define PRIiPTR "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRIoLEAST8 "o"
+#define PRIuLEAST8 "u"
+#define PRIxLEAST8 "x"
+#define PRIXLEAST8 "X"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+
+#define PRIo16 "ho"
+#define PRIu16 "hu"
+#define PRIx16 "hx"
+#define PRIX16 "hX"
+#define PRIoLEAST16 "ho"
+#define PRIuLEAST16 "hu"
+#define PRIxLEAST16 "hx"
+#define PRIXLEAST16 "hX"
+#define PRIoFAST16 "ho"
+#define PRIuFAST16 "hu"
+#define PRIxFAST16 "hx"
+#define PRIXFAST16 "hX"
+
+#define PRIo32 "I32o"
+#define PRIu32 "I32u"
+#define PRIx32 "I32x"
+#define PRIX32 "I32X"
+#define PRIoLEAST32 "I32o"
+#define PRIuLEAST32 "I32u"
+#define PRIxLEAST32 "I32x"
+#define PRIXLEAST32 "I32X"
+#define PRIoFAST32 "I32o"
+#define PRIuFAST32 "I32u"
+#define PRIxFAST32 "I32x"
+#define PRIXFAST32 "I32X"
+
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#define PRIoLEAST64 "I64o"
+#define PRIuLEAST64 "I64u"
+#define PRIxLEAST64 "I64x"
+#define PRIXLEAST64 "I64X"
+#define PRIoFAST64 "I64o"
+#define PRIuFAST64 "I64u"
+#define PRIxFAST64 "I64x"
+#define PRIXFAST64 "I64X"
+
+#define PRIoMAX "I64o"
+#define PRIuMAX "I64u"
+#define PRIxMAX "I64x"
+#define PRIXMAX "I64X"
+
+#define PRIoPTR "Io"
+#define PRIuPTR "Iu"
+#define PRIxPTR "Ix"
+#define PRIXPTR "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8 "d"
+#define SCNi8 "i"
+#define SCNdLEAST8 "d"
+#define SCNiLEAST8 "i"
+#define SCNdFAST8 "d"
+#define SCNiFAST8 "i"
+
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNdLEAST16 "hd"
+#define SCNiLEAST16 "hi"
+#define SCNdFAST16 "hd"
+#define SCNiFAST16 "hi"
+
+#define SCNd32 "ld"
+#define SCNi32 "li"
+#define SCNdLEAST32 "ld"
+#define SCNiLEAST32 "li"
+#define SCNdFAST32 "ld"
+#define SCNiFAST32 "li"
+
+#define SCNd64 "I64d"
+#define SCNi64 "I64i"
+#define SCNdLEAST64 "I64d"
+#define SCNiLEAST64 "I64i"
+#define SCNdFAST64 "I64d"
+#define SCNiFAST64 "I64i"
+
+#define SCNdMAX "I64d"
+#define SCNiMAX "I64i"
+
+#ifdef _WIN64 // [
+# define SCNdPTR "I64d"
+# define SCNiPTR "I64i"
+#else // _WIN64 ][
+# define SCNdPTR "ld"
+# define SCNiPTR "li"
+#endif // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8 "o"
+#define SCNu8 "u"
+#define SCNx8 "x"
+#define SCNX8 "X"
+#define SCNoLEAST8 "o"
+#define SCNuLEAST8 "u"
+#define SCNxLEAST8 "x"
+#define SCNXLEAST8 "X"
+#define SCNoFAST8 "o"
+#define SCNuFAST8 "u"
+#define SCNxFAST8 "x"
+#define SCNXFAST8 "X"
+
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNX16 "hX"
+#define SCNoLEAST16 "ho"
+#define SCNuLEAST16 "hu"
+#define SCNxLEAST16 "hx"
+#define SCNXLEAST16 "hX"
+#define SCNoFAST16 "ho"
+#define SCNuFAST16 "hu"
+#define SCNxFAST16 "hx"
+#define SCNXFAST16 "hX"
+
+#define SCNo32 "lo"
+#define SCNu32 "lu"
+#define SCNx32 "lx"
+#define SCNX32 "lX"
+#define SCNoLEAST32 "lo"
+#define SCNuLEAST32 "lu"
+#define SCNxLEAST32 "lx"
+#define SCNXLEAST32 "lX"
+#define SCNoFAST32 "lo"
+#define SCNuFAST32 "lu"
+#define SCNxFAST32 "lx"
+#define SCNXFAST32 "lX"
+
+#define SCNo64 "I64o"
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#define SCNX64 "I64X"
+#define SCNoLEAST64 "I64o"
+#define SCNuLEAST64 "I64u"
+#define SCNxLEAST64 "I64x"
+#define SCNXLEAST64 "I64X"
+#define SCNoFAST64 "I64o"
+#define SCNuFAST64 "I64u"
+#define SCNxFAST64 "I64x"
+#define SCNXFAST64 "I64X"
+
+#define SCNoMAX "I64o"
+#define SCNuMAX "I64u"
+#define SCNxMAX "I64x"
+#define SCNXMAX "I64X"
+
+#ifdef _WIN64 // [
+# define SCNoPTR "I64o"
+# define SCNuPTR "I64u"
+# define SCNxPTR "I64x"
+# define SCNXPTR "I64X"
+#else // _WIN64 ][
+# define SCNoPTR "lo"
+# define SCNuPTR "lu"
+# define SCNxPTR "lx"
+# define SCNXPTR "lX"
+#endif // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+ imaxdiv_t result;
+
+ result.quot = numer / denom;
+ result.rem = numer % denom;
+
+ if (numer < 0 && result.rem > 0) {
+ // did division wrong; must fix up
+ ++result.quot;
+ result.rem -= denom;
+ }
+
+ return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/extern/libmv/third_party/msinttypes/stdint.h b/extern/libmv/third_party/msinttypes/stdint.h
new file mode 100644
index 00000000000..e236bb00015
--- /dev/null
+++ b/extern/libmv/third_party/msinttypes/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef char int8_t;
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __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;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/extern/libmv/third_party/ssba/COPYING.TXT b/extern/libmv/third_party/ssba/COPYING.TXT
new file mode 100644
index 00000000000..fc8a5de7edf
--- /dev/null
+++ b/extern/libmv/third_party/ssba/COPYING.TXT
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h b/extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h
new file mode 100644
index 00000000000..448ae9714e5
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h
@@ -0,0 +1,204 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_CAMERA_MATRIX_H
+#define V3D_CAMERA_MATRIX_H
+
+#include "Math/v3d_linear.h"
+#include "Geometry/v3d_distortion.h"
+
+namespace V3D
+{
+
+ struct CameraMatrix
+ {
+ CameraMatrix()
+ {
+ makeIdentityMatrix(_K);
+ makeIdentityMatrix(_R);
+ makeZeroVector(_T);
+ this->updateCachedValues(true, true);
+ }
+
+ CameraMatrix(double f, double cx, double cy)
+ {
+ makeIdentityMatrix(_K);
+ _K[0][0] = f;
+ _K[1][1] = f;
+ _K[0][2] = cx;
+ _K[1][2] = cy;
+ makeIdentityMatrix(_R);
+ makeZeroVector(_T);
+ this->updateCachedValues(true, true);
+ }
+
+ CameraMatrix(Matrix3x3d const& K,
+ Matrix3x3d const& R,
+ Vector3d const& T)
+ : _K(K), _R(R), _T(T)
+ {
+ this->updateCachedValues(true, true);
+ }
+
+ void setIntrinsic(Matrix3x3d const& K) { _K = K; this->updateCachedValues(true, false); }
+ void setRotation(Matrix3x3d const& R) { _R = R; this->updateCachedValues(false, true); }
+ void setTranslation(Vector3d const& T) { _T = T; this->updateCachedValues(false, true); }
+
+ template <typename Mat>
+ void setOrientation(Mat const& RT)
+ {
+ _R[0][0] = RT[0][0]; _R[0][1] = RT[0][1]; _R[0][2] = RT[0][2];
+ _R[1][0] = RT[1][0]; _R[1][1] = RT[1][1]; _R[1][2] = RT[1][2];
+ _R[2][0] = RT[2][0]; _R[2][1] = RT[2][1]; _R[2][2] = RT[2][2];
+ _T[0] = RT[0][3]; _T[1] = RT[1][3]; _T[2] = RT[2][3];
+ this->updateCachedValues(false, true);
+ }
+
+ Matrix3x3d const& getIntrinsic() const { return _K; }
+ Matrix3x3d const& getRotation() const { return _R; }
+ Vector3d const& getTranslation() const { return _T; }
+
+ Matrix3x4d getOrientation() const
+ {
+ Matrix3x4d RT;
+ RT[0][0] = _R[0][0]; RT[0][1] = _R[0][1]; RT[0][2] = _R[0][2];
+ RT[1][0] = _R[1][0]; RT[1][1] = _R[1][1]; RT[1][2] = _R[1][2];
+ RT[2][0] = _R[2][0]; RT[2][1] = _R[2][1]; RT[2][2] = _R[2][2];
+ RT[0][3] = _T[0]; RT[1][3] = _T[1]; RT[2][3] = _T[2];
+ return RT;
+ }
+
+ Matrix3x4d getProjection() const
+ {
+ Matrix3x4d const RT = this->getOrientation();
+ return _K * RT;
+ }
+
+ double getFocalLength() const { return _K[0][0]; }
+ double getAspectRatio() const { return _K[1][1] / _K[0][0]; }
+
+ Vector2d getPrincipalPoint() const
+ {
+ Vector2d pp;
+ pp[0] = _K[0][2];
+ pp[1] = _K[1][2];
+ return pp;
+ }
+
+ Vector2d projectPoint(Vector3d const& X) const
+ {
+ Vector3d q = _K*(_R*X + _T);
+ Vector2d res;
+ res[0] = q[0]/q[2]; res[1] = q[1]/q[2];
+ return res;
+ }
+
+ template <typename Distortion>
+ Vector2d projectPoint(Distortion const& distortion, Vector3d const& X) const
+ {
+ Vector3d XX = _R*X + _T;
+ Vector2d p;
+ p[0] = XX[0] / XX[2];
+ p[1] = XX[1] / XX[2];
+ p = distortion(p);
+
+ Vector2d res;
+ res[0] = _K[0][0] * p[0] + _K[0][1] * p[1] + _K[0][2];
+ res[1] = _K[1][1] * p[1] + _K[1][2];
+ return res;
+ }
+
+ Vector3d unprojectPixel(Vector2d const &p, double depth = 1) const
+ {
+ Vector3d pp;
+ pp[0] = p[0]; pp[1] = p[1]; pp[2] = 1.0;
+ Vector3d ray = _invK * pp;
+ ray[0] *= depth/ray[2];
+ ray[1] *= depth/ray[2];
+ ray[2] = depth;
+ ray = _Rt * ray;
+ return _center + ray;
+ }
+
+ Vector3d transformPointIntoCameraSpace(Vector3d const& p) const
+ {
+ return _R*p + _T;
+ }
+
+ Vector3d transformPointFromCameraSpace(Vector3d const& p) const
+ {
+ return _Rt*(p-_T);
+ }
+
+ Vector3d transformDirectionFromCameraSpace(Vector3d const& dir) const
+ {
+ return _Rt*dir;
+ }
+
+ Vector3d const& cameraCenter() const
+ {
+ return _center;
+ }
+
+ Vector3d opticalAxis() const
+ {
+ return this->transformDirectionFromCameraSpace(makeVector3(0.0, 0.0, 1.0));
+ }
+
+ Vector3d upVector() const
+ {
+ return this->transformDirectionFromCameraSpace(makeVector3(0.0, 1.0, 0.0));
+ }
+
+ Vector3d rightVector() const
+ {
+ return this->transformDirectionFromCameraSpace(makeVector3(1.0, 0.0, 0.0));
+ }
+
+ Vector3d getRay(Vector2d const& p) const
+ {
+ Vector3d pp = makeVector3(p[0], p[1], 1.0);
+ Vector3d ray = _invK * pp;
+ ray = _Rt * ray;
+ normalizeVector(ray);
+ return ray;
+ }
+
+ protected:
+ void updateCachedValues(bool intrinsic, bool orientation)
+ {
+ if (intrinsic) _invK = invertedMatrix(_K);
+
+ if (orientation)
+ {
+ makeTransposedMatrix(_R, _Rt);
+ _center = _Rt * (-1.0 * _T);
+ }
+ }
+
+ Matrix3x3d _K, _R;
+ Vector3d _T;
+ Matrix3x3d _invK, _Rt;
+ Vector3d _center;
+ }; // end struct CameraMatrix
+
+} // end namespace V3D
+
+#endif
diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_distortion.h b/extern/libmv/third_party/ssba/Geometry/v3d_distortion.h
new file mode 100644
index 00000000000..d0816558314
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Geometry/v3d_distortion.h
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_DISTORTION_H
+#define V3D_DISTORTION_H
+
+#include "Math/v3d_linear.h"
+#include "Math/v3d_linear_utils.h"
+
+namespace V3D
+{
+
+ struct StdDistortionFunction
+ {
+ double k1, k2, p1, p2;
+
+ StdDistortionFunction()
+ : k1(0), k2(0), p1(0), p2(0)
+ { }
+
+ Vector2d operator()(Vector2d const& xu) const
+ {
+ double const r2 = xu[0]*xu[0] + xu[1]*xu[1];
+ double const r4 = r2*r2;
+ double const kr = 1 + k1*r2 + k2*r4;
+
+ Vector2d xd;
+ xd[0] = kr * xu[0] + 2*p1*xu[0]*xu[1] + p2*(r2 + 2*xu[0]*xu[0]);
+ xd[1] = kr * xu[1] + 2*p2*xu[0]*xu[1] + p1*(r2 + 2*xu[1]*xu[1]);
+ return xd;
+ }
+
+ Matrix2x2d derivativeWrtRadialParameters(Vector2d const& xu) const
+ {
+ double const r2 = xu[0]*xu[0] + xu[1]*xu[1];
+ double const r4 = r2*r2;
+ //double const kr = 1 + k1*r2 + k2*r4;
+
+ Matrix2x2d deriv;
+
+ deriv[0][0] = xu[0] * r2; // d xd/d k1
+ deriv[0][1] = xu[0] * r4; // d xd/d k2
+ deriv[1][0] = xu[1] * r2; // d yd/d k1
+ deriv[1][1] = xu[1] * r4; // d yd/d k2
+ return deriv;
+ }
+
+ Matrix2x2d derivativeWrtTangentialParameters(Vector2d const& xu) const
+ {
+ double const r2 = xu[0]*xu[0] + xu[1]*xu[1];
+ //double const r4 = r2*r2;
+ //double const kr = 1 + k1*r2 + k2*r4;
+
+ Matrix2x2d deriv;
+ deriv[0][0] = 2*xu[0]*xu[1]; // d xd/d p1
+ deriv[0][1] = r2 + 2*xu[0]*xu[0]; // d xd/d p2
+ deriv[1][0] = r2 + 2*xu[1]*xu[1]; // d yd/d p1
+ deriv[1][1] = deriv[0][0]; // d yd/d p2
+ return deriv;
+ }
+
+ Matrix2x2d derivativeWrtUndistortedPoint(Vector2d const& xu) const
+ {
+ double const r2 = xu[0]*xu[0] + xu[1]*xu[1];
+ double const r4 = r2*r2;
+ double const kr = 1 + k1*r2 + k2*r4;
+ double const dkr = 2*k1 + 4*k2*r2;
+
+ Matrix2x2d deriv;
+ deriv[0][0] = kr + xu[0] * xu[0] * dkr + 2*p1*xu[1] + 6*p2*xu[0]; // d xd/d xu
+ deriv[0][1] = xu[0] * xu[1] * dkr + 2*p1*xu[0] + 2*p2*xu[1]; // d xd/d yu
+ deriv[1][0] = deriv[0][1]; // d yd/d xu
+ deriv[1][1] = kr + xu[1] * xu[1] * dkr + 6*p1*xu[1] + 2*p2*xu[0]; // d yd/d yu
+ return deriv;
+ }
+ }; // end struct StdDistortionFunction
+
+} // end namespace V3D
+
+#endif
diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp
new file mode 100644
index 00000000000..1c1f0cb2627
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp
@@ -0,0 +1,365 @@
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Geometry/v3d_metricbundle.h"
+
+#if defined(V3DLIB_ENABLE_SUITESPARSE)
+
+namespace
+{
+
+ typedef V3D::InlineMatrix<double, 2, 4> Matrix2x4d;
+ typedef V3D::InlineMatrix<double, 4, 2> Matrix4x2d;
+ typedef V3D::InlineMatrix<double, 2, 6> Matrix2x6d;
+
+} // end namespace <>
+
+namespace V3D
+{
+
+ void
+ MetricBundleOptimizerBase::updateParametersA(VectorArray<double> const& deltaAi)
+ {
+ Vector3d T, omega;
+ Matrix3x3d R0, dR;
+
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ {
+ T = _cams[i].getTranslation();
+ T[0] += deltaAi[i][0];
+ T[1] += deltaAi[i][1];
+ T[2] += deltaAi[i][2];
+ _cams[i].setTranslation(T);
+
+ // Create incremental rotation using Rodriguez formula.
+ R0 = _cams[i].getRotation();
+ omega[0] = deltaAi[i][3];
+ omega[1] = deltaAi[i][4];
+ omega[2] = deltaAi[i][5];
+ createRotationMatrixRodriguez(omega, dR);
+ _cams[i].setRotation(dR * R0);
+ } // end for (i)
+ } // end MetricBundleOptimizerBase::updateParametersA()
+
+ void
+ MetricBundleOptimizerBase::updateParametersB(VectorArray<double> const& deltaBj)
+ {
+ for (int j = _nNonvaryingB; j < _nParametersB; ++j)
+ {
+ _Xs[j][0] += deltaBj[j][0];
+ _Xs[j][1] += deltaBj[j][1];
+ _Xs[j][2] += deltaBj[j][2];
+ }
+ } // end MetricBundleOptimizerBase::updateParametersB()
+
+ void
+ MetricBundleOptimizerBase::poseDerivatives(int i, int j, Vector3d& XX,
+ Matrix3x6d& d_dRT, Matrix3x3d& d_dX) const
+ {
+ XX = _cams[i].transformPointIntoCameraSpace(_Xs[j]);
+
+ // See Frank Dellaerts bundle adjustment tutorial.
+ // d(dR * R0 * X + t)/d omega = -[R0 * X]_x
+ Matrix3x3d J;
+ makeCrossProductMatrix(XX - _cams[i].getTranslation(), J);
+ scaleMatrixIP(-1.0, J);
+
+ // Now the transformation from world coords into camera space is xx = Rx + T
+ // Hence the derivative of x wrt. T is just the identity matrix.
+ makeIdentityMatrix(d_dRT);
+ copyMatrixSlice(J, 0, 0, 3, 3, d_dRT, 0, 3);
+
+ // The derivative of Rx+T wrt x is just R.
+ copyMatrix(_cams[i].getRotation(), d_dX);
+ } // end MetricBundleOptimizerBase::poseDerivatives()
+
+
+//----------------------------------------------------------------------
+
+ void
+ StdMetricBundleOptimizer::fillJacobians(Matrix<double>& Ak,
+ Matrix<double>& Bk,
+ Matrix<double>& Ck,
+ int i, int j, int k)
+ {
+ Vector3d XX;
+ Matrix3x6d d_dRT;
+ Matrix3x3d d_dX;
+ this->poseDerivatives(i, j, XX, d_dRT, d_dX);
+
+ double const f = _cams[i].getFocalLength();
+ double const ar = _cams[i].getAspectRatio();
+
+ Matrix2x3d dp_dX;
+ double const bx = f / (XX[2] * XX[2]);
+ double const by = ar * bx;
+ dp_dX[0][0] = bx * XX[2]; dp_dX[0][1] = 0; dp_dX[0][2] = -bx * XX[0];
+ dp_dX[1][0] = 0; dp_dX[1][1] = by * XX[2]; dp_dX[1][2] = -by * XX[1];
+
+ multiply_A_B(dp_dX, d_dRT, Ak);
+ multiply_A_B(dp_dX, d_dX, Bk);
+ } // end StdMetricBundleOptimizer::fillJacobians()
+
+ //----------------------------------------------------------------------
+
+ void
+ CommonInternalsMetricBundleOptimizer::fillJacobians(Matrix<double>& Ak,
+ Matrix<double>& Bk,
+ Matrix<double>& Ck,
+ int i, int j, int k)
+ {
+ double const focalLength = _K[0][0];
+
+ Vector3d XX;
+ Matrix3x6d dXX_dRT;
+ Matrix3x3d dXX_dX;
+ this->poseDerivatives(i, j, XX, dXX_dRT, dXX_dX);
+
+ Vector2d xu; // undistorted image point
+ xu[0] = XX[0] / XX[2];
+ xu[1] = XX[1] / XX[2];
+
+ Vector2d const xd = _distortion(xu); // distorted image point
+
+ Matrix2x2d dp_dxd;
+ dp_dxd[0][0] = focalLength; dp_dxd[0][1] = 0;
+ dp_dxd[1][0] = 0; dp_dxd[1][1] = _cachedAspectRatio * focalLength;
+
+ {
+ // First, lets do the derivative wrt the structure and motion parameters.
+ Matrix2x3d dxu_dXX;
+ dxu_dXX[0][0] = 1.0f / XX[2]; dxu_dXX[0][1] = 0; dxu_dXX[0][2] = -XX[0]/(XX[2]*XX[2]);
+ dxu_dXX[1][0] = 0; dxu_dXX[1][1] = 1.0f / XX[2]; dxu_dXX[1][2] = -XX[1]/(XX[2]*XX[2]);
+
+ Matrix2x2d dxd_dxu = _distortion.derivativeWrtUndistortedPoint(xu);
+
+ Matrix2x2d dp_dxu = dp_dxd * dxd_dxu;
+ Matrix2x3d dp_dXX = dp_dxu * dxu_dXX;
+
+ multiply_A_B(dp_dXX, dXX_dRT, Ak);
+ multiply_A_B(dp_dXX, dXX_dX, Bk);
+ } // end scope
+
+ switch (_mode)
+ {
+ case FULL_BUNDLE_RADIAL_TANGENTIAL:
+ {
+ Matrix2x2d dxd_dp1p2 = _distortion.derivativeWrtTangentialParameters(xu);
+ Matrix2x2d d_dp1p2 = dp_dxd * dxd_dp1p2;
+ copyMatrixSlice(d_dp1p2, 0, 0, 2, 2, Ck, 0, 5);
+ // No break here!
+ }
+ case FULL_BUNDLE_RADIAL:
+ {
+ Matrix2x2d dxd_dk1k2 = _distortion.derivativeWrtRadialParameters(xu);
+ Matrix2x2d d_dk1k2 = dp_dxd * dxd_dk1k2;
+ copyMatrixSlice(d_dk1k2, 0, 0, 2, 2, Ck, 0, 3);
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH_PP:
+ {
+ Ck[0][1] = 1; Ck[0][2] = 0;
+ Ck[1][1] = 0; Ck[1][2] = 1;
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH:
+ {
+ Ck[0][0] = xd[0];
+ Ck[1][0] = xd[1];
+ }
+ case FULL_BUNDLE_METRIC:
+ {
+ }
+ } // end switch
+ } // end CommonInternalsMetricBundleOptimizer::fillJacobians()
+
+ void
+ CommonInternalsMetricBundleOptimizer::updateParametersC(Vector<double> const& deltaC)
+ {
+ switch (_mode)
+ {
+ case FULL_BUNDLE_RADIAL_TANGENTIAL:
+ {
+ _distortion.p1 += deltaC[5];
+ _distortion.p2 += deltaC[6];
+ // No break here!
+ }
+ case FULL_BUNDLE_RADIAL:
+ {
+ _distortion.k1 += deltaC[3];
+ _distortion.k2 += deltaC[4];
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH_PP:
+ {
+ _K[0][2] += deltaC[1];
+ _K[1][2] += deltaC[2];
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH:
+ {
+ _K[0][0] += deltaC[0];
+ _K[1][1] = _cachedAspectRatio * _K[0][0];
+ }
+ case FULL_BUNDLE_METRIC:
+ {
+ }
+ } // end switch
+ } // end CommonInternalsMetricBundleOptimizer::updateParametersC()
+
+ //----------------------------------------------------------------------
+
+ void
+ VaryingInternalsMetricBundleOptimizer::fillJacobians(Matrix<double>& Ak,
+ Matrix<double>& Bk,
+ Matrix<double>& Ck,
+ int i, int j, int k)
+ {
+ Vector3d XX;
+ Matrix3x6d dXX_dRT;
+ Matrix3x3d dXX_dX;
+ this->poseDerivatives(i, j, XX, dXX_dRT, dXX_dX);
+
+ Vector2d xu; // undistorted image point
+ xu[0] = XX[0] / XX[2];
+ xu[1] = XX[1] / XX[2];
+
+ Vector2d const xd = _distortions[i](xu); // distorted image point
+
+ double const focalLength = _cams[i].getFocalLength();
+ double const aspectRatio = _cams[i].getAspectRatio();
+
+ Matrix2x2d dp_dxd;
+ dp_dxd[0][0] = focalLength; dp_dxd[0][1] = 0;
+ dp_dxd[1][0] = 0; dp_dxd[1][1] = aspectRatio * focalLength;
+
+ {
+ // First, lets do the derivative wrt the structure and motion parameters.
+ Matrix2x3d dxu_dXX;
+ dxu_dXX[0][0] = 1.0f / XX[2]; dxu_dXX[0][1] = 0; dxu_dXX[0][2] = -XX[0]/(XX[2]*XX[2]);
+ dxu_dXX[1][0] = 0; dxu_dXX[1][1] = 1.0f / XX[2]; dxu_dXX[1][2] = -XX[1]/(XX[2]*XX[2]);
+
+ Matrix2x2d dxd_dxu = _distortions[i].derivativeWrtUndistortedPoint(xu);
+
+ Matrix2x2d dp_dxu = dp_dxd * dxd_dxu;
+ Matrix2x3d dp_dXX = dp_dxu * dxu_dXX;
+
+ Matrix2x6d dp_dRT;
+
+ multiply_A_B(dp_dXX, dXX_dRT, dp_dRT);
+ copyMatrixSlice(dp_dRT, 0, 0, 2, 6, Ak, 0, 0);
+ multiply_A_B(dp_dXX, dXX_dX, Bk);
+ } // end scope
+
+ switch (_mode)
+ {
+ case FULL_BUNDLE_RADIAL_TANGENTIAL:
+ {
+ Matrix2x2d dxd_dp1p2 = _distortions[i].derivativeWrtTangentialParameters(xu);
+ Matrix2x2d d_dp1p2 = dp_dxd * dxd_dp1p2;
+ copyMatrixSlice(d_dp1p2, 0, 0, 2, 2, Ak, 0, 11);
+ // No break here!
+ }
+ case FULL_BUNDLE_RADIAL:
+ {
+ Matrix2x2d dxd_dk1k2 = _distortions[i].derivativeWrtRadialParameters(xu);
+ Matrix2x2d d_dk1k2 = dp_dxd * dxd_dk1k2;
+ copyMatrixSlice(d_dk1k2, 0, 0, 2, 2, Ak, 0, 9);
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH_PP:
+ {
+ Ak[0][7] = 1; Ak[0][8] = 0;
+ Ak[1][7] = 0; Ak[1][8] = 1;
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH:
+ {
+ Ak[0][6] = xd[0];
+ Ak[1][6] = xd[1];
+ }
+ case FULL_BUNDLE_METRIC:
+ {
+ }
+ } // end switch
+ } // end VaryingInternalsMetricBundleOptimizer::fillJacobians()
+
+ void
+ VaryingInternalsMetricBundleOptimizer::updateParametersA(VectorArray<double> const& deltaAi)
+ {
+ Vector3d T, omega;
+ Matrix3x3d R0, dR, K;
+
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ {
+ Vector<double> const& deltaA = deltaAi[i];
+
+ T = _cams[i].getTranslation();
+ T[0] += deltaA[0];
+ T[1] += deltaA[1];
+ T[2] += deltaA[2];
+ _cams[i].setTranslation(T);
+
+ // Create incremental rotation using Rodriguez formula.
+ R0 = _cams[i].getRotation();
+ omega[0] = deltaA[3];
+ omega[1] = deltaA[4];
+ omega[2] = deltaA[5];
+ createRotationMatrixRodriguez(omega, dR);
+ _cams[i].setRotation(dR * R0);
+
+ K = _cams[i].getIntrinsic();
+
+ switch (_mode)
+ {
+ case FULL_BUNDLE_RADIAL_TANGENTIAL:
+ {
+ _distortions[i].p1 += deltaA[11];
+ _distortions[i].p2 += deltaA[12];
+ // No break here!
+ }
+ case FULL_BUNDLE_RADIAL:
+ {
+ _distortions[i].k1 += deltaA[9];
+ _distortions[i].k2 += deltaA[10];
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH_PP:
+ {
+ K[0][2] += deltaA[7];
+ K[1][2] += deltaA[8];
+ // No break here!
+ }
+ case FULL_BUNDLE_FOCAL_LENGTH:
+ {
+ double const ar = K[1][1] / K[0][0];
+ K[0][0] += deltaA[6];
+ K[1][1] = ar * K[0][0];
+ }
+ case FULL_BUNDLE_METRIC:
+ {
+ }
+ } // end switch
+ _cams[i].setIntrinsic(K);
+ } // end for (i)
+ } // end VaryingInternalsMetricBundleOptimizer::updateParametersC()
+
+} // end namespace V3D
+
+#endif // defined(V3DLIB_ENABLE_SUITESPARSE)
diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h
new file mode 100644
index 00000000000..076a9e64346
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h
@@ -0,0 +1,346 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_METRICBUNDLE_H
+#define V3D_METRICBUNDLE_H
+
+# if defined(V3DLIB_ENABLE_SUITESPARSE)
+
+#include "Math/v3d_optimization.h"
+#include "Math/v3d_linear.h"
+#include "Math/v3d_linear_utils.h"
+#include "Geometry/v3d_cameramatrix.h"
+#include "Geometry/v3d_distortion.h"
+
+namespace V3D
+{
+
+ // This structure provides some helper functions common to all metric BAs
+ struct MetricBundleOptimizerBase : public SparseLevenbergOptimizer
+ {
+ typedef SparseLevenbergOptimizer Base;
+
+ MetricBundleOptimizerBase(double inlierThreshold,
+ vector<CameraMatrix>& cams,
+ vector<Vector3d >& Xs,
+ vector<Vector2d > const& measurements,
+ vector<int> const& corrspondingView,
+ vector<int> const& corrspondingPoint,
+ int nAddParamsA, int nParamsC)
+ : SparseLevenbergOptimizer(2, cams.size(), 6+nAddParamsA, Xs.size(), 3, nParamsC,
+ corrspondingView, corrspondingPoint),
+ _cams(cams), _Xs(Xs), _measurements(measurements),
+ _savedTranslations(cams.size()), _savedRotations(cams.size()),
+ _savedXs(Xs.size()),
+ _inlierThreshold(inlierThreshold), _cachedParamLength(0.0)
+ {
+ // Since we assume that BA does not alter the inputs too much,
+ // we compute the overall length of the parameter vector in advance
+ // and return that value as the result of getParameterLength().
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ {
+ _cachedParamLength += sqrNorm_L2(_cams[i].getTranslation());
+ _cachedParamLength += 3.0; // Assume eye(3) for R.
+ }
+ for (int j = _nNonvaryingB; j < _nParametersB; ++j)
+ _cachedParamLength += sqrNorm_L2(_Xs[j]);
+
+ _cachedParamLength = sqrt(_cachedParamLength);
+ }
+
+ // Huber robust cost function.
+ virtual void fillWeights(VectorArray<double> const& residual, Vector<double>& w)
+ {
+ for (unsigned int k = 0; k < w.size(); ++k)
+ {
+ Vector<double> const& r = residual[k];
+ double const e = norm_L2(r);
+ w[k] = (e < _inlierThreshold) ? 1.0 : sqrt(_inlierThreshold / e);
+ } // end for (k)
+ }
+
+ virtual double getParameterLength() const
+ {
+ return _cachedParamLength;
+ }
+
+ virtual void updateParametersA(VectorArray<double> const& deltaAi);
+ virtual void updateParametersB(VectorArray<double> const& deltaBj);
+ virtual void updateParametersC(Vector<double> const& deltaC)
+ {
+ (void)deltaC;
+ }
+
+ virtual void saveAllParameters()
+ {
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ {
+ _savedTranslations[i] = _cams[i].getTranslation();
+ _savedRotations[i] = _cams[i].getRotation();
+ }
+ _savedXs = _Xs;
+ }
+
+ virtual void restoreAllParameters()
+ {
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ {
+ _cams[i].setTranslation(_savedTranslations[i]);
+ _cams[i].setRotation(_savedRotations[i]);
+ }
+ _Xs = _savedXs;
+ }
+
+ protected:
+ typedef InlineMatrix<double, 3, 6> Matrix3x6d;
+
+ void poseDerivatives(int i, int j, Vector3d& XX,
+ Matrix3x6d& d_dRT, Matrix3x3d& d_dX) const;
+
+ vector<CameraMatrix>& _cams;
+ vector<Vector3d>& _Xs;
+
+ vector<Vector2d> const& _measurements;
+
+ vector<Vector3d> _savedTranslations;
+ vector<Matrix3x3d> _savedRotations;
+ vector<Vector3d> _savedXs;
+
+ double const _inlierThreshold;
+ double _cachedParamLength;
+ }; // end struct MetricBundleOptimizerBase
+
+ struct StdMetricBundleOptimizer : public MetricBundleOptimizerBase
+ {
+ typedef MetricBundleOptimizerBase Base;
+
+ StdMetricBundleOptimizer(double inlierThreshold,
+ vector<CameraMatrix>& cams,
+ vector<Vector3d >& Xs,
+ vector<Vector2d > const& measurements,
+ vector<int> const& corrspondingView,
+ vector<int> const& corrspondingPoint)
+ : MetricBundleOptimizerBase(inlierThreshold, cams, Xs, measurements,
+ corrspondingView, corrspondingPoint, 0, 0)
+ { }
+
+ virtual void evalResidual(VectorArray<double>& e)
+ {
+ for (unsigned int k = 0; k < e.count(); ++k)
+ {
+ int const i = _correspondingParamA[k];
+ int const j = _correspondingParamB[k];
+
+ Vector2d const q = _cams[i].projectPoint(_Xs[j]);
+ e[k][0] = q[0] - _measurements[k][0];
+ e[k][1] = q[1] - _measurements[k][1];
+ }
+ }
+
+ virtual void fillJacobians(Matrix<double>& Ak, Matrix<double>& Bk, Matrix<double>& Ck,
+ int i, int j, int k);
+ }; // end struct StdMetricBundleOptimizer
+
+//----------------------------------------------------------------------
+
+ enum
+ {
+ FULL_BUNDLE_METRIC = 0,
+ FULL_BUNDLE_FOCAL_LENGTH = 1, // f
+ FULL_BUNDLE_FOCAL_LENGTH_PP = 2, // f, cx, cy
+ FULL_BUNDLE_RADIAL = 3, // f, cx, cy, k1, k2
+ FULL_BUNDLE_RADIAL_TANGENTIAL = 4 // f, cx, cy, k1, k2, p1, p2
+ };
+
+ struct CommonInternalsMetricBundleOptimizer : public MetricBundleOptimizerBase
+ {
+ static int globalParamDimensionFromMode(int mode)
+ {
+ switch (mode)
+ {
+ case FULL_BUNDLE_METRIC: return 0;
+ case FULL_BUNDLE_FOCAL_LENGTH: return 1;
+ case FULL_BUNDLE_FOCAL_LENGTH_PP: return 3;
+ case FULL_BUNDLE_RADIAL: return 5;
+ case FULL_BUNDLE_RADIAL_TANGENTIAL: return 7;
+ }
+ return 0;
+ }
+
+ typedef MetricBundleOptimizerBase Base;
+
+ CommonInternalsMetricBundleOptimizer(int mode,
+ double inlierThreshold,
+ Matrix3x3d& K,
+ StdDistortionFunction& distortion,
+ vector<CameraMatrix>& cams,
+ vector<Vector3d >& Xs,
+ vector<Vector2d > const& measurements,
+ vector<int> const& corrspondingView,
+ vector<int> const& corrspondingPoint)
+ : MetricBundleOptimizerBase(inlierThreshold, cams, Xs, measurements,
+ corrspondingView, corrspondingPoint,
+ 0, globalParamDimensionFromMode(mode)),
+ _mode(mode), _K(K), _distortion(distortion)
+ {
+ _cachedAspectRatio = K[1][1] / K[0][0];
+ }
+
+ Vector2d projectPoint(Vector3d const& X, int i) const
+ {
+ Vector3d const XX = _cams[i].transformPointIntoCameraSpace(X);
+ Vector2d p;
+ p[0] = XX[0] / XX[2];
+ p[1] = XX[1] / XX[2];
+ p = _distortion(p);
+ Vector2d res;
+ res[0] = _K[0][0] * p[0] + _K[0][1] * p[1] + _K[0][2];
+ res[1] = _K[1][1] * p[1] + _K[1][2];
+ return res;
+ }
+
+ virtual void evalResidual(VectorArray<double>& e)
+ {
+ for (unsigned int k = 0; k < e.count(); ++k)
+ {
+ int const i = _correspondingParamA[k];
+ int const j = _correspondingParamB[k];
+
+ Vector2d const q = this->projectPoint(_Xs[j], i);
+ e[k][0] = q[0] - _measurements[k][0];
+ e[k][1] = q[1] - _measurements[k][1];
+ }
+ }
+
+ virtual void fillJacobians(Matrix<double>& Ak, Matrix<double>& Bk, Matrix<double>& Ck,
+ int i, int j, int k);
+
+ virtual void updateParametersC(Vector<double> const& deltaC);
+
+ virtual void saveAllParameters()
+ {
+ Base::saveAllParameters();
+ _savedK = _K;
+ _savedDistortion = _distortion;
+ }
+
+ virtual void restoreAllParameters()
+ {
+ Base::restoreAllParameters();
+ _K = _savedK;
+ _distortion = _savedDistortion;
+ }
+
+ protected:
+ int _mode;
+ Matrix3x3d& _K;
+ StdDistortionFunction& _distortion;
+
+ Matrix3x3d _savedK;
+ StdDistortionFunction _savedDistortion;
+ double _cachedAspectRatio;
+ }; // end struct CommonInternalsMetricBundleOptimizer
+
+//----------------------------------------------------------------------
+
+ struct VaryingInternalsMetricBundleOptimizer : public MetricBundleOptimizerBase
+ {
+ static int extParamDimensionFromMode(int mode)
+ {
+ switch (mode)
+ {
+ case FULL_BUNDLE_METRIC: return 0;
+ case FULL_BUNDLE_FOCAL_LENGTH: return 1;
+ case FULL_BUNDLE_FOCAL_LENGTH_PP: return 3;
+ case FULL_BUNDLE_RADIAL: return 5;
+ case FULL_BUNDLE_RADIAL_TANGENTIAL: return 7;
+ }
+ return 0;
+ }
+
+ typedef MetricBundleOptimizerBase Base;
+
+ VaryingInternalsMetricBundleOptimizer(int mode,
+ double inlierThreshold,
+ std::vector<StdDistortionFunction>& distortions,
+ vector<CameraMatrix>& cams,
+ vector<Vector3d >& Xs,
+ vector<Vector2d > const& measurements,
+ vector<int> const& corrspondingView,
+ vector<int> const& corrspondingPoint)
+ : MetricBundleOptimizerBase(inlierThreshold, cams, Xs, measurements,
+ corrspondingView, corrspondingPoint,
+ extParamDimensionFromMode(mode), 0),
+ _mode(mode), _distortions(distortions),
+ _savedKs(cams.size()), _savedDistortions(cams.size())
+ { }
+
+ Vector2d projectPoint(Vector3d const& X, int i) const
+ {
+ return _cams[i].projectPoint(_distortions[i], X);
+ }
+
+ virtual void evalResidual(VectorArray<double>& e)
+ {
+ for (unsigned int k = 0; k < e.count(); ++k)
+ {
+ int const i = _correspondingParamA[k];
+ int const j = _correspondingParamB[k];
+
+ Vector2d const q = this->projectPoint(_Xs[j], i);
+ e[k][0] = q[0] - _measurements[k][0];
+ e[k][1] = q[1] - _measurements[k][1];
+ }
+ }
+
+ virtual void fillJacobians(Matrix<double>& Ak, Matrix<double>& Bk, Matrix<double>& Ck,
+ int i, int j, int k);
+
+ virtual void updateParametersA(VectorArray<double> const& deltaAi);
+
+ virtual void saveAllParameters()
+ {
+ Base::saveAllParameters();
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ _savedKs[i] = _cams[i].getIntrinsic();
+ std::copy(_distortions.begin(), _distortions.end(), _savedDistortions.begin());
+ }
+
+ virtual void restoreAllParameters()
+ {
+ Base::restoreAllParameters();
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ _cams[i].setIntrinsic(_savedKs[i]);
+ std::copy(_savedDistortions.begin(), _savedDistortions.end(), _distortions.begin());
+ }
+
+ protected:
+ int _mode;
+ std::vector<StdDistortionFunction>& _distortions;
+
+ std::vector<Matrix3x3d> _savedKs;
+ std::vector<StdDistortionFunction> _savedDistortions;
+ }; // end struct VaryingInternalsMetricBundleOptimizer
+
+} // end namespace V3D
+
+# endif
+
+#endif
diff --git a/extern/libmv/third_party/ssba/Math/v3d_linear.h b/extern/libmv/third_party/ssba/Math/v3d_linear.h
new file mode 100644
index 00000000000..7d6e898169c
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Math/v3d_linear.h
@@ -0,0 +1,923 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_LINEAR_H
+#define V3D_LINEAR_H
+
+#include <cassert>
+#include <algorithm>
+#include <vector>
+#include <cmath>
+
+namespace V3D
+{
+ using namespace std;
+
+ //! Unboxed vector type
+ template <typename Elem, int Size>
+ struct InlineVectorBase
+ {
+ typedef Elem value_type;
+ typedef Elem element_type;
+
+ typedef Elem const * const_iterator;
+ typedef Elem * iterator;
+
+ static unsigned int size() { return Size; }
+
+ Elem& operator[](unsigned int i) { return _vec[i]; }
+ Elem operator[](unsigned int i) const { return _vec[i]; }
+
+ Elem& operator()(unsigned int i) { return _vec[i-1]; }
+ Elem operator()(unsigned int i) const { return _vec[i-1]; }
+
+ const_iterator begin() const { return _vec; }
+ iterator begin() { return _vec; }
+ const_iterator end() const { return _vec + Size; }
+ iterator end() { return _vec + Size; }
+
+ void newsize(unsigned int sz) const
+ {
+ assert(sz == Size);
+ }
+
+ protected:
+ Elem _vec[Size];
+ };
+
+ //! Boxed (heap allocated) vector.
+ template <typename Elem>
+ struct VectorBase
+ {
+ typedef Elem value_type;
+ typedef Elem element_type;
+
+ typedef Elem const * const_iterator;
+ typedef Elem * iterator;
+
+ VectorBase()
+ : _size(0), _ownsVec(true), _vec(0)
+ { }
+
+ VectorBase(unsigned int size)
+ : _size(size), _ownsVec(true), _vec(0)
+ {
+ if (size > 0) _vec = new Elem[size];
+ }
+
+ VectorBase(unsigned int size, Elem * values)
+ : _size(size), _ownsVec(false), _vec(values)
+ { }
+
+ VectorBase(VectorBase<Elem> const& a)
+ : _size(0), _ownsVec(true), _vec(0)
+ {
+ _size = a._size;
+ if (_size == 0) return;
+ _vec = new Elem[_size];
+ std::copy(a._vec, a._vec + _size, _vec);
+ }
+
+ ~VectorBase() { if (_ownsVec && _vec != 0) delete [] _vec; }
+
+ VectorBase& operator=(VectorBase<Elem> const& a)
+ {
+ if (this == &a) return *this;
+
+ this->newsize(a._size);
+ std::copy(a._vec, a._vec + _size, _vec);
+ return *this;
+ }
+
+ unsigned int size() const { return _size; }
+
+ VectorBase<Elem>& newsize(unsigned int sz)
+ {
+ if (sz == _size) return *this;
+ assert(_ownsVec);
+
+ __destroy();
+ _size = sz;
+ if (_size > 0) _vec = new Elem[_size];
+
+ return *this;
+ }
+
+
+ Elem& operator[](unsigned int i) { return _vec[i]; }
+ Elem operator[](unsigned int i) const { return _vec[i]; }
+
+ Elem& operator()(unsigned int i) { return _vec[i-1]; }
+ Elem operator()(unsigned int i) const { return _vec[i-1]; }
+
+ const_iterator begin() const { return _vec; }
+ iterator begin() { return _vec; }
+ const_iterator end() const { return _vec + _size; }
+ iterator end() { return _vec + _size; }
+
+ protected:
+ void __destroy()
+ {
+ assert(_ownsVec);
+
+ if (_vec != 0) delete [] _vec;
+ _size = 0;
+ _vec = 0;
+ }
+
+ unsigned int _size;
+ bool _ownsVec;
+ Elem * _vec;
+ };
+
+ template <typename Elem, int Rows, int Cols>
+ struct InlineMatrixBase
+ {
+ typedef Elem value_type;
+ typedef Elem element_type;
+
+ typedef Elem * iterator;
+ typedef Elem const * const_iterator;
+
+ static unsigned int num_rows() { return Rows; }
+ static unsigned int num_cols() { return Cols; }
+
+ Elem * operator[](unsigned int row) { return _m[row]; }
+ Elem const * operator[](unsigned int row) const { return _m[row]; }
+
+ Elem& operator()(unsigned int row, unsigned int col) { return _m[row-1][col-1]; }
+ Elem operator()(unsigned int row, unsigned int col) const { return _m[row-1][col-1]; }
+
+ template <typename Vec>
+ void getRowSlice(unsigned int row, unsigned int first, unsigned int last, Vec& dst) const
+ {
+ for (unsigned int c = first; c < last; ++c) dst[c-first] = _m[row][c];
+ }
+
+ template <typename Vec>
+ void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const
+ {
+ for (unsigned int r = 0; r < len; ++r) dst[r] = _m[r+first][col];
+ }
+
+ void newsize(unsigned int rows, unsigned int cols) const
+ {
+ assert(rows == Rows && cols == Cols);
+ }
+
+ const_iterator begin() const { return &_m[0][0]; }
+ iterator begin() { return &_m[0][0]; }
+ const_iterator end() const { return &_m[0][0] + Rows*Cols; }
+ iterator end() { return &_m[0][0] + Rows*Cols; }
+
+ protected:
+ Elem _m[Rows][Cols];
+ };
+
+ template <typename Elem>
+ struct MatrixBase
+ {
+ typedef Elem value_type;
+ typedef Elem element_type;
+
+ typedef Elem const * const_iterator;
+ typedef Elem * iterator;
+
+ MatrixBase()
+ : _rows(0), _cols(0), _ownsData(true), _m(0)
+ { }
+
+ MatrixBase(unsigned int rows, unsigned int cols)
+ : _rows(rows), _cols(cols), _ownsData(true), _m(0)
+ {
+ if (_rows * _cols == 0) return;
+ _m = new Elem[rows*cols];
+ }
+
+ MatrixBase(unsigned int rows, unsigned int cols, Elem * values)
+ : _rows(rows), _cols(cols), _ownsData(false), _m(values)
+ { }
+
+ MatrixBase(MatrixBase<Elem> const& a)
+ : _ownsData(true), _m(0)
+ {
+ _rows = a._rows; _cols = a._cols;
+ if (_rows * _cols == 0) return;
+ _m = new Elem[_rows*_cols];
+ std::copy(a._m, a._m+_rows*_cols, _m);
+ }
+
+ ~MatrixBase()
+ {
+ if (_ownsData && _m != 0) delete [] _m;
+ }
+
+ MatrixBase& operator=(MatrixBase<Elem> const& a)
+ {
+ if (this == &a) return *this;
+
+ this->newsize(a.num_rows(), a.num_cols());
+
+ std::copy(a._m, a._m+_rows*_cols, _m);
+ return *this;
+ }
+
+ void newsize(unsigned int rows, unsigned int cols)
+ {
+ if (rows == _rows && cols == _cols) return;
+
+ assert(_ownsData);
+
+ __destroy();
+
+ _rows = rows;
+ _cols = cols;
+ if (_rows * _cols == 0) return;
+ _m = new Elem[rows*cols];
+ }
+
+ unsigned int num_rows() const { return _rows; }
+ unsigned int num_cols() const { return _cols; }
+
+ Elem * operator[](unsigned int row) { return _m + row*_cols; }
+ Elem const * operator[](unsigned int row) const { return _m + row*_cols; }
+
+ Elem& operator()(unsigned int row, unsigned int col) { return _m[(row-1)*_cols + col-1]; }
+ Elem operator()(unsigned int row, unsigned int col) const { return _m[(row-1)*_cols + col-1]; }
+
+ const_iterator begin() const { return _m; }
+ iterator begin() { return _m; }
+ const_iterator end() const { return _m + _rows*_cols; }
+ iterator end() { return _m + _rows*_cols; }
+
+ template <typename Vec>
+ void getRowSlice(unsigned int row, unsigned int first, unsigned int last, Vec& dst) const
+ {
+ Elem const * v = (*this)[row];
+ for (unsigned int c = first; c < last; ++c) dst[c-first] = v[c];
+ }
+
+ template <typename Vec>
+ void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const
+ {
+ for (unsigned int r = 0; r < len; ++r) dst[r] = _m[r+first][col];
+ }
+
+ protected:
+ void __destroy()
+ {
+ assert(_ownsData);
+ if (_m != 0) delete [] _m;
+ _m = 0;
+ _rows = _cols = 0;
+ }
+
+ unsigned int _rows, _cols;
+ bool _ownsData;
+ Elem * _m;
+ };
+
+ template <typename T>
+ struct CCS_Matrix
+ {
+ CCS_Matrix()
+ : _rows(0), _cols(0)
+ { }
+
+ CCS_Matrix(int const rows, int const cols, vector<pair<int, int> > const& nonZeros)
+ : _rows(rows), _cols(cols)
+ {
+ this->initialize(nonZeros);
+ }
+
+ CCS_Matrix(CCS_Matrix const& b)
+ : _rows(b._rows), _cols(b._cols),
+ _colStarts(b._colStarts), _rowIdxs(b._rowIdxs), _destIdxs(b._destIdxs), _values(b._values)
+ { }
+
+ CCS_Matrix& operator=(CCS_Matrix const& b)
+ {
+ if (this == &b) return *this;
+ _rows = b._rows;
+ _cols = b._cols;
+ _colStarts = b._colStarts;
+ _rowIdxs = b._rowIdxs;
+ _destIdxs = b._destIdxs;
+ _values = b._values;
+ return *this;
+ }
+
+ void create(int const rows, int const cols, vector<pair<int, int> > const& nonZeros)
+ {
+ _rows = rows;
+ _cols = cols;
+ this->initialize(nonZeros);
+ }
+
+ unsigned int num_rows() const { return _rows; }
+ unsigned int num_cols() const { return _cols; }
+
+ int getNonzeroCount() const { return _values.size(); }
+
+ T const * getValues() const { return &_values[0]; }
+ T * getValues() { return &_values[0]; }
+
+ int const * getDestIndices() const { return &_destIdxs[0]; }
+ int const * getColumnStarts() const { return &_colStarts[0]; }
+ int const * getRowIndices() const { return &_rowIdxs[0]; }
+
+ void getRowRange(unsigned int col, unsigned int& firstRow, unsigned int& lastRow) const
+ {
+ firstRow = _rowIdxs[_colStarts[col]];
+ lastRow = _rowIdxs[_colStarts[col+1]-1]+1;
+ }
+
+ template <typename Vec>
+ void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const
+ {
+ unsigned int const last = first + len;
+
+ for (int r = 0; r < len; ++r) dst[r] = 0; // Fill vector with zeros
+
+ int const colStart = _colStarts[col];
+ int const colEnd = _colStarts[col+1];
+
+ int i = colStart;
+ int r;
+ // Skip rows less than the given start row
+ while (i < colEnd && (r = _rowIdxs[i]) < first) ++i;
+
+ // Copy elements until the final row
+ while (i < colEnd && (r = _rowIdxs[i]) < last)
+ {
+ dst[r-first] = _values[i];
+ ++i;
+ }
+ } // end getColumnSlice()
+
+ int getColumnNonzeroCount(unsigned int col) const
+ {
+ int const colStart = _colStarts[col];
+ int const colEnd = _colStarts[col+1];
+ return colEnd - colStart;
+ }
+
+ template <typename VecA, typename VecB>
+ void getSparseColumn(unsigned int col, VecA& rows, VecB& values) const
+ {
+ int const colStart = _colStarts[col];
+ int const colEnd = _colStarts[col+1];
+ int const nnz = colEnd - colStart;
+
+ for (int i = 0; i < nnz; ++i)
+ {
+ rows[i] = _rowIdxs[colStart + i];
+ values[i] = _values[colStart + i];
+ }
+ }
+
+ protected:
+ struct NonzeroInfo
+ {
+ int row, col, serial;
+
+ // Sort wrt the column first
+ bool operator<(NonzeroInfo const& rhs) const
+ {
+ if (col < rhs.col) return true;
+ if (col > rhs.col) return false;
+ return row < rhs.row;
+ }
+ };
+
+ void initialize(std::vector<std::pair<int, int> > const& nonZeros)
+ {
+ using namespace std;
+
+ int const nnz = nonZeros.size();
+
+ _colStarts.resize(_cols + 1);
+ _rowIdxs.resize(nnz);
+
+ vector<NonzeroInfo> nz(nnz);
+ for (int k = 0; k < nnz; ++k)
+ {
+ nz[k].row = nonZeros[k].first;
+ nz[k].col = nonZeros[k].second;
+ nz[k].serial = k;
+ }
+
+ // Sort in column major order
+ std::sort(nz.begin(), nz.end());
+
+ for (size_t k = 0; k < nnz; ++k) _rowIdxs[k] = nz[k].row;
+
+ int curCol = -1;
+ for (int k = 0; k < nnz; ++k)
+ {
+ NonzeroInfo const& el = nz[k];
+ if (el.col != curCol)
+ {
+ // Update empty cols between
+ for (int c = curCol+1; c < el.col; ++c) _colStarts[c] = k;
+
+ curCol = el.col;
+ _colStarts[curCol] = k;
+ } // end if
+ } // end for (k)
+
+ // Update remaining columns
+ for (int c = curCol+1; c <= _cols; ++c) _colStarts[c] = nnz;
+
+ _destIdxs.resize(nnz);
+ for (int k = 0; k < nnz; ++k) _destIdxs[nz[k].serial] = k;
+
+ _values.resize(nnz);
+ } // end initialize()
+
+ int _rows, _cols;
+ std::vector<int> _colStarts;
+ std::vector<int> _rowIdxs;
+ std::vector<int> _destIdxs;
+ std::vector<T> _values;
+ }; // end struct CCS_Matrix
+
+//----------------------------------------------------------------------
+
+ template <typename Vec, typename Elem>
+ inline void
+ fillVector(Vec& v, Elem val)
+ {
+ // We do not use std::fill since we rely only on size() and operator[] member functions.
+ for (unsigned int i = 0; i < v.size(); ++i) v[i] = val;
+ }
+
+ template <typename Vec>
+ inline void
+ makeZeroVector(Vec& v)
+ {
+ fillVector(v, 0);
+ }
+
+ template <typename VecA, typename VecB>
+ inline void
+ copyVector(VecA const& src, VecB& dst)
+ {
+ assert(src.size() == dst.size());
+ // We do not use std::fill since we rely only on size() and operator[] member functions.
+ for (unsigned int i = 0; i < src.size(); ++i) dst[i] = src[i];
+ }
+
+ template <typename VecA, typename VecB>
+ inline void
+ copyVectorSlice(VecA const& src, unsigned int srcStart, unsigned int srcLen,
+ VecB& dst, unsigned int dstStart)
+ {
+ unsigned int const end = std::min(srcStart + srcLen, src.size());
+ unsigned int const sz = dst.size();
+ unsigned int i0, i1;
+ for (i0 = srcStart, i1 = dstStart; i0 < end && i1 < sz; ++i0, ++i1) dst[i1] = src[i0];
+ }
+
+ template <typename Vec>
+ inline typename Vec::value_type
+ norm_L1(Vec const& v)
+ {
+ typename Vec::value_type res(0);
+ for (unsigned int i = 0; i < v.size(); ++i) res += fabs(v[i]);
+ return res;
+ }
+
+ template <typename Vec>
+ inline typename Vec::value_type
+ norm_Linf(Vec const& v)
+ {
+ typename Vec::value_type res(0);
+ for (unsigned int i = 0; i < v.size(); ++i) res = std::max(res, fabs(v[i]));
+ return res;
+ }
+
+ template <typename Vec>
+ inline typename Vec::value_type
+ norm_L2(Vec const& v)
+ {
+ typename Vec::value_type res(0);
+ for (unsigned int i = 0; i < v.size(); ++i) res += v[i]*v[i];
+ return sqrt((double)res);
+ }
+
+ template <typename Vec>
+ inline typename Vec::value_type
+ sqrNorm_L2(Vec const& v)
+ {
+ typename Vec::value_type res(0);
+ for (unsigned int i = 0; i < v.size(); ++i) res += v[i]*v[i];
+ return res;
+ }
+
+ template <typename Vec>
+ inline void
+ normalizeVector(Vec& v)
+ {
+ typename Vec::value_type norm(norm_L2(v));
+ for (unsigned int i = 0; i < v.size(); ++i) v[i] /= norm;
+ }
+
+ template<typename VecA, typename VecB>
+ inline typename VecA::value_type
+ innerProduct(VecA const& a, VecB const& b)
+ {
+ assert(a.size() == b.size());
+ typename VecA::value_type res(0);
+ for (unsigned int i = 0; i < a.size(); ++i) res += a[i] * b[i];
+ return res;
+ }
+
+ template <typename Elem, typename VecA, typename VecB>
+ inline void
+ scaleVector(Elem s, VecA const& v, VecB& dst)
+ {
+ for (unsigned int i = 0; i < v.size(); ++i) dst[i] = s * v[i];
+ }
+
+ template <typename Elem, typename Vec>
+ inline void
+ scaleVectorIP(Elem s, Vec& v)
+ {
+ typedef typename Vec::value_type Elem2;
+ for (unsigned int i = 0; i < v.size(); ++i)
+ v[i] = (Elem2)(v[i] * s);
+ }
+
+ template <typename VecA, typename VecB, typename VecC>
+ inline void
+ makeCrossProductVector(VecA const& v, VecB const& w, VecC& dst)
+ {
+ assert(v.size() == 3);
+ assert(w.size() == 3);
+ assert(dst.size() == 3);
+ dst[0] = v[1]*w[2] - v[2]*w[1];
+ dst[1] = v[2]*w[0] - v[0]*w[2];
+ dst[2] = v[0]*w[1] - v[1]*w[0];
+ }
+
+ template <typename VecA, typename VecB, typename VecC>
+ inline void
+ addVectors(VecA const& v, VecB const& w, VecC& dst)
+ {
+ assert(v.size() == w.size());
+ assert(v.size() == dst.size());
+ for (unsigned int i = 0; i < v.size(); ++i) dst[i] = v[i] + w[i];
+ }
+
+ template <typename VecA, typename VecB, typename VecC>
+ inline void
+ subtractVectors(VecA const& v, VecB const& w, VecC& dst)
+ {
+ assert(v.size() == w.size());
+ assert(v.size() == dst.size());
+ for (unsigned int i = 0; i < v.size(); ++i) dst[i] = v[i] - w[i];
+ }
+
+ template <typename MatA, typename MatB>
+ inline void
+ copyMatrix(MatA const& src, MatB& dst)
+ {
+ unsigned int const rows = src.num_rows();
+ unsigned int const cols = src.num_cols();
+ assert(dst.num_rows() == rows);
+ assert(dst.num_cols() == cols);
+ for (unsigned int c = 0; c < cols; ++c)
+ for (unsigned int r = 0; r < rows; ++r) dst[r][c] = src[r][c];
+ }
+
+ template <typename MatA, typename MatB>
+ inline void
+ copyMatrixSlice(MatA const& src, unsigned int rowStart, unsigned int colStart, unsigned int rowLen, unsigned int colLen,
+ MatB& dst, unsigned int dstRow, unsigned int dstCol)
+ {
+ unsigned int const rows = dst.num_rows();
+ unsigned int const cols = dst.num_cols();
+
+ unsigned int const rowEnd = std::min(rowStart + rowLen, src.num_rows());
+ unsigned int const colEnd = std::min(colStart + colLen, src.num_cols());
+
+ unsigned int c0, c1, r0, r1;
+
+ for (c0 = colStart, c1 = dstCol; c0 < colEnd && c1 < cols; ++c0, ++c1)
+ for (r0 = rowStart, r1 = dstRow; r0 < rowEnd && r1 < rows; ++r0, ++r1)
+ dst[r1][c1] = src[r0][c0];
+ }
+
+ template <typename MatA, typename MatB>
+ inline void
+ makeTransposedMatrix(MatA const& src, MatB& dst)
+ {
+ unsigned int const rows = src.num_rows();
+ unsigned int const cols = src.num_cols();
+ assert(dst.num_cols() == rows);
+ assert(dst.num_rows() == cols);
+ for (unsigned int c = 0; c < cols; ++c)
+ for (unsigned int r = 0; r < rows; ++r) dst[c][r] = src[r][c];
+ }
+
+ template <typename Mat>
+ inline void
+ fillMatrix(Mat& m, typename Mat::value_type val)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ for (unsigned int c = 0; c < cols; ++c)
+ for (unsigned int r = 0; r < rows; ++r) m[r][c] = val;
+ }
+
+ template <typename Mat>
+ inline void
+ makeZeroMatrix(Mat& m)
+ {
+ fillMatrix(m, 0);
+ }
+
+ template <typename Mat>
+ inline void
+ makeIdentityMatrix(Mat& m)
+ {
+ makeZeroMatrix(m);
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ unsigned int n = std::min(rows, cols);
+ for (unsigned int i = 0; i < n; ++i)
+ m[i][i] = 1;
+ }
+
+ template <typename Mat, typename Vec>
+ inline void
+ makeCrossProductMatrix(Vec const& v, Mat& m)
+ {
+ assert(v.size() == 3);
+ assert(m.num_rows() == 3);
+ assert(m.num_cols() == 3);
+ m[0][0] = 0; m[0][1] = -v[2]; m[0][2] = v[1];
+ m[1][0] = v[2]; m[1][1] = 0; m[1][2] = -v[0];
+ m[2][0] = -v[1]; m[2][1] = v[0]; m[2][2] = 0;
+ }
+
+ template <typename Mat, typename Vec>
+ inline void
+ makeOuterProductMatrix(Vec const& v, Mat& m)
+ {
+ assert(m.num_cols() == m.num_rows());
+ assert(v.size() == m.num_cols());
+ unsigned const sz = v.size();
+ for (unsigned r = 0; r < sz; ++r)
+ for (unsigned c = 0; c < sz; ++c) m[r][c] = v[r]*v[c];
+ }
+
+ template <typename Mat, typename VecA, typename VecB>
+ inline void
+ makeOuterProductMatrix(VecA const& u, VecB const& v, Mat& m)
+ {
+ assert(m.num_cols() == m.num_rows());
+ assert(u.size() == m.num_cols());
+ assert(v.size() == m.num_cols());
+ unsigned const sz = u.size();
+ for (unsigned r = 0; r < sz; ++r)
+ for (unsigned c = 0; c < sz; ++c) m[r][c] = u[r]*v[c];
+ }
+
+ template <typename MatA, typename MatB, typename MatC>
+ void addMatrices(MatA const& a, MatB const& b, MatC& dst)
+ {
+ assert(a.num_cols() == b.num_cols());
+ assert(a.num_rows() == b.num_rows());
+ assert(dst.num_cols() == a.num_cols());
+ assert(dst.num_rows() == a.num_rows());
+
+ unsigned int const rows = a.num_rows();
+ unsigned int const cols = a.num_cols();
+
+ for (unsigned r = 0; r < rows; ++r)
+ for (unsigned c = 0; c < cols; ++c) dst[r][c] = a[r][c] + b[r][c];
+ }
+
+ template <typename MatA, typename MatB>
+ void addMatricesIP(MatA const& a, MatB& dst)
+ {
+ assert(dst.num_cols() == a.num_cols());
+ assert(dst.num_rows() == a.num_rows());
+
+ unsigned int const rows = a.num_rows();
+ unsigned int const cols = a.num_cols();
+
+ for (unsigned r = 0; r < rows; ++r)
+ for (unsigned c = 0; c < cols; ++c) dst[r][c] += a[r][c];
+ }
+
+ template <typename MatA, typename MatB, typename MatC>
+ void subtractMatrices(MatA const& a, MatB const& b, MatC& dst)
+ {
+ assert(a.num_cols() == b.num_cols());
+ assert(a.num_rows() == b.num_rows());
+ assert(dst.num_cols() == a.num_cols());
+ assert(dst.num_rows() == a.num_rows());
+
+ unsigned int const rows = a.num_rows();
+ unsigned int const cols = a.num_cols();
+
+ for (unsigned r = 0; r < rows; ++r)
+ for (unsigned c = 0; c < cols; ++c) dst[r][c] = a[r][c] - b[r][c];
+ }
+
+ template <typename MatA, typename Elem, typename MatB>
+ inline void
+ makeScaledMatrix(MatA const& m, Elem scale, MatB& dst)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ for (unsigned int c = 0; c < cols; ++c)
+ for (unsigned int r = 0; r < rows; ++r) dst[r][c] = m[r][c] * scale;
+ }
+
+ template <typename Mat, typename Elem>
+ inline void
+ scaleMatrixIP(Elem scale, Mat& m)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ for (unsigned int c = 0; c < cols; ++c)
+ for (unsigned int r = 0; r < rows; ++r) m[r][c] *= scale;
+ }
+
+ template <typename Mat, typename VecA, typename VecB>
+ inline void
+ multiply_A_v(Mat const& m, VecA const& in, VecB& dst)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ assert(in.size() == cols);
+ assert(dst.size() == rows);
+
+ makeZeroVector(dst);
+
+ for (unsigned int r = 0; r < rows; ++r)
+ for (unsigned int c = 0; c < cols; ++c) dst[r] += m[r][c] * in[c];
+ }
+
+ template <typename Mat, typename VecA, typename VecB>
+ inline void
+ multiply_A_v_projective(Mat const& m, VecA const& in, VecB& dst)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ assert(in.size() == cols-1);
+ assert(dst.size() == rows-1);
+
+ typename VecB::value_type w = m(rows-1, cols-1);
+ unsigned int r, i;
+ for (i = 0; i < cols-1; ++i) w += m(rows-1, i) * in[i];
+ for (r = 0; r < rows-1; ++r) dst[r] = m(r, cols-1);
+ for (r = 0; r < rows-1; ++r)
+ for (unsigned int c = 0; c < cols-1; ++c) dst[r] += m[r][c] * in[c];
+ for (i = 0; i < rows-1; ++i) dst[i] /= w;
+ }
+
+ template <typename Mat, typename VecA, typename VecB>
+ inline void
+ multiply_A_v_affine(Mat const& m, VecA const& in, VecB& dst)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ assert(in.size() == cols-1);
+ assert(dst.size() == rows);
+
+ unsigned int r;
+
+ for (r = 0; r < rows; ++r) dst[r] = m(r, cols-1);
+ for (r = 0; r < rows; ++r)
+ for (unsigned int c = 0; c < cols-1; ++c) dst[r] += m[r][c] * in[c];
+ }
+
+ template <typename Mat, typename VecA, typename VecB>
+ inline void
+ multiply_At_v(Mat const& m, VecA const& in, VecB& dst)
+ {
+ unsigned int const rows = m.num_rows();
+ unsigned int const cols = m.num_cols();
+ assert(in.size() == rows);
+ assert(dst.size() == cols);
+
+ makeZeroVector(dst);
+ for (unsigned int c = 0; c < cols; ++c)
+ for (unsigned int r = 0; r < rows; ++r) dst[c] += m[r][c] * in[r];
+ }
+
+ template <typename MatA, typename MatB>
+ inline void
+ multiply_At_A(MatA const& a, MatB& dst)
+ {
+ assert(dst.num_rows() == a.num_cols());
+ assert(dst.num_cols() == a.num_cols());
+
+ typedef typename MatB::value_type Elem;
+
+ Elem accum;
+ for (unsigned int r = 0; r < a.num_cols(); ++r)
+ for (unsigned int c = 0; c < a.num_cols(); ++c)
+ {
+ accum = 0;
+ for (unsigned int k = 0; k < a.num_rows(); ++k) accum += a[k][r] * a[k][c];
+ dst[r][c] = accum;
+ }
+ }
+
+ template <typename MatA, typename MatB, typename MatC>
+ inline void
+ multiply_A_B(MatA const& a, MatB const& b, MatC& dst)
+ {
+ assert(a.num_cols() == b.num_rows());
+ assert(dst.num_rows() == a.num_rows());
+ assert(dst.num_cols() == b.num_cols());
+
+ typedef typename MatC::value_type Elem;
+
+ Elem accum;
+ for (unsigned int r = 0; r < a.num_rows(); ++r)
+ for (unsigned int c = 0; c < b.num_cols(); ++c)
+ {
+ accum = 0;
+ for (unsigned int k = 0; k < a.num_cols(); ++k) accum += a[r][k] * b[k][c];
+ dst[r][c] = accum;
+ }
+ }
+
+ template <typename MatA, typename MatB, typename MatC>
+ inline void
+ multiply_At_B(MatA const& a, MatB const& b, MatC& dst)
+ {
+ assert(a.num_rows() == b.num_rows());
+ assert(dst.num_rows() == a.num_cols());
+ assert(dst.num_cols() == b.num_cols());
+
+ typedef typename MatC::value_type Elem;
+
+ Elem accum;
+ for (unsigned int r = 0; r < a.num_cols(); ++r)
+ for (unsigned int c = 0; c < b.num_cols(); ++c)
+ {
+ accum = 0;
+ for (unsigned int k = 0; k < a.num_rows(); ++k) accum += a[k][r] * b[k][c];
+ dst[r][c] = accum;
+ }
+ }
+
+ template <typename MatA, typename MatB, typename MatC>
+ inline void
+ multiply_A_Bt(MatA const& a, MatB const& b, MatC& dst)
+ {
+ assert(a.num_cols() == b.num_cols());
+ assert(dst.num_rows() == a.num_rows());
+ assert(dst.num_cols() == b.num_rows());
+
+ typedef typename MatC::value_type Elem;
+
+ Elem accum;
+ for (unsigned int r = 0; r < a.num_rows(); ++r)
+ for (unsigned int c = 0; c < b.num_rows(); ++c)
+ {
+ accum = 0;
+ for (unsigned int k = 0; k < a.num_cols(); ++k) accum += a[r][k] * b[c][k];
+ dst[r][c] = accum;
+ }
+ }
+
+ template <typename Mat>
+ inline void
+ transposeMatrixIP(Mat& a)
+ {
+ assert(a.num_rows() == a.num_cols());
+
+ for (unsigned int r = 0; r < a.num_rows(); ++r)
+ for (unsigned int c = 0; c < r; ++c)
+ std::swap(a[r][c], a[c][r]);
+ }
+
+} // end namespace V3D
+
+#endif
diff --git a/extern/libmv/third_party/ssba/Math/v3d_linear_utils.h b/extern/libmv/third_party/ssba/Math/v3d_linear_utils.h
new file mode 100644
index 00000000000..969ec99694f
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Math/v3d_linear_utils.h
@@ -0,0 +1,391 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_LINEAR_UTILS_H
+#define V3D_LINEAR_UTILS_H
+
+#include "Math/v3d_linear.h"
+
+#include <iostream>
+
+namespace V3D
+{
+
+ template <typename Elem, int Size>
+ struct InlineVector : public InlineVectorBase<Elem, Size>
+ {
+ }; // end struct InlineVector
+
+ template <typename Elem>
+ struct Vector : public VectorBase<Elem>
+ {
+ Vector()
+ : VectorBase<Elem>()
+ { }
+
+ Vector(unsigned int size)
+ : VectorBase<Elem>(size)
+ { }
+
+ Vector(unsigned int size, Elem * values)
+ : VectorBase<Elem>(size, values)
+ { }
+
+ Vector(Vector<Elem> const& a)
+ : VectorBase<Elem>(a)
+ { }
+
+ Vector<Elem>& operator=(Vector<Elem> const& a)
+ {
+ (VectorBase<Elem>::operator=)(a);
+ return *this;
+ }
+
+ Vector<Elem>& operator+=(Vector<Elem> const& rhs)
+ {
+ addVectorsIP(rhs, *this);
+ return *this;
+ }
+
+ Vector<Elem>& operator*=(Elem scale)
+ {
+ scaleVectorsIP(scale, *this);
+ return *this;
+ }
+
+ Vector<Elem> operator+(Vector<Elem> const& rhs) const
+ {
+ Vector<Elem> res(this->size());
+ addVectors(*this, rhs, res);
+ return res;
+ }
+
+ Vector<Elem> operator-(Vector<Elem> const& rhs) const
+ {
+ Vector<Elem> res(this->size());
+ subtractVectors(*this, rhs, res);
+ return res;
+ }
+
+ Elem operator*(Vector<Elem> const& rhs) const
+ {
+ return innerProduct(*this, rhs);
+ }
+
+ }; // end struct Vector
+
+ template <typename Elem, int Rows, int Cols>
+ struct InlineMatrix : public InlineMatrixBase<Elem, Rows, Cols>
+ {
+ }; // end struct InlineMatrix
+
+ template <typename Elem>
+ struct Matrix : public MatrixBase<Elem>
+ {
+ Matrix()
+ : MatrixBase<Elem>()
+ { }
+
+ Matrix(unsigned int rows, unsigned int cols)
+ : MatrixBase<Elem>(rows, cols)
+ { }
+
+ Matrix(unsigned int rows, unsigned int cols, Elem * values)
+ : MatrixBase<Elem>(rows, cols, values)
+ { }
+
+ Matrix(Matrix<Elem> const& a)
+ : MatrixBase<Elem>(a)
+ { }
+
+ Matrix<Elem>& operator=(Matrix<Elem> const& a)
+ {
+ (MatrixBase<Elem>::operator=)(a);
+ return *this;
+ }
+
+ Matrix<Elem>& operator+=(Matrix<Elem> const& rhs)
+ {
+ addMatricesIP(rhs, *this);
+ return *this;
+ }
+
+ Matrix<Elem>& operator*=(Elem scale)
+ {
+ scaleMatrixIP(scale, *this);
+ return *this;
+ }
+
+ Matrix<Elem> operator+(Matrix<Elem> const& rhs) const
+ {
+ Matrix<Elem> res(this->num_rows(), this->num_cols());
+ addMatrices(*this, rhs, res);
+ return res;
+ }
+
+ Matrix<Elem> operator-(Matrix<Elem> const& rhs) const
+ {
+ Matrix<Elem> res(this->num_rows(), this->num_cols());
+ subtractMatrices(*this, rhs, res);
+ return res;
+ }
+
+ }; // end struct Matrix
+
+//----------------------------------------------------------------------
+
+ typedef InlineVector<float, 2> Vector2f;
+ typedef InlineVector<double, 2> Vector2d;
+ typedef InlineVector<float, 3> Vector3f;
+ typedef InlineVector<double, 3> Vector3d;
+ typedef InlineVector<float, 4> Vector4f;
+ typedef InlineVector<double, 4> Vector4d;
+
+ typedef InlineMatrix<float, 2, 2> Matrix2x2f;
+ typedef InlineMatrix<double, 2, 2> Matrix2x2d;
+ typedef InlineMatrix<float, 3, 3> Matrix3x3f;
+ typedef InlineMatrix<double, 3, 3> Matrix3x3d;
+ typedef InlineMatrix<float, 4, 4> Matrix4x4f;
+ typedef InlineMatrix<double, 4, 4> Matrix4x4d;
+
+ typedef InlineMatrix<float, 2, 3> Matrix2x3f;
+ typedef InlineMatrix<double, 2, 3> Matrix2x3d;
+ typedef InlineMatrix<float, 3, 4> Matrix3x4f;
+ typedef InlineMatrix<double, 3, 4> Matrix3x4d;
+
+ template <typename Elem>
+ struct VectorArray
+ {
+ VectorArray(unsigned count, unsigned size)
+ : _count(count), _size(size), _values(0), _vectors(0)
+ {
+ unsigned const nTotal = _count * _size;
+ if (count > 0) _vectors = new Vector<Elem>[count];
+ if (nTotal > 0) _values = new Elem[nTotal];
+ for (unsigned i = 0; i < _count; ++i) new (&_vectors[i]) Vector<Elem>(_size, _values + i*_size);
+ }
+
+ VectorArray(unsigned count, unsigned size, Elem initVal)
+ : _count(count), _size(size), _values(0), _vectors(0)
+ {
+ unsigned const nTotal = _count * _size;
+ if (count > 0) _vectors = new Vector<Elem>[count];
+ if (nTotal > 0) _values = new Elem[nTotal];
+ for (unsigned i = 0; i < _count; ++i) new (&_vectors[i]) Vector<Elem>(_size, _values + i*_size);
+ std::fill(_values, _values + nTotal, initVal);
+ }
+
+ ~VectorArray()
+ {
+ delete [] _values;
+ delete [] _vectors;
+ }
+
+ unsigned count() const { return _count; }
+ unsigned size() const { return _size; }
+
+ //! Get the submatrix at position ix
+ Vector<Elem> const& operator[](unsigned ix) const
+ {
+ return _vectors[ix];
+ }
+
+ //! Get the submatrix at position ix
+ Vector<Elem>& operator[](unsigned ix)
+ {
+ return _vectors[ix];
+ }
+
+ protected:
+ unsigned _count, _size;
+ Elem * _values;
+ Vector<Elem> * _vectors;
+
+ private:
+ VectorArray(VectorArray const&);
+ void operator=(VectorArray const&);
+ };
+
+ template <typename Elem>
+ struct MatrixArray
+ {
+ MatrixArray(unsigned count, unsigned nRows, unsigned nCols)
+ : _count(count), _rows(nRows), _columns(nCols), _values(0), _matrices(0)
+ {
+ unsigned const nTotal = _count * _rows * _columns;
+ if (count > 0) _matrices = new Matrix<Elem>[count];
+ if (nTotal > 0) _values = new double[nTotal];
+ for (unsigned i = 0; i < _count; ++i)
+ new (&_matrices[i]) Matrix<Elem>(_rows, _columns, _values + i*(_rows*_columns));
+ }
+
+ ~MatrixArray()
+ {
+ delete [] _matrices;
+ delete [] _values;
+ }
+
+ //! Get the submatrix at position ix
+ Matrix<Elem> const& operator[](unsigned ix) const
+ {
+ return _matrices[ix];
+ }
+
+ //! Get the submatrix at position ix
+ Matrix<Elem>& operator[](unsigned ix)
+ {
+ return _matrices[ix];
+ }
+
+ unsigned count() const { return _count; }
+ unsigned num_rows() const { return _rows; }
+ unsigned num_cols() const { return _columns; }
+
+ protected:
+ unsigned _count, _rows, _columns;
+ double * _values;
+ Matrix<Elem> * _matrices;
+
+ private:
+ MatrixArray(MatrixArray const&);
+ void operator=(MatrixArray const&);
+ };
+
+//----------------------------------------------------------------------
+
+ template <typename Elem, int Size>
+ inline InlineVector<Elem, Size>
+ operator+(InlineVector<Elem, Size> const& v, InlineVector<Elem, Size> const& w)
+ {
+ InlineVector<Elem, Size> res;
+ addVectors(v, w, res);
+ return res;
+ }
+
+ template <typename Elem, int Size>
+ inline InlineVector<Elem, Size>
+ operator-(InlineVector<Elem, Size> const& v, InlineVector<Elem, Size> const& w)
+ {
+ InlineVector<Elem, Size> res;
+ subtractVectors(v, w, res);
+ return res;
+ }
+
+ template <typename Elem, int Size>
+ inline InlineVector<Elem, Size>
+ operator*(Elem scale, InlineVector<Elem, Size> const& v)
+ {
+ InlineVector<Elem, Size> res;
+ scaleVector(scale, v, res);
+ return res;
+ }
+
+ template <typename Elem, int Rows, int Cols>
+ inline InlineVector<Elem, Rows>
+ operator*(InlineMatrix<Elem, Rows, Cols> const& A, InlineVector<Elem, Cols> const& v)
+ {
+ InlineVector<Elem, Rows> res;
+ multiply_A_v(A, v, res);
+ return res;
+ }
+
+ template <typename Elem, int RowsA, int ColsA, int ColsB>
+ inline InlineMatrix<Elem, RowsA, ColsB>
+ operator*(InlineMatrix<Elem, RowsA, ColsA> const& A, InlineMatrix<Elem, ColsA, ColsB> const& B)
+ {
+ InlineMatrix<Elem, RowsA, ColsB> res;
+ multiply_A_B(A, B, res);
+ return res;
+ }
+
+ template <typename Elem, int Rows, int Cols>
+ inline InlineMatrix<Elem, Cols, Rows>
+ transposedMatrix(InlineMatrix<Elem, Rows, Cols> const& A)
+ {
+ InlineMatrix<Elem, Cols, Rows> At;
+ makeTransposedMatrix(A, At);
+ return At;
+ }
+
+ template <typename Elem>
+ inline InlineMatrix<Elem, 3, 3>
+ invertedMatrix(InlineMatrix<Elem, 3, 3> const& A)
+ {
+ Elem a = A[0][0], b = A[0][1], c = A[0][2];
+ Elem d = A[1][0], e = A[1][1], f = A[1][2];
+ Elem g = A[2][0], h = A[2][1], i = A[2][2];
+
+ Elem const det = a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h;
+
+ InlineMatrix<Elem, 3, 3> res;
+ res[0][0] = e*i-f*h; res[0][1] = c*h-b*i; res[0][2] = b*f-c*e;
+ res[1][0] = f*g-d*i; res[1][1] = a*i-c*g; res[1][2] = c*d-a*f;
+ res[2][0] = d*h-e*g; res[2][1] = b*g-a*h; res[2][2] = a*e-b*d;
+
+ scaleMatrixIP(1.0/det, res);
+ return res;
+ }
+
+ template <typename Elem>
+ inline InlineVector<Elem, 2>
+ makeVector2(Elem a, Elem b)
+ {
+ InlineVector<Elem, 2> res;
+ res[0] = a; res[1] = b;
+ return res;
+ }
+
+ template <typename Elem>
+ inline InlineVector<Elem, 3>
+ makeVector3(Elem a, Elem b, Elem c)
+ {
+ InlineVector<Elem, 3> res;
+ res[0] = a; res[1] = b; res[2] = c;
+ return res;
+ }
+
+ template <typename Vec>
+ inline void
+ displayVector(Vec const& v)
+ {
+ using namespace std;
+
+ for (int r = 0; r < v.size(); ++r)
+ cout << v[r] << " ";
+ cout << endl;
+ }
+
+ template <typename Mat>
+ inline void
+ displayMatrix(Mat const& A)
+ {
+ using namespace std;
+
+ for (int r = 0; r < A.num_rows(); ++r)
+ {
+ for (int c = 0; c < A.num_cols(); ++c)
+ cout << A[r][c] << " ";
+ cout << endl;
+ }
+ }
+
+} // end namespace V3D
+
+#endif
diff --git a/extern/libmv/third_party/ssba/Math/v3d_mathutilities.h b/extern/libmv/third_party/ssba/Math/v3d_mathutilities.h
new file mode 100644
index 00000000000..9e38b92a94b
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Math/v3d_mathutilities.h
@@ -0,0 +1,59 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_MATH_UTILITIES_H
+#define V3D_MATH_UTILITIES_H
+
+#include "Math/v3d_linear.h"
+#include "Math/v3d_linear_utils.h"
+
+#include <vector>
+
+namespace V3D
+{
+
+ template <typename Vec, typename Mat>
+ inline void
+ createRotationMatrixRodriguez(Vec const& omega, Mat& R)
+ {
+ assert(omega.size() == 3);
+ assert(R.num_rows() == 3);
+ assert(R.num_cols() == 3);
+
+ double const theta = norm_L2(omega);
+ makeIdentityMatrix(R);
+ if (fabs(theta) > 1e-6)
+ {
+ Matrix3x3d J, J2;
+ makeCrossProductMatrix(omega, J);
+ multiply_A_B(J, J, J2);
+ double const c1 = sin(theta)/theta;
+ double const c2 = (1-cos(theta))/(theta*theta);
+ for (int i = 0; i < 3; ++i)
+ for (int j = 0; j < 3; ++j)
+ R[i][j] += c1*J[i][j] + c2*J2[i][j];
+ }
+ } // end createRotationMatrixRodriguez()
+
+ template <typename T> inline double sqr(T x) { return x*x; }
+
+} // namespace V3D
+
+#endif
diff --git a/extern/libmv/third_party/ssba/Math/v3d_optimization.cpp b/extern/libmv/third_party/ssba/Math/v3d_optimization.cpp
new file mode 100644
index 00000000000..234815fcd1f
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Math/v3d_optimization.cpp
@@ -0,0 +1,955 @@
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Math/v3d_optimization.h"
+
+#if defined(V3DLIB_ENABLE_SUITESPARSE)
+//# include "COLAMD/Include/colamd.h"
+# include "colamd.h"
+extern "C"
+{
+//# include "LDL/Include/ldl.h"
+# include "ldl.h"
+}
+#endif
+
+#include <iostream>
+#include <map>
+
+#define USE_BLOCK_REORDERING 1
+#define USE_MULTIPLICATIVE_UPDATE 1
+
+using namespace std;
+
+namespace
+{
+
+ using namespace V3D;
+
+ inline double
+ squaredResidual(VectorArray<double> const& e)
+ {
+ int const N = e.count();
+ int const M = e.size();
+
+ double res = 0.0;
+
+ for (int n = 0; n < N; ++n)
+ for (int m = 0; m < M; ++m)
+ res += e[n][m] * e[n][m];
+
+ return res;
+ } // end squaredResidual()
+
+} // end namespace <>
+
+namespace V3D
+{
+
+ int optimizerVerbosenessLevel = 0;
+
+#if defined(V3DLIB_ENABLE_SUITESPARSE)
+
+ void
+ SparseLevenbergOptimizer::setupSparseJtJ()
+ {
+ int const nVaryingA = _nParametersA - _nNonvaryingA;
+ int const nVaryingB = _nParametersB - _nNonvaryingB;
+ int const nVaryingC = _paramDimensionC - _nNonvaryingC;
+
+ int const bColumnStart = nVaryingA*_paramDimensionA;
+ int const cColumnStart = bColumnStart + nVaryingB*_paramDimensionB;
+ int const nColumns = cColumnStart + nVaryingC;
+
+ _jointNonzerosW.clear();
+ _jointIndexW.resize(_nMeasurements);
+#if 1
+ {
+ map<pair<int, int>, int> jointNonzeroMap;
+ for (size_t k = 0; k < _nMeasurements; ++k)
+ {
+ int const i = _correspondingParamA[k] - _nNonvaryingA;
+ int const j = _correspondingParamB[k] - _nNonvaryingB;
+ if (i >= 0 && j >= 0)
+ {
+ map<pair<int, int>, int>::const_iterator p = jointNonzeroMap.find(make_pair(i, j));
+ if (p == jointNonzeroMap.end())
+ {
+ jointNonzeroMap.insert(make_pair(make_pair(i, j), _jointNonzerosW.size()));
+ _jointIndexW[k] = _jointNonzerosW.size();
+ _jointNonzerosW.push_back(make_pair(i, j));
+ }
+ else
+ {
+ _jointIndexW[k] = (*p).second;
+ } // end if
+ } // end if
+ } // end for (k)
+ } // end scope
+#else
+ for (size_t k = 0; k < _nMeasurements; ++k)
+ {
+ int const i = _correspondingParamA[k] - _nNonvaryingA;
+ int const j = _correspondingParamB[k] - _nNonvaryingB;
+ if (i >= 0 && j >= 0)
+ {
+ _jointIndexW[k] = _jointNonzerosW.size();
+ _jointNonzerosW.push_back(make_pair(i, j));
+ }
+ } // end for (k)
+#endif
+
+#if defined(USE_BLOCK_REORDERING)
+ int const bBlockColumnStart = nVaryingA;
+ int const cBlockColumnStart = bBlockColumnStart + nVaryingB;
+
+ int const nBlockColumns = cBlockColumnStart + ((nVaryingC > 0) ? 1 : 0);
+
+ //cout << "nBlockColumns = " << nBlockColumns << endl;
+
+ // For the column reordering we treat the columns belonging to one set
+ // of parameters as one (logical) column.
+
+ // Determine non-zeros of JtJ (we forget about the non-zero diagonal for now)
+ // Only consider nonzeros of Ai^t * Bj induced by the measurements.
+ vector<pair<int, int> > nz_blockJtJ(_jointNonzerosW.size());
+ for (int k = 0; k < _jointNonzerosW.size(); ++k)
+ {
+ nz_blockJtJ[k].first = _jointNonzerosW[k].second + bBlockColumnStart;
+ nz_blockJtJ[k].second = _jointNonzerosW[k].first;
+ }
+
+ if (nVaryingC > 0)
+ {
+ // We assume, that the global unknowns are linked to every other variable.
+ for (int i = 0; i < nVaryingA; ++i)
+ nz_blockJtJ.push_back(make_pair(cBlockColumnStart, i));
+ for (int j = 0; j < nVaryingB; ++j)
+ nz_blockJtJ.push_back(make_pair(cBlockColumnStart, j + bBlockColumnStart));
+ } // end if
+
+ int const nnzBlock = nz_blockJtJ.size();
+
+ vector<int> permBlockJtJ(nBlockColumns + 1);
+
+ if (nnzBlock > 0)
+ {
+// cout << "nnzBlock = " << nnzBlock << endl;
+
+ CCS_Matrix<int> blockJtJ(nBlockColumns, nBlockColumns, nz_blockJtJ);
+
+// cout << " nz_blockJtJ: " << endl;
+// for (size_t k = 0; k < nz_blockJtJ.size(); ++k)
+// cout << " " << nz_blockJtJ[k].first << ":" << nz_blockJtJ[k].second << endl;
+// cout << endl;
+
+ int * colStarts = (int *)blockJtJ.getColumnStarts();
+ int * rowIdxs = (int *)blockJtJ.getRowIndices();
+
+// cout << "blockJtJ_colStarts = ";
+// for (int k = 0; k <= nBlockColumns; ++k) cout << colStarts[k] << " ";
+// cout << endl;
+
+// cout << "blockJtJ_rowIdxs = ";
+// for (int k = 0; k < nnzBlock; ++k) cout << rowIdxs[k] << " ";
+// cout << endl;
+
+ int stats[COLAMD_STATS];
+ symamd(nBlockColumns, rowIdxs, colStarts, &permBlockJtJ[0], (double *) NULL, stats, &calloc, &free);
+ if (optimizerVerbosenessLevel >= 2) symamd_report(stats);
+ }
+ else
+ {
+ for (int k = 0; k < permBlockJtJ.size(); ++k) permBlockJtJ[k] = k;
+ } // end if
+
+// cout << "permBlockJtJ = ";
+// for (int k = 0; k < permBlockJtJ.size(); ++k)
+// cout << permBlockJtJ[k] << " ";
+// cout << endl;
+
+ // From the determined symbolic permutation with logical variables, determine the actual ordering
+ _perm_JtJ.resize(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC + 1);
+
+ int curDstCol = 0;
+ for (int k = 0; k < permBlockJtJ.size()-1; ++k)
+ {
+ int const srcCol = permBlockJtJ[k];
+ if (srcCol < nVaryingA)
+ {
+ for (int n = 0; n < _paramDimensionA; ++n)
+ _perm_JtJ[curDstCol + n] = srcCol*_paramDimensionA + n;
+ curDstCol += _paramDimensionA;
+ }
+ else if (srcCol >= bBlockColumnStart && srcCol < cBlockColumnStart)
+ {
+ int const bStart = nVaryingA*_paramDimensionA;
+ int const j = srcCol - bBlockColumnStart;
+
+ for (int n = 0; n < _paramDimensionB; ++n)
+ _perm_JtJ[curDstCol + n] = bStart + j*_paramDimensionB + n;
+ curDstCol += _paramDimensionB;
+ }
+ else if (srcCol == cBlockColumnStart)
+ {
+ int const cStart = nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB;
+
+ for (int n = 0; n < nVaryingC; ++n)
+ _perm_JtJ[curDstCol + n] = cStart + n;
+ curDstCol += nVaryingC;
+ }
+ else
+ {
+ cerr << "Should not reach " << __LINE__ << ":" << __LINE__ << "!" << endl;
+ assert(false);
+ }
+ }
+#else
+ vector<pair<int, int> > nz, nzL;
+ this->serializeNonZerosJtJ(nz);
+
+ for (int k = 0; k < nz.size(); ++k)
+ {
+ // Swap rows and columns, since serializeNonZerosJtJ() generates the
+ // upper triangular part but symamd wants the lower triangle.
+ nzL.push_back(make_pair(nz[k].second, nz[k].first));
+ }
+
+ _perm_JtJ.resize(nColumns+1);
+
+ if (nzL.size() > 0)
+ {
+ CCS_Matrix<int> symbJtJ(nColumns, nColumns, nzL);
+
+ int * colStarts = (int *)symbJtJ.getColumnStarts();
+ int * rowIdxs = (int *)symbJtJ.getRowIndices();
+
+// cout << "symbJtJ_colStarts = ";
+// for (int k = 0; k <= nColumns; ++k) cout << colStarts[k] << " ";
+// cout << endl;
+
+// cout << "symbJtJ_rowIdxs = ";
+// for (int k = 0; k < nzL.size(); ++k) cout << rowIdxs[k] << " ";
+// cout << endl;
+
+ int stats[COLAMD_STATS];
+ symamd(nColumns, rowIdxs, colStarts, &_perm_JtJ[0], (double *) NULL, stats, &calloc, &free);
+ if (optimizerVerbosenessLevel >= 2) symamd_report(stats);
+ }
+ else
+ {
+ for (int k = 0; k < _perm_JtJ.size(); ++k) _perm_JtJ[k] = k;
+ } //// end if
+#endif
+ _perm_JtJ.back() = _perm_JtJ.size() - 1;
+
+// cout << "_perm_JtJ = ";
+// for (int k = 0; k < _perm_JtJ.size(); ++k) cout << _perm_JtJ[k] << " ";
+// cout << endl;
+
+ // Finally, compute the inverse of the full permutation.
+ _invPerm_JtJ.resize(_perm_JtJ.size());
+ for (size_t k = 0; k < _perm_JtJ.size(); ++k)
+ _invPerm_JtJ[_perm_JtJ[k]] = k;
+
+ vector<pair<int, int> > nz_JtJ;
+ this->serializeNonZerosJtJ(nz_JtJ);
+
+ for (int k = 0; k < nz_JtJ.size(); ++k)
+ {
+ int const i = nz_JtJ[k].first;
+ int const j = nz_JtJ[k].second;
+
+ int pi = _invPerm_JtJ[i];
+ int pj = _invPerm_JtJ[j];
+ // Swap values if in lower triangular part
+ if (pi > pj) std::swap(pi, pj);
+ nz_JtJ[k].first = pi;
+ nz_JtJ[k].second = pj;
+ }
+
+ int const nnz = nz_JtJ.size();
+
+// cout << "nz_JtJ = ";
+// for (int k = 0; k < nnz; ++k) cout << nz_JtJ[k].first << ":" << nz_JtJ[k].second << " ";
+// cout << endl;
+
+ _JtJ.create(nColumns, nColumns, nz_JtJ);
+
+// cout << "_colStart_JtJ = ";
+// for (int k = 0; k < _JtJ.num_cols(); ++k) cout << _JtJ.getColumnStarts()[k] << " ";
+// cout << endl;
+
+// cout << "_rowIdxs_JtJ = ";
+// for (int k = 0; k < nnz; ++k) cout << _JtJ.getRowIndices()[k] << " ";
+// cout << endl;
+
+ vector<int> workFlags(nColumns);
+
+ _JtJ_Lp.resize(nColumns+1);
+ _JtJ_Parent.resize(nColumns);
+ _JtJ_Lnz.resize(nColumns);
+
+ ldl_symbolic(nColumns, (int *)_JtJ.getColumnStarts(), (int *)_JtJ.getRowIndices(),
+ &_JtJ_Lp[0], &_JtJ_Parent[0], &_JtJ_Lnz[0],
+ &workFlags[0], NULL, NULL);
+
+ if (optimizerVerbosenessLevel >= 1)
+ cout << "SparseLevenbergOptimizer: Nonzeros in LDL decomposition: " << _JtJ_Lp[nColumns] << endl;
+
+ } // end SparseLevenbergOptimizer::setupSparseJtJ()
+
+ void
+ SparseLevenbergOptimizer::serializeNonZerosJtJ(vector<pair<int, int> >& dst) const
+ {
+ int const nVaryingA = _nParametersA - _nNonvaryingA;
+ int const nVaryingB = _nParametersB - _nNonvaryingB;
+ int const nVaryingC = _paramDimensionC - _nNonvaryingC;
+
+ int const bColumnStart = nVaryingA*_paramDimensionA;
+ int const cColumnStart = bColumnStart + nVaryingB*_paramDimensionB;
+
+ dst.clear();
+
+ // Add the diagonal block matrices (only the upper triangular part).
+
+ // Ui submatrices of JtJ
+ for (int i = 0; i < nVaryingA; ++i)
+ {
+ int const i0 = i * _paramDimensionA;
+
+ for (int c = 0; c < _paramDimensionA; ++c)
+ for (int r = 0; r <= c; ++r)
+ dst.push_back(make_pair(i0 + r, i0 + c));
+ }
+
+ // Vj submatrices of JtJ
+ for (int j = 0; j < nVaryingB; ++j)
+ {
+ int const j0 = j*_paramDimensionB + bColumnStart;
+
+ for (int c = 0; c < _paramDimensionB; ++c)
+ for (int r = 0; r <= c; ++r)
+ dst.push_back(make_pair(j0 + r, j0 + c));
+ }
+
+ // Z submatrix of JtJ
+ for (int c = 0; c < nVaryingC; ++c)
+ for (int r = 0; r <= c; ++r)
+ dst.push_back(make_pair(cColumnStart + r, cColumnStart + c));
+
+ // Add the elements i and j linked by an observation k
+ // W submatrix of JtJ
+ for (size_t n = 0; n < _jointNonzerosW.size(); ++n)
+ {
+ int const i0 = _jointNonzerosW[n].first;
+ int const j0 = _jointNonzerosW[n].second;
+ int const r0 = i0*_paramDimensionA;
+ int const c0 = j0*_paramDimensionB + bColumnStart;
+
+ for (int r = 0; r < _paramDimensionA; ++r)
+ for (int c = 0; c < _paramDimensionB; ++c)
+ dst.push_back(make_pair(r0 + r, c0 + c));
+ } // end for (n)
+
+ if (nVaryingC > 0)
+ {
+ // Finally, add the dense columns linking i (resp. j) with the global parameters.
+ // X submatrix of JtJ
+ for (int i = 0; i < nVaryingA; ++i)
+ {
+ int const i0 = i*_paramDimensionA;
+
+ for (int r = 0; r < _paramDimensionA; ++r)
+ for (int c = 0; c < nVaryingC; ++c)
+ dst.push_back(make_pair(i0 + r, cColumnStart + c));
+ }
+
+ // Y submatrix of JtJ
+ for (int j = 0; j < nVaryingB; ++j)
+ {
+ int const j0 = j*_paramDimensionB + bColumnStart;
+
+ for (int r = 0; r < _paramDimensionB; ++r)
+ for (int c = 0; c < nVaryingC; ++c)
+ dst.push_back(make_pair(j0 + r, cColumnStart + c));
+ }
+ } // end if
+ } // end SparseLevenbergOptimizer::serializeNonZerosJtJ()
+
+ void
+ SparseLevenbergOptimizer::fillSparseJtJ(MatrixArray<double> const& Ui,
+ MatrixArray<double> const& Vj,
+ MatrixArray<double> const& Wn,
+ Matrix<double> const& Z,
+ Matrix<double> const& X,
+ Matrix<double> const& Y)
+ {
+ int const nVaryingA = _nParametersA - _nNonvaryingA;
+ int const nVaryingB = _nParametersB - _nNonvaryingB;
+ int const nVaryingC = _paramDimensionC - _nNonvaryingC;
+
+ int const bColumnStart = nVaryingA*_paramDimensionA;
+ int const cColumnStart = bColumnStart + nVaryingB*_paramDimensionB;
+
+ int const nCols = _JtJ.num_cols();
+ int const nnz = _JtJ.getNonzeroCount();
+
+ // The following has to replicate the procedure as in serializeNonZerosJtJ()
+
+ int serial = 0;
+
+ double * values = _JtJ.getValues();
+ int const * destIdxs = _JtJ.getDestIndices();
+
+ // Add the diagonal block matrices (only the upper triangular part).
+
+ // Ui submatrices of JtJ
+ for (int i = 0; i < nVaryingA; ++i)
+ {
+ int const i0 = i * _paramDimensionA;
+
+ for (int c = 0; c < _paramDimensionA; ++c)
+ for (int r = 0; r <= c; ++r, ++serial)
+ values[destIdxs[serial]] = Ui[i][r][c];
+ }
+
+ // Vj submatrices of JtJ
+ for (int j = 0; j < nVaryingB; ++j)
+ {
+ int const j0 = j*_paramDimensionB + bColumnStart;
+
+ for (int c = 0; c < _paramDimensionB; ++c)
+ for (int r = 0; r <= c; ++r, ++serial)
+ values[destIdxs[serial]] = Vj[j][r][c];
+ }
+
+ // Z submatrix of JtJ
+ for (int c = 0; c < nVaryingC; ++c)
+ for (int r = 0; r <= c; ++r, ++serial)
+ values[destIdxs[serial]] = Z[r][c];
+
+ // Add the elements i and j linked by an observation k
+ // W submatrix of JtJ
+ for (size_t n = 0; n < _jointNonzerosW.size(); ++n)
+ {
+ for (int r = 0; r < _paramDimensionA; ++r)
+ for (int c = 0; c < _paramDimensionB; ++c, ++serial)
+ values[destIdxs[serial]] = Wn[n][r][c];
+ } // end for (k)
+
+ if (nVaryingC > 0)
+ {
+ // Finally, add the dense columns linking i (resp. j) with the global parameters.
+ // X submatrix of JtJ
+ for (int i = 0; i < nVaryingA; ++i)
+ {
+ int const r0 = i * _paramDimensionA;
+ for (int r = 0; r < _paramDimensionA; ++r)
+ for (int c = 0; c < nVaryingC; ++c, ++serial)
+ values[destIdxs[serial]] = X[r0+r][c];
+ }
+
+ // Y submatrix of JtJ
+ for (int j = 0; j < nVaryingB; ++j)
+ {
+ int const r0 = j * _paramDimensionB;
+ for (int r = 0; r < _paramDimensionB; ++r)
+ for (int c = 0; c < nVaryingC; ++c, ++serial)
+ values[destIdxs[serial]] = Y[r0+r][c];
+ }
+ } // end if
+ } // end SparseLevenbergOptimizer::fillSparseJtJ()
+
+ void
+ SparseLevenbergOptimizer::minimize()
+ {
+ status = LEVENBERG_OPTIMIZER_TIMEOUT;
+ bool computeDerivatives = true;
+
+ int const nVaryingA = _nParametersA - _nNonvaryingA;
+ int const nVaryingB = _nParametersB - _nNonvaryingB;
+ int const nVaryingC = _paramDimensionC - _nNonvaryingC;
+
+ if (nVaryingA == 0 && nVaryingB == 0 && nVaryingC == 0)
+ {
+ // No degrees of freedom, nothing to optimize.
+ status = LEVENBERG_OPTIMIZER_CONVERGED;
+ return;
+ }
+
+ this->setupSparseJtJ();
+
+ Vector<double> weights(_nMeasurements);
+
+ MatrixArray<double> Ak(_nMeasurements, _measurementDimension, _paramDimensionA);
+ MatrixArray<double> Bk(_nMeasurements, _measurementDimension, _paramDimensionB);
+ MatrixArray<double> Ck(_nMeasurements, _measurementDimension, _paramDimensionC);
+
+ MatrixArray<double> Ui(nVaryingA, _paramDimensionA, _paramDimensionA);
+ MatrixArray<double> Vj(nVaryingB, _paramDimensionB, _paramDimensionB);
+
+ // Wn = Ak^t*Bk
+ MatrixArray<double> Wn(_jointNonzerosW.size(), _paramDimensionA, _paramDimensionB);
+
+ Matrix<double> Z(nVaryingC, nVaryingC);
+
+ // X = A^t*C
+ Matrix<double> X(nVaryingA*_paramDimensionA, nVaryingC);
+ // Y = B^t*C
+ Matrix<double> Y(nVaryingB*_paramDimensionB, nVaryingC);
+
+ VectorArray<double> residuals(_nMeasurements, _measurementDimension);
+ VectorArray<double> residuals2(_nMeasurements, _measurementDimension);
+
+ VectorArray<double> diagUi(nVaryingA, _paramDimensionA);
+ VectorArray<double> diagVj(nVaryingB, _paramDimensionB);
+ Vector<double> diagZ(nVaryingC);
+
+ VectorArray<double> At_e(nVaryingA, _paramDimensionA);
+ VectorArray<double> Bt_e(nVaryingB, _paramDimensionB);
+ Vector<double> Ct_e(nVaryingC);
+
+ Vector<double> Jt_e(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC);
+
+ Vector<double> delta(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC);
+ Vector<double> deltaPerm(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC);
+
+ VectorArray<double> deltaAi(_nParametersA, _paramDimensionA);
+ VectorArray<double> deltaBj(_nParametersB, _paramDimensionB);
+ Vector<double> deltaC(_paramDimensionC);
+
+ double err = 0.0;
+
+ for (currentIteration = 0; currentIteration < maxIterations; ++currentIteration)
+ {
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: currentIteration: " << currentIteration << endl;
+ if (computeDerivatives)
+ {
+ this->evalResidual(residuals);
+ this->fillWeights(residuals, weights);
+ for (int k = 0; k < _nMeasurements; ++k)
+ scaleVectorIP(weights[k], residuals[k]);
+
+ err = squaredResidual(residuals);
+
+ if (optimizerVerbosenessLevel >= 1) cout << "SparseLevenbergOptimizer: |residual|^2 = " << err << endl;
+ if (optimizerVerbosenessLevel >= 2) cout << "SparseLevenbergOptimizer: lambda = " << lambda << endl;
+
+ for (int k = 0; k < residuals.count(); ++k) scaleVectorIP(-1.0, residuals[k]);
+
+ this->setupJacobianGathering();
+ this->fillAllJacobians(weights, Ak, Bk, Ck);
+
+ // Compute the different parts of J^t*e
+ if (nVaryingA > 0)
+ {
+ for (int i = 0; i < nVaryingA; ++i) makeZeroVector(At_e[i]);
+
+ Vector<double> tmp(_paramDimensionA);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const i = _correspondingParamA[k] - _nNonvaryingA;
+ if (i < 0) continue;
+ multiply_At_v(Ak[k], residuals[k], tmp);
+ addVectors(tmp, At_e[i], At_e[i]);
+ } // end for (k)
+ } // end if
+
+ if (nVaryingB > 0)
+ {
+ for (int j = 0; j < nVaryingB; ++j) makeZeroVector(Bt_e[j]);
+
+ Vector<double> tmp(_paramDimensionB);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const j = _correspondingParamB[k] - _nNonvaryingB;
+ if (j < 0) continue;
+ multiply_At_v(Bk[k], residuals[k], tmp);
+ addVectors(tmp, Bt_e[j], Bt_e[j]);
+ } // end for (k)
+ } // end if
+
+ if (nVaryingC > 0)
+ {
+ makeZeroVector(Ct_e);
+
+ Vector<double> tmp(_paramDimensionC);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ multiply_At_v(Ck[k], residuals[k], tmp);
+ for (int l = 0; l < nVaryingC; ++l) Ct_e[l] += tmp[_nNonvaryingC + l];
+ }
+ } // end if
+
+ int pos = 0;
+ for (int i = 0; i < nVaryingA; ++i)
+ for (int l = 0; l < _paramDimensionA; ++l, ++pos)
+ Jt_e[pos] = At_e[i][l];
+ for (int j = 0; j < nVaryingB; ++j)
+ for (int l = 0; l < _paramDimensionB; ++l, ++pos)
+ Jt_e[pos] = Bt_e[j][l];
+ for (int l = 0; l < nVaryingC; ++l, ++pos)
+ Jt_e[pos] = Ct_e[l];
+
+// cout << "Jt_e = ";
+// for (int k = 0; k < Jt_e.size(); ++k) cout << Jt_e[k] << " ";
+// cout << endl;
+
+ if (this->applyGradientStoppingCriteria(norm_Linf(Jt_e)))
+ {
+ status = LEVENBERG_OPTIMIZER_CONVERGED;
+ goto end;
+ }
+
+ // The lhs J^t*J consists of several parts:
+ // [ U W X ]
+ // J^t*J = [ W^t V Y ]
+ // [ X^t Y^t Z ],
+ // where U, V and W are block-sparse matrices (due to the sparsity of A and B).
+ // X, Y and Z contain only a few columns (the number of global parameters).
+
+ if (nVaryingA > 0)
+ {
+ // Compute Ui
+ Matrix<double> U(_paramDimensionA, _paramDimensionA);
+
+ for (int i = 0; i < nVaryingA; ++i) makeZeroMatrix(Ui[i]);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const i = _correspondingParamA[k] - _nNonvaryingA;
+ if (i < 0) continue;
+ multiply_At_A(Ak[k], U);
+ addMatricesIP(U, Ui[i]);
+ } // end for (k)
+ } // end if
+
+ if (nVaryingB > 0)
+ {
+ // Compute Vj
+ Matrix<double> V(_paramDimensionB, _paramDimensionB);
+
+ for (int j = 0; j < nVaryingB; ++j) makeZeroMatrix(Vj[j]);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const j = _correspondingParamB[k] - _nNonvaryingB;
+ if (j < 0) continue;
+ multiply_At_A(Bk[k], V);
+ addMatricesIP(V, Vj[j]);
+ } // end for (k)
+ } // end if
+
+ if (nVaryingC > 0)
+ {
+ Matrix<double> ZZ(_paramDimensionC, _paramDimensionC);
+ Matrix<double> Zsum(_paramDimensionC, _paramDimensionC);
+
+ makeZeroMatrix(Zsum);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ multiply_At_A(Ck[k], ZZ);
+ addMatricesIP(ZZ, Zsum);
+ } // end for (k)
+
+ // Ignore the non-varying parameters
+ for (int i = 0; i < nVaryingC; ++i)
+ for (int j = 0; j < nVaryingC; ++j)
+ Z[i][j] = Zsum[i+_nNonvaryingC][j+_nNonvaryingC];
+ } // end if
+
+ if (nVaryingA > 0 && nVaryingB > 0)
+ {
+ for (int n = 0; n < Wn.count(); ++n) makeZeroMatrix(Wn[n]);
+
+ Matrix<double> W(_paramDimensionA, _paramDimensionB);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const n = _jointIndexW[k];
+ if (n >= 0)
+ {
+ int const i0 = _jointNonzerosW[n].first;
+ int const j0 = _jointNonzerosW[n].second;
+
+ multiply_At_B(Ak[k], Bk[k], W);
+ addMatricesIP(W, Wn[n]);
+ } // end if
+ } // end for (k)
+ } // end if
+
+ if (nVaryingA > 0 && nVaryingC > 0)
+ {
+ Matrix<double> XX(_paramDimensionA, _paramDimensionC);
+
+ makeZeroMatrix(X);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const i = _correspondingParamA[k] - _nNonvaryingA;
+ // Ignore the non-varying parameters
+ if (i < 0) continue;
+
+ multiply_At_B(Ak[k], Ck[k], XX);
+
+ for (int r = 0; r < _paramDimensionA; ++r)
+ for (int c = 0; c < nVaryingC; ++c)
+ X[r+i*_paramDimensionA][c] += XX[r][c+_nNonvaryingC];
+ } // end for (k)
+ } // end if
+
+ if (nVaryingB > 0 && nVaryingC > 0)
+ {
+ Matrix<double> YY(_paramDimensionB, _paramDimensionC);
+
+ makeZeroMatrix(Y);
+
+ for (int k = 0; k < _nMeasurements; ++k)
+ {
+ int const j = _correspondingParamB[k] - _nNonvaryingB;
+ // Ignore the non-varying parameters
+ if (j < 0) continue;
+
+ multiply_At_B(Bk[k], Ck[k], YY);
+
+ for (int r = 0; r < _paramDimensionB; ++r)
+ for (int c = 0; c < nVaryingC; ++c)
+ Y[r+j*_paramDimensionB][c] += YY[r][c+_nNonvaryingC];
+ } // end for (k)
+ } // end if
+
+ if (currentIteration == 0)
+ {
+ // Initialize lambda as tau*max(JtJ[i][i])
+ double maxEl = -1e30;
+ if (nVaryingA > 0)
+ {
+ for (int i = 0; i < nVaryingA; ++i)
+ for (int l = 0; l < _paramDimensionA; ++l)
+ maxEl = std::max(maxEl, Ui[i][l][l]);
+ }
+ if (nVaryingB > 0)
+ {
+ for (int j = 0; j < nVaryingB; ++j)
+ for (int l = 0; l < _paramDimensionB; ++l)
+ maxEl = std::max(maxEl, Vj[j][l][l]);
+ }
+ if (nVaryingC > 0)
+ {
+ for (int l = 0; l < nVaryingC; ++l)
+ maxEl = std::max(maxEl, Z[l][l]);
+ }
+
+ lambda = tau * maxEl;
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: initial lambda = " << lambda << endl;
+ } // end if (currentIteration == 0)
+ } // end if (computeDerivatives)
+
+ for (int i = 0; i < nVaryingA; ++i)
+ {
+ for (int l = 0; l < _paramDimensionA; ++l) diagUi[i][l] = Ui[i][l][l];
+ } // end for (i)
+
+ for (int j = 0; j < nVaryingB; ++j)
+ {
+ for (int l = 0; l < _paramDimensionB; ++l) diagVj[j][l] = Vj[j][l][l];
+ } // end for (j)
+
+ for (int l = 0; l < nVaryingC; ++l) diagZ[l] = Z[l][l];
+
+ // Augment the diagonals with lambda (either by the standard additive update or by multiplication).
+#if !defined(USE_MULTIPLICATIVE_UPDATE)
+ for (int i = 0; i < nVaryingA; ++i)
+ for (unsigned l = 0; l < _paramDimensionA; ++l)
+ Ui[i][l][l] += lambda;
+
+ for (int j = 0; j < nVaryingB; ++j)
+ for (unsigned l = 0; l < _paramDimensionB; ++l)
+ Vj[j][l][l] += lambda;
+
+ for (unsigned l = 0; l < nVaryingC; ++l)
+ Z[l][l] += lambda;
+#else
+ for (int i = 0; i < nVaryingA; ++i)
+ for (unsigned l = 0; l < _paramDimensionA; ++l)
+ Ui[i][l][l] = std::max(Ui[i][l][l] * (1.0 + lambda), 1e-15);
+
+ for (int j = 0; j < nVaryingB; ++j)
+ for (unsigned l = 0; l < _paramDimensionB; ++l)
+ Vj[j][l][l] = std::max(Vj[j][l][l] * (1.0 + lambda), 1e-15);
+
+ for (unsigned l = 0; l < nVaryingC; ++l)
+ Z[l][l] = std::max(Z[l][l] * (1.0 + lambda), 1e-15);
+#endif
+
+ this->fillSparseJtJ(Ui, Vj, Wn, Z, X, Y);
+
+ bool success = true;
+ double rho = 0.0;
+ {
+ int const nCols = _JtJ_Parent.size();
+ int const nnz = _JtJ.getNonzeroCount();
+ int const lnz = _JtJ_Lp.back();
+
+ vector<int> Li(lnz);
+ vector<double> Lx(lnz);
+ vector<double> D(nCols), Y(nCols);
+ vector<int> workPattern(nCols), workFlag(nCols);
+
+ int * colStarts = (int *)_JtJ.getColumnStarts();
+ int * rowIdxs = (int *)_JtJ.getRowIndices();
+ double * values = _JtJ.getValues();
+
+ int const d = ldl_numeric(nCols, colStarts, rowIdxs, values,
+ &_JtJ_Lp[0], &_JtJ_Parent[0], &_JtJ_Lnz[0],
+ &Li[0], &Lx[0], &D[0],
+ &Y[0], &workPattern[0], &workFlag[0],
+ NULL, NULL);
+
+ if (d == nCols)
+ {
+ ldl_perm(nCols, &deltaPerm[0], &Jt_e[0], &_perm_JtJ[0]);
+ ldl_lsolve(nCols, &deltaPerm[0], &_JtJ_Lp[0], &Li[0], &Lx[0]);
+ ldl_dsolve(nCols, &deltaPerm[0], &D[0]);
+ ldl_ltsolve(nCols, &deltaPerm[0], &_JtJ_Lp[0], &Li[0], &Lx[0]);
+ ldl_permt(nCols, &delta[0], &deltaPerm[0], &_perm_JtJ[0]);
+ }
+ else
+ {
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: LDL decomposition failed. Increasing lambda." << endl;
+ success = false;
+ }
+ }
+
+ if (success)
+ {
+ double const deltaSqrLength = sqrNorm_L2(delta);
+
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: ||delta||^2 = " << deltaSqrLength << endl;
+
+ double const paramLength = this->getParameterLength();
+ if (this->applyUpdateStoppingCriteria(paramLength, sqrt(deltaSqrLength)))
+ {
+ status = LEVENBERG_OPTIMIZER_SMALL_UPDATE;
+ goto end;
+ }
+
+ // Copy the updates from delta to the respective arrays
+ int pos = 0;
+
+ for (int i = 0; i < _nNonvaryingA; ++i) makeZeroVector(deltaAi[i]);
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ for (int l = 0; l < _paramDimensionA; ++l, ++pos)
+ deltaAi[i][l] = delta[pos];
+
+ for (int j = 0; j < _nNonvaryingB; ++j) makeZeroVector(deltaBj[j]);
+ for (int j = _nNonvaryingB; j < _nParametersB; ++j)
+ for (int l = 0; l < _paramDimensionB; ++l, ++pos)
+ deltaBj[j][l] = delta[pos];
+
+ makeZeroVector(deltaC);
+ for (int l = _nNonvaryingC; l < _paramDimensionC; ++l, ++pos)
+ deltaC[l] = delta[pos];
+
+ saveAllParameters();
+ if (nVaryingA > 0) updateParametersA(deltaAi);
+ if (nVaryingB > 0) updateParametersB(deltaBj);
+ if (nVaryingC > 0) updateParametersC(deltaC);
+
+ this->evalResidual(residuals2);
+ for (int k = 0; k < _nMeasurements; ++k)
+ scaleVectorIP(weights[k], residuals2[k]);
+
+ double const newErr = squaredResidual(residuals2);
+ rho = err - newErr;
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: |new residual|^2 = " << newErr << endl;
+
+#if !defined(USE_MULTIPLICATIVE_UPDATE)
+ double const denom1 = lambda * deltaSqrLength;
+#else
+ double denom1 = 0.0f;
+ for (int i = _nNonvaryingA; i < _nParametersA; ++i)
+ for (int l = 0; l < _paramDimensionA; ++l)
+ denom1 += deltaAi[i][l] * deltaAi[i][l] * diagUi[i-_nNonvaryingA][l];
+
+ for (int j = _nNonvaryingB; j < _nParametersB; ++j)
+ for (int l = 0; l < _paramDimensionB; ++l)
+ denom1 += deltaBj[j][l] * deltaBj[j][l] * diagVj[j-_nNonvaryingB][l];
+
+ for (int l = _nNonvaryingC; l < _paramDimensionC; ++l)
+ denom1 += deltaC[l] * deltaC[l] * diagZ[l-_nNonvaryingC];
+
+ denom1 *= lambda;
+#endif
+ double const denom2 = innerProduct(delta, Jt_e);
+ rho = rho / (denom1 + denom2);
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: rho = " << rho
+ << " denom1 = " << denom1 << " denom2 = " << denom2 << endl;
+ } // end if (success)
+
+ if (success && rho > 0)
+ {
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: Improved solution - decreasing lambda." << endl;
+ // Improvement in the new solution
+ decreaseLambda(rho);
+ computeDerivatives = true;
+ }
+ else
+ {
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "SparseLevenbergOptimizer: Inferior solution - increasing lambda." << endl;
+ restoreAllParameters();
+ increaseLambda();
+ computeDerivatives = false;
+
+ // Restore diagonal elements in Ui, Vj and Z.
+ for (int i = 0; i < nVaryingA; ++i)
+ {
+ for (int l = 0; l < _paramDimensionA; ++l) Ui[i][l][l] = diagUi[i][l];
+ } // end for (i)
+
+ for (int j = 0; j < nVaryingB; ++j)
+ {
+ for (int l = 0; l < _paramDimensionB; ++l) Vj[j][l][l] = diagVj[j][l];
+ } // end for (j)
+
+ for (int l = 0; l < nVaryingC; ++l) Z[l][l] = diagZ[l];
+ } // end if
+ } // end for
+
+ end:;
+ if (optimizerVerbosenessLevel >= 2)
+ cout << "Leaving SparseLevenbergOptimizer::minimize()." << endl;
+ } // end SparseLevenbergOptimizer::minimize()
+
+#endif // defined(V3DLIB_ENABLE_SUITESPARSE)
+
+} // end namespace V3D
diff --git a/extern/libmv/third_party/ssba/Math/v3d_optimization.h b/extern/libmv/third_party/ssba/Math/v3d_optimization.h
new file mode 100644
index 00000000000..27d2e12287f
--- /dev/null
+++ b/extern/libmv/third_party/ssba/Math/v3d_optimization.h
@@ -0,0 +1,273 @@
+// -*- C++ -*-
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef V3D_OPTIMIZATION_H
+#define V3D_OPTIMIZATION_H
+
+#include "Math/v3d_linear.h"
+#include "Math/v3d_mathutilities.h"
+
+#include <vector>
+#include <iostream>
+
+namespace V3D
+{
+
+ enum
+ {
+ LEVENBERG_OPTIMIZER_TIMEOUT = 0,
+ LEVENBERG_OPTIMIZER_SMALL_UPDATE = 1,
+ LEVENBERG_OPTIMIZER_CONVERGED = 2
+ };
+
+ extern int optimizerVerbosenessLevel;
+
+ struct LevenbergOptimizerCommon
+ {
+ LevenbergOptimizerCommon()
+ : status(LEVENBERG_OPTIMIZER_TIMEOUT), currentIteration(0), maxIterations(50),
+ tau(1e-3), lambda(1e-3),
+ gradientThreshold(1e-10), updateThreshold(1e-10),
+ _nu(2.0)
+ { }
+ virtual ~LevenbergOptimizerCommon() {}
+
+ // See Madsen et al., "Methods for non-linear least squares problems."
+ virtual void increaseLambda()
+ {
+ lambda *= _nu; _nu *= 2.0;
+ }
+
+ virtual void decreaseLambda(double const rho)
+ {
+ double const r = 2*rho - 1.0;
+ lambda *= std::max(1.0/3.0, 1 - r*r*r);
+ if (lambda < 1e-10) lambda = 1e-10;
+ _nu = 2;
+ }
+
+ bool applyGradientStoppingCriteria(double maxGradient) const
+ {
+ return maxGradient < gradientThreshold;
+ }
+
+ bool applyUpdateStoppingCriteria(double paramLength, double updateLength) const
+ {
+ return updateLength < updateThreshold * (paramLength + updateThreshold);
+ }
+
+ int status;
+ int currentIteration, maxIterations;
+ double tau, lambda;
+ double gradientThreshold, updateThreshold;
+
+ protected:
+ double _nu;
+ }; // end struct LevenbergOptimizerCommon
+
+# if defined(V3DLIB_ENABLE_SUITESPARSE)
+
+ struct SparseLevenbergOptimizer : public LevenbergOptimizerCommon
+ {
+ SparseLevenbergOptimizer(int measurementDimension,
+ int nParametersA, int paramDimensionA,
+ int nParametersB, int paramDimensionB,
+ int paramDimensionC,
+ std::vector<int> const& correspondingParamA,
+ std::vector<int> const& correspondingParamB)
+ : LevenbergOptimizerCommon(),
+ _nMeasurements(correspondingParamA.size()),
+ _measurementDimension(measurementDimension),
+ _nParametersA(nParametersA), _paramDimensionA(paramDimensionA),
+ _nParametersB(nParametersB), _paramDimensionB(paramDimensionB),
+ _paramDimensionC(paramDimensionC),
+ _nNonvaryingA(0), _nNonvaryingB(0), _nNonvaryingC(0),
+ _correspondingParamA(correspondingParamA),
+ _correspondingParamB(correspondingParamB)
+ {
+ assert(correspondingParamA.size() == correspondingParamB.size());
+ }
+
+ ~SparseLevenbergOptimizer() { }
+
+ void setNonvaryingCounts(int nNonvaryingA, int nNonvaryingB, int nNonvaryingC)
+ {
+ _nNonvaryingA = nNonvaryingA;
+ _nNonvaryingB = nNonvaryingB;
+ _nNonvaryingC = nNonvaryingC;
+ }
+
+ void getNonvaryingCounts(int& nNonvaryingA, int& nNonvaryingB, int& nNonvaryingC) const
+ {
+ nNonvaryingA = _nNonvaryingA;
+ nNonvaryingB = _nNonvaryingB;
+ nNonvaryingC = _nNonvaryingC;
+ }
+
+ void minimize();
+
+ virtual void evalResidual(VectorArray<double>& residuals) = 0;
+
+ virtual void fillWeights(VectorArray<double> const& residuals, Vector<double>& w)
+ {
+ (void)residuals;
+ std::fill(w.begin(), w.end(), 1.0);
+ }
+
+ void fillAllJacobians(Vector<double> const& w,
+ MatrixArray<double>& Ak,
+ MatrixArray<double>& Bk,
+ MatrixArray<double>& Ck)
+ {
+ int const nVaryingA = _nParametersA - _nNonvaryingA;
+ int const nVaryingB = _nParametersB - _nNonvaryingB;
+ int const nVaryingC = _paramDimensionC - _nNonvaryingC;
+
+ for (unsigned k = 0; k < _nMeasurements; ++k)
+ {
+ int const i = _correspondingParamA[k];
+ int const j = _correspondingParamB[k];
+
+ if (i < _nNonvaryingA && j < _nNonvaryingB) continue;
+
+ fillJacobians(Ak[k], Bk[k], Ck[k], i, j, k);
+ } // end for (k)
+
+ if (nVaryingA > 0)
+ {
+ for (unsigned k = 0; k < _nMeasurements; ++k)
+ scaleMatrixIP(w[k], Ak[k]);
+ }
+ if (nVaryingB > 0)
+ {
+ for (unsigned k = 0; k < _nMeasurements; ++k)
+ scaleMatrixIP(w[k], Bk[k]);
+ }
+ if (nVaryingC > 0)
+ {
+ for (unsigned k = 0; k < _nMeasurements; ++k)
+ scaleMatrixIP(w[k], Ck[k]);
+ }
+ } // end fillAllJacobians()
+
+ virtual void setupJacobianGathering() { }
+
+ virtual void fillJacobians(Matrix<double>& Ak, Matrix<double>& Bk, Matrix<double>& Ck,
+ int i, int j, int k) = 0;
+
+ virtual double getParameterLength() const = 0;
+
+ virtual void updateParametersA(VectorArray<double> const& deltaAi) = 0;
+ virtual void updateParametersB(VectorArray<double> const& deltaBj) = 0;
+ virtual void updateParametersC(Vector<double> const& deltaC) = 0;
+ virtual void saveAllParameters() = 0;
+ virtual void restoreAllParameters() = 0;
+
+ int currentIteration, maxIterations;
+
+ protected:
+ void serializeNonZerosJtJ(std::vector<std::pair<int, int> >& dst) const;
+ void setupSparseJtJ();
+ void fillSparseJtJ(MatrixArray<double> const& Ui, MatrixArray<double> const& Vj, MatrixArray<double> const& Wk,
+ Matrix<double> const& Z, Matrix<double> const& X, Matrix<double> const& Y);
+
+ int const _nMeasurements, _measurementDimension;
+ int const _nParametersA, _paramDimensionA;
+ int const _nParametersB, _paramDimensionB;
+ int const _paramDimensionC;
+
+ int _nNonvaryingA, _nNonvaryingB, _nNonvaryingC;
+
+ std::vector<int> const& _correspondingParamA;
+ std::vector<int> const& _correspondingParamB;
+
+ std::vector<pair<int, int> > _jointNonzerosW;
+ std::vector<int> _jointIndexW;
+
+ std::vector<int> _JtJ_Lp, _JtJ_Parent, _JtJ_Lnz;
+ std::vector<int> _perm_JtJ, _invPerm_JtJ;
+
+ CCS_Matrix<double> _JtJ;
+ }; // end struct SparseLevenbergOptimizer
+
+ struct StdSparseLevenbergOptimizer : public SparseLevenbergOptimizer
+ {
+ StdSparseLevenbergOptimizer(int measurementDimension,
+ int nParametersA, int paramDimensionA,
+ int nParametersB, int paramDimensionB,
+ int paramDimensionC,
+ std::vector<int> const& correspondingParamA,
+ std::vector<int> const& correspondingParamB)
+ : SparseLevenbergOptimizer(measurementDimension, nParametersA, paramDimensionA,
+ nParametersB, paramDimensionB, paramDimensionC,
+ correspondingParamA, correspondingParamB),
+ curParametersA(nParametersA, paramDimensionA), savedParametersA(nParametersA, paramDimensionA),
+ curParametersB(nParametersB, paramDimensionB), savedParametersB(nParametersB, paramDimensionB),
+ curParametersC(paramDimensionC), savedParametersC(paramDimensionC)
+ { }
+
+ virtual double getParameterLength() const
+ {
+ double res = 0.0;
+ for (int i = 0; i < _nParametersA; ++i) res += sqrNorm_L2(curParametersA[i]);
+ for (int j = 0; j < _nParametersB; ++j) res += sqrNorm_L2(curParametersB[j]);
+ res += sqrNorm_L2(curParametersC);
+ return sqrt(res);
+ }
+
+ virtual void updateParametersA(VectorArray<double> const& deltaAi)
+ {
+ for (int i = 0; i < _nParametersA; ++i) addVectors(deltaAi[i], curParametersA[i], curParametersA[i]);
+ }
+
+ virtual void updateParametersB(VectorArray<double> const& deltaBj)
+ {
+ for (int j = 0; j < _nParametersB; ++j) addVectors(deltaBj[j], curParametersB[j], curParametersB[j]);
+ }
+
+ virtual void updateParametersC(Vector<double> const& deltaC)
+ {
+ addVectors(deltaC, curParametersC, curParametersC);
+ }
+
+ virtual void saveAllParameters()
+ {
+ for (int i = 0; i < _nParametersA; ++i) savedParametersA[i] = curParametersA[i];
+ for (int j = 0; j < _nParametersB; ++j) savedParametersB[j] = curParametersB[j];
+ savedParametersC = curParametersC;
+ }
+
+ virtual void restoreAllParameters()
+ {
+ for (int i = 0; i < _nParametersA; ++i) curParametersA[i] = savedParametersA[i];
+ for (int j = 0; j < _nParametersB; ++j) curParametersB[j] = savedParametersB[j];
+ curParametersC = savedParametersC;
+ }
+
+ VectorArray<double> curParametersA, savedParametersA;
+ VectorArray<double> curParametersB, savedParametersB;
+ Vector<double> curParametersC, savedParametersC;
+ }; // end struct StdSparseLevenbergOptimizer
+
+# endif
+
+} // end namespace V3D
+
+#endif
diff --git a/extern/libmv/third_party/ssba/README.TXT b/extern/libmv/third_party/ssba/README.TXT
new file mode 100644
index 00000000000..734962b1df8
--- /dev/null
+++ b/extern/libmv/third_party/ssba/README.TXT
@@ -0,0 +1,92 @@
+Description
+
+This is an implementation of a sparse Levenberg-Marquardt optimization
+procedure and several bundle adjustment modules based on it. There are three
+versions of bundle adjustment:
+1) Pure metric adjustment. Camera poses have 6 dof and 3D points have 3 dof.
+2) Common, but adjustable intrinsic and distortion parameters. This is useful,
+ if the set of images are taken with the same camera under constant zoom
+ settings.
+3) Variable intrinsics and distortion parameters for each view. This addresses
+ the "community photo collection" setting, where each image is captured with
+ a different camera and/or with varying zoom setting.
+
+There are two demo applications in the Apps directory, bundle_common and
+bundle_varying, which correspond to item 2) and 3) above.
+
+The input data file for both applications is a text file with the following
+numerical values:
+
+First, the number of 3D points, views and 2D measurements:
+<M> <N> <K>
+Then, the values of the intrinsic matrix
+ [ fx skew cx ]
+K = [ 0 fy cy ]
+ [ 0 0 1 ],
+and the distortion parameters according to the convention of the Bouget
+toolbox:
+
+ <fx> <skew> <cx> <fy> <cy> <k1> <k2> <p1> <p2>
+
+For the bundle_varying application this is given <N> times, one for each
+camera/view.
+Then the <M> 3D point positions are given:
+
+ <point-id> <X> <Y> <Z>
+
+Note: the point-ids need not to be exactly from 0 to M-1, any (unique) ids
+will do.
+The camera poses are given subsequently:
+
+ <view-id> <12 entries of the RT matrix>
+
+There is a lot of confusion how to specify the orientation of cameras. We use
+projection matrix notation, i.e. P = K [R|T], and a 3D point X in world
+coordinates is transformed into the camera coordinate system by XX=R*X+T.
+
+Finally, the <K> 2d image measurements (given in pixels) are provided:
+
+ <view-id> <point-id> <x> <y> 1
+
+See the example in the Dataset folder.
+
+
+Performance
+
+This software is able to perform successful loop closing for a video sequence
+containing 1745 views, 37920 3D points and 627228 image measurements in about
+16min on a 2.2 GHz Core 2. The footprint in memory was <700MB.
+
+
+Requirements
+
+Solving the augmented normal equation in the LM optimizer is done with LDL, a
+Cholsky like decomposition method for sparse matrices (see
+http://www.cise.ufl.edu/research/sparse/ldl). The appropriate column
+reordering is done with COLAMD (see
+http://www.cise.ufl.edu/research/sparse/colamd). Both packages are licensed
+under the GNU LGPL.
+
+This software was developed under Linux, but should compile equally well on
+other operating systems.
+
+-Christopher Zach (cmzach@cs.unc.edu)
+
+/*
+Copyright (c) 2008 University of North Carolina at Chapel Hill
+
+This file is part of SSBA (Simple Sparse Bundle Adjustment).
+
+SSBA is free software: you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+SSBA is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with SSBA. If not, see <http://www.gnu.org/licenses/>.
+*/
diff --git a/extern/libmv/third_party/ssba/README.libmv b/extern/libmv/third_party/ssba/README.libmv
new file mode 100755
index 00000000000..45e0a31f6fc
--- /dev/null
+++ b/extern/libmv/third_party/ssba/README.libmv
@@ -0,0 +1,23 @@
+Project: SSBA
+URL: http://www.cs.unc.edu/~cmzach/opensource.html
+License: LGPL3
+Upstream version: 1.0
+
+Local modifications:
+
+ * Added
+ SET(CMAKE_CXX_FLAGS "")
+ to CMakeLists.txt to prevent warnings from being treated as errors.
+ * Fixed "unused variable" in the header files. Warnings in the cpps files
+ are still there.
+ * Fixed a bug in CameraMatrix::opticalAxis() in file
+ Geometry/v3d_cameramatrix.h
+ * Deleted the Dataset directory.
+ * Added '#include <string>' to ssba/Apps/bundle_common.cpp and
+ ssba/Apps/bundle_varying.cpp to stop undefined references to strcmp
+ * Removed unnecessary elements from the CMakeLists.txt file, including the
+ obsoleted local_config.cmake and friends.
+ * Added a virtual destructor to V3D::LevenbergOptimizerCommon in
+ Math/v3d_optimization.h
+ * Added /EHsc WIN32-specific flag to CMakeLists.txt
+ * Remove unused variable Vector3d np in bundle_common.cpp and bundle_varying (in main() function).
diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png
index a68a1f8394c..c309ad11da2 100644
--- a/release/datafiles/blender_icons.png
+++ b/release/datafiles/blender_icons.png
Binary files differ
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 382a47cb4e6..d01b706cc37 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -208,7 +208,7 @@ class BPyOpsSubModOp(object):
return "# %s\n%s" % (descr, as_string)
def __str__(self): # used for print(...)
- return "<function bpy.ops.%s.%s at 0x%x'>" % \
- (self.module, self.func, id(self))
+ return ("<function bpy.ops.%s.%s at 0x%x'>" %
+ (self.module, self.func, id(self)))
ops_fake_module = BPyOps()
diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py
index 6eb19c0ff05..fab6886b314 100644
--- a/release/scripts/modules/bpy_extras/keyconfig_utils.py
+++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py
@@ -92,6 +92,10 @@ KM_HIERARCHY = [
('Script', 'SCRIPTS_WINDOW', 'WINDOW', []),
('Text', 'TEXT_EDITOR', 'WINDOW', []),
('Console', 'CONSOLE', 'WINDOW', []),
+ ('Clip', 'CLIP_EDITOR', 'WINDOW', [
+ ('Clip Editor', 'CLIP_EDITOR', 'WINDOW', []),
+ ('Clip Graph Editor', 'CLIP_EDITOR', 'WINDOW', []),
+ ]),
('View3D Gesture Circle', 'EMPTY', 'WINDOW', []),
('Gesture Border', 'EMPTY', 'WINDOW', []),
diff --git a/release/scripts/modules/bpyml_ui.py b/release/scripts/modules/bpyml_ui.py
index f4b6de23dbb..4828b3649d3 100644
--- a/release/scripts/modules/bpyml_ui.py
+++ b/release/scripts/modules/bpyml_ui.py
@@ -25,9 +25,11 @@ from bpyml import TAG, ARGS, CHILDREN
_uilayout_rna = _bpy.types.UILayout.bl_rna
-_uilayout_tags = ["ui"] + \
- _uilayout_rna.properties.keys() + \
+_uilayout_tags = (
+ ["ui"] +
+ _uilayout_rna.properties.keys() +
_uilayout_rna.functions.keys()
+ )
# these need to be imported directly
# >>> from bpyml_ui.locals import *
diff --git a/release/scripts/presets/tracking_camera/Blender.py b/release/scripts/presets/tracking_camera/Blender.py
new file mode 100644
index 00000000000..507cedac4fc
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Blender.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 32.0
+camera.units = 'MILLIMETERS'
+camera.focal_length = 35.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_1100D.py b/release/scripts/presets/tracking_camera/Canon_1100D.py
new file mode 100644
index 00000000000..7ea78412f40
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_1100D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.2
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_1D.py b/release/scripts/presets/tracking_camera/Canon_1D.py
new file mode 100644
index 00000000000..89590d3cc19
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_1D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 27.9
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_1DS.py b/release/scripts/presets/tracking_camera/Canon_1DS.py
new file mode 100644
index 00000000000..7d9b6c8b390
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_1DS.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 36.0
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_500D.py b/release/scripts/presets/tracking_camera/Canon_500D.py
new file mode 100644
index 00000000000..3dd66c5b609
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_500D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.3
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_550D.py b/release/scripts/presets/tracking_camera/Canon_550D.py
new file mode 100644
index 00000000000..3dd66c5b609
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_550D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.3
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_5D.py b/release/scripts/presets/tracking_camera/Canon_5D.py
new file mode 100644
index 00000000000..7d9b6c8b390
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_5D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 36.0
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_600D.py b/release/scripts/presets/tracking_camera/Canon_600D.py
new file mode 100644
index 00000000000..3dd66c5b609
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_600D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.3
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_60D.py b/release/scripts/presets/tracking_camera/Canon_60D.py
new file mode 100644
index 00000000000..3dd66c5b609
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_60D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.3
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Canon_7D.py b/release/scripts/presets/tracking_camera/Canon_7D.py
new file mode 100644
index 00000000000..3dd66c5b609
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Canon_7D.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.3
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D300S.py b/release/scripts/presets/tracking_camera/Nikon_D300S.py
new file mode 100644
index 00000000000..8db89189cd7
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D300S.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.6
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D3100.py b/release/scripts/presets/tracking_camera/Nikon_D3100.py
new file mode 100644
index 00000000000..a112dd22dd2
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D3100.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.1
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D35.py b/release/scripts/presets/tracking_camera/Nikon_D35.py
new file mode 100644
index 00000000000..7d9b6c8b390
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D35.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 36.0
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D5000.py b/release/scripts/presets/tracking_camera/Nikon_D5000.py
new file mode 100644
index 00000000000..8db89189cd7
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D5000.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.6
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D5100.py b/release/scripts/presets/tracking_camera/Nikon_D5100.py
new file mode 100644
index 00000000000..8db89189cd7
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D5100.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.6
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D7000.py b/release/scripts/presets/tracking_camera/Nikon_D7000.py
new file mode 100644
index 00000000000..8db89189cd7
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D7000.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.6
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Nikon_D90.py b/release/scripts/presets/tracking_camera/Nikon_D90.py
new file mode 100644
index 00000000000..8db89189cd7
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Nikon_D90.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 23.6
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_Epic.py b/release/scripts/presets/tracking_camera/Red_Epic.py
new file mode 100644
index 00000000000..913b507d296
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Red_Epic.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 30.0
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_One_2K.py b/release/scripts/presets/tracking_camera/Red_One_2K.py
new file mode 100644
index 00000000000..0a52b377959
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Red_One_2K.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 11.1
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_One_3K.py b/release/scripts/presets/tracking_camera/Red_One_3K.py
new file mode 100644
index 00000000000..88c232bb944
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Red_One_3K.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 16.65
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_camera/Red_One_4K.py b/release/scripts/presets/tracking_camera/Red_One_4K.py
new file mode 100644
index 00000000000..7ea78412f40
--- /dev/null
+++ b/release/scripts/presets/tracking_camera/Red_One_4K.py
@@ -0,0 +1,10 @@
+import bpy
+camera = bpy.context.edit_movieclip.tracking.camera
+
+camera.sensor_width = 22.2
+camera.units = 'MILLIMETERS'
+camera.focal_length = 24.0
+camera.pixel_aspect = 1
+camera.k1 = 0.0
+camera.k2 = 0.0
+camera.k3 = 0.0
diff --git a/release/scripts/presets/tracking_track_color/default.py b/release/scripts/presets/tracking_track_color/default.py
new file mode 100644
index 00000000000..3213d6e0c83
--- /dev/null
+++ b/release/scripts/presets/tracking_track_color/default.py
@@ -0,0 +1,5 @@
+import bpy
+track = bpy.context.edit_movieclip.tracking.tracks.active
+
+track.color = (0.0, 0.0, 0.0)
+track.use_custom_color = False
diff --git a/release/scripts/presets/tracking_track_color/far_plane.py b/release/scripts/presets/tracking_track_color/far_plane.py
new file mode 100644
index 00000000000..579d5562642
--- /dev/null
+++ b/release/scripts/presets/tracking_track_color/far_plane.py
@@ -0,0 +1,5 @@
+import bpy
+track = bpy.context.edit_movieclip.tracking.tracks.active
+
+track.color = (0.0, 0.0, 1.0)
+track.use_custom_color = True
diff --git a/release/scripts/presets/tracking_track_color/near_plane.py b/release/scripts/presets/tracking_track_color/near_plane.py
new file mode 100644
index 00000000000..790429ce7a1
--- /dev/null
+++ b/release/scripts/presets/tracking_track_color/near_plane.py
@@ -0,0 +1,5 @@
+import bpy
+track = bpy.context.edit_movieclip.tracking.tracks.active
+
+track.color = (0.0, 1.0, 0.0)
+track.use_custom_color = True
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index c0e83cee9d6..06b4429d25c 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -25,6 +25,7 @@ if "bpy" in locals():
_modules = (
"add_mesh_torus",
"anim",
+ "clip",
"console",
"image",
"mesh",
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 490ee230220..a062ac6f4c5 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -105,8 +105,7 @@ class QuickFur(Operator):
psys.settings.child_type = 'INTERPOLATED'
obj.data.materials.append(mat)
- obj.particle_systems[-1].settings.material = \
- len(obj.data.materials)
+ psys.settings.material = len(obj.data.materials)
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 21ac128f177..ac19bab4c66 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -319,6 +319,47 @@ class AddPresetInteraction(AddPresetBase, Operator):
preset_subdir = "interaction"
+class AddPresetTrackingCamera(AddPresetBase, Operator):
+ '''Add a Tracking Camera Intrinsics Preset'''
+ bl_idname = "clip.camera_preset_add"
+ bl_label = "Add Camera Preset"
+ preset_menu = "CLIP_MT_camera_presets"
+
+ preset_defines = [
+ "camera = bpy.context.edit_movieclip.tracking.camera"
+ ]
+
+ preset_values = [
+ "camera.sensor_width",
+ "camera.units",
+ "camera.focal_length",
+ "camera.pixel_aspect",
+ "camera.k1",
+ "camera.k2",
+ "camera.k3"
+ ]
+
+ preset_subdir = "tracking_camera"
+
+
+class AddPresetTrackingTrackColor(AddPresetBase, Operator):
+ '''Add a Clip Track Color Preset'''
+ bl_idname = "clip.track_color_preset_add"
+ bl_label = "Add Track Color Preset"
+ preset_menu = "CLIP_MT_track_color_presets"
+
+ preset_defines = [
+ "track = bpy.context.edit_movieclip.tracking.tracks"
+ ]
+
+ preset_values = [
+ "track.color",
+ "track.use_custom_color"
+ ]
+
+ preset_subdir = "tracking_track_color"
+
+
class AddPresetKeyconfig(AddPresetBase, Operator):
'''Add a Keyconfig Preset'''
bl_idname = "wm.keyconfig_preset_add"
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 66d0d72efc1..17e353ff238 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -212,8 +212,11 @@ def islandIntersectUvIsland(source, target, SourceOffset):
# Edge intersect test
for ed in edgeLoopsSource:
for seg in edgeLoopsTarget:
- i = geometry.intersect_line_line_2d(\
- seg[0], seg[1], SourceOffset+ed[0], SourceOffset+ed[1])
+ i = geometry.intersect_line_line_2d(seg[0],
+ seg[1],
+ SourceOffset+ed[0],
+ SourceOffset+ed[1],
+ )
if i:
return 1 # LINE INTERSECTION
@@ -773,15 +776,16 @@ def main_consts():
global ROTMAT_2D_POS_45D
global RotMatStepRotation
- ROTMAT_2D_POS_90D = Matrix.Rotation( radians(90.0), 2)
- ROTMAT_2D_POS_45D = Matrix.Rotation( radians(45.0), 2)
+ ROTMAT_2D_POS_90D = Matrix.Rotation(radians(90.0), 2)
+ ROTMAT_2D_POS_45D = Matrix.Rotation(radians(45.0), 2)
RotMatStepRotation = []
rot_angle = 22.5 #45.0/2
while rot_angle > 0.1:
- RotMatStepRotation.append([\
- Matrix.Rotation( radians(rot_angle), 2),\
- Matrix.Rotation( radians(-rot_angle), 2)])
+ RotMatStepRotation.append([
+ Matrix.Rotation(radians(+rot_angle), 2),
+ Matrix.Rotation(radians(-rot_angle), 2),
+ ])
rot_angle = rot_angle/2.0
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index 682341cbf2f..48aefa93a5c 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -52,6 +52,7 @@ _modules = (
"properties_scene",
"properties_texture",
"properties_world",
+ "space_clip",
"space_console",
"space_dopesheet",
"space_filebrowser",
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 0abbf281754..1a0fb0ef4ac 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -108,6 +108,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
col.prop(cam, "clip_start", text="Start")
col.prop(cam, "clip_end", text="End")
+
class DATA_PT_camera(CameraButtonsPanel, Panel):
bl_label = "Camera"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -120,8 +121,8 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
row = layout.row(align=True)
row.menu("CAMERA_MT_presets", text=bpy.types.CAMERA_MT_presets.bl_label)
- row.operator("camera.preset_add", text="", icon="ZOOMIN")
- row.operator("camera.preset_add", text="", icon="ZOOMOUT").remove_active = True
+ row.operator("camera.preset_add", text="", icon='ZOOMIN')
+ row.operator("camera.preset_add", text="", icon='ZOOMOUT').remove_active = True
layout.label(text="Sensor:")
@@ -137,6 +138,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel):
col = split.column(align=True)
col.prop(cam, "sensor_fit", text="")
+
class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
bl_label = "Depth of Field"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -156,6 +158,7 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
col.active = cam.dof_object is None
col.prop(cam, "dof_distance", text="Distance")
+
class DATA_PT_camera_display(CameraButtonsPanel, Panel):
bl_label = "Display"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index 4ff180f74fb..974924be46c 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -134,8 +134,8 @@ class DATA_PT_sunsky(DataButtonsPanel, Panel):
row = layout.row(align=True)
row.prop(lamp, "use_sky")
row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label)
- row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMIN")
- row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMOUT").remove_active = True
+ row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMIN')
+ row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMOUT').remove_active = True
row = layout.row()
row.active = lamp.use_sky or lamp.use_atmosphere
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index 0d104571e4b..ba9bb4a624d 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -315,11 +315,9 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
split = layout.split()
- if dome_type == 'FISHEYE' or \
- dome_type == 'TRUNCATED_REAR' or \
- dome_type == 'TRUNCATED_FRONT':
-
+ if dome_type in {'FISHEYE', 'TRUNCATED_REAR', 'TRUNCATED_FRONT'}:
col = split.column()
+
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
col.prop(gs, "dome_angle", slider=True)
@@ -336,6 +334,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
else: # cube map
col = split.column()
+
col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True)
col = split.column()
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 62cb735fda9..f5a95016baa 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -124,7 +124,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
split.template_ID(ob, "active_material", new="material.new")
row = split.row()
if mat:
- row.prop(mat, "use_nodes", icon="NODETREE", text="")
+ row.prop(mat, "use_nodes", icon='NODETREE', text="")
if slot:
row.prop(slot, "link", text="")
@@ -501,8 +501,8 @@ class MATERIAL_PT_sss(MaterialButtonsPanel, Panel):
row = layout.row().split()
sub = row.row(align=True).split(percentage=0.75)
sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label)
- sub.operator("material.sss_preset_add", text="", icon="ZOOMIN")
- sub.operator("material.sss_preset_add", text="", icon="ZOOMOUT").remove_active = True
+ sub.operator("material.sss_preset_add", text="", icon='ZOOMIN')
+ sub.operator("material.sss_preset_add", text="", icon='ZOOMOUT').remove_active = True
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index a359d58b59e..36b8129ad8a 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -267,12 +267,12 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
ob = context.object
split = layout.split()
-
+
col = split.column()
col.label(text="Tracking Axes:")
col.prop(ob, "track_axis", text="Axis")
col.prop(ob, "up_axis", text="Up Axis")
-
+
col = split.column()
col.prop(ob, "use_slow_parent")
row = col.row()
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index dc19f58ca35..c493124c5bb 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -753,6 +753,26 @@ class ConstraintButtonsPanel():
col = layout.column()
col.prop(con, "rotation_range", text="Pivot When")
+ def FOLLOW_TRACK(self, context, layout, con):
+ layout.prop(con, "use_active_clip")
+
+ if not con.use_active_clip:
+ layout.prop(con, "clip")
+
+ layout.prop(con, "track")
+
+ layout.row().prop(con, "reference", expand=True)
+
+ layout.operator("clip.constraint_to_fcurve")
+
+ def CAMERA_SOLVER(self, context, layout, con):
+ layout.prop(con, "use_active_clip")
+
+ if not con.use_active_clip:
+ layout.prop(con, "clip")
+
+ layout.operator("clip.constraint_to_fcurve")
+
def SCRIPT(self, context, layout, con):
layout.label("Blender 2.5 has no py-constraints")
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index c66a0563754..afb3c000980 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -73,8 +73,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
col.label(text="Presets:")
sub = col.row(align=True)
sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label)
- sub.operator("cloth.preset_add", text="", icon="ZOOMIN")
- sub.operator("cloth.preset_add", text="", icon="ZOOMOUT").remove_active = True
+ sub.operator("cloth.preset_add", text="", icon='ZOOMIN')
+ sub.operator("cloth.preset_add", text="", icon='ZOOMOUT').remove_active = True
col.label(text="Quality:")
col.prop(cloth, "quality", text="Steps", slider=True)
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index efb760c0b43..ce65350e69b 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -206,7 +206,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel):
col = split.column()
if scene.use_gravity:
- col.label(text="Use Scene Gravity", icon="SCENE_DATA")
+ col.label(text="Use Scene Gravity", icon='SCENE_DATA')
sub = col.column()
sub.enabled = False
sub.prop(fluid, "gravity", text="")
@@ -215,7 +215,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel):
col.prop(fluid, "gravity", text="")
if scene.unit_settings.system != 'NONE':
- col.label(text="Use Scene Size Units", icon="SCENE_DATA")
+ col.label(text="Use Scene Size Units", icon='SCENE_DATA')
sub = col.column()
sub.enabled = False
sub.prop(fluid, "simulation_scale", text="Metres")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 815f0a77570..145ae292e11 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -186,8 +186,8 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
row = layout.row(align=True)
row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
- row.operator("render.preset_add", text="", icon="ZOOMIN")
- row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True
+ row.operator("render.preset_add", text="", icon='ZOOMIN')
+ row.operator("render.preset_add", text="", icon='ZOOMOUT').remove_active = True
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index d3859a78bea..86880b9ddec 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -42,6 +42,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel):
layout.prop(scene, "camera")
layout.prop(scene, "background_set", text="Background")
+ layout.prop(scene, "active_clip", text="Active Clip")
class SCENE_PT_audio(SceneButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index cf0d10c5844..435b968f243 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -62,7 +62,7 @@ class FILEBROWSER_HT_header(Header):
row.prop(params, "use_filter_folder", text="")
if params.filter_glob:
- #if st.operator and hasattr(st.operator, "filter_glob"):
+ #if st.active_operator and hasattr(st.active_operator, "filter_glob"):
# row.prop(params, "filter_glob", text="")
row.label(params.filter_glob)
else:
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 50db989a2e2..170ba3ccd0e 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -61,7 +61,7 @@ class IMAGE_MT_view(Menu):
layout.separator()
- ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]]
+ ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
for a, b in ratios:
layout.operator("image.view_zoom_ratio", text="Zoom" + " %d:%d" % (a, b)).ratio = a / b
@@ -746,12 +746,12 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
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'
+ 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'
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index 6f8e6a574ec..5209e8be597 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -177,6 +177,7 @@ class TIME_MT_playback(Menu):
layout.prop(screen, "use_play_image_editors")
layout.prop(screen, "use_play_sequence_editors")
layout.prop(screen, "use_play_node_editors")
+ layout.prop(screen, "use_play_clip_editors")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index c6c4a8f3335..a2ede26ecc6 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -967,10 +967,10 @@ class USERPREF_PT_addons(Panel):
continue
# check if addon should be visible with current filters
- if (filter == "All") or \
- (filter == info["category"]) or \
- (filter == "Enabled" and is_enabled) or \
- (filter == "Disabled" and not is_enabled):
+ if ((filter == "All") or
+ (filter == info["category"]) or
+ (filter == "Enabled" and is_enabled) or
+ (filter == "Disabled" and not is_enabled)):
if search and search not in info["name"].lower():
if info["author"]:
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index 5e5ce462da9..d738e806320 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -223,7 +223,7 @@ class InputKeyMapPanel:
col = layout.column()
row = col.row()
- row.label(text=km.name, icon="DOT")
+ row.label(text=km.name, icon='DOT')
row.label()
row.label()
@@ -265,13 +265,13 @@ class InputKeyMapPanel:
if not text:
text = "Blender (default)"
row.menu("USERPREF_MT_keyconfigs", text=text)
- row.operator("wm.keyconfig_preset_add", text="", icon="ZOOMIN")
- row.operator("wm.keyconfig_preset_add", text="", icon="ZOOMOUT").remove_active = True
+ row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMIN')
+ row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMOUT').remove_active = True
#~ layout.context_pointer_set("keyconfig", wm.keyconfigs.active)
#~ row.operator("wm.keyconfig_remove", text="", icon='X')
- row.prop(context.space_data, "filter_text", icon="VIEWZOOM")
+ row.prop(context.space_data, "filter_text", icon='VIEWZOOM')
col.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b626a5dcb55..0631ccf2f70 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1537,7 +1537,7 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
class VIEW3D_MT_edit_mesh_extrude(Menu):
bl_label = "Extrude"
- _extrude_funcs = { \
+ _extrude_funcs = {
"VERT": lambda layout: layout.operator("mesh.extrude_vertices_move", text="Vertices Only"),
"EDGE": lambda layout: layout.operator("mesh.extrude_edges_move", text="Edges Only"),
"FACE": lambda layout: layout.operator("mesh.extrude_faces_move", text="Individual Faces"),
@@ -2169,6 +2169,16 @@ class VIEW3D_PT_view3d_display(Panel):
layout.separator()
+ layout.prop(view, "show_reconstruction")
+ if view.show_reconstruction:
+ layout.label(text="Bundle type:")
+ layout.prop(view, "bundle_draw_type", text="")
+ layout.prop(view, "bundle_draw_size")
+ layout.prop(view, "show_bundle_name")
+ layout.prop(view, "show_camera_path")
+
+ layout.separator()
+
region = view.region_quadview
layout.operator("screen.region_quadview", text="Toggle Quad View")
@@ -2274,8 +2284,10 @@ class VIEW3D_PT_background_image(Panel):
box = layout.box()
row = box.row(align=True)
row.prop(bg, "show_expanded", text="", emboss=False)
- if bg.image:
+ if bg.source == 'IMAGE' and bg.image:
row.prop(bg.image, "name", text="", emboss=False)
+ if bg.source == 'MOVIE' and bg.clip:
+ row.prop(bg.clip, "name", text="", emboss=False)
else:
row.label(text="Not Set")
row.operator("view3d.background_image_remove", text="", emboss=False, icon='X').index = i
@@ -2284,10 +2296,36 @@ class VIEW3D_PT_background_image(Panel):
if bg.show_expanded:
row = box.row()
- row.template_ID(bg, "image", open="image.open")
- if (bg.image):
- box.template_image(bg, "image", bg.image_user, compact=True)
+ row.prop(bg, "source", expand=True)
+
+ hasbg = False
+ if bg.source == 'IMAGE':
+ row = box.row()
+ row.template_ID(bg, "image", open="image.open")
+ if (bg.image):
+ box.template_image(bg, "image", bg.image_user, compact=True)
+ hasbg = True
+
+ elif bg.source == 'MOVIE':
+ has_clip = False
+ box.prop(bg, 'use_camera_clip')
+
+ column = box.column()
+ column.active = not bg.use_camera_clip
+ column.template_ID(bg, "clip", open="clip.open")
+
+ if bg.clip:
+ column.template_movieclip(bg, "clip", compact=True)
+
+ if bg.use_camera_clip or bg.clip:
+ hasbg = True
+
+ column = box.column()
+ column.active = hasbg
+ column.prop(bg.clip_user, "proxy_render_size", text="")
+ column.prop(bg.clip_user, "use_render_undistorted")
+ if hasbg:
box.prop(bg, "opacity", slider=True)
if bg.view_axis != 'CAMERA':
box.prop(bg, "size")
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 332577a7902..5bcdbc1efe8 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -172,7 +172,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
bl_context = "mesh_edit"
bl_label = "Mesh Options"
-
+
@classmethod
def poll(cls, context):
return context.active_object
@@ -912,12 +912,12 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel, Panel):
layout.template_curve_mapping(brush, "curve", brush=True)
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'
+ 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 VIEW3D_PT_sculpt_options(PaintPanel, Panel):
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index 5280d26cc3d..625b847e1d2 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -82,6 +82,8 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view3d_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_windowmanager_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_world_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h
)
add_subdirectory(editors)
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index db576b2de88..6f9bea39ecc 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 260
-#define BLENDER_SUBVERSION 1
+#define BLENDER_SUBVERSION 2
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index c065a210a98..0aefe2231a5 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -61,6 +61,7 @@ struct wmWindow;
struct wmWindowManager;
struct SpaceText;
struct SpaceImage;
+struct SpaceClip;
struct ID;
/* Structs */
@@ -158,6 +159,7 @@ struct SpaceIpo *CTX_wm_space_graph(const bContext *C);
struct SpaceAction *CTX_wm_space_action(const bContext *C);
struct SpaceInfo *CTX_wm_space_info(const bContext *C);
struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C);
+struct SpaceClip *CTX_wm_space_clip(const bContext *C);
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
@@ -252,6 +254,7 @@ struct Object *CTX_data_edit_object(const bContext *C);
struct Image *CTX_data_edit_image(const bContext *C);
struct Text *CTX_data_edit_text(const bContext *C);
+struct MovieClip *CTX_data_edit_movieclip(const bContext *C);
int CTX_data_selected_nodes(const bContext *C, ListBase *list);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 308d7ff22c2..ade055ac457 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -64,7 +64,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id);
struct ListBase *which_libbase(struct Main *mainlib, short type);
-#define MAX_LIBARRAY 39
+#define MAX_LIBARRAY 40
int set_listbasepointers(struct Main *main, struct ListBase **lb);
void free_libblock(struct ListBase *lb, void *idv);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 2f587d3b29c..28eb59ebdb6 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -85,6 +85,7 @@ typedef struct Main {
ListBase particle;
ListBase wm;
ListBase gpencil;
+ ListBase movieclip;
char id_tag_update[256];
} Main;
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
new file mode 100644
index 00000000000..4d16df8afa3
--- /dev/null
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -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.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_MOVIECLIP_H
+#define BKE_MOVIECLIP_H
+
+/** \file BKE_movieclip.h
+ * \ingroup bke
+ * \author Sergey Sharybin
+ */
+
+struct ImBuf;
+struct Main;
+struct MovieClip;
+struct MovieClipScopes;
+struct MovieClipUser;
+struct MovieTrackingTrack;
+struct MovieDistortion;
+
+void free_movieclip(struct MovieClip *clip);
+void unlink_movieclip(struct Main *bmain, struct MovieClip *clip);
+
+struct MovieClip *BKE_add_movieclip_file(const char *name);
+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);
+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);
+void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr);
+
+void BKE_movieclip_select_track(struct MovieClip *clip, struct MovieTrackingTrack *track, int area, int extend);
+
+void BKE_movieclip_update_scopes(struct MovieClip *clip, struct MovieClipUser *user, struct MovieClipScopes *scopes);
+
+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,
+ 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
+
+#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7509205e968..b94fffab714 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -83,6 +83,7 @@ typedef struct bNodeSocketTemplate {
float val1, val2, val3, val4; /* default alloc value for inputs */
float min, max;
PropertySubType subtype;
+ int flag;
/* after this line is used internal only */
struct bNodeSocket *sock; /* used to hold verified socket */
@@ -244,6 +245,7 @@ typedef struct bNodeType {
struct bNodeTreeExec;
typedef void (*bNodeTreeCallback)(void *calldata, struct ID *owner_id, struct bNodeTree *ntree);
+typedef void (*bNodeClassCallback)(void *calldata, int nclass, const char *name);
typedef struct bNodeTreeType
{
int type; /* type identifier */
@@ -255,6 +257,7 @@ typedef struct bNodeTreeType
void (*free_cache)(struct bNodeTree *ntree);
void (*free_node_cache)(struct bNodeTree *ntree, struct bNode *node);
void (*foreach_nodetree)(struct Main *main, void *calldata, bNodeTreeCallback func); /* iteration over all node trees */
+ void (*foreach_nodeclass)(struct Scene *scene, void *calldata, bNodeClassCallback func); /* iteration over all node classes */
/* calls allowing threaded composite */
void (*localize)(struct bNodeTree *localtree, struct bNodeTree *ntree);
@@ -567,6 +570,10 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat);
#define CMP_NODE_COLOR_MATTE 259
#define CMP_NODE_COLORBALANCE 260
#define CMP_NODE_HUECORRECT 261
+#define CMP_NODE_MOVIECLIP 262
+#define CMP_NODE_STABILIZE2D 263
+#define CMP_NODE_TRANSFORM 264
+#define CMP_NODE_MOVIEDISTORTION 265
#define CMP_NODE_GLARE 301
#define CMP_NODE_TONEMAP 302
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9ccdd080158..2ef942a2e09 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -48,6 +48,7 @@ struct Group;
struct bAction;
struct RenderData;
struct rctf;
+struct MovieClip;
void clear_workob(struct Object *workob);
void what_does_parent(struct Scene *scene, struct Object *ob, struct Object *workob);
@@ -99,6 +100,7 @@ struct Object *object_pose_armature_get(struct Object *ob);
void where_is_object_time(struct Scene *scene, struct Object *ob, float ctime);
void where_is_object(struct Scene *scene, struct Object *ob);
void where_is_object_simul(struct Scene *scene, struct Object *ob);
+void where_is_object_mat(struct Scene *scene, struct Object *ob, float obmat[4][4]);
struct BoundBox *unit_boundbox(void);
void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]);
@@ -127,6 +129,8 @@ int object_is_modified(struct Scene *scene, struct Object *ob);
void object_relink(struct Object *ob);
+struct MovieClip *object_get_movieclip(struct Scene *scene, struct Object *ob, int use_default);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index de72428b3d7..508fef8d9a4 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -103,9 +103,12 @@ void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex
int has_current_material_texture(struct Material *ma);
-struct TexMapping *add_mapping(void);
-void init_mapping(struct TexMapping *texmap);
+struct TexMapping *add_tex_mapping(void);
+void default_tex_mapping(struct TexMapping *texmap);
+void init_tex_mapping(struct TexMapping *texmap);
+struct ColorMapping *add_color_mapping(void);
+void default_color_mapping(struct ColorMapping *colormap);
void BKE_free_envmapdata(struct EnvMap *env);
void BKE_free_envmap(struct EnvMap *env);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
new file mode 100644
index 00000000000..a8fb2c836de
--- /dev/null
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -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.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_TRACKING_H
+#define BKE_TRACKING_H
+
+/** \file BKE_trackingp.h
+ * \ingroup bke
+ * \author Sergey Sharybin
+ */
+
+struct bGPDlayer;
+struct ImBuf;
+struct MovieTrackingTrack;
+struct MovieTrackingMarker;
+struct MovieTracking;
+struct MovieTrackingContext;
+struct MovieClipUser;
+struct MovieDistortion;
+struct Camera;
+struct Object;
+struct Scene;
+
+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);
+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);
+
+void BKE_tracking_free_track(struct MovieTrackingTrack *track);
+struct MovieTrackingTrack *BKE_tracking_copy_track(struct MovieTrackingTrack *track);
+
+void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, int action);
+
+int BKE_tracking_test_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track);
+void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track);
+void BKE_tracking_free(struct MovieTracking *tracking);
+
+struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
+ struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]);
+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);
+
+struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, const char *name);
+struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr);
+
+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]);
+
+/* 2D tracking */
+struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
+ short backwards, short disable_failed);
+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 */
+float BKE_tracking_solve_reconstruction(struct MovieTracking *tracking, int width, int height);
+
+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]);
+
+/* Feature detection */
+void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ImBuf *imbuf,
+ int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer,
+ int place_outside_layer);
+
+/* 2D stabilization */
+void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle);
+struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle);
+void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4]);
+
+/* Distortion/Undistortion */
+void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
+void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
+
+struct MovieDistortion *BKE_tracking_distortion_create(void);
+struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
+struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
+ struct ImBuf *ibuf, int width, int height, float overscan, int undistort);
+void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion);
+
+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);
+
+/* Select */
+void BKE_tracking_select_track(struct MovieTracking *tracking, 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))
+#define TRACK_AREA_SELECTED(track, area) ((((track)->flag&TRACK_HIDDEN)==0) && ((area)==TRACK_AREA_POINT?(track)->flag&SELECT : ((area)==TRACK_AREA_PAT?(track)->pat_flag&SELECT:(track)->search_flag&SELECT)))
+#define TRACK_VIEW_SELECTED(sc, track) ((TRACK_AREA_SELECTED(track, TRACK_AREA_POINT) || (((sc)->flag&SC_SHOW_MARKER_PATTERN && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))) || (((sc)->flag&SC_SHOW_MARKER_SEARCH && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)))))
+
+#define MARKER_VISIBLE(sc, marker) (((marker)->flag&MARKER_DISABLED)==0 || ((sc)->flag&SC_HIDE_DISABLED)==0)
+
+#define CLAMP_PAT_DIM 1
+#define CLAMP_PAT_POS 2
+#define CLAMP_SEARCH_DIM 3
+#define CLAMP_SEARCH_POS 4
+#define CLAMP_PYRAMID_LEVELS 5
+
+#define TRACK_AREA_NONE -1
+#define TRACK_AREA_POINT 1
+#define TRACK_AREA_PAT 2
+#define TRACK_AREA_SEARCH 4
+
+#define TRACK_AREA_ALL (TRACK_AREA_POINT|TRACK_AREA_PAT|TRACK_AREA_SEARCH)
+
+#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 82a179eac4a..22ffbcbdd46 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -115,6 +115,7 @@ set(SRC
intern/mesh_validate.c
intern/modifier.c
intern/modifiers_bmesh.c
+ intern/movieclip.c
intern/multires.c
intern/nla.c
intern/node.c
@@ -143,6 +144,7 @@ set(SRC
intern/suggestions.c
intern/text.c
intern/texture.c
+ intern/tracking.c
intern/unit.c
intern/world.c
intern/writeavi.c
@@ -199,6 +201,7 @@ set(SRC
BKE_mball.h
BKE_mesh.h
BKE_modifier.h
+ BKE_movieclip.h
BKE_multires.h
BKE_nla.h
BKE_node.h
@@ -226,6 +229,7 @@ set(SRC
BKE_tessmesh.h
BKE_text.h
BKE_texture.h
+ BKE_tracking.h
BKE_unit.h
BKE_utildefines.h
BKE_world.h
@@ -369,6 +373,13 @@ if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
+if(WITH_LIBMV)
+ list(APPEND INC
+ ../../../extern/libmv
+ )
+ add_definitions(-DWITH_LIBMV)
+endif()
+
## Warnings as errors, this is too strict!
#if(MSVC)
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 7ae27aadd37..0cdcd4aa8eb 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -97,6 +97,10 @@ if env['WITH_BF_GAMEENGINE']:
else:
sources.remove('intern' + os.sep + 'navmesh_conversion.c')
+if env['WITH_BF_LIBMV']:
+ incs += ' #/extern/libmv'
+ defs.append('WITH_LIBMV')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 50f305e4400..a9c29728650 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1818,7 +1818,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
tree->ikData= ikData;
/* AND! link the tree to the root */
- BLI_addtail(&pchanRoot->iktree, tree);
+ BLI_addtail(&pchanRoot->siktree, tree);
}
/* mark root channel having an IK tree */
@@ -2045,27 +2045,24 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_
tSplineIK_Tree *tree;
/* for each pose-tree, execute it if it is spline, otherwise just free it */
- for (tree= pchan_root->iktree.first; tree; tree= pchan_root->iktree.first) {
- /* only evaluate if tagged for Spline IK */
- if (tree->type == CONSTRAINT_TYPE_SPLINEIK) {
- int i;
-
- /* walk over each bone in the chain, calculating the effects of spline IK
- * - the chain is traversed in the opposite order to storage order (i.e. parent to children)
- * so that dependencies are correct
- */
- for (i= tree->chainlen-1; i >= 0; i--) {
- bPoseChannel *pchan= tree->chain[i];
- splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime);
- }
-
- /* free the tree info specific to SplineIK trees now */
- if (tree->chain) MEM_freeN(tree->chain);
- if (tree->free_points) MEM_freeN(tree->points);
+ while ((tree = pchan_root->siktree.first) != NULL) {
+ int i;
+
+ /* walk over each bone in the chain, calculating the effects of spline IK
+ * - the chain is traversed in the opposite order to storage order (i.e. parent to children)
+ * so that dependencies are correct
+ */
+ for (i= tree->chainlen-1; i >= 0; i--) {
+ bPoseChannel *pchan= tree->chain[i];
+ splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime);
}
+ /* free the tree info specific to SplineIK trees now */
+ if (tree->chain) MEM_freeN(tree->chain);
+ if (tree->free_points) MEM_freeN(tree->points);
+
/* free this tree */
- BLI_freelinkN(&pchan_root->iktree, tree);
+ BLI_freelinkN(&pchan_root->siktree, tree);
}
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 56f92b44227..3e14dbe39da 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -44,6 +44,7 @@
#include "BLI_utildefines.h"
#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -51,15 +52,19 @@
#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
#include "DNA_text_types.h"
+#include "DNA_tracking_types.h"
+#include "DNA_movieclip_types.h"
#include "BKE_action.h"
#include "BKE_anim.h" /* for the curve calculation part */
#include "BKE_armature.h"
#include "BKE_blender.h"
+#include "BKE_camera.h"
#include "BKE_constraint.h"
#include "BKE_displist.h"
#include "BKE_deform.h"
@@ -74,6 +79,10 @@
#include "BKE_shrinkwrap.h"
#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
+#include "BKE_tracking.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+#include "BKE_movieclip.h"
#ifdef WITH_PYTHON
#include "BPY_extern.h"
@@ -3924,6 +3933,203 @@ static bConstraintTypeInfo CTI_PIVOT = {
pivotcon_evaluate /* evaluate */
};
+/* ----------- Follow Track ------------- */
+
+static void followtrack_new_data (void *cdata)
+{
+ bFollowTrackConstraint *data= (bFollowTrackConstraint *)cdata;
+
+ data->clip= NULL;
+ data->flag|= FOLLOWTRACK_ACTIVECLIP;
+ data->reference= FOLLOWTRACK_TRACK;
+}
+
+static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
+{
+ bFollowTrackConstraint *data= con->data;
+
+ func(con, (ID**)&data->clip, userdata);
+}
+
+static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
+{
+ Scene *scene= cob->scene;
+ bFollowTrackConstraint *data= con->data;
+ MovieClip *clip= data->clip;
+ MovieTrackingTrack *track;
+
+ if(data->flag&FOLLOWTRACK_ACTIVECLIP)
+ clip= scene->clip;
+
+ if(!clip || !data->track[0])
+ return;
+
+ track= BKE_tracking_named_track(&clip->tracking, data->track);
+
+ if(!track)
+ return;
+
+ if(data->reference==FOLLOWTRACK_BUNDLE) {
+ if(track->flag&TRACK_HAS_BUNDLE) {
+ float pos[3], mat[4][4], obmat[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];
+ }
+ } 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 sensor_x, sensor_y, lens, len, d, ortho_scale= 1.f;
+
+ where_is_object_mat(scene, camob, mat);
+
+ /* camera axis */
+ vec[0]= 0.f;
+ vec[1]= 0.f;
+ vec[2]= 1.f;
+ 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) {
+ float pos[2], rmat[4][4], shiftx= 0.0f, shifty= 0.0f, clipsta= 0.0f, clipend= 0.0f;
+ short is_ortho= 0, sensor_fit= CAMERA_SENSOR_FIT_AUTO;
+ Camera *cam= NULL;
+
+ user.framenr= scene->r.cfra;
+ marker= BKE_tracking_get_marker(track, user.framenr);
+
+ add_v2_v2v2(pos, marker->pos, track->offset);
+
+ object_camera_intrinsics(camob, &cam, &is_ortho, &shiftx, &shifty, &clipsta, &clipend, &lens, &sensor_x, &sensor_y, &sensor_fit);
+
+ if(is_ortho) {
+ if(cam)
+ ortho_scale= cam->ortho_scale;
+
+ vec[0]= ortho_scale * (pos[0]-0.5f+shiftx);
+ vec[1]= ortho_scale * (pos[1]-0.5f+shifty);
+ vec[2]= -len;
+
+ if(aspect>1.f) 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*sensor_x) / (2.f*lens);
+
+ vec[0]= d*(2.f*(pos[0]+shiftx)-1.f);
+ vec[1]= d*(2.f*(pos[1]+shifty)-1.f);
+ vec[2]= -len;
+
+ if(aspect>1.f) 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);
+ }
+ }
+ }
+ }
+}
+
+static bConstraintTypeInfo CTI_FOLLOWTRACK = {
+ CONSTRAINT_TYPE_FOLLOWTRACK, /* type */
+ sizeof(bFollowTrackConstraint), /* size */
+ "Follow Track", /* name */
+ "bFollowTrackConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ followtrack_id_looper, /* id looper */
+ NULL, /* copy data */
+ followtrack_new_data, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ followtrack_evaluate /* evaluate */
+};
+
+/* ----------- Camre Solver ------------- */
+
+static void camerasolver_new_data (void *cdata)
+{
+ bCameraSolverConstraint *data= (bCameraSolverConstraint *)cdata;
+
+ data->clip= NULL;
+ data->flag|= CAMERASOLVER_ACTIVECLIP;
+}
+
+static void camerasolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
+{
+ bCameraSolverConstraint *data= con->data;
+
+ func(con, (ID**)&data->clip, userdata);
+}
+
+static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
+{
+ 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);
+
+ copy_m4_m4(obmat, cob->matrix);
+ mul_m4_m4m4(cob->matrix, mat, obmat);
+ }
+}
+
+static bConstraintTypeInfo CTI_CAMERASOLVER = {
+ CONSTRAINT_TYPE_CAMERASOLVER, /* type */
+ sizeof(bCameraSolverConstraint), /* size */
+ "Camera Solver", /* name */
+ "bCameraSolverConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ camerasolver_id_looper, /* id looper */
+ NULL, /* copy data */
+ camerasolver_new_data, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ camerasolver_evaluate /* evaluate */
+};
+
/* ************************* Constraints Type-Info *************************** */
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
* and operations that involve constraint specific code.
@@ -3962,6 +4168,8 @@ static void constraints_init_typeinfo (void)
constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy Transforms Constraint */
constraintsTypeInfo[24]= &CTI_SAMEVOL; /* Maintain Volume Constraint */
constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */
+ constraintsTypeInfo[26]= &CTI_FOLLOWTRACK; /* Follow Track Constraint */
+ constraintsTypeInfo[27]= &CTI_CAMERASOLVER; /* Camera Solver Constraint */
}
/* This function should be used for getting the appropriate type-info when only
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 18c08b617de..9e9a0ca2d54 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -361,6 +361,13 @@ struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C)
return NULL;
}
+struct SpaceClip *CTX_wm_space_clip(const bContext *C)
+{
+ if(C->wm.area && C->wm.area->spacetype==SPACE_CLIP)
+ return C->wm.area->spacedata.first;
+ return NULL;
+}
+
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
{
C->wm.manager= wm;
@@ -882,6 +889,11 @@ struct Text *CTX_data_edit_text(const bContext *C)
return ctx_data_pointer_get(C, "edit_text");
}
+struct MovieClip *CTX_data_edit_movieclip(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "edit_movieclip");
+}
+
struct EditBone *CTX_data_active_bone(const bContext *C)
{
return ctx_data_pointer_get(C, "active_bone");
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 51edee9ea71..7f099c03d09 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -50,6 +50,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
+#include "DNA_movieclip_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
@@ -591,7 +592,10 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
if(part->ren_as == PART_DRAW_OB && part->dup_ob) {
node2 = dag_get_node(dag, part->dup_ob);
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Object Visualisation");
+ /* note that this relation actually runs in the wrong direction, the problem
+ is that dupli system all have this (due to parenting), and the render
+ engine instancing assumes particular ordering of objects in list */
+ dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualisation");
if(part->dup_ob->type == OB_MBALL)
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Object Visualisation");
}
@@ -639,7 +643,26 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
- if (cti && cti->get_constraint_targets) {
+ if(!cti)
+ 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(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);
+ }
+ }
+ }
+
+ dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation");
+ addtoroot = 0;
+ }
+ else if (cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
for (ct= targets.first; ct; ct= ct->next) {
@@ -2127,18 +2150,25 @@ static void dag_object_time_update_flags(Object *ob)
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
- if (cti && cti->get_constraint_targets) {
- cti->get_constraint_targets(con, &targets);
-
- for (ct= targets.first; ct; ct= ct->next) {
- if (ct->tar) {
- ob->recalc |= OB_RECALC_OB;
- break;
+ 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)) {
+ ob->recalc |= OB_RECALC_OB;
+ }
+ else if (cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar) {
+ ob->recalc |= OB_RECALC_OB;
+ break;
+ }
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
}
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(con, &targets, 1);
}
}
}
@@ -2511,6 +2541,36 @@ static void dag_id_flush_update(Scene *sce, ID *id)
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
}
+ if(idtype == ID_MC) {
+ for(obt=bmain->object.first; obt; obt= obt->id.next){
+ 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)) {
+ obt->recalc |= OB_RECALC_OB;
+ break;
+ }
+ }
+ }
+
+ if(sce->nodetree) {
+ bNode *node;
+
+ for(node= sce->nodetree->nodes.first; node; node= node->next) {
+ if(node->id==id) {
+ nodeUpdate(sce->nodetree, node);
+ }
+ }
+ }
+ }
+
+ /* camera's matrix is used to orient reconstructed stuff,
+ so it should happen tracking-related constraints recalculation
+ when camera is changing (sergey) */
+ if(sce->camera && &sce->camera->id == id && object_get_movieclip(sce, sce->camera, 1)) {
+ dag_id_flush_update(sce, &sce->clip->id);
+ }
+
/* update editors */
dag_editors_update(bmain, id);
}
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index d305499d3a1..0824a9f6685 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -78,6 +78,7 @@ static IDType idtypes[]= {
{ ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE},
{ ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE},
{ ID_WM, "WindowManager", "window_managers", 0},
+ { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE},
};
static int nidtypes= sizeof(idtypes)/sizeof(idtypes[0]);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 64ab27ae47e..f397aa736aa 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -70,6 +70,7 @@
#include "DNA_windowmanager_types.h"
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
@@ -111,6 +112,7 @@
#include "BKE_fcurve.h"
#include "BKE_speaker.h"
#include "BKE_utildefines.h"
+#include "BKE_movieclip.h"
#include "RNA_access.h"
@@ -484,6 +486,8 @@ ListBase *which_libbase(Main *mainlib, short type)
return &(mainlib->wm);
case ID_GD:
return &(mainlib->gpencil);
+ case ID_MC:
+ return &(mainlib->movieclip);
}
return NULL;
}
@@ -565,6 +569,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[a++]= &(main->scene);
lb[a++]= &(main->library);
lb[a++]= &(main->wm);
+ lb[a++]= &(main->movieclip);
lb[a]= NULL;
@@ -673,6 +678,9 @@ static ID *alloc_libblock_notest(short type)
case ID_GD:
id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
break;
+ case ID_MC:
+ id = MEM_callocN(sizeof(MovieClip), "Movie Clip");
+ break;
}
return id;
}
@@ -878,6 +886,9 @@ void free_libblock(ListBase *lb, void *idv)
case ID_GD:
free_gpencil_data((bGPdata *)id);
break;
+ case ID_MC:
+ free_movieclip((MovieClip *)id);
+ break;
}
if (id->properties) {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
new file mode 100644
index 00000000000..b72a3be1014
--- /dev/null
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -0,0 +1,1026 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/movieclip.c
+ * \ingroup bke
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+#include <time.h>
+
+#ifdef _WIN32
+#define open _open
+#define close _close
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_constraint_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_math.h"
+#include "BLI_mempool.h"
+#include "BLI_threads.h"
+
+#include "BKE_constraint.h"
+#include "BKE_library.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+#include "BKE_movieclip.h"
+#include "BKE_image.h" /* openanim */
+#include "BKE_tracking.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_moviecache.h"
+
+/*********************** movieclip buffer loaders *************************/
+
+static int sequence_guess_offset(const char *full_name, int head_len, int numlen)
+{
+ char num[FILE_MAX]= {0};
+
+ BLI_strncpy(num, full_name+head_len, numlen+1);
+
+ return atoi(num);
+}
+
+static int rendersize_to_proxy(MovieClipUser *user, int flag)
+{
+ if((flag&MCLIP_USE_PROXY)==0)
+ return IMB_PROXY_NONE;
+
+ switch(user->render_size) {
+ case MCLIP_PROXY_RENDER_SIZE_25:
+ return IMB_PROXY_25;
+
+ case MCLIP_PROXY_RENDER_SIZE_50:
+ return IMB_PROXY_50;
+
+ case MCLIP_PROXY_RENDER_SIZE_75:
+ return IMB_PROXY_75;
+
+ case MCLIP_PROXY_RENDER_SIZE_100:
+ return IMB_PROXY_100;
+
+ case MCLIP_PROXY_RENDER_SIZE_FULL:
+ return IMB_PROXY_NONE;
+ }
+
+ return IMB_PROXY_NONE;
+}
+
+static int rendersize_to_number(int render_size)
+{
+ switch(render_size) {
+ case MCLIP_PROXY_RENDER_SIZE_25:
+ return 25;
+
+ case MCLIP_PROXY_RENDER_SIZE_50:
+ return 50;
+
+ case MCLIP_PROXY_RENDER_SIZE_75:
+ return 75;
+
+ case MCLIP_PROXY_RENDER_SIZE_100:
+ return 100;
+
+ case MCLIP_PROXY_RENDER_SIZE_FULL:
+ return 100;
+ }
+
+ return 100;
+}
+
+static int get_timecode(MovieClip *clip, int flag)
+{
+ if((flag&MCLIP_USE_PROXY)==0)
+ return IMB_TC_NONE;
+
+ return clip->proxy.tc;
+}
+
+static void get_sequence_fname(MovieClip *clip, int framenr, char *name)
+{
+ unsigned short numlen;
+ char head[FILE_MAX], tail[FILE_MAX];
+ int offset;
+
+ BLI_strncpy(name, clip->name, sizeof(clip->name));
+ BLI_stringdec(name, head, tail, &numlen);
+
+ /* movieclips always points to first image from sequence,
+ autoguess offset for now. could be something smarter in the future */
+ offset= sequence_guess_offset(clip->name, strlen(head), numlen);
+
+ if (numlen) BLI_stringenc(name, head, tail, numlen, offset+framenr-1);
+ else BLI_strncpy(name, clip->name, sizeof(clip->name));
+
+ BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id));
+}
+
+/* supposed to work with sequences only */
+static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistorted, int framenr, char *name)
+{
+ int size= rendersize_to_number(proxy_render_size);
+ char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
+
+ BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX);
+
+ if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) {
+ BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
+ } else {
+ BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir);
+ }
+
+ if(undistorted)
+ BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, framenr);
+ else
+ BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, framenr);
+
+ BLI_path_abs(name, G.main->name);
+ BLI_path_frame(name, 1, 0);
+
+ strcat(name, ".jpg");
+}
+
+static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag)
+{
+ struct ImBuf *ibuf;
+ char name[FILE_MAX];
+ int loadflag /*, size */ /* UNUSED */, undistort;
+
+ /* size= rendersize_to_number(user->render_size); */
+
+ undistort= user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT;
+
+ if((flag&MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL)
+ get_proxy_fname(clip, user->render_size, undistort, framenr, name);
+ else
+ get_sequence_fname(clip, framenr, name);
+
+ loadflag= IB_rect|IB_multilayer;
+
+ /* read ibuf */
+ ibuf= IMB_loadiffname(name, loadflag);
+
+ return ibuf;
+}
+
+static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag)
+{
+ ImBuf *ibuf= NULL;
+ int tc= get_timecode(clip, flag);
+ int proxy= rendersize_to_proxy(user, flag);
+ char str[FILE_MAX];
+
+ if(!clip->anim) {
+ BLI_strncpy(str, clip->name, FILE_MAX);
+ BLI_path_abs(str, ID_BLEND_PATH(G.main, &clip->id));
+
+ /* FIXME: make several stream accessible in image editor, too */
+ clip->anim= openanim(str, IB_rect, 0);
+
+ if(clip->anim) {
+ if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) {
+ char dir[FILE_MAX];
+ BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
+ BLI_path_abs(dir, G.main->name);
+ IMB_anim_set_index_dir(clip->anim, dir);
+ }
+ }
+ }
+
+ if(clip->anim) {
+ int dur;
+ int fra;
+
+ dur= IMB_anim_get_duration(clip->anim, tc);
+ fra= framenr-1;
+
+ if(fra<0)
+ fra= 0;
+
+ if(fra>(dur-1))
+ fra= dur-1;
+
+ ibuf= IMB_anim_absolute(clip->anim, fra, tc, proxy);
+ }
+
+ return ibuf;
+}
+
+/*********************** image buffer cache *************************/
+
+typedef struct MovieClipCache {
+ /* 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;
+
+ /* cache for undistorted shot */
+ int undist_framenr;
+ float principal[2];
+ float k1, k2, k3;
+ ImBuf *undistibuf;
+} MovieClipCache;
+
+typedef struct MovieClipImBufCacheKey {
+ int framenr;
+ int proxy;
+ short render_flag;
+} MovieClipImBufCacheKey;
+
+static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
+{
+ MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)userkey;
+
+ *framenr= key->framenr;
+ *proxy= key->proxy;
+ *render_flags= key->render_flag;
+}
+
+static unsigned int moviecache_hashhash(const void *keyv)
+{
+ MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)keyv;
+ int rval= key->framenr;
+
+ return rval;
+}
+
+static int moviecache_hashcmp(const void *av, const void *bv)
+{
+ const MovieClipImBufCacheKey *a= (MovieClipImBufCacheKey*)av;
+ const MovieClipImBufCacheKey *b= (MovieClipImBufCacheKey*)bv;
+
+ if(a->framenr<b->framenr) return -1;
+ else if(a->framenr>b->framenr) return 1;
+
+ if(a->proxy<b->proxy) return -1;
+ else if(a->proxy>b->proxy) return 1;
+
+ if(a->render_flag<b->render_flag) return -1;
+ else if(a->render_flag>b->render_flag) return 1;
+
+ return 0;
+}
+
+static ImBuf *get_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag)
+{
+ if(clip->cache) {
+ MovieClipImBufCacheKey key;
+
+ key.framenr= user?user->framenr:clip->lastframe;
+
+ if(flag&MCLIP_USE_PROXY) {
+ key.proxy= rendersize_to_proxy(user, flag);
+ key.render_flag= user->render_flag;
+ }
+ else {
+ key.proxy= IMB_PROXY_NONE;
+ key.render_flag= 0;
+ }
+
+ return IMB_moviecache_get(clip->cache->moviecache, &key);
+ }
+
+ return NULL;
+}
+
+static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag)
+{
+ MovieClipImBufCacheKey key;
+
+ if(!clip->cache) {
+ clip->cache= MEM_callocN(sizeof(MovieClipCache), "movieClipCache");
+
+ clip->cache->moviecache= IMB_moviecache_create(sizeof(MovieClipImBufCacheKey), moviecache_hashhash,
+ moviecache_hashcmp, moviecache_keydata);
+ }
+
+ key.framenr= user?user->framenr:clip->lastframe;
+
+ if(flag&MCLIP_USE_PROXY) {
+ key.proxy= rendersize_to_proxy(user, flag);
+ key.render_flag= user->render_flag;
+ }
+ else {
+ key.proxy= IMB_PROXY_NONE;
+ key.render_flag= 0;
+ }
+
+ IMB_moviecache_put(clip->cache->moviecache, &key, ibuf);
+}
+
+/*********************** common functions *************************/
+
+/* only image block itself */
+static MovieClip *movieclip_alloc(const char *name)
+{
+ MovieClip *clip;
+
+ clip= alloc_libblock(&G.main->movieclip, ID_MC, name);
+
+ clip->aspx= clip->aspy= 1.0f;
+
+ clip->tracking.camera.sensor_width= 35.0f;
+ clip->tracking.camera.pixel_aspect= 1.0f;
+ clip->tracking.camera.units= CAMERA_UNITS_MM;
+
+ clip->tracking.settings.frames_limit= 0;
+ clip->tracking.settings.keyframe1= 1;
+ clip->tracking.settings.keyframe2= 30;
+ clip->tracking.settings.dist= 1;
+
+ clip->tracking.stabilization.scaleinf= 1.0f;
+ clip->tracking.stabilization.locinf= 1.0f;
+ clip->tracking.stabilization.rotinf= 1.0f;
+ clip->tracking.stabilization.maxscale= 2.0f;
+
+ 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.quality= 90;
+
+ return clip;
+}
+
+/* checks if image was already loaded, then returns same image
+ otherwise creates new.
+ does not load ibuf itself
+ pass on optional frame for #name images */
+MovieClip *BKE_add_movieclip_file(const char *name)
+{
+ MovieClip *clip;
+ MovieClipUser user;
+ int file, len, width, height;
+ const char *libname;
+ char str[FILE_MAX], strtest[FILE_MAX];
+
+ BLI_strncpy(str, name, sizeof(str));
+ BLI_path_abs(str, G.main->name);
+
+ /* exists? */
+ file= open(str, O_BINARY|O_RDONLY);
+ if(file== -1) return NULL;
+ close(file);
+
+ /* ** first search an identical clip ** */
+ for(clip= G.main->movieclip.first; clip; clip= clip->id.next) {
+ BLI_strncpy(strtest, clip->name, sizeof(clip->name));
+ BLI_path_abs(strtest, G.main->name);
+
+ if(strcmp(strtest, str)==0) {
+ BLI_strncpy(clip->name, name, sizeof(clip->name)); /* for stringcode */
+ clip->id.us++; /* officially should not, it doesn't link here! */
+
+ return clip;
+ }
+ }
+
+ /* ** add new movieclip ** */
+
+ /* create a short library name */
+ len= strlen(name);
+
+ while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') len--;
+ libname= name+len;
+
+ clip= movieclip_alloc(libname);
+ BLI_strncpy(clip->name, name, sizeof(clip->name));
+
+ if(BLI_testextensie_array(name, imb_ext_movie)) clip->source= MCLIP_SRC_MOVIE;
+ else clip->source= MCLIP_SRC_SEQUENCE;
+
+ user.framenr= 1;
+ BKE_movieclip_get_size(clip, &user, &width, &height);
+ if(width && height) {
+ clip->tracking.camera.principal[0]= ((float)width)/2;
+ clip->tracking.camera.principal[1]= ((float)height)/2;
+
+ clip->tracking.camera.focal= 24.0f*width/clip->tracking.camera.sensor_width;
+ }
+
+ return clip;
+}
+
+static void real_ibuf_size(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int *width, int *height)
+{
+ *width= ibuf->x;
+ *height= ibuf->y;
+
+ if(clip->flag&MCLIP_USE_PROXY) {
+ switch(user->render_size) {
+ case MCLIP_PROXY_RENDER_SIZE_25:
+ (*width)*= 4;
+ (*height)*= 4;
+ break;
+
+ case MCLIP_PROXY_RENDER_SIZE_50:
+ (*width)*= 2.0f;
+ (*height)*= 2.0f;
+ break;
+
+ case MCLIP_PROXY_RENDER_SIZE_75:
+ *width= ((float)*width)*4.0f/3.0f;
+ *height= ((float)*height)*4.0f/3.0f;
+ break;
+ }
+ }
+}
+
+static int need_undistorted_cache(MovieClipUser *user, int flag)
+{
+ if (!user)
+ return 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;
+ }
+ else return 0;
+
+ return 1;
+}
+
+static ImBuf *get_undistorted_cache(MovieClip *clip, MovieClipUser *user)
+{
+ MovieClipCache *cache= clip->cache;
+ MovieTrackingCamera *camera= &clip->tracking.camera;
+ int framenr= user?user->framenr:clip->lastframe;
+
+ /* no cache or no cached undistorted image */
+ if(!clip->cache || !clip->cache->undistibuf)
+ return NULL;
+
+ /* undistortion happened for other frame */
+ if(cache->undist_framenr!=framenr)
+ return NULL;
+
+ /* check for distortion model changes */
+ if(!equals_v2v2(camera->principal, cache->principal))
+ return NULL;
+
+ if(!equals_v3v3(&camera->k1, &cache->k1))
+ return NULL;
+
+ IMB_refImBuf(cache->undistibuf);
+
+ return cache->undistibuf;
+}
+
+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 ImBuf *put_undistorted_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf)
+{
+ MovieClipCache *cache= clip->cache;
+ MovieTrackingCamera *camera= &clip->tracking.camera;
+
+ copy_v2_v2(cache->principal, camera->principal);
+ copy_v3_v3(&cache->k1, &camera->k1);
+ cache->undist_framenr= user?user->framenr:clip->lastframe;
+
+ if(cache->undistibuf)
+ IMB_freeImBuf(cache->undistibuf);
+
+ cache->undistibuf= get_undistorted_ibuf(clip, NULL, ibuf);
+
+ if(cache->stableibuf) {
+ /* force stable buffer be re-calculated */
+ IMB_freeImBuf(cache->stableibuf);
+ cache->stableibuf= NULL;
+ }
+
+ IMB_refImBuf(cache->undistibuf);
+
+ return cache->undistibuf;
+}
+
+ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user)
+{
+ ImBuf *ibuf= NULL;
+ int framenr= user?user->framenr:clip->lastframe;
+ int cache_undistorted= 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);
+ if(!ibuf)
+ cache_undistorted= 1;
+ }
+
+ if(!ibuf)
+ ibuf= get_imbuf_cache(clip, user, clip->flag);
+
+ if(!ibuf) {
+ int use_sequence= 1;
+
+ /* undistorted proxies for movies should be read as image sequence */
+ use_sequence&= user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT;
+ use_sequence&= 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);
+ else {
+ ibuf= movieclip_load_movie_file(clip, user, framenr, clip->flag);
+ }
+
+ if(ibuf)
+ put_imbuf_cache(clip, user, ibuf, clip->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) {
+ ImBuf *tmpibuf= ibuf;
+ ibuf= put_undistorted_cache(clip, user, tmpibuf);
+ IMB_freeImBuf(tmpibuf);
+ }
+ }
+
+ BLI_unlock_thread(LOCK_MOVIECLIP);
+
+ return ibuf;
+}
+
+ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag)
+{
+ ImBuf *ibuf= NULL;
+ int framenr= user?user->framenr:clip->lastframe;
+ int cache_undistorted= 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, flag)) {
+ ibuf= get_undistorted_cache(clip, user);
+ if(!ibuf)
+ cache_undistorted= 1;
+ }
+
+ ibuf= get_imbuf_cache(clip, user, flag);
+
+ 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);
+ }
+
+ if(ibuf) {
+ int bits= MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR;
+
+ if((flag&bits)==(clip->flag&bits))
+ put_imbuf_cache(clip, user, ibuf, clip->flag);
+ }
+ }
+
+ /* put undistorted frame to cache */
+ if(ibuf && cache_undistorted) {
+ ImBuf *tmpibuf= ibuf;
+ ibuf= put_undistorted_cache(clip, user, tmpibuf);
+ IMB_freeImBuf(tmpibuf);
+ }
+
+ BLI_unlock_thread(LOCK_MOVIECLIP);
+
+ return ibuf;
+}
+
+ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle)
+{
+ ImBuf *ibuf, *stableibuf= NULL;
+ int framenr= user?user->framenr:clip->lastframe;
+
+ ibuf= BKE_movieclip_get_ibuf(clip, user);
+
+ 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;
+ }
+ }
+ }
+
+ 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;
+ }
+
+ IMB_refImBuf(stableibuf);
+
+ if(loc) copy_v2_v2(loc, tloc);
+ if(scale) *scale= tscale;
+ if(angle) *angle= tangle;
+ } else {
+ if(loc) zero_v2(loc);
+ if(scale) *scale= 1.0f;
+ if(angle) *angle= 0.0f;
+
+ stableibuf= ibuf;
+ }
+
+ if(stableibuf!=ibuf) {
+ IMB_freeImBuf(ibuf);
+ ibuf= stableibuf;
+ }
+
+ return ibuf;
+
+}
+
+int BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user)
+{
+ ImBuf *ibuf= BKE_movieclip_get_ibuf(clip, user);
+
+ if(ibuf) {
+ IMB_freeImBuf(ibuf);
+ return 1;
+ }
+
+ return 0;
+}
+
+void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height)
+{
+ if(!user || user->framenr==clip->lastframe) {
+ *width= clip->lastsize[0];
+ *height= clip->lastsize[1];
+ } else {
+ ImBuf *ibuf= BKE_movieclip_get_ibuf(clip, user);
+
+ if(ibuf && ibuf->x && ibuf->y) {
+ real_ibuf_size(clip, user, ibuf, width, height);
+ } else {
+ *width= 0;
+ *height= 0;
+ }
+
+ if(ibuf)
+ IMB_freeImBuf(ibuf);
+ }
+}
+
+void BKE_movieclip_aspect(MovieClip *clip, float *aspx, float *aspy)
+{
+ *aspx= *aspy= 1.0;
+
+ /* x is always 1 */
+ *aspy = clip->aspy/clip->aspx/clip->tracking.camera.pixel_aspect;
+}
+
+/* get segments of cached frames. useful for debugging cache policies */
+void BKE_movieclip_get_cache_segments(MovieClip *clip, MovieClipUser *user, int *totseg_r, int **points_r)
+{
+ *totseg_r= 0;
+ *points_r= NULL;
+
+ if(clip->cache) {
+ int proxy= rendersize_to_proxy(user, clip->flag);
+
+ IMB_moviecache_get_cache_segments(clip->cache->moviecache, proxy, user->render_flag, totseg_r, points_r);
+ }
+}
+
+void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr)
+{
+ /* TODO: clamp framenr here? */
+
+ iuser->framenr= framenr;
+}
+
+static void free_buffers(MovieClip *clip)
+{
+ if(clip->cache) {
+ IMB_moviecache_free(clip->cache->moviecache);
+
+ if(clip->cache->stableibuf)
+ IMB_freeImBuf(clip->cache->stableibuf);
+
+ if(clip->cache->undistibuf)
+ IMB_freeImBuf(clip->cache->undistibuf);
+
+ MEM_freeN(clip->cache);
+ clip->cache= NULL;
+ }
+
+ if(clip->anim) {
+ IMB_free_anim(clip->anim);
+ clip->anim= FALSE;
+ }
+}
+
+void BKE_movieclip_reload(MovieClip *clip)
+{
+ /* clear cache */
+ free_buffers(clip);
+
+ clip->tracking.stabilization.ok= 0;
+
+ /* update clip source */
+ if(BLI_testextensie_array(clip->name, imb_ext_movie)) clip->source= MCLIP_SRC_MOVIE;
+ else clip->source= MCLIP_SRC_SEQUENCE;
+}
+
+void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
+{
+ if(scopes->ok) return;
+
+ if(scopes->track_preview) {
+ IMB_freeImBuf(scopes->track_preview);
+ scopes->track_preview= NULL;
+ }
+
+ scopes->marker= NULL;
+ scopes->track= NULL;
+
+ if(clip) {
+ if(clip->tracking.act_track) {
+ MovieTrackingTrack *track= clip->tracking.act_track;
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
+
+ if(marker->flag&MARKER_DISABLED) {
+ scopes->track_disabled= 1;
+ } else {
+ ImBuf *ibuf= BKE_movieclip_get_ibuf(clip, user);
+
+ scopes->track_disabled= 0;
+
+ if(ibuf && ibuf->rect) {
+ ImBuf *tmpibuf;
+ MovieTrackingMarker undist_marker= *marker;
+
+ if(user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
+ int width, height;
+ float aspy= 1.0f/clip->tracking.camera.pixel_aspect;;
+
+ BKE_movieclip_get_size(clip, user, &width, &height);
+
+ undist_marker.pos[0]*= width;
+ undist_marker.pos[1]*= height*aspy;
+
+ BKE_tracking_invert_intrinsics(&clip->tracking, undist_marker.pos, undist_marker.pos);
+
+ undist_marker.pos[0]/= width;
+ undist_marker.pos[1]/= height*aspy;
+ }
+
+ tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 1, 1, scopes->track_pos, NULL);
+
+ if(tmpibuf->rect_float)
+ IMB_rect_from_float(tmpibuf);
+
+ if(tmpibuf->rect)
+ scopes->track_preview= tmpibuf;
+ else
+ IMB_freeImBuf(tmpibuf);
+ }
+
+ IMB_freeImBuf(ibuf);
+ }
+
+ if((track->flag&TRACK_LOCKED)==0) {
+ scopes->marker= marker;
+ scopes->track= track;
+ scopes->slide_scale[0]= track->pat_max[0]-track->pat_min[0];
+ scopes->slide_scale[1]= track->pat_max[1]-track->pat_min[1];
+ }
+ }
+ }
+
+ scopes->framenr= user->framenr;
+ scopes->ok= 1;
+}
+
+static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
+{
+ char name[FILE_MAXFILE+FILE_MAXDIR];
+ int quality, rectx, recty;
+ int size= size= rendersize_to_number(proxy_render_size);
+ ImBuf *scaleibuf;
+
+ get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name);
+
+ rectx= ibuf->x*size/100.0f;
+ recty= ibuf->y*size/100.0f;
+
+ scaleibuf= IMB_dupImBuf(ibuf);
+
+ IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
+
+ quality= clip->proxy.quality;
+ scaleibuf->ftype= JPG | quality;
+
+ /* unsupported feature only confuses other s/w */
+ if(scaleibuf->depth==32)
+ scaleibuf->depth= 24;
+
+ BLI_lock_thread(LOCK_MOVIECLIP);
+
+ BLI_make_existing_file(name);
+ if(IMB_saveiff(scaleibuf, name, IB_rect)==0)
+ perror(name);
+
+ BLI_unlock_thread(LOCK_MOVIECLIP);
+
+ IMB_freeImBuf(scaleibuf);
+}
+
+void BKE_movieclip_build_proxy_frame(MovieClip *clip, struct MovieDistortion *distortion,
+ int cfra, int *build_sizes, int build_count, int undistorted)
+{
+ ImBuf *ibuf;
+ MovieClipUser user;
+
+ user.framenr= cfra;
+
+ ibuf= BKE_movieclip_get_ibuf_flag(clip, &user, 0);
+
+ if(ibuf) {
+ ImBuf *tmpibuf= ibuf;
+ int i;
+
+ if(undistorted)
+ tmpibuf= get_undistorted_ibuf(clip, distortion, ibuf);
+
+ for(i= 0; i<build_count; i++)
+ movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted);
+
+ IMB_freeImBuf(ibuf);
+
+ if(tmpibuf!=ibuf)
+ IMB_freeImBuf(tmpibuf);
+ }
+}
+
+void free_movieclip(MovieClip *clip)
+{
+ free_buffers(clip);
+
+ BKE_tracking_free(&clip->tracking);
+}
+
+void unlink_movieclip(Main *bmain, MovieClip *clip)
+{
+ bScreen *scr;
+ ScrArea *area;
+ SpaceLink *sl;
+ Scene *sce;
+ Object *ob;
+
+ for(scr= bmain->screen.first; scr; scr= scr->id.next) {
+ for(area= scr->areabase.first; area; area= area->next) {
+ for(sl= area->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_CLIP) {
+ SpaceClip *sc= (SpaceClip *) sl;
+
+ if(sc->clip==clip)
+ sc->clip= NULL;
+ }
+ else if(sl->spacetype==SPACE_VIEW3D) {
+ View3D *v3d= (View3D *) sl;
+ BGpic *bgpic;
+
+ for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) {
+ if(bgpic->clip==clip)
+ bgpic->clip= NULL;
+ }
+ }
+ }
+ }
+ }
+
+ for(sce= bmain->scene.first; sce; sce= sce->id.next) {
+ if(sce->clip==clip)
+ sce->clip= NULL;
+ }
+
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
+ bConstraint *con= ob->constraints.first;
+
+ for (con= ob->constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+ if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
+ bFollowTrackConstraint *data= (bFollowTrackConstraint *) con->data;
+
+ if(data->clip==clip)
+ data->clip= NULL;
+ }
+ else if(cti->type==CONSTRAINT_TYPE_CAMERASOLVER) {
+ bCameraSolverConstraint *data= (bCameraSolverConstraint *) con->data;
+
+ if(data->clip==clip)
+ data->clip= NULL;
+ }
+ }
+ }
+
+ clip->id.us= 0;
+}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index a9b2ffe7529..115591863cc 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1790,6 +1790,7 @@ static void registerCompositNodes(ListBase *ntypelist)
register_node_type_cmp_value(ntypelist);
register_node_type_cmp_rgb(ntypelist);
register_node_type_cmp_curve_time(ntypelist);
+ register_node_type_cmp_movieclip(ntypelist);
register_node_type_cmp_composite(ntypelist);
register_node_type_cmp_viewer(ntypelist);
@@ -1854,6 +1855,9 @@ static void registerCompositNodes(ListBase *ntypelist)
register_node_type_cmp_glare(ntypelist);
register_node_type_cmp_tonemap(ntypelist);
register_node_type_cmp_lensdist(ntypelist);
+ register_node_type_cmp_transform(ntypelist);
+ register_node_type_cmp_stabilize2d(ntypelist);
+ register_node_type_cmp_moviedistortion(ntypelist);
}
static void registerShaderNodes(ListBase *ntypelist)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 43f199904d5..44a398b8bbe 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -46,6 +46,7 @@
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
@@ -1823,11 +1824,30 @@ void set_no_parent_ipo(int val)
no_parent_ipo= val;
}
-void where_is_object_time(Scene *scene, Object *ob, float ctime)
+static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4])
{
- float *fp1, *fp2, slowmat[4][4] = MAT4_UNITY;
- float stime=ctime, fac1, fac2;
+ float *fp1, *fp2;
+ float fac1, fac2;
int a;
+
+ // include framerate
+ fac1= ( 1.0f / (1.0f + (float)fabs(ob->sf)) );
+ if(fac1 >= 1.0f) return 0;
+ fac2= 1.0f-fac1;
+
+ fp1= obmat[0];
+ fp2= slowmat[0];
+ for(a=0; a<16; a++, fp1++, fp2++) {
+ fp1[0]= fac1*fp1[0] + fac2*fp2[0];
+ }
+
+ return 1;
+}
+
+void where_is_object_time(Scene *scene, Object *ob, float ctime)
+{
+ float slowmat[4][4] = MAT4_UNITY;
+ float stime=ctime;
/* new version: correct parent+vertexparent and track+parent */
/* this one only calculates direct attached parent and track */
@@ -1861,16 +1881,8 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
* An old-fashioned hack which probably doesn't really cut it anymore
*/
if(ob->partype & PARSLOW) {
- // include framerate
- fac1= ( 1.0f / (1.0f + (float)fabs(ob->sf)) );
- if(fac1 >= 1.0f) return;
- fac2= 1.0f-fac1;
-
- fp1= ob->obmat[0];
- fp2= slowmat[0];
- for(a=0; a<16; a++, fp1++, fp2++) {
- fp1[0]= fac1*fp1[0] + fac2*fp2[0];
- }
+ if(!where_is_object_parslow(ob, ob->obmat, slowmat))
+ return;
}
}
else {
@@ -1894,6 +1906,27 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
else ob->transflag &= ~OB_NEG_SCALE;
}
+/* get object transformation matrix without recalculating dependencies and
+ constraints -- assume dependencies are already solved by depsgraph.
+ no changes to object and it's parent would be done.
+ used for bundles orientation in 3d space relative to parented blender camera */
+void where_is_object_mat(Scene *scene, Object *ob, float obmat[4][4])
+{
+ float slowmat[4][4] = MAT4_UNITY;
+
+ if(ob->parent) {
+ Object *par= ob->parent;
+
+ solve_parenting(scene, ob, par, obmat, slowmat, 1);
+
+ if(ob->partype & PARSLOW)
+ where_is_object_parslow(ob, obmat, slowmat);
+ }
+ else {
+ object_to_mat4(ob, obmat);
+ }
+}
+
static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
{
float totmat[4][4];
@@ -2821,3 +2854,28 @@ void object_relink(Object *ob)
ID_NEW(ob->proxy);
ID_NEW(ob->proxy_group);
}
+
+MovieClip *object_get_movieclip(Scene *scene, Object *ob, int use_default)
+{
+ MovieClip *clip= use_default ? scene->clip : NULL;
+ bConstraint *con= ob->constraints.first, *scon= NULL;
+
+ while(con){
+ if(con->type==CONSTRAINT_TYPE_CAMERASOLVER){
+ if(scon==NULL || (scon->flag&CONSTRAINT_OFF))
+ scon= con;
+ }
+
+ con= con->next;
+ }
+
+ if(scon) {
+ bCameraSolverConstraint *solver= scon->data;
+ if((solver->flag&CAMERASOLVER_ACTIVECLIP)==0)
+ clip= solver->clip;
+ else
+ clip= scene->clip;
+ }
+
+ return clip;
+}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 377eeef117e..c80b2880d12 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -202,33 +202,95 @@ void free_plugin_tex(PluginTex *pit)
/* ****************** Mapping ******************* */
-TexMapping *add_mapping(void)
+TexMapping *add_tex_mapping(void)
{
- TexMapping *texmap= MEM_callocN(sizeof(TexMapping), "Tex map");
+ TexMapping *texmap= MEM_callocN(sizeof(TexMapping), "TexMapping");
+ default_tex_mapping(texmap);
+
+ return texmap;
+}
+
+void default_tex_mapping(TexMapping *texmap)
+{
+ memset(texmap, 0, sizeof(TexMapping));
+
texmap->size[0]= texmap->size[1]= texmap->size[2]= 1.0f;
texmap->max[0]= texmap->max[1]= texmap->max[2]= 1.0f;
unit_m4(texmap->mat);
-
- return texmap;
+
+ texmap->projx= PROJ_X;
+ texmap->projy= PROJ_Y;
+ texmap->projz= PROJ_Z;
+ texmap->mapping= MTEX_FLAT;
}
-void init_mapping(TexMapping *texmap)
+void init_tex_mapping(TexMapping *texmap)
{
- float eul[3], smat[3][3], rmat[3][3], mat[3][3];
-
- size_to_mat3( smat,texmap->size);
-
- eul[0]= DEG2RADF(texmap->rot[0]);
- eul[1]= DEG2RADF(texmap->rot[1]);
- eul[2]= DEG2RADF(texmap->rot[2]);
- eul_to_mat3( rmat,eul);
+ float eul[3], smat[3][3], rmat[3][3], mat[3][3], proj[3][3];
+
+ if(texmap->projx == PROJ_X && texmap->projy == PROJ_Y && texmap->projz == PROJ_Z &&
+ is_zero_v3(texmap->loc) && is_zero_v3(texmap->rot) && is_one_v3(texmap->size)) {
+ unit_m4(texmap->mat);
+
+ texmap->flag |= TEXMAP_UNIT_MATRIX;
+ }
+ else {
+ /* axis projection */
+ zero_m3(proj);
+
+ if(texmap->projx != PROJ_N)
+ proj[texmap->projx-1][0]= 1.0f;
+ if(texmap->projy != PROJ_N)
+ proj[texmap->projy-1][1]= 1.0f;
+ if(texmap->projz != PROJ_N)
+ proj[texmap->projz-1][2]= 1.0f;
+
+ /* scale */
+ size_to_mat3(smat, texmap->size);
+
+ /* rotation */
+ eul[0]= DEG2RADF(texmap->rot[0]);
+ eul[1]= DEG2RADF(texmap->rot[1]);
+ eul[2]= DEG2RADF(texmap->rot[2]);
+ eul_to_mat3( rmat,eul);
+
+ /* compose it all */
+ mul_m3_m3m3(mat, rmat, smat);
+ mul_m3_m3m3(mat, proj, mat);
+
+ /* translation */
+ copy_m4_m3(texmap->mat, mat);
+ copy_v3_v3(texmap->mat[3], texmap->loc);
+
+ texmap->flag &= ~TEXMAP_UNIT_MATRIX;
+ }
+}
+
+ColorMapping *add_color_mapping(void)
+{
+ ColorMapping *colormap= MEM_callocN(sizeof(ColorMapping), "ColorMapping");
- mul_m3_m3m3(mat, rmat, smat);
+ default_color_mapping(colormap);
- copy_m4_m3(texmap->mat, mat);
- copy_v3_v3(texmap->mat[3], texmap->loc);
+ return colormap;
+}
+
+void default_color_mapping(ColorMapping *colormap)
+{
+ memset(colormap, 0, sizeof(ColorMapping));
+
+ init_colorband(&colormap->coba, 1);
+
+ colormap->bright= 1.0;
+ colormap->contrast= 1.0;
+ colormap->saturation= 1.0;
+ colormap->blend_color[0]= 0.8f;
+ colormap->blend_color[1]= 0.8f;
+ colormap->blend_color[2]= 0.8f;
+ colormap->blend_type= MA_RAMP_BLEND;
+ colormap->blend_factor= 0.0f;
}
/* ****************** COLORBAND ******************* */
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
new file mode 100644
index 00000000000..a834628641a
--- /dev/null
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -0,0 +1,2206 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/tracking.c
+ * \ingroup bke
+ */
+
+#include <stddef.h>
+#include <limits.h>
+#include <math.h>
+#include <memory.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_scene_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_math_base.h"
+#include "BLI_listbase.h"
+#include "BLI_ghash.h"
+#include "BLI_path_util.h"
+
+#include "BKE_global.h"
+#include "BKE_tracking.h"
+#include "BKE_movieclip.h"
+#include "BKE_object.h"
+#include "BKE_scene.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#ifdef WITH_LIBMV
+# include "libmv-capi.h"
+#else
+struct libmv_Features;
+#endif
+
+typedef struct MovieDistortion {
+ struct libmv_CameraIntrinsics *intrinsics;
+} MovieDistortion;
+
+/*********************** common functions *************************/
+
+void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
+{
+ int a;
+ float pat_min[2];
+ float pat_max[2];
+ float max_pyramid_level_factor = 1.0;
+ if (track->tracker == TRACKER_KLT) {
+ max_pyramid_level_factor = 1 << (track->pyramid_levels - 1);
+ }
+
+ /* sort */
+ for(a= 0; a<2; a++) {
+ if(track->pat_min[a]>track->pat_max[a])
+ SWAP(float, track->pat_min[a], track->pat_max[a]);
+
+ if(track->search_min[a]>track->search_max[a])
+ SWAP(float, track->search_min[a], track->search_max[a]);
+ }
+
+ /* compute the effective pattern size, which differs from the fine resolution
+ * pattern size for the pyramid KLT tracker */
+ for(a= 0; a<2; a++) {
+ pat_min[a] = max_pyramid_level_factor * track->pat_min[a];
+ pat_max[a] = max_pyramid_level_factor * track->pat_max[a];
+ }
+
+ if(event==CLAMP_PAT_DIM) {
+ for(a= 0; a<2; a++) {
+ /* search shouldn't be resized smaller than pattern */
+ track->search_min[a]= MIN2(pat_min[a], track->search_min[a]);
+ track->search_max[a]= MAX2(pat_max[a], track->search_max[a]);
+ }
+ }
+ else if(event==CLAMP_PAT_POS) {
+ float dim[2];
+ sub_v2_v2v2(dim, track->pat_max, pat_min);
+
+ for(a= 0; a<2; a++) {
+ /* pattern shouldn't be moved outside of search */
+ if(pat_min[a] < track->search_min[a]) {
+ track->pat_min[a]= track->search_min[a] - (pat_min[a] - track->pat_min[a]);
+ track->pat_max[a]= (pat_min[a] - track->pat_min[a])+dim[a];
+ }
+ if(track->pat_max[a] > track->search_max[a]) {
+ track->pat_max[a]= track->search_max[a] - (pat_max[a] - track->pat_max[a]);
+ track->pat_min[a]= track->pat_max[a]-dim[a] - (pat_min[a] - track->pat_min[a]);
+ }
+ }
+ }
+ else if(event==CLAMP_SEARCH_DIM) {
+ float max_pyramid_level_factor = 1.0;
+ if (track->tracker == TRACKER_KLT) {
+ max_pyramid_level_factor = 1 << (track->pyramid_levels - 1);
+ }
+ for(a= 0; a<2; a++) {
+ /* search shouldn't be resized smaller than pattern */
+ track->search_min[a]= MIN2(pat_min[a], track->search_min[a]);
+ track->search_max[a]= MAX2(pat_max[a], track->search_max[a]);
+ }
+ }
+ else if(event==CLAMP_SEARCH_POS) {
+ float dim[2];
+ sub_v2_v2v2(dim, track->search_max, track->search_min);
+
+ for(a= 0; a<2; a++) {
+ /* search shouldn't be moved inside pattern */
+ if(track->search_min[a] > pat_min[a]) {
+ track->search_min[a]= pat_min[a];
+ track->search_max[a]= track->search_min[a]+dim[a];
+ }
+ if(track->search_max[a] < pat_max[a]) {
+ track->search_max[a]= pat_max[a];
+ track->search_min[a]= track->search_max[a]-dim[a];
+ }
+ }
+ }
+
+ else if(event==CLAMP_PYRAMID_LEVELS || (event==CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) {
+ float dim[2];
+ sub_v2_v2v2(dim, track->pat_max, track->pat_min);
+ {
+ float search_ratio = 2.3f * max_pyramid_level_factor;
+
+ /* resize the search area to something sensible based
+ * on the number of pyramid levels */
+ for(a= 0; a<2; a++) {
+ track->search_min[a]= search_ratio * track->pat_min[a];
+ track->search_max[a]= search_ratio * track->pat_max[a];
+ }
+ }
+ }
+
+ /* marker's center should be in center of pattern */
+ if(event==CLAMP_PAT_DIM || event==CLAMP_PAT_POS) {
+ float dim[2];
+ sub_v2_v2v2(dim, track->pat_max, track->pat_min);
+
+ for(a= 0; a<2; a++) {
+ track->pat_min[a]= -dim[a]/2.0f;
+ track->pat_max[a]= dim[a]/2.0f;
+ }
+ }
+}
+
+void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear)
+{
+ if(area==TRACK_AREA_NONE)
+ return;
+
+ if(clear) {
+ if(area&TRACK_AREA_POINT) track->flag&= ~flag;
+ if(area&TRACK_AREA_PAT) track->pat_flag&= ~flag;
+ if(area&TRACK_AREA_SEARCH) track->search_flag&= ~flag;
+ } else {
+ if(area&TRACK_AREA_POINT) track->flag|= flag;
+ if(area&TRACK_AREA_PAT) track->pat_flag|= flag;
+ if(area&TRACK_AREA_SEARCH) track->search_flag|= flag;
+ }
+}
+
+MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, float y,
+ int framenr, int width, int height)
+{
+ MovieTrackingTrack *track;
+ MovieTrackingMarker marker;
+
+ /* pick reasonable defaults */
+ float pat[2]= {5.5f, 5.5f}, search[2]= {25.5f, 25.5f}; /* TODO: move to default setting? */
+
+ pat[0] /= (float)width;
+ pat[1] /= (float)height;
+
+ search[0] /= (float)width;
+ search[1] /= (float)height;
+
+ track= MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
+ strcpy(track->name, "Track");
+
+ /* default to KLT tracker */
+ track->tracker = TRACKER_KLT;
+ track->pyramid_levels = 2;
+
+ /* set SAD defaults even though it's not selected by default */
+ track->minimum_correlation= 0.75f;
+
+ memset(&marker, 0, sizeof(marker));
+ marker.pos[0]= x;
+ marker.pos[1]= y;
+ marker.framenr= framenr;
+
+ copy_v2_v2(track->pat_max, pat);
+ negate_v2_v2(track->pat_min, pat);
+
+ copy_v2_v2(track->search_max, search);
+ negate_v2_v2(track->search_min, search);
+
+ BKE_tracking_insert_marker(track, &marker);
+
+ BLI_addtail(&tracking->tracks, track);
+ BKE_track_unique_name(tracking, track);
+
+ return track;
+}
+
+void BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker)
+{
+ MovieTrackingMarker *old_marker= BKE_tracking_get_marker(track, marker->framenr);
+
+ if(old_marker && old_marker->framenr==marker->framenr) {
+ *old_marker= *marker;
+ } else {
+ int a= track->markersnr;
+
+ while(a--) {
+ if(track->markers[a].framenr<marker->framenr)
+ break;
+ }
+
+ track->markersnr++;
+
+ if(track->markers) track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
+ else track->markers= MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
+
+ memmove(track->markers+a+2, track->markers+a+1, (track->markersnr-a-2)*sizeof(MovieTrackingMarker));
+ track->markers[a+1]= *marker;
+
+ track->last_marker= a+1;
+ }
+}
+
+void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr)
+{
+ int a= 0;
+
+ while(a<track->markersnr) {
+ if(track->markers[a].framenr==framenr) {
+ if(track->markersnr>1) {
+ memmove(track->markers+a, track->markers+a+1, (track->markersnr-a-1)*sizeof(MovieTrackingMarker));
+ track->markersnr--;
+ track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
+ } else {
+ MEM_freeN(track->markers);
+ track->markers= NULL;
+ track->markersnr= 0;
+ }
+
+ break;
+ }
+
+ a++;
+ }
+}
+
+MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr)
+{
+ int a= track->markersnr-1;
+
+ if(!track->markersnr)
+ return NULL;
+
+ /* approximate pre-first framenr marker with first marker */
+ if(framenr<track->markers[0].framenr)
+ return &track->markers[0];
+
+ if(track->last_marker<track->markersnr)
+ a= track->last_marker;
+
+ if(track->markers[a].framenr<=framenr) {
+ while(a<track->markersnr && track->markers[a].framenr<=framenr) {
+ if(track->markers[a].framenr==framenr) {
+ track->last_marker= a;
+ return &track->markers[a];
+ }
+ a++;
+ }
+
+ /* if there's no marker for exact position, use nearest marker from left side */
+ return &track->markers[a-1];
+ } else {
+ while(a>=0 && track->markers[a].framenr>=framenr) {
+ if(track->markers[a].framenr==framenr) {
+ track->last_marker= a;
+ return &track->markers[a];
+ }
+
+ a--;
+ }
+
+ /* if there's no marker for exact position, use nearest marker from left side */
+ return &track->markers[a];
+ }
+
+ return NULL;
+}
+
+MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr)
+{
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
+
+ if(marker && marker->framenr!=framenr) {
+ MovieTrackingMarker marker_new;
+
+ marker_new= *marker;
+ marker_new.framenr= framenr;
+
+ BKE_tracking_insert_marker(track, &marker_new);
+ marker= BKE_tracking_get_marker(track, framenr);
+ }
+
+ return marker;
+}
+
+MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr)
+{
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
+
+ if(marker && marker->framenr!=framenr)
+ return NULL;
+
+ return marker;
+}
+
+int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr)
+{
+ return BKE_tracking_exact_marker(track, framenr) != 0;
+}
+
+void BKE_tracking_free_track(MovieTrackingTrack *track)
+{
+ if(track->markers) MEM_freeN(track->markers);
+}
+
+MovieTrackingTrack *BKE_tracking_copy_track(MovieTrackingTrack *track)
+{
+ MovieTrackingTrack *new_track= MEM_dupallocN(track);
+
+ new_track->next= new_track->prev= NULL;
+
+ if(new_track->markers)
+ new_track->markers= MEM_dupallocN(new_track->markers);
+
+ return new_track;
+}
+
+static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite)
+{
+ MovieTrackingMarker marker_new;
+
+ marker_new= *ref_marker;
+ marker_new.flag&= ~MARKER_TRACKED;
+ marker_new.flag|= MARKER_DISABLED;
+
+ if(before) marker_new.framenr--;
+ else marker_new.framenr++;
+
+ if(!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite)
+ BKE_tracking_insert_marker(track, &marker_new);
+}
+
+void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int action)
+{
+ int a;
+
+ if(action==TRACK_CLEAR_REMAINED) {
+ a= 1;
+ while(a<track->markersnr) {
+ if(track->markers[a].framenr>ref_frame) {
+ track->markersnr= a;
+ track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
+
+ break;
+ }
+
+ a++;
+ }
+
+ if(track->markersnr)
+ put_disabled_marker(track, &track->markers[track->markersnr-1], 0, 1);
+ } else if(action==TRACK_CLEAR_UPTO) {
+ a= track->markersnr-1;
+ while(a>=0) {
+ if(track->markers[a].framenr<=ref_frame) {
+ memmove(track->markers, track->markers+a, (track->markersnr-a)*sizeof(MovieTrackingMarker));
+
+ track->markersnr= track->markersnr-a;
+ track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr);
+
+ break;
+ }
+
+ a--;
+ }
+
+ if(track->markersnr)
+ put_disabled_marker(track, &track->markers[0], 1, 1);
+ } else if(action==TRACK_CLEAR_ALL) {
+ MovieTrackingMarker *marker, marker_new;
+
+ marker= BKE_tracking_get_marker(track, ref_frame);
+ marker_new= *marker;
+
+ MEM_freeN(track->markers);
+ track->markers= NULL;
+ track->markersnr= 0;
+
+ BKE_tracking_insert_marker(track, &marker_new);
+
+ put_disabled_marker(track, &marker_new, 1, 1);
+ put_disabled_marker(track, &marker_new, 0, 1);
+ }
+}
+
+int BKE_tracking_test_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
+{
+ int i, a= 0, b= 0, tot= dst_track->markersnr+src_track->markersnr;
+ int count= 0;
+
+ for(i= 0; i<tot; i++) {
+ if(a>=src_track->markersnr) {
+ b++;
+ count++;
+ }
+ else if(b>=dst_track->markersnr) {
+ a++;
+ count++;
+ }
+ else if(src_track->markers[a].framenr<dst_track->markers[b].framenr) {
+ a++;
+ count++;
+ } else if(src_track->markers[a].framenr>dst_track->markers[b].framenr) {
+ b++;
+ count++;
+ } else {
+ if((src_track->markers[a].flag&MARKER_DISABLED)==0 && (dst_track->markers[b].flag&MARKER_DISABLED)==0)
+ return 0;
+
+ a++;
+ b++;
+ count++;
+ }
+ }
+
+ return count;
+}
+
+void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
+{
+ int i, a= 0, b= 0, tot;
+ MovieTrackingMarker *markers;
+
+ tot= BKE_tracking_test_join_tracks(dst_track, src_track);
+
+ markers= MEM_callocN(tot*sizeof(MovieTrackingMarker), "tracking joined tracks");
+
+ for(i= 0; i<tot; i++) {
+ if(b>=dst_track->markersnr) {
+ markers[i]= src_track->markers[a++];
+ }
+ else if(a>=src_track->markersnr) {
+ markers[i]= dst_track->markers[b++];
+ }
+ else if(src_track->markers[a].framenr<dst_track->markers[b].framenr) {
+ markers[i]= src_track->markers[a++];
+ } else if(src_track->markers[a].framenr>dst_track->markers[b].framenr) {
+ markers[i]= dst_track->markers[b++];
+ } else {
+ if((src_track->markers[a].flag&MARKER_DISABLED)) markers[i]= dst_track->markers[b];
+ else markers[i]= src_track->markers[a++];
+
+ a++;
+ b++;
+ }
+ }
+
+ MEM_freeN(dst_track->markers);
+
+ dst_track->markers= markers;
+ dst_track->markersnr= tot;
+}
+
+void BKE_tracking_free(MovieTracking *tracking)
+{
+ MovieTrackingTrack *track;
+
+ for(track= tracking->tracks.first; track; track= track->next) {
+ BKE_tracking_free_track(track);
+ }
+
+ BLI_freelistN(&tracking->tracks);
+
+ if(tracking->reconstruction.cameras)
+ MEM_freeN(tracking->reconstruction.cameras);
+
+ if(tracking->stabilization.scaleibuf)
+ IMB_freeImBuf(tracking->stabilization.scaleibuf);
+
+ if(tracking->camera.intrinsics)
+ BKE_tracking_distortion_destroy(tracking->camera.intrinsics);
+}
+
+/*********************** tracking *************************/
+
+typedef struct TrackContext {
+ MovieTrackingTrack *track;
+
+#ifdef WITH_LIBMV
+ float keyframed_pos[2];
+
+ /* ** KLT tracker ** */
+ struct libmv_RegionTracker *region_tracker;
+ float *patch; /* keyframed patch */
+
+ /* ** SAD tracker ** */
+ int patsize; /* size of pattern (currently only 16x16 due to libmv side) */
+ unsigned char *pattern; /* keyframed pattern */
+ unsigned char *warped; /* warped version of reference */
+#endif
+} TrackContext;
+
+typedef struct MovieTrackingContext {
+ MovieClipUser user;
+ MovieClip *clip;
+
+ int first_time, frames;
+
+ TrackContext *track_context;
+ int num_tracks;
+
+ GHash *hash;
+ MovieTrackingSettings settings;
+
+ short backwards, disable_failed;
+ int sync_frame;
+} MovieTrackingContext;
+
+MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short disable_failed)
+{
+ MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingSettings *settings= &tracking->settings;
+ MovieTrackingTrack *track;
+ TrackContext *track_context;
+
+ context->settings= *settings;
+ context->backwards= backwards;
+ context->disable_failed= disable_failed;
+ context->hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "tracking trackHash");
+ context->sync_frame= user->framenr;
+ context->first_time= 1;
+
+ /* count */
+ track= tracking->tracks.first;
+ while(track) {
+ if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
+
+ if((marker->flag&MARKER_DISABLED)==0)
+ context->num_tracks++;
+ }
+
+ track= track->next;
+ }
+
+ if(context->num_tracks) {
+ int width, height;
+
+ BKE_movieclip_get_size(clip, user, &width, &height);
+
+ /* create tracking data */
+ context->track_context= MEM_callocN(sizeof(TrackContext)*context->num_tracks, "tracking track_context");
+
+ track_context= context->track_context;
+ track= tracking->tracks.first;
+ while(track) {
+ if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ MovieTrackingTrack *new_track= BKE_tracking_copy_track(track);
+
+ track_context->track= new_track;
+#ifdef WITH_LIBMV
+ {
+ if(track_context->track->tracker==TRACKER_KLT) {
+ float search_size_x= (track->search_max[0]-track->search_min[0])*width;
+ float search_size_y= (track->search_max[1]-track->search_min[1])*height;
+ float pattern_size_x= (track->pat_max[0]-track->pat_min[0])*width;
+ float pattern_size_y= (track->pat_max[1]-track->pat_min[1])*height;
+
+ /* compute the maximum pyramid size */
+ double search_to_pattern_ratio= MIN2(search_size_x, search_size_y)
+ / MAX2(pattern_size_x, pattern_size_y);
+ double log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2;
+ int max_pyramid_levels= floor(log2_search_to_pattern_ratio + 1);
+
+ /* try to accomodate the user's choice of pyramid level in a way
+ * that doesn't cause the coarsest pyramid pattern to be larger
+ * than the search size */
+ int level= MIN2(track_context->track->pyramid_levels, max_pyramid_levels);
+ track_context->region_tracker= libmv_regionTrackerNew(100, level);
+ }
+ else if(track_context->track->tracker==TRACKER_SAD) {
+ /* nothing to initialize */
+ }
+ }
+#endif
+
+ BLI_ghash_insert(context->hash, new_track, track);
+
+ track_context++;
+ }
+ }
+
+ track= track->next;
+ }
+ }
+
+ context->clip= clip;
+ context->user= *user;
+
+ return context;
+}
+
+void BKE_tracking_context_free(MovieTrackingContext *context)
+{
+ int a;
+ TrackContext *track_context;
+
+ for(a= 0, track_context= context->track_context; a<context->num_tracks; a++, track_context++) {
+ BKE_tracking_free_track(context->track_context[a].track);
+
+#if WITH_LIBMV
+ if(track_context->region_tracker)
+ libmv_regionTrackerDestroy(track_context->region_tracker);
+
+ if(track_context->patch)
+ MEM_freeN(track_context->patch);
+
+ if(track_context->pattern)
+ MEM_freeN(track_context->pattern);
+
+ if(track_context->warped)
+ MEM_freeN(track_context->warped);
+#endif
+
+ MEM_freeN(track_context->track);
+ }
+
+ if(context->track_context)
+ MEM_freeN(context->track_context);
+
+ BLI_ghash_free(context->hash, NULL, NULL);
+
+ MEM_freeN(context);
+}
+
+static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track)
+{
+ int x, y;
+
+ if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0)
+ return;
+
+ for(y= 0; y<ibuf->y; y++) {
+ for (x= 0; x<ibuf->x; 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;
+ } 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;
+ }
+ }
+ }
+}
+
+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;
+ float mpos[2];
+
+ copy_v2_v2(mpos, marker->pos);
+ if(anchored)
+ add_v2_v2(mpos, track->offset);
+
+ 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;
+
+ 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);
+
+ if(pos != NULL) {
+ pos[0]= mpos[0]*ibuf->x-x1+margin;
+ pos[1]= mpos[1]*ibuf->y-y1+margin;
+ }
+
+ if(origin != NULL) {
+ origin[0]= x1-margin;
+ origin[1]= y1-margin;
+ }
+
+ disable_imbuf_channels(tmpibuf, track);
+
+ return tmpibuf;
+}
+
+ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int margin, int anchored, float pos[2], int origin[2])
+{
+ return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin);
+}
+
+ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int margin, int anchored, float pos[2], int origin[2])
+{
+ return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin);
+}
+
+#ifdef WITH_LIBMV
+static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int *width_r, int *height_r, float pos[2], int origin[2])
+{
+ ImBuf *tmpibuf;
+ float *pixels, *fp;
+ int x, y, width, height;
+
+ width= (track->search_max[0]-track->search_min[0])*ibuf->x;
+ 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);
+
+ *width_r= width;
+ *height_r= height;
+
+ fp= pixels= MEM_callocN(width*height*sizeof(float), "tracking floatBuf");
+ for(y= 0; y<(int)height; y++) {
+ for (x= 0; x<(int)width; x++) {
+ int pixel= tmpibuf->x*y + x;
+
+ 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++;
+ }
+ }
+
+ IMB_freeImBuf(tmpibuf);
+
+ return pixels;
+}
+
+static unsigned char *get_ucharbuf(ImBuf *ibuf)
+{
+ int x, y;
+ unsigned char *pixels, *cp;
+
+ cp= pixels= MEM_callocN(ibuf->x*ibuf->y*sizeof(unsigned char), "tracking ucharBuf");
+ for(y= 0; y<ibuf->y; y++) {
+ for (x= 0; x<ibuf->x; x++) {
+ 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]);
+ } else {
+ unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4;
+
+ *cp= 0.2126f*rrgb[0] + 0.7152f*rrgb[1] + 0.0722f*rrgb[2];
+ }
+
+ cp++;
+ }
+ }
+
+ return pixels;
+}
+
+static unsigned char *get_search_bytebuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int *width_r, int *height_r, float pos[2], int origin[2])
+{
+ ImBuf *tmpibuf;
+ unsigned char *pixels;
+
+ tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
+ disable_imbuf_channels(tmpibuf, track);
+
+ *width_r= tmpibuf->x;
+ *height_r= tmpibuf->y;
+
+ pixels= get_ucharbuf(tmpibuf);
+
+ IMB_freeImBuf(tmpibuf);
+
+ return pixels;
+}
+
+static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
+{
+ ImBuf *ibuf;
+ int framenr_old= context->user.framenr;
+
+ context->user.framenr= framenr;
+
+ ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, 0);
+
+ context->user.framenr= framenr_old;
+
+ return ibuf;
+}
+
+static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed)
+{
+ int framenr= marker->framenr;
+ int a= marker-track->markers;
+
+ *marker_keyed= marker;
+
+ while(a>=0 && a<track->markersnr) {
+ int next= (context->backwards) ? a+1 : a-1;
+ int is_keyframed= 0;
+ MovieTrackingMarker *marker= &track->markers[a];
+ MovieTrackingMarker *next_marker= NULL;
+
+ if(next>=0 && next<track->markersnr)
+ next_marker= &track->markers[next];
+
+ /* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */
+ if(next_marker && next_marker->flag&MARKER_DISABLED)
+ is_keyframed= 1;
+
+ is_keyframed|= (marker->flag&MARKER_TRACKED)==0;
+
+ if(is_keyframed) {
+ framenr= marker->framenr;
+ *marker_keyed= marker;
+ break;
+ }
+
+ a= next;
+ }
+
+ return get_frame_ibuf(context, framenr);
+}
+
+static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int curfra, MovieTrackingMarker **marker_keyed)
+{
+ ImBuf *ibuf= NULL;
+
+ if(context->settings.adjframes == 0) {
+ ibuf= get_keyframed_ibuf(context, track, marker, marker_keyed);
+ } else {
+ ibuf= get_frame_ibuf(context, curfra);
+
+ /* use current marker as keyframed position */
+ *marker_keyed= marker;
+ }
+
+ return ibuf;
+}
+
+static void get_warped(TrackContext *track_context, int x, int y, int width, unsigned char *image)
+{
+ int i, j;
+
+ for(i=0; i<track_context->patsize; i++) {
+ for(j=0; j<track_context->patsize; j++) {
+ track_context->warped[i*track_context->patsize+j]=
+ image[(y+i-track_context->patsize/2)*width+x+j-track_context->patsize/2];
+ }
+ }
+}
+
+#endif
+
+void BKE_tracking_sync(MovieTrackingContext *context)
+{
+ TrackContext *track_context;
+ MovieTracking *tracking= &context->clip->tracking;
+ MovieTrackingTrack *track;
+ ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL};
+ ListBase *old_tracks= &context->clip->tracking.tracks;
+ int a, newframe;
+
+ /* duplicate currently tracking tracks to temporary list.
+ this is needed to keep names in unique state and it's faster to change names
+ of currently tracking tracks (if needed) */
+ for(a= 0, track_context= context->track_context; a<context->num_tracks; a++, track_context++) {
+ int replace_sel= 0;
+ MovieTrackingTrack *new_track, *old;
+
+ track= track_context->track;
+
+ /* find original of tracking track in list of previously displayed tracks */
+ old= BLI_ghash_lookup(context->hash, track);
+ if(old) {
+ MovieTrackingTrack *cur= old_tracks->first;
+
+ while(cur) {
+ if(cur==old)
+ break;
+
+ cur= cur->next;
+ }
+
+ /* original track was found, re-use flags and remove this track */
+ if(cur) {
+ if(cur==tracking->act_track)
+ replace_sel= 1;
+
+ track->flag= cur->flag;
+ track->pat_flag= cur->pat_flag;
+ track->search_flag= cur->search_flag;
+
+ BKE_tracking_free_track(cur);
+ BLI_freelinkN(old_tracks, cur);
+ }
+ }
+
+ new_track= BKE_tracking_copy_track(track);
+
+ BLI_ghash_remove(context->hash, track, NULL, NULL); /* XXX: are we actually need this */
+ BLI_ghash_insert(context->hash, track, new_track);
+
+ if(replace_sel) /* update current selection in clip */
+ tracking->act_track= new_track;
+
+ BLI_addtail(&tracks, new_track);
+ }
+
+ /* move all tracks, which aren't tracking */
+ track= old_tracks->first;
+ while(track) {
+ MovieTrackingTrack *next= track->next;
+
+ track->next= track->prev= NULL;
+ BLI_addtail(&new_tracks, track);
+
+ track= next;
+ }
+
+ /* now move all tracks which are currently tracking and keep their names unique */
+ track= tracks.first;
+ while(track) {
+ MovieTrackingTrack *next= track->next;
+
+ BLI_remlink(&tracks, track);
+
+ track->next= track->prev= NULL;
+ BLI_addtail(&new_tracks, track);
+
+ BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
+
+ track= next;
+ }
+
+ context->clip->tracking.tracks= new_tracks;
+
+ if(context->backwards) newframe= context->user.framenr+1;
+ else newframe= context->user.framenr-1;
+
+ context->sync_frame= newframe;
+}
+
+void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context)
+{
+ user->framenr= context->sync_frame;
+}
+
+int BKE_tracking_next(MovieTrackingContext *context)
+{
+ ImBuf *ibuf_new;
+ int curfra= context->user.framenr;
+ int a, ok= 0;
+
+ /* nothing to track, avoid unneeded frames reading to save time and memory */
+ if(!context->num_tracks)
+ return 0;
+
+ if(context->backwards) context->user.framenr--;
+ else context->user.framenr++;
+
+ ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, 0);
+ if(!ibuf_new)
+ return 0;
+
+ #pragma omp parallel for private(a) shared(ibuf_new, ok) if(context->num_tracks>1)
+ for(a= 0; a<context->num_tracks; a++) {
+ TrackContext *track_context= &context->track_context[a];
+ MovieTrackingTrack *track= track_context->track;
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, curfra);
+
+ if(marker && (marker->flag&MARKER_DISABLED)==0 && marker->framenr==curfra) {
+#ifdef WITH_LIBMV
+ int width, height, origin[2], tracked= 0, need_readjust= 0;
+ float pos[2], margin[2];
+ double x1, y1, x2, y2;
+ ImBuf *ibuf= NULL;
+ MovieTrackingMarker marker_new, *marker_keyed;
+ int onbound= 0, coords_correct= 0;
+ int nextfra;
+
+ if(!context->settings.adjframes) need_readjust= context->first_time;
+ else need_readjust= context->frames%context->settings.adjframes == 0;
+
+ if(context->backwards) nextfra= curfra-1;
+ else nextfra= curfra+1;
+
+ /* margin from frame boundaries */
+ sub_v2_v2v2(margin, track->pat_max, track->pat_min);
+
+ margin[0]= MAX2(margin[0], (float)context->settings.margin / ibuf_new->x);
+ margin[1]= MAX2(margin[1], (float)context->settings.margin / ibuf_new->y);
+
+ /* do not track markers which are too close to boundary */
+ if(marker->pos[0]<margin[0] || marker->pos[0]>1.0f-margin[0] ||
+ marker->pos[1]<margin[1] || marker->pos[1]>1.0f-margin[1]) {
+ onbound= 1;
+ }
+ else if(track_context->track->tracker==TRACKER_KLT) {
+ int wndx, wndy;
+ float *patch_new;
+
+ if(need_readjust) {
+ /* calculate patch for keyframed position */
+ ibuf= get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
+
+ if(track_context->patch)
+ MEM_freeN(track_context->patch);
+
+ track_context->patch= get_search_floatbuf(ibuf, track, marker_keyed, &width, &height, track_context->keyframed_pos, origin);
+
+ IMB_freeImBuf(ibuf);
+ }
+
+ patch_new= get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin);
+
+ x1= track_context->keyframed_pos[0];
+ y1= track_context->keyframed_pos[1];
+
+ x2= pos[0];
+ y2= pos[1];
+
+ wndx= (int)((track->pat_max[0]-track->pat_min[0])*ibuf_new->x)/2;
+ wndy= (int)((track->pat_max[1]-track->pat_min[1])*ibuf_new->y)/2;
+
+ tracked= libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new,
+ width, height, MAX2(wndx, wndy), x1, y1, &x2, &y2);
+
+ MEM_freeN(patch_new);
+ }
+ else if(track_context->track->tracker==TRACKER_SAD) {
+ unsigned char *image_new;
+ float correlation;
+ float warp[3][2]={{0}};
+
+ if(need_readjust) {
+ unsigned char *image;
+
+ /* calculate pattern for keyframed position */
+ ibuf= get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
+
+ image= get_search_bytebuf(ibuf, track, marker_keyed, &width, &height, pos, origin);
+
+ memset(warp, 0, sizeof(warp));
+ warp[0][0]= 1;
+ warp[1][1]= 1;
+ warp[2][0]= pos[0];
+ warp[2][1]= pos[1];
+
+ /* pattern size is hardcoded to 16x16px in libmv */
+ track_context->patsize= 16;
+
+ if(!track_context->pattern)
+ track_context->pattern= MEM_callocN(sizeof(unsigned char)*track_context->patsize*track_context->patsize, "trackking pattern");
+
+ libmv_SADSamplePattern(image, width, warp, track_context->pattern);
+
+ MEM_freeN(image);
+ IMB_freeImBuf(ibuf);
+ }
+
+ image_new= get_search_bytebuf(ibuf_new, track, marker, &width, &height, pos, origin);
+
+ if(track_context->warped==NULL) {
+ unsigned char *image_old;
+
+ ibuf= get_frame_ibuf(context, curfra);
+
+ if(track_context->warped==NULL)
+ track_context->warped= MEM_callocN(sizeof(unsigned char)*track_context->patsize*track_context->patsize, "trackking warped");
+
+ image_old= get_search_bytebuf(ibuf, track, marker, &width, &height, pos, origin);
+ get_warped(track_context, pos[0], pos[1], width, image_old);
+ IMB_freeImBuf(ibuf);
+ MEM_freeN(image_old);
+ }
+
+ memset(warp, 0, sizeof(warp));
+ warp[0][0]= 1;
+ warp[1][1]= 1;
+ warp[2][0]= pos[0];
+ warp[2][1]= pos[1];
+
+ correlation= libmv_SADTrackerTrack(track_context->pattern, track_context->warped, image_new, width, width, height, warp);
+
+ x2= warp[2][0];
+ y2= warp[2][1];
+
+ tracked= track_context->track->minimum_correlation < correlation;
+
+ if(tracked)
+ get_warped(track_context, x2, y2, width, image_new);
+
+ MEM_freeN(image_new);
+ }
+
+ coords_correct= !isnan(x2) && !isnan(y2) && finite(x2) && finite(y2);
+ if(coords_correct && (tracked || !context->disable_failed)) {
+ if(context->first_time) {
+ #pragma omp critical
+ {
+ /* check if there's no keyframe/tracked markers before tracking marker.
+ if so -- create disabled marker before currently tracking "segment" */
+ put_disabled_marker(track, marker, 1, 0);
+ }
+ }
+
+ memset(&marker_new, 0, sizeof(marker_new));
+
+ if(!onbound) {
+ marker_new.pos[0]= (origin[0]+x2)/ibuf_new->x;
+ marker_new.pos[1]= (origin[1]+y2)/ibuf_new->y;
+ } else {
+ copy_v2_v2(marker_new.pos, marker->pos);
+ }
+
+ marker_new.flag|= MARKER_TRACKED;
+ marker_new.framenr= nextfra;
+
+ #pragma omp critical
+ {
+ BKE_tracking_insert_marker(track, &marker_new);
+ }
+
+ /* make currently tracked segment be finished with disabled marker */
+ #pragma omp critical
+ {
+ put_disabled_marker(track, &marker_new, 0, 0);
+ }
+ } else {
+ marker_new= *marker;
+
+ marker_new.framenr= nextfra;
+ marker_new.flag|= MARKER_DISABLED;
+
+ #pragma omp critical
+ {
+ BKE_tracking_insert_marker(track, &marker_new);
+ }
+ }
+
+ ok= 1;
+#endif
+ }
+ }
+
+ IMB_freeImBuf(ibuf_new);
+
+ context->first_time= 0;
+ context->frames++;
+
+ return ok;
+}
+
+#if WITH_LIBMV
+static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height)
+{
+ int tracknr= 0;
+ MovieTrackingTrack *track;
+ struct libmv_Tracks *tracks= libmv_tracksNew();
+
+ track= tracking->tracks.first;
+ while(track) {
+ int a= 0;
+
+ for(a= 0; a<track->markersnr; a++) {
+ MovieTrackingMarker *marker= &track->markers[a];
+
+ if((marker->flag&MARKER_DISABLED)==0)
+ libmv_tracksInsert(tracks, marker->framenr, tracknr,
+ marker->pos[0]*width, marker->pos[1]*height);
+ }
+
+ track= track->next;
+ tracknr++;
+ }
+
+ return tracks;
+}
+
+static int retrieve_libmv_reconstruct(MovieTracking *tracking, struct libmv_Reconstruction *libmv_reconstruction)
+{
+ int tracknr= 0;
+ int sfra= INT_MAX, efra= INT_MIN, a, origin_set= 0;
+ MovieTrackingTrack *track;
+ MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+ MovieReconstructedCamera *reconstructed;
+ float origin[3]= {0.0f, 0.0f, 0.0f};
+ int ok= 1;
+
+ track= tracking->tracks.first;
+ while(track) {
+ double pos[3];
+
+ if(libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) {
+ track->bundle_pos[0]= pos[0];
+ track->bundle_pos[1]= pos[1];
+ track->bundle_pos[2]= pos[2];
+
+ track->flag|= TRACK_HAS_BUNDLE;
+ track->error= libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr);
+ } else {
+ track->flag&= ~TRACK_HAS_BUNDLE;
+ ok= 0;
+
+ printf("No bundle for track #%d '%s'\n", tracknr, track->name);
+ }
+
+ if(track->markersnr) {
+ if(track->markers[0].framenr<sfra) sfra= track->markers[0].framenr;
+ if(track->markers[track->markersnr-1].framenr>efra) efra= track->markers[track->markersnr-1].framenr;
+ }
+
+ track= track->next;
+ tracknr++;
+ }
+
+ if(reconstruction->cameras)
+ MEM_freeN(reconstruction->cameras);
+
+ reconstruction->camnr= 0;
+ reconstruction->cameras= NULL;
+ reconstructed= MEM_callocN((efra-sfra+1)*sizeof(MovieReconstructedCamera), "temp reconstructed camera");
+
+ for(a= sfra; a<=efra; a++) {
+ double matd[4][4];
+
+ if(libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) {
+ int i, j;
+ float mat[4][4];
+ float error= libmv_reporojectionErrorForImage(libmv_reconstruction, a);
+
+ for(i=0; i<4; i++)
+ for(j= 0; j<4; j++)
+ mat[i][j]= matd[i][j];
+
+ if(!origin_set) {
+ copy_v3_v3(origin, mat[3]);
+ origin_set= 1;
+ }
+
+ if(origin_set)
+ sub_v3_v3(mat[3], origin);
+
+ copy_m4_m4(reconstructed[reconstruction->camnr].mat, mat);
+ reconstructed[reconstruction->camnr].framenr= a;
+ reconstructed[reconstruction->camnr].error= error;
+ reconstruction->camnr++;
+ } else {
+ ok= 0;
+ printf("No camera for frame %d\n", a);
+ }
+ }
+
+ if(reconstruction->camnr) {
+ reconstruction->cameras= MEM_callocN(reconstruction->camnr*sizeof(MovieReconstructedCamera), "reconstructed camera");
+ memcpy(reconstruction->cameras, reconstructed, reconstruction->camnr*sizeof(MovieReconstructedCamera));
+ }
+
+ if(origin_set) {
+ track= tracking->tracks.first;
+ while(track) {
+ if(track->flag&TRACK_HAS_BUNDLE)
+ sub_v3_v3(track->bundle_pos, origin);
+
+ track= track->next;
+ }
+ }
+
+ MEM_freeN(reconstructed);
+
+ return ok;
+}
+
+#endif
+
+float BKE_tracking_solve_reconstruction(MovieTracking *tracking, int width, int height)
+{
+#if WITH_LIBMV
+ {
+ MovieTrackingCamera *camera= &tracking->camera;
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+ struct libmv_Tracks *tracks= create_libmv_tracks(tracking, width, height*aspy);
+ struct libmv_Reconstruction *reconstruction = libmv_solveReconstruction(tracks,
+ tracking->settings.keyframe1, tracking->settings.keyframe2,
+ camera->focal,
+ camera->principal[0], camera->principal[1]*aspy,
+ camera->k1, camera->k2, camera->k3);
+ float error= libmv_reprojectionError(reconstruction);
+
+ tracking->reconstruction.error= error;
+
+ if(!retrieve_libmv_reconstruct(tracking, reconstruction))
+ error= -1.0f;
+
+ libmv_destroyReconstruction(reconstruction);
+ libmv_tracksDestroy(tracks);
+
+ tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED;
+
+ return error;
+ }
+#else
+ (void)tracking;
+ (void)width;
+ (void)height;
+
+ return -1.0f;
+#endif
+}
+
+void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track)
+{
+ BLI_uniquename(&tracking->tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
+}
+
+MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char *name)
+{
+ MovieTrackingTrack *track= tracking->tracks.first;
+
+ while(track) {
+ if(!strcmp(track->name, name))
+ return track;
+
+ track= track->next;
+ }
+
+ return NULL;
+}
+
+static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int nearest)
+{
+ MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+ MovieReconstructedCamera *cameras= reconstruction->cameras;
+ int a= 0, d= 1;
+
+ if(!reconstruction->camnr)
+ return -1;
+
+ if(framenr<cameras[0].framenr) {
+ if(nearest) return 0;
+ else return -1;
+ }
+
+ if(framenr>cameras[reconstruction->camnr-1].framenr) {
+ if(nearest) return reconstruction->camnr-1;
+ else return -1;
+ }
+
+ if(reconstruction->last_camera<reconstruction->camnr)
+ a= reconstruction->last_camera;
+
+ if(cameras[a].framenr>=framenr)
+ d= -1;
+
+ while(a>=0 && a<reconstruction->camnr) {
+ int cfra= cameras[a].framenr;
+
+ /* check if needed framenr was "skipped" -- no data for requested frame */
+
+ if(d>0 && cfra>framenr) {
+ /* interpolate with previous position */
+ if(nearest) return a-1;
+ else break;
+ }
+
+ if(d<0 && cfra<framenr) {
+ /* interpolate with next position */
+ if(nearest) return a;
+ else break;
+ }
+
+ if(cfra==framenr) {
+ reconstruction->last_camera= a;
+
+ return a;
+ }
+
+ a+= d;
+ }
+
+ return -1;
+}
+
+MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr)
+{
+ int a= reconstruction_camera_index(tracking, framenr, 0);
+
+ if(a==-1)
+ return NULL;
+
+ return &tracking->reconstruction.cameras[a];
+}
+
+void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr, float mat[4][4])
+{
+ MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+ MovieReconstructedCamera *cameras= reconstruction->cameras;
+ int a= reconstruction_camera_index(tracking, framenr, 1);
+
+ if(a==-1) {
+ unit_m4(mat);
+ return;
+ }
+
+ if(cameras[a].framenr!=framenr && a>0 && a<reconstruction->camnr-1) {
+ float t= ((float)framenr-cameras[a].framenr) / (cameras[a+1].framenr-cameras[a].framenr);
+
+ blend_m4_m4m4(mat, cameras[a].mat, cameras[a+1].mat, t);
+ } else {
+ copy_m4_m4(mat, cameras[a].mat);
+ }
+}
+
+void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
+{
+ if(!ob) {
+ if(scene->camera) ob= scene->camera;
+ else ob= scene_find_camera(scene);
+ }
+
+ if(ob)
+ where_is_object_mat(scene, ob, mat);
+ else
+ unit_m4(mat);
+}
+
+void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
+{
+ *shiftx= (0.5f*winx-tracking->camera.principal[0]) / winx;
+ *shifty= (0.5f*winy-tracking->camera.principal[1]) / winx;
+}
+
+void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
+{
+ float focal= tracking->camera.focal;
+
+ camera->sensor_x= tracking->camera.sensor_width;
+ camera->sensor_fit= CAMERA_SENSOR_FIT_AUTO;
+ camera->lens= focal*camera->sensor_x/width;
+
+ scene->r.xsch= width*tracking->camera.pixel_aspect;
+ scene->r.ysch= height;
+
+ scene->r.xasp= 1.0f;
+ scene->r.yasp= 1.0f;
+
+ 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])
+{
+ MovieReconstructedCamera *camera;
+ float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx;
+ float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
+ float winmat[4][4];
+ float ycor= 1.0f/tracking->camera.pixel_aspect;
+ float shiftx, shifty, winside= MAX2(winx, winy);
+
+ BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty);
+
+ clipsta= 0.1f;
+ clipend= 1000.0f;
+
+ if(winx >= winy)
+ viewfac= (lens*winx)/tracking->camera.sensor_width;
+ else
+ viewfac= (ycor*lens*winy)/tracking->camera.sensor_width;
+
+ pixsize= clipsta/viewfac;
+
+ left= -0.5f*(float)winx + shiftx*winside;
+ bottom= -0.5f*(ycor)*(float)winy + shifty*winside;
+ right= 0.5f*(float)winx + shiftx*winside;
+ top= 0.5f*(ycor)*(float)winy + shifty*winside;
+
+ left *= pixsize;
+ right *= pixsize;
+ bottom *= pixsize;
+ top *= pixsize;
+
+ perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
+
+ camera= BKE_tracking_get_reconstructed_camera(tracking, framenr);
+ if(camera) {
+ float imat[4][4];
+
+ invert_m4_m4(imat, camera->mat);
+ mul_m4_m4m4(mat, imat, winmat);
+ } else copy_m4_m4(mat, winmat);
+}
+
+void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
+{
+ MovieTrackingCamera *camera= &tracking->camera;
+
+#ifdef WITH_LIBMV
+ double x, y;
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+
+ /* normalize coords */
+ x= (co[0]-camera->principal[0]) / camera->focal;
+ y= (co[1]-camera->principal[1] * aspy) / camera->focal;
+
+ libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
+ camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+
+ /* result is in image coords already */
+ nco[0]= x;
+ nco[1]= y;
+#else
+ (void)camera;
+ (void)co;
+ (void)nco;
+#endif
+}
+
+void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
+{
+ MovieTrackingCamera *camera= &tracking->camera;
+
+#ifdef WITH_LIBMV
+ double x= co[0], y= co[1];
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+
+ libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy,
+ camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+
+ nco[0]= x * camera->focal + camera->principal[0];
+ nco[1]= y * camera->focal + camera->principal[1] * aspy;
+#else
+ (void)camera;
+ (void)co;
+ (void)nco;
+#endif
+}
+
+#ifdef WITH_LIBMV
+static int point_in_stroke(bGPDstroke *stroke, float x, float y)
+{
+ int i, prev;
+ int count= 0;
+ bGPDspoint *points= stroke->points;
+
+ prev= stroke->totpoints-1;
+
+ for(i= 0; i<stroke->totpoints; i++) {
+ if((points[i].y<y && points[prev].y>=y) || (points[prev].y<y && points[i].y>=y)) {
+ float fac= (y-points[i].y)/(points[prev].y-points[i].y);
+
+ if (points[i].x+fac*(points[prev].x-points[i].x)<x)
+ count++;
+ }
+
+ prev= i;
+ }
+
+ return count%2;
+}
+
+static int point_in_layer(bGPDlayer *layer, float x, float y)
+{
+ bGPDframe *frame= layer->frames.first;
+
+ while(frame) {
+ bGPDstroke *stroke= frame->strokes.first;
+ while(stroke) {
+ if(point_in_stroke(stroke, x, y))
+ return 1;
+
+ stroke= stroke->next;
+ }
+ frame= frame->next;
+ }
+
+ 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)
+{
+ int a;
+
+ a= libmv_countFeatures(features);
+ while(a--) {
+ MovieTrackingTrack *track;
+ double x, y, size, score;
+ int ok= 1;
+ float xu, yu;
+
+ libmv_getFeature(features, a, &x, &y, &score, &size);
+
+ xu= x/width;
+ yu= y/height;
+
+ if(layer)
+ ok= point_in_layer(layer, xu, yu)!=place_outside_layer;
+
+ if(ok) {
+ track= BKE_tracking_add_track(tracking, xu, yu, framenr, width, height);
+ track->flag|= SELECT;
+ track->pat_flag|= SELECT;
+ track->search_flag|= SELECT;
+ }
+ }
+}
+#endif
+
+void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
+ int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
+ int place_outside_layer)
+{
+#ifdef WITH_LIBMV
+ 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);
+
+ MEM_freeN(pixels);
+
+ retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer);
+
+ libmv_destroyFeatures(features);
+#else
+ (void)tracking;
+ (void)ibuf;
+ (void)framenr;
+ (void)margin;
+ (void)min_trackness;
+ (void)min_distance;
+ (void)layer;
+ (void)place_outside_layer;
+#endif
+}
+
+MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr)
+{
+ MovieTrackingTrack *track= tracking->tracks.first;
+ int cur= 1;
+
+ while(track) {
+ if(track->flag&TRACK_HAS_BUNDLE) {
+ if(cur==tracknr)
+ return track;
+
+ cur++;
+ }
+
+ track= track->next;
+ }
+
+ return NULL;
+}
+
+static int stabilization_median_point(MovieTracking *tracking, int framenr, float median[2])
+{
+ int ok= 0;
+ float min[2], max[2];
+ MovieTrackingTrack *track;
+
+ INIT_MINMAX2(min, max);
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(track->flag&TRACK_USE_2D_STAB) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
+
+ DO_MINMAX2(marker->pos, min, max);
+
+ ok= 1;
+ }
+
+ track= track->next;
+ }
+
+ median[0]= (max[0]+min[0])/2.0f;
+ median[1]= (max[1]+min[1])/2.0f;
+
+ return ok;
+}
+
+static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height,
+ float firstmedian[2], float median[2], float loc[2], float *scale, float *angle)
+{
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+
+ *scale= (stab->scale-1.0f)*stab->scaleinf+1.0f;
+ *angle= 0.0f;
+
+ loc[0]= (firstmedian[0]-median[0])*width*(*scale);
+ loc[1]= (firstmedian[1]-median[1])*height*(*scale);
+
+ mul_v2_fl(loc, stab->locinf);
+
+ if(stab->rot_track && stab->rotinf) {
+ MovieTrackingMarker *marker;
+ float a[2], b[2];
+ float x0= (float)width/2.0f, y0= (float)height/2.0f;
+ float x= median[0]*width, y= median[1]*height;
+
+ marker= BKE_tracking_get_marker(stab->rot_track, 1);
+ sub_v2_v2v2(a, marker->pos, firstmedian);
+ a[0]*= width;
+ a[1]*= height;
+
+ marker= BKE_tracking_get_marker(stab->rot_track, framenr);
+ sub_v2_v2v2(b, marker->pos, median);
+ b[0]*= width;
+ b[1]*= height;
+
+ *angle= -atan2(a[0]*b[1]-a[1]*b[0], a[0]*b[0]+a[1]*b[1]);
+ *angle*= stab->rotinf;
+
+ /* convert to rotation around image center */
+ loc[0]-= (x0 + (x-x0)*cos(*angle)-(y-y0)*sin(*angle) - x)*(*scale);
+ loc[1]-= (y0 + (x-x0)*sin(*angle)+(y-y0)*cos(*angle) - y)*(*scale);
+ }
+}
+
+static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height)
+{
+ float firstmedian[2];
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+
+ if(stab->ok)
+ return stab->scale;
+
+ if(stabilization_median_point(tracking, 1, firstmedian)) {
+ int sfra= INT_MAX, efra= INT_MIN, cfra;
+ float delta[2]= {0.0f, 0.0f}, scalex= 1.0f, scaley= 1.0f;
+ MovieTrackingTrack *track;
+
+ stab->scale= 1.0f;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(track->flag&TRACK_USE_2D_STAB || track==stab->rot_track) {
+ if(track->markersnr) {
+ sfra= MIN2(sfra, track->markers[0].framenr);
+ efra= MAX2(efra, track->markers[track->markersnr-1].framenr);
+ }
+ }
+
+ track= track->next;
+ }
+
+ for(cfra=sfra; cfra<=efra; cfra++) {
+ float median[2], near[2];
+ float loc[2], scale, angle;
+
+ stabilization_median_point(tracking, cfra, median);
+
+ calculate_stabdata(tracking, cfra, width, height, firstmedian, median,
+ loc, &scale, &angle);
+
+ if(angle==0.0f) {
+ loc[0]= fabsf(loc[0]);
+ loc[1]= fabsf(loc[1]);
+
+ delta[0]= MAX2(delta[0], loc[0]);
+ delta[1]= MAX2(delta[1], loc[1]);
+
+ near[0]= MIN2(median[0], 1.0f-median[0]);
+ near[1]= MIN2(median[1], 1.0f-median[1]);
+ near[0]= MAX2(near[0], 0.05f);
+ near[1]= MAX2(near[1], 0.05f);
+
+ scalex= 1.0f+delta[0]/(near[0]*width);
+ scaley= 1.0f+delta[1]/(near[1]*height);
+ } else {
+ int i;
+ float mat[4][4];
+ float points[4][2]={{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}};
+
+ BKE_tracking_stabdata_to_mat4(width, height, loc, scale, angle, mat);
+
+ for(i= 0; i<4; i++) {
+ int j;
+ float a[3]= {0.0f, 0.0f, 0.0f}, b[3]= {0.0f, 0.0f, 0.0f};
+
+ copy_v3_v3(a, points[i]);
+ copy_v3_v3(b, points[(i+1)%4]);
+
+ mul_m4_v3(mat, a);
+ mul_m4_v3(mat, b);
+
+ for(j= 0; j<4; j++) {
+ float point[3]= {points[j][0], points[j][1], 0.0f};
+ float v1[3], v2[3];
+
+ sub_v3_v3v3(v1, b, a);
+ sub_v3_v3v3(v2, point, a);
+
+ if(cross_v2v2(v1, v2) >= 0.0f) {
+ float dist= dist_to_line_v2(point, a, b);
+ if(i%2==0) {
+ scalex= MAX2(scalex, (width+2*dist)/width);
+ } else {
+ scaley= MAX2(scaley, (height+2*dist)/height);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ stab->scale= MAX2(scalex, scaley);
+
+ if(stab->maxscale>0.0f)
+ stab->scale= MIN2(stab->scale, stab->maxscale);
+ } else {
+ stab->scale= 1.0f;
+ }
+
+ stab->ok= 1;
+
+ return stab->scale;
+}
+
+static ImBuf* stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill)
+{
+ int flags;
+
+ if(cacheibuf && (cacheibuf->x != srcibuf->x || cacheibuf->y != srcibuf->y)) {
+ IMB_freeImBuf(cacheibuf);
+ cacheibuf= NULL;
+ }
+
+ flags= IB_rect;
+
+ if(srcibuf->rect_float)
+ flags|= IB_rectfloat;
+
+ if(cacheibuf) {
+ if(fill) {
+ float col[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+ IMB_rectfill(cacheibuf, col);
+ }
+ }
+ else {
+ cacheibuf= IMB_allocImBuf(srcibuf->x, srcibuf->y, srcibuf->depth, flags);
+ cacheibuf->profile= srcibuf->profile;
+ }
+
+ return cacheibuf;
+}
+
+void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle)
+{
+ float firstmedian[2], median[2];
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+
+ if((stab->flag&TRACKING_2D_STABILIZATION)==0) {
+ zero_v2(loc);
+ *scale= 1.0f;
+ *angle= 0.0f;
+
+ return;
+ }
+
+ if(stabilization_median_point(tracking, 1, firstmedian)) {
+ stabilization_median_point(tracking, framenr, median);
+
+ if((stab->flag&TRACKING_AUTOSCALE)==0)
+ stab->scale= 1.0f;
+
+ if(!stab->ok) {
+ if(stab->flag&TRACKING_AUTOSCALE)
+ stabilization_auto_scale_factor(tracking, width, height);
+
+ calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
+
+ stab->ok= 1;
+ } else {
+ calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle);
+ }
+ } else {
+ zero_v2(loc);
+ *scale= 1.0f;
+ *angle= 0.0f;
+ }
+}
+
+ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale, float *angle)
+{
+ float tloc[2], tscale, tangle;
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+ ImBuf *tmpibuf;
+ float width= ibuf->x, height= ibuf->y;
+
+ if(loc) copy_v2_v2(tloc, loc);
+ if(scale) tscale= *scale;
+
+ if((stab->flag&TRACKING_2D_STABILIZATION)==0) {
+ if(loc) zero_v2(loc);
+ if(scale) *scale= 1.0f;
+
+ return ibuf;
+ }
+
+ BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle);
+
+ tmpibuf= stabilize_alloc_ibuf(NULL, ibuf, 1);
+
+ /* scale would be handled by matrix transformation when angle is non-zero */
+ if(tscale!=1.0f && tangle==0.0f) {
+ ImBuf *scaleibuf;
+
+ stabilization_auto_scale_factor(tracking, width, height);
+
+ scaleibuf= stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0);
+ stab->scaleibuf= scaleibuf;
+
+ IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y);
+ IMB_scalefastImBuf(scaleibuf, ibuf->x*tscale, ibuf->y*tscale);
+
+ ibuf= scaleibuf;
+ }
+
+ if(tangle==0.0f) {
+ /* if angle is zero, then it's much faster to use rect copy
+ but could be issues with subpixel precisions */
+ IMB_rectcpy(tmpibuf, ibuf, tloc[0]-(tscale-1.0f)*width/2.0f, tloc[1]-(tscale-1.0f)*height/2.0f, 0, 0, ibuf->x, ibuf->y);
+ } else {
+ float mat[4][4];
+ int i, j;
+
+ BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, tloc, tscale, tangle, mat);
+ invert_m4(mat);
+
+ for(j=0; j<tmpibuf->y; j++) {
+ for(i=0; i<tmpibuf->x;i++) {
+ float vec[3]= {i, j, 0};
+
+ mul_v3_m4v3(vec, mat, vec);
+
+ /* TODO: add selector for interpolation method */
+ neareast_interpolation(ibuf, tmpibuf, vec[0], vec[1], i, j);
+ }
+ }
+ }
+
+ tmpibuf->userflags|= IB_MIPMAP_INVALID;
+
+ if(tmpibuf->rect_float)
+ tmpibuf->userflags|= IB_RECT_INVALID;
+
+ if(loc) copy_v2_v2(loc, tloc);
+ if(scale) *scale= tscale;
+ if(angle) *angle= tangle;
+
+ return tmpibuf;
+}
+
+void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4])
+{
+ float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
+ float svec[3]= {scale, scale, scale};
+
+ unit_m4(rmat);
+ unit_m4(lmat);
+ unit_m4(smat);
+ unit_m4(cmat);
+
+ /* image center as rotation center */
+ cmat[3][0]= (float)width/2.0f;
+ cmat[3][1]= (float)height/2.0f;
+ invert_m4_m4(icmat, cmat);
+
+ size_to_mat4(smat, svec); /* scale matrix */
+ add_v2_v2(lmat[3], loc); /* tranlation matrix */
+ rotate_m4(rmat, 'Z', angle); /* rotation matrix */
+
+ /* compose transformation matrix */
+ mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL);
+}
+
+MovieDistortion *BKE_tracking_distortion_create(void)
+{
+ MovieDistortion *distortion;
+
+ distortion= MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+
+ return distortion;
+}
+
+MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
+{
+ MovieDistortion *new_distortion;
+
+ new_distortion= MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+
+#ifdef WITH_LIBMV
+ new_distortion->intrinsics= libmv_CameraIntrinsicsCopy(distortion->intrinsics);
+#else
+ (void)distortion;
+#endif
+
+ return new_distortion;
+}
+
+void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height)
+{
+ MovieTrackingCamera *camera= &tracking->camera;
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+
+#ifdef WITH_LIBMV
+ if(!distortion->intrinsics) {
+ distortion->intrinsics= libmv_CameraIntrinsicsNew(camera->focal,
+ camera->principal[0], camera->principal[1] * aspy,
+ camera->k1, camera->k2, camera->k3, width, height * aspy);
+ } else {
+ libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal,
+ camera->principal[0], camera->principal[1] * aspy,
+ camera->k1, camera->k2, camera->k3, width, height * aspy);
+ }
+#else
+ (void)distortion;
+ (void)width;
+ (void)height;
+ (void)camera;
+ (void)aspy;
+#endif
+}
+
+ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking,
+ ImBuf *ibuf, int width, int height, float overscan, int undistort)
+{
+ ImBuf *resibuf;
+
+ BKE_tracking_distortion_update(distortion, tracking, width, height);
+
+ resibuf= IMB_dupImBuf(ibuf);
+
+ if(ibuf->rect_float) {
+#ifdef WITH_LIBMV
+ if(undistort) {
+ libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
+ ibuf->rect_float, resibuf->rect_float,
+ ibuf->x, ibuf->y, overscan, ibuf->channels);
+ } else {
+ libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
+ ibuf->rect_float, resibuf->rect_float,
+ ibuf->x, ibuf->y, overscan, ibuf->channels);
+ }
+#endif
+
+ ibuf->userflags|= IB_RECT_INVALID;
+ } else {
+#ifdef WITH_LIBMV
+ if(undistort) {
+ libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
+ (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
+ ibuf->x, ibuf->y, overscan, ibuf->channels);
+ } else {
+ libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
+ (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect,
+ ibuf->x, ibuf->y, overscan, ibuf->channels);
+ }
+#endif
+ }
+
+#ifndef WITH_LIBMV
+ (void)overscan;
+ (void)undistort;
+#endif
+
+ return resibuf;
+}
+
+void BKE_tracking_distortion_destroy(MovieDistortion *distortion)
+{
+#ifdef WITH_LIBMV
+ libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
+#endif
+
+ MEM_freeN(distortion);
+}
+
+ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
+{
+ MovieTrackingCamera *camera= &tracking->camera;
+
+ if(camera->intrinsics == NULL)
+ camera->intrinsics= BKE_tracking_distortion_create();
+
+ return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1);
+}
+
+ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan)
+{
+ MovieTrackingCamera *camera= &tracking->camera;
+
+ if(camera->intrinsics == NULL)
+ camera->intrinsics= BKE_tracking_distortion_create();
+
+ return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0);
+}
+
+/* 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)
+{
+ if(extend) {
+ BKE_tracking_track_flag(track, area, SELECT, 0);
+ } else {
+ MovieTrackingTrack *cur= tracking->tracks.first;
+
+ while(cur) {
+ if(cur==track) {
+ BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
+ BKE_tracking_track_flag(cur, area, SELECT, 0);
+ }
+ else {
+ BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1);
+ }
+
+ cur= cur->next;
+ }
+ }
+}
+
+void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
+{
+ BKE_tracking_track_flag(track, area, SELECT, 1);
+}
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index bd911adeba2..6dd666842d0 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -71,7 +71,8 @@ int BLI_system_thread_count(void); /* gets the number of threads the system can
#define LOCK_RCACHE 4
#define LOCK_OPENGL 5
#define LOCK_NODES 6
-#define LOCK_SCANFILL 7
+#define LOCK_MOVIECLIP 7
+#define LOCK_SCANFILL 8
void BLI_lock_thread(int type);
void BLI_unlock_thread(int type);
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
index 259b25e67dd..8ad79dd819a 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenlib/intern/bpath.c
@@ -362,7 +362,7 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab
void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data)
{
Image *ima;
- const char *absbase= (flag & BPATH_TRAVERSE_ABS) ? (id->lib ? id->lib->filepath : bmain->name) : NULL;
+ const char *absbase= (flag & BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
if ((flag & BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) {
return;
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index f80458682e1..4f3a4a4adf2 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -114,6 +114,7 @@ static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _scanfill_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mainid;
static int thread_levels= 0; /* threads can be invoked inside threads */
@@ -351,8 +352,13 @@ void BLI_lock_thread(int type)
pthread_mutex_lock(&_opengl_lock);
else if (type==LOCK_NODES)
pthread_mutex_lock(&_nodes_lock);
+<<<<<<< .working
else if (type == LOCK_SCANFILL)
pthread_mutex_lock(&_scanfill_lock);
+=======
+ else if (type==LOCK_MOVIECLIP)
+ pthread_mutex_lock(&_movieclip_lock);
+>>>>>>> .merge-right.r41638
}
void BLI_unlock_thread(int type)
@@ -371,8 +377,13 @@ void BLI_unlock_thread(int type)
pthread_mutex_unlock(&_opengl_lock);
else if(type==LOCK_NODES)
pthread_mutex_unlock(&_nodes_lock);
+<<<<<<< .working
else if(type == LOCK_SCANFILL)
pthread_mutex_unlock(&_scanfill_lock);
+=======
+ else if(type==LOCK_MOVIECLIP)
+ pthread_mutex_unlock(&_movieclip_lock);
+>>>>>>> .merge-right.r41638
}
/* Mutex Locks */
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 3f08e2301a7..6e4dcb66bfb 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -301,11 +301,17 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
/* makes lookup of existing images in old main */
blo_make_image_pointer_map(fd, oldmain);
+ /* makes lookup of existing video clips in old main */
+ blo_make_movieclip_pointer_map(fd, oldmain);
+
bfd= blo_read_file_internal(fd, filename);
/* ensures relinked images are not freed */
blo_end_image_pointer_map(fd, oldmain);
+ /* ensures relinked movie clips are not freed */
+ blo_end_movieclip_pointer_map(fd, oldmain);
+
/* move libraries from old main to new main */
if(bfd && mainlist.first!=mainlist.last) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 506e931cecf..a4e71293177 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -88,6 +88,7 @@
#include "DNA_space_types.h"
#include "DNA_vfont_types.h"
#include "DNA_world_types.h"
+#include "DNA_movieclip_types.h"
#include "MEM_guardedalloc.h"
@@ -131,6 +132,7 @@
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#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"
@@ -1039,6 +1041,8 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->globmap);
if (fd->imamap)
oldnewmap_free(fd->imamap);
+ if (fd->movieclipmap)
+ oldnewmap_free(fd->movieclipmap);
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
oldnewmap_free(fd->libmap);
if (fd->bheadmap)
@@ -1114,6 +1118,13 @@ static void *newimaadr(FileData *fd, void *adr) /* used to restore image data a
return NULL;
}
+static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
+{
+ if(fd->movieclipmap && adr)
+ return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
+ return NULL;
+}
+
static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
{
@@ -1242,6 +1253,62 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
}
}
+void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain)
+{
+ MovieClip *clip= oldmain->movieclip.first;
+ Scene *sce= oldmain->scene.first;
+
+ fd->movieclipmap= oldnewmap_new();
+
+ for(;clip; clip= clip->id.next) {
+ if(clip->cache)
+ oldnewmap_insert(fd->movieclipmap, clip->cache, clip->cache, 0);
+
+ if(clip->tracking.camera.intrinsics)
+ oldnewmap_insert(fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0);
+ }
+
+ for(; sce; sce= sce->id.next) {
+ if(sce->nodetree) {
+ bNode *node;
+ for(node= sce->nodetree->nodes.first; node; node= node->next)
+ if(node->type==CMP_NODE_MOVIEDISTORTION)
+ oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0);
+ }
+ }
+}
+
+/* set old main movie clips caches to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
+{
+ OldNew *entry= fd->movieclipmap->entries;
+ MovieClip *clip= oldmain->movieclip.first;
+ Scene *sce= oldmain->scene.first;
+ int i;
+
+ /* used entries were restored, so we put them to zero */
+ for (i=0; i<fd->movieclipmap->nentries; i++, entry++) {
+ if (entry->nr>0)
+ entry->newp= NULL;
+ }
+
+ for(;clip; clip= clip->id.next) {
+ clip->cache= newmclipadr(fd, clip->cache);
+ clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics);
+ }
+
+ for(; sce; sce= sce->id.next) {
+ if(sce->nodetree) {
+ bNode *node;
+ for(node= sce->nodetree->nodes.first; node; node= node->next)
+ if(node->type==CMP_NODE_MOVIEDISTORTION)
+ node->storage= newmclipadr(fd, node->storage);
+ }
+ }
+}
+
+
/* undo file support: add all library pointers in lookup */
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd)
{
@@ -2228,7 +2295,11 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
link_list(fd, &node->inputs);
link_list(fd, &node->outputs);
- node->storage= newdataadr(fd, node->storage);
+ if(node->type == CMP_NODE_MOVIEDISTORTION) {
+ node->storage= newmclipadr(fd, node->storage);
+ } else
+ node->storage= newdataadr(fd, node->storage);
+
if(node->storage) {
/* could be handlerized at some point */
if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
@@ -4059,6 +4130,7 @@ static void direct_link_pose(FileData *fd, bPose *pose)
direct_link_motionpath(fd, pchan->mpath);
pchan->iktree.first= pchan->iktree.last= NULL;
+ pchan->siktree.first= pchan->siktree.last= NULL;
/* incase this value changes in future, clamp else we get undefined behavior */
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
@@ -4828,6 +4900,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
if(sce->nodetree)
direct_link_nodetree(fd, sce->nodetree);
+ sce->clip= newlibadr_us(fd, sce->id.lib, sce->clip);
}
/* ************ READ WM ***************** */
@@ -4982,6 +5055,7 @@ static void lib_link_screen(FileData *fd, Main *main)
for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) {
bgpic->ima= newlibadr_us(fd, sc->id.lib, bgpic->ima);
+ bgpic->clip= newlibadr_us(fd, sc->id.lib, bgpic->clip);
}
if(v3d->localvd) {
v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
@@ -5104,6 +5178,14 @@ static void lib_link_screen(FileData *fd, Main *main)
snode->linkdrag.first = snode->linkdrag.last = NULL;
}
+ else if(sl->spacetype==SPACE_CLIP) {
+ SpaceClip *sclip= (SpaceClip *)sl;
+
+ sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip);
+
+ sclip->scopes.track_preview = NULL;
+ sclip->scopes.ok = 0;
+ }
}
sa= sa->next;
}
@@ -5191,6 +5273,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) {
bgpic->ima= restore_pointer_by_name(newmain, (ID *)bgpic->ima, 1);
+ bgpic->clip= restore_pointer_by_name(newmain, (ID *)bgpic->clip, 1);
}
if(v3d->localvd) {
/*Base *base;*/
@@ -5333,6 +5416,13 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
snode->nodetree= restore_pointer_by_name(newmain, &snode->nodetree->id, 1);
}
}
+ else if(sl->spacetype==SPACE_CLIP) {
+ SpaceClip *sclip= (SpaceClip *)sl;
+
+ sclip->clip= restore_pointer_by_name(newmain, (ID *)sclip->clip, 1);
+
+ sclip->scopes.ok = 0;
+ }
}
sa= sa->next;
}
@@ -5816,6 +5906,55 @@ static void lib_link_group(FileData *fd, Main *main)
}
}
+/* ***************** READ MOVIECLIP *************** */
+
+static void direct_link_movieclip(FileData *fd, MovieClip *clip)
+{
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+
+ if(fd->movieclipmap) clip->cache= newmclipadr(fd, clip->cache);
+ else clip->cache= NULL;
+
+ 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;
+ }
+
+ clip->tracking.act_track= newdataadr(fd, clip->tracking.act_track);
+
+ clip->anim= NULL;
+ clip->tracking_context= NULL;
+
+ clip->tracking.stabilization.ok= 0;
+ clip->tracking.stabilization.scaleibuf= NULL;
+ clip->tracking.stabilization.rot_track= newdataadr(fd, clip->tracking.stabilization.rot_track);
+}
+
+static void lib_link_movieclip(FileData *fd, Main *main)
+{
+ MovieClip *clip;
+
+ clip= main->movieclip.first;
+ while(clip) {
+ if(clip->id.flag & LIB_NEEDLINK) {
+ clip->gpd= newlibadr_us(fd, clip->id.lib, clip->gpd);
+
+ clip->id.flag -= LIB_NEEDLINK;
+ }
+ clip= clip->id.next;
+ }
+}
+
/* ************** GENERAL & MAIN ******************** */
@@ -5850,6 +5989,7 @@ static const char *dataname(short id_code)
case ID_BR: return "Data from BR";
case ID_PA: return "Data from PA";
case ID_GD: return "Data from GD";
+ case ID_MC: return "Data from MC";
}
return "Data from Lib Block";
@@ -5917,7 +6057,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
if(id->flag & LIB_FAKEUSER) id->us= 1;
else id->us= 0;
id->icon_id = 0;
- id->flag &= ~LIB_ID_RECALC;
+ id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA);
/* this case cannot be direct_linked: it's just the ID part */
if(bhead->code==ID_ID) {
@@ -6019,6 +6159,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
case ID_GD:
direct_link_gpencil(fd, (bGPdata *)id);
break;
+ case ID_MC:
+ direct_link_movieclip(fd, (MovieClip *)id);
+ break;
}
/*link direct data of ID properties*/
@@ -7158,6 +7301,22 @@ static void do_versions_nodetree_image_default_alpha_output(bNodeTree *ntree)
}
}
+static void do_version_ntree_tex_mapping_260(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+ bNode *node;
+
+ for(node=ntree->nodes.first; node; node=node->next) {
+ if(node->type == SH_NODE_MAPPING) {
+ TexMapping *tex_mapping;
+
+ tex_mapping= node->storage;
+ tex_mapping->projx= PROJ_X;
+ tex_mapping->projy= PROJ_Y;
+ tex_mapping->projz= PROJ_Z;
+ }
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -12187,7 +12346,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ma= ma->id.next;
}
}
-
}
if (main->versionfile < 260){
@@ -12223,7 +12381,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
-
}
if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 1)){
@@ -12245,9 +12402,74 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 2)) {
+ bNodeTreeType *ntreetype= ntreeGetType(NTREE_SHADER);
+
+ if(ntreetype && ntreetype->foreach_nodetree)
+ ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_mapping_260);
+ }
+
/* put compatibility code here until next subversion bump */
{
-
+ {
+ bScreen *sc;
+ MovieClip *clip;
+
+ for (sc= main->screen.first; sc; sc= sc->id.next) {
+ ScrArea *sa;
+ for (sa= sc->areabase.first; sa; sa= sa->next) {
+ SpaceLink *sl;
+ for (sl= sa->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_VIEW3D) {
+ View3D *v3d= (View3D *)sl;
+ if(v3d->bundle_size==0.0f) {
+ v3d->bundle_size= 0.2f;
+ v3d->flag2 |= V3D_SHOW_RECONSTRUCTION;
+ }
+ else if(sl->spacetype==SPACE_CLIP) {
+ SpaceClip *sc= (SpaceClip *)sl;
+ if(sc->scopes.track_preview_height==0)
+ sc->scopes.track_preview_height= 120;
+ }
+
+ if(v3d->bundle_drawtype==0)
+ v3d->bundle_drawtype= OB_PLAINAXES;
+ }
+ }
+ }
+ }
+
+ for (clip= main->movieclip.first; clip; clip= clip->id.next) {
+ MovieTrackingTrack *track;
+
+ if(clip->aspx<1.0f) {
+ clip->aspx= 1.0f;
+ clip->aspy= 1.0f;
+ }
+
+ /* XXX: a bit hacky, probably include imbuf and use real constants are nicer */
+ clip->proxy.build_tc_flag= 7;
+ if(clip->proxy.build_size_flag==0)
+ clip->proxy.build_size_flag= 1;
+
+ if(clip->proxy.quality==0)
+ clip->proxy.quality= 90;
+
+ if(clip->tracking.camera.pixel_aspect<0.01f)
+ clip->tracking.camera.pixel_aspect= 1.f;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(track->pyramid_levels==0)
+ track->pyramid_levels= 2;
+
+ if(track->minimum_correlation==0.0f)
+ track->minimum_correlation= 0.75f;
+
+ track= track->next;
+ }
+ }
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -12294,6 +12516,7 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */
lib_link_brush(fd, main);
lib_link_particlesettings(fd, main);
+ lib_link_movieclip(fd, main);
lib_link_mesh(fd, main); /* as last: tpage images with users at zero */
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index fdb567a7dce..358a7659d51 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -78,6 +78,7 @@ typedef struct FileData {
struct OldNewMap *globmap;
struct OldNewMap *libmap;
struct OldNewMap *imamap;
+ struct OldNewMap *movieclipmap;
struct bheadsort *bheadmap;
int tot_bheadmap;
@@ -120,6 +121,8 @@ FileData *blo_openblendermemfile(struct MemFile *memfile, struct ReportList *rep
void blo_clear_proxy_pointers_from_lib(Main *oldmain);
void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
+void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
+void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd);
void blo_freefiledata( FileData *fd);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 270885f9df1..c94c9a25516 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -128,6 +128,7 @@ Any case: direct data is ALWAYS after the lib block
#include "DNA_vfont_types.h"
#include "DNA_world_types.h"
#include "DNA_windowmanager_types.h"
+#include "DNA_movieclip_types.h"
#include "MEM_guardedalloc.h" // MEM_freeN
#include "BLI_blenlib.h"
@@ -710,6 +711,8 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
write_curvemapping(wd, node->storage);
else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) )
write_curvemapping(wd, node->storage);
+ else if(ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION)
+ /* pass */ ;
else
writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage);
}
@@ -2261,6 +2264,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
else if(sl->spacetype==SPACE_USERPREF) {
writestruct(wd, DATA, "SpaceUserPref", 1, sl);
}
+ else if(sl->spacetype==SPACE_CLIP) {
+ writestruct(wd, DATA, "SpaceClip", 1, sl);
+ }
sl= sl->next;
}
@@ -2509,6 +2515,38 @@ static void write_scripts(WriteData *wd, ListBase *idbase)
}
}
+static void write_movieclips(WriteData *wd, ListBase *idbase)
+{
+ MovieClip *clip;
+
+ clip= idbase->first;
+ while(clip) {
+ if(clip->id.us>0 || wd->current) {
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+ writestruct(wd, ID_MC, "MovieClip", 1, clip);
+
+ if(tracking->reconstruction.camnr)
+ writestruct(wd, DATA, "MovieReconstructedCamera", tracking->reconstruction.camnr, tracking->reconstruction.cameras);
+
+ track= tracking->tracks.first;
+ while(track) {
+ writestruct(wd, DATA, "MovieTrackingTrack", 1, track);
+
+ if(track->markers)
+ writestruct(wd, DATA, "MovieTrackingMarker", track->markersnr, track->markers);
+
+ track= track->next;
+ }
+ }
+
+ clip= clip->id.next;
+ }
+
+ /* flush helps the compression for undo-save */
+ mywrite(wd, MYWRITE_FLUSH, 0);
+}
+
/* context is usually defined by WM, two cases where no WM is available:
* - for forward compatibility, curscreen has to be saved
* - for undofile, curscene needs to be saved */
@@ -2585,6 +2623,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
write_windowmanagers(wd, &mainvar->wm);
write_screens (wd, &mainvar->screen);
}
+ write_movieclips (wd, &mainvar->movieclip);
write_scenes (wd, &mainvar->scene);
write_curves (wd, &mainvar->curve);
write_mballs (wd, &mainvar->mball);
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt
index 7b7d11bd487..088376b20ef 100644
--- a/source/blender/editors/CMakeLists.txt
+++ b/source/blender/editors/CMakeLists.txt
@@ -35,6 +35,7 @@ if(WITH_BLENDER)
add_subdirectory(space_action)
add_subdirectory(space_api)
add_subdirectory(space_buttons)
+ add_subdirectory(space_clip)
add_subdirectory(space_console)
add_subdirectory(space_file)
add_subdirectory(space_graph)
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript
index a1b766ec2be..ed66a76a324 100644
--- a/source/blender/editors/SConscript
+++ b/source/blender/editors/SConscript
@@ -17,6 +17,7 @@ SConscript(['datafiles/SConscript',
'render/SConscript',
'sound/SConscript',
'space_buttons/SConscript',
+ 'space_clip/SConscript',
'space_file/SConscript',
'space_image/SConscript',
'space_info/SConscript',
diff --git a/source/blender/editors/datafiles/blender_icons.png.c b/source/blender/editors/datafiles/blender_icons.png.c
index a53e2813d2e..93c3b45a3d9 100644
--- a/source/blender/editors/datafiles/blender_icons.png.c
+++ b/source/blender/editors/datafiles/blender_icons.png.c
@@ -1,6723 +1,6760 @@
/* DataToC output of file <blender_icons_png> */
-int datatoc_blender_icons_png_size= 214916;
+int datatoc_blender_icons_png_size= 216116;
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, 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,215, 0, 0, 13,215, 1, 66, 40,155,120, 0,
- 0, 0, 7,116, 73, 77, 69, 7,219, 9, 1, 15, 54, 15, 19,126,136,129, 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, 71, 81,181, 81,252,204,246,190,155,222, 8, 9,161,165,210, 2,132, 94, 2, 33, 8,132,142,
-162, 82, 68, 20,144, 34, 10, 40, 22, 64, 69,154,244, 34, 82,196,130, 8, 8,136,180,208, 4,252, 64, 58, 9, 16, 18, 72, 66, 72,
-175,155, 94, 54,219,119,231,126,127, 36,193, 16, 83,118, 19, 84,208,249, 61,207, 60,155,220,217, 57,123,167,221, 61,251,222,123,
-223,137,191,114,251,198, 37, 35,135,205,130,135,171, 29, 70,135,116,194, 27,227,122,161,179,111, 51,164,230,106,112,225,194,175,
-198,228,228,196,107,150,204, 56,172,210,140,189, 31,117, 53,230,246,101, 19,151, 67,193,215,167, 45, 22,125,244,190,237,242, 79,
- 22,218,180,109,229,129,168,164, 18,252,122,246,148, 49, 43, 35,253,183,127,106,198,225, 69,128, 39, 21, 80, 18, 54,139, 5, 51,
- 75, 80,206,174,156, 72,211,206,223,223,219,217,197, 5,225,225,225, 96, 89, 49, 35,244, 34,192,147, 74, 43,122,193, 85, 42, 21,
-170,244, 90,251,248,248,120,120,122,226,100,120, 56,216, 52,253,160,159,149, 9, 70,227, 42,186,161, 31,235, 82,128,118,102,115,
-200, 90, 55,119,242,177, 85, 72,112, 35, 42, 1, 58, 35,185,249, 99, 17,254,209,124,100,127, 33,211,208,200,174,195, 53,219,183,
-111, 15,218,181,107,215,160,121,243,230, 73, 39, 79,158, 12,161, 80, 8,181, 90, 13,119,119,119,152,205,102,156, 62,125, 26, 17,
- 17, 17, 42,154,166,127,197,159,211, 6,132,160,218, 44,141, 51,137, 16, 85,248, 45,117,208,209, 23, 95,124, 42,154, 0, 32, 77,
-160,229, 5, 45,244,123, 54, 31,188, 60,102,239,153,219,212, 59,175,244, 99,117,246,105, 14, 0,112,118,118,134, 92, 46,183, 90,
-243, 41,240,151,107, 86,239,214,205,201,201,137,203,201,201,201,125,243,205, 55,125,171, 6,190, 11, 4, 2,109,101, 36,171,168,
-182,109, 44,168,167, 1,192,204, 93,187,118, 29, 43, 41, 41, 57,243,222,123,239, 97,249,242,229, 56,126,252,120, 31, 0, 87, 26,
-185,239,230,162,162,162,226,155, 55,111, 58,183,241, 11, 68, 75, 39, 46,250, 46,126, 8, 66, 8,236,197, 4,101,197,133,184,115,
-231, 54,202,202,202,110, 88, 83, 79,131,193, 80,156,155,155,235,224,228,228,132,194,194, 66,228,231,231, 63, 54, 89, 69, 69, 69,
- 40, 44, 44, 36, 20,245,167,156, 45,245,105,150,231,230,230,170, 99, 99, 99,249,206,205,219,160,149, 19, 15,221, 62,138, 3, 8,
-129,135, 29, 11,101,165,197,184,118,237, 26, 74, 74, 74,254, 87,151, 38, 77,211,243, 39, 76,152,192, 6, 48,233,189,247,222,179,
- 3,208,241,253,247,223,255, 21, 53,102, 22,114, 56,156, 13,123,246,236,105, 87,213,197,184,112,225,194,245, 0,118,253, 93,215,
-146,189,189,253,252,240,240,112,153,193, 96,192,230,205,155,177,126,253,250,111,240,231, 68,149,225, 95,126,249,229, 86, 22,139,
- 53,107,246,236,217,152, 62,125,186,184, 75,151, 46,243,178,179,179,127,172, 77, 51, 51, 51,115, 81,231,206,157,151,228,230,230,
-174,176,200, 44, 63,124, 56,173,115,231,206,139,114,115,115, 87,215,119,142, 36, 18,137,196,108, 54, 35, 57, 57,185, 8,168,115,
-124,135, 54, 57, 57, 57,211,108, 54,187,139,197, 98,187,134,174,207,162,162,162, 21, 93,186,116,249, 84,169, 84,158, 5,176,172,
- 22, 67,126, 55, 59, 59, 59, 96,238,220,185,115, 86,173, 90, 53, 38, 39, 39,103,127, 67,154,169,169,169, 43,130,131,131, 23,199,
-199,199,127,143,186,187,128,191,252,236,179,207, 12,123,246,236,121, 43, 57, 57,121,101, 3,154, 39,242,243,243, 79, 88,113,126,
-235,122,255, 99, 77, 54,155,253,254,170, 85,171, 88,219,183,111, 7, 33,100,173,217,108,174,171,158, 81, 71,142, 28,217,221,171,
- 87,175,201, 7, 15, 30, 20, 6, 4, 4, 76,215,233,116,251, 26,186, 62,213,106,245,225,131, 7, 15,142,137,138,138,114,159, 60,
-121,178,208,219,219, 27, 6,131, 1,217,217,217,216,190,125,187, 54, 58, 58, 58,163,184,184,248,176, 53,109,136, 73, 95,250,202,
-213, 11, 71,247,165, 60,140,238,209,255,133,145,182,122,131, 59, 4, 5,108, 20, 23,228,224,244,137,195, 69,201,201,137,215,212,
-234,226, 87,172,209, 52,232, 74, 94,190,246,219,177,253, 25,201,177,221,251, 6, 15,181,213,234, 61, 33,224,177, 80,160,204,196,
-233,240,163,133,201,201, 73,191,107,141,186,215,254,169,118,158,237,133,101,236,156,136, 55,103, 12,239, 4,145,173,251, 29, 46,
-176,185, 23, 32,114,112,118,230, 85,222, 59,144, 86,140,121,180, 72, 83, 9,240,219, 84,246, 82,169,213,106,112, 1,253, 20,128,
-235,232,232, 40, 2,128,248,248,120,136, 43,122, 53,172,170,167, 10,144,136,171,233,178, 0,117, 1, 7,205, 90,203, 37, 20, 0,
-100,228, 20, 64,111,172,247,123,227,121,103,103, 53,195,181,179, 49, 2, 60, 0, 33, 82,169,116,249,146, 37, 75,214,222,184,113,
- 99,109, 88, 88,216, 90,129, 64,176,188,242, 96,243,234, 57, 17,127,155,102, 87, 55,216, 5,183,162, 46,133,182,166,232, 25,125,
-108,205,175,117,147,232, 7, 12, 24,176,181,137,245,108,202,205,242, 87,106, 30, 53, 26,141, 4, 21,221,118, 71, 81,119,151,224,
-135,213,214,231,164,165,165,145,202,191,173,169,167,195,248,241,227,233,178,178, 50,242,210, 75, 47, 17, 52,252, 8,159,122, 53,
- 5, 2, 65,112,223,190,125,141,202,188, 66, 18,151,148, 73,174, 71,222, 39,103, 46, 92, 37,251, 15,135,147, 45, 91,119,144, 14,
- 29, 58,232, 1,120, 90,163,201,225,112, 6, 4, 7, 7, 23, 40,149, 74, 18, 27, 27, 75, 46, 93,186, 68, 14, 29, 58, 68,118,236,
-216, 65,182,109,219, 70,154, 55,111,174, 4,224,108,141,166, 72, 36, 26, 57,100,200, 16, 99,113,169,154, 36,103, 22,144,123,177,
-201,228,202,205,123,228,244,133, 43,228,199,125, 7,137,191,191,191,214, 2, 77, 54,155,205,222,178,127,255,254, 82, 66, 8, 25,
- 57,114,100, 6,158, 76,164,218,114,254,252,249,185,132, 16,178,122,245,234, 2,212, 62, 16,254,175,190,150, 94,104,214,172, 89,
- 28,143,199, 11, 7, 48,169,129,237, 94,230,112, 56,199, 93, 92, 92,110, 1, 24,253, 15,220, 71, 97, 78, 78, 78,215, 1, 52,244,
-132,131,170,247,141,250,151,220,239,127,133,230, 0, 14,135,115, 9,168,255, 33,194,213,218,235,207,217,108,246, 73, 0, 3,173,
-172,103, 91, 7, 7,135,151,108,109,109,223,177,181,181,125,199,201,201,233, 37, 62,159,223,182, 41,251,110,223, 54,100,184, 71,
-224,136, 35,205, 59, 14, 75,245,232, 20,150,234,213,121,228, 17,251,182, 33,195,155,170,233,217,121,228, 81,143, 78, 97,105, 30,
-157,134,167,180,236, 58,242,136,131, 79,200,144,127,242, 28, 77,106, 6,183, 65, 45, 97, 34,151, 22, 19,114,105, 49, 9,105, 9,
-186,135, 13,252,131, 0,217,224,144,144,117,196,108, 94, 55,102,212,168,117,109, 0,123, 2,176,107, 46,181,105, 6, 2,242,199,
-219,142, 28,185,174, 21,224, 48, 8, 16,247,235,211,103, 45, 49,155,215, 77,120,249,229,117, 30,128, 75,109,122,117,105, 18,128,
-221, 12,112,171,174,235, 0,180, 30,231,133,128, 15,135,123, 17,114,105, 49,249,236, 69,111,210,217, 25,147, 26,208,172, 43, 82,
-244, 92, 71,180,172, 69, 82,217,184,174,172,124,149, 60,133,139,240,169,107,118,119,133,119, 72,107, 42,118,168, 15,167, 16, 21,
- 83,146, 37,255,194, 70,242,123,189, 94, 79,180, 90, 45, 81,171,213, 68,165, 82,213, 52, 80,143, 13, 89, 86, 86, 22,201,200,200,
- 32,105,105,105, 36, 37, 37,133,224,143,177, 55, 22,215, 83, 46,151,239,122,241,197, 23,205, 92, 46,119,203,211,216,119, 59, 59,
-187,149,221,186,117, 51,108,218,180,137, 28, 57,114,132,124,253,245,215,100,246,236,217,164, 93,187,118, 58, 27, 27,155, 87, 26,
-163,233,226,226,178,200,199,199,167,224,155,111,190, 33, 63,254,248, 35,217,184,113, 35,249,248,227,143,205,238,238,238, 57, 50,
-153,108,112, 99, 52,157,156,156,118,246,238,221,219,176,115,231, 78,242,235,175,191,146,189,123,247,146,249,243,231, 19, 95, 95,
- 95,157, 68, 34, 25,107,161, 38,155,195,225,172,155, 49, 99, 70,142,155,155, 91,120,141,117, 98,127,127,255, 91, 19, 38, 76,200,
- 2,176,240, 95,116,125, 50,154,140, 38,163,249, 23, 24,173, 87,221,208,140, 0,108, 49,143,247,114,191, 62,125,214,242,128,151,
-173, 53, 69, 66, 54,123, 92,175,110,221,214,242,128, 87,170,222, 43,100,179,199,245,235,211,103, 45,151,205,158, 88,151, 94,125,
-154, 4, 96,243, 56,156,133,189,122,244, 88,199, 1, 62,170, 42, 27,208,146,122, 48,255,133,230,164,143, 39,149, 48,209, 9,226,
-127,177,209,122,234,112,254,130,139,240,121,209,124, 86,110,234, 54,149,134,233,168, 21, 17,173,163,168,120,138,122,155, 70,214,
- 83,244,148,247,189,189,131,131,195,169, 54,109,218,228,181,104,209, 34,203,214,214,118, 31, 0,247, 38,106, 6,184,184,184,252,
-224,236,236,252,208,213,213, 53,202,193,193, 97, 3, 42,178,206, 55, 90,147,203,229,118,115,118,118,254,159,151,151, 87,177,167,
-167,167,210,193,193, 97,127, 45,145, 44, 75, 52, 93, 81,123,163,194,171, 92,199,124,233, 48,154,140, 38,163,249,132,129, 9,109,
-133, 85,131, 90,194, 52,168, 37,204,161, 94,216, 80,221,160,132, 1,162,198,154,162,215, 0, 65,205,247, 55,164,215,144, 38, 1,
-216, 61, 1,105,205,109,134,186,195,223, 66,205,231, 61,162, 85,213,206, 91,151,222,161, 14, 76,127, 65, 37,159, 23,205,103,133,
- 4,212, 51, 24,185, 26, 43,159,226,103,106,158,242, 62,220,203,207,207, 31,146,159,255, 84,231, 38,196,228,228,228, 76,122,154,
-130, 70,163,241,134, 82,169,236,255, 20,164,234,154,122,109,128,133,211,178, 25, 24, 24,254, 59, 80,128, 25,137,248, 32,164, 45,
- 54,115,204, 96,157, 78, 66,102,141, 41,121, 26,170, 49,154, 21,152,191,175,165,141,167, 26, 91,207, 63, 80,253, 73, 35, 3,247,
-169,255,206,105,203, 70,197, 24,173, 38, 27, 45, 6, 6, 6, 6, 6, 6,134,191,129,115, 15,153, 31, 98,207, 1,225,120, 50,250,
- 22, 94,205,136,214, 25,250,180,102, 38, 69, 99,194,167,231, 24, 77, 70,147,209,100, 52, 25, 77, 70,147,209,252,207,105, 86, 81,
-215,179, 83,227,106,252,223,168, 89,124,255, 21,152,126,118, 70,147,209,100, 52, 25, 77, 70,147,209,100, 52,255,237, 52, 58,143,
- 22, 3, 3, 3, 3, 3, 3, 3, 3, 67,253,212, 25,117, 99,140, 22, 3, 3, 3, 3, 3, 3, 3, 67,211,112, 69,197, 35,170,194,
-241,199,163,170,118, 2, 13, 63,130,231, 9, 86,173, 90,197,106,211,166,141,148,207,231,183, 75, 76, 76,100,205,156, 57,179,201,
- 19, 9,214,110,216,194,242,244,244,148, 2,104, 87, 80, 84,198,122,253,141,247, 40,230,124, 49, 48, 48, 48, 48, 48, 48, 60, 71,
- 12,171, 52, 86, 85,175,143, 35, 92, 86, 69,180,150, 45, 91, 6,163,209, 40, 1, 48, 62, 32, 32,224,115,173, 86,171, 61,112,224,
- 0, 85,153, 45,188, 81,124,180,112, 62, 12, 6,131, 4,192,120, 39, 7,155,207,205,102,179,246,224,241,203,212,139,195,123, 19,
-230,188, 49, 48, 48, 48, 48, 48, 48, 60, 39, 76,171,241,186,211,106,163,197,225,112,216, 44, 22,171,149,209,104, 28, 34, 20, 10,
-207,106,181,218, 75, 77, 49, 89, 85,154, 20,139,213,202,100, 52, 14, 17, 8,132,103,213,234,242, 75,140,201, 98, 96, 96, 96, 96,
- 96, 96,120,142,176,108,102,228,137, 19, 39,234, 52, 56,124, 62,159, 21, 16, 16,208,219,211,211,243,138,159,159,159,222,221,221,
-253,144, 88, 44,150, 52,177, 98,172, 54,222,190,189,221, 92,157,175,116,106,229,170,119,114,114, 58,196,229,114, 37,204,249, 98,
- 96, 96, 96, 96, 96,248,111, 82,159, 23,121,134,169,154,105,248,167,167,124, 88, 51, 70,171,163, 82,169,220, 58,106,212,168,238,
-115,231,206,229,177,217,236,230, 18,137,164,157,131,131,195, 19, 81,177, 41, 83,166, 80, 86,105,230,100,111, 93, 62,174, 99,247,
- 43, 31,117,229,113,217,104, 46,145, 72,218,201,229,242, 39, 52, 39,188, 62,157, 25,183,197,192,192,192,192,192,192,240,172, 82,
- 53, 46,107, 24,172, 73,239,208,181,107, 87, 65,122,122,122, 39,141, 70,227,196,227,241, 22,142, 24, 49, 34, 96,204,152, 49,184,
-115,231,142, 57, 32, 32,192,173,160,160, 96, 78, 81, 81,209,185,242,242,242, 59, 52, 77, 7, 8, 4,130, 11,251,246,237,147, 2,
-120, 88,151,102,251,142, 93, 4,233,169, 73,143, 53,103,140, 27, 16, 48,105,222, 16,208,167, 54,155, 7,116,240,112, 75,205, 87,
-207,201, 5,209,176,198, 0, 0, 32, 0, 73, 68, 65, 84, 45, 40, 57,167, 46, 87,221, 49,211, 36, 64, 32, 16, 92,248,241,219, 29,
-245,106, 50, 48, 48, 48, 48, 48, 48, 48,252,131, 84, 25,171,112,212,120,164, 26, 7,168, 8,211,133,133,133, 61, 17, 53,226,243,
-249, 95,197,199,199,247,178,179,179,107,197,229,114,205, 47,191,252,178, 96,194,132, 9,200,203,203,163, 85, 42, 21, 59, 48, 48,
-208,249,214,173, 91, 67, 76, 38, 83, 31, 27, 27, 27,117,113,113,177,131, 78,167, 75, 0, 48,167,158,138,124,245, 48, 46,186,151,
-189,173, 93, 43, 62,151,109,158, 61,117,130,224,163,133, 47,128,210, 69,210,230,220, 2,246,231,157,109,156, 55, 92, 45, 31, 18,
-111, 48,247, 41, 87, 8,213, 57, 37, 58, 75, 52, 25, 24, 24, 24, 24, 24, 24,158,115,106,243, 34,207, 17, 13,230,209,234, 95,217,
- 39, 90,253,193,185,187, 29, 29, 29, 93,164, 82,169,223,180,105,211, 88, 14, 14, 14,136,136,136,160,203,203,203, 89, 92, 46, 23,
- 92, 46,151, 61, 96,192, 0,169,201,100, 18,159, 60,121,146,122,244,232, 81,158,209,104,252,188,160,160,224, 86, 61, 21,217,221,
-218, 70,224, 34,178,225,251, 29,127,175, 47,203,177, 77, 1,112,230, 51,154,168,114, 89, 28,154,192, 65, 66,179,215,245,161,164,
- 57, 10, 47,241,236,253,121,212,239,143,138,243,140, 70,227,231,101,101,101,183,152, 75,144,129,129,129,129,129,225, 95, 77,109,
- 94,228,121,161,122, 30,173, 39, 34, 90,117, 58, 71,103,103,103, 74,171,213,186,120,121,121, 77,115,116,116,156, 40, 22,139,157,
-251,246,237, 43, 50,155,205, 32,132, 64,161, 80,208, 45, 90,180,160,247,237,219,103,186,124,249,114,198,219,111,191, 61,106,214,
-172, 89, 15,134, 14, 29,202, 58,121,242, 36, 93,155,166,141,173, 29,101, 82,151,186,120,180,242,155,214,222,145, 76,244, 82, 24,
-156, 23,143, 16,139, 56,201,249, 32, 14, 28,192,201,139,102,181, 11,165, 87,174, 59,107,250,250, 92, 82,198,251,139, 87,142,122,
-107,234,248, 7, 33,161, 67, 89,231,206,214,174,201,192,192,192,192,192,192,192,240, 15, 51, 13, 21, 81,173,170,215,134,141, 86,
-175, 94,189,168,152,152, 24,202,211,211, 83, 92, 80, 80,224, 15, 96,195,130, 5, 11,130, 8, 33,102,145, 72,196, 22,137, 68,230,
-223,126,251, 77,253,243,207, 63, 95, 54, 26,141,147,244,122,125,145,151,151, 23,149,156,156, 92,231,108,129,174,221,123, 80,247,
-163,238, 80, 30,158,173,196, 5,249, 74,127, 10,100, 67,230, 71,110, 65, 92, 85,145, 25,110,142,108,200,156,204,107, 15, 23,169,
- 63,250,229,238,101,163,209, 48, 9, 64,145,187,155, 43,149,145,149,205,164,123, 96, 96, 96, 96, 96, 96, 96,120,150,141, 86, 77,
-234,207,163,117,229,202, 21, 2,128,100,102,102,154,141, 70,163,188, 95,191,126,182,108, 54, 27,246,246,246,108,181, 90, 77,151,
-151,151,179, 29, 28, 28,178,184, 92,238,143,229,229,229, 69,163, 70,141,162,142, 28, 57, 82,175, 33,186,117,253, 26, 1, 64, 50,
- 50,210,205,180, 81, 43,159,217,187,133, 45,199,100, 0, 29,216,139,173, 42,163,104,169, 38,153,237,235, 42,200,226,241,184, 63,
- 26,141,134,162,209, 97,195,168, 95, 78,132, 51, 38,139,129,129,129,129,129,129,225, 89,166,206, 49, 90, 13,166,119, 80,171,213,
-182, 60, 30, 47, 36, 40, 40,168, 69,121,121, 57,189,108,217,178,244, 77,155, 54,237, 73, 72, 72, 48,218,216,216,180, 18,137, 68,
-239,140, 31, 63,222,225,200,145, 35,164, 79,159, 62, 53, 35,100,181, 62,221, 91,163, 81,217, 10,120,220,144,119,186,201, 90,164,
- 27,108,105,191,119,110,166,247, 91,114,117,207, 47, 49, 28, 99,123, 59, 77, 43, 59, 62,245,206,248,241, 47, 57,252,114, 34,156,
-244,232,209,221, 34,205, 38,194,104, 50,154,140, 38,163,201,104, 50,154,140,230, 63,171,249,188, 51, 13, 53, 82, 59, 0, 22,100,
-134, 23, 8, 4,125, 61, 60, 60,122,199,196,196,152,175, 93,187, 86,194, 98,177,182, 13, 29, 58,244,208,225,195,135,187,217,217,
-217, 57, 53,111,222,220,249,252,249,243,193, 0, 14,252,254,251,239, 22, 69,159, 68, 2, 94,223, 78,238,138,222, 59,239, 18,243,
-183, 17, 15, 75,204,108,193,182, 1, 99,199, 30,122,123,207,222,110,110, 14, 50,167, 78,174,114,231,147, 39, 79, 7, 3, 56,112,
-237,218,117, 38,162,197,192,192,192,192,192,192,240,172,155,172,157,181,253, 95,111, 68,139,207,231, 55, 99,179,217,254, 25, 25,
- 25,169, 39, 79,158,140,233,218,181,235,144,212,212,212, 85,132,144, 20,177, 88, 60, 45, 61, 61,253, 97,122,122,186, 94,163,209,
-204,176,162, 50,205,192,226,249, 71,100,105, 82,191, 56,127, 63,166,125,143,193, 67,114,114,178, 86,153, 9, 73,225,139,229,211,
-226,211,242, 30, 94,207,213,233,181, 90,171, 52, 25, 24, 24, 24, 24, 24, 24, 24,158, 57, 26,138,104, 25,204,102,243, 26,157, 78,
-103,251,203, 47,191,100,134,134,134,234, 0,224,171,175,190,162,167, 78,157,122, 57, 49, 49,113,224,131, 7, 15,134,184,184,184,
- 92, 0, 64, 37, 37, 37, 89, 18,125, 50,208,180,121,141, 94,175,179, 61,255, 91,100,102,223,222,237,117, 0,176,253,203,205,244,
-203,211,230, 94, 78,140,141, 25, 24, 31,125,123,136,139,139,203, 5,179,137, 67,101,231,164, 48, 17, 45, 6, 6, 6, 6, 6, 6,
-134,103,153,170, 25,135,213,255,111,216,104,233,245,250, 60,189, 94, 15, 0, 69,161,161,161, 79,172,251,230,155,111, 8,128,114,
- 0, 7, 11, 10, 10,172,169, 76,158, 70,163, 1,128,162,190,189,219, 63,177, 98,255,206, 77,143, 53, 85,101,165,204,105, 99, 96,
- 96, 96, 96, 96, 96,120,158,204,214,159, 96, 49,199,133,129,129,129,129,129,129,129,161, 73, 76,171,235,127, 10,117,207, 28, 56,
-103,197, 7, 52,102,246,193, 57, 70,147,209,100, 52, 25, 77, 70,147,209,100, 52,255,115,154, 13,105,159,195,243, 71,157,131,225,
-255,106,152,169,175,140, 38,163,201,104, 50,154,140, 38,163,201,104,254,219,113,197,147,233, 29, 92,171, 86,112,152, 99,195,192,
-240,124, 67, 14,130,141, 34, 31, 47, 16,226, 6, 54, 63, 27,217,247, 18,169, 79, 65, 55, 89, 83,233,239, 9,145,209, 25, 38, 97,
- 30,148, 81, 73, 77,213,100, 96, 96,248,247,225,210,115,230,104,138,197,222, 70, 17, 26, 26,101,172,128,167, 73, 17,231,102,167,
-254, 23,189, 69, 54,234,136, 96, 49, 70,139,129,225,121, 39,207,215, 27, 28,172, 4, 11,174, 32,134, 71,112,244, 95, 9,220,143,
-110,178, 38,143, 94, 6, 51,203, 29,196, 16, 15, 39,159, 85, 64,220,125,230, 96,255,251,152, 51,251, 45,242, 32,250, 6,210,210,
-178,208,170,181, 43,188,125,123, 98,211,230,173, 20,115,100, 24, 44,251, 85, 70,237, 12, 25, 62,193, 78, 36,150, 1, 0,104,147,
- 17,223,204,235,244,171,201,100,218, 13,224, 8, 0,205,127,253, 16,253,237,131,225,185, 92,174, 18, 0, 45, 20, 10, 15,163, 90,
-104,141,129,225, 47,192,181,242, 58,163, 43,175, 59,107,144,114, 56,156, 37, 98,177,248, 55,129, 64,144, 43, 16, 8,114, 37, 18,
-201,111, 28, 14,103, 9, 0,233, 51,211,198,253,208, 78, 12,150,121,136,222, 72, 55, 59,125,175,216, 73,173, 51,123,131,101, 26,
- 74,190,105, 43,109,146, 38,135, 10,213, 26,104,143, 31,111,170,157,203,245, 38, 63, 16, 52, 73,179, 26, 54, 60, 30,239, 52, 0,
- 7,230,242,124, 54, 72, 77,138,198,201, 19,235,176,108,233,100,124,183,115, 6,226, 30, 92,111,146,158, 31,208,165, 11,135,179,
-192, 23, 24,128,122,158,167,203,240, 47,129, 34,211,206, 29,255, 49,239,248,190, 47,243,126, 90, 55,131, 28, 93, 25,134,205,155,
- 55,135, 76,158, 60,249, 71, 15, 15,143, 60, 0, 47, 50, 70,235,111,198,104, 52, 58,229,231,231, 83,187,119,239, 30,161, 80, 40,
- 30,113, 56,156, 15, 1,240,254, 43, 7, 92, 42,149, 94,149,203,229, 74,133, 66,161,148,203,229,183, 27, 42,255,151,226,237,232,
-232,152,106,103,103, 23, 95,189,208,177,195,232,158,109,122, 77,250,196,222,127,100,191, 38,234,243, 56, 28,206,135, 10,133,226,
-209,238,221,187, 71,100,102,102, 82, 70,163,209,201,138,237,251,218,218,218, 62,184,113,227,198,226,252,252,252,126,233,215,191,
-113,204,185,177,195, 49,245,127,235,250, 71,156,220,178,216,198, 70,113, 31, 64,223,103,226, 72,106,105,103,176,216,193, 49,217,
-106,113,118,169,209, 57, 50, 69, 45, 3,216,253,161,111,194,143,152, 18,218, 25, 32, 3,238,102,104, 36, 87, 11, 29,157,127, 79,
-212,201,193, 98, 5, 67, 75,185, 52,185,193, 97,177,222,162,105,122, 16,143,199,123,135,249,134,122, 54, 16, 8,120, 0, 33,144,
- 74,132, 0, 8, 88, 77,180, 70,124, 22,171,215,213, 17, 35,150, 45,236,208, 97,142, 47, 48,188, 14,179, 69, 1,120,219,215,215,
-247, 20,128,151,159,226,238,124,225,227,227,147, 9, 96,238,211,106,151, 58,119,238,220, 51, 56, 56,248,147, 78,157, 58,245,123,
- 90,154,255, 38,114,174,126,245, 75,246,229, 45, 78, 89, 87,182, 58, 21, 39, 93,122,219,213,217,150, 78, 74, 74,194,176, 97,195,
-240,229,151, 95,138, 3, 2, 2,246, 0,112,251, 15,220, 74,129, 85, 63,240, 81, 99,140,150,197, 70,107,156, 23,122,189,210, 18,
- 23, 95,242, 66,217,248,150, 80, 77,108,137,203, 99,189, 48,160, 49,181,177,183,183, 71,223,190,125,217,153,153,153,162,249,243,
-231,127, 34, 20, 10,147, 1, 12,110,140,150, 72, 36,138, 16,139,197,233, 28, 14,231,137,186,136,197,226, 8,137, 68,146,206,225,
-112, 6, 86, 47,151,201,100, 87,229,114,185, 82, 38,147,221,174,195, 8, 69,200,229,114,165, 84, 42,141,168, 94,206,225,112, 6,
- 74,165,210, 12,153, 76, 86,179,124,128, 76, 38, 75,175, 89, 94, 23, 92, 46,215, 61, 61, 61,221, 41, 35, 35,195,137,207,231, 59,
- 87, 47, 79, 75, 75,115, 74, 79, 79,127,162,220, 26, 56, 28,206, 0,137, 68,146, 46, 22,139, 35,106, 43,175,185, 79,117, 81,237,
-216, 13,176,164,220,218,134, 39, 52, 52,244,114,118,118,182,135,141,141,141, 77,245, 21,118, 10,155,193, 63,124,179,117,222,200,
-161,161,111, 57,250,141,106,223, 72,253,193, 66,161, 48,121,254,252,249,159,100,102,102,138,122,244,232,193,102,177,172,250, 61,
- 17, 50,114,228,200,163, 74,165,178, 89,199,142, 29,217, 38,147, 9, 49,199,150, 64, 28,245, 14,132,201,219,209, 92,148,199,121,
-244,235, 42,247,208,254, 93,142,226, 31, 30, 12, 74, 14,250,241, 64,209,125,105, 66, 28, 31,100,106, 29,135,141,120,145,115, 39,
- 93,227,104, 52,155,237, 0,118,127,242,157,167,160, 81,154, 28, 99, 31,154, 16,231,243, 41, 92,199,224,151,230,176, 47,164,112,
- 28,141,102,179, 61, 88,232,215, 24,205,234,151, 63,155,205,158,183,110,221, 58, 22,128,217, 0,248,255, 37, 67, 19,228,134,102,
- 3, 90,179,111, 6,186,162,215, 83,148, 13,168,188,223,189,155, 42,180,235,187, 83,152, 58,125, 39,218,250,118,111,146,142,158,
-166,227,246, 39, 37,157,153,216,186,117,216,194, 14, 29,166,212, 98,182, 40, 0, 11, 87,173, 90, 53, 41, 38, 38,198,177,101,203,
-150,211,159,210,143,254,141,171, 86,173,122, 63, 38, 38,198,205,203,203,235, 51, 43, 53,235,108,151,108,109,109, 7,239,218,181,
-107,222,176, 97,195,222,234,220,185,115,251,167,161,249, 47,230,203,187,119,239,122,172, 91,183,238,131,169, 83,167,150, 2,192,
-192,129, 3,121, 0,122, 52,185,189, 35,132, 79, 8, 9, 38,132, 12, 35,132, 12, 36,132, 4, 85,254,221,181,114, 25, 70, 8, 9,
-169,241,218,181,114,219,170,245,221,234,208, 24, 86,115,187,106,219,212,252,255,137,191,107, 49, 90,195, 80, 49, 86,107,216, 19,
- 59,112,226,196, 9, 82,253,181, 38,227,189,240,233,156,158,205,212, 15,142,239, 37,170,244, 36, 82, 20,123,135,220,217,185,130,
-204,233,234,168,126,181, 37,190,176,254,120, 17,114,229,202, 21, 18, 19, 19, 67, 84, 42, 21,121,248,240, 33,233,214,173,155, 70,
- 44, 22,159, 7,224,101,141,152, 76, 38, 83,158, 63,127,158,132,134,134,150, 72,165,210,181, 85, 55,151, 92, 46, 87, 94,185,114,
-133,132,134,134,150,200,100,178,141, 0,216, 0, 48,118,236,216, 92, 66, 8,113,116,116,204,170, 77,111,228,200,145, 69,132, 16,
-162, 80, 40,170,186,154,216, 50,153,108,227,172, 89,179, 84,183,110,221, 34,182,182,182, 85,229, 44,185, 92,190,118,246,236,217,
-170,200,200,200,234,229,245, 98,103,103,151,110, 54,155,201,241,227,199,137,147,147, 83, 86,181,155, 57,221,108, 54,147,163, 71,
-143,214, 89,183,250, 2, 5, 82,169,116,205,196,137, 19,203, 82, 82, 82,136,189,189,189,178, 90,249,218,201,147, 39,151,165,165,
-165, 17, 7, 7, 7,139,234,104,111,111,175,188,122,245, 42, 25, 51,102, 76,105,245, 99,106,111,111,175,188,118,237, 90, 85,249,
- 26, 75, 26, 50, 55, 55,183,233, 78, 78, 78, 89, 78, 78, 78, 89, 54, 54, 54,203, 93, 93, 93,115,242,242,242, 8, 33,132,180,106,
-213, 42,183,122, 36,203, 41, 96,196,187,219, 15, 94,187,113, 41,186, 32,175,195,160,183,214, 40, 58,140, 84, 88,113, 12,188,196,
- 98,241,249,126,253,250,105,210,211,211, 73,121,121, 57,137,138,138, 34, 87,174, 92, 33, 9, 9, 9, 4,128, 37, 79, 24,144, 73,
-165,210, 76,157, 78, 71,235,116, 58, 58, 47, 47,207,156,155,155,107,142, 93,235, 74,200,183,220,199, 75,241,209,225, 36,231,210,
- 74, 90, 46, 21,103, 0,144,253, 99, 70,107,171,191, 59,217,225,179,255,254, 18,143,216, 75,171, 94, 48,146,148, 11,100,239, 20,
- 71,227,197,119,155, 61, 34,219,124,127, 38, 59,252,154, 55, 74,115,155,223,222,168,143, 61,226,182,124,246,182, 49, 53, 53,149,
- 44,152,252,130,233,236,156,102,137,100,187,239,193,198,104, 86,227,149,209,163, 71,171,210,210,210,136,191,191,127, 57,155,205,
-158,250, 95, 50, 89, 33,222,252,204,168, 31, 23,208,195, 3,196, 5, 79,201,108, 5, 56, 57, 57,229,127,255,253,247, 68, 38,147,
-229, 54,214,108,141, 27,213,159,104, 74,206,147, 81, 97, 65,245,222, 35, 47,189,244, 18, 9, 14, 14, 38,115,230,204,105,232, 94,
-162,124,129, 17,187, 59,116, 56, 74,143, 27,103,222,221,161,195, 81, 95, 96, 68,165,193,162, 0,124,176,122,245,234, 72,163,209,
- 24,249,221,119,223, 69,142, 24, 49, 34, 18,192,130, 38, 30,139, 77, 95,124,241, 5, 49, 26,141,228,187,239,190, 35, 35, 70,140,
- 32, 0, 54, 55,165, 93,170,138,100, 5, 6, 6,190,123,228,200,145, 27,113,113,113,121, 97, 97, 97,107, 58,116,232,160,104,172,
-230,179,136, 84, 42,109,211,190,125,251, 61,254,254,254,105, 29, 59,118,212,251,249,249,105,189,189,189, 83, 2, 2, 2,190, 23,
- 8, 4, 94,141,148,237,222,171, 87, 47,243,197,139, 23,201,232,209,163, 73, 53, 19, 82, 47,245,121, 17, 66, 72,208, 7, 31,124,
-240, 33, 0,242,193, 7, 31,124, 72, 8, 25, 86,233, 39,134, 85,255,187,230,107,149,121,170,250,191, 54,141,170,165, 54,205,218,
- 62,163,198,231,160,142, 72,214,180, 63,237,220,137, 19, 39,250,157, 56,113,226, 98,205,157,123,177, 37,122,206,233,217, 76,163,
-201,203, 38,209, 43,222, 33,191, 5,187,147, 43,253, 93, 72,252,188,209, 36,251,199,141,100,102, 39, 91,245,184,150, 8,182,214,
-104, 69, 70, 70,146,200,200, 72,114,251,246,109,146,156,156, 76, 74, 74, 74,200, 79, 63,253,100,182,183,183,215, 8, 4,130, 85,
- 0, 68,150,136,201,229,114, 37, 33,132,232,116, 58,178,124,249,114,109,101,164,202, 89,161, 80, 40, 9, 33,164,184,184,152,172,
- 90,181, 74,171, 80, 40,162, 0,184, 57, 56, 56,164, 39, 37, 37, 17,103,103,231, 90,205,140,173,173,173, 50, 46, 46,174,202, 56,
- 53,179,181,181,141, 62,118,236,152,129, 16, 66, 50, 50, 50,136,157,157,157, 18,128,179,189,189,253,157, 19, 39, 78, 24, 8, 33,
- 36, 43, 43,171,170,220, 34,163,165,209,104,200,217,179,103,159,168, 67, 85,249,169, 83,167,158, 48, 96, 22,224,172, 80, 40, 34,
-127,250,233, 39,189,217,108, 38,209,209,209, 85, 38,209,217,198,198,230,246,193,131, 7,245,102,179,153,196,198,198, 90,108, 6,
- 91,180,104,145, 75, 8, 33, 38,147,137,108,223,190, 93, 87,117, 76,171,202,245,122, 61,249,234,171,175,116,114,185, 60, 18, 64,
-189,209, 55, 7, 7,135, 44,189, 94, 79,138,139,139, 73,183,110,221, 84, 87,174, 92, 33,165,165,165,132, 16, 66, 90,180,104,145,
- 11, 0, 62,253,166,126,126,227,161,170,244,245,247,183, 30,240, 10,122,117,197,153,155,153, 25,187,142, 68, 68, 58, 4,140,124,
-193,146,160,166, 64, 32, 88,229,234,234,170,253,253,247,223,205, 6,131,129,164,165,165,145,219,183,111, 63,190,198,238,221,187,
-103,145,209,226,112, 56, 75,110,220,184, 97, 48,155,205,116,126,126,190, 57, 55, 55,215,156,155,155,107,170,105,180,200,183, 92,
-146,127,234, 77, 18,190,115,174,158,199,227, 45,249,103,162, 89, 96,147, 29, 62, 35,201, 14,159,200,239, 39, 58,228,151,221,222,
- 71,200,175,115, 73,226,231, 45,201,146, 23,100,101,244, 14,159, 72,178,195,119, 28,249,180, 31,199, 42,205,157,126,195,201, 14,
-159,200, 47, 94,244, 44,184, 19,121,139, 92,188,120,145,124,181,113, 53,153, 19,210,172,156,222,225, 19, 73,182,249,141,177, 70,
-179, 58, 2,129,224,225,229,203,151,201,165, 75,151,200,103,159,125, 70,196, 98,113,218,211,136,234,145,109,222,158,228,107,239,
-126,228,155,182,174,228,127,253,158,185, 9, 62, 65,110,104, 54,200,155,159,145,127,231, 8, 33,133, 9, 36,103,173, 63,121,193,
-135,219, 84,179, 21,224,228,228,148,151,146,146, 66,114,114,114,200,250,245,235,137, 92, 46,111,148,217, 26, 55,170, 63,209, 20,
-159,171,215,104,141, 28, 57,146,108,216,176,129, 24,141, 70,210,189,123,119, 75,126,180,252,201,108,249, 0, 35, 1,124,184,102,
-205,154,199, 38,107,235,214,173,145,247,238,221,139,244,240,240, 56,217,132, 99,177,121,205,154, 53,143, 77,214,214,173, 91,201,
-189,123,247,136,167,167,103,122, 83,218,165, 65,131, 6,125,158,156,156, 92,186,104,209,162, 3,125,251,246, 93,113,231,206,157,
-140,240,240,240,200,192,192,192, 23, 26,171,249, 20,162, 58,156,202,200, 14,159, 16,194, 37,132, 84,153, 87, 14, 0,110, 85, 64,
-193, 18, 38, 78,156, 40,238,217,179,103,228,132, 9, 19,212,223,127,255, 61, 73, 73, 73, 33, 81, 81, 81,100,205,154, 53,228,147,
- 79, 62, 33,223,126,251, 45, 25, 51,102, 76,121,183,110,221,110,140, 27, 55, 78,104, 69, 53,253,189,188,188, 74,142, 30, 61, 74,
-246,238,221, 75,120, 60, 94,184,165, 27,214,231, 69,234, 50, 83,117, 25,172,154,235,234, 49, 98,245, 26, 54, 11, 62,239,207,166,
-170,102, 36,164,218,223,255, 11, 11, 11,235,247,167, 47, 31,130,165,211,230,127, 46, 76,254,126, 61,148, 63,125, 9,118,177, 18,
-220,178, 2,232, 46,135,195,120,249, 24, 38,245,232, 33, 18, 81,212, 50,107, 47, 24, 62,159, 15, 62,159, 15, 30,143, 7,181, 90,
-141,172,172, 44,244,238,221,155,117,251,246,109,225,244,233,211,231,138, 68,162, 52, 0,163, 26,188,155,169,138,136,244,213,171,
- 87,241,230,155,111, 10,246,236,217,211,209,209,209,241,174,217,108,230, 3, 64,108,108, 44,198,143, 31, 47,216,183,111, 95, 59,
- 55, 55,183,219, 6,131, 65, 44, 16, 8,192,102,179,235,212,227,243,249, 48, 26,141,130,182,109,219, 70,221,189,123, 55, 32, 44,
- 44,140,155,154,154,138,164,164, 36, 24,141, 70,190,183,183,247,189,219,183,111,119, 28, 54,108, 24, 55, 61, 61, 29,169,169,169,
-143,235, 97, 73,125,245,122, 61, 4, 2, 1,170,119,105, 81, 20, 5,157, 78, 7, 62,159,111,177, 22,135,195, 25,224,235,235,123,
-239,238,221,187,129, 35, 71,142,228,221,186,117, 11, 25, 25, 25, 48,155,205,124, 63, 63,191,123,119,239,222,237, 52, 98,196, 8,
- 94, 84, 84, 20,148, 74, 37, 44,237, 66,171,122,223,221,187,119, 49, 97,194, 4,254,233,211,167, 59,185,186,186, 70,153, 76, 38,
- 62, 0,220,187,119, 15,227,199,143,231,159, 57,115, 38,176,121,243,230, 81, 13,116, 37,178, 1,192,104, 52, 98,250,244,233, 18,
-185, 92,142,244,244,116,208, 52, 13,179,217, 12, 0, 40, 40, 42,184,119,247, 94,116,236,164, 87, 94,236,167, 49,232,116,215,110,
- 70, 60,104,213,194,211,157,162, 72,139, 6,170, 58, 74, 34,145,164,173, 93,187,246,221,148,148, 20,129,175,175, 47, 43, 49, 49,
- 17,101,101,101,224,241,120,143,175, 49, 75,247,155,207,231,247,247,247,247,231,104,181, 90,208, 52, 13, 0,132,197,170,125,196,
-138,176,248, 50,252,156, 77, 92,145, 72,212,255, 31,249,246, 46,245,183, 7,141, 65,169,121,122,129,192,198, 93, 38,117,245, 6,
-210, 46,161,165,163, 0,108, 22, 91,120, 43, 73, 45, 1,200, 32,120,228,219, 91,167, 73, 15, 74,202,213, 11,140,118,237,164,110,
-238, 30, 40, 40, 40, 64,243, 86,190,208,242, 29,249, 87, 19,202,165,160,172,212,252,131, 62,109,219,182,117,105,211,166, 13,242,
-243,243, 17, 24, 24, 8, 91, 91, 91, 91, 0,131, 26,253,165,243,157,167, 0,165,232, 5,176,214,194, 76,125, 6, 35,103, 37, 18,
-242, 2,201,142, 64,238,179,100,178,228, 82,254,245,125,251,127,106,102,239,225, 7,132,191, 14,103, 27, 1,190,121, 43,208,206,
- 81, 33, 56,218, 72,179, 21,224,236,236,124,225,198,141, 27, 14, 66,161, 16,183,111,223,134,191,191, 63,214,175, 95,239,104,107,
-107,123,169,113,145, 45, 2, 66,213,109,178,250,246,237,139,217,179,103, 99,207,158, 61,176,179,179,195,132, 9, 19, 26, 50, 91,
- 36, 22, 56,254, 69, 84,212,119,123, 30, 61, 58, 49,177,117,235,176, 9,222,222,203,103,188,252,242,212,183,223,126, 27,171, 87,
-175,198,209,163, 71,209,171, 87, 47, 76,155, 54,205,152,150,150,182,187,177, 93, 85,107,215,174,157, 51,119,238,220,154,154,134,
-212,212,212, 47,154,212, 46, 21, 20,220,139,138,138,138,125,229,149, 87,250,105,181, 90,221,205,155, 55, 31,120,121,121,185, 3,
-104,209, 88,205, 38, 24, 44,138, 16, 34, 4, 32,174, 92, 36, 0,196,251,246,237, 83,140, 28, 57, 82, 94, 89, 38,170, 92, 26,236,
-222,247,247,247,119,127,248,240, 97,230,188,121,243, 2,247,236,217, 35, 18,139,197, 40, 46, 46,198,215, 95,127,141, 15, 63,252,
- 16, 20, 69,129, 16,130,111,191,253, 86, 60,101,202,148,160, 71,143, 30,101,122,122,122, 90, 50,164, 69, 32,149, 74, 15, 46, 95,
-190, 92, 78,211, 52, 22, 46, 92,152,111, 48, 24,102, 87,174, 91,100, 99, 99,115, 29, 21,134,187, 62,106,245, 34,213,190, 43, 79,
-212, 56, 54, 97, 53,203,106,174, 35,132,132,213,167, 97,229,185,168,237,243,194,235, 51, 91,213,191,129,250,215,234, 34,129, 14,
- 46, 94, 62, 40,249,245, 32, 68, 28, 10, 34,118,229,194,161,192, 74,188,135,230, 66, 46,140,132, 4, 52,214,104, 85, 45, 92, 46,
- 23,106,181, 26,102,179, 25, 31,126,248,161,224,236,217,179,246, 44, 22,235,231,134,116,170, 27,166,248,248,120,248,249,249, 81,
-199,143, 31,119,158, 61,123,182,168,234,115, 74, 74, 74,208,166, 77, 27,234,212,169, 83, 78, 31,127,252,177,180, 62, 51, 67, 81,
- 20,120, 60, 30,230,206,157, 43,186,121,243,166,157,155,155, 27, 18, 19, 19, 81, 88, 88, 8,169, 84,138,185,115,231,138,110,220,
-184,225,232,230,230,134,148,148, 20,148,148,148, 64, 42,149, 90,109,180,120, 60,222, 19,219, 80, 20, 5,131,193, 96,149, 49, 80,
- 40, 20,123, 35, 35, 35, 29, 21, 10, 5,162,162,162, 96, 50,153,160, 80, 40, 48,103,206, 28, 81,100,100,164,163,141,141, 13, 98,
- 99, 99, 65, 8,129, 92, 46,183,170,142, 0, 64,211, 52, 98, 99, 99,209,162, 69, 11, 92,186,116,201,105,198,140, 25,194,170,242,
-132,132, 4,184,187,187,227,210,165, 75, 78, 18,137,100,111, 93, 90, 52, 77, 35, 59, 59, 27, 49, 49, 49, 72, 76, 76, 68, 94, 94,
- 30,242,243,243, 81, 86, 86, 6,147,201, 4, 0, 16,151,149,134,239, 59,112,252,174, 72, 36, 18,251,123,183,245,184, 23,125, 63,
- 87, 36, 18,137, 61, 61, 60,188,129, 79, 89,245, 24,194,159, 83, 83, 83,237,167, 76,153,194,203,201,201, 65, 81, 81, 17, 56, 28,
-206,159,174, 45, 62,223,178,161, 64, 38,147,201, 79, 40, 20, 82, 6,131,225,113, 4,140,207,231,227,221,189,106,248, 47,193, 19,
-203,203, 27,115, 65,204, 70,232,245,122,191,191, 61,154, 5, 80,160,244,109, 65, 81,129,215, 19,203,237,250,132,189,194, 67,210,
-105,128, 54, 2, 44, 14,250,119,112,231, 28,189, 87,238, 12,130, 14,208,193,151,144,134,103,126, 17,128, 2, 12,109, 0,170,203,
-217,135, 38,251, 94,163,223,226,101,102,102,130,199,227, 65, 32, 16, 32,112,192, 88,206,190,187, 70, 23, 80,232, 8, 3,124, 44,
-209,124, 34,236, 40, 18, 45,254,228,147, 79, 36,213, 53,167, 78,157, 42, 81, 40, 20,159, 52,218,100,149,139,123,192, 68,230,198,
-100,170, 91, 44, 15,207,241,123,148,171,241, 1, 33,243, 0, 99,167,167, 96,182,250, 11, 4,130, 36, 0,189,155,100,178,100,252,
-107,251,247,255,212,204,174,121,133,201,130, 73, 11,112, 69,112,113,180,193, 55,239, 6,219, 57,218,136,172, 53, 91, 1,206,206,
-206,231,175, 95,191,238, 32, 20, 10, 17, 25, 25, 9, 30,143, 7,161, 80,136,246,237,219, 99,199,142, 29,142,118,118,118, 86,155,
- 45, 2, 82,107,204,119,212,168, 81,164,111,223,190,152, 53,107, 22,118,239,222, 13,189, 94,143,229,203,151, 35, 53, 53,213, 34,
-217, 88,224,248,170,168,168,239, 87,198,196,196,127, 16, 16,224, 59, 74, 34,177,155, 53, 97,130,226,227,143, 63, 62,113,236,216,
-177,239,134, 13, 27,150,127,243,230,205, 13, 0, 14, 90,121,120, 41, 0, 91,215,173, 91, 55,171,202,184,125,252,241,199,223, 30,
- 59,118,108,229,176, 97,195,178,111,222,188, 57, 15,192,214,166,180, 75, 52, 77,135,255,252,243,207,119, 69, 34,145,216,199,199,
-199, 35, 58, 58, 58, 87, 36, 18,137, 61, 60, 60,188,251,245,235,199,106,140,102, 99,112,114,114, 26,120,253,250,117,127, 84, 76,
- 26, 19, 84, 25,173,232,232,104,155,210,210, 82, 27,169, 84,106,227,234,234, 42,171, 50, 91,163, 71,143,182,225,112, 56,245, 94,
-183, 42,149,234,216,162, 69,139, 20,163, 71,143,174,250, 31,151, 47, 95,198,238,221,187, 33,145, 72,158,120,239,136, 17, 35,240,
-230,155,111,218,234,245,250,159, 45,168,238,228,233,211,167,251, 56, 59, 59, 99,241,226,197,186,204,204,204,129, 0, 82, 1, 40,
- 66, 66, 66, 62,143,142,142,238, 22, 20, 20,116, 0, 64,231,250,238,189,218,188, 72,117,163, 99, 73, 89, 99,223,111,169,217,170,
- 81, 84,103, 14,173, 39,140, 86, 88, 88,216, 69,212, 49,147,202, 80,168,132, 0,102,136,216, 20,196,236,106,102, 11, 52, 56, 37,
-185,160, 26, 49, 75,165,182, 47, 67, 62,159, 15, 54,155, 13,189, 94, 15, 75, 31, 84, 93,101, 10,228,114, 57,164, 82, 41, 52, 26,
- 13, 76, 38, 19,132, 66, 97,149, 25,129, 92, 46, 7,151,203, 5,151,203,133, 80, 40,252, 83, 52,169,102, 52,135,199,227, 65, 34,
-145, 32, 59, 59, 27,169,169,169,160,105, 26, 82,169, 20, 18,137, 4,124, 62, 31, 89, 89, 89,200,202,202, 2, 33, 4, 18,137, 4,
- 18,137, 4,214, 12,184, 54,155,205,181,126,249, 27,141, 70,171, 34, 90, 38,147, 9, 15, 30, 60, 64, 90, 90, 26,132, 66,225,227,
-125, 21, 8, 4, 72, 72, 72, 64, 78, 78, 14,196, 98, 49,228,114, 57, 20, 10,133,197,186, 85,251, 34,147,201, 32, 18,137, 80, 84,
- 84, 4,181, 90,253,248,152,202,229,114, 72, 36, 18,148,148,148, 32, 55, 55,183,222,125, 55,155,205,200,202,202, 66, 94, 94, 30,
-210,211,211,145,159,159,255,184, 1,170,140, 26, 53, 45,176, 83, 90,138,130,130,130,199,145,200,186, 22, 75,160,105, 26,101,101,
-101,184,126,253, 58, 69,211, 52,138,139,139,233,188,156, 28,243,204, 44, 62,142,126,186,141,252,116,250,142,118,223,201, 72,205,
-225,243, 49,154,173,135,239,105,132,221, 62, 51,225,159,224,171, 0, 5,140,220,208,124,149, 81,144,103,224, 41,156, 3, 66,128,
-164, 83, 0,139, 3, 8,109,209,189, 93, 75,164, 22,153, 37,113, 74,189, 16, 20, 6, 99,171,183,173, 69,154,102,238,160,188, 50,
-163, 32,197,224, 40,247,235,208, 25, 74,165, 18, 2,129, 0, 2,129, 0, 93,122,133, 32,169,192, 44,190,159,169, 17,131, 32,212,
- 34,205, 63,104, 37,149, 74,123,244,238,221,155,170,174, 57,116,232, 80, 80, 20,213, 30,128,175, 85,141,220,230, 86,124, 24,196,
-221,193, 33,115,239,103,171,221,142, 70,107,189,135,143, 26,107,183,233, 92,174,223,131, 28,157, 23,136,113, 62,136,161,115, 19,
-204, 86, 63,153, 76,118, 98,203,150, 45, 94, 66,161,240, 20,128, 62,141, 17,145,138,216,219, 23,207,122,165,153,109,149,201, 50,
-170, 1,142, 8,224,138, 0,142, 8, 46, 78, 14, 88,246,230, 32, 59,177,144,123,216, 10,195,186,111,235,214,173,142, 53, 77, 86,
-213, 18, 24, 24,136, 37, 75,150, 56,218,217,217,237,181, 68,111,237,154,213,164,184,164, 4, 32, 64,105,169, 10,107,215,172, 46,
-170, 90, 55,122,244,104,210,167, 79, 31,204,154, 53, 11, 43, 87,174,196,201,147, 39,209,189,123,119, 76,155, 54, 13, 65, 65, 65,
- 13, 73,135, 42, 20,138, 61, 33, 33, 33,215,179,100,178, 55,179, 59,119,230,159, 87, 40, 74, 6,150,148, 40, 60,163,163, 13, 62,
-192, 61, 0, 95,101,100,100,188, 96,133,201,122, 89, 46,151, 71, 14, 28, 56,208, 32,147,201,210,214,175, 95, 63,115,246,236,217,
- 88,189,122, 53, 22, 45, 90,244, 53,128, 55, 0,124,148,145,145,225, 86,159,201,250,171,218,165,191,170,173, 51,155,205,233, 7,
- 15, 30, 12, 50, 24, 12,238,149,221,131,130,226,226, 98,121, 97, 97,161,204, 96, 48, 72,104,154,150,216,216,216, 72, 1,136, 39,
- 77,154,196,185,127,255,190,159,201,100,202,172, 79, 51, 39, 39,231,213,133, 11, 23,230,231,231,231, 3, 0,218,183,111,143,226,
-226, 98, 44, 88,176, 0,239,188, 83, 49, 33,184, 83,167, 78, 32,132, 64,169, 84, 98,237,218,181,202,156,156,156,215, 44,168,110,
-235,182,109,219, 34, 58, 58, 26, 15, 30, 60, 56, 7,128, 70,197, 56,214,146, 59,119,238,220,205,203,203,195,222,189,123,121,205,
-154, 53, 59,134, 58, 82,188,212,231, 69, 26, 3, 69, 81,225,141,217,174, 42,114, 85, 91, 68,172, 14,234,143,104,133,133,133, 81,
-213, 95,159,136, 24, 81,136, 74,139,184, 4,187,128,206, 79, 68,179,196,108, 10, 34,185, 2, 73,233,169,224,129,138,121, 90, 70,
-171,168,168, 8, 51,103,206,212,188,250,234,171, 5, 52, 77,143,181,212, 20, 40, 20, 10, 40, 20, 10,220,191,127,159,140, 25, 51,
- 70,185,126,253,122, 77,117,163, 21, 31, 31, 79, 66, 67, 67,115, 63,249,228, 19, 85,125, 70,171, 42,162,181,106,213, 42, 77,255,
-254,253,243, 98, 98, 98, 72,149,153,146, 74,165, 88,187,118,173, 38, 56, 56, 88,121,235,214, 45, 82, 85,102, 77, 68,139,197, 98,
- 61, 54, 90,213,183, 97,177, 88,160,105,218, 42,163, 85, 94, 94,254,234,176, 97,195,148,177,177,177,164,106, 63, 21, 10, 5,214,
-175, 95,175, 25, 52,104,144, 50, 38, 38,134, 84,149,201,229,114,139,205, 96,213,231,203,100, 50,200,229,114,220,191,127,159,132,
-134,134, 42, 55,111,222,172,173, 94,254,224,193, 3, 50, 98,196, 8,101, 89, 89,217,171,245,153,151,170,238, 60,147,201, 4,173,
- 86,139,252,252,124,164,167,167, 63, 14,167,107, 36,242, 23, 94,121,105,120, 71,141, 70,163,190, 31,255, 48,173,125, 59,127, 39,
-141, 70,163, 78, 77, 75,139, 7, 62,165,235,209, 30, 27, 16, 16, 80, 48,115,230, 76, 77, 81, 81, 81,147,141, 22,159,207,143,229,
-112, 56,164, 79,159, 62, 68,175,215,147,244,244,116, 99,126, 81,145,201,119,197, 10, 18,243,238,187,148, 40, 34, 66, 32,149, 74,
-169, 74, 77, 86, 98, 98, 34, 45, 18,137, 98,255,118,163,197,162, 93, 64,145,222,191, 63, 84,217, 12, 26, 62,158, 79,229,220, 4,
- 12, 42, 64, 96, 11, 8,108,193,145,216, 99, 72,159, 78,236,239,175,151,186,128,208, 61,193, 19,184, 55,168,201, 37,206, 0,221,
-231,215,120,173,109,239,113,115,248,133,133,133, 96,179,217,143, 77,145, 88, 34,193,192, 81,147, 88,223,222,212,185, 0,164, 23,
- 40,182,187, 21,247,250,251,139, 23, 47,230, 21, 21, 21,129,197, 98,253,161, 41, 22, 99,198,140, 25, 2,185, 92,190,200,226,198,
-239,160, 31, 15, 92, 65,119,128,188, 19,151,163,117, 59,118, 79,227, 51,127,213, 55,162,128, 78, 65,152,222,223, 73,180, 42, 60,
- 55,224,110,186,166, 37, 96,126, 23, 38,125,151, 70,152,173, 62, 50,153, 44, 60, 34, 34, 66, 60,116,232, 80,172, 93,187, 86, 34,
- 18,137, 78, 53,166,225, 47, 87,153,103, 47,221,252,131, 50,106,195, 96,192, 80, 94, 97,176,170, 45,185, 42, 26, 75,190,185, 80,
- 98, 52,146, 87, 44,213,212,104, 52,147,223,120,227,141,130,195,135, 15,255,201,100, 9,133, 66, 36, 39, 39, 99,249,242,229,133,
-133,133,133, 13,126, 41,174, 95,183, 54, 50,250,238,111,248,246,235,165, 0, 8,182,172,127, 11,215,126,223,111,211,191, 95, 95,
-210,162, 69, 11, 18, 20, 20,132,153, 51,103, 98,217,178,101,136,139,139,131,131,131, 3,222,122,235, 45,244,235,215, 15,235,214,
-173,171,175,145, 10,157, 61,123,246,242,140,140, 12,159, 95,127,253,149,147,151,151,231,180,110,215,174,146, 67, 37, 37,133, 43,
-163,163,227, 62,106,215,174,237, 7, 29, 58,188, 86, 79,234,135, 90, 77,214,172, 89,179,246,101,100,100, 4,158, 59,119,142,155,
-151,151,231, 62,107,214, 44,172, 89,179, 6,139, 22, 45,218, 1, 96, 58, 44,155,240, 98,113,187,196,102,179, 95, 24, 59,118,108,
- 71,141, 70,163,142,139,139, 75,107,215,174,157,147, 70,163, 81,167,165,165,197, 95,188,120,145,110,140,102, 99, 40, 40, 40,120,
-180,119,239,222,248, 57,115,230, 4,102,100,100,248, 1,176, 47, 43, 43,147,148,149,149, 9,244,122,189,200,214,214,214,182, 83,
-167, 78, 14,211,166, 77,147,222,185,115,199, 47, 35, 35, 67, 85, 25, 69,170, 19,131,193, 16, 87, 84, 84, 20, 54,120,240,224,226,
-162,162, 34,116,232,208, 1,195,135, 15,135,139,139, 11,220,220,220, 48,114,228, 72,120,123,123,163,160,160, 0,175,188,242, 74,
- 97, 94, 94,222, 96, 0,137, 22, 84,247, 81, 78, 78, 14,122,246,236,137,165, 75,151,134,189,248,226,139, 49,125,250,244, 41,109,
-215,174,157,218,221,221,221,119,211,166, 77,104,214,172, 25, 14, 30, 60,232, 42, 16, 8,246,214, 98,178,234,244, 34, 0,242, 42,
- 13,143,190,198,107, 94, 3,235, 44,221,182,214,191, 45,120, 95, 77,179, 85,125,249, 83,215, 97,237, 39, 4, 88,178,251,224,247,
- 90,190, 71, 27, 40,124, 58, 66, 44, 20, 66,196,231, 67,100,107, 15, 29, 77, 99, 87,114,142,186,156,144, 69,214, 94, 60, 53,191,
- 8, 41,138,194,151, 95,126,105,234,209,163,135,246,194,133, 11, 91, 52, 26,141, 7, 42,178,202, 90,108, 10, 54,111,222,172,158,
- 59,119,238,221,220,220,220,142, 66,161, 80, 95, 85,190,101,203, 22,245,164, 73,147,162, 51, 50, 50, 2,197, 98,177,186,174,241,
- 89,213,141,150, 64, 32,208,229,230,230, 6, 77,157, 58, 53,246,171,175,190, 42, 23,139,197,144, 72, 36, 16, 8, 4,250,220,220,
-220,142, 51,103,206,188,187,102,205, 26,181, 72, 36,130, 68, 34,177,170, 91,142, 16,242, 39, 67, 85,189,220, 82, 76, 38,211,133,
-220,220,220,142,115,231,206,189,179,105,211,166,242, 42, 3, 84,189,142,235,214,173, 83, 75,165, 82,171, 34, 90, 85,239,147, 72,
- 36,216,184,113,163,122,206,156, 57,119,115,115,115, 59, 10, 4, 2,125,181,242,242,217,179,103,223,201,205,205,237,104, 50,153,
- 46,212,243,107,204, 92, 90, 90, 10, 14,135,131,232,232,104, 29,143,199, 3,139,197, 66, 66, 66,194,227,198,199,206,206,206,191,
- 99,251,118,190, 63,236, 59,120, 81,196, 19, 8,122, 4,117,241, 75, 76, 73,205, 32,132, 74,105,160,170, 71, 52, 26,141,199,133,
- 11, 23,182,244,232,209, 67,251,229,151, 95,154,234,138,108, 89,130, 78,167,187,120,251,246,109,163, 80, 40,164,178,179,179, 77,
-108, 54, 27,102,179,153,232,130,130,116,237, 55,109, 34,247, 63,248,128,146, 75, 36, 28, 30,143, 7,177, 88, 76,157, 62,125, 90,
-175, 86,171, 47,254,253, 70, 11, 98, 80, 16, 61,204,213,201,132, 44, 19,133,248, 35, 21, 38, 75,104, 3, 8,109, 1,161, 45,154,
- 53,115,199,205,100,181, 12, 44,240, 97,182, 32,135, 24, 33, 18, 80, 16, 71, 43, 33,227,242, 69, 84, 78, 78,206, 99, 67, 84,181,
-120,181,241,195,237, 84,149, 20, 20, 17,128, 13,107, 82,144,132,217,219,219,115,178,179,179,255,164,233,239,239,207, 54, 26,141,
-150,167,118,201, 50,187, 2,244,172,248, 28,173,235, 47,119,203,125,222, 93,249,173, 72,100, 46, 6, 34, 54, 35,160,149, 27,222,
- 29,215,137,255,241,177,188,128, 91, 41,234, 86, 96,147,204, 47, 15,255, 0, 0, 32, 0, 73, 68, 65, 84,233,160, 85,142, 86,212,
-179,183, 76, 38, 59,117,235,214, 45,177, 76, 38, 67, 98, 98, 34,130,130,130,176,115,231, 78,177, 88, 44, 62, 9,192,170,241,120,
- 55,148, 72, 85,149,153,123,188,127, 48, 45, 39, 42,219,244,132,201,202, 43, 39,120,227,139, 99,197, 69,165,218,177,215,211,235,
-190,127,106,225, 78,113,113,113,232,162, 69,139, 10,242,242,242,158, 48, 89,169,169,169, 85, 95,138,253, 1, 52,248,227,247,127,
-191,157, 9, 92,177,108, 46,110, 69,196, 96, 72,216, 59,184, 29,245, 8, 31, 45, 28, 5, 27,185, 8, 23, 46, 92,192,232,209,163,
-177,116,233, 82, 36, 36, 36,224,167,159,126,162,118,238,220, 73, 93,191,126,157,250,226,139, 47,168, 6,134, 52, 76, 88,185,114,
- 37,110,221,186,133,161, 67,135,226,210,165, 75, 40, 44, 44,196,254, 83,167, 30,238,125,248,240,163,170, 49, 91,117,164,126,168,
- 21,185, 92, 62,127,229,202,149,136,136,136,120,172, 89, 80, 80,128,149, 43, 87,102, 0,120,203, 26,147,101, 77,187,212,161, 67,
- 7,223,125,251,246, 93, 20, 10,133,130,160,160, 32,191,228,228,228, 12, 0, 41,141,208, 44,109, 74, 79, 85,126,126,254,213,157,
- 59,119, 94, 31, 48, 96,128,120,242,228,201,142, 71,143, 30,181, 87,171,213,110, 2,129,192, 73,175,215,243, 31, 60,120,192, 62,
-116,232,144,203,253,251,247,147,181, 90,237, 77, 75,142, 71,110,110,238,205,184,184,184,193, 29, 58,116,120,176,101,203,150, 12,
- 87, 87, 87,122,218,180,105,120,227,141, 55,224,232,232,104,222,184,113, 99, 90,159, 62,125,162, 31, 61,122, 20,162, 86,171,239,
- 89, 88,215,239, 86,172, 88,113,101,223,190,125, 24, 62,124, 56,190,248,226, 11,236,223,191, 31,191,253,246,155,232,247,223,127,
-231,239,220,185, 19, 60, 30, 15,221,187,119, 71,104,104,232,192,202,238, 78, 75,191,151,110, 81, 20, 21, 78, 81,212,185, 26,175,
-183,234, 91,103,197,182,117,253, 93,239,251,106, 84,115,103,141,197,114, 38,180,194,167, 51,218,201,212, 87, 39,118, 39, 57,211,
-122, 19,229,120, 63,114,185,159, 29,153,218,154, 42,159,220,200,244, 14, 26,141,230,241,114,248,240, 97,226,226,226, 82, 46,147,
-201,172, 78,239,224,226,226,162, 44, 45, 45, 37, 93,187,118, 45,116,116,116,124,156,138,192,213,213, 85, 89, 94, 94, 78,186,119,
-239, 94,232,228,228,244, 56,189,131,187,187,123, 58, 33,132,120,122,122,102,213,165,103, 50,153,136,139,139, 75,213, 12, 61,174,
-157,157,221,182,110,221,186, 21, 42,149, 74,226,234,234,250, 56,117,130,163,163,227,218,160,160,160,154,229, 13,213, 55, 61, 35,
- 35,131,100,100,100,144,230,205,155,103, 85, 47, 79, 77, 77, 37,169,169,169,196,221,221,221,234,244, 14,142,142,142,107,106,169,
- 75,163,234,232,225,225,161,212,104, 52,164,103,207,158, 79, 28, 83, 15, 15, 15,165, 86,171,173, 42,183, 40,189,131, 72, 36,154,
- 46, 20, 10,179,132, 66, 97,150, 64, 32, 88,222,162, 69,139,220, 3, 7, 14,144,141, 27, 55, 86, 77, 73,135,163,255,136, 30,109,
-122,190,246,145,163,255,200,249, 77, 73,239, 32,147,201,206,187,184,184,148, 31, 62,124,248,137,235, 75,163,209, 88,156,222, 65,
- 36, 18,101,168, 84, 42, 90,169, 84, 26,175, 92,185,162,142,136,136, 80, 71, 71, 71,171,147,147,147, 53, 5,185,185, 6,165, 82,
-169, 41, 41, 41,209,221,189,123, 87, 39, 22,255, 51,233, 29,200, 78,239, 54,100,155,239,177, 71, 75,189,238,207,237, 43,214,222,
- 91,214,145,144,159, 71, 19,114,242, 13, 66, 46,188, 79,110,238,152, 70,122,122, 9,204, 87, 22, 52,143, 39,219,125,126,177, 36,
- 37, 3,217,217,190, 13,217,230,123,242,225,103, 94,247, 39,247,113,211,238,250,106, 35,185,113,227, 6,137,142,142, 38,137,137,
-137,228,228,145, 3,164,103, 43,113,133,230, 54,223, 99, 86,166,121,232, 37, 16, 8, 84,235,215,175, 39,215,175, 95,127,172,121,
-236,216, 49, 34, 22,139,213,128,101,179,150, 9, 64,145,109,254,163, 76, 95,249,252,254,241, 32,105, 89,193,137,247, 9,185,247,
- 61, 33, 59, 3, 8,249,174, 27, 33, 7,134, 17,114,252, 53,114,125,227, 56,210,203,139,103, 36,219,125, 46,145, 29,254, 22, 15,
-182,231,114,185,165,135, 15, 31, 38, 89, 89, 89,228,210,165, 75, 36, 34, 34,130,196,198,198,146,180,180, 52, 18, 30, 30, 78,184,
- 92,174, 22,141,120,108, 89, 55,103,120,134,180,229,101,223, 93,213,139,144,163,175,144,188,189, 19, 72, 88, 59, 89, 97,247,230,
- 77,202, 71,215,201,222,222, 62, 63, 60, 60,156, 36, 39, 39,147,139, 23, 47, 18, 39, 39,167,124, 0, 22,143,151, 13, 27,210,135,
- 16,253, 93, 18,220,183, 29,233,208,161, 29,233,215,171, 45,201,124,180,153, 4,117,110, 65,182,109,219, 70,148, 74, 37,105,209,
-162, 5,177,182, 98, 33, 33, 33, 55, 8, 33,145, 67,135, 14,141, 4,112, 58, 36, 36, 36, 50, 41, 41, 41, 50, 40, 40,232, 58,234,
- 79,253, 80, 39, 3, 7, 14, 52, 16, 66,200,208,161, 67, 9,128,172,144,144, 16,146,148,148, 68,130,130,130,244,141, 57,120,150,
-180, 75,129,129,129, 61, 6, 12, 24,240, 81, 96, 96,224,124, 75,210, 59, 52,160,249,180,146, 80,179, 81,145,252,211, 31, 64,151,
-202,197,175,178,140,221, 4,205,215,184, 92,238, 46, 59, 59,187,223,108,109,109, 47,176,217,236,157, 0, 38,162,113,249,205, 88,
-149, 17,198,179,142,142,142, 9, 29, 58,116,208, 12, 30, 60,152, 12, 25, 50,132,204,154, 53,139,208, 52, 77, 14, 28, 56, 64,150,
- 46, 93, 74, 90,219,219,155, 54, 2,249,219,129, 41, 96,168, 72, 88, 58,165, 21,117,241,213,150, 40,123,165, 37, 84,175,183,166,
- 44, 73, 88, 26, 82,151,209,162,105,154,196,199,199,147,224,224,224,114,137, 68,146, 9,203, 19,150, 62,161,233,224,224, 16,225,
-228,228,244,167, 36,154,213,202,159, 72, 88,234,228,228,116,213,213,213, 85,233,232,232,120,187, 54, 77, 7, 7,135, 8, 87, 87,
- 87,165,131,131,195, 19,201, 61,217,108,246, 80, 7, 7,135,204,154,229, 28, 14,103,128,147,147, 83,122,205,242, 58,246, 29, 46,
- 46, 46,233, 89, 89, 89, 36, 47, 47,143,120,120,120,100,213, 52, 96, 57, 57, 57, 79, 24, 48, 75, 52, 27,170, 75, 61,117,172, 85,
-211,130, 99,218,152,243, 94,133,119,179,102,205,114,215,173, 91, 71,164, 82,233, 19, 83,158,125,250,190,190,248,198, 67, 85,233,
- 27, 11,183, 29,168, 37, 97,169,165,201, 65, 7, 75, 36,146,204,224,224,224,242,248,248,120, 66,211, 52,161,105,186, 46,163, 85,
-155,230, 11, 93,186,116, 41,200,207,207, 55,151,149,149,153,210,211,211,117, 73, 73, 73,154,101,203,150, 25,242,242,242,180, 42,
-149, 74, 31, 21, 21,165,115,117,117,205, 3,240,130,181,231,168,145,132,212,236, 62, 35, 59,252,122,145,237,126,225,177,159,120,
- 62,120,173,155, 68, 23,185,110, 40, 33, 23,222, 39,215,183,189, 65,122,120,241, 43, 12,209, 14,223, 83,228, 91,239,190,100,115,
- 43,190, 69,154,187, 90,247, 33, 59,124, 79,221, 95,226,249, 96,116,103, 71,253,190,239,119,144,132,132, 4,114,236,208, 94,210,
-189,101,165,201,218,238,119,150,108,243, 11,182, 68,179, 54,179,245,205, 55,223,144,132,132, 4,242,203, 47,191, 88,106,178, 66,
-106, 51, 90, 31,134, 72,139,223,232, 38,212,189,210,137,175, 31, 25,192, 51,132,182,225,153,122,122,114,204, 29, 93, 89,180,159,
- 35, 72,168,143, 72, 71,182,251, 92, 34,219,253, 6, 91, 90, 79, 62,159,159,134,106, 57,117,106, 46, 2,129, 32,175, 30,163, 21,
-210,160,217,242, 22,100,159, 95, 58,128, 12,239, 32, 43,176,208,100, 53,116, 45,117,114,112,112,200,255,238,187,239,136,179,179,
-115,158,133, 38,235,177,230,136,176, 80,146,250,232, 36,249,229,192, 74, 18,220,215,143,236,249,102, 46,185,113,233, 19, 50,108,
- 72, 48, 9, 9, 9, 33,249,249,249,100,192,128, 1,196,218,122, 42, 20,138, 61, 42,149, 42,242,204,153, 51,145, 33, 33, 33,145,
-123,246,236,137,188,124,249,114,164, 88, 44,222, 83, 21,156,168,105,182,252,254,220,254,135,212,136,104, 69,150,149,149,145, 51,
-103,206,144,144,144, 16,178,103,207, 30,114,249,242,101, 34, 22,139, 35, 27,123, 31, 89,218, 46, 13, 26, 52,104,113,114,114,114,
-233,146, 37, 75, 14,212,146,176,212, 82,205,132,167, 84,207,167,210,134,252, 3,154, 50,145, 72, 20,121,247,238, 93, 82, 84, 84,
- 68,218, 57, 59,147, 21,108, 54,201,224,241, 72, 22,143, 71,182, 1,133,255, 2,155, 52,173,174,174,195,191,154, 90,141,150, 86,
-171, 37, 11, 22, 44,208, 11,133, 66, 53,143,199,179,246, 17, 60,207,245, 69,232,224,224,112,213,217,217, 89,233,236,236,252,132,
-217,171, 94,238,224,224,112,251, 95,126, 3,122,243,120,188, 84, 46,151,251,228, 35,120,252, 71,244,104,221,107,242, 34,231,128,
- 17, 67,154, 88, 79, 30,143,199,251, 80, 40, 20,170, 23, 44, 88,160, 87,169, 84,214, 24, 45, 0, 24, 36, 22,139, 51,119,239,222,
-173,121,248,240,161,177,176,176,208,116,227,198, 13, 99, 68, 68,132,254,211, 79, 63, 45, 19,139,197,153,168, 59, 45,193,223,114,
- 60,201,230, 86,252, 42,179,117,111,145,103,236,240,118, 98,195,206,121,161,164, 71,139, 26, 38,171,238, 76,238,181,107, 86,154,
-173, 59, 31,123,196, 6,123, 75, 77, 43, 23,189, 75,186,183, 20, 61,105,178,172,208,172,105,182,196, 98,113,217, 39,159,124, 98,
- 77, 36,235, 73, 67,184,203,199,131,236,240,221, 83, 97,162, 26, 88,182,249,124, 77,190,244,241,120, 86,238,163,110,206,240, 28,
-232, 45,136,177, 34,146,101, 73, 61, 59,217,218,218, 62,176, 34,146,245, 88,243,203, 47,183,144, 9,227, 7,145, 71, 15, 14, 19,
- 85,193, 73,114,251,218,122, 50,102, 68, 32,233,222, 61,136,236,216,177,131,196,197,197,145,174, 93,187,146, 70,212, 51,116,198,
-140, 25,145, 73, 73, 73,145,137,137,137,145,151, 47, 95,142, 28, 53,106, 84, 36,128,208,234, 61, 65, 85,102,203, 48,102,140,174,
- 19,139,245,110, 3,154, 47,207,152, 49,131, 36, 37, 37,145,196,196, 68,114,249,242,101, 50,106,212, 40, 2,235, 30,223,211,168,
-118, 41, 48, 48,176, 71,112,112,240,162,206,157, 59, 15,121, 90,154,255, 65,163, 37, 25, 61,122, 52,109, 54,155,201,144, 33, 67,
-204,155,128,226,157, 20,165,220, 73, 81,202, 29, 64,222,191, 61,162,245, 87, 63,240, 51, 4,192,185,234, 5, 66,161, 80,169,213,
-106, 29,165, 82,233, 17,149, 74, 53, 7, 21,211, 34,155,164,249, 87,212,147,209,252, 87,104,186, 74,165,210, 45, 42,149,106,148,
- 80, 40,204,211,106,181,206, 86,104,218, 8, 4,130,119,133, 66, 97,176, 90,173,246, 6, 0,137, 68, 18,175,211,233,126,211,104,
- 52, 27, 0, 20,255,211,251, 78, 54,183,226,131,207,239, 2,130, 15, 34,211,202, 91,174, 60, 83,232, 57,111,128,109, 90,207,214,
-146,100,112,233, 47, 64,233,110, 82, 83, 82,117, 86,107,138,168, 32,152,185, 31,220, 76, 81,183,248,226,215, 50,207,249,193,210,
-180,158,173,164,105, 32,248, 2, 2,245, 53,107, 53,107,154, 45,137, 68,178,187,188,188,252, 77, 0,191, 89,187,239,228,160, 31,
- 15,229,198,102, 48,178,219,129,212,243, 8, 31, 66,212, 96,177,163,145, 3, 37,245,233, 3, 3,115, 31,213,174,249,213, 87, 91,
-201,185, 95, 79, 66,167, 46, 68,118,110, 41, 38, 76,124, 29,157, 58, 5,194,193,193, 1, 43, 86,172, 64,155, 54,109,176,116,233,
- 82,170, 17,245, 12,149, 74,165, 19,124,125,125, 91,221,191,127, 63, 81,173, 86,255, 8,224,108,205,239, 31, 95, 32, 88,204,225,
-116,212,152, 76,151, 30, 0, 17, 13,104,190, 44,149, 74,231,251,250,250, 6,220,191,127, 63, 70,173, 86,175, 3,176,159,105,235,
-158, 15, 77, 22,139,181,193,211,211,115, 76,114,114,242, 7, 0,246,225, 63,196,223,110,180, 24, 77, 70,243, 57,212,172,186, 79,
-200,179, 86,207, 63,204, 22, 61, 7, 20, 90,130, 80, 25,224,209, 27, 27, 48, 89, 13,107,138,168, 32,152, 56,239,128, 66,115, 16,
-228,128,176, 54, 52, 96,178,254, 94,147, 9, 80,248,180,158,246,235, 83, 16,170,238,243,197, 92,243,181,176,120,241, 98,114,250,
-244,105,136,197, 98,104, 52, 26, 12, 30, 60, 24,159,127,254, 57,197,180, 33,140,230,223,168,249,175,132,195, 28, 2, 6,134, 6,
- 33,207,106,197,168,183, 19,245,228,160,223, 45,228,179, 23,128,133,150,128, 41, 21,229,166, 28,234,237, 84,125, 19, 53,111, 32,
-159,154, 11, 54,188,193, 55, 61,130, 74,159, 67,189,213,120,205,191,224, 23, 34,193,167,207,238,121,121, 30,169,105,170, 34, 34,
- 34,152,131,194,192, 96, 57,211,240,228, 76,195,199,255, 51, 70,139,129,225, 57,135,122,241,129, 1, 64, 70,229,242,204,106, 50,
- 48, 48, 48,252, 7, 13, 23, 40,212, 61,160,205,154,144, 96, 99, 6,218,157, 99, 52, 27,165,201, 6,160, 0, 96,131,138, 28, 36,
- 85, 83,122, 27, 74,179, 49, 4,128,145, 57,158,140, 38,163,201,104, 50,154,140,230, 63,172,217,144,246,243,216, 37, 89,219, 44,
-195,157,127,199, 7,135, 48,154, 79,149,193,255,154,125, 39,232, 8,130,141,149, 75, 71,230,188, 51,154,140, 38,163,201,104,254,
-231, 53,255,149, 48, 93,135,207, 23,194,231,182,230,132,184, 2,168, 74,114, 25, 13, 45,229, 11, 33,230, 2, 0,202,112,155, 16,
- 60, 4,208,174,114,125, 58, 69, 89, 61, 27,149,129,129,129,129,129,225,159, 34, 16,192,109, 0,174, 0,134, 1, 8, 71,101, 86,
-133,127,212,104,137,236,219,186,130,195,234, 64,209,196, 23, 0, 8,139,138,133,137,142,210, 20, 60,108,242,151,172,212,205,219,
-142,128,127,144,130,254, 69, 85, 86,124,147,147,161,181,243,150,143,113,118,144, 77,200, 41, 40,217, 29, 19,167, 58,106,205,182,
- 10,133,167, 66,104,103, 59, 78,103, 48,182,227,243,120,105,134,226,210,157, 69, 69,137,101,141,168,134, 93,125, 43, 63,253,148,
- 80, 39,178,111, 83, 60,177,129,101, 47,231, 81, 42,168,136, 42, 91, 74,123, 21, 39,147, 67,135, 94, 36,214,158, 27,138,133,254,
- 18,153,172,179, 64, 40, 14, 18,203,108,219,210, 4, 40, 84,102,166,232,141,166,203,102,189, 58,146,208,248,159, 21,231,106, 18,
-128,149, 0,128, 1, 3,206,161, 29,228,216, 80, 85,113,188, 53,224, 30, 38, 93,184,128,170,228,178, 31, 2, 88,197,220,183, 12,
- 12, 12, 12, 12,207,153,209, 26,134,138, 46,195,134, 7,195,123,250,247,190, 37, 20,138,188, 0,128, 38, 4, 52, 1,202, 75,139,
- 35,115, 18, 35, 6, 3,128, 67,139,192, 51, 92,161,188, 51, 77, 42,214,155,105,192,100,208, 38,151,166,222,232,106, 73,141, 36,
-142,222,163, 7,132, 12, 28, 19, 22, 54,204,167,125,187,246,173, 1,224, 94,244,189, 71, 39, 78,132,199, 93, 56, 71, 29, 46,207,
-139,255,165, 73, 1, 20, 8, 63,239,210,165, 83,239,136,136,219, 75, 1,204,106,234, 17,180,183,151,206, 57,251,243,130,190, 3,
-199,172,149, 0,214, 25, 45,161,157,237,184,145,195, 95,232,244,222,219, 51, 88,111, 44, 88,225,117,235,202,255, 86, 75, 93, 3,
-138, 9,109, 60, 91,174, 28,255,123,125, 15, 78,174,233, 31,235, 50, 88, 63, 22,158,102,109,252,174,135,173,166,240,209,120, 66,
-155,199, 83, 20, 5, 54, 95,124,200,177, 85,239, 3, 54,253,231, 21, 1,176,120,198,152,220,213, 63,196,201,213,253,240,248,215,
-223, 21,138, 21,206, 28,176,121, 0, 40,100,165, 60,192,133,253, 43,109,223,249,236,155,192, 43, 81,169,166,243, 63,111,213, 82,
- 60,238, 24,117,246,253,134,251,211, 83, 83,109,224,233, 89,241,247,215, 95, 47,134, 87,203,123,168, 24,107, 6,172, 71,201, 15,
- 89,104, 7, 84, 24,173,148, 20,216, 50,247, 44, 3, 3, 3, 3,195,115, 68,120,165,185, 10,175,185,162, 78,163, 37, 20,138,188,
-174,255,239,132,221, 47,151,211, 1, 0, 33,129, 46,248,104,217,150,208, 61,155, 35,226, 0,160,199,128, 48,239,165, 31,190,141,
-171, 49,185, 32,132,160, 83, 27,123, 12, 25,249,162,101,198,195,217,175,235,184,113, 99, 95, 93,176, 96,254,136,132,132,132,148,
-125,251,246,253, 14, 0,125,250,246,109,179, 98,197,138,151,214,218,218, 9,126, 58,244,115,166, 86,249,224, 86, 99,246, 86,232,
-214,170,153, 79,219,150, 19,126,250,118, 11,171,255,224,177,175,164,160,124,165, 54, 43, 49,211,146,109, 29, 28, 28,230,114,185,
- 92, 5, 80,241, 52,246, 42, 12, 6,226, 2, 0, 38, 51, 45,179,117,243, 41, 99,243,132,102,129,128,119,191, 76,165,218, 93,154,
-249, 96, 87,125,154, 58,163, 49,224,157,183,166,176,238, 36, 22,192, 43,160, 15,123,227,202,143, 65,155,141,182,239,126,184,108,
- 92,196,141,159, 80,174,196, 69, 11,119,141, 91,179,160, 89,179,238,236,207, 87, 74, 7, 81, 20, 94,243,236,241,250,168,165,223,
- 31,226,118,105, 35,135,206, 72,227, 84,100, 65,143,109, 27, 62, 95,115,101,219,176,227, 0,118, 0, 56, 15,160, 65, 83,103,103,
-111,247,227,220, 69, 27,164,229,250, 63,102,123, 87,154, 44,124,189,251, 32,238,166,211,240,245,241,229,184,204, 93, 45,221,177,
-108,218,247,234,138,231,108,213,102,119, 91, 1,232, 5,196,218, 97,250,103, 3,241,195,170,229,112,114, 42,135, 76,150, 6, 10,
-206, 0,218, 86,190,241, 33, 63, 31,233, 0, 62,204,205,133,100,233, 12, 12,190, 3, 44,236, 8,228, 2,184, 66, 89,246,212,120,
- 6, 6, 6, 6, 6,134,127,138,108, 60, 57,248,125,103,131, 70, 11, 0,164, 34, 14,226,146,114, 0, 0, 54, 34, 96,206,244,201,
- 40,200,207,243,214,155,104,188, 62,121, 34,110,199,102, 35, 46, 57, 15,132, 16,120,187, 91,252, 16,110,176, 65,119,121,125,234,
-235,253,206,156, 61,123,115,241,162,197, 63, 80, 20,174, 1,192,142,157, 95,247, 88,242,201,146, 55, 39, 78,158, 56,232,208,161,
- 67, 49, 0, 26,101,180, 56,148,108,203,154, 85,203,249, 25,249, 90,237,220, 5, 31,208,243,231,205,221, 8, 96,172, 69, 78,134,
-203, 85,100,100,100, 72, 89,172, 39,159,165,249,197,242, 15, 46, 13, 26,179,246, 97, 74, 90,241,157, 51,199,142,117,245,247,247,
- 71, 70,102, 78,175,213,155,182,119, 60,117, 70, 52,165,172, 84, 51, 70,157,255,160,214,135, 54, 11,184,220,152,207, 86,111,235,
- 68,219,180, 97,125,244,230, 80, 4,180,118, 67,102,110, 49,250, 14, 30,193,137,188,117, 43, 20,176,216,104,213, 76, 30, 56, 78,
- 79,231,118, 92,177,251,198,192, 81, 61,221,186,176, 88,108,168, 52, 70,228,149,232, 96,166,129, 62,126, 10,188,176,103, 19,167,
-176,220, 56,122,217,207,233,163,175,109, 14, 83,106, 75,178,102, 3, 56, 92,255,199, 16, 59,119, 39, 57,226,210,203,106, 53, 89,
-229, 90, 19, 0,128,199, 54,131, 2,177,175, 71,168, 23,128,239, 0, 95,224,215,217,175,194,217,121,159,179,179,243, 56, 39,103,
-151, 72,239, 87,167, 80,205,188,252,100, 42,141, 1,247, 99,238,149,249,119,142, 38,101,133,185,239,106,203,139, 14, 61, 0,162,
-125,129, 3,149, 26, 83,192, 24, 45, 6, 6, 6, 6,134,103,155, 58,103, 29,114, 0,224,196,137, 19, 36, 44, 44,236, 79, 25,128,
-205,102,130,184,228,138, 33, 56,108, 54, 27,195,122,183,193,198,213,159, 65,163, 55,225,110, 82, 9,126,185,154, 14,125,121, 49,
- 8, 33,200, 15,112,170,237,131,159,232, 82, 90,187, 82, 20,200, 22,112,199, 95,185, 33,105, 97,103,107,107,251, 48,230,135,242,
- 37,243,148,126, 28, 98,136, 92,246, 69,155, 36,158, 29,167,231,193,131, 7,252,135,135,133,241,165, 82,217,251,132,211,209,157,
- 91, 78,230,151,148, 68,149,212,165, 89, 19,145,147,239,136, 17,195, 94, 24,224,226,226, 76,191,186,226, 70,236,150,217,129, 30,
-109,219,180,237, 21,103,212,140,208,228, 62, 60, 86,199,102,143, 53,105,154, 6,139,197,130, 82,169,132,217,108,134, 78,167,131,
-209,104, 68,122,122,138,146, 38,196,221, 12,154,229,234,234, 14, 14,135, 15,175, 22,158,216,182,113,165,120,207, 79,199,130, 22,
- 46,254,252,168, 58, 31,221,241, 71,114,203,199,154,218,194,162, 67, 39, 79,159,117, 36,184,224,246,209,155, 67,217,185, 69, 42,
- 92,184,149,128,219,247,211,173, 61,145, 53, 83, 56,180,200, 76, 77, 40, 93,187,118, 45,123,233,169,132,244, 1, 67,198,154, 61,
- 91,119,104,161, 51, 19, 0, 20, 4, 60, 14,120, 28, 22, 60, 29,133, 56,242, 65, 59,220, 24, 25,229, 28, 26,232,184,129, 16,114,
-184,190,227,169,211, 25,205,189,125, 37,236,142,173, 20,136,122, 84,132,155,167,174, 97,238,162, 13,136, 72,210,161, 76,165, 6,
-101,214,129, 77,116,200, 79, 77,132,201,108, 38, 13,157,247, 10, 2,139, 0, 64, 32, 16,124,248,203,241,211,110, 58, 90,136,156,
- 98, 29,148, 69, 58,180,233, 62, 70,146,154,153,135,239, 62,123,233, 67, 0,135,124,129, 50,203, 52,155, 12,163,201,104, 50,154,
-140, 38,163,249,140,104,214,229, 69,158, 19,234, 76,229,192,170,111,171, 71,233,133,136, 75,202, 65,103,223,102,104,221,194, 21,
- 55,227,139,240,227,133,116,124,115, 38, 21, 23,238,230,129,230,200,144, 83, 10, 60, 76, 81,226, 97,106,126,131,249,179,217, 2,
-238,248,119,222, 41, 89,208,222,191,180,251,255, 78,205, 65, 51,199,135,254, 11, 23, 22,207, 97, 11,184,227,109,155,203,246,125,
-176,224,221, 9, 50,177,152,175,215,233,209,170,165,167,240,237,217,115,166, 80,182, 2,139,159,137, 36,107,230,103, 43, 16,137,
-118, 45,251,244,125,193,134, 95, 30,166,149,235, 81,126,248,154, 50,113,254, 7, 75, 10, 57, 92,225, 54, 89, 51, 63,139,199,254,
- 24,141, 70,232,116, 58,232,245,122, 24, 12, 6,100,166, 63, 24,113,254,151,247, 6,183,108,110, 55, 88, 32, 20,130, 0, 40,213,
-152,144,148,173, 70,240,192, 65,236,206,129,129, 1, 82, 87,191,169,181,105,149,148,164,150,208,132, 45, 59,113,100, 47,251,192,
-175,119,240,195,137, 91, 56,250,219, 29,220,188,120,202, 68,104,227,227,231,127, 73, 93,219,120, 75, 93,219,167, 74,221, 58, 40,
- 31, 47,205,218,213,155,158,153,205,102,145,224,129, 33,231,166,207,122,251,127,234,178,130,220, 93, 91, 62,203,204,203, 74,121,
- 32,224, 81, 38,177,128, 13,149,214,132,239,207,103, 97,220,202,187,184,159,166, 2, 33,164,193, 7,120,211,192,188,241, 83,223,
- 51, 27, 13, 6,248,120, 72,177,119,231, 42,140, 8,238,136, 1,237,109,209,181,181, 4, 98,142, 14, 49,177,113,216,191,247,123,
- 19, 77,179,230, 55,112, 35,190, 80,185, 68, 2,128, 74,165,122,111,225,251,243,243,244, 38, 26, 6, 35, 13, 67,229,235,249,253,
- 95,228,153,181,234,247, 42,183,139,172,182, 29,243,136, 7, 6, 6, 6, 6,134,231, 33,162, 85,181,184, 86, 95, 81,103,215,161,
- 86,171, 73, 30, 59,126, 34, 92,157, 92,164, 35,251,191,198,139,124, 84,140,188,236, 84, 36,196, 71, 67,173, 53,130,103,219, 18,
- 16,186,160,133,151, 39,162,226,142, 26, 54,175, 9, 87,209, 38, 93,114, 93,122, 35, 70,184,186, 39,196, 82,172, 53,171, 61,174,
-199,199, 21,117,222,187,232, 59,188,250,170,212, 97,205,106,143,235, 41,137, 18,150, 88, 72,122, 78,153,252, 10,197,162, 8, 22,
- 46, 92,128,145, 97, 47,224,245, 41,147,168,221,187,191,239, 94,108,225, 94,210,224,126,249,225,199,159,241,149,197, 38,253,205,
-120,149, 78, 44, 17,137,174, 60, 84,149, 7,120,121,136,134,142,121, 45, 43,252,224,174, 13, 0, 38, 91,162, 85,101,176,140, 70,
- 35, 12, 6, 3, 0,152, 1,128,197,170,120, 45, 40,211, 35,183, 88, 7,101,177, 14, 38, 51,141, 49,227, 39,139,110, 69,220,157,
- 12,160,142,241, 90, 52,109, 52, 25,113,248,215,219,200,188,117,136,166, 88,236,146,106,131,225, 33,117,109,227,237,226,226,113,
- 41,108,204, 36, 71,190,176,162, 27,182,172, 92,135,221,219, 87,215, 91, 79, 22, 69, 17,218,108, 42, 54, 25,141,229,173, 90,182,
-202,244,245,239, 40,188,252,191, 51, 35,174,156, 59,172, 50,181,154,100,243, 40, 37, 27,108,174, 0,108,158, 16, 58,131,101, 19,
- 15,149, 9,215,183, 2,160,166,206, 92,176,241,221,247, 62, 98,207,219,252, 59,244, 90, 53,116,154,114,148,150, 20, 65,196, 49,
- 34,230,234, 49, 19, 49, 27,223, 45,207,190,179,181,110, 37, 42, 11, 64, 86,245,146,194,194,194, 11, 87,127,191,116,252,198,213,
-223, 95,119,105,213,153,165, 55,210, 72,136,190, 65,103, 62,140, 56,174,211,149, 94, 0, 0, 10, 40, 0,112,134,185,111, 25, 24,
- 24, 24, 24,158,195,136,214,180,234,101,117, 26,173,212,251,151,187, 2,128,119,151,208, 2,169,144, 99,199, 97, 81, 80,102, 60,
-194,238,181,115, 65,211, 4, 67,223, 92, 3,153,151, 11, 68, 60, 54,116,170, 2, 85,225,163,139,245,141,213, 1, 69, 25, 7,109,
-221,145,233, 53,243,173, 86,242,189,123, 85, 92, 0,216,187, 87,197,125,107, 70,115,249, 87, 59,146,189,186,245,238, 12, 98, 54,
- 35,108,228, 88,140,127,121, 60, 82,114,212,248,249, 82, 26,202, 53,122,139,102,203,137, 28,124, 59, 58,216, 59,190,240,206,107,
- 47, 72, 56,108,138,106,235,169, 96,167,231, 25, 77,108, 54,215,124,252, 86, 73,214,152, 49, 47, 59, 92, 56,121, 96,128,217,193,
-183,163, 38, 63,246,110, 67,122, 58,157,238,137,174, 67, 59,135,150, 39, 7,141, 93,155,145,157, 83, 22,158, 83,164,237, 86,110,
- 52, 65, 89,172, 67,110,177, 14,197,229, 6,184,200,108, 97, 50,234,219,215,165, 71, 8,249, 97,212,216,137,147, 0,176, 40,150,
-233, 59, 85,118,108,124,197,154, 63, 76,214, 11, 35, 95,117,188, 20,249, 8, 9, 17,167,138, 8,109,170,200,226, 78,209, 25,245,
- 31, 87, 16, 54, 5,154,199,161,140,108, 22,139, 54, 24, 84, 70, 39, 39,199, 11, 23, 47,156, 30,174, 53, 37,130,205, 19, 60,126,
-175, 70,111,182,248,138, 81, 38, 92,255, 18, 0, 54,109,222,184,174,231,160, 87,121, 23,111, 39, 67, 99, 4,122, 4,122,227,200,
- 79, 95,235, 8, 49,190, 87,158,125,231, 75, 43, 46, 66,155,230,205,155,207,229,242,249, 3, 68, 98, 89,115, 71, 87, 15,150,193,
-100,134,193,104,134,196,190, 25, 75, 32,181, 27, 68,179,120,151, 77, 6,253, 5, 67,121,222, 38, 0,197,204,125,203,192,192,192,
-192,240,156, 69,181,128,106, 57,180,158, 48, 90, 39, 78,156, 32, 0, 80, 91,255,104,166,178, 16,246, 82, 14, 28,221,188, 48, 97,
-238, 58,252,176, 97, 30,204,102, 35, 8, 1, 76,102,203, 50, 19, 16,194,253,117,214, 91, 94,190, 45,188,216,142, 19, 94, 21,107,
-126,220,171, 22, 77,120, 85,172,105,215,222,190,100,214, 91, 94,201,101, 90,143, 94, 38,179, 25, 87, 98,114, 17,157, 92,130,232,
-148, 82, 72, 69,150,167,249, 98,243,121,111,173, 94,181,146,199, 97, 83, 84, 76,170, 74,149, 81, 96, 82,177,185, 92,131, 88,196,
- 39,122,194,209,165,228,147,130,129,163,166,104,142,239,217, 52, 21,192,236, 58,163, 98,149, 51, 13,171, 34, 89, 85,175,132, 16,
- 66, 1, 52, 77,153,205, 25,249, 90,168, 12, 70, 40,139,254, 48, 90,148,169,238,158, 83,169,107, 27,111,185, 76,122,154,205,102,
- 11, 8, 1,140, 6,211, 75,112,109, 51, 88,149,157, 16, 95,221,100, 93,143,201,194,163, 59,231,148,102,131,122,162, 58, 55,238,
-188,165,251, 78, 81, 32,108, 54,104, 54,139,162, 41, 10, 52,151, 69,244, 32,132,174, 89, 35,181, 21, 70,171,202,108,241,185,236,
- 69,103,247,111,112,122,125,152, 31,126,186, 84,225,249,180,101,121,165,229,153, 86,153, 44,216,219,219, 79,126,255,253,247, 63,
- 25, 49,246, 85,148,104, 41, 40,139, 42,162,129,122, 35, 13,158,196, 1,131,102,125,219, 60, 59,175,180,121,194,205,227,189,242,
-239,236, 45, 49,106, 75, 54, 50,247, 44, 3, 3, 3,195,127,139,250,188,200,115, 20,213,250,115, 68,171,190, 29, 34, 4,120,152,
-154,143, 22,238,142,112,111,209, 26,241, 15,162,254, 88, 7,192,100,182,172, 59,234,216,177,236,140,117,235,228,244,188,121, 37,
- 61, 86,175,246,184,246,214,140,230,138,118,237,237, 75,222,127, 63,173,199,250,245,138,107,191, 94,231,154, 73,101,190,174,170,
-220, 92,132, 88,147, 99,147, 21,212,209,191, 37,251,179,189, 15,211,206,223, 43,203,229,241,120, 70, 23, 91, 33, 37,147,242,217,
-108, 22,151,175, 51,178,116,222, 1,129,236,227, 44, 42,176, 62,149, 42,163, 85,179,235,176, 32,239,209,136,179, 63, 47,104,215,
-127,212, 26,187,204, 60, 13, 74,244,236,199, 93,135,108, 22,133,123, 15, 82, 1, 54, 47,186, 54, 77,185,204,238,204,190, 31,127,
-240, 88,191,122, 57, 12, 38, 51,102,205, 91,140, 41,147, 39,158,129,107,155,193, 30, 94, 62,145,191, 31,255, 78, 60,120,198, 54,
-164,198, 69,228,152,116,165,251,173, 49, 89,143,205, 22, 64,204,132,102, 21, 22,149, 74,117, 38, 8, 81,139,239,211, 25,232, 70,
- 93, 57, 42,141, 9,199,111,228,224,196, 47,251,161,144, 73, 26,165,161, 80, 40,252,250,246,237, 7,138,195,135,222,168,131,222,
- 68, 67, 95,109,140,150,193, 72,195, 72,184, 16,187,118, 64,225,253, 35,126,208,150, 48, 45, 14, 3, 3, 3,195,127,136,231,120,
- 32,124,117,115, 85,119, 68,171, 62, 60,221,157,113, 35, 58, 25,237,125, 91, 66, 33,151,253,159,189,243, 14,143,162,106,219,248,
- 61, 51,219, 75,122,178,105,132, 18, 74, 66,239, 16,122,135, 72, 21, 20, 41, 34, 40,210, 44, 40, 2,138,138, 74,135, 23,105,130,
-136,210, 68,122,239, 85, 8, 85,233, 53, 1, 18, 72, 37, 61,187,105,219,235,204,124,127,108, 2, 1, 82, 54,128,223,171,190,231,
-119, 93,123, 37,179,217,189,115,166,157,185,207,115,158,115, 14,238,199,167,129,161,133,160, 41,192,238,112,221, 12,241, 54,251,
-246, 37, 75, 60,144,146,164,160,127, 90,149, 84,227,195, 9, 53,146,150, 44,241,184,200,219,236,219, 1,140,224,121,192,105,182,
-156,134,139,173,132, 47,224, 57,123,136,191,183,156,185,150, 96,200,165,105,198,226,227, 33,229,124, 60, 36,180,143,155, 88, 40,
- 18, 50,156,131,167,109, 85, 84, 53,204, 60,199,185,178,174,222, 83, 93,135, 44,203,130,162,104,182,200,136, 41, 82,115, 77, 40,
- 52, 51,200, 46,176, 32, 95,103, 67,157, 96, 5, 78, 70,237, 50,178,118,211,150,210,180, 24,161,200,163, 86,141, 42,248,106,246,
- 18,152, 44, 44, 30,164,235, 33,146, 72, 2,252, 3, 26,220, 26,241,193, 52,201,196,213,241, 24,221,213, 7,159,157,143, 79, 55,
-102, 75,167, 85,230,204,178, 44, 11,147,217, 42,202,214,228,123,105,117, 6,119,153, 84, 98,242,243,246,208,148,246, 89,115, 37,
- 35, 90,197,200,165, 2,244,139, 8,128,217, 54, 12, 38,139, 3,127,158,218,243, 34, 50,161,254, 65, 85,160,183,150, 48, 87, 69,
-102,171,164,233, 18, 42,253, 0, 80,161,164,202, 33, 16, 8, 4,194, 63,136, 50, 71, 29,186,100,180,148,114, 41,120, 70,138,243,
-215,227, 17, 94,191, 49, 54, 28,184,130,218,141, 34,144,169,115,128, 7, 93,225,104,195, 98,166,124,105,186, 1,224, 70,255,254,
-242, 42, 3, 7, 6,247,224,121,225,239,171,126,209,166, 1, 64,104, 67,167, 12,199,241,224,121,128,231,156,134,203,245,144,142,
- 32, 37, 41, 83, 91,189, 70,128, 2,119,211,108, 22,133, 68, 68,123, 41,196,140,159,135, 88, 36, 18, 8,192,242,148, 37, 51, 51,
-222, 66, 1,201,174,200, 61,219,117, 40, 87, 6, 30,233,246,250,247,234,228, 71,133,215,234,228, 25,155, 20,218,196,224,121,160,
- 78,176, 2,209,151, 14,179,217,233, 15, 31,152,178, 99,127, 46, 77,139,227,192,216, 28, 28,110, 37, 20,162,192, 96, 71,129,222,
-134,118, 93,250,137,218,117,239,143,243,209, 26,112, 14, 59, 22,174, 57,172, 99,121,251, 16,224,158,189, 18, 59, 77, 95,190, 17,
- 83, 69,157,111,144, 8, 5,130,130,186,181,171, 37,138, 69, 66,135, 86,171, 21, 63,253, 41, 6, 10,153, 24,121,122, 59, 0,216,
- 43,123,245, 20, 26,236, 56,112, 41, 11, 7,247,108,133, 76, 38, 3,255, 2, 87,160, 72, 36,242, 20,138,164,176, 25,156,221,133,
-197, 47,219, 51, 47, 90, 32, 1,104,129, 39,185,103, 9, 4, 2,129,240, 15,162,228, 26,135,125, 74,154, 47,218,165,168, 9,199,
-195,215,199, 27, 82,133, 59,146,178,109,208, 81, 42,228, 27,121,176,172, 51,162, 85, 78,224,169,212,213,189, 15, 28,200, 76,219,
-191, 95,179,238,192,129,204, 18,137,222, 79, 34, 89,143,127,114,188,203,154, 20,207,158, 60,112,244, 76, 97,255,214,126, 94, 52,
-195,152, 68, 66,218, 34, 16, 49, 54,145,128,182,139, 4,180,213,223, 93,200,156, 57,184, 77,204, 83, 56, 83,145,166,217,108, 70,
-247,238,221,209,187,119,111, 12, 24, 48, 0,131, 7, 15, 70, 88, 88, 61, 21,205, 80, 86,158,226, 56, 63,177, 14,181,252, 40, 8,
-204,169, 56,181,237, 63,198,232, 63,246,221, 98, 45,230,126,120,218,114, 62,209,228,121, 46,175,208, 2,179,141, 69,190,222,134,
-124,131, 13, 14,191, 54,216,247,103, 6, 76, 86, 22, 41,215,119,153,212, 89,105,159, 88,114, 30, 38, 85,112, 42,190,120,122,147,
- 79,123,255,189,145,106, 55, 41,253,176, 67,219,150,106, 95, 31,111, 7, 69, 61,137,188, 82, 20, 5,169,187, 10, 94,158,110, 72,
-186,113, 20, 39, 22,118, 51, 1,248,218,149,227, 89, 18,119,185, 0,253, 91, 7,160,223,160, 97,104, 20,209,203, 21, 99,253,156,
-166, 92, 46,151, 21, 71,175, 74, 78,235, 96, 45, 17,213, 98,139,206, 55, 45,144,200, 92, 61,239, 47, 9,209, 36,154, 68,147,104,
- 18,205,191,143,230, 63,153,226, 53, 14,139,127,186, 54, 51,124,177, 1,170, 25,168, 64,237, 96, 5,204, 54, 21,204, 86, 22, 6,
- 51, 11,173,209, 6,173,209,142,164, 44, 35,162, 15,188,124, 9,157, 81, 44,231,212,231,188,115,190, 77,176, 28,239,114,244, 68,
-108,179,206, 94,188,112,222, 91,219,154, 53,181, 78,236, 19, 24,114, 59,201,154, 65, 81,180,137,102, 4,118,111, 55,129,240,254,
-253,219,234,139,231,142,116,148, 58,216,119,140,229,232, 56, 28,142,194,224,224,224,162, 72,212, 19, 11, 89,175,150,108,192, 31,
-135,191, 8,237,212,127,161,223,210,185, 83,140, 52, 35,226, 40,129, 40,154,181,155,182,154,178, 99, 87,161, 28,251, 65,139,164,
-247, 46,223,188, 27,225,233, 29,130,135,233, 6, 24,204, 14,216, 28, 28,188,148, 34,164,221, 57,110, 75,186,127,109,135, 62,227,
-246,134, 23, 56,108, 91,226,238, 69, 87,137,140,236,245, 70, 68, 68, 27,230,219,111,191, 65,120,120, 56, 76, 38, 19,104,154, 70,
- 72,245, 90, 72,138,187,137, 75,135,103,179,198,220,228,159, 1,204, 2,160,174,236, 63,209,104,173, 56,122, 45, 7,135,247,110,
- 7, 35, 20,191,200,233,165,101, 50,153,180, 52,115, 85,210,116, 61,254,176, 80, 44, 45,106, 4,112,228,222, 37, 16, 8, 4,194,
- 63,132,177,207,252, 92,237,146,209, 50,155,205, 73,237,187,247, 3,199,241, 96,121,128, 99,139, 34, 79,220,147,232, 19,107, 55,
- 39,189,108,233, 56,142,189,242,227,234,117,189,155,181,234,196,212,175,170,132, 54, 55, 11,151,254, 56,237, 0,199, 95,116,229,
-251,185,185, 15,244, 50,255,218,111,188,245,230,192,157, 35,223, 27, 95,208,177, 75, 23,133, 74, 21, 96, 73, 75, 79, 51,174,223,
-180,217,126,252,200,254,142, 28, 28, 67,115,115, 31,234,203,211, 41, 44, 44,252,161,180,247, 37, 98,101, 59, 0,161,140,128,178,
-154,212, 15, 42,149, 17,174, 73, 79, 29, 52,111,246,140,228,225, 99, 38,137,107, 6,215, 66, 78, 33,131,164,180, 44,220, 63,183,
-223,146, 30,119,117,175, 54,237,198,104, 23,165, 50, 75,121, 47, 13,192,210, 75,151, 46, 54,136,140,140,236,213,181,107, 87,126,
-236,216,177,224,121,224,212,234, 9,124, 94,210,165, 93,112, 70,177, 18, 94,240,188,164,156,187,120,211,123,112,199, 22, 2, 31,
-183,209, 88,183,253,136, 29, 60,151, 82, 73, 25,255, 42, 85,171, 11,156,221,133,206, 41, 29,158,125, 89,237, 79,242,199, 68, 74,
-127,129, 17,209,254,101,236, 47,129, 64, 32, 16, 8,127, 55, 94, 60, 71, 43,245,158,115, 62,173,191, 26, 93, 86,206,136, 13, 27,
- 54,206,217,184,105, 91, 59,179,213, 26,204, 67,148,202, 58,172,103,245, 44,190,117, 85,195,148,253,240,154,143, 79,157,134,235,
-215,252,248,245,250,117, 63,117, 2,199,214,165,128,100,158,194, 25,169,157, 29, 89,145,201, 42,215, 44,105,116,191,244,120, 99,
-145, 41, 55, 87,191,177,178,223, 53,229,198,102,209,140, 45,228,151,101,179,191,167,105,166, 39,203,114, 66,142,181, 63,100,109,
-230,255,152,212,177, 7,224,114,150, 27,242,202,249, 91, 12,128,152,168,168,168, 14, 81, 81, 81,173, 0,252, 0,231, 26,138,215,
- 94,230,188, 88,114,117,221,166, 78,153,122,106, 50,168,106, 28,199,195,193,114, 41, 34,147,177, 91, 37,101, 66,106,214,172, 37,
-183,217,217,231, 18,224, 75, 38,194, 63, 54, 90, 30, 85,228, 0, 66,136,209, 34, 16, 8, 4,194, 63,132,177,120,126,210, 82,215,
- 34, 90,255, 95,228,231, 39,232,144,143,137, 47,171,147,155,251, 64, 15,224,185,145,123,198,151,212,141, 59,240,254,158, 0, 0,
- 32, 0, 73, 68, 65, 84,126,160,221,141, 7,218,221, 47,250,125, 67, 78,162, 26, 72, 28,249,146,197,112, 37,145,253,124,209,235,
-149,160,209,220, 51, 64,131,214, 47,123, 90,182,108,222,116,127,219,182,237, 66,158,102,132, 28,207,136, 28, 60, 37,116,112,148,
-208,110,231, 96,177,217,237, 54,135,195, 14,214, 97, 3,199,218,121,206,102,135,115,118,120, 2,129, 64, 32, 16,254,201,134,235,
-239, 99,180, 8,255,106, 18,226, 31,198, 69,144,195, 64, 32, 16, 8,132,127,185,201, 42,249, 19,128, 51,247,188,172,145, 3,149,
- 89,204,247, 69, 70, 31,156, 36,154, 47,173, 41, 4, 32, 6,160, 4, 80, 81,151,102, 47, 20,173,215, 72,142, 39,209, 36,154, 68,
-147,104, 18,205,255,162,102, 69,218, 39, 65,248, 75, 13, 24,209, 36,154, 68,147,104, 18, 77,162, 73, 52,255,247, 52,255,201,140,
- 45,229, 5,128,116, 29, 18, 8, 4, 2,225,127, 16, 31,159, 58, 74,224,113, 94,111,133,200,125,235,249, 3,128, 81,115, 47,155,
- 28, 61, 66, 41,148, 92,231,240,169, 28, 45,250, 5, 5,133,180, 64, 60, 85,238,230,115, 79,225,225,147,254, 63,126,112,169,176,
-234,138,143,123,116,172,177, 47, 60, 84, 54,160, 50, 95,148,251,133,253, 26, 80,171,245, 35,133, 42,236, 99, 4, 54,147,189, 76,
- 33, 20,170, 80, 63,101, 72,139, 63,220,130, 27,188,246, 23,236,163,164,126,253,250,109,234,215,175,223, 6,128,228, 85, 8,202,
- 85, 97,195,170,212,142, 56,167,170,217,244,180,194,191,206,155,175,186,192,202,192,218, 62,202,144,230,187,149, 65,141,243,149,
-129,141,181,202, 42,205,207,186,249,214,171, 89,209,247, 66,250,207,171, 59,115,107,244,214,144,254,243,234,150,246,119,175,200,
-229,110,223,109,123, 48,215,167,223,127,148,164, 94,121, 49, 66,218, 13,243, 12,236, 52,217,167,178,223, 11, 14,139,136,169,222,
-160, 67, 78, 80,157,214,209,174,126,167, 74,120,155, 27,213,234,183,203,174, 18,214,230, 26, 57,242,174, 33,245, 11,109, 35,245,
-170,122, 88,226, 85,245,136,196, 59,180,203,203,234, 5, 6, 6,202,234,214,173, 27, 25, 17, 17, 49,174, 91,183,110,159, 54,109,
-218,116,108,181,106,213,122,254, 55, 27,250,114, 85,216,151, 22, 33,165,177, 8, 41,141, 92, 21,246,101,197,245,107,248, 28,138,
-102, 51, 40,154,205, 80,168,194,231,252, 93,206,149,196, 63,172,154, 92, 21,182,196, 45,160,254, 21,153,170, 78,191,202,126,223,
-203,203,171,167,159,159,223,235,197, 47, 47, 47,175,158,228, 14,120, 97, 74, 70,177, 94, 58,162,197, 8, 37,242, 11,195,223,251,
-176,225,130, 25,211,164,203,214,237,195,178,185, 83,238, 90, 12, 5,245,255,142,123,238, 27,218,234, 26, 67, 51, 85, 74,190,199,
-114,108,154, 38,241, 74,139, 87,161, 31, 94, 93, 54,250,235,207, 71,124, 54,236,173,238,213,186,247,253,132,138, 77, 52,237,119,
-221,162,161,201,142,221,123, 67,206,157, 57,189,124,221,186,213,179,212,142,240, 37, 66,137,224, 71,109,106, 76, 65,101,202,224,
-238, 87, 51, 84,160,240, 61,215,126,192,135, 1,215, 79,110,222,192, 90,185, 30, 70, 77,137,213,191, 95, 28,191, 90,181,106,181,
-100, 24,198,231,227,143, 63, 22, 1,192,210,165, 75,107,179, 44,155, 27, 31, 31,127, 21, 47, 48,249,169,211, 96,134,143,248,225,
-251,153, 27, 95,123,173, 55, 50, 52, 6, 44, 92,178,178,243,177, 67, 59, 6, 27,178, 31,236,122, 21,231,196,211,179,134, 59, 68,
-110,119, 62,249,124,150, 42,178,115, 75, 70,111,118,224,216,185,155, 29, 54,175,156,117, 5,168,215, 74,167,185, 87,230,156, 98,
-156,177,112,186,191,146,143,228,140,133, 0, 48,236,185,135,189,210,222,221, 79,198, 70, 6, 74, 4, 55,115,129, 10, 23,125,244,
-172,222,238,184, 80, 34,169, 70,211, 52,104, 10,160,105, 10, 12, 69, 57,215, 9,181,153, 82,210,239,159,239,245,119,184, 79,220,
-170,182,202, 2, 35,240,161,169, 39,229,163,232,162,159, 60,175,205,122,112,193,231, 21,252, 27,143,134,181, 61, 27,180,171,109,
- 88,127, 54, 49, 79, 33,232,248,233, 97,138,167,127,122,116,126,201, 45,151, 12,128, 84,234,117,240,224, 65,191,200,200, 72, 15,
- 85,131, 1,103, 93,249,142,152,209,215, 63,116,232,128, 40, 50,178, 87, 37,174,207,176, 30,160,233, 77, 20, 32,228, 56,126, 41,
-195,241, 59,244,185,113,241, 64,229, 86,159,146,169,194, 71,211,224, 93,174,103, 56, 80,215, 76, 57,177,235, 94,244,224, 10, 36,
-238,221,132, 34,209,167,161, 97,141,154,165, 39, 63,188,102,208,235,150, 56, 44,133,103, 43, 45,100,119, 76, 61,121,254,250,107,
- 2,161,144,138,236,214,154,177, 0,167, 95,230,164,251,251,251,191,190, 98,197,138,154,109,218,180, 1, 0, 56, 28, 14,247,157,
- 59,119, 6,204,158, 61, 91, 17, 23, 23,183,231, 5,101,131,253,252,252,170,138,197,226, 96, 0,176, 90,173,233,106,181,250, 17,
-128, 10, 27,254, 10,255,154,190,224, 49,235,252,185,115, 2, 0,232,208,161,227,156,170,237, 63,242, 98, 68, 74, 83,169,135,195,
-170, 83, 20,196,159,158,116,233,242, 69, 10, 0, 34, 90,183,153, 38,247,173,247,227,127, 51,178, 37, 85,133,183,166,129,207, 34,
- 58,116, 31, 52,100,232, 8,186, 65,157,170,232,217,163,235, 23, 38,224, 96,165,174, 25,129, 64,118,229,202,149, 90, 52, 77, 51,
- 14,135,195, 28, 17, 17,241,232,101,202, 21, 20,214,230, 79, 10,116,136,205, 97, 93,163, 78,184, 54, 7,207, 79, 58,205,120,132,
- 52,251, 26,140, 96, 12,199,113,169,186, 71,215,218,254, 11, 35, 90,207, 31,231,202, 42,209, 2,241,167,195,222,253,160,225,164,
-201, 95, 73, 63, 89, 22,133,195, 43,167,105,254,174, 38, 11, 0, 24,154,169,114,252,196,113,149, 92,204, 0, 0,244,102, 7, 94,
-139,140,172,248,137, 80,189,213, 25,154,162,194,139, 23,180, 97, 29, 54,169, 64, 40, 54, 83, 78,131, 4, 10,128,111, 80,245, 40,
-127,199, 5,249,176,183,186, 87,219,180,237,247,180, 71,105,185,149,174,212, 40, 70,132,136,142, 61,209,189, 71, 47,143, 43,151,
-255,156,181,250,231, 85, 95, 58,108,246, 85,156,157, 91, 98,206,123,152, 81, 97,101, 30, 80,167,185, 88,233,123,108,208,184,217,
- 62,102,218, 27,223,206,253,193,247,220,209, 45,103,211, 83,155,112, 41, 41,169,102,158,162,238,230,231,101,126,106,200,138,143,
-117,245,144, 41,149,202,154, 74,165,178, 73,227,198,141,165, 83,166, 76, 17,118,238,220,249,137,101, 31, 59, 86,116,230,204,153,
-192, 69,139, 22,245,190,125,251,182, 89,175,215,223,210,235,245, 9,168, 68,162,125, 64,128,223, 71,111, 12,236,135,174,131, 62,
- 4,203, 81, 24,251,193, 36, 28, 63,186,103, 60,128, 87, 98,180,236,114,247,217, 99,198, 77,241,139,104,217,148,153,181, 37, 22,
- 50,177, 0,189, 90,132, 83,239,126, 60,221,115,221,242, 89,107,161, 65,167,210, 34, 89,156,177,112,122, 67, 95,235,208,254,109,
- 66,113, 96,171,117, 40,186,125, 14, 90,238, 49, 39,245,192, 87,247, 1,160,102,228,199,110, 18, 86,189, 34,200,147, 81, 73, 88,
-245,138,154,145, 31,159, 76, 56,182, 66, 87, 94, 89,132, 18, 73,181,173, 91,182,212,241,114, 19, 65, 64, 83, 96, 24, 10, 2,134,
-134,217,202, 98,240, 91, 67, 95,217,101, 46, 83,213,233, 77, 3,239, 58, 31,216,248,213,148,243,224, 72,101,206, 9,197,136,124,
- 14, 29,216, 43, 80,121, 72,192, 48, 20, 24, 26, 96,104, 10,201,217, 38,140, 30,253,174,199,203, 26,246,215,218,169, 90, 78, 29,
- 18,222, 43,162,161,119,227,237, 23, 41,143,136,215,134,248,104,204,242, 81,219,246,159, 30,202,119,152,116,153,231,185,239,211,
- 46,252,112,162, 60, 17,139,197,146,221, 43,242, 53,119, 74,160,144,159,220,183,161,163,128,166, 96,103,121, 56, 88, 30,108,209,
-218,168, 84, 81, 11,134,166, 41,240, 28,143, 49, 99, 70,163, 87,228,107, 70,206,193,165,185, 94,201,209,155,142,157,252,195,207,
- 98,231,176,104,197,186, 89,134, 66,245,172,196,251, 62,201,250, 66,205, 36, 83,206, 3,151,215,193,160,193,183, 72, 77,136, 30,
-183,229,208, 37, 52,172, 95, 15, 44,231, 44,103,120, 21, 5,182, 28,190,132,186,225,117,157,229,230,120,132,133, 40,209,178, 69,
- 75, 0,120, 33,163, 37,144,184,125,219,169,207,136,153,125, 7,191, 7,149,159, 31,104,222,222,247,228,225, 45,125,127,253,233,
-251,169, 14,179,118, 81,165,196,120,246,241,115,129,231,184,151,142, 58, 5, 5, 5,249,181,108,249,100, 58, 70,135,195,129, 26,
- 53,106, 32, 61, 61, 61,252, 69,218,105,129,129,129,125,190,251,238, 59, 85,239,222,189,133, 1, 1, 1, 0,128,172,172,172,224,
- 99,199,142, 53,251,238,187,239,114, 50, 51, 51, 15,163,156, 25,125, 88, 59, 45,162, 5, 96,164, 82,185,115, 31, 65,209, 83, 62,
-122,167,177,127, 96,144,165,180,207,171,213, 89,226,207, 63, 60, 77, 9, 4,162,162,207,131,230,121,142, 42, 39, 74,212, 93, 40,
- 20,150,218, 67, 97, 99,220, 35,120,161,199,251, 52, 67, 59, 47, 86,135, 93,157,255,232, 70,189, 74, 68,226, 26, 8,197,162, 85,
-111, 12,121,175,237,155,131, 6, 32,208,207, 3, 39, 47,220,198,248,143, 62,179, 59,108,246, 37, 47, 84,121, 48,140, 32, 39, 39,
- 39,217,203,203, 43,224,229,159,183, 84,232,239,199,143,170, 78,158,138,154,182,120,217,242, 9, 54,171,195,206,241,252,227,117,
-140,101, 50,137,176, 71,223,183,220, 85,181, 34,164,203,191,123, 95,248, 47,140,104,173,126, 37, 70, 75, 44,115,123,235,155,207,
- 63,150,206,222,124, 9,135, 87,142,215, 24,181, 26,191,199, 45, 5,119,207, 27, 6,109, 65,179, 23, 41,161,210, 47,172, 13,197,
- 8,198, 81, 12,163,160,104, 74,204,177, 92,170,195,106,157, 99,202,125,240,210,147, 86,114, 28,143,221,127,230, 84,206, 0,241,
-168,189,105,251, 94,149,191,167, 4,102, 27,139, 33,195, 70, 96,227,198,141,110,126, 30, 98,152,173, 14,124,191,120,177, 78,159,
-124, 88,149,156,154,159,222,189,223,103, 39, 18,146,114,162, 31,101,154,119, 84,182,108, 22, 27, 11,173,209, 1,163,133, 70,157,
- 6, 45,241,253,146,186,210, 71, 41,137,159,109,248,117,237,196,187,119,153,141, 28, 67,207, 52,103,222, 75, 45,245,166, 11,104,
-216,203,221,203,103,235,192,113,115, 61, 31,228, 8,192,195,134,120,119, 41,222, 26, 53,209,189,102,128, 12, 10, 41,227,153,152,
-146, 30, 56,101,234,212, 11, 9, 44,223, 74,171, 78, 72,172,168, 60,213,171, 87, 31,212,183,111, 95,249,228,201,147,133, 33, 33,
- 33,248,117,203,206,106, 29,122, 13,238,151,145,153, 29,194,243, 60,252, 85,170,212, 49,239, 14, 62,120,228,200,145,148,212,212,
- 84,225,194,133, 11, 91,239,221,187,183,126, 86, 86,150,203, 45, 83,150,231, 97,182,176, 96,139, 30,144,234, 66, 75,165,253,105,
-112,112,176, 36, 61, 61,221, 82, 34,202, 64, 61, 9, 20, 82,189,186,117,106, 45,248,229,104, 18,244,102, 22, 10,169, 16, 73,217,
- 70,180,104,218,136, 90,195, 58,154,148, 38, 56,250,173, 62,211,253,149,124,100,255, 54,161, 80,121,201,177,254,199,185, 56,112,
- 49, 49, 50, 91, 79, 97, 5,207,140, 11,148, 8,122, 40,184,204, 21,157, 91,212, 10,232,218,188, 26,174,182,168, 21,112,238,122,
-108,156,108,240,226,143,211,245,194,147,249,199, 38,234, 74,175,120,104,120,187,137,176,238,120, 10,228, 82, 1, 20, 82, 1, 20,
- 18,231, 79,154,166, 94,174, 85, 27, 88, 47,132,225,216,209, 12, 35, 24, 61,244,173,193, 65,195,135, 14,230,193,208,216,185,251,
-224,128,205,155, 55,101,218,109,214,181, 44,205,172, 43,235,250,121,234,128,210,128,202, 67,140,169,107,163,225, 46, 19,194, 77,
- 46,132,187, 92,136,174,141,253,192,208, 47, 92, 68,175,241, 3,106,246, 30, 63,176,122,151,240,170,202, 58,183,226, 11,239,142,
-158,115,109,217,153,130, 46,159,254,184,180,190,143,190,192, 42,248,118,202, 24, 65, 90, 70, 70,151,157, 7,207,118,101,173,239,
-197, 58,108,134,175,212,183,119,150, 26, 21, 78,139,189,216, 44, 56,226, 77,169, 77,111,191,115, 43, 54,173, 86,190, 69,130,152,
-100, 45, 20, 82, 1,148,197,199, 86, 42,128, 66, 42,132, 82, 42, 64, 70, 90, 18,242, 12,204,133,116, 31,186, 11,206, 94,116, 84,
-166,224,102, 27,139,155,137,122, 84, 15,111,138,192,192, 32, 88,123,191, 93,253,114,212,238,253, 87,206,238,155,111,204,186,255,
-149,171, 58, 91, 14, 93,194,180, 73,227,174, 83,192,141,162,135,116,179,111, 23,172,108, 62,107,218,135, 79,189, 55,101,230,242,
-230, 47, 30,201,114,155,222,117,224, 7, 51, 59,244, 24, 8, 93, 94, 54,254, 60,177, 3,189,250,190,129,183,223,251, 4,158,158,
-190,223, 47,153,243,249, 45,135, 69, 27,245, 92,157, 27, 80,183,125,163,134,245, 54, 7, 7, 5,133,112,156,115,149, 15,158, 7,
-244,186, 66,124,254,233, 24,112, 60,143, 38,205, 90,117,149,118,232,193,243, 69,171,129,104,114, 53,134,216,251,119,187,155,115,
- 98, 47,187,124, 44,205,102,187, 90,173,198,205,155, 55, 17, 23, 23,135,152,152, 24,228,230,230,194,195,195, 67,111, 48, 24, 42,
- 21,188,111,220,184,241,240,168,168, 40,169,151,151,215,227, 55,173, 86, 43,220,220,220, 48,124,248,112, 97,207,158, 61,131,251,
-244,233, 51, 50, 58, 58,122, 11, 0,109,169,229,201,123,152,225,230, 31,254,115,167,206,157, 38, 0,128,204, 61, 48,113,197,175,
- 7, 99,202,109,208,122, 4, 85,107,219,182, 93, 45,240, 60, 40,240, 63, 24,115,227,178,202,137, 18, 41, 46, 93,186, 84,147, 97,
- 24,193,147,103, 16,135,159,214,111,175,251,251,249, 59,131, 22,124,191, 72,234,174,144, 64, 93,104,197,251,111, 15,116,249, 25,
- 44,243, 15,239,221,182,109,199,253,179,102,126, 35, 80, 42, 20, 56,113, 57, 1, 31,127, 58,213,156,153, 28,189,136,231,132, 43,
-141,234,184,156,151,124, 84,242,120, 5,212,169,162,132, 91,255, 94,210,241,239,244,151, 90,237, 44, 10, 12,118, 88,108, 44, 88,
-142, 71,161,193,142,187,143,116,240,117,175,252, 82,110, 60,207,183, 4,224, 7, 64, 77, 81,212,213,146,219,197, 13,186, 98,111,
-252,204,182,166,232,249,224, 3,192, 10,231, 72,253,199,151, 79,209,118, 89,239, 23,127,255, 46,128,122, 69,154, 44,128, 43, 20,
- 69,229,151, 97,182,158,139,114, 9, 14, 29, 58,196,247,237,219,247,113,141,255,236,246,179, 72, 68,194, 32,133,135, 31,120,254,
- 30, 74, 46, 96,172, 10, 8,206, 93,180,100,153,247, 71, 31,140, 75,209, 22,228, 85, 43,122,251,164, 43, 15, 11, 1,197, 44,233,
-212, 46,162,231,132, 15, 62, 64,120,205, 42, 34,150,101,249,232,184, 68,251,134,117,235, 71,157,187, 40, 94,166, 77,139,158, 94,
- 34, 4, 89,169, 97,159, 44,199,166, 61, 27,193, 98, 57,246,217,214,237,115,154, 20, 5,120, 42,197,248,249,104, 18,120, 30,160,
-192,195, 67, 33,196,182, 51,105, 72,188,190, 71,219,183,137,214, 48,124,193,140,174, 93,122, 79,140,186, 27,111,222,145,147, 99,
- 62, 14, 32,171, 60,205,210, 43,116, 14, 22, 27, 11,187,195,129, 93, 7, 15, 34,178,107,107,180,109,219, 26, 29, 59,180, 21, 92,
-187,126,251,189, 15, 38,140, 9,193,147,209, 29,143, 53,165,254,181, 91, 42, 61,124,119, 12,154,176,208,237, 78,154, 3, 2, 6,
- 8, 13,144,193,219, 77, 4,171,131, 66,178,218, 86,116,231,120,226,227, 41, 51,189,167,125, 54,225,136, 86, 45,110, 8,220,179,
-149,183,239, 70,163, 81, 60, 98,196, 8,161,221,110,183, 13,127,255,147,158, 89, 89,234, 1, 63,253,240, 31,137, 74,229, 15,163,
-217,129,235, 49, 15,235,205,154, 53, 51,244,224,177, 51,251,102, 76, 29,191, 63, 50, 50,210, 99,251,246,237, 92, 69,199,243,169,
- 22, 98,182,230,199,245,155,119,109, 92,186,104, 30, 98, 83,242,177,238,151,149,224, 89,199,207, 21, 28,170,146,154,252,136, 17,
- 35,100,251,246,237,171,146,150,150,166, 53, 26,141,234,167,226, 17, 52, 37,200,206, 51,194,215, 77, 12,145,128,134,191,151, 20,
- 42, 15, 9,132, 12, 64, 83, 20, 91,154,230,186, 29,135,231,112,198, 66, 28,216,106, 29,186,254,199,185,120,239,163,175, 17,173,
- 17, 31,163,229, 30,115, 62, 28, 58,104,154,159,140,141, 12,242,164, 85, 93,155, 87,135, 66, 42,194,151, 19, 71,160,213,245,100,
- 85,122, 1,247,181,218,196, 52,157,121,236,241, 98,221, 39,159, 14,142, 56, 35, 88,110,114, 33,142,109,254, 62,199, 80,168, 46,
- 44,238,146,179, 90,204, 41, 46, 94,198, 39, 75,105,217, 78,107,218,168,193,220, 9, 99, 71,211,237,218,180,226,105, 90, 8,141,
-206, 74,241, 60,240,233,199,227,241,225,248, 49, 1,169, 25, 57,223,174, 92,249,243,244,168,223,249,217, 6,245,253, 25,229,105,
-210,148, 51, 10,164,148, 10,160,148, 57,141,139, 82, 42,128,217,202,130,162,192,120, 86,109, 86, 72, 57, 35,185, 25,121, 41,101,
-182,192,159,210,244,174,218,224,212,239,137,110,117,243,119,228, 95, 76,202,136,153,115,253,118,246, 21, 0,121, 33, 29, 61, 71,
-218, 28, 60,244,102, 7,146,178,141,112,216,120,234,189,215,170,161,198,155, 84,248,188,245, 55, 54, 30,189, 13,247, 18,149,254,
- 83,154,233,151,118,153,125, 26, 14, 28,178,116,249, 47, 87, 23,205,253,154,209, 20, 90,193,241, 60,164, 98, 6, 50,177,160,232,
-197,192,100, 40,196,202, 85,107,178, 28,160, 6,225,236, 89, 71,101,174, 79,112,252,219, 3,123,119,220, 70, 1, 98,138, 22,165,
- 5, 85,171, 94,173, 91,191, 81,210,110,253, 71,128,117, 88,167, 93, 63,207,159, 54,230,196,158,114, 69,179, 97,253,122,160,128,
- 27,134,156,184,241, 0,160, 80,133,253, 92, 55,188,110,243,103,223,171, 93, 59,188,185, 43,231,253,113,164, 84,234,246,145,151,
-183,223,215,225, 13,154,170,178,243, 45,148,155, 79, 21, 36, 61,184,137,173,171,190,221,196,153,173, 51, 79, 29,222, 49,119,217,
-186,189,111,117,139, 28,136,245, 63,253,231,203,220,204,199, 70,235,100,137,104,213,219, 27,214,174, 14, 17,138, 37,176, 59, 56,
-216, 89,222,249,211,193, 34, 47, 47, 31,118, 7, 7,169,220, 13, 14,142,130,157,229, 96,119,112,176, 88, 29,138,241, 35,250,124,
- 96, 6, 46,151, 86,206,224,186,157,142,139, 36,146,106, 60,156,107,215,242, 60,143,164, 44, 19, 29, 24, 24,184, 5, 0, 36, 18,
- 9, 36, 18, 9, 56,142,195,245, 88,245, 71,190,225, 97, 19, 80,100,240, 88,155, 53,165, 32,249,143, 94,101,237,123, 64, 64, 64,
-191,103, 77,150,217,108,134, 94,175,199,249,139, 87, 61,214,110,220, 21,153,148,146, 86,147,227, 61, 44,110,170,154,189,116, 57,
- 9,253,202, 58,158,186,236,216, 15,220, 35,198,208,147, 63, 28, 89,123,249,134, 67, 87, 30, 30,159, 83,110,158, 86,141,110, 95,
- 88, 39,143,123,163,197,130, 31,214, 61,200,255,227,231, 73, 21,157, 35,129, 64, 32, 84,171,213,143,239,239, 21,107,182,182,184,
- 17,155,254,250,178,165,203,164,215, 19,116,184,147,148,129,145,221,171, 58, 91, 56, 46,156,119,133,127, 77,223,208, 90,181,182,
-172,252, 97,129,224, 65,134, 25, 63,238,185,130,168,253, 63,159,207,202,185, 28,137,236, 76,211,139,212, 33,175,192,104,149,169,
-121,250,182, 6,122,179, 3, 22,171, 3,118,142,135,214,104, 71, 78,129, 21, 90,163, 13,122,147, 3, 35,123, 84, 45,245,123, 21,
-248, 17, 63,138,162, 14,241, 60,223,151,231,249,238, 0,196,197,219,206,103, 54,117,168,200,144, 61,181, 61,109,218,180,175,230,
-207,159, 31, 83,252,217,226,247,139, 63, 91,222,251, 37,190,239,243,229,151, 95, 54, 92,176, 96,193,188, 54,109,218,108,251,243,
-207, 63, 19, 1,228,187,218,125, 40, 40,185, 51,135, 14, 29,170,232, 64,215,180,217,109, 18,119,153, 16,161, 53,170,226,221,175,
-214,251,254,182, 96,116,142, 84, 44, 96,142, 30, 61,234,157,107, 85,130,166, 25,151,155, 40, 74,191, 58,109, 69, 34,241,225,197,
-139, 23, 99,104,191, 14,178, 71, 26,187,254,246, 35, 83,182,193, 10,135,202, 47, 76, 60,103,222, 2,229,130,133,223,127,120,232,
- 0, 87,160,207,190,251,125,233, 93,124, 45,174, 49, 84,137, 28, 44,138, 2,207,177,105,249,201, 87, 91, 0,192,203,228, 98,233,
-205,118, 48, 69,185, 53, 20, 5, 24,205, 14, 48, 12,149, 83, 16,187,227,238,240,217,115,186,110,218,246,123, 6, 79,123,234, 12,
-134, 36, 57,156,107, 14, 86, 26,179,149,133,197,206, 34,230,214,117,116,140,168,143,182, 45,234,194,104,102, 97,180, 56, 80,163,
- 86, 56, 0,248,150,122,226, 24, 58,145,103,237,102,158,103,221,250,182,244,131,202, 83,140, 64, 47, 9, 36, 98, 1,236, 14,192,
-100,229, 96,182,178, 72,206, 49, 65,103,146,161, 81,167,193,161, 62,129,215, 44, 89,201,178,125,121,143,174, 13, 42,215,156,178,
- 44, 54,108,217, 85, 59, 35, 35,123,192,145,125,155, 37,106,173, 29,183,147, 13,200, 41,176, 0,140, 31,190,155,247,163,228,139,
- 73, 99, 95,223,176,117,119, 74,183, 14,173, 83, 42,187,207, 70,117,236,166, 29, 59,119,253,220,183,239,235,178,152,203, 71,240,
-224,230,169,185,134,156, 74,229,103,209, 77,154, 52,113,140, 29, 59, 86, 55,111,222,188,144, 3, 7, 14,212, 80,171,213, 55, 1,
-216, 61, 61, 61,235,134,213,174,118,235,196,177,163,193,125, 94, 31, 44, 76,211,152,224, 33, 23,161,154, 74,142,139,231,143,219,
-197, 98, 97,169,249, 38, 69,221,131,195,208,237,115, 28,184,152, 24, 25,147, 43, 61, 51,102,244,200,148, 19,231, 98,115, 87,108,
- 60,241,159, 96,165,253,166,148, 83,175,184,214,162, 86,192,180,143, 71, 96,254,242, 77, 56,123, 61, 54,199, 64, 7,206,205,180,
- 56,126, 47, 59,148, 14, 8, 24, 10,110, 50, 33, 12, 90,117, 97,252,141, 99, 97,175, 40, 76, 61,242,196,190, 77,116,158,206,142,
- 84,141,153,202,200,211,129,229,120,120,202, 69,112,112, 60, 10,242, 52,212,230, 77, 27,113,245,234, 69, 26, 12,253, 62,128, 25,
-229, 30, 80,202,217, 85,168,148, 10,157, 17, 33,153,243,167,157,229, 16, 94,187, 22, 86,175, 88,226,238,171,242, 71,251,142,174,
-231, 70,187,249, 84,107,178,237,215, 21, 56,243,231,141,206,103,151,253,216, 82, 25,228,183,156,162,216, 69,224, 97,182,216, 88,
- 20, 22,228, 67,108, 77, 69,171, 96, 53,188,229, 44,146,181,129,136,206,122,160,172,168,194,207,141,222,123,147,226, 95,159,190,
-235, 96,212,252, 94, 61, 58, 35, 58, 89, 11,153, 88, 0,169,152,129, 84,204, 64, 72,177, 88,178,234,103,123,126,161,174,111,110,
-204,126,205, 11, 92,159, 39,139, 90,191, 78,115,199,234,253, 54, 45,159,254,219,152,207, 23,246,138, 28, 56,138,138,190,122,250,
- 43, 35,112,202,181,134, 30,239,210,123, 28,231,250, 51, 78,234,230,251,195,196, 47,230, 76,236,217,119, 48, 24, 70, 0,187,221,
-142,221,219, 55,225,215, 31,191,187,111,213,231,142, 2,192, 89,115,152,177, 59, 54,173, 26,252,249,183, 75,168,134, 77, 90,181,
- 62,157,249,252,114,180, 28, 67,253,242,206,232,113, 67,252,253,253,221,158, 68,180,120,132,133,215, 71,239,254,111,224,248,254,
-189,184, 27,115, 27, 28,239, 52, 76, 28,199,163, 32, 63, 55,203, 97,183,110, 40,179,199, 67, 42,173,182,254,215,141,117,104,154,
-122,188,128,252,164, 15,222,181,142,255,244,171,246,189,123,118,138, 17, 51,208, 38, 63,202,244,188,120,227, 94, 35, 78,168, 12,
- 25, 61,101,137,200,108, 97, 81,104,180,227,200,186,178,189,142,212,171,106,155,234,205,123,143, 30,255,205,106,137,132,161,109,
- 13,194, 66, 18, 59, 69, 52, 72,173, 26,228,171,155,181,224,199, 86, 23, 46,223,232,253,214,240,209,210,145,117,155, 83, 65, 62,
- 50,183,119,135, 15,108,204, 58,108,239, 24,243, 82,203,156, 95, 80, 40,247, 42,168, 90,163,182,241, 73,196, 40,108, 15,197, 35,
-244, 41,231, 65, 33,209,148, 29, 55, 8, 0, 2,131,170,154,133, 18,119, 93, 37, 34, 48, 60, 0, 44, 95,179,181,197,173,184,140,
- 49, 75,151, 46,147, 95, 79,208,225,102, 66, 33, 36, 34, 26, 54, 59, 7,202,197,160, 54,199, 51,227,190,254,114,154,123,190,129,
-197,153,219,106,196, 92, 59,205, 91,245,230,225,114,135,251, 32,168,220,222, 1, 80, 11, 64, 60, 69,241,191, 24,178, 3,246, 3,
-103, 29,149,189,238, 57,206,217, 94,118,247,171, 25,202, 10, 36,189,133, 98, 69, 27,138,226, 27, 80, 60,188, 0, 62, 61,175,232,
-153,234,170, 83, 51,100,199, 97,225,188,111,241,195,218,189,200,200, 53,195,131, 77,197,254,117,115, 48,121,254, 22,152, 44,101,
-103, 53, 84,228, 71, 74, 51, 70,207, 26,174,226,223,139, 63, 55,127,254,252,190,207,156,155,190,101,156,179,231, 62, 87,252,253,
- 5, 11, 22,204, 43,241,119,163,171, 38,235,177,209, 42,222,169, 10,204, 86,152, 95, 96,181, 63,247,239,219,227,149,175,183, 65,
- 42, 98, 80,181, 70,109,204, 88,177,223,239,181, 22,190,208,216, 60,176,117,245,162, 60,179, 81,183,221,165,202, 66, 21,222, 90,
-166, 84, 28,217,179,123, 47,106, 86, 85,137, 54,159,207, 75,186,145,104,122, 28,234,213,170, 83,196, 53,220,141,130, 65, 3, 7,
-202, 79, 69,157,254, 84, 15,148,106,180, 24,138,169,178,102,227,110,149,155, 76, 8,138, 2,116, 38, 7,198,188,243,198,203, 63,
-198,120,142, 25, 61,106, 36,168, 34,147,165,205,205,194, 87, 95,124, 96, 86,216, 31,220,125,148,252, 40,189,123,191,201,167,180,
-122,202, 60,100,196, 7, 87,239,198,205,207, 55, 26, 95,108,145, 31,139,149,133,197,198, 33, 33, 33, 30,147, 70,246,128,144,161,
-193, 48,156, 51, 89,218, 81,246,197,168,207,136,203, 67,128,232,205, 77,139, 63, 90, 19,228,175,242, 81, 42,100,188, 82, 46,161,
- 26,212,173, 35,138,136,104, 43,174, 17,222, 88,116,254,158, 9,143,212, 38, 36,102, 20, 66,226,223, 84, 48,180,235,107,216,180,
-108, 74,231,188, 71,215,104, 60,159,164,248, 20,191,159,185,212,111,237,170,165,146,236, 2, 27,238, 63,210, 35, 43,223,140,204,
-124, 11,178,242,204, 80,202,132,232,216,127,172,228,240,254, 95,250,117,235,208,122,249,139,236,119, 98, 98,210,225,228,244,204,
-193,141,155,181,194,166,223,126,237,224,233, 89,195,189,160, 32, 73,235,234,217,153, 51,103,142,120,193,130, 5,130, 21, 43, 86,
-104, 35, 34, 34, 2,190,252,242,203, 94, 57, 57, 57, 87,170, 87,175, 30,126,124,207,134,168,166, 29, 7,180, 4,103,243,235,208,
-169,139, 72,194, 9,112,226,208, 33,219,142,237,155,115, 77, 38,221,248,114, 13,135,220, 99, 78,182,158,130, 95,112,112,140, 82,
-204,246, 16,208, 5,113,249,199, 38,110,204, 7,246,212,140,252,248,228,233,107,177,113, 45,174, 39,171,162,174, 63,204,201, 51,
-218,194, 18,142, 77, 46,183,226,101, 40, 10, 66,134,134,155, 76, 0,186,168, 86, 85, 6, 53,126, 8,138,242, 43,142,156, 82,160,
-138,126, 2, 20,133,140,252, 71, 55, 93,200,217,160,120,142, 7, 98,211, 12,208,155,157,161,249, 42,190,114,168,179,211,240,211,
-242, 13,184,113,237, 42,122,190,214, 31, 43,215,108,198,152,119, 6,155, 43,106,253,208,116, 81, 68,171, 68, 52, 75, 41, 19, 0,
-160, 80, 96,176, 99,247,133, 84,212, 10,165, 93,126, 48, 0,128,155, 82,142, 66,157, 9,180,200, 13,241,215,143,200,143,158,190,
-252,229,244,217, 75,167,230,103,222,126,244,240,206,121,132,251, 22, 34, 52,216,134,152, 44,119, 92,203,173,129,240,218, 53, 65,
-139,174,186,164,173,137,105,180,112, 63,189,187,111,139,166,245,219, 84, 83,121,194,100,101,139,162, 90, 12,126, 93,191, 17,201,
- 73,105,163,115,239,238,191,241, 42, 28,173, 33, 39, 81, 45, 81,213,254,240,206,229, 83,137, 3,135,127,136,192,224,170, 77, 10,
- 30,221,116, 57,109,193,149,247, 88, 23,141,150, 72,238,249,229,164,175,255, 51,177,103,159, 55,113,233,252, 41,220,140,137, 71,
-235,214, 45,241,218,235, 67,161,211,230,213,221,185,113, 89, 15,135, 81,119, 92, 32,113, 76,108,213,182, 43,197,177, 44, 30,220,
-143,142, 47, 77,203,148, 25,123,243, 98,102,172,251, 83,221, 83,190,117,155, 40, 61,188,111, 90,108, 44,210,211,211,240,199,159,
-103,154,153, 50, 99,111, 86,230,120, 73, 68, 12, 78,220,200,129,173,104, 13,211,142,157,122, 88, 69,180,165,195,220,165,235, 35,
- 50, 51, 50,105,133,187, 47,231, 29, 92, 79, 20, 40,177, 89,110, 37, 20,138,108,118, 14, 53,131, 20,229,106,250, 5,213,158, 55,
-101,202,164,122,140, 72, 6,157,193, 98,205,204, 72, 15, 88,189,245,180,254,222,253, 59,193, 85, 84, 30,238,255, 89,246,139, 72,
-107,166,144, 83,104, 65,158, 78, 75, 13, 31,247,121,208,218, 31,231,191, 93,158,209, 42, 37, 93, 36,244,240,137,243,117,189,220,
- 68,148,222,236,224,114,181, 54,118,248,235, 47, 55,232,178,200,100,141, 93,186,100,153,252, 70,130, 14,183, 18, 10, 33, 21, 49,
- 16,139,104, 88,237, 28, 92,188,157,232, 0, 85,192,248,182, 45, 26,225,248, 77, 13, 24,134,134, 73,151,111, 20, 32, 55,174, 69,
-231,158,242,230,173, 34,208,165,115, 39, 60,140,139,173,122,232,192,238,110, 23,255, 56,155,229,176,133,125,100, 80,199,237,173,
- 84, 96,193,104,100,236,226,128,119, 3,131,171,183, 27, 52,244, 93,143,106, 85,131, 41,149,175, 15, 28,188, 0, 99,223,121,195,
-229, 59,223,105,204,129, 5,179,191,132,197, 98,133,159,167, 24, 60, 15,172, 95, 62, 3, 86,171, 21, 65, 62, 18, 20, 26,202, 94,
- 77,174, 34, 63, 82, 86, 20,170, 82,185, 39, 37,204, 88,121,239, 83, 20,117,104,218,180,105, 95, 1,224,167, 77,155,246, 85,241,
-246,252,249,243, 77, 0, 50, 42,232, 58, 92,253,148,209, 42,222,185,178,239,110, 81,184,175, 79,224,197, 19,199,143,121,236,187,
-197,225,210,222,107,232,211, 58, 16, 34, 1, 13,185, 71, 16,110, 37, 21,226,240,158, 85, 5,251,183,253,146,110,177, 88,190,175,
-184,175,185,118, 11,165, 92,113,252,183, 77,219, 57, 95, 31, 31,250,167, 19,234,132, 92,157,227,113,151, 86,220,229, 3,220,181,
-227,171, 3,121, 80,199,164, 82,105,109,171,213,234, 85,209,137, 93,127, 34,165, 40,137,151,122, 21,117, 43, 40,134, 97, 55,109,
-222, 4, 95,119, 49, 44,118, 14,211,166,126, 98, 26,217, 83, 89, 48,252,173,161, 93,187,244,158, 24, 37, 84,212, 57,213,182, 89,
- 29,190,105,211,166, 5, 12,195,184,148, 74,161, 82,169,102,208, 52, 61, 76, 44, 22,187, 89,173, 86,157,149, 51,203, 13,102, 43,
-204, 54,192,104, 52, 67, 40,114,154, 69, 33, 67,193,100,182,194,104,178,150,127, 99,100, 69, 95, 0, 16,166, 45, 17, 83, 58,117,
-175,166,120,203,206,253,159,188,249,214,144,233,193, 77, 94, 87, 38,101, 22, 66, 68,217,208,178, 94, 32, 78, 31,219,203,167, 37,
-199, 77,170,200,100, 1, 64,142, 58, 47,196,207,207, 31, 55, 18,245, 72,207, 53, 33,171,200,100,101,230, 91,160, 51,233,208,184,
- 90, 16, 10, 10, 11, 67, 94,248,248, 2,123,143, 31, 63, 62,184,247,128, 33,152, 56,117,102,251,117,171, 22,221, 86,136,133,239,
- 25,178, 31,156,113,197,104, 69, 71, 71,231,125,241,197, 23,181,214,172, 89, 67,191,253,246,219,166, 70,141, 26, 73, 71,140, 24,
-209,126,227,198,141, 82,185, 92,106,186,117,254,192,244,247, 63,158, 54, 96,245, 15,115,154,228,231,231, 83, 14,187,253,168, 45,
- 63,127,154,190, 2, 51,151,122,224,171,251,223, 37,216, 70,245,232,224,119,192, 91, 78, 55,144,240,214,161,168, 55, 99, 59,238,
-205,176, 37, 28, 91,161,147, 13, 94,252,113, 70, 1,247,181,153, 86,205,173,200,100, 1, 0,205, 80,176, 58, 88,184,201,132,160,
-105,186,216,196, 7,254,186,253,168,220,207, 67, 12, 33, 67, 67,192, 80,208, 26,237,208,104,109,248,240, 93, 87,103, 8,225, 57,
- 7,203,195,100,117,192, 88,212, 58,212,105, 53,248,114,234,103,120,173,223, 64,188, 63,254, 51,228,155,128,107,137, 58,216,236,
-246, 10,111, 10,154,162, 97,180, 56,240, 94,207,106,200,211,219, 96, 48, 57, 96,117,112,144,139, 5, 16, 10,104, 40,164, 2,184,
-203,133, 0,207,139,138, 43, 19,161, 80,104,182,219,237,155,202,105,209,163, 70,136, 63, 76,118, 26,173,134, 44, 66,247, 54, 97,
-136,185,176, 91,112,246,210,157,208, 79,167,126,141, 79,198,244,195,174,251,181,224,173,170, 6,165, 66, 6, 59, 79, 3,224, 93,
- 76,216,155,193,209,182,129,195,126, 94,179, 62,118,214,183,211,164, 5, 6, 10, 18, 17,131,168, 83, 39,113,241,242,181, 31, 52,
-119,247,111,194, 43, 68,200,211,254,238,238,238,144,138, 25, 88,109, 22,171,235,169, 11, 60,120,160,153, 66, 21,246,115, 81,139,
-191, 25,203,161,148,247, 42, 54, 90, 2,169,251,180,143,166,206,154,215,179,207,155, 56,113,104, 23,118,238,218,206,182,137, 28,
-205,108,254,117, 21,218,119,239,143,246, 61,135,224,232,222,141,159, 25, 56,170,254,216,137,211,103,119,236,218, 27, 39, 14,239,
- 66,118, 86,218, 98, 87,203,203, 8,169,137, 93,123,244,131,217,202,162, 67,183,190, 56,118,112,239,199, 40, 26,100,225,250, 67,
-236,153,250, 25,180,227,179, 73, 19,133, 57, 5, 86,161, 90,107, 69,154,218,136,164,108, 35,246,111, 91,199,187, 94, 95, 88, 91,
-118,108, 92, 69, 56,118, 97, 84,106, 72,149, 64,139,208, 98,146,197,197, 39,212,125,255,221,145,194,208,218,117,233,156, 66, 11,
-212,133, 22,104, 10, 45,208,155, 29,168, 93,165, 14,109,119, 80,109, 42,123,158,125, 61,196,194,149, 7, 19,225,174, 16,162,109,
-221, 23, 31,104,203,113,220, 19,147,181,212,105,178,110, 39, 22, 66, 34, 98, 32, 17,209,144,136, 24, 56, 88,222,165,134,139, 76,
- 21,214,251,195,143, 62, 8,178, 58,128,220, 66, 43, 4, 12, 5,149,175,151,162,101,147, 97, 88,191,232, 99, 0,192,152, 47,126,
-194,251,239,141, 64,189, 6,141, 80,144,159, 31, 48,236,205,222, 75, 1,236,117,181,172, 71, 78,156,169,122,226,220,141, 47, 62,
-156,242,157,242,173,126, 93,152,155, 9,133,200,204,179, 32, 62, 78, 87,169,200, 27, 0, 56, 88, 14, 60,120,108,216,126, 8, 50,
-177, 0,234, 66, 27,120,158,199,156, 21, 59,224, 38, 19, 34, 51,223,217,221, 95, 30,229,250,145,114, 34, 82,149,136, 54,246,133,
- 51,151,203,207,213,136,214,252,249,243, 99,230,207,159, 95,106,132,172,132,201,122,177, 69,165, 69, 34, 69, 93,119, 31,223, 75,
- 39,142, 29,113,219,123,139,197,233, 91,185,120,179, 67, 21,232,243, 30,225,251,169,111,229, 81,224,173, 52,195, 20, 88, 76,198,
- 61, 38,147, 97, 46, 0, 91,185, 23, 77, 64, 88, 51,133, 84,121,114,229,234,223, 28,190, 42, 21, 54,157,207, 75,203, 55, 56,236,
- 79,186,173,236,212,181,227,171, 67, 29,156, 61,210,156,253,240,106, 69, 45,113,142,135,104,254,170,253, 0,120,112, 28, 7,158,
-227, 32,148, 42, 21,190, 53, 35,178,139, 42, 58,169,128,166,204, 37,107, 0,158,115,164,105, 18,203, 15,131, 82, 0, 60,228, 66,
-108, 63,155, 14, 0,217,140,238,250,189,225,111, 57,187, 11,205, 86,169,182, 65,173, 90,124,203,150, 45, 11,100, 50,151,166,191,
- 98,252,253,253,175, 76,159, 62,189,238,251,239,191, 47, 17,139,197,112, 56, 28,222,191,172, 94,205,173,158, 59, 6,131, 62, 94,
- 9,145, 88, 2,147,217, 6,161, 80,128,252, 66, 61, 10,180, 70,232,140,246,202, 95, 65, 9, 9, 86, 53,176,112,223, 94,241,192,
- 94,202,198,173,196,180, 8,205,195, 3,113,250,248, 62,254,210,177,245, 99, 76, 57,113,191,185,120, 33, 66,111,182, 35, 35,215,
-140,244, 92, 51,178,242,205,200,202,179, 32, 43,223, 12,138,162, 96,182, 58, 94,234,193,101,200,137,221,185,233,183,181,253, 45,
- 54, 12,237,216,115, 32, 62,251,110,101,181, 77, 63, 47, 56,153,200,211,237, 92, 76,180,101, 99, 98, 98,146,223,125,247,221, 38,
- 91,183,110,101, 26, 54,108,104,186,119,239,158,188,200, 68,218,148, 74,185,108,221,143,243,143,183,106,213,106, 91,122,220,253,
-168,162,254,244, 10, 43,246,106,157, 70, 73,100,182, 27, 99,171, 42,218,246,170, 25, 32, 71, 85,133,174, 87, 93,229,173,239,115,
-187,126, 50, 79, 29,245, 67, 78,166,197,241,187,218,196, 52, 77,215, 11, 93,202,193,179, 91,204, 41,131,222, 28, 10,134,162, 97,
- 51, 27, 83,138, 47, 46,149,135, 24, 51, 54,223,135, 82, 42,132,155, 76, 0,165, 76,136,246,245,189, 81,137,250,140,183,179, 28,
-140, 22, 22, 38,139, 3,102,171, 3,190, 33, 94, 88,179,105, 39, 30,229,152,176,255,170, 6,177, 41, 58,212,169,162, 0,207, 87,
- 92, 77,114,172,221,208,239,141,183,221, 24,154, 2, 67, 83,116,253,186, 97,200,211,219, 32, 18,208, 16, 73,101, 80, 72, 4,112,
-151, 9, 33, 18, 9,145,147,147, 3,139,197,130,170, 85,171, 74,203,183,130, 60,220,148, 50,212, 9, 13,130,205,238,192,145,115,
-119, 49,119,210, 32,244,232,216, 2,148, 80,137,251,150,102,112,243,118, 3, 71,211,176, 57, 56, 88,109, 44, 0,218, 92,150, 94,
- 72, 72, 72, 87,133, 66, 45,234, 42,153, 0, 0, 32, 0, 73, 68, 65, 84,161, 48, 26,141,186, 71,143, 30,157,201,138,221,251,136,
-101, 6,140, 61,118, 34,106, 83,223,215,122,224,198,237, 24,236,218,123,224,188,198,167,112, 74,241,119, 26, 52,104, 16,225,235,
-235,171,204,205,205,213, 70, 71, 71, 95,121,209,118, 1, 79,211,159,182,105,223, 25,250,130, 28,100,167, 38,185,220,138,174, 87,
-205, 13,223,204, 95,217, 60, 60, 44,188, 57,203, 59,141, 87,253,170,110,152,252,221,242,230,181,234,132, 53, 47, 30, 16, 82,175,
-106,249,211,178, 9,228,110, 61,223,121,255,179,249,253,223, 28,133,168, 19, 7,176,100,238,212, 77, 10, 15,191,122,222, 94, 30,
- 77, 27, 70,244,196,249,147, 7, 32,117, 11,128,151, 79, 64,251,183,223,251,168,251,155,111,143,195,197,243, 39,241,195,130,175,
- 54,178, 22,221, 22, 87,202,170, 80,133,250, 53,105,214,106,184,155,183, 63, 10, 10,117,112,243, 82,161, 94,227,150,195,239,222,
-178,124, 97,200, 73, 84,191,176,233,224,121, 88,108, 60,242,245, 54,164,170, 77, 72,206,114, 26, 45,142,171, 68, 78, 16,203, 81,
- 74,169, 64,224,109,127, 88,245,206,201, 40,190, 90,136, 63,181,112,246, 84,198, 6, 41,212, 5, 78,147,165,214, 90,161, 46,180,
- 66,111,182,195, 91, 33, 0,199,114,149,110,117,231,235,109,112,147, 11,225, 33, 23,185, 28,101, 44,141, 85,191,110, 15,191, 21,
-151,241,250,146, 37,203,228, 55, 19, 75,152, 44,161, 51,154, 37, 17, 49, 96, 57, 14,112,225,142, 23, 10,132, 19, 7,244,238,142,
- 84,141,201, 57,106,153,166, 80,167, 81, 43,248,202, 56,116, 27, 50, 13, 0,208,175,183, 51,181, 45, 49,211,128,131,151,212,192,
-211,137,221,229,215,197, 38, 19,179,122,243,225, 79,119,238,216,230, 97,102, 5,248,229,104, 50,140, 22, 7,164, 34, 6, 18, 17,
- 3,153,136,121, 42, 31,187, 98,163,229,204,185,123,164,177,195,104, 54, 67,107,178,131, 7,112,229,161, 30, 38,171, 3,133, 6,
- 59, 34,234,122,189, 92, 32,132,162, 14,243, 60,223,231, 89, 67,244,172, 89, 42, 17,145, 42, 77,227,106, 73,141,226,207,151,101,
-228, 74,230,108, 1,168,212, 8, 46,193,179,206,177,228,182, 72,225, 85,207,195,205,227,210,177,163,135,148,123,111,113, 56,115,
-219,105,178,236, 38, 13, 22,127, 49, 44, 77, 91,160,233, 2, 32,193,213,127, 38,247,173,215, 88, 42,150, 68,253,103,217, 47, 54,
-149,127, 48,183,231, 82, 65, 78,161,145,125,202, 77,176, 22, 11,205,115,188,200,156,253,208,165, 62, 4,154,166,108,223,125, 60,
- 16, 28,207, 99,198,178,157,152, 55,101, 8,148,178,183,229, 20, 69,201, 13,102, 7, 38,205, 92,139,197,223,140,118,147, 75, 4,
-160, 40,103, 78,212, 59, 67, 7,186,118, 1,154, 29,136,191,188, 85,175, 75, 60,116,175,100,119, 97,235,246,175, 93,107,221,186,
-117,129,151,151, 23,100, 50,217,147, 72, 69, 25,248,251,251,127,243,221,119,223,133,143, 31, 63,254,241,100,159, 2,129, 0, 31,
-126,240, 1,205,178, 60,142, 30, 93, 15,191,234,205,112,224,247, 75,136,236,218, 18,122,163, 25,121, 5, 58,112, 96, 94,248, 66,
-212, 21,104,162,178,146,239,180,106,215,165, 31,206, 28,223,199, 95, 58,186,110, 76,101,230,232,241,242,246, 74,189,126, 39,190,
- 30, 69,121, 59, 35, 90, 69, 38,203,106,231, 80,205, 95,142,212,228,120,120,122,120,164,186,170, 39,243, 11, 31, 64,209,252,120,
- 10,252,122, 67,246,131,157, 0,120, 67,230,189, 97, 59,183,172,190, 29, 19,125,115,110,223,225, 19, 5, 61,223,252,128,249,121,
-254, 71, 95, 1,112,117,226, 61, 91,108,108,236,221,209,163, 71,183,189,120,241, 34, 11,192, 72, 81,148,157, 97, 24,185,213,106,
- 21,117,233,210,165,240,254,253,251,103, 81,122,210,226, 83,180,127,119,167, 47, 37,209,189, 38,230,108,195,170,185,233,122,116,
-233,208, 6,109, 26,132, 32,181, 67, 27, 0,152,152,162, 87,134,155,107,173,221,110,119,200,142,252,252,235,193,121, 99,134,116,
-159,180, 73, 48, 99, 73,230,161, 25,229, 38,162,166,222, 59,219,171, 52, 27, 47, 96,104,184,201,132, 80,202, 4,112,147, 9,225,
- 38, 21,194,238,224, 43,211,114,228,237, 14,206, 25,209,178, 58,160, 55, 57, 16,117, 51, 27, 89,133, 86, 20,232,108, 48,217, 88,
-240,224,157,173, 81, 23,106,115,245,195, 63, 60,139,159,164,158, 85,155, 21,174, 94,177,200,125,247,133,180,199, 35,250, 60,228,
- 98,184,201,157,163,177,207,157, 59, 7, 31,159,138, 91,251, 28,199, 97,215,177, 43, 88,178, 33, 10,199,214,127, 14,169,136, 65,
-227, 1, 51, 49,234,245,214,224,120, 14,241,177, 49,217,117,234, 55,241,167,105, 25,104,138,130,197,206, 1,224,203, 60,158, 86,
-171,213,231,209,163, 71,218,218,181,107, 7, 4, 5, 5,189,201, 48, 12, 15,221, 77,203,190,109,121,198, 83,135,182,200, 13, 38,
- 11, 43,119, 20,174,175,157,105,234,131,218,181, 65, 81, 20,239,238,238, 46,138,138,138,210, 55,106,212,200,239, 5,111, 37, 90,
-166, 10,251,225,253, 9,159,190, 89,171,102, 77,236,220,178, 30, 60, 79,237,118,245,203,155, 15, 94,196,236, 47,159, 30, 97, 56,
-249,187,229,205, 23,207,156,248,212,123, 19,190, 92, 82,238,168, 67,153, 68, 57,101,208,176,177,184,118,229, 79,124, 63,115,242,
- 54,139, 62,111,148,221, 97, 31,156,151,153,184, 45,180,126,107,240, 54, 29, 78,236, 88,132, 33, 35,198, 72,122,246,125, 19, 23,
-207,159,196,188,175, 38,108, 54, 22,228,188, 11, 23,147,156, 57, 94, 56,190, 75,175,215,133, 38,139, 13,203, 23,126,139,113, 83,
-230, 34,162,107, 63, 97,244,205, 75,227, 1,204,114, 57, 29,194,198,162, 75, 35, 95,167,121,182,115, 56,144,200, 8, 74,187, 2,
- 5, 12, 69, 55,173,233, 9,147,213, 1,109, 5,141, 74,129, 72,152, 85, 80,168,173,254,227,188, 79, 25,131,217, 1,117,161, 21,
- 57,133, 22,104, 10,158, 24, 44, 77,161, 5,234, 66, 43,132, 2, 10,113, 9, 41,160,133,130, 74,231,231,229,235,237,104, 21,230,
-229,188, 71, 95,176,119,196, 46,112,111,125,236,236,173, 65, 75,150, 44,149,222, 74,210,225,118,162,182, 40,146,197, 64, 34,164,
- 33, 46,250,157,229,156,185,145,229,225,238, 87, 51,116,228, 59,111,119,115, 87,202,144,241, 32, 7, 2,198, 57, 69,140,135, 42,
- 4, 30, 18, 51, 62,154, 48, 22,190, 62,158,120,164,177,224,135,189,113,184,125,247, 33, 56, 83,229,118,123,249, 47,219, 34,223,
-255,112,178, 39, 45, 20, 99,227,241, 36,103, 57, 25, 22,247, 47, 29, 52,103,196,223, 49,232,181,185, 60,120,214,197, 28,100,138,
-119,176,206,203,109,222,140,105,216,182,225, 39, 28,191,158,243,248, 10,188,176,123, 49, 62,253,114, 14, 52, 90, 43, 74,187, 46,
-203,243, 35, 0,212, 37, 34, 81,207,109,151, 48, 71,165,109, 83, 69,219,214, 50, 52,172,207,152, 43,235, 51,239, 91,159,209, 43,
-109,238,191,213, 21,118, 29, 62,103,138, 60,253, 26,202,165,138, 63,143, 30, 61,168,216,119,155,127,108,178,108, 70, 13, 63,119,
- 98,191, 52,109,129,186,103,165, 76,150, 95,157,134, 18,185,228,236,244, 57, 63, 88,252,131,171, 59,142,220,212,230,234,204,172,
-227,249, 28, 4, 5,171,240,240, 51, 11,196,146, 37, 66,147,245, 91,141,230,158,161,162,200, 19,199,243, 56,116, 57, 11, 60,239,
-108, 34,237, 56,151,142,162,150, 57, 88,206,217,173,242,251,205, 28, 8,138,242, 80, 92, 13,127,175,250,229, 39,109,159, 70,133,
-134,225,243,102, 60,238, 46,140,104,226,140,100,185,187,187,195,211,211, 19, 74,165, 18, 21,117, 29, 82, 20,245,206,251,239,191,
-255, 92,235, 63, 39, 39, 7,221,187,117,193,138,159,214,160, 73,183,145,248,253,143,227,176,217, 57, 52,174, 95, 19,213,131,188,
-144,154,173,123,161, 27, 93,225, 31,254, 97,171, 46,175,127,213,190,107, 63, 68, 29,219,195, 95, 58,246,235,216,202, 78,132,216,
-167,123,219,131,179,103,207, 8,157, 62,247, 71,137,155, 84,128,123,122, 43,104,138, 66, 53,127, 57,124, 20, 52,206,236,219,104,
- 30,210,175,173,203,147,227,133,132, 4,111, 90,188, 98,181, 98,241,130,153, 93,174, 93,167,162,244, 25,113,121, 0, 96,204,142,
- 93,120, 31,184, 91,229,207, 19, 71,154,116, 26, 8,255,160,154, 61, 18,179,239,187,108, 54, 0, 24, 19, 18, 18, 18,167, 79,159,
- 30,190, 96,193, 2,158, 97, 24, 14,128,100,217,178,101,198, 7, 15, 30,220,132,115,104, 46, 42,122,216,116,235,209, 96,146, 82,
-204, 70,120,203,233, 6, 53, 3,228,104,211,192,217, 43, 58,164, 79,123,132, 84,173,138,132, 44, 99,211, 60, 35, 39,212, 91,153,
-154, 43,127,185,125,181,134, 47, 51,198, 97,178,222, 5,176,191,178,231,135,194,147, 4,249,226,104,150,155, 76, 8,206,121,173,
- 84,202,104, 89,108, 44, 76, 22, 22, 38,171, 3, 6, 43, 11,163,149, 5,199, 59,239, 9,138,162, 96,115,112,112,169,217,252,204,
-181,239,238,237,139,154, 53, 40,184,203,157,101,115, 47,154,238,129, 2,224,227,227, 3,149, 74,229, 82, 84,212,106,115,222,226,
- 86, 59,247,184, 91,223,106,115,128,231,121,196,197,197,126,158,156,152, 56,160,118,157,218, 29,235, 55,110,226, 45,151,208, 0,
- 80,166,209, 50, 26,141,172,155,155,155,202,219,219,155, 78, 79, 79,127,108,158,107, 55,237,226,216,187,103, 55, 6, 13, 26,168,
-191,119,229,214,227, 33,238, 38,147,137,106,215,174,157,123, 72, 72, 8,109,177, 88,180,149, 61, 77, 10,191,176,215,189,124,188,
-231,190,243,238,184,176, 46,221, 35,113,250,212, 9,236,223,179,245, 55,163, 58,238,132,171, 34,225,225,117,159, 27,117, 88,171,
- 78,216,115,163, 14,171,135,214, 41,215,104,213,111,220,178, 53, 79, 9,112,252,208, 14,222, 76,219, 38, 0,224, 88,179,110,199,
-246, 85,223,204, 26, 54,254,203, 90,189,251, 15,195, 59, 35, 70, 65, 32, 96,112,230,247,131, 88, 60,243,179,195,250,194,156,145,
-174,164, 9, 56, 67,111,245, 68,193,178,144, 79,170,214,106,136,235,151,206, 35, 62, 46, 58,230,214,213,139, 13,106, 55,138,128,
- 95, 80,181, 79, 82,124,153, 5,184,119,207, 86,145,140,213,108, 78, 25, 53,114, 4, 74,142, 58,108,211, 44,220,135,122,246, 6,
- 0, 96,212,229,216,214, 45,154,244,160,120,212, 33,103,179,166,148,165, 91,152,175,222,117,230,143,203, 83, 6,244,137,164, 53,
- 90,171, 51,130, 85,104, 45,122, 89,160, 41,254, 93,107, 65,157, 32, 37, 98, 99,174,115,230, 66,205,238, 74,222,151,230, 81,131,
-123,221, 45,190,118, 57,142, 7, 5,152, 43,221, 45, 37,116, 31,187,240,251, 37,210, 91,137,122,220, 78,210, 58,187, 10,133,140,
-211, 96, 9,233,199,166,203, 57,154,189,130,232, 16,197,204,123,111,228, 80,104,180, 54,112, 28, 32, 96,232,162,151, 8,143,116,
- 20, 82,117, 70,104,242,213, 72, 76, 78, 65, 65, 86, 60,104,154,134,111, 80,152,203, 51, 73,179,188, 56,208,104,229, 27,189,217,
-167,163, 96,207,159,153,144, 75, 4,176,232,178,113,116,251, 34,181, 69,175,157,107, 50,234,247,184, 50,159,227,147, 20, 4, 74,
-173,213,155,253, 37, 66, 6, 59, 55,252,136,193,163, 38, 60, 85,251,126,254,245,108,128,166,144,151,175, 3, 69, 81,234,202,213,
- 75,212,213,242,182, 95, 48, 50,246,210, 26,165,152,173,231, 27, 10,101,183, 70,249,163, 39,142, 29, 84, 92, 72,150,224, 74,108,
-102,145,201, 82,115,115, 62,238,147,166, 43,204,235, 5, 32,174,114,237, 66,186,215,144,247,166,196,212, 12,171,111, 57, 29,173,
- 79, 42, 48,216,203,204,115,104,243,230,244,152,107,135, 87,244, 46,180, 39,124,160, 8,172,207,114, 14,199, 66,147, 58,110,102,
- 25, 93,135,226,153, 63,236,124,220,109,248,197,130,141,206,223, 89, 22, 44,207,129,231,128,143,190, 89, 5, 7,199,130, 99, 89,
-112, 44, 15, 59,203,203, 43, 42,174, 42,168,250,158,252,251, 59,234, 14,159,245,124,119,161,167,167, 39,124,124,124,224,227,227,
- 3,119,119,247, 10,141,150, 80, 40, 84, 10, 4, 79, 31,234,148,148, 20, 36, 39, 39,195,221,221, 29, 60,103,135,213, 14, 52,140,
-232,137, 59,241,209, 56,121,225, 38,120,142,133, 66, 89,249, 85, 94, 20,254,225, 31,180,236, 60,224,199,174,253, 71,227,247, 61,
-191,240, 87,207, 29, 28,103,202,137, 91,235,114,132,158,101, 41,187,221,142, 62, 61, 59,167,220,136,121,120,236,235, 41,227, 35,
-219,246, 29, 39,105, 19, 30, 12,179,149, 69, 90,114, 60,206,236,251,213, 28, 22, 26,120,188, 91,135,214, 41,118,187, 29, 44,203,
- 86,248, 32, 55, 91,109, 26, 70, 40, 83, 12, 29, 58, 92,120,245,202,149,221, 10,191, 58, 59, 89,138,190, 69,241, 92, 99,138,231,
- 7, 53,110, 92, 15, 54, 59, 7,163, 81,155, 95,217,125,214,233,116,137,235,215,175, 15, 29, 57,114,164,188,126,253,250,194,248,
-248,120, 44, 94,188, 56, 87,167,211, 37,186,170,113,226, 92,236, 50, 1,149,255,160, 56,162,245,168,125, 27, 12,237,219, 30,219,
- 14, 95,192,153,243, 23,145,162, 87,222,212, 59, 4,251, 82, 83, 50, 44, 13,188,181,187,251,183,169,206,236,220,144,191, 59,166,
-243,180,183,120, 94,114, 66,115,118,134,193,245,155, 27,208,153,236,112,151, 59,231,123, 42,142,108, 49, 20,229,178, 35,162,128,
-196,243, 23,175, 55,108, 81,167, 62,110, 36, 22, 34,167,192, 2,147,197, 1,142,227,193,129,135,143,155, 24, 82, 17,141, 71,201,
-137,224,120, 91, 82, 37, 31, 21,234, 78, 29, 59, 9, 0, 10, 20,197, 11,132, 2, 1,120, 56,231, 87,148,201,100,122,149, 74,229,
- 82, 68,203,230,112, 96, 80,100,107, 68,180,108,140, 1,227,156,115,102,158,250,109, 26,188,148, 66,108,219,180, 22,169,231,150,
-109, 10,109, 51,254, 68,244,157,152, 55, 98,110,252, 57,252,181,230,178,166, 1,130, 12, 81, 89, 97, 82,131,193,176, 27,128, 88,
- 36, 18, 69,118,236,216,209,123,247,238,221, 5,190,190,190,156, 88, 36, 82,247,239,215,151, 19,138, 68,121,197,159,253,227,143,
- 63,132,227,198,141,115,203,207,207,127,148,157,157,125, 17,128,189,252,134, 96,120,119,208,216, 10,138,146, 42,101,242,148, 26,
- 53,106, 6,181,140,104,237,241,250,160,193,144,136, 37,248,253,196, 49, 44, 95,186, 96,135, 62,243,222,123,149, 57,146,175,106,
-212, 97,218,163,164, 68,163,201,210,168, 97,139,206,212,249, 19,251, 38,218,224,187,148,145,216, 22,117, 31, 52,161, 86, 98,134,
- 30,203,231,127, 14, 47, 15, 5,146,226,239,155, 30,220,187,179,202,110,214,126,238,178,201, 2, 32,207,101,223,104, 51, 34,210,
-203, 98, 99,113, 46,234,176,153,115,112,145, 23,207, 30,137,175, 18,214, 82,218,176,101, 55, 47,205,254,181,131,140,192,182,138,
-116,210,239, 63, 31,193,229,173, 5, 73,167,162, 78,122,248, 87,107,192, 80,160, 96,179,152,161, 78,184,234, 48,102,223,215,106,
-211,163, 93, 26,133,155,155,138,111,190,252,238, 63, 31,180,108,209, 66,193, 67,250, 84, 4,171,216, 96,105,180, 86,248,186,137,
- 97,210,170,241,224,234, 49,179, 81,205,148, 59,223,153,195,106,144,107,114,178,197, 79,210, 25,226, 34,202,251,188, 38, 39, 91,
-236,176, 26,228, 21, 63,234, 24,184, 43,196,184,147,148,254, 56,241, 93, 34,116,230,102,137,133,204,227, 60,173,226,186,160, 2,
- 58,139,164,158, 72,207, 53,131, 2, 15,142,117,192, 97,183, 66,167,213, 34, 61, 35, 11,217, 89,217,208,233, 10, 32, 87,122,161,
- 97,211, 86,112, 83, 72,113,235,204, 14,240, 60,239,210,188,134,118, 74, 24,222, 50,162,131, 36, 58,217,153,139, 37, 21,242, 56,
-184,117, 65,174, 94,155,211, 65,159,249,224, 65,101,235, 98, 7,203,158,188,125,247, 65,131, 42,129, 53,168,155,241,133,216,180,
-102, 5,172, 69,145, 77,187,157, 69,244, 35, 3, 50,243,140,120,148,112,143,231, 88,246, 36,254, 71, 16,148, 29, 0,132,160,113,
-195,122,232,249,246,235,248,233,167, 85, 72, 72, 76,230,230, 78,236,253, 72,175, 43,120,173, 18, 38,171, 59,138,230,218, 48,102,
-199, 46, 52,121,181, 76, 59,112, 35,143, 54, 89,249,114, 19,124,164,126,213,208,225,189,197,199, 77,186, 60, 49,107, 49, 10, 14,
-110,122,111,107,105,154, 78, 7, 13,235,220,201, 67,160,148, 9, 64, 81, 20,138,187, 11, 87,206, 30, 11,185,196,217,183,108,178,
- 56,240,246,164, 37,216,180,228, 51,240, 0,134, 13,190, 96, 44,171,156,112,174, 93,248, 81, 32,174, 84, 73, 73,206, 73,239,222,
-111,242, 41,179, 77, 98,233, 59,112,228,181, 22, 45, 90, 20,200,100, 50,200,100, 50,184,187,187,195,203,203, 11,158,158,158, 21,
-238,187,221,110,215, 91,173, 86, 31,177, 88, 12,142,227,144,148,148,132,164,164, 36, 20, 22, 22, 66,173, 86,195,160,215, 58,174,
-156,218, 41,104,216,166, 55,130,106, 54, 66,181, 58, 77, 32,100, 40, 8, 4, 52,206, 28, 88, 83, 86, 57, 75, 55, 89,157,250,175,
-236, 54,224,125,252,190,103, 53,127,245,220,193,241,166,156,184, 53,174,158,163,162,238,158, 91,131, 6, 13,106, 52,110,220, 56,
-209,119, 83,198, 29, 63,124,226, 76,220,206, 67,171,251,229,231, 23,132,240, 60, 15, 79, 15,143,212, 33,253,218, 30,236,210,174,
-101,202,169, 83,167,184,173, 91,183, 90, 40,138,186, 83,158,166,179,146,202,249,237,212,201,168, 25, 29, 58,117,198,218, 13, 91,
- 59,197,220,189,215, 41, 62,254, 1, 66,170,213, 68,141,208, 58, 48, 82, 94,136, 58,123, 30,250,130,156,223, 92, 41,231, 51, 81,
- 45, 42, 63, 63,255,207, 33, 67,134,244,188,112,225, 2, 61,100,200, 16,163, 70,163,249,163, 68, 20,139,175, 72,243,226,207, 3,
-213, 0,126,171,214,105,212,142,116, 91,193, 39, 0, 22, 84,173, 86, 21,103,206, 95,196,197, 11,151, 87,105,228, 85,103,190,247,
-246,187, 99,171,247,103,222,239,223,166, 58,163,242,146, 99,203,234,197,204,129,139,201, 75,146,115,217,181, 11,206,206,152,237,
-202, 57,122,252,224,208,217,208,174,158, 55,236, 44, 15,142,119, 86,184,110, 82, 97, 89, 21,239,115,154, 2,171,228,189,241,227,
-198,197, 55,108,220,244,211,183,223, 29, 47,106, 90, 51, 4, 87, 30, 22, 0, 20, 5,239, 0, 5, 50, 51, 51,113,110,215,106, 71,
-126,250,253, 85, 12,195,205,170,196,241, 68,126,202,205,218, 37, 54,199,106, 52, 26,156, 57,115, 6,197, 6,203,207,207,175, 44,
-163,245,148,102,110,118,198, 31,179,191,255,165,221,152,119, 6,162,111,231, 6, 56,123, 53, 30,214,162,249,154,138,135,146, 39,
- 94,252, 89,252,201,144,154,214, 15, 6,133,105, 77,118,113,242, 55, 73,133,231,224, 92,131,149, 43,163,156,214,188,188,188, 3,
-177,177,177,237,155, 52,105, 82,253,200,145, 35,121, 49,151,143, 79, 44, 89,136,201,147, 39, 43,127,250,233, 39, 57,207,243,127,
- 88,173,214, 4,151,246,157,198,150,235,215,174,249,216,236, 28,206, 95,190, 85,175, 91,187,166,224,120,224,234,213,171, 88,187,
-110,173,249,206,237,155,139, 12,217, 1,179,202, 49, 47,165, 30, 79,246,229, 70, 29, 62,214,204, 76, 79, 94,244,251,225, 93,155,
- 90,118,234,135,225, 31,205,154,117,230,240,214, 25,205, 59,244,165,235,181,236,137,235, 23,163,112,242,200,177,255,216,244,121,
- 51, 80,113,238, 72,169,229,148,200,228, 31,215,111,222, 9,143, 82,146,145,244, 32,250, 55,115,222,195,140,148,120,230,183,140,
-180,148,241,161, 13,218,225,194,241,109, 19,203, 49, 90,229, 94,243, 33,126,178,213, 71, 14, 29, 24,154,150,246,115,128,193,100,
-150,240, 60,111,150,136, 5, 89, 74, 90,183, 93,235,114, 57,239,217,212, 25,213, 7, 13,126,123,252,225,229,203,151, 10,253, 61,
-229,200,202, 55, 67,107,178, 65,103,180,129,166, 40,212, 14, 82,192,168,203,195,217, 93,223,219,173,250,252, 33, 64,188,173, 44,
- 77,133, 42,124, 78,254,195,168,143, 38, 79, 56, 13,177, 71, 72, 80,141,174, 95,150, 27,173,211,165,223,236, 55,121,194,193,112,
-158,231,187, 41, 84,225, 58, 67, 78,236,244,178,246,157,162,156,247,247,240, 46, 33,176, 57,156,243,143, 57, 56,128,229,184,162,
- 40, 31,192, 63,238,207,167, 42,216,119,138,219,126,248, 15,100,100, 23,192,100,181,195, 98,117,192,102,103, 65, 51, 12, 60,189,
- 60, 81,167, 70, 51,120,120,186, 35, 59, 43, 3, 23, 79, 29, 64,220,237,179,127, 80, 60,102,154,212, 15, 78,185,114,142, 68, 50,
-207,240,192,160, 0, 58, 83,107,133, 76,204,224,230,217, 35, 54,187,213,178,200, 69,147,245,156,102, 65,110,222,146, 79,167, 76,
- 29,246,235,250, 13, 1,141, 66,221,145,166, 49, 33, 77,109,134,206,108, 47, 50, 98, 28, 44,122, 13,110, 71,109,200, 98,205,186,
- 37,248, 31,161, 76,163,229,176,153,117,187,143, 93,241,153, 54,227,123,230, 97,124,130,125,206, 39,125,210, 76,122,109,239, 74,
- 71,178, 74,240,235,135,161,219,254,138,157,120,174,187,144,231,192,241, 60, 14, 94,206,122,220, 93,200, 21,101, 94,222,136, 47,
-127, 25,193,146,107, 23,118,238, 61,241,247,219,177,186,205, 38, 83,182,199,253,135,139,242, 1,128, 97,152,199,175,226,220, 44,
-179,217,108,173,160, 11,101,227,154, 53,107,190, 24, 63,126,188, 36, 53, 53, 21,241,241,241, 40, 40, 40,128, 84, 42,197,177, 99,
-199,236,224, 28,139,110, 95,216,155, 20,123,253,196,183,225, 45,122, 86,105,212,166, 55,228,114, 5, 4,188,235,201,152,114, 85,
-216,208, 22,157,250,255,216,237,245, 49, 56,185,119, 13,127,245,236,129, 9, 38,117,220,234,202, 30,203,130,130,130, 24, 0, 15,
- 22, 45, 90,212,116,237,218,181,161, 83,166, 76, 73,216,248,227,140,229, 0,144,155,155, 11, 0,184,113,227, 6, 63, 97,194, 4,
-139,217,108, 78,204,207,207,191,142, 10, 6, 64, 0,128, 73, 45,159,183,118,229,130,134,169,233,153, 3,107, 54,108, 5,191,208,
- 86, 8,168,221, 26,249, 58, 27,174, 60,204, 64,194,189, 83,184,119,126,215, 17,163,210, 49, 3,149,156,223,184, 73,147, 38, 33,
- 52, 77,215,208,235,245, 1,245,235,215,111,162, 80, 40,110, 52,105,210,164,153, 64, 32, 72,187,118,237, 90,114,101,180, 82,206,
-110,176, 84,235, 52,234,135, 20,157, 91,151,132, 44, 99,179, 20,157,219, 13,163,196,227, 51,117,212, 15,150, 95,153,224, 37,188,
- 77, 19,179,115,131,118,247,150,213,139,153,183,199, 78,102,163, 11,189, 62, 17,200,196,191, 87, 46, 92, 77,103,126, 48,114,192,
-147,233, 29,138, 34, 89, 69,191,187, 20,166, 47, 44,188, 93, 8,224,139,219,119,133, 63, 70,127, 50,110,118,227,150,237, 70,116,
-124,109, 8,237, 16, 41,113,124,239,207,124,226,237,168,157, 2,158,253,218,228,194,106, 0, 21,118, 7, 89,173,174,152,172,231,
-203,152,170,232,188,115,235,186, 81,187,247,238,153,255,122,255, 1, 62, 43,191,121, 11,223,255,178, 15, 10,153, 4, 60,199,225,
-173, 46, 33,111,126,251,126,221,126, 33,254,210,224,221,167,211,206,125,180, 52,250, 11,163,209, 22,231, 66, 36,134,215,104, 52,
-231,149, 74,165,186,125,251,246, 17, 18,137,132,210,104, 52, 2,149, 74,229,240,240,240,176,166,165,165, 25, 45, 22,203,110, 0,
-149,154,118,220,102,231,144,148,109,198,254, 61,187,113,235,242, 41,220,187, 23,171,187,119,247,222, 10, 74,192, 47, 53,100, 63,
-200, 3, 42,221,192, 7, 87,234,168, 67,190,210,163, 14, 89,139,110,203,198, 85,115,186, 26,205,150, 81, 77,218,246, 65,245,122,
-237,104,155,157,197,157,171,167,113,122,215,210,239,109,250,188,105, 47,115,142,131,170,132,214,225, 25, 49,254, 60,115, 24, 60,
-199,173, 2, 0,158,227, 86,221,184,112,100,124,235,222,239,195, 91, 85,189, 73,193,163, 27, 20, 94, 96,246,112,145,128, 54, 28,
-221,253,235,222,164,164, 36,220,191,127, 31, 15, 31, 62, 68, 94, 94, 30,182,108, 73,170,212,249, 49,230, 39,255, 30,119,151,238,
-245,198, 91,195, 15,190, 57,244, 29,105,104,157, 70,116,120, 21, 47,248, 40, 5,136,125,152,140,184,107,183,185,216, 43, 71,204,
- 54,109,206,235,166,252,228, 50,141,159,220,183,158, 63,192, 78, 43, 94,187,176, 77,155,118,225, 83,231,206,143,240,241, 83,149,
- 90,143,231,170,115,196,159,127,116, 32,252,226,165, 63, 93, 90,235,144, 99,217,220,177,163,134,112,140,115,161, 80, 60,142, 83,
- 23, 29, 61,103, 99,202,249, 62,207, 57, 42,140,224,191, 59,176, 3, 28, 28, 7,131,201, 6,173,193,130, 66,157, 25,153, 57,185,
-184,117,251, 54,206, 30, 60,128,248,216, 91,137,118,171,245, 4, 77, 83,187, 76,217,113,103, 43,215,211, 36, 8,245,241,246, 70,
- 98,158, 30, 82,177, 0,201,113,215, 44, 6,109,225,230, 23,189,142, 76,185, 15, 50,115, 24,170,231,144, 33, 67,143,117,237,213,
-223,163,101,219,238,114, 95,119, 79,136, 4, 60, 30, 36,101,224,250, 31,199, 12, 9,183,206,105,237, 86,125,228,171, 88,245,229,
-111, 78,197,163, 14,109, 22, 67,191, 97, 3, 58,237, 97, 24,129,152,227, 28, 22,155,213,242,198,203,152,172,191, 10,158,103,211,
- 70, 13, 27,248, 84,219,192,193,241,178, 97,131,143,155, 74,182, 21,236, 44, 47, 31, 54,248, 15,163,179, 2, 41, 59,177, 47, 48,
-208,187, 79,241,218,133, 41, 41,185, 87,243,242, 44,167, 1,164,153,205,230, 23, 46, 99,118,118,246,236,185,115,231,246, 53, 26,
-141,117, 59,119,238, 44,113,119,119, 71,110,110, 46, 78,156, 56, 97, 63,116,232,208,221,156,156,156,111,129, 28,135, 9,205,126,
-187,109,222, 59, 50,246,218,137,111,235,182,232, 85,165, 81,219,222,174, 87,102, 18,217,152,174,253, 71, 83, 39,247,173,225,175,
-156,217,247,129, 73,253,224,151,151, 56,172, 54,179,217,124,217,108, 54, 71,127,253,245,215, 45,253,253,253,253,191,253,246, 91,
-169, 86,171, 21,174, 92,185,210,172,209,104,178,180, 90,237, 69,148,147, 79,243, 60, 55,236,133,233, 24,116,116,247,154, 46,252,
-238, 53, 61, 60,125,131,123,122,248, 85,169, 85,160, 78, 79, 44, 84,103,156, 0,112,178,104,162,200, 74,209,180,105,211,154, 20,
- 69, 13, 1,208, 80,161, 80,212, 86, 42,149, 18,158,231,235, 82, 20, 21,195,113,220,237,250,245,235, 31,186,123,247,110,165, 38,
-147, 77, 57,187,193, 18, 18,222,110,107,158,145, 19, 89,105,209,214,148,179, 27, 44, 0,144,243,251, 84, 35,128,253,119, 59,127,
- 49,232,192,197,228,229, 49,249, 30, 19,213,103,230, 31,168,108,153, 11,211,110,213,126, 85,215,191, 57,243,110, 26,128, 81,183,
-175, 97,241,157, 27, 23,191,163,120, 8, 89, 56,230,152,114, 30, 94,123, 21,250, 66,161,208, 28, 28, 28, 92,234,232, 66,137, 68,
- 98,182, 88,202, 11,160,156,117,232, 51,177, 22,232,180, 97,207,142, 13,163,246, 29,216, 63,191, 99,183,215,125,164, 85,170,160,
-134,138,194,134,105,205, 39,158,186,161,190,210,127,234,185,159, 18, 50,204,183, 81,201,124, 24,189, 94, 31, 7, 32, 95,175,215,
- 15,224,121, 62,149,162,168,144,252,252,252,155,118,187,253, 78,165, 13, 1,135,225,109,218,180,218, 66, 81,148,128,119,112, 11,
- 47, 10,153,173,230,204,123,105,120,201,101, 73, 26,213,112,199,164,111,127,104, 94,171,118, 88,243,226,181, 14, 27, 84,119,195,
-184, 47, 22, 55,175, 30, 90,167,249,147,245, 15, 43, 76, 19,224,237,198,252,247,246,172, 91,120,238,198,165,211, 95,249, 6, 86,
-175,158,149,150,112, 47,245,225,205,217,172, 89,187,231,101,207,115,210,195,152,165,107, 23,125, 49, 37, 51, 61,113,173, 81,253,
- 32, 26, 0,140,234, 7,209,247,174,227, 27, 77, 86,218,148,220,156,132, 69, 47,122, 44, 12, 6, 67,198,230,205,155, 61,219,181,
-107, 71,251,251,251, 67,173, 86,227,244,233,211, 28,199,113,233,149,214,202, 75, 60,109,200,163,188,127,251,229,199,133, 34,133,
- 91,111,135,195, 17,196,243,128, 64, 32,200,180, 26,181,199,116,180, 98, 42,242,147,205,229, 63, 51, 56, 10, 0, 93,188,118, 33,
-199,113,212,194,229, 27,146,133, 82,183, 82, 39, 67,180,155,117,114,142,227, 92, 94,235,176,224,209,245, 90,175,234,254,166,120,
-126,102,147, 22, 17, 95,217,237, 54,115,209,253, 97, 6, 96,230,121,228,210, 52,117,150,225,236,199,181, 47,209,152,162, 40,184,
-243,148, 0,110, 50, 1, 40, 80,208, 23,230,241,149,201,201, 42,213, 16,231,196,197, 24,115, 58, 85, 59,106,221, 49, 50,234,247,
- 35,131, 89,150,173, 81, 20, 51, 72,178,152, 12, 59,245,153, 94,191, 1,215, 28,248,247,115,184,216,108, 81,127,241, 63,114,169,
- 27,229,239,164, 25, 30, 42, 27, 80, 37,216,127,100, 82,114,206,149,132, 84,227,111,120,122, 89,157,151, 41, 39,227,239,239,255,
- 13, 69, 81, 35,196, 98,177,210,106,181, 26,120,158,223,152,157,157, 61, 27,207, 45,254,219, 76, 40, 83,153, 70,138,165,242,233,
- 54,179,225, 79, 99, 78,220,240,138,246, 93,238, 23,214, 83,170, 80,124, 97, 54, 25, 54, 26,179,227, 54,188,226,227,233, 33,145,
- 72,154, 41,149, 74,161, 70,163,185, 12,160,240,239,116,222,155, 52,105, 82,149,166,233, 26, 28,199,249, 3,240,128,115, 84,136,
- 70, 32, 16,164, 23, 69,180,248,202,106,182,127,119,167,111,183, 30, 13, 38,157, 56, 23,187,172,168, 91,241, 49,193,111, 46,145,
-142,232,221,101,242,111,123,246,151, 54,234,240, 31,119,205,255,255,105,118, 18, 40, 3, 53,163,104,177,199,156,110,225,102,163,
- 38, 35,125,194,249, 59,234,203, 0,116, 47, 83, 78,145, 72,244,182,205,102,147,137, 68, 34,147,205,102,219,252,119,217,119,153,
- 42,124, 52, 13,222,229,149, 41, 56, 80,215,158, 25,180,242,111,185,150,152, 70,141, 26,117, 16,137, 68, 85, 89,150,149, 91,173,
- 86,163,201,100, 74, 74, 78, 78,254, 19,101, 47,124,254,151,150, 83,161,170,179, 84, 36,146,124, 2, 0, 54,155,229, 7, 67,206,
-131, 73,229,125,177,156,207,255,163,207,145,111,141, 22, 15, 4,140,208, 15, 69, 19,115,115, 14,135, 58, 59,241,106,157,255, 98,
- 57, 9, 47,120,114,137, 38,209, 36,154, 68,243, 89,104,114, 60,137,230,127, 83, 83, 26, 88, 47, 68, 26, 88,207,229, 73,151,203,
-248, 60, 57,158,132, 98,198,150,242, 2,224,194,132,165, 4, 2,129,240, 23,192,145, 67, 64,248,111, 98,206,188,151,250, 87,126,
-158,240, 63, 71,153, 57,209, 84, 57,174,180, 50, 33,193, 23,113,182, 39,137, 38,209, 36,154, 68,147,104, 18, 77,162,249, 63,167,
- 89,145,246, 63,177, 75,114,236, 51,219,135, 1,252,191, 36,252,147,176, 42,209, 36,154, 68,147,104, 18, 77,162, 73, 52,255,215,
-120,108,188,104,114, 44, 8, 4, 2,129, 64, 32, 16,254, 26, 72,142, 22,129, 64, 32, 16, 8, 4,194,203, 81, 90,215, 33, 49, 90,
- 4, 2,129, 64, 32, 16, 8,175,128, 50,147,225, 73,215, 33,129, 64, 32, 16, 8, 4,194,203, 81, 28,209, 10,196, 51,211, 59, 16,
-163, 69, 32, 16, 8, 4, 2,129,240,106,200, 68,105,209,173, 67,135, 14,241,165,253, 78, 32, 16, 8, 4, 2,129,240,255,193, 63,
-220,139,148,140,100,141, 45,218, 6, 80, 34,162, 69, 12, 22,129, 64, 32, 16, 8,132,191,139,217,250,135, 81, 28,201, 42,126,101,
- 62,103,180,250,246,237, 75, 17,179, 69, 32, 16, 8, 4, 2,225,191,197,191,209,139,208,207,238, 32, 57,205, 4, 2,129, 64, 32,
- 16,254,155,102,235,223,180, 63,100,122, 7, 2,129, 64, 32, 16, 8,132,151, 35, 16, 64,159, 18,219,255,111, 75,240, 16, 8, 4,
- 2,129, 64, 32,252,219, 25, 91,214, 54,137,104, 17, 8, 4, 2,129, 64, 32,188,122,179, 69, 32, 16, 8, 4, 2,129, 64,248, 39,
- 67, 86, 54, 39,154, 68,147,104, 18, 77,162, 73, 52,137,230,191,157,226,121,180,128,178,230,209, 34, 16, 8, 4, 2,129, 64, 32,
-188, 16,125,224,156, 63,107,108,209,207, 62,196,104, 17, 8, 4, 2,129, 64, 32,188, 90,158, 91,126,135, 24, 45, 2,129, 64, 32,
- 16, 8,132, 87,107,176, 86, 19,163, 69, 32, 16, 8, 4, 2,129,240, 23, 67,140, 22,129, 64, 32, 16, 8, 4,194, 95, 4,133,178,
- 71, 14,156,172,132,206,139,140, 62, 56, 73, 52,137, 38,209, 36,154, 68,147,104, 18,205,255, 57,205,138,180, 79,226,159, 71,241,
-204,240,135,241, 36, 17,126,245,255,199, 63, 38, 67, 95,137, 38,209, 36,154, 68,147,104, 18, 77,162,249,111,103,236, 51, 63, 31,
- 67,186, 14, 9, 4, 2,129, 64, 32, 16, 94,173,217, 34, 75,240, 16, 8, 4, 2,129, 64, 32,188, 34,202,236, 38, 36, 17, 45, 2,
-129, 64, 32, 16, 8,132,151,163,204, 69,165,137,209, 34, 16, 8, 4, 2,129, 64,248,107, 12, 23, 49, 90, 4, 2,129, 64, 32, 16,
- 8,175,208,100,141, 45,245,175,135, 14, 29,226,201, 49, 34, 16, 8, 4, 2,129,240,223,226, 95,235, 69,138,119,140,152, 45, 2,
-129, 64, 32, 16, 8,196,139, 84,154, 64, 60, 25,109, 56,182,104, 27, 0, 25,117, 72, 32, 16, 8, 4, 2,129,240,178,244,193,211,
- 35, 15,199, 22,111, 19,163, 69, 32, 16, 8, 4, 2,129,240,242,140, 45,247,175,164,219,144, 64, 32, 16, 8, 4,194,127,147,127,
-163, 23,161,200,105, 37, 16, 8, 4, 2,129, 64,120, 41, 74,139,102,173, 38,135,133, 64, 32, 16, 8, 4, 2,225,175, 53, 92, 4,
- 2,129, 64, 32, 16, 8,132,191,194,100,253,213, 19,150,146,149,205,137, 38,209, 36,154, 68,147,104, 18, 77,162,249,191, 98,178,
- 74, 78,241, 0,128,140, 58, 36, 16, 8, 4, 2,129, 64,120, 89,200,162,210, 4, 2,129, 64, 32, 16, 8,127, 17,100, 81,105, 2,
-129, 64, 32, 16, 8,132,255,103,195, 69,140, 22,129, 64, 32, 16, 8, 4,194, 43, 52, 89, 79,153, 45,146,163, 69, 32, 16, 8, 4,
- 2,129,240,114,148,153,163, 69,161,236,145, 3, 39, 43,241, 15, 94,100,244,193, 73,162, 73, 52,137, 38,209, 36,154, 68,147,104,
-254,207,105,254, 31,123,231, 29,214,212,217,254,241,111, 22, 25, 36,144,176,195, 86, 25,226, 2, 69,235, 22,247,170,184,169, 91,
-235,174,213,106,245,181,110, 5, 90,181,142,186,107, 91,251,186,234,168,187, 86,113, 83, 7,110, 37, 40,130, 34, 32,136,128,236,
-145, 9, 36, 33,201,243,251,131, 81,106,153,218,190,191,142,231,115, 93,185, 32,201,201, 55,207, 57,231, 57, 39,223,115,159,231,
-185,239,186,180,195,241,247,103, 6,254, 71, 9, 75,233,212, 87,170, 73, 53,169, 38,213,164,154, 84,147,106,254,219,160,233, 29,
- 40, 20, 10,133, 66,161, 80,254,104, 99,245, 38,212,104, 81, 40, 20, 10,133, 66,161,188, 27, 52,143, 22,133, 66,161, 80, 40, 20,
-202,159,132, 35,202,162, 90, 21,127,253,169,209,162, 80, 40, 20, 10,133, 66,249, 99, 24,132,178,168, 86,197, 95,106,180, 40, 20,
- 10,133, 66,161, 80,254, 64,170,205,163,197, 0,128,176,176, 48, 82,254,188, 71, 96, 96,224, 13,186,173, 40, 20, 10,133, 66,161,
-252, 47,249,167,122,145,202,136, 86, 96, 96, 32, 3,192,117,186,171, 41, 20, 10,133, 66,161,252,127,240, 79,244, 34,204, 55,156,
-100, 15,186,155, 41, 20, 10,133, 66,161,252,127,240, 79,244, 34,236, 55, 92, 36,133, 66,161, 80, 40, 20,202,255, 11,127, 99, 47,
-226,136,178,129,240,231,202,255, 2,229, 41, 31,104, 30, 45, 10,133, 66,161, 80, 40,148,119,163, 98,182,225,239, 74,239,208, 40,
- 22,133, 66,161, 80, 40, 20,202,187, 81, 93,102,248,239,233,102,161, 80, 40, 20, 10,133, 66,249, 19,161, 17, 45, 10,133, 66,161,
- 80, 40,148,119,167,106, 84,235,127, 22,205,162,149,205,169, 38,213,164,154, 84,147,106, 82, 77,170,249,111, 50, 89,191,121, 78,
- 51,195, 83, 40, 20, 10,133, 66,161,252, 73,208, 89,135, 20, 10,133, 66,161, 80, 40,239, 70,197,140,195,170,207,169,209,162, 80,
- 40, 20, 10,133, 66,249, 3,205,214,239,160,183, 14, 41, 20, 10,133, 66,161, 80,222,141, 25, 53,189, 65,141, 22,133, 66,161, 80,
- 40, 20,202,159,100,184, 24,168,121,230, 64,120, 3,132,223,102,246, 65, 56,213,164,154, 84,147,106, 82, 77,170, 73, 53,255,117,
-154,117,105,135,227,239,199,255, 91,194, 82, 58,245,149,106, 82, 77,170, 73, 53,169, 38,213,164,154,255, 90,232,173, 67, 10,133,
- 66,161, 80, 40,148,191,128,209,178, 99,179,217,203, 4, 2,193, 55, 2,129, 96, 23,155,205,254, 10,128, 85, 67,191, 80, 40, 20,
-206,149, 74,165,113, 82,169, 52,221,205,205,237,188,133,133,249,167, 30, 60, 4, 0,224,252, 65,235,227, 3,224, 83,129, 64,240,
-140,207,231,167, 0, 56, 8,224, 83, 0,182,239, 34,252,133, 19, 70,198,204, 27,122,250, 11, 39,140,124,227,173, 65, 14, 14, 14,
- 55, 1,244,251,163,118,202, 24,115,244, 9, 18, 34, 53, 72,136,212, 49,230,111,127,213, 96, 97, 97, 49,193,209,209,241,174,141,
-141,205,107, 71, 71,199,219,124, 62, 63,168,129, 18,246, 14, 14, 14, 27, 93, 93, 93,227,157,156,156,182,162,172, 58,249, 95,150,
-110, 60,116,235,200, 67,110, 39, 46, 84, 93,184,248,166, 19, 23,125,251, 2,230,111, 41,215, 21,192, 9, 75, 75,203, 71,108, 54,
- 59, 12,192,136,242,254, 53,130,205,102,135, 89, 90, 90, 62, 2,112,162,124,185,183,233,167, 27, 1,188, 6,176,182,252,249, 39,
-174,174,174, 42, 63, 63,191, 20, 63, 63,191,125, 94, 94, 94, 19,235, 43, 14,106,110, 21, 0, 0, 32, 0, 73, 68, 65, 84,102,110,
-110,222,215,213,213,245,164,155,155, 91, 74,167, 78,157, 10,156,157,157,159,187,184,184,236,231,241,120, 61,232, 41,142, 66,161,
- 80,254,250, 12, 6,240, 37,128, 29,209,209,209, 50, 66,136,140, 16, 34,139,142,142,150, 1,248, 6,192, 58,212, 28, 66,252,205,
-235, 54, 54, 54,161,171, 87,175, 46,201,204,204, 36,185,185,185, 36, 62, 62,158,108, 89,177,216,212,223,154, 77, 60,236,172,138,
- 28, 29, 29, 95,184,187,184, 28,105, 41, 98, 46, 6,224, 89, 31,205, 42, 88, 9, 4,130,251, 43, 86,172, 80,223,188,121, 83,173,
-211,233,212, 38,147, 73,157,145,145,161, 14, 15, 15, 87,119,233,210, 69, 13, 96, 62, 0, 86, 3, 52, 43,249,220, 9, 55,200,158,
-149,228,115, 39,220,168,250,122,179,102,205,158,154, 76, 38, 50,114,228, 72, 45, 0,231,134,104,190,137, 51,192,111,105, 9, 73,
-144, 8,217,134,253, 95, 16,178,115, 33, 9, 18, 34,245,109, 52,237,237,237,127,158, 59,119,174,242,245,235,215, 68,171,213,146,
-212,212, 84, 50,115,230, 76,133,189,189,253,161,122,174,187,141,175,175,111,246,221,187,119, 77,114,185,156, 92,191,126,221,212,
-170, 85,171,236,122,154,173, 62,111,180,229,123, 39, 39,167,243, 13,121,216,219,219,239,110,232, 62,234,192, 67,170, 94,118,141,
-144,135,151,201,153,145,157,200,150,118, 46,100,132, 53, 87,222,149,139, 79,186, 87,159,202,164, 38,205, 15,186,119,239,174,121,
-242,228,137, 49, 63, 63,159, 60,125,250,212, 52,125,250,244, 18, 0,177,211,167, 79, 47,121,250,244,169, 41, 63, 63,159, 60,121,
-242,196,216,189,123,119, 13,128,105, 13,104, 39, 19,192,222,144,144, 16, 66, 8, 33,171, 87,175, 38,126,126,126,164, 87,175, 94,
- 68,173, 86, 19, 66, 72, 10, 33,100,159,193, 96,248,176, 62,154, 98,177,120,194,220,185,115,213, 69, 69, 69,164, 2,147,201, 68,
-228,114, 57,217,177, 99,135, 70, 42,149,158,175,225, 34,131,222,242,160,154, 84,147,106,254,213, 52,255,206, 56,162,108,156, 86,
-197,163,222,129,137,177,139, 23, 47,174, 48, 85, 23,186,118,237,250,224,195, 15, 63,148,125,248,225,135,178,174, 93,187, 94, 7,
-112, 41, 50, 50, 82,182,104,209, 34, 25,128,177,117,236, 8,171,206,157, 59,203,179,178,178,136,183,183, 55,105,212,168, 17,201,
-202,202, 34,132, 16,242,240,131,182,228,151,230, 32,105, 17, 23,200,229,159, 78,144,233,142,108,210,205, 81, 92,234, 40,149,230,
-219,218,218,174,193,111,107, 50, 86,183,115,135, 55,111,222, 92, 21, 27, 27,171, 78, 72, 72, 80,135,134,134,170,123,245,234,165,
-246,245,245, 85,143, 24, 49, 66,189,125,251,118,181, 94,175, 87,239,222,189, 91,109,105,105, 25, 91,141,217,122,107,163,197,102,
-179,183, 69, 71, 71,147, 23, 47, 94,144,242, 40, 69, 77,154, 98,137, 68, 50,192,202,202,106,190, 68, 34, 25, 0, 64, 12, 0,222,
-128,168,181, 24,110,159,180,246,104, 22, 54,182,143,231,142, 62,239,181, 13,178, 96,202, 75,191, 94, 72,200, 72,183,183, 50, 90,
- 98,177,120,194,167,159,126,170,210,106,181,164,168,168,136,168,213,106, 82, 84, 84, 68, 84, 42, 21, 25, 59,118,172,146,207,231,
- 15,175, 75,211,214,214,246,139,136,136, 8, 67, 86, 86, 22,137,136,136, 32,231,207,159, 39, 59,119,238, 52,217,219,219,111,110,
-232, 1, 40,149, 74,175, 92,190,124, 89, 22, 21, 21, 37,187,127,255,190,172,180,180, 84,166,215,235,101,122,189, 94, 22, 22, 22,
- 38, 59,117,234,148,236,232,209,163, 50,157, 78, 39,211,233,116, 50,173, 86, 43,107,210,164,201,197,134,238,163,246, 60,164,233,
-110,158, 33,100,243,108,162, 88, 63,139,200, 23,188, 79,114,102, 6,144,111,222,115, 33, 1, 2,156,197,239,107,123, 86,171,201,
-225,112,110,164,164,164,152,150, 46, 93,170,107,209,162,133, 98,202,148, 41, 37, 90,173,150, 16, 66,136, 86,171, 37, 83,166, 76,
- 41,105,209,162,133, 98,233,210,165,186,151, 47, 95,154,216,108,118,120, 3,218,185,174,194,100,221,184,113,131, 84, 69,173, 86,
-147, 94,189,122,165,248,249,249,237,107,220,184,241,184,186, 52, 69, 34,209,208, 37, 75,150,168, 73, 53,148,150,150, 18,149, 74,
- 69, 94,190,124,105,106,212,168, 81, 6, 0, 27,122, 50,167,154, 84,147,106, 82,163,245,167, 49,163,142,231,213,111,196, 69,139,
- 22,201, 8, 33,178,229,203,151,203,202, 35, 91,102, 0, 68,229, 15, 54,128, 49, 75,150, 44,145, 17, 66,100,139, 23, 47,174, 88,
-166,166, 29, 49,248,248,241,227,250,173, 91,183, 18, 7, 7, 7, 34,149, 74,201,182,109,219,136,201,100, 34, 89, 97,135,200, 47,
-205, 65,158, 45,155, 68, 8, 33, 36,126,205, 28,242, 75,115,144,164,111, 63, 39,227,199,143, 47, 50, 55, 55, 31, 91,203,206,181,
-110,219,182,173,170,184,184, 88,189,127,255,126,181,185,185,249, 67, 0, 45, 80,118, 43,146, 81,222,214,137, 45, 90,180, 80,198,
-196,196,168,127,252,241, 71, 53,128,208,122,118, 24, 79, 0, 61,133, 66,225,136, 37,206,156, 4,178,103, 37, 89,226,128, 39, 0,
- 90, 1,176, 43, 95,198,105,241,226,197,132, 16, 66, 92, 93, 93, 35,106,208, 20,251,250,250, 46, 78, 72, 72, 8, 46, 45, 45, 13,
-142,138,138, 10,110,218,180,233,210, 33, 77, 28, 59,157, 30,219,215, 95,241,249, 44,127,178,105,129,239, 87, 3,219,247, 57, 50,
-186,199,216,201,141,109,111, 78,177,231, 23,141, 18,179, 84,111,220, 58,172, 87,199,118,118,118,190,159,154,154, 90,105,174, 84,
- 42, 21,121,253,250, 53, 73, 78, 78, 38, 55,111,222, 36,142,142,142,191,212,165, 41,149, 74,159,166,166,166,146,111,183,108, 33,
- 35, 91, 53, 35, 1, 18, 11,210,221,202,130,180, 19,241, 53,205,129,118, 13, 53, 90,143, 30, 61,146, 1,144, 1,144,229,231,231,
-203,242,243,243,101,133,133,133,149,175, 1,144, 41, 20, 10,153, 66,161,144,233,116, 58,153,135,135, 71,131,141, 86, 23, 62,186,
-116,224,163,160, 19, 15,197,131,157,109, 51,102, 53,177, 53,222, 27,219,137, 20,206,238, 69,182,250, 59,147,174, 92,124, 82, 79,
-205,193, 92, 46,247, 58,128,133,229,166,124,210,128, 1, 3,138, 8, 33,100,192,128, 1, 69, 0, 38,149,191,254,105,185,201, 26,
- 80,207,118, 50,189,188,188, 52, 21,145, 44, 0,119,188,188,188, 52,126,126,126,196,207,207,143,184,186,186,170,202,181,235,117,
- 66,243,244,244,140, 47, 46, 46,174, 52,128,114,185,156,100,100,100,144,164,164, 36, 18, 27, 27, 75, 30, 62,124, 72, 82, 82, 82,
-200,177, 99,199,140, 18,137,228, 28, 61,153, 83, 77,170, 73, 53,169,209,250, 83,141,214,155,143,223, 18, 22, 22, 70,222,120,105,
-125,100,100,164,108,201,146, 37,178, 58,156,217,140,229,203,151, 87, 68,189,190,172,229,199,127,119,124,124, 60,153, 52,105, 18,
-241,241,241, 33, 62, 62, 62,228,195, 15, 63, 36, 10,133,130,168, 19, 99,200, 47,205, 65, 30,142,106, 71, 8, 33, 68,245, 44,138,
-252,210, 28, 68, 54,190, 51,121,252,248, 49,113,113,113,185, 92,203,247,159,189,125,251,118,238,161, 67,135,178, 80, 54, 30,139,
- 3,160, 35,128,109, 2,129, 96, 47,202,110, 23, 54, 2, 96,229,237,237, 93, 80, 84, 84,164, 30, 57,114,164, 26,128, 91, 45,154,
-221,125,124,124, 94,236,222,189,155,228,228,228,144,130,130, 2,178,161, 75, 83, 66,246,172, 36,171,219, 53, 50,125,251,237,183,
-218,133, 11, 23,106,172,173,173,195, 0, 56,141, 28, 57,210, 64, 8, 33, 1, 1, 1,217,213,137, 73, 36,146, 1, 9, 9, 9,193,
- 37, 37, 37,193,114,185, 60,184,160,160, 32,248,204,233,211,193,253, 91, 53,157,164,248,124,150,255,233,177,125,253, 7, 58, 91,
-141,216,220,239,189,143, 94, 47,157, 54,114,121,231, 22,207, 74,214,205,187,246, 65, 19,135,141,111,179,183,237,236,236, 50,181,
- 90, 45, 1,240,187,199,139, 23, 47,136,141,141, 77,106, 93, 26,214,214,214,203, 63, 29, 51,218, 56,188,145, 51,121,177,117, 5,
- 41,189,242, 35, 41, 61,191,159, 36,174, 95, 64,134, 72,109,149, 29,205,152, 75,234,219, 30,169, 84,122,229,254,253,251,191, 49,
- 90,133,133,133,213, 26, 45,165, 82, 41,211,233,116, 50, 47, 47,175,139,239,218,235, 59,114,225,209, 93,192,122, 24, 53,169, 27,
-201,157,213,139, 12, 16,115, 82,222, 65,110, 12,128,235, 0,198, 55,240,115, 76, 0,235, 42, 12,213,250,245,235, 9, 33,132,120,
-121,121,105,240,110,147, 81,196,205,154, 53, 75,158, 54,109,154,161,121,243,230, 57, 93,186,116,145, 63,120,240,128,220,184,113,
-131,156, 63,127,158,156, 56,113,130,196,196,196,144,215,175, 95,147,248,248,120, 50,104,208, 32, 57,128,238,244, 92, 72,161, 80,
-254,202, 84,227, 69,254,246, 48, 43, 86, 44, 48, 48,144, 81,101, 5,197, 0,248,237,218,181,203, 93,183,110,221, 38,148,229,130,
- 96,248,178,240, 65, 47, 1,251,113, 47, 1,251,177, 47, 11, 31,148, 71,140,190, 95,179,102,205, 23,126,126,126,153, 0, 4, 0,
-164,213,125, 17, 33,164,155,141,141, 13, 82, 83, 83, 33, 22,139, 33, 22,139,145,154,154, 10, 66, 8, 12, 4, 40, 37,128, 86,175,
- 71,113,113, 49, 74, 76, 4,197, 38, 64,169, 86, 67, 42,149, 66,175,215,123,212,208,254,214,163, 70,141,242,240,245,245,205, 93,
-180,104, 81, 6,202,198,202,236,157, 58,117,234,149, 59,119,238,248,170,213,234,130,216,216,216,146, 86,173, 90, 13, 0, 32, 77,
- 72, 72,152,176, 99,199, 14, 76,154, 52, 9,181,252,232,180, 26, 52,104,208,249,152,152, 24,143,241,227,199,227,250,245,235,216,
-176, 97, 3,242,242,242, 8, 0,104,181, 90, 98, 52, 26,245,157, 59,119,214,111,221,186,181,125, 64, 64,192,253, 38, 77,154,176,
- 0, 32, 57, 57, 57,177, 58, 65, 6,131,209,212,221,221, 29, 90,173, 22,185,185,185,136,137,137,129,133, 88,140,232,140, 60,135,
- 30,155,191,205, 95,118,250, 10,103, 76,123, 95,235,249,125,187,104,215, 94,190,238,221,194,201,193, 65,167, 47,149,198,103,102,
-103,188,205, 78, 53, 51, 51, 75,205,203,203,131, 78,167, 67,113,113, 49,148, 74, 37,242,243,243,145,151,151,135,140,140, 12,152,
-153,153,189,168, 75,195,178,160, 32, 34,249,246, 13,198,177,239,214,195,195, 80, 0,246,201,109, 96,255,252, 13, 60,117,185,216,
-181, 98,166,133,206,198, 46,196,210,194,162, 80, 34,145,124, 15,192,171, 46, 61,127,127,127,228,231,231, 35, 63, 63, 31, 54, 54,
- 54,176,178,178,130,149,149, 21,228,114, 57, 20, 10, 5,148, 74, 37,188,189,189,209,186,117,107, 28, 56,112,224, 15,233,220,247,
-116, 72, 50,192, 56,235,202,243, 12,152, 9,133,104, 98, 37,114,127, 79, 4,235, 90, 62,210,139,195,225, 28,183,182,182,190, 12,
- 96, 54, 0, 33,128,217,214,214,214,151, 57, 28,206, 48, 0,171, 1, 28,106, 96, 51,214,134,132,132, 44, 78, 72, 72, 48,127,252,
-248, 49, 22, 45, 90,132,208,208, 80, 36, 38, 38,126, 13,192, 84,190,204,199, 54, 54, 54, 97, 76, 38,243,191, 0,222, 7, 48,192,
-209,209,177,119, 29,186,195, 22, 46, 92, 88,210,182,109,219,248,103,207,158, 13,187,125,251,118,187, 5, 11, 22, 40, 94,189,122,
-133,248,248,120, 56, 58, 58,194,213,213, 21,106,181, 26,133,133,133, 24, 54,108,152,216,210,210,114, 44, 61,141, 83, 40,148,191,
-178,201,122,195,139,252,221, 34, 90,213, 62,175,246,138,218,220,220, 60, 68, 38,147,117,242,243,243, 99, 3, 56, 6, 0,190, 44,
- 4, 13,235,220,102,239,233,239,215,251,157,218,186,194,175,191,159,247, 94, 95, 22, 42,102,177,133,181,107,215,206, 74, 38,147,
-117,230,241,120,159,212,208, 8, 2, 0, 86, 86, 86, 16,139,197,144, 72, 36,176,178,178,130,201,100,130,186,168, 4, 26, 35,160,
- 42,209, 65,161, 80, 64, 85,254, 92,173,213, 67,163,209, 84,126,182, 26,122, 76,155, 54, 45,119,199,142, 29, 57,153,153,153,235,
- 1,180,154, 52,105,210,208,237,219,183,227,234,213,171, 37,239,251,120,218,172,233,214,230,139, 22,153,137,193, 62, 28, 76, 7,
- 16, 17, 17, 17,129,206,157, 59,131,193, 96,140,174, 78, 80, 32, 16,124,115,228,200, 17, 65,108,108, 44, 60, 61, 61, 99, 71,143,
- 30,253,193,250,245,235, 61,132,234,130, 91, 0, 96,200,207,138,157, 51,103,206,202, 53,107,214,228,230,230,230,234,139,138,138,
-236,135, 12, 25,130,212,212, 84,188,126,253,250, 78, 13, 38, 51, 62, 42, 42,138, 40, 20, 10, 36, 37, 37, 33, 42, 42, 74,176,114,
-229,202,246, 70, 38,115,104, 58, 44, 38, 79,234,210,174,253,248,142,109,112,232,238, 99,179,155,207,147, 37,237, 26, 57, 91, 61,
- 74,203,108, 92,202,192,139,183,217,219, 42,149,106,219, 23, 95,124,161, 86,171,213, 72, 79, 79,199,147, 39, 79,240,236,217, 51,
-164,164,164, 96,195,134, 13,234,130,130,130,237,117,105, 56,241,217,255,217,184, 96, 42,131,253,244, 14,240,248, 6, 80,164, 2,
-138,213,208,198,201,176, 47, 46, 11, 59, 79,254,196,125,149,154, 42, 57,122,244,232, 52, 55, 55, 55, 25, 0,239,218,244, 8, 41,
-219,133, 76, 38,243, 77, 19, 10, 38,147,169, 2,144, 37, 20, 10,211, 44, 44, 44,210,152, 76,102, 22, 33, 68,243,135, 92, 73, 24,
-160, 7,139, 5,112, 5, 96,114,106, 45,237,249,193,232,209,163,143,164,165,165,245, 79, 74, 74,234,180,125,251,246, 47,248,124,
-126,244,246,237,219,191, 72, 74, 74,234,148,150,150,214,127,244,232,209, 71, 0, 76,108,200,247,123,121,121,205, 9, 14, 14,198,
-134, 13, 27,208,186,117,107,120,123,123, 23,133,132,132,108, 3,176, 2,192, 39, 94, 94, 94,183,230,204,153, 51, 37, 39, 39, 71,
-154,158,158,222,250,235,175,191,158,185,109,219,182,247, 50, 50, 50,248,117, 72,119,237,215,175, 31, 46, 92,184, 0, 0,153, 0,
-146,242,243,243, 13, 25, 25, 25,104,214,172, 25,218,183,111, 15,181, 90, 13,181, 90, 13,185, 92, 14,119,119,119,152, 76,166, 78,
-244, 84, 78,161, 80, 40,255, 83,195, 85,189,209,226,243,249, 86,254,254,254,104,210,164,137, 21,202,103,107,217,112,217, 75,231,
- 79, 27, 99, 46,146, 93, 4, 35,234, 23,140,238,214,210,220,134,203, 94, 90,254, 17,182,187,187, 59,207,223,223, 31, 66,161,208,
-185,134, 47,191,158,149,149, 5,127,127,127, 72, 36, 18,136,197, 98,248,251,251, 67,175,215, 67,161, 82, 65, 99, 4,138, 74, 77,
- 80, 40, 20, 40,200,205, 70,145, 17, 48, 88,216, 32, 37, 37, 5, 44, 22, 43,185, 6, 77, 71, 79, 79,207,220,232,232,232, 92, 0,
- 17, 0, 62, 10, 13, 13,197,146, 37, 75,176,106,213,170, 35,230,153, 47,251, 29,185,240,179,205,225,144,143,237,188,185,140, 49,
- 0,244,105,105,105,144, 72, 36, 16, 10,133,213, 26,131,128,128,128,182, 66,161, 16,251,247,239, 39,233,233,233, 93, 80, 54,133,
- 63,153,193, 40, 51,123, 2, 38, 20, 0,182,201,100,178, 14, 43, 87,174,124,222,167, 79, 31, 78,199,142, 29,177,122,245,106, 0,
- 8,171, 78, 83, 46,151,223,155, 56,113,162,238,218,181,107,136,139,139, 19,158, 62,125, 58,104,245,234,213, 45, 95,189,122,197,
- 59,123,254,226,192,131,105,202,160,245,151,111,242,215, 92,186,126,207,214, 82,216,162,177,173, 53,162, 94,189, 54, 51,178,240,
-160,174, 61,218,129,195,154,214,131,207,142,234,198, 99,102,246,224,179,101,239,113, 88, 83, 85, 42,213,209, 51,103,206, 92, 90,
-176, 96,129, 58, 39, 39, 7, 22, 22, 22,200,207,207,199,218,181,107,213, 81, 81, 81, 39,117, 58,221,217,186,116,141, 38,210,214,
-181,145, 27,240, 34,186,242, 53,189,137,224,129,206, 12,129, 31,205,131, 79,179,102,208,233,116,104,213,170, 21, 35, 52, 52, 84,
- 40, 22,139, 63,171,211,244, 48,127,215,221, 12, 12, 6, 35,139, 16,242, 90,173, 86,167, 11, 4,130, 87,102,102,102,175, 10, 10,
- 10,210, 9, 33,217,127,132,207, 34, 76,252,167,115, 43, 47,128, 39,192,171,124,117,198, 67, 53, 10,170, 91,208,194,194, 98,234,
-206,157, 59,249,123,246,236, 41,157, 51,103,142,118,230,204,153,156,226,226, 98,251,153, 51,103,114,230,204,153,163,221,179,103,
- 79,233,206,157, 59,249, 34,145,104,196,219, 52,164,180,180, 20,209,209,209,235, 19, 19, 19,133, 40, 75, 55, 50, 47, 36, 36,100,
- 82, 66, 66, 2,127,199,142, 29, 56,113,226, 4, 78,156, 56,129,161, 67,135, 98,238,220,185, 8, 14, 14,174, 77,206,220,207,207,
-207,223,198,198, 6, 55,110,220,200, 0,240, 10, 64, 91,145, 72,100, 49,116,232, 80,244,239,223, 31, 37, 37, 37,208,235,245,149,
- 70,139,197, 98, 65, 34,145,216,208,115, 32,133, 66,161,252,233, 38,235, 55,102,139, 13, 0, 21,161,186,192,192, 64, 70,109, 63,
-140,198,194, 28,200, 53, 69, 72, 81, 20, 33,181,208,244,155,247, 76, 38, 83,173,223,158,145,145,113,246,238,221,187, 83,253,253,
-253,217, 25, 25,101,119,196,252,253,253, 81, 84, 84,132,140,199,247,161, 49, 1, 66, 79, 95,104, 52, 26, 20, 62,123, 4,145, 95,
- 39,216, 12, 26,143,205, 59,118,104,243,243,243,191,171, 78,147,203,229,114, 92, 92, 92,114,147,147,147, 13, 0, 10,196, 98,113,
- 63, 55, 55, 55, 92,191,126, 29, 0, 14, 17, 96, 35,162,174, 1, 55, 78,129,148,133, 84, 68,238,238,238,200,201,201,129, 90,173,
-190, 94,157,230,221,187,119, 19, 74, 75, 75, 91, 13, 25, 50,132,241,195, 15, 63, 28, 83, 42,149,171, 0, 60,209,154,192,122,156,
-150, 13,141, 17,124, 0,125,173,172,172, 62, 13, 14, 14,238, 61,103,206, 28,156, 57,115, 6,151, 47, 95,214,163,108, 44,216,221,
-106,100, 21, 73, 73, 73,187, 22, 46, 92,216,145,201,100,126,116,229,202, 21,131,183,183,183, 82,175,215, 27,155,250,248, 48, 87,
-133,126,110, 54,251,163, 25,146,252, 34, 60,237,223,212,177, 51,131, 1, 60,125,157,243, 42, 81,141,252,218,182,105, 0,151, 21,
- 54,172,139, 95,192,212,209,131, 69, 66,207, 22,208,196,220,151,238, 58,126,126,179, 32, 42, 33,240, 70, 78,206,208, 51,103,206,
- 4, 93,191,126,125,182, 78,167,107,194,227,241, 94,200,229,242,173,106,181,186, 78,147,197, 98,177, 6,105, 29, 93,172,228, 5,
- 5,224,151, 71,162,148,165, 38,228,105, 13,136,147,120, 99,172,139,107,229,109,208,172,172, 44, 72,165, 82,134,209,104, 28, 92,
-155,230,229,203,151, 17, 24, 24, 88, 97, 60,193, 96, 48,192, 96, 48,242,124,124,124,178,121, 60, 94,190,153,153,153,114,227,198,
-141, 37, 37, 37, 37, 96,179,217,124,163,209,200,122,151,222,222,222, 28,246, 60,194,248,102,230,144,158,125, 90,183,104, 70, 34,
- 30, 62,102, 20, 22,149,236,171, 37, 10,248,181,151,151, 23,187,160,160,224, 44,128,184,210,210,210,195,199,142, 29,227, 79,152,
- 48,161,228,248,241,227,227, 0,120,108,218,180, 41, 72,173, 86, 55,168,164, 66, 98, 98,226,215,107,214,172, 89,188,124,249,114,
- 28, 56,112, 96, 78, 98, 98,226,146,242, 72,215,208,224,224, 96,108,220,184, 17, 7, 14, 28, 48,197,197,197,157, 55,153, 76,137,
- 11, 22, 44,240,115,112,112,200,203,204,204, 76,172, 69,182,221,128, 1, 3,180,183,110,221,226,170, 84,170,155, 0, 62,157, 53,
-107,214,180, 14, 29, 58, 40, 71,143, 30, 45, 42, 40, 40,144,155,155,155,115,119,239,222,109,197,102,179,161,209,104,192, 96, 48,
-160, 82,169,116,244, 60, 72,161, 80,254,170,212,228, 69,254, 38,212,248,219,192,174,110, 5,139,138,138,178, 83, 83, 83,155,189,
-126,253,218, 0,192, 0, 0,249, 58,195,151,107,118,159,218, 51,162,163,151, 48,179,180, 20,167, 31,198, 22,229,235, 12, 21,131,
-223, 13,175, 95,191, 86,189,122,245,202,162,184,184, 88, 93,195,119,221,249,230,155,111,138,175, 93,187,102,145,148,148, 4,163,
-209,136,182,109,219, 34, 62, 62, 30,133,113,209, 16, 54,107, 11, 97,247, 64,196,202, 30, 34,234,114, 56, 94,170,117,134,231, 43,
-214, 40,212, 26, 77,176, 94,175, 63, 93,157, 32,135,195, 41, 0, 64, 8, 33, 70, 0, 80, 42,149, 79,212,106,117, 55, 7, 7, 7,
- 60,125,250, 84,168, 49, 98,110,208,210,205,219, 9, 33, 70,179,178,217, 92,243, 71,143, 30,141,200,200, 72, 0,136,172, 78, 83,
-169, 84,206,153, 62,125,250,181,253,251,247,179,147,146,146,250,239,217,179,167,255,243,231,207, 9,163, 32,213,120,171,136, 3,
-143, 73,115,223,251,214,221,231,114, 96, 96, 32, 28, 29, 29,177,123,247,110,108,221,186,181,244,227,143, 63, 78,216,186,117,235,
-123, 57, 57, 57,135,107, 88,127,133, 92, 46,191,104, 99, 99, 51,187,101,203,150, 42,141, 70,131,252,252,124,100,100,100,192,218,
-198,134,105, 0,179,179,157, 68,114,248,108,150, 74,200,190,120, 15,247,211, 51,107,141,102,117,228,176, 38,142, 8,104, 19,240,
-201,242,165, 34,220, 58, 13,198,244, 96,144, 61, 95, 96,222,135, 65, 22, 37,218,195,221, 53,143, 83, 38,200,148,202,131, 74,165,
-242, 68, 3, 59,203,128,206,157, 59, 31, 89,179,102,141, 96,217,134, 53,216,212,204, 25,134,252,124,228,106,141,200,211, 26,160,
- 44,140,195,211,167,177,176,177,177,197,203,151, 47, 81, 82, 82,130,103,207,158, 17, 22,139,117,182,174,136, 78, 5, 85,110, 23,
-202,121, 60, 94, 62,135,195,201,102,179,217, 5, 73, 73, 73,154,146,146, 18, 48,153, 76,161,209,104, 20,212,163,173, 46,182,182,
-182, 11, 80,150, 76,244,140, 42, 47,111,155, 63, 7, 18,176,209,195,221,214,102,224,138,153, 19,108,221,156,236,229, 73, 9, 47,
- 74,191,187,116, 59,175, 68, 91,243,100, 13, 0, 97, 5, 5, 5,149, 17,201,227,199,143,207, 59,126,252,248, 52, 0,123, 81, 86,
-119, 43, 92, 46,151,127,251, 22, 7,223,138,147, 39, 79, 46, 94,190,124, 57, 4, 2, 65,101,242, 84,129, 64,192, 7,128, 31,127,
-252, 17, 79,159, 62,237,128,242,241, 90, 38,147,233, 72,102,102,102, 93,154, 30,190,190,190, 73,167, 78,157,226, 2,112,154, 53,
-107, 86,167,237,219,183,227,195, 15, 63,204,141,141,141,237, 8, 32, 25,128,199, 71, 31,125,244,224,192,129, 3, 86, 38,147, 9,
-133,133,133,208,233,116,201,244, 84, 78,161, 80,168,217,250, 83,240, 7, 16,133,178,252, 89,131, 0,156, 67,217,176,142, 26,113,
- 45,119,103,151, 0, 12,169,248,125,172, 97, 48, 60, 80, 54, 35,235, 34,128,255, 2,112,168, 73,212,198,198,230,179, 73,147, 38,
-149,166,167,167,147,172,172, 44,114,226,196, 9, 50,127,234, 36, 99, 95, 79, 39,147,167,147,131,198,206,206, 46,222,209,214,122,
- 95, 27,115,204, 7,224, 82,143, 21,155,244,252,249,243, 25,147, 38, 77,154, 90,254,189, 83,143, 28, 57,162,190,114,229,138,154,
-197, 98,133,161, 44,181, 67,133,161,156, 56,120,240, 96,181, 86,171, 85,251,248,248, 20,160,108,224,126, 77, 4,245,232,209,163,
-240,194,133, 11,196,104, 52,254, 46, 71, 81,110,110, 46,185,124,249, 50,233,210,165,139, 28,192,132,222,189,123, 95,191,125,251,
-246,245,174, 93,187,158,172,171,193,182,182,182, 75, 31, 63,126, 28,153,146,146, 34, 59,119,238,156,236,240,225,195,178,143, 62,
-250,232,137,159,159, 95,113, 66, 66,130,201, 96, 48,144,199,143, 30, 17,159,166, 77, 53, 0,220,107,210,233, 37, 96, 63, 80,238,
-254,130,148,172,254,144,148, 12,115, 37, 0,136,106,243,103, 36,123, 78, 31, 18, 63,123, 32,233,201,103,221,125,155,158, 98,109,
-109,125, 41, 50, 50,146,168, 84, 42, 18, 19, 19, 67, 38, 6,246, 39,119,167,245, 33, 23,251,123,145, 3,221, 27,147,205,253,252,
- 72,255,238,221,200, 55,223,124, 67, 78,157, 58, 69,150, 46, 93,106,178,181,181, 85,161,150, 49, 90, 82,169,244,202,177, 99,199,
-100, 0,100, 44, 22, 75,166, 84, 42,101, 42,149,234,108, 90, 90,218, 78, 31, 31,159,197, 45, 91,182, 28,215,172, 89,179, 94, 61,
- 27,187, 47,238,109,193,139,239, 99,201,127,209, 84,100,190, 25,191,207,123, 85,137, 24,112,247,244,240, 80,221,184,113,195,164,
-213,106,201,205,155, 55, 77,205,155,122,151,108, 26, 53,224,228,203,221,235, 78,150, 92,248,225, 82,209,207,223,223, 62, 62, 57,
- 48,186,135, 57,243,135, 78,194,202,116, 28,111,203, 24, 0,167,241,235,172,195, 73, 0,126, 70,237,179, 16,153, 0,246,174, 94,
-189,186,234, 76, 67, 0, 96,250,249,249,201, 8, 33, 50, 63, 63, 63, 89, 67, 27, 98,110,110,190,224,204,153, 51, 33,110,110,110,
- 27, 70,143, 30,189, 91, 46,151,159, 27, 55,110, 92, 52,202, 38,131, 48, 80, 86, 29, 97,176,139,139, 75,110, 84, 84, 20,185,126,
-253, 58, 25, 57,114,164,202,204,204,108, 60, 61,141, 83, 40, 20,202,159,194,140, 26,254,214,202,154,232,232,232,138, 28, 90,179,
-106, 19, 95,178,100,137, 44, 50, 50, 82,134,178, 44,241,181,194,102,179,127,250,248,227,143,137,131,131,131,218,222,222,254, 39,
- 14,139, 53,205, 85, 0,127,188,221, 84,247,110, 7, 15, 30, 28,250,245,215, 95, 15, 2,208, 1, 0,199,217,217, 57, 35, 43, 43,
- 75,125,251,246,109,117,151, 46, 93,212,182,182,182, 57,190,190,190,234, 77,155, 54,169, 75, 75, 75,213, 11, 22, 44, 80,227,247,
-249,190,170,131, 15, 96, 54,151,203,253,169,121,243,230,209, 43,134,244, 42,221, 48,119, 26,153,228,101,167, 6,240, 53,128,143,
- 1, 72, 0,112,130,130,130,126,121,246,236,217, 37, 95, 95,223, 93,245,208,117,106,217,178,229,213, 35, 71,142, 68,158, 58,117,
- 74,246,217,103,159, 69,218,216,216,164, 39, 36, 36,152, 74, 74, 74, 72, 97, 97, 33,145,203,229,228,220,185,115, 70,107,107,235,
- 29, 53,174, 56,143,149, 73, 46, 31,170, 54,133, 67,218,242,241,164, 11,151,249,250,109,122,138, 80, 40, 44,200,207,207, 39, 89,
- 89, 89, 36, 41, 41,137,156, 60,121,146, 12,232,220,158, 28,253,104, 4, 57, 52,117, 40,217, 56,160, 61,233, 96,193,215, 72, 45,
- 68,145, 22, 22, 22, 57,245,153,117, 40,149, 74,175,104,181,218,202,244, 13, 46, 46, 46, 50, 31, 31,159, 83,190,190,190,155,207,
-156, 57, 51,111,203,150, 45, 67,123, 54,118, 95,188,182,127,231,226,162,240,227, 68,117,236,107,178,164,173,119, 73,185,153,175,
- 22,103, 27,235,131, 55,174, 95, 55, 85,152, 95,131,193, 64, 78,255,244, 19, 25, 53,176,111,180,226,226,143,255,189, 25, 60,231,
-200,130,182,222,167,187,240, 49,166, 54,195, 86,121, 41, 34,130, 77,128, 37,115,231,251,110,214,153,221,196,204,175, 59, 90,252,
-166,188,212, 40,111,111,239, 36, 66, 72,102,179,102,205,146, 0, 28,106,214,172, 89,213,231,147,107,144,173, 76, 78, 26, 18, 18,
- 66,202,143, 15, 38,128, 85,107,214,172,145, 17, 66,100, 94, 94, 94,183, 0,160,181, 16,182,221,197,204,255, 14,241,112,200,239,
- 46,102,254,183,181,176,250,146, 81,238,102,104,218,205,206,252,230, 80, 47, 71, 85, 15,103,113,196,161,125,123, 54,188,255,254,
-251,187, 1,236, 0,240,133,141,141,205,205, 49, 99,198, 60, 61,112,224,192,211, 77,155, 54,233, 19, 18, 18,200,148, 41, 83, 52,
- 60, 30,239, 11,122, 30,164, 80, 40,148, 63,141,138,204,240,142, 13, 49, 90,131, 23, 47, 94, 44, 35,132, 84,228,210,154, 80,205,
- 50, 67,150, 47, 95, 46, 35,132, 84,100,135,127, 51,129, 89,117, 9,205, 66,118,238,220, 73,120, 60,222,127,223,114,101,170,106,
- 74,135, 13, 27,214, 81,169, 84,190,231,224,224,240, 94,121,228,202,213,214,214, 54,233,240,225,195,234,226,226, 98, 53, 33, 68,
-109, 48, 24,212,145,145,145,234, 30, 61,122,168,171, 92,245,215,213,206,223,176, 76,138, 91, 15, 87, 76, 37,203,164,184,245,198,
- 91,227,247,238,221,123, 33, 57, 57,249,172,165,165,229,162,122,106,186,218,217,217,173,178,182,182,190,100,107,107,187,204,218,
-218, 58, 83,175,215,147,194,194, 66, 18, 31, 31, 79,174, 95,191, 78,238,222,189, 75,172,173,173,211,107,106,103,111, 1,251, 94,
-225,134,217,196,180,119, 13,209,109, 95, 74, 0, 16,249,150, 37, 36,239,155, 80,242,112,122,127,210,131,207,186,243, 22,219, 19,
- 18,137,228,251,159,126,250,201,148,152,152, 72,194,194,194,200,185,115,231,200,220,185,115, 73, 83, 39, 71,109, 71, 46, 51,187,
- 27,143,125,233,109, 18,150,106,181, 90,153, 82,169,148,169,213,106, 89,243,230,205,101,237,219,183, 63,213,177, 99,199,205,199,
-143, 31,159,183,118,237,218,161,189, 45,120,241, 69,225,199, 9,249,108, 32, 33,179,187,146, 23,211,122,144, 94, 2,246,227, 26,
- 53, 29, 28,210, 43,178,181,107, 52, 26, 18, 17, 17, 65,174, 94,189, 74,164,182,182,202, 0, 1,107, 70, 23, 30,186,119,177,132,
-164,190,237,236, 41,102,238,187,247,205,151,198,226, 11, 7,200,143,147, 6, 26,122, 72,152, 59,171, 44,119,148, 16,146, 57,114,
-228,200,151,132,144,204,147, 39, 79,166, 17, 66, 50, 71,140, 24,241,146, 16,146, 9,224, 72,117,154,111, 36, 39,221, 91,110,178,
-102,135,132,132,200, 8, 33,178,144,144, 16, 25, 80,150, 68,181,187,152,185,255,254,174,141, 38,237,185,253,228,248,148, 65,198,
-238, 98,230,254,106,219, 41, 97,159,141,218,187,133,232, 46, 29, 34, 63,205, 29,103,236, 42,181,188,225,237,237,189,113,222,188,
-121,167,238,222,189,251,196,104, 52, 62, 77, 74, 74,122,186, 99,199,142,167,157, 58,117,186,101, 99, 99, 19,205,229,114, 63,174,
-107, 31,253, 65, 80, 77,170, 73, 53,169, 38,229,205, 0, 83, 45,239,157, 93,191,126,189,144, 16,178, 32, 40, 40, 8,235,214,173,
- 27,213,178,101,203, 49,206,206,206,118, 0,144,145,145, 81, 20, 19, 19,163, 12, 10, 10,194,170, 85,171,176, 97,195,134,205, 40,
- 27,203,242,191, 36,235,244,233,211, 46,115,230,204,201, 89,187,118,173,105,202,148, 41,205, 0,196,228,229,229, 53, 29, 55,110,
-220,108, 54,155, 29,228,238,238,238,155,153,153,153, 91, 92, 92,124, 8,192, 46,212,113,207,180, 38,120, 76, 24,219, 53,114,196,
- 37, 38,140, 85, 94, 30,184,106,213,170,209, 35, 70,140,208,111,217,178,197,160, 84, 42,207,212, 83, 46, 45, 55, 55,247,243,138,
- 39,214,214,214,210,199,143, 31,127,108,111,111,207, 76, 74, 74,130, 86,171, 69, 98, 98,162, 9,101,183,166,170, 69,109, 32,219,
-190, 61,121,197,103,193,248, 64,203,162,184, 71, 48, 99,177, 80,202,225, 34,235,222, 37,236,141,136, 83,106,244,216,254, 54,235,
- 41,151,203,191,154, 59,119,238,184, 69,139, 22,241,221,221,221, 25,119,238,220,193,177, 99,199,180, 57, 57, 57, 3, 0,220,248,
- 53,245, 83,195, 48,153, 76,224,114,185, 0,128, 37, 75,150,128,201,100,114,114,114,114,184, 12, 6,131,199, 96, 48,204, 25, 12,
- 6,171, 52,249, 41, 76,202, 66,100, 23,202,145,150, 45,175, 85,207,104, 50, 29,187,127,255,254,252, 54,109,218, 48, 31, 62,124,
-136,220,220, 92, 36, 38, 38, 18, 35, 33, 71, 34,138,141,101,131, 18,181,245,111,159,185,181,205,176,214, 86, 60, 38,119,223, 42,
- 4,232,152,172,239, 76, 24,137,178, 92, 90, 0,176,151,193, 96,152, 1,200,111,222,188,121,207,103,207,158, 9,154, 55,111, 94,
- 28, 23, 23,119,129,193, 96, 56, 3,216, 95,157,166, 64, 32,200, 3,144,119,242,228, 73, 0,152,142,178,141,215, 54, 56, 56, 56,
- 51, 34, 34, 2, 33, 33, 33,217, 0,118, 2,128,200,202,102,136,175,216,140,193,253, 33, 4,157,180, 96,110, 55,145,106,163,174,
- 34,123,135, 94, 45,133, 76,112,246,172,196,123, 82, 31, 38,215,160,111, 21, 26, 26, 26,161, 86,171,181, 71,143, 30,213, 77,158,
- 60,153,149,144,144,240, 0,192, 77, 0, 39, 81, 62,198,146, 66,161, 80, 40,127, 42,111, 70,176,234, 28,163,245,166,107, 93, 7,
-224,219,231,207,159, 87, 22,149,126,254,252,185, 12,192,119, 40,203, 6, 63,184, 1,142,119, 69,121, 68,107,215, 91,174,204,155,
-154,124,127,127,127,193,179,103,207,204, 80,125, 17, 71,198, 91,104,254,142,234,106, 29,122,123,123,111, 45, 45, 45, 61,245,221,
-119,223, 29,103,177, 88,227,222,193,237,187,123,121,121, 21, 30, 62,124,216, 20, 22, 22, 70, 86,172, 88, 97,116,116,116, 44,196,
-239,199,104,253, 70, 51,128,203, 58,177,176,153,179, 50,114, 66, 87,242, 98,222, 16,114,115,124, 15, 50,195, 89,164, 12,224,179,
-142,189,227, 85,137,151, 88, 44,222, 43, 16, 8,148,150,150,150, 87, 0,116,126,151,125,100, 99, 99,115, 64, 42,149, 94,169,250,
-112,112,112, 56,101,103,103,247,181,173,173,237, 10,137, 68, 50,211,131,207,221, 50,175,169, 83, 73,244,176,230, 36,188,139, 29,
- 25,111,203,125,243,214,225,155,237,116,244,240,240,200, 63,120,240,160,233,236,217,179,100,233,210,165,166, 70,141, 26, 41, 81,
-203,184,182, 90, 35, 90, 18,214,177, 19, 35, 58,154,178, 7, 57,147,117,205, 44, 76, 61,173, 88, 53,205, 80, 28, 95,110,128, 39,
-213,165,233,233,233,249, 29, 33,100,223,234,213,171,247,225,215, 90,160,125, 67, 67, 67,131, 9, 33,193,161,161,161,193, 0,250,
- 3, 64,128,152,121,240,208,208,118,198,140,247,157,200,151,205, 68,198, 0, 49,243, 96,181,145, 76,107,246,233,159,167, 13, 50,
-101, 78,235, 66, 86,121, 9,141, 29,173,121,191,112,185,220,121, 40,139, 56,183, 7,192,165, 87,205, 84,147,106, 82, 77, 26,209,
-250,203, 25,175,122, 33,181,182,182,222,219,164, 73,147,227,238,238,238,199, 69, 34,209,102,148, 13,154,111,232,142,240, 88,179,
-102,141, 82, 44, 22,183,254, 3,119,174, 61, 0,103,252,190,112,238, 31,214, 97, 62,119,196,156,132, 69,163, 30,127,238,136, 57,
- 85, 94,110,223,172, 89,179, 47, 81,150,205,251, 93, 59,161,187,181,181,245, 14,107,107,235,244,242,177, 89,238,245,209,108,199,
- 98,141,235,201,103,221,233,204,101,102,245,228,179,111,191,199, 98,141,253,155, 30,128,181, 77,182,168, 73,211,197,214,214,118,
-139,181,181,117,134,173,173,237,142, 6,154,172,223,104,182, 22,192,177,151,132,117,186,179, 5, 67,211, 75,204, 58,217,206,188,
-230, 73, 29, 13, 88,119,255,144,144,144, 15, 9, 33, 31, 58, 57, 57, 5, 85, 49,254,190,171, 86,173, 10, 36,132, 4, 86,100,128,
-111,111, 14,251, 30, 18,214,225, 46,150, 12,121, 15, 9,235,112,123,115,216,215,212,206,158, 18,214,177, 46,150, 12,121,128, 37,
-243,176, 27, 15,141,232,201,156,106, 82, 77,170, 73,141,214, 63,195,104,209, 14, 67, 53,169, 38,213,164,154, 84,147,106, 82, 77,
-106,180,170, 55, 86, 85, 31,149,119,216,216,116,219, 80, 40, 20, 10,133, 66,161,188, 19, 53, 38, 44,101,212,226, 74, 27, 50,176,
-253,109,156,109, 56,213,164,154, 84,147,106, 82, 77,170, 73, 53,255,117,154,117,105,255,175, 39,214,253,173,161, 97, 85,170, 73,
- 53,169, 38,213,164,154, 84,147,106,254,107, 97,210, 77, 64,161, 80, 40, 20, 10,133,242, 78,248,151,255,125, 51,113,105,245, 99,
-180,216,237, 87,103, 27, 12, 6,123, 0, 96,179,217, 57,165, 15, 86, 56,214,166,206, 1,122, 27,202,202,239,128, 13, 76, 55, 0,
- 87,170,209,188, 98, 48, 24,172,202, 53, 11, 75, 31,172,232, 95,171,102,251,213,151,170, 46,111,120,176,162,239,155,203, 16,128,
-197,105,191, 58,227,141,182, 58,213,119,171, 48,240,155,156, 88,127, 90, 59,255, 46,154,255,102, 56, 29, 86,103,151,150,150,245,
- 35, 14,135,157,163,191, 95,123, 63, 50,235,176, 58,163,234,242,165,247, 87, 56,212,166,105, 46,224,229,123, 58,219,109,174, 77,
- 51, 41, 35,111,129,166,168,196,166, 54,205,134, 30,155,174,142,142,189,141,229,199, 38, 11,152,158,158,153,121,229, 47,214,151,
-218, 1, 88, 1,192,178,202,107,209, 0, 62,165,189,146, 66,161,252,205,140, 86, 20,202,234, 28,126, 95,110,182,190,175,209,104,
- 25, 12, 6,123,217, 79,193,208,104,129,222, 19, 87,219,123, 12,219,245,187, 66,201,134,146, 66,174, 60,246,168, 47,171, 84,105,
-101,199,214, 91,102,100,100, 48, 0,128,193, 96,252, 23,128, 91, 53,154, 86,178,159,130, 81,164, 3, 2,198,132, 90,185, 1,150,
-185,102,102,255, 17, 8,133, 61,139,139,139, 91, 2,128, 64, 32,136, 45,214,104,174,217,233,245,155,222, 92,190,166, 53,171,218,
-214, 94, 19, 86,219, 55, 27,182,107,174,209,100,226,190,126,248, 93, 64, 73, 94, 2,155, 99,208,238, 92, 6, 92, 8,174,198, 84,
-213,160,247,235,247,126,176,212,134, 3,244,226,242,249,173, 37, 86, 86,221, 76,132, 52, 55,153, 76, 12,163,193,240, 84,169, 80,
-220, 52, 25, 12,143, 13, 58,141,141,236,204,151,166,218,218,249,230,186,124, 0,176,127, 2,130,132, 34, 81, 79, 22,135,211, 25,
- 0,140,165,165,119, 52,106,245,181,225,192,137,250,172,123,125,183,207,219, 46,255,111,163,180,212, 96,159,124, 41, 24,218, 82,
-192,127,228,151,246,126,227,126, 56, 12, 0,186,156,199, 14,234,132, 51, 29, 0, 64,232, 25,120,159, 39,245,207, 6, 0,246,171,
- 76,251,248,176,229,208,150, 2,205, 3, 67,237,235,210,156,188,234,152,205,162, 25, 35,120, 0,112,249,228,215, 77,175,158,250,
-118, 32, 0,244, 26, 49,235, 66,191,145,115,226, 1, 96,195,247,167,108,142,124, 57,170, 86,205,250, 29,155, 10, 51, 69, 79,238,
- 8,153, 0, 0, 32, 0, 73, 68, 65, 84, 66,152,151, 78,153, 41,113, 21,178,165, 9, 9, 9, 76, 0,112,114,114,170,215,177,233,
- 2,136, 51,129,217, 76, 22,171,155,167,151,151, 63, 0,146,244,226, 69,148,209, 96,184,229, 8,236,252,131,251,210, 92, 66,126,
-155,156,149,193, 96,208, 14, 73,161, 80,254,110,156, 43, 55, 87,231,126,119, 49, 91,211, 39, 52, 90,224, 70, 34,208,189,163, 31,
-102,140,123, 95, 84,245,189, 19,187, 66,221, 18, 30,254,220,108,207, 15,155,152,126,126,126, 72, 78, 78,174, 87, 43,138,116,192,
-245, 4, 0,242,103, 22,133, 66,225,139, 45, 27, 55, 90,246,237,219,151,237,228,228, 4, 6,131,129,172,172,172,142,225,225,225,
-237,230,207,159,255, 17,228,207, 10,139,116, 80, 93, 79,168, 91,183,162,173, 45,155, 54,194,138, 57,163,196, 0,176,108,226,206,
-118, 15,159,103, 91,191,120,241,162,247,226,197,139,243, 89,215,174,125,107, 11,236,203, 6,210,234,211,206, 3,103,239,243,197,
-153, 63,122,140,159, 51,231,164,151,151,151,200,221,221,157, 97, 97, 97, 1, 22,139,133,194,194, 66,183,152,152,152,129, 15, 30,
- 60,208,132,223,248, 47, 55,242,193,144,164, 28,126,135,146,122,173,123,113, 6,255,178,133, 69,236,132,225,195, 93, 70,141, 26,
-197,247,244,244, 4, 0,188,120,241,194,251,196,137, 19, 99, 78,158, 60,185, 10,197, 25,134, 34, 29, 74,234, 90,247, 74, 77, 0,
-124,160,179,196,222,126, 60,139,195,105,105, 48, 24,156,203,163, 13,175,141,165,165,177,242,156,156, 67,111, 46, 79,249, 61,218,
- 82,224, 89, 38,208,167,155, 63, 38,140,232, 35, 4,128,197,163,215,116,124,245, 50,209, 76,167,211,161,169, 79,243, 46, 95,124,
-185,249, 18,152, 76, 28, 60, 21, 94,185,124,125, 52,163,159, 37, 35,248,139, 45,200,120,114,162,163, 81,145,216, 83,165, 84,176,
- 0,192, 82, 44, 30,113,226,232,143,215,156,124,131,238, 37,230,233,235,165, 89,219,177,121,241,232, 14,199,244,152,107, 45,190,
-185,188,151,227,230,230,134, 39, 79,158, 52,236,216, 84, 60,183, 48, 57, 58, 62,221,244,217,103,210,128,128, 0,136, 68, 34,176,
-217,108, 24, 12,134, 62,183,110,221,234, 19, 28, 28, 60, 11,138,231,154,250, 30,155,245, 96, 19,131,193,232, 57,121,198, 92,199,
-247,135, 6, 97,196,128, 46,180, 35, 82, 40,148,191, 27, 21,209,171,170, 51, 15,191,175,213,104,177,217,236,156,190,147,214,218,
-119,235,208, 10, 15, 31,199, 43, 82, 82, 51,213, 21,239, 21,196,158,104, 58,180,139,115,139,136,136, 27,208,106,181,184,115,231,
- 14, 30, 63,126,140,151, 47, 95, 98,230,204,153,218,242, 91,135,213,105, 22, 6,140, 9,181,130, 34, 65,228,205,125,222, 56, 60,
- 46,142, 85, 82, 82,130,136,136, 8, 20, 22, 22,130,203,229,194,197,197, 5,253,250,245, 99,199,197,197, 89,247,238, 59, 64, 28,
- 48, 96,108, 50,196,222,106, 54,155, 93, 88, 83, 29, 17, 54,155,157,211,123,226,106,251, 22,222,141,240, 34, 37, 67,177,226,203,
- 61,106,147,137,176,147, 94,190,210,223,184,113, 3,254,254,254,184,114,229,138, 77, 65, 65,193,202,157, 59,119,174,224,172,255,
-102, 91,169, 46,127, 33,106,214, 43, 12, 24, 19,106,101,147,115,220,253,234,197,211,102,177,177,177,102,223,125,247, 29,242,243,
-243,193,229,114, 33,145, 72, 32,149, 74,209,180,105, 83,198,178,101,203, 68,129,129,177,248,100,122,144,187,222, 99,218,243,154,
-218, 89,185,238,234, 87,230,182,202,203,158,167,206,157, 99,118,237,218,245, 55,151,237, 77,154, 52, 65,255,254,253,249,227,199,
-143,247, 28, 53,102,156, 41, 96,208,228, 23, 16,185, 23,213,169,169, 73, 19,216, 20,221,117,234, 51,102,204,153,208,208, 80,137,
- 84, 42,133, 80, 40, 4, 0, 40, 20, 10,151,148,148,148,142,171, 86,173, 26,121, 63,250, 40, 59, 32, 48, 45, 3, 66,215,226,218,
-182,231,191, 21, 14,135,157, 83, 17, 69,178, 16, 10, 10,211,210,179, 53, 0,160,211,233,160,211,233,160,213,106,241,241,172,153,
-172,233, 35,219,123,185,119,155,251,232,229,235,236,130,230,225,247,172, 43, 62, 91, 90,135, 38,187,232,165, 92,158,250,203,244,
-224,207, 62,147, 58, 56,252,122, 71,240,224,129, 3,172,130,130,130, 62,193,193,193, 45,136,121, 15,121,243,192, 80, 73,109,154,
-181, 29,155,242,248,115,141,191,152,211,191,245,174, 47,195, 96, 52, 26,113,247,238, 93, 68, 68, 68, 96,243,230,205,228,194,133,
- 11, 10, 75,161,112, 58,106, 61, 54,159, 91,116,117,204,242, 88,191,254, 36,131,199,227,225,231,159,127, 70, 92, 92, 28,152, 76,
- 38,252,252,252, 48, 97,194, 4,244,233,211, 71, 58, 99,198, 76, 18, 48, 96,116, 18,196, 62,170,119,236, 75, 76, 0,115,151, 6,
-175,119,156, 56,109, 54, 54,124,177,140, 26, 45, 10,133,242,119,142,102,213,152,226, 1, 97, 97, 97,164,252,209, 29, 0, 8,192,
-108, 50,108,215,145,227,145,166,115, 77,134,237, 58, 66, 0, 38, 1,152,150, 64,163, 54,109,218,148,202,229,114,242,224,193, 3,
-242,241,199, 31,107,182,109,219,118,237,220,185,115, 39, 12,122,253,110, 39, 71,199,175, 72, 13, 3,236, 9,192,116, 7,196,230,
-230,230,185,169,169,169,228,252,249,243, 36, 36, 36,132, 28, 58,116,136, 92,184,112,129,132,135,135,147, 11, 23, 46,144, 35, 71,
-142,144,232,232,104, 18, 31, 31, 79,132, 66, 97,174, 59, 32,174, 69,147, 69, 0, 86,211, 97,223, 45, 60,249,176, 52,212,103,216,
-174,249, 4, 96, 89, 1,205,218,180,105, 99, 60,113,226, 4, 57,120,240, 32,249,225,135, 31, 72,116,116, 52,201,203,203, 35,108,
-158, 48,183,226,115, 53,181,147, 0, 76,103,103,231, 92,185, 92, 78, 92, 93, 93, 9,151,203, 37, 14, 14, 14,164,105,211,166,164,
- 99,199,142,100,224,192,129,100,220,184,113,100,229,202,149, 68, 46,151, 19, 62,159,159, 93,241,185,154, 52,253, 1,129, 80, 40,
- 76,149,201,100,164, 38,138,139,139, 73, 94, 94, 30,185,116,233, 18, 17, 10,133,169,254,128,160, 54, 77, 1,208,214,215,215, 55,
- 55, 47, 47,143,232,245,122,146,154,154, 74, 98, 98, 98, 72, 92, 92, 28, 73, 77, 77, 37,197,197,197,149,218,241,241,241,196,195,
-195, 35, 87, 0,180, 37,116, 18, 68,141,125,233,205,135,155,131,195, 64,169, 84, 90,124,242,228, 73,242,250,245,107,178,127,255,
-126,194, 4,214,188,185, 92,109,154, 92,160, 95,215,174, 93,141,119,239,222, 37,143, 30, 61, 34, 75,150, 44, 33,253,251,247, 39,
- 3, 6, 12, 32,193,193,193, 36, 61, 61,157,164,167,167,147,129, 3, 7, 26,185, 64,191,186,250,103,117,199,166, 24,112, 11, 12,
- 12, 44,214,235,245, 36, 41, 41,137,180,108,217, 50,157, 5,140, 23, 2, 45,186, 3,188,186,250,167, 51, 96,229,232,232,152,121,
-247,238, 93,114,234,212, 41,226,238,238,158,203, 2, 38, 91, 2, 77, 44,129, 38, 44, 96,114,147, 38, 77,114,239,222,189, 75,242,
-243,243,137,155,155, 91,166, 51, 96,245, 14,125,137, 9, 96,239,210,224,245,228,121,186,134, 44, 13, 94, 79, 0,164, 18, 66, 8,
-170, 25,227, 73,161, 80,254,249,188,233, 69,254, 41, 84,158, 36, 3, 3, 3, 25, 0,174,215,182,112, 49,139,181,118,195,134, 13,
-236,146,146, 18,236,217,179, 71,245,193,200,145,199,187,119,235,150,212,216,221, 93,206, 96, 50,235,172, 54,156,203,227,205,219,
-176, 97,131, 68,167,211, 33, 50, 50, 18,237,218,181,131, 84, 42,133, 72, 36,130, 72, 36,130,189,189, 61,124,124,124,144,147,147,
- 3, 11, 11, 11, 44, 90,180, 72,156,203,227,205,171, 75,215,100, 34,108, 0, 48,154, 76, 92, 51, 96,134,199,123,239, 69,174, 90,
-181,138,105, 99, 99, 3,107,107,107,136, 68, 34,196,197,197, 65,167,211,193, 92, 96, 94,175, 36,173, 76, 38,147, 41, 18,137,112,
-245,234, 85,204,157, 59, 23,157, 59,119,134, 68, 34,129,133,133, 5, 90,182,108,137,126,253,250, 97,250,244,233, 72, 74, 74, 2,
-163, 30,131, 74,158,178,217,179,167, 79,159,110,239,239,239, 95,237,251, 37, 37, 37,144,203,229,200,205,205,133,139,139, 11,130,
-130,130,236,159,178,217,179,107,210,179, 1,164, 46,222,222,103, 30, 60,120, 96, 43, 20, 10,113,240,224, 65,156, 62,125, 26, 23,
- 47, 94,196,249,243,231, 17, 22, 22,134,159,127,254, 25,185,185,185, 0, 0,111,111,111, 28, 59,118,204, 86,100,111, 31,102, 3,
- 72,233, 33, 93, 63, 94,101,103, 95,110,153,149,101, 59,126,220,184,155,106,181, 26,227,199,143,199,218,117,235,150,113,128,249,
-245,249,188, 15, 32,182,118,116,220,183,126,253,122,102, 86, 86, 22,134, 15, 31,158,183,105,221,186,169, 81,151, 46,121,202, 46,
- 94,244, 92, 27, 26, 58,181,123,247,238,121,233,233,233, 56,112,224, 0,211,193,205,109,159, 15, 32,110,104, 59, 85,192,220,173,
- 91,183,242, 75, 74, 74,208,183,111,223, 36, 83,108,172,143, 1,248, 81, 13,196, 93, 7,244,117,125, 62, 19,152,189,104,209, 34,
- 41,143,199,195,127,254,243,159,188,162, 87,175, 90, 25,128, 31, 20, 64,138, 2, 72, 49, 0, 63,168,146,147, 91, 77,156, 56, 49,
-143,199,227, 97,203,150, 45,210,204, 95,139,110,215,151,118, 0,206, 0,184, 1, 32, 99,242,140,185,147,253,219,119,194,129,221,
- 59,241,101,232,226,125, 0, 62, 96, 48, 24,135, 0, 44,164, 61,143, 66,249,119, 82, 31, 47,242, 23,165,198,146, 59,236,170, 78,
- 18, 64,143,218, 84,172,108,108,218,181,106,213, 10, 17, 17, 17,240,245,245,125, 32,145, 72, 12,102, 60, 30, 56, 28, 14,136,169,
- 78,159, 5,129, 80,216,187, 79,159, 62,236,123,247,238,193,195,195, 3, 2,129, 0, 28, 14,231, 55, 15, 51, 51, 51, 56, 58, 58,
- 66,169, 84,162,119,239,222,156,237,219,183,247,134, 86,251, 69,157, 63,136, 9, 49,162,220,123,235,199,253,119,255,190, 38, 1,
- 1, 1, 80, 40,148, 48,153, 76, 48, 55, 55,135, 78,167, 3,155,205, 46,187, 5, 84, 74,148,245,217, 98, 70,163,209,200, 98,177,
-224,225,225,129,181,107,215,162,164,164, 4,102,102,102, 0, 0,165, 82, 9,185, 92,142,152,152, 24,164,164,164,160,252, 42,188,
- 86, 44,196,226,247, 71,141, 26, 85,109,193, 95,173, 86, 11,133, 66, 1,133, 66, 1,185, 92,142,146,146, 18,116,234,212,137,123,
- 46, 44,236,125,228,231,111,170,246, 51,124,254,200, 3, 7, 14,216,115,185, 92, 20, 23, 23, 67,165, 82, 33, 45, 45, 13,175, 94,
-189, 42,201,201,201, 49, 88, 88, 88, 48,221,221,221,153, 60, 30,143, 55,108,216, 48,134, 82,169, 4,131,193, 64, 96, 96,160,205,
-225,131, 7, 71, 65,167,219, 76, 15,233,250,113, 25,208,182,213,233, 6,119,104,223,254,234,131,135, 15,253,231,205,155,135,232,
-232,232,245,230, 71,143,222, 40, 2, 30,215,246,217, 36, 96,246, 87, 85, 12, 12,121,245,202, 87, 15,228, 86, 89, 36,197, 61, 57,
-249,226,196,137, 19,159, 68, 71, 71,219,110,217,178, 69,250,193,240,225,179, 1,172,105, 72, 27, 45,196,226,247, 28, 29, 29,113,
-225,194, 5,164,190,124,185,216, 0, 20, 55,232,138,139,197,234, 26, 16, 16,128,159,127,254, 25,233,175, 94, 45, 54,252,182,141,
-101, 23, 74, 64, 46, 59, 41,105,241,190,125,251,246, 78,153, 50, 5, 44, 54,187, 43, 12, 13,186,113,248,187,129,239, 83,102,206,
-195,190,239,183,239, 3, 48, 13,128, 9,192, 3,218,227, 40,148,127,119, 84,171, 46, 47,242, 55, 50, 91,223, 55, 56,162,101,111,
-111,239, 44, 18,137,144,145,145,129,230,205,154,229,240,120, 60,112, 57, 28,240,185,220,122,181,160,168,168,200,215,201,201, 9,
- 10,133, 2,182,182,182, 48, 51, 51,171,124,112,185,220,202,255, 45, 44, 44,192,100, 50,225,230,230,134,162,162, 34,223, 58,117,
-179, 99,236,143,110,159,245,241,221, 27, 23,154, 12, 31, 62, 2, 86, 86,214,112,117,117,129,189,189, 61, 4, 2, 1, 92, 93, 93,
-225,233,233, 73, 54,109,218, 4,115,123,191,122,157,200,171,154, 39, 54,155, 13,163,209,136,236,236,108, 60,127,254, 28,209,209,
-209,184,123,247, 46, 30, 61,122, 4,149, 74,133,122,248, 44, 20, 21, 23,183,102,179,217,213,154, 44,185, 92, 14,185, 92, 94,105,
-180,114,115,115,145,146,146, 2,181, 70,211,166, 22,211, 59,162, 85,171, 86, 44, 0, 16, 8, 4,104,211,166, 13,118,237,218,101,
- 56,123,250,244,232, 22,119,239, 90,187, 94,186, 36,249,239,119,223,141, 14, 10, 10, 50,222,187,119, 15, 74,165, 18,207,158, 61,
-131,157,157, 29,155,203,231,143,162,135,115,195,144, 1, 26, 91,149,106, 64,231,206,157,147, 21, 10, 5, 54,110,220,200,228, 88,
- 88,124, 31, 90,195, 45,190, 74, 88,172, 46, 1, 1, 1, 56,115,230, 12, 50, 94,189, 90,242,170, 26, 3,243, 10,200, 77, 77, 74,
- 90,178,111,223, 62,244,235,215, 15, 12, 54,187,193, 3,149, 58,118,236,216,202,100, 50,225,201,147, 39,144, 0,247, 27,250,121,
- 79, 47, 47,255,138,200,175, 16,184, 89,211,114, 66,224,102, 84, 84, 20, 4, 2, 1,154,183,104,209,182,129, 95,179,137,193, 96,
-100, 78,153, 57, 15,167, 46,222, 6, 0,236,251,126,123,118, 21,147, 69,161, 80,104, 68,235,239, 26,209,170, 48, 86, 85, 31,248,
-141,209,170,167,249, 0, 0,112, 56, 28,112,121, 60,112,185,220, 50,131,196,227,213, 91,131,193, 96,128,207,231, 87, 26,171,170,
- 6,171,234,255,230,230,230,245, 50, 48, 0, 80,152,120,177,219,180,169, 83,184, 60, 30, 15, 58,157, 22,132, 16,240,120,124, 72,
- 36, 18,120,120,120, 64,169, 84,162,115,151,238,218, 52,185, 89,152, 77,243, 97,209,111,179,245, 12, 6, 3, 52, 26, 13, 10, 11,
- 11, 81, 80, 80, 0,165, 82,137,226,226,226,122, 79, 69, 55,153, 76,172,180,180, 52,252,248,227,143,200,207,207, 7, 80, 54,208,
-186,194, 92, 85,252, 77, 78, 78,198,193,131, 7,241,242,229,203, 6,237,159,110,221,186, 33, 44, 44,140,213,163,119,239,221, 87,
-220,221, 51,174,184,187,103,244,232,221,123,247,153, 51,103, 88,206,206,206, 72, 73, 73, 65,100,100, 36, 10, 11, 11, 65, 8,161,
-243,231,223,130, 23, 64, 97, 81, 65,193,148,101,203,150, 17,145, 72,132,141, 95,125,213,122, 13, 48,182,190, 6, 70, 92,139,129,
- 17,191,155,129, 1, 33, 4, 38,147, 9, 70,163,241,173,214,141,193, 96, 48, 56, 28, 78, 67, 83, 43, 52,100,225,202,129,239,139,
- 86,174,197,249,159, 79, 84,188,158, 64, 77, 22,133, 66,249, 7, 80,227, 64,120,118, 21, 7, 89,249,183, 38,178,179,179, 95,107,
- 52,154, 38,238,238,238, 72, 79, 79,183,119,115,115,123,197,229,112, 96,198,229,130,193,172,219, 19,152,155,155, 63,201,200,200,
-232,226,236,236, 12,131,193, 80,105,170,222,188,117, 88, 17,165,121,244,232, 17,204,205,205,159,160,164,214,204, 9, 48,234, 10,
- 27,181,109,219,182, 50, 50, 36,145, 72, 32,145,136,193,227,241,177,124,249,114,211,150, 77,155,118,186,245, 10, 85,124, 56,127,
- 25, 89,182,102,247, 31,186,101,235,251,195,100,110,110,254,196,213,213,181,147, 88, 44,198,169, 83,167,144,146,146,130,194,194,
- 66, 20, 21, 21, 65,171,213,162,168,168, 8, 58,157, 14,124, 62, 31, 45, 90,180,128,165,165, 37,194,195,195,159, 64,171,173,222,
- 92,230,231,159,122,242,228, 73,167,246,237,219, 87, 70, 84,122,246,236,201,232,217,179,167,109,101, 20,173,168, 8,121,121,121,
-120,240,224, 1,194,195,195,193, 96, 48,144,144,144, 96,212, 22, 23, 31,161,199,196,219, 81, 2,220, 97,237,219,183,247,163,143,
- 62,154,218,165, 75, 23, 24,129,129, 0, 14,254, 63, 26, 24, 0,192,221,187,119, 99,140, 70, 99,151,166, 77,155, 66, 14,116, 0,
-240,115,131, 76,100, 98, 98,148,193, 96,232,221,186,117,107,156, 58,126,188, 27,128,148,234,150,211, 0,221,252,253,253, 81, 92,
- 92,140,103, 79,159,202, 26, 96,178,118, 47, 13, 94, 63,121,226,180,217, 56,176,123, 39,246,125,191, 61,109,239,174,109,174,168,
-199,248, 49, 10,133,242,175,138,102,213,233, 69,254,162,204,168,201,124,177, 27,162,162, 40, 44,148, 69, 69, 69, 53,105,219,182,
- 45,118,239,222,221,190,115,167, 78,175,205,184, 92, 3,215,204, 12,204,122,252,144, 20,107, 52,191,252,242,203, 47, 29,134, 13,
- 27,198,190,119,239, 30,164, 82,105,165,209,170,248,203,102,179, 65, 8,129,185,185, 57,126,250,233, 39,125,177, 70,243, 75,157,
-209, 34,163,201,200, 44, 55,122,132, 16,200,229,114,152,153,153, 97,243,230, 45,216,177,105,211, 56, 35,112,194, 91,104,247, 25,
- 0,254,255,219, 15,116, 81,209,213,243,231,207,183, 91,181,106, 21,199,197,197, 5,114,185, 28,133,133,133,200,207,207,135, 82,
-169,132, 82,169, 68, 97, 97, 33,228,114, 57,248,124, 62,162,163,163, 75, 75,138,138,174,214,164,199, 43, 41, 57, 57,105,210,164,
- 69, 81, 81, 81,142,108, 54, 27,165,165,165, 48,153, 76, 48,153, 76,208,235,245, 72, 76, 76, 68,108,108, 44,226,226,226, 80, 80,
- 80, 0, 14,135, 3, 22,139,133, 71,143, 30, 21, 10, 75, 75,143,235,232, 49,253,214,112,128, 83,183,110,221,154, 58, 97,194, 4,
- 56,185,184,116, 71,122,122,189, 12,204,233, 90, 12,140,226,237, 12,204,175, 6, 72,165,122,152,156,156,220,165, 71,143, 30,112,
-116,113, 89,223, 34, 61,253,202,211, 6,140,211, 50, 26, 12, 55,111,221,186,213,123,226,196,137,216,189,123,247,122,187,228,228,
-139,185,111,220,230,180, 3,236, 26,123,122,174,159, 60,121, 50, 46, 95,190, 12,163,193,112,179, 22,201,170, 25,223, 27, 77,158,
- 49,215,245,141,129,239,187, 24, 12,198, 28, 0, 27,105,143,162, 80, 40,255,228,136, 86,131,110, 29, 10,140,198,165, 11, 23, 46,
- 44,101, 50,153, 24, 49, 98,132,197,207,103,206, 4, 61,122,252,216, 35, 39, 39, 71, 98, 52, 26,235,212,178,211,106,183, 45, 92,
-184, 80,174,211,233,224,227,227,131,130,130, 2, 24,141, 70,176,217,108,176,217,108, 48, 24, 12, 48,153, 76,136, 68, 34, 68, 69,
- 69, 97,239,222,189, 74, 59,173,118, 91,157, 63, 18, 70,227,147,131, 7, 15,130,197, 98, 17, 62,159, 15, 6,131, 1, 54,155,141,
- 45, 91,182,228,236, 0, 78, 1, 0,139,201,212, 1, 0,147,201,168,239,232,221, 58,239, 91,114,185, 92,152,202, 38, 1,212,185,
-172,149, 86,187,117,195,134, 13,170,103,207,158, 65,163,209, 84, 70,223,212,106,117,229,224,122,185, 92, 14, 6,131, 1,141, 70,
-131, 51,103,206,168,172,180,218,173, 53,233,229, 3, 89,233, 9, 9, 67,218,183,111,159,159,156,156, 12,133, 66,129, 39, 79,158,
- 32, 60, 60, 28,199,142, 29,195,229,203,151,145,152,152, 8,131,193, 0,103,103,103, 16, 66,112,250,244,105,133, 65,165, 26,152,
- 15,100,209, 99,162,102, 26, 73,165,189, 29,236,237, 83,237,108,109,211, 27, 73,165,189,223,124, 95, 12,196,199,199,199,195, 96,
- 48,192,195,195,195,186,182,113, 90,196, 96,184,117,235,214, 45, 76,156, 56, 17,174, 77,154,172,115, 7,236,222, 92,198, 29,176,
-115,247,244, 92, 87, 97, 96,136,193,112,171,161,109,182, 0,182,127,246,217,103,197,102,102,102, 56,122,244,168, 71,169,151, 87,
- 28, 27, 24, 43, 2,154,245, 0,204,234,250,188, 35,176,115,229,202,149, 89, 12, 6, 3,135, 14, 29,178, 21,123,122,198,176,129,
- 73, 98,160,145, 24,104,196, 6, 38,137, 61, 61, 99,142, 30, 61,106,107, 48, 24, 48,127,254,252, 44, 71, 96,103, 45,146,115, 9,
- 33,131, 9, 33, 1,132, 16,215,189,187,182,225,252,207, 39, 42, 76,214, 52,148, 13,122,159, 0, 32,134,246, 56, 10,133,242, 79,
-166,218, 48, 20,187,253,234,108,128,216,119,239,232,135,135,143,159, 43,108,173, 44, 47, 85,188, 87, 16,123,162,105, 47, 95, 75,
-191,111,190,249, 6, 28, 14, 7,105,105,105,120,250,244, 41, 44, 45, 45, 49,110,220, 56,109,177, 74, 53,164, 74,173,195, 62, 0,
-194,203, 53,203,234,169, 41, 18, 68,158,236,232, 38, 23,207,135,177,196, 98, 49,212,106, 53,152, 76, 38,248,124, 62,204,205,205,
- 33, 16, 8, 16, 25, 25,137, 65,131,135, 26,115,205, 3,126, 77, 88,250,107, 61,181, 74,205,138, 92, 67, 29, 0,243, 40,224, 63,
-246, 78, 78, 11, 87,172, 88, 33,232,223,191, 63,204,204,204,224,210,200, 59,203, 99,192,198,237, 76, 38,195,144,158,175, 92,238,
-217,200, 73,252, 52, 33, 5, 0, 35,167,244,193, 10,167, 42,181, 14,127,215, 78, 55,221, 13,143,159,126,216,100,217,166, 77,217,
-120,116,185, 92,142,236,236,108,228,228,228, 64, 46,151, 67,163,209, 0, 0,194,194,194,112, 62, 34, 78, 89,236, 18,148, 84, 83,
- 59,127, 93,247,231, 22, 78,250,251,141, 15, 31,252,129,101,103,103,135,236,236,108,228,230,230, 66, 46,151,163,184,184, 24, 70,
-163, 17, 5, 5, 5,216,179,239, 7, 99,190, 40,224,101,101, 66,200,218, 52, 53,105, 2,107,245,109,103,255, 22,238,100,234,212,
-169, 22,150,150,150, 48,153, 76, 40, 44, 44, 68,106,106, 42,146,147,147, 17, 17, 17,161,201,145,235,160,177,237,155, 94,153,176,
-180, 26,205, 63,144,191,157,102,213,188, 85, 78,142,142, 25,175, 94,189,178, 55, 26,141,112,118,118, 54,200, 11, 10,214,113,129,
-203, 22, 64, 38, 0,146, 7,172,216,186,125,251,148,161, 67,135,226,189,247,222, 75,203,202,206,110, 92, 93, 95, 34, 0,203, 7,
- 16, 23,185,184,196, 62,120,240, 64,154,154,154,138,137, 19, 39,230,189,122,241, 98, 73,197,120, 45, 5,208,205,221,211,115,221,
-209,163, 71,109,155, 52,105, 2, 95, 95,223, 44,126,106,106,203,231,128,162,134,254, 89,227,177, 41,143, 63,215,120,214,240, 86,
-239,125,252,241,199, 48, 24, 12,136,136,136,192,253,251,247,241,234,213, 43,220,190,125, 91,110, 41, 20,142,174, 82,235,176,218,
-254, 57,208, 91,227,113,232,208, 65,134,153,153, 25,246,237,219,135,168,168, 40, 0,128,191,191, 63, 38, 79,158, 12,131,193,128,
-241,227, 39,144,115,207, 5, 73,181,245, 79, 0,173, 0,124,133, 50,147,247, 30, 33,132,207, 96, 48, 50, 0,184,162, 97, 99,178,
-104,255,164,154, 84,243,223,163,249,143,164,206, 90,135,171,191,133,248,183,101, 62,166,103,156,216, 21,202,238,218, 45,160, 89,
-104, 72, 48,179,125,251,246,112,117,117,133,191,191, 63, 82, 83, 83,121, 18,137,164,174,122,106,234,128, 1, 99,147,253,252,252,
- 36, 75,150, 44, 17,247,235,215,143,227,234,234, 10, 66, 8,162,162,162,112,234,212, 41,253,238,221,187,149, 69, 14,131,229,178,
-107, 63,170,235, 83, 79,237, 62, 80, 4,224,115,151,140,140,239,103,207,154, 21,220,166,109,219,169, 33, 33, 33, 76,145,185,128,
-179,118,249, 52, 62, 0,172,254,250,152,120,104,208, 56,108,245, 2,186,143,173,190,142, 92,213,118,166,166, 79,127,245,254,240,
-222, 94,255,153, 51,197, 56,106,212, 40,161,165,165, 37, 92, 93, 93, 97,101,101,133,164,164, 36,164,167,167,147,179,103,207,170,
-239, 62,138,231,156,190,252,240, 21, 95,236, 88,159,186,132,170,128,254, 31,188,124,255,253,247,173, 38, 77,154,100,209,174, 93,
- 59, 14,143,199, 3,143,199, 67,118,118, 54, 18, 19, 19,245,103,207,158, 85, 23,217, 15, 44,148, 93, 59,170,170,103,173,195,226,
-128, 49,161,137, 55,175,132,204,143,125,242,100,130, 9,104,173,215,235,157,141, 70, 35,131,201,100,102,154, 76,166, 39,122,149,
-106,175,214, 63,100, 11,173,117, 88, 63,140, 70,163,153,209,104,132, 92, 46,199,149, 43, 87,216, 47, 94,188, 88,241,248,241,227,
- 21, 25, 25, 25, 40, 45, 45,197,200,145, 35,225,239,239,143,107,215,174, 33, 55, 59,251,108,109, 90,207, 1, 5, 47, 61,125,242,
-244,233,211, 47, 28, 60,120,144,249,248,241, 99,219,125,251,246,237,169,206,192, 76,152, 48,193,148,157,154, 58, 89, 11, 40,106,
-233,159,181, 29,155,121, 23,143,238,120, 60,108, 68, 80,139,144, 85, 43, 56,157, 59,119,134,173,173, 45,186,117,235, 6,189, 94,
- 47,105,222,188,121, 93,199,166, 42, 96,192,232,164,214,173, 91, 11,183,108,217, 34,157, 50,101, 10,230,204,153, 3, 0, 40, 46,
- 46,198,229,203,151, 49,127,254,252,172, 84,118, 7, 77, 93,253,179, 60, 82, 85, 97,192,110, 0, 8, 0,144, 4, 58,240,157, 66,
-161,252, 51,169, 40, 42,237,136,178,194,210,231, 80,118,113, 94,119,173,195,155,247, 99, 80,181,204, 71, 25,142, 79, 13,110,147,
- 94,204, 92,184,206,151, 85,170,180,226, 48, 74, 44, 19,226,227, 25,117,213, 60,172,172,167, 38,246, 86,219, 36, 31,105,191,118,
-245,234,121, 91,183,110,237, 93,145,194,193,220,220,252, 73,177, 70,243,139,157, 86,187,173, 72,236,253, 75, 67,107,243,165, 3,
-217, 0,102, 89,201,100,219, 3,135,142,220,192,183,246,224, 44, 91,179,187,132,197,100,234, 18, 51,114,177,213, 11, 16,214, 99,
-130,100,145, 14,136,149, 59, 26,178,109,130,158,175,252,236,179,255,172,254,252,243,246, 34,145,168,187,222, 96,240, 54,153, 76,
-128,201,148, 80,164,209,220, 32,122,253, 3,173,255,170, 77,124,177, 35,169,119, 93, 66, 73,115,149,245,203, 19,237,247,239,221,
- 59,247,248,241,227,191, 91,119, 27,173,118,123,145,164,121,120,125,214,189,234, 50, 37,192, 29,228,228,220,169, 45,116, 73,107,
- 29,214,243,234,195,100,154, 97,101,101,117,160,119,239,222,252, 62,125,250, 96,208,160, 65,232,220,185, 51, 76, 38, 19, 8, 33,
- 80,169, 84, 56,118,236, 24, 54,108,216,144,208, 24,248,188, 46, 61, 45,240, 11,239,252,249,129,173, 91,183,222, 87,155,129, 41,
- 55, 89,117,142, 73,172,253,216,228, 37, 24,196, 67, 82,198,204, 94,235,165, 83,102, 74,108,204, 13,210,216,152, 39,204,250, 31,
-155, 62, 42, 99,212,177, 14, 35,135, 15,159,205, 98,179,187,149,207,128, 36,207,158, 62,149, 85, 20,149,134,255,228, 43, 13,236,
- 75, 21,185,235,232,192,119, 10,133,242, 79, 55, 90,131, 80, 54, 94,171,178, 36, 79,141,181, 14, 43,162, 62,108, 54, 59, 39,233,
-244,204,113,181,169,115,128,222,229,145, 44,212, 89,235,176,252,255, 20, 64, 5,173,246,139,223, 36, 35,173, 50,187,144,243,198,
-242, 13, 73,139, 88, 8, 60,135, 65, 27,136,156,167,192,153, 89,101,122,237, 87, 47,174,186, 78, 53,254,200,254,230,123,205, 10,
- 74,128,155, 80,171,111, 66,173,174,118,208, 46,135,109, 86, 80, 87, 59,223, 92,247, 84, 64,249,174,235,254,166,102,157,230,225,
- 29,182,231,191,141,215,121,121,167, 1,136, 92,194,194, 28, 46,134,133,141,250,207,130, 5, 35, 29,157,156, 60,109,109,109,173,
- 44, 44, 44,152,247,238,221, 75, 54,148,148,108,111, 3,236, 47,143,166,214,137, 22,248,197, 39, 53,181,229, 7,195,135,207,102,
-176,217, 93,171, 26, 24, 98, 48,220,246, 0,118,214, 22,201,122,219, 99,211,149,231,216,187, 60,146, 5, 22, 48,189, 62,125, 35,
-189,172, 29,107, 96, 48,172, 65,116,116, 53,125,190,193,125,105, 53,131,193, 80,129, 14,124,167, 80, 40,255, 92, 42,234, 29,158,
-251, 95,127,113, 31,170, 73, 53,255, 65,154, 44,148,205,162,163,219,147,106, 82, 77,170, 73, 53, 41,245,130, 77, 55, 1,133, 82,
-111,140,248,245, 54, 24,133, 66,161, 80, 40, 21, 84,140,205,170,202,247, 64,217,208,157,154, 92,105, 67,102, 19,188,141,179, 13,
-167,154, 84,147,106, 82, 77,170, 73, 53,169,230,191, 78,179, 46,237,191,227,108,198,138, 49, 89,149, 99,179,254, 87,208,176, 42,
-213,164,154, 84,147,106, 82, 77,170, 73, 53,255,233, 56,150,155,172,170, 15, 0, 13, 76, 88, 74,161, 80, 40,255, 84, 66, 66,192,
- 36, 4, 12, 66, 66,152,132, 28,103, 17, 18,196, 34, 4,239, 84, 10, 36, 40,168,250,100,182,159,140,179,178,160, 91,156, 66,249,
- 71,145,137, 26,138, 74,211, 49, 90,255,191,184, 73,165,210, 93, 0, 24, 89, 89, 89, 51, 0,164,210, 77,242,215,195,218,218,186,
-183,193, 96,128, 82,169,252,229,159,184,126, 45, 60, 49,156, 48,209,188,242, 5,130,212,103,137, 56, 80,221,178,205,189, 48, 17,
-140, 95,115,113, 49, 76,120,246,244, 5,126,106,192,215, 49, 7,246,113,221, 9, 0, 23,194,211,102,227,207,201,171,213,212,206,
-206,238, 18,155,205,102, 27,141,198, 89, 57, 57, 57, 97, 53, 27,161, 32, 22, 0,112,200,181,165,242, 44,251, 37,159,126,196,224,
- 20,105,247,202,181,197, 26, 5,139,195,122,201,227, 72,111,205,156,194,188, 80,168,238,244,180,186,207,159, 56,113,162,198, 42,
-222, 45,189, 48,144,105,108, 49,216,191, 85,114,210, 87,219,218,111,237,238, 97,203, 73, 78,123, 36, 90,255,157, 98, 23, 87,226,
- 62,120,226, 40, 70, 24,219,156, 49, 97,239,222,124, 53, 61,202,234,207, 90,192, 90, 15,248,114,120, 60, 87,163,193,224,192, 0,
- 8,139,205,206, 46,213,106,211,204,128,232,165,128,252,159,174,105,198,227,185, 24, 13, 6, 7, 0,248, 43,182,147,242, 91,106,
- 52, 90, 34,145, 40,146,201,100,186, 84, 45,134, 91, 81, 79,176,226,181,170,239, 49, 24, 12, 24,141,198,244,194,194,194,118, 13,
-248,126, 75, 0,163, 0, 84, 76, 81, 63, 12,224, 24,222,126,192,177,165,153,153,217, 66,161, 80,216,171,184,184,184, 37, 0, 8,
- 4,130, 88,141, 70,115, 85,175,215,127,245,150,186,108, 0, 31,136, 68,162,158, 76, 38,179, 39, 33,132, 65, 8,185,166, 86,171,
-175, 2, 56, 14,224,109, 50, 37, 8,236,237,237,215, 88, 91, 91,143, 93,186,116,105,190,141,141,141,207,252,249,243, 31, 22, 20,
- 20,252,152,151,151,183, 28, 13,168, 81,247, 39,227, 41,149, 74, 15,115, 56, 28, 86, 90, 90, 90, 79, 0,112,117,117,189,166,211,
-233,140, 57, 57, 57,227, 0,188,104,160,158, 16, 64, 71,145, 72,212, 78, 36, 18, 5, 24,141,198,230,229,245, 25,159,169,213,234,
- 8,189, 94, 31, 9,224, 30, 0,205, 95,232, 24,177, 96,179,217, 7,203,251,186, 55, 0,213, 63,237, 36, 64,152,104,254, 52, 54,
-206,167,210,120,181,108, 86,243,194, 12,184, 85,179,108,189,141, 86,175,238,142,131,135, 12,233,203, 4, 0, 93,233,133,193, 87,
-111,100,254,252, 7,175, 78,211, 17, 35, 70,220, 57,120,240,160,149, 86,171,197,140, 25, 51, 14,135,135,135,239, 84, 42,149, 75,
-107, 61,113,136,172,230,111,220,114,217,156,193, 96, 2,128,189,201,100,180,127,253,250,133,247,211,152, 59, 3, 98, 99,239,174,
- 45,142,187,122,207,196,224,204,212,163, 91, 92,125, 26,209,220, 3,129,131, 71, 14, 31,244,249,231, 33, 24, 59,122,108,163,216,
-216, 18,129,179,101, 18,183,160, 88,232,101, 99,103, 63,228,243,213, 39, 24,183,110,158, 30,114,112, 95,232,213, 41, 83,108,122,
- 81,179, 85, 47, 24,171,217,236,142, 98, 47,175,128,209,167, 79, 67,228,234,202,102,243,120, 76, 0, 48,104,181,174,234,180, 52,
-199,163, 67,134,116, 8,137,143,191, 30, 2,220,167,154,255, 47,154,148,134, 24, 45, 38,147,233,242,250,245,107,123,161, 80, 88,
-118, 50, 38, 4, 70,163, 17, 70,163,177,178,120, 49, 33,164,242,175,193, 96, 64,179,102,205,234,117, 69, 11,160, 23,128, 15,123,
-244,232, 17,244,213, 87, 95,113,124,125,125, 43, 74,134,116, 91,182,108,217,215, 81, 81, 81, 39, 1,236, 71, 89,242,198,250, 94,
-241,246, 23, 10,133,135, 54,110,220,104,217,183,111, 95,182,147,147, 19, 24, 12, 6,178,178,178, 58,134,135,135,183,155, 63,127,
-254, 44,141, 70, 51, 30,192,165, 6,108,159, 86, 22, 22, 22, 39,134, 15, 31,238,210,189,123,119,126,139, 22, 45, 96, 52, 26,241,
-232,209,163, 41,145,145,145, 99, 78,158, 60, 25,172, 82,169,130, 80,255,122,109, 12,145, 72, 52,201,210,210,114,205,170, 85,171,
-172,199,143, 31,207,141,137,137, 41,244,240,240, 96,220,186,117,203,238,216,177, 99,179,214,173, 91,247,129, 82,169, 92,174, 86,
-171,127, 64, 61,106, 40, 90, 88, 88, 68, 50,153, 76,151,250, 24, 97, 0, 13, 49,195,109, 26, 55,110,124,236,230,205,155,141, 83,
- 82, 82,140,195,134, 13, 59, 0, 0, 87,175, 94,245, 45, 45, 45,101,244,235,215,239, 66,122,122,250, 40, 0,143,234,185,238,126,
-214,214,214, 63,143, 29, 59,214,218,211,211,211,188,113,227,198, 12,161, 80, 8, 22,139, 5,133, 66,225, 20, 19, 19,211,231,254,
-253,251,197,225,225,225, 5, 90,173,118, 8,128,232, 6,236,167,206,246,246,246, 19, 56, 28, 78, 43,131,193,224, 12, 0,108, 54,
-251,117,105,105,105, 76, 78, 78,206, 65, 0,119,222,246, 0,113,112,112,216,177,102,205, 26,219,156,156, 28,178,110,221,186, 29,
- 42,149,106,210, 63,245,100,112,248,199,227,136,124,120, 31, 40, 43,155,195,168,166,255, 49, 0,152,125,250,233, 2,180,123,175,
- 3,198,141,253,160, 78,205,247,123,187,108,228,112,205,108, 74, 74, 74,238, 40,138,180,199,133,230,252, 81, 99,199, 4, 38, 0,
-192,133,139,215, 71,181,111,111,117, 77,108,206,251,128,207,231,119, 46,213,233,243,207,255,146,254, 89, 67, 76,149,179,179,243,
- 37, 43, 43, 43,243,130,130,130,172,220,220,220,111, 7, 15, 30,188,122,255,254,253, 86,201,201,201, 72, 75, 75,195,188,121,243,
- 68,233,233,233,179,163,163,163,239,234,116,186, 26, 35, 91, 42, 85,193,182,101, 75,134,174, 18,139,109, 89, 66,115, 75, 88,136,
-173,225,225,217, 26, 29, 59, 15,198,192, 65, 83,145,152, 16,213,113,255,190,207,163, 94,191, 14,255, 82,100,221,100,181, 92,222,
-184,198,243, 82,139,166,232, 62,100,120,153,201, 90,181, 42, 4,241,113,113,170,148,151,204, 79,206,157,102,155, 15,236,221,140,
-103,208,101,165,220,186,121,186,113,215,110,195, 0,160,221,193,125,161, 87, 63, 25,103,213,123,199,225, 66, 21,253, 73,170,249,
-220,249, 57,135, 51,169,255,150, 45,246,254,179,102,153,169, 95,190,212, 39,125,247, 93, 81,118, 68,132,145,205,227, 17,215, 1,
- 3, 24,118, 61,123,242,103, 61,123,102,118,123,221,186, 0, 78,104,168,199,114,189,254, 16,213,252,159,106,254,219,169, 24, 4,
- 95,117,246,225,247,181, 26, 45, 6,131, 1,161, 80,136,163, 71,143,130,195,225,128,205,102,131,195,225,212,248,191,155,155, 91,
-125, 26, 50, 66, 42,149,126,189,115,231, 78,135,254,253,251,131,207,231, 87,190,193, 98,177,208,183,111, 95,244,233,211,135,147,
-145,145, 49,230,232,209,163, 99,214,174, 93,155, 45,151,203,231,160,188, 48,116, 45,244,244,241,241, 57,117,249,242,101, 65, 73,
- 73, 9, 34, 34, 34, 80, 88, 88, 8, 46,151, 11, 23, 23, 23,244,235,215,143, 29, 23, 23,103,221,183,111,223, 83,241,241,241,129,
- 0,174,213,163,173,237,236,237,237,111, 28, 63,126,156,223,186,117,107, 70, 98, 98, 34,252,253,253, 1, 0, 10,133, 2,195,134,
- 13,227,143, 31, 63,222,115,204,152, 49,247,114,114,114,186, 3,136,172, 67,175,173, 84, 42,253, 97,248,240,225, 78,107,215,174,
-181,180,176,176, 64, 74, 74, 74,166, 84, 42,245,174,216,222, 99,198,140,225, 14, 30, 60,216,113,195,134, 13,219, 78,156, 56,241,
- 89, 78, 78,206, 36, 0,178, 90, 93,107,185, 33, 54, 55, 55, 71,118,118, 54, 14, 31, 62,140,217,179,103,131,197, 98, 33, 39, 39,
- 7,199,142, 29,195, 39,159,124, 82, 97,104,234,101,134,205,205,205,251,120,121,121,237,185,122,245,170,139, 68, 34,129,147,147,
- 19,115,229,202,149,173, 60, 60, 60, 4,141, 26, 53, 98,101,102,102,226,212,169, 83, 30, 19, 38, 76,248, 57, 53, 53,117,138, 86,
-171,173,243,150,154,131,131,195,222,115,231,206,185,197,198,198,226,187,239,190, 67, 65, 65, 1,184, 92, 46, 36, 18, 9,164, 82,
- 41,188,189,189, 25, 75,150, 44, 49, 31, 60,120,176,249,156, 57,115,246,234,116,186, 54,245,216, 71,173,237,237,237,119,245,236,
-217,211, 35, 52, 52, 84, 34,149, 74, 81,113, 97,160, 80, 40, 92, 82, 82, 82, 58,174, 90,181, 42, 40, 50, 50, 50, 57, 39, 39,103,
- 38,128,199, 13, 60,112,218,180,104,209, 34,112,216,176, 97,172,204,204, 76, 28, 60,120, 48, 80,165, 82,181,105,128,185,252, 91,
- 17,249,240, 62,102,124, 60, 79,237,228,234,106,118,249,210,158, 17, 39,126,106,250, 80, 34, 40, 43, 72, 45, 47,134, 62,104,120,
-252,123,253,250, 79, 53,123,127,208, 48,245,247,223,108, 19,213,199,104,113,184,102, 54,135, 15,109, 78,189,121, 43,178,213,149,
-240,251, 3, 70, 12, 25, 66,204,204, 36, 30, 0,240,217,252, 79, 57,167,206,156,217,215,183, 79,135,140,110, 93,219,165,142, 27,
-191,192,173, 1,205,109,218,180,105,211,235, 81, 81, 81, 14, 60, 30, 15, 5, 5, 5, 54,223,127,255,253,230,174, 93,187, 50,147,
-146,146, 16, 23, 23,135,151, 47, 95, 66,161, 80,160,111,223,190, 34,153, 76,246, 45,128, 26,141,150,158,217,107,141, 83,163,210,
-237, 54, 2, 97, 99,189, 81,105, 79, 74, 51, 91, 92, 57,119,197,239,200,193, 98,127, 7,199,102,222, 31, 78, 14,198,231,171, 79,
-114,126, 60,188,126,213,255,177,119,221, 97, 81, 92,237,247,204,246, 70,135,165, 10, 22,164, 23, 27,106,108,177, 87, 48, 26, 91,
-138, 70, 19, 53,150,152, 88, 99, 52, 26, 53,166,104,140,198, 22,141, 45,137, 5, 19, 99, 55, 88, 81, 17,236, 5, 81,233, 40,210,
-100, 23,118,105,187,203,246, 50,243,251,154, 58,214, 45, 0, 0, 32, 0, 73, 68, 65, 84, 67,150, 15, 9,176,139,229,251, 37,249,
-246, 60,207, 62, 59, 59, 59,115,246,222,185,119,239,156,121,239,123,223,247,194,249,223, 1, 90,235,198, 51, 2, 80,232,254,249,
-146,197,144, 43,180, 24,255,206, 84, 76,120,103,170, 43, 5,157, 23,101,210, 8,116,234, 74, 39,123, 86, 70,220,150, 93, 63,188,
- 9,160, 69, 29,177,117,193, 38,182, 26,199, 74, 6,163,107,204,143, 63, 10, 35,166, 76,225,220,251,242, 75,101, 89, 82,146, 58,
- 96,216,176,202,142,211,167,107, 1, 64,145,151,199,202, 94,190,156, 47,124,253,117, 94,183, 5, 11,156, 77, 58,157,231,202,149,
- 43,187, 44,123,154,188,188, 89,156,126,227,198,153,150,253,250,107,231,164,121,243,250, 16, 6, 3,125, 72,183,110, 41,171,247,
-237, 43,126, 17,206,151, 89, 78, 81, 98,162,182,194,223, 31, 29, 71,142, 44,247,115,119,215,190,204,186,191, 72, 57,109,168,133,
-217, 87,235,195,186, 79,168,136,139,139,235, 13,224, 18,128, 47, 99, 98, 98, 86, 0,128,163,163, 99,105, 85, 85,149,251,145, 35,
- 71, 44,138, 44, 38,147, 9, 47, 47, 47, 4, 6, 6, 74, 36, 18,137, 71, 19, 5, 40, 34, 73,178, 5, 69, 81,181,214,151,198,160,
-213,106,145,147,147,131,118,237,218, 61,193,211, 68,180,141, 26,117,248,124,126,110,102,102,166, 91,122,122, 58,238,220,185, 3,
-127,127,127, 56, 59, 59,131,201,100,194, 96, 48, 64, 46,151, 35, 56, 56, 24, 28, 14, 7,157, 58,117, 42, 83, 42,149,254, 22,166,
-128, 56, 2,129, 32, 39, 49, 49,209,183, 99,199,142,184,117,235, 22,124,125,125,225,233,233, 9, 0,200,203,203,195,149, 43, 87,
- 48,108,216, 48,220,189,123, 23,163, 71,143, 46, 82, 42,149,129, 0,180,141, 17,186,184,184,136, 47, 94,188,248, 36, 50, 50, 82,
-163, 84, 42,105,165,165,165,204,164,164, 36,163, 66,161,176,147,201,100,204,170,170, 42,166, 92, 46,103, 40,149, 74, 38,141, 70,
- 99,169,213,106,230,133, 11, 23,232,122,189,190,201, 0,153,230,118, 58,113,226, 4, 34, 35, 35,113,228,200, 17,204,159, 63, 31,
- 87,175, 94,133,175,175, 47, 14, 30, 60,136, 5, 11, 22, 32, 43, 43, 11,110,110,110, 8, 11, 11,179,212, 70,104,219,182,237,195,
- 7, 15, 30,180,101,177, 88,230,188,142,230,124,121,144, 74,165,120,244,232, 17,138,139,139, 17, 16, 16,128,119,222,121,231, 81,
-113,113,113,128,165,158,231,227,227, 35, 77, 75, 75,115,107,215,174, 29, 74, 75, 75,225,228,228, 4, 71, 71, 71, 56, 57, 57,213,
-110,251,251,251, 99,222,188,121,240,244,244,148,104, 52, 26, 15, 75, 34, 40, 50, 50,242,236,133, 11, 23,220, 28, 28, 28, 80, 82,
- 82, 2,185, 92, 14, 6,131, 1, 62,159, 15, 55, 55,183, 90, 33,159,147,147,131,232,232,232,178,220,220,220,193,205, 16, 73, 52,
- 15, 15,143,204,251,247,239, 7, 82, 20,133,194,194, 66,100,101,101, 97,230,204,153, 57, 26,141, 38, 4,255,162,156,125,117,252,
-174, 88, 19,223,255,144,245,230,136,238,186,140,180, 56,130, 67,102,161, 67,132,131, 12, 0, 82, 82,229,142, 90, 90, 48, 66,195,
- 99,168,163,199,175,177,247,236,222,193, 4, 9, 15, 16,200,202,200,193, 87,141,113, 15,234,235, 53,101,206,156, 15, 34,250,244,
-236, 77, 83, 40,149,238, 63,253,180,190, 83,110,110,134, 59, 0,248,251,135, 74,102,204,152,155,108, 47, 16, 72, 46, 93, 73, 36,
- 55,108,248, 37,245, 92,130,120,151, 21, 69,246, 15, 12, 12,188,126,226,196, 9, 55,119,119,119, 56, 58, 58, 66,169, 84, 66,175,
-215, 35, 61, 61, 93,115,224,192, 1,131,131,131,131,125, 73, 73, 9,170,170,170, 64, 16, 4, 78,156, 56, 81, 8,160,101,125, 34,
-179,143, 22, 0,204, 28, 26,202, 12,235, 23,232,204,226, 24,121, 60,102,182, 23, 8, 19,135,160,236, 60, 78,159, 77,105,119, 58,
-254,214,187,111,142,154, 47,236,213,251, 77, 44, 91, 58,198, 32, 18, 21,118,212,163, 87,102, 67, 62, 90, 33, 1,232, 55,114,244,
-155, 99, 87,174, 92,129, 21,203,190, 68,220,137, 99, 50, 59, 1, 77,235,224,196,116,124,253,181, 30,154,121, 31,141, 40,170,174,
- 22,249,174, 92,115,224,157,232, 17,243, 90,244,236, 53, 18, 87, 46, 31,195,190, 95,191,188, 67,240, 40,219, 52, 98, 61,172, 0,
-156,157,252,253,167,125,146,147,195,186,183, 98, 69,181, 81, 36,170,140,154, 59,183,172,161, 99,159,196,199, 11,216,222,222, 14,
-206,111,188,225,178,177,101, 75,202, 32,145,108,111,200,199,168, 33,206,243,118,118, 78,191,159, 62,221,159, 98, 50,123, 47,252,
-236, 51, 94, 76, 76, 12,228,114, 57, 14, 31, 62,140,237,219,182,105,189,188,188, 30,120,167,166,222,141,144,203,151, 90,203, 25,
- 53,119,110,153,201,100, 34,198, 46, 88, 48, 48, 45, 47,175, 95,137, 68,210, 10, 0,188, 92, 92,138,162,252,253,239,252, 18, 23,
-151,181,185,117,107,210,218,114,238, 60,115,198,227, 80,126,254, 20, 23, 23, 23, 94,169, 68,194,224,176,217,229,175,133,133, 29,
-220,186,100,201, 37,227,253,251, 44,110,139, 22, 14,142, 49, 49,205,174,123,212,220,185,101, 21, 10, 5,227,147,175,191,238, 81,
- 80, 90,218,170, 90,171, 13,168, 82, 40, 60, 77, 6, 3,205,129,207, 47,111, 19, 28, 44, 81, 39, 37,137,219,168, 84,179,119, 1,
-146, 87,213,214, 13,105,145,127, 16,234,199,209,250, 75,174,195, 75, 49, 49, 49,127, 89, 93, 67, 81,148, 85,214, 44, 38,147,249,
-204, 52, 85, 19, 96, 17, 4,129,228,228,100,184,186,186,194,211,211, 19, 28,206,179,201, 7,165, 82, 41,174, 94,189,138,140,140,
- 12,180,111,223,222, 60,141,209,184, 34,226,112,230,172, 89,179,198, 73,167,211,225,206,157, 59,136,138,138, 2,135,195, 1,139,
-197,122, 70, 4, 74, 36, 18,132,135,135, 99,225,194,133,142,223,126,251,237, 28,173, 86,219,232, 19, 41,131,193,152, 53,117,234,
- 84,119,179, 5,171,168,168, 8,157, 58,117,170,253, 94, 40, 20, 34, 37, 37, 5, 81, 81, 81,104,209,162, 5,198,140, 25,227,190,
-111,223,190, 89, 70,163,113,109, 99,156,108, 54,155, 22, 25, 25,217, 25, 0, 4, 2, 1,104, 52, 90,182,131,131,131,208,195,195,
- 67,224,224,224,240,151, 58,254,250,235,175, 85, 52, 26,205, 96, 81, 13,208,104, 40, 41, 41, 65, 68, 68, 4,100,178,167, 25, 92,
-148, 74, 37, 2, 2, 2, 32,151,203,107, 69,171,183,183, 55,212,234,166, 93,191,218,181,107,183, 34, 36, 36,100,144, 64, 32,224,
- 48,153, 76,220,187,119, 15, 29, 59,118,196,129, 3, 7,224,231,231, 7, 62,159,143,156,156, 28, 68, 70, 70, 34, 49, 49, 17, 66,
-161, 16,225,225,225, 28,119,119,247,203, 21, 21, 21, 9, 5, 5, 5, 43,154, 40, 39,205,206,206, 14,137,137,137,248,229,151, 95,
-144,151,151, 7,145, 72, 4,123,123,123,116,232,208, 1, 97, 97, 97,232,222,189, 59,114,114,114, 64, 88,238, 76,158,129,129,129,
-113,183,110,221,114,163, 40, 10,251,246,237, 67,117,117, 53,116, 58, 29,104, 52, 26,184, 92, 46,156,157,157,209,175, 95, 63, 8,
-133, 66, 4, 6, 6,226,143, 63,254,112, 27, 58,116,232, 41,137, 68,210, 1, 64,137,165,235,234,236,236, 60,123,249,242,229,190,
-238,238,238,200,207,207,135, 76, 38,131,135,135, 7,250,244,233,227,115,254,252,249,217, 6,131, 97,253,191,229, 70, 86,199,241,
-157, 56,119,246,231, 81,129,109, 42, 35,219, 7,243,125,143,196,121,248, 30,136,147,132, 3, 64, 68,168, 71,218,168, 24,126,209,
-189,180,184,162,115,103,143,221,201,200,198, 17, 88, 49,181, 45, 83,105, 15,198,159,191, 57,164, 99,251, 78,228,154,239, 22, 68,
-127, 52,115, 10,199,221, 99, 50, 74, 11,143,225,252,197,100,191, 5,243,167, 10,215,174,219,121, 58,254,252, 77,154, 76,165, 93,
-106,157, 41,203,111,243,238,173,221,221, 20,101,135,240, 48,147, 13,158,125, 4,252,253,131, 32,151,203,193,229,114,185,239,188,
-243,142,105,241,226,197, 42, 7, 7, 7, 62, 65, 16, 72, 72, 72,144, 0, 24,108,137, 87,227,238, 76,153,244, 6, 35,197,166,147,
- 20, 97,175, 38, 76, 21,236,212,244,199, 24, 52,160,111,105,207,174, 17,223, 46, 94,185,238,243,192,160,142,194, 15,166,124,201,
-252,122,197,187,219, 64,160, 87, 67, 60,153, 15,113,145, 56,120,148, 7, 32,122,229, 87, 43,144,155,155,227,252,225,164,170, 47,
- 25, 28,158,119, 72,203, 30,246,219,126, 73, 24, 18, 16,208,186,213,188, 89, 99, 78,254,240,227, 15,209,117, 45, 91,187,127, 93,
-126, 28, 64,127,107,174,237,255, 16,218, 77,136,139, 67,117, 97,161,161,226,242,101, 77,255, 31,127, 44,243, 29, 60,120,189, 78,
-175,119, 51, 15, 21, 52,130, 0, 97,118,157, 32, 73,130,177,112, 33,141, 98, 48, 96,112,118,158,132,202,202, 32, 75,156,243,197,
-226, 81,239, 78,153, 18,125,252,204, 25,180,110,221,186,246,126,230,228,228,132, 5, 11, 22, 96,238,220,185,156,148,148,148, 46,
-135, 14, 29,234,178,246,251,239, 61, 0,140,178,166,156,231,110,220,112,158,190,114,229,146,246, 81, 81,126,123,247,239,231,180,
-109,219, 22, 0,240,232,209,163,192,239, 86,175,110, 25, 17, 25, 89,250,237,156, 57,187,211, 22, 47, 14, 7,112,185, 41,206,146,
-164, 36,221,161,252,252, 41, 23, 19, 18,156, 34, 34, 34, 0, 0, 89, 89, 89,238, 27, 55,110,156, 26, 62,102,204,248,149, 51,102,
- 44,141,209,104,170, 28,164, 82, 78,204,230,205,140,223,199,142,181,200,105, 46, 39, 0,244,249,224,131, 57,189,250,246, 13, 27,
- 53,101,138,139,159,159, 31, 97,103,103, 7,189, 94, 15,145, 72,228,156,150,150,214, 54, 78,161,144, 31,189,113, 99, 31, 76,166,
-129,175,176,173, 27,212, 34,255, 48, 75,214, 95, 53, 69,205,123,159,184,184, 56, 10, 64,159,152,152,152, 68,243, 13,220,100, 50,
- 89, 37,178, 24, 12, 6, 8,130,176, 86,108,129,162, 40,148,149,149,161,172,172,172,118,234, 72, 34,145,224,226,197,139,200,201,
-201, 1,147,201, 4,139,197,130, 94,111, 57, 7,173, 64, 32, 24, 48, 96,192, 0,198,141, 27, 55,224,239,239, 15, 30,143, 87, 91,
- 46,243,139,197, 98,193,203,203, 11,114,185, 28,253,251,247,103,110,218,180,105, 64, 83, 66,203,209,209,113,216,184,113,227,216,
-230,207,213,213,213,160,211,233,181,162,165,186,186, 26, 21, 21, 21,168,170,170,130, 70,163, 65,183,110,221,216,113,113,113,195,
-202,203,203,215, 90, 83,127,149, 74, 85, 45,145, 72,156,122,245,234,229,188,123,247,238,172,110,221,186, 5, 63,211,211, 46, 93,
-210,104, 52, 26, 38,141, 70,179, 42,143, 94,108,108,108,237,181, 47, 46, 46,198,182,109,219,106,191,203,201,201,193,166, 77,155,
- 64, 81, 20, 40,138,106,178,141, 66, 66, 66,134,238,219,183, 47,106,239,222,189,149,116, 58, 29, 89, 89, 89,216,191,127, 63, 40,
-138,130, 80, 40,132, 74,165, 66,105,105, 41, 18, 18, 18, 96, 52, 26, 97,103,103, 7, 31, 31, 31,238,172, 89,179,122,126,249,229,
-151,204,166,132,150,201,100, 50,209,233,116,180,108,217, 18,203,150, 45,131, 70,163, 1,139,245, 84, 95,202,229,114, 84, 85, 85,
-225,238,221,187,200,207,207, 7, 69, 81, 77,222,100,184, 92,238,152,189,123,247,186,179,217,108,168,213,106, 40, 20, 10, 20, 21,
- 21,161,160,160, 64, 35,145, 72,140,246,246,246,180,150, 45, 91,210, 56, 28, 14,103,228,200,145,132, 89,112,198,196,196,184,238,
-219,183,239, 45,157, 78,103, 73, 36, 9, 61, 61, 61, 63,159, 58,117, 42,183,110,159, 45, 41, 41,193,168, 81,163,248,215,174, 93,
- 91, 44,151,203,247, 3,144,254,203,110,104,212,161,163, 65,183,239,156,207,138, 60, 18,231,225, 91,240,196,212, 99,193,167,235,
- 24, 0,176, 99,251,170, 30, 71,226,138,175,134,180, 46, 45, 58,116, 52,232,182,179,115,134, 37, 33, 64,235,215,219,107,184,128,
-207, 29, 55,234,141, 55,168,159,126, 90,223,233,163,153, 83, 56, 45,131, 22, 60,181,112, 50,221,209,223,248, 21,161, 82, 63,226,
-254,244,211,250, 78,163,222, 24,125, 55, 47, 47,127,123,191,222,156, 63, 46, 38,138,255,108,202, 98,232,238,202,245,225,115,148,
-240,241, 15, 67,112,168, 0, 41,247,178,112,248,224,117,132,134,191, 6,173, 86, 11,163,209, 40, 24, 62,124,184,234,192,129, 3,
-154,236,236,108,133, 90,173,238, 13, 32,219, 82,229,159, 60, 73, 39,131, 61, 95,211,179,120, 28,163, 66,198, 82, 45, 90,122,104,
-108,167,174,131,162,156,189,124,152, 66, 1,249,231,208,129, 93,246,255,178,107,217,220,165,203,247,163,115,151, 65,221, 50,178,
- 46,135, 1,120,208,160,120,205, 69, 28,237,240, 81, 99,238,195,135,209, 5,249,249, 79,130, 60, 60,117,143,170, 40,195,236, 69,
- 59, 7,246,234, 61,166, 93,219,208,215,217, 25,233,137,196,178,133,111,253,182,114,205, 15,239,152,197,214,133,248,223,122, 79,
-154,116,157,189,123,119,227,214,241,255, 53,176, 56,156, 22,118, 45, 91, 50,242,118,239, 86,251, 15, 31, 94, 9, 0, 58,189,222,
- 45, 47, 63,223,145,207,231,131,162, 40, 24, 12,134,103,124,136,205,126,195, 17,193,193, 30,214,112,230,125,241, 69,187,133, 11,
- 23,162,164,164, 4, 70,163, 17, 76, 38,179,254,152, 13,165, 82,137, 73,147, 38, 97,243,247,223,191,102, 13,167,201,100, 34,166,
-175, 92,185,228,179, 37, 75,218, 78,155, 54,141, 86,119,236,117,113,113,193,161,195,135,217, 91,182,108,105,241,249,230,205,147,
-222,229,112,114,161,213, 54,201, 89, 22, 16, 0,151,210, 82,158, 89,100, 1, 64,112,112, 48,182,109,219,198,153, 60,121, 50,123,
-248,240,225,235, 82,218,183,223,184,190,103,207,135,174, 65, 65, 14,108, 14,167,133, 37, 78,243,245, 4, 0,133, 70, 19,177,126,
-227, 70,231,155, 55,111,162,180,180, 20, 37, 37, 79,159, 71, 9,130, 64,231,206,157,137, 9, 19, 38, 56,182,241,245,237, 2,147,
-233, 85, 54,247, 95,180,200, 63, 8, 31, 54,176,239, 63, 62, 90, 53, 21, 34,106, 42, 72,212,185, 57, 62, 35, 88, 44, 9,173,231,
- 65, 85, 85, 21,170,170,170,176,107,215, 46,176, 88,172,218,155, 47, 0,232,116, 58,107, 68, 75,164,183,183, 55,100, 50, 25,130,
-130,130,158,177,100,177, 88, 44, 48, 24, 12,176, 88, 44,112, 56, 28,104,181, 90,248,249,249, 65,165, 82, 69, 54,197,169, 86,171,
- 59,184,184,184,212,222, 96,181, 53,157, 85,171,213,214,150, 87,167,211,161,178,178, 18,213,213,213, 80, 40, 20, 80, 42,149, 29,
-173,169, 47, 73,146, 72, 77, 77,125, 20, 28, 28,220,129, 78,167,195,206,206, 78,160, 84, 42,107,125,139, 42, 42, 42,176,103,207,
- 30,229,123,239,189,231,118,226,196, 9,139, 66,139, 32, 8,124,252,241,199,224,112, 56, 80,169, 84,248,233,167,159,240,201, 39,
-159,128,197, 98, 65,161, 80, 96,219,182,109,152, 55,111, 30, 24, 12, 6,116, 58, 29, 54,110,220,216, 40, 87,122,122,122,222,141,
- 27, 55, 58,118,234,212,201,249,232,209,163,210,129, 3, 7, 10, 7, 15, 30, 12, 30,143, 7,181, 90, 13,131,193,128,215, 94,123,
- 13, 33, 33, 33,144, 72, 36, 56,125,250,116, 89, 96, 96,160,219,205,155, 55,201,146,146,146, 2, 11,226,154,170, 99, 49,132,201,
-100, 66,105,105, 41,170,170,170, 32,149, 74, 33, 18,137,240,228,201, 19, 48, 24, 12, 88,208, 89,112,117,117, 29, 29, 17, 17, 65,
- 7, 0, 30,143,135, 14, 29, 58, 96,201,146, 37, 70,181, 90, 61, 14,192,233,154,195,134,238,220,185,243,232,149, 43, 87, 24,222,
-222,222,200,204,204,132, 80, 40,100,112,185, 92,139, 66,203,211,211,243,215, 63,255,252,211,197, 44,174,205,215, 89,165,122,218,
- 28,163, 70,141,114,217,187,119,239,175, 70,163,113,216,191,237,166,230,196, 3,171, 67,132,131,236, 64,156, 36,124,193,167,235,
- 24, 33, 17, 79, 31, 94, 63,156, 6,198,218,239,231,135,143, 31,225,112,210,137, 39,103, 89,226, 25, 58,192,119,203, 27,111, 12,
-164,189,243,118, 76, 14,139,229,228,191,125,199,151,238,238, 30,147,235,200, 48, 7,184,186, 57,192,191, 37,155, 56,116, 50,195,
-125,209,226,175,180,177,123,127,200,253,237,247,184, 33,108,102,252,160,211,231,139,102, 52,198,157,253,168,234,132, 74,203, 13,
-149,151,223, 39, 92, 60,122,160, 67,251, 96,184, 11, 43,177,243,215, 3,104,221,166, 51,180, 90, 45, 28, 28, 28,248, 38,147, 73,
- 79,167,211, 99,173, 17, 89, 0,112,225, 66, 21, 25, 30, 94,165,163, 43, 72,227, 71,159,172,125,115,224,208, 55,194,250,245, 27,
- 64,158,139, 63,167,239,209, 81, 47, 30, 58,184, 67,233,153,248, 45, 57, 98,209,227,192,240,200,158, 72, 79, 75, 24, 66, 81, 72,
- 37,136,134,173, 79,105, 15,113, 70, 67,166, 39, 28, 56,240, 33,169, 38,239,242,190,254,230,193,208,232,232,137, 17,175,247,122,
-157,140, 63,127, 81,199, 70, 89,134, 67,207,238,197, 31, 77, 25,122,244,231,216,141,131,206,156,254, 53, 64, 38, 47,136,179,137,
-172,122, 15,105, 70,163, 7,131,195,161, 73, 19, 18,140,145,147, 39,107,205,255, 71, 62,159,143,227,199,143,131,205,102,215,190,
- 88, 44, 86,237,182,135,135, 7,136,154,101,164,214,112, 2,128, 88, 44, 70, 73, 73, 9, 28, 29, 29, 33, 20, 10, 81, 82, 82,130,
-107,215,174, 33, 59, 59, 27, 76, 38, 19, 67,134, 12, 1,173, 17,223,230,250,156, 99, 23, 44, 24, 24, 26, 25,233, 87, 95,100, 1,
-128, 94,175, 71, 69, 69, 5, 70,140, 24, 65, 59,125,250,180,231,153,194,194, 55, 0,196, 54,197,217, 49, 58,186,188,244,208,161,
- 6,127,187, 83,167, 78,196,213,171, 87, 57, 67, 6, 15,158, 59,255,155,111,182,108,222,187,183,200,100, 52,122, 54,167,238, 52,
- 26,141, 70, 16, 4,124,125,125, 81, 81, 81,129,234,234,167, 51,216,118,118,118,112,118,118,134,193, 96, 0, 73, 81,204, 87,217,
-214,141,105,145,127, 8,118,212, 17, 92, 59,254, 98,209,170,169, 20, 0,244,169,123, 99, 33, 73,210, 42,145,197,100, 50, 45,250,
- 92, 89, 99,229,170, 15,107,132,150,185,172, 92, 46,183,246,143, 86, 87, 96,153,203, 73,163,209, 64,167,211, 45,222,196,107,196,
- 16, 93,161, 80,224,240,225,195,232,221,187,119,237,180,148, 76, 38, 67, 85, 85, 21,100, 50, 25, 52, 26, 13,242,242,242,112,225,
-194, 5, 4, 4, 4, 0, 86, 6,127,205,205,205,189,211,186,117,235, 40,243, 77,188,111,223,190, 45,118,239,222, 45, 26, 54,108,
-152, 55, 69, 81, 88,186,116,105,217,107,175,189,230, 86,247, 38,111, 9,116, 58, 29,215,174, 93, 67, 64, 64, 0, 40,138, 2,139,
-197, 66, 86, 86, 22,220,221,221, 65,146, 36, 24, 12, 6,164, 82, 41,236,237,155,142,145,152,154,154,250,254, 7, 31,124, 32,114,
-116,116,108, 87, 94, 94, 46,230,112, 56,189,146,146,146,124,245,122, 61, 28, 28, 28,224,224,224,128, 83,167, 78,193,201,201, 9,
-115,230,204, 41, 84,171,213,215, 4, 2,129,135, 90,173,190, 95, 82, 82,178,180, 57,237,109, 52, 26,161, 84, 42, 81, 89, 89,137,
-138,138, 10,200,229,114,104, 52, 26,139,101,108, 8,189,122,245, 66, 92, 92, 28,125,213,170, 85, 63,231,230,230, 2, 0,252,253,
-253, 49,103,206, 28,186,143,143, 15,242,242,242,112,231,206, 29,232,245,122, 80, 20,213,228,159,151,193, 96,244,125,239,189,247,
-122,250,249,249, 17,122,189, 30, 36, 73, 66,171,213,194,188, 93, 88, 88,136,208,208, 80, 90,203,150, 45,187,229,230,230,246,133,
-117, 11, 43,108, 0, 80, 90,120, 12, 62, 76,119,128,230, 0, 74,125, 12,229,101,207, 23,197, 69, 34,145,124,179,240,139,171,147,
- 55,175,209,123, 60, 17, 3,193, 17, 35, 17, 24,214, 31,239, 79, 48, 98,213,247,135,225,215, 50, 24, 5, 5, 5,232,219,183, 47,
- 75, 36, 18,125, 80, 93, 93,189,192, 90,238,248,248, 27,166,115,167, 78,143, 25,251,214,196,168, 1, 3,134, 25,207,158, 61,133,
-212,251,103,211, 62,120,107,180,132, 34,171, 9, 23, 39,222,221,172,204,219,129,237, 58,244,129,206,104,234, 5,172, 88, 3,172,
-160, 26,255,191, 67,119,242,164, 23,237,228,177, 95, 39,188, 51,126, 82,251,254,253, 7, 25,206,198,255,137, 59,215,227,239,173,
- 91, 51, 53,113,213,198, 63,250, 14, 28, 50, 58, 92,232,113,237, 84, 68,144,118,138,175,171,227,163,157,187, 43,108,157,165,161,
-255, 38,151, 75,162,102, 92,164, 17, 4, 40,138,122, 70,100,213, 23, 90, 52, 26,205,162, 1,160, 46,103,221,123,145,249,129,122,
-251,246,237,224,112, 56, 96,179,217, 96, 50,153, 22,221, 47,234,114,166,229,229,245,219, 19, 27,203,105, 72,100,149,151,151,163,
-188,188, 28,213,213,213,120,251,237,183, 89, 95,222,190,221, 9, 53,174, 31,141,113,250,121,121,105, 5, 60, 94,105,122,122,186,
-119, 88, 88,216, 51,229,149,203,229,224,241,120,136,221,191,159, 21, 19, 29, 61,179,255,169, 83,235, 96, 33,254, 85, 67,117, 39,
- 8, 2,238,238,238,112,118,118, 6, 65, 16, 48, 26,141, 40, 41, 41, 65, 90, 90, 26,110,223,190, 13, 58, 65, 24, 95,101, 27, 55,
-164, 69,254,129, 86,173, 29, 13, 78, 29, 54, 54, 39,218, 28,161, 69,167,211,159,219,170,213, 24,172,153, 58,228,243,249, 15, 68,
- 34, 81, 15, 31, 31, 31, 24,141,198, 90,161, 85,127,234,208,108,253, 72, 73, 73, 1,159,207,127,160,209,104,154,228,164, 40,170,
- 91,151, 46, 93,112,228,200, 17, 36, 36, 36,224,241,227,199, 80,169, 84,208,106,181, 80,171,213, 72, 75, 75, 3, 73,146,136,136,
-136,128, 64, 32, 0,159,207,127,160,213, 54,253, 32,170, 84, 42,197, 76, 38, 51,152,199,227,213,238,243,242,242, 66,121,121, 57,
-105, 48, 24,176,103,207, 30,185,167,167,167,128,199,227, 89, 45, 92, 9,130,128, 68, 34, 65,139, 22, 45,106,125,180, 20, 10, 5,
-220,221,221,205,194, 2, 90,173, 22,246,246,246, 22,167, 14, 1,104, 30, 62,124, 56,191,206,231,206, 99,199,142,253,237,192,129,
- 3,109,206,159, 63,143,155, 55,111, 66, 40, 20,226,219,111,191,125,156,159,159,255, 14,128,219, 18,201,203,245,139,180,166, 15,
-149,151,151, 31,126,240,224, 65,183, 46, 93,186,212,142, 18,125,251,246, 37,250,246,237,235, 86,215,212, 47,149, 74,113,235,214,
- 45,156, 63,127, 30, 4, 65, 32, 39, 39,199,164, 86,171,127,107,106,150,194,199,199,103,247,146, 37, 75,236,140, 70, 99,109,223,
-230,241,120,224,114,185, 96,177, 88,160,211,233,200,207,207,199,136, 17, 35, 28,127,252,241,199, 95,181, 90,109, 91, 0,122,252,
- 75, 80,165,134, 62, 37, 85,238, 24, 17,234,145,182, 99,251,170, 30, 31, 78,131,121,234,208, 24, 17,234,158,150,146, 90,234, 24,
-229,110,185,190,167,207, 23,125,164, 51,156, 30,126,250,204,165,113,159,206,157,195,244,247, 15,149,156,191,152,236,215,223,248,
- 21,225,234,230,128,242, 50, 57,242, 11, 75,145, 91,160,163,252,253, 67, 37,119,110, 61,224,124,191,126, 67,160, 82,165, 49, 79,
- 29, 54,217, 79, 47, 95,123, 60,114,221, 38, 78,226,196, 15, 58,179,121, 60,111, 84,148, 61,128,159,159, 16, 35, 98,218,225,151,
-189,215,224,232,232, 2, 15, 15, 15,208,104, 52,129,181,117, 47, 43, 43, 35, 14,255,126,121,242,123,147,166,190, 54,120, 80,180,
-241,204,217,147,140,132,115, 39,174,253,186,227,243,163, 20, 93,201, 39, 40, 5,175, 85,107,207,251,143, 30,166,188,211,111,192,
-219,224,177,236, 3,128,144, 6, 59,108,237, 2, 3, 10,133, 71, 14,172,224,190, 55,233,195,238,131, 7,191, 97, 60,123,246, 24,
-206,158,218,123, 99,249,242, 86,167, 30, 23,239,103, 93,191,253,132, 59,114,204,140,202,184,211, 25,186,209,195, 91,103,123, 11,
- 58,168,129,199, 54, 85, 85,247, 65,146,193, 40, 53,106,181,190, 45, 6, 15,166,171, 10, 10,152,118, 30, 30, 70, 0, 48, 24, 12,
- 22,133, 22, 26,153,130,174,207,105,109, 89, 84, 42, 21,200, 70, 98, 39,214,231, 44,145, 72, 90,213, 60,132,215,194, 96, 48,212,
-138,172,242,242,114, 84, 85, 85, 65, 32, 16, 64,170,213,122, 88,195, 57,168,107,215, 61, 95,174, 88,177,224,208,225,195,172,186,
- 34,203,252, 98, 50,153,248,110,205, 26,214, 39,159,126, 58, 99, 38,131, 49, 27, 70,163,213,215,211,252,208, 78,167,211,193, 96,
- 48, 80, 80, 80,128,194,194, 66, 20, 20, 20,160,160,160, 0, 60, 30, 15,212, 43, 94, 4,244, 15,246,207, 50,139,172,186,239,181,
- 86,174, 38,195, 59, 52,199, 25,222, 90, 97, 96,106,198,252,174, 53, 66, 75,169, 84,158,191,112,225, 66,215,145, 35, 71, 50,110,
-220,184, 1, 79, 79,207, 90,161,101,126, 55, 79, 71,241,249,124, 28, 61,122, 84,175, 84, 42,207, 91,248, 51, 93, 56,117,234, 84,
-212,178,101,203,152,239,191,255, 62,210,211,211, 49,109,218, 52, 84, 85, 85, 65, 46,151,163,188,188, 28, 42,149, 10, 93,187,118,
- 5,151,203,197,253,251,247, 13, 42,149,234,130, 5,139, 29, 37,145, 72,170,133, 66,161, 87,253,239,198,140, 25,227,177,117,235,
- 86, 85,102,102,166,161, 71,143, 30, 14,214, 10, 14, 51,126,255,253,247, 90, 75, 93,118,118, 54,182,110,221, 90,235,147,149,156,
-156,140,181,107,215,214,198, 62,107, 38,110,151,149,149, 25, 13, 6, 3, 2, 2, 2,224,227,227, 3,141, 70,131, 13, 27, 54, 24,
- 1,220,254,255,234,205, 26,141,230,208,196,137, 19, 63,187,123,247,174, 23,131,193,120,106,210,174,169,159, 94,175,199,195,135,
- 15,145,150,150,134,204,204, 76, 84, 84, 84,212, 62, 8,164,164,164, 84, 26, 12,134, 63, 26,227, 21, 10,133, 75,127,249,229, 23,
- 79, 62,159,255, 76,127, 54, 91, 67,205, 86, 82,169, 84, 10, 39, 39, 39,244,239,223,223,253,194,133, 11, 75,181, 90,237,178,127,
-201, 61,141, 24,243,102,118,231, 79, 62, 26,137, 81, 49,252,162, 35,113,197, 87,215,126, 63,191,198, 25,222, 61,109, 84,140, 79,
-209,189, 44, 39,140,121,243, 88,103, 0, 79,208,180,195, 54,121, 49, 81,124,188, 75, 23,231,132, 35, 39, 78,252,186,120,225,220,
-228, 5,243,167, 10, 85,234, 71, 92,255,150,108, 2, 0,114, 11,116,212,253,116, 82,179,118,221,220,228, 85,107,126,164,149,150,
- 87, 77,187,117,171,241,240, 6,117,197, 11,141, 6,174,127, 72,111, 81, 96, 80,207,214, 55,174,197,194,142,175, 70,112, 72,103,
- 12, 30,212, 13, 9,151, 82, 80, 34,213, 64, 44, 22, 67,171,213, 54, 25, 46, 33,243,254,209, 9, 20, 65,249, 17, 20, 81, 72,208,
- 40,238,132,137, 83,122, 69, 71,191, 65,197,197,157, 48, 30, 59, 26,123,229,143,125,155, 14,209, 88, 76,134, 90,231,168, 35, 8,
-141, 12,180,212,244,106,229,211, 7, 26, 38,135,213,184,249,181, 38,176,107, 88,120,136,231,132,137,211, 28,135, 13, 29, 65,157,
- 58,117,140,252,227,192,158,132, 63,118, 69,198,146, 52, 57, 75, 92,164,226,200,228, 6, 25, 69,176,157,170,229,164,170, 52,183,
-173,198, 59,122,140, 30, 56,100, 83, 87,117,239, 3, 90,237,147,234,162, 34, 47,151,222,189, 57, 15, 87,172,224,123,116,237,170,
- 33,106,124,136,155, 18, 90,116, 58, 29,160,209, 72,107, 56,173, 45,139, 90,173, 6, 9, 24,158,135,211,104, 52, 62, 35,178,204,
- 66,203,252,127,177,134,115,199,242,229, 55,252, 6, 15,174,184,116,233,146, 71,159, 62,125, 8,133, 66, 1,133, 66,241,140,216,
-242,246,246, 38,194, 34, 34,248,191, 39, 36,248, 91,123, 61,173,169, 59,141, 70,123,229, 66,235, 31,142, 70, 19, 73, 55,153,130,
-199,108,209,178, 70,104, 89,105,209, 50, 24, 12, 6,184,187,187,163,172,172,172,209, 27, 63,141, 70, 3,143,199, 51,207, 17, 55,
-185,242, 78,171,213,110, 88,176, 96,193,172,161, 67,135,186, 5, 7, 7, 67, 42,149,194,195,195, 3, 92, 46,183,214,119,204,204,
-151,156,156,140, 95,126,249, 69,174,213,106, 55, 88,224, 92,191,102,205,154,143, 70,141, 26,229,226,233,233, 9,103,103,103,220,
-191,127, 31,206,206,206,144,203,229,200,202,202,130,189,189,125,173,223,206,137, 19, 39, 20, 90,173,118,189, 5,241, 70, 37, 37,
- 37,233,237,237,237,239, 75,165, 82,122, 69, 69, 5,163,178,178,146, 33,151,203,153, 50,153,140,121,230,204, 25, 55, 71, 71, 71,
-213,197,139, 23,165,126,126,126,244,199,143, 31,211, 13, 6,131, 69,245, 74, 16, 4,102,207,158, 13, 22,139, 5,173, 86,139, 13,
- 27, 54, 96,193,130, 5,181, 62, 89,107,214,172,193,146, 37, 75,106,133,243,206,157, 59,155,213,115, 40,138,130, 94,175,135,193,
- 96,128,193, 96,176, 74,252,190, 8,172, 20,236, 37, 57, 57, 57, 49, 93,186,116, 57,119,240,224, 65,215,154,152,100, 40, 45, 45,
- 69,105,105, 41,164, 82, 41,170,171,171, 97, 52, 26,225,227,227,131,210,210, 82, 28, 59,118, 76,166, 80, 40, 6,163,137, 21,135,
-116, 58,125, 98,175, 94,189, 24,245,203, 96,126,202, 51,139,119, 14,135, 3,145, 72,132,190,125,251,178, 47, 93,186, 52, 17,192,
- 63, 90,104,213, 13,239, 48,104,240,100, 86,104,120,119,221,189,180,184,162,144,214,165, 69,227, 71, 56,156, 4,128,148,212, 82,
-199,123, 89, 78, 8, 13,143,161, 6, 13,118,142, 42, 45,217, 17, 9, 64,223, 84,186, 30, 0,112,228,115,198, 14, 28,208, 85,100,
- 47, 16,208,214,174,219,121,250,167,159,214,119, 58,116,242, 63,225, 29,214,174,123, 26,222, 97,224,128,174,100,102, 70,230, 88,
- 0,187,172, 21, 47, 49, 49,195,239,254,178,251, 23,100,166, 93,244,254,108,118, 59,118, 69,169, 1, 60, 59, 95, 68,117,240,192,
-142,221, 15,112,239,222,189, 18,157, 78,215,183,201,254, 77, 80,126,105,233,169, 65,145,225, 97,158, 19, 38,126,232, 16, 19, 51,
- 2,113,113,199,177,111,207,174,164,209,111,143,250,185,184, 82, 78,119,103,242, 89,124,138,100,211, 89,142, 12, 22,135, 39,209,
-233,158,174,129, 96, 50,185, 14,192,216, 38,111, 60,211, 63, 28,239,216,111,192, 8,156, 60,117, 28,251,246,236, 72,252, 34,124,
-204,174,214, 29, 67,137,174,157,190,159,209,186, 77,235,150,202,234, 82, 57,141, 96,235, 53, 26,210,254,251, 61,249, 63,228, 46,
-153,152, 11, 96, 29,108,171, 14,235,226,254,190, 97,195,186,124,242,232, 17, 75,216,179, 39, 79,148,144,192,175,201, 68,210,164,
-208, 98, 48, 24,160, 26,159,234,122,134,147,216,187,151, 6,160,201, 69, 88, 44, 22, 11, 42,149, 10,134,198, 45,216,207,112,122,
-157, 61, 91,244,232,209,163, 64, 23, 23,151,103, 68, 86, 69, 69, 69,237,182, 70,163,129, 74,165, 2,143,199, 75, 83, 55, 60, 35,
-242, 12,103,105, 82,146,102,245,236,217,203,222,121,251,237, 77,231, 47, 92,224,186,186,186, 66, 38,147, 61, 35,180,116, 58, 29,
-250,245,239,207, 90,115,247,238, 4,200,229,203,173,185,158, 30,125,251, 90,244, 7,166,211,233, 32, 95,241,212,225,191, 0, 31,
- 54, 36,188,104,150,166,112,172, 93,117,216,200, 13,178,126,118,239, 37, 81, 81, 81,154,236,236,108,248,249,249,213,138,149,186,
-191,233,224,224, 0, 39, 39, 39, 36, 39, 39,227,155,111,190, 81, 3, 88, 98,129, 83,161, 82,169,222, 26, 56,112,160,154,193, 96,
- 32, 36, 36,164, 54,126, 22, 73,146, 96,179,217, 16, 8, 4,184,123,247, 46,134, 15, 31,174, 82,169, 84,111,225,175, 49,180,234,
-115,202, 84, 42,213,187,131, 6, 13, 82,165,167,167,163, 87,175, 94,184,119,239, 30,170,171,171, 81, 93, 93,141,188,188, 60,132,
-133,133, 65,165, 82, 97,235,214,173,106,149, 74,245, 46, 0, 89, 83,156, 10,133, 98,248,130, 5, 11,232,191,253,246, 91,107, 31,
- 31,159,240,206,157, 59, 7,247,239,223,191,237,155,111,190,217,114,216,176, 97, 94,129,129,129,154,193,131, 7, 11,135, 14, 29,
- 42, 84,169, 84,204,171, 87,175,138, 13, 6,195, 80, 11,229,172, 21, 39,217,217,217,181, 83,133, 12, 6, 3,101,101,101,181,145,
-251,205,131, 82, 35, 66,120,128, 37,177,109, 22, 88,102,193,101,133,159, 91, 67,156, 22, 79, 98,179,217,102,139, 39,101, 5,103,
- 74, 70, 70,198,192,222,189,123,167, 76,158, 60, 89, 81, 82, 82, 2,123,123,123,248,251,251, 35, 40, 40, 8,110,110,110,208,235,
-245, 56,122,244,168,242,216,177, 99, 15,100, 50, 89, 95,252, 53,134,214,128,122,215, 49,175,161, 65,214,108,205, 50, 11, 45, 46,
-151, 11, 31, 31, 31,243,181,205,107,206,245,124, 78,188, 90,206, 26, 1,211,191,223,224, 54,195,162, 71, 58, 30, 61,126,141,189,
-105,203,177, 7, 81, 3,176,211,181,149,252,132,107, 43,249,137,168, 1,216,185,105,203,177, 7, 71,143, 95, 99, 15,139, 30,233,
-216,191,223,224, 54,233,105,153,193,117,243, 30, 54, 84, 78, 46,151,219,189, 87,207,168,202, 75, 87, 18,201, 85,107,126,164,245,
-235, 59,250,238,174,159,143, 30,221,245,243,209,163,253,250,142,190,187,106,205,143,180, 75, 87, 18,201, 94, 61,163, 42,185, 92,
-110,119,107,234, 62,253,195,241,142,209,195, 70, 32, 46,238,168,241,208,239, 91,215, 28, 56,156,211,123,202,172,164,210,236,236,
-123,148,228,201, 89, 48,105, 5,200,200,200,144,213,136,172,108,107, 56,167, 77, 29, 95, 87,100, 93,118,245,236,181, 51, 35, 3,
-166,248,248, 63, 13, 23, 46,220, 85, 95, 78,145,200,238,164,151, 85,136,164, 21,143,229,242,114, 29, 73,154, 96, 50,153,232, 95,
-126, 89,235,176,219, 96, 27,245,232,209, 7, 23,207,239,199,158,221,219,101, 36, 9,205,216, 67,135, 76, 99,199,174,160, 90,182,
-106,213, 50,246,247,253, 68,204, 27, 35, 29, 41,128, 28, 62,106,132,211,111, 7,126, 35,218, 4,180,105,229,239, 95, 27,210,230,
-159,215,151, 94, 1,231, 10,160, 82, 94, 80,144,152,252,227,143, 90,143,183,222,114, 97,123,120, 56,192,100, 34,204,227,123, 99,
- 47, 6,131, 81,223, 2,211, 40,167,143,155, 91,241,137, 19, 39, 16, 20, 20, 4, 31, 31, 31,212,245,145, 53, 7,228,118,117,117,
-197,225,195,135, 65, 61, 27,156,186, 81,206,142,173, 91, 39,127,183,122,181,142, 36, 73, 84, 86, 86,254,197,154, 85, 89, 89, 9,
-146, 36,113,234,228, 73,157,252,105, 38, 16,171,234,222,151, 78,175,126,231,245,215, 87, 69, 71, 71,235, 31, 61,122, 4,146, 36,
- 81,215,178, 37,145, 72, 96,103,103, 7,141, 86,235, 11,128,111, 13,167,228,204, 25, 1, 44,140,235, 13, 88,180, 94, 69,187,255,
-211, 69, 86,221,132,210, 31, 90,101,209, 50, 26,141,240,245,245,125, 38,165, 11,141, 70,123,230,213,204, 21,135,123,211,211,211,
-207, 14, 30, 60,120,217,107,175,189, 54,125,217,178,101,244,224,224, 96,200,100, 50, 56, 59, 59,195,221,221, 29, 89, 89, 89, 56,
-113,226,132,169,172,172,108, 27,128,149,176,110, 9,125, 66, 78, 78, 78, 76,187,118,237, 14, 44, 90,180,200,113,208,160, 65, 76,
- 95, 95, 95, 80, 20,133,187,119,239,226,200,145, 35,250, 93,187,118,201,107, 68,150,181,206,203,231, 68, 34,209,232,161, 67,135,
-198, 78,156, 56,209,222,100, 50, 49,243,242,242,160,213,106, 97, 48, 24, 80, 88, 88,168,143,139,139,171, 86,169, 84,227, 1,156,
-179,130, 47,185,170,170, 42, 44, 62, 62,126,226,213,171, 87,191,153, 60,121,178,107,255,254,253, 89, 70,163, 17, 87,174, 92,145,
-118,236,216,209, 93, 34,145,232, 15, 31, 62, 92,174,209,104,150,152, 76, 38,171, 82,240, 16, 4, 1,185, 92, 14, 55, 55, 55,104,
-181, 90,144, 36, 9,157, 78, 7, 59, 59,187,218,180, 73, 20, 69,161, 57,206,245,245,250, 0, 93,175,215,227,237,183,223, 6, 73,
-146,216,176, 97, 3,140, 70, 99,179,201, 28, 29, 29,239,164,164,164,196,116,232,208,161, 86,188,152,251, 16,135,195,129,155,155,
- 27, 92, 93, 93, 17, 23, 23, 7, 38,147,121,199,146,191, 91, 13,238,149,149,149,117,140,143,143,239,254,224,193,131,247, 0,116,
-208,235,245, 62, 38,147,137,160,209,104, 98,138,162,238,203,229,242,159, 97,101, 10, 30,137, 68,242,205,164, 73,147, 58,238,223,
-191,223,142,193,248,207, 95,131,193, 96,128,195,225,192, 28, 28,147,162, 40,232,116, 58, 44, 93,186, 84,174, 84, 42,191,249,183,
-140, 18, 81,157,187, 98,199,214,141,118, 23, 46,158,149,102,228,224, 72, 3, 33, 28,158,148,150,236,136, 20, 21, 21,217, 69,117,
-238,106, 21,167, 65,167, 47,127,119,252, 60,191,154, 20, 60, 75,243,242,242,183,199,238,253, 33, 23, 0,190, 95,191, 33,176,180,
-188,106, 90,102, 70,230,216,237,219,127,239,110,208,233,203,173,225,252,143,120,137,149,129,130, 6,192,205,187, 15, 74, 91, 15,
-127,235,204,146,128, 54, 14,111, 72,202,213,197,213,213,170,143, 1,228, 90, 91,247,158, 61,122,227,226,185,223,176,111, 79,172,
-156, 34,233, 26, 55, 55, 55, 10, 0, 50, 50,220,168,140,140, 42,234, 63,126,197, 78, 74, 38,117,111,229,188,143,251,207,147,201,
- 43,214,111,216,218,244, 84, 74,187,246,175,161, 93,251,215, 48,235,227,207, 29,195,194, 67,252, 0,224,208, 33,152,194, 3,210,
-255, 92,246,197,138, 55, 86,174, 92, 1,185, 66, 11,115,186,158,172,212,244,147,185,185,208,217,238, 89,207, 98,153,209,120, 19,
-243,230, 5,170, 42, 42,132, 61, 63,251,204,141,241,233,167,180,166,156,225,235,254,127,173,225,188,125,255,254,201,105, 83,166,
- 20, 47, 95,182,108,240,182,237,219,121,145,145,145, 40, 41, 41, 65, 72, 72, 8,124,124,169, 74,126, 90, 0, 0, 32, 0, 73, 68,
- 65, 84,124, 16, 31, 31,143,195,127,252,161,172, 82, 40,150, 0,248,201, 26,206,189,167, 78,101, 5,135,135,151,109,223,190,221,
- 59, 58, 58,154, 80, 42,149,144,201,100,144,201,100,208,106,181,168, 9, 8, 77,101,231,228,100, 24, 12,134,109,214,214,221, 36,
-149,114, 87,118,237,250,132, 69,146,223,141, 30, 53,106,193,202,175,190,226,180,105,211,134,208,106,181,181, 86, 45,189, 94, 15,
- 59, 59, 59,189, 78,167,115, 5,160,178,134,147,179,107,151, 81, 42,149, 66, 40, 20,214,134,107,170, 27,151, 80,161, 80,128,162,
- 40, 91, 48,221,231, 64,163, 10,201,217,217,249, 14,131,193,104, 81,215,186,213, 80,238,188,186,251, 12, 6,195,147,178,178,178,
-168,122,138,183, 49,127, 40,127, 0,223,246,235,215,111,244,252,249,243,137, 75,151, 46,225,216,177, 99, 84,110,110,238,161, 26,
- 43, 86,110, 19, 79, 58,141,113,218,115, 56,156, 57, 2,129, 96,128, 57,132, 3,159,207,127,160, 84, 42,207,215, 76, 23, 42,158,
-131,211,129,195,225,204, 22, 8, 4, 3,107,210,175,192,222,222, 62, 69,169, 84,198,107,181,218,141,104, 60, 81,117, 83,156, 60,
- 71, 71,199,111,220,220,220,222,253,244,211, 79, 93,147,146,146,196, 23, 47, 94,100, 85, 85, 85,237,215,233,116, 77, 37,149,254,
- 11,167,139,139,203, 29, 58,157,222,226, 21,181, 17,218,181,107, 23, 55,124,248,240,232,241,227,199,195, 96, 48,224,167,159,126,
- 66,124,124,252,201,135, 15, 31,198, 88,120, 26,173,207,233,214,162, 69,139, 75,211,167, 79,111,249,246,219,111,243,157,157,157,
-193, 96, 48,160, 84, 42,241,240,225, 67,220,189,123,151, 58,126,252,120,117,114,114,242, 19,149, 74,213, 7, 64, 89, 51,174,231,
-139, 60, 53, 63,195,201, 96, 48,122,251,250,250,254,190,124,249,114,251,129, 3, 7,242, 92, 93, 93, 65,167,211, 97, 48, 24, 32,
- 22,139,145,154,154,138,179,103,207, 42, 15, 29, 58,164, 44, 47, 47,127, 27, 64,226,255, 71, 57, 95, 38,103,104, 32,190,168,151,
- 40,186,209,104,239, 22,142,181, 88,206,126,189,189, 70,140, 29, 61,116, 8, 0, 28, 60,124,250,140, 21, 73,165, 27, 45,167,165,
-178, 90,195, 25, 18, 64, 91,158,150,158,250, 76, 64,203,240,176,136,236,208,200, 81, 95, 91, 67, 84, 39, 50,252, 51,117,175, 51,
- 29, 91,215,166,251,204, 52,107,168, 63, 98, 70,140,125, 51,250,243, 37,139,241,237, 55,171,112,252,224,209,147, 25,185,207,164,
- 9,250,199,245,165, 87,204, 73,124,205, 96,188,198,247,242,122,125, 3, 73, 46,190,151,154,106, 87,247,129,205,108,121,174,251,
- 80,233,237,237, 45, 17,139,197, 30,214,112,198,108,222,172, 87, 9, 4,156,197,223,125,215,187, 90,163,233,189,114,229, 74,198,
-237,219,183,177,245,199, 31,141,154, 39, 79, 98,165,192,236, 70,102, 67, 26,229,108, 57,123, 54,119,225,214,173,239,251, 7, 4,
-184,191,247,222,123, 76, 38,147, 9,165, 82,137,162,162, 34,156, 59,123, 86,151,158,145,145, 46,151,203,223, 0, 32,178,150, 51,
-102,243,102,189,147,191, 63,248, 66, 33,117, 33, 33,193,113,218,156, 57,211, 91,181,110,237, 56,120,200, 16,166,131,131, 3, 42,
- 43, 43,145,151,151,135,163, 71,143, 74,170,171,171,189, 1,152,172,225,140,189,122,181,221,169,196,196, 49, 95,127,253, 53, 59,
- 34, 34, 2,142,142,142, 80, 40, 20, 72, 77, 77, 69, 98, 98,162,118,219,182,109, 50,153, 76, 54,221,100, 50,157,120,133,237,254,
-111,176,106,153,177,195,162,208,250, 47,254, 1,163, 0,124, 81,179,253, 21, 44,231, 12,252, 55, 13, 62,126, 46, 46, 46, 59, 52,
- 26, 13,165, 86,171,167, 1, 40,252, 27,150,147, 17, 21, 21,181, 85, 34,145,116,167, 40, 10,142,142,142,215,210,210,210,102,162,
-145,149, 55, 22, 56,233, 0,186,219,217,217,117,181,183,183,239,173,213,106, 67,107,166,223, 50,148, 74,101,162, 94,175,191, 89,
- 99,125, 50,253, 63,215,157, 14, 96,160,183,183,247, 20,146, 36, 3, 8,130,112, 50,153, 76, 48, 24, 12, 85, 36, 73, 62,148,201,
-100,187, 0,196,255, 13,202,249, 82, 56,195,218,226, 77,138,134,208,198, 4,193, 51, 66,171,158,128, 32, 72,100,164, 63,194,209,
-102,148,147, 54,116,128,239, 22,224,233,202, 68, 88,118,174,253,143,208,178, 66,188, 52, 91,100,182,165, 79,162, 8,234, 25, 78,
-130, 34, 10, 67,218,189,185,239, 69,132,150,181, 8, 11, 66,111, 80,232, 78, 82,184,153,249, 16, 23,255,197, 99,221, 75,227,252,
- 22,112,249,209,217,249, 26,141,193,240, 4, 64,171,177,190,144, 36, 65,152, 40,130, 48,214,157,222,170,247, 96,217, 36,167, 30,
-136,100,114, 56,190, 38,163,209,163, 4,176, 59,101, 50,117,210, 80, 84,117, 11,224,139, 20, 32,235,121,202,169, 7, 34,233, 28,
-142,223, 41,138, 26, 33, 21, 8,218, 73,212,106, 33, 0,202, 78, 32,200,144, 43,149,123, 52, 26,205, 22,252,117,230,194, 34, 39,
-139,195,105, 97, 50, 26, 61, 0,128,198, 96, 72, 14,104,181,190, 79, 28, 28,222,211,104,181, 45,237,236,236, 12, 58,157, 78,174,
-209,104,198, 27,141,198, 11,205,169,251, 67,163, 49,236, 42,141,214, 75, 47, 16,184,234, 9, 66,160, 51, 26,245, 58,189,190, 72,
-163,209, 60, 0,240, 3,128, 71,175,184,221,109,120,206, 63,139,141,211,198,105,227,180,113,218, 56,109,156, 54,206, 87,207,201,
- 7,224, 87,243,176,248, 79,172,251,191, 9,214,249,104,217, 96,131, 13, 54,216, 96,131, 13,255, 24,168,208,128, 79,150, 13,255,
-191, 32,154, 80,165,205, 49, 9, 62,143,178, 61,111,227,180,113,218, 56,109,156, 54, 78, 27,167,141,243,127,142,211, 18,247, 63,
-113, 74,178,209, 92,135,175, 26, 54,243,175,141,211,198,105,227,180,113,218, 56,109,156, 54,206,255, 89,208,108,151,160, 81,120,
-212,188, 94,246,177, 54,252,187,251,194,127, 3, 62, 53,175,230, 28,239,101,107, 70, 27,108,176,193,134,255, 13,161,101,237, 77,
-235, 69,110,110, 47,122, 99, 92, 69, 16, 16, 17, 4, 68, 0, 86,189,196, 99, 45,193,219,205,205,237,147,176,176,176, 88, 15, 15,
-143, 89, 0,220,155,121,126, 32,159,207,223, 40, 16, 8, 46, 9, 4,130, 75,124, 62,127, 35,128,192,151,212,110, 4,128,105, 28,
- 14, 39,193,203,203,171,152,205,102, 39, 0,152,142,231, 95,185, 26,140,167,113,210,190, 2,208,174, 57, 39,186,135,143,248, 67,
- 24, 62,226,190, 48,124, 68,170,107,196,240, 64, 97,248,136, 84, 97,248,136,251,238,225, 35,254,120, 5,253,245,101,182,239,203,
- 42, 79, 33, 65,160,208,202,242,252, 64, 0, 69, 4,129, 39,127,147,242,219, 96,131, 13, 54,216,208,168, 10,240,246, 30,237,229,
-229,117,222,203,203, 43,222,219,219,123,180, 21,167, 12,104,224, 38, 97, 34, 8,152, 44, 12,250, 77, 29,103,201, 92, 89,247,220,
-181, 86, 86,173, 46,167, 7, 65,192, 68,213,128, 32, 64,186,187,187,111,242,242,242, 90, 85,255,229,238,238,190,137, 32, 64,214,
- 57,214, 84, 71,224, 53,215,172,234, 49, 97,194,132,131,149,149,149,113, 58,157, 46, 46, 39, 39, 39,174, 79,159, 62, 7,234, 89,
- 34, 26,229,228,114,185,239,116,233,218, 61, 57,241,202,205,156,236,135,249,162,244,172,199,249,127,158,185,112, 59, 34,178,221,
- 45, 46,151,251, 78, 51,218,136, 0, 48,141,193, 96, 36,216,217,217, 61, 97, 48, 24, 9, 0,102,208,233,244, 19,171, 87,175,206,
- 79, 75, 75, 43,189,122,245,106, 85, 98, 98, 98,241,228,201,147, 31, 18, 4,241,103, 3,130,125,128, 21, 22,152,101, 5, 5, 5,
-103,196, 98,241, 89, 30,143,247,141, 21,199,215,114, 10,195, 71,220,151,200,244,148, 68,166,167,132,225, 35,168, 58,219,247,155,
-121,205, 45,181,209, 95,250, 2,135,195,241,179, 32,232, 95,165,137,254, 47,229, 1,224, 89,243, 93, 20,128,205, 53, 47,243,114,
-118, 79, 46,135,243,178,250,231,203,184,158, 54, 78, 27,167,141,211,198,249,111, 69,199,154,119, 47, 60,245,215,170,189,119, 55,
-119,213,225, 71, 57, 57, 57,118, 0, 16, 20, 20, 52, 19,192,225,230, 8, 9,130,192, 66,146,164,104, 0, 64,163, 17,159,245,237,
-219,175, 35,143,199,123, 38, 10,178, 90,173,102, 39, 36, 92,236, 79,146, 20, 81,115,220, 66,138,194, 70, 0,165,214,254,134, 78,
-167,165, 49,153,108,208,104,196,188,136,136,200, 86,101,101,101, 73, 52, 26, 45,182,184,184,184,178,217,102, 28,130,192,206,157,
- 59,131,188,188,188,254, 18,173, 89, 44, 22,179, 71,140,120,163, 89,124,147, 0,142,150,195,233,202, 34, 8, 47,147,209,232, 4,
- 0, 12, 6,163,242, 54,155, 29,245,237,215, 95,243, 9,130, 32,203,203,203,161, 86,171, 49,119,238, 92, 94,122,122,250,200,178,
-178,178, 45, 22,104,131,218,181,239, 56,247,236,217, 51,161,242,138, 74,205,206,245,219,147,213, 12,150,170,117, 88, 8,107,235,
-142, 61,206, 31,190, 63,254,227,204,204,180, 20, 52,156,142,164, 46,104, 0,142,206,153, 51, 39, 60, 38, 38,134,173, 80, 40,184,
-106,181,186, 85,108,108,236,210,168,168, 40,187, 14, 29, 58,176,127,255,253,119, 66, 38,147,129,162, 40,126, 72, 72, 8, 53,110,
-220, 56,205,129, 3, 7,102, 1,216,212,132,240, 93,248,244, 90,210, 54, 4, 7, 7, 47, 7,128,156,156, 28, 86,157,107,204, 12,
- 13, 13, 21, 0, 64, 86, 86,214,151, 20, 69,206, 1, 0,138,194, 26, 0,139, 27, 48,173,229,132,247, 28, 11, 16, 8, 72,187,114,
-144, 27,222,107,172, 6, 20, 30, 18, 64, 78,205, 3,193, 74,160, 78, 92,168,103,145, 33, 18,137,158, 43, 55, 97,116,116, 12, 65,
- 16,196,161,228,228,228,195, 18,137,164, 53, 73,154,166, 54, 85,206,198,218, 74, 40, 20,158, 53,153, 76,218,138,138,138,218, 64,
-153,194,118,111,118,119,181, 23,244,151, 86, 42,146,202,211,143, 39, 90,217, 55, 9, 87, 87,215, 73,101,101,101,171, 0, 76,201,
-200,200,232, 8, 0,161,161,161, 44, 0,119, 28, 28, 28,122,232,117, 58,194, 54,254,217, 96,131, 13, 54,252, 87,132,214, 93, 0,
-209,248, 79, 10,158, 29,207, 35,180,216, 0,144,148,148, 4, 0,156,231, 40, 8, 81, 87,192,204,158, 61, 27, 94, 94, 94,245,197,
- 11, 46, 93, 74,120,145,202, 62,243, 27, 95,125,245,149, 93, 85, 85,213,128,159,127,254,249,117,138,162,214,138, 68,162, 27, 22,
-206, 47,165, 40,172,161,209,136,207, 8,130, 0,135,195,205,158, 62,125,250,221,154,239, 90,253,249,231,159,252,225,195,135,171,
- 0,228, 3, 0,135,195,245,161,211,105, 65, 20, 69,153,111,184,141, 10,194, 49,128,191,145,205,238, 55,109,243,102, 99,167,225,
-195, 25, 2,161,144, 0,128,252,204, 76,215, 53,223,127,223,163, 50, 55,151,173,118,117, 45, 47, 87, 42,213,217,217,217,224,112,
- 56, 4,157, 78,239,100,169,194, 2,129,224,147,175,191,253, 78, 32,175,168, 82,107,228, 10, 29,221,104,208,218,243,248,166,210,
- 18, 73,185, 29, 79,160,250,236,139, 21,236,143,166, 78,252, 68,169, 84,206,180, 64, 53,107,222,188,121,161, 93,186,116,241,249,
-227,143, 63, 8,153, 76, 6, 6,131, 97,215,161, 67, 7, 68, 69, 69,153, 46, 94,188, 72,180,110,221, 26, 17, 17, 17,184,114,229,
- 10,174, 93,187, 70,116,236,216,145,127,228,200,145, 9, 6,131, 97,147, 37,113, 77,167,211,230,134,132,132,116, 16, 8, 4,186,
-160,160, 32, 76,157, 58, 21, 20, 69, 97,192,128, 1, 17,118,118,118,135,149, 74, 37, 59, 43, 43,243,117, 75, 34, 91,146,118,124,
-156,217,178, 5, 32, 18, 20, 30, 74,211,142,215,157,126, 12,205,202,202,122,173,178,178, 18, 79,219,133,170, 77, 96,254,250,235,
-175, 55,167, 47,149, 82, 20,214, 12, 31, 30,243, 25, 64, 16, 3, 6, 12,168,154, 53,107, 22, 45, 51, 51,243,221, 55,223, 28, 25,
-145,147,243, 16,205,124, 24, 8, 26, 52,104,208,149, 83,167, 78,185, 6, 5, 5, 73, 43, 42, 42,106,191,240,116,117, 26,156,120,
-100,195, 39,223,108,140, 13,217, 75, 17, 85,210,140, 99, 15, 44,244, 77, 98,210,164,247, 75,237,236,236, 70, 29, 58,116, 40, 75,
- 44, 22, 51, 88,172, 90,237, 74,119,119,119, 23, 6, 5, 5,205,112,113,113,145,208,105, 52,119, 10, 20,101,169,127,218, 96,131,
- 13, 54,216,240,220, 56, 89, 35,174, 78,214,255,130, 1, 0,113,113,113,181,145,105, 99, 98, 98, 26,125, 2,166, 40,170,244,222,
-189,123,190, 42,149, 10, 20, 69, 89, 51, 96,215, 93,162, 89, 74, 16,180,173, 52, 26, 49,147, 32, 8, 68, 68, 68, 62,222,176, 97,
- 67, 67, 57,189,116, 17, 17,145,143,233,116, 90, 27,138,162, 64, 16,180,159, 40,138, 44,109,132,179,193, 27, 17,155,205, 89, 8,
- 0,158,158, 94,185,167, 79,159,214,141, 25, 51, 6,223,127,255, 61,107,209,162, 69, 11, 24, 12,198,172,194,194,194,146, 38,202,
- 9, 0,139,133, 66,119,254,206,157, 59,131,166, 79,159,126, 87, 44, 22, 47, 6, 0, 47, 47,175, 85, 0,194, 0,228,215,217,135,
-109,219, 14, 20, 79,157, 58, 53, 91, 34,145, 44,110,140,115, 20,208,214, 55, 36,164,223,202,164, 36,138,166,213, 18,101,151, 47,
-203,165,165,165,134, 71, 82, 41,127,247,157, 59, 49, 75, 87,173, 98,250,250,249,225,210,137, 19,110,101, 42,149, 84,166,213,106,
- 74, 75, 75, 41,163,209,120,205,138,186,135,187, 11,221,249,219,127,248,233,182, 61,147, 78,186,183,240, 33,152, 46, 46, 12, 26,
-223,129, 77,103,208,180,109, 90, 5,178, 1,132, 91,106, 35, 22,139, 53, 97,208,160, 65,252, 3, 7, 14, 16, 17, 17, 17,112,114,
-114,194,229,203,151,145,146,146,130,202,202, 74,154,193, 96, 64,231,206,157,241,221,119,223,193,207,207, 15, 85, 85, 85, 40, 44,
- 44,116, 99,179,217, 66,131,193,208,216,245,124,166, 63, 45, 92,184, 16, 94, 94, 94, 48, 26,141,168,168,168,128,209,104,132,157,
-157, 29, 0,224,201,147, 39, 56,113,226,184, 53,125,201, 34, 40,138, 66,183,110,221, 20, 4, 65,100,212,183,104, 53,135,211,199,
-199,231,119,169,180,108,104,191,126,253, 80, 89, 89,105, 88,177, 98, 5,218,181,107,135,160,160, 32,139,229,244,246,246,158,102,
- 52, 26,151, 1,128, 94,175,223,205,229,114, 63,216,183,111,159,107,221, 20, 33,102, 75, 86,169,164,188,242,218,237,180,172,121,
-211,198,244, 73,186,145, 90,164,103,142, 40,148,221, 63, 46,107,160,156,139, 89, 44,246,207, 45, 91,182,252, 97,246,236,217, 94,
- 46, 46, 46,208,106,181, 75, 75, 74, 74, 48, 99,198, 12, 0,192,176, 97,195,218, 49,153,204,211,147, 39, 79, 70,235,214,173,139,
- 43, 42, 42, 10,147,147,147,167,170, 84,170,212,231,189,158, 86,194,198,105,227,180,113,218, 56,159, 27,214,106,145,191, 41,196,
-120, 54,156,195,142,103,132, 86, 76, 76, 12, 17, 23, 23, 71, 89, 81,177,242, 22, 45, 90,248,242,120, 60, 0, 40,111,110, 41, 72,
-146,156,229,234,234, 42, 89,188,120,113,207,160,160, 32,221,172, 89,179, 82,243,243,243,151,212, 61,166, 85,171, 86,223,252,248,
-227,143,200,206,206,206, 95,181,106,213,149,242,242,242,230,230, 49, 91, 68, 81,216, 80, 99, 29, 43, 59,113,226, 68,187,164,164,
-164,153,235,215,175, 23,126,244,209, 71,172, 79, 62,249,100, 60,128,239, 45,145,208,233,116, 85, 67,211,133, 13,193,203,203, 75,
- 71,167,211, 27, 13, 18, 23, 3,240,184,108,118,223,149, 73, 73,148, 46, 63, 95,245,203,186,117,246,219,111,221, 90,110,160, 40,
- 15,119,119,119,244,234,209,163,154, 75,167,151, 73, 74, 74, 72,247,182,109,233,121,167, 79,187,169,217,108,209,129, 3, 7,100,
-229,229,229,199, 44,154,240, 8, 66, 78, 82,148,206,174,133,159, 97,204,200,129, 17,183,111,166,100,218,187,187,209, 58,118,136,
-104,151,153,157,159, 12,146,212, 19, 4, 33,183,196,227,232,232, 24, 84, 94, 94, 14,185, 92, 14,161, 80,136, 13, 27, 54,192,211,
-211, 19, 42,149, 10,105,105,105, 84,139, 22, 45,136,164,164, 36,180,104,209, 2, 82,169, 20, 58,157, 14, 10,133, 66,162,213,106,
- 27,203,205, 88, 74,163,209,127,165,209,136,247, 9,130, 64,155, 54,254, 5, 91,182,108,209,145, 36,137,208,208, 80,188,249,230,
-155, 56,114,228, 8,210,210,210,204,150, 39, 93,203,150,173, 10,104, 52,162,101,141, 86,122,110, 11,140, 57,181,143, 72, 36, 26,
-245,156,127, 26,154,183,183,247,248,128,128,128,153,239,188,243,142,129,205,102, 67,169, 84,154,175,133, 97,232,208, 97, 85,195,
-135,199, 56,158, 60,121,178,209,114,234,245,250,101,197,197,197, 94,106,181, 26, 67,134, 12,249,100,237,218,181, 2, 54,155, 13,
- 0, 48,153, 76,207, 88,178,190, 94,191,247,236,156,101, 91, 18,206,254,254,157,247,215,139, 62,232, 51,126,214, 55, 9, 0,206,
- 52, 84, 48,157, 78,151, 43,147,201,166,204,155, 55, 47,118,219,182,109,206, 75,150, 44, 1, 73,146,160, 40, 10, 70,163,177, 54,
-145, 56, 73,146, 56,122,244, 40, 30, 61,122,244, 77, 61,145,101,131, 13, 54,216,240,183, 67, 51,180,200,223, 17, 94,120, 58,109,
-136,250, 98,235,191, 30, 25,158, 78,167,111, 63,119,238, 92,135,215, 95,127,157,209,191,127,255,136, 51,103,206, 68, 20, 23, 23,
-167,214, 88, 15, 34,250,247,239, 31,225,238,238,142,141, 27, 55,170,232,116,250,246,231,252,153,218,155, 94, 73, 73,201, 93, 0,
-107,143, 28, 57,178,102,218,180,105,240,244,244, 12, 19,139,197,255,213, 58, 59,112, 56, 29, 39,111,216, 96,100, 26, 12,180,205,
-107,215, 58,172, 75, 72, 88,243,199,193,131,140,110,221,186, 17, 20, 69,225,193,253,251,188,239, 54,109,226,191, 61,114,100,126,
- 86,110,174,241,248,217,179,134,210,226,226,138, 98,169,116, 25,128, 10, 75,252, 6,131,225,122, 78, 78,142,119,175,222,221,124,
- 18,111,165,166,140, 25, 57,172, 31,147, 65, 35, 30,230, 63,185,227,229,233,230,120, 41,225,188,218, 96, 48, 92,183,196,163, 84,
- 42,243,140, 70,163, 11, 69, 81,194, 75,151, 46, 65, 40, 20,162,178,178, 18, 6,131, 1, 58,157, 78,167, 82,169,184,229,229,229,
-208,104, 52,208,106,181,112,112,112,192,131, 7, 15, 74,141, 70,227,197,198, 56, 77, 38,211,100, 14,135,243, 21,147,201,100,179,
- 88, 44,209,157, 59,119, 32,151,203, 91, 57, 57, 57,125,111, 52, 26, 33, 18,137,144,148,148,244,169,131,131, 67, 62, 0,112,185,
- 92,176,217, 28, 87,173, 86,107, 4, 80,252,188,215,156,162,168,231,110, 47, 79, 79, 79, 63, 30,143,183,242,179,207, 22,134,182,
-111,223, 1, 82,169, 20, 36, 73, 66, 32, 16, 64,165, 82,193,193,193, 1,221,187,119,207, 91,185,114,165,152,162,240, 97, 19, 98,
-144, 94,211, 62,152, 54,109,154,192,193,193, 1, 69, 69, 69, 8, 9, 9,169, 21, 90, 98,105,249,131,171,183, 83, 51,231, 77, 31,
-219,123,255,137,132,140,179,151,238,100,140, 28,210,163, 61, 65, 80,173,154, 42,163, 68, 34,145, 50, 24,140, 89,211,166, 77,251,
- 42, 40, 40,168, 13, 69, 81, 8, 12, 12,196,160, 65,131,112,250,244,105,100,103,103, 67,169, 84,154,110,220,184,241,155, 88, 44,
-254,211, 54,132,219, 96,131, 13, 54,188, 82,252,197, 55,235, 25,139,214,127, 19, 18,137, 68,154,153,153,121, 38, 57, 57, 57,102,
-220,184,113,184,116,233,210, 36, 0,243, 0,128,195,225, 76, 26, 55,110, 28,146,147,147,145,153,153,121, 70, 34,145, 72, 95,198,
-111,178,217,108,141, 78,247,212, 56,197,229,114,185,205, 60,189, 85,205,148, 33, 0,180,106, 98, 95,227,166, 17, 6,195, 43,114,
-200, 16, 70,101, 74,138,124,231,205,155, 95,197,198,198, 50,122,246,236, 73, 24,244,122,152, 72, 18,254,254,254, 68,255, 1, 3,
- 4,191,198,198,186,152,148,202,164,175, 63,251,236,242,142,201,147,171,115,106,252,192, 44, 65,171,213,110,154, 57, 99,202,128,
-132, 75,151,125,194, 66,218,186,156, 57,151,112,215,213,213,145, 31, 20, 16, 32, 40,175,172, 48, 45, 89,244, 41, 67,171,213,110,
-182,196,163, 86,171,143,158, 63,127,126,164,175,175,175, 48, 53, 53, 21, 58,157, 14, 38,147, 9,253,251,247, 7, 69, 81, 28, 0,
- 36,131,193, 64,102,102, 38,244,122,189, 36, 39, 39, 71,244,240,225, 67, 14,128,213, 22,202, 87,160,213,106,145,145,241,116,214,
-174, 69,139, 22, 3,163,163,163, 97, 52, 26, 49,100,200, 16, 28, 63,126,124, 96, 70, 70,198,186,186,154,239, 69,219,188,198, 66,
- 22,234,237,237,125,164,102,151, 85, 78,240, 62, 62, 62, 17,254,254,254,219, 86,175, 94,205,106,209,162, 5, 40,138,130,179,179,
- 19, 84, 42, 21,202,202,202, 17, 22, 22, 6, 95, 95, 95,172, 94,189, 26, 0,126,107,202,226, 70,146, 36,196, 98, 49,242,242,242,
-144,155,155, 11, 95, 95, 95, 16, 4, 1,133, 66, 1,163,241,105, 78,110,190, 66,126,242,199, 95,255,236,123,112,219,178,240,174,
-145,129,126, 55,239,166, 75, 38,140, 26,200, 15,108,237, 23, 36, 77, 93, 65, 3, 86, 52,154,116, 89, 36, 18, 61, 20,137, 68,227,
- 36, 18, 9,171,170,170, 42,106,224,192,129, 27, 7, 12, 24,128,187,119,239,226,242,229,203,111,115, 56, 28,137, 94,175, 55,122,
-122,122,126, 72, 16,132,131, 94,175,223, 95, 94, 94, 46,182,141,135, 54,216, 96,131, 13, 47, 29,102, 31, 45,212,121,111,158, 69,
- 43, 52, 52, 84,144,159,159,255, 94,171, 86,173,216, 0,192,227,241,194,252,253,253, 23,228,230,230, 42,154, 91, 26,149, 74,245,
- 71,108,108,236,160, 31,126,248,129, 53,108,216,176,182, 71,142, 28,233, 2, 0,195,134, 13,107,107,111,111,143,216,216, 88,189,
- 74,165,122,105, 49,145, 12, 6,195,235,157, 59,119, 70, 69, 69, 5,242,243,243,155, 53,133,242,231,159,127,242,241,212, 47,171,
-201,125, 77,193,168,211, 57, 59,249,248,208,138, 19, 18,244, 21,114,185,215,235,189,123, 19, 6,189, 30, 52, 26, 13,229,229,229,
- 40, 44, 44,132,163,147, 19,145,153,147, 99,183,107,225,194, 63, 91,181,111,207, 54,233,116,174,205, 40,166,178, 76, 82,250,254,
-199,179, 62, 58,186,127,255,111,194, 42,185,252, 17,143,199,215,114, 56, 44,207,217, 31,127,108,170,168,168,152, 8,160,218, 10,
-158,213,251,247,239, 31, 50,100,200,144,251,126,126,126,238, 82,169,212,179,170,170,202, 84, 81, 81, 65,199, 83, 95, 43, 2, 0,
- 18, 18, 18, 32,151,203,141, 38,147, 41, 9, 79, 99, 97,233,172, 45,104,203,150, 45, 29,163,162,162,250, 8,133, 66,200,100, 50,
-184,186,186,162, 67,135, 14,125,232,116,250,207, 5, 5, 5,178,151,217,235,227,227,227,237, 41,138,122,141,162, 40, 12, 25, 50,
-196,170,115, 76, 38,211, 7,209,209,209, 44,130, 32,160, 86,171,192,229,242, 32, 16,216,193,222,222, 1, 65, 65,193, 16,137, 68,
- 24, 60,120,176,238,209,163, 71, 91,197, 98,241, 31, 22,184, 32, 18,137, 32,149, 74, 81, 88, 88,136,178,178, 50, 0, 64, 89, 89,
- 89,173,115,254,203,128, 76, 38, 27,209,189,123,247,249, 51,102,204,128,209,104,196,136, 17, 35, 80, 84, 84,180, 46, 47, 47,239,
-128,183,183,247,248, 15, 62,248, 64,232,234,234,138,249,243,231,243, 0,124,105, 27, 15,109,176,193, 6, 27, 94, 58,234,251,104,
-253,213,162,213,212,156,168,167,167,103, 47,130, 32,150,170,213,106,182,121, 74,134, 32, 8,182, 80, 40, 60,174, 86,171, 87,137,
-197,226,102, 57,197, 85, 85, 85,201, 31, 63,126,124,252,250,245,235, 99, 71,141, 26,133,248,248,248,137, 0, 48,106,212, 40, 92,
-191,126, 29,143, 31, 63, 62, 94, 85, 85, 37,127, 25, 53,247,241,241, 25,218,187,119,239, 81,157, 59,119, 70, 92, 92, 28, 76, 38,
-211,181,230,156, 95,119,133, 33, 26, 88,117,104,222,103, 21, 25,157, 14,130, 32,106,173, 25,101, 82, 41,178,179,178, 80, 81, 89,
- 9,173, 70, 3,165, 74,101, 10,106,221, 90, 45,211,233,152, 4,208,220,185,175,130,228,219, 55, 10, 85, 74,165,187,171,179,139,
-154,207,231,160, 74, 46, 99,221,185,125,163, 26,192, 35, 43, 57,116, 20, 69,245, 62,125,250,244, 50, 58,157, 62,206,206,206, 14,
- 51,103,206,164,247,233,211, 7, 44, 22, 11, 90,173, 22, 85, 85, 85,136,141,141,149,154, 76,166, 54, 53,231,216,241,249,252, 61,
-116, 58,253,137, 66,161, 88,106,241, 7,116,186, 97, 49, 49, 49, 12,157, 78,135,175,191,254, 26,203,151, 47,199,144, 33, 67, 24,
-183,111,223, 30, 6, 96,255,203,234,241, 36, 73, 98,224,192,129,117,157,225, 51,172, 57,143,201,100, 70, 4, 4, 4, 64, 42,149,
- 66, 42,149, 66, 40, 20,194,219,219, 27,158,158,158, 88,183,110, 29,181,113,227,198, 51,122,189,126,107, 89, 89, 89,169, 53,101,
-200,205,205,173,181, 12,106, 52, 26, 40,149, 74, 20, 21, 21,213, 78, 29,170, 5, 14, 67,102,189, 63,188,189, 82,173, 86,221,124,
-144, 83,184,244,147,241,221,148,106,181, 42, 39,175, 48, 27,216, 68, 90,209,191, 63,156, 56,113,226,135, 99,199,142, 69,117,117,
- 53,174, 95,191,142, 30, 61,122, 96,205,154, 53, 94, 73, 73, 73,243, 58,119,238, 12, 38,147,137, 75,151, 46,193,104, 52, 22,217,
-198, 66, 27,108,176,225,239,140,127,168,127, 86,147,104,210,162,229,235,235,235,100, 50,153, 62,141,142,142, 30, 56,114,228, 72,
- 12, 30, 60,248,153,239,247,239,223,111,127,248,240,225, 85,155, 54,109, 26,162,215,235, 87, 55,103,170,143, 36,201,163,251,247,
-239, 31,214,173, 91, 55,126,223,190,125,253, 1,128,195,225,232,246,239,223,175, 34, 73,242,232,115,212,197, 28,136,177, 20, 0,
-188,189,189,219, 49, 24,140, 81, 67,135, 14,109,247,254,251,239, 35, 45, 45, 13,177,177,177, 15,131,130,130,174,148,150, 54,203,
-191, 58,223,194,170,195, 85,150,172, 91,116, 54,187,188,170,164,196,201,206,207,143,233,108,111, 47,142,139,139,243, 29, 48, 96,
- 0, 81, 84, 84,132,202,202, 74,104, 52, 26,220,190,125,155,100, 0, 5, 12,103,103,162,224,250,117,130,206,102,151,227,217,149,
-124, 22,225,235,229, 28,248,197,162,233,173, 52, 90, 77,184, 76, 38, 51, 50,152, 76,102, 11, 79,167,162,172, 71,205,154,137,211,
-242,249,252, 40, 0, 12,146, 36, 85, 46, 46, 46,252,115,231,206,129,205,102,131, 32, 8, 68, 70, 70,130,203,229,178, 40,138, 42,
- 4, 0,123,123,123,246,246,237,219, 29,199,143, 31,127,217, 18,113,199,142, 29,153, 28, 14,231,141,160,160, 32, 92,191,126, 29,
-169,169,169, 5,215,175, 95,111,217,177, 99, 71,248,249,249,189,225,229,229,117,240,238,221,187,134,151,209,177,159,174, 88,109,
-190, 51,188,201,100, 34, 9,130, 0,141, 70, 3, 73,146,144, 74,165,104,211,166, 13,182,108,217,130, 13, 27, 54,124, 45, 22,139,
- 79, 52,131,203, 36,151,203, 33, 16, 8,144,154,154,170,141,142,142,230,208,104, 52, 60,124,248,176, 86,104,185,187,185,132,245,
-232, 28, 17,242,245,250,189,103, 5, 28, 14,103,112,159,168,208,244,156,130, 39, 20, 69, 88,156, 54, 14, 13, 13,101,181,105,211,
-102,226,216,177, 99,145,155,155,139, 85,171, 86,149,137,197,226,132,179,103,207,142,158, 49, 99, 6,189, 71,143, 30, 40, 47, 47,
-199,175,191,254,106,188,115,231,206, 47, 37, 37, 37,123,109,195,184, 13, 54,216, 96,195,223, 68,104,249,250,250,142,101,177, 88,
-243,223,122,235, 45,122,112,112, 48, 74, 75, 75,225,224,224, 96, 32, 8,130, 9, 0, 78, 78, 78, 6, 30,143,135,233,211,167,163,
-125,251,246,189, 22, 46, 92,216,131,193, 96,108, 17,137, 68,123,172,249, 97,137, 68,162,162,209,104,135,102,206,156,185, 58, 37,
-229,110, 27, 0,184,117,235,214, 99,145, 72,180, 72, 34,145,168,154, 89, 15,115, 80, 76,130,195,225,222, 12, 12, 12,204,139,138,
-138,114, 24, 57,114, 36,132, 66, 33,146,147,147,241,221,119,223,229,232,116,186,101,137,137,137,198,255,246, 69, 54,106,181, 37,
-119,142, 29,179,239,243,238,187, 14,179,163,163,215,126, 52,115,230, 15, 95,124,241, 5, 35, 56, 56,152, 80,169, 84,184,121,243,
- 38,117,248,240, 97,195,175, 95,125,181, 1, 2, 1,243,250,225,195,108,157, 78, 87,208, 76,203, 93,239,158,175,247, 10, 94,251,
-195, 38,104,212,213,184,121,237, 36, 42, 43,165,216,190,227, 72,176,143, 15,213,187,184,184, 56,209, 90, 46,130, 32,130,226,227,
-227,221, 41,138, 2,155,205,198,202,149, 43,225,237,237, 13, 7, 7, 7, 40, 20, 10,204,155, 55,207,113,206,156, 57,142, 0,144,
-150,150, 86, 27,158,193, 18, 68, 34, 81,247,233,211,167,219, 27,141, 70,156, 57,115, 70, 71, 16,196,210,243,231,207,255, 28, 25,
- 25,201,238,213,171,151,253,222,189,123,123, 0,184,244,178,132,214,115,158,247,240,220,185,115,157,199,141, 27, 71, 49,153, 76,
-162,170,170, 10, 78, 78, 78,216,178,101,139, 82, 44, 22,159,108, 38,215,202, 69,139, 22, 45,171,217,222,189,116,233,210, 41,171,
- 87,175, 22,150,148,148,212, 90, 53, 37,101, 21, 23,187, 71,127,108, 42,175,146,233,126, 89,191,112, 12,143,203, 97, 47, 93,253,
-203, 37, 3, 29, 55, 44,246, 43,163,145,205,231,243,217, 20, 69,225,208,161, 67, 40, 40, 40,248,160,188,188,188,196,100, 50, 29,
-249,244,211, 79, 23, 4, 7, 7,183,206,202,202, 42, 80, 40, 20,107, 36, 18, 73,158,109,184,179,193, 6, 27,108,120,101, 48, 59,
-193,155, 87, 31,158,196,211,233,196,198,133,150,201,100,154,126,246,236, 89, 58, 73,146,216,177, 99, 7,238,220,185, 67,241,249,
-252,165,124, 62,255, 71, 30,143,103, 82,171,213,211,166, 78,157, 58,126,249,242,229,180, 94,189,122,225,250,245,235,180, 54,109,
-218, 76, 4, 80, 87,104, 13, 64, 19,177, 54,100, 50,217,237,210,210,146, 54,117, 2, 84,182,225,112,184,183, 45, 84,166, 62,103,
-253,160,152, 93, 87,174, 92,169,244,242,242,210,165,166,166, 98,219,182,109,228,157, 59,119, 18,216,108,246,118,177, 88,172,181,
-146,243,101,160,150,147,109, 52, 38,239, 91,176, 32,180,211,136, 17,228,148,249,243,171, 89, 60,222, 39,107, 55,109, 90, 88,165,
- 80,120,131, 32, 40, 87, 71,199,130, 29, 43, 87,174, 26,242,198, 27,213,105,137,137,220,148,248,120,166,208, 96,184,215,156,114,
- 22, 23, 23, 39, 94,186,116, 25,187,119,254, 0,189, 94, 11,113,241, 83,157, 86, 86, 46,131, 5,145,245, 23, 78,163,209, 40, 27,
- 61,122, 52, 11, 0,111,194,132, 9,108,137, 68,130,182,109,219, 2, 0,228,114, 57, 78,158, 60,137,144,144, 16, 0,192,131, 7,
- 15,106,183, 45,149, 83, 32, 16,188,209,163, 71, 15, 20, 20, 20, 32, 45, 45,237,130, 88, 44, 46, 7,112,161,168,168,104, 88,231,
-206,157,113,244,232,209,225, 77, 8,173,102,181,145,149, 66,235, 47,156, 60, 30,111,209,145, 35, 71, 62,184,118,237,218,184, 5,
- 11, 22, 48,251,247,239, 15, 0, 80, 40, 20, 42, 0,166,230,112,170,213,234,237, 0,106, 87,206,230,231,231,239,155, 63,127,126,
-210,220,185,115,133,230,242, 73,211, 79, 92,151, 2,215,195,251,124,240, 69,247,206,225,193,223,108,140, 61, 91, 88, 84, 26, 43,
-203, 56, 46,179,166,238, 20, 69,193, 96, 48,128, 36, 73,184,184,184, 40,203,203,203, 33,145, 72,242, 36, 18,201,204, 71,143, 30,
- 53,171,238, 47,179,207,219, 56,109,156, 54, 78, 27,231,255, 40,172,143, 12, 79, 81,148,145, 36, 73, 92,186,116, 9, 71,142, 28,
- 49,233,245,250, 15,197, 98,113,221,104,213,155,146,147,147,227, 71,143, 30,189, 39, 43, 43,139,158,158,158, 14,138,162, 76,205,
- 41,141, 70,163, 49, 16,196, 95,247,189,104, 45,119,239,222,141,146,146, 18,125, 81, 81,209,121,163,209,120,244, 5, 87, 47,190,
-240,170,195,221,128,246, 29,157,238,252,242,158, 61, 7, 46,139,143,231, 76,249,252,115,237,164,247,223,255,212,164,211, 25,232,
- 44, 22,201, 22, 8,104, 38, 14,135,153,150,152,200,221, 56, 99,134,139, 90,171, 61, 19,219, 12, 7,115,179, 69,171, 79,159, 94,
-152, 52,101, 46,212,117, 44, 90,215,111,103, 67,171, 71,179, 44, 90, 90,173, 54, 92, 44, 22,131,203,229, 22, 2,240,124,239,189,
-247, 64,146, 36,212,106, 53, 20, 10, 5, 68, 34,145,236,253,247,223, 55,213,136, 39,198,168, 81,163, 28,172,225,245,247,247,247,
-102, 50,153, 56,115,230, 12,152, 76,230, 73, 0, 96, 50,153, 39,227,227,227,135,189,253,246,219,240,241,241,241,207,205,205, 37,
- 96,193, 63,205, 61,124,196, 31, 20, 16, 8, 2, 1, 79, 77,112, 8, 16,134,143,184, 79, 0, 57, 53, 81,227, 51, 58,118,236, 8,
- 88,233,151, 85, 23, 53,139, 59, 54, 24, 12,134,131, 11, 23, 46,156,217,181,107,215, 65,203,151, 47, 39, 80, 19,170,225, 5,145,
- 93, 92, 92,252,250,226,197,139,207, 82, 20,245,140,232,151,148, 85, 92,236, 22, 51,139,170,170,146,165, 72, 51, 78, 60,104,150,
-197,212,104,124,161,112, 22, 54,216, 96,131, 13, 54,188, 52,171,214, 95,208,168,208, 34, 8, 98, 71,239,222,189, 63, 4, 64, 39,
- 8, 98,155, 72, 36,250,203,224, 47, 22,139,179,189,189,189,191,111,221,186,245, 52, 0, 20, 65, 16, 59,154, 89,168, 82,138,194,
-119, 52, 26,177,240,169,184,123,174, 0,149,230,180, 36, 11, 1, 16, 52, 26,125,207,221,187,119, 63, 47, 44, 44,148, 90,105,129,
-104, 18, 47, 99,213, 33, 0,252, 6,228,189, 85, 80,112,118,126, 68,196,128, 33, 51,102,160,221,144, 33, 14,222, 45, 91,154,212,
-122, 61,249,224,202, 21,226,218,161, 67,172,148,248,120,166, 90,171, 61,115, 20, 40,108,110, 57,139,139,139, 19, 47, 38, 36,158,
- 27, 51,106,216, 32,255,214,222, 79, 69, 67,158, 8,101, 21,178,115,205, 17, 89,245, 68,239,136, 45, 91,182,156, 96,177, 88,140,
-186,169,108,244,122,125,133, 86,171, 13, 7,128,202,202, 74,239, 29, 59,118,252, 78,163,209, 10, 44,241,165,167,167, 31, 95,182,
-108,217,168,252,252,252,115, 69, 69, 69,249, 0, 80, 88, 88,152,111, 48, 24,246,136,197,226, 81, 5, 5, 5,135, 97,197, 34, 0,
- 10, 8, 76,187,114, 48, 18, 0,194,123,142, 69,218,149,131, 92, 0,145,225, 61,199, 2, 0,158, 55,151, 97, 93,212,132, 65, 88,
-122,253,250,245,253,131, 6, 13,154,138, 23,136,233, 85, 95,108,233,245,250,150,245,119,154, 45, 91,205, 33,210,233,116, 6,181,
- 90,109, 52,153, 76, 12,189, 94, 79,233,116, 58,131,109,156,179,193, 6, 27,254,173,160, 40,170, 51, 0,161,121,216,172,121, 23,
-214,219,214,161, 38, 93,160,121,168,172,249, 44, 37, 8,226,118, 29,142,218,253, 86,156, 11, 0,101, 0,238, 19, 4,209,152, 17,
-100, 71, 99,159, 27, 21, 90, 34,145,232, 48,172, 72, 26,109,237,113, 77, 96,113, 77,158, 56,224,249,243,176,213,114,152, 76,166,
-210,194,194,194, 23,110, 80, 26,141,150, 55,124,248,240,102, 29,111,233,152, 3, 64,193,199, 90,237,222,184,205,155, 59,156,217,
-182,205,199,100, 52,186, 18, 0, 69,103,179,203,117, 58, 93,190,208, 96,184,215, 92, 75,214, 51,214,152,199,197,131,115, 31, 23,
- 35, 32, 32,128,122,248,240,225, 83, 91,207,139,225,158, 82,169,244,181,212, 5, 84, 42, 85, 47, 43,197,224,111,197,197,197,191,
- 53, 32,216,127, 23,139,197,191, 91, 91,168,218,164,210, 0,141, 36,200, 49,225, 61,199, 30, 2, 64,154,147, 74,191, 76,148,148,
-148,100,161, 38,206,219,223, 13, 5, 5, 5, 90,130, 32,246,125,247,221,119, 19, 82, 82, 82, 14,136, 68, 34,173,109, 40,182,193,
- 6, 27,254,205, 34,139, 32,136,184,154,207, 49, 53, 70,161,184,250,219,230, 99,204,199,213, 61,198,204, 81,127,127, 83,231, 2,
-192,162, 69,139, 62, 95,181,106, 21, 31,128,181,201,152,159, 59,169,244,171, 66,233,223,132,163,174, 40,216,249, 42, 42,186, 25,
-208,193,104,188, 1, 99, 29,159,124,195,203, 53, 68, 60,124,248,144,248, 55,255,225,204, 73,165,235, 32,226,127,117,240,201,207,
-207,223,226,231,231,183, 93, 36, 18, 25, 97,131, 13, 54,216,240,239,133,176, 33, 97,212,136, 40,139,105,234,251,103, 30,220, 27,
- 56,174,161,207, 4, 65,196,173, 90,181, 42,166, 25,229,173,181,104,209,108,109,103,131, 13,255,108,252,127,172,164,181,193, 6,
- 27,108,248, 55,160,190, 21,203, 44,190,234,127, 94,180,104,209,231,104,122,198,201, 11, 79,173, 88, 94, 53,159,107,253,181, 8,
- 60, 93, 57,208, 16,154,179,154, 96,192,115,212,239,188,141,211,198,105,227,180,113,218, 56,109,156, 54,206,255, 57, 78, 75,220,
-231, 27, 16, 68,209,141, 77,245, 53, 53,141, 88,127,219,210,185,150,142, 37, 8,162,177, 48, 63,230,169,194,250,239,175, 28, 3,
-108,156, 54, 78, 27,167,141,211,198,105,227,180,113,218, 56, 95, 4, 20, 69,117,166, 40, 42, 26, 79, 23, 76, 81, 20, 69, 69, 83,
- 20, 53,100,209,162, 69,139,205,251, 22, 45, 90,180,152,162,168,254,230,227,106,142,169, 61,199,188,175,254,123,253,125, 77, 29,
-219, 68, 17, 63,172,183, 93,251,249,239,226,163,101,131, 13, 54,216, 96,131, 13, 54,216,208, 32,204, 43, 6,235, 88,155,164, 0,
- 30,172, 90,181,170,178,142,239,148, 20,192, 61, 0,237,107,142,147,214,136,180,186,190, 85,186,154,207,186, 6,142,209, 89,115,
-108, 35,216,209,200,182, 77,104, 53,134,246,158,180,175,252, 90,184, 71,213, 52, 0,168,154, 36,192,100, 77,188, 34,202, 28,184,
-136, 36, 81, 60,222,237, 0, 0, 32, 0, 73, 68, 65, 84, 65, 81, 20, 68,146,170,228, 7, 18,124,241,188,191, 23,228, 13, 23,119,
- 46,119, 3, 73, 81, 61,107,118, 37,202,202,181,115,211,228,168,178,150, 35,196, 3,161, 92, 26, 62, 37, 41,180, 3, 0, 26,129,
-251, 26, 18,223,103,150, 54, 63,158, 84, 67,253, 60, 92,136, 15,217, 60,254, 91,142, 78,206, 1,149,149,101, 57,122,141,246, 96,
-186, 20,219,209,252,188,140,240,119,198,107, 36,133,207, 1,208,152, 52,172,203,169,176,122, 37,135, 13, 54,216, 96,195,139, 90,
- 71, 94, 40, 46, 30, 65, 16,166, 6, 56,137, 23,228,180, 5,195,179, 66,108, 53,176,251, 86, 3,251,110,255,157,202,221, 44,161,
- 21, 38,196, 12, 16, 88, 1,128, 2,133, 47,211,165,248,169, 89,231,123, 97, 0,151, 78,223, 5,128,174,209,155,230, 83, 36,146,
- 26,188,152, 52,188,206,101,209,215, 1, 32, 53, 38,211,228,116,177,245,254, 98,225, 62, 24,194, 32,105,251, 72,138, 98,154, 72,
-106, 15, 40,196,217,177,112,245, 70, 49, 52,205, 41,171, 95, 11,247,168, 99,183,196,131, 18,126,154,141,174,237,218,130, 50, 25,
- 1,210, 0,126,175, 79,113, 97,253,123,232, 26,234, 7,138, 52, 0,164, 17,118, 67,215, 98,104,132, 35,245, 64,242,124,121,176,
-131,188,225,210,210,205, 61,117,231,206, 93,158,222,254, 97, 4,105,212, 35,235,214,185,241,115, 22, 46,235, 23, 14, 89,132, 53,
- 98,171,157, 23,166,248,181, 10,254,116,238,138, 31,232, 94,222,190, 2,210,160, 53,150,228,101,116,220,180,102,217, 97, 22,173,
- 96,221,125, 49,118, 89,219,151,195,132,152,198,224,176,199,242,184,130, 0,149, 74,241,208,164, 55, 28,164, 49, 25, 67,190, 95,
-187,161, 67,159,129,195,236, 76,138, 18,154,129, 68,216, 31, 7,126,111,185,121,203,214, 97,169, 98,211, 27, 0,200,230,212,153,
-164,176, 48,123,239,135,195,152, 12, 58, 17,250,193, 78, 58, 96,124, 46,161, 21,234,142,119, 8, 10, 22,195, 75, 80, 4, 46,103,
- 72,240,219,243,252, 70,136, 59,126, 38, 40, 4,129,192, 33,130,194,239,233, 82, 72,108, 67,158, 13, 54,252,187, 64,163,209, 18,
- 72,146,236,251,146,133,193,107, 20, 69,221,176, 93,221,255,109, 52,207,162, 69,224,235,180, 71, 69,206, 48,233, 17, 30,228,255,
- 21,208, 60,161,197,165,211,247,220,206, 41,245,132, 81,143,157,223,204, 60,160, 51, 0, 70,131, 30, 38,163, 1, 38,163, 1, 70,
-163, 30, 38,131, 1,148, 65,139,101,191, 36, 0, 58, 5,162, 34, 2,247, 0, 38, 47,107,127,131, 73,209,246, 37, 95, 57,231, 66,
-232,100,248,237,167, 85, 31, 23, 73,171, 63, 62,127, 95, 84, 22,230,174, 94,156, 46,193,175,205, 17, 4, 9,219,102, 35,246,232,
-201, 39, 27,127, 86,102,146, 20, 5, 23, 7, 94,240,248,152, 52,223,189,199, 19,138, 54,236,209,100, 2,128,163,128, 29, 60,241,
-126,142,223,139, 52,130, 59,151,187, 97,251,214,205,158, 94,174, 60,194,120,109, 53,140, 38, 19,124, 91, 70,211, 23,207, 26,239,
-245,245,250, 93,235, 33,215, 78,106,234,252, 96,119,132,181,106, 29, 58,127,207,201,107,126, 74,185, 68,119,110,255,231,143,160,
-133,193,211, 39,148,249,213,170, 31,232, 75, 62,155, 61, 79,103,122,114, 51, 75,130,116, 75, 99, 77,168, 59,142,175, 90,189,182,
- 93,191,161, 49,118,100,181,148,174, 81, 86, 7,237,252,101,215,138,144,118, 93,248,189, 34, 90,176, 36, 7,167, 19,106, 69, 5,
-244, 52, 46,167, 95,248, 0, 7,245,132,183, 13, 59,119,199,206, 74,151, 96, 83,115,234,108,162,254,211,247, 72,242,249,163,174,
- 19, 20,122,165,220, 72,152,102, 18,221, 6,101, 50, 0, 38,125,237, 59, 76, 6, 80,228,211,247,174,211,127, 1,240,124, 66,139,
- 70, 97,208,249, 43,183,189, 74, 75,196,157,215,175,253,118, 49,117,251,246,105,152,176, 47,163, 2,137,205, 21,152, 0,130,218,
-184,210,207, 26, 76,208, 22, 85,153,130,204, 59,251, 5,113,186,123,217, 17,253, 11,101, 68,210,229, 71,234, 68,219,208,100,131,
- 13,255, 47, 22, 19, 35, 69, 81,140,151,204, 57,140,162,168, 83, 47, 72,243, 41,128, 41, 53,219,187, 0,124,255, 18,138,214, 2,
-128,103,205,118, 9,128, 39,182, 30,240, 66,168,239,252,254,220,113,180,184,160, 72,224,208, 72, 0,224, 53,183, 20, 20,192, 5,
- 65, 7, 12, 74,140, 24, 58, 16,110,238,158,128, 65, 5,232, 85,248, 63,246,206, 59, 60,138,170,109,227,247,204,108, 75, 54,189,
-108,122, 33,180,132, 64, 32, 32, 16, 58, 65, 65, 4,194, 71, 17,164, 9, 8, 47, 69, 68, 17, 65, 84, 80, 64, 68,138,138,128,210,
- 65,165, 73, 71, 74, 64, 74,148, 94,162,212,132, 36, 4,146,144,222,123,178,217, 54,229,124,127,164,152, 64,202,110, 64,125,225,
-157,223,117,205, 53, 91,239,157,153, 51, 59,115,207,115,158,231, 12, 88, 13,192,170, 1, 86,131,220,140, 36,192,160, 6,226,127,
- 5, 71,136,194,228,213,213, 21, 1,177, 7,240, 74, 7, 47,168,108,204, 48,107, 72,107,199, 45,167, 98,183,109, 59,115,191,111,
- 84, 54, 70, 25,181,172,132, 32,168,109, 11,172,221,166,142, 57,126, 43,167, 63, 0, 12, 12,116, 56, 21,212,218,219,115,205, 14,
-109,204,201,136,130,215, 0,224,181, 54,214,191,118,246,115,245, 18,208,248,168,175, 64, 72, 79,183, 38, 45, 40,254,246,102, 8,
-197,169, 40, 46,214, 32,245,209, 78,216,185,191, 68,243, 2,122, 55,244,125,115, 6, 31,191,183, 96,165,180,172, 56, 75, 47, 24,
-114,120, 21, 83,192, 72,228, 2,133,180, 11,186, 82,161,144,159, 61,117, 60, 55,231,179, 47, 63, 6, 48,174, 62,157,214, 78,152,
-185,106,213,154,182,221, 59,182,114,202, 60, 52,139, 42, 45,200, 2,199, 40, 21, 67,186,118,135,109,203,214, 66,214,249, 85,148,
-188, 89, 95,216, 58, 52, 67,218,213,159,145,120,253, 48,213,163,195,112,197, 79,123,100,111, 2,134, 90,141, 86, 11, 71,244,232,
-223,171,243,190,102, 94,110,174,132, 8, 16, 4, 2, 34,240, 40,213,178,248,100,127, 60,120,158,199,235,253,123,188, 98, 33,167,
-136, 32, 8, 32, 68, 64, 74,102, 94,217,239,225, 49,175,196, 23, 32,220,152, 72, 85, 96,151, 62, 61,238,222,188,222,138,141, 61,
-142,142,227,150,199, 80,192,229,106,251, 92,143, 91,167,127,106, 5,252,216,120, 47, 71,129, 79, 60,181, 2, 94,189,166, 50,155,
-247,156, 82, 21,229,164, 77, 56,180,115,195,136,141,155, 55,239,142,201,198,116, 83, 76,214,251,189,228,151, 87,255, 94,236,208,
-181,153, 69, 78, 74,181, 56,101, 83, 59,186,255,166,147, 81,239, 93, 91, 18,212,106,193, 9, 82,120, 49, 78, 27, 33, 30,183, 68,
- 68,254, 89, 8, 33,207,220,108, 37, 37, 37,165, 63,141,217,114,119,119,239,149,150,150,246, 85,101,182, 10, 69, 81, 95, 53,105,
-210,100,225, 95, 23,170, 53,174,245,138,120,158, 31,151,150,150,118,177, 62,205, 65,131, 6,185,157, 56,113,194,167,154,166, 15,
- 0,159,218, 62,107,107,107,203,119,235,214, 45,241,196,137, 19,233,226, 30,210, 40,195,101,178,209,138, 73, 62, 48,171,131, 46,
-163, 20, 0, 98,140,248,124,141, 46, 63, 45,203,175,216,190,120,252,138, 54, 77,236, 81,162,214,227,204,141, 68,240, 60, 11,158,
-227, 42, 34, 91, 28,120,142, 69,255, 64, 71,116,211, 78,199,119,161,247,193,241,194,242,250, 52, 31,199, 64,132, 49,237,251,190,
-177, 95, 16,136, 92, 33,165,139,124, 61, 29,156,230,188, 30, 72,207, 26,210, 6, 26, 3,247,198,207,231,227,126,143,206,198, 86,
-163, 52,133, 39,135, 39, 34,181,189,198,115, 13,174,123, 61,209,168,160,190,193, 61,173,137,174, 8,108,110, 60, 74,202, 88,196,
-231,177,200,212, 22, 66, 65,101, 24,165, 41, 16,180,243,112,119, 85, 94,217,247,209, 35, 7,166, 88,226,196,112, 50, 57,205,129,
- 23, 8, 67, 10,163,116,246,173,250, 73, 43,243,182,234, 91, 78,115,165,213,248, 94,175, 14,178, 73,254,121, 42,101,238,219, 31,
- 78, 29, 60,241,232,226,118,100,223, 8, 69, 94,122, 34,101,173, 45,132,179, 67,115, 12, 24, 55, 10, 95,143,234,132,146,226, 18,
- 48, 25,113, 54,114,169,194, 22, 48,212,170, 73,120,140, 91,181,242, 75, 87, 9, 67,151,111,207,202,137,103,161,209,233, 0,158,
-131,153, 68, 0, 69, 42,223, 99,193,179, 6,101,187,225, 31,205, 0,248,240,134,214, 61, 58, 27,123, 90,171,208, 19, 2,219,138,
-176, 26, 80,192,229,168,156,191,204,143,191, 19,198,188,212,255,173,158,132,194,165,198,180, 81,128, 3, 66, 58,250, 88, 90, 88,
- 20,199, 32,245,224,187,136,131, 25,113,238,254, 31,140,153, 52, 83,185,101,203,150,193, 0,121, 27, 53,115,212,170, 52, 91, 57,
- 51,211, 88, 30, 11, 1, 64,195,146,237, 86,114,106,210,170,189,215, 28,192,252,117,135,135,202, 72, 86, 92,158, 80, 96, 56,247,
-233,253, 46,115, 66,131,219,222, 14, 78,161, 40, 69,242,133,135,186, 34, 83,246, 37, 19, 17, 53, 69,205,191, 93,211,218,218,186,
-105,147, 38, 77, 22,178, 44,219, 75, 38,147, 57, 27, 12, 6, 8,130,144, 41,151,203, 47, 37, 38, 38, 46, 41, 46, 46, 78,248,111,
- 91,247,187,119,239,154, 98,182, 26,212,148, 74,165,184,127,255,254, 67, 19,204, 86,216, 99,223,223,117,249,242,101,236,223,191,
- 31, 0, 16, 27, 27,139,150, 45, 91, 90,212,246,197, 71,143, 30, 89, 4, 7, 7,239, 2,224, 89,159,102, 68, 68, 68,211,227,199,
-143,227,224,193,131, 0,128,251,247,239,195,215,215,183,214,133,185,124,249, 50, 51,118,236,216,166, 0,210,255,129, 54,122, 17,
- 76, 86,245,249, 95, 70, 43, 52, 52,148,132,132,132, 80,143, 63,174,133,120, 47, 59,121, 7,104,121, 0,136, 55,117, 9,162,179,
-176,114,237,206,211,175,253,118,112,125, 47, 51, 25,141, 69, 91,231,164,228,228,151,116,145, 80,229,221, 47, 28, 1,109,103, 41,
-191,182,124, 66,160, 87, 65,169, 22,199,254, 72,187, 24,149,109, 90,136, 52, 42, 3,103, 1,193,182,252, 25, 15,173, 38,219,119,
-194,215,103,247,238,253,248,181,118,179,135,180,195,209,171,137,179, 1,174,193, 81,223,137, 32,128, 8, 92, 85,242,123,197,165,
- 3, 32,212,188,129,175, 0, 82,254,154, 96, 90, 68,171, 55, 32, 41,112,194, 0, 43,165,124,221,180,105, 83,172,217,156, 7,200,
-215,203,144, 82,160, 69,166, 70,138, 82,137, 19,210, 98, 34,120,154,194,217, 6, 67, 46, 20,138, 9,167,181,181,147, 91,210, 1,
-253,102,184, 23,159,154, 95, 32,167, 56,198,122,216, 82,219,220,223,190, 77,228,212, 57,106,138, 66,131,195,207,219,216,216,182,
-212,230, 37, 50, 69, 5,185,176,117,105,131,215,222, 8,193,231,131, 90,163,164, 88,141,156,252,107,164,133,171, 53,149,116,105,
- 55, 22, 12,240, 71, 94, 86, 6,116, 44, 64,169,117,249, 90,189,182,180,206,237, 72, 99,243,251,115,231,141,241,118, 85, 89, 84,
- 22, 21, 16,129, 71,160,127, 51,244,235, 21,132,179,151,175,224,207,136, 88, 8, 21, 69, 5, 68, 16,144,154, 93,144,165, 53,240,
-219, 77,218,160, 60, 7,194,106,107, 53, 98,104, 68,151, 97,128, 19,148, 60,240, 89,167,166, 86,147, 63, 14,241,182,178, 80, 80,
-208,178, 60,180,122, 22, 37, 87,214,193,161, 73, 91, 40,205,204,168, 14,208, 72,110,161,246,109,171,101,177, 48, 33,163,208, 21,
-165,153, 24,219,175,205,123, 59,150,191, 99, 65,153,149,239,154, 44, 95, 51,146,117,101,113,167,211, 99,191, 56,114,110,255,129,
-209,110, 95,127, 56, 62,184,255, 7,219,207, 1, 56, 37, 30,183, 68,158, 71, 70,140, 24, 97,150,149,149,117,222,211,211,179,117,
-191,126,253,148, 61,123,246,132, 90,173,198,153, 51,103,160, 86,171,189, 61, 61, 61,189,207,156, 57, 51, 60, 57, 57, 57,202,195,
-195, 35,248,224,193,131, 70,231,208, 86, 24, 32,166,234, 16, 12,112, 20, 69,161,226, 53,170,226,181, 70,223,231, 86, 46,151, 35,
- 41, 41,233,153, 71,182,210,210,210, 30, 54, 38,178, 85, 90, 90, 42,115,119,119,135, 74,165, 2,207,243, 80,171,213, 56,114,228,
- 8,138,138,138, 32, 8, 2,204,205,205,177,116,213, 86,196,220, 58,143,240,240,112, 20, 21, 21,201, 26,210, 76, 77, 77,165, 2,
- 3, 3,161,211,233,192,113, 28,180, 90, 45,194,194,194,170,158, 75, 36, 18,204,251, 98, 53, 98,111,156,199,237,219,183,145,154,
-154,250,143,220,109,196, 4, 47,242,223, 72,157, 99,102,253,227, 85,135, 60,207,125,178,101,199,222,107,159, 76, 31,133,153,163,
-251,122, 46, 89,127,184,111,116, 46,118, 0,128,191, 35, 38,188,217,167,133,151,173, 82,138,207,127,190, 1, 16,242,201,211,254,
-222,189,124,196,182,118, 22,102,255, 18,158,116,126,254,168, 14,104,230,106,221,178, 64,158, 47,143,143, 55,226,158,130, 2, 7,
- 59, 75,133,223,192, 64,135, 83, 16, 4,216, 90, 41, 90,129,231, 96,107,169,240,123,173,141,245,175, 0, 96,173,148,182,170, 45,
-242, 85, 23, 29, 61,165, 83,149, 10,201, 84, 11, 43, 91,175,137,131,251,153, 15, 28, 60,220,220, 82,202, 33, 47,252, 12,138,165,
- 30, 96,237,189,161, 99,243,145,154, 16,199,255,118, 61, 58, 45,183, 68, 55,167,193,197, 36,184,152,150,112, 95,213,180, 93, 63,
-187,220,208, 5,217, 77,223,250,217,135,134, 64,151,236, 30,150,101,225,212,217,252,143,248,132, 82,129,212, 26,209,169, 65,113,
- 81, 81, 34,203,195, 85,195, 75,172,226,206,253,132,143, 7,180, 69, 65,126, 54,180, 6, 14, 69, 26,206,224, 98,107,166,208, 37,
- 68, 66,103,224,160,103, 5, 72,109,221,113,230, 90, 68,174,192,178,191,214,165, 25,159,135,219,241, 71,110, 91, 86,127,173,153,
- 35, 2, 63,178, 54,191, 13, 86,131,164,212,116,236, 56,113,173, 67,124, 30,110, 63, 77, 59, 19,129, 43,239,126,174, 22,201,162,
- 8,122, 54, 38, 9,190,149, 19, 58,203,204,100,223,127, 53,123,108,235,174,190,246, 10, 33,245, 26, 40,193, 0, 11, 94, 2,141,
-156,135,141,103, 51, 8,250, 18, 82,166,213, 22,222, 3,234,107,124, 6, 0,136, 65,141,175,199,183,177,160,236,154,129,143, 63,
- 5, 73,251,169, 96, 43,162,253,113,121, 66,132,225,220,167, 49,221,230, 30,239,253,197,217, 62,209,233, 39, 22, 69,187,143, 88,
- 23, 8,108,111, 34,158,174, 69,158, 71,252,252,252, 92,210,210,210,238,205,157, 59,215,126,216,176, 97,248,229,151, 95, 80, 92,
- 92,140,237,219,183, 99,205,154, 53, 88,188,120, 49, 88,150,197,150, 45, 91,148,135, 14, 29,234,188, 97,195,134, 84, 47, 47,175,
- 54,201,201,201,153, 13, 24, 44, 10,128, 2,128,180,226,220, 69, 1, 16, 78,158, 60,137,129, 3, 7,226,228,201,147, 66,197,107,
- 60,202, 47,126, 26,117,239, 79,185, 92, 14,185, 92,142,162,162,162,103, 98,182,164, 82, 41, 44, 45, 45, 33,151,203, 81, 82, 82,
- 98,178,217,226, 56,142, 73, 77, 77, 69, 81, 81, 17,250, 13, 30,140,213,203,151,163, 79,159, 62,232,215,175, 31, 8, 33, 8, 11,
- 11, 67,223,238, 1, 24,245,127,193,136,142,142, 6,199,113, 70, 45,111,102,102, 38,178,178,178,240,218,224,193,216,186, 97, 3,
-130,130,130,224,231,231, 7,142,227,112,254,252,121,140,232,223, 29,102, 67,251, 34, 54, 54, 86,220,169,141,143,102, 61,147, 28,
-173,167,230, 94, 14,174, 11, 71, 47,132,142,238,223, 57,100,112,143,214,216,186,239,183, 47,161, 42,222, 11, 0, 14, 58,197,210,
-241,125,154, 33, 42,185, 0,191,221, 78, 15,141,206,197, 51,169,214, 16,120, 56, 58, 88, 43, 1, 70, 14,141, 65,224,172,227, 27,
- 78, 96, 22, 8,129,178,215, 71,120,115,112,148,103, 80,107, 79,207,202,170, 67,203,129,223, 98, 66,196, 67,175, 78,126, 46, 94,
-224, 89,128,103, 97, 61,234,103,224, 11,139, 6,151,163,187,143,252,236,251,179,102,117, 27, 48,244, 13,115,185,210, 6,124,113,
- 10,216,204, 8,228, 61,184, 8,181,178, 37, 50,147,226,177,255,116,120,209,131,212,188, 98,154,198,153,172, 34,221,135,241, 5,
- 40,109, 72, 87,203, 98,249,194, 5,115, 6,237,223,187,207, 74,209,172, 7, 21,183,110, 96,145, 92,194, 41, 84, 62, 47,209,101,
-102,142,100,217,246,125,214,106, 61, 86, 52,164, 83,166, 46, 62, 28,118,230,212,168, 22, 77,123, 88, 61,250,243, 4, 52, 90, 29,
-116, 44,208,166,115, 48,120,158,200, 41,154, 18,172, 25,134,202,206, 43, 0,197,242, 89,151,238, 60,202,184,124, 39,158,209, 89,
- 97, 69,189,163,139, 60,238,238, 41,230,189,193,193,237, 1, 86,131,255,235,213, 22,171,119,255,246, 46,192,191,245,116,141, 92,
- 30,209, 34, 64,143,214, 42,108, 34, 4, 61,110, 28, 89,211,170,227,208,247, 97, 74, 68,171,141, 35, 6,248, 55,117,251,105,245,
-210,143,236, 29, 60, 90, 50,148,192,130,184,180, 3,138, 83, 9,149,122, 13, 54,238, 65,224,221,186, 99,203,119,223,148, 10, 2,
-217,139,122,134,182,224, 5, 64, 72,190, 0, 62,230, 23,196,199,199,195,209,251, 6, 64,209, 32, 77, 30,193,192,149,127, 77,103,
- 32, 39,214,110, 63,222,231,195,151,151,183, 25,220, 74,226,117,237, 78, 92,246, 27,147,220,148, 93,188, 24,223,168, 12, 11, 58,
- 87,173, 22,196,227,151,200,243,132, 86,171, 61,188,114,229, 74,251,144,144,144,202,136, 12,174, 93,187,134,109,219,182,193,194,
-162,230,113,114,224,192,129, 32,132,216, 47, 90,180,232, 48,128,174,117,105,118,235,214,109,240,237,219,183,211,219,183,111, 31,
- 95, 97,182,100, 0,232,200,200, 72, 58, 37, 37,133,178,179,179, 35,110,110,110,108,122,122,186, 0,128,159, 52,105, 18,115,224,
-192,129, 22,106,181,250, 66, 99,141,150, 92, 46,127, 38, 57, 91, 82,169, 20, 20, 69, 65, 46,151, 67, 38,147,129, 16, 98,146,217,
-226,121, 94,114,242,228, 73,220,184,113, 3,139,219,183,199,108,119,119,216,219,219,227,252,249,243, 32,132,192,194,194, 2,249,
-249,249,216,187,119, 47, 94,126,249,101,112, 28, 39, 51, 70,247,224,193,131,184,121,243, 38,190,232,216, 17,179,109,108, 96,105,
-105,137,176,176,242,222, 64,133, 66,129,164,164, 36,132,133,133, 33, 56, 56, 88,220,169,159, 18,163,119,158,222,128, 36,159,130,
-139, 65,175, 1,225, 8, 64,193,205,223, 31,178,232,232,154,201, 57,198, 64,211, 88,240,221,142,208, 65,223,190, 63,152,154, 58,
-164,131,219,146,159,206,189, 13, 0,147, 95,247,117, 87, 42, 36, 88,123, 52,138,208, 52, 22, 60,139, 21,244,247,135,140,202,195,
-219,253,130,252,144, 94,168, 71, 92,122,225,239,209,128, 81,119,113,254,237,219, 55,177,243,216,249,148, 53, 59,181, 49,132, 16,
-216, 90, 42,252, 38,220,141,243,250,233,228,205,228, 85,251,181, 49, 68, 32,176, 85, 74, 91,189, 21,221,189,193,170,195,142,158,
-210,169, 31,204,153,211,125,200, 91,115,205,184,152, 3,208,199,157,134, 96,208,160,216, 32, 67, 33,227,130,212,228,100, 44,219,
- 18,154, 82,172,214,143,186,151, 99,154,193,124,144,135, 82, 9, 85, 60,108,217,231,243,207, 46, 95,186,200, 82, 19,127,190,148,
-161, 56, 13,211,164,183,100,233,226,111,169, 18,157,254,141,248, 2,148, 52,164,163,179,194,138,149,171,190, 27, 52,101,220,240,
- 24,223,150,189, 29,248,244, 4, 7,109,113,113,246,207,167,110,186, 84, 92, 41, 82, 0, 16,151,154,135,156, 34, 53,199,115,236,
- 5, 43, 41,150, 68, 25, 19, 29,172,160,169, 19, 84, 33, 61,218,140, 85, 89,201,160, 41, 45,132,147,149, 20,253,131,154,143,101,
-255,136,253, 40, 33,219, 20,187,246,184,209, 98, 65, 88, 13,174,175,120,185, 21,225,217, 86,224, 89, 24,238,238, 50, 61, 50, 70,
- 97,246,204, 94,150,214,118,250, 71, 52,212, 22,128,185, 35, 40,107,111,192,198,135,146,250,191,129,244,248,123,220,187, 99,199,
-229, 37, 36,166,254,224,104, 94,127,183, 54, 43, 16, 8,137,231, 81,154, 21,135,200,116, 3,218,100,151,247,182, 91,103,221, 2,
- 47,142,152, 35,242,130,146,148,148, 52,254,147, 79, 62,185, 28, 20, 20,228,236,232,232,136,182,109,219,226,216,177, 99,152, 59,
-119,110,213,103,218,183,111, 15, 66, 8,242,243,243,177,114,229,202,204,244,244,244,241,245, 94,160,223,187, 23,179,115,231,206,
- 94,173, 91,183, 54,200,100,178, 66, 0,138,194,194, 66,179,252,252,124, 74,171,213, 66, 16, 4,193,198,198,134, 79, 79, 79,103,
- 71,141, 26,165,187,122,245,106,115,181, 90,157,244, 52, 17, 45, 79, 79,207,200,188,188,188, 34,138,162,158,122,232,135, 74,147,
-229,232,232,168, 42, 45, 45, 21, 0, 20, 52,102,232, 7,142,227,208,177, 99, 71,156,190,120, 11, 39,127,187,138,226,244,251,120,
-123,202,120,180,109,219, 22,167, 79,159,110,116,155, 5, 6, 6,226, 84,216,101, 92,190,113, 7, 73,177,119,241,238,219, 83,208,
-166, 77, 27,156, 58, 37,102, 47,152,192, 9,212,204,205, 58,241,184,209, 10, 14, 13, 13,173, 60,244, 63, 97, 95, 91, 57, 34, 80,
-106, 43,223,181,104, 64,115,127,105,191, 69,160,164,230, 56,208,242, 84,247, 5,203,214,197, 48, 78, 73,227, 34,179, 27,174, 14,
-171,241,167,201,198, 61, 18, 30,179,231, 78,116,171,177,255, 23,228,137,173,199,148,159, 1,192, 27, 61,155,226,143, 7, 57, 8,
-143,205,222, 19,149,131,123, 79,187,214, 1, 78, 80,242,185,216,179,242,189, 33,193,222, 30, 46,216,246,203,101, 80, 20, 14, 27,
-117,194, 37,132, 4,181,246,198,154,157,143, 87, 24,186,120,173,218,175,141, 57,115,175,100, 0, 0,244,107,165,252,181, 83,115,
- 59, 47, 82, 61,113,171, 22,204,229,146,105, 3,134,191,105,198,197, 30, 3, 18,195, 64,113, 58,104, 12, 2, 50,114, 75, 80,102,
-227,137,243,215,238,104,138,180,250,247,163,114, 26, 23,197,139,206, 69,188,236,207, 59,201,165,106,141,171, 82,213, 92,203,208,
-130, 80,170, 35,248, 35, 42,177, 56, 42, 19,247,141,209,136,143,135,190,139, 59,215,115,211,142,253, 11,165, 50,249, 27, 12, 5,
-202,201,214, 66,181,233,219, 47, 96,101,101, 9, 65, 95, 10,168,115, 48,236,157,101, 57,145,233,108, 83, 0,104,233, 0,203,158,
- 77,165, 59, 36, 52,149,122, 46,206,240,105, 67,191, 65,177,152, 62,174,127,123,169,160, 87,227,189,149,251,176,249,163, 33,120,
-243, 21,127,233,137, 43,177,211, 1, 44,105,108, 91, 19,158, 3, 97, 53,232, 58,255, 98, 12, 5, 92, 38, 64,143, 27,251,151,182,
- 2,110, 25,173,209, 1,144,242, 18,202,191,157,151,133, 76, 72,189, 2, 33,245, 10, 97, 60,187,131,242,234, 69, 81, 46, 29,201,
-247, 95, 45, 86,111,221,186,237,140, 64,227,115, 35,134,202, 0, 47, 0,185,177,151,161,215,235,193,242,128, 86,171,133, 90,173,
-134, 69,220,169,170, 28, 45,153,148,122,109,214,196,193,129,164, 52,189,236,120, 12,151,188,109, 74,171,174,164, 52,189,236,122,
- 50, 31,155,171,214,137,209, 44,145,231,145,248,244,244,244,215, 6, 14, 28,248,219,233,211,167,237, 3, 2, 2, 0, 0, 55,110,
-220, 40,191,232,236,216, 17,190,190,190,200,202,202,194,232,209,163,115, 51, 50, 50, 94, 67, 3, 57,191, 37, 37, 37, 9, 7, 15,
- 30,116, 86,171,213,237, 63,253,244,211,108,111,111,239, 98,173, 86, 75, 21, 22, 22, 10, 28,199,193,206,206, 78,222,190,125,123,
-116,235,214,173,244,218,181,107, 77, 82, 82, 82, 74, 0, 36, 54,102,225,135, 12, 25,130,139, 23,203,139,246,158,197,184, 90, 50,
-153, 12, 1, 1, 1,238,241,241,241,105, 21,231, 22,147,143,241,213, 79, 47,119,238,220,193,133, 91,169,144,232, 53,144,231,164,
-227,250, 47, 7, 49,120,218, 12,112, 92,227,239, 45,127,231,206, 29, 28, 9,187, 14, 11,133, 4,247,239,223,195,193,131, 7,241,
-246,219,111, 63,149,102, 35,169,215,139,252,151,147,129, 58,242,180, 36, 0, 16, 18, 18,114,161, 50, 90, 81,157,102,205, 32, 87,
-148, 98, 81,191, 14,238,243,222,232,209,156, 97,139,211, 33,240, 2, 24, 41,224,228,104,141, 93,187,246, 52,221,179,111,223,181,
- 13,235, 55,124, 39,112,220,130,200,108,148,153,176, 80,139,190,221,119,249,141, 93,115,130, 37,111, 15,104,101, 15, 0, 50, 9,
-141,181,199,238,113, 0, 22, 61,205,218,118,113,135, 89, 41,139,169, 78, 14, 54,159,125,242,159, 65,246,193, 29,125,113, 33, 60,
- 18,223, 29,188,118, 81,158,141,157, 70,239,220, 2,139,199,253, 83,109, 85,135, 16, 26,206,187,228,121,226, 34,179,176,131, 33,
-241, 28, 96,208, 66,171, 51, 32, 37,143, 71, 74,190, 22, 18,165, 12, 55, 98, 83, 53, 14,153, 8,125,138,213,166, 44,148,102,110,
- 11,191, 92,229,161,213,148,114,197, 5,185,156, 76,126, 93,170, 52, 87,100,152,146,170,112, 61, 13,218, 94, 62,210,151, 0,129,
-145,155,145,178,249, 31, 76,180, 72,139, 58,141, 22,116, 58, 40, 66, 96,238, 63, 8, 86,230,140,172, 71, 19,105, 50, 0, 88, 88,
- 40,229, 43, 63,159,107,243,254, 71,159, 55,152, 3,230, 15,200,124,155,185,188, 31,224,109,135,139, 55, 99,112, 49, 34,233,222,
-197, 27,247,219,244,105,235, 6, 95, 15,219, 89,242,130,194, 21,209, 48, 61, 66, 90,222, 48, 28,192,106,171,170, 14,253,157, 48,
-166,211, 27,159,214, 85,109, 88, 43, 62,128, 16,203, 19, 80, 12, 3, 80,116,121, 5,100,202, 21, 72,108,155,145, 61,251,143,148,
-109,219,182,243,139,232, 92,227,139, 51, 88, 30,124,113,113, 49, 44, 44, 44,112, 42,150,211,189,217, 95,166,160,105, 26, 41,177,
-183,254, 74,134,183,167, 91,203,250, 44,109,117,101,113,167,211, 86,114, 74,225, 54,232,115,127, 46, 98,103,106, 99, 79, 18, 34,
- 34,255, 13, 20, 21, 21,221,141,142,142,238,223,174, 93,187,237,239,189,247,158,213,184,113,227,220,166, 76,153, 66, 3, 64, 86,
- 86,150,176,102,205,154,244,239,191,255,190, 40, 55, 55,247, 45,150,101,141, 25,202,132,100,100,100, 92,253,225,135, 31,114, 46,
- 93,186,212,166,115,231,206,138,151, 94,122, 73,176,179,179,147, 40, 20, 10, 94,175,215,107, 99, 99, 99,249,248,248,120,215,194,
-194,194,135, 0,226,208,136, 59, 86, 84, 68,175,150, 48, 12,179,144, 16, 18,240, 44,114,180,148, 74,165, 27,128,135, 20, 69,181,
- 48,181,219,240,137, 19,182, 68,130,130,130, 2,148,101,222,131, 89,234, 3,180,179,160,209,218,206, 18,214,214,214, 79,101,138,
-138,138,138, 0,117, 26, 46, 95,190, 3,112, 28,108,108,108, 96, 99, 99,243,143, 27,173,186,188,200,115,194,212, 90, 94,171, 63,
- 71,171,181, 10,111,155,235,177,102,218,160,230, 50, 31, 47, 15,232, 82,111,224, 78, 74, 41, 22,116,233, 28,197, 40,172,180,211,
-198, 15,233, 56,124, 68, 19, 4,119,235, 68,249,184,218,204, 90,241,237,198,119, 90, 35,119,110, 84, 54,214, 26,179, 68, 81, 57,
- 72, 16,144,189,237,220,221,212,233, 30, 74, 13, 4,129,224, 92, 68, 6, 34, 18, 11,182,197,228, 32,193,148,181,107,237,138,190,
- 18,208,251, 8, 33,102, 54, 22, 22, 37,173,125, 61, 28,251,118, 13,164, 95,235,221, 17, 50, 6,184,252,199, 29,204,254,246,240,
-117, 65, 32,131,110, 25,217,109, 88, 94, 97, 88,211, 64,149, 87, 24,178, 53, 42, 12, 9, 33,164,188,234,176,254,224, 3,195, 80,
-153,101, 73,127,186, 72, 29, 90, 66, 19,119, 14,137, 5, 2,146,178, 75, 80, 44,113,129, 46, 45, 13, 32, 66,242,133,250, 19,171,
-235,197,209,209,209,169,105,107,223,230,235,118, 28,132,161,172, 8, 9,231,183,163,180, 32, 3, 75, 55, 29,107,238,238,238,208,
- 59, 45, 45,237,130, 9, 7, 27,223,223, 66,247, 56,129, 0,140, 84,129, 19, 27,246, 35,215,193, 28,142, 74, 25, 4, 77, 14,166,
-189, 63,206,102, 64,191,113, 54, 0,144,116,255, 54,188,149, 26,163,116, 13, 14, 24,254, 70, 31, 63, 91,176, 26,236, 56,117, 91,
- 75, 3,175,237, 60,115, 47,174, 79, 43, 91,179, 55,122,120,219, 45, 73, 47,124, 29,121,141, 27, 84,180, 50,162, 85, 21,225,107,
- 68,181,225, 65,128,111, 37, 32,110,223,213,108,139, 17,253, 94, 82,202, 36, 20, 69, 74,211, 64,204, 29,177,113,199,129, 82, 57,
-107,218,157,216, 5, 96, 73,208,242,132,133,229,251, 9,182, 15, 88,126,227, 63,103, 63,235,162,202,204,204,132,161,162,239, 48,
- 33, 95,248,125,124,191,214,124,106,145,160, 63,179, 98,216, 8,202, 92, 37,255,240,235,157,231, 9, 32,142, 38, 45,242, 92,163,
-209,104,110,106, 52,154,182, 31,126,248,225,152,249,243,231,247,178,176,176,104, 10, 0,106,181, 58,129,101,217,139, 21,255, 79,
- 83,170, 3, 9,128,135,113,113,113, 9,113,113,113,206,187,119,239,182, 5, 96, 86,241,158, 22, 64, 33,128, 44, 60, 69,197, 97,
-165,169,162, 40,106,225,179,218, 14,149,166,138,162,168, 22,141,249, 62, 77,211, 60, 69, 81,160, 40, 10, 10,133, 2,151, 46, 93,
-194,200, 65,253, 16,125,162, 16, 1,182,150,232,252,214, 52,236, 59,123, 22, 12,195,128,162, 40, 48, 12, 99,210,121, 68, 34,145,
-224,242,229,203,120,115,244, 8, 40, 36,128,141,141, 13, 62,252,240, 67, 28, 61,122, 20, 18,137,120,151, 62, 19,216, 82,205,112,
- 25, 57,142, 22,133, 37,103,183, 47,147,129,103,113,124,251, 55, 8,141, 44,213,223,207,193, 2,191, 28,172, 57,136, 18, 33,231,
-219,157,211,207, 94,142,252,122,210,168, 16,229,203,125,250,225,229,224, 62,146, 54,157,122,127, 6,212, 48, 90,125, 81,207, 88,
- 27,188,128, 47,182,156,138,153,182,239,124, 44, 5, 67, 9, 70,189,218,137,240, 2,190,104, 96,101,158,208,180, 49,183,220,119,
-249,218, 53, 59, 24, 74,145,120,251,119,179, 38, 77,155, 3,188, 1, 15, 31, 62,192,247, 59,126, 17,206,255,113,127,151,158,195,
-123,241, 5, 80, 27,171, 89,126,166,228, 96, 99, 33,247,123,173,141,245,175, 2, 8,108,149,178, 86, 68,224, 97,171,148,182,234,
-215, 74,249, 43, 33,132, 88,153, 75, 91, 17,158,109, 80, 83,163,231, 54,239,248,113,219,170,201,147, 39, 91,228,166,102, 34,189,
- 56, 18,165,114,119,176, 74, 79,196,221,190,168, 41,211,113,198,156,196,235,220,158,185,185,185,217, 55,195,243,177,111,211,114,
-176,122, 29,178, 83,203,189,106,122,110, 49,172, 29,221,175,165,165,165, 25,173,105,224,132,162,225,227,166,202,204,173, 96,254,
-230,240, 16,121, 92,158, 14, 29,220,172,202, 15, 26,165, 57,136, 14,187,140,224,138, 28,211,248, 20, 26,222,129,110, 70, 45,167,
-149,153,236,189, 1, 47,185, 35, 33, 57, 3,151,238,165,237, 72,200, 71, 58, 31,147,177, 35, 46,189,112,250,144, 46, 94, 88,125,
- 52,234, 93,128,221, 99,202,186,251, 59, 97, 12, 33,232, 81,158, 12,175, 1, 1,122,248, 59, 97,140,145,149,134, 79,104, 74,100,
- 24,187,234,215,164, 79, 15,252,153, 59,100,222,216,158,214,221,186, 13,148,131,211,163, 68,163, 99,163, 11, 81,108,138,102,177,
- 70,216, 12, 96,115,229, 27, 55, 83,133, 93, 61, 23, 93,187,184,103,138,167,170,210,171, 95,140,211, 93, 3,112,109, 82,144,249,
-103,178, 62, 75,253,174, 45, 9, 58, 29,145, 33,236,190, 24, 87, 53,134, 86,131,255,163, 70, 34,106,138,154,255,132, 38, 15, 96,
- 23,203,178,187, 10, 11, 11,159,165,102, 58,158, 28,215,233,169,214,189,122, 55, 33, 33, 68, 82, 17,205,106, 40, 25,190, 94,205,
-234,221,132,132,144,147, 21,209,172,134,162, 90, 53, 52, 5, 65, 72,239,216,177,163,253,224,193,131,193,243, 60, 30, 60,120,128,
-164,148, 20,244,157,254, 46,108,109,109,113,241,238, 93,220,191,127, 31, 11, 23, 46, 4,203,178, 56,114,228, 72,106, 67,154, 18,
-137,196,208,188,121,115,217,208,161, 67,193,113, 28,226,227,227,145,150,150,134,217,179,103,195,198,198, 6, 55,111,222,172,210,
-204,205,205,133, 68, 34, 49,212, 18,221,250, 59,246,165,231,157, 39, 76, 86,253, 70, 11,224,193,179, 40, 58,187, 8,107, 47,193,
- 96, 96,209, 42, 42, 7,143,162,254,138, 72,109,100,194,239, 30,191, 27, 25,147,112,243,202,203,114,100, 71,192,212, 43,137, 7,
-121,200,176, 50, 43, 41,129,161,196, 26,241,191,226, 81, 86, 73,233,131, 60,100,152,124,197, 32,240, 20, 12,101, 64,198, 13, 92,
-189,120, 1,231,175,223,193,159, 17, 49,252,213,155,177,251,104, 1, 95, 68,231,225, 65, 35,174, 66, 96, 57,104, 53, 38, 70, 60,
-244,234,228,235,236, 5,158, 3, 17, 88,216,140,218,131,183,162,186,121,117,106,102,235, 85, 30,201, 98, 97,247,159,223,129, 85,
-102,245,234,221, 72, 97,183,200,143,158,126,189,164, 48,175,203, 43,189,187, 90,216,248, 15, 64,238,195, 88, 60,184,115, 89,115,
- 51, 50,238,234,141, 20,118,203,211,180,174,187,187,123,175, 87,122,251, 97,212,180, 79, 96, 40, 43, 66,252,249, 31, 81,154,159,
-137, 75,215, 44, 17, 83, 92,220, 21,128,209, 17,173,107,201, 92, 27, 36, 23,160,123, 19,105,178, 21,116, 46,227, 67, 6, 67, 65,
-105, 33,232,138, 65,149,229, 34, 46, 77, 95,244,250,166, 20, 30, 0,148, 10, 74, 98, 65,138,172,141,138, 60,122, 59,180, 84, 50,
- 44,118,158,189, 7, 65, 40,191,125,147, 32, 96,227,206,223,227,166,127,241,102, 7,180,246,178, 11,188,157,150, 77,193,132,144,
- 63, 69,208,243,207,125,159,183,210,254,246, 25, 32, 24,112,121,150,125,171,158,107,243,123,162,145,183,219,137, 76, 71, 26,128,
-233,144,148,109,158,181,246,212,103, 29,207, 70,245,152,243,159, 33,214, 32,207,164, 66, 55, 54, 42,147,239, 21,180, 34,233,180,
- 64,106,246,231,150, 71,182,252, 73,122, 49,185,125, 49, 78, 39,142, 10, 47, 34, 34, 2, 0, 40, 45, 45,157,246,214, 91,111,109,
-150, 74,165, 42, 0,148, 32, 8, 16, 4, 65,242,245,215, 95, 75,121,158,167,105,154,230, 25,134,225, 78,158, 60,201,242, 60,159,
-163,213,106,167, 53,164,201,113, 92,220,140, 25, 51,154, 55, 84,161,184,119,239,222, 74,147, 21, 39,182,132, 81, 38,171,250,188,
- 42,202, 37,169, 39, 72,251,121,247, 55, 23, 45, 2, 64,129, 96,113, 84, 14, 30, 61,254,145,136,124,164,183,102, 12,179,219,116,
-234,189,168,242, 59,166, 46,153,150,231, 71,116,106,235,187, 23, 0,116,132,127,179, 49,107, 87,172,211,188,209,190, 83,215,125,
- 2, 33, 18,142,144,109,180,128, 67, 90, 14,209,198, 84,218,213, 69,122,118,225,205, 1, 1, 54, 4, 40,239, 50,172,234, 46,172,
- 24,198,129, 16, 66,170,186, 11,191, 49, 67,110,145,174,193,113,160,174, 60,210,247,211,115,127, 78, 61,115,229,246, 52,158, 39,
- 46, 12, 67,101,106,244,220,230,167, 53, 89, 0,144,150,150,118, 33,236,108,218,153,187,129,206,175, 58, 42, 43,162, 92,101, 64,
-110, 25,206,164,229,148, 94,104,140,102,129,154, 29, 50,127,205,209, 99,114, 41, 35, 1, 33,229, 3,138, 18, 2,173,129,207,191,
-150,204,181, 1,128,182,246,112,251,240, 8,183,151, 97,168,164,134,244,194,239,103,172, 30,181, 34,108,238,189,196,130,109,137,
-133,136, 4,128,196, 66, 68,238,191,252,232,179,184,204,146,185,145, 73, 5,223,192,196,188, 10, 66,225, 82,167, 81,139,158,120,
-237,105,183,103, 76, 6,238, 0, 24, 6,164,246, 27, 53,231,251, 57, 20,133,103,117,251,137, 88,141,129,120, 63,254, 98,101,100,
- 75, 60, 86,137,136,252,119, 80, 25,213,162,105,122,201, 51,212, 60, 73, 81,212, 64, 0, 15, 77,248, 90,120,105,105,105,219,103,
-188,122,121, 28,199,229, 25,243,193,127, 33, 33,254,121,101,203,191,245,195,125, 69,205,127, 94,179, 69,139, 22,196, 4,195, 34,
-110, 79, 81, 83,212, 20, 53,255,167, 52, 9, 33,204,211, 76,117,104, 82, 79, 51,137,109,244,220, 51,181,174,231, 98,166,219, 11,
-200,195,135, 15, 41,113, 43,136,136,136,136,212, 14, 69, 81,252,223,160, 41,142,142, 39, 82,105,176,106, 68,183,104,113,155,136,
-136,136,136,136,136,136,136, 60, 19,147, 85,125, 94,110,194, 81,119,248,207,148,106,130,198,132, 16,195, 68, 77, 81, 83,212, 20,
- 53, 69, 77, 81, 83,212,252,159,211,108, 72, 91,172,102,252,155, 13,152,168, 41,106,138,154,162,166,168, 41,106,138,154,255,123,
-154,207, 51,117,230,104,137, 93,135, 34, 34, 34, 34, 34, 34, 34, 34,127, 19, 98, 50,188,136,136,136,136,136,136,136,200,211,209,
-224, 77,165, 69, 68, 68, 68, 68, 68, 68, 68, 68, 26, 71,253, 55,149, 22, 17, 17, 17, 17, 17, 17, 17, 17,105, 52,166,223, 84, 90,
- 68, 68, 68, 68, 68, 68, 68, 68,196, 40,182,136,155, 64, 68, 68, 68, 68, 68, 68, 68,228,159,161,102,213, 97,104,104, 40,169, 62,
- 23, 17, 17, 17, 17, 17, 17, 17,249, 39,121, 81,189,136,216,117, 40, 34, 34, 34, 34, 34, 34, 34,242,116, 76, 21,141,150,136,136,
-136,136,136,136,136,200,223, 67,157, 57, 90,149, 3,150, 6, 87,132,234,130,197,109, 37, 34, 34, 34, 34, 34, 34,242, 47,240, 98,
-123, 17, 49, 63, 75, 68, 68, 68, 68, 68, 68, 68,244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,255, 77,136,247, 58, 20, 17, 17, 17,
- 17, 17, 17, 17,249,135, 13,215,223,110,180,196, 59,155,139,154,162,166,168, 41,106,138,154,162,166,168,249,191,100,178,106,152,
- 45,177,234, 80, 68, 68, 68, 68, 68, 68, 68,228,233,104,176,234, 80, 68, 68, 68, 68, 68, 68, 68, 68,164,113, 76, 5, 16, 82,241,
- 56, 4,213,162, 90, 98, 68, 75, 68, 68, 68, 68, 68, 68,135,111, 75, 20, 0, 0, 32, 0, 73, 68, 65, 84, 68,228,233,216, 2,192,
-181,194, 96,157, 0,144, 33, 26, 45, 17, 17, 17, 17, 17, 17, 17,145,103, 67,245,188,172, 65,213,204,151,104,180, 68, 68, 68, 68,
- 68, 68, 68, 68,158,146, 58,115,180, 40,212, 93, 57, 16,102,194, 15, 52,166,250, 32, 76,212, 20, 53, 69, 77, 81, 83,212, 20, 53,
- 69,205,255, 57,205,134,180,195,240,252, 49,213, 20,243,245, 44, 17, 75, 95, 69, 77, 81, 83,212, 20, 53, 69, 77, 81, 83,212,252,
-159,229,153, 87, 29,118, 0,204,197,205,250, 66,226, 92, 49,137,136,136,136,136,136,136,212,207,223, 83,117,232, 15,252,103, 92,
-128,106, 19, 27,153, 99, 29, 9,148,213,247, 89,149, 74,181, 89,169, 84,142, 43, 43, 43, 83, 83, 20, 37, 84,190, 78, 8, 1,128,
-234,247, 58,138,207,201,201,233,217,208,111,203,229,242, 53,206,206,206,255, 41, 45, 45, 45,163, 40,138, 80, 20, 5,138,162, 0,
-224,137, 57,207,243,169,121,121,121, 29,159,235, 38, 36,132,113,116,118,254, 67,202, 48,238,166,126,149, 23,132, 71,217, 89, 89,
- 93, 77,248,202,114,138,194,188,242,159,197, 87, 0, 62,121,209,254, 17, 4, 96,140,249, 92, 0, 96, 21, 11,140,226,105,250, 93,
- 41,176, 94, 39, 8,155, 0,128, 2,248,198,254,182, 46, 28,205, 41,130, 64,138,130, 13, 33, 40, 34, 20,238, 40,130, 16,247, 47,
-109,138,225, 82,169,116,136,181,181,181,101, 94, 94,222, 5, 0,123, 1,140,118,112,112,232, 93, 92, 92, 92,202,178,236, 81, 0,
-135, 27, 35,220, 51, 16, 31,201,101,210, 73, 90, 3,187,242,202, 29,252,216,187, 3, 28, 56, 1, 43,204,100,146,158, 58, 61,247,
-213,229,187,216,102,162, 36, 85, 49, 85, 30, 51, 76,190, 71,218, 1, 35,219, 29, 0,142,216,217,249, 42, 84,214,191, 73,229,204,
-163,194,172,210,113, 35,178,179, 83, 70, 62, 69,187,255, 55,226,232,232, 56,145,166,233, 47, 9, 33,224,121,126, 65,126,126,254,
-246,103, 36,189, 0,128,109,197,227, 66, 0, 95, 62,165, 94, 18, 0,175,138,199,201, 0,188,197,243,122,163,217,248,203, 47,191,
- 76,239,211,167, 15, 86,175, 94,141,141, 27, 55, 38,230,228,228,172, 0,176, 3,128,254, 95,208, 17,169,139,214,192,192,175,251,
- 7,241,236, 79, 95, 8,213, 94,238, 91,199,159,249,135,241,227,199, 27, 8, 33,228,254,253,251, 68,175,215, 19,150,101, 9,199,
-113,132,227, 56,194,178,108,213,228,238,238,158,246,216,215,159,208,164,105,122,237,235,175,191, 94, 66, 8, 33, 55,110,220, 32,
- 26,141,134,232,116, 58,162,215,235,137, 86,171, 37, 26,141,166,198,228,236,236,156, 85,159,166,181,181,245, 13, 59, 59,187, 44,
- 59, 59,187, 44,123,123,251, 44,123,123,251, 44, 7, 7,135,170,201,209,209,177,106, 82,169, 84, 89, 42,149, 42,203,222,222,254,
- 70, 67,203, 89, 65,127, 0, 23,140,152,250,215,242,221,190,213,141,150,171,171,107, 22,105, 4, 30, 30, 30, 41, 70, 44,103, 37,
-206, 20, 5,190,242,187, 20, 5, 65,161, 80,120, 85,127, 31, 79, 70,186, 26, 12, 41,187,185,185,189,238,234,234, 26,230,234,234,
-122,214,205,205,237,117, 35,118,177, 26,154, 86, 86, 86, 55, 28, 29, 29,179, 92, 92, 92,178, 43, 39, 87, 87,215, 26,147,155,155,
- 91,213,228,236,236,156,101,103,103, 87,103, 27, 17,128,169,107, 58, 15, 72, 20,192,203, 18,134, 9,117,118,118, 46,142,136,136,
-224, 9, 33,132,166,233,180,202,207,152,178,238,143,155,172,178,203, 88,144,123, 78, 17, 94,250,104, 69, 81,238, 57, 69,120,217,
-101, 44,208,133,163,121, 99, 53,141,164, 54,205, 9, 19, 38, 76,184,147,149,149,149, 86, 88, 88,152,177,105,211,166, 88, 51, 51,
-179,203,155, 54,109,138, 45, 44, 44,204,200,202,202, 74,155, 48, 97,194, 29, 0, 51, 76,208, 4, 0,116, 13, 68,151,201,195, 93,
-203,238, 28,121,179,236,229, 78,146,219,221, 3, 16,210,175,171, 44,109,221,199,254,101, 23,183,246, 40,235,243, 18, 29,105,162,
- 38, 37,145, 72,186,121,121,121, 77, 82,169, 84,227, 43,166, 55, 43, 39, 23, 23,151, 55, 93, 92, 92,222,180,179,179, 27, 89,159,
-230, 1,128, 49,102,242, 52, 51,235, 54,178,169, 87, 89,210,146,197, 36,226,253,119,201,164,102,158,197, 35,156,156,154,252, 11,
-109,244,183,106, 58, 57, 57,165,179, 44, 75, 12, 6, 3,113,112,112, 72,127,134,203,249, 13, 33,228, 27, 66,200, 55, 0,190,121,
- 6,154, 85,199, 51, 19, 12,118,125,154,102, 18,154,158,163,148,203,207, 42, 36,146,108,133, 68,146,173,148,203,207, 74,104,122,
- 46, 0,179,255,166, 54,250, 27, 52, 45, 85, 42, 85,194,154, 53,107, 72, 89, 89, 25, 41, 43, 43, 35,107,214,172, 33, 42,149, 42,
- 1,128,165, 9,154,141,213,121,145, 34, 88,143, 79,207, 46,162,229, 15,116,124, 57,176,197,161, 89, 19, 71, 65, 56,184,134,106,
-224,138,233,135,174, 29, 59, 78,218,177, 99, 7, 0, 96,220,144, 33,120,181,115,103, 88, 89, 90, 64, 46, 47, 95, 28,138, 80,144,
- 73,101, 24, 58,251, 3, 99,126,254,171,161, 67,135,142, 61,120,240,160, 37, 0,108,220,184, 17,195,135, 15,135,189,189, 61,148,
- 74, 37,100, 50, 25,164, 82,105,141,121, 67, 48, 12,227,145,150,150,230,100,102,102, 86, 21,101, 19, 4,161,198, 68, 8,169,140,
-190,129,227, 56,180,108,217,210,216,205,245,113, 81, 81, 81, 47,181, 90, 93,165, 81,219,212,180,105, 83, 0, 56,109,140,224,151,
- 75,191,128,192,169, 33,145, 0, 28, 7,232, 12, 52, 4, 82,171,185,193,140, 25, 51,170,150,187, 49, 12, 26, 20, 66, 81, 20,117,
-240,230,205,155,135,178,179,179,125, 4,129,159,210,200, 72,215, 59, 15, 30, 60,176, 4, 0, 95, 95,223, 25, 0, 14,153,178, 28,
- 18,137,196,227,238,221,187, 78, 10,133,162,206,200,101,181, 8, 38, 12, 6, 3, 58,116,232,192,153,242, 27,206,128, 87, 62, 77,
- 79,105,255,210, 75, 83, 23, 13, 29,106,246,199, 31,127,152,209, 52, 13,142,227,240,245,215, 95,115,132, 16,219,214,128,117, 20,
- 80, 92,143,204,124, 0, 19, 43, 78, 6,219, 0,124, 93,195, 45, 16, 4,106, 88, 69, 72,124,233,208,206, 65, 77, 62, 66,212,189,
-136,206,205, 44,143,192, 74,162,139, 3,254,217,168,150,181,181,245,144,213,171, 87,171,182,109,219, 86,124,255,254,125,195,166,
- 77,155, 84,211,166, 77,179, 50, 24, 12,152, 62,125,122,142,159,159,159,108,245,234,213,170,195,135, 15,191,172, 86,171, 55,152,
-212, 94, 20,190, 24, 61,228, 85,104, 89, 26, 44,203,169, 92, 85, 86,187,102, 77, 8,150, 18,162,199,206,163, 55,193,114,194,143,
- 38, 70,178,186,142, 24, 49,162,217,158, 61,123, 36, 49, 49, 49,146, 86,173, 90, 65, 16, 4,240, 60, 15,150,101, 1, 0,130, 32,
-160, 69,139, 22, 79,189, 93, 38, 1,190,142,206,246,103,187, 14, 28, 96,238,106,166,128,125, 65, 14, 38,203, 36, 86,219,149,186,
-221, 0,186,189, 80,145, 93, 66, 32,145, 72,144,146,146, 2, 39, 39, 39,115, 65, 16, 50, 0, 44, 46, 40, 40,216,130, 23,151,206,
-114,137,228,208,206, 31,215,186, 4,117,235,198, 56,187, 58, 33,246, 65, 50, 36, 20,223,247,238,159, 55,131, 39,189, 61,103,150,
-158,227, 94, 7,240,199,139,182,226, 46,221,102, 12,163,104,102, 35, 69, 4,124,190,238, 88,201,242,175,214, 40,167, 79,153,192,
-204,158, 61, 27,158,158,158, 62,195,134, 13,251, 10,192,219, 13,234, 4,205, 24, 6,134,222, 8, 66,176,232,251, 99, 37,203,190,
- 90,163,124,187, 17, 58,207, 57,117,254, 71,158,218,104,249, 3,205,218,120, 58,157, 89, 62,239,109, 41,249,245, 39,186, 44, 47,
-187,206,207,170, 84,170,205,175,189,246,218,184,237,219,255,138, 70,119, 13, 8,192,176,151,123,192,201,193, 6, 74, 11,121,249,
-233, 72,160,112,231,254, 35,163, 12,129,167,167,231,244, 67,135, 14, 89, 86, 55, 19, 50,153,172,106,170,110,178, 42,167,202, 19,
-112,125,152,153,153, 33, 44, 44, 12, 18,137, 4, 12,195, 64, 34,145, 84, 77,213,159, 51, 12, 3,103,103,147, 82,151, 86,216,216,
-216,180, 43, 41, 41,177, 46, 44, 44,132,151,151, 87, 49,128,187,213,222,111,151,147,147, 99,109,138,160,192,169, 49,123,178, 63,
-164,250,235,208, 75, 59, 67, 35,233,142,171,127, 70, 35,244,244, 5,164,165,103,162, 71,151,246, 24, 63,102, 4,206,158, 61, 11,
-158, 55,185,167, 35,139, 16,124, 53,120,112,200, 71, 0, 69,245,237,219,183,112,230,204,153,116, 76, 76,204,216, 97,195,134, 6,
- 60,120,240,176, 34,170, 72,205, 35, 4,107, 1,100, 25,169, 43, 7,128,139, 23, 47, 2,128,162, 49,251,158, 66,161,192,181,107,
-215, 80,217, 77, 76,211, 52,104,154, 6,195, 48, 56,254,208, 17,106, 61,141,178,172, 72,188, 27,226,133,166, 77,155,130,166, 27,
- 78, 73, 12, 6,204,174, 2,195, 40,169,116,182,171,155,155, 79,239,102,205,148, 97, 97, 97, 12, 0,120,123,123,147,140,140,140,
-194,163, 71,143,150, 72,128,141,222,132,236,168,207,100,121,122,122,118, 79, 75, 75,251,178,114,155, 83, 20,245, 85,147, 38, 77,
- 22, 86,181,155, 32, 96,241,143,106,233,172, 89,239,203,130,130, 63, 5, 0, 4, 13,222,131,226,248,229,254, 84,254,124,155,127,
-250, 40, 81, 92, 92,188,175, 69,139, 22, 76, 94, 94,222, 85, 0, 73, 44,203,126,188,107,215, 46,167,201,147, 39,103,239,222,189,
-123, 5, 0,183,149, 43, 87, 6,171,213,234,253,166,232,246,104,135,129, 47,181, 11,232,226,229,233,137, 11, 87,255,128, 76, 46,
-181,157, 49, 49, 4,150,150, 18,124,179,237,132,144,148,154, 63,243,242, 93,236, 48,193,100,117, 30, 49, 98,132,207,158, 61,123,
-228, 0,112,247,238, 93,100,102,102, 66,165, 82,193,220,220, 28, 82,169, 20, 12,195, 64, 42,149, 62, 19,147,101,227,233, 16,126,
-228,200, 81,115,123,123, 91,172,251, 96, 22,198,103,103,193,214,202, 18,108,169,218,231, 5, 59, 81,248,246,236,217,211,140,231,
-121,168,213,106,156, 63,127,222,198,220,220,220,198,195,195, 99, 17, 76,168,158, 50, 51, 51,203,210,106,181, 78, 21,143,179,181,
- 90,173, 51,128, 98,133, 66, 81,121,156, 46,173,152, 27,219,157,152,132, 39,187, 9,147, 41,138,170,254, 90, 99,233,212,185, 83,
-187,176,195, 7,127,182, 44, 42,201,132,173, 93, 54,104, 20, 97,203,150,245, 48, 55,183,198,162, 69,243, 37,143,250,190,236,222,
-127,224,235, 97,247,162, 99,251,190,112,102,139, 80, 91,250, 14, 30,103,111,174,180,170, 56,151,176,216,190,117, 22,104,154,198,
-194,133, 11,209,166, 77,155,169,247,238,221,251, 20, 64,126,253, 50,216,210,182,215, 27,246,114,179,242, 38, 22,120, 22,155,246,
-206, 45,215,249,100, 26, 70, 15,110, 58,245,195, 17, 9,167,218, 52, 67, 73,197,133,185, 70, 74, 35,153, 10, 66,149, 97, 8, 13,
- 13,237, 29, 18, 18,114,161,174,231,207, 1,174,248,107,252,172, 26,230, 75, 18, 26, 26, 74, 66, 66, 66,168,106, 43, 87,227,121,
-125, 4, 2,142,118, 54,202,176,141,139,103, 89, 74,174,159, 96, 52,201, 15,145,174,173,113, 34,175, 81,162,169, 84, 42,199,109,
-223,190,189, 70, 72,201,203,217, 9, 50,153, 20, 82, 25, 5,219,158,229,163,215, 23, 94, 10, 5, 69,213,105,178,106,104,170,213,
-106,237,237,219,183, 45,183,109,219, 6, 39, 39, 39,248,248,248, 64,169, 84,194,204,204,172,134,185,170,110,184,106, 49, 90, 53,
- 52, 43,223,151, 72, 36,160,105, 26,103,207,158, 5,199,113, 24, 49, 98,196, 19, 38, 75, 34,145,212,101,220,234, 42, 79, 61, 13,
-224, 46, 33,164, 87,197, 9,248, 46,128,222,213,222,239,175, 82,169, 62, 6,176,194, 88, 77,134, 33, 96,180, 87, 33,120,172,129,
- 36,101, 22,244,210, 64,156,187,124, 19,219, 55,175, 6, 0,248,180,234,132,145,195, 66,170,162,113, 70, 46,103, 21,238,238,238,
-123,115,114,114, 7,188,252,242,203, 40, 40, 40, 96, 23, 47, 94,140,118,237,218,193,215,215,215,168, 54,170,227,202, 57,235,238,
-221,187,158, 26,141, 6,132, 16, 99,204,217, 19,154, 20, 69, 97,215,174, 93,208,106,181, 79,124,216,174,247, 50,204, 29,238,141,
-183,222,221,129,175,238,239,199,134, 13, 27,234, 93,119, 37,208, 78,107,211, 98,173,156,225,218,173,152,255,142, 98,252,248,241,
-204, 91,111,189,133,228,228,100, 76,158, 60, 89,123,246,236, 89,125,102, 70,198, 81,185, 32,172, 51,212, 52,198,117,106, 42, 20,
-138,157,167, 79,159,198,254,253,229,190, 36, 54, 54, 22, 45, 91,182,180,168, 97,146,243, 15,160, 36,105, 29,194,143,199, 32,104,
-240, 30,132, 31, 31, 3,190,240,132,180, 99, 75, 20,153,178, 61, 27, 65,109,154,251,243,242,242,170, 76,212,238,221,187,205,119,
-239,222, 61, 20,192, 49, 0,251, 1, 32, 63, 63,255, 91, 19, 53, 1, 10,111,189, 49,124, 40, 36, 50, 43,196, 60, 76, 69,239,174,
- 29,224,236,228,132,187,209,113, 72, 74,203,207,162, 40, 76,236,223, 77,190, 66,163,209,127,122,233, 14,126,104, 64,147,242,240,
-240,240, 61,112,224,128,172, 90, 4,186,234, 63,206, 48, 76,213,243, 74,227,221,152,253,179,210,100, 89,121, 88,134,127,177,190,
-187, 69,120,196,110,180,244, 30, 8,187,129, 33,248,225,204, 25, 60,184, 23,165,213,151,113,175,252, 11,109,244,119,105,250, 14,
- 31, 62,252,234,207, 63,255,108,155,146,146,130,139, 23, 47,194,199,199, 7,101,101,101,198, 92,240,214,208,212,106,181, 78,149,
-223,161, 40,202,169, 50,240,174,215,235, 43, 27,163,242,143,104, 91,237,115,182,245,104,122, 85,251, 92,165,185,242,126, 6,235,
- 46, 55,147,201, 14, 28, 57,188,215, 50, 42,230, 34,218, 7,118,129,165, 77,107, 8,124, 38,242,242, 75, 81,240, 48, 29, 75,151,
-126,133, 69,139, 23,224,216, 47, 7, 45,253,252, 3, 15,233, 57,174, 5, 0,237, 11,211,238, 20,153, 26,118,124,247, 70,138, 8,
-208,100,197, 40,164,234, 4,229,184, 49,175, 51,163, 70,141,194,177, 99,199,112,239,222,189,141,245,152,172,176,106,145,249,169,
-145, 23,247,111, 4, 33,208,100,199, 40,100,154, 4,229,132,177, 35,153,241,163, 95,197,245,223,215,226,213,246, 9,145,110, 78,
- 24, 86, 80, 97,177, 37, 12,242, 20,102,184, 66,194,113,189,154,217, 58, 15,128,170,102,176,206,227,175, 28,204,231,129, 65, 21,
-198,106,234,227, 23, 38,146,198, 24, 44, 0,104, 9, 88, 82,114, 89,248,246, 69,239,184, 41,147,239, 73,116,145,215,144,174, 19,
-200,166, 68, 78,232, 0,152,223, 2, 52,143,127,167,172,172, 76, 29, 23, 23,103, 62,113,216, 48,116, 11, 8,128,171,131, 3, 90,
-120,120,192, 92, 33,135, 92, 38,173,113,201,106,116, 31, 2, 69, 17, 63, 63, 63, 12, 30, 60, 24, 82,169, 20, 74,165, 18,150,150,
-150,144,203,229,181, 70,179,140,189,202, 37,132,128, 97, 24, 68, 70, 70, 34, 41, 41, 9,182,182,182,184,114,229, 10, 94,121,229,
-149, 39,162, 90,213,205,153, 41, 33,250, 90, 78,252,149, 70,236,180, 41, 90, 60, 79,161,148, 4,194, 44,113, 38,202,168, 14,208,
-233, 56,232,116, 58,252,112,217,128, 63,226,212, 48, 24,244,208,233,116,245,253,102, 93,208,110,110,110,227, 90,180,104, 49, 99,
-204,152, 49,172, 92, 46,135, 90,173, 70, 89, 89, 25,238,221,187,199, 14, 24, 48,176,112,240,224, 16,155, 19, 39, 78,144,138,174,
-195, 44, 19,180,243,220,221,221, 61, 43,186,103,243, 26,179, 87, 83, 20, 85,101, 98, 30,103,226,183, 81,144, 48,229,109,178,113,
-227, 70,240, 60, 15, 66, 72,157,141,164,165,168,223, 22, 47, 91,101,179,114,205,143,176,177,119,198,133, 11, 23,248, 83,167, 78,
-149, 80, 64,236,131,123,247,190,253, 63,224,228, 1,192, 96,202,242, 21, 20, 20,152,251,248,248,192,195,195, 3,130, 32,128,101,
-217,170,232, 75, 94, 94, 30, 52, 26, 13,236, 45, 10,209,220,193, 3, 92,201,121,100, 68,126, 14, 87,203, 24,236, 56,173,103, 95,
-242,197,157,255,130, 3,199, 79, 21,211, 83, 94, 53,195,221,201,197, 19, 52, 97,145,158,157,135,161,131, 94, 5, 35,179,196,163,
-148, 92, 4,182,110,230, 58,246,255,186,187, 50, 20,135,121, 43,246,204, 0,132, 31, 26,146, 43, 45, 45,229, 99, 98, 98,112,247,
-110,185,223,181,182,182,134,133,133, 69,141,255, 56, 77,211, 79, 21,209,170, 52, 89,203, 54,190, 98, 65, 75,213, 40,230,195,176,
-109,215, 77, 4,250,133, 96, 83,248,159, 90, 62, 43,191,239, 55, 90,109,236,222,231, 56,152,225,226,226, 50, 77, 16,132, 69,132,
-144,194, 30, 61,122, 56,239,217,179,199, 46, 45, 45, 13, 55,111,222,196,194,133, 11,115,120,158,231, 8, 33, 20, 33,228,243,103,
-240,115, 66, 53,131,245, 44,145, 42,205,240,174,163, 53, 53, 68, 66, 91,251,112,197,165,143,114,245,228,104, 25, 39,124, 15,128,
-173,247,224, 70,211,255, 57,184,111,163,155,163, 74, 64,176,234,101,100,100, 25,176,236,131, 9,200,203, 43,193, 15, 91,151, 3,
-144,195,192, 49,232, 21,252, 58,156,156,220, 49,117,202, 84,151,141,155, 55,189,195, 9,194, 55,120, 65,200,188,186,225, 23, 0,
- 97, 42,149,234,222, 59, 83,167,170,124,124,222,132,153,153, 25,246,238,221,139, 61,235,214,241,107,128,145, 10,224,220,116,224,
-151,122,117,194,255,210,153, 53,125,186,202,223,127, 58, 20, 10, 5,126, 63,245, 19,180,153,187, 74, 6,117,131,161, 76,139, 65,
- 77, 6, 19,251,196,227, 84,190, 84,138,135, 0, 32, 53, 67, 6,128,199,187,193,158, 55,131, 85,201, 9,252,149,151, 53,181, 70,
- 68,171,209,199, 78,169, 60, 98,235,251,163,189,157,161,163,244,151,143, 35, 77, 39,240, 43, 31, 24,152, 91, 69,100,110,116, 45,
- 38,171, 98,199, 22,188,188,188,240,114,199,142, 24,214,179, 39, 36, 18, 9,204,228, 50, 88,153,153,131,240,229,145,172,202,174,
-195,122,206,137,168, 45,250,228,224,224, 0,153, 76, 86,101,176, 76,136,102,213,170, 41, 8, 2, 36, 18, 9,238,222,189,139, 30,
- 61,122,192,211,211, 19,251,247,239, 71,255,254,253,159,232, 74, 52,213,100, 85, 26,173,199,186,241,250, 3,168,140,100,153,100,
-180,180,122, 10,185,250, 64, 80, 84, 0, 56, 14,224, 9,160,211,106, 65, 8, 64, 8,192, 26,244,208,106,181, 85,191,105, 76,151,
-172,139,139,139,151,185,185,249,146,143, 62,154,231, 31, 24,216, 30, 57, 57, 57, 16, 4, 1, 22, 22, 22, 40, 43, 43,131,181,181,
- 53,186,117,235,246,104,201,146, 37, 25,132, 96,170,137, 38,235,169,169,220,230,103,206,156,169,209,109, 88, 57,169, 51, 82,241,
-214,123,187, 33,151,148,119, 45, 85,230,240,212,119,220,237,211,171, 59,174,222,138,229,254, 51,111,173, 78,154,119,115,133,139,
- 32,108, 79,125,138,245, 34,132, 32, 55, 55, 23, 89, 89, 89, 24, 50,116, 40,246,252,252, 51, 18, 19, 19,209,186,117,107,244,233,
-211, 7, 78, 78, 78, 72, 76, 76,196, 31,151,116,208, 21,228, 35, 95,127, 19, 74,171, 32, 28,185, 16,167, 91,184,209, 16,247, 47,
- 30, 48,134, 0,152, 96,109,109,221,180,172,172, 44,131,227,184, 3, 0, 14, 0, 24, 41,145, 72, 70, 42,149, 74,215,226,226,226,
- 4,148, 87, 19, 29,109, 72,204,220,204,204, 65, 97,102, 13,129,211, 65, 34,145,192,211,211, 7,132,215,163,160, 88,131,137,163,
- 6,227,214,221,104,156, 58,119,157, 99, 89,225, 59, 99, 54, 43,195, 48,196,215,215, 23,217,217,217,144, 74,165, 48, 55, 55,135,
-165,165, 37, 62,249,228, 19,172, 91,183,174,202,100, 53,214,104, 77, 2,124,173,189, 44,175,127,185,190,220,100,101,166,103, 32,
- 43, 85, 10,149,131, 51,190, 91,183, 70, 93,144,152, 25,244, 35, 16,251,188,159,100, 5, 65,248, 60, 45, 45,205, 73, 34,145,184,
-112, 28,135,148,148, 20,220,184,113, 3, 51,103,206,204,202,203,203, 11, 70, 35,215,209,204,204, 44,187, 50,146, 85,209,117, 88,
- 87,119, 98, 97,181, 72, 86, 97, 61,146,117,117, 19, 54,243,241,176, 58,187,117,245,108,175, 78, 65,221,104,165,196,186,160,244,
- 97,102,143,203, 23, 47,116,155,185,250,135,119,146, 10, 74, 95, 5, 16, 95,151,168, 66, 42, 29,208,165,123,119, 9, 72, 22, 36,
-242, 30,248,106,229, 40,228,228, 22,163, 32,191, 4, 50,153, 5,244, 44, 3, 94,160,208,173, 71, 79,252,180, 99, 31,218, 76,153,
-204,200,165,210,126,156, 94,255,194, 24,173, 10,150,127,255,253,247, 94,126,126,126,216,190,125, 59,206,237,220,137,241, 69, 69,
-184, 64,211, 12, 43,149, 58,158,100,217, 45,104,192,104, 85,215,105,211,166, 13,126,252,241, 71,236,218,181, 43,121,220, 43,217,
-135,102,143,131,147,193,128,215,110,222,135,125,147,193,192,205,251,176,127,201, 15, 45, 56, 9, 30, 82, 84,205,225,160, 66, 67,
- 67,123, 87,159, 63,103,100,160,142, 46,118, 9,128,224,208,208, 80, 82,125,222,224,129, 83,213,114,250,242, 87,155,122, 7, 52,
-247,162,216,253,107,145,162,230,244,159,222, 55,200, 31,148,146,217,209,192,154,122,174, 32, 8,195, 48,176, 50, 55,135,202,214,
-182, 60,204, 79,211,128, 0, 8, 44, 64,241,229, 6,128, 8, 20, 8,111,210, 1, 3,114,185,188,214,196,119, 83,115,179,170,107,
-150,148,148,224,209,163, 71,152, 58,117, 42,148, 74,101,185,115,207,204,132,183,183, 55, 36, 18, 9,210,210,210,240,251,239,191,
-163,105,211,166, 80, 40, 20, 38,185,173,106,209,165,118, 40,175, 50,108,151,145,145, 97,237,234,234, 10,147, 35, 90, 2, 65,153,
-142,130, 94,207,227,193,131, 7, 72, 79, 79,199,163,132,135,232,164, 46, 6, 1, 3, 66,136, 73, 17, 45,119,119,247,128,102,205,
-154,109, 90,177, 98,133,204,195,195, 3,132, 16,216,217,217,162,172,172, 12,185,185,121,104,221,186, 53, 60, 61, 61,177, 98,197,
- 10, 0,216,243, 79,155,172,199,246,169, 42,163, 85,221,112,189,247,127, 94,200,207,183, 4,195,208, 85,198,185,129, 28, 45, 25,
- 0, 4,191, 58, 92,114,246,212, 73, 11, 14, 88,146,201, 48, 75, 36, 13,183, 35,203, 11,130,178,174,247, 83, 82, 82, 32,149, 74,
-113,240,192, 1,228,103,101, 33, 48, 48, 16,157, 59,119,198,195,135, 15,113,235,214, 45, 56, 56, 56, 64,229,209, 21, 23, 18, 12,
-136, 74,215,192,198,198, 6,113,169,244,191, 57,100,192,148,190,125,251, 46,252,246,219,111,157, 92, 92, 92,164, 57, 57, 57,126,
-235,215,175, 15, 92,191,126,253,172,119,222,121,199,249,157,119,222,177, 83,169, 84,146,204,204, 76,223, 15, 62,248,224,165,176,
-176,176,166, 0, 86,213, 39,104, 97, 97,101,207,200, 44, 64, 81, 18,216,218,216, 65, 34,183,128,192, 73,192, 11,128,181,141, 10,
- 87,111, 29,196,149,136,146,105,217,121, 56, 96, 84,124,172,162,221, 29, 28, 28,158,136, 84,207,156, 57, 19, 91,183,110,173,234,
- 70,108,172,201, 90,182,254, 21, 75,170,194,100,101,166, 72, 64,233,154,226,248, 47,215, 10, 11, 18, 51,123,188, 8, 38,171,242,
- 24, 71, 8, 65, 66, 66, 2,202,202,202,112,233,210, 37,124,254,249,231, 57,143,155, 44, 39, 39,167, 41,214,214,214,139, 75, 75,
- 75,191,202,204,204, 92,219,224,133, 95,185,137,170,124, 92, 57,175,181, 59,209,200, 69,245,174, 45,146,229,233,106,118,250,214,
-165,221,222, 54,228, 14,133,164,169,192,131,226,123, 86,225, 78,189, 6,118, 26, 68,119,216,240, 69,147,206,211, 62, 57,157, 82,
-172,245,171, 43,178, 37,240,124, 7, 11, 75, 43, 0,217,184,121,227,124,149,201,202,203, 47,130,206,192, 64,167,167,160, 53,208,
-120,185,239,107, 88,183,105, 23,210,178,243,193,243,124,219, 23,204,100,217, 7, 4, 4, 76, 31, 57,114, 36,150, 44, 89,130,176,
-111,191,213,191, 77, 81,197, 18,128,156,224,121, 8,132, 80,180,113, 73,236, 53,116,190,249,230,155, 95, 0,140, 94, 49, 19, 93,
- 11, 74, 49,209,109, 48,177,111, 50,184,252,131, 35, 62, 34, 0, 96,159, 19, 86,243,148, 25, 18, 18, 66, 85,246,172,153,218,195,
-246,223,142, 36, 36, 36,228, 66,104,104, 40,170,207,235,251,130,149,179,223,192, 15,231,204, 88,217,169,127, 79, 42, 99, 78, 63,
-228, 23,107,185,249, 81, 6,121,170,166,126,147, 85,157, 15,215,175,199,173,216,242,255,177,135,147, 19,230,141, 29, 11,194, 1,
- 87,238, 69, 97, 95, 88, 24, 70,245,237, 11, 11, 51, 51,163, 35, 27,130, 32,212, 26,197,170, 30,205, 50, 53,234, 84, 88, 88,136,
- 3, 7, 14,160,115,231,206, 80, 42,149,144, 72, 36,104,215,174, 29,162,163,163,209,172, 89, 51, 80, 20,133, 35, 71,142, 96,216,
-176, 97,136,143,143, 71,215,174, 93, 45,147,146,146, 76, 54, 90, 81, 81, 81,214,132,144, 94,149,209,143,198,162,211,233, 16, 19,
- 19,131,193,131, 7,195,206,206, 14,238,238,123, 16,118,122, 55,148, 1,227, 65, 81, 48,201,104,241, 60, 63,105,208,160, 65, 50,
-138,162,160,209,148,193,204,204, 28, 22, 22,150,176,178,178,134,175,175, 31,210,211,211,209,191,127,127,125, 92, 92,220,134,140,
-140,140,253,166, 46,171,191,191,191, 69, 98, 98,226,248, 38, 77,154,200, 1,192,220,220,188,117,179,102,205,230,198,199,199,151,
-152, 26,213,170, 52, 88, 20, 69,129, 97,152, 42,163, 37,161,105,184,186, 56, 85, 61,175,200, 79,163,234,209, 42, 78,203,211, 41,
- 0,192,203,203, 11,235, 54, 31,163, 7, 13, 26,132, 89,179,102,129,101, 89,108,216, 80, 94,100, 55,102,204, 24, 24, 12, 6, 28,
- 58, 84, 94, 36, 41,145, 72,234, 13,155,220,184,113, 3, 55,111,222, 4,203,178, 40, 42, 42,194,175,191,254,138, 11, 23, 47, 98,
-239,145,223,144,152,240, 16,237,252,188, 49,121,242, 36, 72,165, 82,236,216,177, 3, 61,122,244,248, 87, 15, 8, 82,169,116,220,
-214,173, 91, 93,183,111,223, 94,120,228,200, 17,117,151, 46, 93, 20,107,214,172,113, 90,183,110,157, 74,175,215,227,253,247,223,
-207,190,126,253,186,110,232,208,161, 22, 91,182,108,113,109,222,188,121, 63,142,227,106, 51, 90, 22, 0, 70, 1,120,179,160, 68,
- 47, 41, 44,209, 64,224,244, 72, 72,124,132,162, 82, 61, 4,222,128,228,212,116,148,106,121,228,229,151,160, 93,135, 87,191, 63,
-127,254,252, 2,131,193, 48, 31, 64,104, 67,203,121,239,222, 61, 92,191,126, 29,137,137,137, 72, 72, 72,168,233, 20,167, 76,193,
-174, 93,187, 76,142,104,213,110,178, 24, 80,186,102, 8, 61, 18, 94,152,253, 48,227,133, 49, 89, 21,199,160, 69,174,174,174,139,
- 92, 93, 93,205,206,156, 57, 99,211,164, 73, 19,112, 28,167,127, 60,146, 21, 28, 28,252,233,214,173, 91, 93,155, 53,107, 54, 19,
-192,218,255,134,101,167,105, 76,249,106,227,116, 71, 43,121,114, 58, 30,172,170, 24, 75,144, 1,202,138,129,243, 63, 67,210,253,
-179, 71, 51,135,126,100,247,241,246, 37, 83, 4, 8,117, 86,200,198,197,167, 96,227,198,117,152,253,254, 68,252,244,195, 87, 16,
- 4, 9,116, 44, 3, 47,159, 46,208, 25, 4, 80,180, 4,129, 29, 58,226,220,249, 75,144,210,192,129,237, 27, 95, 48,159,133,252,
-200,200,200, 13, 71,142, 28,121,119,214,172, 89, 16, 4, 65,190,120,227, 70, 77, 78, 78,206,114,152, 54,254,213,227, 58,195, 54,
-110,220, 24,251,241,186,156, 95,102,143, 3,147,120,156,202,191,121, 31,246, 35, 62, 34, 56,184,146,194, 75,126,200, 87,214,126,
-138,191,248,216,252,197, 48, 90,149, 78,178,250,188, 54, 58,180,108,250,133,141,189,221, 36,218,202,221,113,222,172,183, 37,241,
-153, 90, 28,106, 50,182,244,247,157,223, 89,100,114,138,239,227,160, 93, 99,202, 15,239,251,253,247,170,199, 95,239,217, 83,235,
-123, 25, 35, 70, 24,125,101, 86, 87, 20,203,212, 72, 22, 0, 40,149, 74,219,126,253,250,225,149, 87, 94,193,235,175,191, 94,149,
-147,213,190,125,123,236,221,187, 23,195,135, 15,199,237,219,183,225,234,234,138, 86,173, 90,161, 85,171, 86, 56,121,242,164,169,
- 7, 57,240, 60,143,128,128,128,202,170,195,118,169,169,169,214,141,109, 72,157, 78,135,188,188, 60,216,219,219, 67, 46,151, 35,
- 40,168, 51,222,125, 47, 8,142,174, 63, 34,192,223, 15,106,181,186,170,252,221,136,147,109, 64,139, 22, 45,144,147,147,131,156,
-156, 28,168, 84, 42,184,185,185,193,197,197, 5,171, 86,173, 34,107,215,174, 61,101, 48, 24, 54,228,230,230,154, 28,201,114,113,
-113,233, 73, 81,212,167, 26,141, 70, 94,237, 10, 87,174, 82,169,142,106, 52,154,229, 25, 25, 25, 70, 39,130, 82, 20, 5,131,193,
- 0,138,162,112, 34,193, 13,106, 61,133,226,212,155,152,245,127,222, 53,140,151, 84, 42,109,176,187,148, 16,162, 30, 61,122,180,
-147,167,167, 7, 82,226,238,225,224, 65,130,111,191,253,182,178, 42, 18,177, 21, 23, 6,149,207,251,244,233, 3, 31, 31, 31, 16,
- 19,198,202, 16, 4, 1,119,239,222,197,158,163, 23,224,234,237,143,228, 7, 49,184,117,242, 56,154,168,236,209,166, 67, 71,176,
- 44,251, 84, 67,111, 60, 11, 88,150,221,214,178,101, 75,162,215,235, 47, 0, 88, 23, 17, 17, 49, 49, 35, 35,227,253, 99,199,142,
-185,141, 28, 57, 50,253,248,241,227,107, 0,108,143,136,136,152,190,116,233,210, 87, 56,142,171,181, 90,144, 97,152,159, 62,248,
-224,131,224,145, 35, 71, 82, 50,154,213,159, 57,189, 67,194,113, 44,245,225,252,109,252,249,203, 23,104,142, 99,169,215, 71,127,
- 32,156,252, 61,130,158,246,222,215,124,251, 46,131, 16, 25, 25,233, 18, 18, 18,178,148,101,217,122,141, 86,101,164,170,174, 8,
- 37,195, 48,152, 56,113, 34,246,238, 53, 62,131,106, 50,208,204,218,219,242,250,178,245,125, 45, 41, 73,105, 53,147,213, 28,161,
- 71,194, 11,179, 30,164,191, 80, 38, 11, 0,242,242,242, 54, 3,216, 44, 8, 66,150,133,133, 5, 74, 74, 74,106,219,255,204, 34,
- 34, 34,204,228,114, 57, 94,125,245, 85,251,176,176,176, 88,154,166,215,166,167,167,215,233, 56,106,235, 38,172,173, 59, 17, 79,
- 81,117,104,167, 66, 72, 80,207, 14, 86,247,109,150, 88,153, 73,180,183,155,196,154, 89, 83, 0,138,116,206, 9, 87,147, 70, 21,
- 83,217,138,246, 29,251,188, 4,107,137, 69, 72, 33, 87, 82,171,209,162, 25,230, 86, 81, 65,225,128,226, 18, 61, 46, 95,137,196,
-232, 81, 45,160, 51, 80, 16, 4, 26,165,106, 29,192, 72, 65, 3, 24, 51,118, 2, 8, 37, 65,126, 86, 58, 24,134,137, 0,199,225,
- 5,227,147,233,211,167, 15,152, 63,127,126,211,121,243,230, 97,222,188,121,222, 91,183,110,221,188,108,217,178,121, 57, 57, 57,
-109,209,192,224,227,245,232, 52, 57,190,247,179, 57, 71, 47,109, 42, 26,212, 77,243,224, 37,191,242,200,215, 75,126,200,151, 74,
-241, 80,194, 32,143,144,154,105, 70, 33, 33, 33,189,171,207,159, 51, 30, 79,130,175,122,110, 84,142, 86,139,166,238,175,117,104,
- 31,240,222,130,249, 11,172,162,175,158,199,199, 95,172, 35, 45, 59,246, 43,217,124,233,150,190,212,194,103, 64,105,238,195, 43,
-198,250, 11, 0,120,237,229,225,104,215,186,243, 19,111,246,232, 83, 62, 88,251,229,115, 55,144,149,147,102,244,201,182,194, 28,
-212,154,147,101, 76, 73,255,227,104, 52,154,194,200,200, 72,167,212,212,212, 26,137,239, 62, 62, 62,160, 40, 10,225,225,225,184,
-126,253, 58, 70,143, 30, 13,137, 68, 2,169, 84,138, 11, 23, 46,152, 20,141,169, 22, 93,170,172, 58,236,239,225,225, 81, 87,181,
- 97,131, 90, 26,141, 6, 69, 69, 69, 56,125,250, 52, 90,180,104,129,101,203,150,193,205,213, 25, 11, 22,204,129, 32, 8, 40, 46,
- 46, 6,207,243,198, 70,180,132,202,104,145, 32, 8,200,201,201, 65,211,166, 77,177,126,253,122,172, 89,179,102,105, 70, 70,198,
- 49, 83,151,209,211,211,211,150,231,249, 15, 7, 13, 26,212,111,232,208,161,232,223,191,230,120,172, 63,255,252,179,213,161, 67,
-135,150,127,247,221,119,175, 25, 12,134, 21,217,217,217, 57,198,232,254,248, 99,249,240, 75,202, 46,139,240,241,200, 38,120,115,
-198, 14,172, 90,117, 24, 10,133,162,198,137,119,201,146, 37,245,154, 24,129,144,150,178,220,171,233,115, 62,250,198,105,249,242,
- 48,132,133,101,131,166,105,184,186,186,130,166,105, 60,122,244, 8, 52, 77,195,219,219, 27, 52, 77, 35, 45, 45,173, 50, 39,176,
- 0,181, 84, 61,214,126, 21, 78, 67,171,213, 34, 37, 57, 17,169,113,177,176, 44,206,132,202, 90,137,130,123,119,209,110,242,148,
-170,241,159,254,101,118,233,245,250, 93,213,158,127,115,252,248,113, 61, 69, 81,175,163, 60, 79,163, 50,162,177,148,227,184,165,
-117,137,116,233,210,165,253,252,249,243,165,149,195,109,184,121,125,201, 25, 12, 6, 1, 0,252,218,245,170,225,246, 31, 62,124,
-136, 85,171, 86, 65,173, 86, 67, 38,147,201,140,217, 14,130, 32, 84, 85, 24,214,102,194, 76, 49, 89, 0,224,224,237,241,125,248,
-205, 11,252,157,184, 77,154,136,251,191,154,103, 36,211,160,245, 47,174,201,122, 60,178,229,225,225,177, 72, 16, 4, 66, 8,249,
-172,218, 91, 10, 47, 47,175, 75,103,206,156,113,224, 56, 14,223,125,247,157,109,102,102,166,109,175, 94,189, 62, 6, 80,167,209,
-170,173,155,176,182,238, 68, 84,171, 58, 84, 40, 20,246,122,125,157,193,147, 39,170, 14,121, 30,190,214, 86,182, 40, 64, 42,116,
-142,108,251, 66, 7, 46,255,108,198,148,219,110, 73, 29, 90, 91,240,108, 83,186, 88, 15,119,165, 45, 4, 66,234, 44,141,214,177,
-236,175,183,111,222,122,213,203,179, 5,115, 44,244, 34,134, 12, 27, 9,157,142,134,150,165, 64, 49, 82, 80,140, 12,109,219,117,
- 64,171, 54,237, 64, 0,220,248,227, 42,167,103,217,179, 47, 82,219,187,118,127,119, 52, 69, 97, 45,136, 64,106, 25, 71,171,233,
-176, 97,195,150, 3,120,175, 33, 29,167, 46,239,142,166,233,114,157,234,227,104,125,240,238,116,220,251, 67,106,115,241,230, 74,
- 89,255, 46, 56,145, 19, 70, 65,105,246, 87,213,161,148,126,170,161, 57,158, 23,195,213,176,209,242,244,244,180,181, 86,152,253,
-248,206,228, 73, 86, 73,119,174, 33, 51, 42, 28, 87, 46,198, 22,236, 59,116, 56, 95,157,151, 61,217, 4,147, 85,213,205,231,224,
-210, 4, 62,254, 79, 26, 45, 51, 75, 21, 0,192,199,191, 51, 24, 11,211,134, 17,170, 45,154,213, 24,147, 85,253,128, 93,219, 24,
- 90,211,166, 77,195,214,173, 91,209,189,123,119,180,108,217,178,234, 96,111,106,212,172,150,232,146,201,213,134,213, 41, 41, 41,
-129,183,183, 55,182,108,217,130,136,136, 8, 88, 89, 89, 97,244,232,209, 40, 41, 41,169, 50, 88,198, 38,195, 19, 66, 30,158, 57,
-115,166,211, 27,111,188, 65,164, 82, 41, 85, 88, 88, 8, 91, 91, 91,172, 95,191, 94,157,145,145,113,162, 17, 38,107,164, 76, 38,
-155, 51,106,212, 40,198,207,207, 15, 89, 89, 89,176,182,182,102, 41,138,146, 2,128,173,173, 45,107,110,110,142,233,211,167, 35,
- 48, 48,176,231,188,121,243,186, 75, 36,146,245,233,233,233, 59,234,219,151, 40,138,170, 58,161, 78, 94, 27, 3,189,190,252, 4,
-189, 97,195, 6, 84,228,186,253,213, 69, 16, 23, 7, 24, 81,201, 98,105,105,137,150, 45, 91,214,218,246, 61,123,246,196,141, 27,
- 55,202,187, 38, 37, 18, 56, 57, 57,225,202,149, 43, 70, 85, 82, 85, 14, 4, 25, 25, 25, 9,127, 31, 71, 68,132,157,129,163, 82,
-138, 64, 55, 23,120,244,236,141,216,216,216,127, 51,154, 69,161, 60, 15,163,111,197, 62,184, 13,192,180,106,207,215, 3,248,222,
- 20, 65,142,227, 8, 77,211, 84, 74, 74,138, 65,169, 84, 82,246,246,246, 18,133, 66, 1,157, 78, 87,101,184, 30, 62,124,136,208,
-208, 80,164,166,166,194,222,222,158,182,177,177,129,193, 96, 40, 48, 70,223,215,215, 23, 46, 46, 46, 53, 18,223, 39, 79,158,220,
- 40,147, 53, 17, 8,216,250,229,138, 38, 10,154,177,241,119,124, 13, 9, 49,143,180,180, 30,102,255, 11, 38, 11, 0, 10, 11, 11,
- 55, 3,216, 92,249,220,209,209,241, 45,134, 97, 22,232,116, 58,155, 11, 23, 46,216,170, 84, 42,106,199,142, 29,236,103,159,125,
- 86,200, 48, 76, 1, 69, 81,171,255,125,115,136,168,220,162, 56,111,169,157,155,112, 71, 75,174,190,159,242,113,171, 2,105, 11,
- 21,213, 38, 0,195,178,163, 47,191,197,197,117,203,202,200,164, 9,132,168,122,142,193,219, 62,158,191,228,195,216,152, 91, 94,
-102,214,102,152, 54,125, 62, 78,156, 58, 7,138,150,226,210,213,112,232, 13, 60,114,243,139, 48,106,204, 56,120,184, 58, 34,234,
-250,233, 28, 78, 16,214,191, 88, 38, 91, 88,247,234,144,183,236, 20,230,202,138,109,194, 99,215, 15,115, 64,211,107,177,112,225,
- 66, 4, 4, 4,204,136,140,140,252, 28, 13,140,163, 69, 81,194,186,182,189,199,216,201, 20,229, 58, 68,224,177,229,192,199, 21,
-227,104,205,198,250,205,135,218,182,241, 73, 88, 92,223, 56, 90, 47,144,201,170, 62,175,223,104,121,123,123, 43, 44,164,152, 42,
-101, 36,243,222, 25, 59, 84,149, 29,119, 15,169,209,183,202,187, 23, 12, 26, 67,230,131,104, 99,134, 66,239,139,154,227,119,144,
-250,186,174,180, 90,163,174,232,107,104, 86,158,112, 31,143,102,153,104,178,158,208,172,110,182,170,143,155,229,233,233,137,229,
-203,151, 27, 51,142,214,227,235, 94, 73,127,148, 39,192, 87, 79,134,239,111,164,201,170, 85, 83,165, 82, 6,231,135, 96, 0, 0,
- 32, 0, 73, 68, 65, 84, 33, 47,175,124,132,132,224,224, 96, 4, 7,255, 85,207, 96, 48, 24,170,162, 88, 86, 86, 86,181, 69,180,
-158,208, 52, 55, 55,255,248,240,225,195,147,174, 94,189,250,198,220,185,115,165,175,188,242, 74,165,153, 43,131,113,247,118,171,
-161,201,243,252,244,211,167, 79, 51,130, 32, 96,203,150, 45,184,113,227, 6, 81, 42,149,159, 42,149,202,117,230,230,230,188, 70,
-163,153, 54,101,202,148,113,139, 23, 47,166,123,246,236,137,107,215,174,209, 77,155, 54,157, 0,212, 24,196,178,214,117, 15, 15,
- 15, 7, 77,211,224,242,147, 49,227,227,125,176, 48,151, 32, 38, 38, 6,249,249,249, 79, 12, 98,106,204,246,172, 30, 41,169,156,
-122,246,236, 89,213, 13, 25, 20, 20, 4,134, 97,112,251,246,237,186,186, 97,171,107, 18, 7, 7,135,170,253, 67, 38,147,225,220,
-185,115,248,226,139, 47,224,101,111,139,130,232, 8,184, 4,191,140,126,147,166, 96,244,232,209, 96, 24, 6,246,246,246, 85,145,
- 95, 35,246,165,167,161,186,230, 36,127,127,255, 9, 81, 81, 81, 30,109,219,182,117,141,140,140,236, 19, 16, 16,224, 29, 17, 17,
- 81,249, 92, 1,227,114,115,170, 52,255,252,243,207,131,235,214,173,155, 62,113,226, 68,153, 32, 8,124, 82, 82, 18, 11,128,114,
-113,113, 97,254,252,243, 79,225,216,177, 99,208,104, 52,240,240,240,160,221,221,221,169,179,103,207, 10,209,209,209,225,132,144,
-249,198,172, 59,207,243, 53,134,113,168,124,252,243,207, 63,155,252,127,111,210,202,119,217, 43,189,252, 60,115,211,111, 35, 35,
- 45, 14,124,145,202, 16,122,228,184,206, 68,147,245,119,183,209, 63,169,185,228,193,131, 7,238, 58,157, 14,114,185, 28, 27, 54,
-108, 48, 44, 95,190, 60, 42, 55, 55,183, 7,106,175, 40,175,161,217,200,170,195,252,122, 52,159,168, 58, 44,202,195,137, 35, 71,
-255,236,100, 57,108, 27,102,164,231, 84, 37, 54, 18,138,178, 63,236,220,186,135,178,115,219, 52,250,228, 34,186,132, 47, 59, 81,
-207,186,235, 53,122,253,200, 97,195,199,252,182,119,239, 30,203,207, 22, 45,194,149,240, 8,228, 21,150, 66, 32, 12, 4,138,194,
-130, 5,159,193,197,209, 30,197,233, 15,202,116, 6,195, 48,212, 28, 67,235,185,111,119,138,162,103,158, 61,182, 99, 45, 77, 65,
- 80,103,221, 87, 48, 37,113,202, 55, 71, 15,147,140, 28, 57, 18,135, 15, 31, 70,100,100,228,166,122, 76, 86,149, 38, 33,244,204,
-136, 11,251,214, 82,128,160,201,185,175,144,148, 38, 40, 39,140, 29, 38, 25, 61,122, 52,126, 9,189,138,189,199, 19, 54,238, 61,
-142,227,120,177, 49,125,100,120, 43, 9, 34,123,180,110,230,222,179, 67, 27, 51, 9,175, 65,106,116, 28,242,213, 90,156,189,151,
- 84, 72, 19,186,209, 99,235,148, 31, 32,101, 72, 78,126, 80,203,149,149, 89,197, 9, 93,107,146, 38, 77,211, 53,162, 89, 79, 19,
-201,170,190,156,206,206,206, 53,110,231, 82,253,196, 93,153, 3,212,136,161, 29, 62, 78, 78, 78,182, 78, 78, 78, 6, 33, 4,225,
-225,225,214, 65, 65, 65, 31, 63, 77, 52,107,206,156, 57, 85, 81,171,199,231,181,189,214, 16, 21, 73,233,107, 88,150, 61, 48,111,
-222,188, 25, 65, 65, 65,175, 46, 90,180,136,130, 9, 55,224,125, 44,154,195, 9,130,128,243,231,207,227,240,225,195,188,193, 96,
-152,154,145,145, 17, 81,237, 35,223,221,188,121,243,236,240,225,195,119,220,191,127,159,137,138,138, 2, 33, 13,215,157,106, 52,
- 26,180,108,217, 18, 28,199, 97,229, 12, 79,148,148,180, 5,199,113,224,121, 30, 22, 22, 22, 85, 81,188,234,230,185,161,253,136,
-231,249, 39,140, 86,120,120, 56, 24,134, 65,143, 30, 61,112,235,214,173,170,136, 86, 67, 17, 40,131,193,144,236,236,236,236,188,
-100,201,146,170,229,202,201,201,193,153, 51,103,208,165,107, 55,180,158, 58, 13,233,233,233, 88,189,122, 53,220,220,220,176,108,
-217, 50,228,231,231,131,227,184,127, 58,156, 62, 32, 42, 42,202, 99,236,216,177,217, 17, 17, 17, 30,161,161,161,182, 33, 33, 33,
- 22, 99,198,140,201,142,136,136,240,160, 40,170, 27, 76, 76,130, 22, 4,225,147, 5, 11, 22,156, 90,182,108,217,199,239,189,247,
- 94,208,196,137, 19,165, 82,169, 84, 72, 75, 75,227,246,236,217, 67,181,108,217,146,150,201,100,212,233,211,167,133, 63,254,248,
-227, 58,199,113, 43, 1, 92, 50, 37,226, 92,221,100, 49, 12, 99,172,201,170,193,251, 78,138, 9, 86,116, 78,143,117, 27,150,211,
-126, 62, 30,134,157,123,206,164, 92,186,246, 32,158,209,113,239,255, 88,207,208, 0, 47, 50, 12,195,236,247,247,247,127,107,230,
-204,153,230,253,251,247, 87, 44, 94,188,184,168,164,164,164, 46,147, 85,203, 5,243, 63, 82,117,248,195, 39,115, 67,223,255,160,
-237, 91,205,254,227,210, 4, 97,234,108, 20, 72, 24,218,218,150, 70, 7,111, 6, 37,185, 15, 85,199,127,219,254, 8, 64, 67,227,
-178,253,121,243,110,100,223, 54,109,219, 31, 90,185,108,165,211,167, 31,205,147, 30, 10,253, 21,132, 51, 32,252,194, 5, 88,202,
-120, 18,125, 51, 44, 75,103,208, 15,197, 11,120, 11,158,140, 43,223,239, 5,112,212,222,222,254,206,164,137, 19, 91,250,251,143,
-129, 82,169,196,193,131, 7,177,235,187,239,248, 53,192, 27, 10,224,214,244, 6,198,211,203,190, 94,165,115,123,202,164, 73,190,
- 29, 58,252, 7, 74,165, 18, 7, 14, 28,192,142, 53,107,140,214,121,206,169, 28, 25,254, 4,254, 26, 33,190,129, 28, 45,154, 42,
-185,254, 32,169, 52,252, 65, 82, 41, 4, 66, 4, 66,116, 52,141, 20,181,193,176,236, 65, 66, 90,163, 76, 65,101,215,225,210, 47,
-103, 62,187, 62,143,106,230,167,177, 37,221,181,152,172,212,234,247, 72,171,126,146,174,235, 49,203,178,169, 70,202,175,240,242,
-242,122,226,181,198,135,126,137, 73, 38,203,216,113,180, 0, 32, 47, 47, 47, 3,192,167,215,174, 93,251,249,213, 87, 95,157, 2,
- 32,173,145,109,180,165,119,239,222, 83, 1, 48, 20, 69,109, 74, 79, 79,143,120,226, 15,159,145, 17,235,230,230,246,181,143,143,
-207,180,242, 11, 83,106, 75, 3, 39,242,132,182,109,219, 26,106,107,139,186,158, 11,130,208, 96, 27, 21, 22, 22,162,115,231,206,
- 79,220,211,146, 16,130,164,164,164,202,136, 83,213,182,175,207,192,149,150,150, 78,123,247,221,119, 55, 75,165, 82, 47, 0, 84,
-165,201,229,121,158,249,254,251,239,205,120,158,103, 0, 80, 52, 77,115, 82,169, 84,123,248,240, 97,142,227,184,100,157, 78, 55,
-237, 31, 62, 64, 28,160,202,111,197,160,142,138,138,242,171,136,100,165, 70, 70, 70,222,222,187,119,175, 10,192,190, 70,234, 94,
- 42, 43, 43,187,180,124,249,242,158, 27, 54,108,248,100,218,180,105,157, 71,143, 30, 45, 9, 14, 14,198,137, 19, 39,248,243,231,
-207,135,107, 52,154, 21,166, 24,172,138,182, 44,242,244,244,172, 50, 92, 13,252,151,235, 77,228,117,240, 86,172, 27,247,182,155,
-217,150, 21,103, 74,115,211,245, 87,217, 82,253,252,237, 64, 36,254,135,201,202,202,154, 11,224,179,213,171, 87,167, 7, 6, 6,
- 42,100, 50,153,222, 88,147,245, 15,194, 9,133,165, 3,191,237, 55,226,104,239, 5,239,250,244,235,211, 67,233,217,196,201, 61,
- 58, 46, 11, 15,175,157, 80,223, 57,254,101, 34,209, 21, 12, 1, 96, 76,230,250, 31, 58,131,161,197,156,121,115,102,200,165,210,
- 87,121,158,111,247,202,217, 35,132, 97,152, 8, 61,203,158,173,232, 46,212,190,192, 77,190,244,235,175,191,110,233,239,239,143,
-131, 7, 15,226,236,238,221, 24,149,155,139,115, 12,195,208, 50,153,195,113,131,225, 27, 24,103,144,150,174, 90,181,202, 55, 32,
- 32, 0,251,247,239,199,233, 29, 59,240,255,236, 93,103, 88, 20,201,218, 61, 61, 57,146, 36, 11,136, 24,128, 69, 49, 98, 90,113,
- 49, 99,118,205,113,205, 57,103, 92,117, 13,107, 14,107, 90,149, 85,215,128, 57,187, 98, 22,179,152, 5, 65, 17, 84, 50,195,144,
-135, 48,121,166,167,251,251, 65,184,168,132, 1,221,187,247,126,119,206,243,244, 51, 51, 29,206, 84, 87, 85, 87,157,126,171,234,
-125, 7, 87,143,167,188,190,174, 5, 0,219,162,159, 89, 0,162, 1, 52, 7, 32, 0,160, 65, 97,104, 39,155,210, 93, 88,209,177,
-226,227,247, 9,130,248, 59, 39,194, 86,238, 25,254,115, 68,126, 72,104,254,173, 83,161, 82,169,114,220,221,221,171,180,230, 90,
-175,215, 87, 56,134, 75,146,100, 74,221,186,117,141,182, 90, 24, 35,138,114,114,114,124,254,198,194,248,170,185, 88,159,116, 34,
- 20,149,224,232,232, 72, 21,119,250,101,137,176,178,246,209, 64,124, 85,254, 39, 45, 45, 45, 26,192,220,234,166, 51, 53, 53,245,
- 44,140, 8, 26,109,236,121, 0, 32,147,201,190,121, 48, 95,130,166, 37, 43, 86,172,168,146,192, 6, 77, 87, 36, 62, 35,228,114,
-121, 43, 99,254, 91,167,211,225, 31,196,169,162,141, 17, 25, 25, 57,129, 32, 8,127, 20, 14, 9, 4,226,219,120,243,126,144,159,
-159,255, 96,227,198,141,237,246,238,221, 59,155,166,105,228,231,231,111,171,170,192, 42,121,123,206,200,184,252,173,110, 60, 39,
- 93,123,251,120, 96, 74, 71, 85,174,110,246, 62,185,246, 48, 76, 40, 49, 70,209, 52,125,112,228,200,145,173, 1, 28,250, 90,178,
-114, 86, 29,126, 45,226, 41, 89, 94,147, 59,243,126, 29,123,199,210,172, 39, 12, 44, 79,104, 25,151,160,205,190, 12,224, 0,140,
-155,230, 80,114,191, 36, 69,109, 33,181,218, 45,165, 58,151,255,133,114,174,225,237,237, 61,123,204,152, 49, 88,182,108, 25,174,
-111,222,172,155, 66, 16,121,108,128,190, 86,248,162,201, 32,128, 69,198,242,140, 26, 53, 10,203,150, 45,195,149, 13, 27,170,203,
- 83, 17,108, 9,130, 8, 6,128,128,128,128,159,215,173, 91,103,181,120,241,226,198,235,215,175, 95, 91,244,251, 77,241,241,162,
-190,174,215,226,197,139, 27,150, 58, 94, 0,224,249,223,156,159,101,122,134,255,187,209,217,196,105,226, 52,113,154, 56, 77,156,
- 38, 78, 19,167,137,243,107, 64,211,116,207,194,143,242, 63,203,251, 94,234,243, 31, 1, 11, 38,152, 96,130, 9, 38,152, 96,130,
- 9,255,133, 40,109,197,170,206,241,111,136,226, 57, 90,165,177, 23, 40, 92,214, 93,158, 42,173,202,170,135,234, 40,219, 91, 38,
- 78, 19,167,137,211,196,105,226, 52,113,154, 56,255,231, 56, 43,227,254,226,122,154,166,123, 18, 4, 17, 76,211,116,175,242, 62,
-139,133,213,231,223, 75,125,126,179,105, 7,101,160,120,110,214, 23,115,180,254,110,152,204,170, 38, 78, 19,167,137,211,196,105,
-226, 52,113,154, 56,191, 10,197, 67,128, 0,232,128,128,128,197,255,129, 67,135,142, 69, 34,171,244, 6,160,130,161, 67,154, 62,
-205,148, 72, 96,206,229, 10, 57, 0,160,213, 42,117, 78, 78,200, 39,136, 65,255,100,192, 91, 19,254, 59, 81,188,220, 59,253, 27,
-159,107,130, 9, 38,152, 96,194,255, 6, 50,139, 45, 85, 0, 50, 1, 16, 69,191,181, 69,159,153, 69,130,236,243,239,159, 28,255,
- 27, 33, 69, 57,150, 44, 86,121, 34, 43, 43, 75,104,195, 98,201, 60, 12, 6,245,119, 0,192, 98, 49,222,101,101, 89,197,208,244,
-233,172,234,136, 45, 27, 59,187,151,108, 38,211,201,152,115,245, 6,131, 36, 43, 61,253, 83,215,241, 4,241,255, 65,224, 25, 43,
- 34,190, 70,108,252,237, 66,197,198,198,198,222,222,222,190,143,185,185,121,155,220,220,220,103,153,153,153,231, 43,136,123,184,
-142, 32,176,176,176, 94, 97, 35,128,197, 21, 80, 87,229,220,207,225, 46, 20, 10,167, 18, 4,225, 93,244,128, 69, 42,149,202,221,
- 0,222,255, 15, 54, 72, 2, 0, 63,178, 88,172, 81, 54, 54, 54, 45,211,210,210, 86, 0,168,174, 55,111, 22,128,121,150,150,150,
- 67, 44, 45, 45,235,230,228,228,196,230,231,231,159, 2,176, 5, 64,165, 75,165, 87,204,116,108,211,222,191,253,210,187,215,239,
-174, 94,177, 67,250,248,139,227,243, 28,173,187,118,105,187,236,238,165,208, 85, 63,239, 74,205,169, 98,218, 24, 69, 27, 80,184,
- 58,146,198,151,206, 94,191, 22,108, 0,189, 1,180, 7,112, 23,192, 37, 99,238,187, 28,180, 6,240,115, 81,154,183, 0,184,243,
- 31, 94,143, 68,246,246,246, 27, 0,244,102,177, 88,111, 37, 18,201, 68, 0, 41,255,112,154, 88, 0, 90, 0,240, 70,161, 27,142,
-231, 48,206,133, 67,165,176,182,182,238,197, 98,177,166, 22,185,118,217,157,157,157, 29,252,159, 90, 48, 92, 46,119,155,131,131,
-195,120,149, 74,165, 36, 8,130, 46,237,239,145, 36,201,148,172,172, 44,159,255,111,141, 26, 65, 16,207,255,195,147, 56,177,140,
-125,229,251,209,146, 72, 96,206, 98,201, 60, 50,210, 34,134,164, 74, 95, 15, 6,128,154,142,141, 79,217, 57, 52, 58, 41,145,112,
-117, 14,158,253,196,108, 33,107, 55,147,201,110,170,214,106,108,216, 44,118,150,142,212,135, 49,180,244,212,180,232,243,101, 58,
- 91,100, 51,153, 78, 9, 49,119,236, 72, 93, 14,216,252,154, 96, 11,106,149,155,218,154, 53,107, 86,235, 46,173,172,234,154,233,
-120,252,217,108, 54,179, 11, 69,147,222, 52, 5, 48, 8,118, 36,105,208,135,112, 52,154,223,100,178,216,130,234,230,160,167, 53,
- 28,104, 96, 40, 8,116, 1,141,155, 4,112, 34, 58, 27,105, 85,160, 48, 86, 68,124,141,216, 40,125,237, 86, 0,243,191,117, 77,
-114,114,114,178,234,213,171,215,182, 95,127,253, 85, 32, 22,139,137,164,164, 36,255, 69,139, 22,253,240,226,197,139,185, 18,137,
- 36,245,115,209, 71, 16, 88, 72, 81, 52, 3, 0, 24, 12, 98,145,173,173,157,144,201,100,126,225,219,200, 96, 48, 8, 51, 51, 51,
-166, 83, 20, 77, 20,157,187,144,166,177,221, 24,193,200,231,243,135,121, 55,106, 58,119,195,166, 45, 98,123, 59, 59, 17,105,160,
-116,241,137, 9,194,165, 1,243, 91,125,252,240,126,187, 90,173, 62, 94,157,231,154,201,100, 14,225,241,120,189, 0,120, 21,237,
-139,210,104, 52,193, 6,131,225,164,177, 29,186,189,189,253,125, 38,147, 89,187, 42,127,108, 48, 24,146,210,211,211,125,171, 89,
- 68,131,106,213,170,117,192,207,207, 79,216,178,101, 75,112,185, 92, 44, 91,182,108,158, 84, 42,173, 76,104,177, 0,204, 19, 10,
-133, 67, 68, 34, 81, 93,185, 92,254, 81,165, 82,157,229,114,185,157,183,111,223,238,210,182,109, 91,179,244,244,116,130,201,100,
-218, 95,185,114,229,167,109,219,182,249,147, 36,217,169,178, 78, 46,239, 35,189,148,215,219,171, 93,222,199, 59, 75, 1,116,255,
-252, 56,169,230,143,162,153, 46,189, 84,244,171,228, 34,241, 97,180,200, 98,179,217,219, 29, 28, 28,198,168, 11,125, 5,208,159,
-119, 56, 0,160,213,106,101,185,185,185,158,213,121,228, 1,140,179,180,180, 28,179, 96,193, 2,171,238,221,187,227,232,209,163,
-211,246,237,219, 39,203,207,207, 63,136, 66, 71,152,209, 85,228, 92,152,150,150,214,131,205,102, 19, 46, 46, 46, 76,149, 74, 85,
- 21,161,229,129,194, 32,204,207, 1,236, 70,161,235,130, 14, 64,225,243, 14, 96, 99,177,112, 99, 48, 24,187, 61, 61, 61,251, 68,
- 69, 69,237, 1,176,186,186,207,186,131,131,195, 31,187,118,237, 26,220,183,111, 95,102,102,102,166, 83,147, 38, 77,142,165,165,
-165,181,251, 6,205,200, 88, 30,143, 55,167,113,227,198, 13,162,163,163, 99,242,243,243,183, 20,229,103, 69,207,148, 51,128,206,
-150,150,150,157,150, 44, 89, 34,238,213,171, 23,246,238,221,219, 99,223,190,125,242,130,130,130, 16, 20,206,233,249, 42, 17,200,
- 98,177,166,166,164,164,216,208, 52, 13, 71, 71,199,169, 0,254, 35,133, 22,131,193,216,222,191,127,255, 49,199,142, 29, 19, 38,
- 36, 36, 8,157,156,156, 74,156,103, 19, 4, 81,237,254,211,132,175,198,222, 82,130,171,114, 63, 90, 92,174,144, 99, 48,168,191,
- 75,149,190, 30,252,131,223, 78, 11, 0,184,127,111,198, 96, 59,135,134,145, 92,174, 48,134,103,206, 63,215,191,119,231,166, 3,
-123,249, 17,206,142,118, 72,145,102,216,255,121,226,122,183,224,235,119,206,161,208,129, 88,153, 32,117, 57, 16,232,110, 33,250,
-225, 14,216,180, 79,197,239, 87, 82,240, 56, 60, 30,202,188, 44,212,118, 16, 96,211,236,174,112,176, 18, 86,239,213,203,206,189,
- 3,201,226,157, 28, 62,108,164, 69,159, 31,189,216,174, 14, 14,160,105, 30, 98, 62,202,191,191,122,227, 78,139,179,167,143, 79,
- 21,177,221,135, 40, 50,222, 27,221,184, 53,115,132, 64,161,195,143, 44, 38,241, 83, 91,159, 6,157,134,245,104,199,104,224, 85,
- 31,111,223, 68,117,189,120,251,233, 38, 70,232,155, 16,210, 64, 7,137, 56,184,240, 74, 90,161, 67,191, 47, 4, 71,167, 78,157,
-219,241,120,188, 79,156, 39,105, 52, 26, 78, 72,200,173,214,213, 17, 27,197,255,161,213,106, 24,108, 54, 23, 12, 6, 49,215,219,
-187,145, 87, 86, 86,214, 29,130, 32, 14,164,166, 86,205, 90, 48, 3,224,202, 88,172,230, 12, 30,207,209,160,213, 90, 3, 0,193,
-229,202,226, 25,140, 70, 75,126,254, 89,204,100, 50,169,236,236,108, 40,149, 74, 98,194,132, 9,252,143, 31, 63,246,151, 72, 36,
- 59, 42,121, 35,193,190,125,251, 60, 28, 29, 29,191,136, 30, 43,149, 74,185,125,251,246,169, 78,209,123, 52,110,210,108,206,245,
-235,215,188,242,115,100,234,125, 91,255,120,169,231, 11, 53,117,188, 60,217,187,247, 30,182,152, 56,102,196,140,119,239,222,132,
-161,106,241,234,106, 9, 4,130,115,155, 55,111,246,238,208,161, 3,219,206,206, 14,233,233,233,136,138,138,242,190,125,251,246,
-143,135, 15, 31,158,167, 82,169,250, 3, 70, 5, 68,117, 15, 9, 58, 96, 39,170, 97, 13,131, 94,143,154,141,155,149,248, 55,251,
-112,251, 6, 72,157, 14,148, 94, 15,175, 94, 63, 22, 89,147,105,120,121,121, 85,215,235,110,205,134, 13, 27, 30, 89,187,118, 45,
- 71,163,209,224,233,211,167,184,115,231, 14, 37,149, 74, 43,115,136,203, 34, 8,226,198,242,229,203,157,125,125,125,205,178,178,
-178, 96, 48, 24,108, 46, 92,184, 48,181,105,211,166,230, 46, 46, 46,220,160,160, 32,200,229,114,144, 36, 89,163,110,221,186, 53,
-134, 13, 27,166, 13, 10, 10,154, 7, 96, 67,121,150,172,252,143,244, 82, 41, 81,183,155,103,243, 81, 72, 35,174,117,155,211, 13,
- 87,205,235, 17, 37,150,173,110,117,235,154,229, 75,132,139,196,230,141,106,228, 75,110, 45,234, 86,183,238,190,107,177, 70,189,
- 12, 49,138, 58,155,225, 39, 78,156, 16, 70, 69, 69, 9,189,188,188, 64, 81, 84,137, 7,254, 98,135,179,238,238,238,213,201,199,
-245,147, 39, 79, 94, 52,120,240, 96, 52,110,220,184,196, 41,234, 47,191,252,130, 69,139, 22, 89,221,191,127,127,222,241,227,199,
-231,157, 63,127,126, 3,128,128, 42, 90, 99,138, 81,213, 50, 94, 25, 23, 23, 55,232,220,185,115, 35, 22, 46, 92,232, 14, 96, 58,
-128,101,217,217,217,126, 69,214, 24,110,145,208, 26, 59,111,222,188, 41, 1, 1, 1,232,209,163,199,178,167, 79,159,174,169,166,
-149,143, 73,146,100,143,190,125,251, 50,245,122, 61, 68, 34, 17,244,122,125,189,175, 53, 74, 0,216, 53,105,210,164, 41,147, 39,
- 79,134,149,149, 21,244,122,189,199,137, 19, 39,246, 45, 91,182,172, 13,128,113,229,164,117,212,148, 41, 83, 6,140, 28, 57, 18,
- 62, 62, 62, 96,177, 10,179,113,243,230,205, 88,181,106,149,248,198,141, 27, 63, 6, 5, 5,253,120,241,226,197,179,248, 52,108,
- 87,149, 64, 81, 20, 88, 44, 22,146,147,147, 97,103,103,199,163, 40,234, 58, 65, 16,123,115,114,114,206,255, 7,117,230, 27, 7,
- 13, 26, 52,252,216,177, 99, 98, 0,216,180,105, 19,230,204,153, 3,123,123,123,136,197, 98,147,212,249,207,177,104, 77,172,212,
-162, 85, 25,148, 74,101,179,197, 51,127, 2,131, 81,248,214, 88,191, 78, 45,172,251,121, 34,113, 49,248,122,179, 10,109,240,252,
-154,136,126,184, 3, 60,151,217,208,232, 73, 60, 9,143,195,205, 77,254,133,189,101,247, 37,208,232, 58, 21,119, 54, 53,184, 2,
-193, 70,173,193,240, 8, 14, 14, 79,145,152,152, 89,153,200,178,117,176, 15, 14, 12,220, 32,240,174,231, 9, 29,169,135, 36, 67,
- 2,130,224,193,217,201, 12, 99, 71,117,103,251,249,213,180, 89,185,242,143,203,105, 20,250, 41,179,222, 87,234, 48,212,195, 6,
-135,154,121,187, 15, 30,214,211,151,215,200,187, 33, 56, 60, 65,201,177,230, 62, 62,104,238,227,195, 8,144, 23,116,121,246,252,
-101,151, 51, 55,158,104,148,250,196, 83, 49, 89, 24, 93, 73, 35, 83, 34, 56,102,205,154, 5,123,123,251, 79, 78, 72, 79, 79,199,
-237,219, 33,101, 94, 83,133,134,172,228, 63,214,172, 89, 99, 38,147,201,186,239,223,191,191, 35, 69, 81,107,210,210,210, 30, 26,
- 67, 50, 18,168,157,199,227,117, 26,179,101, 11,213,180, 79, 31,166,165,131, 3,131, 50, 24,136,212,216, 88,235,173, 59,118,180,
-207,249,240, 65,160,168, 81, 35, 71,166, 82, 41, 99, 98, 98,192,231,243, 9, 22,139,213,162, 12,170,116,154,198, 70, 6,131, 88,
- 68, 16, 4,120, 60,126,204,228,201,147, 95, 21, 29,171,125,233,210, 37, 97,239,222,189,149, 0, 18, 0,128,199,227, 59, 49,153,
- 12,143, 66, 79,236,216,104,140,192, 20,137, 68, 51, 87,175,221, 32,202,207,201, 85,233, 20, 10,189,173,185,152, 32,196,102,204,
-252,188,130, 2,137, 52, 83,179,100,197, 42,230,164,177, 35,103, 42, 20,138,169,198,138,172, 38, 77,154, 60, 59,119,238,156,157,
-181,181, 53,114,115,115,145,157,157,141,103,207,158,129,162, 40,244,239,223,159,247,125,171,150,205,126, 94,178,244,113,178, 68,
-210,198, 24,177, 37,170, 97,131, 77,190, 77, 11, 59,235,132,236,146,242,217, 59,168, 87,201, 57,171, 82,242,138,173,115, 95, 19,
- 66,170, 77,167, 78,157, 56, 0, 48,110,220,184,252,130,130,130,117, 0,142,161,114,143,254,243,150, 46, 93,234, 84,167, 78, 29,
-215, 99,199,142, 65, 46,151, 3,128, 93,157, 58,117,224,225,225, 97,184,123,247, 46, 60, 60, 60, 96,102,102,134,251,247,239,227,
-241,227,199,240,241,241, 49,227,112, 56,131,117, 58, 93,153, 66,171,189,127,251,165,188,222, 94,237, 60,155,143,130,216,220, 17,
-251,142,159, 68,244,203,195,237, 52,186,168,165, 28,195,189,145, 42,154, 55, 58, 51, 73, 28, 80,219,199,207,186,126,195, 62,112,
-109,254,202, 70,109,120, 16,183,180, 75,157,245, 44,190,250,240,138, 45,210,236,242, 68, 22,128, 77,253,251,247, 31,116,226,196,
- 9, 75, 0,136,136,136, 64,122,122, 58,108,109,109,193,231,243,193,102,179, 75,226,147, 86, 19,163,119,239,222, 93, 34,218, 72,
-146, 44,137, 2, 32, 20, 10,241,195, 15, 63,160,105,211,166, 56,127,254,252,232,114,132,150,111,171, 86,173,142,186,186,186,186,
-148,222,169, 80, 40, 48,116,232, 80, 0,128,159,159, 95, 39,129, 64, 64, 23, 11, 66,169, 84, 42,127,254,252,121, 23, 0, 79,203,
- 81,150, 42,137, 68,130, 5, 11, 22, 32, 62, 62,126, 90, 96, 96, 96, 34, 0, 62,151,203, 45,121, 63, 6,224,209,176, 97,195,237,
-115,230,204,193,199,143, 31,241,246,237,219,103,168,254, 80,170, 65, 36, 18,125,208,235,245, 62, 36, 73, 66,165, 82,161, 95,191,
-126,252,179,103,207,166, 51,153,204,119, 89, 89, 89, 35, 80, 56, 39,197, 88,240, 1,108,153, 60,121,242,148,133, 11, 23, 34, 36,
- 36, 4, 23, 47, 94,196,200,145, 35, 49,123,246,108,136,197,226, 49,179,103,207,126,140,194,128,230,159,163,211,238,221,187, 97,
- 48, 24,190,120, 54,248,124, 62,124,125,125,209,160, 65, 3, 92,188,120,177,211, 87, 8, 45, 87, 95, 95, 95, 46, 69, 81, 80, 40,
- 20,184,123,247,174, 88, 32, 16,136,157,157,157, 39, 0,248,143, 17, 90,174,174,174,147, 79,156, 56, 33, 46, 61,250,195,227,241,
- 80,170, 30,152,240,207, 91,180, 42,124,195, 42,129, 86,171,212,177, 88,140,119, 53, 29, 27,159,186,127,111, 70,201,208, 33,192,
-120,167,213, 42,117, 0, 96,160,104,228, 43, 73, 8,120, 12, 36,164, 21,224, 77,108, 86, 89, 84,159, 44,209,100, 11,106,129,215,
- 50, 1, 52, 77, 67,171, 51, 64,147,151,134,117,151,149,136, 74, 81, 67,171,144, 65,171, 43,156,134,101, 99, 99,195,186,126,253,
-234,156, 91,183,110, 79, 57,120,240, 32, 51,197,194,226,109, 1,208,172, 44, 78, 43,171,186,102, 20,151,123,106, 79,224, 50, 1,
-205,140, 69, 76,146, 2,245,157, 91,194,198,210, 5,105, 89, 10, 60,122,123, 5,239,222, 7,163,142,163, 43,102,207,236,198, 95,
-189,246,216, 73, 14,233, 86, 43, 55, 55, 62,191,188,116, 22,191, 69,253,113, 45, 6,100, 78, 44, 12,217, 31, 97, 40, 72,253,226,
- 4,177,109, 45, 52,239,224, 4, 91,151,122,188,209,179, 87,141, 2, 62, 17, 90,165, 57,211, 9,130,177,135,193, 32,166, 16, 4,
-129,198,141,155,164,108,217,178,165, 44, 87,224,186,198,141,155,164, 48,153, 12,231,194,134,157,177,155,166,169,244, 74,210,249,
-137,168,225,114,121, 11, 11,205,254,142,201,151, 47, 95,214, 13, 26, 52, 8,155, 55,111,230, 46, 90,180,104, 9,147,201, 28, 87,
-198,240,222, 39,156,253,128, 90,150,245,234,117, 93,243,232, 17,205,214,235,137,156,103,207,242,115,165, 82, 50,173,160,128,123,
-250,221,187, 30,227,231,207,231,186,184,184,224, 97,112,176,117,166, 66, 65,231,106, 52,170,220,220, 92,154, 36,201,103,229,112,
- 46,182,181,181, 19,238,219,183,207, 99,242,228,201,175,164, 82,233, 98, 0,112,116,116, 92, 7,160, 1,128,132, 82,251, 16, 24,
-120, 82, 50, 97,194,132,152,140,140,140,197, 21,165,179, 20, 26,218,217,218, 9,143,255, 17,244,186,134,153,128, 97,235, 92,147,
-193,182,180,100,145, 92, 1,135, 2, 84,117, 92,234,137, 0, 52, 44,231,218,207, 57, 9,129, 64,112,238,175,191,254,178, 99,179,
-217, 48, 24, 12,176,181,181, 69,124,124, 60,114,115,115, 81, 80, 80,128,184,119, 81,112,115,113,193,202,128, 69,142,211, 23, 5,
-156, 83, 42,149, 62,159,117,102, 95, 6, 64,214,235,190,176,236,149, 21,197,224,243, 97, 47, 35,203,189, 52,226,147,146,146, 32,
- 22,139,225,237,237, 45,126,244,232,209,131, 10, 68, 86,233, 32,192,131,219,182,109,107,118,236,216, 49,248,248,248,192,194,194,
- 2,119,239,222, 69, 68, 68, 4,116, 58, 29, 67, 46,151, 67, 44, 22, 99,253,250,245,168, 85,171, 22, 10, 10, 10,144,144,144, 96,
-205,102,179,109, 62,243,104, 95,194,121,247,250,221,213,121, 31,239, 44, 77, 35,174,117,219,119,252, 36, 38, 12, 27, 2, 7, 58,
-246,129, 69, 61, 98,117,215,222,109,127,161,153, 46,189, 68,102,141,173,220,189,123,131,195, 21, 99,250,194, 85,136,137,188,100,
-165, 44,120, 61,141, 48, 36,187,172,216,114,122, 86, 25,247, 78, 0, 96,184,184,184,140, 63,125,250,180, 89,137,233,133,201, 44,
-137,121, 88, 58, 8,124, 5, 1,223, 43,205, 79,130, 32, 16, 31, 31, 15, 59, 59, 59,136,197,226,146, 0,226, 81, 81, 81,120,242,
-228, 9,138,163, 81,148,195, 57,226,214,173, 91, 46, 34,145,232,147, 19,104,154, 70, 86, 86, 22, 72,146,132, 80, 40,132,193, 96,
-128, 78,167,131, 94,175,135, 90,173, 22, 55,104,208, 96,170, 94,175,127, 90, 22, 39, 69, 81,115, 7, 15, 30,220,246,233,211,167,
-117,119,236,216, 1,173, 86,187, 41, 45, 45, 13, 3, 6, 12, 0, 69, 81,232,212,169, 83,107,154,166,163,151, 44, 89, 2, 0,152,
- 51,103,142, 94,161, 80, 76,174,206,189, 23,161, 65,243,230,205,235,134,132,132,160, 93,187,118,208,104, 52,216,188,121,179,121,
- 96, 96,160,121, 80, 80,144,237,194,133, 11, 15,100,102,102,250, 87,194, 73, 0,216,228,224,224, 48,165,125,251,246,130,162, 24,
-166, 56,124,248, 48, 86,174, 92,121, 2,192,146,171, 87,175, 46,191,120,241,226,168,241,227,199, 99,229,202,149,179,115,115,115,
-247,151,199, 25, 23, 23, 7, 91, 91, 91,152,155,155, 23, 54,150, 58, 29,194,194,194,112,243,230, 77,124,247,221,119,198,220, 83,
-121,233,116,237,223,191,255,129,227,199,143,155, 37, 39, 39,227,254,253,251,112,115,115,131, 82,169, 52, 38, 54,236,173,191,161,
-195, 46,151, 83,165, 82,169,147,146,146,196, 27, 54,108,128,163,163, 35, 92, 93, 93,193,231,243, 65, 16, 4,244,122,125, 69,225,
-213, 42, 77,167,159, 31, 88, 89, 18,171,190, 22,150, 86,211,104,154,102,229,229,201,254,208, 33,247, 76,108, 44,180,255,198,123,
-255,111, 70, 51, 0,175,240,105,204, 67,105,137,208, 10, 14, 14,166,123,245,234, 69, 20,127, 58, 57, 33, 63, 43,203, 42,198,206,
-161,209, 73, 59,135,134, 69,113,191, 24,239,152, 76,171, 24,123,123,101, 62, 0,232, 72, 26,161,239,114,241,250, 67, 26, 34, 62,
-164, 65,196, 51,206,248,162,209,145,133, 51, 86,105, 26,106,249,191, 94, 90,117, 74, 25, 52,186,194,233, 30, 90,141, 18,121,153,
-111,137, 65,253,186,240,167, 76,153, 4, 71, 71, 39,219,242,248,116, 60,254,236,233,115,122, 88,214,176,100, 35,248,209, 53,180,
-254,174, 31,248, 60, 54,178,243,212, 0, 1,188,143,189, 9, 80,102,136,140, 73, 66,171,134, 66,248,119,245, 18,159, 63, 19, 61,
- 31,192, 50, 99,210, 75,166, 60, 3,199,189, 59,216, 6, 61,244, 89,209,160,114, 19, 1,145, 3, 84,132, 24,217,210, 68,188,123,
-112,214,168,119, 70,138,162,166,217,216,216,228, 46, 89,178,164,125,253,250,245,117, 83,167, 78, 13, 79, 76, 76,156,251,217,219,
-202,111,187,119,239,198,135, 15, 31, 36,107,214,172,185,155,149,149,181,180,138, 5, 29, 64,211,216, 86, 52, 20,151,117,225,194,
-133,230,247,238,221,155,189,109,219, 54,251, 25, 51,102,112,103,204,152, 49, 22,192,175, 21, 13, 23,230,243,120,157,215,220,191,
- 79,147, 41, 41,154, 35, 59,119,114,119,133,134, 46,209, 81, 84, 77, 27, 59, 59,226,251, 86,173, 20, 66, 6, 35, 43, 59, 61,157,
-180,173, 91,151, 25,127,243,166, 53, 45, 16,164, 94,189,122, 53, 95, 46,151,151, 27, 58,135,201,100, 42,203, 26, 46, 44, 11,142,
-142,142,218,178,230,112, 85,208, 33,230, 83, 52,173,179,172, 83,135,238,218,169, 77,253, 15,209,177,177,124, 75, 75,166,123,125,
- 55,207, 55,239,226,159,209, 6,131,154, 32,136,124,163,198, 74,152,204, 33,219,182,109,107,100,110,110, 14,138,162, 96, 97, 97,
-129,204,204, 76,104,181, 90,228,231,231, 67, 91,144, 7,109, 94, 30, 34, 18,227,209,182,125,123, 12,234,214,213, 43,232,194, 95,
- 67, 12, 6,195,137, 10,199,243, 26, 55, 43,177,100,173,170,109,253,175,177,160,228,220, 18,209,181,161,153, 59, 56, 98, 49,186,
-204, 13,248,154, 7,253,213,229,203,151,175,244,239,223,191,199,252,249,243, 25, 82,169,244, 90,124,124,124, 91, 0,111, 43,186,
- 72, 44, 22,215,203,202,202,130, 92, 46,135,133,133, 5,182,109,219, 6,123,123,123, 40,149, 74, 60,127,254,156,118,118,118, 38,
-238,222,189, 11,103,103,103,100,103,103, 67,167,211, 65,165, 82,165,105,181,218,114,135,203,139,134, 7,187,207,233,134,171,209,
- 47, 15,183,115, 34,226,158, 15,158,231,247, 33, 58,226, 93,210,141,155,143,126, 37,213,252,228,220,148, 91,139,234,180,120,101,
- 51,109,193, 74,252,190,105, 57,162,159,222,207,177,175,149,191, 75, 64,104, 14, 85,148, 94,133, 66,161,126,247,238,157, 89,120,
-120, 56, 8,130,128,133,133, 5,132, 66, 97,153, 98,171, 26, 96,148,182, 64, 41, 20, 10,112, 56, 28, 88, 91, 91, 99,255,254,253,
- 37, 29,175,155,155, 91, 69, 28,127,116,233,210,101, 72,173, 90,181,204, 74,239,108,209,162, 5, 38, 77,154,132, 61,123,246, 32,
- 52, 52,244,147,120,154,105,105,105, 82,189, 94, 95,209,125,231,166,167,167,119,235,215,175,223,203, 7, 15, 30,152,239,223,191,
- 31, 36, 73,150,185,237,219,183, 15, 79,158, 60, 89, 6,224, 93, 53,235,209,119, 3, 6, 12,184,127,244,232, 81,203,204,204, 76,
- 20,215, 13,133, 66, 1,131,193, 0, 79, 79, 79,130, 36,201,202,230,189, 49,152, 76,230,133,157, 59,119,246,158, 48, 97, 2, 88,
- 44, 22,180, 90, 45,118,238,220,137, 69,139, 22,165, 23,189,148,234, 0, 44, 57,116,232,208,168, 62,125,250,160, 73,147, 38, 94,
-119,238,148, 63,179, 67, 46,151, 67, 46,151,131,205,102,195,193,193, 1,171, 87,175,134, 86, 91,216,172,120,120,120,148, 60,198,
- 0,254,240,240,240,232, 29, 19, 19,179, 25,133,115,215,190,128,131,131, 67, 63,154,166, 39, 26, 12,134,130,118,237,218, 89, 31,
- 63,126,220, 76, 34,145,224,229,203,151, 88,182,108,153,140,162, 40, 3, 69, 81,132, 74,165,138,179,179,179,123,201,227,241, 4,
- 74,165, 50, 39, 59, 59,123, 45,128,107,255, 84, 79, 78, 16, 4,193,102,179, 49,110,220, 56,176, 88, 44, 8, 4, 2,168,213,106,
-232,245,250, 18, 49,143, 42, 14, 75,215,175, 47,182,102,129, 51,193,202,172,193,236, 65,179,122,217, 58,214,116,130,165, 57, 15,
- 81, 81,111,219,222, 14,185,185,147,203,138, 14,164,180,250,192,232,132,188,191, 61,216,253,231, 90,228,191, 84,104,125, 17,243,
-144, 85,118, 97, 14, 50,208,244,233, 44,137,132,171,227,114,133, 49,197, 86, 46,123,123,101, 62, 65, 12, 50,216, 54,236, 11, 82,
-167, 47,106, 40,232,162,205, 72,161,165, 55,224, 67,116, 36, 30,220,248, 11, 54, 74, 9,178,226,154, 2,156, 70,208,170,242,160,
-214,234,138, 68,137, 1,225, 47, 67,144,159,151, 3,111,159, 94, 0,131,241,164, 60, 62, 11,107,162,215,247,205, 27, 51, 63, 36,
- 69,162,133,199, 64,212,117,110,135, 68,105, 62,114,229, 26,200,242,213,104,234, 29,128, 76,153, 10,249, 74, 53,222,126, 8,130,
- 83,205,186, 12,130, 21,219,201, 88,161,165,121,123, 14,154,119, 23,193,113,109, 11,174,103, 31, 48, 93,125,145,244,250, 14,194,
-175,110, 69,202,155,135,160, 41, 3, 28, 61, 90, 26,251,144,236,188,118,237, 90,203,182,109,219,178, 58,119,238,220,228,202,149,
- 43, 77,164, 82,105,120,145,192,104,210,185,115,231, 38,182,182,182,216,190,125,187,138, 32,136,157,213, 44,236, 18, 11, 88, 70,
- 70,198, 51, 0,107,206,157, 59,183,115,210,164, 73,176,179,179,107,148,154,154, 90,238,133,153,108,118,147,209,107,215,210,108,
- 38,147, 62,241,251,239,156,149,215,174,109, 57,120,232, 16,167, 99,135, 14, 4, 77,211, 8, 11, 11, 19,110,248,253,119,225,240,
-190,125, 19, 18, 51, 50,200,123,161,161, 58,105, 74, 74, 65,134, 66,177, 82, 42,149,166,253, 19, 53, 91,175,215, 63,142,139,143,
-115,242,105,213,212,246, 85, 84,220, 27,255,142,223,127,207, 96, 48, 24,209,177,137,161,182,182,230,194,155, 55,110,234,244,122,
-253, 99, 99,184,120, 60, 94,175,142, 29, 59,178,100, 50, 25,106,214,172,137,204,204, 76, 72, 36,146, 66,139, 67,158, 12,186,188,
- 60,232,243,115, 97, 80,200, 17,247,252, 25,154,214,173,195, 59,205,227,245, 82, 42,149, 21, 10,173,226,183,204,178, 2, 93, 23,
-239,227,154,153,129, 43, 22,131,168,250,176, 97, 95, 75, 75,203, 69,185,185,185, 87, 0,172,214,233,116,211, 23, 45, 90,212, 98,
-199,142, 29, 54,107,214,172, 49,159, 56,113,226,105,185, 92,222, 20,133, 65, 85,203,235,192, 62,146, 36,105, 13,192, 62, 36, 36,
- 4,118,118,118,200,203,203, 43,182,180,104,149, 74, 37, 63, 59, 59, 27, 26,141, 6, 90,173, 22,230,230,230,120,241,226, 69, 14,
- 73,146,151, 42, 75,156,121, 61, 98,181, 70, 23,181,212,218, 75,148,170, 35,173,252, 50,114, 40,217,138, 45,210, 85, 0,182,116,
-171, 91,119,159,142,186, 31,247, 62,242,146, 85,252,243,187, 57,169,239, 21,117,247, 95,137,171,104,142, 22, 13,128, 34, 8,130,
-246,240,240, 64,102,102, 38,152, 76, 38,132, 66, 33,196, 98, 49, 22, 47, 94,140,157, 59,119, 86, 71,104,241, 69, 34,209, 90, 6,
-131, 49,132,193, 96,216, 26, 12, 6, 4, 4, 4,160,119,239,222,224,114,185,208,233,116, 37, 22,205, 98, 43, 85, 37,150,142,176,
- 39, 79,158,152, 63,121,242, 73,179,213,193,198,198,230,182, 70,163, 65,108,108, 44, 46, 92,184,208, 30,192,189, 42,150,117,108,
- 88, 88, 88, 55, 95, 95,223,195,205,155, 55,175, 71,211, 52, 26, 53,106,132,161, 67,135, 34, 40, 40, 8,225,225,225,200,203,203,
-163,110,222,188,121, 16,192,230,170,246,225, 69,249,235, 57, 96,192,128,135,199,142, 29,179,202,206,206,134, 74,165,130, 66,161,
-192,233,211,167,209,182,109, 91,216,216,216,224,232,209,163, 36, 77,211, 21,149, 61,131,193, 96,236, 15, 12, 12,236, 61,126,252,
-120,236,218,181, 11, 39, 78,156, 64,159, 62,125, 48,100,200, 16,100,102,102,218,111,218,180,105, 84,209, 48,225,242,161, 67,135,
- 66, 46,151,227,249,243,231, 81, 70, 62,243,200,205,205, 69,110,110, 46, 4, 2, 65,233,103,140, 0, 16,180,117,235,214, 97,179,
-103,207, 70,221,186,117,151,199,197,197,109, 69, 25,171, 68, 41,138,154, 44,145, 72,172, 88, 44,150, 53, 73,146, 72, 78, 78,198,
-139, 23, 47, 48,109,218,180,156,156,156,156, 73, 0, 18, 1, 44, 25, 55,110,220,234,185,115,231,150,212,165,185,115,231, 6, 95,
-185,114,165,219,191,219, 24, 35, 46,110, 0, 0, 32, 0, 73, 68, 65, 84,154,227,225, 97,217,144,203,228,205,146, 21, 48,173,101,
- 50, 89, 73,219,161,213,106,161,209,104, 62,177,100,113, 56,108,235, 22, 77,107, 93, 86, 41, 11,126,126,251, 62,183,220, 0,233,
- 94,245, 44, 26, 11, 69, 22,179,219,182,235, 56,162,107,183, 31,153,164, 94,143,235,215, 47,225,207, 63,119,163,131,175, 7,234,
-214,111,132, 25, 51,103, 89,104,180,100,192,205,155,215, 22, 89, 62,121,112,173, 32, 63,119,113, 69,156,255,227,184, 92, 36,174,
- 46,151, 57,116, 88,150,130, 44,114,225, 32, 43,250,105, 99,101,101,245,187,193, 96,232, 96,110,110, 14, 42, 55, 6,111, 95, 60,
- 69,142,140, 13,141,202, 0,138, 46, 20, 91, 70, 9, 23,141, 22,247,175, 95,196,182,173, 91,144,157,157, 13,223, 31,218, 67,206,
-114, 65, 45,151, 90, 80,171,148, 69, 15, 13,160,211,234, 97,107,239,138, 87,175,194,245,249, 10, 69,185, 13, 18,135,175,243,170,
-101,239, 1,141,174, 13,248, 92, 46,242, 10,180,144, 21,137,172,163,103, 6, 67,163, 84,129,212,234, 64,106,245,176,173, 53, 0,
-223,217,119, 4,101,184,212,176, 74,217, 71, 25,160,139,191, 15, 93,252,125, 8,218,204,196, 95,235,134,125,214,145, 26, 23,119,
- 55, 51, 51, 51,227,205,155, 55,151,194,194,194,250, 13, 30, 60, 24,119,238,220,153, 8, 96, 74,209,240,205,196,193,131, 7, 35,
- 44, 44, 12,111,222,188,185,148,153,153,153,241, 45, 74,158,203,229,170, 52,154,194, 62, 86, 40, 20,242, 43, 57,215,169, 69,255,
-254,140,188, 87,175,242,183, 62,122,180,124,223,254,253,156,206,157, 58, 17,122,146, 4,101, 48,160,190,187, 59,209,181,107, 87,
- 81,208,169, 83,214, 76,189,254,201,130,233,211, 67,246,140, 28, 89,240, 76,161, 48,118,162,121,237,162, 33, 67, 0,168, 93,193,
- 62,163,161,209,104,118, 76,158, 48,166,243,189,251, 15, 93,106,185, 56,153, 95,191,121, 47,156, 39,224, 50,234,186,213, 99,202,
-242,114, 88,171,150,255, 44,208,104, 52,198,138, 86, 47, 27, 27, 27,164,165,165,225,195,135, 15,208,104, 52,208,235,245,160,148,
- 10,104,101,185,208,230,229,128, 80,171,192, 51, 24,160,206, 74, 71,237,186,117,128,127,173, 72,172,116, 40,170, 44,161, 85,252,
-201, 55, 55, 7, 71, 36, 6,131,205, 54, 58, 56, 58,128,230, 45, 91,182, 60,117,246,236, 89,206,216,177, 99, 91,221,186,117,235,
-119, 0,137, 18,137,164,211,178,101,203,158,253,254,251,239,188, 73,147, 38,121,110,222,188,121, 20,128, 63,202, 35, 81,171,213,
-167, 46, 95,190, 60,220,213,213,213, 62, 34, 34, 2,106,181, 26, 20, 69,161,123,247,238, 64,225,220, 26, 0, 64,116,116,180, 74,
-173, 86,103, 68, 70, 70,230, 39, 38, 38,234, 96,196, 42,193, 21, 59,164,143,243,211,238,247,183,119,112,122,194, 23,212,118,163,
-229,175,250,205, 25,232,180,105,235, 25,137,250, 90,108,108,193,210, 46,117,214, 43, 10, 94, 79,179,116,150,239,186, 22, 28,103,
-204, 68,248,146,213,133,214,214,214, 96,177, 88, 96,179,217,224,112, 56, 32, 8, 2, 51,103,206,196,222,189,123, 43, 27, 58,252,
- 68,100,153,153,153,189, 89,185,114,165,243,164, 73,147, 56,124, 62, 31, 50,153, 12, 71,143, 30,197,184,113,227,240,231,159,127,
-150, 57,255,197,136, 33,165,207,173,165,179, 71,142, 28, 9,173, 86,139,161, 67,135, 98,223,190,125,179, 13, 6,195,189,106, 60,
-210, 79,194,195,195,221,195,195,195,205, 1,244, 25, 50,100,200,161, 1, 3, 6,224,222,189,123,184,116,233, 82,123, 20, 46,250,
- 80, 1, 88, 7,192,174,232,179,162,231, 83,100,111,111,191,155,162,168, 62,182,182,182,225, 30, 30, 30,222,199,142, 29,179,204,
-200,200, 40, 94,252,128,248,248,120, 28, 56,112, 64,186,127,255,254,124,131,193, 96,205, 96, 48, 46,231,230,230, 46,174, 64,176,
-237,223,186,117,235,152,162,225, 64,156, 61,123,150,222,178,101, 11,177,108,217, 50,200,100, 50,116,232,208, 1,129,129,129,179,
-228,114,121,147, 45, 91,182, 76, 24, 52,104, 16, 86,173, 90, 5,133, 66,177,181,178,151,149, 10,196, 23, 1,224,251,173, 91,183,
-186,206,158, 61, 27,103,207,158, 69,243,230,205, 5,113,113,113,123, 0,140, 47,171,252,104,154, 70, 92, 92, 28,148, 74, 37, 30,
- 62,124,136,229,203,151,203, 74,137,172, 89, 83,166, 76, 89, 61,107,214, 44,172, 93,187,150,142,136,136,200, 24, 48, 96,128,253,
-222,189,123,153,245,235,215,159,165, 84, 42,255,109, 66,203,179,126,141,245, 45,154,183, 91,228,232, 84, 31, 71,143, 29, 71, 78,
- 78, 78, 73,158, 20,231, 11, 77,211, 40, 40, 40, 64, 90, 90, 26, 44,204,205,176,105,243,234, 30, 83, 39,142,113, 65,161, 27,140,
- 47, 77,150,117,173, 54, 15, 24, 50,118,222,208,225, 99, 16, 17,254, 18, 65,135,254, 64,100, 68, 88, 9, 31,169,215, 33, 38,234,
- 5, 98,162, 94,192,222,193, 21, 93, 59,183, 39,134, 13, 27,214,125,228,240, 33,182, 0,254, 54,215, 17,255,197,214, 44,224, 75,
- 63, 90,123, 63, 17, 90,149,152,235,108,172,172,172,222,156, 60,121,210,218,215,215,151, 73,146, 36,174, 93,191,142,105, 83,126,
-194,168,145, 1,208,193, 10,164,150, 3,138,195, 55, 42, 37, 42,149, 18, 52,104, 40, 20, 10,132,134,134,130,166, 72, 4,237,221,
- 2,154,166, 74,132, 22, 64, 67,171,211,193,169,150, 39,118,239, 91, 67,130,205,126, 6,125,217,174,107,242,179,153, 6, 61, 73,
- 67,146,145,132, 36,105, 36, 44,204,106,129,197,174,133,236, 92, 37, 88, 12, 7,232,213,209, 48, 20, 93,171, 84,164, 64,165,251,
-186,242, 51,148, 97, 61,165,171,208,232,170, 84,170, 35, 71,142, 28,233,241,219,111,191,113,123,246,236,233,113,230,204,153,239,
- 1,160,103,207,158, 30,230,230,230, 56,114,228,136, 86,165, 82, 29,249,134, 22,159,142, 45, 91,182,132, 76, 38, 67,124,124,124,
-120,133,247,166,213, 90,139,237,236,152, 25,119,238,232, 51,101, 50,151,142, 29, 59, 18,122,146, 4,131, 32,144,147,151,135,196,
-132, 4, 88, 90, 90, 18,111,162,163,197, 59,103,204, 56,239,225,237,205, 42, 94,145,104, 12, 46, 93,186, 36, 68,225,188,172, 10,
-247, 85, 17,138,140,244,180, 49,211,167, 79, 63,127,228,200, 81,139,244,140,244, 24, 30,151, 75,138,197,252,154, 35, 71, 76,101,
-229,230,230, 14, 7, 32, 55,150, 76, 38,147, 33, 46, 46, 14, 2,129, 0, 28, 54, 27,148, 74, 9,131, 66, 14,117, 78, 38,152, 58,
- 45,184, 6, 3,106, 8,121,112,177,183, 71, 45, 91, 27,163, 56, 63,220,190, 81, 50,241,189,244,112,225,166,150, 94,224,138,196,
-224,154,137, 49, 53,248,110,209,219, 40, 7, 88,246,171, 49,180, 54, 78, 78, 78,127, 29, 59,118,140,147,153,153,137,176,176,176,
-112, 0,121, 0,204, 0, 80, 81, 81, 81,183, 34, 35, 35,123, 21,173,186,171,108,181,216,150,115,231,206,117,241,245,245, 37,221,
-220,220, 68, 25, 25, 25, 46, 50,153,140,146, 74,165,159,152,132,110,220,184,193, 43, 40, 40, 80, 80, 20,117,190, 72,100, 85,234,
-191,104,206, 64, 39,126,232, 43,204,244,243,175,221,200,220,166, 49,114,200, 87,141,158,132, 75,103,206, 25,232,180, 99,235, 25,
-137, 90, 64,104, 14, 17,134,100, 23, 22, 95,109,236, 36,102, 26, 40,156, 43, 21, 26, 26,138,196,196, 68,196,197,197,125, 34,168,
- 38, 78,156,136,160,160, 32,163, 44, 90, 34,145,104,237,138, 21, 43,156,103,207,158,205, 41, 37,138, 48,125,250,116,228,229,229,
- 97,223,190,125,152, 62,125,122,149, 59,254,207, 80,167, 99,199,142, 61, 29, 29, 29,145,157,157, 13, 7, 7, 7,248,250,250,246,
-190,119,239,158, 27,128,248,106,214,251,169,254,254,254,171, 87,174, 92, 9,189, 94,143,113,227,198,225,253,251,247,167,222,191,
-127,191,173, 86,173, 90, 51, 23, 46, 92,104,111,111,111,143,193,131, 7,139, 72,146,236, 95, 30, 73,141, 26, 53,214,253,241,199,
- 31,195,123,246,236,201,208,233,116, 63,220,190,125, 27, 9, 9, 9,208,106,181, 32, 73, 18, 31, 63,126,196,244,233,211,165, 69,
-171, 27, 63, 26,145,174,177, 75,150, 44, 25, 51,115,230, 76,108,216,176, 1, 43, 86,172, 56,104, 97, 97,225,221,180,105,211,102,
- 43, 86,172,192,130, 5, 11,224,234,234, 10,107,107,235,239,150, 45, 91,230, 53,119,238, 92,236,216,177, 3,203,151, 47, 63, 8,
-224, 64,117, 50,130,162, 40, 98,253,250,245, 77,182,110,221,234, 88, 44,178, 24, 12, 6, 78,158, 60,137, 87,175, 94,245,142,141,
-141, 45,235,154, 64, 7, 7,135,137,142,142,142,220,155, 55,111,138, 93, 93, 93, 65,146,164,190, 72,100,237,172, 85,171,214,180,
-143, 31, 63,162,103,207,158,136,141,141, 61, 2, 96,148,133,133,133, 98,238,220,185, 66,129, 64, 96,161, 84, 42,255, 93,157, 55,
-152, 12, 98,244,218, 85, 11,240,252, 85, 52,206,157,227,224,249,243,231,176,183,183, 7,143,199, 3, 77,211,208,104, 52,200,204,
-204,132, 94,167, 65,163,134,117,112,120,255,122,100,100,100, 2, 12,162,220, 41, 55, 4,131, 24, 49,230,167,126,120,240,240, 58,
-246,236,249, 3,114,185,162,156,151,111, 62,234,123,120,193,169,166, 29,146, 83,146, 65, 48, 96,243,119,222,235,127,249,208, 97,
- 73, 19, 4, 99,220, 59,148,134,165,165,229,182, 19, 39, 78, 88,119,232,208,129,169, 80, 40, 64, 81, 20,218,249,250, 98,230,236,
-217,184,116,236, 24,220, 91, 13, 5,161, 21,131, 20, 26,183,234, 65,173, 82,162, 65,179,239, 49,104,240, 16, 36, 37, 38,194,191,
-215, 0,168,213,202,146, 55,140, 98,139,150, 86,171,131,141,157, 11,110,220,184,193,196,184,113,111,177,179,108,163,132, 65,199,
-125, 29,243, 81,221, 54, 87,245, 10,161,207,131,160,211,232,208,168,209, 50,232, 40,107,216, 57, 79,132, 94,127, 1,249,153,183,
- 11,135, 49,172, 59, 32, 37, 41, 9, 12, 38,231, 77,117,115,144, 82,100,126, 85,163,155,151,151,151, 23, 23, 23,119, 38, 52, 52,
-116, 68,255,254,253,113,227,198,141, 9, 0,208,191,127,127,132,134,134, 34, 46, 46,238, 76, 94, 94, 94,222,183, 40,109, 71, 71,
-199, 62,237,219,183, 31,218,162, 69, 11, 4, 7, 7,131,166,233, 7, 70, 61,216,108, 54,205, 96, 48, 64, 81, 20, 8, 0,217,185,
-185,120,255,254, 61,178,179,178,160,215,235,161,144,203, 41, 47, 15, 15, 57, 77, 81,102, 85, 73, 79,233, 21,134, 40, 99,213, 97,
-241,190,106,220,106,226,179, 39,143,146, 10,228,114, 91, 43, 75,171, 2, 46,151,107,144,229,230,230,189,125, 19,161, 53,178,115,
- 40, 70, 84,100,100,164,119,106,106, 42,146,146,146, 64, 42, 10,192,212,104,193,208, 40,209,233,251, 54, 16,128, 6, 31, 20,216,
-148, 30,108, 38, 27, 5,133,171,243, 42, 29,238, 48,148,122, 73, 40, 22, 89, 4, 65, 20, 14, 23,138, 68,224,138,205, 62,177,112,
- 25, 83,159,120, 60,222,177,211,167, 79, 59, 58, 57, 57, 97,213,170, 85,112,118,118,254,174,102,205,154, 74, 11, 11, 11,129,189,
-189, 61, 26, 52,104,128,239,191,255, 30, 87,175, 94,133, 17,121, 64,210, 52,221,245,193,131, 7,243, 30, 61,122, 52, 72, 36, 18,
- 17, 51,102,204, 96,117,239,222, 29, 60, 30, 15, 74,165, 18, 50,153, 12,199,143, 31,207,162, 40,170,120, 81,138,181, 80, 40, 60,
- 64, 16, 68,188, 66,161,152,253, 57,225,225,223, 26,213,204,200,161,198,209,114, 97, 63, 63,255,218,141, 58,250,119, 70, 29,247,
-142,232,232,159, 4, 0,235,107,176, 18,134,110, 92, 98,121,222,210,140, 56,112,227,218,205,229,190,126, 29,151, 44,146,223, 89,
-189, 97,111,110,165,243,233, 8,130, 0, 69, 81,159,248, 14,250,252,248,168, 81,163,112,242,228,201, 74,243,145,193, 96, 12,153,
- 52,105, 18,231, 51,203, 51, 36, 18, 9,122,245,234,133,254,253,251,127, 34,180,108,108,108,224,224,224,128,132,132, 4, 0,200,
- 54,178, 94,205, 28, 59,118, 44,161, 82,169, 48,126,252,120,236,219,183, 15, 67,135, 14, 37,238,221,187, 55, 19,192,236,170, 86,
-118, 6,131,177,105,225,194,133,243,166, 79,159,142,156,156, 28, 92,185,114, 5,221,187,119,199,201,147, 39,109,175, 92,185,178,
-182, 67,135, 14, 96, 50,153, 8, 14, 14, 6, 73,146, 21,250,250,226,112, 56,125,122,246,236,201, 72, 78, 78, 6,135,195,129,143,
-143, 15, 82, 82, 82,160, 84, 42, 33,145, 72, 48,107,214,172,180,236,236,236,246,198, 62, 71, 28, 14,103,246,204,153, 51,113,226,
-196, 9, 4, 4, 4, 28, 2, 48, 62, 47, 47,111,208,163, 71,143, 78,244,237,219, 23, 18,137, 4,231,207,159,199,242,229,203,137,
- 81,163, 70, 97,215,174, 93,152, 53,107,214,193, 34,171, 83,121, 21,191, 32, 35, 35,195,162, 94,189,122, 72, 79, 79,135, 92, 46,
-199,249,243,231,237,174, 94,189,234,230,228,228,100, 30, 23, 23,103,248,245,215, 95,185,179,103,207,198,182,109,219, 16, 22, 22,
-134,160,160, 32,116,236,216,145,140,141,141, 45,211, 74, 86,228,178,225, 60, 77,211, 55, 69, 34, 17, 10, 10, 10,138,159,187,249,
- 1, 1, 1,211,215,173, 43, 52,178,167,166,166, 98,244,232,209, 35, 67, 66, 66,168, 14, 29, 58, 8, 57, 28, 14,212,106,181,226,
-223,217,107, 83, 6, 10, 0, 5, 55, 23, 49,174, 95,218,143,151,225,177,120, 25, 30, 9, 46,175,112, 18,188, 74,165, 68,179, 70,
-245,209,202,167, 37, 82,165, 18, 28, 9,218,143, 26, 54, 78, 21,182, 35, 52, 77,131,195, 50,192,203,195, 1,199,130,254, 64,240,
-149, 16, 4, 29, 57, 94, 50,231,141,197, 98,163,105,179, 86,240,241,241, 69,108,220, 71,236,223,191, 7,182,118, 46,166,193,193,
-106,162,100,232,176,244,231,103,202,191,163,175,175, 47, 83, 46,151, 67,173, 86, 35, 45, 45, 13, 9, 9, 9,176,180,178, 68,108,
-106, 60,218, 11,117, 72,163,242, 17, 21,254,198, 64, 48,217, 97,149,253, 97, 79,191,166,128, 95, 83, 76, 27, 59,180,130, 87, 86,
- 26, 34,115,155,194,161, 27,146,252,128, 29, 59,200,242,132, 22,105,208,223,186,126,243,118,203,177,163,250,176,111,220,222, 7,
-189,150,130, 74,111, 1,133, 90, 11,133,142, 13,134, 69,119, 32,235, 30,152, 44, 30, 90, 55,169,143,243,231,174,234,104, 82, 31,
- 98,116, 6,217,123,131, 76,143, 44, 37,180, 50, 62, 27,119,168, 97,244,208, 97, 73,199,107, 48,156, 60,122,244,232,143,109,218,
-180, 17,118,232,208,161, 94, 81,199,169, 59,122,244,168,178,200, 25,102, 85,241,137, 55,120, 7, 7,135,102, 28, 14,103,104,247,
-238,221,155,141, 25, 51, 6,111,223,190,197,145, 35, 71, 98,234,215,175,127, 71, 42, 45,127, 69, 54,147,203,205,150,103,100, 88,
-138,221,220, 88, 86,102,102,169, 87,175, 92,113,237,220,165, 11,145,148,148,132,236,236,108,168,213,106,132,133,135,211,108, 38,
- 51,133, 48, 55,103, 68,191,122,197, 96,114,185,217,229, 89, 27,203, 64, 66, 37,171, 14,215, 85,215,186,229,226,104, 85,111,121,
-192,228, 58,106,141,218, 59, 63, 63,159,100,177,217,108,103, 7,203,196,232,143,198,183,137, 26,141, 38,248,214,173, 91, 63,118,
-238,220,153, 23,243, 58, 12,100, 94, 30,180,121, 50,112, 40, 3,106, 52,107, 2,166, 78, 3,104,245,112,242,162,161,206, 21,226,
-222,211,104,189, 70,163,169,212,169, 97,177,208, 98,124, 38, 12,184, 98, 49,120,102,230,224,137,197,159, 11,134,202,222,228,132,
- 93,187,118,237,212,186,117,107,208, 52,141,189,123,247, 66,167,211,113,117, 58, 29,180, 90, 45,116, 58, 29,242,243,243, 17, 20,
- 20,132,221,187,119, 63, 2,112,208,136,219, 39, 5, 2, 65, 95,130, 32,236, 88, 44,150,210,214,214, 86,116,242,228,201, 18,119,
- 19, 77,155, 54,133,153,153, 25, 7, 69, 78, 33,237,236,236,216,127,254,249,167,101,239,222,189,239,151, 57,220,209,232,187, 5,
-117, 72, 43, 63,190,160,182,155,185, 77, 99,212,113,239, 8, 0,232,210,107, 44,234,212,175,133,252,172,215,110,106, 85, 66, 63,
- 14, 75,102,245,102,135,228,173,160,167,247, 24, 69,198,221,247, 40,123,121,127,153, 29, 5,131,193, 40,119, 56,214, 24,145, 85,
-168, 89, 24,182,197,243,124, 0, 32, 59, 59, 27, 82,169, 20, 81, 81, 81,240,244,244, 68, 78, 78, 14,156,156,156,160,213,106,209,
-162, 69, 11,168, 84, 42,108,221,186, 21, 15, 31, 62,124, 4, 96,150, 17,255, 33,112,119,119, 31,221,172, 89, 51, 92,185,114, 5,
-207,159, 63,151, 92,191,126,221,201,215,215, 23,110,110,110, 99,226,227,227,127, 46, 26,234, 51, 22, 34, 95, 95,223, 25,211,167,
- 79, 71,100,100, 36, 38, 79,158,156,157,156,156,124,254,212,169, 83,227,151, 47, 95,206,240,247,247,135, 84, 42,197,166, 77,155,
- 12, 15, 31, 62,220, 12, 96, 85, 37,249,248, 46, 57, 57,217, 89,173, 86, 35, 39, 39, 7, 36, 73, 66,169, 84,226,234,213,171, 8,
- 10, 10, 74, 47, 18, 89, 31,140, 77, 92,147, 38, 77, 26, 48, 24, 12,156, 56,113, 2, 0,150,162,208, 99,255,249,126,253,250, 73,
-126,253,245, 87,167,197,139, 23, 99,194,132, 9,208,233,116,216,176, 97, 3, 22, 47, 94,124,185, 72,100, 85,212,136,254,230,224,
-224, 48,113,242,228,201,223,205,157, 59, 23,161,161,161,118, 47, 94,188,240, 9, 11, 11,131,139,139, 11,178,179,179, 89,214,214,
-214,216,182,109, 27,230,204,153,115, 22, 64,214,227,199,143,135,196,197,197,173, 3,176,169, 18,209, 30,232,228,228, 52,145,166,
-105, 90,169, 84, 38, 4, 4, 4,108, 90,179,102, 13,230,204,153,131, 55,111,222, 32, 47, 47, 15,102,102,102,196,194,133, 11, 71,
- 47, 93,186, 20,227,198,141,163, 21, 10,197,238,127,119, 71, 77,211, 6, 40,101,145, 48,104,172,208,180,145, 39,154,122,215,198,
-245,219, 47, 1, 0,157, 6,248, 66,169, 40,192,161, 67,123,241,225,195,123,176,216,108, 88,214,112, 48,198, 18, 8,109,254, 59,
-228,234,164,232,220,193, 7,221,253,219,227,224,225,147, 32,245, 58,140, 31, 59, 28,178,220, 92, 28, 62,188, 31,177,113, 31,193,
- 98,179, 97,109,243,247, 59, 66,173, 72,139,252,215, 11, 45, 35,134,159, 64, 81, 20, 36, 18, 9, 94,188,120,129,248,248,120, 8,
-133, 66,168, 72, 3,181,231,214, 67,138, 32, 56, 41, 20, 77, 63,162,201, 18, 47,197, 95,114, 24, 12,146, 82, 30,107, 45,172,172,
-172,184, 26,141, 10, 36,169, 47,213,171, 16, 0, 1,112, 88,128, 99,205, 58, 72, 78, 74,166,213,106,245,221, 10,223,160, 52,234,
-109, 23,207,159,158,254,125, 91, 95,155,238,157, 86,226,252,133,101,144,229,231, 67,173, 99, 67,161,214, 65,169, 6, 44,107,120,
-160, 69,163,198, 72, 77,205,198,235,231,247,228, 44,141,210,152,137,162,239,119, 46, 25,235, 62,118,218, 2, 8, 92,219, 66, 19,
-117, 30,148, 60,189,196,162,197, 23, 91,161, 70, 45, 47,228, 42, 52, 56, 29,242, 18,168, 66,168,151,140,140, 12, 37,147,201, 60,
- 58,125,250,244, 13, 47, 95,190,112, 6,128,151, 47, 95,166, 72,165,210, 69, 25, 25, 25, 85,181, 73, 23,123,131, 39,248,124,193,
-203,250,245,235,167,250,248,248, 88,244,235,215, 15, 54, 54, 54, 8, 11, 11,195,186,117,235,222,233,116,186, 5,247,238,221,171,
-112,168, 71,171,213, 74, 94, 94,184, 96,222,254,167,159, 44, 23,244,238,189,105,250,244,233,219, 86,173, 90,197,118,119,119, 39,
-244, 58, 29, 34, 34, 34,232, 99, 71,143,234,119, 47, 94,188,149, 43, 18,177,158, 93,188,200, 38, 53, 26,201, 63, 93,137,157,156,
-156,252,124,127,104,231,181,249,183, 29, 80,171,228,120, 26,122, 25, 50, 89, 38,254,216,123,206,203,201,137,246,147, 72, 36,247,
-140, 21,192, 7, 14, 28,152,215,170, 89,179,102,117, 93, 92, 16,145, 24, 15, 46,101, 0,135, 36,193,212,105,192, 32,213,112,241,
-166, 65, 48,204, 32, 77,203,199,154, 19,103, 34,141, 17,198,223,245,232,131, 85, 41,121, 32, 8, 2, 91,218,120,131,107, 38, 6,
- 71, 36,198,212,191,110,151, 8,131,224, 85,139,193, 21,139, 81,175,149, 81, 14,225,149,119,238,220,121, 17, 17, 17,209,194,219,
-219, 27,243,230,205, 67, 66, 66, 2, 40,138, 66,122,122,186, 90, 42,149, 74, 50, 51, 51, 19, 80,232,255,103, 95, 37,157, 88,105,
-213,225,116,239,222,189,146,225,134,144,144, 16,212,172, 89, 19, 22, 22, 22,200,207,207,199,164, 73,147, 44,127,249,229, 23, 0,
-192,139, 23, 47, 80, 90,160,124,142,136,151, 81,155,115, 11,104, 25, 45,127,213, 47,135,124,213,168,163,127, 50,186,244, 26,131,
-155,193, 7,113,251,250, 45,212, 96, 37,196, 67, 84,112, 53, 43, 62, 43, 63, 69,225, 30,232,213,124, 60, 83,170,184, 30, 56,163,
- 79, 12,211,209,145, 58,189,120, 79,126,110, 69,105,117,119,119,135,189,189,125,201, 28, 45, 22,139,133,113,227,198,129,166,105,
- 99, 69, 86, 81, 95, 67,101,170,213,106,123, 62,159,143,180,180, 52,124,252,248, 17,177,177,177, 37,174, 3, 40,138,210,207,159,
- 63,159, 61, 99,198, 12,236,217,179, 7,119,239,222,125, 4, 96, 37, 0, 99, 95,214,134, 15, 30, 60,216, 76,171,213,226,248,241,
-227, 36,128, 94,167, 79,159,126,209,162, 69, 11, 86,183,110,221,204,118,237,218, 53,188,168,140,140, 22, 90,230,230,230, 28,157,
- 78,135, 93,187,118, 33, 57, 57,217, 15, 64,212,179,103,207, 2, 7, 15, 30,188,219,219,219,187,126,100,100,228,123,185, 92, 62,
- 21,192,235,202,200,210,211,211,199,250,248,248,156,166, 40,202,181,115,231,206,162,223,126,251,205, 60, 58, 58, 26,206,206,206,
-160, 40, 42, 2, 85, 12, 97,245,254,253,251, 40,169, 84,234,213,190,125,123, 92,189,122,117,189,193, 96, 88, 11, 96,195,148, 41,
- 83,156, 18, 19, 19,209,172, 89, 51,212,168, 81, 3,209,209,209, 5, 82,169,116, 55, 10, 67, 18, 85,102,194,141, 3,176, 40, 48,
- 48,176,113, 96, 96,224,208, 26, 53,106,180, 14, 11, 11,195,131, 7, 15,176,121,243,102,252,242,203, 47,104,215,174, 29,230,205,
-155,151, 5, 96, 40, 0, 50, 46, 46,206, 40,191,121,197,150, 45, 0,104,222,188,121,234,186,117,235, 48,126,252,120,250,207, 63,
-255,220,126,244,232,209,217,195,135, 15, 47,233, 3, 71,143, 30, 77, 31, 57,114,100, 52, 10,195, 48,253, 59,161,215,233,180, 48,
-175, 81, 7,242,220, 36,100, 38,135, 66,104,230, 0,255,142, 77,160, 84,105,113,233,226, 89,188,142, 8, 7,131,193,128,189,131,
- 11, 44,173,108, 16, 19,243, 30,168,120,181,177, 94,167,211,193,204,170, 54,228,121,201,208,102,188,132, 64,108,135, 49, 63,245,
-131, 82,165,195,185,243,103, 17, 25,249, 26, 76, 38, 19, 14,142, 46,176,176, 44,228, 36,232,138, 87, 48,155, 0,160, 12,127, 90,
-149, 10, 45, 38,147,121,231,218,181,107, 3, 91,181,106,197,250,240,225, 3, 62,124, 40,124,185,145,201,100, 36, 1,195,153,140,
-136,139,195, 42,184,188, 51,138, 86,103,148,142, 93, 40, 54, 51,147, 68,191,139,178,151,229,164, 35,252,213, 67,124,136,137, 64,
-124,108, 20,116, 58, 53,152, 12, 6, 24, 76, 6,106,215,105,136,135,143, 66,181,106,146, 12, 45,143,179, 48, 29,177, 5, 34, 59,
-247, 33,171, 87,253, 28, 60,103,193, 10,193,160,129,123,240, 58,250, 45,228,164, 3,104, 26,112,176, 22,161,105,221,133,144,164,
-102,226,196,193, 93, 74, 74,167, 27,241,153, 15,173, 47, 56, 1,192, 62, 11, 13,118,239, 61, 56,110, 95,208,177, 21, 11,102, 76,
-178,239,219,127, 4,184, 57,111,161, 79,125,137, 58, 45,186,131,224, 89,226,202,141,219,184,247,226,109, 58,101,160, 87,216,103,
-227,207,152, 74, 56, 75, 35, 55, 55,247,113, 90,154,212,185,148, 23,120,103, 30,143, 95,217,234,184,207, 57, 63,241, 56,207,100,
- 50,154,175, 94,189, 90,111,111,111,175,139,140,140,196,158, 61,123,168,151, 47, 95,222, 96, 48, 24, 59,165, 82,169,186, 50, 78,
- 91,189, 62,252, 88, 64, 64,131,150,253,251,211,195,102,204, 80,130,199,155,185,105,203,150,128, 76,153,172, 38, 77, 81,176,173,
- 81, 35,101,211,226,197,235, 6, 14, 30, 44,123,243,240,161, 32,244,194, 5, 1,151, 36, 95, 26,145,206,111,129,114, 57, 37, 18,
-201,189,187,119, 31,224,208,190,223,160,211,105, 32,149, 36, 2, 0,178,178,243, 80,137,200,250,156,147, 86, 42,149,253,151,254,
-242,203,147,165,115,102, 59,252,208,169, 51,146,194,195,160,203,201, 4,161, 39,193, 38, 88, 80,100, 8,145,145, 46,199,162, 35,
-167, 50,228, 74,101,255, 50, 58,137, 50,211, 89,108,177,226,153,155,129, 35, 18,131, 43, 54,251,196,138,197, 55, 55, 7, 87, 36,
- 6,139,203, 45,107, 2,247, 23,156,114,185,124,192,192,129, 3, 95, 63,123,246,204,106,252,248,241,248,254,251,239, 95,169, 84,
-170, 14, 0, 10,170,155,159, 20, 69, 73,126,248,225, 7, 6, 65, 16,226, 17, 35, 70,240, 50, 51, 51, 75, 60,171,203,229,114, 92,
-189,122, 21,158,158,133,171,250,223,188,121,131,134, 13, 27,150,203, 57, 97, 81,164, 4,192,170, 57, 3,157, 54, 61, 9,151,206,
- 4,176,190, 78,125, 23,220,190,126, 11, 15,110,135, 6,180,246,166,118,244, 24,209,226, 87, 97,135,193, 11,188,154,143,103,138,
-205, 29,113,248,220, 89,102,212,203,253,107,148,202,136,122,216,115,126,126,121,233, 36, 8, 2, 52, 77,127,225,202,129,201,100,
-226,232,209,163, 85,189,247, 83,251,246,237,155, 50,121,242,100,142, 84, 42,197,187,119,239,160, 80, 40,192,231,243,113,253,250,
-117, 18,192,174,163, 71,143, 94, 63,122,244,104, 55, 20,174, 38, 10,169, 74,253, 20,137, 68,211,253,253,253,241,238,221, 59, 60,
-127,254,252, 44,128,215,175, 94,189, 58,251,225,195,135, 33,237,218,181,195,193,131, 7,167,171, 84,170,125, 85,225,164, 40,170,
-180,207,164,226,136, 15,225,114,185,188,117,104,104,104, 85,203, 93,154,157,157,221,182, 72, 88, 39,219,219,219,155,135,135,135,
-163, 86,173, 90,208,233,116,173,170, 90,151,242,242,242,126,219,185,115,231,159, 99,199,142,197,175,191,254, 58,226,212,169, 83,
- 35,122,244,232,129,158, 61,123,226,192,129, 3,120,253,250,245,122, 24, 23, 86,172,172,123,127, 13,224,181,189,189,253, 52, 23,
- 23, 23,108,222,188, 25, 17, 17, 17,235, 86,173, 90,181,248,245,235,215,240,244,244,228, 69, 69, 69,145,213,105, 67, 0,192,220,
-220,220, 92,175,215,227,194,133, 11, 79, 1,204, 25, 49, 98,132,221,182,109,219,134,138,197, 98,228,228,228,168, 34, 35, 35,135,
- 3,184,248,239,110,235,104,130, 88, 50,126,194,204,192, 9,227,135,243,125,154, 55,133, 50, 63, 5, 42,121, 58,148, 5,105,216,
-185,239, 6, 8,130, 1, 91, 91, 71,216, 57, 56, 35, 49, 49, 9,143, 46, 95,209, 42,148,170,109, 92, 61,181,190, 98,206, 25,133,
-156,205, 10, 57,149,138, 12,168,228, 25, 37,156,118,118, 53,139, 56, 19,241, 48,244,138, 90,165, 80,252,166,165,137,141,127,243,
-189,255, 55,163,106,177, 14, 75, 67, 38,147,205,154, 52,105, 82,135, 69,139, 22, 89,147, 36,201,172, 81,163, 6, 18, 19, 19,201,
- 51,103,206,228,200,229,242, 89,213, 73, 13,139,205,126,237,238,225,217,161,111,223,190,100,159, 62,189, 57, 35,199,118, 99,217,
-218,217, 33, 47, 55, 27, 49,239,194, 16,253,246, 37,220, 61,155, 96,249,170,173,128,165,101,165,129, 36,139,194,234,244, 90,185,
-116,254,201,182,126, 93,205, 61, 27, 54,225, 52,173,103, 1,157,158, 68, 74, 74, 10, 46, 94, 8,215, 69,190,120,144, 79,145,218,
- 33,202, 44,227, 66,240,220, 3, 72,100,227, 15,111, 59,221,209,181,155,118,206,219,245,199,161, 5,139,102,142, 23,181,243,237,
-130,136, 91, 7,113, 54,248,164, 66,173,209,110,226, 48,177, 37, 50, 27,202,152, 42,230,129, 90,173,214,125,222,159,170,213,106,
-221,215,150,244,129, 3, 7,144,158,158,174, 77, 72, 72,184, 70,146,228,169, 10,130, 61,127,129,157,128,182,159, 70,115,107,169,
-175,111,183,165,215,175,243, 71, 47, 92,168, 29, 49,114,228,124,104, 52, 58,112,185, 52, 75, 36, 98,128,199, 99,191,121,248, 80,
-176,125,202,148, 26,132, 86,123,243, 80, 5,110, 3,202,192, 55, 95,117, 88,108,209,106,223,190, 29, 70,143,159, 3, 85, 41,139,
-214,227,231, 49,208,232, 96,180, 69,171, 8, 73, 9,201,201,173,103, 46, 89,122,110,136,127, 39, 47,111,215,218, 60, 91,183,218,
- 16, 59, 56, 32, 59, 51, 19, 15,159, 71,235, 87,157, 60, 23, 89, 36,178,140,242, 43, 67, 81, 84,225, 36,119, 0,157,102, 45, 2,
-193,100, 2, 69,110, 28,138, 87, 14,185,181,248, 30, 4,139, 5, 3, 77, 65,163,209, 24, 51,233, 47,229,227,199,143, 3, 70,140,
- 24, 17, 18, 28, 28,204,240,247,247,111,122,254,252,121,234,107,234,142, 74,165,106, 13, 0,124, 62, 63,222,210,210,210,105,236,
-216,177,208,235,245, 80, 42,149,200,203,203, 67, 74, 74, 74,238,216,177, 99,117, 0, 32, 16, 8,184, 3, 7, 14, 52,175,140,115,
-235, 25,137,122,206, 64,167, 29, 53, 88, 9, 67,243,179, 94,187,213, 96, 37,196,183,246,166,118,108, 61, 35, 81,155,215, 84,172,
-206, 74,184, 23, 35, 85, 92, 15, 60,124,238, 44,115, 84,191, 1, 6,103,241,251, 0,190, 29,125,166, 50, 94,130, 32,190,112, 78,
-106,164,200,250, 4, 5, 5, 5,139,151, 45, 91,214, 83, 38,147, 57,119,235,214,141,227,229,229,133, 39, 79,158, 32, 56, 56,152,
-124,252,248,113,178, 66,161,248, 25,128, 26,192,141,234,228,169,135,135,135, 27,139,197, 42, 30, 74,251,189,104,247,239,231,207,
-159, 31, 50,126,252,120,212,174, 93,187, 65, 84, 84, 20, 15, 85,120,142,104,154, 46, 25,101,248,150, 32, 8, 34,118,251,246,237,
- 78, 14, 14, 14,196,213,171, 87, 73, 38,147, 89, 29,203,205,129,253,251,247,183,210,235,245, 19, 38, 78,156, 8, 63, 63, 63,144,
- 36,137, 35, 71,142, 96,255,254,253,198,138,172, 10, 17, 19, 19,243, 50, 57, 57,249,135,249,243,231, 99,243,230,205,139,231,207,
-159,143,228,228,100,196,196,196,132,125, 13,111,126,126,190, 42, 41, 41, 73,216,166, 77, 27,159,200,200,200,200, 14, 29, 58, 52,
- 28, 63,126, 60,214,175, 95, 79,223,189,123,119, 32,128,171,255, 68,239, 29,253, 33, 39,136,109, 96, 93, 95,181,250,183, 95,234,
-213,117,155, 60,110,204, 96,166,135,123, 67, 40,242, 82, 96,109, 99, 15,103,151, 58,200,204,200,194,181,107, 87, 13, 89, 89,185,
- 7, 12, 12, 98,229,135, 15, 57,169, 95,195,233,228, 92, 7, 25, 25, 25,184,114,229,138, 33, 87,150,191, 23,122,198,170,168,196,
-220,116,152, 96,140, 37,107, 34, 42,240, 18, 95, 17,108,172,172,172,142,155,155,155,167,155,155,155,167, 91, 89, 89, 29, 7,140,
- 90,125,208,185, 84,235,192,252,100, 27, 56,144, 15, 62,191, 53, 88,172,185,150, 86, 86, 87, 45, 44, 44,178,219,183,111,175, 13,
- 12, 12, 84, 71, 69,189,161, 36,146,100,218,194,194, 34,175,228,252,178, 56, 63,131,149, 85, 93, 51,145, 99,195, 95, 44,156,155,
- 62, 20, 59, 54, 40, 16, 59, 54, 40,176,112,110,242, 72,228,216, 96,133,149, 85, 93, 51,163,210, 89, 14,234,216,193,214,221, 6,
-187, 60,109, 9,149,187, 13,118,213,177,131,173,209,247, 94,241,176,159,129, 32, 96, 64,225, 50,108, 84,131,179,152,131, 98, 50,
-153,135,156,157,157, 29, 81, 53,135,117, 95,112,142, 4,106,143,228,241, 38,156, 14, 8, 24, 29,127,247,238,136,252,184,184, 97,
-121,177,177,131,195, 78,158, 28,242,251,144, 33, 35,135,241,120, 19, 7, 2,117,141,229,116,116,116, 92,247,242,229,203, 96, 99,
-183, 82,194,203,232,252,172, 91,199,233,186,127,231, 86,244,244, 73,253,233,233,147,250,211,254,157, 91,209,117,235, 56, 93,255,
-138, 50, 34,152, 76,230, 80,161, 80,120, 92, 36, 20, 70,136,132,194, 8,161, 80,120,156,201,100, 14, 69,197,115,168, 62,225,180,
-182,182,126, 97,111,111,159, 94,149,205,198,198,230, 85, 21,210, 57,204,205,205, 45,153,193, 96,108,173,226, 51, 93, 17,167,187,
- 64, 32,136, 21,137, 68, 41,165, 55,129, 64, 80,218, 49,148,181, 80, 40,188, 36, 18,137,182, 25,195,185,113, 73,195, 95, 30,221,
-152,246,122,227,146,134,191,124,126,108,198,143, 86, 99,159,132,172,204,158,241,163,213, 88, 99,210,105,103,103,119,215,206,206,
- 78,106,103,103, 39,181,183,183,175,112,179,177,177,121, 97, 4, 39,223,204,204,108,155,153,153, 89,186, 72, 36, 50,136,197,226,
-116,145, 72,180, 21,165, 92, 91, 84, 55, 63, 25, 12,198,250, 6, 13, 26,168,153, 76,230,159,159, 29,218, 92,175, 94, 61, 53,139,
-197,218, 84, 69, 78,243,118,237,218, 25,194,195,195,105, 63, 63, 63, 26,128,213, 55, 44,119, 7, 43, 43,171,171,230,230,230, 73,
-102,102,102, 59, 1,136,170,201, 73, 0, 24,234,228,228, 20,214,177, 99, 71,165,147,147, 83, 40,128,190,223, 48,157, 61,127,252,
-241, 71, 42, 41, 41,137,166,105,154, 78, 74, 74,162,127,252,241, 71, 10,133,142, 34,191,166, 77, 94, 50,101,202, 20,250,241,227,
-199,244,227,199,143,233,208,208, 80,186,103,207,158, 20,128,159,190,178,157,199,183,186,119,175, 58, 54,117,191,171,111,117,106,
-248, 0, 95,234,198,197,173,244,242,159, 39,211, 93,252, 26,210,158,245,172,206,185,187, 91,187,127, 11,206, 95,126,158, 68,119,
-254,161, 1,229, 85,215,234,164, 87, 29,155,186,255,230,123,255,255,104,213,194,223, 61,225,236, 95,166,197, 79,197, 82,217,168,
- 89,179, 38,178,179, 91,241, 89, 44, 95, 30,143,215,129,193,100,222,201,201,204,156, 93,244,186,101,248,119,153,106, 43,236,208,
-235,130, 91, 65, 72,130,234,112,126, 50,145,189,154,156, 85,225, 48,138,179,188,160,210,148, 70,147,106, 77,146, 47,118,162,194,
- 60,248,132,211,201,201,105, 2, 69, 81,110,198, 38,136,193, 96,196, 75, 36,146,125,213,201,207,250,245,235,211, 69,195,219,196,
-183, 44,247,191,163, 46,253, 47,113, 30,254,173, 81, 77,207, 70,223, 45,136,120, 25,181,185,104, 88,177, 4, 43,102, 88,153,249,
-118,108,191,236,225,237,187,191,174,216, 41, 43,248,135,239,157, 1, 35,231,180,125, 3,206, 98, 39,161, 85,226,100,179,217,129,
- 45, 91,182,156,240,228,201,147, 63, 13, 6,195,196,255,209,250,217,147,201,100,206,247,240,240,104, 26, 19, 19, 19,102, 48, 24,
- 54,163, 12, 71,145,213, 72,231,207,110,110,110, 83, 57, 28, 14, 79, 46,151,203, 82, 83, 83,151, 1, 56,245,159,150,159, 94,245,
-107,248,208,116,137,211,237, 53,239, 62,230, 60,251,102,156, 52,101,160,104,230,234,152,184,236, 87,255, 64,185,255,127, 19, 89,
-123,255, 29,127,220,217,196,105,226, 52,113,154, 56, 77,156,223,156, 83, 96,202, 79, 19,231,255, 67,206,255,151, 96,153,178,192,
- 4, 19, 76, 48,225,191, 14, 42, 83, 22,152, 96,194,127, 28, 74, 91,181, 74,172, 89, 68, 5,170,180, 42, 38,193,234, 40,219, 91,
- 38, 78, 19,167,137,211,196,105,226, 52,113,154, 56,255,231, 56,255,191,138,172,189, 21,252,254,219, 96, 50,171,154, 56, 77,156,
- 38, 78, 19,167,137,211,196,105,226,252, 95, 16, 90,101,254, 54, 13, 29,154,240,183, 99, 71, 63, 56, 1,192,204,243,144,252, 29,
-231,155, 96,130, 9, 38,152, 96,194, 63,140,189, 40,103,232,240, 63, 65,104,213, 4,208, 26,133,129,111,163, 1, 60, 0, 32,251,
- 10, 62, 27, 0,131, 9,130, 24, 4, 0, 52, 77,159, 70,225,170,145, 44, 99, 46,230,243,249,233,106,181,218,174,232,123,134, 90,
-173, 46, 29,203,128,192,151,171,217,232, 82, 91,153,112,115,115, 75,215,104, 52,118, 70,252,125, 30, 77,211,175, 25, 12, 70,132,
- 88, 44,190, 29, 19, 19, 19, 92,149, 27,239,208,161,195,104, 38,147,185, 6, 0, 12, 6,195,146, 59,119,238, 28,250, 27,203,173,
-149, 75, 77,135,131, 58,189,142, 76,207,204, 89,134, 47, 29,249, 1, 0,118,245,194, 58,130,196,130,162,239,155,166, 5, 87,236,
- 71,167,170,231, 87, 0, 31, 54,155, 61,221,222,222,190,123, 74, 74,202, 11, 0, 11,129,202,189, 26,187,184,184,252,196, 98,177,
- 70, 24, 12,134,186, 76, 38, 51,150, 36,201,163,201,201,201, 65,166, 54,196, 4, 19, 76, 48,193, 4, 35,196,214, 23,168,146,208,
-242,180,134, 3, 13, 12, 5,129, 46,160,113,147, 0, 78, 68,103, 35,205,216,235,123,120, 66,175, 39, 11,255,147,195,128,225,234,
- 71,198,222,238,221,187, 59,207,152, 49, 3,223,127,255, 61,158, 60,121,210,230,192,129, 3, 99, 79,157, 58,245,154,162,168, 59,
- 0,158, 0, 70,185, 82, 16,161,208, 79,203,240,238,221,187,119, 94,179,102, 13,179, 97,195,134, 80,169, 84,184,123,247,174,239,
-166, 77,155,182, 61,122,244,232, 22,128, 99, 69,130,160,220, 0,120,106,181,218,174, 56, 24, 39, 65, 16,118, 3, 7, 14,124, 86,
- 90, 92, 21,197, 87, 35,104,154,126, 76, 16, 68,168,193, 96,120,114,230,204,153,100, 79,160,213, 36, 55,206,153,217,241, 58,231,
-207, 57, 53, 26,141,221,133,141,107,193,226,241,160, 41,200, 71,155, 49,255, 18,189, 55,127, 89, 0,130, 34,193, 4, 45,235,176,
-122,219,107, 0, 17,169,169,169,175,253,252,252,226,171, 90,194, 76, 38,115,205,181,107,215, 28,105,154,134,191,191,255, 26, 0,
-127,151,208,226,181,246,105,114,231,210,217,227,124,121, 78, 58,186,245,123,156,100,255, 0, 0, 32, 0, 73, 68, 65, 84, 29,114,
-244,125,114,198,104, 0,103, 63, 17, 77,221, 97, 79, 16, 88, 48,101,237, 49, 38, 0,236,254,121,248,194,173, 93,177, 99,206, 13,
-164, 1,232, 80, 36,126, 0, 96, 35,128, 59,187,186,195, 30,192,162, 41,107,143, 17, 0,176,231,231,225, 11,118,117,199,246,105,
- 87,171,236,182, 98,234,232,209,163,119,172, 89,179,134,233,232,232, 8,137, 68,210,173, 65,131, 6, 30,249,249,249, 13, 80,193,
- 36,226,218,181,107,159,108,215,177,119,157,254,131,134, 10,109,109,172,144, 42,205, 50, 63,121,252,207, 73,204,199,119,187, 39,
- 36, 36, 12, 49,181, 33, 38,152, 96,130, 9, 38,148,131,234,123,134,111,230, 8,129, 66,135, 31, 89, 76,226,167,182, 62, 13, 58,
- 13,235,209,142,209,192,171, 62,222,190,137,234,122,241,246,211, 77,140,208, 55, 33,164,129, 14, 18,113,112,225,149,180,226,149,
- 48,122, 18,172, 27, 23,142, 21,246,132, 99,135, 51,159, 61,123, 86,191,121,243,230, 37,161, 97, 58,117,234,132, 78,157, 58, 17,
-187,119,239,110,114,227,198,141, 38,251,247,239,215,133,132,132, 28, 68,197,254, 81,166,215,171, 87,111,211,142, 29, 59,120,126,
-126,126,224,241,120, 37, 7,196, 98, 49,122,247,238,141,222,189,123, 51, 83, 83, 83,253, 47, 93,186,228,191,113,227, 70,109, 98,
- 98,226,124,252,203, 75,115,133, 88,182,108,153, 79, 25,187,175, 17, 4,241,145, 36,201,176, 38, 77,154, 36,123, 0,245, 39,245,
-248,254,230,212,182,238,162,217,139, 15,148,201,195,226,114,113,120,116, 97, 95, 93, 90,104,197,223,190, 10,177,185, 89,182,208,
-204,236, 53,128, 8, 0,175,105,154,142,136,141,141,141,250, 14,104,210,218,138,113,240, 79, 25,213,184, 10, 98, 11,201,201,201,
-176,176,176, 16,248,249,249, 73, 9,130, 88,113,247,238,221,111, 61, 33,175,213,138, 5, 83, 57,178,132,215, 72,123,247, 24,115,
- 7,249, 10,103,239,252,235, 87,181, 86,127,182,162,139, 8,130,193,216, 24, 74, 5,160, 48, 24,239,178,236,236,108, 63, 0,176,
-182,182,230, 2,184,179,245, 41,122,204,105, 75,124,141,111, 55, 14,147,201,220,117,224,192,129,241, 63,253,244, 83, 97,232,136,
-135, 15, 33, 22,139,177,106,213,170,218,243,230,205, 91, 71,146,228,172,242, 44, 89,237, 58,246,174,179,125,243,175, 13, 10,114,
-242, 52,127,236, 58,245,188,166,183, 39, 99,202,244,121,102,219,117, 26, 7,131,193,240,147,201,178,101,130, 9, 38,152, 96, 66,
- 85,172, 89,149, 10, 45, 15, 27, 28,106,230,237, 62,120, 88, 79, 95, 94, 35,239,134,224,240,254,229,186,165,185,143, 15,154,251,
-248, 48, 2,228, 5, 93,158, 61,127,217,229,204,141, 39, 26,165, 62,241, 84, 76, 22, 70, 27,155,170,226,160,180,107,250,218,119,
- 84,228,102,240, 1, 64,100,105,167,254,249, 66,218,237,182,109,219,194,217,217,153, 19, 18, 18, 50,174, 18,161,245,115,116,116,
- 52,143,201,172,216, 31,106,205,154, 53, 49,112,224, 64,120,122,122,114,219,183,111,255,115,121, 66,139,207,231,103, 16, 4, 97,
- 7, 0, 53,106,212, 48,172, 88,177, 34,140, 46, 4, 0,208, 52, 77, 63,102, 48, 24, 79, 40,138,122,250,215, 95,127,165, 52, 0,
-236,186, 53,247,124, 48,117,228, 64, 33,125,102, 91,185, 34, 65,157,159, 95,230,126,161, 88,148, 41, 16,137, 94,243,132,252, 8,
- 20,198,242,138,112,118,118,142,106, 0, 56,183,244,116,187,177,123,206,112,179, 63, 39,254, 90,105, 94, 54,107,214,204,163,113,
-227,198,124,131,193, 0,133, 66,129, 61,123,246, 88, 8, 4, 2,139,238,221,187, 47, 47, 93, 1,188,128, 70, 3,106, 50, 39,174,
- 76, 53, 76,171, 70, 69,178,108,215,198, 39, 97, 96,239,238,230, 62,173,219,225,253,157, 35,200,201, 41, 64, 94,174, 28, 20, 69,
-125,225,215,103,218, 85,164,239,234,133, 77,187, 23, 15, 95, 68, 48, 24, 68,147,126, 11,209,199, 33,111,102, 96, 96,224, 27, 0,
-108, 46,151, 91,186, 30,214, 20, 56,121,111,170,223,181, 29,246, 44, 25, 9,154,162,104, 0,155,170, 96,205,178, 51, 51, 51,187,
-120,227,198,141, 86, 45, 90,180,192,147, 39, 79, 16, 23, 23,135,169, 83,167,106,167, 77,155,198, 25, 53,106, 20, 49,119,238,220,
- 25, 27, 55,110, 60, 3,224,209, 23, 15, 2,139, 53,162,111,255, 33, 92,121,110,190, 90,171,209,105,107,216, 88, 82, 26,133, 90,
-153, 37,203, 87, 15, 25, 62, 65,251,230,213,211, 17, 0,190, 16, 90, 95,153,159, 38,152, 96,130, 9, 38, 24, 1,154,166, 91, 0,
-176, 5,144, 73, 16,196,243,210,191,139, 78, 41,142,214,242,249,239, 44, 20,142, 74, 89,151,162,203, 66,225,116, 31, 91, 0, 6,
- 0,207, 8,130,144,125,101, 18, 43, 94,101, 24, 28, 28, 76,151,254, 44, 37,180,104,154,166,105,125,246, 71, 90, 19,115,149, 86,
- 62,223,247,197,166,122,115,150,150, 62, 59, 69, 63, 61,246, 11,237, 97, 83,113, 20,246, 30,158,208, 15,111, 12,122, 74, 11,208,
-179,218, 91,170,159, 61,123, 22, 66, 81, 84,112, 64, 59,208,244,219, 99, 52,253,246, 24, 61,167, 13,232, 51,103,206, 92, 91,183,
-110, 93,112, 80, 80, 80, 48,128,202,230, 41,165, 23, 60, 15,165,159,218,129, 46, 15,209,209,209,116, 96, 96, 32,189,120,241, 98,
-250,207, 63,255,164, 81,137, 7,117,127,127,255,187,145,145,145,244,168, 81,163,194, 80,129, 99, 64, 47, 64, 52,162,182,195, 59,
-205,201,109, 58,237, 79,141,104,217, 15,252, 50,239,223,209,209,241,147,244,172,119,119,160,127,111,233, 78, 31,234,210, 60,141,
-166,233,107, 52, 77,175,167,105,122, 8, 77,211,158, 0,208, 12, 48,239,235,104,253, 65,125,106,187, 74, 59,177,117,165,113,239,
-154, 53,107,230, 49,127,254,252, 28,173, 86, 75,199,199,199,211,127,252,241, 7,125,243,230, 77,250,194,133, 11,180,175,175,111,
-106,169,244,218,143,245,116, 77,215,238, 95,169,169, 78, 45, 98, 51,153,191, 63,191,121,134,254,240,224, 52,253,236,196, 58,250,
-232,210, 97,244,140,190,173,116,230, 2,158, 26, 64,199,242,174,155,214, 22,245, 61,107,219,198, 36, 38, 38,210, 58,157,142, 30,
- 51,102, 12,237,239,239, 79,119,237,218,149,238,220,185, 51,221,169, 83, 39,186, 99,199,142,244,237,219,183,233,212,212, 84,186,
-115,187,230,138, 94, 94,240,169, 66,210,188, 93, 93, 93,211,226,227,227,105,157, 78, 71,135,132,132,208, 71,142, 28,161, 67, 66,
- 66,232,128,128, 0, 26,192,161, 41, 83,166,168,100, 50, 25,237,239,239,159,130, 50,188,198,187,186,186, 70, 69,198, 36, 39,111,
- 93,187,239,246,225,223,143,223, 62,119,230,230,237,139,215,159, 93,190,112,253,249,169,167,225,177, 23, 92, 93, 93,163,202, 40,
-255,175,202, 79, 19, 76, 48,193, 4, 19, 42,215, 34, 69, 66,171,103,145,177,163, 39, 77,211,157, 63,251,221,179, 72, 56,125,241,
- 59, 32, 32, 96,113,233,223,197,231, 4, 4, 4, 44, 6, 64,183,105,211,230, 56, 77,211,245,191, 65,242, 39,150,177, 85,110,209,
- 42, 6,153,242, 12, 28,247,238, 96, 27,244,208,103, 69,131,202, 77, 4, 68, 14, 80, 17, 98,100, 75, 19,241,238,193,217,138, 3,
- 73, 20,225, 74, 52,216, 0, 66,162,162,162,240,238,221, 59, 36, 39, 39, 67, 40, 20,126,113,222,195,135, 15, 33, 16, 8,224,232,
-232,104,156,210,213,126,218,207,189,110,238, 10,113, 27, 63,100, 13,155,140,144,144, 16,100,100,100,128,195,225,128,203,229,130,
- 36,201, 74,249, 24,140,194,136,191,197, 86,172,178,206,241, 3, 88,188, 26,226, 75,187,151,207,114, 99, 60, 14,102,171,146, 62,
- 32, 85,109, 48,206,146, 39, 22, 65, 40, 18, 74, 5, 2, 97,201,112, 33,128, 8,130, 32,222, 55, 3,216, 34, 49,255,210,193,213,
-115, 29,152,175, 66,248,170, 15,175,203,228,232,220,185,243, 36, 0,203,105,154,206,109,220,184,177,253,154, 53,107,172, 36, 18,
- 9,222,190,125,139, 83,167, 78,101,146,133, 55, 74,208, 52,189, 18, 0, 90, 3,124, 75, 91,203,235,191,255, 50,203, 12,119, 78,
-114,171, 83,139, 44,188,122, 95, 30, 48,106,202,180, 29,179,122, 67, 81,160,194,177,155,175,112,237,229,199, 62, 0, 30,162,130,
-121,111,187, 30,225, 3,144,217,169,127,255,254, 97,247,239,223,183,217,191,127, 63, 72,146, 44,115,219,191,127, 63,110, 61,120,
- 57, 19,192, 11, 35,147, 85,211,205,205,237,214,211,167, 79,109,133, 66, 33,110,222,188,137,220,220,220, 18, 75,214,232,209,163,
-137,220,220,220,161,123,246,236, 25,144,144,144,176,249,193,131, 7,217, 40,140, 5,249, 73, 69, 96, 50,153, 31, 73, 82,247,157,
-163, 87,125,214,160,222,237,218,201,179, 95, 67,108,221, 24,143,195, 63, 94,202,149,101,171,152, 76,230,199,210,231,127,139,252,
- 52,193, 4, 19, 76, 48,161,106, 32, 8, 34,152,166,233, 94, 4, 65, 4,127,190,239,243,239,197,231,173, 91,183,174,228,119,241,
- 53,235,215,175, 95, 91,234,183,242, 27, 37,175,194,201,240,237,139, 20,100,251,178, 78,210,188, 61, 7,205,187,139,224,184,182,
- 5,215,179, 15,152,174,190, 72,122,125, 7,225, 87,183, 34,229,205, 67,208,148, 1,142, 30, 45,141, 77,136,250,187,239,190,131,
- 90, 93, 56, 53, 75,163,209,128, 35,178, 82,207,157, 56,156, 15, 0, 20,139,175, 41,165, 96,141, 34, 52,107,219, 1, 45,211,105,
- 60,179, 47, 52, 84,180, 76, 47,188,110,245,152, 49,224,112, 56,224,112, 56, 32,138,166,254, 24, 35,180,136,162,147,169,194,225,
-171,178, 18, 65, 40,121,236, 99, 39,150, 79,111,201, 75,136,224,106, 34, 31, 35, 85, 67,209,151,210, 13,151,141, 73,175, 80, 36,
-148, 8,132,194, 8,129, 88, 84, 34,180, 8,130,248, 8, 0, 52,155, 29,116,100,229,244,198,162,244, 88,145,250,121, 8,164,106,
- 74, 87, 14,205,202,171, 87,175,218,177, 88, 44, 7,131,193,128,164,164, 36,188,121,243, 6,219,183,111, 79, 47, 40, 40,104,255,
-234,213,171,152,210,218,209, 32,224,158, 10, 90, 53,171, 14,235,245, 61,190,230, 99,100,149,107,143,141,247,143,254,125,218, 55,
-185, 60,105,228, 18,252,216,163, 43, 70,181,111, 64,199,167,230,168, 1,220, 44, 50,189, 86, 6,201,171, 87,175,186,252,240,195,
- 15, 71,155, 54,109,234, 69,211, 52, 26, 53,106,132,161, 67,135, 34, 40, 40, 8,225,225,225,200,207,207,215,221,184,113, 99, 27,
-128, 3, 70, 38, 75,104,101,101,117,237,246,237,219,182, 66,161, 16, 55,110,220,128, 74,165,130,163,163, 35,166, 77,155,198, 93,
-191,126,253,225,252,252,252, 65,235,214,173,227,199,199,199,255,126,253,250,245,218, 40,140, 59,247, 69, 37,208,106,181,123,143,
- 5, 29,218, 49,109,250, 12,167,219, 79,222,134,104,228, 5, 22,174,174,201,249,182, 86, 98,179,109, 27, 86,214,210,106,181,147,
-202,206,207,187,213,202, 79, 19, 76, 48,193, 4, 19,190, 64,133, 90,164,180,120,250, 92,108, 85, 69,164, 1, 80, 5, 4, 4,252,
- 76, 16, 68,112, 64, 64,192,207,235,214,173, 83, 1, 72,253, 59, 68, 86,137,208,234,213,171,215,189,224,224, 96,244,234,213,235,
- 94,185, 20,148, 1,186,248,251,208,197,223,135,160,205, 76,252,181,110,216,103, 55, 79, 85, 59,117,189, 87,221,188,173,209,104,
- 88,135, 14, 29, 42,153,183, 5, 0, 6,131,225,155,151, 98, 85,132, 86,145,208,251, 34, 17,110, 60,241,189,189,115, 6,181,182,
- 54, 40,217,218,135,151, 32,209, 80,228,230, 15, 58,229,243, 92,122, 99,121,156, 23,102, 79, 66,242,131, 91, 16,138,197,201,227,
-239, 71,148, 88,177,138, 68, 86, 28, 0,212,230,153,133, 4,206,250,209,215,129, 3,142,246,242,105,164,106, 40, 77, 96,130,254,
- 64, 57,149, 13, 52, 77,255, 31,123,223, 29, 22,197,213,120,125,102,182, 47, 75,239,160,128,138,162, 52, 65, 81, 20, 27, 98,137,
- 26, 49,177,247,146,152,232,107, 55,150,136, 26, 99, 73, 20, 18, 99, 47, 81,147, 24,203, 27, 11,177, 69, 68,141, 45,104,196,134,
- 40, 93, 80, 68,154, 75,111, 11,108,159,153,239, 15, 96, 69,100,217, 5,205,247,203,155,236,121,158,125,102,103,103,230,236,157,
-123,103,238, 61,247,220,134,231,207,159,163,186,186, 26,209,209,209, 56,117,234, 84, 97, 35, 34, 11,109,249,198,127,252,244,249,
-148, 30,166,146, 60,174,226,193, 85,188,148,211,122, 53,117, 89,119, 30,217,155, 75, 18,191, 19, 36, 75, 56,176,103, 71, 44,254,
-116, 20,182,253,244,155, 90, 97,219, 55,120,231,185,200,241,149,114,229, 42, 61, 69,150,198,108,140,141,141,245,140,141,141,229,
- 3, 8,154, 56,113, 98,228,152, 49, 99, 16, 21, 21,133,243,231,207,187, 1, 16,215,158,183, 1, 53, 11,101,127, 11, 32, 93,155,
-241,200,229,114,143, 95,189,122,213,203,209,209, 17, 87,175, 94,133, 84, 42,197,156, 57,115, 20,243,231,207,231,206,152, 49,131,
- 40, 47, 47,215, 56, 89,209,209,209,197,218, 68, 22, 0,228,230,230, 94, 60,117,242,104,175,126,253,250,141,106,231,214,201, 52,
- 93, 82, 81, 96,100, 36, 16,222,138,186,193,125,112,239,246,238,220,220,220,251,141,199,231, 53,189,227,211, 0, 3, 12, 48,192,
- 0,237,208, 75,139, 52,112,166,154,131,122,215,113, 66, 67, 67, 19, 67, 67, 67, 95,115,188,222, 18, 13, 71, 29, 94,168, 43,211,
- 90, 52,143, 22, 85,158,245,230, 13,208,116,115,110,246,141,223, 44, 44, 44,212, 66,161,240, 53,161, 69,235,201, 89,114,230, 24,
-210,231, 78,214, 56, 89,117,206, 22,134,206,120, 43,161, 69,211,116, 52,128,215, 2, 97,100,219,113,210,246, 17, 30,189, 61,219,
-181, 34, 85, 39,119, 32,167, 90, 45, 91,251, 68, 41, 75,145, 48, 31, 36, 55,210,201, 90,195,169, 86, 65, 32, 18,102, 10,141, 69,
- 13, 69,214, 11, 0, 16,217,185,141,249,110, 88,167,254,190,157,218,147,234, 19, 91,145, 91,173,170, 12, 73, 86, 42,211,171,152,
-211, 90,226,112,237,123,239,189,183,214,202,202, 74,176,115,231, 78, 51, 23, 23, 23,168,213,106, 69, 67,145,101,100,219,113,210,
-142,145,222,189, 59,218, 91,144,170, 95,119, 33, 91, 74, 85,239, 72, 87, 29,214, 71,100, 89,155, 25, 95,222,183,105,174,208,136,
-207,129, 76, 38, 67,216,222, 95,241,251,237,132,224,162,132,179,151, 1, 92,126,139, 7,242,147,224,224,224,109, 27, 54,108,128,
- 74,165,194,204,153, 51,241,236,217,179,223,159, 60,121,178,195,217,217,121,217,231,159,127,238,104,111,111,143,241,227,199,115,
- 85, 42,213, 12, 45, 28,223,252,242,203, 47,193,190,190,190,136,138,138, 66, 89, 89, 25, 28, 28, 28, 48,127,254,124, 94,104,104,
-232,225,138,138,138,113,155, 54,109, 18, 60,127,254,188, 73, 39,235,181,231,154,162,190,222,191,109,238,178,238, 61,251,144, 79,
-159,166,170,179,252, 3,201, 27, 87,207,223,180,178,178, 58,156,149,149,245, 42, 62, 71,117,110,118,124, 26, 96,128, 1, 6, 24,
-240,110, 64, 16,196,133,218,126, 87,175,185, 92, 13, 69, 88,157, 99, 85,127,191,225,249,181,199,223, 69,101,249, 64, 35,194,235,
-245,233, 29,130,131,131,245, 30, 86, 79, 87, 21,234, 37,158, 26,226,253, 78, 80,181, 50, 6,123, 85, 32, 9,174,200, 66, 54, 98,
-195,149,235,218,206, 21,137, 68,122, 59, 90,180, 92,166, 43, 81,154, 37,180,106,251,104, 93, 98, 24,230, 53,161,101,102,215, 49,
-112,197,231,139,182,247, 25, 51,148,204,255, 52, 0,101,149,114,249,231, 73,106, 58,167,186,105,145, 85, 83,138,171, 50,140, 68,
-198,241, 2,145, 81,125,145,149, 5, 0, 2,219,246,254,203, 23,207,219, 59, 96,210, 8,162,112, 78, 31,148,150, 73,229,203, 18,
-213, 68,174,148, 25,151, 12,220,104,140,238,250,245,235,251, 1,236, 15, 12, 12,204, 23,137, 68,168,172,172,124, 35, 13,234,194,
-219,123,204, 80, 50,255,147, 30, 40,169, 82,202, 63, 79, 84,227,165,148, 62,174, 75,100,217,152,155, 92,222,183,113,174,209,203,
-156, 23,224,114,185, 48, 54, 54,198,149, 63,227, 81,148,120,238,109, 4, 22, 72,146, 92, 23, 18, 18,178,118,222,188,121, 40, 46,
- 46,198,249,243,231,241,254,251,239,227,216,177, 99, 46,145,145,145,219,130,130,130,192, 98,177, 16, 17, 17, 1,149, 74,149,166,
-133,102,212,172, 89,179,150,141, 25, 51, 6,247,239,223,135, 88, 44,126,205,201, 42, 43, 43,155,184,119,239,222, 49, 25, 25, 25,
- 58,157,172, 6,240,111,219,190, 43,119,229,154, 45,144, 87, 23,176, 11,115,239, 70, 93,187, 66,222, 41, 41, 41, 49, 2, 80,222,
-210,248, 52,192, 0, 3, 12, 48, 64,111, 87, 75,155, 22, 41,172, 21, 81,133,141,237,215, 19, 88,141,237, 19, 13, 92, 48, 69,131,
-227,143,255,202,123,210,203,209, 98,219,121, 67,157,159, 80, 79,104, 21,188,118, 92, 96, 98,169, 87,211,161, 74, 13,246,190,131,
-154,121,180, 4,197,197,197, 2,107,107,107, 89,125,129, 96,100,100, 4, 71, 71, 71,148,150,150,226,192,129, 3,128,238, 78,209,
-106,211, 49, 83,225, 63,105, 38, 30,180,230,129, 81, 41, 53,206,214,190,143, 62,122, 77,108,113,185,220,186,190, 97,186, 10,221,
-123,181, 78,211, 29, 0, 76, 87,183,118, 95, 9, 68,162,143, 4,214, 78,214,139,231,126,194,201, 40,144,227,122,159,149,101,191,
-126,179,194, 56,155, 49,158,151,133,242,219, 58,248,210, 63,252,254,104, 67, 39, 43,167,139, 91,187,213, 2, 35,193,167, 60,203,
- 54,246, 33, 75,230,114, 50,242,229,196,117,255,207, 43, 78,125,251,185,209,115,152, 44,203, 65,217, 13, 61,146,103,237,251,239,
-191,191,150, 97, 24,134,166,233, 53, 0, 80, 63,188, 75,230,127,202, 73,207,147,225, 90,159,213,165,167,190, 89, 97,146,141,166,
-195,107,221,121,100,111, 59, 11,211,203,251, 54,205, 51, 18,231,102,130,207,231,195,196,196, 4,217,249,229,224,176, 89,210,183,
-124,222,248,125,251,246, 93, 49,119,238, 92,196,199,199, 99,206,156, 57,226,172,172,172,211, 39, 78,156,152,243,229,151, 95,178,
-135, 12, 25, 2,177, 88,140,205,155, 55,171,254,252,243,207, 77, 0, 54, 55,250, 60,178,217,159,124,245,213, 87,204,203,151, 47,
-137,231,207,159,195,193,193, 1, 11, 22, 44,224,109,218,180, 73,211, 39,171, 57, 78, 86, 29,114,115,115,163,126,191,122, 7, 31,
- 92,220, 14,181, 74, 30, 85, 86,156,117, 51, 37,189, 52,202,146,199, 91,218,170,107,231, 22,197,167, 1, 6, 24, 96,128, 1,239,
-196,197,122,208,212,254,223, 0,141, 53, 29,234, 37,180,210,118,173,254,216,237,227,121,203, 33,116,233, 13,121,242, 25,208,149,
-249, 26, 71, 75, 96,108, 1, 75,103, 15,148, 85,201, 17,126,237, 33, 0,164, 53, 39, 84, 18,137, 4,126,126,126,216, 51,163,227,
- 0,153,164, 88, 32, 4, 32,231,155,202,206,242,250, 94,143,140,140,172,166,105,250, 56,128, 72, 29, 52,235,188,188,188,118,111,
-217,178,133,231, 49,233, 99, 84,222,189,213,208, 65,129, 80, 40, 4,159,207, 71, 92, 92, 28,174, 95,191,174, 0,176, 78, 71,130,
-222, 83,171,213,143, 79,156, 56,145,211,161, 93,171,161,126, 93,124, 22,174, 90, 25, 98,146,116,235,119,172,217,180,155,238,208,
-109, 72,121,216,177,179,146,114, 99,231,129, 82,241,147, 71,122,220,234,227, 6, 34,235,165,123, 91,167, 1, 93,188,189,150,175,
- 89,179,218, 52,241,214, 21,124,249,237, 62,198,205,119, 80,249,183,167,206, 85, 20, 25,181,121, 79, 86,144,114, 95,159, 56,140,
-138,138,218, 15, 96,127,221,126,195,240,134,108,216, 65,119,236, 62,180, 52,236,216,169,170, 10, 19,231, 65, 77,133,215,198, 99,
- 84,175,214, 54, 22,151,119,125,253, 31,163,188,220, 44,240,249,124, 24, 27, 27, 35, 75, 92,134,181,219, 79, 86, 41,105,122,232,
-219, 10, 45, 19, 19, 19,190, 82,169,196,158, 61,123,144,149,149, 21, 0, 32, 43, 38, 38,102,223,132, 9, 19,118,118,238,220,217,
- 61, 49, 49, 49,173,178,178,114, 30,128, 20,109, 36,230,230,230, 1, 54, 54, 54,196,157, 59,119,240,159,255,252, 71,177, 96,193,
- 2,238,244,233,211,137,210,210,210,150, 58, 89, 0,128, 86,173, 90, 5, 14, 30,216, 19,189, 7,207,137, 82,200,202,110,102,164,
- 28,142, 34,153,219,130,150,198,167, 1, 6, 24, 96,128, 1,255, 26,180,108, 98,240, 64,128,221,209, 10,179,189, 90,113,243,142,
-124,179,128,145,164, 71, 51,210,251,251,153,138, 51,159, 50, 23, 54, 79,103, 34,119, 45,102,230, 12,247, 98,220,109,137,188,142,
- 86,152, 29,248,166,112,123,109,117,239,247, 59, 65, 53,184, 61,152,193,237,193, 12,239, 8, 21,128, 85, 93,187,118, 61, 59,223,
-255,213, 60, 90,243,253,193, 0,248, 15, 0, 99, 45,193,106,108,197,112, 7, 0, 7,252,252,252,212, 55,110,220, 96,158,140, 27,
-196,196,186, 91, 51,243,230,205, 99,190,252,242, 75,102,242,228,201,140,141,141,141,186, 54, 34, 28,116,113,126,240,193, 7,173,
- 1,192,201,201,201,188,155, 71,135,188,184,107,231,153,155, 71,118, 50, 63,205, 31,205,244,232,236, 81,100,239,222,239,177,208,
-161, 83, 23, 29,209,167,225,180,183,183, 95,201, 48,204, 80,134, 97, 28, 0,192,205,205,202,184,171,123,135,151,143,175,158,103,
-110, 29,221,205,252, 52,127, 52,211,211,199,179,184,181, 71, 80,138,192,214,221, 95, 31,206,198,208,104,120,189,221,139,236, 58,
-244,122,212, 68,120, 53,156,237,252,199,159,203,121,153,207,220,187,119,143,137,140,140,100,110,221,186,197, 28, 57,113,142,113,
-238, 62,174,210,186,243,200,222,205,120,116,180,133,211,108,248,240,225, 76, 90, 90, 26, 51,108,216, 48, 6,128, 89, 11, 57,207,
-102,100,100, 48, 9, 9, 9,204,170, 85,171, 24, 0,135,230,206,157, 43, 45, 47, 47,103, 6, 13, 26,148, 85, 43,176,216, 45, 9,
-167,107,219, 86, 97,163, 70,244, 93, 55,255, 63, 99, 2,223, 54, 62,223, 33, 12,156, 6, 78, 3,167,129,243,223,192,249,191, 12,
-135, 90, 87,171,110,219, 85, 47, 71, 43, 10, 80,163, 24,251,189,109,149,255,221,180,121,215,210, 61,251, 15, 45, 95,177,240, 19,
- 81,223, 62,131, 17,127,245,103,156,138, 56, 81, 37,147, 43, 54,115, 89,216,146, 80,140,234, 84, 29,161,168,157, 71,235, 53,196,
-198,198, 26, 89,182,127, 53, 7,211,211,154,185, 89,247, 53,243, 6,197, 0,102, 61,124,248,112, 75, 80, 80,208,198, 79,123,251,
-143,158,223,107, 0, 84, 42, 21,142, 28, 57,130,204,204,204,211, 0, 86,235,235,184,197,199,199, 23,121,182,119, 89,196, 97,177,
-151,207,155, 60,202,166,240, 89, 18,114,146, 99, 1, 0,114,185, 84,149,151,118,211,183, 57,129, 19, 10,133,247,108,108,108,158,
-216,216,216,148,118,108,231, 52,139, 15,206,154, 57, 19, 63,180, 45,206, 72, 65,118, 98, 77,203,168, 92, 86,173,204, 73,187,225,
-222,146,212,117,113,113,225,139, 56,152,221,104,120, 21, 50, 85,254,211,148, 46,250,240, 84,203, 21,155,214,111, 59,242,222,215,
-203, 63,226,155,154,154,226, 97,194, 83,172,217,122,172, 74,170, 80, 13, 45,138, 63,251, 78,154,199, 24,134,129, 74,165,210,123,
-160,131, 22,172,240,245,245,237,180,113,227, 70,183, 25, 51,102,224,109,157,172,250, 72,207,200, 13,105,229,228,234,249,244,201,
-195, 32, 75, 33,247,191,111, 19,159, 6, 24, 96,128, 1, 6,252,107, 48,188,214,204,153, 85,111, 27,171, 83,104,213, 33,161, 0,
-213, 0, 54,180, 99, 85,238, 91,185,113,219, 90,146,216,254, 17,205, 48, 63,171, 73,172,127, 94,140,194,183, 12, 92, 53,135, 13,
-245,123, 35, 39,179, 1,128,195,110, 89, 1, 89,139, 52, 0, 99,126,184,125,191,251, 15,183,239,127, 81,251,219,215, 0,154,213,
-150,107,194, 70, 66, 31, 79,215, 86,125,187,122, 9, 88,148, 20, 57,201,207, 80, 82, 37,195,149,196,204, 50,146, 33,127,110,110,
-160,158, 63,127,254, 7, 0,216,153, 25, 37,247,245,108,239,220,207,207,203,136, 67, 40,144,147,244, 16,229, 82, 5,126, 79,204,
- 44, 7, 65,180,184, 67,245,187, 10,111,126,252,185, 7,191,129, 24, 68, 16,196,213, 85,243, 39,241,215,110, 61,254, 78, 69, 22,
-128,234,220,220,220,226,234,234,106,171,151, 47, 95, 42,208,242, 73,226,158, 86, 84, 84,116, 94,188,120,241,134,101,203,150, 45,
-255,230,155,111,184, 45,233,147,165, 13,165,185,153,103,250,121,189,187,244, 55,192, 0, 3, 12, 48,224, 95,129, 89, 13,182,208,
- 91,104,105, 4, 67, 1, 10, 1,204,115,117,101,150,164,167, 67,241,174, 66,214,152,211,245,150,120, 0, 96, 68,139,175, 38, 9,
-201,221,180,204,202,123,105,153,149,160, 25,134,102, 24, 57, 73, 34,187, 74,169,220,148,246, 60,183,229,163,238, 8,130,122,240,
- 52, 75, 26,243, 44, 91,198,208, 52, 67, 51,140,130, 32,144,167, 82,209,155, 18,159,103,158,251, 59,132,183, 40,254,236,237, 8,
- 53,209,247,246,189,132, 37, 85, 85,202,221, 69,201,103,163,223, 97,186,168,226,227,227,167, 4, 4, 4,124, 76, 81,212, 62, 0,
-170,183,224, 82,168,213,234, 21, 97, 97, 97,167,227,227,227, 79, 70, 71, 71,139,223,133,200,250, 75,211,223, 0, 3, 12, 48,192,
-128,127, 42, 90,182,168,180, 54,188, 75,145,245,119, 68,194,211, 23,126,127, 5,111,226,211, 23,222,255, 11,225,205, 79, 62, 19,
-147, 15, 76,252,139,162,247,119,138,162,126,127,151,162,250,210,165, 75,109,209,200,178, 58,127,183,244, 55,192, 0, 3, 12, 48,
-224, 31,139, 89,218,196, 23,219, 16, 55, 6,252, 3,192,188, 43,145,101,128, 1, 6, 24, 96,128, 1, 45,128, 86, 71,139,128,246,
-145, 3, 87,155,241, 7, 45, 25,125,112,213,192,105,224, 52,112, 26, 56, 13,156, 6, 78, 3,231,191,142,243,159, 8, 7,212,116,
-136,191, 80,187,109, 82,124,189, 75, 24,134,190, 26, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,252,167,163,209,142,240, 64,
- 77,231, 97, 3, 12, 48,192, 0, 3, 12,248,171,192,175,253,180,244,184, 1, 6,252, 47,138, 45,141,224,106, 73, 31,173, 14,181,
-219,167,127, 97, 96,231, 59, 56, 56,204,242,241,241,241,224,114,185,164, 68, 34, 89,127,227,198,141,117, 13, 79,234,235,201,142,
- 97,145,104,253,234, 23, 2, 32, 88, 0, 73,130, 98,144,115, 43, 78,218,205,144,238,127,107,184, 8, 77,109,126, 35, 72, 22,143,
- 82, 43, 65,169,148,168,233,110, 85, 3,154, 86,103, 82, 74,249, 16,109, 23,219,251,142,114, 86, 83,244, 55, 0,179, 7, 32,231,
- 2,244, 94, 2,236, 57, 12,212,223, 19, 96,253, 7, 44,230, 91, 80,196,231,108, 14,107,165, 56,246,215,236,127, 66,132,133,135,
-135,179,222,230,250,113,227,198, 53,186,128,168,163,163, 99,132,145,145, 81,123,109,215, 85, 85, 85,137,197, 98,113,208, 63,252,
-121,236, 7, 96, 23, 0,175, 6,191,167, 0, 88, 4,224,218,219,254, 65, 32,192,182, 3,102,115,129,207, 1, 64, 9,124,155, 15,
-236,143,250, 27,245, 49,180,177,177,185,201,102,179,221,170,170,170,170, 36, 18,137,171,137,137, 73,186, 72, 36, 18,169,213,234,
-180,194,194,194,126,205,164,155,139, 87, 75,105, 45, 7,176,183,153,199, 13, 48,224,127, 5,111, 53,234,176, 99, 77,254,128, 64,
- 0,253,186,119,239,110, 87, 85, 85,133,148,148,148,124, 0, 55, 1, 68,213,126, 82,223, 69, 72, 73,146,252,110,219,182,109, 75,
- 23, 44, 88,160, 89, 12, 58, 46, 46, 14,190,190,111,206, 17,202, 34,209,250,198,249,171,182, 15,226, 83,209,125,208,216, 90,161,
- 69, 2, 85, 98, 4, 13,246,111,105, 16, 76, 44, 44, 44,214, 19, 4, 49,142, 36, 73,157,133, 26, 77,211, 20,195, 48,225,165,165,
-165,107, 1, 72,154,243, 71, 34, 35,190, 74, 77, 81,141,254, 7,155,197,162,170,170,229, 90,167,189,176,180,180,140, 38, 73,178,
- 93,253, 5,179,129,215, 23,208,214,118, 76,173, 86,231, 20, 21, 21,233, 35, 66, 5, 36,155,187,136, 32,184,131, 65,210, 29, 1,
- 2, 4,200, 84,154, 82, 92,161,213,202, 29, 0,100,111, 35,178, 28,156, 92,111,125,182, 58,172,117, 66,114, 10, 86,205,159,140,
-111,118, 29,194,202, 69, 31, 99,199,129, 99, 88, 52,107, 18, 60, 61,189,208,212,178,226, 52,184,155, 86, 47, 28, 55, 40,116,207,
-201, 62, 43,231,141,227,135,238, 9,239,187,106,254, 4,222,166,221, 39,251,174,154, 63,158, 31,186,251,100,159,149, 11,199, 9,
- 55,237,253,149, 6, 48,181, 37,129,156,228,230, 88, 69,168,213,141,214,182, 25, 54, 91,126, 44,237,165,232,255,226,141,158, 49,
- 99,134,143, 84, 42,125, 56,121,112,215,176, 46, 29, 91,229, 54,118, 78,113, 94,110,171,244, 39,177, 33, 28,174,208,239,195,144,
- 67,113, 77, 90, 14,124,126,187,148,148, 20, 55,154,166, 65, 81, 20,212,106,181,102,171, 80, 40,208,175, 95,191,119, 53,112,102,
- 4,128,245, 53, 47, 43, 66, 1,156,124, 11, 46, 99, 54,155,253, 25,143,199, 11, 84,171,213, 30, 0,192,225,112,146,229,114,121,
-148, 90,173,222, 6,160,178,153,124,219,115,115,115, 61,141,141,141,161, 84, 42, 53, 11,208,179, 88, 44,119,103,103,231, 61, 50,
-153,204,237,109,111,222, 14,152,221,171, 79,159, 29,211,151, 46,101, 73,111,222,196,142,131, 7,183,163,162, 2, 0,246,232,186,
-150,199,227, 93, 38, 73,210,165, 57,255, 71,211,116,166, 66,161, 24,210,156,107,216,108,182,219,203,151, 47,109, 29, 29, 29, 33,
-145, 72, 32, 18,137, 68,117,251, 45,112,178, 54, 51, 12, 35,172,205,219,119,244,236,217, 51,128, 32, 8, 53, 0,134,166,105,242,
-222,189,123,147,104,154,102,215,230, 79,155, 1, 28, 4, 32, 55,148,217, 6,252,143,186, 89, 7,154, 43,180, 34, 1, 4,118,239,
-222, 93, 56,113,226, 68, 4, 6, 6,194,205,205, 13, 2,129,160, 38, 19, 47, 46,182,123,244,232,209,248,155, 55,111,142, 63,127,
-254, 60,146,146,146,164, 0,254, 4,208,232, 75, 61, 48,184,207, 2,129, 49,127, 39, 0, 20,230, 20,139,115,158, 23,236, 20,139,
-197,155, 1,212,159, 34,220,117,234,212,169, 75, 22, 46, 92,136,136,136, 8, 28, 59,118, 12,114,185, 28, 18, 73, 19,250,165,186,
- 0,165,215,195, 0, 81, 6,144, 21, 5, 24,217, 2, 34,187, 22,199,148,133,133,197,250, 69,139, 22, 45,246,244,244,212,204, 98,
-174, 82,169,160, 86,171,161, 82,169, 80, 90, 90,138, 37, 75,150,212, 20,180, 12, 3,154,166,113,241,226,197, 5,179,102,205, 66,
-105,105,233,103,141,113,246,244,115,138, 33, 9,178,117,157, 87,195, 80, 84,206,221, 71, 57,221,212, 20,197,146,201,148,141,174,
- 84, 46, 16,112,155, 20,121, 28, 14,167,117,210,111,191,217,146, 60, 30, 24,138, 2,104, 26, 12, 77,215, 70,103,237,135,169,249,
-141,161,104, 48, 42, 10,180,154,134, 90, 42,135,255,220,185,250, 68, 69, 47, 14, 79,120,108,202,167, 75,237,123,244,236,201,105,
-227,228, 8, 53, 69,227, 89, 70,142,253,195,152,187,189,195, 15,239,153,163,144, 74, 38, 1,104,209, 60, 91, 60, 35,211,223,119,
-127,255, 67,235, 7,143, 18,112,237,198, 77, 92,189, 30, 5, 0,184,124, 35,186, 78,112,235, 76, 42,168, 43, 59, 47,154, 57,146,
- 31,182,251, 56,103,209,204, 81,172,111,118,159,224, 44,252,248, 67, 86,216,206, 99,220,133, 31,127,200, 10,219,117,140,187,112,
-230, 72, 86,232,142,159,124, 0, 88, 0, 40,213, 70,166, 45,141, 8,181,154,255,223,244,124, 22, 0, 20,238,219, 7, 85, 65, 1,
- 28,215,174, 5, 0, 76,113,181,211,187,185,195,218,218, 58,134,195,225,180,214,117,158, 74,165,210, 41,130,103,204,152,225, 43,
-149, 74, 99,212,106, 53,195,102,179, 67, 38,143,122,239,236,208,190,190,197,245,207,137,139,123,108,181,105,211,111, 35, 79, 62,
-148, 48,227,253, 76, 30, 70,124, 55,163, 91,240,178, 67,143,155, 40,144, 73,185, 92,142,180,180, 52,212, 95,228,189, 30,168,150,
-214,157, 0,236,176,178,178,234, 81, 92, 92, 60, 5,192,170,138,138, 10, 31, 22,139, 5, 75, 75,203, 85, 10,133,226,153,153,153,
-217,143,229,229,229,209,181,174,145,190, 75, 6,244, 51, 53, 53, 61,114,230,204, 25,139,174, 93,187,146, 69, 69, 69,104,219,182,
- 45, 74, 74, 74,252,111,222,188,233, 55,115,230,204,153, 18,137,100, 90,109,101, 80, 95,116, 50, 50, 50, 98,166, 79,159, 78, 80,
-212,171,219,253,233,167,159, 48,196, 91,221,222,198,220,168, 90,166, 96,202,175,165,153,253,135,203,229,254,153,153,153, 89,222,
-220,200,224, 2,159, 79, 95,186,148,101,252,226, 5,140, 31, 63,198,148,138, 10,246, 55, 53,238,150, 78,161, 69,146,164,203,145,
- 99, 63,187,241,120, 60,168,213,106,141, 24,172,203,163, 84, 42, 21,148, 74, 37, 84, 42, 21, 40,138,130, 74,169, 66,232,215,223,
-182, 56, 47, 52, 50, 50, 50,114,112,112,200, 55, 50, 50, 50,122, 23,165, 16,159,207,103, 31, 62,124,120, 18,143,199, 3, 0, 40,
- 20, 10,120,123,123, 19,134,242,217,128,127,152,216,122,195,229,106, 74,104, 13,171,168,168, 0, 69, 81, 48, 49, 49, 1,139,245,
-122,185,111,101,101,133,193,131, 7,163, 95,191,126,152, 56,113, 34,146,146,146,132, 19, 39, 78, 28,172,141,108,242,210, 96, 56,
-185,217,213, 22, 38,180,195,237, 11,143,194,126,250,234, 87,155,188,188,188,165,245, 78,155, 57,123,246,108,162,184,184, 24,227,
-198,141,187, 41,151,203, 63, 0, 80,161,141,147,162,145, 19, 52,113, 10,104,134, 16,110,187,247, 3,161,144, 73, 25,146, 36,165,
-117, 77,135, 45,137, 37,130, 32,198, 57, 58, 58,226,248,241,227, 80, 40,222,156, 46,204,212,212, 20,137,137,137,175, 92, 53, 22,
- 11, 61,123,246,100, 17, 4, 49, 14,192,103,141,115,146,173,111, 63,120, 97, 91,183, 31, 60,216,139,219,211,143,204,127,153, 95,
-197, 0, 32, 86,175, 94,173, 17,110, 0,176,126,253,122,125,194, 9,146,195, 65, 97, 84,212,171,140,152, 77,130,228, 18, 32, 56,
- 0,201,174,105, 69, 5, 3, 48, 20, 64,171, 1, 90, 5, 8, 28,156,244,137, 6,255, 86,206,110, 17,155,182,238, 53,151,171, 24,
- 28, 63,119, 13, 25, 25,207,193, 34, 73,184,182,119,195,123,253,251,114,252,186, 7, 56,125,187,110,233,249,151, 89, 79,135, 1,
-184,223,236,136,166, 25, 65,123,103,107,252,248,211, 67,216, 88, 24, 99,220,200,247, 33, 20,240,241,205,174,159,241,245,202,249,
-112,115,117,193,254,237, 27,181, 94,110,102,102,182,193,195,173,189,203,222,195, 23,224,225,238,206,218,123,228, 2, 60, 60,107,
-183, 94, 30,172,189, 71, 46,192,211,203,147,181,247,200, 5,248,120,117,106, 19, 35,190,183,161,164,164,100,190,246,248,108,144,
- 70,239,213,164, 17,167,146,214, 20, 4, 47,230,204, 1, 0,141,208,106, 14, 56, 28, 78,235,151, 47, 95,218,234, 58, 79,151,107,
- 80,235,100,197,168,213,106, 20, 20, 20, 16,101,101,101,140,185,185,249,200, 75,251, 87,157, 25,210,199,183, 4, 0, 30, 63,126,
-108, 25, 26,186,105,228,137,152, 10, 72,239,238, 38,254,251, 91, 20, 61,229,131,192,152,115, 97, 51,252, 80,187, 36, 68, 67,200,
-229,242,140, 46, 93,186, 48,181,223, 91,241,249,124,110,131,231,205,177, 67,135, 14,111,184,214,122, 52, 41,238,184,115,231,206,
-124, 79, 79, 79,184,187,187, 71,247,232,209,195, 84, 36, 18,225,210,165, 75,240,240,240,240, 50, 53, 53,189, 23, 30, 30,206, 89,
-177, 98,133,239,193,131, 7, 1, 96,129, 30,209, 57, 40, 40, 40,232,120, 68, 68,132,128,203,229, 66, 42,149, 34, 49, 49, 17,102,
-102,102,224,241,120,248,240,195, 15, 89,189,123,247,182,234,223,191,255,169,212,212,212, 73,104,198, 8, 40,153, 76,198,172, 90,
-181, 10, 70, 70, 70, 48, 50, 50,130, 72, 36,130, 72, 36,130,177, 0,196,190, 69,206,194,133, 7,202,132,159,173,221, 23,118,100,
-239,186, 27, 78, 78,244,151,217,217,217,101,205,125, 22,164, 55,111,194,248,241, 99,160,222,187,171, 47,204, 68,150, 8, 9, 9,
-209,229, 72,129,203,229,162, 87,175, 94, 58,249, 44, 45, 45, 79,179,217,236,215,106,166,106,181, 90, 16, 18, 18, 66,165,166,166,
-138, 72,146, 20,209, 52,141,144,144, 16, 74,173, 86, 11,108,109,109,163,105,154,206, 47, 42, 42, 26,173, 71,112,229, 0,150,147,
- 36,185,131,207,231,179,219,180,105,147,185,102,205,154, 59,181,110, 38, 24,134, 33,219,180,105,227, 47, 20, 10, 93,228,114,185,
- 26, 53, 77,135, 6, 55,203,128, 70,193, 48,140, 95,141, 41,172,129, 2, 0,175,246,123,113, 77,105, 7,235, 6,191, 3, 64, 81,
-109, 69,209, 78,203,126, 49,128, 36, 0,157, 0,216,214, 30,123, 64, 16, 68, 73, 11,130,169,221,209,138,136,136,208, 84, 97,131,
-131,131, 53, 5,139,137,137, 9, 30, 60,120, 0,130, 32, 96, 98, 98, 2, 83, 83, 83,152,153,153,161,162,162, 2, 73, 73, 73, 72,
- 73, 73,193,139, 23, 47, 64, 16, 4, 92, 93, 93, 81,247, 2,213,131, 38,131,251,101, 75, 4, 4,198,124, 16, 4,208,117,128, 15,
-124,250,121,163,251,253,244, 69, 49, 87,137, 3, 98,177, 56, 13, 0,219,219,219,123,102,207,158, 61,177,117,235, 86,200,229,242,
-173, 90, 68,150,134,243, 86,146,186, 27, 0, 56, 56, 56, 44, 59,122,233,153,209,212,161,237,171,197, 98,241,119, 45,136,156,215,
- 50,226,162,162, 34,189,215,226,163,105, 26,165,165,165, 77,114, 54,116, 8,182,237,216,109, 46, 41,207,199, 87,223, 28, 63, 96,
-234, 77, 0, 0, 32, 0, 73, 68, 65, 84,133, 74,165,194,210,165, 75, 65,211,180,230, 83, 86, 86,166, 87, 56, 25,138,122,211, 59,
- 32,107, 90, 79, 9, 54,224, 60,161, 70, 87,100, 29,223, 13,130, 1, 8, 10,192,155,247,213,176, 16, 18,176,184,194, 19,235,190,
-217,105, 30,155,146,131,115,215, 98,161,172,200,133,248,241,153, 26,203,177,215, 36,156,148,179,208,195,167, 61, 22,175,254,214,
-226,139,197,211, 78, 40,164, 18,119,188,222,140,120, 85,247, 75, 67,225,171, 13, 27,112, 96,231, 86,124,187,117, 39, 42,202,203,
-192,225, 88,215,102,244, 20, 40,138,106,250,222, 25,102,104,200,162,143,136,111,190, 63, 13,127, 79, 7,156,186,116, 31,125,186,
-184,224,204,239, 49,232,231,215, 22,231,174,198, 98, 64,143,246,136,140, 74,192,226,217,147,136, 73,151, 15, 14,109, 78, 26,109,
-223,190,219, 92, 82,145,143,136,141,135, 81,176,103, 15, 50,231,207,135,127,237, 57,247, 9, 2,220,214,173, 1,174,238, 52,106,
-136,228,228,100,200,229,242,198,106,251,240,240,240,208,153,238, 82,169,244,161, 90,173,102,242,243,243,137,252,252,124,136, 68,
- 34, 34, 49, 49,129,242,242,242, 30,197,164,252,250, 3, 0,132,134,110, 26,117,242, 97, 5,170,163,119, 66,122,103, 23,184,109,
-227,200, 3,235,103, 43,103,173,221,255,176,222, 59,250, 90, 56,243,242,242,134,229,229,229, 1, 0,218,181,107,151,146,154,154,
-218,169,174,169,185,182, 9,145,171, 86,171,221,234,154, 19,213,106, 53,228,114, 57, 6, 13, 26,196,106,234,222, 45, 44, 44,122,
-122,120,120, 32, 54, 54, 22, 59,119,238,180, 12, 10, 10,194,211,167, 79, 65, 16, 4, 54,109,218, 68,120,122,122,114,138,138,138,
- 48,100,200, 16,156, 62,125,186, 87, 69, 69,133,174,248, 52, 17,137, 68, 7,207,159, 63, 47, 32, 73, 18, 18,137, 4, 52, 77,163,
-119,239,222, 32, 73, 18, 9, 9, 9, 88,189,122, 53, 78,159, 62,141,179,103,207, 10,253,252,252, 14, 86, 87, 87,123,224,245,102,
-125,109,105,196,200,100, 50,134,207,231,131,207,231, 67, 32, 16, 64, 32, 16,128,199,227,161, 82, 6,204,218,150, 41,103, 9,172,
-105,175, 46,125,218,127,180,112, 19,249,221,154,143,175, 3, 56,167,239, 51, 15,212,244,201,218,241,243,207, 59,167,148,151,147,
- 0,240, 35, 65,208, 74,134,249, 86,159,247, 29, 0, 42,101,229,112,113,109,141, 83, 39,206, 98,204,132,145,141,138, 44, 14,135,
- 11, 46,135, 3, 83, 75,145, 78, 78, 46,151,107,151,146,146, 98,197,225,112,192, 48, 12, 40,138,130, 82,169,204,255,226,139, 47,
-108,134, 15, 31,110,114,241,226, 69,114,248,240,225,180,133,133, 69,213,253,251,247, 11,212,106,181, 85,223,190,125,155,243,204,
-239,245,241,241,233,122,230,204,153,143, 67, 66, 66, 98,150, 45, 91,246, 85,253,131,155, 55,111,222, 16, 25, 25,233, 50,106,212,
-168, 35,143, 31, 63,222,219,156, 60,228,109,243,121, 3,231,223,143, 83,155, 22,169,133, 29, 65, 16, 17,245,242,236,224,186,253,
-144,144,144, 85,161,161,161,137, 4, 65, 68,212,255,189,238,188,218,202, 98, 68, 99,251,181,215, 90,174, 92,185,210, 59, 44, 44,
-108, 83, 64, 64,192,241,232,232,232,231, 0,154, 43,180,154,238,163, 85,119, 67,245,111,178, 65,161,134,138,138, 10, 84, 84, 84,
- 32, 59, 59, 27,251,246,237,171,125,161, 57, 96,179,217, 96,179,217,154,254, 12,218,112, 45,226,207, 93, 0,118,117,237,218,149,
- 19,127, 39,252,226,231, 7, 22, 14,236, 54,168, 43,235,225,181,248,177,168, 89,143,112,216,244,233,211,173, 1,224,240,225,195,
- 69, 0, 46,254, 31,169,230,240,180,180,180,197, 14, 14, 14,154, 62, 42,245,155, 15,213,106, 53, 4, 2, 1,234,250,178,200,100,
- 50,236,219,183, 79,205, 48, 76,120, 19,156, 72, 77,188,142,180,196, 27, 53,215,209, 52,104,234,213,245,235,214,173, 3,195, 48,
-154,194,126, 78,173,115,162, 83,228, 53, 22,231, 76,131,109,131,223, 25,138,210,209, 60,193, 93, 56,118,218,124, 7,154, 96,227,
-183,235,143,192,225,112, 64,215,115, 51, 57,172,154,218,114,226,211,151,112,180,243,194, 7,147,102,219,159, 57,178,123,161, 90,
- 41,251,166,185,113,237,238, 19,128, 69,139, 23,227,135, 3, 7,176,122,237, 6,141, 2, 80, 83, 20,212, 58,195, 73,146,131,122,
-123, 67, 93,249, 18, 44, 22, 11, 3,252,219,131,197, 98, 97,112, 64, 71,176, 88, 44, 12,233,237, 14, 54,155,141,161,125, 60,209,
-161, 67, 7,176,217,108, 82, 71,186, 35, 53,241, 26,210, 18,255,168, 39,122, 25, 48, 0,148, 98,241, 27,231,171,196, 98, 48,206,
- 86,205,125,182, 48,115,230,204,178,236,236,108,101,195, 99, 78, 78, 78,220,155, 55,111,154,107,105,182,211, 64, 40, 20,250,177,
-217,236,135, 37, 37, 37,180,145,145, 17, 73,211, 20,237,229,229,205,186,180,127,213,153,186,115, 86,174, 92,117,102,188,159,233,
-168,163,225, 17, 12,183, 77, 31,130,224,240,213,159,174,221,207,229,112,133,126,128, 84,159,202, 3, 41,151,203,241,228,201, 19,
-232, 10, 15,195, 48, 77, 54,253,148,150,150, 78,247,240,240,184,185,107,215, 46, 75,130, 32,112,235,214, 45,176, 88, 44,205, 39,
- 61, 61, 29, 36, 73,226,243,207, 63, 87, 86, 84, 84,124,162, 43,108,108, 54,123,241,169, 83,167,204,120, 60, 30, 36, 18,137,230,
-189, 97,177, 88, 72, 73, 73,193,119,223,125,135,233,211,167, 35, 43, 43, 11,142,142,142, 88,186,116,169,113, 88, 88,216, 98,165,
- 82,185, 65,143, 36,138, 83, 40, 20,221,140,140,140, 32, 16, 8, 80, 39,184, 0,224,247, 68, 78,130, 84, 42,237,108,101, 85,109,
-111, 19, 21,241, 91,175,160, 15,124,173,108, 28, 2,196, 98,113,179,150,206,122, 6, 28,200,160,168, 47,134,157, 57, 99,123,251,
-204, 25,250,238,249,243, 57,124,137,100,191,222,207,144,138, 68,102,122, 14,252,252,252,240,240,225, 67,248,249,249,213, 23, 77,
-224,241,120,224,114,185,224,114,185,176,182,208,171, 11, 5, 67,146, 36,110,223,190, 13,138,162,160, 80, 40,160, 80, 40,224,233,
-233, 89,114,227,198, 13, 99, 0, 72, 79, 79,103,166, 78,157, 90,118,239,222, 61,116,233,210,244,122,234,118,118,118, 55, 89, 44,
- 86,155,250,191, 21, 23, 23, 91,140, 30, 61, 26,165,165,165,239,143, 30, 61,186, 79,237,251,155,251,235,175,191, 78, 5, 0, 30,
-143, 7,146, 36, 41, 24,240,175,135, 46, 45, 82, 95, 40, 53, 20, 92,161,161,161,193, 13,127,171, 47,170, 26,251, 94,255,218,176,
-176,176, 77,245,184,165, 45, 8,190,238, 62, 90, 17, 17, 17, 76, 35, 10, 82,111,232, 18, 90,117,136,141,141, 85, 57, 58, 58,254,
-144,246,232,197,192,246, 62,174, 16,138,248,239, 1,216,197,231,243,151, 76,155, 54, 13,119,239,222, 69, 66, 66,194, 79,120,203,
- 81, 56,222,222,222,151,249,124,190,139,150,102,146,204,132,132,132, 33, 90, 10,134,181,231,207,159, 71, 83,157,225,175, 95,191,
- 94,191, 80,170,223, 25,190,241, 7,131,102,160, 82,170, 80, 85, 45,125, 85,136,215, 10,173,170,170, 42, 76,152, 48,225, 53, 71,
-171,160,160, 64,231,253, 17, 4,129,239,206,157,195,149,240,112,188,239,235,139,211,247,239, 35,108,218,100,184,187,180, 2, 67,
- 17, 96, 8, 32,235,216,110, 20, 87, 84,226,151,107,183, 81, 34,169,198,148,190,125,225,102,106,221, 52, 47,135, 59,216,191,103,
- 0,247,106,116, 18, 56, 28, 54, 72,208, 96, 84,213,112,244,232, 15, 22, 73,194,204,174, 45,184, 28, 14, 56, 28, 54,210,179,139,
-224,225,221,157, 23,193, 19, 12,110,137,208,114,114,105, 11,138,162, 48,125,250,116, 28, 63,126, 28, 86,246, 46, 48,115,242,198,
-215, 91, 15,224,253, 65,125,117,222,127, 93, 13,158,205,102,131,197, 98,189,177,173,251,174,143, 59,201,208, 12,148, 13,211,136,
-102, 0,134, 65,235,141, 27,209,122,227, 70,220,175,253, 79,207,170, 42, 72,165, 82,160,135, 87,179, 68,150, 66,161, 64,118,118,
-182, 50, 47, 47,207,174,145,227,249, 10,133, 66,167,176, 57,116,232, 80,220,140, 25, 51,186, 89, 90, 90,198,196, 61,126,172,242,
-241,245,229, 92,220,183,234,108, 93,179, 33, 0,248,250,250,150,172, 90,181,234,236,212,113,193, 35,247,134, 76,164,230,110, 56,
-194,230, 11,133,221,130,151, 29,138, 59, 54,110,156,238,246, 30,185, 60,195,199,199,135,209,231,190,170,171,171,243,154, 56, 60,
- 2,192,250,174, 93,187,154, 6, 5, 5,225,230,205,155, 24, 51,102,140, 92,169, 84,166, 1,192,240,225,195, 59,254,242,203, 47,
-188,164,164, 36,216,216,216,112, 50, 51, 51, 15, 66, 71, 7,121, 30,143,215,191,123,247,238,164, 92, 46,127, 67,100,133,133,133,
- 97,210,164, 73,232,216,177, 35,104,154, 70,101,101, 37,130,130,130, 56, 59,119,238,236,175,167,208, 90,228,238,238,254, 29,106,
- 70, 29,214,207, 11,147, 81,211,172,133,226,226,226,188, 71,247,174, 37,246, 29, 52,186, 91,155, 14,222, 14, 9,113, 15,155, 36,
-180,181,181, 93, 73,146,228,120,154,166, 89, 21, 21, 21,217,143, 20,138, 14,158, 46, 46,118,189, 71,142, 68, 57,135,195,218,113,
-237, 26,153, 47,145, 24, 3,208,171, 9, 82,166,170,130,139,107, 77, 87,191, 49, 19, 70,226,225,195,135, 24, 59,113, 20,184, 92,
- 46,216,108, 78,205,187,201,173,113,180,204,173, 77,245,122, 54, 85, 42,149, 38, 15,175,235,231,165, 84, 42, 81,215, 53,203,200,
-200, 72,115, 76, 46,151,131, 32,136,166,158, 13,183,147, 27,214,216, 10, 77,205, 64,169, 84,240, 26, 57, 86,243, 76,223,251,113,
-175, 16, 52, 45, 44,203,204,192,130,240,243, 28, 24, 96,128, 22, 87,171, 41, 45, 82, 95, 40,189, 45, 8,130,136, 8, 9, 9, 89,
- 5,128, 9, 9, 9, 89, 85,183, 31, 26, 26, 42, 5,144,219, 66,177,245,134,203,197,126, 23, 34,171,174,121,161, 41, 4, 5, 5,
- 45, 48, 49, 49,217, 89,183,159,125, 55, 23,217,119,115,225,209,201,171,119, 87,223,110,229,147, 38, 77,130,149,149, 21,150, 45,
- 91,198, 0,248,169,185,255,159,158,154,104, 12,128,113,112,112, 88, 86,155, 33,251,222,191,127,223,230,193,131, 7,232,222,189,
-251, 43,235, 94,169, 68,159, 62,125,154,162,146,212,118,106,255,236,221,185,100, 52,148, 74, 37,170,171,165, 80, 40,148, 80,171,
-104,168,213,106,248,121,153,224,200,129,144,154,223,212,117,238, 89,141,107,214,218,222, 4, 38,198, 28, 21, 73, 18,210,152,184,
-188, 70,115, 76,133, 66,129,184,204, 76, 60,126,241, 2, 0,240, 65,104,211, 29, 95,143, 92,187, 9, 79, 79, 79, 93,161,109,223,
-218,209, 30, 47,175,196,213,100,222,210,108, 60,248,243, 36, 76, 76,140, 1, 0, 94,129, 83,192,229,214, 8,173, 42,169, 18,214,
-157,156, 64, 48,140,214,105, 1,140, 44,236, 47,179,185, 2, 23,134,162,193, 48, 52, 24,154, 2,195,208, 96,113,184, 70, 11,230,
-124, 12,154,166,224,239,239, 15,130,197, 2,165,146, 99,220,136,193, 40, 45,151,192,202, 92,191, 66,130,203,229, 34, 48, 48, 80,
-168,237,248,211,167, 79,165,245,133, 89,211,105,164, 66, 85,149, 20,114,185, 28, 74,133, 26, 74,149, 26, 84, 59, 46,190,250, 98,
- 50,212, 74, 53,170, 39, 6, 64,169, 82,131, 94, 60, 10, 74,133, 10, 89, 70, 36,233,227, 97,173, 34, 65, 72, 31, 37, 23,154,234,
- 18, 90,117,226, 64, 27, 26,235, 19,168, 69,108, 61,158, 49, 99,134,159,143,175,239,195,241,131,124,183,196, 39, 36,190,140, 79,
- 72,124,227, 60,151,142,190, 25,115,195,142, 47,229,112,133,126,193,203,154, 30,117, 88, 31,245,155, 17,223, 18,171, 36, 18,137,
-143,177,177, 49, 82, 83, 83,193, 98,177, 64, 16,196, 83, 0, 62, 0,224,224,224,240,140,205,102,187,178, 88, 44,236,217,179,135,
- 96,179,217,157, 3, 2, 2, 86,201,100,178,147, 77, 84,232, 60, 76, 76, 76, 94,115,179,184, 92, 46, 66, 66, 66, 48,117,234, 84,
-141,200,226,114,185, 56,116,232, 16,186,117,235, 6,133, 66,225,161,103,120, 31, 0,232,171,135,227, 71,212,138,115,157, 98, 84,
-173, 86,207, 40, 30, 63,190, 3,162,162,208,219,213,213,211,207,207, 15, 74,229, 43, 67,211,213,213,213, 73, 34,145,228, 73,165,
-210,255,162,102,106,131, 71, 77,138, 34, 25,141,204,244,154,238,167, 15, 31, 62,132,191,191,191,198,193,170,239,102,113,185, 92,
- 8,121,198,205, 18, 90, 52, 93,147, 47, 73, 36, 18, 50, 42, 42,202,218,221,221,157, 0, 0,119,119,119,226,209,163, 71,150, 70,
- 70, 70, 69,237,219,183,215, 89, 1, 22,154,154,225,208,140, 9, 0,128, 47, 7, 13,213, 84,140, 46,173, 95, 5, 14,135,131,129,
-203, 86,189,241,220,211, 52,205,130, 1, 6,145,165,135, 22,121, 87, 34,171,161,163, 21, 26, 26,154, 24, 26, 26,250,134, 59,214,
- 76,232,118,180,234, 91,119,205, 69,221,203,170, 13, 91,183,110, 69,231,206,157,155, 44,136,118,238,220,137,163, 71,143,110, 5,
-144,222,108,203,113, 96, 87, 47,108, 59,147,232,218,209,139, 0,128, 13,139, 71,144, 85, 85, 85,184,125,251, 54,204,204,204,240,
-244,169,222,211,126,153,152,153,153,173, 39, 73,114, 28,171,225, 8,128,198, 5, 38, 69,211,116,120,121,121,185,214,233, 29, 24,
- 6, 80,170,212,168,170,150, 65,161, 80, 96,241,231,187,117, 6, 34, 20, 32,148, 10, 9, 59,176, 95,128, 80,155,163,227,223,185,
- 63,230, 77, 51,126,163,240,102,145, 0, 73, 2, 93,252,107, 28,151, 71,247, 19, 65,211, 0, 69, 3,214,182, 22,248,233,216,150,
- 38, 69,190,154,162,107,107,199, 20, 42,229, 20, 60,122, 6, 35, 39, 57, 74,227, 32,241,184, 53, 77,198, 92, 14, 7, 52, 67,212,
-204,250,160, 77, 8,241,132, 46,165,226,116,183, 3, 17,241,152, 21,220, 25,191, 94,141,195,216, 65, 62,184,113, 47, 9, 65, 61,
- 60,145,152,246, 2, 94,110,109,176,231, 96, 56, 24, 6,146,239,183,125,157,247,170, 64, 83,103,234,227,104,221,189,123, 87,218,
-208,197,170,191,101,116,151,135, 96,152, 87,142,150, 84, 38,199,178,149,122, 77,231, 83,147, 70,125,123, 10,245, 57,185, 41,199,
- 74, 31, 33,214,208,217,130,142,233, 89,218, 1,232, 6,172,248,191,204, 56, 41,138,194,133, 11, 23, 52,233,209, 88, 58,214, 79,
- 59, 61, 68, 14, 50, 51, 51,145,152,152,136,158, 61,123,162,188,188, 28, 28,146,196,210,248,120,120, 78,155, 6, 5,151, 11,154,
-166,193,227,241, 48,123,246,108,189,227,179,153,185,115,109,103,110, 74, 23,249,150,128,128,128, 14,169, 85, 85, 72, 76, 73,193,
-160,117,235, 0, 0,145,145,145,175, 61, 19, 75,150, 44,225, 37, 37, 37,205,140,137,137,153,249,242,229,203,173, 0,150,106,205,
-103, 25,185,166,143,214,248,201, 99,208,193,189, 29,142,254,124, 76,115,124,201,242, 69,224,112,184,224,112, 57, 48, 55, 51,215,
-235,110, 84, 42,149, 70,180, 86, 87, 87,147,145,145,145,173, 7, 15, 30,204, 93,180,104, 17, 1, 0, 71,143, 30, 37,119,237,218,
- 37,186,114,229, 10,183, 85,171, 86, 98,157,226, 82,169,124, 35,141, 9,130, 0,135,195, 1,151,199, 5,104, 26, 4, 65,136, 54,
-111,222,188, 33, 49, 49,177,187,187,187, 59,228,114,249, 52,212, 12,212, 48,204,163,101, 16, 91, 77,106,145,198,250, 90,213,186,
- 82,218, 80, 88,191,223,150, 54,161, 86,191,207, 22, 90, 54, 40, 67,191, 62, 90,141,129,197, 98,233,116,171, 72,146,212,217,116,
-184,100,201, 18,152,152,152,104, 43,128,152,248,248,248, 36,177, 88,124, 0,192,238, 22, 37,206,181,216,196,245,159,141,146,160,
-182,109,213,220,220,188,104,192,128, 1,149, 0,148, 39, 79,190, 94, 65,150,203,229, 90, 11,112, 51, 51,179,245, 63,254,248,227,
-194,145, 35, 71,146, 13,167, 24,168,223,188, 87,247, 81,169, 84, 56,121,242,228,194, 21, 43, 86,160,188,188,252,179,166, 10,241,
-234, 42, 41,164,181, 29,161,159, 37,252,170,111,166,174,245,144,177,185, 3, 90,183,243,209, 90,152,144,220,154, 62, 68,118,206,
-175, 10, 48, 19, 19, 1,168, 38, 56, 9,130, 76,127,145,245,178,149,147,189, 37,158,101, 23,194,174, 77,103,148,230,190,138, 7,
- 54,155, 5, 78,109,211,161,185,169, 8,133, 5, 5, 32, 73, 86,147,194,248,235, 95, 98,113, 47,225, 5, 78, 93,125, 4,165,172,
- 10,219, 14, 95,130, 82, 94, 9,165,172, 10, 74, 89,205,118,211,138, 79, 65, 16,200, 83,201,171, 58, 54, 39,221,217,108, 54,122,
-244,232,161, 85,232,228,230,230,234,233,104, 49, 26, 71, 75, 42,107,102, 26,233, 87,115,106,210,177,170, 59,222, 82, 97, 80, 55,
-229,131, 80, 40,236,118,232,144,246,105, 28, 26,131,189,189,253, 69, 99, 99,227,182,250,158,223,140,201, 75, 55,153,155,155,175,
-119,119,119,247,216,182,109, 27,135,197, 98, 97,224,192,129, 29,237,237,237, 51, 1,192,203,203,203,177, 46,143,153, 59,119, 46,
-115,247,238,221,132,154, 58,134,118,240,120,188, 20, 51, 51,179,110, 65, 65, 65, 40, 47, 47, 71,118,118, 54, 68, 34, 17, 60,183,
-108, 65,252,220,185,240,221,183, 15,228,128, 1, 32, 8, 2, 60, 30, 15,241,241,241, 16, 10,133, 41, 50,153,214, 41,223,122, 0,
-248, 22, 64,111,188,106, 46,100, 0,220, 70,205,180, 11,247, 26,201,239, 72, 0,160,104, 90, 87, 98, 77, 94,182,108, 25,202, 56,
- 28, 96,248,112,112,211,211,161, 84, 42,209,179,103, 79,141,203,222,179,103, 79,176,217,108,248,248,248,192,209,209, 17,123,246,
-236,153,220,148,208,146, 85, 42,145,153,158,131,128,128, 0,141,115, 53,124,248,112,141,163,197,225,112, 52,206, 22, 65,233, 22,
-174, 4, 65, 48,245, 43,201, 20, 69, 17,108, 54,155,253,217,103,159, 17, 99,198,140, 97, 20, 10, 5,205,227,241,200, 83,167, 78,
- 17, 55,110,220, 96, 87, 85, 85,233,172,136,123,143, 26,135, 47, 7, 15,171,121,247,219,218,128,195,229,128,199,229, 98, 89, 74,
-142, 38, 93, 76, 15, 29,231,133,133,133,141,117,119,119,175,105,134, 7,216,134,121,180, 12,208, 97,244, 20, 54, 16, 73,138,122,
-251,133, 0,136,218,253,194,122,130,170,144, 32,136, 7, 12,195,116,111,112,110,221,113, 69,131,109,221,241,199, 45, 8,126,221,
- 90,135,111,136,175,166,106,196,105,119,238,220,113,243,243,243, 67, 86, 86,214, 27, 35,225,234, 10, 46,145, 72, 4,161, 80,136,
-232,232,104, 0, 72,211, 70,118,227,198,141, 93,168,153,117,185, 38, 68, 14, 14, 1, 65,227,251, 71,251, 15,237,142, 95, 66,143,
-149,139,197, 98, 31,188,154, 67,135,112,116,116,156,202,225,177, 39,184,122, 59, 7,130,166,191,189,118,254,246,186,166,238,208,
-181,163, 87, 37, 0,105,221,168,195, 22,142, 62, 4, 73,146,227, 70,142, 28, 73, 38, 37, 37, 97,194,132, 9, 56,122,244,168,214,
-115,167, 78,157,138,227,199,143, 99,228,200,145,228,202,149, 43,181, 78,239,240,186, 91,162,120,103, 15,101,234,211,199, 56,114,
-252, 71,173,125,144,108,109,107,250, 99, 21, 20, 20,105,126,235,238,215,116,203, 8,173, 86, 92,137,141,185, 31,208,171,223, 64,
-110,118,126, 25,104,181, 28, 50,201,171,235,171,203,242,193,168,101,224, 26, 89,194,222,218, 12, 15,239,252,174, 80, 42,100, 87,
-154,226, 92, 56,210, 11,115, 71,120, 0, 12,141, 81, 75,127, 66,196,238, 5,154, 26,116,159, 49,139,112,237,228, 14,189,251,248,
- 53, 4,135,195, 65,124,124,188, 84,155,155,197, 98,177,244,153,147,171,214,117, 84,161,186, 90,138,106,169,236, 93,230, 29, 54,
-118,118,118,223, 91, 88, 88, 8,180, 8, 41, 27, 27, 27,155,239,173,172,172, 4,250, 54, 29,106, 19, 89,181,243,106,197,204,152,
- 49,163, 89, 98,139,207,231,183, 77, 75, 75,211, 76, 86,218,212, 86,161, 80, 32, 40, 40, 72,223,201, 75,207, 3,120,238,224,224,
-112,219,211,211,211,236,217,179,103, 56,118,236, 24,151,195,225, 56,215,229, 31, 18,137, 4, 44, 22, 11, 5, 5, 5, 42, 0, 31,
- 67, 71,211,153, 92, 46,143,138,138,138,234, 50, 98,196, 8, 86, 74, 74, 10, 88, 44, 86, 77,184, 2, 2,224,187,111, 31, 18, 62,
-251, 12,129, 47, 94, 64,166, 84, 66, 32, 16,224,242,229,203,202,234,234,234, 40,109,124, 66,161,240, 64, 70, 70,134,151, 64, 32,
-128, 82,169, 4, 77,211, 32, 73,146, 96,179,217,125,204,205,205,119, 2,232,222, 32,177,108,125,187, 7,117,162,212,106, 74,156,
-245,172, 80, 87, 4, 20, 23, 23,227,252,249,243,232,217,179, 39, 2, 3, 3,145,155,155,139,244,244,116,188,255,254,251,154,115,
- 30, 63,126,140,216,216, 88,180,111,223, 94,183,163, 71,170,208,190, 83, 91,112,185,220, 26,135,136,195,173,173,248,112, 52, 78,
- 22,151,195, 5,135,205,129, 64, 40,208,219,209, 34, 8, 2, 36, 73,130, 32, 8, 8,133,194,186, 74, 54,221,186,117,107,113, 73,
- 73,137, 3, 0,150, 80, 40, 4, 69, 81,122, 85, 90,234,202,136, 58,145,197,229,113, 53,206, 22, 0,148,149,149,201, 70,142, 28,
-249, 95,185, 92,254, 17, 90,182, 66,137, 1,255, 50, 16, 4,241,224,255,226,218,102, 96,120,173,176,122,163, 83,124, 83, 15,248,
-251,189,122,245,218, 55,105,210,164,129,219,183,111,135,177,177, 49,196, 98,177,166, 64,228,241,120,112,114,114, 66, 73, 73, 9,
-246,239,223,143,156,156,156,235, 0,102,235, 27, 34,177, 88,124,247,233,163,180,226,160,177,189,172,188,122,117, 50,207, 78,203,
-233, 41, 22,139,163,107, 69,214, 79,147,150,188,255, 81,208,104,127,112,121, 28,100, 63,205,195,181,243,183,255,191, 36, 38,139,
-197, 98, 17, 4,129, 9, 19, 38,232,117,254,196,137, 19, 17, 21, 21,133,166,154, 25,233, 58, 71,171, 90,134, 42,233,187,171,172,
-205, 91, 48, 21,243, 22, 76,213,136, 9,125,154, 94, 0,192,209,241, 68, 19, 66, 75,185, 61,226,196,254, 89, 93,253, 3, 92,186,
-121,181,197,189,152, 71,248,101,223, 43,147,225,224,174, 13,248,230,224,117, 56,217, 89, 64, 41,175,194,197, 95,127,200, 83,202,
-171,183,183,208,148,171, 17,183, 4, 1,134,161,155,117,239,117,226,137,195,225,192,219,219, 91,171,163, 85, 82, 82, 34,213, 85,
- 48,104,210, 72,161, 66,101,149, 20,210,234,119, 38,180,124,251,244,233,115, 37, 60, 60,220,202,214,214, 22, 47, 95,190,108, 40,
-180,124,123,247,238,125, 37, 60, 60,220,202,206,206, 14,217,217,217,122, 79, 43,210,136,200, 66, 97, 97, 33, 81, 90, 90, 74, 91,
- 88, 88, 52, 75,108,145, 36, 9,185, 92,142,228,228,100,125,255, 86,239, 17, 98,102,102,102,135,142, 31, 63,110, 86, 84, 84, 4,
- 22,139,133,228,228,228,215, 70, 29,214,125,126,250,233, 39,238,168, 81,163,126, 44, 43, 43,107,114, 88,155, 90,173,222, 58,117,
-234,212,153,185,185,185, 22,182,182,182, 16,139,197,224,241,120, 96, 24, 6, 68, 80, 16,250, 62,127, 14, 37, 69, 65, 40, 20, 34,
- 53, 53, 21, 7, 14, 28,168,170,157, 42,166, 81,131,140, 32, 8, 55, 46,151,139, 41, 83,166,188,118,224,240,225,195,248,160, 27,
-171,155,141, 25,187, 82, 13,129, 60, 95, 56,236, 34,139,197, 34,124,123, 12,232,216,163,223,112,239, 39, 9,247,158, 21,230,231,
-232,202,148, 84, 10,133, 2,238,238,238,120,240,224, 1,174, 94,189,138, 1, 3, 6, 32, 48, 48, 16,113,113,113,248,253,247,223,
- 17, 27, 27, 11,130, 32, 96,101,101, 85,215,253,162,201, 62, 24,138,106, 53, 10, 94, 22,191,225, 94, 53,220,231,114,185,144, 75,
-149,122,165, 81, 74, 74, 10, 30, 60,120,160,153, 90,134,197, 98,169,167, 77,155, 6,134, 97,152,140,140, 12,152,152,152, 48, 51,
-102,204,160,216,108,182, 58, 55, 87,191,254,193,117,162,170, 78,100,177,185,156,215, 4, 26, 77,211,146,184,184,184, 89, 0,226,
-106,157, 44,192, 48,143,150, 1,255,219,184,128, 55, 23,150,214,233,104, 61, 7, 48,232,216,177, 99,147,207,158, 61,187,117,231,
-206,157, 54,193,193,193, 40, 45, 45,133,139,139, 11, 28, 28, 28, 16, 17, 17,129,200,200,200, 34,138,162,150, 2,104,204,250, 25,
-132, 38,230,172,201,125, 38, 14,151, 87, 86,206,245, 11,244,192,245,147,183, 66,237,237,237,103,179, 88,172,197, 51, 86,125,248,
- 81,255,145,221,145, 26,155,129,187,191,199, 35, 63,171, 72, 39,103,195,206,240,230,230,230, 51,141,140,140,120, 0,148,141,212,
-138, 27,142, 58,212,112, 82, 20, 69, 41, 20, 10,156, 56,113, 66, 47,177,117,236,216, 49,200,100, 50, 80,111,182,175,106, 56, 25,
-154, 33,216, 28, 62, 28,157,220,161, 84, 86,129,166, 91, 60,160, 82,195, 89, 87, 3,125,198,227,193,182,168, 8,247,238,221,211,
- 79,114, 15, 31,174, 43,141,100, 10,153,100,202,142,141,203, 34,230,135,124,107, 62,160, 87, 23,124,185,229, 48,148,202,131, 32,
- 89, 36,132,124, 46,252,252,123,131, 5, 57,190, 15, 91, 94, 86, 93, 81, 58, 5,111, 46,197,243, 26, 39,211, 84, 11, 11, 3, 80,
- 52,141,171, 55,239,235,125,239,154,210,158,162,192,102,179,241,244,233, 83,105, 99,163, 13, 89,172,154,102,206,186,154,122, 83,
-156, 12, 77, 19, 28,174, 0, 78, 46,158, 80,200, 43,223, 73, 26,217,218,218, 46, 63,115,230,140, 85,221, 84, 9,113,113,113, 32,
- 8, 34,249,149,227, 88,115, 92, 42,149, 34, 33, 33, 1,113,113,113, 64,205, 8, 55,189,223,163, 58, 39,171,176,176,144, 16,139,
-197, 48, 50, 50, 34,227,226,226,228, 62, 62, 62, 49, 58,222,111, 13,167, 76, 38,123,161,173,255,164, 76, 38,107, 37, 16, 8, 56,
- 13, 10, 81,199, 14, 29, 58,164, 54,210,132,248, 70, 56,203,203,203,239,173, 88,177,194,111,232,208,161, 88,190,124,121,137,133,
-133,133,201,247,223,127,207,102,177, 88,196,252,249,243,169,130,130,130,202, 31,126,248,193,236,236,217,179, 40, 43, 43,139,214,
-227,222, 37, 50,153,108, 86,175, 94,189, 14, 95,186,116,201,200,205,205, 13, 21, 21, 21, 96, 24, 6,135, 14, 29,194,252,249,243,
- 33, 16, 8,144,154,154,138, 15, 62,248,160,186,186,186,122, 22,222,236, 59, 89,199, 73, 16, 4,193,208, 52,141, 53,107,214,104,
- 38, 39,173,155,172,212, 68, 72,224,192,146,118,162, 69, 63,148,139, 38,127,249,195, 52, 0,160,212,106,234, 73,194,189,103,135,
-118,127,121,131,203,229,222,212,145, 70,171, 23, 45, 90,244,253,240,225,195,133,198,198,198, 40, 41, 41,193,237,219,183,113,231,
-206, 29,220,189,123, 23, 10,133, 2, 86, 86, 86,176,176,176,128, 88, 44, 70, 74, 74,138, 20,192,234,166, 56,121, 70, 28,184,118,
-172, 27,249, 91,227, 96,113,234,141, 54,172,239,110,113, 57, 28,189,222,163,126,253,250,161, 71,143, 30,117, 2,136,202,204,204,
- 20,203,229,114,162,158,232,207,173, 19,228,206,206,206,234,163, 71,143, 50, 77,113,222, 61,176, 7,151,190, 90, 13, 30,151,139,
-165,201,217, 26,209,117,120, 64, 87,112,120, 92,120,140, 24, 83,255,218,189,168,105, 46, 68, 3,145,213, 84,217,241,214,239,166,
-129,243,111,203,249,191, 12, 49, 90,176, 4, 79, 29,126,145,201,100, 23, 63,253,244,211, 48, 95, 95,223, 79,183,109,219, 70,112,
-185, 92,172, 91,183,142,121,249,242,229,207,181,181,144,210,150,132,138, 97,152,159,255, 56, 29, 61,103,122,200, 72, 98,201,246,
- 25,125, 98,174, 37,164,116,238,229,134,206,189,220, 16,115, 61, 9,187, 87, 29, 59, 74,169,168, 53,121,121,121, 89, 58,168,228,
-131,122,119,106,216, 25,222, 42,234,198, 53,171,230,142, 58,164,105, 58,252,216,177, 99, 11, 71,143, 30, 77,222,191,127,255,141,
- 62, 89,117,203,238,208, 52,141, 43, 87,174, 64,169, 84,226,231,159,127,166,105,154,214, 62,143, 22,152,115, 59,182,135, 77,255,
-249,200, 57, 30,143, 75,224,206,205, 83, 40, 47,109,122, 84, 23,151,203,193, 79,135, 78, 43,185, 92,206,147,198,142, 43,149,202,
-236,107,215,174,217, 13,161, 40, 14, 73,146,141, 9,168, 70, 17, 30, 30,174,162,105, 58, 83,199,105,209,249, 57, 89, 35,190, 94,
-254,241,177,225,227, 63,181,235,213,171, 15,199,218,214, 14, 4, 65,160, 32,191, 0,169, 9,247, 85, 23, 79,253,152, 95, 85,173,
-223, 18, 60, 31,127,247,135,166, 79, 22, 0, 4,207,223,169,233,159, 5, 0, 35,102,172, 64, 80, 79, 47, 16,250, 88, 79,175, 68,
- 22,173, 86,171, 33, 18,137,160, 86,171, 27,157,226,193,204,204, 76, 40,147,201,164,181, 19, 49, 54,105, 21, 49,192, 59, 79, 35,
-138,162, 60, 74, 75, 75, 81, 85, 85,133, 59,119,238, 48, 27, 55,110, 44, 44, 44, 44,212,116,218, 84,169, 84, 30, 37, 37, 37,168,
-172,172, 68,116,116, 52, 19, 22, 22, 86, 88, 92, 92,188,170, 57,239,144, 80, 40,236,198,102,179, 99, 74, 75, 75,105, 35, 35, 35,
- 82,165, 82,169,124,124,124,248, 66,161, 80,239, 5,213,197, 98,241, 80,109,199, 92, 93, 93,211,210,210,210, 58, 80, 20, 85,127,
- 13, 68,174, 76, 38,115,235,213,171,151, 62,249,199,162,131, 7, 15,226,244,233,211,254, 21, 21, 21, 83, 51, 51, 51, 15, 3,240,
-103,179,217,120,244,232, 81,178, 76, 38,155, 52,122,244,232, 67,165,165,165,247, 80,179, 4,143, 62,184,148,154,154, 58,197,195,
-195,227,224,250,245,235,141, 3, 3, 3,217,142,142,142,232,222,189, 59, 82, 83, 83,113,225,194, 5,213,222,189,123,171,170,171,
-171, 63, 6,112,165,233,100, 7,161, 86,171,193,227,241, 52, 31, 62,159, 15, 46,151, 11,137,148,193, 39, 91,210,165,106, 8,165,
- 91,215,205,186,192, 0, 68, 94,118,122, 81, 65, 94,246, 61,130, 32,110,138,197,226,114, 45,113,198,147,201,100, 93, 24,134, 97,
- 17, 4,177, 93,169, 84,206, 88,176, 96,129,195,166, 77,155,208,169, 83, 39, 20, 21, 21, 65, 36, 18,193,205,205, 13,133,133,133,
-184,127,255, 62, 85, 93, 93,189, 15,192, 6,212,246, 31,209,134,178,162, 10,180,182,119,126,205,249,100, 24, 6, 12, 5,168,228,
- 20, 40, 37, 3, 5,161, 2,135,163, 2,151,203,213,199,121, 98,104,154, 70,169,131, 3,232,132, 4,220,189,123, 23, 12,195,104,
-117,213,220,221,221,245,200,216,105,240,248,188,215,154, 11, 9,130, 0,151,199, 3,135,199,109,108,228,140,193,197, 50,224, 31,
- 13,125,219,198,203, 0,204,126,252,248,241,225,254,253,251, 71, 48, 12,195, 65, 77,123,228,173,183,249,243,188,188,188,135,209,
- 23, 30,174,180,107,109, 17, 54,108,106, 31,116,234,226, 2, 74, 77,225,118,228, 35,252,188,233,236,241,220,236,220, 25,208, 99,
-237, 51,154,166,111,244,238,214,137, 68,189,185,186, 29, 29, 29,233,150,140, 58, 44, 47, 47, 95,187,116,233, 82, 44, 95,190,188,
- 37,163, 14, 27, 69,124, 74,225,108, 2, 76,235, 17,195,250, 14, 1, 65, 50, 10,133,188,137,140, 15,154,153, 75,185, 92,206,147,
- 7,113, 98,159,198,206, 43, 44, 44, 28,242,209, 71, 31, 93, 97,179,217,109,155, 19,231, 52, 77,103,230,231,231, 15,212,125,166,
-250,182, 92, 90,225,118,254,248,254,207, 46,157, 62, 56,132,166,169,246, 4, 0, 22,155,251, 76,165, 84, 94,150, 75, 43,182, 65,
-207, 69,165, 55,207, 14,192,162, 29,191, 99,207,242, 17, 88, 16,118, 18, 63,174,249, 4, 43,183, 28,195,183,203, 23, 97,227,206,
-255,226,203, 69, 83, 48,118,242, 71, 52, 67,144,127,234,123, 31, 44, 22,235,210,254,253,251,167,127,242,201, 39,154, 65, 11, 12,
-195,188,150,177,171, 84, 42, 41, 77,211,216,183,111, 31, 13,224, 82, 83,124,175,167, 17,193, 52,213, 95, 74,223, 52,170,168,168,
-248, 56, 32, 32,224, 16, 0, 62,195, 48, 79, 75, 75, 75,255, 3,188, 90, 26,170,178,178,242,227, 94,189,122, 29, 98, 24,134, 79,
- 16,196, 27,199,245, 65,237, 84, 15,221, 44, 44, 44, 98,106,157, 44,126, 75, 58,196, 55, 21,213, 77, 52, 43,234,211,132, 72, 3,
- 88, 80,111,198,247, 77,254,254,254,245, 23,149, 78, 46, 45, 45,237,214,130,112, 93,145, 74,165, 94,107,214,172,249, 76, 32, 16,
- 4, 85, 87, 87,119, 4, 0,145, 72,148, 42,151,203,111, 72,165,210,109,208, 61, 55,149,130,166,233, 84,181, 90,237,109, 99, 99,
- 83, 51,162,182, 86,108, 1,192,111, 49, 84, 12, 64,117,175, 49,197,127,209, 59, 96,145,145,145,109, 44, 44, 44,222, 35, 8, 98,
- 44,195, 48,238, 18,137, 68,190,102,205,154,232,240,240,240,242,182,109,219, 14, 27, 62,124, 56, 97,105,105,137, 7, 15, 30, 48,
-197,197,197,167, 0,172,130, 30, 35,173,105,154,206,220,188,121, 51,154,251,190, 55,117, 92,169, 84,230, 69, 70, 70, 90, 15, 45,
- 40, 96,211, 52,141, 17, 35, 70,188, 38,224, 26,226,201,147, 39,144,203,229, 77, 78,230, 40, 47, 47,197,128,207, 86, 0,181,163,
- 63,235, 80,227,100, 49, 96, 20, 6, 93,101,192,191, 11,127,245,130,158,122, 89,139, 14, 14, 14, 19, 4, 34,254, 60,151,142, 14,
- 62, 47,211, 11,146, 36,229,213, 71,197, 98,241,126, 45, 25,185, 94,156,205,156,176,212, 96,255,254, 69,156,175,230,209,162,192,
- 48, 20, 24,154, 1,195,208,160,105,170,102,193,107,134, 6, 67, 81, 4, 65,224, 79,133,180,201,153,193, 27,134,211,194,218,218,
-122, 3,195, 48, 67, 89, 44, 22, 89,223, 12,171,255,189,214,201,186, 84, 88, 88,248,101, 35,206,235,255, 92,124,134,135,135, 55,
- 42,254,245, 29,117, 56,110,220, 56,170,153,239,230, 13,145, 72,228,208,216,177,170,170,170, 44,177, 88,252,222,223, 36, 62,235,
-143, 24,108, 14,103,179, 71, 29,234,226,116,113,113,225, 43,149,202,174, 0,220, 8,130, 48, 7, 80,162, 84, 42, 47, 23, 21, 21,
-229, 3,232, 6, 96, 77,237, 53, 95, 1,136,249, 63,126,223,133,214,214,214, 7, 73,146,108,173,207,197,106,181, 90, 81, 82, 82,
- 50,189, 65,133, 64,195,105,101,101, 21,195,102,179, 91,235,193,147, 83, 92, 92,220,205,144,127, 26, 56,255, 65,104,216, 9, 94,
-235, 76,241,127,133,208, 50,112, 26, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,252,167, 11,173, 70,247, 13,195,106, 13, 48,
-192, 0, 3, 12, 48,192, 0, 3,222, 14, 23, 26,136,173, 11,117, 95,136, 38, 84,105,115, 44,193,150, 40,219,171, 6, 78, 3,167,
-129,211,192,105,224, 52,112, 26, 56,255,117,156, 6,188, 67, 24,108, 85, 3,167,129,211,192,105,224, 52,112, 26, 56, 13,156,255,
-116,104,109, 58, 36, 13,113, 99,128, 1, 6, 24, 96,128, 1, 6, 24,240,215, 64,111,161, 37,178,115,247,176,118,241, 57,100,209,
-186,115,156, 69,235,206,113,214, 46, 62,135, 68,118,238, 30,255,210,120, 19, 2,152,204,102,179,175,216,219,219, 87, 64,203,210,
- 59,255, 0,152, 2, 24,139,154,249,125, 70, 1, 48,122,151,228,129, 0,123, 2, 48,111, 26,144, 53, 13,200,154, 0,204, 11,252,
- 7,246, 27, 92,183,208, 33,224,230,197,201, 23,215, 45,116, 8,104,244,248, 82, 7,171,187,191,143,219,177,105,158,163,229, 59,
-250, 75, 19, 91, 91,219, 3,118,118,118, 47,108,109,109, 51,109,109,109, 15, 2, 48, 51,100,119, 6, 24, 96,128, 1,127, 25,234,
-250,104,213,125, 52,125,180,216, 0, 16, 17, 17, 17, 8,224, 15, 0,253,131,131,131,163, 26, 94,109,225,236,253, 73,251,118,237,
-151,127,189,110, 21, 97,111,107,109,164,166,104,101,198,139,108,207,181, 95,135,253,250,146,199,222, 90,154,149,240, 99, 11, 2,
- 69,176, 88,172, 9,124, 62, 63, 24, 64,157, 96, 75,150,203,229, 17, 20, 69,157,128,126,195,180, 97,103,103,119,147,197, 98,181,
-105,206, 31, 83, 20,149,149,159,159,223,167,133,145, 57,206,217,217,249, 96, 96, 96,160,145,191,191, 63,120, 60, 30,214,172, 89,
-179, 84, 44, 22,111,211,151,192,194,194,213, 68,201, 23, 44,102,243,120,131, 25,149,194,155, 1, 3,144,252, 4, 90, 45,191,198,
-149,203,183,150,150,166, 75,244,164, 90, 5, 96, 70,109, 92,253, 8, 96,243,219, 60, 37,211,187, 64,165,162,106,158, 9, 46, 27,
-212,185,231,102,127,172, 94,189,154, 29, 28, 28,140, 31,127,252,177,207,129, 3, 7,102, 73, 36,146,107, 0,126, 3,240,236,109,
-159, 74, 59, 96,118,175, 62,125,118, 76, 95,186,148, 37,189,121, 19, 59, 14, 30,220,142,154,249,150,246, 52,247, 89,226,114, 49,
-214,218,154, 19,204, 48,232, 74, 0, 4, 1, 60, 42, 44,166, 35,149, 74,234, 4,244,152,139,173, 9, 76,198,235,195,241,127,105,
- 46, 65,249, 51,230, 11,254, 8,143,190,229,207,110,124, 1, 96, 88,195,227,106,153, 96, 58,195,114, 10,150, 50,177,217, 0,182,
-188,101,180, 26,217,216,216,196,157, 59,119,174,181,191,191, 63, 27, 0, 98, 98, 98,166, 5, 7, 7, 15, 40, 44, 44,244, 6, 80,
-241,127,148, 9, 9,216, 36, 57,143,199,225, 12,166, 40,170, 51, 0,176, 88,172,120,133, 74,117, 69, 77,211,123,160,231,156,108,
- 6, 24, 96,192, 63, 23,186,180,200,223, 28, 90,103,134,175,187, 57,166,254,182, 62, 68,182,157, 60,123, 14, 28,243,164, 92, 82,
- 45,123,241, 34,183,116,201,188,141, 87,102, 45,250,238,236,150, 31, 34, 34,163,238, 37,223,245,240,127, 47, 73,100,219,201, 83,
- 11,181,182, 54, 92,103,161, 80,248,112,239,222,189,202,212,212, 84,166,172,172,140,121,242,228, 9,115,234,212, 41,102,206,156,
- 57, 50,161, 80,248, 16,128,179, 62,156,118,118,118,249, 79,174,255,206,228,196,197, 50,153, 49,247, 24,149, 74,197, 40,149, 74,
- 70,169, 84, 50, 73,151, 34,152,184,223,111,128,202, 97, 0, 0, 32, 0, 73, 68, 65, 84, 78, 51,143, 78,157, 96, 20, 10, 5,163,
- 80, 40, 24,185, 92,206,180,107,215,238,165,158,225,108, 8, 71, 47, 47, 47, 69, 68, 68, 4,243,235,175,191, 50, 75,151, 46,101,
-124,125,125, 41, 0,243,245,189,119,145,173, 91,144, 73, 43,159,194, 79, 66,246, 40, 47, 68, 95,102, 18,159, 63, 98, 18,159,167,
- 49,225, 87,147,153, 25,203,118, 42, 77, 90,249, 22,138,108,221,130,116,221,187,133,133, 69, 79,130, 32,152, 58, 0, 96,218,180,
-105, 83, 89,255,227,236,236,252,218,199,201,201,169,178,109,219,182,207,172,172,172,186, 54,198, 57,169, 51, 24, 38,233, 23,134,
- 73,250,133, 89,221, 15, 76, 98, 98,226, 93,134, 97,254,168,251, 72,165,210, 63,206,156, 57,243,199,135, 31,126,248, 7,128, 15,
-154,136, 39,189,226,115, 26,144, 37, 57,119,142, 97,182,109, 99,152,192, 64, 38, 25, 96,166, 1, 89,205,228,108,103,111,207,121,
-244,221,230, 89,138,115,231,126,102, 46, 94,188,192, 68, 70, 70, 48,103,207, 28,100,182,111,155,167,180,179,227, 36, 0,232,208,
- 12, 78, 54,128,141, 0,182,162,198,185, 76, 45, 44, 44,100,242,242,242, 24, 0,169,181,191,109,181,177,177,217,130,198,221,183,
- 65,245,157,172,207,134,218, 95, 28, 63,172, 15, 35, 41,127,201,140, 31,214,135,249,108,168,253,107,206,214, 80, 87, 87,147, 5,
- 35, 58, 23, 38,198, 28,165, 22,140,232, 92, 56,212,213,213,164,133,241, 73,160,102,157,208,189,215,175, 95, 87, 51,245,160, 82,
-169,152,195,135, 15, 83, 22, 22, 22, 63, 55,131,179,163,141,141, 77,166,165,165,101,106,253, 31,109,124, 70,245,114,239, 59,109,
-173,149,231,135,129,205, 8,167,191,128,203,205,185,114,242,123,170, 56, 43,158, 81, 72,243,153,242,167,177, 76, 78,242, 93,230,
-240,254,173, 42, 30,155,157, 3,192,255,109,158,165,102,194,192,105,224, 52,112,254, 13, 57,155,210, 34,255,203, 96, 55,188,193,
-134,224,243,121, 33,107, 87,175, 32,202,138,203,164,178, 10,137, 66, 37,147,201, 72, 46, 35,139, 79,122, 94, 64,178, 89,101,159,
- 45, 90,104, 18,178,114,117, 72, 21, 48, 69,207,255,116,246,245,245,189,127,250,244,105, 91, 75, 75, 75,148,151,151,163,184,184,
- 24,247,239,223, 7,195, 48, 24, 61,122, 52,191, 71,247,238, 93,191, 88,179,230, 78, 78,110,110, 0,180, 23,188,175,196,139,165,
- 53, 54,247,169, 89,139,246,203, 23,197, 53,165, 14, 65,224,192,184, 96,205, 57, 27,114,106, 86,203, 16, 8, 4,154, 5,137, 91,
-128,128,129, 3, 7,114, 1, 96,230,204,153, 21, 18,137, 36,180,214,225,208,107,165, 85,145,173, 91,144,181,131, 99,196,247,251,
- 54, 11, 59,183,119,131, 82,165, 70,102,222, 75,176, 57,230,104,221,154,139,143,166, 12,230,244,235,101,105,189,241,171, 3, 23,
-242,104,140,170, 46, 74,187,172,141,203,220,220,252,240,137, 19, 39,112,242,228, 73, 0, 64,106,106, 42,220,220,220, 68,186,194,
-144,144,144,224,250,193, 7, 31, 28, 47, 46, 46,238,160,235,220,134, 19,227,243,249,124,244,233,211, 7,158,158,158, 56,119,238,
- 92,255, 90,103,235,173, 32,189,121, 19,198,143, 31, 3, 81, 45,170,188,180,243,243,115,185, 27,121,225,168,245,133,200,100,108,
-217,114, 16,207,158,213, 24,109,174,174,174,152, 60,105, 28, 39, 62, 62,218,107,236,216,201,209,183,110, 61,235, 83, 43,148,116,
- 97,253, 15, 63,252,176,170,109,219,182, 24, 59,118,236, 56, 47, 47, 47,123, 83, 83, 83,236,223,191, 31, 14, 14, 14,174, 10,133,
-226,233,185,115,231, 28,243,242,242,176,112,225, 66,228,231,231, 47,213, 70,212,127, 72,255, 47,248, 35, 60,250,118,242,155, 14,
- 99, 83, 7,252,112,236, 4,158, 60, 60,220, 87,174, 76,254,130, 75, 69, 77,149, 50,252, 25,133, 89,198, 33,109,186, 5, 90,117,
-240,250, 0, 46,126,177,214, 50,234,214,243, 47, 6,183, 11, 99, 11,100,135,215,109, 17, 23,191, 65, 58, 54,156,229, 93,145, 98,
-153,112, 5,197,192, 58,186, 78, 96,105,220, 90, 6, 31,244,235,215, 79,147,112, 47, 94,188,128, 92, 46,135,135,135, 7,169, 80,
- 40,130,244,140,215,142,239,189,247,222,159,145,145,145, 86, 29, 59,118, 44, 44, 41, 41,209, 28,176,183, 50, 31, 18,117,122,251,
-194,141, 59,254,235,126,132, 33,202, 10,147,207,198,235,224,242,239,221,211,239,234,197,211, 71,141,137,202,108,240,204,139, 0,
-186, 24,233,199,127, 2, 97,100,137, 9,115,150,176,131, 6, 14,104, 53,120,216,152,171, 79,210,158, 13, 4,240,192, 80,175, 55,
-192,128,127,181,171,197,252,211,238, 73, 35,180,130,131,131,137,198,110,144,102,104, 31, 59, 91, 43,225,246,239, 14, 61, 96, 41,
- 21, 10,145,185,153,130, 99,102, 74, 19, 38,102, 44,165, 66, 85,233,226,234,194,163, 25,218, 71, 11,127,195, 33,158,132, 80, 40,
- 60,253,219,111,191,217,114, 56, 28,208, 52, 13, 27, 27, 27,100,100,100,160,172,172, 12, 18,137, 4,207,146,147,209,214,217, 9,
-235, 66, 86, 56, 44, 92, 17,114,186,186,186,186, 27, 94,111, 70,124, 99,216, 40,165,122,125,221,232,186, 37, 88,222,168,242,215,
-254,214,200, 49,125,135,162,102,100,101,101,193,216,216, 24,222,222,222,198,183,111,223,190,213,132,200,122,141,211,194,194,213,
-132,230,243, 78,238,253,126,141, 80,169, 74, 64, 82,122, 9, 58,181,237, 11, 59, 43,103,188, 44, 81,224,238,253,223,144, 16,247,
- 11,218,183,114,198,252, 57, 3, 4, 97,155,127, 61,193, 85,183,117, 46, 43,203,168,104,140,179,162,162,194,184, 93,187,118,112,
-118,174, 89,247,140,162, 40, 36, 37, 37,129,162, 40,205,126,253,237,161, 83,215,161,174,200,196,244,105,211, 80, 92, 92,108,220,
- 24, 39,135, 5,245,146, 89,147,217, 66, 14,192, 19, 89, 42, 42, 43, 43, 53,203,112, 40,149, 74, 60,122,244, 8, 1, 1, 1,129,
-225,225,225,186, 84,145, 94,241,169, 4,190,221,241,243,207, 59,167,148,151,147, 0,240, 35, 65,208, 74,134,249, 86,223,103,201,
-214,150,115,234,210,197, 35,214, 44, 50, 5,150,102,223,224,254,253, 76, 40,149, 53,225, 45, 46, 46,192,130,121, 21,224,114, 76,
-112,238,220,127,173, 60, 60,250,156,202,203, 83,122,227,245,102,196,198,194, 41,184,120,241, 34, 22, 44, 88,128,164,164, 36, 71,
- 22,139,133,123,247,238, 65, 40, 20,226,187,239,190, 99,121,120,120, 56,138, 68, 34, 92,186,116, 9,249,249,249, 68, 83,225,252,
-227,242, 31, 95,151, 63,187,241, 69, 30,113,105,232, 15,199, 78,224,211, 73, 19, 96,207,164,223, 50,107, 79,124,253,222,136,222,
- 95, 50, 44,167, 96,145,137,143,133,155,247, 8,112,121,198,152,255,249, 6,164, 38,156,183,168,150,196,205, 35,168,108,167,117,
- 91,194, 23,189, 17,206, 95,199, 81, 51,127,185,237,119,197,249,129,203,227, 71,179,238,137, 99, 15,196,189, 18, 90,174,108,130,
-164,204,128,154,229, 83,158, 62,125,138,103,207,158,129,205,102, 67, 42,149, 66,173, 86, 55, 26, 78, 71, 71,199,217,106,181,250,
-203,218,116, 62, 36, 16, 8, 62, 62,122,244,168, 85,125,161,109,227, 51,170,151,149,137,104, 96,126, 65,113,105,244,131,196, 39,
- 75,102,143,237,127,243,110, 66,182,146,243, 97, 86,121,220,185,114, 45,241, 41, 16,242,120,167, 46,157,249,175,177,234,249,117,
-136, 60,250,131, 99,236, 6, 74,149,139,234,210, 42, 72,158,137, 33,255,126, 55,186,204,251, 12,231,207,254,106,236,213,185, 91,
-184, 92,165,114, 3,160,104,193,187,217, 28, 24, 56, 13,156, 6,206,191, 39,167, 86, 45,194, 48,140, 31, 0,187,218,221,226, 90,
- 93, 96, 13,160, 8, 53,171,200,216,213,230, 29,188,122,151, 53,220,175,127,110,195,253,250,223,139,107,191,219,214,110, 31, 16,
- 4, 81,162, 35,232, 14,168, 89,154,240, 66,237, 22,168,109, 74,212,217,241,152, 32,200, 10,138,162,249, 92, 27, 91,217,204,241,
- 3, 59,255,126, 53,230,145,145,181, 41,123, 72,255,174,129,247,227,159,223, 33, 72, 66, 69, 16,164, 94,253, 62, 88, 44,214,132,
-237,219,183,119, 54, 53, 53, 5, 77,211, 48, 51, 51, 67, 97, 97, 33, 20, 10, 5,202,203,203, 33,151, 84, 64, 41,169,192,227,236,
- 23,232, 29,216, 31, 99,134,190,231,241,223,179,191, 77,160, 40,234,120, 83,188,142, 62, 93, 53, 78,214,134, 54, 86,175,172,137,
-236, 50,141,232,250,166,171, 27,184,198,198, 24,188, 36,228,109,158,129,216, 11, 23, 46, 92, 28, 61,122,244,176,101,203,150,145,
- 98,177,248, 82, 70, 70, 70,111, 0, 73, 58, 69, 5, 95,176,120,238,226, 96, 11, 11, 99, 6,225, 87,126, 67,191,174,147, 96,196,
- 99,161,184, 66, 9,130, 0,146, 19, 79,131, 32, 44, 17,151, 42, 70,223, 46,166,120,111,136,135,241,217, 95,147,151,225, 85,255,
-160, 55,146,166,180,180, 20, 5, 5, 5, 80,169, 84, 80,169, 84, 24, 59,110, 28,142, 28, 62,140,170,170, 42, 72,165, 82, 40, 20,
- 10, 80, 20, 5,146, 36,113, 37, 34, 28,217,207,147,209, 43, 32, 0,208,178,244,210,225, 71,224, 0,184,251,228,201, 19, 36, 39,
- 39, 35, 39, 39, 7, 2,129, 0,246,246,246,216,176, 97, 3,228,242,154, 53,202,198,141, 27, 23, 8, 32,254,109, 95,168,103,192,
-129, 12,138,250, 98,216,153, 51,182,183,207,156,161,239,158, 63,159,195,151, 72,246,235,115, 45,151,139,177,155,191,157,211, 73,
- 36, 18, 33, 39,107, 59,220,221,185, 88,250,153, 21, 66,191, 41, 2, 0, 44, 92,208, 26,221,187, 89,163,162,236, 87, 88,219,174,
-194,206,157,139,218,207,152,177,117, 90,117, 53,117, 72, 7,245, 23,191,253,246,219, 24, 55, 55,183, 86,177,177,177, 4,143,199,
-131, 80, 40,132, 80, 40,132, 64, 32, 64, 65, 65, 1, 50, 50, 50,152,205,155, 55,231, 2,248,162, 41,162,117, 59,197,119, 0, 12,
-251,108, 40, 46, 62,121,120,184,111, 43,214,243,199, 99,230,247,121, 17,119, 55, 86,242,251,149,219, 95,169,101,130,236,178,156,
-171, 43,218,117,143,181,158,183,124, 61,118,111, 94,139, 39,247,110,150,216, 57, 87,236, 17, 18,242, 70,195, 25, 24,184,142,237,
- 96,103,169,158, 61, 99,140,249,121,187,232,217,145,108,162, 48,175,232,225,119,200,136,149,242, 59,116,157,218,209,149, 84, 92,
-191,126, 93,216,175, 95, 63,200,100, 50,141, 51,121,244,232, 81, 90,173, 86,223,104,244,217, 84, 42,191,204,205,205,117,144, 74,
-165, 24, 58,116,232,194,239,190,251, 78, 84,183, 70, 29, 69, 81,175, 57, 89, 95,111, 59,114,121,241,151,123,110, 92, 62,254,141,
-227,215, 33, 31,247,159, 50,127,227, 13,104, 89, 71,146, 77,146,243,206,159, 57,104, 47,176, 80, 65,104,249, 30,100,249, 82, 60,
- 57,240, 41,170, 43,100,232,254,245,122, 0, 60, 40, 84, 36,246,143, 24, 11,142,149, 35,214,126,242,177,227,234,253, 63,204,161,
-105,122,187,161, 94,111,128, 1, 6, 52,128, 29, 65, 16, 17, 0, 16, 18, 18,178, 42, 52, 52, 52,145, 32,136, 8,134, 97,130,107,
- 13,148, 8,134, 97,130,235,206,169, 21,103,111,236,215,157,219,112,191,225,247,149, 43, 87,122,133,133,133,109, 10, 8, 8, 56,
- 30, 29, 29,253, 28,128, 46,161, 53,188, 86, 88,189,177,244, 14, 89,167, 32,235,111, 95,115,180,104,250,230,211,231, 47,170,223,
- 27,212,163,117, 68, 84,252,131,143, 62, 26, 62,112,194,136,126, 67, 50,178,138,147,219,187,216, 91, 39, 38,198,155,210, 52,125,
- 83,159, 88,226,243,249,193, 3, 6, 12, 96,151,150,150,194,200,200, 8,133,133,133,200,205,205,133, 82,169,132,172,188, 12,242,
-242, 50,200,202, 74,161, 44, 47,197,179,152,251,240,105,239,202,175,237, 44,223, 36,234, 92,151,134, 78, 85,125,103,139,103, 98,
- 2,190,137, 9,136,230, 55, 27,126,104,110,110,126,183,174, 80, 85, 42,149,243, 86,172, 88, 81, 68,211, 52, 54,110,220,104,106,
-108,108, 28, 14,128,175,139,196,196,134, 21, 28,208,197,155, 76,201,136, 67, 31,223,233,232,216,238,125,100,228, 75, 81, 36, 81,
-162,160, 76,137,238,253,118,161,141,239,122, 56,117, 9, 69,114,102, 9, 28, 91,185,145, 96,243,155, 92,252, 57, 59, 59,251,181,
-253,227,199,142,161,186,186, 26,237,219,183,199,164, 73,147,176, 98,197, 10, 76,154, 52, 9,142,142,142,152, 50,254, 3,172, 93,
-187, 22,121,121,121,186,130, 42,239,216,177,163,220,197,197, 69,238,226,226, 34, 87, 42,149,168,172,172, 68, 89, 89, 89,195,248,
- 94,212,220,136,180,181,181, 93,105,111,111, 31,103,107,107,155,200,231,243, 35, 31, 17, 68,138,204,197,197,174,247,200,145,132,
-231,248,241,172, 76,161,144,136, 2,140,245,225,178,182,228, 12, 15, 26, 48,140, 87, 86,122, 80, 99, 82,125,252,145, 13,254,140,
-242,194,237, 91,221,176, 96, 94,123, 16,164, 0, 4,201, 67,117,213,117,244,240, 15,224,154,155, 19,186,158,165,201, 0, 30,245,
-238,221,219,113,254,252,249, 4,159,207,199,194,133, 11,149,159,124,242, 73,218,164, 73,147,210,174, 93,187, 70,185,184,184,192,
-201,201,137,112,114,114,114, 0,240,168,246,154, 38, 97,218,158,248, 90,174, 76,190,101,238, 38,122, 78,193,186, 87,165,138, 63,
-118,221, 22,113,241,215,123,159,111,201,120, 82,237,250,228,222,205,226,180,132,243,116,198,131, 63,138, 94,166, 73, 92,191,222,
-251,124,203,170, 61, 47, 27,125,169,163,162, 64,159,142,136, 82, 86, 87, 85,179, 71,142, 8,170,158, 61,115, 66, 71, 75, 99,175,
-163,104,245,158,111, 27,231,214, 83,214,110,218,169,252,100,206, 98,229,143, 63, 29,100, 36, 18, 9, 42, 42, 42,176,115,231, 78,
-245,249,243,231,115, 41,138, 90,172,173, 14, 4, 0, 42,149, 10,179,103,207, 22,153,154,154, 34, 59, 59, 91,227,136, 2,128,184,
-176, 56,254,246,131,132,148, 37,255, 25, 23, 88, 37,151,203, 47,255, 17,147,236,233,230,210,154, 32, 24,173, 3, 81,120, 28,206,
-224,110, 61,122,176, 24,166, 12, 4,219, 25,207, 14,111, 70, 69, 94, 9, 42, 10, 74,192,226,136,160, 6, 31, 42,154, 7,115, 31,
-127,164, 62,136, 69, 43, 27, 59, 54,159,195, 25, 98, 40, 79, 12, 48,224,223,137,166,180, 72,125,177, 20, 22, 22,182,169,169,227,
-245,182,138, 6,251, 26, 33,213, 80,132,213,255, 14, 0, 97, 97, 97,155, 24,134, 9,142,142,142, 62, 6, 64,170,231, 45,204,170,
-183,213,127, 30, 45,150, 76, 17,186,108,197, 23,176, 48, 19,154,249,119,117,179, 63,119, 41, 42,230,102,116, 76,114, 27, 39,107,
- 27, 70,165,176,248,118,235,238,214, 68,181, 52, 76,207, 64,120, 88, 91, 91, 67,169, 84,226,233,211,167,200,201,201,129, 82,169,
-132,186,170, 10,242,178, 50,200, 74, 75, 65, 85, 73,192,165, 40, 72, 11, 11, 96,101, 36, 0, 94,141, 72,212,225,188, 17,141, 10,
-173,186,173,192,212, 20,124, 19, 83,144, 28, 78,163,205,138, 90,224,231,239,239,127, 50, 33, 33,161,199,160, 65,131,190, 66,205,
- 16,249,204,220,220,220,129,107,214,172,145,219,217,217, 97,246,236,217,157, 0, 76,215, 41, 50,121, 10, 15, 23,251, 78,232,232,
- 58, 29,109,156, 6,160,172, 74,133,194, 10, 21, 10,202,148,216,191, 43, 0,167,126,244,199,159,167,250, 34,225,242, 96,148,169,
-236, 97,236,248, 33, 24, 74,225,213, 20,231,149, 43, 87,176, 97,195, 6,124,245,213, 87,216,184,113, 35,190,250,234, 43,228,230,
-230,194,219,219, 27, 89, 89, 89,184,120,241, 34,196, 98, 49,172,173,173,113,255,254,125,108,219,182, 13,127,254,249,167,206,155,
-174, 19,174,122,156,211,172,182,116,181, 90, 61, 67, 60,114,100,231,124, 75, 75,207,174, 93,187, 14, 91,184,112,161,107,239,222,
-189, 53,199, 93, 93, 93,157,133, 66, 97, 30,106, 70, 80,118,105,138,139, 6,186,218,216,120, 67, 33, 79,169, 77, 99, 14, 8, 66,
-128, 1,131,147,209,187,111, 12,148, 42, 46, 72,130, 15,146, 20, 64,173, 46,134,133,133, 35, 24,134,240,214, 17,196, 53,133,133,
-133,110, 87,175, 94, 37, 51, 50, 50, 32, 16, 8, 0,224,197,186,117,235,118,111,217,178, 37,201,202,202,138,138,136,136,192,217,
-179,103, 17, 28, 28,204,250,228,147, 79,220,156,156,156,246,233,186,239,117, 59,197,119,126,217,122,113, 34, 71,101,209, 69, 32,
-108,211, 22, 85,198, 31,206, 13,180, 22, 1,192,165,244,116,137,173,115, 69, 88,149, 36, 46,203,188,117,229, 55,151,210,117,141,
- 56, 93, 71, 63, 76, 75,185,251,203,153, 75,229, 5,249,165,156,174,157,189,164,161, 27,150,115,219,180,237,240,237,218, 21,255,
-177,207,173, 16,148, 13, 94,120, 49,229,244,165,251,149, 83, 63,250, 84, 61,115,214,124,217,197, 75, 87,206,208, 52,221, 25, 90,
- 70, 28,210, 52, 13,177, 88,140,196,196, 68,164,167,167,163,176,176, 16, 69, 69, 69,144, 72, 36,154,230, 70, 35, 73,197,133,221,
- 63,159,127, 44, 18, 10,141,122,116,118,115,190, 23,155, 84, 32, 18, 10,141,220,218, 58,119,196,255, 99,239,186,227,162,184,214,
-246, 51,179,189, 81,150,206, 2, 42,160, 40, 42, 8, 68, 68,236,168,145,196,222,176, 68,177, 68,163, 73, 52, 70,147, 24,176, 36,
-118,141,215,168,209,152,168,137, 61,118, 49, 42,118,197,222, 5, 84, 4, 20,164,247, 14,203,246, 50, 51,223, 31, 2, 23, 13,101,
-209, 36, 55,247,187, 60,191,223,176,236,238,204,179,231, 76, 57,231, 57,239,251,158,247, 96, 73,157,237, 8, 69, 81,222, 2,145,
- 16, 0,129,242,184,235, 80,148, 41,160, 40, 87,160,178, 84, 1,173,158, 5,141,150,132, 90, 71,162,101,239, 1, 80, 40, 53, 80,
-148, 84,128,166, 40,159,230,238,166, 25,205,104, 70, 3,125,125,100, 88, 88,216, 2, 19,247, 53,217,189,249,186,240, 10, 11, 11,
- 91, 64, 16, 68,100,120,120,120, 71,212, 63,161,170, 54,182,215,177, 1, 48, 33,189, 67, 73, 73,146,194,140,104, 63,114,238,252,
-111,206, 30,216,177,217, 78,171, 85,101, 90, 75, 37,148, 68,196,179,249,112,198, 74, 84, 42,202, 70, 40, 77, 79, 71,128,178,178,
- 50,164,166,166, 66, 40, 20,130,203,225,128, 82,171, 65,169,149, 80,151,149,128,212,107,193,165, 40, 88,137,132,104, 41,115, 64,
- 43,123, 7,147, 56,147,163, 46,212, 4,190,215,118, 23,254,171, 75,123,240,196, 18,240,204, 36,248, 36,242, 42, 0,128,203,229,
- 2,139,151,155,100, 52,113,114,114, 58,185,127,255,126,110, 81, 81, 17, 98, 99, 99, 31, 1,168, 0, 96, 6,128, 78, 72, 72,184,
- 20, 23, 23, 55,216,195,195, 3, 0, 90, 55, 70, 38, 47, 38, 41,131,145, 65, 86,126, 58,210,178, 99, 96,101,225, 6,142,168, 45,
- 10,203,245,224, 11,221, 96,208,254,219,251,168,145,103, 64,173,103,153, 84,119,157, 78, 7,163,209, 8,163,209, 8,157, 78,135,
-143, 62,250, 8,183,110,223,198,193,223, 47, 35,245,197,115,180,115,117, 64,104,232, 68,116,233,210, 5,183,111,223,110,144,107,
-146, 47, 12, 78, 18,176,215,191, 79,130, 39,177,214,118,253,250,252,189,198,196, 22, 65, 16, 12,234,113, 69,190,134,239, 3, 3,
- 3,219, 60, 87, 42,241, 52, 49, 17,253,151, 44, 1, 0,156, 57,115,230,149,186,204,155, 55,143, 23, 31, 31,255,225,195,135, 15,
- 63,204,205,205, 93, 15,160,238, 96,115, 6, 56,125,250, 14,102,206,140, 71, 81, 81, 17, 0,224,208,129,127,235,210,180, 84, 61,
-222, 27,244,210,163,101,105,105,137,245,235,189, 76, 58,159, 20, 69, 97,251,246,237, 53,238, 66, 0, 96,179,217,221,231,205,155,
- 55,178,174,253,219,180,105,195,109,140,115,238,104, 39,193,205, 71,204,167, 22,109, 90,117, 52,183,233,132, 18, 67,140, 87, 76,
- 78,222,236,185,163,157, 54,110, 56,154,163, 17, 18,218,221, 4,149,229,194, 22,104,246,152, 82,198,148,115,155,117, 37, 45, 39,
-239,201, 47,146, 47,156, 53,253, 3,107,115, 75, 59,229,175, 63,174,150,146, 44,146, 57,249, 80, 95,222,209,221,218,114, 88,215,
- 31, 20, 51,231, 46,142,209, 25,179,102, 33,235,228,115, 52,144,226,130,162, 40,228,230,230,162,168,168, 8,153,153,153, 40, 46,
-126,233,126, 45, 46, 46, 6, 77,211,111,211, 32, 66,157,153,137,140,227,191,162,213,196,137,240, 95,190, 12, 20,205,134, 90, 69,
- 97,125,183,126, 40,171, 80, 67, 75, 19,144,189,211, 13,211,207,220, 0,201, 80,192,182, 45,205, 61, 73, 51,154,241, 63, 10, 83,
-210, 59, 84, 11,162,213,171, 87, 15,254,179,127,191,182,216, 90,189,122,245,211,213,171, 87, 55,229,183, 94,119, 25,214,188,175,
-142,209,186, 90, 43, 0,237, 15,157,102,101,113, 66, 74,124, 60, 59, 87,169, 86,138,236,237,108,181, 34, 1,159,174,144, 87,178,
- 98,158, 60,210, 43,243, 95, 60,107, 66, 61, 18,226,226,226,188,114,115,115,145,153,145, 1,163, 90, 9, 82,171, 3,163, 81,161,
-127,143,110, 16, 0, 16,144, 4,184,180, 30,108, 22, 15,149, 10, 57, 0, 36, 52,218, 57, 26, 12,127,176,108, 17, 4, 1,158,153,
- 25,120, 98, 49,120, 18,179, 87, 44, 92,166, 88,108,248,124,254,254, 35, 71,142, 56, 58, 57, 57, 97,217,178,101,112,118,118,246,
-148,201,100, 42, 11, 11, 11,161,189,189, 61, 58,116,232,128,110,221,186,225,236,217,179,128, 9, 57,165, 12, 70,193,227,103,233,
-232, 94, 92,122, 27, 55,174,254, 12,157, 90, 11,191,222, 63, 67,207,110, 5,219,142, 75, 65, 39,239,131, 42,255,196, 75,235,129,
-195, 16,100,103,166,131, 96,241,158,154,106,121,170,254,255,209,163, 71, 56,112,226, 26, 28, 91,182, 71,102, 82, 34, 18,175, 92,
-194, 45, 91,107,180,108,223,161,198, 13, 84,111, 25, 41,176, 87,108,121,153, 38,106,209,167, 31,240, 75, 75, 75,249, 86, 86, 86,
-218,234,115,231,232,232,248, 54, 98,235,131, 47,191,252, 18,229, 28, 14, 48,104, 16,184, 41, 41,208,235,245,232,218,181, 43,252,
-253,253, 1, 0, 93,187,118, 5,155,205, 70,167, 78,157, 32,147,201,176,101,203,150, 15,234, 19, 90, 36,129, 88,163,177,196,211,
-221,221,189, 70,104,237,217, 91,132,152,135,239,130, 0, 15,155,126, 76,174,217,183, 69,139, 22,200,207, 75, 1, 65, 48,113,141,
-148,113,185,131,131,195, 98, 71, 71, 71,247,239,191,255,158, 37, 16, 8,240,241,199, 31,187, 41, 20,138, 86, 85,166,100,132,135,
-135, 3, 0,190,253,246, 91, 44, 89,178, 4, 90,173, 86, 85, 31,217,158,245,222,178,194, 82,250, 67, 70, 33, 26, 17,100,211,202,
-187,111,112,127,184,121,244, 69,223,224, 76, 0, 88,101,197, 78, 31,179,118,161,229,113, 75, 51, 98,231,133,115, 23,191,237,209,
-187,239,194,175, 21, 87, 86,124,183,189,188,209,152,199,138,140,221,149,207,120, 99, 55,108,222,186,119,195, 55,225,115, 4,153,
- 69,186,178,156, 50, 70, 33,225,179, 37,173,237, 9,201,236,249,203, 83,115,115, 83,190, 64,214,185, 70,103, 90,210, 52,141,148,
-148,148,154,152, 62,141, 70, 3,165, 82,137,172,172,172,154,123, 70, 45, 54,127,111,214,148, 33, 62, 74,181, 90,117,239, 73, 82,
-230,162,207, 38, 4, 42,213,106, 85, 82, 90,230,115, 96, 83,157,106,140, 36,201, 39,170, 74, 85,127, 85,185, 6, 69,177,207,224,
-220,175, 37, 12, 70, 2, 58, 35,133,162,146, 74,104,141, 0, 69,114,208,113, 76, 40, 40,130,141,226,220, 28,144, 44,214, 35,188,
- 26,180,223,140,102, 52,227,127, 7, 13,106,145,106,139, 86, 96, 96,224,193,218, 86,167,234,255, 1,104,209,112, 40, 79, 81,109,
- 49, 85,237, 78,172,239,119, 94,227, 53, 21,127,136,209,106, 52,189, 67,245,111,186, 88,200,101,255,250,118,130, 51,109, 52,182,
- 43, 44, 46, 48,178,217,124,142,139,133, 58,175, 52,211,244, 95,215,106,181,145,151, 46, 93, 26,254,238,187,239,242,147,158, 60,
-130,174,162, 2,186,138,114,112,104, 35,172,132,157, 65,234,181, 32,116, 58, 56,121,210,208, 84, 10,113,237, 86,156, 65,171,213,
- 70,154, 42,180, 72, 22,235,213,184, 44,137, 4,124, 51,115,240, 37,146,215, 93,139,141,137, 2,209,128, 1, 3,250,117,237,218,
- 21, 12,195, 96,251,246,237,208,235,245, 60,189, 94, 15,157, 78, 7,189, 94, 15,185, 92,142,189,123,247,226,167,159,126,186, 5,
- 96, 87,163,157,153, 81,119,233,252,197,168, 46, 83, 39, 12,230,156,137, 92, 15,163,142,130,154,112,134, 82,105,128, 66, 39, 2,
-101, 61, 17, 40, 56, 13, 22, 91,128,192, 78,110, 56,113, 52, 66, 15,163,246,178,137, 42,252, 21,171, 80, 86,102, 58,178, 95, 60,
-135, 68,158, 15, 91,115, 17, 84, 41,207,225, 23, 58,233,141,172, 19, 46, 46, 46,160,105, 26, 65, 65, 65, 53,193,213,111, 42,182,
- 74, 74, 74,112,234,212, 41,116,237,218, 21,189,123,247, 70, 78, 78, 14, 82, 82, 82, 48,112,224,192,154,125, 30, 61,122,132,152,
-152, 24,180,110,221,176,145,176,184,212,112, 38, 59, 43, 54,100,216,176, 97,220,187,119,239,130, 97, 24,120,120,152,195,220, 76,
- 12,130,228,163,125,123, 59, 0, 47,199, 0,125,250,244,129, 92,158, 98, 44, 43, 99,206, 52, 82,221,253, 0,126,215,233,116,201,
-189,122,245,146,189,120,241, 2,115,231,206,101, 31, 58,116,168,218,148,140,176,176, 87, 39, 83,168,213,245,187,238,219,121,123,
-126,229,102,148,246, 22, 8, 91,185,154,219,116,130,155, 71, 95, 0,192,187,131,167,194,173, 77, 11,200,139, 31,187,106,212,233,
- 35,184,236, 50,233,227, 77, 57,241,194, 65, 94, 83, 52,133, 87,147,240,210,117,218,232,101, 87, 39, 29, 42,200,228, 76, 60,252,
-251,201,179, 51, 6, 14, 30,202, 49, 80, 70,163, 87, 75,142,229,145,227,167, 11,115, 50, 50,127, 64,230,185,184,127,219,255, 26,
-180,226, 81,114,185, 28, 98,177, 24,113,113,113,218, 65,131, 6,241, 73,146, 68,114,114,114,141,208,178,179,177,234,208,221,223,
-203,115,197,134,189,231,197,124, 62, 63,184, 79,231,246,241, 73, 25,217, 12, 67,164,215,107,109, 53, 24, 46, 62,137,125, 20,100,
- 43,107,195, 74,185,122, 23,214, 61, 7, 66,171, 37,161,214,209,208, 26, 1, 35,139, 11, 71,223, 0, 88,182,110, 15, 6,192,131,
-187,183, 12, 90,131,225,124,115, 95,211,140,102,252, 79, 91,181,152,134, 68, 82,213,255,165, 0,210, 87,175, 94, 93, 92,203,218,
- 84, 4,224, 17, 0,159,170,253,138, 94, 59,174,136, 32,136, 7, 12,195,248,215,226, 41,170, 37,184,106,255,175,123,109,159, 71,
- 77, 16, 89,181, 95, 95, 21, 90,245, 77,169, 4, 0, 27, 27, 27, 59, 63,191,206,173,127,217,113, 24, 12,195,224, 89,204, 58,148,
- 21, 38, 98,241,170, 59,173,157,156,156,122,231,228,228, 92, 51,165, 4, 20, 69, 29,218,185,115,231, 23, 1,239,248,249,185, 58,
- 59,227, 81,122, 26,184, 12, 5, 46, 69,129,212,107,193,166,116,112,246,162, 64, 18, 18,228,230, 86, 96,205,254,195,113, 85, 89,
-226, 27,132,231,192,161, 88,150, 93, 1,130, 32,240,125,160, 23,120,102, 18,112,197, 18,124,114, 50,170, 70, 92, 69, 46, 11, 7,
- 79, 34, 65,235, 0,147, 18,194,171,174, 92,185,242,240,201,147, 39,254, 94, 94, 94,248,226,139, 47,144,158,158, 14,154,166, 81,
- 80, 80,160,201,203,203,203, 41, 42, 42, 74, 7,112, 28,192, 47, 48, 33,243, 56, 87,171,217, 24,121,108,207,172,192, 30,189,109,
-134,141,248, 9,191, 31,157,135,242, 10, 57, 84, 70, 33,148, 26, 35,148, 90, 22,172,172,189, 17,208,169, 19,114,115, 10,241,244,
-238,121, 5, 91,171, 90,215,148, 27,148, 32, 8,196,196,196,192, 93,102,134,231, 55,174,193, 70,196,129,143,204, 1,178,238, 61,
-106,242, 75, 53, 4, 14, 11,198, 15, 62,248,160, 38, 51,252,128, 1, 3,210, 38, 78,156,232, 56,111,222, 60,236,216,177, 3,183,
-110,221,250, 67,128,118,239,222,189,113,253,250,245,165, 0,190,109,204,168,167,211,233,224,233,233,137, 7, 15, 30,224,210,165,
- 75,232,219,183, 47,122,247,238,141,199,143, 31,227,194,133, 11,136,137,137, 1, 65, 16,176,182,182,134,225,165,120, 54,212, 71,
-166,215,227,200,119,107,119, 46,216,176,225,167,142, 19, 38, 76,192,177, 99, 7, 49,117, 74, 59, 16, 36, 31, 4,193,199,208, 33,
-237,176,108,249, 3, 4, 4,244,129,141, 13, 7, 27,214,159, 72, 85,171,169,189, 38,156,198, 21, 23, 46, 92,144,105, 52, 26,148,
-151,151, 51, 18,137,132, 40, 41,121, 57,163,181, 46,139,150, 74,165, 18,212, 71,244, 36, 58, 97, 93,121, 37, 83,198, 40, 98, 70,
-148, 26, 99,188,251, 6,103,225,221,193, 83,112, 49,114, 23,162,206, 95,130, 21, 59, 61, 13,226,202,179,197,105,197,242, 60,165,
-199,214,246,239, 76, 99,101, 43,207,111,157, 61,244, 57,203,209,145, 62, 18,254,179,188,188, 33,161, 5,128, 40,141,223,119,242,
- 56,131,161,221, 2, 3,218,120,181,112,228,149, 21, 23, 50, 71, 79,156,141,211,167, 29, 59, 85, 75, 96, 49,141, 8,245,101, 97,
- 97, 97,223, 84,253,191,123,209,162, 69,211,214,172, 89, 99,155,159,159, 95, 19,163, 85, 88, 92, 26,213,109,208,108,170,164,188,
- 66,183,115,195,252,209, 66, 1,159,183,104,205,206,171, 6, 22,238,214,199,107,164,233, 45, 99,230, 46,158,147,244, 44,198,169,
-149,144,135, 19,243,191,197,163, 11, 87, 96, 32,185,152,121,233, 30,180,122, 10,229,197, 37,184,252,225,167,144,216, 75,241,211,
-213, 99, 5, 52, 77,255,220,220,213, 52,163, 25,255,187,168, 79,139, 16, 4, 81, 87,142,189,130, 58, 62,123,208,208,113,245,240,
-252, 25,168, 55, 43,188, 73, 83,240,138,139,139, 11,175, 95,191,135,171,145, 43,112, 45,114, 5,158,198, 60, 66,110,142, 14, 57,
- 5, 26,152,155,155,223,105,224,208,215, 51,199, 50, 42,149,106,228,162,197,223,228, 11,132, 34,244,234,215, 15, 14,182,118, 16,
-113, 57, 96, 25,105,176, 8, 14, 20, 69,150,120,254, 88,133,175,119,238, 43, 84,168, 84, 35,235,232, 36,250,215, 39, 50, 8,130,
- 0,223,220, 12, 60,137, 25,248,102,230,175,184, 17, 5,230,230, 16,152,153,131,205,227,213, 21, 12,255, 7, 78,133, 66, 49,106,
-244,232,209,101, 21, 21, 21,152, 54,109, 26,174, 93,187, 22,115,254,252,121,243,199,143, 31, 11,139,138,138,218, 0, 24, 0, 96,
- 91, 3, 34,235, 21,206,178,178,148, 74,198,168, 29,187,250,155,207,213, 26,163, 53, 66, 38, 29,130,152,204,130,145,162,193, 0,
-144, 89,241,208,189,255,114, 20,234,186,225,208,214,149, 42, 90,175,153,240, 90, 14,173, 87, 56, 25,134, 97,236,237,237,255,112,
- 14, 46, 93,186,132,144,209,163, 16, 60, 98, 56,108, 93,221, 97,215,127, 32,130,167,205,196,214,173, 91, 65,146, 36,108,108,108,
- 94,239,120,107, 56,247,196,130,115,224, 9,136, 3, 79, 64,236,142, 1, 27, 64,232,190,125,251,190,243,241,241,185,114,235,214,
-173,117, 0,198,214,254,173, 90, 88,242,154, 53,171,174,107,180,112,206,156, 57,234,164,164, 36,136,197, 98, 24,141, 70,220,186,
-117, 11, 63,253,244, 19,190,255,254,123,196,196,196,192,218,218, 26,173, 91,183,134, 86,171,197,131, 7, 15,212, 0, 22, 54,192,
- 73, 23, 21, 25, 71,109,218,180,166,100,240,224,158,216,185,243, 71, 56, 56,116, 3,135,237, 0, 54,199, 22, 98,137, 39,126,253,
-229, 59,188,255,190, 31, 78,158, 56, 92, 90, 92, 98, 28, 5,192,104,194,189,164,185,119,239, 30,182,110,221,138,209,163, 71,231,
-132,132,132, 80, 21, 21, 21, 53, 22, 45,134, 97,192, 48, 12,150, 84,197,152,105,181, 90,126,125,156,211,191,142,203,153,191,242,
-233,178,130,252,156,174,215,174,220,249, 32,234,252, 37,164, 38, 69, 33,234,252, 37,220,136,186, 29, 86,144,159,211,213,175, 75,
- 91,238,200,105,179,190,218, 19,113,140, 37, 49,119,196,158,136, 99,172,241,179, 63, 95,217, 57,184,239,194,198,238,249,170,235,
-200, 40, 10, 11,194, 87,173,219,172, 48,234, 53,228,191,126,216,146,171, 46,202, 91, 88,235,190,100, 26,187, 63,213,106,245, 54,
-141, 70, 35,211,104, 52, 50,173, 86,187, 48, 61, 61,189,215, 23, 95,124, 81, 68, 81, 84,141,181,180, 40,254,228,157,196,155,187,
- 87,217,217, 72,133,221,252, 59,182, 91,191,237,232,213,204,172,130,223,106,229,208,170,171,156, 26,133, 90, 51,106,248,200,137,
-202,242, 50, 45, 2, 63, 15, 3, 45,144, 64, 75, 1, 6,134, 5, 35,193,198,147, 21,235, 33,180, 50,195,254,180,104, 85,133, 65,
- 63, 10,175,230,208,106,168,238,111,131,102,206,102,206,102,206,127, 38,231,127, 51, 28,241,234, 90,135,142,175, 88,180, 26,155,
- 82,233,228,228,212,107,216,208,254,232, 51,120, 17, 24,134, 65, 98,244, 90,148, 21, 61,131,147, 3, 31, 41,153,242, 64, 0,215,
-154, 80,152,204,244,172,172,174,115, 22, 46,138, 8, 25,208,175,189,151,171, 43,191, 85,171,150, 16,219,217,161,184,184, 8, 55,
-239,198, 27, 86, 30, 56, 18, 87, 37,178, 76,114, 76,210, 52,253, 50,200, 29, 64,191, 57, 95,131, 96,177,128,170, 52, 14,213, 29,
-163,171,127, 55, 16,108, 54, 40,134,134, 86,171, 53,101,182, 92,246,139, 23, 47, 70, 77,152, 48,225,114,100,100, 36, 25, 28, 28,
-236,123,252,248,241,183, 89, 51, 15,202,194,164, 43, 0, 6,175, 12,159,113,168,107,223,225,230, 30, 29, 59,115, 59,183, 98, 65,
-111, 32,144,155,147,129,200,136,251,250,248,123,231,229,140, 81, 51, 86, 85,156,116,165, 33, 46,189, 94,159,217,166, 77, 27,251,
-173, 91,183,214, 4,195, 83, 20,133,226,226, 98,220,185,115, 7,222,254, 1,104, 63,229, 67, 20, 21, 21, 97,211,166, 77,104,209,
-162, 5,134, 12, 25,130,210,210, 82, 24,141, 70, 83, 29,190, 20,128,243, 85, 27, 94, 19, 89, 68,213, 18, 64, 13,186, 13,221,221,
-221,121, 26,141,198,151, 97, 24, 22, 65, 16, 27,117, 58,221,228,240,240,112,199, 85,171, 86,161, 93,187,118, 40, 46, 46,134, 88,
- 44,134,135,135, 7,138,138,138,112,255,254,125, 74,165, 82,109,197,203,133,172,139, 26, 41, 95,242,253,251,105, 93, 63,251,236,
-147,136,239,214,204,240,208,104,251,240,172,172,122,128, 97,140, 40, 42, 74, 71,165,252,150,126,249,178, 93, 47, 10, 10, 13, 35,
- 1, 36,153, 88,231,111,103,205,154, 5, 0, 2, 0,139, 82, 82, 82, 98,219,183,111,239, 81,159, 69,203, 20,108, 56,154,163, 1,
-112, 96, 84,176,108,174,188,248,177,135, 21, 59, 61,173,171, 23,189,105,195,209, 28,141,185, 76,185,162, 56,253,218,243, 60,229,
-249,173,123, 34,142,177, 38,141, 24, 69, 57, 75,146,194, 4,118,204, 81, 19,168, 25, 31, 31, 31, 23,130, 40,117, 43, 44,121,246,
-112,234,180, 25, 99, 44,184,234, 51, 62,206, 37,173,201, 22,126,130,152,152,152, 52, 52,113,102,104, 21,158,231,228,228,244, 10,
- 15, 15, 63,207, 48,204, 43,177, 9,133,197,165, 81,129,131,103, 49,229,229, 21,177, 69, 9, 39, 77,201,165,118,255,126,116, 76,
- 63, 47,111,191, 99,223,173, 90, 99,223,103,206, 23,236,231, 87,174, 2,148, 1, 25,215,174,130,226,235,232,245,183, 47, 22, 84,
-232,245, 35,208,156, 21,190, 25,205,248,159,183,102, 53,164, 69,254,225, 24,132,122,130,225, 77,174,140,187,155,211,249,118, 30,
-173, 6,180,112,182, 5, 0,164,164,229, 34, 37, 45,231, 66, 74,106, 78,112, 35,138,183,190,233,149, 53,139, 74, 19, 85, 41, 28,
- 24,211, 22,149,126,133,211,218,218,250, 33,155,205,118,110,202,217,160, 40, 42,183,184,184,216,207,196,114,142,119,117,117, 93,
-147,145,145, 17, 65,211,244,220, 38,170,253, 58, 57,171, 23,149, 38,217,188,254,140, 81,231, 13, 0, 4,155,103,202,162,210,181,
- 57,189, 37, 18,201, 54, 14,135,211,162,250, 58, 86,199, 96, 81, 20,197,210,235,245, 2,138,162, 88, 0, 8,146, 36,141, 28, 14,
- 71, 67, 16,132,209,104, 52,102,106,181,218, 25,248,119,194,209,134,234,222,104, 71, 95, 37,180, 80,135, 69,235, 18, 0, 36, 37,
- 37,181,149, 74,165, 99, 9,130, 24,205, 48,140,103,101,101,165,118,241,226,197, 49, 71,142, 28,145,187,186,186,190, 55,104,208,
- 32,226,241,227,199,136,139,139, 99, 74, 74, 74,142, 86, 89,177, 82,154,120, 47,145,124, 62,107,156,149, 21, 57,136, 97,224, 3,
- 6, 4, 65,226, 73, 69, 5,125, 70,165,162,126,171, 18,140, 77,189, 63,171,241, 65,171, 86,173,118,165,165,165,113,234,179,164,
-214, 87,247,215,177,118, 97,199, 69,129, 61,123,142,186,115,227,198,241,249, 43,159, 46,171,253,221,236,225,210,169,227, 63,157,
-179,246,192,150, 31,230,111,254,189,108,167, 41,229,244,245,245,117, 39, 8, 98, 44, 0, 47,134, 97,218, 48, 12, 33, 32, 8,166,
-140, 32,136,167, 0, 30,235,116,186,200,248,248,248,236,183,168,251,155,140,112,235,227,172, 89, 84, 26, 20,213,137, 2, 24, 19,
- 23,149,254,187,203,217,204,217,204,217,204,249,159,227,252,111,198, 71,117,124,102, 90,102,248,106,164,164,230, 4,167,164,230,
-160, 77,155, 54, 76,114,114,114,147, 68, 90,125,157, 52, 69, 81, 7, 85, 42,213,193,183, 33, 41, 41, 41,233,252, 23,159,188, 3,
-105,105,105, 7,254, 76,194, 42, 33,181,172,106,123, 83, 60, 81, 40, 20, 1,166,238,172,215,235,255,138,115, 67, 84, 89,179,150,
-214,183,195,128, 1, 3, 50,244,122,253, 37, 0, 89, 4, 65, 88, 2, 40,213,235,245,231,141, 70, 99, 65,114,114,114,231,245,235,
-215, 87,103,190, 95, 14,224,225, 27,150,131,214,106,169,253,185,185,212,254,191,160,142,204, 60, 4, 45, 0, 0, 32, 0, 73, 68,
- 65, 84,251,117, 58,221, 60,107,107,235,214, 26,141,134,167,209,104,184,181, 39, 31, 8,133,194,162,134, 2,226,107,195,210,140,
-216,205,101,151, 89, 91,154, 17,175, 11, 41, 88, 57,225,152, 90, 25,215,206,202, 9,199, 76, 45, 88,108,108,108,138,143,143,207,
- 62,146, 36, 93, 25,134,177, 7, 24, 11,134, 65, 17,195, 48,197,108, 54, 59, 39, 62, 62, 62,231, 31,212, 8,105,140, 52,189,206,
-168,211,253, 59,238,176,121,118, 97, 51,154,209,140,255, 63,168, 55, 70,139,221, 84,166,228,228,100,162,249,124, 54,163,182,216,
-106,232,203,140,140, 12, 45,128,219, 85,219,235,120, 8, 96,200, 63,189,130,121,121,121,126,245,125,103,170,200, 2, 94,198,108,
- 1,113,117,102,103, 95,178,185,172, 18,155, 35,190,106,106,217, 30, 61,122,148, 9, 19, 93,236,205,104, 70, 51,154,209,140,191,
- 12,111,111,209,106, 70, 51,154,209,140,102, 52,163, 25,205,104, 70,157,216, 94, 75,112,189, 98,221, 34, 80,255,204,129,166,248,
- 94,223,100,246,193,165,102,206,102,206,102,206,102,206,102,206,102,206,102,206,255, 57,206,255,175,248,131,200,250, 59,208, 60,
-245,181,153,179,153,179,153,179,153,179,153,179,153,179,153,243,127, 65,100,189,190, 1,104,118, 29, 54,163, 25,205,248, 31,198,
-145, 35, 71, 76, 90, 84,116,220,252, 95, 7, 75, 36,210,197, 10,121,197,154,131,235,166, 30,175,254, 60, 36, 36,132,106, 62,139,
-205,104, 70, 51,240, 38,193,240,110,110,206, 29, 72,138,238,206, 48, 36,139, 33, 25, 3, 33, 87, 31, 74, 41, 43,123, 37,237,128,
-139,139,139, 37,135,196, 16,130, 97,196, 4, 65, 83, 52,139,188,149,154,154, 29,223,132,130,241,164, 82,233, 44, 46,151,219, 95,
-167,211, 57,147, 36,153,173,213,106, 47,169, 84,170, 31,241,199,196,133,255, 49,180,109,219,118,252,213,171, 87, 45,123,244,232,
-161, 21, 10,133, 70,181, 90,205, 62,119,238, 28,255,253,247,223, 47,127,241,226,197, 27,205, 72,148,201,100,125,127,253,245, 87,
-183,224,224, 96,180,105,211, 70, 57,118,236, 88,110, 96, 96, 32,119,218,180,105,169,185,185,185, 81, 77,164,235, 64, 16,196, 94,
-130, 32, 88, 52, 77,135,226,223,169, 27,254,108,144, 36, 73,206, 32, 8, 98, 4,195, 48,238, 4, 65,164, 48, 12,115,156,166,233,
-134, 18,183, 54,132, 81, 0, 6,146, 36,233, 7, 0, 52, 77,199, 0, 56, 3,152, 62,243,238,239,228, 20,137, 68,190, 0,160, 82,
-169, 98,255, 44, 78,130, 32,124, 1,128, 97,152, 55,229,156, 34, 20, 10,167, 3,128, 90,173,254, 5, 38, 44, 7,245, 58,152,173,
-158,140,223,210, 68, 0, 64,204,183,158, 0,128,166,188, 39,102, 38, 18, 77,249,173,186,248,154,194, 81, 7, 6, 78,152, 48, 97,
-213,111,191,253,246, 45,128, 19,127,197,141,239,224,224,242,227,247, 63,108,151,125, 62,235,195, 53,120,185, 34, 68,195, 15, 36,
-240, 46,143,197, 26,170,163,168, 27,241,192, 17, 0,108, 43, 43,171,241, 60, 30,175,151, 78,167,115,100,179,217,121, 58,157,238,
-122, 69, 69,197, 1, 52,176, 2,130,201,231, 53, 1, 82,189, 10, 14, 4,253,239,117,222, 24, 18, 90,174, 8,249, 68,123,148,253,
- 3,154, 81, 18,192,156,170,186,238, 64,253,233, 60, 26,106,124, 62,151,201,100, 35,228,114,185,138,197, 98, 49,120, 57,235,249,
-229,159,151,223, 19, 52, 77, 23,150,150,150,134, 54,198, 37,110,129,118, 60, 49,177,151, 50, 64,109,212, 50, 31, 43,179,144, 40,
-113, 65, 55, 6, 8,101, 0, 87,146, 69,218,210, 52,157, 7, 32,138, 52,226,148, 34, 23,201,255,208,206,189,101,213,121,109, 85,
-245,158, 3,192, 30,192, 99, 0,159, 3, 80, 52,235,159,191, 13,175, 7,195,159, 6,144, 87, 35,180,106,165,187,239, 51,120,240,
-224,107,110,110,206, 29, 70, 15, 31,185,106,230,140,143, 9, 22,139, 68,220,211,167,236, 15, 66,167, 12,144, 74,165, 78, 18,173,
-182, 61, 8,130, 86, 9, 4,113,114,121, 69,206,145, 3,191,153,121,182,107, 71, 81, 20,141,173,219,126,126,255,232,239, 17, 11,
- 76, 20, 91,109, 29, 28, 28,246,134,133,133, 57, 12, 29, 58,148,229,224,224,128,244,244,116,203,131, 7, 15,182,219,188,121,243,
-152,178,178,178, 80, 0,207,223,160,178, 61, 29,172,200, 1,102, 66,162, 31, 42, 41, 84, 26,112, 57, 95,141, 11, 0,110,188,233,
-217, 83,169, 84,179, 85, 42, 85,128,191,191, 63,179, 99,199, 14, 98,242,228,201, 12, 65, 16,132, 90,173,222, 13,224,141,132,150,
- 88, 44,222, 18, 28, 28,236,225,225,225,145,242,226,197,139,129,135, 15, 31, 62, 51,105,210, 36,119,177, 88,156, 4,160,109, 19,
-233,118,149,148,148,248,168,213,106, 56, 59, 59,239, 0,240,206, 95,112, 19, 17, 44, 22,235,184,147,147, 19,179,118,237,218, 19,
- 62, 62, 62,246,165,165,165,198,175,190,250,170,255,221,187,119,223,167, 40,106,104, 19,196,150,148, 32,136,109,246,246,246, 54,
-107,214,172, 73,238,220,185,243, 99, 62,159,207, 75, 74, 74, 18,205,155, 55,111,238,243,231,207,199, 48, 12, 51, 3,104, 82, 7,
- 33, 37, 8, 98,155, 76, 38,179, 89,181,106, 85,186,159,159, 95, 28,151,203,229, 38, 37, 37,137,191,254,250,235,207, 19, 19, 19,
-223,136,147, 36,201,173, 1, 1, 1,210,111,191,253, 54,161, 93,187,118,183, 89, 44, 22, 47, 59, 59,155, 92,178,100,201,172,139,
- 23, 47,134,208, 52, 61,243, 77,202,105,103,103, 39, 93,178,100, 73, 66, 96, 96,224, 93, 46,151,203,125,246,236, 25, 25, 22, 22,
- 54, 43, 57, 57,217,228,114, 90, 89, 89, 5, 17, 4,177, 61, 63, 63,159, 13, 0,142,142,142, 93,204,205,205, 55,215, 94,211,178,
- 58, 21,133,193, 96,168,212,104, 52, 19, 74, 75, 75,235, 76,132, 59, 57,124,211, 16, 0,216,172,175,126,255,242,181,177,247,192,
-214, 83,166, 84,218,215,225,101, 94,188,239,149, 83,135, 3,192,248,170,165,194,191, 87, 2,108, 54,155,246,117,248,156,137,205,
-111, 82,202,152, 97,125,251,246, 93, 18, 21, 21,245,115,159, 62,125,190,222,183,111,159, 93, 86, 86,214,119, 55,110,220,112, 25,
- 55,110,220,228,203,151, 47,175, 46, 46, 46, 62,250,103,221,252, 60, 46,159, 79,144, 4,132, 2,145,185, 41,251,115, 72,114,240,
-237, 97,195,166,255,242,236,153,223,230,196, 68, 55,165,163, 99,192,103,159,125,102, 63,114,228, 72,210,197,197, 5,201,201,201,
-214,251,246,237,107,255,203, 47,191,140, 40, 47, 47,159, 3, 32,227,109, 68,150,178, 28,222, 90, 29,252, 24, 6,150, 53, 15, 44,
-129,114,190, 30, 49, 76, 2,158,252, 3,196,214, 55,187,118,237,250, 54, 57, 57, 25,171, 87,175, 6,128, 31,155,120,252,188, 97,
-195,134, 13,138,136,136, 16, 30, 57,114, 68,232,239,239, 15, 7, 7, 7, 84, 13,166,106, 18, 83,187,185,185,153,118,206,104,124,
-191,241,204,212,119,226, 74,207, 98,203,200,252,213, 66,103, 24,187, 13,243, 24, 49,120,178, 31, 44,108, 69, 16, 72,216, 40, 47,
-145,123, 61,139,201, 10,190,114, 56,249,187,228,232,162, 53,202, 76,124,131,250,115,242,253, 71, 96,109,109,189, 35, 53, 53, 53,
- 72, 44, 22,191,242,121, 74, 74,138,175,135,135, 71, 5,128, 47,154, 42,220,108,109,109,247,211, 52,173, 45, 41, 41,249, 16, 0,
-204,204,204,126, 19,139,197,210,188,188,188, 5,127,213, 64,166, 26,175,107,145,255,114,139, 86, 77,188, 86, 93,107, 29, 18, 36,
- 69,119,159, 57,227, 99, 98,236,248,113,249,201, 41,169, 52,155,195, 27,127,238,252,121, 81,135, 14, 29, 72,237,143, 63,194, 88,
- 84, 4,195,220,185,221, 46, 93,186,100, 8, 25, 63, 81,205, 97, 17,187,220,221, 92, 69,135, 14, 28,116,136, 56,118,180, 59,128,
-198,132, 22,207,193,193, 97,239,213,171, 87,157,220,220,220, 80, 94, 94,142,244,244,116, 40,149, 74,140, 25, 51,134,211,189,123,
-119,167,209,163, 71,239,173,168,168,232,209, 4,203,150,125, 27,103,118,228,140, 41, 35,219,190, 63,160,187,216,201,165, 53,152,
-124, 13,178, 94, 36,250, 71, 94,189,251,217,174, 99,103,158, 39, 87, 48,131, 81,247,218, 72, 13,162,184,184,120,254,136, 17, 35,
-142, 5, 5, 5,217,242,249,124,200,100, 50, 98,232,208,161,133,185,185,185, 75,223, 88,181, 84, 45, 97, 67,146, 36, 85,251,181,
-142,229,129, 76,129,179, 84, 42,133, 84, 42, 5, 0,167,183, 29,121, 90, 90, 90,254,104,102,102, 54, 90, 46,151,171, 73,146,100,
- 8,130, 96,116, 58,157, 80, 42,149, 62, 74, 72,124, 46,211,106,181,109,214,109,252,229,135,190, 61,125,204, 47, 94,188,136,145,
- 35, 71, 50, 23, 46, 92,152, 97,234, 58,117, 4, 65,108, 27, 49, 98,132,106,241,226,197,154,228,148,116,167,132,231, 41,132, 88,
-192,163,109,108,108, 56,247,239,223,103,111,216,176, 65,176,100,201,146,109, 12,195,140,110,194,249,220, 54,110,220, 56,253,151,
- 95,126,153,247, 44, 57,213,238, 73, 66, 50, 35, 17,112,140, 54, 54,214,172,187,119,239,210,111,194, 73,146,228,214,249,243,231,
-203,103,204,152, 81, 86, 82, 90,225, 80, 38, 87, 48,124, 14,203,224,224,224,192, 62,113,226,132,118,255,254,253,228,244,233,211,
-183,210, 52, 29,210,132,243,187,117,232,208,161,149, 97, 97, 97,229, 73, 41,105, 14, 79,226,159, 67,196,231, 24,236,237,237, 88,
- 15, 30, 60,208,175, 91,183,142, 92,177, 98,133, 73,229, 20,139,197,123, 14, 31, 62,204, 62,113,226,101,219,119,231,206, 29,210,
-221,221, 93, 84,123, 31,181, 70, 11,146, 0,138,139,139, 69,129,129,129,123, 0,252, 33,185,175,223,210, 68, 76, 14, 7,102,207,
-158,157,215,212,155,197,207,241,179, 70,247,161,126,246,100, 54,168,166, 14,103,179,217,244,244,233,211,243, 95,255, 94,163,209,
- 16, 0,134,226, 59,211,197,214,192,129, 3, 23,158, 62,125,186,245,190,125,251,214,239,223,191, 95, 7, 0, 2,129,192,230,224,
-193,131,171,199,140, 25,131, 49, 99,198, 44, 62,122,244,232,159, 38,180, 40,134,210, 3, 0, 95,192,231, 39, 38, 38, 18,158,158,
-158, 13,102,220,215,211,244,195, 95,158, 61,235,252,137,167,167,127, 41, 77,183,225,190,255,190, 98,222,188,121,197,114,185, 28,
-233,233,233,208,235,245,152, 60,121, 50,171, 79,159, 62,178, 49, 99,198,108,170,172,172, 28, 5, 64,111,194, 61,185,206,201,201,
-233,163,138,138, 10, 69,181, 85,167, 71, 40,197,238,229,107,228,119,106, 99,224,113, 89, 70,238,144,185, 52,113,225, 71, 66,233,
-233,134,155, 0,192, 85,161,168,137,131,129, 58, 97,238, 12, 55,138,131, 21,182,206,194,190, 69, 25,234,101,202,204, 6,197,210,
- 40,177, 88, 60, 92,169, 84, 30,173,234,156,219, 14, 30, 60, 24,119,239,222, 5,128,238, 85, 66,171, 47, 73,146, 31,208, 52,253,
- 43,128,134,150,114,251,108,216,176, 97,239, 70, 68, 68,152, 1,192,209,163, 71, 97, 48, 24,224,238,238, 14, 46,151, 11, 30,143,
- 7, 14,135, 83,179, 58,136,137,112,180,181,181,129,141, 5, 7, 82, 43,241,251, 95,255, 52,140,221,162,131, 57, 10,169,167, 40,
-101,202, 97,100,180,224, 90,139,209, 46,216, 18,126, 3,250,146,167,182,198, 45, 56,181, 37,161,179,138,196, 16,100, 64,251, 79,
-233,217, 73,146,228, 63,126,252, 24, 50,153,236,149,207, 89, 44, 22, 0,244,122, 3,202,197, 41, 41, 41,129,209,209,209, 8, 10,
- 10, 90,236,237,237,253,222,181,107,215, 28, 74, 74, 74, 16, 20, 20,180, 41, 59, 59,251,196, 95, 93,167,218, 90,228,255,139,169,
-139,124, 77, 73,246,121, 57, 10, 38, 89, 44, 22,137,212,148,116, 67, 80, 80,191, 73,153,153,153,146,128,128, 0,146,195,225, 64,
- 25, 21, 5,205,131, 7,144, 72, 36, 24, 49, 98, 4,231,250,245,235,230,230, 18,243,105,105,169,105,149, 44, 22, 9,134, 33, 27,
-141,121,144, 74,165,179, 22, 44, 88,224,224,225,225, 1,163,209, 88,147,209,220,104, 52, 34, 43, 43, 11, 18,137, 4,161,161,161,
-118, 34,145,104,150,137,245,104,213,214,221, 46,230,234,153,109,239,204,155, 57, 80,220, 86,116, 17,226,172, 57,144, 28,253, 4,
-237,115,207, 33,108,120,128,248,194,150,197,126,173,101, 86, 49,181, 76,172, 38, 67,171,213,222,140,139,139,155,118,237,218, 53,
- 26, 0,174, 92,185,194, 36, 36, 36,204,120,155, 81, 40, 77,211, 40, 47, 47, 7, 77,211,172,170,247,213,175,255,209,251,193,220,
-220,124,235,123,239,189, 55, 46, 35, 35, 67,120,246,236, 89,235,204,204, 76,155,180,180, 52,219,182,109,219,178, 87,175, 94,125,
- 90,163,213,179, 12, 20,163, 51, 82,134,202,188,167, 79, 83,202, 10, 10, 98,118,238,220,169, 38, 8, 98,132,137,191, 49,202,209,
-209,209, 58, 60, 60, 28, 4, 71,212,165, 93,123,111, 15, 22, 71,104, 65,114,120, 22,106,181,134, 74, 77, 77,205, 10, 15, 15,119,
-245,241,241,145,225,165,123,205, 36, 78,153, 76,102,243,229,151, 95,130,205, 55,243,237,228,227,215,154,199, 23,155,177, 56, 66,
-179,128,128,128, 62, 41, 41, 41,185, 97, 97, 97,142,254,254,254, 77,226,244,247,247,151, 78,159, 62,221, 40, 16,154, 5,186,185,
-185,183,239,212,177,253,160,182,109,219, 14,103,179,217,198,162,162,162,140,208,208, 80,199, 33, 67,134,216, 55,133,211,206,206,
- 78, 26, 22, 22,102,116,105,233, 30, 28,252,238,128,174, 92,161,153, 5,155, 39,182, 84,169, 52,212,179,103,207, 50, 22, 45, 90,
-228,232,235,235,107,103, 10,167, 74,165,226,216,216,216,192,203,203, 11, 29,220,221, 81, 81, 81,129,136,136, 8,236,218,181, 11,
-191,254,250, 43, 14, 28, 56,128,206, 61, 6,192,204,204, 12,185,185,185,144,203,229,156,191,251,134,162,126,246,100, 54,235, 62,
- 26,250,241,199, 31,231, 78,159, 62, 61, 95, 40, 20,210,175,111, 86, 86, 86,212,132, 9, 19, 10, 66,191,222, 56,180,218,181,216,
-136, 37,235,241,153, 51,103, 94,236,219,183, 15, 29, 58,116, 64,112,112, 48, 15, 0,102,205,154,197, 27, 51,102, 12, 14, 31, 62,
-140,163, 71,143,198,123,120,120,220, 2, 48,204,148,114,134,134,134,246, 8, 9, 9,185, 17, 18, 18, 18, 59,118,236,216,237, 51,
-102,204,120,165,231,202,203,205,126,168,211,233,224,227,231, 47, 90,190,227,222,132,198,248, 18,128,125,219, 19, 19,119,173,121,
-250, 52, 99,113,135, 14,150, 45,211,210,172,118,175, 91,103, 83,189, 72,183,193, 96, 64, 86, 86, 22,164, 82, 41, 38, 76,152, 96,
-195,231,243, 67, 77, 40,230,134, 97,195,134, 77,201,204,204,148,252,242,203, 47,142,177,177,177,178,188,188, 60,199,203,151,206,
-219,126,245,197, 44, 51, 11, 9,143,151, 91,196, 16, 0,144,150, 11,113, 98, 42,122, 48, 12, 44,107,187, 19,223, 8,142, 16, 10,
-157,177,185,117, 15,203,231, 95, 30,246, 29, 27, 22,233,103, 35,117,228,135, 55,112, 68,167,181,107,215, 30, 57,117,234,212,248,
- 30, 61,122, 28, 3, 32,172, 99, 31, 65,231,206,157, 35, 14, 31, 62, 60,165,103,207,158, 55, 1,120,213, 59,138,116,118, 30,241,
-251,239,191, 91, 87,191,183,177,177,129, 64, 32,248,131,200,226,114,185, 32, 73,178,201,213, 91,121,112, 60,219,170,189, 22,113,
-101,103,112,120,237, 99,172,125,255, 25,189,170, 91,154,246,199,208, 68, 92, 56,252, 24,133,120,140,129,159,180,198,248, 69, 62,
-253, 69, 20, 86,252,147, 58,240,162,162,162, 15,122,245,234,117,100,224,192,129,218,232,232,104, 20, 21, 21,193,201,169,102,172,
-157,255, 6,148, 86, 34,145, 8, 46, 46, 46,240,240,240, 24,127,253,250,117, 7,131,193,128,180,180, 52, 20, 22, 22,198,252, 29,
-117,170,173, 69,254,203,240,122, 32,252,233, 63, 8,173,170,181,133,174, 2, 0, 67, 16,202,199,113,113, 28, 22,143, 55,241,183,
-253,251,249, 92, 46, 23, 25, 25, 25,136,143,143,135,234,242,101,168,111,223, 70, 65, 65, 1, 20, 10, 5,236,237,237,177,109,199,
- 14,177,142, 98,166, 62,123,254,156,197,144, 76,237,120,131, 58,167,120,242,249,252,254, 35, 71,142,172, 87,144,229,230,230, 98,
-224,192,129, 28, 22,139, 85,215,172,134,215, 57, 9,153, 45,113,234,242,177,229,142,142,188,120, 32,121, 30, 80, 25, 3, 48, 90,
-192,168, 3,114,158, 0,167,151,162,165, 34,145, 56,191,124,146,131,147,136,125,170, 14,165,220,216, 84, 84,119, 79, 79,207, 95,
- 39, 78,156, 72, 2, 64,223,190,125, 9, 79, 79,207,237, 0,220, 27, 56,230, 82, 35,157,228,221,178,178, 50,140, 25, 51,198,186,
-117,235,214,151,198,140, 25, 99, 93,253,249,155,114, 86, 91,147, 59,116,232, 80, 34, 16, 8, 14, 0, 38, 53,176, 53,156,150,150,
-150, 63, 14, 28, 56,112,244,254,253,251,185, 0,112,245,234, 85,156, 58,117, 10, 79,159, 62, 69, 82, 82, 18,237,231,231,103,187,
-241,215, 35, 91,127,252,121,207,134,225,221,125,100,125,186,248,181,151, 40,202, 20,246,246,246,221, 25,134,113, 55,177,156, 3,
-151, 46, 93, 26,159,240, 34,195,130,100,115,216, 92, 14,155,111,110, 46,182,151,154,137,157,173, 68, 2, 39, 62, 73, 72, 84, 42,
- 85,254,129, 3, 7,104, 0, 3, 77,229, 92,190,124,121,106, 66,114,134, 37, 65,178,217, 28, 54,135, 43,145,136, 44,223, 15, 14,
-242, 7, 0, 46, 24,174, 92, 46, 47,216,181,107,151,190, 41,156,223,126,251,109, 92,105,185, 66,202,230,112, 56,108, 54,171,230,
- 92,138,133, 66, 91, 17,159,207,211,106,181, 57, 63,252,240,131,186, 41,156, 75,151, 46,141,127,246, 34,211,138, 36, 8, 22, 65,
-144,108,115, 51,177,181,181,133,200,214, 86, 34,180, 17,177, 89, 60,185, 92,158,179,119,239, 94,147, 56,245,122, 61,183,160,160,
- 0, 9, 9, 9,112,241,247,199,197,139, 23,209,162, 69, 11,140, 25, 51, 6,227,198,141,131, 80, 40, 68,223, 64,111,132,135,135,
-227,197,139, 23,208,235,245,252,186, 56,171,227,164, 94,135, 76, 38,139,110,236,230,121,237,216, 87,202,233,235, 0,102,179,238,
-163,161,181, 5, 86,125,252, 86, 86, 86, 84, 93,214,174,215, 57, 7, 14, 28,184,240,242,229,203,173,247,238,221, 59, 52, 52, 52,
-244,230,222,189,123,209,181,107, 87, 36, 36, 36,192,213,213, 21,187,119,239,198,184,113,227,110,110,218,180,105,104,116,116,180,
-143,155,155,219,130,198, 56,199,142, 29,251,169,175,175,111, 84,126,126,126, 96,105,105,169, 87, 68, 68,196,212, 17, 35, 70,164,
-142, 31, 63,190, 95,141, 96, 52, 24,246,159, 62,121, 12,131,134,142, 68,187,142, 94, 91, 39, 47,216,231,221,200,179,201, 60, 5,
-182,239,202,203, 43,218,175,209,168,198,112, 56, 34,209,189,123, 86, 71,127,254,217,166,246,202, 2, 57, 57, 57, 24, 50,100, 8,
-135,203,229,246,108,164,156,107,135, 15, 31, 62, 38, 34, 34, 66, 90,109,213,185,125,251, 54,158, 60,121,130,244,244,116,148,151,
-151,163,223, 12, 5, 62, 94,253,146,251,227,213, 12, 6,204, 98,196,111,216,134,212, 64,216, 2, 14,214,230,236, 91, 83,127,104,
- 55,235,163,173, 29,216, 18, 43, 14,126,251, 58, 9,197,105,218,163,245,112, 18,129,129,129,251, 66, 66, 66, 8,157, 78, 7,157,
- 78,167, 3, 80,103, 86, 95, 39, 39, 39, 65,167, 78,157, 48, 99,198, 12,210,220,220,124, 83,125,229, 84, 42,149,218, 51,103,206,
- 32, 52, 52, 20,115,230,204, 65,155, 54,109, 32,149, 74,193,225,112,176,103,223, 33,155,113, 83,103,182,125,167, 71, 47,159, 14,
-239,116,237, 84,169,101,249,115,132,210,233,245, 88, 67,234,172,187,194, 46, 26,113,105,119,176,121,104, 54,125,127,183, 74,241,
-213, 7,255, 74,124,118,173,224,233,130,144,237,113,204,157,110,197,251, 62,207, 68,129, 33, 1, 61,199,180,132,155,175,116,174,
-216, 5,158,111,122, 62, 77, 68,147, 56,189,189,189,123,220,191,127,159,223,171, 87, 47,100,100,100,128,195,169, 25, 79, 81,111,
- 83,206,165, 75,151,242, 53, 26, 13, 30, 61,122,132, 73,147, 38,229,232,245,250,185,111, 83,206,166, 88,180,170,181,200,127, 25,
-182,191,182,229,213,103,209, 90, 10, 0, 6, 26,167, 38, 78,154,170,138,140,140, 20,241,120, 60,100,100,100, 32, 47, 47, 15,123,
-118,237,162,250,218,217, 85, 6, 59, 57,201,247,236,218,197,232,116, 58, 48, 12, 3, 79, 79, 79,140, 30, 61, 90, 56,106,204,248,
- 66, 66,174, 62,100,130,155,199,177,218,191, 62,117,234,212, 63,124,255,213, 87, 95,193,220,220, 28, 4, 65, 56,152, 80,185,144,
-207,150, 14,119,150,186, 89, 22, 48,249,123, 74,193, 18, 0,108, 51,128,109, 14, 8, 44, 0,190, 25,192, 19, 65, 27, 29, 85, 74,
- 50,193,233, 35,123,126,232, 4,160, 41,174, 30,200,100,178,197, 81, 81, 81,182,209,209,209,140, 92, 46, 71, 94, 94, 30,179,106,
-213, 42, 91,153, 76,182,248, 77,175, 72,110,110,238,242, 65,131, 6, 21, 76,154, 52,201,226,220,185,115, 46,147, 38, 77,178, 24,
- 52,104, 80, 65,110,110,238,242,183,185,210, 92, 46,151,245,244,233, 83,171, 21, 43, 86,140, 3,240,176, 99,199,142, 37, 78, 78,
- 78, 15,241, 50,104,178, 65,152,153,153,213,136,172,106,235, 26,155,205, 6,135,195,129, 76, 38,211,149,150,150, 82, 61,223,113,
- 23,122, 90,144, 6, 25,159, 43,180, 18, 10,156,205,204, 45, 2, 74, 74, 74, 30, 19, 4,145, 98,162,139,207,183, 75,151, 46, 28,
-138,225,208, 31, 79,236, 43,155, 53, 37,200,238,167, 21,211, 91,252,176,252, 35,167,181, 75,166,121, 46,159, 63, 33,136,164,105,
-141,171,171,171, 67,117, 64,187, 9,230,115,191,206,157, 59,179,105,112,144,240, 60,189, 32, 35, 59,167,242,221, 62,129, 53,150,
-203, 14,190,126,193,182,182,182,189, 60, 61, 61, 59, 19, 4, 97,210,148,100,161, 80,232,219,174, 93, 59, 54,201,226, 16,214, 82,
- 51, 23, 51,137,208,190,198,133, 98,105,217,205,202,214, 54,132,100,152, 10, 71, 71, 71, 59,161, 80,232,219,132,186,179,105,112,
- 97,111,103,101, 97,107, 99, 41, 9, 14,234,222, 38,176, 91, 96, 91,239,128,174,129, 29,223,233, 60,138, 48, 26,229,238,238,238,
-118,213, 65,242,141, 88, 90, 5,251,247,239,199,138, 21, 43,208,169,101, 75, 56, 57, 57,193,206,206, 14,183,111,223,198,253,251,
-247, 33,149, 74, 81, 88, 88,136,117,235,214,225,248,241,227,208,235,245,102, 77,189,159, 76, 17, 91, 13,193,104, 52,146,175, 11,
-172,250,248,133, 66, 33, 93, 29, 36, 95, 31,206,156, 57,179,175,218,146,245,249,231,159,247,216,184,113,227,205,196,196, 68, 72,
- 36, 18,220,191,127, 31, 83,167, 78,189,185,105,211,166, 30, 51,103,206,196,174, 93,187,144,154,154,186,163, 33,190,177, 99,199,
- 46,153, 54,109,218, 15,215,174, 93, 35,237,237,237, 33,149, 74, 49,124,248,112,236,216,177,131,109, 52, 26,119,134,132,132,196,
-134,132,132,196, 82, 89, 23, 22, 30,249,117,213,237,184,199,177,248,244,179, 47,121, 58,163, 33,204,132,234, 51,106,137,164,210,
-216,171, 87,233, 97,131, 65, 53,150,203, 21, 89,196,198, 90,157,218,185,179, 70,108,133,135,135,195,194,194, 2,120, 25,192,140,
- 6,172, 58, 31, 29, 63,126,188,166, 61,180,182,182, 6,143,199, 3,151,203, 5,135,195, 1,139,197,194,165,173, 98,252, 28,254,
- 82, 95,252, 28, 78,224,194,143,132,242,109,174,157,200, 9, 94, 82,123, 94,236, 39,187, 59,250,120,245,179,198,237,131,249, 88,
- 53, 40, 58,251,254,225,162,121,154, 66,124, 95,207, 97,239,124,245,213, 87, 29, 10, 11, 11,241,224,193, 3, 60,120,240,160, 62,
- 11,144,230,228,201,147,223, 41, 20, 10,184,185,185, 97,216,176, 97,189, 0,248,215,243,220,160,115,231,206, 24, 50,100, 8,130,
-130,130,208,169, 83, 39,232,244, 70, 78,200,196,143,218, 61, 77, 45,114, 90,181,110,149, 40,234, 74, 4,121,243,230, 53,214,190,
- 99, 23, 44, 2,131, 6,252,192, 53,115,188, 11,161,181,163, 41,245, 84, 81, 37,240,117,124, 31,219, 47,127, 70,110,190, 58, 73,
-178,231,212,102,119, 51, 51, 51, 34,230, 65,172, 97,207,150,195,153, 94,226, 97,133,119, 15,150, 64, 69,228,163,223, 20, 55,146,
- 6, 70,255, 83,122,118,129, 64,176,241,218,181,107, 14,122,189, 30,113,113,113,152, 51,103,142,230, 45, 41,107, 12, 32, 46, 46,
- 46,184,122,245, 42, 38, 76,152,160, 41, 40, 40,184,243,119,213,169,182, 22,249,255, 2,118, 45, 5, 89,131,172,172,172,114,169,
- 84,234,212,174, 93, 59, 82,167,211,189,116, 73, 28, 61, 74,253,186,115,231,105,141, 70,243, 25, 0,238,143, 63,253,180,213,201,
-217, 57,104, 98,104, 40, 97, 48, 24, 48,104,208, 32, 94,100,100,164,117, 74, 97, 97,165, 9, 29,206, 43,191, 55,121,242,100,108,
-220,184, 17, 0, 48,123,246,236, 26,211, 58, 97, 66,192,146,196, 2, 3,131, 7,119, 54,207, 18,111, 54,215,119, 51, 40, 90,189,
- 48,187, 43, 86, 8, 59,131,228,177, 33, 96,129,214, 27,140, 73,133, 35, 30,190, 72,106,223, 65, 88, 90,226,218,191, 99,111,252,
-122,113,239, 64, 21,165, 57,108,114,131, 35, 18,117,145, 72, 36,120,248,240, 97,105,231,206,157,203, 25,134,177, 88,190,124,185,
-141, 72, 36,234,242, 22,231, 62,237,249,243,231,189,186,119,239, 62,139, 36,201,254, 52, 77, 95, 42, 40, 40,248, 17, 64,154,137,
-199,127, 12,224, 91, 0, 53, 35, 75,157, 78, 7,146, 36,193, 48, 12,198,142, 29,139,240,240,240, 14, 79,158, 60, 65, 84, 84,148,
- 85,255,254,253,239, 2, 40, 7,240, 33,128, 58,173,102,114,185, 92,125,255,254,125, 97, 84, 84, 20,104,154,134,149,149, 21,204,
-205,205,193,231,243, 49,124,248,112, 73, 88, 88, 88,191,243,231,207, 23,202, 91,181, 96, 9,242,114,148,124,137,196, 12, 14, 78,
- 61,103,142,255, 32,145, 97,152,227, 77,104, 28,120, 66,182, 81, 67, 80, 90,114,237, 55,155, 72, 17,151, 75, 8,184,108,240,105,
- 21, 22,126,183,146,224, 50, 20, 27, 77,244,207,115,185, 92,174, 25, 31, 58, 22,143,101, 16, 17, 96,254,140,135,131,197, 98,241,
- 4,220,250,227, 49, 56, 36, 73,146, 36,201, 5, 96,242,162,125,124, 62,159,107,198,103,234,229, 20,178, 8, 22, 65, 16, 60,212,
- 51, 19,205,215, 1, 76,181, 21,137,247, 89,138,182,182, 40,238,217,179, 39, 78, 71, 61,196,209, 83,151, 80,156,241, 24,139,190,
-254, 28,254,254,254,136,140,140,108,176, 76,213, 49, 90,245, 89,151,101, 50, 89,116,110,110,238, 59,245, 29,219,144,203,176, 30,
- 43,213, 31,249,191,177,128,223,210, 68, 52, 18,163, 53,172,103,207,158,159,238,223,191, 95,247,222,123,239,241,198,142, 29, 11,
- 47, 47,175, 30, 83,166, 76, 1, 0,244,239,223, 31, 27, 55,110,236, 49,101,202, 20, 28, 58,116, 8, 17, 17, 17,218, 62,125,250,
-124,125,245,234,213, 28,188,156,209,249, 7,208, 52, 61,100,219,182,109,175, 91, 10, 97, 52, 26, 97, 48, 24, 28,141, 70,163, 99,
- 85, 91,132, 31,126,216, 84,124,225,124, 36,190, 94,176, 20,118,182, 14,190, 38,222, 67,196,228, 47,191, 44,222,189,110, 29,214,
- 29, 58,132, 47, 93, 93, 69,123,227,227,113, 65,163,193,225,168,168,226,170,223,105, 52, 54, 83,169, 84,170,207,156, 57, 99,126,
-248,240, 97, 88, 90, 90,162, 77,155, 54,176,178,178, 2,135,195, 1,201, 18,130,197,149,162, 93,199, 46, 0,238, 3, 0, 92,101,
- 80,122,186,225, 38, 65,160,156, 33,155, 30, 83,196,111,129, 86, 54,206,130,107,159,238,242,178, 52,183,227,226,220,143,153, 56,
-191, 57,235,184,166, 24,235, 97,196, 51,212, 31,243,213,217,205,205, 13,133,133,133, 56,115,230,140, 18,168, 87,144,129,166,233,
-239,126,250,233,167,175, 22, 44, 88,192,247,244,244, 4, 0, 95, 0, 15,234,218, 87, 44, 22,195,201,201,169, 70, 88,142,157, 52,
-211,125,198,188,153,194, 17, 3,130,192,102,219,160, 92,105, 64, 73,165, 1, 82, 27, 9,190,158, 23, 34,184,212,217,201,127,219,
-166,223, 78,170,213,240, 7,254,216, 30, 16, 4, 30,220,123,124,211, 91,224, 9, 16, 36,144, 69, 94, 1, 1, 2, 10,194, 0,130,
-197, 98, 40,138, 66,102,102, 38, 24,134,193,132, 17, 83,179, 62, 90, 21, 97,215, 99,130, 28, 46,237,100, 32, 24,244,254,167, 8,
- 1,107,107,107,223,146,146, 18,164,165,165, 97,210,164, 73, 57,197,197,197, 23,149, 74,229,212,220,220, 92, 0, 40,125, 3,202,
- 26, 49,239,235,235,139, 46, 93,186, 96,204,152, 49, 2,149, 74, 21,226,238,238,238, 84, 84, 84,212,237,175,172,207,235, 90,228,
-255,149,208,170,243, 65, 51, 24,218,105,183,110,133,242,210, 37,240, 46, 92,192, 97,153, 76,161,209,104,190, 0,144, 85,245,224,
-127,190,107,247,238, 91, 67,239,220, 49,215, 37, 38,194,253,201, 19,112, 44, 45,125,155, 90,128,157, 59,119, 66, 46,151,163,162,
-162, 2, 0,176,121,243,102,200,229,114, 24, 77, 92,112,150,205, 69, 15, 7, 59, 87,228, 35, 9, 52,155,148,164,183, 83,117,149,
-104,204,114,157, 50,237,149, 21,164, 19, 18, 51, 2,196,234, 18, 93, 87,130,165,131,166, 88, 5,167,238,109,192, 6,187, 71, 83,
-202, 88,237,247,103,179,217,165,207,159, 63, 31,210,182,109,219, 83, 0,108,222, 36, 30,224, 53, 36, 23, 20, 20,124,246, 38, 7,
-178, 88,172,111, 83, 83, 83,237,118,236,216, 49,107,249,242,229, 76,109,161, 85,253, 63,155,205, 6,195, 48,176,176,176, 0,135,
-195,177,191,125,251,182,125, 64, 64,192, 22,154,166,125,235,169, 39,227,229,229,133,212,212, 84,176,217,108, 88, 88, 88,128, 54,
-234,177,116,222, 76, 80, 44, 62,123,254,252,249,190, 35, 71,142,140,219,177, 99,135,193, 60,176,123,183,146,146,146,167,159, 78,
-152, 24,119,226,196, 9, 93, 85,138,135,198,135,248, 12, 19,155,148,148,196,114,150,217,179, 24,163,138, 22,115, 1,193,227, 31,
- 24,158,196, 1, 2, 54,139,225, 18, 36,248, 2,161, 69, 90,118,118, 9, 77,211, 9,166,112,210, 52, 29,147,154,154, 42,180,183,
-179,102,171,212, 58,133,144,195,240,210, 99, 30,166,180,242,235,236, 14, 0,154,152,251, 87,249,237,218, 11,211, 11,138,196,174,
-174,174, 38,113,170,213,234,216,156,156, 28,150,189,189, 61, 59, 35, 43,251,164,165, 68,108,107,110,105,217, 21, 0,244,149, 21,
-247, 73,173,182,136,197, 97,219, 23,149,148,148,170,213,234, 84, 83,235,254,226,197, 11,182,163,163, 29,235,220,133,203,167,236,
- 69,124, 59, 51, 30,219,156, 79, 16,132,136, 69,200,185, 70,186, 88, 32, 18,217,165,101,103,151, 50, 12, 83,175,133,112, 77,249,
-196, 17, 47,175,215,210, 67,181,184,241,248,241, 99,156,189,153, 0, 49,163, 3,161,169,192,133, 93,191, 96,194,252, 5,111, 29,
-247,215,152,216,122, 35,107,214,182,246,209,175,241, 35,175,145, 64,248, 9, 19, 38, 44,221,183,111, 95, 77, 0, 74, 66, 66, 2,
-250,246,237, 91,237,230, 64,112,112, 48, 2, 2, 2,144,144,144, 0, 15, 15, 15, 68, 69, 69,241, 89, 44, 22,127,226,196,137,171,
-126,251,237,183, 51,141,218,253,183,111,199,212,169, 83,235, 10,172,126, 1, 64, 67, 72, 61, 21,225,107,246,216,148,150, 20,163,
-176, 40, 63,214,212,243, 64, 16, 4, 38,127,249,101,241, 54,157, 14,251,239,221, 67,168, 88, 44,218,157,156,140, 65, 1, 1,240,
-238,219,183,216,148,182,174,218,170,163,209,104,192,225,112, 96,110,110, 14,107,107,107,112,185, 92,176, 56, 50,176,121, 62, 32,
-185, 92,248,245,244,193,186, 47,196,170, 73,239, 99, 19, 65,160,156,207, 67, 12, 87, 84,111,172, 14, 33,110,129,225, 12, 3,185,
- 42, 11, 87,170, 5,137, 69, 75, 88,112,204, 56, 23,166,109,241,180, 52,183,227,226,236,166, 12, 92,216,146,125, 76,147,143, 69,
- 85,231,130,110, 96, 32,225,109,105,105,137,172,172, 44,100,102,102,198,163,225, 0,127, 85, 66, 66, 66, 10,159,207,239, 96,107,
-107, 11, 0,110,245, 13,204,105,154,174,137,195,218,187,255,136,141,111, 47,119,193,187, 61, 58, 96,207,169,149,248, 36,100, 19,
- 56, 44, 2, 20,165,199,250,141,131, 65,105, 21, 8, 25,250, 17,209,187,191,135,207,165, 83,186,105, 6,117,217, 47,127, 24, 8,
-176,177,226, 95,227,110, 91,242, 37,164, 55,104,194,210,198,198, 78,204,229,114, 97,109,238,168, 91, 48, 99,110, 30,195, 48, 53,
-207, 13,135,197, 53,144,149, 86,234,146,124,133,208,146,163, 6, 24,178,213,155,101,179,249,243,145,157,157,253, 89,175, 94,189,
- 86, 85, 86, 86,150, 41,149,202, 9, 0,224,230,230,214,146, 36, 73, 62,128,134,188, 35, 45, 81,119, 90, 8,238,147, 39, 79, 96,
-102,102,134,156,156,156,218,198, 23,208, 52,253,143,153, 4,240, 15,133, 31,128, 24, 0,142, 0, 6,161, 86,122, 7,178,202, 84,
-215, 59, 50, 50,146,137,140,140,236, 93,211,121, 49, 12,109, 44, 45, 5,163,125,121,110, 57, 28, 14, 3,160,246,140, 38,145,165,
-165, 37,193,113,118, 6,193,127, 25,250,193,252,137, 83, 95, 13, 6,211, 82,203,208, 20, 88, 32,244, 96,106, 13, 90,148, 2, 2,
- 43,109,250,225, 51,222, 98,228,243, 44,107,247,116,128,145, 1, 5,154,213,196,226, 48, 74,165, 18, 70,163, 81,218,186,117,235,
-211, 70,163, 81, 90,213,185, 49,255,169, 43, 74, 81, 84, 10,139,197,194,172, 89,179, 80,109,253,209,233,116,200,207,207,135, 86,
-171,133, 78,167, 67,106,106, 42, 42, 42, 42,160,211,233,240,244,233, 83,184,185,185,129,197, 98, 57, 54,208,152, 51, 12,195,192,
-197,197, 5,173, 90,181, 2,139, 96,240,235,218, 37, 88, 56,103, 38,198,185,209,216,249,227,122,244,233,211,167,189,171,171,107,
- 32,155,205,166, 28, 28, 28,184, 17, 17, 17, 39, 41,138, 26, 14,211, 91,158, 51,225,225,225,173, 58,118,236,104,103,105,110,102,
-224,243, 88,224, 25,148, 12, 95, 91,194,176, 85,197,112,113,105,105,132, 80,228, 17, 26, 26, 74,213,103,133,168,139,243,139, 47,
-190,112,244,244,244,180,144, 90,154, 41,121, 28, 86, 33, 23, 76,113,197,227, 7,119, 1,128,103,107,167,129, 64,212, 97,210,164,
- 73,198,166,112, 46, 94,188,216,205,214,214,214,146, 4, 83, 73,233,245,255,246,183,107,117, 37, 4,135,163, 6,151,215,121,246,
-236,217, 68, 83, 56,191,250,234, 43,215, 14, 29, 58, 88, 90,154,139, 21,108, 14, 43,143, 75,211,121, 2,208,249, 28,157,190, 76,
- 96,107,163,130, 72,226, 23, 26, 26, 90, 47,103,181, 53, 43, 44, 44, 44,235, 53,225,141,210,210, 82,104,242,227,192,205, 73,132,
-143,132, 3,127, 91, 41,248,124,126,205,212,247,250,110,215,250, 98,180,234, 18, 91,166, 30,219,121, 89, 3, 46,192,109,237,163,
- 95,207,155,149,155,155, 11, 71, 71,199, 6,159,167,223,126,251,109, 65, 80, 80, 80, 97,112,112,176,238,244,233,211, 32, 8, 2,
- 81, 81, 81,200,201,201, 65,112,112, 48, 24,134,169,158,213,134,216,216, 88,244,239,223, 95,215,171, 87,175,156,170,252, 90,141,
- 98,234,212,169, 48, 24, 12, 80, 40, 20, 40, 45, 45, 69,100,100, 36,124,124,124, 24,145, 72, 52,146,229, 50, 96,101,200,180, 5,
-221,188, 58,249, 98,203,166,117, 58, 30,155,179,166, 41,207, 43, 65, 16,152,244,197, 23,197, 21,126,126,165,123,149, 74,213,100,
-115,115, 81,235,172, 44,171,135,231,207,219,232,245,122,147, 56,170,173, 58,206,206,206, 53, 34,139,203,229,130,205,179, 5, 75,
-236, 13,158,117, 48, 68, 14, 35,113, 37,134,175,181, 16,227,184,153, 4,231,196,150,245,167,118, 16,185, 96,101,183,177,142, 17,
-221,199, 57, 94, 22,181,192,142,170,254,128,100,216, 68,196,148,245,109, 91,219,182, 18,226,206,145,124, 92,216,146,253,187, 38,
- 31, 75, 0, 36, 55,246,156,235,245,122, 13, 69, 81, 32, 73, 18,108, 54,187,118, 76,224,173,223,127,255, 29, 15, 31, 62, 4,106,
-165,237,169,172,172,164, 88, 44, 22, 4, 2, 1, 0, 72, 26,104,239,192,225,112,192,225,112,112,245,238,117,235,113,163, 6, 19,
-183, 31, 93, 68,119,159,241, 40, 81,232, 81, 80,161, 71,185, 10,232,232,191, 8, 94,253,143,227,113,106, 37,124, 59,121,177, 88,
- 60,241,164,186,248, 52,105,200, 82,102, 98,116, 73, 60,221, 70,151, 45, 60,123,231, 68, 66,252,245,163,143,159, 30,252,233, 84,
-114, 55,255, 94,202, 42, 99, 2, 20, 10, 5, 67, 16, 4, 51,119,250,130,148,189, 83,203,168, 77, 19, 30,211,108,173,224,197,223,
-216,212,183,180,181,181,189,109,109,109, 29, 85, 37,142, 90,154,153,153,221,114,116,116, 76,196,203,137, 30, 39,242,242,242, 60,
-149, 74,101,119,188,156,156,149, 81, 82, 82,210,183,202,242,148,209,128, 37,108,135, 92, 46,255,156,162,168,161, 85,219,251, 20,
- 69,249, 38, 37, 37,117,240,245,245,141,119,119,119,143,117,119,119, 63,235,238,238,126,210,221,221,253,100, 80, 80,208,198,234,
-116, 15,127,177,219,240, 15, 90,228,191, 76,104,161, 74,100,109,175,122, 69,141,208, 2,112,245,245, 0, 52, 35,159,255,212,248,
-233,167,176, 60,121, 18,156,164, 36, 76,153, 52,201, 92, 36, 18,109,194,203, 28, 77,221, 37, 18,201,150, 37, 75,150,152,217,172,
- 94, 13,217,245,235, 72,143,140,132,129,195,121,240, 38,165, 83,171,213, 96,179,217, 53,150, 24,177, 88, 12,138,162, 80,151,201,
-247, 15, 15,160, 17,119,114, 10, 18,193, 67, 43,208, 96, 20,231,228,189,238,141, 79, 89,100, 23, 41,119,243, 72, 86,114, 61,150,
-217,118,206, 99,233, 94, 0, 0, 32, 0, 73, 68, 65, 84,181,219,212,178,199, 61, 37,193, 86,240, 44, 5,200,204,204, 2, 5,186,
- 73,254,102,141, 70, 83,161, 84, 42,225,235,235,107,253,240,225,195,214, 62, 62, 62, 86, 85,159,223,127,203, 11, 19, 40,147,201,
-142, 56, 57, 57,165,201,100,178, 35, 0, 2,155,112,236,142, 27, 55,110,128,197, 98, 97,201,146, 37,168,172,172,132, 94,175, 71,
- 73, 73, 9, 50, 51, 51,161,211,233,144,157,157,141,103,207,158, 65,167,211, 33, 61, 61, 29, 90,109,227, 3, 18,154,166, 97,110,
-110, 14,141, 90,129,159, 87, 46,196,226,176,121,168,120, 17,141,236,220, 2, 88, 90,136,241,217,103,159,177,164, 82, 41, 77,211,
-116, 43,138,162,250,211, 52,189,213,148,235, 84,235,126,187,233,226,226,226,181,118,237,218, 14, 11, 87,110,229,154,179, 21, 12,
-223, 76, 64,243,204,248, 12,175,125, 87, 76, 93,180,137,251,195,134,239,159,223,185,115, 39, 7,166, 37,239, 36, 1,220,244,243,
-243,107,155,147,147,227,227,233,233,217,206,166,165, 43,159,239,232, 84,206,117,108, 33,103,180,154,123,132, 83,139,158, 91,183,
-110,141,187,117,235, 86,110, 83, 56,197, 98,113,251, 61,123,246,120,217,219,219,123,113,132, 66,129,170,162,226,176, 81,165, 60,
-194,178,148, 10, 72,115,203,247,143, 31, 63, 30,125,236,216,177,252,166,112,122,120,120,120,174, 92,185,178,163,183,183,119, 71,
- 7,183,214,124,161,147, 75,137,192,185,101,137,208,219,135, 15,231, 86,239,109,217,178, 37,246,206,157, 59, 38,113,178, 88, 44,
- 35, 73,146,224,112, 56, 16,137, 68, 56,119,238, 28, 62,157, 54, 30, 46, 78,214,104,231,233,137,126,159,124,142, 99,199,142,213,
-196,240,176, 88,172,122,123,244,221,171, 63, 59,229,231, 72, 68, 99, 91,251,104,108,107, 31,237,231, 72, 68,215, 43,182,170,190,
-175,107, 31,147, 90,163,122,220,141, 38,136,173, 51, 87,175, 94,253,110,242,228,201,188,129, 3, 7,226,222,189,123,152, 58,117,
-234,205,136,136, 8, 0,192,189,123,247, 48,119,238,220,155,151, 47, 95,198,204,153, 51,209,183,111, 95,222,141, 27, 55,182,192,
-132,220, 63, 70,163, 17, 59,119,238,132,209,104,132, 68, 34,129,149,149, 21, 6, 15, 30,140,184,184,184,153,187,118,237, 74,100,
-113, 56, 31, 12, 26, 58, 10,167, 79, 70,224,217,211,184,153,187, 87, 77,108,114, 82, 96,146, 36, 49,112,210,164,226,226,142, 29,
- 75,119,203,229,170, 15,165, 82,145,103,126,190,213,149, 35, 71,108, 76, 16,106, 4, 69, 81, 53,226,170, 90,116, 84,111,108,158,
- 45,216, 98, 47,176,205,252,241, 56,153,107,224, 6, 32,134,231,143,132,134,242,103,113,120,228,212,145, 11,221, 48,114,161, 27,
-134,205,119,157, 34,106,129, 95,197, 45,240,241,192, 57,173,130,220,253, 45, 32, 47,212, 35,114,125,122,134,166, 4,171, 1, 60,
- 51,229, 57,167,105, 58, 62, 39, 39, 7, 60, 30, 15, 45, 90,180,104, 11,160, 58, 46,112,199,244,233,211,103, 47, 91,182,108, 30,
-128,101, 85,159, 73,130,130,130, 58, 42, 20, 10, 36, 37, 37, 1,192,195, 6,172,193, 53,179, 12, 75,229,233,124, 87,153, 55,124,
-218,207,128, 84,218, 9, 57,165, 58,228,150,234,240,235,207,195, 17,125, 99, 5, 30, 94, 8, 69, 70,126, 62,132, 14, 35, 64, 25,
-181, 94, 38, 12,234,101,143, 30, 61, 34,110,220,184, 65,208, 52, 13,131,193,192, 84,202,229, 76,204,205,155, 80, 95,187, 70,152,
-155,155, 19, 61,186,244, 82,236, 94,113,250,254,241, 31,111, 62,212,171,154, 60, 80,127, 27, 44, 78, 73, 73, 9, 60,114,228, 72,
- 16,128,197,222,222,222,119, 50, 51, 51,187, 93,191,126,189,157,179,179,243,166, 55, 37,173, 78, 11,145,158,158,254,202, 86,149,
- 22, 66, 87, 37, 26, 6, 86,137,185, 97, 0,230,226, 45,102,217, 55, 1, 87,255,139,131,225, 79,227,181,217,134,175, 11,173,218,
-137,194,224, 46,149,154, 25, 12,250,236,139, 23, 47,234, 73,146,132, 72, 36,194,228,169, 83,201,159,127,250,169,231,248,192,192,
-168,143,222,125,247,108,212,229,203,126, 1, 1, 1, 96, 24, 6, 36, 73,226,208,161, 67,106,141, 70, 93,226,226,226, 98,105, 74,
-163, 81,251, 1,146,203,229, 53, 66,171,162,162, 2,246,246,246, 38,187, 14,149,114, 92,186,124, 46,186,140,161, 62,201, 28,152,
-188, 65,191, 38,127,120, 64, 57, 77,177, 43, 40, 3, 42,212, 12, 42, 53, 96,223, 35,173, 2, 38,123,140,208,167,246, 15,120,118,
- 45,241,118,137,134,210, 52,105,182, 68, 97, 97,225,194,144,144,144, 18, 71, 71, 71,194,220,220, 28, 78, 78, 78,228,176, 97,195,
-138,179,178,178,150,189,233, 21,177,182,182, 30, 23, 20, 20,116, 42, 39, 39,103,244,181,107,215, 90, 93,191,126,125,116, 80, 80,
-208, 41,107,107,235,113, 38, 82, 28, 94,176, 96,129,146,199,227,161,107,215,174,168,172,172, 68,213, 44,159, 6, 55, 83, 92,164,
- 92, 46, 23,219,214,126,139,197, 97,243, 80,154,120, 15,143,111, 94,196,213,124, 2,139, 86,126, 15, 46,151,251, 70,185,190,218,
-216,138,188,189,101,102, 9,115,167,142,205, 13, 15, 11, 51,139,141,141,229,204,158, 51,151, 73,207, 43, 5,111,224, 58, 22,122,
- 47, 36, 31, 41,109, 49,232,253,126, 88,178,248, 75,239,170,164,157, 13,162,189,173,200,219, 75,102, 22,255,229, 71,227, 83,230,
-204,153, 35, 92,179,102,141, 38, 48, 48, 80, 93, 80, 80, 32, 20, 75,173, 60,217, 22,150, 94,233,121,249,146,192,192,192,212, 79,
- 62,249,164,188,169,156,139, 22, 45, 18,157, 63,127,158, 29, 18, 18, 98, 44, 43, 43,147,112,132, 66, 95,130, 47,232, 82, 84, 86,
-102, 49, 58, 36, 36,121,244,232,209,170,170,132,165, 38,115,126,243,205, 55,162,103,207,158,177, 3, 3, 3, 13,249,249,249,102,
- 98,107, 27, 31,150,165,149,127, 90, 94,129,121,151,128,128, 23,179,103,207, 86, 54, 84,206,218, 34,197,204,204, 44,167,123,247,
-238, 88,191,126, 61,126,248,225, 7,188,247,222,123,136,123, 26,135, 65,179,231,161,195,199,115,113,242,246, 93,228,228,228, 96,
-249,242,229,240,241,241, 1,151,203,125, 86,231,243, 56, 51,145,136,205, 7, 17,155, 15,130,152,153, 72, 84,191,175,215,178,181,
-172, 2,181,247,175,107,191,135,223,212,109,233,242,115, 36,162, 27,138,195,106, 76,108,141, 30, 61,250,211,234, 20, 14, 31,126,
-248,225,205, 77,155, 54,245,248,240,195,151, 3,237,174, 93,187, 98,197,138, 21, 61, 22, 45, 90,116,115,229,202,149,232,215,175,
- 31,220,221,221, 27,157,248, 66, 81, 20,140, 70, 35,198,143, 31, 15,163,209,136,162,162, 34, 60,127,254, 28,219,183,111, 7,195,
- 48, 2, 0,112,148, 57,119,230,241,120,120, 20,243, 64,181,248,195,128,223,154, 96,201, 34,106, 15, 98, 20, 10, 5, 70,127,252,
-113,113,118,155, 54,165, 91,139,139, 85,211,164, 82,145,107, 70,134,149,153, 78,231,132, 6,226, 18, 9,130, 0, 77,211, 53,194,
-170, 90,112,189,190, 85,117,148, 38, 65,175,162,207, 92,223,151, 11, 0,232, 53, 81,134, 97,243, 93,167, 56,122,136, 54,247,156,
-240,210,232,125,108, 69, 10, 83,153, 75,173,129, 1,241, 77,176, 88,223,187,119,239, 30, 44, 45, 45, 17, 18, 18,194, 39, 73,114,
-117,245,120, 21, 47,115,103,109,168,230,226,243,249,235, 66, 67, 67,201,242,242,114, 60,126,252, 24, 0, 46,215,215, 46, 49, 12,
- 83, 83,119, 69, 41, 1,138,230,225, 86,204, 57, 92,184,126, 20,105, 57, 69,200, 40,212, 0,108, 11,104,148,217,208,171,115,160,
- 43,143,129, 92, 43, 50,169,192, 92, 46,183,200,219,219,155,241,247,247,103, 24,134,193,139, 23, 47,140,233, 25, 25,198, 7, 27,
- 55, 50, 79,102,204, 32,204,158, 63,231, 10,133, 66,194,205,205, 13, 2,129,128, 22, 8, 4, 37,127, 99,231,253,151,164, 91,248,
- 11,210, 66,252,153, 86, 45, 6,255,157,200,195,171,179, 13,107, 18,152,214,149,176, 20,140,185,112,236,209, 45, 63, 91,132,140,
-159,168,244,241,241,145, 58, 57, 57,129, 32, 8, 12, 31, 49,130, 8,186,118,205,140, 35,147,193,250,157,119,106,220, 17,151, 46,
- 94,196,185,115,231,148,167,127, 63,238, 52,117,218,180, 33, 0,246, 52, 80, 24, 54,159,207,175,249,221,188,188, 60,240,249,252,
-154,152, 8,185, 92, 14, 91, 91, 91,228,229,229,193, 68,207,220,222,240,176,187, 97,133, 1, 11,221, 2,204, 56,196, 89,101, 62,
- 40,134, 1,135,160, 0, 53, 3, 3, 5,104, 13, 12, 58,187,178,172, 46,168,141,210,200,123, 17,169, 0,246, 54,229,236,105,181,
-218, 43,177,177,177, 51,104,154, 62, 10,128,188,118,237, 26, 29, 31, 31,255, 41, 76, 15, 92,255,163,217, 94, 36,154, 31, 21, 21,
-101, 53,127,254,252,178,200,200,200,138,193,131, 7, 91,108,223,190,221,170,111,223,190,243, 75, 74, 74, 14,154, 98, 8,204,204,
-204,220,147,149,149,245,169,191,191, 63, 74, 75, 75,161,215,235, 17, 29, 29, 13, 15, 15, 15, 60,124,248, 16,109,219,182,197,131,
- 7, 15,208,174, 93, 59, 80, 20, 5,141, 70, 3,154,166,169,198, 26,243,210,226, 34,160, 36, 19,185,247,206,226,249,147,104, 68,
-229, 18,248,241,224, 41,180,104,229,246, 70,121,106,218,218,137, 58, 58,218, 90, 95, 88,179,244, 27,187,244, 43,135, 16,177,243,
- 71,250,234,217,179, 29,120,102,152,209,123,252,231,163,116, 6,180, 4,192,235, 22,224,143,129,210,103,148,168, 21,242,163,226,
- 27, 78,176,216,214, 78,212,209,222,198,250,252,191, 86, 47, 51,123,113,110, 55, 14,111, 91,207, 28,219,119,192, 71, 3, 4,116,
-236,216,113, 32, 73,146,150, 0, 52, 85,113, 94, 38, 45,109, 83, 23,231,165, 83,167,252, 52, 64,192,137, 19, 39, 6,138, 68, 34,
- 7, 0, 6,149, 74,149,242, 54,156,151, 35, 35,253,170,203, 73, 16,132, 29, 0, 61,195, 48, 47,208,196, 37,120,198,140, 25,179,
- 98,238,220,185, 97, 20, 69,217,214, 26,157,179,214,173, 91,199,166,105,154,197, 48,140,158, 36, 73,253,249,243,231, 41,163,209,
-152,171,209,104, 62,126,155, 86,100,212,168, 81,184,123,247,238, 82,188,156,132, 97,170,181,250,149, 56,173,170, 37,123,222,152,
-255,218,181,107,203, 63,248,224,131,240,131, 7, 15, 62,223,180,105,211,208,153, 51,103,226,208,161, 67,104,211,166, 13, 30, 61,
-122,132,133, 11, 23, 2, 64,143, 69,139, 22,157,220,177, 99,135,123,122,122,250, 58, 19, 44, 26, 48, 26,141, 56,112,224, 0,134,
- 15, 31, 14, 91, 91, 91,200,100, 50, 16, 4,113,101,218,180,105, 63, 1, 0,139, 96,113, 1, 64,171,209,106, 61, 61,253, 77,182,
-224,114,185,220,154,182, 46, 63, 63,191,102,166,224,128, 15, 62, 40,254,117,205, 26,252,166, 86, 99,154, 84, 42,202,118,118,118,
- 60,249,226,197, 71, 79, 95, 54,206, 76, 67, 86,157,198, 68,150,169, 33, 13,234, 60, 44,248,125, 85,154, 3,128,247,122, 77,148,
-161,215, 68, 25,252,135,217, 17, 36,139,192,147, 11, 37,136,187, 84,122,204, 32,199, 21, 52,109,185,156,248,213,171, 87,159,236,
-221,187,247,208,246,237,219, 99,250,244,233,159,236,220,185,147,107, 48, 24,230,224,223,105, 30, 44, 72,146, 92,182,109,219,182,
-143,172,172,172,112,227,198, 13, 92,191,126,253, 10,128,204,250,218, 37, 0, 53, 57,179, 90,184,180,213, 60, 75, 87,136, 10,115,
-110,225,230,141,223,209,198,231,115, 8, 29,134,192,202,115, 37,244,137, 63, 64, 87,114, 1, 86, 46,131,145,157,254, 2, 44, 54,
- 63,174,177, 32, 20,134, 97,158,102,103,103,187,187,187,187, 19,105,105,105, 70, 0, 12, 69, 81,140,190,103, 79, 67,135, 53,107,
- 56,113,159,124, 66,116,123,246,140,197, 16, 4, 29, 29, 29, 13, 0, 9,255,137, 94,188, 58,221, 66, 92, 92, 92,125,233, 22,154,
- 4,111,111,239, 30,215,175, 95,231,107, 52, 26, 92,189,122, 21, 93,186,212,204,237,250,143,102,191,175,173, 69,254,203,240, 81,
- 29,159,109,127,197,162,245,202,141, 77, 19,156,118,109,219, 82, 92, 18,187,134, 15, 25,162,138,141,141,173, 25,245,105,238,223,
-135,242,220, 57, 80, 20, 5,134, 97,112,253,218, 53,132, 78,156,168,224,176,136, 95, 93, 93, 91, 49, 4,243, 74,238,150,254,117,
-140, 30, 66, 66, 66, 66,106, 26,159,172,172, 44,136,197, 98,240,120, 60,208, 52, 13,163,209, 8, 22,139, 5, 11, 11, 11, 24,141,
-198,186, 76, 48,175,115, 26,168, 82,229,232, 29,131, 38,228,201, 20,122,102,134,165, 43, 90,114,133, 53, 15,167,131, 57,129,161,
- 62, 28,216,176, 11,153,203,235,222,205,165,181, 37,163,241,199, 25, 93,141, 77,249,111,219,169, 83,167,159, 66, 67, 67, 73, 0,
-232,223,191, 63,217,169, 83,167,205,104,120,169,156, 6, 57, 5, 2, 1, 31, 0, 78,157, 58, 85,250,252,249,243,247, 78,157, 58,
- 85, 90,251,115, 19, 57,183,175, 93,187, 22, 34,145, 8, 70,163, 17, 58,157,174, 38, 62,171,246,171, 94,175,135,141,141, 13, 78,
-159, 62, 13,138,162, 78, 55, 86, 78,151,150,173, 64,216,182,198,158, 83, 81,184, 94,204,125, 19,145, 85,195,217,218, 65,220,206,
-193,198,250,226,191, 86, 45,183, 45, 75,142, 70,118,118, 54,115,254,220,233, 59, 26, 32,167,162, 18,139,203,149,104,167,214, 65,
-208,197, 29,153, 23,183,125,205, 44,234, 5, 3,234,158, 53, 88,195,217,193, 65,220,206,201,214,250,252,247,255, 90,101, 86,158,
- 28,141,188,252,124,156, 57,125, 42, 86, 3, 84,187, 27,167,208, 52,237, 69,211,180, 23,128, 41, 13,136,151, 38,113,170, 84, 42,
-111,149, 74,229,253,103,114, 50, 12,227,205, 48,140,201,156,181, 99,162, 54,108,216,144,152,151,151, 23, 90, 88, 88, 24, 92,189,
-149,149,149,245, 87, 40, 20,125, 84, 42, 85, 79,245,134, 86, 22, 42,149,202, 78,161, 80, 56,106, 52,154,206, 0,162,155,112,207,
-215,160,118,214,233,188,188,188, 37,121,121,121, 68, 99,229,100,125,156, 72,236,255,254,203,223,183,109,219,230,248,150,252,175,
-148,179,184,184,248,232,193,131, 7,125,221,220,220,220,167, 76,153,130,173, 91,183, 98,211,166, 77, 90, 0,216,177, 99,135,182,
-150, 37,203, 37, 61, 61,221,191, 30,183, 97,255, 90,214,146,189, 3, 6, 12, 96,174, 95,191,142,225,195,135,215, 36, 18,253,229,
-151, 95, 96, 52, 26,229,253,250,245,163, 1, 64,173, 81,201, 25,154,129, 78, 95,175,255,253, 15,231,147,199,227,189, 95, 59, 95,
- 96,117, 50,102, 30,143, 7,134, 97,208,174, 71,143,226,114, 31,159,210,157, 21, 21,170, 37,222,222,230, 31,121,122, 78,105, 15,
- 76,172,139,147, 32,136, 87,172, 58,175,111, 77,176,100,213, 46,103,161, 58, 23,211,127, 95,149,118,174,218,178, 37,144,176,161,
-169, 52,226,248,154,180, 34, 77, 17,126,169, 79,252, 52, 84,247,210,210,210,217,107,214,172,209, 74,165, 82,140, 26, 53, 10, 43,
- 87,174,156,214,163, 71,143, 10, 59, 59,187,187,109,218,180,121, 50,118,236,216,188,232,232,232,217, 65, 65, 65, 72, 74, 74,194,
-247,223,127, 95, 94, 86, 86, 54,161, 33, 78,130, 32,106, 44,121,195, 6,245, 47,253,121,243,122,186, 95,239, 79, 33, 18,154,195,
-192,113, 65,169,194,128, 50, 37, 3, 29, 63, 0, 60, 46, 31,193,129, 29,113,247,252,110, 21,165, 83,238,105,236,158, 87, 40, 20,
-199, 38, 79,158, 44,231,114,185,208,233,116, 12,135,195, 1,255,101,220, 49,205,121,239, 61,125,183,248,120, 35,197, 48, 52, 65,
- 16,248,226,139, 47,148,101,101,101, 7,223,228, 57,106, 2,106,115,254, 89,233, 22,250,191,214,255,252, 25,105, 33,254,138,186,
-255, 55, 99,123, 29,219,191, 45, 90,213, 83, 42,171, 95, 9,130,166, 40,138,134,171,155,171, 89,122, 90,230,143, 99,198,132,124,
- 56,112,224, 32,209,160, 65,131, 4, 29, 19, 95,142, 70, 79,157, 58,133,136,136, 8,213,133, 11, 23,228,124, 14,107,135, 75, 11,
- 23,123,138,162, 65, 16,116,131,106,216,204,204,108,206,130, 5, 11,132, 21, 21, 21,216,180,105, 19,237,235,235, 75,138,197, 98,
-232,245,122,236,216,177,195,208,177, 99, 71, 14, 73,146,168,168,168, 0, 73,146,207, 76,172,224,227,138,204,156,224,159,130, 70,
- 70,248,207,154,106,221, 33,168,155,180,143,139, 19, 12,239, 48,200,205, 74,195,243,203, 23,202,158,158,223, 88, 2, 77,193, 72,
- 52,190, 60, 80, 93, 29,193,183, 23, 46, 92,176,155, 61,123, 54,163,209,104,136,204,204, 76,102,213,170, 85,118,211,167, 79,255,
- 54, 55, 55,119,220, 27, 94, 20,162,188,188, 28, 4, 65,208, 85, 13, 73,245,168,191, 41,126,185,184, 61,123,246,156, 24, 49, 98,
-196,176,126,253,250, 33, 49, 49,177,198, 69, 88, 91,104, 85,207, 62, 92,189,122,117, 57,128,240,198, 72, 57, 28, 14, 54,237, 57,
-138,242,178, 98,216,219,203, 32, 16, 10,241,166, 51, 44,121, 36,185,228,187,229,223,216, 21, 39,220, 37,226,238, 68,209, 71, 30,
- 23, 20, 26, 41,166,238,140,255,149,185, 76,149,250,111,120, 52, 67,178,150,124,183,106,153, 69,181, 91,243, 96, 76,158,156,160,
-152,217,111,245,136,252,183,112,254,205,144,201,100,200,203,203, 35,100, 50, 25, 83, 21,163,197, 52, 32,180, 94,189,193, 95,186,
-203,136,134,220,134,111,202,159,154,154,186,234,157,119,222,249, 50, 41, 41,233, 72,135, 14, 29,102, 2,104,161,213,106,203, 23,
- 45, 90,244,175, 29, 59,118,124,104,138, 37, 11, 0, 14, 29, 58,180,113,234,212,169,231,134, 12, 25,242, 53, 77,211,157,106,117,
-236,169,118,118,118, 53, 46,220,162,130,252,176, 25, 31,142, 15, 83, 40,202, 76,206,115, 39,145, 72, 62, 90,180,104,145, 64,169,
- 84, 98,203,150, 45,116,199,142, 29,201,234, 65,209,190,125,251,140,109,219,182,101,135,124,250,105,241,134,252,124,172,184,113,
- 67, 25,230,229,229,187,243,249,243,206,160,233,189,245, 89,117,234,178,100, 85,135, 93,188, 33,114,171,196,214, 47, 0,222,235,
- 54,198, 1, 39,214,166,161, 44, 93,247, 47, 24,241, 2, 38, 44, 11, 84, 7,178,143, 29, 59, 22, 92, 80, 80,112,226,155,111,190,
-177,232,220,185, 51,188,188,188, 56, 18,137, 36,160, 58, 93, 76, 69, 69, 5, 46, 93,186,132,173, 91,183,234,158, 62,125, 58,162,
- 33,119, 21, 69, 81,133,109,219,182,173, 62, 15, 12, 65, 16, 37,114, 45, 97,113,184,125,128,100,202,140, 35,196,205, 7,183,145,
-171,167,161, 53,208,112,117,243, 67,159,247, 54,224,228,217, 39, 84,110,122,124,188, 65, 93,246,171, 9,229,125,145,156,156,124,
-124,249,242,229, 99,190,254,250,107, 97,113,113, 49,165,213,106,233,163, 71,143,178,166, 76,153, 66, 49,108, 54,205,101,179, 49,
-103,206, 28,117,121,121,249,239,192,223,186,192,244, 95,146,110,225, 47, 72, 11,241,167, 89,179,106,191,254,127, 65,157, 79, 40,
-205, 34,111,109,221,246,243,251,135, 14, 28,116, 96,177, 72,135, 23, 41, 41, 15,134,142, 28,157,115,241,226, 69, 43,174,133, 69,
- 23, 0,180,110,230,204, 59,122,173,186, 52,242,196,137,150,174,174,173,124,170, 22,149,102,104, 22,121,171,161, 31, 84, 40, 20,
-202, 27, 55,110,168,194,195,195,137,172,172,172,253,246,246,246, 99,207,158, 61, 43, 25, 57,114,164, 58, 49, 49,241,152,131,131,
-195,176,160,160, 32,179, 47,191,252, 82,171, 80, 40,154,178,240,104, 60, 83, 84,214,254,254, 55,235, 62,184,191,246,231,119,193,
-102,117,135,150, 3,208,134, 91,208, 87, 94, 4,176, 31, 77,200,119, 84, 27, 98,177,216, 71, 36, 18, 33, 54, 54,182, 44, 32, 32,
- 64,167,209,104,184, 43, 87,174,180, 22,139,197, 62,111,122,226, 25,134, 97,202,202,202, 64,211, 52, 27, 0, 81,245, 10,186,233,
-115,241,199, 13, 29, 58,244,196,225,195,135, 7, 12, 26, 52, 8,238,238,238, 48, 24, 12,104,219,182, 45,116, 58, 29, 60, 60, 60,
-160,213,106,177,116,233, 82, 84, 84, 84,204, 67, 3,107,158, 17, 4, 1,163,209, 88, 19,108,235,228,220,242,101,158,158,183, 72,
- 99, 33,230,144,238,207, 34,119,162,176,164,152, 62,252,168,160, 64,165,167,130,147,139, 84, 79, 95,223, 79, 69, 65, 25, 52,229,
-179, 28, 0,208,210, 13,175, 56, 47,230,253, 31,123,215, 29,222, 84,217,190,239,115, 78,246,108,154,182,105, 83, 90, 90, 86, 1,
- 41,171,236, 13,130,130,128,162,204, 15, 65,224, 3, 11,136, 34,160,224,192, 1,101, 9,226, 7, 10, 50, 42, 40, 67, 80, 89,178,
- 81,134,148,150, 77,203, 44,101,143,238,145,166, 73,218, 52,205, 58, 57,191, 63,154,132,180,116, 36,165, 40,248,203,125, 93,231,
- 74,206,200,157,247,172,247,189,223,231,125,222,231, 65,131,155,251,127, 64, 78,174, 10,191, 38,101,105,244,102, 91,191,155, 21,
-112,122, 84,206,231,132, 51,106,110, 10,134, 78,117,255,216, 39,129,187,130,170, 50, 92,204, 6,113, 65,248, 35,131,181, 63, 86,
- 24, 35,235, 9,249,119,223,186,117,107, 55, 0, 36, 39, 39,167,141, 28, 57,242,227,251,247,239,207, 3,112,224,193,131, 7,107,
- 61, 33,250,241,199, 31,111, 1,248,111, 85,199,252,178,244,191,187, 0,236,242,132,183,176,176,176, 36, 49, 49,177,228,195, 15,
- 63, 36,210,210,210, 14, 6, 5, 5,189,124,232,208, 33,225,224,193,131,141, 87,175, 94, 61, 26, 28, 28,220,189, 79,159, 62,226,
- 3,103,207,102, 20,223,185,179,111,223,253,251, 33, 22,155,109, 95, 85,239,103, 45,139,172, 50, 98,107,215,252,251,139,119, 47,
-190,223,199,102,196, 14, 83, 1, 78, 3, 72,127, 2,206, 19, 39, 79,158,108, 54,122,244,232,223, 6, 14, 28,216,185, 89,179,102,
-168, 91,183, 46,110,222,188,137,188,188, 60, 92,190,124, 25,123,247,238,221, 91, 82, 82, 82,109, 66,109,181, 90,253,120,122, 34,
-190, 60,120,195,247,115,246,158, 79,104,223,184,219,128,177,130,230,193, 54,152,204, 12,210, 30,222,193,220,207,215, 21,103, 61,
-188,149,108,182,154,223,128,155, 19,117, 12, 6, 67,236,183,223,126,203,222,183,111,223,128,149, 43, 87, 74,194,194,194, 40, 14,
-135, 67, 2, 96, 46, 92,184,192, 76,157, 58, 85,175, 82,169,246,235,116,186,216,191,185,141, 62,113,247,238,221, 40,138,162,106,
- 53,220,194, 19,132,133,240,162, 54, 81,191,126, 72,179,134, 97,193,147, 26,212, 13,153, 82, 63, 44,116, 76, 69, 78,238, 13,124,
-125, 37,245,195,235, 68, 55,168, 27, 50,165, 97, 88,240,164,250,245, 67,154,185, 97, 90,108, 32,149, 74, 15, 42,149,202,214, 0,
-224,227,227, 51, 72, 38,147, 93,243,241,241, 25,100,239, 5, 14, 18,139,197,215, 35, 35, 35,223,254, 27,205,149, 85,114, 54,110,
-220,120,100, 81, 81,209, 59,141, 27, 55, 30,233, 88,191,115,231,142,115,189, 38,156,161,161,161,189, 47, 92,184,240,159,165, 75,
-151, 14,105,212,168,209,160,133, 11, 23, 14,249,253,247,223,255, 19, 18, 18,210,182, 6,156, 60, 0, 63,179,217,236, 28, 46,151,
-155,203,102,179,115, 28, 11,139,197,202,161, 40, 42, 7,192,218, 74,172,101,125, 92,122, 57, 9,129,129,129, 15, 2, 3, 3, 31,
- 4, 5, 5, 61, 8, 10, 10,122,160, 84, 42, 31, 91,252,253,253, 19,220,189,158, 77,131,196, 93, 59,212,149,156,108,161, 20, 39,
-188, 16, 40,106, 90, 27,247,168,105,144,184,107,251,186, 62, 39, 91, 40, 37,241,255,223, 56, 91, 7,129, 97,214, 52,101,152, 53,
- 77,153,214, 65, 96,170, 91,175, 77,179,191, 82,169,100,148, 74,229,156,167, 53,148, 80, 9,255,223,254,190,215, 34,103, 3,137,
- 68,242, 75,221,186,117, 29,117,221,171, 82,169,244, 47,177, 88,252,170,189,174,123, 85, 36, 18,197, 69, 70, 70,142,173,142, 83,
- 46,151, 95, 80, 40, 20,217,246, 37, 43, 48, 48, 48, 43, 48, 48, 48, 75,161, 80,100, 42, 20,138,204,128,128,128, 12,199, 34,147,
-201,206,212,240,220, 21, 0, 58, 2,104, 11, 64, 90,139,215,179, 62,128,137,246, 58,232, 43, 0,111, 3,104, 89, 11,247,136, 96,
- 11,228,147,121,178,208,147,108,113, 64, 33, 91, 28, 80,200,243, 9, 57, 89, 69, 10, 30,119, 56,155,200,229,242, 5, 82,169,244,
-119,137, 68, 18, 47,145, 72,118,251,251,251, 47, 4,208,228, 31,122,150,196, 0,214,163, 52, 62,211, 1,148, 14,133,239, 70,233,
-164,130,176,103,240,153,255,255,140,232,127,234,143,251,120, 57,189,156, 94, 78, 47,167,151,211,203,249, 28,114,146,222,235,233,
- 21, 90, 30, 10,173,242, 11,128, 42, 34,195,123,225,133, 23, 94,120,225,197,255, 99,216,188,151,192, 11, 15, 81,225,208, 50, 81,
-133, 42,245, 36,214, 84, 77,148,237, 17, 47,167,151,211,203,233,229,244,114,122, 57,189,156,255,239, 56,189,168, 69,120,205,170,
- 94, 78, 47,167,151,211,203,233,229,244,114,122, 57,255,237,240, 14, 29,122,225,133, 23, 94,120,225,133, 23, 94, 60, 37,196,186,
- 8,174, 50, 67,136, 94,161,229, 57, 72, 0,239, 0, 24, 10,160, 33, 74,179,217,111, 7,176, 10, 53, 27,211,151, 2,248, 24, 64,
- 23,148,206,206,185, 7, 32, 30,165,179,115,138,188,151,187, 98,248,251,251,127,202,102,179,101, 64,105,106, 19,199,167,235,119,
-154,166, 53, 58,157,110,225, 83, 42, 2, 5, 55, 35, 40, 59,202,234, 90, 54,215, 79,139,197,242, 52,203,233,197,179,137,198,114,
-185,252,103,181, 90, 61, 10, 46, 73,150,189,240,226,223,128,128,128,128, 73,102,179,249, 51, 14,135,179, 32, 47, 47,111,245,255,
-163, 83,127, 76,100,149, 17, 90,251,246,237,139, 3,128,129, 3, 7,246, 0, 0,153, 76,118,138, 36,201,250,158,252,131,205,102,
-187,167,209,104, 42, 13,160, 38,147,201, 78, 81, 20,245, 24,167,197, 98,145,176, 88,172,194,138,126, 99,181, 90,211,117, 58, 93,
-219,103,228, 34, 18, 0,246,249,250,250,150,204,155, 55,111, 85,207,158, 61, 67, 51, 51, 51,173,179,102,205,234,126,233,210,165,
- 1, 0, 94,241, 80,108,117, 34, 8, 98, 67,235,214,173,119,141, 25, 51,230,183, 14, 29, 58,112,243,243,243, 37,219,183,111,175,
-179,113,227,198, 68,155,205, 54, 10, 85, 36, 90,253,255, 12, 54,155, 45, 75, 79, 79,151, 0,165,169, 73,236,194, 10, 22,139, 5,
- 22,139, 5,122,189, 30,173, 90,181,170,245,255, 13, 10, 10,138, 34, 8, 98,165, 88, 44,110, 91, 84, 84,116, 30,192,148,172,172,
-172, 75,158,148,213,106,181,130, 97, 24,103, 57,155, 53,107,230,189,161,158, 97, 2,151,203,237, 23, 17, 17,209,222,104, 52, 22,
-220,187,119,239, 28, 77,211, 95,160,246,114,180,249, 0,248,130,199,227,117,104,216,176, 97,232,173, 91,183,210,204,102,243, 89,
-148, 38, 67,214,214,134,200,234,209,163, 71,194,247,223,127,239, 55,121,242,228,132,248,248,248,174, 94,177,229,197, 63,133,208,
-208, 80,153, 94,175, 95, 7, 32,138,205,102, 7,241,249,124, 8, 4,130,108, 30,143,119, 81, 32, 16,140, 63,121,242,164,198, 83,
- 78,154,166,191,120,240,224, 65, 80,199,142, 29,151, 40, 20,138,185, 42,149,170,196,108, 54, 31, 45, 40, 40,152, 1, 64, 87,213,
-111,203,107,145,231, 76,100,185,126,194, 33,186, 88,246, 19, 99, 0,244, 44,163,192, 88,172,144,135, 15, 31, 42,248,124, 62,108,
- 54,155,179, 49, 43,191, 56,182,155, 76, 38, 52,111,222,220, 92, 77,131, 19,154,150,150,166,224,114,185,206,109, 38,147, 9,117,
-234,212,177,165,167,167, 43,236,105, 15,156, 48, 26,141, 8, 9, 9,121,150,114, 30,189, 35,151,203,181,169,169,105,173, 74,140,
-230,152,183,223,251,228,211, 81, 67, 95,242, 61,117,234,148,237,149, 87, 94, 49,198,197,197,189,131,210,196,169,110, 85,230, 4,
- 65,108,156, 53,107,214, 92,190, 80,234,119,236, 84,178,113,227,246,253, 25,173, 27,215, 35,102,204,152, 65, 77,157, 58,245, 68,
- 84, 84,212,207, 54,155,173, 13, 60,176,108,249,250,250, 30,226,241,120,225,246,235,151, 90, 80, 80,240,242, 51,248, 64,178,240,
-120,240,216,138,182, 85,139,252,252,124, 24, 12,134,199,150,102,205,154,185,155, 43,211,163,114,179,217,236,221,139, 22, 45,170,
-147,157,149,133,255, 45, 91,214, 17,165,150,204,142,238,252, 56, 55, 55,247,177,114, 54,109,218, 20, 94,120,132,143,231,206,157,
-187,232,205, 55,223, 4, 77,211, 48, 24, 12,193,183,111,223,142,252,236,179,207,222,184,115,231, 78,123, 0,119,159,180, 51, 30,
- 17, 17,145, 50,109,218, 52,121,251,246,237, 97,207, 82, 17, 28, 31, 31,223,113,253,250,245,111,165,166,166, 54, 5,144,247, 36,
-127, 32,151,203,127,254,225,135, 31,252,132, 66, 33,246,236,217,227,215,187,119,239,248,164,164,164,110, 79, 32,182, 72, 63, 63,
-191,169, 0, 94,180,217,108, 92, 0,103, 11, 10, 10,230,195,243,168,238, 74,177, 88,188,131, 36,201,122,192,163,104,244, 36, 73,
-250, 19, 4,161,114,108, 35, 8, 66, 97,179,217, 78,171,213,234,206,222,199,241,249,134,159,159,223,132,156,156,156,239,121, 60,
- 30,199,215,215, 23, 66,161, 16, 44, 22, 11, 44, 22,171, 46,143,199,171,203,227,241,250,247,234,213,107,202, 95,127,253, 85,101,
-132,253, 78,173, 3,199,129, 36, 98, 40,130,164, 0,128,100,139,164, 62, 62, 62,136,137,137, 17, 13, 26, 52, 72, 4, 0, 9, 9,
- 9, 99,198,142, 29,219, 59, 61, 61,189,121,101, 98,171, 34, 45,242, 28, 33,182,170, 6, 15,118,245, 24, 87,230,205, 37, 73,112,
-185, 92,156, 57,115, 6,238, 4, 43,119,164, 72,168,178, 54,176, 71, 24,191,116,233,145, 1,192,209,208,112,185, 92,156, 60, 89,
- 54,168,124,167, 78,157,156, 47,251,223,133,161,205, 74,131, 60,110,123,183,180, 92,195, 86,150, 70,215,222,246,110, 83,116,255,
-230, 33,134, 78,157, 51,162,184,196,220, 14,128, 94, 83, 80, 80,112,126,231,206,204,214,141, 27,115,126,254,249,231,246,117,234,
-212, 25,234,129,208,250,184, 77,155, 54, 59, 40,129,143,255,152,177,227,198,140,103,145,230,183, 38,126,184, 32, 45, 75,165,143,
-142,142,222,185,103,207,158, 49,139, 23, 47,190, 62,115,230,204,143, 1,204,118,183,252,124, 62, 63,252,198,141, 27, 17, 52, 77,
-163, 89,179,102,207, 98, 26,131,214, 40, 13,190,247, 38,128,173,246,109, 35, 81, 26,185, 63, 10,192, 69, 79,200, 28, 22,172,138,
-150,218, 70,157, 58,117,154,142, 30, 61,218, 95,173, 82,225,127,203,150, 57, 54,183, 69, 53,195,136,142,247,199,100, 50, 97,200,
-144, 33,163,105,154,102, 57, 68,160,209,104, 52,105,181,218, 18, 60,114, 44,205, 3,240,146, 27,197,169, 47, 18,137,190, 6, 16,
-101, 48, 24,234, 0,128, 72, 36,202,176,217,108,187,244,122,253,108, 60, 74,224,235,113, 7, 23, 64, 36, 42, 79, 5,197, 44, 90,
-180,232,214, 39,159,124,114,247, 31,224, 12, 15, 12, 12, 92, 56,108,216, 48,236,223,191, 31, 7, 14, 28,176, 8, 4, 2,214,216,
-177, 99,137, 41, 83,166,248, 78,155, 54,173, 63,128,111,159,240, 54,247,159, 59,119,174,252,133, 23, 94,192,246,237,219,113,249,
-242,101, 67, 68, 68,132,160,103,207,158, 96,177, 88,242, 79, 63,253,244, 21, 0, 27,158,228, 15,212,106,245,252, 15, 63,252,112,
-227,214,173, 91, 37,247,238,221,195,202,149, 43,253, 71,140, 24, 17,151,154,154,218,195, 3,177,197, 3, 48, 21, 64, 47,138,162,
-186,141, 29, 59,214,250,222,123,239,177, 73,146,180, 44, 91,182, 44, 96,253,250,245, 35,216,108,118, 84,126,126,190, 59,157, 52,
- 18, 64,204,248,241,227,255,251,215, 95,127,249,158, 59,119,142,235,231,231, 7,154,166,157,150, 98,155,205,166,112, 60,179, 86,
-171, 21, 77,155, 54, 13,113,249,189,224,121, 21, 26, 36, 73,154,109, 54, 27, 27, 0, 31,128,177,186,245,127,147,200,146,203,229,
-147,213,106,245,170,160,160, 32, 4, 6, 6, 62,214,214, 26,141, 70,240,249,124, 78, 80, 80,208, 15,131, 6, 13, 98,239,222,189,
-187,210, 33, 64,130, 34,190,216,243,203,188, 58,114, 95, 9, 0, 96,249,154, 63,138, 1,224,247,223,127, 71,102,102, 38,124,125,
-125,209,188,121,115,106,222,188,121,202, 25, 51,102,252,175,160,160, 96,124,101, 92,229,181,200,115,102,209,138,173,104,189, 74,
- 31, 45,134, 97,156,121,242,220,124,104,203,111, 58, 82,142,143, 48,153, 76, 40,111,209,114,188,188,108, 54,187,188,249, 17, 4,
- 65, 48, 85,113, 86,128,177, 34,145,168,149, 94,175, 95,225, 65,239,214,201,185,237,221,166,216,200,155, 53,210,145,137,180,255,
-135,165,159, 27, 1,156,186, 63,126,229,247, 61,122,212,153,250,249,119,115, 12,249,153,170, 79, 71,191, 26, 30, 17,228, 39, 16,
-105,114,181,242, 38, 77,250,150,179,200, 84, 87,206,238, 99,198,140,217,244,231,153, 7, 4,159,207,225,176, 40,138,221,181, 69,
- 99,191, 80, 31,202, 71, 2,248,164,221,189,117,106,220,184,113, 45,102,206,156,217,205, 3, 78,216, 27, 92,108,222,188, 25, 4,
- 65,144,158,156,123, 45,226, 72, 85, 34,139, 97, 24, 16, 4,177,197,165, 81,217, 98,223,150,228, 34,182, 88, 85, 93, 79,135, 53,
-213, 33,170,198,142, 29, 59,218,106,181,178, 92, 42,137,242, 2,166, 34, 17,227,214,185, 43,149,202, 63, 1,188, 68, 16, 4, 76,
- 37, 37,166,175,191,249,198,117,247,133,114, 34,235, 72,101,239,146,197, 98, 1, 77,211,172,164,164, 36,182,203,179,206, 6, 32,
- 2,224,207, 48, 12, 72,146,188,226,198,245,108, 42, 20, 10, 79,237,221,187, 87,218,182,109, 91,130,203,229,194,106,181,226,234,
-213,171,161,139, 23, 47,158,120,228,200,145, 87,244,122,125, 51, 60,158, 60,221,157,123, 20, 25, 31, 31,175,111,208,160, 65,133,
-194, 81,167,211,177, 26, 55,110,220,163, 18, 81,244,180, 57,211,115,114,114, 94,127,233,165,151, 38,101,103,103,167, 88,173,214,
-143, 0, 52,247,247,247, 79, 26, 60,120, 48, 4, 2, 65, 47,131,193,240,237,147, 60,243, 10,133, 98, 80,231,206,157,177,114,229,
- 74, 44, 94,188,184, 15,128,163, 0,122,235,116,186, 35,175,189,246, 26,100, 50,217,235, 26,141,102,195, 19,188, 71,141,187,119,
-239,254, 67, 76, 76,140,100,255,254,253,136,136,136, 64, 97, 97, 33, 62,248,224, 3,197,151, 95,126,121, 92,163,209,244,116,121,
- 47, 42,227,108,198,227,241, 54,108,221,186, 85,220,160, 65,131, 6, 28, 14,135,108,208,160, 1,212,106, 53, 74, 74, 74,120, 11,
- 22, 44,104, 33, 16, 8, 46,125,251,237,183, 27, 0, 12,174,166,156, 36,128,249,107,215,174,157, 20, 29, 29, 45, 27, 61,122, 52,
-109, 50,153,240,219,111,191,129,162, 40,176,217,108, 8,133, 66,103,242,106, 14,135,131, 38, 77, 30, 11,146,190,167,138,243,213,
-162,212, 15, 85, 6,207,134, 93,143, 84,193,231, 28,250, 96,179,217,224,243,249,224,243,249,224,241,120,184,113,227,198,231,124,
- 62,127, 25, 65, 16, 86,119, 56,137, 71,234,162, 21,128,115,213,173,227,113,215,144,191,179,254,116, 32,132, 32,136,229, 0,122,
-149, 54,187,100,156,191,191,255,251, 57, 57, 57, 15,221,229, 84, 42,149,126,249,249,249,223, 42,149, 74, 4, 6, 6, 58,219,239,
- 58,117,234,192, 98,177, 32, 39, 39, 7, 12,195, 64,163,209, 64, 40, 20, 34, 56, 56,248,219,232,232,232,237,177,177,177,249, 21,
-114,218,176,248,181, 17,159,125, 65, 81, 20, 9, 0, 20, 75, 44,158,246, 9, 16, 30, 30,142,174, 93,187,162,164,164, 4, 90,173,
- 22,145,145,145, 44,130, 32,198, 16, 4, 33,101, 24,102, 53,128, 99,255, 66, 67, 97,165,206,240,115,203,143,139, 58,178,197,115,
- 56, 28,183,132,150,253,248,234, 44, 40,164,197, 98, 1,135,195, 41, 99,145, 32, 8, 2, 52, 77,151,217,238, 16, 90, 53, 17,234,
- 83,166, 76,177,253,240,195, 15,147, 10, 10, 10,214,160,134, 67, 9, 99,198,140,121,204,223, 99,198,140, 25,233,185,185,185,204,
-144,190,173, 68, 41, 7, 51,179, 26,250,138, 5, 1, 18, 73, 61,190,175, 92,150,159,159,127,218, 94,153,184,139, 70,109,218,180,
- 17,108,220, 25,159,254,246,244, 69,243,218, 54,240,147,182, 12,241,247, 13,242, 17,112,197, 36,161,231, 91, 45,233,114,185, 60,
-194,211,114, 59,234, 5,161, 80, 8,146, 36,159, 37,139, 22,203, 33,178,212,106, 53,246,239,223,143, 1, 3, 6, 36, 57, 68,136,
- 78,167, 67, 86, 86, 22,148, 74,101,146,221,242, 81,237, 48,162,205,102,131,217,108,134,217,108,118, 10, 24,151,103,200, 41, 96,
- 28,199, 82, 20,117,165,134,101,159,231,235,235,219,189, 87,175, 94,220, 95,126,251,141,203, 48,140, 30,165, 57,212,138, 24,166,
-146, 4,217,229, 96,181, 90,157, 86, 54, 54,155,141,212,212, 84,103,195,229,200, 45,201,231,243,221, 51,101,240,120, 31,254,250,
-235,175,210,246,237,219, 19,249,249,249,176,217,108,206, 74,114,213,170, 85,252,161, 67,135,214, 73, 76, 76,252,212,104, 52,206,
-173,193,185, 18,149, 9, 34, 0,144, 74,165, 86,184, 23, 49,187, 90, 78,171,213, 74,116,233,210,101,166, 74,165,106, 97, 48, 24,
- 22,184,115, 25, 1,236, 73, 79, 79,119,109,216, 47,165,164,164, 24,134, 15, 31, 46,168, 87,175, 94,135,228,228,228, 39,122, 72,
- 27, 55,110,220,137,205,102,227,236,217,179, 70, 0,142,158,117,220,229,203,151,141,131, 7, 15,230,133,134,134,118,210,104,220,
-118, 89,105,220,180,105,211,195, 10,133, 66,224,168, 67, 3, 2, 2,216,177,177,177,146,140,140, 12,152,205,102,124,252,241,199,
- 24, 56,112, 32,252,253,253, 49, 99,198,140,192, 37, 75,143,140,254,133, 0, 0, 32, 0, 73, 68, 65, 84,150,252, 92, 84, 84,212,
-166, 42,163, 53,151,203,221,116,251,246,237, 8,165, 82, 41, 56,115,230, 12, 90,182,108, 9,149, 74,133,236,236,108, 20, 21, 21,
- 33, 59, 59, 27,227,199,143, 87,252,239,127,255, 11,118,195,146,229, 20, 89,177,177,177,154, 29, 59,118, 80,235,214,173,147,176,
-217,108,167,208, 98,177, 88, 78,161,229,200,173, 88,131,145, 6,141, 93,180,201,180, 90,237,147,248,185,241, 0,112, 93, 69, 22,
-143,199, 3,143,199, 3,159,207,127,162,188,172,207, 9,234, 16, 4,145,204,225,112,120, 66,161,144, 67,146, 36,120, 60, 94, 95,
-185, 92,126,173,121,243,230,205, 15, 31, 62,252,192, 29,146,146,146,146, 77, 60, 30,143,173, 80, 40, 0, 0, 17, 17, 17,104,217,
-178, 37,244,122,189, 77,171,213, 66, 38,147,145, 15, 31, 62,132,193, 96, 64, 86, 86, 22,194,194,194,216, 36, 73,110, 66,169, 31,
-242, 99, 56,149,148,189, 6,192, 26,199,186,191,191,127,142,171,165,147,207,231,163, 78,157, 58,200,200,200,128, 68, 34,161,190,
-252,242,203,193,191,253,246,219, 27,167, 78,157, 26, 3, 96,179, 11,213,220,231,216, 71,203, 33,178, 92, 63, 31, 9,173,129, 3,
- 7,206,217,183,111, 95,143,138,122,225,108, 54,187,214,124, 93, 28,130, 74, 42,149,150,183, 90,193,102,179, 85,102,209,242,248,
-127,248,124,190, 96,242,228,201,133,171, 87,175,246, 88,108, 13, 91,153,226,180, 98, 61,214,141,108,214,236,212,167,159,126, 58,
-232,175,191,254,202,104,219,160, 30, 75,148,249,176,136, 47,149,201, 16, 82,119,192,216,215, 7, 95, 70,233,236, 67,119,113,187,
-176,176, 80,208, 48, 68,104, 34,201, 18,162, 46,143, 37, 81,138, 56,188, 32, 95,223, 58, 28,147, 49, 87,234,235,203, 53, 26,141,
- 26, 84,145, 4, 26, 0, 2, 3, 3,255, 16, 8, 4, 97,142,117, 95, 95, 95, 31,134, 97, 32, 20, 10,161, 84, 42,197, 20, 69,221,
-116,121,185, 30,230,228,228,244,173,174, 96, 50,153,236, 15, 30,143, 23, 70,146, 36, 8,130, 0, 69, 81, 32, 73, 18, 36, 73, 58,
-191, 83, 20, 5,130, 32, 80, 92, 92,252,240,193,131, 7,125,221, 56, 95, 43,128, 40,130, 32,146,246,239,223,143, 14, 29, 58,224,
-224,193,131,232,215,175, 31,180, 90, 45,174, 94,189,138,238,221,187, 3,165, 67,138,110,193,213,249,221,209, 41,184,113,227,134,
- 83,184,184, 46, 18,137,228, 73, 76,236, 9,195,134, 13,195, 15, 63,252,192,216, 59, 19, 34,130, 32, 90,250,248,248,220,184,126,
-253,186, 91,126, 48, 12,195,192,108,126,116,168,163,241,178,251, 67,120,148, 28,152,162,168,190,109,218,180, 33,180, 90,173, 67,
- 64,130,197, 98,129,162, 40, 80, 20,133,239,191,255, 94,208,190,125,251,207,120, 60,222, 76, 14,135,163,179, 88, 44,191,148,148,
-148, 44, 0,160,121,150,106,164,110,221,186, 77, 79, 75, 75, 27, 24, 22, 22,182,247, 9,104, 24,139,197, 98, 2, 32,160, 40,138,
- 93, 11,117, 20,101,127,182, 74, 92,196,190,213,190,206, 67,233, 48,177, 91,240,247,247,255,249,192,129, 3, 33, 97, 97, 97,176,
- 88, 44,176, 90,173, 40, 42, 42, 66, 92, 92, 28,140, 70, 35,172, 86, 43, 34, 34, 34,240,197, 23, 95,148,188,255,254,251,252,181,
-107,215,230, 22, 21, 21,141,170,134,246,253,237,219,183,139,148, 74,165,192, 96, 48,224,238,221,187,104,211,166, 13, 10, 11, 11,
-161,215,235, 81, 92, 92, 12,179,217, 12,157, 78, 39,163,105,218, 84, 13,215,231,174, 34,107,226,196,137, 87,184, 92,110,155,247,
-222,123, 15,233,233,233,206,119,254,237,183,223, 70, 96, 96,160,243, 93,178,215,201, 30, 85,204, 44, 22, 11, 60, 30, 15, 28, 14,
- 71, 83,183,110, 93, 16, 4,193,127,248,240, 97, 77,134,226,164, 0,116,108, 54,155,235, 42,176,120, 60, 30,206,158, 61,251, 41,
-151,203,173,204,154, 85,217,123,201,120,178,254, 79,131, 32,136,229, 28, 14,135, 39,151,203, 57, 46, 29, 78,142, 88, 44,134, 66,
-161, 88, 9,160,191,155,231,221, 90, 46,151, 59,235,247, 86,173, 90, 33, 45, 45,109,151, 86,171,125, 43, 55, 55, 23, 36, 73,110,
- 34, 73,242, 13, 71, 39,181,160,160, 0,161,161,161,173, 43,227,235, 28, 21, 52, 9, 4, 83,198,162, 85,174,131, 6,169, 84,138,
-251,247,239, 67,175,215, 51,183,110,221, 34, 38, 79,158, 76,152, 76,166,159, 18, 19, 19, 79,163,116,182,125,165, 90,228, 57,129,
-231, 62, 90, 14,139,150,187, 13, 0, 65, 16,213,246, 38, 44, 22,139, 56, 50, 50,178, 34,135, 47,162, 34,161,101, 31, 78,170,209,
-131,206,102,179, 37, 53, 21, 91,229,177,119,199,214,192,197, 95,124,252,133, 60,184, 94,195,153, 51, 63,103,189,250,234,171,103,
- 54,110,220, 72,203, 95,232,223,251,216, 31,155, 3,191,253, 96,214,193, 3, 7, 14, 0,165,142,209,238, 34, 97,223,190,125, 65,
- 51,166, 78,193, 23, 31,190,127, 72, 26,225,207, 21, 19,114, 17,223,168,207, 19,131, 49,240, 26, 53, 29,184,115,239,222, 44, 0,
-137, 85,145, 8,133,194,176,228,228,228, 8,215,137, 4, 38,147, 9, 66,161, 16,199,142, 29, 11, 16, 8, 4, 1, 0, 96, 48, 24,
-208,188,121,115,119, 45, 38, 97, 55,111,222,140,144, 72, 36, 40, 46, 46,134,209,104,132,197, 98,129,205,102, 3, 65, 16, 96,179,
-217,224,114,185, 16,137, 68,158,206,236,187, 8,224,205, 1, 3, 6,108, 57,120,240, 32, 34, 35, 35, 81, 80, 80,128,148,148, 20,
-135,200,242,200, 71,203, 97, 37,114,245,199, 98,177, 88,248,185, 65, 3,188,157,153,233, 20, 48,203,125,124,240,133,173,102,217,
- 52,154, 55,111,206, 36, 36, 36,224,208,161, 67,120,237,181,215,136,221,187,119,155,105,154,230,100,102,102, 94,201,204,204,116,
-139,195,102,179, 57,203,234,168,183, 93, 5,150,167, 66,203,106,181, 74,184, 92, 46, 74, 74, 74,224,176, 60,184, 46,245,235,215,
-135, 90,173,102,233,116, 58, 86,102,102,166,112,254,252,249,239, 29, 63,126, 92, 89, 88, 88, 56,242,159,172,133, 86,175, 94, 29,
-246,246,219,111,167,178, 88, 44,166, 95,191,126,163, 31, 62,124,248,186, 82,169, 60,250,215, 95,127,125, 3,160,177,167,124,254,
-254,254, 23, 88, 44, 86,136, 78,167,227,108,219,182,205, 82, 88, 88,200, 9, 8, 8,200,113,212, 29,142,107,109,177, 88,220,154,
-185,236,239,239,127, 65,165, 82,113, 86,172, 88, 97,201,207,207,231, 4, 6, 6,230, 56,120, 52, 26, 13,103,219,182,109, 22,157,
- 78,199,241,241,241,185,160,213,106,171,229, 83,169, 84,163,198,140, 25, 19,127,244,232, 81,127,138,162,240,240,225, 67,228,231,
-231, 67, 38,147, 97,211,166, 77, 8, 11, 11,195,246,237,219,213,106,181,122,194,215, 95,127,253,153, 93,100, 85,231,163,213,189,
- 67,135, 14, 97, 26,141, 6, 50,153, 12,122,189, 30, 23, 46, 92, 64,179,102,205,144,153,153, 9,146, 36, 33,147,201,176,106,213,
-170, 98,130, 32,212, 85, 17, 9, 4,130,215,163,163,163,101, 0, 16, 29, 29, 45,139,142,142,174,176,129,235,212,169, 19, 86,174,
- 92, 89, 94,104,121,210, 49,112, 90,157, 92,196, 81, 73,199,142, 29,113,252,248,241, 89, 30,138, 35,147, 67,180,149,183,102,241,
-120, 60,143, 39,211,216,108, 54, 14, 74, 93, 26, 8,119,214,159, 1,244, 16, 8, 4,156,242, 27,139,139,139, 57, 74,165,178,155,
- 7,194,215, 79, 32, 40, 53, 56,133,133,133, 65,171,213,210, 38,147,105,196,230,205,155, 45, 0, 16, 21, 21, 53,130,166,233, 18,
-171,213, 74,113,185, 92,232,245,122, 40, 20, 10,191, 42,108,163, 31,237,249,101,126, 80,121, 31, 45,165, 82,137,168,168, 40, 24,
-141, 70,100,101,101, 33, 46, 46,206, 66,211,244,150,213,171, 87,219, 2, 2, 2,254, 59,100,200, 16, 42, 49, 49,241, 93, 0,211,
- 43,211, 34,207,153, 53, 43,182, 82,161,101, 87,144,199, 1,244, 44,127,146,229,197, 79, 85, 66,171,186,161, 67, 46,151,171, 73,
- 77, 77, 21,185, 54, 42, 86,171, 21,193,193,193, 54,134, 97,136,138,132,214,147,152,130,217,108,182,228,147, 79, 62,209,172, 94,
-189,122,212,253,251,247,231,184,243,155,109,239, 54,197,198,114, 34,107,205,226,152,149, 43, 22,207,151,223, 57,244, 19,214,125,
-183,148,166,105, 36,182,104,209,162, 91, 81, 81, 17,203, 71,100,129, 74,131,131,118,145,229,174, 40, 36, 1,252,120,238,220,185,
-196,254,253,251,159,252,241,215,157,242,204,187,119, 79,243,116,170, 44,105,163, 8, 22,167, 78,216, 27,133, 37, 37,156, 17, 35,
- 70, 4, 0, 24, 82, 93, 37,166,209,104,144,157,157, 93, 94,128,225,198,141, 27,143, 29,235, 86,225, 72, 18, 52, 77, 99,199,142,
- 29, 16, 10,133, 16,137, 68,101, 22,135,200,170,225, 68,133,155, 0,208,175, 95, 63,168,213,106,136,197, 98,183,203, 85, 94,188,
- 48, 12, 3,147,201, 4,147,201, 4,179,217, 76, 3, 96,179, 88, 44,140, 79, 79,119, 90,121, 60, 17, 48,229,209,162, 69, 11,230,
-212,169, 83, 56,121,242, 36,244,122, 61, 86,172, 88, 1,165, 82,249, 34,128,207, 61,229,114,113,210,167,117, 58, 29, 91,167,211,
- 57,173,131,108, 54,219,105, 61,112,211,146,199, 97,177, 88,206,222,168, 99,113,181,106, 81, 20,133,192,192, 64, 4, 5, 5, 97,
-205,154, 53,156,122,245,234, 13,252, 39,107,160, 37, 75,150, 52, 90,190,124,249,250,141, 27, 55, 30, 28, 53,106,212,111, 87,175,
- 94, 29,231,227,227,115,229,216,177, 99,243,121, 60,158,173,134,239,119, 72,102,102,166,194,117,147,205,102, 19, 90,173, 86,167,
-176, 45, 46, 46,118,187,131,193,102,179, 67,146,147,147,133, 0, 48,127,254,124, 54, 0,161,195, 25,220,193, 89, 92, 92,204,110,
-214,172, 89,136,187,207,122,124,124,124,183, 62,125,250,156, 58,124,248,176,111, 88, 88, 24, 50, 50, 50,144,145,145,129, 70,141,
- 26, 97,225,194,133,122,157, 78,215, 5,192,205,162,162,162,221,110,114, 6,251,250,250,178, 83, 83, 83, 97,181, 90,209,186,117,
-107,172, 90,181, 10, 35, 70,140, 64,243,230,205,161,211,233,144,156,156,140, 13, 27, 54,248,114, 56,156, 42,235, 14,131,193,176,
- 59, 54, 54, 54,180,188, 69,107,244,232,209,162,156,156, 28,231, 51, 25, 19, 19, 83,102, 8,209,147, 58,217, 62,180, 85,233, 82,
- 19, 88,173, 86, 41,159,207,215,241,120, 60,174,195, 63, 43, 46, 46,206, 99,107, 86,185, 14,160, 39,235,255, 24, 28,162,181,130,
-182, 21, 65, 65, 65,110,243,240,120, 60,194, 81, 55, 90,173, 86,104,181, 90, 90,169, 84, 58,135,247,147,146,146,232,240,240,112,
-154,162, 40,138,203,229,130, 32, 8, 8,133,194, 74, 43,124,134,102, 98, 94, 29,241,121,153, 89,135,211, 62, 1,204,102, 51,146,
-146,146, 96, 54,155, 17, 23, 23,103,249,250,235,175, 51, 53, 26,205, 52, 0,172, 63,254,248, 99,204,172, 89,179, 40,133, 66,209,
- 39, 55, 55, 23,213,105,145,231, 72,108, 61,102,229,114,180, 66,199, 7, 14, 28, 72,216,167, 86, 18, 14,225,228,137,208,178,191,
-124,213,182,188, 4, 65, 32, 43, 43,203,185,174, 80, 40, 60,254, 47,119,225,231,231,167,239,212,169,147, 68,165, 82,237, 94,178,
-100, 73,141, 44, 89,107, 22,199,172, 92, 52,239, 75,185,250,250, 25,164,103,102, 65,157,107, 73, 76,184,114,127, 23,128, 93, 0,
-128,181, 47, 28, 39, 38,165,124,239, 46,103, 83,127, 65, 43, 54,135,181,235,165,254, 3, 67,135, 71, 79, 39,223,121,231,157,174,
- 99,198,140,209,142, 26, 53,106,170, 88, 44,110,108, 54,155, 11,118,238,223,255, 96,248,240,225,245,104,154, 30,131,106, 98,142,
- 24, 12,134,135, 61,123,246,116,189,158,210, 35, 71,142, 4, 62,120,240, 0, 83,166, 76,201,203,200,200,208,184, 30,235, 78, 25,
-205,102,243,195, 86,173, 90, 85, 58, 92,232, 24, 82, 4,128,194,194,194,135, 30, 92,210,145,176, 59,190,231,231,231,227,198,141,
- 27, 96,177, 88,232,216,177, 35, 18, 18, 18,208,181,107,215, 36, 79,172, 90, 37, 37, 37, 8, 11, 11, 67, 73, 73, 9,244,122,125,
- 49, 0,222,166,122,245, 0, 0,239,230,231,227,194,215, 95,227,204,162, 69,112,125,158,221, 69,203,150, 45,153, 51,103,206,224,
-202,149, 43, 48, 26,141,152, 48, 97, 2, 0, 16,246,103,215,147,144, 25, 13, 40,138,234,215,191,127,255, 96, 0,208,235,245,196,
-185,115,231,192,231,243,157,239,194,222,189,123,145,145,145, 1,130, 32,224,235,235, 27, 82, 80, 80, 80, 15,192,253, 42,204,254,
-196,253,251,247,241,213, 87, 95,193,102,179, 97,214,172, 89,136,136,136,112, 10,172,135, 15, 31, 98,254,252,249,160,105, 26, 95,
-126,249, 37, 26, 53,106, 4,139,197,194, 71, 13, 67,104,212, 6,102,204,152,113,103,215,174, 93, 7,211,210,210, 94, 89,188,120,
-113, 15,130, 32,108, 51,103,206,252, 74, 42,149,210, 79,194, 91,160, 45,196,141,219, 15,157, 66,168,252, 18,224, 47,247,152,239,
-214,221, 52,231,239,105,218,149,143,134,159,220,215,211, 34, 22, 91, 44, 22,253, 27,111,188, 33,219,177, 99, 7,209,168, 81, 35,
-220,187,119,207, 97, 25, 42,134,231, 33, 29, 50,212,106,117, 4, 69, 81,156,219,183,111, 35, 60, 60, 28, 29, 58,116,192,130, 5,
- 11,160, 82,169, 96,181, 90,161, 80, 40,108, 22,139, 37,201,108, 54,159,168,134, 43,102,226,196,137, 28, 0,147,236,150,173, 22,
-211,166, 77,179, 45, 93,186, 20, 73, 73, 73, 78, 11,150,171, 51,188,167, 67,135,174, 86, 39,215, 37, 46, 46,110, 22,151,203,101,
- 0,156,133,231,129,158, 77,229, 45, 90, 53,177,102, 61, 45, 60,205,153,140, 74,165, 50, 78, 34,145, 12, 44, 40, 40, 40, 99,213,
-234,210,165,139, 57, 48, 48, 48,222, 93, 30,177, 88, 92, 64, 81,148, 31, 0,100,100,100, 64, 36, 18,113,238,222,189,187, 8,165,
-193,179, 81,175, 94,189, 69,106,181,154, 83,207, 94,159, 6, 5, 5,193,100, 50, 85,234,198,114,250, 98,206, 79, 0,126,114,172,
-203,229,242, 44,173, 86, 43, 88,186,116,105,209,162, 69,139, 12, 52, 77, 27, 1, 28,211,104, 52,206, 56, 90,217,217,217, 90, 54,
-155, 45,151,201,100,117, 28, 66,171, 34, 45,242,156,161,114,139,150, 93, 73, 50,229, 5, 17, 65, 16,143, 57,168, 87, 35,180,170,
- 21, 89, 52, 77,151,177, 50, 56, 28,222, 43,250, 47,123,163, 94,163,161, 67,187,200,226,239,220,185,115,211,146, 37, 75,206,186,
-251, 59, 87, 31,173,181,223,204, 91,236, 16, 89,151, 79, 30,198,238, 20,173,106,214,162,101,203,107,122, 7, 94,240, 23,182, 12,
- 12,244, 59,254,245,194, 24,233,157, 67, 27,240,219,218,255, 49,151,207,159,111,127,254,252,249,183,166, 76,153, 82,215,254, 96,
-169, 1, 92, 2, 48, 28,110,204,210,201,200,200,232, 91,174, 17,190,201,225,112, 2,133, 66, 33, 50, 50, 50,138,110,221,186,229,
-241,144,140, 74,165,234,251, 20, 30, 64,150, 67,100,169, 84, 42, 36, 39, 39,163, 87,175, 94, 0,128,132,132, 4,116,233,210, 5,
-137,137,137,104,211,166, 77, 18,128,118,168, 38, 80,171,197, 98,209,188,240,194, 11, 78,235,150, 86,171,181, 1, 64,116, 86, 22,
- 98,149, 74,176, 88, 44,156, 89,180, 8,179, 45, 22, 44,240, 80,192,183,106,213,138, 57,119,238, 28, 30, 60,120, 0,171,213,138,
- 65,131, 6,161,134, 47,125,243,166, 77,155, 30, 57,118,236, 88,128, 88, 44,134, 94,175, 71, 81, 81, 17,198,142, 29,139, 17, 35,
- 70,192,104, 52, 98,219,182,109,216,179,103, 15, 36, 18, 9,244,122, 61,244,122,189,239,128, 1, 3, 78,221,188,121,179, 59,128,
-219,149, 8, 45,166,111,223,190,136,143,143, 7, 69, 81,104,223,190, 61,242,243, 31, 77, 6, 10, 12, 12,172,104, 31,245, 79, 10,
- 45, 22,139,197,196,197,197, 45,238,209,163, 7,210,210,210, 94,105,211,166,205,138,113,227,198,101, 60, 41,175,175,143, 4,173,
-154, 53,128,209,104,132,209,104, 68,112,112, 48, 10, 11, 11,113,231,206, 29, 24,141, 70, 4, 42,100, 30,243, 69, 53,111,228,228,
- 83, 40, 20,208,235,245,184,127,255, 62, 76, 38, 19,252,253, 61, 18, 90,161,125,251,246,253,107,203,150, 45,126, 27, 54,108, 48,
-245,236,217,147,187, 98,197, 10, 66, 42,149,194,165, 97,241, 20,113, 9, 9, 9, 97,125,250,244,105,114,253,250,117,196,197,197,
-193,100, 50, 33, 42, 42, 10,183,110,221, 66,167, 78,157, 80, 84, 84,116,246,252,249,243,123,220, 49, 12, 3,248,108,226,196,137,
-112,136,173,248,248,120,100,101,101, 65, 34,145, 60, 38,180, 28,190,143,246, 89,227,193,238, 20,214, 33,136, 92, 44, 79,179,101,
- 50,153, 25,192,242, 26, 90,159, 0, 0,105,105,105,188, 22, 45, 90, 24,249,124, 62,215, 46,218,150, 61, 9, 95,109,162, 22,102,
- 50, 86,138,160,160,160,105,254,254,254,125,234,215,175,143,156,156, 28, 14,151,203, 69,151, 46, 93,204,237,218,181, 51, 7, 5,
- 5,189,235, 46, 15,143,199,187,206,225,112,186,151,118, 38,104,164,166,166,130, 97,152, 89,205,155, 55,127,191,176,176, 16,249,
-249,249, 92,169, 84,234,236, 84, 55,105,210, 4, 70,163,241,186, 7,150,183,152,240,240,240,207, 56, 28,206, 2,149, 74, 85, 81,
- 88, 8,174, 76, 38,147,114, 56, 28,152,205,230, 50, 98,179,188, 22,121,222, 69, 86, 25,161,229,162, 34,203, 8, 29, 79, 44, 90,
-238, 88, 13, 28, 14,246,174,235, 14, 81, 87,254,191,106, 26, 67,203,199,199,199,232, 16, 89, 11, 22, 44, 56, 91, 19,142,237, 91,
- 54, 43,125,108,197,161,153,103, 15,224,230,149, 68,236, 74,214,168,102, 45, 90, 54,245,213, 33, 35,115,202, 11, 51,119, 16, 17,
- 32,108, 30,168,240, 59,254,205,146, 69, 82,245,245, 51,200,202,206,198,129,179,231, 19,205, 64, 50,128, 89,181,105, 90, 6, 74,
-135, 14, 41,138,122,150, 30, 88,167, 51,124, 86, 86,150, 67,100, 69, 1, 64,215,174, 93,147,236, 34, 11,238, 90,180, 52, 26, 77,
-249,148, 53,125, 0,248, 59,206,159,197, 98,161,203,103,159,121, 44,178, 0, 48,137,137,137, 80,171,213,142,158, 98, 77, 69, 22,
-130,130,130, 62, 60,118,236, 88,192,143, 63,254,168,219,184,113, 99,190,205,102, 99,183,106,213, 42,164,109,219,182,196,166, 77,
-155, 0, 0,195,135, 15,199,172, 89,179,112,237,218, 53,136, 68, 34,116,237,218,149,158, 51,103,142, 98,218,180,105,239,230,228,
-228, 76,173,176,117,180,217, 56,124, 62,255, 40,128, 23,175, 95,191, 14, 0,167, 80,154,194,201, 97, 69,168,116,159, 59,141,111,
- 97, 97, 33, 91, 34,145, 84, 24, 26,130, 83,218, 27,242,212, 2,225,228, 60,121,242,228, 87,223,124,243,205,174, 15, 62,248,224,
-246, 19,114, 86,104,209, 26, 56,112, 32, 12, 70, 51,210,115,180,160,105, 43, 12,230, 92,143,249, 92, 45, 90, 3, 7, 14, 68,113,
-137, 9,169, 89,106, 88,173, 52, 10, 13,110,183,229,194,151, 94,122,233,143, 95,126,249, 37,232,244,233,211,160,105,218,118,235,
-214,173,251,111,188,241,134,116,230,204,153,126, 79, 48,201,232,187,145, 35, 71, 14, 61,121,242,164,186, 73,147, 38,242,179,103,
-207, 34, 55, 55, 23, 86,171, 21, 47,190,248, 34,184, 92,110,234,162, 69,139, 56, 0,190,115,247,222,216,197,150,249,252,249,243,
-111,159, 57,115, 70, 46,151,203,185,182,166, 77,145,117,248, 48,118,236,216,241,216, 15,214,174, 93, 11,184, 25,133,223, 97,113,
- 58,119,238, 92,173, 8,172, 50, 45, 53,151, 91,227,225,199,231, 21,231,206,157,203,120,231,157,119,154, 73,165,210,229,221,186,
-117,235,229,231,231, 71,250,250,250,198,213,169, 83,231,253, 86,173, 90,185, 61,186,192,102,179,199,137, 68,162, 59, 86,171,149,
- 42, 42, 42,130, 94,175, 47,173,164,173, 86, 46, 73,146,168, 87,175,158,179, 45,105,223,190, 61,130,130,130,232,148,148,148,113,
-238,242,231,229,229,149,153,133, 88, 1, 38,118,233,210,133,101, 52, 26,241,224,193,131, 4,215, 29, 21,105,145,231, 4,209, 85,
-138, 47,199, 73,185,158, 92,157, 58,117,210, 44, 22, 11,147, 12, 48,151, 46, 93, 98,162,163,163,171, 92, 74, 74, 74, 24,133, 66,
-145, 85, 65,227, 7, 87, 78,163,209, 88,230,119, 70,163,145, 9, 12, 12,164, 13, 6,195, 99,156, 6,131,129, 9, 9, 9,201,168,
-138,179, 2,140,189,120,241,226,234,217,179,103,119,240,224, 2, 57, 57,153, 53, 77,153, 13, 27, 54,252,135, 97,152, 30,221,154,
-133, 93, 25,214, 42,144,233, 18,161,200,220,179,125,203, 8,134, 97,122,148, 95, 28, 1, 78,171,226,108, 26, 40,122,161,119,100,
-221,130,203,135,182, 50,199,150,190,199,124, 51, 40,130,105, 19, 34,209, 52,245, 23,120,154, 35,166,218,108,233,145,145,145, 55,
-109, 54, 27, 99, 50,153,152,200,200,200, 91,181,193, 89, 3, 84,197,217, 26,165,190,108, 35, 43,216,214,250, 9,202,121,153, 97,
- 24, 70,173, 86, 51, 69, 69, 69,140,209,104,100,104,154,102, 92, 1,224,178, 27,156,140,217,108,102, 10, 10, 10, 24,184,239,115,
- 87, 33,167, 82,169,188,127,247,238, 93,166, 97,195,134,105,118,115,252, 52,189, 94,207,148,135, 94,175,103,122,245,234,197,220,
-186,117,139, 9, 15, 15, 47,185,117,235, 22,163, 84, 42,111, 84, 83,206,250,161,161,161, 71,253,253,253,227, 0, 68,120,176,175,
-202,235,185,109,219,182, 6, 12,195, 76, 96, 24, 38,186,146,101, 2,195, 48, 77,255,105, 78,251,245,205, 97, 24,134, 41, 46, 46,
-102,212,106, 53,147,153,153,201, 20, 23, 23, 51, 69, 69, 69,204,197,139, 23,153,211,167, 79, 51, 87,174, 92, 97,228,114,121,142,
- 59,156, 14, 62,147,201,196,232,116, 58, 38, 55, 55,151, 49, 24, 12,140, 94,175,103,174, 94,189,202, 92,184,112,129,185,126,253,
-122, 69,124,143,113,250,249,249,173,205,206,206, 46, 58,117,234, 84,241,154, 53,107,138,131,130,130,174, 3, 8, 3,208,216,215,
-215, 55,251,189,247,222, 99,196, 98,241,195, 26,190, 71,205,216,108,246,197,197,139, 23,159,219,183,111, 95,206,158, 61,123, 76,
-235,215,175, 79,159, 50,101,202, 9, 22,139,117, 17, 64,179, 26,190, 71, 10,153, 76,118,234,236,217,179,214,130,130, 2, 70,163,
-209, 48, 58,157,142,209,235,245,140,193, 96, 96, 76, 38, 19, 99,177, 88,152, 19, 39, 78, 48,129,129,129,174,195,146, 31, 85,209,
-177,158,206, 48,204,135, 12,195,176,106,187,174,115,225,238, 86, 91,156,181, 81,215,145, 36,105,182,215, 29, 29, 75, 87,171, 94,
-255,167,202,217,187,119,239, 47, 71,140, 24,193,244,235,215,143,137,138,138,122,108,105,211,166, 13, 51,121,242,100,102,223,190,
-125,204,215, 95,127,253,101, 45,148,147,133,210, 73, 47, 11,123,247,238,109,137,143,143,103,134, 15, 31,206, 0,232, 91,149, 22,
-249, 55, 8, 46, 71,120, 7,194,245, 19, 0,204,102,115,218,205,155, 55,149, 77,172, 86, 10, 0,190,255,254,251,199, 44, 83,174,
-136,143,143,183, 18, 4,113,167,170,127, 55,155,205,105,199,142, 29, 11, 92,185,114, 37,219,197, 4, 12,171,213,106,203,204,204,
- 36, 87,172, 88, 81,230,248,227,199,143, 91,173, 86,107,170,135, 39,185,161,117,235,214, 27,106,227,106,157,184,246,224,253, 63,
- 14,252,238,223,177, 67, 55,141, 84, 46,175,176, 23,182,237,221,166, 32, 38, 85,109,213, 34, 88,228,130,197, 11, 99,100,142, 33,
-200, 95,147,178, 53, 37, 70,186, 87,138,202,112,185,182,239,112, 81, 81,209, 3,199, 76, 64,189, 94,159,250, 12, 62,132, 23, 81,
- 26,227,202, 90,110, 91, 59, 60,161,211,169,205,102,131,143,143,143,211, 26, 90, 3,139, 40,227,176,176, 58,110,221,147,148,135,
- 97,152,147, 87,175, 94, 13, 31, 59,118,172,100,227,198,141,119,105,154,102,143, 31, 63,222, 28, 20, 20,196, 73, 72, 72,176, 0,
- 32,122,244,232,193,202,206,206,102, 50, 50, 50,212,175,189,246, 90,225,219,111,191,237,119,233,210, 37,174,205,102,171, 46,104,
-225,189,180,180,180,222, 53,216, 87, 37,134, 13, 27,118, 23, 79,158,198,230,169,115, 58,160,214,232,112,247, 65,134, 61,130,185,
- 13,244,195, 28,167, 95,149,197, 98,133, 90,151,239,177, 69,235,206,253, 12,123,138, 49, 26, 52,157,105,231, 43,117,136,103, 10,
-138,171,111, 77, 88,172,174,115,230,204,233, 79,146, 36,121,230,204, 25,227,146, 37, 75,210,242,242,242, 6, 1, 72, 5,128,130,
-130,130,158, 27, 54,108,248,217,141, 80, 14,149, 33,217, 98,177,116,250,232,163,143,166, 2,232, 10,160,174,157, 59,193,110,201,
-170,105, 4,243, 92,141, 70,243,114,255,254,253, 15, 83, 20, 85,207,229, 61,242, 7,160,114,188, 23, 12,195, 40,114,114,114, 94,
-113,135,144, 32,136,101, 79,171, 34,121,154,220, 79, 88, 15, 61, 23, 51, 25,143, 30, 61, 58,119,208,160, 65,172,176,176,176, 79,
-195,194,194,200,130,130, 2, 20, 21, 21,129, 36, 73, 4, 5, 5, 33, 50, 50, 18, 65, 65, 65,182,235,215,175, 47,252,248,227,143,
-171,141,201,247,194, 11, 47, 52,176, 88, 44, 13, 73,146,108, 0,160, 1,195, 48, 13, 8,130,104, 0, 64, 14, 0, 82,169, 84, 26,
- 30, 30,206,234,216,177, 35, 58,116,232,128,227,199,143, 99,251,246,237, 63, 1,248,195,213,154, 85, 94,139, 60, 11, 72,110, 13,
-166,217, 69, 16,215,218,160, 7, 97,195,113,134, 68,207,200, 68,103,156,189,242, 34,171,242,164,210, 21,152,254,250,190,248,226,
-139,206, 23,206,141, 70,229, 65,117, 47, 95, 94, 94, 94,223,113,227,198,149,225,164,105,218,152,159,159,255, 78,231,206,157, 87,
- 81, 20,197, 43,247,192, 62,204,205,205,253, 91,115,245,149,143,163,213,183,255,235,170, 39,229, 20,115,200,134, 55,247,255,128,
-156, 92, 21,126, 77,202, 46, 40, 52,209, 61,111,169,138,175, 62,141,242, 63,124,248,176,223,115,160,248, 43, 18,173, 79,154, 60,
- 59,207,141,128,164,213,229,168, 35,236,225, 68,106,229, 37,207,206,206, 94,250,217,103,159,189,188,112,225,194,128,131, 7, 15,
- 74, 29, 29,148,193,131, 7,231, 94,189,122,181, 27, 0, 94, 73, 73,201,145,133, 11, 23, 6,196,196,196,248, 1,240, 3,128, 1,
- 3, 6,228,228,228,228,172,132, 23, 85,194, 98,177,164, 71,190,208,196,217,241,115, 13,233,224,250,221,106,181,166,123,194, 87,
- 17,143,235, 58, 77,211, 85,242, 81, 20,245, 65,135, 14, 29,168, 15, 62,248, 32,231,224,193,131,142, 68,186,174, 10,237,102, 53,
- 65, 73,221,129, 17,192, 18,251, 82,155,208,171,213,234, 78, 30,254,134,246, 62,141, 21,118, 40, 61, 89,255, 71,176,123,247,238,
-207,135, 15, 31,190, 65, 46,151,111,110,208,160, 65,147,192,192, 64,169, 64, 32,128,209,104, 44, 52,153, 76, 55,110,222,188, 57,
-234,243,207, 63,191,231,150,133, 99,195, 6, 10, 0,199,102,179,241, 73,146, 20, 1,144, 18, 4,225,235, 16, 90, 4, 65,192,108,
- 54,227,193,131, 7,152, 61,123, 54,125,244,232,209,175, 1,124,233, 65,199,181, 29,128, 0,151,122, 60, 0,128, 9,165, 1,108,
-243, 8,130, 56,255,180,175, 23, 97,195,241,102, 23, 65, 36,183, 70, 69,237, 68,213, 73,165, 43,123,225,242,242,242, 58,213,246,
- 75, 92, 25,103, 94, 94, 94,216,179,242,134,140, 49, 46,217,138,181, 75,202,228, 57,116,136,176,138,214,171,131,214, 96,157,242,
-221, 31,215,150, 26,173,140,205,108,181,253,247, 86, 94,113,178,183, 30,170,117,188, 84, 91,239, 82, 45,150,233,106, 74, 74, 74,
-231, 41, 83,166,124, 46, 20, 10,219, 3, 64,113,113,241,153,204,204,204,121,176,207, 42,172,110,191, 23,149, 67,165, 82,181,125,
- 22,249, 76, 38,211,251,157, 59,119,254,150,166,233,111,172, 86,107,194,255,131, 91, 81,226,125, 26,159, 95,252,246,219,111,247,
- 0,116, 2,128,161, 67,135, 82, 0,176,125,251,118,143,197,243,216,177, 99,105,134, 97,204,246,231, 65,143,210,217,133, 5,142,
- 58, 85,175,215, 23,100,102,102, 94,167,105,250, 58,128,159,225,249,140,219, 0,130, 32,246, 49, 12, 51,208, 46,220,246, 49, 12,
- 51,208,117,219,211,182,106, 85,115, 72,245,206,240, 94,148, 98,123, 50,136,242, 67,129,213,173, 87,135,155, 57,250, 56, 0,109,
-188, 87,247,255, 37,238,102,102,102,142,121,130,253, 94, 60,127, 72, 53,153, 76,131,254, 31,157,175,214,123,203,255, 37,237, 95,
- 13, 4,150, 3,215,175, 95,127,106, 46, 2,255, 52,154, 93, 44,219, 1, 47,191,238,130,232,138,132,151, 87,104,121,225,133, 23,
- 94,120,241, 36,208,120, 47,129, 23,255,102, 56,124,179, 28,235,149,248,104,149,247,207,114,174, 19,168,124,230,128, 39, 89,201,
-107, 50, 75,226,136,151,211,203,233,229,244,114,122, 57,255,113, 78, 25,128,112, 0,139,171, 57,174,252,236,194, 28, 0, 42, 0,
- 22,239,245,244,114, 62,129,126,112, 11, 12,195, 12,168,106,232,144, 32,136,253, 79, 75,104, 57,157,225, 91, 99, 78,228, 69,204,
-113,172,187, 43,180,158, 54,250,120, 57,189,156, 94, 78, 47,167,151,211,203,233,229,244,114, 62,161,208,234,245,241,199, 31,127,
-130,210,208, 24,204,199, 31,127,252, 9,195, 48, 3, 74,119, 49, 3,158,230,127, 95,107,131, 30,201,173,193, 56,150,107,109,208,
-163,146, 67,163, 93, 22, 39,188, 67,135, 94,120,225,133, 23, 94,120,225,197,179,142, 83,139, 22, 45, 42, 94,180,104,145,195,241,
- 61, 15, 0, 97,183,112,229, 61,205, 63,182, 15, 19,186, 51, 81,170,234, 20, 60,255, 0,130, 73, 22,103, 52,155,195,235, 5,198,
- 22, 9, 0, 32,169,107,180,169,228, 47,171,213,188, 25, 64,102, 77,137,155, 2, 47, 52,146, 9,246, 24,105,154,147, 86,104, 26,
-154, 82,154,230,192, 99, 12, 5,186,240,184,220, 63,121, 50,153,160,162,253, 70,141,198, 96, 52,153, 94,222, 14,156,244,190, 3,
- 94,120,225,133, 23, 94, 60, 39, 16,249,250,250, 30, 37, 73, 50,204,177,193, 53,238, 96,249, 24,132, 52, 77,103,169,213,234,151,
- 81, 58, 84,252,119,114,186,254,222,132, 26,182,229,181, 13, 79,135, 14, 89, 64,153, 40,172,127, 75,198,108,138,205,123, 91,226,
- 35, 91,240,159,113,239,251, 69, 52,110, 66,132,134,214, 1, 24, 32, 53, 45, 61,240,206,237, 91,189,127,219,248,221, 12,157, 86,
- 61,219, 98, 52,254,224, 41,247, 11,128,168,174,152,151,240,195,199,111,202, 88,176, 98,228,252, 45,135,136, 34,115,232,245,210,
-233,166, 30,137, 44,153,159,223, 31,139,142, 28, 17,248,182,108, 89,102, 31,195, 48,165,249,245, 46, 95, 22,124,250,242,203,127,
- 12, 85,171,251,122,197,214,191, 18, 65, 82,169,116, 26,155,205,238,105, 54,155,195,184, 92,110, 26, 77,211,113, 5, 5, 5,203,
- 1,100,120, 47,207,191, 27, 77,130, 68,221,154, 52, 8,219,146,153,157,147,164, 43, 49,141,191,153, 89,164,246, 94, 21,143, 81,
- 85,126,205,127, 44,247, 38, 0,136,197,226, 11, 36, 73,134,184,138, 0, 71,206, 94,199,122,249, 79,155,205,118, 79,173, 86,119,
-174,130,182,129, 92, 46, 95, 5,160, 93,117, 1,147,237,177,217,206,171,213,234,119, 80,249,108, 61,137,175,175,239, 92,130, 32,
-134,145, 36, 73, 85,119, 78, 54,155,141,102, 24,102, 91, 65, 65,193,151, 0, 10, 43, 59,206,215,215,247, 72, 74, 74, 74, 59,133,
- 66, 81,173,149,198,106,181, 34, 53, 53, 53,160,125,251,246, 39,212,106,117,211,167,201,249,119,107,145,154,162,138, 89,135,149,
- 62,232, 0,202,228, 23,122,170, 17, 89, 57,124,241,158, 78,221,251,246,154, 60,245, 3,209,197,171, 55,240,231,241,211,208,233,
-141,160, 72, 18, 50,137, 16,141, 27, 55, 36,150,197,238,240,255,105,205,178,111,206,196, 31, 30, 80,162,215,190,230,145, 76, 23,
-178,102,207,122,163,189,200, 79, 78, 3, 54, 26, 31,246,111, 37,250,116, 95,210,108, 20, 91, 63,241, 88,100, 29, 61, 42,204,205,
-201, 65, 76,112, 48, 88, 86, 43,248, 36, 9, 62, 65,128, 79,146, 16,241,249,232,183,126, 61,230, 29, 60, 40,252,252,149, 87,188,
- 98,235, 95, 6,177, 88, 60, 46, 56, 56,120,201,186,117,235,252,234,215,175, 15,145, 72, 4,181, 90,237,127,243,230,205,214,211,
-167, 79, 31,147,149,149,245,153, 78,167, 91,235,189, 82,255, 94,216,108, 24,253,227,130,119,234,100, 61,188, 93,103,226,194,173,
-141, 9, 63,186,231,141,124, 67,182,247,202,184,141,214, 0,146, 80,113,254,210,170,246, 85, 10, 62,159,159, 83, 82, 82,162,168,
-234, 24, 46,151,155,107, 50,153, 2,171,227, 34, 73, 50, 36, 35, 35, 67, 33, 20, 10, 65,211,180, 61, 27,128,205,217,145,118,205,
-126, 98, 15, 84,139,166, 77,155,154,171,226,148, 72, 36,223,231,230,230,246,113,228, 9,116, 17, 84, 21, 34, 35, 35,163, 79,179,
-102,205,190, 47, 44, 44,124,185, 18,241, 50,119,234,212,169,211,154, 55,111,238,176, 2,217,179, 32,148,126,170, 84, 42, 76,153,
- 50,197,249, 31, 54,155, 13,135, 15, 31,158, 58,110,220, 56, 20, 20, 20, 76,175,226,220,195, 20, 10, 5, 97, 79, 40, 94, 41,230,
-204,153,131, 57,115,230,224,187,239,190, 35,216,108,182,172,154,235, 89, 43,156,127,151, 22,169,137, 5,171,154,200,240,251, 81,
-214, 55,107,255, 99, 66,235,239, 0,197,230,253,183, 93,231, 62, 61,167, 76,155, 37,218,250,251, 49,220,188,126, 25, 41, 9,191,
-148, 57,166,237,203,227,144,173, 42,196,184,201, 31,138, 9,138,213, 51,254,200,238,255, 90,140,134, 31,221,180,102, 5,134,241,
-184,239,117,108, 31,201,206, 16,220, 68,144,175, 0, 93,219, 52, 98,135,254,113,229, 61, 61,172,223, 94, 47,157, 37,227,145,200,
- 90,247,230,155,232,102,177, 64, 65, 81,160, 8, 2, 20, 0,146, 32, 80, 98, 52,226,252,232,209,104,191,105, 19,190,220,187, 87,
- 56,247,213, 87, 61, 18, 91, 34,145,232, 34, 65, 16,190, 69, 69, 69, 3, 80,154, 88,250,121, 64, 51,177, 88,188,159, 97,152, 2,
-189, 94,223,250, 25, 42,151, 18,165, 99,244,229,123,199, 28,148,206,168,242, 40,179, 48,143,199,123,123,232,208,161,203, 86,174,
- 92, 41,204,201,201, 65,102,102, 38,104,154, 6,159,207, 71, 68, 68, 4,113,228,200, 17,191, 89,179,102, 45,221,191,127, 63,175,
-176,176,240, 91, 79, 58, 54,108, 54, 59, 86, 46,151,191, 18, 24, 24, 40,202,205,205, 45,214,104, 52,135,141, 70,227,219,168,121,
-218, 20,146,205,102,143, 10, 15, 15,127, 61, 56, 56, 56, 48, 35, 35, 67,149,158,158,190,199,104, 52,254,132, 26, 38,106,118,185,
-166, 45, 97,143, 86, 15, 32, 43, 60, 60,252,218,131, 7, 15,114,107,145, 51, 51, 60, 60, 60,185, 6,156, 34, 0,191, 1, 8,174,
-230,184, 76, 0,195,225,161, 53,219,121, 97, 25,219,129,249,203,215,141,143, 25,219,149,248,113,122,159,136, 73,223, 29, 57, 77,
-114,152,238,215,179, 74,210,188, 26,202, 61,145,101, 79,105, 85, 94, 80, 85,181,175, 74, 24,141,198, 0,179,217, 12,118, 37,201,
-226,245,122, 61, 36, 18, 73,128,187,133, 20, 8, 4,248,229,151, 95,192,102,179,193,102,179, 81, 80, 80,128,144,144, 16,231, 58,
-135,195,113,126,175, 91,183,110,181,124, 52, 77,183,167, 40, 10, 69, 69, 69,160,105,218,185,104, 52, 26, 48, 12, 3, 30,143, 7,
-154, 46, 77,231,228,178,191,125,101,124, 4, 65, 12, 11, 14, 14,198,214,173, 91, 97, 50,153, 30,219, 47,149, 74,113,245,234,163,
- 36, 35, 20, 69,161, 67,135, 14, 36, 65, 16,195, 0, 76,175,130,151, 1,128,232,232,104, 80, 20, 5,138,162, 64,146,164,243,187,
- 99,161,105, 26,115,230,204, 65,185,212,100,127, 27,231,179,134,106, 34,195,103,161, 18, 31, 45,242, 41,151,203,117,138,103,176,
- 80, 36,253,234,157,247, 63, 20,239, 63,113, 5,169,105,169,143,137, 44, 0,184,240,231, 79,200,202,204, 64, 82, 74, 58, 70,253,
-247, 93,177, 84, 42,251,170, 92,133, 90,233,180, 81, 31, 9,231,235,143,135,119,229, 23, 89, 50, 81,232, 11, 80, 13,184, 96, 11,
-245,152, 53,176, 37, 79, 42,225, 44,113,167,156, 60, 46,247,207, 69, 71,142, 56, 69, 86, 23,163, 17, 60,154,134,149,166,157, 34,
-203,100,181,194, 96, 50, 65, 89, 84,132, 59,227,198,129,177, 88,240,217,174, 93, 66, 30,151,251,167, 59,229, 4, 0, 14,135,163,
-220,179,103, 79,221, 22, 45, 90, 28,135,251,193, 76,143, 60,229,123, 84, 21,218,180,106,213, 42,110,211,166, 77,117, 57, 28,142,
-178, 54, 56,249,124,254, 16,145, 72,148,199,231,243,135,212,176,156, 36,128,249,227,199,143, 79,108,216,176,225, 49,187,176,114,
-138,154,134, 13, 27, 30, 25, 63,126,252, 69, 0,115, 42,121,214, 43,226,172, 19, 28, 28,188, 96,229,202,149,194, 91,183,110, 33,
- 35, 35, 3, 22,139, 5, 35, 71,142, 4, 77,211, 48, 24, 12, 48,153, 76, 88,188,120,177,200,207,207,111, 54, 74, 19, 5,187,115,
-238, 28, 31, 31,159, 91, 27, 55,110, 28,122,255,254,125,241,177, 99,199,136,171, 87,175,138,150, 46, 93, 58,200,207,207,239, 38,
- 0, 94, 13,174, 39,169, 84, 42,127,220,189,123,247, 59, 87,175, 94, 13,217,185,115, 39,251,204,153, 51,202, 53,107,214, 76, 80,
- 42,149,155, 0, 80, 53,188, 71,173,133, 66, 97,239,153, 51,103,218, 78,157, 58,149,113,234,212,169,140,101,203,150,161, 91,183,
-110, 93, 98, 98, 98,162,106,200,217, 70, 34,145,188, 56,115,230, 76, 91,124,124,124,230,217,179,103,211,151, 46, 93, 74,190,248,
-226,139, 93, 23, 44, 88,208,210, 67,206,223, 78,157, 58,213, 35, 45, 45,173,126,122,122,122,189,244,244,199,134,205, 2, 0, 0,
- 27,138, 73, 68, 65, 84,244,240,244,244,244,240,140,140,140,176,172,172,172,186,217,217,217,161,185,185,185,161,113,113,113, 93,
- 1,108,113,135,179, 73,160,232,157,233, 35,251, 20,207,254,111,127,230,147,183, 94, 98,102,141,236,193,188,210,189,197,239, 20,
-139, 69,156, 77, 78, 69,136, 15,240,211,148,118, 97,161,254,162,171,145,114,113,227,103,236,221,124,214, 56, 89, 14, 33,165, 86,
-171,177,127,255,126,216,173, 87,173, 93, 69,150, 78,167, 67, 86, 86,150, 99, 31,203,157,114, 74,165,210,163,235,214,173, 99, 74,
- 74, 74,160,213,106,145,155,155,139,180,180, 52,220,185,115, 7,249,249,249,184,113,227, 6,132, 66,225, 81,119,202, 73, 16, 4,
-104,154,118, 10,169,195,135, 15, 99,252,248,241, 80,171,213,206,109, 44, 22,203,249,221,241,155,234, 56, 29,150, 39,154,166,113,
-246,236, 89, 76,156, 56, 17,203,150, 45,195,150, 45, 91,176,111,223, 62,168,213,106,167,216,178, 90,173,213,114,170, 84, 42,216,
-108,238,245,153, 24,134,129, 86,171,117,251,190,187, 10, 32, 22,139,245,152, 40,114, 44,158, 60, 75, 79,200,249,204,194,141,200,
-240,149,247,176, 29, 95,236,166,186,158, 79,171,144, 36,139, 51,106,216,216,169,126,233,185, 58,100,228,104, 65,145,143,218,189,
-168, 62, 99,193,162, 72,156,251,163,212,112, 69, 82, 20,180,122, 35, 52, 69,102, 12, 29, 59, 77,254,195,178, 47, 70, 89,205, 37,
- 85,198,120,105, 14, 68, 68,138,197,111, 52,107, 86,151,188,206, 75, 65,212, 43, 9,160,109, 0, 19,255, 42, 90, 23, 40,168,166,
-127,114,223,208, 23,154, 23, 92, 5,110, 85,105,205,144,201, 4,190, 45, 91, 34, 38, 56, 24,221, 45, 22,112, 24, 6, 47,229,228,
-224,242,180,105, 48,238,216, 1, 18, 0,103,200, 16,244, 90,190, 28, 39,130,131, 17,100, 48, 64, 51, 99, 6, 2, 14, 29, 2, 71,
- 42, 21, 32,207,189,201, 15, 4, 65,160,103,207,158, 56,114,228,136, 95,191,126,253,254,184,114,229,202, 96,171,213,122,162, 38,
-215,214,199,199,231, 2,139,197, 10,169,238, 56,171,213,154,174,213,106, 61, 78, 51,194, 98,177,186,119,232,208, 97,215,206,157,
- 59,125,205,102,115,173,244, 66,184, 92,110,191, 65,131, 6,173, 91,189,122,181,116,194,132, 9,235,246,237,219, 87,108, 50,153,
- 14,121,242, 72, 1,152,191,118,237,218, 73,209,209,209,178, 9, 19, 38, 48,119,238,220,113,181, 94, 5,116,235,214,173,225,186,
-117,235,130,218,181,107, 55,117,226,196,137, 28, 0,159, 85,103,229, 17,139,197,147,215,173, 91,231,175, 82,169, 80, 84, 84,228,
-172,100,211,211,211, 33, 16, 8, 64,146, 36, 72,146, 4,155,205,198, 87, 95,125,229, 55,121,242,228,105,106,181,122,154, 27, 86,
-178,216, 85,171, 86, 5,188,252,242,203,228,253,251,247, 65,146, 36,248,124, 62,222,124,243, 77,210, 96, 48,248,198,196,196,108,
-208,235,245, 35, 60,185,134,108, 54,123, 84,108,108,108,227, 46, 93,186,176, 82, 82, 82,208,169, 83, 39,156, 59,119, 14, 67,134,
- 12, 97, 23, 22, 22,214,155, 53,107,214,120,163,209,232,105, 28, 23,165, 80, 40,108,254,215, 95,127,165,133,134,134, 58, 43,150,
-122,245,234,209, 3, 6, 12, 80,167,164,164, 52, 57,117,234, 84,126,231,206,157, 61, 73, 88, 94, 71, 40, 20, 54, 61,112,224, 64,
- 86, 76, 76, 76,239,181,107,215, 14, 2,128,246,237,219,239,153, 55,111,222, 49,181, 90, 29,121,226,196, 9,117,247,238,221,211,
-221,228, 11, 86, 42,149,244,148, 41, 83,196, 85, 29,180,126,253,122, 13, 74, 19, 46,215, 7, 80,101,190,182, 38,225, 65,179,151,
- 76, 27, 38, 0,109, 6, 99, 49, 0,230, 98,192, 92, 4,155,169, 24, 4, 71, 0, 88, 12, 8,224,169,241,219,228, 38,210,143,182,
-222,189, 78,223, 32, 6,164,168, 10, 15,193,139, 10,171, 26, 0, 81, 4, 65, 36,237,223,191, 31, 29, 58,116,192,254,253,251, 49,
- 96,192,128, 36, 87, 49,112,245,234, 85,116,239,222, 29,118,139,150, 91,190, 90, 90,173,246,227, 57,115,230,196,143, 26, 53, 74,
- 88,166, 50, 32, 73,200,100, 50,244,239,223,191, 68,175,215,127,236,110, 65,105,154, 6,139,197, 66,122,122, 58,214,175, 95,143,
-133, 11, 23, 34, 34, 34, 2, 22,139,229, 49,177,101,175,247,220,170,252,172, 86, 43,206,159, 63,143,205,155, 54,225,179,217,179,
- 33,145, 72, 0, 0,102,179, 25,234,130, 2,240,249,124,167, 24,171, 70, 56,109,187,125,251,246,180,144,144,144, 50, 67,134,142,
- 79,123,157, 5,155,205, 6,171,213,138,146,146, 18, 44, 91,182,204,202, 48,204,182,234,218, 31,135, 40,154, 54,109, 26,140,198,
- 71, 6,245,150,118,159,228,240,240,112,180,106,213,202,185, 78,146, 36,227, 46,231, 15,157,155,195,224,114,116,147, 57, 75, 1,
- 0, 33, 33, 33,104,210,164, 9,148, 74,101,165,156, 79, 91,139,212, 4, 30, 68,134,175, 92,104,253, 29,153,178,217, 28,126,175,
- 6,141, 26, 19,169, 89,106,176, 88, 44,136,124,252,209,249,245,233,160, 40, 18, 98,153, 63, 8,218,240, 72, 17,147, 20, 88, 20,
- 11,234, 66, 3,194,235, 55, 34,121,124, 65, 47,125, 53, 66, 75,234,195, 94, 53,115, 68,103,126,190, 53, 29,130,186,124,208,142,
-230, 52,152, 11,210,175, 16, 31,244,139, 16, 68,239,185,178, 10, 90,203,139,238,148,151,178, 90,161,160, 40,152, 25, 6,151,167,
- 77, 67, 84,108, 44,146, 28,194, 48, 54, 22, 73,209,209,144,179,217,224,145, 36, 24,139,229,177, 49,125,119,132, 22, 0,164,165,
-165, 97,199,142, 29,242, 97,195,134,237,186,122,245,234, 40, 15,197,134,131,203,255,236,217,179,138,250,245,235, 87,122,204,189,
-123,247,208,182,109, 91,143,135,167,184, 92,110,191, 23, 95,124,113,235,142, 29, 59,124,146,147,147,161, 80, 40,158, 88,104,241,
-120,188,238,125,250,244,217,186,113,227, 70,105, 94, 94, 30, 98, 99, 99,165,175,190,250,234,150,196,196,196,215,141, 70,163, 59,
- 98,179,140,200,138,141,141,213,172, 95,191,254, 7,148, 29, 34,204, 90,191,126,253,143,237,218,181,123, 39, 58, 58, 90, 6, 96,
-146,221,119,160, 74,177,197,227,241,122, 54,104,208,160, 76,175,150,199, 43, 53, 54,137, 68, 34,248,248,248,128,195,225,192,104,
- 52, 34, 42, 42,138,224,114,185, 93,221, 57,103,137, 68,210,231,141, 55,222, 32, 19, 18, 18,144,157,157, 13,153, 76, 6,177, 88,
- 12,154,166, 49, 97,194, 4,106,217,178,101, 61,245,122,207, 70,184, 66, 67, 67, 7,245,238,221,155,117,237,218, 53,220,191,127,
- 31, 70,163, 17, 55,111,222,132, 84, 42,197, 91,111,189,197, 89,178,100,201,171, 25, 25, 25,158, 10,173,230,209,209,209, 57,174,
- 34,203, 1,145, 72, 68, 52,110,220, 88,237,231,231,215, 6,128, 39, 66,171,249,187,239,190,155,187,104,209,162,238, 71,142, 28,
-113, 6,189, 60,114,228,200, 44, 0,248,246,219,111,227, 3, 2, 2,218, 0,112, 87,104,129, 97, 24,219,127,254,243,159,135, 92,
- 46, 23,108, 54, 27, 92, 46,183,204,194,225,112, 64,146,164,196,241, 58, 87,199,119,253,126,246,226, 9,179,150, 46, 21,241, 41,
-246,251,175,183, 64, 93, 25, 7, 16,200,193,233,254, 17, 8, 89,169,209,146, 81,223, 3,254,252, 8,223,188,161, 38,163,127, 46,
-249,221, 76,251, 6,220, 45, 40, 40,252,135,219,128,118, 0,254,135,210,228,186,179, 1,156,125, 70,218,166,139, 0,162, 6, 12,
- 24,224, 20, 91, 7, 15, 30, 68,191,126,253,160,209,104,112,237,218, 53, 87,145,229, 73,130,229,139, 22,139,229,210, 47,191,252,
-210,121,216,176, 97,132,203,251,133,228,228,100,220,184,113, 35,201, 93, 62,146, 36, 97,179,217,192,102,179,177,116,233, 82,152,
-205,102,252,252,243,207,216,190,125, 59, 72,146, 4, 65, 16, 32, 8, 2, 82,169, 20,223,125,247,157, 71,245, 30, 77,211,216,176,
- 97, 3, 62,154, 53,203, 41,178,236, 35, 25, 8, 10, 12,132,159,191, 63,238,222,189, 91,173,208, 42, 40, 40,248,114,239,222,189,
-168,202, 25,126,239,222,189,206,239,229,156,225,171,111,231, 40, 10, 70,163, 17, 47,189,244, 40, 85,236,187,239,190,235,252,174,
- 86,171, 65, 81,148,227, 90, 16,238,114, 26, 24,224,117,254,163,109,253, 63,248,160,140,133,174, 50,206,191, 67,139,212,150,117,
-171, 2,177, 21,101,183,206, 42, 1, 12, 64,169,143, 86, 22,240, 55,250,104, 49,140,173,105, 72,157, 96, 92,186,115, 21, 44,138,
- 2,215,199, 31, 62,242, 64,216,172, 38,104,115,239,227,248,206,239, 1, 0,107, 55,108, 3, 73,146, 96,177, 40, 24, 77, 52, 34,
-234, 6,195,102,179, 53,173,138,251, 5,160,115,207, 64,255, 14,161, 97, 50,226,154,239,125, 52, 86,248,149, 27, 8,225, 33, 34,
- 83, 76,116, 18, 11,218, 23,104,117,157,175, 3,167,170, 21, 3, 36, 9,146, 32, 32,228,112, 96,220,177,163,212,107, 51,182,180,
-205, 74,138,142, 6,249,251,239,144,240,120,160, 8, 2, 44,187, 9,186, 38,208,233,116, 32, 8, 2,155, 55,111,246,125,235,173,
-183,182, 92,187,118, 45,186,164,164,100,135, 39, 28, 26,141,102, 64,151, 46, 93,142,109,216,176, 33, 32, 40, 40,232,177,253,217,
-217,217, 24, 59,118,108,158, 70,163,241, 40,168, 27,159,207, 31, 50,104,208,160,117, 63,253,244,147,244,246,237,219, 40, 42, 42,
- 66, 64, 64,192,147, 62, 10,109, 58,118,236,184,107,199,142, 29, 62,217,217,217,208,106,181, 48, 26,141,216,188,121,179,172,127,
-255,254, 59, 82, 82, 82,250, 1, 72,172,134,227,115, 87,145, 53,113,226,196, 43, 0, 20, 0, 86,149,215,160,246,125, 45, 92,196,
-150, 22,192,146, 42,122,162, 97, 34,145, 8,185,185,185, 24, 59,118, 44,110,221,122,100, 0, 13, 14, 14,118,246,244,238,222,189,
-139,128,128, 0, 16, 4,161,112,231,164, 3, 2, 2,196, 38,147, 9,227,199,143, 71, 90, 90, 90, 25,206,244,244,116, 16, 4, 33,
-244,244, 66, 6, 6, 6, 6, 26, 12, 6,116,235,214, 13, 37, 37,165,121,125,135, 15, 31, 14, 54,155,141,220,220, 92,176,217,108,
-255, 26,220, 31,255, 1, 3, 6, 84, 26, 90, 69, 42,149,154,125,125,125, 95,240,144,211,239,213, 87, 95,205,136,141,141,125,108,
- 98,203,185,115,231, 94,147,203,229, 71,228,114,121, 99, 15, 57,109,174,162,138,195,225,148, 17, 90,108, 54, 27, 36, 73,186,237,
-163,118, 43, 87,191,146, 69,100,181, 90, 52,229,229,177,117, 21, 62, 96,138,114,192,121,241, 75, 92,202, 19, 96,233,178, 3, 0,
-128, 15,223,108,139,150,125,230,195,244,211,203,152,214,137,226,142, 78, 55,206, 4,240,249, 63, 92,231,127, 13,192, 49, 11,110,
- 53,128, 86,207, 80,123,228, 20, 91, 7, 15, 30, 68,100,100, 36, 10, 10, 10,144,146,146, 82, 83,145,229,168,239, 62,154, 59,119,
-238,159,131, 7, 15, 22, 57, 58,173, 2,129, 0, 51,102,204, 48, 20, 21, 21,125,228,209, 67,100,179,129,197, 98, 57, 59,201,124,
- 62, 31, 81, 81, 81, 78,145, 69, 16, 4,138,139,139,193, 98,177, 28, 51, 18, 9, 55,203, 8,101, 80, 16, 36, 18, 9, 26, 69, 68,
-224,182,189, 30,113,124,231,241,120, 32, 8, 2, 86,107,181,134,188, 66,187, 83,251,244,218,110,146, 29,162,168, 74,211,113,112,
- 48,108, 54,155, 67,100, 50,181,193,233,239,239,143,162,162, 34,119, 57,159, 73, 84, 98,209,114, 8,173, 1, 40,245,213,122, 44,
-188, 67, 15, 0,199,241, 20,167, 84, 18, 96, 8, 27,195,128, 69,145,246,177, 91, 10, 20, 69, 66,157,151,133,229, 95, 78,178,139,
-172,237,216, 31,159,130,144, 6,145,143,198,113, 9, 2, 96,170,126,184, 3,124, 56,177,147, 7,119, 20,228, 16, 89,144, 5, 11,
-193,231,151,211,143,190, 28, 16,225, 36,166,244, 12, 17,158,223, 91, 18,123, 93,107,174,182,161,224,147,100,169,243, 59, 65, 84,
-232,220, 67,218,247, 81, 4, 1,134, 97,192,216, 60,243, 59,118, 8,121,129, 64, 0,179,217, 12,138,162,176, 98,197, 10, 89,159,
- 62,125, 86,121, 42,180, 0, 36,231,228,228,244,159, 48, 97,194,193,109,219,182,249,251,251,251,151,233, 61, 76,152, 48, 65,149,
-147,147,211, 31, 30, 58,221,179,217,236, 85,171, 87,175,150, 62,120,240, 0,197,197,197, 16, 8, 4,206,202,167,166,207,103,251,
-246,237,255, 56,116,232,144,175, 86,171,133,217,108,134, 64, 32, 0,195, 48,160, 40, 10,191,254,250,171,223,192,129, 3, 15,164,
-166,166,190, 88, 85, 89, 5, 2,193,235,118,225,132,232,232,104, 89,116,116,116, 15,160,210, 72,189, 78, 68, 71, 71,203,166, 79,
-159,254,170,193, 96, 88, 82,197, 57,167,169,213,234, 32,129, 64,128,157, 59,119, 66, 44, 22, 67, 40, 20, 34, 56, 56, 24,106,181,
- 26, 66,161, 16, 12,195,192, 98,177, 56, 42,139,124,119, 78, 60, 47, 47,175,200,106,181,250, 28, 60,120, 16,249,249,143,126, 82,
-183,110, 93,104, 52, 26,216,108,182, 98, 79, 47,102,102,102,102, 14, 65, 16,161,151, 46, 93,194,131, 7, 15,208,175, 95, 63,252,
-254,251,239,104,219,182,116,116,216,100, 50,213, 36,136, 31, 77, 81, 20, 83,197,115, 75, 0,240,173, 77, 78,123,227,229, 17,167,
-205,102,179, 57, 68,150,235,167,171,248,170,230, 63,203,188,206, 47, 4,138,215, 47,154,220,123,236,203,145,254, 48,228,221, 7,
- 95,226, 15, 66, 22,142,165,203, 14,224,218,189,210,251,181,116,203, 5,108,141,233, 15, 8,228,104,226,163, 66,144,132,245,198,
-141,220,127, 92,104,249,184,246, 19,158,213,134,169, 95,191,126, 80,171,213, 16,139,197,181,225,159,115,218, 96, 48,220,220,189,
-123,119,155, 1, 3, 6,128,203,229,226,230,205,155, 72, 76, 76, 76, 1,112,218, 83,161,197,102,179, 49,119,238, 92, 76,154, 52,
- 9,129,129,129,248,232,163,143,192, 98,177,156, 11, 65, 16, 78, 11,151, 39, 80, 4, 86, 61,241,209,225, 16, 95,157, 49,220,199,
-199,103, 46, 73,146,195, 40, 55, 46, 28, 77,211,180,205,102,219,166,213,106,171, 12,239,224,112, 92,119,231, 94,184, 94,131,106,
-218,180, 39,230,252, 59,180, 72, 77, 80,126,182, 97, 37, 22, 45,199,172,195,199, 82, 1, 57,206,242,184,221,100,119,252,105, 21,
-148, 32,169, 27,233, 25,153,240,243, 21,219, 69,150,125, 33, 73,180,140, 44,237,204,238,143, 79, 65, 72,253, 72,176, 40, 10, 44,
-138,130, 88,192, 67, 78,118, 22, 88, 44,242, 70,101,188,205, 41, 12, 30,220, 56, 52,220,215,143, 13, 85,128, 9,202,192, 74, 12,
- 3,109, 36, 8, 81,114,209,215,143, 31,214,156,194,224,170,173,111,140, 83,104,153,173, 86,112,134, 12,113, 14, 23, 38, 69, 71,
- 35, 42, 54, 22,244,160, 65,208,155,205,101, 76,197, 53, 21, 90, 2,129, 0,133,133,133, 24, 53,106,148,218, 98,177,188, 83,195,
- 75,156,152,159,159, 63,116,244,232,209,249, 14, 1, 99, 54,155, 49,122,244,232,252,252,252,252,161,110, 88,137, 30,131,197, 98,
-121,167,109,219,182,106,149, 74,229, 44,103, 77, 42, 28, 7,228,114,249,254,245,235,215,203,141, 70, 35,172, 86,171,147, 83, 32,
- 16,128,162, 40, 4, 4, 4, 96,235,214,173, 1,114,185,188,202,156, 85, 6,131, 97,119,108,108,172, 6, 0, 98, 99, 99, 53, 4,
- 65,196, 17, 4,177,134, 32,136,213,229,150, 53, 4, 65,196,185, 30,107, 48, 24,118, 85,197,109, 50,153,226, 82, 82, 82, 24,161,
- 80, 8,138,162, 96, 54,155,193,231,243,157, 38,113,157, 78, 7,131,161,116,152, 59, 49, 49, 17, 22,139, 37,193,157,115, 47, 44,
- 44, 60,186, 97,195, 6, 91,221,186,117, 17, 25, 25,137,168,168, 40,116,236,216, 17, 97, 97, 97,152, 55,111, 30,173,215,235, 61,
-126,247, 50, 51, 51,247,255,246,219,111,150,208,208, 80,180,105,211, 6, 60, 30, 15, 45, 91,182, 68,112,112, 48, 22, 46, 92,104,
-210,106,181, 7,107,112,155, 82,175, 94,189, 74, 85, 33,114,165,112, 99,246,110, 57,164,157, 63,127,158,234,216,177,227,158,242,
- 59,218,183,111,191, 71, 44, 22,251, 56, 76,236,158,244,200, 93,197, 21,143,199,115, 46,142,237, 44, 22,203,157,222, 15,249, 66,
-160,120,253, 87,147,122,141,125, 57,210, 23,123,142,158, 5,199,172, 1, 76, 85,140, 8,210, 22, 16, 28, 17, 2,125,216, 33,207,
- 64, 27, 48, 13,192, 21,148,198, 97,250, 8,207, 22,156,142,239,249,249,249, 72, 73, 73, 65, 98, 98, 34, 58,118,236,136,132,132,
- 4,224,145,131,188,199,208,106,181, 31,197,196,196,232, 29, 51,249,102,207,158,109, 40, 44, 44,252,200,211, 58,152, 97, 24,176,
-217,108, 52,105,210, 4,211,167, 79,199,129, 3, 7,112,243,230, 77, 88, 44, 22,167, 16,114,248,100,122, 98,209,226,112, 56, 8,
- 12, 12,132,197, 98,113, 90,179, 0,224,246,173, 91, 96,177, 88,176,217,108, 48,153, 76,213, 90,180,124,124,124,230,174, 91,183,
-110,170, 74,165, 82,230,229,229, 41, 92,151,156,156, 28, 69, 86, 86,150, 34, 35, 35, 67,145,150,150,166,120,248,240,161,226,254,
-253,251,202,197,139, 23, 79,245,241,241,153,235, 78, 57, 41,138, 66,203,150, 45,241,238,187,239, 58,151,149, 43, 87, 58,151,227,
-199,143,123,236,188, 78, 81, 20,154,204, 89,138,254,121,140,115, 57, 16, 64, 56,151,107, 31, 78,172,138,243,169,107,145, 26,233,
- 23,251,108, 67,215,196,210, 21,192, 49,235,208, 81,151, 57,221, 54,202, 59,195, 63, 53, 88, 77, 37,199,238,221,185,213,171, 73,
-243,118,100,182,170,168,204,244,207,168,158, 67, 65, 16, 4,234,212,143, 4,197, 98,129,162, 72,176, 40, 10, 50, 41, 31, 41,151,
- 46,217,140, 6,195,177,138, 56,123, 0, 44,174,128,187,242,205,190, 45,249,153,220, 92, 4, 40, 69,224,176, 75,181, 35,115,111,
-104,185, 22,130, 5, 52,151, 96, 92,134,159,224, 88, 78,201, 74, 95,189,121, 79, 92, 37, 61, 64,155,205, 6, 49,143,135, 18,163,
- 17, 6,171, 21, 61,151, 47,119, 14, 23,146, 4,129,139, 0, 90, 44, 95,142, 83, 59,118, 64,202,229, 2, 60,158,219,179, 66, 42,
- 18, 90, 42,149, 10, 99,198,140,201,207,202,202,122,171, 38, 62, 90, 14, 24,141,198, 19,217,217,217,111, 13, 29, 58,116,243,206,
-157, 59,229, 67,135, 14, 85,103,103,103,191,229,166,223,211, 99, 40, 41, 41,217,145,150,150, 86, 60,102,204,152, 77, 91,182,108,
-241,243,247,247,119,246, 68,106,244,176, 18,132,170,119,239,222, 60,119,142,171,230,144, 24,187,115,251, 36,187,101,171,197,196,
-137, 19, 79,161,212,255,202, 21,115,214,174, 93, 59,220,101,136,113, 13,128,229, 85, 17,235,116,186,213,211,167, 79,255,239,137,
- 19, 39,252,249,124, 62, 8,130, 0,135,195, 65,163, 70,141,156,179,104,216,108, 54, 24,134,193, 7, 31,124,160,202,205,205,253,
-214,205,123, 51, 49, 38, 38,166,123, 73, 73,137,239,152, 49, 99, 40, 62,159,143,156,156, 28, 44, 91,182,140,254,233,167,159, 52,
-122,189,126,108, 13,132,240,134, 47,190,248,162,103, 81, 81, 81,253, 9, 19, 38,112,180, 90, 45, 12, 6, 3,102,206,156,105,250,
-241,199, 31,211, 13, 6,131,199, 1,127, 59,117,234,116,231,225,195,135, 93,139,139,139, 11,132, 66, 97,121,107, 31, 33, 18,137,
-218, 1,216,228, 9,103, 84, 84,212,221,212,212,212,142,243,231,207,143,179, 88, 44,236,115,231,206, 57,157,225, 87,172, 88,113,
-156,207,231,247,134,135,201, 87, 9,130,176,241,120,188, 50, 22,172,242,223, 89, 44, 86,181,117, 90,211, 32,225,252,175,222,238,
- 62,246,165, 23,124,176,251,232, 5,196,236,186,119, 35, 98,108, 64,147,134,190,121,176,229,165,224,195, 55,219, 98,233,150, 11,
- 0, 74,135, 14,109,185,215,192, 20,220, 5, 35, 9,197,125,181, 42,243, 25,104, 3,142,163, 52,100,198,179,134, 50, 34,235,218,
-181,107,232,213,171, 23, 0, 32, 33, 33, 1, 93,186,116, 65, 66, 66, 2,186,118,237,234,113, 44, 45, 59,254,210,233,116, 15,143,
- 31, 63,222, 44, 52, 52, 20,167, 79,159,190, 15,224, 47, 79, 11,233, 16, 90, 44, 22, 11, 35, 71,142, 68,159, 62,125, 80,183,110,
-221, 50,179, 13, 29,223, 61, 17, 27, 86,171, 21,205,155, 55,135,209,100, 2,135,195,113, 14, 77,178, 88, 44, 4, 40, 20,184,115,
-231,142, 91, 22, 45,146, 36,135,189,254,250,235,100,114,114, 50, 70,140, 24,129,205,155, 55, 87,122,236,232,209,163,241,203, 47,
-191,224,245,215, 95, 39, 63,249,228,147, 42,195, 59, 56,156,208,221, 57, 39, 71, 59, 93, 93,189, 95, 91,156, 79, 91,139, 60, 9,
- 92, 66, 59, 84, 56,104, 82,193,182,216, 50, 66,203, 37, 72,216,211, 17, 90, 86,243,230,223,127,254,126,122,199, 85, 93, 3,148,
- 10, 31,168,181, 6,167,216, 74, 58,190, 29, 0, 48,120,226, 2,176,168,210, 33, 69,169,152, 15, 1,135,194,142,141,223,170,204,
-230,146, 10,159,174, 66, 54, 57,233,147,206,141,124,184, 34, 11,116, 65, 12, 34, 3, 30,101,202, 33,234,111,127, 92,112,181,246,
-133,255,181, 2,188,217, 80, 44,253, 54, 89, 51, 9, 22,219,202,199, 26, 68,141,198,160,185,116, 73,208,111,221, 58,156,123,235,
- 45,212,161,105,196, 5, 7, 67,206,102,195,135,199, 3, 73, 16, 48,236,219,135, 83, 59,119, 34,144,199, 3, 36, 18, 88,231,205,
-131, 49, 37, 5,150,194, 66, 67, 13,122,102, 24, 62,124,184, 74,165, 82, 13, 53,153, 76, 39,158,244, 58, 27, 12,134, 67,105,105,
-105,147, 58,117,234,180,202, 98,177,188, 99, 48, 24,158,104,102,148,201,100, 58,148,157,157, 61,100,248,240,225,219,119,237,218,
-229, 47,147,201,106,204,149,159,159,223,182,150, 30, 39, 27,128,207,236,206,237,147,162,163,163,101,231,207,159,255,239,250,245,
-235, 87,185,244, 38, 20,227,199,143,127,187,156,200,170,118,214, 33,128,212,220,220,220,121, 51,102,204, 88,240,205, 55,223,136,
- 29,142,239,151, 47, 95,134,213,106, 5,155,205, 6, 77,211, 24, 63,126,124, 81,126,126,254, 82, 84, 30,209,249,177, 71, 75,167,
-211, 53,154, 63,127,254,250,229,203,151,247,161, 40, 74, 68,211,180,190,184,184, 56,174,164,164,100, 44,106, 22, 71,203,150,151,
-151, 55,230,243,207, 63, 31,179,108,217,178,215, 73,146, 84, 88,173, 86, 85, 97, 97,225, 94,131,193,240, 35,106, 48,148,116,250,
-244,233,188, 55,223,124,243, 94, 94, 94, 94,211,144,144, 16,173, 88, 44, 54,153, 76, 38, 74, 32, 16, 72, 69, 34, 81, 20,128,211,
- 4, 65, 92,247,132, 51, 41, 41, 41,123,194,132, 9, 15,140, 70, 99,147, 53,107,214,196, 75,165,210,163, 4, 65, 16, 28, 14,199,
- 87, 32, 16,244, 2, 16, 71, 16,196,109, 79, 56, 73,146,180,185, 90,175,202,251,103,113,185, 92,183,124,180,234, 7, 8,199,245,
-105,196,194,238, 99, 23, 16,179, 59,117, 3,205, 48, 59,119, 38, 21,236,251,168, 11, 96,222,246, 38, 90, 14,221, 84, 58, 92, 8,
-192,150,123, 13,230,109,163, 65, 8,253, 17,159,193,134,214, 96,222, 15, 47, 42,130, 51,188,131, 74,165, 66,114,114,178, 67,100,
- 69, 1, 64,215,174, 93,147, 28, 98, 43, 49, 49, 17,109,218,180, 73, 2,192,246,244,121,213,233,116, 51, 70,141, 26,117,200,222,
- 57,158, 81,131,142,159, 83,104, 57, 4, 85,221,186,117,157,235,174,139,139,143,150, 91,160,105, 26, 28, 14, 7, 44, 22, 11,202,
-224, 96,231,127, 49, 12,131, 59,119,238, 64,173, 86,187, 37,180, 40,138,162, 8,130,192,136, 17,238, 77, 72,254,207,127,254,131,
-184,184, 56, 80,110,170, 66,138,162, 16, 30, 30, 94,237, 49, 14, 93,234, 46,103, 72, 72, 72,141, 57,159,182, 22,169,169,192,170,
-232,123, 69,162,170,178, 23,226,239, 66,102, 81,145,246,179,141,235, 86,124, 51,126,242, 7,226,107,119,115,160, 45, 50,130,162,
- 72,215,202, 19, 44, 22, 5,169,136,143,208, 32, 31,108,249,225,127,133,133, 58,205,231,168, 36,239, 97, 93, 9,103, 98,239,118,
- 13,121, 28,165, 30, 77, 90, 12, 7,197,127, 36, 2,152,236, 74, 70, 7,187,252,137, 87, 82,245,252,223, 83,245, 19, 47, 22,152,
- 30, 23, 90, 38,211,203,179,251,246,253, 35,230,192, 1, 97,251, 13, 27,112,119,252,120, 4, 27, 12,224,217,135, 18, 73,130,128,
-152,195,129,152,195, 41, 21, 89,203,150,193, 96,181, 98,249, 91,111, 21, 27, 77,166,190,158,188,228,249,249,249, 24, 52,104, 80,
- 94,102,102,102,127,212, 96,104,175, 50,232,245,250, 29, 0,118,212, 22,159,209,104, 60,145,158,158,254,202,160, 65,131, 14, 28,
- 58,116, 40,224, 25, 9, 50,231, 16, 91,230,243,231,207,191, 29, 31, 31,127, 23,101, 19,139,106,226,227,227,239, 78,152, 48,129,
- 88,191,126,253,143, 0,190,128,155, 1, 60,245,122,253,138,195,135, 15,163,123,247,238, 95, 44, 90,180,200,175,109,219,182, 80,
- 40, 20, 40, 44, 44, 68, 98, 98, 34,166, 77,155,166,214,233,116,139, 52, 26,205, 55, 30,150,217,108, 52, 26, 71,187, 78,165,174,
-141,235, 96, 52, 26,127,202,202,202,250,169,182, 8,167, 76,153,114,249,206,157, 59,249, 1, 1, 1, 29, 56, 28, 78, 11,148,250,
- 1,101, 3,248,209, 83, 65,228,192,228,201,147, 47,221,185,115, 71, 85,167, 78,157,142,118, 78, 25, 74,211, 24,173,171, 1,103,
-230,133, 11, 23, 66,218,181,107, 71,178,217,108,134,162, 40,176,217,108,134,197, 98, 49,118,191, 26, 6, 0,246,238,221,203, 3,
- 80,101,218,156,187,185,134,249,163,255,119,242,147,235,217, 37, 59, 83,114,138,167, 3, 96,182, 93, 19,254,217, 50,128,122,249,
-229,198,233, 48,198,118, 5, 33, 45, 13, 84,201, 20,101,129, 16, 5, 34,221, 86, 7,115,246,220,200,182,130, 88,226,213, 84, 21,
-247,171, 97, 15,239,144,149,149,229, 42,178, 28, 86,171,168,174, 93,187, 38,217, 69,150, 99, 95, 77,252,203,142,216,108,182, 39,
-106,195, 24,134, 65, 76, 76, 12,214,174, 93,139,234, 34,154,219,103,247, 17,213,241, 57, 44, 90, 52, 77,195,108, 54,227,218,181,
-107,206,152, 93,142,225, 66, 71,104, 7,171,213, 90,229,108,117,154,166,105,147,201,132, 95,127,253,213, 45,177,181,117,235, 86,
-148,148,148,128,174, 70,193,185,134, 98,104,213,170, 21,212,106,181,115,178, 79, 84,212,163, 80,121,102,179,217, 35,225,234,224,
-108,210,164, 9, 84, 42, 21, 28,254,194,161,111, 61, 50,246, 88,245,250,127,235,115, 95,169, 69,235,111,111, 49,121, 66,233,161,
-182,157,251,116,121,235,237,105,162, 34, 35,141, 7, 15, 30, 34, 47, 55, 11, 36, 65, 66, 89, 39, 4, 97, 97,225, 16,112, 73,108,
-142,253, 70,159,116,234,232,201,162,194,130,126,149,113, 13,240,225,156, 90, 54,164, 75,199, 6, 13, 36, 4,172, 22,128,182, 0,
- 86, 11, 96,179,127, 58,182,217,202, 62,115,201,201, 26,230,147,139,234, 51,251,181,230, 10,115, 86, 13, 5,186,200,228,242, 63,
-230,236,221, 43,180,153,205,200,159, 49, 3, 66,171, 21,124,123,175,164,244, 68,120,176,206,155, 87, 42,178, 70,143, 46,214,106,
- 52, 30,165,224,241,247,247,191, 64, 16,132,127, 94, 94,222,115, 21, 25, 62, 32, 32, 96, 63,195, 48, 42,149, 74,213,246, 25, 42,
-151, 2,128, 6,128,185,130,142, 68, 0, 60,247,255,113, 32, 60, 32, 32,224, 19,146, 36, 59, 49, 12,227, 71,146,100,129,205,102,
- 59,157,155,155,187, 24,192, 29,111,123,250,143,193, 17, 25,190, 94, 53,199,229, 2,120, 31,165, 78,193, 15,220, 37,111,233,227,
-227, 99,228, 90,118,189, 22,201,235, 57, 44,202, 7,245,131, 36, 96,115,248,200,212, 89,113,228,186, 14,235,142,103,167, 25, 44,
-244,192, 91,121,197, 87,189,183,162, 74,212,122, 10,158,218,132, 92, 46, 63,251,199, 31,127,180,173, 95,191, 62,233,234,240,238,
-136,149,231, 24,222, 98,177, 74,181,220,137, 19, 39,172, 35, 70,140, 56,157,147,147,211,189, 50, 78,137, 68,242,231,149, 43, 87,
- 94,210,106,181,143, 9, 42,215, 72,241,142,117,189, 94,143,201,147, 39, 31,174, 44, 5,143,143,143,207,178,111,190,249,102,234,
-224,193,131, 73, 71, 56,138,255,107,239,124, 94,155, 8,162, 56,254,221,164,219,212,180, 77,193, 4,148, 84,193,104,192, 20,193,
- 67, 17,188,120,216,160, 69, 60,139,246, 34,245,230,165,254, 9, 66,227,127, 96,132,122,232,205,226,201, 67,207, 22, 20,189,122,
-240,100,109,107, 69,186,136,105, 66, 80,168,177,166,205,207,245,224, 46,172,211,221,184,211,125,179,217,141,251, 96,161, 61,244,
-211,239,204,123,143,188,125,147,153, 49, 63,198,117, 65,198,211,108, 54,177,188,188,220, 45, 22,139,143,119,119,119,109,151, 14,
-211,233,244,151, 82,169,116,218, 56,106,193,201,161,162,153, 76,102, 71, 85,213, 73, 47,153, 1, 46,184,254,234,110,245,165, 53,
- 33,199,227,243,137,241,227, 11, 55,239,220, 79,101,178,231,165,147,233, 83,144, 16, 65,165,252, 21,234,231,143,218,202,179,197,
-111,123, 63,190, 63,172,215,247, 22,123,113, 46, 0,217,179, 19,195,207, 99, 29,228, 96, 20, 64,204,253, 84,135,222, 56, 0, 52,
-229,200,198,118,173, 53,251,161,199,178,143, 81,108, 61, 88, 89, 25,141,229,114,135, 14,138,235,118,187, 56, 88, 95,199,163,185,
- 57,238, 34, 43,180,208, 66, 35,177,115,248,247, 25, 89, 45,252, 57,159,139,183, 99, 34, 77,157, 24,155,213,128,219, 17,116, 47,
- 70, 36, 41,214,214,176, 9, 13,171,163, 67,191,158,188,219, 65, 61,156,126, 71,230,219, 75,165, 1,140, 37,147,201,151,209,104,
-244,140,209,145, 49,119,235, 45, 46,148,222,174, 84, 42,215, 0,244,218, 33,156, 77, 36, 18,139,157, 78,231,178,147, 75,165,163,
-209,232,219, 90,173, 54,143, 30,151, 74,139,216,117,152, 74,165, 62,169,170,154, 53,118, 81,155, 63, 43,173,118,150,111,109,109,
- 65, 81, 20,181, 92, 46,103,188,100,250,213,108,118, 29,250,167,163,101,178,201,225,145,241,187,177,248,177,171,221, 86,123, 10,
- 18, 48, 36,203, 27,141,253,250,171,131,250,207,167,176, 89, 46,244,210,110, 1, 87, 70, 98,177,213,225,137,137,184, 85,209,214,
-170,213,234, 7,141,198,245,176,200, 10, 45,180,208, 66, 11, 45, 64,150, 75, 38,147, 47,100, 89, 30, 49, 23,147,236,207,134,181,
-219,237,253,106,181,122, 3,192,166,199,204,255,211, 56,191,164, 54,227,148,169, 63,138,223,153, 2,199,174, 17, 50, 21,157, 89,
- 8,136, 78,197,175, 76, 99,188, 28,220, 25,158, 56,162,154, 79,147, 78,141, 90,167, 40, 38, 85, 30, 89,232,212, 4,248,189, 16,
- 16,157,138,223,152,108,252, 56,228,114, 49, 29,198, 20,175, 78,141, 90,167, 40,166,219, 60,234,161, 83,115, 27, 75, 54,190, 47,
- 32,128,182, 54, 13,109,109, 26,218,251, 75,150,231, 54,222,179,251, 59,174, 47, 18,138,218, 9, 96, 28,187,175,243, 37,191, 50,
-205,243, 64,121, 85,128,128,107, 7, 94, 83, 51,153,249,164,178,130,190,195,228, 13, 28, 28, 56,202, 51,118, 10,191, 51, 99, 37,
-225, 30,161,200,226, 98, 82,197,189,104, 38, 85, 46,177, 76,138,184,183,242,187, 64, 31, 81,233, 36,201, 37, 17, 49,111, 17, 63,
-174,185, 44,147, 34,151, 88, 38, 69,220,123,193,164,200, 37, 43, 38, 69,220,219,249, 62,168,141, 38, 99,185, 80, 63,226, 65,114,
- 80,108, 45, 1, 64,228, 40,147, 38,176, 83,150,167,102, 82,107, 22, 81,108,114,116, 96,250,206, 36,246, 81, 65,103, 82,190,221,
-228,169,124, 36, 34,222,205, 76, 42, 62,203,161,240,147, 21,211,173, 94, 27,157,228, 99,119, 27,247, 94, 49,137,125, 68,146, 75,
- 12, 51, 79,252, 50,144, 55,253, 94,160,100, 82,229,146,133, 78,215,126,178, 98,186,213,107,163,147,124,236, 20,159, 33,162,184,
-253,236,104,105, 17,219,152, 88, 98, 30, 79, 10,141,190, 45,201,113,178, 7,138,201,185, 60, 51, 35,192,247,125,213, 73,201,100,
- 53, 82, 46,247,136,212, 73,201,228,208, 58,112,204,160,249,221,143,243,105,199,115,179, 44,101,215, 29, 21,161,147,146,233,144,
- 61, 16, 76, 23,190, 31, 56, 27,242,139, 16, 99,226,137,223, 76, 64,220,129, 17, 54,110, 98,157,121, 17, 29, 66, 1, 70,174, 83,
-127, 83, 94, 16, 48,246,160,204,105,152, 75, 97, 46,249, 46,151,152,152,204, 19,118,138, 72, 59,207, 44,147,226,127,152, 25, 84,
- 49, 42,122,236,148,185, 36,194,247, 65,179,223,196,219, 78,253, 18,230,201,232, 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,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 0, 7,116, 73, 77, 69, 7,219, 9, 8, 18, 45, 9, 58,221,
+153,135, 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, 97,252,189,217,
+ 59,105,218, 52, 29,148,150, 2,165,147, 85,160,236, 81, 40,101,149,141,162, 34, 56, 1, 5, 68, 5,197, 1, 40,202,146, 37, 67,
+ 86, 5, 5, 17, 20, 16, 89,101,169, 40,200,166, 5, 74,129,178,186,103,210,221,166, 73, 51,239,249,253, 65,203,175,212,142,164,
+197,129,222,207,243,220, 39,201,185,185,111,206, 93,231,190,249,158,117,231,236,149,139,167, 45, 28, 54, 11,222, 30,206, 24, 29,
+209, 17,175,140,235,137, 78,129,205,144,166, 53,224,228,201,159, 44, 41, 41, 73,231,237,233,113, 88,165,153,120, 51,254,220,141,
+ 43,103,172, 92, 14,133,192,128, 54,152,251,193,187,202, 69, 31,205,113,106,211,202, 27,241,201, 37,248,233,196, 81, 75,118,102,
+198,175,127, 87,143,195, 83, 0, 79, 42,160, 36,108, 22, 11, 54,150,160,156, 93,217,145,166,109,112,176,191,155,187, 59, 98, 98,
+ 98,192,114,160, 71,232, 41,128, 39,149, 62,168, 5,215,233,116,168,210,107, 29, 16, 16,224,237,227,131, 35, 49, 49, 96,211,244,
+173,190, 14, 14, 48,122,251, 65, 53,244, 67, 93, 10,168,120,189, 57,100,173,155,171, 3,148, 10, 9, 46,198,223,131,209, 66, 46,
+125, 91,132,191,117, 60,178, 63,145,201,104,100,213,225,242, 77,155, 54,133,109,217,178,101,224,219,111,191, 45,157, 52,105, 18,
+132, 66, 33,244,122, 61,188,188,188, 96,179,217,112,236,216, 49,196,198,198,234,104,154,254, 9,127, 28, 54, 32, 2,213,122,105,
+ 28, 79,130,232,129,223,210,135, 29,120,234,169,199,162, 9, 0,210,123,180,188,160,133,105,199,218, 61,103,198,236, 60,126,133,
+122,243,217,190,172, 78, 1,205, 1, 0,110,110,110,144,203,229, 14,107, 62, 6,254,116,205,234,213,186,185,185,185,183,115,115,
+115,181,175,190,250,106, 96, 85,195,119,129, 64, 80, 81, 25,201, 42,170,109, 27, 59,242,105, 6,240,250,150, 45, 91, 14,150,148,
+148, 28,127,231,157,119,176,104,209, 34, 28, 58,116,168, 55,128,179,141,220,119, 91, 81, 81, 81,241,165, 75,151,220,252,130, 66,
+209, 82,205, 69,159,121,119, 65, 8,129,139,152,160,172,184, 16, 87,175, 94, 65, 89, 89,217, 69, 71,242,105, 54,155,139,181, 90,
+173, 74,173, 86,163,176,176, 16,249,249,249, 15, 77, 86, 81, 81, 17, 10, 11, 11, 9, 69,253, 97,204,150,250, 52,203,181, 90,173,
+ 62, 49, 49,145,239,214,220, 15,173,212, 60,116,253,224, 54, 64, 8,188,157, 89, 40, 43, 45,198,249,243,231, 81, 82, 82,242, 91,
+ 93,154, 52, 77,207,154, 48, 97, 2, 27,192,196,119,222,121,199, 25, 64,135,119,223,125,247, 39,212,232, 89,200,225,112, 62,223,
+177, 99, 71,219,170, 42,198, 57,115,230,172, 2,176,229,175,186,150, 92, 92, 92,102,197,196,196,200,204,102, 51,214,174, 93,139,
+ 85,171, 86,109,197, 31, 7,170,140,249,226,139, 47,214,179, 88,172,105,211,167, 79,199,148, 41, 83,196,157, 59,119,126, 59, 39,
+ 39,231,219,218, 52,179,178,178,230,118,234,212,105,190, 86,171, 93,108,151, 89,190,123,119,114,167, 78,157,230,106,181,218,101,
+245,157, 35,137, 68, 34,177,217,108, 72, 73, 73, 41, 2,234,108,223, 81,145,146,146,146,101,179,217,188,196, 98,177,115, 67,215,
+103, 81, 81,209,226,206,157, 59,127,172,209,104, 78, 0, 88, 88,139, 33,191,150,147,147, 19, 50,115,230,204, 25, 75,151, 46, 29,
+147,155,155,251, 93, 67,154,105,105,105,139,195,195,195,231,221,185,115,103, 27,234,174, 2,254, 98,193,130, 5,230, 29, 59,118,
+188,150,146,146,178,164, 1,205,195,249,249,249,135, 29, 56,191,117,125,255,161, 38,155,205,126,119,233,210,165,172, 77,155, 54,
+129, 16,178,194,102,179,213,149,207,248,253,251,247,111,239,217,179,231,164, 61,123,246, 8, 67, 66, 66,166, 24,141,198, 93, 13,
+ 93,159,122,189,126,223,158, 61,123,198,196,199,199,123, 77,154, 52, 73,232,239,239, 15,179,217,140,156,156, 28,108,218,180,169,
+ 34, 33, 33, 33,179,184,184,120,159, 35,101,136,213, 84,250,236,185,147, 7,118,165,222, 77,232,222,111,240, 72,165,201,236, 5,
+ 65, 1, 27,197, 5,185, 56,118,120, 95, 81, 74, 74,210,121,189,190,248, 89, 71, 52,205,198,146,103,206,255,122,240,187,204,148,
+196,110,125,194,135, 42, 43, 76, 62, 16,240, 88, 40,208,100,225, 88,204,129,194,148,148,228,223, 43, 44,198, 23,254,174,114,158,
+237,139,133,236,220,216, 87,167, 14,239, 8,145,210,235, 42, 23, 88,219, 19, 16,169,220,220,120,149,247, 14,164, 15,218, 60,218,
+165,169, 1,248,126,149,181, 84,122,189, 30, 92,192,244, 34,192,117,117,117, 21, 1,192,157, 59,119, 32,126, 80,171,225, 80, 62,
+117,128, 68, 92, 77,151, 5,232, 11, 56,104,214, 90, 46,161, 0, 32, 51,183, 0, 38, 75,189,207,141, 39,157,232,106,134, 43,186,
+ 49, 2, 60, 0, 17, 82,169,116,209,252,249,243, 87, 92,188,120,113, 69, 84, 84,212, 10,129, 64,176,168,242, 96,243,234, 57, 17,
+127,153,102, 23, 79, 56,135,183,162, 78, 71,182,166,232,169,189,149,182, 23,186, 74, 76,253,251,247, 95,223,196,124, 54,229,102,
+249, 51, 53, 15, 88, 44, 22,130, 7,213,118, 7, 80,119,149,224,251,213,214,231,166,167,167,147,202,247,142,228, 83, 53,126,252,
+120,186,172,172,140, 60,253,244,211, 4, 13, 79,225, 83,175,166, 64, 32, 8,239,211,167,143, 69,147, 87, 72,110, 39,103,145, 11,
+113, 55,201,241,147,231,200,119,251, 98,200,186,245,155, 73,251,246,237, 77, 0,124, 28,209,228,112, 56,253,195,195,195, 11, 52,
+ 26, 13, 73, 76, 76, 36,167, 79,159, 38,123,247,238, 37,155, 55,111, 38, 27, 55,110, 36,205,155, 55,215, 0,112,115, 68, 83, 36,
+ 18,141, 28, 50,100,136,165,184, 84, 79, 82,178, 10,200,245,196, 20,114,246,210,117,114,236,228, 89,242,237,174, 61, 36, 56, 56,
+184,194, 14, 77, 54,155,205, 94,247,221,119,223,149, 18, 66,200,200,145, 35, 51,241,232, 64,170, 45,103,205,154,165, 37,132,144,
+101,203,150, 21,160,246,134,240,127,246,181, 52,184, 89,179,102,183,121, 60, 94, 12,128,137, 13,108,247, 12,135,195, 57,228,238,
+238,126, 25,192,232,191,225, 62,138, 82,171,213, 23, 0, 52, 52,195, 65,213,247, 70,253, 75,238,247, 63, 67,179, 63,135,195, 57,
+ 13,212, 63,137,112,181,242,250, 83, 54,155,125, 4,192, 0, 7,243,217, 70,165, 82, 61,173, 84, 42,223, 84, 42,149,111,170,213,
+234,167,249,124,126,155,166,236,187, 75,155,136,225,222,161, 35,246, 55,239, 48, 44,205,187, 99, 84,154,111,167,145,251, 93,218,
+ 68, 12,111,170,166, 79,167,145, 7,188, 59, 70,165,123,119, 28,158,218,178,203,200,253,170,128,136, 33,127,231, 57,154,216, 12,
+158, 3, 91,194, 74, 78,207, 35,228,244, 60, 18,209, 18,116,119, 39, 4,135, 1,178, 65, 17, 17, 43,137,205,182,114,204,168, 81,
+ 43,253, 0, 23, 2,176,107, 46,181,105,134, 2,242,135,219,142, 28,185,178, 21,160, 26, 8,136,251,246,238,189,130,216,108, 43,
+ 39, 60,243,204, 74,111,192,189, 54,189,186, 52, 9,192,110, 6,120, 86,215, 85, 1,173,199,249, 34,228,253,225,190,132,156,158,
+ 71, 22, 60,229, 79, 58,185, 97, 98, 3,154,117, 69,138,158,232,136,150,163, 72, 42, 11,215, 37,149,175,146,199,112, 17, 62,118,
+205,110, 30,240,143,104, 77, 37, 14, 13,224, 20,226, 65,151,100,201,191,176,144,220,102, 50,153, 72, 69, 69, 5,209,235,245, 68,
+167,211,213, 52, 80, 15, 13, 89,118,118, 54,201,204,204, 36,233,233,233, 36, 53, 53,149,224,255,109,111,236,206,167, 92, 46,223,
+242,212, 83, 79,217,184, 92,238,186,199,177,239,206,206,206, 75,186,118,237,106, 94,179,102, 13,217,191,127, 63,249,242,203, 47,
+201,244,233,211, 73,219,182,109,141, 78, 78, 78,207, 54, 70,211,221,221,125,110, 64, 64, 64,193,214,173, 91,201,183,223,126, 75,
+ 86,175, 94, 77, 62,252,240, 67,155,151,151, 87,174, 76, 38, 27,212, 24, 77,181, 90, 29,221,171, 87, 47,115,116,116, 52,249,233,
+167,159,200,206,157, 59,201,172, 89,179, 72, 96, 96,160, 81, 34,145,140,181, 83,147,205,225,112, 86, 78,157, 58, 53,215,211,211,
+ 51,166,198, 58,113,112,112,240,229, 9, 19, 38,100, 3,152,243, 47,186, 62, 25, 77, 70,147,209,252, 19,140,214,115,158,104, 70,
+ 0,182,152,199,123,166,111,239,222, 43,120,192, 51,142,154, 34, 33,155, 61,174,103,215,174, 43,120,192,179, 85,223, 21,178,217,
+227,250,246,238,189,130,203,102, 63, 95,151, 94,125,154, 4, 96,243, 56,156, 57, 61,187,119, 95,201, 1, 62,168, 74,235,223,146,
+186, 53,107,112,115,210,219,135,186,247,188, 26,226,127,177,209,122,236,112,254,132,139,240, 73,209,252,167,220,212,126,149,134,
+233,128, 3, 17,173, 3,120, 48,139,186, 95, 35,243, 41,122,204,251,222, 78,165, 82, 29,245,243,243,203,107,209,162, 69,182, 82,
+169,220, 5,192,171,137,154, 33,238,238,238,223,184,185,185,221,245,240,240,136, 87,169, 84,159,227,193,168,243,141,214,228,114,
+185, 93,221,220,220,126,243,245,245, 45,246,241,241,209,168, 84,170,239,106,137,100,217,163,233,129,218, 11, 21, 94,229, 58,230,
+161,195,104, 50,154,140,230, 35, 6, 38,178, 21,150, 14,108, 9,235,192,150,176, 69,250,226,243,234, 6, 37, 10, 16, 53,214, 20,
+189, 0, 8,106,126,191, 33,189,134, 52, 9,192,238, 1, 72,107,110, 51,212, 11,193,118,106, 62,233, 17,173,170,114,222,177,225,
+ 29,234,192,250, 39,100,242, 73,209,252,167,112, 15,245, 52, 70,174,198,146,199,248,155,134,199,188, 15,215,243,243,243,135,228,
+231, 63,214,190, 9, 55,114,115,115, 39, 62, 78, 65,139,197,114, 81,163,209,244,123, 12, 82,117,117,189, 54,195,206,110,217, 12,
+ 12, 12,255, 29, 40,192,134, 36,188, 23,209, 6,107, 57, 54,176,142, 37, 35,171, 70,151, 60, 3,213, 24,205, 7,216,182,213, 82,
+198, 83,141,205,231,255,209,253, 65, 35, 19, 55,169,255,206,105,203,193,131, 54, 90, 77, 54, 90, 12, 12, 12, 12, 12, 12, 12,127,
+ 1, 63,223,101,254,136, 61, 1,196,224,209,232, 91, 76, 53, 35, 90,103,232,211,145,158, 20,141, 9,159,254,204,104, 50,154,140,
+ 38,163,201,104, 50,154,140,230,127, 78,179,138,186,230, 78,189, 93,227,115,163,122,241,253, 87, 96,234,217, 25, 77, 70,147,209,
+100, 52, 25, 77, 70,147,209,252,183,211,232,113,180, 24, 24, 24, 24, 24, 24, 24, 24, 24,234,167,206,168, 27, 99,180, 24, 24, 24,
+ 24, 24, 24, 24, 24,154,134, 7, 30, 76, 81, 21,131,255, 79, 85, 21, 13, 52, 60, 5,207, 35, 44, 93,186,148,229,231,231, 39,229,
+243,249,109,147,146,146, 88,175,191,254,122,147, 59, 18,172,248,124, 29,203,199,199, 71, 10,160,109, 65, 81, 25,235,165, 87,222,
+161,152,243,197,192,192,192,192,192,192,240, 4, 49,172,210, 88, 85,189, 62,140,112, 57,100,180, 22, 46, 92,136,244,244,116, 9,
+128,241, 33, 33, 33,252, 13, 27, 54,144,221,187,119, 55,201, 24,125, 48,103, 22,210,210,210, 36, 0,198,171, 85, 78,252,175,182,
+ 44, 39,123, 14,157,121,236,102, 75,165, 82,185,252,149,219, 49, 48, 48, 48, 48, 48, 48,252,167,152, 92,237,117,114,163,140, 22,
+135,195, 97,243,249,252, 86, 44, 22,107,136, 80, 40,236, 2, 0,149, 83,178, 52, 26, 14,135,195,230, 11, 4,173,216,108,246, 16,
+129,224,129,230, 83,195,123, 53, 85,115,128, 68, 34,201, 16,139,197,177, 0, 68, 50,153,236,138,217,108,190, 41,147,201,206, 57,
+162, 35,147,201,206, 85,110,119, 5,128, 72, 44, 22,199, 74, 36,146, 12, 14,135, 51,128,185,158, 24, 24, 24, 24, 24, 24, 24, 42,
+137,174,101,249, 35,135, 15, 31,174,211,224,240,249,124, 86, 72, 72, 72, 47, 31, 31,159,179, 65, 65, 65, 38, 47, 47,175,189, 98,
+177, 88,210,196,140,177,252,252, 3,123,121,122,184,157,237,216,202,195,164, 86,171,247,114,185,220,166,104,178,101, 50,217,234,
+200,200,200,146,179,103,207, 18,185, 92,174, 1,224,228,234,234,154, 77, 8, 33,238,238,238,180, 35, 98,238,238,238, 52, 33,132,
+184,186,186,102, 3,112,146,203,229,154,179,103,207,146,200,200,200, 18,153, 76,182, 26, 13,143,104,203,192,192,192,192,192,192,
+224, 0,245,121,145,127, 48, 85, 81, 44,143, 70,239, 28,159,207, 15, 85,169, 84, 9,111,189,245,150, 45, 58, 58,154,248,248,248,
+ 92, 82,171,213,221, 85, 42,213, 35, 13,234, 95,124,241, 69, 71,170,253, 66,101,114, 69,194,182,153,131,109,134,175, 70,146,102,
+ 30,234, 75, 78, 78, 78,221,229,114,249, 35,154, 19, 94,154, 98,143,166, 44,251,138,210, 0, 0, 32, 0, 73, 68, 65, 84,167, 66,
+161,136, 95,186,116,105, 69,113,113, 49, 33,132, 16,133, 66,161, 1,160,116,115,115,203, 78, 78, 78, 38, 42,149,138,192,254, 40,
+ 30, 75,165, 82,145,228,228,100,226,230,230,150, 13, 64,169, 80, 40, 52,132, 16, 82, 92, 92, 76,150, 46, 93, 90,161, 80, 40,226,
+ 1,120, 50,183, 5, 3, 3, 3, 3, 3,195,127,218,104,213, 52, 92,246, 85, 29,118,233,210, 69,224,230,230,214, 93, 38,147,141,
+146, 74,165,235, 71,140, 24, 17, 50,102,204, 24,150,209,104,180,133,132,132,120,250,250,250,206, 80, 42,149, 19,133, 66, 97,123,
+ 62,159,255,188, 92, 46,247,216,181,107,151, 95,125,154,237, 58,116, 22, 56, 57, 41,187,243,249,130, 81, 82,169,108,253,212,113,
+253, 67, 38,190, 61,150,197, 51,165,218,250,183,247,246,108,219,202, 99,134,187, 82, 50,145,195,102,181,167, 40,234,121,161, 80,
+232,241,237, 87,155,253, 26,216,177, 86,158,158,158, 87,118,237,218,213,118,252,248,241,130,196,196, 68, 0,128,205,102,227, 3,
+176,176,217,108, 8, 4, 2,152,205,230, 34, 0,246,158, 64, 98, 54,155,139, 4, 2, 1,216,108, 54, 0, 88, 42,245,144,152,152,
+136,241,227,199, 11,118,237,218,213,214,211,211,243, 10,128, 86,204,173,193,192,192,192,192,192,240,159,165,202, 92,197,160, 70,
+213, 33,167,202, 61, 70, 69, 69, 61, 18, 53,226,243,249, 27,238,220,185,211,211,217,217,185, 21,151,203,181, 61,243,204, 51,130,
+ 9, 19, 38, 32, 47, 47,143,214,233,116,236,208,208, 80,183,203,151, 47, 15,177, 90,173,189,157,156,156,244,197,197,197, 42,163,
+209,120, 15,192,140,122, 50,178,225,238,237,132,158, 46, 74,231, 86,124, 46,219, 54,253,229, 9,130, 15,230, 12, 6,101,140,163,
+109,218, 2,246,167,157,156,220, 62, 63, 87, 62,228,142,217,214,187, 92, 33,212,231,150, 24, 27,212, 84,169, 84,157,120, 60, 94,
+236,209,163, 71, 33, 22,139, 81, 82, 82, 2, 62,159, 15, 0,208,233,116, 10, 0, 28,138,162,192,231,243, 81, 90, 90,170,116,228,
+168,149,150,150, 42,249,124, 62, 40,138, 2, 0, 78,165, 30,248,124, 62, 74, 74, 74,224,231,231, 71, 29, 61,122, 84, 61,100,200,
+144,251,102,179,185,115,126,126,126, 28,115,173, 49, 48, 48, 48, 48, 48, 56, 78,109, 94,228, 9,162,193,113,180,250, 85,134,234,
+170, 79,156,187,221,213,213,213, 93, 42,149, 6, 77,158, 60,153,165, 82,169, 16, 27, 27, 75,151,151,151,179,184, 92, 46,184, 92,
+ 46,187,127,255,254, 82,171,213, 42, 62,114,228, 8,117,255,254,253, 60,139,197,242,105, 65, 65,193,229,122, 50,178,189,181,147,
+192, 93,228,196, 15, 58,244, 78, 31,150,171, 95, 1,112,124, 1, 77,116, 90, 22,135, 38, 80, 73,104,246,202,222,148, 52, 87,225,
+ 43,158,254, 93, 30,245,251,253,226, 60,139,197,242,105, 89, 89, 89,125,154, 89, 0, 80,153, 39,200,229,114,216,108,213,231,183,
+ 4, 97,177, 88, 16, 8, 4,141, 58,114, 2,129, 0, 44, 22, 11,168, 22, 9, 83, 40, 20, 96,179,217, 96,177, 88,224,114,185,143,
+228,131,129,129,129,129,129,129,161, 81,212,230, 69,158, 20,170,143,163,101,223,220,148,110,110,110,148, 92, 46,247,232,208,161,
+195,199,145,145,145,201,163, 71,143,214,175, 89,179,134,172, 90,181,138,172, 92,185,146,108,221,186,213,246,235,175,191, 90, 94,
+121,229,149,138, 54,109,218,220, 91,191,126,125, 16, 0, 12, 29, 58,180,206,234, 72, 39,165, 51, 37,229,115, 60,130,131,218,125,
+252, 92,191,182,201,243, 70,249,235,205,219, 66, 9, 61,191, 57,177,173,243, 37,182, 61, 3,108,228,206,114,203,226, 87, 7, 84,
+180,240,105,113,111,227,214,239,131, 0, 32, 34,114,104,189, 85,156, 42,149,170,139,151,151,151,230,196,137, 19,116, 81, 81, 17,
+ 41, 40, 40,168,106,163, 85, 12, 64,225,227,227,147,109,181, 90,137, 82,169, 44,116,228,168, 41,149,202, 66,171,213, 74,124,124,
+124,178, 31,248, 43, 69, 49, 33,132, 20, 20, 20,144,162,162, 34,114,226,196, 9,218,203,203, 75,163, 82,169,186, 48,247, 7, 3,
+ 3, 3, 3, 3,195,127,150,201, 53, 94, 27,166,103,207,158,148, 92, 46,103,181,107,215, 78,234,233,233,217,205,211,211,243,226,
+231,159,127, 78, 86,173, 90,101,221,180,105, 19,249,230,155,111,172, 47,188,240, 66,169, 68, 34,137,225,243,249, 74, 0,240,245,
+245,173, 55,228,215,165, 91,119, 74, 36, 20,176, 2, 2,130,165, 42, 23,151,110,174, 46,206, 23,205,171,218, 18,178,160,153,149,
+108,233, 72,200,158,193,214,229, 79,135,149,114,185,188, 24, 0, 74, 0,240,242,244,176, 55,140,232,169, 86,171,227, 23, 44, 88,
+ 80,110, 54,155, 73,101, 47, 67, 13, 0, 39, 31, 31,159,108, 66, 8,241,242,242,202, 0,160,178, 83, 79,229,229,229,149, 65, 8,
+169, 50, 90, 78,238,238,238, 26, 66, 8, 49,155,205,100,193,130, 5,229,106,181,154,105, 12,207,192,192,192,192,192,192, 80,231,
+ 92,135,117, 70,138,206,158, 61, 75, 74, 75, 75,233,172,172, 44,155, 78,167,147,135,134,134, 42,217,108, 54,220,220,220,216,108,
+ 54,155, 46, 47, 47,103,171, 84,170,108, 46,151,251,173,201,100, 42, 26, 53,106, 20,149,146,146, 82,111, 67,243,203, 23,206, 19,
+ 67,133,145,206,204,204,176,233,117,165,242,137,237,157,149, 28,171, 25,116,104, 79,118,169,168, 13, 77, 27,138,216,129, 30,130,
+108, 30,143,251, 45,128,162,209, 81,195,168,204,236, 28,123, 27,175,103,107,181,218,208, 13, 27, 54,108,233,211,167, 79,145, 94,
+175,175,106, 91, 85,115, 8, 6, 39, 59,245,106,126,143, 77, 81, 20,244,122, 61,250,244,233, 83,180, 97,195,134, 45, 90,173, 54,
+ 20, 64, 54,115,125, 49, 48, 48, 48, 48, 48,252,167,169,115, 28,173, 6,135, 58,208,235,245, 74, 30,143, 23, 17, 22, 22,214,162,
+188,188,156, 94,184,112, 97,198,154, 53,107,118,220,187,119,207,226,228,228,212, 74, 36, 18,189, 57,126,252,120,213,254,253,251,
+ 73,239,222,189,107, 70,159,106,157,221,219, 96,208, 41, 5, 60,110,196,155, 93,101, 45, 50,204, 74, 58,232,205, 75, 25,125,231,
+159,219,241,227, 13,142,165,157,179,161,149, 51,159,122,115,252,248,167, 85, 63, 30,142, 33,221,187,119,179, 75,179, 18,155, 86,
+171,125, 51, 54, 54,246,233,150, 45, 91,102, 90, 44,150, 76, 0, 5, 6,131, 65,227,233,233,169, 53,155,205,153, 0,204,181,108,
+ 87,155,166,217,108, 54,103,122,122,122,106, 13, 6,131, 6, 64,129,197, 98,201,108,217,178,101,102,108,108,236,211, 90,173,246,
+ 77, 0,182,122,242,194,204,234,206,104, 50,154,140, 38,163,201,104, 50,154,255, 29,254, 16,205, 2,236,152, 84, 90, 32, 16,244,
+241,246,246,238,117,227,198, 13,219,249,243,231, 75, 88, 44,214,198,161, 67,135,238,221,183,111, 95, 87,103,103,103,117,243,230,
+205,221,126,249,229,151,112, 0,187,127,255,253,119,187,162, 79, 34, 1,175, 79, 71, 47, 69,175,232,107,196,246, 85,236,221, 18,
+ 27, 91,176,177,255,216,177,123,223,216,177,179,171,167, 74,166,238,232, 33,119, 59,114,228, 88, 56,128,221,231,207, 95,112,120,
+ 60, 13,171,213,250,139, 86,171,109, 94,245, 57, 47, 47, 47, 84,165, 82, 5,225, 65,244,169,196, 78,153, 52,154,166,135,210, 52,
+237,153,159,159,127, 11, 0,242,243,243, 59, 51,215, 17, 3, 3, 3, 3, 3, 3, 67, 45, 38, 43,186,182,207,245, 70,180,248,124,
+126, 51, 54,155, 29,156,153,153,153,118,228,200,145, 27, 93,186,116, 25,146,150,150,182,148, 16,146, 42, 22,139, 39,103,100,100,
+220,205,200,200, 48, 25, 12,134,169, 14,100,166, 25, 88,188,224,216,108, 67,218,103,191,220,188,209,174,251,160, 33,185,185,217,
+ 75,109,132,164,242,197,242,201,119,210,243,238, 94,208, 26, 77, 21, 21, 14,105, 54, 72,126,126,254,173,252,252,252, 18, 7,183,
+ 41,169, 50, 89, 12, 12, 12, 12, 12, 12, 12, 12,142,210, 80, 68,203,108,179,217,150, 27,141, 70,229,143, 63,254,152, 21, 25, 25,
+105, 4,128, 13, 27, 54,208, 47,191,252,242,153,164,164,164, 1,183,110,221, 26,226,238,238,126, 18, 0,149,156,156,108, 79,244,
+201, 76,211,182,229, 38,147, 81,249,203,175,113, 89,125,122,181, 51, 2,192,166, 47,214,210,207, 76,158,121, 38, 41,241,198,128,
+ 59, 9, 87,134,184,187,187,159,180, 89, 57, 84, 78,110, 42, 97, 78, 19, 3, 3, 3, 3, 3, 3,195, 63,152,104, 60, 90,101, 24,
+109,151,209, 50,153, 76,121, 38,147, 9, 0,138, 34, 35, 35, 31, 89,183,117,235, 86, 2,160, 28,192,158,130,130, 2, 71, 50,147,
+103, 48, 24, 0,160,168, 79,175,118,143,172,248, 46,122,205, 67, 77, 93, 89, 41,115,218, 24, 24, 24, 24, 24, 24, 24,158, 36,179,
+245, 7, 88,204,113, 97, 96, 96, 96, 96, 96, 96, 96,104, 18,147,235,250, 76,161,238,158, 3, 63, 59,240, 3,141,233,125,240, 51,
+163,201,104, 50,154,140, 38,163,201,104, 50,154,255, 57,205,134,180,127,198,147, 71,157,141,225,255,108,152,174,175,140, 38,163,
+201,104, 50,154,140, 38,163,201,104,254,219,241,192,163,195, 59,120, 84,173,224, 48,199,134,129,225,201,134,236, 1, 27, 69, 1,
+190, 32,196, 19,108,126, 14,114,174, 39, 81, 31,131,110,178,166, 38,216, 7, 34,139, 27,172,194, 60,104,226,147,155,170,201,192,
+192,240,239,195,189,199,235,163, 41, 22,123, 35, 69,104, 24, 52,137, 2,158, 33, 85,172,205, 73,251, 47,122,139, 28,212, 17,193,
+ 98,140, 22, 3,195,147, 78, 94,160, 63, 56, 88, 2, 22, 60, 64,204,247,225, 26,188, 4,184,153,208,100, 77, 30,189, 16, 54,150,
+ 23,136,249, 14,212, 1, 75,129,219, 55,153,131,253,239, 99,198,244,215,200,173,132,139, 72, 79,207, 70,171,214, 30,240, 15,236,
+129, 53,107,215, 83,204,145, 97,176,239, 95, 25, 21, 29, 49,124,130,179, 72, 44, 3, 0,208, 86, 11,182,190,221,241, 39,171,213,
+186, 29,192,126, 0,134,255,250, 33,250,203, 27,195,115,185, 92, 13, 0, 90, 40, 20,238, 67,181,208, 26, 3,195,159,128, 71,229,
+117, 70, 87, 94,119,142, 32,229,112, 56,243,197, 98,241,175, 2,129, 64, 43, 16, 8,180, 18,137,228, 87, 14,135, 51, 31,128,244,
+ 31, 83,198,125,211, 86, 12,150,109,136,201, 66, 55, 59,118,189, 88,173, 55,218,252,193,178, 14, 37, 91,219, 72,155,164,201,161,
+ 34, 43,204,180,247,183,151,244,110,229, 38,107, 16, 8,154,164, 89, 13, 39, 30,143,119, 12,246,207, 57,202,240, 39,147,150,156,
+128, 35,135, 87, 98,225, 39,147,240,117,244, 84,220,190,117,161, 73,122, 65, 64,231,206, 28,206,236, 64,160, 63, 30,180, 3,102,
+248, 55, 67,145,201, 63, 31,250, 54,239,208,174, 47,242,190, 95, 57,149, 28, 88, 18,133,181,107,215, 70, 76,154, 52,233, 91,111,
+111,239, 60, 0, 79, 49, 70,235, 47,198, 98,177,168,243,243,243,169,237,219,183,143, 80, 40, 20,247, 57, 28,206,251, 0,120,255,
+149, 3, 46,149, 74,207,201,229,114,141, 66,161,208,200,229,242, 43, 13,165,255, 75,241,119,117,117, 77,115,118,118,190, 83, 61,
+209,181,253,232, 30,126, 61, 39,126,228, 18, 60,178,111, 19,245,121, 28, 14,231,125,133, 66,113,127,251,246,237, 35,178,178,178,
+ 40,139,197,162,118, 96,251, 62, 74,165,242,214,197,139, 23,231,229,231,231,247,205,184,176,213, 53,247,226,102,215,180,223, 86,
+246,139, 61,178,110,158,147,147,226, 38,128, 62,255,136, 35, 89, 65,187,129,197, 14,191,145,163, 23,231,148, 90,220,226, 82,245,
+ 50,128,221, 15,166, 38,252,137, 41,161,221, 0,210,255, 90,166, 65,114,174,208,213,237,247, 36,163, 28, 44, 86, 56, 42, 40,247,
+ 38, 23, 56, 44,214,107, 52, 77, 15,228,241,120,111, 50, 79,168,127, 6, 2, 1, 15, 32, 4, 82,137, 16, 0, 1,171,137,214,136,
+207, 98,245, 60, 55, 98,196,194, 57,237,219,207, 8, 4,134,215, 97,182, 40, 0,111, 4, 6, 6, 30, 5,240,204, 99,220,157,207,
+ 2, 2, 2,178, 0,204,124, 92,229, 82,167, 78,157,122,132,135,135,127,212,177, 99,199,190,143, 75,243,223, 68,238,185, 13, 63,
+230,156, 89,167,206, 62,187, 94, 93,156,124,250, 13, 15, 55, 37,157,156,156,140, 97,195,134,225,139, 47,190, 16,135,132,132,236,
+ 0,224,249, 31,184,149, 66,171,254,224,163, 70, 27, 45,187,141,214, 56, 95,244,124,182, 37, 78, 61,237,139,178,241, 45,161,123,
+190, 37,206,140,245, 69,255,198,228,198,197,197, 5,125,250,244, 97,103,101,101,137,102,205,154,245,145, 80, 40, 76, 1, 48,168,
+ 49, 90, 34,145, 40, 86, 44, 22,103,112, 56,156, 71,242, 34, 22,139, 99, 37, 18, 73, 6,135,195, 25, 80, 61, 93, 38,147,157,147,
+203,229, 26,153, 76,118,165, 14, 35, 20, 43,151,203, 53, 82,169, 52,182,122, 58,135,195, 25, 32,149, 74, 51,101, 50, 89,205,244,
+254, 50,153, 44,163,102,122, 93,112,185, 92,175,140,140, 12,117,102,102,166,154,207,231,187, 85, 79, 79, 79, 79, 87,103,100,100,
+ 60,146,238, 8, 28, 14,167,191, 68, 34,201, 16,139,197,177,181,165,215,220,167,186,168,118,236,250,219,147,238,104,193, 19, 25,
+ 25,121, 38, 39, 39,199,219,201,201,233,145,137,187,157, 21, 78,131,190,217,186,254,237,145, 67, 35, 95,115, 13, 26,213,174,145,
+250,131,132, 66, 97,202,172, 89,179, 62,202,202,202, 18,117,239,222,157,205, 98, 57,244,127, 34, 98,228,200,145, 7, 52, 26, 77,
+179, 14, 29, 58,176,173, 86, 43,110, 28,156, 15,113,252,155, 16,166,108, 66,115, 81, 30,231,254, 79, 75,189, 34,251,117, 62,128,
+191,185, 49, 40,217, 19,196, 3, 69,247,161, 9,113,189,149, 85,225, 58,108,196, 83,156,171, 25, 6, 87,139,205,230, 12,176,251,
+145,175,125, 4,141,210,228, 88,122,211,132,184,253,146,202,117, 13,127,122, 6,251,100, 42,199,213, 98,179,185,128,133,190,141,
+209,172,126,249,179,217,236,183, 87,174, 92,201, 2, 48, 29, 0,255,191,100,104,194, 60,209,172,127,107,246,165, 80, 15,244,124,
+140,178, 33,149,247,187,127, 83,133,182,124,125, 20, 47, 79,137, 70,155,192,110, 77,210, 49,209,244,237,239,146,147,143, 63,223,
+186,117,212,156,246,237, 95,172,197,108, 81, 0,230, 44, 93,186,116,226,141, 27, 55, 92, 91,182,108, 57,229, 49,253,233, 95,189,
+116,233,210,119,111,220,184,225,233,235,235,187,192, 65,205, 58,203, 37,165, 82, 57,104,203,150, 45,111, 15, 27, 54,236,181, 78,
+157, 58,181,123, 28,154,255, 98,190,184,118,237,154,247,202,149, 43,223,123,249,229,151, 75, 1, 96,192,128, 1, 60, 0,221,155,
+ 92,222, 17,194, 39,132,132, 19, 66,134, 17, 66, 6, 16, 66,194, 42,223,119,169, 92,134, 17, 66, 34,106,188,118,169,220,182,106,
+125,215, 58, 52,134,213,220,174,218, 54, 53, 63, 63,242,190, 22,163, 53, 12, 15,218,106, 13,123,100, 7, 14, 31, 62, 76,170,191,
+214,100,188, 47, 62,158,209,163,153,254,214,161,157, 68,151,145, 76,138, 18,175,146,171,209,139,201,140, 46,174,250,231, 90,226,
+ 51,199,143, 23, 33,103,207,158, 37, 55,110,220, 32, 58,157,142,220,189,123,151,116,237,218,213, 32, 22,139,127, 1,224,235,136,
+152, 76, 38,211,252,242,203, 47, 36, 50, 50,178, 68, 42,149,174,168,186,185,228,114,185,230,236,217,179, 36, 50, 50,178, 68, 38,
+147,173, 6,192, 6,128,177, 99,199,106, 9, 33,196,213,213, 53,187, 54,189,145, 35, 71, 22, 17, 66,136, 66,161,168,170,106, 98,
+203,100,178,213,211,166, 77,211, 93,190,124,153, 40,149,202,170,116,150, 92, 46, 95, 49,125,250,116, 93, 92, 92, 92,245,244,122,
+113,118,118,206,176,217,108,228,208,161, 67, 68,173, 86,103, 87,187,153, 51,108, 54, 27, 57,112,224, 64,157,121,171, 47, 80, 32,
+149, 74,151, 63,255,252,243,101,169,169,169,196,197,197, 69, 83, 45,125,197,164, 73,147,202,210,211,211,137, 74,165,178, 43,143,
+ 46, 46, 46,154,115,231,206,145, 49, 99,198,148, 86, 63,166, 46, 46, 46,154,243,231,207, 87,165, 47,183,167, 32,243,244,244,156,
+162, 86,171,179,213,106,117,182,147,147,211, 34, 15, 15,143,220,188,188, 60, 66, 8, 33,173, 90,181,210, 86,143,100,169, 67, 70,
+188,181,105,207,249,139,167, 19, 10,242,218, 15,124,109,185,162,253, 72,133, 3,199,192, 87, 44, 22,255,210,183,111, 95, 67, 70,
+ 70, 6, 41, 47, 47, 39,241,241,241,228,236,217,179,228,222,189,123, 4,128, 61, 51, 12,200,164, 82,105,150,209,104,164,141, 70,
+ 35,157,151,151,103,211,106,181,182,196, 21, 30,132,124,197,125,184, 20, 31, 24, 78,114, 79, 47,161,229, 82,113, 38, 0,217,223,
+102,180,214, 7,123,145,205, 1,223,221,156,239,157,120,122,233, 96, 11, 73, 61, 73,118,190,232,106, 57,245, 86,179,251,100, 99,
+224, 15,100,115, 80,243, 70,105,110, 12,218, 25,255,161,247,237,117, 11,222,176,164,165,165,145,217,147, 6, 91, 79,204,104,150,
+ 68, 54, 5,238,105,140,102, 53,158, 29, 61,122,180, 46, 61, 61,157, 4, 7, 7,151,179,217,236,151,255, 75, 38, 43,194,159,159,
+ 21,255,237,108,122,120,136,184,224, 49,153,173, 16,181, 90,157,191,109,219, 54, 34,147,201,180,141, 53, 91,227, 70,245, 35,134,
+146, 95,200,168,168,176,122,239,145,167,159,126,154,132,135,135,147, 25, 51,102, 52,116, 47, 81,129,192,136,237,237,219, 31,160,
+199,141,179,109,111,223,254, 64, 32, 48,162,210, 96, 81, 0,222, 91,182,108, 89,156,197, 98,137,251,250,235,175,227, 70,140, 24,
+ 17, 7, 96,118, 19,143,197,154,207, 62,251,140, 88, 44, 22,242,245,215, 95,147, 17, 35, 70, 16, 0,107,155, 82, 46, 85, 69,178,
+ 66, 67, 67,223,218,191,127,255,197,219,183,111,231, 69, 69, 69, 45,111,223,190,189,162,177,154,255, 68,164, 82,169, 95,187,118,
+237,118, 4, 7, 7,167,119,232,208,193, 20, 20, 20, 84,225,239,239,159, 26, 18, 18,178, 77, 32, 16,248, 54, 82,182, 91,207,158,
+ 61,109,167, 78,157, 34,163, 71,143, 38,213, 76, 72,189,212,231, 69, 8, 33, 97,239,189,247,222,251, 0,200,123,239,189,247, 62,
+ 33,100, 88,165,159, 24, 86,253,125,205,215, 42,243, 84,245,185, 54,141,170,165, 54,205,218,126,163,198,239,160,142, 72,214,228,
+ 63,236,220,225,195,135,251, 30, 62,124,248, 84,205,157,123,170, 37,122,204,232,209,204, 96,200,203, 33, 9,139,223, 36,191,134,
+123,145,179,253,220,201,157,183, 71,147,156,111, 87,147,215, 59, 42,245,227, 90, 34,220, 81,163, 21, 23, 23, 71,226,226,226,200,
+149, 43, 87, 72, 74, 74, 10, 41, 41, 41, 33,223,127,255,189,205,197,197,197, 32, 16, 8,150, 2, 16,217, 35, 38,151,203, 53,132,
+ 16, 98, 52, 26,201,162, 69,139, 42, 42, 35, 85,110, 10,133, 66, 67, 8, 33,197,197,197,100,233,210,165, 21, 10,133, 34, 30,128,
+167, 74,165,202, 72, 78, 78, 38,110,110,110,181,154, 25,165, 82,169,185,125,251,118,149,113,106,166, 84, 42, 19, 14, 30, 60,104,
+ 38,132,144,204,204, 76,226,236,236,172, 1,224,230,226,226,114,245,240,225,195,102, 66, 8,201,206,206,174, 74,183,203,104, 25,
+ 12, 6,114,226,196,137, 71,242, 80,149,126,244,232,209, 71, 12,152, 29,184, 41, 20,138,184,239,191,255,222,100,179,217, 72, 66,
+ 66, 66,149, 73,116,115,114,114,186,178,103,207, 30,147,205,102, 35,137,137,137,118,155,193, 22, 45, 90,104, 9, 33,196,106,181,
+146, 77,155, 54, 25,171,142,105, 85,186,201,100, 34, 27, 54,108, 48,202,229,242, 56, 0,245, 70,223, 84, 42, 85,182,201,100, 34,
+197,197,197,164,107,215,174,186,179,103,207,146,210,210, 82, 66, 8, 33, 45, 90,180,208, 2, 64, 64,223,151, 63,189,120, 87, 87,
+250,210,187,235,119,251,134, 61,183,248,248,165,172,204, 45,251, 99,227, 84, 33, 35, 7,219, 19,212, 20, 8, 4, 75, 61, 60, 60,
+ 42,126,255,253,119,155,217,108, 38,233,233,233,228,202,149, 43, 15,175,177,235,215,175,219,101,180, 56, 28,206,252,139, 23, 47,
+154,109, 54, 27,157,159,159,111,211,106,181, 54,173, 86,107,173,105,180,200, 87, 92,146,127,244, 85, 18, 19, 61,211,196,227,241,
+230,255, 61,209, 44,176,201,230,128,145,100,115, 64,220,182,231, 85,249,101, 87,118, 17,242,211, 76,146,244,105, 75, 50,127,176,
+172,140,222, 28, 16, 71, 54, 7,142, 35, 31,247,229, 56,164, 25, 29, 52,156,108, 14,136,251,236, 41,159,130,171,113,151,201,169,
+ 83,167,200,134,213,203,200,140,136,102,229,244,230,128, 56,178, 49,104,140, 35,154,213, 17, 8, 4,119,207,156, 57, 67, 78,159,
+ 62, 77, 22, 44, 88, 64,196, 98,113,250,227,136,234,145,141,254, 62,228, 75,255,190,100,107, 27, 15,242, 91,223,127, 92, 7,159,
+ 48, 79, 52, 27,232,207,207,204,191,186,159,144,194,123, 36,119, 69, 48, 25, 28,192,109,170,217, 10, 81,171,213,121,169,169,169,
+ 36, 55, 55,151,172, 90,181,138,200,229,242, 70,153,173,113,163,250, 17, 67,241,207,245, 26,173,145, 35, 71,146,207, 63,255,156,
+ 88, 44, 22,210,173, 91, 55,123,254,180,252,193,108, 5, 0, 35, 1,188,191,124,249,242,135, 38,107,253,250,245,113,215,175, 95,
+143,243,246,246, 62,210,132, 99,177,118,249,242,229, 15, 77,214,250,245,235,201,245,235,215,137,143,143, 79, 70, 83,202,165,129,
+ 3, 7,126,154,146,146, 82, 58,119,238,220,221,125,250,244, 89,124,245,234,213,204,152,152,152,184,208,208,208,193,141,213,124,
+ 12, 81, 29, 78,101,100,135, 79, 8,225, 18, 66,170,204, 43, 7, 0,183, 42,160, 96, 15,207, 63,255,188,184, 71,143, 30,113, 19,
+ 38, 76,208,111,219,182,141,164,166,166,146,248,248,120,178,124,249,114,242,209, 71, 31,145,175,190,250,138,140, 25, 51,166,188,
+107,215,174, 23,199,141, 27, 39,116, 32,155,193,190,190,190, 37, 7, 14, 28, 32, 59,119,238, 36, 60, 30, 47,198,222, 13,235,243,
+ 34,117,153,169,186, 12, 86,205,117,245, 24,177,122, 13,155, 29,191,247, 71, 83, 85, 51, 18, 82,237,253,111, 81, 81, 81,125,255,
+240,240, 33,248,100,242,172, 79,133, 41,219, 86, 65,243,253, 23, 96, 23,107,192, 45, 43,128,241, 76, 12, 44,103, 14, 98, 98,247,
+238, 34, 17, 69, 45,116,244,130,225,243,249,224,243,249,224,241,120,208,235,245,200,206,206, 70,175, 94,189, 88, 87,174, 92, 17,
+ 78,153, 50,101,166, 72, 36, 74, 7, 48,170,193,187,153,122, 16,145, 62,119,238, 28, 94,125,245, 85,193,142, 29, 59, 58,184,186,
+186, 94,179,217,108,124, 0, 72, 76, 76,196,248,241,227, 5,187,118,237,106,235,233,233,121,197,108, 54,139, 5, 2, 1,216,108,
+118,157,122,124, 62, 31, 22,139, 69,208,166, 77,155,248,107,215,174,133, 68, 69, 69,113,211,210,210,144,156,156, 12,139,197,194,
+247,247,247,191,126,229,202,149, 14,195,134, 13,227,102,100,100, 32, 45, 45,237, 97, 62,236,201,175,201,100,130, 64, 32, 64,245,
+ 42, 45,138,162, 96, 52, 26,193,231,243,237,214,226,112, 56,253, 3, 3, 3,175, 95,187,118, 45,116,228,200,145,188,203,151, 47,
+ 35, 51, 51, 19, 54,155,141, 31, 20, 20,116,253,218,181,107, 29, 71,140, 24,193,139,143,143,135, 70,163,129,189, 85,104, 85,223,
+187,118,237, 26, 38, 76,152,192, 63,118,236, 88, 71, 15, 15,143,120,171,213,202, 7,128,235,215,175, 99,252,248,241,252,227,199,
+143,135, 54,111,222, 60,190,129,170, 68, 54, 0, 88, 44, 22, 76,153, 50, 69, 34,151,203,145,145,145, 1,154,166, 97,179,217, 0,
+ 0, 5, 69, 5,215,175, 93, 79, 72,156,248,236, 83,125, 13,102,163,241,252,165,216, 91,173, 90,248,120, 81, 20,105,209, 64, 86,
+ 71, 73, 36,146,244, 21, 43, 86,188,149,154,154, 42, 8, 12, 12,100, 37, 37, 37,161,172,172, 12, 60, 30,239,225, 53,102,239,126,
+243,249,252,126,193,193,193,156,138,138, 10,208, 52, 13, 0,132,197,170,189,197,138,176,248, 12,130,220,172, 92,145, 72,212,239,
+111,121,122,151, 6,187,128,198,192,180, 60,147, 64,224,228, 37,147,122,248, 3,233,167,209,210, 85, 0, 54,139, 45,188,156,172,
+151, 0,100, 32,188,243, 93, 28,211,164, 7, 38,107, 77, 2,139,115, 91,169,167,151, 55, 10, 10, 10,208,188, 85, 32, 42,248,174,
+252,115,247,202,165,160, 28,212,252, 63,189,219,180,105,227,238,231,231,135,252,252,124,132,134,134, 66,169, 84, 42, 1, 12,108,
+244, 67,231,107, 31, 1, 74,209, 19, 96,173,128,141, 90, 0, 11,103, 9,238,229,133,146,205,161,220,127,146,201,146, 75,249, 23,
+118,125,247,125, 51, 23,239, 32, 32,230, 37,184, 57, 9,176,245,181, 80,103, 87,133,224, 64, 35,205, 86,136,155,155,219,201,139,
+ 23, 47,170,132, 66, 33,174, 92,185,130,224,224, 96,172, 90,181,202, 85,169, 84,158,110, 92,100,139,128, 80,117,155,172, 62,125,
+250, 96,250,244,233,216,177, 99, 7,156,157,157, 49, 97,194,132,134,204, 22, 73, 4, 14,125, 22, 31,255,245,142,251,247, 15, 63,
+223,186,117,212, 4,127,255, 69, 83,159,121,230,229, 55,222,120, 3,203,150, 45,195,129, 3, 7,208,179,103, 79, 76,158, 60,217,
+146,158,158,190,189,177, 85, 85, 43, 86,172,152, 49,115,230,204,154,154,230,180,180,180,207,154, 84, 46, 21, 20, 92,143,143,143,
+ 79,124,246,217,103,251, 86, 84, 84, 24, 47, 93,186,116,203,215,215,215, 11, 64,139,198,106, 54,193, 96, 81,132, 16, 33, 0,113,
+229, 34, 1, 32,222,181,107,151, 98,228,200,145,242,202, 52, 81,229,210, 96,245,126,112,112,176,215,221,187,119,179,222,126,251,
+237,208, 29, 59,118,136,196, 98, 49,138,139,139,241,229,151, 95,226,253,247,223, 7, 69, 81, 32,132,224,171,175,190, 18,191,248,
+226,139, 97,247,239,223,207,242,241,241,177,167, 73,139, 64, 42,149,238, 89,180,104,145,156,166,105,204,153, 51, 39,223,108, 54,
+ 79,175, 92, 55,215,201,201,233, 2, 30, 24,238,250,168,213,139, 84,123, 86, 30,174,113,108,162,106,166,213, 92, 71, 8,137,170,
+ 79,195,193,115, 81,219,239,197,212,103,182,170, 63,129,250,213,234, 34,129,246,238,190, 1, 40,249,105, 15, 68, 28, 10, 34,118,
+229,194,161,192, 74,186,142,230, 66, 46, 44,132,132, 52,214,104, 85, 45, 92, 46, 23,122,189, 30, 54,155, 13,239,191,255,190,224,
+196,137, 19, 46, 44, 22,235,135,134,116,170, 27,166, 59,119,238, 32, 40, 40,136, 58,116,232,144,219,244,233,211, 69, 85,191, 83,
+ 82, 82, 2, 63, 63, 63,234,232,209,163,234, 15, 63,252, 80, 90,159,153,161, 40, 10, 60, 30, 15, 51,103,206, 20, 93,186,116,201,
+217,211,211, 19, 73, 73, 73, 40, 44, 44,132, 84, 42,197,204,153, 51, 69, 23, 47, 94,116,245,244,244, 68,106,106, 42, 74, 74, 74,
+ 32,149, 74, 29, 54, 90, 60, 30,239,145,109, 40,138,130,217,108,118,200, 24, 40, 20,138,157,113,113,113,174, 10,133, 2,241,241,
+241,176, 90,173, 80, 40, 20,152, 49, 99,134, 40, 46, 46,206,213,201,201, 9,137,137,137, 32,132, 64, 46,151, 59,148, 71, 0,160,
+105, 26,137,137,137,104,209,162, 5, 78,159, 62,173,158, 58,117,170,176, 42,253,222,189,123,240,242,242,194,233,211,167,213, 18,
+137,100,103, 93, 90, 52, 77, 35, 39, 39, 7, 55,110,220, 64, 82, 82, 18,242,242,242,144,159,159,143,178,178, 50, 88,173, 86, 0,
+128,184,172, 52,102,215,238, 67,215, 68, 34,145, 56,216,191,141,247,245,132,155, 90,145, 72, 36,246,241,246,246, 7, 62,102,213,
+ 99, 8,127, 72, 75, 75,115,121,241,197, 23,121,185,185,185, 40, 42, 42, 2,135,195,249,195,181,197,231,219,215, 20,200,106,181,
+ 6, 9,133, 66,202,108, 54, 63,140,128,241,249,124,188,181, 83,143,224,249,120,100,121,102,181, 22,196,102,129,201,100, 10,250,
+203,163, 89, 0, 5,202,212, 6, 20, 21,122, 33,169,220,185,119,212,179, 60, 36, 31, 3,104, 11,192,226,160, 95,123, 47,206,129,
+235,229,110, 32,104, 15, 35, 2, 9,105,184,231, 23, 1, 40,192,236, 7, 80,157, 79,220,181,186,244, 28,253, 26, 47, 43, 43, 11,
+ 60, 30, 15, 2,129, 0,161,253,199,114,118, 93,179,184,131, 66, 7,152, 17, 96,143,230, 35, 97, 71,145,104,222, 71, 31,125, 36,
+169,174,249,242,203, 47, 75, 20, 10,197, 71,141, 54, 89,229,226,238,176,146,153, 55,178,244, 45, 22,197,228, 6,221,215, 26, 2,
+ 64,200,219,128,165,227, 99, 48, 91,253, 4, 2, 65, 50,128, 94, 77, 50, 89, 50,254,249,239,190,251,190,153,115,243, 7, 38, 11,
+214, 10,128, 43,130,187,171, 19,182,190, 21,238,236,234, 36,114,212,108,133,184,185,185,253,114,225,194, 5,149, 80, 40, 68, 92,
+ 92, 28,120, 60, 30,132, 66, 33,218,181,107,135,205,155, 55,187, 58, 59, 59, 59,108,182, 8, 72,173, 49,223, 81,163, 70,145, 62,
+125,250, 96,218,180,105,216,190,125, 59, 76, 38, 19, 22, 45, 90,132,180,180, 52,187,100, 19,129, 67, 75,227,227,183, 45,185,113,
+227,206,123, 33, 33,129,163, 36, 18,231,105, 19, 38, 40, 62,252,240,195,195, 7, 15, 30,252,122,216,176, 97,249,151, 46, 93,250,
+ 28,192, 30, 7, 15, 47, 5, 96,253,202,149, 43,167, 85, 25,183, 15, 63,252,240,171,131, 7, 15, 46, 25, 54,108, 88,206,165, 75,
+151,222, 6,176,190, 41,229, 18, 77,211, 49, 63,252,240,195, 53,145, 72, 36, 14, 8, 8,240, 78, 72, 72,208,138, 68, 34,177,183,
+183,183,127,223,190,125, 89,141,209,108, 12,106,181,122,192,133, 11, 23,130,241,160,211,152,160,202,104, 37, 36, 36, 56,149,150,
+150, 58, 73,165, 82, 39, 15, 15, 15, 89,149,217, 26, 61,122,180, 19,135,195,169,247,186,213,233,116, 7,231,206,157,171, 24, 61,
+122,116,213,103,156, 57,115, 6,219,183,111,135, 68, 34,121,228,187, 35, 70,140,192,171,175,190,170, 52,153, 76, 63,216,145,221,
+ 73, 83,166, 76, 9,112,115,115,195,188,121,243,140, 89, 89, 89, 3, 0,164, 1, 80, 68, 68, 68,124,154,144,144,208, 53, 44, 44,
+108, 55,128, 78,245,221,123,181,121,145,234, 70,199,158,180,198,126,223, 94,179, 85, 35,169,206, 49,180, 30, 49, 90, 81, 81, 81,
+167, 80, 71, 79, 42,115,161, 6, 2,216, 32, 98, 83, 16,179,171,153, 45,208,224,148,104, 65, 53,162,151, 74,109, 15, 67, 62,159,
+ 15, 54,155, 13,147,201, 4,123, 39,170,174, 50, 5,114,185, 28, 82,169, 20, 6,131, 1, 86,171, 21, 66,161,176,202,140, 64, 46,
+151,131,203,229,130,203,229, 66, 40, 20,254, 33,154, 84, 51,154,195,227,241, 32,145, 72,144,147,147,131,180,180, 52,208, 52, 13,
+169, 84, 10,137, 68, 2, 62,159,143,236,236,108,100,103,103,131, 16, 2,137, 68, 2,137, 68, 2, 71, 26, 92,219,108,182, 90, 31,
+254, 22,139,197,161,136,150,213,106,197,173, 91,183,144,158,158, 14,161, 80,248,112, 95, 5, 2, 1,238,221,187,135,220,220, 92,
+136,197, 98,200,229,114, 40, 20, 10,187,117,171,246, 69, 38,147, 65, 36, 18,161,168,168, 8,122,189,254,225, 49,149,203,229,144,
+ 72, 36, 40, 41, 41,129, 86,171,173,119,223,109, 54, 27,178,179,179,145,151,151,135,140,140, 12,228,231,231, 63, 44,128, 42,163,
+ 70, 77, 11,236,148,150,162,160,160,224, 97, 36,178,174,197, 30,104,154, 70, 89, 89, 25, 46, 92,184, 64,209, 52,141,226,226, 98,
+ 58, 47, 55,215,246,122, 54, 31, 7, 62,222, 72,190, 63,118,181, 98,215,145, 56,195,190, 95,110, 24,214,239,187,110, 16,118, 93,
+ 96,197,223,193,134, 16, 5, 44,220,200,124,157, 69,144,103,230, 41,220, 66, 34,128,228,163, 0,139, 3, 8,149,232,214,182, 37,
+210,138,108,146,219, 26,147, 16, 20, 6, 97,189,191,210, 46, 77, 27,119, 96, 94,153, 69,144,106,118,149, 7,181,239, 4,141, 70,
+ 3,129, 64, 0,129, 64,128,206, 61, 35,144, 92, 96, 19,223,204, 50,136, 65, 16,105,151,230,255,105, 37,149, 74,187,247,234,213,
+139,170,174, 57,116,232, 80, 80, 20,213, 14, 64,160, 67,133,220,218, 86,124,152,197,221,192, 33, 51,111,230,232, 61, 15, 36, 84,
+248, 15, 31, 53,214,121,205,207,218,160, 91,185, 70, 95, 16,203, 44, 16,115,167, 38,152,173,190, 50,153,236,240,186,117,235,124,
+133, 66,225, 81, 0,189, 27, 35, 34, 21,177, 55,205,155,246,108, 51,101,149,201,178,232, 1,142, 8,224,138, 0,142, 8,238,106,
+ 21, 22,190, 58,208, 89, 44,228,238,115,192,176,238, 90,191,126,189,107, 77,147, 85,181,132,134,134, 98,254,252,249,174,206,206,
+206, 59,237,209, 91,177,124, 25, 41, 46, 41, 1, 8, 80, 90,170,195,138,229,203,138,170,214,141, 30, 61,154,244,238,221, 27,211,
+166, 77,195,146, 37, 75,112,228,200, 17,116,235,214, 13,147, 39, 79, 70, 88, 88, 88, 67,210,145, 10,133, 98, 71, 68, 68,196,133,
+108,153,236,213,156, 78,157,248,191, 40, 20, 37, 3, 74, 74, 20, 62, 9, 9,230, 0,224, 58,128, 13,153,153,153,131, 29, 48, 89,
+207,200,229,242,184, 1, 3, 6,152,101, 50, 89,250,170, 85,171, 94,159, 62,125, 58,150, 45, 91,134,185,115,231,126, 9,224, 21,
+ 0, 31,100,102,102,122,214,103,178,254,172,114,233,207, 42,235,108, 54, 91,198,158, 61,123,194,204,102,179, 87,101,245,160,160,
+184,184, 88, 94, 88, 88, 40, 51,155,205, 18,154,166, 37, 78, 78, 78, 82, 0,226,137, 19, 39,114,110,222,188, 25,100,181, 90,179,
+234,211,204,205,205,125,110,206,156, 57,249,249,249,249, 0,128,118,237,218,161,184,184, 24,179,103,207,198,155,111, 62,232, 16,
+220,177, 99, 71, 16, 66,160,209,104,176, 98,197, 10, 77,110,110,238, 11,118,100,183,117,155, 54,109,144,144,144,128, 91,183,110,
+253, 12,128,198,131,118,172, 37, 87,175, 94,189,150,151,151,135,157, 59,119,242,154, 53,107,118, 16,117, 12,241, 82,159, 23,105,
+ 12, 20, 69,197, 52,102,187,170,200, 85,109, 17,177, 58,168, 63,162, 21, 21, 21, 69, 85,127,125, 36, 98, 68, 33, 62, 61,246, 52,
+156, 67, 58, 61, 18,205, 18,179, 41,136,228, 10, 36,103,164,129, 7,234,198,227, 50, 90, 69, 69, 69,120,253,245,215, 13,207, 61,
+247, 92, 1, 77,211, 99,237, 53, 5, 10,133, 2, 10,133, 2, 55,111,222, 36, 99,198,140,209,172, 90,181,202, 80,221,104,221,185,
+115,135, 68, 70, 70,106, 63,250,232, 35, 93,125, 70,171, 42,162,181,116,233, 82, 67,191,126,253,242,110,220,184, 65,170,204,148,
+ 84, 42,197,138, 21, 43, 12,225,225,225,154,203,151, 47,147,170, 52, 71, 34, 90, 44, 22,235,161,209,170,190, 13,139,197, 2, 77,
+211, 14, 25,173,242,242,242,231,134, 13, 27,166, 73, 76, 76, 36, 85,251,169, 80, 40,176,106,213, 42,195,192,129, 3, 53, 55,110,
+220, 32, 85,105,114,185,220,110, 51, 88,245,251, 50,153, 12,114,185, 28, 55,111,222, 36,145,145,145,154,181,107,215, 86, 84, 79,
+191,117,235, 22, 25, 49, 98,132,166,172,172,236,185,250,204, 75, 85,117,158,213,106, 69, 69, 69, 5,242,243,243,145,145,145,241,
+ 48,156,110,144,200, 7, 63,251,244,240, 14, 6,131, 65,127,243,206,221,244,118,109,131,213, 6,131, 65,159,150,158,126, 7,248,
+152,174, 71,123,108, 72, 72, 72,193,235,175,191,110, 40, 42, 42,106,178,209,226,243,249,137, 28, 14,135,244,238,221,155,152, 76,
+ 38,146,145,145, 97,201, 47, 42,178, 6, 46, 94, 76,110,188,245, 22, 37,138,141, 21, 72,165, 82,170, 82,147,149,148,148, 68,139,
+ 68,162,196,191,220,104,177,104,119, 80,164,215,239,119,117, 78, 3,135,143,231, 83,185,151, 0,179, 14, 16, 40, 1,129, 18, 28,
+137, 11,134,244,238,200,222,118,161,212, 29,132,238, 1,158,192,171, 65, 77, 46,113, 3,232,222, 63,221,169, 80,246, 26, 55,131,
+ 95, 88, 88, 8, 54,155,253,208, 20,137, 37, 18, 12, 24, 53,145,245,213, 37,163, 59, 64,122,130, 98,123, 57,112,175,191, 59,111,
+222, 60, 94, 81, 81, 17, 88, 44,214,255, 53,197, 98, 76,157, 58, 85, 32,151,203,231,218, 93,248,237, 9,226,129, 43,232, 6,144,
+ 55,111,231, 86,120, 30,188,110, 8,152,181,116,171, 40,164, 99, 24,166,244, 83,139,150,198,104, 67,174,101, 24, 90, 2,182,183,
+ 96, 53,117,110,132,217,234, 45,147,201, 98, 98, 99, 99,197, 67,135, 14,197,138, 21, 43, 36, 34,145,232,104, 99, 10,254,114,157,
+109,250, 39,107,191,209,196,127, 62, 8, 48,151, 63, 48, 88,213, 22,173,142,198,252,173, 39, 75, 44, 22,242,172,189,154, 6,131,
+ 97,210, 43,175,188, 82,176,111,223,190, 63,152, 44,161, 80,136,148,148, 20, 44, 90,180,168,176,176,176,176,193,135,226,170,149,
+ 43,226, 18,174,253,138,175,190,252, 4, 0,193,186, 85,175,225,252,239,223, 57,245,235,219,135,180,104,209,130,132,133,133,225,
+245,215, 95,199,194,133, 11,113,251,246,109,168, 84, 42,188,246,218,107,232,219,183, 47, 86,174, 92, 89, 95, 33, 21, 57,125,250,
+244, 69,153,153,153, 1, 63,253,244, 19, 39, 47, 47, 79,189,114,203,150,146,189, 37, 37,133, 75, 18, 18,110,127,208,182,109,155,
+247,218,183,127,161,158,161, 31,106, 53, 89,211,166, 77,219,149,153,153, 25,250,243,207, 63,115,243,242,242,188,166, 77,155,134,
+229,203,151, 99,238,220,185,155, 1, 76,129,125, 29, 94,236, 46,151,216,108,246,224,177, 99,199,118, 48, 24, 12,250,219,183,111,
+167,183,109,219, 86,109, 48, 24,244,233,233,233,119, 78,157, 58, 69, 55, 70,179, 49, 20, 20, 20,220,223,185,115,231,157, 84, 3,
+ 53,104, 0, 0, 32, 0, 73, 68, 65, 84, 25, 51,102,132,102,102,102, 6, 1,112, 41, 43, 43,147,148,149,149, 9, 76, 38,147, 72,
+169, 84, 42, 59,118,236,168,154, 60,121,178,244,234,213,171, 65,153,153,153,186,202, 40, 82,157,152,205,230,219, 69, 69, 69, 81,
+131, 6, 13, 42, 46, 42, 42, 66,251,246,237, 49,124,248,112,184,187,187,195,211,211, 19, 35, 71,142,132,191,191, 63, 10, 10, 10,
+240,236,179,207, 22,230,229,229, 13, 2,144,100, 71,118,239,231,230,230,162, 71,143, 30,248,228,147, 79,162,158,122,234,169, 27,
+189,123,247, 46,109,219,182,173,222,203,203, 43,112,205,154, 53,104,214,172, 25,246,236,217,227, 33, 16, 8,118,214, 98,178,234,
+244, 34, 0,242, 42, 13,143,169,198,107, 94, 3,235,236,221,182,214,247,118,124,175,166,217,170,190,252,161,234,176,246, 19, 2,
+204,223,190,103, 91, 5,223,219, 15,138,128, 14, 16, 11,133, 16,241,249, 16, 41, 93, 96,164,105,108, 73,201,213,151, 19, 50,215,
+209,139,167,230,131,144,162, 40,124,241,197, 23,214,238,221,187, 87,156, 60,121,114,157,193, 96,240,198,131, 81,101,237, 54, 5,
+107,215,174,213,207,156, 57,243,154, 86,171,237, 32, 20, 10, 77, 85,233,235,214,173,211, 79,156, 56, 49, 33, 51, 51, 51, 84, 44,
+ 22,235,235,106,159, 85,221,104, 9, 4, 2,163, 86,171, 13,123,249,229,151, 19, 55,108,216, 80, 46, 22,139, 33,145, 72, 32, 16,
+ 8, 76, 90,173,182,195,235,175,191,126,109,249,242,229,122,145, 72, 4,137, 68,226, 80,181, 28, 33,228, 15,134,170,122,186,189,
+ 88,173,214,147, 90,173,182,195,204,153, 51,175,174, 89,179,166,188,202, 0, 85,207,227,202,149, 43,245, 82,169,212,161,136, 86,
+213,247, 36, 18, 9, 86,175, 94,173,159, 49, 99,198, 53,173, 86,219, 65, 32, 16,152,170,165,151, 79,159, 62,253,170, 86,171,237,
+ 96,181, 90, 79,214,243,111,204, 86, 90, 90, 10, 14,135,131,132,132, 4, 35,143,199, 3,139,197,194,189,123,247, 30, 22, 62,206,
+206,206,193, 29,218,181, 13,252,102,215,158, 83, 34,158, 64,208, 61,172,115, 80, 82,106, 90, 38, 33, 84,106, 3, 89,221,111, 48,
+ 24,188, 79,158, 60,185,174,123,247,238, 21, 95,124,241,133,181,174,200,150, 61, 24,141,198, 83, 87,174, 92,177, 8,133, 66, 42,
+ 39, 39,199,202,102,179, 97,179,217,136, 49, 44,204,216,110,205, 26,114,243,189,247, 40,185, 68,194,225,241,120, 16,139,197,212,
+177, 99,199, 76,122,189,254,212, 95,111,180, 32, 6, 5,209, 93,173, 81, 38,100, 89, 41,220,217,255,192,100, 9,157, 0,161, 18,
+ 16, 42,209,172,153, 23, 46,165,232,101, 96,129, 15,155, 29, 99,136, 17, 34, 1, 5,113,130, 6, 50, 46, 95, 68,229,230,230, 62,
+ 52, 68, 85,139,175, 95, 16,174,164,233,164,160,136, 0,108, 56, 50, 4, 73,148,139,139, 11, 39, 39, 39,231, 15,154,193,193,193,
+108,139,197, 98,255,208, 46,217, 54, 15,128,158,118, 39,183,194,227,199,107,229, 1,111, 45,249, 74, 36,178, 21, 3,177,107, 17,
+210,202, 19,111,141,235,200,255,240, 96, 94,200,229, 84,125, 43,176,201, 20,208, 58, 87, 7,242,217, 75, 38,147, 29,189,124,249,
+178, 88, 38,147, 33, 41, 41, 9, 97, 97, 97,136,142,142, 22,139,197,226, 35, 0, 28,106,143,119, 81,131, 52, 93,153,173,251,187,
+123,210,115,227,115,172,143,152,172,188,114,130, 87, 62, 59, 88, 92, 84, 90, 49,246, 66, 70,221,247, 79, 45, 92, 45, 46, 46,142,
+156, 59,119,110, 65, 94, 94,222, 35, 38, 43, 45, 45,173,234,161,216, 15, 64,131,127,126,127,251,245,120,232,226,133, 51,113, 57,
+246, 6,134, 68,189,137, 43,241,247,241,193,156, 81,112,146,139,112,242,228, 73,140, 30, 61, 26,159,124,242, 9,238,221,187,135,
+239,191,255,158,138,142,142,166, 46, 92,184, 64,125,246,217,103, 84, 3, 77, 26, 38, 44, 89,178, 4,151, 47, 95,198,208,161, 67,
+113,250,244,105, 20, 22, 22,226,187,163, 71,239,238,188,123,247,131,170, 54, 91,117, 12,253, 80, 43,114,185,124,214,146, 37, 75,
+ 16, 27, 27,251, 80,179,160,160, 0, 75,150, 44,201, 4,240,154, 35, 38,203,145,114,169,125,251,246,129,187,118,237, 58, 37, 20,
+ 10, 5, 97, 97, 97, 65, 41, 41, 41,153, 0, 82, 27,161, 89,218,148,154,170,252,252,252,115,209,209,209, 23,250,247,239, 47,158,
+ 52,105,146,235,129, 3, 7, 92,244,122,189,167, 64, 32, 80,155, 76, 38,254,173, 91,183,216,123,247,238,117,191,121,243,102, 74,
+ 69, 69,197, 37,123,142,135, 86,171,189,116,251,246,237, 65,237,219,183,191,181,110,221,186, 76, 15, 15, 15,122,242,228,201,120,
+229,149, 87,224,234,234,106, 91,189,122,117,122,239,222,189, 19,238,223,191, 31,161,215,235,175,219,153,215,175, 23, 47, 94,124,
+118,215,174, 93, 24, 62,124, 56, 62,251,236, 51,124,247,221,119,248,245,215, 95, 69,191,255,254, 59, 63, 58, 58, 26, 60, 30, 15,
+221,186,117, 67,100,100,228,128,202,234, 78,123,159, 75,151, 41,138,138,161, 40,234,231, 26,175,151,235, 91,231,192,182,117,189,
+175,247,123, 53,178, 25, 93, 99,177,159, 9,173,240,241,212,182, 50,253,185,231,187,145,220,201,189,136,102,124, 16, 57,211,215,
+153,188,220,154, 42,159,212,200,225, 29, 12, 6,195,195,101,223,190,125,196,221,221,189, 92, 38,147, 57, 60,188,131,187,187,187,
+166,180,180,148,116,233,210,165,208,213,213,245,225, 80, 4, 30, 30, 30,154,242,242,114,210,173, 91,183, 66,181, 90,253,112,120,
+ 7, 47, 47,175, 12, 66, 8,241,241,241,201,174, 75,207,106,181, 18,119,119,247,170, 30,122, 92,103,103,231,141, 93,187,118, 45,
+212,104, 52,196,195,195,227,225,208, 9,174,174,174, 43,194,194,194,106,166, 55,148,223,140,204,204, 76,146,153,153, 73,154, 55,
+111,158, 93, 61, 61, 45, 45,141,164,165,165, 17, 47, 47, 47,135,135,119,112,117,117, 93, 94, 75, 94, 26,149, 71,111,111,111,141,
+193, 96, 32, 61,122,244,120,228,152,122,123,123,107, 42, 42, 42,170,210,237, 26,222, 65, 36, 18, 77, 17, 10,133,217, 66,161, 48,
+ 91, 32, 16, 44,106,209,162,133,118,247,238,221,100,245,234,213, 85, 93,210,225, 26, 60,162,187, 95,143, 23, 62,112, 13, 30, 57,
+171, 41,195, 59,200,100,178, 95,220,221,221,203,247,237,219,247,200,245,101, 48, 24,236, 30,222, 65, 36, 18,101,234,116, 58, 90,
+163,209, 88,206,158, 61,171,143,141,141,213, 39, 36, 36,232, 83, 82, 82, 12, 5, 90,173, 89,163,209, 24, 74, 74, 74,140,215,174,
+ 93, 51,138,197,127,207,240, 14, 36,218,223,143,108, 12, 60,120,255, 19,223,155, 51,251,136, 43,174, 47,236, 64,200, 15,163, 9,
+ 57,242, 10, 33, 39,223, 37,151, 54, 79, 38, 61,124, 5,182,179,179,155,223, 33,155, 2,126,180,103, 72, 6, 18,221,206,143,108,
+ 12, 60,114,119,129,239,205, 73,189, 61, 43,182,108, 88, 77, 46, 94,188, 72, 18, 18, 18, 72, 82, 82, 18, 57,178,127, 55,233,209,
+ 74,252, 64,115, 99,224, 65, 7,135,121,232, 41, 16, 8,116,171, 86,173, 34, 23, 46, 92,120,168,121,240,224, 65, 34, 22,139,245,
+128,125,189,150, 9, 64,145,141,193,163,172, 27, 2,126,255,112,160,180,172,224,240,187,132, 92,223, 70, 72,116, 8, 33, 95,119,
+ 37,100,247, 48, 66, 14,189, 64, 46,172, 30, 71,122,250,242, 44,100, 83,192,105,178, 57,216,238,198,246, 92, 46,183,116,223,190,
+125, 36, 59, 59,155,156, 62,125,154,196,198,198,146,196,196, 68,146,158,158, 78, 98, 98, 98, 8,151,203,173, 64, 35,166, 45,235,
+234, 6,159,136, 54,188,156,107, 75,123, 18,114,224, 89,146,183,115, 2,137,106, 43, 43,236,214,188, 73,227,209,117,116,113,113,
+201,143,137,137, 33, 41, 41, 41,228,212,169, 83, 68,173, 86,231, 3,176,187,189,108,212,144,222,132,152,174,145,240, 62,109, 73,
+251,246,109, 73,223,158,109, 72,214,253,181, 36,172, 83, 11,178,113,227, 70,162,209,104, 72,139, 22, 45,136,163, 25,139,136,136,
+184, 72, 8,137, 27, 58,116,104, 28,128, 99, 17, 17, 17,113,201,201,201,113, 97, 97, 97, 23, 80,255,208, 15,117, 50, 96,192, 0,
+ 51, 33,132, 12, 29, 58,148, 0,200,142,136,136, 32,201,201,201, 36, 44, 44,204,212,152,131,103, 79,185, 20, 26, 26,218,189,127,
+255,254, 31,132,134,134,206,178,103,120,135, 6, 52, 31,215, 32,212,108, 60, 24,252, 51, 24, 64,231,202, 37,168, 50,141,221, 4,
+205, 23,184, 92,238, 22,103,103,231, 95,149, 74,229, 73, 54,155, 29, 13,224,121, 52,110,124, 51, 86,101,132,241,132,171,171,235,
+189,246,237,219, 27, 6, 13, 26, 68,134, 12, 25, 66,166, 77,155, 70,104,154, 38,187,119,239, 38,159,124,242, 9,105,237,226, 98,
+ 93, 13,228,111, 2, 94, 4,195,131, 1, 75, 95,108, 69,157,122,174, 37,202,158,109, 9,221, 75,173, 41,123, 6, 44,141,168,203,
+104,209, 52, 77,238,220,185, 67,194,195,195,203, 37, 18, 73, 22,236, 31,176,244, 17, 77,149, 74, 21,171, 86,171,255, 48,136,102,
+181,244, 71, 6, 44, 85,171,213,231, 60, 60, 60, 52,174,174,174, 87,106,211, 84,169, 84,177, 30, 30, 30, 26,149, 74,245,200,224,
+158,108, 54,123,168, 74,165,202,170,153,206,225,112,250,171,213,234,140,154,233,117,236, 59,220,221,221, 51,178,179,179, 73, 94,
+ 94, 30,241,246,246,206,174,105,192,114,115,115, 31, 49, 96,246,104, 54,148,151,122,242, 88,171,166, 29,199,180, 49,231,189, 10,
+255,102,205,154,105, 87,174, 92, 73,164, 82,233, 35, 93,158, 3,250,188, 52,239,226, 93, 93,233, 43,115, 54,238,174,101,192, 82,
+123, 7, 7, 29, 36,145, 72,178,194,195,195,203,239,220,185, 67,104,154, 38, 52, 77,215,101,180,106,211, 28,220,185,115,231,130,
+252,252,124, 91, 89, 89,153, 53, 35, 35,195,152,156,156,108, 88,184,112,161, 57, 47, 47,175, 66,167,211,153,226,227,227,141, 30,
+ 30, 30,121, 0, 6, 59,122,142, 26, 73, 68,205,234, 51,178, 57,168, 39,217, 20, 20,147,248,145,207,173, 23,186, 74,140,113, 43,
+135, 18,114,242, 93,114, 97,227, 43,164,187, 47,255,129, 33,218, 28,120,148,124,229,223,135,172,109,197,183, 75,115, 75,235,222,
+100,115,224,209,155,243,125,110,141,238,228,106,218,181,109, 51,185,119,239, 30, 57,184,119, 39,233,214,178,210,100,109, 10, 58,
+ 65, 54, 6,133,219,163, 89,155,217,218,186,117, 43,185,119,239, 30,249,241,199, 31,237, 53, 89, 17,181, 25,173,247, 35,164,197,
+175,116, 21, 26,159,237,200, 55,141, 12,225,153, 35,253,120,214, 30, 62, 28, 91, 7, 15, 22, 29,228, 10, 18, 25, 32, 50,146, 77,
+ 1,167,201,166,160, 65,246,230,147,207,231,167,163,218,152, 58, 53, 23,129, 64,144, 87,143,209,138,104,208,108,249, 11,114,126,
+249,164, 63, 25,222, 94, 86, 96,167,201,106,232, 90,234,168, 82,169,242,191,254,250,107,226,230,230,150,103,167,201,122,168, 57,
+ 34, 42,146,164,221, 63, 66,126,220,189,132,132,247, 9, 34, 59,182,206, 36, 23, 79,127, 68,134, 13, 9, 39, 17, 17, 17, 36, 63,
+ 63,159,244,239,223,159, 56,154, 79,133, 66,177, 67,167,211,197, 29, 63,126, 60, 46, 34, 34, 34,110,199,142, 29,113,103,206,156,
+137, 19,139,197, 59,170,130, 19, 53,205, 86,208, 31,203,255,136, 26, 17,173,184,178,178, 50,114,252,248,113, 18, 17, 17, 65,118,
+236,216, 65,206,156, 57, 67,196, 98,113, 92, 99,239, 35,123,203,165,129, 3, 7,206, 75, 73, 73, 41,157, 63,127,254,238, 90, 6,
+ 44,181, 87,243,222, 99,202,231, 99, 41, 67,254, 6, 77,153, 72, 36,138,187,118,237, 26, 41, 42, 42, 34,109,221,220,200, 98, 54,
+155,100,242,120, 36,155,199, 35, 27,129,194,127,129, 77,154, 92, 87,213,225,159, 77,173, 70,171,162,162,130,204,158, 61,219, 36,
+ 20, 10,245, 60, 30,207,209, 41,120,158,232,139, 80,165, 82,157,115,115,115,211,184,185,185, 61, 98,246,170,167,171, 84,170, 43,
+255,242, 27,208,159,199,227,165,113,185,220, 71,167,224, 9, 30,209,189,117,207, 73,115,221, 66, 70, 12,105, 98, 62,121, 60, 30,
+239,125,161, 80,168,159, 61,123,182, 73,167,211, 57, 98,180, 0, 96,160, 88, 44,206,218,190,125,187,225,238,221,187,150,194,194,
+ 66,235,197,139, 23, 45,177,177,177,166,143, 63,254,184, 76, 44, 22,103,161,238, 97, 9,254,146,227, 73,214,182,226, 87,153,173,
+235,115,125, 18,135,183, 21,155,163,223,142, 36,221, 91,212, 48, 89,117,143,228, 94,187,102,165,217,186,250,161,119, 98,184,191,
+212,186,100,238, 91,164, 91, 75,209,163, 38,203, 1,205,154,102, 75, 44, 22,151,125,244,209, 71,142, 68,178, 30, 53,132, 91, 2,
+188,201,230,192, 29, 15, 76, 84, 3,203,198,128, 47,201, 23, 1,222,255,148,251,168,171, 27,124, 6,248, 11,110, 56, 16,201,178,
+ 39,159, 29,149, 74,229, 45, 7, 34, 89, 15, 53,191,248, 98, 29,153, 48,126, 32,185,127,107, 31,209, 21, 28, 33, 87,206,175, 34,
+ 99, 70,132,146,110,221,194,200,230,205,155,201,237,219,183, 73,151, 46, 93, 72, 35,242, 25, 57,117,234,212,184,228,228,228,184,
+164,164,164,184, 51,103,206,196,141, 26, 53, 42, 14, 64,100,245,154,160, 42,179,101, 30, 51,198,216,145,197,122,171, 1,205,103,
+166, 78,157, 74,146,147,147, 73, 82, 82, 18, 57,115,230, 12, 25, 53,106, 20,129, 99,211,247, 52,170, 92, 10, 13, 13,237, 30, 30,
+ 30, 62,183, 83,167, 78, 67, 30,151,230,127,208,104, 73, 70,143, 30, 77,219,108, 54, 50,100,200, 16,219, 26,160, 56,154,162, 52,
+209, 20,165,217, 12,228,253,219, 35, 90,127,246,132,159, 17, 0,126,174,158, 32, 20, 10, 53, 21, 21, 21,174, 82,169,116,191, 78,
+167,155,129, 7,221, 34,155,164,249,103,228,147,209,252, 87,104,122, 72,165,210,117, 58,157,110,148, 80, 40,204,171,168,168,112,
+115, 64,211, 73, 32, 16,188, 37, 20, 10,195,245,122,189, 63, 0, 72, 36,146, 59, 70,163,241, 87,131,193,240, 57,128,226,191,123,
+223,201,218, 86,124,240,249,157, 65,240, 94, 92,122,121,203, 37,199, 11,125,222,238,175, 76,239,209, 90,146, 2, 46,253, 25, 40,
+227, 37,234,197, 52,163,195,154, 34, 42, 12, 54,238,123,151, 82,245, 45, 62,251,169,204,103, 86,184, 52,189, 71, 43,105, 58, 8,
+ 62,131, 64,127,222, 81,205,154,102, 75, 34,145,108, 47, 47, 47,127, 21,192,175,142,238, 59,217, 19,196, 67,185,165, 25, 44,236,
+182, 32,245, 76,225, 67,136, 30, 44,118, 2,114,161,161, 62,190,101,102,238,163,218, 53, 55,108, 88, 79,126,254,233, 8,140,250,
+ 66,228,104, 75, 49,225,249,151,208,177, 99, 40, 84, 42, 21, 22, 47, 94, 12, 63, 63, 63,124,242,201, 39, 84, 35,242, 25, 41,149,
+ 74, 39, 4, 6, 6,182,186,121,243,102,146, 94,175,255, 22,192,137,154,207,159, 64, 32, 92,204,225,116, 48, 88,173,167,111, 1,
+177, 13,104, 62, 35,149, 74,103, 5, 6, 6,134,220,188,121,243,134, 94,175, 95, 9,224, 59,166,172,123, 50, 52, 89, 44,214,231,
+ 62, 62, 62, 99, 82, 82, 82,222, 3,176, 11,255, 33,254,114,163,197,104, 50,154, 79,160,102,213,125, 66,254,105,249,252,191,217,
+162,103,128, 66, 75, 16, 42, 19, 60,122,117, 3, 38,171, 97, 77, 17, 21, 6, 43,231, 77, 80,104, 14,130, 92, 16,214,231, 13,152,
+172,191,214,100, 2, 20, 62,174,167,252,250, 24,132,170,251,124, 49,215,124, 45,204,155, 55,143, 28, 59,118, 12, 98,177, 24, 6,
+131, 1,131, 6, 13,194,167,159,126, 74, 49,101, 8,163,249, 23,106,254, 43,225, 48,135,128,129,161, 65,200, 63, 53, 99,212, 27,
+ 73, 38,178, 39,232, 50,242,217,179,193, 66, 75,192,154,134,114,107, 46,245, 70,154,169,137,154, 23,145, 79,205, 4, 27,254,224,
+ 91,239, 67,103,202,165, 94,107,188,230,159,240, 15,145,224,227,127,238,121,121, 18,169,105,170, 98, 99, 99,153,131,194,192, 96,
+ 63,147,241,104, 79,195,135,159, 25,163,197,192,240,132, 67, 61,117,203, 12, 32,179,114,249,199,106, 50, 48, 48, 48,252, 7, 13,
+ 23, 40,212,221,160,205,145,144, 96, 99, 26,218,253,204,104, 54, 74,147, 13, 64, 1,192, 9, 15,198, 32,169,234,210,219,208, 48,
+ 27, 67, 0, 88,152,227,201,104, 50,154,140, 38,163,201,104,254,205,154, 13,105, 63,137, 85,146,181,245, 50,140,254, 43,126, 56,
+130,209,124,172, 12,250,215,236, 59, 65, 7, 16,172,174, 92, 58, 48,231,157,209,100, 52, 25, 77, 70,243, 63,175,249,175,132,169,
+ 58,124,178, 16, 62,177, 57, 39,196, 3, 64,213, 32,151, 9,168,160, 2, 33,196, 76, 0, 64, 25,174, 16,130,187, 0,218, 86,174,
+207,160, 40,135,123,163, 50, 48, 48, 48, 48, 48,252, 93,132, 2,184, 2,192, 3,192, 48, 0, 49,168, 28, 85,225,111, 53, 90, 34,
+151, 54, 30,224,176,218, 83, 52, 9, 4, 0,194,162, 18, 97,165,227, 13, 5,119,155,252,144,149,122,250, 59, 19,240,247, 80, 48,
+ 61,165,203,190,211,228,193,208,218,250,203,199,184,169,100, 19,114, 11, 74,182,223,184,173, 59,224,200,182, 10,133,143, 66,232,
+172, 28,103, 52, 91,218,242,121,188,116,115,113,105,116, 81, 81, 82, 89, 35,178,225, 92,223,202,143, 63, 38,212,225,156, 43, 20,
+ 79,108,102,185,200,121,148, 14, 58,162,203,145,210,190,197, 41,100,239,222,167,136,163,231,134, 98,161,159, 68, 38,235, 36, 16,
+138,195,196, 50,101, 27,154, 0,133,154,172, 84,147,197,122,198,102,210,199, 17, 26,191, 57,112,174, 38, 2, 88, 2, 0,232,223,
+255,103,180,133, 28,159, 87,101, 28,175,245,191,142,137, 39, 79,162,106,112,217,247, 1, 44,101,238, 91, 6, 6, 6, 6,134, 39,
+204,104, 13,195,131, 42,195,134, 27,195,251, 4,247,186, 44, 20,138,124, 1,128, 38, 4, 52, 1,202, 75,139,227,114,147, 98, 7,
+ 1,128,170, 69,232,113,174, 80,222,137, 38, 15,214,219,104,192,106,174, 72, 41, 77,187,216,197,158, 28, 73, 92,253, 71,247,143,
+ 24, 48, 38, 42,106, 88, 64,187,182,237, 90, 3,192,245,132,235,247, 15, 31,142,185,125,242,103,106, 95,121,222,157, 31,155, 20,
+ 64,129,240,211,206,157, 59,246,138,141,189,242, 9,128,105, 77, 61,130, 46, 46,210, 25, 39,126,152,221,103,192,152, 21, 18,192,
+ 49,163, 37,116, 86,142, 27, 57,124,112,199,119,222,152,202,122,101,246, 98,223,203,103,127, 91, 38,245, 8, 41, 38,180,229, 68,
+185,102,252,239,245, 77,156, 92,211, 63,214,101,176,190, 45, 60,198, 90,253,117,119,165,161,240,254,120, 66,219,198, 83, 20, 5,
+ 54, 95,188,215,181, 85,175,221, 78,253,222, 46, 2, 96,119,143, 49,185, 71,112,132,218,195,107,223,248,151,222, 18,138, 21,110,
+ 28,176,121, 0, 40,100,167,222,194,201,239,150, 40,223, 92,176, 53,244,108,124,154,245,151, 31,214, 87, 80, 60,238, 24,125,206,
+205,134,235,211,211,210,156,224,227,243,224,253,151, 95,206,131,111,203,235,120,208,214, 12, 88,133,146,111,178,209, 22,120, 96,
+180, 82, 83,161,100,238, 89, 6, 6, 6, 6,134, 39,136,152, 74,115, 21, 83,115, 69,157, 70, 75, 40, 20,249, 94,248,237,176,243,
+143,103, 50, 0, 0, 17,161,238,248, 96,225,186,200, 29,107, 99,111, 3, 64,247,254, 81,254,159,188,255, 6,206,221,208,130, 16,
+130,142,126, 46, 24, 50,242, 41,251,140,135, 91, 80,151,113,227,198, 62, 55,123,246,172, 17,247,238,221, 75,221,181,107,215,239,
+ 0,208,187, 79, 31,191,197,139, 23, 63,189, 66,233, 44,248,126,239, 15, 89, 21,154, 91,151, 27,179,183, 66,207, 86,205, 2,218,
+180,156,240,253, 87,235, 88,253, 6,141,125, 54, 21,229, 75, 42,178,147,178,236,217, 86,165, 82,205,228,114,185, 10,224,193,108,
+236, 85,152,205,196, 29, 0,172, 54, 90,166,244, 12, 40, 99,243,132, 54,129,128,119,179, 76,167,219, 94,154,117,107, 75,125,154,
+ 70,139, 37,228,205,215, 94,100, 93, 77, 42,128,111, 72,111,246,234, 37, 31,130,182, 89,148,111,189,191,112, 92,236,197,239, 81,
+174,193, 41, 59,119,141, 91, 51,161, 89,179,110,236, 79,151, 72, 7, 82, 20, 94,240,233,254,210,168, 79,182,237,229,118,246,147,
+195,104,161,113, 52,174,160,251,198,207, 63, 93,126,118,227,176, 67, 0, 54, 3,248, 5, 64,131,166,206,217,197,249,219,153,115,
+ 63,151,150,155,254,223,219,187,210,100,225,203,237,123,112, 45,131, 70, 96, 64, 32,199,125,230, 50,233,230,133,147,183,233, 31,
+204,179, 85,155,221,109, 5,160, 39,144,232,140, 41, 11, 6,224,155,165,139,160, 86,151, 67, 38, 75, 7, 5, 55, 0,109, 42,191,
+120,151,159,143, 12, 0,239,107,181,144,124, 50, 21,131,174, 2,115, 58, 0, 90, 0,103, 41,251,102,141,103, 96, 96, 96, 96, 96,
+248,187,200,193,163,141,223,163, 27, 52, 90, 0, 32, 21,113,112, 59, 57, 23, 0,224, 36, 2,102, 76,153,132,130,252, 60,127,147,
+149,198, 75,147,158,199,149,196, 28,220, 78,201, 3, 33, 4,254, 94,118, 79,194, 13, 54,232,206, 47,189,252, 82,223,227, 39, 78,
+ 92,154, 55,119,222, 55, 20,133,243, 0,176, 57,250,203,238,243, 63,154,255,234,243,147,158, 31,184,119,239,222, 27, 0, 26,101,
+180, 56,148,108,221,242,165,139,248,153,249, 21, 21, 51,103,191, 71,207,122,123,230,106, 0, 99,237,114, 50, 92,174, 34, 51, 51,
+ 83,202, 98, 61, 58,151,230,103,139,222, 59, 61,112,204,138,187,169,233,197, 87,143, 31, 60,216, 37, 56, 56, 24,153, 89,185, 61,
+151,173,217,212,225,232,113,209,139,101,165,134, 49,250,252, 91,181, 78,218, 44,224,114,111, 44, 88,182,177, 35,237,228,199,250,
+224,213,161, 8,105,237,137, 44,109, 49,250, 12, 26,193,137,187,124, 57, 18,176,219,104,213, 28, 60,112,156,137,214,118, 88,188,
+253,226,128, 81, 61, 60, 59,179, 88,108,232, 12, 22,228,149, 24, 97,163,129,222, 65, 10, 12,222,177,134, 83, 88,110, 25,189,240,
+135,140,209,231,215, 70,105, 42, 74,178,167, 3,216, 87,255,207, 16,103, 47,181, 28,183, 51,202,106, 53, 89,229, 21, 86, 0, 0,
+143,109, 3, 5,226, 82,143, 80, 79, 0, 95, 3,129,192, 79,211,159,131,155,219, 46, 55, 55,183,113,106, 55,247, 56,255,231, 94,
+164,154,249, 6,201,116, 6, 51,110,222,184, 94, 22,220, 41,129,148, 21,106,223,170, 40, 47,218,123, 11, 72, 8, 4,118, 87,106,
+188, 8,198,104, 49, 48, 48, 48, 48,252,179,169,179,215, 33, 7, 0, 14, 31, 62, 76,162,162,162,254, 48, 2,176,205, 70,112, 59,
+229, 65, 19, 28, 54,155,141, 97,189,252,176,122,217, 2, 24, 76, 86, 92, 75, 46,193,143,231, 50, 96, 42, 47, 6, 33, 4,249, 33,
+234,218,126,248,145, 42,165, 21, 75, 68,161,108, 1,119,252,217,139,146, 22,206, 74,165,242,238,141,111,202,231,191,173, 9,226,
+ 16,115,220,194,207,252,146,121,206,156, 30,123,246,236, 14, 30, 30, 21,197,151, 74,101,239, 18, 78, 7, 47,110, 57,153, 85, 82,
+ 18, 95, 82,151,102, 77, 68,234,192, 17, 35,134, 13,238,239,238,238, 70, 63,183,248, 98,226,186,233,161,222,109,252,218,244,188,
+109, 49,140, 48,104,239, 30,172, 99,179,135,154, 52, 77,131,197, 98, 65,163,209,192,102,179,193,104, 52,194, 98,177, 32, 35, 35,
+ 85, 67, 19,226,101, 3,205,242,240,240, 2,135,195,135,111, 11, 31,108, 92,189, 68,188,227,251,131, 97,115,230,125,122, 64,159,
+143,110,248,255,224,150, 15, 53, 43, 10,139,246, 30, 57,118,194,149,224,164,231, 7,175, 14,101,107,139,116, 56,121,249, 30,174,
+220,204,112,244, 68,214, 28,194,161, 69, 86,218,189,210, 21, 43, 86,176, 63, 57,122, 47,163,255,144,177, 54,159,214,237, 91, 24,
+109, 4, 0, 5, 1,143, 3, 30,135, 5, 31, 87, 33,246,191,215, 22, 23, 71,198,187, 69,134,186,126, 78, 8,217, 87,223,241, 52,
+ 26, 45,182, 94,129, 18,118,135, 86, 10,196,223, 47,194,165,163,231, 49,115,238,231,136, 77, 54,162, 76,167, 7,101, 51,130, 77,
+140,200, 79, 75,130,213,102, 35, 13,157,247, 7,132, 22, 1,128, 64, 32,120,255,199, 67,199, 60,141,180, 16,185,197, 70,104,138,
+140,240,235, 54, 70,146,150,149,135,175, 23, 60,253, 62,128,189,129, 64,153,125,154, 77,134,209,100, 52, 25, 77, 70,147,209,252,
+135,104,214,229, 69,158, 16,234, 28,202,129, 85,223, 86,247, 51, 10,113, 59, 57, 23,157, 2,155,161,117, 11, 15, 92,186, 83,132,
+111, 79,102, 96,235,241, 52,156,188,150, 7,154, 35, 67,110, 41,112, 55, 85,131,187,105,249, 13,142,159,205, 22,112,199,191,249,
+102,201,236,118,193,165,221,126, 59, 58, 3,205, 92,239, 6,207,153, 83, 60,131, 45,224,142, 87, 54,151,237,122,111,246, 91, 19,
+100, 98, 49,223,100, 52,161, 85, 75, 31,225, 27,211,103,188, 72, 41, 5,118,207,137, 36,107, 22,164, 20,136, 68, 91, 22,126,252,
+174,224,243, 31,239,166,151,155, 80,190,239,188, 38,105,214,123,243, 11, 57, 92,225, 70, 89,179, 32,187,219,254, 88, 44, 22, 24,
+141, 70,152, 76, 38,152,205,102,100,101,220, 26,241,203,143,239, 12,106,217,220,121,144, 64, 40, 4, 1, 80,106,176, 34, 57, 71,
+143,240, 1, 3,217,157, 66, 67, 67,164, 30, 65, 47,215,166, 85, 82,146, 86, 66, 19,182,236,240,254,157,236,221, 63, 93,197, 55,
+135, 47,227,192,175, 87,113,233,212, 81, 43,161, 45, 15,231,255,146,122,248,249, 75, 61,218,165, 73, 61,219,107, 30, 46,205,218,
+214, 59, 60, 51,155,205, 34,225, 3, 34,126,158, 50,237,141,223,244,101, 5,218, 45,235, 22,100,229,101,167,222, 18,240, 40,171,
+ 88,192,134,174,194,138,109,191,100, 99,220,146,107,184,153,174, 3, 33,164,193, 9,188,105,224,237,241, 47,191, 99,179,152,205,
+ 8,240,150, 98,103,244, 82,140, 8,239,128,254,237,148,232,210, 90, 2, 49,199,136, 27,137,183,241,221,206,109, 86,154,102,205,
+106,224, 70, 28, 92,185,196, 1,128, 78,167,123,103,206,187,179,242, 76, 86, 26,102, 11, 13,115,229,235, 47,223,125,150,103,171,
+208,191, 83,185, 93, 92,181,237,152, 41, 30, 24, 24, 24, 24, 24,158,132,136, 86,213,226, 81,125, 69,157, 85,135, 21, 21,134,148,
+177,227,159,135,135,218, 93, 58,178,223, 11,188,184,251,197,200,203, 73,195,189, 59, 9,208, 87, 88,192, 83,182, 4,132,238,104,
+225,235,131,248,219, 7,204,107,151,199,232,104,171, 49,165, 46,189, 17, 35, 60,188,238, 37, 82,172,229,203,188, 47,220,185, 93,
+212,105,231,220,175,241,220,115, 82,213,242,101,222, 23, 82,147, 36, 44,177,144,244,120,113,210,179, 20,139, 34,152, 51,103, 54,
+ 70, 70, 13,198, 75, 47, 78,164,182,111,223,214,173,216,206,189,164,193,253,226,253, 15, 23,240, 53,197, 86,211,165, 59, 58,163,
+ 88, 34, 18,157,189,171, 43, 15,241,245, 22, 13, 29,243, 66,118,204,158, 45,159, 3,152,100,143, 86,149,193,178, 88, 44, 48,155,
+205, 0, 96, 3, 0, 22,235,193,107, 65,153, 9,218, 98, 35, 52,197, 70, 88,109, 52,198,140,159, 36,186, 28,123,109, 18,128, 58,
+218,107,209,180,197,106,193,190,159,174, 32,235,242, 94,154, 98,177, 75,170, 53,134,135,212,195,207,223,221,221,251,116,212,152,
+137,174,124,225,131,106,216,178,114, 35,182,111, 90, 86,111, 62, 89, 20, 69,104,155,181,216,106,177,148,183,106,217, 42, 43, 48,
+184,131,240,204,111,199, 71,156,253,121,159,206,218,106,162,211,253,212, 28,176,185, 2,176,121, 66, 24,205,246,117, 60,212,220,
+187,176, 30, 0,245,242,235,179, 87,191,245,206, 7,236,183,215,254, 14, 83,133, 30, 70, 67, 57, 74, 75,138, 32,226, 88,112,227,
+220, 65, 43,177, 89,222, 42,207,185,186,190,110, 37, 42, 27, 64,118,245,148,194,194,194,147,231,126, 63,125,232,226,185,223, 95,
+114,111,213,137,101,178,208,184,151,112,145,206,186, 27,123,200,104, 44, 61, 9, 0, 20, 80, 0,224, 56,115,223, 50, 48, 48, 48,
+ 48, 60,129, 17,173,201,213,211,234, 52, 90,105, 55,207,116, 1, 0,255,206,145, 5, 82, 33,199,153,195,162,160,201,188,143,237,
+ 43,102,130,166, 9,134,190,186, 28, 50, 95,119,136,120,108, 24,117, 5,186,194,251,167,234,107,171, 3,138,178, 12, 92,191, 57,
+203,247,245,215, 90,201,119,238,212,113, 1, 96,231, 78, 29,247,181,169,205,229, 27, 54,167,248,118,237,213, 9,196,102, 67,212,
+200,177, 24,255,204,120,164,230,234,241,195,233,116,148, 27, 76,118,245,150, 19,169, 2, 59,168, 92, 92, 7,191,249,194, 96, 9,
+135, 77, 81,109,124, 20,236,140, 60,139,149,205,230,218, 14, 93, 46,201, 30, 51,230, 25,213,201, 35,187,251,219, 84,129, 29, 12,
+249,137,215, 26,210, 51, 26,141,143, 84, 29, 58,171, 90, 30, 25, 56,118, 69,102, 78,110, 89, 76,110, 81, 69,215,114,139, 21,154,
+ 98, 35,180,197, 70, 20,151,155,225, 46, 83,194,106, 49,181,171, 75,143, 16,242,205,168,177,207, 79, 4,192,162, 88,214,175,117,
+ 57,137,119, 30,172,249,191,201, 26, 60,242, 57,215,211,113,247,113, 47,246,104, 17,161,173, 15, 70,113,167,232,204,250,143, 43,
+ 8,155, 2,205,227, 80, 22, 54,139, 69,155,205, 58,139, 90,237,122,242,212,201, 99,195, 43,172, 73, 96,243, 4, 15,191,107, 48,
+253,143,189,183, 14,143,234, 90,191,199,215, 57,103, 92,226,201,196, 8, 18, 36,193, 29, 18,220, 73,113, 40, 20, 45, 80,138,183,
+212,160,165, 45, 45, 46, 23,215,210, 98,165,184,187, 67,240,226,154, 0, 9,196, 61,153,137,140,219,177,223, 31,147, 64,128,144,
+ 76,160,247,247,189,247,115,179,158,103,158,201, 57,204,121,217,103,235,218,235,125,247,222,172,211, 53, 38,251,197,205,181, 0,
+176,106,245,202,101,173,186, 14, 19, 93,190,159, 8, 51, 13,132, 55, 9,193,225, 61, 27,173, 60, 79, 79, 51,102, 62, 88, 91,142,
+ 74,232, 30, 20, 20,244,149, 80, 44,238, 36,147,187, 4,249,248, 87, 38,237, 12, 11, 59,205, 66,225, 21, 72, 74,148,158, 93, 57,
+ 82,116,141,177,219, 34,237, 70,245, 42, 0, 5, 21,237,182, 2, 21,168, 64, 5, 42,240, 95,166,106, 1,197,246,208,122,141,104,
+ 29, 63,126,156, 7,128,146,252,163,233,217,121,240, 82, 10,224, 19, 80, 13,195,191, 90,134,109, 43,190, 5,203,210,224,121,128,
+ 97,157,219,153,128,231,133,231, 38, 79,172, 86,187,106, 53,202,103,248, 48,185,121,199, 78,147,108,248, 48,185,185,126, 3, 47,
+237,228,137,213, 18,245,150,202,173, 25,150,197,245,232, 28, 68, 37,106, 17,149,164,131, 82,230,252, 54, 95,148, 88, 52,113,241,
+162,133, 34, 1, 69, 16,209,201, 6, 67, 90, 46, 99,160,132, 66,187, 92, 38,230,109,188,192,154,164,225,115, 59,247, 27,109, 62,
+182,125,213, 24, 0, 95,188, 83, 21, 43, 92,105, 88,164,100, 21,125,243, 60,207, 19, 0,199, 17, 44,155,166,177,192, 96,167,145,
+157,255,138,104, 17,204,187, 61,167, 74,255,154, 33,174, 46,202,211, 20, 69, 73,120, 30,160,237,204, 39,240,175,217,221,144,249,
+ 34,182, 56,201,186, 25,157,129,184, 7,231,179, 89,187,105,132, 41, 39,230,130,179,239, 78, 16,224, 41, 10, 28, 69, 18, 28, 65,
+128, 19,146,188, 13, 60,207,189,153, 34, 83, 57,136, 86, 17,217, 18, 11,169, 25,103,119,175, 80,125,214,179, 14,246, 92,113,112,
+ 62,139, 94,173, 51,166,151,139,100,193,203,203,107,228,247,223,127, 63,179,207,199,195,160,181, 16,200,206,119,168,129, 54,154,
+131, 72,225,141,174,147,183, 4,101,170,117, 65, 47,110, 31,107,173,121,176, 83, 75, 91,180, 43, 43,218,108, 5, 42, 80,129, 10,
+252,111,161, 52, 46,242, 95,164,106,189,173,104,149,246, 66, 60, 15, 60, 79,214,160,106, 37, 31, 84,170, 90, 3,177, 79, 31,189,
+250, 55, 0, 12,235,156, 59,234,232,209,204,180,101,203, 92,185,111,191,213,134, 47, 94, 92,249,198,196, 9, 65,110,245, 27,120,
+105,191,255, 62, 37,124,249,114,183, 27,231,110, 10, 89,190,112,191,174,162,189,185,120,190, 60,123,108,146, 45, 26,213, 13,166,
+102,239,124,158,114,225,177, 62, 71, 36, 18,209,126, 30, 82,194, 69, 41,166, 40, 82, 40,182,210,164, 53,164, 94, 19,234, 24, 73,
+ 52, 41,205, 74, 17,209,122,211,117,152,171,142,235,115,246,192,212,250, 29,250, 45,241, 76, 87,155,161,181, 81, 47, 93,135, 20,
+ 73,224,241,211,100,128, 18, 69,149,100,211,213,197,243,204,174, 29,219, 42, 47, 95, 60, 31,118,134,197,228,111,127,193,232,145,
+ 35,206,192,191,102,247,202,213, 66,239, 93, 61,246,167,188,251,132,245, 72,142,185,155,197, 88,117,187,203, 67,178, 94,146, 45,
+128,103,121,142,204,203,215, 41,173, 12,164, 40,129,247, 89,237,220,123,213, 28,131,153,193,177, 91, 89, 56,126,104, 55,220, 92,
+ 20,239,101,195,205,205,173, 78,187,118,237, 65, 8,196,176,209, 86,216, 24, 14,182, 98, 49, 90,118,154, 3,205, 11, 33,247,111,
+136,188, 39,135,235,192,162,173,232,113, 42, 80,129, 10, 84,224,127, 8,255,197,129,240,197,201,213,187, 21,173,210, 80,165,146,
+ 47,110, 69, 37,162, 65,237, 96,184,185,186,224, 89, 92, 26, 40, 82, 8,146, 0,104,198,121, 50,196,219,233, 61,203,151,187, 33,
+ 57, 81, 65,254,182, 62,177,218,228,137,213, 18,151, 47,119,187,193,219,233, 61, 0, 70,240, 60,224, 32, 91, 14,194,197,150,131,
+ 23,240, 28, 29,228,235, 41,167,238,198, 27,115, 73,146,178,122,185, 73, 57, 47, 55, 9,233,229, 34, 22,138,132, 20,199,240,164,
+189,146,170,154,133,231, 56,103,206,213,123,205,117,200,178, 44, 8,130,100, 11,137,152, 34, 53,215, 12,173,133, 66,118,129, 21,
+249,122, 59,106, 5, 42,112, 62,114,191,137,165,205, 59, 75,178, 69, 9, 69,110, 53,170, 85,194, 79,115,151,195,108,101,241, 60,
+221, 0,145, 68,226,231,235, 87,239,225,136, 73,211, 37, 83, 54,196, 97, 76, 39, 47,124,123, 53, 46,221,148, 45,157, 94,158,146,
+101, 89, 22,102,139, 77,148,173,201,247,208,233,141,174, 50,169,196,236,227,233,166, 41,233,183,150,114, 42, 90, 69,144, 75, 5,
+232, 29,230, 7,139,125, 40,204, 86, 6,127, 95, 56,248, 62,102,130,125, 3, 42,193, 96, 43, 70,174, 10,201, 86,113,210, 37, 84,
+250, 0, 32,130, 43,186,156, 10, 84,160, 2, 21,168,192,127, 17,222,185,234,208, 41,162,165,148, 75,193, 83, 82, 92,189, 23,135,
+208,186, 13,177,245,232,109,212,108, 16,134, 76, 61, 3, 30,100,153,171, 13,139, 48,245, 71,243,125, 0,247,251,244,145, 87,234,
+223, 63,176, 43,207, 11,207,173,255, 67,151, 6, 0,193,245, 29,102, 56,142, 7,207, 3, 60,231, 32, 92,206, 75, 58,130,228,196,
+ 76, 93,213,106,126, 10, 60, 73,179, 91, 21, 18, 17,233,161, 16, 83, 62,110, 98,145, 72, 32, 0,203, 19,214,204,204, 56, 43, 1,
+ 36, 57, 99,238, 77,215,161, 92,233,127,178,115,191, 37,234,164, 20,237,221, 90,121,166, 70, 90,187, 24, 60, 15,212, 10, 84, 32,
+234,230, 9, 54, 59,253,197,115,115,118,204,239, 37,217,226, 56, 80,118,134,195,195,120, 45, 10,140, 52, 10, 12,118,180,238,216,
+ 91,212,186, 75, 31, 92,141,210,128, 99,104, 44,222,120, 66,207,242,244, 96,224, 41, 93,142,151, 38,111,221,143,174,164,206, 55,
+ 74,132, 2, 65, 65,237,154, 85, 18,196, 34, 33,163,211,233,196,175,255,138,130, 66, 38, 70,158,129, 6, 0,186,188,181, 71,107,
+164,113,244,102, 22,142, 29,220, 5,153, 76, 6,254, 61,106,160, 72, 36,114, 23,138,164,176, 27, 29,238,194,162,143,253,141, 15,
+ 41,144, 0,164,192,189,162,205, 86,160, 2, 21,168, 64, 5,254,139, 80,252,140,195,158,197,201, 23,233,148,106,194,241,240,246,
+242,132, 84,225,138,196,108, 59,244,132, 10,249, 38, 30, 44,235, 80,180, 74, 17,158, 74, 60,221,251,232,209,204,180, 35, 71, 52,
+155,143, 30,205, 44, 22,232,253, 74,201,122,249,205,241, 78,219, 36,120,246,252,209, 83,151,180,125, 90,250,120,144, 20,101, 22,
+ 9, 73,171, 64, 68,217, 69, 2,146, 22, 9, 72,155,175,171,144,186,116,108,183,152, 39,112,169, 44,155, 22,139, 5, 93,186,116,
+ 65,143, 30, 61,208,183,111, 95, 12, 26, 52, 8, 33, 33,117, 84, 36, 69,216,120,130,227,124,196,122,212,240, 33, 32,176,164,226,
+194,238,127,153,162,174, 31,126,200, 90, 45,189,241, 58,229,124,101,147,231,185, 60,173, 21, 22, 59,139,124,131, 29,249, 70, 59,
+ 24,159,112, 28,254, 59, 3,102, 27,139,228,123,251,205,234,172,180,175,172, 57, 47, 18,203, 40,138, 31, 94,191,228,211, 62,255,
+108,164,218, 69, 74,190,104,219,170,185,218,219,203,147, 33,136, 87,202, 43, 65, 16,144,186,170,224,225,238,130,196,251,167,112,
+118,113,103, 51,128,159,157,201,207,226,112,149, 11,208,167,165, 31,122, 15, 24,138, 6, 97,221,157, 33,214,111,217,148,203,229,
+178, 34,245,170,248,182, 14,182, 98,170, 22, 91, 88,222,164, 64, 34,115,182,220, 63, 16, 21, 54, 43,108, 86,216,172,176, 89, 97,
+243, 63,199,230,127, 51,138,206, 56, 44,250,118,110,103,248, 34, 2, 84,221, 95,129,154,129, 10, 88,236, 42, 88,108, 44,140, 22,
+ 22, 58,147, 29, 58, 19,141,196, 44, 19,162,142,126,120, 10, 29, 42,150, 99,235,115,222,177,223, 38, 88,142,119, 90, 61, 17,219,
+109,115,151, 45, 94,240,201,238, 38,141,109, 83,122,250, 7, 61, 74,180,101, 16, 4,105, 38, 41, 1,237,233, 34, 16, 62,123,246,
+ 72,125,227,202,201,118, 82,134,253,212,129, 93, 93,197, 0, 0, 32, 0, 73, 68, 65, 84, 84,138, 29,134, 97,180,129,129,129,133,
+ 74,212, 43, 10, 89,167,134,172,239,245, 19, 63, 4,183,239,179,216,103,197,252,169, 38,146, 18,113,132, 64, 20,197,210,230, 93,
+230,236,152,245, 40,133,126,144, 34,233,211, 91, 15,158,132,185,123, 6,225, 69,186, 17, 70, 11, 3, 59,195,193, 67, 41, 66,218,
+227, 51,246,196,103,119,247, 26, 50, 30,109,125,143,108,219, 25,251, 52,170, 82, 68, 68,247,143,195,194,194,169, 95,127,253, 5,
+161,161,161, 48,155,205, 32, 73, 18, 65, 85,107, 32, 49,246, 1,110,158,152,203,154,114,147,126, 7, 48, 7,128,186,188,255,137,
+ 70,103,195,169,187, 57, 56,113,104, 15, 40,161,248,125,138,151,148,201,100,210,146,200, 85,113,210,245,242,199, 66,177,180,112,
+ 18,192, 85,180,221, 10, 84,160, 2, 21,168,192,127, 9,198,189,241,189,193, 41,162,101,177, 88, 18,219,116,233, 13,142,227,193,
+242, 0,199, 22, 42, 79,220, 43,245,137,165, 45,137, 31,154, 58,142, 99,111,175,221,176,185, 71,147, 22,237,169,186,149,149,208,
+229,102,225,230,245,139, 12, 56,254,134, 51,207,231,230, 62, 55,200,124,107,126,252,201,192,254,251, 70,126, 54,161,160, 93,199,
+142, 10,149,202,207,154,150,158,102,218,178,125, 7,125,230,228,145,118, 28,152, 33,185,185, 47, 12,165,217,209,106,181,171, 74,
+186, 47, 17, 43, 91, 3, 8,166, 4,132,205,172,126, 94,174,136,112, 77,122,234,128, 5,115,103, 37, 13, 27,251,141,184,122, 96,
+ 13,228,104, 41, 36,166,101,225,217,149, 35,214,244,216, 59,135,116,105,247,199, 56,105, 42,179,132,123,105, 0, 86,220,188,121,
+163, 94, 68, 68, 68,247, 78,157, 58,241,227,198,141, 3,207, 3, 23, 54, 76,228,243, 18,111,238,135, 67,197,138,127,207,114, 73,
+190,114,227,129,231,160,118,205, 4, 94, 46, 99,176,121,207, 73, 26, 60,151, 92, 78, 51,190,149, 42, 87, 21, 56,220,133,142, 45,
+ 29,222,252,216,232, 87,241, 99, 34,165,175,192,132, 40,223,119,188,111, 5, 42, 80,129, 10, 84,160, 2,255,105,120,255, 24,173,
+212,167,142,253,180,254,221,208,103,229,140,216,186,117,219,188,109,219,119,183,182,216,108,129, 60, 68,169, 44, 99,187,108, 96,
+241,171,179, 54,204,217, 47,238,122,121,213,170,191,101,227,218,159,183,108,254,173, 61, 56,182, 54, 1, 36,241, 4, 46, 73,105,
+118,100, 89, 36,171, 84,178,164,209,255,209,245,227,165,230,220, 92,195,182,242, 62,107,206,141,201, 34, 41,123,208, 31, 43,231,
+ 46, 33, 73,170, 27,203,114, 66,142,165, 95,176,118,203,191,204,234,152,163,112, 58,202, 13,121,165,252, 91, 52,128,232,200,200,
+200,182,145,145,145, 45, 0,172,130,227, 12,197,187, 31, 82, 46,214, 92,125,231,105, 83,167, 93,248, 14, 68, 21,142,227,193,176,
+ 92,178,200,108,234, 92, 78, 51, 65,213,171,215,144,219,105,246,173, 0,248,226,129,240, 47,137,150, 91, 37, 57,128,160, 10,162,
+ 85,129, 10, 84,160, 2, 21,248, 47,193, 56,188,189,105,169,115,138,214,255, 95,200,207,143,215, 35, 31, 83, 62,212, 78,110,238,
+115, 3,128,183, 86,238,153, 62,208,110,212,115,221, 1, 60,215, 29,120,223,231,141, 57, 9,106, 32, 97,228, 7, 38,195,153, 64,
+246,171,133,159,127, 4, 26,205, 83, 35, 52,104,249,161,197,178,115,199,246,103,187,119,239, 17,242, 36, 37,228,120, 74,196,240,
+132,144,225, 8, 33, 77,115,176,218,105,218,206, 48, 52, 88,198, 14,142,165,121,206, 78,195,177, 59,124, 5, 42, 80,129, 10, 84,
+160, 2,255,205,132,235, 63,135,104, 85,224,255, 52,226,227, 94,196,134, 85,100, 67, 5, 42, 80,129, 10, 84,224,255, 56,201, 42,
+254, 13,192, 17,123,254,174,149, 3,229, 57,204,247,125, 86, 31,156,175,176,249,193, 54,133, 0,196, 0,148, 0,202,114,105,118,
+ 71,225,121,141, 21,249, 89, 97,179,194,102,133,205, 10,155, 21, 54,255, 31,218, 44,203,246,121, 84,224,223, 74,192, 42,108, 86,
+216,172,176, 89, 97,179,194,102,133,205, 10,155,255,123, 54,255,155, 49,174,132, 15,128, 10,215, 97, 5, 42, 80,129, 10, 84,224,
+127, 16, 94, 94,181,148,192,203,184,222, 50, 33,247,174,227, 11, 0, 38,205,211,236,138,220,171, 64, 9, 40,126,206,225,107, 49,
+ 90,228,123, 26, 20,146, 2,241, 52,185,139,215, 83,133,155, 87,250,255,120,230, 18, 33, 85, 21, 95,118,109, 87,237,112,104,176,
+172,111,121, 30,148,251,132,252,233, 87,163,101,138, 66, 21,242, 37,252,155,200, 62, 36, 17, 10, 85,176,143, 50,168,217,117,151,
+192,122, 31,253, 27,222, 81, 82,183,110,221,240,186,117,235,134, 3,144,252, 19, 6,229,170,144,161,149,106,134, 93, 81, 85,111,
+124, 81,225, 91,107,224, 63,157, 96,165,127, 77, 47,101, 80,211, 3,202,128,134,249, 74,255,134, 58,101,165,166,151, 93,188,235,
+ 84, 47,235,185,160, 62, 11,106,207,222, 21,181, 43,168,207,130,218, 37,253,187, 71,196,106,151,153,187,159,207,247,234,253, 47,
+101, 69,191,242,126, 8,106, 61,212,221,191,253,119, 94,229,125, 46, 48, 36, 44,186,106,189,182, 57, 1,181, 90, 70, 57,251, 76,
+165,208,240,251, 85,234,182,206,174, 20, 18,126,183, 34,231,157,131,212, 39, 56, 92,234, 81,249,132,196,163,242, 73,137,103,112,
+199, 15,181,231,239,239, 47,171, 93,187,118, 68, 88, 88,216,248,206,157, 59,127,221,184,113,227,113, 85,170, 84,233,246,255,114,
+162, 47, 87,133,252,104, 21, 18, 26,171,144,208,200, 85, 33, 63,150,221,191,134,206, 35, 72, 54,131, 32,217, 12,133, 42,116,222,
+127, 74, 89, 73,124, 67,170,200, 85, 33,203, 93,252,234,222,150,169,106,245, 46,239,243, 30, 30, 30,221,124,124,124,250, 21,125,
+ 60, 60, 60,186, 85,180,128,247, 70,113, 21,235,131, 21, 45, 74, 40,145, 95, 27,246,217,228,250,139,102, 77,151,174,220,124, 24,
+ 43,231, 79,125, 98, 53, 22,212,253, 79,124,115,239,224, 22,119, 41,146,170, 84,252, 30,203,177,105,154,132,219,205,254, 9,251,
+161, 85,101, 99,126,254,126,196,183, 67, 63,233, 82,165, 75,175,175,136,152, 4,243, 17,231, 41, 26, 26,237, 61,112, 40,232,202,
+165,139,171, 55,111,222, 48, 71,205,132, 46, 23, 74, 4,107,117,169,209, 5,229, 73,131,171, 79,245, 96,129,194,251, 74,155,190,
+147,253,238,157,223,177,149,181,113, 93, 77,154, 98,167,127,191, 63,124,106,212,168,209,156,162, 40,175, 47,191,252, 82, 4, 0,
+ 43, 86,172,168,201,178,108,110, 92, 92,220, 29,188,199,230,167, 14,130, 25, 58, 98,213,146,217,219, 62,250,168, 7, 50, 52, 70,
+ 44, 94,190,174,195,233,227,123, 7, 25,179,159,239,255, 39,202,196,221,189,154, 43, 68, 46,143,191,250,126,142, 42,162, 67,115,
+202, 96, 97,112,250,202,131,182, 59,214,205,185, 13,212,105,161,215, 60,125,231,158, 98,156, 73, 59,195, 87,201, 71,112, 38, 45,
+ 0, 12,125,107,176, 87,210, 93,124,100,108,132,191, 68,240, 32, 23, 40,243,208, 71,247,170,173,207, 8, 37,146, 42, 36, 73,130,
+ 36, 0,146, 36, 64, 17,132,227,156, 80,187, 57, 57,253,217,213,238,255, 9,237,196,165,114,139, 44, 80, 2, 47,146,120,149, 62,
+130, 44,252,230,121, 93,214,243,107, 94,255,192,127,227, 86,191,166,123,189,214, 53,141, 91, 46, 39,228, 41, 4,237,190, 62, 65,
+240,228,111, 41, 87,151, 63,116,138, 0, 72,165, 30,199,142, 29,243,137,136,136,112, 83,213,235,123,217,153,103,196,148,161,238,
+241,227, 71, 69, 17, 17,221,203, 81, 63, 67,186,130, 36,183, 19,128,144,227,248, 21, 20,199,239, 53,228,198,198, 1,229, 59,125,
+ 74,166, 10, 29, 67,130,119,186,159,225, 64,220, 53,231,196,108,126,223,204, 21, 72, 92, 59, 11, 69,162,175,131, 67, 26, 52, 73,
+ 79,122,113,215,104,208, 47,103,172,218,203,229, 54, 68, 51,211,206, 95,189,247,145, 64, 40, 36, 34, 58,183,164,172,192,197, 15,
+ 41,116, 95, 95,223,126,107,214,172,169, 30, 30, 30, 14, 0, 96, 24,198,117,223,190,125,126,115,231,206, 85,196,198,198, 30,124,
+ 79,179,129, 62, 62, 62,149,197, 98,113, 32, 0,216,108,182,116,181, 90,157, 2,160,204,137,191,194,183,186, 55,120,204,185,122,
+229,138, 0, 0,218,182,109, 55,175,114,155, 47, 60, 40,145,210, 92, 98,118,216,244,138,130,184,139,223,220,188,117,131, 0,128,
+176,150,225,211,229,222,117,214,254,191, 84,182,164,170,208,150, 36,240,109, 88,219, 46, 3, 6, 15, 25, 65,214,171, 85, 25,221,
+186,118,250,193, 12, 28, 43, 87,157, 17, 8,100,183,111,223,174, 65,146, 36,197, 48,140, 37, 44, 44, 44,229, 67,210, 21, 16, 18,
+254, 55, 1, 50,200,206,216, 54,170,227,239,206,195,219,155, 78, 83,110, 65, 77,126, 6, 37, 24,203,113, 92,170, 62,229,110,171,
+255,131,138,214,219,249, 92, 94, 75,164, 64,252,245,208,209,147,234,127,243,221, 79,210,175, 86, 70,226,196,186,233,154,255, 84,
+146, 5, 0, 20, 73, 85, 58,115,246,140, 74, 46,166, 0, 0, 6, 11,131,143, 34, 34,202, 30, 17,170,182,184, 68, 18, 68,104,209,
+129, 54, 44, 99,151, 10,132, 98, 11,225, 32, 72, 32, 0,120, 7, 84,141,244,101,174,201,135,126,210,165,202,246,221,231,210, 82,
+210,114,203,221,169, 17,148, 8, 97,237,186,161, 75,215,238,110,183,111,253, 61,103,195,239,235,127,100,236,244,122,142,230,150,
+ 91,242, 94,100,148,217,153,251,213,106, 42, 86,122,159, 30, 48,126,174,151,133,244,196,175,243, 87,121, 95, 57,181,243,114,122,
+106, 35, 46, 57, 57,213,194, 19,196,147,252,188,204,175,141, 89,113, 49,206,102,153, 82,169,172,174, 84, 42, 27, 53,108,216, 80,
+ 58,117,234, 84, 97,135, 14, 29, 94, 81,246,113,227, 68,151, 46, 93,242, 95,186,116,105,143, 71,143, 30, 89, 12, 6,195, 67,131,
+193, 16,143,114, 4,218,251,249,249,124,241,113,255,222,232, 52, 96, 50, 88,142,192,184, 73,223,224,204,169,131, 19, 0,252, 35,
+ 68,139,150,187,206, 29, 59,126,170, 79, 88,243,198,212,156,157, 49,144,137, 5,232,222, 44,148, 24,253,229, 12,247,205,171,231,
+108,130, 6,237, 75, 82,178, 56,147,118, 70,125,111,219,144, 62,225,193, 56,186,203, 54, 4,157,191, 7, 41,119,155,151,122,244,
+167,103, 0, 80, 61,226, 75, 23, 9,171, 94, 19,224, 78,169, 36,172,122, 77,245,136, 47,207,199,159, 94,163, 47, 45, 45, 66,137,
+164,202,174,157, 59,107,121,184,136, 32, 32, 9, 80, 20, 1, 1, 69,194, 98, 99, 49,232,147, 33,255, 88, 53,151,169,106,245, 32,
+129,209,142, 1, 27,127,154,115,158,159, 44, 79,153, 16,148,200,235,248,209, 67, 2,149,155, 4, 20, 69,128, 34, 1,138, 36,144,
+148,109,198,152, 49,163,221, 62,148,176,127,212, 90,213,124,218,224,208,238, 97,245, 61, 27,238,185, 65,184,133,125, 52,216, 75,
+ 99,145,143,218,125,228,226, 16,190,237, 55,183,120,158, 91,146,118,109,213,217,210,140, 88,173,214,236,238, 17, 31,185, 18, 2,
+133,252,252,225,173,237, 4, 36, 1,154,229,193,176, 60,216,194,179, 81,137,194, 25, 12, 73, 18,224, 57, 30, 99,199,142, 65,247,
+136,143, 76, 28,195,165, 57,223,201,145,219, 79,159,191,238, 99,165, 57, 44, 93,179,121,142, 81,171,158,147,240,204, 43,201,160,
+213,124, 99,206,121,238,244, 57, 24, 36,248,102,169,241, 81,227,119, 30,191,137,250,117,235,128,229, 28,233, 12,173,164,192,206,
+ 19, 55, 81, 59,180,182, 35,221, 28,143,144, 32, 37,154, 55,107, 14, 0,239, 69,180, 4, 18,151, 95,219,247, 28, 49,187,215,160,
+207,160,242,241, 1,201,211,189,206,159,216,217,235,207,223,150, 76, 99, 44,186,165,229, 50,198,179, 47,199, 5,158,227, 62, 88,
+117, 10, 8, 8,240,105,222,252,213,118,140, 12,195,160, 90,181,106, 72, 79, 79, 15,125,159,121,154,191,191,127,207,153, 51,103,
+170,122,244,232, 33,244,243,243, 3, 0,100,101,101, 5,158, 62,125,186,201,204,153, 51,115, 50, 51, 51, 79,160,148, 29,125, 88,
+154, 20,145, 2, 80, 82,169,220,241,142, 32,200,169, 95,124,218,208,215, 63,192, 90,210,239,213,234, 44,241,247,147, 47, 18, 2,
+129,168,240,247, 32,121,158, 35, 74, 81,137,186, 8,133,194, 18, 61, 20,118,202, 53,140, 23,186,125, 78, 82,164,163,178, 50,180,
+ 58, 63,229,126,157,114, 40,113,245,132, 98,209,250,143, 7,127,214,106,224,128,190,240,247,113,195,249,107,143, 48,225,139,111,
+105,198, 78, 47,127,175,206,131,162, 4, 57, 57, 57, 73, 30, 30, 30,126, 31, 62,222, 18,193,231,206,156, 82,157,191, 16, 57,125,
+217,202,213, 19,237, 54,134,230,120,254,229, 57,198, 50,153, 68,216,181,215, 39,174,170, 26, 97,210,213, 51, 63, 23,254, 31, 84,
+180, 54,252, 35, 68, 75, 44,115,249,228,151,239,191,148,206,221,113, 19, 39,214, 77,208,152,116, 26,159,151, 51, 5, 87,247,251,
+ 70, 93, 65,147,247, 73,161,210, 39, 36,156,160, 4,227, 9,138, 82, 16, 36, 33,230, 88, 46,149,177,217,230,153,115,159,127,240,
+166,149, 28,199,227,192,223, 57,229, 35, 64, 60,106,110,223,115, 72,229,235, 46,129,197,206, 98,240,208, 17,216,182,109,155,139,
+143,155, 24, 22, 27,131, 37,203,150,233, 13, 73, 39, 84, 73,169,249,233, 93,122,127,123, 54, 62, 49, 39, 42, 37,211,178,183,188,
+105,179,218, 89,232, 76, 12, 76, 86, 18,181,234, 53,199,146,229,181,165, 41,201, 9,223,110,253,115,211,148, 39, 79,168,109, 28,
+ 69,206,182,100, 62, 77, 45,177,209,249,213,239,238,234,225,181,171,255,248,249,238,207,115, 4,224, 97, 71,156,171, 20,159,140,
+154,226, 90,221, 79, 6,133,148,114, 79, 72, 78,247,159, 58,109,218,181,120,150,111,161, 83,199, 39,148,149,158,170, 85,171, 14,
+232,213,171,151,252,187,239,190, 19, 6, 5, 5,225,207,157,251,170,180,237, 62,168,119, 70,102,118, 16,207,243,240, 85,169, 82,
+199,142, 30,116,236,228,201,147,201,169,169,169,194,197,139, 23,183, 60,116,232, 80,221,172,172, 44,167,103,166, 44,207,195, 98,
+101,193, 22, 14,144,106,173,181,220,252, 52, 48, 48, 80,146,158,158,110, 45,166, 50, 16,175,132, 66,162,123,231,246, 45, 5,127,
+156, 74,132,193,194, 66, 33, 21, 34, 49,219,132,102,141, 27, 16, 27, 89,166, 81, 73, 6,199,124,210,115,134,175,146,143,232, 19,
+ 30, 12,149,135, 28, 91,214,206,199,209, 27, 9, 17,217, 6, 2,107,120,106,188,191, 68,208, 85,193,101,174,233,208,172,134, 95,
+167,166, 85,112,167, 89, 13,191, 43,247, 98, 98,101,131,150,125,153,110, 16,158,207, 63, 61, 69, 95,114,199, 67,194,211, 69,132,
+205,103,146, 33,151, 10,160,144, 10,160,144, 56,190, 73,146,248,176, 89,173,127,157, 32,138, 99,199, 80,148, 96,204,144, 79, 6,
+ 5, 12, 27, 50,136, 7, 69, 98,223,129, 99,125,119,236,216,158, 73,219,109,155, 88,146,218,252,174,250,243, 90,134,146,128,202,
+ 77,140,105,155,162,224, 42, 19,194, 69, 46,132,171, 92,136, 78, 13,125, 64,145,239,157, 68,143, 9,125,171,247,152,208,191,106,
+199,208,202,202, 90, 15,227,180, 79,198,204,187,187,242, 82, 65,199,175,215,174,168,235,101, 40,176, 9,126,157, 58, 86,144,150,
+145,209,113,223,177,203,157, 88,219,103, 49,140,221,248,147,250,209,190, 18, 85,225,180,152, 27, 77, 2,195, 6, 74,237, 6,250,
+241,195,152,180, 26,249, 86, 9,162,147,116, 80, 72, 5, 80, 22,229,173, 84, 0,133, 84, 8,165, 84,128,140,180, 68,228, 25,169,
+107,233, 94,100, 71, 92,190,193,148, 39,225, 22, 59,139, 7, 9, 6, 84, 13,109, 12,127,255, 0,216,122, 12,175,122, 43,242,192,
+145,219,151, 15, 47, 52,101, 61,251,201, 89, 59, 59,143,223,196,244,111,198,223, 35,128,251,133,131,116,147, 95, 23,173,107, 58,
+103,250,228,215,238, 77,157,189,186,233,251, 43, 89, 46, 51, 58,245,159, 52,187,109,215,254,208,231,101,227,239,179,123,209,189,
+215,199, 24,254,217, 87,112,119,247, 94,178,124,222,247, 15, 25,171, 46,242,173, 62,215,175,118,155, 6,245,235,236, 8, 12, 8,
+ 8,226, 56,199, 41, 31, 60, 15, 24,244, 90,124,255,245, 88,112, 60,143, 70, 77, 90,116,146,182,237,202,243,133,167,129,104,114,
+ 53,198,152,103, 79,186, 88,114, 98,110, 57,157,151, 22, 11,173, 86,171,241,224,193, 3,196,198,198, 34, 58, 58, 26,185,185,185,
+112,115,115, 51, 24,141,198,114,137,247, 13, 27, 54, 28, 22, 25, 25, 41,245,240,240,120,121,211,102,179,193,197,197, 5,195,134,
+ 13, 19,118,235,214, 45,176,103,207,158, 35,163,162,162,118, 2,208,149,152,158,188, 23, 25, 46,190,161,191,183,239,208,126, 34,
+ 0,200, 92,253, 19,214,252,121, 44,186,212, 9,173, 91, 64,149, 86,173, 90,215, 0,207,131, 0,191,202,148, 27,155, 85,138, 74,
+164,184,121,243,102,117,138,162, 4,175,198, 32, 14,191,109,217, 83,251,220,213,199, 3, 22, 45, 89, 42,117, 85, 72,160,214,218,
+240,249,240,254, 78,143,193, 50,223,208, 30,173, 90,181, 59, 50,103,246, 47, 2,165, 66,129,179,183,226,241,229,215,211, 44,153,
+ 73, 81, 75,121, 78,184,206,164,142,205,249,192,161,146,199, 63,128, 90,149,148,112,233,211, 93, 58,225,211, 62, 82, 27,205,162,
+192, 72,195,106,103,193,114, 60,180, 70, 26, 79, 82,244,240,118, 45,255, 81,110, 60,207, 55, 7,224, 3, 64, 77, 16,196,157,226,
+215, 69, 19,186, 34,110,252,198,181,166,112,124,240, 2, 96,131, 99,165,254,203,234, 83,120,253,174,251, 69,207, 63, 1, 80,167,
+208, 38, 11,224, 54, 65, 16,249,239, 32, 91,111,169, 92,130,227,199,143,243,189,122,245,122,217,227,191,121,253, 38, 36, 34, 97,
+128,194,205, 7, 60,255, 20,197, 15, 48, 86,249, 5,230, 46, 93,190,210,243,139, 73,227,147,117, 5,121, 85, 10,111,159,119,102,
+176, 16, 16,212,242,246,173,195,186, 77,156, 52, 9,161,213, 43,137, 88,150,229,163, 98, 19,232,173,155,183,140,186,114, 67,188,
+ 82,151, 22, 53,163,152, 4, 89,174,101,159, 44,199,166,189,169, 96,177, 28,251,230,236,246, 45,155, 4, 1,184, 43,197,248,253,
+ 84, 34,120, 30, 32,192,195, 77, 33,196,238, 75,105, 72,184,119, 80,215,171,145,206, 56,108,209,172, 78, 29,123, 76,137,124, 18,
+103,217,155,147, 99, 57, 3, 32,171, 52,155, 37,119,232, 28,172,118, 22, 52,195, 96,255,177, 99,136,232,212, 18,173, 90,181, 68,
+187,182,173, 4,119,239, 61,250,108,210,196,177, 65,120,181,186,227,165, 77,169,111,205,230, 74, 55,239,189, 3, 38, 46,118,121,
+156,198, 64, 64, 1,193,126, 50,120,186,136, 96, 99, 8, 36,169,237,133, 45,199, 29, 95, 78,157,237, 57,253,219,137, 39,117,106,
+113,125,224,169,189,180,119, 55,153, 76,226, 17, 35, 70, 8,105,154,182, 15,251,252,171,110, 89, 89,234,190,191,173,250,151, 68,
+165,242,133,201,194,224, 94,244,139, 58,115,230,204, 14, 62,118,250,210,225, 89,211, 38, 28,137,136,136,112,219,179,103, 15, 87,
+ 86,126,190, 54, 67,204,214,172,221,178, 99,255,182, 21, 75, 23, 32, 38, 57, 31,155,255, 88, 7,158,101,126, 47, 35,171,138,219,
+228, 71,140, 24, 33, 59,124,248,112,165,180,180, 52,157,201,100, 82,191,166, 71,144,132, 32, 59,207, 4,111, 23, 49, 68, 2, 18,
+190, 30, 82,168,220, 36, 16, 82, 0, 73, 16,108, 73, 54, 55,239, 61, 49,143, 51,105,113,116,151,109,200,150,181,243,241,217, 23,
+ 63, 35, 74, 35, 62, 77,202,221,230, 77, 30, 50, 96,186,143,140,141, 8,112, 39, 85,157,154, 86,133, 66, 42,194,143, 83, 70,160,
+197,189, 36, 85,122, 1,247,179,218, 76, 53,158,125,250,229, 97,221,231, 95, 23, 71, 28, 10,150,139, 92,136,211, 59,150,228, 24,
+181,106,109,145, 75,206,102,181, 36, 59, 89,141,207,151, 48,179,157,222,184, 65,189,249, 19,199,141, 33, 91,135,183,224, 73, 82,
+ 8,141,222, 70,240, 60,240,245,151, 19, 48,121,194, 88,191,212,140,156, 95,215,173,251,125, 70,228, 57,126,174, 81,253,108, 86,
+105, 54, 73,194,161, 2, 41,165, 2, 40,101, 14,226,162,148, 10, 96,177,177, 32, 8, 80,238,149,155,104, 9,135,146,155,145,151,
+252,206, 25,248,107, 54, 61, 43,215,187,112, 46,193,165,118,254,222,252, 27,137, 25,209,243,238, 61,202,190, 13, 32, 47,168,157,
+251, 72, 59,195,195, 96, 97,144,152,109, 2, 99,231,137,207, 62,170,130,106, 3,137,208, 5, 91,238,111, 59,245, 8,174,197, 58,
+253,215,108,166,223,220,111,241,170,223,127,240,138,213,127,220, 89, 58,255,103, 74,163,181,129,227,121, 72,197, 20,100, 98, 65,
+225,135,130,217,168,197,186,245, 27,179, 24, 16, 3,112,249, 50, 83,158,250, 9,142, 31,222,191, 71,187,221, 4, 32, 38, 72, 81,
+ 90, 64,149,170, 85, 58,247, 30, 37,237,220,103, 4, 88,198, 54,253,222, 85,254,162, 41, 39,230,130, 51, 54,235,215,173, 3, 2,
+184,111,204,137,157, 0, 0, 10, 85,200,239,181, 67,107, 55,125,243, 94,205,154,161, 77,157, 41,247,151, 74,169,212,229, 11, 15,
+ 79,159,159, 67,235, 53, 86,101,231, 91, 9, 23,175, 74, 72,124,254, 0,187,214,255,186,157,179,216,102, 95, 56,177,119,254,202,
+205,135, 62,233, 28,209, 31, 91,126,251,215,143,185,153, 47,137,214,249, 98,106,213,240,173,155, 54, 4, 9,197, 18,208, 12, 7,
+154,229, 29,223, 12,139,188,188,124,208, 12, 7,169,220, 5, 12, 71,128,102, 57,208, 12, 7,171,141, 81, 76, 24,209,115,146, 5,
+184, 85, 82, 58, 3,107,183, 63, 35,146, 72,170,240,112,156, 93,203,243, 60, 18,179,204,164,191,191,255, 78, 0,144, 72, 36,144,
+ 72, 36,224, 56, 14,247, 98,212, 95,120,135,134, 76, 68, 33,193, 99,237,182,228,130,164,235,221,223,245,238,126,126,126,189,223,
+ 36, 89, 22,139, 5, 6,131, 1, 87,111,220,113,219,180,109,127, 68, 98,114, 90,117,142,119,179,186,168,170,119,215,231,196,247,
+126, 87,126,234,179, 99, 38,185,134,141, 37,191,155, 60,178,230,234,173,199,111,191, 56, 51,175,212, 56,173,106,157,127,176,125,
+ 55,254,227,102,139, 86,109,126,158,127,253,247,111,202, 42, 35,129, 64, 32, 84,171,213, 47,219,247,154,141,187,154,221,143, 73,
+239,183,114,197, 74,233,189,120, 61, 30, 39,102, 96,100,151,202,142, 25,142, 19,229,174,240,173,238, 29, 92,163,198,206,117,171,
+ 22, 9,158,103, 88,176,246,224,109, 68, 30,249,253,106, 86,206,173, 8,100,103,154,223,167, 15,249, 7,136,214, 59,109, 94,124,
+164,129,193,194,192,106, 99, 64,115, 60,116, 38, 26, 57, 5, 54,232, 76,118, 24,204, 12, 70,118,173, 92,226,115,101,240, 17, 31,
+130, 32,142,243, 60,223,139,231,249, 46, 0,196, 69,215,142, 49,155, 56, 94, 72,200, 94,187,158, 62,125,250, 79, 11, 23, 46,140,
+ 46,250,109,209,253,162,223,150,118,191,216,243, 94, 63,254,248, 99,253, 69,139, 22, 45, 8, 15, 15,223,253,247,223,127, 39, 0,
+200,119,214,125, 40, 40,254, 50,199,143, 31, 47, 43,163,171,219,105,187,196, 85, 38, 68,112,181,202, 24,253,211, 22,239,191, 22,
+141,201,145,138, 5,212,169, 83,167, 60,115,109, 74,144, 36,229,244, 20, 69,233, 83,171,149, 72, 36, 62,177,108,217, 50, 12,233,
+221, 86,150,162,161, 13,143, 82,204,217, 70, 27, 24,149, 79,136,120,222,130, 69,202, 69,139,151, 76, 62,126,148, 43, 48,100, 63,
+ 89, 82,178,139,175,217, 93,138, 40, 22,131, 69, 16,224, 57, 54, 45, 63,233, 78, 51, 0,248,144, 88, 44,131,133, 6, 85, 24, 91,
+ 67, 16,128,201,194,128,162,136,156,130,152,189, 79,134,205,157,215,105,251,238,115, 25, 60,233,174, 55, 26, 19,229,112,156, 57,
+ 88,110, 88,108, 44,172, 52,139,232,135,247,208, 46,172, 46, 90, 53,171, 13,147,133,133,201,202,160, 90,141, 80, 0,240, 46,177,
+224, 40, 50,129,103,105, 11,207,179, 46,189,154,251, 64,229, 46,134,191,135, 4, 18,177, 0, 52, 3,152,109, 28, 44, 54, 22, 73,
+ 57,102,232,205, 50, 52,104, 63, 40,216,203,255,174, 53, 43, 73,118, 56, 47,229,238,128, 82,201, 41,203, 98,235,206,253, 53, 51,
+ 50,178,251,158, 60,188, 67,162,214,209,120,148,100, 68, 78,129, 21,160,124, 48,115,193, 90,201, 15,223,140,235,183,117,215,129,
+228,206,109, 91, 38,151,247,157, 77,234,152,237,123,247,237,255,189, 87,175,126,178,232, 91, 39,241,252,193,133,249,198,156,114,
+197,103,145,141, 26, 53, 98,198,141, 27,167, 95,176, 96, 65,208,209,163, 71,171,169,213,234, 7, 0,104,119,119,247,218, 33, 53,
+171, 60, 60,123,250, 84, 96,207,126,131,132,105, 26, 51,220,228, 34, 84, 81,201,113,227,234, 25, 90, 44, 22,150, 24,111, 82,232,
+ 30, 28,138,206,223,227,232,141,132,136,232, 92,233,165,177, 99, 70, 38,159,189, 18,147,187,102,219,217,127, 5, 42,233, 7, 82,
+ 78,189,230,110,179, 26,126,211,191, 28,129,133,171,183,227,242,189,152, 28, 35,233, 63, 63,211,202,156,123,183,148, 14, 8, 40,
+ 2, 46, 50, 33,140, 58,181, 54,238,254,233,144,127, 72,166, 30,121,246,240,118, 50, 79, 79, 35, 85, 99, 33, 50,242,244, 96, 57,
+ 30,238,114, 17, 24,142, 71, 65,158,134,216,177,125, 27,238,220,185, 65,130, 34, 63, 7, 48,171,212, 12, 37, 28,174, 66,165, 84,
+232, 80,132,100,142,111,154,229, 16, 90,179, 6, 54,172, 89,238,234,173,242, 69,155,118,206,199, 70,187,120, 85,105,180,251,207,
+ 53,184,244,247,253, 14,151, 87,174,109,174, 12,240, 89, 77, 16,236, 82,240,176, 88,237, 44,180, 5,249, 16,219, 82,209, 34, 80,
+ 13, 79, 57,139, 36,157, 63,162,178,158, 43,203,234,240,115,163, 14, 61, 32,248,126, 51,246, 31,139, 92,216,189,107, 7, 68, 37,
+233, 32, 19, 11, 32, 21, 83,144,138, 41, 8, 9, 22,203,215,255, 78,231,107,245,189,114,163,143,104,222,163,126,158, 47,156,253,
+ 58,200, 29,107,240,217,190,122,198, 95, 99,191, 95,220, 61,162,255, 40, 34,234,206,197,159, 76,192, 5,231, 38,122,188, 83,247,
+ 56,206,249, 49, 78,234,226,189,106,202, 15,243,166,116,235, 53, 8, 20, 37, 0, 77,211, 56,176,103, 59,254, 92, 59,243,153,205,
+144, 59, 10, 0,103,203,161,198,237,221,190,126,208,247,191, 46, 39,234, 55,106,209,242, 98,230,219,199,209,114, 20,241,199,167,
+ 99,198, 15,246,245,245,117,121,165,104,241, 8, 9,173,139, 30,125, 62,198,153, 35,135,240, 36,250, 17, 56,222, 65,152, 56,142,
+ 71, 65,126,110, 22, 67,219,182,190,211,227, 33,149, 86,217,242,231,182, 90, 36, 73,188, 60, 64,254,155, 73,163,109, 19,190,254,
+169, 77,143,110,237,163,197, 20,116, 73, 41,153,238, 55,238, 63,109,192, 9,149, 65, 99,166, 46, 23, 89,172, 44,180, 38, 26, 39,
+ 55,191,155,235, 72, 61, 42,135, 87,109,218, 99,204,132, 95, 54, 72, 36, 20,105,175, 23, 18,148,208, 62,172, 94,106,229, 0,111,
+253,156, 69,107, 91, 92,187,117,191,199, 39,195,198, 72, 71,214,110, 74, 4,120,201, 92, 70, 15,235,223,144,101,236,159,154,242,
+ 82,223,185,191,160, 80,238, 81, 80,185, 90, 77,211, 43,197, 40,228, 32,193, 35,248, 53,230, 65, 32,193,156, 29, 59, 0, 0,252,
+ 3, 42, 91,132, 18, 87,125, 57, 20, 24, 30, 0, 86,111,220,213,236, 97,108,198,216, 21, 43, 86,202,239,197,235,241, 32, 94, 11,
+137,136,132,157,230, 64, 56, 41,106,115, 60, 53,254,231, 31,167,187,230, 27, 89, 92,122,164, 70,244,221,139,188,205, 96, 25, 38,
+103, 92, 7, 64,229,242, 41,128, 26, 0,226, 8,130,255,195,152,237,119, 4,184,204,148,183,222,115,156, 99,190,236,234, 83, 61,
+152, 21, 72,122, 8,197,138,112,130,224,235, 17, 60, 60, 0, 62, 61,175,112, 76,117,150,169, 25,179, 99,177,120,193,175, 88,181,
+233, 16, 50,114, 45,112, 99, 83,113,100,243, 60,124,183,112, 39,204,214,119, 71, 53,148,197, 71, 74, 34, 70,111, 18,174,162,191,
+139,126,183,112,225,194, 94,111,148, 77,175,119,148,217, 91,191, 43,122,126,209,162, 69, 11,138,253,187,201, 89,146,245,146,104,
+ 21,189, 84, 25,100, 43,196,199,191,202,223, 71, 14, 31,244,200, 55,216, 33, 21, 81,168, 92,173, 38,102,173, 57,226,243, 81, 51,
+111,104,236,110,216,181, 97,105,158,197,164,223,227, 84,103,161, 10,109, 41, 83, 42, 78, 30, 60,112, 8,213, 43,171, 68, 59,174,
+230, 37,222, 79, 48,191,148,122,117,234,100,113, 53, 87,147, 96, 64,255,254,242, 11,145, 23,191, 54, 0, 37, 18, 45,138,160, 42,
+109,220,118, 64,229, 34, 19,130, 32, 0,189,153,193,216, 79, 63,254,240, 97,140,231,168, 49,163, 70,130, 40, 36, 89,186,220, 44,
+252,244,195, 36,139,130,126,254, 36, 37, 41, 37,189, 75,239,239, 46,232, 12,132,101,240,136, 73,119,158,196, 46,204, 55,153,222,
+239,144, 31,171,141,133,213,206, 33, 62, 62, 14,223,140,236, 10, 33, 69,130,162, 56, 71,176, 52,243,238,202,104,200,136,205,131,
+159,104,224,246,101, 95,108, 12,240, 85,121, 41, 21, 50, 94, 41,151, 16,245,106,215, 18,133,133,181, 18, 87, 11,109, 40,186,250,
+212,140, 20,181, 25, 9, 25, 90, 72,124, 27, 11,134,116,250, 8,219, 87, 78,237,144,151,114,151,196,219, 65,138,175,225,220,165,
+155,189, 55,173, 95, 33,201, 46,176,227, 89,138, 1, 89,249, 22,100,230, 91,145,149,103,129, 82, 38, 68,187, 62,227, 36, 39,142,
+252,209,187,115,219,150,171,223,231,189, 19, 18, 18, 79, 36,165,103, 14,106,216,164, 5,182,255,245,103, 91,119,247,106,174, 5,
+ 5,137, 58,103, 75,103,222,188,121,226, 69,139, 22, 9,214,172, 89,163, 11, 11, 11,243,251,241,199, 31,187,231,228,228,220,174,
+ 90,181,106,232,153,131, 91, 35, 27,183,235,219, 28,156,221,167,109,251,142, 34, 9, 39,192,217,227,199,237,123,247,236,200, 53,
+155,245, 19, 74, 37, 28,114,183,121,217, 6, 2, 62,129,129,209, 74, 49,219, 85, 64, 22,196,230,159,158,178, 45, 31, 56, 88, 61,
+226,203,243, 23,239,198,196, 54,187,151,164,138,188,247, 34, 39,207,100, 15,137, 63,253, 93,169, 29, 47, 69, 16, 16, 82, 36, 92,
+100, 2,144,133,189,170, 50,160,225, 11, 16,132, 79,145,114, 74,128, 40,252, 6, 8, 2, 25,249, 41, 15,156,136,217, 32,120,142,
+ 7, 98,210,140, 48, 88, 28,210,124, 37,111, 57,212,217,105,248,109,245, 86,220,191,123, 7,221, 62,234,131,117, 27,119, 96,236,
+167,131, 44,101,205,126, 72,178, 80,209, 42,166,102, 41,101, 2, 0, 4, 10,140, 52, 14, 92, 75, 69,141, 96,210,233,129, 1, 0,
+ 92,148,114,104,245,102,144, 34, 23,196,221, 59, 41, 63,117,241,214,143, 51,230,174,152,150,159,249, 40,229,197,227,171, 8,245,
+214, 34, 56,208,142,232, 44, 87,220,205,173,134,208,154,213, 65,138,238, 56,101, 91, 19,221, 96,241, 17,242, 64,175,102,141,235,
+134, 87, 81,185,195,108, 99, 11, 85, 45, 10,127,110,217,134,164,196,180, 49,185, 79,142,220,255, 39, 24,173, 49, 39, 65, 45, 81,
+213,156,252,248,214,133,132,254,195, 38,195, 63,176,114,163,130,148, 7, 78,135, 45, 56,115,143,117,146,104,137,228,238, 63,126,
+243,243,191,166,116,235, 57, 16, 55,175, 94,192,131,232, 56,180,108,217, 28, 31,245, 27, 2,189, 46,175,246,190,109, 43,187, 50,
+ 38,253, 25,129,132,153,210,162, 85, 39,130, 99, 89, 60,127, 22, 21, 87,146, 45,115,102,204,131, 27,153, 49,174,175,185,167,188,
+107, 55, 82,186,121, 62,176,218, 89,164,167,167,225,250,223,151,154,152, 51, 99, 30,148, 39,191, 36, 34, 10,103,239,231,192, 94,
+120,134,105,187,246, 93,109, 34,210,218,118,254,138, 45, 97,153, 25,153,164,194,213,155,243, 12,172, 35,242,151,216,173, 15,227,
+181, 34, 59,205,161,122,128,162, 84,155, 62, 1, 53, 23, 76,157,250, 77, 29, 74, 36,131,222,104,181,101,102,164,251,109,216,117,
+209,240,244,217,227,192, 74, 42, 55,215,127,173,252, 67,164,179, 16,200,209, 90,145,167,215, 17,195,198,127, 31,176,105,237,194,
+225,165, 17,173, 18,194, 69,130, 79,156,189, 90,219,195, 69, 68, 24, 44, 12,151,171,179,179,195,250,125,216,162,203, 66,146, 53,
+110,197,242,149,242,251,241,122, 60,140,215, 66, 42,162, 32, 22,145,176,209, 28,156,108, 78,164,159,202,111, 66,171,102, 13,112,
+230,129, 6, 20, 69,194,172,207, 55, 9,144, 27,219,172, 67, 55,121,211, 22, 97,232,216,161, 61, 94,196,198, 84, 62,126,244, 64,
+231, 27,215, 47,103, 49,246,144, 47,140,234,216, 67,229, 18, 22, 76, 38,138, 22,251,141,246, 15,172,218,122,192,144,209,110, 85,
+ 42, 7, 18, 42,111, 47, 48,188, 0,227, 62,253,216,233,150,239, 32,230,192,162,185, 63,194,106,181,193,199, 93, 12,158, 7,182,
+172,158, 5,155,205,134, 0, 47, 9,180,198,119,159, 38, 87, 22, 31,121,151, 10, 85,174,216,147, 98,100,172,180,251, 4, 65, 28,
+159, 62,125,250, 79, 0,248,233,211,167,255, 84,116,189,112,225, 66, 51,128,140, 50, 92,135, 27, 94, 35, 90, 69, 47,247,238,214,
+ 45, 10,245,246,242,191,113,246,204,105,183,195, 15, 57,220, 60,116, 23, 61, 91,250, 67, 36, 32, 33,119, 11,192,195, 68, 45, 78,
+ 28, 92, 95,112,100,247, 31,233, 86,171,117, 73,217,190,230,154,205,148,114,197,153,191,182,239,225,188,189,188,200,223,206,170,
+227,115,245,204, 75,151, 86,236,173,163,220,221, 51, 27,252,121, 16,167,165, 82,105, 77,155,205,230, 81, 86,193,110, 57,155, 92,
+ 24,196, 75,252, 19,125, 43, 8,138, 98,183,239,216, 14,111, 87, 49,172, 52,135,233,211,190, 50,143,236,166, 44, 24,246,201,144,
+ 78, 29,123, 76,137, 20, 42,106, 93,104,213,164, 22,223,184,113,227, 2,138,162,156, 10,165, 80,169, 84,179, 72,146, 28, 42, 22,
+139, 93,108, 54,155,222,198, 89,228, 70,139, 13, 22, 59, 96, 50, 89, 32, 20, 57,200,162,144, 34, 96,182,216, 96, 50,219, 74,111,
+ 24, 89, 81,215, 0,132,232,138,105, 74, 23,158, 86, 23,239,220,119,228,171,129,159, 12,158, 17,216,168,159, 50, 49, 83, 11, 17,
+ 97, 71,243, 58,254,184,120,250, 16,159,150, 20,251, 77, 89, 36, 11, 0,114,212,121, 65, 62, 62,190,184,159, 96, 64,122,174, 25,
+ 89,133, 36, 43, 51,223, 10,189, 89,143,134, 85, 2, 80,160,213, 6,189,119,254, 2,135,206,156, 57, 51,168, 71,223,193,152, 50,
+109,118,155,205,235,151, 62, 82,136,133,159, 25,179,159, 95,114,134,104, 69, 69, 69,229,253,240,195, 15, 53, 54,110,220, 72, 14,
+ 31, 62,220,220,160, 65, 3,233,136, 17, 35,218,108,219,182, 77, 42,151, 75,205, 15,175, 30,157,241,249,151,211,251,110, 88, 53,
+175, 81,126,126, 62,193,208,244, 41,123,126,254,116, 67, 25,100, 46,245,232, 79,207,102,198,219, 71,117,109,235,115,212, 83, 78,
+214,147,240,182, 33,168, 51,107, 15,158,206,178,199,159, 94,163,151, 13, 90,246,101, 70, 1,247,179,133, 84,205, 47,139,100, 1,
+ 0, 73, 17,176, 49, 44, 92,100, 66,144, 36, 89, 68,226,253,255,220,115, 74,238,227, 38,134,144, 34, 33,160, 8,232, 76, 52, 52,
+ 58, 59, 38,143,118,118,135, 16,158, 99, 88, 30,102, 27, 3, 83,225,236, 80,175,211,224,199,105,223,226,163,222,253,241,249,132,
+111,145,111, 6,238, 38,232, 97,167,233, 50, 27, 5, 73,144, 48, 89, 25,124,214,173, 10,242, 12,118, 24,205, 12,108, 12, 7,185,
+ 88, 0,161,128,132, 66, 42,128,171, 92, 8,240,188,168,168, 51, 17, 10,133, 22,154,166,183,151, 50,163, 71,181, 32, 95,152,105,
+ 18, 45, 6, 47, 69,151,240, 16, 68, 95, 59, 32,184,124,243,113,240,215,211,126,198, 87, 99,123, 99,255,179, 26,240, 84, 85,129,
+ 82, 33, 3,205,147, 0,120, 39, 3,246,102,113,164,189,255,208,223, 55,110,137,153,243,235,116,105,129,145,128, 68, 68, 33,242,
+194,121,220,184,117,119,149,230,201,145,237,248, 7, 33,228, 73, 95, 87, 87, 87, 72,197, 20,108,118,171,205,249,208, 5, 30, 60,
+208, 68,161, 10,249,189,112,198,223,132,229, 80,194,189,178,137,150, 64,234, 58,253,139,105,115, 22,116,235, 57, 16,103,143,239,
+199,190,253,123,216,240,136, 49,212,142, 63,215,163, 77,151, 62,104,211,109, 48, 78, 29,218,246,173,145, 35,234,142,155, 50, 99,
+110,187, 78, 61,112,246,196,126,100,103,165, 45,115, 54,189,148,144,152,210,169,107,111, 88,108, 44,218,118,238,133,211,199, 14,
+125,137,194, 69, 22,206, 15, 98,111,244,207, 32,153,111,191,153, 34,204, 41,176, 9,213, 58, 27,210,212, 38, 36,102,155,112,100,
+247,102,222,249,254,194,214,188, 93,195, 74,194,113,139, 35, 83,131, 42,249, 91,133, 86,179, 44, 54, 46,190,246,231,163, 71, 10,
+131,107,214, 38,115,180, 86,168,181, 86,104,180, 86, 24, 44, 12,106, 86,170, 69,210, 12, 17, 94,222,114,246,118, 19, 11,215, 29,
+ 75,128,171, 66,136, 86,181,223,127,161, 45,199,113,175, 72,214, 10, 7,201,122,148,160,133, 68, 68, 65, 34, 34, 33, 17, 81, 96,
+ 88,222,169,137,139, 76, 21,210, 99,242, 23,147, 2,108, 12,144,171,181, 65, 64, 17, 80,121,123, 40,154, 55, 26,138, 45, 75,191,
+ 4, 0,140,253,225, 55,124,254,217, 8,212,169,215, 0, 5,249,249,126, 67, 7,246, 88, 1,224,144,179,105, 61,121,246, 82,229,
+179, 87,238,255, 48,121,234, 76,229, 39,189, 59, 82, 15,226,181,200,204,179, 34, 46, 86,189,197,216,208, 0, 0, 32, 0, 73, 68,
+ 65, 84, 95, 46,229, 13, 0, 24,150, 3, 15, 30, 91,247, 28,135, 76, 44,128, 90,107, 7,207,243,152,183,102, 47, 92,100, 66,100,
+230, 59,220,253,165,161, 84, 62, 82,138, 34, 85, 14,181,177, 23, 28,177, 92, 62,206, 42, 90, 11, 23, 46,140, 94,184,112, 97,137,
+ 10, 89, 49,146,245,126,135, 74,139, 68,138,218,174, 94,222, 55,207,158, 62,233,114,232, 33,139,139, 15,115, 49,176,109, 37, 24,
+242, 82,176,100,218, 39,121, 4,120, 27, 73, 81, 5, 86,179,233,160,217,108,156, 15,192, 94,106,165,241, 11,105,162,144, 42,207,
+175,219,240, 23,227,173, 82, 97,251,213,188,180,124, 35, 67,191,114, 91,209,196,221, 51, 27,130, 25,142,142,176,100,191,184, 83,
+214, 76,156,227, 33, 90,184,254, 8, 0, 30, 28,199,129,231, 56, 8,165, 74,133,119,245,176,236,194,142, 78, 42, 32, 9, 75,241,
+ 30,128,231,152, 52, 77, 66,233, 50, 40, 1,192, 77, 46,196,158,203,233, 0,144, 77,233,239, 61, 29,246,137,195, 93,104,177, 73,
+117,245,106,212,224,155, 55,111, 94, 32,147, 57,181,253, 21,229,235,235,123,123,198,140, 25,181, 63,255,252,115,137, 88, 44, 6,
+195, 48,158,127,108,216,192,109,152, 63, 22, 3,190, 92, 7,145, 88, 2,179,197, 14,161, 80,128,124,173, 1, 5, 58, 19,244, 38,
+186,252, 53, 40, 62,222,166, 6, 22, 31, 62, 36,238,223, 93,217,176,133,152, 20,161,105,168, 63, 46,158, 57,204,223, 60,189,101,
+172, 57, 39,246, 47, 39, 43, 34, 12, 22, 26, 25,185, 22,164,231, 90,144,149,111, 65, 86,158, 21, 89,249, 22, 16, 4, 1,139,141,
+249,160,129,203,152, 19,179,111,251, 95,155,250, 88,237, 24,210,174, 91,127,124, 59,115, 93,149,237,191, 47, 58,159,192,147,173,
+157, 12,180,101,163,163,163,147, 70,143, 30,221,104,215,174, 93, 84,253,250,245,205, 79,159, 62,149, 23,146, 72,187, 82, 41,151,
+109, 94,187,240, 76,139, 22, 45,118,167,199, 62,139, 44,244,167,151,217,177, 87,105, 63, 74, 34,179,223, 31, 87, 89,209,170,123,
+117, 63, 57, 42, 43,244,221,107, 43, 31, 46,201,237,244,213, 2,117,228,170,156, 76, 43,115, 78,109,166, 26,167, 27,132, 78,197,
+224,209, 86, 75,242,128,129, 67, 64, 17, 36,236, 22, 83,114, 81,229, 82,185,137, 49,107,199, 51, 40,165, 66,184,200, 4, 80,202,
+132,104, 83,215, 19,229,232,207,120,154,229, 96,178,178, 48, 91, 25, 88,108, 12,188,131, 60,176,113,251, 62,164,228,152,113,228,
+142, 6, 49,201,122,212,170,164, 0,207,151,221, 77,114, 44,109,236,253,241,112, 23,138, 36, 64,145, 4, 89,183,118, 8,242, 12,
+118,136, 4, 36, 68, 82, 25, 20, 18, 1, 92,101, 66,136, 68, 66,228,228,228,192,106,181,162,114,229,202,210,210,169, 32, 15, 23,
+165, 12,181,130, 3, 96,167, 25,156,188,242, 4,243,191, 25,128,174,237,154,129, 16, 42,241,204,218, 4, 46,158, 46,224, 72, 18,
+118,134,131,205,206, 2, 32, 45,239,178, 23, 20, 20,212, 73,161, 80, 40, 76, 38,147, 62, 37, 37,229, 82, 86,204,161, 20,150,234,
+ 59,238,244,217,200,237,189, 62,234,138,251,143,162,177,255,208,209,171, 26, 47,237,212,162,103,234,213,171, 23,230,237,237,173,
+204,205,205,213, 69, 69, 69,221,126,223,121, 1, 79,146, 95,135,183,233, 0, 67, 65, 14,178, 83, 19,157,158, 69,215,169,226,130,
+ 95, 22,174,107, 26, 26, 18,218,148,229, 29,196,171,110,101, 23,124, 55,115,117,211, 26,181, 66,154, 22, 45, 8,169, 83,185,244,
+109,217, 4,114,151,110,159,126,254,237,194, 62, 3, 71, 33,242,236, 81, 44,159, 63,109,187,194,205,167,142,167,135, 91,227,250,
+ 97,221,112,245,252, 81, 72, 93,252,224,225,229,215,102,248,103, 95,116, 25, 56,124, 60,110, 92, 61,143, 85,139,126,218,198, 90,
+245, 59,157, 73,171, 66, 21,236,211,168, 73,139, 97, 46,158,190, 40,208,234,225,226,161, 66,157,134,205,135, 61,121,104,253,193,
+152,147,160,126,111,210,193,243,176,218,121,228, 27,236, 72, 85,155,145,148,229, 32, 90, 28, 87,142,152, 32,150, 35,148, 82,129,
+192,147,126, 81,249,241,249, 72,190, 74,144, 47,177,120,238, 52,202, 14, 41,212, 5, 14,146,165,214,217,160,214,218, 96,176,208,
+240, 84, 8,192,177, 92,185,103,221,249, 6, 59, 92,228, 66,184,201, 69, 78,171,140, 37, 97,253,159,123, 66, 31,198,102,244, 91,
+190,124,165,252, 65, 66, 49,146, 37,116,168, 89, 18, 17, 5,150,227, 0, 39, 90,188, 80, 32,156,210,183, 71, 23,164,106,204,142,
+ 85,203, 36,129, 90, 13, 90,192, 91,198,161,243,224,233, 0,128,222, 61, 28,161,109, 9,153, 70, 28,187,169, 6, 94, 15,236, 46,
+189, 47, 54,155,169, 13, 59, 78,124,189,111,239,110, 55, 11, 43,192, 31,167,146, 96,178, 50,144,138, 40, 72, 68, 20,100, 34,234,
+181,120,236,178,137,150, 35,230, 46, 69, 67,195,100,177, 64,103,166,193, 3,184,253,194, 0,179,141,129,214, 72, 35,172,182,199,
+135, 9, 33, 4,113,130,231,249,158,111, 18,162, 55,201, 82, 49, 69,170, 36, 27,119,138,219, 40,250,253,187,136, 92,241,152, 45,
+ 0,229, 90,193, 37,120,147, 57, 22,191, 22, 41, 60,234,184,185,184,221, 60,125,234,184,242,208, 67, 14,151, 30, 57, 72, 22,109,
+214, 96,217, 15, 67,211,116, 5,154,142, 0,226,157,253,207,228,222,117, 26, 74,197,146,200,127,173,252,195,174,242, 13,228, 14,
+222, 44,200,209,154,216,215,216, 4,107,181,146, 60,199,139, 44,217, 47,156,242, 33,144, 36, 97,159,249,101,127,112, 60,143, 89,
+ 43,247, 97,193,212,193, 80,202,134,203, 9,130,144, 27, 45, 12,190,153,189, 9,203,126, 25,227, 34,151, 8, 64, 16,142,152,168,
+ 79,135,244,119,174, 2, 90, 24,196,221,218,101,208, 39, 28,127, 90,220, 93,216,178,205, 71,119, 91,182,108, 89,224,225,225, 1,
+153, 76,246, 74,169,120, 7,124,125,125,127,153, 57,115,102,232,132, 9, 19, 94,110,246, 41, 16, 8, 48,121,210, 36,146,101,121,
+156, 58,181, 5, 62, 85,155,224,232,185,155,136,232,212, 28, 6,147, 5,121, 5,122,112,160,222,187, 34,234, 11, 52,145, 89, 73,
+143, 91,180,238,216, 27,151,206, 28,230,111,158,218, 60,182, 60,123,244,120,120,122,164,222,123, 28, 87,135, 32, 60, 29,138, 86,
+ 33,201,178,209, 28,170,248,202,145,154, 20, 7,119, 55,183, 84,103,237,201,124, 66,251, 18, 36, 63,129, 0,191,197,152,253,124,
+ 31, 0,222,152,249,116,232,190,157, 27, 30, 69, 71, 61,152,223,107,216, 20, 65,183,129,147,168,223, 23,126,241, 19, 0,103, 55,
+222,179,199,196,196, 60, 25, 51,102, 76,171, 27, 55,110,176, 0, 76, 4, 65,208, 20, 69,201,109, 54,155,168, 99,199,142,218,103,
+207,158, 93, 70,201, 65,139,175,161,205,232,125,222,132, 68,255,145,152,179, 15,173,226,162,239,218,177,109, 56,194,235, 5, 33,
+181,109, 56, 0, 76, 73, 54, 40, 67, 45, 53, 54,237,161, 25,217,201,223,255, 60,182, 96,236,224, 46,223,108, 23,204, 90,158,121,
+124, 86,169,129,168,169, 79, 47,119, 47,137,198, 11, 40, 18, 46, 50, 33,148, 50, 1, 92,100, 66,184, 72,133,160, 25,190, 60, 51,
+ 71,158,102, 56,135,162,101, 99, 96, 48, 51,136,124,144,141, 44,173, 13, 5,122, 59,204,118, 22, 60,120,199,108,212,137,222, 92,
+253,226,186,123,209, 72,234, 94,185,137,118,195,154,165,174, 7,174,165,189, 92,209,231, 38, 23,195, 69,238, 88,141,125,229,202,
+ 21,120,121,149, 61,219,231, 56, 14,251, 79,223,198,242,173,145, 56,189,229,123, 72, 69, 20, 26,246,157,141, 81,253, 90,130,227,
+ 57,196,197, 68,103,215,170,219,200,151, 36,101, 32, 9, 2, 86,154, 3,192,191, 51, 63,109, 54,155, 87, 74, 74,138,174,102,205,
+154,126, 1, 1, 1, 3, 41,138,226,161,127, 96, 61,188, 59,207,116,225,248, 78,185,209,108,101,229,140,118, 75,205, 76,115, 79,
+212,172, 9,130, 32,120, 87, 87, 87, 81,100,100,164,161, 65,131, 6, 62,239,217,148, 72,153, 42,100,213,231, 19,191, 30, 88,163,
+122,117,236,219,185, 5, 60, 79, 28,112,246,225, 29,199,110, 96,238,143,175,175, 48,252,110,230,234,166,203,102, 79,121,237,222,
+196, 31,151,151,186,234, 80, 38, 81, 78, 29, 48,116, 28,238,222,254, 27, 75,102,127,183,219,106,200, 27, 69, 51,244,160,188,204,
+132,221,193,117, 91,130,183,235,113,118,239, 82, 12, 30, 49, 86,210,173,215, 64,220,184,122, 30, 11,126,154,184,195, 84,144, 51,
+ 26, 78, 6, 57,115,188,112, 66,199,238,253,132,102,171, 29,171, 23,255,138,241, 83,231, 35,172, 83,111, 97,212,131,155, 19, 0,
+204,113, 58, 28,194,206,162, 99, 3,111, 7,121,166, 57, 28, 77,160, 4, 37,213, 64, 1, 69,144,141,171,187,195,108, 99,160, 43,
+ 99, 82, 41, 16, 9,179, 10,180,186,170,107, 23,124, 77, 25, 45, 12,212, 90, 27,114,180, 86,104, 10, 94, 17, 44,141,214, 10,181,
+214, 6,161,128, 64,108,124, 50, 72,161,160,220,241,121,249, 6, 26, 45, 66, 60, 28,109,244, 61,189, 35,180,192,181,229,233,203,
+ 15, 7, 44, 95,190, 66,250, 48, 81,143, 71, 9,186, 66, 37,139,130, 68, 72, 66, 92,248, 55,203, 57, 98, 35, 75,131,171, 79,245,
+224,145,159, 14,239,236,170,148, 33,227,121, 14, 4,148, 99,139, 24, 55, 85, 16,220, 36, 22,124, 49,113, 28,188,189,220,145,162,
+177, 98,213,161, 88, 60,122,242, 2,156,185,124,175,189,250,143,221, 17,159, 79,254,206,157, 20,138,177,237, 76,162, 35,157, 20,
+139,103, 55,143, 89, 50,226, 30, 27, 13,186, 92, 30, 60,235,100, 12, 50,193, 51,172,163,186, 45,152, 53, 29,187,183,254,134, 51,
+247,114, 94,214,192,107, 7,150,225,235, 31,231, 65,163,179,161,164,122, 89, 26, 31, 1,160, 46,166, 68,189,117, 93,140, 28,149,
+116, 77, 20, 94,219,222, 97,195,246, 6,185,178,189,113,223,246,134,189,146,246,254,219, 80,166,235,240, 45, 82,228,238, 83, 95,
+ 46, 85,252,125,234,212, 49,197,225, 71,252, 75,146,101, 55,105,248,249, 83,122,167,233, 10,212,221,202, 69,178,124,106,213,151,
+200, 37,151,103,204, 91,101,245, 13,172,202,156,124,160,203,213, 91, 88,230,237, 24, 4, 5,171,112,243,177, 8,196,146,229, 66,
+179,237, 87,141,230,169,177, 44,229,137,227,121, 28,191,149, 5,158,119, 76,145,246, 94, 73, 71,225,204, 28, 44,231,112,171,156,
+123,144, 3, 65, 97, 28,138,179,242,247,250, 63,126,211,245,108,160, 53, 14, 91, 48,235,165,187, 48,172,145, 67,201,114,117,117,
+133,187,187, 59,148, 74, 37,202,114, 29, 18, 4,241,233,231,159,127,254,214,236, 63, 39, 39, 7, 93, 58,119,196,154,223, 54,162,
+ 81,231,145, 56,119,253, 12,236, 52,135,134,117,171,163,106,128, 7, 82,179,245,239,213,208, 21,190,161,147, 91,116,236,247, 83,
+155, 78,189, 17,121,250, 32,127,243,244,159,227,202,187, 17, 98,207, 46,173,142,205,157, 59, 43,120,198,252,181, 18, 23,169, 0,
+ 79, 13, 54,144, 4,129, 42,190,114,120, 41, 72, 92, 58,188,205, 50,184,119, 43,167, 55,199, 11, 10, 10,220,190,108,205, 6,197,
+178, 69,179, 59,222,189, 71, 68, 26, 50, 98,243, 0,192,148, 29,179,248, 25,240,164,210,223,103, 79, 54,106,223, 31,190, 1,213,
+187, 38,100, 63,115,154,108, 0, 48,197,199,199, 39,204,152, 49, 35,116,209,162, 69, 60, 69, 81, 28, 0,201,202,149, 43, 77,207,
+159, 63,127, 0,199,210, 92,148, 53,216,116,238, 90,239, 27,165,152, 13,243,148,147,245,170,251,201, 17, 94,207,225, 21, 29,220,
+179, 13,130, 42, 87, 70,124,150,169,113,158,137, 19, 26,108, 84,245,117,127, 60,186, 83,205,155, 26,203,152,109, 79, 0, 28, 41,
+111,249, 16,120, 21, 32, 95,164,102,185,200,132,224, 28,117,165, 92, 68,203,106,103, 97,182,178, 48,219, 24, 24,109, 44, 76, 54,
+ 22, 28,239,104, 19, 4, 65,192,206,112,112,106,218,252, 70,221,119,245,244, 70,245,106, 4, 92,229,142,180,185, 22,110,247, 64,
+ 0,240,242,242,130, 74,165,114, 74, 21,181,217, 29, 77,220, 70,115, 47,221,250, 54, 59, 3,158,231, 17, 27, 27,243,125, 82, 66,
+ 66,223,154,181,106,182,171,219,176,145,167, 92, 66, 2,192, 59,137,150,201,100, 98, 93, 92, 92, 84,158,158,158,100,122,122,250,
+ 75,242, 92,179,113, 71,230,208,193, 3, 24, 48,160,191,225,233,237,135, 47,151,184,155,205,102,162,117,235,214,174, 65, 65, 65,
+164,213,106,213,149,183,152, 20, 62, 33,253, 60,188, 60,231,127, 58,122,124, 72,199, 46, 17,184,120,225, 44,142, 28,220,245,151,
+ 73, 29,123,214, 89, 35,161,161,181,223, 90,117, 88,163, 86,200, 91,171, 14,171, 6,215, 42,149,104,213,109,216,188, 37, 79, 8,
+112,230,248, 94,222, 66,218, 39, 2,224, 88,139,126,239,158,245,191,204, 25, 58,225,199, 26, 61,250, 12,197,167, 35, 70, 65, 32,
+160,112,233,220, 49, 44,155,253,237, 9,131, 54,103,164, 51, 97, 2, 14,233,173,142, 40, 80, 22,244, 85,229, 26,245,113,239,230,
+ 85,196,197, 70, 69, 63,188,115,163, 94,205, 6, 97,240, 9,168,242, 85,178, 55,181, 8, 79,159,218,203, 50, 99,179, 88,146, 71,
+141, 28,129,226,171, 14,195,155,132,122, 17,111, 54, 0, 0, 38,125,142,125,243,210,111,158, 23,173, 58,228,236,182,228,119,217,
+213,230,171,247, 95,186,126,107,106,223,158, 17,164, 70,103,115, 40, 88, 90, 91,225,199, 10, 77,209,223, 58, 43,106, 5, 40, 17,
+ 19,125,143,179,104, 53, 7,202,217, 46, 45,163, 6,117,127, 82, 84,119, 57,142, 7, 1, 88,202,237,150, 18,186,142, 91,188,100,
+185,244, 97,130, 1,143, 18,117, 14, 87,161,144,114, 16, 44, 33,249,146,116, 57, 86,179,151,161, 14, 17,212,130,207, 70, 14,129,
+ 70,103, 7,199, 1, 2,138, 44,252,136,144,162, 39,144,170, 55, 65,147,175, 70, 66, 82, 50, 10,178,226, 64,146, 36,188, 3, 66,
+156,222, 73,154,229,197,254, 38, 27,223, 96, 96,207,118,130,131,127,103, 66, 46, 17,192,170,207,198,169, 61, 75,213, 86,131,110,
+190,217,100, 56,232,204,126,142,175, 66, 16, 8,181,206, 96,241,149, 8, 41,236,219,186, 22,131, 70, 77,124,173,247,253,254,231,
+185, 0, 73, 32, 47, 95, 15,130, 32,212,229,235,151,136, 59,165, 93,191,167, 50,246,193, 54, 74, 32, 91,111, 79, 20,222, 61, 27,
+229, 79,157, 61,125, 76,113, 45, 73,130,219, 49,153,133, 36, 75,205,205,251,178,103,154, 94,155,215, 29, 64,108,249,230,133,100,
+247,193,159, 77,141,174, 30, 82,215,122, 49,202,144, 88, 96,164,223, 25,231, 16, 62,112, 70,244,221, 19,107,122,104,233,248, 73,
+ 10,255,186, 44,199, 48,139,205,234,216,217,239,112, 29,138,103,175,218,247,210,109,248,195,162,109,142,191, 89, 22, 44,207,129,
+231,128, 47,126, 89, 15,134, 99,193,177, 44, 56,150, 7,205,242,242,178,146,171, 10,168,122, 48,255,217,222,218,195,230,188,237,
+ 46,116,119,119,135,151,151, 23,188,188,188,224,234,234, 90, 38,209, 18, 10,133, 74,129,224,245,172, 78, 78, 78, 70, 82, 82, 18,
+ 92, 93, 93,193,115, 52,108, 52, 80, 63,172, 27, 30,199, 69,225,252,181, 7,224, 57, 22, 10,101,249, 79,121, 81,248,134, 78,106,
+222,161,239,218, 78,125,198,224,220,193, 63,248, 59, 87,142,141, 55,231,196,110,114, 90,161,103, 89,130,166,105,244,236,214, 33,
+249,126,244,139,211, 63, 79,157, 16,209,170,215,120, 73,120,104, 32, 44, 54, 22,105, 73,113,184,116,248, 79, 75, 72,176,255,153,
+206,109, 91, 38,211, 52, 13,150,101,203, 28,200, 45, 54,187,134, 18,202, 20, 67,134, 12, 19,222,185,125,251,128,194,167,214, 62,
+150, 32, 31, 18, 60,215,144,224,249, 1, 13, 27,214,129,157,230, 96, 50,233,242,203,251,206,122,189, 62, 97,203,150, 45,193, 35,
+ 71,142,148,215,173, 91, 87, 24, 23, 23,135,101,203,150,229,234,245,250, 4,103,109,156,189, 18,179, 82, 64,228, 63, 47, 82,180,
+ 82,218,132, 99, 72,175, 54,216,125,226, 26, 46, 93,189,129,100,131,242,129,129, 17, 28, 78, 77,206,176,214,243,212, 29,232, 19,
+ 94,149,218,183, 53,255, 64,116,135,233,159,240,188,228,172,230,242, 44,163,243,141, 27,208,155,105,184,202, 29,251, 61, 21, 41,
+ 91, 20, 65, 56,205,136, 8, 32,225,234,141,123,245,155,213,170,139,251, 9, 90,228, 20, 88, 97,182, 50,224, 56, 30, 28,120,120,
+185,136, 33, 21,145, 72, 73, 74, 0,199,219, 19,203, 57, 84,168,219,183,107, 47, 0, 8, 16, 4, 47, 16, 10, 4,224,225,216, 95,
+ 81, 38,147, 25, 84, 42,149, 83,138,150,157, 97, 48, 32,162, 37,194,154, 55, 68,223,241,142, 61, 51, 47,252, 53, 29, 30, 74, 33,
+118,111,223,132,212, 43, 43,183, 7,135, 79, 56, 27,245, 56,250,227,232,251,127, 15,251,168,169,172,177,159, 32, 67,244, 46,153,
+212,104, 52, 30, 0, 32, 22,137, 68, 17,237,218,181,243, 60,112,224, 64,129,183,183, 55, 39, 22,137,212,125,122,247,226,132, 34,
+ 81, 94,209,111,175, 95,191, 46, 28, 63,126,188, 75,126,126,126, 74,118,118,246, 13, 0,116,233, 19,193,208, 46, 32,177, 11, 4,
+ 33, 85,202,228,201,213,170, 85, 15,104, 30,214,210,173,223,128, 65,144,136, 37, 56,119,246, 52, 86,175, 88,180,215,144,249,244,
+179,242,228,228, 63,181,234, 48, 45, 37, 49,193,100,182, 54,168,223,172, 3,113,245,236,225, 41,118,120,175,160, 36,246,165, 93,
+ 6, 76,172,145,144, 97,192,234,133,223,195,195, 77,129,196,184,103,230,231, 79, 31,175,167, 45,186,239,157, 38, 89, 0,228,185,
+236,199,225, 35, 34, 60,172,118, 22, 87, 34, 79, 88, 56,134,139,184,113,249,100, 92,165,144,230,210,250,205, 59,123,104,142,108,
+ 26, 96, 2,118,151,101, 39,253,217,219, 10, 46,111, 43, 72,188, 16,121,222,205,183, 74, 61,138, 0, 1,187,213, 2,117,252, 29,
+198,148,253, 76,167, 75,143,114,106, 21,110,110, 42,126,249,113,230,191, 38, 53,111,214, 76,193, 67,250,154,130, 85, 68,176, 52,
+ 58, 27,188, 93,196, 48,235,212,120,126,231,180,197,164,166, 74,221,239,140,177, 25,229,154,156,108,241,171,112,134,216,176,210,
+126,175,201,201, 22, 51, 54,163,188,236,161,142,130,171, 66,140,199,137,233, 47, 3,223, 37, 66, 71,108,150, 88, 72,189,140,211,
+ 42,234, 11,202, 64, 7,145,212, 29,233,185, 22, 16,224,193,177, 12, 24,218, 6,189, 78,135,244,140, 44,100,103,101, 67,175, 47,
+128, 92,233,129,250,141, 91,192, 69, 33,197,195, 75,123,193,243,188, 83,251, 26,210,132, 48,180,121, 88, 91, 73, 84,146, 35, 22,
+ 75, 42,228,113,108,215,162, 92,131, 46,167,173, 33,243,249,243,242,246,197, 12,203,158,127,244,228,121,189, 74,254,213,136, 7,
+113, 90,108,223,184, 6,182, 66,101,147,166, 89, 68,165, 24,145,153,103, 66, 74,252, 83,158, 99,217,243,248, 31,129,224,221, 2,
+ 32, 4, 13,235,215, 65,183,225,253,240,219,111,235, 17,159,144,196,205,159,210, 35,197,160, 47,248,168, 28, 36,171, 11, 10,247,
+218, 48,101,199, 44, 54,123, 52, 79, 59,122, 63,143, 52,219,248, 82, 3,124,164, 62, 85,208,246,179,101,103,204,250, 60, 49,107,
+ 53, 9,142,109,255,108, 87, 73, 54, 29, 12, 26,182,249,223, 13,134, 82, 38, 0, 65, 16, 40,114, 23,174,155, 59, 14,114,137,195,
+183,108,182, 50, 24,254,205,114,108, 95,254, 45,120, 0, 67, 7, 93, 51,189, 43,157,112,156, 93,248,133, 63,110, 87, 74, 78,202,
+ 73,239,210,251,187, 11, 22,187,196,218,171,255,200,187,205,154, 53, 43,144,201,100,144,201,100,112,117,117,133,135,135, 7,220,
+221,221,203,124,119,154,166, 13, 54,155,205, 75, 44, 22,131,227, 56, 36, 38, 38, 34, 49, 49, 17, 90,173, 22,106,181, 26, 70,131,
+142,185,125, 97,159,160,126,120, 15, 4, 84,111,128, 42,181, 26, 65, 72, 17, 16, 8, 72, 92, 58,186,241, 93,233, 44,153,100,181,
+239,179,174,115,223,207,113,238,224, 6,254,206,149, 99, 19,204, 57,177, 27,157, 45,163, 66,119,207,195, 1, 3, 6, 52, 24, 63,
+126,188,104,230,212,241,103, 78,156,189, 20,187,239,248,134,222,249,249, 5, 65, 60,207,195,221,205, 45,117,112,239, 86,199, 58,
+182,110,158,124,225,194, 5,110,215,174, 93, 86,130, 32, 30,151,102,211,209, 73,229,252,117,225,124,228,172,182,237, 59, 96,211,
+214, 93,237,163,159, 60,109, 31, 23,247, 28, 65, 85,170,163, 90,112, 45,152, 8, 15, 68, 94,190, 10, 67, 65,206, 95,206,164,243,
+ 13, 85,139,200,207,207,255,123,240,224,193,221,174, 93,187, 70, 14, 30, 60,216,164,209,104,174, 23, 83,177,248,178,108,222,248,
+189,191, 26,192, 95, 85,218,143,218,155,110, 47,248, 10,192,162,202, 85, 42,227,210,213, 27,184,113,237,214,122,141,188,242,236,
+207,134,143, 30, 87,181, 15,245,121,159,240,170,148,202, 67,142,157, 27,150, 81, 71,111, 36, 45, 79,202,101, 55, 45,186, 60,107,
+174, 51,101,244,114,224,208,219,209,186,142, 39,104,150, 7,199, 59, 58, 92, 23,169,240, 93, 29,239, 91, 54, 5, 54,201,103, 19,
+198,143,143,171,223,176,241,215,195, 71, 79, 16, 53,174, 30,132,219, 47, 10, 0,130,128,167,159, 2,153,153,153,184,178,127, 3,
+147,159,254,108, 61, 69,113,115,202,145,159,200, 79,126, 80,179,216,229, 56,141, 70,131, 75,151, 46,161,136, 96,249,248,248,188,
+139,104,189,102, 51, 55, 59,227,250,220, 37,127,180, 30,251,105,127,244,234, 80, 15,151,239,196,193, 86,184, 95, 83,209, 82,242,
+132, 27,191,139,191, 26, 92,221, 54,105, 64,136,206, 76,139,147,126, 73,212, 94,129,227, 12, 86,238, 29,233,180,229,229,229, 29,
+141,137,137,105,211,168, 81,163,170, 39, 79,158,204,139,190,117,102, 74,241, 68,124,247,221,119,202,223,126,251, 77,206,243,252,
+117,155,205, 22,239,212,187,147,216,121,239,238, 93, 47, 59,205,225,234,173,135,117, 58,183,110, 12,142, 7,238,220,185,131, 77,
+155, 55, 89, 30, 63,122,176,212,152,237, 55,167, 20,242, 82, 98,126,178, 31,182,234,240,165,205,204,244,164,165,231, 78,236,223,
+222,188,125,111, 12,251, 98,206,156, 75, 39,118,205,106,218,182, 23, 89,167,121, 55,220,187, 17,137,243, 39, 79,255,203,110,200,
+155,133,178, 99, 71, 74, 76,167, 68, 38,255,178,110,211,246, 72, 73, 78, 66,226,243,168,191, 44,121, 47, 50,146,227,168,191, 50,
+210,146, 39, 4,215,107,141,107,103,118, 79, 41,133,104,149, 90,231,131,124,100, 27, 78, 30, 63, 58, 36, 45,237,119, 63,163,217,
+ 34,225,121,222, 34, 17, 11,178,148,164,126,143,206,233,116, 62,181,171, 51,170, 14, 24, 52,124,194,137,213,171, 87, 8,125,221,
+229,200,202,183, 64,103,182, 67,111,178,131, 36, 8,212, 12, 80,192,164,207,195,229,253, 75,104,155, 33,127, 48, 16,103,127,151,
+ 77,133, 42,116, 94,254,139,200, 47,190,155,120, 17, 98,183,160,128,106,157,126, 44, 85,173,211,167, 63,232,253,221,196, 99,161,
+ 60,207,119, 86,168, 66,245,198,156,152, 25,239,122,119,130,112,180,239, 97, 29,131, 96,103, 28,251,143, 49, 28,192,114, 92,161,
+202, 7,240, 47,253,249, 68, 25,239, 78,112,123, 78, 92, 71, 70,118, 1,204, 54, 26, 86, 27, 3, 59,205,130,164, 40,184,123,184,
+163, 86,181, 38,112,115,119, 69,118, 86, 6,110, 92, 56,138,216, 71,151,175, 19, 60,102,155,213,207, 47, 56, 83, 70, 34,153,123,
+168,127,128, 31,153,169,179, 65, 38,166,240,224,242, 73, 59,109,179, 46,117,146,100,189,101,179, 32, 55,111,249,215, 83,167, 13,
+253,115,203, 86,191, 6,193,174, 72,211,152,145,166,182, 64,111,161, 11,137, 24, 7,171, 65,131, 71,145, 91,179, 88,139,126, 57,
+254, 71,240, 78,162,197,216, 45,250, 3,167,111,123, 77,159,181,132,122, 17, 23, 79,207,251,170,103,154,217,160,235, 81,110, 37,
+171, 24,254,156, 28,188,251,223,241, 18,111,185, 11,121, 14, 28,207,227,216,173,172,151,238, 66,174, 48,242,242,126, 92,233,199,
+ 8, 22, 63,187,176, 67,143, 41,231, 30,197,232,119,152,205,217,110,207, 94, 44,205, 7, 0,138,162, 94,126,138, 98,179, 44, 22,
+139,173, 12, 23,202,182,141, 27, 55,254, 48, 97,194, 4, 73,106,106, 42,226,226,226, 80, 80, 80, 0,169, 84,138,211,167, 79,211,
+224,152,165,143,174, 29, 74,140,185,119,246,215,208,102,221, 42, 53, 8,239, 1,185, 92, 1, 1,239,124, 48,166, 92, 21, 50,164,
+ 89,251, 62,107, 59,247, 27,139,243,135, 54,242,119, 46, 31,157,104, 86,199,110, 40,111, 94, 22, 20, 20, 68, 3,120,190,116,233,
+210,198,155, 54,109, 10,158, 58,117,106,252,182,181,179, 86, 3, 64,110,110, 46, 0,224,254,253,251,252,196,137, 19,173, 22,139,
+ 37, 33, 63, 63,255, 30,202, 88, 0, 1, 0,102,181,124,193,166,117,139,234,167,166,103,246,175, 94,191, 5,124,130, 91,192,175,
+102, 75,228,235,237,184,253, 34, 3,241, 79, 47,224,233,213,253, 39, 77, 74,102, 22,202,185,191,113,163, 70,141,130, 72,146,172,
+102, 48, 24,252,234,214,173,219, 72,161, 80,220,111,212,168, 81, 19,129, 64,144,118,247,238,221,164,242,216, 74,190,188,213, 90,
+165,253,168, 85,201,122,151,142,241, 89,166, 38,201,122,151,251, 38,137,219,183,234,200, 85,214, 63,169,192,229,188, 93, 19,189,
+111,171,238,192,206, 13,203,168,225,227,190, 99,163,180, 30, 95, 9,100,226,115,229,147,171,201,204, 73, 35,251,190,218,222,161,
+ 80,201, 42,252,219, 41,153, 94,171,125,164, 5,240,195,163, 39,194,181, 81, 95,141,159,219,176,121,235, 17,237, 62, 26, 76, 50,
+ 34, 37,206, 28,250,157, 79,120, 20,185, 79,192,179, 63,155,157, 56, 13,160, 76,119,144,205,230, 12,201,122, 59,141,169,138, 14,
+251,118,109, 30,117,224,208,193,133,253,250,244,245, 90,247,203, 39, 88,242,199, 97, 40,100, 18,240, 28,135, 79, 58, 6, 13,252,
+245,243,218,189,131,124,165,129, 7, 46,166, 93,249, 98, 69,212, 15, 38,147, 61,214, 9, 37,134,215,104, 52, 87,149, 74,165,186,
+ 77,155, 54, 97, 18,137,132,208,104, 52, 2,149, 74,197,184,185,185,217,210,210,210, 76, 86,171,245, 0,128,114,109, 59,110,167,
+ 57, 36,102, 91,112,228,224, 1, 60,188,117, 1, 79,159,198,232,159, 62,121,186,134, 16,240, 43,140,217,207,243,128,114, 79,240,
+193,149,184,234,144, 47,247,170, 67,214,170,223,185,109,253,188, 78, 38,139,117, 84,163, 86, 61, 81,181, 78,107,210, 78,179,120,
+124,231, 34, 46,238, 95,177,196,110,200,155,254, 33,101, 28, 80, 41,184, 22, 79,137,241,247,165, 19,224, 57,110, 61, 0,240, 28,
+183,254,254,181,147, 19, 90,246,248, 28,158,170,170,141, 10, 82,238, 19,120,143,221,195, 69, 2,210,120,234,192,159,135, 18, 19,
+ 19,241,236,217, 51,188,120,241, 2,121,121,121,216,185, 51,177, 92,229, 99,202, 79, 58, 23,251,132,236,254,241, 39,195,142, 13,
+ 28,242,169, 52,184, 86, 3, 50,180,146, 7,188,148, 2,196,188, 72, 66,236,221, 71, 92,204,237,147, 22,187, 46,167,159, 57, 63,
+233,157,196, 79,238, 93,199, 23, 96,167, 23,157, 93, 24, 30,222, 58,116,218,252,133, 97, 94, 62,170, 18,251,241, 92,117,142,248,
+251, 47,142,134,222,184,249,183, 83,103, 29,114, 44,155, 59,110,212, 96,142,114, 28, 20,138,151, 58,117, 97,238, 57, 38, 83,142,
+251, 60,199,148,169,224,143,238,223, 22, 12,199,193,104,182, 67,103,180, 66,171,183, 32, 51, 39, 23, 15, 31, 61,194,229, 99, 71,
+ 17, 23,243, 48,129,182,217,206,146, 36,177,223,156, 29,123,185,124,158, 38, 65,176,151,167, 39, 18,242, 12,144,138, 5, 72,138,
+189,107, 53,234,180, 59,222,183, 30,153,115,159,103,230, 80, 68,183,193,131,135,156,238,212,189,143, 91,243, 86, 93,228,222,174,
+238, 16, 9,120, 60, 79,204,192,189,235,167,141,241, 15,175,232,104,155, 33,226,159, 56,245,229, 63, 28,101,175, 58,180, 91,141,
+189,135,246,109,127,144,162, 4, 98,142, 99,172,118,155,245,227, 15, 33, 89,255, 46,240, 60,155, 54,106,104,255,215,230, 6, 12,
+199,203,134, 14, 58, 99, 46, 62, 87,160, 89, 94, 62,116,208,117,147,163, 3,121,119, 96,159,191,191,103,207,162,179, 11,147,147,
+115,239,228,229, 89, 47, 2, 72,179, 88, 44,239,157,198,236,236,236,185,243,231,207,239,101, 50,153,106,119,232,208, 65,226,234,
+234,138,220,220, 92,156, 61,123,150, 62,126,252,248,147,156,156,156, 95,129, 28,198,140, 38,127, 61,178, 28, 26, 25,115,247,236,
+175,181,155,117,175,212,160, 85, 15,231, 59, 51,137,108,108,167, 62, 99,136,243,135, 55,242,183, 47, 29,158,100, 86, 63,255,227,
+ 3,178,213,110,177, 88,110, 89, 44,150,168,159,127,254,185,185,175,175,175,239,175,191,254, 42,213,233,116,194,117,235,214, 89,
+ 52, 26, 77,150, 78,167,187,129, 82,226,105,222,198,125, 90,155,142, 1,167, 14,108,236,200, 31,216,216,213,221, 59,176,155,155,
+ 79,165, 26, 5,234,244, 4,173, 58,227, 44,128,243,133, 27, 69,150, 11,141, 27, 55,174, 78, 16,196, 96, 0,245, 21, 10, 69, 77,
+165, 82, 41,225,121,190, 54, 65, 16,209, 28,199, 61,170, 91,183,238,241, 39, 79,158,148,107, 51,217,228,203, 91,173, 65,161,173,
+119,229,153, 56,145,141, 20,237, 74,190,188,213, 10, 0, 57,231,166,153, 0, 28,121,210,225,135, 1, 71,111, 36,173,142,206,119,
+155,162,190,180,240,104,121,211,172, 77,123, 88,243,159,170,255,150,204, 39,105, 0, 70, 61,186,139,101,143,239,223,152, 73,240,
+ 16,178, 96,230,153,115, 94,220,253, 39,236, 11,133, 66, 75, 96, 96, 96,137,171, 11, 37, 18,137,197,106, 45, 77, 64,185,204, 24,
+ 50,177, 9,104,191,245,224,222,173,163, 14, 31, 61,178,176, 93,231,126, 94,210, 74,149, 80, 77, 69, 96,235,244,166, 83, 46,220,
+ 87,223,238, 51,237,202,111,241, 25,150, 71, 40,103, 60,140,193, 96,136, 5,144,111, 48, 24,250,242, 60,159, 74, 16, 68, 80,126,
+126,254, 3,154,166, 31,151,155, 16,112, 24, 22, 30,222, 98, 39, 65, 16, 2,158,225, 22,223, 16, 82,187, 44,153, 79,211,240,129,
+199,146, 52,168,230,138,111,126, 93,213,180, 70,205,144,166, 69,103, 29,214,171,234,130,241, 63, 44,107, 90, 53,184, 86,211, 87,
+231, 31,150, 25, 38,192,211,166,252,207, 14,110, 94,124,229,254,205,139, 63,121,251, 87,173,154,149, 22,255, 52,245,197,131,185,
+172, 69,119,240, 67,203, 57,241, 69,244,138, 77, 75,127,152,154,153,158,176,201,164,126, 30, 5, 0, 38,245,243,168,167,247,240,
+139, 38, 43,109,106,110, 78,252,210,247,205, 11,163,209,152,177, 99,199, 14,247,214,173, 91,147,190,190,190, 80,171,213,184,120,
+241, 34,199,113, 92,122,185,109,229, 37, 92, 52,230, 17,158,127,253,177,118,177, 72,225,210,131, 97,152, 0,158, 7, 4, 2, 65,
+166,205,164, 59,173, 39, 21,211,144,159,100, 41,125,204,224, 8, 0,100,209,217,133, 28,199, 17,139, 87,111, 77, 18, 74, 93, 74,
+220, 12,145,182,232,229, 28,199, 57,125,214, 97, 65,202,189, 26,255, 84,251, 38,120,126,118,163,102, 97, 63,209,180,221, 82,216,
+ 62, 44, 0, 44, 60,143, 92,146, 36, 46, 83, 28,125, 70,247, 1,147, 41,130,128, 43, 79, 8,224, 34, 19,128, 0, 1,131, 54,143,
+ 47, 79, 76, 86,137,132, 56, 39, 54,218,148,211,190,202, 41,219,222,145,145,231, 78, 14, 98, 89,182, 90,161,102,144,104, 53, 27,
+247, 25, 50, 61,254, 2,238, 50,248,191,143, 19, 69,100,139,248, 55,255, 71, 78,185, 81,254,147,108,134, 6,203,250, 86, 10,244,
+ 29,153,152,148,115, 59, 62,213,244, 23, 94, 63, 86,231, 67,210, 73,249,250,250,254, 66, 16,196, 8,177, 88,172,180,217,108, 70,
+158,231,183,101,103,103,207,197, 91,135,255, 54, 17,202, 84,230,145, 98,169,124,134,221, 98,252,219,148, 19, 59,172,172,119,151,
+251,132,116,147, 42, 20, 63, 88,204,198,109,166,236,216,173,255,112,126,186, 73, 36,146, 38, 74,165, 82,168,209,104,110, 1,208,
+254, 39,149,123,163, 70,141, 42,147, 36, 89,141,227, 56, 95, 0,110,112,172, 10,209, 8, 4,130,244, 66, 69,139, 47,175,205, 54,
+163,247,121,119,238, 90,239,155,179, 87, 98, 86, 22,186, 21, 95, 34,112,224,114,233,136, 30, 29,255, 63,246,238, 59,172,169,235,
+255, 3,248, 59, 11, 18, 72, 32,236, 61, 84,134,184,192,162,181, 78,220,171,226,182,110,173,187, 86,127, 90,173,117, 87,176, 85,
+235,168,117,213,182,246,107,213, 58,234,174, 85,220,180,206,186,131, 34, 56, 0, 65, 4,100,143,144, 1, 36, 33,201,249,253,193,
+ 40,181, 76, 71, 91,237,231,245, 60,121, 88, 55,239,220,155,220, 27, 62, 57,247,220,115, 62,254,241,240, 47,149, 93,117,248,218,
+237,243,127, 95,102, 71,190,196, 57,251,125,174,169,116, 89, 87,191,162,130,236,212,167, 83, 47,221,205,186, 14, 64,249, 34,235,
+105, 98, 98, 50, 74,167,211,153,153,152,152, 20,234,116,186,221,255,150,109, 55,115,240,155,192, 5,171,245,204, 20, 70,112,110,
+ 61,115,209,202,155,178, 47,241,252,253,253, 59,152,152,152,120, 24, 12, 6,115,173, 86, 91, 80, 88, 88,248, 56, 49, 49,241, 10,
+170,158,248,252,149,174,167,216,193,119,157,137,137,112, 38, 0,232,116,154, 13,234,204,216, 89,213,221,177,154,229, 95,235,215,
+200,174,126,203, 88, 62, 79, 96,143,210,129,185,141,122,125, 86, 70,194, 77,223,127,112, 61,201,115,190,184,148, 73,153,148, 73,
+153,207,226,210,243, 73,153,255,100,166,200,185,177,187,200,185,113,173, 7, 93,174, 98,121,122, 62, 73,153,201,149,220, 0,212,
+ 98,192, 82, 66, 8,121, 5,140,244, 20,144,127, 82, 81,218,253,228, 87,185, 60,249,207,169,178, 79, 52,167,154,170,180, 46, 77,
+130,207, 83,217,134, 83, 38,101, 82, 38,101, 82, 38,101, 82,230,127, 46,179,166,236,215,241,148,228,228,103,126, 62, 14,224,111,
+233,240, 79,205,170,148, 73,153,148, 73,153,148, 73,153,148,249, 95, 83, 94,120,113,233,185, 32,132, 16, 66, 8,121, 53,168,143,
+ 22, 33,132, 16, 66,200,139,169,236,212, 33, 21, 90,132, 16, 66, 8, 33, 47, 65,149,157,225,233,212, 33, 33,132, 16, 66,200,139,
+ 41,107,209,114,198, 51,195, 59, 80,161, 69, 8, 33,132, 16,242,114,164,161,178,214,173,176,176, 48, 86,217,247,132, 16, 66, 8,
+ 33,127,135,215,188, 22,169,216,146, 53,185,244,103, 0, 21, 90,180,168,192, 34,132, 16, 66,200,191,165,216,122,205,148,181,100,
+149,221,210,254, 82,104, 5, 7, 7,115,168,216, 34,132, 16, 66,200, 63,229, 77,172, 69,184,207,110, 32,189,204,132, 16, 66, 8,
+249, 39,139,173, 55,105,123,104,120, 7, 66, 8, 33,132,144, 23,227, 12,160, 79,133,159,255,182, 41,120, 8, 33,132, 16, 66,222,
+116,147,171,250,153, 90,180, 8, 33,132, 16, 66, 94,126,177, 69, 8, 33,132, 16, 66, 94,103, 52,179, 57,101, 82, 38,101, 82, 38,
+101, 82, 38,101,190,233,202,198,209, 2,170, 26, 71,139, 16, 66, 8, 33,132, 60,151, 62, 40, 25, 63,107,114,233,215, 62, 84,104,
+ 17, 66, 8, 33,132,188, 92,127,153,126,135, 10, 45, 66, 8, 33,132,144,151, 91, 96,125, 79,133, 22, 33,132, 16, 66,200, 43, 70,
+133, 22, 33,132, 16, 66,200, 43,194, 65,213, 87, 14,132,215, 33,231,121,174, 62, 8,167, 76,202,164, 76,202,164, 76,202,164,204,
+255, 92,102, 77,217,225,120,253,148,141, 12,127, 28,127,116,132,255,254,239,120, 96,186,244,149, 50, 41,147, 50, 41,147, 50, 41,
+147, 50,223,116,147,159,249, 90,142, 78, 29, 18, 66, 8, 33,132,188,220, 98,139,166,224, 33,132, 16, 66, 8,121, 73,170, 60, 77,
+ 72, 45, 90,132, 16, 66, 8, 33, 47,166,202, 73,165,169,208, 34,132, 16, 66, 8,121, 53, 5, 23, 21, 90,132, 16, 66, 8, 33, 47,
+177,200,154, 92,233, 95,195,194,194, 24, 61, 71,132, 16, 66, 8,249,167,188,177,181, 72,217,134, 81,177, 69, 8, 33,132, 16,170,
+ 69,234,204, 25,127, 92,109, 56,185,244,103, 0,116,213, 33, 33,132, 16, 66,200,139,234,131, 63, 95,121, 56,185,236,103, 42,180,
+ 8, 33,132, 16, 66, 94,220,228,106,255, 74,167, 13, 9, 33,132, 16,242, 79,122, 19,107, 17, 14,189,172,132, 16, 66, 8, 33, 47,
+164,178,214,172,239,233,105, 33,132, 16, 66, 8,121,181, 5, 23, 33,132, 16, 66, 8,121, 21, 69,214,171, 30,176,148,102, 54,167,
+ 76,202,164, 76,202,164, 76,202,164,204,255, 74,145, 85,113,136, 7, 0,116,213, 33, 33,132, 16, 66,200,139,162, 73,165, 9, 33,
+132, 16, 66, 94, 17,154, 84,154, 16, 66, 8, 33,228,111, 46,184,168,208, 34,132, 16, 66, 8,121,137, 69,214,159,138, 45,234,163,
+ 69, 8, 33,132, 16,242, 98,170,236,163,197, 65,213, 87, 14,132,215,225, 1,158,231,234,131,112,202,164, 76,202,164, 76,202,164,
+ 76,202,252,207,101,214,148, 29,142,215,223,100,252, 77, 3,150,210,165,175,148, 73,153,148, 73,153,148, 73,153,148,249, 95, 67,
+195, 59, 16, 66, 8, 33,132,188,236,194,234, 89, 84,104, 17, 66, 8, 33,132,188, 24, 26, 71,139, 16, 66, 8, 33,228, 21,113, 70,
+ 73,171, 86,217,215, 64, 42,180, 8, 33,132, 16, 66, 94,142, 62, 40,105,213, 42,251, 74,133, 22, 33,132, 16, 66,200, 75, 84,233,
+ 56, 90, 28, 0, 8, 11, 11, 99,165, 63,119, 10, 14, 14,190, 64,207, 21, 33,132, 16, 66,254, 78,111,106, 45, 82,222,162, 21, 28,
+ 28,204, 98,130,209,125, 0, 0, 32, 0, 73, 68, 65, 84, 1,112,158, 94,106, 66, 8, 33,132,252, 19,222,196, 90,132,251, 76, 37,
+217,137, 94,102, 66, 8, 33,132,252, 19,222,196, 90,132,255, 76, 21, 73, 8, 33,132, 16,242,143,120,141,107, 17,103,148,116,132,
+ 63, 94,250, 21, 40, 29,242,129,198,209, 34,132, 16, 66, 8,121, 49,101, 87, 27,254,101,234, 29,106,197, 34,132, 16, 66, 8,121,
+ 49,149,141, 12,255, 61, 61, 45,132, 16, 66, 8, 33,175, 16,181,104, 17, 66, 8, 33,132,188,184,138,173, 90,127, 91,107, 22,205,
+108, 78,153,148, 73,153,148, 73,153,148, 73,153,255,165, 34,235, 79, 63,211,200,240,132, 16, 66, 8, 33,175, 8, 93,117, 72, 8,
+ 33,132, 16,242, 98,202,174, 56,172,248, 51, 21, 90,132, 16, 66, 8, 33, 47,177,216,250, 11, 58,117, 72, 8, 33,132, 16,242, 98,
+ 38, 87,245, 7, 42,180, 8, 33,132, 16, 66, 94, 81,193,197, 65,213, 87, 14,132,215, 33,248,121,174, 62, 8,167, 76,202,164, 76,
+202,164, 76,202,164,204,255, 92,102, 77,217,225,120,253,252, 99, 3,150,210,165,175,148, 73,153,148, 73,153,148, 73,153,148,249,
+159, 69,167, 14, 9, 33,132, 16, 66,254, 5,133,150, 61,159,207, 95,104,102,102,246,141,153,153,217, 22, 62,159,255, 37, 0,235,
+186, 62,160, 88, 44,158,225,228,228,244,192,201,201, 41,197,195,195,227,132,133,133,249, 71, 94, 66, 4, 1, 16,188,164,237,241,
+ 3,240,145,153,153,217,125,145, 72,148, 8, 96, 23,128,143, 0,216,189, 72,240,231, 46, 24, 28, 53,179,255,145,207, 93, 48,248,
+153, 63,245,113,116,116,188, 4,160,199,203,122, 81,134,155,163,219, 16, 49,146,134,136,145, 52,220,252,249, 63, 53, 88, 88, 88,
+140,118,118,118,190,106,107,107,251,212,217,217,249,119,145, 72, 52,164,142, 17, 14,142,142,142,107,220,221,221, 99, 92, 92, 92,
+214,163,100,118,242,127,173, 14, 66,116,104, 45, 68, 86, 27, 83, 40,219,153,226,155, 54,166,232,222, 29, 48,127,206,184,246, 0,
+ 14, 90, 90, 90,222,230,243,249, 97, 0, 6,149,238, 95,131,248,124,126,152,165,165,229,109, 0, 7, 75,151,123,158,253,116, 13,
+128,167, 0, 86,148,254,252,127,238,238,238,202,128,128,128,196,128,128,128,237, 62, 62, 62, 99,106, 27,102,110,110,222,221,221,
+221,253,144,135,135, 71, 98,155, 54,109,114, 93, 93, 93, 31,186,185,185,237, 16, 10,133,157,232, 45,142, 16, 66,254,253,250, 2,
+248, 2,192,166,200,200, 72, 25, 99, 76,198, 24,147, 69, 70, 70,202, 0,124, 3, 96, 37,170,110, 66,252,211,239,109,109,109,151,
+ 46, 91,182,172, 40, 45, 45,141,101,101,101,177,152,152, 24,182,110,241, 60, 99, 79, 27, 62,243,178,183, 46,112,118,118,126,228,
+233,230,182,183,169,132, 59, 15,128,119,109, 50, 43,176, 54, 51, 51,187,190,120,241, 98,213,165, 75,151, 84, 90,173, 86,101, 52,
+ 26, 85,169,169,169,170,240,240,112, 85,187,118,237, 84, 0,102, 1,224,213, 33,179,220,103, 46,184,192,126,248,148,125,230,130,
+ 11, 21,127,223,168, 81,163,123, 70,163,145, 13, 30, 60, 88, 3,192,181, 46,153,207,114, 5, 68, 77, 45, 97, 53, 68,130, 12,253,
+142,207, 25,219, 60,135, 13, 17, 35,233,121, 50, 29, 28, 28,126,153, 49, 99,134,226,233,211,167, 76,163,209,176,164,164, 36, 54,
+101,202,148,124, 7, 7,135,221,181,220,118, 91,127,127,255,140,171, 87,175, 26,229,114, 57, 59,127,254,188,177, 89,179,102, 25,
+181, 44,182,186, 61,179, 46,223,187,184,184,156,168,203,205,193,193, 97,107, 93, 95,163,119,132, 72,210,201,206, 49,118,243, 12,
+ 59, 58,184, 13, 91,215,210,141, 13,178, 49,149,183, 55,197,255,117,172,124, 40,147,170, 50,223,235,216,177,163,250,238,221,187,
+134,156,156, 28,118,239,222, 61,227,164, 73,147,138, 0, 68, 79,154, 52,169,232,222,189,123,198,156,156, 28,118,247,238, 93, 67,
+199,142, 29,213, 0, 38,214, 97, 61,185, 0,182,133,134,134, 50,198, 24, 91,182,108, 25, 11, 8, 8, 96, 93,186,116, 97, 42,149,
+138, 49,198, 18, 25, 99,219,245,122,253,251,181,201,148, 74,165,163,103,204,152,161, 42, 40, 40, 96,101,140, 70, 35,147,203,229,
+108,211,166, 77,106, 39, 39,167, 19, 85,124,200,160, 83, 30,148, 73,153,148,249,111,203,124,157, 57,163,164,159, 86,217,173,214,
+ 13, 19, 35,230,205,155, 87, 86, 84,157,108,223,190,253,141,247,223,127, 95,246,254,251,239,203,218,183,111,127, 30,192,233, 91,
+183,110,201,230,206,157, 43, 3, 48,162,134, 23,194,186,109,219,182,242,244,244,116,230,235,235,203,234,213,171,199,210,211,211,
+ 25, 99,140,221,124,175, 5,251,181, 49, 88,242,197,147,236,204,207, 7,217, 36,103, 62,235,224, 44, 45,118,118,114,202,177,179,
+179, 91,142, 63,207,201, 88,217,139, 59,176,113,227,198,202,232,232,104, 85,108,108,172,106,233,210,165,170, 46, 93,186,168,252,
+253,253, 85,131, 6, 13, 82,109,220,184, 81,165,211,233, 84, 91,183,110, 85, 89, 90, 90, 70, 87, 82,108, 61,119,161,197,231,243,
+ 55, 68, 70, 70,178, 71,143, 30,177,210, 86,138,170, 50,165, 86, 86, 86,189,172,173,173,103, 89, 89, 89,245, 2, 32, 5, 0, 95,
+ 64,210, 92, 10,143,255,107,238,213, 40,108, 68, 55,239, 77,221,222,110, 49,196,130, 43, 47,254,122, 14, 99,131, 61,158,171,208,
+146, 74,165,163, 63,250,232, 35,165, 70,163, 97, 5, 5, 5, 76,165, 82,177,130,130, 2,166, 84, 42,217,136, 17, 35, 20, 34,145,
+104, 96, 77,153,118,118,118,159, 95,188,120, 81,159,158,158,206, 46, 94,188,200, 78,156, 56,193, 54,111,222,108,116,112,112,248,
+170,174, 7,160,147,147,211,217, 51,103,206,200, 34, 34, 34,100,215,175, 95,151, 21, 23, 23,203,116, 58,157, 76,167,211,201,194,
+194,194,100,135, 15, 31,150,237,219,183, 79,166,213,106,101, 90,173, 86,166,209,104,100, 13, 26, 52, 56, 85,215,215,168,149, 16,
+201,218, 75, 71, 25,251,106, 26,203, 95, 53,149,201,103,191,203, 50,167, 4,177,111,222,118, 99, 65,102, 56,134,191,206,237, 89,
+105,166, 64, 32,184,144,152,152,104, 92,176, 96,129,182, 73,147, 38,249,227,199,143, 47,210,104, 52,140, 49,198, 52, 26, 13, 27,
+ 63,126,124, 81,147, 38, 77,242, 23, 44, 88,160,125,252,248,177,145,207,231,135,215, 97, 61, 87,150, 21, 89, 23, 46, 92, 96, 21,
+169, 84, 42,214,165, 75,151,196,128,128,128,237,245,235,215, 31, 89, 83,166, 68, 34,233, 63,127,254,124, 21,171, 68,113,113, 49,
+ 83, 42,149,236,241,227,199,198,122,245,234,165, 2,176,165, 55,115,202,164, 76,202,164, 66,235,149,153, 92,195,207,149, 63,137,
+115,231,206,149, 49,198,100,139, 22, 45,146,149,182,108,153, 0,144,148,222,248, 0,134,207,159, 63, 95,198, 24,147,205,155, 55,
+175,108,153,170, 94,136,190, 7, 14, 28,208,173, 95,191,158, 57, 58, 58, 50, 39, 39, 39,182, 97,195, 6,102, 52, 26, 89,122,216,
+110,246,107, 99,176,251, 11,199, 50,198, 24,139, 89, 62,157,253,218, 24, 44,254,219,207,216,168, 81,163, 10,204,205,205, 71, 84,
+243,226,218,180,104,209, 66, 89, 88, 88,168,218,177, 99,135,202,220,220,252, 38,128, 38, 40, 57, 21,201, 41, 93,215, 49, 77,154,
+ 52, 81, 68, 69, 69,169,126,250,233, 39, 21,128,165,181,220, 97,188, 1,116, 22,139,197,131,230,187, 10, 98,217, 15,159,178,249,
+142,184, 11,160, 25, 0,251,210,101, 92,230,205,155,199, 24, 99,204,221,221,253, 98, 21,153, 82,127,127,255,121,177,177,177, 33,
+197,197,197, 33, 17, 17, 17, 33, 13, 27, 54, 92,208,175,129,115,155, 35, 35,186, 7,230,127, 54, 53,144,173,157,237,255,101,239,
+ 86,221,246, 14,235, 52, 98, 92,125,187, 75,227, 29, 68, 5, 67,165, 60,229, 51,167, 14,107,181, 99,187,186,186, 94, 79, 74, 74,
+ 42, 47,174,148, 74, 37,123,250,244, 41, 75, 72, 72, 96,151, 46, 93, 98,206,206,206,191,214,148,233,228,228,116, 47, 41, 41,137,
+125,187,110, 29, 27,220,172, 17, 11,178,178, 96, 29,173, 45, 88, 75,137, 72,221, 24,104, 89,215, 66,235,246,237,219, 50, 0, 50,
+ 0,178,156,156, 28, 89, 78, 78,142, 44, 47, 47,175,252,119, 0,100,249,249,249,178,252,252,124,153, 86,171,149,121,121,121,213,
+185,208,106, 39, 66,187,119, 68,200,109, 35, 68, 97, 95, 87,187,212,169, 13,236, 12,215, 70,180, 97,121,211,186,176,245,129,174,
+172,189, 41,254,175,150,153,125, 77, 77, 77,207, 3,152, 83, 90,148,143,237,213,171, 87, 1, 99,140,245,234,213,171, 0,192,216,
+210,223,127, 84, 90,100,245,170,229,122,114,125,124,124,212,101, 45, 89, 0,174,248,248,248,168, 3, 2, 2, 88, 64, 64, 0,115,
+119,119, 87,150,102,215,234, 13,205,219,219, 59,166,176,176,176,188, 0,148,203,229, 44, 53, 53,149,197,199,199,179,232,232,104,
+118,243,230, 77,150,152,152,200,246,239,223,111,176,178,178, 58, 78,111,230,148, 73,153,148, 73,133,214, 43, 45,180,158,189,253,
+ 89, 88, 88, 24,123,230, 87,171,110,221,186, 37,155, 63,127,190,172,134,202,108,242,162, 69,139,202, 90,189,190,168,230,159,255,
+214,152,152, 24, 54,118,236, 88,230,231,231,199,252,252,252,216,251,239,191,207,242,243,243,153, 42, 46,138,253,218, 24,236,230,
+208,150,140, 49,198,148,247, 35,216,175,141,193,100,163,218,178, 59,119,238, 48, 55, 55,183, 51,213, 60,254,177,223,127,255, 61,
+107,247,238,221,233, 40,233,143, 37, 0,208, 26,192, 6, 51, 51,179,109, 40, 57, 93, 88, 15,128,181,175,175,111,110, 65, 65,129,
+106,240,224,193, 42, 0, 30,213,100,118,244,243,243,123,180,117,235, 86,150,153,153,201,114,115,115,217,234,118, 13, 25,251,225,
+ 83,182,172,101, 61,227,183,223,126,171,153, 51,103,142,218,198,198, 38, 12,128,203,224,193,131,245,140, 49, 22, 20, 20,148, 81,
+ 89,152,149,149, 85,175,216,216,216,144,162,162,162, 16,185, 92, 30,146,155,155, 27,114,244,200,145,144,158,205, 26,142,205,255,
+108,106,224,145, 17,221, 3,123,187, 90, 15,250,170,199,219, 31, 60, 93, 48,113,240,162,182, 77,238, 23,173,156,121,238,189, 6,
+142,107,158,231,213,182,183,183, 79,211,104, 52, 12,192, 95,110,143, 30, 61, 98,182,182,182, 73, 53,101,216,216,216, 44,250,104,
+248, 48,195,192,122,174,236,209,250,197,172,248,236, 79,172,248,196, 14, 22,183,106, 54,235,231,100,167,104,109,194,157, 95,219,
+245,113,114,114, 58,123,253,250,245, 63, 21, 90,121,121,121,149, 22, 90, 10,133, 66,166,213,106,101, 62, 62, 62,167, 94,116,175,
+111,109, 10,175,142,102,188,155, 17, 99, 59,176,172,169, 93, 88, 47,169, 32,241, 5,226,134, 3, 56, 15, 96, 84, 29,239,199, 5,
+176,178,172,160, 90,181,106, 21, 99,140, 49, 31, 31, 31, 53, 94,236, 98, 20,105,163, 70,141, 18, 38, 78,156,168,111,220,184,113,
+102,187,118,237,228, 55,110,220, 96, 23, 46, 92, 96, 39, 78,156, 96, 7, 15, 30,100, 81, 81, 81,236,233,211,167, 44, 38, 38,134,
+245,233,211, 71, 14,160, 35,189, 23, 18, 66,254,205, 42,169, 69, 94,123,220,178, 13, 11, 14, 14,230, 84,216, 64, 41, 0, 81,203,
+150, 45,179, 86,174, 92,185, 22, 37, 99, 65,112,252,121,120,175,139, 25,255, 78, 23, 51,254, 29,127, 30,222, 43,109, 49,250,126,
+249,242,229,159, 7, 4, 4,164, 1, 48, 3,224, 84,217, 3, 49,198, 58,216,218,218, 34, 41, 41, 9, 82,169, 20, 82,169, 20, 73,
+ 73, 73, 96,140, 65,207,128, 98, 6,104,116, 58, 20, 22, 22,162,200,200, 80,104, 4, 20, 42, 21,156,156,156,160,211,233,188,170,
+ 88,255,230, 67,135, 14,245,242,247,247,207,154, 59,119,110, 42, 74,250,202,108,155, 48, 97,194,217, 43, 87,174,248,171, 84,170,
+220,232,232,232,162,102,205,154,245, 2,224, 20, 27, 27, 59,122,211,166, 77, 24, 59,118, 44,170,249,167,211,172, 79,159, 62, 39,
+162,162,162,188, 70,141, 26,133,243,231,207, 99,245,234,213,200,206,206,102, 0,160,209,104,152,193, 96,208,181,109,219, 86,183,
+126,253,250, 86, 65, 65, 65,215, 27, 52,104,192, 3,128,132,132,132,184,202, 2, 57, 28, 78, 67, 79, 79, 79,104, 52, 26,100,101,
+101, 33, 42, 42, 10, 22, 82, 41, 34, 83,179, 29, 59,125,245,109,206,194, 35,103, 5,195, 91,249,219,204,234,222, 78,179,226,204,
+121,223, 38, 46,142,142, 90, 93,177, 83, 76, 90, 70,234,243,188,168, 38, 38, 38, 73,217,217,217,208,106,181, 40, 44, 44,132, 66,
+161, 64, 78, 78, 14,178,179,179,145,154,154, 10, 19, 19,147, 71, 53,101, 88,230,230, 94, 76,248,253, 2,103,255,119,171,224,165,
+207, 5,255,208, 6,240,127,249, 6,222,218, 44,108, 89, 60,197, 66,107,107, 31,106,105, 97,145,103,101,101,245, 61, 0,159,154,
+242, 2, 3, 3,145,147,147,131,156,156, 28,216,218,218,194,218,218, 26,214,214,214,144,203,229,200,207,207,135, 66,161,128,175,
+175, 47,154, 55,111,142,157, 59,119,190,148,157,251,154, 22,241,122, 24,166,158,125,152, 10, 19,177, 24, 13,172, 37,158,111, 75,
+ 96, 83,205, 93,186, 8, 4,130, 3, 54, 54, 54,103, 0, 76, 3, 32, 6, 48,205,198,198,230,140, 64, 32, 24, 0, 96, 25,128,221,
+117, 92,141, 21,161,161,161,243, 98, 99, 99,205,239,220,185,131,185,115,231, 98,233,210,165,136,139,139,251, 26,128,177,116,153,
+ 15,109,109,109,195,184, 92,238,255, 0,188, 11,160,151,179,179,115,215, 26,114, 7,204,153, 51,167,168, 69,139, 22, 49,247,239,
+223, 31,240,251,239,191,183,156, 61,123,118,254,147, 39, 79, 16, 19, 19, 3,103,103,103,184,187,187, 67,165, 82, 33, 47, 47, 15,
+ 3, 6, 12,144, 90, 90, 90,142,160,183,113, 66,200,191,185,200,122,166, 22,121,221, 90,180, 42,253,185,210, 79,212,230,230,230,
+161, 50,153,172, 77, 64, 64, 0, 31,192,126, 0,240,231, 97,200,128,182,111,109, 59,242,253,170,128,195,235, 23, 7,244, 12,240,
+221,230,207, 67,217, 85,108, 97, 45, 91,182,180,150,201,100,109,133, 66,225,255, 85,177, 18, 12, 0,172,173,173, 33,149, 74, 97,
+101,101, 5,107,107,107, 24,141, 70,168, 10,138,160, 54, 0,202, 34, 45,242,243,243,161, 44,253, 89,165,209, 65,173, 86,151,223,
+183, 18,157, 38, 78,156,152,181,105,211,166,204,180,180,180, 85, 0,154,141, 29, 59,182,255,198,141, 27,241,219,111,191, 21,189,
+235,231,109,187,188,195, 91,159, 55, 73,139, 11,241, 19, 96, 18,128,139, 23, 47, 94, 68,219,182,109,193,225,112,134, 85, 22,104,
+102,102,246,205,222,189,123,205,162,163,163,225,237,237, 29, 61,108,216,176,247, 86,173, 90,229, 37, 86,229, 94, 6, 0,125, 78,
+122,244,244,233,211, 63, 93,190,124,121, 86, 86, 86,150,174,160,160,192,161, 95,191,126, 72, 74, 74,194,211,167, 79,175, 84, 81,
+100,198, 68, 68, 68,176,252,252,124,196,199,199, 35, 34, 34,194,236,211, 79, 63,109,101,224,114,251,167,192, 98,220,216,118, 45,
+ 91,141,106,253, 22,118, 95,189, 99,114,233, 97,130, 85,203,122,174,214,183,147,211,234, 23,115,240,232,121, 94,109,165, 82,185,
+225,243,207, 63, 87,169, 84, 42,164,164,164,224,238,221,187,184,127,255, 62, 18, 19, 19,177,122,245,106, 85,110,110,238,198,154,
+ 50, 92, 68,252,143,215,204,158,192,225,223,187, 2,220,185, 0, 20, 40,129, 66, 21, 52, 15,100,216,254, 32, 29,155, 15,253,108,
+250, 36, 41,201,106,223,190,125, 19, 61, 60, 60,100, 0,124,171,203, 99,172,228, 37,228,114,185,207, 22,161,224,114,185, 74, 0,
+233, 98,177, 56,217,194,194, 34,153,203,229,166, 51,198,212, 47,229,147,132, 30, 58,240,120,128,169, 25,184,130,106,167,246,124,
+111,216,176, 97,123,147,147,147,123,198,199,199,183,217,184,113,227,231, 34,145, 40,114,227,198,141,159,199,199,199,183, 73, 78,
+ 78,238, 57,108,216,176,189, 0,198,212,229,241,125,124,124,166,135,132,132, 96,245,234,213,104,222,188, 57,124,125,125, 11, 66,
+ 67, 67, 55, 0, 88, 12,224,255,124,124,124, 46, 79,159, 62,125,124,102,102,166, 83, 74, 74, 74,243,175,191,254,122,202,134, 13,
+ 27,222, 78, 77, 77, 21,213, 16,221,190, 71,143, 30, 56,121,242, 36, 0,164, 1,136,207,201,201,209,167,166,166,162, 81,163, 70,
+104,213,170, 21, 84, 42, 21, 84, 42, 21,228,114, 57, 60, 61, 61, 97, 52, 26,219,208, 91, 57, 33,132,252,173, 5, 87,229,133,150,
+ 72, 36,178, 14, 12, 12, 68,131, 6, 13,172, 81,122,181,150,173, 41,127,193,172,137,195,205, 37,178, 83,224, 68,252,138, 97, 29,
+154,154,219,154,242, 23,148,222,133,239,233,233, 41, 12, 12, 12,132, 88, 44,118,173,226,193,207,167,167,167, 35, 48, 48, 16, 86,
+ 86, 86,144, 74,165, 8, 12, 12,132, 78,167, 67,190, 82, 9,181, 1, 40, 40, 54, 34, 63, 63, 31,185, 89, 25, 40, 48, 0,122, 11,
+ 91, 36, 38, 38,130,199,227, 37, 84,145,233,236,237,237,157, 21, 25, 25,153, 5,224, 34,128, 15,150, 46, 93,138,249,243,231, 99,
+201,146, 37,123,205,211, 30,247,216,123,242, 23,219, 61,161, 31,218,251,154,114,134, 3,208, 37, 39, 39,195,202,202, 10, 98,177,
+184,210,194, 32, 40, 40,168,133, 88, 44,198,142, 29, 59, 88, 74, 74, 74, 59,148, 92,194,159,192,225,148, 20,123,102, 92,228, 3,
+216, 32,147,201,222,249,244,211, 79, 31,118,235,214, 77,208,186,117,107, 44, 91,182, 12, 0,194, 42,203,148,203,229,215,198,140,
+ 25,163, 61,119,238, 28, 30, 60,120, 32, 62,114,228,200,144,101,203,150, 53,125,242,228,137,240,216,137, 83,189,119, 37, 43,134,
+172, 58,115, 73,180,252,244,249,107,118,150,226, 38,245,237,108, 16,241,228,169,137,129,135, 27, 53,189,162,239, 8,120, 19, 59,
+137,248, 17, 29,132,220,180, 78, 34,190,236,109, 1,111,130, 82,169,220,119,244,232,209,211,179,103,207, 86,101,102,102,194,194,
+194, 2, 57, 57, 57, 88,177, 98,133, 42, 34, 34,226,144, 86,171, 61, 86, 83,174,193,200, 90,184,215,243, 0, 30, 69,150,255, 78,
+103,100,184,161, 53, 65,240, 7, 51,225,215,168, 17,180, 90, 45,154, 53,107,198, 89,186,116,169, 88, 42,149,126, 82, 99,209,195,
+253,203,238,166,231,112, 56,233,140,177,167, 42,149, 42,197,204,204,236,137,137,137,201,147,220,220,220, 20,198, 88,198,203,168,
+179, 24, 23, 31,183,109,230, 3, 8,205,240, 36, 71,149,122, 83,133,220,202, 22,180,176,176,152,176,121,243,102,209, 15, 63,252,
+ 80, 60,125,250,116,205,148, 41, 83, 4,133,133,133, 14, 83,166, 76, 17, 76,159, 62, 93,243,195, 15, 63, 20,111,222,188, 89, 36,
+145, 72, 6, 61,207,138, 20, 23, 23, 35, 50, 50,114, 85, 92, 92,156, 24, 37,195,141,204, 12, 13, 13, 29, 27, 27, 27, 43,218,180,
+105, 19, 14, 30, 60,136,131, 7, 15,162,127,255,254,152, 49, 99, 6, 66, 66, 66,170,139, 51, 15, 8, 8, 8,180,181,181,197,133,
+ 11, 23, 82, 1, 60, 1,208, 66, 34,145, 88,244,239,223, 31, 61,123,246, 68, 81, 81, 17,116, 58, 93,121,161,197,227,241, 96,101,
+101,101, 75,239,129,132, 16,242,202,139,172, 63, 21, 91,124, 0, 40,107,170, 11, 14, 14,230, 84,247,143,209,144,151, 9,185,186,
+ 0,137,249, 5, 72,202, 51,254,233,111, 70,163,177,218, 71, 79, 77, 77, 61,118,245,234,213, 9,129,129,129,252,212,212,146, 51,
+ 98,129,129,129, 40, 40, 40, 64,234,157,235, 80, 27, 1,177,183, 63,212,106, 53,242,238,223,134, 36,160, 13,108,251,140,194, 87,
+155, 54,105,114,114,114,190,171, 44,211,212,212, 84,224,230,230,150,149,144,144,160, 7,144, 43,149, 74,123,120,120,120,224,252,
+249,243, 0,176,155, 1,107, 16,113, 14,184,112, 24,172,164, 73, 69,226,233,233,137,204,204, 76,168, 84,170,243,149,101, 94,189,
+122, 53,182,184,184,184, 89,191,126,253, 56, 63,254,248,227,126,133, 66,177, 4,192, 93,141, 17,188, 59,201, 25, 80, 27, 32, 2,
+208,221,218,218,250,163,144,144,144,174,211,167, 79,199,209,163, 71,113,230,204, 25, 29, 74,250,130, 93,173, 36, 54, 63, 62, 62,
+126,203,156, 57,115, 90,115,185,220, 15,206,158, 61,171,247,245,245, 85,232,116, 58, 67, 67, 63, 63,238,146,165,159,153, 76,251,
+ 96,178, 85, 78, 1,238,245,108,232,220,150,195, 1,238, 61,205,124, 18,167, 66, 78,117,207,105,144, 41, 47,108, 64,187,128,160,
+ 9,195,250, 74,196,222, 77,160,142,186,238,180,229,192,137,175,204, 34, 98,131, 47,100,102,246, 63,122,244,232,144,243,231,207,
+ 79,211,106,181, 13,132, 66,225, 35,185, 92,190, 94,165, 82,213, 88,100,241,120,188, 62, 26,103, 55,107,121,110, 46, 68,165, 45,
+ 81,138, 98, 35,178, 53,122, 60,176,242,197, 8, 55,247,242,211,160,233,233,233,112,114,114,226, 24, 12,134,190,213,101,158, 57,
+115, 6,193,193,193,101,133, 39, 56, 28, 14, 56, 28, 78,182,159,159, 95,134, 80, 40,204, 49, 49, 49, 81,172, 89,179,166,168,168,
+168, 8,124, 62, 95,100, 48, 24,120, 47,178,183,183, 50,135,131,144,113,190,153,210,175,115,183,230, 77, 26,177,139, 55,239,112,
+242, 10,138,182, 87,211, 10,248,181,143,143, 15, 63, 55, 55,247, 24,128, 7,197,197,197,123,246,239,223, 47, 26, 61,122,116,209,
+129, 3, 7, 70, 2,240, 90,187,118,237, 16,149, 74, 85,167, 41, 21,226,226,226,190, 94,190,124,249,188, 69,139, 22, 97,231,206,
+157,211,227,226,226,230,151,182,116,245, 15, 9, 9,193,154, 53,107,176,115,231, 78,227,131, 7, 15, 78, 24,141,198,184,217,179,
+103, 7, 56, 58, 58,102,167,165,165,197, 85, 19,219,178, 87,175, 94,154,203,151, 47,155, 42,149,202, 75, 0, 62,154, 58,117,234,
+196,119,222,121, 71, 49,108,216, 48, 73,110,110,174,220,220,220,220,116,235,214,173,214,124, 62, 31,106,181, 26, 28, 14, 7, 74,
+165, 82, 75,239,131,132,144,127,171,170,106,145,215, 68,149,255, 27,248,149,109, 96, 65, 65, 65, 70, 82, 82, 82,163,167, 79,159,
+234, 1,232, 1, 32, 71,171,255, 98,249,214,195, 63, 12,106,237, 35, 78, 43, 46,198,145,155,209, 5, 57, 90,125, 89,231,119,253,
+211,167, 79,149, 79,158, 60,177, 40, 44, 44, 84, 85,241, 88, 87,190,249,230,155,194,115,231,206, 89,196,199,199,195, 96, 48,160,
+ 69,139, 22,136,137,137, 65,222,131, 72,136, 27,181,128,184, 99, 48,162,101, 55, 17,113, 38, 28,143, 85, 90,253,195,197,203,243,
+ 85,106,117,136, 78,167, 59, 82, 89,160, 64, 32,200, 5,192, 24, 99, 6, 0, 80, 40, 20,119, 85, 42, 85, 7, 71, 71, 71,220,187,
+119, 79,172, 54, 96,198,144, 5, 95,109,100,140, 25, 76, 74,174,230,154, 53,108,216, 48,220,186,117, 11, 0,110, 85,150,169, 80,
+ 40,166, 79,154, 52,233,220,142, 29, 59,248,241,241,241, 61,127,248,225,135,158, 15, 31, 62,100,156,220, 36,195,229, 2, 1,188,
+198,206,120,251, 91, 79,191, 51,193,193,193,112,118,118,198,214,173, 91,177,126,253,250,226, 15, 63,252, 48,118,253,250,245,111,
+103,102,102,238,169, 98,251,243,229,114,249, 41, 91, 91,219,105, 77,155, 54, 85,170,213,106,228,228,228, 32, 53, 53, 21, 54,182,
+182, 92, 61,184,109,237,173,172,246, 28, 75, 87,138,249,167,174,225,122, 74, 90,181,173, 89,173, 5,188, 49,131,130,222, 10,250,
+191, 69, 11, 36,184,124, 4,156, 73, 33, 96, 63,124,142,153,239, 15,177, 40,210,236,233,168,190,147, 56, 90,166, 80,236, 82, 40,
+ 20, 7,235,184,179,244,106,219,182,237,222,229,203,151,155, 45, 92,189, 28,107, 27,185, 66,159,147,131, 44,141, 1,217, 26, 61,
+ 20,121, 15,112,239, 94, 52,108,109,237,240,248,241, 99, 20, 21, 21,225,254,253,251,140,199,227, 29,171,169, 69,167, 76,133,211,
+133,114,161, 80,152, 35, 16, 8, 50,248,124,126,110,124,124,188,186,168,168, 8, 92, 46, 87,108, 48, 24,204,106,177,174,110,118,
+118,118,179, 81, 50,152,232, 81,101,118,246,134, 64, 1,172,192, 71, 39, 79, 59,219,222,139,167,140,182,243,112,113,144,199,199,
+ 62, 42,254,238,244,239,217, 69,154,170, 47,214, 0, 16,150,155,155, 91,222, 34,121,224,192,129,153, 7, 14, 28,152, 8, 96, 27,
+ 74,230,221, 10,151,203,229,223, 62,199,193,183,248,208,161, 67,243, 22, 45, 90, 4, 51, 51,179,242,193, 83,205,204,204, 68, 0,
+240,211, 79, 63,225,222,189,123,239,160,180,191,150,209,104,220,155,150,150, 86, 83,166,151,191,191,127,252,225,195,135, 77, 1,
+184, 76,157, 58,181,205,198,141, 27,241,254,251,239,103, 69, 71, 71,183, 6,144, 0,192,235,131, 15, 62,184,177,115,231, 78,107,
+163,209,136,188,188, 60,104,181,218, 4,122, 43, 39,132, 80,177,245, 74, 4, 2,136, 64,201,248, 89,125, 0, 28, 71, 73,183,142,
+ 42,185,151, 86,103,167, 1,244, 43,251,255, 88, 69,103,120,160,228,138,172, 83, 0,254, 7,192,177,170, 80, 91, 91,219, 79,198,
+142, 29, 91,156,146,146,194,210,211,211,217,193,131, 7,217,172, 9, 99, 13,221,189, 93,140,222, 46,142,106,123,123,251, 24,103,
+ 59,155,237,111,153, 99, 22, 0,183, 90,108,216,216,135, 15, 31, 78, 30, 59,118,236,132,210,199,157,176,119,239, 94,213,217,179,
+103, 85, 60, 30, 47, 12, 37, 67, 59,148, 21,148, 99,250,246,237,171,210,104, 52, 42, 63, 63,191, 92,148,116,220,175,202,144, 78,
+157, 58,229,157, 60,121,146, 25, 12,134,191,140, 81,148,149,149,197,206,156, 57,195,218,181,107, 39, 7, 48,186,107,215,174,231,
+127,255,253,247,243,237,219,183, 63, 84,211, 10,219,217,217, 45,184,115,231,206,173,196,196, 68,217,241,227,199,101,123,246,236,
+145,125,240,193, 7,119, 3, 2, 2, 10, 99, 99, 99,141,122,189,158,221,185,125,155,249, 53,108,168, 6,224, 89, 85, 78, 23, 51,
+254, 13,197,214,207, 89,209,178,247, 89,209, 0,119, 6,128, 41,191,250,132,101, 76,239,198, 98,166,245,102,157, 69,188,171,207,
+179,167,216,216,216,156,190,117,235, 22, 83, 42,149, 44, 42, 42,138,141, 9,238,201,174, 78,236,198, 78,245,244, 97, 59, 59,214,
+103, 95,245, 8, 96, 61, 59,118, 96,223,124,243, 13, 59,124,248, 48, 91,176, 96,129,209,206,206, 78,137,106,250,104, 57, 57, 57,
+157,221,191,127,191, 12,128,140,199,227,201, 20, 10,133, 76,169, 84, 30, 75, 78, 78,222,236,231,231, 55,175,105,211,166, 35, 27,
+ 53,106,212,165,115,125,207,121, 93, 45,132, 49,221, 44, 69,143, 26, 74,204,191,194, 95,199,189, 42, 39, 5, 60,189,189,188,148,
+ 23, 46, 92, 48,106, 52, 26,118,233,210, 37, 99,227,134,190, 69,107,135,246, 58,244,120,235,202, 67, 69, 39,127, 60, 93,240,203,
+247,191, 31, 24, 23, 28,217,201,156,251, 99, 27,113,249,112, 28,207,107, 56,128, 35,248,227,170,195,177, 0,126, 65,245, 87, 33,
+114, 1,108, 91,182,108, 89,197, 43, 13, 1,128, 27, 16, 16, 32, 99,140,201, 2, 2, 2,100,117, 93, 17,115,115,243,217, 71,143,
+ 30, 13,245,240,240, 88, 61,108,216,176,173,114,185,252,248,200,145, 35, 35, 81,114, 49, 8, 7, 37,179, 35,244,117,115,115,203,
+138,136,136, 96,231,207,159,103,131, 7, 15, 86,154,152,152,140,162,183,113, 66, 8,121, 37, 38, 87,241,181, 90,203, 35, 35, 35,
+203,198,208,154, 90, 93,248,252,249,243,101,183,110,221,146,161,100,148,248,106,241,249,252,159, 63,252,240, 67,230,232,232,168,
+114,112,112,248, 89,192,227, 77,116, 55, 67, 32,158,239, 82,247, 14,187,118,237,234,255,245,215, 95,247, 1,240, 14, 0,129,171,
+171,107,106,122,122,186,234,247,223,127, 87,181,107,215, 78,101,103,103,151,233,239,239,175, 90,187,118,173,170,184,184, 88, 53,
+123,246,108, 21,254, 58,222, 87,101, 68, 0,166,153,154,154,254,220,184,113,227,200,197,253,186, 20,175,158, 49,145,141,245,177,
+ 87, 1,248, 26,192,135, 0,172, 0, 8,134, 12, 25,242,235,253,251,247, 79,251,251,251,111,169, 69,174, 75,211,166, 77,127,219,
+187,119,239,173,195,135, 15,203, 62,249,228,147, 91,182,182,182, 41,177,177,177,198,162,162, 34,150,151,151,199,228,114, 57, 59,
+126,252,184,193,198,198,102, 83,149, 27, 46,228,165,177, 51,187, 43, 29,194, 33,121,209, 40,214,206,148,251,244,121,246, 20,177,
+ 88,156,155,147,147,195,210,211,211, 89,124,124, 60, 59,116,232, 16,235,213,182, 21,219,247,193, 32,182,123, 66,127,182,166, 87,
+ 43,246,142,133, 72,237,100, 33,185,101, 97, 97,145, 89,155,171, 14,157,156,156,206,106, 52,154,242,225, 27,220,220,220,100,126,
+126,126,135,253,253,253,191, 58,122,244,232,204,117,235,214,245,239, 92,223,115,222,138,158,109, 11, 11,194, 15, 48,229,254,175,
+217,252, 22,190, 69,165,197,124,165, 92,109,109,118, 93, 56,127,222, 88, 86,252,234,245,122,118,228,231,159,217,208,222,221, 35,
+243, 79,253,244,191, 75, 33,211,247,206,110,225,123,164,157, 8,195,171, 43,216,202, 63,138, 72, 96, 27,100,201,221,252,174,135,
+ 77, 90, 7, 41,247,235,214, 22,127,154, 94,106,168,175,175,111, 60, 99, 44,173, 81,163, 70,241, 0,118, 55,106,212,168,226,207,
+227,170,136, 45, 31,156, 52, 52, 52,148,149, 30, 31, 92, 0, 75,150, 47, 95, 46, 99,140,201,124,124,124, 46, 3, 64,115, 49,236,
+ 58, 74,185,255,235,231,229,152,211, 81,202,253, 95,115,113,229, 83, 70,121,154,160, 97, 7,123,243, 75,253,125,156,149,157, 92,
+165, 23,119,111,255, 97,245,187,239,190,187, 21,192, 38, 0,159,219,218,218, 94, 26, 62,124,248,189,157, 59,119,222, 91,187,118,
+173, 46, 54, 54,150,141, 31, 63, 94, 45, 20, 10, 63,167,247, 65, 66, 8,121,101,202, 70,134,119,174, 75,161,213,119,222,188,121,
+ 50,198, 88,217, 88, 90,163, 43, 89,166,223,162, 69,139,100,140,177,178,209,225,159, 29,192,172,178, 1,205, 66, 55,111,222,204,
+132, 66,225,255,158,115, 99, 42,102, 58, 13, 24, 48,160,181, 66,161,120,219,209,209,241,237,210,150, 43,119, 59, 59,187,248, 61,
+123,246,168, 10, 11, 11, 85,140, 49,149, 94,175, 87,221,186,117, 75,213,169, 83, 39, 85,133, 79,253, 53,173,231,159, 44,116,194,
+229,155,139, 39,176,133, 78,184,252,204,159, 70,109,219,182,237,100, 66, 66,194, 49, 75, 75,203,185,181,204,116,183,183,183, 95,
+ 98, 99, 99,115,218,206,206,110,161,141,141, 77,154, 78,167, 99,121,121,121, 44, 38, 38,134,157, 63,127,158, 93,189,122,149,217,
+216,216,164, 84,181,158, 93,205,248,215,242, 86, 79, 99,198,109,203,153,118,227, 2, 6,128,201,215,205,103,217,223, 44,101, 55,
+ 39,245,100,157, 68,188, 43,207,241,124,194,202,202,234,251,159,127,254,217, 24, 23, 23,199,194,194,194,216,241,227,199,217,140,
+ 25, 51, 88, 67, 23,103, 77,107, 83,110, 70, 7, 33,255,244,243, 12, 88,170,209,104,100, 10,133, 66,166, 82,169,100,141, 27, 55,
+150,181,106,213,234,112,235,214,173,191, 58,112,224,192,204, 21, 43, 86,244,239,106, 33,140, 41, 8, 63,192,216, 39,189, 25,155,
+214,158, 61,154,216,137,117, 49,227,223,169, 50,211,209, 49,165,108,180,118,181, 90,205, 46, 94,188,200,126,251,237, 55,230,100,
+103,167, 8, 50,227, 77,110, 39, 68,199,118,150,176,170,237,122,118,150,114,183, 95,251,230, 11, 67,225,201,157,236,167,177,189,
+245,157,172,184,155, 43, 44,183,143, 49,150, 54,120,240,224,199,140,177,180, 67,135, 14, 37, 51,198,210, 6, 13, 26,244,152, 49,
+150, 6, 96,111,101,153,207, 12, 78,186,173,180,200,154, 22, 26, 26, 42, 99,140,201, 66, 67, 67,101, 64,201, 32,170, 29,165,220,
+ 29,215,183,172, 49,106,142,239, 96, 7,198,247, 49,116,148,114,119, 84,186,158, 86,252, 99, 17,219,214, 49,237,233,221,236,231,
+ 25, 35, 13,237,157, 44, 47,248,250,250,174,153, 57,115,230,225,171, 87,175,222, 53, 24, 12,247,226,227,227,239,109,218,180,233,
+ 94,155, 54,109, 46,219,218,218, 70,154,154,154,126, 88,211,107,244,146, 80, 38,101, 82, 38,101,146,103, 27,152,170,249,219,177,
+ 85,171, 86,137, 25, 99,179,135, 12, 25,130,149, 43, 87, 14,109,218,180,233,112, 87, 87, 87,123, 0, 72, 77, 77, 45,136,138,138,
+ 82, 12, 25, 50, 4, 75,150, 44,193,234,213,171,191, 66, 73, 95,150,191, 83,250,145, 35, 71,220,166, 79,159,158,185, 98,197, 10,
+227,248,241,227, 27, 1,136,202,206,206,110, 56,114,228,200,105,124, 62,127,136,167,167,167,127, 90, 90, 90, 86, 97, 97,225,110,
+ 0, 91, 80,195, 57,211,170, 8,185, 48,180,172,231,140,211, 92, 24, 42,252,186,247,146, 37, 75,134, 13, 26, 52, 72,183,110,221,
+ 58,189, 66,161, 56, 90,203,184,228,172,172,172,207,202,126,176,177,177,113,186,115,231,206,135, 14, 14, 14,220,248,248,120,104,
+ 52, 26,196,197,197, 25, 81,114,106,170, 82, 42, 61,219,240,237,161,179,126,179, 71, 5, 91, 22, 60,184, 13, 19, 30, 15,197, 2,
+ 83,164, 95, 59,141,109, 23, 31, 40,212, 58,108,124,158,237,148,203,229, 95,206,152, 49, 99,228,220,185,115, 69,158,158,158,156,
+ 43, 87,174, 96,255,254,253,154,204,204,204, 94, 0, 46,252, 49,244, 83,221, 24,141, 70,152,154,154, 2, 0,230,207,159, 15, 46,
+151, 43,200,204,204, 52,229,112, 56, 66, 14,135, 99,206,225,112,120,197, 9,247, 96, 84,228, 33, 35, 79,142,228, 12,121,181,121,
+ 6,163,113,255,245,235,215,103,189,245,214, 91,220,155, 55,111, 34, 43, 43, 11,113,113,113,204,192,216,222,139,133,134,146, 78,
+137,154,218,175,159,185,141,237,128,230,214, 66,174,233,246, 37, 8,210,114,121,223, 25, 49, 24, 37, 99,105, 1,192, 54, 14,135,
+ 99, 2, 32,167,113,227,198,157,239,223,191,111,214,184,113,227,194, 7, 15, 30,156,228,112, 56,174, 0,118, 84,150,105,102,102,
+150, 13, 32,251,208,161, 67, 0, 48, 9, 37, 79, 94,139,144,144,144,180,139, 23, 47, 34, 52, 52, 52, 3,192,102, 0,144, 88,219,
+246,243,151,154,112, 76,127, 12, 69, 27, 13,184, 27,141,172,210, 86, 87,137,131, 99,151,166, 98, 46, 4, 63,124,138,183,157,252,
+184,166,122, 93,179,165, 75,151, 94, 84,169, 84,154,125,251,246,105,199,141, 27,199,139,141,141,189, 1,224, 18,128, 67, 40,237,
+ 99, 73, 8, 33,228,149,122,182, 5,171,198, 62, 90,207, 86,173, 43, 1,124,251,240,225,195,242, 73,165, 31, 62,124, 40, 3,240,
+ 29, 74, 70,131,239, 91,135,138,119,113,105,139,214,150,231,220,152,103, 51, 69,129,129,129,102,247,239,223, 55, 65,229,147, 56,
+114,158, 35,243, 47, 42,155,235,208,215,215,119,125,113,113,241,225,239,190,251,238, 0,143,199, 27,249, 2,213,190,167,143,143,
+ 79,222,158, 61,123,140, 97, 97, 97,108,241,226,197, 6,103,103,231, 60,252,181,143,214,159, 50,131, 76,121, 7,231, 52,114, 85,
+220, 26,221,158, 61,154,217,143, 93, 26,213,137, 77,118,149, 40,130, 68,188,253, 47,248,169,196, 71, 42,149,110, 51, 51, 51, 83,
+ 88, 90, 90,158, 5,208,246, 69, 94, 35, 91, 91,219,157, 78, 78, 78,103, 43,222, 28, 29, 29, 15,219,219,219,127,109,103,103,183,
+216,202,202,106,138,151,200,116,221,204,134, 46, 69,145, 3, 26,179,240,118,246,108,148,157,233,179,167, 14,159, 93, 79,103, 47,
+ 47,175,156, 93,187,118, 25,143, 29, 59,198, 22, 44, 88, 96,172, 87,175,158, 2,213,244,107,171,182, 69,203,138,183,255,224,160,
+214,198,140, 62,174,108,101, 35, 11, 99,103,107, 94, 85, 87, 40,142, 42, 45,128,199,214,148,233,237,237,253, 29, 99,108,251,178,
+101,203,182,227,143,185, 64,187, 47, 93,186, 52,132, 49, 22,178,116,233,210, 16, 0, 61, 1, 32, 72,202,221,181,187,127, 75, 67,
+234,187, 46,236,139, 70, 18, 67,144,148,187,171,210,150, 76, 27,254,145, 95, 38,246, 49,166, 77,108,199,150,248,136, 13,173,109,
+132,191,154,154,154,206, 68, 73,139,115, 43, 0,166,244,169,153, 50, 41,147, 50,169, 69,235, 95, 87,120,213,138,147,141,141,205,
+182, 6, 13, 26, 28,240,244,244, 60, 32,145, 72,190, 66, 73,167,249,186,190, 16, 94,203,151, 47, 87, 72,165,210,230, 47,241,197,
+117, 0,224,138,191, 78,156,251,210,118,152,207,156, 49, 61,118,238,208, 59,159, 57, 99,122,133, 95,183,106,212,168,209, 23, 40,
+ 25,205,251, 69,119, 66, 79, 27, 27,155, 77, 54, 54, 54, 41,165,125,179, 60,107,147,217,146,199, 27,217, 89,196,187,210,214,148,
+155,222, 89,196,255,253,109, 30,111,196,107,122, 0, 86,119,177, 69, 85,153,110,118,118,118,235,108,108,108, 82,237,236,236, 54,
+213,177,200,250, 83,102,115, 51, 56,119,177,226, 29,105,107,193, 81,119,145,242, 14,181, 52,175,250,162,142, 58,108,123, 96,104,
+104,232,251,140,177,247, 93, 92, 92,134, 84, 40,252,253,151, 44, 89, 18,204, 24, 11, 46, 27, 1,190,149, 57, 28, 58, 89,241,246,
+180,179,228,200, 59, 89,241,246,180, 50,135, 67, 85,235,217,217,138,183,191,157, 37, 71, 30,100,201,221,227, 33, 68, 61,122, 51,
+167, 76,202,164, 76, 42,180,222,140, 66,139,118, 24,202,164, 76,202,164, 76,202,164, 76,202,164, 66,171,242,194,170,226,173,252,
+ 12, 27,159,158, 27, 66, 8, 33,132,144, 23, 82,229,128,165,156,106,170,210,186,116,108,127,158,202, 54,156, 50, 41,147, 50, 41,
+147, 50, 41,147, 50,255,115,153, 53,101,255,221, 23,214, 19,174,245,180, 0, 0, 32, 0, 73, 68, 65, 84,189,214,168, 89,149, 50,
+ 41,147, 50, 41,147, 50, 41,147, 50,255,179,184,244, 20, 16, 66, 8, 33,132,188,144,192,210,175,207, 14, 92, 90,121, 31, 45,126,
+171,101, 25,122,189,222, 1, 0,248,124,126,102,241,141,197,206,213,165, 11,128,174,250,146,233,119,192, 7, 38,233,129,179,149,
+100,158,213,235,245,214,165,153,121,197, 55, 22,247,172, 54,179,213,178,211, 21,151,215,223, 88,220,253,217,101, 24,192, 19,180,
+ 90,150,250,204,186,186,212,246, 89,225,224, 79, 99, 98,189,178,245,124, 93, 50,255,203, 4,239, 44,203, 40, 46, 46,217,143, 4,
+ 2,126,166,238,122,245,251,145,201, 59,203, 82, 43, 46, 95,124,125,177, 99,117,153,230,102,194, 28,111, 87,251,175,170,203,140,
+ 79,205,158,173, 46, 40,178,173, 46,179,174,199,166,187,179,115, 87, 67,233,177,201, 3, 38,165,164,165,157,253,151,237, 75, 45,
+ 1, 44, 6, 96, 89,225,119,145, 0, 62,162,189,146, 16,242,154, 21, 90, 17, 40,153,231,240,251,210, 98,235,251, 42, 11, 45,189,
+ 94,239, 32,251, 57, 4,106, 13,208,117,204, 50, 7,175, 1, 91,254, 50, 81,178,190, 40,207, 84, 30,189,207,159, 87,172,176,182,
+231,235, 44, 83, 83, 83, 57, 0,192,225,112,254, 7,192,163,146, 76,107,217,207, 33, 40,208, 2, 65,195,151, 90,123, 0,150, 89,
+ 38, 38, 31,155,137,197,157, 11, 11, 11,155, 2,128,153,153, 89,116,161, 90,125,206, 94,167, 91,251,236,242, 85,109, 89,197,117,
+237, 50,122,153, 67,163, 1, 91,102, 24,140, 70,211,167, 55,191, 11, 42,202,142,229, 11,244,154,205, 11,129,147, 33,149, 20, 85,
+ 85,228,253,241,184,239, 45,176, 21, 0, 93, 76, 69,162,230, 86,214,214, 29,140,140, 53, 54, 26,141, 28,131, 94,127, 79,145,159,
+127,201,168,215,223,209,107,213,182,178,163, 95, 24,171, 91,207,103,183,229, 61,128,255, 51, 48, 68, 44,145,116,230, 9, 4,109,
+ 1,192, 80, 92,124, 69,173, 82,157, 27, 8, 28,172,205,182,215,246,249,121,222,229,255,107,138,139,245, 14, 9,167, 67,160, 41,
+ 6, 2, 7,127,225, 16, 48,242,199, 61, 0,160,205,188,227,168,138, 61,250, 14, 0,136,189,131,175, 11,157, 2, 51, 0,128,255,
+ 36,205, 33, 38,108, 17, 52,197, 64,227,224,165, 14, 53,101,142, 91,178,223,118,238,228, 65, 66, 0, 56,115,232,235,134,191, 29,
+254,182, 55, 0,116, 25, 52,245,100,143,193,211, 99, 0, 96,245,247,135,109,247,126, 49,180,218,204,218, 29,155,249, 38,249,177,
+ 97, 62, 90, 69,154,149,187,152,239, 20, 27, 27,203, 5, 0, 23, 23,151, 90, 29,155,110,128, 52, 13,152,198,229,241, 58,120,251,
+248, 4, 2, 96,241,143, 30, 69, 24,244,250,203,206,192,230,151,188, 47,205, 96,236,207,131,179,114, 56, 28,218, 33, 9, 33,175,
+155,227,165,197,213,241,191,124,152,173,234, 30,106, 13,112, 33, 14,232,216, 58, 0,147, 71,190, 43,169,248,183,131, 91,150,122,
+196,222,252,165,209, 15, 63,174,229, 6, 4, 4, 32, 33, 33,161, 86,107, 81,160, 5,206,199, 2,144,223,183,200, 19,139, 31,173,
+ 91,179,198,178,123,247,238,124, 23, 23, 23,112, 56, 28,164,167,167,183, 14, 15, 15,111, 57,107,214,172, 15, 32,191,159, 87,160,
+133,242,124,108,205,185,101,235,218,180, 97, 61, 44,158, 62, 84, 10, 0, 11,199,108,110,121,243, 97,134,205,163, 71,143,186,206,
+155, 55, 47,135,119,238,220,183,118,192,246, 12, 32,185, 54,235,185,243,216,117,145, 52,237, 39,175, 81,211,167, 31,242,241,241,
+145,120,122,122,114, 44, 44, 44,192,227,241,144,151,151,231, 17, 21, 21,213,251,198,141, 27,234,240, 11,255, 51,189,117,163, 95,
+124,166,232,157,162, 90,109,123, 97,170,232,140,133, 69,244,232,129, 3,221,134, 14, 29, 42,242,246,246, 6, 0, 60,122,244,200,
+247,224,193,131,195, 15, 29, 58,180, 4,133,169,250, 2, 45,138,106,218,246,242, 76, 0, 34,160,173,149,131,195, 40,158, 64,208,
+ 84,175,215,187,150,182, 54, 60, 53, 20, 23, 71,203, 51, 51,119, 63,187, 60,249, 43, 77, 49,112, 63, 13,232,214, 33, 16,163, 7,
+117, 19, 3,192,188, 97,203, 91, 63,121, 28,103,162,213,106,209,208,175,113,187,207,191,248,234, 52,184, 92,236, 58, 28, 94,190,
+124,109, 50, 35,239, 39, 32,228,243,117, 72,189,123,176,181, 33, 63,174,179, 82,145,207, 3, 0, 75,169,116,208,193,125, 63,157,
+115,241, 31,114, 45, 46, 91, 87,171,204,234,142,205, 83,251, 54, 57,167, 68,157,107,242,205,153,109, 2, 15, 15, 15,220,189,123,
+183,110,199,102,254, 67, 11,163,179,243,189,181,159,124,226, 20, 20, 20, 4,137, 68, 2, 62,159, 15,189, 94,223,237,242,229,203,
+221, 66, 66, 66,166, 34,255,161,186,182,199,102, 45,172,229,112, 56,157,199, 77,158,225,252,110,255, 33, 24,212,171, 29,237,136,
+132,144,215, 77, 89,235, 85,197, 43, 15,191,175,182,208,226,243,249,153,221,199,174,112,232,240, 78, 51,220,188, 19,147,159,152,
+148,166, 42,251, 91,110,244,193,134,253,219,185, 54,185,120,241, 2, 52, 26, 13,174, 92,185,130, 59,119,238,224,241,227,199,152,
+ 50,101,138,166,244,212, 97,101,153,121, 65,195,151, 90, 35, 63, 86,226,107,250,176,126,248,131, 7,188,162,162, 34, 92,188,120,
+ 17,121,121,121, 48, 53, 53,133,155,155, 27,122,244,232,193,127,240,224,129, 77,215,238,189,164, 65,189, 70, 36, 64,234,171,226,
+243,249,121, 85,205, 35,194,231,243, 51,187,142, 89,230,208,196,183, 30, 30, 37,166,230, 47,254,226, 7,149,209,200,248,241,143,
+159,232, 46, 92,184,128,192,192, 64,156, 61,123,214, 54, 55, 55,247,211,205,155, 55, 47, 22,172,250,102, 67,177, 54,103, 14,170,
+206,203, 11, 26,190,212,218, 54,243,128,231,111,167,142,152, 68, 71, 71,155,124,247,221,119,200,201,201,129,169,169, 41,172,172,
+172,224,228,228,132,134, 13, 27,114, 22, 46, 92, 40, 9, 14,142,198,255, 77, 26,226,169,243,154,248,176,170,245, 44,223,118,213,
+ 19,115, 59,197, 25,239,195,199,143,115,219,183,111,255,167,143,237, 13, 26, 52, 64,207,158, 61, 69,163, 70,141,242, 30, 58,124,
+164, 49,168,207,184, 71,144,120, 22,212,152,169, 78, 54,179, 45,184,234,210,109,248,240,163, 75,151, 46,181,114,114,114,130, 88,
+ 44, 6, 0,228,231,231,187, 37, 38, 38,182, 94,178,100,201,224,235,145,251,248, 65,193,201,169, 16,187, 23, 86,247,124,254, 87,
+ 9, 4,252,204,178, 86, 36, 11,177, 89, 94,114, 74,134, 26, 0,180, 90, 45,180, 90, 45, 52, 26, 13, 62,156, 58,133, 55,105,112,
+ 43, 31,207, 14, 51,110, 63,126,154,145,219, 56,252,154, 77,217,125,139,107,200,228, 23, 60,150,203,147,126,157, 20,242,201, 39,
+ 78,142,142,127,156, 17,220,181,115, 39, 47, 55, 55,183, 91, 72, 72, 72, 19,102,222, 73,222, 56,120,169, 85,117,153,213, 29,155,
+242,152,227,245, 63,159,222,179,249,150, 47,194, 96, 48, 24,112,245,234, 85, 92,188,120, 17, 95,125,245, 21, 59,121,242,100,190,
+165, 88, 60, 9,213, 30,155, 15, 45,218, 59,167,123,173, 90,117,136, 35, 20, 10,241,203, 47,191,224,193,131, 7,224,114,185, 8,
+ 8, 8,192,232,209,163,209,173, 91, 55,167,201,147,167,176,160, 94,195,226, 33,245, 83,190,224,190,196, 5, 48, 99, 65,200, 42,
+231, 49, 19,167, 97,245,231, 11,169,208, 34,132,188,206,173, 89, 85, 14,241,128,176,176, 48, 86,122,235, 8, 0, 12,224, 54, 24,
+176,101,239,129, 91,198,227, 13, 6,108,217,203, 0, 46, 3,184,150, 64,189,183,222,122,171, 88, 46,151,179, 27, 55,110,176, 15,
+ 63,252, 80,189, 97,195,134,115,199,143, 31, 63,168,215,233,182,186, 56, 59,127,201,170,232, 96,207, 0,174, 39, 32, 53, 55, 55,
+207, 74, 74, 74, 98, 39, 78,156, 96,161,161,161,108,247,238,221,236,228,201,147, 44, 60, 60,156,157, 60,121,146,237,221,187,151,
+ 69, 70, 70,178,152,152, 24, 38, 22,139,179, 60, 1,105, 53,153, 60, 6,240, 26, 14,248,110,206,161,155,197, 75,253, 6,108,153,
+197, 0,158, 53,208,232,173,183,222, 50, 28, 60,120,144,237,218,181,139,253,248,227,143, 44, 50, 50,146,101,103,103, 51,190, 80,
+156, 85,118,191,170,214,147, 1, 92, 87, 87,215, 44,185, 92,206,220,221,221,153,169,169, 41,115,116,116,100, 13, 27, 54,100,173,
+ 91,183,102,189,123,247,102, 35, 71,142,100,159,126,250, 41,147,203,229, 76, 36, 18,101,148,221,175,170,204, 64,192, 76, 44, 22,
+ 39,201,100, 50, 86,149,194,194, 66,150,157,157,205, 78,159, 62,205,196, 98,113, 82, 32, 96, 86, 93,166, 25,208,194,223,223, 63,
+ 43, 59, 59,155,233,116, 58,150,148,148,196,162,162,162,216,131, 7, 15, 88, 82, 82, 18, 43, 44, 44, 44,207,142,137,137, 97, 94,
+ 94, 94, 89,102, 64, 11, 70, 23, 65, 84,185, 47, 61,123,243,112,116,236,237,228,228, 84,120,232,208, 33,246,244,233, 83,182, 99,
+199, 14,198, 5,150, 63,187, 92,117,153,166, 64,143,246,237,219, 27,174, 94,189,202,110,223,190,205,230,207,159,207,122,246,236,
+201,122,245,234,197, 66, 66, 66, 88, 74, 74, 10, 75, 73, 73, 97,189,123,247, 54,152, 2, 61,106,218, 63, 43, 59, 54,165,128, 71,
+112,112,112,161, 78,167, 99,241,241,241,172,105,211,166, 41, 60, 96,148, 24,104,210, 17, 16,214,180,127,186, 2,214,206,206,206,
+105, 87,175, 94,101,135, 15, 31,102,158,158,158, 89, 60, 96,156, 37,208,192, 18,104,192, 3,198, 53,104,208, 32,235,234,213,171,
+ 44, 39, 39,135,121,120,120,164,185, 2,214, 47,176, 47,113, 1,108, 91, 16,178,138, 61, 76, 81,179, 5, 33,171, 24,128, 36,198,
+ 24, 67, 37,125, 60, 9, 33,111,190,103,107,145, 55, 69,249,155,100,112,112, 48, 7,192,249,234, 22, 46,228,241, 86,172, 94,189,
+154, 95, 84, 84,132, 31,126,248, 65,249,222,224,193, 7, 58,118,232, 16, 95,223,211, 83,206,225,114,107,156,109, 56, 75, 40,156,
+185,122,245,106, 43,173, 86,139, 91,183,110,161,101,203,150,112,114,114,130, 68, 34,129, 68, 34,129,131,131, 3,252,252,252,144,
+153,153, 9, 11, 11, 11,204,157, 59, 87,154, 37, 20,206,172, 41,215,104,100,124, 0, 48, 24,141,166, 38,192,100,175,183,223,190,
+181,100,201, 18,174,173,173, 45,108,108,108, 32,145, 72,240,224,193, 3,104,181, 90,152,155,153,215,106,144, 86, 46,151,203,149,
+ 72, 36,248,237,183,223, 48, 99,198, 12,180,109,219, 22, 86, 86, 86,176,176,176, 64,211,166, 77,209,163, 71, 15, 76,154, 52, 9,
+241,241,241,224,212,162, 83,201, 61, 62,127,218,164, 73,147, 28, 2, 3, 3, 43,253,123, 81, 81, 17,228,114, 57,178,178,178,224,
+230,230,134, 33, 67,134, 56,220,227,243,167, 85,149,103, 11, 56,185,249,250, 30,189,113,227,134,157, 88, 44,198,174, 93,187,112,
+228,200, 17,156, 58,117, 10, 39, 78,156, 64, 88, 88, 24,126,249,229, 23,100,101,101, 1, 0,124,125,125,177,127,255,126, 59,137,
+131, 67,152, 45,224, 68,135,116,237, 60,201,200, 56,211, 52, 61,221,110,212,200,145,151, 84, 42, 21, 70,141, 26,133, 21, 43, 87,
+ 46, 20, 0,179,106,115,127, 63, 64,106,227,236,188,125,213,170, 85,220,244,244,116, 12, 28, 56, 48,123,237,202,149, 19, 34, 78,
+159,246,150,157, 58,229,189, 98,233,210, 9, 29, 59,118,204, 78, 73, 73,193,206,157, 59,185,142, 30, 30,219,253, 0,105, 93,215,
+ 83, 9,204, 88,191,126,189,168,168,168, 8,221,187,119,143, 55, 70, 71,251,233,129,159, 84,192,131,243,128,174,166,251,167, 1,
+211,230,206,157,235, 36, 20, 10,241,241,199, 31,103, 23, 60,121,210, 76, 15,252,152, 15, 36,230, 3,137,122,224, 71,101, 66, 66,
+179, 49, 99,198,100, 11,133, 66,172, 91,183,206, 41,237,143, 73,183,107,171, 37,128,163, 0, 46, 0, 72, 29, 55,121,198,184,192,
+ 86,109,176,115,235,102,124,177,116,222,118, 0,239,113, 56,156,221, 0,230,208,158, 71,200,127, 83,109,106,145,127,169, 42,167,
+220,225, 87,172, 36, 1,116,170, 46,197,218,214,182,101,179,102,205,112,241,226, 69,248,251,251,223,176,178,178,210,155, 8,133,
+ 16, 8, 4, 96,198, 26,235, 44,152,137,197, 93,187,117,235,198,191,118,237, 26,188,188,188, 96,102,102, 6,129, 64,240,167,155,
+137,137, 9,156,157,157,161, 80, 40,208,181,107, 87,193,198,141, 27,187, 66,163,249,188,198,127,136,177, 81,146,172,107,171, 70,
+254,111,199,246, 6, 65, 65, 65,200,207, 87,192,104, 52,194,220,220, 28, 90,173, 22,124, 62,191,228, 20, 80, 49, 83,212,230, 25,
+ 51, 24, 12, 6, 30,143, 7, 47, 47, 47,172, 88,177, 2, 69, 69, 69, 48, 49, 49, 1, 0, 40, 20, 10,200,229,114, 68, 69, 69, 33,
+ 49, 49, 17,165,159,194,171,101, 33,149,190, 59,116,232,208, 74, 39,252,213,104, 52,200,207,207, 71,126,126, 62,228,114, 57,138,
+138,138,208,166, 77, 27,211,227, 97, 97,239, 34, 39,103,109,165,247, 17,137, 6,239,220,185,211,193,212,212, 20,133,133,133, 80,
+ 42,149, 72, 78, 78,198,147, 39, 79,138, 50, 51, 51,245, 22, 22, 22, 92, 79, 79, 79,174, 80, 40, 20, 14, 24, 48,128,163, 80, 40,
+192,225,112, 16, 28, 28,108,187,103,215,174,161,208,106,191,162, 67,186,118,206, 0,154, 22, 90,109,223,119, 90,181,250,237,198,
+205,155,129, 51,103,206, 68,100,100,228, 42,243,125,251, 46, 20, 0,119,170,187,111, 60, 48,237,203, 10, 5, 12,123,242,196, 95,
+ 7,100, 85, 88, 36,209, 51, 33,225,212,152, 49, 99,238, 70, 70, 70,218,173, 91,183,206,233,189,129, 3,167, 1, 88, 94,151,117,
+180,144, 74,223,118,118,118,198,201,147, 39,145,244,248,241, 60, 61, 80, 88,167, 79, 92, 60, 94,251,160,160, 32,252,242,203, 47,
+ 72,121,242,100,158,254,207,235, 88,242, 65, 9,200,226,199,199,207,219,190,125,251,182,241,227,199,131,199,231,183,135,190, 78,
+ 39, 14,255,210,241,125,252,148,153,216,254,253,198,237, 0, 38, 2, 48, 2,184, 65,123, 28, 33,255,237, 86,173,154,106,145,215,
+168,216,250,190,206, 45, 90, 14, 14, 14,174, 18,137, 4,169,169,169,104,220,168, 81,166, 80, 40,132,169, 64, 0,145,169,105,173,
+214,160,160,160,192,223,197,197, 5,249,249,249,176,179,179,131,137,137, 73,249,205,212,212,180,252,123, 11, 11, 11,112,185, 92,
+120,120,120,160,160,160,192,191,198,220,140, 40,135,125, 27,167,126,120,245,194,201, 6, 3, 7, 14,130,181,181, 13,220,221,221,
+224,224,224, 0, 51, 51, 51,184,187,187,195,219,219,155,173, 93,187, 22,230, 14, 1,181,122, 35,175, 88, 60,241,249,124, 24, 12,
+ 6,100,100,100,224,225,195,135,136,140,140,196,213,171, 87,113,251,246,109, 40,149, 74,212,162,206, 66, 65, 97, 97,115, 62,159,
+ 95,105,145, 37,151,203, 33,151,203,203, 11,173,172,172, 44, 36, 38, 38, 66,165, 86,191, 85, 77,209, 59,168, 89,179,102, 60, 0,
+ 48, 51, 51,195, 91,111,189,133, 45, 91,182,232,143, 29, 57, 50,172,201,213,171, 54,238,167, 79, 91,253,239,187,239,134, 13, 25,
+ 50,196,112,237,218, 53, 40, 20, 10,220,191,127, 31,246,246,246,124, 83,145,104, 40, 29,206,117, 35, 3,212,118, 74,101,175,182,
+109,219, 38,228,231,231, 99,205,154, 53, 92,129,133,197,247, 75,171, 56,197, 87,142,199,107, 23, 20, 20,132,163, 71,143, 34,245,
+201,147,249, 79, 42, 41, 96,158, 0, 89, 73,241,241,243,183,111,223,142, 30, 61,122,128,195,231,215,185,163, 82,235,214,173,155,
+ 25,141, 70,220,189,123, 23, 86,192,245,186,222,223,219,199, 39,176,172,229, 87, 12, 92,170,106, 57, 49,112, 41, 34, 34, 2,102,
+102,102,104,220,164, 73,139, 58, 62,204, 90, 14,135,147, 54,126,202, 76, 28, 62,245, 59, 0, 96,251,247, 27, 51, 42, 20, 89,132,
+ 16,106,209,122, 93, 91,180,202, 10,171,138, 55,252,169,208,170,101,241, 1, 0, 16, 8, 4, 48, 21, 10, 97,106,106, 90, 82, 32,
+ 9,133,181,206,224,112, 56, 16,137, 68,229,133, 85,197, 2,171,226,247,230,230,230,181, 42, 96, 0, 32, 47,238, 84,135,137, 19,
+198,155, 10,133, 66,104,181, 26, 48,198, 32, 20,138, 96,101,101, 5, 47, 47, 47, 40, 20, 10,180,109,215, 81,147, 44, 55, 9,179,
+109, 60, 32,242,121,158, 61,189, 94, 15,181, 90,141,188,188, 60,228,230,230, 66,161, 80,160,176,176,176,214,151,162, 27,141, 70,
+ 94,114,114, 50,126,250,233, 39,228,228,228, 0, 40,233,104, 93, 86, 92,149,125, 77, 72, 72,192,174, 93,187,240,248,241,227, 58,
+189, 62, 29, 58,116, 64, 88, 88, 24,175, 83,215,174, 91,207,122,122,166,158,245,244, 76,237,212,181,235,214,163, 71,143,242, 92,
+ 93, 93,145,152,152,136, 91,183,110, 33, 47, 47, 15,140, 49,186,126,254, 57, 60, 2,242, 10,114,115,199, 47, 92,184,144, 73, 36,
+ 18,172,249,242,203,230,203,129, 17,181, 45, 96,164,213, 20, 48,210, 23, 43, 96,192, 24,131,209,104,132,193, 96,120,174,109,227,
+112, 56, 28,129, 64, 80,215,161, 21,234,178,112,121,199,247,185,159,174,192,137, 95, 14,150,253, 62,150,138, 44, 66,200, 27,160,
+202,142,240,252, 10, 21,100,249,215,170,100,100,100, 60, 85,171,213, 13, 60, 61, 61,145,146,146,226,224,225,225,241,196, 84, 32,
+128,137,169, 41, 56,220,154,107, 2,115,115,243,187,169,169,169,237, 92, 93, 93,161,215,235,203,139,170,103, 79, 29,150,181,210,
+220,190,125, 27,230,230,230,119, 81, 84,237,200, 9, 48,104,243,234,181,104,209,162,188,101,200,202,202, 10, 86, 86, 82, 8,133,
+ 34, 44, 90,180,200,184,110,237,218,205, 30, 93,150,230,191, 63,107, 33, 91,184,124,235, 75,125,102,107,251,143,201,220,220,252,
+174,187,187,123, 27,169, 84,138,195,135, 15, 35, 49, 49, 17,121,121,121, 40, 40, 40,128, 70,163, 65, 65, 65, 1,180, 90, 45, 68,
+ 34, 17,154, 52,105, 2, 75, 75, 75,132,135,135,223,133, 70, 83,121,113,153,147,115,248,238,221,187,109, 90,181,106, 85,222,162,
+210,185,115,103, 78,231,206,157,237,202, 91,209, 10, 10,144,157,157,141, 27, 55,110, 32, 60, 60, 28, 28, 14, 7,177,177,177, 6,
+ 77, 97,225, 94, 58, 38,158, 79, 17,112,133,183,125,251,182, 15, 62,248, 96, 66,187,118,237, 96, 0,122, 3,216,245, 15, 22, 48,
+ 0,128,171, 87,175, 70, 25, 12,134,118, 13, 27, 54,132, 28,120, 7,192, 47,117, 42, 34,227,226, 34,244,122,125,215,230,205,155,
+227,240,129, 3, 29, 0, 36, 86,182,156, 26,232, 16, 24, 24,136,194,194, 66,220,191,119, 79, 86,135, 34,107,235,130,144, 85,227,
+198, 76,156,134,157, 91, 55, 99,251,247, 27,147,183,109,217,224,142, 90,244, 31, 35,132,252,167, 90,179,106,172, 69,254,165, 38,
+ 87, 85,124,241,235,146,146,159,151, 39,139,136,136,104,208,162, 69, 11,108,221,186,181, 85,219, 54,109,158,154,152,154,234, 77,
+ 77, 76,192,173,197, 63,146, 66,181,250,215, 95,127,253,245,157, 1, 3, 6,240,175, 93,187, 6, 39, 39,167,242, 66,171,236, 43,
+159,207, 7, 99, 12,230,230,230,248,249,231,159,117,133,106,245,175, 53,182, 22, 25,140, 6,110,105,161,199, 24,131, 92, 46,135,
+137,137, 9,190,250,106, 29, 54,173, 93, 59,210, 0, 28,244, 21,219,127, 2, 64,244,143,253,131, 46, 40,248,237,196,137, 19, 45,
+151, 44, 89, 34,112,115,115,131, 92, 46, 71, 94, 94, 30,114,114,114,160, 80, 40,160, 80, 40,144,151,151, 7,185, 92, 14,145, 72,
+132,200,200,200,226,162,130,130,223,170,202, 19, 22, 21, 29, 26, 59,118,236,220,136,136, 8,103, 62,159,143,226,226, 98, 24,141,
+ 70, 24,141, 70,232,116, 58,196,197,197, 33, 58, 58, 26, 15, 30, 60, 64,110,110, 46, 4, 2, 1,120, 60, 30,110,223,190,157, 39,
+ 46, 46, 62,160,165, 99,250,185, 9,128,195,151, 47, 95,158, 48,122,244,104,184,184,185,117, 68, 74, 74,173, 10,152, 35,213, 20,
+ 48,249,207, 87,192,252, 81, 0, 41,149, 55, 19, 18, 18,218,117,234,212, 9,206,110,110,171,154,164,164,156,189, 87,135,126, 90,
+ 6,189,254,210,229,203,151,187,142, 25, 51, 6, 91,183,110, 93,101,159,144,112, 42,235,153,211,156,246,128,125,125,111,239, 85,
+227,198,141,195,153, 51,103, 96,208,235, 47, 85, 19, 89,113,196,247,122,227, 38,207,112,127,166,227,251, 22, 14,135, 51, 29,192,
+ 26,218,163, 8, 33,111,114,139, 86,157, 78, 29,154, 25, 12, 11,230,204,153, 83,204,229,114, 49,104,208, 32,139, 95,142, 30, 29,
+114,251,206, 29,175,204,204, 76, 43,131,193, 80, 99,150,189, 70,179, 97,206,156, 57,114,173, 86, 11, 63, 63, 63,228,230,230,194,
+ 96, 48,128,207,231,131,207,231,131,195,225,128,203,229, 66, 34,145, 32, 34, 34, 2,219,182,109, 83,216,107, 52, 27,106,252, 39,
+ 97, 48,220,221,181,107, 23,120, 60, 30, 19,137, 68,224,112, 56,224,243,249, 88,183,110, 93,230, 38,224, 48, 0,240,184, 92, 45,
+ 0,112,185,156,218,246,222,173,241,188,165,169,169, 41,140, 37, 23, 1,212,184,172,181, 70,179,126,245,234,213,202,251,247,239,
+ 67,173, 86,151,183,190,169, 84,170,242,206,245,114,185, 28, 28, 14, 7,106,181, 26, 71,143, 30, 85, 90,107, 52,235,171,202,203,
+ 1,210, 83, 98, 99,251,181,106,213, 42, 39, 33, 33, 1,249,249,249,184,123,247, 46,194,195,195,177,127,255,126,156, 57,115, 6,
+113,113,113,208,235,245,112,117,117, 5, 99, 12, 71,142, 28,201,215, 43,149,189,115,128,116, 58, 38,170, 86,207,201,169,171,163,
+131, 67,146,189,157, 93, 74, 61, 39,167,174,207,254, 93, 10,196,196,196,196, 64,175,215,195,203,203,203,166,186,126, 90, 76,175,
+191,124,249,242,101,140, 25, 51, 6,238, 13, 26,172,244, 4,236,159, 93,198, 19,176,247,244,246, 94, 89, 86,192, 48,189,254,114,
+ 93,215,217, 2,216,248,201, 39,159, 20,154,152,152, 96,223,190,125, 94,197, 62, 62, 15,248,192, 8, 9,208,168, 19, 96, 82,211,
+253,157,129,205,159,126,250,105, 58,135,195,193,238,221,187,237,164,222,222, 81,124, 96,172, 20,168, 39, 5,234,241,129,177, 82,
+111,239,168,125,251,246,217,233,245,122,204,154, 53, 43,221, 25,216, 92, 77,228, 12,198, 88, 95,198, 88, 16, 99,204,125,219,150,
+ 13, 56,241,203,193,178, 34,107, 34, 74, 58,189,143, 6, 16, 69,123, 28, 33,228, 77, 86,105, 51, 20,191,213,178, 12,128, 57,116,
+108, 29,128,155,119, 30,230,219, 89, 91,158, 46,251, 91,110,244,193,134, 93,252, 45, 3,190,249,230, 27, 8, 4, 2, 36, 39, 39,
+227,222,189,123,176,180,180,196,200,145, 35, 53,133, 74,101,191, 10,115, 29,118, 3, 16, 94,154, 89, 50,159, 90,126,172,196,155,
+ 31,217,224,212,137, 48,158, 84, 42,133, 74,165, 2,151,203,133, 72, 36,130,185,185, 57,204,204,204,112,235,214, 45,244,233,219,
+223,144,101, 30,244,199,128,165,127,204,167, 86,158, 89, 54,214,208, 59,128,121, 4,240,177,131,139,203,156,197,139, 23,155,245,
+236,217, 19, 38, 38, 38,112,171,231,155,238,213,107,205, 70, 46,151,163, 79,201, 81, 44,242,174,231, 34,189, 23,155, 8,128,147,
+ 89,124, 99,177, 75,133,185, 14,255,178,158, 30,218, 11, 94, 63,255,184,214,242,173,183, 74,250,163,203,229,114,100,100,100, 32,
+ 51, 51, 19,114,185, 28,106,181, 26, 0, 16, 22, 22,134, 19, 23, 31, 40, 10,221,134,196, 87,181,158,127,108,251, 67, 11, 23,221,
+245,250,123,118,253,200,179,183,183, 71, 70, 70, 6,178,178,178, 32,151,203, 81, 88, 88, 8,131,193,128,220,220, 92,252,176,253,
+ 71, 67,142, 36,232,113,249,128,144,213,101,170,147,205,108, 84,191,187, 6, 54,241,100, 19, 38, 76,176,176,180,180,132,209,104,
+ 68, 94, 94, 30,146,146,146,144,144,144,128,139, 23, 47,170, 51,229, 90,168,237,186,167,148, 15, 88, 90, 73,230, 75,244,218,101,
+ 86, 28,183,202,197,217, 57,245,201,147, 39, 14, 6,131, 1,174,174,174,122,121,110,238, 74, 83,224,140, 5,144, 6,128,101, 3,
+139,215,111,220, 56,190,127,255,254,120,251,237,183,147,211, 51, 50,234, 87,182, 47, 49,128,231, 7, 72, 11,220,220,162,111,220,
+184,225,148,148,148,132, 49, 99,198,100, 63,121,244,104,126, 89,127,173,124,160,131,167,183,247,202,125,251,246,217, 53,104,208,
+ 0,254,254,254,233,162,164,164,166, 15,129,252, 42,246,207, 42,143, 77,121,204,241,250, 83, 7, 54,123,251,195, 15, 63,132, 94,
+175,199,197,139, 23,113,253,250,117, 60,121,242, 4,191,255,254,187,220, 82, 44, 30, 86, 97,174,195, 74,247,207,222,190,106,175,
+221,187,119,113, 76, 76, 76,176,125,251,118, 68, 68, 68, 0, 0, 2, 3, 3, 49,110,220, 56,232,245,122,140, 26, 53,154, 29,127,
+104, 22, 95,221,254, 9,160, 25,128, 47, 81, 82,228,189,205, 24, 19,113, 56,156, 84, 0,238,168, 91,159, 44,218, 63, 41,147, 50,
+255, 59,153,111,164, 26,231, 58, 92,246, 45,164,127,158,230, 99, 82,234,193, 45, 75,249,237, 59, 4, 53, 90, 26, 26,194,109,213,
+170, 21,220,221,221, 17, 24, 24,136,164,164, 36,161,149,149, 85, 77,243,169,169,130,122,141, 72, 8, 8, 8,176,154, 63,127,190,
+180, 71,143, 30, 2,119,119,119, 48,198, 16, 17, 17,129,195,135, 15,235,182,110,221,170, 40,112,236, 43,151,157,251, 73, 85,155,
+249,212,174, 3, 5, 0, 62,115, 75, 77,253,126,218,212,169, 33,111,181,104, 49, 33, 52, 52,148, 43, 49, 55, 19,172, 88, 52, 81,
+ 4, 0,203,190,222, 47,237, 63,100, 36,214,251, 0, 29, 71, 84, 62,143, 92,197,245, 76, 74,153,244,228,221,129, 93,125, 62,158,
+ 62,222, 48,116,232, 80,177,165,165, 37,220,221,221, 97,109,109,141,248,248,120,164,164,164,176, 99,199,142,169,174,222,142, 17,
+ 28, 57,115,243,137, 72,234, 92,155,121, 9,149, 65, 61,223,123,252,238,187,239, 90,143, 29, 59,214,162,101,203,150, 2,161, 80,
+ 8,161, 80,136,140,140, 12,196,197,197,233,142, 29, 59,166, 42,112,232,157, 39, 59,183, 79, 89,203,185, 14, 11,131,134, 47,141,
+187,116, 54,116, 86,244,221,187,163,141, 64,115,157, 78,231,106, 48, 24, 56, 92, 46, 55,205,104, 52,222,213, 41,149,219, 52,129,
+161,235,104,174,195,218, 49, 24, 12, 38, 6,131, 1,114,185, 28,103,207,158,229, 63,122,244,104,241,157, 59,119, 22,167,166,166,
+162,184,184, 24,131, 7, 15, 70, 96, 96, 32,206,157, 59,135,172,140,140, 99,213,101, 61, 4,242,133, 41, 41,227, 38, 77,154,116,
+114,215,174, 93,220, 59,119,238,216,109,223,190,253,135,202, 10,152,209,163, 71, 27, 51,146,146,198,105,128,252,106,246,207,234,
+142,205,236, 83,251, 54,221, 25, 48,104, 72,147,208, 37,139, 5,109,219,182,133,157,157, 29, 58,116,232, 0,157, 78,103,213,184,
+113,227,154,142, 77,101, 80,175, 97,241,205,155, 55, 23,175, 91,183,206,105,252,248,241,152, 62,125, 58, 0,160,176,176, 16,103,
+206,156,193,172, 89,179,210,147,248,239,168,107,218, 63, 75, 91,170,202, 10,176, 11, 0,130, 0,196,131, 58,190, 19, 66,222, 76,
+101,147, 74, 59,163,100, 98,233,227, 40,249,112, 94,243, 92,135,151,174, 71,161,226, 52, 31, 37,156,239,233, 61,198, 62,154, 50,
+103,165, 63,175, 88, 97, 45,224, 20, 89,198,198,196,112,106,154,243,176,124, 62, 53,169,175,202, 54, 97,111,171, 21,203,150,205,
+ 92,191,126,125,215,178, 33, 28,204,205,205,239, 22,170,213,191,218,107, 52, 27, 10,164,190,191,214,117,110,190, 20, 32, 3,192,
+ 84,107,153,108, 99,112,255,193,171, 69, 54, 94,130,133,203,183, 22,241,184, 92,109, 92,106, 22,214,251, 0,226, 90, 92, 32, 89,
+160, 5,162,229,206,250, 12,219, 33, 15, 63,253,228,147,143,151,125,246, 89, 43,137, 68,210, 81,167,215,251, 26,141, 70,192,104,
+140, 45, 80,171, 47, 48,157,238,134, 38,112,201, 90,145,212,153,213,122, 94, 66,171,198, 74,155,199, 7, 91,237,216,182,109,198,
+129, 3, 7,254,178,237,182, 26,205,198, 2,171,198,225,181,217,246,138,203, 20, 1, 87,144,153,121,165,186,166, 75,154,235,176,
+150,159, 62,140,198,201,214,214,214, 59,187,118,237, 42,234,214,173, 27,250,244,233,131,182,109,219,194,104, 52,130, 49, 6,165,
+ 82,137,253,251,247, 99,245,234,213,177,245,129,207,106,202,211, 0,191, 10, 79,156,232,221,188,121,243,237,213, 21, 48,165, 69,
+ 86,141,125, 18,171, 63, 54,133,177,122,105,191,196,225,211, 86,248,104, 21,105, 86,182,230,122,167,232,168,187,220,218, 31,155,
+126, 74, 67,196,254,119, 6, 15, 28, 56,141,199,231,119, 40,189, 2,146,221,191,119, 79, 86, 54,169, 52, 2,199,157,173,227,190,
+ 84, 54,118, 29,117,124, 39,132,188,233,133, 86, 31,148,244,215, 42,159,146,167,202,185, 14,203, 90,125,248,124,126,102,252,145,
+ 41, 35,171, 75, 23, 0, 93, 75, 91,178, 80,227, 92,135,165,223, 39, 2, 74,104, 52,159,255,105, 48,210, 10, 87, 23, 10,158, 89,
+190, 46,195, 34,230, 1, 15,161,215, 4, 35,243, 30,112,116,106, 73, 94,171,101,243, 42,110, 83,149,255,100,255,244,184, 38,185,
+ 69,192, 37,168, 84,151,160, 82, 85,218,105, 87,192, 55,201,173,105, 61,159,221,246, 36, 64,241,162,219,254,108,102,141,197,195,
+ 11, 60,159,255, 53, 79,179,179,143, 0,144,184,133,133, 57,158, 10, 11, 27,250,241,236,217,131,157, 93, 92,188,237,236,236,172,
+ 45, 44, 44,184,215,174, 93, 75,208, 23, 21,109,124, 11,216, 81,218,154, 90, 35, 13,240,171, 95, 82, 82,211,247, 6, 14,156,198,
+225,243,219, 87, 44, 96,152, 94,255,187, 23,176,185,186,150,172,231, 61, 54,221,133,206, 93, 75, 91,178,192, 3, 38,213,102,223,
+ 72, 41, 89,143,229,208,235,151, 35, 50,178,146,125,190,206,251,210, 50, 14,135,163, 4,117,124, 39,132,188,185,202,230, 59, 60,
+254,119, 63,112, 55,202,164,204, 55, 40,147,135,146,171,232,232,249,164, 76,202,164, 76,202, 36,181,194,167,167,128,144, 90, 51,
+224,143,211, 96,132, 16, 66, 72,153,178,190, 89, 21,125, 15,148,116,221,169,170, 42,173,203,213, 4,207, 83,217,134, 83, 38,101,
+ 82, 38,101, 82, 38,101, 82,230,127, 46,179,166,236,215,241,106,198,178, 62, 89,229,125,179,254, 46,212,172, 74,153,148, 73,153,
+148, 73,153,148, 73,153,111, 58,231,210, 34,171,226, 13, 64, 29, 7, 44, 37,132,144, 55, 85,104, 40,184,140,129,195, 88, 40,151,
+177, 3, 60,198,134,240, 24,195, 11, 77, 5, 50,100, 72,229,131,217,254,223, 72,107, 11,122,198, 9,121,163,164,161,138, 73,165,
+169,143,214, 63,203,195,201,201,105, 11, 0, 78,122,122,250,100, 0, 73,244,148,252,251,216,216,216,116,213,235,245, 80, 40, 20,
+191,190,137,219,215,196, 27, 3, 25, 23,141,203,127,193,144,116, 63, 14, 59, 43, 91,182,177, 15,198,128,243,199, 88, 92, 28, 35,
+238,223,123,132,159,235,240,112,220,222,221,220, 55, 3,192,201,240,228,105,120, 53,227,106, 53,180,183,183, 63,205,231,243,249,
+ 6,131, 97,106,102,102,102, 88,213,133,208, 16, 30, 0, 8,216,185, 5,242,116,135,249, 31,125,192, 17, 20,104,182,201, 53,133,
+234,124,158,128,247, 88, 40,112,186, 60,101, 60,247,100,158,170,205,189,202,238,127,240,224,193, 42,103,241,110,234,131,222, 92,
+ 67,147,190,129,205, 18,226,191,220,208,106,125, 71, 47, 59, 65, 66,242,109,201,170,239,242,183,152, 90,121,246, 29, 51,148, 19,
+198, 55,231,140,222,182, 45, 71, 69, 71, 89,237,173, 0,108,116,128,191, 64, 40,116, 55,232,245,142, 28,128,241,248,252,140, 98,
+141, 38,217, 4,136, 92, 0,200,223,244, 76, 19,161,208,205,160,215, 59, 2,192,191,113, 61,201,159, 85, 89,104, 73, 36,146, 91,
+ 92, 46,215,173,226,100,184,101,243, 9,150,253,174,226,223, 56, 28, 14, 12, 6, 67, 74, 94, 94, 94,203, 58, 60,190, 37,128,161,
+ 0,202, 46, 81,223, 3, 96, 63,158,191,195,177,165,137,137,201, 28,177, 88,220,165,176,176,176, 41, 0,152,153,153, 69,171,213,
+234,223,116, 58,221,151,207,153,203, 7,240,158, 68, 34,233,204,229,114, 59, 51,198, 56,140,177,115, 42,149,234, 55, 0, 7, 0,
+ 60,207, 72, 9,102, 14, 14, 14,203,109,108,108, 70, 44, 88,176, 32,199,214,214,214,111,214,172, 89, 55,115,115,115,127,202,206,
+206, 94,132, 58,204, 81,247,138,121, 59, 57, 57,237, 17, 8, 4,188,228,228,228,206, 0,224,238,238,126, 78,171,213, 26, 50, 51,
+ 51, 71, 2,120, 84,199, 60, 49,128,214, 18,137,164,165, 68, 34, 9, 50, 24, 12,141, 75,231,103,188,175, 82,169, 46,234,116,186,
+ 91, 0,174, 1, 80,255,139,142, 17, 11, 62,159,191,171,116, 95,247, 5,160,124,211,222, 4, 24, 23,141,239, 69, 63,240, 43, 47,
+188,154, 54,170,122, 97, 14, 60, 42, 89,182,214,133, 86,151,142,206,125,251,245,235,206, 5, 0,109,241,201,190,191, 93, 72,251,
+229, 37,111, 78,195, 65,131, 6, 93,217,181,107,151,181, 70,163,193,228,201,147,247,132,135,135,111, 86, 40, 20, 11,170,125,227,
+144, 88,207, 90,179,238,140, 57,135,195, 5, 0, 7,163,209,224,240,244,233, 35,223,123, 81, 87,122, 69, 71, 95, 93, 81,248,224,
+183,107, 70,142, 96,138, 14, 29, 30,212,102, 37, 26,123, 33,184,239,224,129,125, 62,251, 44, 20, 35,134,141,168, 23, 29, 93,100,
+230,106, 25,111,154, 91, 40,246,177,181,119,232,247,217,178,131,156,203,151,142,244,219,181,125,233,111,227,199,219,118,161, 98,
+171, 86, 56,203,248,252,214, 82, 31,159,160, 97, 71,142, 64,226,238,206,231, 11,133, 92, 0,208,107, 52,238,170,228,100,231,125,
+253,250,189, 19, 26, 19,115, 62, 20,184, 78,153,255, 72, 38,169, 75,161,197,229,114,221,158, 62,125,234, 32, 22,139, 75,222,140,
+ 25,131,193, 96,128,193, 96, 40,159,188,152, 49, 86,254, 85,175,215,163, 81,163, 70,181,250, 68, 11,160, 11,128,247, 59,117,234,
+ 52,228,203, 47,191, 20,248,251,251,151, 77, 25,210, 97,225,194,133, 95, 71, 68, 68, 28, 2,176, 3, 37,131, 55,214,246, 19,111,
+ 79,177, 88,188,123,205,154, 53,150,221,187,119,231,187,184,184,128,195,225, 32, 61, 61,189,117,120,120,120,203, 89,179,102, 77,
+ 85,171,213,163, 0,156,174,195,243,211,204,194,194,226,224,192,129, 3,221, 58,118,236, 40,106,210,164, 9, 12, 6, 3,110,223,
+190, 61,254,214,173, 91,195, 15, 29, 58, 20,162, 84, 42,135,160,246,243,181,113, 36, 18,201, 88, 75, 75,203,229, 75,150, 44,177,
+ 25, 53,106,148,105, 84, 84, 84,158,151,151, 23,231,242,229,203,246,251,247,239,159,186,114,229,202,247, 20, 10,197, 34,149, 74,
+245, 35,106, 49,135,162,133,133,197, 45, 46,151,235, 86,155, 66, 24, 64, 93,138,225,183,234,215,175,191,255,210,165, 75,245, 19,
+ 19, 19, 13, 3, 6, 12,216, 9, 0,191,253,246,155,127,113,113, 49,167, 71,143, 30, 39, 83, 82, 82,134, 2,184, 93,203,109, 15,
+176,177,177,249,101,196,136, 17, 54,222,222,222,230,245,235,215,231,136,197, 98,240,120, 60,228,231,231,187, 68, 69, 69,117,187,
+126,253,122, 97,120,120,120,174, 70,163,233, 7, 32,178, 14,175, 83, 91, 7, 7,135,209, 2,129,160,153, 94,175,119, 5, 0, 62,
+159,255,180,184,184, 56, 42, 51, 51,115, 23,128, 43,207,123,128, 56, 58, 58,110, 90,190,124,185, 93,102,102, 38, 91,185,114,229,
+ 38,165, 82, 57,246, 77,125, 51,216,243,211, 1,220,186,121, 29, 40,153, 54,135, 83,201,254,199, 1, 96,242,209, 71,179,209,242,
+237,119, 48,114,196,123, 53,102,190,219,213,109,141,192,212,196,182,168,168,232, 74,126,129,230,128,216, 92, 52,116,196,240,224,
+ 88, 0, 56,121,234,252,208, 86,173,172,207, 73,205,133,239,137, 68,162,182,197, 90, 93,206,137, 95, 83, 62,169, 75, 81,229,234,
+234,122,218,218,218,218, 60, 55, 55, 55, 61, 43, 43,235,219,190,125,251, 46,219,177, 99,135,117, 66, 66, 2,146,147,147, 49,115,
+230, 76, 73, 74, 74,202,180,200,200,200,171, 90,173,182,202,150, 45,165, 50,119,195,194,249,253,151, 72,165,118, 60,177,185, 37,
+ 44,164, 54,240,242,110,142,214,109,251,162,119,159, 9,136,139,141,104,189, 99,251,103, 17, 79,159,134,127, 33,177,105,176, 76,
+ 46,175, 95,229,251, 82,147,134,232,216,111, 96, 73,145,181,100,201,255,179,119,221, 97, 81, 92,237,247,204,246, 70,135,165,131,
+ 5,169, 2, 54,140,177,197,134, 21,236, 37, 38, 26, 77,212, 88, 98, 98,141,209,104,108, 41, 26, 99, 18, 53, 49,177, 36,177, 97,
+ 98,195, 18,172,168, 8,246, 40, 88,232, 32,210,100, 23,118, 41, 91,216,222,230,247,135, 44, 31, 18, 96, 23,163,223, 47,201,183,
+231,121,246,217,221,217,153,179,247,206,189, 51,247,204,123,223,251,190,107,145,155,157, 45, 47, 42,164,188,127,250, 4,141, 59,
+124, 80, 40,203,160, 45, 47,186,118,245, 68,187, 62,125,199, 0, 64,212,129, 61,235, 46,191,255,166,243,160,239, 14,214,200,109,
+ 67, 82,243,247,206,245,116,250,180,161,223,126,235,222,117,238, 92, 70,109, 97,161,174, 96,199, 14,101, 69, 74,138,145,198, 98,
+145,126,195,134, 17,252, 1, 3,216,115,179,178, 24,215, 55,110,124,141,190,110, 93,192, 74,157, 46,206,198,249, 95,229,252, 95,
+135,217, 9,190,225,234,195, 93, 45, 10, 45,130, 32,192,227,241,112,232,208, 33,208,233,116,208,104, 52,181,187, 27,129, 0, 0,
+ 32, 0, 73, 68, 65, 84,208,233,244,102, 63,251,251,251, 91, 83,144,113,158,158,158,223,111,223,190,221, 99,232,208,161, 96,179,
+217,245, 63, 80,169, 84, 12, 30, 60, 24,209,209,209,116,129, 64, 48,249,208,161, 67,147,191,248,226,139, 10,137, 68, 50, 31,117,
+137,161, 91,192,128,144,144,144,248, 11, 23, 46,112,212,106, 53, 82, 82, 82, 80, 83, 83, 3, 38,147, 9, 95, 95, 95, 12, 25, 50,
+132,150,157,157,237, 50,120,240,224,248,220,220,220, 88, 0, 73, 86,148, 53,202,221,221, 61,249,200,145, 35,236,206,157, 59, 19,
+249,249,249,232,218,181, 43, 0, 64, 42,149, 98,204,152, 49,236, 41, 83,166,116,152, 60,121,242, 45,145, 72,212, 15,192, 93, 11,
+124,221, 60, 61, 61,247,141, 29, 59,214,251,139, 47,190,112,176,183,183, 71, 81, 81,145,208,211,211, 51,200,124,190, 39, 79,158,
+204, 28, 57,114,164,215,166, 77,155,182, 30, 61,122,244, 67,145, 72, 52, 13, 64,106,139,170,181, 78, 16,115,185, 92, 84, 84, 84,
+224,224,193,131,120,239,189,247, 64,165, 82, 33, 18,137,112,248,240, 97,188,255,254,251,102, 65, 99,149, 24,230,114,185,209,129,
+129,129, 63, 95,190,124,217,215,201,201, 9,222,222,222,148, 79, 62,249, 36, 34, 32, 32,128,211,182,109, 91,170, 80, 40, 68,124,
+124,124,192,212,169, 83, 79,150,148,148,188,163,209,104, 44, 78,169,121,120,120,252,114,250,244,105,255,140,140, 12,236,216,177,
+ 3,213,213,213, 96, 50,153,112,114,114,130,167,167, 39,130,130,130,136,229,203,151,115, 71,142, 28,201,157, 63,127,254, 47, 90,
+173,182,139, 21,109,212,217,221,221,125,231,128, 1, 3, 2,214,173, 91,231,228,233,233, 9,243,131,129, 84, 42,245, 45, 42, 42,
+122,117,245,234,213, 19,238,222,189,251, 88, 36, 18,205, 6,112,191,149, 23, 78,151,142, 29, 59,198,142, 25, 51,134, 42, 20, 10,
+113,224,192,129, 88,185, 92,222,165, 21,226,242, 31,133,187,119,110,227,221,121, 11,106,189,253,252, 24, 23,206,255, 60,238,232,
+241,224, 59, 78,156,167, 9,169, 37, 42,232, 38,140,205,237, 62,100,232, 12,198,136,152, 49,181,187,126,216,106,103,141,208,162,
+ 51, 25,174, 7,227,190, 41,185,122,237,110, 68,226,197,219,195,198,141, 26, 69, 50, 24, 78, 1, 0,240,225,162,133,244,248, 83,
+167,246, 12,142,238, 33,232,219, 39,170,228,205, 41,139,253, 91, 81,220,224,224,224,224, 43,105,105,105, 30, 44, 22, 11,213,213,
+213,174,187,118,237,250,166, 79,159, 62,148,130,130, 2,100,103,103,163,176,176, 16, 82,169, 20,131, 7, 15,182, 75, 77, 77,253,
+ 17, 64,179, 66, 75, 71, 25,248,185,119, 91,253, 54, 87, 14,175,157,206, 40,115, 39,245,194,142,137,167, 19, 59,253,118, 64,213,
+213,195, 43, 52,104,250,219,107,176,254,179, 99,244, 95, 15,126,185,250,210,197,223, 0, 74,187,230, 51, 2,144,232,245,241,202,
+ 21,144,201, 53,152,242,198, 44, 76,125, 99,150, 43, 9,173, 23,105, 84,243,180,170, 26, 39,123, 70, 86,194,246,159,190, 25, 11,
+192,183,129,216,186,100, 19, 91,205, 99, 61,141,214, 35,246,251,239,249, 17, 51,103,178,238,175, 91,167,168, 76, 73, 81, 5,142,
+ 24, 81,211,117,206, 28, 13, 0,200, 11, 11, 25,185,107,214,112,249,175,189,198,233,185,116,169,179, 81,171,245, 92,191,126,253,
+ 43,171,159, 38, 47,111, 21,167,255,164, 73,198,213,123,246,116, 79, 89,188,184, 63,161,215, 83,135,245,236,121,111,227,129, 3,
+101,127,133,243, 69,150, 83,144,156,172,169, 14, 8, 64,215, 49, 99,170,252,221,221, 53, 47,178,238,127,165,156, 54,212,195,236,
+171,245,110,195, 39, 84, 36, 36, 36,244, 3,112, 5,192,186,216,216,216,181, 0,224,232,232, 88, 33,145, 72,220,227,227,227, 45,
+138, 44, 58,157, 14, 47, 47, 47, 4, 5, 5,137, 68, 34,145, 71, 11, 5, 40, 53,153, 76,190, 36, 73,214, 91, 95,154,131, 70,163,
+ 65, 94, 94, 30, 58,117,234,244, 4, 79, 19,209, 54,107,212,225,114,185, 5,217,217,217,110,153,153,153,184,123,247, 46, 2, 2,
+ 2,224,236,236, 12, 58,157, 14,189, 94, 15,153, 76,134,144,144, 16,176, 88, 44,116,235,214,173, 82,161, 80, 4, 88,152, 2, 98,
+241,120,188,188,228,228,100,191,174, 93,187,226,143, 63,254,128,159,159, 31, 60, 61, 61, 1, 0,133,133,133,184,118,237, 26, 70,
+140, 24,129,180,180, 52,140, 31, 63,190, 84,161, 80, 4, 1,208, 52, 71,232,226,226, 34,188,124,249,242,147,200,200, 72,181, 66,
+161,160, 84, 84, 84,208, 83, 82, 82, 12,114,185,220, 78, 42,149,210, 37, 18, 9, 93, 38,147,209, 20, 10, 5,157, 66,161, 48, 84,
+ 42, 21,253,210,165, 75, 84,157, 78,215, 98,128, 76,115, 59,157, 58,117, 10,145,145,145,136,143,143,199,146, 37, 75,112,253,250,
+117,248,249,249,225,200,145, 35, 88,186,116, 41,114,114,114,224,230,230,134,142, 29, 59, 90,106, 35,116,232,208, 33,255,225,195,
+135, 29, 24, 12,134, 57,175,163, 57, 95, 30,196, 98, 49, 30, 61,122,132,178,178, 50, 4, 6, 6,226,141, 55,222,120, 84, 86, 86,
+ 22,104,169,231,249,248,248,136, 51, 50, 50,220, 58,117,234,132,138,138, 10, 56, 57, 57,193,209,209, 17, 78, 78, 78,245,159, 3,
+ 2, 2,176,120,241, 98,120,122,122,138,212,106,181,135, 37, 17, 20, 25, 25,121,254,210,165, 75,110, 14, 14, 14, 40, 47, 47,135,
+ 76, 38, 3,141, 70, 3,151,203,133,155,155, 91,189,144,207,203,203, 67, 76, 76, 76,101, 65, 65,193,208, 86,136, 36,138,135,135,
+ 71,246,131, 7, 15,130, 72,146, 68, 73, 73, 9,114,114,114, 48,111,222,188, 60,181, 90, 29,138,127, 81,206,190, 6,126, 87,140,
+105,111,191,203, 24, 59,186,151, 54, 43, 35,129, 96,153,114,208, 37,194, 65, 10, 0,247,210,101,142, 26, 74, 8,194,194, 99,201,
+227, 39,111, 48,247,237,221, 69,135, 9, 30, 32,144,147,149,135, 79,155,227, 30, 50,192,107,230,194,133,239, 68,244,239,211,143,
+ 34, 87, 40,220,127,252,241,219,110, 5, 5, 89,238, 0, 16, 16, 16, 38,154, 59,119, 81,170, 61,143, 39,186,114, 45,217,180,101,
+203, 47,233, 23,146,132, 63, 89, 81,228,128,160,160,160,155,167, 78,157,114,115,119,119,135,163,163, 35, 20, 10, 5,116, 58, 29,
+ 50, 51, 51,213,135, 14, 29,210, 59, 56, 56,216,151,151,151, 67, 34,145,128, 32, 8,156, 58,117,170, 4, 64,155,198, 68,102, 31,
+ 45, 0,152, 55, 60,140,222,113, 96,144, 51,131,101,224,112,232,185, 94, 32,140, 44,130,180,243, 56,123,254, 94,167,179,137,127,
+188, 57,118,220, 18,126,223,126, 99,177,122,213, 4,189, 64, 80,210, 85,135,190,217, 77,249,104,133, 6, 98,224,152,241, 99, 39,
+174, 95,191, 22,107, 87,175, 67,194,169, 19, 82, 59, 30, 69,227,224, 68,119,124,237,213,222,234,197,239,141, 46,173,173, 21,248,
+173,223,116,232,141,152,209,139,125,251,244, 29,131,107, 87, 79,224,192,158,117,119, 9, 14,105,155, 70,108,132,181,128,179, 83,
+ 64,192,236, 15,242,242, 24,247,215,174,173, 53, 8, 4, 53, 81,139, 22, 85, 54,181,239,147,196, 68, 30,211,219,219,193,121,212,
+ 40,151,173,109,218,144,122,145,104,103, 83, 62, 70, 77,113, 94,180,179,115,250,237,236,217, 65, 36,157,222,111,217, 71, 31,113,
+ 98, 99, 99, 33,147,201,112,236,216, 49,236,220,177, 67,227,229,229,245,208, 59, 61, 61, 45, 66, 38, 91,101, 45,103,212,162, 69,
+149, 70,163,145,152,184,116,233,224,140,194,194,129,229, 34, 81, 91, 0,240,114,113, 41,141, 10, 8,184,251, 75, 66, 66,206,119,
+237,218,153,172, 45,231,238,115,231, 60,142, 22, 21,205,116,113,113,225, 84,136, 68, 52, 22,147, 89,245,106,199,142, 71,126, 88,
+185,242,138,225,193, 3, 6,219,215,215,193, 49, 54,182,213,117,143, 90,180,168,178, 90, 46,167,125,240,217,103,189,139, 43, 42,
+218,214,106, 52,129, 18,185,220,211,168,215, 83, 28,184,220,170,246, 33, 33, 34, 85, 74,138,176,189, 82,185,224, 39, 64,244,178,
+218,186, 41, 45,242, 15, 66,227, 56, 90,127,202,117,120, 37, 54, 54,246, 79,171,107, 72,146,180,202,154, 69,167,211,159,153,166,
+106, 1, 12,130, 32,144,154,154, 10, 87, 87, 87,120,122,122,130,197,122, 54,249,160, 88, 44,198,245,235,215,145,149,149,133,206,
+157, 59,155,167, 49,154, 87, 68, 44,214,194, 77,155, 54, 57,105,181, 90,220,189,123, 23, 81, 81, 81, 96,177, 88, 96, 48, 24,207,
+136, 64,145, 72,132,240,240,112, 44, 91,182,204,241,139, 47,190, 88,168,209,104,154,125, 34,165,209,104,243,103,205,154,229,110,
+182, 96,149,150,150,162, 91,183,110,245,191,243,249,124,220,187,119, 15, 81, 81, 81,240,245,245,197,132, 9, 19,220, 15, 28, 56,
+ 48,223, 96, 48,108,110,142,147,201,100, 82, 34, 35, 35,187, 3, 0,143,199, 3,133, 66,201,117,112,112,224,123,120,120,240, 28,
+ 28, 28,254, 84,199, 61,123,246, 72, 40, 20,138,222,162, 26,160, 80, 80, 94, 94,142,136,136, 8, 72,165, 79, 51,184, 40, 20, 10,
+ 4, 6, 6, 66, 38,147,213,139, 86,111,111,111,168, 84, 45,187,126,117,234,212,105,109,104,104,232, 16, 30,143,199,162,211,233,
+184,127,255, 62,186,118,237,138, 67,135, 14,193,223,223, 31, 92, 46, 23,121,121,121,136,140,140, 68,114,114, 50,248,124, 62,194,
+195,195, 89,238,238,238, 87,171,171,171,147,138,139,139,215,182, 80, 78,138,157,157, 29,146,147,147,241,203, 47,191,160,176,176,
+ 16, 2,129, 0,246,246,246,232,210,165, 11, 58,118,236,136, 94,189,122, 33, 47, 47, 15,132,229,206,228, 25, 20, 20,148,240,199,
+ 31,127,184,145, 36,137, 3, 7, 14,160,182,182, 22, 90,173, 22, 20, 10, 5,108, 54, 27,206,206,206, 24, 56,112, 32,248,124, 62,
+130,130,130,112,248,240, 97,183,225,195,135,159, 17,137, 68, 93, 0,148, 91, 58,175,206,206,206, 11,214,172, 89,227,231,238,238,
+142,162,162, 34, 72,165, 82,120,120,120,160,127,255,254, 62, 23, 47, 94, 92,160,215,235,191,253,183, 12,100, 13, 28,223,137, 11,
+231,127, 30, 23,212,190, 38,178,115, 8,215, 47, 62,193,195,239, 80,130, 40, 28, 0, 34,194, 60, 50,198,197,114, 75,239,103, 36,
+148, 94, 56,127,226,110, 86, 46,226, 97,197,212,182, 84,169, 57,146,120,241,246,176,174,157,187,153, 54,125,185, 52,230,189,121,
+ 51, 89,238, 30, 51, 80, 81,114, 2, 23, 47,167,250, 47, 93, 50,139,191,249,235,221,103, 19, 47,222,166, 72,149,154, 85,214,153,
+178,252,191,219,251, 67, 47, 55,121,229, 81,228,103, 51,193,177,143, 64, 64, 64, 48,100, 50, 25,216,108, 54,251,141, 55,222, 48,
+174, 88,177, 66,233,224,224,192, 37, 8, 2, 73, 73, 73, 34, 0, 67, 45,241,170,221,157, 73,163, 78,111, 32,153, 84, 19, 73,216,
+171, 8, 99, 53, 51, 61,243, 49,134, 68, 15,168,232,211, 35,226,139, 21,235,191,254, 56, 40,184, 43,255,157,153,235,232,159,173,
+125,115, 7, 8,244,109,138, 39, 59, 31,151,137, 35,199, 57, 0, 98,214,127,186, 22, 5, 5,121,206,239, 78,151,172,163,177, 56,
+222,161,109,122,219,239,248, 37,105, 88, 96, 96,187,182,139,231, 79, 56,253,205,247,223,196, 52,180,108,237,221,179,230, 36,128,
+ 65,214,156,219,255, 33,116,154,154,144,128,218,146, 18,125,245,213,171,234, 65,223,127, 95,233, 55,116,232,183, 90,157,206,205,
+124,171,160, 16, 4, 8,179,235,132,201, 68,208,150, 45,163,144, 52, 26,244,206,206,211, 81, 83, 19,108,137,115,137, 80, 56,238,
+205,153, 51, 99, 78,158, 59,135,118,237,218,213,143,103, 78, 78, 78, 88,186,116, 41, 22, 45, 90,196,186,119,239,222, 43, 71,143,
+ 30,125,101,243, 87, 95,121, 0, 24,103, 77, 57, 47,220,186,229, 60,103,253,250,149,157,163,162,252,247, 31, 60,200,234,208,161,
+ 3, 0,224,209,163, 71, 65, 95,110,220,216, 38, 34, 50,178,226,139,133, 11,247,102,172, 88, 17, 14,224,106, 75,156,229, 41, 41,
+218,163, 69, 69, 51, 47, 39, 37, 57, 69, 68, 68, 0, 0,114,114,114,220,183,110,221, 58, 43,124,194,132, 41,235,231,206, 93, 21,
+171, 86, 75, 28,196, 98, 86,236,119,223,209,126,155, 56,209, 34,167,185,156, 0,208,255,157,119, 22,246, 29, 48,160,227,184,153,
+ 51, 93,252,253,253, 9, 59, 59, 59,232,116, 58, 8, 4, 2,231,140,140,140, 14, 9,114,185,236,248,173, 91, 7, 96, 52, 14,126,
+137,109,221,164, 22,249,135, 89,178,254,172, 41,234,222,251, 39, 36, 36,144, 0,250,199,198,198, 38,155, 7,112,163,209,104,149,
+200,162,209,104, 32, 8,194, 90,177, 5,146, 36, 81, 89, 89,137,202,202,202,250,169, 35,145, 72,132,203,151, 47, 35, 47, 47, 15,
+116, 58, 29, 12, 6, 3, 58,157,229, 28,180, 60, 30, 47, 58, 58, 58,154,118,235,214, 45, 4, 4, 4,128,195,225,212,151,203,252,
+ 98, 48, 24,240,242,242,130, 76, 38,195,160, 65,131,232,219,182,109,139,110, 73,104, 57, 58, 58,142,152, 52,105, 18,211,252,189,
+182,182, 22, 84, 42,181, 94,180,212,214,214,162,186,186, 26, 18,137, 4,106,181, 26, 61,123,246,100, 38, 36, 36,140,168,170,170,
+218,108, 77,253,149, 74,101,173, 72, 36,114,234,219,183,175,243,222,189,123,115,122,246,236, 25,242, 76, 79,187,114, 69,173, 86,
+171,233, 20, 10,197,170, 60,122,113,113,113,245,231,190,172,172, 12, 59,118,236,168,255, 45, 47, 47, 15,219,182,109, 3, 73,146,
+ 32, 73,178,197, 54, 10, 13, 13, 29,126,224,192,129,168,253,251,247,215, 80,169, 84,228,228,228,224,224,193,131, 32, 73, 18,124,
+ 62, 31, 74,165, 18, 21, 21, 21, 72, 74, 74,130,193, 96,128,157,157, 29,124,124,124,216,243,231,207,239,179,110,221, 58,122, 75,
+ 66,203,104, 52, 26,169, 84, 42,218,180,105,131,213,171, 87, 67,173, 86,131,193,120,170, 47,101, 50, 25, 36, 18, 9,210,210,210,
+ 80, 84, 84, 4,146, 36, 91, 28,100,216,108,246,132,253,251,247,187, 51,153, 76,168, 84, 42,200,229,114,148,150,150,162,184,184,
+ 88, 45, 18,137, 12,246,246,246,148, 54,109,218, 80, 88, 44, 22,107,204,152, 49,132, 89,112,198,198,198,186, 30, 56,112,224,117,
+173, 86,107, 73, 36,241, 61, 61, 61, 63,158, 53,107, 22,187, 97,159, 45, 47, 47,199,184,113,227,184, 55,110,220, 88, 33,147,201,
+ 14, 2, 16,255,203, 6, 52,242,232,241,224, 59,119, 47,230, 68,198, 39,120,248, 21, 63, 49,246, 94,250,225,215, 52, 0,216,181,
+115, 67,239,248,132,178,235,161,237, 42, 74,143, 30, 15,190,227,236,156,101, 73, 8, 80, 6,246,243, 26,201,227,178, 39,141, 27,
+ 53,138,252,241,199,111,187,189, 55,111, 38,171, 77,240,210,167, 22, 78,186, 59, 6, 25, 62, 37,148,170, 71,236, 31,127,252,182,
+219,184, 81,227,211, 10, 11,139,118, 14,236,199, 58,124, 57, 89,248,123, 75, 22, 67,119, 87,182, 15,151,165,128, 79, 64, 71,132,
+132,241,112,239,126, 14,142, 29,185,137,176,240, 87,161,209,104, 96, 48, 24,120, 35, 71,142, 84, 30, 58,116, 72,157,155,155, 43,
+ 87,169, 84,253, 0,228, 90,170,252,147, 39,153,166, 16,207, 87,117, 12, 14,203, 32,151, 50,148,203, 87, 29,157,216,173,199,144,
+ 40,103, 47, 31, 58,159,103,250,125,248,224, 87, 14,254,242,211,234, 69,171,214, 28, 68,247, 87,134,244,204,202,185,218, 17,192,
+195, 38,197,107, 1, 18, 40,199,142, 27, 10,242,243, 99,138,139,138,158, 4,123,120,106, 31, 73, 72,253,130,229,187, 7,247,237,
+ 55,161, 83,135,176,215,152, 89,153,201,196,234,101,175,255,186,126,211, 55,111,152,197,214,165,196, 95,251, 77,159,126,147,185,
+119,111,243,214,241,255, 53, 48, 88, 44, 95,187, 54,109,104,133,123,247,170, 2, 70,142,172, 1, 0,173, 78,231, 86, 88, 84,228,
+200,229,114, 65,146, 36,244,122,253, 51, 62,196,102,191,225,136,144, 16, 15,107, 56, 11, 63,249,164,211,178,101,203, 80, 94, 94,
+ 14,131,193, 0, 58,157,222,248,158, 13,133, 66,129,233,211,167,227,187,175,190,122,213, 26, 78,163,209, 72,204, 89,191,126,229,
+ 71, 43, 87,118,152, 61,123, 54,165,225,189,215,197,197, 5, 71,143, 29, 99,110,223,190,221,247,227,239,190,155,254, 38,139, 85,
+ 0,141,166, 69,206,202,192, 64,184, 84, 84,112,204, 34, 11, 0, 66, 66, 66,176, 99,199, 14,214,140, 25, 51,152, 35, 71,142,252,
+250, 94,231,206, 91,191,237,211, 39,223, 53, 56,216,129,201, 98,249, 90,226, 52,159, 79, 0,144,171,213, 17,223,110,221,234,124,
+251,246,109, 84, 84, 84,160,188,252,233,243, 40, 65, 16,232,222,189, 59, 49,117,234, 84,199,246,126,126,175,192,104,124,153,205,
+253, 39, 45,242, 15,194,187, 77,108,251,143,143, 86, 93,133,136,186, 10, 18, 13, 6,199,103, 4,139, 37,161,245, 60,144, 72, 36,
+144, 72, 36,248,233,167,159,192, 96, 48,234, 7, 95, 0,208,106,181,214,136,150, 72,111,111,111, 72,165, 82, 4, 7, 7, 63, 99,
+201, 98, 48, 24,160,209,104, 96, 48, 24, 96,177, 88,208,104, 52,240,247,247,135, 82,169,140,108,137, 83,165, 82,117,113,113,113,
+169, 31, 96, 53,117,157, 85,163,209,212,151, 87,171,213,162,166,166, 6,181,181,181,144,203,229, 80, 40, 20, 93,173,169,175,201,
+100, 66,122,122,250,163,144,144,144, 46, 84, 42, 21,118,118,118, 60,133, 66, 81,239, 91, 84, 93, 93,141,125,251,246, 41,222,122,
+235, 45,183, 83,167, 78, 89, 20, 90, 4, 65,224,253,247,223, 7,139,197,130, 82,169,196,143, 63,254,136, 15, 62,248, 0, 12, 6,
+ 3,114,185, 28, 59,118,236,192,226,197,139, 65,163,209,160,213,106,177,117,235,214,102,185, 50, 51, 51, 11,111,221,186,213,181,
+ 91,183,110,206,199,143, 31, 23, 15, 30, 60,152, 63,116,232, 80,112, 56, 28,168, 84, 42,232,245,122,188,250,234,171, 8, 13, 13,
+133, 72, 36,194,217,179,103, 43,131,130,130,220,110,223,190,109, 42, 47, 47, 47,182, 32,174,201, 6, 22, 67, 24,141, 70, 84, 84,
+ 84, 64, 34,145, 64, 44, 22, 67, 32, 16,224,201,147, 39,160,209,104,176,160,179,224,234,234, 58, 62, 34, 34,130, 10, 0, 28, 14,
+ 7, 93,186,116,193,202,149, 43, 13, 42,149,106, 18,128,179,117,187, 13,223,189,123,247,241,107,215,174,209,188,189,189,145,157,
+157, 13, 62,159, 79, 99,179,217, 22,133,150,167,167,231,158,223,127,255,221,197, 44,174,205,231, 89,169,124,218, 28,227,198,141,
+115,217,191,127,255, 30,131,193, 48,226,223, 54,168, 57,113,192,232, 18,225, 32, 61,148, 32, 10, 95,250,225,215,180,208,136,167,
+ 15,175,239,206, 6,109,243, 87, 75,194,167,140,118, 56,237,196,145, 49, 44,241, 12,143,246,219, 62,106,212, 96,202, 27,147, 99,
+243, 24, 12,167,128,157,187,214,185,187,123,204,104, 32,195, 28,224,234,230,128,128, 54, 76,226,232,233, 44,247,229, 43, 62,213,
+196,237,255,166,224,215,223, 18,134, 49,233,137, 67,206, 94, 44,157,219, 28,119,238, 35,201, 41,165,134, 29, 38,171,122, 64,184,
+120,244, 70,151,206, 33,112,231,215, 96,247,158, 67,104,215,190, 59, 52, 26, 13, 28, 28, 28,184, 70,163, 81, 71,165, 82,227,172,
+ 17, 89, 0,112,233,146,196, 20, 30, 46,209, 82,229, 38,195,123, 31,108, 30, 59,120,248,168,142, 3, 7, 70,155, 46, 36, 94,208,
+245,238,170, 19, 14, 31,218,165,226, 92,226,246, 60,161,224,113, 80,120,100, 31,100,102, 36, 13, 35, 73,164, 19, 68,211,214,167,
+140,124,156, 83,155, 50,147, 14, 29,122,215,164, 50,165,113, 62,251,252,225,240,152,152,105, 17,175,245,125,205,148,120,241,178,
+150,137,202, 44,135, 62,189,202,222,155, 57,252,248,207,113, 91,135,156, 59,187, 39, 80, 42, 43, 78,176,137,172, 70, 15,105, 6,
+131, 7,141,197,162,136,147,146, 12,145, 51,102,104,204,215, 35,151,203,197,201,147, 39,193,100, 50,235, 95, 12, 6,163,254,179,
+135,135, 7,136,186,101,164,214,112, 2,128, 80, 40, 68,121,121, 57, 28, 29, 29,193,231,243, 81, 94, 94,142, 27, 55,110, 32, 55,
+ 55, 23,116, 58, 29,195,134, 13, 3,165, 25,223,230,198,156, 19,151, 46, 29, 28, 22, 25,233,223, 88,100, 1,128, 78,167, 67,117,
+117, 53, 70,143, 30, 77, 57,123,246,172,231,185,146,146, 81, 0,226, 90,226,236, 26, 19, 83, 85,113,244,104,147,255,221,173, 91,
+ 55,226,250,245,235,172, 97, 67,135, 46, 90,242,249,231,219,191,219,191,191,212,104, 48,120,182,166,238, 20, 10,133, 66, 16, 4,
+252,252,252, 80, 93, 93,141,218,218,167, 51,216,118,118,118,112,118,118,134, 94,175,135,137, 36,233, 47,179,173,155,211, 34,255,
+ 16,236,106, 32,184,118,253,201,162, 85, 87, 41, 0,232,223,112, 96, 49,153, 76, 86,137, 44, 58,157,110,209,231,202, 26, 43, 87,
+ 99, 88, 35,180,204,101,101,179,217,245, 23, 90, 67,129,101, 46, 39,133, 66, 1,149, 74,181, 56,136,215,137, 33,170, 92, 46,199,
+177, 99,199,208,175, 95,191,250,105, 41,169, 84, 10,137, 68, 2,169, 84, 10,181, 90,141,194,194, 66, 92,186,116, 9,129,129,129,
+128,149,193, 95, 11, 10, 10,238,182,107,215, 46,202, 60,136, 15, 24, 48,192,119,239,222,189,130, 17, 35, 70,120,147, 36,137, 85,
+171, 86, 85,190,250,234,171,110, 13, 7,121, 75,160, 82,169,184,113,227, 6, 2, 3, 3, 65,146, 36, 24, 12, 6,114,114,114,224,
+238,238, 14,147,201, 4, 26,141, 6,177, 88, 12,123,251,150, 99, 36,166,167,167,191,253,206, 59,239, 8, 28, 29, 29, 59, 85, 85,
+ 85, 9, 89, 44, 86,223,148,148, 20, 63,157, 78, 7, 7, 7, 7, 56, 56, 56,224,204,153, 51,112,114,114,194,194,133, 11, 75, 84,
+ 42,213, 13, 30,143,231,161, 82,169, 30,148,151,151,175,106, 77,123, 27, 12, 6, 40, 20, 10,212,212,212,160,186,186, 26, 50,153,
+ 12,106,181,218, 98, 25,155, 66,223,190,125,145,144,144, 64,221,176, 97,195,207, 5, 5, 5, 0,128,128,128, 0, 44, 92,184,144,
+234,227,227,131,194,194, 66,220,189,123, 23, 58,157, 14, 36, 73,182,120,241,210,104,180, 1,111,189,245, 86, 31,127,127,127, 66,
+167,211,193,100, 50, 65,163,209,192,252,185,164,164, 4, 97, 97, 97,148, 54,109,218,244, 44, 40, 40, 24, 0,235, 22, 86,216, 0,
+160,162,228, 4,124,232,238, 0,197, 1,164,234, 4,170, 42,159, 47,138,139, 72, 36,250,124,217, 39,215,103,124,183, 73,231,241,
+ 68, 8,132, 68,140, 65, 80,199, 65,120,123,170, 1, 27,190, 58, 6,255, 54, 33, 40, 46, 46,198,128, 1, 3, 24, 2,129,224,157,
+218,218,218,165,214,114, 39, 38,222, 50, 94, 56,115,118,194,196,215,167, 69, 69, 71,143, 48,156, 63,127, 6,233, 15,206,103,188,
+243,250,120, 17,105,170, 37, 92,156, 56,105, 57,217,119,130, 58,117,233, 15,173,193,216, 23, 88,187, 9, 88, 75, 54,127,189, 67,
+123,250,180, 23,229,244,137, 61, 83,223,152, 50,189,243,160, 65, 67,244,231, 19,127,199,221,155,137,247,191,222, 52, 43,121,195,
+214,195, 3, 6, 15, 27, 31,206,247,184,113, 38, 34, 88, 51,211,207,213,241,209,238,189,213,182,206,210,212,181,201,102,155, 80,
+119, 95,164, 16, 4, 72,146,124, 70,100, 53, 22, 90, 20, 10,197,162, 1,160, 33,103,195,177,200,252, 64,189,115,231, 78,176, 88,
+ 44, 48,153, 76,208,233,116,139,238, 23, 13, 57, 51, 10, 11, 7,238,139,139, 99, 53, 37,178,170,170,170, 80, 85, 85,133,218,218,
+ 90, 76,158, 60,153,177,238,206,157,110,168,115,253,104,142,211,223,203, 75,195,227,112, 42, 50, 51, 51,189, 59,118,236,248, 76,
+121,101, 50, 25, 56, 28, 14,226, 14, 30,100,196,198,196,204, 27,116,230,204,215,176, 16,255,170,169,186, 19, 4, 1,119,119,119,
+ 56, 59, 59,131, 32, 8, 24, 12, 6,148,151,151, 35, 35, 35, 3,119,238,220, 1,149, 32, 12, 47,179,141,155,210, 34,255, 64,171,
+214,174, 38,167, 14,155,155, 19,109,141,208,162, 82,169,207,109,213,106, 14,214, 76, 29,114,185,220,135, 2,129,160,183,143,143,
+ 15, 12, 6, 67,189,208,106, 60,117,104,182,126,220,187,119, 15, 92, 46,247,161, 90,173,110,145,147, 36,201,158,175,188,242, 10,
+226,227,227,145,148,148,132,199,143, 31, 67,169, 84, 66,163,209, 64,165, 82, 33, 35, 35, 3, 38,147, 9, 17, 17, 17,224,241,120,
+224,114,185, 15, 53,154,150, 31, 68, 21, 10,133,144, 78,167,135,112, 56,156,250,109, 94, 94, 94,168,170,170, 50,233,245,122,236,
+219,183, 79,230,233,233,201,227,112, 56, 86, 11, 87,130, 32, 32, 18,137,224,235,235, 91,239,163, 37,151,203,225,238,238,110, 22,
+ 22,208,104, 52,176,183,183,183, 56,117, 8, 64,157,159,159,191,164,193,247,238, 19, 39, 78,252,245,208,161, 67,237, 47, 94,188,
+136,219,183,111,131,207,231,227,139, 47,190,120, 92, 84, 84,244, 6,128, 59, 34,209,139,245,139,180,166, 15, 85, 85, 85, 29,123,
+248,240, 97,207, 87, 94,121,165,254, 46, 49, 96,192, 0, 98,192,128, 1,110, 13, 77,253, 98,177, 24,127,252,241, 7, 46, 94,188,
+ 8,130, 32,144,151,151,103, 84,169, 84,191,182, 52, 75,225,227,227,179,119,229,202,149,118, 6,131,161,190,111,115, 56, 28,176,
+217,108, 48, 24, 12, 80,169, 84, 20, 21, 21, 97,244,232,209,142,223,127,255,253, 30,141, 70,211, 1,128, 14,255, 18, 72, 84,208,
+221, 75,151, 57, 70,132,121,100,236,218,185,161,247,187,179, 97,158, 58, 52, 68,132,185,103,220, 75,175,112,140,114,183, 92,223,
+179, 23, 75,223,211,234,207,142, 60,123,238,202,164, 15, 23, 45,164, 7, 4,132,137, 46, 94, 78,245, 31,100,248,148,112,117,115,
+ 64, 85,165, 12, 69, 37, 21, 40, 40,214,146, 1, 1, 97,162,187,127, 60,100,125,245,237,150, 32,133, 82,109,158, 58,108,177,159,
+ 94,189,241,120,204,215,219, 88,201,211,222,233,206,228,112,188, 81, 93,249, 16,254,254,124,140,142,237,132, 95,246,223,128,163,
+163, 11, 60, 60, 60, 64,161, 80,120,214,214,189,178,178,146, 56,246,219,213, 25,111, 77,159,245,234,208, 33, 49,134,115,231, 79,
+211,146, 46,156,186,177,103,215,199,199, 73,170,130, 75,144,114, 78,219,118,158, 15, 30,229,223,123, 99, 96,244,100,112, 24,246,
+129, 64,104,147, 29,182,126,129, 1,137,146,248, 67,107,217,111, 77,127,183,215,208,161,163, 12,231,207,159,192,249, 51,251,111,
+173, 89,211,246,204,227,178,131,140,155,119,158,176,199, 76,152, 91,147,112, 54, 75, 59,126,100,187, 92,111, 94, 23, 21,240,216,
+166,170, 26, 62, 72,210,104, 21, 6,141,198,207,119,232, 80,170,178,184,152,110,231,225, 97, 0, 0,189, 94,111, 81,104,161,153,
+ 41,232,198,156,214,150, 69,169, 84,194,212, 76,236,196,198,156,229, 34, 81,219,186,135,240,122,232,245,250,122,145, 85, 85, 85,
+ 5,137, 68, 2, 30,143, 7,177, 70,227, 97, 13,231,144, 30, 61,246,173, 91,187,118,233,209, 99,199, 24, 13, 69,150,249, 69,167,
+211,241,229,166, 77,140, 15, 62,252,112,238, 60, 26,109, 1, 12, 6,171,207,167,249,161,157, 74,165,130, 70,163,161,184,184, 24,
+ 37, 37, 37, 40, 46, 46, 70,113,113, 49, 56, 28, 14,200,151,188, 8,232, 31,236,159,101, 22, 89, 13,223,235,173, 92, 45,134,119,
+104,141, 51,188,181,194,192,216,138,249, 93,107,132,150, 66,161,184,120,233,210,165, 30, 99,198,140,161,221,186,117, 11,158,158,
+158,245, 66,203,252,110,158,142,226,114,185, 56,126,252,184, 78,161, 80, 92,180,112, 49, 93, 58,115,230, 76,212,234,213,171,233,
+111,191,253, 54, 50, 51, 51, 49,123,246,108, 72, 36, 18,200,100, 50, 84, 85, 85, 65,169, 84,162, 71,143, 30, 96,179,217,120,240,
+224,129, 94,169, 84, 94,178, 96,177, 35, 69, 34, 81, 45,159,207,247,106,252,219,132, 9, 19, 60,126,248,225, 7,101,118,118,182,
+190,119,239,222, 14,214, 10, 14, 51,126,251,237,183,122, 75, 93,110,110, 46,126,248,225,135,122,159,172,212,212, 84,108,222,188,
+185, 62,246, 89, 43,113,167,178,178,210,160,215,235, 17, 24, 24, 8, 31, 31, 31,168,213,106,108,217,178,197, 0,224,206,255, 87,
+111, 86,171,213, 71,167, 77,155,246, 81, 90, 90,154, 23,141, 70,123,106,210,174,171,159, 78,167, 67,126,126, 62, 50, 50, 50,144,
+157,157,141,234,234,234,250, 7,129,123,247,238,213,232,245,250,195,205,241,242,249,252, 85,191,252,242,139, 39,151,203,125,166,
+ 63,155,173,161,102, 43,169, 88, 44,134,147,147, 19, 6, 13, 26,228,126,233,210,165, 85, 26,141,102,245,191,100, 76, 35, 38,140,
+205,237,254,193,123, 99, 48, 46,150, 91, 26,159, 80,118,125,243, 87, 75,234,156,225,221, 51,198,197,250,148,222,207,113,194,132,
+177, 39,186, 3,120,130,150, 29,182, 77,151,147,133, 39, 95,121,197, 57, 41,254,212,169, 61, 43,150, 45, 74, 93,186,100, 22, 95,
+169,122,196, 14,104,195, 36, 0,160,160, 88, 75, 62,200, 52,169, 55,127,189, 40,117,195,166,239, 41, 21, 85,146,217,127,252,209,
+124,120,131,134,226,133, 66, 1, 59, 32,180,159, 32, 40,184, 79,187, 91, 55,226, 96,199, 85, 33, 36,180, 59,134, 14,233,137,164,
+ 43,247, 80, 46, 86, 67, 40, 20, 66,163,209,180, 24, 46, 33,251,193,241,169, 36, 65,250, 19, 36, 81, 66, 80, 72,246,212,105, 51,
+251,198,196,140, 34, 19, 18, 78, 25, 78, 28,143,187,118,248,192,182,163, 20, 6,157,166,210, 58,106, 9, 66, 45, 5, 37, 61,179,
+ 86,241,244,129,134,206, 98, 52,111,126,173, 11,236,218, 49, 60,212,115,234,180,217,142, 35,134,143, 38,207,156, 57, 97, 58,124,
+104, 95,210,225,159, 34,227, 76, 20, 25, 67, 88,170,100, 73,101,122, 41, 73, 48,157,106,101, 38,101, 69, 65, 7,181,119,204, 4,
+ 29,112,212,166,174, 26,142, 3, 26,205,147,218,210, 82, 47,151,126,253, 88,249,107,215,114, 61,122,244, 80, 19,117, 62,196, 45,
+ 9, 45, 42,149, 10, 80, 40, 38,107, 56,173, 45,139, 74,165,130, 9,208, 63, 15,167,193, 96,120, 70,100,153,133,150,249,122,177,
+134,115,215,154, 53,183,252,135, 14,173,190,114,229,138, 71,255,254,253, 9,185, 92, 14,185, 92,254,140,216,242,246,246, 38, 58,
+ 70, 68,112,127, 75, 74, 10,176,246,124, 90, 83,119, 10,133,242,210,133,214, 63, 28,205, 38,146,110, 49, 5,143,217,162,101,141,
+208,178,210,162,165,215,235,245,112,119,119, 71,101,101,101,179, 3, 63,133, 66, 1,135,195, 49,207, 17,183,184,242, 78,163,209,
+108, 89,186,116,233,252,225,195,135,187,133,132,132, 64, 44, 22,195,195,195, 3,108, 54,187,222,119,204,204,151,154,154,138, 95,
+126,249, 69,166,209,104,182, 88,224,252,118,211,166, 77,239,141, 27, 55,206,197,211,211, 19,206,206,206,120,240,224, 1,156,157,
+157, 33,147,201,144,147,147, 3,123,123,251,122,191,157, 83,167, 78,201, 53, 26,205,183, 22,196, 27,153,146,146,162,179,183,183,
+127, 32, 22,139,169,213,213,213,180,154,154, 26,154, 76, 38,163, 75,165, 82,250,185,115,231,220, 28, 29, 29,149,151, 47, 95, 22,
+251,251,251, 83, 31, 63,126, 76,213,235,245, 22,213, 43, 65, 16, 88,176, 96, 1, 24, 12, 6, 52, 26, 13,182,108,217,130,165, 75,
+151,214,251,100,109,218,180, 9, 43, 87,174,172, 23,206,187,119,239,110, 85,207, 33, 73, 18, 58,157, 14,122,189, 30,122,189,222,
+ 42,241,251, 87, 96,165, 96, 47,207,203,203,139,125,229,149, 87, 46, 28, 57,114,196,181, 46, 38, 25, 42, 42, 42, 80, 81, 81, 1,
+177, 88,140,218,218, 90, 24, 12, 6,248,248,248,160,162,162, 2, 39, 78,156,144,202,229,242,161,104, 97,197, 33,149, 74,157,214,
+183,111, 95, 90,227, 50,152,159,242,204,226,157,197, 98, 65, 32, 16, 96,192,128, 1,204, 43, 87,174, 76, 3,240,143, 22, 90, 13,
+195, 59, 12, 25, 58,131, 17, 22,222, 75,123, 63, 35,161, 52,180, 93, 69,233,148,209, 14,167, 1,224, 94,122,133,227,253, 28, 39,
+132,133,199,146, 67,134, 58, 71, 85,148,239,138, 4,160,107, 41, 93, 15, 0, 56,114, 89, 19, 7, 71,247, 16,216,243,120,148,205,
+ 95,239, 62,251,227,143,223,118, 59,122,250, 63,225, 29, 54,127,253, 52,188,195,224,232, 30,166,236,172,236,137, 0,126,178, 86,
+188,196,198,142, 76,251,101,239, 47,200,206,184,236,253,209,130, 78,204,234, 10, 61, 56,118,126,136,234,226,129, 93,123, 31,226,
+254,253,251,229, 90,173,118, 64,139,253,155, 32,253, 51, 50,211,131, 35,195, 59,122, 78,157,246,174, 67,108,236,104, 36, 36,156,
+196,129,125, 63,165,140,159, 60,238,231,178, 26, 25,213,157,206,101,112, 73, 19,147,202,112,164, 49, 88, 28,145, 86,251,116, 13,
+ 4,157,206,118, 0, 38,182, 56,240,204,121,119,138,227,192,232,209, 56,125,230, 36, 14,236,219,149,252, 73,248,132,159,218,117,
+ 13, 35,122,116,251,106,110,187,246,237,218, 40,106, 43,100, 20,130,169, 83,171, 77,246, 95,237, 43,250,166, 96,229,180, 2, 0,
+ 95,195,182,234,176, 33, 30, 28, 24, 49,226,149, 15, 30, 61, 98,240,251,244,225, 8,146,146,184,117,153, 72, 90, 20, 90, 52, 26,
+ 13,100,243, 83, 93,207,112, 18,251,247, 83, 0,180,184, 8,139,193, 96, 64,169, 84, 66,223,188, 5,251, 25, 78,175,243,231, 75,
+ 31, 61,122, 20,228,226,226,242,140,200,170,174,174,174,255,172, 86,171,161, 84, 42,193,225,112, 50, 84, 77,207,136, 60,195, 89,
+145,146,162,222,184, 96,193,234, 55, 38, 79,222,118,241,210, 37,182,171,171, 43,164, 82,233, 51, 66, 75,171,213, 98,224,160, 65,
+140, 77,105,105, 83, 33,147,173,177,230,124,122, 12, 24, 96,209, 31,152, 74,165,194,244,146,167, 14,255, 5,120,183, 41,225, 69,
+177, 52,133, 99,237,170,195,102, 6,200,198,217,189, 87, 70, 69, 69,169,115,115,115,225,239,239, 95, 47, 86, 26,254,167,131,131,
+ 3,156,156,156,144,154,154,138,207, 63,255, 92, 5, 96,165, 5, 78,185, 82,169,124,125,240,224,193, 42, 26,141,134,208,208,208,
+250,248, 89, 38,147, 9, 76, 38, 19, 60, 30, 15,105,105,105, 24, 57,114,164, 82,169, 84,190,142, 63,199,208,106,204, 41, 85, 42,
+149,111, 14, 25, 50, 68,153,153,153,137,190,125,251,226,254,253,251,168,173,173, 69,109,109, 45, 10, 11, 11,209,177, 99, 71, 40,
+149, 74,252,240,195, 15, 42,165, 82,249, 38, 0,105, 75,156,114,185,124,228,210,165, 75,169,191,254,250,107, 59, 31, 31,159,240,
+238,221,187,135, 12, 26, 52,168,195,216,177, 99,219,140, 24, 49,194, 43, 40, 40, 72, 61,116,232, 80,254,240,225,195,249, 74,165,
+146,126,253,250,117,161, 94,175, 31,110,161,156,245,226, 36, 55, 55,183,126,170,144, 70,163,161,178,178,178, 62,114,191,249,166,
+212,140, 16,142,182, 36,182,205, 2,203, 44,184,172,240,115,107,138,211,226, 65, 76, 38,211,108,241, 36,173,224,188,151,149,149,
+ 53,184, 95,191,126,247,102,204,152, 33, 47, 47, 47,135,189,189, 61, 2, 2, 2, 16, 28, 28, 12, 55, 55, 55,232,116, 58, 28, 63,
+126, 92,113,226,196,137,135, 82,169,116, 0,254, 28, 67, 43,186,209,121, 44,108,234, 38,107,182,102,153,133, 22,155,205,134,143,
+143,143,249,220, 22,182,230,124, 62, 39, 94, 46,103,157,128, 25, 52,112,104,251, 17, 49, 99, 28,143,159,188,193,220,182,253,196,
+195,168,104,236,118,109, 43, 59,229,218, 86,118, 42, 42, 26,187,183,109, 63,241,240,248,201, 27,204, 17, 49, 99, 28, 7, 13, 28,
+218, 62, 51, 35, 59,164, 97,222,195,166,202,201,102,179,123,245,237, 19, 85,115,229, 90,178,105,195,166,239, 41, 3, 7,140, 79,
+251,233,231,227,199,127,250,249,248,241,129, 3,198,167,109,216,244, 61,229,202,181,100, 83,223, 62, 81, 53,108, 54,187,151, 53,
+117,159,243,238, 20,199,152, 17,163,145,144,112,220,112,244,183, 31, 54, 29, 58,150,215,111,230,252,148,138,220,220,251,164,232,
+201,121,208, 41,197,200,202,202,146,214,137,172, 92,107, 56,103,207,154,210, 80,100, 93,117,245,236,187, 59, 43, 11,198,196,196,
+223,245,151, 46,165,169,174,222, 19, 73,239,102, 86, 86, 11,196,213,143,101,178, 42,173,201,100,132,209,104,164,174, 91, 87,239,
+176,219,100, 27,245,238,221, 31,151, 47, 30,196,190,189, 59,165, 38, 19,212, 19,143, 30, 53, 78,156,184,150,108,211,182,109,155,
+184,223, 14, 18,177,163,198, 56,146,128,105,228,184,209, 78,191, 30,250,149,104, 31,216,190,109, 64, 64,125, 72,155,127, 94, 95,
+122, 9,156,107,129, 26, 89,113,113,114,234,247,223,107, 60, 94,127,221,133,233,225,225, 0,163,145, 48,223,223,155,123,209,104,
+180,198, 22,152,102, 57,125,220,220,202, 78,157, 58,133,224,224, 96,248,248,248,160,161,143,172, 57, 32,183,171,171, 43,142, 29,
+ 59, 6,242,217,224,212,205,114,118,109,215, 46,245,203,141, 27,181, 38,147, 9, 53, 53, 53,127,178,102,213,212,212,192,100, 50,
+225,204,233,211, 90,217,211, 76, 32, 86,213,125, 0,149, 90,251,198,107,175,109,136,137,137,209, 61,122,244, 8, 38,147, 9, 13,
+ 45, 91, 34,145, 8,118,118,118, 80,107, 52,126, 0,184,214,112,138,206,157,227,193,194,125,189, 9,139,214,203,104,247,127,186,
+200,106,152, 80,250, 93,171, 44, 90, 6,131, 1,126,126,126,207,164,116,161, 80, 40,207,188, 90,185,226,112,127,102,102,230,249,
+161, 67,135,174,126,245,213, 87,231,172, 94,189,154, 26, 18, 18, 2,169, 84, 10,103,103,103,184,187,187, 35, 39, 39, 7,167, 78,
+157, 50, 86, 86, 86,238,116,181, 93, 44, 0, 0, 32, 0, 73, 68, 65, 84, 0,176, 30,214, 45,161, 79,202,203,203,139,237,212,169,
+211,161,229,203,151, 59, 14, 25, 50,132,238,231,231, 7,146, 36,145,150,150,134,248,248,120,221, 79, 63,253, 36,171, 19, 89,214,
+ 58, 47, 95, 16, 8, 4,227,135, 15, 31, 30, 55,109,218, 52,123,163,209, 72, 47, 44, 44,132, 70,163,129, 94,175, 71, 73, 73,137,
+ 46, 33, 33,161, 86,169, 84, 78, 1,112,193, 10,190, 84,137, 68,210, 49, 49, 49,113,218,245,235,215, 63,159, 49, 99,134,235,160,
+ 65,131, 24, 6,131, 1,215,174, 93, 19,119,237,218,213, 93, 36, 18,233,142, 29, 59, 86,165, 86,171, 87, 26,141, 70,171, 82,240,
+ 16, 4, 1,153, 76, 6, 55, 55, 55,104, 52, 26,152, 76, 38,104,181, 90,216,217,217,213,167, 77, 34, 73, 18,173,113,174,111,212,
+ 7,168, 58,157, 14,147, 39, 79,134,201,100,194,150, 45, 91, 96, 48, 24, 90, 77,230,232,232,120,247,222,189,123,177, 93,186,116,
+169, 23, 47,230, 62,196, 98,177,224,230,230, 6, 87, 87, 87, 36, 36, 36,128, 78,167,223,181,228,239, 86,135,251,149,149,149, 93,
+ 19, 19, 19,123, 61,124,248,240, 45, 0, 93,116, 58,157,143,209,104, 36, 40, 20,138,144, 36,201, 7, 50,153,236,103, 88,153,130,
+ 71, 36, 18,125, 62,125,250,244,174, 7, 15, 30,180,163,209,254,115,105,208,104, 52,176, 88, 44,152,131, 99,146, 36, 9,173, 86,
+139, 85,171, 86,201, 20, 10,197,231,255,150,187, 68, 84,247, 30,216,245,195, 86,187, 75,151,207,139,179,242, 16,223, 68, 8,135,
+ 39, 21,229,187, 34, 5,165,165,118, 81,221,123, 88,197,169,215,234,170,222,156,178,216,191, 46, 5,207,170,194,194,162,157,113,
+251,191, 41, 0,128,175,190,221, 18, 84, 81, 37,153,157,157,149, 61,113,231,206,223,122,233,181,186, 42,107, 56,255, 35, 94,226,
+164, 32,161, 6,112, 59,237, 97, 69,187,145,175,159, 91, 25,216,222, 97,148,168, 74, 85, 86, 91,171,124, 31, 64,129,181,117,239,
+211,187, 31, 46, 95,248, 21, 7,246,197,201, 72, 19, 85,237,230,230, 70, 2, 64, 86,150, 27,153,149, 37, 33,255,227, 87,236,164,
+160,147,247,215, 47,126,127,208, 98,169,172,250,219, 45, 63,180, 60,149,210,169,243,171,232,212,249, 85,204,127,255, 99,199,142,
+225,161,254, 0,112,244, 40,140,225,129,153,191,175,254,100,237,168,245,235,215, 66, 38,215,192,156,174, 39, 39, 61,243,116, 65,
+ 1,180,182, 49,235, 89,172, 54, 24,110, 99,241,226, 32,101,117, 53,191,207, 71, 31,185,209, 62,252,144,210,146, 51,124,195,235,
+215, 26,206, 59, 15, 30,156,158, 61,115,102,217,154,213,171,135,238,216,185,147, 19, 25, 25,137,242,242,114,132,134,134,194,199,
+199, 7,137,137,137, 56,118,248,176, 66, 34,151,175, 4,240,163, 53,156,251,207,156,201, 9, 9, 15,175,220,185,115,167,119, 76,
+ 76, 12,161, 80, 40, 32,149, 74, 33,149, 74,161,209,104, 80, 23, 16,154,204,205,203,203,210,235,245, 59,172,173,187, 81, 44,102,
+175,239,209,227, 9,195,100,250,114,252,184,113, 75,215,127,250, 41,171,125,251,246,132, 70,163,169,183,106,233,116, 58,216,217,
+217,233,180, 90,173, 43, 0,165, 53,156,172,159,126, 50,136,197, 98,240,249,252,250,112, 77, 13,227, 18,202,229,114,144, 36,105,
+ 11,166,251, 28,104, 86, 33, 57, 59, 59,223,165,209,104,190, 13,173, 91, 77,229,206,107,184, 77,175,215, 63,169,172,172,140,106,
+164,120,155,243,135, 10, 0,240,197,192,129, 3,199, 47, 89,178,132,184,114,229, 10, 78,156, 56, 65, 22, 20, 20, 28,173,179, 98,
+ 21,180,240,164,211, 28,167, 61,139,197, 90,200,227,241,162,205, 33, 28,184, 92,238, 67,133, 66,113,177,110,186, 80,254, 28,156,
+ 14, 44, 22,107, 1,143,199, 27, 92,151,126, 5,246,246,246,247, 20, 10, 69,162, 70,163,217,138,230, 19, 85,183,196,201,113,116,
+116,252,220,205,205,237,205, 15, 63,252,208, 53, 37, 37, 69,120,249,242,101,134, 68, 34, 57,168,213,106, 91, 74, 42,253, 39, 78,
+ 23, 23,151,187, 84, 42,213,247, 37,181, 17, 58,117,234,148, 48,114,228,200,152, 41, 83,166, 64,175,215,227,199, 31,127, 68, 98,
+ 98,226,233,252,252,252, 88, 11, 79,163,141, 57,221,124,125,125,175,204,153, 51,167,205,228,201,147,185,206,206,206,160,209,104,
+ 80, 40, 20,200,207,207, 71, 90, 90, 26,121,242,228,201,218,212,212,212, 39, 74,165,178, 63,128,202, 86,156,207,191,242,212,252,
+ 12, 39,141, 70,235,231,231,231,247,219,154, 53,107,236, 7, 15, 30,204,113,117,117, 5,149, 74,133, 94,175,135, 80, 40, 68,122,
+122, 58,206,159, 63,175, 56,122,244,168,162,170,170,106, 50,128,228,255,143,114,190, 72,206,176, 32,124,210, 40, 81,116,179,209,
+222, 45,236,107,177,156, 3,251,121,141,158, 56,126,248, 48, 0, 56,114,236,236, 57, 43,146, 74, 55, 91, 78, 75,101,181,134, 51,
+ 52,144,178, 38, 35, 51,253,153,128,150,225, 29, 35,114,195, 34,199,125,102, 13, 81,131,200,240,207,212,189,193,116,108, 67,155,
+238, 51,211,172, 97, 1,136, 29, 61,113,108,204,199, 43, 87,224,139,207, 55,224,228,145,227,167,179, 10,158, 73, 19,244,143,235,
+ 75, 47,153,147,248,140, 70,123,149,235,229,245,218, 22,147,105,197,253,244,116,187,134, 15,108,102,203,115,195,135, 74,111,111,
+111,145, 80, 40,244,176,134, 51,246,187,239,116, 74, 30,143,181,226,203, 47,251,213,170,213,253,214,175, 95, 79,187,115,231, 14,
+126,248,254,123,131,250,201,147, 56, 49,176,160,153,217,144,102, 57,219, 44, 88,192, 94,246,195, 15,111, 7, 4, 6,186,191,245,
+214, 91,116, 58,157, 14,133, 66,129,210,210, 82, 92, 56,127, 94,155,153,149,149, 41,147,201, 70, 1, 16, 88,203, 25,251,221,119,
+ 58,167,128, 0,112,249,124,242, 82, 82,146,227,236,133, 11,231,180,109,215,206,113,232,176, 97,116, 7, 7, 7,212,212,212,160,
+176,176, 16,199,143, 31, 23,213,214,214,122, 3, 48, 90,195, 25,119,253,122,167, 51,201,201, 19, 62,251,236, 51,102, 68, 68, 4,
+ 28, 29, 29, 33,151,203,145,158,158,142,228,228,100,205,142, 29, 59,164, 82,169,116,142,209,104, 60,245, 18,219,253,223, 96,213,
+ 50, 99,151, 69,161,245, 95,188, 0,163, 0,124, 82,247,249, 83, 88,206, 25,248,111,186,249,248,187,184,184,236, 82,171,213,164,
+ 74,165,154, 13,160,228,111, 88, 78, 90, 84, 84,212, 15, 34,145,168, 23, 73,146,112,116,116,188,145,145,145, 49, 15,205,172,188,
+177,192, 73, 5,208,203,206,206,174,135,189,189,125, 63,141, 70, 19, 86, 55,253,150,165, 80, 40,146,117, 58,221,237, 58,235,147,
+241,255,185,238, 84, 0,131,189,189,189,103,154, 76,166, 64,130, 32,156,140, 70, 35,244,122,189,196,100, 50,229, 75,165,210,159,
+ 0, 36,254, 13,202,249, 66, 56, 59,118,192, 88,146,130,176,230, 4,193, 51, 66,171,145,128, 32, 76,200,202,124,132,227,173, 40,
+ 39,101,120,180,223,118,224,233,202, 68, 88,118,174,253,143,208,178, 66,188,180, 90,100,118,160, 78, 39, 9,242, 25, 78,130, 36,
+ 74, 66, 59,141, 61,240, 87,132,150,181,232, 24,140,126, 32,209,203, 68,226,118,118, 62, 46,255,139,239,117, 47,140,243, 11,192,
+229,123,103,231, 27, 20, 26,205, 19, 0,165,206,250, 98, 50, 17,132,145, 36, 8, 67,195,233,173, 70, 15,150, 45,114,234,128, 72,
+ 58,139,229,103, 52, 24, 60,202, 1,187, 51, 70, 99, 55, 53, 73,214,250, 2,159,220, 3,114,158,167,156, 58, 32,146,202, 98,249,
+159, 33,201,209, 98, 30,175,147, 72,165,226, 3, 32,237,120,188, 44,153, 66,177, 79,173, 86,111,199,159,103, 46, 44,114, 50, 88,
+ 44, 95,163,193,224, 1, 0, 20, 26, 77,116, 72,163,241,123,226,224,240,150, 90,163,105, 99,103,103,167,215,106,181, 50,181, 90,
+ 61,197, 96, 48, 92,106, 77,221,243, 13,134,142,215, 41,148,190, 58, 30,207, 85, 71, 16, 60,173,193,160,211,234,116,165,106,181,
+250, 33,128,111, 0, 60,122,201,237,110,195,115, 94, 44, 54, 78, 27,167,141,211,198,105,227,180,113,218, 56, 95, 62, 39, 23,128,
+127,221,195,226, 63,177,238,255, 38, 88,231,163,101,131, 13, 54,216, 96,131, 13, 54,252, 99,160, 68, 19, 62, 89, 54,252,255,130,
+104, 65,149,182,198, 36,248, 60,202,246,162,141,211,198,105,227,180,113,218, 56,109,156, 54,206,255, 57, 78, 75,220,255,196, 41,
+201,102,115, 29,190,108,216,204,191, 54, 78, 27,167,141,211,198,105,227,180,113,218, 56,255,103, 65,177,157,130,102,225, 81,247,
+122,209,251,218,240,239,238, 11,255, 13,248,212,189, 90,179,191,151,173, 25,109,176,193, 6, 27,254, 55,132,150,181,131,214, 95,
+ 25,220,254,234,192,184,129, 32, 32, 32, 8, 8, 0,108,120,129,251, 90,130,183,155,155,219, 7, 29, 59,118,140,243,240,240,152,
+ 15,192,189,149,199, 7,113,185,220,173, 60, 30,239, 10,143,199,187,194,229,114,183, 2, 8,122, 65,237, 70, 0,152,205, 98,177,
+146,188,188,188,202,152, 76,102, 18,128, 57,120,254,149,171, 33,120, 26, 39,237, 83, 0,157, 90,115,160,123,248,232,195,252,240,
+209, 15,248,225,163,211, 93, 35, 70, 6,241,195, 71,167,243,195, 71, 63,112, 15, 31,125,248, 37,244,215, 23,217,190, 47,170, 60,
+ 37, 4,129, 18, 43,203,243, 13, 1,148, 18, 4,158,252, 77,202,111,131, 13, 54,216, 96, 67,179, 42,192,219,123,188,151,151,215,
+ 69, 47, 47,175, 68,111,111,239,241, 86, 28, 18,221,196, 32, 97, 36, 8, 24, 45,220,244, 91,218,207,146,185,178,225,177,155,173,
+172, 90, 67, 78, 15,130,128,145,172, 3, 65,192,228,238,238,190,205,203,203,107, 67,227,151,187,187,251, 54,130,128,169,193,190,
+198, 6, 2,175,181,102, 85,143,169, 83,167, 30,169,169,169, 73,208,106,181, 9,121,121,121, 9,253,251,247, 63,212,200, 18,209,
+ 44, 39,155,205,126,227,149, 30,189, 82,147,175,221,206,203,205, 47, 18,100,230, 60, 46,250,253,220,165, 59, 17,145,157,254, 96,
+179,217,111,180,162,141, 8, 0,179,105, 52, 90,146,157,157,221, 19, 26,141,150, 4, 96, 46,149, 74, 61,181,113,227,198,162,140,
+140,140,138,235,215,175, 75,146,147,147,203,102,204,152,145, 79, 16,196,239, 77, 8,246,104, 43, 44, 48,171,139,139,139,207, 9,
+133,194,243, 28, 14,231,115, 43,246,175,231,228,135,143,126, 32,146,234, 72,145, 84, 71,242,195, 71,147, 13, 62, 63,104,229, 57,
+183,212, 70,127,234, 11, 44, 22,203,223,130,160,127,153, 38,250, 63,149, 7,128,103,221,111, 81, 0,190,171,123,153,151,179,123,
+178, 89,172, 23,213, 63, 95,196,249,180,113,218, 56,109,156, 54,206,127, 43,186,214,189,123,225,169,191, 86,253,216,221,218, 85,
+135,239,229,229,229,217, 1, 64,112,112,240, 60, 0,199, 90, 35, 36, 8, 2,203, 76, 38,146, 2, 0, 20, 10,241,209,128, 1, 3,
+187,114, 56,156,103,162, 32,171, 84, 42,102, 82,210,229, 65, 38, 19, 73,212,237,183,140, 36,177, 21, 64,133,181,255,161,213,106,
+ 40,116, 58, 19, 20, 10,177, 56, 34, 34,178,109,101,101,101, 10,133, 66,137, 43, 43, 43,171,105,181, 25,135, 32,176,123,247,238,
+ 96, 47, 47,175, 63, 69,107, 22, 10,133,204,209,163, 71,181,138,111, 58,192,210,176, 88, 61, 24, 4,225,101, 52, 24,156, 0,128,
+ 70,163,213,220, 97, 50,163,190,248,236, 51, 46, 65, 16,166,170,170, 42,168, 84, 42, 44, 90,180,136,147,153,153, 57,166,178,178,
+114,187, 5,218,224, 78,157,187, 46, 58,127,254, 92,152,172,186, 70,189,251,219,157,169, 42, 26, 67,217,174, 99, 40,227,135, 93,
+251,156,223,125,123,202,251,217,217, 25,247,208,116, 58,146,134,160, 0, 56,190,112,225,194,240,216,216, 88,166, 92, 46,103,171,
+ 84,170,182,113,113,113,171,162,162,162,236,186,116,233,194,252,237,183,223, 8,169, 84, 10,146, 36,185,161,161,161,228,164, 73,
+147,212,135, 14, 29,154, 15, 96, 91, 11,194,119,217,211,115, 73,217, 18, 18, 18,178, 6, 0,242,242,242, 24, 13,206, 49, 61, 44,
+ 44,140, 7, 0, 57, 57, 57,235, 72,210,180, 16, 0, 72, 18,155, 0,172,104,194,180,150, 23,222,103, 34, 64, 32, 48,227,218, 17,
+118,120,223,137,106,144,200, 39,128,188,186, 7,130,245, 64,131,184, 80,207, 34, 75, 32, 16, 60, 87,110,194,152,152, 88,130, 32,
+136,163,169,169,169,199, 68, 34, 81, 59,147,201, 56,171,165,114, 54,215, 86,124, 62,255,188,209,104,212, 84, 87, 87,215, 7,202,
+228,119, 26,219,203,213,158, 55, 72, 92, 35, 79,169,202, 60,153,108,101,223, 36, 92, 93, 93,167, 87, 86, 86,110, 0, 48, 51, 43,
+ 43,171, 43, 0,132,133,133, 49, 0,220,117,112,112,232,173,211,106, 9,219,253,207, 6, 27,108,176,225,191, 34,180,210, 0,196,
+224, 63, 41,120,118, 61,143,208, 98, 2, 64, 74, 74, 10, 0,176,158,163, 32, 68, 67, 1,179, 96,193, 2,120,121,121, 53, 22, 47,
+184,114, 37,233,175, 84,246,153,255,248,244,211, 79,237, 36, 18, 73,244,207, 63,255,252, 26, 73,146,155, 5, 2,193, 45, 11,199,
+ 87,144, 36, 54, 81, 40,196, 71, 4, 65,128,197, 98,231,206,153, 51, 39,173,238,183,182,191,255,254, 59,119,228,200,145, 74, 0,
+ 69, 0,192, 98,177,125,168, 84, 74, 48, 73,146,230, 1,183, 89, 65, 56, 1, 8, 48, 48,153, 3,103,127,247,157,161,219,200,145,
+ 52, 30,159, 79, 0, 64, 81,118,182,235,166,175,190,234, 93, 83, 80,192, 84,185,186, 86, 85, 41, 20,170,220,220, 92,176, 88, 44,
+130, 74,165,118,179, 84, 97, 30,143,247,193,103, 95,124,201,147, 85, 75, 84,106,153, 92, 75, 53,232, 53,246, 28,174,177,162, 92,
+ 84,101,199,225, 41, 63,250,100, 45,243,189, 89,211, 62, 80, 40, 20,243, 44, 80,205, 95,188,120,113,216, 43,175,188,226,115,248,
+240, 97, 66, 42,149,130, 70,163,217,117,233,210, 5, 81, 81, 81,198,203,151, 47, 19,237,218,181, 67, 68, 68, 4,174, 93,187,134,
+ 27, 55,110, 16, 93,187,118,229,198,199,199, 79,213,235,245,219, 44,137,107, 42,149,178, 40, 52, 52,180, 11,143,199,211, 6, 7,
+ 7, 99,214,172, 89, 32, 73, 18,209,209,209, 17,118,118,118,199, 20, 10, 5, 51, 39, 39,251, 53, 75, 34, 91,148,113,114,146,217,
+178, 5, 32, 18, 36,242,197, 25, 39, 27, 78, 63,134,229,228,228,188, 90, 83, 83,131,167,237, 66,214, 39, 48,127,237,181,215, 90,
+211,151, 42, 72, 18,155, 70,142,140,253, 8, 32,136,232,232,104,201,252,249,243, 41,217,217,217,111,142, 29, 59, 38, 34, 47, 47,
+ 31,173,124, 24, 8, 30, 50,100,200,181, 51,103,206,184, 6, 7, 7,139,171,171,171,235,127,240,116,117, 26,154, 28,191,229,131,
+207,183,198,133,238, 39, 9,137, 56,235,196, 67, 11,125,147,152, 62,253,237, 10, 59, 59,187,113, 71,143, 30,205, 17, 10,133, 52,
+ 6,163, 94,187, 82,221,221,221,249,193,193,193,115, 93, 92, 92, 68, 84, 10,197,157, 4, 73, 90,234,159, 54,216, 96,131, 13, 54,
+ 60, 55, 78,215,137,171,211,141,127,160, 1, 64, 66, 66, 66,125,100,218,216,216,216,102,159,128, 73,146,172,184,127,255,190,159,
+ 82,169, 4, 73,146,214,220,176, 27, 46,209,172, 32, 8,202, 15, 20, 10, 49,143, 32, 8, 68, 68, 68, 62,222,178,101, 75, 83, 57,
+189,180, 17, 17,145,143,169, 84, 74,123,146, 36, 65, 16,148, 31, 73,210, 84,209, 12,103,147, 3, 17,147,201, 90, 6, 0,158,158,
+ 94, 5,103,207,158,213, 78,152, 48, 1, 95,125,245, 21, 99,249,242,229, 75,105, 52,218,252,146,146,146,242, 22,202, 9, 0, 43,
+248,124,119,238,238,221,187,131,231,204,153,147, 38, 20, 10, 87, 0,128,151,151,215, 6, 0, 29, 1, 20, 53,216,134, 29, 59, 14,
+149,205,154, 53, 43, 87, 36, 18,173,104,142,115, 28,208,193, 47, 52,116,224,250,148, 20,146,162,209, 16,149, 87,175,202,196, 21,
+ 21,250, 71, 98, 49,119,239,221,187,177,171, 54,108,160,251,249,251,227,202,169, 83,110,149, 74,165, 88,170,209,168, 43, 42, 42,
+ 72,131,193,112,195,138,186,135,187,243,221,185, 59,191,249,241,142, 61,157,106,114,247,245, 33,232, 46, 46, 52, 10,215,129, 73,
+165, 81, 52,237,219, 6, 49, 1,132, 91,106, 35, 6,131, 49,117,200,144, 33,220, 67,135, 14, 17, 17, 17, 17,112,114,114,194,213,
+171, 87,113,239,222, 61,212,212,212, 80,244,122, 61,186,119,239,142, 47,191,252, 18,254,254,254,144, 72, 36, 40, 41, 41,113, 99,
+ 50,153,124,189, 94,223,220,249,124,166, 63, 45, 91,182, 12, 94, 94, 94, 48, 24, 12,168,174,174,134,193, 96,128,157,157, 29, 0,
+224,201,147, 39, 56,117,234,164, 53,125,201, 34, 72,146, 68,207,158, 61,229, 4, 65,100, 53,182,104,181,134,211,199,199,231, 55,
+177,184,114,248,192,129, 3, 81, 83, 83,163, 95,187,118, 45, 58,117,234,132,224,224, 96,139,229,244,246,246,158,109, 48, 24, 86,
+ 3,128, 78,167,219,203,102,179,223, 57,112,224,128,107,195, 20, 33,102, 75, 86,133,168,170,230,198,157,140,156,197,179, 39,244,
+ 79,185,149, 94,170,163,143, 46,145, 62, 56, 41,109,162,156, 43, 24, 12,230,207,109,218,180,249,102,193,130, 5, 94, 46, 46, 46,
+208,104, 52,171,202,203,203, 49,119,238, 92, 0,192,136, 17, 35, 58,209,233,244,179, 51,102,204, 64,187,118,237,202,170,171,171,
+ 75, 82, 83, 83,103, 41,149,202,244,231, 61,159, 86,194,198,105,227,180,113,218, 56,159, 27,214,106,145,191, 41,132,120, 54,156,
+195,174,103,132, 86,108,108, 44,145,144,144, 64, 90, 81,177, 42, 95, 95, 95, 63, 14,135, 3, 0, 85,173, 45,133,201,100,154,239,
+234,234, 42, 90,177, 98, 69,159,224,224, 96,237,252,249,243,211,139,138,138, 86, 54,220,167,109,219,182,159,127,255,253,247,200,
+205,205, 45,218,176, 97,195,181,170,170,170,214,230, 49, 91, 78,146,216, 82,103, 29,171, 60,117,234, 84,167,148,148,148,121,223,
+126,251, 45,255,189,247,222, 99,124,240,193, 7, 83, 0,124,101,137,132, 74,165, 42,155,154, 46,108, 10, 94, 94, 94, 90, 42,149,
+218,108,144,184, 88,128,195,102, 50, 7,172, 79, 73, 33,181, 69, 69,202, 95,190,254,218,126,231, 31,127,172,209,147,164,135,187,
+187, 59,250,246,238, 93,203,166, 82, 43, 69,229,229, 38,247, 14, 29,168,133,103,207,186,169,152, 76,193,161, 67,135,164, 85, 85,
+ 85, 39, 44,154,240, 8, 66,102, 34, 73,173,157,175,191,126,194,152,193, 17,119,110,223,203,182,119,119,163,116,237, 18,209, 41,
+ 59,183, 40, 21, 38,147,142, 32, 8,153, 37, 30, 71, 71,199,224,170,170, 42,200,100, 50,240,249,124,108,217,178, 5,158,158,158,
+ 80, 42,149,200,200,200, 32,125,125,125,137,148,148, 20,248,250,250, 66, 44, 22, 67,171,213, 66, 46,151,139, 52, 26, 77,115,185,
+ 25, 43, 40, 20,234, 30, 10,133,120,155, 32, 8,180,111, 31, 80,188,125,251,118,173,201,100, 66, 88, 88, 24,198,142, 29,139,248,
+248,120,100,100,100,152, 45, 79,218, 54,109,218, 22, 83, 40, 68,155, 58,173,244,220, 22, 24,115,106, 31,129, 64, 48,238, 57, 47,
+ 26,138,183,183,247,148,192,192,192,121,111,188,241,134,158,201,100, 66,161, 80,152,207,133,126,248,240, 17,146,145, 35, 99, 29,
+ 79,159, 62,221,108, 57,117, 58,221,234,178,178, 50, 47,149, 74,133, 97,195,134,125,176,121,243,102, 30,147,201, 4, 0, 24,141,
+198,103, 44, 89,159,125,187,255,252,194,213,219,147,206,255,246,165,247,103,203,223,233, 63,101,254,231, 73, 0,206, 53, 85, 48,
+173, 86, 91, 32,149, 74,103, 46, 94,188, 56,110,199,142, 29,206, 43, 87,174,132,201,100, 2, 73,146, 48, 24, 12,245,137,196, 77,
+ 38, 19,142, 31, 63,142, 71,143, 30,125,222, 72,100,217, 96,131, 13, 54,252,237,208, 10, 45,242,119,132, 23,158, 78, 27,162,177,
+216,250,175, 71,134,167, 82,169, 59, 47, 92,184,208,229,181,215, 94,163, 13, 26, 52, 40,226,220,185,115, 17,101,101,101,233,117,
+214,131,136, 65,131, 6, 69,184,187,187, 99,235,214,173, 74, 42,149,186,243, 57,255,166,126,208, 43, 47, 47, 79, 3,176, 57, 62,
+ 62,126,211,236,217,179,225,233,233,217, 81, 40, 20,254, 87,235,236,192, 98,117,157,177,101,139,129,174,215, 83,190,219,188,217,
+225,235,164,164, 77,135,143, 28,161,245,236,217,147, 32, 73, 18, 15, 31, 60,224,124,185,109, 27,119,242,152, 49, 69, 57, 5, 5,
+134,147,231,207,235, 43,202,202,170,203,196,226,213, 0,170, 45,241,235,245,250,155,121,121,121,222,125,251,245,244, 73,254, 35,
+253,222,132, 49, 35, 6,210,105, 20, 34,191,232,201, 93, 47, 79, 55,199, 43, 73, 23, 85,122,189,254,166, 37, 30,133, 66, 81,104,
+ 48, 24, 92, 72,146,228, 95,185,114, 5,124, 62, 31, 53, 53, 53,208,235,245,208,106,181, 90,165, 82,201,174,170,170,130, 90,173,
+134, 70,163,129,131,131, 3, 30, 62,124, 88, 97, 48, 24, 46, 55,199,105, 52, 26,103,176, 88,172, 79,233,116, 58,147,193, 96, 8,
+238,222,189, 11,153, 76,214,214,201,201,233, 43,131,193, 0,129, 64,128,148,148,148, 15, 29, 28, 28,138, 0,128,205,102,131,201,
+100,185,106, 52, 26, 3,128,178,231, 61,231, 36, 73, 62,119,123,121,122,122,250,115, 56,156,245, 31,125,180, 44,172,115,231, 46,
+ 16,139,197, 48,153, 76,224,241,120, 80, 42,149,112,112,112, 64,175, 94,189, 10,215,175, 95, 47, 36, 73,188,219,130, 24,164,214,
+181, 15,102,207,158,205,115,112,112, 64,105,105, 41, 66, 67, 67,235,133,150, 80, 92,245,240,250,157,244,236,197,115, 38,246, 59,
+120, 42, 41,235,252,149,187, 89, 99,134,245,238, 76, 16,100,219,150,202, 40, 18,137,196, 52, 26,109,254,236,217,179, 63, 13, 14,
+ 14,110, 79,146, 36,130,130,130, 48,100,200, 16,156, 61,123, 22,185,185,185, 80, 40, 20,198, 91,183,110,253, 42, 20, 10,127,183,
+221,194,109,176,193, 6, 27, 94, 42,254,228,155,245,140, 69,235,191, 9,145, 72, 36,206,206,206, 62,151,154,154, 26, 59,105,210,
+ 36, 92,185,114,101, 58,128,197, 0,192, 98,177,166, 79,154, 52, 9,169,169,169,200,206,206, 62, 39, 18,137,196, 47,226, 63,153,
+ 76,166, 90,171,125,106,156, 98,179,217,236, 86, 30,222,182,110,202, 16, 0,218,182,176,173,121,211, 8,141,230, 21, 57,108, 24,
+173,230,222, 61,217,238,219,183, 63,141,139,139,163,245,233,211,135,208,235,116, 48,154, 76, 8, 8, 8, 32, 6, 69, 71,243,246,
+196,197,185, 24, 21,138,148,207, 62,250,232,234,174, 25, 51,106,243,234,252,192, 44, 65,163,209,108,155, 55,119,102,116,210,149,
+171, 62, 29, 67, 59,184,156,187,144,148,230,234,234,200, 13, 14, 12,228, 85,213, 84, 27, 87, 46,255,144,166,209,104,190,179,196,
+163, 82,169,142, 95,188,120,113,140,159,159, 31, 63, 61, 61, 29, 90,173, 22, 70,163, 17,131, 6, 13, 2, 73,146, 44, 0, 38, 26,
+141,134,236,236,108,232,116, 58, 81, 94, 94,158, 32, 63, 63,159, 5, 96,163,133,242, 21,107, 52, 26,100,101, 61,157,181,243,245,
+245, 29, 28, 19, 19, 3,131,193,128, 97,195,134,225,228,201,147,131,179,178,178,190,110,168,249,254,106,155,215, 89,200,194,188,
+189,189,227,235, 54, 89,229, 4,239,227,227, 19, 17, 16, 16,176, 99,227,198,141, 12, 95, 95, 95,144, 36, 9,103,103, 39, 40,149,
+ 74, 84, 86, 86,161, 99,199,142,240,243,243,195,198,141, 27, 1,224,215,150, 44,110, 38,147, 9, 66,161, 16,133,133,133, 40, 40,
+ 40,128,159,159, 31, 8,130,128, 92, 46,135,193,240, 52, 39, 55, 87, 46, 59,253,253,158,223, 7, 28,217,177, 58,188, 71,100,144,
+255,237,180, 76,209,212,113,131,185, 65,237,252,131,197,233,107, 41,192,218,102,147, 46, 11, 4,130,124,129, 64, 48, 73, 36, 18,
+ 49, 36, 18, 73,212,224,193,131,183, 70, 71, 71, 35, 45, 45, 13, 87,175, 94,157,204, 98,177, 68, 58,157,206,224,233,233,249, 46,
+ 65, 16, 14, 58,157,238, 96, 85, 85,149,208,118, 63,180,193, 6, 27,108,120,225, 48,251,104,161,193,123,235, 44, 90, 97, 97, 97,
+188,162,162,162,183,218,182,109,203, 4, 0, 14,135,211, 49, 32, 32, 96,105, 65, 65,129,188,181,165, 81, 42,149,135,227,226,226,
+134,124,243,205, 55,140, 17, 35, 70,116,136,143,143,127, 5, 0, 70,140, 24,209,193,222,222, 30,113,113,113, 58,165, 82,249,194,
+ 98, 34,233,245,250,215,186,119,239,142,234,234,106, 20, 21, 21,181,106, 10,229,247,223,127,231,226,169, 95, 86,139,219, 90,130,
+ 65,171,117,118,242,241,161,148, 37, 37,233,170,101, 50,175,215,250,245, 35,244, 58, 29, 40, 20, 10,170,170,170, 80, 82, 82, 2,
+ 71, 39, 39, 34, 59, 47,207,238,167,101,203,126,111,219,185, 51,211,168,213,186,182,162,152,138, 74, 81,197,219,239,207,127,239,
+248,193,131,191,242, 37, 50,217, 35, 14,135,171, 97,177, 24,158, 11,222,127,223, 88, 93, 93, 61, 13, 64,173, 21, 60, 27, 15, 30,
+ 60, 56,108,216,176, 97, 15,252,253,253,221,197, 98,177,167, 68, 34, 49, 86, 87, 87, 83,241,212,215,138, 0,128,164,164, 36,200,
+100, 50,131,209,104, 76,193,211, 88, 88, 90,107, 11,218,166, 77, 27,199,168,168,168,254,124, 62, 31, 82,169, 20,174,174,174,232,
+210,165, 75,127, 42,149,250,115,113,113,177,244, 69,246,250,196,196, 68,123,146, 36, 95, 37, 73, 18,195,134, 13,179,234, 24,163,
+209,248, 78, 76, 76, 12,131, 32, 8,168, 84, 74,176,217, 28,240,120,118,176,183,119, 64,112,112, 8, 4, 2, 1,134, 14, 29,170,
+125,244,232,209, 15, 66,161,240,176, 5, 46, 8, 4, 2,136,197, 98,148,148,148,160,178,178, 18, 0, 80, 89, 89, 89,239,156,255,
+ 34, 32,149, 74, 71,247,234,213,107,201,220,185,115, 97, 48, 24, 48,122,244,104,148,150,150,126, 93, 88, 88,120,200,219,219,123,
+202, 59,239,188,195,119,117,117,197,146, 37, 75, 56, 0,214,217,238,135, 54,216, 96,131, 13, 47, 28,141,125,180,254,108,209,106,
+105, 78,212,211,211,179, 47, 65, 16,171, 84, 42, 21,211, 60, 37, 67, 16, 4,147,207,231,159, 84,169, 84, 27,132, 66, 97,171,156,
+226, 36, 18,137,236,241,227,199, 39,111,222,188, 57,113,220,184,113, 72, 76, 76,156, 6, 0,227,198,141,195,205,155, 55,241,248,
+241,227,147, 18,137, 68,246, 34,106,238,227,227, 51,188, 95,191,126,227,186,119,239,142,132,132, 4, 24,141,198, 27,173, 57,190,
+225, 10, 67, 52,177,234,208,188,205, 42, 50, 42, 21, 4, 65,212, 91, 51, 42,197, 98,228,230,228,160,186,166, 6, 26,181, 26, 10,
+165,210, 24,220,174,157, 74,170,213,210, 9,160,181,115, 95,197,169,119,110,149, 40, 21, 10,119, 87,103, 23, 21,151,203,130, 68,
+ 38,101,220,189,115,171, 22,192, 35, 43, 57,180, 36, 73,246, 59,123,246,236,106, 42,149, 58,201,206,206, 14,243,230,205,163,246,
+239,223, 31, 12, 6, 3, 26,141, 6, 18,137, 4,113,113,113, 98,163,209,216,190,238, 24, 59, 46,151,187,143, 74,165, 62,145,203,
+229,171, 44,254,129, 86, 59, 34, 54, 54,150,166,213,106,241,217,103,159, 97,205,154, 53, 24, 54,108, 24,237,206,157, 59, 35, 0,
+ 28,124, 81, 61,222,100, 50, 97,240,224,193, 13,157,225,179,172, 57,142, 78,167, 71, 4, 6, 6, 66, 44, 22, 67, 44, 22,131,207,
+231,195,219,219, 27,158,158,158,248,250,235,175,201,173, 91,183,158,211,233,116, 63, 84, 86, 86, 86, 88, 83,134,130,130,130,122,
+203,160, 90,173,134, 66,161, 64,105,105,105,253,212,161,138,231, 48,108,254,219, 35, 59, 43, 84, 42,229,237,135,121, 37,171, 62,
+152,210, 83,161, 82, 41,243, 10, 75,114,129,109, 38, 43,250,247,187,211,166, 77,123,119,226,196,137,168,173,173,197,205,155, 55,
+209,187,119,111,108,218,180,201, 43, 37, 37,101,113,247,238,221, 65,167,211,113,229,202, 21, 24, 12,134, 82,219,189,208, 6, 27,
+108,248, 59,227, 31,234,159,213, 34, 90,180,104,249,249,249, 57, 25,141,198, 15, 99, 98, 98, 6,143, 25, 51, 6, 67,135, 14,125,
+230,247,131, 7, 15,218, 31, 59,118,108,195,182,109,219,134,233,116,186,141,173,153,234, 51,153, 76,199, 15, 30, 60, 56,162,103,
+207,158,220, 1, 3, 6, 4, 0, 0,139,197,210, 30, 60,120, 80,105, 50,153,142, 63, 71, 93,204,129, 24, 43, 0,192,219,219,187,
+ 19,141, 70, 27, 55,124,248,240, 78,111,191,253, 54, 50, 50, 50, 16, 23, 23,151, 31, 28, 28,124,173,162,162, 85,254,213, 69, 22,
+ 86, 29,110,176,100,221,162, 50,153, 85,146,242,114, 39, 59,127,127,186,179,189,189, 48, 33, 33,193, 47, 58, 58,154, 40, 45, 45,
+ 69, 77, 77, 13,212,106, 53,238,220,185, 99,162, 1,197, 52,103,103,162,248,230, 77,130,202,100, 86,225,217,149,124, 22,225,231,
+229, 28,244,201,242, 57,109,213, 26,117,184, 84, 42, 53,208,232,116,186,175,167, 83,105,206,163, 86,205,196,105,184, 92,110, 20,
+ 0,154,201,100, 82,186,184,184,112, 47, 92,184, 0, 38,147, 9,130, 32, 16, 25, 25, 9, 54,155,205, 32, 73,178, 4, 0,236,237,
+237,153, 59,119,238,116,156, 50,101,202, 85, 75,196, 93,187,118,165,179, 88,172, 81,193,193,193,184,121,243, 38,210,211,211,139,
+111,222,188,217,166,107,215,174,240,247,247, 31,229,229,229,117, 36, 45, 45, 77,255, 34, 58,246,211, 21,171,173,119,134, 55, 26,
+141, 38,130, 32, 64,161, 80, 96, 50,153, 32, 22,139,209,190,125,123,108,223,190, 29, 91,182,108,249, 76, 40, 20,158,106, 5,151,
+ 81, 38,147,129,199,227, 33, 61, 61, 93, 19, 19, 19,195,162, 80, 40,200,207,207,175, 23, 90,238,110, 46, 29,123,119,143, 8,253,
+236,219,253,231,121, 44, 22,107,104,255,168,176,204,188,226, 39, 36, 73, 88,156, 54, 14, 11, 11, 99,180,111,223,126,218,196,137,
+ 19, 81, 80, 80,128, 13, 27, 54, 84, 10,133,194,164,243,231,207,143,159, 59,119, 46,181,119,239,222,168,170,170,194,158, 61,123,
+ 12,119,239,222,253,165,188,188,124,191,237, 54,110,131, 13, 54,216,240, 55, 17, 90,126,126,126, 19, 25, 12,198,146,215, 95,127,
+157, 26, 18, 18,130,138,138, 10, 56, 56, 56,232, 9,130,160, 3,128,147,147,147,158,195,225, 96,206,156, 57,232,220,185,115,223,
+101,203,150,245,166,209,104,219, 5, 2,193, 62,107,254, 88, 36, 18, 41, 41, 20,202,209,121,243,230,109,188,119, 47,173, 61, 0,
+252,241,199, 31,143, 5, 2,193,114,145, 72,164,108,101, 61,204, 65, 49, 9, 22,139,125, 59, 40, 40,168, 48, 42, 42,202, 97,204,
+152, 49,224,243,249, 72, 77, 77,197,151, 95,126,153,167,213,106, 87, 39, 39, 39, 27,254,219, 39,217,160,209,148,223, 61,113,194,
+190,255,155,111, 58, 44,136,137,217,252,222,188,121,223,124,242,201, 39,180,144,144, 16, 66,169, 84,226,246,237,219,228,177, 99,
+199,244,123, 62,253,116, 11,120, 60,250,205, 99,199,152, 90,173,182,184,149,150,187,126,125, 94,235, 27,178,249,155,109, 80,171,
+106,113,251,198,105,212,212,136,177,115, 87,124,136,143, 15,217,175,172,172, 44,217, 90, 46,130, 32,130, 19, 19, 19,221, 73,146,
+ 4,147,201,196,250,245,235,225,237,237, 13, 7, 7, 7,200,229,114, 44, 94,188,216,113,225,194,133,142, 0,144,145,145, 81, 31,
+158,193, 18, 4, 2, 65,175, 57,115,230,216, 27, 12, 6,156, 59,119, 78, 75, 16,196,170,139, 23, 47,254, 28, 25, 25,201,236,219,
+183,175,253,254,253,251,123, 3,184,242,162,132,214,115, 30,151,127,225,194,133,238,147, 38, 77, 34,233,116, 58, 33,145, 72,224,
+228,228,132,237,219,183, 43,132, 66,225,233, 86,114,173, 95,190,124,249,234,186,207,123, 87,173, 90, 53,115,227,198,141,252,242,
+242,242,122,171,166,168,178,250,114,175,152,247,141, 85, 18,169,246,151,111,151, 77,224,176, 89,204, 85, 27,127,185,162,167,226,
+150,197,126,101, 48, 48,185, 92, 46,147, 36, 73, 28, 61,122, 20,197,197,197,239, 84, 85, 85,149, 27,141,198,248, 15, 63,252,112,
+105, 72, 72, 72,187,156,156,156, 98,185, 92,190, 73, 36, 18, 21,218,110,119, 54,216, 96,131, 13, 47, 13,102, 39,120,243,234,195,
+211,120, 58,157,216,188,208, 50, 26,141,115,206,159, 63, 79, 53,153, 76,216,181,107, 23,238,222,189, 75,114,185,220, 85, 92, 46,
+247,123, 14,135, 99, 84,169, 84,179,103,205,154, 53,101,205,154, 53,148,190,125,251,226,230,205,155,148,246,237,219, 79, 3,208,
+ 80,104, 69,163,133, 88, 27, 82,169,244, 78, 69, 69,121,251, 6, 1, 42,219,179, 88,236, 59, 22, 42,211,152,179,113, 80,204, 30,
+235,215,175, 87,120,121,121,105,211,211,211,177, 99,199, 14,211,221,187,119,147,152, 76,230, 78,161, 80,168,177,146,243, 69,160,
+158,147,105, 48,164, 30, 88,186, 52,172,219,232,209,166,153, 75,150,212, 50, 56,156, 15, 54,111,219,182, 76, 34,151,123,131, 32,
+ 72, 87, 71,199,226, 93,235,215,111, 24, 54,106, 84,109, 70,114, 50,251, 94, 98, 34,157,175,215,223,111, 77, 57,203,202,202,146,
+175, 92,185,138,189,187,191,129, 78,167,129,176,236,169, 78,171,172,146,194,130,200,250, 19,167,193, 96,144,142, 31, 63,158, 1,
+128, 51,117,234, 84,166, 72, 36, 66,135, 14, 29, 0, 0, 50,153, 12,167, 79,159, 70,104,104, 40, 0,224,225,195,135,245,159, 45,
+149,147,199,227,141,234,221,187, 55,138,139,139,145,145,145,113, 73, 40, 20, 86, 1,184, 84, 90, 90, 58,162,123,247,238, 56,126,
+252,248,200, 22,132, 86,171,218,200, 74,161,245, 39, 78, 14,135,179, 60, 62, 62,254,157, 27, 55,110, 76, 90,186,116, 41,125,208,
+160, 65, 0, 0,185, 92,174, 4, 96,108, 13,167, 74,165,218, 9,160,126,229,108, 81, 81,209,129, 37, 75,150,164, 44, 90,180,136,
+111, 46,159, 56,243,212, 77, 49,112, 51,188,255, 59,159,244,234, 30, 30,242,249,214,184,243, 37,165, 21,113,210,172,147, 82,107,
+234, 78,146, 36,244,122, 61, 76, 38, 19, 92, 92, 92, 20, 85, 85, 85, 16,137, 68,133, 34,145,104,222,163, 71,143, 90, 85,247, 23,
+217,231,109,156, 54, 78, 27,167,141,243,127, 20,214, 71,134, 39, 73,210, 96, 50,153,112,229,202, 21,196,199,199, 27,117, 58,221,
+187, 66,161,176, 97,180,234,109,169,169,169,137,227,199,143,223,151,147,147, 67,205,204,204, 4, 73,146,198,214,148, 70,173, 86,
+235, 9,226,207,219,254,106, 45,247,238,221,139,242,242,114, 93,105,105,233, 69,131,193,112,252, 47,174, 94,252,203,171, 14,247,
+ 2,154, 55,180,218,139,107,250,244, 25,188, 58, 49,145, 53,243,227,143, 53,211,223,126,251, 67,163, 86,171,167, 50, 24, 38, 38,
+143, 71, 49,178, 88,244,140,228,100,246,214,185,115, 93, 84, 26,205,185,184, 86, 56,152,155, 45, 90,253,251,247,197,244,153,139,
+160,106, 96,209,186,121, 39, 23, 26, 29, 90,101,209,210,104, 52,225, 66,161, 16,108, 54,187, 4,128,231, 91,111,189, 5,147,201,
+ 4,149, 74, 5,185, 92, 14,129, 64, 32,125,251,237,183,141,117,226,137, 54,110,220, 56, 7,107,120, 3, 2, 2,188,233,116, 58,
+206,157, 59, 7, 58,157,126, 26, 0,232,116,250,233,196,196,196, 17,147, 39, 79,134,143,143, 79, 64, 65, 65, 1, 1, 11,254,105,
+238,225,163, 15,147, 64, 16, 8, 4, 62, 53,193, 33,144, 31, 62,250, 1, 1,228,213, 69,141,207,234,218,181, 43, 96,165, 95, 86,
+ 67,212, 45,238,216,162,215,235,143, 44, 91,182,108, 94,143, 30, 61,134,172, 89,179,134, 64, 93,168,134,191,136,220,178,178,178,
+215, 86,172, 88,113,158, 36,201,103, 68,191,168,178,250,114,207,216,249,164, 68, 34,189, 39,206, 58,245,176, 85, 22, 83,131,225,
+ 47,133,179,176,193, 6, 27,108,176,225,133, 89,181,254,132,102,133, 22, 65, 16,187,250,245,235,247, 46, 0, 42, 65, 16, 59, 4,
+ 2,193,159,110,254, 66,161, 48,215,219,219,251,171,118,237,218,205, 6, 64, 18, 4,177,171,149,133,170, 32, 73,124, 73,161, 16,
+203,158,138,187,231, 10, 80,105, 78, 75,178, 12, 0, 65,161, 80,247,165,165,165,125, 92, 82, 82, 34,182,210, 2,209, 34, 94,196,
+170, 67, 0,248, 21, 40,124,189,184,248,252,146,136,136,232, 97,115,231,162,211,176, 97, 14,222,109,218, 24, 85, 58,157,233,225,
+181,107,196,141,163, 71, 25,247, 18, 19,233, 42,141,230,220,113,160,164,181,229, 44, 43, 43, 75,190,156,148,124, 97,194,184, 17,
+ 67, 2,218,121, 63, 21, 13,133, 2, 84, 86, 75, 47,180, 70,100, 53, 18,189,163,183,111,223,126,138,193, 96,208, 26,166,178,209,
+233,116,213, 26,141, 38, 28, 0,106,106,106,188,119,237,218,245, 27,133, 66, 41,182,196,151,153,153,121,114,245,234,213,227,138,
+138,138, 46,148,150,150, 22, 1, 64, 73, 73, 73,145, 94,175,223, 39, 20, 10,199, 21, 23, 23, 31,131, 21,139, 0, 72, 32, 40,227,
+218,145, 72, 0, 8,239, 51, 17, 25,215,142,176, 1, 68,134,247,153, 8, 0,120,222, 92,134, 13, 81, 23, 6, 97,213,205,155, 55,
+ 15, 14, 25, 50,100, 22,254, 66, 76,175,198, 98, 75,167,211,181,105,188,209,108,217,106, 13,145, 86,171,213,171, 84, 42,131,209,
+104,164,233,116, 58, 82,171,213,234,109,247, 57, 27,108,176,225,223, 10,146, 36,187, 3,224,155,111,155,117,239,252, 70,159,181,
+168, 75, 23,104,190, 85,214,125, 23, 19, 4,113,167, 1, 71,253,118, 43,142, 5,128, 74, 0, 15, 8,130,104,206, 8,178,171,185,
+239,205, 10, 45,129, 64,112, 12, 86, 36,141,182,118,191, 22,176,162, 46, 11,222,235,141, 0, 0, 32, 0, 73, 68, 65, 84, 79, 28,
+240,252,121,216,234, 57,140, 70, 99, 69, 73, 73,201, 95,110, 80, 10,133, 82, 56,114,228,200, 86,237,111,105,159, 67, 64,241,251,
+ 26,205,254,132,239,190,235,114,110,199, 14, 31,163,193,224, 74, 0, 36,149,201,172,210,106,181, 69,124,189,254,126,107, 45, 89,
+207, 88, 99, 30,151, 13, 45,120, 92,134,192,192, 64, 50, 63, 63,255,169,173,231,175,225,190, 66,161,240,179,212, 5,148, 74,101,
+ 95, 43,197,224,175,101,101,101,191, 54, 33,216,127, 19, 10,133,191, 89, 91,168,250,164,210, 0,197, 68,152, 38,132,247,153,120,
+ 20,128,201,156, 84,250, 69,162,188,188, 60, 7,117,113,222,254,110, 40, 46, 46,214, 16, 4,113,224,203, 47,191,156,122,239,222,
+189, 67, 2,129, 64, 99,187, 21,219, 96,131, 13,255,102,145, 69, 16, 68, 66,221,247,216, 58,163, 80, 66,227,207,230,125,204,251,
+ 53,220,199,204,209,120,123, 75,199, 2,192,242,229,203, 63,222,176, 97, 3, 23,128,181,201,152,159, 59,169,244,203, 66,197,223,
+132,163,161, 40,216,253, 50, 42,250, 29,160,133,193,112, 11,134, 6, 62,249,250, 23,107,136,200,207,207, 39,254,205, 23,156, 57,
+169,116, 3, 68,252,175,222,124,138,138,138,182,251,251,251,239, 20, 8, 4, 6,216, 96,131, 13, 54,252,123,193,111, 74, 24, 53,
+ 35,202, 98, 91,250,253,153, 7,247, 38,246,107,234, 59, 65, 16, 9, 27, 54,108,136,109, 69,121,235, 45, 90, 20, 91,219,217, 96,
+195, 63, 27,255, 31, 43,105,109,176,193, 6, 27,254, 13,104,108,197, 50,139,175,198,223,151, 47, 95,254, 49, 90,158,113,242,194,
+ 83, 43,150, 87,221,247,122,127, 45, 2, 79, 87, 14, 52,133,214,172, 38,136,126,142,250, 93,180,113,218, 56,109,156, 54, 78, 27,
+167,141,211,198,249, 63,199,105,137,251, 98, 19,130, 40,166,185,169,190,150,166, 17, 27,127,182,116,172,165,125, 9,130,104, 46,
+204,143,121,170,176,241,251, 75, 71,180,141,211,198,105,227,180,113,218, 56,109,156, 54, 78, 27,231, 95, 1, 73,146,221, 73,146,
+140,193,211, 5, 83, 36, 73,146, 49, 36, 73, 14, 91,190,124,249, 10,243,182,229,203,151,175, 32, 73,114,144,121,191,186,125,234,
+143, 49,111,107,252,222,120, 91, 75,251,182, 80,196,119, 27,125,174,255,254,119,241,209,178,193, 6, 27,108,176,193, 6, 27,108,
+104, 18,230, 21,131, 13,172, 77, 98, 0, 15, 55,108,216, 80,211,192,119, 74, 12,224, 62,128,206,117,251,137,235, 68, 90, 67,223,
+ 42,109,221,119,109, 19,251,104,173,217,183, 25,236,106,230,179, 77,104, 53,135,206,158,148, 79,253,125,221,163,234, 26, 0,100,
+ 93, 18, 96, 83, 93,188, 34,210, 28,184,200,100, 2, 73,146, 16,136, 36,169, 15, 69,248,228,121,255, 47,216, 27, 46,238,108,246,
+ 22, 19, 73,246,169,219,148, 44,173,210, 44,202,144, 65, 98, 45, 71,168, 7,194,216, 20,124,104, 34,209, 9, 0, 40, 4, 30,168,
+ 77,248, 42,187,162,245,241,164,154,234,231,225,124,188,203,228,112, 95,119,116,114, 14,172,169,169,204,211,169, 53, 71, 50,197,
+216,137,214,231,101, 68,128, 51, 94, 53,145,248, 24, 0,133, 78,193,215,121,213, 86,175,228,176,193, 6, 27,108,248,171,214,145,
+191, 20, 23,143, 32, 8, 99, 19,156,196, 95,228,180, 5,195,179, 66,108, 53,177,249,143, 38,182,221,249, 59,149,187, 85, 66,171,
+ 35, 31,115, 65, 96, 45, 0, 18, 36,214,101,138,241, 99,171,142,247, 66, 52,155, 74,253, 9, 0, 85,173, 51, 46, 33, 77, 72,105,
+242,100, 82,240, 26,155, 65,253, 26,128, 73,109, 52,206,200, 20, 90,239, 47, 22,238,131, 97, 52, 19,229,128,137, 36,233, 70, 19,
+185, 15, 36, 18,236, 24,184,126,171, 12,234,214,148,213,223,215, 61,234,196, 31,194, 33, 73, 63, 46, 64,143, 78, 29, 64, 26,255,
+143,189,243, 14,143,162,106,184,248,153,153,173,217,244,178,233,133,158, 70,104, 2,161, 55, 65, 90,248, 40,130, 52, 1,225,165,
+136, 40, 34,138, 10, 10, 8, 74, 81,105, 74, 7,149, 38, 29, 41, 1, 41, 81,122,137,244, 84, 2, 9,164,247,158,108,182, 77,185,
+223, 31, 41, 38,144,182, 1,245,149,119,126,207, 51,207,108, 61, 59, 51,119,118,230,204,185,101, 56, 64, 96,161,234,254, 17,126,
+ 91, 51, 1,129,126,158, 32, 2, 11, 8, 28, 44, 6,126,139,129, 1,214, 36, 44,179, 97,247,193,246,118,133,157,151,131, 99,248,
+182,109,219,157, 93,155,250, 83, 2,103,196,131, 63,206,142,127,127,222,194, 62, 45, 81, 16, 80, 31,179,213,218, 5,255,241,108,
+228,243,209,156,197,171, 25, 23, 87, 15,115,129,213,115,233, 79,162,218,125,247,245,194,195, 50, 58, 97,213,253, 52,108,175,239,
+190,236,175,198,116,137, 66, 62,202, 76,105,222,188,164,164,232, 17,111,100, 15,210, 82,201,128,111,190, 93,219,182, 87,191, 65,
+ 22,124, 81, 58,205, 10,240, 63,176,127,159,215,247, 27, 54, 14, 10, 79,227,255, 15,128, 96,202, 58, 11, 4,243, 98,118, 77, 27,
+ 36,149, 48,148,223,228,109, 12,192, 53,200,104,249, 57, 98, 44, 69, 80,231,240, 18,132,194,229,168, 76,236,109,200,111,248, 58,
+226, 7,138,192, 27, 20, 14, 81, 4,251, 34,179,144, 41, 30,242, 68, 68, 94, 46,104,154, 62, 47, 8, 66,239, 23,108, 12, 58, 17,
+ 66,110,136, 91,247,127, 27,211, 18, 45, 10, 95, 70,196, 38,217,130, 55,162,165,119,211,165,128,105, 70, 75,201, 48, 59,111, 62,
+204,112, 6,103,196,182,175,102,238, 55,176, 0,199, 26,193,115, 44,120,142, 5,199, 25,193,179, 44, 8,171,199,194, 31,207, 3,
+134, 34,180, 15,104,177, 19,224, 93,234,251, 27, 82, 66,239,190,125,229,172, 29,101, 40,192,222, 77,203,223, 77,202, 42,126, 55,
+228,126,106,182,191,163,246,211,200, 76,252,100,138, 33, 56,191,121, 54,246,252,114, 50,121,221, 15,154,104,129, 16,216, 89,153,
+249,140, 15,138,240,216,117,236,124,210,218,157,186,104, 0,176, 54,151,251, 76,188,255,208,243,121, 10,193, 81,169, 92,187,101,
+227,247,206, 46,246,102, 20,119,109, 5, 56,158,135,135,215, 96,230,211, 89,227, 93,190, 92,179,125, 13, 10,245,147,106,251,190,
+143, 35,252, 27, 53,246,155,187,243,228, 53, 79, 77, 97,166,225,236,207,243, 99,161, 7,235,236,230, 39, 93,186,124, 53,179,224,
+227,217, 31, 24,248,228,208, 7,153,136,172,235, 88,227,231,136, 99,203, 87,124,219,186,207,192, 32, 11,161, 56,139,209,105,138,
+189,183,253,184,125,177,111,235,142,170,238, 1,238,178,204,131, 51, 40,109, 81, 46,140,180, 82,209,167,101, 95, 43,237,155, 99,
+216,109, 59,246,204,138,204,196,119,166,172, 51, 79,254,220,247, 4,161,225,163,174, 83, 4,221,239,222, 56, 63,157, 79,189, 9,
+194,179, 0,111,172,152,131,103, 65,132,210,121,224,140, 31, 1, 52,204,104,209, 4,175,133, 92,185,233,146,145,158,214, 97,205,
+183,203, 62, 37, 55,111,254, 10, 30,187,163,114,113,209, 84,131, 9,192,187,137, 61,115,134,229,161, 79,202,231,189,203, 95,236,
+227,173,232,226, 98, 65,189,154, 88, 64, 93,186, 28,171,189, 40, 30,154, 68, 68,254,145,196,132, 35,132, 72, 94,176,230, 32, 66,
+200,169,231,148,249, 8,192,127,202, 30,111, 7,240,205, 11, 88, 52,119, 0,206,101,143,211, 1, 36,139,123,192,115,241,116,227,
+247, 6,143,163,165, 4, 17,128, 67,195, 0,192,204,212,165, 32,128, 18, 20, 3,176, 26, 12, 29,216, 15, 14,142,206, 0, 91, 2,
+ 24, 75, 0, 86, 11,176, 26,128,213, 34, 59, 45, 1, 48,106,128,184, 95,193, 17,162, 48,121,117,245, 5, 64,204, 65,188,218,206,
+ 19,106,107, 37,102, 15,245,119,216,122, 58,102,251,246,179, 15,250, 70,102, 98,116,189,150,149, 16, 4,182,106,142,117,219, 53,
+209, 39,238,100,245, 7,128, 65,109,236, 79, 7,250,123,121,172,221,169,139, 62, 21,150, 55, 0, 0, 6,180,180,250,181,163,143,
+139,167,128,134,167,190, 2, 33,221, 93, 27, 53,167,248,187, 91, 32, 20, 38,163,176, 80,139,228, 39,187, 96,235,246, 10,205, 11,
+232, 89,215,247,205, 24,124,242,222,130,149,210,146,194, 12,131, 96,204,226,213, 76, 30, 35,145, 11, 20, 82, 46,234,139,133,124,
+126,206,180, 9,220,220,207,191,250, 4,192,248,218,116,252, 29, 49,107,213,170,181,173,186,182,247,117, 76, 63, 60,155, 42,206,
+203, 0,199,168, 20, 67, 59,119,133, 77, 11,127, 33,227,194, 42, 74,222,180, 47,108,236,155, 34,229,218,207,136,191,113,132,234,
+214,110,132,226,167,189,178, 55, 1, 99,181, 70,171,185, 3,186,245,239,209,113,127, 83, 79, 87, 23, 66, 4, 8, 2, 1, 17,120,
+ 20,235, 88,124,122, 32, 14, 60,207,227,245,254,221, 94, 53,151, 83, 68, 16, 4, 16, 34, 32, 41, 61,167,228,247,208,232, 87,227,
+242, 16, 90,159,164,170, 77,167,222,221,238,223,190,225,203,198,156, 64,251,241,203,163, 41,224, 74,165,125,174,219,157, 51, 63,
+249, 2, 63, 54,220,203, 81,224,227, 79,175,128,103,143,105,204,150,189,167,213, 5, 89, 41, 19, 15,239,218, 56,114,211,150, 45,
+123,162, 51, 49,195, 20,147,245,126, 15,249,149, 53,191, 23,218,119,110,106,158,149, 84, 41,167,108, 98, 75,247,223,124, 42,242,
+189,235, 75, 2,125, 23,156, 36,249,151, 98,117, 97,226,113, 75, 68,228,239,133, 16,242,194,205, 86, 66, 66, 66,234,243,152, 45,
+ 55, 55,183, 30, 41, 41, 41, 95,151,183, 86,161, 40,234,235, 70,141, 26, 45,252,243, 66,181,202,181, 94, 1,207,243,227, 83, 82,
+ 82, 46,213,166, 57,120,240, 96,215,147, 39, 79, 54,174,164,217, 24, 64,227,234, 62,107, 99, 99,195,119,233,210, 37,254,228,201,
+147,169,226, 30,210, 32,195,101,178,209,138, 78, 60, 56,187,157, 62,173, 24, 0,162,235,241,249, 42, 85,126, 58,150, 95,177, 99,
+241,132, 21, 45, 27,217,161, 72, 99,192,217, 91,241,224,121, 22, 60,199,149, 37, 91, 28,120,142, 69,255, 54, 14,232,162,155,129,
+239,130, 31,128,227,133,229,181,105, 62,141,145, 8, 99,219,246,125,227,128, 32, 16,185, 66, 74, 23,120,123,216, 59,206,125,189,
+ 13, 61,123,104, 75,104,141,220, 27, 63, 95,136,253, 61, 42, 19,219,234,165, 41, 60, 59, 60, 17,169,238, 53,158,171,115,221,107,
+ 73,163, 2,251,246,234,110, 69,244, 5, 96,179,227, 80, 84,194, 34, 46,135, 69,186, 46, 31, 10, 42,173, 94,154, 2, 65,107,119,
+ 55, 23,213,213,253, 31, 63,177,103, 10, 37,142, 12, 39,147,211, 28,120,129, 48, 36, 63, 82,111,231,219, 79, 90,222,110,171,182,
+229, 52, 83, 89, 78,232,241,218, 96,235,196,159,167, 81,102,222,253,225,216,206, 3, 79, 46,237, 64,230,173, 96,228,164,198, 83,
+ 86,186,124, 56,217, 55,195,192,241,163,241,205,232, 14, 40, 42, 44, 2,147, 22,107, 45,151, 42,108, 0, 99,181,154,132,199,248,
+ 85, 43,191,114,145, 48,116,233,246, 44,159,120, 22, 90,189, 30,224, 57, 40, 37, 2, 40, 82,254, 30, 11,158, 53,170, 90,143,248,
+120, 38,192,135,214,181,238, 81,153,216,235,175, 70,119, 8,172, 47, 97,181,160,128, 43,145, 89,127,154, 31, 63, 71,140,125,165,
+255, 91,221, 9,133,203, 13, 41,163, 0,123, 4,181,111,108, 97,110, 94, 24,141,228, 67,239, 34, 22, 74,226,212,245, 63, 24, 59,
+121,150,106,235,214,173, 67, 0,242, 54,170,182, 81,171,208,244,117, 98,166,179, 60, 22, 2,128,150, 37, 59, 44,229,212,228, 85,
+251,174,219,131,249,243, 14, 15,229, 73, 86,108,142,144,103, 60,255,217,131, 78,115,131,123,181,186,219, 43,137,162, 20,137, 23,
+ 31,233, 11, 76,217,151, 76, 68,212, 20, 53,255,114, 77, 43, 43,171, 38,141, 26, 53, 90,200,178,108, 15,153, 76,230,100, 52, 26,
+ 33, 8, 66,186, 92, 46,191, 28, 31, 31,191,164,176,176,240,241,127,219,186,223,191,127,223, 20,179, 85,167,166, 84, 42,197,131,
+ 7, 15, 30,153, 96,182, 66,158,250,254,238, 43, 87,174,224,192,129, 3, 0,128,152,152, 24,180,104,209,194,188,186, 47, 62,121,
+242,196,188, 87,175, 94,187, 1,120,212,166, 25, 22, 22,214,228,196,137, 19, 56,116,232, 16, 0,224,193,131, 7,240,246,246,174,
+118, 97,174, 92,185,194,140, 27, 55,174, 9,128,212,191,161,140, 94, 6,147, 85,121,254,167,209, 10, 14, 14, 38, 65, 65, 65,212,
+211,143,171, 33,206,211, 86,222, 14, 58, 30, 0,226, 76, 93,130,168, 12,172, 92,183,235,204,128,223, 14,109,232,161,148,209, 88,
+180,109,110, 82, 86,110, 81, 39, 9, 85, 90,253,194, 17,208,182, 22,242,235,203, 39,182,241,204, 43,214,225,248, 31, 41,151, 34,
+ 51, 77,139, 72, 35,211,112, 14, 16,108, 74,159,241,208,105, 51,189, 39,126,115,110,223,190, 79, 6,180,158, 51,180, 53,142, 93,
+139,159, 3,112,117,142,250, 78, 4, 1, 68,224, 42, 26,191,151, 93, 58, 0, 66,213, 27,248, 10, 32,165,175, 9,166, 37, 90, 61,
+ 1, 73,158, 35, 6, 90,170,228,235,167, 79,159,106,197,102, 61, 68,174, 65,134,164, 60, 29,210,181, 82, 20, 75, 28,145, 18, 29,
+198,211, 20,206,213, 25,185, 80, 40, 36,156,206,198, 86,110, 65, 7,244,155,233, 86,120,122,126,158,156,226, 24,171,225, 95,218,
+100,255,182, 58,158,211,100,105, 40, 10,117, 14, 63,111,109,109,211, 66,151, 19,207, 20,228,101,195,198,185, 37, 6,188, 17,132,
+ 47, 6,251,163,168, 80,131,172,220,235,164,185,139, 21,149,112,121, 15, 22, 12,244, 67, 78, 70, 26,244, 44, 64,105,244,185, 58,
+131,174,184,198,237, 72, 99,203,251, 31,206, 27,235,229,162, 54, 47,239, 84, 64, 4, 30,109,252,154,162, 95,143, 64,156,187,114,
+ 21, 55,195, 98, 32,148,117, 42, 32,130,128,228,204,188, 12,157,145,223, 97,210, 6,229, 57, 16, 86, 87,173, 17, 67, 3,170, 12,
+ 3, 28,161,226,129,207, 59, 52,177,156,242, 73,144,151,165,185,130,130,142,229,161, 51,176, 40,186,186, 30,246,141, 90, 65,165,
+ 84, 82,237,160,149,220, 65,245,219, 86,199, 98,225,227,180,124, 23, 20,167, 99, 92,191,150,239,237, 92,254,142, 57,165, 44,221,
+ 53, 89,190,106,146,117,117,113,135, 51,227,150, 30, 61,127,224,224, 24,215,111, 62,154,208,171,255, 7, 59,206, 3, 56, 45, 30,
+183, 68,254,141,140, 28, 57, 82,153,145,145,113,193,195,195,195,191, 95,191,126,170,238,221,187, 67,163,209,224,236,217,179,208,
+104, 52, 94, 30, 30, 30, 94,103,207,158, 29,145,152,152, 24,233,238,238,222,235,208,161, 67,245,110, 67, 91,102,128,152,138, 67,
+ 48,192, 81, 20,133,178,215,168,178,215, 26,124,159, 91,185, 92,142,132,132,132, 23,158,108,165,164,164, 60,106, 72,178, 85, 92,
+ 92, 44,115,115,115,131, 90,173, 6,207,243,208,104, 52, 56,122,244, 40, 10, 10, 10, 32, 8, 2,204,204,204,240,229,170,109,136,
+190,115, 1,161,161,161, 40, 40, 40,144,213,165,153,156,156, 76,181,105,211, 6,122,189, 30, 28,199, 65,167,211, 33, 36, 36,164,
+226,185, 68, 34,193,188,165,107, 16,115,235, 2,238,222,189,139,228,228,228,191,229,110, 35, 38,120,145,255, 70,106, 28, 51,235,
+111,239,117,200,243,220,167, 91,119,238,187,254,233,140,209,152, 53,166,175,199,146, 13, 71,250, 70,101, 99, 39, 0,248, 57, 96,
+226,155,189,155,123,218,168,164,248,226,231, 91, 0, 33,159, 62,239,239, 69,228, 34,198,223, 73,152,243, 75,104,194,133,249,163,
+219,161,169,139, 85,139, 60,121,174, 60, 46,174, 30,247, 20, 20, 56,216, 90, 40,124, 6,181,177, 63, 13, 65,128,141,165,194, 23,
+ 60, 7, 27, 11,133,207,128,150, 86,191, 2,128,149, 74,234, 91, 93,242, 85, 19,237, 61,164,211, 84, 10,201, 52,115, 75, 27,207,
+ 73, 67,250,153, 13, 26, 50,194,204, 66,202, 33, 39,244, 44, 10,165,238, 96,237,188,160,103,115,145,252, 56,150,255,237, 70, 84,
+ 74,118,145,126,110,157,139, 73,112, 41,229,241, 3,117,147,214,253,108,179,131, 23,100, 54,121,235,231,198, 52, 4,186,104,207,
+240, 12,115,199,142,102,127,196, 61, 46, 22, 72,181,137, 78, 21, 10, 11, 10,226, 89, 30, 46, 90, 94, 98, 25,123,254, 39,124, 50,
+176, 21,242,114, 51,161, 51,114, 40,208,114, 70,103, 27,165, 66,255, 56, 28,122, 35, 7, 3, 43, 64,106,227,134,179,215,195,178,
+ 5,150,253,181, 38,205,184, 28,220,141, 59,122,215,162,242,107, 77, 29,208,230, 99, 43,179,187, 96,181, 72, 72, 78,197,206,147,
+215,219,197,229,224,238,243,148, 51, 17,184,210,234,231, 74, 73, 22, 69,208,189, 33,141,224,125, 29,209, 81,166,148,125,255,245,
+156,113,254,157,189,237, 20, 66,242,117, 80,130, 17,230,188, 4, 90, 57, 15,107,143,166, 16, 12, 69,164, 68,167,203,143, 0,106,
+ 43,124, 6, 0,136, 81,131,111, 38,180, 52,167,108,155,130,143, 59, 13, 73,219,105, 96,203,210,254,216, 28, 33,204,120,254,179,
+232, 46, 31,158,232,185,244, 92,239,168,212,147,139,162,220, 70,174,111, 3,236,104, 36,158,174, 69,254,141,248,248,248, 56,167,
+164,164, 68,124,248,225,135,118,195,135, 15,199, 47,191,252,130,194,194, 66,236,216,177, 3,107,215,174,197,226,197,139,193,178,
+ 44,182,110,221,170, 58,124,248,112,199,141, 27, 55, 38,123,122,122,182, 76, 76, 76, 76,175,195, 96, 81, 0, 20, 0,164,101,231,
+ 46, 10,128,112,234,212, 41, 12, 26, 52, 8,167, 78,157, 18,202, 94,227, 81,122,241,211,160,123,127,202,229,114,200,229,114, 20,
+ 20, 20,188, 16,179, 37,149, 74, 97, 97, 97, 1,185, 92,142,162,162, 34,147,205, 22,199,113, 76,114,114, 50, 10, 10, 10,208,111,
+200, 16,172, 89,190, 28,189,123,247, 70,191,126,253, 64, 8, 65, 72, 72, 8,250,118, 13,192,232,255,235,133,168,168, 40,112, 28,
+ 87,175,229, 77, 79, 79, 71, 70, 70, 6, 6, 12, 25,130,109, 27, 55, 34, 48, 48, 16, 62, 62, 62,224, 56, 14, 23, 46, 92,192,200,
+254, 93,161, 28,214, 23, 49, 49, 49,226, 78, 93,255, 52,235,133,180,209,122,110, 34,178,112, 67, 56,118, 49,120, 76,255,142, 65,
+ 67,186,249, 99,219,254,223,190,130,186,112, 31, 0,216,235, 21, 95, 78,232,221, 20,145,137,121,248,237,110,106,112, 84, 54, 94,
+ 72,111, 13,129,135,131,189,149, 10, 96,228,208, 26, 5,206, 42,174,238, 6,204, 2, 33, 80,245,248, 24,111, 14,137,244, 8,244,
+247,240, 40,239,117,104, 49,104, 53, 38,134, 61,242,236,224,227,236, 9,158, 5,120, 22, 86,163,127, 6,150,154,215,185, 28, 93,
+ 27,203,207,189, 63,123,118,151,129,195,222, 48,147,171,172,193, 23, 38,129, 77, 15, 67,206,195, 75,208,168, 90, 32, 61, 33, 14,
+ 7,206,132, 22, 60, 76,206, 41,164,105,156,205, 40,208,127, 20,151,135,226,186,116,117, 44,150, 47, 92, 48,119,240,129,125,251,
+ 45, 21, 77,187, 81,177,235, 7, 21,200, 37,156, 66,221,248, 21,186, 68,233, 64,150,237,216,111,165, 49, 96, 69, 93, 58, 37,154,
+194, 35, 33,103, 79,143,110,222,164,155,229,147,155, 39,161,213,233,161,103,129,150, 29,123,129,231,137,156,162, 41,193,138, 97,
+168,204,156, 60, 80, 44,159,113,249,222,147,180, 43,247,226, 24,189, 37, 86,212, 58,186,200,211,238,158, 98,222, 27,210,171, 45,
+192,106,241,127, 61, 90, 97,205,158,223,222, 5,248,183,158,175,144, 75, 19, 45, 2,116,243, 87, 99, 51, 33,232,118,235,232, 90,
+223,246,195,222,135, 41,137, 86, 75, 7, 12,244,107,226,250,211,154, 47, 63,182,179,119,111,193, 80, 2, 11,226,220, 26, 40, 76,
+ 38, 84,242,117, 88,187, 5,130,119,237,138,173,223,125, 91, 44, 8,100, 31,106, 25,218,130, 23, 0, 33,241, 34,248,232, 95, 16,
+ 23, 23, 7, 7,175, 91, 0, 69,131, 52,122, 2, 35, 87,250, 53,189,145,156, 92,183,227, 68,239,143,250, 44,111, 57,196, 87,226,
+121,253, 94,108,230, 27,147, 93, 85,157, 60, 25,239,200, 52,115, 58, 91,163, 17,196,227,151,200,191, 9,157, 78,119,100,229,202,
+149,118, 65, 65, 65,229,137, 12,174, 95,191,142,237,219,183,195,220,188,234,113,114,208,160, 65, 32,132,216, 45, 90,180,232, 8,
+128,206, 53,105,118,233,210,101,200,221,187,119, 83,219,182,109, 27, 87,102,182,100, 0,232,240,240,112, 58, 41, 41,137,178,181,
+181, 37,174,174,174,108,106,106,170, 0,128,159, 60,121, 50,115,240,224,193,230, 26,141,230, 98, 67,141,150, 92, 46,127, 33,109,
+182,164, 82, 41, 40,138,130, 92, 46,135, 76, 38, 3, 33,196, 36,179,197,243,188,228,212,169, 83,184,117,235, 22, 22,183,109,139,
+ 57,110,110,176,179,179,195,133, 11, 23, 64, 8,129,185,185, 57,114,115,115,177,111,223, 62,244,233,211, 7, 28,199,201,234,163,
+123,232,208, 33,220,190,125, 27, 75,219,183,199, 28,107,107, 88, 88, 88, 32, 36,164,180, 54, 80,161, 80, 32, 33, 33, 1, 33, 33,
+ 33,232,213,171,151,184, 83, 63, 39,245,222,121,122, 2,146, 92, 10,206, 70,131, 22,132, 35, 0, 5, 87, 63, 63,200,162,162,170,
+ 54,206,169, 15, 52,141, 5,223,237, 12, 30,188,250,253, 33,212,180,161,237, 92,151,252,116,254,109, 0,152,242,186,183,155, 74,
+ 33,193,186, 99,145,132,166,177,224, 69,172,160,159, 31,100, 84, 14,222,238, 23,232,131,212,124, 3, 98, 83,243,127,143, 2,234,
+117, 23,231,223, 86,191,137, 93,199, 47, 36,173,221,165,139, 38,132,192,198, 66,225, 51,241,126,172,231, 79,167,110, 39,174, 58,
+160,139, 38, 2,129,141, 74,234,251, 86, 84,215, 58,123, 29,182,247,144, 78,251, 96,238,220,174, 67,223,250, 80,201, 69, 31,132,
+ 33,246, 12, 4,163, 22,133, 70, 25,242, 25,103, 36, 39, 38, 98,217,214,224,164, 66,141, 97,116, 68,150,105, 6,243, 97, 14,138,
+ 37, 84,225,240,101, 95,204, 63,183,252,203, 69, 22,218,184, 11,197, 12,197,105,153, 70, 61, 37, 95, 46, 94, 77, 21,233, 13,111,
+196,229,161,168, 46, 29,189, 37, 86,172, 92,245,221,224,169,227, 71, 68,123,183,232,105,207,167, 62,182,215, 21, 22,102,254,124,
+250,182,115,217,149, 34, 5, 0,177,201, 57,200, 42,208,112, 60,199, 94,180,148, 98, 73,100,125,210,193, 50,154, 56, 66, 29,212,
+173,229, 56,181,165, 12,218,226,124, 56, 90, 74,209, 63,176,217, 56,246,143,152,143, 31,103,154, 98,215,158, 54, 90, 44, 8,171,
+197,141, 21,125,124, 9,207,250,130,103, 97,188,191,219,244,100,140,194,156, 89, 61, 44,172,108, 13, 79,104,104,204, 1, 51, 7,
+ 80, 86, 94,128,117, 99, 74,234,247, 6, 82,227, 34,184,119,199,141,207,121, 28,159,252,131,131, 89,237,213,218,172, 64, 32,196,
+ 95, 64,113, 70, 44,194, 83,141,104,153, 89, 90,219,110,149,113, 7,188, 56, 98,142,200, 75, 74, 66, 66,194,132, 79, 63,253,244,
+ 74, 96, 96,160,147,131,131, 3, 90,181,106,133,227,199,143,227,195, 15, 63,172,248, 76,219,182,109, 65, 8, 65,110,110, 46, 86,
+174, 92,153,158,154,154, 58,161,214, 11,244,136,136,232, 93,187,118,245,240,247,247, 55,202,100,178,124, 0,138,252,252,124,101,
+110,110, 46,165,211,233, 32, 8,130, 96,109,109,205,167,166,166,178,163, 71,143,214, 95,187,118,173,153, 70,163, 73,120,158, 68,
+203,195,195, 35, 60, 39, 39,167,128,162,168,231, 30,250,161,220,100, 57, 56, 56,168,139,139,139, 5, 0,121, 13, 25,250,129,227,
+ 56,180,111,223, 30,103, 46,221,193,169,223,174,161, 48,245, 1,222,158, 58, 1,173, 90,181,194,153, 51,103, 26, 92,102,109,218,
+180,193,233,144, 43,184,114,235, 30, 18, 98,238,227,221,183,167,162,101,203,150, 56,125, 90,108,189, 96, 2, 39, 81,181,109,214,
+201,167,141, 86,175,224,224,224,242, 67,255, 51,246,213,215, 1,109,164, 54,242,221,139, 6, 54,243,147,246, 91, 4, 74,106,134,
+131, 45, 78,119, 93,176,108,125, 52,227,152, 48, 62, 60,179,238,222, 97, 85,254, 52,153,136, 32,161,209,123,239, 69,249,142,251,
+191, 64, 15,108, 59,174,250, 28, 0,222,232,222, 4,127, 60,204, 66,104, 76,230,222,200, 44, 68, 60,239, 90, 7, 56, 66,197,103,
+ 99,239,202,247,134,246,242,114,119,198,246, 95,174,128,162,112,164, 94, 39, 92, 66, 72,160,191, 23,214,238,122,186,135,161,179,
+231,170, 3,186,232,179, 17, 69, 3, 1,160,159,175,234,215, 14,205,108, 61, 73,229,134, 91,213, 96, 38,151, 76, 31, 56,226, 77,
+ 37, 23,115, 28,136, 15, 1,197,233,161, 53, 10, 72,203, 46, 66,137,181, 7, 46, 92,191,167, 45,208, 25,222,143,204,106, 88,138,
+ 23,149,141, 56,217,205,123,137,197, 26,173,139, 74,221, 76,199,208,130, 80,172, 39,248, 35, 50,190, 48, 50, 29, 15,234,163, 17,
+ 23, 7, 67, 39, 55,174,251,230,157, 7, 22, 74,101,242, 55, 24, 10,148,163,141,185,122,243,234,165,176,180,180,128, 96, 40, 6,
+ 52, 89, 24,254,206,178,172,240, 84,182, 9, 0,180,176,135, 69,247, 38,210,157, 18,154, 74, 62, 31,107,252,172,174,223,160, 88,
+204, 24,223,191,173, 84, 48,104,240,222,202,253,216,242,241, 80,188,249,170,159,244,228,213,152, 25, 0,150, 52,180,172, 9,207,
+129,176, 90,116,158,127, 41,154, 2,174, 16,160,219,173, 3, 95,250, 2,119,234,173,209, 14,144,242, 18,202,175,181,167,185, 76,
+ 72,190, 10, 33,249, 42, 97, 60,186,130,242,236, 65, 81,206,237,201,247, 95, 47,214,108,219,182,253,172, 64,227,139,122, 12,149,
+ 1, 94, 0,178, 99,174,192, 96, 48,128,229, 1,157, 78, 7,141, 70, 3,243,216,211, 21,109,180,100, 82,106,192,236, 73, 67,218,
+144,226,212,146, 19,209, 92,226,246,169,190,157, 73,113,106,201,141, 68, 62, 38, 91,163, 23,211, 44,145,127, 35,113,169,169,169,
+ 3, 6, 13, 26,244,219,153, 51,103,236, 2, 2, 2, 0, 0,183,110,221, 42,189,232,108,223, 30,222,222,222,200,200,200,192,152,
+ 49, 99,178,211,210,210, 6,160,142, 54,191, 69, 69, 69,143, 15, 29, 58,228,164,209,104,218,126,246,217,103,153, 94, 94, 94,133,
+ 58,157,142,202,207,207, 23, 56,142,131,173,173,173,188,109,219,182,232,210,165, 75,241,245,235,215, 27, 37, 37, 37, 21, 1,136,
+111,200,194, 15, 29, 58, 20,151, 46,149,118,218,123, 17,227,106,201,100, 50, 4, 4, 4,184,197,197,197,165,148,157, 91, 76, 62,
+198, 87, 62,189,220,187,119, 15, 23,239, 36, 67, 98,208, 66,158,149,138, 27,191, 28,194,144,233, 51,193,113, 13,191,183,252,189,
+123,247,112, 52,228, 6,204, 21, 18, 60,120, 16,129, 67,135, 14,225,237,183,223,126, 46,205, 6, 82,171, 23,249, 47, 39, 13, 53,
+180,211,146, 0, 64, 80, 80,208,197,242,180,162, 50, 77,155, 66,174, 40,198,162,126,237,220,230,189,209,173, 25,195, 22,166, 66,
+224, 5, 48, 82,192,209,193, 10,187,119,239,109,178,119,255,254,235, 27, 55,108,252, 78,224,184, 5,225,153, 40, 49, 97,161, 22,
+173,222,127,229,141,221,115,123, 73,222, 30,232,107, 7, 0, 50, 9,141,117,199, 35, 56, 0,139,158,103,109, 59,185, 65, 89,204,
+ 98,154,163,189,245,231,159,254,103,176, 93,175,246,222,184, 24, 26,142,239, 14, 93,191, 36,207,196,174,122,239,220, 2,139,167,
+253, 83,117,189, 14, 33,212,221,238,146,231,137,179,204,220, 22,198,248,243,128, 81, 7,157,222,136,164, 28, 30, 73,185, 58, 72,
+ 84, 50,220,138, 73,214,218,167, 35,248, 57, 86,155, 50, 87, 41, 93, 23,126,181,202, 93,167, 45,230, 10,243,178, 57,153,252,134,
+ 84,101,166, 72, 51,165,169,194,141, 20,232,122, 52,150,190, 2, 8,140, 92, 73, 74,230,127, 48,201, 60, 37,242, 12,154,211,169,
+160, 8,129,153,223, 96, 88,154, 49,178,110,141,164,137, 0, 96,110,174,146,175,252,226, 67,235,247, 63,254,162,206, 54, 96,126,
+128,204,187,169,243,251, 1, 94,182,184,116, 59, 26,151,194, 18, 34, 46,221,122,208,178,119, 43, 87,120,187,219,204,150,231,229,
+175,136,130,233, 9,105,105,193,112, 0,171,171,232,117,232,231,136,177, 29,222,248,172,166,222,134,213,210, 24, 16, 98,120, 2,
+138, 97, 0,138, 46,237, 1,153,116, 21, 18,155,166,100,239,129,163, 37,219,183,239, 90, 26,149, 93,255,206, 25, 44, 15,190,176,
+176, 16,230,230,230, 56, 29,195,233,223,236, 47, 83,208, 52,141,164,152, 59,127, 54,134,183,163,253,101,189,191,244,189,186,184,
+195, 25, 75, 57,165,112, 29,252,133, 31, 23,182, 43,185,161, 39, 9, 17,145,255, 6, 10, 10, 10,238, 71, 69, 69,245,111,221,186,
+245,142,247,222,123,207,114,252,248,241,174, 83,167, 78,165, 1, 32, 35, 35, 67, 88,187,118,109,234,247,223,127, 95,144,157,157,
+253, 22,203,178,245, 25,202,132,164,165,165, 93,251,225,135, 31,178, 46, 95,190,220,178, 99,199,142,138, 87, 94,121, 69,176,181,
+181,149, 40, 20, 10,222, 96, 48,232, 98, 98, 98,248,184,184, 56,151,252,252,252, 71, 0, 98,209,128, 59, 86,148,165, 87, 75, 24,
+134, 89, 72, 8, 9,120, 17,109,180, 84, 42,149, 43,128, 71, 20, 69, 53, 55,181,218,240,153, 19,182, 68,130,188,188, 60,148,164,
+ 71, 64,153,252, 16,173,205,105,248,219, 90,192,202,202,234,185, 76, 81, 65, 65, 1,160, 73,193,149, 43,247, 0,142,131,181,181,
+ 53,172,173,173,255,118,163, 85,147, 23,249,151, 48,173,154,215,106,111,163,229,175,198,219,102, 6,172,157, 62,184,153,172,177,
+167, 59,244,201,183,112, 47,169, 24, 11, 58,117,140,100, 20,150,186,233, 19,134,182, 31, 49,178, 17,122,117,233, 64, 53,118,177,
+158,189, 98,245,166,119,252,145,253, 97,100, 38,214,213,103,137, 34,179,240, 88, 64,230,246,243,247,147,103,184,171,180, 16, 4,
+130,243, 97,105, 8,139,207,219, 30,157,133,199,166,172,157,191, 11,250, 74, 64,239, 39,132, 40,173,205,205,139,252,189,221, 29,
+250,118,110, 67, 15,232,217, 30, 50, 6,184,242,199, 61,204, 89,125,228,134, 32,144,193,119,234, 89,109, 88,218,195,176,170,129,
+ 42,237, 97,200, 86,233, 97, 72, 8, 33,165,189, 14,107, 15, 31, 24,134, 74, 47, 73,184,233, 44,181,111, 1,109,236,121,196,231,
+ 9, 72,200, 44, 66,161,196, 25,250,148, 20,128, 8,137, 23,107,111, 88, 93, 43, 14, 14, 14,142, 77,252,189,155,173,223,121, 8,
+198,146, 2, 60,190,176, 3,197,121,105,248,114,243,241,102,110,110,246, 61, 83, 82, 82, 46,154,112,176,241,254, 45,120,175, 35,
+ 8,192, 72, 21, 56,185,241, 0,178,237,205,224,160,146, 65,208,102, 97,250,251,227,173, 7,246, 27,111, 13, 0, 9, 15,238,194,
+ 75,165,173,151,174,209, 30, 35,222,232,237, 99, 3, 86,139,157,167,239,234,104, 96,192,174,179, 17,177,189,125,109,148,111,116,
+243,178, 93,146,154,255, 58,114, 26, 54,168,104,121,162, 85,145,240, 53,160,183,225, 33,128,247, 21, 16,187,255, 90,166,249,200,
+126,175,168,100, 18,138, 34,197, 41, 32,102, 14,216,180,243, 96,177,156, 53,237, 78,236, 2,176, 36,112,249,227,133,165,251, 9,
+118, 12, 92,126,235, 63,231, 62,239,164, 78, 79, 79,135,177,172,238,240,113,174,240,251,132,126,254,124,114,129, 96, 56,187, 98,
+248, 72,202, 76, 45,255,232,155, 93, 23, 8, 32,142, 38, 45,242,175, 70,171,213,222,214,106,181,173, 62,250,232,163,177,243,231,
+207,239, 97,110,110,222, 4, 0, 52, 26,205, 99,150,101, 47,149,253, 63, 77,233, 29, 72, 0, 60,138,141,141,125, 28, 27, 27,235,
+180,103,207, 30, 27, 0,202,178,247,116, 0,242, 1,100,224, 57,122, 28,150,155, 42,138,162, 22,190,168,237, 80,110,170, 40,138,
+106,222,144,239,211, 52,205, 83, 20, 5,138,162,160, 80, 40,112,249,242,101,140, 26,220, 15, 81, 39,243, 17, 96, 99,129,142,111,
+ 77,199,254,115,231,192, 48, 12, 40,138, 2,195, 48, 38,157, 71, 36, 18, 9,174, 92,185,130, 55,199,140,132, 66, 2, 88, 91, 91,
+227,163,143, 62,194,177, 99,199, 32,145,136,119,233, 51,129,173,149, 12, 87, 61,199,209,162,176,228,220,142,101, 50,240, 44, 78,
+236,248, 22,193,225,197,134, 7, 89, 88,224,147,133,181,135, 80, 36,100,173,222, 53,227,220,149,240,111, 38,143, 14, 82,245,233,
+221, 15,125,122,245,150,180,236,208,243,115,160,138,209,234,139, 90,198,218,224, 5, 44,221,122, 58,122,250,254, 11, 49, 20,140,
+ 69, 24,253, 90, 7,194, 11, 88, 90,199,202, 60,163,105,109,102,177,255,202,245,235,182, 48, 22, 35,254,238,239,202, 70, 77,154,
+ 1,188, 17,143, 30, 61,196,247, 59,127, 17, 46,252,241, 96,183,129,195,123,113,121,208,212, 87,179,244, 76,201,193,218, 92,238,
+ 51,160,165,213,175, 2, 8,108, 84, 50, 95, 34,240,176, 81, 73,125,251,249,170,126, 37,132, 16, 75, 51,169, 47,225,217, 58, 53,
+181, 6,110,203,206, 31,183,175,154, 50,101,138,121,118,114, 58, 82, 11,195, 81, 44,119, 3,171,242, 64,236,221, 75,218, 18, 61,
+ 87,159,147,120,141,219, 51, 59, 59, 59,243,118,104, 46,246,111, 94, 14,214,160, 71,102,114,169, 87, 77,205, 46,132,149,131,219,
+245,148,148,148,122,107, 26, 57,161, 96,196,248,105, 50, 51, 75,152,189, 57, 34, 72, 30,155,163, 71, 59, 87,203,210,131, 70,113,
+ 22,162, 66,174,160, 87, 89, 27,211,184, 36, 26, 94,109, 92,235,181,156,150, 74,217,123, 3, 95,113,195,227,196, 52, 92,142, 72,
+217,249, 56, 23,169,124,116,218,206,216,212,252, 25, 67, 59,121, 98,205,177,200,119, 1,118,175, 41,235,238,231,136,177,132,160,
+ 91,105, 99,120, 45, 8,208,205,207, 17, 99,235,217,211,240, 25, 77,137, 12,227, 86,253,154,240,217,193,155,217, 67,231,141,235,
+110,213,165,203, 32, 57, 56, 3,138,180,122, 54, 42, 31,133,166,104, 22,106,133, 45, 0,182,148,191,113, 59, 89,216,221,125,209,
+245, 75,123,167,122,168,203,189,250,165, 88,253,117, 0,215, 39, 7,154,125, 46,235,253,165,207,245, 37,129,103,194,210,132, 61,
+151, 98, 43,198,208,170,243,127,212, 64, 68, 77, 81,243,239,208,228, 1,236,102, 89,118,119,126,126,254,139,212, 76,197,179,227,
+ 58, 61,215,186, 87,174, 38, 36,132, 72,202,210,172,186, 26,195,215,170, 89,185,154,144, 16,114,170, 44,205,170, 43,213,170,162,
+ 41, 8, 66,106,251,246,237,237,134, 12, 25, 2,158,231,241,240,225, 67, 36, 36, 37,161,239,140,119, 97, 99, 99,131, 75,247,239,
+227,193,131, 7, 88,184,112, 33, 88,150,197,209,163, 71,147,235,210,148, 72, 36,198,102,205,154,201,134, 13, 27, 6,142,227, 16,
+ 23, 23,135,148,148, 20,204,153, 51, 7,214,214,214,184,125,251,118,133,102,118,118, 54, 36, 18,137,177,154,116,235,175,216,151,
+254,237, 60, 99,178,106, 55, 90, 0, 15,158, 69,193,185, 69, 88,119, 25, 70, 35, 11,223,200, 44, 60,137,252, 51,145,218,196,132,
+222, 63,113, 63, 60,250,241,237,171,125,228,200, 12,131,169, 87, 18, 15,115,144,102,169, 44, 42,130,177,200, 10,113,191,226, 73,
+ 70, 81,241,195, 28,164,153,124,197, 32,240, 20,140, 37, 64,218, 45, 92,187,116, 17, 23,110,220,195,205,176,104,254,218,237,152,
+253,180,128,165, 81, 57,120,216,128,171, 16, 88, 12, 94,131, 73, 97,143, 60, 59,120, 59,121,130,231, 64, 4, 22,214,163,247,226,
+173,200, 46,158, 29,154,218,120,150, 38, 89, 44,108,255,243, 59,176, 74, 89,171,222,173, 36,118,171,252,216,153,215,139,242,115,
+ 58,189,218,179,179,185,181,223, 64,100, 63,138,193,195,123, 87,180,183,195, 99,175,221, 74, 98,183, 62, 79,233,186,185,185,245,
+120,181,167, 15, 70, 79,255, 20,198,146, 2,196, 93,248, 17,197,185,233,184,124,221, 2,209,133,133,157, 1,212, 59,209,186,158,
+200,181, 68, 98, 30,186, 54,146, 38, 90, 66,239, 60, 33,104, 8, 20,148, 14,130,190, 16, 84, 73, 54, 98, 83, 12, 5,175,111, 78,
+226, 1, 64,165,160, 36,230,164,192,170, 94,201,163,151,125, 11, 21,195, 98,215,185, 8, 8, 66,233,237,155, 4, 1,155,118,253,
+ 30, 59, 99,233,155,237,224,239,105,219,230,110, 74, 38, 5, 19, 34,127,138,160,251,205,253, 95,248,234,126,251, 28, 16,140,184,
+ 50,219,206,183,251,186,220,238,104,224,237,118,194, 83,145, 2, 96, 6, 36, 37, 91,102,175, 59,253,121,251,115,145,221,230,254,
+103,168, 21,200, 11,233,161, 27, 19,153,206,247, 8, 92,145,112, 70, 32, 85,235,115, 75,147, 45, 63,146, 90, 72,238, 94,138,213,
+139,163,194,139,136,136, 0, 0,138,139,139,167,191,245,214, 91, 91,164, 82,169, 26, 0, 37, 8, 2, 4, 65,144,124,243,205, 55,
+ 82,158,231,105,154,166,121,134, 97,184, 83,167, 78,177, 60,207,103,233,116,186,233,117,105,114, 28, 23, 59,115,230,204,102,117,
+245, 80,220,183,111, 95,185,201,138, 21, 75,162, 94, 38,171,242,188, 34,229,146,212, 18,210,126,209,245,205, 69,139, 0, 80, 32,
+ 88, 28,153,133, 39, 79,127, 36, 44, 23,169,254,140,113, 78,203, 14, 61, 23,149,127,199,212, 37,211,241,252,200, 14,173,188,247,
+ 1,128,158,240,111, 54,100,237, 10,245,218, 55,218,118,232,188, 95, 32, 68,194, 17,178,157, 22,112, 88,199, 33,170, 62, 61,237,
+106, 34, 53, 51,255,246,192, 0,107, 2,148, 86, 25, 86, 84, 23,150, 13,227, 64, 8, 33, 21,213,133,223, 42,145, 93,160,175,115,
+ 28,168,171, 79, 12,253, 12,220,205,105,103,175,222,157,206,243,196,153, 97,168,116,173,129,219,242,188, 38, 11, 0, 82, 82, 82,
+ 46,134,156, 75, 57,123,191,141,211,107, 14,170,178,148,171, 4,200, 46,193,217,148,172,226,139, 13,209,204,211,176, 67,113, 22,
+ 77, 53, 0, 0, 32, 0, 73, 68, 65, 84,231,175, 61,118, 92, 46,101, 36, 32,164,116, 64, 81, 66,160, 51,242,185,215, 19,185,150,
+ 0,208,202, 14,174, 31, 29,229,246, 49, 12,149, 80,151, 94,232,131,180, 53,163, 87,132,124, 24, 17,159,183, 61, 62, 31,225, 0,
+ 16,159,143,240, 3, 87,158,124, 30,155, 94,244, 97,120, 66,222,183, 48,177, 93, 5,161,112,185,195,232, 69,207,188,246,188,219,
+ 51, 58, 13,247, 0, 12, 7,146,251,141,158,251,253, 92,138,194,139,186,253, 68,140,214, 72,188,158,126,177, 60,217, 18,143, 85,
+ 34, 34,255, 29,148,167, 90, 52, 77, 47,121,129,154,167, 40,138, 26, 4,224,145, 9, 95, 11, 45, 46, 46,110,245,130, 87, 47,135,
+227,184,156,250,124,240, 31,104, 16,255,111,101,235, 63,245,195,125, 69,205,191, 95,179,121,243,230,196, 4,195, 34,110, 79, 81,
+ 83,212, 20, 53,255,167, 52, 9, 33,204,243, 76, 53,104, 82,207, 51,137,101,244,175,103, 90, 77,207,197,150,110, 47, 33,143, 30,
+ 61,162,196,173, 32, 34, 34, 34, 82, 61, 20, 69,241,127,129,166, 56, 58,158, 72,185,193,170,146,110,209,226, 54, 17, 17, 17, 17,
+ 17, 17, 17, 17,121, 33, 38,171,242,188,212,132,163,230,248,207,148,222, 4, 13,137, 16, 67, 68, 77, 81, 83,212, 20, 53, 69, 77,
+ 81, 83,212,252,159,211,172, 75, 91,236,205,248, 23, 27, 48, 81, 83,212, 20, 53, 69, 77, 81, 83,212, 20, 53,255,247, 52,255,205,
+212,216, 70, 75,172, 58, 20, 17, 17, 17, 17, 17, 17, 17,249,139, 16, 27,195,139,136,136,136,136,136,136,136, 60, 31,117,222, 84,
+ 90, 68, 68, 68, 68, 68, 68, 68, 68,164, 97,212,126, 83,105, 17, 17, 17, 17, 17, 17, 17, 17,145, 6, 99,250, 77,165, 69, 68, 68,
+ 68, 68, 68, 68, 68, 68,234,197, 86,113, 19,136,136,136,136,136,136,136,136,252, 61, 84,237,117, 24, 28, 28, 76, 42,207, 69, 68,
+ 68, 68, 68, 68, 68, 68,254, 78, 94, 86, 47, 34, 86, 29,138,136,136,136,136,136,136,136, 60, 31,211, 68,163, 37, 34, 34, 34, 34,
+ 34, 34, 34,242,215, 80, 99, 27,173,242, 1, 75,123,149, 69,117,189,196,109, 37, 34, 34, 34, 34, 34, 34,242, 15,240,114,123, 17,
+177,125,150,136,136,136,136,136,136,136,232, 69, 68, 68, 68, 68, 68, 68, 68, 68, 68,254,155, 16,239,117, 40, 34, 34, 34, 34, 34,
+ 34, 34,242, 55, 27,174,191,220,104,137,119, 54, 23, 53, 69, 77, 81, 83,212, 20, 53, 69, 77, 81,243,127,201,100, 85, 49, 91, 98,
+175, 67, 17, 17, 17, 17, 17, 17, 17,145,231,163,206, 94,135, 34, 34, 34, 34, 34, 34, 34, 34, 34, 13, 99, 26,128,160,178,199, 65,
+168,148,106,137,137,150,136,136,136,136,136,136,136,200,243,177, 21,128, 75,153,193, 58, 9, 32, 77, 52, 90, 34, 34, 34, 34, 34,
+ 34, 34, 34, 47,134,202,237,178, 6, 87, 50, 95,162,209, 18, 17, 17, 17, 17, 17, 17, 17,121, 78,106,108,163, 69,161,230,158, 3,
+ 33, 38,252, 64, 67,122, 31,132,136,154,162,166,168, 41,106,138,154,162,166,168,249, 63,167, 89,151,118, 8,254,125, 76, 51,197,
+124,189, 72,196,174,175,162,166,168, 41,106,138,154,162,166,168, 41,106,254,207,242,194,123, 29,182, 3,204,196,205,250, 82,226,
+ 84, 54,137,136,136,136,136,136,136,212,206, 95,211,235,208, 15,248,207,248, 0,245,102, 54, 60,203, 42, 28, 40,169,237,179,106,
+181,122,139, 74,165, 26, 95, 82, 82,162,161, 40, 74, 40,127,157, 16, 2, 0,149,239,117, 20,151,149,149,213,189,174,223,150,203,
+229,107,157,156,156,254, 83, 92, 92, 92, 66, 81, 20,161, 40, 10, 20, 69, 1,192, 51,115,158,231,147,115,114,114,218,255,171,139,
+144, 16,198,193,201,233, 15, 41,195,184,153,250, 85, 94, 16,158,100,102,100,116, 54,225, 43,203, 41, 10,243, 74,127, 22, 95, 3,
+248,244,101,251, 71, 16,128,169,207,231, 2, 0,203, 24, 96, 52, 79,211,239, 74,129, 13,122, 65,216, 12, 0, 20,192, 55,244,183,
+245,161,104, 70, 17,180,161, 40, 88, 19,130, 2, 66,225,158, 34, 16,177,255,208,166, 24, 33,149, 74,135, 90, 89, 89, 89,228,228,
+228, 92, 4,176, 15,192, 24,123,123,251,158,133,133,133,197, 44,203, 30, 3,112,164, 33,194,221,219,224, 99,185, 76, 58, 89,103,
+100, 87, 94,189,135, 31,123,182,131, 61, 39, 96,133, 82, 38,233,174, 55,112, 95, 95,185,143,237, 38, 74, 82,101, 83,249, 49,195,
+228,123,164, 29,172,103,185, 3,192, 81, 91, 91,111,133,218,234, 55,169,156,121,146,159, 81, 60,126,100,102,102,210,168,231, 40,
+247,255, 70, 28, 28, 28, 38,209, 52,253, 21, 33, 4, 60,207, 47,200,205,205,221,241,130,164, 23, 0,176, 41,123,156, 15,224,171,
+231,212, 75, 0,224, 89,246, 56, 17,128,151,120, 94,111, 48,155,126,249,229,151, 25,189,123,247,198,154, 53,107,176,105,211,166,
+248,172,172,172, 21, 0,118, 2, 48,252, 3, 58, 34, 53,225, 15, 12,250,166,127, 32,207,254,180, 84,168,244,114,223, 26,254,204,
+ 63, 76,152, 48,193, 72, 8, 33, 15, 30, 60, 32, 6,131,129,176, 44, 75, 56,142, 35, 28,199, 17,150,101, 43, 38, 55, 55,183,148,
+167,190,254,140, 38, 77,211,235, 94,127,253,245, 34, 66, 8,185,117,235, 22,209,106,181, 68,175,215, 19,131,193, 64,116, 58, 29,
+209,106,181, 85, 38, 39, 39,167,140,218, 52,173,172,172,110,217,218,218,102,216,218,218,102,216,217,217,101,216,217,217,101,216,
+219,219, 87, 76, 14, 14, 14, 21,147, 90,173,206, 80,171,213, 25,118,118,118,183,234, 90,206, 50,250, 3,184, 88,143,169,127, 53,
+223,237, 91,217,104,185,184,184,100,144, 6,224,238,238,158, 84,143,229, 44,199,137,162,192,151,127,151,162, 32, 40, 20, 10,207,
+202,239,227,217,164,171,206, 72,217,213,213,245,117, 23, 23,151, 16, 23, 23,151,115,174,174,174,175,215, 99, 23,171,162,105,105,
+105,121,203,193,193, 33,195,217,217, 57,179,124,114,113,113,169, 50,185,186,186, 86, 76, 78, 78, 78, 25,182,182,182, 53,150, 17,
+ 1,152,154,166, 11,128, 68, 1,244,145, 48, 76,176,147,147, 83, 97, 88, 88, 24, 79, 8, 33, 52, 77,167,148,127,198,148,117,127,
+218,100,149, 92,193,130,236,243,138,208,226, 39, 43, 10,178,207, 43, 66, 75,174, 96,129, 62, 20,205, 26,170, 89, 79,170,211,156,
+ 56,113,226,196,123, 25, 25, 25, 41,249,249,249,105,155, 55,111,142, 81, 42,149, 87, 54,111,222, 28,147,159,159,159,150,145,145,
+145, 50,113,226,196,123, 0,102,154,160, 9, 0,232,220, 6,157,166,140,112, 41,185,119,244,205,146, 62, 29, 36,119,187, 6, 32,
+168, 95,103, 89,202,250, 79,252, 74, 46,109,235, 86,210,251, 21, 58,220, 68, 77, 74, 34,145,116,241,244,244,156,172, 86,171, 39,
+148, 77,111,150, 79,206,206,206,111, 58, 59, 59,191,105,107,107, 59,170, 54,205,131, 0, 83,159,201, 67,169,236, 50,170,137,103,
+ 73,194,146,197, 36,236,253,119,201,228,166, 30,133, 35, 29, 29, 27,253, 3,101,244,151,106, 58, 58, 58,166,178, 44, 75,140, 70,
+ 35,177,183,183, 79,125,129,203,249, 45, 33,228, 91, 66,200,183, 0,190,125, 1,154, 21,199, 51, 19, 12,118,109,154, 74, 9, 77,
+207, 85,201,229,231, 20, 18, 73,166, 66, 34,201, 84,201,229,231, 36, 52,253, 33, 0,229,127, 83, 25,253, 5,154, 22,106,181,250,
+241,218,181,107, 73, 73, 73, 9, 41, 41, 41, 33,107,215,174, 37,106,181,250, 49, 0, 11, 19, 52, 27,170,243, 50, 37, 88, 79, 79,
+ 47, 46,209,242, 3,218,247,105,211,252,240,236, 73,163, 33, 28, 90, 75,213,113,197,244, 67,231,246,237, 39,239,220,185, 19, 0,
+ 48,126,232, 80,188,214,177, 35, 44, 45,204, 33,151,151, 46, 14, 69, 40,200,164, 50, 12,155,243, 65,125,126,254,235, 97,195,134,
+141, 59,116,232,144, 5, 0,108,218,180, 9, 35, 70,140,128,157,157, 29, 84, 42, 21,100, 50, 25,164, 82,105,149,121, 93, 48, 12,
+227,158,146,146,226,168, 84, 42, 43, 82, 54, 65, 16,170, 76,132,144,242,244, 13, 28,199,161, 69,139, 22,245,221, 92,159, 20, 20,
+ 20,244,208,104, 52, 21, 26,213, 77, 77,154, 52, 1,128, 51,245, 17,252,234,203,165, 16, 56, 13, 36, 18,128,227, 0,189,145,134,
+ 64,170, 53, 55,152, 57,115,102,197,114, 55,132,193,131,131, 40,138,162, 14,221,190,125,251,112,102,102,102, 99, 65,224,167, 54,
+ 48,233,122,231,225,195,135, 22, 0,224,237,237, 61, 19,192, 97, 83,150, 67, 34,145,184,223,191,127,223, 81,161, 80,212,152, 92,
+ 86, 74, 48, 97, 52, 26,209,174, 93, 59,206,148,223,112, 2, 60,115,105,122,106,219, 87, 94,153,182,104,216, 48,229, 31,127,252,
+161,164,105, 26, 28,199,225,155,111,190,225, 8, 33, 54,254,128, 85, 36, 80, 88,139,204,124, 0,147,202, 78, 6,219, 1,124, 83,
+197, 45, 16,180,209,178,138,160,184,226, 97, 29, 3, 27,125,140,200,136,176,142, 77, 45,142,194, 82,162,143, 5,254,222, 84,203,
+202,202,106,232,154, 53,107,212,219,183,111, 47,124,240,224,129,113,243,230,205,234,233,211,167, 91, 26,141, 70,204,152, 49, 35,
+203,199,199, 71,182,102,205, 26,245,145, 35, 71,250,104, 52,154,141, 38,149, 23,133,165, 99,134,190, 6, 29, 75,131,101, 57,181,
+139,218,114,247,236,137,189,164,132, 24,176,235,216,109,176,156,240,163,137, 73, 86,231,145, 35, 71, 54,221,187,119,175, 36, 58,
+ 58, 90,226,235,235, 11, 65, 16,192,243, 60, 88,150, 5, 0, 8,130,128,230,205,155, 63,247,118,153, 12,120, 59, 56,217,157,235,
+ 60,104,160,153,139, 82, 1,187,188, 44, 76,145, 73, 44,119,168,244,123, 0,116,121,169,146, 93, 66, 32,145, 72,144,148,148, 4,
+ 71, 71, 71, 51, 65, 16,210, 0, 44,206,203,203,219,138,151,151,142,114,137,228,240,174, 31,215, 57, 7,118,233,194, 56,185, 56,
+ 34,230, 97, 34, 36, 20,223,247,254,205,219,189, 38,191, 61,119,182,129,227, 94, 7,240,199,203,182,226,206, 93,102, 14,167,104,
+102, 19, 69, 4,124,177,254,120,209,242,175,215,170,102, 76,157,200,204,153, 51, 7, 30, 30, 30,141,135, 15, 31,254, 53,128,183,
+235,212, 9,156, 57, 28, 12,189, 9,132, 96,209,247,199,139,150,125,189, 86,245,118, 3,116,254,229,212,248, 31,121,110,163,229,
+ 7, 52,109,233,225,120,118,249,188,183,165,228,215,159,232,146,156,204, 26, 63,171, 86,171,183, 12, 24, 48, 96,252,142, 29,127,
+166,209,157, 3, 2, 48,188, 79, 55, 56,218, 91, 67,101, 46, 47, 61, 29, 9, 20,238, 61,120, 82, 47, 67,224,225,225, 49,227,240,
+225,195, 22,149,205,132, 76, 38,171,152, 42,155,172,242,169,252, 4, 92, 27, 74,165, 18, 33, 33, 33,144, 72, 36, 96, 24, 6, 18,
+137,164, 98,170,252,156, 97, 24, 56, 57,153,212,116,105,133,181,181,117,235,162,162, 34,171,252,252,124,120,122,122, 22, 2,184,
+ 95,233,253,214, 89, 89, 89, 86,166, 8, 10,156, 6,115,166,248, 65,106,184, 1,131,180, 35,180,146,174,184,118, 51, 10,193,103,
+ 46, 34, 37, 53, 29,221, 58,181,197,132,177, 35,113,238,220, 57,240,188,201, 53, 29, 25,132,224,235, 33, 67,130, 62, 6, 40,170,
+111,223,190,249,179,102,205,162,163,163,163,199, 13, 31, 62, 44,224,225,195, 71,101,169, 34, 53,143, 16,172, 3,144, 81, 79, 93,
+ 57, 0, 92,186,116, 9, 0, 20, 13,217,247, 20, 10, 5,174, 95,191,142,242,106, 98,154,166, 65,211, 52, 24,134,193,137, 71, 14,
+208, 24,104,148,100,132,227,221, 32, 79, 52,105,210, 4, 52, 93,119,147,196, 94,128,242, 26, 48,156,146, 74,231,184,184,186, 54,
+238,217,180,169, 42, 36, 36,132, 1, 0, 47, 47, 47,146,150,150,150,127,236,216,177, 34, 9,176,201,139,144,157,181,153, 44, 15,
+ 15,143,174, 41, 41, 41, 95,149,111,115,138,162,190,110,212,168,209,194,138,114, 19, 4, 44,254, 81, 35,157, 61,251,125, 89, 96,
+175,207, 0, 0,129, 67,246,162, 48,110,185, 31,149, 59,223,250,239, 62, 74, 20, 22, 22,238,111,222,188, 57,147,147,147,115, 13,
+ 64, 2,203,178,159,236,222,189,219,113,202,148, 41,153,123,246,236, 89, 1,192,117,229,202,149,189, 52, 26,205, 1, 83,116,187,
+181,198,160, 87, 90, 7,116,242,244,240,192,197,107,127, 64, 38,151,218,204,156, 20, 4, 11, 11, 9,190,221,126, 82, 72, 72,206,
+157,117,229, 62,118,154, 96,178, 58,142, 28, 57,178,241,222,189,123,229, 0,112,255,254,125,164,167,167, 67,173, 86,195,204,204,
+ 12, 82,169, 20, 12,195, 64, 42,149,190, 16,147,101,237, 97, 31,122,244,232, 49, 51, 59, 59, 27,172,255, 96, 54, 38,100,102,192,
+198,210, 2,108,177,166,241, 75,118,162,240,238,222,189,187,146,231,121,104, 52, 26, 92,184,112,193,218,204,204,204,218,221,221,
+125, 17, 76,232, 61,165, 84, 42, 51,116, 58,157, 99,217,227, 76,157, 78,231, 4,160, 80,161, 80,148, 31,167,139,203,230,245,173,
+ 78, 76,192,179,213,132,137, 20, 69, 85,126,173,161,116,232,216,161,117,200,145, 67, 63, 91, 20, 20,165,195,198, 54, 19, 52, 10,
+176,117,235, 6,152,153, 89, 97,209,162,249,146, 39,125,251,184,245, 31,244,122, 72, 68, 84, 76,223,151,206,108, 17,106,107,223,
+ 33,227,237,204, 84,150,101,231, 18, 22, 59,182,205, 6, 77,211, 88,184,112, 33, 90,182,108, 57, 45, 34, 34,226, 51, 0,185,181,
+203, 96,107,171, 30,111,216,201,149,165, 69, 44,240, 44, 54,239,251,176, 84,231,211,233, 24, 51,164,201,180,143, 70, 62, 62,221,
+178, 41,138,202, 46,204,181, 82, 26,137, 84, 32, 42, 12, 67,112,112,112,207,160,160,160,139, 53, 61,255, 23,224,130, 63,199,207,
+170, 98,190, 36,193,193,193, 36, 40, 40,136,170,180,114, 85,158,215, 70, 27,192,193,214, 90, 21,178,105,241,108, 11,201,141,147,
+140, 54,241, 17, 82,117, 85, 78,228, 85,186,104,170, 84,170,241, 59,118,236,168, 18, 41,121, 58, 57, 66, 38,147, 66, 42,163, 96,
+211,189,116,244,250,252,203,193,160,168, 26, 77, 86, 21, 77,141, 70,163,187,123,247,174,197,246,237,219,225,232,232,136,198,141,
+ 27, 67,165, 82, 65,169, 84, 86, 49, 87,149, 13, 87, 53, 70,171,138,102,249,251, 18,137, 4, 52, 77,227,220,185,115,224, 56, 14,
+ 35, 71,142,124,198,100, 73, 36,146,154,140, 91, 77,221, 83,207, 0,184, 79, 8,233, 81,118, 2,190, 15,160,103,165,247,251,171,
+213,234, 79, 0,172,168,175, 38,195, 16, 48,186,107, 16,220,215, 66,146, 52, 27, 6,105, 27,156,191,114, 27, 59,182,172, 1, 0,
+ 52,246,237,128, 81,195,131, 42,210,184,122, 46,103, 5,110,110,110,251,178,178,178, 7,246,233,211, 7,121,121,121,236,226,197,
+139,209,186,117,107,120,123,123,215,171,140,106,184,114,206,184,127,255,190,135, 86,171, 5, 33,164, 62,230,236, 25, 77,138,162,
+176,123,247,110,232,116,186,103, 62,108,219,115, 25, 62, 28,225,133,183,222,221,137,175, 31, 28,192,198,141, 27,107, 93,119, 21,
+208, 90,103,221,124,157,156,225, 90,175,152,255,142, 98,194,132, 9,204, 91,111,189,133,196,196, 68, 76,153, 50, 69,119,238,220,
+ 57, 67,122, 90,218, 49,185, 32,172, 55, 86, 53,198, 53,106, 42, 20,138, 93,103,206,156,193,129, 3,165,190, 36, 38, 38, 6, 45,
+ 90,180, 48,175, 98,146,115, 15,162, 40, 97, 61, 66, 79, 68, 35,112,200, 94,132,158, 24, 11, 62,255,164,180,125, 11, 20,152,178,
+ 61, 27, 64,117,154, 7,114,114,114, 42, 76,212,158, 61,123,204,246,236,217, 51, 12,192,113, 0, 7, 0, 32, 55, 55,119,181,137,
+154, 0,133,183,222, 24, 49, 12, 18,153, 37,162, 31, 37,163,103,231,118,112,114,116,196,253,168, 88, 36,164,228,102, 80, 20, 38,
+245,239, 34, 95,161,213, 26, 62,187,124, 15, 63,212,161, 73,185,187,187,123, 31, 60,120, 80, 86, 41,129,174,248,143, 51, 12, 83,
+241,188,220,120, 55,100,255, 44, 55, 89,150,238, 22,161, 75, 55,116, 53, 15, 13,219,131, 22, 94,131, 96, 59, 40, 8, 63,156, 61,
+139,135, 17,145, 58, 67, 9,247,234, 63, 80, 70,127,149,166,247,136, 17, 35,174,253,252,243,207, 54, 73, 73, 73,184,116,233, 18,
+ 26, 55,110,140,146,146,146,250, 92,240, 86,209,212,233,116,142,229,223,161, 40,202,177, 60,120, 55, 24, 12,229,133, 81,254, 71,
+180,169,244, 57,155, 90, 52, 61, 43,125,174,220, 92,121,189,128,117,151, 43,101,178,131, 71,143,236,179,136,140,190,132,182,109,
+ 58,193,194,218, 31, 2,159,142,156,220, 98,228, 61, 74,197,151, 95,126,141, 69,139, 23,224,248, 47,135, 44,124,252,218, 28, 54,
+112, 92,115, 0,186,151,166,220, 41, 50, 45,228,196,158, 77, 20, 17,160,205,136, 86, 72, 53,143, 85,227,199,190,206,140, 30, 61,
+ 26,199,143, 31, 71, 68, 68,196,166, 90, 76, 86, 72,165,100,126, 90,248,165, 3,155, 64, 8,180,153,209, 10,153,246,177,106,226,
+184, 81,204,132, 49,175,225,198,239,235,240, 90,219,199,225,174,142, 24,158, 87,102,177, 37, 12,114, 20, 74, 92, 37,161,184, 81,
+201,108, 93, 0, 64, 85, 50, 88, 23,240,103, 27,204,127, 3,131,203,140,213,180,167, 47, 76, 36, 13, 49, 88, 0,208, 2,176,160,
+228,178,208, 29,139,222,113, 85, 37, 70, 72,244,225,215,145,170, 23,200,230,120, 78,104, 7,152,221, 1,180, 79,127,167,164,164,
+ 68, 19, 27, 27,107, 54,105,248,112,116, 9, 8,128,139,189, 61,154,187,187,195, 76, 33,135, 92, 38,173,114,201, 90,239, 58, 4,
+138, 34, 62, 62, 62, 24, 50,100, 8,164, 82, 41, 84, 42, 21, 44, 44, 44, 32,151,203,171, 77,179,234,123,149, 75, 8, 1,195, 48,
+ 8, 15, 15, 71, 66, 66, 2,108,108,108,112,245,234, 85,188,250,234,171,207,164, 90,149,205,153, 41, 17,125, 53, 39,254,114, 35,
+118,198, 20, 45,158,167, 80, 76,218, 64, 25, 63, 11, 37, 84, 59,232,245, 28,244,122, 61,126,184, 98,196, 31,177, 26, 24,141, 6,
+232,245,250,218,126,179, 38,104, 87, 87,215,241,205,155, 55,159, 57,118,236, 88, 86, 46,151, 67,163,209,160,164,164, 4, 17, 17,
+ 17,236,192,129,131,242,135, 12, 9,178, 62,121,242, 36, 41,171, 58,204, 48, 65, 59,199,205,205,205,163,172,122, 54,167, 33,123,
+ 53, 69, 81, 21, 38,230,105, 38,173,142,132,132, 41, 45,147, 77,155, 54,129,231,121, 16, 66,106, 44, 36, 29, 69,253,182,120,217,
+ 42,235,149,107,127,132,181,157, 19, 46, 94,188,200,159, 62,125,186,136, 2, 98, 30, 70, 68,172,254, 63,224,212, 65,192,104,202,
+242,229,229,229,153, 53,110,220, 24,238,238,238, 16, 4, 1, 44,203, 86,164, 47, 57, 57, 57,208,106,181,176, 51,207, 71, 51,123,
+119,112, 69, 23,144, 22,254, 5, 92, 44,162,177,243,140,129,125,197, 27,247,254, 11, 14, 28, 63,149, 77,207,121,213, 12, 55, 71,
+103, 15,208,132, 69,106,102, 14,134, 13,126, 13,140,204, 2, 79,146,178,209,198,191,169,203,184,255,235,234,194, 80, 28,230,173,
+216, 59, 19, 16,126,168, 75,174,184,184,152,143,142,142,198,253,251,165,126,215,202,202, 10,230,230,230, 85,254,227, 52, 77, 63,
+ 87,162, 85,110,178,150,109,122,213,156,150,106, 80,200,135, 96,251,238,219,104,227, 19,132,205,161, 55,117,124, 70,110,223,111,
+117,186,152,125,255,226, 48,195,217,217,121,186, 32, 8,139, 8, 33,249,221,186,117,115,218,187,119,175,109, 74, 74, 10,110,223,
+190,141,133, 11, 23,102,241, 60,207, 17, 66, 40, 66,200, 23, 47,224,231,132, 74, 6,235, 69, 34, 85, 41,241,174,131, 21, 53, 84,
+ 66, 91, 53,230, 10,139,159,100, 27,200,177, 18, 78,248, 30, 0, 91,235,193,141,166,255,115,104,255, 38, 87, 7,181,128, 94,234,
+ 62, 72,203, 48, 98,217, 7, 19,145,147, 83,132, 31,182, 45, 7, 32,135,145, 99,208,163,215,235,112,116,116,195,180,169,211,156,
+ 55,109,217,252, 14, 39, 8,223,226, 37, 33,253,218,198, 95, 0,132,168,213,234,136,119,166, 77, 83, 55,110,252, 38,148, 74, 37,
+246,237,219,135,189,235,215,243,107,129, 81, 10,224,252, 12,224,151, 90,117, 66,255,212,153, 61, 99,134,218,207,111, 6, 20, 10,
+ 5,126, 63,253, 19,116,233,187,139, 6,119,129,177, 68,135,193,141,134, 16,187,248, 19, 84,174, 84,138, 71, 0, 32, 85, 34, 13,
+192,211,213, 96,255, 54,131, 85,206, 73,252,217, 46,107, 90,149, 68,171,193,199, 78,169, 60,108,219,251, 99,188,156,160,167, 12,
+ 87, 78, 32, 69, 47,240, 43, 31, 26,153, 59, 5,228,195,168,106, 76, 86,217,142, 45,120,122,122,162, 79,251,246, 24,222,189, 59,
+ 36, 18, 9,148,114, 25, 44,149,102, 32,124,105,146, 85, 94,117, 88,203, 57, 17,213,165, 79,246,246,246,144,201,100, 21, 6,203,
+132, 52,171, 90, 77, 65, 16, 32,145, 72,112,255,254,125,116,235,214, 13, 30, 30, 30, 56,112,224, 0,250,247,239,255, 76, 85,162,
+169, 38,171,220,104, 61, 85,141,215, 31, 64,121,146,101,146,209,210, 25, 40,100, 27,218,128,162, 2,192,113, 0, 79, 0,189, 78,
+ 7, 66, 0, 66, 0,214,104,128, 78,167,171,248,205,250, 84,201, 58, 59, 59,123,154,153,153, 45,249,248,227,121,126,109,218,180,
+ 69, 86, 86, 22, 4, 65,128,185,185, 57, 74, 74, 74, 96,101,101,133, 46, 93,186, 60, 89,178,100, 73, 26, 33,152,102,162,201,122,
+110,202,183,249,217,179,103,171, 84, 27,150, 79,154,180,100,188,245,222, 30,200, 37,165, 85, 75,229,109,120,106, 59,238,246,238,
+209, 21,215,238,196,112,255,153,183, 78, 47,205,185,189,194, 89, 16,118, 36, 63,199,122, 17, 66,144,157,157,141,140,140, 12, 12,
+ 29, 54, 12,123,127,254, 25,241,241,241,240,247,247, 71,239,222,189,225,232,232,136,248,248,120,252,113, 89, 15,125, 94, 46,114,
+ 13,183,161,178, 12,196,209,139,177,250,133,155,140,177,255,224, 1, 99, 40,128,137, 86, 86, 86, 77, 74, 74, 74,210, 56,142, 59,
+ 8,224, 32,128, 81, 18,137,100,148, 74,165,114, 41, 44, 44,124,140,210,222, 68,199,234, 18, 51, 83, 42,237, 21, 74, 43, 8,156,
+ 30, 18,137, 4, 30, 30,141, 65,120, 3,242, 10,181,152, 52,122, 8,238,220,143,194,233,243, 55, 56,150, 21,190,171,207,102,101,
+ 24,134,120,123,123, 35, 51, 51, 19, 82,169, 20,102,102,102,176,176,176,192,167,159,126,138,245,235,215, 87,152,172,134, 26,173,
+201,128,183,149,167,197,141,175, 54,148,154,172,244,212, 52,100, 36, 75,161,182,119,194,119,235,215,106,242,226,211, 3,127, 4,
+ 98,254,237, 39, 89, 65, 16,190, 72, 73, 73,113,148, 72, 36,206, 28,199, 33, 41, 41, 9,183,110,221,194,172, 89,179, 50,114,114,
+114,122,161,129,235,168, 84, 42, 51,203,147,172,178,170,195,154,170, 19,243, 43, 37, 89,249,181, 72,214, 84, 77,216,180,177,187,
+229,185,109,107,230,120,118, 8,236, 66,171, 36, 86,121,197,143,210,187, 93,185,116,177,203,172, 53, 63,188,147,144, 87,252, 26,
+128,184,154, 68, 21, 82,233,192, 78, 93,187, 74, 64, 50, 32,145,119,195,215, 43, 71, 35, 43,187, 16,121,185, 69,144,201,204, 97,
+ 96, 25,240, 2,133, 46,221,186,227,167,157,251,209,114,234, 20, 70, 46,149,246,227, 12,134,151,198,104,149,177,252,251,239,191,
+247,244,241,241,193,142, 29, 59,112,126,215, 46, 76, 40, 40,192, 69,154,102, 88,169,212,225, 20,203,110, 69, 29, 70,171,178, 78,
+203,150, 45,241,227,143, 63, 98,247,238,221,137,227, 95,205, 60, 60,103, 60, 28,141, 70, 12,184,253, 0,118,141,134, 0,183, 31,
+192,238, 21, 31, 52,231, 36,120, 68, 81, 85,135,131, 10, 14, 14,238, 89,121,254, 47, 35, 13, 53, 84,177, 75, 0,244, 10, 14, 14,
+ 38,149,231,117, 30, 56,213, 45,102, 44,127,173,137, 87, 64, 51, 79,138, 61,176, 14, 73, 26,206,240,217, 3,163,252, 97, 49,153,
+ 19, 5,172,173,229, 10,130, 48, 12, 3, 75, 51, 51,168,109,108, 74, 99,126,154, 6, 4, 64, 96, 1,138, 47, 53, 0, 68,160, 64,
+120,147, 14, 24,144,203,229,213, 54,124, 55,181,109, 86,101,205,162,162, 34, 60,121,242, 4,211,166, 77,131, 74,165, 42,117,238,
+233,233,240,242,242,130, 68, 34, 65, 74, 74, 10,126,255,253,119, 52,105,210, 4, 10,133,194, 36,183, 85, 41, 93,106,141,210, 94,
+134,173,211,210,210,172, 92, 92, 92, 96,114,162, 37, 16,148,232, 41, 24, 12, 60, 30, 62,124,136,212,212, 84, 60,121,252, 8, 29,
+ 52,133, 32, 96, 64, 8, 49, 41,209,114,115,115, 11,104,218,180,233,230, 21, 43, 86,200,220,221,221, 65, 8,129,173,173, 13, 74,
+ 74, 74,144,157,157, 3,127,127,127,120,120,120, 96,197,138, 21, 0,176,247,239, 54, 89, 79,237, 83, 21, 70,171,178,225,122,239,
+255, 60,145,155,107, 1,134,161, 43,140,115, 29,109,180,100, 0,208,235,181, 17,146,115,167, 79,153,115,192,146,116,134, 89, 34,
+169,187, 28, 89, 94, 16, 84, 53,189,159,148,148, 4,169, 84,138, 67, 7, 15, 34, 55, 35, 3,109,218,180, 65,199,142, 29,241,232,
+209, 35,220,185,115, 7,246,246,246, 80,187,119,198,197,199, 70, 68,166,106, 97,109,109,141,216,100,250,159, 28, 50, 96,106,223,
+190,125, 23,174, 94,189,218,209,217,217, 89,154,149,149,229,179, 97,195,134, 54, 27, 54,108,152,253,206, 59,239, 56,189,243,206,
+ 59,182,106,181, 90,146,158,158,238,253,193, 7, 31,188, 18, 18, 18,210, 4,192,170,218, 4,205,205, 45,237, 24,153, 57, 40, 74,
+ 2, 27,107, 91, 72,228,230, 16, 56, 9,120, 1,176,178, 86,227,218,157, 67,184, 26, 86, 52, 61, 51, 7, 7,235,149,143,149,149,
+187,189,189,253, 51, 73,245,172, 89,179,176,109,219,182,138,106,196,134,154,172,101, 27, 94,181,160,202, 76, 86,122,146, 4,148,
+190, 9, 78,252,114, 61, 63, 47, 62,189,219,203, 96,178,202,143,113,132, 16, 60,126,252, 24, 37, 37, 37,184,124,249, 50,190,248,
+226,139,172,167, 77,150,163,163,227, 84, 43, 43,171,197,197,197,197, 95,167,167,167,175,171,243,194,175,212, 68,149, 63, 46,159,
+ 87, 91,157, 88,207, 69,245,170, 46,201,242,112, 81,158,185,115,121,143,151, 53,185, 71, 33, 97, 26,240,176, 48,194, 50,212,177,
+199,160, 14,131,233,118, 27,151, 54,234, 56,253,211, 51, 73,133, 58,159,154,146, 45,129,231,219,153, 91, 88, 2,200,196,237, 91,
+ 23, 42, 76, 86, 78,110, 1,244, 70, 6,122, 3, 5,157,145, 70,159,190, 3,176,126,243,110,164,100,230,130,231,249, 86, 47,153,
+201,178, 11, 8, 8,152, 49,106,212, 40, 44, 89,178, 4, 33,171, 87, 27,222,166,168, 66, 9, 64, 78,242, 60, 4, 66, 40,186,126,
+141,216,171,232,124,251,237,183,191, 0, 24,179, 98, 22, 58,231, 21, 99,146,235, 16, 98,215,104, 72,233, 7, 71,126, 76, 0,192,
+ 46, 43,164,234, 41, 51, 40, 40,136, 42,175, 89, 51,181,134,237,191, 29, 73, 80, 80,208,197,224,224, 96, 84,158,215,246, 5, 75,
+ 39,159, 65, 31,205,157,185,178, 67,255,238, 84,218,220,126,200, 45,212,113,243, 35,141,242,100,109,237, 38,171, 50, 31,109,216,
+128, 59, 49,165,255, 99,119, 71, 71,204, 27, 55, 14,132, 3,174, 70, 68, 98,127, 72, 8, 70,247,237, 11,115,165,178,222,201,134,
+ 32, 8,213,166, 88,149,211, 44, 83, 83,167,252,252,124, 28, 60,120, 16, 29, 59,118,132, 74,165,130, 68, 34, 65,235,214,173, 17,
+ 21, 21,133,166, 77,155,130,162, 40, 28, 61,122, 20,195,135, 15, 71, 92, 92, 28, 58,119,238,108,145,144,144, 96,178,209,138,140,
+140,180, 34,132,244, 40, 79, 63, 26,138, 94,175, 71,116,116, 52,134, 12, 25, 2, 91, 91, 91,184,185,237, 69,200,153, 61, 80, 5,
+ 76, 0, 69,193, 36,163,197,243,252,228,193,131, 7,203, 40,138,130, 86, 91, 2,165,210, 12,230,230, 22,176,180,180,130,183,183,
+ 15, 82, 83, 83,209,191,127,127, 67,108,108,236,198,180,180,180, 3,166, 46,171,159,159,159,121,124,124,252,132, 70,141, 26,201,
+ 1,192,204,204,204,191,105,211,166, 31,198,197,197, 21,153,154,106,149, 27, 44,138,162,192, 48, 76,133,209,146,208, 52, 92,156,
+ 29, 43,158,151,181, 79,163,106,209, 42, 76,201,209, 43, 0,192,211,211, 19,235,183, 28,167, 7, 15, 30,140,217,179,103,131,101,
+ 89,108,220, 88,218,201,110,236,216,177, 48, 26,141, 56,124,184,180,147,164, 68, 34,169, 53, 54,185,117,235, 22,110,223,190, 13,
+150,101, 81, 80, 80,128, 95,127,253, 21, 23, 47, 93,194,190,163,191, 33,254,241, 35,180,246,241,194,148, 41,147, 33,149, 74,177,
+115,231, 78,116,235,214,237, 31, 61, 32, 72,165,210,241,219,182,109,115,217,177, 99, 71,254,209,163, 71, 53,157, 58,117, 82,172,
+ 93,187,214,113,253,250,245,106,131,193,128,247,223,127, 63,243,198,141, 27,250, 97,195,134,153,111,221,186,213,165, 89,179,102,
+253, 56,142,171,206,104,153, 3, 24, 13,224,205,188, 34,131, 36,191, 72, 11,129, 51,224,113,252, 19, 20, 20, 27, 32,240, 70, 36,
+ 38,167,162, 88,199, 35, 39,183, 8,173,219,189,246,253,133, 11, 23, 22, 24,141,198,249, 0,130,235, 90,206,136,136, 8,220,184,
+113, 3,241,241,241,120,252,248,113, 85,167, 56,117, 42,118,239,222,109,114,162, 85,189,201, 98, 64,233,155, 34,248,104,104,126,
+230,163,180,151,198,100,149, 29,131, 22,185,184,184, 44,114,113,113, 81,158, 61,123,214,186, 81,163, 70,224, 56,206,240,116,146,
+213,171, 87,175,207,182,109,219,230,210,180,105,211, 89, 0,214,253, 55, 44, 59, 77, 99,234,215,155,102, 56, 88,202, 19, 83,241,
+112, 85,217, 88,130, 12, 80, 82, 8, 92,248, 25,146,174,159, 63,153, 53,236, 99,219, 79,118, 44,153, 42, 64,168,177,135,108,108,
+ 92, 18, 54,109, 90,143, 57,239, 79,194, 79, 63,124, 13, 65,144, 64,207, 50,240,108,220, 9,122,163, 0,138,150,160, 77,187,246,
+ 56,127,225, 50,164, 52,112,112,199,166,151,204,103, 33, 55, 60, 60,124,227,209,163, 71,223,157, 61,123, 54, 4, 65,144, 47,222,
+180, 73,155,149,149,181, 28,166,141,127,245,180,206,240, 77,155, 54,197,124,178, 62,235,151, 57,227,193,196,159,160,114,111, 63,
+128,221,200,143, 9, 14,173,164,240,138, 15,114, 85,213,159,226, 47, 61, 53,127, 57,140, 86,185,147,172, 60,175,142,118, 45,154,
+ 44,181,182,179,157, 76, 91,186, 57,204,155,253,182, 36, 46, 93,135,195,141,198, 21,255,190,235, 59,243,116, 78,241,125, 44,116,
+107, 77,249,225,253,191,255, 94,241,248,155,189,123,171,125, 47,109,228,200,122, 95,153,213,148, 98,153,154,100, 1,128, 74,165,
+178,233,215,175, 31, 94,125,245, 85,188,254,250,235, 21,109,178,218,182,109,139,125,251,246, 97,196,136, 17,184,123,247, 46, 92,
+ 92, 92,224,235,235, 11, 95, 95, 95,156, 58,117,202,212,131, 28,120,158, 71, 64, 64, 64,121,175,195,214,201,201,201, 86, 13, 45,
+ 72,189, 94,143,156,156, 28,216,217,217, 65, 46,151, 35, 48,176, 35,222,125, 47, 16, 14, 46, 63, 34,192,207, 7, 26,141,166,162,
+251,123, 61, 78,182, 1,205,155, 55, 71, 86, 86, 22,178,178,178,160, 86,171,225,234,234, 10,103,103,103,172, 90,181,138,172, 91,
+183,238,180,209,104,220,152,157,157,109,114,146,229,236,236,220,157,162,168,207,180, 90,173,188,210, 21,174, 92,173, 86, 31,211,
+106,181,203,211,210,210,234,221, 16,148,162, 40, 24,141, 70, 80, 20,133,147,143, 93,161, 49, 80, 40, 76,190,141,217,255,231, 85,
+197,120, 73,165,210, 58,171, 75, 9, 33,154, 49, 99,198, 56,122,120,184, 35, 41, 54, 2,135, 14, 17,172, 94,189,186,188, 87, 36,
+ 98,202, 46, 12,202,159,247,238,221, 27,141, 27, 55, 6, 49, 97,172, 12, 65, 16,112,255,254,125,236, 61,118, 17, 46, 94,126, 72,
+124, 24,141, 59,167, 78,160,145,218, 14, 45,219,181, 7,203,178,207, 53,244,198,139,128,101,217,237, 45, 90,180, 32, 6,131,225,
+ 34,128,245, 97, 97, 97,147,210,210,210,222, 63,126,252,184,235,168, 81,163, 82, 79,156, 56,177, 22,192,142,176,176,176, 25, 95,
+126,249,229,171, 28,199, 85,219, 91,144, 97,152,159, 62,248,224,131, 94,163, 70,141,162,100, 52,107, 56,123,102,167,132,227, 88,
+234,163,249,219,249, 11, 87, 46,210, 28,199, 82,175,143,249, 64, 56,245,123, 24, 61,253,189,111,248,182,157, 6, 35, 60, 60,220,
+ 57, 40, 40,232, 75,150,101,107, 53, 90,229, 73, 85, 77, 9, 37,195, 48,152, 52,105, 18,246,237,171,127, 11,170, 41, 64, 83, 43,
+ 47,139, 27,203, 54,244,181,160, 36,197,149, 76, 86, 51, 4, 31, 13,205,207,120,152,250, 82,153, 44, 0,200,201,201,217, 2, 96,
+139, 32, 8, 25,230,230,230, 40, 42, 42,170,110,255, 83,134,133,133, 41,229,114, 57, 94,123,237, 53,187,144,144,144, 24,154,166,
+215,165,166,166,214,232, 56,170,171, 38,172,174, 58, 17,207,209,235,208, 86,141,160,192,238,237, 44, 31, 88, 47,177, 84, 74,116,
+119, 27,197, 40,173, 40, 0, 5,122,167,199,215, 18, 70, 23, 82,153,138,182,237,123,191, 2, 43,137,121, 80, 62, 87, 84,173,209,
+162, 25,230, 78, 65, 94,254,192,194, 34, 3,174, 92, 13,199,152,209,205,161, 55, 82, 16, 4, 26,197, 26, 61,192, 72, 65, 3, 24,
+ 59,110, 34, 8, 37, 65,110, 70, 42, 24,134, 9, 3,199,225, 37,227,211, 25, 51,102, 12,156, 63,127,126,147,121,243,230, 97,222,
+188,121, 94,219,182,109,219,178,108,217,178,121, 89, 89, 89,173, 80,199,224,227,181,232, 52, 58,177,239,243,185,199, 46,111, 46,
+ 24,220, 69,251,240, 21,159,210,228,235, 21, 31,228, 74,165,120, 36, 97,144, 67, 72,213,102, 70, 65, 65, 65, 61, 43,207,255,101,
+ 60,221, 8,190,226,121,189,218,104, 53,111,226, 54,160, 93,219,128,247, 22,204, 95, 96, 25,117,237, 2, 62, 89,186,158,180,104,
+223,175,104,203,229, 59,134, 98,243,198, 3,139,179, 31, 93,173,175,191, 0,128, 1,125, 70,160,181,127,199,103,222,236,214,187,
+116,176,246, 43,231,111, 33, 35, 43,165,222, 39,219, 50,115, 80,109,155,172,250,116,233,127, 26,173, 86,155, 31, 30, 30,238,152,
+156,156, 92,165,225,123,227,198,141, 65, 81, 20, 66, 67, 67,113,227,198, 13,140, 25, 51, 6, 18,137, 4, 82,169, 20, 23, 47, 94,
+ 52, 41,141,169,148, 46,149,247, 58,236,239,238,238, 94, 83,111,195, 58,181,180, 90, 45, 10, 10, 10,112,230,204, 25, 52,111,222,
+ 28,203,150, 45,131,171,139, 19, 22, 44,152, 11, 65, 16, 80, 88, 88, 8,158,231,235,155,104, 9,229,105,145, 32, 8,200,202,202,
+ 66,147, 38, 77,176, 97,195, 6,172, 93,187,246,203,180,180,180,227,166, 46,163,135,135,135, 13,207,243, 31, 13, 30, 60,184,223,
+176, 97,195,208,191,127,213,241, 88,127,254,249,103,203,195,135, 15, 47,255,238,187,239, 6, 24,141,198, 21,153,153,153, 89,245,
+209,253,241,199,210,225,151, 84,157, 22,225,147, 81,141,240,230,204,157, 88,181,234, 8, 20, 10, 69,149, 19,239,146, 37, 75,106,
+ 53, 49, 2, 33, 45,100,217,215, 82,231,126,252,173,227,242,229, 33, 8, 9,201, 4, 77,211,112,113,113, 1, 77,211,120,242,228,
+ 9,104,154,134,151,151, 23,104,154, 70, 74, 74, 74,121,155,192, 60, 84,211,235,177,250,171,112, 26, 58,157, 14, 73,137,241, 72,
+142,141,129, 69, 97, 58,212, 86, 42,228, 69,220, 71,235, 41, 83, 43,198,127,250,135,217,109, 48, 24,118, 87,122,254,237,137, 19,
+ 39, 12, 20, 69,189,142,210,118, 26,229,137,198,151, 28,199,125, 89,147, 72,167, 78,157,218,206,159, 63, 95, 90, 62,220,134,171,
+231, 87,156,209,104, 20, 0,192,167,117,143, 42,110,255,209,163, 71, 88,181,106, 21, 52, 26, 13,100, 50,153,172, 62,219, 65, 16,
+132,138, 30,134,213,153, 48, 83, 76, 22, 0,216,123,185,127, 31,122,251, 34,127, 47,118,179, 54,236,193,175,102,105,137, 52,104,
+195,203,107,178,158, 78,182,220,221,221, 23, 9,130, 64, 8, 33,159, 87,122, 75,225,233,233,121,249,236,217,179,246, 28,199,225,
+187,239,190,179, 73, 79, 79,183,233,209,163,199, 39, 0,106, 52, 90,213, 85, 19, 86, 87,157,136, 74,189, 14, 21, 10,133,157,193,
+ 80, 99,120,242, 76,175, 67,158,135,183,149,165, 13,242,144, 12,189, 3,219, 54,223,158,203, 61,151, 54,245,174,107, 66, 59,127,
+115,158,109, 66, 23, 26,224,166,178,129, 64, 72,141, 93,163,245, 44,251,235,221,219,119, 94,243,244,104,206, 28, 15,190,132,161,
+195, 71, 65,175,167,161, 99, 41, 80,140, 20, 20, 35, 67,171,214,237,224,219,178, 53, 8,128, 91,127, 92,227, 12, 44,123,238,101,
+ 42,123,151,174,239,142,161, 40,172, 3, 17, 72, 53,227,104, 53, 25, 62,124,248,114, 0,239,213,165,227,216,233,221, 49, 52, 93,
+170, 83,121, 28,173, 15,222,157,129,136, 63,164,214,151,110,175,148,245,239,132,147, 89, 33, 20, 84,202, 63,123, 29, 74,233,231,
+ 26,154,227,223, 98,184,234, 54, 90, 30, 30, 30, 54, 86, 10,229,143,239, 76,153,108,153,112,239, 58,210, 35, 67,113,245, 82, 76,
+222,254,195, 71,114, 53, 57,153, 83, 76, 48, 89, 21,213,124,246,206,141,208,216,239, 89,163,165,180, 80, 3, 0, 26,251,117, 4,
+ 99,110,218, 48, 66,213,165, 89, 13, 49, 89,149, 15,216,213,141,161, 53,125,250,116,108,219,182, 13, 93,187,118, 69,139, 22, 45,
+ 42, 14,246,166,166,102,213,164, 75, 38,247, 54,172, 76, 81, 81, 17,188,188,188,176,117,235, 86,132,133,133,193,210,210, 18, 99,
+198,140, 65, 81, 81, 81,133,193,170,111, 99,120, 66,200,163,179,103,207,118,120,227,141, 55,136, 84, 42,165,242,243,243, 97, 99,
+ 99,131, 13, 27, 54,104,210,210,210, 78,101,142,174, 25, 0, 0, 32, 0, 73, 68, 65, 84, 54,192,100,141,146,201,100,115, 71,143,
+ 30,205,248,248,248, 32, 35, 35, 3, 86, 86, 86, 44, 69, 81, 82, 0,176,177,177, 97,205,204,204, 48, 99,198, 12,180,105,211,166,
+251,188,121,243,186, 74, 36,146, 13,169,169,169, 59,107,219,151, 40,138,170, 56,161, 78, 89, 23, 13,131,161,244, 4,189,113,227,
+ 70,148,181,117,251,179,138, 32, 54, 22,168, 71, 79, 22, 11, 11, 11,180,104,209,162,218,178,239,222,189, 59,110,221,186, 85, 90,
+ 53, 41,145,192,209,209, 17, 87,175, 94,173, 87, 79,170,242,129, 32,195,195,195,225,215,216, 1, 97, 33,103,225,160,146,162,141,
+171, 51,220,187,247, 68, 76, 76,204, 63,153,102, 81, 40,109,135,209,183,108, 31,220, 14, 96,122,165,231, 27, 0,124,111,138, 32,
+199,113,132,166,105, 42, 41, 41,201,168, 82,169, 40, 59, 59, 59,137, 66,161,128, 94,175,175, 48, 92,143, 30, 61, 66,112,112, 48,
+146,147,147, 97,103,103, 71, 91, 91, 91,195,104, 52,230,213, 71,223,219,219, 27,206,206,206, 85, 26,190, 79,153, 50,165, 65, 38,
+107, 18, 16,176,237,171, 21,141, 20, 52, 99,237,231, 48, 0,143,163,159,232,104, 3,148,255, 11, 38, 11, 0,242,243,243,183, 0,
+216, 82,254,220,193,193,225, 45,134, 97, 22,232,245,122,235,139, 23, 47,218,168,213,106,106,231,206,157,236,231,159,127,158,207,
+ 48, 76, 30, 69, 81,107,254,121,115,136,200,236,130, 88, 47,169,173,171,112, 79, 71,174,189,159,244,137,111,158,180,185,154,106,
+ 25,128,225,153, 81, 87,222,226, 98,187,100,164,165,211, 4, 66,100, 45,199,224,237,159,204, 95,242, 81, 76,244, 29, 79,165,149,
+ 18,211,103,204,199,201,211,231, 65,209, 82, 92,190, 22, 10,131,145, 71,118,110, 1, 70,143, 29, 15,119, 23, 7, 68,222, 56,147,
+197, 9,194,134,151,203,100, 11,235, 95, 27,250,150,173,194, 76, 85,182, 77,120,236,254, 97, 46,104,122, 29, 22, 46, 92,136,128,
+128,128,153,225,225,225, 95,160,142,113,180, 40, 74, 88,223,170,231, 88, 91,153,162, 84,135, 8, 60,182, 30,252,164,108, 28,173,
+ 57,216,176,229,112,171,150,141, 31, 47,174,109, 28,173,151,200,100, 85,158,215,110,180,188,188,188, 20,230, 82, 76,147, 50,146,
+121,239,140, 27,166,206,140,141, 64,114,212,157,210,234, 5,163,214,152,254, 48,170, 62, 67,161,247, 69,213,241, 59, 72,109, 85,
+ 87, 58, 93,189,174,232,171,104,150,159,112,159, 78,179, 76, 52, 89,207,104, 86, 54, 91,149,199,205,242,240,240,192,242,229,203,
+235, 51,142,214,211,235, 94, 78,127,148, 54,128,175,220, 24,190,127, 61, 77, 86,181,154,106,181, 26, 57, 57,165, 35, 36,244,234,
+213, 11,189,122,253,217,159,193,104, 52, 86,164, 88,150,150,150,213, 37, 90,207,104,154,153,153,125,114,228,200,145,201,215,174,
+ 93,123,227,195, 15, 63,148,190,250,234,171,229,102,174, 4,245,187,183, 91, 21, 77,158,231,103,156, 57,115,134, 17, 4, 1, 91,
+183,110,197,173, 91,183,136, 74,165,250, 76,165, 82,173, 55, 51, 51,227,181, 90,237,244,169, 83,167,142, 95,188,120, 49,221,189,
+123,119, 92,191,126,157,110,210,164,201, 68,160,202, 32,150,213,174,123,104,104, 40,104,154, 6,151,155,136,153,159,236,135,185,
+153, 4,209,209,209,200,205,205,125,102, 16,211,250,108,207,202, 73, 73,249,212,189,123,247,138,106,200,192,192, 64, 48, 12,131,
+187,119,239,214, 84, 13, 91, 89,147,216,219,219, 87,236, 31, 50,153, 12,231,207,159,199,210,165, 75,225,105,103,131,188,168, 48,
+ 56,247,234,131,126,147,167, 98,204,152, 49, 96, 24, 6,118,118,118, 21,201,111, 61,246,165,231,161,178,230,100, 63, 63,191,137,
+145,145,145,238,173, 90,181,114, 9, 15, 15,239, 29, 16, 16,224, 21, 22, 22, 86,254, 92,129,250,181,205,169,208,188,121,243,230,
+161,245,235,215,207,152, 52,105,146, 76, 16, 4, 62, 33, 33,129, 5, 64, 57, 59, 59, 51, 55,111,222, 20,142, 31, 63, 14,173, 86,
+ 11,119,119,119,218,205,205,141, 58,119,238,156, 16, 21, 21, 21, 74, 8,153, 95,159,117,231,121,190,202, 48, 14,229,143,127,254,
+249,103,147,255,239,141,124,189,151,189,218,195,199, 35, 59,245, 46,210, 82, 98,193, 23,168,141,193, 71, 79,232, 77, 52, 89,127,
+117, 25,253,157,154, 75, 30, 62,124,232,166,215,235, 33,151,203,177,113,227, 70,227,242,229,203, 35,179,179,179,187,161,250, 30,
+229, 85, 52, 27,216,235, 48,183, 22,205,103,122, 29, 22,228,224,228,209, 99, 55, 59, 88, 12,223,142,153,169, 89, 21, 13, 27, 9,
+ 69,217, 29,113,242,239,166,234,216, 42,133, 62,181,136, 46,226, 75, 78,214,178,238, 6,173,193, 48,106,248,136,177,191,237,219,
+183,215,226,243, 69,139,112, 53, 52, 12, 57,249,197, 16, 8, 3,129,162,176, 96,193,231,112,118,176, 67, 97,234,195, 18,189,209,
+ 56, 28, 85,199,208,250,215,151, 59, 69,209,179,206, 29,223,185,142,166, 32,104, 50, 30, 40,152,162, 88,213,155, 99,134, 75, 70,
+141, 26,133, 35, 71,142, 32, 60, 60,124,115, 45, 38,171, 66,147, 16,122, 86,216,197,253,235, 40, 64,208,102, 61, 80, 72,138, 31,
+171, 38,142, 27, 46, 25, 51,102, 12,126, 9,190,134,125, 39, 30,111,218,119, 2, 39,240,114, 99,250,200,240,150, 18,132,119,243,
+111,234,214,189, 93, 75,165,132,215, 34, 57, 42, 22,185, 26, 29,206, 69, 36,228,211,132,110,240,216, 58,165, 7, 72, 25, 18, 19,
+ 31, 86,115,101,165, 44, 59,161,235, 76,210,164,105,186, 74,154,245, 60, 73, 86,229,229,116,114,114,170,114, 59,151,202, 39,238,
+242, 54, 64, 13, 24,218,225,147,196,196, 68,171,196,196, 68, 16, 66, 16, 26, 26,106, 21, 24, 24,248,201,243,164, 89,115,231,206,
+173, 72,173,158,158, 87,247, 90, 93,148, 53, 74, 95,203,178,236,193,121,243,230,205, 12, 12, 12,124,109,209,162, 69, 20, 76,184,
+ 1,239, 83,105, 14, 39, 8, 2, 46, 92,184,128, 35, 71,142,240, 70,163,113, 90, 90, 90, 90, 88,165,143,124,119,251,246,237,115,
+ 35, 70,140,216,249,224,193, 3, 38, 50, 50, 18,132,212,221,239, 84,171,213,162, 69,139, 22,224, 56, 14, 43,103,122,160,168,168,
+ 21, 56,142, 3,207,243, 48, 55, 55,175, 72,241, 42,155,231,186,246, 35,158,231,159, 49, 90,161,161,161, 96, 24, 6,221,186,117,
+195,157, 59,119, 42, 18,173,186, 18, 40,163,209,152,232,228,228,228,180,100,201,146,138,229,202,202,202,194,217,179,103,209,169,
+115, 23,248, 79,155,142,212,212, 84,172, 89,179, 6,174,174,174, 88,182,108, 25,114,115,115,193,113,220,223, 29,167, 15,140,140,
+140,116, 31, 55,110, 92,102, 88, 88,152,123,112,112,176, 77, 80, 80,144,249,216,255,103,239,186,195,154,200,218,239,153, 76, 26,
+ 36,161,119, 1, 21, 81, 96, 81,172,168,235,138,139, 29,187,107,175,107,239, 13, 59,174,186,150,181,174,186,186,186,246,142,189,
+187, 98, 23,197,134, 93, 20, 20, 65,165, 9, 33,244, 80,210,147,201,204,239, 15,202, 15,149, 18,208, 45,223,247,229, 60, 79,158,
+ 36, 51,147,147, 59,247,206,220,123,230,125,239,125,223, 33, 67, 50, 34, 35, 35, 93, 8,130,248, 14, 85,156, 4, 77,211,244,130,
+133, 11, 23, 94, 89,181,106, 85,208,244,233,211, 91,142, 28, 57,146,195,225,112,104,177, 88, 76, 29, 61,122,148,240,240,240, 96,
+113,185, 92,226,234,213,171,244,227,199,143, 31, 82, 20,181, 22,192,221,170, 88,156, 75,139, 44,146, 36, 13, 21, 89, 31, 33,208,
+158, 63,194,140,149,233,247,199,182,213, 44, 47, 55, 23,109,240,209,107,201,119, 31,188,141, 35,213, 84,224,190, 10, 66, 3,252,
+ 55,131, 36,201, 19,222,222,222,163,166, 78,157,106, 26, 16, 16,192, 95,186,116,105, 94, 65, 65, 65,121, 34,171,140, 7,230,191,
+101,213,225,222, 5,115, 66, 2,103, 53, 28,229, 62,214,177, 54,110,200, 51, 32,101,147, 44,115, 75, 22,154,214, 34, 81,144,245,
+206,238, 66,232,129, 4, 0,149,197,101,123,242,236,101, 84,199, 6, 13,155,156, 94,187,106,173,253,162,249,243, 56,167, 67, 46,
+131,161,180,120,116,251, 54, 68, 92, 61, 19,253,236, 70,186, 90,171,249, 1,255,133, 41,120, 36,247,183, 28, 3,112,222,218,218,
+250,197,232,145, 35, 61,188,189,135, 64, 32, 16,224,212,169, 83, 56,180,121,179,126, 19, 48,144, 15, 60,159, 88, 73, 60,189,140,
+135, 37, 60, 17,227, 70,143,246,108,218,116, 44, 4, 2, 1, 78,158, 60,137,131,155, 54, 25,204,243, 31,142,226,200,240, 23,241,
+255, 17,226, 43,153,163,197, 34, 10, 30,190, 77,146, 61,122,155, 36, 3,205, 48, 52,195,168, 89, 44, 36,203,181,218, 85,111,227,
+197,213, 18, 5,197,174,195, 21, 43,167,126, 61,159, 71, 41,241, 83,221, 37,221,101,136,172,148,210, 57,210, 74, 15,210,229,125,
+214,233,116, 41, 6,210,175,169, 89,179,230,103,219,170,111,250,101,170, 36,178, 12,141,163, 5, 0,217,217,217, 18, 0,139, 30,
+ 60,120,112,164,115,231,206,227, 0,136,171,217, 70,187,252,253,253,199, 3, 32, 9,130,216,145,154,154, 26,249,217, 13, 47,145,
+196,214,168, 81, 99,157,155,155,219,132,194, 7, 83, 98, 87, 37, 3,121,124,195,134, 13,181,101,181, 69,121,223,105,154,174,180,
+141,114,115,115,209,162, 69,139,207,114, 90, 50, 12,131,164,164,164, 98,139, 83, 73,221, 87, 36,224,100, 50,217,132,105,211,166,
+237,228,112, 56, 53, 1, 16,197, 34, 87,175,215,147, 91,182,108, 49,209,235,245, 36, 0,130,197, 98, 81, 28, 14, 71,117,230,204,
+ 25,138,162,168, 15,106,181,122,194,223,220, 65,156, 36, 10, 83, 49,200, 95,191,126,237, 85,100,201, 74,137,138,138,138, 56,118,
+236,152, 29,128,227,213,228,189,171, 80, 40,238,174, 94,189,186,205,182,109,219, 22, 76,152, 48,161,197,224,193,131,217,109,219,
+182,197,197,139, 23,245, 97, 97, 97,143,148, 74,229,154,170, 8,172,162,182,204,115,117,117, 45, 17, 92,149,220,203, 21, 78,228,
+181,169,197,255, 99,216,164, 26, 38,187,214, 92,147,101,165,106,194,117, 50,205, 79, 7,128, 40,252, 15, 35, 61, 61,125, 14,128,
+197, 27, 55,110, 76,109,220,184, 49,159,203,229,106, 12, 21, 89,127, 35, 40, 58, 87,214,237,183, 78,253,207,251, 47,156,230,214,
+169,157,159,192,181,182,189,115,244,251,116,188,123,112, 81,254,226,194,202, 68, 70, 45,237, 13,192,144,153,235,143,213, 90,109,
+189,217,243,102, 79,230,113, 56,157,245,122,125,163, 14,215,207, 49, 36, 73, 70,106,116,186,235, 69,238, 66,213,127,113,147,175,
+ 88,183,110,157,135,183,183, 55, 78,157, 58,133,235,135, 15, 99, 80, 86, 22,110,145, 36,201,226,114,109, 46,104,181,235, 97,152,
+ 64, 90,177, 97,195, 6, 79, 31, 31, 31,156, 56,113, 2, 87, 15, 30,196,192,234,241,148, 55,214, 53, 7, 96, 87,244, 53, 11, 64,
+ 12,128,102, 0, 76, 1,168, 81,152,218,201,182,244, 16, 86,180,175,120,255, 29,130, 32,254,202,137,176,149, 71,134,255, 20, 81,
+239, 18,155,125,237, 82, 40,149,202, 28, 15, 15,143, 42,173,185,214,233,116, 21,250,112, 41,138, 74,113,119,119, 55,216,106, 97,
+136, 40,202,201,201,241,253, 11, 27,227,139,230, 98,125, 52,136,208,116,162,147,147, 19, 93, 60,232,151, 37,194,202,218,198, 0,
+ 9, 85,249,159,180,180,180, 24, 0,179,170, 91,206,212,212,212,211, 48, 32,105,180,161,199, 1,128, 84, 42,253,234,201,124, 9,
+134, 17, 47, 93,186,180, 74, 2, 27, 12, 83,145,248,140,148,201,100, 45, 13,249,111,173, 86,139,127, 16, 39,138, 94,172,168,168,
+168,113, 4, 65, 4,160,208, 37,176, 3, 95, 39,154,247,221,252,252,252,187,191,254,250,107,155, 93,187,118, 5, 50, 12,131,252,
+252,252, 77, 85, 21, 88, 37, 79,207, 25, 25, 23,191,214,137,231,164,107,110, 30,221,145,210, 94,153,171, 13,220, 45,211, 28,132,
+ 17, 37,198, 40,134, 97,246, 15, 31, 62,252, 91, 0, 7,190,148,172,156, 85,135, 95,138, 4, 90,154,215,248,214,236, 95, 70,223,
+178, 52,235, 14, 61,219, 11, 26,214, 5,104,178, 47, 2,216, 7,195,166, 57,148,156, 47, 69,211, 27, 40,141,102, 67,169,193,229,
+127,161,157,173,125,124,124, 2, 71,141, 26,133,197,139, 23,227,234,250,245,218, 73, 4,145,199, 1,152, 43,133, 15,154, 44, 2,
+152,111, 40,207,136, 17, 35,176,120,241, 98, 92, 90,187,182,186, 60, 21,193,142, 32,136, 16, 0, 8, 10, 10,250,105,245,234,213,
+ 86, 11, 22, 44,104,180,102,205,154, 85, 69,223, 95, 21,239, 47, 26,235,122, 44, 88,176,160, 65,169,253, 5, 0,158,252,197,245,
+ 89,102,100,248,191, 26, 29,141,156, 70, 78, 35,167,145,211,200,105,228, 52,114, 26, 57,191, 4, 12,195,116, 47,124, 43,255,189,
+188,207,165,222,255, 17,176, 97,132, 17, 70, 24, 97,132, 17, 70, 24,241, 31,136,210, 86,172,234,236,255,138, 40,158,163, 85, 26,
+187,128,194,101,221,229,169,210,170,172,122,168,142,178,189, 97,228, 52,114, 26, 57,141,156, 70, 78, 35,167,145,243,127,142,179,
+ 50,238,207,126,207, 48, 76,119,130, 32, 66, 24,134,233, 81,222,123,177,176,250,244,115,169,247,175, 54,237,160, 12, 20,207,205,
+250,108,142,214, 95, 13,163, 89,213,200,105,228, 52,114, 26, 57,141,156, 70, 78, 35,231, 23,161,216, 5, 8,128, 9, 10, 10, 90,
+240, 47,116, 29, 58, 21,137,172,210, 47, 0, 21,184, 14, 25,230, 36, 41, 22,195,156,199, 19,112, 1, 64,163, 81,104,157,157,145,
+ 79, 16, 3,254,201,132,183, 70,252,103,162,120,185,119,250, 87, 62,214, 8, 35,140, 48,194,136,255, 13,100, 22, 91,170, 0,100,
+ 2, 32,138,190,107,138,222, 51,139, 4,217,167,159, 63,218,255, 23, 66,130,114, 44, 89,236,242, 68, 86, 86,150,192,150,205,150,
+122,234,245,170,111, 0,128,205,102,189,201,202,178,138,101,152,147, 89,213, 17, 91,182,246,246,207, 56, 36,233,108,200,177, 58,
+189, 94,156,149,158,254,113,232,120,130,248,111, 16,120,134,138,136, 47, 17, 27,127,185, 80,177,181,181,117,112,112,112,232,101,
+110,110,222, 42, 55, 55,247,113,102,102,230,217, 10,242, 30,174, 38, 8,204, 43,188,174,240, 43,128, 5, 21, 80, 87,229,216, 79,
+225, 33, 16, 8, 38, 19, 4,225, 83,116,131, 69, 41, 20,138,109, 0,222,254, 15,118, 72,166, 0,126, 96,179,217, 35,108,109,109,
+ 91,164,165,165, 45, 5, 80,221,104,222,108, 0,179, 45, 45, 45, 7, 89, 90, 90,186,231,228,228,196,229,231,231,159, 0,176, 1,
+ 64,165, 75,165,151, 78,119,106,213, 54,160,237,162,176,171, 97, 43,150,110,150, 60,248,108,255,108, 39,155,206,157, 90, 47, 14,
+187, 16,190,252,167,173,169, 57, 85, 44, 27,171,232, 5, 20,174,142,100,240,121,176,215, 47, 5, 7, 64, 79, 0,109, 1,132, 1,
+184, 96,200,121,151,131,111, 1,252, 84, 84,230, 13, 0,110,253,203,175, 35,161,131,131,195, 90, 0, 61,217,108,246,107,177, 88,
+ 60, 30, 64,202, 63, 92, 38, 54,128,230, 0,124, 80, 24,134,227, 9, 12, 11,225, 80, 41,108,108,108,122,176,217,236,201, 69,161,
+ 93,182,101,103,103,135,252, 91, 27,134,199,227,109,114,116,116, 28,171, 84, 42, 21, 4, 65, 48,165,227, 61, 82, 20,149,146,149,
+149,229,251,223,214,169, 17, 4,241,228, 95, 94,196,241,101,108, 43, 63,142,150, 88, 12,115, 54, 91,234,153,145, 22, 57, 40, 85,
+242,114, 32, 0,212,112,106,116,194,222,177,225,113,177,152,167,117,244,234, 35,226, 8,216,219, 72,146,211, 68,165, 81,219,114,
+216,156, 44, 45,165,139, 96,105,152,201,105, 49,103,203, 12,182,200, 33, 73,231,196,216, 91,246,148, 54, 7, 28,147, 26,224,152,
+214, 44,183,180, 53,106,212,168,214, 89, 90, 89,185,155,105,249, 38,129, 28, 14,217,137,102, 40, 31,134, 6, 88, 4, 39,138,210,
+235, 66,185,106,245,111, 82,105, 92, 65,117,107,208,203, 6,142, 12, 48, 24, 4, 58,129,193,117, 2, 56, 22,147,141,180, 42, 80,
+ 24, 42, 34,190, 68,108,148,254,237, 70, 0,115,190,246,149,228,236,236,108,213,163, 71,143, 77,191,252,242,139,169, 72, 36, 34,
+ 62,124,248, 16, 48,127,254,252,239,159, 62,125, 58, 75, 44, 22,167,126, 42,250, 8, 2,243,104,154, 97, 1, 0,139, 69,204,183,
+179,179, 23,144, 36,249, 89,108, 35,189, 94, 47,200,204,204,152, 74,211, 12, 81,116,236, 60,134,193,239,134, 8, 70, 19, 19,147,
+ 33, 62, 13,155,204, 90,187,110,131,200,193,222, 94, 72,233,105,109, 66, 82,162, 96, 81,208,156,150,239,223,189,253, 93,165, 82,
+ 29,173,206,125, 77,146,228, 32, 62,159,223, 3,128,119,209,182,104,181, 90, 29,162,215,235,143, 27, 58,160, 59, 56, 56,220, 33,
+ 73,178,118, 85,254, 88,175,215,127, 72, 79, 79,247,171,102, 19, 13,168, 89,179,230, 62,127,127,127, 65,139, 22, 45,192,227,241,
+176,120,241,226,217, 18,137,164, 50,161,197, 6, 48, 91, 32, 16, 12, 18, 10,133,238, 50,153,236,189, 82,169, 60,205,227,241, 58,
+254,254,251,239,174,173, 91,183, 54, 75, 79, 79, 39, 72,146,116,184,116,233,210,143,155, 54,109, 10,160, 40,170, 67,101,131, 92,
+222,123,102, 17,191,167,119,155,188,247,183, 22, 1,232,250,233,126, 74,101, 50,130, 33, 93,123, 40,153,231,201, 69,226,195, 96,
+145,197,225,112,126,119,116,116, 28,165, 42,140, 21,192,124, 58,224, 0,128, 70,163,145,230,230,230,122, 85,231,150, 7, 48,198,
+210,210,114,212,220,185,115,173,186,118,237,138,195,135, 15, 79,217,189,123,183, 52, 63, 63,127, 63, 10, 3, 97,198, 84,145,115,
+ 94, 90, 90, 90, 55, 14,135, 67,184,186,186,146, 74,165,178, 42, 66,203, 19,133, 73,152,159, 0,216,134,194,208, 5,237,128,194,
+251, 29,192,175,197,194,141,197, 98,109,243,242,242,234, 21, 29, 29,189, 29,192,138,234,222,235,142,142,142, 59,183,110,221, 58,
+176,119,239,222,100,102,102,166,115,227,198,141,143,164,165,165,181,249, 10,221,200,104, 62,159, 63,179, 81,163, 70,245, 99, 98,
+ 98, 98,243,243,243, 55, 20,213,103, 69,247,148, 11,128,142,150,150,150, 29, 22, 46, 92, 40,234,209,163, 7,118,237,218,213,109,
+247,238,221,178,130,130,130, 80, 20,206,233,249, 34, 17,200,102,179, 39,167,164,164,216, 50, 12, 3, 39, 39,167,201, 0,254,149,
+ 66,139,197, 98,253,222,183,111,223, 81, 71,142, 28, 17, 36, 38, 38, 10,156,157,157, 75,130,103, 19, 4, 81,237,241,211,136, 47,
+198,174, 82,130,171,242, 56, 90, 60,158,128,171,215,171,190, 73,149,188, 28,248,189,255, 22, 11, 0,184,115,123,218, 64,123,199,
+ 6, 81, 60,158, 32,150,111,110,114,166,111,207,142, 77,250,247,240, 39, 92,156,236,145, 34,201,112,216,123,236,106,151,144,171,
+183,206,160, 48,128, 88,153,160,180, 57, 48,213,222, 64,204,189,205,176,109,155,138, 63, 46,165,224,193,139, 4, 40,242,178, 80,
+219,209, 20,235, 2, 59,195,209, 74, 80,189, 71, 47,123,143,118, 20,155,127,124,232,144,225, 22,189,126,240,230,212,114,116, 4,
+195,240, 17,251, 94,246,221,229,107,183,154,159, 62,121,116,178,144,227, 49, 72,158,241,214,224,206,173,169, 19, 76,229, 90,252,
+192, 38,137, 31, 91,251,214,239, 48,164, 91, 27, 86,125,239,122,120,253, 42,186,243,249,155,143,214,177,194, 95,133, 82,122, 38,
+ 88,200,197,185,231,146, 10, 3,250,125, 38, 56, 58,116,232,216,134,207,231,127, 20, 60, 73,173, 86,115, 67, 67,111,124, 91, 29,
+177, 81,252, 31, 26,141,154,197,225,240,192, 98, 17,179,124,124, 26,122,103,101,101,221, 34, 8, 98, 95,106,106,213,172, 5,211,
+ 0,158,148,205,110,198,226,243,157,244, 26,141, 13, 0, 16, 60,158, 52,129,197,106,184,240,167,159, 68, 36, 73,210,217,217,217,
+ 80, 40, 20,196,184,113,227, 76,222,191,127,223, 87, 44, 22,111,174,228,137, 4,187,119,239,246,116,114,114,250, 44,123,172, 68,
+ 34,225,245,238,221,171, 58, 77,239,217,168,113,211,153, 87,175, 94,241,206,207,145,170,118,111,220,249, 76,103, 34, 80,215,241,
+246,226,108,219,117,208, 98,252,168, 97,211,222,188,121, 21,129,170,229,171,171,105,106,106,122,102,253,250,245, 62,237,218,181,
+227,216,219,219, 35, 61, 61, 29,209,209,209, 62, 55,111,222,252,225,224,193,131,179,149, 74,101, 95,192,160,132,168, 30,161,193,
+251,236,133,214, 54,208,235,116,168,209,168,105, 73,124,179,119, 55,175,129,210,106, 65,235,116,240,238,241, 67,145, 53,153,129,
+183,183,119,117,163,238,214,104,208,160,193,161, 85,171, 86,113,213,106, 53, 30, 61,122,132, 91,183,110,209, 18,137,164,178,128,
+184,108,130, 32,174, 45, 89,178,196,197,207,207,207, 44, 43, 43, 11,122,189,222,246,220,185,115,147,155, 52,105, 98,238,234,234,
+202, 11, 14, 14,134, 76, 38, 3, 69, 81,214,238,238,238,214, 67,134, 12,209, 4, 7, 7,207, 6,176,182, 60, 75, 86,254,123,102,
+145,132,112,239,226,213,108, 4,210,136, 43, 93,102,118,193,101,243,186, 68,137,101,171,139,187,187, 89,190, 88, 48, 95,100,222,
+208, 58, 95,124, 99,126, 23,119,247,221, 87,226, 12,122, 24, 98, 21, 13, 54, 67,143, 29, 59, 38,136,142,142, 22,120,123,123,131,
+166,233,146, 8,252,197, 1,103, 61, 60, 60,170, 83,143,107, 38, 78,156, 56,127,224,192,129,104,212,168, 81, 73, 80,212,159,127,
+254, 25,243,231,207,183,186,115,231,206,236,163, 71,143,206, 62,123,246,236, 90, 0, 65, 85,180,198, 20,163,170,109,188, 44, 62,
+ 62,126,192,153, 51,103,134,205,155, 55,207, 3,192, 84, 0,139,179,179,179,253,139,172, 49,188, 34,161, 53,122,246,236,217,147,
+130,130,130,208,173, 91,183,197,143, 30, 61, 90, 89, 77, 43, 31, 73, 81, 84,183,222,189,123,147, 58,157, 14, 66,161, 16, 58,157,
+174,238,151, 26, 37, 0,108,157, 48, 97,194,164,137, 19, 39,194,202,202, 10, 58,157,206,243,216,177, 99,187, 23, 47, 94,220, 10,
+192,152,114,202, 58, 98,210,164, 73,253,134, 15, 31, 14, 95, 95, 95,176,217,133,213,184,126,253,122, 44, 95,190, 92,116,237,218,
+181, 31,130,131,131,127, 56,127,254,252,105,124,156,182,171, 74,160,105, 26,108, 54, 27,201,201,201,176,183,183,231,211, 52,125,
+149, 32,136, 93, 57, 57, 57,103,255, 69,131,249,175, 3, 6, 12, 24,122,228,200, 17, 17, 0,172, 91,183, 14, 51,103,206,132,131,
+131, 3, 68, 34,145, 81,234,252,123, 44, 90,227, 43,181,104, 85, 6,133, 66,209,116,193,244, 31,193, 98, 21, 62, 53,214,171, 83,
+ 19,171,127, 26, 79,156, 15,185,218,180, 66, 27,188, 73, 13,196,220,219, 12,190,107, 32,212, 58, 10, 15, 95,196,227,250,186,128,
+194,209,178,235, 66,168,181, 29,138, 7, 27,107,158,169,233,175, 26,189,254, 62, 28, 29, 31, 33, 41, 41,179, 50,145,101,231,232,
+ 16,178, 99,199, 90, 83,159,186, 94,208, 82, 58,136, 51,196, 32, 8, 62, 92,156,205, 48,122, 68, 87,142,191,127, 13,219,101,203,
+118, 94, 76,163,209, 71,145,245,182,210,128,161,158,182, 56,208,212,199, 99,224,144,238,126,252,134, 62, 13,192,229,155,150,236,
+107,230,235,139,102,190,190,172, 32, 89, 65,167,199, 79,158,117, 58,117,237,161, 90,161, 75, 58, 17,155,133,145,149,116, 50, 37,
+130, 99,198,140, 25,112,112,112,248,232,128,244,244,116,220,188, 25, 90,230,111,170,208,145,149,252,199,202,149, 43,205,164, 82,
+105,215, 61,123,246,180,167,105,122,101, 90, 90,218, 61, 67, 72,134, 3,181,243,248,252, 14,163, 54,108,160,155,244,234, 69, 90,
+ 58, 58,178,104,189,158, 72,141,139,179,217,184,121,115,219,156,119,239, 76,229,214,214, 57, 82,165, 82, 17, 27, 27, 11, 19, 19,
+ 19,130,205,102, 55, 47,131, 42,157, 97,240, 43,139, 69,204, 39, 8, 2,124,190, 73,236,196,137, 19,159, 23,237,171,125,225,194,
+ 5, 65,207,158, 61, 21, 0, 18, 1,128,207, 55,113, 38, 73,150,103, 97, 36,118,252,106,136,192, 20, 10,133,211, 87,172, 90, 43,
+204,207,201, 85,106,229,114,157,157,185,136, 32, 68,102,100,126, 94, 65,129, 88,146,169, 94,184,116, 57, 57, 97,244,240,233,114,
+185,124,178,161, 34,171,113,227,198,143,207,156, 57, 99,111, 99, 99,131,220,220, 92,100,103,103,227,241,227,199,160,105, 26,125,
+251,246,229,127,215,178, 69,211,159, 22, 46,122,144, 44, 22,183, 50, 68,108, 9,173,109,177,206,175, 73,225, 96,157,152, 93,210,
+ 62,187, 6,244, 40, 57,102,121, 74, 94,177,117,238, 75, 82, 72,181,234,208,161, 3, 23, 0,198,140, 25,147, 95, 80, 80,176, 26,
+192, 17, 84, 30,209,127,246,162, 69,139,156,235,212,169, 83,235,200,145, 35,144,201,100, 0, 96, 95,167, 78, 29,120,122,122,234,
+195,194,194,224,233,233, 9, 51, 51, 51,220,185,115, 7, 15, 30, 60,128,175,175,175, 25,151,203, 29,168,213,106,203, 20, 90,109,
+ 3,218, 46,226,247,244,110,227,213,108, 4, 68,230, 78,216,125,244, 56, 98,158, 29,108,163,214, 70, 47,226,234,111, 15, 87, 50,
+252,145,153, 31, 68, 65,181,125,253,109,234, 53,232,133, 90,205,158,219,170,244,119,227, 23,117,170,179,134,109,162, 58,184,116,
+131, 36,187, 60,145, 5, 96, 93,223,190,125, 7, 28, 59,118,204, 18, 0, 34, 35, 35,145,158,158, 14, 59, 59, 59,152,152,152,128,
+195,225,148,228, 39,173, 38, 70,110,219,182,173, 68,180, 81, 20, 85,146, 5, 64, 32, 16,224,251,239,191, 71,147, 38, 77,112,246,
+236,217,145,229, 8, 45,191,150, 45, 91, 30,174, 85,171,150,107,233,141,114,185, 28,131, 7, 15, 6, 0,248,251,251,119, 48, 53,
+ 53,101,138, 5,161, 68, 34,145, 61,121,242,164, 19,128, 71,229, 40, 75,165, 88, 44,198,220,185,115,145,144,144, 48,101,199,142,
+ 29, 73, 0, 76,120, 60, 94,201,243, 49, 0,207, 6, 13, 26,252, 62,115,230, 76,188,127,255, 30,175, 95,191,126,140,234,187, 82,
+245, 66,161,240,157, 78,167,243,165, 40, 10, 74,165, 18,125,250,244, 49, 57,125,250,116, 58, 73,146,111,178,178,178,134,161,112,
+ 78,138,161, 48, 1,176, 97,226,196,137,147,230,205,155,135,208,208, 80,156, 63,127, 30,195,135, 15, 71, 96, 96, 32, 68, 34,209,
+168,192,192,192, 7, 40, 76,104,254, 41, 58,108,219,182, 13,122,189,254,179,123,195,196,196, 4,126,126,126,168, 95,191, 62,206,
+159, 63,223,225, 11,132, 86, 45, 63, 63, 63, 30, 77,211,144,203,229, 8, 11, 11, 19,153,154,154,138, 92, 92, 92,198, 1,248,215,
+ 8,173, 90,181,106, 77, 60,118,236,152,168,180,247,135,207,231,163,212,117, 96,196, 63,111,209,170,240, 9,171, 4, 26,141, 66,
+203,102,179,222,212,112,106,116,226,206,237,105, 37,174, 67,128,245, 70,163, 81,104, 1, 64, 79, 51,200, 87, 80, 48,229,179,144,
+152, 86,128, 87,113, 89,101, 81,125,180, 68,147, 99, 90, 19,252, 22,137, 96, 24, 6, 26,173, 30,234,188, 52,172,190,168, 64,116,
+138, 10, 26,185, 20, 26,109,225, 52, 44, 91, 91, 91,246,213,171,151,103,222,184,113,115,210,254,253,251,201, 20, 11,139,215, 5,
+ 64,211,178, 56,173,172,220,205,104, 30,239,196,246, 29,139, 77, 25, 50, 14,177, 31,228,168,231,210, 2,182,150,174, 72,203,146,
+227,254,235, 75,120,243, 54, 4,117,156,106, 33,112,122, 23,147, 21,171,142, 28,231, 82,110, 53,115,115, 19,242,203, 43,103,241,
+ 83,212,206, 43,177,160,114,226,160,207,126, 15,125, 65,234,103, 7,136,236,106,162, 89, 59,103,216,185,214,229,143, 12, 92, 62,
+ 2,248, 72,104,149,230, 76, 39, 8,214,118, 22,139,152, 68, 16, 4, 26, 53,106,156,178, 97,195,134,178, 66,129,107, 27, 53,106,
+156, 66,146, 44,151,194,142,157,181,141, 97,232,244, 74,202,249,145,168,225,241,248,243, 10,205,254, 78,201, 23, 47, 94,212, 14,
+ 24, 48, 0,235,215,175,231,205,159, 63,127, 33, 73,146, 99,202,112,239,125,196,217, 7,168,105, 89,183,110,231,149,247,239, 51,
+ 28,157,142,200,121,252, 56, 63, 87, 34,161,210, 10, 10,120, 39,223,188,233, 54,118,206, 28,158,171,171, 43,238,133,132,216,100,
+202,229, 76,174, 90,173,204,205,205,101, 40,138,122, 92, 14,231, 2, 59, 59,123,193,238,221,187, 61, 39, 78,156,248, 92, 34,145,
+ 44, 0, 0, 39, 39,167,213, 0,234, 3, 72, 44,181, 13, 59,118, 28, 23,143, 27, 55, 46, 54, 35, 35, 99, 65, 69,229, 44,133, 6,
+246,118,246,130,163, 59,131, 95, 90,155,153,178,236, 92,106,176, 56,150,150,108,138,103,202,165, 1,101, 29,215,186, 66, 0, 13,
+202,249,237,167,156,132,169,169,233,153, 63,255,252,211,158,195,225, 64,175,215,195,206,206, 14, 9, 9, 9,200,205,205, 69, 65,
+ 65, 1,226,223, 68,195,205,213, 21,203,130,230, 59, 77,157, 31,116, 70,161, 80,248,126, 50,152,125,158, 0, 89,167,253,204,178,
+ 87, 86, 22,131, 79,221, 94, 6,182,123,105, 36,124,248,240, 1, 34,145, 8, 62, 62, 62,162,251,247,239,223,173, 64,100,149, 78,
+ 2, 60,176,117,235,214,102, 71,142, 28,129,175,175, 47, 44, 44, 44, 16, 22, 22,134,200,200, 72,104,181, 90,150, 76, 38,131, 72,
+ 36,194,154, 53,107, 80,179,102, 77, 20, 20, 20, 32, 49, 49,209,134,195,225,216,126, 18,209,190,132, 51,236,106,216,138,188,247,
+183, 22,165, 17, 87,186,236, 62,122, 28,227,134, 12,130, 35, 19,119,215,162, 46,177,162,115,207,214, 63, 51,164,107, 15,161, 89,
+ 35, 43, 15,159,158,224,242, 68,152, 58,111, 57, 98,163, 46, 88, 41, 10, 94, 78, 33,244,201,174, 75, 55,156,156, 81,198,185, 19,
+ 0, 88,174,174,174, 99, 79,158, 60,105, 86, 98,122, 33,201,146,156,135,165,147,192, 87,144,240,189,210,250, 36, 8, 2, 9, 9,
+ 9,176,183,183,135, 72, 36, 42, 73, 32, 30, 29, 29,141,135, 15, 31,162, 56, 27, 69, 57,156,195,110,220,184,225, 42, 20, 10, 63,
+ 58,128, 97, 24,100,101,101,129,162, 40, 8, 4, 2,232,245,122,104,181, 90,232,116, 58,168, 84, 42, 81,253,250,245, 39,235,116,
+186, 71,101,113,210, 52, 61,107,224,192,129,173, 31, 61,122,228,190,121,243,102,104, 52,154,117,105,105,105,232,215,175, 31,104,
+154, 70,135, 14, 29,190,101, 24, 38,102,225,194,133, 0,128,153, 51,103,234,228,114,249,196,234,156,123, 17,234, 55,107,214,204,
+ 61, 52, 52, 20,109,218,180,129, 90,173,198,250,245,235,205,119,236,216, 97, 30, 28, 28,108, 55,111,222,188,125,153,153,153, 1,
+149,112, 18, 0,214, 57, 58, 58, 78,106,219,182,173,105, 81, 14, 83, 28, 60,120, 16,203,150, 45, 59, 6, 96,225,229,203,151,151,
+156, 63,127,126,196,216,177, 99,177,108,217,178,192,220,220,220, 61,229,113,198,199,199,195,206,206, 14,230,230,230,133,157,165,
+ 86,139,136,136, 8, 92,191,126, 29,223,124,243,141, 33,231, 84, 94, 57,107,245,237,219,119,223,209,163, 71,205,146,147,147,113,
+231,206, 29,184,185,185, 65,161, 80, 24,146, 27,246,198, 95, 48, 96,151,203,169, 84, 42, 85, 31, 62,124, 16,173, 93,187, 22, 78,
+ 78, 78,168, 85,171, 22, 76, 76, 76, 64, 16, 4,116, 58, 93, 69,233,213, 42, 45,167,191, 63,216, 89, 98,171,222, 22,150, 86, 83,
+ 24,134, 97,231,229, 73,119,106,145,123, 42, 46, 14,154,191,241,220,255,147,209, 20,192,115,124,156,243, 80, 82, 34,180, 66, 66,
+ 66,152, 30, 61,122, 16,197,239,206,206,200,207,202,178,138,181,119,108,120,220,222,177, 65, 81,222, 47,214, 27,146,180,138,117,
+112, 80,228, 3,128,150, 98, 16,254, 38, 23, 47,223,165, 33,242, 93, 26,132,124,195,140, 47,106, 45, 85, 56, 99,149, 97,160,146,
+253,255, 67,171, 86, 33,133, 90, 91, 56,221, 67,163, 86, 32, 47,243, 53, 49,160, 79, 39,147, 73,147, 38,192,201,201,217,174, 60,
+ 62, 45,223, 36,112,234,204,110,150,214,150, 28,132,220,191,130,111,191,233, 3, 19, 62, 7,217,121, 42,128, 0,222,198, 93, 7,
+104, 51, 68,197,126, 64,203, 6, 2, 4,116,246, 22,157, 61, 21, 51, 7,192, 98, 67,202, 75,165, 60, 6,215,163, 43, 56,122, 29,
+116, 89, 49,160,115,147, 0,161, 35,148,132, 8,217,146, 36,188,185,123,218,160,103, 70,154,166,167,216,218,218,230, 46, 92,184,
+176,109,189,122,245,180,147, 39, 79,126,145,148,148, 52,235,147,167,149,223,182,109,219,134,119,239,222,137, 87,174, 92, 25,150,
+149,149,181,168,138, 13, 29,196, 48,216, 84,228,138,203, 58,119,238, 92,179,219,183,111, 7,110,218,180,201, 97,218,180,105,188,
+105,211,166,141, 6,240, 75, 69,238,194,124, 62,191,227,202, 59,119, 24, 42, 37, 69,125,104,203, 22,222,214,240,240,133, 90,154,
+174, 97,107,111, 79,124,215,178,165, 92,192, 98,101,101,167,167, 83,118,238,238,100,194,245,235, 54,140,169,105,234,229,203,151,
+243,101, 50, 89,185,169,115, 72,146, 84,148,229, 46, 44, 11, 78, 78, 78,154,178,230,112, 85, 48, 32,230,211, 12,163,181,172, 83,
+135,233,220,161, 85,189,119, 49,113,113, 38,150,150,164, 71, 61, 55,175, 87,111, 18, 30, 51,122,189,138, 32,136,124,131,124, 37,
+ 36, 57,104,211,166, 77, 13,205,205,205, 65,211, 52, 44, 44, 44,144,153,153, 9,141, 70,131,252,252,124,104, 10,242,160,201,203,
+ 67,100, 82, 2, 90,183,109,139, 1, 93, 58,123, 7,159,251,115,144, 94,175, 63, 86,161, 63,175, 81,211, 18, 75,214,242,218, 54,
+255,239, 11, 74,206, 45, 17, 93,107,155,122,128, 43, 18,161,211,172,160, 47,185,209,159, 95,188,120,241, 82,223,190,125,187,205,
+153, 51,135, 37,145, 72,174, 36, 36, 36,180, 6,240,186,162, 31,137, 68,162,186, 89, 89, 89,144,201,100,176,176,176,192,166, 77,
+155,224,224,224, 0,133, 66,129, 39, 79,158, 48, 46, 46, 46, 68, 88, 88, 24, 92, 92, 92,144,157,157, 13,173, 86, 11,165, 82,153,
+166,209,104,202,117,151, 23,185, 7,187,206,236,130,203, 49,207, 14,182,113, 38,226,159, 12,156,237,255, 46, 38,242,205,135,107,
+215,239,255, 66,169, 76,146,115, 83,110,204,175,211,252,185,237,148,185,203,240,199,186, 37,136,121,116, 39,199,161,102,254, 86,
+ 83, 66,125,160,162,242,202,229,114,213,155, 55,111,204, 94,188,120, 1,130, 32, 96, 97, 97, 1,129, 64, 80,166,216,170, 6, 88,
+165, 45, 80,114,185, 28, 92, 46, 23, 54, 54, 54,216,179,103, 79,201,192,235,230,230, 86, 17,199,206, 78,157, 58, 13,170, 89,179,
+166, 89,233,141,205,155, 55,199,132, 9, 19,176,125,251,118,132,135,135,127,148, 79, 51, 45, 45, 77,162,211,233, 42, 58,239,220,
+244,244,244, 46,125,250,244,121,118,247,238, 93,243, 61,123,246,128,162,168, 50, 95,187,119,239,198,195,135, 15, 23, 3,120, 83,
+205,235,232,155,126,253,250,221, 57,124,248,176,101,102,102, 38,138,175, 13,185, 92, 14,189, 94, 15, 47, 47, 47,130,162,168,202,
+230,189,177, 72,146, 60,183,101,203,150,158,227,198,141, 3,155,205,134, 70,163,193,150, 45, 91, 48,127,254,252,244,162,135, 82,
+ 45,128,133, 7, 14, 28, 24,209,171, 87, 47, 52,110,220,216,251,214,173,242,103,118,200,100, 50,200,100, 50,112, 56, 28, 56, 58,
+ 58, 98,197,138, 21,208,104, 10,187, 21, 79, 79,207,146,219, 24,192, 78, 79, 79,207,158,177,177,177,235, 81, 56,119,237, 51, 56,
+ 58, 58,246, 97, 24,102,188, 94,175, 47,104,211,166,141,205,209,163, 71,205,196, 98, 49,158, 61,123,134,197,139, 23, 75,105,154,
+214,211, 52, 77, 40,149,202,120,123,123,251,103,124, 62,223, 84,161, 80,228,100,103,103,175, 2,112,229,159, 26,201, 9,130, 32,
+ 56, 28, 14,198,140, 25, 3, 54,155, 13, 83, 83, 83,168, 84, 42,232,116,186, 18, 49,143, 42,186,165,235,213, 19,217,176,193, 29,
+103,101, 86, 63,112,192,140, 30,118, 78, 53,156, 97,105,206, 71,116,244,235,214, 55, 67,175,111,225,177, 99,118,208, 26,221,142,
+152,196,188,191, 60,217,253,167, 90,228, 63, 84,104,125,150,243,144, 93,118, 99, 14,208, 51,204,201, 44,177,152,167,229,241, 4,
+177,197, 86, 46, 7, 7, 69, 62, 65, 12,208,219, 53,232, 13, 74,171, 43,234, 40,152,162,151,129, 66, 75,167,199,187,152, 40,220,
+189,246, 39,108, 21, 98,100,197, 55, 1,184, 13,161, 81,230, 65,165,209, 22,137, 18, 61, 94, 60, 11, 69,126, 94, 14,124,124,123,
+ 0, 44,214,195,242,248, 44,108,136, 30,223, 53,107, 68,190,251, 16,133,230,158,253,225,238,210, 6, 73,146,124,228,202,212,144,
+230,171,208,196, 39, 8,153, 82, 37,242, 21, 42,188,126, 23, 12,231, 26,238, 44,130, 29,215,193, 80,161,165,126,125, 6,234, 55,
+231,193,173,213, 26, 60,175, 94, 32,107,249,225,195,203, 91,120,113,121, 35, 82, 94,221, 3, 67,235,225,228,217,194,208,155,100,
+203,149, 43, 87, 90,180,110,221,154,221,177, 99,199,198,151, 46, 93,106, 44,145, 72, 94, 20, 9,140,198, 29, 59,118,108,108,103,
+103,135,223,127,255, 93, 73, 16,196,150,106, 54,118,137, 5, 44, 35, 35,227, 49,128,149,103,206,156,217, 50, 97,194, 4,216,219,
+219, 55, 76, 77, 77, 45,247,135,153, 28, 78,227,145,171, 86, 49, 28,146,100,142,253,241, 7,119,217,149, 43, 27,246, 31, 56,192,
+109,223,174, 29,193, 48, 12, 34, 34, 34, 4,107,255,248, 67, 48,180,119,239,196,164,140, 12,234,118,120,184, 86,146,146, 82,144,
+ 33,151, 47,147, 72, 36,105,255,196,149,173,211,233, 30,196, 39,196, 59,251,182,108, 98,226,180,160, 87, 0, 0, 32, 0, 73, 68,
+ 65, 84,247, 60, 58,254, 85, 64,251,239,190, 99,177, 88,172,152,184,164,112, 59, 59,115,193,245,107,215,181, 58,157,238,129, 33,
+ 92,124, 62,191, 71,251,246,237,217, 82,169, 20, 53,106,212, 64,102,102, 38,196, 98,113,161,197, 33, 79, 10,109, 94, 30,116,249,
+185,208,203,101,136,127,242, 24, 77,220,235,240, 79,242,249, 61, 20, 10, 69,133, 66,171,248, 41,179,172, 68,215,197,219,120,102,
+102,224,137, 68, 32,170,238, 54,236,109,105,105, 57, 63, 55, 55,247, 18,128, 21, 90,173,118,234,252,249,243,155,111,222,188,217,
+118,229,202,149,230,227,199,143, 63, 41,147,201,154,160, 48,169,106,121, 3,216,123,138,162,108, 0, 56,132,134,134,194,222,222,
+ 30,121,121,121,197,150, 22,141, 66,161, 48,201,206,206,134, 90,173,134, 70,163,129,185,185, 57,158, 62,125,154, 67, 81,212,133,
+202, 10,103, 94,151, 88,161,214, 70, 47,178,241, 22,166,106, 41, 43,255,140, 28, 90,186,116,131,100, 57,128, 13, 93,220,221,119,
+107,233, 59,241,111,163, 46, 88, 37, 60, 9,203, 73,125, 43,119,223,115, 41,190,162, 57, 90, 12, 0,154, 32, 8,198,211,211, 19,
+153,153,153, 32, 73, 18, 2,129, 0, 34,145, 8, 11, 22, 44,192,150, 45, 91,170, 35,180, 76,132, 66,225, 42, 22,139, 53,136,197,
+ 98,217,233,245,122, 4, 5, 5,161,103,207,158,224,241,120,208,106,181, 37, 22,205, 98, 43, 85, 37,150,142,136,135, 15, 31,154,
+ 63,124,248, 81,183,213,206,214,214,246,166, 90,173, 70, 92, 92, 28,206,157, 59,215, 22,192,237, 42,182,117, 92, 68, 68, 68, 23,
+ 63, 63,191,131,205,154, 53,171,203, 48, 12, 26, 54,108,136,193,131, 7, 35, 56, 56, 24, 47, 94,188, 64, 94, 94, 30,125,253,250,
+245,253, 0,214, 87,117, 12, 47,170, 95,175,126,253,250,221, 59,114,228,136, 85,118,118, 54,148, 74, 37,228,114, 57, 78,158, 60,
+137,214,173, 91,195,214,214, 22,135, 15, 31,166, 24,134,169,168,237, 89, 44, 22,107,207,142, 29, 59,122,142, 29, 59, 22, 91,183,
+110,197,177, 99,199,208,171, 87, 47, 12, 26, 52, 8,153,153,153, 14,235,214,173, 27, 81,228, 38, 92, 50,120,240, 96,200,100, 50,
+ 60,121,242, 36,218,192,123, 30,185,185,185,200,205,205,133,169,169,105,233,123,140, 0, 16,188,113,227,198, 33,129,129,129,112,
+119,119, 95, 18, 31, 31,191, 17,101,172, 18,165,105,122,162, 88, 44,182, 98,179,217, 54, 20, 69, 33, 57, 57, 25, 79,159, 62,197,
+148, 41, 83,114,114,114,114, 38, 0, 72, 2,176,112,204,152, 49, 43,102,205,154, 85,114, 45,205,154, 53, 43,228,210,165, 75, 93,
+254,110,107,142,167,167,101, 3, 30,201,159, 33, 45, 32,109,164, 82,105, 73,223,161,209,104,160, 86,171, 63,178,100,113,185, 28,
+155,230, 77,106, 94, 84, 42, 10,126,122,253, 54,183,220, 4,233,222,117, 45, 26, 9,132, 22,129,173,219,180, 31,214,185,203, 15,
+ 36,165,211,225,234,213, 11,216,187,119, 27,218,249,121,194,189, 94, 67, 76,155, 62,195, 66,173,161,130,174, 95,191, 50,223,242,
+225,221, 43, 5,249,185, 11, 42,226,252, 31,199,197, 34,113,117,177, 76,215, 97, 89, 10,178, 40,132,131,180,232,171,173,149,149,
+213, 31,122,189,190,157,185,185, 57,232,220, 88,188,126,250, 8, 57, 82, 14,212, 74, 61,104,166, 80,108, 25, 36, 92,212, 26,220,
+185,122, 30,155, 54,110, 64,118,118, 54,252,190,111, 11, 25,219, 21, 53, 93,107, 66,165, 84, 20,221, 52,128, 86,163,131,157, 67,
+ 45, 60,127,254, 66,151, 47,151,151,219, 33,113, 77,180,222, 53, 29, 60,161,214,182,130, 9,143,135,188, 2, 13,164, 69, 34,235,
+240,169,129, 80, 43,148,160, 52, 90, 80, 26, 29,236,106,246,195, 55, 14,237, 65,235, 47, 52,168, 82,245,209,122,104, 19,238, 64,
+155,112, 7,166,173,166,227,207,213, 67, 62, 25, 72, 13,203,187,155,153,153,153,241,234,213,171, 11, 17, 17, 17,125, 6, 14, 28,
+136, 91,183,110,141, 7, 48,169,200,125, 51,126,224,192,129,136,136,136,192,171, 87,175, 46,100,102,102,102,124,141,150,231,241,
+120, 74,181,186,112,140, 21, 8, 4, 38,149, 28,235,220,188,111, 95, 86,222,243,231,249, 27,239,223, 95,178,123,207, 30,110,199,
+ 14, 29, 8, 29, 69,129,214,235, 81,207,195,131,232,220,185,179, 48,248,196, 9, 27, 82,167,123, 56,119,234,212,208,237,195,135,
+ 23, 60,150,203, 13,157,104, 94,187,200,101, 8, 0,181, 43,216,102, 48,212,106,245,230,137,227, 70,117,188,125,231,158,107, 77,
+ 87,103,243,171,215,111,191,224,155,242, 88,238,110,117, 73,105, 94, 14,123,249,146,159, 76,213,106,181,161,162,213,219,214,214,
+ 22,105,105,105,120,247,238, 29,212,106, 53,116, 58, 29,104,133, 28, 26,105, 46, 52,121, 57, 32, 84, 74,240,245,122,168,178,210,
+ 81,219,189, 14,240,255, 43, 18, 43,117, 69,149, 37,180,138,223, 77,204,205,193, 21,138,192,226,112, 12, 78,142, 14,160, 89,139,
+ 22, 45, 78,156, 62,125,154, 59,122,244,232,150, 55,110,220,248, 3, 64,146, 88, 44,238,176,120,241,226,199,127,252,241, 7,127,
+194,132, 9, 94,235,215,175, 31, 1, 96,103,121, 36, 42,149,234,196,197,139, 23,135,214,170, 85,203, 33, 50, 50, 18, 42,149, 10,
+ 52, 77,163,107,215,174, 64,225,220, 26, 0, 64, 76, 76,140, 82,165, 82,101, 68, 69, 69,229, 39, 37, 37,105, 97,192, 42,193,165,
+155, 37, 15,242,211,238,244,117,112,116,126,104, 98, 90,219,141,145, 61,239, 51,179,191,243,186,141,167,196,170, 43,113,113, 5,
+139, 58,213, 89, 35, 47,120, 57,197,210, 69,182,245, 74, 72,188, 33, 19,225, 75, 86, 23,218,216,216,128,205,102,131,195,225,128,
+203,229,130, 32, 8, 76,159, 62, 29,187,118,237,170,204,117,248,145,200, 50, 51, 51,123,181,108,217, 50,151, 9, 19, 38,112, 77,
+ 76, 76, 32,149, 74,113,248,240, 97,140, 25, 51, 6,123,247,238, 45,115,254,139, 1, 46,165, 79,173,165,129,195,135, 15,135, 70,
+163,193,224,193,131,177,123,247,238, 64,189, 94,127,187, 26,183,244,195, 23, 47, 94,120,188,120,241,194, 28, 64,175, 65,131, 6,
+ 29,232,215,175, 31,110,223,190,141, 11, 23, 46,180, 69,225,162, 15, 37,128,213, 0,236,139,222, 43,186, 63,133, 14, 14, 14,219,
+104,154,238,101,103,103,247,194,211,211,211,231,200,145, 35,150, 25, 25, 25,197,139, 31,144,144,144,128,125,251,246, 73,246,236,
+217,147,175,215,235,109, 88, 44,214,197,220,220,220, 5, 21, 8,182, 61, 27, 55,110, 28, 85,228, 14,196,233,211,167,153, 13, 27,
+ 54, 16,139, 23, 47,134, 84, 42, 69,187,118,237,176, 99,199,142, 25, 50,153,172,241,134, 13, 27,198, 13, 24, 48, 0,203,151, 47,
+135, 92, 46,223, 88,217,195, 74, 5,226,139, 0,240,221,198,141, 27,107, 5, 6, 6,226,244,233,211,104,214,172,153,105,124,124,
+252,118, 0, 99,203,106, 63,134, 97, 16, 31, 31, 15,133, 66,129,123,247,238, 97,201,146, 37,210, 82, 34,107,198,164, 73,147, 86,
+204,152, 49, 3,171, 86,173, 98, 34, 35, 35, 51,250,245,235,231,176,107,215, 46,178, 94,189,122, 51, 20, 10,197,223, 38,180,188,
+234, 89,175,105,222,172,205,124, 39,231,122, 56,124,228, 40,114,114,114, 74,234,164,184, 94, 24,134, 65, 65, 65, 1,210,210,210,
+ 96, 97,110,134,117,235, 87,116,155, 60,126,148, 43, 10,195, 96,124,110,178,116,183, 90,223,111,208,232,217,131,135,142, 66,228,
+139,103, 8, 62,176, 19, 81,145, 17, 37,124,148, 78,139,216,232,167,136,141,126, 10, 7,199, 90,232,220,177, 45, 49,100,200,144,
+174,195,135, 14,178, 3,240,151,133,142,248, 15,182,102, 1,159,199,209,218,245,145,208,170,196, 92,103,107,101,101,245,234,248,
+241,227, 54,126,126,126, 36, 69, 81,184,114,245, 42,166, 76,250, 17, 35,134, 7, 65, 11, 43, 80, 26, 46,104,174,137, 65, 37, 81,
+ 42, 21, 96,192, 64, 46,151, 35, 60, 60, 28, 12, 77, 33,120,215, 6, 48, 12, 93, 34,180, 0, 6, 26,173, 22,206, 53,189,176,109,
+247, 74, 10, 28,206, 99,232,202, 14, 93,147,159, 77,234,117, 20, 3,113,198, 7,124,144, 68,193,194,172, 38,216,156,154,200,206,
+ 85,128,205,114,132, 78, 21, 3,125,209,111, 21,242, 20, 40,181, 95,214,126,250, 50,172,167, 76, 21, 58, 93,165, 82,121,232,208,
+161, 67,221,126,251,237, 55, 94,247,238,221, 61, 79,157, 58,245, 29, 0,116,239,222,221,211,220,220, 28,135, 14, 29,210, 40,149,
+202, 67, 95,209,226,211,190, 69,139, 22,144, 74,165, 72, 72, 72,120, 81,225,185,105, 52, 54, 34,123,123, 50,227,214, 45, 93,166,
+ 84,234,218,190,125,123, 66, 71, 81, 96, 17, 4,114,242,242,144,148,152, 8, 75, 75, 75,226, 85, 76,140,104,203,180,105,103, 61,
+125,124,216,197, 43, 18, 13,193,133, 11, 23, 4, 40,156,151, 85,225,182, 42, 66,158,145,158, 54,106,234,212,169,103, 15, 29, 58,
+108,145,158,145, 30,203,231,241, 40,145,200,164,198,240, 97,147,217,185,185,185, 67, 1,200, 12, 37,147, 74,165,136,143,143,135,
+169,169, 41,184, 28, 14,104,165, 2,122,185, 12,170,156, 76,144, 90, 13,120,122, 61,172, 5,124,184, 58, 56,160,166,157,173, 65,
+156,239,110, 94, 43,153,248, 94,218, 93,184,174,133, 55,120, 66, 17,120,102, 34, 76, 14, 9, 43,122, 26,229, 2,139,127, 49,132,
+214,214,217,217,249,207, 35, 71,142,112, 51, 51, 51, 17, 17, 17,241, 2, 64, 30, 0, 51, 0,116,116,116,244,141,168,168,168, 30,
+ 69,171,238, 42, 91, 45,182,225,204,153, 51,157,252,252,252, 40, 55, 55, 55, 97, 70, 70,134,171, 84, 42,165, 37, 18,201, 71, 38,
+161,107,215,174,241, 11, 10, 10,228, 52, 77,159, 45, 18, 89,149,198, 47,154,217,223,217, 36,252, 57,166,251, 7,212,110,104,110,
+219, 8, 57,212,243,134, 15, 95, 72,166,207,236,239,188,121,227, 41,177,202,148, 80, 31, 32,244,201,174,108, 19,149,161,147,152,
+ 25,160,112,174, 84,120,120, 56,146,146,146, 16, 31, 31,255,145,160, 26, 63,126, 60,130,131,131, 13,178,104, 9,133,194, 85, 75,
+151, 46,117, 9, 12, 12,228,150, 18, 69,152, 58,117, 42,242,242,242,176,123,247,110, 76,157, 58,181,202, 3,255, 39,168,211,190,
+125,251,238, 78, 78, 78,200,206,206,134,163,163, 35,252,252,252,122,222,190,125,219, 13, 64, 66, 53,175,251,201, 1, 1, 1, 43,
+150, 45, 91, 6,157, 78,135, 49, 99,198,224,237,219,183, 39,222,190,125,187,169,102,205,154,211,231,205,155,231,224,224,224,128,
+129, 3, 7, 10, 41,138,234, 91, 30,137,181,181,245,234,157, 59,119, 14,237,222,189, 59, 75,171,213,126,127,243,230, 77, 36, 38,
+ 38, 66,163,209,128,162, 40,188,127,255, 30, 83,167, 78,149, 20,173,110,124,111, 64,185, 70, 47, 92,184,112,212,244,233,211,177,
+118,237, 90, 44, 93,186,116,191,133,133,133, 79,147, 38, 77,154, 46, 93,186, 20,115,231,206, 69,173, 90,181, 96, 99, 99,243,205,
+226,197,139,189,103,205,154,133,205,155, 55, 99,201,146, 37,251, 1,236,171, 78, 69,208, 52, 77,172, 89,179,166,241,198,141, 27,
+157,138, 69, 22,139,197,194,241,227,199,241,252,249,243,158,113,113,113,101,253,102,135,163,163,227,120, 39, 39, 39,222,245,235,
+215, 69,181,106,213, 2, 69, 81,186, 34,145,181,165,102,205,154, 83,222,191,127,143,238,221,187, 35, 46, 46,238, 16,128, 17, 22,
+ 22, 22,242, 89,179,102, 9, 76, 77, 77, 45, 20, 10,197,223, 53,120,131,100, 17, 35, 87, 45,159,139, 39,207, 99,112,230, 12, 23,
+ 79,158, 60,129,131,131, 3,248,124, 62, 24,134,129, 90,173, 70,102,102, 38,116, 90, 53, 26, 54,168,131,131,123,214, 32, 35, 35,
+ 19, 96, 17,229, 78,185, 33, 88,196,176, 81, 63,246,193,221,123, 87,177,125,251, 78,200,100,242,114, 30,190, 77, 80,207,211, 27,
+206, 53,236,145,156,146, 12,130, 5,219,191,242, 92,255,195, 93,135, 37, 93, 16, 12, 9,239, 80, 26,150,150,150,155,142, 29, 59,
+102,211,174, 93, 59, 82, 46,151,131,166,105,180,241,243,195,244,192, 64, 92, 56,114, 4, 30, 45, 7,131,208,136, 64, 9, 12, 91,
+245,160, 82, 42, 80,191,233,119, 24, 48,112, 16, 62, 36, 37, 33,160, 71, 63,168, 84,138,146, 39,140, 98,139,150, 70,163,133,173,
+189, 43,174, 93,187, 70, 98,204,152,215,216, 82,182, 81, 66,175,229,189,140,125,175,106,157,171,124,142,240, 39,193,208,170,181,
+104,216,112, 49,180,180, 13,236, 93,198, 67,167, 59,135,252,204,155,133,110, 12,155,118, 72,249,240, 1, 44,146,251,170,186, 53,
+ 72,203, 51,191,168,211,205,203,203,203,139,143,143, 63, 21, 30, 30, 62,172,111,223,190,184,118,237,218, 56, 0,232,219,183, 47,
+194,195,195, 17, 31, 31,127, 42, 47, 47, 47,239,107,180,182,147,147, 83,175,182,109,219, 14,110,222,188, 57, 66, 66, 66,192, 48,
+204, 93,131,110,108, 14,135, 97,177, 88,160,105, 26, 4,128,236,220, 92,188,125,251, 22,217, 89, 89,208,233,116,144,203,100,180,
+183,167,167,140,161,105,179,170,148,167,244, 10, 67,148,177,234,176,120, 91, 53, 78, 53,233,241,195,251, 31, 10,100, 50, 59, 43,
+ 75,171, 2, 30,143,167,151,230,230,230,189,126, 21,169, 49,112,112, 40, 70,116, 84, 84,148, 79,106,106, 42, 62,124,248, 0, 74,
+ 94, 0, 82,173, 1, 75,173, 64,135,239, 90,193, 20, 12, 76, 64,131, 67,235,192, 33, 57, 40, 40, 92,157, 87,169,187, 67, 95,234,
+ 33,161, 88,100, 17, 4, 81,232, 46, 20, 10,193, 19,153,125,100,225, 50,228,122,226,243,249, 71, 78,158, 60,233,228,236,236,140,
+229,203,151,195,197,197,229,155, 26, 53,106, 40, 44, 44, 44, 76, 29, 28, 28, 80,191,126,125,124,247,221,119,184,124,249, 50, 12,
+168, 3,138, 97,152,206,119,239,222,157,125,255,254,253, 1, 66,161,144,152, 54,109, 26,187,107,215,174,224,243,249, 80, 40, 20,
+144, 74,165, 56,122,244,104, 22, 77,211,197,139, 82,108, 4, 2,193, 62,130, 32, 18,228,114,121,224,167,132, 7,127,107, 88, 35,
+ 35,135, 30,195,200, 4,125,252, 3,106, 55,108, 31,208, 17,117, 60,218,163,125,192, 7, 0, 88, 99,205, 78, 28,252,235, 66,203,
+179,150,102,196,190,107, 87,174, 47,241,243,111,191,112,190,236,214,138,181,187,114, 43,157, 79, 71, 16, 4,104,154,254, 40,118,
+208,167,251, 71,140, 24,129,227,199,143, 87, 90,143, 44, 22,107,208,132, 9, 19,184,159, 88,158, 33, 22,139,209,163, 71, 15,244,
+237,219,247, 35,161,101,107,107, 11, 71, 71, 71, 36, 38, 38, 2, 64,182,129,215,213,244,209,163, 71, 19, 74,165, 18, 99,199,142,
+197,238,221,187, 49,120,240, 96,226,246,237,219,211, 1, 4, 86,245, 98,103,177, 88,235,230,205,155, 55,123,234,212,169,200,201,
+201,193,165, 75,151,208,181,107, 87, 28, 63,126,220,238,210,165, 75,171,218,181,107, 7,146, 36, 17, 18, 18, 2,138,162, 42,140,
+245,197,229,114,123,117,239,222,157,149,156,156, 12, 46,151, 11, 95, 95, 95,164,164,164, 64,161, 80, 64, 44, 22, 99,198,140, 25,
+105,217,217,217,109, 13,189,143,184, 92,110,224,244,233,211,113,236,216, 49, 4, 5, 5, 29, 0, 48, 54, 47, 47,111,192,253,251,
+247,143,245,238,221, 27, 98,177, 24,103,207,158,197,146, 37, 75,136, 17, 35, 70, 96,235,214,173,152, 49, 99,198,254, 34,171, 83,
+121, 23,126, 65, 70, 70,134, 69,221,186,117,145,158,158, 14,153, 76,134,179,103,207,218, 95,190,124,217,205,217,217,217, 60, 62,
+ 62, 94,255,203, 47,191,240, 2, 3, 3,177,105,211, 38, 68, 68, 68, 32, 56, 56, 24,237,219,183,167,226,226,226,202,180,146, 21,
+133,108, 56,203, 48,204,117,161, 80,136,130,130,130,226,251,110, 78, 80, 80,208,212,213,171, 11,141,236,169,169,169, 24, 57,114,
+228,240,208,208, 80,186, 93,187,118, 2, 46,151, 11,149, 74, 37,255, 59, 71,109, 90, 79, 3,160,225,230, 42,194,213, 11,123,240,
+236, 69, 28,158,189,136, 2,143, 95, 56, 9, 94,169, 84,160,105,195,122,104,233,219, 2,169, 18, 49, 14, 5,239,129,181,173,115,
+133,253, 8,195, 48,224,178,245,240,246,116,196,145,224,157, 8,185, 20,138,224, 67, 71, 75,230,188,177,217, 28, 52,105,218, 18,
+190,190,126,136,139,127,143, 61,123,182,195,206,222,213,232, 28,172, 38, 74, 92,135,165,223, 63, 81,254,237,253,252,252, 72,153,
+ 76, 6,149, 74,133,180,180, 52, 36, 38, 38,194,210,202, 18,113,169, 9,104, 43,208, 34,141,206, 71,244,139, 87,122,130,228, 68,
+ 84,246,135,221,253,155, 0,254, 77, 48,101,244,224, 10, 30, 89, 25, 8,205,109, 11, 93, 55, 20,245, 14,155, 55, 83,229, 9, 45,
+ 74,175,187,113,245,250,205, 22,163, 71,244,226, 92,187,185, 27, 58, 13, 13,165,206, 2,114,149, 6,114, 45, 7, 44,139,174, 64,
+214,109,144,108, 62,190,109, 92, 15,103,207, 92,214, 50,148, 46,212,224, 10,114,240, 1,149, 30, 85, 74,104,101,124,226,119,176,
+ 54,216,117, 88, 50,240,234,245,199, 15, 31, 62,252, 67,171, 86,173, 4,237,218,181,171, 91, 52,112,106, 15, 31, 62,172, 40, 10,
+134, 89, 85,124, 20, 13,222,209,209,177, 41,151,203, 29,220,181,107,215,166,163, 70,141,194,235,215,175,113,232,208,161,216,122,
+245,234,221,146, 72,202, 95,145, 77,242,120,217,178,140, 12, 75,145,155, 27,219,202,204, 44,245,242,165, 75,181, 58,118,234, 68,
+124,248,240, 1,217,217,217, 80,169, 84,136,120,241,130,225,144,100, 10, 97,110,206,138,121,254,156, 69,242,120,217,229, 89, 27,
+203, 64, 98, 37,171, 14, 87, 87,215,186,229,234,100, 85,119, 73,208,196, 58, 42,181,202, 39, 63, 63,159, 98,115, 56, 28, 23, 71,
+203,164,152,247,134,247,137,106,181, 58,228,198,141, 27, 63,116,236,216,145, 31,251, 50, 2, 84, 94, 30, 52,121, 82,112,105, 61,
+172,155, 54, 6,169, 85, 3, 26, 29,156,189, 25,168,114, 5,184,253, 40, 70,167, 86,171, 43, 13,106, 88, 44,180, 88,159, 8, 3,
+158, 72, 4,190,153, 57,248, 34,209,167,130,161,178, 39, 57, 65,231,206,157, 59,124,251,237,183, 96, 24, 6,187,118,237,130, 86,
+171,229,105,181, 90,104, 52, 26,104,181, 90,228,231,231, 35, 56, 56, 24,219,182,109,187, 15, 96,191, 1,167, 79,153,154,154,246,
+ 38, 8,194,158,205,102, 43,236,236,236,132,199,143, 31, 47, 9, 55,209,164, 73, 19,152,153,153,113, 81, 20, 20,210,222,222,158,
+179,119,239, 94,203,158, 61,123,222, 41,211,221,209,240,155,185,117, 40, 43,127, 19,211,218,110,230,182,141, 80,199,163, 61, 0,
+160, 83,143,209,168, 83,175, 38,242,179, 94,186,169,148,137,125,184,108,169,213,171,205,226,215,166,221,125, 70,201, 51,194,222,
+162,236,229,253,101, 14, 20, 44, 22,171, 92,119,172, 33, 34,171, 80,179,176,236,138,231,249, 0, 64,118,118, 54, 36, 18, 9,162,
+163,163,225,229,229,133,156,156, 28, 56, 59, 59, 67,163,209,160,121,243,230, 80, 42,149,216,184,113, 35,238,221,187,119, 31,192,
+ 12, 3,254,195,212,195,195, 99,100,211,166, 77,113,233,210, 37, 60,121,242, 68,124,245,234, 85,103, 63, 63, 63,184,185,185,141,
+ 74, 72, 72,248,169,200,213,103, 40,132,126,126,126,211,166, 78,157,138,168,168, 40, 76,156, 56, 49, 59, 57, 57,249,236,137, 19,
+ 39,198, 46, 89,178,132, 21, 16, 16, 0,137, 68,130,117,235,214,233,239,221,187,183, 30,192,242, 74,234,241, 77,114,114,178,139,
+ 74,165, 66, 78, 78, 14, 40,138,130, 66,161,192,229,203,151, 17, 28, 28,156, 94, 36,178,222, 25, 90,184,198,141, 27,215,103,177,
+ 88, 56,118,236, 24, 0, 44, 66, 97,196,254,179,125,250,244, 17,255,242,203, 47,206, 11, 22, 44,192,184,113,227,160,213,106,177,
+118,237, 90, 44, 88,176,224, 98,145,200,170,168, 19,253,205,209,209,113,252,196,137, 19,191,153, 53,107, 22,194,195,195,237,159,
+ 62,125,234, 27, 17, 17, 1, 87, 87, 87,100,103,103,179,109,108,108,176,105,211, 38,204,156, 57,243, 52,128,172, 7, 15, 30, 12,
+138,143,143, 95, 13, 96, 93, 37,162,125,135,179,179,243,120,134, 97, 24,133, 66,145, 24, 20, 20,180,110,229,202,149,152, 57,115,
+ 38, 94,189,122,133,188,188, 60,152,153,153, 17,243,230,205, 27,185,104,209, 34,140, 25, 51,134,145,203,229,219,254,238,129,154,
+ 97,244, 80, 72,163,160, 87, 91,161, 73, 67, 47, 52,241,169,141,171, 55,159, 1, 0, 58,244,243,131, 66, 94,128, 3, 7,118,225,
+221,187,183, 96,115, 56,176,180,118, 52,196, 18, 8, 77,254, 27,228,106, 37,232,216,206, 23, 93, 3,218, 98,255,193,227,160,116,
+ 90,140, 29, 61, 20,210,220, 92, 28, 60,184, 7,113,241,239,193,230,112, 96, 99,251,215, 7, 66,173, 72,139,252,199, 11, 45, 3,
+220, 79,160,105, 26, 98,177, 24, 79,159, 62, 69, 66, 66, 2, 4, 2, 1,148,148,158,222,126,227, 30, 77, 16,220, 20,154, 97,238,
+ 51, 84, 73,148,226,207, 57,244,122,113,169,136,181, 22, 86, 86, 86, 60,181, 90, 9,138,210,149, 26, 85, 8,128, 0,184,108,192,
+169, 70, 29, 36,127, 72,102, 84, 42, 85, 88,133, 79, 80,106,213,166,243,103, 79, 78,253,174,181,159,109,215, 14,203,112,246,220,
+ 98, 72,243,243,161,210,114, 32, 87,105,161, 80, 1,150,214,158,104,222,176, 17, 82, 83,179,241,242,201,109, 25, 91,173, 48,100,
+162,232,219, 45, 11, 71,123,140,158, 50, 23,166,181, 90, 67, 29,125, 22,180, 44,189,196,162,101, 34,178,130,117, 77,111,228,202,
+213, 56, 25,250, 12,168, 66,170,151,140,140, 12, 5, 73,146,135,167, 78,157,186,246,217,179,167, 46, 0,240,236,217,179, 20,137,
+ 68, 50, 63, 35, 35,163,170, 54,233,226,104,240,132,137,137,233,179,122,245,234,165,250,250,250, 90,244,233,211, 7,182,182,182,
+136,136,136,192,234,213,171,223,104,181,218,185,183,111,223,174,208,213,163,209,104,196,207,206,157, 51,111,251,227,143,150,115,
+123,246, 92, 55,117,234,212, 77,203,151, 47,231,120,120,120, 16, 58,173, 22,145,145,145,204,145,195,135,117,219, 22, 44,216,200,
+ 19, 10,217,143,207,159,231, 80,106,181,248,159,190,136,157,157,157,253,253,190,111,227,189,254,183,205, 80, 41,101,120, 20,126,
+ 17, 82,105, 38,118,238, 58,227,237,236,204,248,139,197,226,219,134, 10,224,125,251,246,205,110,217,180,105, 83,119, 87, 87, 68,
+ 38, 37,128, 71,235,193,165, 40,144, 90, 53, 88,148, 10,174, 62, 12, 8,150, 25, 36,105,249, 88,121,236, 84,148, 33,194,248,155,
+110,189,176, 60, 37, 15, 4, 65, 96, 67, 43, 31,240,204, 68,224, 10, 69,152,252,231,205, 18, 97, 16,178,124, 1,120, 34, 17,234,
+182, 52, 40, 32,188,226,214,173, 91, 79, 35, 35, 35,155,251,248,248, 96,246,236,217, 72, 76, 76, 4, 77,211, 72, 79, 79, 87, 73,
+ 36, 18,113,102,102,102, 34, 10,227,255,236,174,100, 16, 43,173, 58,156,111,223,190, 93,226,110, 8, 13, 13, 69,141, 26, 53, 96,
+ 97, 97,129,252,252,124, 76,152, 48,193,242,231,159,127, 6, 0, 60,125,250, 20,165, 5,202,167,136,124, 22,189, 62,183,128,145,
+ 50,178,231,125,114,168,231, 13,219, 7, 36,163, 83,143, 81,184, 30,178, 31, 55,175,222,128, 53, 59, 49, 1,194,130,203, 89, 9,
+ 89,249, 41,114,143, 29,222,205,198,146, 18,249,213, 29,211,122,197,146, 78, 78,244,201, 5,219,243,115, 43, 42,171,135,135, 7,
+ 28, 28, 28, 74,230,104,177,217,108,140, 25, 51, 6, 12,195, 24, 42,178,138,198, 26, 58, 83,165, 82, 57,152,152,152, 32, 45, 45,
+ 13,239,223,191, 71, 92, 92, 92, 73,232, 0,154,166,117,115,230,204,225, 76,155, 54, 13,219,183,111, 71, 88, 88,216,125, 0,203,
+ 0, 24,250,176, 54,116,224,192,129,102, 26,141, 6, 71,143, 30,165, 0,244, 56,121,242,228,211,230,205,155,179,187,116,233, 98,
+182,117,235,214,161, 69,109,100,176,208, 50, 55, 55,231,106,181, 90,108,221,186, 21,201,201,201,254, 0,162, 31, 63,126,188, 99,
+224,192,129,219,124,124,124,234, 69, 69, 69,189,149,201,100,147, 1,188,172,140, 44, 61, 61,125,180,175,175,239, 73,154,166,107,
+117,236,216, 81,248,219,111,191,153,199,196,196,192,197,197, 5, 52, 77, 71,162,138, 41,172,222,190,125, 27, 45,145, 72,188,219,
+182,109,139,203,151, 47,175,209,235,245,171, 0,172,157, 52,105,146,115, 82, 82, 18,154, 54,109, 10,107,107,107,196,196,196, 20,
+ 72, 36,146,109, 40, 76, 73, 84,153, 9, 55, 30,192,252, 29, 59,118, 52,218,177, 99,199, 96,107,107,235,111, 35, 34, 34,112,247,
+238, 93,172, 95,191, 30, 63,255,252, 51,218,180,105,131,217,179,103,103, 1, 24, 12,128,138,143,143, 55, 40,110, 94,177,101, 11,
+ 0,154, 53,107,150,186,122,245,106,140, 29, 59,150,217,187,119,239,239,135, 15, 31, 14, 28, 58,116,104,201, 24, 56,114,228, 72,
+230,208,161, 67, 35, 81,152,134,233,239,132, 78,171,213,192,220,186, 14,100,185, 31,144,153, 28, 14,129,153, 35, 2,218, 55,134,
+ 66,169,193,133,243,167,241, 50,242, 5, 88, 44, 22, 28, 28, 93, 97,105,101,139,216,216,183, 64,197,171,141,117, 90,173, 22,102,
+ 86,181, 33,203, 75,134, 38,227, 25, 76, 69,246, 24,245, 99, 31, 40,148, 90,156, 57,123, 26, 81, 81, 47, 65,146, 36, 28,157, 92,
+ 97, 97, 89,200, 73, 48, 21,175, 96, 54, 2, 64, 25,241,180, 42, 21, 90, 36, 73,222,186,114,229, 74,255,150, 45, 91,178,223,189,
+123,135,119,239, 10, 31,110,164, 82, 41, 69, 64,127, 42, 35,242,252,144, 10,126,222, 17, 69,171, 51, 74,231, 46, 20,153,153,137,
+ 99,222, 68, 59, 72,115,210,241,226,249, 61,188,139,141, 68, 66, 92, 52,180, 90, 21, 72, 22, 11, 44,146,133,218,117, 26,224,222,
+253,112,141,138,162,194,203,227, 44, 44, 71, 92,129,208,222, 99,208,138,229, 63,133,204,156,187,212,116, 64,255,237,120, 25,243,
+ 26, 50,202, 17, 12, 3, 56,218, 8,209,196,125, 30,196,169,153, 56,182,127,171,130,214,106,135,125, 18, 67,235, 51, 78, 0,112,
+200, 66,253,109,187,246,143,217, 29,124,100,233,220,105, 19, 28,122,247, 29, 6, 94,206,107,232, 82,159,161, 78,243,174, 32,248,
+150,184,116,237, 38,110, 63,125,157, 78,235,153,165, 14,217,216, 27, 91, 9,103,105,228,230,230, 62, 72, 75,147,184,148,138, 2,
+239,194,231,155, 84,182, 58,238, 83,206,143, 34,206,147, 36,171,217,138, 21, 43,116, 14, 14, 14,218,168,168, 40,108,223,190,157,
+126,246,236,217, 53, 22,139,181, 69, 34,145,168, 42,227,180,211,233, 94, 28, 9, 10,170,223,162,111, 95,102,200,180,105, 10,240,
+249,211,215,109,216, 16,148, 41,149,214, 96,104, 26,118,214,214, 41,235, 22, 44, 88,221,127,224, 64,233,171,123,247, 76,195,207,
+157, 51,229, 81,212, 51, 3,202,249, 53, 80, 46,167, 88, 44,190, 29, 22,118, 23, 7,118,255, 6,173, 86, 13,137, 56, 9, 0,144,
+149,157,135, 74, 68,214,167,156,140, 66,161,232,187,232,231,159, 31, 46,154, 25,232,248,125,135,142,248,240, 34, 2,218,156, 76,
+ 16, 58, 10, 28,130, 13,121,134, 0, 25,233, 50,204, 63,116, 34, 67,166, 80,244, 45, 99,144, 40,179,156,197, 22, 43,190,185, 25,
+184, 66, 17,120, 34,179,143,172, 88, 38,230,230,224, 9, 69, 96,243,120,101, 77,224,254,140, 83, 38,147,245,235,223,191,255,203,
+199,143, 31, 91,141, 29, 59, 22,223,125,247,221,115,165, 82,217, 14, 64, 65,117,235,147,166,105,241,247,223,127,207, 34, 8, 66,
+ 52,108,216, 48,126,102,102,102, 73,100,117,153, 76,134,203,151, 47,195,203,171,112, 85,255,171, 87,175,208,160, 65,131,114, 57,
+199,205,143, 18, 3, 88, 62,179,191,243,186,135, 47, 36,211, 1,172,169, 83,207, 21, 55,175,222,192,221,155,225, 65,223,250,208,
+155,187, 13,107,254,139,160,221,192,185,222,205,198,146, 34,115, 39, 28, 60,115,154,140,126,182,103,165, 66, 17, 89, 23,219,207,
+206, 41,175,156, 4, 65,128, 97,152,207, 66, 57,144, 36,137,195,135, 15, 87,245,220, 79,236,222,189,123,210,196,137, 19,185, 18,
+137, 4,111,222,188,129, 92, 46,135,137,137, 9,174, 94,189, 74, 1,216,122,248,240,225,171,135, 15, 31,238,130,194,213, 68,161,
+ 85,185, 62,133, 66,225,212,128,128, 0,188,121,243, 6, 79,158, 60, 57, 13,224,229,243,231,207, 79,191,123,247,110, 80,155, 54,
+109,176,127,255,254,169, 74,165,114,119, 85, 56,105,154, 46, 29, 51,169, 56,227,195, 11,153, 76,246,109,120,120,120, 85,219, 93,
+146,157,157,221,186, 72, 88, 39, 59, 56, 56,152,191,120,241, 2, 53,107,214,132, 86,171,109, 89,213,107, 41, 47, 47,239,183, 45,
+ 91,182,236, 29, 61,122, 52,126,249,229,151, 97, 39, 78,156, 24,214,173, 91, 55,116,239,222, 29,251,246,237,195,203,151, 47,215,
+192,176,180, 98,101,157,251, 75, 0, 47, 29, 28, 28,166,184,186,186, 98,253,250,245,136,140,140, 92,189,124,249,242, 5, 47, 95,
+190,132,151,151, 23, 63, 58, 58,154,170, 78, 31, 2, 0,230,230,230,230, 58,157, 14,231,206,157,123, 4, 96,230,176, 97,195,236,
+ 55,109,218, 52, 88, 36, 18, 33, 39, 39, 71, 25, 21, 21, 53, 20,192,249,191,187,175, 99, 8, 98,225,216,113,211,119,140, 27, 59,
+212,196,183, 89, 19, 40,242, 83,160,148,165, 67, 81,144,134, 45,187,175,129, 32, 88,176,179,115,130,189,163, 11,146,146, 62,224,
+254,197, 75, 26,185, 66,185,137,167,163,215, 84,204, 57,173,144,179,105, 33,167, 66,158, 1,165, 44,163,132,211,222,190, 70, 17,
+103, 18,238,133, 95, 82, 41,229,242,223, 52, 12,241,235, 95,124,238,255,201,168, 90,174,195,210,144, 74,165, 51, 38, 76,152,208,
+110,254,252,249, 54, 20, 69,145,214,214,214, 72, 74, 74,162, 78,157, 58,149, 35,147,201,102, 84,167, 52,108, 14,231,165,135,167,
+ 87,187,222,189,123, 83,189,122,245,228, 14, 31,221,133,109,103,111,143,188,220,108,196,190,137, 64,204,235,103,240,240,106,140,
+ 37,203, 55, 2,150,150,149, 38,146, 44, 74,171,211, 99,217,162, 57,199, 91,251,119, 54,247,106,208,152,219,164,174, 5,180, 58,
+ 10, 41, 41, 41, 56,127,238,133, 54,234,233,221,124,154,210, 12, 82,100, 25,150,130,231, 54, 64, 33, 27, 59,125,236,181,135, 87,
+173,219, 50,123,235,206, 3,115,231, 79, 31, 43,108,227,215, 9,145, 55,246,227,116,200,113,185, 74,173, 89,199, 37,177, 33, 42,
+ 27,138,216, 42,214,129, 74,165,210,126, 58,158,170, 84, 42,237,151,182,244,190,125,251,144,158,158,174, 73, 76, 76,188, 66, 81,
+212,137, 10,146, 61,127,134, 45,128,166,143, 90,125, 99,145,159, 95,151, 69, 87,175,154,140,156, 55, 79, 51,108,248,240, 57, 80,
+171,181,224,241, 24,182, 80,200, 2,159,207,121,117,239,158,233,239,147, 38, 89, 19, 26,205,245, 3, 21,132, 13, 40, 3, 95,125,
+213, 97,177, 69,171,109,219, 54, 24, 57,118, 38,148,165, 44, 90, 15,158,196, 66,173,133,193, 22,173, 34,124, 72, 76, 78,254,118,
+250,194, 69,103, 6, 5,116,240,246,169, 85,155,111,231, 86, 27, 34, 71, 71,100,103,102,226,222,147, 24,221,242,227,103,162,138,
+ 68,150, 65,113,101,104,154, 46,156,228, 14,160,195,140,249, 32, 72, 18, 40, 10,227, 80,188,114,200,173,249,119, 32,216,108,232,
+ 25, 26,106,181,218,144, 73,127, 41,239,223,191,239, 55,108,216,176,208,144,144, 16, 86, 64, 64, 64,147,179,103,207,210, 95,114,
+237, 40,149,202,111, 1,192,196,196, 36,193,210,210,210,121,244,232,209,208,233,116, 80, 40, 20,200,203,203, 67, 74, 74, 74,238,
+232,209,163,181, 0, 96,106,106,202,235,223,191,191,121,101,156, 27, 79,137, 85, 51,251, 59,111,182,102, 39, 14,206,207,122,233,
+102,205, 78, 76,248,214,135,222,188,241,148, 88,101, 94, 67,190, 34, 43,241,118,172, 68,126,117,199,193, 51,167,201, 17,125,250,
+233, 93, 68,111,131, 76,236,153, 83,149,241, 18, 4,241, 89,112, 82, 3, 69,214, 71, 40, 40, 40, 88,176,120,241,226,238, 82,169,
+212,165, 75,151, 46, 92,111,111,111, 60,124,248, 16, 33, 33, 33,212,131, 7, 15,146,229,114,249, 79, 0, 84, 0,174, 85,167, 78,
+ 61, 61, 61,221,216,108,118,177, 43,237,143,162,205,127,156, 61,123,118,208,216,177, 99, 81,187,118,237,250,209,209,209,124, 84,
+225, 62, 98, 24,166,196,203,240, 53, 65, 16, 68,220,239,191,255,238,236,232,232, 72, 92,190,124,153, 34, 73,178, 58,150,155,125,
+123,246,236,105,169,211,233,198,141, 31, 63, 30,254,254,254,160, 40, 10,135, 14, 29,194,158, 61,123, 12, 21, 89, 21, 34, 54, 54,
+246, 89,114,114,242,247,115,230,204,193,250,245,235, 23,204,153, 51, 7,201,201,201,136,141,141,141,248, 18,222,252,252,124,229,
+135, 15, 31, 4,173, 90,181,242,141,138,138,138,106,215,174, 93,131,177, 99,199, 98,205,154, 53, 76, 88, 88, 88,127, 0,151,255,
+137,209, 59,230, 93, 78, 48, 71,207,190,186,124,197,111, 63,215,117,119,155, 56,102,212, 64,210,211,163, 1,228,121, 41,176,177,
+117,128,139,107, 29,100,102,100,225,202,149,203,250,172,172,220,125,122, 22,177,236,221,187,156,212, 47,225,116,118,169,131,140,
+140, 12, 92,186,116, 73,159, 43,205,223, 5, 29,107,121,116, 82,110, 58,140, 48,196,146, 53, 30, 21, 68,137,175, 8,182, 86, 86,
+ 86, 71,205,205,205,211,205,205,205,211,173,172,172,142, 2, 6,173, 62,232, 88,170,119, 32, 63,122,245,239,111, 2, 19,147,111,
+193,102,207,178,180,178,186,108, 97, 97,145,221,182,109, 91,205,142, 29, 59, 84,209,209,175,104,177, 56,153,177,176,176,200, 43,
+ 57,190, 44,206, 79, 96,101,229,110, 38,116,106,240,179,133, 75,147,123, 34,167,250, 5, 34,167,250, 5, 22, 46,141,239, 11,157,
+234, 47,181,178,114, 55, 51,168,156,229,160,142, 61,236, 60,108,177,213,203,142, 80,122,216, 98,107, 29,123,216, 25,124,238, 21,
+187,253,244, 4, 1, 61, 10,151, 97,163, 26,156,197, 28, 52, 73,146, 7, 92, 92, 92,156, 80,181,128,117,159,113, 14, 7,106, 15,
+231,243,199,157, 12, 10, 26,153, 16, 22, 54, 44, 63, 62,126, 72, 94, 92,220,192,136,227,199, 7,253, 49,104,208,240, 33,124,254,
+248,254,128,187,161,156, 78, 78, 78,171,159, 61,123, 22, 98,232,171,148,240, 50,184, 62,221,235, 56, 95, 13,232,216,146,153, 58,
+161, 47, 51,117, 66, 95, 38,160, 99, 75,198,189,142,243,213, 47,104, 35,130, 36,201,193, 2,129,224,168, 80, 32,136, 20, 10, 4,
+145, 2,129,224, 40, 73,146,131, 81,241, 28,170,143, 56,109,108,108,158, 58, 56, 56,164, 87,229,101,107,107,251,188, 10,229, 28,
+226,230,230,150,204, 98,177, 54, 86,241,158,174,136,211,195,212,212, 52, 78, 40, 20,166,148,126,153,154,154,150, 14, 12,101, 35,
+ 16, 8, 46, 8,133,194, 77,134,112,254,186,176,193,207,247,175, 77,121,249,235,194, 6, 63,127,186,111,218, 15, 86,163, 31,134,
+ 46,203,158,246,131,213,104, 67,202,105,111,111, 31,102,111,111, 47,177,183,183,151, 56, 56, 56, 84,248,178,181,181,125,106, 0,
+167,137,153,153,217, 38, 51, 51,179,116,161, 80,168, 23,137, 68,233, 66,161,112, 35, 74,133,182,168,110,125,178, 88,172, 53,245,
+235,215, 87,145, 36,185,247,147, 93,235,235,214,173,171, 98,179,217,235,170,200,105,222,166, 77, 27,253,139, 23, 47, 24,127,127,
+127, 6,128,213, 87,108,119, 71, 43, 43,171,203,230,230,230, 31,204,204,204,182, 0, 16, 86,147,147, 0, 48,216,217,217, 57,162,
+125,251,246, 10,103,103,231,112, 0,189,191, 98, 57,187,255,240,195, 15,244,135, 15, 31, 24,134, 97,152, 15, 31, 62, 48, 63,252,
+240, 3,141,194, 64,145, 95,210, 39, 47,156, 52,105, 18,243,224,193, 3,230,193,131, 7, 76,120,120, 56,211,189,123,119, 26,192,
+143, 95,216,207,227,107,157,187,119, 29, 91,247,111,234, 89,157, 24,218,207,143,190,118,126, 35,179,228,167,137, 76, 39,255, 6,
+140, 87, 93,171, 51, 30, 30, 54, 30, 95,131,243,231,159, 38, 48, 29,191,175, 79,123,187, 91, 29,247,174, 99,235,254, 55,159,251,
+127,163, 85, 11,127,245,132,179,255, 55, 45,126, 44,150,202, 70,141, 26, 53,144,157,221,210,132,205,246,227,243,249,237, 88, 36,
+121, 43, 39, 51, 51,176,232,113, 75,255,119,153,106, 43, 28,208,221,193,171, 32, 37, 65,117, 56, 63,154,200, 94, 77,206,170,112,
+ 24,196, 89, 94, 82,105, 90,173, 78,181,161,168,167, 91, 80, 97, 29,124,196,233,236,236, 60,142,166,105, 55, 67, 11,196, 98,177,
+ 18,196, 98,241,238,234,212,103,189,122,245,152, 34,247, 54,241, 53,219,253,175,184,150,254,151, 56, 15,254,214,176,134, 87,195,
+111,230, 70, 62,139, 94, 95,228, 86, 44,193,210,105, 86,102,126,237,219, 46,190,119, 51,236,151,165, 91,164, 5,255,240,185,179,
+ 96,224,156,182,175,192, 89, 28, 36,180, 74,156, 28, 14,103, 71,139, 22, 45,198, 61,124,248,112,175, 94,175, 31,255, 63,122,125,
+118, 39, 73,114,142,167,167,103,147,216,216,216, 8,189, 94,191, 30,101, 4,138,172, 70, 57,127,114,115,115,155,204,229,114,249,
+ 50,153, 76,154,154,154,186, 24,192,137,127, 91,125,122,215,179,246,101,152,146,160,219, 43,223,188,207,121,252,213, 56, 25, 90,
+ 79, 51,228,138,216,248,236,231,255, 64,187,255,183,137,172, 93,127,199, 31,119, 52,114, 26, 57,141,156, 70, 78, 35,231, 87,231,
+ 52, 53, 62,225,159, 41, 0, 0, 32, 0, 73, 68, 65, 84,214,167,145,243,191,144,243,191, 18,108, 99, 21, 24, 97,132, 17, 70,252,
+199, 65,105,172, 2, 35,140,248,215,161,180, 85,171,196,154, 69, 84,160, 74,171, 98, 18,172,142,178,189, 97,228, 52,114, 26, 57,
+141,156, 70, 78, 35,167,145,243,127,142,243,191, 85,100,237,170,224,251, 95, 6,163, 89,213,200,105,228, 52,114, 26, 57,141,156,
+ 70, 78, 35,231,255,130,208, 42,243,187,209,117,104,196, 95,142,205,125,224, 12, 0,211,207, 66,252, 87, 28,111,132, 17, 70, 24,
+ 97,132, 17,255, 48,118,161, 28,215,225,191, 65,104,213, 0,240, 45, 10, 19,223,198, 0,184, 11, 64,250, 5,124,182, 0, 6, 18,
+ 4, 49, 0, 0, 24,134, 57,137,194, 85, 35, 89,134,252,216,196,196, 36, 93,165, 82,217, 23,125,206, 80,169, 84,165,115, 25, 16,
+248,124, 53, 27, 83,234, 85, 38,220,220,220,210,213,106,181,189, 1,127,159,199, 48,204, 75, 22,139, 21, 41, 18,137,110,198,198,
+198,134, 84,229,196,219,181,107, 55,146, 36,201,149, 0,160,215,235, 23,222,186,117,235,192, 95,216,110, 45, 93,107, 56,238,215,
+234,180, 84,122,102,206, 98,124, 30,200, 15, 0,176,181, 7, 86, 19, 20,230, 22,125, 94, 55, 37,164,226, 56, 58, 85, 61,190, 2,
+248,114, 56,156,169, 14, 14, 14, 93, 83, 82, 82,158, 2,152, 7, 84, 30,213,216,213,213,245, 71, 54,155, 61, 76,175,215,187,147,
+ 36, 25, 71, 81,212,225,228,228,228, 96, 99, 31, 98,132, 17, 70, 24, 97,132, 1, 98,235, 51, 84, 73,104,121,217,192,145, 1, 6,
+131, 64, 39, 48,184, 78, 0,199, 98,178,145,102,232,239,187,121, 65,167,163, 10,255,147,203,130,254,242,123,214,174,174, 93,187,
+186, 76,155, 54, 13,223,125,247, 29, 30, 62,124,216,106,223,190,125,163, 79,156, 56,241,146,166,233, 91, 0, 30, 2, 6,133, 82,
+ 16,162, 48, 78,203,208,174, 93,187,118, 92,185,114, 37,217,160, 65, 3, 40,149, 74,132,133,133,249,173, 91,183,110,211,253,251,
+247,111, 0, 56, 82, 36, 8,202, 77,128,167, 82,169,236,139,147,113, 18, 4, 97,223,191,127,255,199,165,197, 85, 81,126, 53,130,
+ 97,152, 7, 4, 65,132,235,245,250,135,167, 78,157, 74,246, 2, 90, 78,112,227,158, 10, 76,208,186,124,202,169, 86,171,237,207,
+253,186, 10,108, 62, 31,234,130,124,180, 26,245,255,162,247,250,207,115, 65,208, 20, 72, 48,210,118, 43, 54,189, 4, 16,153,154,
+154,250,210,223,223, 63,161,170, 45, 76,146,228,202, 43, 87,174, 56, 49, 12,131,128,128,128,149, 0,254, 42,161,197,255,214,183,
+241,173, 11,167,143,154,200,114,210,209,165,247,160,195,111,147, 51, 70, 2, 56,253,145,104,234, 10, 7,130,192,220, 73,171,142,
+144, 0,176,237,167,161,243, 54,118,198,230,153,215,144, 6,160, 93,145,248, 1,128, 95, 1,220,218,218, 21, 14, 0,230, 79, 90,
+117,132, 0,128,237, 63, 13,157,187,181, 43,126,159,114,185,202, 97, 43, 38,143, 28, 57,114,243,202,149, 43, 73, 39, 39, 39,136,
+197,226, 46,245,235,215,247,204,207,207,175,143, 10, 38, 17,215,174, 93,251,120,155,246, 61,235,244, 29, 48, 88, 96,103,107,133,
+ 84, 73,150,249,241,163,123, 39,144, 15,194,186, 38, 38, 38, 14, 50,246, 33, 70, 24, 97,132, 17, 70,148,131,234, 71,134,111,234,
+ 4, 83,185, 22, 63,176, 73,226,199,214,190,245, 59, 12,233,214,134, 85,223,187, 30, 94,191,138,238,124,254,230,163,117,172,240,
+ 87,161,148,158, 9, 22,114,113,238,185,164,226,149, 48, 58, 10,236,107,231,142, 20,142,132,163,135,146,143, 31, 63,174,215,172,
+ 89,179,146,212, 48, 29, 58,116, 64,135, 14, 29,136,109,219,182, 53,190,118,237, 90,227, 61,123,246,104, 67, 67, 67,247,163,226,
+248, 40, 83,235,214,173,187,110,243,230,205,124,127,127,127,240,249,252,146, 29, 34,145, 8, 61,123,246, 68,207,158, 61,201,212,
+212,212,128, 11, 23, 46, 4,252,250,235,175,154,164,164,164, 57,248,255, 40,205, 21, 98,241,226,197,190,101,108,190, 66, 16,196,
+123,138,162, 34, 26, 55,110,156,236, 9,212,155,208,237,187,235,147, 91,123, 8, 3, 23,236, 43,147,135,205,227,225,224,200,194,
+177,186,180,208, 74,184,121, 25, 34,115,179,108,129,153,217, 75, 0,145, 0, 94, 50, 12, 19, 25, 23, 23, 23,253, 13,208,248, 91,
+ 43,214,254,189, 82,186, 81, 21,196, 22,146,147,147, 97, 97, 97, 97,234,239,239, 47, 33, 8, 98,105, 88, 88,216,215,158,144,215,
+114,233,220,201, 92,105,226, 75,164,189,121,128, 89, 3,252, 4,129, 91,254,252, 69,165,209,157,174,232, 71, 4,193, 98,253, 26,
+ 78, 7,161, 48, 25,239,226,236,236,108,127, 0,176,177,177,225, 1,184,181,241, 17,186,205,108, 77,124, 73,108, 55, 46, 73,146,
+ 91,247,237,219, 55,246,199, 31,127, 44, 76, 29,113,239, 30, 68, 34, 17,150, 47, 95, 94,123,246,236,217,171, 41,138,154, 81,158,
+ 37,171, 77,251,158,117,126, 95,255, 75,253,130,156, 60,245,206,173, 39,158,212,240,241, 98, 77,154, 58,219,236,119,173,218, 81,
+175,215,255,104,180,108, 25, 97,132, 17, 70, 24, 81, 21,107, 86,165, 66,203,211, 22, 7,154,250,120, 12, 28,210,221,143,223,208,
+167, 1,184,252,255, 15,221,210,204,215, 23,205,124,125, 89, 65,178,130, 78,143,159, 60,235,116,234,218, 67,181, 66,151,116, 34,
+ 54, 11, 35, 13, 45, 85,113, 82,218,149,189, 29,218,203,115, 51, 76, 0, 64,104,105,175,250,233, 92,218,205,214,173, 91,195,197,
+197,133, 27, 26, 26, 58,166, 18,161,245, 83, 76, 76, 12,159, 36, 43,142,135, 90,163, 70, 13,244,239,223, 31, 94, 94, 94,188,182,
+109,219,254, 84,158,208, 50, 49, 49,201, 32, 8,194, 30, 0,172,173,173,245, 75,151, 46,141, 96, 10, 1, 0, 12,195, 48, 15, 88,
+ 44,214, 67,154,166, 31,253,249,231,159, 41,245, 1,251, 46,205,188,238, 78, 30,222, 95,192,156,218, 84,174, 72, 80,229,231,151,
+185, 93, 32, 18,102,154, 10,133, 47,249, 2,147, 72, 20,230,242,138,116,113,113,137,174, 15,184,180,240,114,187,182,109,230, 80,
+179,189,227,127,169,180, 46,155, 54,109,234,217,168, 81, 35, 19,189, 94, 15,185, 92,142,237,219,183, 91,152,154,154, 90,116,237,
+218,117, 73,233, 11,192, 27,104,216,175, 6, 57,126, 89,170,126, 74, 53, 46, 36,203, 54,173,124, 19,251,247,236,106,238,251,109,
+ 27,188,189,117, 8, 57, 57, 5,200,203,149,129,166,233,207,226,250, 76,185,140,244,173, 61,176,110,219,130,161,243, 9, 22,139,
+104,220,103, 30,122, 57,230, 77,223,177, 99,199, 43, 0, 28, 30,143, 87,250, 58,172, 97,234,236,179,174, 94,231, 54,216,190,112,
+ 56, 24,154,102, 0,172,171,130, 53,203,222,204,204,236,252,181,107,215, 90, 54,111,222, 28, 15, 31, 62, 68,124,124, 60, 38, 79,
+158,172,153, 50,101, 10,119,196,136, 17,196,172, 89,179,166,253,250,235,175,167, 0,220,255,236, 70, 96,179,135,245,238, 59,136,
+ 39,203,205, 87,105,212, 90,141,181,173, 37,173,150,171, 20, 89,210,124,213,160,161,227, 52,175,158, 63, 26, 6,224, 51,161,245,
+133,245,105,132, 17, 70, 24, 97,132, 1, 96, 24,166, 57, 0, 59, 0,153, 4, 65, 60, 41,253,189,232,144,226,108, 45,159,126,207,
+ 66,161, 87,202,166, 20, 93, 22, 10,167,251,216, 1,208, 3,120, 76, 16,132,244, 11,139, 88,241, 42,195,144,144, 16,166,244,123,
+ 41,161,197, 48, 12,195,232,178,223, 51,234,216,203,140,226,201,238,207, 94,202, 87,167, 25,201,227, 19,204,163, 35, 63, 51,158,
+182, 21,103, 97,239,230, 5,221,208, 70, 96, 38, 53, 7, 51,163,173,165,234,241,227,199,161, 52, 77,135, 4,181, 1,195,188, 62,
+194, 48,175,143, 48, 51, 91,129, 57,117,234,212,149,213,171, 87,135, 4, 7, 7,135, 0,168,108,158, 82,122,193,147,112,230,145,
+ 61,152,242, 16, 19, 19,195,236,216,177,131, 89,176, 96, 1,179,119,239, 94, 6,149, 68, 80, 15, 8, 8, 8,139,138,138, 98, 70,
+140, 24, 17,129, 10, 2, 3,122, 3,194, 97,181, 29,223,168,143,111,210,106,126,108,200, 72,191, 55, 41,243,252,157,156,156, 62,
+ 42,207, 26, 15, 71,230,143, 22, 30,204,129, 78,205,210, 24,134,185,194, 48,204, 26,134, 97, 6, 49, 12,227, 5, 0, 77, 1,243,
+222, 78, 54,239, 84, 39,126, 87,106,198,127, 91,105,222,187,166, 77,155,122,206,153, 51, 39, 71,163,209, 48, 9, 9, 9,204,206,
+157, 59,153,235,215,175, 51,231,206,157, 99,252,252,252, 82, 75,149,215, 97,180, 87,173,116,205,158,101,234,234, 92, 69, 28,146,
+252,227,201,245, 83,204,187,187, 39,153,199,199, 86, 51,135, 23, 13, 97,166,245,110,169, 53, 55,229,171, 0,180, 47,239,119, 83,
+ 90,163,158, 87,109,187,216,164,164, 36, 70,171,213, 50,163, 70,141, 98, 2, 2, 2,152,206,157, 59, 51, 29, 59,118,100, 58,116,
+232,192,180,111,223,158,185,121,243, 38,147,154,154,202,116,108,211, 76,222,195, 27,190, 85, 40,154, 79,173, 90,181,210, 18, 18,
+ 18, 24,173, 86,203,132,134,134, 50,135, 14, 29, 98, 66, 67, 67,153,160,160, 32, 6,192,129, 73,147, 38, 41,165, 82, 41, 19, 16,
+ 16,144,130, 50,162,198,215,170, 85, 43, 58, 42, 54, 57,121,227,170,221, 55, 15,254,113,244,230,153, 83,215,111,158,191,250,248,
+226,185,171, 79, 78, 60,122, 17,119,174, 86,173, 90,209,101,180,255, 23,213,167, 17, 70, 24, 97,132, 17,149,107,145, 34,161,213,
+189,200,216,209,157, 97,152,142,159,124,239, 94, 36,156, 62,251, 30, 20, 20,180,160,244,247,226, 99,130,130,130, 22, 0, 96, 90,
+181,106,117,148, 97,152,122, 95,161,248,227,203,120, 85,110,209, 42, 6,149,242, 24, 92,143,174,224,232,117,208,101,197,128,206,
+ 77, 2,132,142, 80, 18, 34,100, 75,146,240,230,238,233,138, 19, 73, 20,225, 82, 12, 56, 0, 66,163,163,163,241,230,205, 27, 36,
+ 39, 39, 67, 32, 16,124,118,220,189,123,247, 96,106,106, 10, 39, 39, 39,195,148,174,230,227,113,238,101,179, 90, 16,181,242, 71,
+214,144,137, 8, 13, 13, 69, 70, 70, 6,184, 92, 46,120, 60, 30, 40,138,170,148,143,197, 42,204,248, 91,108,197, 42,235, 24,127,
+128,205,183, 22, 93,216,182,100,134, 27,235, 65, 8, 71,249,225, 29, 82, 85,122,195, 44,121, 34, 33, 4, 66,129,196,212, 84, 80,
+226, 46, 4, 16, 73, 16,196,219,166, 0, 71, 40, 50,185,176,127,197, 44, 71,242,121,168,137,242,221,203, 50, 57, 58,118,236, 56,
+ 1,192, 18,134, 97,114, 27, 53,106,228,176,114,229, 74, 43,177, 88,140,215,175, 95,227,196,137, 19,153, 84,225,137, 18, 12,195,
+ 44, 3,128,111, 1, 19, 75, 59,203,171,127,252, 60,195, 12,183,142,243,170,115, 21, 89,120,247,188,216,111,196,164, 41,155,103,
+244,132,188, 64,137, 35,215,159,255, 31,123,215, 29, 22,197,181,190,223,153,221,157,173, 32,210,139, 10, 86,148,162,160, 40, 54,
+ 20, 73, 52, 49, 17,141, 37,198, 18, 75, 98,162,215,222, 35,106,140, 37,137,144,104,108, 81,163, 38, 49,150, 27, 11,118,177,183,
+128,177, 43, 74, 81,196,134,128,176, 32,157, 5,182,207,156,223, 31, 44, 43, 34, 11, 11,154,223,205,205,221,247,121,246,153,157,
+157,153,111,207,156, 51,115,206,123,222,243,157,239,224,228,173, 71, 3, 0,252,137, 26,252,222, 54, 92,194, 67, 32,231,237,193,
+131, 7,223,142,137,137,113,248,229,151, 95,160,215,235,171,253,252,242,203, 47, 56,123,241,214, 52, 0, 55,205, 76,150, 91,179,
+102,205,206, 94,187,118,205, 81, 42,149,226,204,153, 51, 40, 44, 44, 52, 42, 89, 99,199,142,165, 10, 11, 11,135,255,244,211, 79,
+ 67,158, 62,125,186,242,226,197,139,121, 40, 95, 11,242,165, 7,129,199,227, 61,210,235,181, 94,174,222,173,248, 67,251,247,232,
+ 81,146, 23, 7, 43,123, 63, 92,185,243,232,104, 97, 65,158,146,199,227, 61,170,124,254,155,200, 79, 11, 44,176,192, 2, 11,234,
+ 6,138,162,162, 8, 33,161, 20, 69, 69, 85,253,173,234,247,138,243,194,195,195,141,251, 21,215, 68, 68, 68, 44,175,180, 95,246,
+134,146, 87,163, 51,124, 47, 3,131,236, 85,221, 73,234,187, 7,160, 78, 58, 12,198,163, 59,132,109, 6,128,231, 17,132,180,184,
+ 11,184,115, 98, 53,158, 37,254, 9,194,177,112,109, 29,104,110, 66, 84, 94, 94, 94, 80,169,202, 93,179,212,106, 53, 24,153,173,
+106,214,248,145, 98, 0,224,248, 98,117, 37, 6,107,150, 65,235,238, 33, 8,204, 38,184,238, 92, 46, 84, 4,102,151, 95,247,205,
+ 39,159,128, 97, 24, 48, 12, 3,202,224,250, 99, 14,209,162, 12, 39,115,229,195, 87,213, 37,130, 42, 19, 9,126,223,189,120, 74,
+160,232,105,188, 80,157,112, 5,153,106,142, 28,205,102,143,153,147, 94,169, 76,154, 33,145, 74,227, 37, 86, 50, 35,209,162, 40,
+234, 17, 0, 16,129, 96,199,206,165, 83,252,100,217,143,101,170, 27,231, 32, 87,113, 90, 19,102,150,158, 56,113,194,137,207,231,
+187,176, 44,139,180,180, 52, 36, 38, 38, 98,237,218,181,217, 10,133,162, 87,108,108,108,114,101,238,200, 74,132,123,119, 44,155,
+222,156, 31, 23, 45, 86, 63, 74,168,243,211,227,208,118,224,187, 3,122,249, 31,155, 48,106, 33, 6,190,255, 14,198,244,242, 33,
+ 41,153,249, 42, 0,103, 12,210,107,109,200,136,141,141,237,211,179,103,207,127,183,111,223,222,155, 16,130,118,237,218, 97,248,
+240,225,216,177, 99, 7,238,220,185,131,226,226, 98,237,233,211,167,215, 0,216,106,102,178,164,182,182,182, 39,207,159, 63,239,
+ 40,149, 74,113,250,244,105, 40,149, 74,184,186,186, 98,242,228,201,194,136,136,136,237,197,197,197, 67,195,195,195,197, 41, 41,
+ 41,235, 79,157, 58,213, 20,229,235,206,189,242, 16,104, 52,154, 45,191,239,216,182,110,242,148,169,141,206, 95,189,123, 78, 93,
+162,176,241,240, 72, 47,118,180,181,178, 94,243,221, 82,119,141, 70, 51,161,250,252,252,163, 94,249,105,129, 5, 22, 88, 96,193,
+ 43,168,145,139, 84, 38, 79, 85,201, 86, 93, 72, 26, 0,101, 88, 88,216, 2,138,162,162,194,194,194, 22,132,135,135, 43, 1,100,
+254, 21, 36,203, 72,180, 66, 67, 67,163,163,162,162, 16, 26, 26, 26,109,210, 4,199, 66,155, 18, 3,109, 74, 12, 36, 93,167,225,
+ 72,248,136, 42, 55,207,213, 59,117,253,151,157, 57,175, 86,171,249,219,182,109, 51,250,109, 1, 0,203,178,111,188, 20,235, 66,
+180, 12, 68,239,149, 68, 52, 19, 89, 69,111,153, 57,180,139, 61, 91, 38,208,252,121, 20, 25,106, 78,191,242,161,182,236, 70, 33,
+249,222,148,205, 67, 51, 38, 32,253,226, 89, 72,173,172,210, 63,139,137, 55,170, 88, 6,146,245, 4, 0,154,138,172,207,109,154,
+ 62, 48,200,133, 1,163, 57, 22,137, 76, 53,167,222,244, 84,183,213,196,195, 6, 66, 8,158, 60,121,130,178,178, 50, 92,190,124,
+ 25,251,247,239,207,169,134,100,161,153,200,234,143, 95,191,248,184,115, 3, 69, 22,163,185,113, 22,153,106,206,172,161, 46,135,
+118, 3,187, 51, 52,117,154,162,121,146,183,187,180,198,140,207, 7, 97,245,175, 71,244, 26,167, 30,161,235, 14, 31,255,168, 68,
+173, 93, 96, 38,201, 50,138,141,177,177,177, 62,177,177,177, 34, 0, 33,195,135, 15, 63, 62,100,200, 16, 68, 71, 71,227,232,209,
+163,158, 0,228,134,243,150,161,124,161,236,239, 1, 60, 54, 37, 60, 50, 12,179,251,236,217,179,190,110,110,110, 56,123,246, 44,
+148, 74, 37, 38, 78,156,168,153, 50,101, 10, 51,118,236, 88,170,168,168,200,168,100, 93,190,124, 57,207, 20,201, 2,128,140,140,
+140, 19,251,247,238,236,214,179,103,207, 65,205, 61,219, 52,120,172, 40,126, 46,149,138, 37, 23,163, 47, 48, 55,174, 93, 90,159,
+145,145,113,189,250,252, 60,103,118,126, 90, 96,129, 5, 22, 88, 96, 26,102,113,145, 42,202, 84, 93, 80,233, 58, 65,120,120,120,
+ 98,120,120,248, 75,138,215,107,162,234,172,195, 99, 21,109, 90,189,226,104,177, 69,105,175,222, 0,199,213,229,102, 95,249,205,
+214,214, 86, 47,145, 72, 94, 34, 90,156,153, 54,243, 15,238,194,227, 73, 35,141, 74, 86,133,178,133,190, 99, 95,139,104,113, 28,
+119, 25,192, 75,137,144, 58,181, 30,177,166,191,119,119,159,230,141,104,221,222,181,120, 86,166, 87, 45,190,175, 85, 37, 41,200,
+128,123,213, 56, 89, 27,109,234,117, 16,203, 36,169, 18, 43, 89, 85,146,245, 20, 0,100,206,158, 67, 86,190,215,166,151,127,155,
+150,180,126,207, 42,100,148,233, 74,194,238,105,181,143, 75,201, 1, 19,121,184,248,157,119,222, 89,108,111,111, 47, 94,183,110,
+157,141,135,135, 7,244,122,189,166, 42,201,146, 58,181, 30,177,118, 96,219,238,173, 93,108,105,221,190, 31,145,174,100,203,214,
+ 62,214,109, 55,135,100, 57,216, 88,157,218,180,124,146, 68, 42, 18, 64,165, 82, 33, 98,227, 62,156,190,148, 16,154,155,112,232,
+ 20,128, 83,175,241, 64,126, 22, 26, 26,186,122,217,178,101,208,233,116, 24, 55,110, 28, 30, 61,122,116,250,254,253,251,107,221,
+221,221,231,124,241,197, 23,110, 46, 46, 46,248,232,163,143, 24,157, 78, 55,214,132,141,239,126,255,253,247, 80,127,127,127, 68,
+ 71, 71,163,176,176, 16,174,174,174,152, 50,101,138, 48, 60, 60,124,123,113,113,241,208,229,203,151,139,159, 60,121, 82,163,146,
+245,210,115,205,178,223,108, 94, 61,105, 78,167, 46, 65,244,195,135,201,250,180,192, 96,250,194,217,163, 49,246,246,246,219,211,
+210,210, 94,228,231,160,118,117,206, 79, 11, 44,176,192, 2, 11,222, 12, 40,138, 58,102,240,187,122, 73,229,170, 74,194, 42, 20,
+171,202,251, 85,207, 55, 28,127, 19,157,229, 45,213, 16,175,151,195, 59,132,134,134,154, 61,173,158, 43,205, 49,139, 60, 85,197,
+251,109,160,107,100, 5,254,130, 96, 26,140,204, 86,213,127,217,153,243,166,206,149,201,100,102, 43, 90,156, 90, 85, 91,161,212,
+137,104, 25,124,180, 78, 18, 66, 94, 34, 90, 54,206,173,131,231,125, 49,125, 77,208,144,190,116,246,231, 93, 81, 88,162, 86,127,
+113, 87,207, 61, 43,171,153,100,149,183,226,186, 20,169,204, 42, 94, 44,147, 86, 38, 89,105, 0, 32,118,106, 25, 56,119,198,228,
+141,111,141,232, 79,229, 76, 12, 66, 65,161, 82, 61, 39, 81, 79,101, 40,201,208,123,192,133,234,204,157, 63,127,126, 51,128,205,
+193,193,193,217, 50,153, 12, 37, 37, 37,175,148, 65, 69,122,187, 15,233, 75,103,127,214, 25,249,165, 90,245, 23,137,122,100, 42,
+185,221,181,145, 44,199,134,214,167, 54,125, 59, 73,154,249,236, 41, 24,134,129,149,149, 21,206,252, 25,143,220,196,195,175, 67,
+176, 64,211,244,146,176,176,176,197,147, 39, 79, 70, 94, 94, 30,142, 30, 61,138,247,223,127, 31,187,118,237,242, 56,126,252,248,
+234,144,144, 16,240,120, 60, 68, 69, 69, 65,167,211, 61, 48, 97,102,208,248,241,227,231, 12, 25, 50, 4,215,175, 95,135, 92, 46,
+127, 73,201, 42, 44, 44, 28,190,113,227,198, 33, 41, 41, 41,181, 42, 89, 85, 16,216,172,101, 7,102,254,162, 31,160, 46,123,206,
+207,201,184, 26,125,238, 12,125, 37, 63, 63, 95, 10,160,168,190,249,105,129, 5, 22, 88, 96,129,217,170,150, 41, 46,146, 99, 32,
+ 81, 57,213,237, 87, 34, 88,213,237, 83, 85, 84, 48, 77,149,227,119,254,202,123, 50, 75,209,226, 59,183,133, 62, 59,161, 18,209,
+122,254,210,113,177,181,157, 89, 67,135, 58, 61,248,155,182, 26,227,104,137,243,242,242,196, 14, 14, 14,170,202, 4, 65, 42,149,
+194,205,205, 13, 5, 5, 5,216,178,101, 11, 80,187, 83,180,190,193,144, 81, 8, 28, 49, 14, 55, 26, 11, 65,116, 90,163,178,181,
+233,147, 79, 94, 34, 91, 12,195, 84,248,134,213,214,232, 94, 51, 40, 77, 87, 0,144, 14,158,205,191, 22,203,100,159,136, 29,154,
+ 56,204,152,244,153, 32,229,185, 26,231,131,230, 23,238,251,110,158, 85, 58,177,154,156,134,162, 75,181,216,123,252,193, 79, 59,
+171, 42, 89,207,218,123, 54, 95, 40,150,138, 63, 23,218, 53,117, 9,155, 53, 73,144,146,173,166,206, 7,126, 81,188,255,251, 47,
+164, 79, 96, 61,231, 25, 10, 47,152, 81, 60,139,223,127,255,253,197,132, 16,194,113,220, 34, 0,168,156,222, 89, 83, 62, 23, 60,
+206, 82,225, 92,208,194,130,253,223,205,179, 78, 71,205,233,117,104, 55,176,187,179,109,131, 83,155,150, 79,150,202, 51, 82, 33,
+ 18,137, 96,109,109,141,244,236, 34, 8,248, 60,229,107, 62,111,162, 30, 61,122,204,155, 52,105, 18,226,227,227, 49,113,226, 68,
+121, 90, 90,218,129, 61,123,246, 76,252,234,171,175,248,239,190,251, 46,228,114, 57, 86,172, 88,161,251,243,207, 63,151, 3, 88,
+ 81,237,243,200,231,127,246,245,215, 95,147,204,204, 76,234,201,147, 39,112,117,117,197,212,169, 83,133,203,151, 47, 55,250,100,
+213, 69,201,170, 64, 70, 70, 70,244,233,179, 87, 48,224,196, 26,232,117,234,232,194,188,180,152,164,199, 5,209,118, 66,225,236,
+ 70, 29,218,213, 43, 63, 45,176,192, 2, 11, 44,120, 35, 42,214,141,154,246,255, 6,168,110,232,208, 44,162,245,224,199,133,159,
+122,126, 58,121, 46, 36, 30,221,161,190,119, 16, 92, 73,182, 81,209, 18, 91,217,194,206,221, 27,133,165,106, 68,158,187, 5, 0,
+ 15,234,146, 42,133, 66,129,128,128, 0,108, 24,219,250, 45,149, 34, 79, 44, 1,160, 22, 53, 80, 29, 18,246, 56,127,252,248,241,
+ 50,142,227,118, 3, 56, 94,139,153, 37,190,190,190,235,127,248,225, 7,161,247,136, 79, 81,114,245, 98, 85, 5, 5, 18,137, 4,
+ 34,145, 8,113,113,113, 56,127,254,188, 6,192,146, 90, 10,244,154, 94,175,191,179,103,207,158,103,173,154, 55,234, 27,208,222,
+111,218,130,249, 97,214,119, 47,158,198,162,229,235,185, 86, 29,223, 45,138,216,117, 72, 81,100,229,254,182, 82,126,255,182, 25,
+183,122,167, 10,201,202,244,106,214,228,173,246,109,125,231, 46, 90,180,176, 65,226,197, 51,248,234,251, 77,196,211,191,119,209,
+247,251, 15, 23,231, 74,155,190,163,122,158,116,221,156, 60,140,142,142,222, 12, 96,115,197,126,213,244,134, 45, 91,203,181,238,
+212,183, 32, 98,215,254,210, 98,107,247,222, 53,165,215,209,123, 80,183,198,142,182,167,126,252,230, 95,210,172,140, 52,136, 68,
+ 34, 88, 89, 89, 33, 77, 94,136,197,107,246,150,106, 57,174,239,235, 18, 45,107,107,107,145, 86,171,197,134, 13, 27,144,150,150,
+214, 21, 64,218,205,155, 55, 55, 13, 27, 54,108, 93,187,118,237,188, 18, 19, 19, 31,148,148,148, 76, 6,144,100,202, 72,195,134,
+ 13,187, 58, 58, 58, 82, 87,174, 92,193,191,254,245, 47,205,212,169, 83,153, 49, 99,198, 80, 5, 5, 5,245, 85,178, 0, 0,141,
+ 26, 53, 10,238,243,118, 23,116,239, 51, 49, 90,163, 42,140, 73, 73,218, 30, 77,147, 75,226,250,230,167, 5, 22, 88, 96,129, 5,
+255, 51,168, 95, 96,240, 96,128,223,218, 30, 19,124, 27, 49, 89, 59,190,155, 74, 20,143, 47, 19,229,245,205,164,248,224,231,228,
+216,138, 49,228,248,143, 51,200,196,126,190,196,203,137,202,106,109,143, 9,193,175, 18,183,151, 86,247,126,191, 13,116,125, 90,
+130,244,105, 9,210,175, 53,116, 0, 22,116,232,208,225,208,148,192, 23,113,180,166, 4,130, 0,248, 23, 0, 43, 19,201,170,110,
+197,112, 87, 0, 91, 2, 2, 2,244, 23, 46, 92, 32,247,135,246, 38,177, 94, 14,100,242,228,201,228,171,175,190, 34, 35, 71,142,
+ 36,142,142,142,122, 67, 70,184,214,102,115,192,128, 1,141, 1,160, 73,147, 38, 13, 59,122,183,202,138, 59,119,148,196,236, 88,
+ 71,126,157, 50,152,116,110,231,157,235,226,213,243,142,196,181, 77,251, 90,178,207,104,211,197,197,101, 62, 33,164, 47, 33,196,
+ 21, 0, 60, 61,237,173, 58,120,181,202,188,115,246, 40,185,184,115, 61,249,117,202, 96,210,197,207, 39,175,177,119, 72,146,216,
+201, 43,208, 28,155,213,161,218,244,182,245,202,117,110,213,237,118, 13,233, 53,218,108, 30,248,209,225,103,153,217,228,218,181,
+107,228,248,241,227,228,226,197,139,100,199,158,195,196,189,211,208, 18,135,118, 3,187,215,225,209, 49,149, 78,155,126,253,250,
+145, 7, 15, 30,144,247,222,123,143, 0,176,169,167,205, 67, 41, 41, 41, 36, 33, 33,129, 44, 88,176,128, 0,216, 54,105,210, 36,
+101, 81, 81, 17,233,221,187,119,154,129, 96,241,235,147,206, 22,205, 26, 69, 12,234,223, 99,201,148,127, 13, 9,126,221,252,124,
+131,176,216,180,216,180,216,180,216,252, 95,176,249,223, 12, 87,131,170, 85,177,237, 96,150,162, 21, 13,232,145,135,205,109,157,
+180,255, 94,190,226,199,217, 27, 54,111,155, 59,111,218,103,178, 30, 65,125, 16,127,246, 55,236,143,218, 83,170, 82,107, 86, 48,
+ 60,252,144,144,135,178,228, 90, 82, 97,136,163,245, 18, 98, 99, 99,165,118, 45, 95,196, 96,122, 88, 30,155,117, 83, 29,111, 80,
+ 14, 96,252,173, 91,183,126, 8, 9, 9,249,246,243,238,129,131,167,116,123, 11, 58,157, 14, 59,118,236, 64,106,106,234, 1, 0,
+ 11,205, 85,220,226,227,227,115,125, 90,122, 76, 23,240,248,115, 39,143, 28,228,152,243,232, 46,158,221,139, 5, 0,168,213, 74,
+ 93,214,131, 24,255,186, 36, 78, 34,145, 92,115,116,116,188,239,232,232, 88,208,186,121,147,241, 34, 8, 22, 77, 28,254,129, 83,
+ 94, 74, 18,210, 19,203, 71, 70,213,170, 50,237,179, 7, 23,188,234, 83,186, 30, 30, 30, 34,153, 0, 19,170, 77,175, 70,165,203,
+126,152,212,222, 28, 59,101,106,205,242,165,171,119,188,243,205,220, 79, 68, 13, 26, 52,192,173,132,135, 88,180,106, 87,169, 82,
+163,235,155, 27,127,232,141, 12,143, 17, 66,160,211,233,204,158,232, 96, 2,243,252,253,253,219,124,251,237,183,158, 99,199,142,
+197,235, 42, 89,149,241, 56, 37, 35,172, 81,147, 22, 62, 15,239,223, 10,177,147, 48,255,126,157,252,180,192, 2, 11, 44,176,224,
+127, 6,253, 12, 98,206,248, 74,219,216, 90,137, 86, 5, 18,158,163, 12,192,178,230,188,146, 77,243,191, 93,189,152,166,214,124,
+194, 17,242,155,158,198,210, 39,121,200,121,205,196,149, 9,248,208,191, 51,112, 36, 31, 0, 4,252,250, 53,144, 6, 60, 0, 48,
+228,231, 75,215, 59,253,124,233,250,151,134,223,190, 1, 80,167,177, 92,107, 62, 18,130,124, 90, 52,234,209,193, 87,204, 99,149,
+120,118,239, 17,242, 75, 85, 56,147,152, 90, 72, 19,250,183,186, 38,234,201,147, 39,127, 0,128,179,141,244, 94, 15,159,150,238,
+ 61, 3,124,165, 2, 74,131,103,119,111,161, 72,169,193,233,196,212, 34, 80, 84,189, 29,170,223, 84,122,179,227, 15,223, 56, 2,
+170, 55, 69, 81,103, 23, 76, 25, 33, 90,188,106,247, 27, 37, 89, 0,202, 50, 50, 50,242,202,202,202,236, 51, 51, 51, 53,168,127,
+144,184,135,197,197,197,237,102,204,152,177,108,206,156, 57,115,191,251,238, 59,166, 62, 62, 89,166, 80,144,145,122,176,167,239,
+155, 43,127, 11, 44,176,192, 2, 11,254, 39, 48,190,202, 22,102, 19, 45, 35, 97,120,142, 28, 0,147, 91,180, 32,179, 30, 63,134,
+230, 77,165,172, 58,165,235, 53,113, 3, 64,255,122, 95, 77, 83,138,171, 15, 82, 75,174, 61, 72, 45, 1, 71, 8, 71,136,154,166,
+145, 94,170,213, 46,127,240, 36,163,254,179,238, 40,138,189,241, 48, 77,121,243, 81,186,138,112, 28,225, 8,209, 80, 20,178,116,
+ 58,110,121,226,147,212,195,127,135,244,230,198, 31,186, 20,165,167,122, 92,186,150, 48,171,180, 84,187, 62,247,222,161,203,111,
+176, 92,116,241,241,241, 31,119,237,218,245, 83,150,101, 55, 1,208,189,134, 45,141, 94,175,159, 23, 17, 17,113, 32, 62, 62,126,
+239,229,203,151,229,111,130,100,253,165,229,111,129, 5, 22, 88, 96,193, 63, 21,245, 91, 84,218, 20,222, 36,201,250, 59, 34,225,
+225,211,128,191,194,110,226,195,167,109,255, 27,210,155,125,239,224,205,108, 96,248, 95,148,189,167, 89,150, 61,253, 38, 73,245,
+201,147, 39,155,161,154,101,117,254,110,229,111,129, 5, 22, 88, 96,193, 63, 22,227, 77,145, 47,190, 37,111, 44,248, 7,128,188,
+ 41,146,101,129, 5, 22, 88, 96,129, 5,245,128, 73, 69,139,130,233,153, 3,103,235,240, 7,245,153,125,112,214, 98,211, 98,211,
+ 98,211, 98,211, 98,211, 98,211, 98,243,127,206,230, 63, 17,174, 40,119,136, 63,102,216,214, 72,190,222, 36, 44, 83, 95, 45, 54,
+ 45, 54, 45, 54, 45, 54, 45, 54, 45, 54, 45, 54,255,233,168,214, 17, 30, 40,119, 30,182,192, 2, 11, 44,176,192,130,255, 38,136,
+ 12,159,250, 30,183,192,130,191,154,108, 25, 9, 87,125,124,180, 90, 25,182, 15,255,194,196, 78,113,117,117, 29,239,231,231,231,
+205, 48, 12,173, 80, 40,150, 94,184,112, 97, 73,213,147,122,248,240,111,242,104, 52,126,241, 11, 5, 80, 60,128,166,193, 18, 60,
+187, 24,167,236,104, 41,247,191, 53, 60, 36, 13, 28,143, 80, 52, 79,200,234,181, 96,117, 90,148,187, 91,149,131,227,244,169,172,
+ 86,253,174,169,139, 93,252, 7,185,235, 89,238, 59,128,108, 0,232, 73, 0,183,145, 2,127, 34,129,254, 39, 10,188,127,129, 71,
+190, 7, 75,125,193, 23,240,230,203, 99,247,165,255, 19, 50, 44, 50, 50,146,247, 58,215, 15, 29, 58,180,218, 5, 68,221,220,220,
+162,164, 82,105, 75, 83,215,149,150,150,202,229,114,121,200, 63,252,121,236, 9,224, 71, 0,190, 85,126, 79, 2, 48, 29,192,185,
+215,253,131, 96,128,239, 12, 76, 96,128, 47, 0, 64, 11,124,159, 13,108,142,254, 27,249, 24, 58, 58, 58,198,240,249,124,207,210,
+210,210, 82,133, 66,209,194,218,218,250,177, 76, 38,147,233,245,250, 7, 57, 57, 57, 61,107,186,150,148, 79, 74,169, 21,109, 1,
+235,100, 96, 24, 75,211, 83, 5,192, 6, 53,199,109, 50,212,224,230, 44,112, 59, 9, 47,150,231,154, 11, 96, 99, 29,143, 91, 96,
+193, 95,129,215,154,117,216,186,188,126, 64, 48,128,158,157, 58,117,114, 46, 45, 45, 69, 82, 82, 82, 54,128, 24, 0,209,134, 79,
+242,155, 72, 41, 77,211, 43, 87,175, 94, 61,123,234,212,169,198,197,160,227,226,226,224,239,255,106,140, 80, 30,141,198, 23,142,
+158,117,186, 17,159,140, 78,189, 63, 52, 16, 45, 26, 40,149, 35,164, 79, 96,125,147, 96,109,107,107,187,148,162,168,161, 52, 77,
+215, 90,105,112, 28,199, 18, 66, 34, 11, 10, 10, 22, 3, 80,212,229,143,100, 82,145, 78,207,178,213,254, 7,159,199, 99, 75,203,
+212, 38,195, 94,216,217,217, 93,166,105,186,121,229, 5,179,129,151, 23,208, 54,117, 76,175,215, 63,203,205,205, 53,135,132,138,
+105, 62, 51,157,162,152, 62,160,185,214, 0, 5, 10,116, 50,199,106,206,112,122,237, 90, 0,170,215, 33, 89,174, 77, 90, 92,156,
+185, 48,162,113,194,189, 36, 44,152, 50, 18,223,253,184, 13,243,167,127,138,181, 91,118, 97,250,248, 17,240,241,241,173,177,214,
+229,192, 44, 95, 56,109,104,239,240, 13,123,131,230, 79, 30, 42, 10,223, 16,217, 99,193,148, 97,194,229,235,247,246, 88, 48,229,
+ 35, 81,248,250,189, 65,243,167, 13,149, 44,223,184,143, 3, 48,170, 62,137, 28,225,233, 86, 74,233,245,213,246,140, 9,159,175,
+222,245, 32, 83,246,159,120,163,199,142, 29,235,167, 84, 42,111,141,236,211, 33,162,125,235, 70, 25,213,157,147,151,149,209,232,
+241,253,216, 48, 1, 35, 9,248, 32,108, 91, 92,141,242,128, 72,212, 60, 41, 41,201,147,227, 56,176, 44, 11,189, 94,111,220,106,
+ 52, 26,244,236,217,243, 77, 77,156,233, 15, 96,105,249,203,138,112, 0,123, 95,195,150, 21,159,207,159, 41, 20, 10,131,245,122,
+189, 55, 0, 8, 4,130,123,106,181, 58, 90,175,215,175, 6, 80, 82, 71,123,107, 50, 50, 50,124,172,172,172,160,213,106,141, 11,
+208,243,120, 60, 47,119,119,247, 13, 42,149,202,243,117,111,222, 25,152,208, 45, 40,104,237,152,217,179,121,202,152, 24,172,221,
+186,117, 13,138,139, 1, 96, 67,109,215, 10,133,194, 83, 52, 77,123,212,229,255, 56,142, 75,213,104, 52,239,214,229, 26, 62,159,
+239,153,153,153,233,228,230,230, 6,133, 66, 1,153, 76, 38,171,216,127, 29, 68, 3, 84, 95,160,167,158,199,155, 97,239,224,208,
+227,214,233,211,178,182,109,219,210, 60, 30,111, 62,204, 15, 82, 45, 2,176,130, 16, 34, 49,180, 23,107,187,116,233,210,149,162,
+ 40, 61, 0,194,113, 28,125,237,218,181, 17, 28,199,241, 13,117,222, 10, 0, 91, 1,168, 45, 60,192,130,255, 7, 53,107, 75, 93,
+137,214,113, 0,193,157, 58,117,146, 12, 31, 62, 28,193,193,193,240,244,244,132, 88, 44, 46,175,196,243,242,156,111,223,190,253,
+ 81, 76, 76,204, 71, 71,143, 30,197,221,187,119,149, 0,254, 4, 80,237, 75,253,118,104,208, 84,177,149,104, 29, 0,228, 60,203,
+147, 63,123,242,124,157, 92, 46, 95, 1,160,114,136,240, 22,163, 70,141,154, 53,109,218, 52, 68, 69, 69, 97,215,174, 93, 80,171,
+213, 80, 40,106,224, 47,101,207, 81,112, 62, 2,144,165, 0,105,209,128,212, 9,144, 57,215, 59,167,108,109,109,151, 78,159, 62,
+125,134,143,143,143, 49,138,185, 78,167,131, 94,175,135, 78,167, 67, 65, 65, 1,102,205,154, 85,222,208, 18, 2,142,227,112,226,
+196,137,169,227,199,143, 71, 65, 65,193,204,234,108,118, 9,104,114,147,166,232,198, 21, 90, 13, 97,217,103, 87,111, 63,235,168,
+103, 89,158, 74,165,173,118,165,114,177,152,169,145,228, 9, 4,130,198,119,143, 28,113,162,133, 66, 16,150, 5, 56, 14,132,227,
+ 12,217,105,248,144,242,223, 8,203,129,232, 88,112,122, 14,122,165, 26,129,147, 38,153,147, 21,221, 4, 66,201,174,143, 63,159,
+237,210,185, 75, 23, 65,211, 38,110,208,179, 28, 30,165, 60,115,185,117,243,106,247,200,237, 27, 38,106,148,138, 17, 0,234, 21,
+103, 75, 40,109,112,122,253, 79, 63, 55,190,113, 59, 1,231, 46,196,224,236,249,104, 0,192,169, 11,151, 43, 8,119,173, 69, 5,
+125, 73,187,233,227, 6,138, 34,214,239, 22, 76, 31, 55,136,247,221,250, 61,130,105,159,126,192,139, 88,183,139,153,246,233, 7,
+188,136, 31,119, 49,211,198, 13,228,133,175,253,213, 15,128, 45,128, 2, 83,198, 76,149, 17,165,215,139,254,253, 56,155, 7, 0,
+ 57,155, 54, 65,247,252, 57,220, 22, 47, 6, 0,124,220,194,217,236,161, 9, 7, 7,135,155, 2,129,160,113,109,231,233,116,186,
+ 90, 73,240,216,177, 99,253,149, 74,229, 77,189, 94, 79,248,124,126,216,200, 65,239, 28,234,219,195, 63,175,242, 57,113,113,119,
+236,151, 47, 63, 50,112,239, 45, 5,249, 40,192,250, 86,212,202,177, 29, 67,231,108,187, 83, 67,131, 76,171,213,106, 60,120,240,
+ 0,149, 23,121,175, 4,182,158,175, 20, 13, 96,173,189,189,125,231,188,188,188,143, 1, 44, 40, 46, 46,246,227,241,120,176,179,
+179, 91,160,209,104, 30,217,216,216,252, 82, 84, 84,116,217,160, 26,153,187,100, 64,207, 6, 13, 26,236, 56,120,240,160,109,135,
+ 14, 29,232,220,220, 92, 52,107,214, 12,249,249,249,129, 49, 49, 49, 1,227,198,141, 27,167, 80, 40, 70, 27, 58,131,230,162,141,
+ 84, 42, 37, 99,198,140,161, 88,246,197,237,254,250,235,175,120,183,173,190,165, 99, 67,105,153, 74, 67,138,206, 61,176,249, 23,
+195, 48,127,166,166,166, 22,213, 53, 51, 24,224,139, 49,179,103,243,172,158, 62,133,213,157, 59,248,184,184,152,255, 93,185,186,
+ 85, 43,209,162,105,218, 99,199,174,223, 60,133, 66, 33,244,122,189,145, 12, 86,212, 81, 58,157, 14, 90,173, 22, 58,157, 14, 44,
+203, 66,167,213, 33,252,155,239,235, 93, 23, 74,165, 82,169,171,171,107,182, 84, 42,149,190, 38,185,116,207,167,233,207,219, 7,
+ 4,140, 95, 60,112,160,248,250,245,235, 98,154,166,161,215,235,177, 98,197, 10, 61, 33,164,161, 15,208,224, 46, 80, 92, 87,219,
+ 34,145,136,191,125,251,246, 17, 66,161, 16, 0,160,209,104,208,182,109, 91,202,210,230, 91,240, 31, 36, 91,175,168, 92, 53, 17,
+173,247,138,139,139,193,178, 44,172,173,173,193,227,189,220,238,219,219,219,163, 79,159, 62,232,217,179, 39,134, 15, 31,142,187,
+119,239, 74,134, 15, 31,222,199,148,177,145,179, 67,209,196,211,217,208,152,112,174,151,142,221,142,248,245,235,125,142, 89, 89,
+ 89,179, 43,157, 54,110,194,132, 9, 84, 94, 94, 30,134, 14, 29, 26,163, 86,171, 7,160,134,151,143,229,240, 44,100,248,199,224,
+ 8, 37, 89,125,237,103, 74,163, 82, 18,154,166,149, 21, 67,135,245,201, 37,138,162,134,186,185,185, 97,247,238,221,208,104, 94,
+ 13, 23,214,160, 65, 3, 36, 38, 38,190, 80,213,120, 60,116,233,210,133, 71, 81,212, 80, 0, 51,171,183, 73, 55,190,116,227,169,
+ 83,197,126,104, 31, 95,166, 75, 0,157,157,153, 93, 74, 0, 80, 11, 23, 46, 52, 18, 55, 0, 88,186,116,169, 57,233, 4, 45, 16,
+ 32, 39, 58,250, 69, 69,204,167, 65, 51, 20, 40, 1, 64,243,203, 71, 81, 65, 0,194, 2,156, 30,224,116,128,216,181,137, 57,217,
+ 16,216,200,221, 51,106,249,170,141, 13,213, 58,130,221,135,207, 33, 37,229, 9,120, 52,141, 22, 45, 61,241, 78,175, 30,130,128,
+ 78, 93,155,124,191,100,246,209,204,180,135,239, 1,184, 94,231,140,230,136,184,165,187, 3,126,249,245, 22, 28,109,173, 48,116,
+224,251,144,136, 69,248,238,199,223,240,205,252, 41,240, 57,211, 49,121, 0, 0, 32, 0, 73, 68, 65, 84,108,225,129,205,107,190,
+ 53,121,185,141,141,205, 50,111,207,150, 30, 27,183, 31,131,183,151, 23,111,227,142, 99,240,246, 49,108,125,189,121, 27,119, 28,
+131,143,175, 15,111,227,142, 99,240,243,109,211,244,166,252,218,178,252,252,252, 41,166,243,179, 74, 25,189, 83, 94, 70,130, 18,
+206, 88,105, 63,157, 56, 17, 0,140, 68,171, 46, 16, 8, 4,141, 51, 51, 51,157,106, 59,175, 54,213,192,160,100,221,212,235,245,
+120,254,252, 57, 85, 88, 88, 72, 26, 54,108, 56,240,228,230, 5, 7,223, 13,242,207, 7,128, 59,119,238,216,133,135, 47, 31,184,
+231,102, 49,148, 87,215, 83,255, 62, 18,205,125, 60, 32,248,230,225,136,177, 1, 48, 44, 9, 81, 21,106,181, 58,165,125,251,246,
+196,240,189,145, 72, 36, 98,170, 60,111,110,173, 90,181,122, 69,181, 54, 99, 72,113,237,149, 43, 87,166,248,248,248,192,203,203,
+235,114,231,206,157, 27,200,100, 50,156, 60,121, 18,222,222,222,190, 13, 26, 52,184, 22, 25, 25, 41,152, 55,111,158,255,214,173,
+ 91, 1, 96,170, 25,217,217, 59, 36, 36,100,119, 84, 84,148,152, 97, 24, 40,149, 74, 36, 38, 38,194,198,198, 6, 66,161, 16, 31,
+124,240, 1,175,123,247,238,246,189,122,245,218,159,156,156, 60, 2,117,152, 1,165, 82,169,200,130, 5, 11, 32,149, 74, 33,149,
+ 74, 33,147,201, 32,147,201, 96, 37, 6,181,105,186,187,100,218,150, 66,201,204,197,155, 34,118,108, 92,114,161, 73, 19,238,171,
+244,244,244,194,186, 62, 11,202,152, 24, 88,221,185, 3, 84,122,119,205,133,141,204, 14, 97, 97, 97,181, 41, 82, 96, 24, 6,221,
+186,117,171,213,158,157,157,221, 1, 62,159,255, 82,207, 84,175,215,139,195,194,194,216,228,228,100, 25, 77,211, 50,142,227, 16,
+ 22, 22,198,234,245,122,177,147,147,211,101,142,227,178,115,115,115, 7,215,100,183, 23, 32,190, 12, 12,162, 4,130,153,174,110,
+110,205,130, 91,180,144,158, 61,123,150, 7, 0, 30, 30, 30, 68, 46,151, 23, 30, 62,124, 88,193, 7,126,242, 32,100,123, 29, 72,
+150, 26,192, 92,154,166,215,138, 68, 34,126,211,166, 77, 83, 23, 45, 90,116,197,160,144,130, 16, 66, 55,109,218, 52, 80, 34,145,
+120,168,213,106, 61,202,135, 14, 45,106,214, 63, 0,132,144,128,114,222,110,132, 6,128,176, 66,192, 47,111,237,224, 80,229,119,
+ 0,200, 53,116, 20,157, 77,236,231, 1,184, 11,160, 13, 0, 39,195,177, 27, 20, 69,229,215, 35,153,166, 21,173,168,168, 40, 99,
+ 23, 54, 52, 52,212,216,176, 88, 91, 91,227,198,141, 27,160, 40, 10,214,214,214,104,208,160, 1,108,108,108, 80, 92, 92,140,187,
+119,239, 34, 41, 41, 9, 79,159, 62, 5, 69, 81,104,209,162, 5, 42, 30,246, 74, 48, 86,112,191,255, 16, 5,177,149, 8, 20, 5,
+116,120,203, 15,126, 61,219,162,211,245,199,211,111,158,165,182,200,229,242, 7, 0,248,109,219,182, 29,215,165, 75, 23,172, 90,
+181, 10,106,181,122,149, 9,146,101,180,121,241,174,190, 35, 0,184,186,186,206,217,121,242,145,116, 84,223,150,101,114,185,124,
+101, 61, 50,231,165,138, 56, 55, 55,215,236,181,248, 56,142, 67, 65, 65, 65,141, 54,171, 42, 4,171,215,174,111,168, 40,202,198,
+215,223,237,132, 78,167,195,236,217,179,193,113,156,241, 83, 88, 88,104, 86, 58, 9,203,190,170, 29,208,229,163,167, 20, 31,112,
+ 31, 86,206, 43,210,118,175, 7, 69, 0,138, 5,240,234,125, 85,109,132,196, 60, 70,178,103,201,119,235, 26,198, 38, 61,195,225,
+115,177,208, 22,103, 64,126,231, 96,185,228,216,109, 4,246,170,121,232,236,215, 18, 51, 22,126,111,251,229,140,209,123, 52, 74,
+133, 23, 94, 30, 70, 60, 91,251, 75,195,226,235,101,203,176,101,221, 42,124,191,106, 29,138,139, 10, 33, 16, 56, 24, 42,122, 22,
+ 44,203,214,124,239,132,244, 13,155,254, 9,245,221, 79, 7, 16,232,227,138,253, 39,175, 35,168,189, 7, 14,158,190,137,158, 1,
+205,112,248,108, 44,222,234,220, 18,199,163, 19, 48, 99,194, 8,106,196,169,173,125,235, 82, 70,107,214,172,111,168, 40,206, 70,
+212,183,219,241,124,195, 6,164, 78,153,130, 64,195, 57,215, 41, 10, 76,227,198, 0, 83,123, 25, 85,197,189,123,247,160, 86,171,
+171,235,153,195,219,219,187,214,114, 87, 42,149,183,244,122, 61,201,206,206,166,178,179,179, 33,147,201,168,196,196, 4,214,215,
+183,237, 32,146,180,239,103, 0, 8, 15, 95, 62,104,239,173, 98,148, 93, 94, 7,229,149, 31,193, 52,139,163,183, 44,157,160, 29,
+191,120,243,173, 74,239,232, 75,233,204,202,202,122, 47, 43, 43, 11, 0,208,188,121,243,164,228,228,228, 54, 21, 67,205,134, 33,
+ 68, 70,175,215,123, 86, 12, 39,234,245,122,168,213,106,244,238,221,155, 87,211,189,219,218,218,118,241,246,246, 70,108,108, 44,
+214,173, 91,103, 23, 18, 18,130,135, 15, 31,130,162, 40, 44, 95,190,156,242,241,241, 17,228,230,230,226,221,119,223,197,129, 3,
+ 7,186, 21, 23, 23,215,150,159,214, 50,153,108,235,209,163, 71,197, 52, 77, 67,161, 80,128,227, 56,116,239,222, 29, 52, 77, 35,
+ 33, 33, 1, 11, 23, 46,196,129, 3, 7,112,232,208, 33, 73, 64, 64,192,214,178,178, 50,111,188, 60,172,111,170,140,136, 74,165,
+ 34, 34,145, 8, 34,145, 8, 98,177, 24, 98,177, 24, 66,161, 16, 37, 42, 96,252,234, 84, 53, 79,236,192,249,182, 15,106,249,201,
+180,229,244,202, 69,159,158, 7,112,216,220,103, 30, 40,247,201, 90,251,219,111,235, 62, 46, 42,162, 1,224, 23,138,226,180,132,
+124,111,206,251, 14, 0, 37,170, 34,120,180,104,140,253,123, 14, 97,200,176,129,213,146, 44,129,128, 1, 35, 16,160,129,157,172,
+ 86,155, 12,195, 56, 39, 37, 37,217, 11, 4, 2, 16, 66,192,178, 44,180, 90,109,246,151, 95,126,233,216,175, 95, 63,235, 19, 39,
+ 78,208,253,250,245,227,108,109,109, 75,175, 95,191,254, 92,175,215,219,247,232,209,195,164, 77, 41,224,167,178,105,181, 86,200,
+211,251, 69, 44,152, 44, 26, 61,122, 52,239,147, 79, 62, 65, 90, 90, 26,198,141, 27,167, 58,115,230,140, 38, 75, 46, 63, 44,228,
+184,245, 90, 32,206,220, 58,185, 10, 54,250,249,249,117, 56,120,240,224,167, 97, 97, 97, 55,231,204,153,243,117,229,131, 43, 86,
+172, 88,118,252,248,113,143, 65,131, 6,237,184,115,231,206,198,186,212, 75,175,219,118, 88,108,190, 30, 76,113,145, 10,113,148,
+162,168,168, 74,117,118,104,197,126, 88, 88,216,130,240,240,240, 68,138,162,162, 42,255, 94,113,158,161,179, 24, 85,221,190,225,
+ 90,187,249,243,231,183,141,136,136, 88,222,181,107,215,221,151, 47, 95,126, 2,160,174, 68,171,102, 31,173,138, 27,170,124,147,
+ 85, 26, 53, 20, 23, 23,163,184,184, 24,233,233,233,216,180,105,147,225,133, 22,128,207,231,131,207,231, 27,253, 25, 76,225, 92,
+212,159, 63, 2,248,177, 67,135, 14,130,248, 43,145, 39,190,216, 50,237,237,142,189, 59,240,110,157,139,255, 16,229,235, 17,190,
+ 55,102,204, 24, 7, 0,216,190,125,123, 46,128, 19,255, 33,214, 28,249,224,193,131, 25,174,174,174, 70, 31,149,202,195,135,122,
+189, 30, 98,177, 24, 21,190, 44, 42,149, 10,155, 54,109,210, 19, 66, 34,107,176,137,228,196,243,120,144,120,161,252, 58,142, 3,
+199,190,184,126,201,146, 37, 32,132, 24, 27,251,137, 6,229,164, 86,146, 87, 93,158,147, 42,219, 42,191, 19,150,173,101,120,130,
+153,246,225,232, 41,174, 28,197,199,145,243,183, 33, 16, 8,192, 85, 82, 51, 5,188,242,222,114,226,195, 76,184, 57,251, 98,192,
+136, 9, 46, 7,119,172,159,166,215,170,190,171,107, 94,123,249,117,197,244, 25, 51,240,243,150, 45, 88,184,120,153,145, 1,232,
+ 89, 22,250, 90,211, 73,211,189,187,183,133,190, 36, 19, 60, 30, 15,111, 5,182, 4,143,199, 67,159,174,173,193,227,241,240,110,
+119, 47,240,249,124,244, 13,242, 65,171, 86,173,192,231,243,233, 90,202, 29,201,137,231,240, 32,241,143, 74,164,151,128, 0,208,
+202,229,175,156,175,147,203, 65,220,237,235,250,108, 97,220,184,113,133,233,233,233,218,170,199,154, 52,105,194,196,196,196, 52,
+ 52, 49,108,103,132, 68, 34, 9,224,243,249,183,242,243,243, 57,169, 84, 74,115, 28,203,249,250,182,229,157,220,188,224, 96,197,
+ 57,243,231, 47, 56,248, 81, 64,131, 65, 59, 35,163, 8,211, 52,136,162, 4, 34,253,231,139, 55, 51, 2, 70, 18, 0, 40,205,233,
+ 60,208,106,181, 26,247,239,223, 71,109,233, 33,132,212, 56, 76, 83, 80, 80, 48,198,219,219, 59,230,199, 31,127,180,163, 40, 10,
+ 23, 47, 94, 4,143,199, 51,126, 30, 63,126, 12,154,166,241,197, 23, 95,104,139,139,139, 63,171, 45,109,124, 62,127,198,254,253,
+251,109,132, 66, 33, 20, 10,133,241,189,225,241,120, 72, 74, 74,194,202,149, 43, 49,102,204, 24,164,165,165,193,205,205, 13,179,
+103,207,182,138,136,136,152,161,213,106,151,153, 81, 68,113, 26,141,166,163, 84, 42,133, 88, 44, 70, 5,225, 2,128,211,137,130,
+ 4,165, 82,217,206,222,190,204,197, 49, 58,234, 72,183,144, 1,254,246,142,174, 93,229,114,121,157,150,206,122, 4,108, 73, 97,
+217, 47,223, 59,120,208,233,210,193,131,220,213,163, 71,159,137, 20,138,205,102, 63, 67, 58, 26,169,143,159, 33, 32, 32, 0,183,
+110,221, 66, 64, 64, 64,101,210, 4,161, 80, 8,134, 97,192, 48, 12, 28,108,205,114,161, 32, 52, 77,227,210,165, 75, 96, 89, 22,
+ 26,141, 6, 26,141, 6, 62, 62, 62,249, 23, 46, 92,176, 2,128,199,143, 31,147, 81,163, 70, 21, 94,187,118, 13,237,219,215,188,
+158,186,138,162,206, 45, 89,254,131,205,119,107,182,194,198,206, 25,209,209,209,236,201,147, 39, 21, 20,144,252, 32, 49,113,213,
+ 0,224,120, 36,160,173, 75,158, 57, 59, 59,199,240,120,188,166,149,127,203,203,203,179, 29, 60,120, 48, 10, 10, 10,222, 31, 60,
+120,112,144,161, 78,200,216,183,111,223, 40, 0, 16, 10,133,160,105,154,133, 5,255, 85,168,141,139, 84, 38, 74, 85, 9, 87,120,
+120,120,104,213,223, 42,147,170,234,190, 87,190, 54, 34, 34, 98,121, 37,219,202,122, 36,191,118, 31,173,168,168, 40, 82, 13,131,
+ 52, 27,181, 17,173, 10,196,198,198,234,220,220,220,126,126,112,251,233,219, 45,253, 90, 64, 34, 19,189, 3,224, 71,145, 72, 52,
+107,244,232,209,184,122,245, 42, 18, 18, 18,126,197,107,206,194,105,219,182,237, 41,145, 72,228, 97, 98,152, 36, 53, 33, 33,225,
+ 93, 19, 13,195,226,163, 71,143,162, 38,103,248,243,231,207, 87,110,148, 42, 59,195, 87,255, 96,112, 4, 58,173, 14,165,101,202,
+ 23,141,184,129,104,149,150,150, 98,216,176, 97, 47, 41, 90,207,159, 63,175,245,254, 40,138,194,202,195,135,113, 38, 50, 18,239,
+251,251,227,192,245,235,136, 24, 61, 18, 94, 30,141, 64, 88, 10,132, 2,210,118,173, 71, 94,113, 9,126, 63,119, 9,249,138, 50,
+124,220,163, 7, 60, 27, 56,212,108, 87,192,244, 9,236,210,149, 57,123,249, 46, 4, 2, 62,104,112, 32,186, 50,184,121,247, 2,
+143,166, 97,227,220, 12,140, 64, 0,129,128,143,199,233,185,240,110,219, 73, 24, 37, 20,247,169, 15,209,106,226,209, 12, 44,203,
+ 98,204,152, 49,216,189,123, 55,236, 93, 60, 96,211,164, 45,190, 89,181, 5,239,247,238, 81,235,253, 87,244,224,249,124, 62,120,
+ 60,222, 43,219,138,239,230,168,147,132, 35,208, 86, 45, 35,142, 0,132,160,241,183,223,162,241,183,223,226,186,225, 63,125, 74,
+ 75,161, 84, 42,129,206,190,117, 34, 89, 26,141, 6,233,233,233,218,172,172, 44,231,106,142,103,107, 52,154, 90,137,205,182,109,
+219,226,198,142, 29,219,209,206,206,238,102,220,157, 59, 58, 63,127,127,193,137, 77, 11, 14, 85, 12, 27, 2,128,191,191,127,254,
+130, 5, 11, 14,141, 26, 26, 58,112, 99,216,112,118,210,178, 29,124,145, 68,210, 49,116,206,182,184, 93, 67,135,214, 62, 54,163,
+ 86,167,248,249,249, 17,115,238,171,172,172, 44,171,134,195,253, 1, 44,237,208,161, 67,131,144,144, 16,196,196,196, 96,200,144,
+ 33,106,173, 86,251, 0, 0,250,245,235,215,250,247,223,127, 23,222,189,123, 23,142,142,142,130,212,212,212,173,168,197, 65, 94,
+ 40, 20,246,234,212,169, 19,173, 86,171, 95, 33, 89, 17, 17, 17, 24, 49, 98, 4, 90,183,110, 13,142,227, 80, 82, 82,130,144,144,
+ 16,193,186,117,235,122,153, 73,180,166,123,121,121,173, 68,249,172,195,202,117,225, 61,195, 16, 20,242,242,242,178,110, 95, 59,
+151,216,163,247,224,142, 77, 91,181,117, 77,136,187, 85,163, 65, 39, 39,167,249, 52, 77,127,196,113, 28,175,184,184, 56,253,182,
+ 70,211,202,199,195,195,185,251,192,129, 40, 18, 8,120,107,207,157,163,179, 21, 10, 43, 0,102, 13, 65,170,116,165,240,104, 81,
+238,234, 55,100,216, 64,220,186,117, 11, 31, 14, 31, 4,134, 97,192,231, 11,202,223, 77,166, 92,209,106,232,208,192,172,103, 83,
+167,211, 25,235,240, 10, 63, 47,173, 86,139, 10,215, 44,169, 84,106, 60,166, 86,171, 65, 81, 84, 77,207, 6, 29,210,179, 59, 46,
+199, 38,235, 63,251, 98,173, 90,144,119, 43,194,133,227,182, 61, 3,178, 95,163, 58,247,220,187,108,145,147,164,129, 13, 88,157,
+ 14,190, 3, 63, 52,190, 39,215,126,217, 40, 1,199, 73, 10, 83, 83, 48, 53,242,232,155, 94, 51,215,130,255, 0,106,227, 34,149,
+137,210,235,130,162,168,168,176,176,176, 5, 0, 72, 88, 88,216,130,138,253,240,240,112, 37,128,140,122,146,173, 87, 84, 46,254,
+155, 32, 89, 21,195, 11, 53, 33, 36, 36,100,170,181,181,245,186,138,253,244,171, 25, 72,191,154, 1,239, 54,190,221, 59,248,119,
+ 44, 26, 49, 98, 4,236,237,237, 49,103,206, 28, 2,224,215,186,254,255,227,228, 68, 43, 0,196,213,213,117,142,161, 66,246,191,
+126,253,186,227,141, 27, 55,208,169, 83,167, 23,210,189, 86,139,160,160,160,154, 76, 41, 12, 78,237, 51,223,156, 74,198, 65,171,
+213,162,172, 76, 9,141, 70, 11,189,142,131, 94,175, 71,128,175, 53,118,108, 9, 43,255, 77, 95,161,158,149,171,102,141, 93,172,
+ 97,109, 37,208,209, 52,165,188, 25,151, 85,109,141,169,209,104, 16,151,154,138, 59, 79,159, 2, 0, 6,132,215,236,248,186,227,
+ 92, 12,124,124,124,106, 75,109,203,198,110, 46,200, 60, 19, 87, 94,121, 43,211,113,227,207,189,176,182,182, 2, 0,248, 6,127,
+ 12,134, 41, 39, 90,165, 74, 45, 28,218, 52, 1, 69,136,201,176, 0, 82, 91,151, 83,124, 70,236, 65, 88, 14,132,112, 32, 28, 11,
+ 66, 56,240, 4,140,116,234,196, 79,193,113, 44, 2, 3, 3, 65,241,120, 96,117,106, 12,237,223, 7, 5, 69, 10,216, 55, 52,175,
+145, 96, 24, 6,193,193,193, 18, 83,199, 31, 62,124,168,172, 76,204,106, 46, 35, 29, 74, 75,149, 80,171,213,208,106,244,208,234,
+244, 96,155, 51,248,250,203,145,208,107,245, 40, 27,222, 21, 90,157, 30,220,140, 65,208,106,116, 72,147,210,180,159,183,131,142,
+ 6,165,188,125, 47,167, 65,109, 68,171,130, 28,152, 66,117, 62,129, 38,200,214,157,177, 99,199, 6,248,249,251,223,250,168,183,
+255, 15,241, 9,137,153,241, 9,137,175,156,231,209,218, 63,101, 82,196,238,217, 2, 70, 18, 16, 58,167,230, 89,135,149, 81,121,
+ 24,241, 53,177, 64,161, 80,248, 89, 89, 89, 33, 57, 57, 25, 60, 30, 15, 20, 69, 61, 4,224, 7, 0,174,174,174,143,248,124,126,
+ 11, 30,143,135, 13, 27, 54, 80,124, 62,191, 93,215,174, 93, 23,168, 84,170,189, 53,116,232,188,173,173,173, 95, 82,179, 24,134,
+ 65, 88, 88, 24, 70,141, 26,101, 36, 89, 12,195, 96,219,182,109,232,216,177, 35, 52, 26,141,183,153,233,189, 1,160,135, 25,138,
+ 31,101, 32,231,181,146, 81,189, 94, 63, 54,239,163,143, 90, 33, 58, 26,221, 91,180,240, 9, 8, 8,128, 86,251, 66,208,105,209,
+162, 69, 19,133, 66,145,165, 84, 42,255,141,242, 48, 4,183,107, 36, 69, 42, 14,169,143,203,221, 79,111,221,186,133,192,192, 64,
+163,130, 85, 89,205, 98, 24, 6, 18,161, 85,157,136, 22,199,149,215, 75, 10,133,130,142,142,142,118,240,242,242,162, 0,192,203,
+203,139,186,125,251,182,157, 84, 42,205,109,217,178,101,109, 29, 96, 6, 0,122,189, 51,152,127,230,228,113,153, 30, 88,150,197,
+227, 45,227,215, 90, 71, 18, 29,203,113, 38,157,238, 37, 13,108,176,109,236, 48, 0,192, 87,189,251, 26, 59, 91, 39,151, 46,128,
+ 64, 32,192,219,115, 22,188,242, 46,113, 28,199,131, 5,255, 40,146, 85,157,162,245,122,109,243, 11, 69, 43, 60, 60, 60, 49, 60,
+ 60,252, 21,117,172,142,168, 93,209,170, 44,221,213, 21, 21, 47,171, 41,172, 90,181, 10,237,218,181,171,177, 33, 90,183,110, 29,
+118,238,220,185, 10,192,227, 58, 75,142,111,119,240,197,234,131,137, 45, 90,251, 82, 0,176,108, 70,127,186,180,180, 20,151, 46,
+ 93,130,141,141, 13, 30, 62, 52, 59,236,151,181,141,141,205, 82,154,166,135,242,170,206, 0,168,158, 96,178, 28,199, 69, 22, 21,
+ 21,153, 12,239, 64, 8,160,213,233, 81, 90,166,130, 70,163,193,140, 47,214,215,154,136,112,128,210,106, 20,252,224,158, 93, 37,
+166, 20,157,192,118,189, 48,121,180,213, 43,141, 55,143, 6,104, 26,104, 31, 88,174,184,220,190,158, 8,142, 3, 88, 14,112,112,
+178,197,175,187,126,168,145,228,235, 89,206,208, 59,102, 81,162,102,225,221, 37, 20,207,238, 69, 27, 21, 36, 33, 83, 62,100,204,
+ 8, 4,224, 8, 85, 30,245,193, 84,173, 43,148,120, 20,200, 31,123,110,137,138,199,248,208,118,216,119, 54, 14, 31,246,246,195,
+133,107,119, 17,210,217, 7,137, 15,158,194,215,179, 41, 54,108,141, 4, 33, 80,252,180,250,155,172, 23, 13,154, 62,213, 28, 69,
+235,234,213,171,202,170, 42, 86,229, 45,169,189, 61, 4, 33, 47, 20, 45,165, 74,141, 57,243,205, 10,189, 83, 94, 70, 61,186, 72,
+204, 57,185, 38,197,202, 28, 34, 86, 85,217, 66, 45,225, 89,154, 3,232, 8,204,251, 79, 86,156, 44,203,226,216,177, 99,198,242,
+168,174, 28, 43,151,157, 25, 36, 7,169,169,169, 72, 76, 76, 68,151, 46, 93, 80, 84, 84, 4, 1, 77, 99,118,124, 60,124, 70,143,
+134,134, 97,192,113, 28,132, 66, 33, 38, 76,152, 96,118,126,214,177,118, 54, 56, 94,179,181, 25,255,161,107,215,174,173,146, 75,
+ 75,145,152,148,132,222, 75,150, 0, 0,142, 31, 63,254,210, 51, 49,107,214, 44,225,221,187,119,199,221,188,121,115, 92,102,102,
+230, 42, 0,179, 77,214,179, 68,109,244,209,250,104,228, 16,180,242,106,142,157,191,237, 50, 30,159, 53,119, 58, 4, 2, 6, 2,
+ 70,128,134, 54, 13,205,186, 27,157, 78,103, 36,173,101,101,101,244,241,227,199, 27,247,233,211,135,153, 62,125, 58, 5, 0, 59,
+119,238,164,127,252,241, 71,217,153, 51,103,152, 70,141, 26,201,107, 81, 8,138, 51,242,212, 34, 0,112,119,119,199,250,205, 71,
+232,126,253,250, 97,250,244,233,208,233,116,216,184,177,252,189, 26, 49, 98, 4,180, 90, 45,246,239,223, 95,241, 30,215,168, 70,
+233,181,218, 87,158, 27,138,162, 32, 16, 8,192, 8, 25,128,227, 64, 81,148,108,197,138, 21,203, 18, 19, 19, 59,121,121,121, 65,
+173, 86,143, 70,249,228, 15, 75, 28,173,255, 50,178, 85, 19, 23,169,206,215,202,160, 74,153, 66, 78,101,191, 45, 83, 68,173,178,
+207, 22,234, 55,129,194, 60, 31,173,234,192,227,241,106, 85,171, 42,166,234,214,132, 89,179,102,193,218,218,218, 84, 3, 68,226,
+227,227,239,202,229,242, 45, 0,214,215,171,112,206,197, 38, 46,157, 57, 72, 1,195,216,106,195,134, 13,115,223,122,235,173, 18,
+ 0,218,189,123, 95,238, 32,171,213,106,147, 13,184,141,141,205,210, 95,126,249,101,218,192,129, 3,233,170, 33, 6, 42, 15,239,
+ 85,124,116, 58, 29,246,238,221, 59,109,222,188,121, 40, 42, 42,154, 89, 83, 35, 94, 86,170,132,210,224, 8,253, 40, 97,159,185,
+149,186,201, 67, 86, 13, 93,209,184,185,159,201,198,132,102,202,125,136,156,221, 95, 52, 96,214,214, 98,176, 53,216,164, 40,250,
+241,211,180,204, 70, 77, 92,236,240, 40, 61, 7,206, 77,219,161, 32,227, 69, 62,240,249, 60, 8, 12, 67,135, 13, 27,200,144,243,
+252, 57,104,154, 87, 35, 49,254,230,247, 88, 92, 75,120,138,253,103,111, 67,171, 42,197,234,237, 39,161, 85,151, 64,171, 42,133,
+ 86, 85,190, 93, 62,239,115, 80, 20,178,116,234,210,214,117, 41,119, 62,159,143,206,157, 59,155, 36, 58, 25, 25, 25,102, 42, 90,
+196,168,104, 41, 85,117, 44, 35,243,122, 78, 53, 42, 86, 21,199,235, 75, 12, 42, 66, 62, 72, 36,146,142,219,182,153, 14,227, 80,
+ 29, 92, 92, 92, 78, 88, 89, 89, 53, 51,247,252, 58, 4, 47, 93,222,176, 97,195,165, 94, 94, 94,222,171, 87,175, 22,240,120, 60,
+188,253,246,219,173, 93, 92, 92, 82, 1,192,215,215,215,173,162,142,153, 52,105, 18,185,122,245,106, 66,121, 31,195, 52,132, 66,
+ 97,146,141,141, 77,199,144,144, 16, 20, 21, 21, 33, 61, 61, 29, 50,153, 12, 62, 63,252,128,248, 73,147,224,191,105, 19,232,183,
+222, 2, 69, 81, 16, 10,133,136,143,143,135, 68, 34, 73, 82,169, 76,134,124,235, 12,224,123, 0,221,241, 98,184,144, 0,184,132,
+242,176, 11,215,170,169,239,104, 0, 96, 57,174,182,194, 26, 57,103,206, 28, 20, 10, 4, 64,191,126, 96, 30, 63,134, 86,171, 69,
+151, 46, 93,140, 42,123,151, 46, 93,192,231,243,225,231,231, 7, 55, 55, 55,108,216,176, 97,100, 77, 68, 75, 85,162, 69,234,227,
+103,232,218,181,171, 81,185,234,215,175,159, 81,209, 18, 8, 4, 70,101,139, 98,107, 39,174, 20, 69,145,202,157,100,150,101, 41,
+ 62,159,207,159, 57,115, 38, 53,100,200, 16,162,209,104, 56,161, 80, 72,239,223,191,159,186,112,225, 2,191,180,180,180, 54,181,
+161,116,248,240,225, 78, 77,154, 52, 70,250,163, 68,236,219, 71,176,106,213, 42,196,196,148, 71,217, 72, 78, 46,159,184, 90,177,
+ 31, 18, 18,130,102,205,154,129,212,242,224,183, 29, 52, 20, 95,245,121,175,188, 62,105,230, 8, 1, 35,128,144, 97, 48, 39,233,
+153,177,172, 27,108,219, 45,140,136,136,248,208,203,203,171,124,104, 31,224, 91,226,104,253,119,161, 22,161, 39,167, 10, 73,210,
+ 84,218,207, 1, 64, 25,246,115, 42, 17,170, 28,138,162,110, 16, 66, 58, 85, 57,183,226,184,166,202,182,226,248,157,122, 36,191,
+ 98,173,195, 87,200, 87, 77, 61,226, 7, 87,174, 92,241, 12, 8, 8, 64, 90, 90,218, 43, 51,225, 42, 26, 46,153, 76, 6,137, 68,
+130,203,151, 47, 3,192, 3, 83,198, 46, 92,184,240, 35,202,163, 46,195, 48,108,208, 53,228,163, 94,151, 3,251,118,194,239,225,
+187,138,228,114,185, 31, 94,196,208,161,220,220,220, 70, 9,132,252, 97, 45,218,186, 7,131,227,190, 63,119,244,210,146,154,238,
+176, 69,107,223, 18, 0,202,138, 89,135,245,156,125, 8,154,166,135, 14, 28, 56,144,190,123,247, 46,134, 13, 27,134,157, 59,119,
+154, 60,119,212,168, 81,216,189,123, 55, 6, 14, 28, 72,207,159, 63,223,100,120,135,151,213, 18,205, 27,123, 40,147, 31,222,193,
+142,221,191,152,244, 65,114,114, 42,247,199,122,254, 60,215,248, 91,167,128,154, 71, 70, 56,189,230, 76,236,205,235, 93,187,245,
+124,155, 73,207, 46, 4,167, 87, 67,165,120,113,125, 89, 97, 54,136, 94, 5, 70,106, 7, 23, 7, 27,220,186,114, 90,163,213,168,
+206,212,100,115,218, 64, 95, 76,234,239, 13, 16, 14,131,102,255,138,168,245, 83,141, 61,232,160, 33,211,113,110,239, 90,179,125,
+252,170, 66, 32, 16, 32, 62, 62, 94,105, 74,205,226,241,120,230,196,228, 50,168,142, 58,148,149, 41, 81,166, 84,189,201,186,195,
+209,217,217,249, 39, 91, 91, 91,177, 9, 34,229,232,232,232,248,147,189,189,189,216,220,161, 67, 83, 36,203, 16, 87,235,230,216,
+177, 99,235, 68,182, 68, 34, 81,179, 7, 15, 30, 24,131,149,214,180,213,104, 52, 8, 9, 9, 49, 55,120,233, 81, 0, 79, 92, 93,
+ 93, 47,249,248,248,216, 60,122,244, 8,187,118,237, 98, 4, 2,129,123, 69,253,161, 80, 40,192,227,241,240,252,249,115, 29,128,
+ 79, 81,203,208,153, 90,173,142,142,142,142,110,223,191,127,127, 94, 82, 82, 18,120, 60, 94,121,186,186,118,133,255,166, 77, 72,
+152, 57, 19,193, 79,159, 66,165,213, 66, 44, 22,227,212,169, 83,218,178,178,178,104, 83,246, 36, 18,201,150,148,148, 20, 95,177,
+ 88, 12,173, 86, 11,142,227, 64,211, 52,197,231,243,131, 26, 54,108,184, 14, 64,167, 42,133,229,228,223, 41,164, 13,171,215,179,
+242,180, 71, 57,181,101, 64, 94, 94, 30,142, 30, 61,138, 46, 93,186, 32, 56, 56, 24, 25, 25, 25,120,252,248, 49,222,127,255,125,
+227, 57,119,238,220, 65,108,108, 44, 90,182,108, 89,187,162, 71,235,208,178, 77, 51, 48, 12, 83,174,230, 8, 24, 67,199, 71, 96,
+ 84,178, 24, 1, 3, 1, 95, 0,177, 68,108,182,162, 69, 81, 20,104,154, 6, 69, 81,144, 72, 36, 21,157,108,174,113,227,198,242,
+252,252,124, 87, 0, 60,137, 68, 2,150,101,107,236,180,112,132,120, 50,185,151, 51,103,207, 91,233, 20, 30,126, 22,103,207, 62,
+ 7, 77,211,112,117,117, 5, 77,211, 72, 73, 73, 1, 77,211,240,240,240, 0, 77,211,200,200,200,168, 32,137, 5, 48, 77,134,141,
+239, 13, 69, 81, 70,146,197, 8, 25,163,178, 5, 0,133,133,133,170,129, 3, 7,254, 91,173, 86,127,130,250,173,122, 98,193,223,
+ 24, 20, 69,221,248, 79, 92, 91, 7,244, 51, 16,171, 87,156,226,107,122, 24,223,239,214,173,219,166, 17, 35, 70,188,189,102,205,
+ 26, 88, 89, 89, 65, 46,151, 27, 27, 68,161, 80,136, 38, 77,154, 32, 63, 63, 31,155, 55,111,198,179,103,207,206, 3,152, 96,110,
+138,228,114,249,213,135,183, 31,228,133,124,216,205,222,183, 91,155,134,233, 15,158,117,145,203,229,151, 13, 36,235,215, 17,179,
+222,255, 36,100,112, 32, 24,161, 0,233, 15,179,112,238,232,165,255,151,194,228,241,120, 60,138,162, 48,108,216, 48,179,206, 31,
+ 62,124, 56,162,163,163, 81,211, 48, 35, 87,161,104,149,169, 80,170,124,115, 29,171,201, 83, 71, 97,242,212, 81, 70, 50, 97,206,
+208, 11, 0,184,185,237,169,129,104,105,215, 68,237,217, 60,190, 67, 96, 87,143,142,190,205,112,237,230,109,252,190,233,133,200,
+176,245,199,101,248,110,235,121, 52,113,182,133, 86, 93,138, 19,251,126,206,210,170,203,214,212, 83,148, 43, 39,183, 20, 5, 66,
+184, 58,221,123, 5,121, 18, 8, 4,104,219,182,173, 73, 69, 43, 63, 63, 95, 89,155,154,101, 44, 35,141, 14, 37,165, 74, 40,203,
+222, 24,209,242, 15, 10, 10, 58, 19, 25, 25,105,239,228,228,132,204,204,204,170, 68,203,191,123,247,238,103, 34, 35, 35,237,157,
+157,157,145,158,158,110,118, 88,145,106, 72, 22,114,114,114,168,130,130, 2,206,214,214,182, 78,100,139,166,105,168,213,106,220,
+187,119,207,220,191, 53,123, 54,151,141,141,205,182,221,187,119,219,228,230,230,130,199,227,225,222,189,123, 47,205, 58,172,248,
+252,250,235,175,204,160, 65,131,126, 41, 44, 44,172,113, 90,155, 94,175, 95, 53,106,212,168,113, 25, 25, 25,182, 78, 78, 78,144,
+203,229, 16, 10,133, 32,132,128, 10, 9, 65,143, 39, 79,160,101, 89, 72, 36, 18, 36, 39, 39, 99,203,150, 45,165,134, 80, 49,213,
+ 10,100, 20, 69,121, 50, 12,131,143, 63,254,248,165, 3,219,183,111,199,128,142,188,142,142, 54,252, 18, 61,196,234,108,201,123,
+ 39,120, 60, 30,229,223,249,173,214,157,123,246,107,123, 63,225,218,163,156,236,103,181, 85, 74, 58,141, 70, 3, 47, 47, 47,220,
+184,113, 3,103,207,158,197, 91,111,189,133,224,224, 96,196,197,197,225,244,233,211,136,141,141, 5, 69, 81,176,183,183,175,112,
+191,168,209, 7, 67, 83,166,199,243,204,188, 87,212,171,170,251, 12,195, 64,173, 52,111,114, 95, 82, 82, 18,110,220,184, 97, 12,
+ 45,195,227,241,244,163, 71,143, 6, 33,132,164,164,164,192,218,218,154,140, 29, 59,150,229,243,249,250,140, 12,243,252,131,173,
+172,172,224,233,233,249, 82,199,167,226,211,163, 71, 15,220,188,121, 19, 52, 77,131,207,231,195,201,201, 9,151, 46, 93,170,245,
+193,175, 32, 85, 21, 36,139,207, 8, 94, 34,125, 28,199, 41,226,226,226,198, 3,136, 51, 40, 89,128, 37,142,150, 5,255,127, 56,
+134, 87, 23,150,174, 85,209,122, 2,160,247,174, 93,187, 70, 30, 58,116,104,213,186,117,235, 28, 67, 67, 67, 81, 80, 80, 0, 15,
+ 15, 15,184,186,186, 34, 42, 42, 10,199,143, 31,207,101, 89,118, 54,128,234,164,159,222,168, 33,102, 77,198, 35,121,164,186,164,
+100, 82, 64,176, 55,206,239,189, 24,238,226,226, 50,129,199,227,205, 24,187,224,131, 79,122, 13,236,132,228,216, 20, 92, 61, 29,
+143,236,180,220, 90,109, 86,117,134,111,216,176,225, 56,169, 84, 42, 68, 53, 83,137,171,153,117,104,180,201,178, 44,171,209,104,
+176,103,207, 30,179,200,214,174, 93,187,160, 82,169,192,190, 58,190,106,180, 73, 56, 66,241, 5, 34,184, 53,241,130, 86, 91, 10,
+142,171,247,132, 74,163,205,138, 30,232, 35,161, 16, 78,185,185,184,118,237,154,121,148,187, 95,191,218,202, 72,165, 81, 41, 62,
+ 94,251,237,156,168, 41, 97,223, 55,124,171, 91,123,124,245,195,118,104,181, 91, 65,243,104, 72, 68, 12, 2, 2,187,131, 7, 53,
+126,138,152, 91, 88, 86, 92,240, 49, 94, 93,138,231, 37,155,164,166, 17, 22, 2,176, 28,135,179, 49,215,205,190,247, 74,195, 28,
+224,243,249,120,248,240,161,178,186,217,134, 60, 94,249, 48,103, 69, 79,189, 38,155,132,227, 40, 1, 35, 70, 19, 15, 31,104,212,
+ 37,111,164,140,156,156,156,230, 30, 60,120,208,190, 34, 84, 66, 92, 92, 28, 40,138,186,247, 66,113, 44, 63,174, 84, 42,145,144,
+144,128,184,184, 56,160,124,134,155,217,239, 81,133,146,149,147,147, 67,201,229,114, 72,165, 82, 58, 46, 46, 78,237,231,231,119,
+179,150,247,219,104, 83,165, 82, 61, 53,229, 63,169, 82,169, 26,137,197, 98, 65,149, 6,207,173, 85,171, 86,201,213, 12, 33,190,
+146,206,162,162,162,107,243,230,205, 11,232,219,183, 47,230,206,157,155,111,107,107,107,253,211, 79, 63,241,121, 60, 30, 53,101,
+202, 20,246,249,243,231, 37, 63,255,252,179,205,161, 67,135, 80, 88, 88,120,217,140,123, 87,168, 84,170,241,221,186,117,219,126,
+242,228, 73,169,167,167, 39,138,139,139, 65, 8,193,182,109,219, 48,101,202, 20,136,197, 98, 36, 39, 39, 99,192,128, 1,101,101,
+101,101,227,241,170,239,100,133, 77,138,162, 40,194,113, 28, 22, 45, 90,100, 12, 78, 90, 17,172,212, 90, 66, 97,203,172,230,178,
+233, 63, 23,201, 70,126,245,243,104, 0, 96,245,122,246,126,194,181, 71,219,214,127,117,129, 97,152,152, 90,202,104,225,244,233,
+211,127,234,215,175,159,196,202,202, 10,249,249,249,184,116,233, 18,174, 92,185,130,171, 87,175, 66,163,209,192,222,222, 30,182,
+182,182,144,203,229, 72, 74, 74, 82, 2, 88, 88,147, 77,161, 84,128, 22,173, 43,102,254,150, 43, 88,130, 74,179, 13, 43,171, 91,
+140, 64, 96,214,123,212,179,103, 79,116,238,220,185,130,172,176,169,169,169,114,181, 90, 77, 85, 34,253, 25, 21,132,220,221,221,
+ 93,191,115,231, 78, 82,155, 77,142,227, 94, 33,211, 61,122,244, 48,118, 10, 59,119,238, 12, 30,143,135,219,183,111,155,114, 77,
+121,201,230,213, 45, 27,112,242,235,133, 16, 50, 12,102,223, 75, 55,146,174,237,111,117,128, 64,200,192,187,255,144,202,215,110,
+ 68,249,112, 33,170,144,172,154,218,163,215,126,223, 45, 54,255,231, 33, 71, 61,150,224,169,192,239, 42,149,234,196,231,159,127,
+ 30,225,239,239,255,249,234,213,171, 41,134, 97,176,100,201, 18,146,153,153,249,155,161,199, 80, 80,159, 84, 17, 66,126,251,227,
+192,229,137, 99,194, 6, 82,179,214,140, 13,186,121, 46, 33,169, 93, 55, 79,180,235,230,137,155,231,239, 98,253,130, 93, 59, 89,
+ 29,187, 40, 43, 43, 43,173, 22, 83,234,222,221,219, 84,117,134,183,143,190,112,206,190,174,179, 14, 57,142,139,220,181,107,215,
+180,193,131, 7,211,215,175, 95,127,197, 39,171, 98,217, 29,142,227,112,230,204, 25,104,181, 90,252,246,219,111, 28,199,113,166,
+227,104,129, 28, 94,187, 38, 98,204,111, 59, 14, 11,133, 12,133, 43, 49,251, 81, 84, 80,243,172, 46,134, 17,224,215,109, 7,180,
+ 12, 35,184, 95,221,113,173, 86,155,126,238,220, 57,231,119, 89, 86, 64,211,116,117, 4,170, 90, 68, 70, 70,234, 56,142, 75,173,
+229,180,203,217,207,210,250,127, 51,247,211, 93,253, 62,250,220,185, 91,183, 32,129,131,147, 51, 40,138,194,243,236,231, 72, 78,
+184,174, 59,177,255,151,236,210, 50,243,150,224,249,116,229, 31, 70,159, 44, 0, 8,157,178,206,232,159, 5, 0,253,199,206, 67,
+ 72, 23, 95, 80,230, 72, 79, 47, 72, 22,167,215,235, 33,147,201,160,215,235,171, 13,241, 96, 99, 99, 35, 81,169, 84, 74, 67, 32,
+198, 26,123,204, 4,120,227,101,196,178,172,119, 65, 65, 1, 74, 75, 75,113,229,202, 21,242,237,183,223,230,228,228,228, 24,157,
+ 54,117, 58,157,119,126,126, 62, 74, 74, 74,112,249,242,101, 18, 17, 17,145,147,151,151,183,160, 46,239,144, 68, 34,233,200,231,
+243,111, 22, 20, 20,112, 82,169,148,214,233,116, 58, 63, 63, 63,145, 68, 34, 49,123, 65,117,185, 92,222,215,212,177, 22, 45, 90,
+ 60,120,240,224, 65, 43,150,101, 43,175,129,200,168, 84, 42,207,110,221,186,153, 83,127, 76,223,186,117, 43, 14, 28, 56, 16, 88,
+ 92, 92, 60, 42, 53, 53,117, 59,128, 64, 62,159,143,219,183,111,223, 83,169, 84, 35, 6, 15, 30,188,173,160,160,224, 26,202,151,
+224, 49, 7, 39,147,147,147, 63,246,246,246,222,186,116,233, 82,171,224,224, 96,190,155,155, 27, 58,117,234,132,228,228,100, 28,
+ 59,118, 76,183,113,227,198,210,178,178,178, 79, 1,156,169,185,216, 65,233,245,122, 8,133, 66,227, 71, 36, 18,129, 97, 24, 40,
+148, 4,159,253,240, 88,169,135, 68,185,106,201,248, 99, 4,160,178,210, 31,231, 62,207, 74,191, 70, 81, 84,140, 92, 46, 47, 50,
+145,103, 66,149, 74,213,158, 16,194,163, 40,106,141, 86,171, 29, 59,117,234, 84,215,229,203,151,163, 77,155, 54,200,205,205,133,
+ 76, 38,131,167,167, 39,114,114,114,112,253,250,117,182,172,172,108, 19,128,101, 48,248,143,152, 66, 97,110, 49, 26,187,184,191,
+164,124, 18, 66, 64, 88, 64,167,102,193,106, 9, 52,148, 14, 2,129, 14, 12,195,152, 51,164, 66, 56,142, 67,129,171, 43,184,132,
+ 4, 92,189,122, 21,132, 16,147,170,154,151,151,151, 89, 10, 41,203,178,175, 16,173,107,215,174,129,199,227, 33, 40, 40, 8,177,
+177,177, 70, 69,203, 44,191, 68,194, 65, 40, 18,190, 52, 92, 72, 81, 20, 24,161, 16, 2, 33, 83,221,108, 28,139,138,101,193,223,
+ 6,230,142, 99, 23, 2,152,112,231,206,157,237,189,122,245,138, 34,132, 8, 80, 62, 30,121,241,117,254, 60, 43, 43,235,214,229,
+ 99,183,230, 59, 55,182,141,120,111, 84, 16,218,180,247, 0,171,103,113,233,248,109,252,182,252,208,238,140,244,140,177, 48, 99,
+237, 51,142,227, 46,116,239,216,134, 70,165, 88,221,110,110,110, 92,125,102, 29, 22, 21, 21, 45,158, 61,123, 54,230,206,157, 91,
+159, 89,135,213, 34, 62, 41,103, 2, 5,210,184,255,123, 61,222, 5, 69, 19,141, 70, 93, 67,197, 7, 99,228, 82,134, 17,220,191,
+ 17, 39,247,171,238,188,156,156,156,119, 63,249,228,147, 51,124, 62,191, 89, 93,242,156,227,184,212,236,236,236,183,107, 63, 83,
+127, 73,173, 44,246, 60,186,123,243,204,147, 7,182,190,203,113,108, 75, 10, 0,143,207, 60,210,105,181,167,212,202,226,213, 48,
+115, 81,233, 21, 19,186, 98,250,218,211,216, 48,183, 63,166, 70,236,197, 47,139, 62,195,252, 31,118,225,251,185,211,241,237,186,
+127,227,171,233, 31,227,195,145,159,112,132,162,255, 52,247, 62,120, 60,222,201,205,155, 55,143,249,236,179,207,140,147, 22, 8,
+ 33, 47, 85,194, 58,157, 78,201,113, 28, 54,109,218,196, 1, 56, 89,147,189,151,203,136, 34, 53,249, 75,153, 91, 70,197,197,197,
+159,118,237,218,117, 27, 0, 17, 33,228, 97, 65, 65,193,191,128, 23, 75, 67,149,148,148,124,218,173, 91,183,109,132, 16, 17, 69,
+ 81,175, 28, 55, 7,134, 80, 15, 29,109,109,109,111, 26,148, 44, 81,125, 28,226,107,202,234, 26,134, 21,205, 25, 66,228, 0, 76,
+173, 20,241,125,121, 96, 96, 96,229, 69,165,239, 21, 20, 20,116,172, 71,186,206, 40,149, 74,223, 69,139, 22,205, 20,139,197, 33,
+101,101,101,173, 1, 64, 38,147, 37,171,213,234, 11, 74,165,114, 53,106,143, 77,165,225, 56, 46, 89,175,215,183,117,116,116, 44,
+159, 81,107, 32, 91, 0,112,228, 38,123, 19, 96, 59,149,139,226,191,155,157,176,227,199,143, 55,181,181,181,125,135,162,168, 15,
+ 9, 33, 94, 10,133, 66,189,104,209,162,203,145,145,145, 69,205,154, 53,123,175, 95,191,126,148,157,157, 29,110,220,184, 65,242,
+242,242,246, 3, 88, 0, 51,102, 90,115, 28,151,186, 98,197, 10,212,245,125,175,233,184, 86,171,205, 58, 32,240, 92,174, 0, 0,
+ 32, 0, 73, 68, 65, 84,126,252,184, 67,223,231,207,249, 28,199,161,127,255,254, 47, 17,184,170,184,127,255, 62,212,106,117,173,
+193, 28, 11, 11, 11, 17, 24, 24,248, 82, 7,181,226,147,154,154, 10, 59, 59,187,151,254,167,182, 62,150,186,168, 0,111,205,156,
+ 7, 24,102,148, 86,160, 92,201, 34, 32, 26, 11,175,178,224,239,139,191,122,241, 77,179,164, 69, 87, 87,215, 97, 98,153,104,178,
+ 71,107, 87,191,204,199,207,239, 42,138,202,118,202,229,242,205, 38, 42,114,179,108,214, 49, 96,169, 69,254,253,139,108,190,136,
+163,197,130, 16, 22,132, 35, 32,132, 3,199,177,229, 11, 94, 19, 14,132,101, 41,138,194,159, 26,101,141,145,193,171,166,211,214,
+193,193, 97, 25, 33,164, 47,143,199,163, 43, 87,212,149,191, 27,148,172,147, 57, 57, 57, 95, 85,163,188,254,215,229,103,100,100,
+100,181,228,223,220, 89,135, 67,135, 14,101,235,248,110, 94,144,201,100,174,213, 29, 43, 45, 45, 77,147,203,229,239,252, 77,242,
+179,242,140,193,186,216,172,243,172,195,218,108,122,120,120,136,180, 90,109, 7, 0,158, 20, 69, 53, 4,144,175,213,106, 79,229,
+230,230,102, 3,232, 8, 96,145,225,154,175, 1,220,252, 15,191,239, 18, 7, 7,135,173, 52, 77, 55, 54,231, 98,189, 94,175,201,
+207,207, 31, 83,165, 67,240, 98, 8, 30,224,137, 25,230, 58,104,186, 81,117,239,163,169,239, 32, 36,163, 84,169, 12,164, 94,212,
+249, 70,155,246,246,246, 55,249,124,126, 99, 51,210,246, 44, 47, 47,175,163,165, 78,254,175,182,249,223,140,170, 78,240, 38, 35,
+197,255, 21, 68,203, 98,211, 98,211, 98,211, 98,211, 98,211, 98,211, 98,211, 98,243,159, 78,180,170,221,183, 76,129,181,192, 2,
+ 11, 44,176,192, 2, 11, 44,120, 61, 28,171, 66,182,142, 85,124,161,106, 96,165,117,145, 4,235,195,108,207, 90,108, 90,108, 90,
+108, 90,108, 90,108, 90,108, 90,108,254,207,217,180,224, 13,194, 34,171, 90,108, 90,108, 90,108, 90,108, 90,108, 90,108, 90,108,
+254,211, 97,114,232,144,182,228,141, 5, 22, 88, 96,129, 5, 22, 88, 96,193, 95, 3,179,137,150,204,217,203,219,193,195,111,155,
+109,227,118,113,182,141,219,197, 57,120,248,109,147, 57,123,121,255,143,230,155, 4,192, 72, 62,159,127,198,197,197,165, 24, 38,
+150,222,249, 7,160, 1,128, 15, 81, 30,223,103, 16, 0,233,155, 52, 30, 12,240,135, 1,147, 71, 3,105,163,129,180, 97,192,228,
+224,127,160,223,224,146,105,174, 93, 99, 78,140, 60,177,100,154,107,215,106,143,207,118,181,191,122,122,232,218,229,147,221,236,
+222,208, 95, 90, 59, 57, 57,109,113,118,118,126,234,228,228,148,234,228,228,180, 21,128,141,165,186,179,192, 2, 11, 44,248,203,
+ 80,225,163, 85,241, 49,250,104,241, 1, 32, 42, 42, 42, 24,192, 31, 0,122,133,134,134, 70, 87,189,218,214,189,237,103, 45,155,
+183,156,251,205,146, 5,148,139,147,131, 84,207,114,218,148,167,233, 62,139,191,137,216,151, 41,228,175, 42, 72, 75,248,165, 30,
+137,162,120, 60,222, 48,145, 72, 20, 10,160,130,176,221, 83,171,213, 81, 44,203,238,129,121,211,180,225,236,236, 28,195,227,241,
+154,214,229,143, 89,150, 77,203,206,206, 14,170,103,102, 14,117,119,119,223, 26, 28, 28, 44, 13, 12, 12,132, 80, 40,196,162, 69,
+139,102,203,229,242,213,230, 26,176,181,109, 97,173, 21,137,103,240,133,194, 62, 68,167,105, 75, 64, 0, 90,148,192,233,213,231,
+ 24,181,122, 85, 65,193, 99,133,153,166, 22, 0, 24,107,200,171, 95, 0,172,120,157,167,100, 76,123,232,116,108,249, 51,193,240,
+193, 30,126, 98,243,199,194,133, 11,249,161,161,161,248,229,151, 95,130,182,108,217, 50, 94,161, 80,156, 3,112, 4,192,163,215,
+125, 42,157,129, 9,221,130,130,214,142,153, 61,155,167,140,137,193,218,173, 91,215,160, 60,222,210,134,186, 62, 75, 12,131, 15,
+ 29, 28, 4,161,132,160, 3, 5, 80, 20,112, 59, 39,143, 59,174,213,178,123, 96, 70, 44,182, 26, 48, 18, 47, 79,199,255,189,174,
+ 6,138, 30,145, 47, 69,253,189,123, 20, 61,186,240, 37,128,247,170, 30,215,171,196, 99, 8,175, 73,168,146,196,166, 3,248,225,
+ 53,179, 85,234,232,232, 24,119,248,240,225,198,129,129,129,124, 0,184,121,243,230,232,208,208,208,183,114,114,114,218, 2, 40,
+254, 15, 85, 66, 98, 62, 77, 79, 22, 10, 4,125, 88,150,109, 7, 0, 60, 30, 47, 94,163,211,157,209,115,220, 6,152, 25,147,205,
+ 2, 11, 44,248,231,162, 54, 46,242, 55,135,201,200,240, 21, 55, 71, 42,111, 43, 67,230,212,198,167,203,219, 67,238, 23, 41,202,
+ 84, 79,159,102, 20,204,154,252,237,153,241,211, 87, 30,250,225,231,168,227,209,215,238, 93,245, 14,124,231,174,204,169,141,143,
+ 9,211,166,198,112,221, 37, 18,201,173,141, 27, 55,106,147,147,147, 73, 97, 97, 33,185,127,255, 62,217,191,127, 63,153, 56,113,
+162, 74, 34,145,220, 2,224,110,142, 77,103,103,231,236,251,231, 79,147,103,113,177, 36,245,230, 53,162,211,233,136, 86,171, 37,
+ 90,173,150,220, 61, 25, 69,226,142, 28, 32,183,247,239, 33, 26,141,134,104, 52, 26,162, 86,171, 73,243,230,205, 51,205, 76,103,
+ 85,184,249,250,250,106,162,162,162,200,190,125,251,200,236,217,179,137,191,191, 63, 11, 96,138,185,247, 46,115,242, 12,177,110,
+228,151,243, 89,216, 6,237,177,203,167, 72,226,147,219, 36,241,201, 3, 18,121,246, 30, 25, 59,103,157,214,186,145,127,142,204,
+201, 51,164,182,123,183,181,181,237, 66, 81, 20,169, 0, 0,210,180,105,211,146,202, 31,119,119,247,151, 62, 77,154, 52, 41,105,
+214,172,217, 35,123,123,251, 14,213,217, 28,209, 14,132,220,253,157,144,187,191,147,133, 61, 65, 18, 19, 19,175, 18, 66,254,168,
+248, 40,149,202, 63, 14, 30, 60,248,199, 7, 31,124,240, 7,128, 1, 53,228,147, 89,249, 57, 26, 72, 83, 28, 62, 76,200,234,213,
+132, 4, 7,147,123, 0, 25, 13,164,213,209,102,115, 23, 23,193,237,149, 43,198,107, 14, 31,254,141,156, 56,113,140, 28, 63, 30,
+ 69, 14, 29,220, 74,214,172,158,172,117,118, 22, 36, 0,104, 85, 7,155,124, 0,223, 2, 88,133,114,229, 50, 57, 39, 39,135,100,
+101,101, 17, 0,201,134,223, 86, 57, 58, 58,254,128,234,213,183,222,149,149,172,153,125, 93, 78,124,244, 94, 16, 81, 20,101,146,
+143,222, 11, 34, 51,251,186,188,164,108,245,109,209,194,122,106,255,118, 57,137, 55,119,178, 83,251,183,203,233,219,162,133,117,
+ 61,243,147, 66,249, 58,161, 27,207,159, 63,175, 39,149,160,211,233,200,246,237,219, 89, 91, 91,219,223,234, 96,179,181,163,163,
+ 99,170,157,157, 93,114,229, 31, 29,253, 6,117,243,234, 49,122,177,189,207, 7,193,117, 72,103,160,152, 97,158,157,217,251, 19,
+155,151, 22, 79, 52,202,108, 82,244, 48,150, 60,187,119,149,108,223,188, 74, 39,228,243,159, 1, 8,124,157,103,169,142,176,216,
+180,216,180,216,252, 27,218,172,137,139,252, 55,131, 95,245, 6,171, 66, 36, 18,134, 45, 94, 56,143, 42,204, 43, 84,170,138, 21,
+ 26,157, 74,165,162, 25,162,138,191,251,228, 57,205,231, 21,206,156, 62,205, 58,108,254,194,176, 82,224, 99, 51,255,211,221,223,
+223,255,250,129, 3, 7,156,236,236,236, 80, 84, 84,132,188,188, 60, 92,191,126, 29,132, 16, 12, 30, 60, 88,212,185, 83,167, 14,
+ 95, 46, 90,116,229, 89, 70, 70, 87,152,110,120, 95,144, 23, 59, 7,172, 8, 42, 95,139,246,171,167,121,229,173, 14, 69, 97,203,
+208, 80,227, 57,203,158,149,175,150, 33, 22,139,141, 11, 18,215, 3, 93,223,126,251,109, 6, 0,198,141, 27, 87,172, 80, 40,194,
+ 13, 10,135, 89, 43,173,202,156, 60, 67, 28, 92,221,162,126,218,180, 66,210,174,165, 39,180, 58, 61, 82,179, 50,193, 23, 52, 68,
+227,198, 12, 62,249,184,143,160,103, 55, 59,135,111,191,222,114, 44,139,195,160,178,220, 7,167, 76,217,106,216,176,225,246, 61,
+123,246, 96,239,222,189, 0,128,228,228,100,120,122,122,202,106, 75, 67, 66, 66, 66,139, 1, 3, 6,236,206,203,203,107, 85,219,
+185, 85, 3,227,139, 68, 34, 4, 5, 5,193,199,199, 7,135, 15, 31,238,101, 80,182, 94, 11,202,152, 24, 88,221,185, 3, 68,215,
+171,243,210, 60, 32,192,227,234,241, 99, 59, 29,142, 29,191,135, 31,126,216,138, 71,143,202,133,182, 22, 45, 90, 96,228,136,161,
+130,248,248,203,190, 31,126, 56,242,242,197,139,143,130, 12, 68,169, 54, 44,253,249,231,159, 23, 52,107,214, 12, 31,126,248,225,
+ 80, 95, 95, 95,151, 6, 13, 26, 96,243,230,205,112,117,117,109,161,209,104, 30, 30, 62,124,216, 45, 43, 43, 11,211,166, 77, 67,
+118,118,246,108, 83,134,122,189,219,235, 75, 81,127,239, 30,109, 2,198,192,170,129, 43,126,222,181, 7,247,111,109,239,161,214,
+222,251,146, 97,163, 71, 41,137,104,108, 78,154, 85, 88,211,142,193,246,173,124, 7,192, 35, 32,214, 65,197, 94,124,242,101,159,
+230, 17,124,177,106,251,146, 31,228,121,175, 24,253, 48,146,215,182, 56,201, 46,225, 12,242,128, 37, 92, 5,193, 50,170,181, 4,
+ 3,122,246,236,105, 44,184,167, 79,159, 66,173, 86,195,219,219,155,214,104, 52, 33,102,230,107,235,119,222,121,231,207,227,199,
+143,219,183,110,221, 58, 39, 63, 63,223,120,192,197,190,225,187,209, 7,214, 76,251,118,237,191,189,118, 16,170, 48,231,222,161,
+248, 90,108, 5,118,239, 18,112,246,196,129,157, 86, 84, 73, 58,132, 13,115, 1, 46, 15,143,119,255, 10, 74,106,135, 97, 19,103,
+241, 67,222,126,171, 81,159,247,134,156,189,255,224,209,219, 0,110, 88,250,245, 22, 88,240, 63,173,106,145,127,218, 61, 25,137,
+ 86,104,104, 40, 85,221, 13,114,132,243,115,118,178,151,172, 89,185,237, 6, 79,171,209,200, 26,218,104, 4, 54, 13, 56,202,218,
+134,167,213,232, 74, 60, 90,120, 8, 57,194,249,153,176, 95,117,138, 39, 37,145, 72, 14, 28, 57,114,196, 73, 32, 16,128,227, 56,
+ 56, 58, 58, 34, 37, 37, 5,133,133,133, 80, 40, 20,120,116,239, 30,154,185, 55,193,146,176,121,174,211,230,133, 29, 40, 43, 43,
+235,136,151,135, 17, 95,153, 54,202,234, 94, 94, 55,186, 98, 9,150, 87,186,252,134,223,170, 57,102,238, 84,212,148,180,180, 52,
+ 88, 89, 89,161,109,219,182, 86,151, 46, 93,186, 88, 3,201,122,201,166,173,109, 11,107, 78, 36,220,187,241,167, 69, 18,173, 46,
+ 1,119, 31,231,163, 77,179, 30,112,182,119, 71,102,190, 6, 87,175, 31, 65, 66,220,239,104,217,200, 29, 83, 38,190, 37,142, 88,
+177,111, 15,163,111,230, 94, 88,152, 82, 92,157,205,226,226, 98,171,230,205,155,195,221,189,124,221, 51,150,101,113,247,238, 93,
+176, 44,107,220,175,188,221,182,255, 60,244,197,169, 24, 51,122, 52,242,242,242,172,170,179, 41,224, 65, 63,107,252, 72,190, 68,
+ 0, 8,101,118,154,146,146, 18,227, 50, 28, 90,173, 22,183,111,223, 70,215,174, 93,131, 35, 35, 35,107, 99, 69,102,229,167, 22,
+248,126,237,111,191,173,251,184,168,136, 6,128, 95, 40,138,211, 18,242,189,185,207,146,147,147, 96,255,201, 19, 59, 28,120,116,
+ 18,236,108,190,195,245,235,169,208,106,203,211,155,151,247, 28, 83, 39, 23,131, 17, 88,227,240,225,127,219,123,123, 7,237,207,
+202,210,182,197,203,195,136,213,165, 83,124,226,196, 9, 76,157, 58, 21,119,239,222,117,171, 88,163, 77, 34,145, 96,229,202,149,
+ 60,111,111,111, 55,153, 76,134,147, 39, 79, 34, 59, 59,155,170, 41,157,127,156,250,227,155,162, 71, 23,190,204,162, 78,246,253,
+121,215, 30,124, 62, 98, 24, 92,200,227,139, 54, 45,169,111,222,233,223,253, 43,194,107, 18, 42,179,246,179,245,108,219, 31,140,
+208, 10, 83,190, 88,134,228,132,163,182,101,138,184,201, 20,155,222,100,201, 15,145,211, 95, 73,231,190,161,236,184,223, 47, 5,
+156,113,191,225,113,231,246,248,107,242,216, 45,113, 47,136, 86, 11, 62, 69,179, 54, 64,249,178, 38, 15, 31, 62,196,163, 71,143,
+192,231,243,161, 84, 42,161,215,235,171, 77,167,155,155,219, 4,189, 94,255,149,161,156,183,137,197,226, 79,119,238,220,105, 95,
+153,104, 59,250, 13,234,102,111, 45,123, 59,251,121, 94,193,229, 27,137,247,103, 77,248,176, 87,204,213,132,116,173,224,131,180,
+162,184,195, 69, 38,242, 83, 44, 17, 10,247,159, 60,248,111, 43,221,147,243,144,121,247,130,192,202, 19,172, 46, 3,101, 5,165,
+ 80, 60,146, 67,253,211,122,180,159, 60, 19, 71, 15,237,179,242,109,215, 49, 82,173,211,121, 2,208,212,227,221,172, 11, 44, 54,
+ 45, 54, 45, 54,255,158, 54, 77,114, 17, 66, 72, 0, 0,103,195,110,158,129, 23, 56, 0,200, 69,249,138, 2,206,134,186, 67, 88,
+233,178,170,251,149,207,173,186, 95,249,123,158,225,187,147, 97,123,131,162,168,252, 90,146,238,138,242,165, 9,143, 25,182,128,
+ 97, 40,177, 86,199, 99,138,162,139, 89,150, 19, 49,142, 78,170,113, 31,189,221,238,244,217,155,183,165, 14, 13,248,239,246,234,
+ 16,124, 61,254,201, 21,138,166,116, 20, 69,155,229,247,193,227,241,134,173, 89,179,166, 93,131, 6, 13,192,113, 28,108,108,108,
+144,147,147, 3,141, 70,131,162,162, 34,168, 21,197,208, 42,138,113, 39,253, 41,186, 7,247,194,144,190,239,120,255,251,208,145,
+ 97, 44,203,238,174,201,174,155, 95, 7,163,146,181,172,169,253, 11,105, 34,189,208, 72,186,190,235,224, 9,198,202, 10,125,102,
+133,189,206, 51, 16,123,236,216,177, 19,131, 7, 15,126,111,206,156, 57,180, 92, 46, 63,153,146,146,210, 29,192,221, 90, 73,133,
+ 72, 60, 99,210,140, 80, 91, 91, 43,130,200, 51, 71,208,179,195, 8, 72,133, 60,228, 21,107, 65, 81,192,189,196, 3,160, 40, 59,
+196, 37,203,209,163,125, 3,188,243,174,183,213,161,125,247,230,224,133,127,208, 43, 69, 83, 80, 80,128,231,207,159, 67,167,211,
+ 65,167,211,225,195,161, 67,177, 99,251,118,148,150,150, 66,169, 84, 66,163,209,128,101, 89,208, 52,141, 51, 81,145, 72,127,114,
+ 15,221,186,118, 5, 76, 44,189,180,253, 54, 4, 0,174,222,191,127, 31,247,238,221,195,179,103,207, 32, 22,139,225,226,226,130,
+101,203,150, 65,173, 46, 95, 79,108,232,208,161,193, 0,226, 95,247,133,122, 4,108, 73, 97,217, 47,223, 59,120,208,233,210,193,
+131,220,213,163, 71,159,137, 20,138,205,230, 92,203, 48,248,112,197,247, 19,219,200,100, 50, 60, 75, 91, 3, 47, 47, 6,179,103,
+218, 35,252,187, 92, 0,192,180,169,141,209,169,163, 3,138, 11,247,193,193,105, 1,214,173,155,222,114,236,216, 85,163,203,202,
+216,109,181,152,254,242,200,145, 35, 67, 60, 61, 61, 27,197,198,198, 82, 66,161, 16, 18,137, 4, 18,137, 4, 98,177, 24,207,159,
+ 63, 71, 74, 74, 10, 89,177, 98, 69, 6,128, 47,107, 50,180,100,157,252, 10,128,247,102,246,197,137,251,183,182,247,104,196,123,
+114,103,200,148,160,167,113, 87, 99, 21,167,207, 92,250, 90,175, 18,167, 23, 62, 59, 59,175,121,167, 88,135,201,115,151, 98,253,
+138,197,184,127, 45, 38,223,217,189,120,131,132, 82, 87,155,206,224,224, 37,124, 87,103, 59,253,132,177, 67, 26, 30,117,190, 60,
+225, 56,159,202,201,202,189,181, 18, 41,177, 74, 81,171, 14,163, 90,183,160, 53,231,207,159,151,244,236,217, 19, 42,149,202,168,
+ 76,238,220,185,147,211,235,245, 23,170,125, 54,181,218,175, 50, 50, 50, 92,149, 74, 37,250,246,237, 59,109,229,202,149,178,138,
+245,228, 88,150,125, 73,201,250,102,245,142, 83, 51,190,218,112,225,212,238,239,220,190, 9,251,180,215,199, 83,190,189, 0, 19,
+235, 72,242,105,122,242,209,131, 91, 93,196,182, 58, 72,236,222,129, 42, 91,137,251, 91, 62, 71, 89,177, 10,157,190, 89, 10, 64,
+ 8,141,142,198,230,254, 31, 66, 96,239,134,197,159,125,234,182,112,243,207, 19, 57,142, 91, 99,233,215, 91, 96,129, 5, 85,224,
+ 76, 81, 84, 20, 0,132,133,133, 45, 8, 15, 15, 79,164, 40, 42,138, 16, 18,106, 16, 80,162, 8, 33,161, 21,231, 24,200,217, 43,
+251, 21,231, 86,221,175,250,125,254,252,249,190, 17, 17, 17,203,187,254, 31,123,215, 29, 23,197,181,182,159,153,237, 21, 88, 58,
+ 11,168,128, 34,168, 32, 16, 17,177,163, 70, 18,187, 70, 44, 81, 44,209,104, 18, 75, 52,137,221,216, 75,188, 70, 19, 91,212, 88,
+162,198, 94,162, 98, 87, 20,123, 5, 21, 5, 5,233,189,195,178,189,204,204,247,135, 64,208, 80, 22,147,220,155,251, 93,158,223,
+111, 88,118,119,230,217,115,166,156,243,156,247,188,239,123,130,131, 15,222,190,125, 59, 25, 64,125, 66,171,111,133,176,250,195,
+210, 59,100,165,130,172,254,250,134, 69,139,166,175, 39, 38,167,170,123,247, 10,114,137,136,122,250, 96,220,184,190, 61,135,247,
+239, 26,154,146, 94, 20,215,188,169,163,237,179,103, 79, 45,104,154,190,110,206, 89,226,243,249,253,122,244,232,193, 46, 41, 41,
+129, 72, 36, 66, 65, 65, 1,178,178,178, 96, 48, 24,160, 45, 43,133,174,172, 20,218,210, 18, 24,202, 74,240,234,225,125,180,109,
+238,193,175,112,150,175, 19,149, 86,151,183, 45, 85,213, 45, 91, 60,169, 20,124,169, 20, 68,195,167, 13, 7, 90, 89, 89,221,173,
+236, 84, 13, 6,195, 23,179,103,207, 46,164,105, 26, 43, 86,172,176,144, 72, 36, 71, 0,240,235, 35,145,218,177,250, 5,251,251,
+144,241, 41, 79,208,217,111, 12, 90,186,247, 65, 74,158, 6,133,229, 6,228,151, 26, 16,216,117, 35,154,249, 45,129,171,255, 42,
+196,165, 21, 67,238,236, 73,130,205,175,115,241,231,140,140,140, 55,222, 31, 60,112, 0,106,181, 26,205,155, 55,199,200,145, 35,
+ 49,123,246,108,140, 28, 57, 18,114,185, 28,163,134, 13,192,162, 69,139,144,155,155, 91, 95, 81,117, 45, 91,182,212, 53,109,218,
+ 84,215,180,105, 83,157,193, 96,128, 82,169, 68,105,105,233,219,231,123,122, 67, 79,164,189,189,253, 92, 71, 71,199, 39,246,246,
+246,207,248,124,254,217, 24,130,136,215, 54,109,234,208,105,208, 32,162,245,176, 97,172, 52,161,144,136, 2, 36,230,112,217, 90,
+115,250,134,244,248,144, 87, 90,178,171,202, 72, 53,126,156, 29,110, 70,181,193,173, 27,237, 48,245,139,230, 32, 72, 1, 8,146,
+ 7,181, 42, 18, 65,237,131,185, 86, 86, 68,125,247,210,199, 0, 98, 58,117,234, 36,159, 50,101, 10,193,231,243, 49,109,218, 52,
+195,132, 9, 19, 18, 70,142, 28,153,112,229,202, 21,170,105,211,166,112,117,117, 37, 92, 93, 93,157, 0,196, 84, 28, 83, 39, 44,
+154, 19,203,117,134,184, 27, 86,158,226,100, 10,182, 29,149, 70,254,208,197,223,231, 20, 45,223,146,252,125,202, 11,181,199,139,
+123,215,139, 18, 98, 79,211, 41, 15,174, 21,102, 39,148,123, 44,223,146,252,253,188,205,217, 53, 62,212, 81, 81,160,143, 71, 68,
+ 25,212, 42, 53,123, 80,255, 16,245,164, 79,134,183,180,150,180,217, 7,231,222,126,205,154,184,140, 90,180,114,131, 97,194,103,
+ 95, 26,118,236,220,197,148,151,151, 67,161, 80, 96,195,134, 13,166,211,167, 79,103, 81, 20,245,101,109, 99, 32, 0, 48, 26,141,
+152, 52,105,146,216,194,194, 2, 25, 25, 25, 85, 22, 81, 0,200, 41, 40,122,122,235, 65,108,252,204,201, 97,221, 84, 58,157,238,
+194,181,135,113,173, 61,155,186, 16, 4, 83,107, 32, 10,143,195,121,191, 93, 80, 16,139, 97, 74, 65,176,155,224,213,158,127, 65,
+145, 91, 12, 69,126, 49, 88, 28, 49, 76,224,195, 72,243, 96,213,182, 61, 94, 62,136,134,179,157, 3,155,207,225,132, 54,246, 39,
+141,104,196,255, 38,234,210, 34,213,197,210,234,213,171, 87,214,245,125,181, 87,253, 91,239,171,132,212,219, 34,172,250,255, 0,
+176,122,245,234,149, 12,195,244,187,125,251,246, 1, 0, 26, 51,171,240,105,181, 87,243,243,104,177,180,250, 85, 95,207, 94, 0,
+153,165,208,178,125,128,167,227,201,243, 81, 15,175,223,126, 24,215,204,213,214,142, 49,234,101,107,214,109,114, 33,212,154,213,
+102, 22,162,149,173,173, 45, 12, 6, 3, 18, 19, 19,145,153,153, 9,131,193, 0,147, 74, 5, 93,105, 41,180, 37, 37,160, 84,229,
+224, 82, 20, 52, 5,249,176, 17, 9,128,223, 35, 18,235,177,188, 17, 53, 10,173,202, 87,129,133, 5,248, 82, 11,144, 28, 78,189,
+ 43,197, 87,195,123,237,219,183, 63, 28, 27, 27, 27,212,171, 87,175,101,120, 29, 34,159,150,149,149,213,115,225,194,133, 58, 7,
+ 7, 7, 76,154, 52,201, 11,192,152,122, 69, 38, 79,223,170,169,163, 23, 90,122,140, 65, 51,215, 30, 40, 85, 25, 81,160, 48, 34,
+191,212,128,109, 27,131,113,108, 71,123,220, 60,214, 5,177, 23,222, 71,169,209, 17, 18,249, 64, 48,148,190, 77, 93,156,151, 46,
+ 93,194,210,165, 75,177,108,217, 50,172, 88,177, 2,203,150, 45, 67, 86, 86, 22,124,124,124,144,158,158,142,115,231,206, 33, 39,
+ 39, 7,182,182,182,184,127,255, 62,214,175, 95,143,155, 55,111,214, 91,233, 74,225,106,198, 62, 13,154, 75, 55,153, 76, 99,115,
+ 6, 13,242,205,179,182,110, 29, 16, 16,240,225,180,105,211, 60, 58,117,234, 84,245,189,135,135, 71, 19,161, 80,152,139,215, 17,
+148,254,117,113,209, 64,128,157,157, 15,244,186,248,138,107,204, 1, 65, 8,208,227,253, 56,116,234,242, 16, 6, 35, 23, 36,193,
+ 7, 73, 10, 96, 50, 21, 65, 38,147,131, 97, 8,159,122,138,184,176,160,160,192,243,242,229,203,100, 74, 74, 10, 4, 2, 1, 0,
+164, 46, 94,188,120,211,247,223,127,255,220,198,198,134,138,136,136,192,111,191,253,134,126,253,250,177, 38, 76,152,224,233,234,
+234,186,181,190,122, 47,222,144,115,103,255,186,115, 35, 56, 70,153,191, 64,216,204, 13, 42,201,192,207,187,217,138, 1,224,124,
+ 82, 82,185,125, 19,197,106, 85,249,147,116, 43, 23,229,119,231,147,234,139, 56, 93, 76, 63, 74,136,191,187,255,196,249,178,252,
+188, 18, 78,128,111, 27,205,170,165,223,112,155,185,181, 88,179,104,246,100,199, 44,133,160,244,253,105,231,226,143,159,191,175,
+ 28, 61,110,162,233,147, 79,167,104,207,157,191,116,130,166,105, 95,212, 18,113, 72,211, 52,114,114,114,240,236,217, 51, 36, 37,
+ 37,161,160,160, 0,133,133,133, 40, 47, 47,175,154,110, 20,149, 43,206,108,218,125,250,177, 88, 40, 20, 5,249,122, 54,185, 23,
+253, 60, 95, 44, 20,138, 60,221,154,180, 4, 22,215,216,142, 80, 20,229, 43, 16, 9, 1, 16, 40,141,189, 14,101,137, 18,202, 82,
+ 37,202,139,149,208, 25, 88,208,234, 72,104,244, 36,154,118,235, 13,165, 74, 11,101, 81, 25,104,138,242,107,236,110, 26,209,136,
+ 70,212,209,215, 71,204,153, 51,103,158,153,251,154, 61,189,249,182,240,154, 51,103,206, 60,130, 32, 34,230,206,157,219, 6,181,
+ 7, 84, 85,199,246, 26, 54, 0,102,164,119, 40, 42, 74, 80, 74,137, 86, 67,102,204,250,246,220,129,157, 27,237,117, 58,117,186,
+141, 76, 66, 73, 68, 60,219, 79, 38,173, 64,185,178,100,176,202,252,116, 4, 40, 41, 41, 65,114,114, 50,132, 66, 33,184, 28, 14,
+ 40,141, 6,148, 70, 5, 77, 73, 17, 72,131, 14, 92,138,130,181, 72,136,166,114, 71, 52,115,112, 52,139, 51, 49,242, 98,149,227,
+123,245,233,194,127,181,111, 5,158, 88, 2,158, 84,130,207, 35,174, 1, 0,184, 92, 46,176,112,153, 89, 70, 19,103,103,231, 83,
+251,247,239,231, 22, 20, 20, 32, 38, 38,230, 49,128, 50, 0, 82, 0,116, 92, 92,220,229,216,216,216,126,158,158,158, 0,208,188,
+ 62, 50, 69, 33, 73, 25, 77, 12, 50,114, 83,145,146, 25, 13,107, 75,119,112, 68, 45,145, 95,106, 0, 95,232, 14,163,238,247,217,
+ 71,173, 34, 13, 26, 3,203,172,186,235,245,122,152, 76, 38,152, 76, 38,232,245,122,124,250,233,167,184,117,251, 54, 14,254,118,
+ 5,201,175, 94,194,203,205, 17,225,225,163,209,190,125,123,220,190,125,187, 78,174, 49,254, 48, 58, 75,192, 94,247, 33, 9,158,
+196, 70,215, 97,246,133,123,245,137, 45,130, 32, 24,212, 50, 21,249, 22,190, 15, 14, 14,110,241, 82,165,194,179,248,120,244, 90,
+188, 24, 0,112,246,236,217, 55,234, 50,115,230, 76,222,243,231,207, 63,121,248,240,225, 39,217,217,217,235, 0,212,236,108,206,
+ 0,103,206,220,193,228,201,207, 81, 80, 80, 0, 0, 56,116,224,119, 93,154,146,108,192, 7,125, 95,207,104, 89, 89, 89, 97,221,
+ 58, 31,179,206, 39, 69, 81,216,190,125,123,213,116, 33, 0,176,217,236, 78, 51,103,206, 28, 82,211,254, 45, 90,180,224,214,199,
+ 57, 99,168,179,224,230, 99,230, 11,203, 22,205,218, 88,216,182, 69,145, 49,218, 39, 58, 43,103,234,140,161,206, 63,172, 63,154,
+165, 21, 18,186, 95, 8, 42,195,149, 45,208,238, 49,167,140, 73,231, 55,234,139,154,142,221,147, 91,160,152, 63,101,226,199, 54,
+ 22, 86,246,170, 29,155, 86,201, 72, 22,201,156,122,104, 40,109,227, 97, 99, 53,176,195,143,202,201, 51, 22, 70,235, 77, 25, 83,
+144,113,234, 37,234, 72,113, 65, 81, 20,178,179,179, 81, 80, 80,128,244,244,116, 20, 22,190,158,126, 45, 44, 44, 4, 77,211,127,
+166, 65,132, 38, 61, 29,105, 39,118,160,217,232,209, 8, 92,182, 20, 20,205,134, 70, 77, 97, 93,199,158, 40, 41,211, 64, 71, 19,
+144,191,215, 17, 19,207,222, 0,201, 80,192,182,205,141, 61, 73, 35, 26,241, 63, 10,115,210, 59, 84, 10,162, 85,171, 86,245,251,
+171,127,191,186,216, 90,181,106,213,179, 85,171, 86, 53,228,183,222,158, 50,172,122, 95,233,163,117,173,154, 3,218, 31, 58,205,
+242,194,184,164,231,207,217,217, 42,141, 74,228, 96,111,167, 19, 9,248,116,153,162,156, 21,253,244,177, 65,149,251,234, 69, 3,
+234, 17, 23, 27, 27,235,147,157,157,141,244,180, 52,152, 52, 42,144, 58, 61, 24,173, 26,189, 58,119,132, 0,128,128, 36,192,165,
+ 13, 96,179,120, 40, 87, 42, 0, 32,174,222,206,209,104,252,131,101,139, 32, 8,240,164, 82,240,196, 98,240, 36,210, 55, 44, 92,
+230, 88,108,248,124,254,254, 35, 71,142, 56, 57, 59, 59, 99,233,210,165,112,113,113,241,150,203,229,106, 75, 75, 75,161,131,131,
+ 3, 90,183,110,141,142, 29, 59,226,220,185,115,128, 25, 57,165,140, 38,193,147, 23,169,232, 84, 88,124, 27, 55,174,253, 4,189,
+ 70,135,128,110, 63,193,192,110, 6,187, 54, 75, 64, 39,238,131, 58,247,228,107,235,129, 99,127,100,166,167,130, 96,241,158,153,
+107,121,170,252,255,241,227,199, 56,112, 50, 10, 78, 77, 91, 33, 61, 33, 30,241, 87, 47,227,150,157, 13,154,182,106, 93, 53, 13,
+ 84,107, 25, 41,176,151,111,126,157, 38,106,193, 23, 31,243,139,139,139,249,214,214,214,186,202,115,231,228,228,244,103,196,214,
+199, 95,127,253, 53, 74, 57, 28,160,111, 95,112,147,146, 96, 48, 24,208,161, 67, 7, 4, 6, 6, 2, 0, 58,116,232, 0, 54,155,
+141,182,109,219, 66, 46,151, 99,243,230,205, 31,215, 38,180, 72, 2, 49, 38, 83,145,183,135,135, 71,149,208,218,179,183, 0,209,
+ 15,223, 7, 1, 30, 54,108, 74,172,218,183, 73,147, 38,200,205, 73, 2, 65, 48,177,245,148,113,153,163,163,227, 66, 39, 39, 39,
+143,239,191,255,158, 37, 16, 8,240,217,103,159,185, 43,149,202,102, 21,166,100,204,157, 59, 23, 0,176,104,209, 34, 44, 94,188,
+ 24, 58,157, 78, 93, 27,217,158,117,190,242,252, 98,250, 19, 70, 41, 26, 28, 98,219,204,183, 71,104, 47,184,123,246, 64,143,208,
+116, 0, 88,105,205, 78, 29,182,102,190,213, 9, 43, 41,177,235,226,249, 75,139, 58,119,235, 49,127,182,242,234,242,239,182,151,
+214,235,243, 88,150,246, 75,249, 11,222,240,245, 27,183,238, 93,255,237,220,233,130,244, 2,125, 73, 86, 9,163,148,240,217,146,
+230, 14,132,100,234,172,101,201,217,217, 73, 95, 33,227,124,189,145,150, 52, 77, 35, 41, 41,169,202,167, 79,171,213, 66,165, 82,
+ 33, 35, 35,163,234,158,209,136, 45, 62,152, 50,174,191,159, 74,163, 81,223,123,154,144,190, 96,218,168, 96,149, 70,163, 78, 72,
+ 73,127, 9,108,168, 81,141,145, 36,249, 84, 93,174,238,165, 46,213,162, 32,230, 5, 92,122, 54,133,209, 68, 64,111,162, 80, 80,
+ 84, 14,157, 9,160, 72, 14,218, 12, 11, 7, 69,176, 81,152,157, 5,146,197,122,140, 55,157,246, 27,209,136, 70,252,239,160, 78,
+ 45, 82,105,209, 10, 14, 14, 62, 88,221,234, 84,249, 63, 0, 29,234,118,229, 41,168, 46,166, 42,167, 19,107,251,157,183,120,205,
+197, 31,124,180,234, 77,239, 80,249,155,174,150, 10,249,191, 22,141,114,161, 77, 38,175,252,194, 60, 19,155,205,231,184, 90,106,
+114,138,211,205,255,117,157, 78, 23,113,249,242,229, 65,239,191,255, 62, 63,225,233, 99,232,203,202,160, 47, 43, 5,135, 54,193,
+ 90,216, 14,164, 65, 7, 66,175,135,179, 55, 13,109,185, 16, 81,183, 98,141, 58,157, 46,194, 92,161, 69,178, 88,111,250,101, 73,
+ 36,224, 75, 45,192,151, 72,222,158, 90,172, 79, 20,136,122,247,238,221,179, 67,135, 14, 96, 24, 6,219,183,111,135,193, 96,224,
+ 25, 12, 6,232,245,122, 24, 12, 6, 40, 20, 10,236,221,187, 23, 91,182,108,185, 5, 96,119,189,157,153, 73,127,249,194,165,200,
+246,227, 71,245,227,156,141, 88, 7,147,158,130,134,112,129, 74,101,132, 82, 47, 2,101, 51, 26,200, 59, 3, 22, 91,128,224,182,
+238, 56,121,244,184, 1, 38,221, 21, 51, 85,248, 27, 86,161,140,244, 84,100,190,122, 9,137, 34, 23,118, 22, 34,168,147, 94, 34,
+ 32,124,204, 59, 89, 39, 92, 93, 93, 65,211, 52, 66, 66, 66,170,156,171,223, 85,108, 21, 21, 21,225,244,233,211,232,208,161, 3,
+186,117,235,134,172,172, 44, 36, 37, 37,161, 79,159, 62, 85,251, 60,126,252, 24,209,209,209,104,222,188,110, 35, 97, 97,177,241,
+108,102, 70, 76,216,192,129, 3,185,119,239,222, 5,195, 48,240,244,180,128,133, 84, 12,130,228,163, 85, 43,123, 0,175,199, 0,
+221,187,119,135, 66,145,100, 42, 41, 97,206,214, 83,221,253, 0,126,211,235,245,137, 93,187,118,149,191,122,245, 10, 51,102,204,
+ 96, 31, 58,116,168,210,148,140, 57,115,222, 12,166,208,104,106,159,186,247,242,245,254,198,221, 36,235, 38, 16, 54,115,179,176,
+109, 11,119,207, 30, 0,128,247,251,141,135,123,139, 38, 80, 20, 62,113,211,106, 82, 7,115,217, 37,178, 39, 27,178,158, 11,251,
+250,140,211,230, 95, 75,192,235,169,211,122, 47,187, 38,225, 80, 94, 58,103,244,225,223, 78,157,155,212,167,223, 0,142,145, 50,
+153,124,154,114,172,142,156, 56,147,159,149,150,254, 35,210,207,199,254,110,255,171,211,138, 71, 41, 20, 10,136,197, 98,196,198,
+198,234,250,246,237,203, 39, 73, 18,137,137,137, 85, 66,203,222,214,186,117,167, 64, 31,239,229,235,247, 94, 16,243,249,252,208,
+238,237, 90, 61, 79, 72,203,100, 24, 34,181, 86,107,171,209,120,233,105,204,227, 16, 59,121, 11, 86,210,181,187,176,233,210, 7,
+ 58, 29, 9,141,158,134,206, 4,152, 88, 92, 56,249, 7,193,170,121, 43, 48, 0, 30,220,189,101,212, 25,141, 23, 26,251,154, 70,
+ 52,226,127,218,170,197,212, 37,146, 42,254, 47, 6,144,186,106,213,170,194,106,214,166, 2, 0,143, 1,248, 85,236, 87,240,214,
+113, 5, 4, 65, 60, 96, 24, 38,176, 26, 79, 65, 53,193, 85,253,127,253, 91,251, 60,110,128,200,170,254,250,166,208,170, 45,164,
+ 18, 0,108,109,109,237, 3, 2,218, 53,255,121,231, 97, 48, 12,131, 23,209,107, 81,146, 31,143,133, 43,239, 52,119,118,118,238,
+150,149,149, 21,101, 78, 9, 40,138, 58,180,107,215,174,175,130,222, 11, 8,112,115,113,193,227,212, 20,112, 25, 10, 92,138, 2,
+105,208,129, 77,233,225,226, 67,129, 36, 36,200,206, 46,195,234,253,135, 99, 43,178,196,215, 9,239, 62, 3,176, 52,179, 12, 4,
+ 65,224,251, 96, 31,240,164, 18,112,197, 18,124,126, 42,178, 74, 92, 69, 44,157, 11,158, 68,130,230, 65,102, 37,132, 87, 95,189,
+122,245,225,211,167, 79, 3,125,124,124,240,213, 87, 95, 33, 53, 53, 21, 52, 77, 35, 47, 47, 79,155,147,147,147, 85, 80, 80,144,
+ 10,224, 4,128,159, 97, 70,230,113,174, 78,251, 67,196,177, 61, 83,130, 59,119,179, 29, 56,120, 11,126, 59, 58, 19,165,101, 10,
+168, 77, 66,168,180, 38,168,116, 44, 88,219,248, 34,168,109, 91,100,103,229,227,217,221, 11, 74,182, 78,189,182, 33, 55, 40, 65,
+ 16,136,142,142,134,135, 92,138,151, 55,162, 96, 43,226,192, 79,238, 8,121,167,206, 85,249,165,234, 2,135, 5,211,199, 31,127,
+ 92,149, 25,190,119,239,222, 41,163, 71,143,118,154, 57,115, 38,118,238,220,137, 91,183,110,253,193, 65,187, 91,183,110,184,126,
+253,250, 18, 0,139,234, 51,234,233,245,122,120,123,123,227,193,131, 7,184,124,249, 50,122,244,232,129,110,221,186,225,201,147,
+ 39,184,120,241, 34,162,163,163, 65, 16, 4,108,108,108, 96,124, 45,158,141,181,145, 25, 12, 56,242,221,154, 93,243,214,175,223,
+210,102,212,168, 81, 56,118,236, 32,198,143,243, 2, 65,242, 65, 16,124, 12,232,239,133,165,203, 30, 32, 40,168, 59,108,109, 57,
+ 88,191,238,100,178, 70, 67,237, 53,227, 52, 46,191,120,241,162, 92,171,213,162,180,180,148,145, 72, 36, 68, 81,209,235,136,214,
+154, 44, 90,106,181, 90, 80, 27,209,211, 71,113,107, 75,203,153, 18, 70, 25, 61,184,216, 20,237,219, 35, 52, 3,239,247, 27,135,
+ 75, 17,187, 17,121,225, 50,172,217,169, 41, 16,151,159, 43, 76, 41, 84,228,168, 60,183,182,122,111, 2, 43, 83,117, 97,235,212,
+ 1, 47, 89, 78, 78,244,145,185, 63, 41, 74,235, 18, 90, 0,136,226,231,251, 78,157, 96, 48,160, 99,112, 80, 11,159, 38, 78,188,
+146,194,124,230,232,201,115,177,134,148, 99,167,171, 9, 44,166, 30,161,190,116,206,156, 57,223, 86,252,255,203,130, 5, 11, 38,
+172, 94,189,218, 46, 55, 55,183,202, 71, 43,191,176, 56,178, 99,223,169, 84, 81,105,153,126,215,250, 89, 67,133, 2, 62,111,193,
+234, 93,215,140, 44,220,173,141,215, 68,211,155,135,205, 88, 56, 61,225, 69,180,115, 51, 33, 15, 39,103, 45,194,227,139, 87, 97,
+ 36,185,152,124,249, 30,116, 6, 10,165,133, 69,184,242,201, 23,144, 56,200,176,229,218,177, 60,154,166,127,106,236,106, 26,209,
+136,255, 93,212,166, 69, 8,130,168, 41,199, 94, 94, 13,159, 61,168,235,184, 90,120,254, 10,212,154, 21,222,172, 16,188,194,194,
+194,252,235,215,239,225, 90,196,114, 68, 69, 44,199,179,232,199,200,206,210, 35, 43, 79, 11, 11, 11,139, 59,117, 28,250,118,230,
+ 88, 70,173, 86, 15, 89,176,240,219, 92,129, 80,132,174, 61,123,194,209,206, 30, 34, 46, 7, 44, 19, 13, 22,193,129,178,192, 10,
+ 47,159,168, 49,123,215,190,124,165, 90, 61,164,134, 78,162, 87,109, 34,131, 32, 8,240, 45,164,224, 73,164,224, 75, 45,222,152,
+ 70, 20, 88, 88, 64, 32,181, 0,155,199,171,201, 25,254, 15,156, 74,165,242,163,161, 67,135,150,148,149,149, 97,194,132, 9,136,
+138,138,138,190,112,225,130,197,147, 39, 79,132, 5, 5, 5, 45, 0,244, 6,176,173, 14,145,245, 6,103, 73, 73, 82, 57, 99,210,
+ 13, 95,245,237,151, 26,173,201, 6, 97, 99, 14, 65, 76,102,192, 68,209, 96, 0,200,173,121,232,212,107, 25,242,245, 29,113,104,
+235, 10, 53,109,208,142,122, 43,135,214, 27,156, 12,195, 48, 14, 14, 14,127, 56, 7,151, 47, 95, 70,216,208,143, 16, 58,120, 16,
+236,220, 60, 96,223,171, 15, 66, 39, 76,198,214,173, 91, 65,146, 36,108,109,109,223,238,120,171, 56,247,196,128,115,224, 41,136,
+ 3, 79, 65,252, 18, 13, 54,128,240,125,251,246,125,231,231,231,119,245,214,173, 91,107, 1, 12,175,254, 91,213,176,248, 45,107,
+ 86, 77,215,104,254,244,233,211, 53, 9, 9, 9, 16,139,197, 48,153, 76,184,117,235, 22,182,108,217,130,239,191,255, 30,209,209,
+209,176,177,177, 65,243,230,205,161,211,233,240,224,193, 3, 13,128,249,117,112,210, 5, 5,166,143, 54,108, 88, 93,212,175, 95,
+ 23,236,218,181, 9,142,142, 29,193, 97, 59,130,205,177,131, 88,226,141, 29, 63,127,135, 15, 63, 12,192,169,147,135,139, 11,139,
+ 76, 31, 1, 48,153,113, 47,105,239,221,187,135,173, 91,183, 98,232,208,161, 89, 97, 97, 97, 84, 89, 89, 89,149, 69,139, 97, 24,
+ 48, 12,131,197, 21, 62,102, 58,157,142, 95, 27,231,196,217,177, 89,179, 86, 60, 91,154,151,155,213, 33,234,234,157,143, 35, 47,
+ 92, 70,114, 66, 36, 34, 47, 92,198,141,200,219,115,242,114,179, 58, 4,180,111,201, 29, 50, 97,202, 55,123,142, 31, 99, 73, 44,
+156,176,231,248, 49,214,200,169, 95,174,104, 23,218, 99,126,125,247,124,197,117,100,148,249,121,115, 87,174,221,168, 52, 25,180,
+228,191,126,220,156,173, 41,200,153, 95,237,190,100,234,187, 63, 53, 26,205, 54,173, 86, 43,215,106,181,114,157, 78, 55, 63, 53,
+ 53,181,235, 87, 95,125, 85, 64, 81, 84,149,181,180,224,249,169, 59,241, 55,127, 89,105,111, 43, 19,118, 12,108,227,181,110,219,
+209,107,233, 25,121,191, 86,203,161, 85, 83, 57,181, 74,141,246,163, 65, 67, 70,171, 74, 75,116, 8,254,114, 14,104,129, 4, 58,
+ 10, 48, 50, 44,152, 8, 50,219, 13, 77, 0, 0, 32, 0, 73, 68, 65, 84, 54,158, 46, 95, 7,161,181, 20,251, 83, 30,169,203,140,
+134,143,240,102, 14,173,186,234,254,103,208,200,217,200,217,200,249,207,228,252,111,134, 19,222, 92,235,208,233, 13,139, 86,125,
+ 33,149,206,206,206, 93, 7, 14,232,133,238,253, 22,128, 97, 24,196, 63, 90,131,146,130, 23,112,118,228, 35, 41, 93, 17, 12, 32,
+170, 1,133, 73, 79,205,200,232, 48,125,254,130,227, 97,189,123,182,242,113,115,227, 55,107,214, 20, 98,123,123, 20, 22, 22,224,
+230,221,231,198, 21, 7,142,196, 86,136, 44,179, 38, 38,105,154,126,237,228, 14,160,231,244,217, 32, 88, 44,160, 34,141, 67,101,
+199,232, 22,216, 17, 4,155, 13,138,161,161,211,233,204,137,150,203,124,245,234,213, 71,163, 70,141,186, 18, 17, 17, 65,134,134,
+134,250,159, 56,113,226,207,172,153, 7, 85,126,194, 85, 0,253, 86,204,157,116,168, 67,143, 65, 22,158,109,218,113,219, 53, 99,
+193, 96, 36,144,157,149,134,136,227,247, 13,207,239, 93, 80, 48, 38,237,112,117, 97,194,213,186,184, 12, 6, 67,122,139, 22, 45,
+ 28,182,110,221, 90,229, 12, 79, 81, 20, 10, 11, 11,113,231,206, 29,248, 6, 6,161,213,184, 79, 80, 80, 80,128, 13, 27, 54,160,
+ 73,147, 38,232,223,191, 63,138,139,139, 97, 50,153,204,157,240,165, 0, 92,168,216,240,150,200, 34, 42,150, 0,170,115,218,208,
+195,195,131,167,213,106,253, 25,134, 97, 17, 4,241,131, 94,175, 31, 59,119,238, 92,167,149, 43, 87,194,203,203, 11,133,133,133,
+ 16,139,197,240,244,244, 68, 65, 65, 1,238,223,191, 79,169,213,234,173,120,189,144,117, 65, 61,229, 75,188,127, 63,165,195,180,
+105,159, 31,255,110,245, 36, 79,173,174, 59,207,218,186, 51, 24,198,132,130,130, 84,148, 43,110, 25,150, 45,221,253, 42, 47,223,
+ 56, 4, 64,130,153,117, 94, 52,101,202, 20, 0, 16, 0, 88,144,148,148, 20,211,170, 85, 43,207,218, 44, 90,230, 96,253,209, 44,
+ 45,128, 3, 31,133,202,103, 40, 10,159,120, 90,179, 83, 83, 58,248,208, 27,214, 31,205,210, 90,200, 85,203, 11, 83,163, 94,230,
+168, 46,108,221,115,252, 24,107,204,224,143, 40, 23, 73,194, 28,129, 61,115,212, 12,106,198,207,207,207,149, 32,138,221,243,139,
+ 94, 60, 28, 63, 97,210, 48, 75,174,230,172,159, 75, 81,115,178, 73,128, 32, 58, 58, 58, 5, 13,140, 12,173,192,203,172,172,172,
+174,115,231,206,189,192, 48,204, 27,190, 9,249,133,197,145,193,253,166, 48,165,165,101, 49, 5,113,167,204,201,165,118,255,254,
+163,232,158, 62,190, 1,199,190, 91,185,218,161,251,244,175,216, 47,175, 94, 3, 40, 35,210,162,174,129,226,235,233,117,183, 47,
+229,149, 25, 12,131,209,152, 21,190, 17,141,248,159,183,102,213,165, 69,254,225,232,139, 90,156,225,205,174,140,135,187,243, 5,
+ 47,207,102,189,155,184,216, 1, 0,146, 82,178,145,148,146,117, 49, 41, 57, 43,180, 30,197, 91, 91,120,101,213,162,210, 68, 69,
+ 10, 7,198,188, 69,165,223,224,180,177,177,121,200,102,179, 93, 26,114, 54, 40,138,202, 46, 44, 44, 12, 48,179,156, 35,221,220,
+220, 86,167,165,165, 29,167,105,122, 70, 3,213,126,141,156,149,139, 74,147,108, 94, 47,198,164,247, 5, 0,130,205, 51,103, 81,
+233,234,156,190, 18,137,100, 27,135,195,105, 82,121, 29, 43,125,176, 40,138, 98, 25, 12, 6, 1, 69, 81, 44, 0, 4, 73,146, 38,
+ 14,135,163, 37, 8,194,100, 50,153,210,117, 58,221, 36,252,158,112,180,174,186,215,219,209, 87, 8, 45,212, 96,209,186, 12, 0,
+ 9, 9, 9, 45,101, 50,217,112,130, 32,134, 50, 12,227, 93, 94, 94,174, 91,184,112, 97,244,145, 35, 71, 20,110,110,110, 31,244,
+237,219,151,120,242,228, 9, 98, 99, 99,153,162,162,162,163, 21, 86,172,164, 6,222, 75, 36,159,207, 26, 97,109, 77,246,101, 24,
+248,129, 1, 65,144,120, 90, 86, 70,159, 85,171,169, 95, 43, 4, 99, 67,239,207, 74,124,220,172, 89,179,221, 41, 41, 41,156,218,
+ 44,169,181,213,253,109,172,153,223,102, 65,112,151, 46, 31,221,185,113,227,196,172, 21,207,150, 86,255,110,234, 32,217,248,145,
+ 95, 76, 95,115, 96,243,143,179, 54,254, 86,178,203,156,114,250,251,251,123, 16, 4, 49, 28,128, 15,195, 48, 45, 24,134, 16, 16,
+ 4, 83, 66, 16,196, 51, 0, 79,244,122,125,196,243,231,207, 51,255, 68,221,223,101,132, 91, 27,103,213,162,210,160,168,182, 20,
+192,152,185,168,244,191,187,156,141,156,141,156,141,156,255, 57,206,255,102,124, 90,195,103,230,101,134,175, 68, 82,114, 86,104,
+ 82,114, 22, 90,180,104,193, 36, 38, 38, 54, 72,164,213,214, 73, 83, 20,117, 80,173, 86, 31,252, 51, 36, 69, 69, 69,237,254,230,
+147,119, 32, 37, 37,229,192, 95, 73, 88, 33,164,150, 86,108,239,138,167, 74,165, 50,200,220,157, 13, 6,195,223,113,110,136, 10,
+107,214,146,218,118,232,221,187,119,154,193, 96,184, 12, 32,131, 32, 8, 43, 0,197, 6,131,225,130,201,100,202, 75, 76, 76,108,
+183,110,221,186,202,204,247,203, 0, 60,124,199,114,208, 58, 29,181, 63, 59,155,218,255, 55,212,113,191, 94,175,159,105, 99, 99,
+211, 92,171,213,242,180, 90, 45,183,122,240,129, 80, 40, 44,168,203, 33,190, 58,172,164,196, 47, 92,118,137,141,149,148,120, 91,
+ 72,193,218, 25,199, 52,170, 88, 47,107,103, 28, 51,183, 96, 49, 49, 49, 73,126,126,126,251, 72,146,116, 99, 24,198, 1, 96, 44,
+ 25, 6, 5, 12,195, 20,178,217,236,172,231,207,159,103,253,131, 26, 33,173,137,166,215,154,244,250,223,253, 14, 27,163, 11, 27,
+209,136, 70,252,255, 65,173, 62, 90,236,134, 50, 37, 38, 38, 18,141,231,179, 17,213,197, 86, 93, 95,166,165,165,233, 0,220,174,
+216,222,198, 67, 0,253,255,233, 21,204,201,201, 9,168,237, 59,115, 69, 22,240,218,103, 11,136,173, 49, 59,251,226,141, 37,229,
+216,120,252,155,134,150,237,241,227,199,233, 48,115,138,189, 17,141,104, 68, 35, 26,241,183,225,207, 91,180, 26,209,136, 70, 52,
+162, 17,141,104, 68, 35, 26, 81, 35,182, 87, 19, 92,111, 88,183, 8,212, 30, 57,208,144,185,215,119,137, 62,184,220,200,217,200,
+217,200,217,200,217,200,217,200,217,200,249, 63,199,249,255, 21,127, 16, 89,255, 14, 52,134,190, 54,114, 54,114, 54,114, 54,114,
+ 54,114, 54,114, 54,114,254, 47,136,172,183, 55, 0,141, 83,135,141,104, 68, 35,254,135,113,228,200, 17,179, 22, 21, 29, 49,107,
+ 71, 63,137, 68,182, 80,169, 40, 91,125,112,237,248, 19,149,159,135,133,133, 81,141,103,177, 17,141,104, 4,222,197, 25,222,221,
+221,165, 53, 73,209,157, 24,134,100, 49, 36, 99, 36, 20,154, 67, 73, 37, 37,111,164, 29,112,117,117,181,226,144,232, 79, 48,140,
+152, 32,104,138,102,145,183,146,147, 51,159, 55,160, 96, 60,153, 76, 54,133,203,229,246,210,235,245, 46, 36, 73,102,234,116,186,
+203,106,181,122, 19,254,152,184,240, 63,134,150, 45, 91,142,188,118,237,154, 85,231,206,157,117, 66,161,208,164,209,104,216,231,
+207,159,231,127,248,225,135,165,175, 94,189,122,167,136, 68,185, 92,222, 99,199,142, 29,238,161,161,161,104,209,162,133,106,248,
+240,225,220,224,224, 96,238,132, 9, 19,146,179,179,179, 35, 27, 72,215,154, 32,136,189, 4, 65,176,104,154, 14,199,239,169, 27,
+254,106,144, 36, 73, 78, 34, 8, 98, 48,195, 48, 30, 4, 65, 36, 49, 12,115,130,166,233,186, 18,183,214,133,143, 0,244, 33, 73,
+ 50, 0, 0,104,154,142, 6,112, 22, 48, 63,242,238,223,201, 41, 18,137,252, 1, 64,173, 86,199,252, 85,156, 4, 65,248, 3, 0,
+195, 48,239,202, 57, 78, 40, 20, 78, 4, 0,141, 70,243, 51,204, 88, 14,234,109, 48, 91,189,153,128, 37,241, 0,128,232, 69,222,
+ 0,128,134,188, 39, 38,199, 19, 13,249,173,154,248, 26,194, 81, 3,250,140, 26, 53,106,229,175,191,254,186, 8,192,201,191,227,
+198,119,116,116,221,244,253,143,219,229, 95, 78,249,100, 53, 94,175, 8, 81,247, 3, 9,188,207, 99,177, 6,232, 41,234,198,115,
+224, 8, 0,182,181,181,245, 72, 30,143,215, 85,175,215, 59,177,217,236, 28,189, 94,127,189,172,172,236, 0,234, 88, 1,193,236,
+243, 26, 7,153, 65, 13, 71,130,254,125,157, 55,134,132,142, 43, 66, 46,209, 10, 37,255,128,102,148, 4, 48,189,162,174, 59, 81,
+123, 58,143,186, 26,159, 47,229,114,249, 96,133, 66,161,102,177, 88, 12, 94, 71, 61,191,254,243,250,123,130,166,233,252,226,226,
+226,240,250,184,196, 77,224,197, 19, 19,123, 41, 35, 52, 38, 29,243,153, 42, 3,241, 18, 87,116,100,128,112, 6,112, 35, 89,164,
+ 29, 77,211, 57, 0, 34, 73, 19, 78, 43,179,145,248, 15,237,220,155, 86,156,215,102, 21,239, 57, 0, 28, 0, 60, 1,240, 37, 0,
+101,163,254,249,183,225,109,103,248, 51, 0,114,170,132, 86,181,116,247,221,251,245,235, 23,229,238,238,210,122,232,160, 33, 43,
+ 39, 79,250,140, 96,177, 72,196, 62,123,198,254, 56,124, 92,111,153, 76,230, 44,209,233, 90,129, 32,104,181, 64, 16,171, 80,148,
+101, 29, 57,240,171,212,219,203,139,162, 40, 26, 91,183,253,244,225,209,223,142,207, 51, 83,108,181,116,116,116,220, 59,103,206,
+ 28,199, 1, 3, 6,176, 28, 29, 29,145,154,154,106,117,240,224, 65,175,141, 27, 55, 14, 43, 41, 41, 9, 7,240,242, 29, 42,219,
+197,209,154,236, 45, 21, 18, 61, 81, 78,161,220,136, 43,185, 26, 92, 4,112,227, 93,207,158, 90,173,158,170, 86,171,131, 2, 3,
+ 3,153,157, 59,119, 18, 99,199,142,101, 8,130, 32, 52, 26,205, 47, 0,222, 73,104,137,197,226,205,161,161,161,158,158,158,158,
+ 73,175, 94,189,234,115,248,240,225,179, 99,198,140,241, 16,139,197, 9, 0, 90, 54,144,110,119, 81, 81,145,159, 70,163,129,139,
+139,203, 78, 0,239,253, 13, 55, 17,193, 98,177, 78, 56, 59, 59, 51,107,214,172, 57,233,231,231,231, 80, 92, 92,108,250,230,155,
+111,122,221,189,123,247, 67,138,162, 6, 52, 64,108,201, 8,130,216,230,224,224, 96,187,122,245,234,196,118,237,218, 61,225,243,
+249,188,132,132, 4,209,204,153, 51,103,188,124,249,114, 24,195, 48,147,128, 6,117, 16, 50,130, 32,182,201,229,114,219,149, 43,
+ 87,166, 6, 4, 4,196,114,185, 92,110, 66, 66,130,120,246,236,217, 95,198,199,199,191, 19, 39, 73,146, 91,131,130,130,100,139,
+ 22, 45,138,243,242,242,186,205, 98,177,120,153,153,153,228,226,197,139,167, 92,186,116, 41,140,166,233,201,239, 82, 78,123,123,
+123,217,226,197,139,227,130,131,131,239,114,185, 92,238,139, 23, 47,200, 57,115,230, 76, 73, 76, 76, 52,187,156,214,214,214, 33,
+ 4, 65,108,207,205,205,101, 3,128,147,147, 83,123, 11, 11,139,141,213,215,180,172, 76, 69, 97, 52, 26,203,181, 90,237,168,226,
+226,226, 26, 19,225,142,157,187,161, 63, 0,108, 52, 84,190,127,253, 90,223,123, 96,235,105,115, 42,237,239,248, 58, 47,222,247,
+170,241,131, 0, 96,100,197, 82,225,223,171, 0, 54,155, 77,251, 59,126,201,196,228, 54, 40,101,204,192, 30, 61,122, 44,142,140,
+140,252,169,123,247,238,179,247,237,219,103,159,145,145,241,221,141, 27, 55, 92, 71,140, 24, 49,246,202,149, 43,171, 10, 11, 11,
+143,254, 85, 55, 63,143,203,231, 19, 36, 1,161, 64,100, 97,206,254, 28,146,236,119,123,224,192,137, 63,191,120, 17,176, 49, 62,
+222, 93,229,228, 20, 52,109,218, 52,135, 33, 67,134,144,174,174,174, 72, 76, 76,180,217,183,111, 95,171,159,127,254,121,112,105,
+105,233,116, 0,105,127, 70,100,169, 74,225,171,211, 35,128, 97, 96, 85,245,192, 18, 40,229, 27, 16,205,196,225,233, 63, 64,108,
+125,187,123,247,238, 69,137,137,137, 88,181,106, 21, 0,108,106,224,241, 51, 7, 14, 28,216,247,248,241,227,194, 35, 71,142, 8,
+ 3, 3, 3,225,232,232,136,138,193, 84, 85, 98,106,119,119,119,243,206, 25,141,239,127, 56, 59,254,189,216,226,115,216, 60, 36,
+119,149,208, 5,166,142, 3, 61, 7,247, 27, 27, 0, 75, 59, 17, 4, 18, 54, 74,139, 20, 62, 47,162, 51, 66,175, 30, 78,252, 46,
+241, 81,193,106, 85, 58,190, 69,237, 57,249,254, 35,176,177,177,217,153,156,156, 28, 34, 22,139,223,248, 60, 41, 41,201,223,211,
+211,179, 12,192, 87, 13, 21,110,118,118,118,251,105,154,214, 21, 21, 21,125, 2, 0, 82,169,244, 87,177, 88, 44,203,201,201,153,
+247,119, 13,100, 42,241,182, 22,249, 47,183,104, 85,249,107,213,180,214, 33, 65, 82,116,167,201,147, 62, 35,134,143, 28,145,155,
+152,148, 76,179, 57,188,145,231, 47, 92, 16,181,110,221,154,212,109,218, 4, 83, 65, 1,140, 51,102,116,188,124,249,178, 49,108,
+228,104, 13,135, 69,236,246,112,119, 19, 29, 58,112,208,241,248,177,163,157, 0,212, 39,180,120,142,142,142,123,175, 93,187,230,
+236,238,238,142,210,210, 82,164,166,166, 66,165, 82, 97,216,176, 97,156, 78,157, 58, 57, 15, 29, 58,116,111, 89, 89, 89,231, 6,
+ 88,182, 28, 90,184,176, 35, 38,141, 27,210,242,195,222,157,196,206,174,205,193,228,106,145,241, 42, 62, 48,226,218,221,105,187,
+143,157,125,153, 88,198,244, 67,205,107, 35,213,137,194,194,194, 89,131, 7, 15, 62, 22, 18, 18, 98,199,231,243, 33,151,203,137,
+ 1, 3, 6,228,103,103,103, 47,121,103,213, 82,177,132, 13, 73,146, 84,245,215, 26,150, 7, 50, 7, 46, 50,153, 12, 50,153, 12,
+ 0,156,255,236,200,211,202,202,106,147, 84, 42, 29,170, 80, 40, 52, 36, 73, 50, 4, 65, 48,122,189, 94, 40,147,201, 30,199,197,
+191,148,235,116,186, 22,107,127,248,249,199, 30, 93,252, 44, 46, 93,186,132, 33, 67,134, 48, 23, 47, 94,156,100,238, 58,117, 4,
+ 65,108, 27, 60,120,176,122,225,194,133,218,196,164, 84,231,184,151, 73,132, 88,192,163,109,109,109, 57,247,239,223,103,175, 95,
+191, 94,176,120,241,226,109, 12,195, 12,109,192,249,220, 54, 98,196, 8,195,215, 95,127,157,243, 34, 49,217,254,105, 92, 34, 35,
+ 17,112, 76,182,182, 54,172,187,119,239,210,239,194, 73,146,228,214, 89,179,102, 41, 38, 77,154, 84, 82, 84, 92,230, 88,162, 80,
+ 50,124, 14,203,232,232,232,200, 62,121,242,164,110,255,254,253,228,196,137, 19,183,210, 52, 29,214,128,243,187,117,192,128, 1,
+229,115,230,204, 41, 77, 72, 74,113,124,250,252, 37, 68,124,142,209,193,193,158,245,224,193, 3,195,218,181,107,201,229,203,151,
+155, 85, 78,177, 88,188,231,240,225,195,236,147, 39, 95,183,125,119,238,220, 33, 61, 60, 60, 68,213,247,209,104,117, 32, 9,160,
+176,176, 80, 20, 28, 28,188, 7,192, 31,146,251, 6, 44,137,199,216,185,192,212,169, 83,115, 26,122,179, 4, 56, 77,171,119, 31,
+234, 39,111,102,189,122,252, 32, 54,155, 77, 79,156, 56, 49,247,237,239,181, 90, 45, 1, 96, 0,190, 51, 95,108,245,233,211,103,
+254,153, 51,103,154,239,219,183,111,221,254,253,251,245, 0, 32, 16, 8,108, 15, 30, 60,184,106,216,176, 97, 24, 54,108,216,194,
+163, 71,143,254,101, 66,139, 98, 40, 3, 0,240, 5,124,126,124,124, 60,225,237,237, 93,103,198,125, 3, 77, 63,252,249,197,139,
+118,159,123,123, 7, 22,211,116, 11,238,135, 31, 42,103,206,156, 89,168, 80, 40,144,154,154, 10,131,193,128,177, 99,199,178,186,
+119,239, 46, 31, 54,108,216,134,242,242,242,143, 0, 24,204,184, 39,215, 58, 59, 59,127, 90, 86, 86,166,172,180,234,116, 14,167,
+216, 93,253, 77,252,182, 45,140, 60, 46,203,196,237, 63,131, 38, 46,110, 34, 84,222,238,184, 9, 0, 92, 53, 10, 26, 56, 24,168,
+ 17, 22, 46,112,167, 56, 88,110,231, 34,236, 81,144,166, 89,170, 74,175, 83, 44,125, 36, 22,139, 7,169, 84,170,163, 21,157,115,
+203,126,253,250,225,238,221,187, 0,208,169, 66,104,245, 32, 73,242, 99,154,166,119, 0,168,107, 41,183,105, 3, 7, 14,124,255,
+248,241,227, 82, 0, 56,122,244, 40,140, 70, 35, 60, 60, 60,192,229,114,193,227,241,192,225,112,170, 86, 7, 49, 19, 78,118,118,
+182,176,181,228, 64,102, 45,254,112,246,150,129,236, 38,173, 45,144, 79, 61, 67, 49, 83, 10, 19,163, 3,215, 70, 12,175, 80, 43,
+ 4,244,238, 65,158,222, 26, 59,239,244,230,184,118,106, 18,253,145, 6,221, 63,165,103, 39, 73,146,255,228,201, 19,200,229,242,
+ 55, 62,103,177, 88, 0,208,245, 29, 40, 23, 38, 37, 37, 5, 63,122,244, 8, 33, 33, 33, 11,125,125,125, 63,136,138,138,114, 44,
+ 42, 42, 66, 72, 72,200,134,204,204,204,147,127,119,157,170,107,145,255, 47,166, 46,242, 45, 37,217,253,245, 40,152,100,177, 88,
+ 36,146,147, 82,141, 33, 33, 61,199,164,167,167, 75,130,130,130, 72, 14,135, 3, 85,100, 36,180, 15, 30, 64, 34,145, 96,240,224,
+193,156,235,215,175, 91, 88, 72, 44, 38,164, 36,167,148,179, 88, 36, 24,134,172,215,231, 65, 38,147, 77,153, 55,111,158,163,167,
+167, 39, 76, 38, 83, 85, 70,115,147,201,132,140,140, 12, 72, 36, 18,132,135,135,219,139, 68,162, 41,102,214,163, 89, 75, 15,251,
+232,107,103,183,189, 55,115,114, 31,113, 75,209, 37,136, 51,166, 67,114,244,115,180,202, 62,143, 57,131,130,196, 23, 55, 47, 12,
+104, 46,183,142,174,102, 98, 53, 27, 58,157,238,102,108,108,236,132,168,168, 40, 26, 0,174, 94,189,202,196,197,197, 77,250, 51,
+163, 80,154,166, 81, 90, 90, 10,154,166, 89, 21,239, 43, 95,255,163,247,131,133,133,197,214, 15, 62,248, 96, 68, 90, 90,154,240,
+220,185,115, 54,233,233,233,182, 41, 41, 41,118, 45, 91,182,100,175, 90,181,234,140, 86,103, 96, 25, 41, 70,111,162,140,229, 57,
+207,158, 37,149,228,229, 69,239,218,181, 75, 67, 16,196, 96, 51,127,227, 35, 39, 39, 39,155,185,115,231,130,224,136,218,123,181,
+242,245,100,113,132,150, 36,135,103,169,209,104,169,228,228,228,140,185,115,231,186,249,249,249,201,241,122,122,205, 44, 78,185,
+ 92,110,251,245,215, 95,131,205,151,250,183,245, 11,104,206,227,139,165, 44,142, 80, 26, 20, 20,212, 61, 41, 41, 41,123,206,156,
+ 57, 78,129,129,129, 13,226, 12, 12, 12,148, 77,156, 56,209, 36, 16, 74,131,221,221, 61, 90,181,109,211,170,111,203,150, 45, 7,
+177,217,108, 83, 65, 65, 65, 90,120,120,184, 83,255,254,253, 29, 26,194,105,111,111, 47,155, 51,103,142,201,181,169, 71,104,232,
+251,189, 59,112,133, 82, 75, 54, 79,108,165, 86,107,169, 23, 47, 94,164, 45, 88,176,192,201,223,223,223,222, 28, 78,181, 90,205,
+177,181,181,133,143,143, 15, 90,123,120,160,172,172, 12,199,143, 31,199,238,221,187,177, 99,199, 14, 28, 56,112, 0,237, 58,247,
+134, 84, 42, 69,118,118, 54, 20, 10, 5,231,223,125, 67, 81, 63,121, 51, 27,245,159, 14,248,236,179,207,178, 39, 78,156,152, 43,
+ 20, 10,233,183, 55,107,107,107,106,212,168, 81,121,225,179,127, 24, 80, 57,181, 88,143, 37,235,201,217,179,103, 95,237,219,183,
+ 15,173, 91,183, 70,104,104, 40, 15, 0,166, 76,153,194, 27, 54,108, 24, 14, 31, 62,140,163, 71,143, 62,247,244,244,188, 5, 96,
+160, 57,229, 12, 15, 15,239, 28, 22, 22,118, 35, 44, 44, 44,102,248,240,225,219, 39, 77,154,244, 70,207,149,147,157,249, 80,175,
+215,195, 47, 32, 80,180,108,231,189, 81,245,241,197, 1,251,182,199,199,239, 94,253,236, 89,218,194,214,173,173,154,166,164, 88,
+255,178,118,173,109,229, 34,221, 70,163, 17, 25, 25, 25,144,201,100, 24, 53,106,148, 45,159,207, 15, 55,163,152,235, 7, 14, 28,
+ 56, 46, 61, 61, 93,242,243,207, 63, 59,197,196,196,200,115,114,114,156,174, 92,190, 96,247,205, 87, 83,164,150, 18, 30, 47,187,
+128, 33, 0, 32, 37, 27,226,248,100,116,102, 24, 88, 85,159, 78,124, 39, 56, 65, 40,116,193,198,230,157,173, 94,126,125,216,127,
+248,156,136, 0, 91,153, 19,127,110, 29, 71,180, 93,179,102,205,145,211,167, 79,143,236,220,185,243, 49, 0,194, 26,246, 17,180,
+107,215,238,248,225,195,135,199,117,233,210,229, 38, 0,159, 90, 71,145, 46, 46,131,127,251,237, 55,155,202,247,182,182,182, 16,
+ 8, 4,127, 16, 89, 92, 46, 23, 36, 73, 54,184,122, 43, 14,142,100, 91,183,210, 33,182,228, 44, 14,175,121,130, 53, 31,190,160,
+ 87,118, 76,209,109, 10,143,199,197,195, 79,144,143, 39,232,243,121,115,140, 92,224,215, 75, 68, 97,249, 63,169, 3, 47, 40, 40,
+248,184,107,215,174, 71,250,244,233,163,123,244,232, 17, 10, 10, 10,224,236, 92, 53,214,206,125, 7, 74,107,145, 72, 4, 87, 87,
+ 87,120,122,122,142,188,126,253,186,163,209,104, 68, 74, 74, 10,242,243,243,163,255, 29,117,170,174, 69,254,203,240,182, 35,252,
+153, 63, 8,173,138,181,133,174, 1, 0, 67, 16,170, 39,177,177, 28, 22,143, 55,250,215,253,251,249, 92, 46, 23,105,105,105,120,
+254,252, 57,212, 87,174, 64,115,251, 54,242,242,242,160, 84, 42,225,224,224,128,109, 59,119,138,245, 20, 51,254,197,203,151, 44,
+134,100,170,251, 27,212, 24,226,201,231,243,123, 13, 25, 50,164, 86, 65,150,157,157,141, 62,125,250,112, 88, 44, 86, 77, 81, 13,
+111,115, 18,114, 59,226,244,149, 99,203,156,156,120,207,129,196,153, 64,121, 52,192,232, 0,147, 30,200,122, 10,156, 89,130,166,
+202,120,226,194,178, 49,142,206, 34,246,233, 26,148,114,125,161,168, 30,222,222,222, 59, 70,143, 30, 77, 2, 64,143, 30, 61, 8,
+111,111,239,237, 0, 60,234, 56,230,114, 61,157,228,221,146,146, 18, 12, 27, 54,204,166,121,243,230,151,135, 13, 27,102, 83,249,
+249,187,114, 86, 90,147, 91,183,110, 93, 36, 16, 8, 14, 0,102, 53,176, 85,156, 86, 86, 86,155,250,244,233, 51,116,255,254,253,
+ 92, 0,184,118,237, 26, 78,159, 62,141,103,207,158, 33, 33, 33,129, 14, 8, 8,176,251, 97,199,145,173,155,126,218,179,126, 80,
+ 39, 63,121,247,246, 1,173, 36,202, 18,165,131,131, 67, 39,134, 97, 60,204, 44,103,159, 37, 75,150, 60,143,123,149,102, 73,178,
+ 57,108, 46,135,205,183,176, 16, 59,200,164, 98, 23,107,145,192,153, 79, 18, 18,181, 90,157,123,224,192, 1, 26, 64, 31,115, 57,
+151, 45, 91,150, 28,151,152,102, 69,144,108, 54,135,205,225, 74, 36, 34,171, 15, 67, 67, 2, 1,128, 11,134,171, 80, 40,242,118,
+239,222,109,104, 8,231,162, 69,139, 98,139, 75,149, 50, 54,135,195, 97,179, 89, 85,231, 82, 44, 20,218,137,248,124,158, 78,167,
+203,250,241,199, 31, 53, 13,225, 92,178,100,201,243, 23,175,210,173, 73,130, 96, 17, 4,201,182,144,138,109,108, 44, 69,118,118,
+ 18,161,173,136,205,226, 41, 20,138,172,189,123,247,154,197,105, 48, 24,184,121,121,121,136,139,139,131,107, 96, 32, 46, 93,186,
+132, 38, 77,154, 96,216,176, 97, 24, 49, 98, 4,132, 66, 33,122, 4,251, 98,238,220,185,120,245,234, 21, 12, 6, 3,191, 38,206,
+ 74, 63,169,183, 33,151,203, 31,213,119,243,188,117,236, 27,229,244,119, 4,179, 81,255,233,128,234, 2,171, 54,126,107,107,107,
+170, 38,107,215,219,156,125,250,244,153,127,229,202,149,230,123,247,238, 29, 16, 30, 30,126,115,239,222,189,232,208,161, 3,226,
+226,226,224,230,230,134, 95,126,249, 5, 35, 70,140,184,185, 97,195,134, 1,143, 30, 61,242,115,119,119,159, 87, 31,231,240,225,
+195,191,240,247,247,143,204,205,205, 13, 46, 46, 46,246, 57,126,252,248,248,193,131, 7, 39,143, 28, 57,178,103,149, 96, 52, 26,
+247,159, 57,117, 12,125, 7, 12,129, 87, 27,159,173, 99,231,237,243,173,231,217,100,158, 1,219,119,231,228, 20,236,215,106,213,
+195, 56, 28,145,232,222, 61,235,163, 63,253,100, 91,125,101,129,172,172, 44,244,239,223,159,195,229,114,187,212, 83,206, 53,131,
+ 6, 13, 26,118,252,248,113, 89,165, 85,231,246,237,219,120,250,244, 41, 82, 83, 83, 81, 90, 90,138,158,147,148,248,108,213,107,
+238,207, 86, 49,232, 61,133, 17,191, 99, 27, 82, 5, 97, 19, 56,218, 88,176,111,141,255,209,107,202,167, 91, 91,179, 37,214, 28,
+252, 58, 59, 1,133, 41,186,163,181,112, 18,193,193,193,251,194,194,194, 8,189, 94, 15,189, 94,175, 7, 80, 99, 86, 95,103,103,
+103, 65,219,182,109, 49,105,210, 36,210,194,194, 98, 67,109,229, 84,169, 84,186,179,103,207, 34, 60, 60, 28,211,167, 79, 71,139,
+ 22, 45, 32,147,201,192,225,112,176,103,223, 33,219, 17,227, 39,183,124,175,115, 87,191,214,239,117,104, 91,174, 99, 5,114,132,
+178,137,181, 88, 67,106,172,187,210,254, 17, 98, 83,238, 96,227,128, 76,250,254, 47,106,229, 55, 31,255, 43,254, 69, 84,222,179,
+121, 97,219, 99,153, 59, 29, 11,247,125,153,142, 60, 99, 28,186, 12,107, 10,119,127,217, 12,177, 43,188,223,245,124,154,137, 6,
+113,250,250,250,118,190,127,255, 62,191,107,215,174, 72, 75, 75, 3,135, 83, 53,158,162,254, 76, 57,151, 44, 89,194,215,106,181,
+120,252,248, 49,198,140, 25,147,101, 48, 24,102,252,153,114, 54,196,162, 85,169, 69,254,203,176,253,173, 45,167, 54,139,214, 18,
+ 0, 48,210, 56, 61,122,204,120,117, 68, 68,132,136,199,227, 33, 45, 45, 13, 57, 57, 57,216,179,123, 55,213,195,222,190, 60,212,
+217, 89,177,103,247,110, 70,175,215,131, 97, 24,120,123,123, 99,232,208,161,194,143,134,141,204, 39, 20,154, 67,102, 76,243, 56,
+ 85,206,175,143, 31, 63,254, 15,223,127,243,205, 55,176,176,176, 0, 65, 16,142,102, 84, 46,108,218,146, 65, 46, 50,119,171, 60,
+ 38,119, 79, 49, 88, 2,128, 45, 5,216, 22,128,192, 18,224, 75, 1,158, 8,186, 71,145,197, 36, 19,154, 58,164,203, 39,206, 0,
+ 26, 50,213, 3,185, 92,190, 48, 50, 50,210,238,209,163, 71,140, 66,161, 64, 78, 78, 14,179,114,229, 74, 59,185, 92,190,240, 93,
+175, 72,118,118,246,178,190,125,251,230,141, 25, 51,198,242,252,249,243,174, 99,198,140,177,236,219,183,111, 94,118,118,246,178,
+ 63,115,165,185, 92, 46,235,217,179,103,214,203,151, 47, 31, 1,224, 97,155, 54,109,138,156,157,157, 31,226,181,211,100,157,144,
+ 74,165, 85, 34,171,210,186,198,102,179,193,225,112, 32,151,203,245,197,197,197, 84,151,247, 60,132,222,150,164, 81,206,231, 10,
+173,133, 2, 23,169,133,101, 80, 81, 81,209, 19,130, 32,146,204,156,226,243,111,223,190, 61,135, 98, 56,244,103,163,123,200,167,
+140, 11,177,223,178,124, 98,147, 31,151,125,234,188,102,241, 4,239,101,179, 70,133,144, 52,173,117,115,115,115,172,116,104, 55,
+195,124, 30,208,174, 93, 59, 54, 13, 14,226, 94,166,230,165,101,102,149,191,223, 61,184,202,114,217,218, 63, 32,212,206,206,174,
+171,183,183,119, 59,130, 32,204, 10, 73, 22, 10,133,254, 94, 94, 94,108,146,197, 33,108,100, 82, 87,169, 68,232, 80, 53,133, 98,
+101,213,209,218,206, 46,140,100,152, 50, 39, 39, 39,123,161, 80,232,223,128,186,179,105,112,225, 96,111,109,105,103,107, 37, 9,
+ 13,233,212, 34,184, 99,112, 75,223,160, 14,193,109,222,107,247, 17, 97, 50, 41, 60, 60, 60,236, 43,157,228,235,177,180, 10,246,
+239,223,143,229,203,151,163,109,211,166,112,118,118,134,189,189, 61,110,223,190,141,251,247,239, 67, 38,147, 33, 63, 63, 31,107,
+215,174,197,137, 19, 39, 96, 48, 24,164, 13,189,159,204, 17, 91,117,193,100, 50,145,111, 11,172,218,248,133, 66, 33, 93,233, 36,
+ 95, 27,206,158, 61,187,175,210,146,245,229,151, 95,118,254,225,135, 31,110,198,199,199, 67, 34,145,224,254,253,251, 24, 63,126,
+252,205, 13, 27, 54,116,158, 60,121, 50,118,239,222,141,228,228,228,157,117,241, 13, 31, 62,124,241,132, 9, 19,126,140,138,138,
+ 34, 29, 28, 28, 32,147,201, 48,104,208, 32,236,220,185,147,109, 50,153,118,133,133,133,197,132,133,133,197, 80, 25, 23,231, 31,
+217,177,242,118,236,147, 24,124, 49,237,107,158,222,100,156, 99, 70,245, 25,141, 68, 82,110,234,218,181,248,176,209,168, 30,206,
+229,138, 44, 99, 98,172, 79,239,218, 85, 37,182,230,206,157, 11, 75, 75, 75,224,181, 3, 51,234,176,234,124,122,226,196,137,170,
+246,208,198,198, 6, 60, 30, 15, 92, 46, 23, 28, 14, 7, 44, 22, 11,151,183,138,241,211,220,215,250,226,167,185, 4, 46,110, 34,
+ 84,127,230,218,137,156,225, 35,115,224,197,124,254, 75, 27, 63,159,158, 54,184,125, 48, 23, 43,251, 62,202,188,127,184, 96,166,
+ 54, 31,223,215,114,216,123,223,124,243, 77,235,252,252,124, 60,120,240, 0, 15, 30, 60,168,205, 2,164, 61,117,234,212,119, 74,
+165, 18,238,238,238, 24, 56,112, 96, 87, 0,129,181, 60, 55,104,215,174, 29,250,247,239,143,144,144, 16,180,109,219, 22,122,131,
+137, 19, 54,250, 83,175,103,201, 5,206, 43,215,174, 20, 69, 94, 61, 78,222,188, 25,197,218,119,236,162,101,112, 72,239, 31,185,
+ 82,167,187, 16,218, 56,153, 83, 79, 53, 85, 4,127,167, 15,177,253,202, 52,114,227,181, 49,146, 61,167, 55,122, 72,165, 82, 34,
+250, 65,140,113,207,230,195,233, 62,226,129,249,119, 15, 22, 65, 77,228,162,231, 56,119,146, 6,134,254, 83,122,118,129, 64,240,
+ 67, 84, 84,148,163,193, 96, 64,108,108, 44,166, 79,159,174,253,147,148, 85, 6, 16, 87, 87, 87, 92,187,118, 13,163, 70,141,210,
+230,229,229,221,249,119,213,169,186, 22,249,255, 2,118, 53, 5, 89,133,140,140,140, 82,153, 76,230,236,229,229, 69,234,245,250,
+215, 83, 18, 71,143, 82, 59,118,237, 58,163,213,106,167, 1,224,110,218,178,101,171,179,139, 75,200,232,240,112,194,104, 52,162,
+111,223,190,188,136,136, 8,155,164,252,252,114, 51, 58,156, 55,126,111,236,216,177,248,225,135, 31, 0, 0, 83,167, 78,173, 50,
+173, 19,102, 56, 44, 73, 44,209, 39,180, 95, 59,139, 12,241, 70, 11, 67, 71,163,178,217, 43,233, 93,177, 82,216, 14, 36,143, 13,
+ 1, 11,180,193,104, 74,200, 31,252,240, 85, 66,171,214,194,226, 34,183, 94,109,186, 97,199,165,189,125,212,148,246,176,217, 13,
+142, 72,212, 94, 34,145,224,225,195,135,197,237,218,181, 43,101, 24,198,114,217,178,101,182, 34,145,168,253,159, 56,247, 41, 47,
+ 95,190,236,218,169, 83,167, 41, 36, 73,246,162,105,250,114, 94, 94,222, 38, 0, 41,102, 30,255, 25,128, 69, 0,170, 70,150,122,
+189, 30, 36, 73,130, 97, 24, 12, 31, 62, 28,115,231,206,109,253,244,233, 83, 68, 70, 70, 90,247,234,213,235, 46,128, 82, 0,159,
+ 0,168,209,106,166, 80, 40, 52,247,239,223, 23, 70, 70, 70,130,166,105, 88, 91, 91,195,194,194, 2,124, 62, 31,131, 6, 13,146,
+204,153, 51,167,231,133, 11, 23,242, 21,205,154,176, 4, 57, 89, 42,190, 68, 34,133,163,115,151,201, 35, 63,142,103, 24,230, 68,
+ 3, 26, 7,158,144,109,210, 18,148,142, 92,243,237, 6, 82,196,229, 18, 2, 46, 27,124, 90,141,249,223,173, 32,184, 12,197, 70,
+ 3,231,231,185, 92, 46, 87,202,135,158,197, 99, 25, 69, 4,152,191,226,225, 96,177, 88, 60, 1,183,118,127, 12, 14, 73,146, 36,
+ 73,114, 1,152,189,104, 31,159,207,231, 74,249, 76,173,156, 66, 22,193, 34, 8,130,135, 90, 34,209,252, 29,193, 84, 90,145,120,
+211,146,116,213, 69,113,151, 46, 93,112, 38,242, 33,142,158,190,140,194,180, 39, 88, 48,251, 75, 4, 6, 6, 34, 34, 34,162,206,
+ 50, 85,250,104,213,102, 93,150,203,229,143,178,179,179,223,171,237,216,186,166, 12,107,177, 82,253,145,255, 91, 75, 4, 44,137,
+ 71, 61, 62, 90, 3,187,116,233,242,197,254,253,251,245, 31,124,240, 1,111,248,240,225,240,241,241,233, 60,110,220, 56, 0, 64,
+175, 94,189,240,195, 15, 63,116, 30, 55,110, 28, 14, 29, 58,132,227,199,143,235,186,119,239, 62,251,218,181,107, 89,120, 29,209,
+249, 7,208, 52,221,127,219,182,109,111, 91, 10, 97, 50,153, 96, 52, 26,157, 76, 38,147, 83, 69, 91,132, 31,127,220, 80,120,241,
+ 66, 4,102,207, 91, 2,123, 59, 71,127, 51,239, 33, 98,236,215, 95, 23,254,178,118, 45,214, 30, 58,132,175,221,220, 68,123,159,
+ 63,199, 69,173, 22,135, 35, 35, 11, 43,126,167, 94,223, 76,149, 74,165, 57,123,246,172,197,225,195,135, 97,101,101,133, 22, 45,
+ 90,192,218,218, 26, 28, 14, 7, 36, 75, 8, 22, 87, 6,175, 54,237, 1,220, 7, 0,184,201,161,242,118,199, 77,130, 64, 41, 67,
+ 54,220,167,136,223, 4,205,108, 93, 4, 81, 95,236,246,177,178,176,231,226,252,166,116, 92,216,152,113, 66, 91,136,117, 48,225,
+ 5,106,247,249,106,231,238,238,142,252,252,124,156, 61,123, 86, 5,212, 42,200, 64,211,244,119, 91,182,108,249,102,222,188,121,
+124,111,111,111, 0,240, 7,240,160,166,125,197, 98, 49,156,157,157,171,132,229,240, 49,147, 61, 38,205,156, 44, 28,220, 59, 4,
+108,182, 45, 74, 85, 70, 20,149, 27, 33,179,149, 96,246,204, 48,193,229,118,206,129,219, 54,252,122, 74,163, 65, 32,240,199,246,
+128, 32,240,224,222,147,155,190, 2,111,128, 32,129, 12,242, 42, 8, 16, 80, 18, 70, 16, 44, 22, 67, 81, 20,210,211,211,193, 48,
+ 12, 70, 13, 30,159,241,233,202,227,246,157, 71, 41,224,234, 37, 7,193,160,219, 63, 69, 8,216,216,216,248, 23, 21, 21, 33, 37,
+ 37, 5, 99,198,140,201, 42, 44, 44,188,164, 82,169,198,103,103,103, 3, 64,241, 59, 80, 86,137,121,127,127,127,180,111,223, 30,
+195,134, 13, 19,168,213,234, 48, 15, 15, 15,231,130,130,130,142,127,103,125,222,214, 34,255,175,132, 86,141, 15,154,209,232,165,
+219,186, 21,170,203,151,193,187,120, 17,135,229,114,165, 86,171,253, 10, 64, 70,197,131,255,229,238, 95,126,185, 53,224,206, 29,
+ 11,125,124, 60, 60,158, 62, 5,199,202,202,191,161, 5,216,181,107, 23, 20, 10, 5,202,202,202, 0, 0, 27, 55,110,132, 66,161,
+128,201,204, 5,103,217, 92,116,118,180,119, 67, 46, 18, 64,179, 73, 73,170,151,186,131, 68, 43,205,118, 78,119, 80,149,145,206,
+136, 79, 11, 18,107,138,244, 29, 8,150, 30,218, 66, 53,156, 59,181, 0, 27,236,206, 13, 41, 99,229,188, 63,155,205, 46,126,249,
+242,101,255,150, 45, 91,158, 6, 96,251, 46,254, 0,111, 33, 49, 47, 47,111,218,187, 28,200, 98,177, 22, 37, 39, 39,219,239,220,
+185,115,202,178,101,203,152,234, 66,171,242,127, 54,155, 13,134, 97, 96,105,105, 9, 14,135,227,112,251,246,109,135,160,160,160,
+205, 52, 77,251,215, 82, 79,198,199,199, 7,201,201,201, 96,179,217,176,180,180, 4,109, 50, 96,201,204,201,160, 88,124,246,172,
+ 89,179,252,135, 12, 25, 18,187,115,231, 78,163, 69,112,167,142, 69, 69, 69,207,190, 24, 53, 58,246,228,201,147,250,138, 20, 15,
+245, 15,241, 25, 38, 38, 33, 33,129,229, 34,119, 96, 49, 38, 53, 45,230, 2,130, 39, 63, 50, 60,137, 35, 4,108, 22,195, 37, 72,
+240, 5, 66,203,148,204,204, 34,154,166,227,204,225,164,105, 58, 58, 57, 57, 89,232, 96,111,195, 86,107,244, 74, 33,135,225,165,
+ 70, 63, 76,106, 22,208,206, 3, 0,180,209,247,175,241,189, 90, 9, 83,243, 10,196,110,110,110,102,113,106, 52,154,152,172,172,
+ 44,150,131,131, 3, 59, 45, 35,243,148,149, 68,108,103, 97,101,213, 1, 0, 12,229,101,247, 73,157,174,128,197, 97, 59, 20, 20,
+ 21, 21,107, 52,154,100,115,235,254,234,213, 43,182,147,147, 61,235,252,197, 43,167, 29, 68,124,123, 41,143,109,193, 39, 8, 66,
+196, 34, 20, 92, 19, 93, 40, 16,137,236, 83, 50, 51,139, 25,134,169,213, 66,184,186,116,244,224,215,215,107,201,161,106,220,120,
+242,228, 9,206,221,140,131,152,209,131,208,150,225,226,238,159, 49,106,214,188, 63,237,247, 87,159,216,122, 39,107,214,182, 86,
+143,222,226, 71, 78, 61,142,240,163, 70,141, 90,178,111,223,190, 42, 7,148,184,184, 56,244,232,209,163,114,154, 3,161,161,161,
+ 8, 10, 10, 66, 92, 92, 28, 60, 61, 61, 17, 25, 25,201,103,177, 88,252,209,163, 71,175,252,245,215, 95,207,214,107,247,223,190,
+ 29,227,199,143,175,201,177,250, 21, 0, 45, 33,243, 86,206, 93,189,199,182,184,168, 16,249, 5,185, 49,230,158, 7,130, 32, 48,
+246,235,175, 11,183,233,245,216,127,239, 30,194,197, 98,209, 47,137,137,232, 27, 20, 4,223, 30, 61, 10,205,105,235, 42,173, 58,
+ 90,173, 22, 28, 14, 7, 22, 22, 22,176,177,177, 1,151,203, 5,139, 35, 7,155,231, 7,146,203, 69, 64, 23, 63,172,253, 74,172,
+ 30,243, 33, 54, 16, 4, 74,249, 60, 68,115, 69,181,250,234, 16,226, 38, 24,196, 48, 80,168, 51,112,181, 82,144, 88, 54,133, 37,
+ 71,202,185, 56, 97,179,183,149,133, 61, 23,231, 54,164,225,226,230,204, 99,218, 92, 44,168, 56, 23,116, 29, 3, 9, 95, 43, 43,
+ 43,100,100,100, 32, 61, 61,253, 57,234,118,240, 87,199,197,197, 37,241,249,252,214,118,118,118, 0,224, 94,219,192,156,166,233,
+ 42, 63,172,189,251,143,216,250,119,245, 16,188,223,185, 53,246,156, 94,129,207,195, 54,128,195, 34, 64, 81, 6,172,251,161, 31,
+ 40,157, 18, 97, 3, 62, 37,186,245,242,244,187,124, 90, 63,193,168, 41,249,249, 15, 3, 1, 54,150,255,107,196,109, 43,190,132,
+244, 5, 77, 88,217,218,218,139,185, 92, 46,108, 44,156,244,243, 38,205,158,147,240,216, 0, 0, 32, 0, 73, 68, 65, 84,200, 97,
+ 24,166,234,185,225,176,184, 70,178,220, 90, 83,148,171, 20, 90,113, 52, 0, 67, 54,123,183,108, 54,127, 61, 50, 51, 51,167,117,
+237,218,117,101,121,121,121,137, 74,165, 26, 5, 0,238,238,238, 77, 73,146,228, 3,168,107,118,164, 41,106, 78, 11,193,125,250,
+244, 41,164, 82, 41,178,178,178,170, 27, 95, 64,211,244, 63, 38, 8,224, 31,138, 0, 0,209, 0,156, 0,244, 69,181,244, 14,100,
+133,169,174, 91, 68, 68, 4, 19, 17, 17,209,173,170,243, 98, 24,218, 84, 92, 12, 70,247,250,220,114, 56, 28, 6, 64,245,136, 38,
+145,149,149, 21,193,113,113, 1,193,127,237,250,193,252,133,161,175, 70,163,121,169,101,104, 10, 44, 16, 6, 48,213, 6, 45, 42,
+ 1,129, 21,182, 61, 49,141,183, 16,185, 60,171,234, 61, 29, 96, 98, 64,129,102, 53,176, 56,140, 74,165,130,201,100,146, 53,111,
+222,252,140,201,100,146, 85,116,110,204,127,234,138, 82, 20,149,196, 98,177, 48,101,202, 20, 84, 90,127,244,122, 61,114,115,115,
+161,211,233,160,215,235,145,156,156,140,178,178, 50,232,245,122, 60,123,246, 12,238,238,238, 96,177, 88, 78,117, 52,230, 12,195,
+ 48,112,117,117, 69,179,102,205,192, 34, 24,236, 88,179, 24,243,167, 79,198, 8,119, 26,187, 54,173, 67,247,238,221, 91,185,185,
+185, 5,179,217,108,202,209,209,145,123,252,248,241, 83, 20, 69, 13,130,249, 45,207,217,185,115,231, 54,107,211,166,141,189,149,
+133,212,200,231,177,192, 51,170, 24,190,174,136, 97,171, 11,225,234,218,212, 4,161,200, 51, 60, 60,156,170,205, 10, 81, 19,231,
+ 87, 95,125,229,228,237,237,109, 41,179,146,170,120, 28, 86, 62, 23, 76, 97,217,147, 7,119, 1,128,103,103,175,133, 64,212,122,
+204,152, 49,166,134,112, 46, 92,184,208,221,206,206,206,138, 4, 83, 78, 25, 12,191,207,183,235,244, 69, 4,135,163, 1,151,215,
+110,234,212,169, 68, 67, 56,191,249,230, 27,183,214,173, 91, 91, 89, 89,136,149,108, 14, 43,135, 75,211, 57, 2,208,185, 28,189,
+161, 68, 96,103,171,134, 72, 18, 16, 30, 30, 94, 43,103,165, 53,107,206,156, 57, 25,111, 9,111, 20, 23, 23, 67,155, 27, 11,110,
+ 86, 60,252, 36, 28, 4,218,201,192,231,243,171, 66,223,107,187, 93,107,243,209,170, 73,108,153,123,108,187,165,117, 76, 1,110,
+107,245,232,237,188, 89,217,217,217,112,114,114,170,243,121,250,245,215, 95,231,133,132,132,228,135,134,134,234,207,156, 57, 3,
+130, 32, 16, 25, 25,137,172,172, 44,132,134,134,130, 97,152,202,168, 54,196,196,196,160, 87,175, 94,250,174, 93,187,102, 85,228,
+215,170, 23,227,199,143,135,209,104,132, 82,169, 68,113,113, 49, 34, 34, 34,224,231,231,199,136, 68,162, 33, 44,215,222, 43,194,
+ 38,204,235,232,211,214, 31,155, 55,172,213,243,216,156,213, 13,121, 94, 9,130,192,152,175,190, 42, 44, 11, 8, 40,222,171, 82,
+169,199, 90, 88,136,154,103,100, 88, 63,188,112,193,214, 96, 48,152,197, 81,105,213,113,113,113,169, 18, 89, 92, 46, 23,108,158,
+ 29, 88, 98, 95,240,108, 66, 33,114, 28,130,171,209,124,157,165, 24, 39,164, 18,156, 23, 91,213,158,218, 65,228,138, 21, 29,135,
+ 59, 29,239, 52,194,233,138,168, 9,118, 86,244, 7, 36,195, 38,142,143, 91,215,178,185, 93, 51, 33,238, 28,201,197,197,205,153,
+191,105,115,177, 24, 64, 98,125,207,185,193, 96,208, 82, 20, 5,146, 36,193,102,179,171,251, 4,222,250,237,183,223,240,240,225,
+ 67,160, 90,218,158,242,242,114,138,197, 98, 65, 32, 16, 0,128,164,142,246, 14, 28, 14, 7, 28, 14, 7,215,238, 94,183, 25,241,
+ 81, 63,226,246,227, 75,232,228, 55, 18, 69, 74, 3,242,202, 12, 40, 85, 3,109, 2, 23,192,167,215, 9, 60, 73, 46,135,127, 91,
+ 31, 22,139, 39, 30, 83, 19,159, 54, 5, 25,170,116, 12, 45,122, 78,183,208,103, 10,207,221, 57, 25,247,252,250,209, 39,207, 14,
+110, 57,157,216, 49,176,171,170,194,152, 0,165, 82,201, 16, 4,193,204,152, 56, 47,105,239,248, 18,106,195,168, 39, 52, 91, 39,
+120,245,111,108,234,155,218,217,217,221,182,177,177,137,172, 16, 71, 77,165, 82,233, 45, 39, 39,167,120,188, 14,244, 56,153,147,
+147,227,173, 82,169, 58,225,117,112, 86, 90, 81, 81, 81,143, 10,203, 83, 90, 29,150,176,157, 10,133,226, 75,138,162, 6, 84,108,
+ 31, 82, 20,229,159,144,144,208,218,223,223,255,185,135,135, 71,140,135,135,199, 57, 15, 15,143, 83, 30, 30, 30,167, 66, 66, 66,
+126,168, 76,247,240, 55, 79, 27,254, 65,139,252,151, 9, 45, 84,136,172,237, 21,175,168, 18, 90, 0,174,189,237,128,102,226,243,
+159,153,190,248, 2, 86,167, 78,129,147,144,128,113, 99,198, 88,136, 68,162, 13,120,157,163,169,147, 68, 34,217,188,120,241, 98,
+169,237,170, 85,144, 95,191,142,212,136, 8, 24, 57,156, 7,239, 82, 58,141, 70, 3, 54,155, 93,101,137, 17,139,197,160, 40, 10,
+ 53,153,124,255,240, 0,154,112, 39, 43, 47, 30, 60, 52, 3, 13, 70,121, 94,209,245,222,200,164, 5,246, 17, 10,119,207, 68, 21,
+215,115,169, 93, 7,251, 13, 77, 59,223, 83, 17,108, 37,207, 74,128,244,244, 12, 80,160, 27, 52,223,172,213,106,203, 84, 42, 21,
+252,253,253,109, 30, 62,124,216,220,207,207,207,186,226,243,251,127,242,194, 4,203,229,242, 35,206,206,206, 41,114,185,252, 8,
+128,224, 6, 28,187,243,198,141, 27, 96,177, 88, 88,188,120, 49,202,203,203, 97, 48, 24, 80, 84, 84,132,244,244,116,232,245,122,
+100,102,102,226,197,139, 23,208,235,245, 72, 77, 77,133, 78, 87,255,128,132,166,105, 88, 88, 88, 64,171, 81,226,167, 21,243,177,
+112,206, 76,148,189,122,132,204,236, 60, 88, 89,138, 49,109,218, 52,150, 76, 38,163,105,154,110, 70, 81, 84, 47,154,166,183,154,
+115,157,170,221,111, 55, 93, 93, 93,125,214,172, 89,211,122,254,138,173, 92, 11,182,146,225, 75, 5, 52, 79,202,103,120,173, 58,
+ 96,252,130, 13,220, 31,215,127,255,242,206,157, 59, 89, 48, 47,121, 39, 9,224,102, 64, 64, 64,203,172,172, 44, 63,111,111,111,
+ 47,219,166,110,124,190,147,115, 41,215,169,137,130,209,105,239, 17,206, 77,186,108,221,186, 53,246,214,173, 91,217, 13,225, 20,
+139,197,173,246,236,217,227,227,224,224,224,195, 17, 10, 5,234,178,178,195, 38,181,234, 8,203, 74, 38, 32, 45,172, 62, 60,113,
+226,196,163, 99,199,142,229, 54,132,211,211,211,211,123,197,138, 21,109,124,125,125,219, 56,186, 55,231, 11,157, 93,139, 4, 46,
+ 77,139,132,190,126,124,184, 52,251, 96,243,230,205, 49,119,238,220, 49,139,147,197, 98,153, 72,146, 4,135,195,129, 72, 36,194,
+249,243,231,241,197,132,145,112,117,182,129,151,183, 55,122,126,254, 37,142, 29, 59, 86,229,195,195, 98,177,106,237,209,127, 89,
+ 53,237,116,128, 19,241, 8,219, 90, 61,194,182, 86,143, 2,156,136, 71,181,138,173,138,239,107,218,199,172,214,168,150,233, 70,
+ 51,196,214,217,107,215,174,125, 55,118,236, 88, 94,159, 62,125,112,239,222, 61,140, 31, 63,254,230,241,227,199, 1, 0,247,238,
+221,195,140, 25, 51,110, 94,185,114, 5,147, 39, 79, 70,143, 30, 61,120, 55,110,220,216, 12, 51,114,255,152, 76, 38,236,218,181,
+ 11, 38,147, 9, 18,137, 4,214,214,214,232,215,175, 31, 98, 99, 99, 39,239,222,189, 59,158,197,225,124,220,119,192, 71, 56,115,
+234, 56, 94, 60,139,157,252,203,202,209, 13, 78, 10, 76,146, 36,250,140, 25, 83, 88,216,166, 77,241, 47, 10,133,250, 19,153, 76,
+228,157,155,107,125,245,200, 17, 91, 51,132, 26, 65, 81, 84,149,184,170, 20, 29,149, 27,155,103, 7,182,216, 7,108,105, 32,158,
+ 36,114,141,220, 32, 68,243, 2, 17, 87, 87,254, 44, 14,143, 28, 63,100,190, 59,134,204,119,199,192, 89,110,227, 68, 77,176, 67,
+220, 4,159,245,153,222, 44,196, 35,208, 18,138,124, 3, 34,214,165,166,105,139,176, 10,192, 11,115,158,115,154,166,159,103,101,
+101,129,199,227,161, 73,147, 38, 45, 1, 84,250, 5,238,156, 56,113,226,212,165, 75,151,206, 4,176,180,226, 51, 73, 72, 72, 72,
+ 27,165, 82,137,132,132, 4, 0,120, 88,135, 53,184, 42,202,176, 88,145,202,119,147,251,194,175,213, 36,200,100,109,145, 85,172,
+ 71,118,177, 30, 59,126, 26,132, 71, 55,150,227,225,197,112,164,229,230, 66,232, 56, 24,148, 73,231, 99,198,160, 94,254,248,241,
+ 99,226,198,141, 27, 4, 77,211, 48, 26,141, 76,185, 66,193, 68,223,188, 9, 77, 84, 20, 97, 97, 97, 65,116,110,223, 85,249,203,
+242, 51,247, 79,108,186,249,208,160,110,240, 64,253,207, 96, 97, 82, 82, 82,240,145, 35, 71, 66, 0, 44,244,245,245,189,147,158,
+158,222,241,250,245,235, 94, 46, 46, 46, 27,222,149,180, 50, 45, 68,106,106,234, 27, 91, 69, 90, 8,125,133,104,232, 83, 33,230,
+ 6, 2,152,129, 63, 17,101,223, 0, 92,251, 47,118,134, 63,131,183,162, 13,223, 22, 90,213, 19,133,193, 67, 38,147, 26,141,134,
+204, 75,151, 46, 25, 72,146,132, 72, 36,194,216,241,227,201,159,182,108,233, 50, 50, 56, 56,242,211,247,223, 63, 23,121,229, 74,
+ 64, 80, 80, 16, 24,134, 1, 73,146, 56,116,232,144, 70,171,213, 20,185,186,186, 90,153,211,104, 84,127,128, 20, 10, 69,149,208,
+ 42, 43, 43,131,131,131,131,217, 83,135, 42, 5, 46, 95, 57,255,168,132,161, 62, 79,239,147,184,222,176, 58,119, 80, 80, 41, 77,
+177,203, 40, 35,202, 52, 12,202,181, 96,223, 35,173,131,198,122, 14, 54, 36,247, 10,122, 17, 21,127,187, 72, 75,105, 27, 20, 45,
+145,159,159, 63, 63, 44, 44,172,200,201,201,137,176,176,176,128,179,179, 51, 57,112,224,192,194,140,140,140,165,239,122, 69,108,
+108,108, 70,132,132,132,156,206,202,202, 26, 26, 21, 21,213,236,250,245,235, 67, 67, 66, 66, 78,219,216,216,140, 48,147,226,240,
+188,121,243, 84, 60, 30, 15, 29, 58,116, 64,121,121, 57, 42,162,124,234,220,204,153, 34,229,114,185,216,182,102, 17, 22,206,153,
+137,226,248,123,120,114,243, 18,174,229, 18, 88,176,226,123,112,185,220,119,202,245,213,194, 78,228,235, 43,151,198,205, 24, 63,
+ 60,123,238,156, 57,210,152,152, 24,206,212,233, 51,152,212,156, 98,240,250,172,101,161,219,124,242,177,202, 14,125, 63,236,137,
+197, 11,191,246,173, 72,218, 89, 39, 90,217,137,124,125,228,210,231, 95,127, 58, 50,105,250,244,233,194,213,171, 87,107,131,131,
+131, 53,121,121,121, 66,177,204,218,155,109,105,229,147,154,147, 43, 9, 14, 14, 78,254,252,243,207, 75, 27,202,185, 96,193, 2,
+209,133, 11, 23,216, 97, 97, 97,166,146,146, 18, 9, 71, 40,244, 39,248,130,246, 5, 37, 37,150, 67,195,194, 18,135, 14, 29,170,
+174, 72, 88,106, 54,231,183,223,126, 43,122,241,226, 5, 59, 56, 56,216,152,155,155, 43, 21,219,216,250,177,172,172, 3, 83,114,
+242, 44,218, 7, 5,189,154, 58,117,170,170,174,114, 86, 23, 41, 82,169, 52,171, 83,167, 78, 88,183,110, 29,126,252,241, 71,124,
+240,193, 7,136,125, 22,139,190, 83,103,162,245,103, 51,112,234,246, 93,100,101,101, 97,217,178,101,240,243,243, 3,151,203,125,
+ 81,227,243, 56, 57,158,136,201, 5, 17,147, 11,130,152, 28, 79, 84,190,175,213,178,181,180, 12,213,247,175,105,191,135,223,214,
+108,233, 10,112, 34, 30,213,229,135, 85,159,216, 26, 58,116,232, 23,149, 41, 28, 62,249,228,147,155, 27, 54,108,232,252,201, 39,
+175, 7,218, 29, 58,116,192,242,229,203, 59, 47, 88,176,224,230,138, 21, 43,208,179,103, 79,120,120,120,212, 27,248, 66, 81, 20,
+ 76, 38, 19, 70,142, 28, 9,147,201,132,130,130, 2,188,124,249, 18,219,183,111, 7,195, 48, 2, 0,112,146,187,180,227,241,120,
+120, 28,253, 64,189,240,147,160, 95, 27, 96,201, 34,170, 15, 98,148, 74, 37,134,126,246, 89, 97,102,139, 22,197, 91, 11, 11,213,
+ 19,100, 50,145, 91, 90,154,181, 84,175,119, 70, 29,126,137, 4, 65,128,166,233, 42, 97, 85, 41,184,222,222, 42, 58, 74,179, 96,
+ 80,211,103,175,239,203, 6, 0,116, 29, 45,199,192, 89,110,227,156, 60, 69, 27,187,140,122,109,244, 62,182, 60,137, 41,207,166,
+ 86,195,136,231, 13,176, 88,223,187,119,239, 30,172,172,172, 16, 22, 22,198, 39, 73,114, 85,229,120, 21,175,115,103,173,175,228,
+226,243,249,107,195,195,195,201,210,210, 82, 60,121,242, 4, 0,174,212,214, 46, 49, 12, 83, 85,119,101, 49, 1,138,230,225, 86,
+244,121, 92,188,126, 20, 41, 89, 5, 72,203,215, 2,108, 75,104, 85,153, 48,104,178,160, 47,141,134, 66, 39, 50,171,192, 92, 46,
+183,192,215,215,151, 9, 12, 12,100, 24,134,193,171, 87,175, 76,169,105,105,166, 7, 63,252,192, 60,157, 52,137,144,190,124,201,
+ 21, 10,133,132,187,187, 59, 4, 2, 1, 45, 16, 8,138,254,141,157,247,223,146,110,225,111, 72, 11,241, 87, 90,181, 24,252,119,
+ 34, 7,111, 70, 27, 86, 37, 48,173, 41, 97, 41, 24, 11,225,240,163,155,127,178, 12, 27, 57, 90,229,231,231, 39,115,118,118, 6,
+ 65, 16, 24, 52,120, 48, 17, 18, 21, 37,229,200,229,176,121,239,189,170,233,136,203,151, 46,225,252,249,243,170, 51,191,157,112,
+ 30, 63, 97, 66,127, 0,123,234, 40, 12,155,207,231, 87,253,110, 78, 78, 14,248,124,126,149, 79,132, 66,161,128,157,157, 29,114,
+114,114, 96,230,204,220,222,185,115,238,206,201, 15,154,239, 30, 36,229, 16,231, 84,185,160, 24, 6, 28,130, 2, 52, 12,140, 20,
+160, 51, 50,104,231,198,178,190,168, 49,201, 34,238, 29, 79, 6,176,183, 33,103, 79,167,211, 93,141,137,137,153, 68,211,244, 81,
+ 0,100, 84, 84, 20,253,252,249,243, 47, 96,190,227,250, 31,205,246, 34,209,172,200,200, 72,235, 89,179,102,149, 68, 68, 68,148,
+245,235,215,207,114,251,246,237,214, 61,122,244,152, 85, 84, 84,116,208, 28, 67, 96,122,122,250,158,140,140,140, 47, 2, 3, 3,
+ 81, 92, 92, 12,131,193,128, 71,143, 30,193,211,211, 19, 15, 31, 62, 68,203,150, 45,241,224,193, 3,120,121,121,129,162, 40,104,
+181, 90,208, 52, 77,213,215,152, 23, 23, 22, 0, 69,233,200,190,119, 14, 47,159, 62, 66,100, 54,129, 77, 7, 79,163, 73, 51,247,
+119,202, 83,211,210, 94,212,198,201,206,230,226,234, 37,223,218,167, 94, 61,132,227,187, 54,209,215,206,157,107,205,147, 98, 82,
+183,145, 95,126,164, 55,162, 41, 0, 94,199,160, 64,244,145,189,160, 68,205,144, 27,249,188,238, 4,139, 45,237, 69,109, 28,108,
+109, 46,252,107,213, 82,233,171,243,191,224,240,182,117,204,177,125, 7,252,180, 64, 80,155, 54,109,250,144, 36,105, 5, 64, 91,
+225,231,101,214,210, 54, 53,113, 94, 62,125, 58, 64, 11, 4,157, 60,121,178,143, 72, 36,114, 4, 96, 84,171,213, 73,127,134,243,
+ 74, 68, 68, 64,101, 57, 9,130,176, 7, 96, 96, 24,230, 21, 26,184, 4,207,176, 97,195,150,207,152, 49, 99, 14, 69, 81,118,213,
+ 70,231,172,181,107,215,178,105,154,102, 49, 12, 99, 32, 73,210,112,225,194, 5,202,100, 50,101,107,181,218,207,254, 76, 43,242,
+209, 71, 31,225,238,221,187, 75,240, 58, 8,195, 92,107,245, 27,126, 90, 21, 75,246,188, 51,127, 84, 84,212,178,143, 63,254,120,
+238,193,131, 7, 95,110,216,176, 97,192,228,201,147,113,232,208, 33,180,104,209, 2,143, 31, 63,198,252,249,243, 1,160,243,130,
+ 5, 11, 78,237,220,185,211, 35, 53, 53,117,173, 25, 22, 13,152, 76, 38, 28, 56,112, 0,131, 6, 13,130,157,157, 29,228,114, 57,
+ 8,130,184, 58, 97,194,132, 45, 0,192, 34, 88, 92, 0,208,105,117, 58,111,239, 64,179, 45,184, 92, 46,183,170,173,203,205,205,
+173,138, 20,236,253,241,199,133, 59, 86,175,198,175, 26, 13, 38,200,100,162, 76, 23, 23,167, 83,175, 94,125,250,236,117,227,204,
+212,101,213,169, 79,100,153,235,210,160,201,193,188,223, 86,166, 56, 2,248,160,235,104, 57,186,142,150, 35,112,160, 61, 65,178,
+ 8, 60,189, 88,132,216,203,197,199,140, 10, 92, 69,195,150,203,121,190,106,213,170, 83,221,186,117, 27,208,170, 85, 43, 76,156,
+ 56,241,243, 93,187,118,113,141, 70,227,116,252,158,230,193,146, 36,201,165,219,182,109,251,212,218,218, 26, 55,110,220,192,245,
+235,215,175, 2, 72,175,173, 93, 2, 80,149, 51,171,137,107, 75,237,139, 84,165, 40, 63,235, 22,110,222,248, 13, 45,252,190,132,
+208,177, 63,172,189, 87,192, 16,255, 35,244, 69, 23, 97,237,218, 15,153,169,175,192, 98,243, 99,235,115, 66, 97, 24,230, 89,102,
+102,166,135,135,135, 7,145,146,146, 98, 2,192, 80, 20,197, 24,186,116, 49,182, 94,189,154, 19,251,249,231, 68,199, 23, 47, 88,
+ 12, 65,208,143, 30, 61, 2,128,184,255, 68, 47, 94,153,110, 33, 54, 54,182,182,116, 11, 13,130,175,175,111,231,235,215,175,243,
+181, 90, 45,174, 93,187,134,246,237,171, 98,187,254,163,217,239,171,107,145,255, 50,124, 90,195,103,219,223,176,104,189,113, 99,
+211, 4,199,171,101, 75,138, 75, 98,247,160,254,253,213, 49, 49, 49, 85,163, 62,237,253,251, 80,157, 63, 15,138,162,192, 48, 12,
+174, 71, 69, 33,124,244,104, 37,135, 69,236,112,115,107,198, 16,204, 27,185, 91,122,213, 48,122, 8, 11, 11, 11,171,106,124, 50,
+ 50, 50, 32, 22,139,193,227,241, 64,211, 52, 76, 38, 19, 88, 44, 22, 44, 45, 45, 97, 50,153,106, 50,193,188,205,105,164,138, 85,
+ 67,119,246, 29,149, 35, 87, 26,152, 73, 86,110,104,202, 21, 86, 61,156,142, 22, 4, 6,248,113, 96,203,206,103,174,172,125, 63,
+155,214, 21, 13,197, 31, 35,186,234, 11,249,111,217,182,109,219, 45,225,225,225, 36, 0,244,234,213,139,108,219,182,237, 70,212,
+189, 84, 78,157,156, 2,129,128, 15, 0,167, 79,159, 46,126,249,242,229, 7,167, 79,159, 46,174,254,185,153,156,219,215,172, 89,
+ 3,145, 72, 4,147,201, 4,189, 94, 95,229,159, 85,253,213, 96, 48,192,214,214, 22,103,206,156, 1, 69, 81,103,234, 43,167,107,
+211,102, 32,236,154, 99,207,233, 72, 92, 47,228,190,139,200,170,226,108,238, 40,246,114,180,181,185,244,175,149,203,236, 74, 18,
+ 31, 33, 51, 51,147,185,112,254,204, 29, 45,144, 85, 86,142,133,165, 42,120,105,244, 16,180,247, 64,250,165,109,179,153, 5, 93,
+ 97, 68,205, 81,131, 85,156,173, 29,197, 94,206,118, 54, 23,190,255,215, 74,105,105,226, 35,228,228,230,226,236,153,211, 49, 90,
+160,114,186,113, 28, 77,211, 62, 52, 77,251, 0, 24, 87,135,120,105, 16,167, 90,173,246, 85,171,213,190,127, 37, 39,195, 48,190,
+ 12,195,152,205, 89,221, 39,106,253,250,245,241, 57, 57, 57,225,249,249,249,161,149, 91, 73, 73, 73, 47,165, 82,217, 93,173, 86,
+119,209,172,111,102,169, 86,171,237,149, 74,165,147, 86,171,109, 7,224, 81, 3,238,249, 42, 84,207, 58,157,147,147,179, 56,231,
+255,216,187,242,240, 38,170,246,123,102, 38,251,210,180, 77,219,164, 41, 45,101, 45, 91,203, 82,144,125, 21, 20,164, 40,202,250,
+ 67, 16, 16, 44, 32,138,128,130,168,168,236, 8,226,135, 11,178, 20, 80, 22, 17, 89,101,119, 1,100,151, 29, 4, 74,161, 44, 45,
+221,151, 52, 75,155, 52,205, 54, 51,191, 63,154,196,180,116, 73, 74, 81,248,190,156,231,153, 39,153,100,114,114,231,206,204,189,
+231,190,247,189,239,155,157, 77, 84, 87, 78,106, 82, 18,177,229,139,247,126, 94,179,102,141,234, 17,249,203,148, 83,173, 86,239,
+216,186,117,107,155, 6, 13, 26, 52, 28, 59,118, 44, 86,175, 94,141,175,191,254,218, 12, 0,235,215,175, 55,187, 89,178, 34, 82,
+ 83, 83,159,169,100,218,176,143,155,181,100,211,243,207, 63,207,158, 56,113, 2, 47,191,252,178, 43,144,232,218,181,107, 97,183,
+219, 11,123,247,238,205, 0,128,169,164,184,144,101, 88, 88,172,149,206,191, 63, 84,159,124, 62,255, 5,247,120,129,206, 96,204,
+124, 62, 31, 44,203,162,105,215,174,106, 93,235,214,154,239,244,250,226, 57, 45, 91,202,226,155, 53, 27,219, 28, 24, 85, 17, 39,
+ 65, 16,101,172, 58,229, 55, 47, 44, 89,238,229,204, 51,101,225,141,159, 23,165,252,226,180,108, 9,165, 28,148, 20,217,177,251,
+179,148,252,146,124,172,173, 76,252, 84,117,238, 26,141,230,237,207, 62,251,204, 28, 24, 24,136,193,131, 7, 99,225,194,133,227,
+187,118,237,170, 87, 40, 20,103, 27, 55,110,124,109,248,240,225,217,151, 46, 93,122,187, 87,175, 94, 72, 78, 78,198, 23, 95,124,
+161,211,106,181, 35,171,226, 36, 8,194,101,201, 27, 24,215, 71,179,234,155,255, 48,189,123, 76,134, 88, 36,131,141, 27, 1,141,
+193, 6,173,145,133, 69,208, 1,124,158, 0,125, 59, 69,227,236,175, 27,138,105,139,113, 99,117,247,188,193, 96,216, 57,102,204,
+152, 66, 30,143, 7,139,197,194,114,185, 92, 8, 74,253,142, 25,110,191,126,214,206,137,137,118,154,101, 25,130, 32,240,238,187,
+239, 26,181, 90,237,214,154, 60, 71, 94,192,157,179,182,194, 45,244, 41,215,255,212, 70, 88,136,199,113,238, 79, 51, 18, 42,216,
+254,182,104, 57,151, 84, 58, 95, 9,130,161,105,154, 65,253, 6,245,253, 82, 83,210, 86, 12, 27, 54,116, 92,255,254,113,226,184,
+184, 56, 97,116, 82,233,104,116,223,190,125,216,181,107, 87,241,111,191,253, 86, 40,224, 82,235, 35,234, 70, 40,105,154, 1, 65,
+ 48, 85,170, 97, 63, 63,191,119, 62,252,240, 67,145, 94,175,199,215, 95,127,205,180,105,211,134,148, 72, 36,176, 90,173, 88,191,
+126,189, 45, 58, 58,154, 75,146, 36,244,122, 61, 72,146,188,229,225, 9,254,165, 79,203,236,187,178,215,160, 93,207,188,245,122,
+ 80,139, 94,157, 3,123, 70,212,129,173, 45,139,172,244, 20,220, 62,242,155,246,198,175, 95, 22,160, 36,119, 16,170, 79, 15, 84,
+ 81, 71,240,233,111,191,253,166,120,251,237,183,217,146,146, 18, 34, 45, 45,141, 93,180,104,145,226,141, 55,222,248, 52, 43, 43,
+235,255,106,120, 81, 8,157, 78, 7,130, 32, 24, 71, 67,226, 28,245,123, 51, 47,119,125,227,198,141,123, 94,121,229,149,129,189,
+123,247, 70, 82, 82,146,107,138,208, 93,104, 57, 87, 31, 46, 94,188, 88, 7,224,131,234, 72,185, 92, 46,190,222,184, 3, 58,173,
+ 26, 74,101, 24,132, 34, 17,106,186,194,146, 79,146,115,150,204,255, 68,161,190,121,150,184,254,231, 81,102,251, 95,185,121,118,
+154,173, 56,226,127, 81, 22,235, 80,255, 85,143,102, 72,106,206,146, 69,243,252,157,211,154, 91, 47,103, 23, 18, 52,251,246, 35,
+ 61, 34, 79, 11,231, 63,140,176,176, 48,100,103,103, 19, 97, 97, 97,172,195, 71,139,173, 66,104,149,189,193, 75,167,203,136,170,
+166, 13,107,202,127,255,254,253, 69,109,219,182,125, 47, 57, 57,121,123,139, 22, 45, 38, 2,168,107, 54,155,117,179,103,207,254,
+124,253,250,245,227, 60,177,100, 1,192, 79, 63,253,244,229,235,175,191,254,203,139, 47,190,248, 62,195, 48,173,220, 58,246,251,
+ 10,133,194, 53,133,155,159,155, 51,107,194,184, 17,179, 12, 6,173,199,113,238,164, 82,105,252,236,217,179,133, 70,163, 17,223,
+126,251, 45, 19, 29, 29, 77, 58, 7, 69,155, 55,111,182, 55,105,210,132, 51,116,242,100,245,242,156, 28, 44, 56,121,210, 56, 43,
+ 38,166,205,119,183,111,183, 3,195,108,170,204,170, 83,145, 37,203,233,118, 81, 67,100, 57,196,214, 90, 0,253, 58, 15, 11,197,
+158,165, 41,208,166, 90, 62,135, 29,119,225, 65, 90,160, 10,144,177,115,231,206,190,185,185,185,123, 62,249,228, 19,255,118,237,
+218, 33, 38, 38,134, 43,149, 74, 59, 56,195,197,232,245,122, 28, 62,124, 24,171, 87,175,182,220,184,113,227,149,170,166,171,104,
+154,206,107,210,164,137,179, 30, 88,130, 32, 10, 10,205,132,255,182,230, 29,164, 99, 39,108, 39, 78, 93, 56,131, 44, 43, 3,179,
+141, 65,253, 6,177,232,217,111, 57,246, 30,186, 70,103,165, 38, 38,218, 76,218,117, 30,148,247,238,157, 59,119,118,207,159, 63,
+127,216,251,239,191, 47, 82,171,213,180,217,108,102,118,236,216, 65,141, 29, 59,150,102, 57, 28,134,199,225,224,157,119,222, 49,
+233,116,186,159,129,127, 52,193,244, 99, 9,183,240, 24,194, 66,212,154, 53,203,253,245,191, 5, 21, 62,161, 12, 69,158, 94,189,
+102,213, 11, 63,253,184, 53,148,162,200,208,187,247,238, 93,120,105,208,144,204,223,127,255, 93,206,243,247,111, 15,128,177, 76,
+156,248,167,213,108,210,236,223,179, 39,178,126,253,122,173, 29, 73,165, 89,134, 34, 79, 87,245,135, 6,131,193,120,242,228,201,
+226, 15, 62,248,128, 72, 79, 79,223,162, 84, 42,135, 31, 58,116, 72, 58,104,208, 32, 83, 82, 82,210,206,208,208,208,129,189,122,
+245,242,123,239,189,247,204, 6,131,193,155,196,163,137,108,190,182,249,249, 79,150,189,122,126,233,170,231,192,161,186,192,204,
+ 5, 24,219,105, 88,139,126, 7,176, 5, 94,196, 59,114,135, 68, 34,105, 45, 22,139,113,229,202, 21,109,135, 14, 29, 44, 37, 37,
+ 37,188,133, 11, 23, 6, 73, 36,146,214, 53,173,120,150,101, 89,173, 86, 11,134, 97, 56, 0, 8,199, 43, 24,239,215,226,255,223,
+ 75, 47,189,180,103,219,182,109,207,199,197,197,161, 97,195,134,176,217,108,104,210,164, 9, 44, 22, 11,162,162,162, 96, 54,155,
+ 49,119,238, 92,232,245,250,233,168, 34,231, 25, 65, 16,176,219,237, 46,103,219, 58,225,145,165,113,122, 30, 33,140,133,132, 75,
+ 54,188,181,255, 59,228, 21,168,153,109, 87,115,115,139,173,116,223, 59,249,197, 55,202, 31, 87, 76,195,216,107,236,148, 76, 0,
+ 48, 51, 85,103,156,151,240,209,240,246,129,181,200,205, 83,227,167,203,217, 58,163,149,233,119,187, 2, 78,175,202,249,148,112,
+198,206, 77,194,144, 41,158, 31,251, 40,240, 84, 80, 85,134, 43, 57, 32, 46,138,191, 99,177,230,187, 10, 99,100, 61, 34,255,158,
+228,228,228, 61, 0,144,152,152,152, 62, 98,196,136, 89, 41, 41, 41,243, 1, 28, 76, 77, 77, 93,227, 13,209,119,223,125,151, 12,
+224,245,170,142,217,186,236,245,221, 0,118,123,195, 91, 84, 84, 84,114,233,210,165,146,247,222,123,143, 72, 79, 79, 63, 20, 26,
+ 26,250,252, 47,191,252, 34, 30, 52,104,144,249,250,245,235, 71,194,194,194,186,247,233,211, 71,122,240,220,185,204,226,187,119,
+247,239, 79, 73, 9,183, 49,204,254,170,158,207, 90, 22, 89,101,196,214,238, 5, 41, 75,246, 44, 73,233,195,152,177,211,162,197,
+159, 0, 50, 30,129,243,196,233,211,167, 91,140, 26, 53,106,219,128, 1, 3, 58,183,104,209, 2,117,235,214,197,237,219,183,145,
+159,159,143,191,254,250, 11,251,246,237,219, 87, 82, 82, 82,109, 66,109,141, 70,243,112,122, 34,161, 60,108,195,183,115,246, 93,
+ 56,213,190, 73,183,184, 49,162,152, 48, 6, 22, 43,139,244, 7,119, 49,247,227,117,197,217, 15,146, 19,173,118,235, 43,240,112,
+161,142,201,100, 74,248,234,171,175,184,251,247,239,143, 91,177, 98,133, 95,100,100, 36,197,227,241, 72, 0,236,197,139, 23,217,
+ 41, 83,166, 24,213,106,245,129,194,194,194,132,127,184,143, 62,113,239,222,189, 88,138,162,106, 53,220,194, 35,132,133,240,161,
+ 54,209,160, 65,120,139, 70,145, 97, 19, 27,214, 13,159,220, 32, 50, 98,116, 69, 78,238, 13, 3, 3,253, 26,212,171, 19,223,176,
+110,248,228, 70,145, 97, 19, 27, 52, 8,111,225,129,105,177,161, 76, 38, 59,164, 82,169,218, 0,128,191,191,255,192,128,128,128,
+ 27,254,254,254, 3, 29,163,192,129, 82,169,244,102,116,116,244, 27,255,160,185,178, 74,206, 38, 77,154,140, 48, 24, 12,111, 54,
+105,210,100,132,115,255,238,221,187,174,253,154,112, 70, 68, 68,244,190,120,241,226,255, 45, 91,182,108,112,227,198,141, 7, 46,
+ 90,180,104,240,207, 63,255,252,127,225,225,225,237,106,192, 41, 0,240, 3,151,203,205,229,243,249,121, 92, 46, 55,215,185,113,
+ 56,156, 92,138,162,114, 1,172,169,196, 90,214,199,109,148,115, 74,169, 84,166, 42,149,202,212,208,208,208,212,208,208,208, 84,
+149, 74,245,208, 22, 28, 28,124,202,211,250,108, 22, 42,237,218,161,174,223,233,150, 42,233,169,230, 74, 73,179,218,184, 70,205,
+ 66,165, 93,219,215,245, 63,221, 82,229,119,242,127,141,179, 77, 40, 88,118,117, 51,150, 93,221,140,109, 19, 10,182,186,253,218,
+ 52,251,171, 84, 42, 86,165, 82,205,121, 92, 83, 9,149,240,255,227,207,123, 45,114, 54,244,243,243,219, 90,183,110, 93,103, 91,
+247,162, 76, 38,251, 67, 42,149,190,232,104,235, 94,148, 72, 36,199,163,163,163,199, 84,199, 41,151,203, 47, 42, 20,138, 28,199,
+150,173, 84, 42,179,149, 74,101,182, 66,161,200, 82, 40, 20, 89, 33, 33, 33,153,206, 45, 32, 32,224,108, 13,207, 93, 1,160, 35,
+128,118, 0,100,181, 88,159, 13, 0, 76,112,180, 65,159, 1,120, 3, 64,171, 90,184, 70, 4, 87, 36,159, 36, 8,136, 56,205,149,
+134, 20,113,165, 33, 69, 2,255,240,211, 85,164,224,241,132,179,169, 92, 46, 95, 40,147,201,126,246,243,243, 59,233,231,231,183,
+ 39, 56, 56,120, 17,128,166,255,210,189, 36, 5,176, 30,165,241,153, 14,162,116, 42,124, 15, 74, 23, 21, 68, 62,129,247,252,255,
+ 50,226,255,173, 63,238,227,227,244,113,250, 56,125,156, 62, 78, 31,231, 83,200, 73,250,234,211, 39,180,188, 20, 90,229, 55, 0,
+ 85, 68,134,247,193, 7, 31,124,240,193,135,255, 97, 48,190, 42,240,193, 75, 84, 56,181, 76, 84,161, 74,189,137, 53, 85, 19,101,
+123,216,199,233,227,244,113,250, 56,125,156, 62, 78, 31,231,255, 28,167, 15,181, 8,159, 89,213,199,233,227,244,113,250, 56,125,
+156, 62, 78, 31,231,127, 59,124, 83,135, 62,248,224,131, 15, 62,248,224,131, 15,143, 9, 9,110,130,171,204, 20,162, 79,104,121,
+ 15, 18,192,155, 0,134, 0,104,132,210,108,246, 59, 0,172, 68,205,230,244,101, 0,102, 1,232,130,210,213, 57,247, 1,156, 68,
+233,234, 28,131,175,186, 43, 70,112,112,240,135, 92, 46, 55, 0, 40, 77,109,226,124,117,127, 79,211,180,174,176,176,112,209, 99,
+ 42, 2, 5, 15, 35, 40, 59,203,234, 94, 54,247, 87,155,205,246, 56,203,233,195,147,137, 38,114,185,252, 7,141, 70, 51, 18,110,
+ 73,150,125,240,225,191, 1, 33, 33, 33, 19,173, 86,235,108, 30,143,183, 48, 63, 63,127,213,255,208,169, 63, 36,178,202, 8,173,
+253,251,247, 31, 7,128, 1, 3, 6,244, 0,128,128,128,128, 51, 36, 73, 54,240,230, 31, 24,134,185,175,211,233, 42, 13,160, 22,
+ 16, 16,112,134,162,168,135, 56,109, 54,155, 31,135,195, 41,170,232, 55,118,187, 61,163,176,176,176,221, 19, 82,137, 4,128,253,
+129,129,129, 37,243,231,207, 95,217,179,103,207,136,172,172, 44,251,204,153, 51,187, 95,189,122, 53, 14,192, 11, 94,138,173, 78,
+ 4, 65,108,104,211,166,205,238,209,163, 71,111,235,208,161, 3,191,160,160,192,111,199,142, 29,117, 54,110,220,120,137, 97,152,
+145,168, 34,209,234,255, 50,184, 92,110, 64, 70, 70,134, 31, 80,154,154,196, 33,172, 96,179,217, 96,179,217, 96, 52, 26,209,186,
+117,235, 90,255,223,208,208,208, 88,130, 32, 86, 72,165,210,118, 6,131,225, 2,128,201,217,217,217, 87,189, 41,171,221,110, 7,
+203,178,174,114,182,104,209,194,119, 65,189,195,120, 62,159,223, 47, 42, 42,170,189,217,108,214,222,191,127,255, 60, 77,211,159,
+160,246,114,180,249, 3,248, 68, 32, 16,116,104,212,168, 81, 68,114,114,114,186,213,106, 61,135,210,100,200,250,218, 16, 89, 61,
+122,244, 56,245,237,183,223, 6, 77,154, 52,233,212,201,147, 39,187,250,196,150, 15,255, 22, 34, 34, 34, 2,140, 70,227, 58, 0,
+177, 92, 46, 55, 84, 40, 20, 66, 36, 18,229, 8, 4,130, 43, 34,145,104,220,233,211,167,117,222,114,210, 52,253, 73,106,106,106,
+104,199,142, 29,151, 42, 20,138,185,106,181,186,196,106,181, 30,209,106,181,211, 1, 20, 86,245,219,242, 90,228, 41, 19, 89,238,
+175,112,138, 46,142,227,196, 88, 0, 61,203, 40, 48, 14, 39,252,193,131, 7, 10,161, 80, 8,134, 97, 92,157, 89,249,205,249,185,
+197, 98, 65, 76, 76,140,181,154, 14, 39, 34, 61, 61, 93,193,231,243, 93,159, 89, 44, 22,212,169, 83,135,201,200,200, 80, 56,210,
+ 30,184, 96, 54,155, 17, 30, 30,254, 36,229, 60,122, 83, 46,151,235,211,210,210, 91,151,152,173,243,222,120,251,131, 15, 71, 14,
+121, 46,240,204,153, 51,204, 11, 47,188, 96, 62,126,252,248,155, 40, 77,156,234, 81, 99, 78, 16,196,198,153, 51,103,206, 21,138,
+101, 65, 71,207, 36,154, 55,238, 56,144,217,166, 73,125, 98,250,244,233,212,148, 41, 83, 78,196,198,198,254,192, 48, 76, 91,120,
+ 97,217, 10, 12, 12,252, 69, 32, 16,212,115,212, 95,154, 86,171,125,254, 9,188, 33, 57,120, 56,120,108, 69,159, 85,139,130,130,
+ 2,152, 76,166,135,182, 22, 45, 90,120,154, 43,211,171,114,115,185,220, 61,139, 23, 47,174,147,147,157,141,255, 44, 95,222, 17,
+165,150,204,142,158,252, 56, 47, 47,239,161,114, 54,107,214, 12, 62,120,133, 89,115,231,206, 93,252,234,171,175,130,166,105,152,
+ 76,166,176, 59,119,238, 68,207,158, 61,251,149,187,119,239,182, 7,112,239, 81, 7,227, 81, 81, 81, 73, 83,167, 78,149,183,111,
+223, 30,142, 44, 21, 97, 39, 79,158,236,184,126,253,250,215,210,210,210,154, 1,200,127,148, 63,144,203,229, 63,172, 93,187, 54,
+ 72, 44, 22, 99,239,222,189, 65,189,123,247, 62,121,249,242,229,110,143, 32,182,200,160,160,160, 41, 0,158,101, 24,134, 15,224,
+156, 86,171, 93, 0,239,163,186,171,164, 82,233, 78,146, 36,235, 3,127, 71,163, 39, 73, 50,152, 32, 8,181,243, 51,130, 32, 20,
+ 12,195,252,169,209,104, 58,251,110,199,167, 27, 65, 65, 65,227,115,115,115,191, 21, 8, 4,188,192,192, 64,136,197, 98,112, 56,
+ 28,112, 56,156,186, 2,129,160,174, 64, 32,232,223,171, 87,175,201,127,252,241, 71,149, 17,246, 59,181, 81,142, 5, 73,204,163,
+ 8,146, 2, 0,146, 43,145,249,251,251, 99,222,188,121,146,129, 3, 7, 74, 0,224,212,169, 83,163,199,140, 25,211, 59, 35, 35,
+ 35,166, 50,177, 85,145, 22,121,138,144, 80, 85,135, 7,135,122, 60, 94,230,201, 37, 73,240,249,124,156, 61,123, 22,158, 4, 43,
+119,166, 72,168,178, 53,112, 68, 24,191,122,245,111, 3,128,179,163,225,243,249, 56,125,186,108, 80,249, 78,157, 58,185, 30,246,
+127, 10, 67, 90,148, 6,121,220,254, 86,105,185,134,174, 40,141,174,189,253,173,102,232,254,197, 3, 12,153, 50,103,120,113,137,
+245, 25, 0, 70,157, 86,171,189,176,107, 87, 86,155, 38, 77,120, 63,252,240, 67,251, 58,117,234, 12,241, 66,104,205,106,219,182,
+237, 78, 74,228, 31, 60,122,204,216,209,227, 56,164,245,181, 9,239, 45, 76,207, 86, 27,227,227,227,119,237,221,187,119,244,146,
+ 37, 75,110,206,152, 49, 99, 22,128,143, 60, 45,191, 80, 40,172,119,235,214,173, 40,154,166,209,162, 69,139, 39, 49,141, 65, 27,
+148, 6,223,123, 21,192,143,142,207, 70,160, 52,114,127, 44,128, 43,222,144, 57, 45, 88, 21,109,181,141, 58,117,234, 52, 27, 53,
+106, 84,176, 70,173,198,127,150, 47,119,126,220, 14,213, 76, 35, 58,159, 31,139,197,130,193,131, 7,143,162,105,154,227, 20,129,
+102,179,217,162,215,235, 75,240,183, 99,105, 62,128,231, 60, 40, 78, 3,137, 68,242, 57,128, 88,147,201, 84, 7, 0, 36, 18, 73,
+ 38,195, 48,187,141, 70,227, 71,248, 59,129,175,215, 3, 92, 0,209,168, 60, 21, 20,187,120,241,226,228, 15, 62,248,224,222,191,
+192, 89, 79,169, 84, 46, 26, 58,116, 40, 14, 28, 56,128,131, 7, 15,218, 68, 34, 17,103,204,152, 49,196,228,201,147, 3,167, 78,
+157,218, 31,192, 87,143,120,153,251,207,157, 59, 87,222,188,121,115,236,216,177, 3,127,253,245,151, 41, 42, 42, 74,212,179,103,
+ 79,112, 56, 28,249,135, 31,126,248, 2,128, 13,143,242, 7, 26,141,102,193,123,239,189,183,241,199, 31,127,244,187,127,255, 62,
+ 86,172, 88, 17, 60,124,248,240,227,105,105,105, 61,188, 16, 91, 2, 0, 83, 0,244,162, 40,170,219,152, 49, 99,236,111,191,253,
+ 54,151, 36, 73,219,242,229,203, 67,214,175, 95, 63,156,203,229,198, 22, 20, 20,120, 50, 72, 35, 1,204, 27, 55,110,220,235,127,
+252,241, 71,224,249,243,231,249, 65, 65, 65,160,105,218,101, 41,102, 24, 70,225,188,103,237,118, 59,154, 53,107, 22,238,246,123,
+209,211, 42, 52, 72,146,180, 50, 12,195, 5, 32, 4, 96,174,110,255,191, 73,100,201,229,242, 73, 26,141,102,101,104,104, 40,148,
+ 74,229, 67,125,173,217,108,134, 80, 40,228,133,134,134,174, 29, 56,112, 32,119,207,158, 61,149, 78, 1, 18, 20,241,201,222,173,
+243,235,200, 3,253, 0, 0, 95,174,254,181, 24, 0,126,254,249,103,100,101,101, 33, 48, 48, 16, 49, 49, 49,212,252,249,243, 85,
+211,167, 79,255,143, 86,171, 29, 87, 25, 87,121, 45,242,148, 89,180, 18, 42,218,175,210, 71,139,101, 89, 87,158, 60, 15,111,218,
+242, 31, 29, 46,199, 71, 88, 44, 22,148,183,104, 57, 31, 94, 46,151, 91,222,252, 8,130, 32,216,170, 56, 43,192, 24,137,101, 26,
+113, 91, 0, 0, 32, 0, 73, 68, 65, 84, 68,210,218,104, 52,126,227,197,232,214,197,185,253,173,102,216, 40,152, 57,194,153,137,
+180,255,123,165,175, 27, 1,156, 73, 25,183,226,219, 30, 61,234, 76,249,248,235, 57,166,130, 44,245,135,163, 94,172, 23, 21, 26,
+ 36,146,232,242,244,242,166, 77,251,150,179,200, 84, 87,206,238,163, 71,143,222,244,219,217, 84, 66, 40,228,241, 56, 20,197,237,
+218,178, 73, 80,132, 63,229,239, 7,248,167,223, 75, 62, 51,118,236,216,150, 51,102,204,232,230, 5, 39, 28, 29, 46, 54,111,222,
+ 12,130, 32, 72,111,206,189, 22,113,184, 42,145,197,178, 44, 8,130,216,226,214,169,108,113,124,118,217, 77,108,113,170,170, 79,
+167, 53,213, 41,170,198,140, 25, 51,202,110,183,115,220, 26,137,242, 2,166, 34, 17,227,209,185,171, 84,170,223, 0, 60, 71, 16,
+ 4, 44, 37, 37,150,207,191,248,194,253,235,139,229, 68,214,225,202,158, 37,155,205, 6,154,166, 57,151, 47, 95,230,186,221,235,
+ 92, 0, 18, 0,193, 44,203,130, 36,201,107, 30,212,103, 51,177, 88,124,102,223,190,125,178,118,237,218, 17,124, 62, 31,118,187,
+ 29,215,175, 95,143, 88,178,100,201,132,195,135, 15,191, 96, 52, 26, 91,224,225,228,233,158, 92,163,232,147, 39, 79, 26, 27, 54,
+108, 88,161,112, 44, 44, 44,228, 52,105,210,164, 71, 37,162,232,113,115,102,228,230,230,190,252,220,115,207, 77,204,201,201, 73,
+178,219,237,239, 3,136, 9, 14, 14,190, 60,104,208, 32,136, 68,162, 94, 38,147,233,171, 71,185,231, 21, 10,197,192,206,157, 59,
+ 99,197,138, 21, 88,178,100, 73, 31, 0, 71, 0,244, 46, 44, 44, 60,252,210, 75, 47, 33, 32, 32,224,101,157, 78,183,225, 17,158,
+163, 38,221,187,119, 95, 59,111,222, 60,191, 3, 7, 14, 32, 42, 42, 10, 69, 69, 69,120,247,221,119, 21,159,126,250,233, 49,157,
+ 78,215,211,237,185,168,140,179,133, 64, 32,216,240,227,143, 63, 74, 27, 54,108,216,144,199,227,145, 13, 27, 54,132, 70,163, 65,
+ 73, 73,137, 96,225,194,133, 45, 69, 34,209,213,175,190,250,106, 3,128, 65,213,148,147, 4,176, 96,205,154, 53, 19,227,227,227,
+ 3, 70,141, 26, 69, 91, 44, 22,108,219,182, 13, 20, 69,129,203,229, 66, 44, 22,187,146, 87,243,120, 60, 52,109,250, 80,144,244,
+189, 85,156,175, 30,165,126,168, 1,240,110,218,245,112, 21,124,174,169, 15, 46,151, 11,161, 80, 8,161, 80, 8,129, 64,128, 91,
+183,110,125, 44, 20, 10,151, 19, 4, 97,247,132,147,248, 91, 93,180, 6,112,190,186,125, 60,236, 26,242, 79,182,159, 78,132, 19,
+ 4,241, 37,128, 94,165,221, 46,121, 60, 56, 56,248,157,220,220,220, 7,158,114,170, 84,170,160,130,130,130,175, 84, 42, 21,148,
+ 74,165,171,255,174, 83,167, 14,108, 54, 27,114,115,115,193,178, 44,116, 58, 29,196, 98, 49,194,194,194,190,138,143,143,223,145,
+144,144, 80, 80, 33, 39,131, 37, 47, 13,159,253, 9, 69, 81, 36, 0, 80, 28,169,116,234, 7, 64,189,122,245,208,181,107, 87,148,
+148,148, 64,175,215, 35, 58, 58,154, 67, 16,196,104,130, 32,100, 44,203,174, 2,112,244,191,208, 80, 88,169, 51,252,220,242,243,
+162,206,108,241, 60, 30,207, 35,161,229, 56,190, 58, 11, 10,105,179,217,192,227,241,202, 88, 36, 8,130, 0, 77,211,101, 62,119,
+ 10,173,154, 8,245,201,147, 39, 51,107,215,174,157,168,213,106, 87,163,134, 83, 9,163, 71,143,126,200,223, 99,250,244,233, 25,
+121,121,121,236,224,190,173, 37, 73,135,178,178, 27, 5, 74, 69, 33,126,126,245,133,129,242,128,130,130,130, 63, 29,141,137,167,
+104,220,182,109, 91,209,198, 93, 39, 51,222,152,182,120,126,187,134, 65,178, 86,225,193,129,161,254, 34,190,148, 36,140, 66,187,
+ 45, 67, 46,151, 71,121, 91,110,103,187, 32, 22,139, 65,146,228,147,100,209,226, 56, 69,150, 70,163,193,129, 3, 7, 16, 23, 23,
+119,217, 41, 66, 10, 11, 11,145,157,157, 13,149, 74,117,217, 97,249,168,118, 26,145, 97, 24, 88,173, 86, 88,173, 86,151,128,113,
+187,135, 92, 2,198,121, 44, 69, 81,215,106, 88,246,249,129,129,129,221,123,245,234,197,223,186,109, 27,159,101, 89, 35, 74,115,
+168, 25, 88,182,146, 4,217,229, 96,183,219, 93, 86, 54, 46,151,139,180,180, 52, 87,199,229,204, 45, 41, 20, 10, 61, 51,101, 8,
+ 4,239,253,244,211, 79,178,246,237,219, 19, 5, 5, 5, 96, 24,198,213, 72,174, 92,185, 82, 56,100,200,144, 58,151, 46, 93,250,
+208,108, 54,207,173,193,185, 18,149, 9, 34, 0,144,201,100,118,120, 22, 49,187, 90, 78,187,221, 78,116,233,210,101,134, 90,173,
+110,105, 50,153, 22,122, 82,141, 0,246,102,100,100,184,119,236, 87,147,146,146, 76,195,134, 13, 19,213,175, 95,191, 67, 98, 98,
+226, 35,221,164, 77,154, 52,233,196,229,114,113,238,220, 57, 51, 0,231,200,250,248, 95,127,253,101, 30, 52,104,144, 32, 34, 34,
+162,147, 78,231,177,203, 74,147,102,205,154,253,174, 80, 40, 68,206, 54, 52, 36, 36,132,155,144,144,224,151,153,153, 9,171,213,
+138, 89,179,102, 97,192,128, 1, 8, 14, 14,198,244,233,211,149, 75,151, 46,253,193, 96, 48,180,173,202,104,205,231,243, 55,221,
+185,115, 39, 74,165, 82,137,206,158, 61,139, 86,173, 90, 65,173, 86, 35, 39, 39, 7, 6,131, 1, 57, 57, 57, 24, 55,110,156,226,
+ 63,255,249, 79,152, 7,150, 44,151,200, 74, 72, 72,208,237,220,185,147, 90,183,110,157, 31,151,203,117, 9, 45, 14,135,227, 18,
+ 90,206,220,138, 53,152,105,208, 57, 68, 91,128, 94,175,127, 20, 63, 55, 1, 0,190,187,200, 18, 8, 4, 16, 8, 4, 16, 10,133,
+143,148,151,245, 41, 65, 29,130, 32, 18,121, 60,158, 64, 44, 22,243, 72,146,132, 64, 32,232, 43,151,203,111,196,196,196,196,252,
+254,251,239,169,158,144,148,148,148,108, 18, 8, 4, 92,133, 66, 1, 0,136,138,138, 66,171, 86,173, 96, 52, 26, 25,189, 94,143,
+128,128, 0,242,193,131, 7, 48,153, 76,200,206,206, 70,100,100, 36,151, 36,201, 77, 40,245, 67,126, 8,103, 46,231,172, 6,176,
+218,185, 31, 28, 28,156,235,110,233, 20, 10,133,168, 83,167, 14, 50, 51, 51,225,231,231, 71,125,250,233,167,131,182,109,219,246,
+202,153, 51,103, 70, 3,216,236, 70, 53,247, 41,246,209,114,138, 44,247,215,191,133,214,128, 1, 3,230,236,223,191,191, 71, 69,
+163,112, 46,151, 91,107,190, 46, 78, 65, 37,147,201,202, 91,173,192, 48, 76,101, 22, 45,175,255, 71, 40, 20,138, 38, 77,154, 84,
+180,106,213, 42,175,197,214,208, 21, 73, 46, 43,214, 67,195,200, 22, 45,206,124,248,225,135, 3,255,248,227,143,204,118, 13,235,
+115, 36, 89, 15, 12, 66, 89, 64, 0,194,235,198,141,121,121,208, 95, 40, 93,125,232, 41,238, 20, 21, 21,137, 26,133,139, 45, 36,
+ 89, 66,212, 21,112,252, 84, 18,158, 32, 52, 48,176, 14,207, 98,206,147, 5, 6,242,205,102,179, 14, 85, 36,129, 6, 0,165, 82,
+249,171, 72, 36,138,116,238, 7, 6, 6,250,179, 44, 11,177, 88, 12,149, 74, 37,165, 40,234,182,219,195,245, 32, 55, 55,183,111,
+117, 5, 11, 8, 8,248, 85, 32, 16, 68,146, 36, 9,130, 32, 64, 81, 20, 72,146, 4, 73,146,174,247, 20, 69,129, 32, 8, 20, 23,
+ 23, 63, 72, 77, 77,237,235,193,249,218, 1,196, 18, 4,113,249,192,129, 3,232,208,161, 3, 14, 29, 58,132,126,253,250, 65,175,
+215,227,250,245,235,232,222,189, 59, 80, 58,165,232, 17,220,157,223,157,131,130, 91,183,110,185,132,139,251,230,231,231,247, 40,
+ 38,246, 83, 67,135, 14,197,218,181,107, 89,199, 96, 66, 66, 16, 68, 43,127,127,255, 91, 55,111,222,244,200, 15,134,101, 89, 88,
+173,127, 31,234,236,188, 28,254, 16, 94, 37, 7,166, 40,170,111,219,182,109, 9,189, 94,239, 20,144,224,112, 56,160, 40, 10, 20,
+ 69,225,219,111,191, 21,181,111,223,126,182, 64, 32,152,193,227,241, 10,109, 54,219,214,146,146,146,133, 0,116, 79, 82,139,212,
+173, 91,183,105,233,233,233, 3, 34, 35, 35,247, 61, 2, 13,107,179,217, 44, 0, 68, 20, 69,113,107,161,141,162, 28,247, 86,137,
+155,216,183, 59,246, 5, 40,157, 38,246, 8,193,193,193, 63, 28, 60,120, 48, 60, 50, 50, 18, 54,155, 13,118,187, 29, 6,131, 1,
+199,143, 31,135,217,108,134,221,110, 71, 84, 84, 20, 62,249,228,147,146,119,222,121, 71,184,102,205,154, 60,131,193, 48,178, 26,
+218,119,118,236,216, 33, 81,169, 84, 34,147,201,132,123,247,238,161,109,219,182, 40, 42, 42,130,209,104, 68,113,113, 49,172, 86,
+ 43, 10, 11, 11, 3,104,154,182, 84,195,245,177,187,200,154, 48, 97,194, 53, 62,159,223,246,237,183,223, 70, 70, 70,134,235,153,
+127,227,141, 55,160, 84, 42, 93,207,146,163, 77,246,170, 97,230,112, 56, 16, 8, 4,224,241,120,186,186,117,235,130, 32, 8,225,
+131, 7, 15,106, 50, 21, 39, 3, 80,200,229,114,249,238, 2, 75, 32, 16,224,220,185,115, 31,242,249,252,202,172, 89,149, 61,151,
+172, 55,251,255, 54, 8,130,248,146,199,227, 9,228,114, 57,207,109,192,201,147, 74,165, 80, 40, 20, 43, 0,244,247,240,188,219,
+200,229,114, 87,251,222,186,117,107,164,167,167,239,214,235,245,175,229,229,229,129, 36,201, 77, 36, 73,190,226, 28,164,106,181,
+ 90, 68, 68, 68,180,169,140,175,115,108,232, 68, 16,108, 25,139, 86,185, 1, 26,100, 50, 25, 82, 82, 82, 96, 52, 26,217,228,228,
+100, 98,210,164, 73,132,197, 98,249,254,210,165, 75,127,162,116,181,125,165, 90,228, 41,129,247, 62, 90, 78,139,150,167, 29, 0,
+ 65, 16,213,142, 38,108, 54,155, 52, 58, 58,186, 34,135, 47,162, 34,161,229,152, 78,170,209,141,206,229,114,253,106, 42,182,202,
+ 99,223,206, 31,149, 75, 62,153,245,137, 60,172,126,163, 25, 51, 62,230,188,248,226,139,103, 55,110,220, 72,203,155,247,239,125,
+244,215,205,202,175,222,157,121,232,224,193,131, 64,169, 99,180,167, 56,181,127,255,254,208,233, 83, 38,227,147,247,222,249, 69,
+ 22, 21,204,151, 18,114,137,208,108,204,151,130, 53, 9, 26, 55, 27,176,107,223,190,108, 0,151,170, 34, 17,139,197,145,137,137,
+137, 81,238, 11, 9, 44, 22, 11,196, 98, 49,142, 30, 61, 26, 34, 18,137, 66, 0,192,100, 50, 33, 38, 38,198, 83,139, 73,228,237,
+219,183,163,252,252,252, 80, 92, 92, 12,179,217, 12,155,205, 6,134, 97, 64, 16, 4,184, 92, 46,248,124, 62, 36, 18,137,183, 43,
+251,174, 0,120, 53, 46, 46,110,203,161, 67,135, 16, 29, 29, 13,173, 86,139,164,164, 36,167,200,242,202, 71,203,105, 37,114,247,
+199,226,112, 56,248,161, 97, 67,188,145,149,229, 18, 48, 95,250,251,227, 19,166,102,217, 52, 98, 98, 98,216, 83,167, 78,225,151,
+ 95,126,193, 75, 47,189, 68,236,217,179,199, 74,211, 52, 47, 43, 43,235, 90, 86, 86,150, 71, 28, 12,195,184,202,234,108,183,221,
+ 5,150,183, 66,203,110,183,251,241,249,124,148,148,148,192,105,121,112,223, 26, 52,104, 0,141, 70,195, 41, 44, 44,228,100,101,
+101,137, 23, 44, 88,240,246,177, 99,199, 84, 69, 69, 69, 35,254,205, 86,104,213,170, 85,145,111,188,241, 70, 26,135,195, 97,251,
+245,235, 55,234,193,131, 7, 47,171, 84,170, 35,127,252,241,199, 23, 0,154,120,203, 23, 28, 28,124,145,195,225,132, 23, 22, 22,
+242,182,111,223,110, 43, 42, 42,226,133,132,132,228, 58,219, 14,103, 93,219,108, 54,143, 86, 46, 7, 7, 7, 95, 84,171,213,188,
+111,190,249,198, 86, 80, 80,192, 83, 42,149,185, 78, 30,157, 78,199,219,190,125,187,173,176,176,144,231,239,239,127, 81,175,215,
+ 87,203,167, 86,171, 71,142, 30, 61,250,228,145, 35, 71,130, 41,138,194,131, 7, 15, 80, 80, 80,128,128,128, 0,108,218,180, 9,
+145,145,145,216,177, 99,135, 70,163,209,140,255,252,243,207,103, 59, 68, 86,117, 62, 90,221, 59,116,232, 16,169,211,233, 16, 16,
+ 16, 0,163,209,136,139, 23, 47,162, 69,139, 22,200,202,202, 2, 73,146, 8, 8, 8,192,202,149, 43,139, 9,130,208, 84, 69, 36,
+ 18,137, 94,142,143,143, 15, 0,128,248,248,248,128,248,248,248, 10, 59,184, 78,157, 58, 97,197,138, 21,229,133,150, 55, 3, 3,
+151,213,201, 77, 28,149,116,236,216, 17,199,142, 29,155,233,165, 56,178, 56, 69, 91,121,107,150, 64, 32,240,122, 49, 13,195, 48,
+ 60,148,186, 52, 16,158,236, 63, 1,232, 33, 18,137,120,229, 63, 44, 46, 46,230,169, 84,170,110, 94, 8,223, 32,145,168,212,224,
+ 20, 25, 25, 9,189, 94, 79, 91, 44,150,225,155, 55,111,182, 1, 64,108,108,236,112,154,166, 75,236,118, 59,197,231,243, 97, 52,
+ 26,161, 80, 40,130,170,176,141,190,191,119,235,130,208,242, 62, 90, 42,149, 10,177,177,177, 48,155,205,200,206,206,198,241,227,
+199,109, 52, 77,111, 89,181,106, 21, 19, 18, 18,242,250,224,193,131,169, 75,151, 46,189, 5, 96, 90,101, 90,228, 41,179,102, 37,
+ 84, 42,180, 28, 10,242, 24,128,158,229, 79,178,188,248,169, 74,104, 85, 55,117,200,231,243,117,105,105,105, 18,247, 78,197,110,
+183, 35, 44, 44,140, 97, 89,150,168, 72,104, 61,138, 41,152,203,229,250,125,240,193, 7,186, 85,171, 86,141, 76, 73, 73,153,227,
+201,111,182,191,213, 12, 27,203,137,172,213, 75,230,173,248,102,201, 2,249,221, 95,190,199,186,175,151,209, 52,141, 75, 45, 91,
+182,236,102, 48, 24, 56,254, 18, 27,212, 58, 28,114,136, 44, 79, 69, 33, 9,224,187,243,231,207, 95,234,223,191,255,233,239,126,
+218, 37,207,186,119,239, 79, 65,161, 58, 91,214, 56,138,195,171, 19,249, 74, 81, 73, 9,111,248,240,225, 33, 0, 6, 87,215,136,
+233,116, 58,228,228,228,148, 23, 96,184,117,235,214, 67,199,122, 84, 56,146, 4, 77,211,216,185,115, 39,196, 98, 49, 36, 18, 73,
+153,205, 41,178,106,184, 80,225, 54, 0,244,235,215, 15, 26,141, 6, 82,169,212,227,114,149, 23, 47, 44,203,194, 98,177,192, 98,
+177,192,106,181,210, 0,184, 28, 14, 7,227, 50, 50, 92, 86, 30,111, 4, 76,121,180,108,217,146, 61,115,230, 12, 78,159, 62, 13,
+163,209,136,111,190,249, 6, 42,149,234, 89, 0, 31,123,203,229,230,164, 79, 23, 22, 22,114, 11, 11, 11, 93,214, 65, 46,151,235,
+178, 30,120,104,201,227,113, 56, 28,215,104,212,185,185, 91,181, 40,138,130, 82,169, 68,104,104, 40, 86,175, 94,205,171, 95,191,
+254,128,127,179, 5, 90,186,116,105,227, 47,191,252,114,253,198,141, 27, 15,141, 28, 57,114,219,245,235,215,199,250,251,251, 95,
+ 59,122,244,232, 2,129, 64,192,212,240,249, 14,207,202,202, 82,184,127,196, 48,140,216,110,183,187,132,109,113,113,177,199, 3,
+ 12, 46,151, 27,158,152,152, 40, 6,128, 5, 11, 22,112, 1,136,157,206,224, 78,206,226,226, 98,110,139, 22, 45,194, 61,189,215,
+ 79,158, 60,217,173, 79,159, 62,103,126,255,253,247,192,200,200, 72,100,102,102, 34, 51, 51, 19,141, 27, 55,198,162, 69,139,140,
+133,133,133, 93, 0,220, 54, 24, 12,123, 60,228, 12, 11, 12, 12,228,166,165,165,193,110,183,163, 77,155, 54, 88,185,114, 37,134,
+ 15, 31,142,152,152, 24, 20, 22, 22, 34, 49, 49, 17, 27, 54,108, 8,228,241,120, 85,182, 29, 38,147,105, 79, 66, 66, 66, 68,121,
+139,214,168, 81,163, 36,185,185,185,174,123,114,222,188,121,101,166, 16,189,105,147, 29, 83, 91,149,110, 53,129,221,110,151, 9,
+133,194, 66,129, 64,192,119,250,103, 29, 63,126,220,107,107, 86,185, 1,160, 55,251,255, 26,156,162,181,130,190, 21,161,161,161,
+ 30,243, 8, 4, 2,194,217, 54,218,237,118,232,245,122, 90,165, 82,185,166,247, 47, 95,190, 76,215,171, 87,143,166, 40,138,226,
+243,249, 32, 8, 2, 98,177,184,210, 6,159,165,217,121, 47, 14,255,184,204,170,195,169, 31, 0, 86,171, 21,151, 47, 95,134,213,
+106,197,241,227,199,109,159,127,254,121,150, 78,167,155, 10,128,243,235,175,191,142,158, 57,115, 38,165, 80, 40,250,228,229,229,
+161, 58, 45,242, 20,137,173,135,172, 92,206, 94,232,216,128, 1, 3, 8,199,210, 74,194, 41,156,188, 17, 90,142,135,175,218,158,
+151, 32, 8,100,103,103,187,246, 21, 10,133,215,255,229, 41,130,130,130,140,157, 58,117,242, 83,171,213,123,150, 46, 93, 90, 35,
+ 75,214,234, 37,243, 86, 44,158,255,169, 92,115,243, 44, 50,178,178,161,201,179, 93, 58,117, 45,101, 55,128,221, 0,128, 53,205,
+143, 17, 19,147,190,245,148,179, 89,176,168, 53,151,199,217,253, 92,255, 1, 17,195,226,167,145,111,190,249,102,215,209,163, 71,
+235, 71,142, 28, 57, 69, 42,149, 54,177, 90,173,218, 93, 7, 14,164, 14, 27, 54,172, 62, 77,211,163, 81, 77,204, 17,147,201,244,
+160,103,207,158,238,245, 41, 59,124,248,176, 50, 53, 53, 21,147, 39, 79,206,207,204,204,212,185, 31,235, 73, 25,173, 86,235,131,
+214,173, 91, 87, 58, 93,232,156, 82, 4,128,162,162,162, 7, 94, 84,233, 8, 56, 28,223, 11, 10, 10,112,235,214, 45,112, 56, 28,
+116,236,216, 17,167, 78,157, 66,215,174, 93, 47,123, 99,213, 42, 41, 41, 65,100,100, 36, 74, 74, 74, 96, 52, 26,139, 1, 8, 54,
+213,175, 15, 0,120,171,160, 0, 23, 63,255, 28,103, 23, 47,134,251,253,236, 41, 90,181,106,197,158, 61,123, 22,215,174, 93,131,
+217,108,198,248,241,227, 1,128,112,220,187,222,132,204,104, 72, 81, 84,191,254,253,251,135, 1,128,209,104, 36,206,159, 63, 15,
+161, 80,232,122, 22,246,237,219,135,204,204, 76, 16, 4,129,192,192,192,112,173, 86, 91, 31, 64, 74, 21,102,127, 34, 37, 37, 5,
+159,125,246, 25, 24,134,193,204,153, 51, 17, 21, 21,229, 18, 88, 15, 30, 60,192,130, 5, 11, 64,211, 52, 62,253,244, 83, 52,110,
+220, 24, 54,155, 77,136, 26,134,208,168, 13, 76,159, 62,253,238,238,221,187, 15,165,167,167,191,176,100,201,146, 30, 4, 65, 48,
+ 51,102,204,248, 76, 38,147,209,143,194,171,213, 23,225,214,157, 7, 46, 33, 84,126, 11, 9,150,123,205,151,124, 47,221,245,123,
+154,118,231,163, 17, 36, 15,244,182,136,197, 54,155,205,248,202, 43,175, 4,236,220,185,147,104,220,184, 49,238,223,191,239,180,
+ 12, 21,195,251,144, 14,153, 26,141, 38,138,162, 40,222,157, 59,119, 80,175, 94, 61,116,232,208, 1, 11, 23, 46,132, 90,173,134,
+221,110,135, 66,161, 96,108, 54,219,101,171,213,122,162, 26,174,121, 19, 38, 76,224, 1,152,232,176,108,181,156, 58,117, 42,179,
+108,217, 50, 92,190,124,217,101,193,114,119,134,247,118,234,208,221,234,228,190, 29, 63,126,124, 38,159,207,103, 1,156,131,247,
+129,158, 45,229, 45, 90, 53,177,102, 61, 46, 60,206,149,140, 42,149,234,184,159,159,223, 0,173, 86, 91,198,170,213,165, 75, 23,
+171, 82,169, 60,233, 41,143, 84, 42,213, 82, 20, 21, 4, 0,153,153,153,144, 72, 36,188,123,247,238, 45, 70,105,240,108,212,175,
+ 95,127,177, 70,163,225,213,119,180,167,161,161,161,176, 88, 44,149,186,177,252,121, 37,247,123, 0,223, 59,247,229,114,121,182,
+ 94,175, 23, 45, 91,182,204,176,120,241, 98, 19, 77,211,102, 0, 71,117, 58,157, 43,142, 86, 78, 78,142,158,203,229,202, 3, 2,
+ 2,234, 56,133, 86, 69, 90,228, 41, 67,229, 22, 45,135,146,100,203, 11, 34,130, 32, 30,114, 80,175, 70,104, 85, 43,178,104,154,
+ 46, 99,101,112, 58,188, 87,244, 95,142, 78,189, 70, 83,135, 14,145, 37,220,181,107,215,166,165, 75,151,158,243,244,119,238, 62,
+ 90,107,190,152,191,196, 41,178,254, 58,253, 59,246, 36,233,213, 51, 23, 47,255,178,166, 87,160,121,176,184,149, 82, 25,116,236,
+243, 69,243,100,119,127,217,128,109,107,254,195,254,117,225, 66,251, 11, 23, 46,188, 54,121,242,228,186,142, 27, 75, 3,224, 42,
+128, 97,240, 96,149, 78,102,102,102,223,114,157,240,109, 30,143,167, 20,139,197,200,204,204, 52, 36, 39, 39,123, 61, 37,163, 86,
+171,251, 62,134, 27,144,227, 20, 89,106,181, 26,137,137,137,232,213,171, 23, 0,224,212,169, 83,232,210,165, 11, 46, 93,186,132,
+182,109,219, 94, 6,240, 12,170, 9,212,106,179,217,116,205,155, 55,119, 89,183,244,122, 61, 3, 0,241,217,217, 72, 80,169,192,
+225,112,112,118,241, 98,124,100,179, 97,161,151, 2,190,117,235,214,236,249,243,231,145,154,154, 10,187,221,142,129, 3, 7,162,
+134, 15,125, 76,179,102,205, 14, 31, 61,122, 52, 68, 42,149,194,104, 52,194, 96, 48, 96,204,152, 49, 24, 62,124, 56,204,102, 51,
+182,111,223,142,189,123,247,194,207,207, 15, 70,163, 17, 70,163, 49, 48, 46, 46,238,204,237,219,183,187, 3,184, 83,137,208, 98,
+251,246,237,139,147, 39, 79,130,162, 40,180,111,223, 30, 5, 5,127, 47, 6, 82, 42,149, 21,125, 71,253,155, 66,139,195,225,176,
+199,143, 31, 95,210,163, 71, 15,164,167,167,191,208,182,109,219,111,198,142, 29,155,249,168,188,129,254,126,104,221,162, 33,204,
+102, 51,204,102, 51,194,194,194, 80, 84, 84,132,187,119,239,194,108, 54, 67,169, 8,240,154, 47, 54,166,177,139, 79,161, 80,192,
+104, 52, 34, 37, 37, 5, 22,139, 5,193,193, 94, 9,173,136,190,125,251,254,177,101,203,150,160, 13, 27, 54, 88,122,246,236,201,
+255,230,155,111, 8,153, 76, 6,183,142,197, 91, 28, 63,117,234, 84,100,159, 62,125,154,222,188,121, 19,199,143, 31,135,197, 98,
+ 65,108,108, 44,146,147,147,209,169, 83, 39, 24, 12,134,115, 23, 46, 92,216,235,137, 97, 24,192,236, 9, 19, 38,192, 41,182, 78,
+158, 60,137,236,236,108,248,249,249, 61, 36,180,156,190,143,142, 85,227, 97,158, 20,214, 41,136,220, 44, 79, 31, 5, 4, 4, 88,
+ 1,124, 89, 67,235, 19, 0, 32, 61, 61, 93,208,178,101, 75,179, 80, 40,228, 59, 68,219,242, 71,225,171, 77,212,194, 74,198, 74,
+ 17, 26, 26, 58, 53, 56, 56,184, 79,131, 6, 13,144,155,155,203,227,243,249,232,210,165,139,245,153,103,158,177,134,134,134,190,
+229, 41,143, 64, 32,184,201,227,241,186,151, 14, 38,104,164,165,165,129,101,217,153, 49, 49, 49,239, 20, 21, 21,161,160,160,128,
+ 47,147,201, 92,131,234,166, 77,155,194,108, 54,223,244,194,242, 54,175, 94,189,122,179,121, 60,222, 66,181, 90, 93, 81, 88, 8,
+126, 64, 64,128,140,199,227,193,106,181,150, 17,155,229,181,200,211, 46,178,202, 8, 45, 55, 21, 89, 70,232,120, 99,209,242,196,
+106,224,116,176,119,223,119,138,186,242,255, 85,211, 24, 90,254,254,254,102,167,200, 90,184,112,225,185,154,112,236,216,178, 89,
+229,207, 20, 71,100,157, 59,136,219,215, 46, 97,119,162, 78, 61,115,241,242, 41, 47, 14, 30,145, 91, 94,152,121,130,168, 16,113,
+140, 82, 17,116,236,139,165,139,101,154,155,103,145,157,147,131,131,231, 46, 92,178, 2,137, 0,102,214,166,105, 25, 40,157, 58,
+164, 40,234, 73,186, 97, 93,206,240,217,217,217, 78,145, 21, 11, 0, 93,187,118,189,236, 16, 89,240,212,162,165,211,233,202,167,
+172,233, 3, 32,216,121,254, 28, 14, 7, 93,102,207,246, 90,100, 1, 96, 47, 93,186, 4,141, 70,227, 28, 41,214, 84,100, 33, 52,
+ 52,244,189,163, 71,143,134,124,247,221,119,133, 27, 55,110, 44, 96, 24,134,219,186,117,235,240,118,237,218, 17,155, 54,109, 2,
+ 0, 12, 27, 54, 12, 51,103,206,196,141, 27, 55, 32,145, 72,208,181,107, 87,122,206,156, 57,138,169, 83,167,190,149,155,155, 59,
+165,194,222,145, 97,120, 66,161,240, 8,128,103,111,222,188, 9, 0,103, 80,154,194,201,105, 69,168,244, 59, 79, 58,223,162,162,
+ 34,174,159,159, 95,133,161, 33,120,165,163, 33,111, 45, 16, 46,206,211,167, 79,127,246,197, 23, 95,236,126,247,221,119,239, 60,
+ 34,103,133, 22,173, 1, 3, 6,192,100,182, 34, 35, 87, 15,154,182,195,100,205,243,154,207,221,162, 53, 96,192, 0, 20,151, 88,
+144,150,173,129,221, 78,163,200,228,113, 95, 46,126,238,185,231,126,221,186,117,107,232,159,127,254, 9,154,166,153,228,228,228,
+148, 87, 94,121, 69, 54, 99,198,140,160, 71, 88,100,244,245,136, 17, 35,134,156, 62,125, 90,211,180,105, 83,249,185,115,231,144,
+151,151, 7,187,221,142,103,159,125, 22,124, 62, 63,109,241,226,197, 60, 0, 95,123,122,109, 28, 98,203,122,225,194,133, 55,206,
+158, 61, 43,151,203,229,124,166, 89, 51,100,255,254, 59,118,238,220,249,208, 15,214,172, 89, 3,120, 24,133,223,105,113, 58,127,
+254,124,173, 8,172, 50, 61, 53,159, 95,227,233,199,167, 21,231,207,159,207,124,243,205, 55, 91,200,100,178, 47,187,117,235,214,
+ 43, 40, 40,136, 12, 12, 12, 60, 94,167, 78,157,119, 90,183,110,237,241,236, 2,151,203, 29, 43,145, 72,238,218,237,118,202, 96,
+ 48,192,104, 52,150, 54,210,118, 59,159, 36, 73,212,175, 95,223,213,151,180,111,223, 30,161,161,161,116, 82, 82,210, 88, 79,249,
+243,243,243,203,172, 66,172, 0, 19,186,116,233,194, 49,155,205, 72, 77, 77, 61,229,254, 69, 69, 90,228, 41, 65,124,149,226,203,
+121, 82,238, 39, 87,167, 78,157,116,155,205,198, 38, 2,236,213,171, 87,217,248,248,248, 42,183,146,146, 18, 86,161, 80,100, 87,
+208,249,193,157,211,108, 54,151,249,157,217,108,102,149, 74, 37,109, 50,153, 30,226, 52,153, 76,108,120,120,120,102, 85,156, 21,
+ 96,204,149, 43, 87, 86,125,244,209, 71, 29,188,168, 32, 23, 39,187,186, 25,187, 97,195,134,255, 99, 89,182, 71,183, 22,145,215,
+134,182, 86,178, 93,162, 20, 89,123,119,108, 25,206,178,108,143,242,155, 51,192,105, 85,156,205,148,146,230,189,163,235,106,255,
+250,229, 71,246,232,178,183,217, 47, 6, 70,177,109,195,253,116,205,130, 69,222,230,136,169, 54, 91,122,116,116,244,109,134, 97,
+ 88,139,197,194, 70, 71, 71, 39,215, 6,103, 13, 80, 21,103, 27,148,250,178,141,168,224,179, 54,143, 80,206,191, 88,150,101, 53,
+ 26, 13,107, 48, 24, 88,179,217,204,210, 52,205,186, 3,192, 95, 30,112,178, 86,171,149,213,106,181, 44, 60,247,185,171,144, 83,
+165, 82,165,220,187,119,143,109,212,168, 81,186,195, 28, 63,213,104, 52,178,229, 97, 52, 26,217, 94,189,122,177,201,201,201,108,
+189,122,245, 74,146,147,147, 89,149, 74,117,171,154,114, 54,136,136,136, 56, 18, 28, 28,124, 28, 64,148, 23,223, 85, 89,159,219,
+183,111,111,200,178,236,120,150,101,227, 43,217,198,179, 44,219,236,223,230,116,212,111, 46,203,178,108,113,113, 49,171,209,104,
+216,172,172, 44,182,184,184,152, 53, 24, 12,236,149, 43, 87,216, 63,255,252,147,189,118,237, 26, 43,151,203,115, 61,225,116,242,
+ 89, 44, 22,182,176,176,144,205,203,203, 99, 77, 38, 19,107, 52, 26,217,235,215,175,179, 23, 47, 94,100,111,222,188, 89, 17,223,
+ 67,156, 65, 65, 65,107,114,114,114, 12,103,206,156, 41, 94,189,122,117,113,104,104,232, 77, 0,145, 0,154, 4, 6, 6,230,188,
+253,246,219,172, 84, 42,125, 80,195,231,168, 5,151,203,189,178,100,201,146,243,251,247,239,207,221,187,119,175,101,253,250,245,
+ 25,147, 39, 79, 62,193,225,112,174, 0,104, 81,195,231, 72, 17, 16, 16,112,230,220,185,115,118,173, 86,203,234,116, 58,182,176,
+176,144, 53, 26,141,172,201,100, 98, 45, 22, 11,107,179,217,216, 19, 39, 78,176, 74,165,210,125, 90,242,253, 42, 6,214,211, 88,
+150,125,143,101, 89, 78,109,183,117,110,220,221,106,139,179, 54,218, 58,146, 36,173,142,182,163, 99,233,110,213,251,255, 86, 57,
+123,247,238,253,233,240,225,195,217,126,253,250,177,177,177,177, 15,109,109,219,182,101, 39, 77,154,196,238,223,191,159,253,252,
+243,207, 63,173,133,114,114, 80,186,232,101, 81,239,222,189,109, 39, 79,158,100,135, 13, 27,198, 2,232, 91,149, 22,249,111, 16,
+ 92,206,240, 14,132,251, 43, 0, 88,173,214,244,219,183,111,171,154,218,237, 20, 0,124,251,237,183, 15, 89,166,220,113,242,228,
+ 73, 59, 65, 16,119,171,250,119,171,213,154,126,244,232, 81,229,138, 21, 43,184,110, 38, 96,216,237,118, 38, 43, 43,139,252,230,
+155,111,202, 28,127,236,216, 49,187,221,110, 79,243,242, 36, 55,180,105,211,102, 67,109,212,214,137, 27,169,239,252,122,240,231,
+224,142, 29,186,233,100,114,121,133,163,176,237,111, 53, 3, 49,177,106,171, 22,193, 33, 23, 46, 89, 52, 47,192, 57, 5,249,211,
+229, 28, 93,137,153,238,149,164, 54,253, 85,219, 87,216, 96, 48,164, 58, 87, 2, 26,141,198,180, 39,240, 38,188,130,210, 24, 87,
+246,114,159, 61,131, 71,116, 58,101, 24, 6,254,254,254, 46,107,104, 13, 44,162,172,211,194,234,188,116,143, 82, 30,150,101, 79,
+ 95,191,126,189,222,152, 49, 99,252, 54,110,220,120,143,166,105,238,184,113,227,172,161,161,161,188, 83,167, 78,217, 0, 16, 61,
+122,244,224,228,228,228,176,153,153,153,154,151, 94,122,169,232,141, 55,222, 8,186,122,245, 42,159, 97,152,234,130, 22,222, 79,
+ 79, 79,239, 93,131,239,170,196,208,161, 67,239,225,209,211,216, 60,118, 78, 39, 52,186, 66,220, 75,205,116, 68, 48,103, 64, 63,
+200,117,249, 85,217,108,118,104, 10, 11,188,182,104,221, 77,201,116,164, 24,163, 65,211, 89, 14,190, 82,135,120, 86, 91, 92,125,
+111,194,225,116,157, 51,103, 78,127,146, 36,201,179,103,207,154,151, 46, 93,154,158,159,159, 63, 16, 64, 26, 0,104,181,218,158,
+ 27, 54,108,248,193,131, 80, 14,149, 33,209,102,179,117,122,255,253,247,167, 0,232, 10,160,174,131,251,148,195,146, 85,211, 8,
+230,121, 58,157,238,249,254,253,251,255, 78, 81, 84,125,183,231, 40, 24,128,218,249, 92,176, 44,171,200,205,205,125,193, 19, 66,
+130, 32,150, 63,174,134,228,113,114, 63, 98, 59,244, 84,172,100, 60,114,228,200,220,129, 3, 7,114, 34, 35, 35, 63,140,140,140,
+ 36,181, 90, 45, 12, 6, 3, 72,146, 68,104,104, 40,162,163,163, 17, 26, 26,202,220,188,121,115,209,172, 89,179,170,141,201,215,
+188,121,243,134, 54,155,173, 17, 73,146, 13, 1, 52,100, 89,182, 33, 65, 16, 13, 1,200, 1, 64, 38,147,201,234,213,171,199,233,
+216,177, 35, 58,116,232,128, 99,199,142, 97,199,142, 29,223, 3,248,213,221,154, 85, 94,139, 60, 9, 72,108, 3,182,197, 21, 16,
+ 55,218,162, 7,193,224, 24, 75,162,103,244, 37, 87,156,189,242, 34,171,242,164,210, 21,152,254,250, 62,251,236,179,174, 7,206,
+131, 78, 37,181,186,135, 47, 63, 63,191,239,216,177, 99,203,112,210, 52,109, 46, 40, 40,120,179,115,231,206, 43, 41,138, 18,148,
+187, 97, 31,228,229,229,253,163,185,250,202,199,209,234,219,255,101,245,163,114, 74,121,100,163,219, 7,214, 34, 55, 79,141,159,
+ 46,231,104,139, 44,116,207,100,117,241,245,199, 81,254, 7, 15, 30,244,123, 10, 20,127, 69,162,245, 81,147,103,231,123, 16,144,
+180,186, 28,117,132, 35,156, 72,173, 60,228, 57, 57, 57,203,102,207,158,253,252,162, 69,139, 66, 14, 29, 58, 36,115, 14, 80, 6,
+ 13, 26,148,119,253,250,245,110, 0, 4, 37, 37, 37,135, 23, 45, 90, 20, 50,111,222,188, 32, 0, 65, 0, 16, 23, 23,151,155,155,
+155,187, 2, 62, 84, 9,155,205,150, 17,221,188,169,107,224,231, 30,210,193,253,189,221,110,207,240,134,175, 34, 30,247,125,154,
+166,171,228,163, 40,234,221, 14, 29, 58, 80,239,190,251,110,238,161, 67,135,156,137,116,221, 21,218,237,106,130,146,122, 2, 51,
+128,165,142,173, 54, 97,212,104, 52,157,188,252, 13,237,187, 27, 43, 28, 80,122,179,255,175, 96,207,158, 61, 31, 15, 27, 54,108,
+131, 92, 46,223,220,176, 97,195,166, 74,165, 82, 38, 18,137, 96, 54,155,139, 44, 22,203,173,219,183,111,143,252,248,227,143,239,
+123,100,225,216,176,129, 2,192, 99, 24, 70, 72,146,164, 4,128,140, 32,136, 64,167,208, 34, 8, 2, 86,171, 21,169,169,169,248,
+232,163,143,232, 35, 71,142,124, 14,224, 83, 47, 6,174,207, 0, 8,113,107,199, 67, 0, 88, 80, 26,192, 54,159, 32,136, 11,143,
+187,190, 8, 6,199, 90, 92, 1,145,216, 6, 21,245, 19, 85, 39,149,174,236,129,203,207,207,239, 84,219, 15,113,101,156,249,249,
+249,145, 79,202, 19, 50,218,188,244, 71,172, 89, 90, 38,207,161, 83,132, 85,180, 95, 29,244, 38,251,228,175,127,189,177,204,108,
+103, 25,171,157,121, 61, 57,191, 56,209,215, 14,213, 58,158,171,173,103,169, 22,203,116, 61, 41, 41,169,243,228,201,147, 63, 22,
+139,197,237, 1,160,184,184,248,108, 86, 86,214,124, 56, 86, 21, 86,247,189, 15,149, 67,173, 86,183,123, 18,249, 44, 22,203, 59,
+157, 59,119,254,138,166,233, 47,236,118,251,169,255,129, 75, 81,226,187, 27,159, 94,108,219,182,237, 62,128, 78, 0, 48,100,200,
+ 16, 10, 0,118,236,216,225,181,120, 30, 51,102, 12,205,178,172,213,113, 63, 24, 81,186,186, 80,235,108, 83,141, 70,163, 54, 43,
+ 43,235, 38, 77,211, 55, 1,252, 0,239, 87,220,134, 16, 4,177,159,101,217, 1, 14,225,182,159,101,217, 1,238,159, 61,110,171,
+ 86, 53,135, 84,239, 12,239, 67, 41,118, 36,130, 40, 63, 21, 88,221,126,117,184,157,107, 60, 14,160,173,175,118,255, 39,113, 47,
+ 43, 43,107,244, 35,124,239,195,211,135, 52,139,197, 50,240,127,232,124,245,190, 75,254, 95,210,255,213, 64, 96, 57,113,243,230,
+205,199,230, 34,240,111,163,197,149,178, 3,240,242,251,110,136,175, 72,120,249,132,150, 15, 62,248,224,131, 15,143, 2,157,175,
+ 10,124,248,111,134,211, 55,203,185, 95,137,143, 86,121,255, 44,215, 62,129,202, 87, 14,120,147,149,188, 38,171, 36, 14,251, 56,
+125,156, 62, 78, 31,167,143,243, 95,231, 12, 0, 80, 15,192,146,106,142, 43,191,186, 48, 23,128, 26,128,205, 87,159, 62,206, 71,
+208, 15, 30,129,101,217,184,170,166, 14, 9,130, 56,240,184,132,150,203, 25,190, 13,230, 68, 95,193, 28,231,190,167, 66,235,113,
+163,143,143,211,199,233,227,244,113,250, 56,125,156, 62, 78, 31,231, 35, 10,173, 94,179,102,205,250, 0,165,161, 49,216, 89,179,
+102,125,192,178,108, 92,233, 87,108,220,227,252,239, 27,109,209, 35,177, 13, 88,231,118,163, 45,122, 84,114,104,188,219,230,130,
+111,234,208, 7, 31,124,240,193, 7, 31,124,120,210,113,102,241,226,197,197,139, 23, 47,118, 58,190,231, 3, 32, 28, 22,174,252,
+199,249,199,142,105, 66, 79, 22, 74, 85,157,130,231, 95, 64, 24,201,225,141,226,242, 4,189,192, 50,209, 0, 0,146,186, 65, 91,
+ 74,254,176,219,173,155, 1,100,213,148,184, 25,208,188,113,128,104,175,153,166,121,233, 69,150, 33, 73,165,105, 14,188,198, 16,
+160,139,128,207,255, 77, 16, 16, 32,170,232,123,179, 78,103, 50, 91, 44,207,239, 0, 78,251,158, 1, 31,124,240,193, 7, 31,158,
+ 18, 72, 2, 3, 3,143,144, 36, 25,233,252,192, 61,238, 96,249, 24,132, 52, 77,103,107, 52,154,231, 81, 58, 85,252, 79,114,186,
+255,222,130, 26,246,229,181, 13,111,167, 14, 57, 64,153, 40,172,255, 72,198,108,138, 43,120,195,207, 63, 96,225,255,141,125, 39,
+ 40,170, 73, 83, 34, 34,162, 14,192, 2,105,233, 25,202,187,119,146,123,111,219,248,245,244, 66,189,230, 35,155,217,188,214, 91,
+238,230,128,164,174, 84,112,106,237,172, 87, 3, 56,176, 99,196,130, 45,191, 16, 6,107,196,205,210,229,166, 94,137,172,128,160,
+160, 95, 23, 31, 62, 44, 10,108,213,170,204,119, 44,203,150,230,215,251,235, 47,209,135,207, 63,255,235, 16,141,166,175, 79,108,
+253, 87, 34, 84, 38,147, 77,229,114,185, 61,173, 86,107, 36,159,207, 79,167,105,250,184, 86,171,253, 18, 64,166,175,122,254,187,
+209, 52, 84,210,173,105,195,200, 45, 89, 57,185,151, 11, 75, 44,227,110,103, 25, 52,190, 90,241, 26, 85,229,215,252,215,114,111,
+ 2,128, 84, 42,189, 72,146,100,184,187, 8,112,230,236,117,238,151,127,101, 24,230,190, 70,163,233, 92, 5,109, 67,185, 92,190,
+ 18,192, 51,213, 5, 76,118,196,102,187,160,209,104,222, 68,229,171,245,252, 2, 3, 3,231, 18, 4, 49,148, 36, 73,170,186,115,
+ 98, 24,134,102, 89,118,187, 86,171,253, 20, 64, 81,101,199, 5, 6, 6, 30, 78, 74, 74,122, 70,161, 80, 84,107,165,177,219,237,
+ 72, 75, 75, 11,105,223,190,253, 9,141, 70,211,236,113,114,254,211, 90,164,166,168, 98,213, 97,165, 55, 58,128, 50,249,133, 30,
+107, 68, 86,158, 80,186,183, 83,247,190,189, 38, 77,121, 87,114,229,250, 45,252,118,236, 79, 20, 26,205,160, 72, 18, 1,126, 98,
+ 52,105,210,136, 88,158,176, 51,248,251,213,203,191, 56,123,242,247,184, 18,163,254, 37,175,100,186,152,243,209,204, 87,218, 75,
+130,228, 52,192,208,120,175,127,107,201,135,251, 47,127,132, 98,251, 7, 94,139,172, 35, 71,196,121,185,185,152, 23, 22, 6,142,
+221, 14, 33, 73, 66, 72, 16, 16,146, 36, 36, 66, 33,250,173, 95,143,249,135, 14,137, 63,126,225, 5,159,216,250, 47,131, 84, 42,
+ 29, 27, 22, 22,182,116,221,186,117, 65, 13, 26, 52,128, 68, 34,129, 70,163, 9,190,125,251,118,155,105,211,166,141,206,206,206,
+158, 93, 88, 88,184,198, 87, 83,255,189, 96, 24,140,250,110,225,155,117,178, 31,220,169, 51, 97,209,143, 77,136, 32,186,231,173,
+ 2, 83,142,175,102, 60, 70, 27, 0,151,248,250,153, 97, 0, 0, 32, 0, 73, 68, 65, 84, 81,113,254,210,170,190,171, 20, 66,161,
+ 48,183,164,164, 68, 81,213, 49,124, 62, 63,207, 98,177, 40,171,227, 34, 73, 50, 60, 51, 51, 83, 33, 22,139, 65,211,180, 35, 27,
+ 0,227, 26, 72,187,103, 63,113, 4,170, 69,179,102,205,172, 85,113,250,249,249,125,155,151,151,215,199,153, 39,208, 77, 80, 85,
+136,204,204,204, 62, 45, 90,180,248,182,168,168,232,249, 74,196,203,220, 41, 83,166, 76,141,137,137,113, 90,129, 28, 89, 16, 74,
+ 95,213,106, 53, 38, 79,158,236,250, 15,134, 97,240,251,239,191, 79, 25, 59,118, 44,180, 90,237,180, 42,206, 61, 82,161, 80, 16,
+142,132,226,149, 98,206,156, 57,152, 51,103, 14,190,254,250,107,130,203,229, 6, 84, 83,159,181,194,249, 79,105,145,154, 88,176,
+170,137, 12,127, 0,101,125,179, 14, 60, 36,180,254, 9, 80, 92,193,235,207,116,238,211,115,242,212,153,146, 31,127, 62,138,219,
+ 55,255, 66,210,169,173,101,142,105,247,252, 88,228,168,139, 48,118,210,123, 82,130,226,244, 60,121,120,207,235, 54,179,233, 59,
+ 15,173, 89,202, 72, 1,255,237,142,237,163,185,153,162,219, 8, 13, 20,161,107,219,198,220,136, 95,175,189,109,132,253,171,155,
+165,171,100,188, 18, 89,235, 94,125, 21,221,108, 54, 40, 40, 10, 20, 65,128, 2, 64, 18, 4, 74,204,102, 92, 24, 53, 10,237, 55,
+109,194,167,251,246,137,231,190,248,162, 87, 98, 75, 34,145, 92, 33, 8, 34,208, 96, 48,196,161, 52,177,244,211,128, 22, 82,169,
+244, 0,203,178, 90,163,209,216,230, 9, 42,151, 10,165,115,244,229, 71,199, 60,148,174,168,242, 42,179,176, 64, 32,120, 99,200,
+144, 33,203, 87,172, 88, 33,206,205,205, 69, 86, 86, 22,104,154,134, 80, 40, 68, 84, 84, 20,113,248,240,225,160,153, 51,103, 46,
+ 59,112,224,128,160,168,168,232, 43,111, 6, 54, 92, 46, 55, 65, 46,151,191,160, 84, 42, 37,121,121,121,197, 58,157,238,119,179,
+217,252, 6,106,158, 54,133,228,114,185, 35,235,213,171,247,114, 88, 88,152, 50, 51, 51, 83,157,145,145,177,215,108, 54,127,143,
+ 26, 38,106,118,171,211, 86,112, 68,171, 7,144, 93,175, 94,189, 27,169,169,169,121,181,200,153, 85,175, 94,189,196, 26,112, 74,
+ 0,108, 3, 16, 86,205,113, 89, 0,134,193, 75,107,182,171, 98, 89,230,224,130, 47,215,141,155, 55,166, 43,241,221,180, 62, 81,
+ 19,191, 62,252, 39,201, 99,187,223,204, 46, 73,247,105, 40,207, 68,150, 35,165, 85,121, 65, 85,213,119, 85,194,108, 54,135, 88,
+173, 86,112, 43, 73, 22,111, 52, 26,225,231,231, 23,226,105, 33, 69, 34, 17,182,110,221, 10, 46,151, 11, 46,151, 11,173, 86,139,
+240,240,112,215, 62,143,199,115,189,175, 91,183,110,181,124, 52, 77,183,167, 40, 10, 6,131, 1, 52, 77,187, 54,157, 78, 7,150,
+101, 33, 16, 8, 64,211,165,233,156,220,190,111, 95, 25, 31, 65, 16, 67,195,194,194,240,227,143, 63,194, 98,177, 60,244,189, 76,
+ 38,195,245,235,127, 39, 25,161, 40, 10, 29, 58,116, 32, 9,130, 24, 10, 96, 90, 21,188, 44, 0,196,199,199,131,162, 40, 80, 20,
+ 5,146, 36, 93,239,157, 27, 77,211,152, 51,103, 14,202,165, 38,251,199, 56,159, 52, 84, 19, 25, 62, 27,149,248,104,145,143,185,
+ 92,238, 75, 60,195,196, 18,217,103,111,190,243,158,244,192,137,107, 72, 75, 79,123, 72,100, 1,192,197,223,190, 71,118, 86, 38,
+ 46, 39,101, 96,228,235,111, 73,101,178,128,207,202, 53,168,149, 46, 27,245,247,227,125, 62,107, 88, 87,161,193,150,133,162, 64,
+128,106,200, 7, 87,108,196,204, 1,173, 4, 50, 63,222, 82, 79,202, 41,224,243,127, 91,124,248,176, 75,100,117, 49,155, 33,160,
+105,216,105,218, 37,178, 44,118, 59, 76, 22, 11, 84, 6, 3,238,142, 29, 11,214,102,195,236,221,187,197, 2, 62,255, 55, 79,202,
+ 9, 0, 60, 30, 79,181,119,239,222,186, 45, 91,182, 60, 6,207,131,153, 30,126,204,215,168, 42,180,109,221,186,245,241, 77,155,
+ 54,213,229,241,120,170,218,224, 20, 10,133,131, 37, 18, 73,190, 80, 40, 28, 92,195,114,146, 0, 22,140, 27, 55,238, 82,163, 70,
+141,142, 58,132,149, 75,212, 52,106,212,232,240,184,113,227,174, 0,152, 83,201,189, 94, 17,103,157,176,176,176,133, 43, 86,172,
+ 16, 39, 39, 39, 35, 51, 51, 19, 54,155, 13, 35, 70,140, 0, 77,211, 48,153, 76,176, 88, 44, 88,178,100,137, 36, 40, 40,232, 35,
+148, 38, 10,246,228,220,121,254,254,254,201, 27, 55,110, 28,146,146,146, 34, 61,122,244, 40,113,253,250,117,201,178,101,203, 6,
+ 6, 5, 5,221, 6, 32,168, 65,125,146, 42,149,234,187, 61,123,246,188,121,253,250,245,240, 93,187,118,113,207,158, 61,171, 90,
+189,122,245,120,149, 74,181, 9, 0, 85,195,107,212, 70, 44, 22,247,158, 49, 99, 6,115,230,204,153,204, 51,103,206,100, 46, 95,
+190, 28,221,186,117,235, 50,111,222,188,216, 26,114,182,245,243,243,123,118,198,140, 25,204,201,147, 39,179,206,157, 59,151,177,
+108,217, 50,242,217,103,159,237,186,112,225,194, 86, 94,114,110, 59,115,230, 76,143,244,244,244, 6, 25, 25, 25,245, 51, 50, 50,
+234,101,100,100,212,203,204,204,140,204,206,206,174,155,147,147, 19,145,151,151, 23,113,252,248,241,174, 0,182,120,194,217, 84,
+ 41,121,115,218,136, 62,197, 31,189,222,159,253,224,181,231,216,153, 35,122,176, 47,116,111,249, 51,197,225, 16,231, 18,211, 16,
+238, 15,124, 63,249,153,200,136, 96,201,245,104,185,180,201, 19,246,108, 62,105,156, 28,167,144,210,104, 52, 56,112,224, 0, 28,
+214,171, 54,238, 34,171,176,176, 16,217,217,217,206,239, 56,158,148, 83, 38,147, 29, 89,183,110, 29, 91, 82, 82, 2,189, 94,143,
+188,188, 60,164,167,167,227,238,221,187, 40, 40, 40,192,173, 91,183, 32, 22,139,143,120, 82, 78,130, 32, 64,211,180, 75, 72,253,
+254,251,239, 24, 55,110, 28, 52, 26,141,235, 51, 14,135,227,122,239,252, 77,117,156, 78,203, 19, 77,211, 56,119,238, 28, 38, 76,
+152,128,229,203,151, 99,203,150, 45,216,191,127, 63, 52, 26,141, 75,108,217,237,246,106, 57,213,106, 53, 24,198,179, 49, 19,203,
+178,208,235,245, 30, 95,119,119, 1,196,225,112, 30, 18, 69,206,205,155,123,233, 17, 57,159, 88,120, 16, 25,190,242, 17,182,243,
+141,195, 84,215,243,113, 21,146,228,240, 70, 14, 29, 51, 37, 40, 35,175, 16,153,185,122, 80,228,223,253, 94,108,159, 49,224, 80,
+ 36,206,255, 90,106,184, 34, 41, 10,122,163, 25, 58,131, 21, 67,198, 76,149,175, 93,254,201, 72,187,181,164,202, 24, 47, 49, 64,
+ 84,180, 84,250, 74,139, 22,117,201,155,130, 36,196,190,112, 10, 52, 3,176, 39, 95, 68, 27,173,130,106,246, 27,255, 21, 99,145,
+117,225,117, 32,185, 74,107, 70, 64,128, 40,176, 85, 43,204, 11, 11, 67,119,155, 13, 60,150,197,115,185,185,248,107,234, 84,152,
+119,238, 4, 9,128, 55,120, 48,122,125,249, 37, 78,132,133, 33,212,100,130,110,250,116,132,252,242, 11,120, 50,153, 8,249,158,
+ 45,126, 32, 8, 2, 61,123,246,196,225,195,135,131,250,245,235,247,235,181,107,215, 6,217,237,246, 19, 53,169, 91,127,127,255,
+139, 28, 14, 39,188,186,227,236,118,123,134, 94,175,247, 58,205, 8,135,195,233,222,161, 67,135,221,187,118,237, 10,180, 90,173,
+181, 50, 10,225,243,249,253, 6, 14, 28,184,110,213,170, 85,178,241,227,199,175,219,191,127,127,177,197, 98,249,197,155, 91, 10,
+192,130, 53,107,214, 76,140,143,143, 15, 24, 63,126, 60,123,247,238, 93,119,235, 85, 72,183,110,221, 26,173, 91,183, 46,244,153,
+103,158,153, 50, 97,194, 4, 30,128,217,213, 89,121,164, 82,233,164,117,235,214, 5,171,213,106, 24, 12, 6, 87, 35,155,145,145,
+ 1,145, 72, 4,146, 36, 65,146, 36,184, 92, 46, 62,251,236,179,160, 73,147, 38, 77,213,104, 52, 83, 61,176,146, 37,172, 92,185,
+ 50,228,249,231,159, 39, 83, 82, 82, 64,146, 36,132, 66, 33, 94,125,245, 85,210,100, 50, 5,206,155, 55,111,131,209,104, 28,238,
+ 77, 29,114,185,220,145, 9, 9, 9, 77,186,116,233,194, 73, 74, 74, 66,167, 78,157,112,254,252,121, 12, 30, 60,152, 91, 84, 84,
+ 84,127,230,204,153,227,204,102,179,183,113, 92, 84, 98,177, 56,230,143, 63,254, 72,143,136,136,112, 53, 44,245,235,215,167,227,
+226,226, 52, 73, 73, 73, 77,207,156, 57, 83,208,185,115,103,111, 18,150,215, 17,139,197,205, 14, 30, 60,152, 61,111,222,188,222,
+107,214,172, 25, 8, 0,237,219,183,223, 59,127,254,252,163, 26,141, 38,250,196,137, 19,154,238,221,187,103,120,200, 23,166, 82,
+169,232,201,147, 39, 75,171, 58,104,253,250,245, 58,148, 38, 92,110, 0,160,202,124,109, 77,235,133,126,180,116,234, 80, 17,104,
+ 43, 88,155, 9,176, 22, 3, 86, 3, 24, 75, 49, 8,158, 8,176,153, 16, 34,208, 96,219,164,166,178,247,127,188,119,147,190, 69,
+196, 37,169,139,126,129, 15, 21, 54, 53, 0, 98, 9,130,184,124,224,192, 1,116,232,208, 1, 7, 14, 28, 64, 92, 92,220,101,119,
+ 49,112,253,250,117,116,239,222, 29, 14,139,150, 71,190, 90,122,189,126,214,156, 57,115, 78,142, 28, 57, 82, 92,166, 49, 32, 73,
+ 4, 4, 4,160,127,255,254, 37, 70,163,113,150,167, 5,165,105, 26, 28, 14, 7, 25, 25, 25, 88,191,126, 61, 22, 45, 90,132,168,
+168, 40,216,108,182,135,196,150,163,221,243,168,241,179,219,237,184,112,225, 2, 54,111,218,132,217, 31,125, 4, 63, 63, 63, 0,
+128,213,106,133, 70,171,133, 80, 40,116,137,177,106,132,211,246, 59,119,238, 76, 13, 15, 15, 47, 51,101,232,124,117,180, 89, 96,
+ 24, 6,118,187, 29, 37, 37, 37, 88,190,124,185,157,101,217,237,213,245, 63, 78, 81, 52,117,234, 84,152,205,127, 27,212, 91, 57,
+124,146,235,213,171,135,214,173, 91,187,246, 73,146,100, 61,229, 92,219, 57, 6, 38,183,163,155,206, 89, 6, 0, 8, 15, 15, 71,
+211,166, 77,161, 82,169, 42,229,124,220, 90,164, 38,240, 34, 50,124,229, 66,235,159,200,148,205,229, 9,123, 53,108,220,132, 72,
+203,214,128,195,225, 64,226, 31,140,206, 47, 79, 3, 69,145,144, 6, 4,131,160, 77,127, 43, 98,146, 2,135,226, 64, 83,100, 66,
+189, 6,141, 73,129, 80,212,203, 88,141,208,146,249,115, 87,206, 24,222, 89, 88, 96,207,128,168,174, 16,180,179, 59, 13,227,131,
+ 12, 42,194,187,253,162, 68,241,123,175,173,132,222,246,172, 39,229,165,236,118, 40, 40, 10, 86,150,197, 95, 83,167, 34, 54, 33,
+ 1,151,157,194, 48, 33, 1,151,227,227, 33,231,114, 33, 32, 73,176, 54,219, 67,115,250,158, 8, 45, 0, 72, 79, 79,199,206,157,
+ 59,229, 67,135, 14,221,125,253,250,245,145, 94,138, 13, 39, 87,240,185,115,231, 20, 13, 26, 52,168,244,152,251,247,239,163, 93,
+187,118, 94, 79, 79,241,249,252,126,207, 62,251,236,143, 59,119,238,244, 79, 76, 76,132, 66,161,120,100,161, 37, 16, 8,186,247,
+233,211,231,199,141, 27, 55,202,242,243,243,145,144,144, 32,123,241,197, 23,183, 92,186,116,233,101,179,217,236,137,216, 44, 35,
+178, 18, 18, 18,116,235,215,175, 95,139,178, 83,132,217,235,215,175,255,238,153,103,158,121, 51, 62, 62, 62, 0,192, 68,135,239,
+ 64,149, 98, 75, 32, 16,244,108,216,176, 97,153, 81,173, 64, 80,106,108,146, 72, 36,240,247,247, 7,143,199,131,217,108, 70,108,
+108, 44,193,231,243,187,122,114,206,126,126,126,125, 94,121,229, 21,242,212,169, 83,200,201,201, 65, 64, 64, 0,164, 82, 41,104,
+154,198,248,241,227,169,229,203,151,247, 52, 26,189,155,225,138,136,136, 24,216,187,119,111,206,141, 27, 55,144,146,146, 2,179,
+217,140,219,183,111, 67, 38,147,225,181,215, 94,227, 45, 93,186,244,197,204,204, 76,111,133, 86, 76,124,124,124,174,187,200,114,
+ 66, 34,145, 16, 77,154, 52,209, 4, 5, 5,181, 5,224,141,208,138,121,235,173,183,242, 22, 47, 94,220,253,240,225,195,174,160,
+151,135, 15, 31,158, 9, 0, 95,125,245,213,201,144,144,144,182, 0, 60, 21, 90, 96, 89,150,249,191,255,251,191, 7,124, 62, 31,
+ 92, 46, 23,124, 62,191,204,198,227,241, 64,146,164,159,243,113,174,142,239,102, 74,206,146,241, 51,151, 45,147, 8, 41,238, 59,
+ 47,183, 68,221, 0, 30, 32,146,131,215,253,125, 16, 1,165, 70, 75, 86,115, 31,248,237,125,124,241,138,134,140,255,161,228,103,
+ 43, 29, 24,114, 79,171, 45,250,151,251,128,103, 0,252, 7,165,201,117, 63, 2,112,238, 9,233,155,174, 0,136,141,139,139,115,
+137,173, 67,135, 14,161, 95,191,126,208,233,116,184,113,227,134,187,200,242, 38,193,242, 21,155,205,118,117,235,214,173,157,135,
+ 14, 29, 74,184, 61, 95, 72, 76, 76,196,173, 91,183, 46,123,202, 71,146, 36, 24,134, 1,151,203,197,178,101,203, 96,181, 90,241,
+195, 15, 63, 96,199,142, 29, 32, 73, 18, 4, 65,128, 32, 8,200,100, 50,124,253,245,215, 94,181,123, 52, 77, 99,195,134, 13,120,
+127,230, 76,151,200,114,204,100, 32, 84,169, 68, 80,112, 48,238,221,187, 87,173,208,210,106,181,159,238,219,183, 15, 85, 57,195,
+239,219,183,207,245,190,156, 51,124,245,253, 28, 69,193,108, 54,227,185,231,254, 78, 21,251,214, 91,111,185,222,107, 52, 26, 80,
+ 20,229,172, 11,194, 83, 78, 19, 11,188, 44,252,251,179,254,239,190, 91,198, 66, 87, 25,231, 63,161, 69,106,203,186, 85,129,216,
+138,117, 88,103, 85, 0,226, 80,234,163,149, 13,252,131, 62, 90, 44,203, 52, 11,175, 19,134,171,119,175,131, 67, 81,224,251, 7,
+195, 95,174, 4, 99,183, 64,159,151,130, 99,187,190, 5, 0,172,217,176, 29, 36, 73,130,195,161, 96,182,208,136,170, 27, 6,134,
+ 97,154, 85,197,221, 28,232,220, 83, 25,220, 33, 34, 50,128,184, 17,152,130, 38,138,160,114, 19, 33, 2, 68,101, 73,137, 78, 82,
+ 81,123,173,190,176,243, 77,224, 76,181, 98,128, 36, 65, 18, 4,196, 60, 30,204, 59,119,150,122,109, 38,148,246, 89,151,227,227,
+ 65,254,252, 51,252, 4, 2, 80, 4, 1,142,195, 4, 93, 19, 20, 22, 22,130, 32, 8,108,222,188, 57,240,181,215, 94,219,114,227,
+198,141,248,146,146,146,157,222,112,232,116,186,184, 46, 93,186, 28,221,176, 97, 67, 72,104,104,232, 67,223,231,228,228, 96,204,
+152, 49,249, 58,157,206,171,160,110, 66,161,112,240,192,129, 3,215,125,255,253,247,178, 59,119,238,192, 96, 48, 32, 36, 36,228,
+ 81,111,133,182, 29, 59,118,220,189,115,231, 78,255,156,156, 28,232,245,122,152,205,102,108,222,188, 57,160,127,255,254, 59,147,
+146,146,250, 1,184, 84, 13,199,199,238, 34,107,194,132, 9,215, 0, 40, 0,172, 44,175, 65, 29,223,181,116, 19, 91,122, 0, 75,
+171, 24,137, 70, 74, 36, 18,228,229,229, 97,204,152, 49, 72, 78,254,219, 0, 26, 22, 22,230, 26,233,221,187,119, 15, 33, 33, 33,
+ 32, 8, 66,225,201, 73,135,132,132, 72, 45, 22, 11,198,141, 27,135,244,244,244, 50,156, 25, 25, 25, 32, 8, 66,236,109, 69, 42,
+149, 74,165,201,100, 66,183,110,221, 80, 82, 82,154,215,119,216,176, 97,224,114,185,200,203,203, 3,151,203, 13,174,193,245, 9,
+142,139,139,171, 52,180,138, 76, 38,179, 6, 6, 6, 54,247,146, 51,232,197, 23, 95,204, 76, 72, 72,120,104, 97,203,249,243,231,
+ 95,146,203,229,135,229,114,121, 19, 47, 57, 25,119, 81,197,227,241,202, 8, 45, 46,151, 11,146, 36, 61,246, 81, 75,206, 51,174,
+224, 16,217,173, 23, 79,126,126, 76, 93,133, 63, 88, 67, 46,120,207,126,138,171,249, 34, 44, 91,126, 16, 0,240,222,171,237,208,
+170,207, 2, 88,190,127, 30, 83, 59, 81,252, 81, 25,230, 25, 0, 62,254,151,219,252,207, 1, 56, 87,193,173, 2,208,250, 9,234,
+143, 92, 98,235,208,161, 67,136,142,142,134, 86,171, 69, 82, 82, 82, 77, 69,150,179,189,123,127,238,220,185,191, 13, 26, 52, 72,
+226, 28,180,138, 68, 34, 76,159, 62,221,100, 48, 24,222,247,234, 38, 98, 24,112, 56, 28,215, 32, 89, 40, 20, 34, 54, 54,214, 37,
+178, 8,130, 64,113,113, 49, 56, 28,142,115, 69, 34,225, 97, 25,161, 10, 13,133,159,159, 31, 26, 71, 69,225,142,163, 29,113,190,
+ 23, 8, 4, 32, 8, 2,118,123,181,134,188, 34,135, 83,251,180,218,238,146,157,162,168, 74,211,113, 88, 24, 24,134,113,138, 76,
+182, 54, 56,131,131,131, 97, 48, 24, 60,229,124, 34, 81,137, 69,203, 41,180,226, 80,234,171,245, 80,120,135, 30, 0,142,225, 49,
+ 46,169, 36,192, 18, 12,203,130, 67,145,142,185, 91, 10, 20, 69, 66,147,159,141, 47, 63,157,232, 16, 89, 59,112,224,100, 18,194,
+ 27, 70,255, 61,143, 75, 16, 0, 91,245,205, 29,226,207, 75,152, 52,168,163, 40,151,200, 70, 64,152, 24, 66, 97, 57,253, 24,200,
+ 3, 81,143,196,228,158,225,226, 11,251, 74, 18,110,234,173,213,118, 20, 66,146, 44,117,126, 39,136, 10,157,123, 72,199,119, 20,
+ 65,128,101, 89,176,140,119,126,199, 78, 33, 47, 18,137, 96,181, 90, 65, 81, 20,190,249,230,155,128, 62,125,250,172,244, 86,104,
+ 1, 72,204,205,205,237, 63,126,252,248, 67,219,183,111, 15, 14, 14, 14, 46, 51,122, 24, 63,126,188, 58, 55, 55,183, 63,188,116,
+186,231,114,185, 43, 87,173, 90, 37, 75, 77, 77, 69,113,113, 49, 68, 34,145,171,241,169,233,253,217,190,125,251, 95,127,249,229,
+151, 64,189, 94, 15,171,213, 10,145, 72, 4,150,101, 65, 81, 20,126,250,233,167,160, 1, 3, 6, 28, 76, 75, 75,123,182,170,178,
+138, 68,162,151, 29,194, 9,241,241,241, 1,241,241,241, 61,128, 74, 35,245,186, 16, 31, 31, 31, 48,109,218,180, 23, 77, 38,211,
+210, 42,206, 57, 93,163,209,132,138, 68, 34,236,218,181, 11, 82,169, 20, 98,177, 24, 97, 97, 97,208,104, 52, 16,139,197, 96, 89,
+ 22, 54,155,205,217, 88, 20,120,114,226,249,249,249, 6,187,221,238,127,232,208, 33, 20, 20,252,253,147,186,117,235, 66,167,211,
+129, 97,152, 98,111, 43, 51, 43, 43, 43,151, 32,136,136,171, 87,175, 34, 53, 53, 21,253,250,245,195,207, 63,255,140,118,237, 74,
+103,135, 45, 22, 75, 77,130,248,209, 20, 69,177, 85,220,183, 4,128,192,218,228,116,116, 94, 94,113, 50, 12,195, 56, 69,150,251,
+171,187,248,170,230, 63,203, 60,206,205,149,210,245,139, 39,245, 30,243,124,116, 48, 76,249, 41, 16,250, 5,131, 8,168,135,101,
+203, 15,226,198,253,210,235,181,108,203, 69,252, 56,175, 63, 32,146,163,169,191, 26,161,126,156, 87,110,229,253,235, 66,203,223,
+125,156,240,164,118, 76,253,250,245,131, 70,163,129, 84, 42,173, 13,255,156, 63, 77, 38,211,237, 61,123,246,180,141,139,139, 3,
+159,207,199,237,219,183,113,233,210,165, 36, 0,127,122, 43,180,184, 92, 46,230,206,157,139,137, 19, 39, 66,169, 84,226,253,247,
+223, 7,135,195,113,109, 4, 65,184, 44, 92,222, 64,161,172,122,225,163,211, 33,190, 58, 99,184,191,191,255, 92,146, 36,135, 82,
+ 30, 84, 28, 77,211, 52,195, 48,219,245,122,125,149,225, 29,156,142,235,158, 92, 11,247, 58,168,166, 79,123,100,206,127, 66,139,
+212, 4,229, 87, 27, 86, 98,209,114,174, 58,124, 40, 21,144,243, 44,143, 57, 76,118,199, 30, 87, 65, 9,146,186,149,145,153,133,
+160, 64,169, 67,100, 57, 54,146, 68,171,232,210,193,236,129,147, 73, 8,111, 16, 13, 14, 69,129, 67, 81,144,138, 4,200,205,201,
+ 6,135, 67,222,170,140, 55,134,194,160, 65, 77, 34,234, 5, 6,113,161, 14,177, 64,165,172,196, 48,208,214, 15,225, 42, 62,250,
+ 6, 9, 35, 99, 40, 12,170,218,250,198,186,132,150,213,110, 7,111,240, 96,215,116,225,229,248,120,196, 38, 36,128, 30, 56, 16,
+ 70,171,181,140,169,184,166, 66, 75, 36, 18,161,168,168, 8, 35, 71,142,212,216,108,182, 55,107, 88,197,151, 10, 10, 10,134,140,
+ 26, 53,170,192, 41, 96,172, 86, 43, 70,141, 26, 85, 80, 80, 80, 48,196, 3, 43,209, 67,176,217,108,111,182,107,215, 78,163, 86,
+171, 93,229,172, 73,131,227,132, 92, 46, 63,176,126,253,122,185,217,108,134,221,110,119,113,138, 68, 34, 80, 20,133,144,144, 16,
+252,248,227,143, 33,114,185,188,202,156, 85, 38,147,105, 79, 66, 66,130, 14, 0, 18, 18, 18,116, 4, 65, 28, 39, 8, 98, 53, 65,
+ 16,171,202,109,171, 9,130, 56,238,126,172,201,100,218, 93, 21,183,197, 98, 57,158,148,148,196,138,197, 98, 80, 20, 5,171,213,
+ 10,161, 80,232, 50,137, 23, 22, 22,194,100, 42,157,230,190,116,233, 18,108, 54,219, 41, 79,206,189,168,168,232,200,134, 13, 27,
+152,186,117,235, 34, 58, 58, 26,177,177,177,232,216,177, 35, 34, 35, 35, 49,127,254,124,218,104, 52,122,253,236,101,101,101, 29,
+216,182,109,155, 45, 34, 34, 2,109,219,182,133, 64, 32, 64,171, 86,173, 16, 22, 22,134, 69,139, 22, 89,244,122,253,161, 26, 92,
+166,180,235,215,175, 83, 85,136, 92, 25, 60, 88,189, 91, 14,233, 23, 46, 92,160, 58,118,236,184,183,252, 23,237,219,183,223, 43,
+149, 74,253,157, 38,118,111, 70,228,238,226, 74, 32, 16,184, 54,231,231, 28, 14,199,147,209, 15,217, 92, 41, 93,255,217,196, 94,
+ 99,158,143, 14,196,222, 35,231,192,179,234, 0, 75, 21, 51,130,180, 13, 4, 79, 2,165, 63, 55,252, 9,232, 3,166, 2,184,134,
+210, 56, 76,239,227,201,130,203,241,189,160,160, 0, 73, 73, 73,184,116,233, 18, 58,118,236,136, 83,167, 78, 1,127, 59,200,123,
+ 13,189, 94,255,254,188,121,243,140,206,149,124, 31,125,244,145,169,168,168,232,125,111,219, 96,150,101,193,229,114,209,180,105,
+ 83, 76,155, 54, 13, 7, 15, 30,196,237,219,183, 97,179,217, 92, 66,200,233,147,233,141, 69,139,199,227, 65,169, 84,194,102,179,
+185,172, 89, 0,112, 39, 57, 25, 28, 14, 7, 12,195,192, 98,177, 84,107,209,242,247,247,159,187,110,221,186, 41,106,181, 90,149,
+159,159,175,112,223,114,115,115, 21,217,217,217,138,204,204, 76, 69,122,122,186,226,193,131, 7,138,148,148, 20,213,146, 37, 75,
+166,248,251,251,207,245,164,156, 20, 69,161, 85,171, 86,120,235,173,183, 92,219,138, 21, 43, 92,219,177, 99,199,188,118, 94,167,
+ 40, 10, 77,231, 44, 67,255,124,214,181, 29, 12, 33, 92,219,141,247, 38, 84,197,249,216,181, 72,141,244,139, 99,181,161,123, 98,
+233, 10,224, 92,117,232,108,203, 92,110, 27,229,157,225, 31, 27,236,150,146,163,247,239, 38,247,106, 26,243, 12,153,163, 54,148,
+ 89,254, 25,219,115, 8, 8,130, 64,157, 6,209,160, 56, 28, 80, 20, 9, 14, 69, 33, 64, 38, 68,210,213,171,140,217,100, 58, 90,
+ 17,103, 15,128,195, 23,241, 87,188,218,183,149, 48,139,159,135, 16,149, 4, 60,110,169,118,100,239, 15, 41,215, 67,112,128, 24,
+ 63,140,205, 12, 18, 29,205, 45, 89, 17,104,180,238, 61, 94,201, 8,144, 97, 24, 72, 5, 2,148,152,205, 48,217,237,232,249,229,
+151,174,233, 66,146, 32,112, 5, 64,203, 47,191,196,153,157, 59, 33,227,243, 1,129,192,227, 85, 33, 21, 9, 45,181, 90,141,209,
+163, 71, 23,100,103,103,191, 86, 19, 31, 45, 39,204,102,243,137,156,156,156,215,134, 12, 25,178,121,215,174, 93,242, 33, 67,134,
+104,114,114,114, 94,243,208,239,233, 33,148,148,148,236, 76, 79, 79, 47, 30, 61,122,244,166, 45, 91,182, 4, 5, 7, 7,187, 70,
+ 34, 53,186, 89, 9, 66,221,187,119,111,129, 39,199, 85,115,200, 60,135,115,251, 68,135,101,171,229,132, 9, 19,206,160,212,255,
+202, 29,115,214,172, 89, 51,204,109,138,113, 53,128, 47,171, 34, 46, 44, 44, 92, 53,109,218,180,215, 79,156, 56, 17, 44, 20, 10,
+ 65, 16, 4,120, 60, 30, 26, 55,110,236, 90, 69,195,229,114,193,178, 44,222,125,247, 93,117, 94, 94,222, 87, 30, 94,155, 9,243,
+230,205,235, 94, 82, 82, 18, 56,122,244,104, 74, 40, 20, 34, 55, 55, 23,203,151, 47,167,191,255,254,123,157,209,104, 28, 83, 3,
+ 33,188,225,147, 79, 62,233,105, 48, 24, 26,140, 31, 63,158,167,215,235, 97, 50,153, 48, 99,198, 12,203,119,223,125,151, 97, 50,
+153,188, 14,248,219,169, 83,167,187, 15, 30, 60,232, 90, 92, 92,172, 21,139,197,229,173,125,132, 68, 34,121, 6,192, 38,111, 56,
+ 99, 99, 99,239,165,165,165,117, 92,176, 96,193,113,155,205,198, 61,127,254,188,203, 25,254,155,111,190, 57, 38, 20, 10,123,195,
+203,228,171, 4, 65, 48, 2,129,160,140, 5,171,252,123, 14,135, 83,109,155,214, 44, 84,188,224,179, 55,186,143,121,174,185, 63,
+246, 28,185,136,121,187,239,223,138, 26, 19,210,180, 81, 96, 62,152,252, 36,188,247,106, 59, 44,219,114, 17, 64,233,212, 33,147,
+119, 3,172,246, 30, 88,191, 8,164,104,212, 89, 79, 64, 31,112, 12,165, 33, 51,158, 52,148, 17, 89, 55,110,220, 64,175, 94,189,
+ 0, 0,167, 78,157, 66,151, 46, 93,112,234,212, 41,116,237,218,213,235, 88, 90, 14,252, 81, 88, 88,248,224,216,177, 99, 45, 34,
+ 34, 34,240,231,159,127,166, 0,248,195,219, 66, 58,133, 22,135,195,193,136, 17, 35,208,167, 79, 31,212,173, 91,183,204,106, 67,
+231,123,111,196,134,221,110, 71, 76, 76, 12,204, 22, 11,120, 60,158,107,106,146,195,225, 32, 68,161,192,221,187,119, 61,178,104,
+145, 36, 57,244,229,151, 95, 38, 19, 19, 19, 49,124,248,112,108,222,188,185,210, 99, 71,141, 26,133,173, 91,183,226,229,151, 95,
+ 38, 63,248,224,131, 42,195, 59, 56,157,208, 61, 57, 39,103, 63, 93, 93,187, 95, 91,156,143, 91,139, 60, 10,220, 66, 59, 84, 56,
+105, 82,193,103, 9,101,132,150, 91,144,176,199, 35,180,236,214,205, 63,255,240,237,180,142, 43,187,134,168, 20,254,208,232, 77,
+ 46,177,117,249,216, 14, 0,192,160, 9, 11,193,161, 74,167, 20,101, 82, 33, 68, 60, 10, 59, 55,126,165,182, 90, 75, 42,188,187,
+138,184,228,196, 15, 58, 55,246,231, 75,108, 40, 12,101, 17, 29,242,119,166, 28,162,193,142,135, 5, 87,155, 64, 4,223,208,226,
+213, 70, 82,217, 87,137,186,137,176, 49, 43, 30,234, 16,117, 58,147,238,234, 85, 81,191,117,235,112,254,181,215, 80,135,166,113,
+ 60, 44, 12,114, 46, 23,254, 2, 1, 72,130,128,105,255,126,156,217,181, 11, 74,129, 0,240,243,131,125,254,124,152,147,146, 96,
+ 43, 42, 50,213, 96,100,134, 97,195,134,169,213,106,245, 16,139,197,114,226, 81,235,217,100, 50,253,146,158,158, 62,177, 83,167,
+ 78, 43,109, 54,219,155, 38,147,233,145, 86, 70, 89, 44,150, 95,114,114,114, 6, 15, 27, 54,108,199,238,221,187,131, 3, 2, 2,
+106,204, 85, 80, 80,208,174,150,110, 39, 6,192,108,135,115,251,255,183,119,245, 65, 81, 93, 87,252,247,222,219, 15, 88, 62,205,
+194,146,240, 17, 37,208, 20,218,105,163, 65, 76,211,194, 8,109,136, 38,109,167,116,172, 17, 71,193,182,160, 41, 67,167,181,244,
+143,142,211,152, 80,181,227,180, 83, 2, 54, 99, 70,173, 24, 99, 90,199,113,162, 77,169, 14, 96,204, 4,153,132,182,124,164, 90,
+ 80, 19,151, 12, 24, 2, 11,187, 32,187,203,178,236, 46,239,237,235, 31,187, 15,215,101, 23,246,193,125,176,144, 61, 51,111,100,
+ 21,127,156,123,207,185,188,223, 61,231,222,115,126,182,103,207,158, 85,109,109,109, 63,173,171,171,123,221, 99, 55,145, 80, 90,
+ 90,186,219,139,100,205,121,235, 16,192,221,225,225,225,131,149,149,149,191,175,174,174,142, 18, 14,190, 95,191,126, 29, 44,203,
+ 66, 46,151,131,227, 56,148,150,150,142,143,140,140,252, 9,254, 43, 58,207,112, 45,147,201,244,248,161, 67,135,234,106,107,107,
+ 11, 24,134,137,228, 56,206, 50, 49, 49,209, 60, 57, 57,249, 99,204,175,142,150, 83,175,215,239,218,191,127,255,174,154,154,154,
+ 31,210, 52,157,192,178,172,193,108, 54,215, 91,173,214, 83,152, 71, 42,169,181,181, 85,191, 99,199,142, 79,245,122,253, 87, 82,
+ 82, 82,140, 81, 81, 81,118,187,221,206,168, 84,170,152,200,200,200, 44, 0,173, 20, 69,221, 20,131,217,217,217,169, 43, 43, 43,
+235,181,217,108,153,199,142, 29,107,137,137,137,185, 74, 81, 20,165, 80, 40, 30, 82,169, 84,223, 6,208, 76, 81,212, 29, 49,152,
+ 52, 77, 59, 61,163, 87,222,231,179,148, 74,101, 64,103,180,210, 52, 17, 63, 41,120, 92,134,119,222,107,199,129,119,238,158,230,
+120,254,194,133,206,123,255,252, 77, 14,224, 56,191, 3,107,183,158,113,165, 11, 1, 56,135,187,224, 56, 95, 12, 42, 34, 30, 45,
+159,203, 97,180, 58, 46, 33, 36,190,100,186,188,131,193, 96, 64,119,119,183, 64,178,178, 0, 32, 55, 55,183, 83, 32, 91, 29, 29,
+ 29, 88,191,126,125, 39, 0,185, 88,127, 53,153, 76,149, 59,119,238,108,112,111,142, 43,231,177,241,155, 38, 90, 2,161, 90,189,
+122,245,244,103,207,199,227,140, 86, 64,194,113, 28, 20, 10, 5,100, 50, 25, 18,147,146,166,127, 22,207,243,208,106,181, 24, 29,
+ 29, 13,136,104, 49, 12,195, 80, 20,133,162,162,192, 46, 36,111,223,190, 29,205,205,205, 96, 2,100,133, 12,195, 32, 53, 53,117,
+206,239, 17,120,105,160,152, 41, 41, 41,243,198,148,154,139,204,151, 96,249,250,218, 23,169,242,183, 32, 22, 75, 6,198,199,141,
+ 47,189,121,242,181,234,210,242, 95, 71,117,245, 12,193, 56,110, 3,195,208,158,191, 60, 33,147, 49,136,137, 12,199,163,143,196,
+226,111,127,121,213,108, 54,141,237,135,159,190,135,171,163, 21, 47, 62,179,225, 75, 97,138, 68, 11, 50,159,216, 6, 38,252, 62,
+ 9,224,117,126,178,131, 57, 77,120,254,174, 37,252,239,119, 45, 47,126,116,207, 62,147,104,217,237,155,126,187,121,115,227,129,
+203,151, 35,158, 58,125, 26, 61,165,165, 72,178, 90, 17,230, 78, 37,210, 20,133, 40,133, 2, 81, 10,133,139,100,213,212,192,202,
+178,168, 45, 41,153,176,217,237,155,197, 44,242,145,145, 17, 20, 22, 22,234, 7, 6, 6,190,139,121,164,246,252,137,197, 98,121,
+ 27,192,219,164,240,108, 54,219,181,254,254,254,231, 11, 11, 11, 47, 55, 52, 52,104,130,164,200,156, 64,182, 28,109,109,109,187,
+ 91, 90, 90,122,240, 96, 99,209,177,150,150,150,158,178,178, 50,170,174,174,238, 20,128,151, 17, 96, 1, 79,139,197,242,218,149,
+ 43, 87,176,113,227,198,151, 15, 31, 62, 28,151,157,157,141,132,132, 4,152,205,102,116,116,116, 96,239,222,189,163, 38,147,233,
+240,216,216, 88,181, 72,157, 29, 54,155,173,216,243, 42, 53,137,121,176,217,108,111, 12, 14, 14,190, 65, 10,176,162,162,226,186,
+ 86,171, 29,209,104, 52,223, 80, 40, 20, 79,192,117, 14, 72, 7,224,148, 88, 66, 36, 72,121,121,249,127,181, 90,173, 33, 57, 57,
+249,105, 55,230, 42,184,218, 24,157,156, 7,230, 64,123,123,123,202,134, 13, 27,104,185, 92,206, 51, 12, 3,185, 92,206,203,100,
+ 50,222,125,174,134, 7,128,250,250,250, 48, 0,179,182,205,233, 25,182, 30, 42,126,245,131,125, 55,117,147, 23,110, 13, 77,252,
+ 10, 0,127,190, 43,162,105,173,134,217,180, 41,163, 31,182, 19,185,160, 98, 92,133, 42,249,241, 65, 80,145, 15,163,223,153,140,
+170,127,220,214,177,160,254, 24,226, 84,190,247,213,112,151,119, 24, 28, 28,244, 36, 89, 66,212, 42, 43, 55, 55,183,211, 77,178,
+132,127,155,207,249,178,119,157, 78,231,130,222, 97, 60,207,227,192,129, 3, 56,126,252, 56,230,170,104,238,190,221, 71,205,133,
+ 39, 68,180, 56,142,131,195,225, 64, 87, 87,215,116,205, 46, 33, 93, 40,148,118, 96, 89,118,214,219,234, 28,199,113,118,187, 29,
+231,206,157, 11,136,108,157, 61,123, 22,147,147,147,224,230, 96,112,158,165, 24,214,173, 91,135,209,209,209,233,203, 62, 89, 89,
+247, 75,229, 57, 28, 14, 81,196, 85,192,204,204,204,132,193, 96,128,112, 94,248,209,146,251,193, 30,214, 98, 89,169,126,239, 55,
+162,181,232,111,204,176,136,152,134,236,111, 21,228,148,236,222, 27, 57,110,227,208,219,219, 7,253,240, 32,104,138, 70, 98,114,
+ 10,214,172, 73,133, 74, 73,227,173, 19,213,150,206, 15,175,126, 48,110,190,247,156, 63,172,239,197, 42, 62,172,249, 81,206,211,
+233,233,209, 20,216, 41,128,155, 2,216, 41,192,233,254, 83,248, 59,231,131, 62,215,221, 61,198,239,251,104,244, 95,151,140, 14,
+159, 61,171,182, 2, 57,171,212,234,198,170,250,250, 8,167,195,129,145,202, 74, 68,176, 44,194,221,187, 18,215, 64,194,192, 30,
+ 60,232, 34, 89,197,197, 19,198,177, 49, 81, 45,120,226,227,227,219, 41,138,138,215,235,245,203,170, 50,188, 70,163,185,196,243,
+188,193, 96, 48,100, 7,145, 94, 9, 0,198, 0, 56,124,108, 36, 52, 16,127,254, 71,144, 84,141, 70,179,143,166,233,111,242, 60,
+ 31, 71,211,244, 61,167,211,217, 58, 60, 60,252, 7, 0,218,208,251,116,201, 68,168, 12,255,216, 28,223, 55, 12,224,151,112, 29,
+ 10,238, 13, 20,124,109,108,108,172, 77, 57,117,241, 7, 95, 11,203,127, 33, 43, 22,105,143, 68, 67,174, 8,199,128,137,197,187,
+ 55, 77, 56,249,190,238, 51,235, 20,247,253, 79,244, 19,255, 11,153, 98, 86, 33,222,130,135,164,168,213,234,127, 55, 54, 54,102,
+167,165,165,209,158, 7,222,133, 90,121, 66,122, 75, 38,115,113,185,107,215,174,177, 69, 69, 69,173, 67, 67, 67, 27,253, 97, 70,
+ 71, 71, 55,221,184,113,227, 89,163,209, 56,131, 80,121, 86,138, 23, 62, 91, 44, 22,148,151,151, 95,241,215,130, 39, 54, 54,182,
+166,186,186,250, 23, 91,182,108,161,133,114, 20,158,143,208, 46, 72,120, 28, 14, 7,206,156, 57,227, 60,114,228,200,159,141, 70,
+163,223,212, 97, 98, 98,226,103, 3, 3, 3, 41, 66,169,133, 64,138,138,166,166,166, 14,246,245,245, 37, 45, 38,230, 50, 38, 92,
+ 15, 68,183,150, 36, 52, 33, 87,169, 42,162,163, 30,122,101,203,206,159,199,165,166,127,153,122, 56, 49, 25, 20,104, 12,233, 62,
+ 71,223,167,159,240, 23,255,122,116,196, 98, 26,253,157,213,106, 57, 58, 27,206, 87,129,244,199, 98, 20,231,149, 28, 50, 32, 16,
+ 32,175,254, 84, 51,118, 28, 0, 28,114,250,118,175,121,106,219,205, 89,210, 62, 2,217,122,233,226,197, 8,101, 70,198,140, 66,
+113, 78,167, 19,182, 91,183, 80, 91, 82, 34,154,100,133, 36, 36, 33, 33, 34,105,152,187, 70,214, 20, 92,245,185,196, 70, 76,168,
+204,132,200,109, 60,240, 2, 13,231,215,105,138, 82,178, 60, 62, 6,143,166, 8,217,196,235,157,131,176,134,166, 63, 32, 9,218,
+166,210, 0, 34,213,106,245, 85,134, 97,214, 8, 17, 25,207,104,189,143,134,210,189, 67, 67, 67,207, 0,152,237,134,112,122,116,
+116,244, 81,142,227,158, 10,164,169, 52,195, 48,255, 49,155,205, 21,152,165,169,180, 20,183, 14,227,226,226,180,125,125,125,233,
+194, 45,106,207,119,165,175,155,229,119,238,220, 65, 94, 94, 94,159, 78,167, 75, 93, 76,204, 96, 21, 63,183, 14,131, 39,162,229,
+ 33, 73,138,176,168, 93, 74, 85,248,119,156, 83,108, 38, 40, 64, 38,151,223,182, 79, 90,223,179, 89,199,223,132,159,116,225, 98,
+202, 86, 32, 39, 76,169,108, 82,196,196,168,124,145,182, 41,179,217,106,179,219, 55,133, 72, 86, 72, 66, 18,146,144,132,100, 25,
+ 73,134, 90,173,110,148,203,229, 97,158,100,210,251,107, 65, 88,150,157,212,235,245,207, 1,248,120,145, 49,191,152, 34,242,144,
+ 90, 65,160,152,238, 39, 47,216, 49, 37, 28, 59, 79, 16, 51,207,141, 89,181, 76,244,204, 11, 86, 76, 97,188, 34,112, 11,196,248,
+ 17,169,249,244,208,147, 39,173,167, 84,152,164,214,145, 15, 61,121, 9,236, 94,181, 76,244,204, 11, 54, 76,111,255, 9, 16, 87,
+ 20,102,128, 62, 37, 86, 79,158,180,158, 82, 97, 46,116, 29,205,162, 39,191, 80, 95,242, 99,251, 42, 44, 67,233,126, 18,124,247,
+147,224,187,214,251,172,219,184,199,223,255, 19,117,144, 80,170,155, 0, 66,217,125, 55, 62, 21,172,152,158,243, 64,178, 85,128,
+ 4,109, 7,222, 39,141,233, 53,159,164,164,202,125,195,164, 25, 1, 20, 28, 21, 51,118, 18,118,247, 26, 43, 17,220,121,144, 44,
+ 81,152,164,252, 94,106, 76, 82,107,201, 27,147,132,223,251,178,187,132, 54, 34,165, 39,145,181, 36,133,207,251,240,159, 5,227,
+122, 99,146, 88, 75,222,152, 36,252,126, 49, 48, 73,172, 37, 95,152, 36,252,222,159,237,151,107,160, 73, 72, 23,186, 75, 60, 80,
+ 1,144,173, 19, 0, 64,207,103,210, 36,140,148,229,147,198, 36,173,179, 20,100, 83, 68, 4,102,201, 49, 9,219,168,202,141, 73,
+114,119,147, 79,202, 70, 82,248,187, 39, 38, 41,124,111, 28, 18,118,242,133,185, 80,125,253,232, 73,124,236, 11,245,251,197,194,
+ 36,108, 35, 34,107,201, 11, 51,159,240,102, 32,223,227,115, 21, 73, 76, 82,107,201,135,158, 11,182,147, 47,204,133,234,235, 71,
+ 79,226, 99, 39,241, 14,145, 10,119, 41, 35, 90, 60,237,215, 39, 78,120, 61,139, 66, 52,150, 44, 37, 39, 18,123, 69, 97,138, 76,
+207, 20, 72, 96,251, 37,213,147, 36,166,183,142, 36,211, 61, 82,234, 73, 18, 83,132,174, 43, 14,115,185,217, 61, 24,231,211, 31,
+222, 66,210, 82,254,162,163, 82,232, 73, 18, 51, 64,236, 21,129,185, 0,219,175, 56,145, 5,139, 34,194,196, 19,222,153,128,112,
+ 4, 70,178,113, 19,214, 51, 95,138, 8,161, 4, 66, 92, 79,247, 78,249, 21, 9,198,190, 89, 87, 78,217, 0, 0, 0, 46, 73, 68,
+ 65, 84, 92,230, 52,180,150, 66,107, 41,232,214,146,151, 79,230, 19,140, 20, 17,141, 60,123, 99,146,248, 25,158, 24,164,124, 84,
+234,177,147, 92, 75, 82,216,126,185,201,255, 1, 22, 74, 86,152, 88,239,214,181, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
0};
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 64da61f8f55..081d604819d 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -693,6 +693,7 @@ void draw_gpencil_2dimage (bContext *C, ImBuf *ibuf)
/* calculate rect */
switch (sa->spacetype) {
case SPACE_IMAGE: /* image */
+ case SPACE_CLIP: /* clip */
{
/* just draw using standard scaling (settings here are currently ignored anyways) */
@@ -766,7 +767,7 @@ void draw_gpencil_view2d (bContext *C, short onlyv2d)
/* special hack for Image Editor */
// FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled
- if (sa->spacetype == SPACE_IMAGE)
+ if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP))
dflag |= GP_DRAWDATA_IEDITHACK;
/* draw it! */
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index 56210864593..81a5f6777e7 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -422,6 +422,7 @@ void paste_gpdata (Scene *scene)
case SPACE_NODE: /* Nodes Editor: either screen-aligned or view-aligned */
case SPACE_IMAGE: /* Image Editor: either screen-aligned or view\image-aligned */
+ case SPACE_CLIP: /* Image Editor: either screen-aligned or view\image-aligned */
if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DSPACE))
stroke_ok= 1;
break;
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 7b79384fbb4..65db5e27ed7 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -69,6 +69,7 @@
#include "ED_gpencil.h"
#include "ED_view3d.h"
+#include "ED_clip.h"
#include "gpencil_intern.h"
@@ -137,6 +138,19 @@ bGPdata **gpencil_data_get_pointers (bContext *C, PointerRNA *ptr)
}
break;
+ case SPACE_CLIP: /* Nodes Editor */
+ {
+ SpaceClip *sc= (SpaceClip *)CTX_wm_space_data(C);
+ MovieClip *clip= ED_space_clip(sc);
+
+ if(clip) {
+ /* for now, as long as there's a clip, default to using that in Clip Editor */
+ if (ptr) RNA_id_pointer_create(&clip->id, ptr);
+ return &clip->gpd;
+ }
+ }
+ break;
+
default: /* unsupported space */
return NULL;
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 12f03f7341c..bd02df2ddba 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -103,6 +103,11 @@ typedef struct tGPsdata {
short radius; /* radius of influence for eraser */
short flags; /* flags that can get set during runtime */
+
+ float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
+ to region space */
+
+ float custom_color[3]; /* custom color for */
} tGPsdata;
/* values for tGPsdata->status */
@@ -277,6 +282,7 @@ static void gp_stroke_convertcoords (tGPsdata *p, const int mval[2], float out[3
/* 2d - on 'canvas' (assume that p->v2d is set) */
else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) {
UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]);
+ mul_v3_m4v3(out, p->imat, out);
}
#if 0
@@ -997,6 +1003,8 @@ static int gp_session_initdata (bContext *C, tGPsdata *p)
/* pass on current scene and window */
p->scene= CTX_data_scene(C);
p->win= CTX_wm_window(C);
+
+ unit_m4(p->imat);
switch (curarea->spacetype) {
/* supported views first */
@@ -1097,6 +1105,33 @@ static int gp_session_initdata (bContext *C, tGPsdata *p)
#endif
}
break;
+ case SPACE_CLIP:
+ {
+ SpaceClip *sc= curarea->spacedata.first;
+
+ /* set the current area */
+ p->sa= curarea;
+ p->ar= ar;
+ p->v2d= &ar->v2d;
+ //p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+
+ invert_m4_m4(p->imat, sc->unistabmat);
+
+ /* custom color for new layer */
+ p->custom_color[0]= 1.0f;
+ 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;
/* unsupported views */
default:
@@ -1182,8 +1217,12 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode)
{
/* get active layer (or add a new one if non-existent) */
p->gpl= gpencil_layer_getactive(p->gpd);
- if (p->gpl == NULL)
+ if (p->gpl == NULL) {
p->gpl= gpencil_layer_addnew(p->gpd);
+
+ if(p->custom_color[3])
+ copy_v3_v3(p->gpl->color, p->custom_color);
+ }
if (p->gpl->flag & GP_LAYER_LOCKED) {
p->status= GP_STATUS_ERROR;
if (G.f & G_DEBUG)
@@ -1299,6 +1338,12 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode)
p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE;
}
break;
+
+ case SPACE_CLIP:
+ {
+ p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE;
+ }
+ break;
}
}
}
@@ -1336,9 +1381,12 @@ static void gp_paint_strokeend (tGPsdata *p)
/* finish off stroke painting operation */
static void gp_paint_cleanup (tGPsdata *p)
{
- /* finish off a stroke */
- if(p->gpd)
+ /* p->gpd==NULL happens when stroke failed to initialize,
+ for example. when GP is hidden in current space (sergey) */
+ if (p->gpd) {
+ /* finish off a stroke */
gp_paint_strokeend(p);
+ }
/* "unlock" frame */
if (p->gpf)
@@ -1724,8 +1772,6 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
if (gp_session_initdata(C, p))
gp_paint_initstroke(p, p->paintmode);
- p= op->customdata;
-
if(p->status != GP_STATUS_ERROR)
p->status= GP_STATUS_PAINTING;
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
new file mode 100644
index 00000000000..7d36159f47e
--- /dev/null
+++ b/source/blender/editors/include/ED_clip.h
@@ -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.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ED_clip.h
+ * \ingroup editors
+ */
+
+#ifndef ED_MOVIECLIP_H
+#define ED_MOVIECLIP_H
+
+struct ARegion;
+struct bContext;
+struct ImBuf;
+struct Main;
+struct MovieClip;
+struct SpaceClip;
+struct wmEvent;
+
+/* clip_editor.c */
+int ED_space_clip_poll(struct bContext *C);
+
+void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip);
+struct MovieClip *ED_space_clip(struct SpaceClip *sc);
+void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height);
+void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy);
+void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy);
+
+struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc);
+struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
+
+void ED_clip_update_frame(const struct Main *mainp, int cfra);
+int ED_clip_view_selection(struct SpaceClip *sc, struct ARegion *ar, int fit);
+
+void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]);
+void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr);
+void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]);
+
+/* clip_ops.c */
+void ED_operatormacros_clip(void);
+
+#endif /* ED_TEXT_H */
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index 8e445ab1cee..b5a1ca193db 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -54,6 +54,7 @@ void ED_spacetype_sequencer(void);
void ED_spacetype_logic(void);
void ED_spacetype_console(void);
void ED_spacetype_userpref(void);
+void ED_spacetype_clip(void);
/* calls for instancing and freeing spacetype static data
called in WM_init_exit */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 3a6cbc556d1..37f647abfd9 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -94,6 +94,7 @@ enum {
#define CTX_AUTOCONFIRM 32
#define CTX_BMESH 64
#define CTX_NDOF 128
+#define CTX_MOVIECLIP 256
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index aa2ee6adc72..51e0e25f545 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -294,4 +294,6 @@ void ED_view3d_camera_lock_init(struct View3D *v3d, struct RegionView3D *rv3d);
/* copy the view to the camera, return TRUE if */
int ED_view3d_camera_lock_sync(struct View3D *v3d, struct RegionView3D *rv3d);
+struct BGpic *ED_view3D_background_image_add(struct View3D *v3d);
+
#endif /* ED_VIEW3D_H */
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 8cb37ab337d..c7afe2fb28f 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -173,6 +173,7 @@ DEF_ICON(NODETREE)
DEF_ICON(LOGIC)
DEF_ICON(CONSOLE)
DEF_ICON(PREFERENCES)
+DEF_ICON(CLIP)
DEF_ICON(ASSET_MANAGER)
#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK057)
@@ -180,7 +181,6 @@ DEF_ICON(ASSET_MANAGER)
DEF_ICON(BLANK059)
DEF_ICON(BLANK060)
DEF_ICON(BLANK061)
- DEF_ICON(BLANK061b)
#endif
/* MODES */
@@ -642,6 +642,8 @@ DEF_ICON(DRIVER)
/* ANIMATION */
DEF_ICON(SOLO_OFF)
DEF_ICON(SOLO_ON)
+DEF_ICON(FRAME_PREV)
+DEF_ICON(FRAME_NEXT)
#ifndef DEF_ICON_BLANK_SKIP
/* available */
DEF_ICON(BLANK186)
@@ -666,8 +668,6 @@ DEF_ICON(SOLO_ON)
DEF_ICON(BLANK205)
DEF_ICON(BLANK206)
DEF_ICON(BLANK207)
- DEF_ICON(BLANK208)
- DEF_ICON(BLANK208b)
#endif
/* EDITING */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 7a556eddd2b..02b8cc9e2c6 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -66,6 +66,9 @@ struct uiWidgetColors;
struct Tex;
struct MTex;
struct ImBuf;
+struct bNodeTree;
+struct bNode;
+struct bNodeSocket;
typedef struct uiBut uiBut;
typedef struct uiBlock uiBlock;
@@ -74,6 +77,10 @@ typedef struct uiLayout uiLayout;
/* Defines */
+/* names */
+#define UI_MAX_DRAW_STR 400
+#define UI_MAX_NAME_STR 128
+
/* uiBlock->dt */
#define UI_EMBOSS 0 /* use widget style for drawing */
#define UI_EMBOSSN 1 /* Nothing, only icon and/or text */
@@ -128,11 +135,11 @@ typedef struct uiLayout uiLayout;
#define UI_ICON_LEFT 128
#define UI_ICON_SUBMENU 256
#define UI_ICON_PREVIEW 512
- /* control for button type block */
-#define UI_MAKE_TOP 1024
-#define UI_MAKE_DOWN 2048
-#define UI_MAKE_LEFT 4096
-#define UI_MAKE_RIGHT 8192
+
+#define UI_TEXT_RIGHT 1024
+#define UI_BUT_NODE_LINK 2048
+#define UI_BUT_NODE_ACTIVE 4096
+#define UI_FLAG_UNUSED 8192
/* button align flag, for drawing groups together */
#define UI_BUT_ALIGN (UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT|UI_BUT_ALIGN_RIGHT|UI_BUT_ALIGN_DOWN)
@@ -222,18 +229,19 @@ typedef struct uiLayout uiLayout;
#define TOGBUT (37<<9)
#define OPTION (38<<9)
#define OPTIONN (39<<9)
+#define TRACKPREVIEW (40<<9)
/* buttons with value >= SEARCH_MENU don't get undo pushes */
-#define SEARCH_MENU (40<<9)
-#define BUT_EXTRA (41<<9)
-#define HSVCIRCLE (42<<9)
-#define LISTBOX (43<<9)
-#define LISTROW (44<<9)
-#define HOTKEYEVT (45<<9)
-#define BUT_IMAGE (46<<9)
-#define HISTOGRAM (47<<9)
-#define WAVEFORM (48<<9)
-#define VECTORSCOPE (49<<9)
-#define PROGRESSBAR (50<<9)
+#define SEARCH_MENU (41<<9)
+#define BUT_EXTRA (42<<9)
+#define HSVCIRCLE (43<<9)
+#define LISTBOX (44<<9)
+#define LISTROW (45<<9)
+#define HOTKEYEVT (46<<9)
+#define BUT_IMAGE (47<<9)
+#define HISTOGRAM (48<<9)
+#define WAVEFORM (49<<9)
+#define VECTORSCOPE (50<<9)
+#define PROGRESSBAR (51<<9)
#define BUTTYPE (63<<9)
@@ -748,6 +756,12 @@ void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type);
+void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
+void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
+
+void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact);
+void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname);
+void uiTemplateMarker(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int cmpact);
/* items */
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 9c46a5d28de..4b1371c532c 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -247,7 +247,18 @@ enum {
TH_DRAWEXTRA_FACEAREA,
TH_DRAWEXTRA_FACEANG,
- TH_NODE_CURVING
+ TH_NODE_CURVING,
+
+ TH_MARKER_OUTLINE,
+ TH_MARKER,
+ TH_ACT_MARKER,
+ TH_SEL_MARKER,
+ TH_BUNDLE_SOLID,
+ TH_DIS_MARKER,
+ TH_PATH_BEFORE,
+ TH_PATH_AFTER,
+ TH_CAMERA_PATH,
+ TH_LOCK_MARKER
};
/* XXX WARNING: previous is saved in file, so do not change order! */
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 3d08e761090..4bc0963aad4 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -34,6 +34,7 @@
#include "DNA_color_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
+#include "DNA_movieclip_types.h"
#include "BLI_math.h"
#include "BLI_rect.h"
@@ -1501,6 +1502,114 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect
fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
}
+static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy)
+{
+ ImBuf *scaleibuf;
+ int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy;
+ scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect);
+
+ for(y= 0; y<scaleibuf->y; y++) {
+ for (x= 0; x<scaleibuf->x; x++) {
+ int pixel= scaleibuf->x*y + x;
+ int orig_pixel= ibuf->x*(int)(((float)y)/zoomy) + (int)(((float)x)/zoomx);
+ 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];
+ }
+ }
+
+ return scaleibuf;
+}
+
+void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
+{
+ rctf rect;
+ int ok= 0;
+ GLint scissor[4];
+ MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
+
+ rect.xmin = (float)recti->xmin+1;
+ rect.xmax = (float)recti->xmax-1;
+ rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2;
+ rect.ymax = (float)recti->ymax-1;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ /* need scissor test, preview image can draw outside of boundary */
+ glGetIntegerv(GL_VIEWPORT, scissor);
+ glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
+
+ if(scopes->track_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);
+
+ ok= 1;
+ }
+ else if(scopes->track_preview) {
+ int a, off_x, off_y;
+ float zoomx, zoomy;
+ ImBuf *drawibuf;
+
+ glPushMatrix();
+
+ /* 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.f);
+ zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.f);
+
+ off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5)*zoomx;
+ off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5)*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);
+
+ 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();
+ }
+
+ glDisable(GL_LINE_STIPPLE);
+ glPopMatrix();
+
+ ok= 1;
+ }
+
+ 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);
+ }
+
+ /* outline, scale gripper */
+ draw_scope_end(&rect, scissor);
+
+ glDisable(GL_BLEND);
+}
/* ****************************************************** */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index c34c10bf1a7..c871c87983c 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -56,6 +56,7 @@
#include "BKE_idprop.h"
#include "BKE_report.h"
#include "BKE_texture.h"
+#include "BKE_tracking.h"
#include "BKE_unit.h"
#include "ED_screen.h"
@@ -259,7 +260,7 @@ static uiBut *ui_but_last(uiBlock *block)
static int ui_is_a_warp_but(uiBut *but)
{
if(U.uiflag & USER_CONTINUOUS_MOUSE)
- if(ELEM3(but->type, NUM, NUMABS, HSVCIRCLE))
+ if(ELEM4(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW))
return TRUE;
return FALSE;
@@ -922,6 +923,13 @@ static void ui_apply_but_WAVEFORM(bContext *C, uiBut *but, uiHandleButtonData *d
data->applied= 1;
}
+static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+ ui_apply_but_func(C, but);
+ data->retval= but->retval;
+ data->applied= 1;
+}
+
static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, int interactive)
{
@@ -1051,6 +1059,9 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
case WAVEFORM:
ui_apply_but_WAVEFORM(C, but, data);
break;
+ case TRACKPREVIEW:
+ ui_apply_but_TRACKPREVIEW(C, but, data);
+ break;
default:
break;
}
@@ -4254,6 +4265,88 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
return WM_UI_HANDLER_CONTINUE;
}
+static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, int shift)
+{
+ MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
+ int changed= 1;
+ float dx, dy;
+
+ dx = mx - data->draglastx;
+ dy = my - data->draglasty;
+
+ if(shift) {
+ dx /= 5.0f;
+ dy /= 5.0f;
+ }
+
+ if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
+ /* resize preview widget itself */
+ scopes->track_preview_height = (but->y2 - but->y1) + (data->dragstarty - my);
+ } else {
+ if(scopes->marker) {
+ if(scopes->marker->framenr!=scopes->framenr)
+ scopes->marker= BKE_tracking_ensure_marker(scopes->track, scopes->framenr);
+
+ scopes->marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED);
+ scopes->marker->pos[0]+= -dx*scopes->slide_scale[0] / (but->block->maxx-but->block->minx);
+ scopes->marker->pos[1]+= -dy*scopes->slide_scale[1] / (but->block->maxy-but->block->miny);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL);
+ }
+
+ scopes->ok= 0;
+ }
+
+ data->draglastx= mx;
+ data->draglasty= my;
+
+ return changed;
+}
+
+static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+ int mx, my;
+
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if(data->state == BUTTON_STATE_HIGHLIGHT) {
+ if(event->type==LEFTMOUSE && event->val==KM_PRESS) {
+ data->dragstartx= mx;
+ data->dragstarty= my;
+ data->draglastx= mx;
+ data->draglasty= my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if(ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift))
+ ui_numedit_apply(C, block, but, data);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if(data->state == BUTTON_STATE_NUM_EDITING) {
+ if(event->type == ESCKEY) {
+ data->cancel= 1;
+ data->escapecancel= 1;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if(event->type == MOUSEMOVE) {
+ if(mx!=data->draglastx || my!=data->draglasty) {
+ if(ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift))
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
{
uiBut *but = (uiBut *)arg1;
@@ -4791,6 +4884,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case INLINK:
retval= ui_do_but_LINK(C, but, data, event);
break;
+ case TRACKPREVIEW:
+ retval= ui_do_but_TRACKPREVIEW(C, block, but, data, event);
+ break;
}
return retval;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9c5fafaf167..aa4158ad4b7 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -79,6 +79,7 @@ typedef enum {
UI_WTYPE_MENU_RADIO,
UI_WTYPE_MENU_ICON_RADIO,
UI_WTYPE_MENU_POINTER_LINK,
+ UI_WTYPE_MENU_NODE_LINK,
UI_WTYPE_PULLDOWN,
UI_WTYPE_MENU_ITEM,
@@ -96,11 +97,6 @@ typedef enum {
} uiWidgetTypeEnum;
-
-
-#define UI_MAX_DRAW_STR 400
-#define UI_MAX_NAME_STR 128
-
/* panel limits */
#define UI_PANEL_MINX 100
#define UI_PANEL_MINY 70
@@ -454,6 +450,7 @@ void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
+void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
/* interface_handlers.c */
extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index edbd5c5684e..34b62155314 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1533,15 +1533,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
if(ELEM(but->type, BLOCK, PULLDOWN))
block->xofs = -2; /* for proper alignment */
- /* only used for automatic toolbox, so can set the shift flag */
- if(but->flag & UI_MAKE_TOP) {
- block->direction= UI_TOP|UI_SHIFT_FLIPPED;
- uiBlockFlipOrder(block);
- }
- if(but->flag & UI_MAKE_DOWN) block->direction= UI_DOWN|UI_SHIFT_FLIPPED;
- if(but->flag & UI_MAKE_LEFT) block->direction |= UI_LEFT;
- if(but->flag & UI_MAKE_RIGHT) block->direction |= UI_RIGHT;
-
ui_block_position(window, butregion, but, block);
}
else {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 19d22a432dc..7c745c3cfef 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2455,6 +2455,7 @@ void uiTemplateOperatorSearch(uiLayout *layout)
#define B_STOPANIM 3
#define B_STOPCOMPO 4
#define B_STOPSEQ 5
+#define B_STOPCLIP 6
static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
{
@@ -2474,6 +2475,9 @@ static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
case B_STOPSEQ:
WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
break;
+ case B_STOPCLIP:
+ WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
+ break;
}
}
@@ -2499,6 +2503,10 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
if(WM_jobs_test(wm, sa))
owner = sa;
handle_event = B_STOPSEQ;
+ } else if(sa->spacetype==SPACE_CLIP) {
+ if(WM_jobs_test(wm, sa))
+ owner = sa;
+ handle_event= B_STOPCLIP;
} else {
Scene *scene;
/* another scene can be rendering too, for example via compositor */
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 878d1bc36a4..aa407bbf6d4 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1181,6 +1181,12 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
widget_draw_icon(but, ICON_DOT, dualset?1.0f:0.25f, rect);
}
+ else if(but->type==MENU && (but->flag & UI_BUT_NODE_LINK)) {
+ int tmp = rect->xmin;
+ rect->xmin = rect->xmax - (rect->ymax - rect->ymin) - 1;
+ widget_draw_icon(but, ICON_LAYER_USED, 1.0f, rect);
+ rect->xmin = tmp;
+ }
/* If there's an icon too (made with uiDefIconTextBut) then draw the icon
and offset the text label to accommodate it */
@@ -1543,6 +1549,10 @@ static void widget_state(uiWidgetType *wt, int state)
char red[4]= {255, 0, 0};
widget_state_blend(wt->wcol.inner, red, 0.4f);
}
+ if(state & UI_BUT_NODE_ACTIVE) {
+ char blue[4]= {86, 128, 194};
+ widget_state_blend(wt->wcol.inner, blue, 0.3f);
+ }
}
/* sliders use special hack which sets 'item' as inner when drawing filling */
@@ -2530,6 +2540,29 @@ static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat
widgetbase_draw(&wtb, wcol);
}
+static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
+{
+ /* silly node link button hacks */
+ uiWidgetBase wtb;
+ uiWidgetColors wcol_backup= *wcol;
+
+ widget_init(&wtb);
+
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, 4.0f);
+
+ wcol->inner[0] += 15;
+ wcol->inner[1] += 15;
+ wcol->inner[2] += 15;
+ wcol->outline[0] += 15;
+ wcol->outline[1] += 15;
+ wcol->outline[2] += 15;
+
+ /* decoration */
+ widgetbase_draw(&wtb, wcol);
+ *wcol= wcol_backup;
+}
+
static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
{
if(state & UI_ACTIVE) {
@@ -2804,6 +2837,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
wt.wcol_theme= &btheme->tui.wcol_menu;
wt.draw= widget_menubut;
break;
+
+ case UI_WTYPE_MENU_NODE_LINK:
+ wt.wcol_theme= &btheme->tui.wcol_menu;
+ wt.draw= widget_menunodebut;
+ break;
case UI_WTYPE_PULLDOWN:
wt.wcol_theme= &btheme->tui.wcol_pulldown;
@@ -2996,7 +3034,9 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case MENU:
case BLOCK:
case ICONTEXTROW:
- if(!but->str[0] && but->icon)
+ if(but->flag & UI_BUT_NODE_LINK)
+ wt= widget_type(UI_WTYPE_MENU_NODE_LINK);
+ else if(!but->str[0] && but->icon)
wt= widget_type(UI_WTYPE_MENU_ICON_RADIO);
else
wt= widget_type(UI_WTYPE_MENU_RADIO);
@@ -3078,6 +3118,10 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
wt= widget_type(UI_WTYPE_SCROLL);
break;
+ case TRACKPREVIEW:
+ ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect);
+ break;
+
default:
wt= widget_type(UI_WTYPE_REGULAR);
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 921a1879bb7..5f392daeec6 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -153,6 +153,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case SPACE_LOGIC:
ts= &btheme->tlogic;
break;
+ case SPACE_CLIP:
+ ts= &btheme->tclip;
+ break;
default:
ts= &btheme->tv3d;
break;
@@ -409,6 +412,27 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_PREVIEW_BACK:
cp= ts->preview_back;
break;
+
+ case TH_MARKER_OUTLINE:
+ cp= ts->marker_outline; break;
+ case TH_MARKER:
+ cp= ts->marker; break;
+ case TH_ACT_MARKER:
+ cp= ts->act_marker; break;
+ case TH_SEL_MARKER:
+ cp= ts->sel_marker; break;
+ case TH_BUNDLE_SOLID:
+ cp= ts->bundle_solid; break;
+ case TH_DIS_MARKER:
+ cp= ts->dis_marker; break;
+ case TH_PATH_BEFORE:
+ cp= ts->path_before; break;
+ case TH_PATH_AFTER:
+ cp= ts->path_after; break;
+ case TH_CAMERA_PATH:
+ cp= ts->camera_path; break;
+ case TH_LOCK_MARKER:
+ cp= ts->lock_marker; break;
}
}
}
@@ -533,6 +557,7 @@ static void ui_theme_init_new(bTheme *btheme)
ui_theme_init_new_do(&btheme->tlogic);
ui_theme_init_new_do(&btheme->tuserpref);
ui_theme_init_new_do(&btheme->tconsole);
+ ui_theme_init_new_do(&btheme->tclip);
}
@@ -639,7 +664,9 @@ void ui_theme_init_default(void)
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw
-
+
+ SETCOL(btheme->tv3d.bundle_solid, 200, 200, 200, 255);
+ SETCOL(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255);
/* space buttons */
/* to have something initialized */
@@ -777,6 +804,23 @@ void ui_theme_init_default(void)
/* space logic */
btheme->tlogic= btheme->tv3d;
SETCOL(btheme->tlogic.back, 100, 100, 100, 255);
+
+ /* space clip */
+ btheme->tclip= btheme->tv3d;
+
+ SETCOL(btheme->tclip.marker_outline, 0x00, 0x00, 0x00, 255);
+ SETCOL(btheme->tclip.marker, 0x7f, 0x7f, 0x00, 255);
+ SETCOL(btheme->tclip.act_marker, 0xff, 0xff, 0xff, 255);
+ SETCOL(btheme->tclip.sel_marker, 0xff, 0xff, 0x00, 255);
+ SETCOL(btheme->tclip.dis_marker, 0x7f, 0x00, 0x00, 255);
+ SETCOL(btheme->tclip.lock_marker, 0x7f, 0x7f, 0x7f, 255);
+ SETCOL(btheme->tclip.path_before, 0xff, 0x00, 0x00, 255);
+ SETCOL(btheme->tclip.path_after, 0x00, 0x00, 0xff, 255);
+ SETCOL(btheme->tclip.grid, 0x5e, 0x5e, 0x5e, 255);
+ SETCOL(btheme->tclip.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tclip.handle_vertex, 0x00, 0x00, 0x00, 0xff);
+ SETCOL(btheme->tclip.handle_vertex_select, 0xff, 0xff, 0, 0xff);
+ btheme->tclip.handle_vertex_size= 4;
}
@@ -1590,6 +1634,35 @@ void init_userdef_do_versions(void)
}
}
+ {
+ bTheme *btheme;
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ if(btheme->tv3d.bundle_solid[3] == 0)
+ SETCOL(btheme->tv3d.bundle_solid, 200, 200, 200, 255);
+
+ if(btheme->tv3d.camera_path[3] == 0)
+ SETCOL(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255);
+
+ if((btheme->tclip.back[3]) == 0) {
+ btheme->tclip= btheme->tv3d;
+
+ SETCOL(btheme->tclip.marker_outline, 0x00, 0x00, 0x00, 255);
+ SETCOL(btheme->tclip.marker, 0x7f, 0x7f, 0x00, 255);
+ SETCOL(btheme->tclip.act_marker, 0xff, 0xff, 0xff, 255);
+ SETCOL(btheme->tclip.sel_marker, 0xff, 0xff, 0x00, 255);
+ SETCOL(btheme->tclip.dis_marker, 0x7f, 0x00, 0x00, 255);
+ SETCOL(btheme->tclip.lock_marker, 0x7f, 0x7f, 0x7f, 255);
+ SETCOL(btheme->tclip.path_before, 0xff, 0x00, 0x00, 255);
+ SETCOL(btheme->tclip.path_after, 0x00, 0x00, 0xff, 255);
+ SETCOL(btheme->tclip.grid, 0x5e, 0x5e, 0x5e, 255);
+ SETCOL(btheme->tclip.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tclip.handle_vertex, 0x00, 0x00, 0x00, 0xff);
+ SETCOL(btheme->tclip.handle_vertex_select, 0xff, 0xff, 0, 0xff);
+ btheme->tclip.handle_vertex_size= 4;
+ }
+ }
+ }
+
/* GL Texture Garbage Collection (variable abused above!) */
if (U.textimeout == 0) {
U.texcollectrate = 60;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 50b798c5bea..b36416151a9 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -55,6 +55,7 @@
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
+#include "BKE_tracking.h"
#include "BIK_api.h"
#ifdef WITH_PYTHON
@@ -402,6 +403,23 @@ static void test_constraints (Object *owner, bPoseChannel *pchan)
data->flag &= ~CONSTRAINT_SPLINEIK_BOUND;
}
}
+ else if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
+ bFollowTrackConstraint *data = curcon->data;
+
+ if((data->flag&CAMERASOLVER_ACTIVECLIP)==0) {
+ if(data->clip != NULL && data->track[0]) {
+ if (!BKE_tracking_named_track(&data->clip->tracking, data->track))
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ }
+ else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) {
+ bCameraSolverConstraint *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) {
@@ -1368,7 +1386,9 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
BPY_pyconstraint_update(ob, con);
}
#endif
+ break;
}
+
default:
break;
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 9d6d663df5c..e6ae8698b14 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1366,6 +1366,7 @@ static const char *editortype_pup(void)
"|UV/Image Editor %x6"
"|Video Sequence Editor %x8"
+ "|Movie Clip Editor %x20"
"|Text Editor %x9"
"|Node Editor %x16"
"|Logic Editor %x17"
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 72fb0a019b6..a76be0c3c42 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -58,6 +58,7 @@
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "ED_fileselect.h"
+#include "ED_clip.h"
#include "UI_interface.h"
@@ -1809,6 +1810,8 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, bScreen *screen, int UNUS
* call before scene_update_for_newframe so modifiers with textuers dont lag 1 frame */
ED_image_update_frame(bmain, scene->r.cfra);
+ ED_clip_update_frame(bmain, scene->r.cfra);
+
/* this function applies the changes too */
/* XXX future: do all windows */
scene_update_for_newframe(bmain, scene, BKE_screen_visible_layers(screen, scene)); /* BKE_scene.h */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index efafdff83fa..ddf766330d4 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2781,10 +2781,23 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws)
if(redraws & TIME_ALL_IMAGE_WIN)
return 1;
break;
+ case SPACE_CLIP:
+ if(redraws & TIME_CLIPS)
+ return 1;
+ break;
}
}
else if(regiontype==RGN_TYPE_UI) {
+ if(spacetype==SPACE_CLIP) {
+ /* Track Preview button is on Properties Editor in SpaceClip,
+ and it's very common case when users want it be refreshing
+ during playback, so asking people to enable special option
+ for this is a bit ticky, so add exception here for refreshing
+ Properties Editor for SpaceClip always */
+ return 1;
+ }
+
if(redraws & TIME_ALL_BUTS_WIN)
return 1;
}
@@ -2798,6 +2811,8 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws)
if(redraws & (TIME_SEQ|TIME_ALL_ANIM_WIN))
return 1;
break;
+ case SPACE_CLIP:
+ return 1;
}
}
return 0;
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index d8f2db02754..9fff70fd5ab 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -63,6 +63,7 @@
#include "ED_uvedit.h"
#include "ED_mball.h"
#include "ED_logic.h"
+#include "ED_clip.h"
/* only call once on startup, storage is global in BKE kernel listbase */
void ED_spacetypes_init(void)
@@ -91,6 +92,7 @@ void ED_spacetypes_init(void)
ED_spacetype_logic();
ED_spacetype_console();
ED_spacetype_userpref();
+ ED_spacetype_clip();
// ...
/* register operator types for screen and all spaces */
@@ -131,6 +133,7 @@ void ED_spacetypes_init(void)
ED_operatormacros_file();
ED_operatormacros_graph();
ED_operatormacros_action();
+ ED_operatormacros_clip();
/* register dropboxes (can use macros) */
spacetypes = BKE_spacetypes_list();
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 39fae43a877..05fdcd50067 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -100,7 +100,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
{
FileBrowseOp *fbo= op->customdata;
ID *id;
- char *base, *str, path[FILE_MAX];
+ 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)
@@ -113,10 +113,9 @@ static int file_browse_exec(bContext *C, wmOperator *op)
char name[FILE_MAX];
id = fbo->ptr.id.data;
- base = (id && id->lib)? id->lib->filepath: G.main->name;
BLI_strncpy(path, str, FILE_MAX);
- BLI_path_abs(path, base);
+ BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name);
if(BLI_is_dir(path)) {
str = MEM_reallocN(str, strlen(str)+2);
diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt
new file mode 100644
index 00000000000..4f9819e8e77
--- /dev/null
+++ b/source/blender/editors/space_clip/CMakeLists.txt
@@ -0,0 +1,56 @@
+# ***** 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.
+#
+# Contributor(s): Blender Foundation,
+# Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ ../include
+ ../../blenkernel
+ ../../blenloader
+ ../../blenfont
+ ../../blenlib
+ ../../imbuf
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ${GLEW_INCLUDE_PATH}
+)
+
+set(INC_SYS
+)
+
+set(SRC
+ space_clip.c
+ clip_draw.c
+ clip_toolbar.c
+ clip_ops.c
+ clip_graph_ops.c
+ clip_graph_draw.c
+ clip_editor.c
+ clip_buttons.c
+ clip_utils.c
+ tracking_ops.c
+
+ clip_intern.h
+)
+
+blender_add_lib(bf_editor_space_clip "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript
new file mode 100644
index 00000000000..70331b0ec4a
--- /dev/null
+++ b/source/blender/editors/space_clip/SConscript
@@ -0,0 +1,9 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('*.c')
+defs = []
+incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna'
+incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
+
+env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] )
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
new file mode 100644
index 00000000000..149aa9106b0
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -0,0 +1,436 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_buttons.c
+ * \ingroup spclip
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_screen.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "ED_clip.h"
+#include "ED_gpencil.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "clip_intern.h" // own include
+
+/* Panels */
+
+void ED_clip_buttons_register(ARegionType *art)
+{
+ PanelType *pt;
+
+ pt= MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil");
+ strcpy(pt->idname, "CLIP_PT_gpencil");
+ strcpy(pt->label, "Grease Pencil");
+ pt->draw= gpencil_panel_standard;
+ pt->flag|= PNL_DEFAULT_CLOSED;
+ BLI_addtail(&art->paneltypes, pt);
+}
+
+/********************* MovieClip Template ************************/
+
+void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, int compact)
+{
+ PropertyRNA *prop;
+ PointerRNA clipptr;
+ MovieClip *clip;
+ uiLayout *row, *split;
+ uiBlock *block;
+
+ if(!ptr->data)
+ return;
+
+ prop= RNA_struct_find_property(ptr, propname);
+ if(!prop) {
+ printf("uiTemplateMovieClip: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ if(RNA_property_type(prop) != PROP_POINTER) {
+ printf("uiTemplateMovieClip: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ clipptr= RNA_property_pointer_get(ptr, prop);
+ clip= clipptr.data;
+
+ uiLayoutSetContextPointer(layout, "edit_movieclip", &clipptr);
+
+ if(!compact)
+ uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL);
+
+ if(clip) {
+ row= uiLayoutRow(layout, 0);
+ block= uiLayoutGetBlock(row);
+ uiDefBut(block, LABEL, 0, "File Path:", 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
+
+ row= uiLayoutRow(layout, 0);
+ split = uiLayoutSplit(row, 0.0, 0);
+ row= uiLayoutRow(split, 1);
+
+ uiItemR(row, &clipptr, "filepath", 0, "", ICON_NONE);
+ uiItemO(row, "", ICON_FILE_REFRESH, "clip.reload");
+ }
+}
+
+/********************* Track Template ************************/
+
+void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname)
+{
+ PropertyRNA *prop;
+ PointerRNA scopesptr;
+ uiBlock *block;
+ rctf rect;
+ MovieClipScopes *scopes;
+
+ if(!ptr->data)
+ return;
+
+ prop= RNA_struct_find_property(ptr, propname);
+ if(!prop) {
+ printf("uiTemplateTrack: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ if(RNA_property_type(prop) != PROP_POINTER) {
+ printf("uiTemplateTrack: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ scopesptr= RNA_property_pointer_get(ptr, prop);
+ scopes= (MovieClipScopes *)scopesptr.data;
+
+ rect.xmin= 0; rect.xmax= 200;
+ rect.ymin= 0; rect.ymax= 120;
+
+ block= uiLayoutAbsoluteBlock(layout);
+
+ scopes->track_preview_height= (scopes->track_preview_height<=UI_UNIT_Y)?UI_UNIT_Y:scopes->track_preview_height;
+
+ uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->track_preview_height, scopes, 0, 0, 0, 0, "");
+}
+
+/********************* Marker Template ************************/
+
+#define B_MARKER_POS 3
+#define B_MARKER_OFFSET 4
+#define B_MARKER_PAT_DIM 5
+#define B_MARKER_SEARCH_POS 6
+#define B_MARKER_SEARCH_DIM 7
+#define B_MARKER_FLAG 8
+
+typedef struct {
+ int compact; /* compact mode */
+
+ MovieClip *clip;
+ MovieClipUser *user; /* user of clip */
+ MovieTrackingTrack *track;
+
+ int framenr; /* current frame number */
+ float marker_pos[2]; /* position of marker in pixel coords */
+ float track_pat[2]; /* position and dimensions of marker pattern in pixel coords */
+ float track_offset[2]; /* offset of "parenting" point */
+ float track_search_pos[2], track_search[2]; /* position and dimensions of marker search in pixel coords */
+ int marker_flag; /* marker's flags */
+} MarkerUpdateCb;
+
+static void to_pixel_space(float r[2], float a[2], int width, int height)
+{
+ copy_v2_v2(r, a);
+ r[0]*= width;
+ r[1]*= height;
+}
+
+static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
+{
+ MarkerUpdateCb *cb= (MarkerUpdateCb*) arg_cb;
+ MovieTrackingMarker *marker;
+
+ if(!cb->compact)
+ return;
+
+ marker= BKE_tracking_ensure_marker(cb->track, cb->framenr);
+
+ marker->flag= cb->marker_flag;
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
+static void marker_block_handler(bContext *C, void *arg_cb, int event)
+{
+ MarkerUpdateCb *cb= (MarkerUpdateCb*) arg_cb;
+ MovieTrackingMarker *marker;
+ int width, height, ok= 0;
+
+ BKE_movieclip_get_size(cb->clip, cb->user, &width, &height);
+
+ marker= BKE_tracking_ensure_marker(cb->track, cb->framenr);
+
+ if(event==B_MARKER_POS) {
+ marker->pos[0]= cb->marker_pos[0]/width;
+ marker->pos[1]= cb->marker_pos[1]/height;
+
+ /* to update position of "parented" objects */
+ DAG_id_tag_update(&cb->clip->id, 0);
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ ok= 1;
+ }
+ else if(event==B_MARKER_PAT_DIM) {
+ float dim[2], pat_dim[2];
+
+ sub_v2_v2v2(pat_dim, cb->track->pat_max, cb->track->pat_min);
+
+ dim[0]= cb->track_pat[0]/width;
+ dim[1]= cb->track_pat[1]/height;
+
+ sub_v2_v2(dim, pat_dim);
+ mul_v2_fl(dim, 0.5f);
+
+ cb->track->pat_min[0]-= dim[0];
+ cb->track->pat_min[1]-= dim[1];
+
+ cb->track->pat_max[0]+= dim[0];
+ cb->track->pat_max[1]+= dim[1];
+
+ BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM);
+
+ ok= 1;
+ }
+ else if(event==B_MARKER_SEARCH_POS) {
+ float delta[2], side[2];
+
+ sub_v2_v2v2(side, cb->track->search_max, cb->track->search_min);
+ mul_v2_fl(side, 0.5f);
+
+ delta[0]= cb->track_search_pos[0]/width;
+ delta[1]= cb->track_search_pos[1]/height;
+
+ sub_v2_v2v2(cb->track->search_min, delta, side);
+ add_v2_v2v2(cb->track->search_max, delta, side);
+
+ BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_POS);
+
+ ok= 1;
+ }
+ else if(event==B_MARKER_SEARCH_DIM) {
+ float dim[2], search_dim[2];
+
+ sub_v2_v2v2(search_dim, cb->track->search_max, cb->track->search_min);
+
+ dim[0]= cb->track_search[0]/width;
+ dim[1]= cb->track_search[1]/height;
+
+ sub_v2_v2(dim, search_dim);
+ mul_v2_fl(dim, 0.5f);
+
+ cb->track->search_min[0]-= dim[0];
+ cb->track->search_min[1]-= dim[1];
+
+ cb->track->search_max[0]+= dim[0];
+ cb->track->search_max[1]+= dim[1];
+
+ BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_DIM);
+
+ ok= 1;
+ } else if(event==B_MARKER_FLAG) {
+ marker->flag= cb->marker_flag;
+
+ ok= 1;
+ } else if(event==B_MARKER_OFFSET) {
+ float offset[2], delta[2];
+ int i;
+
+ offset[0]= cb->track_offset[0]/width;
+ offset[1]= cb->track_offset[1]/height;
+
+ sub_v2_v2v2(delta, offset, cb->track->offset);
+ copy_v2_v2(cb->track->offset, offset);
+
+ for(i=0; i<cb->track->markersnr; i++)
+ sub_v2_v2(cb->track->markers[i].pos, delta);
+
+ /* to update position of "parented" objects */
+ DAG_id_tag_update(&cb->clip->id, 0);
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ ok= 1;
+ }
+
+ if(ok)
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, cb->clip);
+}
+
+void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int compact)
+{
+ PropertyRNA *prop;
+ uiBlock *block;
+ uiBut *bt;
+ PointerRNA clipptr;
+ MovieClip *clip;
+ MovieClipUser *user;
+ MovieTrackingTrack *track;
+ MovieTrackingMarker *marker;
+ MarkerUpdateCb *cb;
+
+ if(!ptr->data)
+ return;
+
+ prop= RNA_struct_find_property(ptr, propname);
+ if(!prop) {
+ printf("uiTemplateMarker: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ if(RNA_property_type(prop) != PROP_POINTER) {
+ printf("uiTemplateMarker: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ clipptr= RNA_property_pointer_get(ptr, prop);
+ clip= (MovieClip *)clipptr.data;
+ user= userptr->data;
+ track= trackptr->data;
+
+ marker= BKE_tracking_get_marker(track, user->framenr);
+
+ cb= MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb");
+ cb->compact= compact;
+ cb->clip= clip;
+ cb->user= user;
+ cb->track= track;
+ cb->marker_flag= marker->flag;
+ cb->framenr= user->framenr;
+
+ if(compact) {
+ block= uiLayoutGetBlock(layout);
+
+ bt= uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20, &cb->marker_flag, 0, 0, 1, 0, "Marker is disabled for current frame.");
+ uiButSetNFunc(bt, marker_update_cb, cb, NULL);
+ } else {
+ int width, height, step, digits;
+ float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2];
+ uiLayout *col;
+
+ BKE_movieclip_get_size(clip, user, &width, &height);
+
+ if(track->flag&TRACK_LOCKED) {
+ uiLayoutSetActive(layout, 0);
+ block= uiLayoutAbsoluteBlock(layout);
+ uiDefBut(block, LABEL, 0, "Track is locked", 0, 0, 300, 19, NULL, 0, 0, 0, 0, "");
+
+ return;
+ }
+
+ step= 100;
+ digits= 2;
+
+ sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min);
+ sub_v2_v2v2(search_dim, track->search_max, track->search_min);
+
+ add_v2_v2v2(search_pos, track->search_max, track->search_min);
+ mul_v2_fl(search_pos, 0.5);
+
+ add_v2_v2v2(pat_pos, track->pat_max, track->pat_min);
+ mul_v2_fl(pat_pos, 0.5);
+
+ to_pixel_space(cb->marker_pos, marker->pos, width, height);
+ to_pixel_space(cb->track_pat, pat_dim, width, height);
+ to_pixel_space(cb->track_search, search_dim, width, height);
+ to_pixel_space(cb->track_search_pos, search_pos, width, height);
+ to_pixel_space(cb->track_offset, track->offset, width, height);
+
+ cb->marker_flag= marker->flag;
+
+ block= uiLayoutAbsoluteBlock(layout);
+ uiBlockSetHandleFunc(block, marker_block_handler, cb);
+ uiBlockSetNFunc(block, marker_update_cb, cb, NULL);
+
+ uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag,
+ 0, 0, 0, 0, "Marker is disabled for current frame.");
+
+ col= uiLayoutColumn(layout, 1);
+ uiLayoutSetActive(col, (cb->marker_flag&MARKER_DISABLED)==0);
+
+ block= uiLayoutAbsoluteBlock(col);
+ uiBlockBeginAlign(block);
+
+ uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0],
+ -10*width, 10.0*width, step, digits, "X-position of marker at frame in screen coordinates.");
+ uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1],
+ -10*height, 10.0*height, step, digits, "Y-position of marker at frame in screen coordinates.");
+
+ uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0],
+ -10*width, 10.0*width, step, digits, "X-offset to parenting point.");
+ uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1],
+ -10*height, 10.0*height, step, digits, "Y-offset to parenting point.");
+
+ uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f,
+ 10.0*width, step, digits, "Width of marker's pattern in screen soordinates.");
+ uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f,
+ 10.0*height, step, digits, "Height of marker's pattern in screen soordinates.");
+
+ uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0],
+ -width, width, step, digits, "X-position of search at frame relative to marker's position");
+ uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1],
+ -height, height, step, digits, "X-position of search at frame relative to marker's position");
+ uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f,
+ 10.0*width, step, digits, "Width of marker's search in screen soordinates.");
+ uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f,
+ 10.0*height, step, digits, "Height of marker's search in screen soordinates.");
+
+ uiBlockEndAlign(block);
+ }
+}
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
new file mode 100644
index 00000000000..9eb96a9a4c5
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -0,0 +1,1325 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_draw.c
+ * \ingroup spclip
+ */
+
+#include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_rect.h"
+#include "BLI_math_base.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+#include "ED_gpencil.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "RNA_access.h"
+
+#include "BLF_api.h"
+
+#include "clip_intern.h" // own include
+
+/*********************** main area drawing *************************/
+
+void clip_draw_curfra_label(SpaceClip *sc, float x, float y)
+{
+ uiStyle *style= UI_GetStyle();
+ int fontid= style->widget.uifont_id;
+ char str[32];
+ float fontsize, fontwidth;
+
+ /* 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);
+
+ glRecti(x, y, x+fontwidth+6, y+fontsize+4);
+
+ UI_ThemeColor(TH_TEXT);
+ BLF_position(fontid, x+2.0f, y+2.0f, 0.0f);
+ BLF_draw(fontid, str, strlen(str));
+}
+
+static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
+{
+ float x;
+ int *points, totseg, i, a;
+ float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1);
+
+ glEnable(GL_BLEND);
+
+ /* cache background */
+ glColor4ub(128, 128, 255, 64);
+ glRecti(0, 0, ar->winx, 8);
+
+ /* cached segments -- could be usefu lto debug caching strategies */
+ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
+ if(totseg) {
+ glColor4ub(128, 128, 255, 128);
+
+ for(a= 0; a<totseg; a++) {
+ float x1, x2;
+
+ x1= (points[a*2]-sfra)/(efra-sfra+1)*ar->winx;
+ x2= (points[a*2+1]-sfra+1)/(efra-sfra+1)*ar->winx;
+
+ glRecti(x1, 0, x2, 8);
+ }
+ }
+
+ /* track */
+ if(clip->tracking.act_track) {
+ MovieTrackingTrack *track= clip->tracking.act_track;
+
+ for(i= sfra, a= 0; i <= efra; i++) {
+ int framenr;
+ MovieTrackingMarker *marker;
+
+ while(a<track->markersnr) {
+ if(track->markers[a].framenr>=i)
+ break;
+
+ if(a<track->markersnr-1 && track->markers[a+1].framenr>i)
+ break;
+
+ a++;
+ }
+
+ if(a<track->markersnr) marker= &track->markers[a];
+ else marker= &track->markers[track->markersnr-1];
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ framenr= marker->framenr;
+
+ if(framenr!=i) glColor4ub(128, 128, 0, 96);
+ else if((marker->flag&MARKER_TRACKED)==0) glColor4ub(255, 255, 0, 196);
+ else glColor4ub(255, 255, 0, 96);
+
+ glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 4);
+ }
+ }
+ }
+
+ /* failed frames */
+ if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
+ int n= clip->tracking.reconstruction.camnr;
+ MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras;
+
+ glColor4ub(255, 0, 0, 96);
+
+ for(i= sfra, a= 0; i <= efra; i++) {
+ int ok= 0;
+
+ while(a<n) {
+ if(cameras[a].framenr==i) {
+ ok= 1;
+ break;
+ }
+ else if(cameras[a].framenr>i) {
+ break;
+ }
+
+ a++;
+ }
+
+ if(!ok)
+ glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 8);
+ }
+ }
+
+ glDisable(GL_BLEND);
+
+ /* current frame */
+ x= (sc->user.framenr-sfra)/(efra-sfra+1)*ar->winx;
+
+ UI_ThemeColor(TH_CFRAME);
+ glRecti(x, 0, x+framelen, 8);
+
+ clip_draw_curfra_label(sc, x, 8.0f);
+}
+
+static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
+{
+ char str[256]= {0};
+
+ if(sc->flag&SC_LOCK_SELECTION)
+ strcpy(str, "Locked");
+
+ if(str[0]) {
+ uiStyle *style= UI_GetStyle();
+ int fontsize, fontwidth;
+ int fontid= style->widget.uifont_id;
+
+ BLF_size(fontid, 11.0f, U.dpi);
+ fontsize= BLF_height(fontid, str);
+ fontwidth= BLF_width(fontid, str);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(0.0f, 0.0f, 0.0f, 0.6f);
+ glRecti(0, ar->winy-fontsize-9, fontwidth+12, ar->winy);
+
+ glColor3f(1.0f, 1.0f, 1.0f);
+ BLF_position(fontid, 6.0f, ar->winy-fontsize-5.0f, 0.0f);
+ BLF_draw(fontid, str, strlen(str));
+
+ glDisable(GL_BLEND);
+ }
+}
+
+static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
+ int width, int height, float zoomx, float zoomy)
+{
+ int x, y;
+ MovieClip *clip= ED_space_clip(sc);
+
+ /* set zoom */
+ glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y);
+
+ /* find window pixel coordinates of origin */
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ if(sc->flag&SC_MUTE_FOOTAGE) {
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glRectf(x, y, x+zoomx*width, y+zoomy*height);
+ } else {
+ if(ibuf->rect_float && !ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ if(ibuf->rect)
+ glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ }
+
+ /* draw boundary border for frame if stabilization is enabled */
+ if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_NOR);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+
+ glScalef(zoomx, zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(0.0f, 0.0f);
+ glVertex2f(ibuf->x, 0.0f);
+ glVertex2f(ibuf->x, ibuf->y);
+ glVertex2f(0.0f, ibuf->y);
+ glEnd();
+
+ glPopMatrix();
+
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisable(GL_LINE_STIPPLE);
+ }
+
+
+ /* reset zoom */
+ glPixelZoom(1.0f, 1.0f);
+}
+
+static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
+{
+ int count= sc->path_length;
+ int i, a, b, curindex= -1;
+ float path[102][2];
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER, framenr;
+ MovieTrackingMarker *marker;
+
+ if(count==0)
+ return;
+
+ marker= BKE_tracking_get_marker(track, sc->user.framenr);
+ if(marker->framenr!=sc->user.framenr || marker->flag&MARKER_DISABLED)
+ return;
+
+ framenr= marker->framenr;
+
+ a= count;
+ i= framenr-1;
+ while(i>=framenr-count) {
+ marker= BKE_tracking_get_marker(track, i);
+
+ if(!marker || marker->flag&MARKER_DISABLED)
+ break;
+
+ if(marker->framenr==i) {
+ add_v2_v2v2(path[--a], marker->pos, track->offset);
+ ED_clip_point_undistorted_pos(sc, path[a], path[a]);
+
+ if(marker->framenr==sc->user.framenr)
+ curindex= a;
+ } else
+ break;
+
+ i--;
+ }
+
+ b= count;
+ i= framenr;
+ while(i<=framenr+count) {
+ marker= BKE_tracking_get_marker(track, i);
+
+ if(!marker || marker->flag&MARKER_DISABLED)
+ break;
+
+ if(marker->framenr==i) {
+ if(marker->framenr==sc->user.framenr)
+ curindex= b;
+
+ add_v2_v2v2(path[b++], marker->pos, track->offset);
+ ED_clip_point_undistorted_pos(sc, path[b-1], path[b-1]);
+ } else
+ break;
+
+ i++;
+ }
+
+ if(!tiny) {
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ glPointSize(5.0f);
+ glBegin(GL_POINTS);
+ for(i= a; i<b; i++) {
+ if(i!=curindex)
+ glVertex2f(path[i][0], path[i][1]);
+ }
+ glEnd();
+ }
+
+ glLineWidth(3.0f);
+ glBegin(GL_LINE_STRIP);
+ for(i= a; i<b; i++)
+ glVertex2f(path[i][0], path[i][1]);
+ glEnd();
+ glLineWidth(1.0f);
+ }
+
+ UI_ThemeColor(TH_PATH_BEFORE);
+
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ glPointSize(3.0f);
+ glBegin(GL_POINTS);
+ for(i= a; i<b; i++) {
+ if(i==count+1)
+ UI_ThemeColor(TH_PATH_AFTER);
+
+ if(i!=curindex)
+ glVertex2f(path[i][0], path[i][1]);
+ }
+ glEnd();
+ }
+
+ UI_ThemeColor(TH_PATH_BEFORE);
+
+ glBegin(GL_LINE_STRIP);
+ for(i= a; i<b; i++) {
+ if(i==count+1)
+ UI_ThemeColor(TH_PATH_AFTER);
+
+ glVertex2f(path[i][0], path[i][1]);
+ }
+ glEnd();
+ glPointSize(1.0f);
+}
+
+static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int width, int height)
+{
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER;
+ int show_search= 0;
+ float px[2];
+
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+
+ px[0]= 1.0f/width/sc->zoom;
+ px[1]= 1.0f/height/sc->zoom;
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ float pos[2];
+ rctf r;
+
+ BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
+ add_v2_v2v2(pos, marker->pos, track->offset);
+
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+
+ if(BLI_in_rctf(&r, pos[0]-marker_pos[0], pos[1]-marker_pos[1])) {
+ if(tiny) glPointSize(3.0f);
+ else glPointSize(4.0f);
+ glBegin(GL_POINTS);
+ glVertex2f(pos[0], pos[1]);
+ glEnd();
+ glPointSize(1.0f);
+ } else {
+ if(!tiny) glLineWidth(3.0f);
+ glBegin(GL_LINES);
+ glVertex2f(pos[0] + px[0]*2, pos[1]);
+ glVertex2f(pos[0] + px[0]*8, pos[1]);
+
+ glVertex2f(pos[0] - px[0]*2, pos[1]);
+ glVertex2f(pos[0] - px[0]*8, pos[1]);
+
+ glVertex2f(pos[0], pos[1] - px[1]*2);
+ glVertex2f(pos[0], pos[1] - px[1]*8);
+
+ glVertex2f(pos[0], pos[1] + px[1]*2);
+ glVertex2f(pos[0], pos[1] + px[1]*8);
+ glEnd();
+ if(!tiny) glLineWidth(1.0f);
+ }
+ }
+
+ /* pattern and search outline */
+ glPushMatrix();
+ glTranslatef(marker_pos[0], marker_pos[1], 0);
+
+ if(!tiny) glLineWidth(3.0f);
+
+ if(sc->flag&SC_SHOW_MARKER_PATTERN) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->pat_min[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_max[1]);
+ glVertex2f(track->pat_min[0], track->pat_max[1]);
+ glEnd();
+ }
+
+ show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0);
+ if(sc->flag&SC_SHOW_MARKER_SEARCH && show_search) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->search_min[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_max[1]);
+ glVertex2f(track->search_min[0], track->search_max[1]);
+ glEnd();
+ }
+ glPopMatrix();
+
+ if(!tiny) glLineWidth(1.0f);
+}
+
+static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
+{
+ if(track->flag&TRACK_CUSTOMCOLOR) {
+ if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
+ else copy_v3_v3(scol, track->color);
+
+ mul_v3_v3fl(col, track->color, 0.5f);
+ } else {
+ UI_GetThemeColor3fv(TH_MARKER, col);
+
+ if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
+ else UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
+ }
+}
+
+static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int width, int height, int act, int sel)
+{
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER;
+ int show_search= 0;
+ float col[3], scol[3], px[2];
+
+ track_colors(track, act, col, scol);
+
+ px[0]= 1.0f/width/sc->zoom;
+ px[1]= 1.0f/height/sc->zoom;
+
+ /* marker position and offset position */
+ if((track->flag&SELECT)==sel && (marker->flag&MARKER_DISABLED)==0) {
+ float pos[2];
+ rctf r;
+
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ } else {
+ if(track->flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]);
+ add_v2_v2v2(pos, marker->pos, track->offset);
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+
+ if(BLI_in_rctf(&r, pos[0]-marker_pos[0], pos[1]-marker_pos[1])) {
+ if(!tiny) glPointSize(2.0f);
+ glBegin(GL_POINTS);
+ glVertex2f(pos[0], pos[1]);
+ glEnd();
+ if(!tiny) glPointSize(1.0f);
+ } else {
+ glBegin(GL_LINES);
+ glVertex2f(pos[0] + px[0]*3, pos[1]);
+ glVertex2f(pos[0] + px[0]*7, pos[1]);
+
+ glVertex2f(pos[0] - px[0]*3, pos[1]);
+ glVertex2f(pos[0] - px[0]*7, pos[1]);
+
+ glVertex2f(pos[0], pos[1] - px[1]*3);
+ glVertex2f(pos[0], pos[1] - px[1]*7);
+
+ glVertex2f(pos[0], pos[1] + px[1]*3);
+ glVertex2f(pos[0], pos[1] + px[1]*7);
+ glEnd();
+
+ glColor3f(0.0f, 0.0f, 0.0f);
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_NOR);
+
+ glBegin(GL_LINES);
+ glVertex2fv(pos);
+ glVertex2fv(marker_pos);
+ glEnd();
+
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisable(GL_LINE_STIPPLE);
+ }
+ }
+
+ /* pattern */
+ glPushMatrix();
+ glTranslatef(marker_pos[0], marker_pos[1], 0);
+
+ if(tiny) {
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ }
+
+ if((track->pat_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_PATTERN)) {
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ }
+ else if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ else UI_ThemeColor(TH_DIS_MARKER);
+ } else {
+ if(track->pat_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->pat_min[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_max[1]);
+ glVertex2f(track->pat_min[0], track->pat_max[1]);
+ glEnd();
+ }
+
+ /* search */
+ show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0);
+ if((track->search_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_SEARCH) && show_search) {
+ if(track->flag&TRACK_LOCKED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ }
+ else if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ else UI_ThemeColor(TH_DIS_MARKER);
+ } else {
+ if(track->search_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->search_min[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_min[1]);
+ glVertex2f(track->search_max[0], track->search_max[1]);
+ glVertex2f(track->search_min[0], track->search_max[1]);
+ glEnd();
+ }
+
+ /* pyramid */
+ if(sel && TRACK_SELECTED(track) && (sc->flag&SC_SHOW_PYRAMID_LEVELS) && (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);
+ else UI_ThemeColor(TH_LOCK_MARKER);
+ }
+ else if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ else UI_ThemeColor(TH_DIS_MARKER);
+ } else {
+ if(track->pat_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ {
+ int i = 0;
+ glPushMatrix();
+ glEnable(GL_LINE_STIPPLE);
+ for (i = 1; i < track->pyramid_levels; ++i) {
+ glScalef(2.0f, 2.0f, 1.0);
+ }
+ /* only draw a pattern for the coarsest level */
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(track->pat_min[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_min[1]);
+ glVertex2f(track->pat_max[0], track->pat_max[1]);
+ glVertex2f(track->pat_min[0], track->pat_max[1]);
+ glEnd();
+ glDisable(GL_LINE_STIPPLE);
+ glPopMatrix();
+ }
+ }
+
+ if(tiny)
+ glDisable(GL_LINE_STIPPLE);
+
+ glPopMatrix();
+}
+
+static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ float marker_pos[2], int outline, int sel, int act, int width, int height)
+{
+ float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy;
+ int tiny= sc->flag&SC_SHOW_TINY_MARKER;
+ float col[3], scol[3], px[2];
+
+ if((tiny && outline) || (marker->flag&MARKER_DISABLED))
+ return;
+
+ if(!TRACK_VIEW_SELECTED(sc, track) || track->flag&TRACK_LOCKED)
+ return;
+
+ track_colors(track, act, col, scol);
+
+ if(outline) {
+ glLineWidth(3.0f);
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+ }
+
+ glPushMatrix();
+ glTranslatef(marker_pos[0], marker_pos[1], 0);
+
+ dx= 6.0f/width/sc->zoom;
+ dy= 6.0f/height/sc->zoom;
+
+ patdx= MIN2(dx*2.0f/3.0f, (track->pat_max[0]-track->pat_min[0])/6.0f);
+ patdy= MIN2(dy*2.0f/3.0f, (track->pat_max[1]-track->pat_min[1])/6.0f);
+
+ searchdx= MIN2(dx, (track->search_max[0]-track->search_min[0])/6.0f);
+ searchdy= MIN2(dy, (track->search_max[1]-track->search_min[1])/6.0f);
+
+ px[0]= 1.0f/sc->zoom/width/sc->scale;
+ px[1]= 1.0f/sc->zoom/height/sc->scale;
+
+ if((sc->flag&SC_SHOW_MARKER_SEARCH) && ((track->search_flag&SELECT)==sel || outline)) {
+ if(!outline) {
+ if(track->search_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ /* search offset square */
+ x= track->search_min[0];
+ y= track->search_max[1];
+
+ tdx= searchdx;
+ tdy= searchdy;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_QUADS);
+ glVertex3f(x-tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y-tdy, 0);
+ glVertex3f(x-tdx, y-tdy, 0);
+ glEnd();
+
+ /* search resizing triangle */
+ x= track->search_max[0];
+ y= track->search_min[1];
+
+ tdx= searchdx*2.0f;
+ tdy= searchdy*2.0f;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_TRIANGLES);
+ glVertex3f(x, y, 0);
+ glVertex3f(x-tdx, y, 0);
+ glVertex3f(x, y+tdy, 0);
+ glEnd();
+ }
+
+ if((sc->flag&SC_SHOW_MARKER_PATTERN) && ((track->pat_flag&SELECT)==sel || outline)) {
+ if(!outline) {
+ if(track->pat_flag&SELECT) glColor3fv(scol);
+ else glColor3fv(col);
+ }
+
+ /* pattern offset square */
+ x= track->pat_min[0];
+ y= track->pat_max[1];
+
+ tdx= patdx;
+ tdy= patdy;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_QUADS);
+ glVertex3f(x-tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y+tdy, 0);
+ glVertex3f(x+tdx, y-tdy, 0);
+ glVertex3f(x-tdx, y-tdy, 0);
+ glEnd();
+
+ /* pattern resizing triangle */
+ x= track->pat_max[0];
+ y= track->pat_min[1];
+
+ tdx= patdx*2.0f;
+ tdy= patdy*2.0f;
+
+ if(outline) {
+ tdx+= px[0];
+ tdy+= px[1];
+ }
+
+ glBegin(GL_TRIANGLES);
+ glVertex3f(x, y, 0);
+ glVertex3f(x-tdx, y, 0);
+ glVertex3f(x, y+tdy, 0);
+ glEnd();
+ }
+
+ glPopMatrix();
+
+ if(outline)
+ glLineWidth(1.0f);
+}
+
+static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int act,
+ int width, int height, float zoomx, float zoomy)
+{
+ char str[128]= {0}, state[64]= {0};
+ float dx= 0.0f, dy= 0.0f, fontsize, pos[3];
+ uiStyle *style= U.uistyles.first;
+ int fontid= style->widget.uifont_id;
+
+ if(!TRACK_VIEW_SELECTED(sc, track))
+ return;
+
+ BLF_size(fontid, 11.0f, U.dpi);
+ fontsize= BLF_height_max(fontid);
+
+ if(marker->flag&MARKER_DISABLED) {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else UI_ThemeColorShade(TH_DIS_MARKER, 128);
+ } else {
+ if(act) UI_ThemeColor(TH_ACT_MARKER);
+ else UI_ThemeColor(TH_SEL_MARKER);
+ }
+
+ if(sc->flag&SC_SHOW_MARKER_SEARCH) {
+ dx= track->search_min[0];
+ dy= track->search_min[1];
+ } else if(sc->flag&SC_SHOW_MARKER_PATTERN) {
+ dx= track->pat_min[0];
+ dy= track->pat_min[1];
+ }
+
+ pos[0]= (marker_pos[0]+dx)*width;
+ pos[1]= (marker_pos[1]+dy)*height;
+ pos[2]= 0.0f;
+
+ mul_m4_v3(sc->stabmat, pos);
+
+ pos[0]= pos[0]*zoomx;
+ pos[1]= pos[1]*zoomy - fontsize;
+
+ if(marker->flag&MARKER_DISABLED) strcpy(state, "disabled");
+ else if(marker->framenr!=sc->user.framenr) strcpy(state, "estimated");
+ else if(marker->flag&MARKER_TRACKED) strcpy(state, "tracked");
+ else strcpy(state, "keyframed");
+
+ if(state[0])
+ BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
+ else
+ BLI_snprintf(str, sizeof(str), "%s", track->name);
+
+ BLF_position(fontid, pos[0], pos[1], 0.0f);
+ BLF_draw(fontid, str, strlen(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));
+ pos[1]-= fontsize;
+ }
+
+ if(track->flag&TRACK_LOCKED) {
+ BLF_position(fontid, pos[0], pos[1], 0.0f);
+ BLF_draw(fontid, "locked", 6);
+ }
+}
+
+static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
+{
+ /* express given coordinates as proportional values */
+ x= -v2d->cur.xmin / (v2d->cur.xmax-v2d->cur.xmin);
+ y= -v2d->cur.ymin / (v2d->cur.ymax-v2d->cur.ymin);
+
+ /* convert proportional distances to screen coordinates */
+ *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin);
+ *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin);
+}
+
+static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
+ int width, int height, float zoomx, float zoomy)
+{
+ float x, y;
+ MovieTracking* tracking= &clip->tracking;
+ MovieTrackingMarker *marker;
+ MovieTrackingTrack *track, *act_track;
+ 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];
+
+ /* ** find window pixel coordinates of origin ** */
+
+ /* UI_view2d_to_region_no_clip return integer values, this could
+ lead to 1px flickering when view is locked to selection during playbeck.
+ to avoid this flickering, calclate base point in the same way as it happens
+ in UI_view2d_to_region_no_clip, but do it in floats here */
+
+ view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+
+ glPushMatrix();
+ glScalef(zoomx, zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+ glScalef(width, height, 0);
+
+ act_track= clip->tracking.act_track;
+
+ if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
+ int count= 0;
+
+ /* count */
+ track= tracking->tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker))
+ count++;
+ }
+
+ track= track->next;
+ }
+
+ /* undistort */
+ if(count) {
+ marker_pos= MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos");
+
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ ED_clip_point_undistorted_pos(sc, marker->pos, fp);
+
+ if(track==act_track)
+ active_pos= fp;
+
+ fp+= 2;
+ }
+ }
+
+ track= track->next;
+ }
+ }
+ }
+
+ if(sc->flag&SC_SHOW_TRACK_PATH) {
+ track= tracking->tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0)
+ draw_track_path(sc, clip, track);
+
+ track= track->next;
+ }
+ }
+
+ /* markers outline and non-selected areas */
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ copy_v2_v2(cur_pos, fp ? fp : marker->pos);
+
+ draw_marker_outline(sc, track, marker, cur_pos, width, height);
+ draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);
+
+ if(fp) fp+= 2;
+ }
+ }
+
+ track= track->next;
+ }
+
+ /* selected areas only, so selection wouldn't be overlapped by
+ non-selected areas */
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ int act= track==act_track;
+
+ if(!act) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ copy_v2_v2(cur_pos, fp ? fp : marker->pos);
+
+ draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
+ draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
+ }
+ }
+
+ if(MARKER_VISIBLE(sc, marker) && fp)
+ fp+= 2;
+ }
+
+ track= track->next;
+ }
+
+ /* active marker would be displayed on top of everything else */
+ if(act_track) {
+ if((act_track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(act_track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
+
+ draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
+ draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
+ }
+ }
+ }
+
+ if(sc->flag&SC_SHOW_BUNDLES) {
+ 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);
+
+ track= tracking->tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ float npos[2];
+ copy_v4_v4(vec, track->bundle_pos);
+ vec[3]=1;
+
+ mul_v4_m4v4(pos, mat, vec);
+
+ pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width;
+ pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height*aspy;
+
+ BKE_tracking_apply_intrinsics(tracking, pos, npos);
+
+ if(npos[0]>=0.0f && npos[1]>=0.0f && npos[0]<=width && npos[1]<=height*aspy) {
+ vec[0]= (marker->pos[0]+track->offset[0])*width;
+ vec[1]= (marker->pos[1]+track->offset[1])*height*aspy;
+
+ sub_v2_v2(vec, npos);
+
+ if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f);
+ else glColor3f(1.0f, 0.0f, 0.0f);
+
+ glBegin(GL_POINTS);
+ if(undistort) glVertex3f(pos[0]/width, pos[1]/(height*aspy), 0);
+ else glVertex3f(npos[0]/width, npos[1]/(height*aspy), 0);
+ glEnd();
+ }
+ }
+ }
+
+ track= track->next;
+ }
+
+ glPointSize(1.0f);
+ glDisable(GL_POINT_SMOOTH);
+ }
+
+ glPopMatrix();
+
+ if(sc->flag&SC_SHOW_NAMES) {
+ /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
+ track= tracking->tracks.first;
+ fp= marker_pos;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ if(MARKER_VISIBLE(sc, marker)) {
+ int act= track==act_track;
+
+ copy_v2_v2(cur_pos, fp ? fp : marker->pos);
+
+ draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
+
+ if(fp) fp+= 2;
+ }
+ }
+
+ track= track->next;
+ }
+ }
+
+ glPopMatrix();
+
+ if(marker_pos)
+ MEM_freeN(marker_pos);
+}
+
+static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy)
+{
+ float x, y;
+ const int n= 10;
+ int i, j, a;
+ float pos[2], tpos[2], grid[11][11][2];
+ MovieTracking *tracking= &clip->tracking;
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+ float dx= (float)width/n, dy= (float)height/n*aspy;
+
+ if(sc->mode!=SC_MODE_DISTORTION)
+ return;
+
+ if(!tracking->camera.focal)
+ return;
+
+ if((sc->flag&SC_SHOW_GRID)==0 && (sc->flag&SC_MANUAL_CALIBRATION)==0)
+ return;
+
+ view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+ glScalef(zoomx, zoomy, 0);
+ glMultMatrixf(sc->stabmat);
+ glScalef(width, height, 0);
+
+ /* grid */
+ if(sc->flag&SC_SHOW_GRID) {
+ float val[4][2], idx[4][2];
+ float min[2], max[2];
+
+ for(a=0; a<4; a++) {
+ if(a<2) val[a][a%2]= FLT_MAX;
+ else val[a][a%2]= -FLT_MAX;
+ }
+
+ zero_v2(pos);
+ for(i= 0; i<=n; i++) {
+ for(j= 0; j<=n; j++) {
+ if(i==0 || j==0 || i==n || j==n) {
+ BKE_tracking_apply_intrinsics(tracking, pos, tpos);
+
+ for(a=0; a<4; a++) {
+ int ok;
+
+ if(a<2) ok= tpos[a%2] < val[a][a%2];
+ else ok= tpos[a%2] > val[a][a%2];
+
+ if(ok) {
+ copy_v2_v2(val[a], tpos);
+ idx[a][0]= j;
+ idx[a][1]= i;
+ }
+ }
+ }
+
+ pos[0]+= dx;
+ }
+
+ pos[0]= 0.0f;
+ pos[1]+= dy;
+ }
+
+ INIT_MINMAX2(min, max);
+
+ for(a= 0; a<4; a++) {
+ pos[0]= idx[a][0]*dx;
+ pos[1]= idx[a][1]*dy;
+
+ BKE_tracking_invert_intrinsics(tracking, pos, tpos);
+
+ DO_MINMAX2(tpos, min, max);
+ }
+
+ copy_v2_v2(pos, min);
+ dx= (max[0]-min[0])/n;
+ dy= (max[1]-min[1])/n;
+
+ for(i= 0; i<=n; i++) {
+ for(j= 0; j<=n; j++) {
+ BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]);
+
+ grid[i][j][0]/= width;
+ grid[i][j][1]/= height*aspy;
+
+ pos[0]+= dx;
+ }
+
+ pos[0]= min[0];
+ pos[1]+= dy;
+ }
+
+ glColor3f(1.0f, 0.0f, 0.0f);
+
+ for(i= 0; i<=n; i++) {
+ glBegin(GL_LINE_STRIP);
+ for(j= 0; j<=n; j++) {
+ glVertex2fv(grid[i][j]);
+ }
+ glEnd();
+ }
+
+ for(j= 0; j<=n; j++) {
+ glBegin(GL_LINE_STRIP);
+ for(i= 0; i<=n; i++) {
+ glVertex2fv(grid[i][j]);
+ }
+ glEnd();
+ }
+ }
+
+ if(sc->flag&SC_MANUAL_CALIBRATION && clip->gpd) {
+ bGPDlayer *layer= clip->gpd->layers.first;
+
+ while(layer) {
+ bGPDframe *frame= layer->frames.first;
+
+ glColor4fv(layer->color);
+ glLineWidth(layer->thickness);
+ glPointSize((float)(layer->thickness + 2));
+
+ while(frame) {
+ bGPDstroke *stroke= frame->strokes.first;
+
+ while(stroke) {
+ if(stroke->flag&GP_STROKE_2DSPACE) {
+ if(stroke->totpoints>1) {
+ glBegin(GL_LINE_STRIP);
+ for(i= 0; i<stroke->totpoints-1; i++) {
+ float npos[2], dpos[2], len;
+ int steps;
+
+ pos[0]= stroke->points[i].x*width;
+ pos[1]= stroke->points[i].y*height*aspy;
+
+ npos[0]= stroke->points[i+1].x*width;
+ npos[1]= stroke->points[i+1].y*height*aspy;
+
+ len= len_v2v2(pos, npos);
+ steps= ceil(len/5.0f);
+
+ /* we want to distort only long straight lines */
+ if(stroke->totpoints==2) {
+ BKE_tracking_invert_intrinsics(tracking, pos, pos);
+ BKE_tracking_invert_intrinsics(tracking, npos, npos);
+ }
+
+ sub_v2_v2v2(dpos, npos, pos);
+ mul_v2_fl(dpos, 1.0f/steps);
+
+ for(j= 0; j<=steps; j++) {
+ BKE_tracking_apply_intrinsics(tracking, pos, tpos);
+ glVertex2f(tpos[0]/width, tpos[1]/(height*aspy));
+
+ add_v2_v2(pos, dpos);
+ }
+ }
+ glEnd();
+ }
+ else if(stroke->totpoints==1) {
+ glBegin(GL_POINTS);
+ glVertex2f(stroke->points[0].x, stroke->points[0].y);
+ glEnd();
+ }
+ }
+
+ stroke= stroke->next;
+ }
+
+ frame= frame->next;
+ }
+
+ layer= layer->next;
+ }
+
+ glLineWidth(1.0f);
+ glPointSize(1.0f);
+ }
+
+ glPopMatrix();
+}
+
+void clip_draw_main(SpaceClip *sc, ARegion *ar, Scene *scene)
+{
+ MovieClip *clip= ED_space_clip(sc);
+ ImBuf *ibuf;
+ int width, height;
+ float zoomx, zoomy;
+
+ /* if no clip, nothing to do */
+ if(!clip)
+ return;
+
+ ED_space_clip_size(sc, &width, &height);
+ ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+
+ if(sc->flag&SC_SHOW_STABLE) {
+ 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);
+
+ mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL);
+ } else {
+ ibuf= ED_space_clip_get_buffer(sc);
+
+ zero_v2(sc->loc);
+ sc->scale= 1.0f;
+ unit_m4(sc->stabmat);
+ unit_m4(sc->unistabmat);
+ }
+
+ if(ibuf) {
+ draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy);
+ IMB_freeImBuf(ibuf);
+
+ draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy);
+ draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
+ }
+
+ draw_movieclip_cache(sc, ar, clip, scene);
+ draw_movieclip_notes(sc, ar);
+}
+
+/* draw grease pencil */
+void clip_draw_grease_pencil(bContext *C, int onlyv2d)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ ImBuf *ibuf;
+
+ if((sc->flag&SC_SHOW_GPENCIL)==0 || !clip)
+ return;
+
+ if(onlyv2d) {
+ /* if manual calibration is used then grase pencil data is already
+ drawed in draw_distortion */
+ if((sc->flag&SC_MANUAL_CALIBRATION)==0 || sc->mode!=SC_MODE_DISTORTION) {
+ ibuf= ED_space_clip_get_buffer(sc);
+
+ if(ibuf) {
+ glPushMatrix();
+ glMultMatrixf(sc->unistabmat);
+ draw_gpencil_2dimage(C, ibuf);
+
+ IMB_freeImBuf(ibuf);
+ glPopMatrix();
+ }
+ }
+ } else {
+ draw_gpencil_view2d(C, 0);
+ }
+}
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
new file mode 100644
index 00000000000..c5036145792
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -0,0 +1,310 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_editor.c
+ * \ingroup spclip
+ */
+
+#include <stddef.h>
+
+#include "BKE_main.h"
+#include "BKE_movieclip.h"
+#include "BKE_context.h"
+#include "BKE_tracking.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "BIF_gl.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_view2d.h"
+
+#include "clip_intern.h" // own include
+
+int ED_space_clip_poll(bContext *C)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ if(sc && sc->clip)
+ return 1;
+
+ return 0;
+}
+
+void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip)
+{
+ sc->clip= clip;
+
+ if(sc->clip && sc->clip->id.us==0)
+ sc->clip->id.us= 1;
+
+ if(C)
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip);
+}
+
+MovieClip *ED_space_clip(SpaceClip *sc)
+{
+ return sc->clip;
+}
+
+ImBuf *ED_space_clip_get_buffer(SpaceClip *sc)
+{
+ if(sc->clip) {
+ ImBuf *ibuf;
+
+ ibuf= BKE_movieclip_get_ibuf(sc->clip, &sc->user);
+
+ if(ibuf && (ibuf->rect || ibuf->rect_float))
+ return ibuf;
+
+ if(ibuf)
+ IMB_freeImBuf(ibuf);
+ }
+
+ return NULL;
+}
+
+ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale, float *angle)
+{
+ if(sc->clip) {
+ ImBuf *ibuf;
+
+ ibuf= BKE_movieclip_get_stable_ibuf(sc->clip, &sc->user, loc, scale, angle);
+
+ if(ibuf && (ibuf->rect || ibuf->rect_float))
+ return ibuf;
+
+ if(ibuf)
+ IMB_freeImBuf(ibuf);
+ }
+
+ return NULL;
+}
+
+void ED_space_clip_size(SpaceClip *sc, int *width, int *height)
+{
+ if(!sc->clip) {
+ *width= 0;
+ *height= 0;
+ } else
+ BKE_movieclip_get_size(sc->clip, &sc->user, width, height);
+}
+
+void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy)
+{
+ int width, height;
+
+ ED_space_clip_size(sc, &width, &height);
+
+ *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width);
+ *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height);
+}
+
+void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy)
+{
+ MovieClip *clip= ED_space_clip(sc);
+
+ if(clip)
+ BKE_movieclip_aspect(clip, aspx, aspy);
+ else
+ *aspx= *aspy= 1.0f;
+}
+
+void ED_clip_update_frame(const Main *mainp, int cfra)
+{
+ wmWindowManager *wm;
+ wmWindow *win;
+
+ /* image window, compo node users */
+ for(wm=mainp->wm.first; wm; wm= wm->id.next) { /* only 1 wm */
+ for(win= wm->windows.first; win; win= win->next) {
+ ScrArea *sa;
+ for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+ if(sa->spacetype==SPACE_CLIP) {
+ SpaceClip *sc= sa->spacedata.first;
+
+ sc->scopes.ok= 0;
+
+ BKE_movieclip_user_set_frame(&sc->user, cfra);
+ }
+ }
+ }
+ }
+}
+
+static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
+{
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ int width, height, ok= 0;
+
+ INIT_MINMAX2(min, max);
+
+ ED_space_clip_size(sc, &width, &height);
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
+
+ if(marker) {
+ float pos[3];
+
+ pos[0]= marker->pos[0]+track->offset[0];
+ pos[1]= marker->pos[1]+track->offset[1];
+ pos[2]= 0.0f;
+
+ /* undistortion happens for normalized coords */
+ if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT)
+ /* undistortion happens for normalized coords */
+ ED_clip_point_undistorted_pos(sc, pos, pos);
+
+ pos[0]*= width;
+ pos[1]*= height;
+
+ mul_v3_m4v3(pos, sc->stabmat, pos);
+
+ DO_MINMAX2(pos, min, max);
+
+ ok= 1;
+ }
+ }
+
+ track= track->next;
+ }
+
+ return ok;
+}
+
+int ED_clip_view_selection(SpaceClip *sc, ARegion *ar, int fit)
+{
+ int w, h, frame_width, frame_height;
+ float min[2], max[2];
+
+ ED_space_clip_size(sc, &frame_width, &frame_height);
+
+ if(frame_width==0 || frame_height==0) return 0;
+
+ if(!selected_boundbox(sc, min, max))
+ return 0;
+
+ /* center view */
+ clip_view_center_to_point(sc, (max[0]+min[0])/(2*frame_width), (max[1]+min[1])/(2*frame_height));
+
+ w= max[0]-min[0];
+ h= max[1]-min[1];
+
+ /* set zoom to see all selection */
+ if(w>0 && h>0) {
+ int width, height;
+ float zoomx, zoomy, newzoom, aspx, aspy;
+
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ width= ar->winrct.xmax - ar->winrct.xmin + 1;
+ height= ar->winrct.ymax - ar->winrct.ymin + 1;
+
+ zoomx= (float)width/w/aspx;
+ zoomy= (float)height/h/aspy;
+
+ newzoom= 1.0f/power_of_2(1/MIN2(zoomx, zoomy));
+
+ if(fit || sc->zoom>newzoom)
+ sc->zoom= newzoom;
+ }
+
+ return 1;
+}
+
+void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2])
+{
+ copy_v2_v2(nco, co);
+
+ if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
+ MovieClip *clip= ED_space_clip(sc);
+ float aspy= 1.0f/clip->tracking.camera.pixel_aspect;
+ int width, height;
+
+ ED_space_clip_size(sc, &width, &height);
+
+ nco[0]*= width;
+ nco[1]*= height*aspy;
+
+ BKE_tracking_invert_intrinsics(&clip->tracking, nco, nco);
+ nco[0]/= width;
+ nco[1]/= height*aspy;
+ }
+}
+
+void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *yr)
+{
+ ARegion *ar= CTX_wm_region(C);
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ int sx, sy, width, height;
+ float zoomx, zoomy, pos[3]={0.0f, 0.0f, 0.0f}, imat[4][4];
+
+ ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+ ED_space_clip_size(sc, &width, &height);
+
+ UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+
+ pos[0]= (x-sx)/zoomx;
+ pos[1]= (y-sy)/zoomy;
+
+ invert_m4_m4(imat, sc->stabmat);
+ mul_v3_m4v3(pos, imat, pos);
+
+ *xr= pos[0]/width;
+ *yr= pos[1]/height;
+
+ if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ float aspy= 1.0f/tracking->camera.pixel_aspect;
+ float tmp[2]= {*xr*width, *yr*height*aspy};
+
+ BKE_tracking_apply_intrinsics(tracking, tmp, tmp);
+
+ *xr= tmp[0]/width;
+ *yr= tmp[1]/(height*aspy);
+ }
+}
+
+void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2])
+{
+ ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]);
+}
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
new file mode 100644
index 00000000000..7b14783d4ca
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -0,0 +1,255 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_graph_draw.c
+ * \ingroup spclip
+ */
+
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "BIF_gl.h"
+
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "BLF_api.h"
+
+#include "clip_intern.h" // own include
+
+static void draw_curve_knot(float x, float y, float xscale, float yscale, float hsize)
+{
+ static GLuint displist=0;
+
+ /* initialise round circle shape */
+ if (displist == 0) {
+ GLUquadricObj *qobj;
+
+ displist= glGenLists(1);
+ glNewList(displist, GL_COMPILE);
+
+ qobj= gluNewQuadric();
+ gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+ gluDisk(qobj, 0, 0.7, 8, 1);
+ gluDeleteQuadric(qobj);
+
+ glEndList();
+ }
+
+ glPushMatrix();
+
+ glTranslatef(x, y, 0.0f);
+ glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f);
+ glCallList(displist);
+
+ glPopMatrix();
+}
+
+static void draw_graph_cfra(SpaceClip *sc, ARegion *ar, Scene *scene)
+{
+ View2D *v2d= &ar->v2d;
+ float xscale, yscale;
+ float vec[2];
+
+ /* Draw a light green line to indicate current frame */
+ vec[0]= (float)(sc->user.framenr * scene->r.framelen);
+
+ UI_ThemeColor(TH_CFRAME);
+ glLineWidth(2.0);
+
+ glBegin(GL_LINE_STRIP);
+ vec[1]= v2d->cur.ymin;
+ glVertex2fv(vec);
+
+ vec[1]= v2d->cur.ymax;
+ glVertex2fv(vec);
+ glEnd();
+
+ glLineWidth(1.0);
+
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+
+ /* because the frame number text is subject to the same scaling as the contents of the view */
+ UI_view2d_getscale(v2d, &xscale, &yscale);
+ glScalef(1.0f/xscale, 1.0f, 1.0f);
+
+ clip_draw_curfra_label(sc, (float)sc->user.framenr * xscale, 18);
+
+ /* restore view transform */
+ glScalef(xscale, 1.0, 1.0);
+}
+
+static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track),
+ MovieTrackingMarker *marker, int UNUSED(coord), float val)
+{
+ glVertex2f(marker->framenr, val);
+}
+
+void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
+{
+ static float colors[2][3] = {{1.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f}};
+ float col[4];
+
+ copy_v3_v3(col, colors[coord]);
+
+ if(track==userdata) {
+ col[3]= 1.0f;
+ glLineWidth(2.0f);
+ } else {
+ col[3]= 0.5f;
+ glLineWidth(1.0f);
+ }
+
+ glColor4fv(col);
+
+ glBegin(GL_LINE_STRIP);
+}
+
+void tracking_segment_end_cb(void *UNUSED(userdata))
+{
+ glEnd();
+
+ glLineWidth(1.0f);
+}
+
+static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker, int UNUSED(coord), float val)
+{
+ struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata;
+ int sel= 0;
+
+ if(track!=data->act_track)
+ return;
+
+ sel= (marker->flag&MARKER_GRAPH_SEL) ? 1 : 0;
+
+ if(sel == data->sel) {
+ if(sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT);
+ else UI_ThemeColor(TH_HANDLE_VERTEX);
+
+ draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize);
+ }
+}
+
+static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
+{
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ int width, height;
+ struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;
+
+ BKE_movieclip_get_size(clip, &sc->user, &width, &height);
+
+ if(!width || !height)
+ return;
+
+ /* non-selected knot handles */
+ userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
+ userdata.sel= 0;
+ userdata.act_track= clip->tracking.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);
+ glDisable(GL_BLEND);
+
+ /* selected knot handles on top of curves */
+ userdata.sel= 1;
+ clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
+}
+
+static void draw_frame_curves(SpaceClip *sc)
+{
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+ int i, lines= 0, prevfra= 0;
+
+ glColor3f(0.0f, 0.0f, 1.0f);
+
+ for(i= 0; i<reconstruction->camnr; i++) {
+ MovieReconstructedCamera *camera= &reconstruction->cameras[i];
+
+ if(lines && camera->framenr!=prevfra+1) {
+ glEnd();
+ lines= 0;
+ }
+
+ if(!lines) {
+ glBegin(GL_LINE_STRIP);
+ lines= 1;
+ }
+
+ glVertex2f(camera->framenr, camera->error);
+
+ prevfra= camera->framenr;
+ }
+
+ if(lines)
+ glEnd();
+}
+
+void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
+{
+ View2D *v2d= &ar->v2d;
+ View2DGrid *grid;
+ short unitx= V2D_UNIT_FRAMESCALE, unity= V2D_UNIT_VALUES;
+
+ /* grid */
+ grid= UI_view2d_grid_calc(scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
+ UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+ UI_view2d_grid_free(grid);
+
+ if(sc->flag&SC_SHOW_GRAPH_TRACKS)
+ draw_tracks_curves(v2d, sc);
+
+ if(sc->flag&SC_SHOW_GRAPH_FRAMES)
+ draw_frame_curves(sc);
+
+ /* current frame */
+ draw_graph_cfra(sc, ar, scene);
+}
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
new file mode 100644
index 00000000000..831b225386a
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -0,0 +1,356 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_graph_ops.c
+ * \ingroup spclip
+ */
+
+#include "DNA_object_types.h" /* SELECT */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "UI_interface.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "clip_intern.h" // own include
+
+/******************** common graph-editing utilities ********************/
+
+typedef struct {
+ int action;
+} SelectUserData;
+
+static void toggle_selection_cb(void *userdata, MovieTrackingMarker *marker)
+{
+ SelectUserData *data= (SelectUserData *)userdata;
+
+ switch(data->action) {
+ case SEL_SELECT:
+ marker->flag|= MARKER_GRAPH_SEL;
+ break;
+ case SEL_DESELECT:
+ marker->flag&= ~MARKER_GRAPH_SEL;
+ break;
+ case SEL_INVERT:
+ marker->flag^= MARKER_GRAPH_SEL;
+ break;
+ }
+}
+
+/******************** mouse select operator ********************/
+
+typedef struct {
+ int coord, /* coordinate index of found entuty (0 = X-axis, 1 = Y-axis) */
+ has_prev; /* if there's valid coordinate of previous point of curve segment */
+
+ float min_dist, /* minimal distance between mouse and currently found entuty */
+ mouse_co[2], /* mouse coordinate */
+ prev_co[2], /* coordinate of previeous point of segment */
+ min_co[2]; /* coordinate of entity with minimal distance */
+
+ MovieTrackingTrack *track; /* nearest found track */
+ MovieTrackingMarker *marker; /* nearest found marker */
+} MouseSelectUserData;
+
+static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker, int coord, float val)
+{
+ MouseSelectUserData *data= userdata;
+ float co[2]= {marker->framenr, val};
+
+ if(data->has_prev) {
+ float d= dist_to_line_segment_v2(data->mouse_co, data->prev_co, co);
+
+ if(data->track==NULL || d<data->min_dist) {
+ data->track= track;
+ data->min_dist= d;
+ data->coord= coord;
+ copy_v2_v2(data->min_co, co);
+ }
+ }
+
+ data->has_prev= 1;
+ copy_v2_v2(data->prev_co, co);
+}
+
+void find_nearest_tracking_segment_end_cb(void *userdata)
+{
+ MouseSelectUserData *data= userdata;
+
+ data->has_prev= 0;
+}
+
+static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker, int coord, float val)
+{
+ MouseSelectUserData *data= userdata;
+ float dx= marker->framenr-data->mouse_co[0], dy= val-data->mouse_co[1];
+ float d= dx*dx+dy*dy;
+
+ if(data->marker==NULL || d<data->min_dist) {
+ float co[2]= {marker->framenr, val};
+
+ data->track= track;
+ data->marker= marker;
+ data->min_dist= d;
+ data->coord= coord;
+ copy_v2_v2(data->min_co, co);
+ }
+
+}
+
+static void mouse_select_init_data(MouseSelectUserData *userdata, float *co)
+{
+ memset(userdata, 0, sizeof(MouseSelectUserData));
+ userdata->min_dist= FLT_MAX;
+ copy_v2_v2(userdata->mouse_co, co);
+}
+
+static int mouse_select_knot(bContext *C, float co[2], int extend)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ ARegion *ar= CTX_wm_region(C);
+ View2D *v2d= &ar->v2d;
+ MovieTracking *tracking= &clip->tracking;
+ static const int delta= 6;
+
+ if(tracking->act_track) {
+ MouseSelectUserData userdata;
+
+ mouse_select_init_data(&userdata, co);
+ clip_graph_tracking_values_iterate_track(sc, tracking->act_track,
+ &userdata, find_nearest_tracking_knot_cb, NULL, NULL);
+
+ if(userdata.marker) {
+ int x1, y1, x2, y2;
+
+ UI_view2d_view_to_region(v2d, co[0], co[1], &x1, &y1);
+ UI_view2d_view_to_region(v2d, userdata.min_co[0], userdata.min_co[1], &x2, &y2);
+
+ if(abs(x2-x1)<=delta && abs(y2-y1)<=delta) {
+ if(!extend) {
+ SelectUserData selectdata = {SEL_DESELECT};
+ clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb);
+ }
+
+ userdata.marker->flag|= MARKER_GRAPH_SEL;
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int mouse_select_curve(bContext *C, float co[2], int extend)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MouseSelectUserData userdata;
+
+ mouse_select_init_data(&userdata, co);
+ clip_graph_tracking_values_iterate(sc, &userdata, find_nearest_tracking_segment_cb, NULL, find_nearest_tracking_segment_end_cb);
+
+ if(userdata.track) {
+ if(extend) {
+ if(tracking->act_track==userdata.track) {
+ /* currently only single curve can be selected (selected curve represents active track) */
+ tracking->act_track= NULL;
+ }
+ }
+ else if(tracking->act_track!=userdata.track) {
+ MovieTrackingMarker *marker;
+ SelectUserData selectdata = {SEL_DESELECT};
+
+ tracking->act_track= userdata.track;
+
+ /* make active track be centered to screen */
+ marker= BKE_tracking_get_marker(userdata.track, sc->user.framenr);
+
+ clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]);
+
+ /* deselect all knots on newly selected curve */
+ clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int mouse_select(bContext *C, float co[2], int extend)
+{
+ int sel= 0;
+
+ /* first try to select knot on selected curves */
+ sel= mouse_select_knot(C, co, extend);
+
+ if(!sel) {
+ /* if there's no close enough knot to mouse osition, select nearest curve */
+ sel= mouse_select_curve(C, co, extend);
+ }
+
+ if(sel)
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int select_exec(bContext *C, wmOperator *op)
+{
+ float co[2];
+ int extend= RNA_boolean_get(op->ptr, "extend");
+
+ RNA_float_get_array(op->ptr, "location", co);
+
+ return mouse_select(C, co, extend);
+}
+
+static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ ARegion *ar= CTX_wm_region(C);
+ float co[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+ RNA_float_set_array(op->ptr, "location", co);
+
+ return select_exec(C, op);
+}
+
+void CLIP_OT_graph_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Select";
+ ot->description= "Select graph curves";
+ ot->idname= "CLIP_OT_graph_select";
+
+ /* api callbacks */
+ ot->exec= select_exec;
+ ot->invoke= select_invoke;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
+ "Location", "Mouse location to select nearest entity closest to", -100.0f, 100.0f);
+ RNA_def_boolean(ot->srna, "extend", 0,
+ "Extend", "Extend selection rather than clearing the existing selection");
+}
+
+/******************** delete curve operator ********************/
+
+static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+
+ if(tracking->act_track)
+ clip_delete_track(C, clip, tracking->act_track);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_graph_delete_curve(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Delete Curve";
+ ot->description= "Delete selected curves";
+ ot->idname= "CLIP_OT_graph_delete_curve";
+
+ /* api callbacks */
+ ot->invoke= WM_operator_confirm;
+ ot->exec= delete_curve_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/******************** delete knot operator ********************/
+
+static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+
+ if(tracking->act_track) {
+ int a= 0;
+ MovieTrackingTrack *track= tracking->act_track;
+
+ while(a<track->markersnr) {
+ MovieTrackingMarker *marker= &track->markers[a];
+
+ if(marker->flag&MARKER_GRAPH_SEL)
+ clip_delete_marker(C, clip, track, marker);
+ else
+ a++;
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_graph_delete_knot(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Delete Knot";
+ ot->description= "Delete curve knots";
+ ot->idname= "CLIP_OT_graph_delete_knot";
+
+ /* api callbacks */
+ ot->exec= delete_knot_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
new file mode 100644
index 00000000000..da0b589652e
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -0,0 +1,144 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_intern.h
+ * \ingroup spclip
+ */
+
+#ifndef ED_CLIP_INTERN_H
+#define ED_CLIP_INTERN_H
+
+struct bContext;
+struct ARegion;
+struct MovieClip;
+struct MovieTrackingMarker;
+struct MovieTrackingTrack;
+struct Scene;
+struct SpaceClip;
+struct wmOperatorType;
+
+/* internal exports only */
+
+/* clip_buttons.c */
+void ED_clip_buttons_register(struct ARegionType *art);
+
+/* clip_draw.c */
+void clip_draw_main(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene);
+void clip_draw_grease_pencil(struct bContext *C, int onlyv2d);
+void clip_draw_curfra_label(struct SpaceClip *sc, float x, float y);
+
+/* clip_graph_draw.c */
+void clip_draw_graph(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene);
+
+/* clip_graph_ops.c */
+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);
+
+/* clip_ops.c */
+void CLIP_OT_open(struct wmOperatorType *ot);
+void CLIP_OT_reload(struct wmOperatorType *ot);
+void CLIP_OT_view_pan(struct wmOperatorType *ot);
+void CLIP_OT_view_zoom(wmOperatorType *ot);
+void CLIP_OT_view_zoom_in(struct wmOperatorType *ot);
+void CLIP_OT_view_zoom_out(struct wmOperatorType *ot);
+void CLIP_OT_view_zoom_ratio(struct wmOperatorType *ot);
+void CLIP_OT_view_all(struct wmOperatorType *ot);
+void CLIP_OT_view_selected(struct wmOperatorType *ot);
+void CLIP_OT_change_frame(wmOperatorType *ot);
+void CLIP_OT_rebuild_proxy(struct wmOperatorType *ot);
+void CLIP_OT_mode_set(struct wmOperatorType *ot);
+
+/* clip_toolbar.c */
+void CLIP_OT_tools(struct wmOperatorType *ot);
+void CLIP_OT_properties(struct wmOperatorType *ot);
+void ED_clip_tool_props_register(struct ARegionType *art);
+
+/* clip_utils.c */
+void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata,
+ void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val),
+ void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord),
+ void (*segment_end) (void *userdata));
+
+void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata,
+ void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val),
+ void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord),
+ void (*segment_end) (void *userdata));
+
+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_view_center_to_point(struct SpaceClip *sc, float x, float y);
+
+/* tracking_ops.c */
+void CLIP_OT_select(struct wmOperatorType *ot);
+void CLIP_OT_select_all(struct wmOperatorType *ot);
+void CLIP_OT_select_border(struct wmOperatorType *ot);
+void CLIP_OT_select_circle(struct wmOperatorType *ot);
+void CLIP_OT_select_grouped(struct wmOperatorType *ot);
+
+void CLIP_OT_add_marker(struct wmOperatorType *ot);
+void CLIP_OT_delete_track(struct wmOperatorType *ot);
+void CLIP_OT_delete_marker(struct wmOperatorType *ot);
+
+void CLIP_OT_track_markers(struct wmOperatorType *ot);
+void CLIP_OT_solve_camera(struct wmOperatorType *ot);
+void CLIP_OT_clear_solution(struct wmOperatorType *ot);
+
+void CLIP_OT_clear_track_path(struct wmOperatorType *ot);
+void CLIP_OT_join_tracks(struct wmOperatorType *ot);
+
+void CLIP_OT_disable_markers(struct wmOperatorType *ot);
+void CLIP_OT_hide_tracks(struct wmOperatorType *ot);
+void CLIP_OT_hide_tracks_clear(struct wmOperatorType *ot);
+void CLIP_OT_lock_tracks(struct wmOperatorType *ot);
+
+void CLIP_OT_set_origin(struct wmOperatorType *ot);
+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_center_principal(struct wmOperatorType *ot);
+
+void CLIP_OT_slide_marker(struct wmOperatorType *ot);
+
+void CLIP_OT_frame_jump(struct wmOperatorType *ot);
+void CLIP_OT_track_copy_color(struct wmOperatorType *ot);
+
+void CLIP_OT_detect_features(struct wmOperatorType *ot);
+
+void CLIP_OT_stabilize_2d_add(struct wmOperatorType *ot);
+void CLIP_OT_stabilize_2d_remove(struct wmOperatorType *ot);
+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);
+
+#endif /* ED_CLIP_INTERN_H */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
new file mode 100644
index 00000000000..c52346fd4b6
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -0,0 +1,1004 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_ops.c
+ * \ingroup spclip
+ */
+
+#include <errno.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_userdef_types.h"
+#include "DNA_scene_types.h" /* min/max frames */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_report.h"
+#include "BKE_main.h"
+#include "BKE_library.h"
+#include "BKE_movieclip.h"
+#include "BKE_sound.h"
+#include "BKE_tracking.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "UI_interface.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "clip_intern.h" // own include
+
+/******************** view navigation utilities *********************/
+
+static void sclip_zoom_set(SpaceClip *sc, ARegion *ar, float zoom)
+{
+ float oldzoom= sc->zoom;
+ int width, height;
+
+ sc->zoom= zoom;
+
+ if (sc->zoom > 0.1f && sc->zoom < 4.0f)
+ return;
+
+ /* check zoom limits */
+ ED_space_clip_size(sc, &width, &height);
+
+ width*= sc->zoom;
+ height*= sc->zoom;
+
+ if((width < 4) && (height < 4))
+ sc->zoom= oldzoom;
+ else if((ar->winrct.xmax - ar->winrct.xmin) <= sc->zoom)
+ sc->zoom= oldzoom;
+ else if((ar->winrct.ymax - ar->winrct.ymin) <= sc->zoom)
+ sc->zoom= oldzoom;
+}
+
+static void sclip_zoom_set_factor(SpaceClip *sc, ARegion *ar, float zoomfac)
+{
+ sclip_zoom_set(sc, ar, sc->zoom*zoomfac);
+}
+
+
+/******************** open clip operator ********************/
+
+static void clip_filesel(bContext *C, wmOperator *op, const char *path)
+{
+ RNA_string_set(op->ptr, "filepath", path);
+ WM_event_add_fileselect(C, op);
+}
+
+static void open_init(bContext *C, wmOperator *op)
+{
+ PropertyPointerRNA *pprop;
+
+ op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
+ uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+}
+
+static int open_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
+static int open_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ PropertyPointerRNA *pprop;
+ PointerRNA idptr;
+ MovieClip *clip= NULL;
+ char str[FILE_MAX];
+
+ RNA_string_get(op->ptr, "filepath", str);
+ /* default to frame 1 if there's no scene in context */
+
+ errno= 0;
+
+ clip= BKE_add_movieclip_file(str);
+
+ if(!clip) {
+ if(op->customdata)
+ MEM_freeN(op->customdata);
+
+ BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, errno ? strerror(errno) : "Unsupported movie clip format");
+
+ return OPERATOR_CANCELLED;
+ }
+
+ if(!op->customdata)
+ open_init(C, op);
+
+ /* hook into UI */
+ pprop= op->customdata;
+
+ if(pprop->prop) {
+ /* when creating new ID blocks, use is already 1, but RNA
+ * pointer se also increases user, so this compensates it */
+ clip->id.us--;
+
+ RNA_id_pointer_create(&clip->id, &idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
+ RNA_property_update(C, &pprop->ptr, pprop->prop);
+ }
+ else if(sc) {
+ ED_space_clip_set(C, sc, clip);
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_ADDED, clip);
+
+ MEM_freeN(op->customdata);
+
+ return OPERATOR_FINISHED;
+}
+
+static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ char *path= U.textudir;
+ MovieClip *clip= NULL;
+
+ if(sc)
+ clip= ED_space_clip(sc);
+
+ if(clip)
+ path= clip->name;
+
+ if(!RNA_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"))
+ return open_exec(C, op);
+
+ open_init(C, op);
+
+ clip_filesel(C, op, path);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void CLIP_OT_open(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Open Clip";
+ ot->description= "Open clip";
+ ot->idname= "CLIP_OT_open";
+
+ /* api callbacks */
+ ot->exec= open_exec;
+ ot->invoke= open_invoke;
+ ot->cancel= open_cancel;
+
+ /* flags */
+ 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);
+}
+
+/******************* 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);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_reload(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Reload Clip";
+ ot->description= "Reload clip";
+ ot->idname= "CLIP_OT_reload";
+
+ /* api callbacks */
+ ot->exec= reload_exec;
+}
+
+/********************** view pan operator *********************/
+
+typedef struct ViewPanData {
+ float x, y;
+ float xof, yof, xorig, yorig;
+ int event_type;
+ float *vec;
+} ViewPanData;
+
+static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ViewPanData *vpd;
+
+ op->customdata= vpd= MEM_callocN(sizeof(ViewPanData), "ClipViewPanData");
+ WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR);
+
+ vpd->x= event->x;
+ vpd->y= event->y;
+
+ if(sc->flag&SC_LOCK_SELECTION) vpd->vec= &sc->xlockof;
+ else vpd->vec= &sc->xof;
+
+ copy_v2_v2(&vpd->xof, vpd->vec);
+ copy_v2_v2(&vpd->xorig, &vpd->xof);
+
+ vpd->event_type= event->type;
+
+ WM_event_add_modal_handler(C, op);
+}
+
+static void view_pan_exit(bContext *C, wmOperator *op, int cancel)
+{
+ ViewPanData *vpd= op->customdata;
+
+ if(cancel) {
+ copy_v2_v2(vpd->vec, &vpd->xorig);
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
+
+ WM_cursor_restore(CTX_wm_window(C));
+ MEM_freeN(op->customdata);
+}
+
+static int view_pan_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ float offset[2];
+
+ RNA_float_get_array(op->ptr, "offset", offset);
+
+ if(sc->flag&SC_LOCK_SELECTION) {
+ sc->xlockof+= offset[0];
+ sc->ylockof+= offset[1];
+ } else {
+ sc->xof+= offset[0];
+ sc->yof+= offset[1];
+ }
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (event->type==MOUSEPAN) {
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ float offset[2];
+
+ offset[0]= (event->x - event->prevx)/sc->zoom;
+ offset[1]= (event->y - event->prevy)/sc->zoom;
+
+ RNA_float_set_array(op->ptr, "offset", offset);
+
+ view_pan_exec(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ view_pan_init(C, op, event);
+ return OPERATOR_RUNNING_MODAL;
+ }
+}
+
+static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ViewPanData *vpd= op->customdata;
+ float offset[2];
+
+ switch(event->type) {
+ case MOUSEMOVE:
+ copy_v2_v2(vpd->vec, &vpd->xorig);
+ offset[0]= (vpd->x - event->x)/sc->zoom;
+ offset[1]= (vpd->y - event->y)/sc->zoom;
+ RNA_float_set_array(op->ptr, "offset", offset);
+ view_pan_exec(C, op);
+ break;
+ case ESCKEY:
+ view_pan_exit(C, op, 1);
+ return OPERATOR_CANCELLED;
+ case SPACEKEY:
+ view_pan_exit(C, op, 0);
+ return OPERATOR_FINISHED;
+ default:
+ if(event->type==vpd->event_type && event->val==KM_RELEASE) {
+ view_pan_exit(C, op, 0);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int view_pan_cancel(bContext *C, wmOperator *op)
+{
+ view_pan_exit(C, op, 1);
+
+ return OPERATOR_CANCELLED;
+}
+
+void CLIP_OT_view_pan(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View Pan";
+ ot->idname= "CLIP_OT_view_pan";
+
+ /* api callbacks */
+ ot->exec= view_pan_exec;
+ ot->invoke= view_pan_invoke;
+ ot->modal= view_pan_modal;
+ ot->cancel= view_pan_cancel;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_BLOCKING;
+
+ /* properties */
+ RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX,
+ "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX);
+}
+
+/********************** view zoom operator *********************/
+
+typedef struct ViewZoomData {
+ float x, y;
+ float zoom;
+ int event_type;
+} ViewZoomData;
+
+static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ViewZoomData *vpd;
+
+ op->customdata= vpd= MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData");
+ WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR);
+
+ vpd->x= event->x;
+ vpd->y= event->y;
+ vpd->zoom= sc->zoom;
+ vpd->event_type= event->type;
+
+ WM_event_add_modal_handler(C, op);
+}
+
+static void view_zoom_exit(bContext *C, wmOperator *op, int cancel)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ViewZoomData *vpd= op->customdata;
+
+ if(cancel) {
+ sc->zoom= vpd->zoom;
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
+
+ WM_cursor_restore(CTX_wm_window(C));
+ MEM_freeN(op->customdata);
+}
+
+static int view_zoom_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ sclip_zoom_set_factor(sc, ar, RNA_float_get(op->ptr, "factor"));
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (event->type==MOUSEZOOM) {
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+ float factor;
+
+ factor= 1.0f + (event->x-event->prevx+event->y-event->prevy)/300.0f;
+ RNA_float_set(op->ptr, "factor", factor);
+ sclip_zoom_set(sc, ar, sc->zoom*factor);
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ view_zoom_init(C, op, event);
+ return OPERATOR_RUNNING_MODAL;
+ }
+}
+
+static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+ ViewZoomData *vpd= op->customdata;
+ float factor;
+
+ switch(event->type) {
+ case MOUSEMOVE:
+ factor= 1.0f + (vpd->x-event->x+vpd->y-event->y)/300.0f;
+ RNA_float_set(op->ptr, "factor", factor);
+ sclip_zoom_set(sc, ar, vpd->zoom*factor);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ break;
+ default:
+ if(event->type==vpd->event_type && event->val==KM_RELEASE) {
+ view_zoom_exit(C, op, 0);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int view_zoom_cancel(bContext *C, wmOperator *op)
+{
+ view_zoom_exit(C, op, 1);
+ return OPERATOR_CANCELLED;
+}
+
+void CLIP_OT_view_zoom(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View Zoom";
+ ot->idname= "CLIP_OT_view_zoom";
+
+ /* api callbacks */
+ ot->exec= view_zoom_exec;
+ ot->invoke= view_zoom_invoke;
+ ot->modal= view_zoom_modal;
+ ot->cancel= view_zoom_cancel;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
+
+ /* properties */
+ RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX,
+ "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX);
+}
+
+/********************** view zoom in/out operator *********************/
+
+static int view_zoom_in_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ sclip_zoom_set_factor(sc, ar, 1.25f);
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static int view_zoom_out_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ sclip_zoom_set_factor(sc, ar, 0.8f);
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+static int view_zoom_inout_invoke(bContext *C, wmOperator *op, wmEvent *event, int out)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ float co[2], oldzoom= sc->zoom;
+
+ ED_clip_mouse_pos(C, event, co);
+
+ if(out)
+ view_zoom_out_exec(C, op);
+ else
+ view_zoom_in_exec(C, op);
+
+ if(U.uiflag&USER_ZOOM_TO_MOUSEPOS) {
+ int width, height;
+
+ ED_space_clip_size(sc, &width, &height);
+
+ sc->xof+= ((co[0]-0.5)*width-sc->xof)*(sc->zoom-oldzoom)/sc->zoom;
+ sc->yof+= ((co[1]-0.5)*height-sc->yof)*(sc->zoom-oldzoom)/sc->zoom;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return view_zoom_inout_invoke(C, op, event, 0);
+}
+
+void CLIP_OT_view_zoom_in(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View Zoom In";
+ ot->idname= "CLIP_OT_view_zoom_in";
+
+ /* api callbacks */
+ ot->exec= view_zoom_in_exec;
+ ot->invoke= view_zoom_in_invoke;
+ ot->poll= ED_space_clip_poll;
+}
+
+static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return view_zoom_inout_invoke(C, op, event, 1);
+}
+
+void CLIP_OT_view_zoom_out(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View Zoom Out";
+ ot->idname= "CLIP_OT_view_zoom_out";
+
+ /* api callbacks */
+ ot->exec= view_zoom_out_exec;
+ ot->invoke= view_zoom_out_invoke;
+ ot->poll= ED_space_clip_poll;
+}
+
+/********************** view zoom ratio operator *********************/
+
+static int view_zoom_ratio_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ sclip_zoom_set(sc, ar, RNA_float_get(op->ptr, "ratio"));
+
+ /* ensure pixel exact locations for draw */
+ sc->xof= (int)sc->xof;
+ sc->yof= (int)sc->yof;
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_view_zoom_ratio(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View Zoom Ratio";
+ ot->idname= "CLIP_OT_view_zoom_ratio";
+
+ /* api callbacks */
+ ot->exec= view_zoom_ratio_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* properties */
+ RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX,
+ "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
+}
+
+/********************** view all operator *********************/
+
+static int view_all_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc;
+ ARegion *ar;
+ int w, h, width, height;
+ float aspx, aspy;
+
+ /* retrieve state */
+ sc= CTX_wm_space_clip(C);
+ ar= CTX_wm_region(C);
+
+ ED_space_clip_size(sc, &w, &h);
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ w= w*aspx;
+ h= h*aspy;
+
+ /* check if the image will fit in the image with zoom==1 */
+ width= ar->winrct.xmax - ar->winrct.xmin + 1;
+ height= ar->winrct.ymax - ar->winrct.ymin + 1;
+
+ if((w >= width || h >= height) && (width > 0 && height > 0)) {
+ float zoomx, zoomy;
+
+ /* find the zoom value that will fit the image in the image space */
+ zoomx= (float)width/w;
+ zoomy= (float)height/h;
+ sclip_zoom_set(sc, ar, 1.0f/power_of_2(1/MIN2(zoomx, zoomy)));
+ }
+ else
+ sclip_zoom_set(sc, ar, 1.0f);
+
+ sc->xof= sc->yof= 0.0f;
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_view_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View All";
+ ot->idname= "CLIP_OT_view_all";
+
+ /* api callbacks */
+ ot->exec= view_all_exec;
+ ot->poll= ED_space_clip_poll;
+}
+
+/********************** view selected operator *********************/
+
+static int view_selected_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ sc->xlockof= 0.0f;
+ sc->ylockof= 0.0f;
+
+ ED_clip_view_selection(sc, ar, 1);
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_view_selected(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "View Selected";
+ ot->idname= "CLIP_OT_view_selected";
+
+ /* api callbacks */
+ ot->exec= view_selected_exec;
+ ot->poll= ED_space_clip_poll;
+}
+
+/********************** change frame operator *********************/
+
+static int change_frame_poll(bContext *C)
+{
+ /* prevent changes during render */
+ if(G.rendering)
+ return 0;
+
+ return ED_space_clip_poll(C);
+}
+
+static void change_frame_apply(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ /* set the new frame number */
+ CFRA= RNA_int_get(op->ptr, "frame");
+ FRAMENUMBER_MIN_CLAMP(CFRA);
+ SUBFRA = 0.0f;
+
+ /* do updates */
+ sound_seek_scene(CTX_data_main(C), CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+}
+
+static int change_frame_exec(bContext *C, wmOperator *op)
+{
+ change_frame_apply(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+static int frame_from_event(bContext *C, wmEvent *event)
+{
+ ARegion *ar= CTX_wm_region(C);
+ Scene *scene= CTX_data_scene(C);
+ int framenr= 0;
+
+ if(ar->regiontype == RGN_TYPE_WINDOW) {
+ float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1);
+
+ framenr= sfra+event->mval[0]/framelen;
+ } else {
+ float viewx, viewy;
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
+
+ framenr= (int)floor(viewx+0.5f);
+ }
+
+ return framenr;
+}
+
+static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ ARegion *ar= CTX_wm_region(C);
+
+ if(ar->regiontype == RGN_TYPE_WINDOW) {
+ if(event->mval[1]>16)
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
+
+ change_frame_apply(C, op);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ switch (event->type) {
+ case ESCKEY:
+ return OPERATOR_FINISHED;
+
+ case MOUSEMOVE:
+ RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
+ change_frame_apply(C, op);
+ break;
+
+ case LEFTMOUSE:
+ case RIGHTMOUSE:
+ if (event->val==KM_RELEASE)
+ return OPERATOR_FINISHED;
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void CLIP_OT_change_frame(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Change frame";
+ ot->idname= "CLIP_OT_change_frame";
+ ot->description= "Interactively change the current frame number";
+
+ /* api callbacks */
+ ot->exec= change_frame_exec;
+ ot->invoke= change_frame_invoke;
+ ot->modal= change_frame_modal;
+ ot->poll= change_frame_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_UNDO;
+
+ /* rna */
+ RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
+}
+
+/********************** rebuild proxies operator *********************/
+
+typedef struct ProxyBuildJob {
+ Scene *scene;
+ struct Main *main;
+ MovieClip *clip;
+} ProxyJob;
+
+static void proxy_freejob(void *pjv)
+{
+ ProxyJob *pj= pjv;
+
+ MEM_freeN(pj);
+}
+
+/* only this runs inside thread */
+static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+{
+ ProxyJob *pj= pjv;
+ 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;
+ int build_sizes[4], build_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;
+
+ 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) {
+ return;
+ }
+ else {
+ sfra= 1;
+ efra= IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+ }
+ }
+
+ 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)
+ 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);
+
+ if(undistort)
+ BKE_movieclip_build_proxy_frame(clip, distortion, cfra, build_sizes, build_count, 1);
+
+ if(*stop || G.afbreek)
+ break;
+
+ *do_update= 1;
+ *progress= ((float)cfra)/(efra-sfra);
+ }
+
+ if(distortion)
+ BKE_tracking_distortion_destroy(distortion);
+}
+
+static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ wmJob * steve;
+ ProxyJob *pj;
+ Scene *scene= CTX_data_scene(C);
+ ScrArea *sa= CTX_wm_area(C);
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+
+ if((clip->flag&MCLIP_USE_PROXY)==0)
+ return OPERATOR_CANCELLED;
+
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies", WM_JOB_PROGRESS);
+
+ pj= MEM_callocN(sizeof(ProxyJob), "proxy rebuild job");
+ pj->scene= scene;
+ pj->main= CTX_data_main(C);
+ pj->clip= clip;
+
+ WM_jobs_customdata(steve, pj, proxy_freejob);
+ WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|ND_DISPLAY, 0);
+ WM_jobs_callbacks(steve, proxy_startjob, NULL, NULL, NULL);
+
+ G.afbreek= 0;
+ WM_jobs_start(CTX_wm_manager(C), steve);
+
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_rebuild_proxy(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Rebuild Proxy and Timecode Indices";
+ ot->idname= "CLIP_OT_rebuild_proxy";
+ ot->description="Rebuild all selected proxies and timecode indeces using the job system";
+
+ /* api callbacks */
+ ot->exec= sequencer_rebuild_proxy_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER;
+}
+
+/********************** mode set operator *********************/
+
+static int mode_set_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ int mode= RNA_enum_get(op->ptr, "mode");
+ int toggle= RNA_boolean_get(op->ptr, "toggle");
+
+ if(sc->mode==mode) {
+ if(toggle)
+ sc->mode= SC_MODE_TRACKING;
+ } else {
+ sc->mode= mode;
+ }
+
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_mode_set(wmOperatorType *ot)
+{
+ static EnumPropertyItem mode_items[] = {
+ {SC_MODE_TRACKING, "TRACKING", 0, "Tracking", "Show tracking and solving tools"},
+ {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", 0, "Reconstruction", "Show tracking/reconstruction tools"},
+ {SC_MODE_DISTORTION, "DISTORTION", 0, "Distortion", "Show distortion tools"},
+ {0, NULL, 0, NULL, NULL}};
+
+
+ /* identifiers */
+ ot->name= "Set Clip Mode";
+ ot->description = "Sets the clip interaction mode";
+ ot->idname= "CLIP_OT_mode_set";
+
+ /* api callbacks */
+ ot->exec= mode_set_exec;
+
+ ot->poll= ED_space_clip_poll;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "mode", mode_items, SC_MODE_TRACKING, "Mode", "");
+ RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");
+}
+
+/********************** macroses *********************/
+
+void ED_operatormacros_clip(void)
+{
+ wmOperatorType *ot;
+ wmOperatorTypeMacro *otmacro;
+
+ ot= WM_operatortype_append_macro("CLIP_OT_add_marker_move", "Add Marker and Move", OPTYPE_UNDO|OPTYPE_REGISTER);
+ ot->description = "Add new marker and move it on movie";
+ WM_operatortype_macro_define(ot, "CLIP_OT_add_marker");
+ otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_struct_idprops_unset(otmacro->ptr, "release_confirm");
+
+ ot= WM_operatortype_append_macro("CLIP_OT_add_marker_slide", "Add Marker and Slide", OPTYPE_UNDO|OPTYPE_REGISTER);
+ 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);
+}
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
new file mode 100644
index 00000000000..c8113c5ea7b
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -0,0 +1,244 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_header.c
+ * \ingroup spclip
+ */
+
+#include <string.h>
+
+#include "DNA_windowmanager_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+
+#include "ED_screen.h"
+#include "ED_util.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+/* ************************ header area region *********************** */
+
+/************************** properties ******************************/
+
+static ARegion *clip_has_properties_region(ScrArea *sa)
+{
+ ARegion *ar, *arnew;
+
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if(ar)
+ return ar;
+
+ /* add subdiv level; after header */
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+
+ /* is error! */
+ if(ar==NULL)
+ return NULL;
+
+ arnew= MEM_callocN(sizeof(ARegion), "clip properties region");
+
+ BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+ arnew->regiontype= RGN_TYPE_UI;
+ arnew->alignment= RGN_ALIGN_RIGHT;
+
+ arnew->flag= RGN_FLAG_HIDDEN;
+
+ return arnew;
+}
+
+static int properties_poll(bContext *C)
+{
+ return (CTX_wm_space_clip(C) != NULL);
+}
+
+static int properties_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= clip_has_properties_region(sa);
+
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_properties(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Properties";
+ ot->description= "Toggle clip properties panel";
+ ot->idname= "CLIP_OT_properties";
+
+ /* api callbacks */
+ ot->exec= properties_exec;
+ ot->poll= properties_poll;
+}
+
+/************************** tools ******************************/
+
+static ARegion *clip_has_tools_region(ScrArea *sa)
+{
+ ARegion *ar, *artool=NULL, *arprops=NULL, *arhead;
+
+ for(ar= sa->regionbase.first; ar; ar= ar->next) {
+ if(ar->regiontype==RGN_TYPE_TOOLS)
+ artool= ar;
+ if(ar->regiontype==RGN_TYPE_TOOL_PROPS)
+ arprops= ar;
+ }
+
+ /* tool region hide/unhide also hides props */
+ if(arprops && artool)
+ return artool;
+
+ if(artool==NULL) {
+ /* add subdiv level; after header */
+ arhead= BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
+
+ /* is error! */
+ if(arhead==NULL)
+ return NULL;
+
+ artool= MEM_callocN(sizeof(ARegion), "clip tools region");
+
+ BLI_insertlinkafter(&sa->regionbase, arhead, artool);
+ artool->regiontype= RGN_TYPE_TOOLS;
+ artool->alignment= RGN_ALIGN_LEFT;
+
+ artool->flag= RGN_FLAG_HIDDEN;
+ }
+
+ if(arprops==NULL) {
+ /* add extra subdivided region for tool properties */
+ arprops= MEM_callocN(sizeof(ARegion), "tool props for clip");
+
+ BLI_insertlinkafter(&sa->regionbase, artool, arprops);
+ arprops->regiontype= RGN_TYPE_TOOL_PROPS;
+ arprops->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
+ }
+
+ return artool;
+}
+
+static int tools_poll(bContext *C)
+{
+ return (CTX_wm_space_clip(C) != NULL);
+}
+
+static int tools_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= clip_has_tools_region(sa);
+
+ if(ar)
+ ED_region_toggle_hidden(C, ar);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_tools(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Tools";
+ ot->description= "Toggle clip tools panel";
+ ot->idname= "CLIP_OT_tools";
+
+ /* api callbacks */
+ ot->exec= tools_exec;
+ ot->poll= tools_poll;
+}
+
+/************************** redo panel ******************************/
+
+static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
+{
+ uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0);
+}
+
+static void clip_panel_operator_redo_header(const bContext *C, Panel *pa)
+{
+ wmOperator *op= WM_operator_last_redo(C);
+
+ if(op) BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
+ else BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname));
+}
+
+static void clip_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op)
+{
+ if(op->type->flag & OPTYPE_MACRO) {
+ for(op= op->macro.first; op; op= op->next) {
+ uiItemL(pa->layout, op->type->name, ICON_NONE);
+ clip_panel_operator_redo_operator(C, pa, op);
+ }
+ }
+ else {
+ clip_panel_operator_redo_buts(C, pa, op);
+ }
+}
+
+static void clip_panel_operator_redo(const bContext *C, Panel *pa)
+{
+ wmOperator *op= WM_operator_last_redo(C);
+ uiBlock *block;
+
+ if(op==NULL)
+ return;
+ if(WM_operator_poll((bContext*)C, op->type) == 0)
+ return;
+
+ block= uiLayoutGetBlock(pa->layout);
+
+ if(ED_undo_valid(C, op->type->name)==0)
+ uiLayoutSetEnabled(pa->layout, 0);
+
+ /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
+ uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
+
+ clip_panel_operator_redo_operator(C, pa, op);
+}
+
+void ED_clip_tool_props_register(ARegionType *art)
+{
+ PanelType *pt;
+
+ pt= MEM_callocN(sizeof(PanelType), "spacetype clip panel last operator");
+ strcpy(pt->idname, "CLIP_PT_last_operator");
+ strcpy(pt->label, "Operator");
+ pt->draw_header= clip_panel_operator_redo_header;
+ pt->draw= clip_panel_operator_redo;
+ BLI_addtail(&art->paneltypes, pt);
+}
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
new file mode 100644
index 00000000000..649b278ab3d
--- /dev/null
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -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.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/clip_utils.c
+ * \ingroup spclip
+ */
+
+#include "DNA_object_types.h" /* SELECT */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+#include "BKE_depsgraph.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+
+#include "UI_interface.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "clip_intern.h" // own include
+
+void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata,
+ void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val),
+ void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord),
+ void (*segment_end) (void *userdata))
+{
+ MovieClip *clip= ED_space_clip(sc);
+ int width, height, coord;
+
+ BKE_movieclip_get_size(clip, &sc->user, &width, &height);
+
+ for(coord= 0; coord<2; coord++) {
+ int i, open= 0, prevfra= 0;
+ float prevval= 0.0f;
+
+ for(i= 0; i<track->markersnr; i++) {
+ MovieTrackingMarker *marker= &track->markers[i];
+ float val;
+
+ if(marker->flag&MARKER_DISABLED) {
+ if(open) {
+ if(segment_end)
+ segment_end(userdata);
+
+ open= 0;
+ }
+
+ continue;
+ }
+
+ if(!open) {
+ if(segment_start)
+ segment_start(userdata, track, coord);
+
+ open= 1;
+ prevval= marker->pos[coord];
+ }
+
+ /* value is a pixels per frame speed */
+ val= (marker->pos[coord] - prevval) * ((i==0) ? (width) : (height));
+ val/= marker->framenr-prevfra;
+
+ if(func)
+ func(userdata, track, marker, coord, val);
+
+ prevval= marker->pos[coord];
+ prevfra= marker->framenr;
+ }
+
+ if(open) {
+ if(segment_end)
+ segment_end(userdata);
+ }
+ }
+}
+
+void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata,
+ void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val),
+ void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord),
+ void (*segment_end) (void *userdata))
+{
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end);
+ }
+
+ track= track->next;
+ }
+}
+
+void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata,
+ void (*func) (void *userdata, MovieTrackingMarker *marker))
+{
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ int i;
+
+ for(i= 0; i<track->markersnr; i++) {
+ MovieTrackingMarker *marker= &track->markers[i];
+
+ if(marker->flag&MARKER_DISABLED)
+ continue;
+
+ if(func)
+ func(userdata, marker);
+ }
+ }
+
+ track= track->next;
+ }
+}
+
+void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
+{
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+
+ int has_bundle= 0, update_stab= 0;
+
+ if(track==tracking->act_track)
+ tracking->act_track= NULL;
+
+ if(track==stab->rot_track) {
+ stab->rot_track= NULL;
+
+ update_stab= 1;
+ }
+
+ /* handle reconstruction display in 3d viewport */
+ if(track->flag&TRACK_HAS_BUNDLE)
+ has_bundle= 1;
+
+ BKE_tracking_free_track(track);
+ BLI_freelinkN(&tracking->tracks, track);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+ if(update_stab) {
+ tracking->stabilization.ok= 0;
+
+ DAG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+ }
+
+ if(has_bundle)
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+}
+
+void clip_delete_marker(bContext *C, MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker)
+{
+ if(track->markersnr==1) {
+ clip_delete_track(C, clip, track);
+ }
+ else {
+ BKE_tracking_delete_marker(track, marker->framenr);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+ }
+}
+
+void clip_view_center_to_point(SpaceClip *sc, float x, float y)
+{
+ int width, height;
+ float aspx, aspy;
+
+ ED_space_clip_size(sc, &width, &height);
+ ED_space_clip_aspect(sc, &aspx, &aspy);
+
+ sc->xof= (x-0.5f)*width*aspx;
+ sc->yof= (y-0.5f)*height*aspy;
+}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
new file mode 100644
index 00000000000..c8577f7760e
--- /dev/null
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -0,0 +1,949 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/space_clip.c
+ * \ingroup spclip
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "DNA_scene_types.h"
+#include "DNA_movieclip_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BKE_main.h"
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+#include "ED_transform.h"
+
+#include "IMB_imbuf.h"
+
+#include "BIF_gl.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "RNA_access.h"
+
+
+#include "clip_intern.h" // own include
+
+static void init_preview_region(const bContext *C, ARegion *ar)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ ar->regiontype= RGN_TYPE_PREVIEW;
+ ar->alignment= RGN_ALIGN_TOP;
+ ar->flag|= RGN_FLAG_HIDDEN;
+
+ ar->v2d.tot.xmin= 0.0f;
+ ar->v2d.tot.ymin= (float)scene->r.sfra - 10.0f;
+ ar->v2d.tot.xmax= (float)scene->r.efra;
+ ar->v2d.tot.ymax= 10.0f;
+
+ ar->v2d.cur= ar->v2d.tot;
+
+ ar->v2d.min[0]= FLT_MIN;
+ ar->v2d.min[1]= FLT_MIN;
+
+ ar->v2d.max[0]= MAXFRAMEF;
+ ar->v2d.max[1]= FLT_MAX;
+
+ ar->v2d.scroll= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
+
+ ar->v2d.keeptot= 0;
+}
+
+static ARegion *clip_has_preview_region(const bContext *C, ScrArea *sa)
+{
+ ARegion *ar, *arnew;
+
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
+ if(ar)
+ return ar;
+
+ /* add subdiv level; after header */
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+
+ /* is error! */
+ if(ar==NULL)
+ return NULL;
+
+ arnew= MEM_callocN(sizeof(ARegion), "clip preview region");
+
+ BLI_insertlinkbefore(&sa->regionbase, ar, arnew);
+ init_preview_region(C, arnew);
+
+ return arnew;
+}
+
+static void clip_scopes_tag_refresh(ScrArea *sa)
+{
+ SpaceClip *sc= (SpaceClip *)sa->spacedata.first;
+ ARegion *ar;
+
+ if(sc->mode!=SC_MODE_TRACKING)
+ return;
+
+ /* only while proeprties are visible */
+ for (ar=sa->regionbase.first; ar; ar=ar->next) {
+ if (ar->regiontype == RGN_TYPE_UI && ar->flag & RGN_FLAG_HIDDEN)
+ return;
+ }
+
+ sc->scopes.ok= 0;
+}
+
+static void clip_stabilization_tag_refresh(ScrArea *sa)
+{
+ SpaceClip *sc= (SpaceClip *)sa->spacedata.first;
+ MovieClip *clip= ED_space_clip(sc);
+
+ if(clip) {
+ MovieTrackingStabilization *stab= &clip->tracking.stabilization;
+
+ stab->ok= 0;
+ }
+}
+
+/* ******************** default callbacks for clip space ***************** */
+
+static SpaceLink *clip_new(const bContext *C)
+{
+ ARegion *ar;
+ SpaceClip *sc;
+
+ 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->zoom= 1.0f;
+ sc->path_length= 20;
+ sc->scopes.track_preview_height= 120;
+
+ /* header */
+ ar= MEM_callocN(sizeof(ARegion), "header for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ ar->regiontype= RGN_TYPE_HEADER;
+ ar->alignment= RGN_ALIGN_BOTTOM;
+
+ /* tools view */
+ ar= MEM_callocN(sizeof(ARegion), "tools for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ ar->regiontype= RGN_TYPE_TOOLS;
+ ar->alignment= RGN_ALIGN_LEFT;
+
+ /* tool properties */
+ ar= MEM_callocN(sizeof(ARegion), "tool properties for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ ar->regiontype= RGN_TYPE_TOOL_PROPS;
+ ar->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
+
+ /* properties view */
+ ar= MEM_callocN(sizeof(ARegion), "properties for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ ar->regiontype= RGN_TYPE_UI;
+ ar->alignment= RGN_ALIGN_RIGHT;
+
+ /* preview view */
+ ar= MEM_callocN(sizeof(ARegion), "preview for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ init_preview_region(C, ar);
+
+ /* main area */
+ ar= MEM_callocN(sizeof(ARegion), "main area for clip");
+
+ BLI_addtail(&sc->regionbase, ar);
+ ar->regiontype= RGN_TYPE_WINDOW;
+
+ return (SpaceLink *)sc;
+}
+
+/* not spacelink itself */
+static void clip_free(SpaceLink *sl)
+{
+ SpaceClip *sc= (SpaceClip*) sl;
+
+ sc->clip= NULL;
+
+ if(sc->scopes.track_preview)
+ IMB_freeImBuf(sc->scopes.track_preview);
+}
+
+/* spacetype; init callback */
+static void clip_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
+{
+
+}
+
+static SpaceLink *clip_duplicate(SpaceLink *sl)
+{
+ SpaceClip *scn= MEM_dupallocN(sl);
+
+ /* clear or remove stuff from old */
+ scn->scopes.track_preview= NULL;
+ scn->scopes.ok= 0;
+
+ return (SpaceLink *)scn;
+}
+
+static void clip_listener(ScrArea *sa, wmNotifier *wmn)
+{
+ /* context changes */
+ switch(wmn->category) {
+ case NC_SCENE:
+ switch(wmn->data) {
+ case ND_FRAME:
+ clip_scopes_tag_refresh(sa);
+ /* no break! */
+
+ case ND_FRAME_RANGE:
+ ED_area_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
+ case NC_MOVIECLIP:
+ switch(wmn->data) {
+ case ND_DISPLAY:
+ case ND_SELECT:
+ clip_scopes_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ switch(wmn->action) {
+ case NA_REMOVED:
+ case NA_EDITED:
+ case NA_EVALUATED:
+ clip_stabilization_tag_refresh(sa);
+ /* no break! */
+
+ case NA_SELECTED:
+ clip_scopes_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
+ case NC_GEOM:
+ switch(wmn->data) {
+ case ND_SELECT:
+ clip_scopes_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
+ case NC_SCREEN:
+ if(wmn->data==ND_ANIMPLAY) {
+ ED_area_tag_redraw(sa);
+ }
+ break;
+ case NC_SPACE:
+ if(wmn->data==ND_SPACE_CLIP) {
+ clip_scopes_tag_refresh(sa);
+ clip_stabilization_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ }
+ break;
+ }
+}
+
+static void clip_operatortypes(void)
+{
+ /* ** clip_ops.c ** */
+ WM_operatortype_append(CLIP_OT_open);
+ WM_operatortype_append(CLIP_OT_reload);
+ WM_operatortype_append(CLIP_OT_view_pan);
+ WM_operatortype_append(CLIP_OT_view_zoom);
+ WM_operatortype_append(CLIP_OT_view_zoom_in);
+ WM_operatortype_append(CLIP_OT_view_zoom_out);
+ WM_operatortype_append(CLIP_OT_view_zoom_ratio);
+ WM_operatortype_append(CLIP_OT_view_all);
+ WM_operatortype_append(CLIP_OT_view_selected);
+ WM_operatortype_append(CLIP_OT_change_frame);
+ WM_operatortype_append(CLIP_OT_rebuild_proxy);
+ WM_operatortype_append(CLIP_OT_mode_set);
+
+ /* ** clip_toolbar.c ** */
+ WM_operatortype_append(CLIP_OT_tools);
+ WM_operatortype_append(CLIP_OT_properties);
+
+ /* ** tracking_ops.c ** */
+
+ /* navigation */
+ WM_operatortype_append(CLIP_OT_frame_jump);
+
+ /* foorage */
+ WM_operatortype_append(CLIP_OT_set_center_principal);
+
+ /* selection */
+ WM_operatortype_append(CLIP_OT_select);
+ WM_operatortype_append(CLIP_OT_select_all);
+ WM_operatortype_append(CLIP_OT_select_border);
+ WM_operatortype_append(CLIP_OT_select_circle);
+ WM_operatortype_append(CLIP_OT_select_grouped);
+
+ /* markers */
+ WM_operatortype_append(CLIP_OT_add_marker);
+ WM_operatortype_append(CLIP_OT_slide_marker);
+ WM_operatortype_append(CLIP_OT_delete_track);
+ WM_operatortype_append(CLIP_OT_delete_marker);
+
+ /* track */
+ WM_operatortype_append(CLIP_OT_track_markers);
+
+ /* solving */
+ WM_operatortype_append(CLIP_OT_solve_camera);
+ WM_operatortype_append(CLIP_OT_clear_solution);
+
+ WM_operatortype_append(CLIP_OT_disable_markers);
+ WM_operatortype_append(CLIP_OT_hide_tracks);
+ WM_operatortype_append(CLIP_OT_hide_tracks_clear);
+ WM_operatortype_append(CLIP_OT_lock_tracks);
+
+ /* orientation */
+ WM_operatortype_append(CLIP_OT_set_origin);
+ WM_operatortype_append(CLIP_OT_set_floor);
+ WM_operatortype_append(CLIP_OT_set_axis);
+ WM_operatortype_append(CLIP_OT_set_scale);
+
+ /* detect */
+ WM_operatortype_append(CLIP_OT_detect_features);
+
+ /* stabilization */
+ WM_operatortype_append(CLIP_OT_stabilize_2d_add);
+ WM_operatortype_append(CLIP_OT_stabilize_2d_remove);
+ WM_operatortype_append(CLIP_OT_stabilize_2d_select);
+ WM_operatortype_append(CLIP_OT_stabilize_2d_set_rotation);
+
+ /* clean-up */
+ WM_operatortype_append(CLIP_OT_clear_track_path);
+ WM_operatortype_append(CLIP_OT_join_tracks);
+ WM_operatortype_append(CLIP_OT_track_copy_color);
+
+ WM_operatortype_append(CLIP_OT_clean_tracks);
+
+ /* graph editing */
+ WM_operatortype_append(CLIP_OT_graph_select);
+ WM_operatortype_append(CLIP_OT_graph_delete_curve);
+ WM_operatortype_append(CLIP_OT_graph_delete_knot);
+}
+
+static void clip_keymap(struct wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap;
+ wmKeyMapItem *kmi;
+
+ /* ******** Global hotkeys avalaible for all regions ******** */
+
+ keymap= WM_keymap_find(keyconf, "Clip", SPACE_CLIP, 0);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_tools", TKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_properties", NKEY, KM_PRESS, 0, 0);
+
+ /* 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);
+ 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);
+ 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);
+
+ /* 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);
+
+ 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);
+
+ /* ******** Hotkeys avalaible for main region only ******** */
+
+ keymap= WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);
+
+ /* ** View/navigation ** */
+
+ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MOUSEPAN, 0, 0, 0);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
+
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
+ RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
+
+ /* jump to special frame */
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "position", 0);
+
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "position", 1);
+
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "position", 2);
+
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "position", 3);
+
+ /* "timeline" */
+ 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);
+ 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);
+
+ /* marker */
+ WM_keymap_add_item(keymap, "CLIP_OT_add_marker_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", DELKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", XKEY, KM_PRESS, KM_SHIFT, 0);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0);
+
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "action", 2); /* toggle */
+
+ /* tracks */
+ WM_keymap_add_item(keymap, "CLIP_OT_delete_track", DELKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_delete_track", XKEY, KM_PRESS, 0, 0);
+
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "action", 0); /* lock */
+
+ 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, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", 1);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0);
+
+ /* clean-up */
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
+ kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
+
+ WM_keymap_add_item(keymap, "CLIP_OT_join_tracks", JKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* menus */
+ WM_keymap_add_menu(keymap, "CLIP_MT_tracking_specials", WKEY, KM_PRESS, 0, 0);
+
+ /* display */
+ 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", MKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.use_mute_footage");
+
+ transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
+
+ /* ******** Hotkeys avalaible for preview region only ******** */
+
+ keymap= WM_keymap_find(keyconf, "Clip Graph Editor", SPACE_CLIP, 0);
+
+ /* "timeline" */
+ 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);
+
+ /* delete */
+ WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", DELKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", XKEY, KM_PRESS, 0, 0);
+
+ 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);
+}
+
+const char *clip_context_dir[]= {"edit_movieclip", NULL};
+
+static int clip_context(const bContext *C, const char *member, bContextDataResult *result)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ if(CTX_data_dir(member)) {
+ CTX_data_dir_set(result, clip_context_dir);
+ return 1;
+ }
+ else if(CTX_data_equals(member, "edit_movieclip")) {
+ CTX_data_id_pointer_set(result, &sc->clip->id);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void clip_refresh(const bContext *C, ScrArea *sa)
+{
+ wmWindowManager *wm= CTX_wm_manager(C);
+ wmWindow *window= CTX_wm_window(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);
+ int view_changed= 0;
+
+ switch (sc->view) {
+ case SC_VIEW_CLIP:
+ if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) {
+ ar_preview->flag |= RGN_FLAG_HIDDEN;
+ ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ WM_event_remove_handlers((bContext*)C, &ar_preview->handlers);
+ view_changed= 1;
+ }
+ if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
+ 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)) {
+ ar_preview->flag &= ~RGN_FLAG_HIDDEN;
+ ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ ar_preview->v2d.cur = ar_preview->v2d.tot;
+ view_changed= 1;
+ }
+ if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
+ ar_main->alignment= RGN_ALIGN_NONE;
+ view_changed= 1;
+ }
+ if (ar_preview && ar_preview->alignment != RGN_ALIGN_TOP) {
+ ar_preview->alignment= RGN_ALIGN_TOP;
+ view_changed= 1;
+ }
+ break;
+ }
+
+ if(view_changed) {
+ ED_area_initialize(wm, window, sa);
+ ED_area_tag_redraw(sa);
+ }
+
+ BKE_movieclip_user_set_frame(&sc->user, CTX_data_scene(C)->r.cfra);
+}
+
+/********************* main region ********************/
+
+/* sets up the fields of the View2D from zoom and offset */
+static void movieclip_main_area_set_view2d(SpaceClip *sc, ARegion *ar)
+{
+ MovieClip *clip= ED_space_clip(sc);
+ float x1, y1, w, h;
+ int width, height, winx, winy;
+
+ ED_space_clip_size(sc, &width, &height);
+
+ w= width;
+ h= height;
+
+ if(clip)
+ h*= clip->aspy/clip->aspx/clip->tracking.camera.pixel_aspect;
+
+ winx= ar->winrct.xmax - ar->winrct.xmin + 1;
+ winy= ar->winrct.ymax - ar->winrct.ymin + 1;
+
+ ar->v2d.tot.xmin= 0;
+ ar->v2d.tot.ymin= 0;
+ ar->v2d.tot.xmax= w;
+ ar->v2d.tot.ymax= h;
+
+ ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0;
+ ar->v2d.mask.xmax= winx;
+ ar->v2d.mask.ymax= winy;
+
+ /* which part of the image space do we see? */
+ x1= ar->winrct.xmin+(winx-sc->zoom*w)/2.0f;
+ y1= ar->winrct.ymin+(winy-sc->zoom*h)/2.0f;
+
+ x1-= sc->zoom*sc->xof;
+ y1-= sc->zoom*sc->yof;
+
+ /* relative display right */
+ ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sc->zoom);
+ ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sc->zoom);
+
+ /* relative display left */
+ ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sc->zoom);
+ ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sc->zoom);
+
+ /* normalize 0.0..1.0 */
+ ar->v2d.cur.xmin /= w;
+ ar->v2d.cur.xmax /= w;
+ ar->v2d.cur.ymin /= h;
+ ar->v2d.cur.ymax /= h;
+}
+
+/* add handlers, stuff you only do once or on area/region changes */
+static void clip_main_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ wmKeyMap *keymap;
+
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
+
+ /* own keymap */
+ keymap= WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Clip Editor", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+}
+
+static void clip_main_area_draw(const bContext *C, ARegion *ar)
+{
+ /* draw entirely, view changes should be handled here */
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ Scene *scene= CTX_data_scene(C);
+ MovieClip *clip= ED_space_clip(sc);
+
+ /* if trcking is in progress, we should sunchronize framenr from clipuser
+ so latest tracked frame would be shown */
+ if(clip && clip->tracking_context)
+ BKE_tracking_sync_user(&sc->user, clip->tracking_context);
+
+ if(sc->flag&SC_LOCK_SELECTION) {
+ ImBuf *tmpibuf= NULL;
+
+ if(clip && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) {
+ tmpibuf= ED_space_clip_get_stable_buffer(sc, NULL, NULL, NULL);
+ }
+
+ if(ED_clip_view_selection(sc, ar, 0)) {
+ sc->xof+= sc->xlockof;
+ sc->yof+= sc->ylockof;
+ }
+
+ if(tmpibuf)
+ IMB_freeImBuf(tmpibuf);
+ }
+
+ /* clear and setup matrix */
+ UI_ThemeClearColor(TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* data... */
+ movieclip_main_area_set_view2d(sc, ar);
+
+ clip_draw_main(sc, ar, scene);
+
+ /* Grease Pencil */
+ clip_draw_grease_pencil((bContext *)C, 1);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* draw Grease Pencil - screen space only */
+ clip_draw_grease_pencil((bContext *)C, 0);
+}
+
+static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+ /* context changes */
+ switch(wmn->category) {
+ case NC_SCREEN:
+ if (wmn->data==ND_GPENCIL)
+ ED_region_tag_redraw(ar);
+ break;
+ }
+}
+
+/****************** preview region ******************/
+
+static void clip_preview_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ wmKeyMap *keymap;
+
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
+
+ /* own keymap */
+ keymap= WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+}
+
+static void clip_preview_area_draw(const bContext *C, ARegion *ar)
+{
+ View2D *v2d= &ar->v2d;
+ View2DScrollers *scrollers;
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ Scene *scene= CTX_data_scene(C);
+ short unitx= V2D_UNIT_FRAMESCALE, unity= V2D_UNIT_VALUES;
+
+ /* clear and setup matrix */
+ UI_ThemeClearColor(TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ UI_view2d_view_ortho(v2d);
+
+ /* data... */
+ clip_draw_graph(sc, ar, scene);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ scrollers= UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
+}
+
+static void clip_preview_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+{
+}
+
+/****************** header region ******************/
+
+/* add handlers, stuff you only do once or on area/region changes */
+static void clip_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
+{
+ ED_region_header_init(ar);
+}
+
+static void clip_header_area_draw(const bContext *C, ARegion *ar)
+{
+ ED_region_header(C, ar);
+}
+
+/****************** tools region ******************/
+
+/* add handlers, stuff you only do once or on area/region changes */
+static void clip_tools_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ ED_region_panels_init(wm, ar);
+}
+
+static void clip_tools_area_draw(const bContext *C, ARegion *ar)
+{
+ ED_region_panels(C, ar, 1, NULL, -1);
+}
+
+/****************** tool properties region ******************/
+
+static void clip_props_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+ /* context changes */
+ switch(wmn->category) {
+ case NC_WM:
+ if(wmn->data == ND_HISTORY)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCENE:
+ if(wmn->data == ND_MODE)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SPACE:
+ if(wmn->data == ND_SPACE_CLIP)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCREEN:
+ if(wmn->data == ND_GPENCIL)
+ ED_region_tag_redraw(ar);
+ break;
+ }
+}
+
+/****************** properties region ******************/
+
+/* add handlers, stuff you only do once or on area/region changes */
+static void clip_properties_area_init(wmWindowManager *wm, ARegion *ar)
+{
+ wmKeyMap *keymap;
+
+ ED_region_panels_init(wm, ar);
+
+ keymap= WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
+}
+
+static void clip_properties_area_draw(const bContext *C, ARegion *ar)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ BKE_movieclip_update_scopes(sc->clip, &sc->user, &sc->scopes);
+
+ ED_region_panels(C, ar, 1, NULL, -1);
+}
+
+static void clip_properties_area_listener(ARegion *ar, wmNotifier *wmn)
+{
+ /* context changes */
+ switch(wmn->category) {
+ case NC_SCREEN:
+ if (wmn->data==ND_GPENCIL)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_BRUSH:
+ if(wmn->action==NA_EDITED)
+ ED_region_tag_redraw(ar);
+ break;
+ }
+}
+
+/********************* registration ********************/
+
+/* only called once, from space/spacetypes.c */
+void ED_spacetype_clip(void)
+{
+ SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype clip");
+ ARegionType *art;
+
+ st->spaceid= SPACE_CLIP;
+ strncpy(st->name, "Clip", BKE_ST_MAXNAME);
+
+ st->new= clip_new;
+ st->free= clip_free;
+ st->init= clip_init;
+ st->duplicate= clip_duplicate;
+ st->operatortypes= clip_operatortypes;
+ st->keymap= clip_keymap;
+ st->listener= clip_listener;
+ st->context= clip_context;
+ st->refresh= clip_refresh;
+
+ /* regions: main window */
+ art= MEM_callocN(sizeof(ARegionType), "spacetype clip region");
+ art->regionid= RGN_TYPE_WINDOW;
+ art->init= clip_main_area_init;
+ art->draw= clip_main_area_draw;
+ art->listener= clip_main_area_listener;
+ art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI|ED_KEYMAP_GPENCIL;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* preview */
+ art= MEM_callocN(sizeof(ARegionType), "spacetype clip region preview");
+ art->regionid = RGN_TYPE_PREVIEW;
+ art->prefsizey = 240;
+ art->init= clip_preview_area_init;
+ art->draw= clip_preview_area_draw;
+ art->listener= clip_preview_area_listener;
+ art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: properties */
+ art= MEM_callocN(sizeof(ARegionType), "spacetype clip region properties");
+ art->regionid= RGN_TYPE_UI;
+ art->prefsizex= UI_COMPACT_PANEL_WIDTH;
+ art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI;
+ art->init= clip_properties_area_init;
+ art->draw= clip_properties_area_draw;
+ art->listener= clip_properties_area_listener;
+ BLI_addhead(&st->regiontypes, art);
+ ED_clip_buttons_register(art);
+
+ /* regions: tools */
+ art= MEM_callocN(sizeof(ARegionType), "spacetype clip region tools");
+ art->regionid= RGN_TYPE_TOOLS;
+ art->prefsizex= UI_COMPACT_PANEL_WIDTH;
+ art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI;
+ art->listener= clip_props_area_listener;
+ art->init= clip_tools_area_init;
+ art->draw= clip_tools_area_draw;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* tool properties */
+ art= MEM_callocN(sizeof(ARegionType), "spacetype clip tool properties region");
+ art->regionid = RGN_TYPE_TOOL_PROPS;
+ art->prefsizex= 0;
+ art->prefsizey= 120;
+ art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI;
+ art->listener= clip_props_area_listener;
+ art->init= clip_tools_area_init;
+ art->draw= clip_tools_area_draw;
+ ED_clip_tool_props_register(art);
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: header */
+ art= MEM_callocN(sizeof(ARegionType), "spacetype clip region");
+ art->regionid= RGN_TYPE_HEADER;
+ art->prefsizey= HEADERY;
+ art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER;
+
+ art->init= clip_header_area_init;
+ art->draw= clip_header_area_draw;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ BKE_spacetype_register(st);
+}
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
new file mode 100644
index 00000000000..e5bf053aa1c
--- /dev/null
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -0,0 +1,2941 @@
+/*
+ * ***** 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.
+ *
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_clip/tracking_ops.c
+ * \ingroup spclip
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_scene_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_rect.h"
+#include "BLI_blenlib.h"
+
+#include "BKE_main.h"
+#include "BKE_context.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+#include "BKE_global.h"
+#include "BKE_depsgraph.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_library.h"
+#include "BKE_sound.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_clip.h"
+#include "ED_keyframing.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "UI_interface.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "PIL_time.h"
+
+#include "UI_view2d.h"
+
+#include "clip_intern.h" // own include
+
+static int space_clip_frame_poll(bContext *C)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+
+ if(sc) {
+ MovieClip *clip= ED_space_clip(sc);
+
+ if(clip)
+ return BKE_movieclip_has_frame(clip, &sc->user);
+ }
+
+ 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);
+ 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);
+
+ BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, 0);
+
+ clip->tracking.act_track= track;
+}
+
+static int add_marker_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ float pos[2];
+ int width, height;
+
+ ED_space_clip_size(sc, &width, &height);
+ if(!width || !height)
+ return OPERATOR_CANCELLED;
+
+ RNA_float_get_array(op->ptr, "location", pos);
+
+ add_marker(sc, pos[0], pos[1]);
+
+ /* reset offset from locked position, so frame jumping wouldn't be so confusing */
+ sc->xlockof= 0;
+ sc->ylockof= 0;
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+static int add_marker_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ float co[2];
+
+ ED_clip_mouse_pos(C, event, co);
+
+ RNA_float_set_array(op->ptr, "location", co);
+
+ return add_marker_exec(C, op);
+}
+
+void CLIP_OT_add_marker(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Marker";
+ ot->idname= "CLIP_OT_add_marker";
+ ot->description= "Place new marker at specified location";
+
+ /* api callbacks */
+ ot->invoke= add_marker_invoke;
+ ot->exec= add_marker_exec;
+ ot->poll= space_clip_frame_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX,
+ "Location", "Location of marker on frame", -1.0f, 1.0f);
+}
+
+/********************** delete track operator *********************/
+
+static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track= tracking->tracks.first, *next;
+
+ while(track) {
+ next= track->next;
+
+ if(TRACK_VIEW_SELECTED(sc, track))
+ clip_delete_track(C, clip, track);
+
+ track= next;
+ }
+
+ /* nothing selected now, unlock view so it can be scrolled nice again */
+ sc->flag&= ~SC_LOCK_SELECTION;
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_delete_track(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Delete Track";
+ ot->idname= "CLIP_OT_delete_track";
+ ot->description= "Delete selected tracks";
+
+ /* api callbacks */
+ ot->invoke= WM_operator_confirm;
+ ot->exec= delete_track_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** delete marker operator *********************/
+
+static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track= clip->tracking.tracks.first, *next;
+ int framenr= sc->user.framenr;
+ int has_selection= 0;
+
+ while(track) {
+ next= track->next;
+
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, framenr);
+
+ if(marker) {
+ has_selection|= track->markersnr>1;
+
+ clip_delete_marker(C, clip, track, marker);
+ }
+ }
+
+ track= next;
+ }
+
+ if(!has_selection) {
+ /* nothing selected now, unlock view so it can be scrolled nice again */
+ sc->flag&= ~SC_LOCK_SELECTION;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_delete_marker(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Delete Marker";
+ ot->idname= "CLIP_OT_delete_marker";
+ ot->description= "Delete marker for current frame from selected tracks";
+
+ /* api callbacks */
+ ot->invoke= WM_operator_confirm;
+ ot->exec= delete_marker_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** slide marker operator *********************/
+
+#define SLIDE_ACTION_POS 0
+#define SLIDE_ACTION_SIZE 1
+#define SLIDE_ACTION_OFFSET 2
+
+typedef struct {
+ int area, action;
+ MovieTrackingTrack *track;
+ MovieTrackingMarker *marker;
+
+ int mval[2];
+ int width, height;
+ float *min, *max, *pos, *offset;
+ float smin[2], smax[2], spos[2], soff[2];
+ float (*smarkers)[2];
+
+ int lock, accurate;
+} SlideMarkerData;
+
+static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker, wmEvent *event, int area, int action, int width, int height)
+{
+ SlideMarkerData *data= MEM_callocN(sizeof(SlideMarkerData), "slide marker data");
+
+ marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
+
+ data->area= area;
+ data->action= action;
+ data->track= track;
+ data->marker= marker;
+
+ if(area==TRACK_AREA_POINT) {
+ data->pos= marker->pos;
+ data->offset= track->offset;
+ copy_v2_v2(data->spos, marker->pos);
+ copy_v2_v2(data->soff, track->offset);
+ } else if(area==TRACK_AREA_PAT) {
+ if(action==SLIDE_ACTION_SIZE) {
+ data->min= track->pat_min;
+ data->max= track->pat_max;
+ } else {
+ int a;
+
+ data->pos= marker->pos;
+ data->offset= track->offset;
+
+ copy_v2_v2(data->soff, track->offset);
+
+ data->smarkers= MEM_callocN(sizeof(*data->smarkers)*track->markersnr, "slide marekrs");
+ for(a= 0; a<track->markersnr; a++)
+ copy_v2_v2(data->smarkers[a], track->markers[a].pos);
+ }
+ } else if(area==TRACK_AREA_SEARCH) {
+ data->min= track->search_min;
+ data->max= track->search_max;
+ }
+
+ if(area==TRACK_AREA_SEARCH || (area==TRACK_AREA_PAT && action!=SLIDE_ACTION_OFFSET)) {
+ copy_v2_v2(data->smin, data->min);
+ copy_v2_v2(data->smax, data->max);
+ }
+
+ data->mval[0]= event->mval[0];
+ data->mval[1]= event->mval[1];
+
+ data->width= width;
+ data->height= height;
+
+ if(action==SLIDE_ACTION_SIZE)
+ data->lock= 1;
+
+ return data;
+}
+
+/* corner = 0: right-bottom corner,
+ corner = 1: left-top corner */
+static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int area, float co[2], int corner, int width, int height)
+{
+ int inside= 0;
+ float size= 12.0f;
+ float min[2], max[2];
+ float crn[2], dx, dy, tdx, tdy;
+
+ if(area==TRACK_AREA_SEARCH) {
+ copy_v2_v2(min, track->search_min);
+ copy_v2_v2(max, track->search_max);
+ } else {
+ copy_v2_v2(min, track->pat_min);
+ copy_v2_v2(max, track->pat_max);
+ }
+
+ dx= size/width/sc->zoom;
+ dy= size/height/sc->zoom;
+
+ tdx= 5.0f/width/sc->zoom;
+ tdy= 5.0f/height/sc->zoom;
+
+ dx= MIN2(dx, (max[0]-min[0])/6.0f) + tdx;
+ dy= MIN2(dy, (max[1]-min[1])/6.0f) + tdy;
+
+ if(corner==0) {
+ crn[0]= marker->pos[0]+max[0];
+ crn[1]= marker->pos[1]+min[1];
+
+ inside= co[0]>=crn[0]-dx && co[0]<=crn[0]+tdx && co[1]>=crn[1]-tdy && co[1]<=crn[1]+dy;
+ } else {
+ crn[0]= marker->pos[0]+min[0];
+ crn[1]= marker->pos[1]+max[1];
+
+ inside= co[0]>=crn[0]-dx && co[0]<=crn[0]+dx && co[1]>=crn[1]-dy && co[1]<=crn[1]+dy;
+ }
+
+ return inside;
+}
+
+static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ float co[2], int width, int height)
+{
+ float pos[2], dx, dy;
+
+ add_v2_v2v2(pos, marker->pos, track->offset);
+
+ dx= 12.0f/width/sc->zoom;
+ dy= 12.0f/height/sc->zoom;
+
+ dx=MIN2(dx, (track->pat_max[0]-track->pat_min[0])/2.0f);
+ dy=MIN2(dy, (track->pat_max[1]-track->pat_min[1])/2.0f);
+
+ return co[0]>=pos[0]-dx && co[0]<=pos[0]+dx && co[1]>=pos[1]-dy && co[1]<=pos[1]+dy;
+}
+
+static void hide_cursor(bContext *C)
+{
+ wmWindow *win= CTX_wm_window(C);
+
+ WM_cursor_set(win, CURSOR_NONE);
+}
+
+static void show_cursor(bContext *C)
+{
+ wmWindow *win= CTX_wm_window(C);
+
+ WM_cursor_set(win, CURSOR_STD);
+}
+
+static void *slide_marker_customdata(bContext *C, wmEvent *event)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ int width, height;
+ float co[2];
+ void *customdata= NULL;
+
+ ED_space_clip_size(sc, &width, &height);
+
+ if(width==0 || height==0)
+ return NULL;
+
+ ED_clip_mouse_pos(C, event, co);
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ if(!customdata)
+ if(mouse_on_offset(sc, track, marker, co, width, height))
+ customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, SLIDE_ACTION_POS, width, height);
+
+ if(sc->flag&SC_SHOW_MARKER_SEARCH) {
+ if(mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height))
+ customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, SLIDE_ACTION_OFFSET, width, height);
+ else if(mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height))
+ customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, SLIDE_ACTION_SIZE, width, height);
+ }
+
+ if(!customdata && sc->flag&SC_SHOW_MARKER_PATTERN) {
+ if(mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height))
+ customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, SLIDE_ACTION_OFFSET, width, height);
+
+ if(!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height))
+ customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, SLIDE_ACTION_SIZE, width, height);
+ }
+
+ if(customdata)
+ break;
+ }
+ }
+
+ track= track->next;
+ }
+
+ return customdata;
+}
+
+static int slide_marker_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SlideMarkerData *slidedata= slide_marker_customdata(C, event);
+
+ if(slidedata) {
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+
+ tracking->act_track= slidedata->track;
+
+ op->customdata= slidedata;
+
+ hide_cursor(C);
+ WM_event_add_modal_handler(C, op);
+
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+static void cancel_mouse_slide(SlideMarkerData *data)
+{
+ /* cancel sliding */
+ if(data->area == TRACK_AREA_POINT) {
+ if(data->action==SLIDE_ACTION_OFFSET)
+ copy_v2_v2(data->offset, data->soff);
+ else
+ copy_v2_v2(data->pos, data->spos);
+ } else {
+ if(data->action==SLIDE_ACTION_SIZE) {
+ copy_v2_v2(data->min, data->smin);
+ copy_v2_v2(data->max, data->smax);
+ } else {
+ int a;
+
+ for(a= 0; a<data->track->markersnr; a++)
+ copy_v2_v2(data->track->markers[a].pos, data->smarkers[a]);
+
+ copy_v2_v2(data->offset, data->soff);
+ }
+ }
+}
+
+static void free_slide_data(SlideMarkerData *data)
+{
+ if(data->smarkers) MEM_freeN(data->smarkers);
+ MEM_freeN(data);
+}
+
+static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ SlideMarkerData *data= (SlideMarkerData *)op->customdata;
+ float dx, dy, mdelta[2];
+
+ switch(event->type) {
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ if(data->action==SLIDE_ACTION_SIZE)
+ if(ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY))
+ data->lock= event->val==KM_RELEASE;
+
+ if(ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY))
+ data->accurate= event->val==KM_PRESS;
+
+ /* no break! update area size */
+
+ case MOUSEMOVE:
+ mdelta[0]= event->mval[0]-data->mval[0];
+ mdelta[1]= event->mval[1]-data->mval[1];
+
+ dx= mdelta[0]/data->width/sc->zoom;
+
+ if(data->lock) dy= -dx/data->height*data->width;
+ else dy= mdelta[1]/data->height/sc->zoom;
+
+ if(data->accurate) {
+ dx/= 5;
+ dy/= 5;
+ }
+
+ if(data->area==TRACK_AREA_POINT) {
+ if(data->action==SLIDE_ACTION_OFFSET) {
+ data->offset[0]= data->soff[0]+dx;
+ data->offset[1]= data->soff[1]+dy;
+ } else {
+ data->pos[0]= data->spos[0]+dx;
+ data->pos[1]= data->spos[1]+dy;
+
+ data->marker->flag&= ~MARKER_TRACKED;
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+ DAG_id_tag_update(&sc->clip->id, 0);
+ } else {
+ if(data->action==SLIDE_ACTION_SIZE) {
+ data->min[0]= data->smin[0]-dx;
+ data->max[0]= data->smax[0]+dx;
+
+ data->min[1]= data->smin[1]+dy;
+ data->max[1]= data->smax[1]-dy;
+
+ if(data->area==TRACK_AREA_SEARCH) BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM);
+ else BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM);
+ } else {
+ float d[2]={dx, dy};
+
+ if(data->area==TRACK_AREA_SEARCH) {
+ add_v2_v2v2(data->min, data->smin, d);
+ add_v2_v2v2(data->max, data->smax, d);
+ } else {
+ int a;
+
+ for(a= 0; a<data->track->markersnr; a++)
+ add_v2_v2v2(data->track->markers[a].pos, data->smarkers[a], d);
+
+ sub_v2_v2v2(data->offset, data->soff, d);
+ }
+
+ if(data->area==TRACK_AREA_SEARCH)
+ BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS);
+ }
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ break;
+
+ case LEFTMOUSE:
+ if(event->val==KM_RELEASE) {
+ free_slide_data(op->customdata);
+
+ show_cursor(C);
+
+ return OPERATOR_FINISHED;
+ }
+
+ break;
+
+ case ESCKEY:
+ cancel_mouse_slide(op->customdata);
+
+ free_slide_data(op->customdata);
+
+ show_cursor(C);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void CLIP_OT_slide_marker(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Slide Marker";
+ ot->description= "Slide marker areas";
+ ot->idname= "CLIP_OT_slide_marker";
+
+ /* api callbacks */
+ ot->poll= space_clip_frame_poll;
+ ot->invoke= slide_marker_invoke;
+ ot->modal= slide_marker_modal;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_GRAB_POINTER|OPTYPE_BLOCKING;
+
+ /* properties */
+ RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX,
+ "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX);
+}
+
+/********************** mouse select operator *********************/
+
+static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy)
+{
+ if(x1>x2) SWAP(float, x1, x2);
+ if(y1>y2) SWAP(float, y1, y2);
+
+ return (co[0]>=x1-epsx && co[0]<=x2+epsx) && (co[1]>=y1-epsy && co[1]<=y2+epsy);
+}
+
+static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], float epsx, float epsy)
+{
+ return mouse_on_side(co, pos[0]+min[0], pos[1]+min[1], pos[0]+max[0], pos[1]+min[1], epsx, epsy) ||
+ mouse_on_side(co, pos[0]+min[0], pos[1]+min[1], pos[0]+min[0], pos[1]+max[1], epsx, epsy) ||
+ mouse_on_side(co, pos[0]+min[0], pos[1]+max[1], pos[0]+max[0], pos[1]+max[1], epsx, epsy) ||
+ mouse_on_side(co, pos[0]+max[0], pos[1]+min[1], pos[0]+max[0], pos[1]+max[1], epsx, epsy);
+}
+
+static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track)
+{
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
+ float epsx, epsy;
+ int width, height;
+
+ ED_space_clip_size(sc, &width, &height);
+
+ epsx= MIN4(track->pat_min[0]-track->search_min[0], track->search_max[0]-track->pat_max[0],
+ fabsf(track->pat_min[0]), fabsf(track->pat_max[0])) / 2;
+ epsy= MIN4(track->pat_min[1]-track->search_min[1], track->search_max[1]-track->pat_max[1],
+ fabsf(track->pat_min[1]), fabsf(track->pat_max[1])) / 2;
+
+ epsx= MAX2(epsy, 2.0f / width);
+ epsy= MAX2(epsy, 2.0f / height);
+
+ if(sc->flag&SC_SHOW_MARKER_SEARCH)
+ if(mouse_on_rect(co, marker->pos, track->search_min, track->search_max, epsx, epsy))
+ return TRACK_AREA_SEARCH;
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ if(sc->flag&SC_SHOW_MARKER_PATTERN)
+ if(mouse_on_rect(co, marker->pos, track->pat_min, track->pat_max, epsx, epsy))
+ return TRACK_AREA_PAT;
+
+ epsx= 12.0f/width;
+ epsy= 12.0f/height;
+
+ if(fabsf(co[0]-marker->pos[0]-track->offset[0])< epsx && fabsf(co[1]-marker->pos[1]-track->offset[1])<=epsy)
+ return TRACK_AREA_POINT;
+ }
+
+ return TRACK_AREA_NONE;
+}
+
+static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
+{
+ float d1, d2, d3, d4;
+ float p[2]= {co[0]-pos[0], co[1]-pos[1]};
+ float v1[2]= {min[0], min[1]}, v2[2]= {max[0], min[1]},
+ v3[2]= {max[0], max[1]}, v4[2]= {min[0], max[1]};
+
+ d1= dist_to_line_segment_v2(p, v1, v2);
+ d2= dist_to_line_segment_v2(p, v2, v3);
+ d3= dist_to_line_segment_v2(p, v3, v4);
+ d4= dist_to_line_segment_v2(p, v4, v1);
+
+ return MIN4(d1, d2, d3, d4);
+}
+
+static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, MovieClip *clip, float co[2])
+{
+ MovieTrackingTrack *track= NULL, *cur;
+ float mindist= 0.0f;
+
+ cur= clip->tracking.tracks.first;
+ while(cur) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(cur, sc->user.framenr);
+
+ if(((cur->flag&TRACK_HIDDEN)==0) && MARKER_VISIBLE(sc, marker)) {
+ float dist, d1, d2=FLT_MAX, d3=FLT_MAX;
+
+ d1= sqrtf((co[0]-marker->pos[0]-cur->offset[0])*(co[0]-marker->pos[0]-cur->offset[0])+
+ (co[1]-marker->pos[1]-cur->offset[1])*(co[1]-marker->pos[1]-cur->offset[1])); /* distance to marker point */
+
+ /* distance to pattern boundbox */
+ if(sc->flag&SC_SHOW_MARKER_PATTERN)
+ d2= dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max);
+
+ /* distance to search boundbox */
+ if(sc->flag&SC_SHOW_MARKER_SEARCH)
+ d3= dist_to_rect(co, marker->pos, cur->search_min, cur->search_max);
+
+ /* choose minimal distance. useful for cases of overlapped markers. */
+ dist= MIN3(d1, d2, d3);
+
+ if(track==NULL || dist<mindist) {
+ track= cur;
+ mindist= dist;
+ }
+ }
+
+ cur= cur->next;
+ }
+
+ return track;
+}
+
+static int mouse_select(bContext *C, float co[2], int extend)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *act_track= tracking->act_track;
+ MovieTrackingTrack *track= NULL; /* selected marker */
+
+ track= find_nearest_track(sc, clip, co);
+
+ if(track) {
+ int area= track_mouse_area(sc, co, track);
+
+ if(!extend || !TRACK_VIEW_SELECTED(sc, track))
+ area= TRACK_AREA_ALL;
+
+ if(extend && TRACK_AREA_SELECTED(track, area)) {
+ if(track==act_track)
+ BKE_tracking_deselect_track(track, area);
+ else
+ clip->tracking.act_track= track;
+ } else {
+ if(area==TRACK_AREA_POINT)
+ area= TRACK_AREA_ALL;
+
+ BKE_tracking_select_track(tracking, track, area, extend);
+ clip->tracking.act_track= track;
+ }
+ }
+
+ if(!extend) {
+ sc->xlockof= 0.0f;
+ sc->ylockof= 0.0f;
+ }
+
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int select_exec(bContext *C, wmOperator *op)
+{
+ float co[2];
+ int extend;
+
+ RNA_float_get_array(op->ptr, "location", co);
+ extend= RNA_boolean_get(op->ptr, "extend");
+
+ return mouse_select(C, co, extend);
+}
+
+static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ float co[2];
+ int extend= RNA_boolean_get(op->ptr, "extend");
+
+ if(!extend) {
+ SlideMarkerData *slidedata= slide_marker_customdata(C, event);
+
+ if(slidedata) {
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+
+ clip->tracking.act_track= slidedata->track;
+
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ MEM_freeN(slidedata);
+
+ return OPERATOR_PASS_THROUGH;
+ }
+ }
+
+ ED_clip_mouse_pos(C, event, co);
+ RNA_float_set_array(op->ptr, "location", co);
+
+ return select_exec(C, op);
+}
+
+void CLIP_OT_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Select";
+ ot->description= "Select tracking markers";
+ ot->idname= "CLIP_OT_select";
+
+ /* api callbacks */
+ ot->exec= select_exec;
+ ot->invoke= select_invoke;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "extend", 0,
+ "Extend", "Extend selection rather than clearing the existing selection");
+ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
+ "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f);
+}
+
+/********************** border select operator *********************/
+
+static int border_select_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ rcti rect;
+ rctf rectf;
+ int change= 0, mode;
+
+ /* get rectangle from operator */
+ rect.xmin= RNA_int_get(op->ptr, "xmin");
+ rect.ymin= RNA_int_get(op->ptr, "ymin");
+ rect.xmax= RNA_int_get(op->ptr, "xmax");
+ rect.ymax= RNA_int_get(op->ptr, "ymax");
+
+ ED_clip_point_stable_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
+ ED_clip_point_stable_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
+
+ mode= RNA_int_get(op->ptr, "gesture_mode");
+
+ /* do actual selection */
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
+
+ if(MARKER_VISIBLE(sc, marker) && BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) {
+ BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode!=GESTURE_MODAL_SELECT);
+
+ change= 1;
+ }
+ }
+
+ track= track->next;
+ }
+
+ if(change) {
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+void CLIP_OT_select_border(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Border Select";
+ ot->description= "Select markers using border selection";
+ ot->idname= "CLIP_OT_select_border";
+
+ /* api callbacks */
+ ot->invoke= WM_border_select_invoke;
+ ot->exec= border_select_exec;
+ ot->modal= WM_border_select_modal;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_border(ot, FALSE);
+}
+
+/********************** circle select operator *********************/
+
+static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+{
+ /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
+ float x, y;
+
+ x= (marker->pos[0] - offset[0])*ellipse[0];
+ y= (marker->pos[1] - offset[1])*ellipse[1];
+
+ return x*x + y*y < 1.0f;
+}
+
+static int circle_select_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ ARegion *ar= CTX_wm_region(C);
+ MovieTrackingTrack *track;
+ int x, y, radius, width, height, mode, change= 0;
+ float zoomx, zoomy, offset[2], ellipse[2];
+
+ /* get operator properties */
+ x= RNA_int_get(op->ptr, "x");
+ y= RNA_int_get(op->ptr, "y");
+ radius= RNA_int_get(op->ptr, "radius");
+
+ mode= RNA_int_get(op->ptr, "gesture_mode");
+
+ /* compute ellipse and position in unified coordinates */
+ ED_space_clip_size(sc, &width, &height);
+ ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
+
+ ellipse[0]= width*zoomx/radius;
+ ellipse[1]= height*zoomy/radius;
+
+ ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]);
+
+ /* do selection */
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
+
+ if(MARKER_VISIBLE(sc, marker) && marker_inside_ellipse(marker, offset, ellipse)) {
+ BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode!=GESTURE_MODAL_SELECT);
+
+ change= 1;
+ }
+ }
+
+ track= track->next;
+ }
+
+ if(change) {
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+void CLIP_OT_select_circle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Circle Select";
+ ot->description= "Select markers using circle selection";
+ ot->idname= "CLIP_OT_select_circle";
+
+ /* api callbacks */
+ ot->invoke= WM_gesture_circle_invoke;
+ ot->modal= WM_gesture_circle_modal;
+ ot->exec= circle_select_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
+}
+
+/********************** select all operator *********************/
+
+static int select_all_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track= NULL; /* selected track */
+ 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;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ action= SEL_DESELECT;
+ break;
+ }
+
+ track= track->next;
+ }
+ }
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if((track->flag&TRACK_HIDDEN)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
+
+ if(marker && MARKER_VISIBLE(sc, marker)) {
+ switch (action) {
+ case SEL_SELECT:
+ track->flag|= SELECT;
+ track->pat_flag|= SELECT;
+ track->search_flag|= SELECT;
+ break;
+ case SEL_DESELECT:
+ track->flag&= ~SELECT;
+ track->pat_flag&= ~SELECT;
+ track->search_flag&= ~SELECT;
+ break;
+ case SEL_INVERT:
+ track->flag^= SELECT;
+ track->pat_flag^= SELECT;
+ track->search_flag^= SELECT;
+ break;
+ }
+ }
+ }
+
+ if(TRACK_VIEW_SELECTED(sc, track))
+ has_selection= 1;
+
+ track= track->next;
+ }
+
+ if(!has_selection)
+ sc->flag&= ~SC_LOCK_SELECTION;
+
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_select_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Select or Deselect All";
+ ot->description= "Change selection of all tracking markers";
+ ot->idname= "CLIP_OT_select_all";
+
+ /* api callbacks */
+ ot->exec= select_all_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ WM_operator_properties_select_all(ot);
+}
+
+/********************** select grouped operator *********************/
+
+static int select_groped_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ MovieTrackingMarker *marker;
+ int group= RNA_enum_get(op->ptr, "group");
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ int ok= 0;
+
+ marker= BKE_tracking_get_marker(track, sc->user.framenr);
+
+ if(group==0) { /* Keyframed */
+ ok= marker->framenr==sc->user.framenr && (marker->flag&MARKER_TRACKED)==0;
+ }
+ else if(group==1) { /* Estimated */
+ ok= marker->framenr!=sc->user.framenr;
+ }
+ else if(group==2) { /* tracked */
+ ok= marker->framenr==sc->user.framenr && (marker->flag&MARKER_TRACKED);
+ }
+ else if(group==3) { /* locked */
+ ok= track->flag&TRACK_LOCKED;
+ }
+ else if(group==4) { /* disabled */
+ 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);
+
+ if(ok && track->flag&TRACK_CUSTOMCOLOR)
+ ok= equals_v3v3(track->color, clip->tracking.act_track->color);
+ }
+ }
+ else if(group==6) { /* failed */
+ ok= (track->flag&TRACK_HAS_BUNDLE) == 0;
+ }
+
+ if(ok) {
+ track->flag|= SELECT;
+ if(sc->flag&SC_SHOW_MARKER_PATTERN) track->pat_flag|= SELECT;;
+ if(sc->flag&SC_SHOW_MARKER_SEARCH) track->search_flag|= SELECT;;
+ }
+
+ track= track->next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_select_grouped(wmOperatorType *ot)
+{
+ static EnumPropertyItem select_group_items[] = {
+ {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"},
+ {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"},
+ {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"},
+ {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"},
+ {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"},
+ {5, "COLOR", 0, "Tracks with same color", "Select all tracks with same color as actiev track"},
+ {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Select Grouped";
+ ot->description= "Joint Selected Tracks";
+ ot->idname= "CLIP_OT_select_grouped";
+
+ /* api callbacks */
+ ot->exec= select_groped_exec;
+ ot->poll= space_clip_frame_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* proeprties */
+ RNA_def_enum(ot->srna, "group", select_group_items, TRACK_CLEAR_REMAINED, "Action", "Clear action to execute");
+}
+
+/********************** track operator *********************/
+
+typedef struct TrackMarkersJob {
+ struct MovieTrackingContext *context; /* tracking context */
+ int sfra, efra, lastfra; /* Start, end and recently tracked frames */
+ int backwards; /* Backwards tracking flag */
+ MovieClip *clip; /* Clip which is tracking */
+ float delay; /* Delay in milliseconds to allow tracking at fixed FPS */
+
+ struct Main *main;
+ struct Scene *scene;
+ struct bScreen *screen;
+} TrackMarkersJob;
+
+static int track_markers_testbreak(void)
+{
+ return G.afbreek;
+}
+
+static int track_count_markers(SpaceClip *sc, MovieClip *clip)
+{
+ int tot= 0;
+ MovieTrackingTrack *track;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0)
+ tot++;
+
+ track= track->next;
+ }
+
+ return tot;
+}
+
+static void track_init_markers(SpaceClip *sc, MovieClip *clip)
+{
+ MovieTrackingTrack *track;
+ int framenr= sc->user.framenr, 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;
+
+ track= clip->tracking.tracks.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);
+ }
+
+ track= track->next;
+ }
+}
+
+static int track_markers_check_direction(int backwards, int curfra, int efra)
+{
+ if(backwards) {
+ if(curfra<efra) return 0;
+ }
+ else {
+ if(curfra>efra) return 0;
+ }
+
+ return 1;
+}
+
+static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backwards)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ Scene *scene= CTX_data_scene(C);
+ MovieTrackingSettings *settings= &clip->tracking.settings;
+
+ tmj->sfra= sc->user.framenr;
+ tmj->clip= clip;
+ tmj->backwards= backwards;
+
+ if(backwards) tmj->efra= SFRA;
+ else tmj->efra= EFRA;
+
+ /* limit frames to be tracked by user setting */
+ if(settings->frames_limit) {
+ if(backwards) tmj->efra= MAX2(tmj->efra, tmj->sfra-settings->frames_limit);
+ else tmj->efra= MIN2(tmj->efra, tmj->sfra+settings->frames_limit);
+ }
+
+ if(settings->speed!=TRACKING_SPEED_FASTEST) {
+ tmj->delay= 1.0f/scene->r.frs_sec*1000.0f;
+
+ if(settings->speed==TRACKING_SPEED_HALF) tmj->delay*= 2;
+ else if(settings->speed==TRACKING_SPEED_QUARTER) tmj->delay*= 4;
+ else if(settings->speed==TRACKING_SPEED_DOUBLE) tmj->delay/= 2;
+ }
+
+ track_init_markers(sc, clip);
+
+ tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards, 1);
+
+ clip->tracking_context= tmj->context;
+
+ tmj->lastfra= tmj->sfra;
+
+ /* XXX: silly to store this, but this data is needed to update scene and movieclip
+ frame numbers when tracking is finished. This introduces better feedback for artists.
+ Maybe there's another way to solve this problem, but can't think better way atm.
+ Anyway, this way isn't more unstable as animation rendering animation
+ which uses the same approach (except storing screen). */
+ tmj->scene= scene;
+ tmj->main= CTX_data_main(C);
+ tmj->screen= CTX_wm_screen(C);
+
+ return track_markers_check_direction(backwards, tmj->sfra, tmj->efra);
+}
+
+static void track_markers_startjob(void *tmv, short *stop, short *do_update, float *progress)
+{
+ TrackMarkersJob *tmj= (TrackMarkersJob *)tmv;
+ int framenr= tmj->sfra;
+ //double t= PIL_check_seconds_timer();
+
+ while(framenr != tmj->efra) {
+ if(tmj->delay>0) {
+ /* tracking should happen with fixed fps. Calculate time
+ using current timer value before tracking frame and after.
+
+ Small (and maybe unneeded optimization): do not calculate exec_time
+ for "Fastest" tracking */
+
+ double start_time= PIL_check_seconds_timer(), exec_time;
+
+ if(!BKE_tracking_next(tmj->context))
+ break;
+
+ exec_time= PIL_check_seconds_timer()-start_time;
+ if(tmj->delay>exec_time)
+ PIL_sleep_ms(tmj->delay-exec_time);
+ } else if(!BKE_tracking_next(tmj->context))
+ break;
+
+ *do_update= 1;
+ *progress=(float)(framenr-tmj->sfra) / (tmj->efra-tmj->sfra);
+
+ if(tmj->backwards) framenr--;
+ else framenr++;
+
+ tmj->lastfra= framenr;
+
+ if(*stop || track_markers_testbreak())
+ break;
+ }
+
+ //printf("Tracking time: %lf\n", PIL_check_seconds_timer()-t);
+}
+
+static void track_markers_updatejob(void *tmv)
+{
+ TrackMarkersJob *tmj= (TrackMarkersJob *)tmv;
+
+ BKE_tracking_sync(tmj->context);
+}
+
+static void track_markers_freejob(void *tmv)
+{
+ TrackMarkersJob *tmj= (TrackMarkersJob *)tmv;
+
+ tmj->clip->tracking_context= NULL;
+ tmj->scene->r.cfra= tmj->lastfra;
+ ED_update_for_newframe(tmj->main, tmj->scene, tmj->screen, 0);
+
+ BKE_tracking_sync(tmj->context);
+ BKE_tracking_context_free(tmj->context);
+
+ MEM_freeN(tmj);
+
+ WM_main_add_notifier(NC_SCENE|ND_FRAME, tmj->scene);
+}
+
+static int track_markers_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ Scene *scene= CTX_data_scene(C);
+ struct MovieTrackingContext *context;
+ int framenr= sc->user.framenr;
+ int sfra= framenr, efra;
+ int backwards= RNA_boolean_get(op->ptr, "backwards");
+ int sequence= RNA_boolean_get(op->ptr, "sequence");
+ MovieTrackingSettings *settings= &clip->tracking.settings;
+
+ if(track_count_markers(sc, clip)==0)
+ return OPERATOR_CANCELLED;
+
+ if(backwards) efra= SFRA;
+ else efra= EFRA;
+
+ /* limit frames to be tracked by user setting */
+ if(settings->frames_limit) {
+ if(backwards) efra= MAX2(efra, sfra-settings->frames_limit);
+ else efra= MIN2(efra, sfra+settings->frames_limit);
+ }
+
+ if(!track_markers_check_direction(backwards, framenr, efra))
+ return OPERATOR_CANCELLED;
+
+ track_init_markers(sc, clip);
+
+ /* do not disable tracks due to threshold when tracking frame-by-frame */
+ context= BKE_tracking_context_new(clip, &sc->user, backwards, sequence);
+
+ while(framenr != efra) {
+ if(!BKE_tracking_next(context))
+ break;
+
+ if(backwards) framenr--;
+ else framenr++;
+
+ if(!sequence)
+ break;
+ }
+
+ BKE_tracking_sync(context);
+ BKE_tracking_context_free(context);
+
+ /* update scene current frame to the lastes tracked frame */
+ scene->r.cfra= framenr;
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ TrackMarkersJob *tmj;
+ ScrArea *sa= CTX_wm_area(C);
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ wmJob *steve;
+ int backwards= RNA_boolean_get(op->ptr, "backwards");
+ int sequence= RNA_boolean_get(op->ptr, "sequence");
+
+ if(clip->tracking_context)
+ return OPERATOR_CANCELLED;
+
+ if(track_count_markers(sc, clip)==0)
+ return OPERATOR_CANCELLED;
+
+ if(!sequence)
+ return track_markers_exec(C, op);
+
+ tmj= MEM_callocN(sizeof(TrackMarkersJob), "TrackMarkersJob data");
+ if(!track_markers_initjob(C, tmj, backwards)) {
+ track_markers_freejob(tmj);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ /* setup job */
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Track Markers", WM_JOB_PROGRESS);
+ WM_jobs_customdata(steve, tmj, track_markers_freejob);
+
+ /* if there's delay set in tracking job, tracking should happen
+ with fixed FPS. To deal with editor refresh we have to syncronize
+ tracks from job and tracks in clip. Do this in timer callback
+ to prevent threading conflicts. */
+ if(tmj->delay>0) WM_jobs_timer(steve, tmj->delay/1000.0f, NC_MOVIECLIP|NA_EVALUATED, 0);
+ else WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|NA_EVALUATED, 0);
+
+ WM_jobs_callbacks(steve, track_markers_startjob, NULL, track_markers_updatejob, NULL);
+
+ G.afbreek= 0;
+
+ WM_jobs_start(CTX_wm_manager(C), steve);
+ WM_cursor_wait(0);
+
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+ /* no running blender, remove handler and pass through */
+ if(0==WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C)))
+ return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
+
+ /* running tracking */
+ switch (event->type) {
+ case ESCKEY:
+ return OPERATOR_RUNNING_MODAL;
+ break;
+ }
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+void CLIP_OT_track_markers(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Track Markers";
+ ot->description= "Track selected markers";
+ ot->idname= "CLIP_OT_track_markers";
+
+ /* api callbacks */
+ ot->exec= track_markers_exec;
+ ot->invoke= track_markers_invoke;
+ ot->poll= space_clip_frame_poll;
+ ot->modal= track_markers_modal;
+
+ /* flags */
+ ot->flag= OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "backwards", 0, "Backwards", "Do backwards tracking");
+ RNA_def_boolean(ot->srna, "sequence", 0, "Track Sequence", "Track marker during image sequence rather than single image");
+}
+
+/********************** solve camera operator *********************/
+
+static int check_solve_track_count(MovieTracking *tracking)
+{
+ int tot= 0;
+ int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2;
+ MovieTrackingTrack *track;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(BKE_tracking_has_marker(track, frame1))
+ if(BKE_tracking_has_marker(track, frame2))
+ tot++;
+
+ track= track->next;
+ }
+
+ return tot>=8;
+}
+
+static int solve_camera_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ Scene *scene= CTX_data_scene(C);
+ MovieTracking *tracking= &clip->tracking;
+ int width, height;
+ float error;
+
+ if(!check_solve_track_count(tracking)) {
+ BKE_report(op->reports, RPT_ERROR, "At least 8 tracks on both of keyframes are needed for reconstruction");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* could fail if footage uses images with different sizes */
+ BKE_movieclip_get_size(clip, NULL, &width, &height);
+
+ error= BKE_tracking_solve_reconstruction(tracking, width, height);
+
+ if(error<0)
+ BKE_report(op->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details");
+ else
+ BKE_reportf(op->reports, RPT_INFO, "Average reprojection error %.3f", error);
+
+ scene->clip= clip;
+ id_us_plus(&clip->id);
+
+ if(!scene->camera)
+ scene->camera= scene_find_camera(scene);
+
+ if(scene->camera) {
+ /* set blender camera focal length so result would look fine there */
+ Camera *camera= (Camera*)scene->camera->data;
+
+ BKE_tracking_camera_to_blender(tracking, scene, camera, width, height);
+
+ WM_event_add_notifier(C, NC_OBJECT, camera);
+ }
+
+ DAG_id_tag_update(&clip->id, 0);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ /* update active clip displayed in scene buttons */
+ WM_event_add_notifier(C, NC_SCENE, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_solve_camera(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Solve Camera";
+ ot->description= "Solve camera motion from tracks";
+ ot->idname= "CLIP_OT_solve_camera";
+
+ /* api callbacks */
+ ot->exec= solve_camera_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** clear solution operator *********************/
+
+static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track= tracking->tracks.first;
+
+ while(track) {
+ track->flag&= ~TRACK_HAS_BUNDLE;
+
+ track= track->next;
+ }
+
+ if(tracking->reconstruction.cameras)
+ MEM_freeN(tracking->reconstruction.cameras);
+
+ tracking->reconstruction.cameras= NULL;
+ tracking->reconstruction.camnr= 0;
+
+ tracking->reconstruction.flag&= ~TRACKING_RECONSTRUCTED;
+
+ DAG_id_tag_update(&clip->id, 0);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_clear_solution(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Clear Solution";
+ ot->description= "Clear all calculated data";
+ ot->idname= "CLIP_OT_clear_solution";
+
+ /* api callbacks */
+ ot->exec= clear_solution_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** clear track operator *********************/
+
+static int clear_track_path_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ int action= RNA_enum_get(op->ptr, "action");
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track))
+ BKE_tracking_clear_path(track, sc->user.framenr, action);
+
+ track= track->next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_clear_track_path(wmOperatorType *ot)
+{
+ static EnumPropertyItem clear_path_actions[] = {
+ {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"},
+ {TRACK_CLEAR_REMAINED, "REMAINED", 0, "Clear remained", "Clear path at remained frames (after current)"},
+ {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Clear Track Path";
+ ot->description= "Clear path of selected tracks";
+ ot->idname= "CLIP_OT_clear_track_path";
+
+ /* api callbacks */
+ ot->exec= clear_track_path_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* proeprties */
+ RNA_def_enum(ot->srna, "action", clear_path_actions, TRACK_CLEAR_REMAINED, "Action", "Clear action to execute");
+}
+
+/********************** disable markers operator *********************/
+
+static int disable_markers_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track= tracking->tracks.first;
+ int action= RNA_enum_get(op->ptr, "action");
+
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
+ MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
+
+ if(action==0) marker->flag|= MARKER_DISABLED;
+ else if(action==1) marker->flag&= ~MARKER_DISABLED;
+ else marker->flag^= MARKER_DISABLED;
+ }
+
+ track= track->next;
+ }
+
+ DAG_id_tag_update(&clip->id, 0);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_disable_markers(wmOperatorType *ot)
+{
+ static EnumPropertyItem actions_items[] = {
+ {0, "DISABLE", 0, "Disable", "Disable selected markers"},
+ {1, "ENABLE", 0, "Enable", "Enable selected markers"},
+ {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Disable Markers";
+ ot->description= "Disable/enable selected markers";
+ ot->idname= "CLIP_OT_disable_markers";
+
+ /* api callbacks */
+ ot->exec= disable_markers_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Disable action to execute");
+}
+
+/********************** set origin operator *********************/
+
+static int count_selected_bundles(bContext *C)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ int tot= 0;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_HAS_BUNDLE))
+ tot++;
+
+ track= track->next;
+ }
+
+ return tot;
+}
+
+static int set_origin_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ Scene *scene= CTX_data_scene(C);
+ Object *parent= scene->camera;
+ float mat[4][4], vec[3];
+
+ 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;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track))
+ break;
+
+ track= track->next;
+ }
+
+ BKE_get_tracking_mat(scene, NULL, mat);
+ mul_v3_m4v3(vec, mat, track->bundle_pos);
+
+ sub_v3_v3(parent->loc, vec);
+
+ DAG_id_tag_update(&clip->id, 0);
+ DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_set_origin(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Set Origin";
+ ot->description= "Set active marker as origin by moving camera (or it's parent if present) in 3d space";
+ ot->idname= "CLIP_OT_set_origin";
+
+ /* api callbacks */
+ ot->exec= set_origin_exec;
+ ot->poll= space_clip_frame_camera_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** set floor operator *********************/
+
+static void set_axis(Scene *scene, Object *ob, MovieTrackingTrack *track, char axis)
+{
+ float mat[4][4], vec[3], obmat[4][4];
+
+ BKE_get_tracking_mat(scene, NULL, mat);
+ mul_v3_m4v3(vec, mat, track->bundle_pos);
+
+ if(len_v2(vec)<1e-3)
+ return;
+
+ unit_m4(mat);
+
+ if(axis=='X') {
+ if(fabsf(vec[1])<1e-3) {
+ 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]);
+ }
+ } else {
+ if(fabsf(vec[0])<1e-3) {
+ 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]);
+ }
+ }
+
+ normalize_v3(mat[0]);
+ normalize_v3(mat[1]);
+ normalize_v3(mat[2]);
+
+ invert_m4(mat);
+
+ object_to_mat4(ob, obmat);
+ mul_m4_m4m4(mat, obmat, mat);
+ object_apply_mat4(ob, mat, 0, 0);
+}
+
+static int set_floor_exec(bContext *C, wmOperator *op)
+{
+ 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;
+ 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},
+ {0.0f, 1.0f, 0.0f, 0.0f},
+ {1.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 1.0f}}; /* 90 degrees Y-axis rotation matrix */
+
+ 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;
+
+ BKE_get_tracking_mat(scene, NULL, mat);
+
+ /* get 3 bundles to use as reference */
+ track= clip->tracking.tracks.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)
+ copy_v3_v3(orig, vec[tot]);
+ else
+ axis_track= track;
+
+ tot++;
+ }
+
+ track= track->next;
+ }
+
+ sub_v3_v3(vec[1], vec[0]);
+ sub_v3_v3(vec[2], vec[0]);
+
+ /* construct ortho-normal basis */
+ unit_m4(mat);
+
+ cross_v3_v3v3(mat[0], vec[1], vec[2]);
+ copy_v3_v3(mat[1], vec[1]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+
+ normalize_v3(mat[0]);
+ normalize_v3(mat[1]);
+ normalize_v3(mat[2]);
+
+ /* move to origin point */
+ mat[3][0]= orig[0];
+ mat[3][1]= orig[1];
+ mat[3][2]= orig[2];
+
+ 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 */
+ mul_v3_m4v3(vec[0], mat, camera->loc);
+ if(camera->loc[2]<0) {
+ invert_m4(rot);
+ mul_m4_m4m4(newmat, mat, rot);
+ object_apply_mat4(camera, newmat, 0, 0);
+ }
+
+ where_is_object(scene, parent);
+ set_axis(scene, parent, axis_track, 'X');
+
+ DAG_id_tag_update(&clip->id, 0);
+ DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_set_floor(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Set Floor";
+ ot->description= "Set floor based on 3 selected bundles by moving camera (or it's parent if present) in 3d space";
+ ot->idname= "CLIP_OT_set_floor";
+
+ /* api callbacks */
+ ot->exec= set_floor_exec;
+ ot->poll= space_clip_camera_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** set axis operator *********************/
+
+static int set_axis_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ Scene *scene= CTX_data_scene(C);
+ Object *parent= scene->camera;
+ int axis= RNA_enum_get(op->ptr, "axis");
+
+ if(count_selected_bundles(C)!=1) {
+ BKE_report(op->reports, RPT_ERROR, "Single track with bundle should be selected to define axis");
+
+ return OPERATOR_CANCELLED;
+ }
+
+ if(scene->camera->parent)
+ parent= scene->camera->parent;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track))
+ break;
+
+ track= track->next;
+ }
+
+ set_axis(scene, parent, track, axis==0?'X':'Y');
+
+ DAG_id_tag_update(&clip->id, 0);
+ DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_set_axis(wmOperatorType *ot)
+{
+ static EnumPropertyItem axis_actions[] = {
+ {0, "X", 0, "X", "Align bundle align X axis"},
+ {1, "Y", 0, "Y", "Align bundle align Y axis"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Set Axis";
+ ot->description= "Set direction of scene axis rotating camera (or it's parent if present) and assuming selected track lies on real axis joining it with the origin";
+ ot->idname= "CLIP_OT_set_axis";
+
+ /* api callbacks */
+ ot->exec= set_axis_exec;
+ ot->poll= space_clip_frame_camera_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "axis", axis_actions, 0, "Axis", "Axis to use to align bundle along");
+}
+
+/********************** set scale operator *********************/
+
+static int set_scale_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ Scene *scene= CTX_data_scene(C);
+ Object *parent= scene->camera;
+ 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");
+
+ return OPERATOR_CANCELLED;
+ }
+
+ if(scene->camera->parent)
+ parent= scene->camera->parent;
+
+ BKE_get_tracking_mat(scene, NULL, mat);
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
+ tot++;
+ }
+
+ track= track->next;
+ }
+
+ sub_v3_v3(vec[0], vec[1]);
+
+ if(len_v3(vec[0])>1e-5) {
+ scale= dist / len_v3(vec[0]);
+
+ mul_v3_fl(parent->size, scale);
+ mul_v3_fl(parent->loc, scale);
+
+ DAG_id_tag_update(&clip->id, 0);
+ DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+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)
+ RNA_float_set(op->ptr, "distance", clip->tracking.settings.dist);
+
+ return set_scale_exec(C, op);
+}
+
+void CLIP_OT_set_scale(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Set Scale";
+ ot->description= "Set scale of scene by scaling camera (or it's parent if present)";
+ ot->idname= "CLIP_OT_set_scale";
+
+ /* api callbacks */
+ ot->exec= set_scale_exec;
+ ot->invoke= set_scale_invoke;
+ ot->poll= space_clip_frame_camera_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 principal center operator *********************/
+
+static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ int width, height;
+
+ BKE_movieclip_get_size(clip, &sc->user, &width, &height);
+
+ if(width==0 || height==0)
+ return OPERATOR_CANCELLED;
+
+ clip->tracking.camera.principal[0]= ((float)width)/2.0f;
+ clip->tracking.camera.principal[1]= ((float)height)/2.0f;
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_set_center_principal(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Set Principal to Center";
+ ot->description= "Set principal point to center of footage";
+ ot->idname= "CLIP_OT_set_center_principal";
+
+ /* api callbacks */
+ ot->exec= set_center_principal_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** hide tracks operator *********************/
+
+static int hide_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ int unselected;
+
+ unselected= RNA_boolean_get(op->ptr, "unselected");
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(unselected==0 && TRACK_VIEW_SELECTED(sc, track)) {
+ track->flag|= TRACK_HIDDEN;
+ } else if(unselected==1 && !TRACK_VIEW_SELECTED(sc, track)) {
+ track->flag|= TRACK_HIDDEN;
+ }
+
+ track= track->next;
+ }
+
+ if(clip->tracking.act_track && clip->tracking.act_track->flag&TRACK_HIDDEN)
+ clip->tracking.act_track= NULL;
+
+ if(unselected==0) {
+ /* no selection on screen now, unlock view so it can be scrolled nice again */
+ sc->flag&= ~SC_LOCK_SELECTION;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_hide_tracks(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Hide Tracks";
+ ot->description= "Hide selected tracks";
+ ot->idname= "CLIP_OT_hide_tracks";
+
+ /* api callbacks */
+ ot->exec= hide_tracks_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected tracks");
+}
+
+/********************** hide tracks clear operator *********************/
+
+static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ track->flag&= ~TRACK_HIDDEN;
+
+ track= track->next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_hide_tracks_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Hide Tracks Clear";
+ ot->description= "Clear hide selected tracks";
+ ot->idname= "CLIP_OT_hide_tracks_clear";
+
+ /* api callbacks */
+ ot->exec= hide_tracks_clear_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** detect features operator *********************/
+
+static bGPDlayer *detect_get_layer(MovieClip *clip)
+{
+ bGPDlayer *layer;
+
+ if(!clip->gpd)
+ return NULL;
+
+ layer= clip->gpd->layers.first;
+ while(layer) {
+ if(layer->flag&GP_LAYER_ACTIVE)
+ return layer;
+
+ layer= layer->next;
+ }
+
+ return NULL;
+}
+
+static int detect_features_exec(bContext *C, wmOperator *op)
+{
+ 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 placement= RNA_enum_get(op->ptr, "placement");
+ int margin= RNA_int_get(op->ptr, "margin");
+ int min_trackness= RNA_int_get(op->ptr, "min_trackness");
+ int min_distance= RNA_int_get(op->ptr, "min_distance");
+ int place_outside_layer= 0;
+ bGPDlayer *layer= NULL;
+
+ if(placement!=0) {
+ layer= detect_get_layer(clip);
+ place_outside_layer= placement==2;
+ }
+
+ /* deselect existing tracks */
+ while(track) {
+ track->flag&= ~SELECT;
+ track->pat_flag&= ~SELECT;
+ track->search_flag&= ~SELECT;
+
+ track= track->next;
+ }
+
+ BKE_tracking_detect_fast(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackness, min_distance, layer, place_outside_layer);
+
+ IMB_freeImBuf(ibuf);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_detect_features(wmOperatorType *ot)
+{
+ static EnumPropertyItem placement_items[] = {
+ {0, "FRAME", 0, "Whole Frame", "Place markers across the whole frame"},
+ {1, "INSIDE_GPENCIL", 0, "Inside grease pencil", "Place markers only inside areas oulined with grease pencil"},
+ {2, "OUTSIDE_GPENCIL", 0, "Outside grease pencil", "Place markers only outside areas oulined with grease pencil"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Detect Features";
+ ot->description= "Automatically detect features to track";
+ ot->idname= "CLIP_OT_detect_features";
+
+ /* api callbacks */
+ ot->exec= detect_features_exec;
+ ot->poll= space_clip_frame_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "placement", placement_items, 0, "Placement", "Placement for detected features");
+ RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin", "Only corners further than margin pixels from the image edges are considered", 0, 300);
+ RNA_def_int(ot->srna, "min_trackness", 16, 0, INT_MAX, "Trackness", "Minimum score to add a corner", 0, 300);
+ RNA_def_int(ot->srna, "min_distance", 120, 0, INT_MAX, "Distance", "Minimal distance accepted between two corners", 0, 300);
+}
+
+/********************** frame jump operator *********************/
+
+static int frame_jump_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track;
+ int pos= RNA_enum_get(op->ptr, "position");
+ int delta;
+
+ if(pos<=1) { /* jump to path */
+ track= clip->tracking.act_track;
+
+ if(!track)
+ return OPERATOR_CANCELLED;
+
+ delta= pos == 1 ? 1 : -1;
+
+ while(sc->user.framenr+delta >= SFRA && sc->user.framenr+delta <= EFRA) {
+ MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, sc->user.framenr+delta);
+
+ if(!marker || marker->flag&MARKER_DISABLED)
+ break;
+
+ sc->user.framenr+= delta;
+ }
+ }
+ else { /* to to failed frame */
+ if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
+ int a= sc->user.framenr;
+ MovieTracking *tracking= &clip->tracking;
+
+ delta= pos == 3 ? 1 : -1;
+
+ a+= delta;
+
+ while(a+delta >= SFRA && a+delta <= EFRA) {
+ MovieReconstructedCamera *cam= BKE_tracking_get_reconstructed_camera(tracking, a);
+
+ if(!cam) {
+ sc->user.framenr= a;
+
+ break;
+ }
+
+ a+= delta;
+ }
+ }
+ }
+
+ if(CFRA!=sc->user.framenr) {
+ CFRA= sc->user.framenr;
+ sound_seek_scene(CTX_data_main(C), CTX_data_scene(C));
+
+ WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_frame_jump(wmOperatorType *ot)
+{
+ static EnumPropertyItem position_items[] = {
+ {0, "PATHSTART", 0, "Path Start", "Jump to start of current path"},
+ {1, "PATHEND", 0, "Path End", "Jump to end of current path"},
+ {2, "FAILEDPREV", 0, "Previons Failed", "Jump to previous failed frame"},
+ {2, "FAILNEXT", 0, "Next Failed", "Jump to next failed frame"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Jump to Frame";
+ ot->description= "Jump to special frame";
+ ot->idname= "CLIP_OT_frame_jump";
+
+ /* api callbacks */
+ ot->exec= frame_jump_exec;
+ ot->poll= space_clip_frame_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "position", position_items, 0, "Position", "Position to jumo to");
+}
+
+/********************** join tracks operator *********************/
+
+static int join_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *act_track, *track, *next;
+
+ act_track= clip->tracking.act_track;
+
+ if(!act_track) {
+ BKE_report(op->reports, RPT_ERROR, "No active track to join to");
+ return OPERATOR_CANCELLED;
+ }
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) {
+ if(!BKE_tracking_test_join_tracks(act_track, track)) {
+ BKE_report(op->reports, RPT_ERROR, "Some selected tracks have got keyframed markers to the same frame");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ track= track->next;
+ }
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ next= track->next;
+
+ if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) {
+ BKE_tracking_join_tracks(act_track, track);
+
+ BKE_tracking_free_track(track);
+ BLI_freelinkN(&clip->tracking.tracks, track);
+ }
+
+ track= next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_join_tracks(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Join Tracks";
+ ot->description= "Joint Selected Tracks";
+ ot->idname= "CLIP_OT_join_tracks";
+
+ /* api callbacks */
+ ot->exec= join_tracks_exec;
+ ot->poll= space_clip_frame_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** lock tracks operator *********************/
+
+static int lock_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track= tracking->tracks.first;
+ int action= RNA_enum_get(op->ptr, "action");
+
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ if(action==0) track->flag|= TRACK_LOCKED;
+ else if(action==1) track->flag&= ~TRACK_LOCKED;
+ else track->flag^= TRACK_LOCKED;
+ }
+
+ track= track->next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_lock_tracks(wmOperatorType *ot)
+{
+ static EnumPropertyItem actions_items[] = {
+ {0, "LOCK", 0, "Lock", "Lock selected tracks"},
+ {1, "UNLOCK", 0, "Unlock", "Unlock selected tracks"},
+ {2, "TOGGLE", 0, "Toggle", "Toggle locked flag for selected tracks"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Lock Tracks";
+ ot->description= "Lock/unlock selected tracks";
+ ot->idname= "CLIP_OT_lock_tracks";
+
+ /* api callbacks */
+ ot->exec= lock_tracks_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Lock action to execute");
+}
+
+/********************** track copy color operator *********************/
+
+static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTrackingTrack *track, *act_track= clip->tracking.act_track;
+
+ if(!act_track)
+ return OPERATOR_CANCELLED;
+
+ track= clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) {
+ track->flag&= ~TRACK_CUSTOMCOLOR;
+
+ if(act_track->flag&TRACK_CUSTOMCOLOR) {
+ copy_v3_v3(track->color, act_track->color);
+ track->flag|= TRACK_CUSTOMCOLOR;
+ }
+ }
+
+ track= track->next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_track_copy_color(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Copy Color";
+ ot->description= "Copy color to all selected tracks";
+ ot->idname= "CLIP_OT_track_copy_color";
+
+ /* api callbacks */
+ ot->exec= track_copy_color_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** add 2d stabilization tracks operator *********************/
+
+static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+ int update= 0;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_USE_2D_STAB)==0) {
+ track->flag|= TRACK_USE_2D_STAB;
+ stab->tot_track++;
+
+ update= 1;
+ }
+
+ track= track->next;
+ }
+
+ if(update) {
+ stab->ok= 0;
+
+ DAG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_stabilize_2d_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Stabilization Tracks";
+ ot->description= "Add selected tracks to 2D stabilization tool";
+ ot->idname= "CLIP_OT_stabilize_2d_add";
+
+ /* api callbacks */
+ ot->exec= stabilize_2d_add_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** remove 2d stabilization tracks operator *********************/
+
+static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+ MovieTrackingTrack *track;
+ int a= 0, update= 0;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(track->flag&TRACK_USE_2D_STAB) {
+ if(a==stab->act_track) {
+ track->flag&= ~TRACK_USE_2D_STAB;
+
+ stab->act_track--;
+ stab->tot_track--;
+
+ if(stab->act_track<0)
+ stab->act_track= 0;
+
+ update= 1;
+
+ break;
+ }
+
+ a++;
+ }
+
+ track= track->next;
+ }
+
+ if(update) {
+ stab->ok= 0;
+
+ DAG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_stabilize_2d_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Stabilization Track";
+ ot->description= "Remove selected track from stabilization";
+ ot->idname= "CLIP_OT_stabilize_2d_remove";
+
+ /* api callbacks */
+ ot->exec= stabilize_2d_remove_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** select 2d stabilization tracks operator *********************/
+
+static int stabilize_2d_select_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+ int update= 0;
+
+ track= tracking->tracks.first;
+ while(track) {
+ if(track->flag&TRACK_USE_2D_STAB) {
+ BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0);
+
+ update= 1;
+ }
+
+ track= track->next;
+ }
+
+ if(update)
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_stabilize_2d_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Select Stabilization Tracks";
+ ot->description= "Select track which are used for stabilization";
+ ot->idname= "CLIP_OT_stabilize_2d_select";
+
+ /* api callbacks */
+ ot->exec= stabilize_2d_select_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** set 2d stabilization rotation track operator *********************/
+
+static int stabilize_2d_set_rotation_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc= CTX_wm_space_clip(C);
+ MovieClip *clip= ED_space_clip(sc);
+ MovieTracking *tracking= &clip->tracking;
+
+ if(tracking->act_track) {
+ MovieTrackingStabilization *stab= &tracking->stabilization;
+
+ stab->rot_track= tracking->act_track;
+ stab->ok= 0;
+
+ DAG_id_tag_update(&clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_stabilize_2d_set_rotation(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Set Rotation Track";
+ ot->description= "Use active track to compensate rotaiton when doing 2D stabilization";
+ ot->idname= "CLIP_OT_stabilize_2d_set_rotation";
+
+ /* api callbacks */
+ ot->exec= stabilize_2d_set_rotation_exec;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** clean tracks operator *********************/
+
+static int is_track_clean(MovieTrackingTrack *track, int frames, int del)
+{
+ int ok= 1, a, prev= -1, count= 0;
+ MovieTrackingMarker *markers= track->markers, *new_markers= NULL;
+ int start_disabled= 0;
+ int markersnr= track->markersnr;
+
+ if(del)
+ new_markers= MEM_callocN(markersnr*sizeof(MovieTrackingMarker), "track cleaned markers");
+
+ for(a= 0; a<markersnr; a++) {
+ int end= 0;
+
+ if(prev==-1) {
+ if((markers[a].flag&MARKER_DISABLED)==0)
+ prev= a;
+ else
+ start_disabled= 1;
+ }
+
+ if(prev >= 0) {
+ end= a == markersnr-1;
+ end|= (a < markersnr-1) && (markers[a].framenr != markers[a+1].framenr-1 ||
+ markers[a].flag&MARKER_DISABLED);
+ }
+
+ if(end) {
+ int segok= 1, len= 0;
+
+ if(a != prev && markers[a].framenr != markers[a-1].framenr+1)
+ len= a-prev;
+ else if(markers[a].flag&MARKER_DISABLED)
+ len= a-prev;
+ else len= a-prev+1;
+
+ if(frames) {
+ if(len < frames) {
+ segok= 0;
+ ok= 0;
+
+ if(!del)
+ break;
+ }
+ }
+
+ if(del) {
+ if(segok) {
+ int t= len;
+
+ if(markers[a].flag&MARKER_DISABLED)
+ t++;
+
+ /* place disabled marker in front of current segment */
+ if(start_disabled) {
+ memcpy(new_markers+count, markers+prev, sizeof(MovieTrackingMarker));
+ new_markers[count].framenr--;
+ new_markers[count].flag|= MARKER_DISABLED;
+
+ count++;
+ start_disabled= 0;
+ }
+
+ memcpy(new_markers+count, markers+prev, t*sizeof(MovieTrackingMarker));
+ count+= t;
+ }
+ else if(markers[a].flag&MARKER_DISABLED) {
+ /* current segment which would be deleted was finished by disabled marker,
+ so next segment should be started from disabled marker */
+ start_disabled= 1;
+ }
+ }
+
+ prev= -1;
+ }
+ }
+
+ if(del) {
+ MEM_freeN(track->markers);
+
+ if(count) {
+ track->markers= new_markers;
+ }
+ else {
+ track->markers= NULL;
+ MEM_freeN(new_markers);
+ }
+
+ track->markersnr= count;
+ }
+
+ return ok;
+}
+
+static int clean_tracks_exec(bContext *C, wmOperator *op)
+{
+ 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;
+ int frames= RNA_int_get(op->ptr, "frames");
+ int action= RNA_enum_get(op->ptr, "action");
+ float error= RNA_float_get(op->ptr, "error");
+
+ if(error && action==TRACKING_CLEAN_DELETE_SEGMENT)
+ action= TRACKING_CLEAN_DELETE_TRACK;
+
+ track= tracking->tracks.first;
+ while(track) {
+ next= track->next;
+
+ if((track->flag&TRACK_HIDDEN)==0 && (track->flag&TRACK_LOCKED)==0) {
+ int ok= 1;
+
+ ok= (is_track_clean(track, frames, action==TRACKING_CLEAN_DELETE_SEGMENT)) &&
+ (error == 0.0f || (track->flag&TRACK_HAS_BUNDLE)==0 || track->error < error);
+
+ if(!ok) {
+ if(action==TRACKING_CLEAN_SELECT) {
+ BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0);
+ }
+ else if(action==TRACKING_CLEAN_DELETE_TRACK) {
+ if(track==act_track)
+ clip->tracking.act_track= NULL;
+
+ BKE_tracking_free_track(track);
+ BLI_freelinkN(&clip->tracking.tracks, track);
+ track= NULL;
+ }
+
+ /* happens when all tracking segments are not long enough */
+ if(track && track->markersnr==0) {
+ if(track==act_track)
+ clip->tracking.act_track= NULL;
+
+ BKE_tracking_free_track(track);
+ BLI_freelinkN(&clip->tracking.tracks, track);
+ }
+ }
+ }
+
+ track= next;
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+static int clean_tracks_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ 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) {
+ RNA_int_set(op->ptr, "frames", clip->tracking.settings.clean_frames);
+ RNA_float_set(op->ptr, "error", clip->tracking.settings.clean_error);
+ RNA_enum_set(op->ptr, "action", clip->tracking.settings.clean_action);
+ }
+
+ return clean_tracks_exec(C, op);
+}
+
+void CLIP_OT_clean_tracks(wmOperatorType *ot)
+{
+ static EnumPropertyItem actions_items[] = {
+ {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"},
+ {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"},
+ {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name= "Clean Tracks";
+ ot->description= "Clean tracks";
+ ot->idname= "CLIP_OT_clean_tracks";
+
+ /* api callbacks */
+ ot->exec= clean_tracks_exec;
+ ot->invoke= clean_tracks_invoke;
+ ot->poll= ED_space_clip_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna, "frames", 0, 0, INT_MAX, "Tracked Frames", "Effect on tracks which are tracked less than specified amount of frames", 0, INT_MAX);
+ 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");
+}
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 8a27bcca8af..991b35585a6 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
node_ops.c
node_select.c
node_state.c
+ node_templates.c
space_node.c
node_intern.h
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 24ea51567ad..648027b9c58 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -95,6 +95,14 @@ static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v)
}
}
+static void node_socket_button_label(const bContext *UNUSED(C), uiBlock *block,
+ bNodeTree *UNUSED(ntree), bNode *UNUSED(node), bNodeSocket *sock,
+ const char *UNUSED(name), int x, int y, int width)
+{
+ uiDefBut(block, LABEL, 0, sock->name, x, y, width, NODE_DY, NULL, 0, 0, 0, 0, "");
+}
+
+
static void node_socket_button_default(const bContext *C, uiBlock *block,
bNodeTree *ntree, bNode *node, bNodeSocket *sock,
const char *name, int x, int y, int width)
@@ -938,28 +946,28 @@ static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA
static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
+ PointerRNA mappingptr = RNA_pointer_get(ptr, "mapping");
uiLayout *row;
uiItemL(layout, "Location:", ICON_NONE);
row= uiLayoutRow(layout, 1);
- uiItemR(row, ptr, "location", 0, "", ICON_NONE);
+ uiItemR(row, &mappingptr, "location", 0, "", ICON_NONE);
uiItemL(layout, "Rotation:", ICON_NONE);
row= uiLayoutRow(layout, 1);
- uiItemR(row, ptr, "rotation", 0, "", ICON_NONE);
+ uiItemR(row, &mappingptr, "rotation", 0, "", ICON_NONE);
uiItemL(layout, "Scale:", ICON_NONE);
row= uiLayoutRow(layout, 1);
- uiItemR(row, ptr, "scale", 0, "", ICON_NONE);
+ uiItemR(row, &mappingptr, "scale", 0, "", ICON_NONE);
row= uiLayoutRow(layout, 1);
- uiItemR(row, ptr, "use_min", 0, "Min", ICON_NONE);
- uiItemR(row, ptr, "min", 0, "", ICON_NONE);
+ uiItemR(row, &mappingptr, "use_min", 0, "Min", ICON_NONE);
+ uiItemR(row, &mappingptr, "min", 0, "", ICON_NONE);
row= uiLayoutRow(layout, 1);
- uiItemR(row, ptr, "use_max", 0, "Max", ICON_NONE);
- uiItemR(row, ptr, "max", 0, "", ICON_NONE);
-
+ uiItemR(row, &mappingptr, "use_max", 0, "Max", ICON_NONE);
+ uiItemR(row, &mappingptr, "max", 0, "", ICON_NONE);
}
static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -1679,6 +1687,40 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
+static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
+}
+
+static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ bNode *node= ptr->data;
+
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
+
+ if(!node->id)
+ return;
+
+ uiItemR(layout, ptr, "filter_type", 0, "", 0);
+}
+
+static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "filter_type", 0, "", 0);
+}
+
+static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ bNode *node= ptr->data;
+
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
+
+ if(!node->id)
+ return;
+
+ uiItemR(layout, ptr, "distortion_type", 0, "", 0);
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -1829,6 +1871,20 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_SEPYCCA:
ntype->uifunc=node_composit_buts_ycc;
break;
+ case CMP_NODE_MOVIECLIP:
+ ntype->uifunc= node_composit_buts_movieclip;
+ break;
+ case CMP_NODE_STABILIZE2D:
+ ntype->uifunc= node_composit_buts_stabilize2d;
+ break;
+ case CMP_NODE_TRANSFORM:
+ ntype->uifunc= node_composit_buts_transform;
+ break;
+ case CMP_NODE_MOVIEDISTORTION:
+ ntype->uifunc= node_composit_buts_moviedistortion;
+ break;
+ default:
+ ntype->uifunc= NULL;
}
if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc;
@@ -2041,6 +2097,9 @@ void ED_init_node_butfuncs(void)
case SOCK_RGBA:
stype->buttonfunc = node_socket_button_color;
break;
+ case SOCK_SHADER:
+ stype->buttonfunc = node_socket_button_label;
+ break;
default:
stype->buttonfunc = NULL;
}
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 3886c709196..15e5719be37 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -45,6 +45,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_global.h"
#include "BKE_node.h"
#include "BKE_screen.h"
@@ -122,6 +123,34 @@ static void active_node_panel(const bContext *C, Panel *pa)
node->typeinfo->uifunc(layout, (bContext *)C, &ptr);
}
+static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ SpaceNode *snode= CTX_wm_space_node(C);
+
+ return (snode && snode->nodetree && G.rt == 777);
+}
+
+static void node_sockets_panel(const bContext *C, Panel *pa)
+{
+ SpaceNode *snode= CTX_wm_space_node(C);
+ bNodeTree *ntree= (snode) ? snode->edittree : NULL;
+ bNode *node = (ntree) ? nodeGetActive(ntree) : NULL;
+ bNodeSocket *sock;
+ uiLayout *layout= pa->layout, *split;
+ char name[UI_MAX_NAME_STR];
+
+ if(ELEM(NULL, ntree, node))
+ return;
+
+ for(sock=node->inputs.first; sock; sock=sock->next) {
+ BLI_snprintf(name, sizeof(name), "%s:", sock->name);
+
+ split = uiLayoutSplit(layout, 0.35f, 0);
+ uiItemL(split, name, ICON_NONE);
+ uiTemplateNodeLink(split, ntree, node, sock);
+ }
+}
+
/* ******************* node buttons registration ************** */
void node_buttons_register(ARegionType *art)
@@ -134,6 +163,14 @@ void node_buttons_register(ARegionType *art)
pt->draw= active_node_panel;
pt->poll= active_node_poll;
BLI_addtail(&art->paneltypes, pt);
+
+ pt= MEM_callocN(sizeof(PanelType), "spacetype node panel node sockets");
+ strcpy(pt->idname, "NODE_PT_sockets");
+ strcpy(pt->label, "Sockets");
+ pt->draw= node_sockets_panel;
+ pt->poll= node_sockets_poll;
+ pt->flag |= PNL_DEFAULT_CLOSED;
+ BLI_addtail(&art->paneltypes, pt);
pt= MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil");
strcpy(pt->idname, "NODE_PT_gpencil");
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index c2a2f319c28..a932f1b10d9 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -108,7 +108,8 @@ void ED_node_changed_update(ID *id, bNode *node)
WM_main_add_notifier(NC_WORLD|ND_WORLD_DRAW, id);
}
else if(treetype==NTREE_COMPOSIT) {
- nodeUpdate(edittree, node);
+ if(node)
+ nodeUpdate(edittree, node);
/* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */
node= node_tree_get_editgroup(nodetree);
@@ -691,7 +692,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE);
- if (sock->link) {
+ if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) {
uiDefBut(node->block, LABEL, 0, sock->name, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY, NODE_DY,
NULL, 0, 0, 0, 0, "");
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index c1e50c112fa..745611c6251 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2207,8 +2207,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate
ED_node_set_active(bmain, snode->edittree, node);
if(snode->nodetree->type==NTREE_COMPOSIT) {
- if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE))
+ if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) {
node->id = &scene->id;
+ }
+ else if(ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) {
+ if(G.main->movieclip.first == G.main->movieclip.last) {
+ node->id= G.main->movieclip.first;
+ }
+ }
ntreeCompositForceHidden(snode->edittree, scene);
}
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index 42b5dafa3e1..d752dd79a19 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -226,52 +226,24 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass)
}
}
+static void node_menu_add_foreach_cb(void *calldata, int nclass, const char *name)
+{
+ uiLayout *layout= calldata;
+ uiItemMenuF(layout, IFACE_(name), 0, node_add_menu, SET_INT_IN_POINTER(nclass));
+}
+
static void node_menu_add(const bContext *C, Menu *menu)
{
Scene *scene= CTX_data_scene(C);
SpaceNode *snode= CTX_wm_space_node(C);
uiLayout *layout= menu->layout;
+ bNodeTreeType *ntreetype= ntreeGetType(snode->treetype);
if(!snode->nodetree)
uiLayoutSetActive(layout, 0);
-
- if(snode->treetype==NTREE_SHADER) {
- uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
- uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
- if(scene_use_new_shading_nodes(scene)) {
- uiItemMenuF(layout, IFACE_("Shader"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_SHADER));
- uiItemMenuF(layout, IFACE_("Texture"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE));
- }
- uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
- uiItemMenuF(layout, IFACE_("Vector"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR));
- uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
- uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
- //uiItemMenuF(layout, IFACE_("Dynamic"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC));
- uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT));
- }
- else if(snode->treetype==NTREE_COMPOSIT) {
- uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
- uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
- uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
- uiItemMenuF(layout, IFACE_("Vector"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR));
- uiItemMenuF(layout, IFACE_("Filter"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_FILTER));
- uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
- uiItemMenuF(layout, IFACE_("Matte"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_MATTE));
- uiItemMenuF(layout, IFACE_("Distort"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT));
- uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
- uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT));
- }
- else if(snode->treetype==NTREE_TEXTURE) {
- uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT));
- uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT));
- uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR));
- uiItemMenuF(layout, IFACE_("Patterns"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_PATTERN));
- uiItemMenuF(layout, IFACE_("Textures"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE));
- uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR));
- uiItemMenuF(layout, IFACE_("Distort"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT));
- uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP));
- uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT));
- }
+
+ if(ntreetype && ntreetype->foreach_nodeclass)
+ ntreetype->foreach_nodeclass(scene, layout, node_menu_add_foreach_cb);
}
void node_menus_register(void)
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
new file mode 100644
index 00000000000..b877bea6be9
--- /dev/null
+++ b/source/blender/editors/space_node/node_templates.c
@@ -0,0 +1,636 @@
+/*
+ * $Id$
+ *
+ * ***** 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): Blender Foundation 2009.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/interface/interface_node.c
+ * \ingroup edinterface
+ */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "../interface/interface_intern.h"
+
+#include "ED_node.h"
+
+/************************* Node Socket Manipulation **************************/
+
+static void node_tag_recursive(bNode *node)
+{
+ bNodeSocket *input;
+
+ if(!node || (node->flag & NODE_TEST))
+ return; /* in case of cycles */
+
+ node->flag |= NODE_TEST;
+
+ for(input=node->inputs.first; input; input=input->next)
+ if(input->link)
+ node_tag_recursive(input->link->fromnode);
+}
+
+static void node_clear_recursive(bNode *node)
+{
+ bNodeSocket *input;
+
+ if(!node || !(node->flag & NODE_TEST))
+ return; /* in case of cycles */
+
+ node->flag &= ~NODE_TEST;
+
+ for(input=node->inputs.first; input; input=input->next)
+ if(input->link)
+ node_clear_recursive(input->link->fromnode);
+}
+
+static void node_remove_linked(bNodeTree *ntree, bNode *rem_node)
+{
+ bNode *node, *next;
+ bNodeSocket *sock;
+
+ if(!rem_node)
+ return;
+
+ /* tag linked nodes to be removed */
+ for(node=ntree->nodes.first; node; node=node->next)
+ node->flag &= ~NODE_TEST;
+
+ node_tag_recursive(rem_node);
+
+ /* clear tags on nodes that are still used by other nodes */
+ for(node=ntree->nodes.first; node; node=node->next)
+ if(!(node->flag & NODE_TEST))
+ for(sock=node->inputs.first; sock; sock=sock->next)
+ if(sock->link && sock->link->fromnode != rem_node)
+ node_clear_recursive(sock->link->fromnode);
+
+ /* remove nodes */
+ for(node=ntree->nodes.first; node; node=next) {
+ next = node->next;
+
+ if(node->flag & NODE_TEST) {
+ if(node->id)
+ node->id->us--;
+ nodeFreeNode(ntree, node);
+ }
+ }
+}
+
+/* disconnect socket from the node it is connected to */
+static void node_socket_disconnect(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to)
+{
+ if(!sock_to->link)
+ return;
+
+ nodeRemLink(ntree, sock_to->link);
+
+ nodeUpdate(ntree, node_to);
+ ntreeUpdateTree(ntree);
+
+ ED_node_generic_update(bmain, ntree, node_to);
+}
+
+/* remove all nodes connected to this socket, if they aren't connected to other nodes */
+static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to)
+{
+ if(!sock_to->link)
+ return;
+
+ node_remove_linked(ntree, sock_to->link->fromnode);
+
+ nodeUpdate(ntree, node_to);
+ ntreeUpdateTree(ntree);
+
+ ED_node_generic_update(bmain, ntree, node_to);
+}
+
+/* add new node connected to this socket, or replace an existing one */
+static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num)
+{
+ bNode *node_from;
+ bNodeSocket *sock_from;
+ bNode *node_prev = NULL;
+
+ /* unlink existing node */
+ if(sock_to->link) {
+ node_prev = sock_to->link->fromnode;
+ nodeRemLink(ntree, sock_to->link);
+ }
+
+ /* find existing node that we can use */
+ for(node_from=ntree->nodes.first; node_from; node_from=node_from->next)
+ if(node_from->type == ntemp->type)
+ break;
+
+ if(node_from)
+ if(!(node_from->inputs.first == NULL && !(node_from->typeinfo->flag & NODE_OPTIONS)))
+ node_from = NULL;
+
+ if(node_prev && node_prev->type == ntemp->type &&
+ (ntemp->type != NODE_GROUP || node_prev->id == &ntemp->ngroup->id)) {
+ /* keep the previous node if it's the same type */
+ node_from = node_prev;
+ }
+ else if(!node_from) {
+ node_from= nodeAddNode(ntree, ntemp);
+ node_from->locx = node_to->locx - (node_from->typeinfo->width + 50);
+ node_from->locy = node_to->locy;
+
+ if(node_from->id)
+ id_us_plus(node_from->id);
+ }
+
+ nodeSetActive(ntree, node_from);
+
+ /* add link */
+ sock_from = BLI_findlink(&node_from->outputs, sock_num);
+ nodeAddLink(ntree, node_from, sock_from, node_to, sock_to);
+
+ /* copy input sockets from previous node */
+ if(node_prev && node_from != node_prev) {
+ bNodeSocket *sock_prev, *sock_from;
+
+ for(sock_prev=node_prev->inputs.first; sock_prev; sock_prev=sock_prev->next) {
+ for(sock_from=node_from->inputs.first; sock_from; sock_from=sock_from->next) {
+ if(strcmp(sock_prev->name, sock_from->name) == 0 && sock_prev->type == sock_from->type) {
+ bNodeLink *link = sock_prev->link;
+
+ if(link && link->fromnode) {
+ nodeAddLink(ntree, link->fromnode, link->fromsock, node_from, sock_from);
+ 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);
+ }
+ }
+ }
+ }
+
+ /* remove node */
+ node_remove_linked(ntree, node_prev);
+ }
+
+ nodeUpdate(ntree, node_from);
+ nodeUpdate(ntree, node_to);
+ ntreeUpdateTree(ntree);
+
+ ED_node_generic_update(bmain, ntree, node_to);
+}
+
+/****************************** Node Link Menu *******************************/
+
+#define UI_NODE_LINK_ADD 0
+#define UI_NODE_LINK_DISCONNECT -1
+#define UI_NODE_LINK_REMOVE -2
+
+typedef struct NodeLinkArg {
+ Main *bmain;
+ Scene *scene;
+ bNodeTree *ntree;
+ bNode *node;
+ bNodeSocket *sock;
+
+ bNodeTree *ngroup;
+ int type;
+ int output;
+
+ uiLayout *layout;
+} NodeLinkArg;
+
+static void ui_node_link(bContext *UNUSED(C), void *arg_p, void *event_p)
+{
+ NodeLinkArg *arg = (NodeLinkArg*)arg_p;
+ Main *bmain = arg->bmain;
+ bNode *node_to = arg->node;
+ bNodeSocket *sock_to = arg->sock;
+ bNodeTree *ntree = arg->ntree;
+ int event = GET_INT_FROM_POINTER(event_p);
+ bNodeTemplate ntemp;
+
+ ntemp.type = arg->type;
+ ntemp.ngroup = arg->ngroup;
+
+ if(event == UI_NODE_LINK_DISCONNECT)
+ node_socket_disconnect(bmain, ntree, node_to, sock_to);
+ else if(event == UI_NODE_LINK_REMOVE)
+ node_socket_remove(bmain, ntree, node_to, sock_to);
+ else
+ node_socket_add_replace(bmain, ntree, node_to, sock_to, &ntemp, arg->output);
+}
+
+static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR])
+{
+ if(sock->link && sock->link->fromnode) {
+ bNode *node = sock->link->fromnode;
+ char node_name[UI_MAX_NAME_STR];
+
+ if(node->type == NODE_GROUP)
+ BLI_strncpy(node_name, node->id->name+2, UI_MAX_NAME_STR);
+ else
+ BLI_strncpy(node_name, node->typeinfo->name, UI_MAX_NAME_STR);
+
+ if(node->inputs.first == NULL &&
+ node->outputs.first != node->outputs.last &&
+ !(node->typeinfo->flag & NODE_OPTIONS))
+ BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", node_name, sock->link->fromsock->name);
+ else
+ BLI_strncpy(name, node_name, UI_MAX_NAME_STR);
+ }
+ else if(sock->type == SOCK_SHADER)
+ BLI_strncpy(name, "None", UI_MAX_NAME_STR);
+ else
+ BLI_strncpy(name, "Default", UI_MAX_NAME_STR);
+}
+
+static int ui_compatible_sockets(int typeA, int typeB)
+{
+ return (typeA == typeB);
+}
+
+static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
+{
+ Main *bmain = arg->bmain;
+ bNodeTree *ntree = arg->ntree;
+ bNodeSocket *sock = arg->sock;
+ uiLayout *layout = arg->layout;
+ uiLayout *column = NULL;
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but;
+ bNodeType *ntype;
+ bNodeTree *ngroup;
+ NodeLinkArg *argN;
+ int first = 1;
+ int compatibility= 0;
+
+ if(ntree->type == NTREE_SHADER) {
+ if(scene_use_new_shading_nodes(arg->scene))
+ compatibility= NODE_NEW_SHADING;
+ else
+ compatibility= NODE_OLD_SHADING;
+ }
+
+ if(nclass == NODE_CLASS_GROUP) {
+ for(ngroup=bmain->nodetree.first; ngroup; ngroup=ngroup->id.next) {
+ bNodeSocket *gsock;
+ char name[UI_MAX_NAME_STR];
+ int i, j, num = 0;
+
+ if(ngroup->type != ntree->type)
+ continue;
+
+ for(gsock=ngroup->inputs.first; gsock; gsock=gsock->next)
+ if(ui_compatible_sockets(gsock->type, sock->type))
+ num++;
+
+ for(i=0, j=0, gsock=ngroup->outputs.first; gsock; gsock=gsock->next, i++) {
+ if(!ui_compatible_sockets(gsock->type, sock->type))
+ continue;
+
+ if(first) {
+ column= uiLayoutColumn(layout, 0);
+ uiBlockSetCurLayout(block, column);
+
+ uiItemL(column, cname, ICON_NODE);
+ but= block->buttons.last;
+ but->flag= UI_TEXT_LEFT;
+
+ first = 0;
+ }
+
+ if(num > 1) {
+ if(j == 0) {
+ uiItemL(column, ngroup->id.name+2, ICON_NODE);
+ but= block->buttons.last;
+ but->flag= UI_TEXT_LEFT;
+ }
+
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s", gsock->name);
+ j++;
+ }
+ else
+ BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR);
+
+ but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");
+
+ argN = MEM_dupallocN(arg);
+ argN->ngroup = ngroup;
+ argN->output = i;
+ uiButSetNFunc(but, ui_node_link, argN, NULL);
+ }
+ }
+ }
+ else {
+ bNodeTreeType *ttype= ntreeGetType(ntree->type);
+
+ for(ntype=ttype->node_types.first; ntype; ntype=ntype->next) {
+ bNodeSocketTemplate *stemp;
+ char name[UI_MAX_NAME_STR];
+ int i, j, num = 0;
+
+ if(compatibility && !(ntype->compatibility & compatibility))
+ continue;
+
+ if(ntype->nclass != nclass)
+ continue;
+
+ for(i=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++)
+ if(ui_compatible_sockets(stemp->type, sock->type))
+ num++;
+
+ for(i=0, j=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) {
+ if(!ui_compatible_sockets(stemp->type, sock->type))
+ continue;
+
+ if(first) {
+ column= uiLayoutColumn(layout, 0);
+ uiBlockSetCurLayout(block, column);
+
+ uiItemL(column, cname, ICON_NODE);
+ but= block->buttons.last;
+ but->flag= UI_TEXT_LEFT;
+
+ first = 0;
+ }
+
+ if(num > 1) {
+ if(j == 0) {
+ uiItemL(column, ntype->name, ICON_NODE);
+ but= block->buttons.last;
+ but->flag= UI_TEXT_LEFT;
+ }
+
+ BLI_snprintf(name, UI_MAX_NAME_STR, " %s", stemp->name);
+ j++;
+ }
+ else
+ BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR);
+
+ but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");
+
+ argN = MEM_dupallocN(arg);
+ argN->type = ntype->type;
+ argN->output = i;
+ uiButSetNFunc(but, ui_node_link, argN, NULL);
+ }
+ }
+ }
+}
+
+static void node_menu_column_foreach_cb(void *calldata, int nclass, const char *name)
+{
+ NodeLinkArg *arg = (NodeLinkArg*)calldata;
+
+ if(!ELEM(nclass, NODE_CLASS_GROUP, NODE_CLASS_LAYOUT))
+ ui_node_menu_column(arg, nclass, IFACE_(name));
+}
+
+static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_p)
+{
+ Main *bmain= CTX_data_main(C);
+ Scene *scene= CTX_data_scene(C);
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but = (uiBut*)but_p;
+ uiLayout *split, *column;
+ NodeLinkArg *arg = (NodeLinkArg*)but->func_argN;
+ bNodeSocket *sock = arg->sock;
+ bNodeTreeType *ntreetype= ntreeGetType(arg->ntree->type);
+
+ uiBlockSetCurLayout(block, layout);
+ split= uiLayoutSplit(layout, 0, 0);
+
+ arg->bmain= bmain;
+ arg->scene= scene;
+ arg->layout= split;
+
+ if(ntreetype && ntreetype->foreach_nodeclass)
+ ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb);
+
+ column= uiLayoutColumn(split, 0);
+ uiBlockSetCurLayout(block, column);
+
+ if(sock->link) {
+ uiItemL(column, "Link", ICON_NONE);
+ but= block->buttons.last;
+ but->flag= UI_TEXT_LEFT;
+
+ but = uiDefBut(block, BUT, 0, "Remove", 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, "Remove nodes connected to the input");
+ uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE));
+
+ but = uiDefBut(block, BUT, 0, "Disconnect", 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, "Disconnect nodes connected to the input");
+ uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT));
+ }
+
+ ui_node_menu_column(arg, NODE_CLASS_GROUP, IFACE_("Group"));
+}
+
+void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSocket *sock)
+{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ NodeLinkArg *arg;
+ uiBut *but;
+
+ arg = MEM_callocN(sizeof(NodeLinkArg), "NodeLinkArg");
+ arg->ntree = ntree;
+ arg->node = node;
+ arg->sock = sock;
+ arg->type = 0;
+ arg->output = 0;
+
+ uiBlockSetCurLayout(block, layout);
+
+ if(sock->link || sock->type == SOCK_SHADER || (sock->flag & SOCK_HIDE_VALUE)) {
+ char name[UI_MAX_NAME_STR];
+ ui_node_sock_name(sock, name);
+ but= uiDefMenuBut(block, ui_template_node_link_menu, NULL, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
+ }
+ else
+ but= uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
+
+ but->type= MENU;
+ but->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK;
+ but->poin= (char*)but;
+ but->func_argN = arg;
+}
+
+/**************************** Node Tree Layout *******************************/
+
+static void ui_node_draw_input(uiLayout *layout, bContext *C,
+ bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth);
+
+static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, int depth)
+{
+ bNodeSocket *input;
+ uiLayout *col, *split;
+ PointerRNA nodeptr;
+
+ RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);
+
+ if(node->typeinfo->uifunc) {
+ if(node->type != NODE_GROUP) {
+ split = uiLayoutSplit(layout, 0.35f, 0);
+ col = uiLayoutColumn(split, 0);
+ col = uiLayoutColumn(split, 0);
+
+ node->typeinfo->uifunc(col, C, &nodeptr);
+ }
+ }
+
+ for(input=node->inputs.first; input; input=input->next)
+ ui_node_draw_input(layout, C, ntree, node, input, depth+1);
+}
+
+static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth)
+{
+ PointerRNA inputptr;
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *bt;
+ uiLayout *split, *row, *col;
+ bNode *lnode;
+ char label[UI_MAX_NAME_STR];
+ int indent = (depth > 1)? 2*(depth - 1): 0;
+
+ if(input->flag & SOCK_UNAVAIL)
+ return;
+
+ /* to avoid eternal loops on cyclic dependencies */
+ node->flag |= NODE_TEST;
+ lnode = (input->link)? input->link->fromnode: NULL;
+
+ /* socket RNA pointer */
+ RNA_pointer_create(&ntree->id, &RNA_NodeSocket, input, &inputptr);
+
+ /* indented label */
+ memset(label, ' ', indent);
+ label[indent] = '\0';
+ BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, input->name);
+
+ /* split in label and value */
+ split = uiLayoutSplit(layout, 0.35f, 0);
+
+ row = uiLayoutRow(split, 1);
+
+ if(depth > 0) {
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ if(lnode && (lnode->inputs.first || (lnode->typeinfo->uifunc && lnode->type != NODE_GROUP))) {
+ int icon = (input->flag & SOCK_COLLAPSED)? ICON_DISCLOSURE_TRI_RIGHT: ICON_DISCLOSURE_TRI_DOWN;
+ uiItemR(row, &inputptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", icon);
+ }
+ else
+ uiItemL(row, "", ICON_BLANK1);
+
+ bt = block->buttons.last;
+ bt->x2 = UI_UNIT_X/2;
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+
+ uiItemL(row, label, ICON_NONE);
+ bt= block->buttons.last;
+ bt->flag= UI_TEXT_LEFT;
+
+ if(lnode) {
+ /* input linked to a node */
+ uiTemplateNodeLink(split, ntree, node, input);
+
+ if(!(input->flag & SOCK_COLLAPSED)) {
+ if(depth == 0)
+ uiItemS(layout);
+
+ ui_node_draw_node(layout, C, ntree, lnode, depth);
+ }
+ }
+ else {
+ /* input not linked, show value */
+ if(input->type != SOCK_SHADER && !(input->flag & SOCK_HIDE_VALUE)) {
+ if(input->type == SOCK_VECTOR) {
+ row = uiLayoutRow(split, 0);
+ col = uiLayoutColumn(row, 0);
+
+ uiItemR(col, &inputptr, "default_value", 0, "", 0);
+ }
+ else {
+ row = uiLayoutRow(split, 1);
+ uiItemR(row, &inputptr, "default_value", 0, "", 0);
+ }
+ }
+ else
+ row = uiLayoutRow(split, 0);
+
+ uiTemplateNodeLink(row, ntree, node, input);
+ }
+
+ /* clear */
+ node->flag &= ~NODE_TEST;
+}
+
+void uiTemplateNodeView(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input)
+{
+ bNode *tnode;
+
+ if(!ntree)
+ return;
+
+ /* clear for cycle check */
+ for(tnode=ntree->nodes.first; tnode; tnode=tnode->next)
+ tnode->flag &= ~NODE_TEST;
+
+ if(input)
+ ui_node_draw_input(layout, C, ntree, node, input, 0);
+ else
+ ui_node_draw_node(layout, C, ntree, node, 0);
+}
+
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 6f40f28ea5c..a297f9bdf0f 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -77,6 +77,8 @@
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_unit.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
#include "BKE_tessmesh.h"
@@ -205,6 +207,40 @@ static void view3d_project_short_noclip(ARegion *ar, const float vec[3], short *
}
}
+/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */
+static void view3d_project_short_clip_persmat(ARegion *ar, float *vec, short *adr, int local)
+{
+ RegionView3D *rv3d= ar->regiondata;
+ float fx, fy, vec4[4];
+
+ adr[0]= IS_CLIPPED;
+
+ /* clipplanes in eye space */
+ if(rv3d->rflag & RV3D_CLIPPING) {
+ if(ED_view3d_test_clipping(rv3d, vec, local))
+ return;
+ }
+
+ copy_v3_v3(vec4, vec);
+ vec4[3]= 1.0;
+
+ mul_m4_v4(rv3d->persmat, vec4);
+
+ /* clipplanes in window space */
+ if( vec4[3] > (float)BL_NEAR_CLIP ) { /* is the NEAR clipping cutoff for picking */
+ fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]);
+
+ if( fx>0 && fx<ar->winx) {
+
+ fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]);
+
+ if(fy > 0.0f && fy < (float)ar->winy) {
+ adr[0]= (short)floorf(fx);
+ adr[1]= (short)floorf(fy);
+ }
+ }
+ }
+}
/* ************************ */
/* check for glsl drawing */
@@ -736,7 +772,12 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
for(vos= strings->first; vos; vos= vos->next) {
if(mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
mul_m4_v3(mat, vos->vec);
- view3d_project_short_clip(ar, vos->vec, vos->sco, 0);
+
+ if(vos->flag&V3D_CACHE_TEXT_GLOBALSPACE)
+ view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, 0);
+ else
+ view3d_project_short_clip(ar, vos->vec, vos->sco, 0);
+
if(vos->sco[0]!=IS_CLIPPED)
tot++;
}
@@ -1368,16 +1409,203 @@ float view3d_camera_border_hack_col[4];
short view3d_camera_border_hack_test= FALSE;
#endif
+/* ****************** draw clip data *************** */
+
+static void draw_bundle_sphere(void)
+{
+ static GLuint displist= 0;
+
+ if (displist == 0) {
+ GLUquadricObj *qobj;
+
+ displist= glGenLists(1);
+ glNewList(displist, GL_COMPILE);
+
+ qobj= gluNewQuadric();
+ gluQuadricDrawStyle(qobj, GLU_FILL);
+ glShadeModel(GL_SMOOTH);
+ gluSphere(qobj, 0.05, 8, 8);
+ glShadeModel(GL_FLAT);
+ gluDeleteQuadric(qobj);
+
+ glEndList();
+ }
+
+ glCallList(displist);
+}
+
+static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag)
+{
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingTrack *track;
+ float mat[4][4], imat[4][4], curcol[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);
+
+ 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);
+
+ /* 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);
+
+ 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));
+
+ glPushMatrix();
+ glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
+ glScalef(v3d->bundle_size/0.05, v3d->bundle_size/0.05, v3d->bundle_size/0.05);
+
+ if(v3d->drawtype==OB_WIRE) {
+ glDisable(GL_LIGHTING);
+ glDepthMask(0);
+
+ if(selected) {
+ if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+ else UI_ThemeColor(TH_SELECT);
+ } else {
+ if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+ else UI_ThemeColor(TH_WIRE);
+ }
+
+ drawaxes(0.05f, v3d->bundle_drawtype);
+
+ glDepthMask(1);
+ glEnable(GL_LIGHTING);
+ } else if(v3d->drawtype>OB_WIRE) {
+ if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) {
+ /* selection outline */
+ if(selected) {
+ 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);
+
+ draw_bundle_sphere();
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glEnable(GL_LIGHTING);
+ glLineWidth(1.f);
+ glDepthMask(1);
+ }
+
+ if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+ else UI_ThemeColor(TH_BUNDLE_SOLID);
+
+ draw_bundle_sphere();
+ } else {
+ glDisable(GL_LIGHTING);
+ glDepthMask(0);
+
+ if(selected) {
+ if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
+ else UI_ThemeColor(TH_SELECT);
+ } else {
+ if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
+ else UI_ThemeColor(TH_WIRE);
+ }
+
+ drawaxes(0.05f, v3d->bundle_drawtype);
+
+ glDepthMask(1);
+ glEnable(GL_LIGHTING);
+ }
+ }
+
+ glPopMatrix();
+
+ if((flag & DRAW_PICKING)==0 && (v3d->flag2&V3D_SHOW_BUNDLENAME)) {
+ float pos[3];
+ unsigned char tcol[4];
+
+ if(selected) memcpy(tcol, scol, sizeof(tcol));
+ else memcpy(tcol, col, sizeof(tcol));
+
+ mul_v3_m4v3(pos, mat, track->bundle_pos);
+ view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol);
+ }
+
+ bundlenr++;
+ }
+
+ 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;
+
+ glDisable(GL_LIGHTING);
+ UI_ThemeColor(TH_CAMERA_PATH);
+ glLineWidth(2.0f);
+
+ glBegin(GL_LINE_STRIP);
+ for(a= 0; a<reconstruction->camnr; a++, camera++) {
+ glVertex3f(camera->mat[3][0], camera->mat[3][1], camera->mat[3][2]);
+ }
+ glEnd();
+
+ glLineWidth(1.0f);
+ glEnable(GL_LIGHTING);
+ }
+ }
+
+ glPopMatrix();
+
+ /* restore */
+ glShadeModel(GL_FLAT);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_LIGHTING);
+
+ glColor4fv(curcol);
+
+ if(flag&DRAW_PICKING)
+ glLoadName(base->selcol);
+}
+
/* flag similar to draw_object() */
-static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int flag)
+static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag)
{
/* a standing up pyramid with (0,0,0) as top */
Camera *cam;
+ Object *ob= base->object;
float tvec[3];
float vec[4][3], asp[2], shift[2], scale[3];
int i;
float drawsize;
const short is_view= (rv3d->persp==RV3D_CAMOB && ob==v3d->camera);
+ MovieClip *clip= object_get_movieclip(scene, base->object, 0);
+
+ /* draw data for movie clip set as active for scene */
+ if(clip)
+ draw_viewport_reconstruction(scene, base, v3d, clip, flag);
#ifdef VIEW3D_CAMERA_BORDER_HACK
if(is_view && !(G.f & G_PICKSEL)) {
@@ -6165,7 +6393,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
break;
case OB_CAMERA:
if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0 || (rv3d->persp==RV3D_CAMOB && v3d->camera==ob)) /* special exception for active camera */
- drawcamera(scene, v3d, rv3d, ob, flag);
+ drawcamera(scene, v3d, rv3d, base, flag);
break;
case OB_SPEAKER:
if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index faf4e9412be..218b7ce4dbf 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -250,6 +250,7 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->gridflag &= ~V3D_SHOW_Z;
v3d->flag |= V3D_SELECT_OUTLINE;
+ v3d->flag2 |= V3D_SHOW_RECONSTRUCTION;
v3d->lens= 35.0f;
v3d->near= 0.01f;
@@ -259,6 +260,9 @@ static SpaceLink *view3d_new(const bContext *C)
v3d->twtype= V3D_MANIP_TRANSLATE;
v3d->around= V3D_CENTROID;
+ v3d->bundle_size= 0.2f;
+ v3d->bundle_drawtype= OB_PLAINAXES;
+
/* header */
ar= MEM_callocN(sizeof(ARegion), "header for view3d");
@@ -745,6 +749,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
/* same as above */
ED_region_tag_redraw(ar);
break;
+ case NC_MOVIECLIP:
+ if(wmn->data==ND_DISPLAY)
+ ED_region_tag_redraw(ar);
+ break;
case NC_SPACE:
if(wmn->data == ND_SPACE_VIEW3D) {
if (wmn->subtype == NS_VIEW3D_GPU) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 309578699f7..51bbf591bb3 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -62,6 +62,7 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_unit.h"
+#include "BKE_movieclip.h"
#include "RE_engine.h"
#include "RE_pipeline.h" // make_stars
@@ -1487,7 +1488,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
RegionView3D *rv3d= ar->regiondata;
BGpic *bgpic;
Image *ima;
- ImBuf *ibuf= NULL;
+ MovieClip *clip;
+ ImBuf *ibuf= NULL, *freeibuf;
float vec[4], fac, asp, zoomx, zoomy;
float x1, y1, x2, y2, cx, cy;
@@ -1498,15 +1500,46 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
(bgpic->view & (1<<rv3d->view)) || /* check agaist flags */
(rv3d->persp==RV3D_CAMOB && bgpic->view == (1<<RV3D_VIEW_CAMERA))
) {
- ima= bgpic->ima;
- if(ima==NULL)
- continue;
- BKE_image_user_calc_frame(&bgpic->iuser, CFRA, 0);
- ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser);
- if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL) )
+ freeibuf= NULL;
+ if(bgpic->source==V3D_BGPIC_IMAGE) {
+ ima= bgpic->ima;
+ if(ima==NULL)
+ continue;
+ BKE_image_user_calc_frame(&bgpic->iuser, CFRA, 0);
+ ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser);
+ } else {
+ 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;
+
+ if(clip==NULL)
+ continue;
+
+ BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA);
+ ibuf= BKE_movieclip_get_ibuf(clip, &bgpic->cuser);
+
+ /* working with ibuf from image and clip has got different workflow now.
+ ibuf acquired from clip is referenced by cache system and should
+ be dereferenced after usage. */
+ freeibuf= ibuf;
+ }
+
+ if(ibuf==NULL)
continue;
- if(ibuf->channels!=4)
+
+ if((ibuf->rect==NULL && ibuf->rect_float==NULL) || ibuf->channels!=4) { /* invalid image format */
+ if(freeibuf)
+ IMB_freeImBuf(freeibuf);
+
continue;
+ }
+
if(ibuf->rect==NULL)
IMB_rect_from_float(ibuf);
@@ -1545,10 +1578,12 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
/* complete clip? */
- if(x2 < 0 ) continue;
- if(y2 < 0 ) continue;
- if(x1 > ar->winx ) continue;
- if(y1 > ar->winy ) continue;
+ if(x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) {
+ if(freeibuf)
+ IMB_freeImBuf(freeibuf);
+
+ continue;
+ }
zoomx= (x2-x1)/ibuf->x;
zoomy= (y2-y1)/ibuf->y;
@@ -1603,6 +1638,9 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
glDepthMask(1);
if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+
+ if(freeibuf)
+ IMB_freeImBuf(freeibuf);
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index b677a8fd7cf..7331959ef51 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2940,18 +2940,8 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
static BGpic *background_image_add(bContext *C)
{
View3D *v3d= CTX_wm_view3d(C);
-
- BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image");
- bgpic->size= 5.0;
- bgpic->blend= 0.5;
- bgpic->iuser.fie_ima= 2;
- bgpic->iuser.ok= 1;
- bgpic->view= 0; /* 0 for all */
- bgpic->flag |= V3D_BGPIC_EXPANDED;
-
- BLI_addtail(&v3d->bgpicbase, bgpic);
-
- return bgpic;
+
+ return ED_view3D_background_image_add(v3d);
}
static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3027,7 +3017,8 @@ static int background_image_remove_exec(bContext *C, wmOperator *op)
if(bgpic_rem) {
BLI_remlink(&vd->bgpicbase, bgpic_rem);
- if(bgpic_rem->ima) bgpic_rem->ima->id.us--;
+ if(bgpic_rem->ima) id_us_min(&bgpic_rem->ima->id);
+ if(bgpic_rem->clip) id_us_min(&bgpic_rem->clip->id);
MEM_freeN(bgpic_rem);
WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, vd);
return OPERATOR_FINISHED;
@@ -3534,3 +3525,18 @@ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], co
ED_view3d_to_m4(mat, ofs, quat, dist);
object_apply_mat4(ob, mat, TRUE, TRUE);
}
+
+BGpic *ED_view3D_background_image_add(View3D *v3d)
+{
+ BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image");
+
+ bgpic->size= 5.0;
+ bgpic->blend= 0.5;
+ bgpic->iuser.fie_ima= 2;
+ bgpic->iuser.ok= 1;
+ bgpic->view= 0; /* 0 for all */
+
+ BLI_addtail(&v3d->bgpicbase, bgpic);
+
+ return bgpic;
+}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index b07d2d1ca73..5aa8d95912d 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -121,6 +121,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
#define V3D_CACHE_TEXT_ZBUF (1<<0)
#define V3D_CACHE_TEXT_WORLDSPACE (1<<1)
#define V3D_CACHE_TEXT_ASCII (1<<2)
+#define V3D_CACHE_TEXT_GLOBALSPACE (1<<3)
/* drawarmature.c */
int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index d719ac188e5..29c7f2cc7fd 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -42,6 +42,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_tracking_types.h"
#include "MEM_guardedalloc.h"
@@ -61,6 +62,9 @@
#include "BKE_paint.h"
#include "BKE_armature.h"
#include "BKE_tessmesh.h"
+#include "BKE_movieclip.h"
+#include "BKE_object.h"
+#include "BKE_tracking.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -1380,6 +1384,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce
if(hits>0) {
int has_bones= 0;
+ /* note: bundles are handling in the same way as bones */
for(a=0; a<hits; a++) if(buffer[4*a+3] & 0xFFFF0000) has_bones= 1;
/* note; shift+alt goes to group-flush-selecting */
@@ -1390,7 +1395,45 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce
}
if(has_bones && basact) {
- if(ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) { /* then bone is found */
+ if(basact->object->type==OB_CAMERA) {
+ if(BASACT==basact) {
+ int i, hitresult;
+ MovieTrackingTrack *track;
+
+ 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))
+ 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);
+
+ selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT);
+
+ if(selected && extend) BKE_tracking_deselect_track(track, TRACK_AREA_ALL);
+ else BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, extend);
+
+ basact->flag|= SELECT;
+ basact->object->flag= basact->flag;
+
+ retval= 1;
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, track);
+ WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
+
+ break;
+ }
+ }
+ }
+ }
+ else if(ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) { /* then bone is found */
/* we make the armature selected:
not-selected active object in posemode won't work well for tools */
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index ed5c480643c..582ee56961a 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -57,6 +57,7 @@
#include "BKE_object.h"
#include "BKE_tessmesh.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_tracking.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -804,6 +805,37 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
/* **************************************************** */
+static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
+{
+ MovieTrackingTrack *track;
+ MovieClip *clip= object_get_movieclip(scene, ob, 0);
+ int ok= 0;
+ float min[3], max[3], mat[4][4], pos[3];
+
+ if(!clip)
+ return;
+
+ 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);
+ }
+
+ track= track->next;
+ }
+
+ if(ok) {
+ interp_v3_v3v3(vec, min, max, 0.5);
+ }
+}
+
static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit= CTX_data_edit_object(C);
@@ -868,6 +900,15 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
else {
CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
copy_v3_v3(vec, ob->obmat[3]);
+
+ /* special case for camera -- snap to bundles */
+ if(ob->type==OB_CAMERA) {
+ /* snap to bundles should happen only when bundles are visible */
+ if(v3d->flag2&V3D_SHOW_RECONSTRUCTION) {
+ bundle_midpoint(scene, ob, vec);
+ }
+ }
+
add_v3_v3(centroid, vec);
DO_MINMAX(vec, min, max);
count++;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 99d7017258f..e5ae4aa56b3 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -48,6 +48,7 @@
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
#include "RNA_access.h"
@@ -71,6 +72,7 @@
#include "ED_markers.h"
#include "ED_view3d.h"
#include "ED_mesh.h"
+#include "ED_clip.h"
#include "UI_view2d.h"
#include "WM_types.h"
@@ -159,6 +161,17 @@ void convertViewVec(TransInfo *t, float *vec, int dx, int dy)
else if(ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
convertViewVec2D(&t->ar->v2d, vec, dx, dy);
}
+ else if(t->spacetype==SPACE_CLIP) {
+ View2D *v2d = t->view;
+ float divx, divy;
+
+ divx= v2d->mask.xmax-v2d->mask.xmin;
+ divy= v2d->mask.ymax-v2d->mask.ymin;
+
+ vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx;
+ vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy;
+ vec[2]= 0.0f;
+ }
}
void projectIntView(TransInfo *t, float *vec, int *adr)
@@ -209,6 +222,9 @@ void projectIntView(TransInfo *t, float *vec, int *adr)
adr[0]= out[0];
adr[1]= out[1];
}
+ else if(t->spacetype==SPACE_CLIP) {
+ UI_view2d_to_region_no_clip(t->view, vec[0], vec[1], adr, adr+1);
+ }
}
void projectFloatView(TransInfo *t, float *vec, float *adr)
@@ -217,7 +233,7 @@ void projectFloatView(TransInfo *t, float *vec, float *adr)
if(t->ar->regiontype == RGN_TYPE_WINDOW)
project_float_noclip(t->ar, vec, adr);
}
- else if(t->spacetype==SPACE_IMAGE) {
+ else if(ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
int a[2];
projectIntView(t, vec, a);
@@ -315,6 +331,15 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
if(sima->lock) WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data);
else ED_area_tag_redraw(t->sa);
}
+ else if (t->spacetype==SPACE_CLIP) {
+ SpaceClip *sc= (SpaceClip*)t->sa->spacedata.first;
+ MovieClip *clip= ED_space_clip(sc);
+
+ /* objects could be parented to tracking data, so send this for viewport refresh */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+ }
}
static void viewRedrawPost(bContext *C, TransInfo *t)
@@ -583,10 +608,18 @@ int transformEvent(TransInfo *t, wmEvent *event)
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
}
+ else if(t->mode == TFM_TRANSLATION) {
+ if(t->options&CTX_MOVIECLIP) {
+ restoreTransObjects(t);
+
+ t->flag^= T_ALT_TRANSFORM;
+ t->redraw |= TREDRAW_HARD;
+ }
+ }
break;
case TFM_MODAL_ROTATE:
/* only switch when... */
- if(!(t->options & CTX_TEXTURE)) {
+ if(!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) {
if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
resetTransRestrictions(t);
@@ -841,7 +874,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
break;
case RKEY:
/* only switch when... */
- if(!(t->options & CTX_TEXTURE)) {
+ if(!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) {
if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
resetTransRestrictions(t);
@@ -1506,6 +1539,11 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
//t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
}
+ else if(t->spacetype == SPACE_CLIP) {
+ unit_m3(t->spacemtx);
+ t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+ t->options |= CTX_MOVIECLIP;
+ }
else
unit_m3(t->spacemtx);
@@ -3297,7 +3335,7 @@ void initTranslation(TransInfo *t)
t->snap[2] = t->snap[1] * 0.1f;
}
}
- else if(t->spacetype == SPACE_IMAGE) {
+ else if(ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
t->snap[0] = 0.0f;
t->snap[1] = 0.125f;
t->snap[2] = 0.0625f;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 7138fd01fdd..9bc62fdf952 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -394,6 +394,9 @@ typedef struct TransInfo {
#define T_RELEASE_CONFIRM (1 << 23)
+ /* alternative transformation. used to add offset to tracking markers */
+#define T_ALT_TRANSFORM (1 << 24)
+
/* TransInfo->modifiers */
#define MOD_CONSTRAINT_SELECT 0x01
#define MOD_PRECISION 0x02
@@ -558,6 +561,7 @@ void flushTransParticles(TransInfo *t);
int clipUVTransform(TransInfo *t, float *vec, int resize);
void flushTransNodes(TransInfo *t);
void flushTransSeq(TransInfo *t);
+void flushTransTracking(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index d391289df15..b104c5bb513 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -51,6 +51,7 @@
#include "DNA_scene_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
#include "MEM_guardedalloc.h"
@@ -75,6 +76,9 @@
#include "BKE_tessmesh.h"
#include "BKE_scene.h"
#include "BKE_report.h"
+#include "BKE_tracking.h"
+#include "BKE_movieclip.h"
+#include "BKE_node.h"
#include "ED_anim_api.h"
@@ -89,8 +93,12 @@
#include "ED_node.h"
#include "ED_types.h"
#include "ED_uvedit.h"
+#include "ED_clip.h"
#include "ED_util.h" /* for crazyspace correction */
+#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
+#include "WM_types.h"
+
#include "UI_view2d.h"
#include "BLI_math.h"
@@ -4933,6 +4941,17 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
/* clear link line */
ED_node_link_intersect_test(t->sa, 0);
}
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sc= t->sa->spacedata.first;
+ MovieClip *clip= ED_space_clip(sc);
+
+ if(t->scene->nodetree) {
+ /* tracks can be used for stabilization nodes,
+ flush update for such nodes */
+ nodeUpdateID(t->scene->nodetree, &clip->id);
+ WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+ }
+ }
else if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
bAnimContext ac;
@@ -5401,6 +5420,229 @@ static void createTransNodeData(bContext *C, TransInfo *t)
CTX_DATA_END
}
+/* *** CLIP EDITOR *** */
+
+typedef struct TransDataTracking {
+ int area;
+ float *relative, *loc;
+ float soffset[2], srelative[2];
+ float offset[2];
+
+ float (*smarkers)[2];
+ int markersnr;
+ MovieTrackingMarker *markers;
+} TransDataTracking;
+
+static void markerToTransDataInit(TransData *td, TransData2D *td2d,
+ TransDataTracking *tdt, MovieTrackingTrack *track, int area, float *loc, float *rel, float *off)
+{
+ int anchor = area==TRACK_AREA_POINT && off;
+
+ if(anchor) {
+ td2d->loc[0] = rel[0]; /* hold original location */
+ td2d->loc[1] = rel[1];
+
+ tdt->loc= loc;
+ td2d->loc2d = loc; /* current location */
+ } else {
+ td2d->loc[0] = loc[0]; /* hold original location */
+ td2d->loc[1] = loc[1];
+
+ td2d->loc2d = loc; /* current location */
+ }
+ td2d->loc[2] = 0.0f;
+
+ tdt->relative= rel;
+ tdt->area= area;
+
+ tdt->markersnr= track->markersnr;
+ tdt->markers= track->markers;
+
+ if(rel) {
+ if(!anchor) {
+ td2d->loc[0]+= rel[0];
+ td2d->loc[1]+= rel[1];
+ }
+
+ copy_v2_v2(tdt->srelative, rel);
+ }
+
+ if(off)
+ copy_v2_v2(tdt->soffset, off);
+
+ 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 trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d,
+ TransDataTracking *tdt, MovieTrackingTrack *track)
+{
+ MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
+
+ track->transflag= marker->flag;
+
+ marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED);
+
+ markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset);
+
+ if(track->flag&SELECT)
+ markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL);
+
+ if(track->pat_flag&SELECT) {
+ markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_min, marker->pos, NULL);
+ markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_max, marker->pos, NULL);
+ }
+
+ if(track->search_flag&SELECT) {
+ markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_min, marker->pos, NULL);
+ markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_max, marker->pos, NULL);
+ }
+}
+
+static void transDataTrackingFree(TransInfo *t)
+{
+ TransDataTracking *tdt= t->customData;
+
+ if(tdt) {
+ if(tdt->smarkers) MEM_freeN(tdt->smarkers);
+ MEM_freeN(tdt);
+ }
+}
+
+static void createTransTrackingData(bContext *C, TransInfo *t)
+{
+ TransData *td;
+ TransData2D *td2d;
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip(sc);
+ 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;
+ 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 */
+
+ 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;
+ }
+
+ 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 = clip->tracking.tracks.first;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
+ marker= BKE_tracking_get_marker(track, framenr);
+
+ trackToTransData(sc, td, td2d, tdt, track);
+
+ /* offset */
+ td++;
+ td2d++;
+ tdt++;
+
+ if((marker->flag&MARKER_DISABLED)==0) {
+ if(track->flag&SELECT) {td++; td2d++; tdt++;}
+ if(track->pat_flag&SELECT) {td+= 2; td2d+= 2;tdt+=2;}
+ }
+
+ if(track->search_flag&SELECT) {
+ td+= 2;
+ td2d+= 2;
+ tdt+= 2;
+
+ if(marker->flag&MARKER_DISABLED) {
+ td+= 3;
+ td2d+= 3;
+ tdt+= 3;
+ };
+ }
+ }
+
+ track = track->next;
+ }
+}
+
+void flushTransTracking(TransInfo *t)
+{
+ TransData *td;
+ TransData2D *td2d;
+ TransDataTracking *tdt;
+ int a;
+
+ /* flush to 2d vector from internally used 3d vector */
+ for(a=0, td= t->data, td2d= t->data2d, tdt= t->customData; a<t->total; 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->smarkers) {
+ tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers");
+ for(a= 0; a<tdt->markersnr; 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(d2, td2d->loc, tdt->srelative);
+
+ for(a= 0; a<tdt->markersnr; a++)
+ add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
+
+ 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->relative)
+ sub_v2_v2(td2d->loc2d, tdt->relative);
+ }
+ }
+}
+
void createTransData(bContext *C, TransInfo *t)
{
Scene *scene = t->scene;
@@ -5466,6 +5708,10 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
+ else if (t->spacetype == SPACE_CLIP) {
+ t->flag |= T_POINTS|T_2D_EDIT;
+ createTransTrackingData(C, t);
+ }
else if (t->obedit) {
t->ext = NULL;
if (t->obedit->type == OB_MESH) {
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 09a4e366611..409dbdf33af 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -47,6 +47,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_view3d_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_movieclip_types.h"
#include "RNA_access.h"
@@ -71,6 +72,7 @@
#include "BKE_nla.h"
#include "BKE_context.h"
#include "BKE_tessmesh.h"
+#include "BKE_tracking.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -84,6 +86,7 @@
#include "ED_uvedit.h"
#include "ED_view3d.h"
#include "ED_curve.h" /* for curve_editnurbs */
+#include "ED_clip.h"
//#include "BDR_unwrapper.h"
@@ -865,6 +868,48 @@ void recalcData(TransInfo *t)
else if (t->spacetype == SPACE_VIEW3D) {
recalcData_view3d(t);
}
+ else if (t->spacetype == SPACE_CLIP) {
+ SpaceClip *sc= t->sa->spacedata.first;
+ MovieClip *clip= ED_space_clip(sc);
+ 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;
+ while(track) {
+ if(TRACK_VIEW_SELECTED(sc, track)) {
+ if (t->mode == TFM_TRANSLATION) {
+ if(TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_clamp_track(track, CLAMP_PAT_POS);
+ if(TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS);
+ }
+ else if (t->mode == TFM_RESIZE) {
+ if(TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))
+ BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
+ if(TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+ }
+ }
+
+ track= track->next;
+ }
+
+ DAG_id_tag_update(&clip->id, 0);
+ }
}
void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index f926f442830..7951fe0ee02 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -973,6 +973,11 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
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");
break;
+ case SPACE_CLIP:
+ 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);
+ WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
+ break;
default:
break;
}
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 1badfb458ee..e56d5802e1f 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
../include/BIF_glutil.h
../include/ED_anim_api.h
../include/ED_armature.h
+ ../include/ED_clip.h
../include/ED_curve.h
../include/ED_datafiles.h
../include/ED_fileselect.h
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 787766f0fa6..2a83052c827 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -526,12 +526,14 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose
/* 6. apply the differences to the channels,
we need to calculate the original differences first */
- for(a=0; a<tree->totchannel; a++)
+ for(a=0; a<tree->totchannel; a++) {
make_dmats(tree->pchan[a]);
+ }
- for(a=0; a<tree->totchannel; a++)
+ for(a=0; a<tree->totchannel; a++) {
/* sets POSE_DONE */
where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
+ }
/* 7. and free */
BLI_remlink(&pchan->iktree, tree);
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 6f2933d154b..7fa26478ae2 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -194,6 +194,7 @@ typedef struct PreviewImage {
#define ID_PA MAKE_ID2('P', 'A') /* ParticleSettings */
#define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */
#define ID_WM MAKE_ID2('W', 'M') /* WindowManager */
+#define ID_MC MAKE_ID2('M', 'C') /* MovieClip */
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
#define ID_SEQ MAKE_ID2('S', 'Q')
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index db574160771..b198231df3a 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -198,7 +198,9 @@ typedef struct bPoseChannel {
struct Bone *bone; /* set on read file or rebuild pose */
struct bPoseChannel *parent; /* set on read file or rebuild pose */
struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */
- struct ListBase iktree; /* only while evaluating pose */
+
+ struct ListBase iktree; /* "IK trees" - only while evaluating pose */
+ struct ListBase siktree; /* Spline-IK "trees" - only while evaluating pose */
bMotionPath *mpath; /* motion path cache for this bone */
struct Object *custom; /* draws custom object instead of default bone shape */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 00f6f2433af..3620131b8df 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -406,6 +406,18 @@ typedef struct bShrinkwrapConstraint {
char pad[9];
} bShrinkwrapConstraint;
+/* Follow Track constraints */
+typedef struct bFollowTrackConstraint {
+ struct MovieClip *clip;
+ char track[24];
+ int flag, reference;
+} bFollowTrackConstraint;
+
+/* Camera Solver constraints */
+typedef struct bCameraSolverConstraint {
+ struct MovieClip *clip;
+ int flag, pad;
+} bCameraSolverConstraint;
/* ------------------------------------------ */
@@ -440,6 +452,8 @@ typedef enum eBConstraint_Types {
CONSTRAINT_TYPE_TRANSLIKE, /* Copy transform matrix */
CONSTRAINT_TYPE_SAMEVOL, /* Maintain volume during scaling */
CONSTRAINT_TYPE_PIVOT, /* Pivot Constraint */
+ CONSTRAINT_TYPE_FOLLOWTRACK, /* Follow Track Constraint */
+ CONSTRAINT_TYPE_CAMERASOLVER, /* Camera Solver Constraint */
/* NOTE: no constraints are allowed to be added after this */
NUM_CONSTRAINT_TYPES
@@ -737,6 +751,21 @@ typedef enum ePivotConstraint_Flag {
PIVOTCON_FLAG_ROTACT_NEG = (1<<1)
} ePivotConstraint_Flag;
+/* FollowTrack Constraint -> flag */
+typedef enum eFollowTrack_Reference {
+ FOLLOWTRACK_TRACK = (1<<0),
+ FOLLOWTRACK_BUNDLE = (1<<1)
+} FollowTrack_Reference;
+
+typedef enum eFollowTrack_Flags {
+ FOLLOWTRACK_ACTIVECLIP = (1<<0)
+} eFollowTrack_Flags;
+
+/* CameraSolver Constraint -> flag */
+typedef enum eCameraSolver_Flags {
+ CAMERASOLVER_ACTIVECLIP = (1<<0)
+} eCameraSolver_Flags;
+
/* Rigid-Body Constraint */
#define CONSTRAINT_DRAW_PIVOT 0x40
#define CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index a2a288d1f82..594d416157a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -30,7 +30,8 @@
#define MODSTACK_DEBUG 1
-/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */
+/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE!
+ * (ONLY ADD NEW ITEMS AT THE END) */
typedef enum ModifierType {
eModifierType_None = 0,
diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h
new file mode 100644
index 00000000000..fc21f26fa32
--- /dev/null
+++ b/source/blender/makesdna/DNA_movieclip_types.h
@@ -0,0 +1,126 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** 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
+ */
+
+#include "DNA_ID.h"
+#include "DNA_tracking_types.h"
+
+struct anim;
+struct bGPdata;
+struct ImBuf;
+struct MovieClipProxy;
+struct MovieTrackingTrack;
+struct MovieTrackingMarker;
+
+typedef struct MovieClipUser {
+ int framenr; /* current frame number */
+ short render_size, render_flag; /* proxy render size */
+} MovieClipUser;
+
+typedef struct MovieClipProxy {
+ char dir[160]; /* 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 */
+
+ int source; /* sequence or movie */
+ int lastframe; /* last accessed frame number */
+ int lastsize[2]; /* size of last accessed frame */
+
+ float aspx, aspy; /* display aspect */
+
+ struct anim *anim; /* movie source data */
+ struct MovieClipCache *cache; /* cache for different stuff, not in file */
+ struct bGPdata *gpd; /* grease pencil data */
+
+ struct MovieTracking tracking; /* data for SfM tracking */
+ void *tracking_context; /* context of tracking job
+ used to synchronize data like framenumber
+ in SpaceClip clip user */
+
+ struct MovieClipProxy proxy; /* proxy to clip data */
+ int flag, pad;
+} MovieClip;
+
+typedef struct MovieClipScopes {
+ int ok; /* 1 means scopes are ok and recalculation is unneeded */
+ int track_preview_height; /* height of track preview widget */
+ struct ImBuf *track_preview; /* ImBuf displayed in track preview */
+ float track_pos[2]; /* sub-pizel position of marker in track ImBuf */
+ short track_disabled; /* active track is disabled, special notifier should be drawn */
+ char pad[2];
+ int framenr; /* frame number scopes are created for */
+ struct MovieTrackingTrack *track; /* track scopes are created for */
+ struct MovieTrackingMarker *marker; /* marker scopes are created for */
+ 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 */
+
+/* MovieClip->source */
+#define MCLIP_SRC_SEQUENCE 1
+#define MCLIP_SRC_MOVIE 2
+
+/* MovieClip->selection types */
+#define MCLIP_SEL_NONE 0
+#define MCLIP_SEL_TRACK 1
+
+/* MovieClip->flag */
+#define MCLIP_USE_PROXY (1<<0)
+#define MCLIP_USE_PROXY_CUSTOM_DIR (1<<1)
+
+/* MovieClip->render_size */
+#define MCLIP_PROXY_RENDER_SIZE_FULL 0
+#define MCLIP_PROXY_RENDER_SIZE_25 1
+#define MCLIP_PROXY_RENDER_SIZE_50 2
+#define MCLIP_PROXY_RENDER_SIZE_75 3
+#define MCLIP_PROXY_RENDER_SIZE_100 4
+
+/* MovieClip->render_flag */
+#define MCLIP_PROXY_RENDER_UNDISTORT 1
+
+#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index cc77df7e679..27e21290a9b 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -54,6 +54,7 @@ struct AnimData;
struct Editing;
struct SceneStats;
struct bGPdata;
+struct MovieClip;
typedef struct Base {
struct Base *next, *prev;
@@ -863,6 +864,9 @@ typedef struct Scene {
/* Physics simulation settings */
struct PhysicsSettings physics_settings;
+
+ /* Movie Tracking */
+ struct MovieClip *clip; /* active movie clip */
} Scene;
@@ -1337,7 +1341,6 @@ typedef enum SculptFlags {
#define USER_UNIT_OPT_SPLIT 1
#define USER_UNIT_ROT_RADIANS 2
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 0c7943ce056..289c7ac2fc3 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -37,6 +37,7 @@
#include "DNA_vec_types.h"
#include "DNA_outliner_types.h" /* for TreeStoreElem */
#include "DNA_image_types.h" /* ImageUser */
+#include "DNA_movieclip_types.h" /* MovieClipUser */
/* Hum ... Not really nice... but needed for spacebuts. */
#include "DNA_view2d_types.h"
@@ -62,6 +63,8 @@ struct bScreen;
struct Scene;
struct wmOperator;
struct wmTimer;
+struct MovieClip;
+struct MovieClipScopes;
/**
* The base structure all the other spaces
@@ -489,6 +492,32 @@ typedef struct SpaceUserPref {
} SpaceUserPref;
+typedef struct SpaceClip {
+ SpaceLink *next, *prev;
+ ListBase regionbase; /* storage of regions for inactive spaces */
+ int spacetype;
+
+ float xof, yof; /* user defined offset, image is centered */
+ float xlockof, ylockof; /* user defined offset from locked position */
+ float zoom; /* user defined zoom level */
+
+ struct MovieClipUser user; /* user of clip */
+ struct MovieClip *clip; /* clip data */
+ struct MovieClipScopes scopes; /* different scoped displayed in space panels */
+
+ int flag; /* flags */
+ short mode; /* editor mode (editing context being displayed) */
+ short view; /* type of the clip editor view */
+
+ int path_length; /* length of displaying path, in frames */
+
+ /* current stabilization data */
+ float loc[2], scale, angle; /* pre-composed stabilization data */
+ 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 */
+} SpaceClip;
+
/* view3d Now in DNA_view3d_types.h */
@@ -824,6 +853,7 @@ enum {
#define TIME_ALL_IMAGE_WIN 64
#define TIME_CONTINUE_PHYSICS 128
#define TIME_NODES 256
+#define TIME_CLIPS 512
/* time->cache */
#define TIME_CACHE_DISPLAY 1
@@ -861,6 +891,33 @@ enum {
#define SEQ_PROXY_RENDER_SIZE_100 99
#define SEQ_PROXY_RENDER_SIZE_FULL 100
+/* SpaceClip->flag */
+#define SC_SHOW_MARKER_PATTERN (1<<0)
+#define SC_SHOW_MARKER_SEARCH (1<<1)
+#define SC_LOCK_SELECTION (1<<2)
+#define SC_SHOW_TINY_MARKER (1<<3)
+#define SC_SHOW_TRACK_PATH (1<<4)
+#define SC_SHOW_BUNDLES (1<<5)
+#define SC_MUTE_FOOTAGE (1<<6)
+#define SC_HIDE_DISABLED (1<<7)
+#define SC_SHOW_NAMES (1<<8)
+#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_FILTERS (1<<13)
+#define SC_SHOW_GRAPH_FRAMES (1<<14)
+#define SC_SHOW_GRAPH_TRACKS (1<<15)
+#define SC_SHOW_PYRAMID_LEVELS (1<<16)
+
+/* SpaceClip->mode */
+#define SC_MODE_TRACKING 0
+#define SC_MODE_RECONSTRUCTION 1
+#define SC_MODE_DISTORTION 2
+
+/* SpaceClip->view */
+#define SC_VIEW_CLIP 0
+#define SC_VIEW_GRAPH 1
/* space types, moved from DNA_screen_types.h */
/* Do NOT change order, append on end. types are hardcoded needed */
@@ -885,7 +942,8 @@ enum {
SPACE_LOGIC,
SPACE_CONSOLE,
SPACE_USERPREF,
- SPACEICONMAX = SPACE_USERPREF
+ SPACE_CLIP,
+ SPACEICONMAX = SPACE_CLIP
};
#endif
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 4cf31edb891..1ecca5a0b2a 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -267,11 +267,13 @@ typedef struct Tex {
} Tex;
-/* used for mapping node. note: rot is in degrees */
+/* used for mapping and texture nodes. note: rot is in degrees */
typedef struct TexMapping {
float loc[3], rot[3], size[3];
int flag;
+ char projx, projy, projz, mapping;
+ int pad;
float mat[4][4];
float min[3], max[3];
@@ -279,10 +281,24 @@ typedef struct TexMapping {
} TexMapping;
+typedef struct ColorMapping {
+ struct ColorBand coba;
+
+ float bright, contrast, saturation;
+ int flag;
+
+ float blend_color[3];
+ float blend_factor;
+ int blend_type, pad[3];
+} ColorMapping;
+
/* texmap->flag */
-#define TEXMAP_CLIP_MIN 1
-#define TEXMAP_CLIP_MAX 2
+#define TEXMAP_CLIP_MIN 1
+#define TEXMAP_CLIP_MAX 2
+#define TEXMAP_UNIT_MATRIX 4
+/* colormap->flag */
+#define COLORMAP_USE_RAMP 1
/* **************** TEX ********************* */
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
new file mode 100644
index 00000000000..b359ea3544d
--- /dev/null
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -0,0 +1,217 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** 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
+ */
+
+#include "DNA_listBase.h"
+
+/* match-moving data */
+
+struct ImBuf;
+struct MovieReconstructedCamera;
+struct MovieTrackingCamera;
+struct MovieTrackingBundle;
+struct MovieTrackingMarker;
+struct MovieTrackingTrack;
+struct MovieTracking;
+
+typedef struct MovieReconstructedCamera {
+ int framenr;
+ float error;
+ float mat[4][4];
+} MovieReconstructedCamera;
+
+typedef struct MovieTrackingCamera {
+ void *intrinsics; /* intrinsics handle */
+
+ float sensor_width; /* width of CCD sensor */
+ float pixel_aspect; /* pixel aspect ratio */
+ float pad;
+ float focal; /* focal length */
+ short units; /* units of focal length user is working with */
+ short pad1;
+ float principal[2]; /* principal point */
+ float k1, k2, k3; /* radial distortion */
+} MovieTrackingCamera;
+
+typedef struct MovieTrackingMarker {
+ float pos[2]; /* 2d position of marker on frame (in unified 0..1 space) */
+ int framenr; /* number of frame marker is associated with */
+ int flag; /* Marker's flag (alive, ...) */
+} MovieTrackingMarker;
+
+typedef struct MovieTrackingTrack {
+ struct MovieTrackingTrack *next, *prev;
+
+ char name[24];
+
+ /* ** setings ** */
+ float pat_min[2], pat_max[2]; /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */
+ float search_min[2], search_max[2]; /* positions of left-bottom and right-top corners of search area (in unified 0..1 space) */
+ float offset[2]; /* offset to "parenting" point */
+
+ /* ** track ** */
+ int markersnr; /* count of markers in track */
+ int last_marker; /* most recently used marker */
+ MovieTrackingMarker *markers; /* markers in track */
+
+ /* ** reconstruction data ** */
+ 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 */
+ short tracker;
+ char pad4[2];
+
+ /* ** SAD tracker settings ** */
+ float minimum_correlation; /* minimal correlation which is still treated as successful tracking */
+
+ /* ** KLT tracker settings ** */
+ int pyramid_levels; /* number of pyramid levels to use for KLT tracking */
+ char pad5[4];
+} MovieTrackingTrack;
+
+typedef struct MovieTrackingSettings {
+ /* ** common tracker settings ** */
+ short speed; /* speed of tracking */
+ short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */
+ short margin; /* margin from frame boundaries */
+ char pad[2];
+
+ int adjframes; /* re-adjust every N frames */
+
+ /* ** reconstruction settings ** */
+ int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */
+
+ /* ** tool settings ** */
+
+ /* set scale */
+ float dist; /* distance between two bundles used for scene scaling */
+
+ /* cleanup */
+ int clean_frames, clean_action;
+ float clean_error;
+} MovieTrackingSettings;
+
+typedef struct MovieTrackingStabilization {
+ int flag;
+ int tot_track, act_track; /* total number and index of active track in list */
+
+ /* 2d stabilization */
+ float maxscale; /* max auto-scale factor */
+ MovieTrackingTrack *rot_track; /* track used to stabilize rotation */
+
+ float locinf, scaleinf, rotinf; /* influence on location, scale and rotation */
+
+ /* some pre-computing run-time variables */
+ int ok, pad; /* are precomputed values and scaled buf relevant? */
+ float scale; /* autoscale factor */
+
+ struct ImBuf *scaleibuf; /* currently scaled ibuf */
+} MovieTrackingStabilization;
+
+typedef struct MovieTrackingReconstruction {
+ int flag;
+
+ float error; /* average error of reconstruction */
+
+ int last_camera; /* most recently used camera */
+ int camnr; /* number of reconstructed cameras */
+ struct MovieReconstructedCamera *cameras; /* reconstructed cameras */
+} MovieTrackingReconstruction;
+
+typedef struct MovieTracking {
+ MovieTrackingSettings settings; /* different tracking-related settings */
+ char pad2[4];
+
+ MovieTrackingCamera camera; /* camera intrinsics */
+ ListBase tracks; /* all tracks */
+ MovieTrackingReconstruction reconstruction; /* reconstruction data */
+ MovieTrackingStabilization stabilization; /* stabilization data */
+ MovieTrackingTrack *act_track; /* active track */
+} MovieTracking;
+
+/* MovieTrackingCamera->units */
+enum {
+ CAMERA_UNITS_PX = 0,
+ CAMERA_UNITS_MM
+};
+
+/* MovieTrackingMarker->flag */
+#define MARKER_DISABLED (1<<0)
+#define MARKER_TRACKED (1<<1)
+#define MARKER_GRAPH_SEL (1<<2)
+
+/* MovieTrackingTrack->flag */
+#define TRACK_HAS_BUNDLE (1<<1)
+#define TRACK_DISABLE_RED (1<<2)
+#define TRACK_DISABLE_GREEN (1<<3)
+#define TRACK_DISABLE_BLUE (1<<4)
+#define TRACK_HIDDEN (1<<5)
+#define TRACK_LOCKED (1<<6)
+#define TRACK_CUSTOMCOLOR (1<<7)
+#define TRACK_USE_2D_STAB (1<<8)
+
+/* MovieTrackingSettings->tracker */
+#define TRACKER_KLT 0
+#define TRACKER_SAD 1
+
+/* MovieTrackingSettings->speed */
+#define TRACKING_SPEED_FASTEST 0
+#define TRACKING_SPEED_REALTIME 1
+#define TRACKING_SPEED_HALF 2
+#define TRACKING_SPEED_QUARTER 4
+#define TRACKING_SPEED_DOUBLE 5
+
+/* MovieTrackingStrabilization->flag */
+#define TRACKING_2D_STABILIZATION (1<<0)
+#define TRACKING_AUTOSCALE (1<<1)
+
+/* MovieTrackingReconstruction->flag */
+#define TRACKING_RECONSTRUCTED (1<<0)
+
+#define TRACKING_CLEAN_SELECT 0
+#define TRACKING_CLEAN_DELETE_TRACK 1
+#define TRACKING_CLEAN_DELETE_SEGMENT 2
+
+#endif
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index e1b4d9d138c..81753ed5b21 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -234,6 +234,11 @@ typedef struct ThemeSpace {
char handle_vertex_select[4];
char handle_vertex_size;
+
+ char marker_outline[4], marker[4], act_marker[4], sel_marker[4], dis_marker[4], lock_marker[4];
+ char bundle_solid[4];
+ char path_before[4], path_after[4];
+ char camera_path[4];
char hpad[7];
char preview_back[4];
@@ -279,6 +284,7 @@ typedef struct bTheme {
ThemeSpace tlogic;
ThemeSpace tuserpref;
ThemeSpace tconsole;
+ ThemeSpace tclip;
/* 20 sets of bone colors for this theme */
ThemeWireColor tarm[20];
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index aaf4186945e..93f4b209712 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -38,6 +38,8 @@ struct Tex;
struct SpaceLink;
struct Base;
struct BoundBox;
+struct MovieClip;
+struct MovieClipUser;
struct RenderInfo;
struct RenderEngine;
struct bGPdata;
@@ -55,6 +57,7 @@ struct wmTimer;
#include "DNA_listBase.h"
#include "DNA_image_types.h"
+#include "DNA_movieclip_types.h"
/* ******************************** */
@@ -67,10 +70,12 @@ typedef struct BGpic {
struct Image *ima;
struct ImageUser iuser;
+ struct MovieClip *clip;
+ struct MovieClipUser cuser;
float xof, yof, size, blend;
short view;
short flag;
- float pad2;
+ short source, pad;
} BGpic;
/* ********************************* */
@@ -146,7 +151,12 @@ typedef struct View3D {
float blockscale;
short blockhandler[8];
- float viewquat[4], dist, pad1; /* XXX depricated */
+ float viewquat[4], dist; /* XXX depricated */
+
+ float bundle_size; /* size of bundles in reconstructed data */
+ short bundle_drawtype; /* display style for bundle */
+
+ char pad[6];
unsigned int lay_used; /* used while drawing */
@@ -248,6 +258,9 @@ typedef struct View3D {
#define V3D_DISPGP 16
#define V3D_LOCK_CAMERA 32
#define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */
+#define V3D_SHOW_RECONSTRUCTION 128
+#define V3D_SHOW_CAMERAPATH 256
+#define V3D_SHOW_BUNDLENAME 512
/* View3D->around */
#define V3D_CENTER 0
@@ -294,6 +307,12 @@ typedef struct View3D {
/* BGPic->flag */
/* may want to use 1 for select ?*/
#define V3D_BGPIC_EXPANDED 2
+#define V3D_BGPIC_CAMERACLIP 4
+
+/* BGPic->source */
+/* may want to use 1 for select ?*/
+#define V3D_BGPIC_IMAGE 0
+#define V3D_BGPIC_MOVIE 1
#define RV3D_CAMZOOM_MIN -30
#define RV3D_CAMZOOM_MAX 600
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index a966523d990..ec60fc7b2b8 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -131,6 +131,8 @@ const char *includefiles[] = {
"DNA_boid_types.h",
"DNA_smoke_types.h",
"DNA_speaker_types.h",
+ "DNA_movieclip_types.h",
+ "DNA_tracking_types.h",
// empty string to indicate end of includefiles
""
@@ -1196,4 +1198,6 @@ int main(int argc, char ** argv)
#include "DNA_boid_types.h"
#include "DNA_smoke_types.h"
#include "DNA_speaker_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_tracking_types.h"
/* end of list */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index e22789218ad..665215b6592 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -473,6 +473,7 @@ extern StructRNA RNA_SpaceTimeline;
extern StructRNA RNA_SpaceUVEditor;
extern StructRNA RNA_SpaceUserPreferences;
extern StructRNA RNA_SpaceView3D;
+extern StructRNA RNA_SpaceClipEditor;
extern StructRNA RNA_Speaker;
extern StructRNA RNA_SpeedControlSequence;
extern StructRNA RNA_Spline;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 68f0a52c0a9..904d26aac71 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -59,6 +59,7 @@ set(DEFSRC
rna_mesh.c
rna_meta.c
rna_modifier.c
+ rna_movieclip.c
rna_nla.c
rna_nodetree.c
rna_object.c
@@ -82,6 +83,7 @@ set(DEFSRC
rna_text.c
rna_texture.c
rna_timeline.c
+ rna_tracking.c
rna_ui.c
rna_userdef.c
rna_vfont.c
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 891b62f7c79..533d1e2c929 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2479,6 +2479,8 @@ static RNAProcessItem PROCESS_ITEMS[]= {
{"rna_vfont.c", NULL, RNA_def_vfont},
{"rna_wm.c", "rna_wm_api.c", RNA_def_wm},
{"rna_world.c", NULL, RNA_def_world},
+ {"rna_movieclip.c", NULL, RNA_def_movieclip},
+ {"rna_tracking.c", NULL, RNA_def_tracking},
{NULL, NULL}};
static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const char *api_filename)
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index e4692d32338..eed178b238d 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -143,6 +143,7 @@ short RNA_type_to_ID_code(StructRNA *type)
if(RNA_struct_is_a(type, &RNA_VectorFont)) return ID_VF;
if(RNA_struct_is_a(type, &RNA_World)) return ID_WO;
if(RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM;
+ if(RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC;
return 0;
}
@@ -177,6 +178,7 @@ StructRNA *ID_code_to_RNA_type(short idcode)
case ID_VF: return &RNA_VectorFont;
case ID_WO: return &RNA_World;
case ID_WM: return &RNA_WindowManager;
+ case ID_MC: return &RNA_MovieClip;
default: return &RNA_ID;
}
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index fdbb4f09f93..e1e4f3929b2 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -64,9 +64,11 @@ EnumPropertyItem constraint_type_items[] ={
{CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To", "Legacy tracking constraint prone to twisting artifacts"},
{0, "", 0, "Relationship", ""},
{CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action", ""},
+ {CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""},
{CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of", ""},
{CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor", ""},
{CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path", ""},
+ {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
{CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot", ""},
{CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint", ""},
{CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script", ""},
@@ -156,6 +158,10 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
return &RNA_CopyTransformsConstraint;
case CONSTRAINT_TYPE_PIVOT:
return &RNA_PivotConstraint;
+ case CONSTRAINT_TYPE_FOLLOWTRACK:
+ return &RNA_FollowTrackConstraint;
+ case CONSTRAINT_TYPE_CAMERASOLVER:
+ return &RNA_CameraSolverConstraint;
default:
return &RNA_UnknownType;
}
@@ -2026,6 +2032,70 @@ static void rna_def_constraint_pivot(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
+static void rna_def_constraint_follow_track(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem reference_items[] = {
+ {FOLLOWTRACK_TRACK, "TRACK", 0, "Track", "Use 2D track position as reference"},
+ {FOLLOWTRACK_BUNDLE, "BUNDLE", 0, "Bundle", "Use 3D reconstructed bundle position as reference"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "FollowTrackConstraint", "Constraint");
+ RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Locks motion to the target motion track");
+ RNA_def_struct_sdna_from(srna, "bFollowTrackConstraint", "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");
+
+ /* track */
+ prop= RNA_def_property(srna, "track", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "track");
+ RNA_def_property_ui_text(prop, "Track", "Movie tracking track to follow");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ /* reference */
+ prop= RNA_def_property(srna, "reference", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "reference");
+ RNA_def_property_enum_items(prop, reference_items);
+ RNA_def_property_ui_text(prop, "Reference", "Reference source to follow");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ /* use default clip */
+ prop= RNA_def_property(srna, "use_active_clip", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", FOLLOWTRACK_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");
+}
+
+static void rna_def_constraint_camera_solver(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "CameraSolverConstraint", "Constraint");
+ RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Locks motion to the reconstructed camera movenment");
+ RNA_def_struct_sdna_from(srna, "bCameraSolverConstraint", "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");
+}
+
/* base struct for constraints */
void RNA_def_constraint(BlenderRNA *brna)
{
@@ -2136,6 +2206,8 @@ void RNA_def_constraint(BlenderRNA *brna)
rna_def_constraint_damped_track(brna);
rna_def_constraint_spline_ik(brna);
rna_def_constraint_pivot(brna);
+ rna_def_constraint_follow_track(brna);
+ rna_def_constraint_camera_solver(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 2e3b371c3f3..a137ddc6bc0 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -177,6 +177,8 @@ void RNA_def_userdef(struct BlenderRNA *brna);
void RNA_def_vfont(struct BlenderRNA *brna);
void RNA_def_wm(struct BlenderRNA *brna);
void RNA_def_world(struct BlenderRNA *brna);
+void RNA_def_movieclip(struct BlenderRNA *brna);
+void RNA_def_tracking(struct BlenderRNA *brna);
/* Common Define functions */
@@ -290,6 +292,7 @@ void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop);
/* ID Properties */
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 076bdfe1964..be03da6839d 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -245,6 +245,12 @@ static void rna_Main_wm_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
rna_iterator_listbase_begin(iter, &bmain->wm, NULL);
}
+static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Main *bmain= (Main*)ptr->data;
+ rna_iterator_listbase_begin(iter, &bmain->movieclip, NULL);
+}
+
#ifdef UNIT_TEST
static PointerRNA rna_Test_test_get(PointerRNA *ptr)
@@ -307,6 +313,7 @@ void RNA_def_main(BlenderRNA *brna)
{"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks", RNA_def_main_actions},
{"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks", RNA_def_main_particles},
{"grease_pencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks", RNA_def_main_gpencil},
+ {"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips},
{NULL, NULL, NULL, NULL, NULL, NULL}};
int i;
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index dfa368d6b94..f568f6de855 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -66,6 +66,7 @@
#include "BKE_node.h"
#include "BKE_depsgraph.h"
#include "BKE_speaker.h"
+#include "BKE_movieclip.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
@@ -85,6 +86,7 @@
#include "DNA_particle_types.h"
#include "DNA_vfont_types.h"
#include "DNA_node_types.h"
+#include "DNA_movieclip_types.h"
#include "ED_screen.h"
@@ -521,6 +523,26 @@ void rna_Main_particles_remove(Main *bmain, ReportList *reports, ParticleSetting
/* XXX python now has invalid pointer? */
}
+MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath)
+{
+ MovieClip *clip;
+
+ errno= 0;
+ clip= BKE_add_movieclip_file(filepath);
+
+ if(!clip)
+ BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s.", filepath, errno ? strerror(errno) : "Unable to load movie clip");
+
+ return clip;
+}
+
+void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip)
+{
+ unlink_movieclip(bmain, clip);
+ free_libblock(&bmain->movieclip, clip);
+ /* XXX python now has invalid pointer? */
+}
+
/* tag functions, all the same */
void rna_Main_cameras_tag(Main *bmain, int value) { tag_main_lb(&bmain->camera, value); }
void rna_Main_scenes_tag(Main *bmain, int value) { tag_main_lb(&bmain->scene, value); }
@@ -550,6 +572,7 @@ void rna_Main_armatures_tag(Main *bmain, int value) { tag_main_lb(&bmain->armatu
void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action, value); }
void rna_Main_particles_tag(Main *bmain, int value) { tag_main_lb(&bmain->particle, value); }
void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); }
+void rna_Main_movieclips_tag(Main *bmain, int value) { tag_main_lb(&bmain->text, value); }
static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); }
static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); }
@@ -1468,5 +1491,36 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_boolean_funcs(prop, "rna_Main_gpencil_is_updated_get", NULL);
}
+void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "BlendDataMovieClips");
+ srna= RNA_def_struct(brna, "BlendDataMovieClips", NULL);
+ RNA_def_struct_sdna(srna, "Main");
+ RNA_def_struct_ui_text(srna, "Main Movie Clips", "Collection of movie clips");
+
+ func= RNA_def_function(srna, "tag", "rna_Main_movieclips_tag");
+ parm= RNA_def_boolean(func, "value", 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "remove", "rna_Main_movieclips_remove");
+ RNA_def_function_ui_description(func, "Remove a movie clip from the current blendfile.");
+ parm= RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+
+ /* load func */
+ func= RNA_def_function(srna, "load", "rna_Main_movieclip_load");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Add a new movie clip to the main database from a file");
+ parm= RNA_def_string_file_path(func, "filepath", "Path", FILE_MAXDIR + FILE_MAXFILE, "", "path for the datablock");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /* return type */
+ parm= RNA_def_pointer(func, "clip", "MovieClip", "", "New movie clip datablock");
+ RNA_def_function_return(func, parm);
+}
+
#endif
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
new file mode 100644
index 00000000000..afdf3cd9c46
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -0,0 +1,278 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_movieclip.c
+ * \ingroup RNA
+ */
+
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_depsgraph.h"
+
+static void rna_MovieClip_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+
+ BKE_movieclip_reload(clip);
+ DAG_id_tag_update(&clip->id, 0);
+}
+
+static void rna_MovieClip_size_get(PointerRNA *ptr, int *values)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+
+ values[0]= clip->lastsize[0];
+ values[1]= clip->lastsize[1];
+}
+
+static void rna_MovieClip_resolution_get(PointerRNA *ptr, float *values)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ ImBuf *ibuf;
+
+ ibuf= BKE_movieclip_get_ibuf(clip, NULL);
+ if (ibuf) {
+ values[0]= ibuf->ppm[0];
+ values[1]= ibuf->ppm[1];
+
+ IMB_freeImBuf(ibuf);
+ }
+ else {
+ values[0]= 0;
+ values[1]= 0;
+ }
+}
+
+#else
+
+static void rna_def_movieclip_proxy(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem clip_tc_items[]= {
+ {IMB_TC_NONE, "NONE", 0, "No TC in use", ""},
+ {IMB_TC_RECORD_RUN, "RECORD_RUN", 0, "Record Run", "use images in the order as 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"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna = RNA_def_struct(brna, "MovieClipProxy", NULL);
+ RNA_def_struct_ui_text(srna, "Movie Clip Proxy", "Proxy parameters for a movie clip");
+ RNA_def_struct_sdna(srna, "MovieClipProxy");
+
+ /* 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_ui_text(prop, "25%", "Build 25% proxy resolution");
+
+ 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_ui_text(prop, "50%", "Build 50% proxy resolution");
+
+ 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_ui_text(prop, "75%", "Build 75% proxy resolution");
+
+ 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_ui_text(prop, "100%", "Build 100% proxy resolution");
+
+ 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");
+
+ /* build timecodes */
+ prop= RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_RECORD_RUN);
+ RNA_def_property_ui_text(prop, "Rec Run", "Build record run time code index");
+
+ prop= RNA_def_property(srna, "build_free_run", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_FREE_RUN);
+ RNA_def_property_ui_text(prop, "Free Run", "Build free run time code index");
+
+ prop= RNA_def_property(srna, "build_free_run_rec_date", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN);
+ RNA_def_property_ui_text(prop, "Free Run (Rec Date)", "Build free run time code index using Record Date/Time");
+
+ /* quality of proxied image */
+ prop= RNA_def_property(srna, "quality", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "quality");
+ RNA_def_property_ui_text(prop, "Quality", "JPEG Quality of proxies to build");
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
+
+ prop= RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "tc");
+ RNA_def_property_enum_items(prop, clip_tc_items);
+ RNA_def_property_ui_text(prop, "Timecode", "");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* directory */
+ prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
+ RNA_def_property_string_sdna(prop, NULL, "dir");
+ RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update");
+}
+
+static void rna_def_moviecliUser(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem clip_render_size_items[] = {
+ {MCLIP_PROXY_RENDER_SIZE_25, "PROXY_25", 0, "Proxy size 25%", ""},
+ {MCLIP_PROXY_RENDER_SIZE_50, "PROXY_50", 0, "Proxy size 50%", ""},
+ {MCLIP_PROXY_RENDER_SIZE_75, "PROXY_75", 0, "Proxy size 75%", ""},
+ {MCLIP_PROXY_RENDER_SIZE_100, "PROXY_100", 0, "Proxy size 100%", ""},
+ {MCLIP_PROXY_RENDER_SIZE_FULL, "FULL", 0, "No proxy, full render", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "MovieClipUser", NULL);
+ RNA_def_struct_ui_text(srna, "Movie Clip User", "Parameters defining how a MovieClip datablock is used by another datablock");
+
+ prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_TIME);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_int_sdna(prop, NULL, "framenr");
+ RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
+ RNA_def_property_ui_text(prop, "Current Frame", "Current frame number in movie or image sequence");
+
+ /* render size */
+ prop= RNA_def_property(srna, "proxy_render_size", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "render_size");
+ RNA_def_property_enum_items(prop, clip_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_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* render undistorted */
+ prop= RNA_def_property(srna, "use_render_undistorted", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "render_flag", MCLIP_PROXY_RENDER_UNDISTORT);
+ RNA_def_property_ui_text(prop, "Render Undistorted", "Draw preview using undistorted proxy");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+}
+
+static void rna_def_movieClipScopes(BlenderRNA *brna)
+{
+ StructRNA *srna;
+
+ srna= RNA_def_struct(brna, "MovieClipScopes", NULL);
+ RNA_def_struct_ui_text(srna, "MovieClipScopes", "Scopes for statistical view of a movie clip");
+}
+
+
+static void rna_def_movieclip(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem clip_source_items[]= {
+ {MCLIP_SRC_SEQUENCE, "SEQUENCE", 0, "Image Sequence", "Multiple image files, as a sequence"},
+ {MCLIP_SRC_MOVIE, "MOVIE", 0, "Movie File", "Movie file"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "MovieClip", "ID");
+ RNA_def_struct_ui_text(srna, "MovieClip", "MovieClip datablock referencing an external movie file");
+ RNA_def_struct_ui_icon(srna, ICON_SEQUENCE);
+
+ prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property_string_sdna(prop, NULL, "name");
+ RNA_def_property_ui_text(prop, "File Path", "Filename of the text file");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update");
+
+ prop= RNA_def_property(srna, "tracking", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieTracking");
+
+ prop= RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieClipProxy");
+
+ /* use proxy */
+ prop= RNA_def_property(srna, "use_proxy", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY);
+ RNA_def_property_ui_text(prop, "Use Proxy / Timecode", "Use a preview proxy and/or timecode index for this clip");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ prop= RNA_def_int_vector(srna, "size" , 2 , NULL , 0, 0, "Size" , "Width and height in pixels, zero when image data cant be loaded" , 0 , 0);
+ RNA_def_property_int_funcs(prop, "rna_MovieClip_size_get" , NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop= RNA_def_float_vector(srna, "resolution" , 2 , NULL , 0, 0, "Resolution" , "X/Y pixels per meter" , 0 , 0);
+ RNA_def_property_float_funcs(prop, "rna_MovieClip_resolution_get", NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop= RNA_def_property(srna, "display_aspect", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "aspx");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_range(prop, 0.1f, 5000.0f);
+ RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2);
+ RNA_def_property_ui_text(prop, "Display Aspect", "Display Aspect for this clip, does not affect rendering");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* source */
+ prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, clip_source_items);
+ RNA_def_property_ui_text(prop, "Source", "Where the clip comes from");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ /* custom proxy directory */
+ prop= RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY_CUSTOM_DIR);
+ RNA_def_property_ui_text(prop, "Proxy Custom Directory", "Use a custom directory to store data");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update");
+
+ /* grease pencil */
+ prop= RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "gpd");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip");
+}
+
+void RNA_def_movieclip(BlenderRNA *brna)
+{
+ rna_def_movieclip(brna);
+ rna_def_movieclip_proxy(brna);
+ rna_def_moviecliUser(brna);
+ rna_def_movieClipScopes(brna);
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 1445cf3b537..7e74c490e5c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -425,15 +425,6 @@ static void rna_NodeSocketVector_range(PointerRNA *ptr, float *min, float *max)
*max = val->max;
}
-static void rna_Node_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr)
-{
- bNode *node= (bNode*)ptr->data;
-
- init_mapping((TexMapping *)node->storage);
-
- rna_Node_update(bmain, scene, ptr);
-}
-
static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNode *node= (bNode*)ptr->data;
@@ -1077,48 +1068,12 @@ static void def_sh_material(StructRNA *srna)
static void def_sh_mapping(StructRNA *srna)
{
PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "TexMapping", "storage");
- prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
- RNA_def_property_float_sdna(prop, NULL, "loc");
- RNA_def_property_ui_text(prop, "Location", "Location offset for the input coordinate");
- RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2);
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_mapping_update");
-
- prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_XYZ); /* Not PROP_EUL, this is already in degrees, not radians */
- RNA_def_property_float_sdna(prop, NULL, "rot");
- RNA_def_property_ui_text(prop, "Rotation", "Rotation offset for the input coordinate");
- RNA_def_property_ui_range(prop, -360.f, 360.f, 1.f, 2);
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_mapping_update");
-
- prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
- RNA_def_property_float_sdna(prop, NULL, "size");
- RNA_def_property_ui_text(prop, "Scale", "Scale adjustment for the input coordinate");
- RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2);
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_mapping_update");
-
- prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
- RNA_def_property_ui_text(prop, "Clamp Minimum", "Clamp the output coordinate to a minimum value");
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
-
- prop= RNA_def_property(srna, "min", PROP_FLOAT, PROP_XYZ);
- RNA_def_property_float_sdna(prop, NULL, "min");
- RNA_def_property_ui_text(prop, "Minimum", "Minimum value to clamp coordinate to");
- RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2);
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
- RNA_def_property_ui_text(prop, "Clamp Maximum", "Clamp the output coordinate to a maximum value");
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
-
- prop= RNA_def_property(srna, "max", PROP_FLOAT, PROP_XYZ);
- RNA_def_property_float_sdna(prop, NULL, "max");
- RNA_def_property_ui_text(prop, "Maximum", "Maximum value to clamp coordinate to");
- RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2);
- RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+ prop= RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "storage");
+ RNA_def_property_struct_type(prop, "TexMapping");
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Mapping", "Texture coordinate mapping settings");
}
static void def_sh_geometry(StructRNA *srna)
@@ -2414,6 +2369,84 @@ static void def_cmp_ycc(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}
+static void def_cmp_movieclip(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "MovieClip");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Movie Clip", "");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "MovieClipUser", "storage");
+}
+
+static void def_cmp_stabilize2d(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem filter_type_items[] = {
+ {0, "NEAREST", 0, "Nearest", ""},
+ {1, "BILINEAR", 0, "Bilinear", ""},
+ {2, "BICUBIC", 0, "Bicubic", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "MovieClip");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Movie Clip", "");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, filter_type_items);
+ RNA_def_property_ui_text(prop, "Filter", "Method to use to filter stabilization");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
+static void def_cmp_moviedistortion(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem distortion_type_items[] = {
+ {0, "UNDISTORT", 0, "Undistort", ""},
+ {1, "DISTORT", 0, "Distort", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "MovieClip");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Movie Clip", "");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "distortion_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, distortion_type_items);
+ RNA_def_property_ui_text(prop, "Distortion", "Distortion to use to filter image");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
+static void dev_cmd_transform(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ static EnumPropertyItem filter_type_items[] = {
+ {0, "NEAREST", 0, "Nearest", ""},
+ {1, "BILINEAR", 0, "Bilinear", ""},
+ {2, "BICUBIC", 0, "Bicubic", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, filter_type_items);
+ RNA_def_property_ui_text(prop, "Filter", "Method to use to filter transform");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
/* -- Texture Nodes --------------------------------------------------------- */
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index 1bbf47db094..2545826cd46 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -117,6 +117,10 @@ DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR
DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" )
DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" )
DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECORRECT", HueCorrect, "Hue Correct", "" )
+DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "MovieClip", "" )
+DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" )
+DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" )
+DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" )
DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 9abc7a7c192..c0291542213 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -78,7 +78,7 @@ EnumPropertyItem proportional_falloff_items[] ={
{PROP_ROOT, "ROOT", ICON_ROOTCURVE, "Root", "Root falloff"},
{PROP_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", "Sharp falloff"},
{PROP_LIN, "LINEAR", ICON_LINCURVE, "Linear", "Linear falloff"},
- {PROP_CONST, "CONSTANT", ICON_NOCURVE, "Constant", "Consant falloff"},
+ {PROP_CONST, "CONSTANT", ICON_NOCURVE, "Constant", "Constant falloff"},
{PROP_RANDOM, "RANDOM", ICON_RNDCURVE, "Random", "Random falloff"},
{0, NULL, 0, NULL, NULL}};
@@ -1076,6 +1076,15 @@ static void rna_Scene_update_active_object_data(Main *UNUSED(bmain), Scene *scen
}
}
+static void rna_SceneCamera_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ Scene *scene= (Scene*)ptr->id.data;
+ Object *camera= scene->camera;
+
+ if(camera)
+ DAG_id_tag_update(&camera->id, 0);
+}
+
#else
static void rna_def_transform_orientation(BlenderRNA *brna)
@@ -2430,13 +2439,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "xsch");
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, NULL);
+ 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_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, NULL);
+ 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");
@@ -2461,13 +2470,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "xasp");
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, NULL);
+ 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_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, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update");
/* JPEG and AVI JPEG */
@@ -3754,6 +3763,14 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "TransformOrientation");
RNA_def_property_ui_text(prop, "Transform Orientations", "");
+ /* active MovieClip */
+ prop= RNA_def_property(srna, "active_clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "clip");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "MovieClip");
+ RNA_def_property_ui_text(prop, "Active Movie Clip", "Active movie clip used for constraints and viewport drawing");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
/* Nestled Data */
rna_def_tool_settings(brna);
rna_def_unit_settings(brna);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 795ea417d90..c8792ef30f3 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -288,6 +288,11 @@ static void rna_def_screen(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_NODES);
RNA_def_property_ui_text(prop, "Node Editors", "");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_Screen_redraw_update");
+
+ prop= RNA_def_property(srna, "use_play_clip_editors", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_CLIPS);
+ RNA_def_property_ui_text(prop, "Clip Editors", "");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_Screen_redraw_update");
}
void RNA_def_screen(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 0dc4ca343fe..bb07fa86f3a 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -70,6 +70,7 @@ EnumPropertyItem space_type_items[] = {
{SPACE_LOGIC, "LOGIC_EDITOR", 0, "Logic Editor", ""},
{SPACE_CONSOLE, "CONSOLE", 0, "Python Console", ""},
{SPACE_USERPREF, "USER_PREFERENCES", 0, "User Preferences", ""},
+ {SPACE_CLIP, "CLIP_EDITOR", 0, "Clip Editor", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem draw_channels_items[] = {
@@ -126,6 +127,7 @@ EnumPropertyItem viewport_shade_items[] = {
#include "ED_screen.h"
#include "ED_view3d.h"
#include "ED_sequencer.h"
+#include "ED_clip.h"
#include "IMB_imbuf_types.h"
@@ -166,6 +168,8 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr)
return &RNA_SpaceConsole;
case SPACE_USERPREF:
return &RNA_SpaceUserPreferences;
+ case SPACE_CLIP:
+ return &RNA_SpaceClipEditor;
default:
return &RNA_Space;
}
@@ -883,6 +887,15 @@ static void rna_BackgroundImage_opacity_set(PointerRNA *ptr, float value)
bgpic->blend = 1.0f - value;
}
+static BGpic *rna_BackgroundImage_add(View3D *v3d)
+{
+ BGpic *bgpic= ED_view3D_background_image_add(v3d);;
+
+ WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ return bgpic;
+}
+
/* Space Node Editor */
static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, PointerRNA value)
@@ -955,6 +968,34 @@ static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C,
return item;
}
+static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value)
+{
+ SpaceClip *sc= (SpaceClip*)(ptr->data);
+
+ ED_space_clip_set(NULL, sc, (MovieClip*)value.data);
+}
+
+static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ SpaceClip *sc= (SpaceClip*)(ptr->data);
+
+ sc->scopes.ok= 0;
+}
+
+static void rna_SpaceClipEditor_lock_selection_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ SpaceClip *sc= (SpaceClip*)(ptr->data);
+
+ sc->xlockof= 0.f;
+ sc->ylockof= 0.f;
+}
+
+static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ ScrArea *sa= rna_area_from_space(ptr);
+ ED_area_tag_refresh(sa);
+}
+
#else
static void rna_def_space(BlenderRNA *brna)
@@ -1170,21 +1211,46 @@ static void rna_def_background_image(BlenderRNA *brna)
{(1<<RV3D_VIEW_CAMERA), "CAMERA", 0, "Camera", "Show background image in camera view"},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem bgpic_source_items[] = {
+ {V3D_BGPIC_IMAGE, "IMAGE", 0, "Image", ""},
+ {V3D_BGPIC_MOVIE, "MOVIE", 0, "Movie", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna= RNA_def_struct(brna, "BackgroundImage", NULL);
RNA_def_struct_sdna(srna, "BGpic");
RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3d View background");
+ prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "source");
+ RNA_def_property_enum_items(prop, bgpic_source_items);
+ RNA_def_property_ui_text(prop, "Background Source", "Data source used for background");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ima");
RNA_def_property_ui_text(prop, "Image", "Image displayed and edited in this space");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+ prop= RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "clip");
+ RNA_def_property_ui_text(prop, "MovieClip", "Movie clip displayed and edited in this space");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "iuser");
RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "clip_user", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "MovieClipUser");
+ RNA_def_property_pointer_sdna(prop, NULL, "cuser");
+ RNA_def_property_ui_text(prop, "Clip User", "Parameters defining which frame of the movie clip is displayed");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
prop= RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xof");
@@ -1220,6 +1286,28 @@ static void rna_def_background_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Expanded", "Show the expanded in the user interface");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
+ prop= RNA_def_property(srna, "use_camera_clip", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_BGPIC_CAMERACLIP);
+ RNA_def_property_ui_text(prop, "Camera Clip", "Use movie clip from active scene camera");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+}
+
+static void rna_def_backgroundImages(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "BackgroundImages");
+ srna= RNA_def_struct(brna, "BackgroundImages", NULL);
+ RNA_def_struct_sdna(srna, "View3D");
+ RNA_def_struct_ui_text(srna, "Background Images", "Collection of background images");
+
+ func= RNA_def_function(srna, "add", "rna_BackgroundImage_add");
+ RNA_def_function_ui_description(func, "Add new background image");
+
+ parm= RNA_def_pointer(func, "image", "BackgroundImage", "", "Image displayed as viewport background");
+ RNA_def_function_return(func, parm);
}
static void rna_def_space_view3d(BlenderRNA *brna)
@@ -1243,6 +1331,16 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{RV3D_CAMOB, "CAMERA", 0, "Camera", ""},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem bundle_drawtype_items[] = {
+ {OB_PLAINAXES, "PLAIN_AXES", 0, "Plain Axes", ""},
+ {OB_ARROWS, "ARROWS", 0, "Arrows", ""},
+ {OB_SINGLE_ARROW, "SINGLE_ARROW", 0, "Single Arrow", ""},
+ {OB_CIRCLE, "CIRCLE", 0, "Circle", ""},
+ {OB_CUBE, "CUBE", 0, "Cube", ""},
+ {OB_EMPTY_SPHERE, "SPHERE", 0, "Sphere", ""},
+ {OB_EMPTY_CONE, "CONE", 0, "Cone", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "SpaceView3D", "Space");
RNA_def_struct_sdna(srna, "View3D");
RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data");
@@ -1386,6 +1484,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "BackgroundImage");
RNA_def_property_ui_text(prop, "Background Images", "List of background images");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+ rna_def_backgroundImages(brna, prop);
prop= RNA_def_property(srna, "show_background_images", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_DISPBGPICS);
@@ -1471,6 +1570,33 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_SpaceView3D_region_quadview_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Quad View Region", "3D region that defines the quad view settings");
+ prop= RNA_def_property(srna, "show_reconstruction", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_RECONSTRUCTION);
+ RNA_def_property_ui_text(prop, "Show Reconstruction", "Display reconstruction data from active movie clip");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "bundle_draw_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_float_sdna(prop, NULL, "bundle_size");
+ RNA_def_property_ui_text(prop, "Bundle Size", "Display size of bundles from reconstructed data");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "bundle_draw_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "bundle_drawtype");
+ RNA_def_property_enum_items(prop, bundle_drawtype_items);
+ RNA_def_property_ui_text(prop, "Bundle Display Type", "Viewport display style for bundles");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "show_camera_path", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_CAMERAPATH);
+ RNA_def_property_ui_text(prop, "Show Camera Path", "Show reconstructed path of camera");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "show_bundle_name", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_BUNDLENAME);
+ RNA_def_property_ui_text(prop, "Show Bundle Name", "Show names for bundle objects");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
/* region */
srna= RNA_def_struct(brna, "RegionView3D", NULL);
@@ -1542,6 +1668,17 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "dist");
RNA_def_property_ui_text(prop, "Distance", "Distance to the view location");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "view_camera_zoom", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "camzoom");
+ RNA_def_property_ui_text(prop, "Camera Zoom", "Zoom factor in camera view");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+ prop= RNA_def_property(srna, "view_camera_offset", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "camdx");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_text(prop, "Camera Offset", "View shift in camera view");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
}
static void rna_def_space_buttons(BlenderRNA *brna)
@@ -2438,9 +2575,9 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "params");
RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser");
- prop= RNA_def_property(srna, "operator", PROP_POINTER, PROP_NONE);
+ prop= RNA_def_property(srna, "active_operator", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "op");
- RNA_def_property_ui_text(prop, "Operator", "");
+ RNA_def_property_ui_text(prop, "Active Operator", "");
}
static void rna_def_space_info(BlenderRNA *brna)
@@ -2659,6 +2796,172 @@ static void rna_def_space_logic(BlenderRNA *brna)
}
+static void rna_def_space_clip(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem mode_items[] = {
+ {SC_MODE_TRACKING, "TRACKING", ICON_ANIM_DATA, "Tracking", "Show tracking and solving tools"},
+ {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", ICON_SNAP_FACE, "Reconstruction", "Show tracking/reconstruction tools"},
+ {SC_MODE_DISTORTION, "DISTORTION", ICON_GRID, "Distortion", "Show distortion tools"},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem view_items[] = {
+ {SC_VIEW_CLIP, "CLIP", ICON_SEQUENCE, "Clip", "Show editing clip preview"},
+ {SC_VIEW_GRAPH, "GRAPH", ICON_IPO, "Graph", "Show graph view for active element"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "SpaceClipEditor", "Space");
+ RNA_def_struct_sdna(srna, "SpaceClip");
+ RNA_def_struct_ui_text(srna, "Space Clip Editor", "Clip editor space data");
+
+ /* movieclip */
+ prop= RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Movie Clip", "Movie clip displayed and edited in this space");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceClipEditor_clip_set", NULL, NULL);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* clip user */
+ prop= RNA_def_property(srna, "clip_user", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "MovieClipUser");
+ RNA_def_property_pointer_sdna(prop, NULL, "user");
+ RNA_def_property_ui_text(prop, "Movie Clip User", "Parameters defining which frame of the movie clip is displayed");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* mode */
+ prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mode");
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, "rna_SpaceClipEditor_clip_mode_update");
+
+ /* view */
+ prop= RNA_def_property(srna, "view", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "view");
+ RNA_def_property_enum_items(prop, view_items);
+ RNA_def_property_ui_text(prop, "View", "Type of the clip editor view");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, "rna_SpaceClipEditor_view_type_update");
+
+ /* show pattern */
+ prop= RNA_def_property(srna, "show_marker_pattern", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Marker Pattern", "Show pattern boundbox for markers");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_MARKER_PATTERN);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show search */
+ prop= RNA_def_property(srna, "show_marker_search", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Marker Search", "Show search boundbox for markers");
+ 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");
+
+ /* 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);
+ RNA_def_property_ui_text(prop, "Show Track Path", "Show path of how track moves");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* path length */
+ prop= RNA_def_property(srna, "path_length", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "path_length");
+ RNA_def_property_range(prop, 0, 50);
+ RNA_def_property_ui_text(prop, "Path Length", "Length of displaying path, in frames");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show tiny markers */
+ prop= RNA_def_property(srna, "show_tiny_markers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Tiny Markers", "Show markers tiny");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_TINY_MARKER);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show bundles */
+ prop= RNA_def_property(srna, "show_bundles", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Bundles", "Show projection of bundles into footage");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_BUNDLES);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* mute footage */
+ prop= RNA_def_property(srna, "use_mute_footage", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Mute Footage", "Mute footage and show black background instead");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_MUTE_FOOTAGE);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* hide disabled */
+ prop= RNA_def_property(srna, "show_disabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Show Disabled", "Show disabled tracks from the footage");
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SC_HIDE_DISABLED);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* scopes */
+ prop= RNA_def_property(srna, "scopes", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "scopes");
+ RNA_def_property_struct_type(prop, "MovieClipScopes");
+ RNA_def_property_ui_text(prop, "Scopes", "Scopes to visualize movie clip statistics");
+
+ /* show names */
+ prop= RNA_def_property(srna, "show_names", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_NAMES);
+ RNA_def_property_ui_text(prop, "Show Names", "Show track names and status");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show grid */
+ prop= RNA_def_property(srna, "show_grid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRID);
+ RNA_def_property_ui_text(prop, "Show Grid", "Show grid showing lens distortion");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show stable */
+ prop= RNA_def_property(srna, "show_stable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_STABLE);
+ RNA_def_property_ui_text(prop, "Show Stable", "Show stable footage in editor (if stabilization is enabled)");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* manual calibration */
+ prop= RNA_def_property(srna, "use_manual_calibration", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_MANUAL_CALIBRATION);
+ 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);
+ RNA_def_property_ui_text(prop, "Show Filters", "Show filters for graph editor");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show graph_frames */
+ prop= RNA_def_property(srna, "show_graph_frames", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_FRAMES);
+ RNA_def_property_ui_text(prop, "Show Frames", "Show curves for frames in graph editor");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+ /* show graph_tracks */
+ prop= RNA_def_property(srna, "show_graph_tracks", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS);
+ RNA_def_property_ui_text(prop, "Show Tracks", "Show curves for tracks in graph editor");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+}
+
+
void RNA_def_space(BlenderRNA *brna)
{
rna_def_space(brna);
@@ -2681,6 +2984,7 @@ void RNA_def_space(BlenderRNA *brna)
rna_def_space_userpref(brna);
rna_def_space_node(brna);
rna_def_space_logic(brna);
+ rna_def_space_clip(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index c420ecefdae..aac4da9e6f6 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -75,6 +75,25 @@ EnumPropertyItem texture_type_items[] = {
{TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - Wave generated bands or rings, with optional noise"},
{0, NULL, 0, NULL, NULL}};
+EnumPropertyItem blend_type_items[] = {
+ {MTEX_BLEND, "MIX", 0, "Mix", ""},
+ {MTEX_ADD, "ADD", 0, "Add", ""},
+ {MTEX_SUB, "SUBTRACT", 0, "Subtract", ""},
+ {MTEX_MUL, "MULTIPLY", 0, "Multiply", ""},
+ {MTEX_SCREEN, "SCREEN", 0, "Screen", ""},
+ {MTEX_OVERLAY, "OVERLAY", 0, "Overlay", ""},
+ {MTEX_DIFF, "DIFFERENCE", 0, "Difference", ""},
+ {MTEX_DIV, "DIVIDE", 0, "Divide", ""},
+ {MTEX_DARK, "DARKEN", 0, "Darken", ""},
+ {MTEX_LIGHT, "LIGHTEN", 0, "Lighten", ""},
+ {MTEX_BLEND_HUE, "HUE", 0, "Hue", ""},
+ {MTEX_BLEND_SAT, "SATURATION", 0, "Saturation", ""},
+ {MTEX_BLEND_VAL, "VALUE", 0, "Value", ""},
+ {MTEX_BLEND_COLOR, "COLOR", 0, "Color", ""},
+ {MTEX_SOFT_LIGHT, "SOFT_LIGHT", 0, "Soft Light", ""},
+ {MTEX_LIN_LIGHT , "LINEAR_LIGHT", 0, "Linear Light", ""},
+ {0, NULL, 0, NULL, NULL}};
+
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@@ -131,13 +150,33 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
}
}
-static void rna_Texture_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- Tex *tex= ptr->id.data;
+ ID *id= ptr->id.data;
- DAG_id_tag_update(&tex->id, 0);
- WM_main_add_notifier(NC_TEXTURE, tex);
- WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ if(GS(id->name) == ID_TE) {
+ Tex *tex= ptr->id.data;
+
+ DAG_id_tag_update(&tex->id, 0);
+ WM_main_add_notifier(NC_TEXTURE, tex);
+ WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, NULL);
+ }
+ else if(GS(id->name) == ID_NT) {
+ bNodeTree *ntree= ptr->id.data;
+ ED_node_generic_update(bmain, ntree, NULL);
+ }
+}
+
+static void rna_Texture_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ TexMapping *texmap = ptr->data;
+ init_tex_mapping(texmap);
+ rna_Texture_update(bmain, scene, ptr);
+}
+
+static void rna_Color_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ /* nothing to do */
}
static void rna_Texture_voxeldata_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -400,71 +439,139 @@ static char *rna_VoxelData_path(PointerRNA *UNUSED(ptr))
static void rna_def_texmapping(BlenderRNA *brna)
{
+ static EnumPropertyItem prop_mapping_items[] = {
+ {MTEX_FLAT, "FLAT", 0, "Flat", "Map X and Y coordinates directly"},
+ {MTEX_CUBE, "CUBE", 0, "Cube", "Map using the normal vector"},
+ {MTEX_TUBE, "TUBE", 0, "Tube", "Map with Z as central axis"},
+ {MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem prop_xyz_mapping_items[] = {
+ {0, "NONE", 0, "None", ""},
+ {1, "X", 0, "X", ""},
+ {2, "Y", 0, "Y", ""},
+ {3, "Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}};
+
StructRNA *srna;
PropertyRNA *prop;
srna= RNA_def_struct(brna, "TexMapping", NULL);
- RNA_def_struct_ui_text(srna, "Texture Mapping", "Mapping settings");
+ RNA_def_struct_ui_text(srna, "Texture Mapping", "Texture coordinate mapping settings");
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
- prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
+ prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_XYZ); /* Not PROP_EUL, this is already in degrees, not radians */
RNA_def_property_float_sdna(prop, NULL, "rot");
RNA_def_property_ui_text(prop, "Rotation", "");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_ui_text(prop, "Scale", "");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
prop= RNA_def_property(srna, "min", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum", "Minimum value for clipping");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
prop= RNA_def_property(srna, "max", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum", "Maximum value for clipping");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
prop= RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
RNA_def_property_ui_text(prop, "Has Minimum", "Whether to use minimum clipping value");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
prop= RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
RNA_def_property_ui_text(prop, "Has Maximum", "Whether to use maximum clipping value");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
+
+ prop= RNA_def_property(srna, "mapping_x", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projx");
+ RNA_def_property_enum_items(prop, prop_xyz_mapping_items);
+ RNA_def_property_ui_text(prop, "X Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
+
+ prop= RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projy");
+ RNA_def_property_enum_items(prop, prop_xyz_mapping_items);
+ RNA_def_property_ui_text(prop, "Y Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
+
+ prop= RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "projz");
+ RNA_def_property_enum_items(prop, prop_xyz_mapping_items);
+ RNA_def_property_ui_text(prop, "Z Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
+
+ prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_mapping_items);
+ RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
}
-static void rna_def_mtex(BlenderRNA *brna)
+static void rna_def_colormapping(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "ColorMapping", NULL);
+ RNA_def_struct_ui_text(srna, "Color Mapping", "Color mapping settings");
- static EnumPropertyItem prop_blend_type_items[] = {
- {MTEX_BLEND, "MIX", 0, "Mix", ""},
- {MTEX_ADD, "ADD", 0, "Add", ""},
- {MTEX_SUB, "SUBTRACT", 0, "Subtract", ""},
- {MTEX_MUL, "MULTIPLY", 0, "Multiply", ""},
- {MTEX_SCREEN, "SCREEN", 0, "Screen", ""},
- {MTEX_OVERLAY, "OVERLAY", 0, "Overlay", ""},
- {MTEX_DIFF, "DIFFERENCE", 0, "Difference", ""},
- {MTEX_DIV, "DIVIDE", 0, "Divide", ""},
- {MTEX_DARK, "DARKEN", 0, "Darken", ""},
- {MTEX_LIGHT, "LIGHTEN", 0, "Lighten", ""},
- {MTEX_BLEND_HUE, "HUE", 0, "Hue", ""},
- {MTEX_BLEND_SAT, "SATURATION", 0, "Saturation", ""},
- {MTEX_BLEND_VAL, "VALUE", 0, "Value", ""},
- {MTEX_BLEND_COLOR, "COLOR", 0, "Color", ""},
- {MTEX_SOFT_LIGHT, "SOFT_LIGHT", 0, "Soft Light", ""},
- {MTEX_LIN_LIGHT , "LINEAR_LIGHT", 0, "Linear Light", ""},
- {0, NULL, 0, NULL, NULL}};
+ prop= RNA_def_property(srna, "use_color_ramp", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", COLORMAP_USE_RAMP);
+ RNA_def_property_ui_text(prop, "Use Color Ramp", "Toggle color ramp operations");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "coba");
+ RNA_def_property_struct_type(prop, "ColorRamp");
+ RNA_def_property_ui_text(prop, "Color Ramp", "");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "brightness", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "bright");
+ RNA_def_property_range(prop, 0, 2);
+ RNA_def_property_ui_text(prop, "Brightness", "Adjust the brightness of the texture");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.01, 5);
+ RNA_def_property_ui_text(prop, "Contrast", "Adjust the contrast of the texture");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "saturation", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0, 2);
+ RNA_def_property_ui_text(prop, "Saturation", "Adjust the saturation of colors in the texture");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, blend_type_items);
+ RNA_def_property_ui_text(prop, "Blend Type", "Mode used to mix with texture output color");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "blend_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Color", "Blend color to mix with texture output color");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+
+ prop= RNA_def_property(srna, "blend_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Blend Factor", "");
+ RNA_def_property_update(prop, 0, "rna_Color_mapping_update");
+}
+
+static void rna_def_mtex(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
static EnumPropertyItem output_node_items[] = {
{0, "DUMMY", 0, "Dummy", ""},
@@ -512,7 +619,7 @@ static void rna_def_mtex(BlenderRNA *brna)
prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "blendtype");
- RNA_def_property_enum_items(prop, prop_blend_type_items);
+ RNA_def_property_enum_items(prop, blend_type_items);
RNA_def_property_ui_text(prop, "Blend Type", "Mode used to apply the texture");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
@@ -1866,6 +1973,7 @@ void RNA_def_texture(BlenderRNA *brna)
rna_def_mtex(brna);
rna_def_environment_map(brna);
rna_def_texmapping(brna);
+ rna_def_colormapping(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index d4e39a5a8e4..f1a6bb1b921 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -118,10 +118,10 @@ void RNA_api_environment_map(StructRNA *srna)
RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken");
- parm = RNA_def_float_array(func, "layout", 12, default_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_float_array(func, "layout", 12, default_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);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
new file mode 100644
index 00000000000..15ded001237
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -0,0 +1,764 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_tracking.c
+ * \ingroup RNA
+ */
+
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_depsgraph.h"
+#include "BKE_node.h"
+
+#include "IMB_imbuf.h"
+
+#include "WM_api.h"
+
+static void rna_tracking_tracks_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)
+{
+ int a;
+
+ for(a= 0; a<number; a++)
+ BKE_tracking_add_track(tracking, 0, 0, frame, 1, 1);
+
+ WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
+static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+
+ return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, clip->tracking.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);
+
+ 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;
+ MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data;
+ BLI_strncpy(track->name, value, sizeof(track->name));
+
+ BKE_track_unique_name(&clip->tracking, track);
+}
+
+static void rna_tracking_trackerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data;
+
+ BKE_tracking_clamp_track(track, CLAMP_PAT_DIM);
+}
+
+static void rna_tracking_trackerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data;
+
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+}
+
+static void rna_tracking_trackerAlgorithm_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data;
+
+ if(track->tracker==TRACKER_KLT)
+ BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
+ else
+ BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM);
+}
+
+static void rna_tracking_trackerPyramid_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data;
+
+ BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
+}
+
+static float rna_trackingCamera_focal_mm_get(PointerRNA *ptr)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ MovieTrackingCamera *camera= &clip->tracking.camera;
+ float val= camera->focal;
+
+ if(clip->lastsize[0])
+ val= val*camera->sensor_width/(float)clip->lastsize[0];
+
+ return val;
+}
+
+static void rna_trackingCamera_focal_mm_set(PointerRNA *ptr, float value)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ MovieTrackingCamera *camera= &clip->tracking.camera;
+
+ if(clip->lastsize[0])
+ value= clip->lastsize[0]*value/camera->sensor_width;
+
+ camera->focal= value;
+}
+
+static int rna_track_2d_stabilization(CollectionPropertyIterator *UNUSED(iter), void *data)
+{
+ MovieTrackingTrack *track= (MovieTrackingTrack*)data;
+
+ if((track->flag&TRACK_USE_2D_STAB)==0)
+ return 1;
+
+ return 0;
+}
+
+static void rna_tracking_stabTracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ rna_iterator_listbase_begin(iter, &clip->tracking.tracks, rna_track_2d_stabilization);
+}
+
+static int rna_tracking_stabTracks_active_index_get(PointerRNA *ptr)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ return clip->tracking.stabilization.act_track;
+}
+
+static void rna_tracking_stabTracks_active_index_set(PointerRNA *ptr, int value)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ clip->tracking.stabilization.act_track= value;
+}
+
+static void rna_tracking_stabTracks_active_index_range(PointerRNA *ptr, int *min, int *max)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+
+ *min= 0;
+ *max= clip->tracking.stabilization.tot_track-1;
+ *max= MAX2(0, *max);
+}
+
+static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+ MovieTrackingStabilization *stab= &clip->tracking.stabilization;
+
+ stab->ok= 0;
+
+ nodeUpdateID(scene->nodetree, &clip->id);
+
+ WM_main_add_notifier(NC_SCENE|ND_NODES, NULL);
+ DAG_id_tag_update(&clip->id, 0);
+}
+
+/* API */
+
+static MovieTrackingMarker *rna_trackingTrack_marker_find_frame(MovieTrackingTrack *track, int framenr)
+{
+ return BKE_tracking_get_marker(track, framenr);
+}
+
+#else
+
+static int rna_matrix_dimsize_4x4[]= {4, 4};
+
+static void rna_def_trackingSettings(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem speed_items[] = {
+ {0, "FASTEST", 0, "Fastest", "Track as fast as it's possible"},
+ {TRACKING_SPEED_DOUBLE, "DOUBLE", 0, "Double", "Track with double speed"},
+ {TRACKING_SPEED_REALTIME, "REALTIME", 0, "Realtime", "Track with realtime speed"},
+ {TRACKING_SPEED_HALF, "HALF", 0, "Half", "Track with half of realtime speed"},
+ {TRACKING_SPEED_QUARTER, "QUARTER", 0, "Quarter", "Track with quarter of realtime speed"},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem cleanup_items[] = {
+ {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"},
+ {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"},
+ {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna= RNA_def_struct(brna, "MovieTrackingSettings", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking settings", "Match moving settings");
+
+ /* speed */
+ prop= RNA_def_property(srna, "speed", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, speed_items);
+ RNA_def_property_ui_text(prop, "Speed", "Speed to make tracking with");
+
+ /* limit frames */
+ prop= RNA_def_property(srna, "frames_limit", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "frames_limit");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_text(prop, "Frames Limit", "Amount of frames to be tracked during single tracking operation");
+
+ /* adjust frames */
+ prop= RNA_def_property(srna, "frames_adjust", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "adjframes");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_text(prop, "Adjust Frames", "Automatically re-adjust marker position using position on each N frames. 0 means only keyframed position is used");
+
+ /* margin */
+ prop= RNA_def_property(srna, "margin", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "margin");
+ RNA_def_property_range(prop, 0, 300);
+ RNA_def_property_ui_text(prop, "Margin", "Margin for markers from image boundary");
+
+ /* keyframe_a */
+ prop= RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "keyframe1");
+ RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization");
+
+ /* keyframe_b */
+ prop= RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "keyframe2");
+ RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization");
+
+ /* tool settings */
+
+ /* distance */
+ 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_ui_text(prop, "Distance", "Distance between two bundles used for scene scaling");
+
+ /* frames count */
+ prop= RNA_def_property(srna, "clean_frames", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "clean_frames");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_text(prop, "Tracked Frames", "Effect on tracks which are tracked less than the specified amount of frames");
+
+ /* reprojection error */
+ prop= RNA_def_property(srna, "clean_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_float_sdna(prop, NULL, "clean_error");
+ RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Reprojection Error", "Effect on tracks which have a larger reprojection error");
+
+ /* cleanup action */
+ prop= RNA_def_property(srna, "clean_action", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "clean_action");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, cleanup_items);
+ RNA_def_property_ui_text(prop, "Action", "Cleanup action to execute");
+}
+
+static void rna_def_trackingCamera(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem camera_units_items[] = {
+ {CAMERA_UNITS_PX, "PIXELS", 0, "px", "Use pixels for units of focal length"},
+ {CAMERA_UNITS_MM, "MILLIMETERS", 0, "mm", "Use millimeters for units of focal length"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "MovieTrackingCamera", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking camera data", "Match-moving camera data for tracking");
+
+ /* Sensor */
+ prop= RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "sensor_width");
+ RNA_def_property_range(prop, 0.0f, 500.0f);
+ RNA_def_property_ui_text(prop, "Sensor", "Width of CCD sensor in millimeters");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ /* Focal Length */
+ prop= RNA_def_property(srna, "focal_length", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "focal");
+ RNA_def_property_range(prop, 0.0f, 5000.0f);
+ RNA_def_property_float_funcs(prop, "rna_trackingCamera_focal_mm_get", "rna_trackingCamera_focal_mm_set", NULL);
+ RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ /* Focal Length in pixels */
+ prop= RNA_def_property(srna, "focal_length_pixels", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "focal");
+ RNA_def_property_range(prop, 0.0f, 5000.0f);
+ RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ /* Units */
+ prop= RNA_def_property(srna, "units", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "units");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, camera_units_items);
+ RNA_def_property_ui_text(prop, "Units", "Units used for camera focal length");
+
+ /* Principal Point */
+ prop= RNA_def_property(srna, "principal", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_float_sdna(prop, NULL, "principal");
+ RNA_def_property_ui_text(prop, "Principal Point", "Optical center of lens");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ /* Radial distortion parameters */
+ prop= RNA_def_property(srna, "k1", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "k1");
+ RNA_def_property_ui_range(prop, -10, 10, .1, 3);
+ RNA_def_property_ui_text(prop, "K1", "First coefficient of third order polynomial radial distortion");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
+
+ prop= RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "k2");
+ RNA_def_property_ui_range(prop, -10, 10, .1, 3);
+ RNA_def_property_ui_text(prop, "K2", "Second coefficient of third order polynomial radial distortion");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
+
+ prop= RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "k3");
+ RNA_def_property_ui_range(prop, -10, 10, .1, 3);
+ RNA_def_property_ui_text(prop, "K3", "Third coefficient of third order polynomial radial distortion");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
+
+ /* pixel aspect */
+ prop= RNA_def_property(srna, "pixel_aspect", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "pixel_aspect");
+ RNA_def_property_range(prop, 0.1f, 5000.0f);
+ RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2);
+ RNA_def_property_ui_text(prop, "Pixel Aspect", "Pixel aspect ratio");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+}
+
+static void rna_def_trackingMarker(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "MovieTrackingMarker", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking marker data", "Match-moving marker data for tracking");
+
+ /* position */
+ prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5);
+ RNA_def_property_float_sdna(prop, NULL, "pos");
+ RNA_def_property_ui_text(prop, "Position", "Marker position at frame in normalized coordinates");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
+ /* 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);
+
+ /* enable */
+ prop= RNA_def_property(srna, "enable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MARKER_DISABLED);
+ RNA_def_property_ui_text(prop, "Enable", "Is marker enabled for current frame");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
+static void rna_def_trackingTrack(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ static EnumPropertyItem tracker_items[] = {
+ {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker"},
+ {TRACKER_KLT, "KLT", 0, "KLT", "Kanade–Lucas–Tomasi racker"},
+ {0, NULL, 0, NULL, NULL}};
+
+ rna_def_trackingMarker(brna);
+
+ srna= RNA_def_struct(brna, "MovieTrackingTrack", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking track data", "Match-moving track data for tracking");
+ RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA);
+
+ /* name */
+ 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_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+ RNA_def_struct_name_property(srna, prop);
+
+ /* Pattern */
+ prop= RNA_def_property(srna, "pattern_min", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5);
+ RNA_def_property_float_sdna(prop, NULL, "pat_min");
+ RNA_def_property_ui_text(prop, "Pattern Min", "Left-bottom corner of pattern area in normalized coordinates relative to marker position");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update");
+
+ prop= RNA_def_property(srna, "pattern_max", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5);
+ RNA_def_property_float_sdna(prop, NULL, "pat_max");
+ RNA_def_property_ui_text(prop, "Pattern Max", "Right-bottom corner of pattern area in normalized coordinates relative to marker position");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update");
+
+ /* Search */
+ prop= RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5);
+ RNA_def_property_float_sdna(prop, NULL, "search_min");
+ RNA_def_property_ui_text(prop, "Search Min", "Left-bottom corner of search area in normalized coordinates relative to marker position");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update");
+
+ prop= RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5);
+ RNA_def_property_float_sdna(prop, NULL, "search_max");
+ RNA_def_property_ui_text(prop, "Search Max", "Right-bottom corner of search area in normalized coordinates relative to marker position");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update");
+
+ /* tracking algorithm */
+ prop= RNA_def_property(srna, "tracker", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_enum_items(prop, tracker_items);
+ RNA_def_property_ui_text(prop, "Tracker", "Tracking algorithm to use");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerAlgorithm_update");
+
+ /* pyramid level for pyramid klt tracking */
+ prop= RNA_def_property(srna, "pyramid_levels", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_int_sdna(prop, NULL, "pyramid_levels");
+ RNA_def_property_range(prop, 1, 16);
+ RNA_def_property_ui_text(prop, "Pyramid levels", "Number of pyramid levels for KLT tracking");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPyramid_update");
+
+ /* minmal correlation - only used for SAD tracker */
+ prop= RNA_def_property(srna, "correlation_min", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_float_sdna(prop, NULL, "minimum_correlation");
+ RNA_def_property_range(prop, -1.0f, 1.0f);
+ RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3);
+ RNA_def_property_ui_text(prop, "Correlation", "Minimal value of correlation between mathed pattern and reference which is still treated as successful tracking");
+
+ /* markers */
+ prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE);
+ 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");
+
+ /* ** channels ** */
+
+ /* use_red_channel */
+ prop= RNA_def_property(srna, "use_red_channel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "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_green_channel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "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_blue_channel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "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);
+
+ /* has bundle */
+ prop= RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Has Bundle", "True if track has a valid bundle");
+
+ /* bundle position */
+ prop= RNA_def_property(srna, "bundle", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_sdna(prop, NULL, "bundle_pos");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Bundle", "Position of bundle reconstructed from this track");
+
+ /* hide */
+ prop= RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HIDDEN);
+ RNA_def_property_ui_text(prop, "Hide", "Track is hidden");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* locked */
+ prop= RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_LOCKED);
+ RNA_def_property_ui_text(prop, "Lock", "Track is locked and all changes to it are disabled");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* custom color */
+ prop= RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_CUSTOMCOLOR);
+ RNA_def_property_ui_text(prop, "Custom Color", "Use custom color instead of theme-defined");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* color */
+ prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Color", "Color of the track in the Clip Editor");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+ /* average error */
+ prop= RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE);
+ 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)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "MovieTrackingStabilization", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking stabilization data", "Match-moving stabilization data for tracking");
+
+ /* 2d stabilization */
+ prop= RNA_def_property(srna, "use_2d_stabilization", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_2D_STABILIZATION);
+ RNA_def_property_ui_text(prop, "Use 2D stabilization", "Use 2D stabilization for footage");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+ /* tracks */
+ prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_funcs(prop, "rna_tracking_stabTracks_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 used for stabilization");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+ /* rotation track */
+ prop= RNA_def_property(srna, "rotation_track", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "rot_track");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Rotation Track", "Track used to compensate rotation");
+ RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate");
+
+ /* active track index */
+ prop= RNA_def_property(srna, "active_track_index", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "act_track");
+ RNA_def_property_int_funcs(prop, "rna_tracking_stabTracks_active_index_get", "rna_tracking_stabTracks_active_index_set", "rna_tracking_stabTracks_active_index_range");
+ RNA_def_property_ui_text(prop, "Active Track Index", "Index of active track in stabilization tracks list");
+
+ /* autoscale */
+ prop= RNA_def_property(srna, "use_autoscale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_AUTOSCALE);
+ RNA_def_property_ui_text(prop, "Autoscale", "Automatically scale footage to cover unfilled areas when stabilizating");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+ /* max scale */
+ prop= RNA_def_property(srna, "scale_max", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "maxscale");
+ RNA_def_property_range(prop, 0.0f, 10.0f);
+ RNA_def_property_ui_text(prop, "Miximal Scale", "Maximal value for scale factor");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+ /* influence_location */
+ prop= RNA_def_property(srna, "influence_location", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "locinf");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Location Influence", "Influence of stabilization algorithm on footage location");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+ /* influence_scale */
+ prop= RNA_def_property(srna, "influence_scale", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "scaleinf");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Scale Influence", "Influence of stabilization algorithm on footage scale");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+
+ /* influence_rotation */
+ prop= RNA_def_property(srna, "influence_rotation", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "rotinf");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Rotation Influence", "Influence of stabilization algorithm on footage rotation");
+ RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate");
+}
+
+static void rna_def_reconstructedCamera(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "MovieReconstructedCamera", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking reconstructed camera data", "Match-moving reconstructed camera data from tracker");
+
+ /* frame */
+ prop= RNA_def_property(srna, "frame", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_int_sdna(prop, NULL, "framenr");
+ RNA_def_property_ui_text(prop, "Frame", "Frame number marker is keyframed on");
+
+ /* matrix */
+ prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "mat");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(prop, "Matrix", "Worldspace transformation matrix");
+
+ /* average_error */
+ prop= RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE);
+ 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 resonctruction");
+}
+
+static void rna_def_trackingReconstruction(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ rna_def_reconstructedCamera(brna);
+
+ srna= RNA_def_struct(brna, "MovieTrackingReconstruction", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking reconstruction data", "Match-moving reconstruction data from tracker");
+
+ /* is_valid */
+ prop= RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_RECONSTRUCTED);
+ RNA_def_property_ui_text(prop, "Reconstructed", "Is tracking data contains valid reconstruction information");
+
+ /* average_error */
+ prop= RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE);
+ 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 resonctruction");
+
+ /* cameras */
+ prop= RNA_def_property(srna, "cameras", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieReconstructedCamera");
+ RNA_def_property_collection_sdna(prop, NULL, "cameras", "camnr");
+ RNA_def_property_ui_text(prop, "Cameras", "Collection of solved cameras");
+}
+
+static void rna_def_trackingTracks(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ 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");
+ 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_tracking(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ rna_def_trackingSettings(brna);
+ rna_def_trackingCamera(brna);
+ rna_def_trackingTrack(brna);
+ rna_def_trackingStabilization(brna);
+ rna_def_trackingReconstruction(brna);
+
+ srna= RNA_def_struct(brna, "MovieTracking", NULL);
+ RNA_def_struct_ui_text(srna, "Movie tracking data", "Match-moving data for tracking");
+
+ /* settings */
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieTrackingSettings");
+
+ /* camera properties */
+ prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieTrackingCamera");
+
+ /* 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_struct_type(prop, "MovieTrackingTrack");
+ RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object");
+ rna_def_trackingTracks(brna, prop);
+
+ /* stabilization */
+ prop= RNA_def_property(srna, "stabilization", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieTrackingStabilization");
+
+ /* reconstruction */
+ prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "MovieTrackingReconstruction");
+}
+
+void RNA_def_tracking(BlenderRNA *brna)
+{
+ rna_def_tracking(brna);
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 7e111fba621..078126a9c9a 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -397,6 +397,25 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
RNA_def_boolean(func, "compact", 0, "", "Use more compact layout");
+ func= RNA_def_function(srna, "template_movieclip", "uiTemplateMovieClip");
+ RNA_def_function_ui_description(func, "Item(s). User interface for selecting movie clips and their source paths");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ api_ui_item_rna_common(func);
+ RNA_def_boolean(func, "compact", 0, "", "Use more compact layout");
+
+ func= RNA_def_function(srna, "template_track", "uiTemplateTrack");
+ RNA_def_function_ui_description(func, "Item. A movie-track widget to preview tracking image.");
+ api_ui_item_rna_common(func);
+
+ func= RNA_def_function(srna, "template_marker", "uiTemplateMarker");
+ RNA_def_function_ui_description(func, "Item. A widget to control single marker settings.");
+ api_ui_item_rna_common(func);
+ parm= RNA_def_pointer(func, "clip_user", "MovieClipUser", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
+ parm= RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
+ RNA_def_boolean(func, "compact", 0, "", "Use more compact layout");
+
func= RNA_def_function(srna, "template_list", "uiTemplateList");
RNA_def_function_ui_description(func, "Item. A list widget to display data. e.g. vertexgroups");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -408,9 +427,9 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_string(func, "prop_list", "", 0, "",
- "Identifier of a string property in each data member, specifying which "
- "of its properties should have a widget displayed in its row");
+ RNA_def_string(func, "prop_list", "", 0, "",
+ "Identifier of a string property in each data member, specifying which "
+ "of its properties should have a widget displayed in its row");
RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display", 0, INT_MAX);
RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Maximum number of rows to display", 0, INT_MAX);
RNA_def_enum(func, "type", list_type_items, 0, "Type", "Type of list to use");
@@ -429,6 +448,23 @@ void RNA_api_ui_layout(StructRNA *srna)
func= RNA_def_function(srna, "template_reports_banner", "uiTemplateReportsBanner");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ func= RNA_def_function(srna, "template_node_link", "uiTemplateNodeLink");
+ parm= RNA_def_pointer(func, "ntree", "NodeTree", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "node", "Node", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "template_node_view", "uiTemplateNodeView");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ parm= RNA_def_pointer(func, "ntree", "NodeTree", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "node", "Node", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
func= RNA_def_function(srna, "template_keymap_item_properties", "uiTemplateKeymapItemProperties");
parm= RNA_def_pointer(func, "item", "KeyMapItem", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index fc9c8a241c6..e4e1c78ab3e 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1030,8 +1030,21 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_property_range(prop, 1, 5);
RNA_def_property_ui_text(prop, "Outline Width", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "bundle_solid", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "bundle_solid");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Bundle Solid", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "camera_path", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "camera_path");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Camera Path", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
+
static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1741,6 +1754,94 @@ static void rna_def_userdef_theme_colorset(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
+static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ /* space_clip */
+
+ srna= RNA_def_struct(brna, "ThemeClipEditor", NULL);
+ RNA_def_struct_sdna(srna, "ThemeSpace");
+ 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);
+
+ prop= RNA_def_property(srna, "marker_outline", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "marker_outline");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Marker Outline Color", "Color of marker's outile");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "marker", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "marker");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Marker Color", "Color of marker");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "active_marker", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "act_marker");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Active Marker", "Color of active marker");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "selected_marker", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "sel_marker");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Selected Marker", "Color of sleected marker");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "disabled_marker", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "dis_marker");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Disabled Marker", "Color of disabled marker");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "locked_marker", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "lock_marker");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Locked Marker", "Color of locked marker");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "path_before", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "path_before");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Path Before", "Color of path before current frame");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "path_after", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "path_after");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Path After", "Color of path after current frame");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Grid", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "cframe");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Current Frame", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "handle_vertex", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Handle Vertex", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "handle_vertex_select", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Handle Vertex Select", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "handle_vertex_size", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 0, 255);
+ RNA_def_property_ui_text(prop, "Handle Vertex Size", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+}
+
static void rna_def_userdef_themes(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1765,6 +1866,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
{15, "INFO", ICON_INFO, "Info", ""},
{16, "FILE_BROWSER", ICON_FILESEL, "File Browser", ""},
{17, "CONSOLE", ICON_CONSOLE, "Python Console", ""},
+ {20, "CLIP_EDITOR", ICON_CLIP, "Movie Clip Editor", ""},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "Theme", NULL);
@@ -1887,6 +1989,12 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "tarm", "");
RNA_def_property_struct_type(prop, "ThemeBoneColorSet");
RNA_def_property_ui_text(prop, "Bone Color Sets", "");
+
+ prop= RNA_def_property(srna, "clip_editor", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "tclip");
+ RNA_def_property_struct_type(prop, "ThemeClipEditor");
+ RNA_def_property_ui_text(prop, "Clip Editor", "");
}
static void rna_def_userdef_addon(BlenderRNA *brna)
@@ -1926,6 +2034,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_space_userpref(brna);
rna_def_userdef_theme_space_console(brna);
rna_def_userdef_theme_space_logic(brna);
+ rna_def_userdef_theme_space_clip(brna);
rna_def_userdef_theme_colorset(brna);
rna_def_userdef_themes(brna);
}
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 82848c6a5d7..69e7f9cac6b 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -80,6 +80,8 @@ set(SRC
composite/nodes/node_composite_mapValue.c
composite/nodes/node_composite_math.c
composite/nodes/node_composite_mixrgb.c
+ composite/nodes/node_composite_movieclip.c
+ composite/nodes/node_composite_moviedistortion.c
composite/nodes/node_composite_normal.c
composite/nodes/node_composite_normalize.c
composite/nodes/node_composite_outputFile.c
@@ -93,8 +95,10 @@ set(SRC
composite/nodes/node_composite_sepcombYUVA.c
composite/nodes/node_composite_setalpha.c
composite/nodes/node_composite_splitViewer.c
+ composite/nodes/node_composite_stabilize2d.c
composite/nodes/node_composite_texture.c
composite/nodes/node_composite_tonemap.c
+ composite/nodes/node_composite_transform.c
composite/nodes/node_composite_translate.c
composite/nodes/node_composite_valToRgb.c
composite/nodes/node_composite_value.c
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index d768a5d794f..f1415a8c8f0 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -52,6 +52,7 @@ void register_node_type_cmp_texture(ListBase *lb);
void register_node_type_cmp_value(ListBase *lb);
void register_node_type_cmp_rgb(ListBase *lb);
void register_node_type_cmp_curve_time(ListBase *lb);
+void register_node_type_cmp_movieclip(ListBase *lb);
void register_node_type_cmp_composite(ListBase *lb);
void register_node_type_cmp_viewer(ListBase *lb);
@@ -113,6 +114,9 @@ void register_node_type_cmp_flip(ListBase *lb);
void register_node_type_cmp_crop(ListBase *lb);
void register_node_type_cmp_displace(ListBase *lb);
void register_node_type_cmp_mapuv(ListBase *lb);
+void register_node_type_cmp_transform(ListBase *lb);
+void register_node_type_cmp_stabilize2d(ListBase *lb);
+void register_node_type_cmp_moviedistortion(ListBase *lb);
void register_node_type_cmp_glare(ListBase *lb);
void register_node_type_cmp_tonemap(ListBase *lb);
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 2151176f907..06f88002a70 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -45,6 +45,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_tracking.h"
#include "BKE_utildefines.h"
#include "node_exec.h"
@@ -67,6 +68,20 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
}
}
+static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
+{
+ func(calldata, NODE_CLASS_INPUT, "Input");
+ func(calldata, NODE_CLASS_OUTPUT, "Output");
+ func(calldata, NODE_CLASS_OP_COLOR, "Color");
+ func(calldata, NODE_CLASS_OP_VECTOR, "Vector");
+ func(calldata, NODE_CLASS_OP_FILTER, "Filter");
+ func(calldata, NODE_CLASS_CONVERTOR, "Convertor");
+ func(calldata, NODE_CLASS_MATTE, "Matte");
+ func(calldata, NODE_CLASS_DISTORT, "Distort");
+ func(calldata, NODE_CLASS_GROUP, "Group");
+ func(calldata, NODE_CLASS_LAYOUT, "Layout");
+}
+
static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock;
@@ -168,6 +183,17 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id);
}
}
+ else if(lnode->type==CMP_NODE_MOVIEDISTORTION) {
+ /* special case for distortion node: distortion context is allocating in exec function
+ and to achive much better performance on further calls this context should be
+ copied back to original node */
+ if(lnode->storage) {
+ if(lnode->new_node->storage)
+ BKE_tracking_distortion_destroy(lnode->new_node->storage);
+
+ lnode->new_node->storage= BKE_tracking_distortion_copy(lnode->storage);
+ }
+ }
for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) {
if(ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
@@ -195,6 +221,7 @@ bNodeTreeType ntreeType_Composite = {
/* free_cache */ free_cache,
/* free_node_cache */ free_node_cache,
/* foreach_nodetree */ foreach_nodetree,
+ /* foreach_nodeclass */ foreach_nodeclass,
/* localize */ localize,
/* local_sync */ local_sync,
/* local_merge */ local_merge,
@@ -806,6 +833,10 @@ int ntreeCompositTagAnimated(bNodeTree *ntree)
nodeUpdate(ntree, node);
}
}
+ else if(ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) {
+ nodeUpdate(ntree, node);
+ tagged= 1;
+ }
}
return tagged;
diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h
index 6da9b901e76..9cac4c477eb 100644
--- a/source/blender/nodes/composite/node_composite_util.h
+++ b/source/blender/nodes/composite/node_composite_util.h
@@ -44,6 +44,7 @@
#include "DNA_ID.h"
#include "DNA_image_types.h"
#include "DNA_material_types.h"
+#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -63,8 +64,10 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_movieclip.h"
#include "BKE_node.h"
#include "BKE_texture.h"
+#include "BKE_tracking.h"
#include "BKE_library.h"
#include "BKE_object.h"
@@ -210,4 +213,11 @@ CompBuf* qd_downScaledCopy(CompBuf* src, int scale);
void IIR_gauss(CompBuf* src, float sigma, int chan, int xy);
/* end utility funcs */
+/* transformations */
+
+#define CMP_SCALE_MAX 12000
+
+CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type);
+float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc);
+
#endif
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index c1e9d28bb4d..41427c42286 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -58,6 +58,36 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= {
{ -1, 0, "" }
};
+/* float buffer from the image with matching color management */
+float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
+{
+ float *rect;
+
+ *alloc= FALSE;
+
+ if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if(ibuf->profile != IB_PROFILE_NONE) {
+ rect= ibuf->rect_float;
+ }
+ 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);
+ *alloc= TRUE;
+ }
+ }
+ else {
+ if(ibuf->profile == IB_PROFILE_NONE) {
+ rect= ibuf->rect_float;
+ }
+ 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);
+ *alloc= TRUE;
+ }
+ }
+
+ return rect;
+}
/* note: this function is used for multilayer too, to ensure uniform
handling with BKE_image_get_ibuf() */
@@ -82,26 +112,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
/* now we need a float buffer from the image with matching color management */
/* XXX weak code, multilayer is excluded from this */
if(ibuf->channels == 4 && ima->rr==NULL) {
- if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
- if(ibuf->profile != IB_PROFILE_NONE) {
- rect= ibuf->rect_float;
- }
- 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);
- alloc= TRUE;
- }
- }
- else {
- if(ibuf->profile == IB_PROFILE_NONE) {
- rect= ibuf->rect_float;
- }
- 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);
- alloc= TRUE;
- }
- }
+ rect= node_composit_get_float_buffer(rd, ibuf, &alloc);
}
else {
/* non-rgba passes can't use color profiles */
diff --git a/source/blender/nodes/composite/nodes/node_composite_mapValue.c b/source/blender/nodes/composite/nodes/node_composite_mapValue.c
index 81e963d4790..6930fbf0664 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mapValue.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mapValue.c
@@ -79,7 +79,7 @@ static void node_composit_exec_map_value(void *UNUSED(data), bNode *node, bNodeS
static void node_composit_init_map_value(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp))
{
- node->storage= add_mapping();
+ node->storage= add_tex_mapping();
}
void register_node_type_cmp_map_value(ListBase *lb)
diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c
new file mode 100644
index 00000000000..8931b899017
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c
@@ -0,0 +1,157 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_movieclip.c
+ * \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+static bNodeSocketTemplate cmp_node_movieclip_out[]= {
+ { SOCK_RGBA, 0, "Image"},
+ { SOCK_FLOAT, 1, "Offset X"},
+ { SOCK_FLOAT, 1, "Offset Y"},
+ { SOCK_FLOAT, 1, "Scale"},
+ { SOCK_FLOAT, 1, "Angle"},
+ { -1, 0, "" }
+};
+
+static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user)
+{
+ ImBuf *ibuf;
+ CompBuf *stackbuf;
+ int type;
+
+ float *rect;
+ int alloc= FALSE;
+
+ ibuf= BKE_movieclip_get_ibuf(clip, user);
+
+ if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
+ IMB_freeImBuf(ibuf);
+ return NULL;
+ }
+
+ if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) {
+ IMB_float_from_rect(ibuf);
+ ibuf->userflags&= ~IB_RECT_INVALID;
+ }
+
+ /* now we need a float buffer from the image with matching color management */
+ if(ibuf->channels == 4) {
+ rect= node_composit_get_float_buffer(rd, ibuf, &alloc);
+ }
+ else {
+ /* non-rgba passes can't use color profiles */
+ rect= ibuf->rect_float;
+ }
+ /* done coercing into the correct color management */
+
+ if(!alloc) {
+ rect= MEM_dupallocN(rect);
+ alloc= 1;
+ }
+
+ type= ibuf->channels;
+
+ if(rd->scemode & R_COMP_CROP) {
+ stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
+ if(alloc)
+ MEM_freeN(rect);
+ }
+ else {
+ /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
+ stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
+ stackbuf->rect= rect;
+ stackbuf->malloc= alloc;
+ }
+
+ IMB_freeImBuf(ibuf);
+
+ return stackbuf;
+}
+
+static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
+{
+ if(node->id) {
+ RenderData *rd= data;
+ MovieClip *clip= (MovieClip *)node->id;
+ MovieClipUser *user= (MovieClipUser *)node->storage;
+ CompBuf *stackbuf= NULL;
+
+ BKE_movieclip_user_set_frame(user, rd->cfra);
+
+ stackbuf= node_composit_get_movieclip(rd, clip, user);
+
+ if (stackbuf) {
+ MovieTrackingStabilization *stab= &clip->tracking.stabilization;
+
+ /* put image on stack */
+ out[0]->data= stackbuf;
+
+ if(stab->flag&TRACKING_2D_STABILIZATION) {
+ float loc[2], scale, angle;
+
+ BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y,
+ loc, &scale, &angle);
+
+ out[1]->vec[0]= loc[0];
+ out[2]->vec[0]= loc[1];
+
+ out[3]->vec[0]= scale;
+ out[4]->vec[0]= angle;
+ }
+
+ /* generate preview */
+ generate_preview(data, node, stackbuf);
+ }
+ }
+}
+
+static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
+{
+ MovieClipUser *user= MEM_callocN(sizeof(MovieClipUser), "node movie clip user");
+
+ node->storage= user;
+ user->framenr= 1;
+}
+
+void register_node_type_cmp_movieclip(ListBase *lb)
+{
+ static bNodeType ntype;
+
+ node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
+ node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out);
+ node_type_size(&ntype, 120, 80, 300);
+ node_type_init(&ntype, init);
+ node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage);
+ node_type_exec(&ntype, node_composit_exec_movieclip);
+
+ nodeRegisterType(lb, &ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
new file mode 100644
index 00000000000..439616377a1
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
@@ -0,0 +1,135 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_moviedistortion.c
+ * \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+/* **************** Translate ******************** */
+
+static bNodeSocketTemplate cmp_node_moviedistortion_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate cmp_node_moviedistortion_out[]= {
+ { SOCK_RGBA, 0, "Image"},
+ { -1, 0, "" }
+};
+
+static void exec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ if(in[0]->data) {
+ if(node->id) {
+ MovieClip *clip= (MovieClip *)node->id;
+ CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+ CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
+ ImBuf *ibuf;
+
+ ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
+
+ if(ibuf) {
+ ImBuf *obuf;
+ MovieTracking *tracking= &clip->tracking;
+ int width, height;
+ float overscan= 0.0f;
+
+ ibuf->rect_float= cbuf->rect;
+
+ BKE_movieclip_get_size(clip, NULL, &width, &height);
+
+ if(!node->storage)
+ node->storage= BKE_tracking_distortion_create();
+
+ if(node->custom1==0)
+ obuf= BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1);
+ else
+ obuf= BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 0);
+
+ stackbuf->rect= obuf->rect_float;
+ stackbuf->malloc= 1;
+
+ obuf->mall&= ~IB_rectfloat;
+ obuf->rect_float= NULL;
+
+ IMB_freeImBuf(ibuf);
+ IMB_freeImBuf(obuf);
+ }
+
+ /* pass on output and free */
+ out[0]->data= stackbuf;
+
+ if(cbuf!=in[0]->data)
+ free_compbuf(cbuf);
+ } else {
+ CompBuf *cbuf= in[0]->data;
+ CompBuf *stackbuf= pass_on_compbuf(cbuf);
+
+ out[0]->data= stackbuf;
+ }
+ }
+}
+
+static const char *label(bNode *node)
+{
+ if(node->custom1==0)
+ return "Undistortion";
+ else
+ return "Distortion";
+}
+
+static void storage_free(bNode *node)
+{
+ if(node->storage)
+ BKE_tracking_distortion_destroy(node->storage);
+
+ node->storage= NULL;
+}
+
+void storage_copy(bNode *orig_node, bNode *new_node)
+{
+ if(orig_node->storage)
+ new_node->storage= BKE_tracking_distortion_copy(orig_node->storage);
+}
+
+void register_node_type_cmp_moviedistortion(ListBase *lb)
+{
+ static bNodeType ntype;
+
+ node_type_base(&ntype, CMP_NODE_MOVIEDISTORTION, "Movie Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS);
+ node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out);
+ node_type_size(&ntype, 140, 100, 320);
+ node_type_label(&ntype, label);
+ node_type_exec(&ntype, exec);
+ node_type_storage(&ntype, NULL, storage_free, storage_copy);
+
+ nodeRegisterType(lb, &ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c
index a6220fbd20d..d14f589f3f2 100644
--- a/source/blender/nodes/composite/nodes/node_composite_normalize.c
+++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c
@@ -109,7 +109,6 @@ void register_node_type_cmp_normalize(ListBase *lb)
node_type_socket_templates(&ntype, cmp_node_normalize_in, cmp_node_normalize_out);
node_type_size(&ntype, 100, 60, 150);
node_type_exec(&ntype, node_composit_exec_normalize);
- node_type_storage(&ntype, "TexMapping", NULL, NULL);
nodeRegisterType(lb, &ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c
index 5eb789ae0c9..37332c9bd7e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_scale.c
+++ b/source/blender/nodes/composite/nodes/node_composite_scale.c
@@ -34,8 +34,6 @@
/* **************** Scale ******************** */
-#define CMP_SCALE_MAX 12000
-
static bNodeSocketTemplate cmp_node_scale_in[]= {
{ SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f},
{ SOCK_FLOAT, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR},
@@ -110,6 +108,25 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b
if(cbuf!=in[0]->data)
free_compbuf(cbuf);
}
+ else if (node->custom1==CMP_SCALE_ABSOLUTE) {
+ CompBuf *stackbuf;
+ int a, x, y;
+ float *fp;
+
+ x = MAX2((int)in[1]->vec[0], 1);
+ y = MAX2((int)in[2]->vec[0], 1);
+
+ stackbuf = alloc_compbuf(x, y, CB_RGBA, 1);
+ fp = stackbuf->rect;
+
+ a = stackbuf->x * stackbuf->y;
+ while(a--) {
+ copy_v4_v4(fp, in[0]->vec);
+ fp += 4;
+ }
+
+ out[0]->data= stackbuf;
+ }
}
void register_node_type_cmp_scale(ListBase *lb)
diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
new file mode 100644
index 00000000000..c5d60e65530
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
@@ -0,0 +1,79 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_stabilize2d.c
+ * \ingroup cmpnodes
+ */
+
+
+#include "node_composite_util.h"
+
+/* **************** Translate ******************** */
+
+static bNodeSocketTemplate cmp_node_stabilize2d_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate cmp_node_stabilize2d_out[]= {
+ { SOCK_RGBA, 0, "Image"},
+ { -1, 0, "" }
+};
+
+static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ if(in[0]->data && node->id) {
+ RenderData *rd= data;
+ MovieClip *clip= (MovieClip *)node->id;
+ CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+ CompBuf *stackbuf;
+ float loc[2], scale, angle;
+
+ BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle);
+
+ stackbuf= node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1);
+
+ /* pass on output and free */
+ out[0]->data= stackbuf;
+
+ if(cbuf!=in[0]->data)
+ free_compbuf(cbuf);
+ }
+}
+
+void register_node_type_cmp_stabilize2d(ListBase *lb)
+{
+ static bNodeType ntype;
+
+ node_type_base(&ntype, CMP_NODE_STABILIZE2D, "Stabilize 2D", NODE_CLASS_DISTORT, NODE_OPTIONS);
+ node_type_socket_templates(&ntype, cmp_node_stabilize2d_in, cmp_node_stabilize2d_out);
+ node_type_size(&ntype, 140, 100, 320);
+ node_type_exec(&ntype, node_composit_exec_stabilize2d);
+
+ nodeRegisterType(lb, &ntype);
+}
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c
new file mode 100644
index 00000000000..de9b8fceaee
--- /dev/null
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.c
@@ -0,0 +1,142 @@
+/*
+ * ***** 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): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/composite/nodes/node_composite_transform.c
+ * \ingroup cmpnodes
+ */
+
+#include "node_composite_util.h"
+
+/* **************** Transform ******************** */
+
+static bNodeSocketTemplate cmp_node_transform_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+ { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+ { SOCK_FLOAT, 1, "Angle", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_ANGLE},
+ { SOCK_FLOAT, 1, "Scale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate cmp_node_transform_out[]= {
+ { SOCK_RGBA, 0, "Image"},
+ { -1, 0, "" }
+};
+
+CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type)
+{
+ CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1);
+ ImBuf *ibuf, *obuf;
+ float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4];
+ float svec[3]= {scale, scale, scale}, loc[2]= {x, y};
+
+ unit_m4(rmat);
+ unit_m4(lmat);
+ unit_m4(smat);
+ unit_m4(cmat);
+
+ /* image center as rotation center */
+ cmat[3][0]= (float)cbuf->x/2.0f;
+ cmat[3][1]= (float)cbuf->y/2.0f;
+ invert_m4_m4(icmat, cmat);
+
+ size_to_mat4(smat, svec); /* scale matrix */
+ add_v2_v2(lmat[3], loc); /* tranlation matrix */
+ rotate_m4(rmat, 'Z', angle); /* rotation matrix */
+
+ /* compose transformation matrix */
+ mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL);
+
+ invert_m4(mat);
+
+ ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
+ obuf= IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);
+
+ if(ibuf && obuf) {
+ int i, j;
+
+ ibuf->rect_float= cbuf->rect;
+ obuf->rect_float= stackbuf->rect;
+
+ for(j=0; j<cbuf->y; j++) {
+ for(i=0; i<cbuf->x;i++) {
+ float vec[3]= {i, j, 0};
+
+ mul_v3_m4v3(vec, mat, vec);
+
+ switch(filter_type) {
+ case 0:
+ neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
+ break ;
+ case 1:
+ bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
+ break;
+ case 2:
+ bicubic_interpolation(ibuf, obuf, vec[0], vec[1], i, j);
+ break;
+ }
+ }
+ }
+
+ IMB_freeImBuf(ibuf);
+ IMB_freeImBuf(obuf);
+ }
+
+ /* pass on output and free */
+ return stackbuf;
+}
+
+static void node_composit_exec_transform(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ if(in[0]->data) {
+ CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+ CompBuf *stackbuf;
+
+ stackbuf= node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], in[3]->vec[0], in[4]->vec[0], node->custom1);
+
+ /* pass on output and free */
+ out[0]->data= stackbuf;
+
+ if(cbuf!=in[0]->data)
+ free_compbuf(cbuf);
+ }
+}
+
+void register_node_type_cmp_transform(ListBase *lb)
+{
+ static bNodeType ntype;
+
+ node_type_base(&ntype, CMP_NODE_TRANSFORM, "Transform", NODE_CLASS_DISTORT, NODE_OPTIONS);
+ node_type_socket_templates(&ntype, cmp_node_transform_in, cmp_node_transform_out);
+ node_type_size(&ntype, 140, 100, 320);
+ node_type_exec(&ntype, node_composit_exec_transform);
+
+ nodeRegisterType(lb, &ntype);
+}
+
+
diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c
index 4a851a3acac..9381eff30dd 100644
--- a/source/blender/nodes/intern/node_socket.c
+++ b/source/blender/nodes/intern/node_socket.c
@@ -305,6 +305,7 @@ struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct
default:
sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type);
}
+ sock->flag |= stemp->flag;
return sock;
}
@@ -351,6 +352,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in
sock->type= stemp->type; /* in future, read this from tydefs! */
if(stemp->limit==0) sock->limit= 0xFFF;
else sock->limit= stemp->limit;
+ sock->flag |= stemp->flag;
/* Copy the property range and subtype parameters in case the template changed.
* NOT copying the actual value here, only button behavior changes!
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index d0ae17914ca..aa8ba12f799 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -35,6 +35,7 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "BLI_listbase.h"
@@ -45,6 +46,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_scene.h"
#include "BKE_utildefines.h"
#include "GPU_material.h"
@@ -74,6 +76,23 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
func(calldata, &wo->id, wo->nodetree);
}
+static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func)
+{
+ func(calldata, NODE_CLASS_INPUT, "Input");
+ func(calldata, NODE_CLASS_OUTPUT, "Output");
+
+ if(scene_use_new_shading_nodes(scene)) {
+ func(calldata, NODE_CLASS_SHADER, "Shader");
+ func(calldata, NODE_CLASS_TEXTURE, "Texture");
+ }
+
+ func(calldata, NODE_CLASS_OP_COLOR, "Color");
+ func(calldata, NODE_CLASS_OP_VECTOR, "Vector");
+ func(calldata, NODE_CLASS_CONVERTOR, "Convertor");
+ func(calldata, NODE_CLASS_GROUP, "Group");
+ func(calldata, NODE_CLASS_LAYOUT, "Layout");
+}
+
static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
{
bNode *lnode;
@@ -108,6 +127,7 @@ bNodeTreeType ntreeType_Shader = {
/* free_cache */ NULL,
/* free_node_cache */ NULL,
/* foreach_nodetree */ foreach_nodetree,
+ /* foreach_nodeclass */ foreach_nodeclass,
/* localize */ NULL,
/* local_sync */ local_sync,
/* local_merge */ NULL,
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index 862c52187dc..35007724037 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -69,7 +69,7 @@ static void node_shader_exec_mapping(void *UNUSED(data), bNode *node, bNodeStack
static void node_shader_init_mapping(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp))
{
- node->storage= add_mapping();
+ node->storage= add_tex_mapping();
}
static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out)
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index 42460e141e2..dbf9fdbdb7e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -36,7 +36,7 @@
/* **************** TEXTURE ******************** */
static bNodeSocketTemplate sh_node_texture_in[]= {
- { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, /* no limit */
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, /* no limit */
{ -1, 0, "" }
};
static bNodeSocketTemplate sh_node_texture_out[]= {
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 5e5d44540dc..84bb53e2215 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -62,6 +62,19 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
}
}
+static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
+{
+ func(calldata, NODE_CLASS_INPUT, "Input");
+ func(calldata, NODE_CLASS_OUTPUT, "Output");
+ func(calldata, NODE_CLASS_OP_COLOR, "Color");
+ func(calldata, NODE_CLASS_PATTERN, "Patterns");
+ func(calldata, NODE_CLASS_TEXTURE, "Textures");
+ func(calldata, NODE_CLASS_CONVERTOR, "Convertor");
+ func(calldata, NODE_CLASS_DISTORT, "Distort");
+ func(calldata, NODE_CLASS_GROUP, "Group");
+ func(calldata, NODE_CLASS_LAYOUT, "Layout");
+}
+
static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
{
bNode *lnode;
@@ -91,6 +104,7 @@ bNodeTreeType ntreeType_Texture = {
/* free_cache */ NULL,
/* free_node_cache */ NULL,
/* foreach_nodetree */ foreach_nodetree,
+ /* foreach_nodeclass */ foreach_nodeclass,
/* localize */ NULL,
/* local_sync */ local_sync,
/* local_merge */ NULL,
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index dbcc478990a..758cf7bd61c 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -166,6 +166,7 @@ typedef struct wmNotifier {
#define NC_NODE (17<<24)
#define NC_ID (18<<24)
#define NC_LOGIC (19<<24)
+#define NC_MOVIECLIP (20<<24)
/* data type, 256 entries is enough, it can overlap */
#define NOTE_DATA 0x00FF0000
@@ -275,6 +276,7 @@ typedef struct wmNotifier {
#define ND_SPACE_SEQUENCER (16<<16)
#define ND_SPACE_NODE_VIEW (17<<16)
#define ND_SPACE_CHANGED (18<<16) /*sent to a new editor type after it's replaced an old one*/
+#define ND_SPACE_CLIP (19<<16)
/* subtype, 256 entries too */
#define NOTE_SUBTYPE 0x0000FF00
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 83e4681251f..8d7e812a386 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -733,7 +733,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re
/* send the OnSave event */
for (li= G.main->library.first; li; li= li->id.next) {
if (BLI_path_cmp(li->filepath, filepath) == 0) {
- BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.200s'", filepath);
+ BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.240s'", filepath);
return -1;
}
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 19e9a6bd483..f12dec6459a 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3625,6 +3625,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle");
WM_modalkeymap_assign(keymap, "UV_OT_circle_select");
+ WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle");
}
@@ -3704,6 +3705,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "SEQUENCER_OT_select_border");
WM_modalkeymap_assign(keymap, "SEQUENCER_OT_view_ghost_border");
WM_modalkeymap_assign(keymap, "UV_OT_select_border");
+ WM_modalkeymap_assign(keymap, "CLIP_OT_select_border");
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 963f521c781..913b6523ae6 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -168,6 +168,12 @@ endif()
list(APPEND BLENDER_SORTED_LIBS extern_colamd)
+ if(WITH_LIBMV)
+ list(APPEND BLENDER_SORTED_LIBS extern_libmv)
+ endif()
+
+ list(APPEND BLENDER_SORTED_LIBS extern_colamd)
+
if(WITH_MOD_DECIMATE)
list(APPEND BLENDER_SORTED_LIBS bf_intern_decimate)
endif()
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 3119c4c1d11..8945d6d26cc 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -41,6 +41,7 @@ struct ARegionType;
struct Base;
struct Brush;
struct bNodeTree;
+struct bNodeSocket;
struct CSG_FaceIteratorDescriptor;
struct CSG_VertexIteratorDescriptor;
struct ColorBand;
@@ -212,6 +213,7 @@ void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings
void ED_space_image_set(struct bContext *C, 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_screen_set_scene(struct bContext *C, struct Scene *scene){}
+void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip){}
void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype){}
void ED_render_engine_changed(struct Main *bmain) {}
@@ -269,6 +271,7 @@ void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene){}
int ED_view3d_scene_layer_set(int lay, const int *values){return 0;}
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar){}
void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist){}
+struct BGpic *ED_view3D_background_image_add(struct View3D *v3d){return (struct BGpic *) NULL;}
void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist){}
int text_file_modified(struct Text *text){return 0;}
void ED_node_shader_default(struct Material *ma){}
@@ -386,7 +389,12 @@ void uiTemplateHistogram(struct uiLayout *layout, struct PointerRNA *ptr, char *
void uiTemplateReportsBanner(struct uiLayout *layout, struct bContext *C, struct wmOperator *op){}
void uiTemplateWaveform(struct uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand){}
void uiTemplateVectorscope(struct uiLayout *_self, struct PointerRNA *data, char* property, int expand){}
+void uiTemplateNodeLink(struct uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {}
+void uiTemplateNodeView(struct uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {}
void uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr){}
+void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact){}
+void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname){}
+void uiTemplateMarker(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int compact){}
/* rna render */
struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 1be424d93aa..c1fee1c1642 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -68,6 +68,11 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_LIBMV)
+ blender_include_dirs(../../extern/libmv)
+ add_definitions(-DWITH_LIBMV)
+endif()
+
if(WITH_PYTHON)
blender_include_dirs(../blender/python)
add_definitions(-DWITH_PYTHON)
@@ -570,6 +575,14 @@ elseif(WIN32)
DESTINATION ${TARGETDIR}
)
+ if(WITH_OPENIMAGEIO)
+ install(
+ FILES
+ ${LIBDIR}/openimageio/bin/OpenImageIO.dll
+ DESTINATION ${TARGETDIR}
+ )
+ endif()
+
elseif(APPLE)
set(SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app)
set(SOURCEINFO ${SOURCEDIR}/Contents/Info.plist)
@@ -715,6 +728,9 @@ elseif(APPLE)
endif()
endif()
+# install more files specified elsewhere
+delayed_do_install(${TARGETDIR_VER})
+
unset(BLENDER_TEXT_FILES)
@@ -758,6 +774,7 @@ endif()
bf_editor_space_time
bf_editor_space_userpref
bf_editor_space_view3d
+ bf_editor_space_clip
bf_editor_text
bf_editor_transform
@@ -816,6 +833,7 @@ endif()
extern_minilzo
extern_lzma
extern_colamd
+ extern_libmv
ge_logic_ketsji
extern_recastnavigation
ge_phys_common
@@ -839,6 +857,10 @@ endif()
bf_intern_mikktspace
)
+ if(WITH_LIBMV)
+ list(APPEND BLENDER_SORTED_LIBS extern_libmv)
+ endif()
+
if(WITH_MOD_CLOTH_ELTOPO)
list(APPEND BLENDER_SORTED_LIBS extern_eltopo)
endif()
diff --git a/source/creator/creator.c b/source/creator/creator.c
index c9b8b82054a..7e9e433598b 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -122,6 +122,10 @@
#include "binreloc.h"
#endif
+#ifdef WITH_LIBMV
+#include "libmv-capi.h"
+#endif
+
static int no_handler = 0;
// from buildinfo.c
@@ -382,6 +386,10 @@ static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
#endif // WITH_BUILDINFO
+#ifdef WITH_LIBMV
+ libmv_startDebugLogging();
+#endif
+
BLI_argsPrint(data);
return 0;
}
@@ -1162,6 +1170,10 @@ int main(int argc, const char **argv)
br_init( NULL );
#endif
+#ifdef WITH_LIBMV
+ libmv_initLogging(argv[0]);
+#endif
+
setCallbacks();
#ifdef __APPLE__
/* patch to ignore argument finder gives us (pid?) */