summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--.travis.yml34
-rw-r--r--CONTRIBUTING.md59
-rw-r--r--ISSUE_TEMPLATE10
-rw-r--r--LICENSE.md48
-rw-r--r--README.md6
-rw-r--r--bin/tests/test_containers.cpp22
-rw-r--r--bin/tests/test_detailer.cpp30
-rw-r--r--bin/tests/test_gdscript.cpp2
-rw-r--r--bin/tests/test_gui.cpp56
-rw-r--r--bin/tests/test_io.cpp22
-rw-r--r--bin/tests/test_main.cpp32
-rw-r--r--bin/tests/test_math.cpp83
-rw-r--r--bin/tests/test_particles.cpp32
-rw-r--r--bin/tests/test_physics.cpp60
-rw-r--r--bin/tests/test_python.cpp2
-rw-r--r--bin/tests/test_render.cpp40
-rw-r--r--bin/tests/test_shader_lang.cpp2
-rw-r--r--bin/tests/test_string.cpp332
-rw-r--r--core/bind/core_bind.cpp141
-rw-r--r--core/bind/core_bind.h16
-rw-r--r--core/color.cpp20
-rw-r--r--core/color.h18
-rw-r--r--core/command_queue_mt.cpp2
-rw-r--r--core/command_queue_mt.h280
-rw-r--r--core/dvector.h198
-rw-r--r--core/error_macros.h17
-rw-r--r--core/event_queue.cpp54
-rw-r--r--core/event_queue.h10
-rw-r--r--core/global_constants.cpp18
-rw-r--r--core/globals.cpp34
-rw-r--r--core/globals.h16
-rw-r--r--core/hash_map.h330
-rw-r--r--core/hashfuncs.h8
-rw-r--r--core/image.cpp131
-rw-r--r--core/image.h55
-rw-r--r--core/input_map.cpp7
-rw-r--r--core/io/aes256.h12
-rw-r--r--core/io/fastlz.h26
-rw-r--r--core/io/file_access_buffered.cpp22
-rw-r--r--core/io/file_access_buffered.h6
-rw-r--r--core/io/file_access_network.cpp2
-rw-r--r--core/io/http_client.cpp14
-rw-r--r--core/io/http_client.h4
-rw-r--r--core/io/image_loader.cpp28
-rw-r--r--core/io/image_loader.h14
-rw-r--r--core/io/ip.cpp2
-rw-r--r--core/io/marshalls.cpp8
-rw-r--r--core/io/marshalls.h42
-rw-r--r--core/io/packet_peer.cpp6
-rw-r--r--core/io/resource_format_binary.cpp4
-rw-r--r--core/io/resource_format_xml.cpp3
-rw-r--r--core/io/resource_loader.cpp14
-rw-r--r--core/io/resource_loader.h10
-rw-r--r--core/io/resource_saver.cpp26
-rw-r--r--core/io/resource_saver.h10
-rw-r--r--core/io/stream_peer_ssl.cpp16
-rw-r--r--core/io/stream_peer_ssl.h14
-rw-r--r--core/list.h52
-rw-r--r--core/map.h284
-rw-r--r--core/math/aabb.h32
-rw-r--r--core/math/bsp_tree.cpp84
-rw-r--r--core/math/bsp_tree.h22
-rw-r--r--core/math/camera_matrix.cpp118
-rw-r--r--core/math/camera_matrix.h16
-rw-r--r--core/math/face3.h4
-rw-r--r--core/math/geometry.cpp328
-rw-r--r--core/math/geometry.h106
-rw-r--r--core/math/math_2d.cpp54
-rw-r--r--core/math/math_2d.h92
-rw-r--r--core/math/math_funcs.cpp20
-rw-r--r--core/math/math_funcs.h16
-rw-r--r--core/math/matrix3.cpp42
-rw-r--r--core/math/matrix3.h32
-rw-r--r--core/math/octree.h418
-rw-r--r--core/math/plane.cpp6
-rw-r--r--core/math/plane.h4
-rw-r--r--core/math/quat.cpp12
-rw-r--r--core/math/quat.h14
-rw-r--r--core/math/transform.cpp24
-rw-r--r--core/math/transform.h62
-rw-r--r--core/method_bind.h13
-rw-r--r--core/object.cpp60
-rw-r--r--core/object_type_db.cpp112
-rw-r--r--core/object_type_db.h30
-rw-r--r--core/os/copymem.cpp2
-rw-r--r--core/os/dir_access.cpp22
-rw-r--r--core/os/dir_access.h12
-rw-r--r--core/os/file_access.cpp96
-rw-r--r--core/os/file_access.h46
-rw-r--r--core/os/input.h2
-rw-r--r--core/os/input_event.cpp28
-rw-r--r--core/os/input_event.h8
-rw-r--r--core/os/keyboard.cpp2
-rw-r--r--core/os/keyboard.h22
-rw-r--r--core/os/main_loop.h6
-rw-r--r--core/os/memory.cpp6
-rw-r--r--core/os/memory.h94
-rw-r--r--core/os/memory_pool_dynamic.h8
-rw-r--r--core/os/memory_pool_dynamic_static.cpp84
-rw-r--r--core/os/memory_pool_dynamic_static.h16
-rw-r--r--core/os/memory_pool_static.cpp4
-rw-r--r--core/os/memory_pool_static.h8
-rw-r--r--core/os/mutex.cpp6
-rw-r--r--core/os/mutex.h8
-rw-r--r--core/os/os.cpp8
-rw-r--r--core/os/os.h51
-rw-r--r--core/os/semaphore.h8
-rw-r--r--core/os/shell.h2
-rw-r--r--core/os/thread.cpp14
-rw-r--r--core/os/thread.h24
-rw-r--r--core/os/thread_safe.cpp14
-rw-r--r--core/os/thread_safe.h6
-rw-r--r--core/packed_data_container.cpp6
-rw-r--r--core/path_db.cpp86
-rw-r--r--core/path_db.h10
-rw-r--r--core/pool_allocator.cpp202
-rw-r--r--core/pool_allocator.h58
-rw-r--r--core/register_core_types.cpp7
-rw-r--r--core/res_ptr.cpp2
-rw-r--r--core/res_ptr.h2
-rw-r--r--core/resource.cpp28
-rw-r--r--core/resource.h18
-rw-r--r--core/rid.h76
-rw-r--r--core/ring_buffer.h28
-rw-r--r--core/safe_refcount.cpp4
-rw-r--r--core/safe_refcount.h68
-rw-r--r--core/script_language.cpp10
-rw-r--r--core/script_language.h24
-rw-r--r--core/set.h264
-rw-r--r--core/simple_type.h24
-rw-r--r--core/sort.h128
-rw-r--r--core/string_db.cpp104
-rw-r--r--core/string_db.h36
-rw-r--r--core/typedefs.h43
-rw-r--r--core/undo_redo.cpp6
-rw-r--r--core/ustring.cpp259
-rw-r--r--core/ustring.h18
-rw-r--r--core/variant.cpp373
-rw-r--r--core/variant.h54
-rw-r--r--core/variant_op.cpp65
-rw-r--r--core/variant_parser.cpp13
-rw-r--r--core/vector.h129
-rw-r--r--demos/2d/normalmaps/diffuse.jpgbin535660 -> 309334 bytes
-rw-r--r--demos/2d/normalmaps/diffuse.pngbin2392221 -> 0 bytes
-rw-r--r--demos/2d/normalmaps/normal.jpgbin0 -> 501428 bytes
-rw-r--r--demos/2d/normalmaps/normal.pngbin2301245 -> 0 bytes
-rw-r--r--demos/2d/normalmaps/normal_material.resbin503 -> 508 bytes
-rw-r--r--demos/2d/normalmaps/normalmap.scnbin3168 -> 2829 bytes
-rw-r--r--demos/2d/platformer/stage.xml156
-rw-r--r--demos/2d/screen_space_shaders/art/burano.jpgbin246589 -> 265390 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/burano.pngbin974437 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/forest.jpgbin0 -> 314190 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/forest.pngbin1199433 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/mountains.jpgbin0 -> 214974 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/mountains.pngbin927435 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/platformer.jpgbin0 -> 116815 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/platformer.pngbin44102 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/engine.cfg2
-rw-r--r--demos/2d/screen_space_shaders/screen_shaders.scnbin7562 -> 7897 bytes
-rw-r--r--demos/3d/polygon_path_finder/engine.cfg5
-rw-r--r--demos/3d/polygon_path_finder/icon.pngbin712 -> 0 bytes
-rw-r--r--demos/3d/polygon_path_finder/poly_with_holes.scnbin2974 -> 0 bytes
-rw-r--r--demos/3d/polygon_path_finder/polygonpathfinder.gd77
-rw-r--r--demos/gui/translation/main.scnbin2939 -> 2119 bytes
-rw-r--r--demos/gui/translation/notosans.otfbin16426032 -> 0 bytes
-rw-r--r--demos/plugins/custom_dock/custom_dock.scnbin0 -> 1494 bytes
-rw-r--r--demos/plugins/custom_dock/dock_plugin.gd23
-rw-r--r--demos/plugins/custom_dock/plugin.cfg14
-rw-r--r--demos/plugins/custom_import_plugin/import_plugin.gd81
-rw-r--r--demos/plugins/custom_import_plugin/material_dialog.gd67
-rw-r--r--demos/plugins/custom_import_plugin/material_dialog.tscn111
-rw-r--r--demos/plugins/custom_import_plugin/material_import.gd22
-rw-r--r--demos/plugins/custom_import_plugin/plugin.cfg14
-rw-r--r--demos/plugins/custom_import_plugin/test.mtxt1
-rw-r--r--demos/plugins/custom_node/heart.gd12
-rw-r--r--demos/plugins/custom_node/heart.pngbin0 -> 12584 bytes
-rw-r--r--demos/plugins/custom_node/heart_icon.pngbin0 -> 809 bytes
-rw-r--r--demos/plugins/custom_node/heart_plugin.gd18
-rw-r--r--demos/plugins/custom_node/plugin.cfg14
-rw-r--r--demos/plugins/readme.txt13
-rw-r--r--doc/Makefile2
-rw-r--r--doc/base/classes.xml1905
-rw-r--r--doc/tools/makerst.py518
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp78
-rw-r--r--drivers/gles2/rasterizer_gles2.h2
-rw-r--r--drivers/jpegd/image_loader_jpegd.cpp54
-rw-r--r--drivers/nrex/regex.cpp9
-rw-r--r--drivers/nrex/regex.h1
-rw-r--r--drivers/openssl/stream_peer_openssl.cpp46
-rw-r--r--drivers/openssl/stream_peer_openssl.h1
-rw-r--r--drivers/png/SCsub11
-rw-r--r--drivers/register_driver_types.cpp1
-rw-r--r--drivers/theora/video_stream_theora.cpp3
-rw-r--r--drivers/unix/dir_access_unix.cpp7
-rw-r--r--drivers/unix/memory_pool_static_malloc.cpp29
-rw-r--r--drivers/unix/os_unix.cpp3
-rw-r--r--drivers/unix/thread_posix.cpp17
-rw-r--r--drivers/unix/thread_posix.h5
-rw-r--r--drivers/windows/dir_access_windows.cpp7
-rw-r--r--godot_icon.pngbin12574 -> 0 bytes
-rw-r--r--godot_icon.svg133
-rw-r--r--icon.pngbin0 -> 12525 bytes
-rw-r--r--icon.svg132
-rw-r--r--logo.svg (renamed from godot_logo.svg)0
-rw-r--r--main/input_default.cpp209
-rw-r--r--main/input_default.h9
-rw-r--r--main/main.cpp146
-rw-r--r--modules/gdscript/gd_compiler.cpp6
-rw-r--r--modules/gdscript/gd_compiler.h8
-rw-r--r--modules/gdscript/gd_editor.cpp29
-rw-r--r--modules/gdscript/gd_parser.cpp4
-rw-r--r--modules/gdscript/gd_script.cpp73
-rw-r--r--modules/gdscript/gd_script.h2
-rw-r--r--modules/gdscript/gd_tokenizer.cpp18
-rw-r--r--modules/gridmap/grid_map.cpp6
-rw-r--r--platform/android/SCsub2
-rw-r--r--platform/android/export/export.cpp12
-rw-r--r--platform/android/file_access_android.cpp2
-rw-r--r--platform/android/file_access_jandroid.cpp2
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotLib.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java237
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java140
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java107
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java211
-rw-r--r--platform/android/java_glue.cpp75
-rw-r--r--platform/android/java_glue.h2
-rw-r--r--platform/android/os_android.cpp37
-rw-r--r--platform/android/os_android.h25
-rw-r--r--platform/bb10/export/export.cpp2
-rw-r--r--platform/bb10/os_bb10.cpp4
-rw-r--r--platform/bb10/os_bb10.h2
-rw-r--r--platform/flash/dir_access_flash.cpp4
-rw-r--r--platform/flash/include/GL/gl.h4
-rw-r--r--platform/flash/include/GL/glext.h6
-rw-r--r--platform/flash/include/GL/glxext.h6
-rw-r--r--platform/flash/rasterizer_flash.cpp2
-rw-r--r--platform/haiku/context_gl_haiku.cpp2
-rw-r--r--platform/haiku/context_gl_haiku.h4
-rw-r--r--platform/haiku/godot_haiku.cpp8
-rw-r--r--platform/haiku/key_mapping_haiku.cpp4
-rw-r--r--platform/haiku/os_haiku.cpp2
-rw-r--r--platform/iphone/Appirater.h18
-rwxr-xr-xplatform/iphone/gl_view.h14
-rwxr-xr-xplatform/iphone/gl_view.mm71
-rw-r--r--platform/iphone/icloud.h4
-rw-r--r--platform/iphone/os_iphone.cpp30
-rw-r--r--platform/iphone/os_iphone.h14
-rw-r--r--platform/iphone/rasterizer_iphone.cpp2
-rw-r--r--platform/iphone/xcode/godot_xcode/data.pck0
-rwxr-xr-xplatform/iphone/xcode/godot_xcode/godot_debug.iphone0
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj370
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.pngbin0 -> 529 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.pngbin0 -> 648 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.pngbin0 -> 782 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.pngbin0 -> 1641 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.pngbin0 -> 2547 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.pngbin0 -> 2547 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.pngbin0 -> 3096 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.pngbin0 -> 599 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.pngbin0 -> 3035 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.pngbin0 -> 554 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.pngbin0 -> 480 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.pngbin0 -> 274 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json128
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.pngbin0 -> 215 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.pngbin0 -> 218 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.pngbin0 -> 218 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.pngbin0 -> 224 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.pngbin0 -> 225 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.pngbin0 -> 230 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.pngbin0 -> 207 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.pngbin0 -> 205 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.pngbin0 -> 208 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.pngbin0 -> 208 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.pngbin0 -> 208 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.pngbin0 -> 209 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.pngbin0 -> 209 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.pngbin0 -> 211 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.pngbin0 -> 210 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.pngbin0 -> 227 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.pngbin0 -> 212 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes17
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings2
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist50
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/main.m (renamed from core/os/pc_joystick_map.h)63
-rwxr-xr-xplatform/iphone/xcode/godot_xcode/godot_opt.iphone0
-rw-r--r--platform/javascript/javascript_main.cpp19
-rw-r--r--platform/javascript/os_javascript.cpp6
-rw-r--r--platform/javascript/os_javascript.h4
-rw-r--r--platform/nacl/nacl_keycodes.h2
-rw-r--r--platform/nacl/os_nacl.cpp6
-rw-r--r--platform/nacl/pepper_main.cpp2
-rw-r--r--platform/osx/context_gl_osx.h4
-rw-r--r--platform/osx/dir_access_osx.h26
-rw-r--r--platform/osx/dir_access_osx.mm7
-rw-r--r--platform/osx/os_osx.h2
-rw-r--r--platform/osx/os_osx.mm17
-rw-r--r--platform/server/detect.py1
-rw-r--r--platform/server/godot_server.cpp8
-rw-r--r--platform/server/os_server.cpp18
-rw-r--r--platform/server/os_server.h14
-rw-r--r--platform/windows/context_gl_win.cpp8
-rw-r--r--platform/windows/context_gl_win.h10
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/windows/export/export.cpp343
-rw-r--r--platform/windows/export/export.h33
-rw-r--r--platform/windows/godot_win.cpp2
-rw-r--r--platform/windows/joystick.cpp2
-rw-r--r--platform/windows/key_mapping_win.cpp2
-rw-r--r--platform/windows/os_windows.cpp101
-rw-r--r--platform/windows/os_windows.h34
-rw-r--r--platform/winrt/app.cpp6
-rw-r--r--platform/winrt/app.h2
-rw-r--r--platform/winrt/include/FunctionDiscoveryKeys_devpkey.h2
-rw-r--r--platform/winrt/include/GLES2/gl2ext.h68
-rw-r--r--platform/winrt/include/GLES3/gl3.h2
-rw-r--r--platform/winrt/include/GLSLANG/ShaderLang.h2
-rw-r--r--platform/winrt/include/KHR/khrplatform.h2
-rw-r--r--platform/winrt/os_winrt.cpp29
-rw-r--r--platform/winrt/os_winrt.h26
-rw-r--r--platform/x11/context_gl_x11.cpp26
-rw-r--r--platform/x11/context_gl_x11.h8
-rw-r--r--platform/x11/detect.py22
-rw-r--r--platform/x11/godot_x11.cpp8
-rw-r--r--platform/x11/joystick_linux.cpp53
-rw-r--r--platform/x11/joystick_linux.h8
-rw-r--r--platform/x11/key_mapping_x11.cpp78
-rw-r--r--platform/x11/key_mapping_x11.h2
-rw-r--r--platform/x11/os_x11.cpp279
-rw-r--r--platform/x11/os_x11.h16
-rw-r--r--scene/2d/camera_2d.h2
-rw-r--r--scene/2d/canvas_item.cpp8
-rw-r--r--scene/2d/collision_object_2d.cpp2
-rw-r--r--scene/2d/navigation_polygon.cpp4
-rw-r--r--scene/2d/particles_2d.cpp4
-rw-r--r--scene/2d/particles_2d.h4
-rw-r--r--scene/2d/sprite.cpp12
-rw-r--r--scene/2d/tile_map.cpp13
-rw-r--r--scene/2d/tile_map.h1
-rw-r--r--scene/3d/baked_light_instance.cpp2
-rw-r--r--scene/3d/camera.cpp61
-rw-r--r--scene/3d/camera.h16
-rw-r--r--scene/3d/character_camera.cpp2
-rw-r--r--scene/3d/light.cpp36
-rw-r--r--scene/3d/light.h24
-rw-r--r--scene/3d/mesh_instance.cpp8
-rw-r--r--scene/3d/mesh_instance.h6
-rw-r--r--scene/3d/navigation.cpp10
-rw-r--r--scene/3d/particles.cpp24
-rw-r--r--scene/3d/particles.h38
-rw-r--r--scene/3d/portal.cpp28
-rw-r--r--scene/3d/portal.h10
-rw-r--r--scene/3d/room_instance.cpp2
-rw-r--r--scene/3d/skeleton.cpp110
-rw-r--r--scene/3d/skeleton.h38
-rw-r--r--scene/3d/spatial.cpp34
-rw-r--r--scene/3d/spatial.h14
-rw-r--r--scene/3d/spatial_sample_player.h2
-rw-r--r--scene/3d/test_cube.h4
-rw-r--r--scene/3d/visual_instance.cpp42
-rw-r--r--scene/3d/visual_instance.h16
-rw-r--r--scene/animation/animation_player.cpp186
-rw-r--r--scene/animation/animation_player.h70
-rw-r--r--scene/animation/animation_tree_player.cpp54
-rw-r--r--scene/animation/tween.cpp12
-rw-r--r--scene/animation/tween.h4
-rw-r--r--scene/audio/event_player.cpp2
-rw-r--r--scene/audio/stream_player.cpp16
-rw-r--r--scene/audio/stream_player.h1
-rw-r--r--scene/gui/base_button.cpp96
-rw-r--r--scene/gui/base_button.h16
-rw-r--r--scene/gui/button.cpp32
-rw-r--r--scene/gui/button.h16
-rw-r--r--scene/gui/button_array.cpp4
-rw-r--r--scene/gui/button_array.h2
-rw-r--r--scene/gui/button_group.h2
-rw-r--r--scene/gui/check_button.cpp10
-rw-r--r--scene/gui/check_button.h14
-rw-r--r--scene/gui/color_picker.cpp97
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/color_ramp_edit.cpp2
-rw-r--r--scene/gui/control.cpp195
-rw-r--r--scene/gui/control.h64
-rw-r--r--scene/gui/dialogs.cpp22
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/file_dialog.cpp184
-rw-r--r--scene/gui/file_dialog.h25
-rw-r--r--scene/gui/graph_edit.cpp108
-rw-r--r--scene/gui/graph_edit.h15
-rw-r--r--scene/gui/graph_node.cpp1
-rw-r--r--scene/gui/item_list.cpp85
-rw-r--r--scene/gui/item_list.h7
-rw-r--r--scene/gui/line_edit.cpp285
-rw-r--r--scene/gui/line_edit.h42
-rw-r--r--scene/gui/link_button.cpp124
-rw-r--r--scene/gui/link_button.h40
-rw-r--r--scene/gui/menu_button.cpp10
-rw-r--r--scene/gui/menu_button.h12
-rw-r--r--scene/gui/option_button.cpp60
-rw-r--r--scene/gui/option_button.h18
-rw-r--r--scene/gui/panel.cpp4
-rw-r--r--scene/gui/panel.h4
-rw-r--r--scene/gui/panel_container.cpp7
-rw-r--r--scene/gui/popup.cpp20
-rw-r--r--scene/gui/popup.h12
-rw-r--r--scene/gui/popup_menu.cpp112
-rw-r--r--scene/gui/popup_menu.h26
-rw-r--r--scene/gui/range.cpp34
-rw-r--r--scene/gui/range.h10
-rw-r--r--scene/gui/rich_text_label.cpp6
-rw-r--r--scene/gui/scroll_bar.cpp324
-rw-r--r--scene/gui/scroll_bar.h42
-rw-r--r--scene/gui/scroll_container.cpp38
-rw-r--r--scene/gui/slider.cpp8
-rw-r--r--scene/gui/slider.h2
-rw-r--r--scene/gui/tab_container.cpp4
-rw-r--r--scene/gui/tabs.cpp2
-rw-r--r--scene/gui/text_edit.cpp1753
-rw-r--r--scene/gui/text_edit.h37
-rw-r--r--scene/gui/texture_frame.h2
-rw-r--r--scene/gui/texture_progress.cpp6
-rw-r--r--scene/gui/tree.cpp35
-rw-r--r--scene/gui/tree.h123
-rw-r--r--scene/gui/video_player.cpp2
-rw-r--r--scene/io/resource_format_image.cpp40
-rw-r--r--scene/main/http_request.cpp512
-rw-r--r--scene/main/http_request.h103
-rw-r--r--scene/main/misc.h2
-rw-r--r--scene/main/node.cpp326
-rw-r--r--scene/main/node.h74
-rw-r--r--scene/main/scene_main_loop.cpp4
-rw-r--r--scene/main/scene_main_loop.h2
-rw-r--r--scene/main/timer.cpp5
-rw-r--r--scene/main/viewport.cpp77
-rw-r--r--scene/main/viewport.h12
-rw-r--r--scene/register_scene_types.cpp12
-rw-r--r--scene/resources/animation.cpp316
-rw-r--r--scene/resources/animation.h76
-rw-r--r--scene/resources/default_theme/default_theme.cpp33
-rw-r--r--scene/resources/default_theme/icon_zoom_less.pngbin0 -> 390 bytes
-rw-r--r--scene/resources/default_theme/icon_zoom_more.pngbin0 -> 388 bytes
-rw-r--r--scene/resources/default_theme/icon_zoom_reset.pngbin0 -> 311 bytes
-rw-r--r--scene/resources/default_theme/popup_window.pngbin1050 -> 866 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h22
-rw-r--r--scene/resources/environment.h2
-rw-r--r--scene/resources/font.cpp36
-rw-r--r--scene/resources/font.h28
-rw-r--r--scene/resources/material.h2
-rw-r--r--scene/resources/mesh.cpp64
-rw-r--r--scene/resources/mesh.h26
-rw-r--r--scene/resources/mesh_library.cpp2
-rw-r--r--scene/resources/mesh_library.h2
-rw-r--r--scene/resources/packed_scene.cpp38
-rw-r--r--scene/resources/packed_scene.h13
-rw-r--r--scene/resources/polygon_path_finder.cpp2
-rw-r--r--scene/resources/polygon_path_finder.h2
-rw-r--r--scene/resources/room.cpp2
-rw-r--r--scene/resources/room.h8
-rw-r--r--scene/resources/sample.cpp2
-rw-r--r--scene/resources/scene_format_text.cpp30
-rw-r--r--scene/resources/shader_graph.cpp18
-rw-r--r--scene/resources/style_box.cpp30
-rw-r--r--scene/resources/style_box.h46
-rw-r--r--scene/resources/surface_tool.cpp2
-rw-r--r--scene/resources/texture.cpp36
-rw-r--r--scene/resources/texture.h16
-rw-r--r--scene/resources/theme.cpp104
-rw-r--r--scene/resources/theme.h12
-rw-r--r--scene/resources/tile_set.cpp6
-rw-r--r--scene/resources/volume.cpp34
-rw-r--r--scene/resources/volume.h18
-rw-r--r--servers/audio/audio_mixer_sw.cpp6
-rw-r--r--servers/audio/audio_mixer_sw.h2
-rw-r--r--servers/audio/audio_server_sw.cpp3
-rw-r--r--servers/audio/audio_server_sw.h2
-rw-r--r--servers/physics/gjk_epa.cpp104
-rw-r--r--servers/physics/space_sw.cpp2
-rw-r--r--servers/physics_2d/body_2d_sw.cpp8
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp6
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h2
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp22
-rw-r--r--servers/physics_2d/space_2d_sw.cpp8
-rw-r--r--servers/physics_2d/space_2d_sw.h2
-rw-r--r--servers/physics_2d/step_2d_sw.cpp2
-rw-r--r--servers/physics_2d_server.h4
-rw-r--r--servers/physics_server.h4
-rw-r--r--servers/register_server_types.cpp4
-rw-r--r--servers/spatial_sound/spatial_sound_server_sw.cpp8
-rw-r--r--servers/spatial_sound/spatial_sound_server_sw.h2
-rw-r--r--servers/visual/particle_system_sw.cpp34
-rw-r--r--servers/visual/particle_system_sw.h18
-rw-r--r--servers/visual/rasterizer.cpp2
-rw-r--r--servers/visual/rasterizer.h96
-rw-r--r--servers/visual/shader_graph.cpp104
-rw-r--r--servers/visual/shader_graph.h12
-rw-r--r--servers/visual/shader_language.cpp4
-rw-r--r--servers/visual/visual_server_raster.cpp497
-rw-r--r--servers/visual/visual_server_raster.h201
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp34
-rw-r--r--servers/visual/visual_server_wrap_mt.h13
-rw-r--r--servers/visual_server.cpp68
-rw-r--r--servers/visual_server.h140
-rwxr-xr-xtools/Godot.app/Contents/Info.plist4
-rw-r--r--tools/SCsub1
-rw-r--r--tools/certs/ca-certificates.crt4826
-rw-r--r--tools/collada/collada.cpp2
-rw-r--r--tools/doc/doc_data.cpp10
-rw-r--r--tools/docdump/doc_dump.cpp2
-rw-r--r--tools/docker/Dockerfile13
-rw-r--r--tools/docker/README.md40
-rw-r--r--tools/docker/scripts/install-android-tools90
-rw-r--r--tools/editor/SCsub28
-rw-r--r--tools/editor/addon_editor_plugin.cpp1273
-rw-r--r--tools/editor/addon_editor_plugin.h286
-rw-r--r--tools/editor/animation_editor.cpp79
-rw-r--r--tools/editor/animation_editor.h4
-rw-r--r--tools/editor/call_dialog.cpp134
-rw-r--r--tools/editor/call_dialog.h26
-rw-r--r--tools/editor/code_editor.cpp14
-rw-r--r--tools/editor/code_editor.h2
-rw-r--r--tools/editor/connections_dialog.cpp120
-rw-r--r--tools/editor/connections_dialog.h30
-rw-r--r--tools/editor/create_dialog.cpp111
-rw-r--r--tools/editor/create_dialog.h18
-rw-r--r--tools/editor/editor_asset_installer.cpp327
-rw-r--r--tools/editor/editor_asset_installer.h28
-rw-r--r--tools/editor/editor_data.cpp33
-rw-r--r--tools/editor/editor_data.h4
-rw-r--r--tools/editor/editor_file_dialog.cpp14
-rw-r--r--tools/editor/editor_file_dialog.h3
-rw-r--r--tools/editor/editor_file_system.cpp2
-rw-r--r--tools/editor/editor_help.cpp229
-rw-r--r--tools/editor/editor_help.h9
-rw-r--r--tools/editor/editor_import_export.cpp166
-rw-r--r--tools/editor/editor_import_export.h15
-rw-r--r--tools/editor/editor_initialize_ssl.cpp21
-rw-r--r--tools/editor/editor_initialize_ssl.h6
-rw-r--r--tools/editor/editor_node.cpp450
-rw-r--r--tools/editor/editor_node.h54
-rw-r--r--tools/editor/editor_plugin.cpp107
-rw-r--r--tools/editor/editor_plugin.h42
-rw-r--r--tools/editor/editor_plugin_settings.cpp188
-rw-r--r--tools/editor/editor_plugin_settings.h35
-rw-r--r--tools/editor/editor_settings.cpp303
-rw-r--r--tools/editor/editor_settings.h17
-rw-r--r--tools/editor/editor_sub_scene.cpp4
-rw-r--r--tools/editor/groups_editor.h2
-rw-r--r--tools/editor/icons/icon_array_data.pngbin212 -> 176 bytes
-rw-r--r--tools/editor/icons/icon_array_float.pngbin213 -> 177 bytes
-rw-r--r--tools/editor/icons/icon_array_int.pngbin204 -> 172 bytes
-rw-r--r--tools/editor/icons/icon_array_string.pngbin217 -> 178 bytes
-rw-r--r--tools/editor/icons/icon_array_variant.pngbin209 -> 172 bytes
-rw-r--r--tools/editor/icons/icon_bool.pngbin147 -> 164 bytes
-rw-r--r--tools/editor/icons/icon_color.pngbin322 -> 301 bytes
-rw-r--r--tools/editor/icons/icon_godot_asset_default.pngbin0 -> 4167 bytes
-rw-r--r--tools/editor/icons/icon_h_t_t_p_request.pngbin0 -> 573 bytes
-rw-r--r--tools/editor/icons/icon_integer.pngbin142 -> 162 bytes
-rw-r--r--tools/editor/icons/icon_link_button.pngbin0 -> 376 bytes
-rw-r--r--tools/editor/icons/icon_quat.pngbin265 -> 239 bytes
-rw-r--r--tools/editor/icons/icon_rating_no_star.pngbin0 -> 288 bytes
-rw-r--r--tools/editor/icons/icon_rating_star.pngbin0 -> 289 bytes
-rw-r--r--tools/editor/icons/icon_real.pngbin146 -> 162 bytes
-rw-r--r--tools/editor/icons/icon_rect2.pngbin240 -> 193 bytes
-rw-r--r--tools/editor/icons/icon_rect3.pngbin230 -> 202 bytes
-rw-r--r--tools/editor/icons/icon_reload_empty.pngbin0 -> 251 bytes
-rw-r--r--tools/editor/icons/icon_reload_small.pngbin0 -> 447 bytes
-rw-r--r--tools/editor/icons/icon_string.pngbin121 -> 136 bytes
-rw-r--r--tools/editor/icons/icon_thumbnail_wait.pngbin0 -> 2616 bytes
-rw-r--r--tools/editor/icons/icon_vector.pngbin158 -> 183 bytes
-rw-r--r--tools/editor/icons/icon_vector2.pngbin141 -> 172 bytes
-rw-r--r--tools/editor/io_plugins/editor_font_import_plugin.cpp2
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp8
-rw-r--r--tools/editor/io_plugins/editor_sample_import_plugin.cpp8
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp13
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.h2
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.cpp4
-rw-r--r--tools/editor/output_strings.cpp2
-rw-r--r--tools/editor/output_strings.h2
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp22
-rw-r--r--tools/editor/plugins/animation_tree_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/baked_light_baker.h2
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp27
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.h14
-rw-r--r--tools/editor/plugins/collision_polygon_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/collision_shape_2d_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/color_ramp_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/control_editor_plugin.cpp56
-rw-r--r--tools/editor/plugins/control_editor_plugin.h24
-rw-r--r--tools/editor/plugins/cube_grid_theme_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/editor_preview_plugins.cpp6
-rw-r--r--tools/editor/plugins/item_list_editor_plugin.cpp12
-rw-r--r--tools/editor/plugins/multimesh_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/particles_2d_editor_plugin.cpp28
-rw-r--r--tools/editor/plugins/particles_2d_editor_plugin.h6
-rw-r--r--tools/editor/plugins/path_editor_plugin.cpp12
-rw-r--r--tools/editor/plugins/path_editor_plugin.h6
-rw-r--r--tools/editor/plugins/polygon_2d_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/resource_preloader_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp42
-rw-r--r--tools/editor/plugins/script_editor_plugin.h2
-rw-r--r--tools/editor/plugins/shader_editor_plugin.cpp8
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp102
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.h24
-rw-r--r--tools/editor/progress_dialog.cpp4
-rw-r--r--tools/editor/progress_dialog.h2
-rw-r--r--tools/editor/project_export.cpp12
-rw-r--r--tools/editor/project_export.h3
-rw-r--r--tools/editor/project_manager.cpp6
-rw-r--r--tools/editor/project_settings.cpp239
-rw-r--r--tools/editor/project_settings.h21
-rw-r--r--tools/editor/property_editor.cpp111
-rw-r--r--tools/editor/property_editor.h11
-rw-r--r--tools/editor/reparent_dialog.cpp16
-rw-r--r--tools/editor/reparent_dialog.h16
-rw-r--r--tools/editor/run_settings_dialog.cpp2
-rw-r--r--tools/editor/scene_tree_editor.cpp66
-rw-r--r--tools/editor/scene_tree_editor.h16
-rw-r--r--tools/editor/scenes_dock.cpp6
-rw-r--r--tools/editor/scenes_dock.h2
-rw-r--r--tools/editor/script_create_dialog.cpp4
-rw-r--r--tools/editor/settings_config_dialog.cpp207
-rw-r--r--tools/editor/settings_config_dialog.h14
-rw-r--r--tools/editor/spatial_editor_gizmos.cpp69
-rw-r--r--tools/editor/spatial_editor_gizmos.h94
-rw-r--r--tools/export/blender25/io_scene_dae/export_dae.py2
-rw-r--r--tools/pe_bliss/README84
-rw-r--r--tools/pe_bliss/SCsub5
-rw-r--r--tools/pe_bliss/entropy.cpp111
-rw-r--r--tools/pe_bliss/entropy.h51
-rw-r--r--tools/pe_bliss/file_version_info.cpp440
-rw-r--r--tools/pe_bliss/file_version_info.h199
-rw-r--r--tools/pe_bliss/message_table.cpp81
-rw-r--r--tools/pe_bliss/message_table.h56
-rw-r--r--tools/pe_bliss/pe_base.cpp1680
-rw-r--r--tools/pe_bliss/pe_base.h544
-rw-r--r--tools/pe_bliss/pe_bliss.h39
-rw-r--r--tools/pe_bliss/pe_bliss_godot.cpp118
-rw-r--r--tools/pe_bliss/pe_bliss_godot.h7
-rw-r--r--tools/pe_bliss/pe_bliss_resources.h36
-rw-r--r--tools/pe_bliss/pe_bound_import.cpp311
-rw-r--r--tools/pe_bliss/pe_bound_import.h108
-rw-r--r--tools/pe_bliss/pe_checksum.cpp103
-rw-r--r--tools/pe_bliss/pe_checksum.h30
-rw-r--r--tools/pe_bliss/pe_debug.cpp865
-rw-r--r--tools/pe_bliss/pe_debug.h324
-rw-r--r--tools/pe_bliss/pe_directory.cpp59
-rw-r--r--tools/pe_bliss/pe_directory.h50
-rw-r--r--tools/pe_bliss/pe_dotnet.cpp186
-rw-r--r--tools/pe_bliss/pe_dotnet.h97
-rw-r--r--tools/pe_bliss/pe_exception.cpp40
-rw-r--r--tools/pe_bliss/pe_exception.h130
-rw-r--r--tools/pe_bliss/pe_exception_directory.cpp177
-rw-r--r--tools/pe_bliss/pe_exception_directory.h88
-rw-r--r--tools/pe_bliss/pe_exports.cpp700
-rw-r--r--tools/pe_bliss/pe_exports.h184
-rw-r--r--tools/pe_bliss/pe_factory.cpp43
-rw-r--r--tools/pe_bliss/pe_factory.h39
-rw-r--r--tools/pe_bliss/pe_imports.cpp777
-rw-r--r--tools/pe_bliss/pe_imports.h208
-rw-r--r--tools/pe_bliss/pe_load_config.cpp557
-rw-r--r--tools/pe_bliss/pe_load_config.h184
-rw-r--r--tools/pe_bliss/pe_properties.cpp41
-rw-r--r--tools/pe_bliss/pe_properties.h236
-rw-r--r--tools/pe_bliss/pe_properties_generic.cpp645
-rw-r--r--tools/pe_bliss/pe_properties_generic.h277
-rw-r--r--tools/pe_bliss/pe_rebuilder.cpp214
-rw-r--r--tools/pe_bliss/pe_rebuilder.h40
-rw-r--r--tools/pe_bliss/pe_relocations.cpp320
-rw-r--r--tools/pe_bliss/pe_relocations.h122
-rw-r--r--tools/pe_bliss/pe_resource_manager.cpp286
-rw-r--r--tools/pe_bliss/pe_resource_manager.h113
-rw-r--r--tools/pe_bliss/pe_resource_viewer.cpp382
-rw-r--r--tools/pe_bliss/pe_resource_viewer.h153
-rw-r--r--tools/pe_bliss/pe_resources.cpp726
-rw-r--r--tools/pe_bliss/pe_resources.h245
-rw-r--r--tools/pe_bliss/pe_rich_data.cpp152
-rw-r--r--tools/pe_bliss/pe_rich_data.h58
-rw-r--r--tools/pe_bliss/pe_section.cpp303
-rw-r--r--tools/pe_bliss/pe_section.h158
-rw-r--r--tools/pe_bliss/pe_structures.h1028
-rw-r--r--tools/pe_bliss/pe_tls.cpp396
-rw-r--r--tools/pe_bliss/pe_tls.h122
-rw-r--r--tools/pe_bliss/resource_bitmap_reader.cpp86
-rw-r--r--tools/pe_bliss/resource_bitmap_reader.h50
-rw-r--r--tools/pe_bliss/resource_bitmap_writer.cpp75
-rw-r--r--tools/pe_bliss/resource_bitmap_writer.h47
-rw-r--r--tools/pe_bliss/resource_cursor_icon_reader.cpp521
-rw-r--r--tools/pe_bliss/resource_cursor_icon_reader.h84
-rw-r--r--tools/pe_bliss/resource_cursor_icon_writer.cpp447
-rw-r--r--tools/pe_bliss/resource_cursor_icon_writer.h94
-rw-r--r--tools/pe_bliss/resource_data_info.cpp48
-rw-r--r--tools/pe_bliss/resource_data_info.h48
-rw-r--r--tools/pe_bliss/resource_internal.h34
-rw-r--r--tools/pe_bliss/resource_message_list_reader.cpp131
-rw-r--r--tools/pe_bliss/resource_message_list_reader.h49
-rw-r--r--tools/pe_bliss/resource_string_table_reader.cpp109
-rw-r--r--tools/pe_bliss/resource_string_table_reader.h57
-rw-r--r--tools/pe_bliss/resource_version_info_reader.cpp311
-rw-r--r--tools/pe_bliss/resource_version_info_reader.h67
-rw-r--r--tools/pe_bliss/resource_version_info_writer.cpp283
-rw-r--r--tools/pe_bliss/resource_version_info_writer.h52
-rw-r--r--tools/pe_bliss/stdint_defs.h45
-rw-r--r--tools/pe_bliss/utils.cpp85
-rw-r--r--tools/pe_bliss/utils.h105
-rw-r--r--tools/pe_bliss/version_info_editor.cpp184
-rw-r--r--tools/pe_bliss/version_info_editor.h79
-rw-r--r--tools/pe_bliss/version_info_types.h38
-rw-r--r--tools/pe_bliss/version_info_viewer.cpp180
-rw-r--r--tools/pe_bliss/version_info_viewer.h89
-rw-r--r--tools/scripts/sort-demos.sh29
-rw-r--r--tools/steam/make_icons.sh5
-rw-r--r--version.py2
716 files changed, 23145 insertions, 28749 deletions
diff --git a/.gitignore b/.gitignore
index 92516285b6..15ca139916 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@ core/global_defaults.cpp
drivers/unix/os_unix_global_settings_path.cpp
tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h
+tools/editor/certs_compressed.h
tools/editor/editor_icons.cpp
-fpic
.fscache
@@ -64,6 +65,9 @@ platform/android/libs/play_licensing/gen/*
.deps/*
.dirstamp
+# Vim temp files
+*.swo
+*.swp
# QT project files
*.config
diff --git a/.travis.yml b/.travis.yml
index a8ecc62c58..11dcdf447c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
language: cpp
-sudo: required
-dist: trusty
+sudo: false
compiler:
- gcc
@@ -32,15 +31,42 @@ matrix:
env: GODOT_TARGET=windows
- compiler: gcc
env: GODOT_TARGET=iphone
+ - compiler: gcc
+ env: GODOT_TARGET=osx
- compiler: clang
env: GODOT_TARGET=android
- compiler: clang
env: GODOT_TARGET=windows
+ - compiler: clang
+ env: GODOT_TARGET=x11
+
+addons:
+ apt:
+ packages:
+ - build-essential
+ - scons
+ - pkg-config
+ - libx11-dev
+ - libxcursor-dev
+ - libasound2-dev
+ - libfreetype6-dev
+ - libgl1-mesa-dev
+ - libglu1-mesa-dev
+ - libssl-dev
+ - libxinerama-dev
+ - libudev-dev
+
+ # For cross-compiling to Windows.
+ - binutils-mingw-w64-i686
+ - binutils-mingw-w64-x86-64
+ - gcc-mingw-w64-i686
+ - gcc-mingw-w64-x86-64
+ - g++-mingw-w64-i686
+ - g++-mingw-w64-x86-64
+ - mingw-w64
before_script:
- - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq; sudo apt-get install -y scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libudev-dev; fi
- - if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "windows" ]; then sudo apt-get update -qq; sudo apt-get install -y mingw32 mingw-w64; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then brew update; brew install android-sdk android-ndk; export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk; fi
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..887fe93779
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,59 @@
+# How to contribute efficiently
+
+**Please read the first section before reporting a bug!**
+
+## Reporting bugs or proposing features
+
+The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
+
+Everything refered to hereafter as "bug" also applies for feature requests.
+
+If you are reporting a new issue, you will make our life much simpler (and the fix come much sooner) by following those guidelines:
+
+#### Search first in the existing database
+
+Issues are often reported several times by various users. It's a good practice to **search first** in the issues database before reporting your issue. If you don't find a relevant match or if you are unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
+
+#### Specify the platform
+
+Godot runs on a large variety of platforms and operating systems and devices. If you believe your issue is device/platform dependent (for example if it is related to the rendering, crashes or compilation errors), please specify:
+* Operating system
+* Device (including architecture, e.g. x86, x86_64, arm, etc.)
+* GPU model (and driver in use if you know it)
+
+#### Specify steps to reproduce
+
+Many bugs can't be reproduced unless specific steps are taken. Please **specify the exact steps** that must be taken to reproduce the condition, and try to keep them as minimal as possible.
+
+#### Provide a simple, example project
+
+Sometimes an unexpected behavior happens in your project. In such case, understand that:
+
+* What happens to you may not happen to other users.
+* We can't take the time to look at your project, understand how it is set up and then figure out why it's failing.
+
+To speed up our work, please prepare for us **a simple project** that isolates and reproduces the issue. This is always the **the best way for us to fix it**. You can attach a zip file with the minimal project directly to the bug report, by drag and dropping the file in the GitHub edition field.
+
+## Contributing pull requests
+
+If you want to add new engine functionalities, please make sure that:
+
+* This functionality is desired.
+* You talked to other developers on how to implement it best (on either communication channel, and maybe in a GitHub issue first before making your PR).
+* Even if it does not get merged, your PR is useful for future work by another developer.
+
+Similar rules can be applied when contributing bug fixes - it's always best to discuss the implementation in the bug report first if you are not 100% about what would be the best fix.
+
+#### Be nice to the git history
+
+Try to make simple PRs with that handle one specific topic. Just like for reporting issues, it's better to open 3 different PRs that each address a different issue than one big PR with three commits.
+
+When updating your fork with upstream changes, please use ``git pull --rebase`` to avoid creating "merge commits". Those commits unnecessarily pollute the git history when coming from PRs.
+
+Also try to make commits that bring the engine from one stable state to another stable state, i.e. if your first commit has a bug that you fixed in the second commit, try to merge them together before making your pull request (see ``git rebase -i`` and relevant help about rebasing or ammending commits on the Internet).
+
+This git style guide has some good practices to have in mind: https://github.com/agis-/git-style-guide
+
+Thanks!
+
+The Godot development team
diff --git a/ISSUE_TEMPLATE b/ISSUE_TEMPLATE
new file mode 100644
index 0000000000..06fa7b316d
--- /dev/null
+++ b/ISSUE_TEMPLATE
@@ -0,0 +1,10 @@
+**Operating system or device:**
+
+
+**Issue description** (what happened, and what was expected):
+
+
+**Steps to reproduce:**
+
+
+**Link to minimal example project** (optional but very welcome):
diff --git a/LICENSE.md b/LICENSE.md
index 2f78f0e37d..2f3e879c8c 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,27 +1,27 @@
- GODOT ENGINE
- http://www.godotengine.org
-**********************************************************************
- Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.
-
- 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.
+ GODOT ENGINE
+ http://www.godotengine.org
+
+************************************************************************
+
+ Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.
+ 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.
+************************************************************************
diff --git a/README.md b/README.md
index 20d1367762..2586a5ea0d 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
![GODOT](/logo.png)
+http://www.godotengine.org
+
### The Engine
Godot is a fully featured, open source, MIT licensed, game engine. It focuses on having great tools, and a visual oriented workflow that can export to PC, Mobile and Web platforms with no hassle.
@@ -11,7 +13,7 @@ Godot has been developed by Juan Linietsky and Ariel Manzur for several years, a
### Documentation
-Documentation has been moved to the [OpenProject Wiki](http://godotengine.org/projects/godot-engine/wiki/Documentation).
+Documentation has been moved to [ReadTheDocs](http://docs.godotengine.org).
### Binary Downloads, Community, etc.
@@ -22,6 +24,6 @@ http://www.godotengine.org
### Compiling from Source
Compilation instructions for every platform can be found in the Wiki:
-http://godotengine.org/projects/godot-engine/wiki/Advanced_topics
+http://docs.godotengine.org/en/latest/reference/_compiling.html
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
diff --git a/bin/tests/test_containers.cpp b/bin/tests/test_containers.cpp
index f8cc8ccd41..4bc297d0ba 100644
--- a/bin/tests/test_containers.cpp
+++ b/bin/tests/test_containers.cpp
@@ -44,9 +44,9 @@ MainLoop * test() {
/*
HashMap<int,int> int_map;
-
+
for (int i=0;i<68000;i++) {
-
+
int num=(int)Math::random(0,1024);
int_map[i]=num;
}
@@ -70,21 +70,21 @@ MainLoop * test() {
};
};
-
-#if 0
+
+#if 0
Set<int> set;
-
+
print_line("Begin Insert");
for (int i=0;i<1100;i++) {
-
+
int num=i;//(int)Math::random(0,1024);
- // print_line("inserting "+itos(num));
+ // print_line("inserting "+itos(num));
set.insert( num );
}
-
+
/*
for (int i=0;i<400;i++) {
-
+
int num=(int)Math::random(0,1024);
set.erase(num);
}
@@ -92,11 +92,11 @@ MainLoop * test() {
//set.print_tree();
for(Set<int>::Element *I=set.front();I;I=I->next()) {
-
+
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
}
-
+
print_line("depth is "+itos(set.calculate_depth()));
print_line("Insert Success");
#endif
diff --git a/bin/tests/test_detailer.cpp b/bin/tests/test_detailer.cpp
index 616356077e..5dba7c3f72 100644
--- a/bin/tests/test_detailer.cpp
+++ b/bin/tests/test_detailer.cpp
@@ -44,7 +44,7 @@ class TestMainLoop : public MainLoop {
RID light;
RID mesh;
RID scenario;
-
+
#define MULTIMESH_COUNT 1500
float ofs_x,ofs_y;
@@ -122,9 +122,9 @@ public:
}
virtual void input_event(const InputEvent& p_event) {
-
+
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
-
+
ofs_x+=p_event.mouse_motion.relative_y/200.0;
ofs_y+=p_event.mouse_motion.relative_x/200.0;
}
@@ -142,16 +142,16 @@ public:
}
-
+
virtual void request_quit() {
-
+
quit=true;
}
virtual void init() {
-
+
VisualServer *vs=VisualServer::get_singleton();
@@ -163,13 +163,13 @@ public:
_update_qh();
instance = vs->instance_create2(mesh,scenario);
-
+
camera = vs->camera_create();
-
+
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
- vs->viewport_attach_camera( viewport, camera );
+ vs->viewport_attach_camera( viewport, camera );
vs->viewport_attach_to_screen(viewport);
vs->viewport_set_scenario( viewport, scenario );
@@ -179,7 +179,7 @@ public:
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
light = vs->instance_create2( lightaux,scenario );
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
-
+
ofs_x=0;
ofs_y=0;
quit=false;
@@ -190,20 +190,20 @@ public:
}
virtual bool iteration(float p_time) {
-
+
VisualServer *vs=VisualServer::get_singleton();
-
+
Transform tr_camera;
tr_camera.rotate( Vector3(0,1,0), ofs_y );
tr_camera.rotate( Vector3(1,0,0),ofs_x );
tr_camera.translate(0,0,10);
-
+
vs->camera_set_transform( camera, tr_camera );
-
+
return quit;
}
virtual void finish() {
-
+
}
};
diff --git a/bin/tests/test_gdscript.cpp b/bin/tests/test_gdscript.cpp
index 683191fba2..4578f5aa02 100644
--- a/bin/tests/test_gdscript.cpp
+++ b/bin/tests/test_gdscript.cpp
@@ -81,7 +81,7 @@ static String _parser_expr(const GDParser::Node *p_expr) {
case GDParser::Node::TYPE_IDENTIFIER: {
- const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
+ const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
txt=id_node->name;
} break;
case GDParser::Node::TYPE_CONSTANT: {
diff --git a/bin/tests/test_gui.cpp b/bin/tests/test_gui.cpp
index cba488a3da..f4341fd7b3 100644
--- a/bin/tests/test_gui.cpp
+++ b/bin/tests/test_gui.cpp
@@ -62,16 +62,16 @@ class TestMainLoop : public SceneTree {
Control *control;
-
+
public:
virtual void request_quit() {
-
+
quit();
-
+
}
virtual void init() {
-
+
SceneTree::init();
@@ -112,7 +112,7 @@ public:
Ref<Theme> t = memnew( Theme );
frame->set_theme(t);
-
+
get_root()->add_child( frame );
Label *label = memnew( Label );
@@ -198,21 +198,21 @@ public:
//root->add_child( control );
-
+
LineEdit *line_edit = memnew( LineEdit );
-
+
line_edit->set_pos( Point2( 30,190 ) );
line_edit->set_size( Point2( 180,1 ) );
-
+
frame->add_child(line_edit);
-
+
HScrollBar *hscroll = memnew( HScrollBar );
-
+
hscroll->set_pos( Point2( 30,290 ) );
hscroll->set_size( Point2( 180,1 ) );
hscroll->set_max(10);
hscroll->set_page(4);
-
+
frame->add_child(hscroll);
@@ -234,36 +234,36 @@ public:
hscroll->share(progress);
MenuButton *menu_button = memnew( MenuButton );
-
+
menu_button->set_text("I'm a menu!");
menu_button->set_pos( Point2( 30,380 ) );
menu_button->set_size( Point2( 1,1 ) );
-
- frame->add_child(menu_button);
-
+
+ frame->add_child(menu_button);
+
PopupMenu *popup = menu_button->get_popup();
-
+
popup->add_item("Hello, testing");
popup->add_item("My Dearest");
popup->add_separator();
popup->add_item("Popup");
popup->add_check_item("Check Popup");
- popup->set_item_checked(4,true);
-
+ popup->set_item_checked(4,true);
+
OptionButton *options = memnew( OptionButton );
-
+
options->add_item("Hello, testing");
options->add_item("My Dearest");
-
+
options->set_pos( Point2( 230,180 ) );
options->set_size( Point2( 1,1 ) );
-
- frame->add_child(options);
+
+ frame->add_child(options);
/*
Tree * tree = memnew( Tree );
tree->set_columns(2);
-
+
tree->set_pos( Point2( 230,210 ) );
tree->set_size( Point2( 150,250 ) );
@@ -286,7 +286,7 @@ public:
item->set_editable(0,true);
item->set_text(0,"Have,Many,Several,Options!");
item->set_range(0,2);
-
+
frame->add_child(tree);
*/
@@ -365,11 +365,11 @@ public:
tabc->add_child(ctl);
frame->add_child(tabc);
-
+
tabc->set_pos( Point2( 400,210 ) );
tabc->set_size( Point2( 180,250 ) );
-
+
Ref<ImageTexture> text = memnew( ImageTexture );
text->load("test_data/concave.png");
@@ -387,13 +387,13 @@ public:
}
-
+
};
MainLoop* test() {
-
+
return memnew( TestMainLoop );
}
diff --git a/bin/tests/test_io.cpp b/bin/tests/test_io.cpp
index a1eb2be19b..a8e8d7d0fd 100644
--- a/bin/tests/test_io.cpp
+++ b/bin/tests/test_io.cpp
@@ -47,37 +47,37 @@ namespace TestIO {
class TestMainLoop : public MainLoop {
-
-
+
+
bool quit;
-
+
public:
virtual void input_event(const InputEvent& p_event) {
-
-
+
+
}
virtual bool idle(float p_time) {
return false;
}
virtual void request_quit() {
-
+
quit=true;
-
+
}
virtual void init() {
quit=true;
}
virtual bool iteration(float p_time) {
-
+
return quit;
}
virtual void finish() {
-
+
}
-
-
+
+
};
diff --git a/bin/tests/test_main.cpp b/bin/tests/test_main.cpp
index 8143a95d66..363aede96e 100644
--- a/bin/tests/test_main.cpp
+++ b/bin/tests/test_main.cpp
@@ -64,7 +64,7 @@ const char ** tests_get_names() {
"physics",
NULL
};
-
+
return test_names;
}
@@ -72,22 +72,22 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
if (p_test=="string") {
-
+
return TestString::test();
}
-
+
if (p_test=="containers") {
-
+
return TestContainers::test();
}
-
+
if (p_test=="math") {
-
+
return TestMath::test();
}
-
+
if (p_test=="physics") {
-
+
return TestPhysics::test();
}
@@ -97,15 +97,15 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
}
if (p_test=="misc") {
-
+
return TestMisc::test();
}
if (p_test=="render") {
-
+
return TestRender::test();
}
-
+
#ifndef _3D_DISABLED
if (p_test=="gui") {
@@ -119,17 +119,17 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
}
if (p_test=="io") {
-
+
return TestIO::test();
}
-
+
if (p_test=="particles") {
return TestParticles::test();
}
-
+
if (p_test=="multimesh") {
-
+
return TestMultiMesh::test();
}
@@ -171,7 +171,7 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
#ifdef PYTHON_ENABLED
if (p_test=="python") {
-
+
return TestPython::test();
}
#endif
diff --git a/bin/tests/test_math.cpp b/bin/tests/test_math.cpp
index b5041b265f..22d14ada34 100644
--- a/bin/tests/test_math.cpp
+++ b/bin/tests/test_math.cpp
@@ -70,14 +70,95 @@ fix: 0, 0, 49.949951, 50
v0: 0, 0, 100, 100
v1: 0, 0, 100, 100
fix: 0, 0, 100, 100
-*/
+*/
}
+uint32_t ihash( uint32_t a)
+{
+ a = (a+0x7ed55d16) + (a<<12);
+ a = (a^0xc761c23c) ^ (a>>19);
+ a = (a+0x165667b1) + (a<<5);
+ a = (a+0xd3a2646c) ^ (a<<9);
+ a = (a+0xfd7046c5) + (a<<3);
+ a = (a^0xb55a4f09) ^ (a>>16);
+ return a;
+}
+
+uint32_t ihash2( uint32_t a) {
+ a = (a ^ 61) ^ (a >> 16);
+ a = a + (a << 3);
+ a = a ^ (a >> 4);
+ a = a * 0x27d4eb2d;
+ a = a ^ (a >> 15);
+ return a;
+}
+
+uint32_t ihash3( uint32_t a)
+{
+ a = (a+0x479ab41d) + (a<<8);
+ a = (a^0xe4aa10ce) ^ (a>>5);
+ a = (a+0x9942f0a6) - (a<<14);
+ a = (a^0x5aedd67d) ^ (a>>3);
+ a = (a+0x17bea992) + (a<<7);
+ return a;
+}
MainLoop* test() {
+
+ {
+
+ Vector<int32_t> hashes;
+ List<StringName> tl;
+ ObjectTypeDB::get_type_list(&tl);
+
+
+ for (List<StringName>::Element *E=tl.front();E;E=E->next()) {
+
+ Vector<uint8_t> m5b = E->get().operator String().md5_buffer();
+ uint32_t *ub = (uint32_t*)m5b.ptr();
+ //hashes.push_back(ihash(ihash2(ihash3(*ub))));
+ hashes.push_back(hashes.size());
+ //hashes.push_back(E->get().hash());
+
+ }
+
+ //hashes.resize(50);
+
+ for(int i=nearest_shift(hashes.size());i<20;i++) {
+
+ bool success=true;
+ for(int s=0;s<10000;s++) {
+ Set<uint32_t> existing;
+ success=true;
+
+ for(int j=0;j<hashes.size();j++) {
+
+ uint32_t eh = ihash2(ihash3(hashes[j]+ihash(s)+s))&((1<<i)-1);
+ if (existing.has(eh)) {
+ success=false;
+ break;
+ }
+ existing.insert(eh);
+ }
+
+ if (success) {
+ print_line("success at "+itos(i)+"/"+itos(nearest_shift(hashes.size()))+" shift "+itos(s));
+ break;
+ }
+ }
+ if (success)
+ break;
+ }
+
+ print_line("DONE");
+
+
+
+ return NULL;
+ }
{
diff --git a/bin/tests/test_particles.cpp b/bin/tests/test_particles.cpp
index bafd78eda0..23a4b9e635 100644
--- a/bin/tests/test_particles.cpp
+++ b/bin/tests/test_particles.cpp
@@ -43,38 +43,38 @@ class TestMainLoop : public MainLoop {
RID viewport;
RID light;
RID scenario;
-
+
struct InstanceInfo {
-
+
RID instance;
Transform base;
Vector3 rot_axis;
};
-
+
List<InstanceInfo> instances;
-
+
float ofs;
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
-
-
+
+
}
virtual void request_quit() {
-
+
quit=true;
}
virtual void init() {
-
+
VisualServer *vs=VisualServer::get_singleton();
particles = vs->particles_create();
vs->particles_set_amount(particles,1000);
-
+
instance = vs->instance_create2(particles,scenario);
-
-
+
+
camera = vs->camera_create();
-
+
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera );
@@ -89,7 +89,7 @@ public:
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
light = vs->instance_create2( lightaux, scenario );
-
+
ofs=0;
quit=false;
}
@@ -99,14 +99,14 @@ public:
virtual bool iteration(float p_time) {
-
+
// VisualServer *vs=VisualServer::get_singleton();
-
+
ofs+=p_time;
return quit;
}
virtual void finish() {
-
+
}
};
diff --git a/bin/tests/test_physics.cpp b/bin/tests/test_physics.cpp
index ce96f37f3f..ecd90a13d4 100644
--- a/bin/tests/test_physics.cpp
+++ b/bin/tests/test_physics.cpp
@@ -47,7 +47,7 @@ class TestPhysicsMainLoop : public MainLoop {
};
RID test_cube;
-
+
RID plane;
RID sphere;
RID light;
@@ -74,13 +74,13 @@ class TestPhysicsMainLoop : public MainLoop {
//t.basis.scale( Vector3(1.0,0.5,0.2) );
vs->instance_set_transform(p_visual_instance,t);
}
-
+
bool quit;
-
+
protected:
static void _bind_methods() {
-
+
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
}
@@ -90,11 +90,11 @@ protected:
PhysicsServer * ps = PhysicsServer::get_singleton();
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
- RID body = ps->body_create(p_body,!p_active_default);
+ RID body = ps->body_create(p_body,!p_active_default);
ps->body_set_space(body,space);
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
//todo set space
- ps->body_add_shape(body,type_shape_map[p_shape]);
+ ps->body_add_shape(body,type_shape_map[p_shape]);
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
@@ -289,7 +289,7 @@ protected:
public:
virtual void input_event(const InputEvent& p_event) {
-
+
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
ofs_y-=p_event.mouse_motion.relative_y/200.0;
@@ -329,7 +329,7 @@ public:
}
virtual void request_quit() {
-
+
quit=true;
}
virtual void init() {
@@ -388,53 +388,53 @@ public:
/* Make Trimesh */
quit=false;
return;
-
+
#if 0
#define GRID_SIZE 5
-
+
float grid[GRID_SIZE][GRID_SIZE];
-
+
for (int i=0;i<GRID_SIZE;i++) {
-
+
for (int j=0;j<GRID_SIZE;j++) {
-
+
grid[j][i]=Math::random(0.0, 1.0 );
}
}
-
+
Vector<Vector3> faces;
-
+
for (int i=1;i<GRID_SIZE;i++) {
-
+
for (int j=1;j<GRID_SIZE;j++) {
-
-
+
+
#define MAKE_VERTEX(m_x,m_z)\
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
-
+
MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i,j);
MAKE_VERTEX(i-1,j);
-
+
MAKE_VERTEX(i-1,j-1);
MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i-1,j);
-
+
}
}
/*
- faces.clear();
+ faces.clear();
faces.push_back( Vector3(0,0,-5) );
faces.push_back( Vector3(1,0,-1) );
faces.push_back( Vector3(-1,-0,-1) );
*/
-
+
RID trimesh_shape = ps->shape_create();
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
faces=ps->shape_get_shape(trimesh_shape, 0);
Vector<Vector3> normals; // for drawing
for (int i=0;i<faces.size()/3;i++) {
-
+
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
normals.push_back(p.normal);
normals.push_back(p.normal);
@@ -448,11 +448,11 @@ public:
RID trimesh_mat = vs->fixed_material_create();
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
-
+
RID triins = vs->instance_create2(trimesh_mesh);
-
-
-
+
+
+
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
@@ -483,7 +483,7 @@ public:
return quit;
}
virtual void finish() {
-
+
}
void test_joint() {
@@ -599,7 +599,7 @@ public:
PhysicsServer::ShapeType type=shape_idx[i%4];
//type=PhysicsServer::SHAPE_CONVEX_POLYGON;
- Transform t;
+ Transform t;
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);
diff --git a/bin/tests/test_python.cpp b/bin/tests/test_python.cpp
index 575caf2513..26fb4bdafb 100644
--- a/bin/tests/test_python.cpp
+++ b/bin/tests/test_python.cpp
@@ -47,7 +47,7 @@ void test() {
PyRun_SimpleString("b=Moch();\n");
PyRun_SimpleString("b.mooch();\n");
PyRun_SimpleString("b.meis();\n");
-
+
}
diff --git a/bin/tests/test_render.cpp b/bin/tests/test_render.cpp
index 568699e5e6..9c3a287afa 100644
--- a/bin/tests/test_render.cpp
+++ b/bin/tests/test_render.cpp
@@ -49,16 +49,16 @@ class TestMainLoop : public MainLoop {
RID viewport;
RID light;
RID scenario;
-
+
struct InstanceInfo {
-
+
RID instance;
Transform base;
Vector3 rot_axis;
};
-
+
List<InstanceInfo> instances;
-
+
float ofs;
bool quit;
protected:
@@ -66,13 +66,13 @@ protected:
public:
virtual void input_event(const InputEvent& p_event) {
-
+
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
quit=true;
}
virtual void init() {
-
+
print_line("INITIALIZING TEST RENDER");
VisualServer *vs=VisualServer::get_singleton();
@@ -150,26 +150,26 @@ public:
};
for (int i=0;i<object_count;i++) {
-
+
InstanceInfo ii;
-
-
+
+
ii.instance = vs->instance_create2( test_cube, scenario );
-
-
+
+
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
- vs->instance_set_transform( ii.instance, ii.base );
-
+ vs->instance_set_transform( ii.instance, ii.base );
+
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
-
+
instances.push_back(ii);
-
+
}
-
+
camera = vs->camera_create();
-
+
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
@@ -226,9 +226,9 @@ public:
ofs+=p_time*0.05;
//return quit;
-
+
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
-
+
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
vs->instance_set_transform( E->get().instance, pre * E->get().base );
/*
@@ -238,7 +238,7 @@ public:
instances.erase(E );
}*/
}
-
+
return quit;
}
diff --git a/bin/tests/test_shader_lang.cpp b/bin/tests/test_shader_lang.cpp
index e55ad3074f..9c0075c47d 100644
--- a/bin/tests/test_shader_lang.cpp
+++ b/bin/tests/test_shader_lang.cpp
@@ -290,7 +290,7 @@ MainLoop* test() {
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
- if (!fa) {
+ if (!fa) {
ERR_FAIL_V(NULL);
}
diff --git a/bin/tests/test_string.cpp b/bin/tests/test_string.cpp
index fe7bf4d9cf..be37ce118f 100644
--- a/bin/tests/test_string.cpp
+++ b/bin/tests/test_string.cpp
@@ -38,145 +38,145 @@
namespace TestString {
bool test_1() {
-
+
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
-
+
String s = "Hello";
-
+
OS::get_singleton()->print("\tExpected: Hello\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
-
+
return (wcscmp(s.c_str(),L"Hello")==0);
-
+
}
bool test_2() {
-
+
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
-
+
String s = "Dolly";
String t = s;
-
+
OS::get_singleton()->print("\tExpected: Dolly\n");
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
-
+
return (wcscmp(t.c_str(),L"Dolly")==0);
-
+
}
bool test_3() {
-
+
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
-
+
String s("Sheep");
String t(s);
-
+
OS::get_singleton()->print("\tExpected: Sheep\n");
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
-
+
return (wcscmp(t.c_str(),L"Sheep")==0);
-
+
}
bool test_4() {
-
+
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
-
+
String s(L"Give me");
-
+
OS::get_singleton()->print("\tExpected: Give me\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
-
+
return (wcscmp(s.c_str(),L"Give me")==0);
-
+
}
bool test_5() {
-
+
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
-
+
String s(L"Wool");
-
+
OS::get_singleton()->print("\tExpected: Wool\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
-
+
return (wcscmp(s.c_str(),L"Wool")==0);
-
+
}
bool test_6() {
-
+
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
-
-
+
+
String s="Test Compare";
-
+
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
-
+
if (! ( s=="Test Compare" ) )
return false;
-
+
if (! ( s==L"Test Compare" ) )
return false;
-
+
if (! ( s==String("Test Compare") ) )
return false;
-
+
return true;
-
+
}
bool test_7() {
-
+
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
-
-
+
+
String s="Test Compare";
-
+
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
-
+
if (! ( s!="Peanut" ) )
return false;
-
+
if (! ( s!=L"Coconut" ) )
return false;
-
+
if (! ( s!=String("Butter") ) )
return false;
-
+
return true;
-
+
}
bool test_8() {
-
+
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
-
-
+
+
String s="Bees";
-
+
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
-
+
if ( ! (s < "Elephant") )
return false;
-
+
if ( s < L"Amber" )
return false;
-
+
if ( s < String("Beatrix") )
return false;
-
+
return true;
-
+
}
bool test_9() {
-
+
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
-
-
+
+
String s;
-
+
s+="Have";
s+=' ';
s+='a';
@@ -184,279 +184,279 @@ bool test_9() {
s = s + L"Nice";
s = s + " ";
s = s + String("Day");
-
+
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
-
+
return (s == "Have a Nice Day");
-
+
}
bool test_10() {
-
+
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
-
+
if (! String("").empty())
return false;
-
+
if (String("Mellon").size() != 7)
return false;
if (String("Oranges").length() != 7)
return false;
-
+
return true;
-
+
}
bool test_11() {
-
+
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
-
+
String a="Kugar Sane";
-
+
a[0]='S';
a[6]='C';
-
+
if (a != "Sugar Cane")
return false;
-
+
if (a[1]!='u')
return false;
-
+
return true;
-
+
}
bool test_12() {
-
+
OS::get_singleton()->print("\n\nTest 12: case functions\n");
-
-
+
+
String a="MoMoNgA";
-
+
if (a.to_upper() != "MOMONGA")
return false;
-
+
if (a.nocasecmp_to("momonga")!=0)
return false;
-
+
return true;
-
+
}
bool test_13() {
-
+
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
-
+
/* how can i embed UTF in here? */
-
+
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
String s=ustr;
-
+
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
s.parse_utf8( s.utf8().get_data() );
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
-
+
return (s==ustr);
-
+
}
bool test_14() {
-
+
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
-
+
String s = L"Primero Leche";
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
-
+
String t=s.ascii().get_data();
return (s==t);
-
+
}
bool test_15() {
-
+
OS::get_singleton()->print("\n\nTest 15: substr\n");
-
+
String s="Killer Baby";
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
-
+
return (s.substr(3,4)=="ler ");
-
+
}
bool test_16() {
-
+
OS::get_singleton()->print("\n\nTest 16: find\n");
-
+
String s="Pretty Woman";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
-
+
if (s.find("tty")!=3)
return false;
-
+
if (s.find("Revenge of the Monster Truck")!=-1)
return false;
-
+
return true;
-
+
}
bool test_17() {
-
+
OS::get_singleton()->print("\n\nTest 17: find no case\n");
-
+
String s="Pretty Whale";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
-
+
if (s.findn("WHA")!=7)
return false;
-
+
if (s.findn("Revenge of the Monster SawFish")!=-1)
return false;
-
+
return true;
-
+
}
bool test_18() {
-
+
OS::get_singleton()->print("\n\nTest 18: find no case\n");
-
+
String s="Pretty Whale";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
-
+
if (s.findn("WHA")!=7)
return false;
-
+
if (s.findn("Revenge of the Monster SawFish")!=-1)
return false;
-
+
return true;
-
+
}
bool test_19() {
-
+
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
-
+
String s="Happy Birthday, Anna!";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
-
+
s=s.replace("Birthday","Halloween");
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
-
+
return (s=="Happy Halloween, Anna!");
-
+
}
bool test_20() {
-
+
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
-
+
String s="Who is Frederic?";
-
+
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
s=s.insert( s.find("?")," Chopin" );
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
-
+
return (s=="Who is Frederic Chopin?");
-
+
}
bool test_21() {
-
+
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
-
+
OS::get_singleton()->print("\tPi is %f\n",33.141593);
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
-
+
return String::num(3.141593)=="3.141593";
-
+
}
bool test_22() {
-
+
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
-
+
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
static const int num[4]={ 1237461283, -22, 0, -1123412 };
-
+
for (int i=0;i<4;i++) {
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
-
+
if (String(nums[i]).to_int()!=num[i])
return false;
}
-
+
return true;
-
+
}
bool test_23() {
-
+
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
-
+
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
-
+
for (int i=0;i<4;i++) {
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
-
+
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
return false;
}
-
+
return true;
-
+
}
bool test_24() {
-
+
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
-
+
String s="Mars,Jupiter,Saturn,Uranus";
-
+
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
-
+
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
-
+
for (int i=0;i<s.get_slice_count(",");i++) {
-
+
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
-
-
+
+
if (s.get_slice(",",i)!=slices[i])
return false;
}
-
+
return true;
-
+
}
bool test_25() {
-
+
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
-
+
String s="Josephine is such a cute girl!";
-
+
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\tRemoving \"cute\"\n");
-
+
s.erase(s.find("cute "),String("cute ").length());
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
-
-
+
+
return (s=="Josephine is such a girl!");
-
+
}
bool test_26() {
@@ -472,7 +472,7 @@ bool test_26() {
{
printf("%ls\n", regexp.get_capture(i).c_str());
}
- return res;
+ return (res>=0);
};
struct test_27_data {
@@ -516,7 +516,7 @@ bool test_28() {
String format, output;
Array args;
bool error;
-
+
// %%
format = "fish %% frog";
args.clear();
@@ -846,7 +846,7 @@ bool test_28() {
typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = {
-
+
test_1,
test_2,
test_3,
@@ -876,18 +876,18 @@ TestFunc test_funcs[] = {
test_27,
test_28,
0
-
+
};
MainLoop* test() {
-
+
/** A character length != wchar_t may be forced, so the tests wont work */
-
+
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
-
+
int count=0;
int passed=0;
-
+
while(true) {
if (!test_funcs[count])
break;
@@ -895,17 +895,17 @@ MainLoop* test() {
if (pass)
passed++;
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
-
+
count++;
}
-
+
OS::get_singleton()->print("\n\n\n");
OS::get_singleton()->print("*************\n");
OS::get_singleton()->print("***TOTALS!***\n");
OS::get_singleton()->print("*************\n");
-
- OS::get_singleton()->print("Passed %i of %i tests\n",count,passed);
-
+
+ OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
+
return NULL;
}
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 94d9e22a1e..915cbc0578 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -6,6 +6,15 @@
#include "core/globals.h"
#include "io/file_access_encrypted.h"
#include "os/keyboard.h"
+
+/**
+ * Time constants borrowed from loc_time.h
+ */
+#define EPOCH_YR 1970 /* EPOCH = Jan 1 1970 00:00:00 */
+#define SECS_DAY (24L * 60L * 60L)
+#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
+#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
+
_ResourceLoader *_ResourceLoader::singleton=NULL;
Ref<ResourceInteractiveLoader> _ResourceLoader::load_interactive(const String& p_path,const String& p_type_hint) {
@@ -55,11 +64,17 @@ bool _ResourceLoader::has(const String &p_path) {
return ResourceCache::has(local_path);
};
+Ref<ResourceImportMetadata> _ResourceLoader::load_import_metadata(const String& p_path) {
+
+ return ResourceLoader::load_import_metadata(p_path);
+}
+
void _ResourceLoader::_bind_methods() {
ObjectTypeDB::bind_method(_MD("load_interactive:ResourceInteractiveLoader","path","type_hint"),&_ResourceLoader::load_interactive,DEFVAL(""));
ObjectTypeDB::bind_method(_MD("load:Resource","path","type_hint", "p_no_cache"),&_ResourceLoader::load,DEFVAL(""), DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("load_import_metadata:ResourceImportMetadata","path"),&_ResourceLoader::load_import_metadata);
ObjectTypeDB::bind_method(_MD("get_recognized_extensions_for_type","type"),&_ResourceLoader::get_recognized_extensions_for_type);
ObjectTypeDB::bind_method(_MD("set_abort_on_missing_resources","abort"),&_ResourceLoader::set_abort_on_missing_resources);
ObjectTypeDB::bind_method(_MD("get_dependencies","path"),&_ResourceLoader::get_dependencies);
@@ -245,6 +260,13 @@ bool _OS::is_window_maximized() const {
return OS::get_singleton()->is_window_maximized();
}
+void _OS::set_borderless_window(bool p_borderless) {
+ OS::get_singleton()->set_borderless_window(p_borderless);
+}
+
+bool _OS::get_borderless_window() const {
+ return OS::get_singleton()->get_borderless_window();
+}
void _OS::set_use_file_access_save_and_swap(bool p_enable) {
@@ -390,6 +412,12 @@ bool _OS::is_ok_left_and_cancel_right() const {
return OS::get_singleton()->get_swap_ok_cancel();
}
+Error _OS::set_thread_name(const String& p_name) {
+
+ return Thread::set_name(p_name);
+};
+
+
/*
enum Weekday {
DAY_SUNDAY,
@@ -467,9 +495,8 @@ Dictionary _OS::get_date(bool utc) const {
dated["weekday"]=date.weekday;
dated["dst"]=date.dst;
return dated;
-
-
}
+
Dictionary _OS::get_time(bool utc) const {
OS::Time time = OS::get_singleton()->get_time(utc);
@@ -478,7 +505,68 @@ Dictionary _OS::get_time(bool utc) const {
timed["minute"]=time.min;
timed["second"]=time.sec;
return timed;
+}
+
+/**
+ * Get a dictionary of time values when given epoch time
+ *
+ * Dictionary Time values will be a union if values from #get_time
+ * and #get_date dictionaries (with the exception of dst =
+ * day light standard time, as it cannot be determined from epoch)
+ */
+Dictionary _OS::get_time_from_unix_time( uint64_t unix_time_val) const {
+
+ OS::Date date;
+ OS::Time time;
+
+ unsigned long dayclock, dayno;
+ int year = EPOCH_YR;
+
+ dayclock = (unsigned long)unix_time_val % SECS_DAY;
+ dayno = (unsigned long)unix_time_val / SECS_DAY;
+
+ time.sec = dayclock % 60;
+ time.min = (dayclock % 3600) / 60;
+ time.hour = dayclock / 3600;
+
+ /* day 0 was a thursday */
+ date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7);
+ while (dayno >= YEARSIZE(year)) {
+ dayno -= YEARSIZE(year);
+ year++;
+ }
+
+ date.year = year;
+
+ // Table of number of days in each month (for regular year and leap year)
+ const unsigned int _ytab[2][12] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+ };
+
+ size_t imonth = 0;
+
+ while (dayno >= _ytab[LEAPYEAR(year)][imonth]) {
+ dayno -= _ytab[LEAPYEAR(year)][imonth];
+ imonth++;
+ }
+
+ /// Add 1 to month to make sure months are indexed starting at 1
+ date.month = static_cast<OS::Month>(imonth+1);
+
+ date.day = dayno + 1;
+
+ Dictionary timed;
+ timed["hour"]=time.hour;
+ timed["minute"]=time.min;
+ timed["second"]=time.sec;
+ timed["year"]=date.year;
+ timed["month"]=date.month;
+ timed["day"]=date.day;
+ timed["weekday"]=date.weekday;
+
+ return timed;
}
Dictionary _OS::get_time_zone_info() const {
@@ -683,6 +771,10 @@ void _OS::native_video_pause() {
OS::get_singleton()->native_video_pause();
};
+void _OS::native_video_unpause() {
+ OS::get_singleton()->native_video_unpause();
+};
+
void _OS::native_video_stop() {
OS::get_singleton()->native_video_stop();
@@ -781,6 +873,9 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_window_maximized", "enabled"),&_OS::set_window_maximized);
ObjectTypeDB::bind_method(_MD("is_window_maximized"),&_OS::is_window_maximized);
+ ObjectTypeDB::bind_method(_MD("set_borderless_window", "borderless"), &_OS::set_borderless_window);
+ ObjectTypeDB::bind_method(_MD("get_borderless_window"), &_OS::get_borderless_window);
+
ObjectTypeDB::bind_method(_MD("set_screen_orientation","orientation"),&_OS::set_screen_orientation);
ObjectTypeDB::bind_method(_MD("get_screen_orientation"),&_OS::get_screen_orientation);
@@ -821,6 +916,8 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_time","utc"),&_OS::get_time,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_time_zone_info"),&_OS::get_time_zone_info);
ObjectTypeDB::bind_method(_MD("get_unix_time"),&_OS::get_unix_time);
+ ObjectTypeDB::bind_method(_MD("get_time_from_unix_time", "unix_time_val"),
+ &_OS::get_time_from_unix_time);
ObjectTypeDB::bind_method(_MD("get_system_time_secs"), &_OS::get_system_time_secs);
ObjectTypeDB::bind_method(_MD("set_icon","icon"),&_OS::set_icon);
@@ -868,6 +965,7 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("native_video_is_playing"),&_OS::native_video_is_playing);
ObjectTypeDB::bind_method(_MD("native_video_stop"),&_OS::native_video_stop);
ObjectTypeDB::bind_method(_MD("native_video_pause"),&_OS::native_video_pause);
+ ObjectTypeDB::bind_method(_MD("native_video_unpause"),&_OS::native_video_unpause);
ObjectTypeDB::bind_method(_MD("get_scancode_string","code"),&_OS::get_scancode_string);
ObjectTypeDB::bind_method(_MD("is_scancode_unicode","code"),&_OS::is_scancode_unicode);
@@ -877,6 +975,8 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("alert","text","title"),&_OS::alert,DEFVAL("Alert!"));
+ ObjectTypeDB::bind_method(_MD("set_thread_name","name"),&_OS::set_thread_name);
+
BIND_CONSTANT( DAY_SUNDAY );
BIND_CONSTANT( DAY_MONDAY );
@@ -1306,6 +1406,15 @@ String _File::get_as_text() const {
}
+
+
+String _File::get_md5(const String& p_path) const {
+
+ return FileAccess::get_md5(p_path);
+
+}
+
+
String _File::get_line() const{
ERR_FAIL_COND_V(!f,String());
@@ -1313,9 +1422,9 @@ String _File::get_line() const{
}
-Vector<String> _File::get_csv_line() const {
+Vector<String> _File::get_csv_line(String delim) const {
ERR_FAIL_COND_V(!f,Vector<String>());
- return f->get_csv_line();
+ return f->get_csv_line(delim);
}
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
@@ -1494,11 +1603,12 @@ void _File::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_buffer","len"),&_File::get_buffer);
ObjectTypeDB::bind_method(_MD("get_line"),&_File::get_line);
ObjectTypeDB::bind_method(_MD("get_as_text"),&_File::get_as_text);
+ ObjectTypeDB::bind_method(_MD("get_md5","path"),&_File::get_md5);
ObjectTypeDB::bind_method(_MD("get_endian_swap"),&_File::get_endian_swap);
ObjectTypeDB::bind_method(_MD("set_endian_swap","enable"),&_File::set_endian_swap);
ObjectTypeDB::bind_method(_MD("get_error:Error"),&_File::get_error);
ObjectTypeDB::bind_method(_MD("get_var"),&_File::get_var);
- ObjectTypeDB::bind_method(_MD("get_csv_line"),&_File::get_csv_line);
+ ObjectTypeDB::bind_method(_MD("get_csv_line","delim"),&_File::get_csv_line,DEFVAL(","));
ObjectTypeDB::bind_method(_MD("store_8","value"),&_File::store_8);
ObjectTypeDB::bind_method(_MD("store_16","value"),&_File::store_16);
@@ -1895,13 +2005,7 @@ void _Thread::_start_func(void *ud) {
Variant::CallError ce;
const Variant* arg[1]={&t->userdata};
- // we don't know our thread pointer yet :(
- if (t->name == "") {
- // come up with a better name using maybe the filename on the Script?
- //t->thread->set_name(t->target_method);
- } else {
- //t->thread->set_name(t->name);
- };
+ Thread::set_name(t->target_method);
t->ret=t->target_instance->call(t->target_method,arg,1,ce);
if (ce.error!=Variant::CallError::CALL_OK) {
@@ -1972,7 +2076,6 @@ String _Thread::get_id() const {
return itos(thread->get_ID());
}
-
bool _Thread::is_active() const {
return active;
@@ -1992,24 +2095,12 @@ Variant _Thread::wait_to_finish() {
return r;
}
-Error _Thread::set_name(const String &p_name) {
-
- name = p_name;
-
- if (thread) {
- return thread->set_name(p_name);
- };
-
- return OK;
-};
-
void _Thread::_bind_methods() {
ObjectTypeDB::bind_method(_MD("start:Error","instance","method","userdata","priority"),&_Thread::start,DEFVAL(Variant()),DEFVAL(PRIORITY_NORMAL));
ObjectTypeDB::bind_method(_MD("get_id"),&_Thread::get_id);
ObjectTypeDB::bind_method(_MD("is_active"),&_Thread::is_active);
ObjectTypeDB::bind_method(_MD("wait_to_finish:Variant"),&_Thread::wait_to_finish);
- ObjectTypeDB::bind_method(_MD("set_name:Error", "name"),&_Thread::set_name);
BIND_CONSTANT( PRIORITY_LOW );
BIND_CONSTANT( PRIORITY_NORMAL );
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index e03657f3a0..db5ff42cfe 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -26,6 +26,7 @@ public:
void set_abort_on_missing_resources(bool p_abort);
StringArray get_dependencies(const String& p_path);
bool has(const String& p_path);
+ Ref<ResourceImportMetadata> load_import_metadata(const String& p_path);
_ResourceLoader();
};
@@ -80,7 +81,9 @@ public:
};
enum Month {
- MONTH_JANUARY,
+ /// Start at 1 to follow Windows SYSTEMTIME structure
+ /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
+ MONTH_JANUARY = 1,
MONTH_FEBRUARY,
MONTH_MARCH,
MONTH_APRIL,
@@ -127,10 +130,13 @@ public:
virtual void set_window_maximized(bool p_enabled);
virtual bool is_window_maximized() const;
+ virtual void set_borderless_window(bool p_borderless);
+ virtual bool get_borderless_window() const;
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing();
void native_video_pause();
+ void native_video_unpause();
void native_video_stop();
void set_iterations_per_second(int p_ips);
@@ -206,6 +212,7 @@ public:
void set_icon(const Image& p_icon);
Dictionary get_date(bool utc) const;
Dictionary get_time(bool utc) const;
+ Dictionary get_time_from_unix_time(uint64_t unix_time_val) const;
Dictionary get_time_zone_info() const;
uint64_t get_unix_time() const;
uint64_t get_system_time_secs() const;
@@ -270,6 +277,8 @@ public:
bool is_ok_left_and_cancel_right() const;
+ Error set_thread_name(const String& p_name);
+
static _OS *get_singleton() { return singleton; }
_OS();
@@ -364,6 +373,7 @@ public:
DVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
String get_line() const;
String get_as_text() const;
+ String get_md5(const String& p_path) const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
@@ -390,7 +400,7 @@ public:
virtual void store_pascal_string(const String& p_string);
virtual String get_pascal_string();
- Vector<String> get_csv_line() const;
+ Vector<String> get_csv_line(String delim=",") const;
void store_buffer(const DVector<uint8_t>& p_buffer); ///< store an array of bytes
@@ -512,7 +522,6 @@ protected:
Object *target_instance;
StringName target_method;
Thread *thread;
- String name;
static void _bind_methods();
static void _start_func(void *ud);
public:
@@ -528,7 +537,6 @@ public:
String get_id() const;
bool is_active() const;
Variant wait_to_finish();
- Error set_name(const String& p_name);
_Thread();
~_Thread();
diff --git a/core/color.cpp b/core/color.cpp
index c53de360bc..bf9c94462f 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -75,11 +75,11 @@ float Color::get_h() const {
h = 2 + ( b - r ) / delta; // between cyan & yellow
else
h = 4 + ( r - g ) / delta; // between magenta & cyan
-
+
h/=6.0;
if (h<0)
h+=1.0;
-
+
return h;
}
@@ -117,19 +117,21 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
}
p_h *=6.0;
+ p_h = Math::fmod(p_h,6);
i = Math::floor( p_h );
+
f = p_h - i;
p = p_v * ( 1 - p_s );
q = p_v * ( 1 - p_s * f );
t = p_v * ( 1 - p_s * ( 1 - f ) );
switch( i ) {
- case 0:
+ case 0: // Red is the dominant color
r = p_v;
g = t;
b = p;
break;
- case 1:
+ case 1: // Green is the dominant color
r = q;
g = p_v;
b = p;
@@ -139,7 +141,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
g = p_v;
b = t;
break;
- case 3:
+ case 3: // Blue is the dominant color
r = p;
g = q;
b = p_v;
@@ -149,7 +151,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
g = p;
b = p_v;
break;
- default: // cap_se 5:
+ default: // (5) Red is the dominant color
r = p_v;
g = p;
b = q;
@@ -160,8 +162,8 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
void Color::invert() {
r=1.0-r;
- g=1.0-g;
- b=1.0-b;
+ g=1.0-g;
+ b=1.0-b;
}
void Color::contrast() {
@@ -366,7 +368,7 @@ String Color::to_html(bool p_alpha) const {
float Color::gray() const {
- return (r+g+b)/3.0;
+ return (r+g+b)/3.0;
}
Color::operator String() const {
diff --git a/core/color.h b/core/color.h
index d0a1e8835c..5b671d5f62 100644
--- a/core/color.h
+++ b/core/color.h
@@ -37,13 +37,13 @@
struct Color {
union {
-
+
struct {
float r;
float g;
float b;
float a;
- };
+ };
float components[4];
};
@@ -58,28 +58,28 @@ struct Color {
float get_v() const;
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
- _FORCE_INLINE_ float& operator[](int idx) {
+ _FORCE_INLINE_ float& operator[](int idx) {
return components[idx];
}
- _FORCE_INLINE_ const float& operator[](int idx) const {
+ _FORCE_INLINE_ const float& operator[](int idx) const {
return components[idx];
}
-
+
void invert();
void contrast();
Color inverted() const;
Color contrasted() const;
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
-
+
Color res=*this;
-
+
res.r+= (p_t * (p_b.r-r));
res.g+= (p_t * (p_b.g-g));
res.b+= (p_t * (p_b.b-b));
res.a+= (p_t * (p_b.a-a));
-
- return res;
+
+ return res;
}
_FORCE_INLINE_ Color blend(const Color& p_over) const {
diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp
index a2507b1378..acd3aeddfb 100644
--- a/core/command_queue_mt.cpp
+++ b/core/command_queue_mt.cpp
@@ -76,7 +76,7 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
CommandQueueMT::CommandQueueMT(bool p_sync){
read_ptr=0;
- write_ptr=0;
+ write_ptr=0;
mutex = Mutex::create();
for(int i=0;i<SYNC_SEMAPHORES;i++) {
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 142668f6f6..b1e0066c35 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -47,69 +47,69 @@ class CommandQueueMT {
};
struct CommandBase {
-
+
virtual void call()=0;
virtual ~CommandBase() {};
};
-
+
template<class T,class M>
struct Command0 : public CommandBase {
T*instance;
M method;
-
+
virtual void call() { (instance->*method)(); }
};
-
+
template<class T,class M,class P1>
struct Command1 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
-
+
virtual void call() { (instance->*method)(p1); }
};
-
+
template<class T,class M,class P1,class P2>
struct Command2 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2;
-
+
virtual void call() { (instance->*method)(p1,p2); }
};
template<class T,class M,class P1,class P2,class P3>
struct Command3 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2;
typename GetSimpleTypeT<P3>::type_t p3;
-
+
virtual void call() { (instance->*method)(p1,p2,p3); }
};
template<class T,class M,class P1,class P2,class P3,class P4>
struct Command4 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2;
typename GetSimpleTypeT<P3>::type_t p3;
typename GetSimpleTypeT<P4>::type_t p4;
-
+
virtual void call() { (instance->*method)(p1,p2,p3,p4); }
};
template<class T,class M,class P1,class P2,class P3,class P4,class P5>
struct Command5 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -117,13 +117,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P3>::type_t p3;
typename GetSimpleTypeT<P4>::type_t p4;
typename GetSimpleTypeT<P5>::type_t p5;
-
+
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); }
};
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6>
struct Command6 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -132,13 +132,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P4>::type_t p4;
typename GetSimpleTypeT<P5>::type_t p5;
typename GetSimpleTypeT<P6>::type_t p6;
-
+
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); }
};
-
+
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7>
struct Command7 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -148,12 +148,12 @@ class CommandQueueMT {
typename GetSimpleTypeT<P5>::type_t p5;
typename GetSimpleTypeT<P6>::type_t p6;
typename GetSimpleTypeT<P7>::type_t p7;
-
+
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
};
-
+
/* comands that return */
-
+
template<class T,class M,class R>
struct CommandRet0 : public CommandBase {
@@ -161,38 +161,38 @@ class CommandQueueMT {
M method;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; }
};
-
+
template<class T,class M,class P1,class R>
struct CommandRet1 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; }
};
-
+
template<class T,class M,class P1,class P2,class R>
struct CommandRet2 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=false; ; }
};
template<class T,class M,class P1,class P2,class P3,class R>
struct CommandRet3 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -200,13 +200,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P3>::type_t p3;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=false; ; }
};
template<class T,class M,class P1,class P2,class P3,class P4,class R>
struct CommandRet4 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -215,13 +215,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P4>::type_t p4;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=false; ; }
};
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class R>
struct CommandRet5 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -231,13 +231,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P5>::type_t p5;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=false; ; }
};
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class R>
struct CommandRet6 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -248,13 +248,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P6>::type_t p6;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=false; ; }
- };
+ };
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class R>
struct CommandRet7 : public CommandBase {
-
+
T*instance;
M method;
typename GetSimpleTypeT<P1>::type_t p1;
@@ -266,9 +266,9 @@ class CommandQueueMT {
typename GetSimpleTypeT<P7>::type_t p7;
R* ret;
SyncSemaphore *sync;
-
+
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; }
- };
+ };
/** commands that don't return but sync */
@@ -392,7 +392,7 @@ class CommandQueueMT {
/***** BASE *******/
- enum {
+ enum {
COMMAND_MEM_SIZE_KB=256,
COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
SYNC_SEMAPHORES=8
@@ -405,30 +405,30 @@ class CommandQueueMT {
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
Mutex *mutex;
Semaphore *sync;
-
-
+
+
template<class T>
T* allocate() {
-
+
// alloc size is size+T+safeguard
uint32_t alloc_size=sizeof(T)+sizeof(uint32_t);
-
+
tryagain:
-
+
if (write_ptr < read_ptr) {
// behind read_ptr, check that there is room
if ( (read_ptr-write_ptr) <= alloc_size )
return NULL;
} else if (write_ptr >= read_ptr) {
// ahead of read_ptr, check that there is room
-
-
+
+
if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
// no room at the end, wrap down;
-
+
if (read_ptr==0) // dont want write_ptr to become read_ptr
return NULL;
-
+
// if this happens, it's a bug
ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL );
// zero means, wrap to begining
@@ -447,147 +447,147 @@ class CommandQueueMT {
T* cmd = memnew_placement( &command_mem[write_ptr], T );
write_ptr+=sizeof(T);
return cmd;
-
+
}
-
+
template<class T>
T* allocate_and_lock() {
-
+
lock();
T* ret;
-
+
while ( (ret=allocate<T>())==NULL ) {
-
+
unlock();
- // sleep a little until fetch happened and some room is made
+ // sleep a little until fetch happened and some room is made
wait_for_flush();
lock();
-
+
}
-
+
return ret;
}
-
-
+
+
bool flush_one() {
-
+
tryagain:
-
+
// tried to read an empty queue
if (read_ptr == write_ptr )
return false;
-
+
uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
-
+
if (size==0) {
//end of ringbuffer, wrap
read_ptr=0;
goto tryagain;
}
-
+
read_ptr+=sizeof(uint32_t);
-
+
CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] );
-
+
cmd->call();
cmd->~CommandBase();
-
- read_ptr+=size;
+
+ read_ptr+=size;
return true;
}
-
-
+
+
void lock();
void unlock();
void wait_for_flush();
SyncSemaphore* _alloc_sync_sem();
-
-
+
+
public:
/* NORMAL PUSH COMMANDS */
-
+
template<class T, class M>
void push( T * p_instance, M p_method ) {
-
+
Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1>
void push( T * p_instance, M p_method, P1 p1 ) {
-
+
Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1, class P2>
void push( T * p_instance, M p_method, P1 p1, P2 p2 ) {
-
+
Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
cmd->p2=p2;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1, class P2, class P3>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
-
+
Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
cmd->p2=p2;
cmd->p3=p3;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1, class P2, class P3, class P4>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
-
+
Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
cmd->p2=p2;
cmd->p3=p3;
cmd->p4=p4;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1, class P2, class P3, class P4, class P5>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
-
+
Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -595,17 +595,17 @@ public:
cmd->p3=p3;
cmd->p4=p4;
cmd->p5=p5;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
-
+
Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -614,17 +614,17 @@ public:
cmd->p4=p4;
cmd->p5=p5;
cmd->p6=p6;
-
+
unlock();
-
+
if (sync) sync->post();
}
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) {
-
+
Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -634,19 +634,19 @@ public:
cmd->p5=p5;
cmd->p6=p6;
cmd->p7=p7;
-
+
unlock();
-
+
if (sync) sync->post();
}
/*** PUSH AND RET COMMANDS ***/
-
-
+
+
template<class T, class M,class R>
void push_and_ret( T * p_instance, M p_method, R* r_ret) {
-
+
CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->ret=r_ret;
@@ -654,34 +654,34 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
template<class T, class M, class P1,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) {
-
+
CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
cmd->ret=r_ret;
SyncSemaphore *ss=_alloc_sync_sem();
cmd->sync=ss;
-
+
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
template<class T, class M, class P1, class P2,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) {
-
+
CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -691,16 +691,16 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
template<class T, class M, class P1, class P2, class P3,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) {
-
+
CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -711,16 +711,16 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
template<class T, class M, class P1, class P2, class P3, class P4,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) {
-
+
CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -732,16 +732,16 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
template<class T, class M, class P1, class P2, class P3, class P4, class P5,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) {
-
+
CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -754,16 +754,16 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) {
-
+
CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -777,16 +777,16 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
-
+
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) {
-
+
CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >();
-
+
cmd->instance=p_instance;
cmd->method=p_method;
cmd->p1=p1;
@@ -801,7 +801,7 @@ public:
cmd->sync=ss;
unlock();
-
+
if (sync) sync->post();
ss->sem->wait();
}
@@ -975,12 +975,12 @@ public:
ERR_FAIL_COND(!sync);
sync->wait();
lock();
- flush_one();
+ flush_one();
unlock();
}
-
+
void flush_all() {
-
+
//ERR_FAIL_COND(sync);
lock();
while (true) {
@@ -990,10 +990,10 @@ public:
}
unlock();
}
-
+
CommandQueueMT(bool p_sync);
~CommandQueueMT();
-
+
};
#endif
diff --git a/core/dvector.h b/core/dvector.h
index 17431b33a6..fbb1fc4824 100644
--- a/core/dvector.h
+++ b/core/dvector.h
@@ -43,18 +43,18 @@ template<class T>
class DVector {
mutable MID mem;
-
-
+
+
void copy_on_write() {
-
+
if (!mem.is_valid())
return;
if (dvector_lock)
dvector_lock->lock();
-
+
MID_Lock lock( mem );
-
+
if ( *(int*)lock.data() == 1 ) {
// one reference, means no refcount changes
@@ -62,114 +62,114 @@ class DVector {
dvector_lock->unlock();
return;
}
-
+
MID new_mem= dynalloc( mem.get_size() );
-
+
if (!new_mem.is_valid()) {
-
+
if (dvector_lock)
dvector_lock->unlock();
- ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
+ ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
}
-
+
MID_Lock dst_lock( new_mem );
-
+
int *rc = (int*)dst_lock.data();
-
+
*rc=1;
-
+
T * dst = (T*)(rc + 1 );
-
+
T * src =(T*) ((int*)lock.data() + 1 );
-
+
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
-
+
for (int i=0;i<count;i++) {
-
+
memnew_placement( &dst[i], T(src[i]) );
}
-
+
(*(int*)lock.data())--;
-
+
// unlock all
dst_lock=MID_Lock();
lock=MID_Lock();
-
+
mem=new_mem;
-
+
if (dvector_lock)
dvector_lock->unlock();
-
+
}
-
+
void reference( const DVector& p_dvector ) {
-
+
unreference();
-
+
if (dvector_lock)
dvector_lock->lock();
-
+
if (!p_dvector.mem.is_valid()) {
-
+
if (dvector_lock)
dvector_lock->unlock();
- return;
+ return;
}
-
+
MID_Lock lock(p_dvector.mem);
-
+
int * rc = (int*)lock.data();
(*rc)++;
-
+
lock = MID_Lock();
mem=p_dvector.mem;
-
+
if (dvector_lock)
dvector_lock->unlock();
-
+
}
-
-
+
+
void unreference() {
-
+
if (dvector_lock)
dvector_lock->lock();
-
+
if (!mem.is_valid()) {
-
+
if (dvector_lock)
dvector_lock->unlock();
- return;
+ return;
}
-
+
MID_Lock lock(mem);
-
+
int * rc = (int*)lock.data();
(*rc)--;
-
+
if (*rc==0) {
// no one else using it, destruct
-
+
T * t= (T*)(rc+1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
-
+
for (int i=0;i<count;i++) {
-
+
t[i].~T();
}
-
+
}
-
-
+
+
lock = MID_Lock();
-
+
mem = MID ();
-
+
if (dvector_lock)
dvector_lock->unlock();
-
+
}
-
+
public:
class Read {
@@ -177,10 +177,10 @@ public:
MID_Lock lock;
const T * mem;
public:
-
+
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
_FORCE_INLINE_ const T *ptr() const { return mem; }
-
+
Read() { mem=NULL; }
};
@@ -189,32 +189,32 @@ public:
MID_Lock lock;
T * mem;
public:
-
+
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
_FORCE_INLINE_ T *ptr() { return mem; }
-
+
Write() { mem=NULL; }
};
Read read() const {
-
+
Read r;
- if (mem.is_valid()) {
+ if (mem.is_valid()) {
r.lock = MID_Lock( mem );
r.mem = (const T*)((int*)r.lock.data()+1);
}
- return r;
+ return r;
}
Write write() {
-
+
Write w;
if (mem.is_valid()) {
copy_on_write();
w.lock = MID_Lock( mem );
w.mem = (T*)((int*)w.lock.data()+1);
}
- return w;
+ return w;
}
template<class MC>
@@ -280,12 +280,12 @@ public:
bool is_locked() const { return mem.is_locked(); }
-
+
inline const T operator[](int p_index) const;
Error resize(int p_size);
-
-
+
+
void operator=(const DVector& p_dvector) { reference(p_dvector); }
DVector() {}
DVector(const DVector& p_dvector) { reference(p_dvector); }
@@ -308,7 +308,7 @@ T DVector<T>::get(int p_index) const {
template<class T>
void DVector<T>::set(int p_index, const T& p_val) {
- if (p_index<0 || p_index>=size()) {
+ if (p_index<0 || p_index>=size()) {
ERR_FAIL_COND(p_index<0 || p_index>=size());
}
@@ -332,7 +332,7 @@ const T DVector<T>::operator[](int p_index) const {
}
Read r = read();
-
+
return r[p_index];
}
@@ -344,83 +344,83 @@ Error DVector<T>::resize(int p_size) {
dvector_lock->lock();
bool same = p_size==size();
-
+
if (dvector_lock)
dvector_lock->unlock();
- // no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
-
+ // no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
+
if (same)
return OK;
if (p_size == 0 ) {
-
+
unreference();
return OK;
}
copy_on_write(); // make it unique
-
+
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
-
+
if (p_size > size() ) {
-
+
int oldsize=size();
-
+
MID_Lock lock;
-
+
if (oldsize==0) {
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
lock=MID_Lock(mem);
int *rc = ((int*)lock.data());
*rc=1;
-
+
} else {
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
-
+
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
}
-
- lock=MID_Lock(mem);
+
+ lock=MID_Lock(mem);
}
-
-
-
-
+
+
+
+
T *t = (T*)((int*)lock.data() + 1);
-
+
for (int i=oldsize;i<p_size;i++) {
-
+
memnew_placement(&t[i], T );
}
-
+
lock = MID_Lock(); // clear
} else {
-
+
int oldsize=size();
-
+
MID_Lock lock(mem);
-
-
+
+
T *t = (T*)((int*)lock.data() + 1);
-
+
for (int i=p_size;i<oldsize;i++) {
-
+
t[i].~T();
}
-
+
lock = MID_Lock(); // clear
-
+
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
-
- ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
+
+ ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
}
-
-
+
+
}
-
+
return OK;
}
diff --git a/core/error_macros.h b/core/error_macros.h
index cafbf0c16e..6d931e899e 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -33,12 +33,12 @@
/**
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
* inside the code. It is recommended to always return processable data, so in case of an error, the
- * engine can stay working well.
+ * engine can stay working well.
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
* to fail or crash.
*/
-/**
+/**
* Pointer to the error macro priting function. Reassign to any function to have errors printed
*/
@@ -136,7 +136,7 @@ extern bool _err_error_exists;
return m_retval; \
}else _err_error_exists=false; } \
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
+/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
@@ -146,7 +146,7 @@ extern bool _err_error_exists;
return; \
}else _err_error_exists=false; } \
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
+/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
@@ -158,7 +158,7 @@ extern bool _err_error_exists;
return m_retval; \
}else _err_error_exists=false; } \
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
+/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will skip to the next iteration.
*/
@@ -168,7 +168,7 @@ extern bool _err_error_exists;
continue;\
} else _err_error_exists=false;} \
-/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
+/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will break
*/
@@ -223,5 +223,10 @@ extern bool _err_error_exists;
} \
+#define WARN_PRINTS(m_string) \
+ { \
+ _err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data(),ERR_HANDLER_WARNING); \
+ _err_error_exists=false;\
+ } \
#endif
diff --git a/core/event_queue.cpp b/core/event_queue.cpp
index 088e80b266..53638c5431 100644
--- a/core/event_queue.cpp
+++ b/core/event_queue.cpp
@@ -43,118 +43,118 @@ Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method,
args=2;
else if (p_arg1.get_type()!=Variant::NIL)
args=1;
- else
+ else
args=0;
-
+
room_needed+=sizeof(Variant)*args;
-
+
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
ev->args=args;
ev->instance_ID=p_instance_ID;
ev->method=p_method;
-
+
buffer_end+=sizeof(Event);
-
+
if (args>=1) {
-
+
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg1;
}
if (args>=2) {
-
+
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg2;
}
if (args>=3) {
-
+
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg3;
-
+
}
if (args>=4) {
-
+
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg4;
}
if (args>=5) {
-
+
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg5;
}
-
+
if (buffer_max_used>buffer_end);
buffer_max_used=buffer_end;
-
+
return OK;
}
void EventQueue::flush_events() {
uint32_t read_pos=0;
-
+
while (read_pos < buffer_end ) {
-
+
Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1);
Object *obj = ObjectDB::get_instance(event->instance_ID);
-
- if (obj) {
+
+ if (obj) {
// events don't expect a return value
- obj->call( event->method,
+ obj->call( event->method,
(event->args>=1) ? args[0] : Variant(),
(event->args>=2) ? args[1] : Variant(),
(event->args>=3) ? args[2] : Variant(),
(event->args>=4) ? args[3] : Variant(),
(event->args>=5) ? args[4] : Variant() );
}
-
+
if (event->args>=1) args[0].~Variant();
if (event->args>=2) args[1].~Variant();
if (event->args>=3) args[2].~Variant();
if (event->args>=4) args[3].~Variant();
if (event->args>=5) args[4].~Variant();
event->~Event();
-
+
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
}
-
+
buffer_end=0; // reset buffer
}
EventQueue::EventQueue(uint32_t p_buffer_size) {
-
+
buffer_end=0;
buffer_max_used=0;
buffer_size=p_buffer_size;
event_buffer = memnew_arr( uint8_t, buffer_size );
-
+
}
EventQueue::~EventQueue() {
uint32_t read_pos=0;
-
+
while (read_pos < buffer_end ) {
-
+
Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1);
for (int i=0;i<event->args;i++)
args[i].~Variant();
event->~Event();
-
+
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
}
-
+
memdelete_arr(event_buffer);
event_buffer=NULL;
}
diff --git a/core/event_queue.h b/core/event_queue.h
index af0a4df2b8..99e853fd28 100644
--- a/core/event_queue.h
+++ b/core/event_queue.h
@@ -36,18 +36,18 @@
class EventQueue {
enum {
-
+
DEFAULT_EVENT_QUEUE_SIZE_KB=256
};
struct Event {
-
+
uint32_t instance_ID;
StringName method;
int args;
};
-
-
+
+
uint8_t *event_buffer;
uint32_t buffer_end;
uint32_t buffer_max_used;
@@ -57,7 +57,7 @@ public:
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
void flush_events();
-
+
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
~EventQueue();
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index 92e50a8b96..130fca1b2a 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -106,7 +106,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( KEY_KP_ENTER ),
BIND_GLOBAL_CONSTANT( KEY_KP_MULTIPLY ),
BIND_GLOBAL_CONSTANT( KEY_KP_DIVIDE ),
- BIND_GLOBAL_CONSTANT( KEY_KP_SUBSTRACT ),
+ BIND_GLOBAL_CONSTANT( KEY_KP_SUBTRACT ),
BIND_GLOBAL_CONSTANT( KEY_KP_PERIOD ),
BIND_GLOBAL_CONSTANT( KEY_KP_ADD ),
BIND_GLOBAL_CONSTANT( KEY_KP_0 ),
@@ -317,16 +317,19 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( KEY_MASK_KPAD ),
BIND_GLOBAL_CONSTANT( KEY_MASK_GROUP_SWITCH ),
- // joysticks
+ // mouse
BIND_GLOBAL_CONSTANT( BUTTON_LEFT ),
BIND_GLOBAL_CONSTANT( BUTTON_RIGHT ),
BIND_GLOBAL_CONSTANT( BUTTON_MIDDLE ),
BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_UP ),
BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_DOWN ),
+ BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_LEFT ),
+ BIND_GLOBAL_CONSTANT( BUTTON_WHEEL_RIGHT ),
BIND_GLOBAL_CONSTANT( BUTTON_MASK_LEFT ),
BIND_GLOBAL_CONSTANT( BUTTON_MASK_RIGHT ),
BIND_GLOBAL_CONSTANT( BUTTON_MASK_MIDDLE ),
+ //joysticks
BIND_GLOBAL_CONSTANT( JOY_BUTTON_0 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_1 ),
BIND_GLOBAL_CONSTANT( JOY_BUTTON_2 ),
@@ -429,6 +432,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),
+ BIND_GLOBAL_CONSTANT( ERR_PARSE_ERROR ),
BIND_GLOBAL_CONSTANT( ERROR_QUERY_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_ALREADY_IN_USE ),
BIND_GLOBAL_CONSTANT( ERR_LOCKED ), ///< resource is locked
@@ -476,6 +480,16 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT ),
+
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_NORMAL ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_EDITOR ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_NOSCRIPT ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_CONST ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_REVERSE ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_VIRTUAL ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAG_FROM_SCRIPT ),
+ BIND_GLOBAL_CONSTANT( METHOD_FLAGS_DEFAULT ),
+
{"TYPE_NIL",Variant::NIL},
{"TYPE_BOOL",Variant::BOOL},
{"TYPE_INT",Variant::INT},
diff --git a/core/globals.cpp b/core/globals.cpp
index 5f52420735..c0c1171ae6 100644
--- a/core/globals.cpp
+++ b/core/globals.cpp
@@ -40,7 +40,7 @@
Globals *Globals::singleton=NULL;
Globals *Globals::get_singleton() {
-
+
return singleton;
}
@@ -108,7 +108,7 @@ bool Globals::is_persisting(const String& p_name) const {
String Globals::globalize_path(const String& p_path) const {
-
+
if (p_path.begins_with("res://")) {
if (resource_path != "") {
@@ -125,7 +125,7 @@ String Globals::globalize_path(const String& p_path) const {
bool Globals::_set(const StringName& p_name, const Variant& p_value) {
_THREAD_SAFE_METHOD_
-
+
if (p_value.get_type()==Variant::NIL)
props.erase(p_name);
else {
@@ -174,7 +174,7 @@ bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
return false;
r_ret=props[p_name].variant;
return true;
-
+
}
struct _VCSort {
@@ -188,13 +188,13 @@ struct _VCSort {
};
void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
-
+
_THREAD_SAFE_METHOD_
Set<_VCSort> vclist;
-
+
for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
-
+
const VariantContainer *v=&E->get();
if (v->hide_from_editor)
@@ -250,7 +250,7 @@ bool Globals::_load_resource_pack(const String& p_pack) {
Error Globals::setup(const String& p_path,const String & p_main_pack) {
//an absolute mess of a function, must be cleaned up and reorganized somehow at some point
-
+
//_load_settings(p_path+"/override.cfg");
if (p_main_pack!="") {
@@ -292,7 +292,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
}
}
-
+
if (FileAccessNetworkClient::get_singleton()) {
@@ -332,7 +332,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
resource_path = p_path;
} else {
-
+
d->change_dir(p_path);
String candidate = d->get_current_dir();
@@ -395,7 +395,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
}
bool Globals::has(String p_var) const {
-
+
_THREAD_SAFE_METHOD_
return props.has(p_var);
@@ -916,6 +916,14 @@ static String _encode_variant(const Variant& p_variant) {
float val = p_variant;
return rtos(val)+(val==int(val)?".0":"");
} break;
+ case Variant::VECTOR2: {
+ Vector2 val = p_variant;
+ return String("Vector2(")+rtos(val.x)+String(", ")+rtos(val.y)+String(")");
+ } break;
+ case Variant::VECTOR3: {
+ Vector3 val = p_variant;
+ return String("Vector3(")+rtos(val.x)+ String(", ") +rtos(val.y)+ String(", ") +rtos(val.z)+String(")");
+ } break;
case Variant::STRING: {
String val = p_variant;
return "\""+val.xml_escape()+"\"";
@@ -1402,7 +1410,7 @@ void Globals::_bind_methods() {
}
Globals::Globals() {
-
+
singleton=this;
last_order=0;
@@ -1523,7 +1531,7 @@ Globals::Globals() {
Globals::~Globals() {
-
+
singleton=NULL;
}
diff --git a/core/globals.h b/core/globals.h
index 8951f5fbd2..68bb859ace 100644
--- a/core/globals.h
+++ b/core/globals.h
@@ -38,7 +38,7 @@
class Globals : public Object {
-
+
OBJ_TYPE( Globals, Object );
_THREAD_SAFE_CLASS_
@@ -77,13 +77,13 @@ protected:
bool using_datapack;
List<String> input_presets;
-
+
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
-
+
static Globals *singleton;
-
+
Error _load_settings(const String p_path);
Error _load_settings_binary(const String p_path);
@@ -101,7 +101,7 @@ protected:
static void _bind_methods();
public:
-
+
bool has(String p_var) const;
String localize_path(const String& p_path) const;
String globalize_path(const String& p_path) const;
@@ -110,13 +110,13 @@ public:
bool is_persisting(const String& p_name) const;
String get_resource_path() const;
-
+
static Globals *get_singleton();
void clear(const String& p_name);
int get_order(const String& p_name) const;
void set_order(const String& p_name, int p_order);
-
+
Error setup(const String& p_path, const String &p_main_pack);
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
@@ -141,7 +141,7 @@ public:
void set_registering_order(bool p_registering);
- Globals();
+ Globals();
~Globals();
};
diff --git a/core/hash_map.h b/core/hash_map.h
index 33eb25652c..e83710c700 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -38,7 +38,7 @@
class HashMapHahserDefault {
public:
-
+
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
@@ -66,8 +66,8 @@ public:
/**
* @class HashMap
- * @author Juan Linietsky <reduzio@gmail.com>
- *
+ * @author Juan Linietsky <reduzio@gmail.com>
+ *
* Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key.
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide
* your own.
@@ -77,213 +77,213 @@ public:
* @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter.
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
- *
+ *
*/
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
class HashMap {
-public:
-
+public:
+
struct Pair {
-
+
TKey key;
TData data;
-
+
Pair() {}
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
};
-
-
-private:
+
+
+private:
struct Entry {
-
+
uint32_t hash;
Entry *next;
Pair pair;
-
+
Entry() { next=0; }
};
-
+
Entry **hash_table;
uint8_t hash_table_power;
uint32_t elements;
-
+
void make_hash_table() {
-
+
ERR_FAIL_COND( hash_table );
-
-
+
+
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
-
+
hash_table_power = MIN_HASH_TABLE_POWER;
elements=0;
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
hash_table[i]=0;
}
-
+
void erase_hash_table() {
-
+
ERR_FAIL_COND(elements);
-
+
memdelete_arr( hash_table );
hash_table=0;
- hash_table_power=0;
- elements=0;
- }
-
+ hash_table_power=0;
+ elements=0;
+ }
+
void check_hash_table() {
int new_hash_table_power=-1;
-
+
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
/* rehash up */
new_hash_table_power=hash_table_power+1;
-
+
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
-
+
new_hash_table_power++;
}
-
+
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
-
+
/* rehash down */
new_hash_table_power=hash_table_power-1;
-
+
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
-
+
new_hash_table_power--;
}
-
+
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
new_hash_table_power=MIN_HASH_TABLE_POWER;
}
-
-
+
+
if (new_hash_table_power==-1)
return;
-
+
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
if (!new_hash_table) {
-
+
ERR_PRINT("Out of Memory");
return;
}
-
+
for (int i=0;i<(1<<new_hash_table_power);i++) {
-
+
new_hash_table[i]=0;
}
-
+
for (int i=0;i<(1<<hash_table_power);i++) {
-
+
while( hash_table[i] ) {
-
+
Entry *se=hash_table[i];
hash_table[i]=se->next;
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
se->next=new_hash_table[new_pos];
new_hash_table[new_pos]=se;
}
-
+
}
-
+
if (hash_table)
memdelete_arr( hash_table );
hash_table=new_hash_table;
- hash_table_power=new_hash_table_power;
+ hash_table_power=new_hash_table_power;
}
/* I want to have only one function.. */
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
-
+
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
-
+
Entry *e = hash_table[index];
-
+
while (e) {
-
+
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) {
-
+
/* the pair exists in this hashtable, so just update data */
return e;
}
-
+
e=e->next;
}
-
+
return NULL;
}
-
+
Entry * create_entry(const TKey& p_key) {
-
+
/* if entry doesn't exist, create it */
Entry *e = memnew( Entry );
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
- e->next = hash_table[index];
+ e->next = hash_table[index];
e->hash = hash;
e->pair.key=p_key;
-
+
hash_table[index]=e;
elements++;
-
+
return e;
}
-
-
+
+
void copy_from(const HashMap& p_t) {
-
+
if (&p_t==this)
return; /* much less bother with that */
-
+
clear();
-
+
if (!p_t.hash_table || p_t.hash_table_power==0)
return; /* not copying from empty table */
-
+
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
hash_table_power=p_t.hash_table_power;
elements=p_t.elements;
-
+
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
-
+
hash_table[i]=NULL;
/* elements will be in the reverse order, but it doesn't matter */
-
+
const Entry *e = p_t.hash_table[i];
-
+
while(e) {
-
+
Entry *le = memnew( Entry ); /* local entry */
-
+
*le=*e; /* copy data */
-
+
/* add to list and reassign pointers */
le->next=hash_table[i];
hash_table[i]=le;
-
+
e=e->next;
}
-
-
+
+
}
-
-
+
+
}
public:
-
-
+
+
void set( const TKey& p_key, const TData& p_data ) {
-
+
set( Pair( p_key, p_data ) );
-
+
}
-
+
void set( const Pair& p_pair ) {
Entry *e=NULL;
@@ -291,63 +291,63 @@ public:
make_hash_table(); // if no table, make one
else
e = const_cast<Entry*>( get_entry(p_pair.key) );
-
+
/* if we made it up to here, the pair doesn't exist, create and assign */
-
+
if (!e) {
-
+
e=create_entry(p_pair.key);
if (!e)
return;
check_hash_table(); // perform mantenience routine
}
-
+
e->pair.data = p_pair.data;
-
+
}
-
-
+
+
bool has( const TKey& p_key ) const {
-
+
return getptr(p_key)!=NULL;
}
-
+
/**
- * Get a key from data, return a const reference.
+ * Get a key from data, return a const reference.
* WARNING: this doesn't check errors, use either getptr and check NULL, or check
* first with has(key)
*/
-
+
const TData& get( const TKey& p_key ) const {
-
+
const TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res);
return *res;
}
-
+
TData& get( const TKey& p_key ) {
-
+
TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res);
return *res;
}
-
+
/**
* Same as get, except it can return NULL when item was not found.
* This is mainly used for speed purposes.
*/
-
+
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
-
+
if (!hash_table)
return NULL;
-
+
Entry *e=const_cast<Entry*>(get_entry(p_key ));
-
+
if (e)
return &e->pair.data;
-
+
return NULL;
}
@@ -427,108 +427,108 @@ public:
/**
* Erase an item, return true if erasing was succesful
*/
-
+
bool erase( const TKey& p_key ) {
-
+
if (!hash_table)
return false;
-
+
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
-
-
+
+
Entry *e = hash_table[index];
Entry *p=NULL;
while (e) {
-
+
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) {
-
+
if (p) {
-
+
p->next=e->next;
- } else {
+ } else {
//begin of list
hash_table[index]=e->next;
}
-
+
memdelete(e);
elements--;
-
+
if (elements==0)
erase_hash_table();
else
- check_hash_table();
+ check_hash_table();
return true;
}
-
+
p=e;
e=e->next;
}
-
-
+
+
return false;
-
+
}
-
+
inline const TData& operator[](const TKey& p_key) const { //constref
-
+
return get(p_key);
}
inline TData& operator[](const TKey& p_key ) { //assignment
-
+
Entry *e=NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
e = const_cast<Entry*>( get_entry(p_key) );
-
+
/* if we made it up to here, the pair doesn't exist, create */
if (!e) {
-
+
e=create_entry(p_key);
if (!e)
return *(TData*)NULL; /* panic! */
check_hash_table(); // perform mantenience routine
}
-
+
return e->pair.data;
-
+
}
-
- /**
- * Get the next key to p_key, and the first key if p_key is null.
+
+ /**
+ * Get the next key to p_key, and the first key if p_key is null.
* Returns a pointer to the next key if found, NULL otherwise.
* Adding/Removing elements while iterating will, of course, have unexpected results, don't do it.
- *
+ *
* Example:
- *
+ *
* const TKey *k=NULL;
- *
+ *
* while( (k=table.next(k)) ) {
- *
+ *
* print( *k );
* }
- *
+ *
*/
const TKey* next(const TKey* p_key) const {
-
+
if (!hash_table) return NULL;
-
+
if (!p_key) { /* get the first key */
-
+
for (int i=0;i<(1<<hash_table_power);i++) {
-
+
if (hash_table[i]) {
return &hash_table[i]->pair.key;
}
}
} else { /* get the next key */
-
+
const Entry *e = get_entry( *p_key );
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
-
+
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;
@@ -537,60 +537,60 @@ public:
uint32_t index = e->hash&((1<<hash_table_power)-1);
index++;
for (int i=index;i<(1<<hash_table_power);i++) {
-
+
if (hash_table[i]) {
return &hash_table[i]->pair.key;
}
}
}
-
+
/* nothing found, was at end */
-
+
}
-
-
+
+
return NULL; /* nothing found */
}
-
+
inline unsigned int size() const {
-
+
return elements;
}
-
+
inline bool empty() const {
-
+
return elements==0;
}
-
+
void clear() {
-
+
/* clean up */
if (hash_table) {
for (int i=0;i<(1<<hash_table_power);i++) {
-
+
while (hash_table[i]) {
-
+
Entry *e=hash_table[i];
hash_table[i]=e->next;
memdelete( e );
}
}
-
+
memdelete_arr( hash_table );
}
-
+
hash_table=0;
hash_table_power=0;
- elements=0;
+ elements=0;
}
-
-
+
+
void operator=(const HashMap& p_table) {
-
+
copy_from(p_table);
}
-
- HashMap() {
+
+ HashMap() {
hash_table=NULL;
elements=0;
hash_table_power=0;
@@ -609,18 +609,18 @@ public:
}
}
- HashMap(const HashMap& p_table) {
-
+ HashMap(const HashMap& p_table) {
+
hash_table=NULL;
elements=0;
hash_table_power=0;
-
+
copy_from(p_table);
-
+
}
-
+
~HashMap() {
-
+
clear();
}
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index c2ed5bd679..a917ee5edb 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -47,10 +47,10 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
const unsigned char* chr=(const unsigned char*)p_cstr;
uint32_t hash = 5381;
uint32_t c;
-
+
while ((c = *chr++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-
+
return hash;
}
@@ -86,7 +86,7 @@ static inline uint32_t make_uint32_t(T p_in) {
T t;
uint32_t _u32;
} _u;
- _u._u32=0;
+ _u._u32=0;
_u.t=p_in;
return _u._u32;
}
@@ -106,7 +106,7 @@ static inline uint64_t make_uint64_t(T p_in) {
uint64_t _u64;
} _u;
_u._u64=0; // in case p_in is smaller
-
+
_u.t=p_in;
return _u._u64;
}
diff --git a/core/image.cpp b/core/image.cpp
index 798fc41f40..52946bbb85 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -382,7 +382,7 @@ void Image::convert( Format p_new_format ){
Image new_img(width,height,0,p_new_format);
-
+
int len=data.size();
DVector<uint8_t>::Read r = data.read();
@@ -413,7 +413,7 @@ void Image::convert( Format p_new_format ){
w = DVector<uint8_t>::Write();
bool gen_mipmaps=mipmaps>0;
-
+
*this=new_img;
if (gen_mipmaps)
@@ -643,13 +643,13 @@ void Image::resize( int p_width, int p_height, Interpolation p_interpolation ) {
ERR_FAIL_COND(p_height<=0);
ERR_FAIL_COND(p_width>MAX_WIDTH);
ERR_FAIL_COND(p_height>MAX_HEIGHT);
-
+
if (p_width==width && p_height==height)
return;
-
+
Image dst( p_width, p_height, 0, format );
-
+
if (format==FORMAT_INDEXED)
p_interpolation=INTERPOLATE_NEAREST;
@@ -714,34 +714,34 @@ void Image::crop( int p_width, int p_height ) {
ERR_FAIL_COND(p_height<=0);
ERR_FAIL_COND(p_width>MAX_WIDTH);
ERR_FAIL_COND(p_height>MAX_HEIGHT);
-
+
/* to save memory, cropping should be done in-place, however, since this function
will most likely either not be used much, or in critical areas, for now it wont, because
it's a waste of time. */
if (p_width==width && p_height==height)
return;
-
+
Image dst( p_width, p_height,0, format );
-
+
for (int y=0;y<p_height;y++) {
-
+
for (int x=0;x<p_width;x++) {
Color col = (x>=width || y>=height)? Color() : get_pixel(x,y);
dst.put_pixel(x,y,col);
}
}
-
+
if (mipmaps>0)
dst.generate_mipmaps();
*this=dst;
-
+
}
void Image::flip_y() {
-
+
if (!_can_modify(format)) {
ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
ERR_FAIL();
@@ -756,12 +756,12 @@ void Image::flip_y() {
for (int y=0;y<(height/2);y++) {
-
+
for (int x=0;x<width;x++) {
Color up = get_pixel(x,y);
Color down = get_pixel(x,height-y-1);
-
+
put_pixel(x,y,down);
put_pixel(x,height-y-1,up);
}
@@ -783,12 +783,12 @@ void Image::flip_x() {
clear_mipmaps();;
for (int y=0;y<(height/2);y++) {
-
+
for (int x=0;x<width;x++) {
-
+
Color up = get_pixel(x,y);
Color down = get_pixel(width-x-1,y);
-
+
put_pixel(x,y,down);
put_pixel(width-x-1,y,up);
}
@@ -1040,26 +1040,26 @@ void Image::make_normalmap(float p_height_scale) {
}
ERR_FAIL_COND( empty() );
-
+
Image normalmap(width,height,0, FORMAT_RGB);
/*
for (int y=0;y<height;y++) {
for (int x=0;x<width;x++) {
-
+
float center=get_pixel(x,y).gray()/255.0;
float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center;
float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center;
float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center;
float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center;
-
-
+
+
// uhm, how do i do this? ....
-
+
Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) );
-
+
normalmap.put_pixel( x, y, result );
}
-
+
}
*/
*this=normalmap;
@@ -1071,14 +1071,14 @@ bool Image::empty() const {
}
DVector<uint8_t> Image::get_data() const {
-
+
return data;
}
void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format) {
- int mm=0;
+ int mm=0;
int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps?-1:0);
data.resize( size );
{
@@ -1095,7 +1095,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format
}
void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) {
-
+
ERR_FAIL_INDEX(p_width-1,MAX_WIDTH);
ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT);
@@ -1108,48 +1108,48 @@ void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, co
ERR_FAIL_COND(p_data.size()!=size);
}
};
-
+
height=p_height;
width=p_width;
format=p_format;
- data=p_data;
+ data=p_data;
mipmaps=p_mipmaps;
}
void Image::create( const char ** p_xpm ) {
-
+
int size_width,size_height;
int pixelchars=0;
mipmaps=0;
bool has_alpha=false;
-
+
enum Status {
READING_HEADER,
READING_COLORS,
READING_PIXELS,
DONE
};
-
+
Status status = READING_HEADER;
int line=0;
-
+
HashMap<String,Color> colormap;
int colormap_size;
-
+
while (status!=DONE) {
-
+
const char * line_ptr = p_xpm[line];
-
-
+
+
switch (status) {
-
+
case READING_HEADER: {
-
+
String line_str=line_ptr;
line_str.replace("\t"," ");
-
+
size_width=line_str.get_slicec(' ',0).to_int();
size_height=line_str.get_slicec(' ',1).to_int();
colormap_size=line_str.get_slicec(' ',2).to_int();
@@ -1161,10 +1161,10 @@ void Image::create( const char ** p_xpm ) {
status=READING_COLORS;
} break;
case READING_COLORS: {
-
+
String colorstring;
for (int i=0;i<pixelchars;i++) {
-
+
colorstring+=*line_ptr;
line_ptr++;
}
@@ -1175,25 +1175,25 @@ void Image::create( const char ** p_xpm ) {
line_ptr++;
}
if (*line_ptr=='c') {
-
+
line_ptr++;
while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) {
if (*line_ptr==0)
break;
line_ptr++;
}
-
+
if (*line_ptr=='#') {
line_ptr++;
uint8_t col_r;
uint8_t col_g;
uint8_t col_b;
// uint8_t col_a=255;
-
+
for (int i=0;i<6;i++) {
-
+
char v = line_ptr[i];
-
+
if (v>='0' && v<='9')
v-='0';
else if (v>='A' && v<='F')
@@ -1202,7 +1202,7 @@ void Image::create( const char ** p_xpm ) {
v=(v-'a')+10;
else
break;
-
+
switch(i) {
case 0: col_r=v<<4; break;
case 1: col_r|=v; break;
@@ -1211,48 +1211,48 @@ void Image::create( const char ** p_xpm ) {
case 4: col_b=v<<4; break;
case 5: col_b|=v; break;
};
-
+
}
-
+
// magenta mask
if (col_r==255 && col_g==0 && col_b==255) {
-
+
colormap[colorstring]=Color(0,0,0,0);
has_alpha=true;
} else {
colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0);
}
-
+
}
}
if (line==colormap_size) {
-
+
status=READING_PIXELS;
create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB);
}
} break;
case READING_PIXELS: {
-
+
int y=line-colormap_size-1;
for (int x=0;x<size_width;x++) {
-
+
char pixelstr[6]={0,0,0,0,0,0};
for (int i=0;i<pixelchars;i++)
pixelstr[i]=line_ptr[x*pixelchars+i];
-
+
Color *colorptr = colormap.getptr(pixelstr);
ERR_FAIL_COND(!colorptr);
put_pixel(x,y,*colorptr);
-
+
}
-
+
if (y==(size_height-1))
status=DONE;
} break;
default:{}
}
-
+
line++;
}
}
@@ -2022,7 +2022,7 @@ Image Image::compressed(int p_mode) {
};
Image::Image(const char **p_xpm) {
-
+
width=0;
height=0;
mipmaps=0;
@@ -2214,6 +2214,8 @@ void Image::blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2&
Image (*Image::_png_mem_loader_func)(const uint8_t*,int)=NULL;
+Image (*Image::_jpg_mem_loader_func)(const uint8_t*,int)=NULL;
+
void (*Image::_image_compress_bc_func)(Image *)=NULL;
void (*Image::_image_compress_pvrtc2_func)(Image *)=NULL;
void (*Image::_image_compress_pvrtc4_func)(Image *)=NULL;
@@ -2388,7 +2390,7 @@ String Image::get_format_name(Format p_format) {
return format_names[p_format];
}
-Image::Image(const uint8_t* p_png,int p_len) {
+Image::Image(const uint8_t* p_mem_png_jpg, int p_len) {
width=0;
height=0;
@@ -2396,8 +2398,13 @@ Image::Image(const uint8_t* p_png,int p_len) {
format=FORMAT_GRAYSCALE;
if (_png_mem_loader_func) {
- *this = _png_mem_loader_func(p_png,p_len);
+ *this = _png_mem_loader_func(p_mem_png_jpg,p_len);
}
+
+ if (empty() && _jpg_mem_loader_func) {
+ *this = _jpg_mem_loader_func(p_mem_png_jpg,p_len);
+ }
+
}
Image::Image() {
diff --git a/core/image.h b/core/image.h
index aea5dc6438..fe1822f661 100644
--- a/core/image.h
+++ b/core/image.h
@@ -46,7 +46,7 @@ typedef Error (*SavePNGFunc)(const String &p_path, Image& p_img);
class Image {
- enum {
+ enum {
MAX_WIDTH=16384, // force a limit somehow
MAX_HEIGHT=16384// force a limit somehow
};
@@ -55,12 +55,12 @@ public:
static SavePNGFunc save_png_func;
enum Format {
- FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
- FORMAT_INTENSITY, ///< one byte per pixel, 0-255
- FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
- FORMAT_RGB, ///< one byte R, one byte G, one byte B
- FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
- FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
+ FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
+ FORMAT_INTENSITY, ///< one byte per pixel, 0-255
+ FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
+ FORMAT_RGB, ///< one byte R, one byte G, one byte B
+ FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
+ FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha)
FORMAT_YUV_422,
FORMAT_YUV_444,
@@ -89,7 +89,7 @@ public:
static const char* format_names[FORMAT_MAX];
enum Interpolation {
-
+
INTERPOLATE_NEAREST,
INTERPOLATE_BILINEAR,
INTERPOLATE_CUBIC,
@@ -97,6 +97,7 @@ public:
};
static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size);
+ static Image (*_jpg_mem_loader_func)(const uint8_t* p_png,int p_size);
static void (*_image_compress_bc_func)(Image *);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
@@ -186,7 +187,7 @@ private:
DVector<uint8_t> data;
int width,height,mipmaps;
-
+
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
@@ -207,7 +208,7 @@ public:
int get_width() const; ///< Get image width
int get_height() const; ///< Get image height
int get_mipmaps() const;
-
+
/**
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
* value.
@@ -217,7 +218,7 @@ public:
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
*/
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
-
+
/**
* Convert the image to another format, as close as it can be done.
*/
@@ -230,7 +231,7 @@ public:
ret.convert((Format)p_new_format);
return ret;
};
-
+
/**
* Get the current image format.
*/
@@ -243,7 +244,7 @@ public:
/**
* Resize the image, using the prefered interpolation method.
* Indexed-Color images always use INTERPOLATE_NEAREST.
- */
+ */
void resize_to_po2(bool p_square=false);
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
@@ -252,22 +253,22 @@ public:
* Crop the image to a specific size, if larger, then the image is filled by black
*/
void crop( int p_width, int p_height );
-
-
+
+
void flip_x();
void flip_y();
/**
- * Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
+ * Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
*/
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
void clear_mipmaps();
-
+
/**
* Generate a normal map from a grayscale image
*/
-
+
void make_normalmap(float p_height_scale=1.0);
/**
@@ -276,26 +277,26 @@ public:
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
- void create( const char ** p_xpm );
+ void create( const char ** p_xpm );
/**
* returns true when the image is empty (0,0) in size
*/
bool empty() const;
-
+
DVector<uint8_t> get_data() const;
-
+
Error load(const String& p_path);
Error save_png(const String& p_path);
-
- /**
+
+ /**
* create an empty image
*/
Image();
- /**
+ /**
* create an empty image of a specific size and format
*/
Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
- /**
+ /**
* import an image of a specific size and format from a pointer
*/
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
@@ -313,7 +314,7 @@ public:
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
void set_pallete(const DVector<uint8_t>& p_data);
-
+
static int get_format_pixel_size(Format p_format);
static int get_format_pixel_rshift(Format p_format);
static int get_format_pallete_size(Format p_format);
@@ -355,7 +356,7 @@ public:
static void set_compress_bc_func(void (*p_compress_func)(Image *));
static String get_format_name(Format p_format);
- Image(const uint8_t* p_mem_png, int p_len=-1);
+ Image(const uint8_t* p_mem_png_jpg, int p_len=-1);
Image(const char **p_xpm);
~Image();
diff --git a/core/input_map.cpp b/core/input_map.cpp
index d4560a1e1b..5a9b035771 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -38,7 +38,7 @@ void InputMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
-
+
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
@@ -156,10 +156,7 @@ void InputMap::action_erase_event(const StringName& p_action,const InputEvent& p
List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event);
if (E)
- return; //already gots
-
- input_map[p_action].inputs.erase(E);
-
+ input_map[p_action].inputs.erase(E);
}
diff --git a/core/io/aes256.h b/core/io/aes256.h
index fabbcf1968..8fcc25a4de 100644
--- a/core/io/aes256.h
+++ b/core/io/aes256.h
@@ -1,6 +1,6 @@
-/*
+/*
* Byte-oriented AES-256 implementation.
-* All lookup tables replaced with 'on the fly' calculations.
+* All lookup tables replaced with 'on the fly' calculations.
*
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
* Other contributors: Hal Finney
@@ -24,14 +24,14 @@
#include "typedefs.h"
#ifdef __cplusplus
-extern "C" {
+extern "C" {
#endif
typedef struct {
- uint8_t key[32];
- uint8_t enckey[32];
+ uint8_t key[32];
+ uint8_t enckey[32];
uint8_t deckey[32];
- } aes256_context;
+ } aes256_context;
void aes256_init(aes256_context *, uint8_t * /* key */);
diff --git a/core/io/fastlz.h b/core/io/fastlz.h
index f87bc7be31..e5ca8dfc02 100644
--- a/core/io/fastlz.h
+++ b/core/io/fastlz.h
@@ -1,4 +1,4 @@
-/*
+/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
@@ -40,11 +40,11 @@ extern "C" {
#endif
/**
- Compress a block of data in the input buffer and returns the size of
- compressed block. The size of input buffer is specified by length. The
+ Compress a block of data in the input buffer and returns the size of
+ compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
- The output buffer must be at least 5% larger than the input buffer
+ The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
@@ -56,9 +56,9 @@ extern "C" {
int fastlz_compress(const void* input, int length, void* output);
/**
- Decompress a block of compressed data and returns the size of the
- decompressed block. If error occurs, e.g. the compressed data is
- corrupted or the output buffer is not large enough, then 0 (zero)
+ Decompress a block of compressed data and returns the size of the
+ decompressed block. If error occurs, e.g. the compressed data is
+ corrupted or the output buffer is not large enough, then 0 (zero)
will be returned instead.
The input buffer and the output buffer can not overlap.
@@ -67,14 +67,14 @@ int fastlz_compress(const void* input, int length, void* output);
more than what is specified in maxout.
*/
-int fastlz_decompress(const void* input, int length, void* output, int maxout);
+int fastlz_decompress(const void* input, int length, void* output, int maxout);
/**
- Compress a block of data in the input buffer and returns the size of
- compressed block. The size of input buffer is specified by length. The
+ Compress a block of data in the input buffer and returns the size of
+ compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
- The output buffer must be at least 5% larger than the input buffer
+ The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
@@ -82,14 +82,14 @@ int fastlz_decompress(const void* input, int length, void* output, int maxout);
The input buffer and the output buffer can not overlap.
- Compression level can be specified in parameter level. At the moment,
+ Compression level can be specified in parameter level. At the moment,
only level 1 and level 2 are supported.
Level 1 is the fastest compression and generally useful for short data.
Level 2 is slightly slower but it gives better compression ratio.
Note that the compressed data, regardless of the level, can always be
decompressed using the function fastlz_decompress above.
-*/
+*/
int fastlz_compress_level(int level, const void* input, int length, void* output);
diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp
index b38fda3686..e6b01475b6 100644
--- a/core/io/file_access_buffered.cpp
+++ b/core/io/file_access_buffered.cpp
@@ -33,17 +33,17 @@
#include "error_macros.h"
Error FileAccessBuffered::set_error(Error p_error) const {
-
+
return (last_error = p_error);
};
void FileAccessBuffered::set_cache_size(int p_size) {
-
+
cache_size = p_size;
};
int FileAccessBuffered::get_cache_size() {
-
+
return cache_size;
};
@@ -66,27 +66,27 @@ int FileAccessBuffered::cache_data_left() const {
};
void FileAccessBuffered::seek(size_t p_position) {
-
+
file.offset = p_position;
};
void FileAccessBuffered::seek_end(int64_t p_position) {
-
+
file.offset = file.size + p_position;
};
size_t FileAccessBuffered::get_pos() const {
-
+
return file.offset;
};
size_t FileAccessBuffered::get_len() const {
-
+
return file.size;
};
bool FileAccessBuffered::eof_reached() const {
-
+
return file.offset > file.size;
};
@@ -165,12 +165,12 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
};
bool FileAccessBuffered::is_open() const {
-
+
return file.open;
};
Error FileAccessBuffered::get_error() const {
-
+
return last_error;
};
@@ -180,5 +180,5 @@ FileAccessBuffered::FileAccessBuffered() {
};
FileAccessBuffered::~FileAccessBuffered(){
-
+
}
diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h
index 9d405e15f7..058c26b8a9 100644
--- a/core/io/file_access_buffered.h
+++ b/core/io/file_access_buffered.h
@@ -60,9 +60,9 @@ protected:
String name;
int access_flags;
} file;
-
+
mutable struct Cache {
-
+
Vector<uint8_t> buffer;
int offset;
} cache;
@@ -71,7 +71,7 @@ protected:
void set_cache_size(int p_size);
int get_cache_size();
-
+
public:
virtual size_t get_pos() const; ///< get position in the file
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index e63b57533f..a3c839e761 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -217,7 +217,7 @@ Error FileAccessNetworkClient::connect(const String& p_host,int p_port,const Str
return ERR_CANT_CONNECT;
}
- CharString cs = p_password.utf8();
+ CharString cs = p_password.utf8();
put_32(cs.length());
client->put_data((const uint8_t*)cs.ptr(),cs.length());
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 19a7286dcf..e0c01c9422 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -31,10 +31,6 @@
VARIANT_ENUM_CAST(HTTPClient::Status);
-Error HTTPClient::connect_url(const String& p_url) {
-
- return OK;
-}
Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl,bool p_verify_host){
@@ -306,17 +302,17 @@ Error HTTPClient::poll(){
for(int i=0;i<responses.size();i++) {
- String s = responses[i].strip_edges();
- s = s.to_lower();
+ String header = responses[i].strip_edges();
+ String s = header.to_lower();
if (s.length()==0)
- continue;
+ continue;
if (s.begins_with("content-length:")) {
body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int();
body_left=body_size;
}
if (s.begins_with("transfer-encoding:")) {
- String encoding = s.substr(s.find(":")+1,s.length()).strip_edges();
+ String encoding = header.substr(header.find(":")+1,header.length()).strip_edges();
//print_line("TRANSFER ENCODING: "+encoding);
if (encoding=="chunked") {
chunked=true;
@@ -330,7 +326,7 @@ Error HTTPClient::poll(){
response_num=num.to_int();
} else {
- response_headers.push_back(s);
+ response_headers.push_back(header);
}
}
diff --git a/core/io/http_client.h b/core/io/http_client.h
index e138681396..e795646c70 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -164,7 +164,7 @@ private:
public:
- Error connect_url(const String& p_url); //connects to a full url and perform request
+ //Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request
Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true);
void set_connection(const Ref<StreamPeer>& p_connection);
@@ -192,7 +192,7 @@ public:
Error poll();
- String query_string_from_dict(const Dictionary& p_dict);
+ String query_string_from_dict(const Dictionary& p_dict);
HTTPClient();
~HTTPClient();
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index aa641f00b4..05bad97e90 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -30,16 +30,16 @@
#include "print_string.h"
bool ImageFormatLoader::recognize(const String& p_extension) const {
-
-
+
+
List<String> extensions;
get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
-
+
if (E->get().nocasecmp_to(p_extension.extension())==0)
return true;
}
-
+
return false;
}
@@ -55,12 +55,12 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
return err;
}
}
-
+
String extension = p_file.extension();
for (int i=0;i<loader_count;i++) {
-
+
if (!loader[i]->recognize(extension))
continue;
Error err = loader[i]->load_image(p_image,f);
@@ -73,25 +73,25 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
return err;
}
-
-
+
+
}
print_line("NO LOADER?");
if (!p_custom)
- memdelete(f);
-
+ memdelete(f);
+
return ERR_FILE_UNRECOGNIZED;
}
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
-
+
for (int i=0;i<loader_count;i++) {
-
+
loader[i]->get_recognized_extensions(p_extensions);
-
- }
+
+ }
}
bool ImageLoader::recognize(const String& p_extension) {
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index 3cc6c6cf43..c799837792 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -41,11 +41,11 @@
/**
* @class ImageScanLineLoader
* @author Juan Linietsky <reduzio@gmail.com>
- *
-
+ *
+
*/
class ImageLoader;
-
+
/**
* @class ImageLoader
@@ -60,8 +60,8 @@ protected:
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
bool recognize(const String& p_extension) const;
-
-
+
+
public:
virtual ~ImageFormatLoader() {}
};
@@ -79,11 +79,11 @@ protected:
public:
-
+
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
static void get_recognized_extensions(List<String> *p_extensions) ;
static bool recognize(const String& p_extension) ;
-
+
static void add_image_format_loader(ImageFormatLoader *p_loader);
};
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index b8bd00c2fb..a77aace07f 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -49,7 +49,7 @@ struct _IP_ResolverPrivate {
response = IP_Address();
hostname="";
};
-
+
QueueItem() {
clear();
};
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 4dccf21d2d..1733aecd46 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -95,7 +95,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
str.parse_utf8((const char*)buf,strlen);
r_variant=str;
- if (r_len) {
+ if (r_len) {
if (strlen%4)
(*r_len)+=4-strlen%4;
(*r_len)+=4+strlen;
@@ -294,7 +294,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
} break;
case Variant::NODE_PATH: {
- ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
uint32_t strlen = decode_uint32(buf);
if (strlen&0x80000000) {
@@ -1077,7 +1077,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
r_len+=data.size()+5*4+pad;
- } break;
+ } break;
/*case Variant::RESOURCE: {
ERR_EXPLAIN("Can't marshallize resources");
@@ -1238,7 +1238,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
DVector<uint8_t> data = p_variant;
int datalen=data.size();
int datasize=sizeof(uint8_t);
-
+
if (buf) {
encode_uint32(datalen,buf);
buf+=4;
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index 7a5b16e8af..6a46e9882a 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -37,7 +37,7 @@
* Miscelaneous helpers for marshalling data types, and encoding
* in an endian independent way
*/
-
+
union MarshallFloat {
@@ -54,22 +54,22 @@ union MarshallDouble {
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
for (int i=0;i<2;i++) {
-
+
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
}
-
+
return sizeof( uint16_t );
}
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
for (int i=0;i<4;i++) {
-
+
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
}
-
+
return sizeof( uint32_t );
}
@@ -85,11 +85,11 @@ static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
for (int i=0;i<8;i++) {
-
+
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
}
-
+
return sizeof(uint64_t);
}
@@ -100,25 +100,25 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
encode_uint64( md.l, p_arr );
return sizeof(uint64_t);
-
+
}
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
int len=0;
-
+
while (*p_string) {
if (p_data) {
-
+
*p_data=(uint8_t)*p_string;
p_data++;
}
p_string++;
len++;
};
-
+
if (p_data) *p_data = 0;
return len+1;
}
@@ -126,35 +126,35 @@ static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
uint16_t u=0;
-
+
for (int i=0;i<2;i++) {
-
+
uint16_t b = *p_arr;
b<<=(i*8);
u|=b;
p_arr++;
}
-
+
return u;
}
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
uint32_t u=0;
-
+
for (int i=0;i<4;i++) {
-
+
uint32_t b = *p_arr;
b<<=(i*8);
u|=b;
p_arr++;
}
-
+
return u;
}
static inline float decode_float(const uint8_t *p_arr) {
-
+
MarshallFloat mf;
mf.i = decode_uint32(p_arr);
return mf.f;
@@ -163,15 +163,15 @@ static inline float decode_float(const uint8_t *p_arr) {
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
uint64_t u=0;
-
+
for (int i=0;i<8;i++) {
-
+
uint64_t b = (*p_arr)&0xFF;
b<<=(i*8);
u|=b;
p_arr++;
}
-
+
return u;
}
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 973a2ec9a5..22b8bc0b39 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -180,10 +180,10 @@ int PacketPeerStream::get_available_packet_count() const {
ring_buffer.copy(lbuf,ofs,4);
uint32_t len = decode_uint32(lbuf);
remaining-=4;
- ofs+=4;
+ ofs+=4;
if (len>remaining)
break;
- remaining-=len;
+ remaining-=len;
ofs+=len;
count++;
}
@@ -201,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
uint8_t lbuf[4];
ring_buffer.copy(lbuf,0,4);
remaining-=4;
- uint32_t len = decode_uint32(lbuf);
+ uint32_t len = decode_uint32(lbuf);
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index c008c3f9a4..58f3a4df2b 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -378,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
} break;
case OBJECT_INTERNAL_RESOURCE: {
uint32_t index=f->get_32();
- String path = res_path+"::"+itos(index);
+ String path = res_path+"::"+itos(index);
RES res = ResourceLoader::load(path);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
@@ -2100,7 +2100,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
p.value=E->get()->get(F->get().name);
if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) )
continue;
- p.pi=F->get();
+ p.pi=F->get();
rd.properties.push_back(p);
diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp
index 8c8d79948a..a42a922baf 100644
--- a/core/io/resource_format_xml.cpp
+++ b/core/io/resource_format_xml.cpp
@@ -1796,6 +1796,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
fw->store_8(c);
c=f->get_8();
}
+ f->close();
bool all_ok = fw->get_error()==OK;
@@ -1817,7 +1818,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
- error=OK;
+ error=OK;
lines=1;
f=p_f;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 67208b5960..abb1082256 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -49,16 +49,16 @@ Error ResourceInteractiveLoader::wait() {
bool ResourceFormatLoader::recognize(const String& p_extension) const {
-
-
+
+
List<String> extensions;
get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
-
+
if (E->get().nocasecmp_to(p_extension.extension())==0)
return true;
}
-
+
return false;
}
@@ -184,9 +184,9 @@ RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p
String extension=remapped_path.extension();
bool found=false;
-
+
for (int i=0;i<loader_count;i++) {
-
+
if (!loader[i]->recognize(extension))
continue;
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
@@ -356,7 +356,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
}
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) {
-
+
ERR_FAIL_COND( loader_count >= MAX_LOADERS );
loader[loader_count++]=p_format_loader;
}
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index fe58303066..6404e6cb13 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -47,7 +47,7 @@ public:
virtual Ref<Resource> get_resource()=0;
virtual Error poll()=0;
virtual int get_stage() const=0;
- virtual int get_stage_count() const=0;
+ virtual int get_stage_count() const=0;
virtual Error wait();
ResourceInteractiveLoader() {}
@@ -76,12 +76,12 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
-class ResourceLoader {
-
+class ResourceLoader {
+
enum {
MAX_LOADERS=64
};
-
+
static ResourceFormatLoader *loader[MAX_LOADERS];
static int loader_count;
static bool timestamp_on_load;
@@ -96,7 +96,7 @@ class ResourceLoader {
public:
-
+
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 51020a0285..8d78ecabbf 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -39,30 +39,30 @@ bool ResourceSaver::timestamp_on_save=false;
ResourceSavedCallback ResourceSaver::save_callback=0;
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
-
+
String extension=p_path.extension();
Error err=ERR_FILE_UNRECOGNIZED;
for (int i=0;i<saver_count;i++) {
-
+
if (!saver[i]->recognize(p_resource))
continue;
-
+
List<String> extensions;
bool recognized=false;
saver[i]->get_recognized_extensions(p_resource,&extensions);
-
+
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
-
+
if (E->get().nocasecmp_to(extension.extension())==0)
recognized=true;
}
if (!recognized)
continue;
-
+
String old_path=p_resource->get_path();
-
+
String local_path=Globals::get_singleton()->localize_path(p_path);
@@ -92,10 +92,10 @@ Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_
return OK;
} else {
-
+
}
}
-
+
return err;
}
@@ -108,16 +108,16 @@ void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) {
void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) {
-
+
for (int i=0;i<saver_count;i++) {
-
+
saver[i]->get_recognized_extensions(p_resource,p_extensions);
}
-
+
}
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) {
-
+
ERR_FAIL_COND( saver_count >= MAX_SAVERS );
saver[saver_count++]=p_format_saver;
}
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 7bc96c1087..97500c46f4 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -42,7 +42,7 @@
class ResourceFormatSaver {
public:
-
+
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
virtual bool recognize(const RES& p_resource) const=0;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
@@ -52,12 +52,12 @@ public:
typedef void (*ResourceSavedCallback)(const String& p_path);
-class ResourceSaver {
-
+class ResourceSaver {
+
enum {
MAX_SAVERS=64
};
-
+
static ResourceFormatSaver *saver[MAX_SAVERS];
static int saver_count;
static bool timestamp_on_save;
@@ -86,7 +86,7 @@ public:
static void set_save_callback(ResourceSavedCallback p_callback);
-
+
};
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index a7132d99ef..2114993783 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -4,12 +4,28 @@
StreamPeerSSL* (*StreamPeerSSL::_create)()=NULL;
+
+
StreamPeerSSL *StreamPeerSSL::create() {
return _create();
}
+
+StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func=NULL;
+bool StreamPeerSSL::available=false;
+bool StreamPeerSSL::initialize_certs=true;
+
+void StreamPeerSSL::load_certs_from_memory(const ByteArray& p_memory) {
+ if (load_certs_func)
+ load_certs_func(p_memory);
+}
+
+bool StreamPeerSSL::is_available() {
+ return available;
+}
+
void StreamPeerSSL::_bind_methods() {
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index be7504cd8f..4b1c8e93bb 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -5,11 +5,23 @@
class StreamPeerSSL : public StreamPeer {
OBJ_TYPE(StreamPeerSSL,StreamPeer);
+public:
+
+ typedef void (*LoadCertsFromMemory)(const ByteArray& p_certs);
protected:
static StreamPeerSSL* (*_create)();
static void _bind_methods();
+
+ static LoadCertsFromMemory load_certs_func;
+ static bool available;
+
+
+friend class Main;
+ static bool initialize_certs;
+
public:
+
enum Status {
STATUS_DISCONNECTED,
STATUS_CONNECTED,
@@ -25,6 +37,8 @@ public:
static StreamPeerSSL* create();
+ static void load_certs_from_memory(const ByteArray& p_memory);
+ static bool is_available();
StreamPeerSSL();
};
diff --git a/core/list.h b/core/list.h
index fbeb653da4..b989f009a9 100644
--- a/core/list.h
+++ b/core/list.h
@@ -245,7 +245,7 @@ public:
_data->first=n;
_data->size_cache++;
-
+
return n;
};
@@ -285,7 +285,7 @@ public:
_data->last=n;
_data->size_cache++;
-
+
return n;
};
@@ -363,30 +363,30 @@ public:
}
void swap(Element* p_A, Element *p_B) {
-
+
ERR_FAIL_COND(!p_A || !p_B);
ERR_FAIL_COND(p_A->data!=_data);
ERR_FAIL_COND(p_B->data!=_data);
-
+
Element* A_prev=p_A->prev_ptr;
Element* A_next=p_A->next_ptr;
-
+
p_A->next_ptr=p_B->next_ptr;
p_A->prev_ptr=p_B->prev_ptr;
-
+
p_B->next_ptr=A_next;
- p_B->prev_ptr=A_prev;
-
+ p_B->prev_ptr=A_prev;
+
if (p_A->prev_ptr)
p_A->prev_ptr->next_ptr=p_A;
if (p_A->next_ptr)
- p_A->next_ptr->prev_ptr=p_A;
-
+ p_A->next_ptr->prev_ptr=p_A;
+
if (p_B->prev_ptr)
p_B->prev_ptr->next_ptr=p_B;
if (p_B->next_ptr)
- p_B->next_ptr->prev_ptr=p_B;
-
+ p_B->next_ptr->prev_ptr=p_B;
+
}
/**
* copy the list
@@ -552,10 +552,10 @@ public:
*/
void sort() {
-
+
sort_custom< Comparator<T> >();
}
-
+
template<class C>
void sort_custom_inplace() {
@@ -565,44 +565,44 @@ public:
Element *from=front();
Element *current=from;
Element *to=from;
-
+
while(current) {
-
+
Element *next=current->next_ptr;
-
+
//disconnect
current->next_ptr=NULL;
-
+
if (from!=current) {
-
+
current->prev_ptr=NULL;
current->next_ptr=from;
-
+
Element *find=from;
C less;
while( find && less(find->value,current->value) ) {
-
+
current->prev_ptr=find;
current->next_ptr=find->next_ptr;
find=find->next_ptr;
}
-
+
if (current->prev_ptr)
current->prev_ptr->next_ptr=current;
else
from=current;
-
+
if (current->next_ptr)
current->next_ptr->prev_ptr=current;
else
to=current;
} else {
-
+
current->prev_ptr=NULL;
current->next_ptr=NULL;
-
+
}
-
+
current=next;
}
_data->first=from;
diff --git a/core/map.h b/core/map.h
index 35dc73df48..81cda1ece2 100644
--- a/core/map.h
+++ b/core/map.h
@@ -39,12 +39,12 @@
template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator>
class Map {
-
- enum Color {
+
+ enum Color {
RED,
BLACK
};
- struct _Data;
+ struct _Data;
public:
class Element {
@@ -66,34 +66,34 @@ public:
public:
const Element *next() const {
-
+
return _next;
}
Element *next() {
-
+
return _next;
}
const Element *prev() const {
-
+
return _prev;
}
Element *prev() {
-
+
return _prev;
}
- const K& key() const {
+ const K& key() const {
return _key;
};
- V& value() {
+ V& value() {
return _value;
};
- const V& value() const {
+ const V& value() const {
return _value;
};
- V& get() {
+ V& get() {
return _value;
};
- const V& get() const {
+ const V& get() const {
return _value;
};
Element() {
@@ -106,15 +106,15 @@ public:
};
};
-
+
private:
struct _Data {
-
+
Element* _root;
Element* _nil;
int size_cache;
-
+
_FORCE_INLINE_ _Data() {
#ifdef GLOBALNIL_DISABLED
_nil = memnew_allocator( Element, A );
@@ -126,7 +126,7 @@ private:
_root=NULL;
size_cache=0;
}
-
+
void _create_root() {
_root = memnew_allocator( Element,A );
@@ -145,23 +145,23 @@ private:
~_Data() {
_free_root();
-
+
#ifdef GLOBALNIL_DISABLED
memdelete_allocator<Element,A>(_nil);
#endif
// memdelete_allocator<Element,A>(_root);
}
};
-
+
_Data _data;
-
+
inline void _set_color(Element *p_node, int p_color) {
-
+
ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
p_node->color=p_color;
}
inline void _rotate_left(Element *p_node) {
-
+
Element *r=p_node->right;
p_node->right=r->left;
if (r->left != _data._nil )
@@ -171,14 +171,14 @@ private:
p_node->parent->left=r;
else
p_node->parent->right=r;
-
+
r->left=p_node;
p_node->parent=r;
-
+
}
-
+
inline void _rotate_right(Element *p_node) {
-
+
Element *l=p_node->left;
p_node->left=l->right;
if (l->right != _data._nil)
@@ -188,25 +188,25 @@ private:
p_node->parent->right=l;
else
p_node->parent->left=l;
-
+
l->right=p_node;
p_node->parent=l;
-
+
}
-
- inline Element* _successor(Element *p_node) const {
-
+
+ inline Element* _successor(Element *p_node) const {
+
Element *node=p_node;
-
+
if (node->right != _data._nil) {
-
+
node=node->right;
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
node=node->left;
}
return node;
} else {
-
+
while(node == node->parent->right) {
node=node->parent;
}
@@ -215,44 +215,44 @@ private:
return node->parent;
}
}
-
- inline Element* _predecessor(Element *p_node) const {
+
+ inline Element* _predecessor(Element *p_node) const {
Element *node=p_node;
-
+
if (node->left != _data._nil) {
-
+
node=node->left;
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
node=node->right;
}
return node;
} else {
-
+
while(node == node->parent->left) {
if (node->parent == _data._root)
- return NULL;
+ return NULL;
node=node->parent;
}
return node->parent;
}
}
-
-
+
+
Element *_find(const K& p_key) const {
-
+
Element *node = _data._root->left;
- C less;
-
+ C less;
+
while(node!=_data._nil) {
-
- if (less(p_key,node->_key))
+
+ if (less(p_key,node->_key))
node=node->left;
else if (less(node->_key,p_key))
node=node->right;
else
break; // found
}
-
+
return (node!=_data._nil)?node:NULL;
}
@@ -289,73 +289,73 @@ private:
}
Element *_insert(const K& p_key, bool& r_exists) {
-
+
Element *new_parent=_data._root;
Element *node = _data._root->left;
- C less;
-
+ C less;
+
while (node!=_data._nil) {
-
+
new_parent=node;
-
+
if (less(p_key,node->_key))
node=node->left;
else if (less(node->_key,p_key))
node=node->right;
- else {
+ else {
r_exists=true;
return node;
- }
+ }
}
-
+
Element *new_node = memnew_allocator( Element, A );
-
+
new_node->parent=new_parent;
new_node->right=_data._nil;
new_node->left=_data._nil;
new_node->_key=p_key;
//new_node->data=_data;
if (new_parent==_data._root || less(p_key,new_parent->_key)) {
-
+
new_parent->left=new_node;
} else {
new_parent->right=new_node;
}
-
+
r_exists=false;
-
+
new_node->_next=_successor(new_node);
new_node->_prev=_predecessor(new_node);
if (new_node->_next)
new_node->_next->_prev=new_node;
if (new_node->_prev)
new_node->_prev->_next=new_node;
-
+
return new_node;
}
-
+
Element * _insert_rb(const K& p_key, const V& p_value) {
-
+
bool exists=false;
Element *new_node = _insert(p_key,exists);
-
+
if (new_node) {
new_node->_value=p_value;
}
if (exists)
return new_node;
-
+
Element *node=new_node;
_data.size_cache++;
- while(node->parent->color==RED) {
-
+ while(node->parent->color==RED) {
+
if (node->parent == node->parent->parent->left) {
-
+
Element *aux=node->parent->parent->right;
-
+
if (aux->color==RED) {
_set_color(node->parent,BLACK);
_set_color(aux,BLACK);
@@ -369,10 +369,10 @@ private:
_set_color(node->parent,BLACK);
_set_color(node->parent->parent,RED);
_rotate_right(node->parent->parent);
- }
- } else {
+ }
+ } else {
Element *aux=node->parent->parent->left;
-
+
if (aux->color==RED) {
_set_color(node->parent,BLACK);
_set_color(aux,BLACK);
@@ -386,19 +386,19 @@ private:
_set_color(node->parent,BLACK);
_set_color(node->parent->parent,RED);
_rotate_left(node->parent->parent);
- }
+ }
}
}
_set_color(_data._root->left,BLACK);
- return new_node;
- }
+ return new_node;
+ }
void _erase_fix(Element *p_node) {
-
+
Element *root = _data._root->left;
Element *node=p_node;
-
-
+
+
while( (node->color==BLACK) && (root != node)) {
if (node == node->parent->left) {
Element *aux=node->parent->right;
@@ -408,7 +408,7 @@ private:
_rotate_left(node->parent);
aux=node->parent->right;
}
- if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
+ if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
_set_color(aux,RED);
node=node->parent;
} else {
@@ -432,7 +432,7 @@ private:
_rotate_right(node->parent);
aux=node->parent->left;
}
- if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
+ if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
_set_color(aux,RED);
node=node->parent;
} else {
@@ -446,24 +446,24 @@ private:
_set_color(node->parent,BLACK);
_set_color(aux->left,BLACK);
_rotate_right(node->parent);
- node=root;
+ node=root;
}
}
}
-
+
_set_color(node,BLACK);
-
+
ERR_FAIL_COND(_data._nil->color!=BLACK);
}
-
+
void _erase(Element *p_node) {
-
-
+
+
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
if (!rp)
rp=_data._nil;
Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
-
+
if (_data._root == (node->parent=rp->parent) ) {
_data._root->left=node;
} else {
@@ -473,47 +473,47 @@ private:
rp->parent->right=node;
}
}
-
- if (rp != p_node) {
-
+
+ if (rp != p_node) {
+
ERR_FAIL_COND( rp == _data._nil );
-
+
if (rp->color==BLACK)
_erase_fix(node);
-
-
+
+
rp->left=p_node->left;
rp->right=p_node->right;
rp->parent=p_node->parent;
rp->color=p_node->color;
p_node->left->parent=rp;
p_node->right->parent=rp;
-
+
if (p_node == p_node->parent->left) {
- p_node->parent->left=rp;
+ p_node->parent->left=rp;
} else {
p_node->parent->right=rp;
}
} else {
- if (p_node->color==BLACK)
+ if (p_node->color==BLACK)
_erase_fix(node);
-
+
}
-
-
+
+
if (p_node->_next)
p_node->_next->_prev=p_node->_prev;
if (p_node->_prev)
p_node->_prev->_next=p_node->_next;
-
+
memdelete_allocator<Element,A>(p_node);
_data.size_cache--;
ERR_FAIL_COND( _data._nil->color==RED );
}
-
-
+
+
void _calculate_depth(Element *p_element,int &max_d,int d) const {
-
+
if (p_element==_data._nil) {
return;
}
@@ -522,23 +522,23 @@ private:
if (d>max_d)
max_d=d;
}
-
+
void _cleanup_tree(Element *p_element) {
-
+
if (p_element==_data._nil)
return;
-
+
_cleanup_tree(p_element->left);
_cleanup_tree(p_element->right);
memdelete_allocator<Element,A>( p_element );
}
-
+
void _copy_from( const Map& p_map) {
-
+
clear();
// not the fastest way, but safeset to write.
for(Element *I=p_map.front();I;I=I->next()) {
-
+
insert(I->key(),I->value());
}
}
@@ -554,7 +554,7 @@ public:
}
Element *find(const K& p_key) {
-
+
if (!_data._root)
return NULL;
Element *res=_find(p_key);
@@ -578,15 +578,15 @@ public:
}
Element *insert(const K& p_key,const V& p_value) {
-
+
if (!_data._root)
_data._create_root();
return _insert_rb(p_key,p_value);
-
+
}
-
+
void erase(Element* p_element) {
-
+
if (!_data._root)
return;
_erase(p_element);
@@ -595,72 +595,72 @@ public:
}
bool erase(const K& p_key) {
-
+
if (!_data._root)
return false;
Element *e=find(p_key);
if (!e)
return false;
- _erase(e);
+ _erase(e);
return true;
}
-
+
bool has(const K& p_key) const {
-
+
if (!_data._root)
return false;
return find(p_key) != NULL;
}
-
+
const V& operator[](const K& p_key) const {
-
+
ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
const Element *e=find(p_key);
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
return e->_value;
}
V& operator[](const K& p_key) {
-
+
if (!_data._root)
_data._create_root();
Element *e=find(p_key);
if (!e)
e=insert(p_key,V());
-
- ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
+
+ ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
return e->_value;
}
-
+
Element *front() const {
-
+
if (!_data._root)
return NULL;
Element *e=_data._root->left;
if (e==_data._nil)
return NULL;
-
+
while(e->left!=_data._nil)
e=e->left;
-
+
return e;
}
-
+
Element *back() const {
-
+
if (!_data._root)
return NULL;
Element *e=_data._root->left;
if (e==_data._nil)
return NULL;
-
+
while(e->right!=_data._nil)
e=e->right;
-
+
return e;
}
-
+
inline bool empty() const { return _data.size_cache==0; }
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
@@ -671,9 +671,9 @@ public:
_calculate_depth(_data._root->left,max_d,0);
return max_d;
}
-
+
void clear() {
-
+
if (!_data._root)
return;
_cleanup_tree(_data._root->left);
@@ -682,25 +682,25 @@ public:
_data._nil->parent=_data._nil;
_data._free_root();
}
-
+
void operator=(const Map& p_map) {
-
+
_copy_from( p_map );
}
-
+
Map(const Map& p_map) {
-
+
_copy_from( p_map );
}
_FORCE_INLINE_ Map() {
-
+
}
-
-
+
+
~Map() {
-
- clear();
+
+ clear();
}
};
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 7c9c3081ac..57fe1b32f5 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -47,25 +47,26 @@ public:
float get_area() const; /// get area
_FORCE_INLINE_ bool has_no_area() const {
-
+
return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON);
}
_FORCE_INLINE_ bool has_no_surface() const {
-
+
return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON);
}
-
+
const Vector3& get_pos() const { return pos; }
void set_pos(const Vector3& p_pos) { pos=p_pos; }
const Vector3& get_size() const { return size; }
void set_size(const Vector3& p_size) { size=p_size; }
-
+
bool operator==(const AABB& p_rval) const;
bool operator!=(const AABB& p_rval) const;
_FORCE_INLINE_ bool intersects(const AABB& p_aabb) const; /// Both AABBs overlap
+ _FORCE_INLINE_ bool intersects_inclusive(const AABB& p_aabb) const; /// Both AABBs (or their faces) overlap
_FORCE_INLINE_ bool encloses(const AABB & p_aabb) const; /// p_aabb is completely inside this
AABB merge(const AABB& p_with) const;
@@ -126,6 +127,23 @@ inline bool AABB::intersects(const AABB& p_aabb) const {
return true;
}
+inline bool AABB::intersects_inclusive(const AABB& p_aabb) const {
+
+ if ( pos.x > (p_aabb.pos.x + p_aabb.size.x) )
+ return false;
+ if ( (pos.x+size.x) < p_aabb.pos.x )
+ return false;
+ if ( pos.y > (p_aabb.pos.y + p_aabb.size.y) )
+ return false;
+ if ( (pos.y+size.y) < p_aabb.pos.y )
+ return false;
+ if ( pos.z > (p_aabb.pos.z + p_aabb.size.z) )
+ return false;
+ if ( (pos.z+size.z) < p_aabb.pos.z )
+ return false;
+
+ return true;
+}
inline bool AABB::encloses(const AABB & p_aabb) const {
@@ -247,7 +265,7 @@ bool AABB::has_point(const Vector3& p_point) const {
return false;
if (p_point.z>pos.z+size.z)
return false;
-
+
return true;
}
@@ -279,11 +297,11 @@ void AABB::project_range_in_plane(const Plane& p_plane,float &r_min,float& r_max
Vector3 half_extents( size.x * 0.5, size.y * 0.5, size.z * 0.5 );
Vector3 center( pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z );
-
+
float length = p_plane.normal.abs().dot(half_extents);
float distance = p_plane.distance_to( center );
r_min = distance - length;
- r_max = distance + length;
+ r_max = distance + length;
}
inline real_t AABB::get_longest_axis_size() const {
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index 0c07b733f0..d16495217c 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -66,12 +66,12 @@ Vector<Plane> BSP_Tree::get_planes() const {
return planes;
}
-
+
AABB BSP_Tree::get_aabb() const {
return aabb;
}
-
+
int BSP_Tree::_get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const {
@@ -245,22 +245,22 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
if (!aabb.has_point(p_point)) {
return false;
}
-
+
int node_count=nodes.size();
-
+
if (node_count==0) // no nodes!
return false;
-
-
+
+
const Node *nodesptr=&nodes[0];
const Plane *planesptr=&planes[0];
int plane_count=planes.size();
-
+
int idx=node_count-1;
int steps=0;
-
+
while(true) {
-
+
if (idx==OVER_LEAF) {
return false;
}
@@ -268,28 +268,28 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
return true;
}
-
+
uint16_t plane=nodesptr[ idx ].plane;
#ifdef DEBUG_ENABLED
-
+
ERR_FAIL_INDEX_V( plane, plane_count, false );
#endif
bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point);
idx = over ? nodes[ idx ].over : nodes[ idx ].under;
-
+
#ifdef DEBUG_ENABLED
-
+
ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false );
#endif
-
+
steps++;
}
return false;
}
-
-
+
+
static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) {
int ic = p_indices.size();
@@ -304,7 +304,7 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
const Face3& f=p_faces[ indices[i] ];
Plane p = f.get_plane();
-
+
int num_over=0,num_under=0,num_spanning=0;
for(int j=0;j<ic;j++) {
@@ -335,17 +335,17 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
num_over++;
else
num_under++;
-
+
}
//double split_cost = num_spanning / (double) face_count;
double relation = Math::abs(num_over-num_under) / (double) ic;
-
+
// being honest, i never found a way to add split cost to the mix in a meaninguful way
// in this engine, also, will likely be ignored anyway
-
+
double plane_cost = /*split_cost +*/ relation;
//printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
@@ -360,10 +360,10 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
return best_plane;
}
-
+
static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes,float p_tolerance) {
-
+
ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 );
// should not reach here
@@ -387,7 +387,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
if (i==divisor_idx)
continue;
-
+
const Face3& f=p_faces[ indices[i] ];
//if (f.get_plane().is_almost_like(divisor_plane))
@@ -416,7 +416,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
}
-
+
uint16_t over_idx=BSP_Tree::OVER_LEAF,under_idx=BSP_Tree::UNDER_LEAF;
if (faces_over.size()>0) { //have facess above?
@@ -434,13 +434,13 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
}
/* Create the node */
-
+
// find existing divisor plane
int divisor_plane_idx=-1;
-
-
+
+
for (int i=0;i<p_planes.size();i++) {
-
+
if (p_planes[i].is_almost_like( divisor_plane )) {
divisor_plane_idx=i;
break;
@@ -448,22 +448,22 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
}
if (divisor_plane_idx==-1) {
-
+
ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 );
divisor_plane_idx=p_planes.size();
p_planes.push_back( divisor_plane );
}
-
+
BSP_Tree::Node node;
node.plane=divisor_plane_idx;
node.under=under_idx;
node.over=over_idx;
-
+
p_nodes.push_back(node);
-
+
return p_nodes.size()-1;
}
-
+
BSP_Tree::operator Variant() const {
@@ -563,7 +563,7 @@ BSP_Tree::BSP_Tree(const Variant& p_variant) {
BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
// compute aabb
-
+
int face_count=p_faces.size();
DVector<Face3>::Read faces_r=p_faces.read();
const Face3 *facesptr = faces_r.ptr();
@@ -574,26 +574,26 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
Vector<int> indices;
for (int i=0;i<face_count;i++) {
-
+
const Face3& f=facesptr[i];
-
+
if (f.is_degenerate())
continue;
-
+
for (int j=0;j<3;j++) {
-
+
if (first) {
-
+
aabb.pos=f.vertex[0];
first=false;
} else {
-
+
aabb.expand_to(f.vertex[j]);
}
}
indices.push_back(i);
-
+
}
ERR_FAIL_COND( aabb.has_no_area() );
@@ -609,7 +609,7 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
-
+
error_radius=p_error_radius;
}
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
index a7145f9ff1..2bfc26b51e 100644
--- a/core/math/bsp_tree.h
+++ b/core/math/bsp_tree.h
@@ -43,7 +43,7 @@ class BSP_Tree {
public:
enum {
-
+
UNDER_LEAF=0xFFFF,
OVER_LEAF=0xFFFE,
MAX_NODES=0xFFFE,
@@ -51,22 +51,22 @@ public:
};
struct Node {
-
+
uint16_t plane;
uint16_t under;
uint16_t over;
};
-
-private:
- // thanks to the properties of Vector,
+
+private:
+ // thanks to the properties of Vector,
// this class can be assigned and passed around between threads
// with no cost.
-
+
Vector<Node> nodes;
Vector<Plane> planes;
AABB aabb;
- float error_radius;
+ float error_radius;
int _get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const;
@@ -79,8 +79,8 @@ public:
Vector<Node> get_nodes() const;
Vector<Plane> get_planes() const;
AABB get_aabb() const;
-
- bool point_is_inside(const Vector3& p_point) const;
+
+ bool point_is_inside(const Vector3& p_point) const;
int get_points_inside(const Vector3* p_points, int p_point_count) const;
template<class T>
bool convex_is_inside(const T& p_convex) const;
@@ -91,8 +91,8 @@ public:
BSP_Tree();
BSP_Tree(const Variant& p_variant);
- BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
- BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
+ BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
+ BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
~BSP_Tree();
};
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 61c8b78e0a..f7dd8839b8 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -33,9 +33,9 @@
void CameraMatrix::set_identity() {
for (int i=0;i<4;i++) {
-
+
for (int j=0;j<4;j++) {
-
+
matrix[i][j]=(i==j)?1:0;
}
}
@@ -90,7 +90,7 @@ void CameraMatrix::set_perspective(float p_fovy_degrees, float p_aspect, float p
matrix[2][2] = -(p_z_far + p_z_near) / deltaZ;
matrix[2][3] = -1;
matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ;
- matrix[3][3] = 0;
+ matrix[3][3] = 0;
}
@@ -155,95 +155,95 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa
float CameraMatrix::get_z_far() const {
-
- const float * matrix = (const float*)this->matrix;
+
+ const float * matrix = (const float*)this->matrix;
Plane new_plane=Plane(matrix[ 3] - matrix[ 2],
matrix[ 7] - matrix[ 6],
matrix[11] - matrix[10],
matrix[15] - matrix[14]);
-
+
new_plane.normal=-new_plane.normal;
new_plane.normalize();
-
+
return new_plane.d;
}
float CameraMatrix::get_z_near() const {
-
- const float * matrix = (const float*)this->matrix;
+
+ const float * matrix = (const float*)this->matrix;
Plane new_plane=Plane(matrix[ 3] + matrix[ 2],
matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10],
-matrix[15] - matrix[14]);
-
+
new_plane.normalize();
return new_plane.d;
}
void CameraMatrix::get_viewport_size(float& r_width, float& r_height) const {
- const float * matrix = (const float*)this->matrix;
+ const float * matrix = (const float*)this->matrix;
///////--- Near Plane ---///////
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10],
-matrix[15] - matrix[14]).normalized();
-
+
///////--- Right Plane ---///////
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
matrix[ 7] - matrix[ 4],
matrix[11] - matrix[ 8],
- matrix[15] + matrix[12]).normalized();
-
+
Plane top_plane=Plane(matrix[ 3] - matrix[ 1],
matrix[ 7] - matrix[ 5],
matrix[11] - matrix[ 9],
-matrix[15] + matrix[13]).normalized();
-
+
Vector3 res;
near_plane.intersect_3(right_plane,top_plane,&res);
-
+
r_width=res.x;
r_height=res.y;
}
bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8points) const {
- const float * matrix = (const float*)this->matrix;
-
+ const float * matrix = (const float*)this->matrix;
+
///////--- Near Plane ---///////
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10],
-matrix[15] - matrix[14]).normalized();
-
+
///////--- Far Plane ---///////
Plane far_plane=Plane(matrix[ 2] - matrix[ 3],
matrix[ 6] - matrix[ 7],
matrix[10] - matrix[11],
matrix[15] - matrix[14]).normalized();
-
+
///////--- Right Plane ---///////
Plane right_plane=Plane(matrix[ 0] - matrix[ 3],
matrix[ 4] - matrix[ 7],
matrix[8] - matrix[ 11],
- matrix[15] + matrix[12]).normalized();
-
- ///////--- Top Plane ---///////
+
+ ///////--- Top Plane ---///////
Plane top_plane=Plane(matrix[ 1] - matrix[ 3],
matrix[ 5] - matrix[ 7],
matrix[9] - matrix[ 11],
-matrix[15] + matrix[13]).normalized();
-
+
Vector3 near_endpoint;
Vector3 far_endpoint;
-
+
bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint);
ERR_FAIL_COND_V(!res,false);
-
+
res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint);
ERR_FAIL_COND_V(!res,false);
-
+
p_8points[0]=p_transform.xform( Vector3( near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
p_8points[1]=p_transform.xform( Vector3( near_endpoint.x,-near_endpoint.y, near_endpoint.z ) );
p_8points[2]=p_transform.xform( Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
@@ -252,7 +252,7 @@ bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8point
p_8points[5]=p_transform.xform( Vector3( far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
p_8points[6]=p_transform.xform( Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z ) );
p_8points[7]=p_transform.xform( Vector3(-far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
-
+
return true;
}
@@ -263,10 +263,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
* http://www.markmorley.com/opengl/frustumculling.html
* http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
*/
-
+
Vector<Plane> planes;
-
- const float * matrix = (const float*)this->matrix;
+
+ const float * matrix = (const float*)this->matrix;
Plane new_plane;
@@ -275,7 +275,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10],
matrix[15] + matrix[14]);
-
+
new_plane.normal=-new_plane.normal;
new_plane.normalize();
@@ -298,7 +298,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[ 7] + matrix[ 4],
matrix[11] + matrix[ 8],
matrix[15] + matrix[12]);
-
+
new_plane.normal=-new_plane.normal;
new_plane.normalize();
@@ -310,8 +310,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[ 7] - matrix[ 5],
matrix[11] - matrix[ 9],
matrix[15] - matrix[13]);
-
-
+
+
new_plane.normal=-new_plane.normal;
new_plane.normalize();
@@ -324,10 +324,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[11] - matrix[ 8],
matrix[15] - matrix[12]);
-
+
new_plane.normal=-new_plane.normal;
new_plane.normalize();
-
+
planes.push_back( p_transform.xform(new_plane) );
@@ -337,12 +337,12 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[11] + matrix[ 9],
matrix[15] + matrix[13]);
-
+
new_plane.normal=-new_plane.normal;
new_plane.normalize();
planes.push_back( p_transform.xform(new_plane) );
-
+
return planes;
}
@@ -356,7 +356,7 @@ CameraMatrix CameraMatrix::inverse() const {
}
void CameraMatrix::invert() {
-
+
int i,j,k;
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
float pvt_val; /* Value of current pivot element */
@@ -448,7 +448,7 @@ void CameraMatrix::invert() {
}
}
-
+
}
CameraMatrix::CameraMatrix() {
@@ -475,31 +475,31 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix& p_matrix) const {
void CameraMatrix::set_light_bias() {
float *m=&matrix[0][0];
-
- m[0]=0.5,
- m[1]=0.0,
- m[2]=0.0,
+
+ m[0]=0.5,
+ m[1]=0.0,
+ m[2]=0.0,
m[3]=0.0,
- m[4]=0.0,
- m[5]=0.5,
- m[6]=0.0,
+ m[4]=0.0,
+ m[5]=0.5,
+ m[6]=0.0,
m[7]=0.0,
- m[8]=0.0,
- m[9]=0.0,
- m[10]=0.5,
+ m[8]=0.0,
+ m[9]=0.0,
+ m[10]=0.5,
m[11]=0.0,
- m[12]=0.5,
- m[13]=0.5,
- m[14]=0.5,
- m[15]=1.0;
-
+ m[12]=0.5,
+ m[13]=0.5,
+ m[14]=0.5,
+ m[15]=1.0;
+
}
CameraMatrix::operator String() const {
String str;
- for (int i=0;i<4;i++)
- for (int j=0;j<4;j++)
+ for (int i=0;i<4;i++)
+ for (int j=0;j<4;j++)
str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]);
return str;
@@ -513,7 +513,7 @@ float CameraMatrix::get_aspect() const {
}
float CameraMatrix::get_fov() const {
- const float * matrix = (const float*)this->matrix;
+ const float * matrix = (const float*)this->matrix;
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
matrix[ 7] - matrix[ 4],
@@ -588,7 +588,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
const Transform &tr = p_transform;
float *m=&matrix[0][0];
-
+
m[0]=tr.basis.elements[0][0];
m[1]=tr.basis.elements[1][0];
m[2]=tr.basis.elements[2][0];
@@ -604,7 +604,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
m[12]=tr.origin.x;
m[13]=tr.origin.y;
m[14]=tr.origin.z;
- m[15]=1.0;
+ m[15]=1.0;
}
CameraMatrix::~CameraMatrix()
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 27500a545e..d192b1fef1 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -48,8 +48,8 @@ struct CameraMatrix {
};
float matrix[4][4];
-
-
+
+
void set_identity();
void set_zero();
void set_light_bias();
@@ -67,12 +67,12 @@ struct CameraMatrix {
float get_z_near() const;
float get_aspect() const;
float get_fov() const;
-
+
Vector<Plane> get_projection_planes(const Transform& p_transform) const;
-
+
bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const;
void get_viewport_size(float& r_width, float& r_height) const;
-
+
void invert();
CameraMatrix inverse() const;
@@ -80,15 +80,15 @@ struct CameraMatrix {
Plane xform4(const Plane& p_vec4);
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
-
+
operator String() const;
void scale_translate_to_fit(const AABB& p_aabb);
void make_scale(const Vector3 &p_scale);
operator Transform() const;
- CameraMatrix();
- CameraMatrix(const Transform& p_transform);
+ CameraMatrix();
+ CameraMatrix(const Transform& p_transform);
~CameraMatrix();
};
diff --git a/core/math/face3.h b/core/math/face3.h
index c36fdd1332..bc34be9935 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -55,7 +55,7 @@ public:
* @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
* @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
*/
-
+
int split_by_plane(const Plane& p_plane,Face3 *p_res,bool *p_is_point_over) const;
Plane get_plane(ClockDirection p_dir=CLOCKWISE) const;
@@ -77,7 +77,7 @@ public:
void get_support(const Vector3& p_normal,const Transform& p_transform,Vector3 *p_vertices,int* p_count,int p_max) const;
void project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const;
-
+
AABB get_aabb() const {
AABB aabb( vertex[0], Vector3() );
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 2905d26fe5..5b767212f5 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -211,7 +211,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
int len = p_array.size();
DVector<Face3>::Read r=p_array.read();
-
+
const Face3* arrayptr = r.ptr();
DVector< _FaceClassify> fc;
@@ -219,7 +219,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
fc.resize( len );
DVector< _FaceClassify >::Write fcw=fc.write();
-
+
_FaceClassify * _fcptr = fcw.ptr();
for (int i=0;i<len;i++) {
@@ -278,7 +278,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
/*** GEOMETRY WRAPPER ***/
enum _CellFlags {
-
+
_CELL_SOLID=1,
_CELL_EXTERIOR=2,
_CELL_STEP_MASK=0x1C,
@@ -299,7 +299,7 @@ enum _CellFlags {
_CELL_PREV_Z_POS=5<<5,
_CELL_PREV_Z_NEG=6<<5,
_CELL_PREV_FIRST=7<<5,
-
+
};
static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) {
@@ -316,9 +316,9 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
p_cell_status[x][y][z]=_CELL_SOLID;
return;
}
-
-
-
+
+
+
int div_x=len_x>1?2:1;
int div_y=len_y>1?2:1;
int div_z=len_z>1?2:1;
@@ -343,14 +343,14 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
int new_len_z;
for (int i=0;i<div_x;i++) {
-
-
+
+
_SPLIT(i,div_x,x,len_x,new_x,new_len_x);
-
+
for (int j=0;j<div_y;j++) {
_SPLIT(j,div_y,y,len_y,new_y,new_len_y);
-
+
for (int k=0;k<div_z;k++) {
_SPLIT(k,div_z,z,len_z,new_z,new_len_z);
@@ -365,39 +365,39 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
if (p_cell_status[x][y][z]&3)
return; // nothing to do, already used and/or visited
-
+
p_cell_status[x][y][z]=_CELL_PREV_FIRST;
-
+
while(true) {
-
+
uint8_t &c = p_cell_status[x][y][z];
-
+
//printf("at %i,%i,%i\n",x,y,z);
-
- if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
+
+ if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
/* Haven't been in here, mark as outside */
p_cell_status[x][y][z]|=_CELL_EXTERIOR;
//printf("not marked as anything, marking exterior\n");
}
-
+
//printf("cell step is %i\n",(c&_CELL_STEP_MASK));
-
+
if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
/* if not done, increase step */
c+=1<<2;
//printf("incrementing cell step\n");
}
-
+
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
/* Go back */
//printf("done, going back a cell\n");
-
+
switch(c&_CELL_PREV_MASK) {
case _CELL_PREV_FIRST: {
- //printf("at end, finished marking\n");
+ //printf("at end, finished marking\n");
return;
} break;
- case _CELL_PREV_Y_POS: {
+ case _CELL_PREV_Y_POS: {
y++;
ERR_FAIL_COND(y>=len_y);
} break;
@@ -427,16 +427,16 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
}
continue;
}
-
+
//printf("attempting new cell!\n");
-
+
int next_x=x,next_y=y,next_z=z;
uint8_t prev=0;
-
+
switch(c&_CELL_STEP_MASK) {
-
+
case _CELL_STEP_Y_POS: {
-
+
next_y++;
prev=_CELL_PREV_Y_NEG;
} break;
@@ -454,32 +454,32 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
} break;
case _CELL_STEP_Z_POS: {
next_z++;
- prev=_CELL_PREV_Z_NEG;
+ prev=_CELL_PREV_Z_NEG;
} break;
case _CELL_STEP_Z_NEG: {
next_z--;
- prev=_CELL_PREV_Z_POS;
+ prev=_CELL_PREV_Z_POS;
} break;
- default: ERR_FAIL();
-
+ default: ERR_FAIL();
+
}
-
+
//printf("testing if new cell will be ok...!\n");
-
+
if (next_x<0 || next_x>=len_x)
continue;
if (next_y<0 || next_y>=len_y)
continue;
if (next_z<0 || next_z>=len_z)
continue;
-
+
//printf("testing if new cell is traversable\n");
-
+
if (p_cell_status[next_x][next_y][next_z]&3)
continue;
-
+
//printf("move to it\n");
-
+
x=next_x;
y=next_y;
z=next_z;
@@ -488,14 +488,14 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
}
static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) {
-
+
ERR_FAIL_INDEX(x,len_x);
ERR_FAIL_INDEX(y,len_y);
ERR_FAIL_INDEX(z,len_z);
-
+
if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
- return;
-
+ return;
+
/* static const Vector3 vertices[8]={
Vector3(0,0,0),
Vector3(0,0,1),
@@ -510,73 +510,73 @@ static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int l
#define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 )
static const uint8_t indices[6][4]={
- {7,6,4,5},
+ {7,6,4,5},
{7,3,2,6},
- {7,5,1,3},
- {0,2,3,1},
- {0,1,5,4},
+ {7,5,1,3},
+ {0,2,3,1},
+ {0,1,5,4},
{0,4,6,2},
};
-/*
+/*
- {0,1,2,3},
- {0,1,4,5},
+ {0,1,2,3},
+ {0,1,4,5},
{0,2,4,6},
- {4,5,6,7},
+ {4,5,6,7},
{2,3,7,6},
- {1,3,5,7},
+ {1,3,5,7},
- {0,2,3,1},
- {0,1,5,4},
+ {0,2,3,1},
+ {0,1,5,4},
{0,4,6,2},
- {7,6,4,5},
+ {7,6,4,5},
{7,3,2,6},
- {7,5,1,3},
+ {7,5,1,3},
*/
-
+
for (int i=0;i<6;i++) {
-
+
Vector3 face_points[4];
int disp_x=x+((i%3)==0?((i<3)?1:-1):0);
int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0);
int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
-
+
bool plot=false;
-
+
if (disp_x<0 || disp_x>=len_x)
plot=true;
if (disp_y<0 || disp_y>=len_y)
plot=true;
if (disp_z<0 || disp_z>=len_z)
plot=true;
-
+
if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
plot=true;
-
+
if (!plot)
continue;
-
+
for (int j=0;j<4;j++)
face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
-
- p_faces.push_back(
- Face3(
+
+ p_faces.push_back(
+ Face3(
face_points[0],
face_points[1],
face_points[2]
)
);
-
- p_faces.push_back(
- Face3(
+
+ p_faces.push_back(
+ Face3(
face_points[2],
face_points[3],
face_points[0]
)
);
-
- }
+
+ }
}
@@ -601,7 +601,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
global_aabb.merge_with( faces[i].get_aabb() );
}
}
-
+
global_aabb.grow_by(0.01); // avoid numerical error
// determine amount of cells in grid axis
@@ -649,7 +649,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
// plot faces into cells
print_line("Wrapper (1/6): Plotting Faces");
-
+
for (int i=0;i<face_count;i++) {
Face3 f=faces[i];
@@ -666,68 +666,68 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
print_line("Wrapper (2/6) Flood Filling");
for (int i=0;i<div_x;i++) {
-
+
for (int j=0;j<div_y;j++) {
-
+
_mark_outside(cell_status,i,j,0,div_x,div_y,div_z);
_mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z);
}
}
-
+
for (int i=0;i<div_z;i++) {
-
+
for (int j=0;j<div_y;j++) {
-
+
_mark_outside(cell_status,0,j,i,div_x,div_y,div_z);
_mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z);
}
}
-
+
for (int i=0;i<div_x;i++) {
-
+
for (int j=0;j<div_z;j++) {
-
+
_mark_outside(cell_status,i,0,j,div_x,div_y,div_z);
_mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z);
}
}
-
+
// build faces for the inside-outside cell divisors
-
+
print_line("Wrapper (3/6): Building Faces");
DVector<Face3> wrapped_faces;
-
+
for (int i=0;i<div_x;i++) {
-
+
for (int j=0;j<div_y;j++) {
-
+
for (int k=0;k<div_z;k++) {
-
- _build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
+
+ _build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
}
}
}
-
+
print_line("Wrapper (4/6): Transforming Back Vertices");
// transform face vertices to global coords
-
+
int wrapped_faces_count=wrapped_faces.size();
DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
-
+
for(int i=0;i<wrapped_faces_count;i++) {
-
+
for(int j=0;j<3;j++) {
-
+
Vector3& v = wrapped_faces_ptr[i].vertex[j];
v=v*voxelsize;
v+=global_aabb.pos;
}
}
-
- // clean up grid
+
+ // clean up grid
print_line("Wrapper (5/6): Grid Cleanup");
for(int i=0;i<div_x;i++) {
@@ -736,14 +736,14 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
memdelete_arr( cell_status[i][j] );
}
-
+
memdelete_arr( cell_status[i] );
}
-
+
memdelete_arr(cell_status);
if (p_error)
*p_error=voxelsize.length();
-
+
print_line("Wrapper (6/6): Finished.");
return wrapped_faces;
}
@@ -751,67 +751,67 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
MeshData mesh;
-
-
+
+
#define SUBPLANE_SIZE 1024.0
-
+
float subplane_size = 1024.0; // should compute this from the actual plane
for (int i=0;i<p_planes.size();i++) {
-
+
Plane p =p_planes[i];
-
+
Vector3 ref=Vector3(0.0,1.0,0.0);
-
+
if (ABS(p.normal.dot(ref))>0.95)
ref=Vector3(0.0,0.0,1.0); // change axis
-
+
Vector3 right = p.normal.cross(ref).normalized();
Vector3 up = p.normal.cross( right ).normalized();
-
+
Vector< Vector3 > vertices;
-
+
Vector3 center = p.get_any_point();
// make a quad clockwise
vertices.push_back( center - up * subplane_size + right * subplane_size );
vertices.push_back( center - up * subplane_size - right * subplane_size );
vertices.push_back( center + up * subplane_size - right * subplane_size );
vertices.push_back( center + up * subplane_size + right * subplane_size );
-
+
for (int j=0;j<p_planes.size();j++) {
if (j==i)
continue;
-
+
Vector< Vector3 > new_vertices;
Plane clip=p_planes[j];
-
+
if (clip.normal.dot(p.normal)>0.95)
continue;
-
+
if (vertices.size()<3)
break;
-
+
for(int k=0;k<vertices.size();k++) {
-
+
int k_n=(k+1)%vertices.size();
-
+
Vector3 edge0_A=vertices[k];
Vector3 edge1_A=vertices[k_n];
-
+
real_t dist0 = clip.distance_to(edge0_A);
real_t dist1 = clip.distance_to(edge1_A);
-
-
- if ( dist0 <= 0 ) { // behind plane
-
- new_vertices.push_back(vertices[k]);
+
+
+ if ( dist0 <= 0 ) { // behind plane
+
+ new_vertices.push_back(vertices[k]);
}
-
-
+
+
// check for different sides and non coplanar
- if ( (dist0*dist1) < 0) {
-
+ if ( (dist0*dist1) < 0) {
+
// calculate intersection
Vector3 rel = edge1_A - edge0_A;
@@ -822,55 +822,55 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den;
Vector3 inters = edge0_A+rel*dist;
new_vertices.push_back(inters);
- }
+ }
}
-
+
vertices=new_vertices;
}
-
+
if (vertices.size()<3)
continue;
-
-
+
+
//result is a clockwise face
-
+
MeshData::Face face;
-
+
// add face indices
for (int j=0;j<vertices.size();j++) {
-
-
+
+
int idx=-1;
for (int k=0;k<mesh.vertices.size();k++) {
-
+
if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
-
+
idx=k;
break;
}
}
-
+
if (idx==-1) {
-
+
idx=mesh.vertices.size();
mesh.vertices.push_back(vertices[j]);
}
-
+
face.indices.push_back(idx);
}
face.plane=p;
mesh.faces.push_back(face);
-
+
//add edge
-
+
for(int j=0;j<face.indices.size();j++) {
-
+
int a=face.indices[j];
int b=face.indices[(j+1)%face.indices.size()];
-
+
bool found=false;
for(int k=0;k<mesh.edges.size();k++) {
-
+
if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
found=true;
break;
@@ -878,9 +878,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
if (mesh.edges[k].b==a && mesh.edges[k].a==b) {
found=true;
break;
- }
+ }
}
-
+
if (found)
continue;
MeshData::Edge edge;
@@ -888,8 +888,8 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
edge.b=b;
mesh.edges.push_back(edge);
}
-
-
+
+
}
return mesh;
@@ -899,36 +899,36 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
DVector<Plane> planes;
-
+
planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) );
planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) );
planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) );
planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) );
planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) );
planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) );
-
+
return planes;
}
DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
DVector<Plane> planes;
-
+
for (int i=0;i<p_sides;i++) {
-
+
Vector3 normal;
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
-
+
planes.push_back( Plane( normal, p_radius ) );
}
-
+
Vector3 axis;
axis[p_axis]=1.0;
-
+
planes.push_back( Plane( axis, p_height*0.5 ) );
planes.push_back( Plane( -axis, p_height*0.5 ) );
-
+
return planes;
}
@@ -972,34 +972,34 @@ DVector<Plane> Geometry::build_sphere_planes(float p_radius, int p_lats,int p_lo
DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
DVector<Plane> planes;
-
+
Vector3 axis;
axis[p_axis]=1.0;
-
- Vector3 axis_neg;
+
+ Vector3 axis_neg;
axis_neg[(p_axis+1)%3]=1.0;
axis_neg[(p_axis+2)%3]=1.0;
axis_neg[p_axis]=-1.0;
-
+
for (int i=0;i<p_sides;i++) {
-
+
Vector3 normal;
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
-
+
planes.push_back( Plane( normal, p_radius ) );
-
+
for (int j=1;j<=p_lats;j++) {
-
+
Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
Vector3 pos = axis*p_height*0.5 + angle*p_radius;
planes.push_back( Plane( pos, angle ) );
planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
-
+
}
}
-
+
return planes;
}
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 8370990d6e..b353423851 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -44,7 +44,7 @@
class Geometry {
Geometry();
public:
-
+
@@ -201,37 +201,37 @@ public:
real_t a =e1.dot(h);
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
return false;
-
+
real_t f=1.0/a;
-
+
Vector3 s=p_from-p_v0;
real_t u = f * s.dot(h);
-
+
if ( u< 0.0 || u > 1.0)
return false;
-
+
Vector3 q=s.cross(e1);
-
+
real_t v = f * p_dir.dot(q);
-
+
if (v < 0.0 || u + v > 1.0)
return false;
-
- // at this stage we can compute t to find out where
+
+ // at this stage we can compute t to find out where
// the intersection point is on the line
real_t t = f * e2.dot(q);
-
+
if (t > 0.00001) {// ray intersection
if (r_res)
*r_res=p_from+p_dir*t;
return true;
- } else // this means that there is a line intersection
+ } else // this means that there is a line intersection
// but not a ray intersection
return false;
- }
-
+ }
+
static inline bool segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2,Vector3* r_res=0) {
-
+
Vector3 rel=p_to-p_from;
Vector3 e1=p_v1-p_v0;
Vector3 e2=p_v2-p_v0;
@@ -239,34 +239,34 @@ public:
real_t a =e1.dot(h);
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
return false;
-
+
real_t f=1.0/a;
-
+
Vector3 s=p_from-p_v0;
real_t u = f * s.dot(h);
-
+
if ( u< 0.0 || u > 1.0)
return false;
-
+
Vector3 q=s.cross(e1);
-
+
real_t v = f * rel.dot(q);
-
+
if (v < 0.0 || u + v > 1.0)
return false;
-
- // at this stage we can compute t to find out where
+
+ // at this stage we can compute t to find out where
// the intersection point is on the line
real_t t = f * e2.dot(q);
-
+
if (t > CMP_EPSILON && t<=1.0) {// ray intersection
if (r_res)
*r_res=p_from+rel*t;
return true;
- } else // this means that there is a line intersection
+ } else // this means that there is a line intersection
// but not a ray intersection
return false;
- }
+ }
static inline bool segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius,Vector3* r_res=0,Vector3 *r_norm=0) {
@@ -356,24 +356,24 @@ public:
real_t box_end=size[i];
real_t cmin,cmax;
-
+
if (seg_from < seg_to) {
-
+
if (seg_from > box_end || seg_to < box_begin)
return false;
real_t length=seg_to-seg_from;
cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0;
cmax = (seg_to > box_end)?((box_end - seg_from)/length):1;
-
+
} else {
-
+
if (seg_to > box_end || seg_from < box_begin)
return false;
real_t length=seg_to-seg_from;
cmin = (seg_from > box_end)?(box_end - seg_from)/length:0;
cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1;
}
-
+
if (cmin > min) {
min = cmin;
axis=i;
@@ -468,9 +468,9 @@ public:
if (l<1e-10)
return p_segment[0]; // both points are the same, just give any
n/=l;
-
+
float d=n.dot(p);
-
+
if (d<=0.0)
return p_segment[0]; // before first point
else if (d>=l)
@@ -570,27 +570,27 @@ public:
static inline bool point_in_projected_triangle(const Vector3& p_point,const Vector3& p_v1,const Vector3& p_v2,const Vector3& p_v3) {
-
-
- Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
-
- Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
-
+
+
+ Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
+
+ Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
+
if (face_n.dot(n1)<0)
return false;
-
- Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
-
+
+ Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
+
if (face_n.dot(n2)<0)
return false;
-
- Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
-
+
+ Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
+
if (face_n.dot(n3)<0)
return false;
-
+
return true;
-
+
}
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle,const Vector3& p_normal,const Vector3& p_sphere_pos, real_t p_sphere_radius,Vector3& r_triangle_contact,Vector3& r_sphere_contact) {
@@ -814,21 +814,21 @@ public:
struct MeshData {
-
+
struct Face {
Plane plane;
Vector<int> indices;
};
-
+
Vector<Face> faces;
-
+
struct Edge {
-
+
int a,b;
};
-
+
Vector<Edge> edges;
-
+
Vector< Vector3 > vertices;
void optimize_vertices();
@@ -927,7 +927,7 @@ public:
static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
-
+
};
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp
index a485125cb4..0e2060008c 100644
--- a/core/math/math_2d.cpp
+++ b/core/math/math_2d.cpp
@@ -45,10 +45,10 @@ float Vector2::length_squared() const {
}
void Vector2::normalize() {
-
+
float l = x*x + y*y;
if (l!=0) {
-
+
l=Math::sqrt(l);
x/=l;
y/=l;
@@ -56,14 +56,14 @@ void Vector2::normalize() {
}
Vector2 Vector2::normalized() const {
-
+
Vector2 v=*this;
v.normalize();
return v;
}
float Vector2::distance_to(const Vector2& p_vector2) const {
-
+
return Math::sqrt( (x-p_vector2.x)*(x-p_vector2.x) + (y-p_vector2.y)*(y-p_vector2.y));
}
@@ -73,7 +73,7 @@ float Vector2::distance_squared_to(const Vector2& p_vector2) const {
}
float Vector2::angle_to(const Vector2& p_vector2) const {
-
+
return Math::atan2( tangent().dot(p_vector2), dot(p_vector2) );
}
@@ -83,7 +83,7 @@ float Vector2::angle_to_point(const Vector2& p_vector2) const {
}
float Vector2::dot(const Vector2& p_other) const {
-
+
return x*p_other.x + y*p_other.y;
}
@@ -99,62 +99,62 @@ Vector2 Vector2::cross(real_t p_other) const {
Vector2 Vector2::operator+(const Vector2& p_v) const {
-
+
return Vector2(x+p_v.x,y+p_v.y);
}
void Vector2::operator+=(const Vector2& p_v) {
-
+
x+=p_v.x; y+=p_v.y;
}
Vector2 Vector2::operator-(const Vector2& p_v) const {
-
+
return Vector2(x-p_v.x,y-p_v.y);
}
void Vector2::operator-=(const Vector2& p_v) {
-
+
x-=p_v.x; y-=p_v.y;
}
Vector2 Vector2::operator*(const Vector2 &p_v1) const {
-
+
return Vector2(x * p_v1.x, y * p_v1.y);
};
Vector2 Vector2::operator*(const float &rvalue) const {
-
+
return Vector2(x * rvalue, y * rvalue);
};
void Vector2::operator*=(const float &rvalue) {
-
+
x *= rvalue; y *= rvalue;
};
Vector2 Vector2::operator/(const Vector2 &p_v1) const {
-
+
return Vector2(x / p_v1.x, y / p_v1.y);
};
Vector2 Vector2::operator/(const float &rvalue) const {
-
+
return Vector2(x / rvalue, y / rvalue);
};
void Vector2::operator/=(const float &rvalue) {
-
+
x /= rvalue; y /= rvalue;
};
Vector2 Vector2::operator-() const {
-
+
return Vector2(-x,-y);
}
bool Vector2::operator==(const Vector2& p_vec2) const {
-
+
return x==p_vec2.x && y==p_vec2.y;
}
bool Vector2::operator!=(const Vector2& p_vec2) const {
-
+
return x!=p_vec2.x || y!=p_vec2.y;
}
Vector2 Vector2::floor() const {
@@ -621,25 +621,25 @@ float Matrix32::basis_determinant() const {
}
Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const {
-
+
//extract parameters
Vector2 p1 = get_origin();
Vector2 p2 = p_transform.get_origin();
-
+
real_t r1 = get_rotation();
real_t r2 = p_transform.get_rotation();
-
+
Vector2 s1 = get_scale();
Vector2 s2 = p_transform.get_scale();
-
+
//slerp rotation
Vector2 v1(Math::cos(r1), Math::sin(r1));
Vector2 v2(Math::cos(r2), Math::sin(r2));
-
+
real_t dot = v1.dot(v2);
-
+
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
-
+
Vector2 v;
if (dot > 0.9995) {
@@ -649,7 +649,7 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons
Vector2 v3 = (v2 - v1*dot).normalized();
v = v1*Math::cos(angle) + v3*Math::sin(angle);
}
-
+
//construct matrix
Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index 1171364671..ad4655b8f7 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -35,15 +35,15 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
enum Margin {
-
+
MARGIN_LEFT,
MARGIN_TOP,
MARGIN_RIGHT,
- MARGIN_BOTTOM
+ MARGIN_BOTTOM
};
enum Orientation {
-
+
HORIZONTAL,
VERTICAL
};
@@ -63,7 +63,7 @@ enum VAlign {
};
struct Vector2 {
-
+
union {
float x;
float width;
@@ -87,7 +87,7 @@ struct Vector2 {
float length() const;
float length_squared() const;
- float distance_to(const Vector2& p_vector2) const;
+ float distance_to(const Vector2& p_vector2) const;
float distance_squared_to(const Vector2& p_vector2) const;
float angle_to(const Vector2& p_vector2) const;
float angle_to_point(const Vector2& p_vector2) const;
@@ -114,19 +114,19 @@ struct Vector2 {
Vector2 operator-(const Vector2& p_v) const;
void operator-=(const Vector2& p_v);
Vector2 operator*(const Vector2 &p_v1) const;
-
+
Vector2 operator*(const float &rvalue) const;
void operator*=(const float &rvalue);
void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
Vector2 operator/(const Vector2 &p_v1) const;
-
+
Vector2 operator/(const float &rvalue) const;
-
+
void operator/=(const float &rvalue);
-
+
Vector2 operator-() const;
-
+
bool operator==(const Vector2& p_vec2) const;
bool operator!=(const Vector2& p_vec2) const;
@@ -151,14 +151,14 @@ struct Vector2 {
return Vector2(y,-x);
}
-
+
Vector2 floor() const;
Vector2 snapped(const Vector2& p_by) const;
float get_aspect() const { return width/height; }
-
+
operator String() const { return String::num(x)+","+String::num(y); }
-
+
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
_FORCE_INLINE_ Vector2() { x=0; y=0; }
};
@@ -202,7 +202,7 @@ struct Matrix32;
struct Rect2 {
-
+
Point2 pos;
Size2 size;
@@ -213,7 +213,7 @@ struct Rect2 {
float get_area() const { return size.width*size.height; }
- inline bool intersects(const Rect2& p_rect) const {
+ inline bool intersects(const Rect2& p_rect) const {
if ( pos.x >= (p_rect.pos.x + p_rect.size.width) )
return false;
if ( (pos.x+size.width) <= p_rect.pos.x )
@@ -222,7 +222,7 @@ struct Rect2 {
return false;
if ( (pos.y+size.height) <= p_rect.pos.y )
return false;
-
+
return true;
}
@@ -254,73 +254,73 @@ struct Rect2 {
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
inline bool encloses(const Rect2& p_rect) const {
-
+
return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
-
+
}
-
+
inline bool has_no_area() const {
-
+
return (size.x<=0 || size.y<=0);
-
+
}
inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect
-
+
Rect2 new_rect=p_rect;
-
+
if (!intersects( new_rect ))
return Rect2();
-
+
new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
-
+
Point2 p_rect_end=p_rect.pos+p_rect.size;
Point2 end=pos+size;
-
+
new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x;
new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y;
-
+
return new_rect;
}
-
+
inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect
-
+
Rect2 new_rect;
-
+
new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
-
-
+
+
new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
-
+
new_rect.size = new_rect.size - new_rect.pos; //make relative again
-
+
return new_rect;
};
inline bool has_point(const Point2& p_point) const {
if (p_point.x < pos.x)
- return false;
+ return false;
if (p_point.y < pos.y)
- return false;
-
+ return false;
+
if (p_point.x >= (pos.x+size.x) )
- return false;
+ return false;
if (p_point.y >= (pos.y+size.y) )
- return false;
-
+ return false;
+
return true;
}
-
+
inline bool no_area() const { return (size.width<=0 || size.height<=0 ); }
-
+
bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; }
bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; }
-
+
inline Rect2 grow(real_t p_by) const {
-
+
Rect2 g=*this;
g.pos.x-=p_by;
g.pos.y-=p_by;
@@ -357,9 +357,9 @@ struct Rect2 {
operator String() const { return String(pos)+","+String(size); }
-
+
Rect2() {}
- Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
+ Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
Rect2( const Point2& p_pos, const Size2& p_size ) { pos=p_pos; size=p_size; }
};
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 20d9db3375..07f114725d 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -185,12 +185,12 @@ double Math::fmod(double p_x,double p_y) {
double Math::fposmod(double p_x,double p_y) {
if (p_x>=0) {
-
+
return Math::fmod(p_x,p_y);
-
+
} else {
-
- return p_y-Math::fmod(-p_x,p_y);
+
+ return p_y-Math::fmod(-p_x,p_y);
}
}
@@ -205,7 +205,7 @@ double Math::ceil(double p_x) {
}
int Math::decimals(double p_step) {
-
+
int max=4;
double llimit = Math::pow(0.1,max);
double ulimit = 1.0-llimit;
@@ -220,7 +220,7 @@ int Math::decimals(double p_step) {
max--;
i++;
}
-
+
return i;
}
@@ -251,11 +251,11 @@ double Math::ease(double p_x, double p_c) {
}
double Math::stepify(double p_value,double p_step) {
-
+
if (p_step!=0) {
-
- p_value=floor( p_value / p_step + 0.5 ) * p_step;
- }
+
+ p_value=floor( p_value / p_step + 0.5 ) * p_step;
+ }
return p_value;
}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 62890b0371..2e1b9c989e 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -91,25 +91,25 @@ public:
static uint32_t rand();
static double randf();
-
+
static double round(double p_val);
static double random(double from, double to);
-
+
static _FORCE_INLINE_ real_t abs(real_t g) {
-#ifdef REAL_T_IS_DOUBLE
-
- return absd(g);
+#ifdef REAL_T_IS_DOUBLE
+
+ return absd(g);
#else
- return absf(g);
+ return absf(g);
#endif
}
static _FORCE_INLINE_ float absf(float g) {
-
+
union {
float f;
uint32_t i;
@@ -174,7 +174,7 @@ public:
static double pow(double x, double y);
static double log(double x);
static double exp(double x);
-
+
};
diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp
index f51da80a83..71e6b62212 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/matrix3.cpp
@@ -62,11 +62,11 @@ void Matrix3::invert() {
real_t det = elements[0][0] * co[0]+
elements[0][1] * co[1]+
elements[0][2] * co[2];
-
+
ERR_FAIL_COND( det == 0 );
real_t s = 1.0/det;
-
- set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
+
+ set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
co[1]*s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
co[2]*s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s );
@@ -148,7 +148,7 @@ Vector3 Matrix3::get_scale() const {
Vector3(elements[0][1],elements[1][1],elements[2][1]).length(),
Vector3(elements[0][2],elements[1][2],elements[2][2]).length()
);
-
+
}
void Matrix3::rotate(const Vector3& p_axis, real_t p_phi) {
@@ -223,7 +223,7 @@ bool Matrix3::operator==(const Matrix3& p_matrix) const {
return false;
}
}
-
+
return true;
}
bool Matrix3::operator!=(const Matrix3& p_matrix) const {
@@ -235,16 +235,16 @@ Matrix3::operator String() const {
String mtx;
for (int i=0;i<3;i++) {
-
+
for (int j=0;j<3;j++) {
-
+
if (i!=0 || j!=0)
mtx+=", ";
-
+
mtx+=rtos( elements[i][j] );
}
}
-
+
return mtx;
}
@@ -255,34 +255,34 @@ Matrix3::operator Quat() const {
real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2];
real_t temp[4];
-
- if (trace > 0.0)
+
+ if (trace > 0.0)
{
real_t s = Math::sqrt(trace + 1.0);
temp[3]=(s * 0.5);
s = 0.5 / s;
-
+
temp[0]=((m.elements[2][1] - m.elements[1][2]) * s);
temp[1]=((m.elements[0][2] - m.elements[2][0]) * s);
temp[2]=((m.elements[1][0] - m.elements[0][1]) * s);
- }
- else
+ }
+ else
{
int i = m.elements[0][0] < m.elements[1][1] ?
(m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
(m.elements[0][0] < m.elements[2][2] ? 2 : 0);
- int j = (i + 1) % 3;
+ int j = (i + 1) % 3;
int k = (i + 2) % 3;
-
+
real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
temp[i] = s * 0.5;
s = 0.5 / s;
-
+
temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
}
-
+
return Quat(temp[0],temp[1],temp[2],temp[3]);
}
@@ -439,7 +439,7 @@ void Matrix3::get_axis_and_angle(Vector3 &r_axis,real_t& r_angle) const {
Matrix3::Matrix3(const Vector3& p_euler) {
set_euler( p_euler );
-
+
}
Matrix3::Matrix3(const Quat& p_quat) {
@@ -450,8 +450,8 @@ Matrix3::Matrix3(const Quat& p_quat) {
real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs;
real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs;
real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs;
- set( 1.0 - (yy + zz), xy - wz, xz + wy,
- xy + wz, 1.0 - (xx + zz), yz - wx,
+ set( 1.0 - (yy + zz), xy - wz, xz + wy,
+ xy + wz, 1.0 - (xx + zz), yz - wx,
xz - wy, yz + wx, 1.0 - (xx + yy)) ;
}
diff --git a/core/math/matrix3.h b/core/math/matrix3.h
index 291934b8eb..e514f490f7 100644
--- a/core/math/matrix3.h
+++ b/core/math/matrix3.h
@@ -39,20 +39,20 @@ class Matrix3 {
public:
Vector3 elements[3];
-
+
_FORCE_INLINE_ const Vector3& operator[](int axis) const {
-
+
return elements[axis];
}
_FORCE_INLINE_ Vector3& operator[](int axis) {
-
+
return elements[axis];
}
- void invert();
+ void invert();
void transpose();
-
- Matrix3 inverse() const;
+
+ Matrix3 inverse() const;
Matrix3 transposed() const;
_FORCE_INLINE_ float determinant() const;
@@ -90,7 +90,7 @@ public:
_FORCE_INLINE_ real_t tdotz(const Vector3& v) const {
return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
}
-
+
bool operator==(const Matrix3& p_matrix) const;
bool operator!=(const Matrix3& p_matrix) const;
@@ -110,7 +110,7 @@ public:
_FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
-
+
elements[0][0]=xx;
elements[0][1]=xy;
elements[0][2]=xz;
@@ -119,15 +119,15 @@ public:
elements[1][2]=yz;
elements[2][0]=zx;
elements[2][1]=zy;
- elements[2][2]=zz;
+ elements[2][2]=zz;
}
_FORCE_INLINE_ Vector3 get_column(int i) const {
-
+
return Vector3(elements[0][i],elements[1][i],elements[2][i]);
}
-
+
_FORCE_INLINE_ Vector3 get_row(int i) const {
-
+
return Vector3(elements[i][0],elements[i][1],elements[i][2]);
}
_FORCE_INLINE_ void set_row(int i, const Vector3& p_row) {
@@ -155,8 +155,8 @@ public:
elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y,
elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
}
- Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
-
+ Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
+
set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
}
@@ -170,7 +170,7 @@ public:
Matrix3(const Vector3& p_axis, real_t p_phi);
_FORCE_INLINE_ Matrix3() {
-
+
elements[0][0]=1;
elements[0][1]=0;
elements[0][2]=0;
@@ -191,7 +191,7 @@ _FORCE_INLINE_ void Matrix3::operator*=(const Matrix3& p_matrix) {
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
-
+
}
_FORCE_INLINE_ Matrix3 Matrix3::operator*(const Matrix3& p_matrix) const {
diff --git a/core/math/octree.h b/core/math/octree.h
index b51c4bcba7..6080b21680 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -52,11 +52,11 @@ public:
typedef void* (*PairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int);
typedef void (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*);
-private:
+private:
enum {
-
+
NEG=0,
- POS=1,
+ POS=1,
};
enum {
@@ -72,7 +72,7 @@ private:
struct PairKey {
-
+
union {
struct {
OctreeElementID A;
@@ -80,66 +80,66 @@ private:
};
uint64_t key;
};
-
+
_FORCE_INLINE_ bool operator<(const PairKey& p_pair) const {
-
+
return key<p_pair.key;
}
-
+
_FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) {
-
+
if (p_A<p_B) {
-
+
A=p_A;
- B=p_B;
+ B=p_B;
} else {
-
+
B=p_A;
A=p_B;
}
}
-
+
_FORCE_INLINE_ PairKey() {}
- };
-
+ };
+
struct Element;
-
+
struct Octant {
-
+
// cached for FAST plane check
AABB aabb;
-
+
uint64_t last_pass;
Octant *parent;
Octant *children[8];
-
+
int children_count; // cache for amount of childrens (fast check for removal)
int parent_index; // cache for parent index (fast check for removal)
-
+
List<Element*,AL> pairable_elements;
List<Element*,AL> elements;
-
+
Octant() {
children_count=0;
parent_index=-1;
last_pass=0;
parent=NULL;
for (int i=0;i<8;i++)
- children[i]=NULL;
+ children[i]=NULL;
}
-
+
~Octant() {
-
+
//for (int i=0;i<8;i++)
// memdelete_notnull(children[i]);
}
};
-
+
struct PairData;
struct Element {
-
+
Octree *octree;
T *userdata;
@@ -147,28 +147,28 @@ private:
bool pairable;
uint32_t pairable_mask;
uint32_t pairable_type;
-
+
uint64_t last_pass;
OctreeElementID _id;
Octant *common_parent;
-
+
AABB aabb;
AABB container_aabb;
List<PairData*,AL> pair_list;
-
+
struct OctantOwner {
-
+
Octant *octant;
typename List<Element*,AL>::Element *E;
- }; // an element can be in max 8 octants
-
+ }; // an element can be in max 8 octants
+
List<OctantOwner,AL> octant_owners;
-
-
+
+
Element() { last_pass=0; _id=0; pairable=false; subindex=0; userdata=0; octree=0; pairable_mask=0; pairable_type=0; common_parent=NULL; }
};
-
+
struct PairData {
@@ -181,15 +181,15 @@ private:
typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
- ElementMap element_map;
- PairMap pair_map;
+ ElementMap element_map;
+ PairMap pair_map;
PairCallback pair_callback;
UnpairCallback unpair_callback;
void *pair_callback_userdata;
void *unpair_callback_userdata;
-
- OctreeElementID last_element_id;
+
+ OctreeElementID last_element_id;
uint64_t pass;
real_t unit_size;
@@ -201,7 +201,7 @@ private:
_FORCE_INLINE_ void _pair_check(PairData *p_pair) {
- bool intersect=p_pair->A->aabb.intersects( p_pair->B->aabb );
+ bool intersect=p_pair->A->aabb.intersects_inclusive( p_pair->B->aabb );
if (intersect!=p_pair->intersect) {
@@ -231,7 +231,7 @@ private:
if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata))
return;
-
+
if ( !(p_A->pairable_type&p_B->pairable_mask) &&
!(p_B->pairable_type&p_A->pairable_mask) )
return; // none can pair with none
@@ -253,17 +253,17 @@ private:
// if (pair_callback)
// pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
} else {
-
+
E->get().refcount++;
}
-
+
}
-
+
_FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) {
-
+
if (p_A==p_B)
return;
-
+
PairKey key(p_A->_id, p_B->_id);
typename PairMap::Element *E=pair_map.find(key);
if (!E) {
@@ -293,7 +293,7 @@ private:
p_B->pair_list.erase( E->get().eB );
pair_map.erase(E);
}
-
+
}
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
@@ -341,7 +341,7 @@ private:
void _ensure_valid_root(const AABB& p_aabb);
bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL);
void _remove_element(Element *p_element);
- void _pair_element(Element *p_element,Octant *p_octant);
+ void _pair_element(Element *p_element,Octant *p_octant);
void _unpair_element(Element *p_element,Octant *p_octant);
@@ -361,16 +361,16 @@ private:
void _cull_point(Octant *p_octant,const Vector3& p_point,T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask);
void _remove_tree(Octant *p_octant) {
-
+
if (!p_octant)
return;
for(int i=0;i<8;i++) {
-
+
if (p_octant->children[i])
_remove_tree(p_octant->children[i]);
}
-
+
memdelete_allocator<Octant,AL>(p_octant);
}
public:
@@ -432,24 +432,24 @@ template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant) {
float element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
-
+
if (p_octant->aabb.size.x/OCTREE_DIVISOR < element_size) {
- //if (p_octant->aabb.size.x*0.5 < element_size) {
-
- /* at smallest possible size for the element */
+ //if (p_octant->aabb.size.x*0.5 < element_size) {
+
+ /* at smallest possible size for the element */
typename Element::OctantOwner owner;
owner.octant=p_octant;
-
+
if (use_pairs && p_element->pairable) {
-
+
p_octant->pairable_elements.push_back(p_element);
owner.E = p_octant->pairable_elements.back();
} else {
-
+
p_octant->elements.push_back(p_element);
owner.E = p_octant->elements.back();
}
-
+
p_element->octant_owners.push_back( owner );
if (p_element->common_parent==NULL) {
@@ -461,13 +461,13 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
if (use_pairs && p_octant->children_count>0) {
-
+
pass++; //elements below this only get ONE reference added
for (int i=0;i<8;i++) {
-
+
if (p_octant->children[i]) {
- _pair_element(p_element,p_octant->children[i]);
+ _pair_element(p_element,p_octant->children[i]);
}
}
}
@@ -477,29 +477,29 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
bool candidate=p_element->common_parent==NULL;
for (int i=0;i<8;i++) {
-
+
if (p_octant->children[i]) {
/* element exists, go straight to it */
- if (p_octant->children[i]->aabb.intersects( p_element->aabb ) ) {
+ if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) {
_insert_element( p_element, p_octant->children[i] );
splits++;
}
} else {
/* check againt AABB where child should be */
-
+
AABB aabb=p_octant->aabb;
aabb.size*=0.5;
-
+
if (i&1)
aabb.pos.x+=aabb.size.x;
if (i&2)
aabb.pos.y+=aabb.size.y;
if (i&4)
aabb.pos.z+=aabb.size.z;
-
- if (aabb.intersects( p_element->aabb) ) {
+
+ if (aabb.intersects_inclusive( p_element->aabb) ) {
/* if actually intersects, create the child */
-
+
Octant *child = memnew_allocator( Octant, AL );
p_octant->children[i]=child;
child->parent=p_octant;
@@ -517,14 +517,14 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
}
}
-
+
if (candidate && splits>1) {
p_element->common_parent=p_octant;
}
-
+
}
-
+
if (use_pairs) {
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
@@ -532,8 +532,8 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
while(E) {
_pair_reference( p_element,E->get() );
E=E->next();
- }
-
+ }
+
if (p_element->pairable) {
// and always test non-pairable if element is pairable
E=p_octant->elements.front();
@@ -541,9 +541,9 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
_pair_reference( p_element,E->get() );
E=E->next();
}
- }
+ }
}
-
+
}
@@ -553,35 +553,35 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
if (!root) {
// octre is empty
-
+
AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size);
-
+
while ( !base.encloses(p_aabb) ) {
-
+
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
/* grow towards positive */
base.size*=2.0;
} else {
- base.pos-=base.size;
+ base.pos-=base.size;
base.size*=2.0;
}
}
-
+
root = memnew_allocator( Octant, AL );
- root->parent=NULL;
- root->parent_index=-1;
+ root->parent=NULL;
+ root->parent_index=-1;
root->aabb=base;
-
+
octant_count++;
-
-
- } else {
-
+
+
+ } else {
+
AABB base=root->aabb;
-
+
while( !base.encloses( p_aabb ) ) {
-
+
if (base.size.x > OCTREE_SIZE_LIMIT) {
ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
ERR_FAIL();
@@ -590,7 +590,7 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
Octant * gp = memnew_allocator( Octant, AL );
octant_count++;
root->parent=gp;
-
+
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
/* grow towards positive */
base.size*=2.0;
@@ -598,16 +598,16 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
gp->children[0]=root;
root->parent_index=0;
} else {
- base.pos-=base.size;
+ base.pos-=base.size;
base.size*=2.0;
gp->aabb=base;
gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive
root->parent_index=(1<<0)|(1<<1)|(1<<2);
}
-
+
gp->children_count=1;
- root=gp;
- }
+ root=gp;
+ }
}
}
@@ -615,16 +615,16 @@ template<class T,bool use_pairs,class AL>
bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit) {
bool octant_removed=false;
-
+
while(true) {
-
+
// check all exit conditions
-
+
if (p_octant==p_limit) // reached limit, nothing to erase, exit
return octant_removed;
-
+
bool unpaired=false;
-
+
if (use_pairs && p_octant->last_pass!=pass) {
// check wether we should unpair stuff
// always test pairable
@@ -644,21 +644,21 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
p_octant->last_pass=pass;
unpaired=true;
}
-
+
bool removed=false;
-
+
Octant *parent=p_octant->parent;
-
+
if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
-
+
// erase octant
-
+
if (p_octant==root) { // won't have a parent, just erase
-
+
root=NULL;
} else {
ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed);
-
+
parent->children[ p_octant->parent_index ]=NULL;
parent->children_count--;
}
@@ -668,12 +668,12 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
removed=true;
octant_removed=true;
}
-
+
if (!removed && !unpaired)
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
-
+
p_octant=parent;
-
+
}
return octant_removed;
@@ -682,8 +682,8 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant) {
-
- // always test pairable
+
+ // always test pairable
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
while(E) {
if (E->get()->last_pass!=pass) { // only remove ONE reference
@@ -692,7 +692,7 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
}
E=E->next();
}
-
+
if (p_element->pairable) {
// and always test non-pairable if element is pairable
E=p_octant->elements.front();
@@ -704,14 +704,14 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
E=E->next();
}
}
-
+
p_octant->last_pass=pass;
-
+
if (p_octant->children_count==0)
return; // small optimization for leafs
-
+
for (int i=0;i<8;i++) {
-
+
if (p_octant->children[i])
_unpair_element(p_element,p_octant->children[i]);
}
@@ -732,7 +732,7 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
}
E=E->next();
}
-
+
if (p_element->pairable) {
// and always test non-pairable if element is pairable
E=p_octant->elements.front();
@@ -745,12 +745,12 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
}
}
p_octant->last_pass=pass;
-
+
if (p_octant->children_count==0)
return; // small optimization for leafs
-
+
for (int i=0;i<8;i++) {
-
+
if (p_octant->children[i])
_pair_element(p_element,p_octant->children[i]);
}
@@ -760,13 +760,13 @@ template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
pass++; // will do a new pass for this
-
+
typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front();
-
+
/* FIRST remove going up normally */
for(;I;I=I->next()) {
-
+
Octant *o=I->get().octant;
if (!use_pairs) // small speedup
@@ -809,14 +809,14 @@ void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
int remaining=p_element->pair_list.size();
//p_element->pair_list.clear();
ERR_FAIL_COND( remaining );
- }
+ }
}
template<class T,bool use_pairs,class AL>
OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb, int p_subindex,bool p_pairable,uint32_t p_pairable_type,uint32_t p_pairable_mask) {
- // check for AABB validity
+ // check for AABB validity
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V( p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0 );
ERR_FAIL_COND_V( p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0 );
@@ -828,12 +828,12 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.y) , 0 );
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.z) , 0 );
-
+
#endif
typename ElementMap::Element *E = element_map.insert(last_element_id++,
Element());
Element &e = E->get();
-
+
e.aabb=p_aabb;
e.userdata=p_userdata;
e.subindex=p_subindex;
@@ -843,7 +843,7 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
e.pairable_type=p_pairable_type;
e.pairable_mask=p_pairable_mask;
e._id=last_element_id-1;
-
+
if (!e.aabb.has_no_surface()) {
_ensure_valid_root(p_aabb);
_insert_element(&e,root);
@@ -964,7 +964,7 @@ void Octree<T,use_pairs,AL>::move(OctreeElementID p_id, const AABB& p_aabb) {
_insert_element(&e,common_parent); // reinsert from this point
pass++;
-
+
for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) {
Octant *o=E->get().octant;
@@ -1018,28 +1018,28 @@ void Octree<T,use_pairs,AL>::set_pairable(OctreeElementID p_id,bool p_pairable,u
typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
-
+
Element &e = E->get();
if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask)
return; // no changes, return
-
+
if (!e.aabb.has_no_surface()) {
_remove_element(&e);
}
-
+
e.pairable=p_pairable;
e.pairable_type=p_pairable_type;
e.pairable_mask=p_pairable_mask;
e.common_parent=NULL;
-
+
if (!e.aabb.has_no_surface()) {
_ensure_valid_root(e.aabb);
_insert_element(&e,root);
if (use_pairs)
_element_check_pairs(&e);
- }
+ }
}
@@ -1048,155 +1048,155 @@ void Octree<T,use_pairs,AL>::erase(OctreeElementID p_id) {
typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
-
+
Element &e = E->get();
if (!e.aabb.has_no_surface()) {
-
- _remove_element(&e);
+
+ _remove_element(&e);
}
-
+
element_map.erase(p_id);
_optimize();
}
template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) {
-
+
if (*p_cull->result_idx==p_cull->result_max)
return; //pointless
-
+
if (!p_octant->elements.empty()) {
-
+
typename List< Element*,AL >::Element *I;
I=p_octant->elements.front();
-
+
for(;I;I=I->next()) {
-
+
Element *e=I->get();
-
+
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
continue;
e->last_pass=pass;
-
+
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
-
+
if (*p_cull->result_idx<p_cull->result_max) {
p_cull->result_array[*p_cull->result_idx] = e->userdata;
(*p_cull->result_idx)++;
} else {
-
+
return; // pointless to continue
}
}
}
}
-
+
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
+
typename List< Element*,AL >::Element *I;
I=p_octant->pairable_elements.front();
-
+
for(;I;I=I->next()) {
-
+
Element *e=I->get();
-
+
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
continue;
e->last_pass=pass;
-
+
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
-
+
if (*p_cull->result_idx<p_cull->result_max) {
p_cull->result_array[*p_cull->result_idx] = e->userdata;
(*p_cull->result_idx)++;
} else {
-
+
return; // pointless to continue
}
}
}
}
-
+
for (int i=0;i<8;i++) {
-
+
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
_cull_convex(p_octant->children[i],p_cull);
}
- }
+ }
}
template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask) {
-
+
if (*p_result_idx==p_result_max)
return; //pointless
-
+
if (!p_octant->elements.empty()) {
-
+
typename List< Element*,AL >::Element *I;
I=p_octant->elements.front();
for(;I;I=I->next()) {
-
+
Element *e=I->get();
-
+
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue;
e->last_pass=pass;
-
- if (p_aabb.intersects(e->aabb)) {
-
+
+ if (p_aabb.intersects_inclusive(e->aabb)) {
+
if (*p_result_idx<p_result_max) {
-
+
p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex;
(*p_result_idx)++;
} else {
-
+
return; // pointless to continue
}
}
}
}
-
+
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
+
typename List< Element*,AL >::Element *I;
I=p_octant->pairable_elements.front();
for(;I;I=I->next()) {
-
+
Element *e=I->get();
-
+
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue;
e->last_pass=pass;
-
- if (p_aabb.intersects(e->aabb)) {
-
+
+ if (p_aabb.intersects_inclusive(e->aabb)) {
+
if (*p_result_idx<p_result_max) {
-
+
p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex;
(*p_result_idx)++;
} else {
-
+
return; // pointless to continue
}
}
}
- }
+ }
for (int i=0;i<8;i++) {
-
- if (p_octant->children[i] && p_octant->children[i]->aabb.intersects(p_aabb)) {
+
+ if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
_cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
}
- }
+ }
}
@@ -1205,53 +1205,53 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
if (*p_result_idx==p_result_max)
return; //pointless
-
+
if (!p_octant->elements.empty()) {
-
+
typename List< Element*,AL >::Element *I;
I=p_octant->elements.front();
for(;I;I=I->next()) {
-
+
Element *e=I->get();
-
+
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue;
e->last_pass=pass;
-
+
if (e->aabb.intersects_segment(p_from,p_to)) {
-
+
if (*p_result_idx<p_result_max) {
-
+
p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex;
(*p_result_idx)++;
} else {
-
+
return; // pointless to continue
}
}
}
}
-
+
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
+
typename List< Element*,AL >::Element *I;
I=p_octant->pairable_elements.front();
for(;I;I=I->next()) {
-
+
Element *e=I->get();
-
+
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue;
-
+
e->last_pass=pass;
-
+
if (e->aabb.intersects_segment(p_from,p_to)) {
-
+
if (*p_result_idx<p_result_max) {
-
+
p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex;
@@ -1259,20 +1259,20 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
(*p_result_idx)++;
} else {
-
+
return; // pointless to continue
}
}
}
}
-
+
for (int i=0;i<8;i++) {
-
+
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from,p_to)) {
_cull_segment(p_octant->children[i],p_from,p_to, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
}
- }
+ }
}
@@ -1357,7 +1357,7 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
if (!root)
return 0;
-
+
int result_count=0;
pass++;
_CullConvexData cdata;
@@ -1367,9 +1367,9 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
cdata.result_max=p_result_max;
cdata.result_idx=&result_count;
cdata.mask=p_mask;
-
+
_cull_convex(root,&cdata);
-
+
return result_count;
}
@@ -1381,11 +1381,11 @@ int Octree<T,use_pairs,AL>::cull_AABB(const AABB& p_aabb,T** p_result_array,int
if (!root)
return 0;
-
+
int result_count=0;
pass++;
_cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
-
+
return result_count;
}
@@ -1395,11 +1395,11 @@ int Octree<T,use_pairs,AL>::cull_segment(const Vector3& p_from, const Vector3& p
if (!root)
return 0;
-
+
int result_count=0;
pass++;
_cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
-
+
return result_count;
}
@@ -1436,7 +1436,7 @@ void Octree<T,use_pairs,AL>::set_unpair_callback( UnpairCallback p_callback, voi
template<class T,bool use_pairs,class AL>
Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) {
-
+
last_element_id=1;
pass=1;
unit_size=p_unit_size;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index d17ce01bec..b29350fe3c 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -50,7 +50,7 @@ void Plane::normalize() {
}
Plane Plane::normalized() const {
-
+
Plane p = *this;
p.normalize();
return p;
@@ -66,12 +66,12 @@ Vector3 Plane::get_any_perpendicular_normal() const {
static const Vector3 p1 = Vector3(1,0,0);
static const Vector3 p2 = Vector3(0,1,0);
Vector3 p;
-
+
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
p=p2; // use p2
else
p=p1; // use p1
-
+
p-=normal * normal.dot(p);
p.normalize();
diff --git a/core/math/plane.h b/core/math/plane.h
index d20e63dc47..81a968682e 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -62,9 +62,9 @@ public:
bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const;
_FORCE_INLINE_ Vector3 project(const Vector3& p_point) const {
-
+
return p_point - normal * distance_to(p_point);
- }
+ }
/* misc */
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index ebc5ec4e65..c6c12129b3 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -30,9 +30,9 @@
#include "print_string.h"
void Quat::set_euler(const Vector3& p_euler) {
- real_t half_yaw = p_euler.x * 0.5;
- real_t half_pitch = p_euler.y * 0.5;
- real_t half_roll = p_euler.z * 0.5;
+ real_t half_yaw = p_euler.x * 0.5;
+ real_t half_pitch = p_euler.y * 0.5;
+ real_t half_roll = p_euler.z * 0.5;
real_t cos_yaw = Math::cos(half_yaw);
real_t sin_yaw = Math::sin(half_yaw);
real_t cos_pitch = Math::cos(half_pitch);
@@ -75,7 +75,7 @@ void Quat::normalize() {
Quat Quat::normalized() const {
return *this / length();
-}
+}
Quat Quat::inverse() const {
return Quat( -x, -y, -z, w );
@@ -252,7 +252,7 @@ Quat Quat::cubic_slerp(const Quat& q, const Quat& prep, const Quat& postq,const
Quat::operator String() const {
- return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
+ return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
}
Quat::Quat(const Vector3& axis, const real_t& angle) {
@@ -261,7 +261,7 @@ Quat::Quat(const Vector3& axis, const real_t& angle) {
set(0,0,0,0);
else {
real_t s = Math::sin(-angle * 0.5) / d;
- set(axis.x * s, axis.y * s, axis.z * s,
+ set(axis.x * s, axis.y * s, axis.z * s,
Math::cos(-angle * 0.5));
}
}
diff --git a/core/math/quat.h b/core/math/quat.h
index 738b6946c7..0d206bb3b7 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -89,18 +89,18 @@ public:
_FORCE_INLINE_ Quat operator-() const;
_FORCE_INLINE_ Quat operator*(const real_t& s) const;
_FORCE_INLINE_ Quat operator/(const real_t& s) const;
-
+
_FORCE_INLINE_ bool operator==(const Quat& p_quat) const;
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
-
+
operator String() const;
-
+
inline void set( real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
- x=p_x; y=p_y; z=p_z; w=p_w;
+ x=p_x; y=p_y; z=p_z; w=p_w;
}
inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
- x=p_x; y=p_y; z=p_z; w=p_w;
+ x=p_x; y=p_y; z=p_z; w=p_w;
}
Quat(const Vector3& axis, const real_t& angle);
@@ -127,7 +127,7 @@ public:
}
inline Quat() {x=y=z=0; w=1; }
-
+
};
@@ -141,7 +141,7 @@ real_t Quat::length_squared() const {
}
void Quat::operator+=(const Quat& q) {
- x += q.x; y += q.y; z += q.z; w += q.w;
+ x += q.x; y += q.y; z += q.z; w += q.w;
}
void Quat::operator-=(const Quat& q) {
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 8371f7e34b..22eb6c4fdd 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -30,7 +30,7 @@
#include "math_funcs.h"
#include "os/copymem.h"
#include "print_string.h"
-
+
void Transform::affine_invert() {
@@ -50,7 +50,7 @@ Transform Transform::affine_inverse() const {
void Transform::invert() {
basis.transpose();
- origin = basis.xform(-origin);
+ origin = basis.xform(-origin);
}
Transform Transform::inverse() const {
@@ -87,30 +87,30 @@ void Transform::set_look_at( const Vector3& p_eye, const Vector3& p_target, cons
// Reference: MESA source code
Vector3 v_x, v_y, v_z;
-
+
/* Make rotation matrix */
-
+
/* Z vector */
v_z = p_eye - p_target;
-
+
v_z.normalize();
-
+
v_y = p_up;
-
+
v_x=v_y.cross(v_z);
-
+
/* Recompute Y = Z cross X */
v_y=v_z.cross(v_x);
-
+
v_x.normalize();
v_y.normalize();
-
+
basis.set_axis(0,v_x);
basis.set_axis(1,v_y);
basis.set_axis(2,v_z);
origin=p_eye;
-
+
}
Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const {
@@ -193,7 +193,7 @@ bool Transform::operator!=(const Transform& p_transform) const {
void Transform::operator*=(const Transform& p_transform) {
origin=xform(p_transform.origin);
- basis*=p_transform.basis;
+ basis*=p_transform.basis;
}
Transform Transform::operator*(const Transform& p_transform) const {
diff --git a/core/math/transform.h b/core/math/transform.h
index bd1247084d..f948a4c919 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -40,9 +40,9 @@ public:
Matrix3 basis;
Vector3 origin;
-
- void invert();
- Transform inverse() const;
+
+ void invert();
+ Transform inverse() const;
void affine_invert();
Transform affine_inverse() const;
@@ -76,27 +76,27 @@ public:
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const;
_FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const;
-
+
_FORCE_INLINE_ Plane xform(const Plane& p_plane) const;
_FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const;
_FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
_FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
-
+
void operator*=(const Transform& p_transform);
Transform operator*(const Transform& p_transform) const;
Transform interpolate_with(const Transform& p_transform, float p_c) const;
-
+
_FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
-
+
Vector3 v = t.origin - origin;
return Transform(basis.transpose_xform(t.basis),
basis.xform(v));
}
-
+
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) {
-
+
basis.elements[0][0]=xx;
basis.elements[0][1]=xy;
basis.elements[0][2]=xz;
@@ -105,14 +105,14 @@ public:
basis.elements[1][2]=yz;
basis.elements[2][0]=zx;
basis.elements[2][1]=zy;
- basis.elements[2][2]=zz;
+ basis.elements[2][2]=zz;
origin.x=tx;
origin.y=ty;
origin.z=tz;
}
-
+
operator String() const;
-
+
Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
Transform() {}
@@ -128,9 +128,9 @@ _FORCE_INLINE_ Vector3 Transform::xform(const Vector3& p_vector) const {
);
}
_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
-
+
Vector3 v = p_vector - origin;
-
+
return Vector3(
(basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ),
(basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ),
@@ -140,16 +140,16 @@ _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
_FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const {
-
+
Vector3 point=p_plane.normal*p_plane.d;
Vector3 point_dir=point+p_plane.normal;
point=xform(point);
point_dir=xform(point_dir);
-
+
Vector3 normal=point_dir-point;
normal.normalize();
real_t d=normal.dot(point);
-
+
return Plane(normal,d);
}
@@ -159,11 +159,11 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane& p_plane) const {
Vector3 point_dir=point+p_plane.normal;
xform_inv(point);
xform_inv(point_dir);
-
+
Vector3 normal=point_dir-point;
normal.normalize();
real_t d=normal.dot(point);
-
+
return Plane(normal,d);
}
@@ -199,17 +199,17 @@ _FORCE_INLINE_ AABB Transform::xform(const AABB& p_aabb) const {
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
};
-
-
+
+
AABB ret;
-
+
ret.pos=xform(vertices[0]);
-
+
for (int i=1;i<8;i++) {
-
+
ret.expand_to( xform(vertices[i]) );
}
-
+
return ret;
#endif
@@ -227,17 +227,17 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB& p_aabb) const {
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
};
-
-
+
+
AABB ret;
-
+
ret.pos=xform_inv(vertices[0]);
-
+
for (int i=1;i<8;i++) {
-
+
ret.expand_to( xform_inv(vertices[i]) );
}
-
+
return ret;
}
diff --git a/core/method_bind.h b/core/method_bind.h
index 4c2598e50c..48848c5848 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -50,6 +50,7 @@ enum MethodFlags {
METHOD_FLAG_CONST=8,
METHOD_FLAG_REVERSE=16, // used for events
METHOD_FLAG_VIRTUAL=32,
+ METHOD_FLAG_FROM_SCRIPT=64,
METHOD_FLAGS_DEFAULT=METHOD_FLAG_NORMAL,
};
@@ -57,8 +58,8 @@ template<class T>
struct VariantCaster {
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
-
- return p_variant;
+
+ return p_variant;
}
};
@@ -66,8 +67,8 @@ template<class T>
struct VariantCaster<T&> {
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
-
- return p_variant;
+
+ return p_variant;
}
};
@@ -75,8 +76,8 @@ template<class T>
struct VariantCaster<const T&> {
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
-
- return p_variant;
+
+ return p_variant;
}
};
diff --git a/core/object.cpp b/core/object.cpp
index c92fc35b24..7bdec06c1b 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -255,7 +255,7 @@ Object::Connection::Connection(const Variant& p_variant) {
bool Object::_predelete() {
-
+
_predelete_ok=1;
notification(NOTIFICATION_PREDELETE,true);
if (_predelete_ok) {
@@ -269,16 +269,16 @@ void Object::_postinitialize() {
_type_ptr=_get_type_namev();
_initialize_typev();
notification(NOTIFICATION_POSTINITIALIZE);
-
+
}
void Object::get_valid_parents_static(List<String> *p_parents) {
-
-
+
+
}
void Object::_get_valid_parents_static(List<String> *p_parents) {
-
-
+
+
}
#if 0
//old style set, deprecated
@@ -286,7 +286,7 @@ void Object::_get_valid_parents_static(List<String> *p_parents) {
void Object::set(const String& p_name, const Variant& p_value) {
_setv(p_name,p_value);
-
+
//if (!_use_builtin_script())
// return;
@@ -303,8 +303,8 @@ void Object::set(const String& p_name, const Variant& p_value) {
} else if (script_instance) {
script_instance->set(p_name,p_value);
}
-
-
+
+
}
#endif
@@ -348,7 +348,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
*r_valid=true;
return;
} else {
- //something inside the object... :|
+ //something inside the object... :|
bool success = _setv(p_name,p_value);
if (success) {
if (r_valid)
@@ -420,7 +420,7 @@ Variant Object::get(const String& p_name) const {
Variant ret=_getv(p_name);
if (ret.get_type()!=Variant::NIL)
return ret;
-
+
bool success;
ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
if (success) {
@@ -431,11 +431,11 @@ Variant Object::get(const String& p_name) const {
return metadata;
else if (p_name=="script/script")
return script;
-
+
if (script_instance) {
return script_instance->get(p_name);
}
-
+
return Variant();
}
@@ -449,10 +449,10 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
}
_get_property_listv(p_list,p_reversed);
-
+
if (!_use_builtin_script())
return;
-
+
if (!is_type("Script")) // can still be set, but this is for userfriendlyness
p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
if (!metadata.empty())
@@ -460,15 +460,15 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
if (script_instance && !p_reversed) {
p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY));
script_instance->get_property_list(p_list);
- }
-
+ }
+
}
void Object::get_method_list(List<MethodInfo> *p_list) const {
ObjectTypeDB::get_method_list(get_type_name(),p_list);
if (script_instance) {
script_instance->get_method_list(p_list);
- }
+ }
}
@@ -898,22 +898,22 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
void Object::notification(int p_notification,bool p_reversed) {
-
+
_notificationv(p_notification,p_reversed);
-
+
if (script_instance) {
script_instance->notification(p_notification);
}
}
void Object::_changed_callback(Object *p_changed,const char *p_prop) {
-
-
+
+
}
void Object::add_change_receptor( Object *p_receptor ) {
-
+
change_receptors.insert(p_receptor);
}
@@ -941,8 +941,8 @@ void Object::set_script(const RefPtr& p_script) {
memdelete(script_instance);
script_instance=NULL;
}
-
- script=p_script;
+
+ script=p_script;
Ref<Script> s(script);
if (!s.is_null() && s->can_instance() ) {
@@ -1760,7 +1760,7 @@ bool Object::is_edited() const {
#endif
Object::Object() {
-
+
_type_ptr=NULL;
_block_signals=false;
_predelete_ok=0;
@@ -1831,12 +1831,12 @@ Object::~Object() {
bool predelete_handler(Object *p_object) {
-
+
return p_object->_predelete();
}
void postinitialize_handler(Object *p_object) {
-
+
p_object->_postinitialize();
}
@@ -1900,8 +1900,8 @@ void ObjectDB::cleanup() {
GLOBAL_LOCK_FUNCTION;
if (instances.size()) {
-
- WARN_PRINT("ObjectDB Instances still exist!");
+
+ WARN_PRINT("ObjectDB Instances still exist!");
if (OS::get_singleton()->is_stdout_verbose()) {
const uint32_t *K=NULL;
while((K=instances.next(K))) {
diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp
index dd9304f1f9..14b595d61b 100644
--- a/core/object_type_db.cpp
+++ b/core/object_type_db.cpp
@@ -200,37 +200,37 @@ ObjectTypeDB::TypeInfo::TypeInfo() {
disabled=false;
}
ObjectTypeDB::TypeInfo::~TypeInfo() {
-
-
+
+
}
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
-
+
OBJTYPE_LOCK;
-
+
StringName inherits=p_type;
-
+
while (inherits.operator String().length()) {
-
+
if (inherits==p_inherits)
return true;
inherits=type_inherits_from(inherits);
}
-
+
return false;
}
void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
-
+
OBJTYPE_LOCK;
-
+
const StringName *k=NULL;
-
+
while((k=types.next(k))) {
-
+
p_types->push_back(*k);
}
-
+
p_types->sort();
}
@@ -238,11 +238,11 @@ void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) {
OBJTYPE_LOCK;
-
+
const StringName *k=NULL;
-
+
while((k=types.next(k))) {
-
+
if (*k!=p_type && is_type(*k,p_type))
p_types->push_back(*k);
}
@@ -250,18 +250,18 @@ void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName
}
StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
-
+
OBJTYPE_LOCK;
-
+
TypeInfo *ti = types.getptr(p_type);
ERR_FAIL_COND_V(!ti,"");
return ti->inherits;
}
bool ObjectTypeDB::type_exists(const StringName &p_type) {
-
+
OBJTYPE_LOCK;
- return types.has(p_type);
+ return types.has(p_type);
}
void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringName& p_fallback) {
@@ -270,7 +270,7 @@ void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringN
}
Object *ObjectTypeDB::instance(const StringName &p_type) {
-
+
TypeInfo *ti;
{
OBJTYPE_LOCK;
@@ -288,9 +288,9 @@ Object *ObjectTypeDB::instance(const StringName &p_type) {
return ti->creation_func();
}
bool ObjectTypeDB::can_instance(const StringName &p_type) {
-
+
OBJTYPE_LOCK;
-
+
TypeInfo *ti = types.getptr(p_type);
ERR_FAIL_COND_V(!ti,false);
return (!ti->disabled && ti->creation_func!=NULL);
@@ -326,11 +326,11 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
OBJTYPE_LOCK;
-
+
TypeInfo *type=types.getptr(p_type);
-
+
while(type) {
-
+
if (type->disabled) {
if (p_no_inheritance)
@@ -348,14 +348,14 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
}
for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) {
-
+
MethodBind *method=type->method_map.get(E->get());
MethodInfo minfo;
minfo.name=E->get();
minfo.id=method->get_method_id();
for (int i=0;i<method->get_argument_count();i++) {
-
+
//Variant::Type t=method->get_argument_type(i);
minfo.arguments.push_back(method->get_argument_info(i));
@@ -386,24 +386,24 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
#endif
-
+
if (p_no_inheritance)
break;
-
+
type=type->inherits_ptr;
}
-
+
}
MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
OBJTYPE_LOCK;
-
+
TypeInfo *type=types.getptr(p_type);
-
+
while(type) {
-
+
MethodBind **method=type->method_map.getptr(p_name);
if (method && *method)
return *method;
@@ -416,18 +416,18 @@ MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant) {
OBJTYPE_LOCK;
-
+
TypeInfo *type=types.getptr(p_type);
if (!type) {
ERR_FAIL_COND(!type);
}
-
+
if (type->constant_map.has(p_name)) {
ERR_FAIL();
}
-
+
type->constant_map[p_name]=p_constant;
#ifdef DEBUG_METHODS_ENABLED
type->constant_order.push_back(p_name);
@@ -438,11 +438,11 @@ void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringN
void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance) {
OBJTYPE_LOCK;
-
+
TypeInfo *type=types.getptr(p_type);
-
+
while(type) {
-
+
#ifdef DEBUG_METHODS_ENABLED
for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
p_constants->push_back(E->get());
@@ -456,7 +456,7 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
#endif
if (p_no_inheritance)
break;
-
+
type=type->inherits_ptr;
}
@@ -466,28 +466,28 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
int ObjectTypeDB::get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success) {
OBJTYPE_LOCK;
-
-
+
+
TypeInfo *type=types.getptr(p_type);
-
+
while(type) {
-
+
int *constant=type->constant_map.getptr(p_name);
if (constant) {
-
+
if (p_success)
*p_success=true;
return *constant;
}
-
+
type=type->inherits_ptr;
}
-
+
if (p_success)
- *p_success=false;
+ *p_success=false;
- return 0;
+ return 0;
}
void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) {
@@ -966,7 +966,7 @@ void ObjectTypeDB::init() {
}
void ObjectTypeDB::cleanup() {
-
+
#ifndef NO_THREADS
@@ -974,19 +974,19 @@ void ObjectTypeDB::cleanup() {
#endif
//OBJTYPE_LOCK; hah not here
-
+
const StringName *k=NULL;
-
+
while((k=types.next(k))) {
-
+
TypeInfo &ti=types[*k];
-
+
const StringName *m=NULL;
while((m=ti.method_map.next(m))) {
-
+
memdelete( ti.method_map[*m] );
}
- }
+ }
types.clear();
resource_base_extensions.clear();
compat_types.clear();
diff --git a/core/object_type_db.h b/core/object_type_db.h
index f6caf14be5..a4896fff81 100644
--- a/core/object_type_db.h
+++ b/core/object_type_db.h
@@ -42,9 +42,9 @@ struct ParamHint {
PropertyHint hint;
String hint_text;
Variant default_val;
-
+
ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
-
+
name=p_name;
hint=p_hint;
hint_text=p_hint_text;
@@ -73,9 +73,9 @@ struct MethodDefinition {
StringName name;
Vector<StringName> args;
- MethodDefinition() {}
+ MethodDefinition() {}
MethodDefinition(const char *p_name) { name=p_name; }
- MethodDefinition(const StringName& p_name) { name=p_name; }
+ MethodDefinition(const StringName& p_name) { name=p_name; }
};
@@ -109,7 +109,7 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
#endif
class ObjectTypeDB {
-
+
struct PropertySetGet {
int index;
@@ -121,7 +121,7 @@ class ObjectTypeDB {
};
struct TypeInfo {
-
+
TypeInfo *inherits_ptr;
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
HashMap<StringName,int,StringNameHasher> constant_map;
@@ -143,12 +143,12 @@ class ObjectTypeDB {
TypeInfo();
~TypeInfo();
};
-
+
template<class T>
static Object *creator() {
return memnew( T );
}
-
+
static Mutex *lock;
static HashMap<StringName,TypeInfo,StringNameHasher> types;
static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions;
@@ -163,8 +163,8 @@ class ObjectTypeDB {
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
-public:
-
+public:
+
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template<class T>
static void _add_type() {
@@ -195,7 +195,7 @@ public:
template<class T>
static void register_type() {
-
+
GLOBAL_LOCK_FUNCTION;
T::initialize_type();
TypeInfo *t=types.getptr(T::get_type_static());
@@ -206,7 +206,7 @@ public:
template<class T>
static void register_virtual_type() {
-
+
GLOBAL_LOCK_FUNCTION;
T::initialize_type();
//nothing
@@ -247,9 +247,9 @@ public:
ParamDef d4=ParamDef(),
ParamDef d5=ParamDef()
) {
-
+
return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5);
- }
+ }
@@ -472,7 +472,7 @@ public:
static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true );
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
-
+
static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
diff --git a/core/os/copymem.cpp b/core/os/copymem.cpp
index 234ca50b45..49f53f1a51 100644
--- a/core/os/copymem.cpp
+++ b/core/os/copymem.cpp
@@ -32,7 +32,7 @@
void movemem_system(void *to, void *from,int amount) {
- memmove(to,from,amount);
+ memmove(to,from,amount);
}
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 32d66a7408..9a7135913a 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -344,7 +344,7 @@ DirAccess *DirAccess::open(const String& p_path,Error *r_error) {
}
DirAccess *DirAccess::create(AccessType p_access) {
-
+
DirAccess * da = create_func[p_access]?create_func[p_access]():NULL;
if (da) {
da->_access_type=p_access;
@@ -359,7 +359,7 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
DirAccess *d=DirAccess::create(p_access);
if (!d)
return p_path;
-
+
d->change_dir(p_path);
String full=d->get_current_dir();
memdelete(d);
@@ -367,31 +367,31 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
}
Error DirAccess::copy(String p_from,String p_to) {
-
+
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
Error err;
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err);
-
+
if (err) {
ERR_FAIL_COND_V( err, err );
}
-
+
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err );
if (err) {
-
+
fsrc->close();
memdelete( fsrc );
ERR_FAIL_COND_V( err, err );
}
-
+
fsrc->seek_end(0);
int size = fsrc->get_pos();
fsrc->seek(0);
err = OK;
while(size--) {
-
+
if (fsrc->get_error()!=OK) {
err= fsrc->get_error();
break;
@@ -400,13 +400,13 @@ Error DirAccess::copy(String p_from,String p_to) {
err= fdst->get_error();
break;
}
-
+
fdst->store_8( fsrc->get_8() );
}
-
+
memdelete(fsrc);
memdelete(fdst);
-
+
return err;
}
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index e97a065998..7a850ddc6d 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -79,13 +79,13 @@ public:
virtual String get_next()=0;
virtual bool current_is_dir() const=0;
virtual bool current_is_hidden() const=0;
-
- virtual void list_dir_end()=0; ///<
-
+
+ virtual void list_dir_end()=0; ///<
+
virtual int get_drive_count()=0;
virtual String get_drive(int p_drive)=0;
virtual int get_current_drive();
-
+
virtual Error change_dir(String p_dir)=0; ///< can be relative or absolute, return false on success
virtual String get_current_dir()=0; ///< return current dir location
virtual Error make_dir(String p_dir)=0;
@@ -100,7 +100,7 @@ public:
virtual Error copy(String p_from,String p_to);
virtual Error rename(String p_from, String p_to)=0;
virtual Error remove(String p_name)=0;
-
+
static String get_full_path(const String& p_path,AccessType p_access);
static DirAccess *create_for_path(const String& p_path);
@@ -111,7 +111,7 @@ public:
FILE_TYPE_FILE,
FILE_TYPE_DIR,
};
-
+
//virtual DirType get_file_type() const=0;
*/
static DirAccess *create(AccessType p_access);
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index d82d0b63c5..0846ef3eb0 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -169,69 +169,69 @@ String FileAccess::fix_path(const String& p_path) const {
return r_path;
} break;
}
-
+
return r_path;
}
/* these are all implemented for ease of porting, then can later be optimized */
uint16_t FileAccess::get_16()const {
-
+
uint16_t res;
uint8_t a,b;
-
+
a=get_8();
b=get_8();
-
+
if (endian_swap) {
-
+
SWAP( a,b );
}
-
+
res=b;
res<<=8;
res|=a;
-
+
return res;
}
uint32_t FileAccess::get_32() const{
-
+
uint32_t res;
uint16_t a,b;
-
+
a=get_16();
b=get_16();
-
+
if (endian_swap) {
-
+
SWAP( a,b );
}
-
+
res=b;
res<<=16;
res|=a;
-
- return res;
+
+ return res;
}
uint64_t FileAccess::get_64()const {
-
+
uint64_t res;
uint32_t a,b;
-
+
a=get_32();
b=get_32();
-
+
if (endian_swap) {
-
+
SWAP( a,b );
}
-
+
res=b;
res<<=32;
res|=a;
-
- return res;
-
+
+ return res;
+
}
float FileAccess::get_float() const {
@@ -262,22 +262,24 @@ String FileAccess::get_line() const {
CharString line;
CharType c=get_8();
-
+
while(!eof_reached()) {
-
+
if (c=='\n' || c=='\0') {
line.push_back(0);
return String::utf8(line.get_data());
} else if (c!='\r')
line.push_back(c);
-
+
c=get_8();
}
line.push_back(0);
return String::utf8(line.get_data());
}
-Vector<String> FileAccess::get_csv_line() const {
+Vector<String> FileAccess::get_csv_line(String delim) const {
+
+ ERR_FAIL_COND_V(delim.length()!=1,Vector<String>());
String l;
int qc=0;
@@ -303,7 +305,7 @@ Vector<String> FileAccess::get_csv_line() const {
CharType s[2]={0,0};
- if (!in_quote && c==',') {
+ if (!in_quote && c==delim[0]) {
strings.push_back(current);
current=String();
} else if (c=='"') {
@@ -329,7 +331,7 @@ Vector<String> FileAccess::get_csv_line() const {
int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
-
+
int i=0;
for (i=0; i<p_length && !eof_reached(); i++)
p_dst[i]=get_8();
@@ -338,53 +340,53 @@ int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
}
void FileAccess::store_16(uint16_t p_dest) {
-
+
uint8_t a,b;
-
+
a=p_dest&0xFF;
b=p_dest>>8;
-
+
if (endian_swap) {
-
+
SWAP( a,b );
}
-
+
store_8(a);
store_8(b);
}
void FileAccess::store_32(uint32_t p_dest) {
-
-
+
+
uint16_t a,b;
-
+
a=p_dest&0xFFFF;
b=p_dest>>16;
-
+
if (endian_swap) {
-
+
SWAP( a,b );
}
-
+
store_16(a);
store_16(b);
-
+
}
void FileAccess::store_64(uint64_t p_dest) {
-
+
uint32_t a,b;
-
+
a=p_dest&0xFFFFFFFF;
b=p_dest>>32;
-
+
if (endian_swap) {
-
+
SWAP( a,b );
}
-
+
store_32(a);
store_32(b);
-
+
}
void FileAccess::store_real(real_t p_real) {
@@ -459,7 +461,7 @@ void FileAccess::store_line(const String& p_line) {
}
void FileAccess::store_buffer(const uint8_t *p_src,int p_length) {
-
+
for (int i=0;i<p_length;i++)
store_8(p_src[i]);
}
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 51cf839117..2c894c94eb 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -80,21 +80,21 @@ public:
READ_WRITE=3,
WRITE_READ=7,
};
-
- virtual void close()=0; ///< close a file
- virtual bool is_open() const=0; ///< true when file is open
- virtual void seek(size_t p_position)=0; ///< seek to a given position
- virtual void seek_end(int64_t p_position=0)=0; ///< seek from the end of file
- virtual size_t get_pos() const=0; ///< get position in the file
- virtual size_t get_len() const=0; ///< get size of the file
+ virtual void close()=0; ///< close a file
+ virtual bool is_open() const=0; ///< true when file is open
- virtual bool eof_reached() const=0; ///< reading passed EOF
+ virtual void seek(size_t p_position)=0; ///< seek to a given position
+ virtual void seek_end(int64_t p_position=0)=0; ///< seek from the end of file
+ virtual size_t get_pos() const=0; ///< get position in the file
+ virtual size_t get_len() const=0; ///< get size of the file
- virtual uint8_t get_8() const=0; ///< get a byte
- virtual uint16_t get_16() const; ///< get 16 bits uint
- virtual uint32_t get_32() const; ///< get 32 bits uint
- virtual uint64_t get_64() const; ///< get 64 bits uint
+ virtual bool eof_reached() const=0; ///< reading passed EOF
+
+ virtual uint8_t get_8() const=0; ///< get a byte
+ virtual uint16_t get_16() const; ///< get 16 bits uint
+ virtual uint32_t get_32() const; ///< get 32 bits uint
+ virtual uint64_t get_64() const; ///< get 64 bits uint
virtual float get_float() const;
virtual double get_double() const;
@@ -102,22 +102,22 @@ public:
virtual int get_buffer(uint8_t *p_dst,int p_length) const; ///< get an array of bytes
virtual String get_line() const;
- virtual Vector<String> get_csv_line() const;
-
+ virtual Vector<String> get_csv_line(String delim=",") const;
+
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
* this flags get reset to false (little endian) on each open
*/
-
+
virtual void set_endian_swap(bool p_swap) { endian_swap=p_swap; }
inline bool get_endian_swap() const { return endian_swap; }
- virtual Error get_error() const=0; ///< get last error
+ virtual Error get_error() const=0; ///< get last error
- virtual void store_8(uint8_t p_dest)=0; ///< store a byte
- virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
- virtual void store_32(uint32_t p_dest); ///< store 32 bits uint
- virtual void store_64(uint64_t p_dest); ///< store 64 bits uint
+ virtual void store_8(uint8_t p_dest)=0; ///< store a byte
+ virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
+ virtual void store_32(uint32_t p_dest); ///< store 32 bits uint
+ virtual void store_64(uint64_t p_dest); ///< store 64 bits uint
virtual void store_float(float p_dest);
virtual void store_double(double p_dest);
@@ -129,9 +129,9 @@ public:
virtual void store_pascal_string(const String& p_string);
virtual String get_pascal_string();
- virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
-
- virtual bool file_exists(const String& p_name)=0; ///< return true if a file exists
+ virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
+
+ virtual bool file_exists(const String& p_name)=0; ///< return true if a file exists
virtual Error reopen(const String& p_path, int p_mode_flags); ///< does not change the AccessType
diff --git a/core/os/input.h b/core/os/input.h
index 2dd4496f26..535776f39c 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -55,7 +55,7 @@ public:
static Input *get_singleton();
- virtual bool is_key_pressed(int p_scancode)=0;
+ virtual bool is_key_pressed(int p_scancode)=0;
virtual bool is_mouse_button_pressed(int p_button)=0;
virtual bool is_joy_button_pressed(int p_device, int p_button)=0;
virtual bool is_action_pressed(const StringName& p_action)=0;
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 2f39567a7e..2d47645a66 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -30,7 +30,7 @@
#include "input_map.h"
#include "os/keyboard.h"
/**
- *
+ *
*/
bool InputEvent::operator==(const InputEvent &p_event) const {
@@ -40,15 +40,15 @@ bool InputEvent::operator==(const InputEvent &p_event) const {
InputEvent::operator String() const {
String str="Device "+itos(device)+" ID "+itos(ID)+" ";
-
+
switch(type) {
-
+
case NONE: {
-
+
return "Event: None";
} break;
case KEY: {
-
+
str+= "Event: Key ";
str=str+"Unicode: "+String::chr(key.unicode)+" Scan: "+itos( key.scancode )+" Echo: "+String(key.echo?"True":"False")+" Pressed"+String(key.pressed?"True":"False")+" Mod: ";
if (key.mod.shift)
@@ -59,15 +59,15 @@ InputEvent::operator String() const {
str+="A";
if (key.mod.meta)
str+="M";
-
+
return str;
} break;
case MOUSE_MOTION: {
-
+
str+= "Event: Motion ";
str=str+" Pos: " +itos(mouse_motion.x)+","+itos(mouse_motion.y)+" Rel: "+itos(mouse_motion.relative_x)+","+itos(mouse_motion.relative_y)+" Mask: ";
for (int i=0;i<8;i++) {
-
+
if ((1<<i)&mouse_motion.button_mask)
str+=itos(i+1);
}
@@ -87,7 +87,7 @@ InputEvent::operator String() const {
str+= "Event: Button ";
str=str+"Pressed: "+itos(mouse_button.pressed)+" Pos: " +itos(mouse_button.x)+","+itos(mouse_button.y)+" Button: "+itos(mouse_button.button_index)+" Mask: ";
for (int i=0;i<8;i++) {
-
+
if ((1<<i)&mouse_button.button_mask)
str+=itos(i+1);
}
@@ -102,18 +102,18 @@ InputEvent::operator String() const {
str+="M";
str+=String(" DoubleClick: ")+(mouse_button.doubleclick?"Yes":"No");
-
+
return str;
-
+
} break;
case JOYSTICK_MOTION: {
- str+= "Event: JoyMotion ";
+ str+= "Event: JoystickMotion ";
str=str+"Axis: "+itos(joy_motion.axis)+" Value: " +rtos(joy_motion.axis_value);
return str;
} break;
case JOYSTICK_BUTTON: {
- str+= "Event: JoyButton ";
+ str+= "Event: JoystickButton ";
str=str+"Pressed: "+itos(joy_button.pressed)+" Index: " +itos(joy_button.button_index)+" pressure "+rtos(joy_button.pressure);
return str;
@@ -137,7 +137,7 @@ InputEvent::operator String() const {
} break;
}
-
+
return "";
}
diff --git a/core/os/input_event.h b/core/os/input_event.h
index b601adc875..0588374790 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -51,6 +51,8 @@ enum {
BUTTON_MIDDLE=3,
BUTTON_WHEEL_UP=4,
BUTTON_WHEEL_DOWN=5,
+ BUTTON_WHEEL_LEFT=6,
+ BUTTON_WHEEL_RIGHT=7,
BUTTON_MASK_LEFT=(1<<(BUTTON_LEFT-1)),
BUTTON_MASK_RIGHT=(1<<(BUTTON_RIGHT-1)),
BUTTON_MASK_MIDDLE=(1<<(BUTTON_MIDDLE-1)),
@@ -187,7 +189,7 @@ struct InputModifierState {
struct InputEventKey {
InputModifierState mod;
-
+
bool pressed; /// otherwise release
uint32_t scancode; ///< check keyboard.h , KeyCode enum, without modifier masks
@@ -210,11 +212,11 @@ struct InputEventMouse {
struct InputEventMouseButton : public InputEventMouse {
-
+
int button_index;
bool pressed; //otherwise released
bool doubleclick; //last even less than doubleclick time
-
+
};
struct InputEventMouseMotion : public InputEventMouse {
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index 633aa06a9a..4c0a074a07 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -82,7 +82,7 @@ static const _KeyCodeText _keycodes[]={
{KEY_KP_ENTER ,"Kp Enter"},
{KEY_KP_MULTIPLY ,"Kp Multiply"},
{KEY_KP_DIVIDE ,"Kp Divide"},
- {KEY_KP_SUBSTRACT ,"Kp Substract"},
+ {KEY_KP_SUBTRACT ,"Kp Subtract"},
{KEY_KP_PERIOD ,"Kp Period"},
{KEY_KP_ADD ,"Kp Add"},
{KEY_KP_0 ,"Kp 0"},
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 69e74d1252..80472acc09 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -98,7 +98,7 @@ enum KeyList {
KEY_KP_ENTER=SPKEY | 0x80,
KEY_KP_MULTIPLY=SPKEY | 0x81,
KEY_KP_DIVIDE=SPKEY | 0x82,
- KEY_KP_SUBSTRACT=SPKEY | 0x83,
+ KEY_KP_SUBTRACT=SPKEY | 0x83,
KEY_KP_PERIOD=SPKEY | 0x84,
KEY_KP_ADD=SPKEY | 0x85,
KEY_KP_0=SPKEY | 0x86,
@@ -121,7 +121,7 @@ enum KeyList {
KEY_DIRECTION_R=SPKEY | 0x33,
KEY_BACK=SPKEY | 0x40,
KEY_FORWARD=SPKEY | 0x41,
- KEY_STOP=SPKEY | 0x42,
+ KEY_STOP=SPKEY | 0x42,
KEY_REFRESH=SPKEY | 0x43,
KEY_VOLUMEDOWN=SPKEY | 0x44,
KEY_VOLUMEMUTE=SPKEY | 0x45,
@@ -159,11 +159,11 @@ enum KeyList {
KEY_LAUNCHD=SPKEY | 0x65,
KEY_LAUNCHE=SPKEY | 0x66,
KEY_LAUNCHF=SPKEY | 0x67,
-
+
KEY_UNKNOWN=SPKEY | 0xFFFFFF,
-
+
/* PRINTABLE LATIN 1 CODES */
-
+
KEY_SPACE=0x0020,
KEY_EXCLAM=0x0021,
KEY_QUOTEDBL=0x0022,
@@ -297,18 +297,18 @@ enum KeyList {
KEY_YACUTE=0x00DD,
KEY_THORN=0x00DE,
KEY_SSHARP=0x00DF,
-
+
KEY_DIVISION=0x00F7,
KEY_YDIAERESIS=0x00FF,
-
-
+
+
};
enum KeyModifierMask {
-
+
KEY_CODE_MASK=((1<<25)-1), ///< Apply this mask to any keycode to remove modifiers.
- KEY_MODIFIER_MASK=(0xFF<<24), ///< Apply this mask to isolate modifiers.
+ KEY_MODIFIER_MASK=(0xFF<<24), ///< Apply this mask to isolate modifiers.
KEY_MASK_SHIFT = (1<<25),
KEY_MASK_ALT = (1<<26),
KEY_MASK_META = (1<<27),
@@ -322,7 +322,7 @@ enum KeyModifierMask {
KEY_MASK_KPAD = (1<<29),
KEY_MASK_GROUP_SWITCH = (1<<30)
// bit 31 can't be used because variant uses regular 32 bits int as datatype
-
+
};
String keycode_get_string(uint32_t p_code);
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index 059624dbe4..a34014983e 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -36,7 +36,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class MainLoop : public Object {
-
+
OBJ_TYPE( MainLoop, Object );
OBJ_CATEGORY("Main Loop");
@@ -44,7 +44,7 @@ class MainLoop : public Object {
protected:
static void _bind_methods();
-public:
+public:
enum {
NOTIFICATION_WM_MOUSE_ENTER = 3,
@@ -55,7 +55,7 @@ public:
NOTIFICATION_WM_UNFOCUS_REQUEST = 8,
NOTIFICATION_OS_MEMORY_WARNING = 9,
};
-
+
virtual void input_event( const InputEvent& p_event );
virtual void input_text( const String& p_text );
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index f7f8fef2b7..c2ff2aa781 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -88,16 +88,16 @@ void Memory::dump_static_mem_to_file(const char* p_file) {
MID Memory::alloc_dynamic(size_t p_bytes, const char *p_descr) {
MemoryPoolDynamic::ID id = MemoryPoolDynamic::get_singleton()->alloc(p_bytes,p_descr);
-
+
return MID(id);
}
Error Memory::realloc_dynamic(MID p_mid,size_t p_bytes) {
MemoryPoolDynamic::ID id = p_mid.data?p_mid.data->id:MemoryPoolDynamic::INVALID_ID;
-
+
if (id==MemoryPoolDynamic::INVALID_ID)
return ERR_INVALID_PARAMETER;
-
+
return MemoryPoolDynamic::get_singleton()->realloc(p_mid, p_bytes);
}
diff --git a/core/os/memory.h b/core/os/memory.h
index 98b973bc06..8257e66851 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -42,61 +42,61 @@
class MID {
struct Data {
-
+
SafeRefCount refcount;
MemoryPoolDynamic::ID id;
};
mutable Data *data;
-
+
void unref() {
-
+
if (!data)
return;
if (data->refcount.unref()) {
-
+
if (data->id!=MemoryPoolDynamic::INVALID_ID)
- MemoryPoolDynamic::get_singleton()->free(data->id);
- MemoryPoolStatic::get_singleton()->free(data);
+ MemoryPoolDynamic::get_singleton()->free(data->id);
+ MemoryPoolStatic::get_singleton()->free(data);
}
-
+
data=NULL;
}
-
+
void ref(Data *p_data) {
-
+
if (data==p_data)
return;
unref();
-
+
if (p_data && p_data->refcount.ref())
- data=p_data;
+ data=p_data;
}
-
+
friend class MID_Lock;
inline void lock() {
-
+
if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
MemoryPoolDynamic::get_singleton()->lock(data->id);
}
inline void unlock() {
-
+
if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
MemoryPoolDynamic::get_singleton()->unlock(data->id);
-
+
}
-
+
inline void * get() {
-
+
if (data && data->id!=MemoryPoolDynamic::INVALID_ID)
return MemoryPoolDynamic::get_singleton()->get(data->id);
-
+
return NULL;
}
-
- Error _resize(size_t p_size) {
-
+
+ Error _resize(size_t p_size) {
+
if (p_size==0 && (!data || data->id==MemoryPoolDynamic::INVALID_ID))
return OK;
if (p_size && !data) {
@@ -104,46 +104,46 @@ friend class MID_Lock;
data = (Data*)MemoryPoolStatic::get_singleton()->alloc(sizeof(Data),"MID::Data");
ERR_FAIL_COND_V( !data,ERR_OUT_OF_MEMORY );
data->refcount.init();
- data->id=MemoryPoolDynamic::INVALID_ID;
+ data->id=MemoryPoolDynamic::INVALID_ID;
}
-
+
if (p_size==0 && data && data->id==MemoryPoolDynamic::INVALID_ID) {
-
+
MemoryPoolDynamic::get_singleton()->free(data->id);
data->id=MemoryPoolDynamic::INVALID_ID;
}
-
+
if (p_size>0) {
-
+
if (data->id==MemoryPoolDynamic::INVALID_ID) {
-
+
data->id=MemoryPoolDynamic::get_singleton()->alloc(p_size,"Unnamed MID");
ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
} else {
-
+
MemoryPoolDynamic::get_singleton()->realloc(data->id,p_size);
ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
-
+
}
- }
-
+ }
+
return OK;
}
friend class Memory;
-
+
MID(MemoryPoolDynamic::ID p_id) {
-
+
data = (Data*)MemoryPoolStatic::get_singleton()->alloc(sizeof(Data),"MID::Data");
data->refcount.init();
data->id=p_id;
}
-public:
+public:
bool is_valid() const { return data; }
operator bool() const { return data; }
-
-
+
+
size_t get_size() const { return (data && data->id!=MemoryPoolDynamic::INVALID_ID) ? MemoryPoolDynamic::get_singleton()->get_size(data->id) : 0; }
Error resize(size_t p_size) { return _resize(p_size); }
inline void operator=(const MID& p_mid) { ref( p_mid.data ); }
@@ -157,7 +157,7 @@ public:
class MID_Lock {
MID mid;
-
+
public:
void *data() { return mid.get(); }
@@ -174,21 +174,21 @@ class Memory{
Memory();
public:
-
+
static void * alloc_static(size_t p_bytes,const char *p_descr="");
static void * realloc_static(void *p_memory,size_t p_bytes);
static void free_static(void *p_ptr);
static size_t get_static_mem_available();
- static size_t get_static_mem_usage();
+ static size_t get_static_mem_usage();
static size_t get_static_mem_max_usage();
static void dump_static_mem_to_file(const char* p_file);
static MID alloc_dynamic(size_t p_bytes, const char *p_descr="");
static Error realloc_dynamic(MID p_mid,size_t p_bytes);
-
+
static size_t get_dynamic_mem_available();
static size_t get_dynamic_mem_usage();
-
+
};
template<class T>
@@ -241,7 +241,7 @@ _ALWAYS_INLINE_ void postinitialize_handler(void *) {}
template<class T>
_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
-
+
postinitialize_handler(p_obj);
return p_obj;
}
@@ -272,7 +272,7 @@ _ALWAYS_INLINE_ bool predelete_handler(void *) { return true; }
template<class T>
void memdelete(T *p_class) {
-
+
if (!predelete_handler(p_class))
return; // doesn't want to be deleted
p_class->~T();
@@ -308,11 +308,11 @@ T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
same strategy used by std::vector, and the DVector class, so it should be safe.*/
size_t len = sizeof(T) * p_elements;
- unsigned int *mem = (unsigned int*)Memory::alloc_static( len + DEFAULT_ALIGNMENT, p_descr );
+ unsigned int *mem = (unsigned int*)Memory::alloc_static( len + MAX(sizeof(size_t), DEFAULT_ALIGNMENT), p_descr );
T *failptr=0; //get rid of a warning
ERR_FAIL_COND_V( !mem, failptr );
*mem=p_elements;
- mem = (unsigned int *)( ((uint8_t*)mem) + DEFAULT_ALIGNMENT);
+ mem = (unsigned int *)( ((uint8_t*)mem) + MAX(sizeof(size_t), DEFAULT_ALIGNMENT));
T* elems = (T*)mem;
/* call operator new */
@@ -331,14 +331,14 @@ T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
template<typename T>
size_t memarr_len(const T *p_class) {
- uint8_t* ptr = ((uint8_t*)p_class) - DEFAULT_ALIGNMENT;
+ uint8_t* ptr = ((uint8_t*)p_class) - MAX(sizeof(size_t), DEFAULT_ALIGNMENT);
return *(size_t*)ptr;
}
template<typename T>
void memdelete_arr(T *p_class) {
- unsigned int * elems = (unsigned int*)(((uint8_t*)p_class) - DEFAULT_ALIGNMENT);
+ unsigned int * elems = (unsigned int*)(((uint8_t*)p_class) - MAX(sizeof(size_t), DEFAULT_ALIGNMENT));
for (unsigned int i=0;i<*elems;i++) {
diff --git a/core/os/memory_pool_dynamic.h b/core/os/memory_pool_dynamic.h
index 82149bcf5d..70752fb10d 100644
--- a/core/os/memory_pool_dynamic.h
+++ b/core/os/memory_pool_dynamic.h
@@ -40,10 +40,10 @@ friend class Memory;
friend class MID;
enum {
-
+
INVALID_ID=0xFFFFFFFF
};
-
+
static MemoryPoolDynamic* get_singleton();
typedef uint64_t ID;
@@ -55,12 +55,12 @@ friend class MID;
virtual bool is_valid(ID p_id)=0;
virtual size_t get_size(ID p_id) const=0;
virtual const char* get_description(ID p_id) const=0;
-
+
virtual Error lock(ID p_id)=0;
virtual void * get(ID p_ID)=0;
virtual Error unlock(ID p_id)=0;
virtual bool is_locked(ID p_id) const=0;
-
+
virtual size_t get_available_mem() const=0;
virtual size_t get_total_usage() const=0;
diff --git a/core/os/memory_pool_dynamic_static.cpp b/core/os/memory_pool_dynamic_static.cpp
index 894066708e..c047c931ec 100644
--- a/core/os/memory_pool_dynamic_static.cpp
+++ b/core/os/memory_pool_dynamic_static.cpp
@@ -37,10 +37,10 @@ MemoryPoolDynamicStatic::Chunk *MemoryPoolDynamicStatic::get_chunk(ID p_id) {
uint64_t check = p_id/MAX_CHUNKS;
uint64_t idx = p_id%MAX_CHUNKS;
-
+
if (!chunk[idx].mem || chunk[idx].check!=check)
return NULL;
-
+
return &chunk[idx];
}
@@ -49,32 +49,32 @@ const MemoryPoolDynamicStatic::Chunk *MemoryPoolDynamicStatic::get_chunk(ID p_id
uint64_t check = p_id/MAX_CHUNKS;
uint64_t idx = p_id%MAX_CHUNKS;
-
+
if (!chunk[idx].mem || chunk[idx].check!=check)
return NULL;
-
+
return &chunk[idx];
}
MemoryPoolDynamic::ID MemoryPoolDynamicStatic::alloc(size_t p_amount,const char* p_description) {
_THREAD_SAFE_METHOD_
-
+
int idx=-1;
-
+
for (int i=0;i<MAX_CHUNKS;i++) {
-
+
last_alloc++;
if (last_alloc>=MAX_CHUNKS)
last_alloc=0;
-
+
if ( !chunk[last_alloc].mem ) {
-
+
idx=last_alloc;
break;
}
}
-
+
if (idx==-1) {
ERR_EXPLAIN("Out of dynamic Memory IDs");
@@ -86,36 +86,36 @@ MemoryPoolDynamic::ID MemoryPoolDynamicStatic::alloc(size_t p_amount,const char*
chunk[idx].mem = memalloc(p_amount);
if (!chunk[idx].mem)
return INVALID_ID;
-
+
chunk[idx].size=p_amount;
chunk[idx].check=++last_check;
chunk[idx].descr=p_description;
chunk[idx].lock=0;
-
+
total_usage+=p_amount;
if (total_usage>max_usage)
max_usage=total_usage;
-
+
ID id = chunk[idx].check*MAX_CHUNKS + (uint64_t)idx;
-
+
return id;
-
+
}
void MemoryPoolDynamicStatic::free(ID p_id) {
_THREAD_SAFE_METHOD_
-
+
Chunk *c = get_chunk(p_id);
ERR_FAIL_COND(!c);
-
-
+
+
total_usage-=c->size;
memfree(c->mem);
c->mem=0;
-
+
if (c->lock>0) {
-
+
ERR_PRINT("Freed ID Still locked");
}
}
@@ -123,14 +123,14 @@ void MemoryPoolDynamicStatic::free(ID p_id) {
Error MemoryPoolDynamicStatic::realloc(ID p_id, size_t p_amount) {
_THREAD_SAFE_METHOD_
-
+
Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(c->lock > 0 , ERR_LOCKED );
-
-
+
+
void * new_mem = memrealloc(c->mem,p_amount);
-
+
ERR_FAIL_COND_V(!new_mem,ERR_OUT_OF_MEMORY);
total_usage-=c->size;
c->mem=new_mem;
@@ -138,37 +138,37 @@ Error MemoryPoolDynamicStatic::realloc(ID p_id, size_t p_amount) {
total_usage+=c->size;
if (total_usage>max_usage)
max_usage=total_usage;
-
+
return OK;
}
bool MemoryPoolDynamicStatic::is_valid(ID p_id) {
_THREAD_SAFE_METHOD_
-
+
Chunk *c = get_chunk(p_id);
-
+
return c!=NULL;
}
size_t MemoryPoolDynamicStatic::get_size(ID p_id) const {
_THREAD_SAFE_METHOD_
-
+
const Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,0);
-
+
return c->size;
-
+
}
const char* MemoryPoolDynamicStatic::get_description(ID p_id) const {
_THREAD_SAFE_METHOD_
-
+
const Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,"");
-
+
return c->descr;
}
@@ -177,10 +177,10 @@ const char* MemoryPoolDynamicStatic::get_description(ID p_id) const {
bool MemoryPoolDynamicStatic::is_locked(ID p_id) const {
_THREAD_SAFE_METHOD_
-
+
const Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,false);
-
+
return c->lock>0;
}
@@ -188,10 +188,10 @@ bool MemoryPoolDynamicStatic::is_locked(ID p_id) const {
Error MemoryPoolDynamicStatic::lock(ID p_id) {
_THREAD_SAFE_METHOD_
-
+
Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,ERR_INVALID_PARAMETER);
-
+
c->lock++;
return OK;
@@ -199,23 +199,23 @@ Error MemoryPoolDynamicStatic::lock(ID p_id) {
void * MemoryPoolDynamicStatic::get(ID p_id) {
_THREAD_SAFE_METHOD_
-
+
const Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,NULL);
ERR_FAIL_COND_V( c->lock==0, NULL );
-
+
return c->mem;
}
Error MemoryPoolDynamicStatic::unlock(ID p_id) {
_THREAD_SAFE_METHOD_
-
+
Chunk *c = get_chunk(p_id);
ERR_FAIL_COND_V(!c,ERR_INVALID_PARAMETER);
-
+
ERR_FAIL_COND_V( c->lock<=0, ERR_INVALID_PARAMETER );
c->lock--;
-
+
return OK;
}
@@ -226,7 +226,7 @@ size_t MemoryPoolDynamicStatic::get_available_mem() const {
size_t MemoryPoolDynamicStatic::get_total_usage() const {
_THREAD_SAFE_METHOD_
-
+
return total_usage;
}
diff --git a/core/os/memory_pool_dynamic_static.h b/core/os/memory_pool_dynamic_static.h
index 6177c78de7..a72d39355c 100644
--- a/core/os/memory_pool_dynamic_static.h
+++ b/core/os/memory_pool_dynamic_static.h
@@ -40,19 +40,19 @@ class MemoryPoolDynamicStatic : public MemoryPoolDynamic {
enum {
MAX_CHUNKS=65536
};
-
-
+
+
struct Chunk {
-
+
uint64_t lock;
uint64_t check;
void *mem;
size_t size;
- const char *descr;
-
+ const char *descr;
+
Chunk() { mem=NULL; lock=0; check=0; }
};
-
+
Chunk chunk[MAX_CHUNKS];
uint64_t last_check;
int last_alloc;
@@ -62,14 +62,14 @@ class MemoryPoolDynamicStatic : public MemoryPoolDynamic {
Chunk *get_chunk(ID p_id);
const Chunk *get_chunk(ID p_id) const;
public:
-
+
virtual ID alloc(size_t p_amount,const char* p_description);
virtual void free(ID p_id);
virtual Error realloc(ID p_id, size_t p_amount);
virtual bool is_valid(ID p_id);
virtual size_t get_size(ID p_id) const;
virtual const char* get_description(ID p_id) const;
-
+
virtual bool is_locked(ID p_id) const;
virtual Error lock(ID p_id);
virtual void * get(ID p_ID);
diff --git a/core/os/memory_pool_static.cpp b/core/os/memory_pool_static.cpp
index 321f4d989e..88c2ba3b3e 100644
--- a/core/os/memory_pool_static.cpp
+++ b/core/os/memory_pool_static.cpp
@@ -31,13 +31,13 @@
MemoryPoolStatic *MemoryPoolStatic::singleton=0;
MemoryPoolStatic *MemoryPoolStatic::get_singleton() {
-
+
return singleton;
}
MemoryPoolStatic::MemoryPoolStatic() {
-
+
singleton=this;
}
diff --git a/core/os/memory_pool_static.h b/core/os/memory_pool_static.h
index 2e11b7ded4..f7f60b8df8 100644
--- a/core/os/memory_pool_static.h
+++ b/core/os/memory_pool_static.h
@@ -38,17 +38,17 @@
*/
class MemoryPoolStatic {
private:
-
+
static MemoryPoolStatic *singleton;
public:
-
+
static MemoryPoolStatic *get_singleton();
-
+
virtual void* alloc(size_t p_bytes,const char *p_description)=0; ///< Pointer in p_description shold be to a const char const like "hello"
virtual void* realloc(void * p_memory,size_t p_bytes)=0; ///< Pointer in p_description shold be to a const char const like "hello"
virtual void free(void *p_ptr)=0; ///< Pointer in p_description shold be to a const char const
-
+
virtual size_t get_available_mem() const=0;
virtual size_t get_total_usage()=0;
virtual size_t get_max_usage()=0;
diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp
index 9b379009b9..21400d2ccf 100644
--- a/core/os/mutex.cpp
+++ b/core/os/mutex.cpp
@@ -50,13 +50,13 @@ Mutex::~Mutex() {
Mutex *_global_mutex=NULL;;
void _global_lock() {
-
+
if (_global_mutex)
_global_mutex->lock();
}
void _global_unlock() {
-
+
if (_global_mutex)
- _global_mutex->unlock();
+ _global_mutex->unlock();
}
diff --git a/core/os/mutex.h b/core/os/mutex.h
index f16375aa26..5870171dc7 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -33,7 +33,7 @@
/**
- * @class Mutex
+ * @class Mutex
* @author Juan Linietsky
* Portable Mutex (thread-safe locking) implementation.
* Mutexes are always recursive ( they don't self-lock in a single thread ).
@@ -43,9 +43,9 @@
class Mutex {
-protected:
+protected:
static Mutex* (*create_func)(bool);
-
+
public:
virtual void lock()=0; ///< Lock the mutex, block if locked by someone else
@@ -53,7 +53,7 @@ public:
virtual Error try_lock()=0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock.
static Mutex * create(bool p_recursive=true); ///< Create a mutex
-
+
virtual ~Mutex();
};
diff --git a/core/os/os.cpp b/core/os/os.cpp
index e93038f854..1aee6d9aa2 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -478,6 +478,10 @@ void OS::native_video_pause() {
};
+void OS::native_video_unpause() {
+
+};
+
void OS::native_video_stop() {
};
@@ -523,6 +527,10 @@ String OS::get_joy_guid(int p_device) const {
return "Default Joystick";
}
+void OS::set_context(int p_context) {
+
+}
+
OS::OS() {
last_error=NULL;
frames_drawn=0;
diff --git a/core/os/os.h b/core/os/os.h
index e53980a8fe..160c0495bb 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -71,42 +71,43 @@ public:
RENDER_SEPARATE_THREAD
};
struct VideoMode {
-
+
int width,height;
bool fullscreen;
bool resizable;
+ bool borderless_window;
float get_aspect() const { return (float)width/(float)height; }
- VideoMode(int p_width=1024,int p_height=600,bool p_fullscreen=false, bool p_resizable = true) {width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; }
+ VideoMode(int p_width=1024,int p_height=600,bool p_fullscreen=false, bool p_resizable = true,bool p_borderless_window=false) { width=p_width; height=p_height; fullscreen=p_fullscreen; resizable = p_resizable; borderless_window=p_borderless_window; }
};
protected:
friend class Main;
-
+
RenderThreadMode _render_thread_mode;
// functions used by main to initialize/deintialize the OS
virtual int get_video_driver_count() const=0;
virtual const char * get_video_driver_name(int p_driver) const=0;
-
+
virtual VideoMode get_default_video_mode() const=0;
-
+
virtual int get_audio_driver_count() const=0;
virtual const char * get_audio_driver_name(int p_driver) const=0;
-
+
virtual void initialize_core()=0;
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver)=0;
-
- virtual void set_main_loop( MainLoop * p_main_loop )=0;
+
+ virtual void set_main_loop( MainLoop * p_main_loop )=0;
virtual void delete_main_loop()=0;
-
+
virtual void finalize()=0;
virtual void finalize_core()=0;
virtual void set_cmdline(const char* p_execpath, const List<String>& p_args);
void _ensure_data_dir();
-
+
public:
-
+
typedef int64_t ProcessID;
static OS* get_singleton();
@@ -148,7 +149,7 @@ public:
virtual void set_clipboard(const String& p_text);
virtual String get_clipboard() const;
-
+
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0)=0;
virtual VideoMode get_video_mode(int p_screen=0) const=0;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const=0;
@@ -172,6 +173,10 @@ public:
virtual void set_window_maximized(bool p_enabled) {}
virtual bool is_window_maximized() const { return true; }
+ virtual void set_borderless_window(int p_borderless) {}
+ virtual bool get_borderless_window() { return 0; }
+
+
virtual void set_iterations_per_second(int p_ips);
virtual int get_iterations_per_second() const;
@@ -217,9 +222,11 @@ public:
DAY_FRIDAY,
DAY_SATURDAY
};
-
+
enum Month {
- MONTH_JANUARY,
+ /// Start at 1 to follow Windows SYSTEMTIME structure
+ /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
+ MONTH_JANUARY = 1,
MONTH_FEBRUARY,
MONTH_MARCH,
MONTH_APRIL,
@@ -234,7 +241,7 @@ public:
};
struct Date {
-
+
int year;
Month month;
int day;
@@ -243,7 +250,7 @@ public:
};
struct Time {
-
+
int hour;
int min;
int sec;
@@ -260,7 +267,7 @@ public:
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
- virtual void delay_usec(uint32_t p_usec) const=0;
+ virtual void delay_usec(uint32_t p_usec) const=0;
virtual uint64_t get_ticks_usec() const=0;
uint32_t get_ticks_msec() const;
uint64_t get_splash_tick_msec() const;
@@ -374,6 +381,7 @@ public:
virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
virtual bool native_video_is_playing() const;
virtual void native_video_pause();
+ virtual void native_video_unpause();
virtual void native_video_stop();
virtual bool can_use_threads() const;
@@ -402,7 +410,14 @@ public:
virtual bool is_joy_known(int p_device);
virtual String get_joy_guid(int p_device)const;
- OS();
+ enum EngineContext {
+ CONTEXT_EDITOR,
+ CONTEXT_PROJECTMAN,
+ };
+
+ virtual void set_context(int p_context);
+
+ OS();
virtual ~OS();
};
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index b65542ce35..8469408e65 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -35,17 +35,17 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Semaphore {
-protected:
+protected:
static Semaphore* (*create_func)();
-
+
public:
virtual Error wait()=0; ///< wait until semaphore has positive value, then decrement and pass
virtual Error post()=0; ///< unlock the semaphore, incrementing the value
virtual int get() const=0; ///< get semaphore value
-
+
static Semaphore * create(); ///< Create a mutex
-
+
virtual ~Semaphore();
};
diff --git a/core/os/shell.h b/core/os/shell.h
index 805dd70301..8b0c286d73 100644
--- a/core/os/shell.h
+++ b/core/os/shell.h
@@ -42,7 +42,7 @@ public:
static Shell * get_singleton();
virtual void execute(String p_path)=0;
-
+
Shell();
virtual ~Shell();
};
diff --git a/core/os/thread.cpp b/core/os/thread.cpp
index 7fb1e969d4..c1ae53074b 100644
--- a/core/os/thread.cpp
+++ b/core/os/thread.cpp
@@ -32,34 +32,38 @@
Thread* (*Thread::create_func)(ThreadCreateCallback,void *,const Settings&)=NULL;
Thread::ID (*Thread::get_thread_ID_func)()=NULL;
void (*Thread::wait_to_finish_func)(Thread*)=NULL;
+Error (*Thread::set_name_func)(const String&)=NULL;
Thread::ID Thread::_main_thread_id=0;
Thread::ID Thread::get_caller_ID() {
-
+
if (get_thread_ID_func)
return get_thread_ID_func();
return 0;
}
Thread* Thread::create(ThreadCreateCallback p_callback,void * p_user,const Settings& p_settings) {
-
+
if (create_func) {
-
+
return create_func(p_callback,p_user,p_settings);
}
return NULL;
}
void Thread::wait_to_finish(Thread *p_thread) {
-
+
if (wait_to_finish_func)
wait_to_finish_func(p_thread);
-
+
}
Error Thread::set_name(const String &p_name) {
+ if (set_name_func)
+ return set_name_func(p_name);
+
return ERR_UNAVAILABLE;
};
diff --git a/core/os/thread.h b/core/os/thread.h
index 5711561809..7349b83dbc 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -41,28 +41,29 @@ typedef void (*ThreadCreateCallback)(void *p_userdata);
class Thread {
public:
-
+
enum Priority {
-
+
PRIORITY_LOW,
PRIORITY_NORMAL,
PRIORITY_HIGH
};
-
+
struct Settings {
-
+
Priority priority;
Settings() { priority=PRIORITY_NORMAL; }
};
-
+
typedef uint64_t ID;
-protected:
+protected:
static Thread* (*create_func)(ThreadCreateCallback p_callback,void *,const Settings&);
static ID (*get_thread_ID_func)();
static void (*wait_to_finish_func)(Thread*);
+ static Error (*set_name_func)(const String&);
friend class Main;
@@ -71,18 +72,17 @@ protected:
Thread();
public:
-
- virtual Error set_name(const String& p_name);
-
+
virtual ID get_ID() const=0;
-
+
+ static Error set_name(const String &p_name);
_FORCE_INLINE_ static ID get_main_ID() { return _main_thread_id; } ///< get the ID of the main thread
static ID get_caller_ID(); ///< get the ID of the caller function ID
static void wait_to_finish(Thread *p_thread); ///< waits until thread is finished, and deallocates it.
static Thread * create(ThreadCreateCallback p_callback,void * p_user,const Settings& p_settings=Settings()); ///< Static function to create a thread, will call p_callback
-
-
+
+
virtual ~Thread();
};
diff --git a/core/os/thread_safe.cpp b/core/os/thread_safe.cpp
index f252190504..a742b1144e 100644
--- a/core/os/thread_safe.cpp
+++ b/core/os/thread_safe.cpp
@@ -30,17 +30,17 @@
#include "error_macros.h"
#include "os/memory.h"
-ThreadSafe::ThreadSafe() {
+ThreadSafe::ThreadSafe() {
- mutex = Mutex::create();
+ mutex = Mutex::create();
if (!mutex) {
-
+
WARN_PRINT("THREAD_SAFE defined, but no default mutex type");
}
}
-ThreadSafe::~ThreadSafe() {
-
- if (mutex)
- memdelete( mutex );
+ThreadSafe::~ThreadSafe() {
+
+ if (mutex)
+ memdelete( mutex );
}
diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h
index 793dd88543..1c82cbe704 100644
--- a/core/os/thread_safe.h
+++ b/core/os/thread_safe.h
@@ -42,7 +42,7 @@ public:
ThreadSafe();
~ThreadSafe();
-
+
};
@@ -51,11 +51,11 @@ class ThreadSafeMethod {
const ThreadSafe *_ts;
public:
ThreadSafeMethod(const ThreadSafe *p_ts) {
-
+
_ts=p_ts;
_ts->lock();
}
-
+
~ThreadSafeMethod() { _ts->unlock(); }
};
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index dd736502a3..91f886ff4b 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -182,12 +182,12 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs,const Variant& p_key,boo
err=true;
return Variant();
}
-
+
} else if (type==TYPE_DICT) {
uint32_t hash=p_key.hash();
uint32_t len = decode_uint32(r+4);
-
+
bool found=false;
for(int i=0;i<len;i++) {
uint32_t khash=decode_uint32(r+8+i*12+0);
@@ -214,7 +214,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs,const Variant& p_key,boo
err=true;
return Variant();
}
-
+
}
diff --git a/core/path_db.cpp b/core/path_db.cpp
index d3521fcb23..7545088978 100644
--- a/core/path_db.cpp
+++ b/core/path_db.cpp
@@ -58,17 +58,17 @@ bool NodePath::is_absolute() const {
if (!data)
return false;
-
+
return data->absolute;
-
+
}
int NodePath::get_name_count() const {
if (!data)
return 0;
-
+
return data->path.size();
-
+
}
StringName NodePath::get_name(int p_idx) const {
@@ -103,24 +103,24 @@ StringName NodePath::get_subname(int p_idx) const {
void NodePath::unref() {
if (data && data->refcount.unref()) {
-
+
memdelete(data);
}
data=NULL;
-
+
}
-
+
bool NodePath::operator==(const NodePath& p_path) const {
if (data==p_path.data)
return true;
-
+
if (!data || !p_path.data)
return false;
-
+
if (data->absolute != p_path.data->absolute)
return false;
-
+
if (data->path.size() != p_path.data->path.size())
return false;
@@ -131,7 +131,7 @@ bool NodePath::operator==(const NodePath& p_path) const {
return false;
for (int i=0;i<data->path.size();i++) {
-
+
if (data->path[i]!=p_path.data->path[i])
return false;
}
@@ -148,17 +148,17 @@ bool NodePath::operator!=(const NodePath& p_path) const {
return (!(*this == p_path));
}
-
-
+
+
void NodePath::operator=(const NodePath& p_path) {
if (this==&p_path)
return;
unref();
-
+
if (p_path.data && p_path.data->refcount.ref()) {
-
+
data=p_path.data;
}
}
@@ -167,13 +167,13 @@ NodePath::operator String() const {
if (!data)
return String();
-
+
String ret;
if (data->absolute)
ret="/";
-
+
for (int i=0;i<data->path.size();i++) {
-
+
if (i>0)
ret+="/";
ret+=data->path[i].operator String();
@@ -184,7 +184,7 @@ NodePath::operator String() const {
ret+=":"+data->subpath[i].operator String();
}
- if (data->property.operator String()!="")
+ if (data->property.operator String()!="")
ret+=":"+String(data->property);
return ret;
}
@@ -195,7 +195,7 @@ NodePath::NodePath(const NodePath& p_path) {
data=NULL;
if (p_path.data && p_path.data->refcount.ref()) {
-
+
data=p_path.data;
}
}
@@ -258,17 +258,17 @@ NodePath NodePath::rel_path_to(const NodePath& p_np) const {
NodePath::NodePath(const Vector<StringName>& p_path,bool p_absolute,const String& p_property) {
-
+
data=NULL;
-
+
if (p_path.size()==0)
return;
-
+
data = memnew( Data );
data->refcount.init();
data->absolute=p_absolute;
data->path=p_path;
- data->property=p_property;
+ data->property=p_property;
}
NodePath::NodePath(const Vector<StringName>& p_path,const Vector<StringName>& p_subpath,bool p_absolute,const String& p_property) {
@@ -327,17 +327,17 @@ NodePath::NodePath(const String& p_path) {
String path=p_path;
StringName property;
Vector<StringName> subpath;
-
- int absolute=(path[0]=='/')?1:0;;
+
+ int absolute=(path[0]=='/')?1:0;;
bool valid=false;
bool last_is_slash=true;
int slices=0;
int subpath_pos=path.find(":");
-
+
if (subpath_pos!=-1) {
-
+
int from=subpath_pos+1;
for (int i=from;i<=path.length();i++) {
@@ -362,44 +362,44 @@ NodePath::NodePath(const String& p_path) {
path=path.substr(0,subpath_pos);
}
-
+
for (int i=absolute;i<path.length();i++) {
-
+
if (path[i]=='/') {
-
+
last_is_slash=true;
} else {
-
+
if (last_is_slash)
slices++;
-
+
valid=true;
last_is_slash=false;
}
}
-
+
if (slices==0 && !absolute && !property)
return;
-
+
data = memnew( Data );
data->refcount.init();
data->absolute=absolute?true:false;
data->property=property;
data->subpath=subpath;
-
+
if (slices==0)
return;
- data->path.resize(slices);
+ data->path.resize(slices);
last_is_slash=true;
int from=absolute;
int slice=0;
-
+
for (int i=absolute;i<path.length()+1;i++) {
-
+
if (path[i]=='/' || path[i]==0) {
-
+
if (!last_is_slash) {
-
+
String name=path.substr(from,i-from);
ERR_FAIL_INDEX( slice,data->path.size() );
data->path[slice++]=name;
@@ -410,8 +410,8 @@ NodePath::NodePath(const String& p_path) {
last_is_slash=false;
}
}
-
-
+
+
}
bool NodePath::is_empty() const {
diff --git a/core/path_db.h b/core/path_db.h
index 9c9be65d28..63adb42955 100644
--- a/core/path_db.h
+++ b/core/path_db.h
@@ -41,14 +41,14 @@
class NodePath {
struct Data {
-
+
SafeRefCount refcount;
StringName property;
- Vector<StringName> path;
+ Vector<StringName> path;
Vector<StringName> subpath;
bool absolute;
};
-
+
Data *data;
void unref();
public:
@@ -77,7 +77,7 @@ public:
NodePath get_parent() const;
uint32_t hash() const;
-
+
operator String() const;
bool is_empty() const;
@@ -88,7 +88,7 @@ public:
void simplify();
NodePath simplified() const;
- NodePath(const Vector<StringName>& p_path,bool p_absolute,const String& p_property="");
+ NodePath(const Vector<StringName>& p_path,bool p_absolute,const String& p_property="");
NodePath(const Vector<StringName>& p_path,const Vector<StringName>& p_subpath,bool p_absolute,const String& p_property="");
NodePath(const NodePath& p_path);
NodePath(const String& p_path);
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index 23be650fda..849fd75f50 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -42,11 +42,11 @@ do { \
} while (0);
void PoolAllocator::mt_lock() const {
-
+
}
void PoolAllocator::mt_unlock() const {
-
+
}
@@ -61,7 +61,7 @@ bool PoolAllocator::get_free_entry(EntryArrayPos* p_pos) {
*p_pos=i;
return true;
}
-
+
}
ERR_PRINT("Out of memory Chunks!");
@@ -78,7 +78,7 @@ bool PoolAllocator::get_free_entry(EntryArrayPos* p_pos) {
bool PoolAllocator::find_hole(EntryArrayPos *p_pos, int p_for_size) {
/* position where previous entry ends. Defaults to zero (begin of pool) */
-
+
int prev_entry_end_pos=0;
for (int i=0;i<entry_count;i++) {
@@ -106,16 +106,16 @@ bool PoolAllocator::find_hole(EntryArrayPos *p_pos, int p_for_size) {
*p_pos=entry_count;
return true;
}
-
+
return false;
-
+
}
void PoolAllocator::compact(int p_up_to) {
-
+
uint32_t prev_entry_end_pos=0;
-
+
if (p_up_to<0)
p_up_to=entry_count;
for (int i=0;i<p_up_to;i++) {
@@ -129,16 +129,16 @@ void PoolAllocator::compact(int p_up_to) {
/* if we can compact, do it */
if (hole_size>0 && !entry.lock) {
-
+
COMPACT_CHUNK(entry,prev_entry_end_pos);
-
+
}
-
+
/* prepare for next one */
prev_entry_end_pos=entry_end(entry);
}
-
-
+
+
}
void PoolAllocator::compact_up(int p_from) {
@@ -169,81 +169,81 @@ void PoolAllocator::compact_up(int p_from) {
bool PoolAllocator::find_entry_index(EntryIndicesPos *p_map_pos,Entry *p_entry) {
-
+
EntryArrayPos entry_pos=entry_max;
-
+
for (int i=0;i<entry_count;i++) {
-
+
if (&entry_array[ entry_indices[ i ] ]==p_entry) {
-
+
entry_pos=i;
break;
}
}
-
+
if (entry_pos==entry_max)
return false;
-
+
*p_map_pos=entry_pos;
return true;
-
+
}
PoolAllocator::ID PoolAllocator::alloc(int p_size) {
-
+
ERR_FAIL_COND_V(p_size<1,POOL_ALLOCATOR_INVALID_ID);
#ifdef DEBUG_ENABLED
if (p_size > free_mem) OS::get_singleton()->debug_break();
#endif
ERR_FAIL_COND_V(p_size>free_mem,POOL_ALLOCATOR_INVALID_ID);
-
+
mt_lock();
-
+
if (entry_count==entry_max) {
mt_unlock();
ERR_PRINT("entry_count==entry_max");
return POOL_ALLOCATOR_INVALID_ID;
}
-
-
+
+
int size_to_alloc=aligned(p_size);
-
+
EntryIndicesPos new_entry_indices_pos;
-
+
if (!find_hole(&new_entry_indices_pos, size_to_alloc)) {
/* No hole could be found, try compacting mem */
compact();
/* Then search again */
-
+
if (!find_hole(&new_entry_indices_pos, size_to_alloc)) {
-
+
mt_unlock();
ERR_PRINT("memory can't be compacted further");
- return POOL_ALLOCATOR_INVALID_ID;
+ return POOL_ALLOCATOR_INVALID_ID;
}
}
-
+
EntryArrayPos new_entry_array_pos;
-
+
bool found_free_entry=get_free_entry(&new_entry_array_pos);
-
+
if (!found_free_entry) {
mt_unlock();
ERR_FAIL_COND_V( !found_free_entry , POOL_ALLOCATOR_INVALID_ID );
}
-
+
/* move all entry indices up, make room for this one */
for (int i=entry_count;i>new_entry_indices_pos;i-- ) {
-
+
entry_indices[i]=entry_indices[i-1];
}
-
+
entry_indices[new_entry_indices_pos]=new_entry_array_pos;
-
+
entry_count++;
-
+
Entry &entry=entry_array[ entry_indices[ new_entry_indices_pos ] ];
-
+
entry.len=p_size;
entry.pos=(new_entry_indices_pos==0)?0:entry_end(entry_array[ entry_indices[ new_entry_indices_pos-1 ] ]); //alloc either at begining or end of previous
entry.lock=0;
@@ -251,40 +251,40 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
free_mem-=size_to_alloc;
if (free_mem<free_mem_peak)
free_mem_peak=free_mem;
-
+
ID retval = (entry_indices[ new_entry_indices_pos ]<<CHECK_BITS)|entry.check;
mt_unlock();
//ERR_FAIL_COND_V( (uintptr_t)get(retval)%align != 0, retval );
return retval;
-
+
}
PoolAllocator::Entry * PoolAllocator::get_entry(ID p_mem) {
-
+
unsigned int check=p_mem&CHECK_MASK;
int entry=p_mem>>CHECK_BITS;
ERR_FAIL_INDEX_V(entry,entry_max,NULL);
ERR_FAIL_COND_V(entry_array[entry].check!=check,NULL);
ERR_FAIL_COND_V(entry_array[entry].len==0,NULL);
-
+
return &entry_array[entry];
}
const PoolAllocator::Entry * PoolAllocator::get_entry(ID p_mem) const {
-
+
unsigned int check=p_mem&CHECK_MASK;
int entry=p_mem>>CHECK_BITS;
ERR_FAIL_INDEX_V(entry,entry_max,NULL);
ERR_FAIL_COND_V(entry_array[entry].check!=check,NULL);
ERR_FAIL_COND_V(entry_array[entry].len==0,NULL);
-
+
return &entry_array[entry];
}
void PoolAllocator::free(ID p_mem) {
-
+
mt_lock();
Entry *e=get_entry(p_mem);
if (!e) {
@@ -297,23 +297,23 @@ void PoolAllocator::free(ID p_mem) {
ERR_PRINT("e->lock");
return;
}
-
+
EntryIndicesPos entry_indices_pos;
-
+
bool index_found = find_entry_index(&entry_indices_pos,e);
if (!index_found) {
-
+
mt_unlock();
ERR_FAIL_COND(!index_found);
}
-
-
+
+
for (int i=entry_indices_pos;i<(entry_count-1);i++) {
-
+
entry_indices[ i ] = entry_indices[ i+1 ];
}
-
+
entry_count--;
free_mem+=aligned(e->len);
e->clear();
@@ -327,21 +327,21 @@ int PoolAllocator::get_size(ID p_mem) const {
const Entry *e=get_entry(p_mem);
if (!e) {
-
+
mt_unlock();
ERR_PRINT("!e");
return 0;
}
-
+
size=e->len;
-
+
mt_unlock();
-
+
return size;
-}
+}
Error PoolAllocator::resize(ID p_mem,int p_new_size) {
-
+
mt_lock();
Entry *e=get_entry(p_mem);
@@ -443,18 +443,18 @@ Error PoolAllocator::resize(ID p_mem,int p_new_size) {
Error PoolAllocator::lock(ID p_mem) {
-
+
if (!needs_locking)
return OK;
mt_lock();
Entry *e=get_entry(p_mem);
if (!e) {
-
+
mt_unlock();
ERR_PRINT("!e");
return ERR_INVALID_PARAMETER;
}
- e->lock++;
+ e->lock++;
mt_unlock();
return OK;
}
@@ -480,85 +480,85 @@ bool PoolAllocator::is_locked(ID p_mem) const {
const void *PoolAllocator::get(ID p_mem) const {
if (!needs_locking) {
-
+
const Entry *e=get_entry(p_mem);
ERR_FAIL_COND_V(!e,NULL);
return &pool[e->pos];
-
+
}
-
+
mt_lock();
const Entry *e=get_entry(p_mem);
-
+
if (!e) {
-
+
mt_unlock();
ERR_FAIL_COND_V(!e,NULL);
}
if (e->lock==0) {
-
+
mt_unlock();
ERR_PRINT( "e->lock == 0" );
return NULL;
}
-
+
if (e->pos<0 || (int)e->pos>=pool_size) {
-
+
mt_unlock();
ERR_PRINT("e->pos<0 || e->pos>=pool_size");
return NULL;
}
const void *ptr=&pool[e->pos];
-
+
mt_unlock();
-
+
return ptr;
}
void *PoolAllocator::get(ID p_mem) {
-
+
if (!needs_locking) {
-
+
Entry *e=get_entry(p_mem);
if (!e) {
ERR_FAIL_COND_V(!e,NULL);
};
return &pool[e->pos];
-
+
}
-
+
mt_lock();
Entry *e=get_entry(p_mem);
-
+
if (!e) {
-
+
mt_unlock();
ERR_FAIL_COND_V(!e,NULL);
}
if (e->lock==0) {
-
+
//assert(0);
mt_unlock();
ERR_PRINT( "e->lock == 0" );
return NULL;
}
-
+
if (e->pos<0 || (int)e->pos>=pool_size) {
-
+
mt_unlock();
ERR_PRINT("e->pos<0 || e->pos>=pool_size");
return NULL;
}
void *ptr=&pool[e->pos];
-
+
mt_unlock();
-
+
return ptr;
-
+
}
void PoolAllocator::unlock(ID p_mem) {
-
+
if (!needs_locking)
return;
mt_lock();
@@ -568,7 +568,7 @@ void PoolAllocator::unlock(ID p_mem) {
ERR_PRINT( "e->lock == 0" );
return;
}
- e->lock--;
+ e->lock--;
mt_unlock();
}
@@ -583,34 +583,34 @@ int PoolAllocator::get_free_peak() {
}
int PoolAllocator::get_free_mem() {
-
+
return free_mem;
}
void PoolAllocator::create_pool(void * p_mem,int p_size,int p_max_entries) {
-
+
pool=(uint8_t*)p_mem;
pool_size=p_size;
-
+
entry_array = memnew_arr( Entry, p_max_entries );
entry_indices = memnew_arr( int, p_max_entries );
entry_max = p_max_entries;
entry_count=0;
-
+
free_mem=p_size;
free_mem_peak=p_size;
-
- check_count=0;
+
+ check_count=0;
}
PoolAllocator::PoolAllocator(int p_size,bool p_needs_locking,int p_max_entries) {
-
+
mem_ptr=Memory::alloc_static( p_size,"PoolAllocator()");
ERR_FAIL_COND(!mem_ptr);
align=1;
create_pool(mem_ptr,p_size,p_max_entries);
needs_locking=p_needs_locking;
-
+
}
PoolAllocator::PoolAllocator(void * p_mem,int p_size, int p_align ,bool p_needs_locking,int p_max_entries) {
@@ -626,16 +626,16 @@ PoolAllocator::PoolAllocator(void * p_mem,int p_size, int p_align ,bool p_needs_
p_mem = (void*)mem8;
};
};
-
+
create_pool( p_mem,p_size,p_max_entries);
needs_locking=p_needs_locking;
align=p_align;
- mem_ptr=NULL;
+ mem_ptr=NULL;
}
PoolAllocator::PoolAllocator(int p_align,int p_size,bool p_needs_locking,int p_max_entries) {
-
- ERR_FAIL_COND(p_align<1);
+
+ ERR_FAIL_COND(p_align<1);
mem_ptr=Memory::alloc_static( p_size+p_align,"PoolAllocator()");
uint8_t *mem8=(uint8_t*)mem_ptr;
uint64_t ofs = (uint64_t)mem8;
@@ -647,12 +647,12 @@ PoolAllocator::PoolAllocator(int p_align,int p_size,bool p_needs_locking,int p_m
}
PoolAllocator::~PoolAllocator() {
-
+
if (mem_ptr)
Memory::free_static( mem_ptr );
-
+
memdelete_arr( entry_array );
memdelete_arr( entry_indices );
-
+
}
diff --git a/core/pool_allocator.h b/core/pool_allocator.h
index 2c5920149b..438548bfe4 100644
--- a/core/pool_allocator.h
+++ b/core/pool_allocator.h
@@ -41,66 +41,66 @@
*/
enum {
-
+
POOL_ALLOCATOR_INVALID_ID=-1 ///< default invalid value. use INVALID_ID( id ) to test
};
class PoolAllocator {
-public:
+public:
typedef int ID;
-private:
+private:
enum {
CHECK_BITS=8,
CHECK_LEN=(1<<CHECK_BITS),
CHECK_MASK=CHECK_LEN-1
-
+
};
-
-
+
+
struct Entry {
-
+
unsigned int pos;
unsigned int len;
unsigned int lock;
- unsigned int check;
-
+ unsigned int check;
+
inline void clear() { pos=0; len=0; lock=0; check=0; }
Entry() { clear(); }
};
-
-
+
+
typedef int EntryArrayPos;
typedef int EntryIndicesPos;
-
+
Entry *entry_array;
int *entry_indices;
int entry_max;
int entry_count;
-
+
uint8_t *pool;
void *mem_ptr;
int pool_size;
-
+
int free_mem;
int free_mem_peak;
unsigned int check_count;
int align;
-
+
bool needs_locking;
-
- inline int entry_end(const Entry& p_entry) const {
- return p_entry.pos+aligned(p_entry.len);
+
+ inline int entry_end(const Entry& p_entry) const {
+ return p_entry.pos+aligned(p_entry.len);
}
inline int aligned(int p_size) const {
-
+
int rem=p_size%align;
if (rem)
p_size+=align-rem;
-
+
return p_size;
}
-
+
void compact(int p_up_to=-1);
void compact_up(int p_from=0);
bool get_free_entry(EntryArrayPos* p_pos);
@@ -108,14 +108,14 @@ private:
bool find_entry_index(EntryIndicesPos *p_map_pos,Entry *p_entry);
Entry* get_entry(ID p_mem);
const Entry* get_entry(ID p_mem) const;
-
+
void create_pool(void * p_mem,int p_size,int p_max_entries);
-protected:
+protected:
virtual void mt_lock() const; ///< Reimplement for custom mt locking
virtual void mt_unlock() const; ///< Reimplement for custom mt locking
-
+
public:
-
+
enum {
DEFAULT_MAX_ALLOCS=4096,
};
@@ -124,7 +124,7 @@ public:
void free(ID p_mem); ///< Free allocated memory
Error resize(ID p_mem,int p_new_size); ///< resize a memory chunk
int get_size(ID p_mem) const;
-
+
int get_free_mem(); ///< get free memory
int get_used_mem() const;
int get_free_peak(); ///< get free memory
@@ -134,13 +134,13 @@ public:
const void *get(ID p_mem) const;
void unlock(ID p_mem);
bool is_locked(ID p_mem) const;
-
+
PoolAllocator(int p_size,bool p_needs_locking=false,int p_max_entries=DEFAULT_MAX_ALLOCS);
PoolAllocator(void * p_mem,int p_size, int p_align = 1, bool p_needs_locking=false,int p_max_entries=DEFAULT_MAX_ALLOCS);
PoolAllocator(int p_align,int p_size,bool p_needs_locking=false,int p_max_entries=DEFAULT_MAX_ALLOCS);
-
+
virtual ~PoolAllocator();
-
+
};
#endif
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index d977ea3e18..97bd5f2a32 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -51,6 +51,7 @@
#include "packed_data_container.h"
#include "func_ref.h"
#include "input_map.h"
+#include "undo_redo.h"
#ifdef XML_ENABLED
static ResourceFormatSaverXML *resource_saver_xml=NULL;
@@ -80,7 +81,7 @@ extern void unregister_variant_methods();
void register_core_types() {
-
+
_global_mutex=Mutex::create();
@@ -91,7 +92,7 @@ void register_core_types() {
CoreStringNames::create();
-
+
resource_format_po = memnew( TranslationLoaderPO );
ResourceLoader::add_resource_format_loader( resource_format_po );
@@ -128,7 +129,7 @@ void register_core_types() {
// ObjectTypeDB::register_type<OptimizedSaver>();
ObjectTypeDB::register_type<Translation>();
ObjectTypeDB::register_type<PHashTranslation>();
-
+ ObjectTypeDB::register_type<UndoRedo>();
ObjectTypeDB::register_type<HTTPClient>();
ObjectTypeDB::register_virtual_type<ResourceInteractiveLoader>();
diff --git a/core/res_ptr.cpp b/core/res_ptr.cpp
index 11312b8021..2fada627e7 100644
--- a/core/res_ptr.cpp
+++ b/core/res_ptr.cpp
@@ -53,7 +53,7 @@ RefPtr::RefPtr(const RefPtr& p_other) {
Ref<Resource> *ref = reinterpret_cast<Ref<Resource>*>( &data[0] );
Ref<Resource> *ref_other = reinterpret_cast<Ref<Resource>*>( const_cast<char*>(&p_other.data[0]) );
-
+
*ref = *ref_other;
}
diff --git a/core/res_ptr.h b/core/res_ptr.h
index e1dc66b290..54b74bb113 100644
--- a/core/res_ptr.h
+++ b/core/res_ptr.h
@@ -41,7 +41,7 @@
class ResBase;
class RefPtr {
-friend class ResBase;
+friend class ResBase;
enum {
DATASIZE=sizeof(void*)*4
diff --git a/core/resource.cpp b/core/resource.cpp
index e0706cf541..672e64b1bb 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -156,14 +156,14 @@ void Resource::_resource_path_changed() {
}
-
+
void Resource::set_path(const String& p_path, bool p_take_over) {
if (path_cache==p_path)
return;
-
+
if (path_cache!="") {
-
+
ResourceCache::resources.erase(path_cache);
}
@@ -179,19 +179,19 @@ void Resource::set_path(const String& p_path, bool p_take_over) {
}
path_cache=p_path;
-
+
if (path_cache!="") {
-
+
ResourceCache::resources[path_cache]=this;;
}
_change_notify("resource/path");
_resource_path_changed();
-
+
}
String Resource::get_path() const {
-
+
return path_cache;
}
@@ -342,7 +342,7 @@ Resource::Resource() {
Resource::~Resource() {
-
+
if (path_cache!="")
ResourceCache::resources.erase(path_cache);
if (owners.size()) {
@@ -350,12 +350,12 @@ Resource::~Resource() {
}
}
-HashMap<String,Resource*> ResourceCache::resources;
+HashMap<String,Resource*> ResourceCache::resources;
void ResourceCache::clear() {
if (resources.size())
ERR_PRINT("Resources Still in use at Exit!");
-
+
resources.clear();
}
@@ -374,18 +374,18 @@ void ResourceCache::reload_externals() {
bool ResourceCache::has(const String& p_path) {
GLOBAL_LOCK_FUNCTION
-
+
return resources.has(p_path);
}
Resource *ResourceCache::get(const String& p_path) {
-
+
GLOBAL_LOCK_FUNCTION
-
+
Resource **res = resources.getptr(p_path);
if (!res) {
return NULL;
}
-
+
return *res;
}
diff --git a/core/resource.h b/core/resource.h
index f0c86631cc..8bcdd6b4b7 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -87,7 +87,7 @@ public:
class Resource : public Reference {
-
+
OBJ_TYPE( Resource, Reference );
OBJ_CATEGORY("Resources");
RES_BASE_EXTENSION("res");
@@ -95,8 +95,8 @@ class Resource : public Reference {
Set<ObjectID> owners;
friend class ResBase;
-friend class ResourceCache;
-
+friend class ResourceCache;
+
String name;
String path_cache;
int subindex;
@@ -109,7 +109,7 @@ friend class ResourceCache;
#endif
protected:
-
+
void emit_changed();
void notify_change_to_owners();
@@ -120,7 +120,7 @@ protected:
void _set_path(const String& p_path);
void _take_over_path(const String& p_path);
public:
-
+
virtual bool can_reload_from_file();
virtual void reload_from_file();
@@ -151,7 +151,7 @@ public:
virtual RID get_rid() const; // some resources may offer conversion to RID
- Resource();
+ Resource();
~Resource();
};
@@ -160,11 +160,11 @@ public:
typedef Ref<Resource> RES;
class ResourceCache {
-friend class Resource;
- static HashMap<String,Resource*> resources;
+friend class Resource;
+ static HashMap<String,Resource*> resources;
friend void unregister_core_types();
static void clear();
-public:
+public:
static void reload_externals();
static bool has(const String& p_path);
diff --git a/core/rid.h b/core/rid.h
index 85ae1b15d3..2de6956096 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -44,19 +44,19 @@ class RID_OwnerBase;
typedef uint32_t ID;
-class RID {
-friend class RID_OwnerBase;
+class RID {
+friend class RID_OwnerBase;
ID _id;
RID_OwnerBase *owner;
public:
_FORCE_INLINE_ ID get_id() const { return _id; }
bool operator==(const RID& p_rid) const {
-
+
return _id==p_rid._id;
}
_FORCE_INLINE_ bool operator<(const RID& p_rid) const {
-
+
return _id < p_rid._id;
}
_FORCE_INLINE_ bool operator<=(const RID& p_rid) const {
@@ -64,11 +64,11 @@ public:
return _id <= p_rid._id;
}
_FORCE_INLINE_ bool operator>(const RID& p_rid) const {
-
+
return _id > p_rid._id;
}
bool operator!=(const RID& p_rid) const {
-
+
return _id!=p_rid._id;
}
_FORCE_INLINE_ bool is_valid() const { return _id>0; }
@@ -91,7 +91,7 @@ friend class RID;
void set_ownage(RID& p_rid) const { p_rid.owner=const_cast<RID_OwnerBase*>(this); }
ID new_ID();
public:
-
+
virtual bool owns(const RID& p_rid) const=0;
virtual void get_owned_list(List<RID> *p_owned) const=0;
@@ -105,67 +105,67 @@ class RID_Owner : public RID_OwnerBase {
public:
typedef void (*ReleaseNotifyFunc)(void*user,T *p_data);
-private:
+private:
Mutex *mutex;
mutable HashMap<ID,T*> id_map;
-
+
public:
RID make_rid(T * p_data) {
-
+
if (thread_safe) {
mutex->lock();
}
-
+
ID id = new_ID();
id_map[id]=p_data;
RID rid;
set_id(rid,id);
set_ownage(rid);
-
+
if (thread_safe) {
mutex->unlock();
}
-
+
return rid;
}
-
+
_FORCE_INLINE_ T * get(const RID& p_rid) {
-
+
if (thread_safe) {
mutex->lock();
}
-
+
T**elem = id_map.getptr(p_rid.get_id());
-
+
if (thread_safe) {
mutex->unlock();
}
ERR_FAIL_COND_V(!elem,NULL);
-
+
return *elem;
}
-
+
virtual bool owns(const RID& p_rid) const {
-
+
if (thread_safe) {
mutex->lock();
}
-
+
T**elem = id_map.getptr(p_rid.get_id());
-
+
if (thread_safe) {
mutex->lock();
}
-
+
return elem!=NULL;
}
-
- virtual void free(RID p_rid) {
-
+
+ virtual void free(RID p_rid) {
+
if (thread_safe) {
mutex->lock();
}
@@ -173,40 +173,40 @@ public:
id_map.erase(p_rid.get_id());
}
virtual void get_owned_list(List<RID> *p_owned) const {
-
+
if (thread_safe) {
mutex->lock();
}
-
+
const ID*id=NULL;
while((id=id_map.next(id))) {
-
+
RID rid;
set_id(rid,*id);
set_ownage(rid);
p_owned->push_back(rid);
-
+
}
-
+
if (thread_safe) {
mutex->lock();
}
}
RID_Owner() {
-
+
if (thread_safe) {
-
+
mutex = Mutex::create();
}
-
+
}
-
-
+
+
~RID_Owner() {
-
+
if (thread_safe) {
-
+
memdelete(mutex);
}
}
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index 4658ec5e51..7d78fac660 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -38,21 +38,21 @@ class RingBuffer {
int read_pos;
int write_pos;
int size_mask;
-
+
inline int inc(int& p_var, int p_size) {
int ret = p_var;
p_var += p_size;
p_var = p_var&size_mask;
return ret;
};
-
+
public:
T read() {
ERR_FAIL_COND_V(space_left() < 1, T());
return data[inc(read_pos, 1)];
};
-
+
int read(T* p_buf, int p_size, bool p_advance=true) {
int left = data_left();
p_size = MIN(left, p_size);
@@ -76,7 +76,7 @@ public:
};
int copy(T* p_buf, int p_offset, int p_size) {
-
+
int left = data_left();
if ((p_offset+p_size)>left) {
p_size-=left-p_offset;
@@ -106,18 +106,18 @@ public:
inc(read_pos, p_n);
return p_n;
};
-
+
Error write(const T& p_v) {
ERR_FAIL_COND_V( space_left() < 1, FAILED);
data[inc(write_pos, 1)] = p_v;
return OK;
};
-
+
int write(const T* p_buf, int p_size) {
-
+
int left = space_left();
p_size = MIN(left, p_size);
-
+
int pos = write_pos;
int to_write = p_size;
int src = 0;
@@ -126,7 +126,7 @@ public:
int end = pos + to_write;
end = MIN(end, size());
int total = end - pos;
-
+
for (int i=0; i<total; i++) {
data[pos+i] = p_buf[src++];
};
@@ -137,7 +137,7 @@ public:
inc(write_pos, p_size);
return p_size;
};
-
+
inline int space_left() {
int left = read_pos - write_pos;
if (left < 0) {
@@ -151,7 +151,7 @@ public:
inline int data_left() {
return size() - space_left() - 1;
};
-
+
inline int size() {
return data.size();
};
@@ -161,7 +161,7 @@ public:
write_pos = 0;
}
-
+
void resize(int p_power) {
int old_size = size();
int new_size = 1<<p_power;
@@ -176,10 +176,10 @@ public:
read_pos = read_pos & mask;
write_pos = write_pos & mask;
};
-
+
size_mask = mask;
};
-
+
RingBuffer<T>(int p_power=0) {
read_pos = 0;
write_pos = 0;
diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp
index 7718e466f2..9736f96f34 100644
--- a/core/safe_refcount.cpp
+++ b/core/safe_refcount.cpp
@@ -40,9 +40,9 @@ long atomic_conditional_increment( register long * pw ) {
while (true) {
long tmp = static_cast< long const volatile& >( *pw );
- if( tmp == 0 )
+ if( tmp == 0 )
return 0; // if zero, can't add to it anymore
- if( InterlockedCompareExchange( pw, tmp + 1, tmp ) == tmp )
+ if( InterlockedCompareExchange( pw, tmp + 1, tmp ) == tmp )
return tmp+1;
}
diff --git a/core/safe_refcount.h b/core/safe_refcount.h
index e5dc854c23..d976458c1d 100644
--- a/core/safe_refcount.h
+++ b/core/safe_refcount.h
@@ -42,15 +42,15 @@ struct SafeRefCount {
int count;
public:
-
+
// destroy() is called when weak_count_ drops to zero.
-
+
bool ref() { //true on success
-
+
if (count==0)
return false;
count++;
-
+
return true;
}
@@ -66,17 +66,17 @@ public:
if (count>0)
count--;
-
+
return count==0;
}
-
+
long get() const { // nothrow
-
+
return static_cast<int const volatile &>( count );
}
-
+
void init(int p_value=1) {
-
+
count=p_value;
};
@@ -105,9 +105,9 @@ static inline int atomic_conditional_increment( volatile int * pw ) {
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
-
+
int rv, tmp;
-
+
__asm__
(
"movl %0, %%eax\n\t"
@@ -124,22 +124,22 @@ static inline int atomic_conditional_increment( volatile int * pw ) {
"m"( *pw ): // input (%3)
"cc" // clobbers
);
-
+
return rv;
}
static inline int atomic_decrement( volatile int *pw) {
-
+
// return --(*pw);
-
+
unsigned char rv;
-
+
__asm__
(
"lock\n\t"
"decl %0\n\t"
- "setne %1":
- "=m" (*pw), "=qm" (rv):
+ "setne %1":
+ "=m" (*pw), "=qm" (rv):
"m" (*pw):
"memory"
);
@@ -266,15 +266,15 @@ inline long atomic_conditional_increment( register long * pw )
asm
{
loop:
-
+
lwarx a, 0, pw
cmpwi a, 0
beq store
-
+
addi a, a, 1
-
+
store:
-
+
stwcx. a, 0, pw
bne- loop
}
@@ -288,16 +288,16 @@ inline long atomic_decrement( register long * pw )
register int a;
asm {
-
+
sync
-
+
loop:
-
+
lwarx a, 0, pw
addi a, a, -1
stwcx. a, 0, pw
bne- loop
-
+
isync
}
@@ -338,11 +338,11 @@ struct SafeRefCount {
REFCOUNT_T count;
public:
-
+
// destroy() is called when weak_count_ drops to zero.
-
+
bool ref() { //true on success
-
+
return atomic_conditional_increment( &count ) != 0;
}
@@ -356,17 +356,17 @@ public:
if( atomic_decrement ( &count ) == 0 ) {
return true;
}
-
+
return false;
}
-
+
long get() const { // nothrow
-
+
return static_cast<REFCOUNT_GET_T>( count );
}
-
+
void init(int p_value=1) {
-
+
count=p_value;
};
@@ -376,4 +376,4 @@ public:
#endif // no thread safe
-#endif
+#endif
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 0eac39e7d1..1503418269 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -61,26 +61,26 @@ void ScriptServer::set_scripting_enabled(bool p_enabled) {
}
bool ScriptServer::is_scripting_enabled() {
-
+
return scripting_enabled;
}
int ScriptServer::get_language_count() {
-
+
return _language_count;
-
+
}
ScriptLanguage* ScriptServer::get_language(int p_idx) {
ERR_FAIL_INDEX_V(p_idx,_language_count,NULL);
-
+
return _languages[p_idx];
}
void ScriptServer::register_language(ScriptLanguage *p_language) {
-
+
ERR_FAIL_COND( _language_count >= MAX_LANGUAGES );
_languages[_language_count++]=p_language;
}
diff --git a/core/script_language.h b/core/script_language.h
index 7e278b8555..1be1aabdab 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -40,15 +40,15 @@ class ScriptLanguage;
class ScriptServer {
enum {
-
+
MAX_LANGUAGES=4
};
-
+
static ScriptLanguage *_languages[MAX_LANGUAGES];
static int _language_count;
static bool scripting_enabled;
-public:
-
+public:
+
static void set_scripting_enabled(bool p_enabled);
static bool is_scripting_enabled();
static int get_language_count();
@@ -76,14 +76,14 @@ protected:
friend class PlaceHolderScriptInstance;
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {}
public:
-
+
virtual bool can_instance() const=0;
virtual StringName get_instance_base_type() const=0; // this may not work in all scripts, will return empty if so
virtual ScriptInstance* instance_create(Object *p_this)=0;
virtual bool instance_has(const Object *p_this) const=0;
-
+
virtual bool has_source_code() const=0;
virtual String get_source_code() const=0;
virtual void set_source_code(const String& p_code)=0;
@@ -102,7 +102,7 @@ public:
virtual void update_exports() {} //editor tool
-
+
Script() {}
};
@@ -148,13 +148,13 @@ class ScriptLanguage {
public:
virtual String get_name() const=0;
-
+
/* LANGUAGE FUNCTIONS */
- virtual void init()=0;
+ virtual void init()=0;
virtual String get_type() const=0;
virtual String get_extension() const=0;
- virtual Error execute_file(const String& p_path) =0;
- virtual void finish()=0;
+ virtual Error execute_file(const String& p_path) =0;
+ virtual void finish()=0;
/* EDITOR FUNCTIONS */
virtual void get_reserved_words(List<String> *p_words) const=0;
@@ -197,7 +197,7 @@ public:
virtual void frame();
- virtual ~ScriptLanguage() {};
+ virtual ~ScriptLanguage() {};
};
extern uint8_t script_encryption_key[32];
diff --git a/core/set.h b/core/set.h
index 808ffe5b36..d4d19129d4 100644
--- a/core/set.h
+++ b/core/set.h
@@ -42,16 +42,16 @@
template <class T,class C=Comparator<T>,class A=DefaultAllocator >
class Set {
-
- enum Color {
+
+ enum Color {
RED,
BLACK
};
- struct _Data;
+ struct _Data;
public:
-
-
+
+
class Element {
private:
@@ -72,18 +72,18 @@ public:
return _next;
}
Element *next() {
-
+
return _next;
}
const Element *prev() const {
-
+
return _prev;
}
Element *prev() {
-
+
return _prev;
}
- const T& get() const {
+ const T& get() const {
return value;
};
Element() {
@@ -96,7 +96,7 @@ public:
};
};
-
+
private:
struct _Data {
@@ -104,7 +104,7 @@ private:
Element* _root;
Element* _nil;
int size_cache;
-
+
_Data() {
#ifdef GLOBALNIL_DISABLED
@@ -119,7 +119,7 @@ private:
size_cache=0;
}
-
+
void _create_root() {
_root = memnew_allocator( Element,A );
@@ -136,7 +136,7 @@ private:
}
~_Data() {
-
+
_free_root();
#ifdef GLOBALNIL_DISABLED
memdelete_allocator<Element,A>(_nil);
@@ -144,16 +144,16 @@ private:
// memdelete_allocator<Element,A>(_root);
}
};
-
+
_Data _data;
-
+
inline void _set_color(Element *p_node, int p_color) {
-
+
ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
p_node->color=p_color;
}
inline void _rotate_left(Element *p_node) {
-
+
Element *r=p_node->right;
p_node->right=r->left;
if (r->left != _data._nil )
@@ -163,14 +163,14 @@ private:
p_node->parent->left=r;
else
p_node->parent->right=r;
-
+
r->left=p_node;
p_node->parent=r;
-
+
}
-
+
inline void _rotate_right(Element *p_node) {
-
+
Element *l=p_node->left;
p_node->left=l->right;
if (l->right != _data._nil)
@@ -180,25 +180,25 @@ private:
p_node->parent->right=l;
else
p_node->parent->left=l;
-
+
l->right=p_node;
p_node->parent=l;
-
+
}
-
- inline Element* _successor(Element *p_node) const {
-
+
+ inline Element* _successor(Element *p_node) const {
+
Element *node=p_node;
-
+
if (node->right != _data._nil) {
-
+
node=node->right;
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
node=node->left;
}
return node;
} else {
-
+
while(node == node->parent->right) {
node=node->parent;
}
@@ -207,19 +207,19 @@ private:
return node->parent;
}
}
-
- inline Element* _predecessor(Element *p_node) const {
+
+ inline Element* _predecessor(Element *p_node) const {
Element *node=p_node;
-
+
if (node->left != _data._nil) {
-
+
node=node->left;
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
node=node->right;
}
return node;
} else {
-
+
while(node == node->parent->left) {
if (node->parent == _data._root)
return NULL;
@@ -229,23 +229,23 @@ private:
return node->parent;
}
}
-
-
+
+
Element *_find(const T& p_value) const {
-
+
Element *node = _data._root->left;
- C less;
-
+ C less;
+
while(node!=_data._nil) {
-
- if (less(p_value,node->value))
+
+ if (less(p_value,node->value))
node=node->left;
else if (less(node->value,p_value))
node=node->right;
else
break; // found
}
-
+
return (node!=_data._nil)?node:NULL;
}
@@ -282,68 +282,68 @@ private:
Element *_insert(const T& p_value, bool& r_exists) {
-
+
Element *new_parent=_data._root;
Element *node = _data._root->left;
- C less;
-
+ C less;
+
while (node!=_data._nil) {
-
+
new_parent=node;
-
+
if (less(p_value,node->value))
node=node->left;
else if (less(node->value,p_value))
node=node->right;
- else {
+ else {
r_exists=true;
return node;
- }
+ }
}
-
+
Element *new_node = memnew_allocator( Element,A );
-
+
new_node->parent=new_parent;
new_node->right=_data._nil;
new_node->left=_data._nil;
new_node->value=p_value;
// new_node->data=_data;
if (new_parent==_data._root || less(p_value,new_parent->value)) {
-
+
new_parent->left=new_node;
} else {
new_parent->right=new_node;
}
-
+
r_exists=false;
-
+
new_node->_next=_successor(new_node);
new_node->_prev=_predecessor(new_node);
if (new_node->_next)
new_node->_next->_prev=new_node;
if (new_node->_prev)
new_node->_prev->_next=new_node;
-
+
return new_node;
}
-
+
Element * _insert_rb(const T& p_value) {
-
+
bool exists=false;
Element *new_node = _insert(p_value,exists);
if (exists)
return new_node;
-
+
Element *node=new_node;
_data.size_cache++;
- while(node->parent->color==RED) {
-
+ while(node->parent->color==RED) {
+
if (node->parent == node->parent->parent->left) {
-
+
Element *aux=node->parent->parent->right;
-
+
if (aux->color==RED) {
_set_color(node->parent,BLACK);
_set_color(aux,BLACK);
@@ -357,10 +357,10 @@ private:
_set_color(node->parent,BLACK);
_set_color(node->parent->parent,RED);
_rotate_right(node->parent->parent);
- }
- } else {
+ }
+ } else {
Element *aux=node->parent->parent->left;
-
+
if (aux->color==RED) {
_set_color(node->parent,BLACK);
_set_color(aux,BLACK);
@@ -374,19 +374,19 @@ private:
_set_color(node->parent,BLACK);
_set_color(node->parent->parent,RED);
_rotate_left(node->parent->parent);
- }
+ }
}
}
_set_color(_data._root->left,BLACK);
- return new_node;
- }
+ return new_node;
+ }
void _erase_fix(Element *p_node) {
-
+
Element *root = _data._root->left;
Element *node=p_node;
-
-
+
+
while( (node->color==BLACK) && (root != node)) {
if (node == node->parent->left) {
Element *aux=node->parent->right;
@@ -396,7 +396,7 @@ private:
_rotate_left(node->parent);
aux=node->parent->right;
}
- if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
+ if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
_set_color(aux,RED);
node=node->parent;
} else {
@@ -420,7 +420,7 @@ private:
_rotate_right(node->parent);
aux=node->parent->left;
}
- if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
+ if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
_set_color(aux,RED);
node=node->parent;
} else {
@@ -434,24 +434,24 @@ private:
_set_color(node->parent,BLACK);
_set_color(aux->left,BLACK);
_rotate_right(node->parent);
- node=root;
+ node=root;
}
}
}
-
+
_set_color(node,BLACK);
-
+
ERR_FAIL_COND(_data._nil->color!=BLACK);
}
-
+
void _erase(Element *p_node) {
-
-
+
+
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
if (!rp)
rp=_data._nil;
Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
-
+
if (_data._root == (node->parent=rp->parent) ) {
_data._root->left=node;
} else {
@@ -461,47 +461,47 @@ private:
rp->parent->right=node;
}
}
-
- if (rp != p_node) {
-
+
+ if (rp != p_node) {
+
ERR_FAIL_COND( rp == _data._nil );
-
+
if (rp->color==BLACK)
_erase_fix(node);
-
-
+
+
rp->left=p_node->left;
rp->right=p_node->right;
rp->parent=p_node->parent;
rp->color=p_node->color;
p_node->left->parent=rp;
p_node->right->parent=rp;
-
+
if (p_node == p_node->parent->left) {
- p_node->parent->left=rp;
+ p_node->parent->left=rp;
} else {
p_node->parent->right=rp;
}
} else {
- if (p_node->color==BLACK)
+ if (p_node->color==BLACK)
_erase_fix(node);
-
+
}
-
-
+
+
if (p_node->_next)
p_node->_next->_prev=p_node->_prev;
if (p_node->_prev)
p_node->_prev->_next=p_node->_next;
-
+
memdelete_allocator<Element,A>(p_node);
_data.size_cache--;
ERR_FAIL_COND( _data._nil->color==RED );
}
-
-
+
+
void _calculate_depth(Element *p_element,int &max_d,int d) const {
-
+
if (p_element==_data._nil) {
return;
}
@@ -510,30 +510,30 @@ private:
if (d>max_d)
max_d=d;
}
-
+
void _cleanup_tree(Element *p_element) {
-
+
if (p_element==_data._nil)
return;
-
+
_cleanup_tree(p_element->left);
_cleanup_tree(p_element->right);
memdelete_allocator<Element,A>( p_element );
}
-
+
void _copy_from( const Set& p_set) {
-
+
clear();
// not the fastest way, but safeset to write.
for(Element *I=p_set.front();I;I=I->next()) {
-
+
insert(I->get());
}
}
public:
const Element *find(const T& p_value) const {
-
+
if (!_data._root)
return NULL;
@@ -542,30 +542,30 @@ public:
}
Element *find(const T& p_value) {
-
+
if (!_data._root)
return NULL;
Element *res=_find(p_value);
return res;
}
-
+
bool has(const T& p_value) const {
-
+
if (!_data._root)
return false;
return find(p_value)!=NULL;
}
-
+
Element *insert(const T& p_value) {
-
+
if (!_data._root)
_data._create_root();
return _insert_rb(p_value);
-
+
}
-
+
void erase(Element* p_element) {
-
+
if (!_data._root)
return;
_erase(p_element);
@@ -574,7 +574,7 @@ public:
}
bool erase(const T& p_value) {
-
+
if (!_data._root)
return false;
Element *e=find(p_value);
@@ -585,32 +585,32 @@ public:
_data._free_root();
return true;
}
-
+
Element *front() const {
-
+
if (!_data._root)
return NULL;
Element *e=_data._root->left;
if (e==_data._nil)
return NULL;
-
+
while(e->left!=_data._nil)
e=e->left;
-
+
return e;
}
-
+
Element *back() const {
-
+
if (!_data._root)
return NULL;
Element *e=_data._root->left;
if (e==_data._nil)
return NULL;
-
+
while(e->right!=_data._nil)
e=e->right;
-
+
return e;
}
@@ -619,7 +619,7 @@ public:
return _lower_bound(p_value);
}
-
+
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
// used for debug mostly
@@ -629,9 +629,9 @@ public:
_calculate_depth(_data._root->left,max_d,0);
return max_d;
}
-
+
void clear() {
-
+
if (!_data._root)
return;
@@ -641,25 +641,25 @@ public:
_data._nil->parent=_data._nil;
_data._free_root();
}
-
+
void operator=(const Set& p_set) {
-
+
_copy_from( p_set );
}
-
+
Set(const Set& p_set) {
-
+
_copy_from( p_set );
}
_FORCE_INLINE_ Set() {
-
+
}
-
-
+
+
~Set() {
-
- clear();
+
+ clear();
}
};
diff --git a/core/simple_type.h b/core/simple_type.h
index 1cc597146e..1754deec71 100644
--- a/core/simple_type.h
+++ b/core/simple_type.h
@@ -33,61 +33,61 @@
template<class T>
struct GetSimpleType {
-
+
T type;
};
template<class T>
struct GetSimpleTypeT {
-
+
typedef T type_t;
};
template<class T>
struct GetSimpleType<T&> {
-
+
T type;
-
+
};
template<class T>
struct GetSimpleTypeT<T&> {
-
+
typedef T type_t;
};
template<class T>
struct GetSimpleType<T const> {
-
+
T type;
_FORCE_INLINE_ GetSimpleType() { }
-
+
};
template<class T>
struct GetSimpleTypeT<T const> {
-
+
typedef T type_t;
};
template<class T>
struct GetSimpleType<const T&> {
-
+
T type;
_FORCE_INLINE_ GetSimpleType() { }
-
+
};
template<class T>
struct GetSimpleType<T*> {
-
+
T *type;
_FORCE_INLINE_ GetSimpleType() { type=NULL; }
};
template<class T>
struct GetSimpleType<const T*> {
-
+
T *type;
_FORCE_INLINE_ GetSimpleType() { type=NULL; }
};
diff --git a/core/sort.h b/core/sort.h
index bd61921c8a..2070065a0d 100644
--- a/core/sort.h
+++ b/core/sort.h
@@ -44,7 +44,7 @@ template<class T, class Comparator=_DefaultComparator<T> >
class SortArray {
enum {
-
+
INTROSORT_TRESHOLD=16
};
@@ -54,7 +54,7 @@ public:
inline const T& median_of_3(const T& a, const T& b, const T& c) const {
-
+
if (compare(a, b))
if (compare(b, c))
return b;
@@ -69,90 +69,90 @@ public:
else
return b;
}
-
-
+
+
inline int bitlog(int n) const {
int k;
- for (k = 0; n != 1; n >>= 1)
+ for (k = 0; n != 1; n >>= 1)
++k;
return k;
}
-
-
+
+
/* Heap / Heapsort functions */
-
+
inline void push_heap(int p_first,int p_hole_idx,int p_top_index,T p_value,T* p_array) const {
-
+
int parent = (p_hole_idx - 1) / 2;
while (p_hole_idx > p_top_index && compare(p_array[p_first + parent], p_value)) {
-
+
p_array[p_first + p_hole_idx] = p_array[p_first + parent];
p_hole_idx = parent;
parent = (p_hole_idx - 1) / 2;
}
- p_array[p_first + p_hole_idx] = p_value;
- }
-
+ p_array[p_first + p_hole_idx] = p_value;
+ }
+
inline void pop_heap(int p_first, int p_last, int p_result, T p_value, T* p_array) const {
-
+
p_array[p_result]=p_array[p_first];
adjust_heap(p_first,0,p_last-p_first,p_value,p_array);
}
inline void pop_heap(int p_first,int p_last,T* p_array) const {
-
+
pop_heap(p_first,p_last-1,p_last-1,p_array[p_last-1],p_array);
}
-
+
inline void adjust_heap(int p_first,int p_hole_idx,int p_len,T p_value,T* p_array) const {
-
-
+
+
int top_index = p_hole_idx;
int second_child = 2 * p_hole_idx + 2;
-
+
while (second_child < p_len) {
-
+
if (compare(p_array[p_first + second_child],p_array[p_first + (second_child - 1)]))
second_child--;
-
+
p_array[p_first + p_hole_idx] = p_array[p_first + second_child];
p_hole_idx = second_child;
second_child = 2 * (second_child + 1);
}
-
+
if (second_child == p_len) {
p_array[p_first + p_hole_idx] = p_array[p_first + (second_child - 1)];
p_hole_idx = second_child - 1;
}
push_heap(p_first, p_hole_idx, top_index, p_value,p_array);
}
-
+
inline void sort_heap(int p_first,int p_last,T* p_array) const {
-
+
while(p_last-p_first > 1) {
-
+
pop_heap(p_first,p_last--,p_array);
}
}
-
+
inline void make_heap(int p_first, int p_last,T* p_array) const {
- if (p_last - p_first < 2)
+ if (p_last - p_first < 2)
return;
int len = p_last - p_first;
int parent = (len - 2)/2;
-
+
while (true) {
adjust_heap(p_first, parent, len, p_array[p_first + parent], p_array);
- if (parent == 0)
+ if (parent == 0)
return;
parent--;
}
}
-
+
inline void partial_sort(int p_first,int p_last,int p_middle,T* p_array) const {
-
+
make_heap(p_first,p_middle,p_array);
- for(int i=p_middle;i<p_last;i++)
+ for(int i=p_middle;i<p_last;i++)
if (compare( p_array[i],p_array[p_first]))
pop_heap(p_first,p_middle,i,p_array[i],p_array);
sort_heap(p_first,p_middle,p_array);
@@ -167,17 +167,17 @@ public:
}
inline int partitioner(int p_first, int p_last, T p_pivot, T* p_array) const {
-
+
while (true) {
- while (compare(p_array[p_first],p_pivot))
+ while (compare(p_array[p_first],p_pivot))
p_first++;
p_last--;
while (compare(p_pivot,p_array[p_last]))
p_last--;
-
+
if (!(p_first < p_last))
return p_first;
-
+
SWAP(p_array[p_first],p_array[p_last]);
p_first++;
}
@@ -186,28 +186,28 @@ public:
inline void introsort(int p_first, int p_last, T* p_array, int p_max_depth) const {
while( p_last - p_first > INTROSORT_TRESHOLD ) {
-
+
if (p_max_depth == 0) {
partial_sort(p_first,p_last,p_last,p_array);
return;
}
-
+
p_max_depth--;
-
- int cut = partitioner(
- p_first,
- p_last,
- median_of_3(
- p_array[p_first],
- p_array[p_first + (p_last-p_first)/2],
+
+ int cut = partitioner(
+ p_first,
+ p_last,
+ median_of_3(
+ p_array[p_first],
+ p_array[p_first + (p_last-p_first)/2],
p_array[p_last-1]
),
p_array
);
-
+
introsort(cut,p_last,p_array,p_max_depth);
p_last=cut;
-
+
}
}
@@ -245,7 +245,7 @@ public:
}
inline void unguarded_linear_insert(int p_last,T p_value,T* p_array) const {
-
+
int next = p_last-1;
while (compare(p_value,p_array[next])) {
p_array[p_last]=p_array[next];
@@ -254,48 +254,48 @@ public:
}
p_array[p_last] = p_value;
}
-
+
inline void linear_insert(int p_first,int p_last,T*p_array) const {
-
+
T val = p_array[p_last];
if (compare(val, p_array[p_first])) {
-
+
for (int i=p_last; i>p_first; i--)
p_array[i]=p_array[i-1];
-
+
p_array[p_first] = val;
} else
- unguarded_linear_insert(p_last, val, p_array);
+ unguarded_linear_insert(p_last, val, p_array);
}
-
+
inline void insertion_sort(int p_first,int p_last,T* p_array) const {
-
+
if (p_first==p_last)
return;
for (int i=p_first+1; i!=p_last ; i++)
linear_insert(p_first,i,p_array);
}
-
+
inline void unguarded_insertion_sort(int p_first,int p_last,T* p_array) const {
-
+
for (int i=p_first; i!=p_last ; i++)
unguarded_linear_insert(i,p_array[i],p_array);
}
-
+
inline void final_insertion_sort(int p_first,int p_last,T* p_array) const {
-
+
if (p_last - p_first > INTROSORT_TRESHOLD) {
insertion_sort(p_first,p_first+INTROSORT_TRESHOLD,p_array);
unguarded_insertion_sort(p_first+INTROSORT_TRESHOLD,p_last,p_array);
} else {
-
+
insertion_sort(p_first,p_last,p_array);
-
- }
+
+ }
}
inline void sort_range(int p_first, int p_last,T* p_array) const {
-
+
if (p_first != p_last) {
introsort(p_first, p_last,p_array,bitlog(p_last - p_first) * 2);
final_insertion_sort(p_first, p_last, p_array);
@@ -303,7 +303,7 @@ public:
}
inline void sort(T* p_array,int p_len) const {
-
+
sort_range(0,p_len,p_array);
}
diff --git a/core/string_db.cpp b/core/string_db.cpp
index 0e953cc326..9a693f88e9 100644
--- a/core/string_db.cpp
+++ b/core/string_db.cpp
@@ -43,23 +43,23 @@ StringName _scs_create(const char *p_chr) {
bool StringName::configured=false;
void StringName::setup() {
-
+
ERR_FAIL_COND(configured);
for(int i=0;i<STRING_TABLE_LEN;i++) {
-
+
_table[i]=NULL;
}
configured=true;
}
void StringName::cleanup() {
-
- _global_lock();
+
+ _global_lock();
int lost_strings=0;
for(int i=0;i<STRING_TABLE_LEN;i++) {
-
+
while(_table[i]) {
-
+
_Data*d=_table[i];
lost_strings++;
if (OS::get_singleton()->is_stdout_verbose()) {
@@ -71,23 +71,23 @@ void StringName::cleanup() {
}
}
- _table[i]=_table[i]->next;
+ _table[i]=_table[i]->next;
memdelete(d);
}
}
if (OS::get_singleton()->is_stdout_verbose() && lost_strings) {
print_line("StringName: "+itos(lost_strings)+" unclaimed string names at exit.");
}
- _global_unlock();
+ _global_unlock();
}
void StringName::unref() {
-
+
ERR_FAIL_COND(!configured);
if (_data && _data->refcount.unref()) {
-
- _global_lock();
+
+ _global_lock();
if (_data->prev) {
_data->prev->next=_data->next;
@@ -97,26 +97,26 @@ void StringName::unref() {
}
_table[_data->idx]=_data->next;
}
-
+
if (_data->next) {
_data->next->prev=_data->prev;
}
memdelete(_data);
- _global_unlock();
+ _global_unlock();
}
-
+
_data=NULL;
-
+
}
bool StringName::operator==(const String& p_name) const {
-
+
if (!_data) {
-
+
return (p_name.length()==0);
}
-
+
return (_data->get_name()==p_name);
}
@@ -131,50 +131,50 @@ bool StringName::operator==(const char* p_name) const {
}
bool StringName::operator!=(const String& p_name) const {
-
+
return !(operator==(p_name));
}
bool StringName::operator!=(const StringName& p_name) const {
-
- // the real magic of all this mess happens here.
+
+ // the real magic of all this mess happens here.
// this is why path comparisons are very fast
return _data!=p_name._data;
-
+
}
void StringName::operator=(const StringName& p_name) {
-
+
if (this==&p_name)
return;
-
+
unref();
-
+
if (p_name._data && p_name._data->refcount.ref()) {
-
- _data = p_name._data;
+
+ _data = p_name._data;
}
}
/* was inlined
StringName::operator String() const {
-
+
if (_data)
return _data->get_name();
-
+
return "";
}
*/
StringName::StringName(const StringName& p_name) {
-
+
ERR_FAIL_COND(!configured);
_data=NULL;
if (p_name._data && p_name._data->refcount.ref()) {
-
- _data = p_name._data;
- }
+
+ _data = p_name._data;
+ }
}
StringName::StringName(const char *p_name) {
@@ -184,17 +184,17 @@ StringName::StringName(const char *p_name) {
ERR_FAIL_COND(!configured);
ERR_FAIL_COND( !p_name || !p_name[0]);
-
- _global_lock();
-
+
+ _global_lock();
+
uint32_t hash = String::hash(p_name);
-
+
uint32_t idx=hash&STRING_TABLE_MASK;
-
+
_data=_table[idx];
-
+
while(_data) {
-
+
// compare hash first
if (_data->hash==hash && _data->get_name()==p_name)
break;
@@ -226,7 +226,7 @@ StringName::StringName(const char *p_name) {
_global_unlock();
-
+
}
StringName::StringName(const StaticCString& p_static_string) {
@@ -268,7 +268,7 @@ StringName::StringName(const StaticCString& p_static_string) {
_data->refcount.init();
_data->hash=hash;
- _data->idx=idx;
+ _data->idx=idx;
_data->cname=p_static_string.ptr;
_data->next=_table[idx];
_data->prev=NULL;
@@ -283,26 +283,26 @@ StringName::StringName(const StaticCString& p_static_string) {
StringName::StringName(const String& p_name) {
-
+
_data=NULL;
ERR_FAIL_COND(!configured);
- _global_lock();
-
+ _global_lock();
+
uint32_t hash = p_name.hash();
-
+
uint32_t idx=hash&STRING_TABLE_MASK;
_data=_table[idx];
-
+
while(_data) {
-
+
if (_data->hash==hash && _data->get_name()==p_name)
break;
_data=_data->next;
}
-
+
if (_data) {
if (_data->refcount.ref()) {
@@ -329,7 +329,7 @@ StringName::StringName(const String& p_name) {
_table[idx]=_data;
_global_unlock();
-
+
}
StringName StringName::search(const char *p_name) {
@@ -435,12 +435,12 @@ StringName StringName::search(const String &p_name) {
StringName::StringName() {
-
+
_data=NULL;
}
StringName::~StringName() {
-
+
unref();
}
diff --git a/core/string_db.h b/core/string_db.h
index f6c6ecefec..43bcccc902 100644
--- a/core/string_db.h
+++ b/core/string_db.h
@@ -46,16 +46,16 @@ struct StaticCString {
class StringName {
-
+
enum {
-
+
STRING_TABLE_BITS=12,
STRING_TABLE_LEN=1<<STRING_TABLE_BITS,
STRING_TABLE_MASK=STRING_TABLE_LEN-1
};
-
- struct _Data {
+
+ struct _Data {
SafeRefCount refcount;
const char* cname;
String name;
@@ -67,32 +67,32 @@ class StringName {
_Data *next;
_Data() { cname=NULL; next=prev=NULL; hash=0; }
};
-
-
+
+
static _Data *_table[STRING_TABLE_LEN];
-
+
_Data *_data;
-
+
union _HashUnion {
-
+
_Data *ptr;
uint32_t hash;
};
-
+
void unref();
friend void register_core_types();
friend void unregister_core_types();
-
+
static void setup();
static void cleanup();
static bool configured;
-
+
StringName(_Data *p_data) { _data=p_data; }
public:
operator const void*() const { return (_data && (_data->cname || !_data->name.empty()))?(void*)1:0; }
-
+
bool operator==(const String& p_name) const;
bool operator==(const char* p_name) const;
bool operator!=(const String& p_name) const;
@@ -101,19 +101,19 @@ public:
return _data<p_name._data;
}
_FORCE_INLINE_ bool operator==(const StringName& p_name) const {
- // the real magic of all this mess happens here.
+ // the real magic of all this mess happens here.
// this is why path comparisons are very fast
return _data==p_name._data;
- }
+ }
_FORCE_INLINE_ uint32_t hash() const {
-
+
if (_data)
return _data->hash;
else
return 0;
}
bool operator!=(const StringName& p_name) const;
-
+
_FORCE_INLINE_ operator String() const {
if (_data) {
@@ -148,7 +148,7 @@ public:
};
struct StringNameHasher {
-
+
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string) { return p_string.hash(); }
};
diff --git a/core/typedefs.h b/core/typedefs.h
index 1ca7a4f66d..5047644692 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -74,7 +74,7 @@
#endif
#ifndef DEFAULT_ALIGNMENT
-#define DEFAULT_ALIGNMENT 16
+#define DEFAULT_ALIGNMENT 1
#endif
@@ -154,6 +154,23 @@ inline void __swap_tmpl(T &x, T &y ) {
((m_hex>='A' && m_hex<='F')?(10+m_hex-'A'):\
((m_hex>='a' && m_hex<='f')?(10+m_hex-'a'):0)))
+// Macro to check whether we are compiled by clang
+// and we have a specific builtin
+#if defined(__llvm__) && defined(__has_builtin)
+ #define _llvm_has_builtin(x) __has_builtin(x)
+#else
+ #define _llvm_has_builtin(x) 0
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_mul_overflow)
+# define _mul_overflow __builtin_mul_overflow
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_add_overflow)
+# define _add_overflow __builtin_add_overflow
+#endif
+
+
@@ -167,6 +184,28 @@ static _FORCE_INLINE_ unsigned int nearest_power_of_2(unsigned int x) {
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
+
+ return ++x;
+}
+
+// We need this definition inside the function below.
+static inline int get_shift_from_power_of_2(unsigned int p_pixel);
+
+template<class T>
+static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) {
+
+ --x;
+
+ // The number of operations on x is the base two logarithm
+ // of the p_number of bits in the type. Add three to account
+ // for sizeof(T) being in bytes.
+ size_t num = get_shift_from_power_of_2(sizeof(T)) + 3;
+
+ // If the compiler is smart, it unrolls this loop
+ // If its dumb, this is a bit slow.
+ for (size_t i = 0; i < num; i++)
+ x |= x >> (1 << i);
+
return ++x;
}
@@ -231,7 +270,7 @@ void _global_lock();
void _global_unlock();
struct _GlobalLock {
-
+
_GlobalLock() { _global_lock(); }
~_GlobalLock() { _global_unlock(); }
};
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index ecbda1d3fd..d6d32ccaef 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -239,7 +239,7 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
case Operation::TYPE_METHOD: {
- obj->call(op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
+ obj->call(op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
#ifdef TOOLS_ENABLED
Resource* res = obj->cast_to<Resource>();
if (res)
@@ -450,10 +450,10 @@ void UndoRedo::_bind_methods() {
ObjectTypeDB::bind_method(_MD("create_action","name","mergeable"),&UndoRedo::create_action, DEFVAL(false) );
ObjectTypeDB::bind_method(_MD("commit_action"),&UndoRedo::commit_action);
-
+
//ObjectTypeDB::bind_method(_MD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
//ObjectTypeDB::bind_method(_MD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method);
-
+
{
MethodInfo mi;
mi.name="add_do_method";
diff --git a/core/ustring.cpp b/core/ustring.cpp
index ee750c39e5..a9d0012ebe 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -67,14 +67,14 @@ void String::copy_from(const char *p_cstr) {
len++;
if (len==0) {
-
+
resize(0);
return;
}
-
+
resize(len+1); // include 0
-
+
CharType *dst = this->ptr();
for (int i=0;i<len+1;i++) {
@@ -85,35 +85,35 @@ void String::copy_from(const char *p_cstr) {
}
void String::copy_from(const CharType* p_cstr, int p_clip_to) {
-
+
int len=0;
const CharType *ptr=p_cstr;
while (*(ptr++)!=0)
len++;
-
+
if (p_clip_to>=0 && len>p_clip_to)
len=p_clip_to;
-
+
if (len==0) {
-
+
resize(0);
return;
}
-
+
resize(len+1);
set(len,0);
-
+
CharType *dst = &operator[](0);
-
-
+
+
for (int i=0;i<len;i++) {
-
+
dst[i]=p_cstr[i];
}
}
void String::copy_from(const CharType& p_char) {
-
+
resize(2);
set(0,p_char);
set(1,0);
@@ -126,12 +126,12 @@ bool String::operator==(const String& p_str) const {
return false;
if (empty())
return true;
-
+
int l=length();
-
+
const CharType *src = c_str();
const CharType *dst = p_str.c_str();
-
+
/* Compare char by char */
for (int i=0;i<l;i++) {
@@ -170,19 +170,19 @@ String& String::operator+=(const String &p_str) {
*this=p_str;
return *this;
}
-
+
if (p_str.empty())
return *this;
-
+
int from=length();
-
+
resize( length() + p_str.size() );
-
+
const CharType *src = p_str.c_str();
CharType *dst = &operator[](0);
set( length(), 0 );
-
+
for (int i=0;i<p_str.length();i++)
dst[from+i]=src[i];
@@ -200,11 +200,11 @@ String& String::operator+=(const CharType *p_str) {
String& String::operator+=(CharType p_char) {
-
+
resize( size() ? size() + 1 : 2);
set( length(), 0 );
set( length() -1, p_char );
-
+
return *this;
}
@@ -220,13 +220,13 @@ String& String::operator+=(const char * p_str) {
src_len++;
int from=length();
-
+
resize( from + src_len + 1 );
-
+
CharType *dst = &operator[](0);
-
+
set( length(), 0 );
-
+
for (int i=0;i<src_len;i++)
dst[from+i]=p_str[i];
@@ -283,11 +283,11 @@ bool String::operator==(const char *p_str) const {
return false;
if (empty())
return true;
-
+
int l=length();
-
+
const CharType *dst = c_str();
-
+
/* Compare char by char */
for (int i=0;i<l;i++) {
@@ -312,11 +312,11 @@ bool String::operator==(const CharType *p_str) const {
return false;
if (empty())
return true;
-
+
int l=length();
-
+
const CharType *dst = c_str();
-
+
/* Compare char by char */
for (int i=0;i<l;i++) {
@@ -347,8 +347,8 @@ bool String::operator<(const CharType *p_str) const {
return false;
if (empty())
return true;
-
-
+
+
const CharType *this_str=c_str();
while (true) {
@@ -382,7 +382,7 @@ bool String::operator<(const char *p_str) const {
return false;
if (empty())
return true;
-
+
const CharType *this_str=c_str();
while (true) {
@@ -412,7 +412,7 @@ bool String::operator<(String p_str) const {
return operator<(p_str.c_str());
}
-signed char String::nocasecmp_to(const String &p_str) const {
+signed char String::nocasecmp_to(const String &p_str) const {
if (empty() && p_str.empty())
return 0;
@@ -423,7 +423,7 @@ signed char String::nocasecmp_to(const String &p_str) const {
const CharType *that_str=p_str.c_str();
const CharType *this_str=c_str();
-
+
while (true) {
if (*that_str==0 && *this_str==0)
@@ -445,7 +445,7 @@ signed char String::nocasecmp_to(const String &p_str) const {
}
-signed char String::casecmp_to(const String &p_str) const {
+signed char String::casecmp_to(const String &p_str) const {
if (empty() && p_str.empty())
return 0;
@@ -456,7 +456,7 @@ signed char String::casecmp_to(const String &p_str) const {
const CharType *that_str=p_str.c_str();
const CharType *this_str=c_str();
-
+
while (true) {
if (*that_str==0 && *this_str==0)
@@ -493,47 +493,56 @@ String String::capitalize() const {
String aux=this->replace("_"," ").to_lower();
String cap;
for (int i=0;i<aux.get_slice_count(" ");i++) {
-
+
String slice=aux.get_slicec(' ',i);
if (slice.length()>0) {
-
+
slice[0]=_find_upper(slice[0]);
if (i>0)
cap+=" ";
cap+=slice;
}
}
-
+
return cap;
}
-String String::camelcase_to_underscore() const {
+String String::camelcase_to_underscore(bool lowercase) const {
const CharType * cstr = c_str();
- String newString;
+ String new_string;
const char A = 'A', Z = 'Z';
- int startIndex = 0;
+ const char a = 'a', z = 'z';
+ int start_index = 0;
- for ( int i = 1; i < this->size()-1; i++ ) {
- bool isCapital = cstr[i] >= A && cstr[i] <= Z;
+ for ( size_t i = 1; i < this->size(); i++ ) {
+ bool is_upper = cstr[i] >= A && cstr[i] <= Z;
+ bool are_next_2_lower = false;
+ bool was_precedent_upper = cstr[i-1] >= A && cstr[i-1] <= Z;
- if ( isCapital ) {
- newString += "_" + this->substr(startIndex, i-startIndex);
- startIndex = i;
+ if (i+2 < this->size()) {
+ are_next_2_lower = cstr[i+1] >= a && cstr[i+1] <= z && cstr[i+2] >= a && cstr[i+2] <= z;
}
- }
- newString += "_" + this->substr(startIndex, this->size()-startIndex);
+ bool should_split = ((is_upper && !was_precedent_upper) || (was_precedent_upper && is_upper && are_next_2_lower));
+ if (should_split) {
+ new_string += this->substr(start_index, i - start_index) + "_";
+ start_index = i;
+ }
+ }
- return newString;
+ new_string += this->substr(start_index, this->size() - start_index);
+ return lowercase ? new_string.to_lower() : new_string;
}
+
+
int String::get_slice_count(String p_splitter) const{
if (empty())
return 0;
if (p_splitter.empty())
return 0;
-
+
int pos=0;
int slices=1;
@@ -550,7 +559,7 @@ String String::get_slice(String p_splitter, int p_slice) const {
if (empty() || p_splitter.empty())
return "";
-
+
int pos=0;
int prev_pos=0;
// int slices=1;
@@ -835,7 +844,7 @@ int String::length() const {
const CharType * String::c_str() const {
static const CharType zero=0;
-
+
return size()?&operator[](0):&zero;
}
@@ -858,10 +867,10 @@ String String::md5(const uint8_t *p_md5) {
}
String String::chr(CharType p_char) {
-
+
CharType c[2]={p_char,0};
return String(c);
-
+
}
String String::num(double p_num,int p_decimals) {
@@ -1005,7 +1014,7 @@ String String::num(double p_num,int p_decimals) {
String decimal;
for (int i=0;i<digit;i++) {
-
+
char num[2]={0,0};
num[0]='0'+dec_int%10;
decimal=num+decimal;
@@ -1191,10 +1200,10 @@ CharString String::ascii(bool p_allow_extended) const {
CharString cs;
cs.resize(size());
-
+
for (int i=0;i<size();i++)
cs[i]=operator[](i);
-
+
return cs;
}
@@ -1599,7 +1608,7 @@ int String::to_int() const {
integer+=c-'0';
} else if (integer==0 && c=='-') {
-
+
sign=-sign;
}
@@ -2198,14 +2207,14 @@ double String::to_double() const {
double exp=0;
double exp_sign=1.0;
int reading=READING_SIGN;
-
+
const CharType *str=&operator[](0);
while(*str && reading!=READING_DONE) {
-
+
CharType c=*(str++);
switch(reading) {
- case READING_SIGN: {
+ case READING_SIGN: {
if (c>='0' && c<='9')
reading=READING_INT;
// let it fallthrough
@@ -2219,26 +2228,26 @@ double String::to_double() const {
} else {
break;
}
- }
+ }
case READING_INT: {
-
+
if (c>='0' && c<='9') {
-
+
integer*=10;
- integer+=c-'0';
- } else if (c=='.') {
+ integer+=c-'0';
+ } else if (c=='.') {
reading=READING_DEC;
} else if (c=='e') {
reading=READING_EXP;
} else {
reading=READING_DONE;
}
-
+
} break;
case READING_DEC: {
-
+
if (c>='0' && c<='9') {
-
+
decimal+=(c-'0')*decimal_mult;
decimal_mult*=0.1;
} else if (c=='e') {
@@ -2246,12 +2255,12 @@ double String::to_double() const {
} else {
reading=READING_DONE;
}
-
+
} break;
case READING_EXP: {
-
+
if (c>='0' && c<='9') {
-
+
exp*=10.0;
exp+=(c-'0');
} else if (c=='-' && exp==0) {
@@ -2265,14 +2274,14 @@ double String::to_double() const {
} break;
}
}
-
+
return sign*(integer+decimal)*Math::pow(10,exp_sign*exp);
#endif
#if 0
double ret=sign*(integer+decimal)*Math::pow(10,exp_sign*exp);
-
+
print_line(*this +" == "+rtos(ret));
return ret;
#endif
@@ -2299,14 +2308,14 @@ String operator+(CharType p_chr, const String& p_str) {
}
uint32_t String::hash(const char* p_cstr) {
-
+
uint32_t hashv = 5381;
uint32_t c;
-
+
while ((c = *p_cstr++))
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
-
- return hashv;
+
+ return hashv;
}
uint32_t String::hash(const char* p_cstr,int p_len) {
@@ -2339,19 +2348,19 @@ uint32_t String::hash(const CharType* p_cstr) {
}
uint32_t String::hash() const {
-
+
/* simple djb2 hashing */
-
+
const CharType * chr = c_str();
uint32_t hashv = 5381;
uint32_t c;
-
+
while ((c = *chr++))
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
-
+
return hashv;
-
-
+
+
}
uint64_t String::hash64() const {
@@ -2433,16 +2442,16 @@ String String::substr(int p_from,int p_chars) const{
}
int String::find_last(String p_str) const {
-
+
int pos=-1;
int findfrom=0;
int findres=-1;
while((findres=find(p_str,findfrom))!=-1) {
-
+
pos=findres;
findfrom=pos+1;
}
-
+
return pos;
}
int String::find(String p_str,int p_from) const {
@@ -2699,48 +2708,48 @@ bool String::ends_with(const String& p_string) const {
}
bool String::begins_with(const String& p_string) const {
-
+
if (p_string.length() > length())
return false;
-
+
int l=p_string.length();
if (l==0)
return true;
-
+
const CharType *src=&p_string[0];
const CharType *str=&operator[](0);
-
+
int i = 0;
for (;i<l;i++) {
-
+
if (src[i]!=str[i])
return false;
}
-
+
// only if i == l the p_string matches the beginning
return i == l;
-
+
}
bool String::begins_with(const char* p_string) const {
-
+
int l=length();
if (l==0||!p_string)
return false;
-
+
const CharType *str=&operator[](0);
int i=0;
-
+
while (*p_string && i<l) {
-
+
if (*p_string != str[i])
return false;
i++;
p_string++;
-
+
}
-
+
return *p_string == 0;
-
+
}
@@ -2753,27 +2762,27 @@ static bool _wildcard_match(const CharType* p_pattern, const CharType* p_string,
case '?' :
return *p_string && (*p_string != '.') && _wildcard_match(p_pattern+1, p_string+1,p_case_sensitive);
default :
-
+
return (p_case_sensitive?(*p_string==*p_pattern):(_find_upper(*p_string)==_find_upper(*p_pattern))) && _wildcard_match(p_pattern+1, p_string+1,p_case_sensitive);
- }
+ }
}
bool String::match(const String& p_wildcard) const {
-
+
if (!p_wildcard.length() || !length())
return false;
-
+
return _wildcard_match(p_wildcard.c_str(),c_str(),true);
}
bool String::matchn(const String& p_wildcard) const {
-
+
if (!p_wildcard.length() || !length())
return false;
return _wildcard_match(p_wildcard.c_str(),c_str(),false);
-
+
}
String String::replace(String p_key,String p_with) const {
@@ -2845,7 +2854,7 @@ String String::right(int p_pos) const {
if (p_pos>=size())
return *this;
-
+
if (p_pos<0)
return "";
@@ -2859,26 +2868,26 @@ CharType String::ord_at(int p_idx) const {
}
String String::strip_edges() const {
-
+
int len=length();
int beg=0,end=len;
-
+
for (int i=0;i<length();i++) {
-
+
if (operator[](i)<=32)
beg++;
else
break;
}
-
+
for (int i=(int)(length()-1);i>=0;i--) {
-
+
if (operator[](i)<=32)
end--;
else
break;
}
-
+
if (beg==0 && end==len)
return *this;
@@ -3003,7 +3012,7 @@ String String::humanize_size(size_t p_size) {
int digits=prefix_idx>0?_humanize_digits(p_size/_div):0;
double divisor = prefix_idx>0?_div:1;
-
+
return String::num(p_size/divisor,digits)+prefix[prefix_idx];
}
bool String::is_abs_path() const {
@@ -3578,12 +3587,12 @@ String String::get_file() const {
}
String String::extension() const {
-
+
int pos = find_last(".");
if (pos<0)
return *this;
-
- return substr( pos+1, length() );
+
+ return substr( pos+1, length() );
}
String String::plus_file(const String& p_file) const {
@@ -3740,7 +3749,7 @@ String String::sprintf(const Array& values, bool* error) const {
if (!values[value_index].is_num()) {
return "a number is required";
}
-
+
int64_t value = values[value_index];
int base;
bool capitalize = false;
@@ -3802,7 +3811,7 @@ String String::sprintf(const Array& values, bool* error) const {
formatted += str;
++value_index;
in_format = false;
-
+
break;
}
case 's': { // String
diff --git a/core/ustring.h b/core/ustring.h
index 9276afa0f7..6310d0a854 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -40,7 +40,7 @@
class CharString : public Vector<char> {
-public:
+public:
int length() const { return size() ? size()-1 : 0; }
const char *get_data() const;
operator const char*() {return get_data();};
@@ -120,7 +120,7 @@ public:
bool match(const String& p_wildcard) const;
bool matchn(const String& p_wildcard) const;
bool begins_with(const String& p_string) const;
- bool begins_with(const char* p_string) const;
+ bool begins_with(const char* p_string) const;
bool ends_with(const String& p_string) const;
String replace_first(String p_key,String p_with) const;
String replace(String p_key,String p_with) const;
@@ -149,7 +149,7 @@ public:
static double to_double(const CharType* p_str, const CharType **r_end=NULL);
static int64_t to_int(const CharType* p_str,int p_len=-1);
String capitalize() const;
- String camelcase_to_underscore() const;
+ String camelcase_to_underscore(bool lowercase=true) const;
int get_slice_count(String p_splitter) const;
String get_slice(String p_splitter,int p_slice) const;
@@ -182,17 +182,17 @@ public:
CharString utf8() const;
bool parse_utf8(const char* p_utf8,int p_len=-1); //return true on error
static String utf8(const char* p_utf8,int p_len=-1);
-
+
static uint32_t hash(const CharType* p_str,int p_len); /* hash the string */
static uint32_t hash(const CharType* p_str); /* hash the string */
static uint32_t hash(const char* p_cstr,int p_len); /* hash the string */
static uint32_t hash(const char* p_cstr); /* hash the string */
uint32_t hash() const; /* hash the string */
- uint64_t hash64() const; /* hash the string */
+ uint64_t hash64() const; /* hash the string */
String md5_text() const;
Vector<uint8_t> md5_buffer() const;
- inline bool empty() const { return length() == 0; }
+ inline bool empty() const { return length() == 0; }
// path functions
bool is_abs_path() const;
@@ -213,7 +213,7 @@ public:
String c_unescape() const;
String json_escape() const;
String world_wrap(int p_chars_per_line) const;
-
+
String percent_encode() const;
String percent_decode() const;
@@ -247,9 +247,9 @@ String rtoss(double p_val); //scientific version
struct NoCaseComparator {
-
+
bool operator()(const String& p_a, const String& p_b) const {
-
+
return p_a.nocasecmp_to(p_b)<0;
}
};
diff --git a/core/variant.cpp b/core/variant.cpp
index 3bd8d80528..527a0d238f 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -37,7 +37,7 @@
String Variant::get_type_name(Variant::Type p_type) {
-
+
switch( p_type ) {
case NIL: {
@@ -297,7 +297,7 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
valid_types=valid;
- } break;
+ } break;
case COLOR: {
@@ -948,52 +948,52 @@ bool Variant::is_one() const {
void Variant::reference(const Variant& p_variant) {
-
+
if (this == &p_variant)
return;
-
+
clear();
-
+
type=p_variant.type;
-
+
switch( p_variant.type ) {
case NIL: {
-
+
// none
} break;
-
- // atomic types
+
+ // atomic types
case BOOL: {
-
+
_data._bool=p_variant._data._bool;
} break;
case INT: {
-
+
_data._int=p_variant._data._int;
-
+
} break;
case REAL: {
-
+
_data._real=p_variant._data._real;
-
+
} break;
case STRING: {
-
+
memnew_placement( _data._mem, String( *reinterpret_cast<const String*>(p_variant._data._mem) ) );
-
+
} break;
-
+
// math types
-
+
case VECTOR2: {
-
+
memnew_placement( _data._mem, Vector2( *reinterpret_cast<const Vector2*>(p_variant._data._mem) ) );
-
+
} break;
case RECT2: {
-
+
memnew_placement( _data._mem, Rect2( *reinterpret_cast<const Rect2*>(p_variant._data._mem) ) );
-
+
} break;
case MATRIX32: {
@@ -1001,100 +1001,100 @@ void Variant::reference(const Variant& p_variant) {
} break;
case VECTOR3: {
-
+
memnew_placement( _data._mem, Vector3( *reinterpret_cast<const Vector3*>(p_variant._data._mem) ) );
-
+
} break;
case PLANE: {
-
+
memnew_placement( _data._mem, Plane( *reinterpret_cast<const Plane*>(p_variant._data._mem) ) );
-
+
} break;
-/*
+/*
case QUAT: {
-
-
+
+
} break;*/
case _AABB: {
-
+
_data._aabb = memnew( AABB( *p_variant._data._aabb ) );
} break;
case QUAT: {
-
+
memnew_placement( _data._mem, Quat( *reinterpret_cast<const Quat*>(p_variant._data._mem) ) );
-
+
} break;
case MATRIX3: {
-
+
_data._matrix3 = memnew( Matrix3( *p_variant._data._matrix3 ) );
-
+
} break;
case TRANSFORM: {
-
+
_data._transform = memnew( Transform( *p_variant._data._transform ) );
-
+
} break;
-
- // misc types
+
+ // misc types
case COLOR: {
-
+
memnew_placement( _data._mem, Color( *reinterpret_cast<const Color*>(p_variant._data._mem) ) );
-
+
} break;
case IMAGE: {
-
+
_data._image = memnew( Image( *p_variant._data._image ) );
-
+
} break;
case _RID: {
-
+
memnew_placement( _data._mem, RID( *reinterpret_cast<const RID*>(p_variant._data._mem) ) );
} break;
case OBJECT: {
-
+
memnew_placement( _data._mem, ObjData( p_variant._get_obj() ) );
} break;
case NODE_PATH: {
-
+
memnew_placement( _data._mem, NodePath( *reinterpret_cast<const NodePath*>(p_variant._data._mem) ) );
-
+
} break;
case INPUT_EVENT: {
-
+
_data._input_event= memnew( InputEvent( *p_variant._data._input_event ) );
-
+
} break;
case DICTIONARY: {
-
+
memnew_placement( _data._mem, Dictionary( *reinterpret_cast<const Dictionary*>(p_variant._data._mem) ) );
-
+
} break;
case ARRAY: {
-
+
memnew_placement( _data._mem, Array ( *reinterpret_cast<const Array*>(p_variant._data._mem) ) );
-
+
} break;
-
+
// arrays
case RAW_ARRAY: {
-
+
memnew_placement( _data._mem, DVector<uint8_t> ( *reinterpret_cast<const DVector<uint8_t>*>(p_variant._data._mem) ) );
-
+
} break;
case INT_ARRAY: {
-
+
memnew_placement( _data._mem, DVector<int> ( *reinterpret_cast<const DVector<int>*>(p_variant._data._mem) ) );
-
+
} break;
case REAL_ARRAY: {
-
+
memnew_placement( _data._mem, DVector<real_t> ( *reinterpret_cast<const DVector<real_t>*>(p_variant._data._mem) ) );
-
+
} break;
case STRING_ARRAY: {
-
+
memnew_placement( _data._mem, DVector<String> ( *reinterpret_cast<const DVector<String>*>(p_variant._data._mem) ) );
-
+
} break;
case VECTOR2_ARRAY: {
@@ -1102,25 +1102,40 @@ void Variant::reference(const Variant& p_variant) {
} break;
case VECTOR3_ARRAY: {
-
+
memnew_placement( _data._mem, DVector<Vector3> ( *reinterpret_cast<const DVector<Vector3>*>(p_variant._data._mem) ) );
-
+
} break;
case COLOR_ARRAY: {
-
+
memnew_placement( _data._mem, DVector<Color> ( *reinterpret_cast<const DVector<Color>*>(p_variant._data._mem) ) );
-
+
} break;
default: {}
- }
+ }
}
+void Variant::zero() {
+ switch(type) {
+ case NIL: break;
+ case BOOL: this->_data._bool = false; break;
+ case INT: this->_data._int = 0; break;
+ case REAL: this->_data._real = 0; break;
+ case VECTOR2: *reinterpret_cast<Vector2*>(this->_data._mem) = Vector2(); break;
+ case RECT2: *reinterpret_cast<Rect2*>(this->_data._mem) = Rect2(); break;
+ case VECTOR3: *reinterpret_cast<Vector3*>(this->_data._mem) = Vector3(); break;
+ case PLANE: *reinterpret_cast<Plane*>(this->_data._mem) = Plane(); break;
+ case QUAT: *reinterpret_cast<Quat*>(this->_data._mem) = Quat(); break;
+ case COLOR: *reinterpret_cast<Color*>(this->_data._mem) = Color(); break;
+ default: this->clear(); break;
+ }
+}
void Variant::clear() {
switch(type) {
case STRING: {
-
+
reinterpret_cast<String*>(_data._mem)->~String();
} break;
/*
@@ -1138,33 +1153,33 @@ void Variant::clear() {
} break;
case _AABB: {
-
+
memdelete( _data._aabb );
-
+
} break;
case MATRIX3: {
-
+
memdelete( _data._matrix3 );
} break;
case TRANSFORM: {
-
+
memdelete( _data._transform );
-
+
} break;
-
- // misc types
+
+ // misc types
case IMAGE: {
-
+
memdelete( _data._image );
-
+
} break;
case NODE_PATH: {
-
+
reinterpret_cast<NodePath*>(_data._mem)->~NodePath();
-
+
} break;
case OBJECT: {
-
+
_get_obj().obj=NULL;
_get_obj().ref.unref();
} break;
@@ -1173,41 +1188,41 @@ void Variant::clear() {
reinterpret_cast<RID*>(_data._mem)->~RID();
} break;
case DICTIONARY: {
-
+
reinterpret_cast<Dictionary*>(_data._mem)->~Dictionary();
-
+
} break;
case ARRAY: {
-
+
reinterpret_cast<Array*>(_data._mem)->~Array();
-
+
} break;
case INPUT_EVENT: {
-
+
memdelete( _data._input_event );
-
+
} break;
-
+
// arrays
case RAW_ARRAY: {
-
+
reinterpret_cast< DVector<uint8_t>* >(_data._mem)->~DVector<uint8_t>();
-
+
} break;
case INT_ARRAY: {
-
+
reinterpret_cast< DVector<int>* >(_data._mem)->~DVector<int>();
-
+
} break;
case REAL_ARRAY: {
-
+
reinterpret_cast< DVector<real_t>* >(_data._mem)->~DVector<real_t>();
-
+
} break;
case STRING_ARRAY: {
-
+
reinterpret_cast< DVector<String>* >(_data._mem)->~DVector<String>();
-
+
} break;
case VECTOR2_ARRAY: {
@@ -1215,55 +1230,55 @@ void Variant::clear() {
} break;
case VECTOR3_ARRAY: {
-
+
reinterpret_cast< DVector<Vector3>* >(_data._mem)->~DVector<Vector3>();
-
+
} break;
case COLOR_ARRAY: {
-
+
reinterpret_cast< DVector<Color>* >(_data._mem)->~DVector<Color>();
-
+
} break;
default: {} /* not needed */
}
-
+
type=NIL;
}
-
+
Variant::operator signed int() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
case REAL: return _data._real;
case STRING: return operator String().to_int();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
Variant::operator unsigned int() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
case REAL: return _data._real;
case STRING: return operator String().to_int();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
@@ -1365,69 +1380,69 @@ Variant::operator unsigned long() const {
Variant::operator signed short() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
case REAL: return _data._real;
case STRING: return operator String().to_int();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
Variant::operator unsigned short() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
case REAL: return _data._real;
case STRING: return operator String().to_int();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
Variant::operator signed char() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
case REAL: return _data._real;
case STRING: return operator String().to_int();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
Variant::operator unsigned char() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
case REAL: return _data._real;
case STRING: return operator String().to_int();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
#ifndef CHARTYPE_16BITS
@@ -1440,40 +1455,40 @@ Variant::operator CharType() const {
Variant::operator float() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1.0 : 0.0;
case INT: return (float)_data._int;
case REAL: return _data._real;
case STRING: return operator String().to_double();
default: {
-
+
return 0;
- }
+ }
}
-
+
return 0;
}
Variant::operator double() const {
switch( type ) {
-
- case NIL: return 0;
+
+ case NIL: return 0;
case BOOL: return _data._bool ? 1.0 : 0.0;
case INT: return (float)_data._int;
case REAL: return _data._real;
case STRING: return operator String().to_double();
default: {
-
+
return 0;
- }
+ }
}
-
+
return true;
}
Variant::operator StringName() const {
-
+
if (type==NODE_PATH) {
return reinterpret_cast<const NodePath*>(_data._mem)->get_sname();
}
@@ -1494,8 +1509,8 @@ struct _VariantStrPair {
Variant::operator String() const {
switch( type ) {
-
- case NIL: return "";
+
+ case NIL: return "";
case BOOL: return _data._bool ? "True" : "False";
case INT: return String::num(_data._int);
case REAL: return String::num(_data._real);
@@ -1505,7 +1520,7 @@ Variant::operator String() const {
case MATRIX32: return operator Matrix32();
case VECTOR3: return operator Vector3();
case PLANE: return operator Plane();
- //case QUAT:
+ //case QUAT:
case _AABB: return operator AABB();
case QUAT: return operator Quat();
case MATRIX3: return operator Matrix3();
@@ -1514,7 +1529,7 @@ Variant::operator String() const {
case INPUT_EVENT: return operator InputEvent();
case COLOR: return String::num( operator Color().r)+","+String::num( operator Color().g)+","+String::num( operator Color().b)+","+String::num( operator Color().a) ;
case DICTIONARY: {
-
+
const Dictionary &d =*reinterpret_cast<const Dictionary*>(_data._mem);
//const String *K=NULL;
String str;
@@ -1538,15 +1553,15 @@ Variant::operator String() const {
str+=", ";
str+="("+pairs[i].key+":"+pairs[i].value+")";
}
-
+
return str;
} break;
- case VECTOR3_ARRAY: {
-
+ case VECTOR3_ARRAY: {
+
DVector<Vector3> vec = operator DVector<Vector3>();
String str;
for(int i=0;i<vec.size();i++) {
-
+
if (i>0)
str+=", ";
str=str+Variant( vec[i] );
@@ -1619,9 +1634,9 @@ Variant::operator String() const {
} break;
default: {
return "["+get_type_name(type)+"]";
- }
+ }
}
-
+
return "";
}
@@ -1804,7 +1819,7 @@ Variant::operator Control*() const {
}
Variant::operator InputEvent() const {
-
+
if (type==INPUT_EVENT)
return *reinterpret_cast<const InputEvent*>(_data._input_event);
else
@@ -1812,8 +1827,8 @@ Variant::operator InputEvent() const {
}
Variant::operator Dictionary() const {
-
- if (type==DICTIONARY)
+
+ if (type==DICTIONARY)
return *reinterpret_cast<const Dictionary*>(_data._mem);
else
return Dictionary();
@@ -1854,10 +1869,10 @@ inline DA _convert_array_from_variant(const Variant& p_variant) {
}
Variant::operator Array() const {
-
- if (type==ARRAY)
+
+ if (type==ARRAY)
return *reinterpret_cast<const Array*>(_data._mem);
- else
+ else
return _convert_array_from_variant<Array >(*this);
}
@@ -2004,17 +2019,17 @@ Variant::operator Vector<Plane>() const {
}
Variant::operator Vector<Variant>() const {
-
+
Array from=operator Array();
Vector<Variant> to;
int len=from.size();
to.resize(len);
for (int i=0;i<len;i++) {
-
+
to[i]=from[i];
}
return to;
-
+
}
Variant::operator Vector<uint8_t>() const {
@@ -2024,7 +2039,7 @@ Variant::operator Vector<uint8_t>() const {
int len=from.size();
to.resize(len);
for (int i=0;i<len;i++) {
-
+
to[i]=from[i];
}
return to;
@@ -2036,7 +2051,7 @@ Variant::operator Vector<int>() const {
int len=from.size();
to.resize(len);
for (int i=0;i<len;i++) {
-
+
to[i]=from[i];
}
return to;
@@ -2048,7 +2063,7 @@ Variant::operator Vector<real_t>() const {
int len=from.size();
to.resize(len);
for (int i=0;i<len;i++) {
-
+
to[i]=from[i];
}
return to;
@@ -2061,7 +2076,7 @@ Variant::operator Vector<String>() const {
int len=from.size();
to.resize(len);
for (int i=0;i<len;i++) {
-
+
to[i]=from[i];
}
return to;
@@ -2078,7 +2093,7 @@ Variant::operator Vector<Vector3>() const {
DVector<Vector3>::Read r = from.read();
Vector3 *w = &to[0];
for (int i=0;i<len;i++) {
-
+
w[i]=r[i];
}
return to;
@@ -2153,16 +2168,16 @@ Variant::Variant(unsigned int p_int) {
#ifdef NEED_LONG_INT
Variant::Variant(signed long p_int) {
-
+
type=INT;
_data._int=p_int;
-
+
}
Variant::Variant(unsigned long p_int) {
-
+
type=INT;
_data._int=p_int;
-
+
}
#endif
@@ -2217,10 +2232,10 @@ Variant::Variant(double p_double) {
}
Variant::Variant(const StringName& p_string) {
-
+
type=STRING;
memnew_placement( _data._mem, String( p_string.operator String() ) );
-
+
}
Variant::Variant(const String& p_string) {
@@ -2320,9 +2335,9 @@ Variant::Variant(const NodePath& p_node_path) {
}
Variant::Variant(const InputEvent& p_input_event) {
-
+
type=INPUT_EVENT;
- _data._input_event = memnew( InputEvent(p_input_event) );
+ _data._input_event = memnew( InputEvent(p_input_event) );
}
@@ -2352,10 +2367,10 @@ Variant::Variant(const Object* p_object) {
}
Variant::Variant(const Dictionary& p_dictionary) {
-
+
type=DICTIONARY;
memnew_placement( _data._mem, (Dictionary)( p_dictionary) );
-
+
}
Variant::Variant(const Array& p_array) {
@@ -2367,15 +2382,15 @@ Variant::Variant(const Array& p_array) {
Variant::Variant(const DVector<Plane>& p_array) {
-
+
type=ARRAY;
Array *plane_array=memnew_placement( _data._mem, Array );
-
+
plane_array->resize( p_array.size() );
-
+
for (int i=0;i<p_array.size();i++) {
-
+
plane_array->operator [](i)=Variant(p_array[i]);
}
}
diff --git a/core/variant.h b/core/variant.h
index b58c781bdd..ed33de6660 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -75,17 +75,17 @@ class Variant {
public:
enum Type {
-
- NIL,
-
- // atomic types
+
+ NIL,
+
+ // atomic types
BOOL,
INT,
REAL,
STRING,
-
+
// math types
-
+
VECTOR2, // 5
RECT2,
VECTOR3,
@@ -95,17 +95,17 @@ public:
_AABB, //sorry naming convention fail :( not like it's used often
MATRIX3,
TRANSFORM,
-
- // misc types
+
+ // misc types
COLOR,
IMAGE, // 15
NODE_PATH,
_RID,
- OBJECT,
+ OBJECT,
INPUT_EVENT,
DICTIONARY, // 20
ARRAY,
-
+
// arrays
RAW_ARRAY,
INT_ARRAY,
@@ -114,10 +114,10 @@ public:
VECTOR2_ARRAY,
VECTOR3_ARRAY,
COLOR_ARRAY,
-
+
VARIANT_MAX
-
- };
+
+ };
private:
@@ -125,7 +125,7 @@ private:
friend class _VariantCall;
// Variant takes 20 bytes when real_t is float, and 36 if double
// it only allocates extra memory for aabb/matrix.
-
+
Type type;
struct ObjData {
@@ -133,25 +133,25 @@ private:
Object *obj;
RefPtr ref;
};
-
+
_FORCE_INLINE_ ObjData& _get_obj();
_FORCE_INLINE_ const ObjData& _get_obj() const;
union {
-
+
bool _bool;
int _int;
double _real;
Matrix32 *_matrix32;
AABB* _aabb;
Matrix3 *_matrix3;
- Transform *_transform;
+ Transform *_transform;
RefPtr *_resource;
InputEvent *_input_event;
Image *_image;
void *_ptr; //generic pointer
-#ifdef USE_QUAD_VECTORS
+#ifdef USE_QUAD_VECTORS
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t)*5) ? sizeof(ObjData) : (sizeof(real_t)*5)]; // plane uses an extra real
#else
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t)*4) ? sizeof(ObjData) : (sizeof(real_t)*4)];
@@ -172,7 +172,7 @@ public:
template<class T>
static Type get_type_for() {
-
+
GetSimpleType<T> t;
Variant v(t.type);
Type r = v.get_type();
@@ -231,7 +231,7 @@ public:
operator Dictionary() const;
operator Array() const;
-
+
operator DVector<uint8_t>() const;
operator DVector<int>() const;
operator DVector<real_t>() const;
@@ -260,7 +260,7 @@ public:
operator IP_Address() const;
-
+
Variant(bool p_bool);
Variant(signed int p_int); // real one
Variant(unsigned int p_int);
@@ -286,8 +286,8 @@ public:
Variant(const Vector3& p_vector3);
Variant(const Plane& p_plane);
Variant(const AABB& p_aabb);
- Variant(const Quat& p_quat);
- Variant(const Matrix3& p_transform);
+ Variant(const Quat& p_quat);
+ Variant(const Matrix3& p_transform);
Variant(const Matrix32& p_transform);
Variant(const Transform& p_transform);
Variant(const Color& p_color);
@@ -295,10 +295,10 @@ public:
Variant(const NodePath& p_path);
Variant(const RefPtr& p_resource);
Variant(const RID& p_rid);
- Variant(const Object* p_object);
+ Variant(const Object* p_object);
Variant(const InputEvent& p_input_event);
Variant(const Dictionary& p_dictionary);
-
+
Variant(const Array& p_array);
Variant(const DVector<Plane>& p_array); // helper
Variant(const DVector<uint8_t>& p_raw_array);
@@ -309,7 +309,7 @@ public:
Variant(const DVector<Color>& p_color_array);
Variant(const DVector<Face3>& p_face_array);
-
+
Variant(const Vector<Variant>& p_array);
Variant(const Vector<uint8_t>& p_raw_array);
Variant(const Vector<int>& p_int_array);
@@ -372,6 +372,8 @@ public:
return res;
}
+ void zero();
+ static void blend(const Variant& a, const Variant& b, float c,Variant &r_dst);
static void interpolate(const Variant& a, const Variant& b, float c,Variant &r_dst);
struct CallError {
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 204a00e1d5..f03ab43fce 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -662,7 +662,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
case OP_DIVIDE: {
switch(p_a.type) {
- DEFAULT_OP_FAIL(NIL);
+ DEFAULT_OP_FAIL(NIL);
DEFAULT_OP_NUM(/,BOOL,_bool);
case INT: {
switch(p_b.type) {
@@ -779,7 +779,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
}
#endif
_RETURN( p_a._data._int % p_b._data._int );
-
+
} else if (p_a.type==STRING) {
const String* format=reinterpret_cast<const String*>(p_a._data._mem);
@@ -2409,7 +2409,7 @@ Variant Variant::get(const Variant& p_index, bool *r_valid) const {
} if (str=="value") {
valid=true;
return ie.joy_motion.axis_value;
- }
+ }
}
if (ie.type==InputEvent::SCREEN_TOUCH) {
@@ -3431,6 +3431,65 @@ Variant Variant::iter_get(const Variant& r_iter,bool &r_valid) const {
}
+void Variant::blend(const Variant& a, const Variant& b, float c, Variant &r_dst) {
+ if (a.type!=b.type) {
+ if(a.is_num() && b.is_num()) {
+ real_t va=a;
+ real_t vb=b;
+ r_dst=va + vb * c;
+ } else {
+ r_dst=a;
+ }
+ return;
+ }
+
+ switch(a.type) {
+ case NIL: { r_dst=Variant(); } return;
+ case INT:{
+ int va=a._data._int;
+ int vb=b._data._int;
+ r_dst=int(va + vb * c + 0.5);
+ } return;
+ case REAL:{
+ double ra=a._data._real;
+ double rb=b._data._real;
+ r_dst=ra + rb * c;
+ } return;
+ case VECTOR2:{ r_dst=*reinterpret_cast<const Vector2*>(a._data._mem)+*reinterpret_cast<const Vector2*>(b._data._mem)*c; } return;
+ case RECT2:{
+ const Rect2 *ra = reinterpret_cast<const Rect2*>(a._data._mem);
+ const Rect2 *rb = reinterpret_cast<const Rect2*>(b._data._mem);
+ r_dst=Rect2(ra->pos + rb->pos * c, ra->size + rb->size * c);
+ } return;
+ case VECTOR3:{ r_dst=*reinterpret_cast<const Vector3*>(a._data._mem)+*reinterpret_cast<const Vector3*>(b._data._mem)*c; } return;
+ case _AABB:{
+ const AABB *ra = reinterpret_cast<const AABB*>(a._data._mem);
+ const AABB *rb = reinterpret_cast<const AABB*>(b._data._mem);
+ r_dst=AABB(ra->pos + rb->pos * c, ra->size + rb->size * c);
+ } return;
+ case QUAT:{
+ Quat empty_rot;
+ const Quat *qa = reinterpret_cast<const Quat*>(a._data._mem);
+ const Quat *qb = reinterpret_cast<const Quat*>(b._data._mem);
+ r_dst=*qa * empty_rot.slerp(*qb,c);
+ } return;
+ case COLOR:{
+ const Color *ca = reinterpret_cast<const Color*>(a._data._mem);
+ const Color *cb = reinterpret_cast<const Color*>(b._data._mem);
+ float r = ca->r + cb->r * c;
+ float g = ca->g + cb->g * c;
+ float b = ca->b + cb->b * c;
+ float a = ca->a + cb->a * c;
+ r = r > 1.0 ? 1.0 : r;
+ g = g > 1.0 ? 1.0 : g;
+ b = b > 1.0 ? 1.0 : b;
+ a = a > 1.0 ? 1.0 : a;
+ r_dst=Color(r, g, b, a);
+ } return;
+ default:{ r_dst = c<0.5 ? a : b; } return;
+ }
+}
+
void Variant::interpolate(const Variant& a, const Variant& b, float c,Variant &r_dst) {
if (a.type!=b.type) {
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 3efa87de80..8bd1fddfad 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -338,6 +338,8 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
exp_beg=true;
} else if ((c=='-' || c=='+') && !exp_sign && !exp_beg) {
+ if (c=='-')
+ is_float=true;
exp_sign=true;
} else {
@@ -358,6 +360,7 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
r_token.type=TK_NUMBER;
+
if (is_float)
r_token.value=num.to_double();
else
@@ -448,7 +451,7 @@ Error VariantParser::_parse_construct(Stream *p_stream,Vector<T>& r_construct,in
if (!first) {
get_token(p_stream,token,line,r_err_str);
if (token.type==TK_COMMA) {
- //do none
+ //do none
} else if (token.type==TK_PARENTHESIS_CLOSE) {
break;
} else {
@@ -542,7 +545,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
value=true;
else if (id=="false")
value=false;
- else if (id=="null")
+ else if (id=="null" || id=="nil")
value=Variant();
else if (id=="Vector2"){
@@ -1203,7 +1206,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_STRING) {
- r_err_str="Expected string";
+ r_err_str="Expected string";
return ERR_PARSE_ERROR;
}
@@ -1282,7 +1285,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
arr.resize(len);
DVector<Color>::Write w = arr.write();
for(int i=0;i<len;i++) {
- w[i]=Color(args[i*3+0],args[i*3+1],args[i*3+2],args[i*3+3]);
+ w[i]=Color(args[i*4+0],args[i*4+1],args[i*4+2],args[i*4+3]);
}
}
@@ -1673,7 +1676,7 @@ Error VariantParser::_parse_tag(Token& token, Stream *p_stream, int &line, Strin
if (err)
return err;
- r_tag.fields[id]=value;
+ r_tag.fields[id]=value;
}
diff --git a/core/vector.h b/core/vector.h
index 641721f401..16a09c1ddd 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -43,39 +43,54 @@ template<class T>
class Vector {
mutable T* _ptr;
-
+
// internal helpers
-
+
_FORCE_INLINE_ SafeRefCount* _get_refcount() const {
-
+
if (!_ptr)
return NULL;
-
+
return reinterpret_cast<SafeRefCount*>((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount));
}
-
+
_FORCE_INLINE_ int* _get_size() const {
-
+
if (!_ptr)
return NULL;
return reinterpret_cast<int*>((uint8_t*)_ptr-sizeof(int));
-
+
}
_FORCE_INLINE_ T* _get_data() const {
-
+
if (!_ptr)
return NULL;
return reinterpret_cast<T*>(_ptr);
-
- }
-
- _FORCE_INLINE_ int _get_alloc_size(int p_elements) const {
-
- return nearest_power_of_2(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+
}
-
+
+ _FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
+ return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+ }
+
+ _FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
+#if defined(_add_overflow) && defined(_mul_overflow)
+ size_t o;
+ size_t p;
+ if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
+ if (_add_overflow(o, sizeof(SafeRefCount)+sizeof(int), &p)) return false;
+ *out = nearest_power_of_2_templated(p);
+ return true;
+#else
+ // Speed is more important than correctness here, do the operations unchecked
+ // and hope the best
+ *out = _get_alloc_size(p_elements);
+ return true;
+#endif
+ }
+
void _unref(void *p_data);
-
+
void _copy_from(const Vector& p_from);
void _copy_on_write();
public:
@@ -86,18 +101,18 @@ public:
_FORCE_INLINE_ void clear() { resize(0); }
-
+
_FORCE_INLINE_ int size() const {
int* size = _get_size();
if (size)
return *size;
- else
+ else
return 0;
}
_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
Error resize(int p_size);
bool push_back(T p_elem);
-
+
void remove(int p_index);
void erase(const T& p_val) { int idx = find(p_val); if (idx>=0) remove(idx); };
void invert();
@@ -117,7 +132,7 @@ public:
}
_copy_on_write(); // wants to write, so copy on write.
-
+
return _get_data()[p_index];
}
@@ -130,7 +145,7 @@ public:
// no cow needed, since it's reading
return _get_data()[p_index];
}
-
+
Error insert(int p_pos,const T& p_val);
template<class C>
@@ -173,21 +188,21 @@ void Vector<T>::_unref(void *p_data) {
if (!p_data)
return;
-
+
SafeRefCount *src = reinterpret_cast<SafeRefCount*>((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
-
+
if (!src->unref())
return; // still in use
// clean up
-
+
int *count = (int*)(src+1);
T *data = (T*)(count+1);
-
+
for (int i=0;i<*count;i++) {
- // call destructors
+ // call destructors
data[i].~T();
}
-
+
// free mem
memfree((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
@@ -198,7 +213,7 @@ void Vector<T>::_copy_on_write() {
if (!_ptr)
return;
-
+
if (_get_refcount()->get() > 1 ) {
/* in use by more than me */
void* mem_new = memalloc(_get_alloc_size(*_get_size()));
@@ -206,15 +221,15 @@ void Vector<T>::_copy_on_write() {
src_new->init();
int * _size = (int*)(src_new+1);
*_size=*_get_size();
-
+
T*_data=(T*)(_size+1);
-
+
// initialize new elements
for (int i=0;i<*_size;i++) {
-
+
memnew_placement(&_data[i], T( _get_data()[i] ) );
}
-
+
_unref(_ptr);
_ptr=_data;
}
@@ -225,11 +240,11 @@ template<class T> template<class T_val>
int Vector<T>::find(const T_val &p_val) const {
int ret = -1;
- if (size() == 0)
+ if (size() == 0)
return ret;
-
+
for (int i=0; i<size(); i++) {
-
+
if (operator[](i) == p_val) {
ret = i;
break;
@@ -246,46 +261,48 @@ Error Vector<T>::resize(int p_size) {
if (p_size==size())
return OK;
-
+
if (p_size==0) {
- // wants to clean up
+ // wants to clean up
_unref(_ptr);
_ptr=NULL;
return OK;
}
-
+
// possibly changing size, copy on write
_copy_on_write();
-
+
+ size_t alloc_size;
+ ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
+
if (p_size>size()) {
if (size()==0) {
// alloc from scratch
- void* ptr=memalloc(_get_alloc_size(p_size));
+ void* ptr=memalloc(alloc_size);
ERR_FAIL_COND_V( !ptr ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)ptr+sizeof(int)+sizeof(SafeRefCount));
_get_refcount()->init(); // init refcount
*_get_size()=0; // init size (currently, none)
} else {
-
- void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
+ void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount), alloc_size);
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
}
// construct the newly created elements
T*elems = _get_data();
-
+
for (int i=*_get_size();i<p_size;i++) {
-
+
memnew_placement(&elems[i], T) ;
}
*_get_size()=p_size;
} else if (p_size<size()) {
-
+
// deinitialize no longer needed elements
for (int i=p_size;i<*_get_size();i++) {
@@ -293,13 +310,13 @@ Error Vector<T>::resize(int p_size) {
t->~T();
}
- void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
+ void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount), alloc_size);
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
-
+
_ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
-
+
*_get_size()=p_size;
-
+
}
return OK;
@@ -308,9 +325,9 @@ Error Vector<T>::resize(int p_size) {
template<class T>
void Vector<T>::invert() {
-
+
for(int i=0;i<size()/2;i++) {
-
+
SWAP( operator[](i), operator[](size()-i-1) );
}
}
@@ -357,13 +374,13 @@ void Vector<T>::_copy_from(const Vector& p_from) {
if (_ptr == p_from._ptr)
return; // self assign, do nothing.
-
+
_unref(_ptr);
_ptr=NULL;
-
+
if (!p_from._ptr)
return; //nothing to do
-
+
if (p_from._get_refcount()->ref()) // could reference
_ptr=p_from._ptr;
@@ -378,13 +395,13 @@ void Vector<T>::operator=(const Vector& p_from) {
template<class T>
Error Vector<T>::insert(int p_pos,const T& p_val) {
-
+
ERR_FAIL_INDEX_V(p_pos,size()+1,ERR_INVALID_PARAMETER);
resize(size()+1);
for (int i=(size()-1);i>p_pos;i--)
set( i, get(i-1) );
set( p_pos, p_val );
-
+
return OK;
}
diff --git a/demos/2d/normalmaps/diffuse.jpg b/demos/2d/normalmaps/diffuse.jpg
index 87bc9cf158..b6f32fd825 100644
--- a/demos/2d/normalmaps/diffuse.jpg
+++ b/demos/2d/normalmaps/diffuse.jpg
Binary files differ
diff --git a/demos/2d/normalmaps/diffuse.png b/demos/2d/normalmaps/diffuse.png
deleted file mode 100644
index 634d955f8d..0000000000
--- a/demos/2d/normalmaps/diffuse.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/normalmaps/normal.jpg b/demos/2d/normalmaps/normal.jpg
new file mode 100644
index 0000000000..848ee9a9cd
--- /dev/null
+++ b/demos/2d/normalmaps/normal.jpg
Binary files differ
diff --git a/demos/2d/normalmaps/normal.png b/demos/2d/normalmaps/normal.png
deleted file mode 100644
index d5b3d53a24..0000000000
--- a/demos/2d/normalmaps/normal.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/normalmaps/normal_material.res b/demos/2d/normalmaps/normal_material.res
index 34129cccdc..27928519f8 100644
--- a/demos/2d/normalmaps/normal_material.res
+++ b/demos/2d/normalmaps/normal_material.res
Binary files differ
diff --git a/demos/2d/normalmaps/normalmap.scn b/demos/2d/normalmaps/normalmap.scn
index cf5fc05ce1..4501e7116a 100644
--- a/demos/2d/normalmaps/normalmap.scn
+++ b/demos/2d/normalmaps/normalmap.scn
Binary files differ
diff --git a/demos/2d/platformer/stage.xml b/demos/2d/platformer/stage.xml
index 3b5d281551..ea0daf3ff8 100644
--- a/demos/2d/platformer/stage.xml
+++ b/demos/2d/platformer/stage.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<resource_file type="PackedScene" subresource_count="10" version="2.0" version_name="Godot Engine v2.0.alpha.custom_build">
- <ext_resource path="res://tileset.xml" type="TileSet" index="0"></ext_resource>
+<resource_file type="PackedScene" subresource_count="10" version="2.0" version_name="Godot Engine v2.0.beta.custom_build">
<ext_resource path="res://music.ogg" type="AudioStream" index="6"></ext_resource>
+ <ext_resource path="res://tileset.xml" type="TileSet" index="0"></ext_resource>
<ext_resource path="res://coin.xml" type="PackedScene" index="1"></ext_resource>
- <ext_resource path="res://one_way_platform.xml" type="PackedScene" index="4"></ext_resource>
<ext_resource path="res://moving_platform.xml" type="PackedScene" index="2"></ext_resource>
- <ext_resource path="res://enemy.xml" type="PackedScene" index="7"></ext_resource>
- <ext_resource path="res://seesaw.xml" type="PackedScene" index="3"></ext_resource>
+ <ext_resource path="res://one_way_platform.xml" type="PackedScene" index="4"></ext_resource>
<ext_resource path="res://player.xml" type="PackedScene" index="5"></ext_resource>
+ <ext_resource path="res://seesaw.xml" type="PackedScene" index="3"></ext_resource>
+ <ext_resource path="res://enemy.xml" type="PackedScene" index="7"></ext_resource>
<ext_resource path="res://parallax_bg.xml" type="PackedScene" index="8"></ext_resource>
<main_resource>
<dictionary name="_bundled" shared="false">
@@ -19,7 +19,7 @@
<array len="0" shared="false">
</array>
<string> "names" </string>
- <string_array len="112">
+ <string_array len="110">
<string> "stage" </string>
<string> "__meta__" </string>
<string> "Node" </string>
@@ -37,14 +37,13 @@
<string> "collision/bounce" </string>
<string> "collision/layers" </string>
<string> "collision/mask" </string>
+ <string> "occluder/light_mask" </string>
<string> "tile_data" </string>
<string> "TileMap" </string>
<string> "coins" </string>
<string> "coin" </string>
<string> "transform/pos" </string>
- <string> "input/pickable" </string>
<string> "linear_damp" </string>
- <string> "angular_damp" </string>
<string> "coin 2" </string>
<string> "coin 3" </string>
<string> "coin 4" </string>
@@ -118,7 +117,6 @@
<string> "enemy 14" </string>
<string> "enemy 15" </string>
<string> "parallax_bg" </string>
- <string> "scroll/ignore_camera_zoom" </string>
<string> "Label" </string>
<string> "margin/left" </string>
<string> "margin/top" </string>
@@ -139,144 +137,12 @@
<array len="0" shared="false">
</array>
<string> "nodes" </string>
- <int_array len="925"> -1, -1, 2, 0, -1, 1, 1, 0, 0, 0, 0, 18, 3, -1, 15, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 1, 11, 7, 12, 7, 13, 8, 14, 9, 15, 10, 16, 10, 17, 11, 1, 12, 0, 0, 0, 2, 19, -1, 0, 0, 2, 0, 2147483647, 20, 13, 4, 21, 14, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 25, 13, 4, 21, 17, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 26, 13, 4, 21, 18, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 27, 13, 4, 21, 19, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 28, 13, 4, 21, 20, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 29, 13, 4, 21, 21, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 30, 13, 4, 21, 22, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 31, 13, 4, 21, 23, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 32, 13, 4, 21, 24, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 33, 13, 4, 21, 25, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 34, 13, 4, 21, 26, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 35, 13, 4, 21, 27, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 36, 13, 4, 21, 28, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 37, 13, 4, 21, 29, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 38, 13, 4, 21, 30, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 39, 13, 4, 21, 31, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 40, 13, 4, 21, 32, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 41, 13, 4, 21, 33, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 42, 13, 4, 21, 34, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 43, 13, 4, 21, 35, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 44, 13, 4, 21, 36, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 45, 13, 4, 21, 37, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 46, 13, 4, 21, 38, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 47, 13, 4, 21, 39, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 48, 13, 4, 21, 40, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 49, 13, 4, 21, 41, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 50, 13, 4, 21, 42, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 51, 13, 4, 21, 43, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 52, 13, 4, 21, 44, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 53, 13, 4, 21, 45, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 54, 13, 4, 21, 46, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 55, 13, 4, 21, 47, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 56, 13, 4, 21, 48, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 57, 13, 4, 21, 49, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 58, 13, 4, 21, 50, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 59, 13, 4, 21, 51, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 60, 13, 4, 21, 52, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 61, 13, 4, 21, 53, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 62, 13, 4, 21, 54, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 63, 13, 4, 21, 55, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 64, 13, 4, 21, 56, 22, 15, 23, 16, 24, 8, 0, 2, 0, 2147483647, 65, 13, 4, 21, 57, 22, 15, 23, 16, 24, 8, 0, 0, 0, 2, 66, -1, 0, 0, 45, 0, 2147483647, 67, 58, 3, 21, 59, 68, 60, 69, 61, 0, 45, 0, 2147483647, 70, 58, 3, 21, 62, 68, 63, 69, 64, 0, 45, 0, 2147483647, 71, 58, 3, 21, 65, 68, 66, 69, 64, 0, 45, 0, 2147483647, 72, 67, 1, 21, 68, 0, 45, 0, 2147483647, 73, 69, 1, 21, 70, 0, 0, 0, 2147483647, 74, 71, 1, 21, 72, 0, 0, 0, 84, 75, -1, 8, 76, 73, 77, 7, 78, 15, 79, 74, 80, 15, 81, 7, 82, 9, 83, 75, 0, 0, 0, 2, 85, -1, 0, 0, 53, 0, 2147483647, 86, 76, 1, 21, 77, 0, 53, 0, 2147483647, 87, 76, 1, 21, 78, 0, 53, 0, 2147483647, 88, 76, 1, 21, 79, 0, 53, 0, 2147483647, 89, 76, 1, 21, 80, 0, 53, 0, 2147483647, 90, 76, 1, 21, 81, 0, 53, 0, 2147483647, 91, 76, 1, 21, 82, 0, 53, 0, 2147483647, 92, 76, 1, 21, 83, 0, 53, 0, 2147483647, 93, 76, 1, 21, 84, 0, 53, 0, 2147483647, 94, 76, 1, 21, 85, 0, 53, 0, 2147483647, 95, 76, 1, 21, 86, 0, 53, 0, 2147483647, 96, 76, 1, 21, 87, 0, 0, 0, 2147483647, 97, 88, 1, 98, 7, 0, 0, 0, 99, 99, -1, 12, 100, 89, 101, 90, 102, 91, 103, 92, 104, 15, 105, 15, 106, 6, 107, 93, 108, 15, 109, 8, 110, 1, 111, 94, 0 </int_array>
+ <int_array len="757"> -1, -1, 2, 0, -1, 1, 1, 0, 0, 0, 0, 19, 3, -1, 16, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 1, 11, 7, 12, 7, 13, 8, 14, 9, 15, 10, 16, 10, 17, 10, 18, 11, 1, 12, 0, 0, 0, 2, 20, -1, 0, 0, 2, 0, 2147483647, 21, 13, 2, 22, 14, 23, 15, 0, 2, 0, 2147483647, 24, 13, 2, 22, 16, 23, 15, 0, 2, 0, 2147483647, 25, 13, 2, 22, 17, 23, 15, 0, 2, 0, 2147483647, 26, 13, 2, 22, 18, 23, 15, 0, 2, 0, 2147483647, 27, 13, 2, 22, 19, 23, 15, 0, 2, 0, 2147483647, 28, 13, 2, 22, 20, 23, 15, 0, 2, 0, 2147483647, 29, 13, 2, 22, 21, 23, 15, 0, 2, 0, 2147483647, 30, 13, 2, 22, 22, 23, 15, 0, 2, 0, 2147483647, 31, 13, 2, 22, 23, 23, 15, 0, 2, 0, 2147483647, 32, 13, 2, 22, 24, 23, 15, 0, 2, 0, 2147483647, 33, 13, 2, 22, 25, 23, 15, 0, 2, 0, 2147483647, 34, 13, 2, 22, 26, 23, 15, 0, 2, 0, 2147483647, 35, 13, 2, 22, 27, 23, 15, 0, 2, 0, 2147483647, 36, 13, 2, 22, 28, 23, 15, 0, 2, 0, 2147483647, 37, 13, 2, 22, 29, 23, 15, 0, 2, 0, 2147483647, 38, 13, 2, 22, 30, 23, 15, 0, 2, 0, 2147483647, 39, 13, 2, 22, 31, 23, 15, 0, 2, 0, 2147483647, 40, 13, 2, 22, 32, 23, 15, 0, 2, 0, 2147483647, 41, 13, 2, 22, 33, 23, 15, 0, 2, 0, 2147483647, 42, 13, 2, 22, 34, 23, 15, 0, 2, 0, 2147483647, 43, 13, 2, 22, 35, 23, 15, 0, 2, 0, 2147483647, 44, 13, 2, 22, 36, 23, 15, 0, 2, 0, 2147483647, 45, 13, 2, 22, 37, 23, 15, 0, 2, 0, 2147483647, 46, 13, 2, 22, 38, 23, 15, 0, 2, 0, 2147483647, 47, 13, 2, 22, 39, 23, 15, 0, 2, 0, 2147483647, 48, 13, 2, 22, 40, 23, 15, 0, 2, 0, 2147483647, 49, 13, 2, 22, 41, 23, 15, 0, 2, 0, 2147483647, 50, 13, 2, 22, 42, 23, 15, 0, 2, 0, 2147483647, 51, 13, 2, 22, 43, 23, 15, 0, 2, 0, 2147483647, 52, 13, 2, 22, 44, 23, 15, 0, 2, 0, 2147483647, 53, 13, 2, 22, 45, 23, 15, 0, 2, 0, 2147483647, 54, 13, 2, 22, 46, 23, 15, 0, 2, 0, 2147483647, 55, 13, 2, 22, 47, 23, 15, 0, 2, 0, 2147483647, 56, 13, 2, 22, 48, 23, 15, 0, 2, 0, 2147483647, 57, 13, 2, 22, 49, 23, 15, 0, 2, 0, 2147483647, 58, 13, 2, 22, 50, 23, 15, 0, 2, 0, 2147483647, 59, 13, 2, 22, 51, 23, 15, 0, 2, 0, 2147483647, 60, 13, 2, 22, 52, 23, 15, 0, 2, 0, 2147483647, 61, 13, 2, 22, 53, 23, 15, 0, 2, 0, 2147483647, 62, 13, 2, 22, 54, 23, 15, 0, 2, 0, 2147483647, 63, 13, 2, 22, 55, 23, 15, 0, 2, 0, 2147483647, 64, 13, 2, 22, 56, 23, 15, 0, 0, 0, 2, 65, -1, 0, 0, 45, 0, 2147483647, 66, 57, 3, 22, 58, 67, 59, 68, 60, 0, 45, 0, 2147483647, 69, 57, 3, 22, 61, 67, 62, 68, 63, 0, 45, 0, 2147483647, 70, 57, 3, 22, 64, 67, 65, 68, 63, 0, 45, 0, 2147483647, 71, 66, 1, 22, 67, 0, 45, 0, 2147483647, 72, 68, 1, 22, 69, 0, 0, 0, 2147483647, 73, 70, 1, 22, 71, 0, 0, 0, 83, 74, -1, 8, 75, 72, 76, 7, 77, 73, 78, 74, 79, 73, 80, 7, 81, 9, 82, 75, 0, 0, 0, 2, 84, -1, 0, 0, 53, 0, 2147483647, 85, 76, 1, 22, 77, 0, 53, 0, 2147483647, 86, 76, 1, 22, 78, 0, 53, 0, 2147483647, 87, 76, 1, 22, 79, 0, 53, 0, 2147483647, 88, 76, 1, 22, 80, 0, 53, 0, 2147483647, 89, 76, 1, 22, 81, 0, 53, 0, 2147483647, 90, 76, 1, 22, 82, 0, 53, 0, 2147483647, 91, 76, 1, 22, 83, 0, 53, 0, 2147483647, 92, 76, 1, 22, 84, 0, 53, 0, 2147483647, 93, 76, 1, 22, 85, 0, 53, 0, 2147483647, 94, 76, 1, 22, 86, 0, 53, 0, 2147483647, 95, 76, 1, 22, 87, 0, 0, 0, 2147483647, 96, 88, 0, 0, 0, 0, 97, 97, -1, 12, 98, 89, 99, 90, 100, 91, 101, 92, 102, 73, 103, 73, 104, 6, 105, 93, 106, 73, 107, 8, 108, 1, 109, 94, 0 </int_array>
<string> "variants" </string>
<array len="95" shared="false">
<dictionary shared="false">
<string> "__editor_plugin_screen__" </string>
- <string> "Script" </string>
- <string> "__editor_plugin_states__" </string>
- <dictionary shared="false">
- <string> "2D" </string>
- <dictionary shared="false">
- <string> "ofs" </string>
- <vector2> -70.6559, 735.599 </vector2>
- <string> "snap_grid" </string>
- <bool> False </bool>
- <string> "snap_offset" </string>
- <vector2> 0, 0 </vector2>
- <string> "snap_pixel" </string>
- <bool> False </bool>
- <string> "snap_relative" </string>
- <bool> False </bool>
- <string> "snap_rotation" </string>
- <bool> False </bool>
- <string> "snap_rotation_offset" </string>
- <real> 0 </real>
- <string> "snap_rotation_step" </string>
- <real> 0.261799 </real>
- <string> "snap_show_grid" </string>
- <bool> False </bool>
- <string> "snap_step" </string>
- <vector2> 10, 10 </vector2>
- <string> "zoom" </string>
- <real> 0.663419 </real>
- </dictionary>
- <string> "3D" </string>
- <dictionary shared="false">
- <string> "ambient_light_color" </string>
- <color> 0.15, 0.15, 0.15, 1 </color>
- <string> "default_light" </string>
- <bool> True </bool>
- <string> "default_srgb" </string>
- <bool> False </bool>
- <string> "deflight_rot_x" </string>
- <real> 0.942478 </real>
- <string> "deflight_rot_y" </string>
- <real> 0.628319 </real>
- <string> "fov" </string>
- <real> 45 </real>
- <string> "show_grid" </string>
- <bool> True </bool>
- <string> "show_origin" </string>
- <bool> True </bool>
- <string> "viewport_mode" </string>
- <int> 1 </int>
- <string> "viewports" </string>
- <array len="4" shared="false">
- <dictionary shared="false">
- <string> "distance" </string>
- <real> 18.643827 </real>
- <string> "listener" </string>
- <bool> True </bool>
- <string> "pos" </string>
- <vector3> 0, 0, 0 </vector3>
- <string> "use_environment" </string>
- <bool> False </bool>
- <string> "use_orthogonal" </string>
- <bool> False </bool>
- <string> "x_rot" </string>
- <real> 0 </real>
- <string> "y_rot" </string>
- <real> 0 </real>
- </dictionary>
- <dictionary shared="false">
- <string> "distance" </string>
- <real> 4 </real>
- <string> "listener" </string>
- <bool> False </bool>
- <string> "pos" </string>
- <vector3> 0, 0, 0 </vector3>
- <string> "use_environment" </string>
- <bool> False </bool>
- <string> "use_orthogonal" </string>
- <bool> False </bool>
- <string> "x_rot" </string>
- <real> 0 </real>
- <string> "y_rot" </string>
- <real> 0 </real>
- </dictionary>
- <dictionary shared="false">
- <string> "distance" </string>
- <real> 4 </real>
- <string> "listener" </string>
- <bool> False </bool>
- <string> "pos" </string>
- <vector3> 0, 0, 0 </vector3>
- <string> "use_environment" </string>
- <bool> False </bool>
- <string> "use_orthogonal" </string>
- <bool> False </bool>
- <string> "x_rot" </string>
- <real> 0 </real>
- <string> "y_rot" </string>
- <real> 0 </real>
- </dictionary>
- <dictionary shared="false">
- <string> "distance" </string>
- <real> 4 </real>
- <string> "listener" </string>
- <bool> False </bool>
- <string> "pos" </string>
- <vector3> 0, 0, 0 </vector3>
- <string> "use_environment" </string>
- <bool> False </bool>
- <string> "use_orthogonal" </string>
- <bool> False </bool>
- <string> "x_rot" </string>
- <real> 0 </real>
- <string> "y_rot" </string>
- <real> 0 </real>
- </dictionary>
- </array>
- <string> "zfar" </string>
- <real> 500 </real>
- <string> "znear" </string>
- <real> 0.1 </real>
- </dictionary>
- <string> "Anim" </string>
- <dictionary shared="false">
- <string> "visible" </string>
- <bool> False </bool>
- </dictionary>
- </dictionary>
- <string> "__editor_run_settings__" </string>
- <dictionary shared="false">
- <string> "custom_args" </string>
- <string> "-l $scene" </string>
- <string> "run_mode" </string>
- <int> 0 </int>
- </dictionary>
+ <string> "2D" </string>
</dictionary>
<int> 0 </int>
<resource external="0"> </resource>
@@ -288,14 +154,13 @@
<real> 1 </real>
<real> 0 </real>
<int> 1 </int>
- <int_array len="2008"> 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 0, 983052, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870914, 1048587, 536870922, 1048588, 2, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114122, 536870925, 1114123, 11, 1114124, 13, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179663, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 0, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 </int_array>
+ <int_array len="2008"> 0, 2, 70, 536870914, 71, 10, 72, 10, 73, 10, 74, 10, 75, 10, 76, 10, 77, 10, 78, 10, 65536, 2, 65606, 536870914, 65607, 10, 65608, 10, 65609, 10, 65610, 10, 65611, 10, 65612, 10, 65613, 10, 65614, 10, 131072, 2, 131142, 536870914, 131143, 10, 131144, 10, 131145, 10, 131146, 10, 131147, 10, 131148, 10, 131149, 10, 131150, 10, 196608, 2, 196626, 9, 196678, 536870914, 196679, 10, 196680, 10, 196681, 10, 196682, 10, 196683, 10, 196684, 10, 196685, 10, 196686, 10, 262144, 2, 262162, 8, 262214, 536870914, 262215, 10, 262216, 10, 262217, 10, 262218, 10, 262219, 10, 262220, 10, 262221, 10, 262222, 10, 327680, 2, 327697, 536870921, 327698, 7, 327733, 9, 327750, 536870914, 327751, 10, 327752, 10, 327753, 10, 327754, 10, 327755, 10, 327756, 10, 327757, 10, 327758, 10, 393216, 2, 393233, 536870920, 393234, 7, 393257, 9, 393269, 7, 393286, 536870914, 393287, 10, 393288, 10, 393289, 10, 393290, 10, 393291, 10, 393292, 10, 393293, 10, 393294, 10, 458752, 2, 458769, 7, 458770, 8, 458790, 9, 458793, 8, 458805, 8, 458822, 536870914, 458823, 10, 458824, 10, 458825, 10, 458826, 10, 458827, 10, 458828, 10, 458829, 10, 458830, 10, 524288, 4, 524289, 1, 524304, 536870913, 524305, 536870918, 524306, 6, 524307, 5, 524308, 1, 524326, 8, 524329, 7, 524341, 7, 524358, 536870914, 524359, 10, 524360, 10, 524361, 10, 524362, 10, 524363, 10, 524364, 10, 524365, 10, 524366, 10, 589824, 10, 589825, 13, 589840, 536870914, 589841, 10, 589842, 10, 589843, 10, 589844, 2, 589862, 7, 589865, 7, 589876, 536870913, 589877, 6, 589878, 1, 589894, 536870914, 589895, 10, 589896, 10, 589897, 10, 589898, 10, 589899, 10, 589900, 10, 589901, 10, 589902, 10, 655360, 2, 655376, 536870914, 655377, 10, 655378, 10, 655379, 10, 655380, 2, 655398, 7, 655401, 8, 655412, 536870925, 655413, 11, 655414, 13, 655430, 536870914, 655431, 10, 655432, 10, 655433, 10, 655434, 10, 655435, 10, 655436, 10, 655437, 10, 655438, 10, 720896, 2, 720912, 536870914, 720913, 10, 720914, 10, 720915, 10, 720916, 2, 720934, 8, 720937, 7, 720958, 536870913, 720959, 5, 720960, 536870917, 720961, 5, 720962, 5, 720963, 536870917, 720964, 5, 720965, 0, 720966, 536870916, 720967, 10, 720968, 10, 720969, 10, 720970, 10, 720971, 10, 720972, 10, 720973, 10, 720974, 10, 786432, 2, 786437, 9, 786448, 536870914, 786449, 10, 786450, 10, 786451, 10, 786452, 2, 786464, 536870913, 786465, 1, 786470, 7, 786473, 7, 786474, 536870924, 786475, 1, 786494, 536870914, 786495, 10, 786496, 10, 786497, 10, 786498, 10, 786499, 10, 786500, 10, 786501, 10, 786502, 10, 786503, 10, 786504, 10, 786505, 10, 786506, 10, 786507, 10, 786508, 10, 786509, 10, 851968, 2, 851973, 7, 851984, 536870914, 851985, 10, 851986, 10, 851987, 10, 851988, 2, 851996, 536870913, 851997, 1, 852000, 536870914, 852001, 3, 852006, 7, 852009, 536870913, 852011, 2, 852030, 536870914, 852031, 10, 852032, 10, 852033, 10, 852034, 10, 852035, 10, 852036, 10, 852037, 10, 852038, 10, 852039, 10, 852040, 10, 852041, 10, 852042, 10, 852043, 10, 852044, 10, 852045, 10, 917504, 2, 917506, 9, 917509, 7, 917512, 536870921, 917520, 536870925, 917521, 11, 917522, 11, 917523, 11, 917524, 13, 917532, 536870925, 917533, 13, 917536, 536870914, 917537, 4, 917538, 1, 917540, 536870913, 917541, 0, 917542, 1, 917545, 536870914, 917546, 10, 917547, 4, 917548, 1, 917566, 536870914, 917567, 10, 917568, 10, 917569, 10, 917570, 10, 917571, 10, 917572, 10, 917573, 10, 917574, 10, 917575, 10, 917576, 10, 917577, 10, 917578, 10, 917579, 10, 917580, 10, 917581, 10, 983040, 2, 983042, 7, 983045, 7, 983048, 536870920, 983050, 536870913, 983051, 0, 983052, 1, 983064, 536870913, 983065, 1, 983072, 536870914, 983073, 10, 983074, 4, 983075, 0, 983076, 536870916, 983077, 10, 983078, 4, 983079, 536870912, 983080, 536870912, 983081, 536870916, 983082, 10, 983083, 10, 983084, 2, 983095, 9, 983102, 536870914, 983103, 10, 983104, 10, 983105, 10, 983106, 10, 983107, 10, 983108, 10, 983109, 10, 983110, 10, 983111, 10, 983112, 10, 983113, 10, 983114, 10, 983115, 10, 983116, 10, 983117, 10, 1048576, 2, 1048578, 8, 1048581, 8, 1048584, 536870919, 1048586, 536870914, 1048587, 536870922, 1048588, 2, 1048600, 536870925, 1048601, 13, 1048604, 9, 1048608, 536870925, 1048609, 536870923, 1048610, 536870923, 1048611, 536870923, 1048612, 10, 1048613, 10, 1048614, 10, 1048615, 10, 1048616, 10, 1048617, 10, 1048618, 10, 1048619, 10, 1048620, 4, 1048621, 1, 1048630, 536870921, 1048631, 8, 1048638, 536870914, 1048639, 10, 1048640, 10, 1048641, 10, 1048642, 10, 1048643, 10, 1048644, 10, 1048645, 10, 1048646, 10, 1048647, 10, 1048648, 10, 1048649, 10, 1048650, 10, 1048651, 10, 1048652, 10, 1048653, 10, 1114112, 4, 1114113, 0, 1114114, 6, 1114115, 0, 1114116, 0, 1114117, 6, 1114118, 1, 1114120, 536870920, 1114122, 536870925, 1114123, 11, 1114124, 13, 1114128, 536870913, 1114129, 5, 1114130, 536870917, 1114131, 5, 1114132, 0, 1114133, 1, 1114140, 7, 1114141, 536870921, 1114148, 536870914, 1114149, 10, 1114150, 10, 1114151, 10, 1114152, 10, 1114153, 10, 1114154, 10, 1114155, 10, 1114156, 10, 1114157, 2, 1114166, 536870920, 1114167, 8, 1114174, 536870914, 1114175, 10, 1114176, 10, 1114177, 10, 1114178, 10, 1114179, 10, 1114180, 10, 1114181, 10, 1114182, 10, 1114183, 10, 1114184, 10, 1114185, 10, 1114186, 10, 1114187, 10, 1114188, 10, 1179648, 10, 1179649, 10, 1179650, 10, 1179651, 10, 1179652, 10, 1179653, 10, 1179654, 2, 1179656, 536870919, 1179664, 536870915, 1179665, 10, 1179666, 10, 1179667, 10, 1179668, 10, 1179669, 4, 1179670, 12, 1179675, 9, 1179676, 8, 1179677, 8, 1179684, 536870914, 1179685, 10, 1179686, 10, 1179687, 10, 1179688, 10, 1179689, 10, 1179690, 10, 1179691, 10, 1179692, 10, 1179693, 4, 1179694, 1, 1179701, 9, 1179702, 536870919, 1179703, 7, 1179710, 536870914, 1179711, 10, 1179712, 10, 1179713, 10, 1179714, 10, 1179715, 10, 1179716, 10, 1179717, 10, 1179718, 10, 1179719, 10, 1179720, 10, 1179721, 10, 1179722, 10, 1245184, 10, 1245185, 10, 1245186, 10, 1245187, 10, 1245188, 10, 1245189, 10, 1245190, 2, 1245192, 536870919, 1245199, 536870913, 1245200, 536870916, 1245201, 10, 1245202, 10, 1245203, 10, 1245204, 10, 1245205, 10, 1245207, 1, 1245211, 7, 1245212, 7, 1245213, 536870920, 1245220, 536870914, 1245221, 10, 1245222, 10, 1245223, 10, 1245224, 10, 1245225, 10, 1245226, 10, 1245227, 10, 1245228, 10, 1245229, 10, 1245230, 2, 1245237, 8, 1245238, 536870919, 1245239, 8, 1245240, 536870921, 1245246, 536870914, 1245247, 10, 1245248, 10, 1245249, 10, 1245250, 10, 1245251, 10, 1245252, 10, 1245253, 10, 1245254, 10, 1245255, 10, 1245256, 10, 1245257, 10, 1245258, 10, 1310720, 10, 1310721, 10, 1310722, 10, 1310723, 10, 1310724, 10, 1310725, 10, 1310726, 2, 1310728, 536870920, 1310730, 536870913, 1310731, 1, 1310734, 536870913, 1310735, 536870916, 1310736, 10, 1310737, 10, 1310738, 10, 1310739, 10, 1310740, 10, 1310741, 10, 1310742, 10, 1310743, 4, 1310744, 1, 1310747, 8, 1310748, 7, 1310749, 536870919, 1310756, 536870914, 1310757, 10, 1310758, 10, 1310759, 10, 1310760, 10, 1310761, 10, 1310762, 10, 1310763, 10, 1310764, 10, 1310765, 10, 1310766, 4, 1310767, 5, 1310768, 12, 1310773, 7, 1310774, 536870919, 1310775, 7, 1310776, 536870919, 1310782, 536870914, 1310783, 10, 1310784, 10, 1310785, 10, 1310786, 10, 1310787, 10, 1310788, 10, 1310789, 10, 1310790, 10, 1310791, 10, 1310792, 10, 1310793, 10, 1376256, 10, 1376257, 10, 1376258, 10, 1376259, 10, 1376260, 10, 1376261, 10, 1376262, 4, 1376263, 0, 1376264, 0, 1376265, 0, 1376266, 536870916, 1376267, 4, 1376268, 0, 1376269, 0, 1376270, 536870916, 1376271, 10, 1376272, 10, 1376273, 10, 1376274, 10, 1376275, 10, 1376276, 10, 1376277, 10, 1376278, 10, 1376279, 10, 1376280, 4, 1376281, 12, 1376283, 8, 1376284, 8, 1376285, 536870920, 1376287, 536870924, 1376288, 0, 1376289, 5, 1376290, 536870917, 1376291, 0, 1376292, 536870916, 1376293, 10, 1376294, 10, 1376295, 10, 1376296, 10, 1376297, 10, 1376298, 10, 1376299, 10, 1376300, 10, 1376301, 10, 1376302, 10, 1376303, 10, 1376305, 12, 1376309, 7, 1376310, 536870920, 1376311, 7, 1376312, 536870920, 1376318, 536870914, 1376319, 10, 1376320, 10, 1376321, 10, 1376322, 10, 1376323, 10, 1376324, 10, 1376325, 10, 1376326, 10, 1376327, 10, 1376328, 10, 1441792, 10, 1441793, 10, 1441794, 10, 1441795, 10, 1441796, 10, 1441797, 10, 1441798, 10, 1441799, 10, 1441800, 10, 1441801, 10, 1441802, 10, 1441803, 10, 1441804, 10, 1441805, 10, 1441806, 10, 1441807, 10, 1441808, 10, 1441809, 10, 1441810, 10, 1441811, 10, 1441812, 10, 1441813, 10, 1441814, 10, 1441815, 10, 1441816, 10, 1441818, 0, 1441819, 6, 1441820, 6, 1441821, 536870918, 1441822, 5, 1441824, 10, 1441825, 10, 1441826, 10, 1441827, 10, 1441828, 10, 1441829, 10, 1441830, 10, 1441831, 10, 1441832, 10, 1441833, 10, 1441834, 10, 1441835, 10, 1441836, 10, 1441837, 10, 1441838, 10, 1441839, 10, 1441840, 10, 1441842, 0, 1441843, 0, 1441844, 0, 1441845, 6, 1441846, 536870918, 1441847, 6, 1441848, 536870918, 1441849, 0, 1441850, 5, 1441851, 536870917, 1441852, 5, 1441853, 0, 1441854, 536870916, 1441855, 10, 1441856, 10, 1441857, 10, 1441858, 10, 1441859, 10, 1441860, 10, 1441861, 10, 1441862, 10, 1441863, 10, 1507328, 10, 1507329, 10, 1507330, 10, 1507331, 10, 1507332, 10, 1507333, 10, 1507334, 10, 1507335, 10, 1507336, 10, 1507337, 10, 1507338, 10, 1507339, 10, 1507340, 10, 1507341, 10, 1507342, 10, 1507343, 10, 1507344, 10, 1507345, 10, 1507346, 10, 1507347, 10, 1507348, 10, 1507349, 10, 1507350, 10, 1507351, 10, 1507352, 10, 1507353, 10, 1507354, 10, 1507355, 10, 1507356, 10, 1507357, 10, 1507358, 10, 1507359, 10, 1507360, 10, 1507361, 10, 1507362, 10, 1507363, 10, 1507364, 10, 1507365, 10, 1507366, 10, 1507367, 10, 1507368, 10, 1507369, 10, 1507370, 10, 1507371, 10, 1507372, 10, 1507373, 10, 1507374, 10, 1507375, 10, 1507376, 10, 1507377, 10, 1507378, 10, 1507379, 10, 1507380, 10, 1507381, 10, 1507382, 10, 1507383, 10, 1507384, 10, 1507385, 10, 1507386, 10, 1507387, 10, 1507388, 10, 1507389, 10, 1507390, 10, 1507391, 10, 1507392, 10, 1507393, 10, 1507394, 10, 1507395, 10, 1507396, 10, 1507397, 10, 1507398, 10, 1507399, 10, 1572864, 10, 1572865, 10, 1572866, 10, 1572867, 10, 1572868, 10, 1572869, 10, 1572870, 10, 1572871, 10, 1572872, 10, 1572873, 10, 1572874, 10, 1572875, 10, 1572876, 10, 1572877, 10, 1572878, 10, 1572879, 10, 1572880, 10, 1572881, 10, 1572882, 10, 1572883, 10, 1572884, 10, 1572885, 10, 1572886, 10, 1572887, 10, 1572888, 10, 1572889, 10, 1572890, 10, 1572891, 10, 1572892, 10, 1572893, 10, 1572894, 10, 1572895, 10, 1572896, 10, 1572897, 10, 1572898, 10, 1572899, 10, 1572900, 10, 1572901, 10, 1572902, 10, 1572903, 10, 1572904, 10, 1572905, 10, 1572906, 10, 1572907, 10, 1572908, 10, 1572909, 10, 1572910, 10, 1572911, 10, 1572912, 10, 1572913, 10, 1572914, 10, 1572915, 10, 1572916, 10, 1572917, 10, 1572918, 10, 1572919, 10, 1572920, 10, 1572921, 10, 1572922, 10, 1572923, 10, 1572924, 10, 1572925, 10, 1572926, 10, 1572927, 10, 1572928, 10, 1572929, 10, 1572930, 10, 1572931, 10, 1572932, 10, 1572933, 10, 1572934, 10, 1572935, 10, 1638400, 10, 1638401, 10, 1638402, 10, 1638403, 10, 1638404, 10, 1638405, 10, 1638406, 10, 1638407, 10, 1638408, 10, 1638409, 10, 1638410, 10, 1638411, 10, 1638412, 10, 1638413, 10, 1638414, 10, 1638415, 10, 1638416, 10, 1638417, 10, 1638418, 10, 1638419, 10, 1638420, 10, 1638421, 10, 1638422, 10, 1638423, 10, 1638424, 10, 1638425, 10, 1638426, 10, 1638427, 10, 1638428, 10, 1638429, 10, 1638430, 10, 1638431, 10, 1638432, 10, 1638433, 10, 1638434, 10, 1638435, 10, 1638436, 10, 1638437, 10, 1638438, 10, 1638439, 10, 1638440, 10, 1638441, 10, 1638442, 10, 1638443, 10, 1638444, 10, 1638445, 10, 1638446, 10, 1638447, 10, 1638448, 10, 1638449, 10, 1638450, 10, 1638451, 10, 1638452, 10, 1638453, 10, 1638454, 10, 1638455, 10, 1638456, 10, 1638457, 10, 1638458, 10, 1638459, 10, 1638460, 10, 1638461, 10, 1638462, 10, 1638463, 10, 1638464, 10, 1638465, 10, 1638466, 10, 1638467, 10, 1638468, 10, 1638469, 10, 1638470, 10, 1638471, 10, 1703952, 10, 1703953, 10, 1703954, 10, 1703955, 10, 1703956, 10, 1703957, 10, 1703958, 10, 1703959, 10, 1703960, 10, 1703961, 10, 1703962, 10, 1703963, 10, 1703964, 10, 1703965, 10, 1703966, 10, 1703967, 10, 1703968, 10, 1703969, 10, 1703970, 10, 1703971, 10, 1703972, 10, 1703973, 10, 1703974, 10, 1703975, 10, 1703976, 10, 1703977, 10, 1703978, 10, 1703979, 10, 1703980, 10, 1703981, 10, 1703982, 10, 1703983, 10, 1703984, 10, 1703985, 10, 1703986, 10, 1703987, 10, 1703988, 10, 1703989, 10, 1703990, 10, 1703991, 10, 1703992, 10, 1703993, 10, 1703994, 10, 1703995, 10, 1703996, 10, 1703997, 10, 1703998, 10, 1703999, 10, 1704000, 10, 1704001, 10, 1704002, 10, 1704003, 10, 1704004, 10, 1704005, 10, 1704006, 10, 1704007, 10, 1769488, 10, 1769489, 10, 1769490, 10, 1769491, 10, 1769492, 10, 1769493, 10, 1769494, 10, 1769495, 10, 1769496, 10, 1769497, 10, 1769498, 10, 1769499, 10, 1769500, 10, 1769501, 10, 1769502, 10, 1769503, 10, 1769504, 10, 1769505, 10, 1769506, 10, 1769507, 10, 1769508, 10, 1769509, 10, 1769510, 10, 1769511, 10, 1769512, 10, 1769513, 10, 1769514, 10, 1769515, 10, 1769516, 10, 1769517, 10, 1769518, 10, 1769519, 10, 1769520, 10, 1769521, 10, 1769522, 10, 1769523, 10, 1769524, 10, 1769525, 10, 1769526, 10, 1769527, 10, 1769528, 10, 1769529, 10, 1769530, 10, 1769531, 10, 1769532, 10, 1769533, 10, 1769534, 10, 1769535, 10, 1769536, 10, 1769537, 10, 1769538, 10, 1769539, 10, 1769540, 10, 1769541, 10 </int_array>
<dictionary shared="false">
<string> "_edit_lock_" </string>
<bool> True </bool>
</dictionary>
<resource external="1"> </resource>
<vector2> 672, 1179 </vector2>
- <bool> True </bool>
<real> 0.1 </real>
<vector2> 704, 1179 </vector2>
<vector2> 736, 1179 </vector2>
@@ -354,6 +219,7 @@
<resource external="5"> </resource>
<vector2> 251.684, 1045.6 </vector2>
<resource external="6"> </resource>
+ <bool> True </bool>
<real> 2 </real>
<int> 500 </int>
<resource external="7"> </resource>
diff --git a/demos/2d/screen_space_shaders/art/burano.jpg b/demos/2d/screen_space_shaders/art/burano.jpg
index cdab993ec1..3017616384 100644
--- a/demos/2d/screen_space_shaders/art/burano.jpg
+++ b/demos/2d/screen_space_shaders/art/burano.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/burano.png b/demos/2d/screen_space_shaders/art/burano.png
deleted file mode 100644
index 6eec09d585..0000000000
--- a/demos/2d/screen_space_shaders/art/burano.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/forest.jpg b/demos/2d/screen_space_shaders/art/forest.jpg
new file mode 100644
index 0000000000..705acf8a5d
--- /dev/null
+++ b/demos/2d/screen_space_shaders/art/forest.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/forest.png b/demos/2d/screen_space_shaders/art/forest.png
deleted file mode 100644
index f5a2fb9bfb..0000000000
--- a/demos/2d/screen_space_shaders/art/forest.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/mountains.jpg b/demos/2d/screen_space_shaders/art/mountains.jpg
new file mode 100644
index 0000000000..d75baf530c
--- /dev/null
+++ b/demos/2d/screen_space_shaders/art/mountains.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/mountains.png b/demos/2d/screen_space_shaders/art/mountains.png
deleted file mode 100644
index b8435bb1a8..0000000000
--- a/demos/2d/screen_space_shaders/art/mountains.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/platformer.jpg b/demos/2d/screen_space_shaders/art/platformer.jpg
new file mode 100644
index 0000000000..e6197cd62b
--- /dev/null
+++ b/demos/2d/screen_space_shaders/art/platformer.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/platformer.png b/demos/2d/screen_space_shaders/art/platformer.png
deleted file mode 100644
index 21c1cb4c4b..0000000000
--- a/demos/2d/screen_space_shaders/art/platformer.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/engine.cfg b/demos/2d/screen_space_shaders/engine.cfg
index 383ca7bf11..f7caa7abbc 100644
--- a/demos/2d/screen_space_shaders/engine.cfg
+++ b/demos/2d/screen_space_shaders/engine.cfg
@@ -6,7 +6,7 @@ icon="res://icon.png"
[display]
-width=780
+width=800
height=600
stretch_mode="2d"
stretch_aspect="keep"
diff --git a/demos/2d/screen_space_shaders/screen_shaders.scn b/demos/2d/screen_space_shaders/screen_shaders.scn
index be12cef02d..00c7fe8eba 100644
--- a/demos/2d/screen_space_shaders/screen_shaders.scn
+++ b/demos/2d/screen_space_shaders/screen_shaders.scn
Binary files differ
diff --git a/demos/3d/polygon_path_finder/engine.cfg b/demos/3d/polygon_path_finder/engine.cfg
deleted file mode 100644
index 47450408af..0000000000
--- a/demos/3d/polygon_path_finder/engine.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[application]
-
-name="Polygon Pathfinder"
-main_scene="res://poly_with_holes.scn"
-icon="res://icon.png"
diff --git a/demos/3d/polygon_path_finder/icon.png b/demos/3d/polygon_path_finder/icon.png
deleted file mode 100644
index 643f5595ee..0000000000
--- a/demos/3d/polygon_path_finder/icon.png
+++ /dev/null
Binary files differ
diff --git a/demos/3d/polygon_path_finder/poly_with_holes.scn b/demos/3d/polygon_path_finder/poly_with_holes.scn
deleted file mode 100644
index 6b340377b7..0000000000
--- a/demos/3d/polygon_path_finder/poly_with_holes.scn
+++ /dev/null
Binary files differ
diff --git a/demos/3d/polygon_path_finder/polygonpathfinder.gd b/demos/3d/polygon_path_finder/polygonpathfinder.gd
deleted file mode 100644
index 1e843043da..0000000000
--- a/demos/3d/polygon_path_finder/polygonpathfinder.gd
+++ /dev/null
@@ -1,77 +0,0 @@
-
-extends Spatial
-
-
-func _ready():
- var pf = PolygonPathFinder.new()
-
- var points = Vector2Array()
- var connections = IntArray()
-
- # Poly 1
- points.push_back(Vector2(0, 0)) # 0
- points.push_back(Vector2(10, 0)) # 1
- points.push_back(Vector2(10, 10)) # 2
- points.push_back(Vector2(0, 10)) # 3
-
- connections.push_back(0) # Connect vertex 0...
- connections.push_back(1) # ... to 1
- drawLine(points[0], points[1], get_node("/root/Spatial/Polys"))
- connections.push_back(1) # Connect vertex 1...
- connections.push_back(2) # ... to 2
- drawLine(points[1], points[2], get_node("/root/Spatial/Polys"))
- connections.push_back(2) # Etc.
- connections.push_back(3)
- drawLine(points[2], points[3], get_node("/root/Spatial/Polys"))
- connections.push_back(3) # Connect vertex 3...
- connections.push_back(0) # ... back to vertex 0, to close the polygon
- drawLine(points[3], points[0], get_node("/root/Spatial/Polys"))
-
- # Poly 2, as obstacle inside poly 1
- points.push_back(Vector2(2, 0.5)) # 4
- points.push_back(Vector2(4, 0.5)) # 5
- points.push_back(Vector2(4, 9.5)) # 6
- points.push_back(Vector2(2, 9.5)) # 7
-
- connections.push_back(4)
- connections.push_back(5)
- drawLine(points[4], points[5], get_node("/root/Spatial/Polys"))
- connections.push_back(5)
- connections.push_back(6)
- drawLine(points[5], points[6], get_node("/root/Spatial/Polys"))
- connections.push_back(6)
- connections.push_back(7)
- drawLine(points[6], points[7], get_node("/root/Spatial/Polys"))
- connections.push_back(7)
- connections.push_back(4)
- drawLine(points[7], points[4], get_node("/root/Spatial/Polys"))
-
- print("points: ", points)
- print("connections: ", connections)
-
- pf.setup(points, connections)
-
- var path = pf.find_path(Vector2(1, 5), Vector2(8, 5))
-
- var lastStep = null
- print("path: ", path)
- for step in path:
- print("step: ", step)
- if (lastStep != null):
- var currPathSegment = Vector2Array()
- drawLine(lastStep, step, get_node("/root/Spatial/Path"))
- lastStep = step
-
-
-func drawLine(pointA, pointB, immediateGeo):
- var drawPosY = 0.1
- var im = immediateGeo
-
- im.begin(Mesh.PRIMITIVE_POINTS, null)
- im.add_vertex(Vector3(pointA.x, drawPosY, pointA.y))
- im.add_vertex(Vector3(pointB.x, drawPosY, pointB.y))
- im.end()
- im.begin(Mesh.PRIMITIVE_LINE_STRIP, null)
- im.add_vertex(Vector3(pointA.x, drawPosY, pointA.y))
- im.add_vertex(Vector3(pointB.x, drawPosY, pointB.y))
- im.end()
diff --git a/demos/gui/translation/main.scn b/demos/gui/translation/main.scn
index 8fc0b4ffb2..be833fcdb8 100644
--- a/demos/gui/translation/main.scn
+++ b/demos/gui/translation/main.scn
Binary files differ
diff --git a/demos/gui/translation/notosans.otf b/demos/gui/translation/notosans.otf
deleted file mode 100644
index 6443f9023e..0000000000
--- a/demos/gui/translation/notosans.otf
+++ /dev/null
Binary files differ
diff --git a/demos/plugins/custom_dock/custom_dock.scn b/demos/plugins/custom_dock/custom_dock.scn
new file mode 100644
index 0000000000..0e32ece264
--- /dev/null
+++ b/demos/plugins/custom_dock/custom_dock.scn
Binary files differ
diff --git a/demos/plugins/custom_dock/dock_plugin.gd b/demos/plugins/custom_dock/dock_plugin.gd
new file mode 100644
index 0000000000..ce8a3bcd09
--- /dev/null
+++ b/demos/plugins/custom_dock/dock_plugin.gd
@@ -0,0 +1,23 @@
+tool
+extends EditorPlugin
+
+var dock = null
+
+func _enter_tree():
+ # When this plugin node enters tree, add the custom type
+
+ dock = preload("res://addons/custom_dock/custom_dock.scn").instance()
+
+ add_control_to_dock( DOCK_SLOT_LEFT_UL, dock )
+
+func _exit_tree():
+
+ # Remove from docks (must be called so layout is updated and saved)
+ remove_control_from_docks(dock)
+ # Remove the node
+ dock.free()
+
+
+
+
+ \ No newline at end of file
diff --git a/demos/plugins/custom_dock/plugin.cfg b/demos/plugins/custom_dock/plugin.cfg
new file mode 100644
index 0000000000..e295384c25
--- /dev/null
+++ b/demos/plugins/custom_dock/plugin.cfg
@@ -0,0 +1,14 @@
+[plugin]
+
+name="Custom Dock"
+description="Adds a new Customizable Dock"
+author="Juan Linietsky"
+version="1.0"
+script="dock_plugin.gd"
+
+
+
+
+
+
+
diff --git a/demos/plugins/custom_import_plugin/import_plugin.gd b/demos/plugins/custom_import_plugin/import_plugin.gd
new file mode 100644
index 0000000000..2cf8a0302f
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/import_plugin.gd
@@ -0,0 +1,81 @@
+tool
+
+extends EditorImportPlugin
+
+
+# Simple plugin that imports a text file with extension .mtxt
+# which contains 3 integers in format R,G,B (0-255)
+# (see example .mtxt in this folder)
+# Imported file is converted to a material
+
+var dialog = null
+
+func get_name():
+ return "silly_material"
+
+func get_visible_name():
+ return "Silly Material"
+
+func import_dialog(path):
+ var md = null
+ if (path!=""):
+ md = ResourceLoader.load_import_metadata(path)
+ dialog.configure(self,path,md)
+ dialog.popup_centered()
+
+func import(path,metadata):
+
+ assert(metadata.get_source_count() == 1)
+
+ var source = metadata.get_source_path(0)
+ var use_red_anyway = metadata.get_option("use_red_anyway")
+
+ var f = File.new()
+ var err = f.open(source,File.READ)
+ if (err!=OK):
+ return ERR_CANT_OPEN
+
+ var l = f.get_line()
+
+ f.close()
+
+ var channels = l.split(",")
+ if (channels.size()!=3):
+ return ERR_PARSE_ERROR
+
+ var color = Color8(int(channels[0]),int(channels[1]),int(channels[2]))
+
+ var material
+
+ if (ResourceLoader.has(path)):
+ # Material is in use, update it
+ material = ResourceLoader.load(path)
+ else:
+ # Material not in use, create
+ material = FixedMaterial.new()
+
+ if (use_red_anyway):
+ color=Color8(255,0,0)
+
+ material.set_parameter(FixedMaterial.PARAM_DIFFUSE,color)
+
+ # Make sure import metadata links to this plugin
+
+ metadata.set_editor("silly_material")
+
+ # Update the import metadata
+
+ material.set_import_metadata(metadata)
+
+
+ # Save
+ err = ResourceSaver.save(path,material)
+
+ return err
+
+
+func config(base_control):
+
+ dialog = preload("res://addons/custom_import_plugin/material_dialog.tscn").instance()
+ base_control.add_child(dialog)
+
diff --git a/demos/plugins/custom_import_plugin/material_dialog.gd b/demos/plugins/custom_import_plugin/material_dialog.gd
new file mode 100644
index 0000000000..1022743254
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/material_dialog.gd
@@ -0,0 +1,67 @@
+tool
+extends ConfirmationDialog
+
+var src_fs
+var dst_fs
+var import_plugin
+
+func configure(p_import_plugin,path,metadata):
+ import_plugin=p_import_plugin
+ if (metadata):
+ # metadata from previous import exists, fill in fields
+ assert( metadata.get_source_count() > 0 )
+ # Always expand the source paths
+ var src_path = import_plugin.expand_source_path( metadata.get_source_path(0) )
+ get_node("src_file").set_text(src_path)
+ get_node("dst_file").set_text(path)
+ # Fill in from metadata options
+ get_node("use_red_anyway").set_pressed( metadata.get_option("use_red_anyway") )
+
+
+func _ready():
+
+ src_fs = FileDialog.new()
+ src_fs.set_mode(FileDialog.MODE_OPEN_FILE)
+ src_fs.set_access(FileDialog.ACCESS_FILESYSTEM) #access all filesystem, not only res://
+ src_fs.add_filter("*.mtxt")
+ src_fs.connect("file_selected",self,"_on_src_selected")
+
+ add_child(src_fs)
+
+ dst_fs = EditorFileDialog.new()
+ dst_fs.set_mode(EditorFileDialog.MODE_SAVE_FILE)
+ dst_fs.add_filter("*.mtl") # Use binary extension always, text can't save metadata
+ dst_fs.connect("file_selected",self,"_on_dst_selected")
+
+ add_child(dst_fs)
+
+ set_hide_on_ok(true)
+ get_ok().set_text("Import!")
+
+
+func _on_src_browse_pressed():
+ src_fs.popup_centered_ratio()
+
+func _on_dst_browse_pressed():
+ dst_fs.popup_centered_ratio()
+
+func _on_src_selected(path):
+ get_node("src_file").set_text(path)
+
+func _on_dst_selected(path):
+ get_node("dst_file").set_text(path)
+
+func _on_MaterialImport_confirmed():
+ # Create an import metadata
+ var imd = ResourceImportMetadata.new()
+ # Add the source files, always validate the source path
+ imd.add_source( import_plugin.validate_source_path( get_node("src_file").get_text() ))
+ # Add the options
+ imd.set_option( "use_red_anyway", get_node("use_red_anyway").is_pressed() )
+ # Perform regular import
+ var err = import_plugin.import( get_node("dst_file").get_text(), imd )
+ # Warn if error
+ if (err!=OK):
+ get_node("error").set_text("Error Importing!")
+ get_node("error").popup_centered_minsize()
+
diff --git a/demos/plugins/custom_import_plugin/material_dialog.tscn b/demos/plugins/custom_import_plugin/material_dialog.tscn
new file mode 100644
index 0000000000..9ad6f492fd
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/material_dialog.tscn
@@ -0,0 +1,111 @@
+[gd_scene load_steps=2 format=1]
+
+[ext_resource path="res://addons/custom_import_plugin/material_dialog.gd" type="Script" id=1]
+
+[node name="MaterialImport" type="ConfirmationDialog"]
+
+margin/right = 276.0
+margin/bottom = 154.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+popup/exclusive = false
+window/title = "Silly Material Import"
+dialog/hide_on_ok = true
+script/script = ExtResource( 1 )
+__meta__ = { "__editor_plugin_screen__":"Script" }
+
+[node name="src_file" type="LineEdit" parent="."]
+
+margin/left = 19.0
+margin/top = 6.0
+margin/right = 190.0
+margin/bottom = 29.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+text = ""
+max_length = 0
+editable = true
+secret = false
+
+[node name="src_browse" type="Button" parent="."]
+
+margin/left = 195.0
+margin/top = 7.0
+margin/right = 249.0
+margin/bottom = 29.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+toggle_mode = false
+text = "browse"
+flat = false
+
+[node name="dst_browse" type="Button" parent="."]
+
+margin/left = 195.0
+margin/top = 47.0
+margin/right = 249.0
+margin/bottom = 69.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+toggle_mode = false
+text = "browse"
+flat = false
+
+[node name="dst_file" type="LineEdit" parent="."]
+
+margin/left = 19.0
+margin/top = 46.0
+margin/right = 190.0
+margin/bottom = 69.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+text = ""
+max_length = 0
+editable = true
+secret = false
+
+[node name="use_red_anyway" type="CheckBox" parent="."]
+
+margin/left = 20.0
+margin/top = 84.0
+margin/right = 144.0
+margin/bottom = 106.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+toggle_mode = true
+text = "Use Red Anyway"
+flat = false
+align = 0
+
+[node name="error" type="AcceptDialog" parent="."]
+
+visibility/visible = false
+margin/right = 40.0
+margin/bottom = 40.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+popup/exclusive = false
+window/title = "Alert!"
+dialog/hide_on_ok = true
+
+[connection signal="confirmed" from="." to="." method="_on_MaterialImport_confirmed"]
+
+[connection signal="pressed" from="src_browse" to="." method="_on_src_browse_pressed"]
+
+[connection signal="pressed" from="dst_browse" to="." method="_on_dst_browse_pressed"]
+
+
diff --git a/demos/plugins/custom_import_plugin/material_import.gd b/demos/plugins/custom_import_plugin/material_import.gd
new file mode 100644
index 0000000000..f9859251af
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/material_import.gd
@@ -0,0 +1,22 @@
+tool
+extends EditorPlugin
+
+var import_plugin
+
+func _enter_tree():
+
+ import_plugin = preload("res://addons/custom_import_plugin/import_plugin.gd").new()
+
+ # pass the GUI base control, so the dialog has a parent node
+ import_plugin.config( get_base_control() )
+
+ add_import_plugin( import_plugin)
+
+func _exit_tree():
+
+ remove_import_plugin( import_plugin )
+
+
+
+
+ \ No newline at end of file
diff --git a/demos/plugins/custom_import_plugin/plugin.cfg b/demos/plugins/custom_import_plugin/plugin.cfg
new file mode 100644
index 0000000000..a002ad680d
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/plugin.cfg
@@ -0,0 +1,14 @@
+[plugin]
+
+name="Silly Material Importer"
+description="Imports a 3D Material from an external text file"
+author="Juan Linietsky"
+version="1.0"
+script="material_import.gd"
+
+
+
+
+
+
+
diff --git a/demos/plugins/custom_import_plugin/test.mtxt b/demos/plugins/custom_import_plugin/test.mtxt
new file mode 100644
index 0000000000..546ea2af20
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/test.mtxt
@@ -0,0 +1 @@
+0,0,255
diff --git a/demos/plugins/custom_node/heart.gd b/demos/plugins/custom_node/heart.gd
new file mode 100644
index 0000000000..d53c92d800
--- /dev/null
+++ b/demos/plugins/custom_node/heart.gd
@@ -0,0 +1,12 @@
+tool
+extends Node2D
+
+
+var heart = preload("res://addons/custom_node/heart.png")
+
+func _draw():
+ draw_texture(heart,-heart.get_size()/2)
+
+func _get_item_rect():
+ #override
+ return Rect2(-heart.get_size()/2,heart.get_size())
diff --git a/demos/plugins/custom_node/heart.png b/demos/plugins/custom_node/heart.png
new file mode 100644
index 0000000000..1dfd14a456
--- /dev/null
+++ b/demos/plugins/custom_node/heart.png
Binary files differ
diff --git a/demos/plugins/custom_node/heart_icon.png b/demos/plugins/custom_node/heart_icon.png
new file mode 100644
index 0000000000..2eb819aa24
--- /dev/null
+++ b/demos/plugins/custom_node/heart_icon.png
Binary files differ
diff --git a/demos/plugins/custom_node/heart_plugin.gd b/demos/plugins/custom_node/heart_plugin.gd
new file mode 100644
index 0000000000..01a6177c9b
--- /dev/null
+++ b/demos/plugins/custom_node/heart_plugin.gd
@@ -0,0 +1,18 @@
+tool
+extends EditorPlugin
+
+
+func _enter_tree():
+ # When this plugin node enters tree, add the custom type
+
+ add_custom_type("Heart","Node2D",preload("res://addons/custom_node/heart.gd"),preload("res://addons/custom_node/heart_icon.png"))
+
+func _exit_tree():
+ # When the plugin node exits the tree, remove the custom type
+
+ remove_custom_type("Heart")
+
+
+
+
+ \ No newline at end of file
diff --git a/demos/plugins/custom_node/plugin.cfg b/demos/plugins/custom_node/plugin.cfg
new file mode 100644
index 0000000000..ebb4b56499
--- /dev/null
+++ b/demos/plugins/custom_node/plugin.cfg
@@ -0,0 +1,14 @@
+[plugin]
+
+name="Heart"
+description="Adds a new Heart node in 2D"
+author="Juan Linietsky"
+version="1.0"
+script="heart_plugin.gd"
+
+
+
+
+
+
+
diff --git a/demos/plugins/readme.txt b/demos/plugins/readme.txt
new file mode 100644
index 0000000000..963850dcbb
--- /dev/null
+++ b/demos/plugins/readme.txt
@@ -0,0 +1,13 @@
+
+To install these, copy each of these folders to a folder:
+
+addons/
+
+inside your projects, example:
+
+addons/custom_node
+
+To distribute and install from UI, make a zip that contains the folder,
+example:
+
+zip -r custom_node.zip custom_node/* \ No newline at end of file
diff --git a/doc/Makefile b/doc/Makefile
index 286a5162af..d59c77063b 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -38,7 +38,7 @@ rst:
rm -rf $(OUTPUTDIR)/rst
mkdir -p $(OUTPUTDIR)/rst
pushd $(OUTPUTDIR)/rst
- echo "TODO"
+ python2 $(TOOLSDIR)/makerst.py $(CLASSES)
popd
textile:
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index e642430636..bc8bec4bbf 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<doc version="2.0.beta.custom_build" name="Engine Types">
+<doc version="2.0.stable.custom_build" name="Engine Types">
<class name="@GDScript" category="Core">
<brief_description>
Built-in GDScript functions.
@@ -97,7 +97,7 @@
<argument index="1" name="y" type="float">
</argument>
<description>
- Arc-tangent that takes a 2D vector as argument, retuns the full -pi to +pi range.
+ Arc-tangent that takes a 2D vector as argument, returns the full -pi to +pi range.
</description>
</method>
<method name="sqrt">
@@ -318,6 +318,7 @@
<argument index="0" name="seed" type="float">
</argument>
<description>
+ Set seed for the random number generator.
</description>
</method>
<method name="rand_seed">
@@ -344,7 +345,7 @@
<argument index="0" name="rad" type="float">
</argument>
<description>
- Convert from radias to degrees.
+ Convert from radians to degrees.
</description>
</method>
<method name="linear2db">
@@ -426,7 +427,7 @@
<argument index="1" name="funcname" type="String">
</argument>
<description>
- Returns a reference to the specified function
+ Return a reference to the specified function.
</description>
</method>
<method name="convert">
@@ -446,7 +447,7 @@
<argument index="0" name="what" type="Variant">
</argument>
<description>
- Returns the internal type of the given Variant object, using the TYPE_* enum in [@Global Scope].
+ Return the internal type of the given Variant object, using the TYPE_* enum in [@Global Scope].
</description>
</method>
<method name="str">
@@ -490,6 +491,7 @@
<argument index="1" name="..." type="Variant">
</argument>
<description>
+ Print one or more arguments to the console with a space between each argument.
</description>
</method>
<method name="printerr">
@@ -520,7 +522,7 @@
<argument index="0" name="var" type="Variant">
</argument>
<description>
- Converts the value of a variable to a String.
+ Convert a value to a formatted string that can later be parsed using [method str2var].
</description>
</method>
<method name="str2var">
@@ -529,6 +531,7 @@
<argument index="0" name="string" type="String">
</argument>
<description>
+ Convert a formatted string that was returned by [method var2str] to the original value.
</description>
</method>
<method name="var2bytes">
@@ -537,6 +540,7 @@
<argument index="0" name="var" type="Variant">
</argument>
<description>
+ Encode a variable value to a byte array.
</description>
</method>
<method name="bytes2var">
@@ -545,6 +549,7 @@
<argument index="0" name="bytes" type="RawArray">
</argument>
<description>
+ Decode a byte array back to a value.
</description>
</method>
<method name="range">
@@ -553,7 +558,7 @@
<argument index="0" name="..." type="Variant">
</argument>
<description>
- Return an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial,final-1,increment).
+ Return an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial, final-1, increment).
</description>
</method>
<method name="load">
@@ -586,10 +591,10 @@
<method name="hash">
<return type="int">
</return>
- <argument index="0" name="var:Variant" type="Variant">
+ <argument index="0" name="Variant" type="Variant">
</argument>
<description>
- Hashes the variable passed and returns an integer.
+ Hash the variable passed and return an integer.
</description>
</method>
<method name="Color8">
@@ -604,6 +609,7 @@
<argument index="3" name="a8" type="int">
</argument>
<description>
+ Make a color from red, green, blue and alpha. Arguments can range from 0 to 255.
</description>
</method>
<method name="print_stack">
@@ -619,6 +625,38 @@
<argument index="0" name="instance_id" type="int">
</argument>
<description>
+ Get an object by its ID.
+ </description>
+ </method>
+ <method name="preload">
+ <return type="Resource">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ Preload a resource from the filesystem. The resource is loaded during script parsing.
+ </description>
+ </method>
+ <method name="yield">
+ <return type="Object">
+ </return>
+ <argument index="0" name="object" type="Object">
+ </argument>
+ <argument index="1" name="signal" type="String">
+ </argument>
+ <description>
+ Stop the function execution and return the current state. Call resume on the state to resume execution. This makes the state invalid.
+ Returns anything that was passed to the resume function call.
+ If passed an object and a signal, the execution is resumed when the object's signal is emmited.
+ </description>
+ </method>
+ <method name="assert">
+ <return type="Nil">
+ </return>
+ <argument index="0" name="condition" type="bool">
+ </argument>
+ <description>
+ Assert that the condition is true. If the condition is false, generates an error.
</description>
</method>
</methods>
@@ -681,9 +719,9 @@
</member>
<member name="PS2D" type="Physics2DServer">
</member>
- <member name="SpatialSoundServer" type="SpatialSound2DServer">
+ <member name="SpatialSoundServer" type="SpatialSoundServer">
</member>
- <member name="SS" type="SpatialSound2DServer">
+ <member name="SS" type="SpatialSoundServer">
</member>
<member name="SpatialSound2DServer" type="SpatialSound2DServer">
</member>
@@ -737,119 +775,172 @@
Tab Key
</constant>
<constant name="KEY_BACKTAB" value="16777219">
- Shift-Tab key
+ Shift-Tab Key
</constant>
<constant name="KEY_BACKSPACE" value="16777220">
+ Backspace Key
</constant>
<constant name="KEY_RETURN" value="16777221">
+ Return Key
</constant>
<constant name="KEY_ENTER" value="16777222">
+ Enter Key
</constant>
<constant name="KEY_INSERT" value="16777223">
+ Insert Key
</constant>
<constant name="KEY_DELETE" value="16777224">
+ Delete Key
</constant>
<constant name="KEY_PAUSE" value="16777225">
+ Pause Key
</constant>
<constant name="KEY_PRINT" value="16777226">
+ Printscreen Key
</constant>
<constant name="KEY_SYSREQ" value="16777227">
</constant>
<constant name="KEY_CLEAR" value="16777228">
</constant>
<constant name="KEY_HOME" value="16777229">
+ Home Key
</constant>
<constant name="KEY_END" value="16777230">
+ End Key
</constant>
<constant name="KEY_LEFT" value="16777231">
+ Left Arrow Key
</constant>
<constant name="KEY_UP" value="16777232">
+ Up Arrow Key
</constant>
<constant name="KEY_RIGHT" value="16777233">
+ Right Arrow Key
</constant>
<constant name="KEY_DOWN" value="16777234">
+ Down Arrow Key
</constant>
<constant name="KEY_PAGEUP" value="16777235">
+ Pageup Key
</constant>
<constant name="KEY_PAGEDOWN" value="16777236">
+ Pagedown Key
</constant>
<constant name="KEY_SHIFT" value="16777237">
+ Shift Key
</constant>
<constant name="KEY_CONTROL" value="16777238">
+ Control Key
</constant>
<constant name="KEY_META" value="16777239">
</constant>
<constant name="KEY_ALT" value="16777240">
+ Alt Key
</constant>
<constant name="KEY_CAPSLOCK" value="16777241">
+ Capslock Key
</constant>
<constant name="KEY_NUMLOCK" value="16777242">
+ Numlock Key
</constant>
<constant name="KEY_SCROLLLOCK" value="16777243">
+ Scrolllock Key
</constant>
<constant name="KEY_F1" value="16777244">
+ F1 Key
</constant>
<constant name="KEY_F2" value="16777245">
+ F2 Key
</constant>
<constant name="KEY_F3" value="16777246">
+ F3 Key
</constant>
<constant name="KEY_F4" value="16777247">
+ F4 Key
</constant>
<constant name="KEY_F5" value="16777248">
+ F5 Key
</constant>
<constant name="KEY_F6" value="16777249">
+ F6 Key
</constant>
<constant name="KEY_F7" value="16777250">
+ F7 Key
</constant>
<constant name="KEY_F8" value="16777251">
+ F8 Key
</constant>
<constant name="KEY_F9" value="16777252">
+ F9 Key
</constant>
<constant name="KEY_F10" value="16777253">
+ F10 Key
</constant>
<constant name="KEY_F11" value="16777254">
+ F11 Key
</constant>
<constant name="KEY_F12" value="16777255">
+ F12 Key
</constant>
<constant name="KEY_F13" value="16777256">
+ F13 Key
</constant>
<constant name="KEY_F14" value="16777257">
+ F14 Key
</constant>
<constant name="KEY_F15" value="16777258">
+ F15 Key
</constant>
<constant name="KEY_F16" value="16777259">
+ F16 Key
</constant>
<constant name="KEY_KP_ENTER" value="16777344">
+ Enter Key on Numpad
</constant>
<constant name="KEY_KP_MULTIPLY" value="16777345">
+ Multiply Key on Numpad
</constant>
<constant name="KEY_KP_DIVIDE" value="16777346">
+ Divide Key on Numpad
</constant>
- <constant name="KEY_KP_SUBSTRACT" value="16777347">
+ <constant name="KEY_KP_SUBTRACT" value="16777347">
+ Subtract Key on Numpad
</constant>
<constant name="KEY_KP_PERIOD" value="16777348">
+ Period Key on Numpad
</constant>
<constant name="KEY_KP_ADD" value="16777349">
+ Add Key on Numpad
</constant>
<constant name="KEY_KP_0" value="16777350">
+ Number 0 on Numpad
</constant>
<constant name="KEY_KP_1" value="16777351">
+ Number 1 on Numpad
</constant>
<constant name="KEY_KP_2" value="16777352">
+ Number 2 on Numpad
</constant>
<constant name="KEY_KP_3" value="16777353">
+ Number 3 on Numpad
</constant>
<constant name="KEY_KP_4" value="16777354">
+ Number 4 on Numpad
</constant>
<constant name="KEY_KP_5" value="16777355">
+ Number 5 on Numpad
</constant>
<constant name="KEY_KP_6" value="16777356">
+ Number 6 on Numpad
</constant>
<constant name="KEY_KP_7" value="16777357">
+ Number 7 on Numpad
</constant>
<constant name="KEY_KP_8" value="16777358">
+ Number 8 on Numpad
</constant>
<constant name="KEY_KP_9" value="16777359">
+ Number 9 on Numpad
</constant>
<constant name="KEY_SUPER_L" value="16777260">
</constant>
@@ -950,6 +1041,7 @@
<constant name="KEY_UNKNOWN" value="33554431">
</constant>
<constant name="KEY_SPACE" value="32">
+ Space Key
</constant>
<constant name="KEY_EXCLAM" value="33">
</constant>
@@ -982,24 +1074,34 @@
<constant name="KEY_SLASH" value="47">
</constant>
<constant name="KEY_0" value="48">
+ Number 0
</constant>
<constant name="KEY_1" value="49">
+ Number 1
</constant>
<constant name="KEY_2" value="50">
+ Number 2
</constant>
<constant name="KEY_3" value="51">
+ Number 3
</constant>
<constant name="KEY_4" value="52">
+ Number 4
</constant>
<constant name="KEY_5" value="53">
+ Number 5
</constant>
<constant name="KEY_6" value="54">
+ Number 6
</constant>
<constant name="KEY_7" value="55">
+ Number 7
</constant>
<constant name="KEY_8" value="56">
+ Number 8
</constant>
<constant name="KEY_9" value="57">
+ Number 9
</constant>
<constant name="KEY_COLON" value="58">
</constant>
@@ -1016,56 +1118,82 @@
<constant name="KEY_AT" value="64">
</constant>
<constant name="KEY_A" value="65">
+ A Key
</constant>
<constant name="KEY_B" value="66">
+ B Key
</constant>
<constant name="KEY_C" value="67">
+ C Key
</constant>
<constant name="KEY_D" value="68">
+ D Key
</constant>
<constant name="KEY_E" value="69">
+ E Key
</constant>
<constant name="KEY_F" value="70">
+ F Key
</constant>
<constant name="KEY_G" value="71">
+ G Key
</constant>
<constant name="KEY_H" value="72">
+ H Key
</constant>
<constant name="KEY_I" value="73">
+ I Key
</constant>
<constant name="KEY_J" value="74">
+ J Key
</constant>
<constant name="KEY_K" value="75">
+ K Key
</constant>
<constant name="KEY_L" value="76">
+ L Key
</constant>
<constant name="KEY_M" value="77">
+ M Key
</constant>
<constant name="KEY_N" value="78">
+ N Key
</constant>
<constant name="KEY_O" value="79">
+ O Key
</constant>
<constant name="KEY_P" value="80">
+ P Key
</constant>
<constant name="KEY_Q" value="81">
+ Q Key
</constant>
<constant name="KEY_R" value="82">
+ R Key
</constant>
<constant name="KEY_S" value="83">
+ S Key
</constant>
<constant name="KEY_T" value="84">
+ T Key
</constant>
<constant name="KEY_U" value="85">
+ U Key
</constant>
<constant name="KEY_V" value="86">
+ V Key
</constant>
<constant name="KEY_W" value="87">
+ W Key
</constant>
<constant name="KEY_X" value="88">
+ X Key
</constant>
<constant name="KEY_Y" value="89">
+ Y Key
</constant>
<constant name="KEY_Z" value="90">
+ Z Key
</constant>
<constant name="KEY_BRACKETLEFT" value="91">
</constant>
@@ -1238,15 +1366,22 @@
<constant name="KEY_MASK_GROUP_SWITCH" value="1073741824">
</constant>
<constant name="BUTTON_LEFT" value="1">
+ Left Mouse Button
</constant>
<constant name="BUTTON_RIGHT" value="2">
+ Right Mouse Button
</constant>
<constant name="BUTTON_MIDDLE" value="3">
+ Middle Mouse Button
</constant>
<constant name="BUTTON_WHEEL_UP" value="4">
</constant>
<constant name="BUTTON_WHEEL_DOWN" value="5">
</constant>
+ <constant name="BUTTON_WHEEL_LEFT" value="6">
+ </constant>
+ <constant name="BUTTON_WHEEL_RIGHT" value="7">
+ </constant>
<constant name="BUTTON_MASK_LEFT" value="1">
</constant>
<constant name="BUTTON_MASK_RIGHT" value="2">
@@ -1345,54 +1480,76 @@
<constant name="JOY_DS_Y" value="2">
</constant>
<constant name="JOY_SELECT" value="10">
+ Joystick Button Select
</constant>
<constant name="JOY_START" value="11">
+ Joystick Button Start
</constant>
<constant name="JOY_DPAD_UP" value="12">
+ Joystick DPad Up
</constant>
<constant name="JOY_DPAD_DOWN" value="13">
+ Joystick DPad Down
</constant>
<constant name="JOY_DPAD_LEFT" value="14">
+ Joystick DPad Left
</constant>
<constant name="JOY_DPAD_RIGHT" value="15">
+ Joystick DPad Right
</constant>
<constant name="JOY_L" value="4">
+ Joystick Left Shoulder Button
</constant>
<constant name="JOY_L2" value="6">
+ Joystick Left Trigger
</constant>
<constant name="JOY_L3" value="8">
+ Joystick Left Stick Click
</constant>
<constant name="JOY_R" value="5">
+ Joystick Right Shoulder Button
</constant>
<constant name="JOY_R2" value="7">
+ Joystick Right Trigger
</constant>
<constant name="JOY_R3" value="9">
+ Joystick Right Stick Click
</constant>
<constant name="JOY_AXIS_0" value="0">
+ Joystick Left Stick Horizontal Axis
</constant>
<constant name="JOY_AXIS_1" value="1">
+ Joystick Left Stick Vertical Axis
</constant>
<constant name="JOY_AXIS_2" value="2">
+ Joystick Right Stick Horizontal Axis
</constant>
<constant name="JOY_AXIS_3" value="3">
+ Joystick Right Stick Vertical Axis
</constant>
<constant name="JOY_AXIS_4" value="4">
</constant>
<constant name="JOY_AXIS_5" value="5">
</constant>
<constant name="JOY_AXIS_6" value="6">
+ Joystick Left Trigger Analog Axis
</constant>
<constant name="JOY_AXIS_7" value="7">
+ Joystick Right Trigger Analog Axis
</constant>
<constant name="JOY_AXIS_MAX" value="8">
</constant>
<constant name="JOY_ANALOG_0_X" value="0">
+ Joystick Left Stick Horizontal Axis
</constant>
<constant name="JOY_ANALOG_0_Y" value="1">
+ Joystick Left Stick Vertical Axis
</constant>
<constant name="JOY_ANALOG_1_X" value="2">
+ Joystick Right Stick Horizontal Axis
</constant>
<constant name="JOY_ANALOG_1_Y" value="3">
+ Joystick Right Stick Vertical Axis
</constant>
<constant name="JOY_ANALOG_2_X" value="4">
</constant>
@@ -1403,7 +1560,7 @@
<constant name="JOY_ANALOG_R2" value="7">
</constant>
<constant name="OK" value="0">
- Functions that return [Error] return OK when everything went ok. Most functions don't return error anyway and/or just print errors to stdout.
+ Functions that return Error return OK when everything went ok. Most functions don't return error anyway and/or just print errors to stdout.
</constant>
<constant name="FAILED" value="1">
Generic fail return error.
@@ -1446,6 +1603,8 @@
</constant>
<constant name="ERR_CANT_CREATE" value="20">
</constant>
+ <constant name="ERR_PARSE_ERROR" value="43">
+ </constant>
<constant name="ERROR_QUERY_FAILED" value="21">
</constant>
<constant name="ERR_ALREADY_IN_USE" value="22">
@@ -1534,9 +1693,6 @@
<constant name="PROPERTY_USAGE_STORAGE" value="1">
Property will be used as storage (default).
</constant>
- <constant name="PROPERTY_USAGE_STORAGE" value="1">
- Property will be used as storage (default).
- </constant>
<constant name="PROPERTY_USAGE_EDITOR" value="2">
Property will be visible in editor (default).
</constant>
@@ -1545,6 +1701,22 @@
<constant name="PROPERTY_USAGE_DEFAULT" value="7">
Default usage (storage and editor).
</constant>
+ <constant name="METHOD_FLAG_NORMAL" value="1">
+ </constant>
+ <constant name="METHOD_FLAG_EDITOR" value="2">
+ </constant>
+ <constant name="METHOD_FLAG_NOSCRIPT" value="4">
+ </constant>
+ <constant name="METHOD_FLAG_CONST" value="8">
+ </constant>
+ <constant name="METHOD_FLAG_REVERSE" value="16">
+ </constant>
+ <constant name="METHOD_FLAG_VIRTUAL" value="32">
+ </constant>
+ <constant name="METHOD_FLAG_FROM_SCRIPT" value="64">
+ </constant>
+ <constant name="METHOD_FLAGS_DEFAULT" value="1">
+ </constant>
<constant name="TYPE_NIL" value="0">
Variable is of type nil (only applied for null).
</constant>
@@ -1582,34 +1754,34 @@
Variable is of type [AABB].
</constant>
<constant name="TYPE_MATRIX3" value="12">
- Variable is fo type [Matrix3].
+ Variable is of type [Matrix3].
</constant>
<constant name="TYPE_TRANSFORM" value="13">
- Variable is fo type [Transform].
+ Variable is of type [Transform].
</constant>
<constant name="TYPE_COLOR" value="14">
- Variable is fo type [Color].
+ Variable is of type [Color].
</constant>
<constant name="TYPE_IMAGE" value="15">
- Variable is fo type [Image].
+ Variable is of type [Image].
</constant>
<constant name="TYPE_NODE_PATH" value="16">
- Variable is fo type [NodePath].
+ Variable is of type [NodePath].
</constant>
<constant name="TYPE_RID" value="17">
- Variable is fo type [RID].
+ Variable is of type [RID].
</constant>
<constant name="TYPE_OBJECT" value="18">
- Variable is fo type [Object].
+ Variable is of type [Object].
</constant>
<constant name="TYPE_INPUT_EVENT" value="19">
- Variable is fo type [InputEvent].
+ Variable is of type [InputEvent].
</constant>
<constant name="TYPE_DICTIONARY" value="20">
- Variable is fo type [Dictionary].
+ Variable is of type [Dictionary].
</constant>
<constant name="TYPE_ARRAY" value="21">
- Variable is fo type [Array].
+ Variable is of type [Array].
</constant>
<constant name="TYPE_RAW_ARRAY" value="22">
</constant>
@@ -1760,7 +1932,7 @@
<argument index="0" name="with" type="AABB">
</argument>
<description>
- Return the intersection between two [AABB]s. An empty AABB (size 0,0,0) is returned on failure.
+ Return the intersection between two [AABB]. An empty AABB (size 0,0,0) is returned on failure.
</description>
</method>
<method name="intersects">
@@ -1953,7 +2125,7 @@
<return type="bool">
</return>
<description>
- Return true when centered. See [set_centered].
+ Return true when centered. See [method set_centered].
</description>
</method>
<method name="set_offset">
@@ -2081,7 +2253,8 @@
Contains data used to animate everything in the engine.
</brief_description>
<description>
- An Animation resource contains data used to animate everything in the engine. Animations are divided into tracks, and each track must be linked to a node. The state of that node can be changed through time, by adding timed keys (events) to the track. [br] Animations are just data containers, and must be added to odes such as an [AnimationPlayer] or [AnimationTreePlayer] to be played back.
+ An Animation resource contains data used to animate everything in the engine. Animations are divided into tracks, and each track must be linked to a node. The state of that node can be changed through time, by adding timed keys (events) to the track.
+ Animations are just data containers, and must be added to odes such as an [AnimationPlayer] or [AnimationTreePlayer] to be played back.
</description>
<methods>
<method name="add_track">
@@ -2092,7 +2265,7 @@
<argument index="1" name="at_pos" type="int" default="-1">
</argument>
<description>
- Add a track to the Animation. The track type must be specified as any of the values in te TYPE_* enumeration.
+ Add a track to the Animation. The track type must be specified as any of the values in the TYPE_* enumeration.
</description>
</method>
<method name="remove_track">
@@ -2155,7 +2328,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Nove a track down.
+ Move a track down.
</description>
</method>
<method name="transform_track_insert_key">
@@ -2180,7 +2353,7 @@
</argument>
<argument index="1" name="time" type="float">
</argument>
- <argument index="2" name="key" type="var">
+ <argument index="2" name="key" type="Variant">
</argument>
<argument index="3" name="transition" type="float" default="1">
</argument>
@@ -2211,7 +2384,7 @@
</argument>
<argument index="1" name="key" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
Set the value of an existing key.
@@ -2325,7 +2498,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Return wether interpolation is enabled or disabled for a whole track. By default tracks are interpolated.
+ Return whether interpolation is enabled or disabled for a whole track. By default tracks are interpolated.
</description>
</method>
<method name="value_track_get_key_indices" qualifiers="const">
@@ -2401,7 +2574,7 @@
<return type="bool">
</return>
<description>
- Return wether the animation has the loop flag set.
+ Return whether the animation has the loop flag set.
</description>
</method>
<method name="set_step">
@@ -2448,7 +2621,7 @@
Container and player of [Animation] resources.
</brief_description>
<description>
- An animation player is used for general purpose playback of [Animation] resources. It contains a dictionary of animations (referenced by name) and custom blend times between their transitions. Additionally, animations can be played and blended in diferent channels.
+ An animation player is used for general purpose playback of [Animation] resources. It contains a dictionary of animations (referenced by name) and custom blend times between their transitions. Additionally, animations can be played and blended in different channels.
</description>
<methods>
<method name="add_animation">
@@ -2484,7 +2657,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
- Request wether an [Animation] name exist within the player.
+ Request whether an [Animation] name exist within the player.
</description>
</method>
<method name="get_animation" qualifiers="const">
@@ -2511,7 +2684,7 @@
<argument index="2" name="sec" type="float">
</argument>
<description>
- Specify a blend time (in seconds) between two animations, referemced by their names.
+ Specify a blend time (in seconds) between two animations, referenced by their names.
</description>
</method>
<method name="get_blend_time" qualifiers="const">
@@ -2522,7 +2695,7 @@
<argument index="1" name="anim_to" type="String">
</argument>
<description>
- Get the blend time between two animations, referemced by their names.
+ Get the blend time between two animations, referenced by their names.
</description>
</method>
<method name="set_default_blend_time">
@@ -2575,7 +2748,7 @@
<return type="bool">
</return>
<description>
- Return wether an animation is playing.
+ Return whether an animation is playing.
</description>
</method>
<method name="set_current_animation">
@@ -2658,7 +2831,7 @@
<return type="NodePath">
</return>
<description>
- Return path to root node (see [set_root]).
+ Return path to root node (see [method set_root]).
</description>
</method>
<method name="seek">
@@ -3793,7 +3966,7 @@
<argument index="3" name="area_shape" type="int">
</argument>
<description>
- This signal triggers only once when a body enters this area. The first parameter is the body's [RID]. The second one is the body as an object. The third one is the index of the shape of the body that entered this area, and the fourth one is the index of the shape in this area that repored the entering.
+ This signal triggers only once when a body enters this area. The first parameter is the body's [RID]. The second one is the body as an object. The third one is the index of the shape of the body that entered this area, and the fourth one is the index of the shape in this area that reported the entering.
</description>
</signal>
<signal name="area_enter">
@@ -3891,7 +4064,7 @@
<argument index="0" name="value" type="var">
</argument>
<description>
- Remove the first occurence of a value from the array.
+ Remove the first occurrence of a value from the array.
</description>
</method>
<method name="find">
@@ -4173,7 +4346,7 @@
<argument index="1" name="data" type="RealArray">
</argument>
<description>
- Set the sample data for a given sample as an array of floats. The length must be equal to the sample lenght or an error will be produced.
+ Set the sample data for a given sample as an array of floats. The length must be equal to the sample length or an error will be produced.
For this method, a stereo sample is made from two samples. Thus, in case of a stereo sample, the array length must be twice the length returned by [method sample_get_length].
Trying to alter a SAMPLE_FORMAT_IMA_ADPCM sample is not supported. It will throw an error to the console, but will not alter the sample data.
</description>
@@ -4184,8 +4357,8 @@
<argument index="1" name="data" type="RawArray">
</argument>
<description>
- Set the sample data for a given sample as an array of bytes. The length must be equal to the sample lenght expected in bytes or an error will be produced. The byte length can be calculated as follows:
- Get the sample length ([method get_sample_length]).
+ Set the sample data for a given sample as an array of bytes. The length must be equal to the sample length expected in bytes or an error will be produced. The byte length can be calculated as follows:
+ Get the sample length ([method sample_get_length]).
If the sample format is SAMPLE_FORMAT_PCM16, multiply it by 2.
If the sample format is SAMPLE_FORMAT_IMA_ADPCM, divide it by 2 (rounding any fraction up), then add 4.
If the sample is stereo ([method sample_is_stereo]), multiply it by 2.
@@ -4360,7 +4533,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
- Set wether a given voice is positional. This is only interpreted as a hint and used for backends that may support binaural encoding.
+ Set whether a given voice is positional. This is only interpreted as a hint and used for backends that may support binaural encoding.
</description>
</method>
<method name="voice_get_volume" qualifiers="const">
@@ -4468,7 +4641,7 @@
<argument index="0" name="voice" type="RID">
</argument>
<description>
- Return wether the current voice is positional. See [method voice_set_positional].
+ Return whether the current voice is positional. See [method voice_set_positional].
</description>
</method>
<method name="voice_stop">
@@ -4597,7 +4770,7 @@
Base class for audio streams.
</brief_description>
<description>
- Base class for audio streams. Audio streams are used for music playback, or other types of streamed sounds that don't fit or requiere more flexibility than a [Sample].
+ Base class for audio streams. Audio streams are used for music playback, or other types of streamed sounds that don't fit or require more flexibility than a [Sample].
</description>
<methods>
</methods>
@@ -5145,7 +5318,7 @@
Provides a base class for different kinds of buttons.
</brief_description>
<description>
- BaseButton is the abstract base class for buttons, so it shouldn't be used directly (It doesnt display anything). Other types of buttons inherit from it.
+ BaseButton is the abstract base class for buttons, so it shouldn't be used directly (It doesn't display anything). Other types of buttons inherit from it.
</description>
<methods>
<method name="_pressed" qualifiers="virtual">
@@ -5203,14 +5376,14 @@
<return type="bool">
</return>
<description>
- Return wether the button is in disabled state (see [method set_disabled]).
+ Return whether the button is in disabled state (see [method set_disabled]).
</description>
</method>
<method name="set_click_on_press">
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Set the button click_on_press mode. This mode generates click events when a mousebutton or key is just pressed (by default events are generated when the button/keys are released and both press and release occur in the visual area of the Button).
+ Set the button click_on_press mode. This mode generates click events when a mouse button or key is just pressed (by default events are generated when the button/keys are released and both press and release occur in the visual area of the Button).
</description>
</method>
<method name="get_click_on_press" qualifiers="const">
@@ -5224,7 +5397,7 @@
<return type="int">
</return>
<description>
- Return the visual state used to draw the button. This is useful mainly when implementing your own draw code by either overiding _draw() or connecting to "draw" signal. The visual state of the button is defined by the DRAW_* enum.
+ Return the visual state used to draw the button. This is useful mainly when implementing your own draw code by either overriding _draw() or connecting to "draw" signal. The visual state of the button is defined by the DRAW_* enum.
</description>
</method>
</methods>
@@ -5386,7 +5559,7 @@
Standard themed Button.
</brief_description>
<description>
- Button is just the standard themed button: [image src="images/button_example.png"/] It can contain text and an icon, and will display them according to the current [Theme].
+ Button is the standard themed button. It can contain text and an icon, and will display them according to the current [Theme].
</description>
<methods>
<method name="set_text">
@@ -5419,7 +5592,7 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
- Set the [i]flat[/i] property of a Button. Flat buttons don't display decoration unless hoevered or pressed.
+ Set the [i]flat[/i] property of a Button. Flat buttons don't display decoration unless hovered or pressed.
</description>
</method>
<method name="set_clip_text">
@@ -5488,7 +5661,7 @@
Array of Buttons.
</brief_description>
<description>
- Array of Buttons. A Button array is useful to have an array of buttons laid out vertically or horizontally. Only one can be selected. This is useful for joypad based interfaces and option menus.
+ Array of Buttons. A Button array is useful to have an array of buttons laid out vertically or horizontally. Only one can be selected. This is useful for joy pad based interfaces and option menus.
</description>
<methods>
<method name="add_button">
@@ -5566,7 +5739,7 @@
<argument index="0" name="button" type="int">
</argument>
<description>
- Sekect a button in the array.
+ Select a button in the array.
</description>
</method>
<method name="erase_button">
@@ -5593,7 +5766,7 @@
</signals>
<constants>
<constant name="ALIGN_BEGIN" value="0">
- Align buttons at the begining.
+ Align buttons at the beginning.
</constant>
<constant name="ALIGN_CENTER" value="1">
Align buttons in the middle.
@@ -5614,7 +5787,7 @@
Group of Buttons.
</brief_description>
<description>
- Group of [Button]s. All direct and indirect children buttons become radios. Only one allows being pressed.
+ Group of [Button]. All direct and indirect children buttons become radios. Only one allows being pressed.
</description>
<methods>
<method name="get_pressed_button" qualifiers="const">
@@ -5665,7 +5838,7 @@
Camera node, displays from a point of view.
</brief_description>
<description>
- Camera is a special node that displays what is visible from its current location. Cameras register themselves in the nearest [Viewport] node (when ascending the tree). Only one camera can be active per viewport. If no viewport is available ascending the tree, the Camera will register in the global viewport. In other words, a Camera just provides [i]3D[/i] display capabilities to a [Viewport], and, without one, a [Scene] registered in that [Viewport] (or higher viewports) can't be displayed.
+ Camera is a special node that displays what is visible from its current location. Cameras register themselves in the nearest [Viewport] node (when ascending the tree). Only one camera can be active per viewport. If no viewport is available ascending the tree, the Camera will register in the global viewport. In other words, a Camera just provides [i]3D[/i] display capabilities to a [Viewport], and, without one, a scene registered in that [Viewport] (or higher viewports) can't be displayed.
</description>
<methods>
<method name="project_ray_normal" qualifiers="const">
@@ -5700,7 +5873,7 @@
<argument index="0" name="world_point" type="Vector3">
</argument>
<description>
- Return how a 3D point in worldpsace maps to a 2D coordinate in the [Viewport] rectangle.
+ Return how a 3D point in worldspace maps to a 2D coordinate in the [Viewport] rectangle.
</description>
</method>
<method name="is_position_behind" qualifiers="const">
@@ -5754,7 +5927,7 @@
<return type="bool">
</return>
<description>
- Return wether the Camera is the current one in the [Viewport], or plans to become current (if outside the scene tree).
+ Return whether the Camera is the current one in the [Viewport], or plans to become current (if outside the scene tree).
</description>
</method>
<method name="get_camera_transform" qualifiers="const">
@@ -5904,7 +6077,7 @@
<return type="bool">
</return>
<description>
- Return true of this is the current camera (see [method Camera2D.make_current]).
+ Return true of this is the current camera (see [method make_current]).
</description>
</method>
<method name="set_limit">
@@ -6059,7 +6232,7 @@
</brief_description>
<description>
Base class of anything 2D. Canvas items are laid out in a tree and children inherit and extend the transform of their parent. CanvasItem is extended by [Control], for anything GUI related, and by [Node2D] for anything 2D engine related.
- Any CanvasItem can draw. For this, the "update" function must be called, then NOTIFICATION_DRAW will be received on idle time to request redraw. Because of this, canvas items don't need to be redraw on every frame, improving the performance significan'tly. Several functions for drawing on the CanvasItem are provided (see draw_* functions). They can only be used inside the notification, signal or _draw() overrided function, though.
+ Any CanvasItem can draw. For this, the "update" function must be called, then NOTIFICATION_DRAW will be received on idle time to request redraw. Because of this, canvas items don't need to be redraw on every frame, improving the performance significantly. Several functions for drawing on the CanvasItem are provided (see draw_* functions). They can only be used inside the notification, signal or _draw() overrides function, though.
Canvas items are draw in tree order. By default, children are on top of their parents so a root CanvasItem will be drawn behind everything (this can be changed per item though).
Canvas items can also be hidden (hiding also their subtree). They provide many means for changing standard parameters such as opacity (for it and the subtree) and self opacity, blend mode.
Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
@@ -6071,10 +6244,10 @@
</description>
</method>
<method name="edit_set_state">
- <argument index="0" name="state" type="var">
+ <argument index="0" name="state" type="Variant">
</argument>
<description>
- Used for editing, returns an opaque value represeting the transform state.
+ Used for editing, returns an opaque value representing the transform state.
</description>
</method>
<method name="edit_get" qualifiers="const">
@@ -6154,7 +6327,7 @@
<return type="bool">
</return>
<description>
- Return if set as toplevel. See [method set_as_toplevel]/
+ Return if set as toplevel. See [method set_as_toplevel].
</description>
</method>
<method name="set_blend_mode">
@@ -6488,7 +6661,7 @@
<signals>
<signal name="item_rect_changed">
<description>
- Emitted when the intem rect has changed.
+ Emitted when the item rect has changed.
</description>
</signal>
<signal name="draw">
@@ -6515,7 +6688,7 @@
Additive blending mode.
</constant>
<constant name="BLEND_MODE_SUB" value="2">
- Substractive blending mode.
+ Subtractive blending mode.
</constant>
<constant name="BLEND_MODE_MUL" value="3">
Multiplicative blending mode.
@@ -6561,7 +6734,7 @@
<method name="set_shader_param">
<argument index="0" name="param" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -6777,7 +6950,7 @@
Capsule 2D shape resource for physics.
</brief_description>
<description>
- Capsule 2D shape resource for physics. A capsule (or sometimes called "pill") is like a line grown in all directions. It has a radius and a height, and is often useful for modelling biped characters.
+ Capsule 2D shape resource for physics. A capsule (or sometimes called "pill") is like a line grown in all directions. It has a radius and a height, and is often useful for modeling biped characters.
</description>
<methods>
<method name="set_radius">
@@ -6927,7 +7100,7 @@
Circular Shape for 2D Physics.
</brief_description>
<description>
- Circular Shape for 2D Physics. This shape is useful for modelling balls or small characters and it's collision detection with everything else is very fast.
+ Circular Shape for 2D Physics. This shape is useful for modeling balls or small characters and it's collision detection with everything else is very fast.
</description>
<methods>
<method name="set_radius">
@@ -7318,7 +7491,7 @@
</argument>
<description>
Set the array of points forming the polygon.
- When editing the point list via the editor, depending on [method get_build_mode], it has to be a list of points (for [code]build_mode[/code]=0), or a list of lines (for [code]build_mode[/code]=1). In the second case, the even elements of the array define the start point of the line, and the odd elements the end point.
+ When editing the point list via the editor, depending on [method get_build_mode], it has to be a list of points (for [code]build_mode==0[/code]), or a list of lines (for [code]build_mode==1[/code]). In the second case, the even elements of the array define the start point of the line, and the odd elements the end point.
</description>
</method>
<method name="get_polygon" qualifiers="const">
@@ -7332,14 +7505,14 @@
<argument index="0" name="build_mode" type="int">
</argument>
<description>
- Set whether the polygon is to be a [ConvexPolygon2D] ([code]build_mode[/code]=0), or a [ConcavePolygon2D] ([code]build_mode[/code]=1).
+ Set whether the polygon is to be a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
<method name="get_build_mode" qualifiers="const">
<return type="int">
</return>
<description>
- Return whether the polygon is a [ConvexPolygon2D] ([code]build_mode[/code]=0), or a [ConcavePolygon2D] ([code]build_mode[/code]=1).
+ Return whether the polygon is a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
<method name="set_trigger">
@@ -7361,7 +7534,7 @@
</return>
<description>
Return the index of the first shape generated by the editor.
- When [code]build_mode[/code] is set to generate convex polygons, the shape shown in the editor may be decomopsed into many convex polygons. In that case, a range of indexes is needed to directly access the [Shape2D]s.
+ When [code]build_mode[/code] is set to generate convex polygons, the shape shown in the editor may be decomposed into many convex polygons. In that case, a range of indexes is needed to directly access the [Shape2D].
When [code]build_mode[/code] is set to generate concave polygons, there is only one [Shape2D] generated, so the start index and the end index are the same.
</description>
</method>
@@ -7525,7 +7698,7 @@
<return type="int">
</return>
<description>
- Convert the color to a 32 its integer (each byte represets a RGBA).
+ Convert the color to a 32 its integer (each byte represents a RGBA).
</description>
</method>
<method name="to_ARGB32">
@@ -8012,7 +8185,7 @@
</argument>
<argument index="1" name="key" type="String">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -8022,7 +8195,7 @@
</argument>
<argument index="1" name="key" type="String">
</argument>
- <argument index="2" name="default" type="var" default="NULL">
+ <argument index="2" name="default" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -8084,7 +8257,7 @@
Dialog for confirmation of actions.
</brief_description>
<description>
- Dialog for confirmation of actions. This dialog inherits from [AcceptDialog], but has by default an OK and Cancel buton (in host OS order).
+ Dialog for confirmation of actions. This dialog inherits from [AcceptDialog], but has by default an OK and Cancel button (in host OS order).
</description>
<methods>
<method name="get_cancel">
@@ -8103,8 +8276,8 @@
Base node for containers.
</brief_description>
<description>
- Base node for conainers. A [Container] contains other controls and automatically arranges them in a certain way.
- A Control can inherit this to reate custom container classes.
+ Base node for containers. A [Container] contains other controls and automatically arranges them in a certain way.
+ A Control can inherit this to create custom container classes.
</description>
<methods>
<method name="queue_sort">
@@ -8125,7 +8298,7 @@
<signals>
<signal name="sort_children">
<description>
- Enmitted when sorting the children is needed.
+ Emitted when sorting the children is needed.
</description>
</signal>
</signals>
@@ -8143,10 +8316,10 @@
Control is the base class Node for all the GUI components. Every GUI component inherits from it, directly or indirectly. In this way, sections of the scene tree made of contiguous control nodes, become user interfaces.
Controls are relative to the parent position and size by using anchors and margins. This ensures that they can adapt easily in most situation to changing dialog and screen sizes. When more flexibility is desired, [Container] derived nodes can be used.
Anchors work by defining which margin do they follow, and a value relative to it. Allowed anchoring modes are ANCHOR_BEGIN, where the margin is relative to the top or left margins of the parent (in pixels), ANCHOR_END for the right and bottom margins of the parent and ANCHOR_RATIO, which is a ratio from 0 to 1 in the parent range.
- Input device events ([InputEvent]) are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [Node._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event].
+ Input device events ([InputEvent]) are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [method MainLoop._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event].
Only one control can hold the keyboard focus (receiving keyboard events), for that the control must define the focus mode with [method set_focus_mode]. Focus is lost when another control gains it, or the current focus owner is hidden.
It is sometimes desired for a control to ignore mouse/pointer events. This is often the case when placing other controls on top of a button, in such cases. Calling [method set_ignore_mouse] enables this function.
- Finally, controls are skinned according to a [Theme]. Setting a [Theme] on a control will propagate all the skinning down the tree. Optionally, skinning can be overrided per each control by calling the add_*_override functions, or from the editor.
+ Finally, controls are skinned according to a [Theme]. Setting a [Theme] on a control will propagate all the skinning down the tree. Optionally, skinning can be overridden per each control by calling the add_*_override functions, or from the editor.
</description>
<methods>
<method name="_input_event" qualifiers="virtual">
@@ -8161,7 +8334,7 @@
</return>
<argument index="0" name="pos" type="Vector2">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -8169,7 +8342,7 @@
<method name="drop_data" qualifiers="virtual">
<argument index="0" name="pos" type="Vector2">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -8212,8 +8385,12 @@
</argument>
<argument index="1" name="anchor_mode" type="int">
</argument>
+ <argument index="2" name="keep_margin" type="bool" default="false">
+ </argument>
<description>
- Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Changing the anchor mode converts the current margin offset from the previos anchor mode to the new one, so margin offsets ([method set_margin]) must be done after setting anchors, or at the same time ([method set_anchor_and_margin]).
+ Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Changing the anchor mode converts the current margin offset from the previous anchor mode to the new one, so margin offsets ([method set_margin]) must be done after setting anchors, or at the same time ([method set_anchor_and_margin])
+
+ Additionally, [code]keep_margin[/code] controls whether margins should be left the same, or changed to keep the same position and size on-screen.
</description>
</method>
<method name="get_anchor" qualifiers="const">
@@ -8324,7 +8501,7 @@
<return type="Vector2">
</return>
<description>
- Returns the Control position, relative to the top-left corner of the parent Control and independly of the anchor mode.
+ Returns the Control position, relative to the top-left corner of the parent Control and independent of the anchor mode.
</description>
</method>
<method name="get_size" qualifiers="const">
@@ -8369,28 +8546,28 @@
<return type="Rect2">
</return>
<description>
- Return position and size of the Control, relative to the top-left corner of the parent Control. This is a helper (see [method get_pos],[method get_size]).
+ Return position and size of the Control, relative to the top-left corner of the parent Control. This is a helper (see [method get_pos], [method get_size]).
</description>
</method>
<method name="get_global_rect" qualifiers="const">
<return type="Rect2">
</return>
<description>
- Return position and size of the Control, relative to the top-left corner of the [i]window[/i] Control. This is a helper (see [method get_global_pos],[method get_size]).
+ Return position and size of the Control, relative to the top-left corner of the [i]window[/i] Control. This is a helper (see [method get_global_pos], [method get_size]).
</description>
</method>
<method name="set_area_as_parent_rect">
<argument index="0" name="margin" type="int" default="0">
</argument>
<description>
- Change all margins and anchors, so this Control always takes up the same area as the parent Control. This is a helper (see [method set_anchor],[method set_margin]).
+ Change all margins and anchors, so this Control always takes up the same area as the parent Control. This is a helper (see [method set_anchor], [method set_margin]).
</description>
</method>
<method name="show_modal">
<argument index="0" name="exclusive" type="bool" default="false">
</argument>
<description>
- Display a Control as modal. Control must be a subwindow (see [method set_as_subwindow]). Modal controls capture the input signals until closed or the area outside them is accessed. When a modal control loses focus, or the ESC key is pressed, they automatically hide. Modal controls are used extensively for popup dialogs and menus.
+ Display a Control as modal. Control must be a subwindow. Modal controls capture the input signals until closed or the area outside them is accessed. When a modal control loses focus, or the ESC key is pressed, they automatically hide. Modal controls are used extensively for popup dialogs and menus.
</description>
</method>
<method name="set_focus_mode">
@@ -8404,7 +8581,7 @@
<return type="bool">
</return>
<description>
- Return wether the Control is the current focused control (see [method set_focus_mode]).
+ Return whether the Control is the current focused control (see [method set_focus_mode]).
</description>
</method>
<method name="grab_focus">
@@ -8660,7 +8837,7 @@
</description>
</method>
<method name="force_drag">
- <argument index="0" name="data" type="var">
+ <argument index="0" name="data" type="Variant">
</argument>
<argument index="1" name="preview" type="Object">
</argument>
@@ -9218,7 +9395,7 @@ If "atpos" is given, the point is inserted before the point number "atpos", movi
</argument>
<description>
Sets the tilt angle in radians for the point "idx". If the index is out of bounds, the function sends an error to the console.
-The tilt controls the rotation along the look-at axis an object travelling the path would have. In the case of a curve controlling a [PathFollow], this tilt is an offset over the natural tilt the PathFollow calculates.
+The tilt controls the rotation along the look-at axis an object traveling the path would have. In the case of a curve controlling a [PathFollow], this tilt is an offset over the natural tilt the PathFollow calculates.
</description>
</method>
<method name="get_point_tilt" qualifiers="const">
@@ -9365,7 +9542,7 @@ This approximation makes straight segments between each point, then subdivides t
Damped spring constraint for 2D physics.
</brief_description>
<description>
- Damped spring constraint for 2D physics. This resembles a spring joint that always want to go back to a given length.
+ Damped spring constraint for 2D physics. This resembles a spring joint that always wants to go back to a given length.
</description>
<methods>
<method name="set_length">
@@ -9400,28 +9577,28 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="stiffness" type="float">
</argument>
<description>
- Set the stiffness of the spring joint.
+ Set the stiffness of the spring joint. The joint applies a force equal to the stiffness times the distance from its resting length.
</description>
</method>
<method name="get_stiffness" qualifiers="const">
<return type="float">
</return>
<description>
- Return the stiffness of the spring joint.
+ Return the stiffness of the spring joint. The joint applies a force equal to the stiffness times the distance from its resting length.
</description>
</method>
<method name="set_damping">
<argument index="0" name="damping" type="float">
</argument>
<description>
- Set the damping of the spring joint.
+ Set the damping ratio of the spring joint. A value of 0 indicates an undamped spring, while 1 causes the system to reach equilibrium as fast as possible (critical damping).
</description>
</method>
<method name="get_damping" qualifiers="const">
<return type="float">
</return>
<description>
- Return the damping of the spring joint.
+ Return the damping ratio of the spring joint. A value of 0 indicates an undamped spring, while 1 causes the system to reach equilibrium as fast as possible (critical damping).
</description>
</method>
</methods>
@@ -9508,7 +9685,7 @@ This approximation makes straight segments between each point, then subdivides t
Directional Light, such as the Sun or the Moon.
</brief_description>
<description>
- A DirectionalLight is a type of [Light] node that emits light constantly in one direction (the negative z axis of the node). It is used lights with strong intensity that are located far away from the scene to model sunlight or moonlight. The worldpace location of the DirectionalLight transform (origin) is ignored, only the basis is used do determine light direction.
+ A DirectionalLight is a type of [Light] node that emits light constantly in one direction (the negative z axis of the node). It is used lights with strong intensity that are located far away from the scene to model sunlight or moonlight. The worldspace location of the DirectionalLight transform (origin) is ignored, only the basis is used do determine light direction.
</description>
<methods>
<method name="set_shadow_mode">
@@ -9559,8 +9736,26 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="Directory" inherits="Reference" category="Core">
<brief_description>
+ Type used to handle the filesystem.
</brief_description>
<description>
+ Directory type. Is used to manage directories and their content (not restricted to the project folder).
+ Example for how to iterate through the files of a directory:
+ [codeblock]
+ func dir(path):
+ var d = Directory.new()
+ if d.open( path )==0:
+ d.list_dir_begin()
+ var file_name = d.get_next()
+ while(file_name!=""):
+ if d.current_is_dir():
+ print("Found directory: " + file_name)
+ else:
+ print("Found file:" + file_name)
+ file_name = d.get_next()
+ else:
+ print("Some open Error, maybe directory not found?")
+ [/codeblock]
</description>
<methods>
<method name="open">
@@ -9569,28 +9764,34 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="path" type="String">
</argument>
<description>
+ Opens a directory to work with. Needs a path, example "res://folder"
</description>
</method>
<method name="list_dir_begin">
<return type="bool">
</return>
<description>
+ Loads all file names of the current directory (prepares the get_next() function).
</description>
</method>
<method name="get_next">
<return type="String">
</return>
<description>
+ Is used to iterate through the files of the current directory. Returns the name(no path) of the current file/directory, it also contains "." and ".." .
+Returns an empty String "" at the end of the list.
</description>
</method>
<method name="current_is_dir" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns true if the current file you are looking at with get_next() is a directory or "." or ".." otherwise false.
</description>
</method>
<method name="list_dir_end">
<description>
+ Run this to empty the list of remaining files in get_next(). You can use it to end the iteration, as soon as your goal is reached.
</description>
</method>
<method name="get_drive_count">
@@ -9613,12 +9814,14 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="todir" type="String">
</argument>
<description>
+ Needs a path or name to the next directory. When the target directory is in the current directory you can use "newfolder" otherwise you need the full path "res://currentfolder/newfolder"
</description>
</method>
<method name="get_current_dir">
<return type="String">
</return>
<description>
+ Returns a path to the current directory, example: "res://folder"
</description>
</method>
<method name="make_dir">
@@ -9651,6 +9854,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns true if directory exists otherwise false. Needs a path, example: "res://folder"
</description>
</method>
<method name="get_space_left">
@@ -9691,6 +9895,47 @@ This approximation makes straight segments between each point, then subdivides t
<constants>
</constants>
</class>
+<class name="EditorExportPlugin" inherits="Reference" category="Core">
+ <brief_description>
+ Editor plugin to control the export process.
+ </brief_description>
+ <description>
+ This plugin is added into EditorImportExport and allows to modify
+ the behavior of the export process for individual files.
+ </description>
+ <methods>
+ <method name="custom_export" qualifiers="virtual">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="platform" type="EditorExportPlatform">
+ </argument>
+ <description>
+ This function is called for each file exported and
+ depending from the return value one of many things
+ might happen.
+
+ 1) If returned value is null, the file is exported
+ as is.
+
+ 2) If the returned value is a RawAray (array of
+ bytes), the content of that array becomes the new
+ file being exported.
+
+ 3) If the file must also change it's name when
+ exported, then a [Dictionary] must be returned with
+ two fields: 'name' with the new filename and 'data'
+ with a [RawArray] containing the raw contents of the
+ file. Even if the name is changed, the run-time will
+ redirect the old file to the new file automatically
+ when accessed.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="EditorFileDialog" inherits="ConfirmationDialog" category="Core">
<brief_description>
</brief_description>
@@ -9841,8 +10086,14 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="EditorImportPlugin" inherits="Reference" category="Core">
<brief_description>
+ Import plugin for editor
</brief_description>
<description>
+ Import plugins make it easy to handle importing of external assets
+ into a project.
+
+ They way they work is not that obvious though, so please make sure
+ to read the documentation, tutorials and examples.
</description>
<methods>
<method name="custom_export" qualifiers="virtual">
@@ -9850,19 +10101,35 @@ This approximation makes straight segments between each point, then subdivides t
</return>
<argument index="0" name="path" type="String">
</argument>
+ <argument index="1" name="platform" type="EditorExportPlatform">
+ </argument>
<description>
+ Generally, files that are imported stay the same
+ when exported. The only exception is in some cases
+ when the file must be re-imported for different
+ platforms (ie. texture compression).
+
+ If you want to customize the export process, it's
+ recommended to use [EditorExportPlugin.custom_export]
+ instead.
</description>
</method>
<method name="get_name" qualifiers="virtual">
<return type="String">
</return>
<description>
+ Get the name of the import plugin, which will be
+ used to identify content imported by this plugin.
+
+ Try to use lowecase and underscores if possible.
</description>
</method>
<method name="get_visible_name" qualifiers="virtual">
<return type="String">
</return>
<description>
+ Visible name for this plugin, which will be shown on
+ the import menu.
</description>
</method>
<method name="import" qualifiers="virtual">
@@ -9870,15 +10137,70 @@ This approximation makes straight segments between each point, then subdivides t
</return>
<argument index="0" name="path" type="String">
</argument>
- <argument index="1" name="from" type="ResourceImportMetaData">
- </argument>
- <description>
+ <argument index="1" name="from" type="ResourceImportMetadata">
+ </argument>
+ <description>
+ Perform an import of an external resources into the
+ project. This function is both called on import
+ (from the dialog) or re-import
+ (manual or automatic when external source files
+ changed).
+
+ An import process generally works like this:
+
+ 1) Check the metadata for source files and options.
+ Metadata is either generated in the import dialog or
+ taken from an existing resource upon reimport.
+
+ 2) Perform the import process into a new resource.
+ Some times the resource being re-imported may be already loaded
+ and in use, so checking for this by using
+ [ResourceLoader.has] is recommended. Otherwise
+ create a new resource.
+
+ 3) Set the metadata from the argument into the existing or new
+ resource being created using
+ [Resource.set_import_metadata].
+
+ 4) Save the resource into 'path' (function argument)
</description>
</method>
<method name="import_dialog" qualifiers="virtual">
<argument index="0" name="from" type="String">
</argument>
<description>
+ This function is called when either the user chooses
+ to import a resource of this type (Import menu), or
+ when the user chooses to re-import the resource
+ (from filesystem). In the later case, the path for
+ the existing file is supplied in the argument.
+
+ If the path is supplied, it is recommended to read
+ the import metadata with
+ [ResourceLoader.load_import_metadata] and fill in
+ the fields with the values contained there.
+
+ The dialog can be shown in any way (just use a
+ ConfirmationDialog and pop it up). Upon
+ confirmation, fill up a ResourceImportMetadata and
+ call the [EditorImportPlugin.import] function with
+ this information.
+ </description>
+ </method>
+ <method name="validate_source_path">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="expand_source_path">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
</description>
</method>
</methods>
@@ -9887,22 +10209,52 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="EditorPlugin" inherits="Node" category="Core">
<brief_description>
+ Used by the editor to extend it's functionality.
</brief_description>
<description>
+ Plugins are used by the editor to extend functionality. The most
+ common types of plugins are those which edit a given node or
+ resource type, import plugins and export plugins.
</description>
<methods>
<method name="apply_changes" qualifiers="virtual">
<description>
+ This method is called when the editor is about to
+ save the project, switch to another tab, etc. It
+ asks the plugin to apply any pending state changes
+ to ensure consistency.
+
+ This is used, for example, in shader editors to let
+ the plugin know that it must apply the shader code
+ being written by the user to the object.
</description>
</method>
<method name="clear" qualifiers="virtual">
<description>
+ Clear all the state and reset the object being
+ edited to zero. This ensures your plugin does not
+ keep editing a currently existing node, or a node
+ fromt the wrong scene.
+ </description>
+ </method>
+ <method name="create_spatial_gizmo" qualifiers="virtual">
+ <return type="EditorSpatialGizmo">
+ </return>
+ <argument index="0" name="for_spatial" type="Spatial">
+ </argument>
+ <description>
+ This is used for plugins that create gizmos used by
+ the spatial editor. Just check that the node passed
+ in the "for_spatial" argument matches your plugin.
</description>
</method>
<method name="edit" qualifiers="virtual">
<argument index="0" name="object" type="Object">
</argument>
<description>
+ This function is used for plugins that edit specific
+ object types (nodes or resources). It requests the
+ editor to edit the given object.
</description>
</method>
<method name="forward_input_event" qualifiers="virtual">
@@ -9911,6 +10263,13 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
+ This is a low level function for plugins that edit a given
+ object type derived from CanvasItem to capture the input in the 2D editor
+ viewport. The function is only being called if your
+ object is being edited.
+
+ Return true if you want to capture the input,
+ otherwise false.
</description>
</method>
<method name="forward_spatial_input_event" qualifiers="virtual">
@@ -9921,24 +10280,45 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="1" name="event" type="InputEvent">
</argument>
<description>
+ This is a low level function for plugins that edit a
+ given objet type derived from Spatial to capture the
+ input of the viewport. The function is only being
+ called if your object is being edited.
+
+ By using the [InputEvent] and the [Camera] arguments
+ it's pretty easy to do raycasts into space using
+ Camera functions.
+
+ Return true if you want to capture the input,
+ otherwise false.
</description>
</method>
<method name="get_breakpoints" qualifiers="virtual">
<return type="StringArray">
</return>
<description>
+ This is for editors that edit script based objects.
+ You can return a list of breakpoints in the format
+ (script:line), for example: res://path_to_script.gd:25
</description>
</method>
<method name="get_name" qualifiers="virtual">
<return type="String">
</return>
<description>
+ Get the name of the editor plugin. For main scren
+ plugins this is what will appear in the selector
+ (which by default is 2D, 3D, Script).
</description>
</method>
<method name="get_state" qualifiers="virtual">
<return type="Dictionary">
</return>
<description>
+ Get the state of your plugin editor. This is used
+ when saving the scene (so state is kept when opening
+ it again) and for switching tabs (so state can be
+ restored when the tab returns).
</description>
</method>
<method name="handles" qualifiers="virtual">
@@ -9947,38 +10327,107 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="object" type="Object">
</argument>
<description>
+ Implement this function if your plugin edits a
+ specific type of object (Resource or Node). If you
+ return true, then you will get the functions
+ [EditorPlugin.edit] and [EditorPlugin.make_visible]
+ called when the editor requests them.
</description>
</method>
<method name="has_main_screen" qualifiers="virtual">
<return type="bool">
</return>
<description>
+ Return true if this is a main screen editor plugin
+ (it goes in the main screen selector together with
+ 2D, 3D, Script).
</description>
</method>
<method name="make_visible" qualifiers="virtual">
<argument index="0" name="visible" type="bool">
</argument>
<description>
+ This function will be called when the editor is
+ requested to become visible. It is used for plugins
+ that edit a specific object type.
+
+ Remember that you have to manage the visibility of
+ all your editor controls manually.
</description>
</method>
<method name="set_state" qualifiers="virtual">
<argument index="0" name="state" type="Dictionary">
</argument>
<description>
+ Restore the state saved by [EditorPlugin.get_state].
</description>
</method>
- <method name="get_undo_redo">
- <return type="Object">
- </return>
+ <method name="add_control_to_container">
+ <argument index="0" name="container" type="int">
+ </argument>
+ <argument index="1" name="control" type="Control">
+ </argument>
<description>
+ Add a custom control to a container (see
+ CONTAINER_* enum). There are many locations where
+ custom controls can be added in the editor UI.
+
+ Please remember that you have to manage the
+ visibility of your custom controls yourself (and likely
+ hide it after adding it).
+
+ If your plugin is being removed, also make sure to
+ remove your custom controls too.
</description>
</method>
- <method name="add_custom_control">
- <argument index="0" name="container" type="int">
+ <method name="add_control_to_bottom_panel">
+ <argument index="0" name="control" type="Control">
+ </argument>
+ <argument index="1" name="title" type="String">
</argument>
- <argument index="1" name="control" type="Object">
+ <description>
+ Add a control to the bottom panel (together with
+ Output, Debug, Animation, etc).
+
+ If your plugin is being removed, also make sure to
+ remove your control by calling [method
+ remove_control_from_bottom_panel].
+ </description>
+ </method>
+ <method name="add_control_to_dock">
+ <argument index="0" name="slot" type="int">
+ </argument>
+ <argument index="1" name="control" type="Control">
</argument>
<description>
+ Add the control to a specific dock slot (see DOCK_*
+ enum for options).
+
+ If the dock is repositioned and as long as the
+ plugin is active, the editor will save the dock
+ position on further sessions.
+
+ If your plugin is being removed, also make sure to
+ remove your control by calling [method
+ remove_control_from_docks].
+ </description>
+ </method>
+ <method name="remove_control_from_docks">
+ <argument index="0" name="control" type="Control">
+ </argument>
+ <description>
+ Remove the control from the dock. Don't forget to
+ call this if you added one, so the editor can save
+ the layout and remove it cleanly.
+ </description>
+ </method>
+ <method name="remove_control_from_bottom_panel">
+ <argument index="0" name="control" type="Control">
+ </argument>
+ <description>
+ Remove the control from the bottom panel. Don't forget
+ to call this if you added one, so the editor can
+ remove it cleanly.
</description>
</method>
<method name="add_custom_type">
@@ -9991,12 +10440,102 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="3" name="icon" type="Texture">
</argument>
<description>
+ Add a custom type, which will appear in the list of
+ nodes or resources. An icon can be optionally
+ passed.
+
+ When given node or resource is selected, the base
+ type will be instanced (ie, "Spatial", "Control",
+ "Resource"), then the script will be loaded and set
+ to this object.
+
+ You can use the [EditorPlugin.handles] to check if
+ your custom object is being edited by checking the
+ script or using 'extends' keyword.
+
+ During run-time, this will be a simple object with a
+ script so this function does not need to be called
+ then.
</description>
</method>
<method name="remove_custom_type">
<argument index="0" name="type" type="String">
</argument>
<description>
+ Remove a custom type added by
+ [EditorPlugin.add_custom_type]
+ </description>
+ </method>
+ <method name="add_import_plugin">
+ <argument index="0" name="plugin" type="EditorImportPlugin">
+ </argument>
+ <description>
+ Add an import plugin. These plugins manage importing
+ external content (from outside the project) into
+ formats the engine can understand.
+
+ On exit, don't forget to remove the plugin by
+ calling [method remove_import_plugin]
+ </description>
+ </method>
+ <method name="remove_import_plugin">
+ <argument index="0" name="plugin" type="EditorImportPlugin">
+ </argument>
+ <description>
+ Remove the import plugin, don't forget to call this
+ on exit.
+ </description>
+ </method>
+ <method name="add_export_plugin">
+ <argument index="0" name="plugin" type="EditorExportPlugin">
+ </argument>
+ <description>
+ Add an export plugin. Plugins of this kind can
+ change files being exported. On exit don't forget to
+ call [method remove_export_plugin].
+ </description>
+ </method>
+ <method name="remove_export_plugin">
+ <argument index="0" name="plugin" type="EditorExportPlugin">
+ </argument>
+ <description>
+ Remove the export plugin, don't forget to call this
+ on exit.
+ </description>
+ </method>
+ <method name="get_base_control">
+ <return type="Control">
+ </return>
+ <description>
+ Get a base control where it's safe to place dialogs.
+ Many plugins open dialogs and they need a control as
+ a base to make sure they use the editor icons and
+ theme.
+ </description>
+ </method>
+ <method name="get_undo_redo">
+ <return type="UndoRedo">
+ </return>
+ <description>
+ Get the undo/redo object. Most actions in the editor
+ can be undoable, so use this object to make sure
+ this happens when it's worth it.
+ </description>
+ </method>
+ <method name="get_selection">
+ <return type="EditorSelection">
+ </return>
+ <description>
+ Get the object that handles the selection of nodes
+ in the Scene Tree editor.
+ </description>
+ </method>
+ <method name="get_editor_settings">
+ <return type="EditorSettings">
+ </return>
+ <description>
+ Get the general settings for the editor (the same
+ window that appears in the Settings menu).
</description>
</method>
</methods>
@@ -10013,18 +10552,45 @@ This approximation makes straight segments between each point, then subdivides t
</constant>
<constant name="CONTAINER_CANVAS_EDITOR_SIDE" value="5">
</constant>
+ <constant name="DOCK_SLOT_LEFT_UL" value="0">
+ </constant>
+ <constant name="DOCK_SLOT_LEFT_BL" value="1">
+ </constant>
+ <constant name="DOCK_SLOT_LEFT_UR" value="2">
+ </constant>
+ <constant name="DOCK_SLOT_LEFT_BR" value="3">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_UL" value="4">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_BL" value="5">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_UR" value="6">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_BR" value="7">
+ </constant>
+ <constant name="DOCK_SLOT_MAX" value="8">
+ </constant>
</constants>
</class>
<class name="EditorScenePostImport" inherits="Reference" category="Core">
<brief_description>
+ Base script for post-processing scenes being imported.
</brief_description>
<description>
+ These scripts can modify scenes after being imported by the 3D Scene
+ import option of the Import menu.
</description>
<methods>
<method name="post_import" qualifiers="virtual">
<argument index="0" name="scene" type="Object">
</argument>
<description>
+ This function is called upon import with the
+ imported scene.
+
+ Just do any changes desired to the scene and return
+ it. If null is returned, import will fail and throw
+ an error to the user.
</description>
</method>
</methods>
@@ -10033,8 +10599,10 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="EditorScript" inherits="Reference" category="Core">
<brief_description>
+ Simple script to perform changes in the currently edited scene.
</brief_description>
<description>
+ This script can be run from the Scene -&gt; Run Script menu option.
</description>
<methods>
<method name="_run" qualifiers="virtual">
@@ -10057,6 +10625,300 @@ This approximation makes straight segments between each point, then subdivides t
<constants>
</constants>
</class>
+<class name="EditorSelection" inherits="Object" category="Core">
+ <brief_description>
+ Manages the SceneTree selection in the editor.
+ </brief_description>
+ <description>
+ This object manages the SceneTree selection in the editor.
+ </description>
+ <methods>
+ <method name="clear">
+ <description>
+ Clear the selection.
+ </description>
+ </method>
+ <method name="add_node">
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ Add a node to the selection.
+ </description>
+ </method>
+ <method name="remove_node">
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ Remove a node from the selection.
+ </description>
+ </method>
+ <method name="get_selected_nodes">
+ <return type="Array">
+ </return>
+ <description>
+ Get the list of selectes nodes.
+ </description>
+ </method>
+ </methods>
+ <signals>
+ <signal name="selection_changed">
+ <description>
+ Emitted when the selection changes.
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
+<class name="EditorSettings" inherits="Resource" category="Core">
+ <brief_description>
+ Object that holds the project-independent editor settings.
+ </brief_description>
+ <description>
+ Object that holds the project-independent editor settings. These
+ settings are generally visible in the Editor Settings menu.
+
+ Accessing the settings is done by using the regular [Object] API,
+ such as.
+
+ settings.set(prop,value)
+
+ settings.get(prop)
+
+ list_of_settings = settings.get_property_list()
+ </description>
+ <methods>
+ <method name="erase">
+ <argument index="0" name="property" type="String">
+ </argument>
+ <description>
+ Erase a given setting (pass full property path).
+ </description>
+ </method>
+ <method name="get_settings_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ Get the global settings path for the engine. Inside
+ this path you can find some standard paths such as:
+
+ settings/tmp - used for temporary storage of files
+
+ settings/templates - where export templates are
+ located
+ </description>
+ </method>
+ <method name="get_project_settings_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ Get the specific project settings path. Projects all
+ have an unique sub-directory inside the settings
+ path where project specific settings are saved.
+ </description>
+ </method>
+ <method name="set_favorite_dirs">
+ <argument index="0" name="dirs" type="StringArray">
+ </argument>
+ <description>
+ Set the list of favorite directories for this
+ project.
+ </description>
+ </method>
+ <method name="get_favorite_dirs" qualifiers="const">
+ <return type="StringArray">
+ </return>
+ <description>
+ Get the list of favorite directories for this
+ project.
+ </description>
+ </method>
+ <method name="set_recent_dirs">
+ <argument index="0" name="dirs" type="StringArray">
+ </argument>
+ <description>
+ Set the list of recently visited folders in the file
+ dialog for this project.
+ </description>
+ </method>
+ <method name="get_recent_dirs" qualifiers="const">
+ <return type="StringArray">
+ </return>
+ <description>
+ Get the list of recently visited folders in the file
+ dialog for this project.
+ </description>
+ </method>
+ </methods>
+ <signals>
+ <signal name="settings_changed">
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
+<class name="EditorSpatialGizmo" inherits="SpatialGizmo" category="Core">
+ <brief_description>
+ Custom gizmo for editing Spatial objects.
+ </brief_description>
+ <description>
+ Custom gizmo that is used for providing custom visualization and
+ editing (handles) for 3D Spatial objects. These are created by
+ [method EditorPlugin.create_spatial_gizmo].
+ </description>
+ <methods>
+ <method name="commit_handle" qualifiers="virtual">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="restore" type="Variant">
+ </argument>
+ <argument index="2" name="cancel" type="bool">
+ </argument>
+ <description>
+ Commit a handle being edited (handles must have been
+ prevously added by [method add_handles]).
+
+ If the cancel parameter is true, an option to
+ restore the edited value to the original is
+ provided.
+ </description>
+ </method>
+ <method name="get_handle_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ Get the name of an edited handle (handles must have
+ been previously added by [method add_handles]).
+
+ Handles can be named for reference to the user when editing.
+ </description>
+ </method>
+ <method name="get_handle_value" qualifiers="virtual">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ Get actual value of a handle. This value can be
+ anything and used for eventually undoing the motion
+ when calling [method commit_handle]
+ </description>
+ </method>
+ <method name="redraw" qualifiers="virtual">
+ <description>
+ This function is called when the Spatial this gizmo
+ refers to changes (the [method Spatial.update_gizmo]
+ is called).
+ </description>
+ </method>
+ <method name="set_handle" qualifiers="virtual">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="camera" type="Camera">
+ </argument>
+ <argument index="2" name="point" type="Vector2">
+ </argument>
+ <description>
+ This function is used when the user drags a gizmo
+ handle (previously added with [method add_handles])
+ in screen coordinates.
+
+ The [Camera] is also provided
+ so screen coordinates can be converted to raycasts.
+ </description>
+ </method>
+ <method name="add_lines">
+ <argument index="0" name="lines" type="Vector3Array">
+ </argument>
+ <argument index="1" name="material" type="Material">
+ </argument>
+ <argument index="2" name="billboard" type="bool" default="false">
+ </argument>
+ <description>
+ Add lines to the gizmo (as sets of 2 points), with a
+ given material. The lines are used for visualizing
+ the gizmo.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_mesh">
+ <argument index="0" name="mesh" type="Mesh">
+ </argument>
+ <argument index="1" name="billboard" type="bool" default="false">
+ </argument>
+ <argument index="2" name="skeleton" type="RID" default="RID()">
+ </argument>
+ <description>
+ Add a mesh to the gizmo, this is used for
+ visualization.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_collision_segments">
+ <argument index="0" name="segments" type="Vector3Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="add_collision_triangles">
+ <argument index="0" name="triangles" type="TriangleMesh">
+ </argument>
+ <description>
+ Add collision triangles to the gizmo for picking. A
+ [TriangleMesh] can be generated from a regular
+ [Mesh] too.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_unscaled_billboard">
+ <argument index="0" name="material" type="Material">
+ </argument>
+ <argument index="1" name="default_scale" type="float" default="1">
+ </argument>
+ <description>
+ Add an unscaled billboard for visualization.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_handles">
+ <argument index="0" name="handles" type="Vector3Array">
+ </argument>
+ <argument index="1" name="billboard" type="bool" default="false">
+ </argument>
+ <argument index="2" name="secondary" type="bool" default="false">
+ </argument>
+ <description>
+ Add a list of handles (points) which can be used to
+ deform the object being edited.
+
+ There are virtual functions which will be called
+ upon editing of these handles.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="set_spatial_node">
+ <argument index="0" name="node" type="Spatial">
+ </argument>
+ <description>
+ Call this function once and upon creation of the
+ gizmo, otherwise no other function will work.
+
+ The argument is the node being edited by the gizmo.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="Environment" inherits="Resource" category="Core">
<brief_description>
</brief_description>
@@ -10078,7 +10940,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="set_background_param">
<argument index="0" name="param" type="int">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -10108,7 +10970,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="fx_set_param">
<argument index="0" name="param" type="int">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -10312,7 +11174,7 @@ This approximation makes straight segments between each point, then subdivides t
</argument>
<description>
Set the playback volume for this player. This is a float between 0.0 (silent) and 1.0 (full volume). Values over 1.0 may amplify sound even more, but may introduce distortion. Negative values may just invert the output waveform, which produces no audible difference.
- The effect of these special values uiltimately depends on the low-level implementation of the file format being played.
+ The effect of these special values ultimately depends on the low-level implementation of the file format being played.
</description>
</method>
<method name="get_volume" qualifiers="const">
@@ -10354,7 +11216,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="db" type="float">
</argument>
<description>
- Set the playback volume for this player, in decibels. This is a float between -80.0 (silent) and 0.0 (full volume). Values under -79.0 get truncated to -80, but values over 0.0 do not, so the warnings for overamplifying (see [set_volume]) still apply.
+ Set the playback volume for this player, in decibels. This is a float between -80.0 (silent) and 0.0 (full volume). Values under -79.0 get truncated to -80, but values over 0.0 do not, so the warnings for over amplifying (see [method set_volume]) still apply.
</description>
</method>
<method name="get_volume_db" qualifiers="const">
@@ -10419,7 +11281,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="1" name="channel_volume" type="float">
</argument>
<description>
- Set the volume scale for an individual channel of the stream, with the same value range as [methid set_volume]. The channel number depends on the stream format. For example, MIDIs range from 0 to 15, and MODs from 0 to 63.
+ Set the volume scale for an individual channel of the stream, with the same value range as [method set_volume]. The channel number depends on the stream format. For example, MIDIs range from 0 to 15, and MODs from 0 to 63.
Many stream formats are multichannel, so this allows to affect only a part of the music.
</description>
</method>
@@ -10463,10 +11325,10 @@ This approximation makes straight segments between each point, then subdivides t
Driver for MOD playback.
</brief_description>
<description>
- This driver plays MOD music. MOD music, as all event-based streams, is a music format defined by note events ocurring at defined moments, instead of a stream of audio samples.
+ This driver plays MOD music. MOD music, as all event-based streams, is a music format defined by note events occurring at defined moments, instead of a stream of audio samples.
Currently, this driver supports the MOD, S3M, IT, and XM formats.
This class exposes no methods.
- This class can return its playback positon in seconds, but does not allow to set it, failing with only a console warning.
+ This class can return its playback position in seconds, but does not allow to set it, failing with only a console warning.
This class can not return its song length, returning 1.0 when queried.
This class does not limit its volume settings, allowing for overflow/distortion and wave inversion.
</description>
@@ -10617,6 +11479,16 @@ This approximation makes straight segments between each point, then subdivides t
<description>
</description>
</method>
+ <method name="get_md5" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ Returns on success, a md5 String representing the file of the given path.
+ else, empty String "".
+ </description>
+ </method>
<method name="get_endian_swap">
<return type="bool">
</return>
@@ -10642,6 +11514,8 @@ This approximation makes straight segments between each point, then subdivides t
<method name="get_csv_line" qualifiers="const">
<return type="StringArray">
</return>
+ <argument index="0" name="delim" type="String" default="&quot;,&quot;">
+ </argument>
<description>
</description>
</method>
@@ -10706,7 +11580,7 @@ This approximation makes straight segments between each point, then subdivides t
</description>
</method>
<method name="store_var">
- <argument index="0" name="value" type="var">
+ <argument index="0" name="value" type="Variant">
</argument>
<description>
</description>
@@ -10906,13 +11780,13 @@ This approximation makes straight segments between each point, then subdivides t
Simple Material with a fixed parameter set.
</brief_description>
<description>
- FixedMaterial is a simple type of material [Resource], which contains a fixed amount of paramters. It is the only type of material supported in fixed-pipeline devices and APIs. It is also an often a better alternative to [ShaderMaterial] for most simple use cases.
+ FixedMaterial is a simple type of material [Resource], which contains a fixed amount of parameters. It is the only type of material supported in fixed-pipeline devices and APIs. It is also an often a better alternative to [ShaderMaterial] for most simple use cases.
</description>
<methods>
<method name="set_parameter">
<argument index="0" name="param" type="int">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set a parameter, parameters are defined in the PARAM_* enum. The type of each parameter may change, so it's best to check the enum.
@@ -10981,14 +11855,14 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="transform" type="Transform">
</argument>
<description>
- Sets a special transform used to post-transform UV coordinates of the uv_xfrom tecoord mode: TEXCOORD_UV_TRANSFORM.
+ Sets a special transform used to post-transform UV coordinates of the uv_xform texcoord mode: TEXCOORD_UV_TRANSFORM.
</description>
</method>
<method name="get_uv_transform" qualifiers="const">
<return type="Transform">
</return>
<description>
- Returns the special transform used to post-transform UV coordinates of the uv_xfrom tecoord mode: TEXCOORD_UV_TRANSFORM.
+ Returns the special transform used to post-transform UV coordinates of the uv_xform texcoord mode: TEXCOORD_UV_TRANSFORM.
</description>
</method>
<method name="set_light_shader">
@@ -11230,7 +12104,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="4" name="clip_w" type="int" default="-1">
</argument>
<description>
- Draw "string" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally clipping the width. "pos" specifies te baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
+ Draw "string" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis.
</description>
</method>
<method name="draw_char" qualifiers="const">
@@ -11247,7 +12121,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="4" name="modulate" type="Color" default="Color(1,1,1,1)">
</argument>
<description>
- Draw character "char" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally kerning if "next" is apassed. clipping the width. "pos" specifies te baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character.
+ Draw character "char" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally kerning if "next" is passed. clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character.
</description>
</method>
<method name="set_fallback">
@@ -11273,25 +12147,25 @@ This approximation makes straight segments between each point, then subdivides t
</description>
<methods>
<method name="call_func">
- <argument index="0" name="arg0" type="var" default="NULL">
+ <argument index="0" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="1" name="arg1" type="var" default="NULL">
+ <argument index="1" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg2" type="var" default="NULL">
+ <argument index="2" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg3" type="var" default="NULL">
+ <argument index="3" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg4" type="var" default="NULL">
+ <argument index="4" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg5" type="var" default="NULL">
+ <argument index="5" name="arg5" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg6" type="var" default="NULL">
+ <argument index="6" name="arg6" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg7" type="var" default="NULL">
+ <argument index="7" name="arg7" type="Variant" default="NULL">
</argument>
- <argument index="8" name="arg8" type="var" default="NULL">
+ <argument index="8" name="arg8" type="Variant" default="NULL">
</argument>
- <argument index="9" name="arg9" type="var" default="NULL">
+ <argument index="9" name="arg9" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -11321,7 +12195,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="resume">
<return type="Variant">
</return>
- <argument index="0" name="arg" type="var" default="NULL">
+ <argument index="0" name="arg" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -11966,7 +12840,7 @@ This approximation makes straight segments between each point, then subdivides t
</brief_description>
<description>
GraphEdit manages the showing of GraphNodes it contains, as well as connections an disconnections between them. Signals are sent for each of these two events. Disconnection between GraphNodes slots is disabled by default.
- It is greatly advised to enable low processor usage mode [OS.set_low_processor_usage_mode()] when using GraphEdits.
+ It is greatly advised to enable low processor usage mode (see [method OS.set_low_processor_usage_mode]) when using GraphEdits.
</description>
<methods>
<method name="connect_node">
@@ -12104,6 +12978,16 @@ This approximation makes straight segments between each point, then subdivides t
</signals>
<constants>
</constants>
+ <theme_items>
+ <theme_item name="more" type="Texture">
+ </theme_item>
+ <theme_item name="reset" type="Texture">
+ </theme_item>
+ <theme_item name="minus" type="Texture">
+ </theme_item>
+ <theme_item name="bg" type="StyleBox">
+ </theme_item>
+ </theme_items>
</class>
<class name="GraphNode" inherits="Container" category="Core">
<brief_description>
@@ -12150,7 +13034,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="idx" type="int">
</argument>
<description>
- Disable input and ouput slot whose index is 'idx'.
+ Disable input and output slot whose index is 'idx'.
</description>
</method>
<method name="clear_all_slots">
@@ -12783,7 +13667,7 @@ This approximation makes straight segments between each point, then subdivides t
Horizontal separator.
</brief_description>
<description>
- Horizontal separator. See [Separator]. It is used to separate objects vertiacally, though (but it looks horizontal!).
+ Horizontal separator. See [Separator]. It is used to separate objects vertically, though (but it looks horizontal!).
</description>
<methods>
</methods>
@@ -12863,9 +13747,8 @@ This approximation makes straight segments between each point, then subdivides t
</argument>
<description>
Connect to a host. This needs to be done before any requests are sent.
-The host should not have http:// prepended but will strip the protocol identifier if provided.
-
-verify_host will check the SSL identity of the host if set to true.
+ The host should not have http:// prepended but will strip the protocol identifier if provided.
+ verify_host will check the SSL identity of the host if set to true.
</description>
</method>
<method name="set_connection">
@@ -12886,19 +13769,15 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="3" name="body" type="String" default="&quot;&quot;">
</argument>
<description>
- Sends a request to the connected host. The url is the what is normally behind the hostname, i.e:
-http://somehost.com/index.php
-url would be "index.php"
-
-Headers are HTTP request headers
-
-To create a POST request with query strings to push to the server, do:
-var fields = {"username" : "user",
- "password" : "pass"}
-var queryString = httpClient.query_string_from_dict(fields)
-var headers = ["Content-Type: application/x-www-form-urlencoded",
- "Content-Length: " + str(queryString.length())]
-var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, queryString)
+ Sends a request to the connected host. The url is what is normally behind the hostname, i.e. in [code]http://somehost.com/index.php[/code], url would be "index.php".
+ Headers are HTTP request headers.
+ To create a POST request with query strings to push to the server, do:
+ [codeblock]
+ var fields = {"username" : "user", "password" : "pass"}
+ var queryString = httpClient.query_string_from_dict(fields)
+ var headers = ["Content-Type: application/x-www-form-urlencoded", "Content-Length: " + str(queryString.length())]
+ var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, queryString)
+ [/codeblock]
</description>
</method>
<method name="send_body_text">
@@ -12951,6 +13830,9 @@ var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, qu
<return type="Dictionary">
</return>
<description>
+ Returns all response headers as dictionary where the case-sensitivity of the keys and values is kept like the server delivers it. A value is a simple String, this string can have more than one value where "; " is used as separator.
+Structure: ("key":"value1; value2")
+Example: (content-length:12), (Content-Type:application/json; charset=UTF-8)
</description>
</method>
<method name="get_response_body_length" qualifiers="const">
@@ -13005,12 +13887,12 @@ var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, qu
<argument index="0" name="fields" type="Dictionary">
</argument>
<description>
- Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary.
-
-var fields = {"username": "user", "password": "pass"}
-String queryString = httpClient.query_string_from_dict(fields)
-
-returns:= "username=user&amp;password=pass"
+ Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary, e.g.:
+ [codeblock]
+ var fields = {"username": "user", "password": "pass"}
+ String queryString = httpClient.query_string_from_dict(fields)
+ returns:= "username=user&amp;password=pass"
+ [/codeblock]
</description>
</method>
</methods>
@@ -13224,7 +14106,7 @@ returns:= "username=user&amp;password=pass"
IP Protocol support functions.
</brief_description>
<description>
- IP contains some support functions for the IPv4 protocol. TCP/IP support is in different classes (see [TCP_Client], [TCP_Server]). IP provides hostname resolution support, both blocking and threaded.
+ IP contains some support functions for the IPv4 protocol. TCP/IP support is in different classes (see [StreamPeerTCP] and [TCP_Server]). IP provides hostname resolution support, both blocking and threaded.
</description>
<methods>
<method name="resolve_hostname">
@@ -13731,6 +14613,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="button" type="int">
</argument>
<description>
+ Returns true or false depending on whether mouse button is pressed or not. You can pass BUTTON_*, which are pre-defined constants listed in [@Global Scope].
</description>
</method>
<method name="is_joy_button_pressed">
@@ -13741,7 +14624,7 @@ returns:= "username=user&amp;password=pass"
<argument index="1" name="button" type="int">
</argument>
<description>
- Returns if the joystick button at the given index is currently pressed. (see JOY_* constans in [@Global Scope])
+ Returns if the joystick button at the given index is currently pressed. (see JOY_* constants in [@Global Scope])
</description>
</method>
<method name="is_action_pressed">
@@ -13971,7 +14854,7 @@ returns:= "username=user&amp;password=pass"
Mouse button event.
</constant>
<constant name="JOYSTICK_MOTION" value="4">
- Jostick motion event.
+ Joystick motion event.
</constant>
<constant name="JOYSTICK_BUTTON" value="5">
Joystick button event.
@@ -14064,7 +14947,7 @@ returns:= "username=user&amp;password=pass"
</constant>
</constants>
</class>
-<class name="InputEventJoyButton" category="Built-In Types">
+<class name="InputEventJoystickButton" category="Built-In Types">
<brief_description>
</brief_description>
<description>
@@ -14150,7 +15033,7 @@ returns:= "username=user&amp;password=pass"
</constant>
</constants>
</class>
-<class name="InputEventJoyMotion" category="Built-In Types">
+<class name="InputEventJoystickMotion" category="Built-In Types">
<brief_description>
</brief_description>
<description>
@@ -15054,7 +15937,7 @@ returns:= "username=user&amp;password=pass"
<method name="set_item_metadata">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="metadata" type="var">
+ <argument index="1" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -15339,10 +16222,10 @@ returns:= "username=user&amp;password=pass"
</class>
<class name="Joint2D" inherits="Node2D" category="Core">
<brief_description>
- Base node for all joint constraints in 2D phyisics.
+ Base node for all joint constraints in 2D physics.
</brief_description>
<description>
- Base node for all joint constraints in 2D phyisics. Joints take 2 bodies and apply a custom constraint.
+ Base node for all joint constraints in 2D physics. Joints take 2 bodies and apply a custom constraint.
</description>
<methods>
<method name="set_node_a">
@@ -15627,7 +16510,7 @@ returns:= "username=user&amp;password=pass"
<return type="Variant">
</return>
<description>
- Return the metadata of the shape that collided with this body. If there is no collision, it will return 0, so collisions must be checked first with [method is_colliding]. Aditionally, this metadata can not be set with [method Object.set_meta], it must be set with [method Physics2DServer.body_set_shape_metadata].
+ Return the metadata of the shape that collided with this body. If there is no collision, it will return 0, so collisions must be checked first with [method is_colliding]. Additionally, this metadata can not be set with [method Object.set_meta], it must be set with [method Physics2DServer.body_set_shape_metadata].
</description>
</method>
<method name="set_collision_margin">
@@ -16545,7 +17428,7 @@ returns:= "username=user&amp;password=pass"
Main loop is the abstract main loop base class.
</brief_description>
<description>
- Main loop is the abstract main loop base class. All other main loop classes are derived from it. Upon application start, a [MainLoop] has to be provided to OS, else the application will exit. This happens automatically (and a [SceneMainLoop] is created), unless a main [Script] is supplied, which may or not create and return a [MainLoop].
+ Main loop is the abstract main loop base class. All other main loop classes are derived from it. Upon application start, a [MainLoop] has to be provided to OS, else the application will exit. This happens automatically (and a [SceneTree] is created), unless a main [Script] is supplied, which may or not create and return a [MainLoop].
</description>
<methods>
<method name="_finalize" qualifiers="virtual">
@@ -16659,7 +17542,7 @@ returns:= "username=user&amp;password=pass"
<method name="variant_to_base64">
<return type="String">
</return>
- <argument index="0" name="variant" type="var">
+ <argument index="0" name="variant" type="Variant">
</argument>
<description>
</description>
@@ -16812,7 +17695,7 @@ returns:= "username=user&amp;password=pass"
Use additive blending equation, often used for particle effects such as fire or light decals.
</constant>
<constant name="BLEND_MODE_SUB" value="2">
- Use substractive blending equation, often used for some smoke effects or types of glass.
+ Use subtractive blending equation, often used for some smoke effects or types of glass.
</constant>
<constant name="BLEND_MODE_MUL" value="3">
</constant>
@@ -17162,7 +18045,7 @@ returns:= "username=user&amp;password=pass"
Special button that brings up a [PopupMenu] when clicked.
</brief_description>
<description>
- Special button that brings up a [PopupMenu] when clicked. That's pretty much all it does, as it's just a helper class when bulding GUIs.
+ Special button that brings up a [PopupMenu] when clicked. That's pretty much all it does, as it's just a helper class when building GUIs.
</description>
<methods>
<method name="get_popup">
@@ -17211,7 +18094,7 @@ returns:= "username=user&amp;password=pass"
A [Resource] that contains vertex-array based geometry.
</brief_description>
<description>
- Mesh is a type of [Resource] that contains vertex-array based geometry, divided in [i]surfaces[/i]. Each surface contains a completely separate array and a material used to draw it. Design wise, a mesh with multiple surfaces is prefered to a single surface, because objects created in 3D editing software commonly contain multiple materials.
+ Mesh is a type of [Resource] that contains vertex-array based geometry, divided in [i]surfaces[/i]. Each surface contains a completely separate array and a material used to draw it. Design wise, a mesh with multiple surfaces is preferred to a single surface, because objects created in 3D editing software commonly contain multiple materials.
</description>
<methods>
<method name="add_morph_target">
@@ -17378,22 +18261,22 @@ returns:= "username=user&amp;password=pass"
Amount of weights/bone indices per vertex (always 4).
</constant>
<constant name="ARRAY_VERTEX" value="0">
- Vertex array (array of [Vector3]() vertices).
+ Vertex array (array of [Vector3] vertices).
</constant>
<constant name="ARRAY_NORMAL" value="1">
- Normal array (array of [Vector3]() normals).
+ Normal array (array of [Vector3] normals).
</constant>
<constant name="ARRAY_TANGENT" value="2">
Tangent array, array of groups of 4 floats. first 3 floats determine the tangent, and the last the binormal direction as -1 or 1.
</constant>
<constant name="ARRAY_COLOR" value="3">
- Vertex array (array of [Color]() colors).
+ Vertex array (array of [Color] colors).
</constant>
<constant name="ARRAY_TEX_UV" value="4">
- UV array (array of [Vector3]() UVs or float array of groups of 2 floats (u,v)).
+ UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
</constant>
<constant name="ARRAY_TEX_UV2" value="5">
- Second UV array (array of [Vector3]() UVs or float array of groups of 2 floats (u,v)).
+ Second UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
</constant>
<constant name="ARRAY_BONES" value="6">
Array of bone indices, as a float array. Each element in groups of 4 floats.
@@ -17637,7 +18520,7 @@ returns:= "username=user&amp;password=pass"
<method name="set_vertex_meta">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -17685,7 +18568,7 @@ returns:= "username=user&amp;password=pass"
<method name="set_edge_meta">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -17719,7 +18602,7 @@ returns:= "username=user&amp;password=pass"
<method name="set_face_meta">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -17756,10 +18639,10 @@ returns:= "username=user&amp;password=pass"
</class>
<class name="MeshInstance" inherits="GeometryInstance" category="Core">
<brief_description>
- Node that instances meshes into a [Scenario].
+ Node that instances meshes into a scenario.
</brief_description>
<description>
- MeshInstance is a [Node] that takes a [Mesh] resource and adds it to the current [Scenario] by creating an instance of it. This is the class most often used to get 3D geometry rendered and can be used to instance a sigle [Mesh] in many places. This allows to reuse geometry and save on resources. When a [Mesh] has to be instanced more than thousands of times at close proximity, consider using a [MultiMesh] in a [MultiMeshInstance] instead.
+ MeshInstance is a [Node] that takes a [Mesh] resource and adds it to the current scenario by creating an instance of it. This is the class most often used to get 3D geometry rendered and can be used to instance a single [Mesh] in many places. This allows to reuse geometry and save on resources. When a [Mesh] has to be instanced more than thousands of times at close proximity, consider using a [MultiMesh] in a [MultiMeshInstance] instead.
</description>
<methods>
<method name="set_mesh">
@@ -17907,11 +18790,12 @@ returns:= "username=user&amp;password=pass"
</class>
<class name="MultiMesh" inherits="Resource" category="Core">
<brief_description>
- Provides high perfomance mesh instancing.
+ Provides high performance mesh instancing.
</brief_description>
<description>
MultiMesh provides low level mesh instancing. If the amount of [Mesh] instances needed goes from hundreds to thousands (and most need to be visible at close proximity) creating such a large amount of [MeshInstance] nodes may affect performance by using too much CPU or video memory.
- For this case a MultiMesh becomes very useful, as it can draw thousands of instances with little API overhead.[br] As a drawback, if the instances are too far away of each other, performance may be reduced as every sigle instance will always rendered (they are spatially indexed as one, for the whole object).
+ For this case a MultiMesh becomes very useful, as it can draw thousands of instances with little API overhead.
+ As a drawback, if the instances are too far away of each other, performance may be reduced as every single instance will always rendered (they are spatially indexed as one, for the whole object).
Since instances may have any behavior, the AABB used for visibility must be provided by the user, or generated with [method generate_aabb].
</description>
<methods>
@@ -17933,14 +18817,14 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="count" type="int">
</argument>
<description>
- Set the amount of instnces that is going to be drawn. Changing this number will erase all the existing instance transform and color data.
+ Set the amount of instances that is going to be drawn. Changing this number will erase all the existing instance transform and color data.
</description>
</method>
<method name="get_instance_count" qualifiers="const">
<return type="int">
</return>
<description>
- Return the amount of instnces that is going to be drawn.
+ Return the amount of instances that is going to be drawn.
</description>
</method>
<method name="set_instance_transform">
@@ -18007,7 +18891,7 @@ returns:= "username=user&amp;password=pass"
Node that instances a [MultiMesh].
</brief_description>
<description>
- MultiMeshInstance is a [Node] that takes a [MultiMesh] resource and adds it to the current [Scenario] by creating an instance of it (yes, this is an instance of instances).
+ MultiMeshInstance is a [Node] that takes a [MultiMesh] resource and adds it to the current scenario by creating an instance of it (yes, this is an instance of instances).
</description>
<methods>
<method name="set_multimesh">
@@ -18395,13 +19279,13 @@ returns:= "username=user&amp;password=pass"
</description>
<methods>
<method name="set_navigation_polygon">
- <argument index="0" name="navpoly" type="Object">
+ <argument index="0" name="navpoly" type="NavigationPolygon">
</argument>
<description>
</description>
</method>
<method name="get_navigation_polygon" qualifiers="const">
- <return type="Object">
+ <return type="NavigationPolygon">
</return>
<description>
</description>
@@ -18607,12 +19491,12 @@ returns:= "username=user&amp;password=pass"
<description>
Nodes can be set as children of other nodes, resulting in a tree arrangement. Any tree of nodes is called a "Scene".
Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects.
- [SceneMainLoop] contains the "active" tree of nodes, and a node becomes active (receinving NOTIFICATION_ENTER_SCENE) when added to that tree.
- A node can contain any number of nodes as a children (but there is only one tree root) with the requirement that no two childrens with the same name can exist.
+ [SceneTree] contains the "active" tree of nodes, and a node becomes active (receiving NOTIFICATION_ENTER_SCENE) when added to that tree.
+ A node can contain any number of nodes as a children (but there is only one tree root) with the requirement that no two children with the same name can exist.
Nodes can, optionally, be added to groups. This makes it easy to reach a number of nodes from the code (for example an "enemies" group).
Nodes can be set to "process" state, so they constantly receive a callback requesting them to process (do anything). Normal processing ([method _process]) happens as fast as possible and is dependent on the frame rate, so the processing time delta is variable. Fixed processing ([method _fixed_process]) happens a fixed amount of times per second (by default 60) and is useful to link itself to the physics.
Nodes can also process input events. When set, the [method _input] function will be called with every input that the program receives. Since this is usually too overkill (unless used for simple projects), an [method _unhandled_input] function is called when the input was not handled by anyone else (usually, GUI [Control] nodes).
- To keep track of the scene hieararchy (specially when instancing scenes into scenes) an "owner" can be set to a node. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
+ To keep track of the scene hierarchy (specially when instancing scenes into scenes) an "owner" can be set to a node. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
Finally, when a node is freed, it will free all its children nodes too.
</description>
<methods>
@@ -18732,7 +19616,7 @@ returns:= "username=user&amp;password=pass"
</argument>
<description>
Fetch a node. NodePath must be valid (or else error will occur) and can be either the path to child node, a relative path (from the current node to another node), or an absolute path to a node.
- Note: fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_scene]). Examples. Assume your current node is Character and following tree:[br]
+ Note: fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_tree]). Examples. Assume your current node is Character and following tree:[br]
root/
root/Character
root/Character/Sword
@@ -18812,7 +19696,7 @@ returns:= "username=user&amp;password=pass"
<return type="NodePath">
</return>
<description>
- Return the absolute path of the current node. This only works if the curent node is inside the scene tree (see [method is_inside_scene]).
+ Return the absolute path of the current node. This only works if the current node is inside the scene tree (see [method is_inside_tree]).
</description>
</method>
<method name="get_path_to" qualifiers="const">
@@ -18830,7 +19714,7 @@ returns:= "username=user&amp;password=pass"
<argument index="1" name="persistent" type="bool" default="false">
</argument>
<description>
- Add a node to a group. Groups are helpers to name and organize group of nodes, like for example: "Enemies", "Collectables", etc. A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_scene]).
+ Add a node to a group. Groups are helpers to name and organize group of nodes, like for example: "Enemies", "Collectables", etc. A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_tree]).
</description>
</method>
<method name="remove_from_group">
@@ -18854,7 +19738,7 @@ returns:= "username=user&amp;password=pass"
<argument index="1" name="to_pos" type="int">
</argument>
<description>
- Move a child node to a different position (order) amongst the other children. Since calls, signals, etc are performed by tree order, changing the order of chilren nodes may be useful.
+ Move a child node to a different position (order) amongst the other children. Since calls, signals, etc are performed by tree order, changing the order of children nodes may be useful.
</description>
</method>
<method name="get_groups" qualifiers="const">
@@ -18879,12 +19763,12 @@ returns:= "username=user&amp;password=pass"
<return type="Node">
</return>
<description>
- Get the node owner (see [method set_node_owner]).
+ Get the node owner (see [method set_owner]).
</description>
</method>
<method name="remove_and_skip">
<description>
- Remove a node and set all its children as childrens of the parent node (if exists). All even subscriptions that pass by the removed node will be unsubscribed.
+ Remove a node and set all its children as children of the parent node (if exists). All even subscriptions that pass by the removed node will be unsubscribed.
</description>
</method>
<method name="get_index" qualifiers="const">
@@ -18896,7 +19780,7 @@ returns:= "username=user&amp;password=pass"
</method>
<method name="print_tree">
<description>
- Print the screne to stdout. Used mainly for debugging purposes.
+ Print the scene to stdout. Used mainly for debugging purposes.
</description>
</method>
<method name="set_filename">
@@ -18917,21 +19801,21 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="what" type="int">
</argument>
<description>
- Notify the current node and all its chldren recursively by calling notification() in all of them.
+ Notify the current node and all its children recursively by calling notification() in all of them.
</description>
</method>
<method name="set_fixed_process">
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enables or disables node fixed framerate processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS at a fixed (usually 60fps, check [OS] to change that) interval (and the [method _fixed_process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_fixed_process_time].
+ Enables or disables node fixed framerate processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS at a fixed (usually 60 fps, check [OS] to change that) interval (and the [method _fixed_process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_fixed_process_delta_time].
</description>
</method>
<method name="get_fixed_process_delta_time" qualifiers="const">
<return type="float">
</return>
<description>
- Return the time elapsed since the last fixed frame. This is always the same in fixed proecssing unless the frames per second is changed in [OS].
+ Return the time elapsed since the last fixed frame. This is always the same in fixed processing unless the frames per second is changed in [OS].
</description>
</method>
<method name="is_fixed_processing" qualifiers="const">
@@ -18945,7 +19829,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enables or disables node processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS on every drawn frame (and the [method _process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_process_time].
+ Enables or disables node processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS on every drawn frame (and the [method _process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_process_delta_time].
</description>
</method>
<method name="get_process_delta_time" qualifiers="const">
@@ -18966,7 +19850,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enable input processing for node. This is not requiered for GUI controls! It hooks up the node to receive all input (see [method _input]).
+ Enable input processing for node. This is not required for GUI controls! It hooks up the node to receive all input (see [method _input]).
</description>
</method>
<method name="is_processing_input" qualifiers="const">
@@ -18980,7 +19864,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enable unhandled input processing for node. This is not requiered for GUI controls! It hooks up the node to receive all input that was not previously handled before (usually by a [Control]). (see [method _unhandled_input]).
+ Enable unhandled input processing for node. This is not required for GUI controls! It hooks up the node to receive all input that was not previously handled before (usually by a [Control]). (see [method _unhandled_input]).
</description>
</method>
<method name="is_processing_unhandled_input" qualifiers="const">
@@ -19131,7 +20015,7 @@ returns:= "username=user&amp;password=pass"
Base node for 2D system.
</brief_description>
<description>
- Base node for 2D system. Node2D contains a position, rotation and scale, which is used to position and animate. It can alternatively be used with a custom 2D transform ([Matrix32]). A tree of Node2Ds allows complex hierachies for animation and positioning.
+ Base node for 2D system. Node2D contains a position, rotation and scale, which is used to position and animate. It can alternatively be used with a custom 2D transform ([Matrix32]). A tree of Node2Ds allows complex hierarchies for animation and positioning.
</description>
<methods>
<method name="set_pos">
@@ -19299,10 +20183,12 @@ returns:= "username=user&amp;password=pass"
</class>
<class name="NodePath" category="Built-In Types">
<brief_description>
- Built-in type optimized for path traversing.
+ Pre-parsed scene tree path.
</brief_description>
<description>
- Built-in type optimized for path traversing. A Node path is an optimized compiled path used for traversing the scene tree. It references nodes and can reference properties in that node, or even reference properties inside the resources of the node.
+ A pre-parsed relative or absolute path in a scene tree, for use with [method Node.get_node] and similar functions. It can reference a node, a resource within a node, or a property of a node or resource. For instance, [code]"Path2D/PathFollow2D/Sprite:texture:size"[/code] would refer to the size property of the texture resource on the node named "Sprite" which is a child of the other named nodes in the path. Note that if you want to get a resource, you must end the path with a colon, otherwise the last element will be used as a property name.
+ You will usually just pass a string to [method Node.get_node] and it will be automatically converted, but you may occasionally want to parse a path ahead of time with [NodePath] or the literal syntax [code]@"path"[/code]. Exporting a [NodePath] variable will give you a node selection widget in the properties panel of the editor, which can often be useful.
+ A [NodePath] is made up of a list of node names, a list of "subnode" (resource) names, and the name of a property in the final node or resource.
</description>
<methods>
<method name="get_name">
@@ -19311,21 +20197,21 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="idx" type="int">
</argument>
<description>
- Return a path level name.
+ Get the node name indicated by [code]idx[/code] (0 to [method get_name_count])
</description>
</method>
<method name="get_name_count">
<return type="int">
</return>
<description>
- Return the path level count.
+ Get the number of node names which make up the path.
</description>
</method>
<method name="get_property">
<return type="String">
</return>
<description>
- Return the property associated (empty if none).
+ Get the path's property name, or an empty string if the path doesn't have a property.
</description>
</method>
<method name="get_subname">
@@ -19334,14 +20220,14 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="idx" type="int">
</argument>
<description>
- Return the subname level name.
+ Get the resource name indicated by [code]idx[/code] (0 to [method get_subname_count])
</description>
</method>
<method name="get_subname_count">
<return type="int">
</return>
<description>
- Return the subname count.
+ Get the number of resource names in the path.
</description>
</method>
<method name="is_absolute">
@@ -19364,6 +20250,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="from" type="String">
</argument>
<description>
+ Create a NodePath from a string, e.g. "Path2D/PathFollow2D/Sprite:texture:size". A path is absolute if it starts with a slash. Absolute paths are only valid in the global scene tree, not within individual scenes. In a relative path, [code]"."[/code] and [code]".."[/code] indicate the current node and its parent.
</description>
</method>
</methods>
@@ -19611,6 +20498,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="time_scale" type="float">
</argument>
<description>
+ Speeds up or slows down the physics by changing the delta variable. (delta * time_scale)
</description>
</method>
<method name="get_time_scale">
@@ -19711,14 +20599,14 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="environment" type="String">
</argument>
<description>
- Return true if an envieronment variable exists.
+ Return true if an environment variable exists.
</description>
</method>
<method name="get_name" qualifiers="const">
<return type="String">
</return>
<description>
- Return the name of the host OS.
+ Return the name of the host OS. Possible values are: "Android", "BlackBerry 10", "Flash", "Haiku", "iOS", "HTML5", "OSX", "Server", "Windows", "WinRT", "X11"
</description>
</method>
<method name="get_cmdline_args">
@@ -19751,6 +20639,18 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
+ <method name="get_time_from_unix_time" qualifiers="const">
+ <return type="Dictionary">
+ </return>
+ <argument index="0" name="unix_time_val" type="int">
+ </argument>
+ <description>
+ Get a dictionary of time values when given epoch time.
+ Dictionary Time values will be a union of values from [method get_time]
+ and [method get_date] dictionaries (with the exception of dst =
+ day light standard time, as it cannot be determined from epoc)
+ </description>
+ </method>
<method name="get_time_zone_info" qualifiers="const">
<return type="Dictionary">
</return>
@@ -19968,6 +20868,10 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
+ <method name="native_video_unpause">
+ <description>
+ </description>
+ </method>
<method name="get_scancode_string" qualifiers="const">
<return type="String">
</return>
@@ -20006,6 +20910,14 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
+ <method name="set_thread_name">
+ <return type="int">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
<constant name="DAY_SUNDAY" value="0">
@@ -20022,29 +20934,29 @@ returns:= "username=user&amp;password=pass"
</constant>
<constant name="DAY_SATURDAY" value="6">
</constant>
- <constant name="MONTH_JANUARY" value="0">
+ <constant name="MONTH_JANUARY" value="1">
</constant>
- <constant name="MONTH_FEBRUARY" value="1">
+ <constant name="MONTH_FEBRUARY" value="2">
</constant>
- <constant name="MONTH_MARCH" value="2">
+ <constant name="MONTH_MARCH" value="3">
</constant>
- <constant name="MONTH_APRIL" value="3">
+ <constant name="MONTH_APRIL" value="4">
</constant>
- <constant name="MONTH_MAY" value="4">
+ <constant name="MONTH_MAY" value="5">
</constant>
- <constant name="MONTH_JUNE" value="5">
+ <constant name="MONTH_JUNE" value="6">
</constant>
- <constant name="MONTH_JULY" value="6">
+ <constant name="MONTH_JULY" value="7">
</constant>
- <constant name="MONTH_AUGUST" value="7">
+ <constant name="MONTH_AUGUST" value="8">
</constant>
- <constant name="MONTH_SEPTEMBER" value="8">
+ <constant name="MONTH_SEPTEMBER" value="9">
</constant>
- <constant name="MONTH_OCTOBER" value="9">
+ <constant name="MONTH_OCTOBER" value="10">
</constant>
- <constant name="MONTH_NOVEMBER" value="10">
+ <constant name="MONTH_NOVEMBER" value="11">
</constant>
- <constant name="MONTH_DECEMBER" value="11">
+ <constant name="MONTH_DECEMBER" value="12">
</constant>
<constant name="SCREEN_ORIENTATION_LANDSCAPE" value="0">
</constant>
@@ -20085,8 +20997,8 @@ returns:= "username=user&amp;password=pass"
<description>
Base class for all non built-in types. Everything not a built-in type starts the inheritance chain from this class.
Objects do not manage memory, if inheriting from one the object will most likely have to be deleted manually (call the [method free] function from the script or delete from C++).
- Some derivates add memory management, such as [Reference] (which keps a reference count and deletes itself automatically when no longer referenced) and [Node], which deletes the children tree when deleted.
- Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [_set]. However, scripting languages and C++ have simper means to export them.
+ Some derivates add memory management, such as [Reference] (which keeps a reference count and deletes itself automatically when no longer referenced) and [Node], which deletes the children tree when deleted.
+ Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them.
Objects also receive notifications ([method _notification]). Notifications are a simple way to notify the object about simple events, so they can all be handled together.
</description>
<methods>
@@ -20101,7 +21013,7 @@ returns:= "username=user&amp;password=pass"
<return type="Array">
</return>
<description>
- Return the property list, array of dictionaries, dictionaries must countain: name:String, type:int (see TYPE_* enum in globals) and optionally: hint:int (see PROPERTY_HINT_* in globals), hint_string:String, usage:int (see PROPERTY_USAGE_* in globals).
+ Return the property list, array of dictionaries, dictionaries must contain: name:String, type:int (see TYPE_* enum in globals) and optionally: hint:int (see PROPERTY_HINT_* in globals), hint_string:String, usage:int (see PROPERTY_USAGE_* in globals).
</description>
</method>
<method name="_init" qualifiers="virtual">
@@ -20118,7 +21030,7 @@ returns:= "username=user&amp;password=pass"
<method name="_set" qualifiers="virtual">
<argument index="0" name="property" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set a property. Return true if the property was found.
@@ -20141,13 +21053,13 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="type" type="String">
</argument>
<description>
- Check the type of the obeject against a string (including inheritance).
+ Check the type of the object against a string (including inheritance).
</description>
</method>
<method name="set">
<argument index="0" name="property" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set property into the object.
@@ -20164,7 +21076,7 @@ returns:= "username=user&amp;password=pass"
<return type="Array">
</return>
<description>
- Return the list of properties as an array of dictionaries, dictionaries countain: name:String, type:int (see TYPE_* enum in globals) and optionally: hint:int (see PROPERTY_HINT_* in globals), hint_string:String, usage:int (see PROPERTY_USAGE_* in globals).
+ Return the list of properties as an array of dictionaries, dictionaries contain: name:String, type:int (see TYPE_* enum in globals) and optionally: hint:int (see PROPERTY_HINT_* in globals), hint_string:String, usage:int (see PROPERTY_USAGE_* in globals).
</description>
</method>
<method name="get_method_list" qualifiers="const">
@@ -20206,10 +21118,10 @@ returns:= "username=user&amp;password=pass"
<method name="set_meta">
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
- Set a metadata into the object. Medatada is serialized. Metadata can be [i]anything[/i].
+ Set a metadata into the object. Metadata is serialized. Metadata can be [i]anything[/i].
</description>
</method>
<method name="get_meta" qualifiers="const">
@@ -20232,7 +21144,7 @@ returns:= "username=user&amp;password=pass"
<return type="StringArray">
</return>
<description>
- Return the list of metadatas in the object.
+ Return the list of metadata in the object.
</description>
</method>
<method name="add_user_signal">
@@ -20255,15 +21167,15 @@ returns:= "username=user&amp;password=pass"
<method name="emit_signal">
<argument index="0" name="signal" type="String">
</argument>
- <argument index="1" name="arg0" type="var" default="NULL">
+ <argument index="1" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg1" type="var" default="NULL">
+ <argument index="2" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg2" type="var" default="NULL">
+ <argument index="3" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg3" type="var" default="NULL">
+ <argument index="4" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg4" type="var" default="NULL">
+ <argument index="5" name="arg4" type="Variant" default="NULL">
</argument>
<description>
Emit a signal. Arguments are passed in an array.
@@ -20272,25 +21184,25 @@ returns:= "username=user&amp;password=pass"
<method name="call">
<argument index="0" name="method" type="String">
</argument>
- <argument index="1" name="arg0" type="var" default="NULL">
+ <argument index="1" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg1" type="var" default="NULL">
+ <argument index="2" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg2" type="var" default="NULL">
+ <argument index="3" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg3" type="var" default="NULL">
+ <argument index="4" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg4" type="var" default="NULL">
+ <argument index="5" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg5" type="var" default="NULL">
+ <argument index="6" name="arg5" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg6" type="var" default="NULL">
+ <argument index="7" name="arg6" type="Variant" default="NULL">
</argument>
- <argument index="8" name="arg7" type="var" default="NULL">
+ <argument index="8" name="arg7" type="Variant" default="NULL">
</argument>
- <argument index="9" name="arg8" type="var" default="NULL">
+ <argument index="9" name="arg8" type="Variant" default="NULL">
</argument>
- <argument index="10" name="arg9" type="var" default="NULL">
+ <argument index="10" name="arg9" type="Variant" default="NULL">
</argument>
<description>
Call a function in the object, result is returned.
@@ -20299,15 +21211,15 @@ returns:= "username=user&amp;password=pass"
<method name="call_deferred">
<argument index="0" name="method" type="String">
</argument>
- <argument index="1" name="arg0" type="var" default="NULL">
+ <argument index="1" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg1" type="var" default="NULL">
+ <argument index="2" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg2" type="var" default="NULL">
+ <argument index="3" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg3" type="var" default="NULL">
+ <argument index="4" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg4" type="var" default="NULL">
+ <argument index="5" name="arg4" type="Variant" default="NULL">
</argument>
<description>
Create and store a function in the object. The call will take place on idle time.
@@ -20522,7 +21434,7 @@ returns:= "username=user&amp;password=pass"
</class>
<class name="OmniLight" inherits="Light" category="Core">
<brief_description>
- OmniDirectional Light, such as a lightbulb or a candle.
+ OmniDirectional Light, such as a light bulb or a candle.
</brief_description>
<description>
An OmniDirectional light is a type of [Light] node that emits lights in all directions. The light is attenuated through the distance and this attenuation can be configured by changing the energy, radius and attenuation parameters of [Light]. TODO: Image of an omnilight.
@@ -20598,7 +21510,7 @@ returns:= "username=user&amp;password=pass"
<method name="set_item_metadata">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="metadata" type="var">
+ <argument index="1" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -20797,7 +21709,7 @@ returns:= "username=user&amp;password=pass"
<method name="pack">
<return type="Error">
</return>
- <argument index="0" name="value" type="var">
+ <argument index="0" name="value" type="Variant">
</argument>
<description>
</description>
@@ -20841,7 +21753,7 @@ returns:= "username=user&amp;password=pass"
<argument index="0" name="path" type="Node">
</argument>
<description>
- Pack will ignore any sub-nodes not owned by given node. See [Node.set_owner].
+ Pack will ignore any sub-nodes not owned by given node. See [method Node.set_owner].
</description>
</method>
<method name="instance" qualifiers="const">
@@ -20873,7 +21785,7 @@ returns:= "username=user&amp;password=pass"
Abstraction and base class for packet-based protocols.
</brief_description>
<description>
- PacketPeer is an abstration and base class for packet-based protocols (such as UDP). It provides an API for sending and receiving packets both as raw data or variables. This makes it easy to transfer data over a protocol, without having to encode data as low level bytes or having to worry about network ordering.
+ PacketPeer is an abstraction and base class for packet-based protocols (such as UDP). It provides an API for sending and receiving packets both as raw data or variables. This makes it easy to transfer data over a protocol, without having to encode data as low level bytes or having to worry about network ordering.
</description>
<methods>
<method name="get_var" qualifiers="const">
@@ -21006,7 +21918,7 @@ returns:= "username=user&amp;password=pass"
Provides an opaque background for [Control] children.
</brief_description>
<description>
- Panel is a [Control] that displays an opaque background. It's commoly used as a parent and container for other types of [Control] nodes. [center][img]images/panel_example.png[/img][/center]
+ Panel is a [Control] that displays an opaque background. It's commonly used as a parent and container for other types of [Control] nodes.
</description>
<methods>
</methods>
@@ -22226,7 +23138,7 @@ This method controls whether the position between two cached points is interpola
Singleton containing the list of remapped resources.
</brief_description>
<description>
- When exporting, the types of some resources may change internally so they are converted to more optimized versions. While it's not usually necesary to access to this directly (path remapping happens automatically when opeining a file), it's exported just for information.
+ When exporting, the types of some resources may change internally so they are converted to more optimized versions. While it's not usually necessary to access to this directly (path remapping happens automatically when opening a file), it's exported just for information.
</description>
<methods>
<method name="add_remap">
@@ -22614,11 +23526,11 @@ This method controls whether the position between two cached points is interpola
Intersect a ray in a given space, the returned object is a dictionary with the following fields:
position: place where ray is stopped.
normal: normal of the object at the point where the ray was stopped.
- shape: shape index of the object agaisnt which the ray was stopped.
- collider_: collider agaisnt which the ray was stopped.
- collider_id: collider id of the object agaisnt which the ray was stopped.
- collider: collider object agaisnt which the ray was stopped.
- rid: [RID] of the object agaisnt which the ray was stopped.
+ shape: shape index of the object against which the ray was stopped.
+ collider_: collider against which the ray was stopped.
+ collider_id: collider id of the object against which the ray was stopped.
+ collider: collider object against which the ray was stopped.
+ rid: [RID] of the object against which the ray was stopped.
If the ray did not intersect anything, then an empty dictionary (dir.empty()==true) is returned instead.
</description>
</method>
@@ -22694,7 +23606,7 @@ This method controls whether the position between two cached points is interpola
<method name="shape_set_data">
<argument index="0" name="shape" type="RID">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -22894,7 +23806,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="param" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -23026,7 +23938,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="shape_idx" type="int">
</argument>
- <argument index="2" name="metadata" type="var">
+ <argument index="2" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -23190,7 +24102,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="state" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -23308,7 +24220,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="userdata" type="var" default="NULL">
+ <argument index="3" name="userdata" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -23811,7 +24723,7 @@ This method controls whether the position between two cached points is interpola
Base class for all objects affected by physics.
</brief_description>
<description>
- PhysicsBody2D is an abstract base class for implementing a physics body. All [i]x[/i]Body2D types inherit from it.
+ PhysicsBody2D is an abstract base class for implementing a physics body. All *Body2D types inherit from it.
</description>
<methods>
<method name="set_layer_mask">
@@ -23898,7 +24810,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="depth" type="float">
</argument>
<description>
- Set how far a body can go through this one, when it allows one-way collisions (see [method set_one_way_collision_detection]).
+ Set how far a body can go through this one, when it allows one-way collisions (see [method set_one_way_collision_direction]).
</description>
</method>
<method name="get_one_way_collision_max_depth" qualifiers="const">
@@ -24227,7 +25139,7 @@ This method controls whether the position between two cached points is interpola
<method name="shape_set_data">
<argument index="0" name="shape" type="RID">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -24411,7 +25323,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="param" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -24653,7 +25565,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="state" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -24755,7 +25667,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="userdata" type="var" default="NULL">
+ <argument index="3" name="userdata" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -25533,7 +26445,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="epsilon" type="float" default="0.00001">
</argument>
<description>
- Returns true if "point" is inside the plane (by a very minimum treshold).
+ Returns true if "point" is inside the plane (by a very minimum threshold).
</description>
</method>
<method name="intersect_3">
@@ -25882,21 +26794,21 @@ This method controls whether the position between two cached points is interpola
Base container control for popups and dialogs.
</brief_description>
<description>
- PopUp is a base [Control] used to show dialogs and popups. It's a subwindow and modal by default (see [Control]) and has helpers for custom popup behavior.
+ Popup is a base [Control] used to show dialogs and popups. It's a subwindow and modal by default (see [Control]) and has helpers for custom popup behavior.
</description>
<methods>
<method name="popup_centered">
<argument index="0" name="size" type="Vector2" default="Vector2(0,0)">
</argument>
<description>
- Popup (show the control in modal form) in the center of the screen, at the curent size, or at a size determined by "size".
+ Popup (show the control in modal form) in the center of the screen, at the current size, or at a size determined by "size".
</description>
</method>
<method name="popup_centered_ratio">
<argument index="0" name="ratio" type="float" default="0.75">
</argument>
<description>
- Popup (show the control in modal form) in the center of the screen, scalled at a ratio of size of the screen.
+ Popup (show the control in modal form) in the center of the screen, scaled at a ratio of size of the screen.
</description>
</method>
<method name="popup_centered_minsize">
@@ -25970,7 +26882,7 @@ This method controls whether the position between two cached points is interpola
<argument index="3" name="accel" type="int" default="0">
</argument>
<description>
- Add a new item with text "label" and icon "texture". An id can optonally be provided, as well as an accelerator. If no id is provided, one will be created from the index.
+ Add a new item with text "label" and icon "texture". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index.
</description>
</method>
<method name="add_item">
@@ -25981,7 +26893,7 @@ This method controls whether the position between two cached points is interpola
<argument index="2" name="accel" type="int" default="0">
</argument>
<description>
- Add a new item with text "label". An id can optonally be provided, as well as an accelerator. If no id is provided, one will be created from the index.
+ Add a new item with text "label". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index.
</description>
</method>
<method name="add_icon_check_item">
@@ -25994,7 +26906,7 @@ This method controls whether the position between two cached points is interpola
<argument index="3" name="accel" type="int" default="0">
</argument>
<description>
- Add a new checkable item with text "label" and icon "texture". An id can optonally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
+ Add a new check able item with text "label" and icon "texture". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
</description>
</method>
<method name="add_check_item">
@@ -26005,7 +26917,7 @@ This method controls whether the position between two cached points is interpola
<argument index="2" name="accel" type="int" default="0">
</argument>
<description>
- Add a new checkable item with text "label". An id can optonally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
+ Add a new checkable item with text "label". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually.
</description>
</method>
<method name="add_submenu_item">
@@ -26048,7 +26960,7 @@ This method controls whether the position between two cached points is interpola
<method name="set_item_metadata">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="metadata" type="var">
+ <argument index="1" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -26281,35 +27193,35 @@ This method controls whether the position between two cached points is interpola
Portals provide virtual openings to rooms.
</brief_description>
<description>
- Portals provide virtual openings to [RoomInstance] nodes, so cameras can look at them from the outside. Note that portals are a visibility optimization technique, and are in no way related to the game of the same name (as in, they are not used for teleportation). For more information on how rooms and portals work, see [RoomInstance]. Portals are represented as 2D convex polygon shapes (in the X,Y local plane), and are placed on the surface of the areas occupied by a [RoomInstance], to indicate that the room can be accessed or looked-at through them. If two rooms are next to each other, and two similar portals in each of them share the same world position (and are parallel and opposed to each other), they will automatically "connect" and form "doors" (for example, the portals that connect a kitchen to a living room are placed in the door they share). Portals must always have a [RoomInstance] node as a parent, grandparent or far parent, or else they will not be active.
+ Portals provide virtual openings to [VisualInstance] nodes, so cameras can look at them from the outside. Note that portals are a visibility optimization technique, and are in no way related to the game of the same name (as in, they are not used for teleportation). For more information on how rooms and portals work, see [VisualInstance]. Portals are represented as 2D convex polygon shapes (in the X,Y local plane), and are placed on the surface of the areas occupied by a [VisualInstance], to indicate that the room can be accessed or looked-at through them. If two rooms are next to each other, and two similar portals in each of them share the same world position (and are parallel and opposed to each other), they will automatically "connect" and form "doors" (for example, the portals that connect a kitchen to a living room are placed in the door they share). Portals must always have a [VisualInstance] node as a parent, grandparent or far parent, or else they will not be active.
</description>
<methods>
<method name="set_shape">
<argument index="0" name="points" type="Vector2Array">
</argument>
<description>
- Set the portal shape. The shape is an array of [Point2] points, representing a convex polygon in the X,Y plane.
+ Set the portal shape. The shape is an array of [Vector2] points, representing a convex polygon in the X,Y plane.
</description>
</method>
<method name="get_shape" qualifiers="const">
<return type="Vector2Array">
</return>
<description>
- Return the portal shape. The shape is an array of [Point2] points, representing a convex polygon in the X,Y plane.
+ Return the portal shape. The shape is an array of [Vector2] points, representing a convex polygon in the X,Y plane.
</description>
</method>
<method name="set_enabled">
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enable the portal (it is enabled by defaul though), disabling it will cause the parent [RoomInstance] to not be visible any longer when looking through the portal.
+ Enable the portal (it is enabled by default though), disabling it will cause the parent [VisualInstance] to not be visible any longer when looking through the portal.
</description>
</method>
<method name="is_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
- Return wether the portal is active. When disabled it causes the parent [RoomInstance] to not be visible any longer when looking through the portal.
+ Return whether the portal is active. When disabled it causes the parent [VisualInstance] to not be visible any longer when looking through the portal.
</description>
</method>
<method name="set_disable_distance">
@@ -26435,7 +27347,7 @@ This method controls whether the position between two cached points is interpola
<method name="broadcast">
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="parameters" type="var">
+ <argument index="1" name="parameters" type="Variant">
</argument>
<description>
</description>
@@ -26565,7 +27477,7 @@ This method controls whether the position between two cached points is interpola
<return type="Quat">
</return>
<description>
- Returns the inverse of the quaternion (applies to the inverse rotatio too).
+ Returns the inverse of the quaternion (applies to the inverse rotation too).
</description>
</method>
<method name="length">
@@ -27035,7 +27947,7 @@ This method controls whether the position between two cached points is interpola
<return type="Object">
</return>
<description>
- Return the closest object the ray is pointing to. Note that this does not consider the length of the vector, so you must also use [is_colliding] to check if the object returned is actually colliding with the ray.
+ Return the closest object the ray is pointing to. Note that this does not consider the length of the vector, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray.
</description>
</method>
<method name="get_collider_shape" qualifiers="const">
@@ -27139,7 +28051,7 @@ This method controls whether the position between two cached points is interpola
Ray 2D shape resource for physics.
</brief_description>
<description>
- Ray 2D shape resource for physics. A ray is not really a collision body, isntead it tries to separate itself from whatever is touching its far endpoint. It's often useful for characters.
+ Ray 2D shape resource for physics. A ray is not really a collision body, instead it tries to separate itself from whatever is touching its far endpoint. It's often useful for characters.
</description>
<methods>
<method name="set_length">
@@ -27334,7 +28246,7 @@ This method controls whether the position between two cached points is interpola
Rectangle Shape for 2D Physics.
</brief_description>
<description>
- Rectangle Shape for 2D Physics. This shape is useful for modelling box-like 2D objects.
+ Rectangle Shape for 2D Physics. This shape is useful for modeling box-like 2D objects.
</description>
<methods>
<method name="set_extents">
@@ -27412,12 +28324,12 @@ This method controls whether the position between two cached points is interpola
Currently supported features:
Capturing [code]()[/code] and non-capturing [code](?:)[/code] groups
Any character [code].[/code]
- Shorthand caracter classes [code]\w \W \s \S \d \D[/code]
+ Shorthand character classes [code]\w \W \s \S \d \D[/code]
User-defined character classes such as [code][A-Za-z][/code]
Simple quantifiers [code]?[/code], [code]*[/code] and [code]+[/code]
Range quantifiers [code]{x,y}[/code]
Lazy (non-greedy) quantifiers [code]*?[/code]
- Begining [code]^[/code] and end [code]$[/code] anchors
+ Beginning [code]^[/code] and end [code]$[/code] anchors
Alternation [code]|[/code]
Backreferences [code]\1[/code] and [code]\g{1}[/code]
POSIX character classes [code][[:alnum:]][/code]
@@ -27478,6 +28390,14 @@ This method controls whether the position between two cached points is interpola
Returns a captured group. A captured group is the part of a string that matches a part of the pattern delimited by parentheses (unless they are non-capturing parentheses [i](?:)[/i]).
</description>
</method>
+ <method name="get_capture_start" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="capture" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_captures" qualifiers="const">
<return type="StringArray">
</return>
@@ -27526,7 +28446,7 @@ This method controls whether the position between two cached points is interpola
Base class for all resources.
</brief_description>
<description>
- Resource is the base class for all resource types. Resources are primarily data containers. They are reference counted and freed when no longer in use. They are also loaded only once from disk, and further attempts to load the resource will return the same reference (all this in contrast to a [Node], which is not reference counted and can be instanced from disk as many times as desred). Resources can be saved externally on disk or bundled into another object, such as a [Node] or another resource.
+ Resource is the base class for all resource types. Resources are primarily data containers. They are reference counted and freed when no longer in use. They are also loaded only once from disk, and further attempts to load the resource will return the same reference (all this in contrast to a [Node], which is not reference counted and can be instanced from disk as many times as desired). Resources can be saved externally on disk or bundled into another object, such as a [Node] or another resource.
</description>
<methods>
<method name="set_path">
@@ -27657,7 +28577,7 @@ This method controls whether the position between two cached points is interpola
<method name="set_option">
<argument index="0" name="key" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -27697,7 +28617,7 @@ This method controls whether the position between two cached points is interpola
<return type="int">
</return>
<description>
- Poll the load. If OK is returned, this means poll will have to be called again. If ERR_EOF is returned, them the load has finished and the resource can be obtained by calling [get_resource].
+ Poll the load. If OK is returned, this means poll will have to be called again. If ERR_EOF is returned, them the load has finished and the resource can be obtained by calling [method get_resource].
</description>
</method>
<method name="wait">
@@ -27710,14 +28630,14 @@ This method controls whether the position between two cached points is interpola
<return type="int">
</return>
<description>
- Return the load stage. The total amount of stages can be queried with [get_stage_count]
+ Return the load stage. The total amount of stages can be queried with [method get_stage_count]
</description>
</method>
<method name="get_stage_count" qualifiers="const">
<return type="int">
</return>
<description>
- Return the total amount of stages (calls to [poll] ) needed to completely load this resource.
+ Return the total amount of stages (calls to [method poll]) needed to completely load this resource.
</description>
</method>
</methods>
@@ -27755,6 +28675,14 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
+ <method name="load_import_metadata">
+ <return type="ResourceImportMetadata">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_recognized_extensions_for_type">
<return type="StringArray">
</return>
@@ -27796,7 +28724,7 @@ This method controls whether the position between two cached points is interpola
Resource Preloader Node.
</brief_description>
<description>
- Resource Preloader Node. This node is used to preload sub-resources inside a scene, so when the scene is loaded all the resourcs are ready to use and be retrieved from here.
+ Resource Preloader Node. This node is used to preload sub-resources inside a scene, so when the scene is loaded all the resources are ready to use and be retrieved from here.
</description>
<methods>
<method name="add_resource">
@@ -27954,7 +28882,7 @@ This method controls whether the position between two cached points is interpola
</description>
</method>
<method name="push_meta">
- <argument index="0" name="data" type="var">
+ <argument index="0" name="data" type="Variant">
</argument>
<description>
</description>
@@ -28497,7 +29425,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="state" type="Physics2DDirectBodyState">
</argument>
<description>
- Override this function to use a custom force integrator. This allows to hook up to the physics processing and alter the simulation state for the object on every frame.
+ Called during physics processing, allowing you to read and safely modify the simulation state for the object. By default it works in addition to the usual physics behavior, but [method set_use_custom_integrator] allows you to disable the default behavior and do fully custom force integration for a body.
</description>
</method>
<method name="set_mode">
@@ -28588,7 +29516,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="linear_damp" type="float">
</argument>
<description>
- Set the linear damp for this body. If this value is different from -1, any linear damp derived from the world or areas will be overriden.
+ Set the linear damp for this body. If this value is different from -1, any linear damp derived from the world or areas will be overridden.
</description>
</method>
<method name="get_linear_damp" qualifiers="const">
@@ -28602,7 +29530,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="angular_damp" type="float">
</argument>
<description>
- Set the angular damp for this body. If this value is different from -1, any angular damp derived from the world or areas will be overriden.
+ Set the angular damp for this body. If this value is different from -1, any angular damp derived from the world or areas will be overridden.
</description>
</method>
<method name="get_angular_damp" qualifiers="const">
@@ -28616,7 +29544,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="linear_velocity" type="Vector2">
</argument>
<description>
- Set the body linear velocity. Can be used sporadically, but[b] DONT SET THIS IN EVERY FRAME [/b], because physics may be running in another thread and definitely runs at a different granularity. Use [_integrate_forces] as your process loop if you want to have precise control of the body state.
+ Set the body linear velocity. Can be used sporadically, but [b]DON'T SET THIS IN EVERY FRAME[/b], because physics may be running in another thread and definitely runs at a different granularity. Use [method _integrate_forces] as your process loop if you want to have precise control of the body state.
</description>
</method>
<method name="get_linear_velocity" qualifiers="const">
@@ -28630,7 +29558,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="angular_velocity" type="float">
</argument>
<description>
- Set the body angular velocity. Can be used sporadically, but[b] DONT SET THIS IN EVERY FRAME [/b], because physics may be running in another thread and definitely runs at a different granularity. Use [_integrate_forces] as your process loop if you want to have precise control of the body state.
+ Set the body angular velocity. Can be used sporadically, but [b]DON'T SET THIS IN EVERY FRAME[/b], because physics may be running in another thread and definitely runs at a different granularity. Use [method _integrate_forces] as your process loop if you want to have precise control of the body state.
</description>
</method>
<method name="get_angular_velocity" qualifiers="const">
@@ -28658,7 +29586,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Set to true if the body shall not do any internal force integration at all (like gravity or air friction). Only the [method _integrate_forces] will be able to integrate them if overrided.
+ Pass true to disable the internal force integration (like gravity or air friction) for this body. Other than collision response, the body will only move as determined by the [method _integrate_forces] function, if defined.
</description>
</method>
<method name="is_using_custom_integrator">
@@ -28687,7 +29615,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<description>
Set the continuous collision detection mode from the enum CCD_MODE_*.
- Coninuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided. The first is more precise, and misses less impacts by small, fast-moving objects. The second is faster to compute, but can miss small, fat-moving objects.
+ Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided. The first is more precise, and misses less impacts by small, fast-moving objects. The second is faster to compute, but can miss small, fat-moving objects.
</description>
</method>
<method name="get_continuous_collision_detection_mode" qualifiers="const">
@@ -28731,7 +29659,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="sleeping" type="bool">
</argument>
<description>
- Set whether a body is isleeping or not. Sleeping bodies are not affected by forces until a collision or an [method apply_impulse]/[method set_applied_force] wakes them up. Until then, they behave like a static body.
+ Set whether a body is sleeping or not. Sleeping bodies are not affected by forces until a collision or an [method apply_impulse] / [method set_applied_force] wakes them up. Until then, they behave like a static body.
</description>
</method>
<method name="is_sleeping" qualifiers="const">
@@ -28746,7 +29674,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<description>
Set the body ability to fall asleep when not moving. This saves an enormous amount of processor time when there are plenty of rigid bodies (non static) in a scene.
- Sleeping bodies are not affected by forces until a collision or an [method apply_impulse]/[method set_applied_force] wakes them up. Until then, they behave like a static body.
+ Sleeping bodies are not affected by forces until a collision or an [method apply_impulse] / [method set_applied_force] wakes them up. Until then, they behave like a static body.
</description>
</method>
<method name="is_able_to_sleep" qualifiers="const">
@@ -28850,7 +29778,7 @@ This method controls whether the position between two cached points is interpola
Room data resource.
</brief_description>
<description>
- Room contains the data to define the bounds of a scene (using a BSP Tree). It is instanced by a [RoomInstance] node to create rooms. See that class documentation for more information about rooms.
+ Room contains the data to define the bounds of a scene (using a BSP Tree). It is instanced by a [VisualInstance] node to create rooms. See that class documentation for more information about rooms.
</description>
<methods>
<method name="set_room">
@@ -29069,7 +29997,7 @@ This method controls whether the position between two cached points is interpola
Library that contains a collection of samples.
</brief_description>
<description>
- Library that contains a collection of [Sample]s, each identified by a text ID. This is used as a data container for the majority of the SamplePlayer classes and derivatives.
+ Library that contains a collection of [Sample], each identified by a text ID. This is used as a data container for the majority of the SamplePlayer classes and derivatives.
</description>
<methods>
<method name="add_sample">
@@ -29800,6 +30728,22 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
+ <method name="is_node_instance_placeholder" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_node_instance_placeholder" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_node_instance" qualifiers="const">
<return type="PackedScene">
</return>
@@ -29923,7 +30867,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="property" type="String">
</argument>
- <argument index="3" name="value" type="var">
+ <argument index="3" name="value" type="Variant">
</argument>
<description>
</description>
@@ -30059,15 +31003,15 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="arg0" type="var" default="NULL">
+ <argument index="3" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg1" type="var" default="NULL">
+ <argument index="4" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg2" type="var" default="NULL">
+ <argument index="5" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg3" type="var" default="NULL">
+ <argument index="6" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg4" type="var" default="NULL">
+ <argument index="7" name="arg4" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -30238,7 +31182,7 @@ This method controls whether the position between two cached points is interpola
</class>
<class name="ScrollContainer" inherits="Container" category="Core">
<brief_description>
- A helper node for displaying scollable elements (e.g. lists).
+ A helper node for displaying scrollable elements (e.g. lists).
</brief_description>
<description>
A ScrollContainer node with a [Control] child and scrollbar child ([HScrollbar], [VScrollBar], or both) will only draw the Control within the ScrollContainer area. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the minimum_size of the Control relative to the ScrollContainer. Works great with a [Panel] control.
@@ -30363,7 +31307,7 @@ This method controls whether the position between two cached points is interpola
Base class for separators.
</brief_description>
<description>
- Separator is a [Control] used for sepataring other controls. It's purely a visual decoration. Horizontal ([HSeparator]) and Vertical ([VSeparator]) versions are available.
+ Separator is a [Control] used for separating other controls. It's purely a visual decoration. Horizontal ([HSeparator]) and Vertical ([VSeparator]) versions are available.
</description>
<methods>
</methods>
@@ -30519,7 +31463,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="param_id" type="int">
</argument>
- <argument index="3" name="value" type="var">
+ <argument index="3" name="value" type="Variant">
</argument>
<description>
</description>
@@ -31071,7 +32015,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="id" type="int">
</argument>
- <argument index="2" name="state" type="var">
+ <argument index="2" name="state" type="Variant">
</argument>
<description>
</description>
@@ -31419,8 +32363,8 @@ This method controls whether the position between two cached points is interpola
<argument index="4" name="shape_motion" type="Vector2">
</argument>
<description>
- Return whether this shape would collide with another, if a given movemen was applied.
- This method needs the transformation matrix for this shape ([code]local_xform[/code]), the movement to test on this shape ([code]local_motion[/code]), the shape to check collisions with ([code]with_shape[/code]), the transformation matrix of that shape ([code]shape_xform[/code]), and the movement to test ont the other object ([code]shape_motion[/code]).
+ Return whether this shape would collide with another, if a given movement was applied.
+ This method needs the transformation matrix for this shape ([code]local_xform[/code]), the movement to test on this shape ([code]local_motion[/code]), the shape to check collisions with ([code]with_shape[/code]), the transformation matrix of that shape ([code]shape_xform[/code]), and the movement to test onto the other object ([code]shape_motion[/code]).
</description>
</method>
<method name="collide_and_get_contacts">
@@ -31452,7 +32396,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<description>
Return a list of the points where this shape would touch another, if a given movement was applied. If there are no collisions, the list is empty.
- This method needs the transformation matrix for this shape ([code]local_xform[/code]), the movement to test on this shape ([code]local_motion[/code]), the shape to check collisions with ([code]with_shape[/code]), the transformation matrix of that shape ([code]shape_xform[/code]), and the movement to test ont the other object ([code]shape_motion[/code]).
+ This method needs the transformation matrix for this shape ([code]local_xform[/code]), the movement to test on this shape ([code]local_motion[/code]), the shape to check collisions with ([code]with_shape[/code]), the transformation matrix of that shape ([code]shape_xform[/code]), and the movement to test onto the other object ([code]shape_motion[/code]).
</description>
</method>
</methods>
@@ -31464,7 +32408,7 @@ This method controls whether the position between two cached points is interpola
Skeleton for characters and animated objects.
</brief_description>
<description>
- Skeleton provides a hierachial interface for managing bones, including pose, rest and animation (see [Animation]). Skeleton will support rag doll dynamics in the future.
+ Skeleton provides a hierarchical interface for managing bones, including pose, rest and animation (see [Animation]). Skeleton will support rag doll dynamics in the future.
</description>
<methods>
<method name="add_bone">
@@ -31924,7 +32868,7 @@ This method controls whether the position between two cached points is interpola
<return type="Transform">
</return>
<description>
- Return the gloal transform, relative to worldspace.
+ Return the global transform, relative to worldspace.
</description>
</method>
<method name="get_parent_spatial" qualifiers="const">
@@ -32093,7 +33037,7 @@ This method controls whether the position between two cached points is interpola
</signals>
<constants>
<constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29">
- Spatial nodes receive this notifacation with their global transform changes. This means that either the current or a parent node changed its transform.
+ Spatial nodes receive this notification with their global transform changes. This means that either the current or a parent node changed its transform.
</constant>
<constant name="NOTIFICATION_ENTER_WORLD" value="41">
</constant>
@@ -32103,6 +33047,16 @@ This method controls whether the position between two cached points is interpola
</constant>
</constants>
</class>
+<class name="SpatialGizmo" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="SpatialPlayer" inherits="Spatial" category="Core">
<brief_description>
</brief_description>
@@ -32574,7 +33528,7 @@ This method controls whether the position between two cached points is interpola
</class>
<class name="SpotLight" inherits="Light" category="Core">
<brief_description>
- Spotlight [Light], such as a reflector spotlight or a latern.
+ Spotlight [Light], such as a reflector spotlight or a lantern.
</brief_description>
<description>
A SpotLight light is a type of [Light] node that emits lights in a specific direction, in the shape of a cone. The light is attenuated through the distance and this attenuation can be configured by changing the energy, radius and attenuation parameters of [Light]. TODO: Image of a spotlight.
@@ -32631,14 +33585,14 @@ This method controls whether the position between two cached points is interpola
<return type="Vector2">
</return>
<description>
- Return sprite draw offst.
+ Return sprite draw offset.
</description>
</method>
<method name="set_flip_h">
<argument index="0" name="flip_h" type="bool">
</argument>
<description>
- Set true to flip the sprite horizontaly.
+ Set true to flip the sprite horizontally.
</description>
</method>
<method name="is_flipped_h" qualifiers="const">
@@ -32715,7 +33669,7 @@ This method controls whether the position between two cached points is interpola
<return type="int">
</return>
<description>
- Return the amount of vertical frames. See [set_vframes].
+ Return the amount of vertical frames. See [method set_vframes].
</description>
</method>
<method name="set_hframes">
@@ -32729,7 +33683,7 @@ This method controls whether the position between two cached points is interpola
<return type="int">
</return>
<description>
- Return the amount of horizontal frames. See [set_hframes].
+ Return the amount of horizontal frames. See [method set_hframes].
</description>
</method>
<method name="set_modulate">
@@ -33118,7 +34072,7 @@ This method controls whether the position between two cached points is interpola
Static body for 2D Physics.
</brief_description>
<description>
- Static body for 2D Physics. A static body is a simple body that is not intended to move. They don't consume any CPU resources in contrast to a [RigidBody2D] so they are great for scenaro collision.
+ Static body for 2D Physics. A static body is a simple body that is not intended to move. They don't consume any CPU resources in contrast to a [RigidBody2D] so they are great for scenario collision.
A static body can also be animated by using simulated motion mode. This is useful for implementing functionalities such as moving platforms. When this mode is active the body can be animated and automatically computes linear and angular velocity to apply in that frame and to influence other bodies.
Alternatively, a constant linear or angular velocity can be set for the static body, so even if it doesn't move, it affects other bodies as if it was moving (this is useful for simulating conveyor belts or conveyor wheels).
</description>
@@ -33188,7 +34142,7 @@ This method controls whether the position between two cached points is interpola
Abstraction and base class for stream-based protocols.
</brief_description>
<description>
- StreamPeer is an abstration and base class for stream-based protocols (such as TCP or Unix Sockets). It provides an API for sending and receiving data through streams as raw data or strings.
+ StreamPeer is an abstraction and base class for stream-based protocols (such as TCP or Unix Sockets). It provides an API for sending and receiving data through streams as raw data or strings.
</description>
<methods>
<method name="put_data">
@@ -33197,7 +34151,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="data" type="RawArray">
</argument>
<description>
- Send a chunk of data through the connection, blocking if necesary until the data is done sending. This function returns an [Error] code.
+ Send a chunk of data through the connection, blocking if necessary until the data is done sending. This function returns an Error code.
</description>
</method>
<method name="put_partial_data">
@@ -33206,7 +34160,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="data" type="RawArray">
</argument>
<description>
- Send a chunk of data through the connection, if all the data could not be sent at once, only part of it will. This function returns two values, an [Error] code and an integer, describing how much data was actually sent.
+ Send a chunk of data through the connection, if all the data could not be sent at once, only part of it will. This function returns two values, an Error code and an integer, describing how much data was actually sent.
</description>
</method>
<method name="get_data">
@@ -33215,7 +34169,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="bytes" type="int">
</argument>
<description>
- Return a chunk data with the received bytes. The amount of bytes to be received can be requested in the "bytes" argument. If not enough bytes are available, the function will block until the desired amount is received. This function returns two values, an [Error] code and a data array.
+ Return a chunk data with the received bytes. The amount of bytes to be received can be requested in the "bytes" argument. If not enough bytes are available, the function will block until the desired amount is received. This function returns two values, an Error code and a data array.
</description>
</method>
<method name="get_partial_data">
@@ -33224,7 +34178,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="bytes" type="int">
</argument>
<description>
- Return a chunk data with the received bytes. The amount of bytes to be received can be requested in the "bytes" argument. If not enough bytes are available, the function will return how many were actually received. This function returns two values, an [Error] code, and a data array.
+ Return a chunk data with the received bytes. The amount of bytes to be received can be requested in the "bytes" argument. If not enough bytes are available, the function will return how many were actually received. This function returns two values, an Error code, and a data array.
</description>
</method>
<method name="get_available_bytes" qualifiers="const">
@@ -33596,7 +34550,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="db" type="float">
</argument>
<description>
- Set the playback volume for this player, in decibels. This is a float between -80.0 (silent) and 0.0 (full volume). Values under -79.0 get truncated to -80, but values over 0.0 do not, so the warnings for overamplifying (see [set_volume]) still apply.
+ Set the playback volume for this player, in decibels. This is a float between -80.0 (silent) and 0.0 (full volume). Values under -79.0 get truncated to -80, but values over 0.0 do not, so the warnings for overamplifying (see [method set_volume]) still apply.
</description>
</method>
<method name="get_volume_db" qualifiers="const">
@@ -33700,7 +34654,7 @@ This method controls whether the position between two cached points is interpola
Built-in string class.
</brief_description>
<description>
- This is the built-in string class (and the one used by GDScript). It supports Unicode and provides all necesary means for string handling. Strings are reference counted and use a copy-on-write approach, so passing them around is cheap in resources.
+ This is the built-in string class (and the one used by GDScript). It supports Unicode and provides all necessary means for string handling. Strings are reference counted and use a copy-on-write approach, so passing them around is cheap in resources.
</description>
<methods>
<method name="basename">
@@ -33744,7 +34698,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="to" type="String">
</argument>
<description>
- Perform a case-sensitive comparison to antoher string, return -1 if less, 0 if equal and +1 if greater.
+ Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
</description>
</method>
<method name="empty">
@@ -33769,7 +34723,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="from" type="int" default="0">
</argument>
<description>
- Find the first occurence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
+ Find the first occurrence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
</description>
</method>
<method name="find_last">
@@ -33778,7 +34732,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="what" type="String">
</argument>
<description>
- Find the last occurence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
+ Find the last occurrence of a substring, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
</description>
</method>
<method name="findn">
@@ -33789,7 +34743,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="from" type="int" default="0">
</argument>
<description>
- Find the first occurence of a substring but search as case-insensitive, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
+ Find the first occurrence of a substring but search as case-insensitive, return the starting position of the substring or -1 if not found. Optionally, the initial search index can be passed.
</description>
</method>
<method name="get_base_dir">
@@ -33937,7 +34891,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="to" type="String">
</argument>
<description>
- Perform a case-insensitive comparison to antoher string, return -1 if less, 0 if equal and +1 if greater.
+ Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
</description>
</method>
<method name="ord_at">
@@ -34015,7 +34969,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="from" type="int" default="-1">
</argument>
<description>
- Perform a search for a substring, but start from the end of the string instead of the begining.
+ Perform a search for a substring, but start from the end of the string instead of the beginning.
</description>
</method>
<method name="rfindn">
@@ -34026,7 +34980,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="from" type="int" default="-1">
</argument>
<description>
- Perform a search for a substring, but start from the end of the string instead of the begining. Also search case-insensitive.
+ Perform a search for a substring, but start from the end of the string instead of the beginning. Also search case-insensitive.
</description>
</method>
<method name="right">
@@ -34046,7 +35000,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="allow_empty" type="bool" default="True">
</argument>
<description>
- Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
+ Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return \["One","Two","Three"\] if split by ",".
</description>
</method>
<method name="split_floats">
@@ -34057,14 +35011,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="allow_empty" type="bool" default="True">
</argument>
<description>
- Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return [1,2.5,3] if split by ",".
+ Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return \[1,2.5,3\] if split by ",".
</description>
</method>
<method name="strip_edges">
<return type="String">
</return>
<description>
- Return a copy of the string stripped of any non-printable character at the begining and the end.
+ Return a copy of the string stripped of any non-printable character at the beginning and the end.
</description>
</method>
<method name="substr">
@@ -34200,7 +35154,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="rect" type="Rect2">
</argument>
<description>
- Test a position in a rectangle, return wether it pases the mask test.
+ Test a position in a rectangle, return whether it passes the mask test.
</description>
</method>
<method name="set_default_margin">
@@ -34247,7 +35201,7 @@ This method controls whether the position between two cached points is interpola
<return type="Vector2">
</return>
<description>
- Return the "offset" of a stylebox, this is a helper function, like writing Point2( style.get_margin(MARGIN_LEFT), style.get_margin(MARGIN_TOP) )
+ Return the "offset" of a stylebox, this is a helper function, like writing [code]Vector2(style.get_margin(MARGIN_LEFT), style.get_margin(MARGIN_TOP))[/code].
</description>
</method>
<method name="draw" qualifiers="const">
@@ -34363,7 +35317,7 @@ This method controls whether the position between two cached points is interpola
Image mask based StyleBox, for mask test.
</brief_description>
<description>
- This StyleBox is similar to [StyleBoxTexture], but only meant to be used for mask testing. It takes an image and applies stretch rules to determine if the poit clicked is masked or not.
+ This StyleBox is similar to [StyleBoxTexture], but only meant to be used for mask testing. It takes an image and applies stretch rules to determine if the point clicked is masked or not.
</description>
<methods>
<method name="set_image">
@@ -34377,7 +35331,7 @@ This method controls whether the position between two cached points is interpola
<return type="Image">
</return>
<description>
- Return the image used for mask testing. (see [method set_imag]).
+ Return the image used for mask testing. (see [method set_image]).
</description>
</method>
<method name="set_expand">
@@ -34391,7 +35345,7 @@ This method controls whether the position between two cached points is interpola
<return type="bool">
</return>
<description>
- Return wether the expand property is set(default). When expanding, the image will use the same rules as [StyleBoxTexture] for expand. If not expanding, the image will always be tested at its original size.
+ Return whether the expand property is set(default). When expanding, the image will use the same rules as [StyleBoxTexture] for expand. If not expanding, the image will always be tested at its original size.
</description>
</method>
<method name="set_expand_margin_size">
@@ -34706,7 +35660,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="title" type="String">
</argument>
<description>
- Set a title for the tab. Tab titles are by default the children node name, but this can be overriden.
+ Set a title for the tab. Tab titles are by default the children node name, but this can be overridden.
</description>
</method>
<method name="get_tab_title" qualifiers="const">
@@ -34715,7 +35669,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
- Return the title for the tab. Tab titles are by default the children node name, but this can be overriden.
+ Return the title for the tab. Tab titles are by default the children node name, but this can be overridden.
</description>
</method>
<method name="set_tab_icon">
@@ -35259,7 +36213,7 @@ This method controls whether the position between two cached points is interpola
Match whole words when searching.
</constant>
<constant name="SEARCH_BACKWARDS" value="4">
- Search from end to begining.
+ Search from end to beginning.
</constant>
</constants>
<theme_items>
@@ -35312,7 +36266,7 @@ This method controls whether the position between two cached points is interpola
Texture for 2D and 3D.
</brief_description>
<description>
- A texture works by registering an image in the video hardware, which then can be used in 3D models or 2D [Sprite] or GUI [Control]s.
+ A texture works by registering an image in the video hardware, which then can be used in 3D models or 2D [Sprite] or GUI [Control].
</description>
<methods>
<method name="get_width" qualifiers="const">
@@ -35973,7 +36927,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="userdata" type="var" default="NULL">
+ <argument index="2" name="userdata" type="Variant" default="NULL">
</argument>
<argument index="3" name="priority" type="int" default="1">
</argument>
@@ -35998,14 +36952,6 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
- <method name="set_name">
- <return type="Error">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
</methods>
<constants>
<constant name="PRIORITY_LOW" value="0">
@@ -36301,6 +37247,15 @@ This method controls whether the position between two cached points is interpola
Return the tile index of the referenced cell.
</description>
</method>
+ <method name="get_cellv" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="pos" type="Vector2">
+ </argument>
+ <description>
+ Return the tile index of the cell referenced by a Vector2.
+ </description>
+ </method>
<method name="is_cell_x_flipped" qualifiers="const">
<return type="bool">
</return>
@@ -36323,6 +37278,17 @@ This method controls whether the position between two cached points is interpola
Return whether the referenced cell is flipped over the Y axis.
</description>
</method>
+ <method name="is_cell_transposed" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="x" type="int">
+ </argument>
+ <argument index="1" name="y" type="int">
+ </argument>
+ <description>
+ Return whether the referenced cell is transposed, i.e. the X and Y axes are swapped (mirroring with regard to the (1,1) vector).
+ </description>
+ </method>
<method name="clear">
<description>
Clear all cells.
@@ -37583,7 +38549,7 @@ This method controls whether the position between two cached points is interpola
<method name="set_metadata">
<argument index="0" name="column" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -37753,7 +38719,9 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="button" type="Texture">
</argument>
- <argument index="2" name="button_idx" type="int">
+ <argument index="2" name="button_idx" type="int" default="-1">
+ </argument>
+ <argument index="3" name="disabled" type="bool" default="false">
</argument>
<description>
</description>
@@ -37784,6 +38752,16 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
+ <method name="is_button_disabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="button_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_tooltip">
<argument index="0" name="column" type="int">
</argument>
@@ -37824,62 +38802,81 @@ This method controls whether the position between two cached points is interpola
</class>
<class name="Tween" inherits="Node" category="Core">
<brief_description>
+ Node useful for animations with unknown start and end points.
</brief_description>
<description>
+ Node useful for animations with unknown start and end points, procedural animations, making one node follow another, and other simple behavior.
+ Because it is easy to get it wrong, here is a quick usage example:
+ [codeblock]
+ var tween = get_node("Tween")
+ tween.interpolate_property(get_node("Node2D_to_move"), "transform/pos", Vector2(0,0), Vector2(100,100), Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
+ tween.start()
+ [/codeblock]
+ Some of the methods of this class require a property name. You can get the property name by hovering over the property in the inspector of the editor.
+ Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an TRANS_* constant, and refers to the way the timing of the animation is handled (you might want to see [code]http://easings.net/[/code] for some examples). The second accepts an EASE_* constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the begining, the end, or both). If you don't know which transision and easing to pick, you can try different TRANS_* constants with EASE_IN_OUT, and use the one that looks best.
</description>
<methods>
<method name="is_active" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns true if any tweens are currently running, and false otherwise. Note that this method doesn't consider tweens that have ended.
</description>
</method>
<method name="set_active">
<argument index="0" name="active" type="bool">
</argument>
<description>
+ Activate/deactivate the tween. You can use this for pausing animations, though [method stop_all] and [method resume_all] might be more fit for this.
</description>
</method>
<method name="is_repeat" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns true if repeat has been set from editor GUI or [method set_repeat].
</description>
</method>
<method name="set_repeat">
<argument index="0" name="repeat" type="bool">
</argument>
<description>
+ Make the tween repeat after all tweens have finished.
</description>
</method>
<method name="set_speed">
<argument index="0" name="speed" type="float">
</argument>
<description>
+ Set the speed multiplier of the tween. Set it to 1 for normal speed, 2 for two times nromal speed, and 0.5 for half of the normal speed. Setting it to 0 would pause the animation, but you might consider using [method set_active] or [method stop_all] and [method resume_all] for this.
</description>
</method>
<method name="get_speed" qualifiers="const">
<return type="float">
</return>
<description>
+ Returns the speed that has been set from editor GUI or [method set_repeat].
</description>
</method>
<method name="set_tween_process_mode">
<argument index="0" name="mode" type="int">
</argument>
<description>
+ Set whether the Tween uses [code]_process[/code] or [code]_fixed_process[/code] (accepts TWEEN_PROCESS_IDLE and TWEEN_PROCESS_FIXED constants, respectively).
</description>
</method>
<method name="get_tween_process_mode" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the process mode that has been set from editor GUI or [method set_tween_process_mode]
</description>
</method>
<method name="start">
<return type="bool">
</return>
<description>
+ Start the tween node. You can define tweens both before and after this.
</description>
</method>
<method name="reset">
@@ -37890,12 +38887,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Resets a tween to the initial value (the one given, not the one before the tween), given its object and property/method pair.
</description>
</method>
<method name="reset_all">
<return type="bool">
</return>
<description>
+ Resets all tweens to their initial values (the ones given, not those before the tween).
</description>
</method>
<method name="stop">
@@ -37906,12 +38905,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Stop animating a tween, given its object and property/method pair.
</description>
</method>
<method name="stop_all">
<return type="bool">
</return>
<description>
+ Stop animating all tweens.
</description>
</method>
<method name="resume">
@@ -37922,12 +38923,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Continue animating a stopped tween, given its object and property/method pair.
</description>
</method>
<method name="resume_all">
<return type="bool">
</return>
<description>
+ Continue animating all stopped tweens.
</description>
</method>
<method name="remove">
@@ -37938,12 +38941,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Stop animating and completely remove a tween, given its object and property/method pair.
</description>
</method>
<method name="remove_all">
<return type="bool">
</return>
<description>
+ Stop animating and completely remove all tweens.
</description>
</method>
<method name="seek">
@@ -37952,18 +38957,21 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="time" type="float">
</argument>
<description>
+ Seek the animation to the given [code]time[/code] in seconds.
</description>
</method>
<method name="tell" qualifiers="const">
<return type="float">
</return>
<description>
+ Returns the current time of the tween.
</description>
</method>
<method name="get_runtime" qualifiers="const">
<return type="float">
</return>
<description>
+ Returns the time needed for all tweens to end in seconds, measured from the start. Thus, if you have two tweens, one ending 10 seconds after the start and the other - 20 seconds, it would return 20 seconds, as by that time all tweens would have finished.
</description>
</method>
<method name="interpolate_property">
@@ -37973,9 +38981,9 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="property" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
- <argument index="3" name="final_val" type="var">
+ <argument index="3" name="final_val" type="Variant">
</argument>
<argument index="4" name="times_in_sec" type="float">
</argument>
@@ -37986,6 +38994,8 @@ This method controls whether the position between two cached points is interpola
<argument index="7" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]property[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later.
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="interpolate_method">
@@ -37995,9 +39005,9 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
- <argument index="3" name="final_val" type="var">
+ <argument index="3" name="final_val" type="Variant">
</argument>
<argument index="4" name="times_in_sec" type="float">
</argument>
@@ -38008,6 +39018,8 @@ This method controls whether the position between two cached points is interpola
<argument index="7" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]method[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values.
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="interpolate_callback">
@@ -38019,17 +39031,18 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="callback" type="String">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg5" type="var" default="NULL">
+ <argument index="7" name="arg5" type="Variant" default="NULL">
</argument>
<description>
+ Call [code]callback[/code] of [code]object[/code] after [code]times_in_sec[/code]. [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
</description>
</method>
<method name="interpolate_deferred_callback">
@@ -38041,17 +39054,18 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="callback" type="String">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg5" type="var" default="NULL">
+ <argument index="7" name="arg5" type="Variant" default="NULL">
</argument>
<description>
+ Call [code]callback[/code] of [code]object[/code] after [code]times_in_sec[/code] on the main thread (similar to [methog Object.call_deferred). [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
</description>
</method>
<method name="follow_property">
@@ -38061,7 +39075,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="property" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
<argument index="3" name="target" type="Object">
</argument>
@@ -38076,6 +39090,8 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Follow [code]property[/code] of [code]object[/code] and apply it on [code]target_property[/code] of [code]target[/code], beginning from [code]initial_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later. Note that [code]target:target_property[/code] would equal [code]object:property[/code] at the end of the tween.
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="follow_method">
@@ -38085,7 +39101,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
<argument index="3" name="target" type="Object">
</argument>
@@ -38100,6 +39116,8 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Follow [code]method[/code] of [code]object[/code] and apply the returned value on [code]target_method[/code] of [code]target[/code], beginning from [code]initial_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] later. Methods are animated by calling them with consequitive values.
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="targeting_property">
@@ -38113,7 +39131,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="3" name="initial_val" type="String">
</argument>
- <argument index="4" name="final_val" type="var">
+ <argument index="4" name="final_val" type="Variant">
</argument>
<argument index="5" name="times_in_sec" type="float">
</argument>
@@ -38124,6 +39142,8 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]property[/code] of [code]object[/code] from the current value of the [code]initial_val[/code] property of [code]initial[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later.
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="targeting_method">
@@ -38137,7 +39157,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="3" name="initial_method" type="String">
</argument>
- <argument index="4" name="final_val" type="var">
+ <argument index="4" name="final_val" type="Variant">
</argument>
<argument index="5" name="times_in_sec" type="float">
</argument>
@@ -38148,6 +39168,8 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]method[/code] of [code]object[/code] from the value returned by [code]initial.initial_method[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values.
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
</methods>
@@ -38158,6 +39180,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ This signal is emitted when a tween ends.
</description>
</signal>
<signal name="tween_step">
@@ -38170,6 +39193,7 @@ This method controls whether the position between two cached points is interpola
<argument index="3" name="value" type="Object">
</argument>
<description>
+ This signal is emitted each step of the tweening.
</description>
</signal>
<signal name="tween_start">
@@ -38178,50 +39202,74 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ This signal is emitted when a tween starts.
</description>
</signal>
</signals>
<constants>
<constant name="TWEEN_PROCESS_FIXED" value="0">
+ The [Tween] should use [code]_fixed_process[/code] for timekeeping when this is enabled.
</constant>
<constant name="TWEEN_PROCESS_IDLE" value="1">
+ The [Tween] should use [code]_process[/code] for timekeeping when this is enabled (default).
</constant>
<constant name="TRANS_LINEAR" value="0">
+ Means that the animation is interpolated linearly.
</constant>
<constant name="TRANS_SINE" value="1">
+ Means that the animation is interpolated using a sine wave.
</constant>
<constant name="TRANS_QUINT" value="2">
+ Means that the animation is interpolated with a quinary (to the power of 5) function.
</constant>
<constant name="TRANS_QUART" value="3">
+ Means that the animation is interpolated with a quartic (to the power of 4) function.
</constant>
<constant name="TRANS_QUAD" value="4">
+ Means that the animation is interpolated with a quadratic (to the power of 2) function.
</constant>
<constant name="TRANS_EXPO" value="5">
+ Means that the animation is interpolated with a exponential (some number to the power of x) function.
</constant>
<constant name="TRANS_ELASTIC" value="6">
+ Means that the animation is interpolated with elasticity, wiggling around the edges.
</constant>
<constant name="TRANS_CUBIC" value="7">
+ Means that the animation is interpolated with a cubic (to the power of 3) function.
</constant>
<constant name="TRANS_CIRC" value="8">
+ Means that the animation is interpolated with a function using square roots.
</constant>
<constant name="TRANS_BOUNCE" value="9">
+ Means that the animation is interpolated by bouncing at, but never surpassing, the end.
</constant>
<constant name="TRANS_BACK" value="10">
+ Means that the animation is interpolated backing out at edges.
</constant>
<constant name="EASE_IN" value="0">
+ Signifies that the interpolation should be focused in the beginning.
</constant>
<constant name="EASE_OUT" value="1">
+ Signifies that the interpolation should be focused in the end.
</constant>
<constant name="EASE_IN_OUT" value="2">
+ Signifies that the interpolation should be focused in both ends.
</constant>
<constant name="EASE_OUT_IN" value="3">
+ Signifies that the interpolation should be focused in both ends, but they should be switched (a bit hard to explain, try it for yourself to be sure).
</constant>
</constants>
</class>
<class name="UndoRedo" inherits="Object" category="Core">
<brief_description>
+ Helper to manage UndoRedo in the editor or custom tools.
</brief_description>
<description>
+ Helper to maange UndoRedo in the editor or custom tools. It works by
+ storing calls to functions in both 'do' an 'undo' lists.
+
+ Common behavior is to create an action, then add do/undo calls to
+ functions or property changes, then commiting the action.
</description>
<methods>
<method name="create_action">
@@ -38230,10 +39278,16 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="mergeable" type="bool" default="false">
</argument>
<description>
+ Create a new action. After this is called, do all
+ your calls to [method add_do_method],
+ [method add_undo_method], [method add_do_property]
+ and [method add_undo_property].
</description>
</method>
<method name="commit_action">
<description>
+ Commit the action. All 'do' methods/properties are
+ called/set when this function is called.
</description>
</method>
<method name="add_do_method">
@@ -38241,17 +39295,19 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="arg0" type="var" default="NULL">
+ <argument index="2" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
<description>
+ Add a call to a method in a given object with custom
+ arguments.
</description>
</method>
<method name="add_undo_method">
@@ -38259,17 +39315,20 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="arg0" type="var" default="NULL">
+ <argument index="2" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
<description>
+ Add a call to an undo method in a given object with
+ custom arguments. Undo calls are used to revert 'do'
+ calls.
</description>
</method>
<method name="add_do_property">
@@ -38280,6 +39339,7 @@ This method controls whether the position between two cached points is interpola
<argument index="2" name="value" type="Variant">
</argument>
<description>
+ Set a property with a custom value.
</description>
</method>
<method name="add_undo_property">
@@ -38290,34 +39350,51 @@ This method controls whether the position between two cached points is interpola
<argument index="2" name="value" type="Variant">
</argument>
<description>
+ Undo setting of a property with a custom value.
</description>
</method>
<method name="add_do_reference">
<argument index="0" name="object" type="Object">
</argument>
<description>
+ Add a 'do' reference that will be erased if the 'do'
+ history is lost. This is useful mostly for new nodes
+ created for the 'do' call. Do not use for resources.
</description>
</method>
<method name="add_undo_reference">
<argument index="0" name="object" type="Object">
</argument>
<description>
+ Add an 'undo' reference that will be erased if the
+ 'undo' history is lost. This is useful mostly for
+ nodes rmoved with the 'do' call (not the 'undo'
+ call!).
</description>
</method>
<method name="clear_history">
<description>
+ Clear the undo/redo history and associated
+ references.
</description>
</method>
<method name="get_current_action_name" qualifiers="const">
<return type="String">
</return>
<description>
+ Get the name of the current action.
</description>
</method>
<method name="get_version" qualifiers="const">
<return type="int">
</return>
<description>
+ Get the version, each time a new action is commited,
+ the version number of the UndoRedo is increased
+ automatically.
+
+ This is useful mostly to check if something changed
+ from a saved version.
</description>
</method>
</methods>
@@ -39297,7 +40374,7 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
- <method name="get_video_texutre">
+ <method name="get_video_texture">
<return type="Texture">
</return>
<description>
@@ -39412,7 +40489,7 @@ This method controls whether the position between two cached points is interpola
<return type="Rect2">
</return>
<description>
- Return the final, visuble rect in global screen coordinates.
+ Return the final, visible rect in global screen coordinates.
</description>
</method>
<method name="set_transparent_background">
@@ -39426,7 +40503,7 @@ This method controls whether the position between two cached points is interpola
<return type="bool">
</return>
<description>
- Reurn whether the viewport lets whatever is behind it to show.
+ Return whether the viewport lets whatever is behind it to show.
</description>
</method>
<method name="set_size_override">
@@ -40042,7 +41119,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="arg1" type="String">
</argument>
- <argument index="2" name="arg2" type="var">
+ <argument index="2" name="arg2" type="Variant">
</argument>
<description>
</description>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
new file mode 100644
index 0000000000..6311be767c
--- /dev/null
+++ b/doc/tools/makerst.py
@@ -0,0 +1,518 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import sys
+import xml.etree.ElementTree as ET
+
+input_list = []
+
+for arg in sys.argv[1:]:
+ input_list.append(arg)
+
+if len(input_list) < 1:
+ print 'usage: makerst.py <classes.xml>'
+ sys.exit(0)
+
+
+def validate_tag(elem, tag):
+ if elem.tag != tag:
+ print "Tag mismatch, expected '" + tag + "', got " + elem.tag
+ sys.exit(255)
+
+
+class_names = []
+classes = {}
+
+def ul_string(str,ul):
+ str+="\n"
+ for i in range(len(str)-1):
+ str+=ul
+ str+="\n"
+ return str
+
+def make_class_list(class_list, columns):
+
+ f = open('class_list.rst', 'wb')
+ prev = 0
+ col_max = len(class_list) / columns + 1
+ print ('col max is ', col_max)
+ col_count = 0
+ row_count = 0
+ last_initial = ''
+ fit_columns = []
+
+ for n in range(0, columns):
+ fit_columns += [[]]
+
+ indexers = []
+ last_initial = ''
+
+ idx = 0
+ for n in class_list:
+ col = idx / col_max
+ if col >= columns:
+ col = columns - 1
+ fit_columns[col] += [n]
+ idx += 1
+ if n[:1] != last_initial:
+ indexers += [n]
+ last_initial = n[:1]
+
+ row_max = 0
+ f.write("\n")
+
+ for n in range(0, columns):
+ if len(fit_columns[n]) > row_max:
+ row_max = len(fit_columns[n])
+
+ f.write("| ")
+ for n in range(0, columns):
+ f.write(" | |")
+
+ f.write("\n")
+ f.write("+")
+ for n in range(0, columns):
+ f.write("--+-------+")
+ f.write("\n")
+
+ for r in range(0, row_max):
+ s = '+ '
+ for c in range(0, columns):
+ if r >= len(fit_columns[c]):
+ continue
+
+ classname = fit_columns[c][r]
+ initial = classname[0]
+ if classname in indexers:
+ s += '**' + initial + '** | '
+ else:
+ s += ' | '
+
+ s += '[' + classname + '](class_'+ classname.lower()+') | '
+
+ s += '\n'
+ f.write(s)
+
+ for n in range(0, columns):
+ f.write("--+-------+")
+ f.write("\n")
+
+
+def rstize_text(text,cclass):
+
+ # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock"
+ pos = 0
+ while True:
+ pos = text.find('\n', pos)
+ if pos == -1:
+ break
+
+ pre_text = text[:pos]
+ while text[pos+1] == '\t':
+ pos += 1
+ post_text = text[pos+1:]
+
+ # Handle codeblocks
+ if post_text.startswith("[codeblock]"):
+ end_pos = post_text.find("[/codeblock]")
+ if end_pos == -1:
+ sys.exit("ERROR! [codeblock] without a closing tag!")
+
+ code_text = post_text[len("[codeblock]"):end_pos]
+ post_text = post_text[end_pos:]
+
+ # Remove extraneous tabs
+ code_pos = 0
+ while True:
+ code_pos = code_text.find('\n', code_pos)
+ if code_pos == -1:
+ break
+
+ to_skip = 0
+ while code_pos+to_skip+1 < len(code_text) and code_text[code_pos+to_skip+1] == '\t':
+ to_skip += 1
+
+ if len(code_text[code_pos+to_skip+1:])==0:
+ code_text = code_text[:code_pos] + "\n"
+ code_pos += 1
+ else:
+ code_text = code_text[:code_pos] + "\n " + code_text[code_pos+to_skip+1:]
+ code_pos += 5 - to_skip
+
+ text = pre_text + "\n[codeblock]" + code_text + post_text
+ pos += len("\n[codeblock]" + code_text)
+
+ # Handle normal text
+ else:
+ text = pre_text + "\n\n" + post_text
+ pos += 2
+
+ # Escape * character to avoid interpreting it as emphasis
+ pos = 0
+ while True:
+ pos = text.find('*', pos)
+ if pos == -1:
+ break
+ text = text[:pos] + "\*" + text[pos + 1:]
+ pos += 2
+
+ # Escape _ character at the end of a word to avoid interpreting it as an inline hyperlink
+ pos = 0
+ while True:
+ pos = text.find('_', pos)
+ if pos == -1:
+ break
+ if not text[pos + 1].isalnum(): # don't escape within a snake_case word
+ text = text[:pos] + "\_" + text[pos + 1:]
+ pos += 2
+ else:
+ pos += 1
+
+ # Handle [tags]
+ pos = 0
+ while True:
+ pos = text.find('[', pos)
+ if pos == -1:
+ break
+
+ endq_pos = text.find(']', pos + 1)
+ if endq_pos == -1:
+ break
+
+ pre_text = text[:pos]
+ post_text = text[endq_pos + 1:]
+ tag_text = text[pos + 1:endq_pos]
+
+ if tag_text in class_names:
+ tag_text = make_type(tag_text)
+ else: # command
+ cmd = tag_text
+ space_pos = tag_text.find(' ')
+ if cmd.find('html') == 0:
+ cmd = tag_text[:space_pos]
+ param = tag_text[space_pos + 1:]
+ tag_text = param
+ elif cmd.find('method') == 0:
+ cmd = tag_text[:space_pos]
+ param = tag_text[space_pos + 1:]
+
+ if param.find('.') != -1:
+ (class_param, method_param) = param.split('.')
+ tag_text = ':ref:`'+class_param+'.'+method_param+'<class_' + class_param + '_' + method_param + '>`'
+ else:
+ tag_text = ':ref:`' + param + '<class_' + cclass +"_"+ param + '>`'
+ elif cmd.find('image=') == 0:
+ tag_text = "" #'![](' + cmd[6:] + ')'
+ elif cmd.find('url=') == 0:
+ tag_text = ':ref:`' + cmd[4:] + '<'+cmd[4:]+">`"
+ elif cmd == '/url':
+ tag_text = ')'
+ elif cmd == 'center':
+ tag_text = ''
+ elif cmd == '/center':
+ tag_text = ''
+ elif cmd == 'codeblock':
+ tag_text = '\n::\n'
+ elif cmd == '/codeblock':
+ tag_text = ''
+ # Strip newline if the tag was alone on one
+ if pre_text[-1] == '\n':
+ pre_text = pre_text[:-1]
+ elif cmd == 'br':
+ # Make a new paragraph instead of a linebreak, rst is not so linebreak friendly
+ tag_text = '\n\n'
+ # Strip potential leading spaces
+ while post_text[0] == ' ':
+ post_text = post_text[1:]
+ elif cmd == 'i' or cmd == '/i':
+ tag_text = '*'
+ elif cmd == 'b' or cmd == '/b':
+ tag_text = '**'
+ elif cmd == 'u' or cmd == '/u':
+ tag_text = ''
+ elif cmd == 'code' or cmd == '/code':
+ tag_text = '``'
+ else:
+ tag_text = ':ref:`' + tag_text + '<class_'+tag_text.lower()+'>`'
+
+ text = pre_text + tag_text + post_text
+ pos = len(pre_text) + len(tag_text)
+
+ # tnode = ET.SubElement(parent,"div")
+ # tnode.text=text
+
+ return text
+
+
+def make_type(t):
+ global class_names
+ if t in class_names:
+ return ':ref:`'+t+'<class_' + t.lower()+'>`'
+ return t
+
+
+def make_method(
+ f,
+ name,
+ m,
+ declare,
+ cname,
+ event=False,
+ pp=None
+ ):
+
+ if (declare or pp==None):
+ t = '- '
+ else:
+ t = ""
+
+ ret_type = 'void'
+ args = list(m)
+ mdata = {}
+ mdata['argidx'] = []
+ for a in args:
+ if a.tag == 'return':
+ idx = -1
+ elif a.tag == 'argument':
+ idx = int(a.attrib['index'])
+ else:
+ continue
+
+ mdata['argidx'].append(idx)
+ mdata[idx] = a
+
+ if not event:
+ if -1 in mdata['argidx']:
+ t += make_type(mdata[-1].attrib['type'])
+ else:
+ t += 'void'
+ t += ' '
+
+ if declare or pp==None:
+
+ # span.attrib["class"]="funcdecl"
+ # a=ET.SubElement(span,"a")
+ # a.attrib["name"]=name+"_"+m.attrib["name"]
+ # a.text=name+"::"+m.attrib["name"]
+
+ s = ' **'+m.attrib['name']+'** '
+ else:
+ s = ':ref:`'+ m.attrib['name']+'<class_' + cname+"_"+m.attrib['name'] + '>` '
+
+ s += ' **(**'
+ argfound = False
+ for a in mdata['argidx']:
+ arg = mdata[a]
+ if a < 0:
+ continue
+ if a > 0:
+ s += ', '
+ else:
+ s += ' '
+
+ s += make_type(arg.attrib['type'])
+ if 'name' in arg.attrib:
+ s += ' ' + arg.attrib['name']
+ else:
+ s += ' arg' + str(a)
+
+ if 'default' in arg.attrib:
+ s += '=' + arg.attrib['default']
+
+ argfound = True
+
+ if argfound:
+ s += ' '
+ s += ' **)**'
+
+ if 'qualifiers' in m.attrib:
+ s += ' ' + m.attrib['qualifiers']
+
+# f.write(s)
+ if (not declare):
+ if (pp!=None):
+ pp.append( (t,s) )
+ else:
+ f.write("- "+t+" "+s+"\n")
+ else:
+ f.write(t+s+"\n")
+
+
+def make_heading(title, underline):
+ return title + '\n' + underline*len(title) + "\n\n"
+
+
+
+def make_rst_class(node):
+
+ name = node.attrib['name']
+
+ f = open("class_"+name.lower() + '.rst', 'wb')
+
+ # Warn contributors not to edit this file directly
+ f.write(".. Generated automatically by doc/tools/makerst.py in Godot's source tree.\n")
+ f.write(".. DO NOT EDIT THIS FILE, but the doc/base/classes.xml source instead.\n\n")
+
+ f.write(".. _class_"+name+":\n\n")
+ f.write(make_heading(name, '='))
+
+ if 'inherits' in node.attrib:
+ inh = node.attrib['inherits'].strip()
+# whle inh in classes[cn]
+ f.write('**Inherits:** ')
+ first=True
+ while(inh in classes):
+ if (not first):
+ f.write(" **<** ")
+ else:
+ first=False
+
+ f.write(make_type(inh))
+ inode = classes[inh]
+ if ('inherits' in inode.attrib):
+ inh=inode.attrib['inherits'].strip()
+ else:
+ inh=None
+
+
+ f.write("\n\n")
+
+ inherited=[]
+ for cn in classes:
+ c=classes[cn]
+ if 'inherits' in c.attrib:
+ if (c.attrib['inherits'].strip()==name):
+ inherited.append(c.attrib['name'])
+
+ if (len(inherited)):
+ f.write('**Inherited By:** ')
+ for i in range(len(inherited)):
+ if (i>0):
+ f.write(", ")
+ f.write(make_type(inherited[i]))
+ f.write("\n\n")
+ if 'category' in node.attrib:
+ f.write('**Category:** ' + node.attrib['category'].strip() + "\n\n")
+
+ f.write(make_heading('Brief Description', '-'))
+ briefd = node.find('brief_description')
+ if briefd != None:
+ f.write(rstize_text(briefd.text.strip(),name) + "\n\n")
+
+ methods = node.find('methods')
+
+ if methods != None and len(list(methods)) > 0:
+ f.write(make_heading('Member Functions', '-'))
+ ml=[]
+ for m in list(methods):
+ make_method(f, node.attrib['name'], m, False,name,False,ml)
+ longest_t = 0
+ longest_s = 0
+ for s in ml:
+ sl = len(s[0])
+ if (sl>longest_s):
+ longest_s=sl
+ tl = len(s[1])
+ if (tl>longest_t):
+ longest_t=tl
+
+ sep="+"
+ for i in range(longest_s+2):
+ sep+="-"
+ sep+="+"
+ for i in range(longest_t+2):
+ sep+="-"
+ sep+="+\n"
+ f.write(sep)
+ for s in ml:
+ rt = s[0]
+ while( len(rt) < longest_s ):
+ rt+=" "
+ st = s[1]
+ while( len(st) < longest_t ):
+ st+=" "
+ f.write("| "+rt+" | "+st+" |\n")
+ f.write(sep)
+ f.write('\n')
+
+
+ events = node.find('signals')
+ if events != None and len(list(events)) > 0:
+ f.write(make_heading('Signals', '-'))
+ for m in list(events):
+ make_method(f, node.attrib['name'], m, True,name, True)
+ f.write('\n')
+
+ members = node.find('members')
+ if members != None and len(list(members)) > 0:
+ f.write(make_heading('Member Variables', '-'))
+
+ for c in list(members):
+ s = '- '
+ s += make_type(c.attrib['type']) + ' '
+ s += '**' + c.attrib['name'] + '**'
+ if c.text.strip() != '':
+ s += ' - ' + c.text.strip()
+ f.write(s + '\n')
+ f.write('\n')
+
+ constants = node.find('constants')
+ if constants != None and len(list(constants)) > 0:
+ f.write(make_heading('Numeric Constants', '-'))
+ for c in list(constants):
+ s = '- '
+ s += '**' + c.attrib['name'] + '**'
+ if 'value' in c.attrib:
+ s += ' = **' + c.attrib['value'] + '**'
+ if c.text.strip() != '':
+ s += ' --- ' + rstize_text(c.text.strip(),name)
+ f.write(s + '\n')
+ f.write('\n')
+
+ descr = node.find('description')
+ if descr != None and descr.text.strip() != '':
+ f.write(make_heading('Description', '-'))
+ f.write(rstize_text(descr.text.strip(),name) + "\n\n")
+
+ methods = node.find('methods')
+ if methods != None and len(list(methods)) > 0:
+ f.write(make_heading('Member Function Description', '-'))
+ for m in list(methods):
+ f.write(".. _class_"+name+"_"+m.attrib['name']+":\n\n")
+# f.write(ul_string(m.attrib['name'],"^"))
+ #f.write('\n<a name="'+m.attrib['name']+'">' + m.attrib['name'] + '</a>\n------\n')
+ make_method(f, node.attrib['name'], m, True,name)
+ f.write('\n')
+ d = m.find('description')
+ if d == None or d.text.strip() == '':
+ continue
+ f.write(rstize_text(d.text.strip(),name))
+ f.write("\n\n")
+ f.write('\n')
+
+
+for file in input_list:
+ tree = ET.parse(file)
+ doc = tree.getroot()
+
+ if 'version' not in doc.attrib:
+ print "Version missing from 'doc'"
+ sys.exit(255)
+
+ version = doc.attrib['version']
+
+ for c in list(doc):
+ if c.attrib['name'] in class_names:
+ continue
+ class_names.append(c.attrib['name'])
+ classes[c.attrib['name']] = c
+
+class_names.sort()
+
+#Don't make class list for Sphinx, :toctree: handles it
+#make_class_list(class_names, 2)
+
+for cn in class_names:
+ c = classes[cn]
+ make_rst_class(c)
+
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 23d5860d2a..f9b58939dc 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -4781,9 +4781,12 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD
if (has_blend_alpha || (has_base_alpha && m->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA))
return; //bye
- if (m->shader_cache && !m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && m->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA) {
+ if (!m->shader_cache || (!m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && m->depth_draw_mode!=VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA)) {
//shader does not use discard and does not write a vertex position, use generic material
- m = shadow_mat_ptr;
+ if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)
+ m = shadow_mat_double_sided_ptr;
+ else
+ m = shadow_mat_ptr;
if (m->last_pass!=frame) {
if (m->shader.is_valid()) {
@@ -6368,6 +6371,8 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
uint8_t prev_sort_flags=0xFF;
const BakedLightData *prev_baked_light=NULL;
RID prev_baked_light_texture;
+ const float *prev_morph_values=NULL;
+ int prev_receive_shadows_state=-1;
Geometry::Type prev_geometry_type=Geometry::GEOMETRY_INVALID;
@@ -6406,6 +6411,8 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
const Skeleton *skeleton = e->skeleton;
const Geometry *geometry_cmp = e->geometry_cmp;
const BakedLightData *baked_light = e->instance->baked_light;
+ const float *morph_values = e->instance->morph_values.ptr();
+ int receive_shadows_state = e->instance->receive_shadows == true ? 1 : 0;
bool rebind=false;
bool bind_baked_light_octree=false;
@@ -6428,6 +6435,8 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
prev_overrides=NULL; // make it diferent than NULL
prev_skeleton =NULL;
prev_sort_flags=0xFF;
+ prev_morph_values=NULL;
+ prev_receive_shadows_state=-1;
prev_geometry_type=Geometry::GEOMETRY_INVALID;
glEnable(GL_BLEND);
glDepthMask(GL_TRUE);
@@ -6436,7 +6445,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
}
- if (light_type!=prev_light_type) {
+ if (light_type!=prev_light_type || receive_shadows_state!=prev_receive_shadows_state) {
if (material->flags[VS::MATERIAL_FLAG_UNSHADED] || current_debug==VS::SCENARIO_DEBUG_SHADELESS) {
material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL,false);
@@ -6450,9 +6459,16 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL,(light_type&0x3)==VS::LIGHT_DIRECTIONAL);
material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_OMNI,(light_type&0x3)==VS::LIGHT_OMNI);
material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,(light_type&0x3)==VS::LIGHT_SPOT);
- material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,(light_type&0x8));
- material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,(light_type&0x10));
- material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,(light_type&0x20));
+ if (receive_shadows_state==1) {
+ material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,(light_type&0x8));
+ material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,(light_type&0x10));
+ material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,(light_type&0x20));
+ }
+ else {
+ material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false);
+ material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false);
+ material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,false);
+ }
material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false);
}
@@ -6650,10 +6666,15 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
}
rebind=true;
}
- if (use_hw_skeleton_xform && skeleton!=prev_skeleton) {
+
+ if (use_hw_skeleton_xform && (skeleton!=prev_skeleton||morph_values!=prev_morph_values)) {
if (!prev_skeleton || !skeleton)
rebind=true; //went from skeleton <-> no skeleton, needs rebind
- _setup_skeleton(skeleton);
+
+ if (morph_values==NULL)
+ _setup_skeleton(skeleton);
+ else
+ _setup_skeleton(NULL);
}
if (material!=prev_material || rebind) {
@@ -6726,10 +6747,6 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (i==0 || rebind) {
material_shader.set_uniform(MaterialShaderGLES2::CAMERA_INVERSE_TRANSFORM, p_view_transform_inverse);
material_shader.set_uniform(MaterialShaderGLES2::PROJECTION_TRANSFORM, p_projection);
- if (skeleton && use_hw_skeleton_xform) {
- material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES,GL_TEXTURE0+max_texture_units-2);
- material_shader.set_uniform(MaterialShaderGLES2::SKELTEX_PIXEL_SIZE,skeleton->pixel_size);
- }
if (!shadow) {
if (!additive && current_env && current_env->fx_enabled[VS::ENV_FX_AMBIENT_LIGHT]) {
@@ -6744,6 +6761,13 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
_rinfo.shader_change_count++;
}
+ if (skeleton != prev_skeleton || rebind) {
+ if (skeleton && morph_values == NULL) {
+ material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES, max_texture_units - 2);
+ material_shader.set_uniform(MaterialShaderGLES2::SKELTEX_PIXEL_SIZE, skeleton->pixel_size);
+ }
+ }
+
if (e->instance->billboard || e->instance->depth_scale) {
Transform xf=e->instance->transform;
@@ -6795,7 +6819,9 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
prev_light_type=e->light_type;
prev_sort_flags=sort_flags;
prev_baked_light=baked_light;
+ prev_morph_values=morph_values;
// prev_geometry_type=geometry->type;
+ prev_receive_shadows_state=receive_shadows_state;
}
//print_line("shaderchanges: "+itos(p_alpha_pass)+": "+itos(_rinfo.shader_change_count));
@@ -7099,11 +7125,13 @@ void RasterizerGLES2::_draw_tex_bg() {
copy_shader.set_uniform(CopyShaderGLES2::ENERGY,nrg);
copy_shader.set_uniform(CopyShaderGLES2::CUSTOM_ALPHA,float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]));
+ float flip_sign = (current_env->bg_mode==VS::ENV_BG_TEXTURE && current_rt && current_rt_vflip)?-1:1;
+
Vector3 vertices[4]={
- Vector3(-1,-1,1),
- Vector3( 1,-1,1),
- Vector3( 1, 1,1),
- Vector3(-1, 1,1)
+ Vector3(-1,-1*flip_sign,1),
+ Vector3( 1,-1*flip_sign,1),
+ Vector3( 1, 1*flip_sign,1),
+ Vector3(-1, 1*flip_sign,1)
};
@@ -7249,7 +7277,7 @@ void RasterizerGLES2::end_scene() {
bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR];
else
bgcolor = Globals::get_singleton()->get("render/default_clear_color");
- bgcolor = _convert_color(bgcolor);
+ bgcolor = _convert_color(bgcolor);
float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0;
glClearColor(bgcolor.r,bgcolor.g,bgcolor.b,a);
_glClearDepth(1.0);
@@ -10828,7 +10856,6 @@ void RasterizerGLES2::init() {
use_depth24 =true;
s3tc_supported = true;
atitc_supported = false;
- use_hw_skeleton_xform = false;
// use_texture_instancing=false;
// use_attribute_instancing=true;
use_texture_instancing=false;
@@ -10839,7 +10866,11 @@ void RasterizerGLES2::init() {
s3tc_srgb_supported=true;
use_anisotropic_filter=true;
float_linear_supported=true;
- float_supported=true;
+
+ GLint vtf;
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,&vtf);
+ float_supported = extensions.has("GL_OES_texture_float") || extensions.has("GL_ARB_texture_float");
+ use_hw_skeleton_xform=vtf>0 && float_supported;
read_depth_supported=_test_depth_shadow_buffer();
use_rgba_shadowmaps=!read_depth_supported;
@@ -10889,7 +10920,7 @@ void RasterizerGLES2::init() {
GLint vtf;
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,&vtf);
- float_supported = extensions.has("GL_OES_texture_float");
+ float_supported = extensions.has("GL_OES_texture_float") || extensions.has("GL_ARB_texture_float");
use_hw_skeleton_xform=vtf>0 && float_supported;
float_linear_supported = extensions.has("GL_OES_texture_float_linear");
@@ -10922,7 +10953,6 @@ void RasterizerGLES2::init() {
//etc_supported=false;
- use_hw_skeleton_xform=false;
#endif
@@ -10964,6 +10994,12 @@ void RasterizerGLES2::init() {
shadow_material = material_create(); //empty with nothing
shadow_mat_ptr = material_owner.get(shadow_material);
+
+ // Now create a second shadow material for double-sided shadow instances
+ shadow_material_double_sided = material_create();
+ shadow_mat_double_sided_ptr = material_owner.get(shadow_material_double_sided);
+ shadow_mat_double_sided_ptr->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED] = true;
+
overdraw_material = create_overdraw_debug_material();
copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR,!use_fp16_fb);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS,read_depth_supported);
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 0f70ceaa97..2a2f587f11 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -829,7 +829,9 @@ class RasterizerGLES2 : public Rasterizer {
bool fragment_lighting;
RID shadow_material;
+ RID shadow_material_double_sided;
Material *shadow_mat_ptr;
+ Material *shadow_mat_double_sided_ptr;
int max_texture_units;
GLuint base_framebuffer;
diff --git a/drivers/jpegd/image_loader_jpegd.cpp b/drivers/jpegd/image_loader_jpegd.cpp
index 9d1263b81b..5339e9f69d 100644
--- a/drivers/jpegd/image_loader_jpegd.cpp
+++ b/drivers/jpegd/image_loader_jpegd.cpp
@@ -17,23 +17,9 @@
#include <string.h>
-Error ImageLoaderJPG::load_image(Image *p_image,FileAccess *f) {
-
-
- DVector<uint8_t> src_image;
- int src_image_len = f->get_len();
- ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
- src_image.resize(src_image_len);
-
- DVector<uint8_t>::Write w = src_image.write();
-
- f->get_buffer(&w[0],src_image_len);
-
- f->close();
-
+Error jpeg_load_image_from_buffer(Image *p_image,const uint8_t* p_buffer, int p_buffer_len) {
-
- jpgd::jpeg_decoder_mem_stream mem_stream(w.ptr(),src_image_len);
+ jpgd::jpeg_decoder_mem_stream mem_stream(p_buffer,p_buffer_len);
jpgd::jpeg_decoder decoder(&mem_stream);
@@ -85,14 +71,36 @@ Error ImageLoaderJPG::load_image(Image *p_image,FileAccess *f) {
fmt=Image::FORMAT_RGBA;
dw = DVector<uint8_t>::Write();
- w = DVector<uint8_t>::Write();
-
p_image->create(image_width,image_height,0,fmt,data);
return OK;
}
+
+Error ImageLoaderJPG::load_image(Image *p_image,FileAccess *f) {
+
+
+ DVector<uint8_t> src_image;
+ int src_image_len = f->get_len();
+ ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
+ src_image.resize(src_image_len);
+
+ DVector<uint8_t>::Write w = src_image.write();
+
+ f->get_buffer(&w[0],src_image_len);
+
+ f->close();
+
+
+ Error err = jpeg_load_image_from_buffer(p_image,w.ptr(),src_image_len);
+
+ w = DVector<uint8_t>::Write();
+
+ return err;
+
+}
+
void ImageLoaderJPG::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("jpg");
@@ -100,9 +108,17 @@ void ImageLoaderJPG::get_recognized_extensions(List<String> *p_extensions) const
}
-ImageLoaderJPG::ImageLoaderJPG() {
+static Image _jpegd_mem_loader_func(const uint8_t* p_png,int p_size) {
+
+ Image img;
+ Error err = jpeg_load_image_from_buffer(&img,p_png,p_size);
+ return img;
+}
+
+ImageLoaderJPG::ImageLoaderJPG() {
+ Image::_jpg_mem_loader_func=_jpegd_mem_loader_func;
}
diff --git a/drivers/nrex/regex.cpp b/drivers/nrex/regex.cpp
index 459cf28e1e..5d6c9583ef 100644
--- a/drivers/nrex/regex.cpp
+++ b/drivers/nrex/regex.cpp
@@ -21,6 +21,7 @@ void RegEx::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid);
ObjectTypeDB::bind_method(_MD("get_capture_count"),&RegEx::get_capture_count);
ObjectTypeDB::bind_method(_MD("get_capture","capture"),&RegEx::get_capture);
+ ObjectTypeDB::bind_method(_MD("get_capture_start","capture"),&RegEx::get_capture_start);
ObjectTypeDB::bind_method(_MD("get_captures"),&RegEx::_bind_get_captures);
};
@@ -68,6 +69,14 @@ String RegEx::get_capture(int capture) const {
}
+int RegEx::get_capture_start(int capture) const {
+
+ ERR_FAIL_COND_V( get_capture_count() <= capture, -1 );
+
+ return captures[capture].start;
+
+}
+
Error RegEx::compile(const String& p_pattern, int capture) {
clear();
diff --git a/drivers/nrex/regex.h b/drivers/nrex/regex.h
index ae8d40ceab..4b063f0bf1 100644
--- a/drivers/nrex/regex.h
+++ b/drivers/nrex/regex.h
@@ -35,6 +35,7 @@ public:
void clear();
bool is_valid() const;
int get_capture_count() const;
+ int get_capture_start(int capture) const;
String get_capture(int capture) const;
Error compile(const String& p_pattern, int capture = 9);
int find(const String& p_text, int p_start = 0, int p_end = -1) const;
diff --git a/drivers/openssl/stream_peer_openssl.cpp b/drivers/openssl/stream_peer_openssl.cpp
index 81795fdc60..aad3a11b7e 100644
--- a/drivers/openssl/stream_peer_openssl.cpp
+++ b/drivers/openssl/stream_peer_openssl.cpp
@@ -532,8 +532,26 @@ StreamPeerSSL* StreamPeerOpenSSL::_create_func() {
Vector<X509*> StreamPeerOpenSSL::certs;
+void StreamPeerOpenSSL::_load_certs(const ByteArray& p_array) {
+
+ ByteArray::Read r = p_array.read();
+ BIO* mem = BIO_new(BIO_s_mem());
+ BIO_puts(mem,(const char*)r.ptr());
+ while(true) {
+ X509*cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
+ if (!cert)
+ break;
+ certs.push_back(cert);
+ }
+ BIO_free(mem);
+}
+
void StreamPeerOpenSSL::initialize_ssl() {
+ available=true;
+
+ load_certs_func=_load_certs;
+
_create=_create_func;
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
SSL_library_init(); // Initialize OpenSSL's SSL libraries
@@ -544,20 +562,24 @@ void StreamPeerOpenSSL::initialize_ssl() {
Globals::get_singleton()->set_custom_property_info("ssl/certificates",PropertyInfo(Variant::STRING,"ssl/certificates",PROPERTY_HINT_FILE,"*.crt"));
if (certs_path!="") {
- Vector<uint8_t> data = FileAccess::get_file_as_array(certs_path);;
- if (data.size()) {
- data.push_back(0);
- BIO* mem = BIO_new(BIO_s_mem());
- BIO_puts(mem,(const char*) data.ptr());
- while(true) {
- X509*cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
- if (!cert)
- break;
- certs.push_back(cert);
+
+
+ FileAccess *f=FileAccess::open(certs_path,FileAccess::READ);
+ if (f) {
+ ByteArray arr;
+ int flen = f->get_len();
+ arr.resize(flen+1);
+ {
+ ByteArray::Write w = arr.write();
+ f->get_buffer(w.ptr(),flen);
+ w[flen]=0; //end f string
}
- BIO_free(mem);
+
+ memdelete(f);
+
+ _load_certs(arr);
+ print_line("Loaded certs from '"+certs_path+"': "+itos(certs.size()));
}
- print_line("Loaded certs from '"+certs_path+"': "+itos(certs.size()));
}
String config_path =GLOBAL_DEF("ssl/config","");
Globals::get_singleton()->set_custom_property_info("ssl/config",PropertyInfo(Variant::STRING,"ssl/config",PROPERTY_HINT_FILE,"*.cnf"));
diff --git a/drivers/openssl/stream_peer_openssl.h b/drivers/openssl/stream_peer_openssl.h
index 64f5a1d7ac..20266ee584 100644
--- a/drivers/openssl/stream_peer_openssl.h
+++ b/drivers/openssl/stream_peer_openssl.h
@@ -54,6 +54,7 @@ private:
static Vector<X509*> certs;
+ static void _load_certs(const ByteArray& p_array);
protected:
static void _bind_methods();
public:
diff --git a/drivers/png/SCsub b/drivers/png/SCsub
index 5532e28ade..df521de3eb 100644
--- a/drivers/png/SCsub
+++ b/drivers/png/SCsub
@@ -22,17 +22,16 @@ png_sources = [
"png/image_loader_png.cpp"
]
-if ("neon_enabled" in env and env["neon_enabled"]):
+# Currently .ASM filter_neon.S does not compile on NT.
+import os
+if ("neon_enabled" in env and env["neon_enabled"]) and os.name!="nt":
env.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=2"])
env_neon = env.Clone();
if "S_compiler" in env:
env_neon['CC'] = env['S_compiler']
#env_neon.Append(CPPFLAGS=["-DPNG_ARM_NEON"])
- import os
- # Currently .ASM filter_neon.S does not compile on NT.
- if (os.name!="nt"):
- png_sources.append(env_neon.Object("#drivers/png/arm/arm_init.c"))
- png_sources.append(env_neon.Object("#drivers/png/arm/filter_neon.S"))
+ png_sources.append(env_neon.Object("#drivers/png/arm/arm_init.c"))
+ png_sources.append(env_neon.Object("#drivers/png/arm/filter_neon.S"))
else:
env.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=0"])
diff --git a/drivers/register_driver_types.cpp b/drivers/register_driver_types.cpp
index e7bbf28f01..235438f126 100644
--- a/drivers/register_driver_types.cpp
+++ b/drivers/register_driver_types.cpp
@@ -31,7 +31,6 @@
#endif
#ifdef TOOLS_ENABLED
-#include "pe_bliss/pe_bliss_godot.h"
#include "platform/windows/export/export.h"
#endif
diff --git a/drivers/theora/video_stream_theora.cpp b/drivers/theora/video_stream_theora.cpp
index 1d2e6b9dda..e577c3f932 100644
--- a/drivers/theora/video_stream_theora.cpp
+++ b/drivers/theora/video_stream_theora.cpp
@@ -489,6 +489,9 @@ Ref<Texture> VideoStreamPlaybackTheora::get_texture() {
void VideoStreamPlaybackTheora::update(float p_delta) {
+ if (!file)
+ return;
+
if (!playing || paused) {
//printf("not playing\n");
return;
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 23a63be339..8b097ad25e 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -292,8 +292,11 @@ Error DirAccessUnix::rename(String p_path,String p_new_path) {
}
Error DirAccessUnix::remove(String p_path) {
- p_path=fix_path(p_path);
-
+ if (p_path.is_rel_path())
+ p_path=get_current_dir().plus_file(p_path);
+ else
+ p_path=fix_path(p_path);
+
struct stat flags;
if ((stat(p_path.utf8().get_data(),&flags)!=0))
return FAILED;
diff --git a/drivers/unix/memory_pool_static_malloc.cpp b/drivers/unix/memory_pool_static_malloc.cpp
index 1a79272dc1..f89b55de12 100644
--- a/drivers/unix/memory_pool_static_malloc.cpp
+++ b/drivers/unix/memory_pool_static_malloc.cpp
@@ -48,7 +48,12 @@ void* MemoryPoolStaticMalloc::alloc(size_t p_bytes,const char *p_description) {
#else
- int total = p_bytes + DEFAULT_ALIGNMENT;
+ size_t total;
+ #if defined(_add_overflow)
+ if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL;
+ #else
+ total = p_bytes + DEFAULT_ALIGNMENT;
+ #endif
uint8_t* ptr = (uint8_t*)_alloc(total, p_description);
ERR_FAIL_COND_V( !ptr, ptr );
int ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1)));
@@ -64,11 +69,18 @@ void* MemoryPoolStaticMalloc::_alloc(size_t p_bytes,const char *p_description) {
MutexLock lock(mutex);
#ifdef DEBUG_MEMORY_ENABLED
- void *mem=malloc(p_bytes+sizeof(RingPtr)); /// add for size and ringlist
+
+ size_t total;
+ #if defined(_add_overflow)
+ if (_add_overflow(p_bytes, sizeof(RingPtr), &total)) return NULL;
+ #else
+ total = p_bytes + sizeof(RingPtr);
+ #endif
+ void *mem=malloc(total); /// add for size and ringlist
if (!mem) {
- printf("**ERROR: out of memory while allocating %i bytes by %s?\n",(int) p_bytes, p_description);
- printf("**ERROR: memory usage is %i\n", (int)get_total_usage());
+ printf("**ERROR: out of memory while allocating %lu bytes by %s?\n", (unsigned long) p_bytes, p_description);
+ printf("**ERROR: memory usage is %lu\n", (unsigned long) get_total_usage());
};
ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request
@@ -129,7 +141,12 @@ void* MemoryPoolStaticMalloc::realloc(void *p_memory,size_t p_bytes) {
if (!p_memory)
return alloc(p_bytes);
- int total = p_bytes + DEFAULT_ALIGNMENT;
+ size_t total;
+ #if defined(_add_overflow)
+ if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL;
+ #else
+ total = p_bytes + DEFAULT_ALIGNMENT;
+ #endif
uint8_t* mem = (uint8_t*)p_memory;
int ofs = *(mem-1);
mem = mem - ofs;
@@ -321,7 +338,7 @@ size_t MemoryPoolStaticMalloc::get_max_usage() {
/* Most likely available only if memory debugger was compiled in */
int MemoryPoolStaticMalloc::get_alloc_count() {
- return 0;
+ return total_pointers;
}
void * MemoryPoolStaticMalloc::get_alloc_ptr(int p_alloc_idx) {
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index a004a116e0..84b6dc24dc 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -251,6 +251,9 @@ OS::Date OS_Unix::get_date(bool utc) const {
lt=localtime(&t);
Date ret;
ret.year=1900+lt->tm_year;
+ // Index starting at 1 to match OS_Unix::get_date
+ // and Windows SYSTEMTIME and tm_mon follows the typical structure
+ // of 0-11, noted here: http://www.cplusplus.com/reference/ctime/tm/
ret.month=(Month)(lt->tm_mon + 1);
ret.day=lt->tm_mday;
ret.weekday=(Weekday)lt->tm_wday;
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index bd33c81298..6ace64a923 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -81,9 +81,9 @@ void ThreadPosix::wait_to_finish_func_posix(Thread* p_thread) {
tp->pthread=0;
}
-Error ThreadPosix::set_name(const String& p_name) {
+Error ThreadPosix::set_name_func_posix(const String& p_name) {
- ERR_FAIL_COND_V(pthread == 0, ERR_UNCONFIGURED);
+ pthread_t running_thread = pthread_self();
#ifdef PTHREAD_NO_RENAME
return ERR_UNAVAILABLE;
@@ -93,22 +93,15 @@ Error ThreadPosix::set_name(const String& p_name) {
#ifdef PTHREAD_RENAME_SELF
// check if thread is the same as caller
- int caller = Thread::get_caller_ID();
- int self = get_ID();
- if (caller != self) {
- ERR_EXPLAIN("On this platform, thread can only be renamed with calls from the threads to be renamed.");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- return ERR_UNAVAILABLE;
- };
int err = pthread_setname_np(p_name.utf8().get_data());
#else
#ifdef PTHREAD_BSD_SET_NAME
- pthread_set_name_np(pthread, p_name.utf8().get_data());
+ pthread_set_name_np(running_thread, p_name.utf8().get_data());
int err = 0; // Open/FreeBSD ignore errors in this function
#else
- int err = pthread_setname_np(pthread, p_name.utf8().get_data());
+ int err = pthread_setname_np(running_thread, p_name.utf8().get_data());
#endif // PTHREAD_BSD_SET_NAME
#endif // PTHREAD_RENAME_SELF
@@ -123,7 +116,7 @@ void ThreadPosix::make_default() {
create_func=create_func_posix;
get_thread_ID_func=get_thread_ID_func_posix;
wait_to_finish_func=wait_to_finish_func_posix;
-
+ set_name_func = set_name_func_posix;
}
ThreadPosix::ThreadPosix() {
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index 179d56d5bd..06a17c2ae6 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -55,13 +55,14 @@ class ThreadPosix : public Thread {
static Thread* create_func_posix(ThreadCreateCallback p_callback,void *,const Settings&);
static ID get_thread_ID_func_posix();
static void wait_to_finish_func_posix(Thread* p_thread);
-
+
+ static Error set_name_func_posix(const String& p_name);
+
ThreadPosix();
public:
virtual ID get_ID() const;
- Error set_name(const String& p_name);
static void make_default();
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 0a413979fc..b9476b870b 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -310,8 +310,11 @@ Error DirAccessWindows::rename(String p_path,String p_new_path) {
Error DirAccessWindows::remove(String p_path) {
- p_path=fix_path(p_path);
-
+ if (p_path.is_rel_path())
+ p_path=get_current_dir().plus_file(p_path);
+ else
+ p_path=fix_path(p_path);
+
printf("erasing %s\n",p_path.utf8().get_data());
//WIN32_FILE_ATTRIBUTE_DATA fileInfo;
//DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
diff --git a/godot_icon.png b/godot_icon.png
deleted file mode 100644
index 013632ddf1..0000000000
--- a/godot_icon.png
+++ /dev/null
Binary files differ
diff --git a/godot_icon.svg b/godot_icon.svg
deleted file mode 100644
index 6e32074d89..0000000000
--- a/godot_icon.svg
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="1024"
- height="1024"
- id="svg3030"
- version="1.1"
- inkscape:version="0.48.4 r9939"
- sodipodi:docname="godot_icon.svg">
- <defs
- id="defs3032" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.24748737"
- inkscape:cx="340.91041"
- inkscape:cy="224.06536"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1366"
- inkscape:window-height="748"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata3035">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-28.362183)">
- <rect
- style="fill:#a39f9f;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4009"
- width="990"
- height="990"
- x="20"
- y="47.362183"
- ry="187.81349" />
- <path
- style="fill:#ffffff;fill-opacity:1;stroke:none"
- d="m 116.99388,715.36604 43.13957,-74.51381 75.99672,-171.42666 271.088,-13.63746 282.06373,14.1696 138.45065,255.56931 -25.0756,66.96734 -376.12685,53.39482 -367.70391,-40.32222 z"
- id="path3239"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccc" />
- <g
- id="g3412"
- transform="matrix(12.995388,0,0,-12.995388,898.37246,704.73082)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 z"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3414" />
- </g>
- <g
- id="g3416"
- transform="matrix(12.995388,0,0,-12.995388,140.10982,467.34929)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 z"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3418" />
- </g>
- <g
- id="g3420"
- transform="matrix(12.995388,0,0,-12.995388,411.4457,567.42812)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3422" />
- </g>
- <g
- id="g3424"
- transform="matrix(12.995388,0,0,-12.995388,391.00655,572.46636)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3426" />
- </g>
- <g
- id="g3428"
- transform="matrix(12.995388,0,0,-12.995388,526.30933,660.10985)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3430" />
- </g>
- <g
- id="g3432"
- transform="matrix(12.995388,0,0,-12.995388,641.18731,567.42812)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3434" />
- </g>
- <g
- id="g3436"
- transform="matrix(12.995388,0,0,-12.995388,661.63165,572.46636)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3438" />
- </g>
- </g>
-</svg>
diff --git a/icon.png b/icon.png
new file mode 100644
index 0000000000..e334f5fa78
--- /dev/null
+++ b/icon.png
Binary files differ
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000000..34747d34fe
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1024"
+ height="1024"
+ id="svg3030"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon.svg"
+ inkscape:export-filename="/home/akien/Projects/godot/godot.git/icon.png"
+ inkscape:export-xdpi="22.5"
+ inkscape:export-ydpi="22.5">
+ <defs
+ id="defs3032" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="-560.15123"
+ inkscape:cy="190.62119"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1015"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata3035">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-28.362183)">
+ <g
+ id="g4149"
+ transform="matrix(1.0688992,0,0,1.1334985,-45.061194,-81.689066)">
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0"
+ id="path3239"
+ d="m 116.99388,715.36604 43.13957,-74.51381 75.99672,-171.42666 271.088,-13.63746 282.06373,14.1696 138.45065,255.56931 -25.0756,66.96734 -376.12685,53.39482 -367.70391,-40.32222 z"
+ style="fill:#ffffff;fill-opacity:1;stroke:none" />
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,898.37246,704.73082)"
+ id="g3412">
+ <path
+ id="path3414"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 Z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,140.10982,467.34929)"
+ id="g3416">
+ <path
+ id="path3418"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 Z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,411.4457,567.42812)"
+ id="g3420">
+ <path
+ id="path3422"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,391.00655,572.46636)"
+ id="g3424">
+ <path
+ id="path3426"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,526.30933,660.10985)"
+ id="g3428">
+ <path
+ id="path3430"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,641.18731,567.42812)"
+ id="g3432">
+ <path
+ id="path3434"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,661.63165,572.46636)"
+ id="g3436">
+ <path
+ id="path3438"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/godot_logo.svg b/logo.svg
index 98dcddfd2b..98dcddfd2b 100644
--- a/godot_logo.svg
+++ b/logo.svg
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 676ac85ada..226656d8f4 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -102,6 +102,18 @@ bool InputDefault::is_action_pressed(const StringName& p_action) {
if (joy_buttons_pressed.has(c))
return true;
} break;
+ case InputEvent::JOYSTICK_MOTION: {
+
+ const InputEventJoystickMotion &iejm=E->get().joy_motion;
+ int c = _combine_device(iejm.axis,device);
+ if (_joy_axis.has(c)) {
+ if (iejm.axis_value < 0) {
+ if (_joy_axis[c] < -0.5f) return true;
+ }
+ else
+ if (_joy_axis[c] > 0.5f) return true;
+ }
+ } break;
}
}
@@ -157,10 +169,11 @@ void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_
};
js.uid = uidname;
//printf("looking for mappings for guid %ls\n", uidname.c_str());
- int mapping = -1;
+ int mapping = fallback_mapping;
for (int i=0; i < map_db.size(); i++) {
if (js.uid == map_db[i].uid) {
mapping = i;
+ js.name = map_db[i].name;
//printf("found mapping\n");
};
};
@@ -387,115 +400,138 @@ void InputDefault::set_mouse_in_window(bool p_in_window) {
static const char *s_ControllerMappings [] =
{
#ifdef WINDOWS_ENABLED
- "8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
- "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
- "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,",
- "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
- "6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
- "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,",
- "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,",
- "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,",
- "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,",
- "6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,platform:Windows,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
- "36280100000000000000504944564944,OUYA Controller,platform:Windows,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,",
- "4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Windows,",
- "00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,",
- "00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,",
- "28040140000000000000504944564944,GamePad Pro USB,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,",
- "ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,",
- "8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
- "8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
- "10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,",
- "79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,",
- "4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows,",
- "d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,",
- "a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,",
- "8f0e0300000000000000504944564944,Trust GTX 28,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,",
- "4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
- "6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
- "83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows,",
- "c911f055000000000000504944564944,GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
+ "00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
+ "00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
+ "10080300000000000000504944564944,PS2 USB,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,",
+ "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,",
+ "28040140000000000000504944564944,GamePad Pro USB,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,",
+ "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+ "36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,",
+ "4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,",
+ "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
+ "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
+ "4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
+ "4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+ "6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+ "6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
"79000600000000000000504944564944,Generic Speedlink,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
+ "83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
+ "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,",
+ "8f0e0300000000000000504944564944,Trust GXT 28,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "8f0e0d31000000000000504944564944,Multilaser JS071 USB,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "8f0e1200000000000000504944564944,Acme,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "c911f055000000000000504944564944,GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
+ "d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,",
+ "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
-
#endif
+
#ifdef OSX_ENABLED
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
- "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
- "6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
- "6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
- "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
+ "050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,",
+ "0d0f0000000000004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
"4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
+ "4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
+ "4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
+ "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
+ "6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+ "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
+ "6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
+ "79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,",
+ "83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
+ "891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
+ "8f0e0000000000000300000000000000,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
#endif
+
#if X11_ENABLED
- "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
- "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
- "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
- "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
- "030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
- "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
- "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
- "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
- "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
- "03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
- "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
- "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
- "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
+ "0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
+ "030000000d0f00001000000011010000,HORI CO.,LTD. FIGHTING STICK 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7",
+ "030000000d0f00002200000011010000,HORI CO.,LTD. REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,",
+ "030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,",
- "03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
+ "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,",
+ "03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
+ "03000000280400000140000000010000,Gravis GamePad Pro USB ,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,",
+ "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
+ "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
+ "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
+ "030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
+ "030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,",
- "030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
- "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
+ "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
- "030000006d04000016c2000010010000,Logitech Logitech Dual Action,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
- "03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
+ "030000005e040000d102000001010000,Microsoft X-Box One pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,",
"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,",
+ "030000006d04000016c2000010010000,Logitech Logitech Dual Action,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
- "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,",
- "030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
- "030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
- "0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
- "0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
- "030000006f0e00001f01000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
- "03000000280400000140000000010000,Gravis GamePad Pro USB ,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,",
- "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+ "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+ "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "030000006f0e00001304000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
- "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,",
+ "030000006f0e00001f01000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,",
+ "030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "03000000790000001100000010010000,RetroLink Saturn Classic Controller,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
+ "03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,",
"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
- "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
+ "030000008916000001fd000024010000,Razer Onza Classic Edition,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,",
+ "03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
+ "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
+ "03000000c9110000f055000011010000,HJC Game GAMEPAD,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b4,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+ "03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,",
+ "03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
+ "05000000362800000100000002010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,",
+ "05000000362800000100000003010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,",
+ "05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,",
+ "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
+ "050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,",
+ "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,",
"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
- "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
- "03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,",
- "05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",
- "05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",
- "030000008916000001fd000024010000,Razer Onza Classic Edition,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
- "030000005e040000d102000001010000,Microsoft X-Box One pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
- "03000000790000001100000010010000,RetroLink Saturn Classic Controller,platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
- "050000007e0500003003000001000000,Nintendo Wii U Pro Controller,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,",
- "030000005e0400008e02000004010000,Microsoft X-Box 360 pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
- "030000000d0f00002200000011010000,HORI CO.,LTD. REAL ARCADE Pro.V3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,",
- "030000000d0f00001000000011010000,HORI CO.,LTD. FIGHTING STICK 3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7",
- "03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
- "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
- "03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,",
#endif
#if defined(__ANDROID__)
+ "Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,",
+ "47656e6572696320582d426f78207061,Logitech F-310,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a5,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a4,b:b1,",
+ "484f524920434f2e2c4c544420205041,Hori Gem Pad 3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:b15,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,",
+ "4d6963726f736f667420582d426f7820,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,",
"4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
+ "532e542e442e20496e74657261637420,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b25,rightshoulder:b27,rightx:a2,start:b31,righty:a3,dpleft:h0.8,lefttrigger:b28,x:b20,dpup:h0.1,back:b30,leftstick:b22,leftshoulder:b26,y:b21,a:b23,dpright:h0.2,righttrigger:b29,b:b24,",
+ "506572666f726d616e63652044657369,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:h0.2,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,",
#endif
#ifdef JAVASCRIPT_ENABLED
"Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,",
+ "303435652d303238652d4d6963726f73,Wired X360 Controller,leftx:a0,lefty:a1,dpdown:a7,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:a6,lefttrigger:a2,x:b2,dpup:a7,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:a6,righttrigger:a5,b:b1,",
+ "303435652d303731392d58626f782033,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,",
"303534632d303236382d536f6e792050,PS3 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:b6,rightstick:b2,rightshoulder:b11,rightx:a2,start:b3,righty:a3,dpleft:b7,lefttrigger:b8,x:b15,dpup:b4,back:b0,leftstick:b1,leftshoulder:b10,y:b12,a:b14,dpright:b5,righttrigger:b9,b:b13,",
"303534632d303563342d536f6e792043,PS4 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:a7,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,dpleft:a6,lefttrigger:a3,x:b0,dpup:a7,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:a6,righttrigger:a4,b:b2,",
"303534632d303563342d576972656c65,PS4 Controller USB/Win,leftx:a0,lefty:a1,dpdown:b15,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,lefttrigger:a3,x:b0,dpup:b14,dpleft:b16,dpright:b17,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,righttrigger:b7,b:b2,",
- "303435652d303238652d4d6963726f73,Wired X360 Controller,leftx:a0,lefty:a1,dpdown:a7,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:a6,lefttrigger:a2,x:b2,dpup:a7,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:a6,righttrigger:a5,b:b1,",
- "303435652d303731392d58626f782033,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,",
"c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,",
#endif
NULL
@@ -523,6 +559,8 @@ InputDefault::InputDefault() {
hat_map_default[HAT_LEFT].index = JOY_DPAD_LEFT;
hat_map_default[HAT_LEFT].value = 0;
+ fallback_mapping = -1;
+
String env_mapping = OS::get_singleton()->get_environment("SDL_GAMECONTROLLERCONFIG");
if (env_mapping != "") {
@@ -789,6 +827,7 @@ void InputDefault::parse_mapping(String p_mapping) {
uid.resize(17);
mapping.uid = entry[0];
+ mapping.name = entry[1];
int idx = 1;
while (++idx < entry.size()) {
@@ -863,6 +902,16 @@ void InputDefault::remove_joy_mapping(String p_guid) {
}
}
+void InputDefault::set_fallback_mapping(String p_guid) {
+
+ for (int i = 0; i < map_db.size(); i++) {
+ if (map_db[i].uid == p_guid) {
+ fallback_mapping = i;
+ return;
+ }
+ }
+}
+
//Defaults to simple implementation for platforms with a fixed gamepad layout, like consoles.
bool InputDefault::is_joy_known(int p_device) {
@@ -875,10 +924,10 @@ String InputDefault::get_joy_guid(int p_device) const {
//platforms that use the remapping system can override and call to these ones
bool InputDefault::is_joy_mapped(int p_device) {
- return joy_names[p_device].mapping != -1 ? true : false;
+ int mapping = joy_names[p_device].mapping;
+ return mapping != -1 ? (mapping != fallback_mapping) : false;
}
String InputDefault::get_joy_guid_remapped(int p_device) const {
return joy_names[p_device].uid;
}
-
diff --git a/main/input_default.h b/main/input_default.h
index a75865e0cb..471ae9e692 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -18,7 +18,6 @@ class InputDefault : public Input {
MainLoop *main_loop;
bool emulate_touch;
-
struct SpeedTrack {
uint64_t last_tick;
@@ -36,7 +35,7 @@ class InputDefault : public Input {
struct Joystick {
StringName name;
StringName uid;
- bool last_buttons[JOY_BUTTON_MAX + 2]; //html5 needs support for 18 buttons to map some devices correctly
+ bool last_buttons[JOY_BUTTON_MAX + 19]; //apparently SDL specifies 35 possible buttons on android
float last_axis[JOY_AXIS_MAX];
float filter;
int last_hat;
@@ -50,7 +49,7 @@ class InputDefault : public Input {
last_axis[i] = 0.0f;
}
- for (int i = 0; i < JOY_BUTTON_MAX + 2; i++) {
+ for (int i = 0; i < JOY_BUTTON_MAX + 19; i++) {
last_buttons[i] = false;
}
@@ -62,6 +61,7 @@ class InputDefault : public Input {
SpeedTrack mouse_speed_track;
Map<int, Joystick> joy_names;
+ int fallback_mapping;
RES custom_cursor;
public:
enum HatMask {
@@ -102,6 +102,7 @@ private:
struct JoyDeviceMapping {
String uid;
+ String name;
Map<int,JoyEvent> buttons;
Map<int,JoyEvent> axis;
JoyEvent hat[HAT_MAX];
@@ -169,7 +170,7 @@ public:
bool is_joy_mapped(int p_device);
String get_joy_guid_remapped(int p_device) const;
-
+ void set_fallback_mapping(String p_guid);
InputDefault();
};
diff --git a/main/main.cpp b/main/main.cpp
index 19fe037613..9c98e3780d 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -73,6 +73,7 @@
#include "core/os/thread.h"
#include "core/io/file_access_pack.h"
#include "core/io/file_access_zip.h"
+#include "core/io/stream_peer_ssl.h"
#include "translation.h"
#include "version.h"
#include "main/input_default.h"
@@ -136,13 +137,13 @@ void Main::print_help(const char* p_binary) {
const char **test_names=tests_get_names();
const char* coma = "";
while(*test_names) {
-
+
OS::get_singleton()->print("%s%s", coma, *test_names);
test_names++;
coma = ", ";
}
OS::get_singleton()->print(")\n");
-
+
OS::get_singleton()->print("\t-r WIDTHxHEIGHT\t : Request Window Resolution\n");
OS::get_singleton()->print("\t-p XxY\t : Request Window Position\n");
OS::get_singleton()->print("\t-f\t\t : Request Fullscreen\n");
@@ -150,7 +151,7 @@ void Main::print_help(const char* p_binary) {
OS::get_singleton()->print("\t-w\t\t Request Windowed\n");
OS::get_singleton()->print("\t-vd DRIVER\t : Video Driver (");
for (int i=0;i<OS::get_singleton()->get_video_driver_count();i++) {
-
+
if (i!=0)
OS::get_singleton()->print(", ");
OS::get_singleton()->print("%s",OS::get_singleton()->get_video_driver_name(i));
@@ -158,7 +159,7 @@ void Main::print_help(const char* p_binary) {
OS::get_singleton()->print(")\n");
OS::get_singleton()->print("\t-ad DRIVER\t : Audio Driver (");
for (int i=0;i<OS::get_singleton()->get_audio_driver_count();i++) {
-
+
if (i!=0)
OS::get_singleton()->print(", ");
OS::get_singleton()->print("%s",OS::get_singleton()->get_audio_driver_name(i));
@@ -166,7 +167,7 @@ void Main::print_help(const char* p_binary) {
OS::get_singleton()->print(")\n");
OS::get_singleton()->print("\t-rthread <mode>\t : Render Thread Mode ('unsafe', 'safe', 'separate).");
OS::get_singleton()->print(")\n");
- OS::get_singleton()->print("\t-s,-script [script] : Run a script.\n");
+ OS::get_singleton()->print("\t-s,-script [script] : Run a script.\n");
OS::get_singleton()->print("\t-d,-debug : Debug (local stdout debugger).\n");
OS::get_singleton()->print("\t-rdebug ADDRESS : Remote debug (<ip>:<port> host address).\n");
OS::get_singleton()->print("\t-fdelay [msec]: Simulate high CPU load (delay each frame by [msec]).\n");
@@ -217,7 +218,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
/* argument parsing and main creation */
List<String> args;
List<String> main_args;
-
+
for(int i=0;i<argc;i++) {
args.push_back(String::utf8(argv[i]));
@@ -235,7 +236,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
}
I=args.front();
-
+
video_mode = OS::get_singleton()->get_default_video_mode();
String video_driver="";
@@ -264,7 +265,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
packed_data = memnew(PackedData);
#ifdef MINIZIP_ENABLED
-
+
//XXX: always get_singleton() == 0x0
zip_packed_data = ZipArchive::get_singleton();
//TODO: remove this temporary fix
@@ -285,44 +286,44 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
// no op
} else if (I->get()=="-h" || I->get()=="--help" || I->get()=="/?") { // resolution
-
+
goto error;
-
-
+
+
} else if (I->get()=="-r") { // resolution
-
+
if (I->next()) {
-
+
String vm=I->next()->get();
-
+
if (vm.find("x")==-1) { // invalid parameter format
-
+
OS::get_singleton()->print("Invalid -r argument: %s\n",vm.utf8().get_data());
goto error;
-
-
+
+
}
-
+
int w=vm.get_slice("x",0).to_int();
int h=vm.get_slice("x",1).to_int();
-
+
if (w==0 || h==0) {
-
+
OS::get_singleton()->print("Invalid -r resolution, x and y must be >0\n");
goto error;
-
+
}
-
+
video_mode.width=w;
video_mode.height=h;
force_res=true;
-
+
N=I->next()->next();
} else {
OS::get_singleton()->print("Invalid -p argument, needs resolution\n");
goto error;
-
-
+
+
}
} else if (I->get()=="-p") { // position
@@ -360,15 +361,15 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
init_windowed=true;
} else if (I->get()=="-vd") { // video driver
-
+
if (I->next()) {
-
+
video_driver=I->next()->get();
N=I->next()->next();
} else {
OS::get_singleton()->print("Invalid -cd argument, needs driver name\n");
goto error;
-
+
}
} else if (I->get()=="-lang") { // language
@@ -420,18 +421,18 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
}
} else if (I->get()=="-ad") { // video driver
-
+
if (I->next()) {
-
+
audio_driver=I->next()->get();
N=I->next()->next();
} else {
goto error;
-
+
}
-
+
} else if (I->get()=="-f") { // fullscreen
-
+
//video_mode.fullscreen=false;
init_fullscreen=true;
} else if (I->get()=="-e" || I->get()=="-editor") { // fonud editor
@@ -446,9 +447,9 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
} else if (I->get()=="-v") { // fullscreen
OS::get_singleton()->_verbose_stdout=true;
} else if (I->get()=="-path") { // resolution
-
+
if (I->next()) {
-
+
String p = I->next()->get();
if (OS::get_singleton()->set_cwd(p)==OK) {
//nothing
@@ -458,7 +459,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
N=I->next()->next();
} else {
goto error;
-
+
}
} else if (I->get()=="-bp") { // /breakpoints
@@ -567,7 +568,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
main_args.push_back(I->get());
}
}
-
+
I=N;
}
@@ -635,13 +636,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
if (editor) {
packed_data->set_disabled(true);
globals->set_disable_platform_override(true);
+ StreamPeerSSL::initialize_certs=false; //will be initialized by editor
}
#endif
if (globals->setup(game_path,main_pack)!=OK) {
-
+
#ifdef TOOLS_ENABLED
editor=false;
#else
@@ -689,6 +691,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
video_mode.fullscreen=globals->get("display/fullscreen");
if (use_custom_res && globals->has("display/resizable"))
video_mode.resizable=globals->get("display/resizable");
+ if (use_custom_res && globals->has("display/borderless_window"))
+ video_mode.borderless_window = globals->get("display/borderless_window");
if (!force_res && use_custom_res && globals->has("display/test_width") && globals->has("display/test_height")) {
int tw = globals->get("display/test_width");
@@ -704,6 +708,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
GLOBAL_DEF("display/height",video_mode.height);
GLOBAL_DEF("display/fullscreen",video_mode.fullscreen);
GLOBAL_DEF("display/resizable",video_mode.resizable);
+ GLOBAL_DEF("display/borderless_window", video_mode.borderless_window);
GLOBAL_DEF("display/test_width",0);
GLOBAL_DEF("display/test_height",0);
OS::get_singleton()->_pixel_snap=GLOBAL_DEF("display/use_2d_pixel_snap",false);
@@ -726,39 +731,41 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
/* Determine Video Driver */
- if (audio_driver=="") // specified in engine.cfg
+ if (audio_driver=="") { // specified in engine.cfg
audio_driver=GLOBAL_DEF("audio/driver",OS::get_singleton()->get_audio_driver_name(0));
-
-
+ }
+
+
for (int i=0;i<OS::get_singleton()->get_video_driver_count();i++) {
if (video_driver==OS::get_singleton()->get_video_driver_name(i)) {
-
+
video_driver_idx=i;
break;
}
}
if (video_driver_idx<0) {
-
+
OS::get_singleton()->alert( "Invalid Video Driver: "+video_driver );
video_driver_idx = 0;
//goto error;
}
for (int i=0;i<OS::get_singleton()->get_audio_driver_count();i++) {
-
+
if (audio_driver==OS::get_singleton()->get_audio_driver_name(i)) {
-
+
audio_driver_idx=i;
break;
}
}
if (audio_driver_idx<0) {
-
+
OS::get_singleton()->alert( "Invalid Audio Driver: "+audio_driver );
- goto error;
+ audio_driver_idx = 0;
+ //goto error;
}
{
@@ -797,14 +804,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
return OK;
error:
-
- video_driver="";
+
+ video_driver="";
audio_driver="";
game_path="";
-
- args.clear();
+
+ args.clear();
main_args.clear();
-
+
print_help(execpath);
if (performance)
@@ -833,14 +840,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
unregister_core_driver_types();
unregister_core_types();
-
+
OS::get_singleton()->_cmdline.clear();
if (message_queue)
memdelete( message_queue);
OS::get_singleton()->finalize_core();
locale=String();
-
+
return ERR_INVALID_PARAMETER;
}
@@ -1009,6 +1016,7 @@ bool Main::start() {
bool noquit=false;
bool convert_old=false;
bool export_debug=false;
+ bool project_manager_request = false;
List<String> args = OS::get_singleton()->get_cmdline_args();
for (int i=0;i<args.size();i++) {
//parameters that do not have an argument to the right
@@ -1020,6 +1028,8 @@ bool Main::start() {
convert_old=true;
} else if (args[i]=="-editor" || args[i]=="-e") {
editor=true;
+ } else if (args[i] == "-pm" || args[i] == "-project_manager") {
+ project_manager_request = true;
} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
game_path=args[i];
}
@@ -1131,9 +1141,9 @@ bool Main::start() {
Ref<Script> script_res = ResourceLoader::load(script);
ERR_EXPLAIN("Can't load script: "+script);
ERR_FAIL_COND_V(script_res.is_null(),false);
-
+
if( script_res->can_instance() /*&& script_res->inherits_from("SceneTreeScripted")*/) {
-
+
StringName instance_type=script_res->get_instance_base_type();
Object *obj = ObjectTypeDB::instance(instance_type);
@@ -1156,10 +1166,10 @@ bool Main::start() {
} else {
main_loop_type=GLOBAL_DEF("application/main_loop_type","");
}
-
+
if (!main_loop && main_loop_type=="")
main_loop_type="SceneTree";
-
+
if (!main_loop) {
if (!ObjectTypeDB::type_exists(main_loop_type)) {
OS::get_singleton()->alert("godot: error: MainLoop type doesn't exist: "+main_loop_type);
@@ -1174,17 +1184,17 @@ bool Main::start() {
main_loop=ml->cast_to<MainLoop>();
if (!main_loop) {
-
+
memdelete(ml);
ERR_EXPLAIN("Invalid MainLoop type");
ERR_FAIL_V(false);
-
+
}
}
}
if (main_loop->is_type("SceneTree")) {
-
+
SceneTree *sml = main_loop->cast_to<SceneTree>();
if (debug_collisions) {
@@ -1199,7 +1209,7 @@ bool Main::start() {
EditorNode *editor_node=NULL;
if (editor) {
- editor_node = memnew( EditorNode );
+ editor_node = memnew( EditorNode );
sml->get_root()->add_child(editor_node);
//root_node->set_editor(editor);
@@ -1253,7 +1263,7 @@ bool Main::start() {
}
- if (game_path!="") {
+ if (game_path!="" && !project_manager_request) {
String local_game_path=game_path.replace("\\","/");
@@ -1319,6 +1329,7 @@ bool Main::start() {
}
}
}
+ OS::get_singleton()->set_context(OS::CONTEXT_EDITOR);
//editor_node->set_edited_scene(game);
} else {
@@ -1459,10 +1470,11 @@ bool Main::start() {
};
}
*/
- if (script=="" && test=="" && game_path=="" && !editor) {
+ if (project_manager_request || (script=="" && test=="" && game_path=="" && !editor)) {
ProjectManager *pmanager = memnew( ProjectManager );
sml->get_root()->add_child(pmanager);
+ OS::get_singleton()->set_context(OS::CONTEXT_PROJECTMAN);
}
#endif
@@ -1649,13 +1661,13 @@ void Main::cleanup() {
EditorNode::unregister_editor_types();
#endif
- unregister_driver_types();
+ unregister_driver_types();
unregister_module_types();
- unregister_scene_types();
+ unregister_scene_types();
unregister_server_types();
OS::get_singleton()->finalize();
-
+
if (packed_data)
memdelete(packed_data);
if (file_access_network_client)
diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp
index 53519030fc..e8e8ce4e96 100644
--- a/modules/gdscript/gd_compiler.cpp
+++ b/modules/gdscript/gd_compiler.cpp
@@ -776,7 +776,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
if (named) {
- key_idx = codegen.get_name_map_pos(static_cast<const GDParser::IdentifierNode*>(E->get()->arguments[1])->name);
+ key_idx = codegen.get_name_map_pos(static_cast<const GDParser::IdentifierNode*>(E->get()->arguments[1])->name);
//printf("named key %x\n",key_idx);
} else {
@@ -1567,7 +1567,7 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
GDScript::MemberInfo minfo;
minfo.index = p_script->member_indices.size();
minfo.setter = p_class->variables[i].setter;
- minfo.getter = p_class->variables[i].getter;
+ minfo.getter = p_class->variables[i].getter;
p_script->member_indices[name]=minfo;
p_script->members.insert(name);
@@ -1712,6 +1712,8 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
}
}
#endif
+
+ p_script->valid=true;
return OK;
}
diff --git a/modules/gdscript/gd_compiler.h b/modules/gdscript/gd_compiler.h
index 5bf7ec980d..32e18c6dcf 100644
--- a/modules/gdscript/gd_compiler.h
+++ b/modules/gdscript/gd_compiler.h
@@ -44,7 +44,7 @@ class GDCompiler {
List< Map<StringName,int> > stack_id_stack;
Map<StringName,int> stack_identifiers;
-
+
List<GDFunction::StackDebug> stack_debug;
List< Map<StringName,int> > block_identifier_stack;
Map<StringName,int> block_identifiers;
@@ -65,7 +65,7 @@ class GDCompiler {
void push_stack_identifiers() {
stack_id_stack.push_back( stack_identifiers );
if (debug_stack) {
-
+
block_identifier_stack.push_back(block_identifiers);
block_identifiers.clear();
}
@@ -74,10 +74,10 @@ class GDCompiler {
void pop_stack_identifiers() {
stack_identifiers = stack_id_stack.back()->get();
stack_id_stack.pop_back();
-
+
if (debug_stack) {
for (Map<StringName,int>::Element *E=block_identifiers.front();E;E=E->next()) {
-
+
GDFunction::StackDebug sd;
sd.added=false;
sd.identifier=E->key();
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index 126a8cd1eb..ff19518ad5 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -52,6 +52,7 @@ String GDScriptLanguage::get_template(const String& p_class_name, const String&
"# var a=2\n"+
"# var b=\"textvar\"\n\n"+
"func _ready():\n"+
+ "\t# Called every time the node is added to the scene.\n"+
"\t# Initialization here\n"+
"\tpass\n"+
"\n"+
@@ -285,6 +286,30 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const
p_functions->push_back(GDFunctions::get_info(GDFunctions::Function(i)));
}
+
+ //not really "functions", but..
+ {
+ MethodInfo mi;
+ mi.name="preload:Resource";
+ mi.arguments.push_back(PropertyInfo(Variant::STRING,"path"));
+ mi.return_val=PropertyInfo(Variant::OBJECT,"",PROPERTY_HINT_RESOURCE_TYPE,"Resource");
+ p_functions->push_back(mi);
+ }
+ {
+ MethodInfo mi;
+ mi.name="yield";
+ mi.arguments.push_back(PropertyInfo(Variant::OBJECT,"object"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING,"signal"));
+ mi.default_arguments.push_back(Variant::NIL);
+ mi.default_arguments.push_back(Variant::STRING);
+ p_functions->push_back(mi);
+ }
+ {
+ MethodInfo mi;
+ mi.name="assert";
+ mi.arguments.push_back(PropertyInfo(Variant::BOOL,"condition"));
+ p_functions->push_back(mi);
+ }
}
void GDScriptLanguage::get_public_constants(List<Pair<String,Variant> > *p_constants) const {
@@ -2300,8 +2325,8 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
"# Key",
"# MouseMotion",
"# MouseButton",
- "# JoyMotion",
- "# JoyButton",
+ "# JoystickMotion",
+ "# JoystickButton",
"# ScreenTouch",
"# ScreenDrag",
"# Action"
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index b6e8478846..b713dc318f 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -912,7 +912,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
default: valid=false; break;
}
- if (valid) {
+ if (valid) {
e.is_op=true;
e.op=op;
expression.push_back(e);
@@ -1790,7 +1790,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
p_block->sub_blocks.push_back(cf_for->body);
if (!_enter_indent_block(cf_for->body)) {
- _set_error("Expected indented block after 'while'");
+ _set_error("Expected indented block after 'for'");
p_block->end_line=tokenizer->get_token_line();
return;
}
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 62c5eb735a..beec314e44 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -1481,6 +1481,11 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError&
/* STEP 1, CREATE */
+ if (!valid) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+
r_error.error=Variant::CallError::CALL_OK;
REF ref;
Object *owner=NULL;
@@ -1510,7 +1515,7 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError&
return Variant();
}
- if (ref.is_valid()) {
+ if (ref.is_valid()) {
return ref;
} else {
return owner;
@@ -2008,7 +2013,7 @@ void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
void GDScript::_bind_methods() {
- ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"new",&GDScript::_new,MethodInfo("new"));
+ ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"new",&GDScript::_new,MethodInfo("new"));
ObjectTypeDB::bind_method(_MD("get_as_byte_code"),&GDScript::get_as_byte_code);
@@ -2456,6 +2461,7 @@ void GDInstance::get_method_list(List<MethodInfo> *p_list) const {
MethodInfo mi;
mi.name=E->key();
+ mi.flags|=METHOD_FLAG_FROM_SCRIPT;
for(int i=0;i<E->get().get_argument_count();i++)
mi.arguments.push_back(PropertyInfo(Variant::NIL,"arg"+itos(i)));
p_list->push_back(mi);
@@ -2677,40 +2683,47 @@ void GDScriptLanguage::frame() {
void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
static const char *_reserved_words[]={
- "break",
- "class",
- "continue",
- "const",
- "else",
- "elif",
- "enum",
- "extends" ,
- "onready",
- "for" ,
- "func" ,
- "if" ,
- "in" ,
- "null" ,
- "not" ,
- "return" ,
- "self" ,
- "while" ,
- "true" ,
- "false" ,
- "tool",
- "var",
- "setget",
- "pass",
+ // operators
"and",
+ "in",
+ "not",
"or",
- "export",
+ // types and values
+ "false",
+ "float",
+ "int",
+ "null",
+ "PI",
+ "self",
+ "true",
+ // functions
"assert",
"breakpoint",
+ "class",
+ "extends",
+ "func",
+ "preload",
+ "setget",
+ "signal",
+ "tool",
"yield",
+ // var
+ "const",
+ "enum",
+ "export",
+ "onready",
"static",
- "float",
- "int",
- "signal",
+ "var",
+ // control flow
+ "break",
+ "continue",
+ "if",
+ "elif",
+ "else",
+ "for",
+ "pass",
+ "return",
+ "while",
0};
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index a69f99314a..663fc985a7 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -260,7 +260,7 @@ friend class GDScriptLanguage;
Map<StringName,Variant> constants;
Map<StringName,GDFunction> member_functions;
Map<StringName,MemberInfo> member_indices; //members are just indices to the instanced script.
- Map<StringName,Ref<GDScript> > subclasses;
+ Map<StringName,Ref<GDScript> > subclasses;
Map<StringName,Vector<StringName> > _signals;
#ifdef TOOLS_ENABLED
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 71c56aba01..56eacfd20e 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -541,14 +541,14 @@ void GDTokenizerText::_advance() {
}
INCPOS(1);
is_node_path=true;
-
+
case '\'':
case '"': {
-
+
if (GETCHAR(0)=='\'')
string_mode=STRING_SINGLE_QUOTE;
-
-
+
+
int i=1;
if (string_mode==STRING_DOUBLE_QUOTE && GETCHAR(i)=='"' && GETCHAR(i+1)=='"') {
i+=2;
@@ -1054,7 +1054,7 @@ Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
const uint8_t *buf=p_buffer.ptr();
int total_len=p_buffer.size();
ERR_FAIL_COND_V( p_buffer.size()<24 || p_buffer[0]!='G' || p_buffer[1]!='D' || p_buffer[2]!='S' || p_buffer[3]!='C',ERR_INVALID_DATA);
-
+
int version = decode_uint32(&buf[4]);
if (version>BYTECODE_VERSION) {
ERR_EXPLAIN("Bytecode is too New! Please use a newer engine version.");
@@ -1066,13 +1066,13 @@ Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
int token_count = decode_uint32(&buf[20]);
const uint8_t *b=buf;
-
+
b=&buf[24];
total_len-=24;
-
+
identifiers.resize(identifier_count);
for(int i=0;i<identifier_count;i++) {
-
+
int len = decode_uint32(b);
ERR_FAIL_COND_V(len>total_len,ERR_INVALID_DATA);
b+=4;
@@ -1089,7 +1089,7 @@ Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
total_len-=len+4;
identifiers[i]=s;
}
-
+
constants.resize(constant_count);
for(int i=0;i<constant_count;i++) {
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 7d463b13d4..e8b443a9e3 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -122,7 +122,7 @@ bool GridMap::_set(const StringName& p_name, const Variant& p_value) {
Octant &g = *octant_map[ok];
g.baked=b;
- g.bake_instance=VS::get_singleton()->instance_create();;
+ g.bake_instance=VS::get_singleton()->instance_create();;
VS::get_singleton()->instance_set_base(g.bake_instance,g.baked->get_rid());
VS::get_singleton()->instance_geometry_set_baked_light(g.bake_instance,baked_light_instance?baked_light_instance->get_baked_light_instance():RID());
}
@@ -398,7 +398,7 @@ void GridMap::set_cell_item(int p_x,int p_y,int p_z, int p_item,int p_rot){
PhysicsServer::get_singleton()->free(g.collision_debug_instance);
}
- memdelete(&g);
+ memdelete(&g);
octant_map.erase(octantkey);
} else {
@@ -984,7 +984,7 @@ void GridMap::_notification(int p_what) {
void GridMap::_queue_dirty_map() {
if (awaiting_update)
- return;
+ return;
if (is_inside_world()) {
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 3d645de38f..fab8458b26 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -59,7 +59,7 @@ for x in env.android_dependencies:
gradle_java_dirs_text=""
for x in env.android_java_dirs:
- gradle_java_dirs_text+=",'"+x+"'"
+ gradle_java_dirs_text+=",'"+x.replace("\\","/")+"'"
gradle_res_dirs_text=""
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index d4755f4ed6..0f1cbdc73a 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1129,7 +1129,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
if (file=="lib/armeabi/libgodot_android.so" && !export_arm) {
skip=true;
}
-
+
if (file.begins_with("META-INF") && _signed) {
skip=true;
}
@@ -1493,6 +1493,16 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) {
OS::get_singleton()->delay_usec(3000000);
}
+ if (EditorSettings::get_singleton()->get("android/shutdown_adb_on_exit")) {
+ String adb=EditorSettings::get_singleton()->get("android/adb");
+ if (!FileAccess::exists(adb)) {
+ return; //adb not configured
+ }
+
+ List<String> args;
+ args.push_back("kill-server");
+ OS::get_singleton()->execute(adb,args,true);
+ };
}
Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index 7a038cca64..334d32de0c 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -122,7 +122,7 @@ uint8_t FileAccessAndroid::get_8() const {
}
- uint8_t byte;
+ uint8_t byte;
AAsset_read(a,&byte,1);
pos++;
return byte;
diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp
index b1b758edb1..da8ceaff14 100644
--- a/platform/android/file_access_jandroid.cpp
+++ b/platform/android/file_access_jandroid.cpp
@@ -203,7 +203,7 @@ void FileAccessJAndroid::setup( jobject p_io) {
__android_log_print(ANDROID_LOG_INFO,"godot","STEP6");
cls=(jclass)env->NewGlobalRef(c);
- _file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I");
+ _file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I");
if(_file_open != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_open ok!!");
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
index aef6591864..7c5ac33c85 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java
@@ -54,6 +54,8 @@ public class GodotLib {
public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
public static native void joybutton(int p_device, int p_but, boolean p_pressed);
public static native void joyaxis(int p_device, int p_axis, float p_value);
+ public static native void joyhat(int p_device, int p_hat_x, int p_hat_y);
+ public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
public static native void focusin();
public static native void focusout();
public static native void audio();
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index 492eb4cb54..e210161e8b 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -36,14 +36,21 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.content.ContextWrapper;
import android.view.InputDevice;
+import android.hardware.input.InputManager;
import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
+import org.godotengine.godot.input.InputManagerCompat;
+import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
@@ -62,7 +69,7 @@ import javax.microedition.khronos.opengles.GL10;
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
-public class GodotView extends GLSurfaceView {
+public class GodotView extends GLSurfaceView implements InputDeviceListener {
private static String TAG = "GodotView";
private static final boolean DEBUG = false;
@@ -75,6 +82,8 @@ public class GodotView extends GLSurfaceView {
private Godot activity;
+
+ private InputManagerCompat mInputManager;
public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, boolean p_use_32_bits, Godot p_activity) {
super(context);
ctx=context;
@@ -88,7 +97,8 @@ public class GodotView extends GLSurfaceView {
//will only work on SDK 11+!!
setPreserveEGLContextOnPause(true);
}
-
+ mInputManager = InputManagerCompat.Factory.getInputManager(this.getContext());
+ mInputManager.registerInputDeviceListener(this, null);
init(false, 16, 0);
}
@@ -119,50 +129,112 @@ public class GodotView extends GLSurfaceView {
button = 3;
break;
case KeyEvent.KEYCODE_BUTTON_L1:
- button = 4;
+ button = 9;
break;
case KeyEvent.KEYCODE_BUTTON_L2:
- button = 6;
+ button = 15;
break;
case KeyEvent.KEYCODE_BUTTON_R1:
- button = 5;
+ button = 10;
break;
case KeyEvent.KEYCODE_BUTTON_R2:
- button = 7;
+ button = 16;
break;
case KeyEvent.KEYCODE_BUTTON_SELECT:
- button = 10;
+ button = 4;
break;
case KeyEvent.KEYCODE_BUTTON_START:
- button = 11;
+ button = 6;
break;
case KeyEvent.KEYCODE_BUTTON_THUMBL:
- button = 8;
+ button = 7;
break;
case KeyEvent.KEYCODE_BUTTON_THUMBR:
- button = 9;
+ button = 8;
break;
case KeyEvent.KEYCODE_DPAD_UP:
- button = 12;
+ button = 11;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
- button = 13;
+ button = 12;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
- button = 14;
+ button = 13;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
- button = 15;
+ button = 14;
+ break;
+ case KeyEvent.KEYCODE_BUTTON_C:
+ button = 17;
+ break;
+ case KeyEvent.KEYCODE_BUTTON_Z:
+ button = 18;
break;
default:
- button = keyCode - KeyEvent.KEYCODE_BUTTON_1;
+ button = keyCode - KeyEvent.KEYCODE_BUTTON_1 + 20;
break;
};
-
return button;
};
+ private static class joystick {
+ public int device_id;
+ public String name;
+ public ArrayList<InputDevice.MotionRange> axes;
+ public ArrayList<InputDevice.MotionRange> hats;
+ }
+
+ private static class RangeComparator implements Comparator<InputDevice.MotionRange> {
+ @Override
+ public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) {
+ return arg0.getAxis() - arg1.getAxis();
+ }
+ }
+
+ ArrayList<joystick> joy_devices = new ArrayList<joystick>();
+
+ private int find_joy_device(int device_id) {
+ for (int i=0; i<joy_devices.size(); i++) {
+ if (joy_devices.get(i).device_id == device_id) {
+ return i;
+ }
+ }
+ onInputDeviceAdded(device_id);
+ return joy_devices.size() - 1;
+ }
+
+ @Override public void onInputDeviceAdded(int deviceId) {
+ joystick joy = new joystick();
+ joy.device_id = deviceId;
+ int id = joy_devices.size();
+ InputDevice device = mInputManager.getInputDevice(deviceId);
+ joy.name = device.getName();
+ joy.axes = new ArrayList<InputDevice.MotionRange>();
+ joy.hats = new ArrayList<InputDevice.MotionRange>();
+ List<InputDevice.MotionRange> ranges = device.getMotionRanges();
+ Collections.sort(ranges, new RangeComparator());
+ for (InputDevice.MotionRange range : ranges) {
+ if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
+ joy.hats.add(range);
+ }
+ else {
+ joy.axes.add(range);
+ }
+ }
+ joy_devices.add(joy);
+ GodotLib.joyconnectionchanged(id, true, joy.name);
+ }
+
+ @Override public void onInputDeviceRemoved(int deviceId) {
+ int id = find_joy_device(deviceId);
+ joy_devices.remove(id);
+ GodotLib.joyconnectionchanged(id, false, "");
+ }
+
+ @Override public void onInputDeviceChanged(int deviceId) {
+
+ }
@Override public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
@@ -177,7 +249,7 @@ public class GodotView extends GLSurfaceView {
if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) {
int button = get_godot_button(keyCode);
- int device = event.getDeviceId();
+ int device = find_joy_device(event.getDeviceId());
GodotLib.joybutton(device, button, false);
return true;
@@ -209,7 +281,8 @@ public class GodotView extends GLSurfaceView {
if (event.getRepeatCount() > 0) // ignore key echo
return true;
int button = get_godot_button(keyCode);
- int device = event.getDeviceId();
+ int device = find_joy_device(event.getDeviceId());
+
//Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device));
GodotLib.joybutton(device, button, true);
@@ -221,125 +294,27 @@ public class GodotView extends GLSurfaceView {
return super.onKeyDown(keyCode, event);
}
- public float axis_value(MotionEvent p_event, InputDevice p_device, int p_axis, int p_pos) {
-
- final InputDevice.MotionRange range = p_device.getMotionRange(p_axis, p_event.getSource());
- if (range == null)
- return 0;
-
- //Log.e(TAG, String.format("axis ranges %f, %f, %f", range.getRange(), range.getMin(), range.getMax()));
-
- final float flat = range.getFlat();
- final float value =
- p_pos < 0 ? p_event.getAxisValue(p_axis):
- p_event.getHistoricalAxisValue(p_axis, p_pos);
-
- final float absval = Math.abs(value);
- if (absval <= flat) {
- return 0;
- };
-
- final float ret = (value - range.getMin()) / range.getRange() * 2 - 1.0f;
-
- return ret;
- };
-
- float[] last_axis_values = { 0, 0, 0, 0, -1, -1 };
- boolean[] last_axis_buttons = { false, false, false, false, false, false }; // dpad up down left right, ltrigger, rtrigger
-
- public void process_axis_state(MotionEvent p_event, int p_pos) {
-
- int device_id = p_event.getDeviceId();
- InputDevice device = p_event.getDevice();
- float val;
-
- val = axis_value(p_event, device, MotionEvent.AXIS_X, p_pos);
- if (val != last_axis_values[0]) {
- last_axis_values[0] = val;
- //Log.e(TAG, String.format("axis moved! axis %d, value %f", 0, val));
- GodotLib.joyaxis(device_id, 0, val);
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_Y, p_pos);
- if (val != last_axis_values[1]) {
- last_axis_values[1] = val;
- //Log.e(TAG, String.format("axis moved! axis %d, value %f", 1, val));
- GodotLib.joyaxis(device_id, 1, val);
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_Z, p_pos);
- if (val != last_axis_values[2]) {
- last_axis_values[2] = val;
- //Log.e(TAG, String.format("axis moved! axis %d, value %f", 2, val));
- GodotLib.joyaxis(device_id, 2, val);
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_RZ, p_pos);
- if (val != last_axis_values[3]) {
- last_axis_values[3] = val;
- //Log.e(TAG, String.format("axis moved! axis %d, value %f", 3, val));
- GodotLib.joyaxis(device_id, 3, val);
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_LTRIGGER, p_pos);
- if (val != last_axis_values[4]) {
- last_axis_values[4] = val;
- if ((val != 0) != (last_axis_buttons[4])) {
- last_axis_buttons[4] = (val != 0);
- GodotLib.joybutton(device_id, 6, (val != 0));
- };
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_RTRIGGER, p_pos);
- if (val != last_axis_values[5]) {
- last_axis_values[5] = val;
- if ((val != 0) != (last_axis_buttons[5])) {
- last_axis_buttons[5] = (val != 0);
- GodotLib.joybutton(device_id, 7, (val != 0));
- };
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_HAT_Y, p_pos);
-
- if (last_axis_buttons[0] != (val > 0)) {
- last_axis_buttons[0] = val > 0;
- GodotLib.joybutton(device_id, 12, val > 0);
- };
- if (last_axis_buttons[1] != (val < 0)) {
- last_axis_buttons[1] = val < 0;
- GodotLib.joybutton(device_id, 13, val > 0);
- };
-
- val = axis_value(p_event, device, MotionEvent.AXIS_HAT_X, p_pos);
- if (last_axis_buttons[2] != (val < 0)) {
- last_axis_buttons[2] = val < 0;
- GodotLib.joybutton(device_id, 14, val < 0);
- };
- if (last_axis_buttons[3] != (val > 0)) {
- last_axis_buttons[3] = val > 0;
- GodotLib.joybutton(device_id, 15, val > 0);
- };
- };
-
@Override public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
- // Process all historical movement samples in the batch
- final int historySize = event.getHistorySize();
+ int device_id = find_joy_device(event.getDeviceId());
+ joystick joy = joy_devices.get(device_id);
- // Process the movements starting from the
- // earliest historical position in the batch
- for (int i = 0; i < historySize; i++) {
- // Process the event at historical position i
- process_axis_state(event, i);
+ for (int i = 0; i < joy.axes.size(); i++) {
+ InputDevice.MotionRange range = joy.axes.get(i);
+ float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
+ //Log.e(TAG, String.format("axis event: %d, value %f", i, value));
+ GodotLib.joyaxis(device_id, i, value);
}
- // Process the current movement sample in the batch (position -1)
- process_axis_state(event, -1);
+ for (int i = 0; i < joy.hats.size(); i+=2) {
+ int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
+ int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis()));
+ //Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY));
+ GodotLib.joyhat(device_id, hatX, hatY);
+ }
return true;
-
-
};
return super.onGenericMotionEvent(event);
@@ -413,12 +388,12 @@ public class GodotView extends GLSurfaceView {
/* Fallback if 32bit View is not supported*/
private static class FallbackConfigChooser extends ConfigChooser {
private ConfigChooser fallback;
-
+
public FallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, ConfigChooser fallback) {
super(r, g, b, a, depth, stencil);
this.fallback = fallback;
}
-
+
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
EGLConfig ec = super.chooseConfig(egl, display, configs);
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
new file mode 100644
index 0000000000..4615d2fbb5
--- /dev/null
+++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.godotengine.godot.input;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.Handler;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+public interface InputManagerCompat {
+ /**
+ * Gets information about the input device with the specified id.
+ *
+ * @param id The device id
+ * @return The input device or null if not found
+ */
+ public InputDevice getInputDevice(int id);
+
+ /**
+ * Gets the ids of all input devices in the system.
+ *
+ * @return The input device ids.
+ */
+ public int[] getInputDeviceIds();
+
+ /**
+ * Registers an input device listener to receive notifications about when
+ * input devices are added, removed or changed.
+ *
+ * @param listener The listener to register.
+ * @param handler The handler on which the listener should be invoked, or
+ * null if the listener should be invoked on the calling thread's
+ * looper.
+ */
+ public void registerInputDeviceListener(InputManagerCompat.InputDeviceListener listener,
+ Handler handler);
+
+ /**
+ * Unregisters an input device listener.
+ *
+ * @param listener The listener to unregister.
+ */
+ public void unregisterInputDeviceListener(InputManagerCompat.InputDeviceListener listener);
+
+ /*
+ * The following three calls are to simulate V16 behavior on pre-Jellybean
+ * devices. If you don't call them, your callback will never be called
+ * pre-API 16.
+ */
+
+ /**
+ * Pass the motion events to the InputManagerCompat. This is used to
+ * optimize for polling for controllers. If you do not pass these events in,
+ * polling will cause regular object creation.
+ *
+ * @param event the motion event from the app
+ */
+ public void onGenericMotionEvent(MotionEvent event);
+
+ /**
+ * Tell the V9 input manager that it should stop polling for disconnected
+ * devices. You can call this during onPause in your activity, although you
+ * might want to call it whenever your game is not active (or whenever you
+ * don't care about being notified of new input devices)
+ */
+ public void onPause();
+
+ /**
+ * Tell the V9 input manager that it should start polling for disconnected
+ * devices. You can call this during onResume in your activity, although you
+ * might want to call it less often (only when the gameplay is actually
+ * active)
+ */
+ public void onResume();
+
+ public interface InputDeviceListener {
+ /**
+ * Called whenever the input manager detects that a device has been
+ * added. This will only be called in the V9 version when a motion event
+ * is detected.
+ *
+ * @param deviceId The id of the input device that was added.
+ */
+ void onInputDeviceAdded(int deviceId);
+
+ /**
+ * Called whenever the properties of an input device have changed since
+ * they were last queried. This will not be called for the V9 version of
+ * the API.
+ *
+ * @param deviceId The id of the input device that changed.
+ */
+ void onInputDeviceChanged(int deviceId);
+
+ /**
+ * Called whenever the input manager detects that a device has been
+ * removed. For the V9 version, this can take some time depending on the
+ * poll rate.
+ *
+ * @param deviceId The id of the input device that was removed.
+ */
+ void onInputDeviceRemoved(int deviceId);
+ }
+
+ /**
+ * Use this to construct a compatible InputManager.
+ */
+ public static class Factory {
+
+ /**
+ * Constructs and returns a compatible InputManger
+ *
+ * @param context the Context that will be used to get the system
+ * service from
+ * @return a compatible implementation of InputManager
+ */
+ public static InputManagerCompat getInputManager(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ return new InputManagerV16(context);
+ } else {
+ return new InputManagerV9();
+ }
+ }
+ }
+}
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
new file mode 100644
index 0000000000..f05701f455
--- /dev/null
+++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.godotengine.godot.input;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.os.Build;
+import android.os.Handler;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+public class InputManagerV16 implements InputManagerCompat {
+
+ private final InputManager mInputManager;
+ private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners;
+
+ public InputManagerV16(Context context) {
+ mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
+ mListeners = new HashMap<InputManagerCompat.InputDeviceListener, V16InputDeviceListener>();
+ }
+
+ @Override
+ public InputDevice getInputDevice(int id) {
+ return mInputManager.getInputDevice(id);
+ }
+
+ @Override
+ public int[] getInputDeviceIds() {
+ return mInputManager.getInputDeviceIds();
+ }
+
+ static class V16InputDeviceListener implements InputManager.InputDeviceListener {
+ final InputManagerCompat.InputDeviceListener mIDL;
+
+ public V16InputDeviceListener(InputDeviceListener idl) {
+ mIDL = idl;
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ mIDL.onInputDeviceAdded(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ mIDL.onInputDeviceChanged(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ mIDL.onInputDeviceRemoved(deviceId);
+ }
+
+ }
+
+ @Override
+ public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
+ V16InputDeviceListener v16Listener = new V16InputDeviceListener(listener);
+ mInputManager.registerInputDeviceListener(v16Listener, handler);
+ mListeners.put(listener, v16Listener);
+ }
+
+ @Override
+ public void unregisterInputDeviceListener(InputDeviceListener listener) {
+ V16InputDeviceListener curListener = mListeners.remove(listener);
+ if (null != curListener)
+ {
+ mInputManager.unregisterInputDeviceListener(curListener);
+ }
+
+ }
+
+ @Override
+ public void onGenericMotionEvent(MotionEvent event) {
+ // unused in V16
+ }
+
+ @Override
+ public void onPause() {
+ // unused in V16
+ }
+
+ @Override
+ public void onResume() {
+ // unused in V16
+ }
+
+}
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
new file mode 100644
index 0000000000..0334c00997
--- /dev/null
+++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.godotengine.godot.input;
+
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayDeque;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Queue;
+
+public class InputManagerV9 implements InputManagerCompat {
+ private static final String LOG_TAG = "InputManagerV9";
+ private static final int MESSAGE_TEST_FOR_DISCONNECT = 101;
+ private static final long CHECK_ELAPSED_TIME = 3000L;
+
+ private static final int ON_DEVICE_ADDED = 0;
+ private static final int ON_DEVICE_CHANGED = 1;
+ private static final int ON_DEVICE_REMOVED = 2;
+
+ private final SparseArray<long[]> mDevices;
+ private final Map<InputDeviceListener, Handler> mListeners;
+ private final Handler mDefaultHandler;
+
+ private static class PollingMessageHandler extends Handler {
+ private final WeakReference<InputManagerV9> mInputManager;
+
+ PollingMessageHandler(InputManagerV9 im) {
+ mInputManager = new WeakReference<InputManagerV9>(im);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what) {
+ case MESSAGE_TEST_FOR_DISCONNECT:
+ InputManagerV9 imv = mInputManager.get();
+ if (null != imv) {
+ long time = SystemClock.elapsedRealtime();
+ int size = imv.mDevices.size();
+ for (int i = 0; i < size; i++) {
+ long[] lastContact = imv.mDevices.valueAt(i);
+ if (null != lastContact) {
+ if (time - lastContact[0] > CHECK_ELAPSED_TIME) {
+ // check to see if the device has been
+ // disconnected
+ int id = imv.mDevices.keyAt(i);
+ if (null == InputDevice.getDevice(id)) {
+ // disconnected!
+ imv.notifyListeners(ON_DEVICE_REMOVED, id);
+ imv.mDevices.remove(id);
+ } else {
+ lastContact[0] = time;
+ }
+ }
+ }
+ }
+ sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT,
+ CHECK_ELAPSED_TIME);
+ }
+ break;
+ }
+ }
+
+ }
+
+ public InputManagerV9() {
+ mDevices = new SparseArray<long[]>();
+ mListeners = new HashMap<InputDeviceListener, Handler>();
+ mDefaultHandler = new PollingMessageHandler(this);
+ // as a side-effect, populates our collection of watched
+ // input devices
+ getInputDeviceIds();
+ }
+
+ @Override
+ public InputDevice getInputDevice(int id) {
+ return InputDevice.getDevice(id);
+ }
+
+ @Override
+ public int[] getInputDeviceIds() {
+ // add any hitherto unknown devices to our
+ // collection of watched input devices
+ int[] activeDevices = InputDevice.getDeviceIds();
+ long time = SystemClock.elapsedRealtime();
+ for ( int id : activeDevices ) {
+ long[] lastContact = mDevices.get(id);
+ if ( null == lastContact ) {
+ // we have a new device
+ mDevices.put(id, new long[] { time });
+ }
+ }
+ return activeDevices;
+ }
+
+ @Override
+ public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
+ mListeners.remove(listener);
+ if (handler == null) {
+ handler = mDefaultHandler;
+ }
+ mListeners.put(listener, handler);
+ }
+
+ @Override
+ public void unregisterInputDeviceListener(InputDeviceListener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void notifyListeners(int why, int deviceId) {
+ // the state of some device has changed
+ if (!mListeners.isEmpty()) {
+ // yes... this will cause an object to get created... hopefully
+ // it won't happen very often
+ for (InputDeviceListener listener : mListeners.keySet()) {
+ Handler handler = mListeners.get(listener);
+ DeviceEvent odc = DeviceEvent.getDeviceEvent(why, deviceId, listener);
+ handler.post(odc);
+ }
+ }
+ }
+
+ private static class DeviceEvent implements Runnable {
+ private int mMessageType;
+ private int mId;
+ private InputDeviceListener mListener;
+ private static Queue<DeviceEvent> sEventQueue = new ArrayDeque<DeviceEvent>();
+
+ private DeviceEvent() {
+ }
+
+ static DeviceEvent getDeviceEvent(int messageType, int id,
+ InputDeviceListener listener) {
+ DeviceEvent curChanged = sEventQueue.poll();
+ if (null == curChanged) {
+ curChanged = new DeviceEvent();
+ }
+ curChanged.mMessageType = messageType;
+ curChanged.mId = id;
+ curChanged.mListener = listener;
+ return curChanged;
+ }
+
+ @Override
+ public void run() {
+ switch (mMessageType) {
+ case ON_DEVICE_ADDED:
+ mListener.onInputDeviceAdded(mId);
+ break;
+ case ON_DEVICE_CHANGED:
+ mListener.onInputDeviceChanged(mId);
+ break;
+ case ON_DEVICE_REMOVED:
+ mListener.onInputDeviceRemoved(mId);
+ break;
+ default:
+ Log.e(LOG_TAG, "Unknown Message Type");
+ break;
+ }
+ // dump this runnable back in the queue
+ sEventQueue.offer(this);
+ }
+ }
+
+ @Override
+ public void onGenericMotionEvent(MotionEvent event) {
+ // detect new devices
+ int id = event.getDeviceId();
+ long[] timeArray = mDevices.get(id);
+ if (null == timeArray) {
+ notifyListeners(ON_DEVICE_ADDED, id);
+ timeArray = new long[1];
+ mDevices.put(id, timeArray);
+ }
+ long time = SystemClock.elapsedRealtime();
+ timeArray[0] = time;
+ }
+
+ @Override
+ public void onPause() {
+ mDefaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT);
+ }
+
+ @Override
+ public void onResume() {
+ mDefaultHandler.sendEmptyMessage(MESSAGE_TEST_FOR_DISCONNECT);
+ }
+
+}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 75c1d78151..b5beb8fa2c 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -41,6 +41,7 @@
#include "core/os/keyboard.h"
#include "java_class_wrapper.h"
#include "android/asset_manager_jni.h"
+#include "main/input_default.h"
static JavaClassWrapper *java_class_wrapper=NULL;
static OS_Android *os_android=NULL;
@@ -639,6 +640,7 @@ struct JAndroidPointerEvent {
static List<JAndroidPointerEvent> pointer_events;
static List<InputEvent> key_events;
+static List<OS_Android::JoystickEvent> joy_events;
static bool initialized=false;
static Mutex *input_mutex=NULL;
static Mutex *suspend_mutex=NULL;
@@ -1067,6 +1069,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv * env, jo
key_events.pop_front();
};
+ while (joy_events.size()) {
+
+ OS_Android::JoystickEvent event = joy_events.front()->get();
+ os_android->process_joy_event(event);
+
+ joy_events.pop_front();
+ }
+
if (quit_request) {
os_android->main_loop_request_quit();
@@ -1380,48 +1390,57 @@ static unsigned int android_get_keysym(unsigned int p_code) {
return KEY_UNKNOWN;
}
-static int find_device(int p_device) {
-
- for (int i=0; i<joy_device_ids.size(); i++) {
-
- if (joy_device_ids[i] == p_device) {
- //print_line("found device at "+String::num(i));
- return i;
- };
- };
-
- //print_line("adding a device at" + String::num(joy_device_ids.size()));
- joy_device_ids.push_back(p_device);
-
- return joy_device_ids.size() - 1;
-};
-
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) {
- InputEvent ievent;
- ievent.type = InputEvent::JOYSTICK_BUTTON;
- ievent.device = find_device(p_device);
- ievent.joy_button.button_index = p_button;
- ievent.joy_button.pressed = p_pressed;
+ OS_Android::JoystickEvent jevent;
+ jevent.device = p_device;
+ jevent.type = OS_Android::JOY_EVENT_BUTTON;
+ jevent.index = p_button;
+ jevent.pressed = p_pressed;
input_mutex->lock();
- key_events.push_back(ievent);
+ joy_events.push_back(jevent);
input_mutex->unlock();
};
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value) {
- InputEvent ievent;
- ievent.type = InputEvent::JOYSTICK_MOTION;
- ievent.device = find_device(p_device);
- ievent.joy_motion.axis = p_axis;
- ievent.joy_motion.axis_value = p_value;
+ OS_Android::JoystickEvent jevent;
+ jevent.device = p_device;
+ jevent.type = OS_Android::JOY_EVENT_AXIS;
+ jevent.index = p_axis;
+ jevent.value = p_value;
input_mutex->lock();
- key_events.push_back(ievent);
+ joy_events.push_back(jevent);
input_mutex->unlock();
};
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv * env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) {
+ OS_Android::JoystickEvent jevent;
+ jevent.device = p_device;
+ jevent.type = OS_Android::JOY_EVENT_HAT;
+ int hat = 0;
+ if (p_hat_x != 0) {
+ if (p_hat_x < 0) hat |= InputDefault::HAT_MASK_LEFT;
+ else hat |= InputDefault::HAT_MASK_RIGHT;
+ }
+ if (p_hat_y != 0) {
+ if (p_hat_y < 0) hat |= InputDefault::HAT_MASK_UP;
+ else hat |= InputDefault::HAT_MASK_DOWN;
+ }
+ jevent.hat = hat;
+ input_mutex->lock();
+ joy_events.push_back(jevent);
+ input_mutex->unlock();
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv * env, jobject obj, jint p_device, jboolean p_connected, jstring p_name) {
+ if (os_android) {
+ String name = env->GetStringUTFChars( p_name, NULL );
+ os_android->joy_connection_changed(p_device, p_connected, name);
+ }
+}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) {
diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h
index efa5b2839d..1d65d21251 100644
--- a/platform/android/java_glue.h
+++ b/platform/android/java_glue.h
@@ -45,6 +45,8 @@ extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value);
+ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv * env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y);
+ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv * env, jobject obj, jint p_device, jboolean p_connected, jstring p_name);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv * env, jobject obj);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 03177317af..2ef28333be 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -178,7 +178,7 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_
physics_2d_server->init();
input = memnew( InputDefault );
-
+ input->set_fallback_mapping("Default Android Gamepad");
}
void OS_Android::set_main_loop( MainLoop * p_main_loop ) {
@@ -304,7 +304,7 @@ void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen)
void OS_Android::set_keep_screen_on(bool p_enabled) {
OS::set_keep_screen_on(p_enabled);
-
+
if (set_keep_screen_on_func) {
set_keep_screen_on_func(p_enabled);
}
@@ -370,6 +370,25 @@ void OS_Android::main_loop_focusin(){
}
+void OS_Android::process_joy_event(OS_Android::JoystickEvent p_event) {
+
+ switch (p_event.type) {
+ case JOY_EVENT_BUTTON:
+ last_id = input->joy_button(last_id, p_event.device, p_event.index, p_event.pressed);
+ break;
+ case JOY_EVENT_AXIS:
+ InputDefault::JoyAxis value;
+ value.min = -1;
+ value.value = p_event.value;
+ last_id = input->joy_axis(last_id, p_event.device, p_event.index, value);
+ break;
+ case JOY_EVENT_HAT:
+ last_id = input->joy_hat(last_id, p_event.device, p_event.hat);
+ break;
+ default:
+ return;
+ }
+}
void OS_Android::process_event(InputEvent p_event) {
@@ -742,6 +761,18 @@ void OS_Android::set_context_is_16_bits(bool p_is_16) {
rasterizer->set_force_16_bits_fbo(p_is_16);
}
+void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) {
+ return input->joy_connection_changed(p_device, p_connected, p_name, "");
+}
+
+bool OS_Android::is_joy_known(int p_device) {
+ return input->is_joy_mapped(p_device);
+}
+
+String OS_Android::get_joy_guid(int p_device) const {
+ return input->get_joy_guid_remapped(p_device);
+}
+
OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id,GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, bool p_use_apk_expansion) {
@@ -765,7 +796,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFu
get_model_func=p_get_model_func;
get_unique_id_func=p_get_unique_id;
get_system_dir_func=p_get_sdir_func;
-
+
video_play_func = p_video_play_func;
video_is_playing_func = p_video_is_playing_func;
video_pause_func = p_video_pause_func;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 1ae42e9cc7..ec1f4119b4 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -83,6 +83,22 @@ public:
Point2 pos;
};
+ enum {
+ JOY_EVENT_BUTTON = 0,
+ JOY_EVENT_AXIS = 1,
+ JOY_EVENT_HAT = 2
+ };
+
+ struct JoystickEvent {
+
+ int device;
+ int type;
+ int index;
+ bool pressed;
+ float value;
+ int hat;
+ };
+
private:
Vector<TouchPos> touch;
@@ -177,9 +193,9 @@ public:
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
-
+
virtual void set_keep_screen_on(bool p_enabled);
-
+
virtual Size2 get_window_size() const;
virtual String get_name();
@@ -224,6 +240,7 @@ public:
void process_accelerometer(const Vector3& p_accelerometer);
void process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points);
+ void process_joy_event(JoystickEvent p_event);
void process_event(InputEvent p_event);
void init_video_mode(int p_video_width,int p_video_height);
@@ -232,6 +249,10 @@ public:
virtual void native_video_pause();
virtual void native_video_stop();
+ virtual bool is_joy_known(int p_device);
+ virtual String get_joy_guid(int p_device) const;
+ void joy_connection_changed(int p_device, bool p_connected, String p_name);
+
OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id,GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, bool p_use_apk_expansion);
~OS_Android();
diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp
index 2acd920f31..a17c4cb134 100644
--- a/platform/bb10/export/export.cpp
+++ b/platform/bb10/export/export.cpp
@@ -482,7 +482,7 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
return err;
if (ec!=0)
return ERR_CANT_CREATE;
-
+
return OK;
}
diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp
index d2a350cf83..58ea26b8c9 100644
--- a/platform/bb10/os_bb10.cpp
+++ b/platform/bb10/os_bb10.cpp
@@ -29,7 +29,6 @@
#include "os_bb10.h"
#include "drivers/gles2/rasterizer_gles2.h"
-#include "drivers/gles1/rasterizer_gles1.h"
#include "servers/visual/visual_server_raster.h"
#include "core/os/dir_access.h"
@@ -605,6 +604,9 @@ String OSBB10::get_data_dir() const {
return data_dir;
};
+Size2 OSBB10::get_window_size() const {
+ return Vector2(default_videomode.width, default_videomode.height);
+}
OSBB10::OSBB10() {
diff --git a/platform/bb10/os_bb10.h b/platform/bb10/os_bb10.h
index a0481d1190..4ee5af8323 100644
--- a/platform/bb10/os_bb10.h
+++ b/platform/bb10/os_bb10.h
@@ -32,6 +32,7 @@
#include "os/input.h"
#include "drivers/unix/os_unix.h"
#include "os/main_loop.h"
+#include "main/input_default.h"
#include "servers/physics/physics_server_sw.h"
#include "servers/spatial_sound/spatial_sound_server_sw.h"
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
@@ -135,6 +136,7 @@ public:
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
+ virtual Size2 get_window_size() const;
virtual String get_name();
virtual MainLoop *get_main_loop() const;
diff --git a/platform/flash/dir_access_flash.cpp b/platform/flash/dir_access_flash.cpp
index 443242fd99..ce9eed2c59 100644
--- a/platform/flash/dir_access_flash.cpp
+++ b/platform/flash/dir_access_flash.cpp
@@ -183,12 +183,12 @@ size_t DirAccessFlash::get_space_left() {
Error DirAccessFlash::rename(String p_from, String p_to) {
- return FAILED;
+ ERR_FAIL_V(ERR_UNAVAILABLE);
};
Error DirAccessFlash::remove(String p_name) {
- return FAILED;
+ ERR_FAIL_V(ERR_UNAVAILABLE);
};
extern char* psp_drive;
diff --git a/platform/flash/include/GL/gl.h b/platform/flash/include/GL/gl.h
index e65e1bc8a8..d6387cc5a4 100644
--- a/platform/flash/include/GL/gl.h
+++ b/platform/flash/include/GL/gl.h
@@ -35,7 +35,7 @@
/**********************************************************************
* Begin system-specific stuff. Do not do any of this when building
* for SciTech SNAP, as this is all done before this header file is
- * included.
+ * included.
*/
#if !defined(__SCITECH_SNAP__)
@@ -60,7 +60,7 @@
# define GLAPI extern
# endif /* _STATIC_MESA support */
# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */
-# define GLAPIENTRY
+# define GLAPIENTRY
# else
# define GLAPIENTRY __stdcall
# endif
diff --git a/platform/flash/include/GL/glext.h b/platform/flash/include/GL/glext.h
index 73467e3cad..d032419a10 100644
--- a/platform/flash/include/GL/glext.h
+++ b/platform/flash/include/GL/glext.h
@@ -7,7 +7,7 @@ extern "C" {
/*
** Copyright (c) 2007-2011 The Khronos Group Inc.
-**
+**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
@@ -15,10 +15,10 @@ extern "C" {
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
-**
+**
** THE MATERIALS ARE 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.
diff --git a/platform/flash/include/GL/glxext.h b/platform/flash/include/GL/glxext.h
index e042cf8794..47eeae61dc 100644
--- a/platform/flash/include/GL/glxext.h
+++ b/platform/flash/include/GL/glxext.h
@@ -7,7 +7,7 @@ extern "C" {
/*
** Copyright (c) 2007-2010 The Khronos Group Inc.
-**
+**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
@@ -15,10 +15,10 @@ extern "C" {
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
-**
+**
** THE MATERIALS ARE 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.
diff --git a/platform/flash/rasterizer_flash.cpp b/platform/flash/rasterizer_flash.cpp
index a36890e3d8..f450956592 100644
--- a/platform/flash/rasterizer_flash.cpp
+++ b/platform/flash/rasterizer_flash.cpp
@@ -1612,7 +1612,7 @@ void RasterizerFlash::_add_geometry( const Geometry* p_geometry, const InstanceD
if (m->flags[VS::MATERIAL_FLAG_UNSHADED]) {
- e->light_key-=1;
+ e->light_key-=1;
} else {
//setup lights
diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp
index 21107a52a4..330046162d 100644
--- a/platform/haiku/context_gl_haiku.cpp
+++ b/platform/haiku/context_gl_haiku.cpp
@@ -38,6 +38,6 @@ int ContextGL_Haiku::get_window_width() {
int ContextGL_Haiku::get_window_height() {
return window->Bounds().IntegerHeight();
-}
+}
#endif
diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h
index e37fe14970..63caec6fb3 100644
--- a/platform/haiku/context_gl_haiku.h
+++ b/platform/haiku/context_gl_haiku.h
@@ -18,8 +18,8 @@ public:
~ContextGL_Haiku();
virtual Error initialize();
- virtual void release_current();
- virtual void make_current();
+ virtual void release_current();
+ virtual void make_current();
virtual void swap_buffers();
virtual int get_window_width();
virtual int get_window_height();
diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp
index b4e5e50891..fa5651d89a 100644
--- a/platform/haiku/godot_haiku.cpp
+++ b/platform/haiku/godot_haiku.cpp
@@ -3,17 +3,17 @@
int main(int argc, char* argv[]) {
OS_Haiku os;
-
+
Error error = Main::setup(argv[0], argc-1, &argv[1]);
if (error != OK) {
return 255;
}
-
+
if (Main::start()) {
os.run();
}
-
+
Main::cleanup();
-
+
return os.get_exit_code();
}
diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp
index d7bde9a727..f0622d3f1d 100644
--- a/platform/haiku/key_mapping_haiku.cpp
+++ b/platform/haiku/key_mapping_haiku.cpp
@@ -70,7 +70,7 @@ static _HaikuTranslatePair _hb_to_keycode[] = {
{ KEY_INSERT, B_INSERT },
{ KEY_DELETE, B_DELETE },
// { KEY_HELP, ??? },
-
+
{ KEY_0, (0x30) },
{ KEY_1, (0x31) },
{ KEY_2, (0x32) },
@@ -160,7 +160,7 @@ unsigned int KeyMappingHaiku::get_keysym(int32 raw_char, int32 key) {
if (raw_char == B_UP_ARROW && key == 0x38) { return KEY_KP_8; }
if (raw_char == B_PAGE_UP && key == 0x39) { return KEY_KP_9; }
if (raw_char == 0x2F && key == 0x23) { return KEY_KP_DIVIDE; }
- if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBSTRACT; }
+ if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBTRACT; }
if (raw_char == B_DELETE && key == 0x65) { return KEY_KP_PERIOD; }
if (raw_char == 0x10) {
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index ef483657ca..308800cec0 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -138,7 +138,7 @@ void OS_Haiku::finalize() {
memdelete(spatial_sound_2d_server);
memdelete(sample_manager);
-
+
audio_server->finish();
memdelete(audio_server);
diff --git a/platform/iphone/Appirater.h b/platform/iphone/Appirater.h
index 6ff25532f7..9c7e3febf6 100644
--- a/platform/iphone/Appirater.h
+++ b/platform/iphone/Appirater.h
@@ -27,10 +27,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
This file is part of Appirater.
-
+
Copyright (c) 2010, Arash Payan
All rights reserved.
-
+
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
@@ -39,10 +39,10 @@
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
@@ -119,7 +119,7 @@ extern NSString *const kAppiraterDeclinedToRate;
a 'use'. You tell Appirater about these events using the two methods:
[Appirater appLaunched:]
[Appirater appEnteredForeground:]
-
+
Users need to 'use' the same version of the app this many times before
before they will be prompted to rate it.
*/
@@ -161,7 +161,7 @@ extern NSString *const kAppiraterDeclinedToRate;
/*
DEPRECATED: While still functional, it's better to use
appLaunched:(BOOL)canPromptForRating instead.
-
+
Calls [Appirater appLaunched:YES]. See appLaunched: for details of functionality.
*/
+ (void)appLaunched:(int)p_app_id;
@@ -171,7 +171,7 @@ extern NSString *const kAppiraterDeclinedToRate;
support multitasking, the 'uses' count will be incremented. You should
call this method at the end of your application delegate's
application:didFinishLaunchingWithOptions: method.
-
+
If the app has been used enough to be rated (and enough significant events),
you can suppress the rating alert
by passing NO for canPromptForRating. The rating alert will simply be postponed
@@ -185,7 +185,7 @@ extern NSString *const kAppiraterDeclinedToRate;
Tells Appirater that the app was brought to the foreground on multitasking
devices. You should call this method from the application delegate's
applicationWillEnterForeground: method.
-
+
If the app has been used enough to be rated (and enough significant events),
you can suppress the rating alert
by passing NO for canPromptForRating. The rating alert will simply be postponed
@@ -201,7 +201,7 @@ extern NSString *const kAppiraterDeclinedToRate;
calls, then you might want to call this method whenever the user places
a call. If it's a game, you might want to call this whenever the user
beats a level boss.
-
+
If the user has performed enough significant events and used the app enough,
you can suppress the rating alert by passing NO for canPromptForRating. The
rating alert will simply be postponed until it is called again with YES for
diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h
index e69ddc839a..9c27c6a025 100755
--- a/platform/iphone/gl_view.h
+++ b/platform/iphone/gl_view.h
@@ -42,15 +42,15 @@
// The pixel dimensions of the backbuffer
GLint backingWidth;
GLint backingHeight;
-
+
EAGLContext *context;
-
+
// OpenGL names for the renderbuffer and framebuffers used to render to this view
GLuint viewRenderbuffer, viewFramebuffer;
-
+
// OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist)
GLuint depthRenderbuffer;
-
+
BOOL useCADisplayLink;
// CADisplayLink available on 3.1+ synchronizes the animation timer & drawing with the refresh rate of the display, only supports animation intervals of 1/60 1/30 & 1/15
CADisplayLink *displayLink;
@@ -58,12 +58,12 @@
// An animation timer that, when animation is started, will periodically call -drawView at the given rate.
// Only used if CADisplayLink is not
NSTimer *animationTimer;
-
+
NSTimeInterval animationInterval;
-
+
// Delegate to do our drawing, called by -drawView, which can be called manually or via the animation timer.
id<GLViewDelegate> delegate;
-
+
// Flag to denote that the -setupView method of a delegate has been called.
// Resets to NO whenever the delegate changes.
BOOL delegateSetup;
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 88361e87e4..94fbb9e174 100755
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -58,6 +58,7 @@ void _show_keyboard(String);
void _hide_keyboard();
bool _play_video(String, float, String, String);
bool _is_video_playing();
+void _pause_video();
void _focus_out_video();
void _unpause_video();
void _stop_video();
@@ -74,64 +75,30 @@ void _hide_keyboard() {
keyboard_text = "";
};
-/*
-bool _play_video(String p_path, float p_volume) {
-
- float player_volume = p_volume * AudioServer::get_singleton()->get_singleton()->get_stream_global_volume_scale();
- video_previous_volume = [[MPMusicPlayerController applicationMusicPlayer] volume];
-
- //[[MPMusicPlayerController applicationMusicPlayer] setVolume: player_volume];
-
- p_path = Globals::get_singleton()->globalize_path(p_path);
-
- NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
- NSURL *file_url = [NSURL fileURLWithPath:file_path];
-
- _instance.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:file_url];
- _instance.moviePlayerController.controlStyle = MPMovieControlStyleNone;
- [_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFit];
- //[_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFill];
-
- [[NSNotificationCenter defaultCenter] addObserver:_instance
- selector:@selector(moviePlayBackDidFinish:)
- name:MPMoviePlayerPlaybackDidFinishNotification
- object:_instance.moviePlayerController];
-
- [_instance.moviePlayerController.view setFrame:_instance.bounds];
- _instance.moviePlayerController.view.userInteractionEnabled = NO;
- [_instance addSubview:_instance.moviePlayerController.view];
- [_instance.moviePlayerController play];
-
- video_playing = true;
-
- return true;
-}
-*/
-
bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
p_path = Globals::get_singleton()->globalize_path(p_path);
NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
- //NSURL *file_url = [NSURL fileURLWithPath:file_path];
_instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]];
+
_instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset];
[_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil];
- _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem];
- _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
+ _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem];
+ _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
- [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil];
- [[NSNotificationCenter defaultCenter] addObserver:_instance
+ [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:_instance
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_instance.avPlayer currentItem]];
[_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0];
- [_instance.avPlayerLayer setFrame:_instance.bounds];
- [_instance.layer addSublayer:_instance.avPlayerLayer];
- [_instance.avPlayer play];
+ [_instance.avPlayerLayer setFrame:_instance.bounds];
+ [_instance.layer addSublayer:_instance.avPlayerLayer];
+ [_instance.avPlayer play];
AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible];
@@ -173,23 +140,19 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
}
}
- video_playing = true;
+ video_playing = true;
return true;
}
bool _is_video_playing() {
- //NSInteger playback_state = _instance.moviePlayerController.playbackState;
- //return video_playing || _instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying;
- //if (video_found_error)
- // return false;
- //return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying);
-
- return video_playing || (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error);
+ if (_instance.avPlayer.error) {
+ printf("Error during playback\n");
+ }
+ return (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error);
}
void _pause_video() {
- //[_instance.moviePlayerController pause];
video_current_time = _instance.avPlayer.currentTime;
[_instance.avPlayer pause];
video_playing = false;
@@ -204,15 +167,9 @@ void _unpause_video() {
[_instance.avPlayer play];
video_playing = true;
-
- //video_current_time = kCMTimeZero;
};
void _stop_video() {
- //[_instance.moviePlayerController stop];
- //[_instance.moviePlayerController.view removeFromSuperview];
- //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume];
-
[_instance.avPlayer pause];
[_instance.avPlayerLayer removeFromSuperlayer];
_instance.avPlayer = nil;
diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h
index c772555835..dcf3677c85 100644
--- a/platform/iphone/icloud.h
+++ b/platform/iphone/icloud.h
@@ -44,13 +44,13 @@ class ICloud : public Object {
List<Variant> pending_events;
public:
-
+
Error remove_key(Variant p_param);
Variant set_key_values(Variant p_param);
Variant get_key_value(Variant p_param);
Error synchronize_key_values();
Variant get_all_key_values();
-
+
int get_pending_event_count();
Variant pop_pending_event();
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index ec62cb5c26..56dffc8aa4 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -41,6 +41,7 @@
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
+#include "core/io/file_access_pack.h"
#include "core/globals.h"
#include "sem_iphone.h"
@@ -159,13 +160,13 @@ void OSIPhone::initialize(const VideoMode& p_desired,int p_video_driver,int p_au
#ifdef STOREKIT_ENABLED
store_kit = memnew(InAppStore);
Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", store_kit));
-#endif
+#endif
#ifdef ICLOUD_ENABLED
icloud = memnew(ICloud);
Globals::get_singleton()->add_singleton(Globals::Singleton("ICloud", icloud));
//icloud->connect();
-#endif
+#endif
};
MainLoop *OSIPhone::get_main_loop() const {
@@ -302,7 +303,7 @@ void OSIPhone::queue_event(const InputEvent& p_event) {
ERR_FAIL_INDEX( event_count, MAX_EVENTS );
- event_queue[event_count++] = p_event;
+ event_queue[event_count++] = p_event;
};
void OSIPhone::touches_cancelled() {
@@ -489,7 +490,7 @@ String OSIPhone::get_name() {
};
Size2 OSIPhone::get_window_size() const {
-
+
return Vector2(video_mode.width, video_mode.height);
}
@@ -517,12 +518,25 @@ extern void _focus_out_video();
Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
FileAccess* f = FileAccess::open(p_path, FileAccess::READ);
bool exists = f && f->is_open();
- printf("file exists for %ls, %i, %p\n", p_path.c_str(), (int)exists, f);
- if (f)
- memdelete(f);
+
+ String tempFile = get_data_dir();
if (!exists)
return FAILED;
- if ( _play_video(p_path, p_volume, p_audio_track, p_subtitle_track) )
+
+ if (p_path.begins_with("res://")) {
+ if (PackedData::get_singleton()->has_path(p_path)) {
+ print("Unable to play %S using the native player as it resides in a .pck file\n", p_path.c_str());
+ return ERR_INVALID_PARAMETER;
+ } else {
+ p_path = p_path.replace("res:/", Globals::get_singleton()->get_resource_path());
+ }
+ } else if (p_path.begins_with("user://"))
+ p_path = p_path.replace("user:/", get_data_dir());
+
+ memdelete(f);
+
+ print("Playing video: %S\n", p_path.c_str());
+ if (_play_video(p_path, p_volume, p_audio_track, p_subtitle_track) )
return OK;
return FAILED;
}
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index abe797fed1..9f919940c0 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -166,7 +166,7 @@ public:
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
-
+
virtual void set_keep_screen_on(bool p_enabled);
virtual bool can_draw() const;
@@ -176,7 +176,7 @@ public:
virtual void hide_virtual_keyboard();
virtual void set_cursor_shape(CursorShape p_shape);
-
+
virtual Size2 get_window_size() const;
virtual bool has_touchscreen_ui_hint() const;
@@ -188,19 +188,19 @@ public:
Error shell_open(String p_uri);
String get_data_dir() const;
-
+
void set_locale(String p_locale);
String get_locale() const;
void set_unique_ID(String p_ID);
String get_unique_ID() const;
- virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
- virtual bool native_video_is_playing() const;
- virtual void native_video_pause();
+ virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
+ virtual bool native_video_is_playing() const;
+ virtual void native_video_pause();
virtual void native_video_unpause();
virtual void native_video_focus_out();
- virtual void native_video_stop();
+ virtual void native_video_stop();
OSIPhone(int width, int height);
~OSIPhone();
diff --git a/platform/iphone/rasterizer_iphone.cpp b/platform/iphone/rasterizer_iphone.cpp
index 29364d091a..f06f12547f 100644
--- a/platform/iphone/rasterizer_iphone.cpp
+++ b/platform/iphone/rasterizer_iphone.cpp
@@ -2071,7 +2071,7 @@ void RasterizerIPhone::_setup_light(LightInstance* p_instance, int p_idx) {
glPopMatrix();
-
+
} break;
default: break;
diff --git a/platform/iphone/xcode/godot_xcode/data.pck b/platform/iphone/xcode/godot_xcode/data.pck
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/data.pck
diff --git a/platform/iphone/xcode/godot_xcode/godot_debug.iphone b/platform/iphone/xcode/godot_xcode/godot_debug.iphone
new file mode 100755
index 0000000000..e69de29bb2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_debug.iphone
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..bdba8488c8
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj
@@ -0,0 +1,370 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D07CD43F1C5D573600B7FB28 /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */; };
+ D07CD4401C5D573600B7FB28 /* Default-667h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4341C5D573600B7FB28 /* Default-667h.png */; };
+ D07CD4411C5D573600B7FB28 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */; };
+ D07CD4421C5D573600B7FB28 /* Default-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4361C5D573600B7FB28 /* Default-736h.png */; };
+ D07CD4431C5D573600B7FB28 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */; };
+ D07CD4441C5D573600B7FB28 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */; };
+ D07CD4451C5D573600B7FB28 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */; };
+ D07CD4461C5D573600B7FB28 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */; };
+ D07CD4471C5D573600B7FB28 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */; };
+ D07CD4481C5D573600B7FB28 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */; };
+ D07CD4491C5D573600B7FB28 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */; };
+ D07CD44A1C5D573600B7FB28 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43E1C5D573600B7FB28 /* Default~iphone.png */; };
+ D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; };
+ D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */; };
+ D0BCFE3A18AEBDA2004A7AAE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */; };
+ D0BCFE3C18AEBDA2004A7AAE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */; };
+ D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */; };
+ D0BCFE4018AEBDA2004A7AAE /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */; };
+ D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; };
+ D0BCFE7818AEBFEB004A7AAE /* data.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* data.pck */; };
+ D0BCFE7A18AEC06A004A7AAE /* godot_opt.iphone in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; };
+ D07CD4341C5D573600B7FB28 /* Default-667h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h.png"; sourceTree = "<group>"; };
+ D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = "<group>"; };
+ D07CD4361C5D573600B7FB28 /* Default-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h.png"; sourceTree = "<group>"; };
+ D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; };
+ D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape-736h.png"; sourceTree = "<group>"; };
+ D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = "<group>"; };
+ D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
+ D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = "<group>"; };
+ D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
+ D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = "<group>"; };
+ D07CD43E1C5D573600B7FB28 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = "<group>"; };
+ D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
+ D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = godot_ios.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
+ D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ D0BCFE4318AEBDA2004A7AAE /* godot_ios-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "godot_ios-Info.plist"; sourceTree = "<group>"; };
+ D0BCFE4518AEBDA2004A7AAE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ D0BCFE4918AEBDA2004A7AAE /* godot_ios-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "godot_ios-Prefix.pch"; sourceTree = "<group>"; };
+ D0BCFE6118AEBDA3004A7AAE /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
+ D0BCFE7718AEBFEB004A7AAE /* data.pck */ = {isa = PBXFileReference; lastKnownFileType = text; path = data.pck; sourceTree = "<group>"; };
+ D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = godot_opt.iphone; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D0BCFE3118AEBDA2004A7AAE /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D0BCFE4018AEBDA2004A7AAE /* OpenGLES.framework in Frameworks */,
+ D0BCFE3A18AEBDA2004A7AAE /* CoreGraphics.framework in Frameworks */,
+ D0BCFE3C18AEBDA2004A7AAE /* UIKit.framework in Frameworks */,
+ D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */,
+ D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ D0BCFE2B18AEBDA2004A7AAE = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */,
+ D0BCFE7718AEBFEB004A7AAE /* data.pck */,
+ D0BCFE4118AEBDA2004A7AAE /* godot_ios */,
+ D0BCFE3618AEBDA2004A7AAE /* Frameworks */,
+ D0BCFE3518AEBDA2004A7AAE /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ D0BCFE3518AEBDA2004A7AAE /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */,
+ D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */,
+ D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */,
+ D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */,
+ D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */,
+ D0BCFE6118AEBDA3004A7AAE /* XCTest.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ D0BCFE4118AEBDA2004A7AAE /* godot_ios */ = {
+ isa = PBXGroup;
+ children = (
+ D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */,
+ D07CD4341C5D573600B7FB28 /* Default-667h.png */,
+ D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */,
+ D07CD4361C5D573600B7FB28 /* Default-736h.png */,
+ D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */,
+ D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */,
+ D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */,
+ D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */,
+ D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */,
+ D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */,
+ D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */,
+ D07CD43E1C5D573600B7FB28 /* Default~iphone.png */,
+ D07CD44D1C5D589C00B7FB28 /* Images.xcassets */,
+ D0BCFE4218AEBDA2004A7AAE /* Supporting Files */,
+ );
+ path = godot_ios;
+ sourceTree = "<group>";
+ };
+ D0BCFE4218AEBDA2004A7AAE /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE4318AEBDA2004A7AAE /* godot_ios-Info.plist */,
+ D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */,
+ D0BCFE4918AEBDA2004A7AAE /* godot_ios-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ D0BCFE3318AEBDA2004A7AAE /* godot_ios */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "godot_ios" */;
+ buildPhases = (
+ D0BCFE3018AEBDA2004A7AAE /* Sources */,
+ D0BCFE3118AEBDA2004A7AAE /* Frameworks */,
+ D0BCFE3218AEBDA2004A7AAE /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = godot_ios;
+ productName = godot_ios;
+ productReference = D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D0BCFE2C18AEBDA2004A7AAE /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0500;
+ ORGANIZATIONNAME = GodotEngine;
+ };
+ buildConfigurationList = D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "godot_ios" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = D0BCFE2B18AEBDA2004A7AAE;
+ productRefGroup = D0BCFE3518AEBDA2004A7AAE /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D0BCFE3318AEBDA2004A7AAE /* godot_ios */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D0BCFE3218AEBDA2004A7AAE /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D07CD4471C5D573600B7FB28 /* Default-Portrait@2x~ipad.png in Resources */,
+ D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */,
+ D0BCFE7818AEBFEB004A7AAE /* data.pck in Resources */,
+ D07CD4461C5D573600B7FB28 /* Default-Landscape~ipad.png in Resources */,
+ D07CD4411C5D573600B7FB28 /* Default-667h@2x.png in Resources */,
+ D07CD4401C5D573600B7FB28 /* Default-667h.png in Resources */,
+ D07CD4431C5D573600B7FB28 /* Default-736h@3x.png in Resources */,
+ D07CD43F1C5D573600B7FB28 /* Default-568h@2x~iphone.png in Resources */,
+ D07CD4451C5D573600B7FB28 /* Default-Landscape@2x~ipad.png in Resources */,
+ D07CD44A1C5D573600B7FB28 /* Default~iphone.png in Resources */,
+ D07CD4491C5D573600B7FB28 /* Default@2x~iphone.png in Resources */,
+ D07CD4441C5D573600B7FB28 /* Default-Landscape-736h.png in Resources */,
+ D07CD4421C5D573600B7FB28 /* Default-736h.png in Resources */,
+ D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */,
+ D0BCFE7A18AEC06A004A7AAE /* godot_opt.iphone in Resources */,
+ D07CD4481C5D573600B7FB28 /* Default-Portrait~ipad.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D0BCFE3018AEBDA2004A7AAE /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D0BCFE4518AEBDA2004A7AAE /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ D0BCFE6F18AEBDA3004A7AAE /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ D0BCFE7018AEBDA3004A7AAE /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ D0BCFE7218AEBDA3004A7AAE /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD)";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "godot_ios/godot_ios-Prefix.pch";
+ INFOPLIST_FILE = "godot_ios/godot_ios-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ PRODUCT_BUNDLE_IDENTIFIER = org.godotengine.game.ios;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALID_ARCHS = "armv7 armv7s";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ D0BCFE7318AEBDA3004A7AAE /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD)";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Distribution: Ariel Manzur (BYC57PA2Q5)";
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "godot_ios/godot_ios-Prefix.pch";
+ INFOPLIST_FILE = "godot_ios/godot_ios-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ PRODUCT_BUNDLE_IDENTIFIER = org.godotengine.game.ios;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALID_ARCHS = "armv7 armv7s";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "godot_ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D0BCFE6F18AEBDA3004A7AAE /* Debug */,
+ D0BCFE7018AEBDA3004A7AAE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "godot_ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D0BCFE7218AEBDA3004A7AAE /* Debug */,
+ D0BCFE7318AEBDA3004A7AAE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = D0BCFE2C18AEBDA2004A7AAE /* Project object */;
+}
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..3c9ba38bbe
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:godot_ios.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png
new file mode 100644
index 0000000000..1341174454
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png
new file mode 100644
index 0000000000..c480d2e3c0
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png
new file mode 100644
index 0000000000..3cc1dfa290
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png
new file mode 100644
index 0000000000..813d689162
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png
new file mode 100644
index 0000000000..7707005e76
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png
new file mode 100644
index 0000000000..b02873323e
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png
new file mode 100644
index 0000000000..d86c4a2510
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png
new file mode 100644
index 0000000000..e4f6cef02b
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png
new file mode 100644
index 0000000000..f306652a31
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png
new file mode 100644
index 0000000000..71a16db6df
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png
new file mode 100644
index 0000000000..5305cb9bdb
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png
new file mode 100644
index 0000000000..91c62d1e43
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..a458b67873
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,128 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "1x",
+ "filename": "Icon-29.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x",
+ "filename": "Icon-58.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x",
+ "filename": "icon-87.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x",
+ "filename": "Icon-80.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x",
+ "filename": "Icon-120.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "57x57",
+ "scale" : "1x",
+ "filename": "Icon-57.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "57x57",
+ "scale" : "2x",
+ "filename": "Icon-114.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x",
+ "filename": "Icon-120.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x",
+ "filename": "Icon-180.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x",
+ "filename": "Icon-29.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x",
+ "filename": "Icon-58.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x",
+ "filename": "Icon-40.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x",
+ "filename": "Icon-80.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "50x50",
+ "scale" : "1x",
+ "filename": "Icon-50.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "50x50",
+ "scale" : "2x",
+ "filename": "Icon-100.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "72x72",
+ "scale" : "1x",
+ "filename": "Icon-72.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "72x72",
+ "scale" : "2x",
+ "filename": "Icon-144.png",
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-76.png",
+ "scale" : "1x",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x",
+ "filename": "Icon-152.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x",
+ "filename": "icon-167.png",
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png
new file mode 100644
index 0000000000..f9dca1ab57
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png
new file mode 100644
index 0000000000..e7f9bd7388
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png
new file mode 100644
index 0000000000..4faa0f28e2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png
new file mode 100644
index 0000000000..1c4cb51d56
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png
new file mode 100644
index 0000000000..e99b11c519
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png
new file mode 100644
index 0000000000..3edbcadfc5
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png
new file mode 100644
index 0000000000..0ae5893203
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png
new file mode 100644
index 0000000000..bb4ffa70ad
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png
new file mode 100644
index 0000000000..7a4b7107e7
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png
new file mode 100644
index 0000000000..b00bd79091
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png
new file mode 100644
index 0000000000..46335efdf6
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png
new file mode 100644
index 0000000000..2c9c2b61dc
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png
new file mode 100644
index 0000000000..d711958ef1
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png
new file mode 100644
index 0000000000..464e7e7289
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png
new file mode 100644
index 0000000000..1151bc6b4b
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png
new file mode 100644
index 0000000000..487c8326be
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png
new file mode 100644
index 0000000000..e54cee23a6
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes
new file mode 100644
index 0000000000..e328a62cb6
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes
@@ -0,0 +1,17 @@
+100
+114
+120
+144
+152
+167
+180
+29
+40
+50
+57
+58
+60
+72
+76
+80
+87
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings b/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000000..477b28ff8f
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist b/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist
new file mode 100644
index 0000000000..f97b0fca36
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>Insert Name Here</string>
+ <key>CFBundleExecutable</key>
+ <string>godot_opt.iphone</string>
+ <key>CFBundleIcons</key>
+ <dict/>
+ <key>CFBundleIcons~ipad</key>
+ <dict/>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UIRequiresFullScreen</key>
+ <true/>
+ <key>UIStatusBarHidden</key>
+ <true/>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/core/os/pc_joystick_map.h b/platform/iphone/xcode/godot_xcode/godot_ios/main.m
index df123c5c1b..3e4ea5e129 100644
--- a/core/os/pc_joystick_map.h
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/main.m
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* pc_joystick_map.h */
+/* main.m */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -26,61 +26,14 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef PC_JOYSTICK_MAP_H
-#define PC_JOYSTICK_MAP_H
-#include "input_event.h"
+#import <UIKit/UIKit.h>
-static const int _pc_joystick_button_remap[JOY_BUTTON_MAX]={
+#import "AppDelegate.h"
- JOY_SELECT,
- JOY_L3,
- JOY_R3,
- JOY_START,
-
- JOY_DPAD_UP,
- JOY_DPAD_RIGHT,
- JOY_DPAD_DOWN,
- JOY_DPAD_LEFT,
-
- JOY_L2,
- JOY_R2,
- JOY_L,
- JOY_R,
-
- JOY_SNES_X,
- JOY_SNES_A,
- JOY_SNES_B,
- JOY_SNES_Y,
-
- // JOY_HOME = 16
-};
-
-
-static int _pc_joystick_get_native_button(int p_pc_button) {
-
- if (p_pc_button<0 || p_pc_button>=JOY_BUTTON_MAX)
- return p_pc_button;
- return _pc_joystick_button_remap[p_pc_button];
+int main(int argc, char * argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
}
-
-static const int _pc_joystick_axis_remap[JOY_AXIS_MAX]={
- JOY_ANALOG_0_X,
- JOY_ANALOG_0_Y,
- JOY_ANALOG_1_X,
- JOY_ANALOG_1_Y,
- JOY_ANALOG_2_X,
- JOY_ANALOG_2_Y,
- JOY_AXIS_6,
- JOY_AXIS_7
-};
-
-
-static int _pc_joystick_get_native_axis(int p_pc_axis) {
-
- if (p_pc_axis<0 || p_pc_axis>=JOY_BUTTON_MAX)
- return p_pc_axis;
- return _pc_joystick_axis_remap[p_pc_axis];
-}
-
-#endif // PC_JOYSTICK_MAP_H
diff --git a/platform/iphone/xcode/godot_xcode/godot_opt.iphone b/platform/iphone/xcode/godot_xcode/godot_opt.iphone
new file mode 100755
index 0000000000..e69de29bb2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_opt.iphone
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index e66110b655..632ef2b6b2 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -74,6 +74,15 @@ static void _glut_skey(bool pressed,int key) {
case GLUT_KEY_INSERT: ev.key.scancode=KEY_INSERT; break;
}
+ if (pressed) {
+ if (os->skey_pressed[key])
+ ev.key.echo = true;
+ else
+ os->skey_pressed[key] = true;
+ }
+ else {
+ os->skey_pressed[key] = false;
+ }
uint32_t m = glutGetModifiers();
ev.key.mod.alt=(m&GLUT_ACTIVE_ALT)!=0;
@@ -107,6 +116,16 @@ static void _glut_key(bool pressed,unsigned char key) {
default: {
ev.key.unicode=key;
}
+
+ if (pressed) {
+ if (os->key_pressed[key])
+ ev.key.echo = true;
+ else
+ os->key_pressed[key] = true;
+ }
+ else {
+ os->key_pressed[key] = false;
+ }
}
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 562733ab89..413d88ee23 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -693,7 +693,11 @@ OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, Ope
time_to_save_sync=-1;
-
+ for (int i = 0; i < 256; i++) {
+ key_pressed[i] = false;
+ if (i < 121)
+ skey_pressed[i] = false;
+ }
}
OS_JavaScript::~OS_JavaScript() {
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index ec3a6cf911..4a8265b9d9 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -56,10 +56,12 @@ public:
Point2 pos;
};
+ bool skey_pressed[121];
+ bool key_pressed[256];
+
private:
Vector<TouchPos> touch;
-
Point2 last_mouse;
unsigned int last_id;
GFXInitFunc gfx_init_func;
diff --git a/platform/nacl/nacl_keycodes.h b/platform/nacl/nacl_keycodes.h
index 45dba075db..a0642fc3b7 100644
--- a/platform/nacl/nacl_keycodes.h
+++ b/platform/nacl/nacl_keycodes.h
@@ -286,7 +286,7 @@ static uint32_t godot_key(uint32_t p_key, bool& is_char) {
case VKEY_MULTIPLY: return KEY_KP_MULTIPLY;
case VKEY_ADD: return KEY_KP_ADD;
// case VKEY_SEPARATOR: return KEY_SEPARATOR;
- case VKEY_SUBTRACT: return KEY_KP_SUBSTRACT;
+ case VKEY_SUBTRACT: return KEY_KP_SUBTRACT;
case VKEY_DECIMAL: return KEY_KP_PERIOD;
case VKEY_DIVIDE: return KEY_KP_DIVIDE;
case VKEY_F1: return KEY_F1;
diff --git a/platform/nacl/os_nacl.cpp b/platform/nacl/os_nacl.cpp
index de6a15525b..e2a92ee8c7 100644
--- a/platform/nacl/os_nacl.cpp
+++ b/platform/nacl/os_nacl.cpp
@@ -249,7 +249,11 @@ OS::Date OSNacl::get_date(bool utc) const {
lt=localtime(&t);
Date ret;
ret.year=lt->tm_year;
- ret.month=(Month)lt->tm_mon;
+
+ // Index starting at 1 to match OS_Unix::get_date
+ // and Windows SYSTEMTIME and tm_mon follows the typical structure
+ // of 0-11, noted here: http://www.cplusplus.com/reference/ctime/tm/
+ ret.month=(Month)(lt->tm_mon+1);
ret.day=lt->tm_mday;
ret.weekday=(Weekday)lt->tm_wday;
ret.dst=lt->tm_isdst;
diff --git a/platform/nacl/pepper_main.cpp b/platform/nacl/pepper_main.cpp
index fe10db19a9..6b81776624 100644
--- a/platform/nacl/pepper_main.cpp
+++ b/platform/nacl/pepper_main.cpp
@@ -198,7 +198,7 @@ NPError NPP_New(NPMIMEType pluginType,
NPError NPP_Destroy(NPP instance, NPSavedData** save) {
nacl_cleanup();
-
+
return NPERR_NO_ERROR;
}
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h
index 4a94c20c00..565a0ee02a 100644
--- a/platform/osx/context_gl_osx.h
+++ b/platform/osx/context_gl_osx.h
@@ -48,8 +48,8 @@ class ContextGL_OSX : public ContextGL {
public:
- virtual void release_current();
- virtual void make_current();
+ virtual void release_current();
+ virtual void make_current();
virtual void swap_buffers();
virtual Error initialize();
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index caeeaf643c..8b742b64fa 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -43,44 +43,44 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class DirAccessOSX : public DirAccess {
-
+
DIR *dir_stream;
-
+
static DirAccess *create_fs();
-
+
String current_dir;
bool _cisdir;
bool _cishidden;
-
+
public:
-
+
virtual bool list_dir_begin(); ///< This starts dir listing
virtual String get_next();
virtual bool current_is_dir() const;
virtual bool current_is_hidden() const;
-
- virtual void list_dir_end(); ///<
-
+
+ virtual void list_dir_end(); ///<
+
virtual int get_drive_count();
virtual String get_drive(int p_drive);
-
+
virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
virtual String get_current_dir(); ///< return current dir location
virtual Error make_dir(String p_dir);
-
+
virtual bool file_exists(String p_file);
virtual bool dir_exists(String p_dir);
virtual uint64_t get_modified_time(String p_file);
-
+
virtual Error rename(String p_from, String p_to);
virtual Error remove(String p_name);
virtual size_t get_space_left();
-
-
+
+
DirAccessOSX();
~DirAccessOSX();
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index e345bea60a..29f8fda663 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -297,8 +297,11 @@ Error DirAccessOSX::rename(String p_path,String p_new_path) {
}
Error DirAccessOSX::remove(String p_path) {
- p_path=fix_path(p_path);
-
+ if (p_path.is_rel_path())
+ p_path=get_current_dir().plus_file(p_path);
+ else
+ p_path=fix_path(p_path);
+
struct stat flags;
if ((stat(p_path.utf8().get_data(),&flags)!=0))
return FAILED;
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index a1fd34def7..29c652051a 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -138,7 +138,7 @@ public:
virtual Point2 get_mouse_pos() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String& p_title);
-
+
virtual Size2 get_window_size() const;
virtual void set_icon(const Image& p_icon);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 2bb35fdc60..4b339af6d4 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -650,7 +650,7 @@ static int translateKey(unsigned int key)
/* 4b */ KEY_KP_DIVIDE,
/* 4c */ KEY_KP_ENTER,
/* 4d */ KEY_UNKNOWN,
- /* 4e */ KEY_KP_SUBSTRACT,
+ /* 4e */ KEY_KP_SUBTRACT,
/* 4f */ KEY_UNKNOWN,
/* 50 */ KEY_UNKNOWN,
/* 51 */ KEY_EQUAL, //wtf equal?
@@ -809,6 +809,21 @@ static int translateKey(unsigned int key)
OS_OSX::singleton->push_input(ev);
}
+ if (fabs(deltaX)) {
+
+ InputEvent ev;
+ ev.type=InputEvent::MOUSE_BUTTON;
+ ev.mouse_button.button_index=deltaX < 0 ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT;
+ ev.mouse_button.pressed=true;
+ ev.mouse_button.x=mouse_x;
+ ev.mouse_button.y=mouse_y;
+ ev.mouse_button.global_x=mouse_x;
+ ev.mouse_button.global_y=mouse_y;
+ ev.mouse_button.button_mask=button_mask;
+ OS_OSX::singleton->push_input(ev);
+ ev.mouse_button.pressed=false;
+ OS_OSX::singleton->push_input(ev);
+ }
}
@end
diff --git a/platform/server/detect.py b/platform/server/detect.py
index e2d64c6545..15c5982b14 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -28,7 +28,6 @@ def get_flags():
return [
('builtin_zlib', 'no'),
- ('theora','no'), #use builtin openssl
]
diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp
index db6c13633d..1c55c03bd7 100644
--- a/platform/server/godot_server.cpp
+++ b/platform/server/godot_server.cpp
@@ -30,16 +30,16 @@
#include "os_server.h"
int main(int argc, char* argv[]) {
-
+
OS_Server os;
-
+
Error err = Main::setup(argv[0],argc-1,&argv[1]);
if (err!=OK)
return 255;
-
+
if (Main::start())
os.run(); // it is actually the OS that decides how to run
Main::cleanup();
-
+
return os.get_exit_code();
}
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index f042318f78..5404980ff3 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -56,7 +56,7 @@ void OS_Server::initialize(const VideoMode& p_desired,int p_video_driver,int p_a
args=OS::get_singleton()->get_cmdline_args();
current_videomode=p_desired;
main_loop=NULL;
-
+
rasterizer = memnew( RasterizerDummy );
visual_server = memnew( VisualServerRaster(rasterizer) );
@@ -76,7 +76,7 @@ void OS_Server::initialize(const VideoMode& p_desired,int p_video_driver,int p_a
spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
spatial_sound_2d_server->init();
-
+
ERR_FAIL_COND(!visual_server);
visual_server->init();
@@ -90,7 +90,7 @@ void OS_Server::initialize(const VideoMode& p_desired,int p_video_driver,int p_a
_ensure_data_dir();
-
+
}
void OS_Server::finalize() {
@@ -115,7 +115,7 @@ void OS_Server::finalize() {
visual_server->finish();
memdelete(visual_server);
memdelete(rasterizer);
-
+
physics_server->finish();
memdelete(physics_server);
@@ -218,18 +218,18 @@ void OS_Server::set_cursor_shape(CursorShape p_shape) {
void OS_Server::run() {
force_quit = false;
-
+
if (!main_loop)
return;
-
+
main_loop->init();
-
+
while (!force_quit) {
-
+
if (Main::iteration()==true)
break;
};
-
+
main_loop->finish();
}
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 2487c7b3fb..2081d5f2f4 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -55,11 +55,11 @@ class OS_Server : public OS_Unix {
VisualServer *visual_server;
VideoMode current_videomode;
List<String> args;
- MainLoop *main_loop;
+ MainLoop *main_loop;
AudioDriverDummy driver_dummy;
bool grab;
-
+
PhysicsServer *physics_server;
Physics2DServer *physics_2d_server;
@@ -80,13 +80,13 @@ class OS_Server : public OS_Unix {
protected:
virtual int get_video_driver_count() const;
- virtual const char * get_video_driver_name(int p_driver) const;
+ virtual const char * get_video_driver_name(int p_driver) const;
virtual VideoMode get_default_video_mode() const;
-
- virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
+
+ virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
virtual void finalize();
- virtual void set_main_loop( MainLoop * p_main_loop );
+ virtual void set_main_loop( MainLoop * p_main_loop );
public:
@@ -102,7 +102,7 @@ public:
virtual void set_window_title(const String& p_title);
virtual MainLoop *get_main_loop() const;
-
+
virtual bool can_draw() const;
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp
index e671101432..ab66b81421 100644
--- a/platform/windows/context_gl_win.cpp
+++ b/platform/windows/context_gl_win.cpp
@@ -31,7 +31,7 @@
//
// C++ Implementation: context_gl_x11
//
-// Description:
+// Description:
//
//
// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
@@ -105,21 +105,21 @@ Error ContextGL_Win::initialize() {
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER,
- PFD_TYPE_RGBA,
+ PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0,// No Alpha Buffer
0,// Shift Bit Ignored
0,// No Accumulation Buffer
0, 0, 0, 0,// Accumulation Bits Ignored
- 24,// 24Bit Z-Buffer (Depth Buffer)
+ 24,// 24Bit Z-Buffer (Depth Buffer)
0,// No Stencil Buffer
0,// No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0,// Reserved
0, 0, 0 // Layer Masks Ignored
};
-
+
if (!(hDC=GetDC(hWnd))) {
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h
index af15ad2659..055e0b2f51 100644
--- a/platform/windows/context_gl_win.h
+++ b/platform/windows/context_gl_win.h
@@ -30,7 +30,7 @@
//
// C++ Interface: context_gl_x11
//
-// Description:
+// Description:
//
//
// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
@@ -62,14 +62,14 @@ public:
virtual void release_current();
virtual void make_current();
-
+
virtual int get_window_width();
virtual int get_window_height();
virtual void swap_buffers();
-
+
virtual Error initialize();
-
-
+
+
ContextGL_Win(HWND hwnd,bool p_opengl_3_context);
~ContextGL_Win();
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 397ca078fb..1ad0f164d2 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -305,7 +305,7 @@ def configure(env):
if (env["target"]=="release"):
- env.Append(CCFLAGS=['-ffast-math','-fomit-frame-pointer','-msse2'])
+ env.Append(CCFLAGS=['-msse2'])
if (env["bits"]=="64"):
env.Append(CCFLAGS=['-O3'])
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 899edde087..952f51fdd4 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -1,345 +1,6 @@
-/*************************************************************************/
-/* export.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "export.h"
#include "platform/windows/logo.h"
-#include "os/os.h"
-#include "globals.h"
-#include "tools/editor/editor_node.h"
-#include "tools/pe_bliss/pe_bliss_godot.h"
-
-/**
- @author Masoud BaniHashemian <masoudbh3@gmail.com>
-*/
-
-
-void EditorExportPlatformWindows::store_16(DVector<uint8_t>& vector, uint16_t value) {
- const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
- int size = vector.size();
- vector.resize( size + 2 );
- DVector<uint8_t>::Write w = vector.write();
- w[size]=bytes[0];
- w[size+1]=bytes[1];
-}
-void EditorExportPlatformWindows::store_32(DVector<uint8_t>& vector, uint32_t value) {
- const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
- int size = vector.size();
- vector.resize( size + 4 );
- DVector<uint8_t>::Write w = vector.write();
- w[size]=bytes[0];
- w[size+1]=bytes[1];
- w[size+2]=bytes[2];
- w[size+3]=bytes[3];
-}
-
-bool EditorExportPlatformWindows::_set(const StringName& p_name, const Variant& p_value) {
-
- String n = p_name;
-
- if (n=="icon/icon_ico") {
-
- icon_ico=p_value;
- } else if (n=="icon/icon_png") {
-
- icon_png=p_value;
- } else if (n=="icon/icon_png16x16") {
-
- icon16=p_value;
- } else if (n=="icon/icon_png32x32") {
-
- icon32=p_value;
- } else if (n=="icon/icon_png48x48") {
-
- icon48=p_value;
- } else if (n=="icon/icon_png64x64") {
-
- icon64=p_value;
- } else if (n=="icon/icon_png128x128") {
-
- icon128=p_value;
- } else if (n=="icon/icon_png256x256") {
-
- icon256=p_value;
- } else if (n=="version_info/version_major") {
-
- version_major=p_value;
- } else if (n=="version_info/version_minor") {
-
- version_minor=p_value;
- } else if (n=="version_info/version_text") {
-
- version_text=p_value;
- } else if (n=="version_info/company_name") {
-
- company_name=p_value;
- } else if (n=="version_info/file_description") {
-
- file_description=p_value;
- } else if (n=="version_info/product_name") {
-
- product_name=p_value;
- } else if (n=="version_info/legal_copyright") {
-
- legal_copyright=p_value;
- } else if (n=="version_info/add_godot_version") {
-
- set_godot_version=p_value;
- } else
- return false;
-
- return true;
-
-}
-
-bool EditorExportPlatformWindows::_get(const StringName& p_name,Variant &r_ret) const {
-
- String n = p_name;
-
- if (n=="icon/icon_ico") {
-
- r_ret=icon_ico;
- } else if (n=="icon/icon_png") {
-
- r_ret=icon_png;
- } else if (n=="icon/icon_png16x16") {
-
- r_ret=icon16;
- } else if (n=="icon/icon_png32x32") {
-
- r_ret=icon32;
- } else if (n=="icon/icon_png48x48") {
-
- r_ret=icon48;
- } else if (n=="icon/icon_png64x64") {
-
- r_ret=icon64;
- } else if (n=="icon/icon_png128x128") {
-
- r_ret=icon128;
- } else if (n=="icon/icon_png256x256") {
-
- r_ret=icon256;
- } else if (n=="version_info/version_major") {
-
- r_ret=version_major;
- } else if (n=="version_info/version_minor") {
-
- r_ret=version_minor;
- } else if (n=="version_info/version_text") {
-
- r_ret=version_text;
- } else if (n=="version_info/company_name") {
-
- r_ret=company_name;
- } else if (n=="version_info/file_description") {
-
- r_ret=file_description;
- } else if (n=="version_info/product_name") {
-
- r_ret=product_name;
- } else if (n=="version_info/legal_copyright") {
-
- r_ret=legal_copyright;
- } else if (n=="version_info/add_godot_version") {
-
- r_ret=set_godot_version;
- } else
- return false;
-
- return true;
-
-}
-
-void EditorExportPlatformWindows::_get_property_list( List<PropertyInfo> *p_list) const {
-
- p_list->push_back( PropertyInfo( Variant::STRING, "icon/icon_ico",PROPERTY_HINT_FILE,"ico") );
- p_list->push_back( PropertyInfo( Variant::STRING, "icon/icon_png",PROPERTY_HINT_FILE,"png") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png16x16") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png32x32") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png48x48") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png64x64") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png128x128") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png256x256") );
- p_list->push_back( PropertyInfo( Variant::INT, "version_info/version_major", PROPERTY_HINT_RANGE,"0,65535,1"));
- p_list->push_back( PropertyInfo( Variant::INT, "version_info/version_minor", PROPERTY_HINT_RANGE,"0,65535,0"));
- p_list->push_back( PropertyInfo( Variant::STRING, "version_info/version_text") );
- p_list->push_back( PropertyInfo( Variant::STRING, "version_info/company_name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "version_info/file_description") );
- p_list->push_back( PropertyInfo( Variant::STRING, "version_info/product_name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "version_info/legal_copyright") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "version_info/add_godot_version") );
-
-}
-
-Error EditorExportPlatformWindows::export_project(const String& p_path, bool p_debug, int p_flags) {
-
- Error err = EditorExportPlatformPC::export_project(p_path, p_debug, p_flags);
- if(err != OK)
- {
- return err;
- }
- EditorProgress ep("editexe","Edit EXE File",102);
- ep.step("Create ico file..",0);
-
- DVector<uint8_t> icon_content;
- if (this->icon_ico!="" && this->icon_ico.ends_with(".ico")) {
- FileAccess *f = FileAccess::open(this->icon_ico,FileAccess::READ);
- if (f) {
- icon_content.resize(f->get_len());
- DVector<uint8_t>::Write write = icon_content.write();
- f->get_buffer(write.ptr(),icon_content.size());
- f->close();
- memdelete(f);
- }
- } else if (this->icon_png!="" && this->icon_png.ends_with(".png") && (icon16 || icon32 || icon48 || icon64 || icon128 || icon256)) {
- #ifdef PNG_ENABLED
- Vector<Image> pngs;
- Image png;
- Error err_png = png.load(this->icon_png);
- if (err_png==OK && !png.empty()) {
- if(icon256) {
- Image icon_256(png);
- if(!(png.get_height()==256 && png.get_width()==256)) icon_256.resize(256,256);
- pngs.push_back(icon_256);
- }
- if(icon128) {
- Image icon_128(png);
- if(!(png.get_height()==128 && png.get_width()==128)) icon_128.resize(128,128);
- pngs.push_back(icon_128);
- }
- if(icon64) {
- Image icon_64(png);
- if(!(png.get_height()==64 && png.get_width()==64)) icon_64.resize(64,64);
- pngs.push_back(icon_64);
- }
- if(icon48) {
- Image icon_48(png);
- if(!(png.get_height()==48 && png.get_width()==48)) icon_48.resize(48,48);
- pngs.push_back(icon_48);
- }
- if(icon32) {
- Image icon_32(png);
- if(!(png.get_height()==32 && png.get_width()==32)) icon_32.resize(32,32);
- pngs.push_back(icon_32);
- }
- if(icon16) {
- Image icon_16(png);
- if(!(png.get_height()==16 && png.get_width()==16)) icon_16.resize(16,16);
- pngs.push_back(icon_16);
- }
- // create icon according to https://www.daubnet.com/en/file-format-ico
- store_16(icon_content,0); //Reserved
- store_16(icon_content,1); //Type
- store_16(icon_content,pngs.size()); //Count
- int offset = 6+pngs.size()*16;
- //List of bitmaps
- for(int i=0;i<pngs.size();i++) {
- int w = pngs[i].get_width();
- int h = pngs[i].get_height();
- icon_content.push_back(w<256?w:0); //width
- icon_content.push_back(h<256?h:0); //height
- icon_content.push_back(0); //ColorCount = 0
- icon_content.push_back(0); //Reserved
- store_16(icon_content,1); //Planes
- store_16(icon_content,32); //BitCount (bit per pixel)
- int size = 40 + (w * h * 4) + (w * h / 8);
- store_32(icon_content,size); //Size of (InfoHeader + ANDbitmap + XORbitmap)
- store_32(icon_content,offset); //FileOffset
- offset += size;
- }
- //Write bmp files.
- for(int i=0;i<pngs.size();i++) {
- int w = pngs[i].get_width();
- int h = pngs[i].get_height();
- store_32(icon_content,40); //Size of InfoHeader structure = 40
- store_32(icon_content,w); //Width
- store_32(icon_content,h*2); //Height
- store_16(icon_content,1); //Planes
- store_16(icon_content,32); //BitCount
- store_32(icon_content,0); //Compression
- store_32(icon_content,w*h*4); //ImageSize = Size of Image in Bytes
- store_32(icon_content,0); //unused = 0
- store_32(icon_content,0); //unused = 0
- store_32(icon_content,0); //unused = 0
- store_32(icon_content,0); //unused = 0
- //XORBitmap
- for(int y=h-1;y>=0;y--) {
- for(int x=0;x<w;x++) {
- store_32(icon_content,pngs[i].get_pixel(x,y).to_32());
- }
- }
- //ANDBitmap
- for(int m=0;m<(w * h / 8);m+=4) store_32(icon_content,0x00000000); // Add empty ANDBitmap , TODO create full ANDBitmap Structure if need.
- }
- }
- #endif
- }
-
- ep.step("Add rsrc..",50);
-
- String basename = Globals::get_singleton()->get("application/name");
- product_name=product_name.replace("$genname",basename);
- String godot_version;
- if(set_godot_version) godot_version = String( VERSION_MKSTRING );
- String ret = pe_bliss_add_resrc(p_path.utf8(), version_major, version_minor,
- company_name, file_description, legal_copyright, version_text,
- product_name, godot_version, icon_content);
- if (ret.empty()) {
- return OK;
- } else {
- EditorNode::add_io_error(ret);
- return ERR_FILE_CANT_WRITE;
- }
-}
-
-EditorExportPlatformWindows::EditorExportPlatformWindows() {
-
- icon16=true;
- icon32=true;
- icon48=true;
- icon64=true;
- icon128=true;
- icon256=true;
- product_name="$genname";
- company_name="Godot Engine";
- file_description="Created With Godot Engine";
- version_text="1.0";
- OS::Date date = OS::get_singleton()->get_date();
- legal_copyright="Copyright (c) 2007-";
- legal_copyright+=String::num(date.year);
- legal_copyright+=" Juan Linietsky, Ariel Manzur";
- version_major=1;
- version_minor=0;
- set_godot_version=true;
-}
-
-
+#include "tools/editor/editor_import_export.h"
void register_windows_exporter() {
@@ -348,7 +9,7 @@ void register_windows_exporter() {
logo->create_from_image(img);
{
- Ref<EditorExportPlatformWindows> exporter = Ref<EditorExportPlatformWindows>( memnew(EditorExportPlatformWindows) );
+ Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) );
exporter->set_binary_extension("exe");
exporter->set_release_binary32("windows_32_release.exe");
exporter->set_debug_binary32("windows_32_debug.exe");
diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h
index 2424efc861..68ce500a20 100644
--- a/platform/windows/export/export.h
+++ b/platform/windows/export/export.h
@@ -1,37 +1,4 @@
-#include "tools/editor/editor_import_export.h"
-class EditorExportPlatformWindows : public EditorExportPlatformPC {
- OBJ_TYPE( EditorExportPlatformWindows,EditorExportPlatformPC );
-
-private:
- String icon_ico;
- String icon_png;
- bool icon16;
- bool icon32;
- bool icon48;
- bool icon64;
- bool icon128;
- bool icon256;
- String company_name;
- String file_description;
- String product_name;
- String legal_copyright;
- String version_text;
- int version_major;
- int version_minor;
- bool set_godot_version;
- void store_16(DVector<uint8_t>& vector, uint16_t value); ///< store 16 bits uint
- void store_32(DVector<uint8_t>& vector, uint32_t value); ///< store 32 bits uint
-
-protected:
- bool _set(const StringName& p_name, const Variant& p_value);
- bool _get(const StringName& p_name,Variant &r_ret) const;
- void _get_property_list( List<PropertyInfo> *p_list) const;
-
-public:
- Error export_project(const String& p_path, bool p_debug,int p_flags=0);
- EditorExportPlatformWindows();
-};
void register_windows_exporter();
diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp
index fa7989c726..c89d02bb05 100644
--- a/platform/windows/godot_win.cpp
+++ b/platform/windows/godot_win.cpp
@@ -179,5 +179,5 @@ HINSTANCE godot_hinstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
godot_hinstance = hInstance;
- return main(0,NULL);
+ return main(0,NULL);
}
diff --git a/platform/windows/joystick.cpp b/platform/windows/joystick.cpp
index f4fb09820f..f8526b5ec1 100644
--- a/platform/windows/joystick.cpp
+++ b/platform/windows/joystick.cpp
@@ -472,7 +472,7 @@ InputDefault::JoyAxis joystick_windows::axis_correct(int p_val, bool p_xinput, b
InputDefault::JoyAxis jx;
if (Math::abs(p_val) < MIN_JOY_AXIS) {
- jx.min = -1;
+ jx.min = p_trigger ? 0 : -1;
jx.value = 0.0f;
return jx;
}
diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp
index 07d5f32253..23fa29d68f 100644
--- a/platform/windows/key_mapping_win.cpp
+++ b/platform/windows/key_mapping_win.cpp
@@ -145,7 +145,7 @@ static _WinTranslatePair _vk_to_keycode[]={
{ KEY_KP_MULTIPLY,VK_MULTIPLY},// (0x6A)
{ KEY_KP_ADD,VK_ADD},// (0x6B)
//VK_SEPARATOR (0x6C)
-{ KEY_KP_SUBSTRACT,VK_SUBTRACT},// (0x6D)
+{ KEY_KP_SUBTRACT,VK_SUBTRACT},// (0x6D)
{ KEY_KP_PERIOD,VK_DECIMAL},// (0x6E)
{ KEY_KP_DIVIDE,VK_DIVIDE},// (0x6F)
{ KEY_F1,VK_F1},// (0x70)
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 886c43d116..9def8d4f9c 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -47,7 +47,6 @@
#include "tcp_server_winsock.h"
#include "packet_peer_udp_winsock.h"
#include "stream_peer_winsock.h"
-#include "os/pc_joystick_map.h"
#include "lang_table.h"
#include "os/memory_pool_dynamic_prealloc.h"
#include "globals.h"
@@ -67,6 +66,10 @@ extern "C" {
#endif
}
+#ifndef WM_MOUSEHWHEEL
+#define WM_MOUSEHWHEEL 0x020e
+#endif
+
//#define STDOUT_FILE
extern HINSTANCE godot_hinstance;
@@ -174,10 +177,11 @@ void OS_Windows::initialize_core() {
//RedirectIOToConsole();
maximized=false;
minimized=false;
+ borderless=false;
- ThreadWindows::make_default();
- SemaphoreWindows::make_default();
- MutexWindows::make_default();
+ ThreadWindows::make_default();
+ SemaphoreWindows::make_default();
+ MutexWindows::make_default();
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
@@ -190,7 +194,7 @@ void OS_Windows::initialize_core() {
TCPServerWinsock::make_default();
StreamPeerWinsock::make_default();
PacketPeerUDPWinsock::make_default();
-
+
mempool_static = new MemoryPoolStaticMalloc;
#if 1
mempool_dynamic = memnew( MemoryPoolDynamicStatic );
@@ -200,7 +204,7 @@ void OS_Windows::initialize_core() {
mempool_dynamic = memnew( MemoryPoolDynamicPrealloc(buffer,DYNPOOL_SIZE) );
#endif
-
+
// We need to know how often the clock is updated
if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second) )
ticks_per_second = 1000;
@@ -423,7 +427,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (main_loop)
input->parse_input_event(event);
-
+
} break;
case WM_LBUTTONDOWN:
@@ -433,6 +437,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
/*case WM_XBUTTONDOWN:
@@ -472,7 +477,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
} break;
case WM_MBUTTONUP: {
mb.pressed=false;
- mb.button_index=3;
+ mb.button_index=3;
} break;
case WM_RBUTTONDOWN: {
mb.pressed=true;
@@ -503,11 +508,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (motion>0)
- mb.button_index=4;
+ mb.button_index= BUTTON_WHEEL_UP;
else
- mb.button_index=5;
+ mb.button_index= BUTTON_WHEEL_DOWN;
+
+
+ } break;
+ case WM_MOUSEHWHEEL: {
+ mb.pressed = true;
+ int motion = (short)HIWORD(wParam);
+ if (!motion)
+ return 0;
+ if (motion<0)
+ mb.button_index = BUTTON_WHEEL_LEFT;
+ else
+ mb.button_index = BUTTON_WHEEL_RIGHT;
} break;
/*
case WM_XBUTTONDOWN: {
@@ -535,7 +552,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
mb.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
mb.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
mb.x=GET_X_LPARAM(lParam);
- mb.y=GET_Y_LPARAM(lParam);
+ mb.y=GET_Y_LPARAM(lParam);
if (mouse_mode==MOUSE_MODE_CAPTURED) {
@@ -806,11 +823,11 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
outside=true;
WNDCLASSEXW wc;
-
+
video_mode=p_desired;
//printf("**************** desired %s, mode %s\n", p_desired.fullscreen?"true":"false", video_mode.fullscreen?"true":"false");
RECT WindowRect;
-
+
WindowRect.left=0;
WindowRect.right=video_mode.width;
WindowRect.top=0;
@@ -824,18 +841,18 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
wc.cbWndExtra= 0;
//wc.hInstance = hInstance;
wc.hInstance = godot_hinstance ? godot_hinstance : GetModuleHandle(NULL);
- wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
+ wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
+ wc.lpszMenuName = NULL;
wc.lpszClassName = L"Engine";
if (!RegisterClassExW(&wc)) {
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
- return; // Return
+ return; // Return
}
-
-
+
+
EnumDisplayMonitors(NULL,NULL,MonitorEnumProc,0);
print_line("DETECTED MONITORS: "+itos(monitor_info.size()));
@@ -845,7 +862,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
DEVMODE current;
memset(&current,0,sizeof(current));
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &current);
-
+
WindowRect.right = current.dmPelsWidth;
WindowRect.bottom = current.dmPelsHeight;
@@ -868,11 +885,11 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
DWORD dwExStyle;
DWORD dwStyle;
- if (video_mode.fullscreen) {
+ if (video_mode.fullscreen||video_mode.borderless_window) {
dwExStyle=WS_EX_APPWINDOW;
dwStyle=WS_POPUP;
-
+
} else {
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
@@ -914,14 +931,14 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
video_mode.fullscreen = false;
} else {
- if (!(hWnd=CreateWindowExW(dwExStyle,L"Engine",L"", dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, 0, 0,WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top, NULL,NULL, hInstance,NULL))) {
+ if (!(hWnd=CreateWindowExW(dwExStyle,L"Engine",L"", dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, (GetSystemMetrics(SM_CXSCREEN)-WindowRect.right)/2, (GetSystemMetrics(SM_CYSCREEN)-WindowRect.bottom)/2, WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top, NULL,NULL, hInstance,NULL))) {
MessageBoxW(NULL,L"Window Creation Error.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return; // Return FALSE
}
};
-
+
#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) || defined(LEGACYGL_ENABLED)
gl_context = memnew( ContextGL_Win(hWnd,false) );
gl_context->initialize();
@@ -965,7 +982,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
*/
- visual_server->init();
+ visual_server->init();
input = memnew( InputDefault );
joystick = memnew (joystick_windows(input, &hWnd));
@@ -1264,7 +1281,7 @@ OS::VideoMode OS_Windows::get_video_mode(int p_screen) const {
}
void OS_Windows::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
-
+
}
int OS_Windows::get_screen_count() const {
@@ -1512,6 +1529,14 @@ bool OS_Windows::is_window_maximized() const{
}
+void OS_Windows::set_borderless_window(int p_borderless) {
+ video_mode.borderless_window = p_borderless;
+}
+
+bool OS_Windows::get_borderless_window() {
+ return video_mode.borderless_window;
+}
+
void OS_Windows::print_error(const char* p_function, const char* p_file, int p_line, const char* p_code, const char* p_rationale, ErrorType p_type) {
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -1698,18 +1723,18 @@ void OS_Windows::delay_usec(uint32_t p_usec) const {
Sleep(1);
else
Sleep(p_usec / 1000);
-
+
}
uint64_t OS_Windows::get_ticks_usec() const {
uint64_t ticks;
- uint64_t time;
+ uint64_t time;
// This is the number of clock ticks since start
if( !QueryPerformanceCounter((LARGE_INTEGER *)&ticks) )
ticks = (UINT64)timeGetTime();
// Divide by frequency to get the time in seconds
time = ticks * 1000000L / ticks_per_second;
- // Subtract the time at game start to get
+ // Subtract the time at game start to get
// the time since the game started
time -= ticks_start;
return time;
@@ -1721,13 +1746,13 @@ void OS_Windows::process_events() {
MSG msg;
last_id = joystick->process_joysticks(last_id);
-
+
while(PeekMessageW(&msg,NULL,0,0,PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
-
+
}
process_key_events();
@@ -2018,21 +2043,21 @@ void OS_Windows::run() {
if (!main_loop)
return;
-
+
main_loop->init();
-
+
uint64_t last_ticks=get_ticks_usec();
-
+
int frames=0;
uint64_t frame=0;
-
+
while (!force_quit) {
-
+
process_events(); // get rid of pending events
if (Main::iteration()==true)
break;
};
-
+
main_loop->finish();
}
@@ -2059,7 +2084,7 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const {
id=CSIDL_MYPICTURES;
} break;
case SYSTEM_DIR_DOCUMENTS: {
- id=0x000C;
+ id=CSIDL_PERSONAL;
} break;
case SYSTEM_DIR_DOWNLOADS: {
id=0x000C ;
@@ -2140,7 +2165,7 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
}
-OS_Windows::~OS_Windows()
+OS_Windows::~OS_Windows()
{
#ifdef STDOUT_FILE
fclose(stdo);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index e433d5cc11..3116847daa 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -29,7 +29,7 @@
#ifndef OS_WINDOWS_H
#define OS_WINDOWS_H
-#define WINVER 0x0500
+#define WINVER 0x0600
#include "os/input.h"
#include "os/os.h"
@@ -138,27 +138,27 @@ class OS_Windows : public OS {
void _touch_event(bool p_pressed, int p_x, int p_y, int idx);
// functions used by main to initialize/deintialize the OS
-protected:
+protected:
virtual int get_video_driver_count() const;
virtual const char * get_video_driver_name(int p_driver) const;
-
+
virtual VideoMode get_default_video_mode() const;
-
+
virtual int get_audio_driver_count() const;
virtual const char * get_audio_driver_name(int p_driver) const;
-
+
virtual void initialize_core();
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
-
- virtual void set_main_loop( MainLoop * p_main_loop );
+
+ virtual void set_main_loop( MainLoop * p_main_loop );
virtual void delete_main_loop();
-
+
virtual void finalize();
virtual void finalize_core();
-
+
void process_events();
void process_key_events();
-
+
struct ProcessInfo {
STARTUPINFO si;
@@ -179,6 +179,7 @@ protected:
Vector<MonitorInfo> monitor_info;
bool maximized;
bool minimized;
+ bool borderless;
static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);
@@ -200,7 +201,7 @@ public:
virtual Point2 get_mouse_pos() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String& p_title);
-
+
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
@@ -223,10 +224,13 @@ public:
virtual void set_window_maximized(bool p_enabled);
virtual bool is_window_maximized() const;
+ virtual void set_borderless_window(int p_borderless);
+ virtual bool get_borderless_window();
+
virtual MainLoop *get_main_loop() const;
virtual String get_name();
-
+
virtual Date get_date(bool utc) const;
virtual Time get_time(bool utc) const;
virtual TimeZoneInfo get_time_zone_info() const;
@@ -236,12 +240,12 @@ public:
virtual bool can_draw() const;
virtual Error set_cwd(const String& p_cwd);
- virtual void delay_usec(uint32_t p_usec) const;
+ virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL);
virtual Error kill(const ProcessID& p_pid);
-
+
virtual bool has_environment(const String& p_var) const;
virtual String get_environment(const String& p_var) const;
@@ -273,7 +277,7 @@ public:
virtual bool is_joy_known(int p_device);
virtual String get_joy_guid(int p_device) const;
- OS_Windows(HINSTANCE _hInstance);
+ OS_Windows(HINSTANCE _hInstance);
~OS_Windows();
};
diff --git a/platform/winrt/app.cpp b/platform/winrt/app.cpp
index 263cd684c4..ea7619a64b 100644
--- a/platform/winrt/app.cpp
+++ b/platform/winrt/app.cpp
@@ -61,7 +61,7 @@ void App::Initialize(CoreApplicationView^ applicationView)
{
// Register event handlers for app lifecycle. This example includes Activated, so that we
// can make the CoreWindow active and start rendering on the window.
- applicationView->Activated +=
+ applicationView->Activated +=
ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
// Logic for other event handlers could go here.
@@ -78,10 +78,10 @@ void App::SetWindow(CoreWindow^ p_window)
window->VisibilityChanged +=
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
- window->Closed +=
+ window->Closed +=
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
- window->SizeChanged +=
+ window->SizeChanged +=
ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &App::OnWindowSizeChanged);
#if !(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
diff --git a/platform/winrt/app.h b/platform/winrt/app.h
index 9ce2fe560f..25b0d524ae 100644
--- a/platform/winrt/app.h
+++ b/platform/winrt/app.h
@@ -46,7 +46,7 @@ namespace $ext_safeprojectname$
bool mWindowVisible;
GLsizei mWindowWidth;
GLsizei mWindowHeight;
-
+
EGLDisplay mEglDisplay;
EGLContext mEglContext;
EGLSurface mEglSurface;
diff --git a/platform/winrt/include/FunctionDiscoveryKeys_devpkey.h b/platform/winrt/include/FunctionDiscoveryKeys_devpkey.h
index 303e70b029..25fa6660c2 100644
--- a/platform/winrt/include/FunctionDiscoveryKeys_devpkey.h
+++ b/platform/winrt/include/FunctionDiscoveryKeys_devpkey.h
@@ -29,7 +29,7 @@ Revision History:
20-June-2006 dougb
Copied Jim's version replaced "DEFINE_DEVPROPKEY(DEVPKEY_" with "DEFINE_PROPERTYKEY(PKEY_"
-
+
--*/
//#include <devpropdef.h>
diff --git a/platform/winrt/include/GLES2/gl2ext.h b/platform/winrt/include/GLES2/gl2ext.h
index d77fdbaebc..d5a9dd195b 100644
--- a/platform/winrt/include/GLES2/gl2ext.h
+++ b/platform/winrt/include/GLES2/gl2ext.h
@@ -94,23 +94,23 @@ typedef void* GLeglImageOES;
#endif
/* GL_OES_required_internalformat */
-#ifndef GL_OES_required_internalformat
+#ifndef GL_OES_required_internalformat
#define GL_ALPHA8_OES 0x803C
#define GL_DEPTH_COMPONENT16_OES 0x81A5
-/* reuse GL_DEPTH_COMPONENT24_OES */
-/* reuse GL_DEPTH24_STENCIL8_OES */
-/* reuse GL_DEPTH_COMPONENT32_OES */
+/* reuse GL_DEPTH_COMPONENT24_OES */
+/* reuse GL_DEPTH24_STENCIL8_OES */
+/* reuse GL_DEPTH_COMPONENT32_OES */
#define GL_LUMINANCE4_ALPHA4_OES 0x8043
#define GL_LUMINANCE8_ALPHA8_OES 0x8045
#define GL_LUMINANCE8_OES 0x8040
#define GL_RGBA4_OES 0x8056
#define GL_RGB5_A1_OES 0x8057
#define GL_RGB565_OES 0x8D62
-/* reuse GL_RGB8_OES */
-/* reuse GL_RGBA8_OES */
+/* reuse GL_RGB8_OES */
+/* reuse GL_RGBA8_OES */
/* reuse GL_RGB10_EXT */
/* reuse GL_RGB10_A2_EXT */
-#endif
+#endif
/* GL_OES_rgb8_rgba8 */
#ifndef GL_OES_rgb8_rgba8
@@ -210,9 +210,9 @@ typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLen
#define GL_SHADER 0x82E1
#define GL_PROGRAM 0x82E2
#define GL_QUERY 0x82E3
-/* PROGRAM_PIPELINE only in GL */
+/* PROGRAM_PIPELINE only in GL */
#define GL_SAMPLER 0x82E6
-/* DISPLAY_LIST only in GL */
+/* DISPLAY_LIST only in GL */
#define GL_MAX_LABEL_LENGTH 0x82E8
#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
@@ -322,12 +322,12 @@ typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLen
#endif
/* GL_ANGLE_instanced_arrays */
-#ifndef GL_ANGLE_instanced_arrays
+#ifndef GL_ANGLE_instanced_arrays
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
#endif
/* GL_ANGLE_pack_reverse_row_order */
-#ifndef GL_ANGLE_pack_reverse_row_order
+#ifndef GL_ANGLE_pack_reverse_row_order
#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
#endif
@@ -337,23 +337,23 @@ typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLen
#endif
/* GL_ANGLE_texture_compression_dxt3 */
-#ifndef GL_ANGLE_texture_compression_dxt3
+#ifndef GL_ANGLE_texture_compression_dxt3
#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
#endif
/* GL_ANGLE_texture_compression_dxt5 */
-#ifndef GL_ANGLE_texture_compression_dxt5
+#ifndef GL_ANGLE_texture_compression_dxt5
#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
#endif
/* GL_ANGLE_texture_usage */
-#ifndef GL_ANGLE_texture_usage
+#ifndef GL_ANGLE_texture_usage
#define GL_TEXTURE_USAGE_ANGLE 0x93A2
#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
#endif
/* GL_ANGLE_translated_shader_source */
-#ifndef GL_ANGLE_translated_shader_source
+#ifndef GL_ANGLE_translated_shader_source
#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
#endif
@@ -363,7 +363,7 @@ typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLen
/* GL_APPLE_copy_texture_levels */
/* No new tokens introduced by this extension. */
-
+
/* GL_APPLE_framebuffer_multisample */
#ifndef GL_APPLE_framebuffer_multisample
#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
@@ -388,9 +388,9 @@ typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLen
#ifndef __gl3_h_
/* These types are defined with reference to <inttypes.h>
* in the Apple extension spec, but here we use the Khronos
- * portable types in khrplatform.h, and assume those types
+ * portable types in khrplatform.h, and assume those types
* are always defined.
- * If any other extensions using these types are defined,
+ * If any other extensions using these types are defined,
* the typedefs must move out of this block and be shared.
*/
typedef khronos_int64_t GLint64;
@@ -496,7 +496,7 @@ typedef struct __GLsync *GLsync;
/* GL_EXT_multisampled_render_to_texture */
#ifndef GL_EXT_multisampled_render_to_texture
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
-/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */
+/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
#define GL_MAX_SAMPLES_EXT 0x8D57
@@ -604,10 +604,10 @@ typedef struct __GLsync *GLsync;
/* GL_EXT_texture_storage */
#ifndef GL_EXT_texture_storage
#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
-#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA8_EXT 0x803C
#define GL_LUMINANCE8_EXT 0x8040
#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
-#define GL_RGBA32F_EXT 0x8814
+#define GL_RGBA32F_EXT 0x8814
#define GL_RGB32F_EXT 0x8815
#define GL_ALPHA32F_EXT 0x8816
#define GL_LUMINANCE32F_EXT 0x8818
@@ -617,12 +617,12 @@ typedef struct __GLsync *GLsync;
#define GL_ALPHA16F_EXT 0x881C
#define GL_LUMINANCE16F_EXT 0x881E
#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
-#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGB10_A2_EXT 0x8059
#define GL_RGB10_EXT 0x8052
#define GL_BGRA8_EXT 0x93A1
#define GL_R8_EXT 0x8229
#define GL_RG8_EXT 0x822B
-#define GL_R32F_EXT 0x822E
+#define GL_R32F_EXT 0x822E
#define GL_RG32F_EXT 0x8230
#define GL_R16F_EXT 0x822D
#define GL_RG16F_EXT 0x822F
@@ -817,7 +817,7 @@ typedef struct __GLsync *GLsync;
#ifndef GL_NV_framebuffer_blit
#define GL_READ_FRAMEBUFFER_NV 0x8CA8
#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9
-#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
+#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
#endif
@@ -856,10 +856,10 @@ typedef struct __GLsync *GLsync;
/* GL_NV_shadow_samplers_array */
#ifndef GL_NV_shadow_samplers_array
#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
-#endif
-
+#endif
+
/* GL_NV_shadow_samplers_cube */
-#ifndef GL_NV_shadow_samplers_cube
+#ifndef GL_NV_shadow_samplers_cube
#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
#endif
@@ -1194,7 +1194,7 @@ GL_APICALL void GL_APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GL
GL_APICALL void GL_APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
GL_APICALL void GL_APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
GL_APICALL void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
-#endif
+#endif
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
@@ -1288,7 +1288,7 @@ GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
#endif
-#ifndef GL_ANGLE_instanced_arrays
+#ifndef GL_ANGLE_instanced_arrays
#define GL_ANGLE_instanced_arrays 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
@@ -1301,7 +1301,7 @@ typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLu
#endif
/* GL_ANGLE_pack_reverse_row_order */
-#ifndef GL_ANGLE_pack_reverse_row_order
+#ifndef GL_ANGLE_pack_reverse_row_order
#define GL_ANGLE_pack_reverse_row_order 1
#endif
@@ -1311,21 +1311,21 @@ typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLu
#endif
/* GL_ANGLE_texture_compression_dxt3 */
-#ifndef GL_ANGLE_texture_compression_dxt3
+#ifndef GL_ANGLE_texture_compression_dxt3
#define GL_ANGLE_texture_compression_dxt3 1
#endif
/* GL_ANGLE_texture_compression_dxt5 */
-#ifndef GL_ANGLE_texture_compression_dxt5
+#ifndef GL_ANGLE_texture_compression_dxt5
#define GL_ANGLE_texture_compression_dxt5 1
#endif
/* GL_ANGLE_texture_usage */
-#ifndef GL_ANGLE_texture_usage
+#ifndef GL_ANGLE_texture_usage
#define GL_ANGLE_texture_usage 1
#endif
-#ifndef GL_ANGLE_translated_shader_source
+#ifndef GL_ANGLE_translated_shader_source
#define GL_ANGLE_translated_shader_source 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
diff --git a/platform/winrt/include/GLES3/gl3.h b/platform/winrt/include/GLES3/gl3.h
index 9c79862c0d..b7e91e6881 100644
--- a/platform/winrt/include/GLES3/gl3.h
+++ b/platform/winrt/include/GLES3/gl3.h
@@ -1,7 +1,7 @@
#ifndef __gl3_h_
#define __gl3_h_
-/*
+/*
* gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
*/
diff --git a/platform/winrt/include/GLSLANG/ShaderLang.h b/platform/winrt/include/GLSLANG/ShaderLang.h
index 647fed6a02..e486692482 100644
--- a/platform/winrt/include/GLSLANG/ShaderLang.h
+++ b/platform/winrt/include/GLSLANG/ShaderLang.h
@@ -107,7 +107,7 @@ typedef enum {
// This is needed only as a workaround for certain OpenGL driver bugs.
SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100,
- // This is an experimental flag to enforce restrictions that aim to prevent
+ // This is an experimental flag to enforce restrictions that aim to prevent
// timing attacks.
// It generates compilation errors for shaders that could expose sensitive
// texture information via the timing channel.
diff --git a/platform/winrt/include/KHR/khrplatform.h b/platform/winrt/include/KHR/khrplatform.h
index c9e6f17d34..43aac97a73 100644
--- a/platform/winrt/include/KHR/khrplatform.h
+++ b/platform/winrt/include/KHR/khrplatform.h
@@ -223,7 +223,7 @@ typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
- * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
diff --git a/platform/winrt/os_winrt.cpp b/platform/winrt/os_winrt.cpp
index f507c1aae7..5ec1bd2756 100644
--- a/platform/winrt/os_winrt.cpp
+++ b/platform/winrt/os_winrt.cpp
@@ -43,7 +43,6 @@
#include "servers/audio/audio_server_sw.h"
#include "servers/visual/visual_server_wrap_mt.h"
-#include "os/pc_joystick_map.h"
#include "os/memory_pool_dynamic_prealloc.h"
#include "globals.h"
#include "io/marshalls.h"
@@ -96,7 +95,7 @@ void OSWinrt::initialize_core() {
ThreadWinrt::make_default();
//SemaphoreWindows::make_default();
- MutexWindows::make_default();
+ MutexWindows::make_default();
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
@@ -108,7 +107,7 @@ void OSWinrt::initialize_core() {
//TCPServerWinsock::make_default();
//StreamPeerWinsock::make_default();
-
+
mempool_static = new MemoryPoolStaticMalloc;
#if 1
mempool_dynamic = memnew( MemoryPoolDynamicStatic );
@@ -118,7 +117,7 @@ void OSWinrt::initialize_core() {
mempool_dynamic = memnew( MemoryPoolDynamicPrealloc(buffer,DYNPOOL_SIZE) );
#endif
-
+
// We need to know how often the clock is updated
if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second) )
ticks_per_second = 1000;
@@ -176,7 +175,7 @@ void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_aud
physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server->init();
- visual_server->init();
+ visual_server->init();
input = memnew( InputDefault );
@@ -308,7 +307,7 @@ void OSWinrt::finalize() {
memdelete(main_loop);
main_loop=NULL;
-
+
visual_server->finish();
memdelete(visual_server);
#ifdef OPENGL_ENABLED
@@ -326,7 +325,7 @@ void OSWinrt::finalize() {
//if (debugger_connection_console) {
// memdelete(debugger_connection_console);
//}
-
+
memdelete(sample_manager);
audio_server->finish();
@@ -419,7 +418,7 @@ OS::VideoMode OSWinrt::get_video_mode(int p_screen) const {
}
void OSWinrt::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
-
+
}
void OSWinrt::print_error(const char* p_function, const char* p_file, int p_line, const char* p_code, const char* p_rationale, ErrorType p_type) {
@@ -528,7 +527,7 @@ void OSWinrt::delay_usec(uint32_t p_usec) const {
// no Sleep()
WaitForSingleObjectEx(GetCurrentThread(), msec, false);
-
+
}
uint64_t OSWinrt::get_ticks_usec() const {
@@ -634,22 +633,22 @@ void OSWinrt::run() {
if (!main_loop)
return;
-
+
main_loop->init();
-
+
uint64_t last_ticks=get_ticks_usec();
-
+
int frames=0;
uint64_t frame=0;
-
+
while (!force_quit) {
-
+
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
process_events(); // get rid of pending events
if (Main::iteration()==true)
break;
};
-
+
main_loop->finish();
}
diff --git a/platform/winrt/os_winrt.h b/platform/winrt/os_winrt.h
index 3fbb4a4c1b..0307f81954 100644
--- a/platform/winrt/os_winrt.h
+++ b/platform/winrt/os_winrt.h
@@ -122,7 +122,7 @@ class OSWinrt : public OS {
List<Joystick> joystick_change_queue;
int joystick_count;
Joystick joysticks[JOYSTICKS_MAX];
-
+
VideoMode video_mode;
MainLoop *main_loop;
@@ -153,30 +153,30 @@ class OSWinrt : public OS {
// functions used by main to initialize/deintialize the OS
-protected:
+protected:
virtual int get_video_driver_count() const;
virtual const char * get_video_driver_name(int p_driver) const;
-
+
virtual VideoMode get_default_video_mode() const;
-
+
virtual int get_audio_driver_count() const;
virtual const char * get_audio_driver_name(int p_driver) const;
-
+
virtual void initialize_core();
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
-
- virtual void set_main_loop( MainLoop * p_main_loop );
+
+ virtual void set_main_loop( MainLoop * p_main_loop );
virtual void delete_main_loop();
-
+
virtual void finalize();
virtual void finalize_core();
-
+
void process_events();
void probe_joysticks();
void process_joysticks();
void process_key_events();
-
+
public:
void print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type);
@@ -191,7 +191,7 @@ public:
virtual Point2 get_mouse_pos() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String& p_title);
-
+
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
@@ -199,7 +199,7 @@ public:
virtual MainLoop *get_main_loop() const;
virtual String get_name();
-
+
virtual Date get_date(bool utc) const;
virtual Time get_time(bool utc) const;
virtual TimeZoneInfo get_time_zone_info() const;
@@ -208,7 +208,7 @@ public:
virtual bool can_draw() const;
virtual Error set_cwd(const String& p_cwd);
- virtual void delay_usec(uint32_t p_usec) const;
+ virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL);
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 89bd5f58ff..9f987e1376 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -41,7 +41,7 @@
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
-struct ContextGL_X11_Private {
+struct ContextGL_X11_Private {
::GLXContext glx_context;
};
@@ -76,13 +76,13 @@ static GLWrapperFuncPtr wrapper_get_proc_address(const char* p_function) {
Error ContextGL_X11::initialize() {
-
+
GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL;
-
+
// const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
-
+
glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
-
+
ERR_FAIL_COND_V( !glXCreateContextAttribsARB, ERR_UNCONFIGURED );
@@ -94,13 +94,13 @@ Error ContextGL_X11::initialize() {
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DEPTH_SIZE, 24,
- None
+ None
};
int fbcount;
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
ERR_FAIL_COND_V(!fbc,ERR_UNCONFIGURED);
-
+
XVisualInfo *vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);
XSetWindowAttributes swa;
@@ -140,7 +140,7 @@ Error ContextGL_X11::initialize() {
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
None
};
-
+
p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs);
ERR_FAIL_COND_V(!p->glx_context,ERR_UNCONFIGURED);
}
@@ -150,7 +150,7 @@ Error ContextGL_X11::initialize() {
/*
glWrapperInit(wrapper_get_proc_address);
glFlush();
-
+
glXSwapBuffers(x11_display,x11_window);
*/
//glXMakeCurrent(x11_display, None, NULL);
@@ -165,14 +165,14 @@ int ContextGL_X11::get_window_width() {
XWindowAttributes xwa;
XGetWindowAttributes(x11_display,x11_window,&xwa);
-
+
return xwa.width;
}
int ContextGL_X11::get_window_height() {
XWindowAttributes xwa;
XGetWindowAttributes(x11_display,x11_window,&xwa);
-
+
return xwa.height;
}
@@ -181,9 +181,9 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,con
default_video_mode=p_default_video_mode;
x11_display=p_x11_display;
-
+
opengl_3_context=p_opengl_3_context;
-
+
double_buffer=false;
direct_render=false;
glx_minor=glx_major=0;
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index 56404d0fae..c77fb3e333 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -50,22 +50,22 @@ class ContextGL_X11 : public ContextGL {
OS::VideoMode default_video_mode;
// ::Colormap x11_colormap;
::Display *x11_display;
- ::Window& x11_window;
+ ::Window& x11_window;
bool double_buffer;
bool direct_render;
int glx_minor,glx_major;
bool opengl_3_context;
public:
- virtual void release_current();
- virtual void make_current();
+ virtual void release_current();
+ virtual void make_current();
virtual void swap_buffers();
virtual int get_window_width();
virtual int get_window_height();
virtual Error initialize();
- ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context);
+ ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context);
~ContextGL_X11();
};
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index bb4bf9bd6f..6b147db130 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -52,10 +52,11 @@ def get_opts():
return [
('use_llvm','Use llvm compiler','no'),
+ ('use_static_cpp','link stdc++ statically','no'),
('use_sanitizer','Use llvm compiler sanitize address','no'),
('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'),
('pulseaudio','Detect & Use pulseaudio','yes'),
- ('gamepad','Gamepad support, requires libudev and libevdev','yes'),
+ ('udev','Use udev for gamepad connection callbacks','no'),
('new_wm_api', 'Use experimental window management API','no'),
('debug_release', 'Add debug symbols to release version','no'),
]
@@ -155,20 +156,18 @@ def configure(env):
else:
print("ALSA libraries not found, disabling driver")
- if (env["gamepad"]=="yes" and platform.system() == "Linux"):
+ if (platform.system() == "Linux"):
+ env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
+ if (env["udev"]=="yes"):
# pkg-config returns 0 when the lib exists...
found_udev = not os.system("pkg-config --exists libudev")
-
+
if (found_udev):
- print("Enabling gamepad support with udev")
- env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
+ print("Enabling udev support")
+ env.Append(CPPFLAGS=["-DUDEV_ENABLED"])
env.ParseConfig('pkg-config libudev --cflags --libs')
else:
- print("libudev development libraries not found")
-
- print("Some libraries are missing for the required gamepad support, aborting!")
- print("Install the mentioned libraries or build with 'gamepad=no' to disable gamepad support.")
- sys.exit(255)
+ print("libudev development libraries not found, disabling udev support")
if (env["pulseaudio"]=="yes"):
if not os.system("pkg-config --exists libpulse-simple"):
@@ -203,5 +202,8 @@ def configure(env):
env.Append(CPPFLAGS=['-DNEW_WM_API'])
env.ParseConfig('pkg-config xinerama --cflags --libs')
+ if (env["use_static_cpp"]=="yes"):
+ env.Append(LINKFLAGS=['-static-libstdc++'])
+
env["x86_opt_gcc"]=True
diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp
index ee83da25c1..c500f939c4 100644
--- a/platform/x11/godot_x11.cpp
+++ b/platform/x11/godot_x11.cpp
@@ -30,16 +30,16 @@
#include "os_x11.h"
int main(int argc, char* argv[]) {
-
+
OS_X11 os;
-
+
Error err = Main::setup(argv[0],argc-1,&argv[1]);
if (err!=OK)
return 255;
-
+
if (Main::start())
os.run(); // it is actually the OS that decides how to run
Main::cleanup();
-
+
return os.get_exit_code();
}
diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp
index 5007976f0d..0615f33f96 100644
--- a/platform/x11/joystick_linux.cpp
+++ b/platform/x11/joystick_linux.cpp
@@ -33,13 +33,17 @@
#include "joystick_linux.h"
#include <linux/input.h>
-#include <libudev.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
-#define test_bit(nr, addr) (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
-#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
+#ifdef UDEV_ENABLED
+#include <libudev.h>
+#endif
+
+#define LONG_BITS (sizeof(long) * 8)
+#define test_bit(nr, addr) (((1UL << ((nr) % LONG_BITS)) & ((addr)[(nr) / LONG_BITS])) != 0)
+#define NBITS(x) ((((x)-1)/LONG_BITS)+1)
static const char* ignore_str = "/dev/input/js";
@@ -98,14 +102,18 @@ void joystick_linux::joy_thread_func(void *p_user) {
}
void joystick_linux::run_joystick_thread() {
-
+#ifdef UDEV_ENABLED
udev *_udev = udev_new();
ERR_FAIL_COND(!_udev);
enumerate_joysticks(_udev);
monitor_joysticks(_udev);
udev_unref(_udev);
+#else
+ monitor_joysticks();
+#endif
}
+#ifdef UDEV_ENABLED
void joystick_linux::enumerate_joysticks(udev *p_udev) {
udev_enumerate *enumerate;
@@ -191,6 +199,23 @@ void joystick_linux::monitor_joysticks(udev *p_udev) {
//printf("exit udev\n");
udev_monitor_unref(mon);
}
+#endif
+
+void joystick_linux::monitor_joysticks() {
+
+ while (!exit_udev) {
+ joy_mutex->lock();
+ for (int i = 0; i < 32; i++) {
+ char fname[64];
+ sprintf(fname, "/dev/input/event%d", i);
+ if (attached_devices.find(fname) == -1) {
+ open_joystick(fname);
+ }
+ }
+ joy_mutex->unlock();
+ usleep(1000000); // 1s
+ }
+}
int joystick_linux::get_free_joy_slot() const {
@@ -228,6 +253,7 @@ void joystick_linux::close_joystick(int p_id) {
close(joy.fd);
joy.fd = -1;
+ attached_devices.remove(attached_devices.find(joy.devpath));
input->joy_connection_changed(p_id, false, "");
};
};
@@ -301,17 +327,23 @@ void joystick_linux::open_joystick(const char *p_path) {
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
+ // add to attached devices so we don't try to open it again
+ attached_devices.push_back(String(p_path));
+
if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
(ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
+ close(fd);
return;
}
//check if the device supports basic gamepad events, prevents certain keyboards from
//being detected as joysticks
if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
- ((test_bit(ABS_X, absbit) || test_bit(ABS_Y, absbit)) ||
- (test_bit(BTN_A, keybit) || test_bit(BTN_THUMBL, keybit))))) {
+ (test_bit(ABS_X, absbit) || test_bit(ABS_Y, absbit) || test_bit(ABS_HAT0X, absbit) ||
+ test_bit(ABS_GAS, absbit) || test_bit(ABS_RUDDER, absbit)) &&
+ (test_bit(BTN_A, keybit) || test_bit(BTN_THUMBL, keybit) ||
+ test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_1, keybit)))) {
close(fd);
return;
}
@@ -397,6 +429,12 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) {
for (int j = 0; j < len; j++) {
input_event &ev = events[j];
+
+ // ev may be tainted and out of MAX_KEY range, which will cause
+ // joy->key_map[ev.code] to crash
+ if( ev.code < 0 || ev.code >= MAX_KEY )
+ return p_event_id;
+
switch (ev.type) {
case EV_KEY:
p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value);
@@ -442,6 +480,9 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) {
p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]);
}
}
+ if (len == 0 || (len < 0 && errno != EAGAIN)) {
+ close_joystick(i);
+ };
}
joy_mutex->unlock();
return p_event_id;
diff --git a/platform/x11/joystick_linux.h b/platform/x11/joystick_linux.h
index 7f96e3451f..4f0533721b 100644
--- a/platform/x11/joystick_linux.h
+++ b/platform/x11/joystick_linux.h
@@ -49,13 +49,11 @@ private:
JOYSTICKS_MAX = 16,
MAX_ABS = 63,
MAX_KEY = 767, // Hack because <linux/input.h> can't be included here
- BT_MISC = 256,
- HAT_MAX = 4,
};
struct Joystick {
InputDefault::JoyAxis curr_axis[MAX_ABS];
- int key_map[MAX_KEY - BT_MISC];
+ int key_map[MAX_KEY];
int abs_map[MAX_ABS];
int dpad;
int fd;
@@ -73,6 +71,7 @@ private:
Thread *joy_thread;
InputDefault *input;
Joystick joysticks[JOYSTICKS_MAX];
+ Vector<String> attached_devices;
static void joy_thread_func(void *p_user);
@@ -81,8 +80,11 @@ private:
void setup_joystick_properties(int p_id);
void close_joystick(int p_id = -1);
+#ifdef UDEV_ENABLED
void enumerate_joysticks(struct udev *_udev);
void monitor_joysticks(struct udev *_udev);
+#endif
+ void monitor_joysticks();
void run_joystick_thread();
void open_joystick(const char* path);
diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp
index 48f415a730..190d6925dd 100644
--- a/platform/x11/key_mapping_x11.cpp
+++ b/platform/x11/key_mapping_x11.cpp
@@ -32,14 +32,14 @@
/***** SCAN CODE CONVERSION ******/
struct _XTranslatePair {
-
+
KeySym keysym;
unsigned int keycode;
};
-static _XTranslatePair _xkeysym_to_keycode[]={
+static _XTranslatePair _xkeysym_to_keycode[]={
// misc keys
-
+
{ XK_Escape, KEY_ESCAPE },
{ XK_Tab, KEY_TAB },
{ XK_ISO_Left_Tab, KEY_BACKTAB },
@@ -97,7 +97,7 @@ static _XTranslatePair _xkeysym_to_keycode[]={
{ XK_KP_Enter, KEY_KP_ENTER },
{ XK_KP_Multiply, KEY_KP_MULTIPLY},
{ XK_KP_Divide, KEY_KP_DIVIDE},
- { XK_KP_Subtract, KEY_KP_SUBSTRACT},
+ { XK_KP_Subtract, KEY_KP_SUBTRACT},
{ XK_KP_Add, KEY_KP_ADD},
{ XK_KP_0, KEY_KP_0},
{ XK_KP_1, KEY_KP_1},
@@ -136,8 +136,8 @@ static _XTranslatePair _xkeysym_to_keycode[]={
{ XK_F14, KEY_F14},
{ XK_F15, KEY_F15},
{ XK_F16, KEY_F16},
-
- // media keys
+
+ // media keys
{ XF86XK_Back, KEY_BACK },
{ XF86XK_Forward, KEY_FORWARD },
{ XF86XK_Stop, KEY_STOP },
@@ -146,7 +146,7 @@ static _XTranslatePair _xkeysym_to_keycode[]={
{ XF86XK_AudioMedia, KEY_LAUNCHMEDIA },
{ XF86XK_OpenURL, KEY_OPENURL },
{ XF86XK_HomePage, KEY_HOMEPAGE },
- { XF86XK_Search, KEY_SEARCH },
+ { XF86XK_Search, KEY_SEARCH },
{ XF86XK_AudioLowerVolume, KEY_VOLUMEDOWN },
{ XF86XK_AudioMute, KEY_VOLUMEMUTE },
{ XF86XK_AudioRaiseVolume, KEY_VOLUMEUP },
@@ -155,13 +155,13 @@ static _XTranslatePair _xkeysym_to_keycode[]={
{ XF86XK_AudioPrev, KEY_MEDIAPREVIOUS },
{ XF86XK_AudioNext, KEY_MEDIANEXT },
{ XF86XK_AudioRecord, KEY_MEDIARECORD },
-
+
// launch keys
{ XF86XK_Mail, KEY_LAUNCHMAIL },
{ XF86XK_MyComputer, KEY_LAUNCH0 },
{ XF86XK_Calculator, KEY_LAUNCH1 },
{ XF86XK_Standby, KEY_STANDBY },
-
+
{ XF86XK_Launch0, KEY_LAUNCH2 },
{ XF86XK_Launch1, KEY_LAUNCH3 },
{ XF86XK_Launch2, KEY_LAUNCH4 },
@@ -176,41 +176,41 @@ static _XTranslatePair _xkeysym_to_keycode[]={
{ XF86XK_LaunchB, KEY_LAUNCHD },
{ XF86XK_LaunchC, KEY_LAUNCHE },
{ XF86XK_LaunchD, KEY_LAUNCHF },
-
+
{0, 0 }
};
unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
-
+
// kinda bruteforce.. could optimize.
-
+
if (p_keysym<0x100) // Latin 1, maps 1-1
return p_keysym;
-
+
// look for special key
for(int idx=0;_xkeysym_to_keycode[idx].keysym!=0;idx++) {
-
+
if (_xkeysym_to_keycode[idx].keysym==p_keysym)
return _xkeysym_to_keycode[idx].keycode;
}
-
+
return 0;
}
KeySym KeyMappingX11::get_keysym(unsigned int p_code) {
-
+
// kinda bruteforce.. could optimize.
-
+
if (p_code<0x100) // Latin 1, maps 1-1
return p_code;
-
+
// look for special key
for(int idx=0;_xkeysym_to_keycode[idx].keysym!=0;idx++) {
-
+
if (_xkeysym_to_keycode[idx].keycode==p_code)
return _xkeysym_to_keycode[idx].keysym;
}
-
+
return 0;
}
@@ -220,13 +220,13 @@ KeySym KeyMappingX11::get_keysym(unsigned int p_code) {
// Tables taken from FOX toolkit
struct _XTranslateUnicodePair {
-
+
KeySym keysym;
unsigned int unicode;
};
enum {
-
+
_KEYSYM_MAX=759
};
@@ -992,7 +992,7 @@ static _XTranslateUnicodePair _xkeysym_to_unicode[_KEYSYM_MAX] = {
};
unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) {
-
+
/* Latin-1 */
if (p_keysym>=0x20 && p_keysym<=0x7e)
return p_keysym;
@@ -1001,13 +1001,13 @@ unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) {
// keypad to latin1 is easy
if (p_keysym>=0xffaa && p_keysym<=0xffb9)
return p_keysym-0xff80;
-
+
/* Unicode (may be present)*/
-
- if((p_keysym&0xff000000)==0x01000000)
+
+ if((p_keysym&0xff000000)==0x01000000)
return p_keysym&0x00ffffff;
-
- int middle,low=0,high=_KEYSYM_MAX-1;
+
+ int middle,low=0,high=_KEYSYM_MAX-1;
do {
middle=(high+low)/2;
if ( _xkeysym_to_unicode[middle].keysym==p_keysym)
@@ -1017,19 +1017,19 @@ unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) {
else
high=middle-1;
} while (high>=low);
-
+
return 0;
-
+
}
struct _XTranslateUnicodePairReverse {
-
+
unsigned int unicode;
KeySym keysym;
};
enum {
-
+
_UNICODE_MAX=750
};
@@ -1783,20 +1783,20 @@ static _XTranslateUnicodePairReverse _unicode_to_xkeysym[_UNICODE_MAX] = {
{ 0x0EF4, 0x3184 },
{ 0x0EF5, 0x3186 },
{ 0x0EF6, 0x318D },
- { 0x0EF7, 0x318E }
+ { 0x0EF7, 0x318E }
};
KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) {
-
+
/* Latin 1 */
-
+
if (p_unicode>=0x20 && p_unicode<=0x7e)
return p_unicode;
-
+
if (p_unicode>=0xa0 && p_unicode<=0xff)
return p_unicode;
-
- int middle,low=0,high=_UNICODE_MAX-1;
+
+ int middle,low=0,high=_UNICODE_MAX-1;
do {
middle=(high+low)/2;
if ( _unicode_to_xkeysym[middle].keysym==p_unicode)
@@ -1806,7 +1806,7 @@ KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) {
else
high=middle-1;
} while (high>=low);
-
+
// if not found, let's hope X understands it as unicode
return p_unicode|0x01000000;
}
diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h
index 979d8a112f..e3aede8388 100644
--- a/platform/x11/key_mapping_x11.h
+++ b/platform/x11/key_mapping_x11.h
@@ -48,7 +48,7 @@ public:
static KeySym get_keysym(unsigned int p_code);
static unsigned int get_unicode_from_keysym(KeySym p_keysym);
static KeySym get_keysym_from_unicode(unsigned int p_unicode);
-
+
};
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index f42e93b93f..f60610693f 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -65,7 +65,6 @@
#include <X11/Xatom.h>
-//#include "os/pc_joystick_map.h"
#undef CursorShape
@@ -110,15 +109,15 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
if (get_render_thread_mode()==RENDER_SEPARATE_THREAD) {
XInitThreads();
}
-
+
/** XLIB INITIALIZATION **/
x11_display = XOpenDisplay(NULL);
-
+
char * modifiers = XSetLocaleModifiers ("@im=none");
ERR_FAIL_COND( modifiers == NULL );
-
+
xim = XOpenIM (x11_display, NULL, NULL, NULL);
-
+
if (xim == NULL) {
WARN_PRINT("XOpenIM failed");
@@ -131,19 +130,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
if (imvalret != NULL || xim_styles == NULL) {
fprintf (stderr, "Input method doesn't support any styles\n");
}
-
+
if (xim_styles) {
xim_style = 0L;
for (int i=0;i<xim_styles->count_styles;i++) {
-
+
if (xim_styles->supported_styles[i] ==
(XIMPreeditNothing | XIMStatusNothing)) {
-
+
xim_style = xim_styles->supported_styles[i];
break;
}
}
-
+
XFree (xim_styles);
}
XFree( imvalret );
@@ -226,7 +225,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
} else {
XGetWindowAttributes(x11_display,x11_window,&xwa);
}
- xsh->min_width = xwa.width;
+ xsh->min_width = xwa.width;
xsh->max_width = xwa.width;
xsh->min_height = xwa.height;
xsh->max_height = xwa.height;
@@ -283,7 +282,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
spatial_sound_2d_server->init();
-
+
ERR_FAIL_COND(!visual_server);
ERR_FAIL_COND(x11_window==0);
@@ -303,7 +302,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
ColormapChangeMask | OwnerGrabButtonMask;
XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr);
-
+
XClassHint* classHint;
/* set the titlebar name */
@@ -318,19 +317,19 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint);
- wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
+ wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
-
+
if (xim && xim_style) {
-
+
xic = XCreateIC (xim,XNInputStyle, xim_style,XNClientWindow,x11_window,XNFocusWindow, x11_window, (char*)NULL);
} else {
-
+
xic=NULL;
WARN_PRINT("XCreateIC couldn't create xic");
- }
+ }
XcursorSetTheme(x11_display,"default");
cursor_size = XcursorGetDefaultSize(x11_display);
@@ -460,7 +459,7 @@ void OS_X11::finalize() {
visual_server->finish();
memdelete(visual_server);
memdelete(rasterizer);
-
+
physics_server->finish();
memdelete(physics_server);
@@ -475,10 +474,10 @@ void OS_X11::finalize() {
#endif
for(int i=0;i<CURSOR_MAX;i++) {
if( cursors[i] != None )
- XFreeCursor( x11_display, cursors[i] );
+ XFreeCursor( x11_display, cursors[i] );
if( img[i] != NULL )
XcursorImageDestroy( img[i] );
- };
+ };
XDestroyIC( xic );
XCloseIM( xim );
@@ -487,7 +486,7 @@ void OS_X11::finalize() {
if (xmbstring)
memfree(xmbstring);
-
+
args.clear();
}
@@ -575,6 +574,10 @@ Point2 OS_X11::get_mouse_pos() const {
void OS_X11::set_window_title(const String& p_title) {
XStoreName(x11_display,x11_window,p_title.utf8().get_data());
+
+ Atom _net_wm_name = XInternAtom(x11_display, "_NET_WM_NAME", false);
+ Atom utf8_string = XInternAtom(x11_display, "UTF8_STRING", false);
+ XChangeProperty( x11_display, x11_window, _net_wm_name, utf8_string, 8, PropModeReplace, (unsigned char*) p_title.utf8().get_data(), p_title.utf8().length());
}
void OS_X11::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
@@ -627,7 +630,7 @@ int OS_X11::get_screen_count() const {
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
if( !ext_okay ) return 0;
-
+
int count;
XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
XFree(xsi);
@@ -644,7 +647,7 @@ int OS_X11::get_current_screen() const {
Point2i pos = get_screen_position(i);
Size2i size = get_screen_size(i);
if( (x >= pos.x && x <pos.x + size.width) && (y >= pos.y && y < pos.y + size.height) )
- return i;
+ return i;
}
return 0;
}
@@ -652,7 +655,7 @@ int OS_X11::get_current_screen() const {
void OS_X11::set_current_screen(int p_screen) {
int count = get_screen_count();
if(p_screen >= count) return;
-
+
if( current_videomode.fullscreen ) {
Point2i position = get_screen_position(p_screen);
Size2i size = get_screen_size(p_screen);
@@ -674,13 +677,13 @@ Point2 OS_X11::get_screen_position(int p_screen) const {
if( !ext_okay ) {
return Point2i(0,0);
}
-
+
int count;
XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
if( p_screen >= count ) {
return Point2i(0,0);
}
-
+
Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org);
XFree(xsi);
@@ -693,11 +696,11 @@ Size2 OS_X11::get_screen_size(int p_screen) const {
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
if( !ext_okay ) return Size2i(0,0);
-
+
int count;
XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
if( p_screen >= count ) return Size2i(0,0);
-
+
Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height);
XFree(xsi);
return size;
@@ -711,12 +714,12 @@ Point2 OS_X11::get_window_position() const {
int screen = get_current_screen();
Point2i screen_position = get_screen_position(screen);
- return Point2i(x-screen_position.x, y-screen_position.y);
+ return Point2i(x-screen_position.x, y-screen_position.y);
}
void OS_X11::set_window_position(const Point2& p_position) {
// Using EWMH -- Extended Window Manager Hints
- // to get the size of the decoration
+ // to get the size of the decoration
#if 0
Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True);
Atom type;
@@ -739,17 +742,17 @@ void OS_X11::set_window_position(const Point2& p_position) {
&len,
&remaining,
&data
- );
+ );
long left = 0L;
long top = 0L;
if( result == Success ) {
long *extends = (long *) data;
-
+
left = extends[0];
top = extends[2];
-
+
XFree(data);
}
@@ -791,7 +794,7 @@ void OS_X11::set_window_resizable(bool p_enabled) {
if(!p_enabled) {
XWindowAttributes xwa;
XGetWindowAttributes(x11_display,x11_window,&xwa);
- xsh->min_width = xwa.width;
+ xsh->min_width = xwa.width;
xsh->max_width = xwa.width;
xsh->min_height = xwa.height;
xsh->max_height = xwa.height;
@@ -818,7 +821,7 @@ void OS_X11::set_window_minimized(bool p_enabled) {
xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
-
+
//XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", False);
@@ -831,7 +834,7 @@ void OS_X11::set_window_minimized(bool p_enabled) {
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
xev.xclient.data.l[1] = wm_hidden;
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
bool OS_X11::is_window_minimized() const {
@@ -860,14 +863,14 @@ bool OS_X11::is_window_minimized() const {
if( result == Success ) {
long *state = (long *) data;
- if( state[0] == WM_IconicState )
+ if( state[0] == WM_IconicState )
return true;
}
return false;
}
void OS_X11::set_window_maximized(bool p_enabled) {
- // Using EWMH -- Extended Window Manager Hints
+ // Using EWMH -- Extended Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
@@ -925,7 +928,7 @@ bool OS_X11::is_window_maximized() const {
&data
);
- if(result == Success) {
+ if(result == Success) {
Atom *atoms = (Atom*) data;
Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
@@ -949,65 +952,65 @@ bool OS_X11::is_window_maximized() const {
InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) {
-
+
InputModifierState state;
-
+
state.shift = (p_x11_state&ShiftMask);
state.control = (p_x11_state&ControlMask);
state.alt = (p_x11_state&Mod1Mask /*|| p_x11_state&Mod5Mask*/); //altgr should not count as alt
state.meta = (p_x11_state&Mod4Mask);
-
+
return state;
}
unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) {
unsigned int state=0;
-
+
if (p_x11_state&Button1Mask) {
-
+
state|=1<<0;
}
if (p_x11_state&Button3Mask) {
-
+
state|=1<<1;
}
if (p_x11_state&Button2Mask) {
-
+
state|=1<<2;
}
-
+
if (p_x11_state&Button4Mask) {
-
+
state|=1<<3;
}
if (p_x11_state&Button5Mask) {
-
+
state|=1<<4;
}
last_button_state=state;
return state;
}
-
+
void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
-
+
// X11 functions don't know what const is
XKeyEvent *xkeyevent = p_event;
-
+
// This code was pretty difficult to write.
// The docs stink and every toolkit seems to
- // do it in a different way.
-
+ // do it in a different way.
+
/* Phase 1, obtain a proper keysym */
-
+
// This was also very difficult to figure out.
// You'd expect you could just use Keysym provided by
- // XKeycodeToKeysym to obtain internationalized
- // input.. WRONG!!
+ // XKeycodeToKeysym to obtain internationalized
+ // input.. WRONG!!
// you must use XLookupString (???) which not only wastes
// cycles generating an unnecesary string, but also
// still works in half the cases. (won't handle deadkeys)
@@ -1016,57 +1019,57 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
// So.. then you have to chosse which of both results
// you want to keep.
// This is a real bizarreness and cpu waster.
-
+
KeySym keysym_keycode=0; // keysym used to find a keycode
KeySym keysym_unicode=0; // keysym used to find unicode
-
+
// XLookupString returns keysyms usable as nice scancodes/
char str[256+1];
XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL);
-
+
// Meanwhile, XLookupString returns keysyms useful for unicode.
-
-
+
+
if (!xmbstring) {
// keep a temporary buffer for the string
xmbstring=(char*)memalloc(sizeof(char)*8);
xmblen=8;
- }
-
+ }
+
if (xkeyevent->type == KeyPress && xic) {
Status status;
do {
-
+
int mnbytes = XmbLookupString (xic, xkeyevent, xmbstring, xmblen - 1, &keysym_unicode, &status);
xmbstring[mnbytes] = '\0';
if (status == XBufferOverflow) {
xmblen = mnbytes + 1;
xmbstring = (char*)memrealloc (xmbstring, xmblen);
- }
+ }
} while (status == XBufferOverflow);
- }
+ }
+
-
/* Phase 2, obtain a pigui keycode from the keysym */
-
+
// KeyMappingX11 just translated the X11 keysym to a PIGUI
// keysym, so it works in all platforms the same.
unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
-
+
/* Phase 3, obtain an unicode character from the keysym */
-
+
// KeyMappingX11 also translates keysym to unicode.
// It does a binary search on a table to translate
- // most properly.
+ // most properly.
//print_line("keysym_unicode: "+rtos(keysym_unicode));
unsigned int unicode = keysym_unicode>0? KeyMappingX11::get_unicode_from_keysym(keysym_unicode):0;
-
+
/* Phase 4, determine if event must be filtered */
-
+
// This seems to be a side-effect of using XIM.
// XEventFilter looks like a core X11 funciton,
// but it's actually just used to see if we must
@@ -1075,47 +1078,47 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
// Guess it was a design problem of the extension
bool keypress = xkeyevent->type == KeyPress;
-
+
if (xkeyevent->type == KeyPress && xic) {
if (XFilterEvent((XEvent*)xkeyevent, x11_window))
- return;
+ return;
}
-
+
if (keycode==0 && unicode==0)
return;
/* Phase 5, determine modifier mask */
-
+
// No problems here, except I had no way to
// know Mod1 was ALT and Mod4 was META (applekey/winkey)
// just tried Mods until i found them.
//print_line("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask));
-
+
InputModifierState state = get_key_modifier_state(xkeyevent->state);
-
+
/* Phase 6, determine echo character */
-
+
// Echo characters in X11 are a keyrelease and a keypress
// one after the other with the (almot) same timestamp.
// To detect them, i use XPeekEvent and check that their
// difference in time is below a treshold.
-
+
if (xkeyevent->type != KeyPress) {
-
+
// make sure there are events pending,
// so this call won't block.
if (XPending(x11_display)>0) {
XEvent peek_event;
XPeekEvent(x11_display, &peek_event);
-
- // I'm using a treshold of 5 msecs,
+
+ // I'm using a treshold of 5 msecs,
// since sometimes there seems to be a little
// jitter. I'm still not convinced that all this approach
// is correct, but the xorg developers are
// not very helpful today.
-
+
::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time);
if (peek_event.type == KeyPress && tresh<5 ) {
KeySym rk;
@@ -1127,16 +1130,16 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
return; //ignore current, echo next
}
}
-
+
// use the time from peek_event so it always works
}
-
- // save the time to check for echo when keypress happens
+
+ // save the time to check for echo when keypress happens
}
-
-
+
+
/* Phase 7, send event to Window */
-
+
InputEvent event;
event.ID=++event_id;
event.type = InputEvent::KEY;
@@ -1231,24 +1234,24 @@ void OS_X11::process_xevents() {
case ConfigureNotify:
/* call resizeGLScene only if our window-size changed */
-
- if ((event.xconfigure.width == current_videomode.width) &&
+
+ if ((event.xconfigure.width == current_videomode.width) &&
(event.xconfigure.height == current_videomode.height))
break;
-
+
current_videomode.width=event.xconfigure.width;
current_videomode.height=event.xconfigure.height;
break;
case ButtonPress:
case ButtonRelease: {
-
+
/* exit in case of a mouse button press */
last_timestamp=event.xbutton.time;
if (mouse_mode==MOUSE_MODE_CAPTURED) {
event.xbutton.x=last_mouse_pos.x;
event.xbutton.y=last_mouse_pos.y;
}
-
+
InputEvent mouse_event;
mouse_event.ID=++event_id;
mouse_event.type = InputEvent::MOUSE_BUTTON;
@@ -1264,31 +1267,31 @@ void OS_X11::process_xevents() {
mouse_event.mouse_button.button_index=3;
else if (mouse_event.mouse_button.button_index==3)
mouse_event.mouse_button.button_index=2;
-
+
mouse_event.mouse_button.pressed=(event.type==ButtonPress);
if (event.type==ButtonPress && event.xbutton.button==1) {
-
+
uint64_t diff = get_ticks_usec()/1000 - last_click_ms;
if (diff<400 && Point2(last_click_pos).distance_to(Point2(event.xbutton.x,event.xbutton.y))<5) {
-
+
last_click_ms=0;
last_click_pos = Point2(-100,-100);
- mouse_event.mouse_button.doubleclick=true;
+ mouse_event.mouse_button.doubleclick=true;
mouse_event.ID=++event_id;
-
+
} else {
- last_click_ms+=diff;
+ last_click_ms+=diff;
last_click_pos = Point2(event.xbutton.x,event.xbutton.y);
}
- }
+ }
input->parse_input_event( mouse_event);
-
- } break;
+
+ } break;
case MotionNotify: {
// FUCK YOU X11 API YOU SERIOUSLY GROSS ME OUT
@@ -1301,7 +1304,7 @@ void OS_X11::process_xevents() {
// PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL
// MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG.
-
+
while(true) {
if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) {
//this is likely the warp event since it was warped here
@@ -1323,7 +1326,7 @@ void OS_X11::process_xevents() {
}
last_timestamp=event.xmotion.time;
-
+
// Motion is also simple.
// A little hack is in order
// to be able to send relative motion events.
@@ -1356,13 +1359,13 @@ void OS_X11::process_xevents() {
0,0,0,0, (int)center.x, (int)center.y);
#endif
}
-
+
if (!last_mouse_pos_valid) {
-
+
last_mouse_pos=pos;
last_mouse_pos_valid=true;
}
-
+
Point2i rel = pos - last_mouse_pos;
#ifdef NEW_WM_API
@@ -1376,7 +1379,7 @@ void OS_X11::process_xevents() {
motion_event.ID=++event_id;
motion_event.type=InputEvent::MOUSE_MOTION;
motion_event.device=0;
-
+
motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state);
motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state);
motion_event.mouse_motion.x=pos.x;
@@ -1389,23 +1392,23 @@ void OS_X11::process_xevents() {
motion_event.mouse_motion.relative_x=rel.x;
motion_event.mouse_motion.relative_y=rel.y;
-
+
last_mouse_pos=pos;
// printf("rel: %d,%d\n", rel.x, rel.y );
-
+
input->parse_input_event( motion_event);
-
- } break;
- case KeyPress:
+
+ } break;
+ case KeyPress:
case KeyRelease: {
last_timestamp=event.xkey.time;
-
+
// key event is a little complex, so
// it will be handled in it's own function.
handle_key_event( (XKeyEvent*)&event );
- } break;
+ } break;
case SelectionRequest: {
XSelectionRequestEvent *req;
@@ -1452,8 +1455,8 @@ void OS_X11::process_xevents() {
} break;
- case ClientMessage:
-
+ case ClientMessage:
+
if ((unsigned int)event.xclient.data.l[0]==(unsigned int)wm_delete)
main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
break;
@@ -1461,7 +1464,7 @@ void OS_X11::process_xevents() {
break;
}
}
-
+
XFlush(x11_display);
if (do_mouse_warp) {
@@ -1469,7 +1472,7 @@ void OS_X11::process_xevents() {
XWarpPointer(x11_display, None, x11_window,
0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2);
- /*
+ /*
Window root, child;
int root_x, root_y;
int win_x, win_y;
@@ -1750,19 +1753,19 @@ void OS_X11::set_icon(const Image& p_icon) {
void OS_X11::run() {
force_quit = false;
-
+
if (!main_loop)
return;
-
+
main_loop->init();
-
+
// uint64_t last_ticks=get_ticks_usec();
-
+
// int frames=0;
// uint64_t frame=0;
-
+
while (!force_quit) {
-
+
process_xevents(); // get rid of pending events
#ifdef JOYDEV_ENABLED
event_id = joystick->process_joysticks(event_id);
@@ -1770,7 +1773,7 @@ void OS_X11::run() {
if (Main::iteration()==true)
break;
};
-
+
main_loop->finish();
}
@@ -1782,6 +1785,22 @@ String OS_X11::get_joy_guid(int p_device) const {
return input->get_joy_guid_remapped(p_device);
}
+void OS_X11::set_context(int p_context) {
+
+ XClassHint* classHint = NULL;
+ classHint = XAllocClassHint();
+ if (classHint) {
+
+ if (p_context == CONTEXT_EDITOR)
+ classHint->res_name = (char *)"Godot_Editor";
+ if (p_context == CONTEXT_PROJECTMAN)
+ classHint->res_name = (char *)"Godot_ProjectList";
+ classHint->res_class = (char *)"Godot";
+ XSetClassHint(x11_display, x11_window, classHint);
+ XFree(classHint);
+ }
+}
+
OS_X11::OS_X11() {
#ifdef RTAUDIO_ENABLED
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 91dbeac284..d9a5b1688c 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -78,7 +78,7 @@ class OS_X11 : public OS_Unix {
VideoMode current_videomode;
List<String> args;
Window x11_window;
- MainLoop *main_loop;
+ MainLoop *main_loop;
::Display* x11_display;
char *xmbstring;
int xmblen;
@@ -93,7 +93,7 @@ class OS_X11 : public OS_Unix {
uint64_t last_click_ms;
unsigned int event_id;
uint32_t last_button_state;
-
+
PhysicsServer *physics_server;
unsigned int get_mouse_button_state(unsigned int p_x11_state);
InputModifierState get_key_modifier_state(unsigned int p_x11_state);
@@ -101,7 +101,7 @@ class OS_X11 : public OS_Unix {
MouseMode mouse_mode;
Point2i center;
-
+
void handle_key_event(XKeyEvent *p_event,bool p_echo=false);
void process_xevents();
virtual void delete_main_loop();
@@ -154,16 +154,16 @@ class OS_X11 : public OS_Unix {
protected:
virtual int get_video_driver_count() const;
- virtual const char * get_video_driver_name(int p_driver) const;
+ virtual const char * get_video_driver_name(int p_driver) const;
virtual VideoMode get_default_video_mode() const;
virtual int get_audio_driver_count() const;
virtual const char * get_audio_driver_name(int p_driver) const;
- virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
+ virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
virtual void finalize();
- virtual void set_main_loop( MainLoop * p_main_loop );
+ virtual void set_main_loop( MainLoop * p_main_loop );
public:
@@ -183,7 +183,7 @@ public:
virtual void set_icon(const Image& p_icon);
virtual MainLoop *get_main_loop() const;
-
+
virtual bool can_draw() const;
virtual void set_clipboard(const String& p_text);
@@ -226,6 +226,8 @@ public:
virtual bool is_joy_known(int p_device);
virtual String get_joy_guid(int p_device) const;
+ virtual void set_context(int p_context);
+
void run();
OS_X11();
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 3c51bbf220..22e5bc382a 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -103,7 +103,7 @@ public:
bool is_v_drag_enabled() const;
void set_drag_margin(Margin p_margin,float p_drag_margin);
- float get_drag_margin(Margin p_margin) const;
+ float get_drag_margin(Margin p_margin) const;
void set_v_offset(float p_offset);
float get_v_offset() const;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 316097fbcf..483feea5c4 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -233,7 +233,7 @@ bool CanvasItem::is_visible() const {
const CanvasItem *p=this;
- while(p) {
+ while(p) {
if (p->hidden)
return false;
p=p->get_parent_item();
@@ -310,11 +310,11 @@ void CanvasItem::hide() {
}
void CanvasItem::set_hidden(bool p_hidden) {
-
+
if (hidden == p_hidden) {
return;
}
-
+
_set_visible_(!p_hidden);
}
@@ -1209,7 +1209,7 @@ CanvasItem::CanvasItem() : xform_change(this) {
pending_update=false;
opacity=1;
self_opacity=1;
- toplevel=false;
+ toplevel=false;
pending_children_sort=false;
first_draw=false;
blend_mode=BLEND_MODE_MIX;
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 3a45b0c84e..b5a6cc435f 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -261,7 +261,7 @@ void CollisionObject2D::add_shape(const Ref<Shape2D>& p_shape, const Matrix32& p
else
Physics2DServer::get_singleton()->body_add_shape(get_rid(),p_shape->get_rid(),p_transform);
- shapes.push_back(sdata);
+ shapes.push_back(sdata);
}
int CollisionObject2D::get_shape_count() const {
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 4c00d8cec9..376aeb2d85 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -429,8 +429,8 @@ void NavigationPolygonInstance::_navpoly_changed() {
void NavigationPolygonInstance::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("set_navigation_polygon","navpoly"),&NavigationPolygonInstance::set_navigation_polygon);
- ObjectTypeDB::bind_method(_MD("get_navigation_polygon"),&NavigationPolygonInstance::get_navigation_polygon);
+ ObjectTypeDB::bind_method(_MD("set_navigation_polygon","navpoly:NavigationPolygon"),&NavigationPolygonInstance::set_navigation_polygon);
+ ObjectTypeDB::bind_method(_MD("get_navigation_polygon:NavigationPolygon"),&NavigationPolygonInstance::get_navigation_polygon);
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&NavigationPolygonInstance::set_enabled);
ObjectTypeDB::bind_method(_MD("is_enabled"),&NavigationPolygonInstance::is_enabled);
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp
index 5b13c32d93..ffea060e82 100644
--- a/scene/2d/particles_2d.cpp
+++ b/scene/2d/particles_2d.cpp
@@ -504,7 +504,7 @@ void Particles2D::_notification(int p_what) {
invxform=get_global_transform().affine_inverse();
int start_particle = (int)(time * (float)particle_count / lifetime);
-
+
for (int id=0;id<particle_count;++id) {
int i = start_particle + id;
if (i >= particle_count) {
@@ -645,7 +645,7 @@ static const char* _particlesframe_property_rnames[Particles2D::PARAM_MAX]={
"randomness/gravity_strength",
"randomness/radial_accel",
"randomness/tangential_accel",
- "randomness/damping",
+ "randomness/damping",
"randomness/initial_angle",
"randomness/initial_size",
"randomness/final_size",
diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h
index 101395589e..06dcda7165 100644
--- a/scene/2d/particles_2d.h
+++ b/scene/2d/particles_2d.h
@@ -88,7 +88,7 @@ public:
enum Parameter {
PARAM_DIRECTION,
PARAM_SPREAD,
- PARAM_LINEAR_VELOCITY,
+ PARAM_LINEAR_VELOCITY,
PARAM_SPIN_VELOCITY,
PARAM_ORBIT_VELOCITY,
PARAM_GRAVITY_DIRECTION,
@@ -150,7 +150,7 @@ private:
Point2 emissor_offset;
Vector2 initial_velocity;
Vector2 extents;
- DVector<Vector2> emission_points;
+ DVector<Vector2> emission_points;
float time;
int active_count;
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index 001a1366a9..b2902b2867 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -188,13 +188,15 @@ bool Sprite::is_region() const{
void Sprite::set_region_rect(const Rect2& p_region_rect) {
- bool changed=region_rect!=p_region_rect;
+ if (region_rect==p_region_rect)
+ return;
+
region_rect=p_region_rect;
- if (region && changed) {
- update();
+
+ if (region)
item_rect_changed();
- _change_notify("region_rect");
- }
+
+ _change_notify("region_rect");
}
Rect2 Sprite::get_region_rect() const {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 179d1f451a..34a67c088f 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -450,15 +450,20 @@ void TileMap::_update_dirty_quadrants() {
_fix_cell_transform(xform,c,shape_ofs+center_ofs,s);
if (debug_canvas_item) {
+ vs->canvas_item_add_set_transform(debug_canvas_item,xform);
shape->draw(debug_canvas_item,debug_collision_color);
}
- ps->body_add_shape(q.body,shape->get_rid(),xform);
+ ps->body_add_shape(q.body,shape->get_rid(),xform);
ps->body_set_shape_metadata(q.body,shape_idx++,Vector2(E->key().x,E->key().y));
}
}
+ if (debug_canvas_item) {
+ vs->canvas_item_add_set_transform(debug_canvas_item,Matrix32());
+ }
+
if (navigation) {
Ref<NavigationPolygon> navpoly = tile_set->tile_get_navigation_polygon(c.id);
if (navpoly.is_valid()) {
@@ -694,6 +699,10 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bo
}
+int TileMap::get_cellv(const Vector2& p_pos) const {
+ return get_cell(p_pos.x,p_pos.y);
+}
+
int TileMap::get_cell(int p_x,int p_y) const {
PosKey pk(p_x,p_y);
@@ -1198,8 +1207,10 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_cellv","pos","tile","flip_x","flip_y","transpose"),&TileMap::set_cellv,DEFVAL(false),DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
+ ObjectTypeDB::bind_method(_MD("get_cellv","pos"),&TileMap::get_cellv);
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
+ ObjectTypeDB::bind_method(_MD("is_cell_transposed","x","y"),&TileMap::is_cell_transposed);
ObjectTypeDB::bind_method(_MD("clear"),&TileMap::clear);
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 14cb52b736..cec5ac0a1b 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -211,6 +211,7 @@ public:
bool is_cell_transposed(int p_x,int p_y) const;
void set_cellv(const Vector2& p_pos,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false);
+ int get_cellv(const Vector2& p_pos) const;
Rect2 get_item_rect() const;
diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp
index 1ae7866f0b..4487415030 100644
--- a/scene/3d/baked_light_instance.cpp
+++ b/scene/3d/baked_light_instance.cpp
@@ -13,7 +13,7 @@ RID BakedLightInstance::get_baked_light_instance() const {
void BakedLightInstance::set_baked_light(const Ref<BakedLight>& p_baked_light) {
- baked_light=p_baked_light;
+ baked_light=p_baked_light;
RID base_rid;
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 3e78fef147..e76c0938fb 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -56,8 +56,8 @@ void Camera::_update_camera_mode() {
} break;
case PROJECTION_ORTHOGONAL: {
set_orthogonal(size,near,far);
- } break;
-
+ } break;
+
}
}
@@ -81,7 +81,7 @@ bool Camera::_set(const StringName& p_name, const Variant& p_value) {
else if (p_name=="near")
near=p_value;
else if (p_name=="far")
- far=p_value;
+ far=p_value;
else if (p_name=="keep_aspect")
set_keep_aspect_mode(KeepAspect(int(p_value)));
else if (p_name=="vaspect")
@@ -102,7 +102,7 @@ bool Camera::_set(const StringName& p_name, const Variant& p_value) {
set_environment(p_value);
} else
return false;
-
+
_update_camera_mode();
if (changed_all)
_change_notify();
@@ -147,21 +147,21 @@ bool Camera::_get(const StringName& p_name,Variant &r_ret) const {
void Camera::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal") );
-
+
switch(mode) {
-
+
case PROJECTION_PERSPECTIVE: {
-
+
p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_NOEDITOR) );
if (keep_aspect==KEEP_WIDTH)
p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) );
else
p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) );
-
+
} break;
case PROJECTION_ORTHOGONAL: {
-
+
p_list->push_back( PropertyInfo( Variant::REAL, "size" , PROPERTY_HINT_RANGE, "1,16384,0.01",PROPERTY_USAGE_NOEDITOR ) );
if (keep_aspect==KEEP_WIDTH)
p_list->push_back( PropertyInfo( Variant::REAL, "sizex" , PROPERTY_HINT_RANGE, "0.1,16384,0.01",PROPERTY_USAGE_EDITOR) );
@@ -169,9 +169,9 @@ void Camera::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::REAL, "sizey" , PROPERTY_HINT_RANGE, "0.1,16384,0.01",PROPERTY_USAGE_EDITOR) );
} break;
-
+
}
-
+
p_list->push_back( PropertyInfo( Variant::REAL, "near" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
p_list->push_back( PropertyInfo( Variant::REAL, "far" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
p_list->push_back( PropertyInfo( Variant::INT, "keep_aspect",PROPERTY_HINT_ENUM,"Keep Width,Keep Height") );
@@ -209,23 +209,22 @@ void Camera::_update_camera() {
void Camera::_notification(int p_what) {
switch(p_what) {
-
+
case NOTIFICATION_ENTER_WORLD: {
- bool first_camera = get_viewport()->cameras.size()==0;
- get_viewport()->cameras.insert(this);
+ bool first_camera = get_viewport()->_camera_add(this);
if (!get_tree()->is_node_being_edited(this) && (current || first_camera))
make_current();
- } break;
+ } break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
+
_request_camera_update();
} break;
case NOTIFICATION_EXIT_WORLD: {
-
+
if (!get_tree()->is_node_being_edited(this)) {
if (is_current()) {
clear_current();
@@ -236,7 +235,7 @@ void Camera::_notification(int p_what) {
}
}
- get_viewport()->cameras.erase(this);
+ get_viewport()->_camera_remove(this);
} break;
@@ -251,7 +250,7 @@ void Camera::_notification(int p_what) {
}
} break;
-
+
}
}
@@ -271,7 +270,7 @@ void Camera::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far
near=p_z_near;
far=p_z_far;
mode=PROJECTION_PERSPECTIVE;
-
+
VisualServer::get_singleton()->camera_set_perspective(camera,fov,near,far);
update_gizmo();
force_change=false;
@@ -282,12 +281,12 @@ void Camera::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
return;
size = p_size;
-
+
near=p_z_near;
far=p_z_far;
mode=PROJECTION_ORTHOGONAL;
force_change=false;
-
+
VisualServer::get_singleton()->camera_set_orthogonal(camera,size,near,far);
update_gizmo();
}
@@ -304,7 +303,7 @@ void Camera::make_current() {
if (!is_inside_tree())
return;
- get_viewport()->_set_camera(this);
+ get_viewport()->_camera_set(this);
//get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this);
}
@@ -319,20 +318,8 @@ void Camera::clear_current() {
return;
if (get_viewport()->get_camera()==this) {
- get_viewport()->_set_camera(NULL);
- //a group is used beause this needs to be in order to be deterministic
-
- for (Set<Camera*>::Element *E=get_viewport()->cameras.front();E;E=E->next()) {
-
- if (this==E->get())
- continue;
- if (!E->get()->is_inside_tree())
- continue;
- if (get_viewport()->get_camera()!=NULL)
- return;
-
- E->get()->make_current();
- }
+ get_viewport()->_camera_set(NULL);
+ get_viewport()->_camera_make_next_current(this);
}
}
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index 02ca6ffb9a..30c6928245 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -41,7 +41,7 @@ class Camera : public Spatial {
OBJ_TYPE( Camera, Spatial );
public:
enum Projection {
-
+
PROJECTION_PERSPECTIVE,
PROJECTION_ORTHOGONAL
};
@@ -57,14 +57,14 @@ private:
bool current;
Projection mode;
-
+
float fov;
float size;
float near,far;
float v_offset;
float h_offset;
KeepAspect keep_aspect;
-
+
RID camera;
RID scenario_id;
@@ -86,14 +86,14 @@ protected:
void _update_camera();
virtual void _request_camera_update();
void _update_camera_mode();
-
+
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
void _notification(int p_what);
-
+
static void _bind_methods();
-
+
public:
enum {
@@ -104,7 +104,7 @@ public:
void set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far);
void set_orthogonal(float p_size, float p_z_near, float p_z_far);
-
+
void make_current();
void clear_current();
bool is_current() const;
@@ -145,7 +145,7 @@ public:
float get_h_offset() const;
- Camera();
+ Camera();
~Camera();
};
diff --git a/scene/3d/character_camera.cpp b/scene/3d/character_camera.cpp
index 2b22026fe9..fc3dfcd645 100644
--- a/scene/3d/character_camera.cpp
+++ b/scene/3d/character_camera.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "character_camera.h"
-
+
#include "physics_body.h"
#if 0
void CharacterCamera::_set(const String& p_name, const Variant& p_value) {
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 18463742c6..227bb3a59d 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "light.h"
-
+
#include "globals.h"
#include "scene/resources/surface_tool.h"
@@ -86,7 +86,7 @@ void Light::set_project_shadows(bool p_enabled) {
_change_notify("shadow");
}
bool Light::has_project_shadows() const {
-
+
return shadows;
}
@@ -175,9 +175,9 @@ RES Light::_get_gizmo_geometry() const {
Ref< Mesh > mesh;
Ref<SurfaceTool> surftool( memnew( SurfaceTool ));
-
+
switch(type) {
-
+
case VisualServer::LIGHT_DIRECTIONAL: {
@@ -260,9 +260,9 @@ RES Light::_get_gizmo_geometry() const {
surftool->set_material(mat_light);
mesh=surftool->commit(mesh);
} break;
-
+
case VisualServer::LIGHT_SPOT: {
-
+
_make_sphere( 5,5,0.1, surftool );
surftool->set_material(mat_light);
mesh=surftool->commit(mesh);
@@ -273,14 +273,14 @@ RES Light::_get_gizmo_geometry() const {
float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
-
+
for(int i = 0; i < points; i++) {
-
+
float x0=Math::sin(i * Math_PI * 2 / points);
float y0=Math::cos(i * Math_PI * 2 / points);
float x1=Math::sin((i+1) * Math_PI * 2 / points);
float y1=Math::cos((i+1) * Math_PI * 2 / points);
-
+
Vector3 v1=Vector3(x0*size,y0*size,-len).normalized()*len;
Vector3 v2=Vector3(x1*size,y1*size,-len).normalized()*len;
@@ -288,7 +288,7 @@ RES Light::_get_gizmo_geometry() const {
Vector3 v4=Vector3(0,0,v1.z);
Vector3 n = Plane(v1,v2,v3).normal;
-
+
surftool->add_normal(n);
surftool->add_vertex(v1);
@@ -306,7 +306,7 @@ RES Light::_get_gizmo_geometry() const {
surftool->add_normal(n);
surftool->add_vertex(v4);
-
+
}
surftool->set_material(mat_area);
@@ -323,15 +323,15 @@ RES Light::_get_gizmo_geometry() const {
AABB Light::get_aabb() const {
if (type==VisualServer::LIGHT_DIRECTIONAL) {
-
- return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
-
+
+ return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
+
} else if (type==VisualServer::LIGHT_OMNI) {
-
+
return AABB( Vector3(-1,-1,-1) * vars[PARAM_RADIUS], Vector3(2, 2, 2 ) * vars[PARAM_RADIUS]);
-
+
} else if (type==VisualServer::LIGHT_SPOT) {
-
+
float len=vars[PARAM_RADIUS];
float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) );
@@ -542,7 +542,7 @@ void Light::_bind_methods() {
BIND_CONSTANT( COLOR_DIFFUSE );
- BIND_CONSTANT( COLOR_SPECULAR );
+ BIND_CONSTANT( COLOR_SPECULAR );
BIND_CONSTANT( BAKE_MODE_DISABLED );
BIND_CONSTANT( BAKE_MODE_INDIRECT );
diff --git a/scene/3d/light.h b/scene/3d/light.h
index b74085b7a9..b25c6a44b5 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -43,7 +43,7 @@ class Light : public VisualInstance {
OBJ_CATEGORY("3D Light Nodes");
public:
-
+
enum Parameter {
PARAM_RADIUS=VisualServer::LIGHT_PARAM_RADIUS,
PARAM_ENERGY=VisualServer::LIGHT_PARAM_ENERGY,
@@ -57,10 +57,10 @@ public:
PARAM_SHADOW_BLUR_PASSES=VisualServer::LIGHT_PARAM_SHADOW_BLUR_PASSES,
PARAM_MAX=VisualServer::LIGHT_PARAM_MAX
};
-
-
+
+
enum LightColor {
-
+
COLOR_DIFFUSE=VisualServer::LIGHT_COLOR_DIFFUSE,
COLOR_SPECULAR=VisualServer::LIGHT_COLOR_SPECULAR
};
@@ -81,13 +81,13 @@ public:
OPERATOR_SUB
};
private:
-
-
+
+
Ref<Texture> projector;
float vars[PARAM_MAX];
Color colors[3];
-
-
+
+
BakeMode bake_mode;
VisualServer::LightType type;
bool shadows;
@@ -98,18 +98,18 @@ private:
void _update_visibility();
// bind helpers
-protected:
+protected:
RID light;
virtual bool _can_gizmo_scale() const;
virtual RES _get_gizmo_geometry() const;
-
+
static void _bind_methods();
void _notification(int p_what);
-
- Light(VisualServer::LightType p_type);
+
+ Light(VisualServer::LightType p_type);
public:
VS::LightType get_light_type() const { return type; }
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index 997d2dea7c..cfe273fa20 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -139,7 +139,7 @@ AABB MeshInstance::get_aabb() const {
if (!mesh.is_null())
return mesh->get_aabb();
-
+
return AABB();
}
@@ -150,7 +150,7 @@ DVector<Face3> MeshInstance::get_faces(uint32_t p_usage_flags) const {
if (mesh.is_null())
return DVector<Face3>();
-
+
return mesh->get_faces();
}
@@ -177,7 +177,7 @@ void MeshInstance::create_trimesh_collision() {
StaticBody* static_body = create_trimesh_collision_node()->cast_to<StaticBody>();
ERR_FAIL_COND(!static_body);
static_body->set_name( String(get_name()) + "_col" );
-
+
add_child(static_body);
if (get_owner())
static_body->set_owner( get_owner() );
@@ -233,7 +233,7 @@ void MeshInstance::_notification(int p_what) {
void MeshInstance::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("set_mesh","mesh:Mesh"),&MeshInstance::set_mesh);
ObjectTypeDB::bind_method(_MD("get_mesh:Mesh"),&MeshInstance::get_mesh);
ObjectTypeDB::bind_method(_MD("set_skeleton_path","skeleton_path:NodePath"),&MeshInstance::set_skeleton_path);
diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h
index f26ef52000..7c605c2d6d 100644
--- a/scene/3d/mesh_instance.h
+++ b/scene/3d/mesh_instance.h
@@ -38,7 +38,7 @@
class MeshInstance : public GeometryInstance {
OBJ_TYPE( MeshInstance, GeometryInstance );
-
+
Ref<Mesh> mesh;
NodePath skeleton_path;
@@ -68,7 +68,7 @@ public:
void set_skeleton_path(const NodePath& p_skeleton);
NodePath get_skeleton_path();
-
+
Node* create_trimesh_collision_node();
void create_trimesh_collision();
@@ -78,7 +78,7 @@ public:
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
- MeshInstance();
+ MeshInstance();
~MeshInstance();
};
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index ce28350be0..2b74d43ad2 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -64,7 +64,11 @@ void Navigation::_navmesh_link(int p_id) {
continue;
}
- p.center=center/plen;
+ p.center = center;
+ if( plen != 0 ) {
+ p.center /= plen;
+ }
+
//connect
@@ -455,7 +459,7 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3& p_start, const Vector
_clip_path(path,apex_poly,portal_right,right_poly);
- apex_point=portal_right;
+ apex_point=portal_right;
p=right_poly;
left_poly=p;
apex_poly=p;
@@ -721,5 +725,3 @@ Navigation::Navigation() {
last_id=1;
up=Vector3(0,1,0);
}
-
-
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index dfd5c38266..3ac5d8ed7b 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -95,15 +95,15 @@ DVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const {
void Particles::set_amount(int p_amount) {
- ERR_FAIL_INDEX(p_amount,4096);
+ ERR_FAIL_INDEX(p_amount,1024);
amount=p_amount;
VisualServer::get_singleton()->particles_set_amount(particles,p_amount);
}
int Particles::get_amount() const {
-
+
return amount;
}
-
+
void Particles::set_emitting(bool p_emitting) {
emitting=p_emitting;
@@ -115,19 +115,19 @@ bool Particles::is_emitting() const {
return emitting;
}
-
+
void Particles::set_visibility_aabb(const AABB& p_aabb) {
visibility_aabb=p_aabb;
VisualServer::get_singleton()->particles_set_visibility_aabb(particles,p_aabb);
update_gizmo();
-
+
}
AABB Particles::get_visibility_aabb() const {
return visibility_aabb;
}
-
+
void Particles::set_emission_points(const DVector<Vector3>& p_points) {
@@ -179,7 +179,7 @@ Vector3 Particles::get_gravity_normal() const {
return gravity_normal;
}
-
+
void Particles::set_variable(Variable p_variable,float p_value) {
ERR_FAIL_INDEX(p_variable,VAR_MAX);
@@ -273,7 +273,7 @@ float Particles::get_emit_timeout() const {
Ref<Material> Particles::get_material() const {
return material;
-}
+}
void Particles::set_height_from_velocity(bool p_enable) {
@@ -441,7 +441,7 @@ void Particles::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material" ), _SCS("set_material"), _SCS("get_material") );
- ADD_PROPERTY( PropertyInfo( Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,4096,1" ), _SCS("set_amount"), _SCS("get_amount") );
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1024,1" ), _SCS("set_amount"), _SCS("get_amount") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "emitting" ), _SCS("set_emitting"), _SCS("is_emitting") );
ADD_PROPERTY( PropertyInfo( Variant::_AABB, "visibility" ), _SCS("set_visibility_aabb"), _SCS("get_visibility_aabb") );
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "emission_extents" ), _SCS("set_emission_half_extents"), _SCS("get_emission_half_extents") );
@@ -507,11 +507,11 @@ Particles::Particles() {
set_amount(64);
set_emitting(true);
set_visibility_aabb(AABB( Vector3(-4,-4,-4), Vector3(8,8,8) ) );
-
+
for (int i=0;i<VAR_MAX;i++) {
set_randomness((Variable)i,0.0);
}
-
+
set_variable( VAR_LIFETIME, 5.0);
set_variable( VAR_SPREAD, 0.2);
set_variable( VAR_GRAVITY, 9.8);
@@ -523,7 +523,7 @@ Particles::Particles() {
set_variable( VAR_DAMPING, 0.0);
set_variable( VAR_INITIAL_SIZE, 1.0);
set_variable( VAR_FINAL_SIZE, 1.0);
- set_variable( VAR_INITIAL_ANGLE, 0.0);
+ set_variable( VAR_INITIAL_ANGLE, 0.0);
set_variable( VAR_HEIGHT, 1.0);
set_variable( VAR_HEIGHT_SPEED_SCALE, 0.0);
diff --git a/scene/3d/particles.h b/scene/3d/particles.h
index b9cae332e2..42d27c41d7 100644
--- a/scene/3d/particles.h
+++ b/scene/3d/particles.h
@@ -63,7 +63,7 @@ private:
OBJ_TYPE( Particles, GeometryInstance );
RID particles;
-
+
int amount;
bool emitting;
float emit_timeout;
@@ -71,14 +71,14 @@ private:
Vector3 gravity_normal;
Vector3 emission_half_extents;
bool using_points;
- float var[VAR_MAX];
- float var_random[VAR_MAX];
+ float var[VAR_MAX];
+ float var_random[VAR_MAX];
bool height_from_velocity;
Vector3 emission_base_velocity;
bool local_coordinates;
-
+
struct ColorPhase {
-
+
Color color;
float pos;
};
@@ -87,18 +87,18 @@ private:
virtual RES _get_gizmo_geometry() const;
int color_phase_count;
-
+
ColorPhase color_phase[4];
-
+
Ref<Material> material;
Timer* timer;
void setup_timer();
-protected:
-
+protected:
+
static void _bind_methods();
-
+
public:
@@ -107,13 +107,13 @@ public:
void set_amount(int p_amount);
int get_amount() const;
-
+
void set_emitting(bool p_emitting);
bool is_emitting() const;
-
+
void set_visibility_aabb(const AABB& p_aabb);
AABB get_visibility_aabb() const;
-
+
void set_emission_half_extents(const Vector3& p_half_extents);
Vector3 get_emission_half_extents() const;
@@ -125,25 +125,25 @@ public:
void set_gravity_normal(const Vector3& p_normal);
Vector3 get_gravity_normal() const;
-
+
void set_variable(Variable p_variable,float p_value);
float get_variable(Variable p_variable) const;
-
+
void set_randomness(Variable p_variable,float p_randomness);
float get_randomness(Variable p_variable) const;
void set_color_phases(int p_phases);
int get_color_phases() const;
-
+
void set_color_phase_pos(int p_phase, float p_pos);
float get_color_phase_pos(int p_phase) const;
-
+
void set_color_phase_color(int p_phase, const Color& p_color);
Color get_color_phase_color(int p_phase) const;
void set_height_from_velocity(bool p_enable);
bool has_height_from_velocity() const;
-
+
void set_material(const Ref<Material>& p_material);
Ref<Material> get_material() const;
@@ -156,7 +156,7 @@ public:
void start_emitting(float p_time);
- Particles();
+ Particles();
~Particles();
};
diff --git a/scene/3d/portal.cpp b/scene/3d/portal.cpp
index 84f94402d5..23bc64615d 100644
--- a/scene/3d/portal.cpp
+++ b/scene/3d/portal.cpp
@@ -40,7 +40,7 @@ bool Portal::_set(const StringName& p_name, const Variant& p_value) {
ERR_FAIL_COND_V(src_coords_size%2,false);
points.resize(src_coords_size/2);
for (int i=0;i<points.size();i++) {
-
+
points[i].x=src_coords[i*2+0];
points[i].y=src_coords[i*2+1];
set_shape(points);
@@ -65,13 +65,13 @@ bool Portal::_get(const StringName& p_name,Variant &r_ret) const {
Vector<Point2> points=get_shape();
DVector<float> dst_coords;
dst_coords.resize(points.size()*2);
-
+
for (int i=0;i<points.size();i++) {
-
+
dst_coords.set(i*2+0,points[i].x);
dst_coords.set(i*2+1,points[i].y);
}
-
+
r_ret= dst_coords;
} else if (p_name=="enabled") {
r_ret= is_enabled();
@@ -115,17 +115,17 @@ RES Portal::_get_gizmo_geometry() const {
Vector2 center;
for (int i=0;i<shape.size();i++) {
-
+
int n=(i+1)%shape.size();
Vector<Vector3> points;
surface_tool->add_vertex( Vector3( shape[i].x, shape[i].y,0 ));
surface_tool->add_vertex( Vector3( shape[n].x, shape[n].y,0 ));
center+=shape[i];
-
+
}
if (shape.size()>0) {
-
+
center/=shape.size();
Vector<Vector3> points;
surface_tool->add_vertex( Vector3( center.x, center.y,0 ));
@@ -139,7 +139,7 @@ RES Portal::_get_gizmo_geometry() const {
AABB Portal::get_aabb() const {
- return aabb;
+ return aabb;
}
DVector<Face3> Portal::get_faces(uint32_t p_usage_flags) const {
@@ -149,28 +149,28 @@ DVector<Face3> Portal::get_faces(uint32_t p_usage_flags) const {
Vector<Point2> shape = get_shape();
if (shape.size()==0)
return DVector<Face3>();
-
+
Vector2 center;
for (int i=0;i<shape.size();i++) {
-
+
center+=shape[i];
-
+
}
-
+
DVector<Face3> ret;
center/=shape.size();
for (int i=0;i<shape.size();i++) {
int n=(i+1)%shape.size();
-
+
Face3 f;
f.vertex[0]=Vector3( center.x, center.y, 0 );
f.vertex[1]=Vector3( shape[i].x, shape[i].y, 0 );
f.vertex[2]=Vector3( shape[n].x, shape[n].y, 0 );
ret.push_back(f);
}
-
+
return ret;
}
diff --git a/scene/3d/portal.h b/scene/3d/portal.h
index 388eac4dd3..149a56900f 100644
--- a/scene/3d/portal.h
+++ b/scene/3d/portal.h
@@ -45,14 +45,14 @@
class Portal : public VisualInstance {
OBJ_TYPE(Portal, VisualInstance);
-
+
RID portal;
-
+
bool enabled;
float disable_distance;
Color disabled_color;
float connect_range;
-
+
AABB aabb;
virtual RES _get_gizmo_geometry() const;
@@ -62,9 +62,9 @@ protected:
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
+
static void _bind_methods();
-
+
public:
virtual AABB get_aabb() const;
diff --git a/scene/3d/room_instance.cpp b/scene/3d/room_instance.cpp
index e358da136b..9e6867d2a2 100644
--- a/scene/3d/room_instance.cpp
+++ b/scene/3d/room_instance.cpp
@@ -29,7 +29,7 @@
#include "room_instance.h"
#include "servers/visual_server.h"
-
+
#include "geometry.h"
#include "globals.h"
#include "scene/resources/surface_tool.h"
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index 64133f67b5..d0b739e17f 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "skeleton.h"
-
+
#include "message_queue.h"
#include "scene/resources/surface_tool.h"
@@ -40,19 +40,19 @@ bool Skeleton::_set(const StringName& p_path, const Variant& p_value) {
if (!path.begins_with("bones/"))
return false;
-
+
int which=path.get_slicec('/',1).to_int();
String what=path.get_slicec('/',2);
if (which==bones.size() && what=="name") {
-
+
add_bone(p_value);
return true;
}
-
+
ERR_FAIL_INDEX_V( which, bones.size(), false );
-
+
if (what=="parent")
set_bone_parent(which, p_value );
else if (what=="rest")
@@ -63,11 +63,11 @@ bool Skeleton::_set(const StringName& p_path, const Variant& p_value) {
set_bone_pose(which, p_value);
else if (what=="bound_childs") {
Array children=p_value;
-
+
bones[which].nodes_bound.clear();
-
+
for (int i=0;i<children.size();i++) {
-
+
NodePath path=children[i];
ERR_CONTINUE( path.operator String()=="" );
Node *node = get_node(path);
@@ -87,12 +87,12 @@ bool Skeleton::_get(const StringName& p_name,Variant &r_ret) const {
if (!path.begins_with("bones/"))
return false;
-
+
int which=path.get_slicec('/',1).to_int();
String what=path.get_slicec('/',2);
-
+
ERR_FAIL_INDEX_V( which, bones.size(), false );
-
+
if (what=="name")
r_ret=get_bone_name(which);
else if (what=="parent")
@@ -105,29 +105,29 @@ bool Skeleton::_get(const StringName& p_name,Variant &r_ret) const {
r_ret=get_bone_pose(which);
else if (what=="bound_childs") {
Array children;
-
+
for (const List<uint32_t>::Element *E=bones[which].nodes_bound.front();E;E=E->next()) {
-
+
Object *obj=ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
Node *node=obj->cast_to<Node>();
ERR_CONTINUE(!node);
NodePath path=get_path_to(node);
children.push_back(path);
-
+
}
-
+
r_ret=children;
} else
return false;
-
+
return true;
}
void Skeleton::_get_property_list( List<PropertyInfo>* p_list ) const {
for (int i=0;i<bones.size();i++) {
-
+
String prep="bones/"+itos(i)+"/";
p_list->push_back( PropertyInfo( Variant::STRING, prep+"name" ) );
p_list->push_back( PropertyInfo( Variant::INT, prep+"parent" , PROPERTY_HINT_RANGE,"-1,"+itos(i-1)+",1") );
@@ -141,18 +141,18 @@ void Skeleton::_get_property_list( List<PropertyInfo>* p_list ) const {
void Skeleton::_notification(int p_what) {
switch(p_what) {
-
+
case NOTIFICATION_ENTER_WORLD: {
-
+
if (dirty) {
-
+
dirty=false;
_make_dirty(); // property make it dirty
}
-
+
} break;
case NOTIFICATION_EXIT_WORLD: {
-
+
} break;
case NOTIFICATION_UPDATE_SKELETON: {
@@ -178,15 +178,15 @@ void Skeleton::_notification(int p_what) {
Bone &b=bonesptr[i];
b.rest_global_inverse.affine_invert();
}
-
+
rest_global_inverse_dirty=false;
}
-
+
for (int i=0;i<len;i++) {
-
+
Bone &b=bonesptr[i];
-
+
if (b.disable_rest) {
if (b.enabled) {
@@ -241,7 +241,7 @@ void Skeleton::_notification(int p_what) {
}
}
}
-
+
vs->skeleton_bone_set_transform( skeleton, i, b.pose_global * b.rest_global_inverse );
for(List<uint32_t>::Element *E=b.nodes_bound.front();E;E=E->next()) {
@@ -255,7 +255,7 @@ void Skeleton::_notification(int p_what) {
}
dirty=false;
- } break;
+ } break;
}
}
@@ -298,16 +298,16 @@ RID Skeleton::get_skeleton() const {
void Skeleton::add_bone(const String& p_name) {
ERR_FAIL_COND( p_name=="" || p_name.find(":")!=-1 || p_name.find("/")!=-1 );
-
+
for (int i=0;i<bones.size();i++) {
-
+
ERR_FAIL_COND( bones[i].name=="p_name");
}
Bone b;
b.name=p_name;
bones.push_back(b);
-
+
rest_global_inverse_dirty=true;
_make_dirty();
update_gizmo();
@@ -315,11 +315,11 @@ void Skeleton::add_bone(const String& p_name) {
int Skeleton::find_bone(String p_name) const {
for (int i=0;i<bones.size();i++) {
-
+
if (bones[i].name==p_name)
return i;
}
-
+
return -1;
}
String Skeleton::get_bone_name(int p_bone) const {
@@ -338,7 +338,7 @@ void Skeleton::set_bone_parent(int p_bone, int p_parent) {
ERR_FAIL_INDEX( p_bone, bones.size() );
ERR_FAIL_COND( p_parent!=-1 && (p_parent<0 || p_parent>=p_bone));
-
+
bones[p_bone].parent=p_parent;
rest_global_inverse_dirty=true;
_make_dirty();
@@ -378,14 +378,14 @@ bool Skeleton::is_bone_rest_disabled(int p_bone) const {
int Skeleton::get_bone_parent(int p_bone) const {
ERR_FAIL_INDEX_V( p_bone, bones.size(), -1 );
-
+
return bones[p_bone].parent;
}
void Skeleton::set_bone_rest(int p_bone, const Transform& p_rest) {
ERR_FAIL_INDEX( p_bone, bones.size() );
-
+
bones[p_bone].rest=p_rest;
rest_global_inverse_dirty=true;
_make_dirty();
@@ -394,7 +394,7 @@ void Skeleton::set_bone_rest(int p_bone, const Transform& p_rest) {
Transform Skeleton::get_bone_rest(int p_bone) const {
ERR_FAIL_INDEX_V( p_bone, bones.size(), Transform() );
-
+
return bones[p_bone].rest;
}
@@ -402,7 +402,7 @@ Transform Skeleton::get_bone_rest(int p_bone) const {
void Skeleton::set_bone_enabled(int p_bone, bool p_enabled) {
ERR_FAIL_INDEX( p_bone, bones.size() );
-
+
bones[p_bone].enabled=p_enabled;
rest_global_inverse_dirty=true;
_make_dirty();
@@ -418,23 +418,23 @@ void Skeleton::bind_child_node_to_bone(int p_bone,Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX( p_bone, bones.size() );
-
+
uint32_t id=p_node->get_instance_ID();
-
+
for (List<uint32_t>::Element *E=bones[p_bone].nodes_bound.front();E;E=E->next()) {
-
+
if (E->get()==id)
return; // already here
}
-
+
bones[p_bone].nodes_bound.push_back(id);
-
+
}
void Skeleton::unbind_child_node_from_bone(int p_bone,Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX( p_bone, bones.size() );
-
+
uint32_t id=p_node->get_instance_ID();
bones[p_bone].nodes_bound.erase(id);
@@ -442,9 +442,9 @@ void Skeleton::unbind_child_node_from_bone(int p_bone,Node *p_node) {
void Skeleton::get_bound_child_nodes_to_bone(int p_bone,List<Node*> *p_bound) const {
ERR_FAIL_INDEX( p_bone, bones.size() );
-
+
for (const List<uint32_t>::Element *E=bones[p_bone].nodes_bound.front();E;E=E->next()) {
-
+
Object *obj=ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
p_bound->push_back(obj->cast_to<Node>());
@@ -465,7 +465,7 @@ void Skeleton::set_bone_pose(int p_bone, const Transform& p_pose) {
ERR_FAIL_INDEX( p_bone, bones.size() );
ERR_FAIL_COND( !is_inside_tree() );
-
+
bones[p_bone].pose=p_pose;
_make_dirty();
@@ -501,7 +501,7 @@ void Skeleton::_make_dirty() {
if (dirty)
return;
-
+
if (!is_inside_tree()) {
dirty=true;
return;
@@ -538,13 +538,13 @@ RES Skeleton::_get_gizmo_geometry() const {
int len=bones.size();
for (int i=0;i<len;i++) {
-
+
const Bone &b=bonesptr[i];
-
+
Transform t;
if (b.parent<0)
continue;
-
+
Vector3 v1=(bonesptr[b.parent].pose_global * bonesptr[b.parent].rest_global_inverse).xform(bonesptr[b.parent].rest_global_inverse.affine_inverse().origin);
Vector3 v2=(b.pose_global * b.rest_global_inverse).xform(b.rest_global_inverse.affine_inverse().origin);
@@ -576,10 +576,10 @@ void Skeleton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_bone","name"),&Skeleton::add_bone);
ObjectTypeDB::bind_method(_MD("find_bone","name"),&Skeleton::find_bone);
ObjectTypeDB::bind_method(_MD("get_bone_name","bone_idx"),&Skeleton::get_bone_name);
-
+
ObjectTypeDB::bind_method(_MD("get_bone_parent","bone_idx"),&Skeleton::get_bone_parent);
ObjectTypeDB::bind_method(_MD("set_bone_parent","bone_idx","parent_idx"),&Skeleton::set_bone_parent);
-
+
ObjectTypeDB::bind_method(_MD("get_bone_count"),&Skeleton::get_bone_count);
ObjectTypeDB::bind_method(_MD("unparent_bone_and_rest","bone_idx"),&Skeleton::unparent_bone_and_rest);
@@ -593,9 +593,9 @@ void Skeleton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("bind_child_node_to_bone","bone_idx","node:Node"),&Skeleton::bind_child_node_to_bone);
ObjectTypeDB::bind_method(_MD("unbind_child_node_from_bone","bone_idx","node:Node"),&Skeleton::unbind_child_node_from_bone);
ObjectTypeDB::bind_method(_MD("get_bound_child_nodes_to_bone","bone_idx"),&Skeleton::_get_bound_child_nodes_to_bone);
-
+
ObjectTypeDB::bind_method(_MD("clear_bones"),&Skeleton::clear_bones);
-
+
ObjectTypeDB::bind_method(_MD("get_bone_pose","bone_idx"),&Skeleton::get_bone_pose);
ObjectTypeDB::bind_method(_MD("set_bone_pose","bone_idx","pose"),&Skeleton::set_bone_pose);
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 033f212a58..bfdb1d1499 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -49,36 +49,36 @@ class Skeleton : public Spatial {
bool disable_rest;
Transform rest;
Transform rest_global_inverse;
-
+
Transform pose;
Transform pose_global;
bool custom_pose_enable;
Transform custom_pose;
-
+
List<uint32_t> nodes_bound;
-
+
Bone() { parent=-1; enabled=true; custom_pose_enable=false; disable_rest=false; }
};
bool rest_global_inverse_dirty;
Vector<Bone> bones;
-
+
RID skeleton;
-
+
void _make_dirty();
bool dirty;
-
+
//bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
-
+
Array bound;
List<Node*> childs;
get_bound_child_nodes_to_bone(p_bone,&childs);
-
+
for (int i=0;i<childs.size();i++) {
-
+
bound.push_back( childs[i] );
}
return bound;
@@ -93,11 +93,11 @@ protected:
void _get_property_list( List<PropertyInfo>* p_list ) const;
void _notification(int p_what);
static void _bind_methods();
-
+
public:
enum {
-
+
NOTIFICATION_UPDATE_SKELETON=50
};
@@ -108,7 +108,7 @@ public:
void add_bone(const String&p_name);
int find_bone(String p_name) const;
String get_bone_name(int p_bone) const;
-
+
void set_bone_parent(int p_bone, int p_parent);
int get_bone_parent(int p_bone) const;
@@ -118,7 +118,7 @@ public:
bool is_bone_rest_disabled(int p_bone) const;
int get_bone_count() const;
-
+
void set_bone_rest(int p_bone, const Transform& p_rest);
Transform get_bone_rest(int p_bone) const;
Transform get_bone_transform(int p_bone) const;
@@ -128,15 +128,15 @@ public:
void set_bone_enabled(int p_bone, bool p_enabled);
bool is_bone_enabled(int p_bone) const;
-
+
void bind_child_node_to_bone(int p_bone,Node *p_node);
void unbind_child_node_from_bone(int p_bone,Node *p_node);
void get_bound_child_nodes_to_bone(int p_bone,List<Node*> *p_bound) const;
-
+
void clear_bones();
-
+
// posing api
-
+
void set_bone_pose(int p_bone, const Transform& p_pose);
Transform get_bone_pose(int p_bone) const;
@@ -144,8 +144,8 @@ public:
Transform get_bone_custom_pose(int p_bone) const;
void localize_rests(); // used for loaders and tools
-
- Skeleton();
+
+ Skeleton();
~Skeleton();
};
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 0c1e1e2d1c..c2d318e8a7 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "spatial.h"
-
+
#include "scene/main/viewport.h"
#include "message_queue.h"
#include "scene/scene_string_names.h"
@@ -99,14 +99,14 @@ void Spatial::_propagate_transform_changed(Spatial *p_origin) {
// return; //already dirty
data.children_lock++;
-
+
for (List<Spatial*>::Element *E=data.children.front();E;E=E->next()) {
-
+
if (E->get()->data.toplevel_active)
continue; //don't propagate to a toplevel
E->get()->_propagate_transform_changed(p_origin);
}
-
+
if (!data.ignore_notification && !xform_change.in_list()) {
@@ -211,14 +211,14 @@ void Spatial::_notification(int p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: {
-
+
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
data.gizmo->transform();
}
#endif
} break;
-
+
default: {}
}
}
@@ -257,7 +257,7 @@ Transform Spatial::get_transform() const {
_update_local_transform();
}
-
+
return data.local_transform;
}
Transform Spatial::get_global_transform() const {
@@ -272,16 +272,16 @@ Transform Spatial::get_global_transform() const {
}
if (data.parent && !data.toplevel_active) {
-
+
data.global_transform=data.parent->get_global_transform() * data.local_transform;
} else {
-
+
data.global_transform=data.local_transform;
}
-
+
data.dirty&=~DIRTY_GLOBAL;
}
-
+
return data.global_transform;
}
#if 0
@@ -290,7 +290,7 @@ void Spatial::add_child_notify(Node *p_child) {
Spatial *s=p_child->cast_to<Spatial>();
if (!s)
return;
-
+
ERR_FAIL_COND(data.children_lock>0);
s->data.dirty=DIRTY_GLOBAL; // don't allow global transform to be valid
@@ -305,12 +305,12 @@ void Spatial::remove_child_notify(Node *p_child) {
Spatial *s=p_child->cast_to<Spatial>();
if (!s)
return;
-
+
ERR_FAIL_COND(data.children_lock>0);
-
+
if (s->data.C)
data.children.erase(s->data.C);
- s->data.parent=NULL;
+ s->data.parent=NULL;
s->data.C=NULL;
*/
}
@@ -595,11 +595,11 @@ bool Spatial::is_hidden() const{
}
void Spatial::set_hidden(bool p_hidden) {
-
+
if (data.visible != p_hidden) {
return;
}
-
+
_set_visible_(!p_hidden);
}
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index 23f1c6d103..50123b2d81 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -57,7 +57,7 @@ class Spatial : public Node {
OBJ_TYPE( Spatial, Node );
OBJ_CATEGORY("3D");
-
+
enum TransformDirty {
DIRTY_NONE=0,
DIRTY_VECTORS=1,
@@ -68,7 +68,7 @@ class Spatial : public Node {
mutable SelfList<Node> xform_change;
struct Data {
-
+
mutable Transform global_transform;
@@ -84,12 +84,12 @@ class Spatial : public Node {
bool toplevel_active;
bool toplevel;
bool inside_world;
-
+
int children_lock;
Spatial *parent;
List<Spatial*> children;
List<Spatial*>::Element *C;
-
+
bool ignore_notification;
bool notify_local_transform;
@@ -130,7 +130,7 @@ protected:
public:
enum {
-
+
NOTIFICATION_TRANSFORM_CHANGED=SceneTree::NOTIFICATION_TRANSFORM_CHANGED,
NOTIFICATION_ENTER_WORLD=41,
NOTIFICATION_EXIT_WORLD=42,
@@ -153,7 +153,7 @@ public:
void set_transform(const Transform& p_transform);
void set_global_transform(const Transform& p_transform);
-
+
Transform get_transform() const;
Transform get_global_transform() const;
@@ -198,7 +198,7 @@ public:
Transform get_import_transform() const;
#endif
- Spatial();
+ Spatial();
~Spatial();
};
diff --git a/scene/3d/spatial_sample_player.h b/scene/3d/spatial_sample_player.h
index 9b3220458e..037cdc906a 100644
--- a/scene/3d/spatial_sample_player.h
+++ b/scene/3d/spatial_sample_player.h
@@ -47,7 +47,7 @@ public:
typedef int VoiceID;
-private:
+private:
Ref<SampleLibrary> library;
int polyphony;
diff --git a/scene/3d/test_cube.h b/scene/3d/test_cube.h
index 21f2b3c794..332276ab89 100644
--- a/scene/3d/test_cube.h
+++ b/scene/3d/test_cube.h
@@ -42,14 +42,14 @@ class TestCube : public GeometryInstance {
OBJ_TYPE( TestCube, GeometryInstance );
RID instance;
-
+
public:
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
- TestCube();
+ TestCube();
~TestCube();
};
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 723b0a9af5..b15226cce3 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -267,6 +267,15 @@ void GeometryInstance::_update_visibility() {
void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
ERR_FAIL_INDEX(p_flag,FLAG_MAX);
+ if (p_flag==FLAG_CAST_SHADOW) {
+ if (p_value == true) {
+ set_cast_shadows_setting(SHADOW_CASTING_SETTING_ON);
+ }
+ else {
+ set_cast_shadows_setting(SHADOW_CASTING_SETTING_OFF);
+ }
+ }
+
if (flags[p_flag]==p_value)
return;
@@ -294,10 +303,32 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
bool GeometryInstance::get_flag(Flags p_flag) const{
ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
+
+ if (p_flag == FLAG_CAST_SHADOW) {
+ if (shadow_casting_setting == SHADOW_CASTING_SETTING_OFF) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+
return flags[p_flag];
}
+void GeometryInstance::set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting) {
+
+ shadow_casting_setting = p_shadow_casting_setting;
+
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(get_instance(), (VS::ShadowCastingSetting)p_shadow_casting_setting);
+}
+
+GeometryInstance::ShadowCastingSetting GeometryInstance::get_cast_shadows_setting() const {
+
+ return shadow_casting_setting;
+}
+
void GeometryInstance::set_baked_light_texture_id(int p_id) {
baked_light_texture_id=p_id;
@@ -330,6 +361,9 @@ void GeometryInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_flag","flag","value"), &GeometryInstance::set_flag);
ObjectTypeDB::bind_method(_MD("get_flag","flag"), &GeometryInstance::get_flag);
+ ObjectTypeDB::bind_method(_MD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance::set_cast_shadows_setting);
+ ObjectTypeDB::bind_method(_MD("get_cast_shadows_setting"), &GeometryInstance::get_cast_shadows_setting);
+
ObjectTypeDB::bind_method(_MD("set_draw_range_begin","mode"), &GeometryInstance::set_draw_range_begin);
ObjectTypeDB::bind_method(_MD("get_draw_range_begin"), &GeometryInstance::get_draw_range_begin);
@@ -346,7 +380,7 @@ void GeometryInstance::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "geometry/material_override",PROPERTY_HINT_RESOURCE_TYPE,"Material"), _SCS("set_material_override"), _SCS("get_material_override"));
- ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/cast_shadow"), _SCS("set_flag"), _SCS("get_flag"),FLAG_CAST_SHADOW);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), _SCS("set_cast_shadows_setting"), _SCS("get_cast_shadows_setting"));
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS);
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end"));
@@ -369,6 +403,11 @@ void GeometryInstance::_bind_methods() {
BIND_CONSTANT(FLAG_VISIBLE_IN_ALL_ROOMS );
BIND_CONSTANT(FLAG_MAX );
+ BIND_CONSTANT(SHADOW_CASTING_SETTING_OFF);
+ BIND_CONSTANT(SHADOW_CASTING_SETTING_ON);
+ BIND_CONSTANT(SHADOW_CASTING_SETTING_DOUBLE_SIDED);
+ BIND_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY);
+
}
GeometryInstance::GeometryInstance() {
@@ -381,6 +420,7 @@ GeometryInstance::GeometryInstance() {
flags[FLAG_VISIBLE]=true;
flags[FLAG_CAST_SHADOW]=true;
flags[FLAG_RECEIVE_SHADOWS]=true;
+ shadow_casting_setting=SHADOW_CASTING_SETTING_ON;
baked_light_instance=NULL;
baked_light_texture_id=0;
extra_cull_margin=0;
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index e49f4fb82f..e286d5fa88 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -65,7 +65,7 @@ public:
RID get_instance() const;
virtual AABB get_aabb() const=0;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const=0;
-
+
virtual AABB get_transformed_aabb() const; // helper
void set_base(const RID& p_base);
@@ -74,7 +74,7 @@ public:
uint32_t get_layer_mask() const;
- VisualInstance();
+ VisualInstance();
~VisualInstance();
};
@@ -98,10 +98,17 @@ public:
FLAG_MAX=VS::INSTANCE_FLAG_MAX,
};
+ enum ShadowCastingSetting {
+ SHADOW_CASTING_SETTING_OFF=VS::SHADOW_CASTING_SETTING_OFF,
+ SHADOW_CASTING_SETTING_ON = VS::SHADOW_CASTING_SETTING_ON,
+ SHADOW_CASTING_SETTING_DOUBLE_SIDED=VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED,
+ SHADOW_CASTING_SETTING_SHADOWS_ONLY=VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY
+ };
private:
bool flags[FLAG_MAX];
+ ShadowCastingSetting shadow_casting_setting;
Ref<Material> material_override;
float draw_begin;
float draw_end;
@@ -121,6 +128,9 @@ public:
void set_flag(Flags p_flag,bool p_value);
bool get_flag(Flags p_flag) const;
+ void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting);
+ ShadowCastingSetting get_cast_shadows_setting() const;
+
void set_draw_range_begin(float p_dist);
float get_draw_range_begin() const;
@@ -140,5 +150,7 @@ public:
};
VARIANT_ENUM_CAST( GeometryInstance::Flags );
+VARIANT_ENUM_CAST( GeometryInstance::ShadowCastingSetting );
+
#endif
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index f6d058c2fd..32958112e5 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "animation_player.h"
-
+
#include "message_queue.h"
#include "scene/scene_string_names.h"
@@ -50,10 +50,10 @@ bool AnimationPlayer::_set(const StringName& p_name, const Variant& p_value) {
else
play(which);
} else if (name.begins_with("anims/")) {
-
+
String which=name.get_slicec('/',1);
-
+
add_animation(which,p_value);
} else if (name.begins_with("next/")) {
@@ -62,7 +62,7 @@ bool AnimationPlayer::_set(const StringName& p_name, const Variant& p_value) {
animation_set_next(which,p_value);
} else if (p_name==SceneStringNames::get_singleton()->blend_times) {
-
+
Array array=p_value;
int len = array.size();
ERR_FAIL_COND_V(len%3,false);
@@ -79,7 +79,7 @@ bool AnimationPlayer::_set(const StringName& p_name, const Variant& p_value) {
} else if (p_name==SceneStringNames::get_singleton()->autoplay) {
autoplay=p_value;
-
+
} else
return false;
@@ -92,7 +92,7 @@ bool AnimationPlayer::_get(const StringName& p_name,Variant &r_ret) const {
String name=p_name;
if (name=="playback/speed") { //bw compatibility
-
+
r_ret=speed_scale;
} else if (name=="playback/active") {
@@ -105,9 +105,9 @@ bool AnimationPlayer::_get(const StringName& p_name,Variant &r_ret) const {
r_ret="[stop]";
} else if (name.begins_with("anims/")) {
-
+
String which=name.get_slicec('/',1);
-
+
r_ret= get_animation(which).get_ref_ptr();
} else if (name.begins_with("next/")) {
@@ -117,7 +117,7 @@ bool AnimationPlayer::_get(const StringName& p_name,Variant &r_ret) const {
} else if (name=="blend_times") {
-
+
Array array;
array.resize(blend_times.size()*3);
@@ -147,14 +147,21 @@ void AnimationPlayer::_get_property_list( List<PropertyInfo> *p_list) const {
List<String> names;
+ List<PropertyInfo> anim_names;
+
for( Map<StringName, AnimationData>::Element *E=animation_set.front();E;E=E->next()) {
- p_list->push_back( PropertyInfo( Variant::OBJECT, "anims/"+String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation",PROPERTY_USAGE_NOEDITOR) );
+ anim_names.push_back( PropertyInfo( Variant::OBJECT, "anims/"+String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation",PROPERTY_USAGE_NOEDITOR) );
if (E->get().next!=StringName())
- p_list->push_back( PropertyInfo( Variant::STRING, "next/"+String(E->key()), PROPERTY_HINT_NONE, "",PROPERTY_USAGE_NOEDITOR) );
+ anim_names.push_back( PropertyInfo( Variant::STRING, "next/"+String(E->key()), PROPERTY_HINT_NONE, "",PROPERTY_USAGE_NOEDITOR) );
names.push_back(E->key());
}
+ anim_names.sort();
+
+ for( List<PropertyInfo>::Element *E=anim_names.front();E;E=E->next()) {
+ p_list->push_back(E->get());
+ }
{
names.sort();
@@ -188,7 +195,7 @@ void AnimationPlayer::advance(float p_time) {
void AnimationPlayer::_notification(int p_what) {
switch(p_what) {
-
+
case NOTIFICATION_ENTER_TREE: {
if (!processing) {
@@ -204,6 +211,7 @@ void AnimationPlayer::_notification(int p_what) {
if (!get_tree()->is_editor_hint() && animation_set.has(autoplay)) {
play(autoplay);
+ set_autoplay(""); //this line is the fix for autoplay issues with animatio
}
} break;
case NOTIFICATION_PROCESS: {
@@ -214,7 +222,7 @@ void AnimationPlayer::_notification(int p_what) {
_animation_process( get_process_delta_time() );
} break;
case NOTIFICATION_FIXED_PROCESS: {
-
+
if (animation_process_mode==ANIMATION_PROCESS_IDLE)
break;
@@ -222,7 +230,7 @@ void AnimationPlayer::_notification(int p_what) {
_animation_process( get_fixed_process_delta_time() );
} break;
case NOTIFICATION_EXIT_TREE: {
-
+
//stop_all();
clear_caches();
} break;
@@ -232,15 +240,15 @@ void AnimationPlayer::_notification(int p_what) {
void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
Node *parent = get_node(root);
-
+
ERR_FAIL_COND(!parent);
Animation *a=p_anim->animation.operator->();
-
+
p_anim->node_cache.resize( a->get_track_count() );
-
+
for (int i=0;i<a->get_track_count();i++) {
-
+
p_anim->node_cache[i]=NULL;
RES resource;
Node *child = parent->get_node_and_resource(a->track_get_path(i),resource);
@@ -259,7 +267,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
continue;
}
}
-
+
{
if (!child->is_connected("exit_tree",this,"_node_removed"))
child->connect("exit_tree",this,"_node_removed",make_binds(child),CONNECT_ONESHOT);
@@ -269,15 +277,15 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
key.id=id;
key.bone_idx=bone_idx;
-
+
if (node_cache_map.has(key)) {
-
+
p_anim->node_cache[i]=&node_cache_map[key];
} else {
-
+
node_cache_map[key]=TrackNodeCache();
-
+
p_anim->node_cache[i]=&node_cache_map[key];
p_anim->node_cache[i]->path=a->track_get_path(i);
p_anim->node_cache[i]->node=child;
@@ -285,7 +293,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
p_anim->node_cache[i]->node_2d=child->cast_to<Node2D>();
if (a->track_get_type(i)==Animation::TYPE_TRANSFORM) {
// special cases and caches for transform tracks
-
+
// cache spatial
p_anim->node_cache[i]->spatial=child->cast_to<Spatial>();
// cache skeleton
@@ -294,7 +302,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
StringName bone_name=a->track_get_path(i).get_property();
if (bone_name.operator String()!="") {
-
+
p_anim->node_cache[i]->bone_idx=p_anim->node_cache[i]->skeleton->find_bone(bone_name);
if (p_anim->node_cache[i]->bone_idx<0) {
// broken track (nonexistent bone)
@@ -306,9 +314,9 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
}
} else {
// no property, just use spatialnode
- p_anim->node_cache[i]->skeleton=NULL;
+ p_anim->node_cache[i]->skeleton=NULL;
}
-
+
}
}
}
@@ -348,29 +356,29 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
ERR_FAIL_COND( p_anim->node_cache.size() != p_anim->animation->get_track_count() );
-
+
Animation *a=p_anim->animation.operator->();
bool can_call = is_inside_tree() && !get_tree()->is_editor_hint();
-
+
for (int i=0;i<a->get_track_count();i++) {
-
+
TrackNodeCache *nc=p_anim->node_cache[i];
-
+
if (!nc) // no node cache for this track, skip it
continue;
-
+
if (a->track_get_key_count(i)==0)
continue; // do nothing if track is empty
switch(a->track_get_type(i)) {
-
+
case Animation::TYPE_TRANSFORM: {
-
+
if (!nc->spatial)
continue;
-
-
+
+
Vector3 loc;
Quat rot;
Vector3 scale;
@@ -398,10 +406,10 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
nc->scale_accum=nc->scale_accum.linear_interpolate(scale,p_interp);
}
-
+
} break;
case Animation::TYPE_VALUE: {
-
+
if (!nc->node)
continue;
@@ -480,21 +488,21 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
}
}
-
+
} break;
case Animation::TYPE_METHOD: {
-
+
if (!nc->node)
continue;
if (p_delta==0)
continue;
if (!p_allow_discrete)
break;
-
+
List<int> indices;
a->method_track_get_key_indices(i,p_time,p_delta,&indices);
-
+
for(List<int>::Element *E=indices.front();E;E=E->next()) {
StringName method=a->method_track_get_name(i,E->get());
@@ -515,8 +523,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
);
}
}
-
-
+
+
} break;
}
}
@@ -527,17 +535,17 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd,float p_delta,flo
float delta=p_delta*speed_scale*cd.speed_scale;
bool backwards=delta<0;
float next_pos=cd.pos+delta;
-
+
float len=cd.from->animation->get_length();
bool loop=cd.from->animation->has_loop();
-
+
if (!loop) {
-
+
if (next_pos<0)
next_pos=0;
else if (next_pos>len)
next_pos=len;
-
+
// fix delta
delta=next_pos-cd.pos;
@@ -556,39 +564,39 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd,float p_delta,flo
}
} else {
-
+
next_pos=Math::fposmod(next_pos,len);
}
-
+
cd.pos=next_pos;
_animation_process_animation(cd.from,cd.pos,delta,p_blend,&cd == &playback.current);
-
+
}
void AnimationPlayer::_animation_process2(float p_delta) {
Playback &c=playback;
-
+
float prev_blend=1.0;
accum_pass++;
-
+
int pop_count=1;
int pop=0; // if >0, then amount of elements to pop from the back
for (List<Blend>::Element *E=c.blend.back();E;E=E->prev(),pop_count++) {
-
+
Blend& b=E->get();
_animation_process_data(b.data,p_delta,prev_blend);
-
+
prev_blend=1.0-b.blend_left/b.blend_time;
-
+
b.blend_left-=Math::absf(speed_scale*p_delta);
-
+
if (b.blend_left<0) {
pop=pop_count;
@@ -600,22 +608,22 @@ void AnimationPlayer::_animation_process2(float p_delta) {
c.blend.pop_back();
}
-
+
_animation_process_data(c.current,p_delta,prev_blend);
-
+
}
void AnimationPlayer::_animation_update_transforms() {
for (int i=0;i<cache_update_size;i++) {
-
+
TrackNodeCache *nc=cache_update[i];
ERR_CONTINUE( nc->accum_pass!=accum_pass );
if (nc->spatial) {
-
+
Transform t;
t.origin=nc->loc_accum;
t.basis=nc->rot_accum;
@@ -630,9 +638,9 @@ void AnimationPlayer::_animation_update_transforms() {
nc->spatial->set_transform(t);
}
}
-
+
}
-
+
cache_update_size=0;
for (int i=0;i<cache_update_prop_size;i++) {
@@ -704,7 +712,7 @@ void AnimationPlayer::_animation_process(float p_delta) {
// bool any_active=false;
-
+
if (playback.current.from) {
end_notify=false;
@@ -742,7 +750,7 @@ Error AnimationPlayer::add_animation(const StringName& p_name, const Ref<Animati
#endif
ERR_FAIL_COND_V( p_animation.is_null() , ERR_INVALID_PARAMETER );
-
+
//print_line("Add anim: "+String(p_name)+" name: "+p_animation->get_name());
if (animation_set.has(p_name)) {
@@ -751,12 +759,12 @@ Error AnimationPlayer::add_animation(const StringName& p_name, const Ref<Animati
animation_set[p_name].animation=p_animation;
clear_caches();
} else {
-
+
AnimationData ad;
ad.animation=p_animation;
ad.name=p_name;
animation_set[p_name]=ad;
- }
+ }
_ref_anim(p_animation);
_change_notify();
@@ -766,10 +774,10 @@ Error AnimationPlayer::add_animation(const StringName& p_name, const Ref<Animati
void AnimationPlayer::remove_animation(const StringName& p_name) {
ERR_FAIL_COND(!animation_set.has(p_name) );
-
+
stop_all();
_unref_anim(animation_set[p_name].animation);
- animation_set.erase(p_name);
+ animation_set.erase(p_name);
clear_caches();
_change_notify();
@@ -868,7 +876,7 @@ Ref<Animation> AnimationPlayer::get_animation(const StringName& p_name) const {
ERR_FAIL_COND_V( !animation_set.has(p_name), Ref<Animation>() );
const AnimationData& data = animation_set[p_name];
-
+
return data.animation;
}
@@ -942,7 +950,7 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float
//printf("animation is %ls\n", String(p_name).c_str());
//ERR_FAIL_COND(!is_inside_scene());
StringName name=p_name;
-
+
if (String(name)=="")
name=playback.assigned;
@@ -950,11 +958,11 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float
ERR_EXPLAIN("Animation not found: "+name);
ERR_FAIL();
}
-
+
Playback &c=playback;
if (c.current.from) {
-
+
float blend_time=0;
// find if it can blend
BlendKey bk;
@@ -964,37 +972,37 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float
if (p_custom_blend>=0) {
blend_time=p_custom_blend;
} else if (blend_times.has(bk)) {
-
+
blend_time=blend_times[bk];
} else {
-
+
bk.from="*";
if (blend_times.has(bk)) {
blend_time=blend_times[bk];
} else {
-
+
bk.from=c.current.from->name;
bk.to="*";
-
+
if (blend_times.has(bk)) {
-
+
blend_time=blend_times[bk];
}
}
}
-
+
if (p_custom_blend<0 && blend_time==0 && default_blend_time)
blend_time=default_blend_time;
if (blend_time>0) {
-
+
Blend b;
b.data=c.current;
b.blend_time=b.blend_left=blend_time;
- c.blend.push_back(b);
+ c.blend.push_back(b);
}
}
-
+
c.current.from=&animation_set[name];
c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0;
c.current.speed_scale=p_custom_scale;
@@ -1051,7 +1059,7 @@ String AnimationPlayer::get_current_animation() const {
}
void AnimationPlayer::stop(bool p_reset) {
-
+
Playback &c=playback;
c.blend.clear();
if (p_reset) {
@@ -1065,15 +1073,15 @@ void AnimationPlayer::stop(bool p_reset) {
void AnimationPlayer::stop_all() {
stop();
-
+
_set_process(false); // always process when starting an animation
-
+
}
void AnimationPlayer::set_speed(float p_speed) {
speed_scale=p_speed;
-
+
}
float AnimationPlayer::get_speed() const {
@@ -1143,7 +1151,7 @@ void AnimationPlayer::_node_removed(Node *p_node) {
void AnimationPlayer::clear_caches() {
-
+
node_cache_map.clear();
for( Map<StringName, AnimationData>::Element *E=animation_set.front();E;E=E->next()) {
@@ -1288,7 +1296,7 @@ void AnimationPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_animation","name"),&AnimationPlayer::has_animation);
ObjectTypeDB::bind_method(_MD("get_animation:Animation","name"),&AnimationPlayer::get_animation);
ObjectTypeDB::bind_method(_MD("get_animation_list"),&AnimationPlayer::_get_animation_list);
-
+
ObjectTypeDB::bind_method(_MD("set_blend_time","anim_from","anim_to","sec"),&AnimationPlayer::set_blend_time);
ObjectTypeDB::bind_method(_MD("get_blend_time","anim_from","anim_to"),&AnimationPlayer::get_blend_time);
@@ -1307,7 +1315,7 @@ void AnimationPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_active","active"),&AnimationPlayer::set_active);
ObjectTypeDB::bind_method(_MD("is_active"),&AnimationPlayer::is_active);
-
+
ObjectTypeDB::bind_method(_MD("set_speed","speed"),&AnimationPlayer::set_speed);
ObjectTypeDB::bind_method(_MD("get_speed"),&AnimationPlayer::get_speed);
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 853526c80a..2ae3a0756c 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -53,7 +53,7 @@ public:
private:
enum {
-
+
NODE_CACHE_UPDATE_MAX=1024,
BLEND_FROM_MAX=3
};
@@ -96,23 +96,23 @@ private:
Map<StringName,PropertyAnim> property_anim;
-
+
TrackNodeCache() { skeleton=NULL; spatial=NULL; node=NULL; accum_pass=0; bone_idx=-1; node_2d=NULL; }
-
+
};
struct TrackNodeCacheKey {
-
+
uint32_t id;
int bone_idx;
inline bool operator<(const TrackNodeCacheKey& p_right) const {
-
+
if (id<p_right.id)
return true;
else if (id>p_right.id)
return false;
- else
+ else
return bone_idx<p_right.bone_idx;
}
};
@@ -135,7 +135,7 @@ private:
StringName next;
Vector<TrackNodeCache*> node_cache;
Ref<Animation> animation;
-
+
};
Map<StringName, AnimationData> animation_set;
@@ -148,41 +148,41 @@ private:
Map<BlendKey, float > blend_times;
-
-
+
+
struct PlaybackData {
-
+
AnimationData* from;
float pos;
float speed_scale;
PlaybackData() {
-
+
pos=0;
speed_scale=1.0;
- from=NULL;
+ from=NULL;
}
};
-
+
struct Blend {
-
+
PlaybackData data;
-
+
float blend_time;
float blend_left;
-
+
Blend() {
-
+
blend_left=0;
blend_time=0;
}
};
-
+
struct Playback {
-
- List<Blend> blend;
+
+ List<Blend> blend;
PlaybackData current;
StringName assigned;
} playback;
@@ -197,25 +197,25 @@ private:
bool active;
NodePath root;
-
+
void _animation_process_animation(AnimationData* p_anim,float p_time, float p_delta,float p_interp, bool p_allow_discrete=true);
-
- void _generate_node_caches(AnimationData* p_anim);
+
+ void _generate_node_caches(AnimationData* p_anim);
void _animation_process_data(PlaybackData &cd,float p_delta,float p_blend);
void _animation_process2(float p_delta);
void _animation_update_transforms();
void _animation_process(float p_delta);
-
+
void _node_removed(Node *p_node);
-
+
// bind helpers
DVector<String> _get_animation_list() const {
-
+
List<StringName> animations;
get_animation_list(&animations);
DVector<String> ret;
while(animations.size()) {
-
+
ret.push_back( animations.front()->get());
animations.pop_front();
}
@@ -236,9 +236,9 @@ protected:
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
void _notification(int p_what);
-
- static void _bind_methods();
-
+
+ static void _bind_methods();
+
public:
StringName find_animation(const Ref<Animation>& p_animation) const;
@@ -249,7 +249,7 @@ public:
bool has_animation(const StringName& p_name) const;
Ref<Animation> get_animation(const StringName& p_name) const;
void get_animation_list( List<StringName> * p_animations) const;
-
+
void set_blend_time(const StringName& p_animation1, const StringName& p_animation2, float p_time);
float get_blend_time( const StringName& p_animation1, const StringName& p_animation2) const;
@@ -258,7 +258,7 @@ public:
void set_default_blend_time(float p_default);
float get_default_blend_time() const;
-
+
void play(const StringName& p_name=StringName(),float p_custom_blend=-1,float p_custom_scale=1.0,bool p_from_end=false);
void play_backwards(const StringName& p_name=StringName(),float p_custom_blend=-1);
void queue(const StringName& p_name);
@@ -271,7 +271,7 @@ public:
void set_active(bool p_active);
bool is_active() const;
bool is_valid() const;
-
+
void set_speed(float p_speed);
float get_speed() const;
@@ -295,8 +295,8 @@ public:
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
-
- AnimationPlayer();
+
+ AnimationPlayer();
~AnimationPlayer();
};
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 77d9f77bb5..9dcad8a533 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -420,7 +420,7 @@ void AnimationTreePlayer::_notification(int p_what) {
_process_animation( get_process_delta_time() );
} break;
case NOTIFICATION_FIXED_PROCESS: {
-
+
if (animation_process_mode==ANIMATION_PROCESS_IDLE)
break;
@@ -507,7 +507,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!(*r_prev_anim))
active_list=an;
- else
+ else
(*r_prev_anim)->next=an;
an->next=NULL;
@@ -607,20 +607,21 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
Blend3Node *bn = static_cast<Blend3Node*>(nb);
float rem;
-
- if (bn->value==0) {
- rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
- } else if (bn->value>0) {
-
- rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value));
- _process_node(bn->inputs[2].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value);
-
+ float blend, lower_blend, upper_blend;
+ if (bn->value < 0) {
+ lower_blend = -bn->value;
+ blend = 1.0 - lower_blend;
+ upper_blend = 0;
} else {
-
- rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*(1.0+bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0+bn->value));
- _process_node(bn->inputs[0].node,r_prev_anim,p_weight*-bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*-bn->value);
+ lower_blend = 0;
+ blend = 1.0 - bn->value;
+ upper_blend = bn->value;
}
+ rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,switched,p_seek,p_filter,p_reverse_weight*blend);
+ _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*upper_blend);
+ _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*lower_blend);
+
return rem;
} break;
case NODE_BLEND4: {
@@ -636,10 +637,15 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
} break;
case NODE_TIMESCALE: {
TimeScaleNode *tsn = static_cast<TimeScaleNode*>(nb);
+ float rem;
if (p_seek)
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight);
+ rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight);
+ else
+ rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight);
+ if (tsn->scale == 0)
+ return INFINITY;
else
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight);
+ return rem / tsn->scale;
} break;
case NODE_TIMESEEK: {
@@ -768,6 +774,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
t.scale.x=0;
t.scale.y=0;
t.scale.z=0;
+
+ Variant value = t.node->get(t.property);
+ value.zero();
+ t.node->set(t.property, value);
}
@@ -777,11 +787,9 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
Quat empty_rot;
- int total = 0;
while(anim_list) {
if (!anim_list->animation.is_null() && !anim_list->skip) {
- ++total;
//check if animation is meaningful
Animation *a = anim_list->animation.operator->();
@@ -816,8 +824,9 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated.
if (a->value_track_is_continuous(tr.local_track)) {
- Variant value = a->value_track_interpolate(tr.local_track,anim_list->time);
- tr.track->node->set(tr.track->property,value);
+ Variant blended, value = a->value_track_interpolate(tr.local_track,anim_list->time);
+ Variant::blend(tr.track->node->get(tr.track->property),value,blend,blended);
+ tr.track->node->set(tr.track->property,blended);
} else {
List<int> indices;
@@ -857,8 +866,9 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
if (!t.node)
continue;
- //if (E->get()->t.type!=Animation::TYPE_TRANSFORM)
- // continue;
+
+ if(t.property) // value track; was applied in step 2
+ continue;
Transform xform;
xform.basis=t.rot;
@@ -1826,7 +1836,7 @@ void AnimationTreePlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("reset"),&AnimationTreePlayer::reset);
- ObjectTypeDB::bind_method(_MD("recompute_caches"),&AnimationTreePlayer::recompute_caches);
+ ObjectTypeDB::bind_method(_MD("recompute_caches"),&AnimationTreePlayer::recompute_caches);
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_animation_process_mode"), _SCS("get_animation_process_mode"));
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 31f30dd1d9..7edd57603b 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -126,7 +126,7 @@ bool Tween::_get(const StringName& p_name,Variant &r_ret) const {
String name=p_name;
if (name=="playback/speed") { //bw compatibility
-
+
r_ret=speed_scale;
} else if (name=="playback/active") {
@@ -149,7 +149,7 @@ void Tween::_get_property_list(List<PropertyInfo> *p_list) const {
void Tween::_notification(int p_what) {
switch(p_what) {
-
+
case NOTIFICATION_ENTER_TREE: {
if (!processing) {
@@ -170,7 +170,7 @@ void Tween::_notification(int p_what) {
_tween_process( get_process_delta_time() );
} break;
case NOTIFICATION_FIXED_PROCESS: {
-
+
if (tween_process_mode==TWEEN_PROCESS_IDLE)
break;
@@ -178,7 +178,7 @@ void Tween::_notification(int p_what) {
_tween_process( get_fixed_process_delta_time() );
} break;
case NOTIFICATION_EXIT_TREE: {
-
+
stop_all();
} break;
}
@@ -1183,7 +1183,7 @@ bool Tween::interpolate_callback(Object *p_object
args=2;
else if (p_arg1.get_type()!=Variant::NIL)
args=1;
- else
+ else
args=0;
data.args = args;
@@ -1247,7 +1247,7 @@ bool Tween::interpolate_deferred_callback(Object *p_object
args=2;
else if (p_arg1.get_type()!=Variant::NIL)
args=1;
- else
+ else
args=0;
data.args = args;
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index f06ca1e9e7..d0455cdc71 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -57,7 +57,7 @@ public:
TRANS_COUNT,
};
-
+
enum EaseType {
EASE_IN,
EASE_OUT,
@@ -206,7 +206,7 @@ public:
, String p_callback
, VARIANT_ARG_DECLARE
);
-
+
bool interpolate_deferred_callback(Object *p_object
, real_t p_times_in_sec
, String p_callback
diff --git a/scene/audio/event_player.cpp b/scene/audio/event_player.cpp
index eabe84a8ee..f43c3c2a59 100644
--- a/scene/audio/event_player.cpp
+++ b/scene/audio/event_player.cpp
@@ -54,6 +54,8 @@ void EventPlayer::set_stream(const Ref<EventStream> &p_stream) {
stream=p_stream;
if (stream.is_valid())
playback=stream->instance_playback();
+ else
+ playback.unref();
if (playback.is_valid()) {
diff --git a/scene/audio/stream_player.cpp b/scene/audio/stream_player.cpp
index f7cfc31b03..c1799ec12c 100644
--- a/scene/audio/stream_player.cpp
+++ b/scene/audio/stream_player.cpp
@@ -100,11 +100,22 @@ void StreamPlayer::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
//set_idle_process(false); //don't annoy
- if (stream.is_valid() && autoplay && !get_tree()->is_editor_hint())
- play();
+ if (stream.is_valid() && !get_tree()->is_editor_hint()) {
+ if (resume_pos>=0) {
+ play(resume_pos);
+ resume_pos=-1;
+ } else if (autoplay) {
+ play();
+ autoplay = false; //this line fix autoplay issues
+ }
+ }
+
} break;
case NOTIFICATION_EXIT_TREE: {
+ if (is_playing()) {
+ resume_pos=get_pos();
+ }
stop(); //wathever it may be doing, stop
} break;
}
@@ -397,6 +408,7 @@ StreamPlayer::StreamPlayer() {
buffering_ms=500;
loop_point=0;
stop_request=false;
+ resume_pos=-1;
}
diff --git a/scene/audio/stream_player.h b/scene/audio/stream_player.h
index 30840137e2..475139c2a4 100644
--- a/scene/audio/stream_player.h
+++ b/scene/audio/stream_player.h
@@ -67,6 +67,7 @@ class StreamPlayer : public Node {
float loop_point;
int buffering_ms;
volatile bool stop_request;
+ float resume_pos;
AudioRBResampler resampler;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 698dbce2b5..3bcc60b86a 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -37,19 +37,19 @@ void BaseButton::_input_event(InputEvent p_event) {
if (status.disabled) // no interaction with disabled button
return;
-
+
switch(p_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &b=p_event.mouse_button;
-
+
if ( status.disabled || b.button_index!=1 )
return;
if (status.pressing_button)
break;
-
+
if (status.click_on_press) {
if (b.pressed) {
@@ -96,13 +96,13 @@ void BaseButton::_input_event(InputEvent p_event) {
}
if (b.pressed) {
-
+
status.press_attempt=true;
status.pressing_inside=true;
-
+
} else {
-
-
+
+
if (status.press_attempt &&status.pressing_inside) {
if (!toggle_mode) { //mouse press attempt
@@ -114,14 +114,14 @@ void BaseButton::_input_event(InputEvent p_event) {
}
emit_signal("pressed");
-
+
} else {
status.pressed=!status.pressed;
-
+
pressed();
emit_signal("pressed");
-
+
toggled(status.pressed);
emit_signal("toggled",status.pressed);
if (get_script_instance()) {
@@ -134,10 +134,10 @@ void BaseButton::_input_event(InputEvent p_event) {
}
status.press_attempt=false;
-
+
}
-
- update();
+
+ update();
} break;
case InputEvent::MOUSE_MOTION: {
@@ -151,7 +151,7 @@ void BaseButton::_input_event(InputEvent p_event) {
case InputEvent::ACTION:
case InputEvent::JOYSTICK_BUTTON:
case InputEvent::KEY: {
-
+
if (p_event.is_echo()) {
break;
@@ -166,7 +166,7 @@ void BaseButton::_input_event(InputEvent p_event) {
}
if (p_event.is_action("ui_accept")) {
-
+
if (p_event.is_pressed()) {
status.pressing_button++;
@@ -183,18 +183,18 @@ void BaseButton::_input_event(InputEvent p_event) {
status.press_attempt=false;
status.pressing_inside=false;
-
+
if (!toggle_mode) { //mouse press attempt
-
+
pressed();
- emit_signal("pressed");
+ emit_signal("pressed");
} else {
-
+
status.pressed=!status.pressed;
-
+
pressed();
emit_signal("pressed");
-
+
toggled(status.pressed);
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_toggled,status.pressed);
@@ -202,29 +202,29 @@ void BaseButton::_input_event(InputEvent p_event) {
emit_signal("toggled",status.pressed);
}
}
-
+
accept_event();
- update();
+ update();
}
- }
-
+ }
+
}
}
void BaseButton::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_MOUSE_ENTER) {
-
+
status.hovering=true;
update();
}
-
+
if (p_what==NOTIFICATION_MOUSE_EXIT) {
status.hovering=false;
update();
- }
+ }
if (p_what==NOTIFICATION_FOCUS_EXIT) {
if (status.pressing_button && status.press_attempt) {
@@ -282,7 +282,7 @@ void BaseButton::toggled(bool p_pressed) {
void BaseButton::set_disabled(bool p_disabled) {
-
+
status.disabled = p_disabled;
update();
_change_notify("disabled");
@@ -298,7 +298,7 @@ bool BaseButton::is_disabled() const {
}
void BaseButton::set_pressed(bool p_pressed) {
-
+
if (!toggle_mode)
return;
if (status.pressed==p_pressed)
@@ -309,12 +309,12 @@ void BaseButton::set_pressed(bool p_pressed) {
}
bool BaseButton::is_pressing() const{
-
+
return status.press_attempt;
}
bool BaseButton::is_pressed() const {
-
+
return toggle_mode?status.pressed:status.press_attempt;
}
@@ -324,11 +324,11 @@ bool BaseButton::is_hovered() const {
}
BaseButton::DrawMode BaseButton::get_draw_mode() const {
-
+
if (status.disabled) {
return DRAW_DISABLED;
};
-
+
//print_line("press attempt: "+itos(status.press_attempt)+" hover: "+itos(status.hovering)+" pressed: "+itos(status.pressed));
if (status.press_attempt==false && status.hovering && !status.pressed) {
@@ -336,34 +336,34 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
return DRAW_HOVER;
} else {
/* determine if pressed or not */
-
+
bool pressing;
if (status.press_attempt) {
-
+
pressing=status.pressing_inside;
if (status.pressed)
pressing=!pressing;
} else {
-
+
pressing=status.pressed;
}
-
- if (pressing)
+
+ if (pressing)
return DRAW_PRESSED;
- else
+ else
return DRAW_NORMAL;
- }
+ }
return DRAW_NORMAL;
}
void BaseButton::set_toggle_mode(bool p_on) {
-
+
toggle_mode=p_on;
}
bool BaseButton::is_toggle_mode() const {
-
+
return toggle_mode;
}
@@ -414,7 +414,7 @@ void BaseButton::_bind_methods() {
}
BaseButton::BaseButton() {
-
+
toggle_mode=false;
status.pressed=false;
status.press_attempt=false;
@@ -426,7 +426,7 @@ BaseButton::BaseButton() {
set_focus_mode( FOCUS_ALL );
group=NULL;
-
+
}
BaseButton::~BaseButton()
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 83c66326c5..9a5213d971 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -42,9 +42,9 @@ class BaseButton : public Control {
OBJ_TYPE( BaseButton, Control );
bool toggle_mode;
-
+
struct Status {
-
+
bool pressed;
bool hovering;
bool press_attempt;
@@ -55,15 +55,15 @@ class BaseButton : public Control {
int pressing_button;
} status;
-
+
ButtonGroup *group;
-
+
protected:
-
+
virtual void pressed();
virtual void toggled(bool p_pressed);
static void _bind_methods();
@@ -82,7 +82,7 @@ public:
DrawMode get_draw_mode() const;
/* Signals */
-
+
bool is_pressed() const; ///< return wether button is pressed (toggled in)
bool is_pressing() const; ///< return wether button is pressed (toggled in)
bool is_hovered() const;
@@ -90,7 +90,7 @@ public:
void set_pressed(bool p_pressed); ///only works in toggle mode
void set_toggle_mode(bool p_on);
bool is_toggle_mode() const;
-
+
void set_disabled(bool p_disabled);
bool is_disabled() const;
@@ -98,7 +98,7 @@ public:
bool get_click_on_press() const;
- BaseButton();
+ BaseButton();
~BaseButton();
};
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index b9ce46d738..0f3f762ba1 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -45,7 +45,7 @@ Size2 Button::get_minimum_size() const {
_icon=icon;
if (!_icon.is_null()) {
-
+
minsize.height=MAX( minsize.height, _icon->get_height() );
minsize.width+=_icon->get_width();
if (text!="")
@@ -53,48 +53,48 @@ Size2 Button::get_minimum_size() const {
}
return get_stylebox("normal" )->get_minimum_size() + minsize;
-
+
}
void Button::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
Size2 size=get_size();
Color color;
//print_line(get_text()+": "+itos(is_flat())+" hover "+itos(get_draw_mode()));
-
+
switch( get_draw_mode() ) {
-
+
case DRAW_NORMAL: {
-
+
if (!flat)
get_stylebox("normal" )->draw( ci, Rect2(Point2(0,0), size) );
- color=get_color("font_color");
+ color=get_color("font_color");
} break;
case DRAW_PRESSED: {
-
+
get_stylebox("pressed" )->draw( ci, Rect2(Point2(0,0), size) );
if (has_color("font_color_pressed"))
color=get_color("font_color_pressed");
else
color=get_color("font_color");
-
+
} break;
case DRAW_HOVER: {
-
+
get_stylebox("hover" )->draw( ci, Rect2(Point2(0,0), size) );
color=get_color("font_color_hover");
-
+
} break;
case DRAW_DISABLED: {
get_stylebox("disabled" )->draw( ci, Rect2(Point2(0,0), size) );
color=get_color("font_color_disabled");
-
+
} break;
}
@@ -139,12 +139,12 @@ void Button::_notification(int p_what) {
if (!_icon.is_null()) {
int valign = size.height-style->get_minimum_size().y;
-
+
_icon->draw(ci,style->get_offset()+Point2(0, Math::floor( (valign-_icon->get_height())/2.0 ) ),is_disabled()?Color(1,1,1,0.4):Color(1,1,1) );
}
-
+
}
}
@@ -236,7 +236,7 @@ void Button::_bind_methods() {
}
Button::Button(const String &p_text) {
-
+
flat=false;
clip_text=false;
set_stop_mouse(true);
diff --git a/scene/gui/button.h b/scene/gui/button.h
index bd244f5087..8a17a164a0 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -34,7 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Button : public BaseButton {
-
+
OBJ_TYPE( Button, BaseButton );
public:
@@ -49,25 +49,25 @@ private:
bool flat;
String text;
- Ref<Texture> icon;
+ Ref<Texture> icon;
bool clip_text;
TextAlign align;
-
-protected:
+
+protected:
virtual Size2 get_minimum_size() const;
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
-//
+//
void set_text(const String& p_text);
String get_text() const;
-
+
void set_icon(const Ref<Texture>& p_icon);
Ref<Texture> get_icon() const;
-
+
void set_flat(bool p_flat);
bool is_flat() const;
diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp
index 9e3476899f..de77b83403 100644
--- a/scene/gui/button_array.cpp
+++ b/scene/gui/button_array.cpp
@@ -171,9 +171,9 @@ void ButtonArray::_notification(int p_what) {
case NOTIFICATION_READY:{
MethodInfo mi;
mi.name="mouse_sub_enter";
-
+
add_user_signal(mi);
-
+
}break;
case NOTIFICATION_DRAW: {
diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h
index 39661eaabd..c4b9b0c9e3 100644
--- a/scene/gui/button_array.h
+++ b/scene/gui/button_array.h
@@ -69,7 +69,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
-
+
public:
void _input_event(const InputEvent& p_event);
diff --git a/scene/gui/button_group.h b/scene/gui/button_group.h
index 38c61991b7..4afba22228 100644
--- a/scene/gui/button_group.h
+++ b/scene/gui/button_group.h
@@ -55,7 +55,7 @@ friend class BaseButton;
public:
void get_button_list(List<BaseButton*> *p_buttons) const;
- BaseButton *get_pressed_button() const;
+ BaseButton *get_pressed_button() const;
BaseButton *get_focused_button() const;
void set_pressed_button(BaseButton *p_button);
int get_pressed_button_index() const;
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index ecaea251a5..f8c0c6b208 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -33,9 +33,9 @@
void CheckButton::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
Ref<Texture> on=Control::get_icon("on");
@@ -50,17 +50,17 @@ void CheckButton::_notification(int p_what) {
else
off->draw(ci,ofs);
-
+
}
}
CheckButton::CheckButton() {
-
+
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
-
+
}
diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h
index 022ade2193..a1ed4c1896 100644
--- a/scene/gui/check_button.h
+++ b/scene/gui/check_button.h
@@ -35,18 +35,18 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class CheckButton : public Button {
-
+
OBJ_TYPE( CheckButton, Button );
-
-
-protected:
+
+
+protected:
void _notification(int p_what);
public:
-
- CheckButton();
+
+ CheckButton();
~CheckButton();
-
+
};
#endif
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 862a5d6bcb..bd24b43761 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -34,7 +34,7 @@
#include "os/input.h"
#include "os/keyboard.h"
-void update_material(Ref<CanvasItemMaterial>mat,const Color& p_color) {
+void update_material(Ref<CanvasItemMaterial>mat,const Color& p_color,float h,float s,float v) {
if (!mat.is_valid())
return;
Ref<Shader> sdr = mat->get_shader();
@@ -44,9 +44,9 @@ void update_material(Ref<CanvasItemMaterial>mat,const Color& p_color) {
mat->set_shader_param("R",p_color.r);
mat->set_shader_param("G",p_color.g);
mat->set_shader_param("B",p_color.b);
- mat->set_shader_param("H",p_color.get_h());
- mat->set_shader_param("S",p_color.get_s());
- mat->set_shader_param("V",p_color.get_v());
+ mat->set_shader_param("H",h);
+ mat->set_shader_param("S",s);
+ mat->set_shader_param("V",v);
mat->set_shader_param("A",p_color.a);
}
@@ -57,14 +57,25 @@ void ColorPicker::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
uv_material->set_shader(get_shader("uv_editor"));
w_material->set_shader(get_shader("w_editor"));
- update_material(uv_material,color);
- update_material(w_material,color);
+ update_material(uv_material,color,h,s,v);
+ update_material(w_material,color,h,s,v);
_update_controls();
} break;
case NOTIFICATION_ENTER_TREE: {
btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
+ update_material(uv_material, color,h,s,v);
+ update_material(w_material, color,h,s,v);
+
+ uv_edit->get_child(0)->cast_to<Control>()->update();
+ w_edit->get_child(0)->cast_to<Control>()->update();
+ _update_color();
}
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ c_text->call_deferred("grab_focus");
+ c_text->call_deferred("select");
+ } break;
}
}
@@ -85,11 +96,19 @@ void ColorPicker::_update_controls() {
void ColorPicker::set_color(const Color& p_color) {
color=p_color;
- h=color.get_h();
- s=color.get_s();
- v=color.get_v();
- update_material(uv_material, color);
- update_material(w_material, color);
+ if (color != last_hsv) {
+ h=color.get_h();
+ s=color.get_s();
+ v=color.get_v();
+ last_hsv = color;
+ }
+
+ if (!is_inside_tree())
+ return;
+
+ update_material(uv_material, color,h,s,v);
+ update_material(w_material, color,h,s,v);
+
uv_edit->get_child(0)->cast_to<Control>()->update();
w_edit->get_child(0)->cast_to<Control>()->update();
_update_color();
@@ -100,6 +119,10 @@ void ColorPicker::set_edit_alpha(bool p_show) {
edit_alpha=p_show;
_update_controls();
+
+ if (!is_inside_tree())
+ return;
+
_update_color();
sample->update();
}
@@ -119,13 +142,10 @@ void ColorPicker::_value_changed(double) {
}
color.components[3] = scroll[3]->get_val()/255.0;
- update_material(uv_material,color);
- update_material(w_material,color);
+ set_color(color);
c_text->set_text(color.to_html(edit_alpha && color.a<1));
- sample->update();
-
emit_signal("color_changed",color);
}
@@ -136,6 +156,10 @@ void ColorPicker::_html_entered(const String& p_html) {
return;
color = Color::html(p_html);
+
+ if (!is_inside_tree())
+ return;
+
_update_color();
emit_signal("color_changed",color);
}
@@ -163,8 +187,6 @@ void ColorPicker::_update_color() {
} else {
c_text->set_text(color.to_html(edit_alpha && color.a<1));
}
- c_text->grab_focus();
- c_text->select();
sample->update();
updating=false;
@@ -224,7 +246,10 @@ void ColorPicker::set_raw_mode(bool p_enabled) {
raw_mode_enabled=p_enabled;
if (btn_mode->is_pressed()!=p_enabled)
btn_mode->set_pressed(p_enabled);
-
+
+ if (!is_inside_tree())
+ return;
+
_update_controls();
_update_color();
}
@@ -243,15 +268,17 @@ void ColorPicker::_hsv_draw(int p_wich,Control* c)
if (!c)
return;
if (p_wich==0) {
- int x=c->get_size().x*color.get_s();
- int y=c->get_size().y-c->get_size().y*color.get_v();
- c->draw_line(Point2(x,0),Point2(x,c->get_size().y),color.inverted());
- c->draw_line(Point2(0,y),Point2(c->get_size().x,y),color.inverted());
+ int x=c->get_size().x*s;
+ int y=c->get_size().y-c->get_size().y*v;
+ Color col = color;
+ col.a=1;
+ c->draw_line(Point2(x,0),Point2(x,c->get_size().y),col.inverted());
+ c->draw_line(Point2(0,y),Point2(c->get_size().x,y),col.inverted());
c->draw_line(Point2(x,y),Point2(x,y),Color(1,1,1),2);
} else if (p_wich==1) {
- int y=c->get_size().y-c->get_size().y*color.get_h();
+ int y=c->get_size().y-c->get_size().y*h;
Color col=Color();
- col.set_hsv(color.get_h(),1,1);
+ col.set_hsv(h,1,1);
c->draw_line(Point2(0,y),Point2(c->get_size().x,y),col.inverted());
}
}
@@ -266,6 +293,7 @@ void ColorPicker::_uv_input(const InputEvent &ev) {
s=x/256;
v=1.0-y/256.0;
color.set_hsv(h,s,v,color.a);
+ last_hsv = color;
set_color(color);
_update_color();
emit_signal("color_changed", color);
@@ -281,6 +309,7 @@ void ColorPicker::_uv_input(const InputEvent &ev) {
s=x/256;
v=1.0-y/256.0;
color.set_hsv(h,s,v,color.a);
+ last_hsv = color;
set_color(color);
_update_color();
emit_signal("color_changed", color);
@@ -293,11 +322,12 @@ void ColorPicker::_w_input(const InputEvent &ev) {
if (bev.pressed) {
changing_color = true;
h=1-((float)bev.y)/256.0;
-
+
} else {
changing_color = false;
}
color.set_hsv(h,s,v,color.a);
+ last_hsv = color;
set_color(color);
_update_color();
emit_signal("color_changed", color);
@@ -308,6 +338,7 @@ void ColorPicker::_w_input(const InputEvent &ev) {
float y = CLAMP((float)bev.y,0,256);
h=1.0-y/256.0;
color.set_hsv(h,s,v,color.a);
+ last_hsv = color;
set_color(color);
_update_color();
emit_signal("color_changed", color);
@@ -330,7 +361,10 @@ void ColorPicker::_preset_input(const InputEvent &ev) {
emit_signal("color_changed", color);
} else if (ev.type == InputEvent::MOUSE_MOTION) {
const InputEventMouse &mev = ev.mouse_motion;
- int index = mev.x/(preset->get_size().x/presets.size());
+ int index = mev.x * presets.size();
+ if( preset->get_size().x != 0 ) {
+ index /= preset->get_size().x;
+ }
if (index<0 || index >= presets.size())
return;
preset->set_tooltip("Color: #"+presets[index].to_html(presets[index].a<1)+"\n"
@@ -471,7 +505,7 @@ ColorPicker::ColorPicker() :
args.push_back(1);
args.push_back(c);
c->connect("draw",this,"_hsv_draw",args);
-
+
hb_edit->add_child(uv_edit);
hb_edit->add_child(memnew( VSeparator ));
hb_edit->add_child(w_edit);
@@ -512,7 +546,7 @@ ColorPicker::ColorPicker() :
}
HBoxContainer *hhb = memnew( HBoxContainer );
-
+
btn_mode = memnew( CheckButton );
btn_mode->set_text("RAW Mode");
btn_mode->connect("toggled", this, "set_raw_mode");
@@ -531,7 +565,7 @@ ColorPicker::ColorPicker() :
_update_controls();
- _update_color();
+ //_update_color();
updating=false;
uv_material.instance();
@@ -539,7 +573,7 @@ ColorPicker::ColorPicker() :
uv_material->set_shader(s_uv);
w_material.instance();
-
+
Ref<Shader> s_w = get_shader("w_editor");
w_material->set_shader(s_w);
@@ -594,6 +628,8 @@ void ColorPickerButton::pressed() {
popup->set_pos(get_global_pos()-Size2(0,ms.height));
popup->set_size(ms);
popup->popup();
+
+
}
void ColorPickerButton::_notification(int p_what) {
@@ -651,4 +687,3 @@ ColorPickerButton::ColorPickerButton() {
picker->connect("color_changed",this,"_color_changed");
add_child(popup);
}
-
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 59668ebac1..4559bc7391 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -73,6 +73,7 @@ private:
bool updating;
bool changing_color;
float h,s,v;
+ Color last_hsv;
void _html_entered(const String& p_html);
void _value_changed(double);
@@ -89,6 +90,7 @@ private:
void _screen_input(const InputEvent& p_input);
void _add_preset_pressed();
void _screen_pick_pressed();
+
protected:
void _notification(int);
diff --git a/scene/gui/color_ramp_edit.cpp b/scene/gui/color_ramp_edit.cpp
index 14a48fe3d3..2ab004e04b 100644
--- a/scene/gui/color_ramp_edit.cpp
+++ b/scene/gui/color_ramp_edit.cpp
@@ -185,7 +185,7 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
int x = p_event.mouse_motion.x;
float newofs = CLAMP(x/float(total_w),0,1);
-
+
//Snap to nearest point if holding shift
if (p_event.key.mod.shift) {
float snap_treshhold = 0.03;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 71a0f50240..d7befd6e11 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -39,6 +39,9 @@
#include "scene/scene_string_names.h"
#include "scene/gui/panel.h"
#include "scene/gui/label.h"
+#ifdef TOOLS_ENABLED
+#include "tools/editor/editor_settings.h"
+#endif
#include <stdio.h>
@@ -85,9 +88,14 @@ Size2 Control::edit_get_minimum_size() const {
void Control::edit_set_rect(const Rect2& p_edit_rect) {
- Rect2 new_rect=get_rect();
+ Matrix32 postxf;
+ postxf.set_rotation_and_scale(data.rotation,data.scale);
+ Vector2 new_pos = postxf.xform(p_edit_rect.pos);
+
+ Vector2 pos = get_pos()+new_pos;
- new_rect.pos+=p_edit_rect.pos.snapped(Vector2(1,1));
+ Rect2 new_rect=get_rect();
+ new_rect.pos=pos.snapped(Vector2(1,1));
new_rect.size=p_edit_rect.size.snapped(Vector2(1,1));
set_pos(new_rect.pos);
@@ -221,9 +229,9 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
return false;
-
+
return true;
-
+
}
void Control::_get_property_list( List<PropertyInfo> *p_list) const {
@@ -321,7 +329,7 @@ Control *Control::get_parent_control() const {
void Control::_resize(const Size2& p_size) {
-
+
_size_changed();
}
@@ -621,7 +629,7 @@ void Control::set_drag_preview(Control *p_control) {
}
-
+
bool Control::is_window_modal_on_top() const {
@@ -635,7 +643,7 @@ bool Control::is_window_modal_on_top() const {
Size2 Control::get_minimum_size() const {
-
+
ScriptInstance *si = const_cast<Control*>(this)->get_script_instance();
if (si) {
@@ -649,7 +657,7 @@ Size2 Control::get_minimum_size() const {
Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type) const {
-
+
if (p_type==StringName()) {
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
@@ -709,7 +717,7 @@ Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_typ
}
Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p_type) const {
-
+
if (p_type==StringName()) {
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
if (style)
@@ -823,12 +831,12 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
return Theme::get_default()->get_constant( p_name, type );
-
+
}
bool Control::has_icon(const StringName& p_name,const StringName& p_type) const {
-
+
if (p_type==StringName()) {
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
if (tex)
@@ -854,7 +862,7 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const
}
return Theme::get_default()->has_icon( p_name, type );
-
+
}
bool Control::has_shader(const StringName &p_name, const StringName &p_type) const
@@ -884,10 +892,10 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con
}
return Theme::get_default()->has_shader( p_name, type );
-
+
}
bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const {
-
+
if (p_type==StringName()) {
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
@@ -917,7 +925,7 @@ bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) co
}
bool Control::has_font(const StringName& p_name,const StringName& p_type) const {
-
+
if (p_type==StringName()) {
const Ref<Font>* font = data.font_override.getptr(p_name);
if (font)
@@ -947,7 +955,7 @@ bool Control::has_font(const StringName& p_name,const StringName& p_type) const
}
bool Control::has_color(const StringName& p_name,const StringName& p_type) const {
-
+
if (p_type==StringName()) {
const Color* color = data.color_override.getptr(p_name);
if (color)
@@ -1019,7 +1027,7 @@ Size2 Control::get_parent_area_size() const {
} else {
parent_size=get_viewport()->get_visible_rect().size;
- }
+ }
return parent_size;
}
@@ -1078,11 +1086,11 @@ void Control::_size_changed() {
}
float Control::_get_parent_range(int p_idx) const {
-
+
if (!is_inside_tree()) {
-
+
return 1.0;
-
+
} if (data.parent_canvas_item) {
return data.parent_canvas_item->get_item_rect().size[p_idx&1];
@@ -1095,21 +1103,21 @@ float Control::_get_parent_range(int p_idx) const {
float Control::_get_range(int p_idx) const {
-
+
p_idx&=1;
float parent_range = _get_parent_range( p_idx );
float from = _a2s( data.margin[p_idx], data.anchor[p_idx], parent_range );
float to = _a2s( data.margin[p_idx+2], data.anchor[p_idx+2], parent_range );
-
+
return to-from;
}
float Control::_s2a(float p_val, AnchorType p_anchor,float p_range) const {
-
+
switch(p_anchor) {
-
- case ANCHOR_BEGIN: {
+
+ case ANCHOR_BEGIN: {
return p_val;
} break;
case ANCHOR_END: {
@@ -1117,21 +1125,21 @@ float Control::_s2a(float p_val, AnchorType p_anchor,float p_range) const {
} break;
case ANCHOR_RATIO: {
return p_val/p_range;
- } break;
+ } break;
case ANCHOR_CENTER: {
return (p_range/2)-p_val;
} break;
- }
-
+ }
+
return 0;
}
float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const {
-
+
switch(p_anchor) {
-
- case ANCHOR_BEGIN: {
+
+ case ANCHOR_BEGIN: {
return Math::floor(p_val);
} break;
case ANCHOR_END: {
@@ -1139,7 +1147,7 @@ float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const {
} break;
case ANCHOR_RATIO: {
return Math::floor(p_range*p_val);
- } break;
+ } break;
case ANCHOR_CENTER: {
return Math::floor((p_range/2)-p_val);
} break;
@@ -1148,20 +1156,36 @@ float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const {
}
-void Control::set_anchor(Margin p_margin,AnchorType p_anchor) {
-
+void Control::set_anchor(Margin p_margin,AnchorType p_anchor, bool p_keep_margin) {
+
if (!is_inside_tree()) {
-
- data.anchor[p_margin]=p_anchor;
- } else {
+
+ data.anchor[p_margin] = p_anchor;
+ } else if(!p_keep_margin) {
float pr = _get_parent_range(p_margin);
float s = _a2s( data.margin[p_margin], data.anchor[p_margin], pr );
- data.anchor[p_margin]=p_anchor;
+ data.anchor[p_margin] = p_anchor;
data.margin[p_margin] = _s2a( s, p_anchor, pr );
+ } else {
+ data.anchor[p_margin] = p_anchor;
+ _size_changed();
}
_change_notify();
}
+void Control::_set_anchor(Margin p_margin,AnchorType p_anchor) {
+ #ifdef TOOLS_ENABLED
+ SceneTree *st=OS::get_singleton()->get_main_loop()->cast_to<SceneTree>();
+ if (st && st->is_editor_hint()) {
+ set_anchor(p_margin, p_anchor, EDITOR_DEF("2d_editor/keep_margins_when_changing_anchors", false));
+ } else {
+ set_anchor(p_margin, p_anchor);
+ }
+ #else
+ set_anchor(p_margin, p_anchor);
+ #endif
+}
+
void Control::set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p_pos) {
set_anchor(p_margin,p_anchor);
@@ -1170,8 +1194,8 @@ void Control::set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p
Control::AnchorType Control::get_anchor(Margin p_margin) const {
-
- return data.anchor[p_margin];
+
+ return data.anchor[p_margin];
}
@@ -1199,40 +1223,40 @@ void Control::set_margin(Margin p_margin,float p_value) {
}
void Control::set_begin(const Size2& p_point) {
-
+
data.margin[0]=p_point.x;
data.margin[1]=p_point.y;
_size_changed();
}
void Control::set_end(const Size2& p_point) {
-
+
data.margin[2]=p_point.x;
data.margin[3]=p_point.y;
_size_changed();
}
float Control::get_margin(Margin p_margin) const {
-
+
return data.margin[p_margin];
}
Size2 Control::get_begin() const {
-
+
return Size2( data.margin[0], data.margin[1] );
}
Size2 Control::get_end() const {
-
+
return Size2( data.margin[2], data.margin[3] );
}
Point2 Control::get_global_pos() const {
-
+
return get_global_transform().get_origin();
}
void Control::set_global_pos(const Point2& p_point) {
-
+
Matrix32 inv;
if (data.parent_canvas_item) {
@@ -1259,10 +1283,10 @@ void Control::set_pos(const Size2& p_point) {
Size2 size = Size2(MAX( min.width, ret.width),MAX( min.height, ret.height));
float w=size.x;
float h=size.y;
-
+
x=p_point.x;
y=p_point.y;
-
+
data.margin[0] = _s2a( x, data.anchor[0], pw );
data.margin[1] = _s2a( y, data.anchor[1], ph );
data.margin[2] = _s2a( x+w, data.anchor[2], pw );
@@ -1272,26 +1296,26 @@ void Control::set_pos(const Size2& p_point) {
}
void Control::set_size(const Size2& p_size) {
-
+
Size2 new_size=p_size;
Size2 min=get_combined_minimum_size();
if (new_size.x<min.x)
new_size.x=min.x;
if (new_size.y<min.y)
new_size.y=min.y;
-
+
float pw = _get_parent_range(0);
float ph = _get_parent_range(1);
-
+
float x = _a2s( data.margin[0], data.anchor[0], pw );
float y = _a2s( data.margin[1], data.anchor[1], ph );
-
+
float w=new_size.width;
float h=new_size.height;
-
+
data.margin[2] = _s2a( x+w, data.anchor[2], pw );
data.margin[3] = _s2a( y+h, data.anchor[3], ph );
-
+
_size_changed();
}
@@ -1303,13 +1327,13 @@ Size2 Control::get_pos() const {
}
Size2 Control::get_size() const {
-
+
return data.size_cache;
}
Rect2 Control::get_global_rect() const {
-
- return Rect2( get_global_pos(), get_size() );
+
+ return Rect2( get_global_pos(), get_size() );
}
Rect2 Control::get_window_rect() const {
@@ -1321,7 +1345,7 @@ Rect2 Control::get_window_rect() const {
Rect2 Control::get_rect() const {
-
+
return Rect2(get_pos(),get_size());
}
@@ -1331,7 +1355,7 @@ Rect2 Control::get_item_rect() const {
}
void Control::set_area_as_parent_rect(int p_margin) {
-
+
data.anchor[MARGIN_LEFT]=ANCHOR_BEGIN;
data.anchor[MARGIN_TOP]=ANCHOR_BEGIN;
data.anchor[MARGIN_RIGHT]=ANCHOR_END;
@@ -1340,7 +1364,7 @@ void Control::set_area_as_parent_rect(int p_margin) {
data.margin[i]=p_margin;
_size_changed();
-
+
}
void Control::add_icon_override(const StringName& p_name, const Ref<Texture>& p_icon) {
@@ -1349,7 +1373,7 @@ void Control::add_icon_override(const StringName& p_name, const Ref<Texture>& p_
data.icon_override[p_name]=p_icon;
notification(NOTIFICATION_THEME_CHANGED);
update();
-
+
}
void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader) {
@@ -1401,7 +1425,7 @@ static Control *_next_control(Control *p_from) {
if (p_from->is_set_as_toplevel())
return NULL; // can't go above
- Control *parent = p_from->get_parent()?p_from->get_parent()->cast_to<Control>():NULL;
+ Control *parent = p_from->get_parent()?p_from->get_parent()->cast_to<Control>():NULL;
if (!parent) {
@@ -1427,10 +1451,10 @@ static Control *_next_control(Control *p_from) {
Control *Control::find_next_valid_focus() const {
Control *from = const_cast<Control*>(this);
-
+
while(true) {
-
-
+
+
// find next child
Control *next_child=NULL;
@@ -1489,7 +1513,7 @@ Control *Control::find_next_valid_focus() const {
from = next_child;
}
-
+
return NULL;
@@ -1597,13 +1621,15 @@ bool Control::has_focus() const {
void Control::grab_focus() {
- ERR_FAIL_COND(!is_inside_tree());
+ if (!is_inside_tree()){
+ ERR_FAIL_COND(!is_inside_tree());
+ }
if (data.focus_mode==FOCUS_NONE)
return;
get_viewport()->_gui_control_grab_focus(this);
-}
+}
void Control::release_focus() {
@@ -1623,7 +1649,7 @@ bool Control::is_toplevel_control() const {
}
void Control::show_modal(bool p_exclusive) {
-
+
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND(!data.SI);
@@ -1635,7 +1661,7 @@ void Control::show_modal(bool p_exclusive) {
raise();
data.modal_exclusive=p_exclusive;
data.MI=get_viewport()->_gui_show_modal(this);
-
+
}
void Control::_modal_set_prev_focus_owner(ObjectID p_prev) {
@@ -2083,7 +2109,8 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("accept_event"),&Control::accept_event);
ObjectTypeDB::bind_method(_MD("get_minimum_size"),&Control::get_minimum_size);
ObjectTypeDB::bind_method(_MD("get_combined_minimum_size"),&Control::get_combined_minimum_size);
- ObjectTypeDB::bind_method(_MD("set_anchor","margin","anchor_mode"),&Control::set_anchor);
+ ObjectTypeDB::bind_method(_MD("set_anchor","margin","anchor_mode","keep_margin"),&Control::set_anchor,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("_set_anchor","margin","anchor_mode"),&Control::_set_anchor);
ObjectTypeDB::bind_method(_MD("get_anchor","margin"),&Control::get_anchor);
ObjectTypeDB::bind_method(_MD("set_margin","margin","offset"),&Control::set_margin);
ObjectTypeDB::bind_method(_MD("set_anchor_and_margin","margin","anchor_mode","offset"),&Control::set_anchor_and_margin);
@@ -2128,7 +2155,7 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_theme","theme:Theme"),&Control::set_theme);
ObjectTypeDB::bind_method(_MD("get_theme:Theme"),&Control::get_theme);
-
+
ObjectTypeDB::bind_method(_MD("add_icon_override","name","texture:Texture"),&Control::add_icon_override);
ObjectTypeDB::bind_method(_MD("add_shader_override","name","shader:Shader"),&Control::add_shader_override);
ObjectTypeDB::bind_method(_MD("add_style_override","name","stylebox:StyleBox"),&Control::add_style_override);
@@ -2143,7 +2170,7 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_constant","name","type"),&Control::get_constant,DEFVAL(""));
- ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control);
+ ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control);
ObjectTypeDB::bind_method(_MD("set_tooltip","tooltip"),&Control::set_tooltip);
ObjectTypeDB::bind_method(_MD("get_tooltip","atpos"),&Control::get_tooltip,DEFVAL(Point2()));
@@ -2177,10 +2204,10 @@ void Control::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::BOOL,"can_drop_data",PropertyInfo(Variant::VECTOR2,"pos"),PropertyInfo(Variant::NIL,"data")));
BIND_VMETHOD(MethodInfo("drop_data",PropertyInfo(Variant::VECTOR2,"pos"),PropertyInfo(Variant::NIL,"data")));
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/left", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_LEFT );
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/top", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_TOP );
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/right", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_RIGHT );
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/bottom", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_BOTTOM );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/left", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_LEFT );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/top", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_TOP );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/right", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_RIGHT );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/bottom", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_BOTTOM );
ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"margin/left", PROPERTY_HINT_RANGE, "-4096,4096"), _SCS("set_margin"),_SCS("get_margin"), MARGIN_LEFT );
ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"margin/top", PROPERTY_HINT_RANGE, "-4096,4096"), _SCS("set_margin"),_SCS("get_margin"), MARGIN_TOP );
@@ -2207,7 +2234,7 @@ void Control::_bind_methods() {
BIND_CONSTANT( ANCHOR_BEGIN );
BIND_CONSTANT( ANCHOR_END );
- BIND_CONSTANT( ANCHOR_RATIO );
+ BIND_CONSTANT( ANCHOR_RATIO );
BIND_CONSTANT( ANCHOR_CENTER );
BIND_CONSTANT( FOCUS_NONE );
BIND_CONSTANT( FOCUS_CLICK );
@@ -2254,11 +2281,11 @@ void Control::_bind_methods() {
ADD_SIGNAL( MethodInfo("minimum_size_changed") );
ADD_SIGNAL( MethodInfo("modal_close") );
-
+
}
Control::Control() {
-
- data.parent=NULL;
+
+ data.parent=NULL;
data.ignore_mouse=false;
data.stop_mouse=true;
@@ -2290,12 +2317,10 @@ Control::Control() {
-
+
}
Control::~Control()
{
}
-
-
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 74d40b7579..1e2db7a575 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -45,19 +45,19 @@ class Label;
class Panel;
class Control : public CanvasItem {
-
+
OBJ_TYPE( Control, CanvasItem );
OBJ_CATEGORY("GUI Nodes");
public:
-
- enum AnchorType {
+
+ enum AnchorType {
ANCHOR_BEGIN,
ANCHOR_END,
ANCHOR_RATIO,
ANCHOR_CENTER,
};
-
+
enum FocusMode {
FOCUS_NONE,
FOCUS_CLICK,
@@ -106,7 +106,7 @@ private:
};
struct Data {
-
+
Point2 pos_cache;
Size2 size_cache;
@@ -132,7 +132,7 @@ private:
bool modal;
bool modal_exclusive;
Ref<Theme> theme;
- Control *theme_owner;
+ Control *theme_owner;
String tooltip;
CursorShape default_cursor;
@@ -153,7 +153,7 @@ private:
HashMap<StringName, Color, StringNameHasher > color_override;
HashMap<StringName, int, StringNameHasher > constant_override;
} data;
-
+
// used internally
Control* _find_control_at_pos(CanvasItem* p_node,const Point2& p_pos,const Matrix32& p_xform,Matrix32& r_inv_xform);
@@ -162,6 +162,8 @@ private:
Control *_get_focus_neighbour(Margin p_margin,int p_count=0);
+ void _set_anchor(Margin p_margin,AnchorType p_anchor);
+
float _get_parent_range(int p_idx) const;
float _get_range(int p_idx) const;
float _s2a(float p_val, AnchorType p_anchor,float p_range) const;
@@ -184,7 +186,7 @@ friend class Viewport;
void _modal_stack_remove();
void _modal_set_prev_focus_owner(ObjectID p_prev);
-protected:
+protected:
//virtual void _window_input_event(InputEvent p_event);
@@ -194,15 +196,15 @@ protected:
void _notification(int p_notification);
-
- static void _bind_methods();
-
- //bind helpers
-
+
+ static void _bind_methods();
+
+ //bind helpers
+
public:
enum {
-
+
/* NOTIFICATION_DRAW=30,
NOTIFICATION_VISIBILITY_CHANGED=38*/
NOTIFICATION_RESIZED=40,
@@ -241,29 +243,29 @@ public:
Control *get_parent_control() const;
-
+
/* POSITIONING */
-
- void set_anchor(Margin p_margin,AnchorType p_anchor);
+
+ void set_anchor(Margin p_margin,AnchorType p_anchor, bool p_keep_margin=false);
void set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p_pos);
-
+
AnchorType get_anchor(Margin p_margin) const;
-
+
void set_margin(Margin p_margin,float p_value);
-
+
void set_begin(const Point2& p_point); // helper
void set_end(const Point2& p_point); // helper
-
-
-
+
+
+
float get_margin(Margin p_margin) const;
Point2 get_begin() const;
Point2 get_end() const;
-
+
void set_pos(const Point2& p_point);
void set_size(const Size2& p_size);
void set_global_pos(const Point2& p_point);
-
+
Point2 get_pos() const;
Point2 get_global_pos() const;
Size2 get_size() const;
@@ -277,9 +279,9 @@ public:
void set_scale(const Vector2& p_scale);
Vector2 get_scale() const;
-
+
void set_area_as_parent_rect(int p_margin=0);
-
+
void show_modal(bool p_exclusive=false);
void set_theme(const Ref<Theme>& p_theme);
@@ -297,7 +299,7 @@ public:
void minimum_size_changed();
/* FOCUS */
-
+
void set_focus_mode(FocusMode p_focus_mode);
FocusMode get_focus_mode() const;
bool has_focus() const;
@@ -319,7 +321,7 @@ public:
bool is_stopping_mouse() const;
/* SKINNING */
-
+
void add_icon_override(const StringName& p_name, const Ref<Texture>& p_icon);
void add_shader_override(const StringName& p_name, const Ref<Shader>& p_shader);
void add_style_override(const StringName& p_name, const Ref<StyleBox>& p_style);
@@ -367,9 +369,9 @@ public:
Control *get_root_parent_control() const;
- Control();
+ Control();
~Control();
-
+
};
VARIANT_ENUM_CAST(Control::AnchorType);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 9f08b6f845..d00dacd256 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -188,7 +188,7 @@ void AcceptDialog::_post_popup() {
}
void AcceptDialog::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_MODAL_CLOSE) {
cancel_pressed();
@@ -197,7 +197,7 @@ void AcceptDialog::_notification(int p_what) {
- }
+ }
}
void AcceptDialog::_builtin_text_entered(const String& p_text) {
@@ -206,7 +206,7 @@ void AcceptDialog::_builtin_text_entered(const String& p_text) {
}
void AcceptDialog::_ok_pressed() {
-
+
if (hide_on_ok)
hide();
ok_pressed();
@@ -214,7 +214,7 @@ void AcceptDialog::_ok_pressed() {
}
void AcceptDialog::_close_pressed() {
-
+
cancel_pressed();
}
@@ -223,7 +223,7 @@ String AcceptDialog::get_text() const {
return label->get_text();
}
void AcceptDialog::set_text(String p_text) {
-
+
label->set_text(p_text);
}
@@ -291,7 +291,7 @@ Button* AcceptDialog::add_cancel(const String &p_cancel) {
}
void AcceptDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("_ok"),&AcceptDialog::_ok_pressed);
ObjectTypeDB::bind_method(_MD("get_ok"),&AcceptDialog::get_ok);
ObjectTypeDB::bind_method(_MD("get_label"),&AcceptDialog::get_label);
@@ -321,11 +321,11 @@ void AcceptDialog::set_swap_ok_cancel(bool p_swap) {
}
AcceptDialog::AcceptDialog() {
-
+
int margin = get_constant("margin","Dialogs");
int button_margin = get_constant("button_margin","Dialogs");
-
-
+
+
label = memnew( Label );
label->set_anchor(MARGIN_RIGHT,ANCHOR_END);
label->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
@@ -345,8 +345,8 @@ AcceptDialog::AcceptDialog() {
hbc->add_child(ok);
hbc->add_spacer();
//add_child(ok);
-
-
+
+
ok->connect("pressed", this,"_ok");
set_as_toplevel(true);
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 7c06ded866..f256c49aee 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -142,7 +142,7 @@ public:
class ConfirmationDialog : public AcceptDialog {
-
+
OBJ_TYPE(ConfirmationDialog,AcceptDialog);
Button *cancel;
protected:
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 56b9260837..64fdfdfefe 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -51,7 +51,7 @@ void FileDialog::_notification(int p_what) {
refresh->set_icon(get_icon("reload"));
}
-
+
if (p_what==NOTIFICATION_DRAW) {
//RID ci = get_canvas_item();
@@ -117,13 +117,13 @@ Vector<String> FileDialog::get_selected_files() const {
};
void FileDialog::update_dir() {
-
+
dir->set_text(dir_access->get_current_dir());
}
void FileDialog::_dir_entered(String p_dir) {
-
-
+
+
dir_access->change_dir(p_dir);
file->set_text("");
invalidate();
@@ -132,13 +132,13 @@ void FileDialog::_dir_entered(String p_dir) {
void FileDialog::_file_entered(const String& p_file) {
- _action_pressed();
+ _action_pressed();
}
void FileDialog::_save_confirm_pressed() {
String f=dir_access->get_current_dir().plus_file(file->get_text());
emit_signal("file_selected",f);
- hide();
+ hide();
}
void FileDialog::_post_popup() {
@@ -158,7 +158,7 @@ void FileDialog::_post_popup() {
}
void FileDialog::_action_pressed() {
-
+
if (mode==MODE_OPEN_FILES) {
TreeItem *ti=tree->get_next_selected(NULL);
@@ -180,13 +180,11 @@ void FileDialog::_action_pressed() {
}
String f=dir_access->get_current_dir().plus_file(file->get_text());
-
- if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) {
+
+ if ((mode==MODE_OPEN_ANY || mode==MODE_OPEN_FILE) && dir_access->file_exists(f)) {
emit_signal("file_selected",f);
hide();
- }
-
- if (mode==MODE_OPEN_DIR) {
+ }else if (mode==MODE_OPEN_ANY || mode==MODE_OPEN_DIR) {
String path=dir_access->get_current_dir();
@@ -202,7 +200,7 @@ void FileDialog::_action_pressed() {
}
if (mode==MODE_SAVE_FILE) {
-
+
bool valid=false;
if (filter->get_selected()==filter->get_item_count()-1) {
@@ -263,7 +261,7 @@ void FileDialog::_action_pressed() {
confirm_save->set_text("File Exists, Overwrite?");
confirm_save->popup_centered(Size2(200,80));
} else {
-
+
emit_signal("file_selected",f);
hide();
@@ -279,51 +277,51 @@ void FileDialog::_cancel_pressed() {
}
void FileDialog::_tree_selected() {
-
+
TreeItem *ti=tree->get_selected();
if (!ti)
return;
Dictionary d=ti->get_metadata(0);
-
+
if (!d["dir"]) {
-
+
file->set_text(d["name"]);
}
-
+
}
void FileDialog::_tree_dc_selected() {
-
+
TreeItem *ti=tree->get_selected();
if (!ti)
return;
-
+
Dictionary d=ti->get_metadata(0);
if (d["dir"]) {
-
+
dir_access->change_dir(d["name"]);
- if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
+ if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR || mode==MODE_OPEN_ANY)
file->set_text("");
call_deferred("_update_file_list");
call_deferred("_update_dir");
} else {
-
+
_action_pressed();
}
}
void FileDialog::update_file_list() {
-
+
tree->clear();
dir_access->list_dir_begin();
-
+
TreeItem *root = tree->create_item();
Ref<Texture> folder = get_icon("folder");
List<String> files;
List<String> dirs;
-
+
bool isdir;
bool ishidden;
bool show_hidden = show_hidden_files;
@@ -340,12 +338,12 @@ void FileDialog::update_file_list() {
dirs.push_back(item);
}
}
-
+
dirs.sort_custom<NoCaseComparator>();
files.sort_custom<NoCaseComparator>();
-
+
while(!dirs.empty()) {
-
+
if (dirs.front()->get()!=".") {
TreeItem *ti=tree->create_item(root);
ti->set_text(0,dirs.front()->get()+"/");
@@ -356,23 +354,23 @@ void FileDialog::update_file_list() {
ti->set_metadata(0,d);
}
dirs.pop_front();
-
+
}
-
+
dirs.clear();
-
+
List<String> patterns;
// build filter
if (filter->get_selected()==filter->get_item_count()-1) {
-
- // match all
+
+ // match all
} else if (filters.size()>1 && filter->get_selected()==0) {
// match all filters
for (int i=0;i<filters.size();i++) {
-
+
String f=filters[i].get_slice(";",0);
for (int j=0;j<f.get_slice_count(",");j++) {
-
+
patterns.push_back(f.get_slice(",",j).strip_edges());
}
}
@@ -380,34 +378,34 @@ void FileDialog::update_file_list() {
int idx=filter->get_selected();
if (filters.size()>1)
idx--;
-
+
if (idx>=0 && idx<filters.size()) {
-
+
String f=filters[idx].get_slice(";",0);
for (int j=0;j<f.get_slice_count(",");j++) {
-
+
patterns.push_back(f.get_slice(",",j).strip_edges());
- }
+ }
}
}
String base_dir = dir_access->get_current_dir();
-
-
+
+
while(!files.empty()) {
-
+
bool match=patterns.empty();
-
+
for(List<String>::Element *E=patterns.front();E;E=E->next()) {
-
+
if (files.front()->get().matchn(E->get())) {
-
+
match=true;
break;
}
}
-
+
if (match) {
TreeItem *ti=tree->create_item(root);
ti->set_text(0,files.front()->get());
@@ -426,35 +424,35 @@ void FileDialog::update_file_list() {
d["name"]=files.front()->get();
d["dir"]=false;
ti->set_metadata(0,d);
-
+
if (file->get_text()==files.front()->get())
ti->select(0);
}
-
+
files.pop_front();
}
-
+
if (tree->get_root() && tree->get_root()->get_children())
tree->get_root()->get_children()->select(0);
-
+
files.clear();
-
+
}
void FileDialog::_filter_selected(int) {
-
+
update_file_list();
}
void FileDialog::update_filters() {
-
+
filter->clear();
-
+
if (filters.size()>1) {
String all_filters;
const int max_filters=5;
-
+
for(int i=0;i<MIN( max_filters, filters.size()) ;i++) {
String flt=filters[i].get_slice(";",0);
if (i>0)
@@ -464,11 +462,11 @@ void FileDialog::update_filters() {
if (max_filters<filters.size())
all_filters+=", ...";
-
+
filter->add_item("All Recognized ( "+all_filters+" )");
}
for(int i=0;i<filters.size();i++) {
-
+
String flt=filters[i].get_slice(";",0).strip_edges();
String desc=filters[i].get_slice(";",1).strip_edges();
if (desc.length())
@@ -476,46 +474,46 @@ void FileDialog::update_filters() {
else
filter->add_item("( "+flt+" )");
}
-
+
filter->add_item("All Files (*)");
-
+
}
void FileDialog::clear_filters() {
-
+
filters.clear();
update_filters();
invalidate();
}
void FileDialog::add_filter(const String& p_filter) {
-
+
filters.push_back(p_filter);
update_filters();
invalidate();
-
+
}
String FileDialog::get_current_dir() const {
-
- return dir->get_text();
+
+ return dir->get_text();
}
String FileDialog::get_current_file() const {
-
+
return file->get_text();
}
String FileDialog::get_current_path() const {
-
+
return dir->get_text().plus_file(file->get_text());
}
void FileDialog::set_current_dir(const String& p_dir) {
-
+
dir_access->change_dir(p_dir);
update_dir();
invalidate();
-
+
}
void FileDialog::set_current_file(const String& p_file) {
-
+
file->set_text(p_file);
update_dir();
invalidate();
@@ -525,18 +523,18 @@ void FileDialog::set_current_file(const String& p_file) {
file->grab_focus();
}
-
+
}
void FileDialog::set_current_path(const String& p_path) {
-
+
if (!p_path.size())
return;
int pos=MAX( p_path.find_last("/"), p_path.find_last("\\") );
if (pos==-1) {
-
+
set_current_file(p_path);
} else {
-
+
String dir=p_path.substr(0,pos);
String file=p_path.substr(pos+1,p_path.length());
set_current_dir(dir);
@@ -546,14 +544,15 @@ void FileDialog::set_current_path(const String& p_path) {
void FileDialog::set_mode(Mode p_mode) {
-
+
mode=p_mode;
switch(mode) {
-
+
case MODE_OPEN_FILE: get_ok()->set_text("Open"); set_title("Open a File"); makedir->hide(); break;
case MODE_OPEN_FILES: get_ok()->set_text("Open"); set_title("Open File(s)"); makedir->hide(); break;
- case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
case MODE_OPEN_DIR: get_ok()->set_text("Open"); set_title("Open a Directory"); makedir->show(); break;
+ case MODE_OPEN_ANY: get_ok()->set_text("Open"); set_title("Open a File or Directory"); makedir->show(); break;
+ case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
}
if (mode==MODE_OPEN_FILES) {
@@ -565,7 +564,7 @@ void FileDialog::set_mode(Mode p_mode) {
}
FileDialog::Mode FileDialog::get_mode() const {
-
+
return mode;
}
@@ -655,7 +654,7 @@ void FileDialog::_update_drives() {
drives->show();
for(int i=0;i<dir_access->get_drive_count();i++) {
- String d = dir_access->get_drive(i);
+ String d = dir_access->get_drive(i);
drives->add_item(dir_access->get_drive(i));
}
@@ -668,7 +667,7 @@ bool FileDialog::default_show_hidden_files=false;
void FileDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("_unhandled_input"),&FileDialog::_unhandled_input);
ObjectTypeDB::bind_method(_MD("_tree_selected"),&FileDialog::_tree_selected);
@@ -679,7 +678,7 @@ void FileDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_cancel_pressed"),&FileDialog::_cancel_pressed);
ObjectTypeDB::bind_method(_MD("_filter_selected"),&FileDialog::_filter_selected);
ObjectTypeDB::bind_method(_MD("_save_confirm_pressed"),&FileDialog::_save_confirm_pressed);
-
+
ObjectTypeDB::bind_method(_MD("clear_filters"),&FileDialog::clear_filters);
ObjectTypeDB::bind_method(_MD("add_filter","filter"),&FileDialog::add_filter);
ObjectTypeDB::bind_method(_MD("get_current_dir"),&FileDialog::get_current_dir);
@@ -710,6 +709,8 @@ void FileDialog::_bind_methods() {
BIND_CONSTANT( MODE_OPEN_FILE );
BIND_CONSTANT( MODE_OPEN_FILES );
BIND_CONSTANT( MODE_OPEN_DIR );
+ BIND_CONSTANT( MODE_OPEN_ANY );
+
BIND_CONSTANT( MODE_SAVE_FILE );
BIND_CONSTANT( ACCESS_RESOURCES );
@@ -742,7 +743,7 @@ FileDialog::FileDialog() {
mode=MODE_SAVE_FILE;
set_title("Save a File");
-
+
dir = memnew(LineEdit);
HBoxContainer *pathhb = memnew( HBoxContainer );
pathhb->add_child(dir);
@@ -760,17 +761,17 @@ FileDialog::FileDialog() {
makedir->set_text("Create Folder");
makedir->connect("pressed",this,"_make_dir");
pathhb->add_child(makedir);
-
+
vbc->add_margin_child("Path:",pathhb);
-
+
tree = memnew(Tree);
tree->set_hide_root(true);
vbc->add_margin_child("Directories & Files:",tree,true);
-
+
file = memnew(LineEdit);
//add_child(file);
vbc->add_margin_child("File:",file);
-
+
filter = memnew( OptionButton );
//add_child(filter);
@@ -781,7 +782,7 @@ FileDialog::FileDialog() {
access=ACCESS_RESOURCES;
_update_drives();
-
+
connect("confirmed", this,"_action_pressed");
//cancel->connect("pressed", this,"_cancel_pressed");
tree->connect("cell_selected", this,"_tree_selected",varray(),CONNECT_DEFERRED);
@@ -790,12 +791,12 @@ FileDialog::FileDialog() {
file->connect("text_entered", this,"_file_entered");
filter->connect("item_selected", this,"_filter_selected");
-
+
confirm_save = memnew( ConfirmationDialog );
confirm_save->set_as_toplevel(true);
add_child(confirm_save);
-
+
confirm_save->connect("confirmed", this,"_save_confirm_pressed");
makedialog = memnew( ConfirmationDialog );
@@ -828,12 +829,12 @@ FileDialog::FileDialog() {
invalidated=true;
if (register_func)
register_func(this);
-
+
}
FileDialog::~FileDialog() {
-
+
if (unregister_func)
unregister_func(this);
memdelete(dir_access);
@@ -877,3 +878,4 @@ LineEditFileChooser::LineEditFileChooser() {
dialog->connect("files_selected",this,"_chosen");
}
+
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index b71a157fa7..1fcf8387ce 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -41,9 +41,9 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class FileDialog : public ConfirmationDialog {
-
+
OBJ_TYPE( FileDialog, ConfirmationDialog );
-
+
public:
enum Access {
@@ -57,7 +57,8 @@ public:
MODE_OPEN_FILE,
MODE_OPEN_FILES,
MODE_OPEN_DIR,
- MODE_SAVE_FILE,
+ MODE_OPEN_ANY,
+ MODE_SAVE_FILE
};
typedef Ref<Texture> (*GetIconFunc)(const String&);
@@ -89,7 +90,7 @@ private:
ConfirmationDialog *confirm_save;
ToolButton *refresh;
-
+
Vector<String> filters;
@@ -97,13 +98,13 @@ private:
bool show_hidden_files;
bool invalidated;
-
+
void update_dir();
void update_file_list();
void update_filters();
-
+
void _tree_selected();
-
+
void _select_drive(int p_idx);
void _tree_dc_selected();
void _dir_entered(String p_dir);
@@ -122,18 +123,18 @@ private:
virtual void _post_popup();
protected:
-
+
void _notification(int p_what);
static void _bind_methods();
//bind helpers
public:
-
+
void clear_filters();
void add_filter(const String& p_filter);
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const;
-
+
String get_current_dir() const;
String get_current_file() const;
String get_current_path() const;
@@ -156,8 +157,8 @@ public:
static void set_default_show_hidden_files(bool p_show);
void invalidate();
-
- FileDialog();
+
+ FileDialog();
~FileDialog();
};
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 9472c589ca..9123194589 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -4,6 +4,12 @@
#include "scene/gui/box_container.h"
+#define ZOOM_SCALE 1.2
+
+#define MIN_ZOOM (((1/ZOOM_SCALE)/ZOOM_SCALE)/ZOOM_SCALE)
+#define MAX_ZOOM (1*ZOOM_SCALE*ZOOM_SCALE*ZOOM_SCALE)
+
+
bool GraphEditFilter::has_point(const Point2& p_point) const {
return ge->_filter_input(p_point);
@@ -85,9 +91,10 @@ void GraphEdit::_update_scroll_offset() {
if (!gn)
continue;
- Point2 pos=gn->get_offset();
+ Point2 pos=gn->get_offset()*zoom;
pos-=Point2(h_scroll->get_val(),v_scroll->get_val());
gn->set_pos(pos);
+ gn->set_scale(Vector2(zoom,zoom));
}
}
@@ -106,8 +113,8 @@ void GraphEdit::_update_scroll() {
continue;
Rect2 r;
- r.pos=gn->get_offset();
- r.size=gn->get_size();
+ r.pos=gn->get_offset()*zoom;
+ r.size=gn->get_size()*zoom;
screen = screen.merge(r);
}
@@ -193,10 +200,11 @@ void GraphEdit::_notification(int p_what) {
h_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,hmin.height);
h_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0);
- zoom_icon->set_texture( get_icon("Zoom", "EditorIcons"));
+// zoom_icon->set_texture( get_icon("Zoom", "EditorIcons"));
}
if (p_what==NOTIFICATION_DRAW) {
+ draw_style_box( get_stylebox("bg"),Rect2(Point2(),get_size()) );
VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true);
}
@@ -516,7 +524,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
for(int i=get_child_count()-1;i>=0;i--) {
GraphNode *gn=get_child(i)->cast_to<GraphNode>();
if (gn && gn->is_selected())
- gn->set_offset(gn->get_drag_from()+drag_accum);
+ gn->set_offset((gn->get_drag_from()*zoom+drag_accum)/zoom);
}
}
@@ -609,7 +617,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
if (b.button_index==BUTTON_LEFT && b.pressed) {
- GraphNode *gn;
+ GraphNode *gn = NULL;
for(int i=get_child_count()-1;i>=0;i--) {
gn=get_child(i)->cast_to<GraphNode>();
@@ -650,6 +658,8 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
} else {
if (_filter_input(Vector2(b.x,b.y)))
return;
+ if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
+ return;
box_selecting = true;
box_selecting_from = get_local_mouse_pos();
@@ -697,11 +707,13 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
}
if (b.button_index==BUTTON_WHEEL_UP && b.pressed) {
- sl_zoom->set_val(zoom/0.9);
+ //too difficult to get right
+ //set_zoom(zoom*ZOOM_SCALE);
}
if (b.button_index==BUTTON_WHEEL_DOWN && b.pressed) {
- sl_zoom->set_val(zoom*0.9);
+ //too difficult to get right
+ //set_zoom(zoom/ZOOM_SCALE);
}
}
@@ -725,21 +737,29 @@ void GraphEdit::clear_connections() {
void GraphEdit::set_zoom(float p_zoom) {
- if (p_zoom<0.01) p_zoom=0.01;
- if (p_zoom>4) p_zoom=4;
+ p_zoom=CLAMP(p_zoom,MIN_ZOOM,MAX_ZOOM);
if (zoom == p_zoom)
return;
+ zoom_minus->set_disabled(zoom==MIN_ZOOM);
+ zoom_plus->set_disabled(zoom==MAX_ZOOM);
+
+ Vector2 sbofs = (Vector2( h_scroll->get_val(), v_scroll->get_val() ) + get_size()/2)/zoom;
+
float prev_zoom = zoom;
zoom = p_zoom;
- for (int i = 0; i < get_child_count(); i++) {
- GraphNode *child = get_child(i)->cast_to<GraphNode>();
- if (!child)
- continue;
- Point2 ofs = child->get_offset() / prev_zoom * zoom;
- child->set_scale(Vector2(zoom,zoom));
- child->set_offset(ofs);
+ top_layer->update();
+
+ _update_scroll();
+
+ if (is_visible()) {
+
+ Vector2 ofs = sbofs*zoom - get_size()/2;
+ h_scroll->set_val( ofs.x );
+ v_scroll->set_val( ofs.y );
}
+
+
update();
}
@@ -772,6 +792,26 @@ Array GraphEdit::_get_connection_list() const {
}
return arr;
}
+
+
+
+void GraphEdit::_zoom_minus() {
+
+
+ set_zoom(zoom/ZOOM_SCALE);
+}
+void GraphEdit::_zoom_reset() {
+
+
+ set_zoom(1);
+}
+
+void GraphEdit::_zoom_plus() {
+
+ set_zoom(zoom*ZOOM_SCALE);
+}
+
+
void GraphEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node);
@@ -792,6 +832,9 @@ void GraphEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_top_layer_input"),&GraphEdit::_top_layer_input);
ObjectTypeDB::bind_method(_MD("_top_layer_draw"),&GraphEdit::_top_layer_draw);
ObjectTypeDB::bind_method(_MD("_scroll_moved"),&GraphEdit::_scroll_moved);
+ ObjectTypeDB::bind_method(_MD("_zoom_minus"),&GraphEdit::_zoom_minus);
+ ObjectTypeDB::bind_method(_MD("_zoom_reset"),&GraphEdit::_zoom_reset);
+ ObjectTypeDB::bind_method(_MD("_zoom_plus"),&GraphEdit::_zoom_plus);
ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event);
@@ -837,18 +880,25 @@ GraphEdit::GraphEdit() {
zoom = 1;
- HBoxContainer* tools = memnew( HBoxContainer );
- add_child(tools);
+ HBoxContainer *zoom_hb = memnew( HBoxContainer );
+ top_layer->add_child(zoom_hb);
+ zoom_hb->set_pos(Vector2(10,10));
+
+
+ zoom_minus = memnew( ToolButton );
+ zoom_hb->add_child(zoom_minus);
+ zoom_minus->connect("pressed",this,"_zoom_minus");
+ zoom_minus->set_icon(get_icon("minus"));
+
+ zoom_reset = memnew( ToolButton );
+ zoom_hb->add_child(zoom_reset);
+ zoom_reset->connect("pressed",this,"_zoom_reset");
+ zoom_reset->set_icon(get_icon("reset"));
+
+ zoom_plus = memnew( ToolButton );
+ zoom_hb->add_child(zoom_plus);
+ zoom_plus->connect("pressed",this,"_zoom_plus");
+ zoom_plus->set_icon(get_icon("more"));
- zoom_icon = memnew( TextureFrame );
- tools->add_child(zoom_icon);
- sl_zoom = memnew( HSlider );
- sl_zoom->set_min(0.01);
- sl_zoom->set_max(4);
- sl_zoom->set_val(1);
- sl_zoom->set_step(0.01);
- sl_zoom->connect("value_changed", this, "set_zoom");
- tools->add_child(sl_zoom);
- sl_zoom->set_custom_minimum_size(Size2(200,0));
}
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index fe9c36cee4..8a7721b9b5 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -4,7 +4,9 @@
#include "scene/gui/graph_node.h"
#include "scene/gui/scroll_bar.h"
#include "scene/gui/slider.h"
+#include "scene/gui/tool_button.h"
#include "texture_frame.h"
+
class GraphEdit;
class GraphEditFilter : public Control {
@@ -35,8 +37,15 @@ public:
};
private:
- TextureFrame* zoom_icon;
- HSlider* sl_zoom;
+
+ ToolButton *zoom_minus;
+ ToolButton *zoom_reset;
+ ToolButton *zoom_plus;
+
+ void _zoom_minus();
+ void _zoom_reset();
+ void _zoom_plus();
+
HScrollBar* h_scroll;
VScrollBar* v_scroll;
@@ -109,7 +118,7 @@ public:
void set_right_disconnects(bool p_enable);
bool is_right_disconnects_enabled() const;
-
+
Vector2 get_scroll_ofs() const;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 762afb158a..eef1bf79c4 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -591,4 +591,5 @@ void GraphNode::_bind_methods() {
GraphNode::GraphNode() {
show_close=false;
connpos_dirty=true;
+ set_stop_mouse(false);
}
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index f035cb7722..171dd94bfa 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -7,6 +7,7 @@ void ItemList::add_item(const String& p_item,const Ref<Texture>& p_texture,bool
Item item;
item.icon=p_texture;
+ item.icon_region=Rect2i();
item.text=p_item;
item.selectable=p_selectable;
item.selected=false;
@@ -23,6 +24,7 @@ void ItemList::add_icon_item(const Ref<Texture>& p_item,bool p_selectable){
Item item;
item.icon=p_item;
+ item.icon_region=Rect2i();
//item.text=p_item;
item.selectable=p_selectable;
item.selected=false;
@@ -79,6 +81,7 @@ void ItemList::set_item_icon(int p_idx,const Ref<Texture>& p_icon){
}
+
Ref<Texture> ItemList::get_item_icon(int p_idx) const{
ERR_FAIL_INDEX_V(p_idx,items.size(),Ref<Texture>());
@@ -87,6 +90,22 @@ Ref<Texture> ItemList::get_item_icon(int p_idx) const{
}
+void ItemList::set_item_icon_region(int p_idx,const Rect2& p_region) {
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].icon_region=p_region;
+ update();
+ shape_changed=true;
+}
+
+Rect2 ItemList::get_item_icon_region(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),Rect2());
+
+ return items[p_idx].icon_region;
+}
+
void ItemList::set_item_custom_bg_color(int p_idx,const Color& p_custom_bg_color) {
ERR_FAIL_INDEX(p_idx,items.size());
@@ -362,7 +381,15 @@ Size2 ItemList::get_min_icon_size() const {
return min_icon_size;
}
+Size2 ItemList::Item::get_icon_size() const {
+ if (icon.is_null())
+ return Size2();
+ if (icon_region.has_no_area())
+ return icon->get_size();
+
+ return icon_region.size;
+}
void ItemList::_input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT && p_event.mouse_button.pressed) {
@@ -702,7 +729,9 @@ void ItemList::_notification(int p_what) {
Size2 minsize;
if (items[i].icon.is_valid()) {
- minsize=items[i].icon->get_size();
+
+ minsize=items[i].get_icon_size();
+
if (min_icon_size.x!=0)
minsize.x = MAX(minsize.x,min_icon_size.x);
if (min_icon_size.y!=0)
@@ -826,40 +855,55 @@ void ItemList::_notification(int p_what) {
if (current_columns==1) {
rcache.size.width = width-rcache.pos.x;
}
- if (items[i].custom_bg.a>0.001) {
- Rect2 r=rcache;
- r.pos+=base_ofs;
- draw_rect(r,items[i].custom_bg);
- }
- if (items[i].selected) {
- Rect2 r=rcache;
- r.pos+=base_ofs;
- r.pos.x-=sbsel->get_margin(MARGIN_LEFT);
- r.size.x+=sbsel->get_margin(MARGIN_LEFT)+sbsel->get_margin(MARGIN_RIGHT);
- r.pos.y-=sbsel->get_margin(MARGIN_TOP);
- r.size.y+=sbsel->get_margin(MARGIN_TOP)+sbsel->get_margin(MARGIN_BOTTOM);
+ Rect2 r=rcache;
+ r.pos+=base_ofs;
- draw_style_box(sbsel,r);
+ // Use stylebox to dimension potential bg color, even if not selected
+ r.pos.x-=sbsel->get_margin(MARGIN_LEFT);
+ r.size.x+=sbsel->get_margin(MARGIN_LEFT)+sbsel->get_margin(MARGIN_RIGHT);
+ r.pos.y-=sbsel->get_margin(MARGIN_TOP);
+ r.size.y+=sbsel->get_margin(MARGIN_TOP)+sbsel->get_margin(MARGIN_BOTTOM);
+ if (items[i].selected) {
+ draw_style_box(sbsel,r);
+ }
+ if (items[i].custom_bg.a>0.001) {
+ r.pos.x+=2;
+ r.size.x-=4;
+ r.pos.y+=2;
+ r.size.y-=4;
+ draw_rect(r,items[i].custom_bg);
}
Vector2 text_ofs;
if (items[i].icon.is_valid()) {
+ Size2 icon_size = items[i].get_icon_size();
+
Vector2 icon_ofs;
if (min_icon_size!=Vector2()) {
- icon_ofs = (min_icon_size - items[i].icon->get_size())/2;
+ icon_ofs = (min_icon_size - icon_size)/2;
}
+ Point2 pos = items[i].rect_cache.pos + icon_ofs + base_ofs;
+
if (icon_mode==ICON_MODE_TOP) {
- draw_texture(items[i].icon,icon_ofs+items[i].rect_cache.pos+Vector2(items[i].rect_cache.size.width/2-items[i].icon->get_width()/2,0).floor()+base_ofs);
- text_ofs.y = MAX(items[i].icon->get_height(),min_icon_size.y)+icon_margin;
+
+ pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width)/2);
+ text_ofs.y = MAX(icon_size.height, min_icon_size.y) + icon_margin;
} else {
- draw_texture(items[i].icon,icon_ofs+items[i].rect_cache.pos+Vector2(0,items[i].rect_cache.size.height/2-items[i].icon->get_height()/2).floor()+base_ofs);
- text_ofs.x = MAX(items[i].icon->get_width(),min_icon_size.x)+icon_margin;
+
+ pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height)/2);
+ text_ofs.x = MAX(icon_size.width, min_icon_size.x) + icon_margin;
}
+
+ if (items[i].icon_region.has_no_area())
+ draw_texture(items[i].icon, pos);
+ else
+ draw_texture_rect_region(items[i].icon, Rect2(pos, icon_size), items[i].icon_region);
+
}
if (items[i].tag_icon.is_valid()) {
@@ -1058,6 +1102,9 @@ void ItemList::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon:Texture"),&ItemList::set_item_icon);
ObjectTypeDB::bind_method(_MD("get_item_icon:Texture","idx"),&ItemList::get_item_icon);
+ ObjectTypeDB::bind_method(_MD("set_item_icon_region","idx","rect"),&ItemList::set_item_icon_region);
+ ObjectTypeDB::bind_method(_MD("get_item_icon_region","idx"),&ItemList::get_item_icon_region);
+
ObjectTypeDB::bind_method(_MD("set_item_selectable","idx","selectable"),&ItemList::set_item_selectable);
ObjectTypeDB::bind_method(_MD("is_item_selectable","idx"),&ItemList::is_item_selectable);
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index bd3cf6484e..c9c575fd54 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -22,6 +22,7 @@ private:
struct Item {
Ref<Texture> icon;
+ Rect2i icon_region;
Ref<Texture> tag_icon;
String text;
bool selectable;
@@ -31,9 +32,10 @@ private:
String tooltip;
Color custom_bg;
-
Rect2 rect_cache;
+ Size2 get_icon_size() const;
+
bool operator<(const Item& p_another) const { return text<p_another.text; }
};
@@ -76,6 +78,9 @@ public:
void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
Ref<Texture> get_item_icon(int p_idx) const;
+ void set_item_icon_region(int p_idx,const Rect2& p_region);
+ Rect2 get_item_icon_region(int p_idx) const;
+
void set_item_selectable(int p_idx,bool p_selectable);
bool is_item_selectable(int p_idx) const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index fdced3f62f..3953ef06a5 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -36,20 +36,20 @@ void LineEdit::_input_event(InputEvent p_event) {
switch(p_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &b = p_event.mouse_button;
if (b.button_index!=1)
break;
-
+
if (b.pressed) {
-
+
set_cursor_at_pixel_pos(b.x);
-
+
if (b.doubleclick) {
-
+
selection.enabled=true;
selection.begin=0;
selection.end=text.length();
@@ -57,9 +57,9 @@ void LineEdit::_input_event(InputEvent p_event) {
}
selection.drag_attempt=false;
-
+
if ((cursor_pos<selection.begin) || (cursor_pos>selection.end) || !selection.enabled) {
-
+
selection_clear();
selection.cursor_start=cursor_pos;
selection.creating=true;
@@ -67,45 +67,45 @@ void LineEdit::_input_event(InputEvent p_event) {
selection.drag_attempt=true;
}
-
+
// if (!editable)
// non_editable_clicked_signal.call();
update();
-
+
} else {
-
+
if ( (!selection.creating) && (!selection.doubleclick)) {
selection_clear();
}
selection.creating=false;
selection.doubleclick=false;
- // notify to show soft keyboard
- notification(NOTIFICATION_FOCUS_ENTER);
+ if (OS::get_singleton()->has_virtual_keyboard())
+ OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect());
}
-
- update();
+
+ update();
} break;
case InputEvent::MOUSE_MOTION: {
-
+
const InputEventMouseMotion& m=p_event.mouse_motion;
-
+
if (m.button_mask&1) {
-
+
if (selection.creating) {
set_cursor_at_pixel_pos(m.x);
selection_fill_at_cursor();
}
}
-
+
} break;
case InputEvent::KEY: {
-
+
const InputEventKey &k =p_event.key;
-
+
if (!k.pressed)
return;
- unsigned int code = k.scancode;
+ unsigned int code = k.scancode;
if (k.mod.command) {
@@ -230,8 +230,9 @@ void LineEdit::_input_event(InputEvent p_event) {
case KEY_RETURN: {
emit_signal( "text_entered",text );
- // notify to hide soft keyboard
- notification(NOTIFICATION_FOCUS_EXIT);
+ if (OS::get_singleton()->has_virtual_keyboard())
+ OS::get_singleton()->hide_virtual_keyboard();
+
return;
} break;
@@ -345,11 +346,11 @@ void LineEdit::_input_event(InputEvent p_event) {
}
-
+
return;
-
+
} break;
-
+
}
}
@@ -404,30 +405,30 @@ void LineEdit::drop_data(const Point2& p_point,const Variant& p_data){
void LineEdit::_notification(int p_what) {
-
+
switch(p_what) {
-
+
case NOTIFICATION_RESIZED: {
-
+
set_cursor_pos( get_cursor_pos() );
-
+
} break;
case NOTIFICATION_DRAW: {
-
+
int width,height;
-
+
Size2 size=get_size();
width=size.width;
height=size.height;
-
+
RID ci = get_canvas_item();
-
+
Ref<StyleBox> style = get_stylebox("normal");
if (!is_editable())
style=get_stylebox("read_only");
Ref<Font> font=get_font("font");
-
+
style->draw( ci, Rect2( Point2(), size ) );
if (has_focus()) {
@@ -438,7 +439,7 @@ void LineEdit::_notification(int p_what) {
int x_ofs=0;
switch (align) {
-
+
case ALIGN_FILL:
case ALIGN_LEFT: {
@@ -456,19 +457,19 @@ void LineEdit::_notification(int p_what) {
int ofs_max=width-style->get_minimum_size().width;
int char_ofs=window_pos;
-
+
int y_area=height-style->get_minimum_size().height;
int y_ofs=style->get_offset().y;
-
+
int font_ascent=font->get_ascent();
-
+
Color selection_color=get_color("selection_color");
Color font_color=get_color("font_color");
Color font_color_selected=get_color("font_color_selected");
Color cursor_color=get_color("cursor_color");
-
+
while(true) {
-
+
//end of string, break!
if (char_ofs>=text.length())
break;
@@ -476,32 +477,32 @@ void LineEdit::_notification(int p_what) {
CharType cchar=pass?'*':text[char_ofs];
CharType next=pass?'*':text[char_ofs+1];
int char_width=font->get_char_size( cchar,next ).width;
-
+
// end of widget, break!
if ((x_ofs + char_width) > ofs_max)
break;
-
-
+
+
bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end;
-
+
if (selected)
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, y_area)), selection_color);
-
+
font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color);
-
+
if (char_ofs==cursor_pos && has_focus())
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
-
+
x_ofs+=char_width;
char_ofs++;
}
if (char_ofs==cursor_pos && has_focus()) //may be at the end
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
- Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
-
+ Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
+
} break;
case NOTIFICATION_FOCUS_ENTER: {
@@ -520,15 +521,15 @@ void LineEdit::_notification(int p_what) {
}
void LineEdit::copy_text() {
-
+
if(selection.enabled) {
-
+
OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
}
}
void LineEdit::cut_text() {
-
+
if(selection.enabled) {
undo_text = text;
OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
@@ -537,9 +538,9 @@ void LineEdit::cut_text() {
}
void LineEdit::paste_text() {
-
+
String paste_buffer = OS::get_singleton()->get_clipboard();
-
+
if(paste_buffer != "") {
if(selection.enabled) selection_delete();
@@ -549,28 +550,28 @@ void LineEdit::paste_text() {
_change_notify("text");
}
-
+
}
void LineEdit::shift_selection_check_pre(bool p_shift) {
-
+
if (!selection.old_shift && p_shift) {
selection.cursor_start=cursor_pos;
}
if (!p_shift)
selection_clear();
-
+
}
void LineEdit::shift_selection_check_post(bool p_shift) {
-
+
if (p_shift)
selection_fill_at_cursor();
}
void LineEdit::set_cursor_at_pixel_pos(int p_x) {
-
+
Ref<Font> font = get_font("font");
int ofs = window_pos;
Ref<StyleBox> style = get_stylebox("normal");
@@ -578,10 +579,10 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
Size2 size = get_size();
switch (align) {
-
+
case ALIGN_FILL:
case ALIGN_LEFT: {
-
+
pixel_ofs = int(style->get_offset().x);
} break;
case ALIGN_CENTER: {
@@ -596,30 +597,30 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
while (ofs<text.length()) {
-
+
int char_w = 0;
if (font != NULL) {
char_w = font->get_char_size(text[ofs]).width;
}
pixel_ofs+=char_w;
-
+
if (pixel_ofs > p_x) { //found what we look for
-
-
+
+
if ( (pixel_ofs-p_x) < (char_w >> 1 ) ) {
-
+
ofs+=1;
}
-
+
break;
}
-
-
+
+
ofs++;
}
-
+
set_cursor_pos( ofs );
-
+
/*
int new_cursor_pos=p_x;
int charwidth=draw_area->get_font_char_width(' ',0);
@@ -630,29 +631,29 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
void LineEdit::delete_char() {
-
+
if ((text.length()<=0) || (cursor_pos==0)) return;
-
+
Ref<Font> font = get_font("font");
if (font != NULL) {
cached_width -= font->get_char_size(text[cursor_pos - 1]).width;
}
-
+
text.erase( cursor_pos-1, 1 );
-
+
set_cursor_pos(get_cursor_pos()-1);
-
+
if (cursor_pos==window_pos) {
-
+
// set_window_pos(cursor_pos-get_window_length());
}
-
+
emit_signal("text_changed",text);
_change_notify("text");
}
void LineEdit::set_text(String p_text) {
-
+
clear_internal();
append_at_cursor(p_text);
update();
@@ -661,86 +662,86 @@ void LineEdit::set_text(String p_text) {
}
void LineEdit::clear() {
-
+
clear_internal();
}
String LineEdit::get_text() const {
-
+
return text;
}
void LineEdit::set_cursor_pos(int p_pos) {
-
+
if (p_pos>(int)text.length())
p_pos=text.length();
-
+
if(p_pos<0)
p_pos=0;
-
-
-
+
+
+
cursor_pos=p_pos;
-
+
// if (cursor_pos>(window_pos+get_window_length())) {
// set_window_pos(cursor_pos-get_window_lengt//h());
// }
-
+
if (!is_inside_tree()) {
-
+
window_pos=cursor_pos;
return;
}
-
+
Ref<StyleBox> style = get_stylebox("normal");
Ref<Font> font=get_font("font");
-
+
if (cursor_pos<window_pos) {
/* Adjust window if cursor goes too much to the left */
set_window_pos(cursor_pos);
} else if (cursor_pos>window_pos) {
/* Adjust window if cursor goes too much to the right */
int window_width=get_size().width-style->get_minimum_size().width;
-
+
if (window_width<0)
return;
int width_to_cursor=0;
int wp=window_pos;
-
+
if (font != NULL) {
for (int i=window_pos;i<cursor_pos;i++)
width_to_cursor+=font->get_char_size( text[i] ).width;
-
+
while (width_to_cursor >= window_width && wp < text.length()) {
width_to_cursor -= font->get_char_size(text[wp]).width;
wp++;
}
}
-
+
if (wp!=window_pos)
set_window_pos( wp );
-
+
}
update();
}
int LineEdit::get_cursor_pos() const {
-
+
return cursor_pos;
}
void LineEdit::set_window_pos(int p_pos) {
-
+
window_pos=p_pos;
if (window_pos<0) window_pos=0;
}
void LineEdit::append_at_cursor(String p_text) {
-
-
+
+
if ( ( max_length <= 0 ) || (text.length()+p_text.length() <= max_length)) {
-
+
undo_text = text;
Ref<Font> font = get_font("font");
@@ -760,7 +761,7 @@ void LineEdit::append_at_cursor(String p_text) {
}
void LineEdit::clear_internal() {
-
+
cached_width = 0;
cursor_pos=0;
window_pos=0;
@@ -770,21 +771,21 @@ void LineEdit::clear_internal() {
}
Size2 LineEdit::get_minimum_size() const {
-
+
Ref<StyleBox> style = get_stylebox("normal");
Ref<Font> font=get_font("font");
-
+
Size2 min=style->get_minimum_size();
min.height+=font->get_height();
min.width+=get_constant("minimum_spaces")*font->get_char_size(' ').x;
-
+
return min;
}
/* selection */
void LineEdit::selection_clear() {
-
+
selection.begin=0;
selection.end=0;
selection.cursor_start=0;
@@ -797,9 +798,9 @@ void LineEdit::selection_clear() {
void LineEdit::selection_delete() {
-
+
if (selection.enabled) {
-
+
undo_text = text;
if (text.size() > 0)
@@ -817,80 +818,80 @@ void LineEdit::selection_delete() {
text.erase(selection.begin,selection.end-selection.begin);
cursor_pos-=CLAMP( cursor_pos-selection.begin, 0, selection.end-selection.begin);
-
+
if (cursor_pos>=text.length()) {
-
+
cursor_pos=text.length();
}
if (window_pos>cursor_pos) {
-
+
window_pos=cursor_pos;
}
-
+
emit_signal("text_changed",text);
_change_notify("text");
};
-
+
selection_clear();
}
void LineEdit::set_max_length(int p_max_length) {
-
+
ERR_FAIL_COND(p_max_length<0);
max_length = p_max_length;
set_text(text);
}
int LineEdit::get_max_length() const {
-
+
return max_length;
}
void LineEdit::selection_fill_at_cursor() {
-
+
int aux;
-
+
selection.begin=cursor_pos;
selection.end=selection.cursor_start;
-
+
if (selection.end<selection.begin) {
aux=selection.end;
selection.end=selection.begin;
selection.begin=aux;
}
-
+
selection.enabled=(selection.begin!=selection.end);
}
void LineEdit::select_all() {
-
+
if (!text.length())
return;
-
+
selection.begin=0;
selection.end=text.length();
selection.enabled=true;
update();
-
+
}
void LineEdit::set_editable(bool p_editable) {
-
+
editable=p_editable;
update();
}
bool LineEdit::is_editable() const {
-
+
return editable;
}
void LineEdit::set_secret(bool p_secret) {
-
+
pass=p_secret;
update();
}
bool LineEdit::is_secret() const {
-
+
return pass;
}
@@ -927,24 +928,24 @@ bool LineEdit::is_text_field() const {
}
void LineEdit::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align);
ObjectTypeDB::bind_method(_MD("get_align"), &LineEdit::get_align);
ObjectTypeDB::bind_method(_MD("_input_event"),&LineEdit::_input_event);
- ObjectTypeDB::bind_method(_MD("clear"),&LineEdit::clear);
- ObjectTypeDB::bind_method(_MD("select_all"),&LineEdit::select_all);
+ ObjectTypeDB::bind_method(_MD("clear"),&LineEdit::clear);
+ ObjectTypeDB::bind_method(_MD("select_all"),&LineEdit::select_all);
ObjectTypeDB::bind_method(_MD("set_text","text"),&LineEdit::set_text);
- ObjectTypeDB::bind_method(_MD("get_text"),&LineEdit::get_text);
+ ObjectTypeDB::bind_method(_MD("get_text"),&LineEdit::get_text);
ObjectTypeDB::bind_method(_MD("set_cursor_pos","pos"),&LineEdit::set_cursor_pos);
- ObjectTypeDB::bind_method(_MD("get_cursor_pos"),&LineEdit::get_cursor_pos);
+ ObjectTypeDB::bind_method(_MD("get_cursor_pos"),&LineEdit::get_cursor_pos);
ObjectTypeDB::bind_method(_MD("set_max_length","chars"),&LineEdit::set_max_length);
- ObjectTypeDB::bind_method(_MD("get_max_length"),&LineEdit::get_max_length);
+ ObjectTypeDB::bind_method(_MD("get_max_length"),&LineEdit::get_max_length);
ObjectTypeDB::bind_method(_MD("append_at_cursor","text"),&LineEdit::append_at_cursor);
ObjectTypeDB::bind_method(_MD("set_editable","enabled"),&LineEdit::set_editable);
- ObjectTypeDB::bind_method(_MD("is_editable"),&LineEdit::is_editable);
+ ObjectTypeDB::bind_method(_MD("is_editable"),&LineEdit::is_editable);
ObjectTypeDB::bind_method(_MD("set_secret","enabled"),&LineEdit::set_secret);
- ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret);
+ ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret);
ObjectTypeDB::bind_method(_MD("select","from","to"),&LineEdit::select,DEFVAL(0),DEFVAL(-1));
ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) );
@@ -963,25 +964,25 @@ void LineEdit::_bind_methods() {
}
LineEdit::LineEdit() {
-
+
align = ALIGN_LEFT;
cached_width = 0;
cursor_pos=0;
window_pos=0;
max_length = 0;
pass=false;
-
+
selection_clear();
set_focus_mode( FOCUS_ALL );
editable=true;
set_default_cursor_shape(CURSOR_IBEAM);
set_stop_mouse(true);
-
-
+
+
}
LineEdit::~LineEdit() {
-
-
+
+
}
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index bf6459361a..207c6b115b 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -34,7 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class LineEdit : public Control {
-
+
OBJ_TYPE( LineEdit, Control );
public:
@@ -50,18 +50,18 @@ private:
bool editable;
bool pass;
-
+
String undo_text;
String text;
-
+
int cursor_pos;
int window_pos;
int max_length; // 0 for no maximum
int cached_width;
-
+
struct Selection {
-
+
int begin;
int end;
int cursor_start;
@@ -71,41 +71,41 @@ private:
bool doubleclick;
bool drag_attempt;
} selection;
-
+
void shift_selection_check_pre(bool);
void shift_selection_check_post(bool);
-
+
void selection_clear();
void selection_fill_at_cursor();
void selection_delete();
void set_window_pos(int p_pos);
-
+
void set_cursor_at_pixel_pos(int p_x);
-
+
void clear_internal();
void changed_internal();
-
+
void copy_text();
void cut_text();
void paste_text();
-
+
void _input_event(InputEvent p_event);
void _notification(int p_what);
-
-protected:
- static void _bind_methods();
+
+protected:
+ static void _bind_methods();
public:
void set_align(Align p_align);
Align get_align() const;
-
+
virtual Variant get_drag_data(const Point2& p_point);
virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const;
virtual void drop_data(const Point2& p_point,const Variant& p_data);
-
+
void select_all();
-
+
void delete_char();
void set_text(String p_text);
String get_text() const;
@@ -115,11 +115,11 @@ public:
int get_max_length() const;
void append_at_cursor(String p_text);
void clear();
-
-
+
+
void set_editable(bool p_editable);
bool is_editable() const;
-
+
void set_secret(bool p_secret);
bool is_secret() const;
@@ -130,7 +130,7 @@ public:
virtual bool is_text_field() const;
LineEdit();
~LineEdit();
-
+
};
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
new file mode 100644
index 0000000000..007d0a709e
--- /dev/null
+++ b/scene/gui/link_button.cpp
@@ -0,0 +1,124 @@
+#include "link_button.h"
+
+
+void LinkButton::set_text(const String& p_text) {
+
+ text=p_text;
+ update();
+ minimum_size_changed();
+}
+
+String LinkButton::get_text() const {
+ return text;
+}
+
+void LinkButton::set_underline_mode(UnderlineMode p_underline_mode) {
+
+ underline_mode=p_underline_mode;
+ update();
+}
+
+LinkButton::UnderlineMode LinkButton::get_underline_mode() const {
+
+ return underline_mode;
+}
+
+
+Size2 LinkButton::get_minimum_size() const {
+
+ return get_font("font")->get_string_size( text );
+}
+
+
+
+void LinkButton::_notification(int p_what) {
+
+ switch( p_what ) {
+
+ case NOTIFICATION_DRAW: {
+
+
+ RID ci = get_canvas_item();
+ Size2 size=get_size();
+ Color color;
+ bool do_underline=false;
+
+ //print_line(get_text()+": "+itos(is_flat())+" hover "+itos(get_draw_mode()));
+
+ switch( get_draw_mode() ) {
+
+ case DRAW_NORMAL: {
+
+ color=get_color("font_color");
+ do_underline=underline_mode==UNDERLINE_MODE_ALWAYS;
+ } break;
+ case DRAW_PRESSED: {
+
+ if (has_color("font_color_pressed"))
+ color=get_color("font_color_pressed");
+ else
+ color=get_color("font_color");
+
+ do_underline=true;
+
+ } break;
+ case DRAW_HOVER: {
+
+ color=get_color("font_color_hover");
+ do_underline=true;
+
+ } break;
+ case DRAW_DISABLED: {
+
+ color=get_color("font_color_disabled");
+ do_underline=underline_mode==UNDERLINE_MODE_ALWAYS;
+
+ } break;
+ }
+
+ if (has_focus()) {
+
+ Ref<StyleBox> style = get_stylebox("focus");
+ style->draw(ci,Rect2(Point2(),size));
+ }
+
+ Ref<Font> font=get_font("font");
+
+ draw_string(font,Vector2(0,font->get_ascent()),text,color);
+
+
+
+ if (do_underline) {
+ int underline_spacing = get_constant("underline_spacing");
+ int width = font->get_string_size(text).width;
+ int y = font->get_ascent()+underline_spacing;
+
+ draw_line(Vector2(0,y),Vector2(width,y),color);
+ }
+
+ } break;
+ }
+}
+
+void LinkButton::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_text","text"),&LinkButton::set_text);
+ ObjectTypeDB::bind_method(_MD("get_text"),&LinkButton::get_text);
+
+ ObjectTypeDB::bind_method(_MD("set_underline_mode","underline_mode"),&LinkButton::set_underline_mode);
+ ObjectTypeDB::bind_method(_MD("get_underline_mode"),&LinkButton::get_underline_mode);
+
+
+ BIND_CONSTANT( UNDERLINE_MODE_ALWAYS );
+ BIND_CONSTANT( UNDERLINE_MODE_ON_HOVER );
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::STRING,"text"), _SCS("set_text"), _SCS("get_text"));
+ ADD_PROPERTYNZ(PropertyInfo(Variant::INT,"underline",PROPERTY_HINT_ENUM,"Always,On Hover"), _SCS("set_underline_mode"), _SCS("get_underline_mode"));
+
+}
+
+LinkButton::LinkButton() {
+ underline_mode=UNDERLINE_MODE_ALWAYS;
+ set_focus_mode(FOCUS_NONE);
+ set_default_cursor_shape(CURSOR_POINTING_HAND);
+}
diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h
new file mode 100644
index 0000000000..d218482337
--- /dev/null
+++ b/scene/gui/link_button.h
@@ -0,0 +1,40 @@
+#ifndef LINKBUTTON_H
+#define LINKBUTTON_H
+
+
+#include "scene/gui/base_button.h"
+#include "scene/resources/bit_mask.h"
+
+class LinkButton : public BaseButton {
+
+ OBJ_TYPE( LinkButton, BaseButton );
+public:
+
+ enum UnderlineMode {
+ UNDERLINE_MODE_ALWAYS,
+ UNDERLINE_MODE_ON_HOVER
+ };
+private:
+ String text;
+ UnderlineMode underline_mode;
+
+protected:
+
+ virtual Size2 get_minimum_size() const;
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+
+ void set_text(const String& p_text);
+ String get_text() const;
+
+ void set_underline_mode(UnderlineMode p_underline_mode);
+ UnderlineMode get_underline_mode() const;
+
+ LinkButton();
+};
+
+VARIANT_ENUM_CAST( LinkButton::UnderlineMode );
+
+#endif // LINKBUTTON_H
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 26540843de..cb8806e2ef 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -76,18 +76,18 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) {
void MenuButton::pressed() {
-
+
emit_signal("about_to_show");
Size2 size=get_size();
Point2 gp = get_global_pos();
popup->set_global_pos( gp + Size2( 0, size.height ) );
- popup->set_size( Size2( size.width, 0) );
+ popup->set_size( Size2( size.width, 0) );
popup->set_parent_rect( Rect2(Point2(gp-popup->get_global_pos()),get_size()));
popup->popup();
popup->call_deferred("grab_click_focus");
popup->set_invalidate_click_until_motion();
-
+
}
void MenuButton::_input_event(InputEvent p_event) {
@@ -111,7 +111,7 @@ void MenuButton::_input_event(InputEvent p_event) {
}
PopupMenu *MenuButton::get_popup() {
-
+
return popup;
}
@@ -136,7 +136,7 @@ void MenuButton::_bind_methods() {
ADD_SIGNAL( MethodInfo("about_to_show") );
}
MenuButton::MenuButton() {
-
+
set_flat(true);
set_focus_mode(FOCUS_NONE);
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 2df632811f..650e4aba5c 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -35,24 +35,24 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class MenuButton : public Button {
-
+
OBJ_TYPE( MenuButton, Button );
bool clicked;
PopupMenu *popup;
- virtual void pressed();
+ virtual void pressed();
void _unhandled_key_input(InputEvent p_event);
Array _get_items() const;
void _set_items(const Array& p_items);
void _input_event(InputEvent p_event);
-protected:
-
+protected:
+
- static void _bind_methods();
+ static void _bind_methods();
public:
-
+
PopupMenu *get_popup();
MenuButton();
~MenuButton();
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 5c8e5a7381..587a68ae37 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -55,7 +55,7 @@ void OptionButton::_notification(int p_what) {
Ref<Texture> arrow = Control::get_icon("arrow");
Ref<StyleBox> normal = get_stylebox("normal" );
- Size2 size = get_size();
+ Size2 size = get_size();
Point2 ofs( size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height-arrow->get_height())/2)));
arrow->draw(ci,ofs);
@@ -66,7 +66,7 @@ void OptionButton::_notification(int p_what) {
void OptionButton::_selected(int p_which) {
-
+
int selid = -1;
for (int i=0;i<popup->get_item_count();i++) {
@@ -89,39 +89,39 @@ void OptionButton::_selected(int p_which) {
void OptionButton::pressed() {
-
+
Size2 size=get_size();
popup->set_global_pos( get_global_pos() + Size2( 0, size.height ) );
popup->set_size( Size2( size.width, 0) );
-
+
popup->popup();
}
void OptionButton::add_icon_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID) {
-
- popup->add_icon_check_item( p_icon, p_label, p_ID );
+
+ popup->add_icon_check_item( p_icon, p_label, p_ID );
if (popup->get_item_count()==1)
select(0);
}
void OptionButton::add_item(const String& p_label,int p_ID) {
-
- popup->add_check_item( p_label, p_ID );
+
+ popup->add_check_item( p_label, p_ID );
if (popup->get_item_count()==1)
- select(0);
+ select(0);
}
void OptionButton::set_item_text(int p_idx,const String& p_text) {
-
+
popup->set_item_text(p_idx,p_text);
-
+
}
void OptionButton::set_item_icon(int p_idx,const Ref<Texture>& p_icon) {
-
+
popup->set_item_icon(p_idx,p_icon);
-
+
}
void OptionButton::set_item_ID(int p_idx,int p_ID) {
-
+
popup->set_item_ID(p_idx,p_ID);
}
@@ -136,17 +136,17 @@ void OptionButton::set_item_disabled(int p_idx,bool p_disabled) {
}
String OptionButton::get_item_text(int p_idx) const {
-
+
return popup->get_item_text(p_idx);
}
Ref<Texture> OptionButton::get_item_icon(int p_idx) const {
-
+
return popup->get_item_icon(p_idx);
}
int OptionButton::get_item_ID(int p_idx) const {
-
+
return popup->get_item_ID(p_idx);
}
Variant OptionButton::get_item_metadata(int p_idx) const {
@@ -161,17 +161,17 @@ bool OptionButton::is_item_disabled(int p_idx) const {
int OptionButton::get_item_count() const {
-
+
return popup->get_item_count();
}
void OptionButton::add_separator() {
-
+
popup->add_separator();
}
void OptionButton::clear() {
-
+
popup->clear();
set_text("");
current=-1;
@@ -210,12 +210,12 @@ void OptionButton::_select_int(int p_which) {
}
void OptionButton::select(int p_idx) {
-
+
_select(p_idx,false);
}
int OptionButton::get_selected() const {
-
+
return current;
}
@@ -286,9 +286,9 @@ void OptionButton::get_translatable_strings(List<String> *p_strings) const {
void OptionButton::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("_selected"),&OptionButton::_selected);
-
+
ObjectTypeDB::bind_method(_MD("add_item","label","id"),&OptionButton::add_item,DEFVAL(-1));
ObjectTypeDB::bind_method(_MD("add_icon_item","texture:Texture","label","id"),&OptionButton::add_icon_item);
ObjectTypeDB::bind_method(_MD("set_item_text","idx","text"),&OptionButton::set_item_text);
@@ -305,7 +305,7 @@ void OptionButton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_separator"),&OptionButton::add_separator);
ObjectTypeDB::bind_method(_MD("clear"),&OptionButton::clear);
ObjectTypeDB::bind_method(_MD("select","idx"),&OptionButton::select);
- ObjectTypeDB::bind_method(_MD("get_selected"),&OptionButton::get_selected);
+ ObjectTypeDB::bind_method(_MD("get_selected"),&OptionButton::get_selected);
ObjectTypeDB::bind_method(_MD("get_selected_ID"),&OptionButton::get_selected_ID);
ObjectTypeDB::bind_method(_MD("get_selected_metadata"),&OptionButton::get_selected_metadata);
ObjectTypeDB::bind_method(_MD("remove_item","idx"),&OptionButton::remove_item);
@@ -320,23 +320,23 @@ void OptionButton::_bind_methods() {
}
OptionButton::OptionButton() {
-
-
+
+
popup = memnew( PopupMenu );
popup->hide();
popup->set_as_toplevel(true);
add_child(popup);
popup->connect("item_pressed", this,"_selected");
-
+
current=-1;
set_text_align(ALIGN_LEFT);
}
OptionButton::~OptionButton() {
-
-
+
+
}
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 34e2bdd384..70ebc66a46 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -35,12 +35,12 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class OptionButton : public Button {
-
+
OBJ_TYPE( OptionButton, Button );
-
+
PopupMenu *popup;
int current;
-
+
void _selected(int p_which);
void _select(int p_which,bool p_emit=false);
void _select_int(int p_which);
@@ -55,10 +55,10 @@ protected:
void _notification(int p_what);
static void _bind_methods();
public:
-
+
void add_icon_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1);
void add_item(const String& p_label,int p_ID=-1);
-
+
void set_item_text(int p_idx,const String& p_text);
void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
void set_item_ID(int p_idx,int p_ID);
@@ -73,11 +73,11 @@ public:
int get_item_count() const;
-
+
void add_separator();
-
+
void clear();
-
+
void select(int p_idx);
int get_selected() const;
int get_selected_ID() const;
@@ -87,7 +87,7 @@ public:
virtual void get_translatable_strings(List<String> *p_strings) const;
- OptionButton();
+ OptionButton();
~OptionButton();
};
diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp
index d40daa972c..682ea5b92c 100644
--- a/scene/gui/panel.cpp
+++ b/scene/gui/panel.cpp
@@ -30,7 +30,7 @@
#include "print_string.h"
void Panel::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
RID ci = get_canvas_item();
@@ -40,7 +40,7 @@ void Panel::_notification(int p_what) {
}
Panel::Panel() {
-
+
set_stop_mouse(true);
}
diff --git a/scene/gui/panel.h b/scene/gui/panel.h
index ee4bcd139e..efa9ebcaa0 100644
--- a/scene/gui/panel.h
+++ b/scene/gui/panel.h
@@ -34,13 +34,13 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Panel : public Control{
-
+
OBJ_TYPE(Panel,Control);
protected:
void _notification(int p_what);
public:
- Panel();
+ Panel();
~Panel();
};
diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp
index bcf75b79f8..b5e3ef8c7b 100644
--- a/scene/gui/panel_container.cpp
+++ b/scene/gui/panel_container.cpp
@@ -31,7 +31,12 @@
Size2 PanelContainer::get_minimum_size() const {
- Ref<StyleBox> style=get_stylebox("panel");
+ Ref<StyleBox> style;
+
+ if (has_stylebox("panel"))
+ style=get_stylebox("panel");
+ else
+ style=get_stylebox("panel","PanelContainer");
Size2 ms;
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 1f04985ec6..0d9a76937c 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -32,12 +32,12 @@
void Popup::_input_event(InputEvent p_event) {
-
+
}
void Popup::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
if (popped_up && !is_visible()) {
popped_up=false;
@@ -58,11 +58,11 @@ void Popup::_notification(int p_what) {
}
void Popup::_fix_size() {
-
+
#if 0
Point2 pos = get_pos();
- Size2 size = get_size();
+ Size2 size = get_size();
Point2 window_size = window==this ? get_parent_area_size() :window->get_size();
#else
@@ -75,7 +75,7 @@ void Popup::_fix_size() {
pos.x=window_size.width-size.width;
if (pos.x<0)
pos.x=0;
-
+
if (pos.y+size.height > window_size.height)
pos.y=window_size.height-size.height;
if (pos.y<0)
@@ -179,7 +179,7 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) {
}
void Popup::popup_centered(const Size2& p_size) {
-
+
Point2 window_size = get_viewport_rect().size;
emit_signal("about_to_show");
@@ -203,9 +203,9 @@ void Popup::popup_centered(const Size2& p_size) {
}
void Popup::popup_centered_ratio(float p_screen_ratio) {
-
-
-
+
+
+
emit_signal("about_to_show");
Rect2 rect;
@@ -214,7 +214,7 @@ void Popup::popup_centered_ratio(float p_screen_ratio) {
rect.pos = ((window_size-rect.size)/2.0).floor();
set_pos( rect.pos );
set_size( rect.size );
-
+
show_modal(exclusive);
_fix_size();
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 9c66e6d7bd..8afcdc01db 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -35,12 +35,12 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Popup : public Control {
-
+
OBJ_TYPE( Popup, Control );
bool exclusive;
bool popped_up;
-
+
protected:
virtual void _post_popup() {}
@@ -48,14 +48,14 @@ protected:
void _input_event(InputEvent p_event);
void _notification(int p_what);
void _fix_size();
- static void _bind_methods();
+ static void _bind_methods();
public:
enum {
NOTIFICATION_POST_POPUP=80,
NOTIFICATION_POPUP_HIDE=81
};
-
+
void set_exclusive(bool p_exclusive);
bool is_exclusive() const;
@@ -65,8 +65,8 @@ public:
void set_as_minsize();
virtual void popup();
-
- Popup();
+
+ Popup();
~Popup();
};
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index a93d8e524f..3329d24890 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -59,34 +59,34 @@ Size2 PopupMenu::get_minimum_size() const {
int vseparation = get_constant("vseparation");
int hseparation = get_constant("hseparation");
-
+
Size2 minsize = get_stylebox("panel")->get_minimum_size();
Ref<Font> font = get_font("font");
-
+
float max_w=0;
int font_h = font->get_height();
int check_w = get_icon("checked")->get_width();
int accel_max_w=0;
-
+
for (int i=0;i<items.size();i++) {
-
+
Size2 size;
if (!items[i].icon.is_null()) {
-
+
Size2 icon_size = items[i].icon->get_size();
size.height = MAX( icon_size.height, font_h );
size.width+=icon_size.width;
size.width+=hseparation;
} else {
-
+
size.height=font_h;
}
-
+
if (items[i].checkable) {
-
+
size.width+=check_w+hseparation;
}
-
+
size.width+=font->get_string_size(items[i].text).width;
if (i>0)
size.height+=vseparation;
@@ -100,11 +100,11 @@ Size2 PopupMenu::get_minimum_size() const {
minsize.height+=size.height;
max_w = MAX( max_w, size.width );
-
+
}
-
+
minsize.width+=max_w+accel_max_w;
-
+
return minsize;
}
@@ -115,41 +115,41 @@ int PopupMenu::_get_mouse_over(const Point2& p_over) const {
return -1;
Ref<StyleBox> style = get_stylebox("panel");
-
+
Point2 ofs=style->get_offset();
-
+
if (ofs.y>p_over.y)
return -1;
-
-
- Ref<Font> font = get_font("font");
+
+
+ Ref<Font> font = get_font("font");
int vseparation = get_constant("vseparation");
// int hseparation = get_constant("hseparation");
float font_h=font->get_height();
-
+
for (int i=0;i<items.size();i++) {
-
+
if (i>0)
ofs.y+=vseparation;
float h;
-
+
if (!items[i].icon.is_null()) {
-
+
Size2 icon_size = items[i].icon->get_size();
h = MAX( icon_size.height, font_h );
} else {
-
+
h=font_h;
}
-
+
ofs.y+=h;
if (p_over.y < ofs.y) {
return i;
- }
+ }
}
-
+
return -1;
}
@@ -271,11 +271,11 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
} break;
case InputEvent::MOUSE_BUTTON: {
-
-
+
+
const InputEventMouseButton &b=p_event.mouse_button;
if (b.pressed)
- break;
+ break;
switch(b.button_index) {
@@ -347,11 +347,11 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
} break;
}
-
+
//update();
} break;
case InputEvent::MOUSE_MOTION: {
-
+
if (invalidated_click) {
moved+=Vector2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y);
@@ -409,13 +409,13 @@ bool PopupMenu::has_point(const Point2& p_point) const {
void PopupMenu::_notification(int p_what) {
switch(p_what) {
-
+
case NOTIFICATION_DRAW: {
-
+
RID ci = get_canvas_item();
Size2 size=get_size();
-
+
Ref<StyleBox> style = get_stylebox("panel");
Ref<StyleBox> hover = get_stylebox("hover");
Ref<Font> font = get_font("font");
@@ -423,7 +423,7 @@ void PopupMenu::_notification(int p_what) {
Ref<Texture> uncheck = get_icon("unchecked");
Ref<Texture> submenu= get_icon("submenu");
Ref<StyleBox> separator = get_stylebox("separator");
-
+
style->draw( ci, Rect2( Point2(), get_size() ) );
Point2 ofs=style->get_offset();
int vseparation = get_constant("vseparation");
@@ -433,36 +433,36 @@ void PopupMenu::_notification(int p_what) {
Color font_color_accel = get_color("font_color_accel");
Color font_color_hover = get_color("font_color_hover");
float font_h=font->get_height();
-
+
for (int i=0;i<items.size();i++) {
-
+
if (i>0)
ofs.y+=vseparation;
Point2 item_ofs=ofs;
float h;
Size2 icon_size;
-
+
if (!items[i].icon.is_null()) {
-
+
icon_size = items[i].icon->get_size();
h = MAX( icon_size.height, font_h );
} else {
-
+
h=font_h;
}
-
+
if (i==mouse_over) {
-
+
hover->draw(ci, Rect2( ofs+Point2(-hseparation,-vseparation), Size2( get_size().width - style->get_minimum_size().width + hseparation*2, h+vseparation*2 ) ));
}
-
+
if (items[i].separator) {
-
+
int sep_h=separator->get_center_size().height+separator->get_minimum_size().height;
separator->draw(ci, Rect2( ofs+Point2(0,Math::floor((h-sep_h)/2.0)), Size2( get_size().width - style->get_minimum_size().width , sep_h ) ));
-
+
}
-
+
if (items[i].checkable) {
if (items[i].checked)
@@ -499,16 +499,16 @@ void PopupMenu::_notification(int p_what) {
items[i]._ofs_cache=ofs.y;
ofs.y+=h;
-
+
}
-
+
} break;
case NOTIFICATION_MOUSE_ENTER: {
grab_focus();
} break;
case NOTIFICATION_MOUSE_EXIT: {
-
+
if (mouse_over>=0) {
mouse_over=-1;
update();
@@ -574,7 +574,7 @@ void PopupMenu::set_item_text(int p_idx,const String& p_text) {
ERR_FAIL_INDEX(p_idx,items.size());
items[p_idx].text=XL_MESSAGE(p_text);
-
+
update();
}
@@ -597,8 +597,8 @@ void PopupMenu::set_item_checked(int p_idx,bool p_checked) {
void PopupMenu::set_item_ID(int p_idx,int p_ID) {
ERR_FAIL_INDEX(p_idx,items.size());
- items[p_idx].ID=p_ID;
-
+ items[p_idx].ID=p_ID;
+
update();
}
@@ -785,7 +785,7 @@ void PopupMenu::add_separator() {
items.push_back(sep);
update();
}
-
+
void PopupMenu::clear() {
items.clear();
@@ -888,7 +888,7 @@ void PopupMenu::clear_autohide_areas(){
void PopupMenu::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("_input_event"),&PopupMenu::_input_event);
+ ObjectTypeDB::bind_method(_MD("_input_event"),&PopupMenu::_input_event);
ObjectTypeDB::bind_method(_MD("add_icon_item","texture","label","id","accel"),&PopupMenu::add_icon_item,DEFVAL(-1),DEFVAL(0));
ObjectTypeDB::bind_method(_MD("add_item","label","id","accel"),&PopupMenu::add_item,DEFVAL(-1),DEFVAL(0));
ObjectTypeDB::bind_method(_MD("add_icon_check_item","texture","label","id","accel"),&PopupMenu::add_icon_check_item,DEFVAL(-1),DEFVAL(0));
@@ -916,7 +916,7 @@ void PopupMenu::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_item_ID","idx"),&PopupMenu::get_item_ID);
ObjectTypeDB::bind_method(_MD("get_item_index","id"),&PopupMenu::get_item_index);
ObjectTypeDB::bind_method(_MD("get_item_count"),&PopupMenu::get_item_count);
- ObjectTypeDB::bind_method(_MD("add_separator"),&PopupMenu::add_separator);
+ ObjectTypeDB::bind_method(_MD("add_separator"),&PopupMenu::add_separator);
ObjectTypeDB::bind_method(_MD("remove_item","idx"),&PopupMenu::remove_item);
ObjectTypeDB::bind_method(_MD("clear"),&PopupMenu::clear);
@@ -930,7 +930,7 @@ void PopupMenu::_bind_methods() {
ADD_SIGNAL( MethodInfo("item_pressed", PropertyInfo( Variant::INT,"ID") ) );
}
-
+
void PopupMenu::set_invalidate_click_until_motion() {
moved=Vector2();
@@ -941,7 +941,7 @@ PopupMenu::PopupMenu() {
mouse_over=-1;
-
+
set_focus_mode(FOCUS_ALL);
set_as_toplevel(true);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 624f4f542a..72f8795067 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -37,7 +37,7 @@
class PopupMenu : public Popup {
OBJ_TYPE(PopupMenu, Popup );
-
+
struct Item {
Ref<Texture> icon;
String text;
@@ -45,16 +45,16 @@ class PopupMenu : public Popup {
bool checkable;
bool separator;
bool disabled;
- int ID;
+ int ID;
Variant metadata;
String submenu;
String tooltip;
uint32_t accel;
int _ofs_cache;
-
+
Item() { checked=false; checkable=false; separator=false; accel=0; disabled=false; _ofs_cache=0; }
};
-
+
Timer *submenu_timer;
List<Rect2> autohide_areas;
@@ -64,7 +64,7 @@ class PopupMenu : public Popup {
Rect2 parent_rect;
String _get_accel_text(uint32_t p_accel) const;
int _get_mouse_over(const Point2& p_over) const;
- virtual Size2 get_minimum_size() const;
+ virtual Size2 get_minimum_size() const;
void _input_event(const InputEvent &p_event);
void _activate_submenu(int over);
void _submenu_timeout();
@@ -79,11 +79,11 @@ protected:
virtual bool has_point(const Point2& p_point) const;
-friend class MenuButton;
+friend class MenuButton;
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
-
+
void add_icon_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1,uint32_t p_accel=0);
void add_item(const String& p_label,int p_ID=-1,uint32_t p_accel=0);
void add_icon_check_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1,uint32_t p_accel=0);
@@ -92,7 +92,7 @@ public:
void set_item_text(int p_idx,const String& p_text);
void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
- void set_item_checked(int p_idx,bool p_checked);
+ void set_item_checked(int p_idx,bool p_checked);
void set_item_ID(int p_idx,int p_ID);
void set_item_accelerator(int p_idx,uint32_t p_accel);
void set_item_metadata(int p_idx,const Variant& p_meta);
@@ -110,7 +110,7 @@ public:
uint32_t get_item_accelerator(int p_idx) const;
Variant get_item_metadata(int p_idx) const;
bool is_item_disabled(int p_idx) const;
- String get_item_submenu(int p_ID) const;
+ String get_item_submenu(int p_ID) const;
bool is_item_separator(int p_idx) const;
bool is_item_checkable(int p_idx) const;
String get_item_tooltip(int p_idx) const;
@@ -121,9 +121,9 @@ public:
void activate_item(int p_item);
void remove_item(int p_idx);
-
+
void add_separator();
-
+
void clear();
void set_parent_rect(const Rect2& p_rect);
@@ -137,7 +137,7 @@ public:
void set_invalidate_click_until_motion();
- PopupMenu();
+ PopupMenu();
~PopupMenu();
};
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index ffcdf98519..b00fcfe42c 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -67,14 +67,14 @@ void Range::Shared::emit_changed(const char *p_what) {
void Range::set_val(double p_val) {
-
+
if(_rounded_values){
p_val = Math::round(p_val);
}
-
+
if (p_val>shared->max-shared->page)
p_val=shared->max-shared->page;
-
+
if (p_val<shared->min)
p_val=shared->min;
@@ -84,58 +84,58 @@ void Range::set_val(double p_val) {
if (shared->val==p_val)
return;
-
+
shared->val=p_val;
-
+
shared->emit_value_changed();
}
void Range::set_min(double p_min) {
-
+
shared->min=p_min;
set_val(shared->val);
-
+
shared->emit_changed("range/min");
}
void Range::set_max(double p_max) {
-
+
shared->max=p_max;
set_val(shared->val);
-
+
shared->emit_changed("range/max");
}
void Range::set_step(double p_step) {
-
+
shared->step=p_step;
shared->emit_changed("range/step");
}
void Range::set_page(double p_page) {
-
+
shared->page=p_page;
set_val(shared->val);
-
+
shared->emit_changed("range/page");
}
double Range::get_val() const {
-
+
return shared->val;
}
double Range::get_min() const {
-
+
return shared->min;
}
double Range::get_max() const {
-
+
return shared->max;
}
double Range::get_step() const {
-
+
return shared->step;
}
double Range::get_page() const {
-
+
return shared->page;
}
diff --git a/scene/gui/range.h b/scene/gui/range.h
index d96ecdfb0b..85c3687b7d 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -34,7 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Range : public Control {
-
+
OBJ_TYPE( Range, Control );
@@ -57,15 +57,15 @@ class Range : public Control {
void _value_changed_notify();
void _changed_notify(const char *p_what="");
-protected:
+protected:
virtual void _value_changed(double) {}
static void _bind_methods();
-
+
bool _rounded_values;
public:
-
+
void set_val(double p_val);
void set_min(double p_min);
void set_max(double p_max);
@@ -89,7 +89,7 @@ public:
void share(Range *p_range);
void unshare();
- Range();
+ Range();
~Range();
};
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index d4ac2652dc..98bc0b9434 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -237,7 +237,7 @@ if (m_height > line_height) {\
if (font.is_null())
font=p_base_font;
- const CharType *c = text->text.c_str();
+ const CharType *c = text->text.c_str();
const CharType *cf=c;
int fh=font->get_height();
int ascent = font->get_ascent();
@@ -297,7 +297,7 @@ if (m_height > line_height) {\
fw+=cw;
}
- end++;
+ end++;
}
ENSURE_WIDTH(w);
@@ -2058,7 +2058,7 @@ RichTextLabel::RichTextLabel() {
scroll_active=true;
scroll_w=0;
- vscroll = memnew( VScrollBar );
+ vscroll = memnew( VScrollBar );
add_child(vscroll);
vscroll->set_drag_slave(String(".."));
vscroll->set_step(1);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 0fd4286f38..d8365feb24 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -35,7 +35,7 @@ bool ScrollBar::focus_by_default=false;
void ScrollBar::set_can_focus_by_default(bool p_can_focus) {
-
+
focus_by_default=p_can_focus;
}
@@ -43,14 +43,14 @@ void ScrollBar::_input_event(InputEvent p_event) {
switch(p_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &b=p_event.mouse_button;
accept_event();
if (b.button_index==5 && b.pressed) {
-
+
//if (orientation==VERTICAL)
// set_val( get_val() + get_page() / 4.0 );
//else
@@ -58,16 +58,16 @@ void ScrollBar::_input_event(InputEvent p_event) {
accept_event();
}
-
+
if (b.button_index==4 && b.pressed) {
-
+
//if (orientation==HORIZONTAL)
// set_val( get_val() - get_page() / 4.0 );
//else
set_val( get_val() - get_page() / 4.0 );
accept_event();
}
-
+
if (b.button_index!=1)
return;
@@ -78,177 +78,177 @@ void ScrollBar::_input_event(InputEvent p_event) {
double ofs = orientation==VERTICAL ? b.y : b.x ;
Ref<Texture> decr = get_icon("decrement");
Ref<Texture> incr = get_icon("increment");
-
+
double decr_size = orientation==VERTICAL ? decr->get_height() : decr->get_width();
double incr_size = orientation==VERTICAL ? incr->get_height() : incr->get_width();
double grabber_ofs = get_grabber_offset();
double grabber_size = get_grabber_size();
double total = orientation==VERTICAL ? get_size().height : get_size().width;
-
+
if (ofs < decr_size ) {
-
+
set_val( get_val() - (custom_step>=0?custom_step:get_step()) );
break;
}
-
+
if (ofs > total-incr_size ) {
-
+
set_val( get_val() + (custom_step>=0?custom_step:get_step()) );
break;
}
-
+
ofs-=decr_size;
-
+
if ( ofs < grabber_ofs ) {
-
+
set_val( get_val() - get_page() );
break;
-
- }
-
+
+ }
+
ofs-=grabber_ofs;
-
+
if (ofs < grabber_size ) {
-
+
drag.active=true;
drag.pos_at_click=grabber_ofs+ofs;
- drag.value_at_click=get_unit_value();
+ drag.value_at_click=get_unit_value();
update();
} else {
-
-
+
+
set_val( get_val() + get_page() );
}
-
-
+
+
} else {
-
+
drag.active=false;
update();
}
-
+
} break;
case InputEvent::MOUSE_MOTION: {
-
+
const InputEventMouseMotion &m=p_event.mouse_motion;
accept_event();
-
+
if (drag.active) {
-
+
double ofs = orientation==VERTICAL ? m.y : m.x ;
Ref<Texture> decr = get_icon("decrement");
-
+
double decr_size = orientation==VERTICAL ? decr->get_height() : decr->get_width();
ofs-=decr_size;
-
+
double diff = (ofs-drag.pos_at_click) / get_area_size();
- set_unit_value( drag.value_at_click + diff );
+ set_unit_value( drag.value_at_click + diff );
} else {
-
-
+
+
double ofs = orientation==VERTICAL ? m.y : m.x ;
Ref<Texture> decr = get_icon("decrement");
Ref<Texture> incr = get_icon("increment");
-
+
double decr_size = orientation==VERTICAL ? decr->get_height() : decr->get_width();
double incr_size = orientation==VERTICAL ? incr->get_height() : incr->get_width();
double total = orientation==VERTICAL ? get_size().height : get_size().width;
-
+
HiliteStatus new_hilite;
-
+
if (ofs < decr_size ) {
-
+
new_hilite=HILITE_DECR;
-
+
} else if (ofs > total-incr_size ) {
-
+
new_hilite=HILITE_INCR;
-
+
} else {
-
+
new_hilite=HILITE_RANGE;
}
-
+
if (new_hilite!=hilite) {
-
+
hilite=new_hilite;
update();
-
+
}
-
+
}
} break;
case InputEvent::KEY: {
-
+
const InputEventKey &k=p_event.key;
-
+
if (!k.pressed)
return;
-
+
switch (k.scancode) {
-
+
case KEY_LEFT: {
-
+
if (orientation!=HORIZONTAL)
return;
set_val( get_val() - (custom_step>=0?custom_step:get_step()) );
-
+
} break;
case KEY_RIGHT: {
-
+
if (orientation!=HORIZONTAL)
return;
set_val( get_val() + (custom_step>=0?custom_step:get_step()) );
-
+
} break;
case KEY_UP: {
-
+
if (orientation!=VERTICAL)
return;
-
+
set_val( get_val() - (custom_step>=0?custom_step:get_step()) );
-
-
+
+
} break;
case KEY_DOWN: {
-
+
if (orientation!=VERTICAL)
return;
set_val( get_val() + (custom_step>=0?custom_step:get_step()) );
-
+
} break;
case KEY_HOME: {
-
+
set_val( get_min() );
-
+
} break;
case KEY_END: {
-
+
set_val( get_max() );
-
+
} break;
-
+
} break;
- }
+ }
}
}
void ScrollBar::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
-
+
Ref<Texture> decr = hilite==HILITE_DECR ? get_icon("decrement_hilite") : get_icon("decrement");
Ref<Texture> incr = hilite==HILITE_INCR ? get_icon("increment_hilite") : get_icon("increment");
Ref<StyleBox> bg = has_focus() ? get_stylebox("scroll_focus") : get_stylebox("scroll");
Ref<StyleBox> grabber = (drag.active || hilite==HILITE_RANGE) ? get_stylebox("grabber_hilite") : get_stylebox("grabber");
-
+
Point2 ofs;
-
+
VisualServer *vs = VisualServer::get_singleton();
vs->canvas_item_add_texture_rect( ci, Rect2( Point2(), decr->get_size()),decr->get_rid() );
@@ -266,33 +266,33 @@ void ScrollBar::_notification(int p_what) {
area.height-=incr->get_height()+decr->get_height();
bg->draw(ci,Rect2(ofs,area));
-
- if (orientation==HORIZONTAL)
+
+ if (orientation==HORIZONTAL)
ofs.width+=area.width;
else
ofs.height+=area.height;
vs->canvas_item_add_texture_rect( ci, Rect2( ofs, decr->get_size()),incr->get_rid() );
Rect2 grabber_rect;
-
+
if (orientation==HORIZONTAL) {
-
+
grabber_rect.size.width=get_grabber_size();
grabber_rect.size.height=get_size().height;
grabber_rect.pos.y=0;
grabber_rect.pos.x=get_grabber_offset()+decr->get_width()+bg->get_margin( MARGIN_LEFT );
} else {
-
+
grabber_rect.size.width=get_size().width;
grabber_rect.size.height=get_grabber_size();
grabber_rect.pos.y=get_grabber_offset()+decr->get_height()+bg->get_margin( MARGIN_TOP );
- grabber_rect.pos.x=0;
+ grabber_rect.pos.x=0;
}
-
+
grabber->draw(ci,grabber_rect);
-
+
}
-
+
if (p_what==NOTIFICATION_ENTER_TREE) {
@@ -405,48 +405,48 @@ void ScrollBar::_notification(int p_what) {
}
if (p_what==NOTIFICATION_MOUSE_EXIT) {
-
+
hilite=HILITE_NONE;
update();
}
}
double ScrollBar::get_grabber_min_size() const {
-
+
Ref<StyleBox> grabber=get_stylebox("grabber");
Size2 gminsize=grabber->get_minimum_size()+grabber->get_center_size();
- return (orientation==VERTICAL)?gminsize.height:gminsize.width;
+ return (orientation==VERTICAL)?gminsize.height:gminsize.width;
}
double ScrollBar::get_grabber_size() const {
-
+
float range = get_max()-get_min();
if (range<=0)
return 0;
-
+
float page = (get_page()>0)? get_page() : 0;
// if (grabber_range < get_step())
// grabber_range=get_step();
-
+
double area_size=get_area_size();
double grabber_size = page / range * area_size;
return grabber_size+get_grabber_min_size();
-
-}
+
+}
double ScrollBar::get_area_size() const {
-
+
if (orientation==VERTICAL) {
-
+
double area=get_size().height;
area-=get_stylebox("scroll")->get_minimum_size().height;
area-=get_icon("increment")->get_height();
area-=get_icon("decrement")->get_height();
area-=get_grabber_min_size();
return area;
-
+
} else if (orientation==HORIZONTAL) {
-
+
double area=get_size().width;
area-=get_stylebox("scroll")->get_minimum_size().width;
area-=get_icon("increment")->get_width();
@@ -454,38 +454,38 @@ double ScrollBar::get_area_size() const {
area-=get_grabber_min_size();
return area;
} else {
-
+
return 0;
}
-
+
}
double ScrollBar::get_area_offset() const {
-
+
double ofs=0;
-
+
if (orientation==VERTICAL) {
-
+
ofs+=get_stylebox("hscroll")->get_margin( MARGIN_TOP );
ofs+=get_icon("decrement")->get_height();
- }
-
+ }
+
if (orientation==HORIZONTAL) {
-
+
ofs+=get_stylebox("hscroll")->get_margin( MARGIN_LEFT );
ofs+=get_icon("decrement")->get_width();
}
-
- return ofs;
+
+ return ofs;
}
double ScrollBar::get_click_pos(const Point2& p_pos) const {
-
-
+
+
float pos=(orientation==VERTICAL)?p_pos.y:p_pos.x;
pos-=get_area_offset();
-
+
float area=get_area_size();
if (area==0)
return 0;
@@ -495,8 +495,8 @@ double ScrollBar::get_click_pos(const Point2& p_pos) const {
}
double ScrollBar::get_grabber_offset() const {
-
-
+
+
return (get_area_size()) * get_unit_value();
}
@@ -504,30 +504,30 @@ double ScrollBar::get_grabber_offset() const {
Size2 ScrollBar::get_minimum_size() const {
-
+
Ref<Texture> incr = get_icon("increment");
Ref<Texture> decr = get_icon("decrement");
Ref<StyleBox> bg = get_stylebox("scroll");
Size2 minsize;
-
+
if (orientation==VERTICAL) {
-
+
minsize.width=MAX(incr->get_size().width,(bg->get_minimum_size()+bg->get_center_size()).width);
minsize.height+=incr->get_size().height;
minsize.height+=decr->get_size().height;
minsize.height+=bg->get_minimum_size().height;
minsize.height+=get_grabber_min_size();
}
-
+
if (orientation==HORIZONTAL) {
-
+
minsize.height=MAX(incr->get_size().height,(bg->get_center_size()+bg->get_minimum_size()).height);
minsize.width+=incr->get_size().width;
minsize.width+=decr->get_size().width;
minsize.width+=bg->get_minimum_size().width;
minsize.width+=get_grabber_min_size();
}
-
+
return minsize;
}
@@ -671,65 +671,65 @@ NodePath ScrollBar::get_drag_slave() const{
#if 0
void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pressed,int p_modifier_mask) {
-
- // wheel!
-
+
+ // wheel!
+
if (b.button_index==BUTTON_WHEEL_UP && b.pressed) {
-
+
if (orientation==VERTICAL)
set_val( get_val() - get_page() / 4.0 );
else
set_val( get_val() + get_page() / 4.0 );
-
+
}
if (b.button_index==BUTTON_WHEEL_DOWN && b.pressed) {
-
+
if (orientation==HORIZONTAL)
set_val( get_val() - get_page() / 4.0 );
else
set_val( get_val() + get_page() / 4.0 );
}
-
+
if (b.button_index!=BUTTON_LEFT)
return;
-
+
if (b.pressed) {
-
+
int ofs = orientation==VERTICAL ? p_pos.y : p_pos.x ;
int grabber_ofs = get_grabber_offset();
int grabber_size = get_grabber_size();
-
+
if ( ofs < grabber_ofs ) {
-
+
set_val( get_val() - get_page() );
-
+
} else if (ofs > grabber_ofs + grabber_size ) {
-
+
set_val( get_val() + get_page() );
-
+
} else {
-
-
+
+
drag.active=true;
drag.pos_at_click=get_click_pos(p_pos);
drag.value_at_click=get_unit_value();
}
-
-
+
+
} else {
-
+
drag.active=false;
}
-
+
}
void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b.button_index_mask) {
-
+
if (!drag.active)
return;
-
+
double value_ofs=drag.value_at_click+(get_click_pos(p_pos)-drag.pos_at_click);
-
-
+
+
value_ofs=value_ofs*( get_max() - get_min() );
if (value_ofs<get_min())
value_ofs=get_min();
@@ -737,64 +737,64 @@ void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b.but
value_ofs=get_max()-get_page();
if (get_val()==value_ofs)
return; //dont bother if the value is the same
-
+
set_val( value_ofs );
-
+
}
bool ScrollBar::key(unsigned long p_unicode, unsigned long p_scan_code,bool b.pressed,bool p_repeat,int p_modifier_mask) {
-
+
if (!b.pressed)
return false;
-
+
switch (p_scan_code) {
-
+
case KEY_LEFT: {
-
+
if (orientation!=HORIZONTAL)
return false;
set_val( get_val() - get_step() );
-
+
} break;
case KEY_RIGHT: {
-
+
if (orientation!=HORIZONTAL)
return false;
set_val( get_val() + get_step() );
-
+
} break;
case KEY_UP: {
-
+
if (orientation!=VERTICAL)
return false;
-
+
set_val( get_val() - get_step() );
-
-
+
+
} break;
case KEY_DOWN: {
-
+
if (orientation!=VERTICAL)
return false;
set_val( get_val() + get_step() );
-
+
} break;
case KEY_HOME: {
-
+
set_val( get_min() );
-
+
} break;
case KEY_END: {
-
+
set_val( get_max() );
-
+
} break;
-
+
default:
return false;
-
+
}
-
+
return true;
}
@@ -823,7 +823,7 @@ ScrollBar::ScrollBar(Orientation p_orientation)
hilite=HILITE_NONE;
custom_step=-1;
drag_slave=NULL;
-
+
drag.active=false;
drag_slave_speed=Vector2();
@@ -833,7 +833,7 @@ ScrollBar::ScrollBar(Orientation p_orientation)
if (focus_by_default)
set_focus_mode( FOCUS_ALL );
-
+
}
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index a629ddc56c..c68db02b33 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -36,40 +36,40 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class ScrollBar : public Range {
-
+
OBJ_TYPE( ScrollBar, Range );
-
+
enum HiliteStatus {
HILITE_NONE,
HILITE_DECR,
HILITE_RANGE,
- HILITE_INCR,
+ HILITE_INCR,
};
-
+
static bool focus_by_default;
-
+
Orientation orientation;
Size2 size;
float custom_step;
-
+
HiliteStatus hilite;
-
+
struct Drag {
-
+
bool active;
float pos_at_click;
float value_at_click;
} drag;
-
-
+
+
double get_grabber_size() const;
double get_grabber_min_size() const;
double get_area_size() const;
double get_area_offset() const;
double get_click_pos(const Point2& p_pos) const;
double get_grabber_offset() const;
-
- static void set_can_focus_by_default(bool p_can_focus);
+
+ static void set_can_focus_by_default(bool p_can_focus);
Node* drag_slave;
NodePath drag_slave_path;
@@ -86,12 +86,12 @@ class ScrollBar : public Range {
void _drag_slave_exit();
void _drag_slave_input(const InputEvent& p_input);
-
+
void _input_event(InputEvent p_event);
-protected:
+protected:
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
@@ -101,25 +101,25 @@ public:
void set_drag_slave(const NodePath& p_path);
NodePath get_drag_slave() const;
- virtual Size2 get_minimum_size() const;
- ScrollBar(Orientation p_orientation=VERTICAL);
+ virtual Size2 get_minimum_size() const;
+ ScrollBar(Orientation p_orientation=VERTICAL);
~ScrollBar();
};
class HScrollBar : public ScrollBar {
-
+
OBJ_TYPE( HScrollBar, ScrollBar );
public:
-
+
HScrollBar() : ScrollBar(HORIZONTAL) { set_v_size_flags(0); }
};
class VScrollBar : public ScrollBar {
-
+
OBJ_TYPE( VScrollBar, ScrollBar );
public:
-
+
VScrollBar() : ScrollBar(VERTICAL) { set_h_size_flags(0); }
};
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index a2fc038f9e..9bf93aff77 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -35,7 +35,37 @@ bool ScrollContainer::clips_input() const {
Size2 ScrollContainer::get_minimum_size() const {
- return Size2(1, 1);
+
+ Size2 min_size;
+
+ for(int i=0;i<get_child_count();i++) {
+
+ Control *c = get_child(i)->cast_to<Control>();
+ if (!c)
+ continue;
+ if (c->is_set_as_toplevel())
+ continue;
+ if (c == h_scroll || c == v_scroll)
+ continue;
+ Size2 minsize = c->get_combined_minimum_size();
+
+
+ if (!scroll_h) {
+ min_size.x = MAX(min_size.x, minsize.x);
+ }
+ if (!scroll_v) {
+ min_size.y = MAX(min_size.y, minsize.y);
+
+ }
+ }
+
+ if (h_scroll->is_visible()) {
+ min_size.y+=h_scroll->get_minimum_size().y;
+ }
+ if (v_scroll->is_visible()) {
+ min_size.x+=v_scroll->get_minimum_size().x;
+ }
+ return min_size;
};
@@ -179,6 +209,12 @@ void ScrollContainer::_notification(int p_what) {
child_max_size = Size2(0, 0);
Size2 size = get_size();
+ if (h_scroll->is_visible())
+ size.y-=h_scroll->get_minimum_size().y;
+
+ if (v_scroll->is_visible())
+ size.x-=h_scroll->get_minimum_size().x;
+
for(int i=0;i<get_child_count();i++) {
Control *c = get_child(i)->cast_to<Control>();
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 7ef9d4216b..f66f909517 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -231,13 +231,13 @@ void Slider::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_input_event"),&Slider::_input_event);
ObjectTypeDB::bind_method(_MD("set_ticks","count"),&Slider::set_ticks);
ObjectTypeDB::bind_method(_MD("get_ticks"),&Slider::get_ticks);
-
- ObjectTypeDB::bind_method(_MD("get_ticks_on_borders"),&Slider::get_ticks_on_borders);
+
+ ObjectTypeDB::bind_method(_MD("get_ticks_on_borders"),&Slider::get_ticks_on_borders);
ObjectTypeDB::bind_method(_MD("set_ticks_on_borders","ticks_on_border"),&Slider::set_ticks_on_borders);
-
+
ADD_PROPERTY( PropertyInfo( Variant::INT, "tick_count", PROPERTY_HINT_RANGE,"0,4096,1"), _SCS("set_ticks"), _SCS("get_ticks") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "ticks_on_borders" ), _SCS("set_ticks_on_borders"), _SCS("get_ticks_on_borders") );
-
+
}
Slider::Slider(Orientation p_orientation) {
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index f85e6d1807..cf009b9a75 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -53,7 +53,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
bool ticks_on_borders;
-
+
public:
virtual Size2 get_minimum_size() const;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 91d0fc157e..1c6a97bab8 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "tab_container.h"
-
+
#include "message_queue.h"
@@ -209,7 +209,7 @@ void TabContainer::_notification(int p_what) {
Ref<Texture> incr = get_icon("increment");
Ref<Texture> incr_hl = get_icon("increment_hilite");
Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> decr_hl = get_icon("decrement_hilite");
+ Ref<Texture> decr_hl = get_icon("decrement_hilite");
Ref<Texture> menu = get_icon("menu");
Ref<Texture> menu_hl = get_icon("menu_hl");
Ref<Font> font = get_font("font");
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index c3e75842c3..9692d08882 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -493,7 +493,7 @@ void Tabs::set_current_tab(int p_current) {
ERR_FAIL_INDEX( p_current, get_tab_count() );
//printf("DEBUG %p: set_current_tab to %i\n", this, p_current);
- current=p_current;
+ current=p_current;
_change_notify("current_tab");
//emit_signal("tab_changed",current);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 7f7c8c023c..e268375c8a 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -38,12 +38,12 @@
#define TAB_PIXELS
static bool _is_text_char(CharType c) {
-
+
return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
}
static bool _is_symbol(CharType c) {
-
+
return c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t');
}
@@ -84,81 +84,81 @@ static CharType _get_right_pair_symbol(CharType c) {
}
void TextEdit::Text::set_font(const Ref<Font>& p_font) {
-
+
font=p_font;
}
void TextEdit::Text::set_tab_size(int p_tab_size) {
-
+
tab_size=p_tab_size;
}
void TextEdit::Text::_update_line_cache(int p_line) const {
-
+
int w = 0;
int tab_w=font->get_char_size(' ').width*tab_size;
int len = text[p_line].data.length();
const CharType *str = text[p_line].data.c_str();
-
+
//update width
-
+
for(int i=0;i<len;i++) {
if (str[i]=='\t') {
-
+
int left = w%tab_w;
if (left==0)
w+=tab_w;
else
w+=tab_w-w%tab_w; // is right...
-
+
} else {
-
+
w+=font->get_char_size(str[i],str[i+1]).width;
}
}
-
-
+
+
text[p_line].width_cache=w;
-
+
//update regions
-
+
text[p_line].region_info.clear();
-
+
for(int i=0;i<len;i++) {
-
+
if (!_is_symbol(str[i]))
continue;
if (str[i]=='\\') {
i++; //skip quoted anything
continue;
}
-
+
int left=len-i;
-
+
for(int j=0;j<color_regions->size();j++) {
-
+
const ColorRegion& cr=color_regions->operator [](j);
-
+
/* BEGIN */
-
+
int lr=cr.begin_key.length();
if (lr==0 || lr>left)
continue;
-
+
const CharType* kc = cr.begin_key.c_str();
-
+
bool match=true;
-
+
for(int k=0;k<lr;k++) {
if (kc[k]!=str[i+k]) {
match=false;
break;
}
}
-
+
if (match) {
-
+
ColorRegionInfo cri;
cri.end=false;
cri.region=j;
@@ -166,26 +166,26 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
i+=lr-1;
break;
}
-
+
/* END */
-
+
lr=cr.end_key.length();
if (lr==0 || lr>left)
continue;
-
+
kc = cr.end_key.c_str();
-
+
match=true;
-
+
for(int k=0;k<lr;k++) {
if (kc[k]!=str[i+k]) {
match=false;
break;
}
}
-
+
if (match) {
-
+
ColorRegionInfo cri;
cri.end=true;
cri.region=j;
@@ -193,72 +193,72 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
i+=lr-1;
break;
}
-
+
}
}
-
-
+
+
}
const Map<int,TextEdit::Text::ColorRegionInfo>& TextEdit::Text::get_color_region_info(int p_line) {
-
+
Map<int,ColorRegionInfo> *cri=NULL;
ERR_FAIL_INDEX_V(p_line,text.size(),*cri); //enjoy your crash
-
+
if (text[p_line].width_cache==-1) {
_update_line_cache(p_line);
}
-
+
return text[p_line].region_info;
}
int TextEdit::Text::get_line_width(int p_line) const {
-
+
ERR_FAIL_INDEX_V(p_line,text.size(),-1);
-
+
if (text[p_line].width_cache==-1) {
_update_line_cache(p_line);
}
-
+
return text[p_line].width_cache;
}
void TextEdit::Text::clear_caches() {
-
+
for(int i=0;i<text.size();i++)
text[i].width_cache=-1;
-
+
}
void TextEdit::Text::clear() {
-
-
+
+
text.clear();;
insert(0,"");
}
int TextEdit::Text::get_max_width() const {
//quite some work.. but should be fast enough.
-
+
int max = 0;
-
+
for(int i=0;i<text.size();i++)
max=MAX(max,get_line_width(i));
return max;
-
+
}
void TextEdit::Text::set(int p_line,const String& p_text) {
-
+
ERR_FAIL_INDEX(p_line,text.size());
-
+
text[p_line].width_cache=-1;
text[p_line].data=p_text;
}
void TextEdit::Text::insert(int p_at,const String& p_text) {
-
+
Line line;
line.marked=false;
line.breakpoint=false;
@@ -267,86 +267,89 @@ void TextEdit::Text::insert(int p_at,const String& p_text) {
text.insert(p_at,line);
}
void TextEdit::Text::remove(int p_at) {
-
+
text.remove(p_at);
}
void TextEdit::_update_scrollbars() {
-
-
+
+
Size2 size = get_size();
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
-
-
-
+
+
+
v_scroll->set_begin( Point2(size.width - vmin.width, cache.style_normal->get_margin(MARGIN_TOP)) );
v_scroll->set_end( Point2(size.width, size.height - cache.style_normal->get_margin(MARGIN_TOP) - cache.style_normal->get_margin(MARGIN_BOTTOM)) );
-
+
h_scroll->set_begin( Point2( 0, size.height - hmin.height) );
h_scroll->set_end( Point2(size.width-vmin.width, size.height) );
-
-
+
+
int hscroll_rows = ((hmin.height-1)/get_row_height())+1;
int visible_rows = get_visible_rows();
int total_rows = text.size();
-
+ if (scroll_past_end_of_file_enabled) {
+ total_rows += get_visible_rows() - 1;
+ }
+
int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
int total_width = text.get_max_width() + vmin.x;
-
+
if (line_numbers)
total_width += cache.line_number_w;
-
+
bool use_hscroll=true;
bool use_vscroll=true;
-
+
if (total_rows <= visible_rows && total_width <= visible_width) {
//thanks yessopie for this clever bit of logic
use_hscroll=false;
use_vscroll=false;
-
+
} else {
-
+
if (total_rows > visible_rows && total_width <= visible_width - vscroll_pixels) {
//thanks yessopie for this clever bit of logic
use_hscroll=false;
}
-
+
if (total_rows <= visible_rows - hscroll_rows && total_width > visible_width) {
//thanks yessopie for this clever bit of logic
use_vscroll=false;
}
}
-
+
updating_scrolls=true;
-
+
if (use_vscroll) {
-
+
v_scroll->show();
v_scroll->set_max(total_rows);
v_scroll->set_page(visible_rows);
v_scroll->set_val(cursor.line_ofs);
-
+
} else {
cursor.line_ofs = 0;
v_scroll->hide();
}
-
+
if (use_hscroll) {
-
+
h_scroll->show();
h_scroll->set_max(total_width);
h_scroll->set_page(visible_width);
h_scroll->set_val(cursor.x_ofs);
-
+
} else {
-
+
h_scroll->hide();
}
-
-
-
+
+
+
updating_scrolls=false;
}
@@ -375,32 +378,32 @@ void TextEdit::_click_selection_held() {
void TextEdit::_notification(int p_what) {
-
+
switch(p_what) {
case NOTIFICATION_ENTER_TREE: {
-
+
_update_caches();
if (cursor_changed_dirty)
MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit");
if (text_changed_dirty)
MessageQueue::get_singleton()->push_call(this,"_text_changed_emit");
-
+
} break;
case NOTIFICATION_RESIZED: {
-
+
cache.size=get_size();
adjust_viewport_to_cursor();
-
-
+
+
} break;
case NOTIFICATION_THEME_CHANGED: {
-
+
_update_caches();
};
case NOTIFICATION_DRAW: {
-
+
int line_number_char_count=0;
-
+
{
int lc=text.size()+1;
cache.line_number_w=0;
@@ -408,20 +411,20 @@ void TextEdit::_notification(int p_what) {
cache.line_number_w+=1;
lc/=10;
};
-
+
if (line_numbers) {
-
+
line_number_char_count=cache.line_number_w;
cache.line_number_w=(cache.line_number_w+1)*cache.font->get_char_size('0').width;
} else {
cache.line_number_w=0;
}
-
-
+
+
}
_update_scrollbars();
-
-
+
+
RID ci = get_canvas_item();
int xmargin_beg=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w;
int xmargin_end=cache.size.width-cache.style_normal->get_margin(MARGIN_RIGHT);
@@ -429,56 +432,56 @@ void TextEdit::_notification(int p_what) {
cache.style_normal->draw(ci,Rect2(Point2(),cache.size));
if (has_focus())
cache.style_focus->draw(ci,Rect2(Point2(),cache.size));
-
-
+
+
int ascent=cache.font->get_ascent();
-
+
int visible_rows = get_visible_rows();
-
+
int tab_w = cache.font->get_char_size(' ').width*tab_size;
-
+
Color color = cache.font_color;
int in_region=-1;
-
+
if (syntax_coloring) {
-
+
if (custom_bg_color.a>0.01) {
-
+
Point2i ofs = Point2i(cache.style_normal->get_offset())/2.0;
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(ofs, get_size()-cache.style_normal->get_minimum_size()+ofs),custom_bg_color);
}
//compute actual region to start (may be inside say, a comment).
//slow in very large documments :( but ok for source!
-
+
for(int i=0;i<cursor.line_ofs;i++) {
-
+
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(i);
-
+
if (in_region>=0 && color_regions[in_region].line_only) {
in_region=-1; //reset regions that end at end of line
}
-
+
for( const Map<int,Text::ColorRegionInfo>::Element* E= cri_map.front();E;E=E->next() ) {
-
+
const Text::ColorRegionInfo &cri=E->get();
-
+
if (in_region==-1) {
-
+
if (!cri.end) {
-
+
in_region=cri.region;
}
} else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise
-
+
if (cri.end || color_regions[cri.region].eq) {
-
+
in_region=-1;
}
}
}
}
}
-
+
int brace_open_match_line=-1;
int brace_open_match_column=-1;
bool brace_open_matching=false;
@@ -487,15 +490,15 @@ void TextEdit::_notification(int p_what) {
int brace_close_match_column=-1;
bool brace_close_matching=false;
bool brace_close_mismatch=false;
-
-
+
+
if (brace_matching_enabled) {
-
+
if (cursor.column<text[cursor.line].length()) {
//check for open
CharType c = text[cursor.line][cursor.column];
CharType closec=0;
-
+
if (c=='[') {
closec=']';
} else if (c=='{') {
@@ -503,17 +506,17 @@ void TextEdit::_notification(int p_what) {
} else if (c=='(') {
closec=')';
}
-
+
if (closec!=0) {
-
+
int stack=1;
-
-
+
+
for(int i=cursor.line;i<text.size();i++) {
-
+
int from = i==cursor.line?cursor.column+1:0;
for(int j=from;j<text[i].length();j++) {
-
+
CharType cc = text[i][j];
//ignore any brackets inside a string
if (cc== '"' || cc == '\'') {
@@ -541,32 +544,32 @@ void TextEdit::_notification(int p_what) {
stack++;
else if (cc==closec)
stack--;
-
+
if (stack==0) {
brace_open_match_line=i;
brace_open_match_column=j;
brace_open_matching=true;
-
+
break;
}
}
if (brace_open_match_line!=-1)
break;
}
-
+
if (!brace_open_matching)
brace_open_mismatch=true;
-
-
+
+
}
}
-
+
if (cursor.column>0) {
CharType c = text[cursor.line][cursor.column-1];
CharType closec=0;
-
-
-
+
+
+
if (c==']') {
closec='[';
} else if (c=='}') {
@@ -574,17 +577,17 @@ void TextEdit::_notification(int p_what) {
} else if (c==')') {
closec='(';
}
-
+
if (closec!=0) {
-
+
int stack=1;
-
-
+
+
for(int i=cursor.line;i>=0;i--) {
-
+
int from = i==cursor.line?cursor.column-2:text[i].length()-1;
for(int j=from;j>=0;j--) {
-
+
CharType cc = text[i][j];
//ignore any brackets inside a string
if (cc== '"' || cc == '\'') {
@@ -613,49 +616,49 @@ void TextEdit::_notification(int p_what) {
stack++;
else if (cc==closec)
stack--;
-
+
if (stack==0) {
brace_close_match_line=i;
brace_close_match_column=j;
brace_close_matching=true;
-
+
break;
}
}
if (brace_close_match_line!=-1)
break;
}
-
+
if (!brace_close_matching)
brace_close_mismatch=true;
-
-
+
+
}
-
-
+
+
}
}
-
-
+
+
int deregion=0; //force it to clear inrgion
Point2 cursor_pos;
-
+
for (int i=0;i<visible_rows;i++) {
-
+
int line=i+cursor.line_ofs;
-
+
if (line<0 || line>=(int)text.size())
continue;
-
+
const String &str=text[line];
-
+
int char_margin=xmargin_beg-cursor.x_ofs;
int char_ofs=0;
int ofs_y=i*get_row_height()+cache.line_spacing/2;
bool prev_is_char=false;
bool in_keyword=false;
Color keyword_color;
-
+
if (cache.line_number_w) {
Color fcol = cache.font_color;
fcol.a*=0.4;
@@ -663,191 +666,191 @@ void TextEdit::_notification(int p_what) {
while (fc.length() < line_number_char_count) {
fc="0"+fc;
}
-
+
cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol);
}
-
+
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(line);
-
-
+
+
if (text.is_marked(line)) {
-
+
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.mark_color);
}
-
+
if (text.is_breakpoint(line)) {
-
+
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.breakpoint_color);
}
-
-
+
+
if (line==cursor.line) {
-
+
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.current_line_color);
-
+
}
for (int j=0;j<str.length();j++) {
-
+
//look for keyword
-
+
if (deregion>0) {
deregion--;
if (deregion==0)
in_region=-1;
}
if (syntax_coloring && deregion==0) {
-
-
+
+
color = cache.font_color; //reset
//find keyword
bool is_char = _is_text_char(str[j]);
bool is_symbol=_is_symbol(str[j]);
-
+
if (j==0 && in_region>=0 && color_regions[in_region].line_only) {
in_region=-1; //reset regions that end at end of line
}
-
+
if (is_symbol && cri_map.has(j)) {
-
-
+
+
const Text::ColorRegionInfo &cri=cri_map[j];
-
+
if (in_region==-1) {
-
+
if (!cri.end) {
-
+
in_region=cri.region;
}
} else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise
-
+
if (cri.end || color_regions[cri.region].eq) {
-
+
deregion=color_regions[cri.region].eq?color_regions[cri.region].begin_key.length():color_regions[cri.region].end_key.length();
}
}
}
-
+
if (!is_char)
in_keyword=false;
-
+
if (in_region==-1 && !in_keyword && is_char && !prev_is_char) {
-
+
int to=j;
while(to<str.length() && _is_text_char(str[to]))
to++;
-
+
uint32_t hash = String::hash(&str[j],to-j);
StrRange range(&str[j],to-j);
-
+
const Color *col=keywords.custom_getptr(range,hash);
-
+
if (col) {
-
+
in_keyword=true;
keyword_color=*col;
}
}
-
-
+
+
if (in_region>=0)
color=color_regions[in_region].color;
else if (in_keyword)
color=keyword_color;
else if (is_symbol)
color=symbol_color;
-
+
prev_is_char=is_char;
-
+
}
int char_w;
-
+
//handle tabulator
-
-
+
+
if (str[j]=='\t') {
int left = char_ofs%tab_w;
if (left==0)
char_w=tab_w;
else
char_w=tab_w-char_ofs%tab_w; // is right...
-
+
} else {
char_w=cache.font->get_char_size(str[j],str[j+1]).width;
}
-
+
if ( (char_ofs+char_margin)<xmargin_beg) {
char_ofs+=char_w;
continue;
}
-
+
if ( (char_ofs+char_margin+char_w)>=xmargin_end) {
if (syntax_coloring)
continue;
else
break;
}
-
+
bool in_selection = (selection.active && line>=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (line<selection.to_line || j<selection.to_column));
-
-
+
+
if (in_selection) {
//inside selection!
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,get_row_height())),cache.selection_color);
}
-
-
+
+
if (brace_matching_enabled) {
if ( (brace_open_match_line==line && brace_open_match_column==j) ||
(cursor.column==j && cursor.line==line && (brace_open_matching||brace_open_mismatch))) {
-
+
if (brace_open_mismatch)
color=cache.brace_mismatch_color;
cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),'_',str[j+1],in_selection?cache.font_selected_color:color);
-
+
}
-
+
if (
(brace_close_match_line==line && brace_close_match_column==j) ||
(cursor.column==j+1 && cursor.line==line && (brace_close_matching||brace_close_mismatch))) {
-
-
+
+
if (brace_close_mismatch)
color=cache.brace_mismatch_color;
cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),'_',str[j+1],in_selection?cache.font_selected_color:color);
-
+
}
}
-
-
+
+
if (str[j]>=32)
cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color);
-
+
else if (draw_tabs && str[j]=='\t') {
int yofs= (get_row_height() - cache.tab_icon->get_height())/2;
cache.tab_icon->draw(ci, Point2(char_ofs+char_margin,ofs_y+yofs),in_selection?cache.font_selected_color:color);
}
-
-
+
+
if (cursor.column==j && cursor.line==line) {
-
+
cursor_pos = Point2i( char_ofs+char_margin, ofs_y );
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color);
-
-
+
+
}
char_ofs+=char_w;
-
+
}
-
+
if (cursor.column==str.length() && cursor.line==line && (char_ofs+char_margin)>=xmargin_beg) {
-
+
cursor_pos=Point2i( char_ofs+char_margin, ofs_y );
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color);
-
+
}
}
-
-
+
+ bool completion_below = false;
if (completion_active) {
// code completion box
Ref<StyleBox> csb = get_stylebox("completion");
@@ -858,15 +861,15 @@ void TextEdit::_notification(int p_what) {
existing.a=0.2;
int scrollw = get_constant("completion_scroll_width");
Color scrollc = get_color("completion_scroll_color");
-
-
-
+
+
+
int lines = MIN(completion_options.size(),maxlines);
int w=0;
int h=lines*get_row_height();
int nofs = cache.font->get_string_size(completion_base).width;
-
-
+
+
if (completion_options.size() < 50) {
for(int i=0;i<completion_options.size();i++) {
int w2=MIN(cache.font->get_string_size(completion_options[i]).x,cmax_width);
@@ -876,39 +879,40 @@ void TextEdit::_notification(int p_what) {
} else {
w=cmax_width;
}
-
+
int th = h + csb->get_minimum_size().y;
+
if (cursor_pos.y+get_row_height()+th > get_size().height) {
completion_rect.pos.y=cursor_pos.y-th;
} else {
completion_rect.pos.y=cursor_pos.y+get_row_height()+csb->get_offset().y;
-
+ completion_below = true;
}
-
+
if (cursor_pos.x-nofs+w+scrollw > get_size().width) {
completion_rect.pos.x=get_size().width-w-scrollw;
} else {
completion_rect.pos.x=cursor_pos.x-nofs;
}
-
+
completion_rect.size.width=w+2;
completion_rect.size.height=h;
if (completion_options.size()<=maxlines)
scrollw=0;
-
+
draw_style_box(csb,Rect2(completion_rect.pos-csb->get_offset(),completion_rect.size+csb->get_minimum_size()+Size2(scrollw,0)));
-
-
+
+
int line_from = CLAMP(completion_index - lines/2, 0, completion_options.size() - lines);
draw_style_box(csel,Rect2(Point2(completion_rect.pos.x,completion_rect.pos.y+(completion_index-line_from)*get_row_height()),Size2(completion_rect.size.width,get_row_height())));
-
+
draw_rect(Rect2(completion_rect.pos,Size2(nofs,completion_rect.size.height)),existing);
-
-
-
-
+
+
+
+
for(int i=0;i<lines;i++) {
-
+
int l = line_from + i;
ERR_CONTINUE( l < 0 || l>= completion_options.size());
Color text_color = cache.font_color;
@@ -919,31 +923,47 @@ void TextEdit::_notification(int p_what) {
}
draw_string(cache.font,Point2(completion_rect.pos.x,completion_rect.pos.y+i*get_row_height()+cache.font->get_ascent()),completion_options[l],text_color,completion_rect.size.width);
}
-
+
if (scrollw) {
//draw a small scroll rectangle to show a position in the options
float r = maxlines / (float)completion_options.size();
float o = line_from / (float)completion_options.size();
draw_rect(Rect2(completion_rect.pos.x+completion_rect.size.width,completion_rect.pos.y+o*completion_rect.size.y,scrollw,completion_rect.size.y*r),scrollc);
}
-
+
completion_line_ofs=line_from;
-
+
}
-
+
+ // check to see if the hint should be drawn
+ bool show_hint = false;
if (completion_hint!="") {
-
+ if (completion_active) {
+ if (completion_below && !callhint_below) {
+ show_hint = true;
+ }
+ else if (!completion_below && callhint_below) {
+ show_hint = true;
+ }
+ }
+ else {
+ show_hint = true;
+ }
+ }
+
+ if (show_hint) {
+
Ref<StyleBox> sb = get_stylebox("panel","TooltipPanel");
Ref<Font> font = cache.font;
Color font_color = get_color("font_color","TooltipLabel");
-
-
+
+
int max_w=0;
int sc = completion_hint.get_slice_count("\n");
int offset=0;
int spacing=0;
for(int i=0;i<sc;i++) {
-
+
String l = completion_hint.get_slice("\n",i);
int len = font->get_string_size(l).x;
max_w = MAX(len,max_w);
@@ -952,35 +972,43 @@ void TextEdit::_notification(int p_what) {
} else {
spacing+=cache.line_spacing;
}
-
-
+
+
}
-
-
-
+
+
+
Size2 size = Size2(max_w,sc*font->get_height()+spacing);
Size2 minsize = size+sb->get_minimum_size();
-
-
+
+
if (completion_hint_offset==-0xFFFF) {
completion_hint_offset=cursor_pos.x-offset;
}
-
-
- Point2 hint_ofs = Vector2(completion_hint_offset,cursor_pos.y-minsize.y);
+
+
+ Point2 hint_ofs = Vector2(completion_hint_offset,cursor_pos.y) + callhint_offset;
+
+ if (callhint_below) {
+ hint_ofs.y += get_row_height() + sb->get_offset().y;
+ }
+ else {
+ hint_ofs.y -= minsize.y + sb->get_offset().y;
+ }
+
draw_style_box(sb,Rect2(hint_ofs,minsize));
-
+
spacing=0;
for(int i=0;i<sc;i++) {
int begin=0;
int end=0;
String l = completion_hint.get_slice("\n",i);
-
+
if (l.find(String::chr(0xFFFF))!=-1) {
begin = font->get_string_size(l.substr(0,l.find(String::chr(0xFFFF)))).x;
end = font->get_string_size(l.substr(0,l.rfind(String::chr(0xFFFF)))).x;
}
-
+
draw_string(font,hint_ofs+sb->get_offset()+Vector2(0,font->get_ascent()+font->get_height()*i+spacing),l.replace(String::chr(0xFFFF),""),font_color);
if (end>0) {
Vector2 b = hint_ofs+sb->get_offset()+Vector2(begin,font->get_height()+font->get_height()*i+spacing-1);
@@ -989,60 +1017,60 @@ void TextEdit::_notification(int p_what) {
spacing+=cache.line_spacing;
}
}
-
-
+
+
} break;
case NOTIFICATION_FOCUS_ENTER: {
-
+
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect());
-
+
} break;
case NOTIFICATION_FOCUS_EXIT: {
-
+
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard();
-
+
} break;
-
+
}
}
void TextEdit::_consume_pair_symbol(CharType ch) {
-
+
int cursor_position_to_move = cursor_get_column() + 1;
-
+
CharType ch_single[2] = {ch, 0};
CharType ch_single_pair[2] = {_get_right_pair_symbol(ch), 0};
CharType ch_pair[3] = {ch, _get_right_pair_symbol(ch), 0};
-
+
if(is_selection_active()) {
-
+
int new_column,new_line;
-
+
_begin_compex_operation();
_insert_text(get_selection_from_line(), get_selection_from_column(),
ch_single,
&new_line, &new_column);
-
+
int to_col_offset = 0;
if(get_selection_from_line() == get_selection_to_line())
to_col_offset = 1;
-
+
_insert_text(get_selection_to_line(),
get_selection_to_column() + to_col_offset,
ch_single_pair,
&new_line,&new_column);
_end_compex_operation();
-
+
cursor_set_line(get_selection_to_line());
cursor_set_column(get_selection_to_column() + to_col_offset);
-
+
deselect();
update();
return;
}
-
+
if( (ch == '\'' || ch == '"') &&
cursor_get_column() > 0 &&
_is_text_char(text[cursor.line][cursor_get_column() - 1])
@@ -1051,7 +1079,7 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
cursor_set_column(cursor_position_to_move);
return;
}
-
+
if(cursor_get_column() < text[cursor.line].length()) {
if(_is_text_char(text[cursor.line][cursor_get_column()])) {
insert_text_at_cursor(ch_single);
@@ -1065,34 +1093,34 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
return;
}
}
-
-
+
+
insert_text_at_cursor(ch_pair);
cursor_set_column(cursor_position_to_move);
return;
-
+
}
void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column) {
-
+
bool remove_right_symbol = false;
-
+
if(cursor.column < text[cursor.line].length() && cursor.column > 0) {
-
+
CharType left_char = text[cursor.line][cursor.column - 1];
CharType right_char = text[cursor.line][cursor.column];
-
+
if(right_char == _get_right_pair_symbol(left_char)) {
remove_right_symbol = true;
}
-
+
}
if(remove_right_symbol) {
_remove_text(prev_line,prev_column,cursor.line,cursor.column + 1);
} else {
_remove_text(prev_line,prev_column,cursor.line,cursor.column);
}
-
+
}
void TextEdit::backspace_at_cursor() {
@@ -1101,7 +1129,7 @@ void TextEdit::backspace_at_cursor() {
if (cursor.column==0 && cursor.line==0)
return;
-
+
int prev_line = cursor.column?cursor.line:cursor.line-1;
int prev_column = cursor.column?(cursor.column-1):(text[cursor.line-1].length());
if(auto_brace_completion_enabled &&
@@ -1111,15 +1139,15 @@ void TextEdit::backspace_at_cursor() {
} else {
_remove_text(prev_line,prev_column,cursor.line,cursor.column);
}
-
+
cursor_set_line(prev_line);
cursor_set_column(prev_column);
-
+
}
void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const {
-
+
float rows=p_mouse.y;
rows-=cache.style_normal->get_margin(MARGIN_TOP);
rows/=get_row_height();
@@ -1129,56 +1157,56 @@ void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) co
row=0;
int col=0;
-
+
if (row>=text.size()) {
-
+
row=text.size()-1;
col=text[row].size();
} else {
-
+
col=p_mouse.x-(cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w);
col+=cursor.x_ofs;
col=get_char_pos_for( col, get_line(row) );
}
-
+
r_row=row;
r_col=col;
}
void TextEdit::_input_event(const InputEvent& p_input_event) {
-
+
switch(p_input_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &mb=p_input_event.mouse_button;
-
+
if (completion_active && completion_rect.has_point(Point2(mb.x,mb.y))) {
-
+
if (!mb.pressed)
return;
-
+
if (mb.button_index==BUTTON_WHEEL_UP) {
if (completion_index>0) {
completion_index--;
completion_current=completion_options[completion_index];
update();
}
-
+
}
if (mb.button_index==BUTTON_WHEEL_DOWN) {
-
+
if (completion_index<completion_options.size()-1) {
completion_index++;
completion_current=completion_options[completion_index];
update();
}
}
-
+
if (mb.button_index==BUTTON_LEFT) {
-
+
completion_index=CLAMP(completion_line_ofs+(mb.y-completion_rect.pos.y)/get_row_height(),0,completion_options.size()-1);
-
+
completion_current=completion_options[completion_index];
update();
if (mb.doubleclick)
@@ -1189,7 +1217,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
_cancel_completion();
_cancel_code_hint();
}
-
+
if (mb.pressed) {
if (mb.button_index==BUTTON_WHEEL_UP) {
v_scroll->set_val( v_scroll->get_val() -3 );
@@ -1197,19 +1225,25 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (mb.button_index==BUTTON_WHEEL_DOWN) {
v_scroll->set_val( v_scroll->get_val() +3 );
}
+ if (mb.button_index==BUTTON_WHEEL_LEFT) {
+ h_scroll->set_val( h_scroll->get_val() -3 );
+ }
+ if (mb.button_index==BUTTON_WHEEL_RIGHT) {
+ h_scroll->set_val( h_scroll->get_val() +3 );
+ }
if (mb.button_index==BUTTON_LEFT) {
-
+
int row,col;
_get_mouse_pos(Point2i(mb.x,mb.y), row,col);
-
+
int prev_col=cursor.column;
int prev_line=cursor.line;
-
-
-
+
+
+
cursor_set_line( row );
cursor_set_column( col );
-
+
if (mb.mod.shift && (cursor.column!=prev_col || cursor.line!=prev_line)) {
if (!selection.active) {
@@ -1264,99 +1298,99 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
-
+
} else {
-
+
//if sel active and dblick last time < something
-
+
//else
selection.active=false;
selection.selecting_mode=Selection::MODE_POINTER;
selection.selecting_line=row;
selection.selecting_column=col;
}
-
-
+
+
if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600 && cursor.line==prev_line) {
//tripleclick select line
select(cursor.line,0,cursor.line,text[cursor.line].length());
selection.selecting_column=0;
last_dblclk=0;
-
+
} else if (mb.doubleclick && text[cursor.line].length()) {
-
+
//doubleclick select world
String s = text[cursor.line];
int beg=CLAMP(cursor.column,0,s.length());
int end=beg;
-
+
if (s[beg]>32 || beg==s.length()) {
-
+
bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
-
+
while(beg>0 && s[beg-1]>32 && (symbol==_is_symbol(s[beg-1]))) {
beg--;
}
while(end<s.length() && s[end+1]>32 && (symbol==_is_symbol(s[end+1]))) {
end++;
}
-
+
if (end<s.length())
end+=1;
-
+
select(cursor.line,beg,cursor.line,end);
selection.selecting_column=beg;
}
-
+
last_dblclk = OS::get_singleton()->get_ticks_msec();
-
+
}
-
+
update();
}
} else {
if (mb.button_index==BUTTON_LEFT)
click_select_held->stop();
-
+
// notify to show soft keyboard
notification(NOTIFICATION_FOCUS_ENTER);
}
-
+
} break;
case InputEvent::MOUSE_MOTION: {
-
+
const InputEventMouseMotion &mm=p_input_event.mouse_motion;
-
+
if (mm.button_mask&BUTTON_MASK_LEFT) {
-
+
if (selection.selecting_mode!=Selection::MODE_NONE) {
int row,col;
_get_mouse_pos(Point2i(mm.x,mm.y), row,col);
-
+
select(selection.selecting_line,selection.selecting_column,row,col);
-
+
cursor_set_line( row );
cursor_set_column( col );
update();
click_select_held->start();
-
+
}
-
+
}
-
+
} break;
-
+
case InputEvent::KEY: {
-
+
InputEventKey k=p_input_event.key;
-
+
if (!k.pressed)
return;
-
+
if (completion_active) {
if (readonly)
break;
@@ -1364,9 +1398,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool valid=true;
if (k.mod.command || k.mod.meta)
valid=false;
-
+
if (valid) {
-
+
if (!k.mod.alt) {
if (k.scancode==KEY_UP) {
@@ -1465,13 +1499,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
return;
}
}
-
+
if (k.unicode>32) {
-
+
if (cursor.column<text[cursor.line].length() && text[cursor.line][cursor.column]==k.unicode) {
//same char, move ahead
cursor_set_column(cursor.column+1);
-
+
} else {
//different char, go back
const CharType chr[2] = {(CharType)k.unicode, 0};
@@ -1481,34 +1515,34 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
_insert_text_at_cursor(chr);
}
}
-
+
_update_completion_candidates();
accept_event();
-
+
return;
}
}
-
+
_cancel_completion();
-
+
}
-
+
/* TEST CONTROL FIRST!! */
-
+
// some remaps for duplicate functions..
if (k.mod.command && !k.mod.shift && !k.mod.alt && !k.mod.meta && k.scancode==KEY_INSERT) {
-
+
k.scancode=KEY_C;
}
if (!k.mod.command && k.mod.shift && !k.mod.alt && !k.mod.meta && k.scancode==KEY_INSERT) {
-
+
k.scancode=KEY_V;
k.mod.command=true;
k.mod.shift=false;
}
-
+
// stuff to do when selection is active..
-
+
if (selection.active) {
if (readonly)
@@ -1517,16 +1551,16 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool clear=false;
bool unselect=false;
bool dobreak=false;
-
+
switch(k.scancode) {
-
+
case KEY_TAB: {
-
+
String txt = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
String prev_txt=txt;
-
+
if (k.mod.shift) {
-
+
for(int i=0;i<txt.length();i++) {
if (((i>0 && txt[i-1]=='\n') || (i==0 /*&& selection.from_column==0*/)) && (txt[i]=='\t' || txt[i]==' ')) {
txt.remove(i);
@@ -1534,21 +1568,21 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
}
} else {
-
+
for(int i=0;i<txt.length();i++) {
-
+
if (((i>0 && txt[i-1]=='\n') || (i==0 /*&& selection.from_column==0*/))) {
txt=txt.insert(i,"\t");
//i--;
}
}
}
-
+
if (txt!=prev_txt) {
-
+
int sel_line=selection.from_line;
int sel_column=selection.from_column;
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
_begin_compex_operation();
@@ -1562,10 +1596,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
selection.to_line=cursor.line;
update();
}
-
+
dobreak=true;
accept_event();
-
+
} break;
case KEY_X:
case KEY_C:
@@ -1590,21 +1624,21 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
unselect=true;
break;
-
+
default:
if (k.unicode>=32 && !k.mod.command && !k.mod.alt && !k.mod.meta)
clear=true;
if (auto_brace_completion_enabled && _is_pair_left_symbol(k.unicode))
clear=false;
}
-
+
if (unselect) {
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
update();
}
if (clear) {
-
+
selection.active=false;
update();
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
@@ -1615,15 +1649,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (dobreak)
break;
}
-
+
selection.selecting_text=false;
-
+
bool scancode_handled=true;
-
+
// special scancode test...
-
+
switch (k.scancode) {
-
+
case KEY_ENTER:
case KEY_RETURN: {
@@ -1631,7 +1665,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
String ins="\n";
-
+
//keep indentation
for(int i=0;i<text[cursor.line].length();i++) {
if (text[cursor.line][i]=='\t')
@@ -1646,33 +1680,54 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
ins+="\t";
}
}
-
+
+ bool first_line = false;
+ if (k.mod.command) {
+ if (k.mod.shift) {
+ if (cursor.line > 0) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
+ }
+ else {
+ cursor_set_column(0);
+ first_line = true;
+ }
+ }
+ else {
+ cursor_set_column(text[cursor.line].length());
+ }
+ }
+
_insert_text_at_cursor(ins);
_push_current_op();
-
+
+ if (first_line) {
+ cursor_set_line(0);
+ }
+
} break;
case KEY_ESCAPE: {
if (completion_hint!="") {
completion_hint="";
update();
-
+
}
} break;
case KEY_TAB: {
-
+
if (readonly)
break;
-
+
if (selection.active) {
-
-
+
+
} else {
if (k.mod.shift) {
-
+
int cc = cursor.column;
if (cc>0 && cc<=text[cursor.line].length() && text[cursor.line][cursor.column-1]=='\t') {
//simple unindent
-
+
backspace_at_cursor();
}
} else {
@@ -1680,7 +1735,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
_insert_text_at_cursor("\t");
}
}
-
+
} break;
case KEY_BACKSPACE: {
if (readonly)
@@ -1748,15 +1803,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_left
}
case KEY_LEFT: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
#ifdef APPLE_STYLE_KEYS
if (k.mod.command) {
cursor_set_column(0);
} else if (k.mod.alt) {
-
+
#else
if (k.mod.alt) {
scancode_handled=false;
@@ -1766,21 +1821,21 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool prev_char=false;
int cc=cursor.column;
while (cc>0) {
-
+
bool ischar=_is_text_char(text[cursor.line][cc-1]);
-
+
if (prev_char && !ischar)
break;
-
+
prev_char=ischar;
cc--;
-
+
}
-
+
cursor_set_column(cc);
-
+
} else if (cursor.column==0) {
-
+
if (cursor.line>0) {
cursor_set_line(cursor.line-1);
cursor_set_column(text[cursor.line].length());
@@ -1788,10 +1843,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
cursor_set_column(cursor_get_column()-1);
}
-
+
if (k.mod.shift)
_post_shift_selection();
-
+
} break;
case KEY_KP_6: {
if (k.unicode != 0) {
@@ -1801,10 +1856,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_right
}
case KEY_RIGHT: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
#ifdef APPLE_STYLE_KEYS
if (k.mod.command) {
cursor_set_column(text[cursor.line].length());
@@ -1818,19 +1873,19 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool prev_char=false;
int cc=cursor.column;
while (cc<text[cursor.line].length()) {
-
+
bool ischar=_is_text_char(text[cursor.line][cc]);
-
+
if (prev_char && !ischar)
break;
prev_char=ischar;
cc++;
}
-
+
cursor_set_column(cc);
-
+
} else if (cursor.column==text[cursor.line].length()) {
-
+
if (cursor.line<text.size()-1) {
cursor_set_line(cursor.line+1);
cursor_set_column(0);
@@ -1838,10 +1893,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
cursor_set_column(cursor_get_column()+1);
}
-
+
if (k.mod.shift)
_post_shift_selection();
-
+
} break;
case KEY_KP_8: {
if (k.unicode != 0) {
@@ -1851,7 +1906,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_up
}
case KEY_UP: {
-
+
if (k.mod.shift)
_pre_shift_selection();
if (k.mod.alt) {
@@ -1864,11 +1919,11 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
else
#endif
cursor_set_line(cursor_get_line()-1);
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_code_hint();
-
+
} break;
case KEY_KP_2: {
if (k.unicode != 0) {
@@ -1878,7 +1933,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_down
}
case KEY_DOWN: {
-
+
if (k.mod.shift)
_pre_shift_selection();
if (k.mod.alt) {
@@ -1891,22 +1946,22 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
else
#endif
cursor_set_line(cursor_get_line()+1);
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_code_hint();
-
+
} break;
-
+
case KEY_DELETE: {
-
+
if (readonly)
break;
int curline_len = text[cursor.line].length();
-
+
if (cursor.line==text.size()-1 && cursor.column==curline_len)
break; //nothing to do
-
+
int next_line=cursor.column<curline_len?cursor.line:cursor.line+1;
int next_column;
@@ -1974,24 +2029,24 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
#ifdef APPLE_STYLE_KEYS
case KEY_HOME: {
-
-
+
+
if (k.mod.shift)
_pre_shift_selection();
-
+
cursor_set_line(0);
-
+
if (k.mod.shift)
_post_shift_selection();
-
+
} break;
#else
case KEY_HOME: {
-
-
+
+
if (k.mod.shift)
_pre_shift_selection();
-
+
// compute whitespace symbols seq length
int current_line_whitespace_len = 0;
while(current_line_whitespace_len < text[cursor.line].length()) {
@@ -2000,20 +2055,20 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
current_line_whitespace_len++;
}
-
+
if(cursor_get_column() == current_line_whitespace_len)
cursor_set_column(0);
else
cursor_set_column(current_line_whitespace_len);
-
+
if (k.mod.command)
cursor_set_line(0);
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
#endif
case KEY_KP_1: {
@@ -2037,20 +2092,20 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} break;
#else
case KEY_END: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
if (k.mod.command)
cursor_set_line(text.size()-1);
cursor_set_column(text[cursor.line].length());
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
#endif
case KEY_KP_9: {
@@ -2061,19 +2116,19 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_pageup
}
case KEY_PAGEUP: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
cursor_set_line(cursor_get_line()-get_visible_rows());
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
case KEY_KP_3: {
if (k.unicode != 0) {
@@ -2083,75 +2138,75 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_pageup
}
case KEY_PAGEDOWN: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
cursor_set_line(cursor_get_line()+get_visible_rows());
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
case KEY_A: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
select_all();
-
+
} break;
case KEY_X: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
if (!selection.active){
-
+
String clipboard = text[cursor.line];
OS::get_singleton()->set_clipboard(clipboard);
cursor_set_line(cursor.line);
cursor_set_column(0);
_remove_text(cursor.line,0,cursor.line,text[cursor.line].length());
-
+
backspace_at_cursor();
update();
cursor_set_line(cursor.line+1);
cut_copy_line = true;
-
+
}
else
{
-
+
String clipboard = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
OS::get_singleton()->set_clipboard(clipboard);
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
update();
cut_copy_line = false;
}
-
+
} break;
case KEY_C: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
if (!selection.active){
String clipboard = _base_get_text(cursor.line,0,cursor.line,text[cursor.line].length());
OS::get_singleton()->set_clipboard(clipboard);
@@ -2164,32 +2219,32 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
} break;
case KEY_Z: {
-
+
if (!k.mod.command) {
scancode_handled=false;
break;
}
-
+
if (k.mod.shift)
redo();
else
undo();
} break;
case KEY_V: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
String clipboard = OS::get_singleton()->get_clipboard();
-
+
if (selection.active) {
selection.active=false;
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
}
else if (cut_copy_line)
{
@@ -2197,9 +2252,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
String ins="\n";
clipboard += ins;
}
-
+
_insert_text_at_cursor(clipboard);
-
+
update();
} break;
case KEY_SPACE: {
@@ -2208,15 +2263,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
#else
if (completion_enabled && k.mod.command) {
#endif
-
+
query_code_comple();
scancode_handled=true;
} else {
scancode_handled=false;
}
-
+
} break;
-
+
case KEY_U:{
if (!k.mod.command || k.mod.shift) {
scancode_handled=false;
@@ -2239,40 +2294,40 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
update();
}
break;}
-
+
default: {
-
+
scancode_handled=false;
} break;
-
+
}
-
+
if (scancode_handled)
accept_event();
/*
if (!scancode_handled && !k.mod.command && !k.mod.alt) {
-
+
if (k.unicode>=32) {
-
+
if (readonly)
break;
-
+
accept_event();
} else {
-
+
break;
}
}
*/
if (!scancode_handled && !k.mod.command) { //for german kbds
-
+
if (k.unicode>=32) {
-
+
if (readonly)
break;
-
+
const CharType chr[2] = {(CharType)k.unicode, 0};
-
+
if (completion_hint!="" && k.unicode==')') {
completion_hint="";
}
@@ -2281,27 +2336,27 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
_insert_text_at_cursor(chr);
}
-
+
accept_event();
} else {
-
+
break;
}
}
-
+
return;
} break;
-
+
}
-
+
}
void TextEdit::_pre_shift_selection() {
-
-
+
+
if (!selection.active || selection.selecting_mode==Selection::MODE_NONE) {
-
+
selection.selecting_line=cursor.line;
selection.selecting_column=cursor.column;
selection.active=true;
@@ -2311,115 +2366,115 @@ void TextEdit::_pre_shift_selection() {
}
void TextEdit::_post_shift_selection() {
-
-
+
+
if (selection.active && selection.selecting_mode==Selection::MODE_SHIFT) {
-
+
select(selection.selecting_line,selection.selecting_column,cursor.line,cursor.column);
update();
}
-
-
+
+
selection.selecting_text=true;
}
/**** TEXT EDIT CORE API ****/
void TextEdit::_base_insert_text(int p_line, int p_char,const String& p_text,int &r_end_line,int &r_end_column) {
-
+
//save for undo...
ERR_FAIL_INDEX(p_line,text.size());
ERR_FAIL_COND(p_char<0);
-
+
/* STEP 1 add spaces if the char is greater than the end of the line */
while(p_char>text[p_line].length()) {
-
+
text.set(p_line,text[p_line]+String::chr(' '));
}
-
+
/* STEP 2 separate dest string in pre and post text */
-
+
String preinsert_text = text[p_line].substr(0,p_char);
String postinsert_text = text[p_line].substr(p_char,text[p_line].size());
-
+
/* STEP 3 remove \r from source text and separate in substrings */
-
+
//buh bye \r and split
Vector<String> substrings = p_text.replace("\r","").split("\n");
-
-
+
+
for(int i=0;i<substrings.size();i++) {
//insert the substrings
-
+
if (i==0) {
-
+
text.set(p_line,preinsert_text+substrings[i]);
} else {
-
+
text.insert(p_line+i,substrings[i]);
}
-
+
if (i==substrings.size()-1){
-
+
text.set(p_line+i,text[p_line+i]+postinsert_text);
}
}
-
+
r_end_line=p_line+substrings.size()-1;
r_end_column=text[r_end_line].length()-postinsert_text.length();
-
+
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_text_changed_emit");
text_changed_dirty=true;
}
-
+
}
String TextEdit::_base_get_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) const {
-
+
ERR_FAIL_INDEX_V(p_from_line,text.size(),String());
ERR_FAIL_INDEX_V(p_from_column,text[p_from_line].length()+1,String());
ERR_FAIL_INDEX_V(p_to_line,text.size(),String());
ERR_FAIL_INDEX_V(p_to_column,text[p_to_line].length()+1,String());
ERR_FAIL_COND_V(p_to_line < p_from_line ,String()); // from > to
ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column<p_from_column,String()); // from > to
-
+
String ret;
-
+
for(int i=p_from_line;i<=p_to_line;i++) {
-
+
int begin = (i==p_from_line)?p_from_column:0;
int end = (i==p_to_line)?p_to_column:text[i].length();
-
+
if (i>p_from_line)
ret+="\n";
ret+=text[i].substr(begin,end-begin);
}
-
+
return ret;
}
void TextEdit::_base_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) {
-
+
ERR_FAIL_INDEX(p_from_line,text.size());
ERR_FAIL_INDEX(p_from_column,text[p_from_line].length()+1);
ERR_FAIL_INDEX(p_to_line,text.size());
ERR_FAIL_INDEX(p_to_column,text[p_to_line].length()+1);
ERR_FAIL_COND(p_to_line < p_from_line ); // from > to
ERR_FAIL_COND(p_to_line == p_from_line && p_to_column<p_from_column); // from > to
-
-
+
+
String pre_text = text[p_from_line].substr(0,p_from_column);
String post_text = text[p_to_line].substr(p_to_column,text[p_to_line].length());
-
+
for(int i=p_from_line;i<p_to_line;i++) {
-
+
text.remove(p_from_line+1);
}
-
+
text.set(p_from_line,pre_text+post_text);
-
+
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_text_changed_emit");
@@ -2428,24 +2483,24 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column,int p_to_lin
}
void TextEdit::_insert_text(int p_line, int p_char,const String& p_text,int *r_end_line,int *r_end_column) {
-
+
if (!setting_text)
idle_detect->start();
-
+
if (undo_enabled) {
_clear_redo();
}
-
+
int retline,retchar;
_base_insert_text(p_line,p_char,p_text,retline,retchar);
if (r_end_line)
*r_end_line=retline;
if (r_end_column)
*r_end_column=retchar;
-
+
if (!undo_enabled)
return;
-
+
/* UNDO!! */
TextOperation op;
op.type=TextOperation::TYPE_INSERT;
@@ -2457,45 +2512,47 @@ void TextEdit::_insert_text(int p_line, int p_char,const String& p_text,int *r_e
op.version=++version;
op.chain_forward=false;
op.chain_backward=false;
-
+
//see if it shold just be set as current op
if (current_op.type!=op.type) {
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
-
+
return; //set as current op, return
}
//see if it can be merged
if (current_op.to_line!=p_line || current_op.to_column!=p_char) {
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
return; //set as current op, return
}
//merge current op
-
+
current_op.text+=p_text;
current_op.to_column=retchar;
current_op.to_line=retline;
current_op.version=op.version;
-
+
}
void TextEdit::_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) {
-
+
if (!setting_text)
idle_detect->start();
-
+
String text;
if (undo_enabled) {
_clear_redo();
text=_base_get_text(p_from_line,p_from_column,p_to_line,p_to_column);
}
-
+
_base_remove_text(p_from_line,p_from_column,p_to_line,p_to_column);
-
+
if (!undo_enabled)
return;
-
+
/* UNDO!! */
TextOperation op;
op.type=TextOperation::TYPE_REMOVE;
@@ -2507,9 +2564,10 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column,int p_to_line,int
op.version=++version;
op.chain_forward=false;
op.chain_backward=false;
-
+
//see if it shold just be set as current op
if (current_op.type!=op.type) {
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
return; //set as current op, return
@@ -2523,26 +2581,27 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column,int p_to_line,int
return; //update current op
}
if (current_op.from_line==p_from_line && current_op.from_column==p_from_column) {
-
+
//current_op.text=text+current_op.text;
//current_op.from_line=p_from_line;
//current_op.from_column=p_from_column;
//return; //update current op
}
-
+
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
-
+
}
void TextEdit::_insert_text_at_cursor(const String& p_text) {
-
+
int new_column,new_line;
_insert_text(cursor.line,cursor.column,p_text,&new_line,&new_column);
cursor_set_line(new_line);
cursor_set_column(new_column);
-
+
update();
}
@@ -2550,144 +2609,144 @@ void TextEdit::_insert_text_at_cursor(const String& p_text) {
int TextEdit::get_char_count() {
-
+
int totalsize=0;
-
+
for (int i=0;i<text.size();i++) {
-
+
if (i>0)
totalsize++; // incliude \n
totalsize+=text[i].length();
}
-
+
return totalsize; // omit last \n
}
Size2 TextEdit::get_minimum_size() {
-
+
return cache.style_normal->get_minimum_size();
}
int TextEdit::get_visible_rows() const {
-
+
int total=cache.size.height;
total-=cache.style_normal->get_minimum_size().height;
total/=get_row_height();
return total;
}
void TextEdit::adjust_viewport_to_cursor() {
-
+
if (cursor.line_ofs>cursor.line)
cursor.line_ofs=cursor.line;
-
+
int visible_width=cache.size.width-cache.style_normal->get_minimum_size().width-cache.line_number_w;
if (v_scroll->is_visible())
visible_width-=v_scroll->get_combined_minimum_size().width;
visible_width-=20; // give it a little more space
-
-
+
+
//printf("rowofs %i, visrows %i, cursor.line %i\n",cursor.line_ofs,get_visible_rows(),cursor.line);
-
+
int visible_rows = get_visible_rows();
if (h_scroll->is_visible())
visible_rows-=((h_scroll->get_combined_minimum_size().height-1)/get_row_height());
-
+
if (cursor.line>=(cursor.line_ofs+visible_rows))
cursor.line_ofs=cursor.line-visible_rows+1;
if (cursor.line<cursor.line_ofs)
cursor.line_ofs=cursor.line;
-
+
int cursor_x = get_column_x_offset( cursor.column, text[cursor.line] );
-
+
if (cursor_x>(cursor.x_ofs+visible_width))
cursor.x_ofs=cursor_x-visible_width+1;
-
+
if (cursor_x < cursor.x_ofs)
cursor.x_ofs=cursor_x;
-
+
update();
/*
get_range()->set_max(text.size());
-
+
get_range()->set_page(get_visible_rows());
-
+
get_range()->set((int)cursor.line_ofs);
*/
-
-
+
+
}
void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) {
-
+
if (p_col<0)
p_col=0;
-
+
cursor.column=p_col;
if (cursor.column > get_line( cursor.line ).length())
cursor.column=get_line( cursor.line ).length();
-
+
cursor.last_fit_x=get_column_x_offset(cursor.column,get_line(cursor.line));
-
+
if (p_adjust_viewport)
adjust_viewport_to_cursor();
-
+
if (!cursor_changed_dirty) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit");
cursor_changed_dirty=true;
}
-
+
}
void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) {
-
+
if (setting_row)
return;
-
+
setting_row=true;
if (p_row<0)
p_row=0;
-
-
+
+
if (p_row>=(int)text.size())
p_row=(int)text.size()-1;
-
+
cursor.line=p_row;
cursor.column=get_char_pos_for( cursor.last_fit_x, get_line( cursor.line) );
-
+
if (p_adjust_viewport)
adjust_viewport_to_cursor();
-
+
setting_row=false;
-
-
+
+
if (!cursor_changed_dirty) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit");
cursor_changed_dirty=true;
}
-
+
}
int TextEdit::cursor_get_column() const {
-
+
return cursor.column;
}
int TextEdit::cursor_get_line() const {
-
+
return cursor.line;
}
void TextEdit::_scroll_moved(double p_to_val) {
-
+
if (updating_scrolls)
return;
-
+
if (h_scroll->is_visible())
cursor.x_ofs=h_scroll->get_val();
if (v_scroll->is_visible())
@@ -2700,87 +2759,87 @@ void TextEdit::_scroll_moved(double p_to_val) {
int TextEdit::get_row_height() const {
-
+
return cache.font->get_height()+cache.line_spacing;
}
int TextEdit::get_char_pos_for(int p_px,String p_str) const {
-
+
int px=0;
int c=0;
-
+
int tab_w = cache.font->get_char_size(' ').width*tab_size;
-
+
while (c<p_str.length()) {
-
+
int w=0;
-
+
if (p_str[c]=='\t') {
-
+
int left = px%tab_w;
if (left==0)
w=tab_w;
else
w=tab_w-px%tab_w; // is right...
-
+
} else {
-
+
w=cache.font->get_char_size(p_str[c],p_str[c+1]).width;
}
-
+
if (p_px<(px+w/2))
break;
px+=w;
c++;
}
-
+
return c;
}
int TextEdit::get_column_x_offset(int p_char,String p_str) {
-
+
int px=0;
-
+
int tab_w = cache.font->get_char_size(' ').width*tab_size;
-
+
for (int i=0;i<p_char;i++) {
-
+
if (i>=p_str.length())
break;
-
+
if (p_str[i]=='\t') {
-
+
int left = px%tab_w;
if (left==0)
px+=tab_w;
else
px+=tab_w-px%tab_w; // is right...
-
+
} else {
px+=cache.font->get_char_size(p_str[i],p_str[i+1]).width;
}
}
-
+
return px;
-
+
}
void TextEdit::insert_text_at_cursor(const String& p_text) {
-
+
if (selection.active) {
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
-
+
}
-
+
_insert_text_at_cursor(p_text);
update();
-
+
}
Control::CursorShape TextEdit::get_cursor_shape(const Point2& p_pos) const {
@@ -2792,7 +2851,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2& p_pos) const {
void TextEdit::set_text(String p_text){
-
+
setting_text=true;
clear();
_insert_text_at_cursor(p_text);
@@ -2806,7 +2865,7 @@ void TextEdit::set_text(String p_text){
cursor_set_column(0);
update();
setting_text=false;
-
+
//get_range()->set(0);
};
@@ -2814,53 +2873,53 @@ String TextEdit::get_text() {
String longthing;
int len = text.size();
for (int i=0;i<len;i++) {
-
-
+
+
longthing+=text[i];
if (i!=len-1)
longthing+="\n";
}
-
+
return longthing;
-
+
};
String TextEdit::get_text_for_completion() {
-
+
String longthing;
int len = text.size();
for (int i=0;i<len;i++) {
-
+
if (i==cursor.line) {
longthing+=text[i].substr(0,cursor.column);
longthing+=String::chr(0xFFFF); //not unicode, represents the cursor
longthing+=text[i].substr(cursor.column,text[i].size());
} else {
-
+
longthing+=text[i];
}
-
-
+
+
if (i!=len-1)
longthing+="\n";
}
-
+
return longthing;
-
+
};
String TextEdit::get_line(int line) const {
-
+
if (line<0 || line>=text.size())
return "";
-
+
return text[line];
-
+
};
void TextEdit::_clear() {
-
+
clear_undo_history();
text.clear();
cursor.column=0;
@@ -2873,31 +2932,31 @@ void TextEdit::_clear() {
void TextEdit::clear() {
-
+
setting_text=true;
_clear();
setting_text=false;
-
+
};
void TextEdit::set_readonly(bool p_readonly) {
-
-
+
+
readonly=p_readonly;
}
void TextEdit::set_wrap(bool p_wrap) {
-
+
wrap=p_wrap;
}
void TextEdit::set_max_chars(int p_max_chars) {
-
+
max_chars=p_max_chars;
}
void TextEdit::_update_caches() {
-
+
cache.style_normal=get_stylebox("normal");
cache.style_focus=get_stylebox("focus");
cache.font=get_font("font");
@@ -2913,12 +2972,12 @@ void TextEdit::_update_caches() {
cache.row_height = cache.font->get_height() + cache.line_spacing;
cache.tab_icon=get_icon("tab");
text.set_font(cache.font);
-
+
}
void TextEdit::clear_colors() {
-
+
keywords.clear();
color_regions.clear();;
text.clear_caches();
@@ -2926,40 +2985,40 @@ void TextEdit::clear_colors() {
}
void TextEdit::set_custom_bg_color(const Color& p_color) {
-
+
custom_bg_color=p_color;
update();
}
void TextEdit::add_keyword_color(const String& p_keyword,const Color& p_color) {
-
+
keywords[p_keyword]=p_color;
update();
-
+
}
void TextEdit::add_color_region(const String& p_begin_key,const String& p_end_key,const Color &p_color,bool p_line_only) {
-
+
color_regions.push_back(ColorRegion(p_begin_key,p_end_key,p_color,p_line_only));
text.clear_caches();
update();
-
+
}
void TextEdit::set_symbol_color(const Color& p_color) {
-
+
symbol_color=p_color;
update();
}
void TextEdit::set_syntax_coloring(bool p_enabled) {
-
+
syntax_coloring=p_enabled;
update();
}
bool TextEdit::is_syntax_coloring_enabled() const {
-
+
return syntax_coloring;
}
@@ -2968,28 +3027,28 @@ void TextEdit::set_auto_indent(bool p_auto_indent) {
}
void TextEdit::cut() {
-
+
if (!selection.active)
return;
-
+
String clipboard = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
OS::get_singleton()->set_clipboard(clipboard);
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
update();
-
+
}
void TextEdit::copy() {
-
+
if (!selection.active)
return;
-
+
print_line("from line: "+itos(selection.from_line));
print_line("from column: "+itos(selection.from_column));
print_line("to line: "+itos(selection.to_line));
@@ -2997,29 +3056,29 @@ void TextEdit::copy() {
String clipboard = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
OS::get_singleton()->set_clipboard(clipboard);
-
+
}
void TextEdit::paste() {
-
+
if (selection.active) {
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
-
+
}
-
+
String clipboard = OS::get_singleton()->get_clipboard();
_insert_text_at_cursor(clipboard);
update();
-
+
}
void TextEdit::select_all() {
-
+
if (text.size()==1 && text[0].length()==0)
return;
selection.active=true;
@@ -3034,43 +3093,43 @@ void TextEdit::select_all() {
cursor_set_line( selection.to_line, false );
cursor_set_column( selection.to_column, false );
update();
-
+
}
void TextEdit::deselect() {
-
+
selection.active=false;
update();
}
void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_column) {
-
+
if (p_from_line>=text.size())
p_from_line=text.size()-1;
if (p_from_column>=text[p_from_line].length())
p_from_column=text[p_from_line].length();
-
+
if (p_to_line>=text.size())
p_to_line=text.size()-1;
if (p_to_column>=text[p_to_line].length())
p_to_column=text[p_to_line].length();
-
+
selection.from_line=p_from_line;
selection.from_column=p_from_column;
selection.to_line=p_to_line;
selection.to_column=p_to_column;
-
+
selection.active=true;
-
+
if (selection.from_line==selection.to_line) {
-
+
if (selection.from_column==selection.to_column) {
-
+
selection.active=false;
-
+
} else if (selection.from_column>selection.to_column) {
-
+
selection.shiftclick_left = false;
SWAP( selection.from_column, selection.to_column );
} else {
@@ -3078,7 +3137,7 @@ void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_c
selection.shiftclick_left = true;
}
} else if (selection.from_line>selection.to_line) {
-
+
selection.shiftclick_left = false;
SWAP( selection.from_line, selection.to_line );
SWAP( selection.from_column, selection.to_column );
@@ -3086,51 +3145,51 @@ void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_c
selection.shiftclick_left = true;
}
-
-
+
+
update();
}
bool TextEdit::is_selection_active() const {
-
+
return selection.active;
}
int TextEdit::get_selection_from_line() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.from_line;
-
+
}
int TextEdit::get_selection_from_column() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.from_column;
-
+
}
int TextEdit::get_selection_to_line() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.to_line;
-
+
}
int TextEdit::get_selection_to_column() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.to_column;
-
+
}
String TextEdit::get_selection_text() const {
-
+
if (!selection.active)
return "";
-
+
return _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
-
+
}
String TextEdit::get_word_under_cursor() const {
-
+
int prev_cc = cursor.column;
while(prev_cc >0) {
bool is_char = _is_text_char(text[cursor.line][prev_cc-1]);
@@ -3138,7 +3197,7 @@ String TextEdit::get_word_under_cursor() const {
break;
--prev_cc;
}
-
+
int next_cc = cursor.column;
while(next_cc<text[cursor.line].length()) {
bool is_char = _is_text_char(text[cursor.line][next_cc]);
@@ -3152,7 +3211,7 @@ String TextEdit::get_word_under_cursor() const {
}
DVector<int> TextEdit::_search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const {
-
+
int col,line;
if (search(p_key,p_search_flags,p_from_line,p_from_column,col,line)) {
DVector<int> result;
@@ -3160,46 +3219,46 @@ DVector<int> TextEdit::_search_bind(const String &p_key,uint32_t p_search_flags,
result.set(0,line);
result.set(1,col);
return result;
-
+
} else {
-
+
return DVector<int>();
}
}
bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_line, int p_from_column,int &r_line,int &r_column) const {
-
+
if (p_key.length()==0)
return false;
ERR_FAIL_INDEX_V(p_from_line,text.size(),false);
ERR_FAIL_INDEX_V(p_from_column,text[p_from_line].length()+1,false);
-
+
//search through the whole documment, but start by current line
-
+
int line=-1;
int pos=-1;
-
+
line=p_from_line;
-
+
for(int i=0;i<text.size()+1;i++) {
//backwards is broken...
//int idx=(p_search_flags&SEARCH_BACKWARDS)?(text.size()-i):i; //do backwards seearch
-
-
+
+
if (line<0) {
line=text.size()-1;
}
if (line==text.size()) {
line=0;
}
-
+
String text_line = text[line];
int from_column=0;
if (line==p_from_line) {
-
+
if (i==text.size()) {
//wrapped
-
+
if (p_search_flags&SEARCH_BACKWARDS) {
text_line=text_line.substr(from_column,text_line.length());
from_column=text_line.length();
@@ -3207,13 +3266,13 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
text_line=text_line.substr(0,from_column);
from_column=0;
}
-
+
} else {
-
+
from_column=p_from_column;
}
-
-
+
+
} else {
//text_line=text_line.substr(0,p_from_column); //wrap around for missing begining.
if (p_search_flags&SEARCH_BACKWARDS)
@@ -3221,17 +3280,17 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
else
from_column=0;
}
-
+
pos=-1;
-
+
if (!(p_search_flags&SEARCH_BACKWARDS)) {
-
+
pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,from_column):text_line.findn(p_key,from_column);
} else {
-
+
pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.rfind(p_key,from_column):text_line.rfindn(p_key,from_column);
}
-
+
if (pos!=-1 && (p_search_flags&SEARCH_WHOLE_WORDS)) {
//validate for whole words
if (pos>0 && _is_text_char(text_line[pos-1]))
@@ -3239,66 +3298,66 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
else if (_is_text_char(text_line[pos+p_key.length()]))
pos=-1;
}
-
+
if (pos!=-1)
break;
-
+
if (p_search_flags&SEARCH_BACKWARDS)
line--;
else
line++;
-
+
}
-
+
if (pos==-1) {
r_line=-1;
r_column=-1;
return false;
}
-
+
r_line=line;
r_column=pos;
-
-
+
+
return true;
}
void TextEdit::_cursor_changed_emit() {
-
+
emit_signal("cursor_changed");
cursor_changed_dirty=false;
}
void TextEdit::_text_changed_emit() {
-
+
emit_signal("text_changed");
text_changed_dirty=false;
}
void TextEdit::set_line_as_marked(int p_line,bool p_marked) {
-
+
ERR_FAIL_INDEX(p_line,text.size());
text.set_marked(p_line,p_marked);
update();
}
bool TextEdit::is_line_set_as_breakpoint(int p_line) const {
-
+
ERR_FAIL_INDEX_V(p_line,text.size(),false);
return text.is_breakpoint(p_line);
-
+
}
void TextEdit::set_line_as_breakpoint(int p_line,bool p_breakpoint) {
-
-
+
+
ERR_FAIL_INDEX(p_line,text.size());
text.set_breakpoint(p_line,p_breakpoint);
update();
}
void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
-
+
for(int i=0;i<text.size();i++) {
if (text.is_breakpoint(i))
p_breakpoints->push_back(i);
@@ -3306,39 +3365,39 @@ void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
}
int TextEdit::get_line_count() const {
-
+
return text.size();
}
void TextEdit::_do_text_op(const TextOperation& p_op, bool p_reverse) {
-
+
ERR_FAIL_COND(p_op.type==TextOperation::TYPE_NONE);
-
+
bool insert = p_op.type==TextOperation::TYPE_INSERT;
if (p_reverse)
insert=!insert;
-
+
if (insert) {
-
+
int check_line;
int check_column;
_base_insert_text(p_op.from_line,p_op.from_column,p_op.text,check_line,check_column);
ERR_FAIL_COND( check_line != p_op.to_line ); // BUG
ERR_FAIL_COND( check_column != p_op.to_column ); // BUG
} else {
-
+
_base_remove_text(p_op.from_line,p_op.from_column,p_op.to_line,p_op.to_column);
}
-
+
}
void TextEdit::_clear_redo() {
-
+
if (undo_stack_pos==NULL)
return; //nothing to clear
-
+
_push_current_op();
-
+
while (undo_stack_pos) {
List<TextOperation>::Element *elem = undo_stack_pos;
undo_stack_pos=undo_stack_pos->next();
@@ -3348,61 +3407,69 @@ void TextEdit::_clear_redo() {
void TextEdit::undo() {
-
+
_push_current_op();
-
+
if (undo_stack_pos==NULL) {
-
+
if (!undo_stack.size())
return; //nothing to undo
-
+
undo_stack_pos=undo_stack.back();
-
+
} else if (undo_stack_pos==undo_stack.front())
return; // at the bottom of the undo stack
else
undo_stack_pos=undo_stack_pos->prev();
-
- _do_text_op( undo_stack_pos->get(),true);
+
+ TextOperation op = undo_stack_pos->get();
+ _do_text_op(op, true);
+ current_op.version=op.prev_version;
if(undo_stack_pos->get().chain_backward) {
do {
undo_stack_pos = undo_stack_pos->prev();
- _do_text_op(undo_stack_pos->get(), true);
+ op = undo_stack_pos->get();
+ _do_text_op(op, true);
+ current_op.version = op.prev_version;
} while(!undo_stack_pos->get().chain_forward);
}
-
+
cursor_set_line(undo_stack_pos->get().from_line);
cursor_set_column(undo_stack_pos->get().from_column);
update();
}
void TextEdit::redo() {
-
+
_push_current_op();
-
+
if (undo_stack_pos==NULL)
return; //nothing to do.
-
- _do_text_op(undo_stack_pos->get(), false);
+
+ TextOperation op = undo_stack_pos->get();
+ _do_text_op(op, false);
+ current_op.version = op.version;
if(undo_stack_pos->get().chain_forward) {
do {
undo_stack_pos=undo_stack_pos->next();
- _do_text_op(undo_stack_pos->get(), false);
+ op = undo_stack_pos->get();
+ _do_text_op(op, false);
+ current_op.version = op.version;
} while(!undo_stack_pos->get().chain_backward);
}
- cursor_set_line(undo_stack_pos->get().from_line);
- cursor_set_column(undo_stack_pos->get().from_column);
+ cursor_set_line(undo_stack_pos->get().to_line);
+ cursor_set_column(undo_stack_pos->get().to_column);
undo_stack_pos=undo_stack_pos->next();
update();
}
void TextEdit::clear_undo_history() {
-
+
saved_version=0;
current_op.type=TextOperation::TYPE_NONE;
undo_stack_pos=NULL;
undo_stack.clear();
-
+
}
void TextEdit::_begin_compex_operation() {
@@ -3411,42 +3478,49 @@ void TextEdit::_begin_compex_operation() {
}
void TextEdit::_end_compex_operation() {
-
+
_push_current_op();
ERR_FAIL_COND(undo_stack.size() == 0);
-
+
if(undo_stack.back()->get().chain_forward) {
undo_stack.back()->get().chain_forward=false;
return;
}
-
+
undo_stack.back()->get().chain_backward=true;
}
void TextEdit::_push_current_op() {
-
+
if (current_op.type==TextOperation::TYPE_NONE)
return; // do nothing
-
+
if(next_operation_is_complex) {
current_op.chain_forward=true;
next_operation_is_complex=false;
}
-
+
undo_stack.push_back(current_op);
current_op.type=TextOperation::TYPE_NONE;
current_op.text="";
current_op.chain_forward=false;
-
+
+}
+
+void TextEdit::set_tab_size(const int p_size) {
+ ERR_FAIL_COND(p_size <= 0);
+ tab_size = p_size;
+ text.set_tab_size(p_size);
+ update();
}
void TextEdit::set_draw_tabs(bool p_draw) {
-
+
draw_tabs=p_draw;
}
bool TextEdit::is_drawing_tabs() const{
-
+
return draw_tabs;
}
@@ -3454,35 +3528,35 @@ uint32_t TextEdit::get_version() const {
return current_op.version;
}
uint32_t TextEdit::get_saved_version() const {
-
+
return saved_version;
}
void TextEdit::tag_saved_version() {
-
+
saved_version=get_version();
}
int TextEdit::get_v_scroll() const {
-
+
return v_scroll->get_val();
}
void TextEdit::set_v_scroll(int p_scroll) {
-
+
v_scroll->set_val(p_scroll);
cursor.line_ofs=p_scroll;
}
int TextEdit::get_h_scroll() const {
-
+
return h_scroll->get_val();
}
void TextEdit::set_h_scroll(int p_scroll) {
-
+
h_scroll->set_val(p_scroll);
}
void TextEdit::set_completion(bool p_enabled,const Vector<String>& p_prefixes) {
-
+
completion_prefixes.clear();
completion_enabled=p_enabled;
for(int i=0;i<p_prefixes.size();i++)
@@ -3490,7 +3564,7 @@ void TextEdit::set_completion(bool p_enabled,const Vector<String>& p_prefixes) {
}
void TextEdit::_confirm_completion() {
-
+
String remaining=completion_current.substr(completion_base.length(),completion_current.length()-completion_base.length());
String l = text[cursor.line];
bool same=true;
@@ -3502,7 +3576,7 @@ void TextEdit::_confirm_completion() {
break;
}
}
-
+
if (same)
cursor_set_column(cursor.column+remaining.length());
else {
@@ -3512,7 +3586,7 @@ void TextEdit::_confirm_completion() {
cursor.column--;
}
}
-
+
_cancel_completion();
}
@@ -3523,27 +3597,27 @@ void TextEdit::_cancel_code_hint() {
}
void TextEdit::_cancel_completion() {
-
+
if (!completion_active)
return;
-
+
completion_active=false;
update();
-
+
}
static bool _is_completable(CharType c) {
-
+
return !_is_symbol(c) || c=='"' || c=='\'';
}
void TextEdit::_update_completion_candidates() {
-
+
String l = text[cursor.line];
int cofs = CLAMP(cursor.column,0,l.length());
-
-
+
+
String s;
//look for keywords first
@@ -3599,15 +3673,15 @@ void TextEdit::_update_completion_candidates() {
}
}
-
+
update();
-
+
if (cancel || (!pre_keyword && s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1]))))) {
//none to complete, cancel
_cancel_completion();
return;
}
-
+
completion_options.clear();
completion_index=0;
completion_base=s;
@@ -3620,7 +3694,7 @@ void TextEdit::_update_completion_candidates() {
if (max<ci_match)
continue;
for(int j=0;j<max;j++) {
-
+
if (j>=completion_strings[i].length())
break;
if (completion_current[j]!=completion_strings[i][j])
@@ -3631,21 +3705,21 @@ void TextEdit::_update_completion_candidates() {
ci_match=m;
completion_index=completion_options.size()-1;
}
-
+
}
}
-
-
-
+
+
+
if (completion_options.size()==0) {
//no options to complete, cancel
_cancel_completion();
return;
-
+
}
-
+
completion_current=completion_options[completion_index];
-
+
#if 0 // even there's only one option, user still get the chance to choose using it or not
if (completion_options.size()==1) {
//one option to complete, just complete it automagically
@@ -3653,22 +3727,22 @@ void TextEdit::_update_completion_candidates() {
// insert_text_at_cursor(completion_options[0].substr(s.length(),completion_options[0].length()-s.length()));
_cancel_completion();
return;
-
+
}
#endif
if (completion_options.size()==1 && s==completion_options[0])
_cancel_completion();
-
+
completion_enabled=true;
}
void TextEdit::query_code_comple() {
-
+
String l = text[cursor.line];
int ofs = CLAMP(cursor.column,0,l.length());
-
+
bool inquote=false;
int c=ofs-1;
@@ -3680,20 +3754,20 @@ void TextEdit::query_code_comple() {
if (ofs>0 && (inquote || _is_completable(l[ofs-1]) || completion_prefixes.has(String::chr(l[ofs-1]))))
emit_signal("request_completion");
-
+
}
void TextEdit::set_code_hint(const String& p_hint) {
-
+
completion_hint=p_hint;
completion_hint_offset=-0xFFFF;
update();
}
void TextEdit::code_complete(const Vector<String> &p_strings) {
-
-
+
+
completion_strings=p_strings;
completion_active=true;
completion_current="";
@@ -3704,7 +3778,7 @@ void TextEdit::code_complete(const Vector<String> &p_strings) {
String TextEdit::get_tooltip(const Point2& p_pos) const {
-
+
if (!tooltip_obj)
return Control::get_tooltip(p_pos);
int row,col;
@@ -3715,34 +3789,34 @@ String TextEdit::get_tooltip(const Point2& p_pos) const {
return Control::get_tooltip(p_pos);
int beg=CLAMP(col,0,s.length());
int end=beg;
-
-
+
+
if (s[beg]>32 || beg==s.length()) {
-
+
bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
-
+
while(beg>0 && s[beg-1]>32 && (symbol==_is_symbol(s[beg-1]))) {
beg--;
}
while(end<s.length() && s[end+1]>32 && (symbol==_is_symbol(s[end+1]))) {
end++;
}
-
+
if (end<s.length())
end+=1;
-
+
String tt = tooltip_obj->call(tooltip_func,s.substr(beg,end-beg),tooltip_ud);
-
+
return tt;
-
+
}
-
+
return Control::get_tooltip(p_pos);
-
+
}
void TextEdit::set_tooltip_request_func(Object *p_obj, const StringName& p_function,const Variant& p_udata) {
-
+
tooltip_obj=p_obj;
tooltip_func=p_function;
tooltip_ud=p_udata;
@@ -3767,7 +3841,7 @@ void TextEdit::insert_at(const String &p_text, int at)
}
void TextEdit::set_show_line_numbers(bool p_show) {
-
+
line_numbers=p_show;
update();
}
@@ -3777,48 +3851,48 @@ bool TextEdit::is_text_field() const {
return true;
}
void TextEdit::_bind_methods() {
-
-
+
+
ObjectTypeDB::bind_method(_MD("_input_event"),&TextEdit::_input_event);
ObjectTypeDB::bind_method(_MD("_scroll_moved"),&TextEdit::_scroll_moved);
ObjectTypeDB::bind_method(_MD("_cursor_changed_emit"),&TextEdit::_cursor_changed_emit);
ObjectTypeDB::bind_method(_MD("_text_changed_emit"),&TextEdit::_text_changed_emit);
ObjectTypeDB::bind_method(_MD("_push_current_op"),&TextEdit::_push_current_op);
ObjectTypeDB::bind_method(_MD("_click_selection_held"),&TextEdit::_click_selection_held);
-
+
BIND_CONSTANT( SEARCH_MATCH_CASE );
BIND_CONSTANT( SEARCH_WHOLE_WORDS );
BIND_CONSTANT( SEARCH_BACKWARDS );
-
+
/*
ObjectTypeDB::bind_method(_MD("delete_char"),&TextEdit::delete_char);
ObjectTypeDB::bind_method(_MD("delete_line"),&TextEdit::delete_line);
*/
-
+
ObjectTypeDB::bind_method(_MD("set_text","text"),&TextEdit::set_text);
ObjectTypeDB::bind_method(_MD("insert_text_at_cursor","text"),&TextEdit::insert_text_at_cursor);
-
+
ObjectTypeDB::bind_method(_MD("get_line_count"),&TextEdit::get_line_count);
ObjectTypeDB::bind_method(_MD("get_text"),&TextEdit::get_text);
ObjectTypeDB::bind_method(_MD("get_line","line"),&TextEdit::get_line);
-
+
ObjectTypeDB::bind_method(_MD("cursor_set_column","column","adjust_viewport"),&TextEdit::cursor_set_column,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("cursor_set_line","line","adjust_viewport"),&TextEdit::cursor_set_line,DEFVAL(false));
-
+
ObjectTypeDB::bind_method(_MD("cursor_get_column"),&TextEdit::cursor_get_column);
ObjectTypeDB::bind_method(_MD("cursor_get_line"),&TextEdit::cursor_get_line);
-
-
+
+
ObjectTypeDB::bind_method(_MD("set_readonly","enable"),&TextEdit::set_readonly);
ObjectTypeDB::bind_method(_MD("set_wrap","enable"),&TextEdit::set_wrap);
ObjectTypeDB::bind_method(_MD("set_max_chars","amount"),&TextEdit::set_max_chars);
-
+
ObjectTypeDB::bind_method(_MD("cut"),&TextEdit::cut);
ObjectTypeDB::bind_method(_MD("copy"),&TextEdit::copy);
ObjectTypeDB::bind_method(_MD("paste"),&TextEdit::paste);
ObjectTypeDB::bind_method(_MD("select_all"),&TextEdit::select_all);
ObjectTypeDB::bind_method(_MD("select","from_line","from_column","to_line","to_column"),&TextEdit::select);
-
+
ObjectTypeDB::bind_method(_MD("is_selection_active"),&TextEdit::is_selection_active);
ObjectTypeDB::bind_method(_MD("get_selection_from_line"),&TextEdit::get_selection_from_line);
ObjectTypeDB::bind_method(_MD("get_selection_from_column"),&TextEdit::get_selection_from_column);
@@ -3827,30 +3901,30 @@ void TextEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_selection_text"),&TextEdit::get_selection_text);
ObjectTypeDB::bind_method(_MD("get_word_under_cursor"),&TextEdit::get_word_under_cursor);
ObjectTypeDB::bind_method(_MD("search","flags","from_line","from_column","to_line","to_column"),&TextEdit::_search_bind);
-
+
ObjectTypeDB::bind_method(_MD("undo"),&TextEdit::undo);
ObjectTypeDB::bind_method(_MD("redo"),&TextEdit::redo);
ObjectTypeDB::bind_method(_MD("clear_undo_history"),&TextEdit::clear_undo_history);
-
+
ObjectTypeDB::bind_method(_MD("set_syntax_coloring","enable"),&TextEdit::set_syntax_coloring);
ObjectTypeDB::bind_method(_MD("is_syntax_coloring_enabled"),&TextEdit::is_syntax_coloring_enabled);
-
-
+
+
ObjectTypeDB::bind_method(_MD("add_keyword_color","keyword","color"),&TextEdit::add_keyword_color);
ObjectTypeDB::bind_method(_MD("add_color_region","begin_key","end_key","color","line_only"),&TextEdit::add_color_region,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_symbol_color","color"),&TextEdit::set_symbol_color);
ObjectTypeDB::bind_method(_MD("set_custom_bg_color","color"),&TextEdit::set_custom_bg_color);
ObjectTypeDB::bind_method(_MD("clear_colors"),&TextEdit::clear_colors);
-
-
+
+
ADD_SIGNAL(MethodInfo("cursor_changed"));
ADD_SIGNAL(MethodInfo("text_changed"));
ADD_SIGNAL(MethodInfo("request_completion"));
-
+
}
TextEdit::TextEdit() {
-
+
readonly=false;
setting_row=false;
draw_tabs=false;
@@ -3870,29 +3944,29 @@ TextEdit::TextEdit() {
// text.insert(1,"Mongolia..");
// text.insert(2,"PAIS GENEROSO!!");
text.set_color_regions(&color_regions);
-
+
h_scroll = memnew( HScrollBar );
v_scroll = memnew( VScrollBar );
-
+
add_child(h_scroll);
add_child(v_scroll);
-
+
updating_scrolls=false;
selection.active=false;
-
+
h_scroll->connect("value_changed", this,"_scroll_moved");
v_scroll->connect("value_changed", this,"_scroll_moved");
-
+
cursor_changed_dirty=false;
text_changed_dirty=false;
-
+
selection.selecting_mode=Selection::MODE_NONE;
selection.selecting_line=0;
selection.selecting_column=0;
selection.selecting_text=false;
selection.active=false;
syntax_coloring=false;
-
+
custom_bg_color=Color(0,0,0,0);
idle_detect = memnew( Timer );
add_child(idle_detect);
@@ -3904,7 +3978,7 @@ TextEdit::TextEdit() {
add_child(click_select_held);
click_select_held->set_wait_time(0.05);
click_select_held->connect("timeout", this,"_click_selection_held");
-
+
#if 0
syntax_coloring=true;
keywords["void"]=Color(0.3,0.0,0.1);
@@ -3914,15 +3988,15 @@ TextEdit::TextEdit() {
keywords["extends"]=Color(0.3,0.0,0.1);
keywords["constructor"]=Color(0.3,0.0,0.1);
symbol_color=Color(0.1,0.0,0.3,1.0);
-
+
color_regions.push_back(ColorRegion("/*","*/",Color(0.4,0.6,0,4)));
color_regions.push_back(ColorRegion("//","",Color(0.6,0.6,0.4)));
color_regions.push_back(ColorRegion("\"","\"",Color(0.4,0.7,0.7)));
color_regions.push_back(ColorRegion("'","'",Color(0.4,0.8,0.8)));
color_regions.push_back(ColorRegion("#","",Color(0.2,1.0,0.2)));
-
+
#endif
-
+
current_op.type=TextOperation::TYPE_NONE;
undo_enabled=true;
undo_stack_pos=NULL;
@@ -3931,13 +4005,14 @@ TextEdit::TextEdit() {
current_op.version=0;
version=0;
saved_version=0;
-
+
completion_enabled=false;
completion_active=false;
completion_line_ofs=0;
tooltip_obj=NULL;
line_numbers=false;
next_operation_is_complex=false;
+ scroll_past_end_of_file_enabled=false;
auto_brace_completion_enabled=false;
brace_matching_enabled=false;
auto_indent=false;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 2ca5ab054a..d38c57804d 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -128,7 +128,7 @@ class TextEdit : public Control {
void set_font(const Ref<Font>& p_font);
void set_color_regions(const Vector<ColorRegion>*p_regions) { color_regions=p_regions; }
int get_line_width(int p_line) const;
- int get_max_width() const;
+ int get_max_width() const;
const Map<int,ColorRegionInfo>& get_color_region_info(int p_line);
void set(int p_line,const String& p_string);
void set_marked(int p_line,bool p_marked) { text[p_line].marked=p_marked; }
@@ -156,6 +156,7 @@ class TextEdit : public Control {
int from_line,from_column;
int to_line, to_column;
String text;
+ uint32_t prev_version;
uint32_t version;
bool chain_forward;
bool chain_backward;
@@ -210,7 +211,8 @@ class TextEdit : public Control {
bool text_changed_dirty;
bool undo_enabled;
bool line_numbers;
-
+
+ bool scroll_past_end_of_file_enabled;
bool auto_brace_completion_enabled;
bool brace_matching_enabled;
bool auto_indent;
@@ -228,9 +230,12 @@ class TextEdit : public Control {
Object *tooltip_obj;
StringName tooltip_func;
Variant tooltip_ud;
-
+
bool next_operation_is_complex;
+ bool callhint_below;
+ Vector2 callhint_offset;
+
int get_visible_rows() const;
int get_char_count();
@@ -254,13 +259,13 @@ class TextEdit : public Control {
void _update_caches();
void _cursor_changed_emit();
void _text_changed_emit();
-
+
void _begin_compex_operation();
void _end_compex_operation();
void _push_current_op();
/* super internal api, undo/redo builds on it */
-
+
void _base_insert_text(int p_line, int p_column,const String& p_text,int &r_end_line,int &r_end_column);
String _base_get_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) const;
void _base_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column);
@@ -278,16 +283,16 @@ class TextEdit : public Control {
protected:
virtual String get_tooltip(const Point2& p_pos) const;
-
+
void _insert_text(int p_line, int p_column,const String& p_text,int *r_end_line=NULL,int *r_end_char=NULL);
void _remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column);
void _insert_text_at_cursor(const String& p_text);
void _input_event(const InputEvent& p_input);
void _notification(int p_what);
-
+
void _consume_pair_symbol(CharType ch);
void _consume_backspace_for_pair_symbol(int prev_line, int prev_column);
-
+
static void _bind_methods();
@@ -300,7 +305,7 @@ public:
SEARCH_WHOLE_WORDS=2,
SEARCH_BACKWARDS=4
};
-
+
virtual CursorShape get_cursor_shape(const Point2& p_pos=Point2i()) const;
//void delete_char();
@@ -318,7 +323,11 @@ public:
String get_line(int line) const;
void set_line(int line, String new_text);
void backspace_at_cursor();
-
+
+ inline void set_scroll_pass_end_of_file(bool p_enabled) {
+ scroll_past_end_of_file_enabled = p_enabled;
+ update();
+ }
inline void set_auto_brace_completion(bool p_enabled) {
auto_brace_completion_enabled = p_enabled;
}
@@ -326,6 +335,10 @@ public:
brace_matching_enabled=p_enabled;
update();
}
+ inline void set_callhint_settings(bool below, Vector2 offset) {
+ callhint_below = below;
+ callhint_offset = offset;
+ }
void set_auto_indent(bool p_auto_indent);
void cursor_set_column(int p_col, bool p_adjust_viewport=true);
@@ -366,7 +379,7 @@ public:
void redo();
void clear_undo_history();
-
+ void set_tab_size(const int p_size);
void set_draw_tabs(bool p_draw);
bool is_drawing_tabs() const;
@@ -390,7 +403,7 @@ public:
void set_tooltip_request_func(Object *p_obj, const StringName& p_function, const Variant& p_udata);
- void set_completion(bool p_enabled,const Vector<String>& p_prefixes);
+ void set_completion(bool p_enabled,const Vector<String>& p_prefixes);
void code_complete(const Vector<String> &p_strings);
void set_code_hint(const String& p_hint);
void query_code_comple();
diff --git a/scene/gui/texture_frame.h b/scene/gui/texture_frame.h
index f6fe6ae89d..e1f0de92df 100644
--- a/scene/gui/texture_frame.h
+++ b/scene/gui/texture_frame.h
@@ -42,7 +42,7 @@ class TextureFrame : public Control {
Ref<Texture> texture;
protected:
- void _notification(int p_what);
+ void _notification(int p_what);
virtual Size2 get_minimum_size() const;
static void _bind_methods();
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index e05d35a81d..923a35031c 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -195,7 +195,7 @@ void TextureProgress::_notification(int p_what){
draw_texture_rect_region(progress,Rect2(Point2(),Size2(s.x*get_unit_value(),s.y)),Rect2(Point2(),Size2(s.x*get_unit_value(),s.y)));
}
-
+
}
if (over.is_valid())
draw_texture(over,Point2());
@@ -269,10 +269,10 @@ void TextureProgress::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_radial_initial_angle","mode"),&TextureProgress::set_radial_initial_angle);
ObjectTypeDB::bind_method(_MD("get_radial_initial_angle"), &TextureProgress::get_radial_initial_angle);
-
+
ObjectTypeDB::bind_method(_MD("set_radial_center_offset","mode"),&TextureProgress::set_radial_center_offset);
ObjectTypeDB::bind_method(_MD("get_radial_center_offset"), &TextureProgress::get_radial_center_offset);
-
+
ObjectTypeDB::bind_method(_MD("set_fill_degrees","mode"),&TextureProgress::set_fill_degrees);
ObjectTypeDB::bind_method(_MD("get_fill_degrees"), &TextureProgress::get_fill_degrees);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 3b25701944..483aa47f35 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -482,7 +482,7 @@ void TreeItem::deselect(int p_column) {
_cell_deselected(p_column);
}
-void TreeItem::add_button(int p_column,const Ref<Texture>& p_button,int p_id) {
+void TreeItem::add_button(int p_column, const Ref<Texture>& p_button, int p_id, bool p_disabled) {
ERR_FAIL_INDEX( p_column, cells.size() );
@@ -492,6 +492,7 @@ void TreeItem::add_button(int p_column,const Ref<Texture>& p_button,int p_id) {
if (p_id<0)
p_id=cells[p_column].buttons.size();
button.id=p_id;
+ button.disabled=p_disabled;
cells[p_column].buttons.push_back(button);
_changed_notify(p_column);
}
@@ -533,6 +534,15 @@ int TreeItem::get_button_by_id(int p_column,int p_id) const {
return -1;
}
+
+bool TreeItem::is_button_disabled(int p_column, int p_idx) const {
+
+ ERR_FAIL_INDEX_V( p_column, cells.size(), false );
+ ERR_FAIL_INDEX_V( p_idx, cells[p_column].buttons.size(), false );
+
+ return cells[p_column].buttons[p_idx].disabled;
+
+}
void TreeItem::set_button(int p_column,int p_idx,const Ref<Texture>& p_button){
ERR_FAIL_COND( p_button.is_null() );
@@ -564,7 +574,14 @@ void TreeItem::set_custom_color(int p_column,const Color& p_color) {
cells[p_column].color=p_color;
_changed_notify(p_column);
}
+Color TreeItem::get_custom_color(int p_column) const {
+
+ ERR_FAIL_INDEX_V( p_column, cells.size(), Color() );
+ if (!cells[p_column].custom_color)
+ return Color();
+ return cells[p_column].color;
+}
void TreeItem::clear_custom_color(int p_column) {
ERR_FAIL_INDEX( p_column, cells.size() );
@@ -672,10 +689,11 @@ void TreeItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear_custom_bg_color","column"),&TreeItem::clear_custom_bg_color);
ObjectTypeDB::bind_method(_MD("get_custom_bg_color","column"),&TreeItem::get_custom_bg_color);
- ObjectTypeDB::bind_method(_MD("add_button","column","button:Texture","button_idx"),&TreeItem::add_button);
+ ObjectTypeDB::bind_method(_MD("add_button","column","button:Texture","button_idx","disabled"),&TreeItem::add_button,DEFVAL(-1),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_button_count","column"),&TreeItem::get_button_count);
ObjectTypeDB::bind_method(_MD("get_button:Texture","column","button_idx"),&TreeItem::get_button);
ObjectTypeDB::bind_method(_MD("erase_button","column","button_idx"),&TreeItem::erase_button);
+ ObjectTypeDB::bind_method(_MD("is_button_disabled","column","button_idx"),&TreeItem::is_button_disabled);
ObjectTypeDB::bind_method(_MD("set_tooltip","column","tooltip"),&TreeItem::set_tooltip);
ObjectTypeDB::bind_method(_MD("get_tooltip","column"),&TreeItem::get_tooltip);
@@ -1015,14 +1033,15 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2&
Point2i o = Point2i( ofs+w-s.width, p_pos.y )-cache.offset+p_draw_ofs;
- if (cache.click_type==Cache::CLICK_BUTTON && cache.click_item==p_item && cache.click_column==i) {
+ if (cache.click_type==Cache::CLICK_BUTTON && cache.click_item==p_item && cache.click_column==i && !p_item->cells[i].buttons[j].disabled) {
//being pressed
cache.button_pressed->draw(get_canvas_item(),Rect2(o,s));
}
o.y+=(label_h-s.height)/2;
o+=cache.button_pressed->get_offset();
- b->draw(ci,o);
+
+ b->draw(ci,o,p_item->cells[i].buttons[j].disabled?Color(1,1,1,0.5):Color(1,1,1,1));
w-=s.width+cache.button_margin;
bw+=s.width+cache.button_margin;
}
@@ -1472,7 +1491,13 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
for(int j=c.buttons.size()-1;j>=0;j--) {
Ref<Texture> b=c.buttons[j].texture;
int w = b->get_size().width + cache.button_pressed->get_minimum_size().width;
+
if (x>col_width-w) {
+ if (c.buttons[j].disabled) {
+ pressed_button=-1;
+ cache.click_type=Cache::CLICK_NONE;
+ return -1;
+ }
pressed_button=j;
cache.click_type=Cache::CLICK_BUTTON;
cache.click_index=j;
@@ -2146,7 +2171,7 @@ void Tree::_input_event(InputEvent p_event) {
float diff_y = -b.relative_y;
diff_y=Math::pow(ABS(diff_y),1.8)*SGN(diff_y);
diff_y*=0.1;
- range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
+ range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
popup_edited_item->set_range(popup_edited_item_col,range_drag_base);
item_edited(popup_edited_item_col,popup_edited_item);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index e4d349978c..1ba1c6a494 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -46,22 +46,22 @@ class TreeItem : public Object {
OBJ_TYPE(TreeItem,Object);
public:
-
+
enum TreeCellMode {
-
+
CELL_MODE_STRING, ///< just a string
CELL_MODE_CHECK, ///< string + check
CELL_MODE_RANGE, ///< Contains a range
CELL_MODE_ICON, ///< Contains a icon, not editable
CELL_MODE_CUSTOM, ///< Contains a custom value, show a string, and an edit button
};
-
+
private:
friend class Tree;
-
-
+
+
struct Cell {
-
+
TreeCellMode mode;
Ref<Texture> icon;
@@ -86,14 +86,15 @@ friend class Tree;
struct Button {
int id;
+ bool disabled;
Ref<Texture> texture;
- Button() { id=0; }
+ Button() { id=0; disabled=false; }
};
Vector< Button > buttons;
-
+
Cell() {
-
+
custom_draw_obj=0;
mode=TreeItem::CELL_MODE_STRING;
min=0;
@@ -115,30 +116,30 @@ friend class Tree;
void draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size=Size2()) const;
};
-
+
Vector<Cell> cells;
-
+
bool collapsed; // wont show childs
-
+
TreeItem *parent; // parent item
TreeItem *next; // next in list
TreeItem *childs; //child items
Tree *tree; //tree (for reference)
-
+
TreeItem(Tree *p_tree);
-
+
void _changed_notify(int p_cell);
void _changed_notify();
void _cell_selected(int p_cell);
void _cell_deselected(int p_cell);
protected:
-
+
static void _bind_methods();
//bind helpers
- Dictionary _get_range_config( int p_column ) {
+ Dictionary _get_range_config( int p_column ) {
Dictionary d;
double min,max,step;
get_range_config(p_column,min,max,step);
@@ -151,18 +152,18 @@ protected:
}
void _remove_child(Object *p_child) { remove_child( p_child->cast_to<TreeItem>() ); }
public:
-
+
/* cell mode */
void set_cell_mode( int p_column, TreeCellMode p_mode );
TreeCellMode get_cell_mode( int p_column ) const;
-
+
/* check mode */
void set_checked(int p_column,bool p_checked);
bool is_checked(int p_column) const;
-
+
void set_text(int p_column,String p_text);
String get_text(int p_column) const;
-
+
void set_icon(int p_column,const Ref<Texture>& p_icon);
Ref<Texture> get_icon(int p_column) const;
@@ -172,31 +173,32 @@ public:
void set_icon_max_width(int p_column,int p_max);
int get_icon_max_width(int p_column) const;
- void add_button(int p_column,const Ref<Texture>& p_button,int p_id=-1);
+ void add_button(int p_column,const Ref<Texture>& p_button,int p_id=-1,bool p_disabled=false);
int get_button_count(int p_column) const;
Ref<Texture> get_button(int p_column,int p_idx) const;
int get_button_id(int p_column,int p_idx) const;
void erase_button(int p_column,int p_idx);
int get_button_by_id(int p_column,int p_id) const;
+ bool is_button_disabled(int p_column,int p_idx) const;
void set_button(int p_column,int p_idx,const Ref<Texture>& p_button);
/* range works for mode number or mode combo */
-
+
void set_range(int p_column,double p_value);
double get_range(int p_column) const;
-
+
void set_range_config(int p_column,double p_min,double p_max,double p_step,bool p_exp=false);
void get_range_config(int p_column,double& r_min,double& r_max,double &r_step) const;
bool is_range_exponential(int p_column) const;
-
+
void set_metadata(int p_column,const Variant& p_meta);
Variant get_metadata(int p_column) const;
-
+
void set_custom_draw(int p_column,Object *p_object,const StringName& p_callback);
-
+
void set_collapsed(bool p_collapsed);
bool is_collapsed();
-
+
TreeItem *get_prev();
TreeItem *get_next();
TreeItem *get_parent();
@@ -204,21 +206,22 @@ public:
TreeItem *get_prev_visible();
TreeItem *get_next_visible();
-
+
void remove_child(TreeItem *p_item);
-
+
void set_selectable(int p_column,bool p_selectable);
bool is_selectable(int p_column) const;
-
+
bool is_selected(int p_column);
void select(int p_column);
void deselect(int p_column);
void set_as_cursor(int p_column);
-
+
void set_editable(int p_column,bool p_editable);
bool is_editable(int p_column);
-
+
void set_custom_color(int p_column,const Color& p_color);
+ Color get_custom_color(int p_column) const;
void clear_custom_color(int p_column);
void set_custom_bg_color(int p_column,const Color& p_color);
@@ -235,7 +238,7 @@ public:
void move_to_bottom();
~TreeItem();
-
+
};
@@ -243,18 +246,18 @@ VARIANT_ENUM_CAST( TreeItem::TreeCellMode );
class Tree : public Control {
-
+
OBJ_TYPE( Tree, Control );
-public:
+public:
enum SelectMode {
SELECT_SINGLE,
SELECT_ROW,
SELECT_MULTI
};
-
-private:
-friend class TreeItem;
-
+
+private:
+friend class TreeItem;
+
TreeItem *root;
TreeItem *popup_edited_item;
TreeItem *selected_item;
@@ -285,7 +288,7 @@ friend class TreeItem;
int blocked;
struct ColumnInfo {
-
+
int min_width;
bool expand;
String title;
@@ -318,21 +321,21 @@ friend class TreeItem;
void value_editor_changed(double p_value);
void popup_select(int p_option);
-
+
void _input_event(InputEvent p_event);
void _notification(int p_what);
-
+
Size2 get_minimum_size() const;
-
+
void item_edited(int p_column,TreeItem *p_item);
void item_changed(int p_column,TreeItem *p_item);
void item_selected(int p_column,TreeItem *p_item);
void item_deselected(int p_column,TreeItem *p_item);
-
+
void propagate_set_columns(TreeItem *p_item);
-
+
struct Cache {
-
+
Ref<Font> font;
Ref<Font> tb_font;
Ref<StyleBox> bg;
@@ -352,14 +355,14 @@ friend class TreeItem;
Ref<Texture> arrow;
Ref<Texture> select_arrow;
Ref<Texture> updown;
-
+
Color font_color;
Color font_color_selected;
Color guide_color;
int hseparation;
int vseparation;
int item_margin;
- int guide_width;
+ int guide_width;
int button_margin;
Point2 offset;
@@ -379,14 +382,14 @@ friend class TreeItem;
int hover_index;
} cache;
-
-
+
+
int _get_title_button_height() const;
void _scroll_moved(float p_value);
HScrollBar *h_scroll;
VScrollBar *v_scroll;
-
+
Size2 get_internal_min_size() const;
void update_cache();
void update_scrollbars();
@@ -421,10 +424,10 @@ friend class TreeItem;
protected:
static void _bind_methods();
-
+
//bind helpers
Object* _create_item(Object *p_parent) { return create_item(p_parent->cast_to<TreeItem>() ); }
- TreeItem *_get_next_selected(Object *p_item) { return get_next_selected(p_item->cast_to<TreeItem>() ); }
+ TreeItem *_get_next_selected(Object *p_item) { return get_next_selected(p_item->cast_to<TreeItem>() ); }
Rect2 _get_item_rect(Object *p_item,int p_column) const { return get_item_rect(p_item->cast_to<TreeItem>(),p_column ); }
public:
@@ -432,21 +435,21 @@ public:
void clear();
- TreeItem* create_item(TreeItem *p_parent=0);
+ TreeItem* create_item(TreeItem *p_parent=0);
TreeItem* get_root();
TreeItem* get_last_item();
void set_column_min_width(int p_column,int p_min_width);
- void set_column_expand(int p_column,bool p_expand);
+ void set_column_expand(int p_column,bool p_expand);
int get_column_width(int p_column) const;
-
+
void set_hide_root(bool p_eanbled);
TreeItem *get_next_selected( TreeItem* p_item);
TreeItem *get_selected() const;
int get_selected_column() const;
int get_pressed_button() const;
void set_select_mode(SelectMode p_mode);
-
+
void set_columns(int p_columns);
int get_columns() const;
@@ -460,11 +463,11 @@ public:
int get_edited_column() const;
void ensure_cursor_is_visible();
-
+
Rect2 get_custom_popup_rect() const;
int get_item_offset(TreeItem *p_item) const;
- Rect2 get_item_rect(TreeItem *p_item,int p_column=-1) const;
+ Rect2 get_item_rect(TreeItem *p_item,int p_column=-1) const;
bool edit_selected();
TreeItem* search_item_text(const String& p_find,int *r_col=NULL,bool p_selectable=false);
@@ -482,7 +485,7 @@ public:
Tree();
- ~Tree();
+ ~Tree();
};
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index 517cd414c5..fc7cc0a362 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -393,7 +393,7 @@ void VideoPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_buffering_msec","msec"),&VideoPlayer::set_buffering_msec);
ObjectTypeDB::bind_method(_MD("get_buffering_msec"),&VideoPlayer::get_buffering_msec);
- ObjectTypeDB::bind_method(_MD("get_video_texutre:Texture"), &VideoPlayer::get_video_texture );
+ ObjectTypeDB::bind_method(_MD("get_video_texture:Texture"), &VideoPlayer::get_video_texture );
ADD_PROPERTY( PropertyInfo(Variant::INT, "stream/audio_track",PROPERTY_HINT_RANGE,"0,128,1"), _SCS("set_audio_track"), _SCS("get_audio_track") );
ADD_PROPERTY( PropertyInfo(Variant::OBJECT, "stream/stream", PROPERTY_HINT_RESOURCE_TYPE,"VideoStream"), _SCS("set_stream"), _SCS("get_stream") );
diff --git a/scene/io/resource_format_image.cpp b/scene/io/resource_format_image.cpp
index c80975dbfe..6174d134a3 100644
--- a/scene/io/resource_format_image.cpp
+++ b/scene/io/resource_format_image.cpp
@@ -32,7 +32,7 @@
#include "globals.h"
#include "os/os.h"
RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_original_path, Error *r_error) {
-
+
if (r_error)
*r_error=ERR_CANT_OPEN;
@@ -45,31 +45,31 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
Error err;
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
if (err) {
-
+
ERR_FAIL_COND_V( err, RES() );
}
-
+
String base_path=p_path.substr( 0, p_path.find_last("/")+1 );
for(int i=0;i<6;i++) {
-
+
String file = f->get_line().strip_edges();
Image image;
-
+
Error err = ImageLoader::load_image(base_path+file,&image);
-
+
if (err) {
-
+
memdelete(f);
ERR_FAIL_COND_V( err, RES() );
}
-
+
if (i==0) {
-
+
//cubemap->create(image.get_width(),image.get_height(),image.get_format(),Texture::FLAGS_DEFAULT|Texture::FLAG_CUBEMAP);
}
-
+
static const CubeMap::Side cube_side[6]= {
CubeMap::SIDE_LEFT,
CubeMap::SIDE_RIGHT,
@@ -78,10 +78,10 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
CubeMap::SIDE_FRONT,
CubeMap::SIDE_BACK
};
-
+
cubemap->set_side(cube_side[i],image);
}
-
+
memdelete(f);
cubemap->set_name(p_path.get_file());
@@ -89,9 +89,9 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
*r_error=OK;
return cubemap;
-
+
} else {
- // simple image
+ // simple image
ImageTexture* ptr = memnew(ImageTexture);
Ref<ImageTexture> texture( ptr );
@@ -115,7 +115,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
ERR_EXPLAIN("Failed loading image: "+p_path);
- ERR_FAIL_COND_V(err, RES());
+ ERR_FAIL_COND_V(err, RES());
if (r_error)
*r_error=ERR_FILE_CORRUPT;
@@ -134,8 +134,8 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
}
#endif
#endif
-
-
+
+
uint32_t flags=0;
FileAccess *f2 = FileAccess::open(p_path+".flags",FileAccess::READ);
@@ -186,7 +186,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
if (flags_found["tolinear"])
flags|=Texture::FLAG_CONVERT_TO_LINEAR;
}
-
+
if (flags_found.has("mirroredrepeat")) {
if (flags_found["mirroredrepeat"])
flags|=Texture::FLAG_MIRRORED_REPEAT;
@@ -210,7 +210,7 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_origin
return RES( texture );
}
-
+
}
@@ -220,7 +220,7 @@ bool ResourceFormatLoaderImage::handles_type(const String& p_type) const {
}
void ResourceFormatLoaderImage::get_recognized_extensions(List<String> *p_extensions) const {
-
+
ImageLoader::get_recognized_extensions(p_extensions);
p_extensions->push_back("cube");
}
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
new file mode 100644
index 0000000000..90e3713799
--- /dev/null
+++ b/scene/main/http_request.cpp
@@ -0,0 +1,512 @@
+#include "http_request.h"
+
+void HTTPRequest::_redirect_request(const String& p_new_url) {
+
+
+}
+
+Error HTTPRequest::_request() {
+
+ print_line("Requesting:\n\tURL: "+url+"\n\tString: "+request_string+"\n\tPort: "+itos(port)+"\n\tSSL: "+itos(use_ssl)+"\n\tValidate SSL: "+itos(validate_ssl));
+ return client->connect(url,port,use_ssl,validate_ssl);
+}
+
+Error HTTPRequest::_parse_url(const String& p_url) {
+
+ url=p_url;
+ use_ssl=false;
+
+ request_string="";
+ port=80;
+ request_sent=false;
+ got_response=false;
+ body_len=-1;
+ body.resize(0);
+ downloaded=0;
+ redirections=0;
+
+ print_line("1 url: "+url);
+ if (url.begins_with("http://")) {
+
+ url=url.substr(7,url.length()-7);
+ print_line("no SSL");
+
+ } else if (url.begins_with("https://")) {
+ url=url.substr(8,url.length()-8);
+ use_ssl=true;
+ port=443;
+ print_line("yes SSL");
+ } else {
+ ERR_EXPLAIN("Malformed URL");
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ }
+
+ print_line("2 url: "+url);
+
+ int slash_pos = url.find("/");
+
+ if (slash_pos!=-1) {
+ request_string=url.substr(slash_pos,url.length());
+ url=url.substr(0,slash_pos);
+ print_line("request string: "+request_string);
+ } else {
+ request_string="/";
+ print_line("no request");
+ }
+
+ print_line("3 url: "+url);
+
+ int colon_pos = url.find(":");
+ if (colon_pos!=-1) {
+ port=url.substr(colon_pos+1,url.length()).to_int();
+ url=url.substr(0,colon_pos);
+ ERR_FAIL_COND_V(port<1 || port > 65535,ERR_INVALID_PARAMETER);
+ }
+
+ print_line("4 url: "+url);
+
+ return OK;
+}
+
+Error HTTPRequest::request(const String& p_url, const Vector<String>& p_custom_headers, bool p_ssl_validate_domain) {
+
+ ERR_FAIL_COND_V(!is_inside_tree(),ERR_UNCONFIGURED);
+ if ( requesting ) {
+ ERR_EXPLAIN("HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one.");
+ ERR_FAIL_V(ERR_BUSY);
+ }
+
+ Error err = _parse_url(p_url);
+ validate_ssl=p_ssl_validate_domain;
+
+ bool has_user_agent=false;
+ bool has_accept=false;
+ headers=p_custom_headers;
+
+ for(int i=0;i<headers.size();i++) {
+
+ if (headers[i].findn("user-agent:")==0)
+ has_user_agent=true;
+ if (headers[i].findn("Accept:")==0)
+ has_accept=true;
+ }
+
+ if (!has_user_agent) {
+ headers.push_back("User-Agent: GodotEngine/"+String(VERSION_MKSTRING)+" ("+OS::get_singleton()->get_name()+")");
+ }
+
+ if (!has_accept) {
+ headers.push_back("Accept: */*");
+ }
+
+
+ err = _request();
+
+ if (err==OK) {
+ set_process(true);
+ requesting=true;
+ }
+
+
+ return err;
+}
+
+
+void HTTPRequest::cancel_request() {
+
+ if (!requesting)
+ return;
+
+ if (!use_threads) {
+ set_process(false);
+ }
+
+ if (file) {
+ memdelete(file);
+ file=NULL;
+ }
+ client->close();
+ body.resize(0);
+ //downloaded=0;
+ got_response=false;
+ response_code=-1;
+ //body_len=-1;
+ request_sent=false;
+ requesting=false;
+}
+
+
+bool HTTPRequest::_handle_response(bool *ret_value) {
+
+ if (!client->has_response()) {
+ call_deferred("emit_signal","request_completed",RESULT_NO_RESPONSE,0,StringArray(),ByteArray());
+ *ret_value=true;
+ return true;
+ }
+
+ got_response=true;
+ response_code=client->get_response_code();
+ List<String> rheaders;
+ client->get_response_headers(&rheaders);
+ response_headers.resize(0);
+ downloaded=0;
+ for (List<String>::Element *E=rheaders.front();E;E=E->next()) {
+ print_line("HEADER: "+E->get());
+ response_headers.push_back(E->get());
+ }
+
+ if (response_code==301 || response_code==302) {
+ //redirect
+ if (max_redirects>=0 && redirections>=max_redirects) {
+
+ call_deferred("emit_signal","request_completed",RESULT_REDIRECT_LIMIT_REACHED,response_code,response_headers,ByteArray());
+ *ret_value=true;
+ return true;
+ }
+
+ String new_request;
+
+ for (List<String>::Element *E=rheaders.front();E;E=E->next()) {
+ if (E->get().findn("Location: ")!=-1) {
+ new_request=E->get().substr(9,E->get().length()).strip_edges();
+ }
+ }
+
+ print_line("NEW LOCATION: "+new_request);
+
+ if (new_request!="") {
+ //process redirect
+ client->close();
+ int new_redirs=redirections+1; //because _request() will clear it
+ Error err;
+ if (new_request.begins_with("http")) {
+ //new url, request all again
+ err=_parse_url(new_request);
+ } else {
+ request_string=new_request;
+ }
+
+ err = _request();
+
+ print_line("new connection: "+itos(err));
+ if (err==OK) {
+ request_sent=false;
+ got_response=false;
+ body_len=-1;
+ body.resize(0);
+ downloaded=0;
+ redirections=new_redirs;
+ *ret_value=false;
+ return true;
+
+ }
+ }
+ }
+
+ return false;
+}
+
+
+bool HTTPRequest::_update_connection() {
+
+ switch( client->get_status() ) {
+ case HTTPClient::STATUS_DISCONNECTED: {
+ return true; //end it, since it's doing something
+ } break;
+ case HTTPClient::STATUS_RESOLVING: {
+ client->poll();
+ //must wait
+ return false;
+ } break;
+ case HTTPClient::STATUS_CANT_RESOLVE: {
+ call_deferred("emit_signal","request_completed",RESULT_CANT_RESOLVE,0,StringArray(),ByteArray());
+ return true;
+
+ } break;
+ case HTTPClient::STATUS_CONNECTING: {
+ client->poll();
+ //must wait
+ return false;
+ } break; //connecting to ip
+ case HTTPClient::STATUS_CANT_CONNECT: {
+
+ call_deferred("emit_signal","request_completed",RESULT_CANT_CONNECT,0,StringArray(),ByteArray());
+ return true;
+
+ } break;
+ case HTTPClient::STATUS_CONNECTED: {
+
+ if (request_sent) {
+
+ if (!got_response) {
+
+ //no body
+
+ bool ret_value;
+
+ if (_handle_response(&ret_value))
+ return ret_value;
+
+
+ call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray());
+ return true;
+ }
+ if (got_response && body_len<0) {
+ //chunked transfer is done
+ call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body);
+ return true;
+
+ }
+
+ call_deferred("emit_signal","request_completed",RESULT_CHUNKED_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray());
+ return true;
+ //request migh have been done
+ } else {
+ //did not request yet, do request
+
+ Error err = client->request(HTTPClient::METHOD_GET,request_string,headers);
+ if (err!=OK) {
+ call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray());
+ return true;
+ }
+
+ request_sent=true;
+ return false;
+ }
+ } break; //connected: { } break requests only accepted here
+ case HTTPClient::STATUS_REQUESTING: {
+ //must wait, it's requesting
+ client->poll();
+ return false;
+
+ } break; // request in progress
+ case HTTPClient::STATUS_BODY: {
+
+ if (!got_response) {
+
+
+ bool ret_value;
+
+ if (_handle_response(&ret_value))
+ return ret_value;
+
+ if (!client->is_response_chunked() && client->get_response_body_length()==0) {
+
+ call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray());
+ return true;
+ }
+
+
+ if (client->is_response_chunked()) {
+ body_len=-1; //no body len because chunked, change your webserver configuration if you want body len
+ } else {
+ body_len=client->get_response_body_length();
+
+ if (body_size_limit>=0 && body_len>body_size_limit) {
+ call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray());
+ return true;
+ }
+ }
+
+ if (download_to_file!=String()) {
+ file=FileAccess::open(download_to_file,FileAccess::WRITE);
+ if (!file) {
+
+ call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_CANT_OPEN,response_code,response_headers,ByteArray());
+ }
+ }
+ }
+
+
+ //print_line("BODY: "+itos(body.size()));
+ client->poll();
+
+ ByteArray chunk = client->read_response_body_chunk();
+ downloaded+=chunk.size();
+
+ if (file) {
+ ByteArray::Read r=chunk.read();
+ file->store_buffer(r.ptr(),chunk.size());
+ if (file->get_error()!=OK) {
+ call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_WRITE_ERROR,response_code,response_headers,ByteArray());
+ return true;
+ }
+ } else {
+ body.append_array(chunk);
+ }
+
+ if (body_size_limit>=0 && downloaded>body_size_limit) {
+ call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray());
+ return true;
+ }
+
+ if (body_len>=0) {
+
+ if (downloaded==body_len) {
+ call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body);
+ return true;
+ }
+ /*if (body.size()>=body_len) {
+ call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray());
+ return true;
+ }*/
+ }
+
+ return false;
+
+ } break; // request resulted in body: { } break which must be read
+ case HTTPClient::STATUS_CONNECTION_ERROR: {
+ call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray());
+ return true;
+ } break;
+ case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: {
+ call_deferred("emit_signal","request_completed",RESULT_SSL_HANDSHAKE_ERROR,0,StringArray(),ByteArray());
+ return true;
+ } break;
+
+ }
+
+ ERR_FAIL_V(false);
+}
+
+void HTTPRequest::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_PROCESS) {
+
+ bool done = _update_connection();
+ if (done) {
+
+ set_process(false);
+ cancel_request();
+ }
+ }
+}
+
+void HTTPRequest::set_use_threads(bool p_use) {
+
+ ERR_FAIL_COND( status!=HTTPClient::STATUS_DISCONNECTED );
+ use_threads=p_use;
+}
+
+bool HTTPRequest::is_using_threads() const {
+
+ return use_threads;
+}
+
+void HTTPRequest::set_body_size_limit(int p_bytes) {
+
+ ERR_FAIL_COND( status!=HTTPClient::STATUS_DISCONNECTED );
+
+ body_size_limit=p_bytes;
+}
+
+int HTTPRequest::get_body_size_limit() const {
+
+ return body_size_limit;
+}
+
+
+void HTTPRequest::set_download_file(const String& p_file) {
+
+ ERR_FAIL_COND( status!=HTTPClient::STATUS_DISCONNECTED );
+
+ download_to_file=p_file;
+}
+
+String HTTPRequest::get_download_file() const {
+
+ return download_to_file;
+}
+HTTPClient::Status HTTPRequest::get_http_client_status() const {
+ return client->get_status();
+}
+
+void HTTPRequest::set_max_redirects(int p_max) {
+
+ max_redirects=p_max;
+}
+
+int HTTPRequest::get_max_redirects() const{
+
+ return max_redirects;
+}
+
+int HTTPRequest::get_downloaded_bytes() const {
+
+ return downloaded;
+}
+int HTTPRequest::get_body_size() const{
+ return body_len;
+}
+
+
+void HTTPRequest::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("request","url","custom_headers","ssl_validate_domain"),&HTTPRequest::request,DEFVAL(StringArray()),DEFVAL(true));
+ ObjectTypeDB::bind_method(_MD("cancel_request"),&HTTPRequest::cancel_request);
+
+ ObjectTypeDB::bind_method(_MD("get_http_client_status"),&HTTPRequest::get_http_client_status);
+
+ ObjectTypeDB::bind_method(_MD("set_use_threads","enable"),&HTTPRequest::set_use_threads);
+ ObjectTypeDB::bind_method(_MD("is_using_threads"),&HTTPRequest::is_using_threads);
+
+ ObjectTypeDB::bind_method(_MD("set_body_size_limit","bytes"),&HTTPRequest::set_body_size_limit);
+ ObjectTypeDB::bind_method(_MD("get_body_size_limit"),&HTTPRequest::get_body_size_limit);
+
+ ObjectTypeDB::bind_method(_MD("set_max_redirects","amount"),&HTTPRequest::set_max_redirects);
+ ObjectTypeDB::bind_method(_MD("get_max_redirects"),&HTTPRequest::get_max_redirects);
+
+ ObjectTypeDB::bind_method(_MD("set_download_file","path"),&HTTPRequest::set_download_file);
+ ObjectTypeDB::bind_method(_MD("get_download_file"),&HTTPRequest::get_download_file);
+
+ ObjectTypeDB::bind_method(_MD("get_downloaded_bytes"),&HTTPRequest::get_downloaded_bytes);
+ ObjectTypeDB::bind_method(_MD("get_body_size"),&HTTPRequest::get_body_size);
+
+ ObjectTypeDB::bind_method(_MD("_redirect_request"),&HTTPRequest::_redirect_request);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"use_threads"),_SCS("set_use_threads"),_SCS("is_using_threads"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"body_size_limit",PROPERTY_HINT_RANGE,"-1,2000000000"),_SCS("set_body_size_limit"),_SCS("get_body_size_limit"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"max_redirects",PROPERTY_HINT_RANGE,"-1,1024"),_SCS("set_max_redirects"),_SCS("get_max_redirects"));
+
+ ADD_SIGNAL(MethodInfo("request_completed",PropertyInfo(Variant::INT,"result"),PropertyInfo(Variant::INT,"response_code"),PropertyInfo(Variant::STRING_ARRAY,"headers"),PropertyInfo(Variant::RAW_ARRAY,"body")));
+
+ BIND_CONSTANT( RESULT_SUCCESS );
+ //BIND_CONSTANT( RESULT_NO_BODY );
+ BIND_CONSTANT( RESULT_CHUNKED_BODY_SIZE_MISMATCH );
+ BIND_CONSTANT( RESULT_CANT_CONNECT );
+ BIND_CONSTANT( RESULT_CANT_RESOLVE );
+ BIND_CONSTANT( RESULT_CONNECTION_ERROR );
+ BIND_CONSTANT( RESULT_SSL_HANDSHAKE_ERROR );
+ BIND_CONSTANT( RESULT_NO_RESPONSE );
+ BIND_CONSTANT( RESULT_BODY_SIZE_LIMIT_EXCEEDED );
+ BIND_CONSTANT( RESULT_REQUEST_FAILED );
+ BIND_CONSTANT( RESULT_REDIRECT_LIMIT_REACHED );
+ BIND_CONSTANT( RESULT_DOWNLOAD_FILE_WRITE_ERROR );
+
+}
+
+HTTPRequest::HTTPRequest()
+{
+
+
+ port=80;
+ redirections=0;
+ max_redirects=8;
+ body_len=-1;
+ got_response=false;
+ validate_ssl=false;
+ use_ssl=false;
+ response_code=0;
+ request_sent=false;
+ client.instance();
+ use_threads=false;
+ body_size_limit=-1;
+ file=NULL;
+ status=HTTPClient::STATUS_DISCONNECTED;
+
+}
+
+HTTPRequest::~HTTPRequest() {
+ if (file)
+ memdelete(file);
+}
diff --git a/scene/main/http_request.h b/scene/main/http_request.h
new file mode 100644
index 0000000000..7659d9e6d6
--- /dev/null
+++ b/scene/main/http_request.h
@@ -0,0 +1,103 @@
+#ifndef HTTPREQUEST_H
+#define HTTPREQUEST_H
+
+#include "node.h"
+#include "io/http_client.h"
+#include "os/file_access.h"
+
+class HTTPRequest : public Node {
+
+ OBJ_TYPE(HTTPRequest,Node);
+public:
+
+ enum Result {
+ RESULT_SUCCESS,
+ //RESULT_NO_BODY,
+ RESULT_CHUNKED_BODY_SIZE_MISMATCH,
+ RESULT_CANT_CONNECT,
+ RESULT_CANT_RESOLVE,
+ RESULT_CONNECTION_ERROR,
+ RESULT_SSL_HANDSHAKE_ERROR,
+ RESULT_NO_RESPONSE,
+ RESULT_BODY_SIZE_LIMIT_EXCEEDED,
+ RESULT_REQUEST_FAILED,
+ RESULT_DOWNLOAD_FILE_CANT_OPEN,
+ RESULT_DOWNLOAD_FILE_WRITE_ERROR,
+ RESULT_REDIRECT_LIMIT_REACHED
+
+ };
+
+private:
+
+ bool requesting;
+
+ String request_string;
+ String url;
+ int port;
+ Vector<String> headers;
+ bool validate_ssl;
+ bool use_ssl;
+
+ bool request_sent;
+ Ref<HTTPClient> client;
+ ByteArray body;
+ bool use_threads;
+
+ bool got_response;
+ int response_code;
+ DVector<String> response_headers;
+
+ String download_to_file;
+
+ FileAccess *file;
+
+ int body_len;
+ int downloaded;
+ int body_size_limit;
+
+ int redirections;
+
+ HTTPClient::Status status;
+
+ bool _update_connection();
+
+ int max_redirects;
+
+ void _redirect_request(const String& p_new_url);
+
+ bool _handle_response(bool *ret_value);
+
+ Error _parse_url(const String& p_url);
+ Error _request();
+
+
+protected:
+
+ void _notification(int p_what);
+ static void _bind_methods();
+public:
+
+ Error request(const String& p_url,const Vector<String>& p_custom_headers=Vector<String>(),bool p_ssl_validate_domain=true); //connects to a full url and perform request
+ void cancel_request();
+ HTTPClient::Status get_http_client_status() const;
+
+ void set_use_threads(bool p_use);
+ bool is_using_threads() const;
+
+ void set_download_file(const String& p_file);
+ String get_download_file() const;
+
+ void set_body_size_limit(int p_bytes);
+ int get_body_size_limit() const;
+
+ void set_max_redirects(int p_max);
+ int get_max_redirects() const;
+
+ int get_downloaded_bytes() const;
+ int get_body_size() const;
+
+ HTTPRequest();
+ ~HTTPRequest();
+};
+
+#endif // HTTPREQUEST_H
diff --git a/scene/main/misc.h b/scene/main/misc.h
index 1c5bc7208e..d5db8c3247 100644
--- a/scene/main/misc.h
+++ b/scene/main/misc.h
@@ -37,7 +37,7 @@ class Misc : public Node {
OBJ_TYPE( Misc, Node );
public:
- Misc();
+ Misc();
~Misc();
};
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 450578a241..b90edb38b2 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -41,7 +41,7 @@ VARIANT_ENUM_CAST(Node::PauseMode);
void Node::_notification(int p_notification) {
-
+
switch(p_notification) {
case NOTIFICATION_PROCESS: {
@@ -114,21 +114,21 @@ void Node::_notification(int p_notification) {
case NOTIFICATION_PREDELETE: {
set_owner(NULL);
-
+
while ( data.owned.size() ) {
-
- data.owned.front()->get()->set_owner(NULL);
+
+ data.owned.front()->get()->set_owner(NULL);
}
if (data.parent) {
-
+
data.parent->remove_child(this);
}
// kill children as cleanly as possible
while( data.children.size() ) {
-
- Node *child = data.children[0];
+
+ Node *child = data.children[0];
remove_child(child);
memdelete( child );
}
@@ -161,7 +161,7 @@ void Node::_propagate_enter_tree() {
data.depth=1;
}
-
+
data.viewport = cast_to<Viewport>();
if (!data.viewport)
data.viewport = data.parent->data.viewport;
@@ -191,10 +191,10 @@ void Node::_propagate_enter_tree() {
//block while adding children
for (int i=0;i<data.children.size();i++) {
-
+
if (!data.children[i]->is_inside_tree()) // could have been added in enter_tree
data.children[i]->_propagate_enter_tree();
- }
+ }
data.blocked--;
@@ -279,15 +279,15 @@ void Node::_propagate_exit_tree() {
-void Node::move_child(Node *p_child,int p_pos) {
-
+void Node::move_child(Node *p_child,int p_pos) {
+
ERR_FAIL_NULL(p_child);
ERR_EXPLAIN("Invalid new child position: "+itos(p_pos));
ERR_FAIL_INDEX( p_pos, data.children.size()+1 );
ERR_EXPLAIN("child is not a child of this node.");
ERR_FAIL_COND(p_child->data.parent!=this);
ERR_FAIL_COND(data.blocked>0);
-
+
data.children.remove( p_child->data.pos );
data.children.insert( p_pos, p_child );
@@ -298,7 +298,7 @@ void Node::move_child(Node *p_child,int p_pos) {
data.blocked++;
//new pos first
for (int i=0;i<data.children.size();i++) {
-
+
data.children[i]->data.pos=i;
}
// notification second
@@ -313,17 +313,17 @@ void Node::move_child(Node *p_child,int p_pos) {
}
void Node::raise() {
-
+
if (!data.parent)
return;
-
+
data.parent->move_child(this,data.parent->data.children.size()-1);
}
void Node::add_child_notify(Node *p_child) {
-
- // to be used when not wanted
+
+ // to be used when not wanted
}
/*
@@ -340,26 +340,26 @@ void Node::remove_and_delete_child(Node *p_child) {
void Node::remove_child_notify(Node *p_child) {
- // to be used when not wanted
+ // to be used when not wanted
}
void Node::move_child_notify(Node *p_child) {
- // to be used when not wanted
+ // to be used when not wanted
}
void Node::set_fixed_process(bool p_process) {
-
+
if (data.fixed_process==p_process)
return;
data.fixed_process=p_process;
-
+
if (data.fixed_process)
add_to_group("fixed_process",false);
else
remove_from_group("fixed_process");
-
+
data.fixed_process=p_process;
_change_notify("fixed_process");
}
@@ -437,7 +437,7 @@ bool Node::can_process() const {
float Node::get_fixed_process_delta_time() const {
-
+
if (data.tree)
return data.tree->get_fixed_process_time();
else
@@ -469,7 +469,7 @@ float Node::get_process_delta_time() const {
}
bool Node::is_fixed_processing() const {
-
+
return data.fixed_process;
}
@@ -541,7 +541,7 @@ bool Node::is_processing_unhandled_key_input() const {
StringName Node::get_name() const {
-
+
return data.name;
}
@@ -552,14 +552,14 @@ void Node::_set_name_nocheck(const StringName& p_name) {
}
void Node::set_name(const String& p_name) {
-
+
String name=p_name.replace(":","").replace("/","").replace("@","");
ERR_FAIL_COND(name=="");
data.name=name;
-
+
if (data.parent) {
-
+
data.parent->_validate_child_name(this);
}
@@ -741,12 +741,12 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name) {
ERR_FAIL_COND( p_child->data.parent );
ERR_EXPLAIN("Can't add child while a notification is happening");
ERR_FAIL_COND( data.blocked > 0 );
-
+
/* Validate name */
_validate_child_name(p_child,p_legible_unique_name);
_add_child_nocheck(p_child,p_child->data.name);
-
+
}
@@ -791,36 +791,36 @@ void Node::remove_child(Node *p_child) {
ERR_FAIL_NULL(p_child);
ERR_FAIL_COND( data.blocked > 0 );
-
+
int idx=-1;
for (int i=0;i<data.children.size();i++) {
-
+
if (data.children[i]==p_child) {
-
+
idx=i;
break;
}
}
-
+
ERR_FAIL_COND( idx==-1 );
//ERR_FAIL_COND( p_child->data.blocked > 0 );
-
+
//if (data.scene) { does not matter
-
+
p_child->_set_tree(NULL);
//}
-
- remove_child_notify(p_child);
+
+ remove_child_notify(p_child);
p_child->notification(NOTIFICATION_UNPARENTED);
-
+
data.children.remove(idx);
-
+
for (int i=idx;i<data.children.size();i++) {
-
+
data.children[i]->data.pos=i;
}
-
+
p_child->data.parent=NULL;
p_child->data.pos=-1;
@@ -828,17 +828,17 @@ void Node::remove_child(Node *p_child) {
// validate owner
p_child->_propagate_validate_owner();
-
+
}
int Node::get_child_count() const {
-
- return data.children.size();
+
+ return data.children.size();
}
Node *Node::get_child(int p_index) const {
-
+
ERR_FAIL_INDEX_V( p_index, data.children.size(), NULL );
-
+
return data.children[p_index];
}
@@ -862,10 +862,10 @@ Node *Node::_get_node(const NodePath& p_path) const {
ERR_EXPLAIN("Can't use get_node() with absolute paths from outside the active scene tree.");
ERR_FAIL_V(NULL);
}
-
- Node *current=NULL;
+
+ Node *current=NULL;
Node *root=NULL;
-
+
if (!p_path.is_absolute()) {
current=const_cast<Node*>(this); //start from this
} else {
@@ -874,42 +874,42 @@ Node *Node::_get_node(const NodePath& p_path) const {
while (root->data.parent)
root=root->data.parent; //start from root
}
-
+
for(int i=0;i<p_path.get_name_count();i++) {
-
-
- StringName name = p_path.get_name(i);
+
+
+ StringName name = p_path.get_name(i);
Node *next = NULL;
-
+
if (name==SceneStringNames::get_singleton()->dot) { // .
-
+
next=current;
-
+
} else if (name==SceneStringNames::get_singleton()->doubledot) { // ..
-
+
if (current==NULL || !current->data.parent)
return NULL;
-
+
next=current->data.parent;
} else if (current==NULL) {
-
+
if (name==root->get_name())
next=root;
-
+
} else {
-
+
next=NULL;
-
+
for(int j=0;j<current->data.children.size();j++) {
-
+
Node *child = current->data.children[j];
if ( child->data.name == name ) {
-
+
next = child;
break;
- }
+ }
}
if (next == NULL) {
return NULL;
@@ -917,7 +917,7 @@ Node *Node::_get_node(const NodePath& p_path) const {
}
current=next;
}
-
+
return current;
}
@@ -969,12 +969,12 @@ bool Node::is_a_parent_of(const Node *p_node) const {
ERR_FAIL_NULL_V(p_node,false);
Node *p=p_node->data.parent;
while(p) {
-
+
if (p==this)
return true;
p=p->data.parent;
}
-
+
return false;
}
@@ -983,25 +983,25 @@ bool Node::is_greater_than(const Node *p_node) const {
ERR_FAIL_NULL_V(p_node,false);
ERR_FAIL_COND_V( !data.inside_tree, false );
ERR_FAIL_COND_V( !p_node->data.inside_tree, false );
-
+
ERR_FAIL_COND_V( data.depth<0, false);
ERR_FAIL_COND_V( p_node->data.depth<0, false);
#ifdef NO_ALLOCA
-
+
Vector<int> this_stack;
Vector<int> that_stack;
this_stack.resize(data.depth);
that_stack.resize(p_node->data.depth);
#else
-
+
int *this_stack=(int*)alloca(sizeof(int)*data.depth);
int *that_stack=(int*)alloca(sizeof(int)*p_node->data.depth);
-
+
#endif
-
+
const Node *n = this;
-
+
int idx=data.depth-1;
while(n) {
ERR_FAIL_INDEX_V(idx, data.depth,false);
@@ -1014,15 +1014,15 @@ bool Node::is_greater_than(const Node *p_node) const {
while(n) {
ERR_FAIL_INDEX_V(idx, p_node->data.depth,false);
that_stack[idx--]=n->data.pos;
-
+
n=n->data.parent;
}
ERR_FAIL_COND_V(idx!=-1,false);
idx=0;
-
+
bool res;
while(true) {
-
+
// using -2 since out-of-tree or nonroot nodes have -1
int this_idx = (idx >= data.depth)? -2 : this_stack[idx];
int that_idx = (idx >= p_node->data.depth)? -2 : that_stack[idx];
@@ -1039,7 +1039,7 @@ bool Node::is_greater_than(const Node *p_node) const {
}
idx++;
}
-
+
return res;
}
@@ -1063,39 +1063,39 @@ void Node::_set_owner_nocheck(Node* p_owner) {
}
void Node::set_owner(Node *p_owner) {
-
+
if (data.owner) {
-
+
data.owner->data.owned.erase( data.OW );
data.OW=NULL;
data.owner=NULL;
}
-
+
ERR_FAIL_COND(p_owner==this);
-
+
if (!p_owner)
return;
-
+
Node *check=this->get_parent();
bool owner_valid=false;
-
+
while(check) {
-
+
if (check==p_owner) {
owner_valid=true;
break;
}
-
+
check=check->data.parent;
}
-
+
ERR_FAIL_COND(!owner_valid);
_set_owner_nocheck(p_owner);
}
Node *Node::get_owner() const {
-
- return data.owner;
+
+ return data.owner;
}
NodePath Node::get_path_to(const Node *p_node) const {
@@ -1104,68 +1104,68 @@ NodePath Node::get_path_to(const Node *p_node) const {
if (this==p_node)
return NodePath(".");
-
+
Set<const Node*> visited;
-
+
const Node *n=this;
-
+
while(n) {
-
+
visited.insert(n);
n=n->data.parent;
}
const Node *common_parent=p_node;
-
+
while(common_parent) {
-
+
if (visited.has(common_parent))
break;
common_parent=common_parent->data.parent;
}
-
+
ERR_FAIL_COND_V(!common_parent,NodePath()); //nodes not in the same tree
-
+
visited.clear();
-
+
Vector<StringName> path;
-
+
n=p_node;
-
+
while(n!=common_parent) {
-
+
path.push_back( n->get_name() );
n=n->data.parent;
}
-
+
n=this;
- StringName up=String("..");
-
+ StringName up=String("..");
+
while(n!=common_parent) {
-
+
path.push_back( up );
n=n->data.parent;
}
-
+
path.invert();
-
- return NodePath(path,false);
+
+ return NodePath(path,false);
}
NodePath Node::get_path() const {
-
+
ERR_FAIL_COND_V(!is_inside_tree(),NodePath());
const Node *n = this;
-
+
Vector<StringName> path;
-
+
while(n) {
path.push_back(n->get_name());
n=n->data.parent;
- }
-
+ }
+
path.invert();
-
+
return NodePath( path, true );
}
@@ -1175,36 +1175,36 @@ bool Node::is_in_group(const StringName& p_identifier) const {
}
void Node::add_to_group(const StringName& p_identifier,bool p_persistent) {
-
+
ERR_FAIL_COND(!p_identifier.operator String().length());
-
+
if (data.grouped.has(p_identifier))
return;
-
+
GroupData gd;
-
+
if (data.tree)
data.tree->add_to_group(p_identifier,this);
- gd.persistent=p_persistent;
-
+ gd.persistent=p_persistent;
+
data.grouped[p_identifier]=gd;
}
void Node::remove_from_group(const StringName& p_identifier) {
-
+
ERR_FAIL_COND(!data.grouped.has(p_identifier) );
-
+
GroupData *g=data.grouped.getptr(p_identifier);
-
+
ERR_FAIL_COND(!g);
-
+
if (data.tree)
data.tree->remove_from_group(p_identifier,this);
- data.grouped.erase(p_identifier);
+ data.grouped.erase(p_identifier);
}
@@ -1223,15 +1223,15 @@ Array Node::_get_groups() const {
void Node::get_groups(List<GroupInfo> *p_groups) const {
const StringName *K=NULL;
-
+
while ((K=data.grouped.next(K))) {
-
+
GroupInfo gi;
gi.name=*K;
gi.persistent=data.grouped[*K].persistent;
p_groups->push_back(gi);
}
-
+
}
@@ -1249,13 +1249,13 @@ void Node::print_tree() {
void Node::_propagate_reverse_notification(int p_notification) {
-
- data.blocked++;
+
+ data.blocked++;
for (int i=data.children.size()-1;i>=0;i--) {
-
- data.children[i]->_propagate_reverse_notification(p_notification);
+
+ data.children[i]->_propagate_reverse_notification(p_notification);
}
-
+
notification(p_notification,true);
data.blocked--;
}
@@ -1281,75 +1281,75 @@ void Node::_propagate_deferred_notification(int p_notification, bool p_reverse)
}
void Node::propagate_notification(int p_notification) {
-
- data.blocked++;
+
+ data.blocked++;
notification(p_notification);
-
+
for (int i=0;i<data.children.size();i++) {
-
- data.children[i]->propagate_notification(p_notification);
+
+ data.children[i]->propagate_notification(p_notification);
}
- data.blocked--;
+ data.blocked--;
}
-void Node::_propagate_replace_owner(Node *p_owner,Node* p_by_owner) {
+void Node::_propagate_replace_owner(Node *p_owner,Node* p_by_owner) {
if (get_owner()==p_owner)
set_owner(p_by_owner);
-
+
data.blocked++;
- for (int i=0;i<data.children.size();i++)
+ for (int i=0;i<data.children.size();i++)
data.children[i]->_propagate_replace_owner(p_owner,p_by_owner);
- data.blocked--;
+ data.blocked--;
}
int Node::get_index() const {
-
+
return data.pos;
}
void Node::remove_and_skip() {
-
+
ERR_FAIL_COND(!data.parent);
-
+
Node *new_owner=get_owner();
-
+
List<Node*> children;
-
+
while(true) {
-
+
bool clear=true;
for (int i=0;i<data.children.size();i++) {
if (!data.children[i]->get_owner())
continue;
-
+
remove_child(data.children[i]);
data.children[i]->_propagate_replace_owner(this,NULL);
- children.push_back(data.children[i]);
+ children.push_back(data.children[i]);
clear=false;
break;
}
-
+
if (clear)
break;
}
-
+
while(!children.empty()) {
-
+
Node *c=children.front()->get();
data.parent->add_child(c);
- c->_propagate_replace_owner(NULL,new_owner);
+ c->_propagate_replace_owner(NULL,new_owner);
children.pop_front();
}
-
+
data.parent->remove_child(this);
}
void Node::set_filename(const String& p_filename) {
-
+
data.filename=p_filename;
}
String Node::get_filename() const {
-
+
return data.filename;
}
@@ -2117,7 +2117,7 @@ void Node::_bind_methods() {
Node::Node() {
-
+
data.pos=-1;
data.depth=-1;
data.blocked=0;
@@ -2141,12 +2141,12 @@ Node::Node() {
}
Node::~Node() {
-
+
data.grouped.clear();
data.owned.clear();
data.children.clear();
-
+
ERR_FAIL_COND(data.parent);
ERR_FAIL_COND(data.children.size());
diff --git a/scene/main/node.h b/scene/main/node.h
index 4d05dd381c..5c6147d644 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -43,7 +43,7 @@ class Node : public Object {
OBJ_TYPE( Node, Object );
OBJ_CATEGORY("Nodes");
-
+
public:
enum PauseMode {
@@ -59,16 +59,16 @@ public:
bool operator()(const Node* p_a, const Node* p_b) const { return p_b->is_greater_than(p_a); }
};
-private:
-
+private:
+
struct GroupData {
-
- bool persistent;
+
+ bool persistent;
GroupData() { persistent=false; }
};
-
+
struct Data {
-
+
String filename;
Ref<SceneState> instance_state;
Ref<SceneState> inherited_state;
@@ -90,11 +90,11 @@ private:
Viewport *viewport;
-
+
HashMap< StringName, GroupData,StringNameHasher> grouped;
List<Node*>::Element *OW; // owned element
List<Node*> owned;
-
+
PauseMode pause_mode;
Node *pause_owner;
// variables used to properly sort the node when processing, ignored otherwise
@@ -112,10 +112,10 @@ private:
} data;
-
- void _print_tree(const Node *p_node);
-
+
+ void _print_tree(const Node *p_node);
+
virtual bool _use_builtin_script() const { return true; }
Node *_get_node(const NodePath& p_path) const;
Node *_get_child_by_name(const StringName& p_name) const;
@@ -124,7 +124,7 @@ private:
void _validate_child_name(Node *p_name, bool p_force_human_readable=false);
- void _propagate_reverse_notification(int p_notification);
+ void _propagate_reverse_notification(int p_notification);
void _propagate_deferred_notification(int p_notification, bool p_reverse);
void _propagate_enter_tree();
void _propagate_ready();
@@ -147,15 +147,15 @@ protected:
void _block() { data.blocked++; }
void _unblock() { data.blocked--; }
- void _notification(int p_notification);
-
+ void _notification(int p_notification);
+
virtual void add_child_notify(Node *p_child);
virtual void remove_child_notify(Node *p_child);
virtual void move_child_notify(Node *p_child);
//void remove_and_delete_child(Node *p_child);
-
- void _propagate_replace_owner(Node *p_owner,Node* p_by_owner);
-
+
+ void _propagate_replace_owner(Node *p_owner,Node* p_by_owner);
+
static void _bind_methods();
friend class SceneState;
@@ -181,15 +181,15 @@ public:
NOTIFICATION_UNPARENTED=19,
NOTIFICATION_INSTANCED=20,
};
-
- /* NODE/TREE */
-
+
+ /* NODE/TREE */
+
StringName get_name() const;
void set_name(const String& p_name);
-
+
void add_child(Node *p_child,bool p_legible_unique_name=false);
void remove_child(Node *p_child);
-
+
int get_child_count() const;
Node *get_child(int p_index) const;
bool has_node(const NodePath& p_path) const;
@@ -197,43 +197,43 @@ public:
Node* find_node(const String& p_mask,bool p_recursive=true,bool p_owned=true) const;
bool has_node_and_resource(const NodePath& p_path) const;
Node *get_node_and_resource(const NodePath& p_path,RES& r_res) const;
-
+
Node *get_parent() const;
_FORCE_INLINE_ SceneTree *get_tree() const { ERR_FAIL_COND_V( !data.tree, NULL ); return data.tree; }
_FORCE_INLINE_ bool is_inside_tree() const { return data.inside_tree; }
-
+
bool is_a_parent_of(const Node *p_node) const;
bool is_greater_than(const Node *p_node) const;
-
+
NodePath get_path() const;
NodePath get_path_to(const Node *p_node) const;
-
+
void add_to_group(const StringName& p_identifier,bool p_persistent=false);
void remove_from_group(const StringName& p_identifier);
bool is_in_group(const StringName& p_identifier) const;
-
+
struct GroupInfo {
-
+
StringName name;
bool persistent;
};
-
+
void get_groups(List<GroupInfo> *p_groups) const;
-
+
void move_child(Node *p_child,int p_pos);
void raise();
-
+
void set_owner(Node *p_owner);
Node *get_owner() const;
void get_owned_by(Node *p_by,List<Node*> *p_owned);
-
+
void remove_and_skip();
int get_index() const;
-
+
void print_tree();
-
+
void set_filename(const String& p_filename);
String get_filename() const;
@@ -242,9 +242,9 @@ public:
/* NOTIFICATIONS */
-
+
void propagate_notification(int p_notification);
-
+
/* PROCESSING */
void set_fixed_process(bool p_process);
float get_fixed_process_delta_time() const;
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index 8e2d6aa669..cc103b5115 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -211,7 +211,7 @@ void SceneTree::call_group(uint32_t p_call_flags,const StringName& p_group,const
else
nodes[i]->call(p_function,VARIANT_ARG_PASS);
} else
- MessageQueue::get_singleton()->push_call(nodes[i],p_function,VARIANT_ARG_PASS);
+ MessageQueue::get_singleton()->push_call(nodes[i],p_function,VARIANT_ARG_PASS);
}
}
@@ -433,7 +433,7 @@ void SceneTree::input_event( const InputEvent& p_event ) {
ScriptDebugger::get_singleton()->request_quit();
}
- _flush_ugc();
+ _flush_ugc();
root_lock--;
MessageQueue::get_singleton()->flush(); //small little hack
diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h
index c6fc124345..b6a015c9ed 100644
--- a/scene/main/scene_main_loop.h
+++ b/scene/main/scene_main_loop.h
@@ -76,7 +76,7 @@ private:
struct Group {
Vector<Node*> nodes;
- uint64_t last_tree_version;
+ uint64_t last_tree_version;
Group() { last_tree_version=0; };
};
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 2c23b62b12..73458e03c0 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -42,6 +42,7 @@ void Timer::_notification(int p_what) {
break;
#endif
start();
+ autostart=false;
}
} break;
case NOTIFICATION_PROCESS: {
@@ -110,7 +111,7 @@ bool Timer::has_autostart() const {
}
void Timer::start() {
- time_left=wait_time;
+ time_left=wait_time;
_set_process(true);
}
@@ -153,7 +154,7 @@ Timer::TimerProcessMode Timer::get_timer_process_mode() const{
}
-void Timer::_set_process(bool p_process, bool p_force)
+void Timer::_set_process(bool p_process, bool p_force)
{
switch (timer_process_mode) {
case TIMER_PROCESS_FIXED: set_fixed_process(p_process); break;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index a1bfbda1fc..5017ae61ff 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -318,10 +318,10 @@ void Viewport::_test_new_mouseover(ObjectID new_collider) {
}
void Viewport::_notification(int p_what) {
-
+
switch( p_what ) {
-
+
case NOTIFICATION_ENTER_TREE: {
if (get_parent()) {
@@ -533,7 +533,7 @@ void Viewport::_notification(int p_what) {
Vector2 point = get_canvas_transform().affine_inverse().xform(pos);
Physics2DDirectSpaceState::ShapeResult res[64];
- int rc = ss2d->intersect_point(point,res,64,Set<RID>(),0xFFFFFFFF,0xFFFFFFFF);
+ int rc = ss2d->intersect_point(point,res,64,Set<RID>(),0xFFFFFFFF,0xFFFFFFFF,true);
for(int i=0;i<rc;i++) {
if (res[i].collider_id && res[i].collider) {
@@ -696,8 +696,8 @@ void Viewport::_notification(int p_what) {
}
RID Viewport::get_viewport() const {
-
- return viewport;
+
+ return viewport;
}
void Viewport::set_rect(const Rect2& p_rect) {
@@ -715,12 +715,12 @@ Rect2 Viewport::get_visible_rect() const {
Rect2 r;
-
+
if (rect.pos==Vector2() && rect.size==Size2()) {
-
+
r=Rect2( Point2(), Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ) );
} else {
-
+
r=Rect2( rect.pos , rect.size );
}
@@ -733,7 +733,7 @@ Rect2 Viewport::get_visible_rect() const {
}
Rect2 Viewport::get_rect() const {
-
+
return rect;
}
@@ -855,7 +855,7 @@ void Viewport::_camera_transform_changed_notify() {
#endif
}
-void Viewport::_set_camera(Camera* p_camera) {
+void Viewport::_camera_set(Camera* p_camera) {
#ifndef _3D_DISABLED
@@ -880,6 +880,37 @@ void Viewport::_set_camera(Camera* p_camera) {
#endif
}
+bool Viewport::_camera_add(Camera* p_camera) {
+
+ cameras.insert(p_camera);
+ return cameras.size()==1;
+}
+
+void Viewport::_camera_remove(Camera* p_camera) {
+
+ cameras.erase(p_camera);
+ if (camera==p_camera) {
+ camera=NULL;
+ }
+}
+
+#ifndef _3D_DISABLED
+void Viewport::_camera_make_next_current(Camera* p_exclude) {
+
+ for(Set<Camera*>::Element *E=cameras.front();E;E=E->next()) {
+
+ if (p_exclude==E->get())
+ continue;
+ if (!E->get()->is_inside_tree())
+ continue;
+ if (camera!=NULL)
+ return;
+
+ E->get()->make_current();
+
+ }
+}
+#endif
void Viewport::set_transparent_background(bool p_enable) {
@@ -1305,7 +1336,7 @@ void Viewport::_vp_input(const InputEvent& p_ev) {
//they are converted to viewport coordinates
- InputEvent ev = p_ev;
+ InputEvent ev = p_ev;
_make_input_local(ev);
input(ev);
@@ -1486,7 +1517,8 @@ Control* Viewport::_gui_find_control(const Point2& p_global) {
CanvasItem *pci = sw->get_parent_item();
if (pci)
xform=pci->get_global_transform_with_canvas();
-
+ else
+ xform=sw->get_canvas_transform();
Control *ret = _gui_find_control_at_pos(sw,p_global,xform,gui.focus_inv_xform);
if (ret)
@@ -1505,6 +1537,8 @@ Control* Viewport::_gui_find_control(const Point2& p_global) {
CanvasItem *pci = sw->get_parent_item();
if (pci)
xform=pci->get_global_transform_with_canvas();
+ else
+ xform=sw->get_canvas_transform();
Control *ret = _gui_find_control_at_pos(sw,p_global,xform,gui.focus_inv_xform);
@@ -1624,7 +1658,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
- Matrix32 parent_xform;
+ //Matrix32 parent_xform;
//if (data.parent_canvas_item)
// parent_xform=data.parent_canvas_item->get_global_transform();
@@ -1770,6 +1804,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
+
if (gui.drag_data.get_type()==Variant::NIL && over && !gui.modal_stack.empty()) {
Control *top = gui.modal_stack.back()->get();
@@ -1803,7 +1838,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
- Matrix32 localizer = over->get_canvas_transform().affine_inverse();
+ Matrix32 localizer = over->get_global_transform_with_canvas().affine_inverse();
Size2 pos = localizer.xform(mpos);
Vector2 speed = localizer.basis_xform(Point2(p_event.mouse_motion.speed_x,p_event.mouse_motion.speed_y));
Vector2 rel = localizer.basis_xform(Point2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y));
@@ -1838,7 +1873,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
- pos = gui.focus_inv_xform.xform(pos);
+ //pos = gui.focus_inv_xform.xform(pos);
p_event.mouse_motion.x = pos.x;
@@ -2177,7 +2212,7 @@ void Viewport::_gui_grab_click_focus(Control *p_control) {
//send unclic
- Point2 click =gui.mouse_focus->get_global_transform().affine_inverse().xform(gui.last_mouse_pos);
+ Point2 click =gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
mb.x=click.x;
mb.y=click.y;
mb.button_index=gui.mouse_focus_button;
@@ -2186,8 +2221,8 @@ void Viewport::_gui_grab_click_focus(Control *p_control) {
gui.mouse_focus=p_control;
- gui.focus_inv_xform=gui.mouse_focus->get_global_transform().affine_inverse();
- click =gui.mouse_focus->get_global_transform().affine_inverse().xform(gui.last_mouse_pos);
+ gui.focus_inv_xform=gui.mouse_focus->get_global_transform_with_canvas().affine_inverse();
+ click =gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
mb.x=click.x;
mb.y=click.y;
mb.button_index=gui.mouse_focus_button;
@@ -2206,7 +2241,7 @@ void Viewport::input(const InputEvent& p_event) {
ERR_FAIL_COND(!is_inside_tree());
- get_tree()->_call_input_pause(input_group,"_input",p_event);
+ get_tree()->_call_input_pause(input_group,"_input",p_event);
_gui_input_event(p_event);
//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check
}
@@ -2375,10 +2410,10 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip);
ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip);
-
+
ObjectTypeDB::bind_method(_MD("set_render_target_clear_on_new_frame","enable"), &Viewport::set_render_target_clear_on_new_frame);
ObjectTypeDB::bind_method(_MD("get_render_target_clear_on_new_frame"), &Viewport::get_render_target_clear_on_new_frame);
-
+
ObjectTypeDB::bind_method(_MD("render_target_clear"), &Viewport::render_target_clear);
ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index cff729612e..afabd499a9 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -264,9 +264,13 @@ friend class Control;
friend class Camera;
void _camera_transform_changed_notify();
- void _set_camera(Camera* p_camera);
+ void _camera_set(Camera* p_camera);
+ bool _camera_add(Camera* p_camera); //true if first
+ void _camera_remove(Camera* p_camera);
+ void _camera_make_next_current(Camera* p_exclude);
-protected:
+
+protected:
void _notification(int p_what);
static void _bind_methods();
public:
@@ -280,7 +284,7 @@ public:
void set_as_audio_listener_2d(bool p_enable);
bool is_audio_listener_2d() const;
- void set_rect(const Rect2& p_rect);
+ void set_rect(const Rect2& p_rect);
Rect2 get_rect() const;
Rect2 get_visible_rect() const;
RID get_viewport() const;
@@ -358,7 +362,7 @@ public:
bool gui_has_modal_stack() const;
- Viewport();
+ Viewport();
~Viewport();
};
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 3c1b5268fc..9930aa07f6 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -38,9 +38,11 @@
#include "scene/main/canvas_layer.h"
#include "scene/main/instance_placeholder.h"
#include "scene/main/viewport.h"
+#include "scene/main/http_request.h"
#include "scene/gui/control.h"
#include "scene/gui/texture_progress.h"
#include "scene/gui/button.h"
+#include "scene/gui/link_button.h"
#include "scene/gui/button_array.h"
#include "scene/gui/button_group.h"
#include "scene/gui/label.h"
@@ -273,6 +275,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<Viewport>();
ObjectTypeDB::register_virtual_type<RenderTargetTexture>();
+ ObjectTypeDB::register_type<HTTPRequest>();
ObjectTypeDB::register_type<Timer>();
ObjectTypeDB::register_type<CanvasLayer>();
ObjectTypeDB::register_type<CanvasModulate>();
@@ -297,9 +300,10 @@ void register_scene_types() {
ObjectTypeDB::register_type<Popup>();
ObjectTypeDB::register_type<PopupPanel>();
ObjectTypeDB::register_type<MenuButton>();
- ObjectTypeDB::register_type<CheckBox>();
+ ObjectTypeDB::register_type<CheckBox>();
ObjectTypeDB::register_type<CheckButton>();
ObjectTypeDB::register_type<ToolButton>();
+ ObjectTypeDB::register_type<LinkButton>();
ObjectTypeDB::register_type<Panel>();
ObjectTypeDB::register_type<Range>();
@@ -428,7 +432,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<ConeTwistJoint>();
ObjectTypeDB::register_type<Generic6DOFJoint>();
- //scenariofx
+ //scenariofx
OS::get_singleton()->yield(); //may take time to init
@@ -625,9 +629,9 @@ void register_scene_types() {
}
void unregister_scene_types() {
-
+
clear_default_theme();
-
+
memdelete( resource_loader_image );
memdelete( resource_loader_wav );
#ifdef TOOLS_ENABLED
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index e8bd6c14ad..f7d5ddc744 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -41,33 +41,33 @@ bool Animation::_set(const StringName& p_name, const Variant& p_value) {
else if (name=="step")
set_step(p_value);
else if (name.begins_with("tracks/")) {
-
+
int track=name.get_slicec('/',1).to_int();
String what=name.get_slicec('/',2);
if (tracks.size()==track && what=="type") {
-
+
String type=p_value;
-
+
if (type=="transform") {
-
+
add_track(TYPE_TRANSFORM);
} else if (type=="value") {
-
+
add_track(TYPE_VALUE);
} else if (type=="method") {
-
+
add_track(TYPE_METHOD);
} else {
-
+
return false;
}
-
+
return true;
}
-
+
ERR_FAIL_INDEX_V( track, tracks.size(),false );
-
+
if (what=="path")
track_set_path(track,p_value);
else if (what=="interp")
@@ -261,10 +261,10 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
String what=name.get_slicec('/',2);
ERR_FAIL_INDEX_V( track, tracks.size(), false );
if (what=="type") {
-
-
+
+
switch (track_get_type(track)) {
-
+
case TYPE_TRANSFORM: r_ret= "transform"; break;
case TYPE_VALUE: r_ret= "value";break;
case TYPE_METHOD: r_ret= "method";break;
@@ -281,7 +281,7 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
if (track_get_type(track)==TYPE_TRANSFORM) {
DVector<real_t> keys;
- int kk=track_get_key_count(track);
+ int kk=track_get_key_count(track);
keys.resize(kk*12);
DVector<real_t>::Write w = keys.write();
@@ -406,7 +406,7 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
return false;
} else
return false;
-
+
return true;
}
@@ -415,11 +415,11 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
void Animation::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"));
- p_list->push_back( PropertyInfo( Variant::BOOL, "loop" ));
+ p_list->push_back( PropertyInfo( Variant::BOOL, "loop" ));
p_list->push_back( PropertyInfo( Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001" ));
for (int i=0;i<tracks.size();i++) {
-
+
p_list->push_back( PropertyInfo( Variant::STRING, "tracks/"+itos(i)+"/type", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo( Variant::NODE_PATH, "tracks/"+itos(i)+"/path", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo( Variant::INT, "tracks/"+itos(i)+"/interp", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
@@ -433,24 +433,24 @@ int Animation::add_track(TrackType p_type,int p_at_pos) {
p_at_pos=tracks.size();
switch( p_type ) {
-
+
case TYPE_TRANSFORM: {
-
+
TransformTrack *tt = memnew( TransformTrack );
tracks.insert( p_at_pos,tt );
} break;
case TYPE_VALUE: {
-
+
tracks.insert( p_at_pos,memnew( ValueTrack ) );
-
+
} break;
case TYPE_METHOD: {
-
+
tracks.insert( p_at_pos,memnew( MethodTrack ) );
-
+
} break;
default: {
-
+
ERR_PRINT("Unknown track type");
}
}
@@ -462,29 +462,29 @@ void Animation::remove_track(int p_track) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t=tracks[p_track];
-
+
switch(t->type) {
-
+
case TYPE_TRANSFORM: {
-
+
TransformTrack * tt = static_cast<TransformTrack*>(t);
_clear(tt->transforms);
-
+
} break;
case TYPE_VALUE: {
-
- ValueTrack * vt = static_cast<ValueTrack*>(t);
+
+ ValueTrack * vt = static_cast<ValueTrack*>(t);
_clear(vt->values);
-
+
} break;
case TYPE_METHOD: {
-
+
MethodTrack * mt = static_cast<MethodTrack*>(t);
_clear(mt->methods);
-
- } break;
- }
-
+
+ } break;
+ }
+
memdelete( t );
tracks.remove(p_track);
emit_changed();
@@ -548,30 +548,30 @@ template<class T>
int Animation::_insert_pos(float p_time, T& p_keys) {
// simple, linear time inset that should be fast enough in reality.
-
+
int idx=p_keys.size();
-
+
while(true) {
-
-
+
+
if (idx==0 || p_keys[idx-1].time < p_time) {
//condition for insertion.
p_keys.insert(idx,T());
return idx;
} else if (p_keys[idx-1].time == p_time) {
-
+
// condition for replacing.
return idx-1;
- }
-
+ }
+
idx--;
}
-
+
}
*/
template<class T, class V>
int Animation::_insert(float p_time, T& p_keys, const V& p_value) {
-
+
int idx=p_keys.size();
while(true) {
@@ -597,7 +597,7 @@ int Animation::_insert(float p_time, T& p_keys, const V& p_value) {
template<class T>
void Animation::_clear(T& p_keys) {
-
+
p_keys.clear();
}
@@ -727,11 +727,11 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant& p_val
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t=tracks[p_track];
-
+
switch(t->type) {
-
+
case TYPE_TRANSFORM: {
-
+
Dictionary d = p_value;
Vector3 loc;
if (d.has("loc"))
@@ -750,36 +750,36 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant& p_val
} break;
case TYPE_VALUE: {
-
+
ValueTrack * vt = static_cast<ValueTrack*>(t);
-
+
TKey<Variant> k;
k.time=p_time;
k.transition=p_transition;
k.value=p_value;
_insert( p_time, vt->values, k );
-
+
} break;
case TYPE_METHOD: {
-
+
MethodTrack * mt = static_cast<MethodTrack*>(t);
-
+
ERR_FAIL_COND( p_value.get_type() != Variant::DICTIONARY );
-
+
Dictionary d=p_value;
ERR_FAIL_COND(!d.has("method") || d["method"].get_type()!=Variant::STRING);
ERR_FAIL_COND(!d.has("args") || !d["args"].is_array());
MethodKey k;
-
+
k.time=p_time;
k.transition=p_transition;
k.method=d["method"];
k.params=d["args"];
_insert( p_time, mt->methods, k );
-
- } break;
+
+ } break;
}
@@ -790,27 +790,27 @@ int Animation::track_get_key_count(int p_track) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(),-1);
Track *t=tracks[p_track];
-
+
switch(t->type) {
-
+
case TYPE_TRANSFORM: {
-
+
TransformTrack * tt = static_cast<TransformTrack*>(t);
return tt->transforms.size();
} break;
case TYPE_VALUE: {
-
+
ValueTrack * vt = static_cast<ValueTrack*>(t);
return vt->values.size();
-
+
} break;
case TYPE_METHOD: {
-
+
MethodTrack * mt = static_cast<MethodTrack*>(t);
return mt->methods.size();
- } break;
+ } break;
}
-
+
ERR_FAIL_V(-1);
}
@@ -818,11 +818,11 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Variant());
Track *t=tracks[p_track];
-
+
switch(t->type) {
-
+
case TYPE_TRANSFORM: {
-
+
TransformTrack * tt = static_cast<TransformTrack*>(t);
ERR_FAIL_INDEX_V( p_key_idx, tt->transforms.size(), Variant() );
@@ -834,25 +834,25 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
return d;
} break;
case TYPE_VALUE: {
-
- ValueTrack * vt = static_cast<ValueTrack*>(t);
+
+ ValueTrack * vt = static_cast<ValueTrack*>(t);
ERR_FAIL_INDEX_V( p_key_idx, vt->values.size(), Variant() );
return vt->values[p_key_idx].value;
} break;
case TYPE_METHOD: {
-
+
MethodTrack * mt = static_cast<MethodTrack*>(t);
ERR_FAIL_INDEX_V( p_key_idx, mt->methods.size(), Variant() );
Dictionary d;
d["method"]=mt->methods[p_key_idx].method;
d["args"]=mt->methods[p_key_idx].params;
- return d;
-
- } break;
+ return d;
+
+ } break;
}
-
+
ERR_FAIL_V(Variant());
}
@@ -860,33 +860,33 @@ float Animation::track_get_key_time(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t=tracks[p_track];
-
+
switch(t->type) {
-
+
case TYPE_TRANSFORM: {
-
+
TransformTrack * tt = static_cast<TransformTrack*>(t);
ERR_FAIL_INDEX_V( p_key_idx, tt->transforms.size(), -1 );
return tt->transforms[p_key_idx].time;
} break;
case TYPE_VALUE: {
-
- ValueTrack * vt = static_cast<ValueTrack*>(t);
+
+ ValueTrack * vt = static_cast<ValueTrack*>(t);
ERR_FAIL_INDEX_V( p_key_idx, vt->values.size(), -1 );
return vt->values[p_key_idx].time;
-
+
} break;
case TYPE_METHOD: {
-
+
MethodTrack * mt = static_cast<MethodTrack*>(t);
ERR_FAIL_INDEX_V( p_key_idx, mt->methods.size(), -1 );
return mt->methods[p_key_idx].time;
-
-
- } break;
+
+
+ } break;
}
-
+
ERR_FAIL_V(-1);
}
@@ -1004,19 +1004,19 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx,float p_tran
template<class K>
int Animation::_find( const Vector<K>& p_keys, float p_time) const {
-
+
int len=p_keys.size();
if (len==0)
return -2;
-
+
int low = 0;
int high = len -1;
int middle;
-
+
const K* keys =&p_keys[0];
-
+
while( low <= high ) {
-
+
middle = ( low + high ) / 2;
if( p_time == keys[ middle ].time ) { //match
@@ -1029,7 +1029,7 @@ int Animation::_find( const Vector<K>& p_keys, float p_time) const {
if (keys[middle].time>p_time)
middle--;
-
+
return middle;
}
@@ -1197,58 +1197,58 @@ T Animation::_interpolate( const Vector< TKey<T> >& p_keys, float p_time, Inter
int len=_find( p_keys, length )+1; // try to find last key (there may be more past the end)
- if (len<=0) {
+ if (len<=0) {
// (-1 or -2 returned originally) (plus one above)
// meaning no keys, or only key time is larger than length
if (p_ok)
*p_ok=false;
return T();
} else if (len==1) { // one key found (0+1), return it
-
+
if (p_ok)
*p_ok=true;
return p_keys[0].value;
}
-
+
int idx=_find(p_keys, p_time);
-
+
ERR_FAIL_COND_V( idx==-2, T());
-
+
if (p_ok)
*p_ok=true;
int next=0;
- float c=0;
+ float c=0;
// prepare for all cases of interpolation
-
+
if (loop) {
// loop
if (idx>=0) {
-
+
if ((idx+1) < len) {
-
+
next=idx+1;
float delta=p_keys[next].time - p_keys[idx].time;
float from=p_time-p_keys[idx].time;
if (Math::absf(delta)>CMP_EPSILON)
c=from/delta;
- else
+ else
c=0;
-
+
} else {
-
+
next=0;
float delta=(length - p_keys[idx].time) + p_keys[next].time;
float from=p_time-p_keys[idx].time;
-
+
if (Math::absf(delta)>CMP_EPSILON)
- c=from/delta;
- else
+ c=from/delta;
+ else
c=0;
-
+
}
-
+
} else {
// on loop, behind first key
idx=len-1;
@@ -1258,47 +1258,47 @@ T Animation::_interpolate( const Vector< TKey<T> >& p_keys, float p_time, Inter
endtime=0;
float delta=endtime + p_keys[next].time;
float from=endtime+p_time;
-
+
if (Math::absf(delta)>CMP_EPSILON)
- c=from/delta;
- else
+ c=from/delta;
+ else
c=0;
- }
-
- } else { // no loop
+ }
+
+ } else { // no loop
if (idx>=0) {
-
+
if ((idx+1) < len) {
-
+
next=idx+1;
float delta=p_keys[next].time - p_keys[idx].time;
float from=p_time - p_keys[idx].time;
-
+
if (Math::absf(delta)>CMP_EPSILON)
c=from/delta;
else
c=0;
-
+
} else {
-
+
next=idx;
}
-
+
} else if (idx<0) {
-
+
idx=next=0;
- }
-
+ }
+
}
-
+
float tr = p_keys[idx].transition;
if (tr==0 || idx==next) {
// don't interpolate if not needed
return p_keys[idx].value;
}
-
+
if (tr!=1.0) {
c = Math::ease(c,tr);
@@ -1331,7 +1331,7 @@ T Animation::_interpolate( const Vector< TKey<T> >& p_keys, float p_time, Inter
// do a barrel roll
-
+
}
@@ -1340,7 +1340,7 @@ Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3
ERR_FAIL_INDEX_V(p_track, tracks.size(),ERR_INVALID_PARAMETER);
Track *t=tracks[p_track];
ERR_FAIL_COND_V(t->type!=TYPE_TRANSFORM,ERR_INVALID_PARAMETER);
-
+
TransformTrack * tt = static_cast<TransformTrack*>(t);
bool ok;
@@ -1368,7 +1368,7 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(),0);
Track *t=tracks[p_track];
ERR_FAIL_COND_V(t->type!=TYPE_VALUE, Variant());
- ValueTrack * vt = static_cast<ValueTrack*>(t);
+ ValueTrack * vt = static_cast<ValueTrack*>(t);
bool ok;
@@ -1377,7 +1377,7 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
if (ok) {
-
+
return res;
}
@@ -1426,15 +1426,15 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
float from_time=p_time-p_delta;
float to_time=p_time;
-
+
if (from_time>to_time)
SWAP(from_time,to_time);
-
+
if (loop) {
-
- from_time=Math::fposmod(from_time,length);
- to_time=Math::fposmod(to_time,length);
-
+
+ from_time=Math::fposmod(from_time,length);
+ to_time=Math::fposmod(to_time,length);
+
if (from_time>to_time) {
// handle loop by splitting
_value_track_get_key_indices_in_range(vt,length-from_time,length,p_indices);
@@ -1442,12 +1442,12 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
return;
}
} else {
-
+
if (from_time<0)
from_time=0;
if (from_time>length)
from_time=length;
-
+
if (to_time<0)
to_time=0;
if (to_time>length)
@@ -1455,10 +1455,10 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
}
-
+
_value_track_get_key_indices_in_range(vt,from_time,to_time,p_indices);
-
+
}
void Animation::value_track_set_continuous(int p_track, bool p_continuous) {
@@ -1519,19 +1519,19 @@ void Animation::_method_track_get_key_indices_in_range(const MethodTrack * mt, f
void Animation::method_track_get_key_indices(int p_track, float p_time, float p_delta,List<int> *p_indices) const {
ERR_FAIL_INDEX(p_track, tracks.size());
- Track *t=tracks[p_track];
+ Track *t=tracks[p_track];
ERR_FAIL_COND( t->type != TYPE_METHOD );
MethodTrack * mt = static_cast<MethodTrack*>(t);
float from_time=p_time-p_delta;
float to_time=p_time;
-
+
if (from_time>to_time)
SWAP(from_time,to_time);
-
+
if (loop) {
-
+
if (from_time > length || from_time < 0)
from_time=Math::fposmod(from_time,length);
@@ -1545,19 +1545,19 @@ void Animation::method_track_get_key_indices(int p_track, float p_time, float p_
return;
}
} else {
-
+
if (from_time<0)
from_time=0;
if (from_time>length)
from_time=length;
-
+
if (to_time<0)
to_time=0;
if (to_time>length)
to_time=length;
-
+
}
-
+
_method_track_get_key_indices_in_range(mt,from_time,to_time,p_indices);
@@ -1569,9 +1569,9 @@ Vector<Variant> Animation::method_track_get_params(int p_track,int p_key_idx) co
ERR_FAIL_COND_V( t->type != TYPE_METHOD, Vector<Variant>() );
MethodTrack * pm = static_cast<MethodTrack*>(t);
-
+
ERR_FAIL_INDEX_V( p_key_idx, pm->methods.size(), Vector<Variant>() );
-
+
const MethodKey& mk=pm->methods[p_key_idx];
return mk.params;
@@ -1583,9 +1583,9 @@ StringName Animation::method_track_get_name(int p_track,int p_key_idx) const {
ERR_FAIL_COND_V( t->type != TYPE_METHOD, StringName() );
MethodTrack * pm = static_cast<MethodTrack*>(t);
-
+
ERR_FAIL_INDEX_V( p_key_idx, pm->methods.size(), StringName() );
-
+
return pm->methods[ p_key_idx ].method;
}
@@ -1600,7 +1600,7 @@ void Animation::set_length(float p_length) {
float Animation::get_length() const {
return length;
-}
+}
void Animation::set_loop(bool p_enabled) {
@@ -1678,16 +1678,16 @@ void Animation::_bind_methods() {
ObjectTypeDB::bind_method(_MD("transform_track_interpolate","idx","time_sec"),&Animation::_transform_track_interpolate);
ObjectTypeDB::bind_method(_MD("value_track_set_continuous","idx","continuous"),&Animation::value_track_set_continuous);
ObjectTypeDB::bind_method(_MD("value_track_is_continuous","idx"),&Animation::value_track_is_continuous);
-
+
ObjectTypeDB::bind_method(_MD("value_track_get_key_indices","idx","time_sec","delta"),&Animation::_value_track_get_key_indices);
ObjectTypeDB::bind_method(_MD("method_track_get_key_indices","idx","time_sec","delta"),&Animation::_method_track_get_key_indices);
ObjectTypeDB::bind_method(_MD("method_track_get_name","idx","key_idx"),&Animation::method_track_get_name);
ObjectTypeDB::bind_method(_MD("method_track_get_params","idx","key_idx"),&Animation::method_track_get_params);
-
+
ObjectTypeDB::bind_method(_MD("set_length","time_sec"),&Animation::set_length);
ObjectTypeDB::bind_method(_MD("get_length"),&Animation::get_length);
-
+
ObjectTypeDB::bind_method(_MD("set_loop","enabled"),&Animation::set_loop);
ObjectTypeDB::bind_method(_MD("has_loop"),&Animation::has_loop);
@@ -1699,7 +1699,7 @@ void Animation::_bind_methods() {
BIND_CONSTANT( TYPE_VALUE );
BIND_CONSTANT( TYPE_TRANSFORM );
BIND_CONSTANT( TYPE_METHOD );
-
+
BIND_CONSTANT( INTERPOLATION_NEAREST );
BIND_CONSTANT( INTERPOLATION_LINEAR );
BIND_CONSTANT( INTERPOLATION_CUBIC );
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 405b8b6a05..1f2d9b80ab 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -61,7 +61,7 @@ public:
private:
struct Track {
-
+
TrackType type;
InterpolationType interpolation;
NodePath path; // path to something
@@ -70,20 +70,20 @@ private:
};
struct Key {
-
+
float transition;
- float time; // time in secs
+ float time; // time in secs
Key() { transition=1; }
};
-
+
// transform key holds either Vector3 or Quaternion
template<class T>
struct TKey : public Key {
-
+
float time;
T value;
};
-
+
struct TransformKey {
@@ -93,45 +93,45 @@ private:
};
/* TRANSFORM TRACK */
-
+
struct TransformTrack : public Track {
Vector< TKey<TransformKey> > transforms;
-
+
TransformTrack() { type=TYPE_TRANSFORM; }
};
-
+
/* PROPERTY VALUE TRACK */
struct ValueTrack : public Track {
bool continuous;
Vector< TKey<Variant> > values;
-
+
ValueTrack() { type=TYPE_VALUE; continuous=true; }
};
/* METHOD TRACK */
-
+
struct MethodKey : public Key {
-
+
StringName method;
Vector<Variant> params;
};
-
+
struct MethodTrack : public Track {
-
+
Vector< MethodKey > methods;
MethodTrack() { type=TYPE_METHOD; }
- };
-
+ };
+
Vector<Track*> tracks;
/*
template<class T>
int _insert_pos(float p_time, T& p_keys);*/
-
+
template<class T>
void _clear(T& p_keys);
@@ -140,7 +140,7 @@ private:
template<class K>
inline int _find( const Vector<K>& p_keys, float p_time) const;
-
+
_FORCE_INLINE_ Animation::TransformKey _interpolate( const Animation::TransformKey& p_a, const Animation::TransformKey& p_b, float p_c) const;
_FORCE_INLINE_ Vector3 _interpolate( const Vector3& p_a, const Vector3& p_b, float p_c) const;
@@ -163,9 +163,9 @@ private:
float length;
float step;
bool loop;
-
+
// bind helpers
-private:
+private:
Array _transform_track_interpolate(int p_track, float p_time) const {
Vector3 loc;
@@ -180,25 +180,25 @@ private:
}
DVector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const {
-
+
List<int> idxs;
value_track_get_key_indices(p_track,p_time,p_delta,&idxs);
DVector<int> idxr;
-
+
for (List<int>::Element *E=idxs.front();E;E=E->next()) {
-
+
idxr.push_back(E->get());
}
return idxr;
}
DVector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const {
-
+
List<int> idxs;
method_track_get_key_indices(p_track,p_time,p_delta,&idxs);
DVector<int> idxr;
-
+
for (List<int>::Element *E=idxs.front();E;E=E->next()) {
-
+
idxr.push_back(E->get());
}
return idxr;
@@ -207,28 +207,28 @@ private:
bool _transform_track_optimize_key(const TKey<TransformKey> &t0,const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err,float p_alowed_angular_err,float p_max_optimizable_angle,const Vector3& p_norm);
void _transform_track_optimize(int p_idx, float p_allowed_err=0.05, float p_alowed_angular_err=0.01,float p_max_optimizable_angle=Math_PI*0.125);
-protected:
+protected:
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
- static void _bind_methods();
-
+
+ static void _bind_methods();
+
public:
-
+
int add_track(TrackType p_type,int p_at_pos=-1);
void remove_track(int p_track);
int get_track_count() const;
TrackType track_get_type(int p_track) const;
-
+
void track_set_path(int p_track,const NodePath& p_path);
NodePath track_get_path(int p_track) const;
int find_track(const NodePath& p_path) const;
// transform
-
+
void track_move_up(int p_track);
void track_move_down(int p_track);
@@ -248,9 +248,9 @@ public:
void track_set_interpolation_type(int p_track,InterpolationType p_interp);
InterpolationType track_get_interpolation_type(int p_track) const;
-
+
Error transform_track_interpolate(int p_track, float p_time, Vector3 * r_loc, Quat *r_rot, Vector3 *r_scale) const;
-
+
Variant value_track_interpolate(int p_track, float p_time) const;
void value_track_get_key_indices(int p_track, float p_time, float p_delta,List<int> *p_indices) const;
void value_track_set_continuous(int p_track, bool p_continuous);
@@ -259,11 +259,11 @@ public:
void method_track_get_key_indices(int p_track, float p_time, float p_delta,List<int> *p_indices) const;
Vector<Variant> method_track_get_params(int p_track,int p_key_idx) const;
StringName method_track_get_name(int p_track,int p_key_idx) const;
-
+
void set_length(float p_length);
float get_length() const;
-
+
void set_loop(bool p_enabled);
bool has_loop() const;
@@ -274,7 +274,7 @@ public:
void optimize(float p_allowed_linear_err=0.05,float p_allowed_angular_err=0.01,float p_max_optimizable_angle=Math_PI*0.125);
- Animation();
+ Animation();
~Animation();
};
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index f713b9e979..005a46c0bc 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -241,7 +241,15 @@ void make_default_theme() {
t->set_constant("hseparation","Button", 2);
+ // LinkButton
+ t->set_font("font","LinkButton", default_font );
+
+ t->set_color("font_color","LinkButton", control_font_color );
+ t->set_color("font_color_pressed","LinkButton", control_font_color_pressed );
+ t->set_color("font_color_hover","LinkButton", control_font_color_hover );
+
+ t->set_constant("underline_spacing","LinkButton", 2 );
// ColorPickerButton
@@ -264,8 +272,8 @@ void make_default_theme() {
// ToolButton
Ref<StyleBox> tb_empty = memnew( StyleBoxEmpty );
- tb_empty->set_default_margin(MARGIN_LEFT,8);
- tb_empty->set_default_margin(MARGIN_RIGHT,8);
+ tb_empty->set_default_margin(MARGIN_LEFT,6);
+ tb_empty->set_default_margin(MARGIN_RIGHT,6);
tb_empty->set_default_margin(MARGIN_TOP,4);
tb_empty->set_default_margin(MARGIN_BOTTOM,4);
@@ -550,10 +558,10 @@ void make_default_theme() {
t->set_constant("close_v_ofs","WindowDialog", 20 );
t->set_constant("titlebar_height","WindowDialog", 18 );
t->set_constant("title_height","WindowDialog", 20 );
-
-
+
+
// File Dialog
-
+
t->set_icon("reload","FileDialog",make_icon( icon_reload_png ));
@@ -776,7 +784,7 @@ void make_default_theme() {
t->set_icon("screen_picker","ColorPicker", make_icon( icon_color_pick_png ) );
t->set_icon("add_preset","ColorPicker", make_icon( icon_add_png ) );
-
+
t->set_shader("uv_editor", "ColorPicker", make_shader("", uv_editor_shader_code, ""));
t->set_shader("w_editor", "ColorPicker", make_shader("", w_editor_shader_code, ""));
@@ -882,7 +890,18 @@ void make_default_theme() {
t->set_stylebox("border","ReferenceFrame", make_stylebox( reference_border_png,4,4,4,4) );
t->set_stylebox("panelnc","Panel", ttnc );
t->set_stylebox("panelf","Panel", tc_sb );
- t->set_stylebox("panel","PanelContainer", tc_sb );
+
+ Ref<StyleBoxTexture> sb_pc = make_stylebox( tab_container_bg_png,4,4,4,4,7,7,7,7);
+ t->set_stylebox("panel","PanelContainer", sb_pc );
+
+
+
+ t->set_icon("minus","GraphEdit", make_icon(icon_zoom_less_png) );
+ t->set_icon("reset","GraphEdit", make_icon(icon_zoom_reset_png) );
+ t->set_icon("more","GraphEdit", make_icon(icon_zoom_more_png) );
+ t->set_stylebox("bg","GraphEdit", make_stylebox( tree_bg_png,4,4,4,5) );
+
+
t->set_icon( "logo","Icons", make_icon(logo_png) );
diff --git a/scene/resources/default_theme/icon_zoom_less.png b/scene/resources/default_theme/icon_zoom_less.png
new file mode 100644
index 0000000000..3e50ce0c22
--- /dev/null
+++ b/scene/resources/default_theme/icon_zoom_less.png
Binary files differ
diff --git a/scene/resources/default_theme/icon_zoom_more.png b/scene/resources/default_theme/icon_zoom_more.png
new file mode 100644
index 0000000000..4f2928064c
--- /dev/null
+++ b/scene/resources/default_theme/icon_zoom_more.png
Binary files differ
diff --git a/scene/resources/default_theme/icon_zoom_reset.png b/scene/resources/default_theme/icon_zoom_reset.png
new file mode 100644
index 0000000000..36fafc2037
--- /dev/null
+++ b/scene/resources/default_theme/icon_zoom_reset.png
Binary files differ
diff --git a/scene/resources/default_theme/popup_window.png b/scene/resources/default_theme/popup_window.png
index fc42e725f8..c897ada988 100644
--- a/scene/resources/default_theme/popup_window.png
+++ b/scene/resources/default_theme/popup_window.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 4c440ab99a..42695c4905 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -214,6 +214,21 @@ static const unsigned char icon_stop_png[]={
};
+static const unsigned char icon_zoom_less_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x12,0x0,0x0,0xb,0x12,0x1,0xd2,0xdd,0x7e,0xfc,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x2,0x8,0x11,0x19,0x15,0x8e,0xdd,0x4e,0x19,0x0,0x0,0x1,0x25,0x49,0x44,0x41,0x54,0x38,0xcb,0x9d,0x92,0xc1,0x8a,0xc2,0x30,0x10,0x86,0xbf,0x99,0x36,0x94,0xd2,0xaa,0x4,0x5b,0x28,0x78,0xe9,0xfb,0x3f,0x95,0x22,0x78,0x11,0x9,0x4a,0xf,0xb5,0xd8,0x64,0x2f,0xdb,0xec,0xb2,0xad,0xbb,0xae,0xdf,0x29,0xcc,0x64,0xfe,0xfc,0x33,0x19,0xe1,0x13,0xe7,0x1c,0xd6,0x5a,0x2e,0x97,0xb,0xde,0x7b,0x0,0x54,0x95,0xed,0x76,0x1b,0x73,0x4b,0xc8,0x54,0xc,0xd0,0x75,0x1d,0xe3,0x38,0x92,0xa6,0x29,0x0,0x8f,0xc7,0x83,0x24,0x49,0x28,0x8a,0x2,0x11,0x59,0x14,0x91,0xe9,0xb0,0xdf,0xef,0x11,0x11,0xd2,0x34,0x65,0xb7,0xdb,0xc5,0xb,0xa7,0xd3,0x89,0x61,0x18,0x68,0xdb,0x76,0xd1,0x89,0x38,0xe7,0xb8,0xdf,0xef,0xf4,0x7d,0xf,0xc0,0x66,0xb3,0x1,0xc0,0x5a,0x1b,0xb,0x8e,0xc7,0x23,0xc6,0x18,0x9a,0xa6,0x99,0x39,0x50,0x6b,0x2d,0x7d,0xdf,0x53,0x96,0x25,0xab,0xd5,0x2a,0x16,0x7f,0x17,0xc9,0xf3,0x3c,0x3e,0x30,0x13,0x88,0x56,0x44,0x50,0xd5,0xe5,0x3e,0x45,0x78,0x86,0x0,0x1c,0xe,0x7,0x42,0x8,0x81,0x7f,0xd0,0xb6,0xad,0x0,0xa8,0x73,0x8e,0x2c,0xcb,0x78,0x17,0x5,0x16,0x87,0xf3,0xb2,0xc0,0x34,0xa8,0x77,0x91,0xa5,0x4d,0x1c,0xc7,0x11,0x80,0x24,0x49,0xe2,0x26,0x5e,0xaf,0x57,0xb2,0x2c,0xc3,0x18,0x43,0x55,0x55,0xf3,0x5f,0x98,0xa6,0xaf,0xaa,0x18,0x63,0x30,0xc6,0xa0,0x1a,0xd3,0xe4,0x79,0xce,0x30,0xc,0x74,0x5d,0xc7,0xf9,0x7c,0x9e,0x3b,0xf8,0xd,0xe7,0x1c,0x21,0x4,0x6e,0xb7,0x5b,0x8c,0x15,0x45,0x41,0x5d,0xd7,0xaf,0x9,0x3c,0x13,0x29,0xcb,0xf2,0xab,0x85,0xbf,0xb0,0xd6,0x22,0x22,0xac,0xd7,0xeb,0x18,0xf3,0xde,0xbf,0xee,0xe0,0xa7,0x13,0xef,0x3d,0x55,0x55,0xf1,0x1,0x48,0x6e,0x80,0x3e,0x13,0xf0,0x5,0xd,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
+static const unsigned char icon_zoom_more_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x12,0x0,0x0,0xb,0x12,0x1,0xd2,0xdd,0x7e,0xfc,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x2,0x8,0x11,0x19,0x1f,0x6e,0x8,0xa7,0x7,0x0,0x0,0x1,0x23,0x49,0x44,0x41,0x54,0x38,0xcb,0x9d,0x92,0x4d,0xaf,0x82,0x30,0x10,0x45,0xcf,0x8c,0x36,0xe0,0x77,0x1a,0x59,0xb0,0x70,0xe1,0xff,0xff,0x57,0xae,0xd5,0x34,0x10,0x30,0x60,0x68,0xeb,0xe6,0xc1,0xf3,0x9,0x26,0xfa,0xee,0xae,0x69,0xe7,0xcc,0xcc,0xbd,0x15,0x7e,0xe4,0x9c,0xc3,0x5a,0xcb,0xf5,0x7a,0x25,0x84,0x0,0x80,0xaa,0xb2,0xdf,0xef,0x87,0xbb,0x29,0x49,0x5f,0xc,0x50,0x55,0x15,0xde,0x7b,0xe6,0xf3,0x39,0x0,0x5d,0xd7,0x31,0x9b,0xcd,0x58,0xad,0x56,0x88,0xc8,0x24,0x44,0x1,0xac,0xb5,0x14,0x45,0x41,0x8,0x1,0x63,0xc,0x87,0xc3,0x81,0xae,0xeb,0x22,0x10,0xbd,0xf7,0xb1,0x2c,0xcb,0x68,0xad,0x1d,0x1a,0xfd,0x99,0xc0,0x39,0x47,0xdb,0xb6,0x34,0x4d,0x3,0xc0,0x6e,0xb7,0x3,0xa0,0x28,0x8a,0xf8,0xfc,0x30,0x4d,0x53,0xc9,0xf3,0x7c,0x3c,0x81,0xb5,0x96,0xa6,0x69,0x58,0xaf,0xd7,0x6c,0x36,0x1b,0xfa,0x89,0x5e,0xd5,0x37,0x98,0x5c,0x1,0x40,0x44,0x50,0xd5,0xb7,0x66,0xbd,0x93,0x0,0x9c,0x4e,0x27,0x62,0x8c,0xf1,0x9b,0xc2,0xe3,0xf1,0x28,0x0,0xea,0x9c,0x23,0x49,0x12,0xfe,0x2b,0x5,0x98,0x32,0xe7,0x63,0xc0,0xbb,0x78,0xbe,0xf2,0xe0,0xf5,0x27,0x7a,0xef,0xb9,0xdd,0x6e,0xaf,0x9e,0x48,0x92,0x24,0x18,0x63,0xc8,0xb2,0x6c,0x9c,0x42,0xef,0xbe,0xaa,0x62,0x8c,0x19,0x75,0x5a,0x2c,0x16,0xdc,0xef,0x77,0xaa,0xaa,0xe2,0x7c,0x3e,0x8f,0x1,0xcf,0xa0,0xa9,0x28,0x8d,0x31,0xf4,0x41,0xd5,0x75,0x3d,0x40,0xf4,0xe3,0x5d,0x45,0xd8,0x6e,0xb7,0xc3,0xb9,0xae,0x6b,0x2e,0x97,0xcb,0xaf,0x7,0x9f,0xc8,0x39,0x47,0x8c,0x91,0xb2,0x2c,0x1,0x58,0x2e,0x97,0xdf,0x1,0x9e,0x21,0x21,0x4,0xb2,0x2c,0xe3,0x1,0xf3,0xd9,0x85,0xaf,0x46,0x21,0x2f,0x17,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
+static const unsigned char icon_zoom_reset_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x12,0x0,0x0,0xb,0x12,0x1,0xd2,0xdd,0x7e,0xfc,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x2,0x8,0x11,0x1b,0xa,0x31,0xe3,0x21,0x6e,0x0,0x0,0x0,0xd6,0x49,0x44,0x41,0x54,0x38,0xcb,0xa5,0x92,0xc1,0xaa,0x84,0x30,0xc,0x45,0x4f,0xaa,0x20,0xea,0x42,0x8a,0x2e,0x5c,0xf6,0xff,0xbf,0xaa,0x1f,0xa0,0x4,0xc4,0x85,0x82,0xb6,0x6f,0xf3,0x94,0x19,0x47,0x1d,0x66,0xe6,0xac,0x4a,0x93,0x9b,0x26,0xe9,0x15,0xfe,0x51,0x55,0xac,0xb5,0xf4,0x7d,0x4f,0x8,0x1,0x0,0x63,0xc,0x75,0x5d,0xef,0xb1,0x33,0x64,0x13,0x3,0x8c,0xe3,0xc8,0xba,0xae,0xa4,0x69,0xa,0xc0,0xb2,0x2c,0x24,0x49,0x42,0x59,0x96,0x88,0xc8,0x69,0x11,0xd9,0xe,0xde,0x7b,0x80,0x78,0xbc,0xdf,0x70,0xce,0x3d,0xe5,0x38,0xe7,0x4,0x20,0x55,0x55,0xe6,0x79,0x66,0x9a,0xa6,0xc8,0xd,0x87,0x7,0x76,0x8c,0xb5,0xf6,0x4e,0x1c,0x1f,0x44,0xa7,0x39,0x86,0x1f,0x31,0x0,0x22,0x22,0x67,0x73,0x9f,0xec,0xeb,0x25,0xc7,0xa8,0x2a,0x59,0x96,0x7d,0x24,0x7a,0xe9,0xa0,0x6d,0xdb,0xef,0x47,0xb0,0xd6,0xee,0x3e,0x78,0xb3,0xc4,0xeb,0xe,0xac,0xb5,0x54,0x55,0xf5,0xfd,0x12,0xb7,0x22,0x77,0xe4,0x79,0x7e,0x6d,0x65,0xef,0x7d,0xbc,0x8a,0x1d,0xc6,0x39,0xba,0x53,0x7e,0xf2,0x41,0xd7,0x75,0x6f,0xff,0xfe,0x9,0x55,0x25,0xc6,0xc8,0x30,0xc,0x0,0x14,0x45,0xf1,0x59,0x81,0xc7,0x22,0x21,0x4,0x9a,0xa6,0xe1,0xf,0x29,0x54,0x56,0xd3,0x43,0xf4,0x61,0x53,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
static const unsigned char line_edit_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0xa,0x0,0x0,0x0,0xa,0x8,0x6,0x0,0x0,0x0,0x8d,0x32,0xcf,0xbd,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0xa,0x14,0x3,0x1d,0x2f,0xec,0x8c,0x33,0x2f,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0x9d,0x49,0x44,0x41,0x54,0x18,0xd3,0xb5,0x90,0x31,0xe,0xc2,0x40,0x10,0x3,0xed,0xbb,0xd5,0x25,0xa1,0xa1,0x3,0x9,0x41,0xc1,0x33,0x78,0x15,0x5f,0xc8,0x93,0x41,0x14,0x49,0x2e,0xbb,0xb7,0x29,0x2,0x52,0x20,0x14,0x34,0x58,0x72,0x63,0x4f,0x61,0x99,0xfb,0xdd,0xe1,0x9a,0x52,0xd5,0xc6,0x10,0x6b,0x92,0x58,0xca,0xdd,0x61,0xc5,0xfa,0x9c,0x87,0x96,0xa7,0xe3,0xf9,0x56,0xa5,0x7a,0x2b,0x22,0x0,0xde,0x41,0xc0,0xa1,0xaa,0x18,0x72,0x7f,0x97,0x18,0x62,0x23,0x22,0x88,0x22,0xe0,0x7,0xe8,0x70,0x0,0x80,0x6a,0x6c,0x2,0xc9,0x2,0x70,0x5,0x1,0x78,0x66,0x4,0xc9,0x12,0xf0,0xa3,0xfe,0x0,0xba,0x7b,0x98,0x67,0xfb,0xaa,0x9c,0x33,0x87,0xbb,0x7,0xb1,0x62,0x9d,0xaa,0xa6,0xd7,0xfc,0x6f,0xf7,0x58,0xb1,0x3e,0x36,0xf5,0xa6,0x3,0x70,0x29,0x66,0x30,0x53,0x5d,0x5a,0x75,0xd4,0x51,0xc7,0x47,0xce,0x43,0x3b,0x1,0xc,0x2e,0x55,0x5d,0x5f,0x72,0xb6,0x33,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
@@ -234,6 +249,11 @@ static const unsigned char logo_png[]={
};
+static const unsigned char oc3_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x5,0x0,0x0,0x0,0x2,0xd0,0x8,0x6,0x0,0x0,0x0,0xcf,0x7d,0xdd,0x56,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x2,0x9,0x12,0x8,0x1b,0x80,0x46,0x99,0x32,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x78,0xda,0xec,0xdd,0xe9,0xb3,0x6d,0x77,0x79,0x27,0xf6,0xef,0x6f,0x58,0x6b,0xef,0x73,0xee,0xbd,0xba,0x92,0xd0,0x80,0x66,0x81,0xb0,0x4,0x2,0x21,0x31,0x8,0xc,0x6,0x6c,0xc0,0x4c,0x26,0x4d,0x9b,0x6e,0xbb,0xdd,0x9d,0x38,0xae,0x7e,0x93,0x4a,0xaa,0xf2,0x47,0xe4,0x65,0xde,0x25,0xe9,0xaa,0xa4,0x92,0x4a,0xa5,0x3a,0xe9,0x6a,0xaa,0xdb,0xae,0xd8,0x45,0xb9,0x71,0xe3,0xc6,0xe9,0xb6,0xc1,0x6,0x33,0x63,0x40,0x2,0x9,0x90,0x84,0x4,0x68,0x9e,0xef,0x70,0xce,0xde,0x6b,0xfd,0x86,0xbc,0x78,0x9e,0xe7,0xb7,0xd6,0x3e,0xc3,0x95,0xdc,0x7d,0x6f,0xe2,0xda,0xf5,0xfd,0x50,0x17,0xdd,0x7b,0x86,0xbd,0xd7,0x5e,0x7b,0xdd,0x7d,0xee,0xf9,0x9e,0x67,0x70,0x0,0x2a,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x2b,0x79,0x9e,0x2,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0xed,0xc5,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x31,0x0,0x24,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xda,0x62,0xc,0x0,0x89,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xb6,0x18,0x3,0x40,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xa2,0x2d,0xc6,0x0,0x90,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x68,0x8b,0x45,0x9e,0x2,0x22,0xa2,0x57,0x2f,0xc4,0x1e,0x3e,0xf6,0x38,0x71,0xfa,0xa,0xd4,0x5c,0x50,0x51,0x11,0xbb,0x1e,0xa8,0x15,0xa5,0x14,0x84,0xd8,0xc1,0x7b,0x8f,0xfd,0xbd,0xb3,0xd8,0xd9,0x3d,0x85,0xb3,0x2f,0x3d,0x87,0xe5,0x89,0x53,0x48,0xe3,0x0,0xef,0x3,0xba,0x7e,0x9,0x0,0xd8,0x3f,0x7f,0x6,0xfd,0x62,0x7,0x69,0x1c,0xd0,0x2f,0x96,0x48,0x69,0x44,0x29,0x19,0xde,0x7,0x94,0x9c,0xd1,0x2f,0x77,0x30,0xac,0xf7,0xd1,0xeb,0xc7,0xf,0xeb,0x15,0xfa,0xc5,0x12,0xa5,0x64,0x84,0xd8,0xa1,0x96,0x82,0x10,0x23,0xf6,0xcf,0x9f,0x43,0xec,0xba,0x76,0xdf,0xeb,0xfd,0xf3,0x38,0x79,0xfa,0x4a,0xc,0xab,0x3d,0xb9,0xad,0x52,0xd0,0xf5,0x3d,0x4a,0x29,0x0,0x80,0x71,0x58,0xa3,0xeb,0x17,0xed,0xf7,0xf2,0x31,0x72,0xbf,0xde,0x7b,0xc,0xeb,0x15,0x42,0xd7,0x21,0x8f,0x23,0x16,0x3b,0xbb,0x18,0xd7,0x6b,0xc4,0xae,0x43,0x1a,0x47,0xa4,0x71,0xc0,0xce,0xc9,0x53,0xc8,0x69,0xc4,0x7a,0xb5,0x8f,0xe5,0xee,0x49,0x8c,0xeb,0x15,0x16,0x3b,0xbb,0xc8,0x69,0x44,0x8,0x1d,0x4a,0x2d,0xf0,0xce,0x61,0xef,0xfc,0x59,0xf4,0xcb,0x1d,0x74,0xdd,0x2,0x39,0x8f,0xa8,0xa5,0x20,0x8d,0x23,0x16,0xcb,0x5d,0xc0,0x1,0xeb,0xfd,0x3d,0xe4,0x9c,0xda,0x6d,0xf4,0x8b,0x25,0x86,0xf5,0x3e,0x0,0x87,0xc5,0xce,0x2e,0xd2,0x38,0xc2,0x7,0x8f,0x9c,0x12,0x96,0x3b,0x27,0x30,0x8e,0x3,0xbc,0xf7,0x28,0xa5,0x20,0x8d,0x3,0x62,0xd7,0x63,0x5c,0xef,0x23,0xc4,0x1e,0xb1,0xeb,0xb0,0xde,0xdf,0x83,0xf7,0x1e,0xa1,0xeb,0xe1,0x9d,0xc7,0x7a,0xb5,0x87,0xd8,0x75,0x88,0x5d,0x8f,0xf3,0x67,0x5f,0xc6,0xc9,0xd3,0x57,0xa2,0xe4,0x84,0xf5,0xfe,0x1e,0xba,0x7e,0x81,0x94,0x46,0x0,0x90,0xc7,0x74,0xe2,0x14,0x86,0xd5,0xbe,0xdc,0xce,0x6a,0x1f,0x25,0x27,0x2c,0x96,0xbb,0x7a,0x1e,0x12,0x2a,0x2a,0xfa,0x7e,0x81,0x52,0xa,0x9c,0xf7,0xc8,0x69,0x84,0xf7,0x1,0xab,0xfd,0xf3,0x58,0xee,0x9c,0xc0,0x6a,0xff,0x3c,0xba,0xae,0x47,0x88,0x1d,0x72,0x1a,0x51,0x1,0xc4,0xae,0xc3,0xb0,0x5a,0xb5,0x73,0x9b,0xc6,0x35,0x76,0x4f,0x9e,0x6e,0xcf,0x5d,0x45,0x45,0x2d,0x5,0x39,0x8d,0x18,0xf5,0xf1,0xd4,0x92,0x51,0x1,0xf4,0xfd,0x12,0x69,0x1c,0xe0,0x9c,0x93,0xdb,0x8a,0x1d,0x2a,0x2a,0x4a,0x4a,0x8,0xb1,0xc3,0x6a,0xff,0x3c,0x0,0xe8,0x79,0x4f,0xed,0xf9,0xac,0xa5,0x60,0x58,0xaf,0xb0,0xb3,0x7b,0x12,0x29,0x8f,0x58,0xef,0xef,0x61,0xb9,0x73,0xa2,0x1d,0x83,0xf3,0x5e,0x3e,0x66,0x58,0xc9,0x7d,0xa4,0x11,0x31,0x76,0xd8,0x3b,0xf7,0x32,0x96,0xbb,0x27,0xe1,0xbc,0xc7,0xb8,0x5e,0xc3,0x7,0xb9,0x16,0xd2,0x38,0xa2,0x5b,0x2c,0xe0,0x5d,0x0,0x9c,0x5e,0x3b,0x5d,0x8f,0x9c,0x33,0xd2,0xb8,0x86,0xf,0x11,0x21,0x46,0x3d,0xf7,0x61,0xe3,0xf3,0x7c,0x8,0xf2,0x17,0xa6,0x56,0xf8,0x30,0xdd,0x77,0xc9,0x59,0xde,0xee,0x1c,0xd2,0xb0,0xc6,0xfe,0xd9,0x17,0xf8,0xa2,0x42,0x44,0x44,0x44,0x44,0xf4,0xff,0x1,0x6,0x80,0x44,0x44,0xaf,0xd2,0x2f,0xdd,0xf3,0x2b,0xb8,0xe1,0xd6,0xdb,0xb1,0xd8,0xd9,0x5,0x0,0xd4,0x52,0x1,0xd4,0x16,0xb4,0x1,0x80,0xf3,0xe,0xa8,0x40,0x45,0x95,0x0,0xa7,0x54,0x9,0x3f,0x6a,0x81,0x73,0x1e,0xa8,0x15,0xb5,0x56,0xc0,0xc9,0x6d,0x3a,0x27,0xc1,0x88,0x84,0x3d,0x55,0xde,0x6,0x87,0x5a,0xab,0xdc,0x16,0x20,0x1f,0xf,0x0,0x15,0x70,0x4e,0xde,0x56,0x4a,0x86,0x73,0xbe,0xdd,0xb6,0xbd,0xaf,0xd6,0xda,0xfe,0x2b,0x9f,0x2b,0xb7,0xd,0x3b,0x16,0x37,0xbb,0xed,0xd9,0x71,0xa2,0x56,0x0,0x4e,0x3e,0xde,0x87,0xe9,0x38,0x31,0xdd,0x67,0x3b,0x8,0x38,0x0,0x12,0x78,0xfa,0x10,0x50,0x4b,0x81,0x3d,0xa0,0x83,0xb7,0xf,0x54,0xb9,0xe9,0x76,0x9e,0xa6,0x0,0xa8,0x96,0x2,0xef,0x83,0x1e,0xb3,0x3c,0x72,0x38,0x9,0xb2,0x30,0xbf,0x4f,0x3d,0xb6,0x76,0x98,0x98,0xff,0xb9,0xb6,0xa0,0x4c,0x4f,0x5f,0x7b,0xdc,0xf3,0xfb,0xb3,0xf0,0xd0,0x39,0xf,0xe7,0xd0,0x9e,0x2f,0x3d,0x18,0x0,0x55,0x9e,0x9f,0x8d,0x1b,0x91,0xe3,0x6c,0xc7,0x34,0x7b,0xbe,0x80,0xa,0xe7,0x83,0x9c,0x7b,0xbb,0x15,0x37,0x7b,0xbe,0x34,0xf8,0x2a,0x7a,0xce,0xe5,0x3c,0xd4,0x8d,0xe7,0x68,0xf3,0xbe,0xed,0x39,0x73,0xb3,0xf3,0x31,0xbd,0xbf,0x56,0x0,0x55,0x2,0x48,0xbb,0x8f,0xcd,0xe7,0xd9,0x6e,0xd3,0x1,0x55,0xce,0xdf,0x74,0xad,0xc8,0x31,0x7a,0xe7,0x25,0x78,0xac,0x15,0x5e,0x3,0xb9,0xf6,0x71,0x7a,0x2d,0xc8,0x75,0x5d,0xf4,0xba,0xaa,0x9b,0xcf,0xa9,0xf3,0x72,0x34,0xf5,0xf0,0xfb,0x8b,0x5e,0xc3,0x73,0x55,0xaf,0xf,0x54,0xa0,0xd8,0x75,0xa8,0x8f,0x7,0x0,0x72,0x4e,0x38,0x7f,0xe6,0x25,0xfc,0xec,0xa1,0x1f,0xe2,0xa9,0x47,0x1f,0xe0,0xb,0xc,0x11,0x11,0x11,0x11,0xd1,0x25,0xe4,0x36,0xbf,0xdb,0x21,0x22,0xa2,0x83,0x76,0x4f,0x5f,0x8d,0x7b,0xde,0xfb,0xeb,0x38,0x75,0xfa,0x4a,0x94,0x52,0x5a,0xa5,0xd6,0x46,0xe0,0x3,0x6c,0x4,0x32,0x7,0xff,0x7c,0x54,0x38,0x37,0x7d,0x9c,0x6,0x83,0x90,0x60,0x6,0x40,0xb,0x54,0x5a,0xb0,0x33,0xb,0x7a,0x2c,0xb4,0xb1,0xe0,0x10,0xce,0xb5,0x80,0xf1,0xe0,0x6d,0x37,0xc7,0x1c,0x97,0xbe,0x61,0xfa,0x18,0xbb,0xaf,0xf9,0x57,0x7,0xfd,0xbd,0x45,0x7f,0xed,0x26,0x51,0x25,0xac,0x3c,0xe2,0x8b,0xc9,0xf4,0xe7,0xc3,0x9f,0x35,0xfd,0x79,0xf6,0xfb,0x16,0x8a,0xce,0xde,0x37,0xbf,0xff,0xa3,0xbe,0x74,0xd5,0x63,0xbe,0xaa,0xe1,0x88,0xaf,0x6c,0x17,0xfa,0x6a,0xe7,0x80,0x23,0x1f,0xc4,0xd1,0x27,0x72,0xf3,0x80,0xda,0xa1,0xc8,0xb9,0x38,0xfe,0xb3,0xa6,0xf7,0xcf,0x83,0x5e,0xcc,0xde,0xd2,0x9e,0x6f,0x7d,0xef,0x74,0x7e,0x2b,0xbc,0xf3,0x28,0xb5,0x1c,0x38,0x6c,0xd,0x8d,0x8f,0x3b,0xc5,0x7,0xff,0x7b,0xd4,0x79,0x39,0xf4,0xc9,0xf6,0x39,0x47,0x3d,0x4f,0x17,0x7a,0xa6,0x8f,0xbd,0x83,0x63,0x3f,0x46,0x72,0xd2,0x82,0x71,0x58,0xe3,0x99,0xc7,0x1f,0xc5,0x43,0xdf,0xff,0x2a,0x5f,0x6c,0x88,0x88,0x88,0x88,0x88,0x2e,0x11,0x56,0x0,0x12,0x11,0xbd,0x82,0x37,0xbf,0xe3,0x7d,0x38,0x71,0xd9,0xe5,0x18,0xc7,0x1,0xb5,0xce,0xda,0x18,0x6b,0xdd,0x8,0x2,0xe7,0xac,0x2a,0xa,0x98,0x2a,0xaf,0xe6,0xef,0x9b,0x57,0x59,0x49,0x90,0x33,0x55,0xd1,0xb5,0x10,0x68,0x56,0x9d,0x55,0x6a,0x41,0x8,0x5a,0x2d,0xe7,0xa5,0x35,0xf6,0xb8,0x8a,0x2b,0xbb,0xed,0x92,0x25,0xa8,0xf4,0x87,0xaa,0xb9,0xb4,0x62,0xd0,0x7b,0x38,0xe7,0xa5,0x4a,0xce,0xc2,0x3f,0xb,0x6a,0xf4,0xb1,0x79,0xe7,0x50,0xe6,0x21,0x64,0xb,0xf,0xad,0xa,0x6f,0xa,0xad,0x36,0x3f,0x1e,0xb3,0xdb,0xd9,0xc,0xc7,0xe6,0x61,0x17,0xf4,0xf1,0x1c,0x7c,0x1c,0x7,0x2b,0x22,0x37,0xef,0xb7,0x9d,0x49,0xab,0x8f,0x9b,0x85,0x85,0x7,0x92,0xcb,0x79,0xe8,0x3a,0xf,0xb6,0x8e,0xc9,0xad,0xa6,0x8a,0xc8,0xd9,0xfb,0x8e,0xbc,0x1f,0xb4,0x6b,0x0,0xb3,0x60,0xcf,0xcd,0x2b,0xf6,0x9c,0x1d,0x3b,0xe,0xe5,0x62,0xf6,0x3c,0xcc,0x2b,0x17,0x9d,0x55,0x1b,0xce,0xce,0xe7,0xfc,0x38,0xe6,0xb7,0x3d,0xf,0x9f,0xdd,0x2c,0x38,0x9d,0x87,0x86,0x56,0x49,0x6a,0x8f,0xdb,0xf9,0x30,0x9d,0xdb,0x5a,0x70,0x28,0xe0,0x3b,0x74,0x4e,0x36,0x1f,0xec,0xac,0x50,0x74,0x7a,0xdf,0x2c,0x9c,0xb6,0x4f,0x71,0xee,0xe8,0x24,0x75,0xe3,0x53,0xf5,0x37,0xa5,0x64,0xe4,0x94,0x70,0xd9,0x95,0x57,0xe3,0xaa,0x1b,0x6e,0xc3,0x73,0x8f,0x3f,0xcc,0x17,0x1c,0x22,0x22,0x22,0x22,0xa2,0x4b,0x80,0x1,0x20,0x11,0xd1,0x2b,0xd8,0x3d,0x75,0x1a,0x39,0x25,0x94,0x9c,0x64,0x8e,0x99,0xb5,0x8f,0x3a,0x68,0x80,0x56,0x70,0xa0,0x63,0x13,0xb9,0x4e,0x2d,0x91,0xb9,0x16,0xd,0xa2,0x36,0x83,0x40,0x5f,0xa7,0x80,0x66,0xa,0xe2,0x0,0x38,0x27,0xb3,0xf4,0xe0,0x51,0x34,0x24,0xf1,0x6e,0x6a,0x61,0x2d,0x39,0xb7,0xb9,0x6e,0x16,0xbe,0xf8,0x10,0x50,0x6a,0x6d,0xf3,0xe5,0xa0,0x61,0xa0,0x54,0x2c,0x5a,0xeb,0x68,0xd5,0xe0,0x50,0xe,0xd4,0xc3,0xa1,0x94,0x34,0xb5,0xac,0xfa,0x28,0xef,0xf7,0x5e,0x42,0xa2,0x9c,0x51,0x9c,0xd7,0x30,0x33,0xeb,0xc3,0xd3,0x50,0xaf,0x2,0x70,0x15,0x80,0xb4,0x20,0x5b,0x8b,0x68,0xd1,0x90,0xac,0xcc,0xda,0x4b,0xa5,0xd5,0xd4,0xb7,0x0,0xad,0xce,0x2a,0xc,0x9d,0x97,0xfb,0xd9,0xc,0xcf,0x34,0x14,0xd4,0xc0,0xb1,0xb5,0x8f,0xce,0xde,0xde,0x5a,0x5f,0x67,0xa9,0xd5,0x66,0xf5,0xe5,0xf4,0x9b,0x92,0x8b,0xb4,0x24,0x6b,0xe6,0x55,0x4b,0x9e,0x2a,0x27,0xb3,0xbc,0x71,0x9e,0xa5,0x6e,0xb6,0x7,0xa3,0x5,0xb5,0x1b,0x2d,0xd1,0xd6,0x1e,0x3c,0x6b,0xb5,0x6,0xe,0xc4,0x5e,0x55,0x8e,0xcf,0x5a,0x95,0xa7,0x63,0x73,0x28,0xe5,0x88,0x80,0xac,0x4e,0x17,0x51,0x9d,0xdf,0x5a,0xb5,0x8b,0xad,0xce,0xda,0x84,0x2d,0xc8,0x9b,0xee,0xcc,0x5a,0x7a,0x2d,0x36,0x2d,0x35,0x4f,0xc7,0x5a,0x81,0x5a,0x92,0x7c,0x9c,0x3e,0x76,0xb4,0x56,0x66,0xaf,0x2d,0xe5,0xae,0xb5,0x7,0x97,0x59,0xcb,0x33,0x50,0x36,0x3,0xe4,0xa2,0xd7,0x72,0x2d,0xd3,0xdb,0xe,0x84,0x80,0xed,0x37,0x7,0xc3,0xf1,0x76,0x3d,0xd8,0x31,0x15,0x94,0x92,0x51,0x73,0xc6,0x72,0xf7,0x24,0x5f,0x6c,0x88,0x88,0x88,0x88,0x88,0x2e,0x11,0x6e,0x1,0x26,0x22,0xba,0xd0,0x8b,0x64,0xe8,0x36,0x2a,0xcf,0xe,0x34,0xef,0x4a,0xb8,0x6,0xa9,0xbc,0x9a,0x57,0x88,0x79,0x1f,0xda,0xc7,0x4c,0xe5,0x60,0x4e,0xdb,0x7d,0xe5,0x3d,0xb5,0x94,0x16,0xe4,0x48,0xc0,0xe6,0x5a,0x75,0x96,0xb5,0xd6,0xd6,0x52,0x10,0x42,0x6c,0x4b,0x15,0x4a,0xc9,0x32,0x7b,0x4f,0xc3,0x3f,0x1f,0xa2,0x84,0x5c,0x56,0xfd,0x67,0xb3,0xda,0x9c,0x47,0x9e,0x5,0x96,0xb5,0x56,0x94,0x2c,0x8b,0x42,0x6a,0x95,0xc0,0x30,0xa5,0xb1,0xcd,0xb6,0x83,0x6,0x8b,0x16,0xa4,0xcd,0xe7,0xfa,0x59,0x0,0xe7,0x7d,0x68,0x95,0x7c,0x36,0x9f,0x10,0xf3,0x96,0x55,0xd,0x84,0x4a,0xc9,0x2d,0x1c,0xb3,0xe0,0x4c,0xce,0x8d,0x54,0xd7,0x85,0x10,0xe0,0x60,0xe3,0xf5,0xe4,0xb3,0xbd,0x6,0x8d,0x76,0xe,0x30,0x9b,0x7b,0x68,0xbf,0x6c,0xfe,0x5e,0xd1,0x0,0x72,0x9a,0x7f,0x67,0x1,0x5c,0xd5,0xe3,0x74,0xed,0xfd,0xed,0xb9,0xb3,0x79,0x84,0xb3,0x39,0x88,0x75,0x2a,0x45,0xdb,0xac,0x2b,0x74,0x1e,0xf3,0xb6,0xd8,0x7a,0x20,0x10,0x6c,0x9f,0x6b,0xa1,0xd8,0x46,0x5,0xe3,0x34,0xb,0xd1,0x42,0xd7,0x3a,0xab,0x12,0x94,0x99,0x87,0xd3,0xed,0x78,0xd,0x34,0xdd,0x6c,0x66,0x9f,0x9c,0xdb,0x3,0x6d,0xb6,0xed,0x94,0x4c,0x61,0xe5,0xa1,0x2b,0x72,0xa3,0x25,0x7d,0xba,0xcd,0x76,0xfe,0xdd,0xf4,0x31,0xb0,0x10,0x6e,0x56,0xa9,0x3a,0x7f,0x7c,0x72,0xe,0x30,0xb,0x77,0xf,0x54,0x9b,0xce,0x2,0xee,0xa3,0xde,0x7f,0x9c,0x36,0xdf,0x71,0xe3,0xf9,0xd1,0xa7,0xf8,0x40,0x8b,0x33,0x11,0x11,0x11,0x11,0x11,0x5d,0xc4,0xef,0x6d,0x79,0xa,0x88,0x88,0x2e,0xc0,0x1d,0xdd,0xe2,0x2b,0x79,0x8e,0x2e,0xf8,0xc0,0xb4,0xb8,0xc3,0x7e,0xc9,0xbb,0x2b,0xbc,0x86,0x5a,0x7e,0x16,0x12,0x6d,0xce,0x6,0xf4,0x1a,0x4,0x45,0x9,0x2,0xb5,0x3d,0xd7,0xc2,0x3f,0xd9,0xe,0x2b,0x55,0x52,0x4e,0x6f,0x27,0xc6,0xd8,0x8e,0x21,0x8d,0x43,0xbb,0x4d,0x7b,0x5b,0x29,0x5,0xa5,0x66,0xd9,0x4e,0xec,0xe4,0x73,0x5c,0x7b,0x5f,0xd2,0xa,0xaf,0xbc,0x11,0x18,0xc2,0x2,0x22,0x54,0x84,0x10,0x35,0x44,0x9c,0x2a,0xcd,0x50,0x81,0x92,0x13,0xe4,0x23,0x34,0xc8,0x69,0xc1,0x92,0x6b,0xd5,0x68,0x55,0x97,0x5f,0xd4,0x32,0x5f,0x5c,0xe2,0x37,0x5a,0x7d,0x4b,0x2d,0xad,0x55,0xd4,0x82,0x53,0x9,0x9a,0x24,0xc4,0xab,0xfa,0x39,0x16,0xa0,0xc1,0x4d,0x8f,0xab,0xce,0x72,0xac,0x16,0x98,0x6d,0xfc,0x7e,0x5a,0xa2,0x61,0xd5,0x82,0xb6,0x28,0xa5,0x15,0xa4,0xb5,0x30,0xb3,0x3d,0x21,0x53,0x85,0x66,0xb,0xcf,0xb0,0x11,0x48,0x1e,0xac,0xe0,0x33,0x12,0xac,0xa6,0xf6,0x5c,0x3a,0xd,0x79,0xa7,0x10,0x75,0x6a,0xed,0xb5,0x8f,0xb7,0xd0,0xce,0x96,0xc7,0x38,0x5d,0x84,0x32,0xf,0x3f,0xe5,0xb1,0xcf,0x96,0x66,0x94,0xe9,0xb8,0x5a,0x6b,0xb9,0x86,0xcc,0xb5,0xd4,0x16,0xf2,0xc2,0xcd,0x26,0xb,0xd6,0x69,0xf1,0x88,0xf7,0x53,0xa8,0x39,0xcd,0x8d,0x3c,0x66,0x2e,0x64,0x3d,0x1c,0xc6,0xcd,0x97,0x8d,0x4c,0x6f,0x3b,0xaa,0x2,0xf0,0x88,0xd9,0x92,0xd3,0x67,0xe0,0xe8,0x31,0x89,0xd3,0x42,0x14,0xdf,0xb3,0xa,0x90,0x88,0x88,0x88,0x88,0xe8,0x52,0x60,0x0,0x48,0x44,0x74,0x1,0x25,0x8d,0x87,0x2,0x40,0xb7,0x51,0xdd,0xa6,0x15,0x80,0x16,0xa4,0xb9,0xf9,0xfc,0xbf,0x3,0x8b,0x3f,0x6c,0xfb,0x6a,0xad,0x88,0xb1,0x83,0xf,0xa1,0x55,0x69,0x59,0xb,0xa6,0x77,0x1e,0x21,0x76,0xf0,0xde,0x4b,0x70,0xe7,0xbd,0x86,0x3a,0xae,0x6d,0x70,0xad,0x55,0x96,0x42,0xd4,0xa,0x84,0x18,0xf,0x4,0x52,0x12,0xa7,0x78,0x1f,0x5a,0xb5,0x9b,0xf3,0xae,0x7d,0x8e,0x85,0x4e,0xb6,0xc1,0xb8,0xb5,0xd4,0x16,0x9,0x1e,0xbd,0xf,0x52,0x9,0xa8,0xc7,0x35,0x6d,0x32,0x76,0xed,0xf1,0xf9,0x16,0xce,0xb9,0xd6,0xc6,0x9,0x40,0x83,0x46,0x37,0x6d,0x24,0x86,0xd5,0xd6,0xcd,0xab,0xee,0xca,0xe6,0x70,0x3b,0x9d,0x81,0xe8,0xf4,0xf1,0xa0,0x6d,0xcc,0x2d,0x5a,0x21,0xa9,0x4d,0xbe,0xa5,0x68,0x9e,0x54,0xf,0x84,0xa7,0xe5,0xd0,0xd6,0xe3,0x56,0xfd,0x67,0xf3,0xee,0xca,0x66,0x50,0x55,0x4b,0x9d,0x55,0xb6,0xe1,0x70,0x1b,0x6f,0xdd,0xac,0xda,0x3b,0xd8,0xac,0x3b,0xbf,0x7f,0xef,0x43,0xb,0xfe,0xa6,0xe5,0x16,0x7,0xc2,0xb3,0x52,0x67,0x1,0xe3,0xc1,0x6d,0xc2,0xc0,0xe6,0x6,0x62,0xad,0xba,0xcc,0x59,0xab,0x3,0xe7,0xed,0xe6,0xba,0x70,0x65,0x56,0x9d,0x67,0x95,0xa5,0x21,0x6a,0x95,0xe8,0x51,0x6d,0xb7,0x98,0xce,0x7d,0xad,0x53,0x58,0xe8,0xe6,0xcf,0xf1,0xbc,0x8a,0xcf,0x4d,0xf7,0x31,0xaf,0x4c,0xc4,0xc6,0x1c,0xcb,0x29,0x50,0xdc,0xdc,0x16,0x7d,0x44,0xe8,0x37,0x3b,0x8e,0x76,0x91,0x2,0xed,0x38,0xdd,0x74,0xa2,0x50,0xc7,0xf3,0x7c,0xd1,0x21,0x22,0x22,0x22,0x22,0xba,0x4,0x18,0x0,0x12,0x11,0x5d,0xe8,0x45,0x32,0x74,0xd3,0xd2,0xf,0x60,0x56,0x15,0xe7,0x37,0x42,0xad,0xd6,0xb6,0x5a,0x37,0x5b,0x22,0x6d,0x7e,0x9c,0xcd,0x66,0x2b,0x39,0xb7,0x5,0x1d,0x56,0xc9,0x55,0x66,0x41,0xd5,0x46,0x28,0xe5,0x1c,0x72,0x1a,0x10,0x42,0x98,0x2a,0xf9,0x9c,0x93,0x79,0x84,0x35,0x4b,0x6b,0xf0,0x6c,0x91,0x47,0x2d,0x45,0x82,0xc3,0x10,0xa4,0xfd,0x57,0x67,0xf,0xb6,0xca,0xaf,0x56,0xf9,0xe7,0x11,0x62,0xc4,0x3c,0xac,0x9,0xb1,0x93,0x0,0x32,0x58,0x55,0x99,0xce,0x3a,0x74,0x5e,0x83,0x28,0xf9,0xb8,0x92,0x8b,0xce,0x3c,0xb4,0x96,0x56,0x9,0x82,0x5a,0x35,0xdf,0xac,0x2a,0xcc,0xfe,0xb7,0xd9,0x56,0xc,0x58,0x20,0x38,0xf,0x49,0xed,0x1c,0x60,0xd6,0x7e,0xda,0xaa,0xe9,0x30,0xaf,0xba,0x73,0x53,0xf8,0xa8,0x65,0x8d,0xa5,0x6c,0xb6,0xbb,0x5a,0xa0,0x66,0xa1,0xe2,0x66,0xb0,0xb5,0xb9,0x24,0x64,0xaa,0xf2,0xb3,0x4a,0xcc,0xa0,0xa1,0x9e,0x86,0x62,0x5e,0x1f,0xc1,0xac,0xc2,0xd0,0x8e,0xab,0x58,0x65,0x66,0xbb,0xe,0xda,0x45,0x82,0x8d,0x6a,0x3b,0x4c,0x73,0xfb,0xe6,0x6f,0xab,0x7,0xd6,0x2c,0x17,0x9d,0xc9,0x67,0xe7,0xb5,0xe4,0xb4,0x19,0x3e,0xb6,0x30,0x6e,0xbe,0x19,0x5a,0x63,0x56,0xd,0x70,0x5b,0xab,0x76,0xb,0x25,0x37,0x2b,0xf5,0xa6,0x2a,0x45,0x77,0x28,0xc,0x9c,0xdd,0xd1,0xa1,0x30,0xd4,0xcd,0xcf,0x57,0x9d,0x9e,0xe7,0x59,0x3f,0x73,0xab,0xa,0xdd,0x64,0x7f,0x2f,0x66,0x8f,0xf5,0xc0,0x92,0x91,0x79,0x1b,0x30,0x3c,0x47,0x13,0x13,0x11,0x11,0x11,0x11,0x5d,0x92,0xef,0x6d,0x79,0xa,0x88,0x88,0x8e,0x57,0xf2,0xa8,0x55,0x72,0xf2,0xe7,0x5a,0xb5,0x65,0xb3,0x6d,0xc1,0xf5,0x9a,0xfb,0x4d,0x55,0x50,0xd6,0xea,0xda,0x96,0x2a,0x68,0x65,0x96,0x73,0x80,0xf,0xb1,0x7d,0xcc,0xbc,0x2,0xb,0x90,0x80,0xce,0xda,0x67,0x43,0xd7,0xb5,0xc0,0x66,0xe3,0x45,0xdb,0x7,0x84,0xae,0xd3,0xc0,0xe,0xad,0x72,0x2c,0xc6,0xbe,0xdd,0x66,0xd1,0xb9,0x81,0xf3,0xb6,0x5b,0xab,0x1e,0x9c,0xb7,0xa9,0xce,0x97,0x53,0x94,0x9c,0x0,0x7,0xe4,0x24,0xed,0xac,0x3e,0x4,0xa9,0x56,0x9c,0xcd,0x10,0x6c,0x33,0xeb,0x30,0xf,0x6d,0xaa,0x8e,0x74,0xd3,0x4a,0x3e,0x1f,0x5a,0xa5,0x19,0x5a,0x20,0x38,0x6d,0x4b,0xb6,0x70,0x6a,0xa,0xdf,0xea,0x6c,0x61,0xc7,0x34,0xb,0x6e,0x5e,0x81,0x27,0x1,0x9c,0x9e,0x53,0xef,0x5a,0xf5,0x62,0xc9,0xa5,0x7d,0xbe,0x5,0x7d,0xf3,0xb6,0xe0,0xd6,0x8e,0x6c,0x55,0x98,0xe5,0xa8,0x19,0x73,0x6e,0x23,0xd4,0xad,0x55,0x97,0x52,0xd4,0x59,0xb0,0xb6,0xf1,0xe1,0x53,0x25,0xa4,0x5d,0x14,0x12,0x2,0xfa,0xf6,0x78,0xf,0x85,0x8c,0x3e,0x60,0xaa,0xee,0x73,0x6d,0x96,0x9f,0x85,0xa7,0x75,0xb6,0x60,0x65,0xfe,0xb8,0xa7,0xd0,0x57,0xcf,0xb9,0x2e,0x74,0xb1,0x6b,0xb,0xb3,0x76,0x63,0x7b,0x4e,0xa6,0x50,0x6f,0xde,0x12,0xec,0xda,0xef,0x51,0xcb,0x46,0x6b,0xf0,0xfc,0x3a,0x9d,0x82,0xc1,0x72,0x38,0x60,0x4,0x5a,0xa5,0xeb,0x74,0x78,0x6e,0x5a,0xeb,0x6b,0x8b,0x45,0xdc,0x81,0xc0,0x6f,0x56,0x2d,0xd9,0xde,0x6e,0x95,0x9e,0xf3,0xd0,0xb1,0x55,0x6c,0x6,0xbe,0xe8,0x10,0x11,0x11,0x11,0x11,0x5d,0x2,0xc,0x0,0x89,0x88,0x2e,0xf4,0x22,0xd9,0x96,0x80,0x60,0x63,0x3,0xab,0xb5,0xb1,0x3a,0xa0,0xb5,0xc7,0x5a,0xbb,0xae,0x5,0x6f,0x4e,0x2b,0xc9,0x0,0xe8,0xcc,0x35,0xb4,0x59,0x77,0x16,0xb8,0xcc,0x17,0x30,0xd4,0xd9,0xb2,0x10,0xab,0x3a,0x74,0xce,0x23,0x84,0x6e,0xa3,0xda,0x30,0xc6,0xae,0x85,0x62,0xa5,0xc8,0x9f,0xad,0x12,0x6d,0x6a,0x1f,0xe,0xb2,0x20,0x64,0xb6,0x7c,0xc2,0x42,0x30,0xe7,0x82,0x6,0x5d,0x75,0xa3,0xf2,0xad,0x96,0x8a,0x10,0x3b,0x0,0x52,0xa9,0x38,0xcd,0xd2,0x73,0x87,0x42,0x1f,0x5b,0x2a,0x21,0x5b,0x87,0xd1,0x7a,0x8f,0x25,0x48,0x9c,0x82,0x2c,0x99,0x53,0xa7,0xf5,0x82,0xfa,0x78,0xe7,0x5b,0x94,0xed,0x31,0xb6,0xcc,0x6c,0x63,0xc6,0xdc,0xe6,0x9c,0x44,0xa7,0x81,0xa4,0xf3,0x16,0xa2,0x59,0x4b,0xf5,0xc6,0x42,0x5e,0x48,0x55,0xa0,0x56,0xb0,0x95,0x69,0xb1,0x9,0x30,0x5f,0xa4,0x61,0xdb,0x79,0xe5,0xf9,0xf0,0xde,0xcf,0x82,0xc7,0xd9,0xdc,0x42,0xe7,0xe,0xb5,0x13,0x5b,0xb5,0xa5,0x5,0xa9,0x72,0xee,0x72,0xdb,0xd6,0x3b,0x5f,0xa0,0xa2,0x8f,0x64,0xe3,0x9a,0xa,0x21,0xb4,0xc0,0x51,0xae,0xb1,0xd0,0xaa,0xd,0xe7,0x8b,0x53,0xe,0xb6,0xe1,0xda,0x73,0x38,0x3f,0x26,0xa0,0xb6,0x6d,0xcf,0xb6,0x98,0x65,0xbe,0x58,0xc4,0x9e,0x97,0x10,0xc2,0xf4,0x5c,0x61,0x33,0xf4,0x83,0x6,0xd2,0x55,0xc3,0xb9,0x56,0x49,0xd9,0x96,0xb4,0xb8,0xd6,0x7e,0xdc,0x2,0xbd,0xf9,0xf3,0x63,0xb,0x6f,0x5a,0x88,0xe8,0x67,0xc1,0xa0,0xbd,0xab,0xa0,0x1e,0x3a,0x13,0xb5,0x2d,0x38,0x9e,0x8e,0x29,0xf1,0x45,0x87,0x88,0x88,0x88,0x88,0xe8,0x52,0x7c,0x6f,0xcb,0x53,0x40,0x44,0x74,0x61,0x1b,0xa1,0x10,0xa6,0xcd,0xb5,0xad,0xdd,0x57,0x43,0x1f,0xfb,0x65,0x41,0x55,0x9b,0xd1,0x6,0xe8,0xfc,0x3d,0x9,0x59,0x2c,0xd0,0xf3,0x3e,0x20,0x84,0x20,0x81,0x9e,0xb5,0xda,0x3a,0x6c,0x6,0x51,0xde,0x21,0x97,0x24,0x61,0x9e,0xde,0x9f,0x2c,0xfe,0xd0,0xcd,0xbf,0x5e,0xb6,0xfd,0xc6,0xae,0x9f,0xb5,0x23,0x6b,0xab,0xaf,0xf7,0x6d,0x99,0x85,0xd7,0xb6,0xe3,0xd8,0x75,0x98,0x62,0x98,0x3a,0xb5,0x15,0x5b,0x6b,0xf2,0xac,0xfa,0x6d,0xfe,0x98,0xa7,0xe0,0x6d,0xb6,0x9d,0x17,0x52,0xb5,0xd8,0x36,0x16,0x5b,0x68,0x75,0x60,0x21,0xc4,0x7c,0x71,0x4,0xdc,0xd4,0x21,0x3b,0x1b,0xbf,0xb7,0xf1,0xf1,0x7e,0x1e,0x9c,0xa2,0xea,0x31,0x95,0x16,0xba,0xa1,0x1e,0xdd,0xf2,0x2b,0x81,0x64,0xdd,0x78,0x7c,0x9b,0x2d,0xc1,0x53,0xfb,0x6c,0x5,0x36,0x42,0xca,0x52,0xa6,0xd9,0x7c,0xad,0xa,0x2e,0xcc,0x96,0x73,0x78,0x3f,0xab,0x32,0xf4,0x1b,0x95,0x99,0xb2,0x81,0x39,0xb6,0x0,0xae,0x55,0x0,0xce,0x2b,0x1,0xeb,0xb4,0x64,0x25,0xe7,0x3c,0xcd,0x7d,0xf4,0x9b,0xe1,0xe4,0xbc,0x32,0xd4,0x8e,0xbf,0xd4,0xd2,0x16,0x99,0x58,0x8b,0x72,0x99,0x85,0x8c,0x55,0x37,0x40,0x6f,0xb4,0xd4,0x1e,0xa8,0xb0,0xdb,0x9c,0xd3,0x87,0x8d,0xd9,0x94,0xed,0xda,0x9d,0xcd,0x9,0xf4,0xb3,0xe7,0x55,0x3f,0x71,0xe3,0x69,0x6a,0x6d,0xd9,0x15,0xad,0x82,0xd1,0x3e,0xb6,0xb4,0xd9,0x84,0xf2,0x84,0xcf,0x9f,0x91,0x29,0xe7,0xad,0xf3,0x2,0x43,0xb9,0x3d,0xbf,0xb9,0x7d,0x99,0x88,0x88,0x88,0x88,0x88,0x2e,0x1e,0x6,0x80,0x44,0x44,0xaf,0xf4,0x42,0x69,0x95,0x7d,0x5a,0xf1,0x67,0xd5,0x68,0xd6,0xca,0x2b,0x55,0x4c,0x6e,0xfa,0xb3,0x86,0x29,0xde,0x79,0xd4,0x92,0x25,0xc0,0x9a,0x85,0x5b,0x36,0x3f,0x2d,0xe7,0x4,0xb,0x48,0x5a,0x3b,0x26,0x1c,0x42,0x8,0xad,0x82,0xaf,0x55,0x65,0xc9,0x3b,0xe1,0xbc,0x9f,0xb6,0xfb,0x6,0x5d,0xca,0x11,0xa2,0x2c,0x8d,0x8,0x41,0x16,0xc6,0x6a,0x88,0x97,0xd2,0x8,0xc0,0x5a,0x61,0x63,0xab,0x8,0x74,0x2d,0x88,0x8c,0xed,0x98,0xda,0xc6,0x5d,0x4c,0x21,0x57,0x88,0x51,0x82,0xa6,0x59,0x35,0x9a,0xdc,0x20,0xa6,0xcd,0xc2,0xed,0x1c,0x85,0x8d,0xcf,0xb5,0xb0,0x53,0x4f,0x8d,0x7c,0x5a,0x9b,0x53,0xe7,0xe1,0x9d,0x47,0x29,0xd6,0x26,0x5c,0x37,0x16,0x6a,0x60,0x16,0xec,0xd5,0x8d,0xfb,0x76,0xb3,0x5f,0xb3,0xca,0x40,0x5b,0xae,0x61,0x2d,0xcf,0xb3,0x16,0x6b,0x1c,0x58,0x4c,0x61,0x8f,0xbd,0x5,0x79,0x7e,0x5a,0x24,0x62,0xb,0x53,0xda,0xac,0xbd,0xb6,0x99,0x17,0x2d,0x1c,0x6b,0xdb,0x76,0x31,0xf,0x39,0x6b,0x3b,0xe7,0xf3,0xf0,0x16,0xda,0x8e,0xdb,0xc2,0xb8,0x16,0x32,0x4e,0xc7,0xde,0x2a,0x3d,0xbd,0x87,0xf7,0xf3,0x96,0xf0,0xe9,0x97,0x2d,0x41,0x81,0x6e,0x89,0xce,0x5a,0xed,0xe9,0xbc,0x5,0x74,0xae,0xcd,0x94,0x9c,0xcf,0x4a,0x9c,0x3f,0x1f,0x53,0xcb,0xef,0xec,0x5c,0x1c,0xbb,0xdd,0x5a,0xe7,0x52,0xfa,0x69,0x8e,0x60,0xc9,0x59,0xb7,0x3e,0xa3,0x2d,0xaf,0x99,0x57,0x10,0x1e,0x79,0x7b,0xf5,0xe0,0xec,0xc4,0xc3,0xb,0x55,0xa6,0xf6,0xf1,0x3,0x41,0x31,0x11,0x11,0x11,0x11,0x11,0x5d,0xdc,0xef,0x6b,0x79,0xa,0x88,0x88,0x8e,0x57,0xb2,0x84,0x68,0xd6,0x9a,0x9,0x5d,0x76,0x51,0x72,0x6e,0xf3,0xea,0x5a,0x68,0x33,0xab,0x4e,0xb,0x21,0xea,0xbc,0x40,0xdf,0x36,0xbe,0x5a,0x8,0x62,0x2d,0x95,0x56,0x8d,0x57,0x2d,0xd0,0x71,0x5e,0x17,0x74,0xc8,0x3c,0xbf,0x10,0x2,0xbc,0xf3,0x88,0x5d,0x27,0xc1,0x5f,0x9c,0x5a,0x81,0xa7,0xc5,0x1c,0x52,0x7d,0x28,0x95,0x84,0x3d,0x9c,0x73,0xe8,0xfa,0x85,0xb4,0x2,0x6b,0x50,0x63,0xd5,0x7f,0xd3,0x76,0xdd,0xda,0x2a,0xd0,0x20,0x6f,0x6d,0xb7,0xd7,0x42,0x30,0x0,0x49,0x37,0x20,0x5b,0xe8,0x3,0x40,0xab,0xd1,0xb4,0x72,0xc,0x68,0x95,0x77,0x25,0x27,0x3d,0x4d,0xa5,0xb5,0x8,0xdb,0xfc,0xc1,0xf6,0x5,0xc7,0x87,0x36,0x63,0x6f,0x33,0xac,0x42,0x7b,0xbb,0xcc,0xf6,0x4b,0xb3,0xe0,0xc8,0xeb,0x9c,0x41,0x3f,0x9b,0x27,0x58,0xdb,0xc7,0x6f,0x2e,0x63,0x99,0xb5,0xd1,0x96,0xcd,0x6a,0xc4,0x79,0x28,0xe7,0xac,0x75,0x59,0x67,0xd2,0x59,0x5b,0x70,0xdb,0x10,0x5c,0x8a,0x3e,0x17,0x71,0xda,0xa0,0xbc,0x31,0xb3,0x51,0xaf,0x8d,0x3,0xad,0xbe,0x61,0x36,0xdf,0xd1,0xda,0xaa,0xa7,0xb6,0x6b,0x7,0x1f,0xe3,0x34,0x73,0xb1,0xc8,0x12,0x17,0xab,0x2c,0xb4,0xe7,0xd2,0xf9,0xa9,0x9d,0xd7,0x5a,0xb0,0x5b,0xeb,0x79,0x29,0x1b,0xad,0xc7,0xd6,0x32,0xed,0xf5,0x5a,0x71,0xd6,0x66,0x5e,0xa,0xbc,0x9f,0xb7,0x22,0xcf,0x5a,0x7d,0x67,0xbf,0xac,0x6d,0xdc,0xde,0x3f,0x5f,0xe8,0x62,0xe7,0x6c,0xde,0xa2,0xe,0x27,0xe1,0xf4,0x7c,0x26,0x24,0xdc,0xe6,0x26,0xe0,0xb6,0xc4,0x6,0xb3,0x5,0x38,0xed,0xef,0x4f,0x7b,0xb6,0xdb,0x7e,0xe5,0xf9,0x2c,0x49,0xdb,0x96,0x4c,0x44,0x44,0x44,0x44,0x44,0x17,0x1f,0x3,0x40,0x22,0xa2,0xb,0xbd,0x48,0x6,0x6d,0x99,0x9d,0xb7,0x4e,0xda,0x4c,0x34,0xd,0xd0,0x5a,0x38,0x38,0x6b,0xbd,0xac,0x98,0x6,0xd3,0x79,0xef,0xb5,0xc2,0x4b,0xe6,0xe1,0x79,0xef,0xd1,0xf5,0xb,0xe4,0x94,0xa7,0xa0,0xa9,0x55,0x54,0xf9,0x59,0x40,0x53,0x66,0xd5,0x70,0x92,0xf7,0xd8,0x8c,0x3f,0xe8,0x82,0xb,0xd9,0x10,0xc,0xfd,0x38,0x9,0x6b,0xd2,0x38,0xb6,0x10,0xd2,0x87,0x88,0x10,0x7b,0x8c,0xc3,0x7a,0x16,0xc8,0x4c,0x15,0x70,0x36,0x8f,0x4e,0x82,0x3b,0x87,0x9c,0x46,0x78,0x1f,0xf5,0x78,0xa7,0xf0,0xad,0xb4,0x19,0x77,0xd2,0x66,0x6b,0x8f,0x57,0xde,0x3e,0x2d,0x9b,0xf0,0x21,0xb6,0x4a,0x3f,0x9,0x9,0xab,0x2e,0xb3,0x8,0x68,0xad,0xba,0x40,0xb,0xf3,0xec,0x3e,0xc4,0x34,0x6f,0x4e,0x4f,0xab,0x3c,0x7,0x6d,0x16,0x9e,0x54,0x5b,0x86,0x56,0xcd,0x68,0xb3,0xe5,0xa6,0xed,0xbd,0x56,0x29,0x7,0x4c,0x4b,0x55,0xe6,0x36,0x82,0x4b,0x4c,0xa1,0xe1,0x3c,0x64,0xb4,0xe7,0x22,0xa7,0xb1,0x1d,0x44,0xd9,0xd8,0x70,0x2b,0xb7,0x2f,0x15,0x94,0xb5,0x85,0x7e,0x39,0xa7,0x8d,0xa,0x43,0xd9,0xc4,0x7c,0x78,0x8e,0xa0,0x3d,0x96,0x52,0xb,0x7c,0xb,0xde,0xa6,0xe3,0x93,0xd,0xcd,0x3a,0x7b,0x51,0x5b,0x94,0x37,0x36,0x3a,0xd7,0xa9,0xad,0xdb,0x36,0x37,0x5b,0xd0,0x1c,0xa2,0x5c,0xf,0x65,0xb6,0x71,0xb9,0xcc,0xc2,0x4e,0x69,0xd,0xf,0xb3,0x65,0x2c,0x53,0x4b,0xbb,0xb5,0x26,0xcb,0xf1,0x6d,0x2e,0x93,0xf1,0xad,0x42,0x74,0x3a,0x5e,0xfb,0x98,0xf9,0x42,0x91,0x5a,0xe7,0xd7,0xc6,0xe6,0xfb,0x5a,0x4d,0xa3,0x85,0x91,0xd3,0x6e,0xe1,0xf6,0x5c,0xfa,0xb0,0xe0,0x8b,0xe,0x11,0x11,0x11,0x11,0xd1,0xa5,0xf8,0xde,0x96,0xa7,0x80,0x88,0xe8,0x78,0x25,0x8f,0x5a,0xa1,0x55,0x37,0x66,0xbb,0xb5,0xd6,0xca,0x52,0x35,0x3c,0x72,0x1a,0x36,0x69,0x3b,0xab,0x6d,0xfe,0xf5,0x7e,0x63,0x79,0x3,0x30,0x2d,0x59,0x88,0x9d,0x54,0xe9,0x75,0xfd,0xa2,0xfd,0x57,0xda,0x52,0x9d,0x56,0x93,0x49,0xbb,0x6f,0xd1,0x8a,0x34,0x9b,0xb9,0xa6,0x3,0xd3,0x66,0xc1,0xcf,0x66,0x3b,0x66,0x88,0xb1,0x55,0xc8,0xf5,0x8b,0x25,0x4a,0x4e,0xe8,0x17,0x4b,0x38,0xe7,0xd1,0x75,0x7d,0x6b,0x2d,0x76,0xce,0xa1,0xe4,0xd2,0xaa,0xc9,0xa4,0x92,0x2c,0xce,0x36,0xd9,0x3a,0xd,0x80,0x66,0x95,0x67,0xb3,0x8a,0x32,0xe7,0xb4,0xd,0xd8,0x79,0xdd,0x0,0x2c,0x81,0x67,0x8,0xb1,0x85,0x94,0xf3,0xa5,0x12,0x56,0x51,0xd7,0xce,0x89,0x55,0x9c,0x1d,0x5a,0x98,0xb1,0xd9,0x52,0x3a,0x2d,0xb8,0xb0,0xb6,0xea,0x82,0x32,0xb,0xab,0x50,0xa5,0x9d,0xda,0x76,0xd5,0x6,0xbd,0x1f,0x5b,0x64,0x22,0xb3,0xf3,0x5c,0x9b,0xe1,0x7,0x9b,0x95,0xa8,0xa1,0x96,0x55,0x44,0xd6,0x59,0xc0,0x67,0xf3,0xf6,0xa4,0xfa,0x31,0xea,0x57,0x4c,0x3f,0x9b,0xd1,0xe7,0x5b,0x9b,0x6c,0x6b,0xd3,0xd6,0x2a,0x4a,0xaf,0xcf,0x95,0x9f,0xb5,0xd0,0x2,0xd8,0xbc,0x7d,0xad,0xbe,0x3b,0xb4,0x2d,0xd9,0x96,0xc4,0x6c,0x6c,0xfb,0xd5,0xbb,0xf,0xa1,0x5,0x9a,0xf3,0x56,0xe3,0x9c,0x52,0xdb,0xfc,0x9b,0x53,0x6a,0xc7,0x18,0x63,0xb7,0x71,0xed,0xcd,0xcf,0xe7,0xc6,0xa6,0x65,0x77,0xc4,0x3f,0x5,0xdc,0x14,0x3c,0xda,0x6c,0x48,0x99,0x3d,0x98,0xa7,0x5,0x2b,0xd6,0x4a,0xdd,0x1e,0xdb,0x34,0x1f,0xb2,0xa2,0xc2,0xb7,0x39,0x86,0xa5,0xed,0x12,0xb6,0x3d,0x2f,0x16,0x56,0x4f,0xcb,0x45,0xa6,0x6a,0x4f,0x22,0x22,0x22,0x22,0x22,0xba,0xf8,0x18,0x0,0x12,0x11,0xbd,0x1a,0xe,0x7,0xda,0x19,0x25,0xd2,0x90,0xd6,0x4b,0x5d,0xa4,0x91,0x52,0xb,0xbc,0x4a,0xb2,0x96,0xd8,0x2a,0x4b,0x3a,0x62,0xd7,0xaa,0xea,0x0,0xb4,0x80,0xc7,0xfb,0x80,0x9c,0x46,0xdd,0xd0,0xaa,0xf3,0xe4,0xb2,0x4,0x34,0xfd,0x62,0xa9,0xed,0x9c,0x1,0xde,0x66,0xff,0x1,0x8,0x5d,0x87,0xae,0x5f,0x0,0x70,0x8,0x5e,0xaa,0xe1,0x24,0x3c,0x74,0xe8,0x17,0x4b,0x69,0x1,0xe,0x11,0x8b,0xe5,0x9,0xa4,0x71,0x90,0x4a,0x41,0xad,0x1c,0xb4,0x63,0xb0,0x2a,0xba,0xd6,0xae,0x1a,0x82,0xe5,0x75,0x1b,0x15,0x63,0x39,0x8d,0x12,0x10,0xcd,0xb6,0x19,0xcf,0x17,0x42,0x38,0x9d,0x73,0xd8,0x6,0xbc,0xb9,0xa9,0xf2,0x4f,0xee,0xcf,0xb5,0xf6,0xe3,0x92,0x33,0x6a,0xd1,0x10,0xf,0xd3,0xfc,0x3b,0x9,0x89,0x70,0xa8,0xfa,0xcc,0xe9,0xd2,0xc,0xa7,0xcb,0x3d,0xa6,0xe0,0xaa,0x6c,0xb4,0x42,0x5b,0x10,0x6a,0x8b,0x4a,0xac,0x1d,0x39,0xe8,0x4c,0xc4,0xf9,0xa6,0xe0,0x79,0x1b,0x6c,0xd5,0xe5,0x1d,0x5e,0x3f,0x77,0xaa,0xe6,0xb3,0xa0,0x2c,0x6b,0xfb,0xb4,0xdc,0x9e,0xd7,0xc0,0xb3,0xd4,0xb2,0xf1,0xf8,0x2d,0x28,0xab,0xb3,0x63,0x46,0xab,0xb0,0x94,0xb9,0x8b,0x21,0xc6,0xd9,0x9c,0x43,0xb,0xb,0xa7,0xad,0xcf,0x16,0xf8,0x2,0x3a,0x6f,0x6f,0x16,0xc0,0x59,0xd5,0x5d,0x29,0x53,0xc5,0x60,0x8,0xb1,0xcd,0x37,0x9c,0xcf,0x97,0xd4,0x4b,0xb5,0x55,0x6d,0x4e,0x6d,0xd2,0xbe,0x2d,0x8d,0x99,0xb7,0x3,0xcf,0xab,0x3f,0x6d,0x6e,0x63,0xab,0x66,0x45,0x6d,0xc1,0x9c,0x73,0x52,0xe1,0x88,0x8d,0xed,0xc4,0xf6,0xec,0xa1,0xb5,0xf,0x4f,0xef,0x98,0xaa,0x2a,0xad,0x18,0xd6,0x2a,0x67,0x6d,0xb2,0x61,0x9d,0x2d,0x69,0xd1,0xab,0x0,0x98,0x9d,0x5b,0x22,0x22,0x22,0x22,0x22,0xba,0x78,0x18,0x0,0x12,0x11,0xbd,0x82,0x36,0x5f,0x6e,0xbe,0x44,0xc1,0xcd,0x66,0x9c,0xd5,0x69,0x86,0x9a,0xcd,0xa7,0x9b,0x87,0x6e,0xde,0x7,0x59,0xe0,0x50,0xa,0x42,0xb4,0xb6,0xdc,0x69,0x9e,0x9f,0xf3,0x1e,0xb1,0x5f,0x20,0xc6,0xe,0x5d,0xbf,0x6c,0x61,0x5f,0xc9,0x9,0xb1,0xeb,0x64,0xbe,0x9f,0x86,0x7f,0x36,0xd7,0xcf,0x39,0x87,0xae,0xd3,0x59,0x81,0xda,0xfa,0x1a,0xbb,0x45,0xab,0x78,0xb3,0x4a,0xbe,0x10,0xbb,0x36,0x3b,0xd0,0x66,0x1,0xda,0xec,0x37,0xb,0x23,0xa5,0x62,0x2f,0xc0,0x7b,0xd7,0xc2,0x46,0x7b,0xdc,0x21,0xc4,0x36,0x8b,0x10,0xe,0xf0,0x36,0x7f,0xce,0xa1,0x85,0x52,0x56,0x9,0xd8,0xb6,0x1e,0x5b,0xeb,0x73,0x88,0xa8,0xa5,0x22,0xc6,0xe,0xb6,0x15,0xb6,0xb5,0x5,0x5b,0x5,0xe2,0x6c,0x4e,0x9d,0x9c,0x8b,0xd0,0x5a,0x7a,0x8b,0xcd,0xf1,0x6b,0x2d,0xb7,0x72,0x1e,0xad,0x62,0xcf,0xde,0x57,0x67,0xf3,0xf4,0xac,0xf5,0x18,0x0,0x72,0xb1,0x5,0x1b,0xa1,0x85,0x9f,0xf2,0xb8,0xd0,0x2,0x3a,0xa9,0x12,0x94,0xf3,0x25,0x9b,0x94,0xa7,0x70,0xd6,0xe6,0xee,0x4d,0x8b,0x34,0x24,0x18,0x8d,0xb3,0x2a,0xc9,0x5a,0x8a,0xcc,0x45,0x6c,0x81,0x1d,0xa6,0xa0,0xcd,0x3b,0x5d,0xf4,0x52,0xdb,0xa6,0xde,0x8d,0xe5,0x28,0x7e,0x6a,0x6d,0xce,0x59,0xaa,0xf8,0x62,0xec,0xe4,0xf9,0xd0,0xf9,0x85,0xad,0xa,0x4f,0x2b,0x3e,0x73,0xce,0xad,0xad,0xda,0x5a,0xd0,0xfd,0xac,0x82,0xcf,0xe6,0x0,0x3a,0xe7,0x10,0x62,0xd7,0x66,0x2d,0x4e,0xf3,0xfe,0xe4,0xda,0xf1,0x1a,0x4e,0xb6,0x8a,0x46,0xcc,0xdb,0x8d,0x35,0x90,0x2b,0x45,0xdb,0x89,0xf3,0xc6,0x75,0x3c,0x6d,0x77,0xc6,0x66,0x5,0xe0,0x6c,0x3b,0xb3,0x3d,0x9f,0x16,0x2e,0xe2,0xc0,0x46,0xe1,0x8d,0xad,0xc4,0x2d,0x7,0x75,0xa8,0x35,0xf3,0x5,0x87,0x88,0x88,0x88,0x88,0xe8,0x12,0x60,0x0,0x48,0x44,0xf4,0x8a,0xea,0x66,0x9b,0xa3,0xfc,0x1,0x80,0xd3,0xa5,0x18,0xbe,0xcd,0xeb,0x8b,0x51,0x82,0xba,0x29,0x8,0xa,0x6d,0x41,0x83,0x55,0x49,0xc9,0xdc,0xbd,0xa9,0xda,0xcc,0x6b,0xb,0x6d,0x29,0xd2,0xb6,0x2b,0x41,0x54,0x6d,0xed,0xbf,0xd6,0x22,0x1c,0x35,0xcc,0x93,0x90,0x68,0x6a,0x7,0xb5,0x56,0x61,0x6b,0x5b,0xf5,0x3e,0xb6,0xaa,0xb2,0x9c,0x46,0xf8,0x18,0xa5,0xc2,0xf,0x40,0x88,0x11,0x31,0xf6,0x1b,0x41,0x62,0xec,0x3a,0xdd,0x62,0x8b,0xa9,0x3a,0x4e,0x67,0xd1,0xcd,0xb7,0x1a,0xd7,0xaa,0x73,0xe2,0xf4,0x1,0xe6,0xb6,0xac,0x43,0x9b,0x6f,0xb5,0x55,0x54,0xaa,0x19,0xd1,0x2,0x4c,0x9b,0x2d,0x67,0x15,0x72,0x53,0x3b,0xb0,0xd7,0x60,0xc9,0xb7,0xb6,0x5d,0xd9,0x2e,0x2c,0xb7,0x69,0xb,0x27,0x5c,0x9b,0x6f,0xe8,0xda,0xec,0xc3,0x6a,0xcb,0x48,0x30,0x55,0x6,0xfa,0xb6,0x28,0x4,0xb3,0x56,0x69,0x48,0xb,0xf3,0x2c,0x70,0xf2,0xb3,0xf6,0x60,0x5b,0xaf,0x5c,0xca,0xbc,0x82,0xcf,0x66,0x8,0xba,0x59,0xc5,0x63,0x6d,0xe1,0x5a,0x4a,0x63,0x9b,0x1d,0x68,0xb3,0x1,0xe7,0x21,0x71,0x88,0x5d,0x5b,0x26,0x12,0x6c,0x93,0x33,0xa4,0x32,0x31,0xe7,0xdc,0xaa,0x2,0xf3,0x38,0xc2,0xc2,0x41,0xdb,0x9c,0x3c,0xb5,0x32,0xa3,0x2d,0xd9,0xb0,0x8a,0x49,0xb,0x11,0xad,0xba,0x6f,0x5a,0x52,0x52,0xe,0xb4,0xf9,0x56,0x3d,0xff,0x53,0x98,0x26,0xd7,0x61,0x94,0xaa,0x40,0xad,0xfa,0x9b,0x57,0xf4,0xd9,0xf9,0xb4,0x60,0xd7,0xae,0xab,0xd6,0x7a,0x8e,0x29,0xc0,0xb6,0xe7,0xc4,0xae,0x63,0x9b,0xe7,0x57,0x31,0x6d,0x41,0x9e,0xaa,0x11,0xa7,0x4a,0xc3,0x79,0xc5,0xa1,0xf3,0x7,0x5a,0xbf,0xad,0x37,0xb8,0x30,0x0,0x24,0x22,0x22,0x22,0x22,0xba,0x14,0x18,0x0,0x12,0x11,0x5d,0xe8,0x45,0x32,0x74,0x6d,0xf9,0x44,0xab,0x46,0xb3,0xb6,0x48,0xa0,0x2d,0x49,0x0,0x70,0x28,0xe8,0xb0,0x4d,0xae,0x45,0xdf,0x6f,0x21,0x17,0x0,0xdd,0x0,0x2c,0x15,0x57,0xdd,0x62,0xd9,0x16,0x7a,0x58,0xa5,0x9f,0x55,0xed,0x85,0xd9,0xbc,0x3e,0x37,0x9b,0xfb,0x67,0x55,0x54,0xf3,0xd6,0x62,0xa7,0x1b,0x83,0xa5,0xfa,0x30,0xb6,0xb9,0x82,0x72,0xdf,0xa1,0xb5,0x99,0x4e,0xb,0x2f,0xaa,0xce,0xb,0xd4,0xda,0x2c,0x87,0x56,0x6d,0x36,0xdf,0xac,0xb,0x40,0xe7,0x12,0x4a,0x55,0x23,0xa0,0xd5,0x5f,0x3a,0x5f,0xe,0xb6,0x4c,0xa4,0xd4,0xf6,0x18,0xed,0xed,0x25,0xe7,0x56,0x29,0x28,0xd5,0x67,0x5a,0xa5,0x57,0x36,0x5b,0x3d,0x73,0x4e,0xa8,0xa5,0x68,0xb8,0x56,0x66,0x6d,0xa6,0x9b,0x5b,0x6b,0x2d,0xf4,0x94,0xf3,0x2e,0xad,0xc1,0x56,0x49,0x57,0xb4,0xda,0xcc,0xfe,0xec,0x43,0x68,0xf7,0x63,0xcf,0x8b,0x6d,0x6f,0x8e,0xd6,0x12,0xad,0xd5,0x8c,0x6d,0x99,0x48,0x88,0xad,0x1a,0x2d,0xf8,0xa0,0x79,0xaf,0x9b,0x55,0xcf,0xa1,0x2d,0x6e,0xb1,0x6d,0xbb,0xad,0xa2,0x53,0xe7,0x1b,0xca,0x22,0x15,0xad,0x4e,0x9c,0x5,0xc4,0xad,0x8a,0x50,0x8f,0xc7,0xc7,0xd8,0x96,0x91,0xb8,0xd9,0x5c,0x49,0xa7,0x55,0x94,0x52,0x61,0x5a,0x5a,0x65,0x63,0xbf,0xd8,0x99,0x96,0xbb,0xb4,0xd9,0x7e,0xbe,0x2d,0xf5,0x8,0x71,0x6a,0x23,0xb6,0xa,0x3c,0x9b,0x1b,0x58,0x51,0x65,0xab,0x33,0x24,0x50,0xcc,0x16,0x80,0xb6,0x79,0x87,0x53,0x35,0xeb,0xb4,0x5,0xd9,0xb7,0xe0,0x55,0xb6,0x16,0x6b,0x20,0xb,0x9,0xb7,0xf3,0x6c,0xf3,0x73,0xd5,0x76,0x61,0xab,0x5e,0x9c,0x57,0x39,0xd6,0xd9,0xcc,0x40,0x3d,0xb4,0x36,0x27,0x70,0xbe,0xe0,0x6,0x70,0x70,0xa1,0xe7,0x8b,0xe,0x11,0x11,0x11,0x11,0xd1,0x25,0x10,0x79,0xa,0x88,0x88,0x8e,0x57,0xf2,0xd8,0xb6,0xda,0xda,0x3e,0x6,0x17,0x2,0x4a,0x4e,0x70,0x3e,0xa2,0xe4,0x24,0xa1,0x51,0x6b,0x69,0x95,0xb9,0x74,0xfd,0xa2,0xd7,0xa,0x39,0x5b,0x78,0x21,0x41,0x4b,0xec,0x16,0xa8,0x59,0x5a,0x73,0xbb,0x6e,0x61,0xdd,0xaf,0x12,0xe2,0x41,0x82,0xc6,0xae,0x5f,0x4c,0xb3,0xf9,0xb4,0x22,0xca,0xaa,0xaf,0xa4,0xbd,0x38,0x4a,0xb0,0xa6,0x1,0x57,0x17,0x3c,0x72,0x4a,0xe8,0x97,0x4b,0xe4,0x71,0x44,0x8c,0x9d,0x6e,0x9d,0x95,0x2a,0xb1,0x52,0xb2,0x4,0x3e,0xda,0xd2,0xe9,0x9d,0x1c,0xbf,0xf7,0xa1,0x1d,0x63,0xec,0xfa,0xd6,0xce,0xa,0xa0,0xb5,0x16,0x5b,0x65,0xa0,0x55,0xcd,0x79,0x1f,0x50,0x50,0xe1,0x31,0x9f,0xd5,0xe7,0x36,0x82,0x36,0xbb,0x5d,0x9,0xaf,0x42,0xdb,0xfc,0x6a,0xb7,0x25,0x15,0x72,0xa5,0x85,0x40,0xb6,0xb8,0xc3,0x87,0xd0,0xb6,0xd,0x97,0x92,0xe1,0x7c,0xdc,0xd8,0x34,0xb,0xe8,0xc6,0x58,0x7,0xd,0x9f,0x5c,0xb,0xa5,0xa0,0xc1,0x5c,0xc9,0xd3,0x12,0xc,0x3b,0x47,0x76,0xdc,0x16,0x88,0xb5,0xe5,0x1b,0xe,0xba,0x8c,0xc3,0xeb,0x22,0xc,0xa7,0xcf,0x67,0x68,0x73,0xf8,0xd0,0xb6,0x20,0x4b,0xf5,0x5d,0xcd,0xb3,0x80,0xd7,0x36,0x36,0x6b,0xe5,0xa3,0x9e,0x0,0x69,0xbd,0xad,0x53,0x9b,0x6c,0x8,0x1,0x5,0x59,0x2a,0x1c,0xe1,0x5b,0x65,0x20,0x0,0xdd,0x4,0x2c,0xed,0xc9,0x25,0x27,0x94,0x22,0xcb,0x61,0xda,0x39,0x75,0xd3,0xa6,0x5f,0xbb,0x8f,0x9c,0x47,0xad,0x6e,0x94,0xd0,0x30,0x74,0xbd,0xcc,0x6a,0x84,0x54,0x78,0x96,0x21,0x6b,0xfb,0x76,0x40,0x1a,0x47,0xe4,0x3a,0xb6,0x79,0x84,0x45,0xe7,0x35,0x86,0xd8,0x4d,0x55,0xad,0x4e,0x2,0x59,0x2b,0x6c,0x75,0x36,0xbb,0x31,0xa5,0x8d,0x56,0x63,0x0,0x1b,0xcb,0x49,0xec,0x9c,0x3a,0xe8,0xf1,0x3,0x6d,0x9,0x89,0x9d,0x1f,0xbb,0x3e,0xd0,0x96,0xaf,0x60,0x36,0x3c,0x70,0x73,0x6,0x60,0xa9,0x5,0xb5,0x8c,0x7c,0xd1,0x21,0x22,0x22,0x22,0x22,0xba,0x4,0x18,0x0,0x12,0x11,0xbd,0x82,0x69,0x26,0xda,0x7c,0x41,0xc2,0x34,0xe7,0xce,0x36,0xdf,0x4e,0x9b,0x5c,0x2b,0xd2,0x38,0x20,0xc6,0x7e,0x9a,0x9,0x88,0x28,0xad,0xb8,0xce,0x23,0xbb,0xa2,0xad,0x98,0x49,0x82,0x37,0x48,0x25,0x9f,0xb5,0x7e,0x96,0x92,0x5b,0xc0,0xe6,0x82,0x84,0x60,0x1,0xb6,0x38,0x41,0x32,0x43,0xdf,0x49,0x15,0x57,0x88,0x11,0x39,0x25,0x2c,0x77,0x4e,0x20,0xe7,0x4,0x1f,0x23,0x62,0xec,0x30,0xae,0xd7,0x12,0x2a,0x5a,0x5b,0x68,0x5,0x5c,0x8c,0x28,0x29,0xb7,0x30,0x72,0x3a,0x66,0xa0,0x14,0x6b,0x37,0xd,0xa8,0x25,0xb7,0xe5,0x25,0xed,0xb1,0xb7,0xc,0x48,0x2,0xce,0x62,0xc7,0xa9,0x6d,0xa0,0xa5,0x96,0x56,0x4d,0x68,0x55,0x7e,0x5d,0xd7,0xb7,0x8a,0x3b,0xe7,0xbd,0x1c,0xbd,0x6,0xa5,0xd5,0xc9,0xec,0xba,0x94,0x46,0x4d,0x55,0x81,0x5a,0x5c,0xb,0xb6,0x42,0xec,0x50,0xf4,0xfe,0xe5,0x71,0xc8,0x3c,0x41,0x3b,0x26,0x6b,0x31,0x85,0xb6,0x51,0x3b,0x6d,0xc7,0x6e,0x95,0x77,0xa8,0xf0,0x41,0x8f,0xa3,0x97,0xd9,0x88,0x36,0xef,0xaf,0x6a,0x25,0x9f,0xf,0x11,0x2e,0x44,0xa4,0x71,0x44,0x8,0xa1,0xb5,0x34,0x4b,0x68,0x8b,0xd9,0xc,0xbe,0xe9,0x79,0xb7,0xca,0xbb,0x79,0xb0,0x55,0x66,0x21,0xad,0x83,0xb4,0xdb,0x4e,0x41,0x71,0x6e,0xe1,0xe4,0x7c,0xe9,0xc8,0x38,0xac,0x25,0x8c,0xac,0xe,0xb9,0x64,0x44,0x1f,0xb4,0xa5,0x57,0x8e,0xb3,0x5f,0xee,0x48,0x98,0xa6,0xe7,0xbb,0xea,0x6c,0x43,0xa9,0xa6,0x44,0xab,0xfa,0xb4,0x6a,0xc3,0xa2,0x55,0x7d,0xb6,0xdc,0xc5,0xc2,0x5c,0x69,0xef,0xd6,0x85,0x33,0xb3,0x19,0x84,0xce,0xb9,0xd9,0xb9,0x9c,0xaa,0x2d,0xab,0x56,0x0,0x16,0xdb,0xe,0x5c,0x2b,0x42,0xd7,0xe9,0xd6,0x65,0xf,0xe7,0xa6,0x85,0x1d,0xd3,0xb2,0x12,0xdf,0x42,0x5a,0xb,0xae,0x1d,0x2c,0xc0,0x9c,0x16,0xbb,0x64,0x9d,0x8d,0x68,0x2d,0xe2,0x98,0x37,0x1,0x57,0x69,0xa5,0x76,0x61,0x89,0x5a,0xce,0xf3,0x45,0x87,0x88,0x88,0x88,0x88,0xe8,0x22,0x63,0x0,0x48,0x44,0xf4,0xa,0xac,0xa5,0x74,0xa,0xaa,0xea,0x14,0xfe,0xe4,0xdc,0x2a,0x9e,0x80,0xa9,0xd,0x38,0xc4,0xe,0x70,0xc0,0x89,0xe5,0x12,0xff,0xf4,0xb7,0x3e,0x86,0xe5,0x62,0xd1,0x96,0x20,0xb4,0xd,0xb0,0x6d,0x2e,0xde,0x54,0x1,0xe6,0x75,0x9,0x46,0x6b,0x39,0xd5,0xcf,0xa9,0x6d,0x8d,0xad,0x2d,0xdf,0xc8,0x2d,0x6c,0x6b,0x4b,0x1e,0x7c,0x68,0xed,0xc8,0x56,0xed,0x7,0x48,0xd0,0x56,0x4a,0xc6,0x38,0x8e,0xf8,0xec,0x9f,0x7d,0x15,0x4f,0x3d,0xf7,0x2,0xba,0x7e,0x89,0x9c,0x46,0xad,0x60,0xb,0x70,0x4e,0x6e,0x4f,0x82,0x1c,0xa9,0x24,0xcb,0x39,0x23,0x68,0x35,0x5f,0x8,0x11,0x29,0x8d,0x6d,0xe6,0x9d,0xf3,0x56,0xd9,0xe8,0x91,0x87,0xb5,0x4,0xa1,0xd8,0x6c,0xd5,0x51,0xd5,0xf8,0x26,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x4d,0x69,0xb4,0xe2,0x2e,0x74,0x7d,0x8f,0x9c,0x25,0x38,0xcb,0x29,0xb5,0xd0,0x28,0xc4,0x4e,0xce,0x9d,0x6,0x7f,0x6d,0x13,0xad,0x1e,0x87,0x9f,0xb5,0x58,0x3,0xd2,0x62,0x3a,0xb5,0x30,0x97,0x16,0x66,0xd5,0x52,0xdb,0xd9,0xb2,0xb7,0x59,0x40,0x55,0x73,0x6d,0xcf,0xd9,0xb4,0xc8,0x62,0x5a,0x5c,0x61,0xc1,0xa5,0x5,0x67,0xb6,0xb8,0x22,0xa5,0xa4,0x8b,0x47,0x24,0x3c,0xb3,0xe7,0xdb,0x7b,0x2f,0x95,0x76,0x5a,0x55,0xe9,0x43,0x40,0x4e,0xa9,0x55,0x5e,0xda,0xd6,0x67,0x7b,0x9f,0x85,0x71,0x41,0x37,0x3e,0x17,0x27,0x6d,0xc3,0x56,0xcd,0x19,0x9c,0x84,0x87,0x76,0xdb,0xfd,0x72,0x47,0x2b,0xf5,0x0,0x54,0x87,0x10,0xfb,0x16,0xca,0x16,0xd,0x6e,0xad,0x6a,0x6f,0xaa,0x70,0xf4,0x2d,0x8,0xd,0x21,0xa2,0xba,0xd2,0x2,0x65,0x7b,0xac,0xf3,0x2a,0xc5,0x6a,0xed,0xd8,0x28,0x2d,0xe0,0x94,0xf3,0x1d,0x50,0xdd,0xb4,0x45,0xd8,0xda,0xd8,0x37,0x3e,0xdf,0x7b,0x38,0x3d,0x16,0x94,0x82,0x32,0xdf,0xe2,0xac,0x61,0x78,0xb6,0x4a,0x4a,0xd,0x1,0x4b,0xce,0x1a,0xb2,0xca,0x46,0x68,0xb9,0x6e,0x1,0x57,0xfd,0x46,0xb8,0x5c,0xd3,0x3e,0x5f,0x70,0x88,0x88,0x88,0x88,0x88,0x2e,0x1,0x6,0x80,0x44,0x44,0x17,0x60,0xa1,0x90,0xf3,0xe,0x65,0x2c,0x2d,0xd0,0xaa,0x0,0x9c,0xb6,0x94,0x2,0x12,0xc6,0x4c,0xf3,0xf1,0xa6,0x99,0x6e,0xbb,0xcb,0x1e,0x77,0xdf,0xf5,0x26,0xec,0x2c,0x97,0xff,0xbf,0x3f,0x96,0x71,0x1c,0xf1,0xa7,0x5f,0xfc,0xd6,0xd4,0xba,0xaa,0x41,0x94,0x54,0xc6,0x49,0xb0,0xe9,0xbd,0xcd,0xcd,0x73,0x6d,0xf3,0xaf,0x3c,0xde,0xda,0x2,0x1e,0x9b,0x93,0x7,0xd,0xad,0x6c,0x4e,0x61,0x6d,0xa1,0xe4,0xe6,0xc2,0x88,0x52,0x32,0xc6,0x61,0xd0,0x19,0x75,0xe,0x3e,0x46,0xd,0x97,0x24,0x64,0x8a,0xb1,0xd7,0xb6,0xd6,0x8a,0xa4,0x2d,0xa4,0xa8,0x75,0xb6,0x31,0xb7,0xc2,0xc3,0xc3,0x85,0x79,0xab,0xed,0x34,0x77,0xce,0x39,0x79,0x5f,0x3b,0xf7,0x6d,0x51,0x48,0x6d,0x61,0x63,0x86,0xb4,0xc,0x3b,0xdd,0x84,0xc,0x68,0x5b,0xf2,0xac,0x2d,0xb8,0x68,0x45,0xe5,0xbc,0x62,0xce,0xaa,0xdf,0xa4,0x9d,0xd8,0x6b,0x78,0x56,0xdb,0x6d,0x58,0x6b,0x6e,0xab,0x84,0xd4,0xf3,0x61,0xb7,0x5d,0x4b,0x86,0x83,0x43,0xd7,0x2f,0xda,0xfb,0xa0,0x41,0xe4,0x38,0xac,0x24,0xa8,0x6b,0x5b,0x7b,0x63,0x7b,0xcc,0xd2,0xae,0x2b,0x61,0x6b,0x29,0x19,0x39,0x25,0x84,0x28,0x73,0xf,0xbd,0x97,0xca,0x49,0xb,0x60,0xc7,0x61,0xa5,0x2d,0xbd,0x52,0xf9,0x98,0xd3,0x38,0xcd,0x41,0xd4,0x76,0x68,0x5b,0xe4,0xe2,0x9c,0x43,0x81,0xb6,0x69,0xa7,0x71,0x76,0x7d,0x5b,0x20,0x6a,0xed,0xd6,0x45,0x97,0x92,0xe4,0x36,0x7b,0xb2,0x9d,0x37,0x6c,0x2e,0x8b,0xb1,0x39,0x86,0xf6,0xf7,0x22,0xe7,0xd4,0xe6,0x4,0x2,0xba,0xd9,0x59,0x43,0x44,0xdb,0xc6,0x5c,0x4b,0x69,0x8b,0x57,0xe6,0x9c,0xef,0x50,0xf3,0x9a,0x2f,0x3c,0x44,0x44,0x44,0x44,0x44,0x17,0x19,0x3,0x40,0x22,0xa2,0xb,0x72,0xd3,0x6,0x5b,0xd,0xa6,0x6c,0x76,0x5a,0xa9,0x75,0x6a,0xb1,0xd5,0x45,0x9,0x16,0xae,0xe5,0x94,0xe0,0xfb,0x45,0x6b,0xbf,0xfd,0xbb,0xf1,0x50,0xa4,0x6a,0xb1,0x5b,0x2c,0x90,0xc6,0x41,0xb7,0x14,0xfb,0x16,0x62,0xd5,0x2a,0x33,0xef,0xbc,0xf7,0xba,0x29,0x56,0x37,0xcf,0x6a,0x28,0xe8,0xda,0x62,0x8a,0xda,0xe6,0xea,0xd9,0x26,0x58,0xaf,0x2d,0xa5,0x4e,0xc3,0xa9,0xae,0x5b,0x68,0x9b,0x71,0x98,0x42,0x28,0xad,0xb8,0xb3,0x39,0x83,0xb5,0x4c,0x9b,0x7b,0x6d,0x26,0x5e,0x70,0xb6,0x28,0xa4,0xce,0xaa,0xdc,0xba,0x56,0xad,0x28,0x9b,0x8d,0xd3,0x14,0xbc,0xc5,0xb0,0xb1,0xe1,0x57,0x66,0x8,0x56,0x94,0xa2,0x5b,0x6a,0xf5,0x78,0x6d,0xa3,0x32,0x80,0x69,0x8b,0xb0,0x93,0x16,0xe9,0x79,0x50,0x68,0x1f,0x63,0xc1,0x54,0x49,0x9,0xa1,0x9b,0x82,0x5d,0x38,0xa0,0x8b,0x8b,0x56,0x81,0x29,0x6d,0xbf,0xae,0x9d,0x9f,0xae,0xef,0xdb,0xed,0x85,0xd8,0x4d,0xed,0xc1,0x1a,0xa4,0x95,0x92,0xe0,0x74,0x86,0x61,0x88,0x1d,0xba,0x7e,0x81,0x9c,0xd2,0xac,0x15,0xbb,0xa0,0x8c,0x23,0x62,0xd7,0xb7,0x2a,0xca,0x3e,0x2e,0xe1,0xfb,0x1e,0x31,0x78,0x78,0xdf,0x63,0x4c,0x19,0x9d,0xf,0xed,0xb1,0x76,0xdd,0x42,0xb7,0x7,0xcb,0x31,0x76,0xb,0xa9,0xee,0xc,0x21,0x22,0x8d,0xc3,0xd4,0x86,0xab,0xa1,0x60,0xc,0xfd,0xb4,0x58,0x65,0x36,0x4b,0x52,0xc6,0x2b,0xea,0xa2,0x13,0x2f,0xcf,0x43,0xd0,0xdb,0x74,0x70,0xad,0x55,0x78,0x3a,0xdf,0x1e,0x3e,0xfa,0xd6,0x92,0x6d,0x8b,0x56,0xac,0x5a,0xd4,0x5a,0xe5,0xe7,0xf3,0x21,0x2d,0xa0,0x85,0x2d,0x1c,0x91,0x77,0xb4,0xdb,0xad,0x35,0x69,0xeb,0x71,0xe1,0x4b,0xf,0x11,0x11,0x11,0x11,0xd1,0x45,0xc4,0x0,0x90,0x88,0xe8,0x95,0x48,0xc9,0x93,0x56,0x40,0xd5,0x36,0xb,0xd0,0xcf,0xaa,0xce,0x7c,0xb0,0xf6,0xdb,0xda,0x16,0x5f,0x0,0xd0,0x96,0xd3,0xbf,0x23,0x8f,0x43,0x2b,0xcd,0xaa,0x86,0x56,0xb1,0xeb,0x64,0x26,0xa0,0xb5,0x6e,0x46,0x59,0x6a,0x2,0x0,0x31,0xf6,0x32,0xa7,0x50,0x3,0xac,0xda,0xba,0x47,0xab,0x2e,0x8,0x89,0x32,0x77,0xcf,0x96,0x80,0x54,0xc0,0xeb,0x52,0x94,0xbe,0x5f,0x62,0x58,0xef,0xeb,0x26,0x63,0x9,0xbd,0xd2,0x38,0xca,0x46,0x62,0x57,0xd0,0x6b,0x60,0x95,0x73,0x96,0x19,0x88,0xda,0x72,0xbb,0x11,0x14,0x95,0x82,0xd8,0x2f,0x90,0xeb,0x38,0x1d,0x83,0xce,0x56,0x5c,0x2c,0x77,0xdb,0x52,0xe,0x99,0xd7,0xe7,0x30,0x8e,0x6b,0x78,0xe7,0x25,0x50,0xd4,0x96,0xdd,0x9c,0xd2,0x6c,0x81,0x86,0x84,0x9d,0x25,0xe7,0x16,0xbe,0xcd,0x97,0x86,0xc4,0x36,0xe7,0x4e,0xc3,0xb2,0x10,0xda,0x8c,0xbc,0x92,0xb2,0x56,0x78,0x46,0xd4,0xea,0xda,0x2,0x12,0x9b,0x7,0x98,0x73,0x46,0xec,0x7b,0xd4,0x32,0x6d,0xd5,0xd,0x51,0x37,0x3e,0x17,0xb9,0x6,0x24,0x30,0x4c,0x3a,0x33,0x70,0xda,0x72,0x6c,0x41,0xa2,0xfd,0x7e,0xb9,0x73,0x2,0xa3,0xcd,0x8f,0xac,0x5,0xb1,0xeb,0x11,0x1c,0xf0,0x3b,0xff,0xd9,0x7,0xf1,0xb6,0xbb,0xef,0x44,0xf0,0x1e,0x3f,0x7e,0xe8,0xa7,0xf8,0xa3,0xcf,0x7f,0x9,0xcf,0xbc,0x70,0x6,0x3a,0xac,0x10,0xc8,0xb2,0x25,0x38,0x8d,0x43,0x6b,0x4b,0xcf,0x39,0xc1,0x85,0xd0,0x2,0x6b,0x3b,0x27,0xf3,0xf3,0x69,0x21,0xa5,0x55,0xf8,0xd9,0xdc,0xc8,0xaa,0xd5,0x7b,0xd3,0xf6,0x6b,0xcc,0x66,0x2f,0xda,0xc,0xc1,0xb1,0x55,0x25,0x5a,0xf8,0x27,0x2d,0xbe,0x52,0x1,0xe8,0xf4,0x71,0xcb,0x6,0x61,0xa9,0x68,0xf4,0x4e,0xe6,0x58,0x42,0xaf,0x19,0x6b,0xa5,0xaf,0xd0,0x45,0x24,0xbe,0x43,0x4d,0x2b,0xbe,0xe6,0x10,0x11,0x11,0x11,0x11,0x5d,0x64,0xc,0x0,0x89,0x88,0x2e,0xa0,0xe4,0xb1,0xcd,0x96,0x6b,0xd5,0x7c,0xb3,0x59,0x80,0x3e,0x4e,0x15,0x64,0x6d,0xc6,0x9c,0x7e,0x6c,0x1a,0xd7,0xb2,0x41,0xf5,0xef,0x48,0x5,0xa0,0xd3,0xad,0xb7,0x31,0x76,0x18,0xb5,0x25,0x34,0x97,0xa4,0x1,0x8f,0x9b,0x66,0xed,0x69,0x35,0x1f,0x6c,0x99,0x83,0x5,0x3f,0xba,0x11,0x36,0x68,0xdb,0xb0,0x55,0x91,0x39,0xef,0xe0,0xaa,0x85,0x83,0x12,0x10,0x2d,0x76,0x4e,0xb4,0xaa,0x3f,0xef,0x3,0x5c,0xe7,0xda,0xf6,0xdb,0x71,0x58,0xcb,0xa2,0x8f,0x30,0xcd,0x17,0x74,0xce,0x21,0xeb,0xc2,0x94,0xa8,0x5b,0x6d,0x8b,0x2e,0xe5,0x90,0xa5,0x1e,0xa5,0xb5,0xc9,0x5a,0x80,0x27,0x9b,0x6f,0xeb,0x34,0x73,0x51,0xdb,0x93,0x73,0x1a,0xdb,0x2,0x8a,0xa2,0x15,0x67,0x56,0xed,0x16,0xbb,0xae,0xb5,0x6d,0x5b,0x38,0x28,0x33,0xfa,0xaa,0x6,0x81,0x3d,0x86,0xd5,0x3e,0x42,0x8c,0x7a,0x1c,0x49,0x66,0x0,0xc6,0xd8,0x16,0x71,0x48,0x45,0x5c,0x45,0x4e,0x19,0x21,0x76,0x8,0x1,0xd3,0xc6,0x5c,0x3b,0xf,0xba,0xf4,0xa3,0xeb,0x17,0x6d,0xae,0xa0,0x5d,0x1b,0xb5,0x6,0x5d,0x8a,0x3b,0x55,0x52,0x42,0x1f,0x5b,0x1a,0xc7,0x8d,0x6a,0x3a,0x7,0x87,0xff,0xe6,0x77,0xff,0x3e,0xde,0xfd,0xce,0x7b,0xda,0xf3,0x78,0xd5,0x6b,0xae,0xc4,0x75,0xaf,0xbd,0x16,0xff,0xfd,0xff,0xf2,0x19,0xac,0xd6,0x6b,0x0,0xbe,0x9d,0x33,0xa9,0xb2,0x93,0x59,0x89,0x29,0x67,0x74,0xb1,0x93,0x6a,0x3c,0x0,0x79,0x1c,0x5b,0x68,0x6a,0xe1,0x66,0x9b,0xb7,0xa8,0xcf,0xbb,0x5,0xa0,0xd0,0x79,0x82,0x5d,0xd4,0x73,0x0,0x6d,0x77,0xce,0xb6,0xe8,0x46,0xb6,0x1b,0x5b,0x30,0x2a,0xc1,0x62,0x69,0xb3,0x11,0x9d,0x5e,0x2b,0xed,0xf9,0xb3,0x8a,0x4a,0x3d,0xf,0x55,0x2b,0x69,0x4b,0x2d,0xf6,0xd7,0xc9,0x2e,0x50,0xbe,0xe8,0x10,0x11,0x11,0x11,0x11,0x5d,0x2,0xc,0x0,0x89,0x88,0x5e,0x41,0xad,0x65,0x63,0xc1,0x84,0xb5,0xfa,0x5a,0x8b,0xaa,0x54,0x49,0xb9,0xf6,0xb1,0xa8,0x5e,0x83,0x96,0x1e,0xa9,0x54,0x9c,0x3d,0x77,0x1e,0xc3,0x38,0xe8,0xe2,0xa,0x4b,0x10,0x6b,0xdb,0x38,0x2b,0x15,0x59,0xda,0x6a,0x6c,0x9b,0x72,0xe1,0xb0,0x58,0x2e,0xb0,0xe8,0xbb,0x43,0xc7,0x33,0x8c,0x9,0xab,0xd5,0x5a,0x3f,0x1e,0xd2,0x4a,0x59,0xab,0x76,0x7a,0x6a,0x80,0xa3,0xcb,0x48,0x9c,0xf4,0x75,0x2,0xb5,0x62,0x1c,0x13,0xaa,0x97,0x0,0xd,0xce,0x21,0x8f,0x9,0xc1,0xc7,0xd6,0xee,0xab,0x9f,0x88,0x52,0x12,0xbc,0x8f,0xa8,0xc8,0x5a,0x25,0x26,0xb,0x3e,0x86,0xd5,0x5e,0xdb,0xa8,0x2b,0x2d,0xab,0xbe,0x2d,0xe0,0xb0,0x25,0x14,0xb6,0x5,0x19,0xa5,0xc8,0x32,0x9,0xad,0x88,0x3,0x74,0x8e,0x20,0x6a,0xb,0xf1,0x8a,0x6,0x63,0x21,0xc6,0x8d,0x85,0x15,0xb2,0x48,0x42,0xf6,0x1e,0xcb,0x71,0xe,0x8,0xb1,0x6b,0x15,0x6c,0xde,0x7b,0x64,0x6d,0x6d,0x75,0x4e,0x2b,0xf,0xf5,0x79,0xc8,0x6d,0x36,0x9e,0x9c,0xdb,0x71,0x58,0xb7,0x85,0x21,0x41,0x97,0x74,0x38,0xe7,0x65,0x8e,0x9f,0x3e,0x8f,0x36,0xbb,0xd1,0xaa,0xd5,0x2c,0x20,0x2c,0x39,0x63,0xb1,0x94,0xaa,0xba,0xaa,0xd5,0x71,0xc0,0x2c,0x38,0x6c,0x6d,0xca,0xd2,0xa,0xdc,0x2d,0x96,0x1a,0x7a,0xf9,0xb6,0x18,0x26,0x8d,0x43,0xb,0x4a,0x43,0x88,0x18,0xc7,0x41,0x37,0xf5,0x6,0xa4,0x71,0x68,0x55,0x84,0x72,0x7f,0x52,0xd5,0x18,0xbb,0x1e,0xe3,0xb0,0x46,0xdf,0x2f,0x70,0xe3,0xd5,0xa7,0xf1,0xb6,0xb7,0xbe,0xf9,0xd0,0x35,0x70,0xeb,0xcd,0x37,0xe0,0xae,0xdb,0x6f,0xc6,0xdf,0x3c,0xf8,0x98,0x56,0x35,0x4a,0x8b,0xba,0x7,0xda,0xf1,0x77,0xbd,0xb4,0x7a,0x4b,0xc8,0x59,0x51,0x67,0xd7,0x87,0xf7,0xbe,0xcd,0x6e,0xf4,0xda,0x2a,0x6c,0x1b,0x83,0xbd,0xf7,0xd0,0xf,0x46,0xce,0x79,0xb6,0x80,0x46,0xde,0x66,0xdb,0xa3,0x9d,0x6,0x95,0xc5,0xda,0xe3,0x35,0x54,0x6e,0x1b,0x95,0x75,0xd6,0xdf,0xf4,0xdc,0xcb,0xc2,0x19,0x6b,0x97,0xae,0x1a,0xfd,0xd9,0xdf,0xb,0x99,0xe5,0xd8,0x1,0x79,0xe0,0x8b,0xe,0x11,0x11,0x11,0x11,0xd1,0x45,0xc6,0x0,0x90,0x88,0xe8,0x2,0x7c,0xe8,0x0,0x4c,0x9b,0x50,0xad,0x45,0x12,0xb6,0x80,0xc2,0xfb,0x56,0xe5,0x27,0xb,0x24,0x64,0xc6,0x9d,0x2b,0x12,0xc8,0xbd,0x78,0xe6,0x1c,0xfe,0xbb,0xff,0xe1,0x9f,0x3,0x0,0xfa,0x7e,0x1,0x40,0xe6,0xd1,0xb5,0x85,0x14,0x45,0xda,0x86,0xfb,0x7e,0x1,0x1f,0x3b,0xdd,0x5c,0x2b,0x1,0xcd,0x6f,0x7e,0xf8,0xdd,0x78,0xd7,0xdd,0xb7,0x1f,0x3a,0xa6,0x87,0x1f,0x7b,0x2,0xff,0xea,0xf3,0x5f,0x45,0xd0,0x99,0x75,0xce,0x1,0x29,0x67,0x4,0xef,0x91,0xc6,0x51,0x5b,0x54,0xd1,0x2a,0xad,0xec,0xcf,0x39,0x8d,0x18,0xc6,0xb1,0x85,0x35,0x32,0xd3,0xcd,0xc1,0x57,0xdd,0xbe,0x3b,0x9f,0x73,0xe8,0x1d,0x80,0xa8,0x2d,0x9d,0x52,0x11,0xd8,0x2f,0x77,0x74,0x59,0x88,0xb5,0xee,0xd6,0xb6,0x38,0x63,0xbe,0x0,0xc3,0xaa,0xbc,0xac,0xbd,0xb5,0x56,0xa0,0xeb,0x3a,0xd,0x85,0x42,0xab,0x4,0x74,0x3e,0x20,0xd,0xeb,0x56,0x85,0x66,0x73,0x0,0x6d,0x3e,0x9f,0xfe,0x41,0xda,0x54,0xab,0x6e,0x1f,0x76,0xf2,0x38,0x62,0xbf,0x40,0x1e,0x47,0x6d,0xa9,0x95,0x96,0x56,0xa9,0xa0,0x1b,0xf4,0xd3,0x2a,0x6a,0x99,0xaa,0xb,0x9d,0xb,0xf0,0x21,0x60,0x1c,0xd6,0x52,0x71,0x77,0x60,0x6e,0x5d,0x45,0x6d,0x6d,0xc1,0x76,0xde,0x4a,0x19,0xb4,0xca,0x10,0x88,0xfd,0x42,0x2b,0x12,0xfd,0x14,0xfe,0x69,0xc0,0xea,0x9c,0x47,0xe8,0x3c,0x1c,0x74,0x69,0x8c,0xde,0x7f,0xd0,0x5,0x1b,0xfd,0x72,0x7,0xc3,0x6a,0x85,0xaa,0xcf,0x9,0x0,0x3d,0x6f,0xdd,0xc6,0xe2,0x91,0x7e,0xb9,0x23,0xf7,0x1,0x5b,0x50,0x52,0x70,0xea,0xe4,0xe,0xba,0xee,0xf0,0x97,0x6a,0xe7,0x1c,0xae,0xbb,0xe6,0x2a,0xfc,0xcd,0x83,0x3f,0xd3,0x76,0x63,0x2f,0x73,0xff,0xb4,0xa5,0xda,0xaa,0xf6,0x82,0x6e,0x23,0xb6,0x59,0x8c,0x16,0xe8,0xa6,0x71,0xd0,0x65,0x1d,0x12,0x66,0xf6,0xb,0x9,0x76,0xbb,0xbe,0x97,0xa,0xbe,0x18,0xad,0xee,0x15,0xc3,0x7a,0x1f,0xe,0x1e,0x3e,0x78,0x38,0xd8,0x66,0x5f,0x0,0xda,0x26,0x6c,0x5b,0x88,0xe5,0xa3,0x5d,0xbb,0xe,0x72,0x96,0xcd,0xd4,0x25,0x8f,0xb3,0xea,0xc7,0xba,0xb9,0x50,0x44,0x1f,0x27,0xe0,0x50,0x72,0x6a,0x2d,0xe8,0x44,0x44,0x44,0x44,0x44,0x74,0x71,0x31,0x0,0x24,0x22,0xba,0x80,0x92,0x47,0xfd,0x9d,0x2e,0x2a,0x28,0xb2,0x7d,0xd6,0x5a,0x5b,0xb3,0x2e,0x89,0xd8,0xd8,0x66,0x2a,0x65,0x79,0x12,0x7c,0xf5,0x4b,0xec,0xaf,0x7,0x59,0x92,0x1,0x9,0x97,0x56,0xe3,0xa,0x21,0x46,0x9d,0x8b,0x26,0x15,0x67,0xe3,0x6a,0x5,0xef,0x65,0x4e,0x5e,0x1e,0x53,0xab,0x2,0x3b,0x4a,0xce,0x19,0x63,0x2e,0x18,0x52,0x96,0xf0,0x11,0x0,0xe0,0xb0,0xca,0x52,0x5d,0xb6,0x5e,0x4b,0x8,0x66,0xd5,0x85,0x56,0x5,0x26,0xb,0x2b,0x80,0x34,0xca,0x82,0x88,0x8c,0x4,0xe7,0x1d,0x6a,0x96,0xaa,0x44,0xe7,0x3,0x50,0x8b,0x6c,0xbe,0xd5,0xed,0xb5,0x40,0x6e,0xad,0x9c,0xce,0x7b,0x14,0xfd,0x5c,0xb,0x44,0x43,0xd7,0x69,0x30,0xe7,0x66,0xd5,0x86,0x56,0x65,0x26,0xf7,0x19,0xa3,0xd7,0x20,0x11,0x88,0xb1,0xd3,0x5,0x24,0x52,0xff,0x65,0xa1,0x5b,0xe8,0x64,0x7e,0xa0,0xf7,0xae,0x55,0x96,0x49,0x18,0x27,0x73,0xfb,0xbc,0x56,0xd5,0x5,0xdd,0x22,0x9b,0xd3,0x88,0x4e,0x43,0x2b,0x6b,0xf7,0x6d,0xdb,0x8d,0xbd,0xd7,0xb0,0xab,0x48,0x9b,0x6e,0x8,0xad,0xbd,0x35,0x6a,0xb5,0x5f,0x2e,0x75,0xa3,0xe2,0xcd,0xda,0x80,0xbd,0x43,0x9b,0x2f,0xd8,0x75,0x7d,0xab,0xa4,0x4,0xa6,0x8d,0xd0,0xed,0xf1,0xea,0xf6,0x60,0x38,0x7,0xaf,0xed,0xc6,0xf2,0xb8,0x7d,0xab,0xa8,0x8c,0x5d,0x8f,0x34,0x8e,0x6d,0xce,0xa2,0x14,0x35,0xca,0x31,0xb6,0x16,0x6a,0xe7,0xe1,0x9c,0x7c,0x7c,0xd0,0x0,0x31,0xc6,0xe,0x70,0xe,0x4f,0x3f,0xf7,0x32,0xf6,0xf7,0x57,0xd8,0xdd,0xdd,0xd9,0xbc,0x2e,0x4b,0xc1,0x2f,0x9e,0x7a,0xae,0xb5,0x12,0xd7,0x52,0x10,0x3b,0x9,0x29,0x7d,0x88,0x70,0xce,0x63,0x18,0x56,0x88,0xa1,0x7,0xbc,0xd7,0x6b,0x20,0x6e,0x5c,0x2f,0xce,0xf9,0xa9,0x5a,0xcf,0xaa,0x10,0x75,0x3b,0xaf,0x5c,0x3f,0x12,0xc,0xf7,0xcb,0x5d,0xa9,0xf4,0xd3,0x70,0x3a,0x76,0x5d,0x9b,0xc7,0xe8,0x35,0x58,0x84,0xb6,0xc7,0xdb,0x62,0x92,0x56,0x39,0x58,0x73,0xb,0x5c,0xad,0x52,0xb6,0xe8,0xf3,0xd5,0xfe,0x4e,0xcd,0x67,0x67,0xfe,0x1d,0xda,0x99,0x43,0x44,0x44,0x44,0x44,0xb4,0x4d,0x3c,0x4f,0x1,0x11,0xd1,0x5,0x5e,0x24,0x43,0xd4,0xc0,0xf,0x1b,0x9b,0x6c,0xdb,0x66,0x5c,0xb,0x8f,0x2c,0x38,0x99,0x2d,0x74,0x40,0xad,0x18,0x87,0x15,0x6a,0xc9,0x28,0xb5,0x22,0x8d,0x23,0xc6,0x61,0x5,0xe7,0x9d,0xcc,0xb8,0xd3,0xa,0xb9,0x79,0xb5,0x1b,0x0,0xad,0xa8,0x2b,0xad,0xaa,0xea,0x28,0x25,0x27,0x78,0xe7,0x10,0x62,0xdf,0xda,0x92,0x65,0x16,0xe1,0xd8,0xc2,0x39,0x19,0xeb,0x27,0xad,0xaf,0xe3,0xb0,0x46,0xc9,0x9,0x49,0xb7,0xe9,0x8e,0xc3,0x5a,0x42,0x28,0xdb,0xfa,0x6a,0x81,0x8c,0x73,0xd2,0xf2,0x5a,0xab,0xb4,0x6d,0x6a,0xbb,0x6b,0x3b,0x1f,0x31,0xc2,0x36,0x5,0x87,0x10,0xdb,0xa2,0xf,0xef,0x43,0xb,0x46,0x3b,0xdd,0xb8,0x6b,0xdb,0x7f,0xbd,0x6,0x65,0x52,0xf1,0x26,0xed,0xc7,0x5d,0xdf,0x23,0x4,0x6b,0xd5,0x75,0x6d,0x21,0x45,0xec,0x16,0x8,0x21,0x22,0x84,0x6e,0x63,0xf6,0x5c,0xbf,0xd8,0x69,0xbf,0x8f,0x5d,0x8f,0xae,0x5f,0xb4,0x16,0x5e,0xaf,0x95,0x83,0xe3,0xb0,0x96,0x6d,0xbf,0x5a,0xb5,0x18,0xbb,0x85,0x84,0x55,0x98,0x5a,0xb4,0xa1,0xe1,0x5b,0xd4,0xca,0x38,0xfb,0xaf,0xf3,0x5e,0x3,0x3f,0x68,0xa8,0x15,0xda,0x79,0xb4,0xc5,0x17,0xfd,0x62,0x89,0xae,0x5f,0x68,0xc0,0x18,0xda,0x71,0xc7,0xd8,0xc1,0xc7,0x28,0x1b,0xa1,0x31,0x6d,0xc9,0xb5,0xea,0x43,0x9,0xb7,0xa4,0x65,0x3c,0x68,0x38,0x67,0x6d,0xdf,0xf3,0x6b,0x20,0xeb,0x66,0x66,0x3b,0x67,0xde,0x7b,0xbc,0x78,0x6e,0x1f,0x5f,0xf9,0xc6,0x77,0x5b,0x28,0x67,0x97,0xc9,0x77,0xef,0x7b,0x10,0xf,0xfc,0xf4,0x49,0x38,0x27,0xf3,0xff,0xe4,0xf9,0x8,0x1b,0x73,0x28,0x2d,0x60,0xb6,0x73,0x64,0x8b,0x55,0xec,0x73,0x42,0x8c,0x2d,0x88,0x96,0xb6,0xe5,0x80,0x18,0x7b,0xdd,0xee,0x1c,0x5b,0x68,0x2c,0x41,0xea,0xa8,0xe7,0xc2,0x6b,0xd0,0x57,0xa6,0x59,0x8a,0xfa,0x3c,0x87,0x28,0x9f,0x63,0x5b,0x87,0xbd,0x86,0xb5,0x16,0xd0,0xc2,0xe6,0xd,0xb6,0x6a,0xce,0x69,0xb9,0x88,0x9d,0xb3,0xda,0x2,0x77,0x22,0x22,0x22,0x22,0x22,0xba,0x98,0x58,0x1,0x48,0x44,0xf4,0xa,0xe6,0xdb,0x69,0xad,0x7d,0xd1,0xaa,0xc2,0x50,0x6b,0xb,0x43,0xe6,0xed,0xb0,0x28,0x40,0x76,0x19,0x7d,0xd7,0xa3,0xe4,0x84,0xa0,0x1b,0x67,0xbb,0x7e,0x81,0x92,0xa4,0x15,0x76,0x1c,0xd6,0xad,0x22,0x4d,0x16,0x33,0x64,0x84,0x92,0x51,0x52,0xd2,0x79,0x75,0xc7,0x2f,0x44,0x68,0x4b,0x39,0x34,0x28,0xcc,0x39,0x6b,0x57,0xe6,0xb4,0x1d,0x77,0x1c,0x56,0x7a,0xfc,0x9b,0xf3,0xeb,0x60,0x21,0x93,0xf,0x48,0xe3,0x1a,0x39,0xa5,0x59,0x70,0x6,0x74,0x5d,0x8f,0xac,0xcb,0x29,0x1c,0xa4,0x3d,0x76,0xa,0xf5,0xa6,0x56,0x52,0xb,0xda,0x2a,0xa4,0xdd,0x35,0x68,0x8b,0x74,0x4e,0x23,0x42,0x8,0x8,0xb1,0x47,0x29,0xab,0xd9,0x72,0x9,0xa9,0x10,0xb4,0xd6,0x65,0x9,0xd1,0xa6,0x90,0x50,0x66,0xd9,0x8d,0xe8,0xb4,0xbd,0xb8,0x5f,0x2c,0xdb,0x31,0xe7,0x94,0xda,0xe3,0xa,0x21,0x62,0x58,0xed,0x49,0x50,0xa5,0xed,0xac,0xde,0x7,0x74,0xbd,0x4,0x4f,0xfd,0x72,0x89,0x92,0xb3,0x9c,0xf7,0x18,0x65,0xb6,0x9e,0xde,0xa7,0xb5,0x2e,0x7b,0xe7,0x30,0xea,0x1c,0x41,0xad,0x7f,0x6c,0xb,0x49,0xd2,0x38,0xa0,0x3a,0xd7,0x2a,0x4,0x65,0x7e,0x5f,0x8f,0x61,0xbd,0x6a,0xe1,0x60,0x29,0x72,0x7e,0x4a,0x4e,0xc8,0x39,0x49,0x10,0xea,0x6d,0x96,0x9d,0x6b,0xcf,0xa7,0x3d,0x57,0xd6,0xee,0x5b,0x8a,0x2c,0x22,0x19,0x47,0x6b,0xfd,0x5e,0xb6,0x90,0xcd,0x69,0xa8,0x68,0x5b,0x73,0x65,0x26,0x5e,0xc4,0xef,0xff,0xc9,0x17,0xf1,0xf4,0x73,0x2f,0xe0,0xed,0x77,0xbd,0x11,0x21,0x78,0xdc,0xff,0xc0,0x43,0xf8,0xe2,0xb7,0x1e,0x44,0x4a,0xa3,0xcc,0xef,0xd3,0xa5,0x2a,0xc5,0xae,0x4f,0xb,0x15,0xe1,0x5a,0x95,0xa4,0x2d,0x18,0x9,0x3a,0xf,0x30,0x8d,0x6b,0x74,0xfd,0xb2,0x5d,0x63,0xf6,0x58,0xab,0x56,0xa4,0xca,0x35,0xef,0x5a,0xe5,0x62,0xd7,0x2f,0xdb,0xb5,0x9e,0x4b,0x6a,0xed,0xc1,0xb6,0x18,0x6,0x70,0x28,0x35,0xb7,0x70,0x5c,0x66,0x5c,0x6a,0xd0,0xa9,0xb7,0x61,0xe7,0x7,0xa5,0x2,0xb3,0x79,0x91,0x6d,0x66,0x62,0xc9,0x70,0xa1,0xe7,0x16,0x60,0x22,0x22,0x22,0x22,0xa2,0x4b,0x80,0x1,0x20,0x11,0xd1,0x5,0xd8,0xdc,0x37,0xb,0x75,0xac,0x32,0xae,0xe6,0x8a,0x18,0xa3,0xb4,0x7f,0x6a,0x25,0x57,0xec,0xfb,0x16,0x36,0x59,0xe8,0x95,0xc6,0x41,0xdb,0x2c,0x25,0xac,0xb1,0x79,0x7c,0x5d,0xef,0x35,0xb8,0x4b,0xa8,0x3,0xda,0x92,0x88,0x9c,0x92,0xcc,0x6c,0xbb,0xc0,0x31,0xb5,0x80,0x29,0x25,0xc8,0xc,0x36,0xdd,0xb0,0xaa,0xa1,0xd4,0x38,0x26,0xd4,0x92,0x74,0x46,0xa1,0x43,0x1,0x5a,0x0,0x33,0xe,0x6b,0x84,0xd0,0xb5,0x2d,0xba,0xce,0x39,0xd,0xc5,0xca,0x46,0xb5,0x56,0xb,0x81,0x9c,0x43,0xc,0x5d,0xb,0xae,0x52,0x1a,0x75,0xe,0x9c,0x2d,0xcb,0xa8,0xf0,0xda,0xaa,0x5b,0xb5,0xe2,0xcb,0x75,0x3d,0x6a,0x29,0xc8,0x69,0x98,0xb6,0x22,0x7b,0xaf,0x95,0x86,0xd2,0x72,0xda,0xf5,0xb,0x69,0xe3,0xed,0x7a,0x0,0xd0,0xf9,0x78,0xd2,0x12,0xec,0x67,0x95,0x61,0x36,0x23,0xae,0xeb,0x7b,0x7b,0xf0,0x18,0xd7,0x2b,0x84,0xae,0x6f,0xe7,0x17,0x40,0x9b,0xa3,0xe7,0xec,0xbe,0x6c,0x69,0x4b,0xd1,0x85,0x25,0x3a,0x3,0xb0,0x68,0xc8,0x17,0x34,0xb0,0xb3,0x4a,0xc5,0x7e,0xb1,0xd0,0x4d,0xb6,0x19,0x3e,0x48,0x65,0x1c,0xaa,0xcc,0x6b,0x5c,0xaf,0xf6,0xa5,0x22,0x4e,0xc3,0x4f,0x59,0x1c,0xa2,0x9b,0x8b,0xb5,0xd5,0x78,0x5e,0x29,0x69,0xd5,0x83,0x52,0x81,0xa7,0x5b,0x73,0x35,0x48,0xb4,0x0,0x32,0x84,0x88,0xd8,0x75,0x6d,0xa9,0xc9,0xb4,0x10,0xc3,0xa1,0xe6,0x4,0xc0,0xa1,0x5f,0x2e,0xb1,0xde,0xdf,0x43,0xbf,0x58,0xe2,0xaf,0xbe,0xfd,0x23,0xfc,0xe5,0xb7,0x1f,0x94,0xb6,0xf3,0x9c,0xda,0xb6,0xdf,0x92,0x33,0x62,0xbf,0x0,0x0,0xac,0x57,0x7b,0xe8,0xba,0x5,0x0,0xad,0x68,0xec,0x17,0x53,0x7b,0xaf,0xce,0xde,0x73,0x2e,0xc0,0x85,0xda,0x8e,0xc3,0x39,0x8f,0x7e,0xb9,0x23,0xb3,0xe,0x65,0xac,0xe5,0x46,0x5,0x67,0xd6,0xf9,0x7e,0xeb,0xd5,0x3e,0xba,0xbe,0x6f,0x15,0x8f,0x45,0xe7,0xa,0xae,0xd7,0xfb,0xe8,0x3a,0xb9,0x1f,0x3b,0x6e,0xa7,0xed,0xd0,0x36,0xcf,0xcf,0xcd,0x16,0xd2,0x38,0x0,0xf0,0x4e,0x8f,0xdf,0x16,0xd7,0x58,0x1b,0x37,0x9b,0x12,0x88,0x88,0x88,0x88,0x88,0x2e,0x15,0x6,0x80,0x44,0x44,0x17,0xe0,0x43,0xd4,0xe5,0xa7,0x36,0xaf,0x4c,0x43,0xa6,0xe0,0x65,0xe6,0x9b,0xb6,0x35,0x7a,0xef,0x91,0x86,0xa1,0x55,0xee,0xd5,0x52,0x37,0x2,0x1f,0xe7,0x64,0x39,0x82,0xb5,0x9f,0xa6,0x51,0x66,0xd8,0x95,0x24,0x1,0x8d,0xcc,0x59,0x93,0x56,0x5e,0xaf,0x5b,0x6a,0x6b,0x39,0x66,0x1a,0x5a,0x45,0xab,0x56,0x5b,0xaf,0xce,0xc3,0x87,0xa8,0x15,0x6f,0x5,0x49,0x97,0x56,0xc8,0x8c,0xbf,0x11,0xe3,0xb0,0x46,0xad,0x80,0xf7,0x32,0x5c,0x2d,0x84,0xae,0x6d,0xa6,0xb5,0xe3,0xb2,0x6a,0x3f,0xa0,0xc2,0x5,0xd7,0xb6,0xbc,0x66,0xa0,0x55,0xd9,0xf9,0xe2,0xa7,0x76,0x57,0x6d,0xf,0xb5,0xd,0xb0,0x16,0x20,0x42,0x3f,0x3e,0x69,0x65,0x1d,0x74,0xb9,0x88,0xbc,0xdd,0x6b,0x3b,0xaa,0xd3,0xf0,0x2f,0x21,0x46,0xf9,0xbc,0x94,0x92,0xb4,0x4,0x77,0x5a,0x65,0xb7,0xe8,0x91,0xd7,0x52,0x5,0x69,0x21,0x69,0xd4,0x50,0xaa,0x64,0x9,0xe8,0x6c,0x81,0xc9,0x62,0xb9,0xdb,0x9e,0x17,0x99,0x51,0x37,0xcd,0xec,0x93,0x85,0x2d,0x1e,0x1,0x51,0x1f,0xaf,0x2c,0x62,0xa9,0xb5,0xca,0x7c,0x45,0x3d,0x96,0x92,0x83,0xcc,0xdd,0xeb,0x17,0x18,0xd6,0xfb,0x8,0xfa,0x79,0xb9,0x24,0xd4,0x5a,0xb1,0x58,0xee,0xc8,0x63,0xd7,0x63,0xb1,0x6e,0x62,0x99,0xfd,0xe7,0x51,0xf4,0xbe,0xac,0x9d,0x58,0xde,0x35,0x9d,0x5f,0xb4,0xf0,0xb8,0x6c,0xb4,0xe,0xcf,0x83,0x43,0xb,0x2f,0x6d,0x7e,0x1f,0x6a,0x41,0x1a,0x6,0xd,0xfc,0x74,0xa9,0xc6,0x38,0xc0,0x41,0xe6,0x18,0xd6,0x5a,0x11,0x96,0x51,0x9f,0x5f,0x89,0xf,0xbb,0x6e,0xd1,0xc2,0x45,0x5b,0x78,0xd2,0x75,0x3d,0xc6,0x71,0x90,0x90,0x71,0x1c,0xe1,0x63,0x87,0x94,0x6,0x59,0x44,0x33,0x9b,0xdb,0x28,0xed,0xbd,0xb5,0x55,0x8a,0x7a,0x6b,0x77,0xd7,0xeb,0xbe,0xd3,0x5,0x36,0xed,0xef,0x85,0x2d,0x14,0xd1,0x50,0xdb,0x2a,0x3c,0xad,0x2,0xd1,0x3b,0x8f,0xe2,0x6c,0x5b,0xf4,0xd4,0x96,0x9c,0xad,0x25,0x59,0xaf,0x87,0x52,0xa6,0x2a,0xc0,0x5a,0xe6,0x33,0x2d,0x89,0x88,0x88,0x88,0x88,0xe8,0xa2,0x7e,0x6f,0xcb,0x53,0x40,0x44,0xf4,0xa,0x74,0x3e,0x99,0xac,0xc0,0xb5,0x3f,0x3a,0xd9,0x2,0xbb,0x11,0xf4,0x0,0x39,0x8f,0x12,0xf4,0xe9,0xac,0xb9,0x34,0x8e,0x52,0xd5,0x57,0x2d,0xc,0xa9,0x6d,0xc6,0x5e,0x1a,0x6,0x69,0x99,0xcd,0x19,0xe3,0x38,0x60,0x1c,0xd7,0x1a,0xee,0x65,0xd,0xba,0x8e,0x79,0x89,0xd6,0x0,0x6a,0x58,0xef,0xc3,0xfb,0xa8,0x2d,0xc9,0x15,0x3e,0x4a,0x7b,0x27,0x6a,0x45,0xd6,0x36,0x50,0x3f,0x9b,0x3,0x37,0xac,0x57,0x6d,0xc3,0xaf,0xcd,0xc4,0xab,0x55,0x16,0x4e,0x58,0x50,0x57,0x6b,0xc5,0x7a,0xb5,0xf,0x0,0xda,0xc6,0x2b,0x3f,0x27,0xf2,0x21,0xe8,0xaf,0x38,0x2d,0xe4,0x88,0x1d,0xfa,0xe5,0xe,0x42,0x8c,0xe8,0xfa,0x5,0x62,0xbf,0x80,0xf7,0x1,0xb1,0x5f,0xe8,0xa6,0x60,0xa9,0xb2,0xb3,0x50,0xc9,0xaa,0xee,0xa0,0xed,0xbd,0x39,0x8f,0x72,0x1b,0xda,0xea,0x2b,0x9b,0x86,0x97,0xc8,0x69,0x44,0xbf,0x5c,0xca,0xe7,0x6b,0x48,0x37,0xe,0x83,0x2c,0xd,0x9,0x11,0x31,0x46,0x99,0x61,0x17,0x42,0x6b,0x2b,0xb5,0xd9,0x80,0xb1,0xef,0xb5,0xc2,0x31,0x6a,0x78,0x38,0xb6,0xf3,0xd0,0xaa,0x4,0x9d,0x43,0xa7,0xf3,0xfc,0x4a,0x4e,0x6d,0xa6,0x1f,0xac,0x32,0xaf,0x5f,0xc0,0xc7,0x88,0x7e,0xb9,0x83,0xae,0x5f,0xa0,0x96,0x69,0xe6,0x63,0x8c,0x1d,0x16,0xcb,0x1d,0x5d,0x7a,0x2,0x54,0xd4,0xd6,0xfe,0xb,0x3d,0x3e,0xab,0x0,0xb5,0xd9,0x7c,0xde,0x4d,0x33,0xf2,0xec,0x18,0xfc,0xec,0xb8,0x6d,0x1b,0x71,0xd4,0x70,0xd2,0x39,0x9d,0x3d,0xa9,0x15,0x88,0x76,0x2d,0x75,0x7d,0x8f,0x6e,0xb1,0x6c,0x8f,0xb9,0xb4,0x45,0x1b,0x3a,0xaf,0x51,0x97,0x9f,0x78,0x5d,0xfa,0xe1,0x9c,0x6f,0x6d,0xc1,0x16,0xce,0xc9,0x22,0x94,0x5e,0x42,0x5a,0xdd,0x5c,0xed,0x9c,0x6f,0x8f,0x21,0x68,0x4b,0xba,0xcd,0xfb,0xb3,0x59,0x8b,0x5e,0xdf,0x17,0x62,0x44,0xb0,0xe7,0xd5,0x4d,0xcb,0x5e,0x6c,0x31,0x8a,0x55,0xfa,0xd9,0x8c,0x43,0x67,0x15,0xa0,0xfa,0xf7,0xc4,0x96,0xb3,0xb4,0xd0,0xf,0xba,0x49,0xbb,0x85,0xa1,0x1d,0x9c,0xb,0x7c,0xcd,0x21,0x22,0x22,0x22,0x22,0xba,0xc8,0x58,0x1,0x48,0x44,0x74,0x1,0xd6,0xc6,0x38,0x5f,0x54,0x60,0x29,0xa0,0xee,0xd9,0x68,0x5b,0x66,0xbd,0x9b,0xb6,0xbf,0x5a,0xd5,0x97,0x8f,0x6e,0x36,0xfb,0xad,0xd7,0xd,0xbf,0x1d,0x80,0x2a,0x95,0x53,0xb3,0x8d,0xb5,0x56,0xd9,0x67,0x9b,0x6f,0xe7,0x8b,0x1f,0x36,0x54,0x5d,0xb0,0xd0,0xf5,0xb2,0x85,0x58,0x97,0x7c,0x78,0x9b,0xc7,0xe6,0x3d,0x4a,0x1e,0x75,0x26,0x60,0x46,0xd7,0x2d,0x5a,0xcb,0x6e,0x2e,0x49,0x3e,0x27,0x4c,0x2f,0xff,0x55,0x67,0xbb,0x85,0x18,0x91,0xd3,0xa8,0xb,0x22,0x3a,0xd,0x64,0x62,0xab,0x6a,0x1b,0xc7,0x35,0xfa,0xae,0x97,0xb9,0x73,0x29,0xc9,0xbc,0xbe,0xd8,0x21,0xa5,0x84,0xaa,0xe7,0xa1,0xd6,0xa,0x97,0x81,0x6e,0xb1,0xd3,0xda,0x6d,0x6b,0xad,0x18,0x73,0x42,0x74,0x11,0xb5,0x24,0xf8,0x28,0xa1,0xe4,0x62,0xe7,0x84,0x9c,0x57,0x6d,0x33,0xed,0x16,0x4b,0xe4,0x24,0xed,0xc1,0x72,0x4e,0x0,0xf8,0xcd,0x5,0x1e,0x31,0x78,0xa4,0x14,0x74,0x4e,0x9e,0xce,0x49,0x74,0x40,0xec,0x16,0x58,0xa7,0x3d,0x44,0xdf,0x21,0xd7,0x11,0x80,0x6f,0x81,0xa5,0x6d,0xee,0xd,0xb1,0x43,0x2a,0x83,0x6e,0x13,0xd6,0x19,0x8c,0xdd,0xa2,0x6d,0xbb,0x95,0xa0,0xd4,0x96,0x38,0x57,0xad,0x72,0xac,0xe8,0x16,0x4b,0x39,0xaf,0xd1,0x16,0x78,0x48,0x6b,0x74,0x8,0x5d,0xab,0x4c,0xf4,0x6d,0xfe,0x9f,0x47,0x1e,0x13,0x76,0x76,0x76,0x90,0x72,0x46,0xbf,0xdc,0x69,0x15,0x97,0x53,0x5,0xa3,0x84,0xa9,0x41,0x43,0xe1,0xa0,0xe7,0xa3,0xcd,0x90,0x6c,0x5b,0x8d,0xa7,0x5f,0x79,0x1c,0xe0,0x75,0xde,0x21,0x20,0x81,0x6c,0xd1,0xf6,0x61,0xbb,0x7f,0x79,0xe,0xbb,0xd6,0xa,0x6e,0x15,0x90,0x15,0x52,0x59,0xba,0x58,0xec,0xca,0xf9,0x9d,0x3d,0xbf,0x16,0xd8,0xf9,0x28,0xe7,0x2a,0x78,0xa7,0x41,0x28,0xa4,0x2d,0xd8,0xaa,0x24,0xf5,0xd8,0x6d,0xb6,0xa0,0x73,0xe,0x29,0x25,0xbd,0x66,0xd2,0x6c,0xf6,0xa4,0x3c,0x4e,0xaf,0x4f,0x59,0x2d,0xb2,0xfd,0xb7,0xe4,0x8c,0x52,0xb,0x42,0x90,0x6b,0x5f,0xaa,0x64,0x25,0x10,0xb7,0xdb,0x83,0x73,0x28,0x25,0x49,0x2b,0x70,0x65,0x25,0x20,0x11,0x11,0x11,0x11,0xd1,0xc5,0xc4,0x0,0x90,0x88,0xe8,0x2,0xa4,0x5,0x78,0xaa,0x74,0x6a,0xed,0x8e,0x6d,0xe3,0xab,0x4,0x19,0x41,0x43,0x3b,0xab,0x8c,0xaa,0xa5,0x20,0x97,0xda,0x16,0x7f,0xd4,0x52,0x75,0xfe,0x9e,0xb4,0x4c,0x76,0x61,0x89,0x9c,0x7,0xd4,0x92,0x91,0xb5,0x8d,0xd8,0x2,0xb0,0x29,0x10,0x3c,0xa6,0x5,0xd8,0x61,0x6a,0xb3,0x75,0x90,0x4d,0xc3,0xb5,0xa2,0x14,0x5d,0xca,0xa0,0xb7,0x97,0x34,0x4c,0xcc,0x79,0xda,0x38,0xc,0x37,0xb5,0xf8,0xb6,0x10,0x50,0x17,0x4f,0x60,0x5e,0x71,0xe6,0x1c,0x96,0x7d,0x8f,0x3b,0x5f,0x7f,0x3,0xde,0x7c,0xc7,0xad,0x78,0xed,0x35,0xaf,0xc1,0x89,0x9d,0x1d,0x84,0xe0,0x31,0x8c,0x23,0xf6,0x57,0x6b,0x3c,0xf9,0xf4,0x73,0xb8,0xff,0xc7,0x8f,0xe1,0x91,0x5f,0x3c,0x8b,0xb3,0xe7,0xcf,0xeb,0x56,0xd7,0xa2,0xf3,0x3,0x2b,0xe2,0x62,0xa9,0x33,0xfb,0xd6,0x1b,0x5b,0x7c,0x73,0x1a,0x71,0xe3,0xb5,0xaf,0xc1,0xeb,0x6f,0x7a,0x6d,0x3b,0xc7,0xb5,0x48,0xfb,0xf2,0x8f,0x7f,0xf6,0xc,0x5e,0x78,0xe9,0xc,0xe0,0x3,0xba,0x4e,0xda,0x55,0x6f,0xb8,0xe6,0xa,0x7c,0xe0,0xde,0xbb,0xf0,0xfa,0x5b,0xae,0xc7,0x72,0xb1,0xc0,0xf9,0xbd,0x7d,0x3c,0xf2,0xd8,0xe3,0xf8,0xea,0xb7,0xef,0xc7,0x63,0x4f,0xbf,0x38,0x6d,0xf4,0xed,0x24,0xfc,0xa,0xb1,0x43,0xf4,0xe,0xf7,0xbc,0xf1,0x56,0xf4,0x5d,0xc4,0x7c,0x59,0xc5,0x73,0x2f,0xed,0xe1,0xa1,0x5f,0x3c,0x5,0x0,0xad,0xc5,0x78,0xb9,0xe8,0xf1,0xab,0xef,0xb8,0x3,0x77,0xdd,0xf9,0x4b,0x38,0x7d,0xea,0x24,0x86,0x61,0xc0,0x13,0x4f,0x3d,0x8b,0x6f,0x7c,0xff,0xc7,0xb8,0xff,0xa1,0x5f,0xa0,0xd4,0x2,0x20,0x0,0x45,0xe6,0xed,0x95,0x9c,0xd1,0xf5,0xb,0xa4,0x61,0x40,0x17,0x16,0xb8,0xf1,0x9a,0xcb,0xf1,0xe6,0xdb,0x6f,0xc1,0xeb,0x6f,0xba,0xe,0x57,0x5c,0x7e,0xa,0x27,0x4e,0x9c,0x80,0x3,0x30,0x8e,0x23,0xf6,0x56,0x3,0x9e,0x78,0xf2,0x69,0x3c,0xf4,0xb3,0xa7,0xf0,0x83,0x87,0x7e,0x81,0xf3,0xfb,0x2b,0x7d,0x2e,0x6c,0xdb,0x70,0xaf,0xa1,0xaf,0x54,0x30,0x26,0xd,0xdd,0x74,0xed,0x34,0x4a,0xc9,0x78,0xcb,0x6d,0x37,0xe0,0xf2,0xd3,0xa7,0xb5,0xaa,0x4e,0xaa,0xc,0xcf,0x9c,0x3d,0x8b,0xfb,0x1f,0x7e,0x42,0xae,0x43,0xd,0xe6,0x6c,0x6e,0x61,0x88,0x1d,0x5e,0x77,0xfd,0xd5,0xb8,0xe6,0xca,0x53,0x8,0xad,0x2,0xd3,0x21,0xd7,0x8a,0xef,0x3e,0xf8,0x33,0xc,0xe3,0x80,0x92,0x13,0xfa,0xe5,0xe,0xae,0xb9,0xfc,0x24,0xde,0x7e,0xe7,0xad,0xb8,0xed,0xd6,0x1b,0x71,0xc5,0xe9,0xcb,0x74,0xae,0xdf,0x1a,0x2f,0xbc,0x74,0x6,0xf,0xfc,0xe4,0xa7,0xf8,0xce,0xf,0x1f,0xc5,0xb,0x67,0xce,0x21,0xe8,0xdc,0xc3,0xa2,0xd5,0xa9,0xb5,0xa2,0x5,0x97,0x76,0x1e,0x2d,0x24,0xb7,0xea,0x44,0x9,0x34,0xbb,0x76,0xcd,0x7b,0xc8,0x82,0x18,0x6b,0x13,0xb6,0x45,0x34,0x63,0x5a,0x6b,0x70,0xee,0xe0,0x43,0x8f,0x3c,0x9c,0xe3,0xb,0xf,0x11,0x11,0x11,0x11,0xd1,0x45,0xc6,0x0,0x90,0x88,0xe8,0x2,0x4a,0x4e,0x6d,0x23,0x6a,0x2e,0x69,0x63,0x7e,0x1b,0x0,0xb8,0xa,0x9d,0x5f,0x56,0x5a,0x3b,0x66,0xd0,0xb6,0x5b,0x40,0x43,0x19,0xe7,0x64,0xe1,0x45,0xbf,0x90,0x30,0xa4,0x64,0x8c,0xe3,0xba,0xcd,0x4d,0x73,0x0,0xa0,0x2d,0xba,0xb2,0xbd,0x57,0xaa,0xbc,0x8e,0xdb,0x2,0x6c,0x9b,0x67,0x4b,0x29,0x5a,0x39,0x66,0xdb,0x5b,0x23,0x86,0xf5,0xaa,0x5,0x2e,0xb2,0x88,0x23,0xc9,0xb2,0xf,0x9d,0x5f,0x57,0x72,0xd6,0xb9,0x70,0xeb,0x76,0xdf,0xfd,0x72,0x57,0x1e,0x17,0xa4,0x1a,0xef,0xf4,0xa9,0x5d,0x7c,0xec,0xfd,0xef,0xc0,0xbd,0xf7,0xbc,0x19,0x97,0x9f,0x3e,0x35,0x55,0xe0,0x1d,0xf0,0x86,0xd7,0xdd,0x8c,0xf7,0xbd,0xfb,0x6d,0x78,0xe1,0xc5,0x97,0xf1,0x95,0x6f,0xde,0x8f,0xbf,0xf8,0xc6,0xfd,0xd8,0xdb,0xdf,0x6f,0x73,0xf,0x51,0xab,0x56,0xf4,0xc9,0x9f,0xdb,0xb6,0x5c,0xe7,0x70,0xc7,0x6d,0xb7,0xe0,0xbf,0xf8,0x7,0x1f,0xdb,0xb8,0xbd,0x5a,0x2b,0xfe,0x8f,0x7f,0xf5,0x39,0xfc,0xcd,0xbe,0x2e,0xf6,0x8,0xe,0x1f,0xbc,0xf7,0x2e,0x7c,0xec,0x83,0xef,0xc5,0xc9,0x13,0xbb,0xed,0xe3,0xae,0x6,0x70,0xeb,0xcd,0x37,0xe0,0xbd,0xef,0xba,0x7,0xdf,0xf9,0xde,0xf,0xf1,0xd9,0x7f,0xff,0x35,0x9c,0xdf,0x1f,0xa4,0xd5,0x55,0xab,0xf0,0x4e,0x9f,0x58,0xe0,0x77,0x7f,0xeb,0x13,0xd8,0x59,0x2e,0x37,0xee,0xe3,0x1b,0xdf,0xb9,0xf,0xf,0xff,0xe2,0x69,0x9,0xad,0x6a,0xc1,0x2d,0xd7,0x5e,0x81,0xdf,0xfd,0x7,0x1f,0xc1,0x75,0xd7,0x5e,0xbd,0xf1,0x38,0xaf,0xbf,0xee,0x5a,0xbc,0xed,0xad,0x77,0xe2,0xb1,0x9f,0x3f,0x81,0x3f,0xfc,0xfc,0x97,0xf0,0xc8,0x13,0xcf,0x4e,0xcf,0x15,0x2a,0xbc,0x8f,0xf8,0xa5,0x5b,0x6e,0xc0,0x27,0x3f,0xf4,0x6e,0xbc,0xe1,0x75,0x37,0x61,0xb1,0xe8,0x8f,0x3d,0x4f,0xb7,0xdd,0x7a,0x23,0xde,0xf7,0xcb,0x15,0xcf,0xbf,0xf8,0x32,0xbe,0xfc,0xf5,0xef,0xe1,0x4b,0xdf,0x7a,0x0,0x43,0xca,0x6d,0x7b,0x71,0x88,0x1d,0x86,0xf5,0xbe,0xcc,0x53,0x8c,0xb2,0x68,0xc5,0x82,0xd8,0x52,0xa,0x7e,0xf3,0xe3,0xbf,0x8a,0x9b,0x6e,0x78,0xed,0xc6,0x6d,0x3e,0xfb,0xfc,0x8b,0xf8,0xc1,0x3f,0xfb,0x8c,0x54,0xd5,0xd9,0x42,0x12,0xbd,0x26,0x6a,0x4e,0xf8,0xe0,0x7b,0xee,0xc1,0x2f,0xbf,0xf3,0xad,0x1b,0x9f,0xb3,0x5e,0xf,0xf8,0xe9,0xff,0xfc,0x19,0xbc,0x78,0x6,0x78,0xcd,0xe9,0x93,0xf8,0xd4,0x87,0xdf,0x8d,0xbb,0xdf,0x7c,0x7,0x96,0xcb,0xc5,0xa1,0x63,0xbe,0xe9,0xc6,0xeb,0x71,0xf7,0x5b,0xde,0x88,0x8f,0x7d,0xe8,0xc,0xfe,0x9f,0x2f,0x7e,0xd,0x5f,0xfa,0xd6,0xf,0x91,0x72,0xd1,0xb9,0x94,0xb9,0xcd,0x2a,0xac,0xe8,0x30,0xae,0xf7,0xe5,0xfa,0x1a,0x74,0xb6,0x64,0xc9,0x6d,0xe6,0x1f,0x1c,0x74,0x9e,0x65,0x69,0x6d,0xd2,0x56,0x45,0x58,0x31,0x2d,0x7a,0xb1,0xeb,0xba,0x64,0xb9,0x2e,0xe7,0xf3,0x6,0x89,0x88,0x88,0x88,0x88,0xe8,0x3f,0x1d,0x3,0x40,0x22,0xa2,0xb,0xf0,0xa1,0x9b,0x2d,0x43,0xa8,0x28,0xb5,0xb6,0x5,0x1f,0xf6,0xab,0xb4,0xb9,0x67,0x5,0x1e,0x15,0x69,0xac,0x6d,0xa3,0xae,0xf3,0x1e,0x3e,0x58,0xb5,0x97,0x6f,0x21,0x9b,0x6d,0x6e,0xad,0xda,0x2,0x9,0xad,0x24,0xcc,0x59,0x16,0x34,0x54,0x54,0xe0,0x98,0x0,0x10,0x0,0x52,0x1a,0xa5,0xaa,0x70,0xbd,0x42,0xd4,0xd,0xb9,0xab,0xfd,0x73,0xc8,0x29,0x21,0x8d,0x3,0xc6,0xf5,0xa,0x3e,0xc6,0xb6,0x51,0xd7,0x5a,0x47,0x73,0x4e,0x3a,0x63,0x6f,0xb7,0x55,0x18,0xca,0x2c,0x41,0x99,0xf7,0x77,0xcf,0x1d,0xb7,0xe0,0x1f,0xff,0xe6,0xc7,0x70,0xf5,0x55,0xaf,0xc1,0x31,0x79,0xd6,0x6,0xe7,0x1c,0x5e,0x73,0xe5,0xe5,0xf8,0x7b,0x1f,0x7d,0x1f,0xee,0xb8,0xed,0x26,0xfc,0xeb,0xcf,0x7d,0x11,0xcf,0xbd,0x74,0xe,0xce,0x4b,0x20,0x15,0x2d,0xfc,0x4b,0xa3,0x2e,0xc0,0xf0,0x8,0xe1,0xb8,0x16,0x4f,0xd7,0x2a,0x14,0x1,0xe0,0x93,0x1f,0x78,0x1b,0x3e,0xfc,0xfe,0x77,0xc9,0xc7,0x1f,0x61,0xb9,0xe8,0xf1,0xde,0x77,0xdd,0x83,0x5b,0x6e,0xba,0xe,0x9f,0xf9,0xec,0x7f,0xc0,0xcf,0x9f,0x79,0xa9,0x2d,0xd,0xf1,0xb3,0x4d,0xc0,0x7,0xef,0x23,0x76,0x3d,0x62,0xd7,0xe3,0xd,0xd7,0x9d,0xc6,0xef,0xfd,0xf6,0x6f,0xe0,0xd4,0xc9,0xdd,0x23,0x6f,0x3f,0x4,0x8f,0xd7,0xdf,0x7a,0x23,0xfe,0xdb,0x7f,0xfa,0x69,0x7c,0xee,0xcf,0xbe,0x82,0xaf,0x7c,0xef,0xa1,0xb6,0xc1,0xf8,0xa3,0xef,0x79,0x2b,0x7e,0xfd,0x3,0xf7,0x62,0x77,0x67,0xf9,0xaa,0xae,0x23,0xe7,0x1c,0xae,0xd2,0xf3,0xf4,0xfa,0x9b,0xaf,0xc3,0xbf,0xfc,0xe3,0x2f,0xe2,0x5c,0xd6,0xad,0xc3,0x80,0xce,0x23,0xcc,0xa8,0xb5,0xa0,0xef,0x17,0x70,0xba,0x2c,0x4,0x69,0x3c,0x32,0xa,0x73,0x90,0xb6,0xe5,0x10,0x7a,0xd4,0x92,0x31,0xe,0xb2,0xe8,0x23,0xc6,0x5e,0x2b,0xc,0xcb,0x51,0x7,0x81,0x10,0x3a,0xdc,0x75,0xfb,0x55,0xf8,0x47,0x9f,0xfc,0x55,0x5c,0x71,0xf9,0xe9,0x57,0x3c,0xee,0x2b,0x4e,0x5f,0x86,0xdf,0xfe,0xd4,0x47,0xf0,0xba,0x9b,0xaf,0xc7,0xff,0xf9,0x47,0xff,0x1e,0x9,0x68,0x73,0x21,0x93,0x1e,0xaf,0x73,0x72,0xae,0x7d,0x90,0x30,0xd3,0x25,0xaf,0x95,0xac,0xf2,0x18,0xc6,0x61,0xdd,0xfe,0xae,0xc8,0xa5,0x5e,0x64,0x3b,0x75,0x9e,0x5f,0x3,0x55,0xb7,0x6d,0x47,0x54,0x8c,0x7c,0xe1,0x21,0x22,0x22,0x22,0x22,0xba,0xd8,0xdf,0xdb,0xf2,0x14,0x10,0x11,0x5d,0xe0,0x45,0x32,0xc4,0x56,0xa1,0xe4,0x9c,0xcc,0x54,0xf3,0x5e,0x66,0xa7,0x55,0xd4,0xb6,0xd8,0x40,0xe6,0xf9,0xc9,0xdc,0x3f,0x68,0xb,0xb0,0xd7,0x20,0xab,0xe4,0x4,0x7,0x99,0x99,0x96,0x86,0x1,0x15,0x40,0x1a,0x65,0x59,0x48,0xcd,0x59,0x42,0xb9,0x9c,0x31,0xac,0xf7,0x31,0xc,0x6b,0xac,0x57,0xfb,0xc8,0x29,0x1,0x38,0x3a,0x81,0x2b,0x5a,0xc9,0x27,0x9f,0x27,0x4b,0x46,0xc6,0x61,0xad,0x15,0x7f,0x23,0x86,0x95,0x54,0x64,0x8d,0xeb,0x15,0xd6,0xab,0x7d,0xec,0xef,0x9d,0x45,0x1a,0x6,0x59,0x46,0xa2,0xe1,0x65,0x1e,0x7,0xac,0xf7,0xcf,0x63,0xbd,0xda,0x93,0xe3,0x40,0xc5,0x47,0xde,0xf3,0x56,0xfc,0xd7,0xbf,0xf7,0x5b,0xb8,0xe6,0xea,0x57,0x17,0xfe,0xcd,0x39,0x7,0xdc,0xf1,0x86,0x5b,0xf0,0x5f,0xfd,0xe3,0xdf,0xc0,0xe5,0x97,0x9d,0x94,0x39,0x7b,0x3a,0xff,0xcf,0x7b,0x9d,0x2f,0xa7,0xdb,0x69,0x43,0x8c,0x8,0xfe,0xa8,0x45,0xf,0x15,0x21,0x4,0xf4,0x8b,0x25,0x3e,0xf4,0xae,0x37,0xe3,0xc3,0xef,0xbf,0xf7,0xd8,0xf0,0x6f,0xee,0x86,0xeb,0xae,0xc5,0x3f,0xfa,0xe4,0x7,0x74,0xb9,0x4a,0x69,0x1,0xdf,0x51,0xc1,0x99,0x85,0x8b,0xd7,0x5e,0x71,0x2,0xff,0xe5,0x6f,0x7d,0xe2,0xd8,0xf0,0x6f,0xee,0xc4,0xee,0x2e,0x3e,0xf5,0xd1,0xf7,0xe3,0x9a,0x2b,0x4e,0x21,0x84,0x80,0x8f,0xbd,0xf7,0xad,0xf8,0x8d,0xf,0xbf,0xe7,0x55,0x87,0x7f,0x9b,0xf7,0x1f,0x70,0xd7,0x9d,0xbf,0x84,0xdf,0xfb,0xf4,0x87,0x70,0xea,0xb2,0xd3,0xba,0xbc,0xa4,0xd3,0x45,0x1d,0x68,0x33,0x6,0xbd,0xf7,0x58,0xed,0x9f,0x97,0x10,0xed,0x88,0xeb,0xe0,0xe0,0x7c,0xc6,0x9d,0x13,0x27,0xa5,0xea,0xce,0x4d,0x8b,0x3d,0x8e,0xf2,0xc6,0xd7,0x5d,0x87,0xdf,0xfd,0xf4,0x47,0x5e,0x55,0xf8,0x37,0xbf,0xaf,0x77,0xdc,0xf3,0x66,0xfc,0xce,0x27,0xde,0x87,0xe5,0xce,0x8e,0x6c,0xba,0xd6,0x79,0x83,0xce,0x7b,0x99,0x69,0xa9,0xed,0xbc,0x39,0x8d,0xda,0x16,0x1c,0x1,0xd4,0x56,0xe1,0x67,0xcb,0x40,0x42,0xd0,0x5,0x22,0xba,0xcd,0x18,0x7a,0x7d,0xc8,0xf1,0x56,0xa0,0x32,0xfc,0x23,0x22,0x22,0x22,0x22,0xba,0x24,0xdf,0xdb,0xf2,0x14,0x10,0x11,0x1d,0x2f,0xd,0xfb,0x6d,0x76,0x9e,0x54,0x0,0x96,0x36,0xaf,0xcc,0xc2,0xd,0xa9,0x64,0x72,0x12,0xd4,0xd8,0x32,0x10,0x0,0xb6,0xf1,0xb7,0x94,0xaa,0x2d,0xb9,0xd3,0x8c,0x40,0x6f,0x5b,0x12,0xf4,0x76,0x0,0x9b,0x49,0x17,0x5a,0x78,0x57,0xf2,0xd1,0x61,0x48,0x29,0x5,0xeb,0xfd,0x3d,0xc,0xab,0x3d,0x38,0x1f,0x30,0x8e,0x6b,0xa9,0xfa,0x1b,0xd6,0xd2,0x2,0x8a,0x8a,0xd5,0xfe,0x79,0x94,0x9c,0xb1,0x77,0xee,0x65,0xc,0xab,0x7d,0xec,0xef,0x9d,0xc3,0x6a,0xff,0x3c,0xd6,0xfb,0xe7,0x90,0xc6,0x1,0xeb,0xd5,0x1e,0x9c,0xb6,0xcc,0xd6,0x5a,0xf0,0xde,0x7b,0xee,0xc0,0x3f,0xfc,0xd4,0x47,0xb1,0x58,0xf4,0x47,0xde,0x67,0xad,0xc0,0x30,0x26,0xac,0x56,0x6b,0xc,0xe3,0x38,0x5b,0x88,0xb2,0xe9,0x86,0xeb,0xae,0xc6,0x3f,0xf9,0xe4,0xfb,0x65,0x9b,0x6e,0xd7,0xa3,0xeb,0x7a,0xf8,0x10,0xd0,0x69,0x28,0x27,0x1b,0x80,0x77,0x0,0x7f,0xf4,0x97,0x9f,0x52,0x81,0x5b,0xae,0xbd,0x1c,0x9f,0xf8,0xe0,0xbb,0x65,0xb9,0xca,0xab,0x79,0x8e,0x52,0xc6,0x5f,0x7d,0xf3,0x7e,0x74,0x7d,0xdf,0xb6,0xd8,0x4a,0x66,0x76,0xc4,0x31,0x3a,0xe0,0xb2,0x93,0xbb,0xf8,0xcf,0x3f,0xf5,0x6b,0xb8,0xec,0xd4,0x89,0x57,0x7d,0x1d,0xfc,0xe0,0x47,0xf,0xe1,0x99,0x17,0xcf,0x20,0x84,0xe,0xf7,0xde,0x73,0x27,0x62,0xfc,0x8f,0x2f,0xa0,0x77,0xce,0xe1,0x2d,0x6f,0xbc,0xd,0xef,0x78,0xe3,0x4d,0xe8,0xfb,0xa5,0x54,0xec,0x69,0xb5,0x68,0x5b,0xa2,0xa1,0x41,0x68,0x45,0x45,0x39,0xa2,0x5a,0xb2,0x68,0x85,0x9f,0xcc,0x54,0x4c,0xd0,0x4b,0x52,0xde,0x67,0xdb,0x81,0xf,0x88,0x21,0xe0,0xd3,0x1f,0xff,0x0,0x4e,0xec,0xee,0xb4,0xb7,0xad,0x87,0x11,0x3f,0x7f,0xfc,0x29,0x3c,0xf8,0xd0,0x63,0x78,0xf8,0xd1,0x5f,0xe0,0xa5,0x97,0xcf,0x1c,0xb9,0x7c,0xc6,0x3b,0x87,0xf7,0xdc,0x7b,0x37,0xee,0x7c,0xdd,0x75,0xb3,0xf0,0x4f,0x36,0xa,0x67,0xad,0xe4,0xab,0xba,0x71,0xb8,0x2d,0xf5,0x80,0xd3,0x25,0x2d,0xe,0xce,0xdb,0x1c,0x4d,0xdf,0xda,0xe8,0x4b,0x91,0xe0,0xd9,0x36,0x35,0xcb,0xfd,0x72,0x3,0x30,0x11,0x11,0x11,0x11,0xd1,0xa5,0xc0,0x16,0x60,0x22,0xa2,0xb,0xf0,0xa1,0x9b,0xb2,0xa4,0x2a,0x31,0x9f,0x85,0x2f,0xe,0xe,0x39,0xe7,0x16,0xe8,0x59,0x3b,0x67,0xf1,0x68,0x1b,0x78,0xfb,0xc5,0x4e,0x6b,0x93,0x6c,0x9b,0x84,0x6b,0x45,0x9e,0x85,0x28,0xa8,0x52,0xd5,0x97,0xd2,0x28,0xf3,0xfb,0x2c,0x60,0x3b,0xa6,0xc,0xcf,0xe6,0xbd,0x55,0xd,0x23,0x73,0x1a,0x25,0x84,0xd1,0x50,0x65,0xbd,0xda,0x87,0x73,0xe,0xab,0x61,0xaf,0x55,0x94,0x39,0xa7,0xb,0x18,0xbc,0x9f,0x2,0x9b,0x52,0x10,0xba,0x1e,0x37,0x5e,0x7d,0x1a,0xbf,0xf3,0x9b,0x9f,0x40,0xdf,0x75,0x87,0xee,0x6b,0x7f,0x7f,0x85,0x7,0x1f,0xfe,0x39,0xbe,0xf7,0xc0,0x4f,0xf1,0xf4,0x8b,0x67,0x91,0x72,0xc1,0xa2,0xeb,0x70,0xd5,0xe9,0x1d,0xbc,0xe3,0xae,0xdb,0xf1,0xa6,0x37,0xdc,0x74,0x28,0xc,0xbb,0xf3,0x8e,0xd7,0xe1,0x7d,0xf7,0xdc,0x8e,0xbf,0xfe,0xfe,0x43,0x28,0xba,0x29,0x39,0x17,0x6d,0xcb,0x75,0x1d,0xd6,0xab,0x3d,0x1c,0xf7,0xf3,0xa7,0x45,0xd7,0xe1,0x63,0x1f,0x78,0x67,0x9b,0x4b,0xb7,0xb7,0xbf,0xc2,0x93,0x4f,0x3f,0x8f,0x67,0x9e,0x7f,0x11,0xcb,0xc5,0x2,0x37,0x5f,0x7f,0x35,0xae,0xbc,0xe2,0xf4,0xc6,0xbc,0xbd,0x9f,0x3c,0xf2,0x18,0xbe,0xfd,0xc0,0x63,0x80,0x73,0x48,0xa3,0xcc,0xcf,0x4b,0xc3,0x70,0x64,0xe5,0x5c,0x2d,0x5,0x1f,0x7d,0xef,0xdd,0xb8,0xe9,0xfa,0x6b,0x1,0x48,0x98,0xfa,0xd4,0x33,0xcf,0xe3,0xf1,0xa7,0x9e,0x45,0xca,0x5,0x37,0x5f,0x7f,0x2d,0xae,0xbd,0xe6,0x4a,0xc4,0x59,0xf8,0xf8,0xf2,0x99,0x73,0xf8,0x77,0x5f,0xb9,0x4f,0xc2,0xd5,0x3a,0x1c,0x79,0xdc,0xe3,0x98,0xf0,0xf4,0xb3,0x2f,0xe0,0x89,0xa7,0x9f,0xc3,0xcb,0x67,0xcf,0x21,0x84,0x88,0xcb,0x4e,0x9d,0xc0,0xcd,0xd7,0x5f,0x83,0x6b,0xae,0xba,0xe2,0xc8,0xe7,0xf0,0x7d,0xf7,0xbe,0x5,0x5f,0xbb,0xff,0xa7,0xf0,0x3e,0xa2,0xa2,0xb4,0x96,0xd9,0xde,0x79,0x69,0x9b,0x85,0x43,0xec,0x3a,0xb8,0x23,0xce,0x95,0x73,0x1e,0x31,0x4,0xc,0x69,0x44,0xd7,0xcb,0x96,0x62,0x5b,0x42,0x93,0xd2,0x88,0xa3,0xc2,0xcf,0x10,0xa4,0x65,0x58,0x8e,0x77,0xc4,0xb7,0xef,0xfb,0x31,0xfe,0xe2,0x6b,0xf7,0xe1,0xd9,0x97,0xce,0x49,0x6b,0x7b,0xad,0xd8,0x5d,0x2e,0x71,0xef,0x9b,0x6f,0xc5,0xc7,0x7f,0xed,0x5d,0x87,0x2a,0x1c,0xfb,0xbe,0xc3,0x47,0xde,0x7f,0x2f,0xbe,0xff,0x93,0x9f,0xcb,0xb9,0x1b,0x65,0x53,0xb5,0x2d,0x95,0xf1,0xbe,0xc7,0xb0,0x5e,0xe9,0xf2,0x12,0xb9,0xbe,0x53,0xd2,0xd,0xc8,0x29,0xe9,0xe6,0xe0,0xb1,0x5,0x80,0xb6,0x29,0x5b,0xaa,0x3,0xb5,0xe5,0xfd,0x6f,0x5b,0x7a,0x4a,0x44,0x44,0x44,0x44,0x44,0xaf,0xa,0x3,0x40,0x22,0xa2,0xb,0x28,0x79,0x94,0x79,0x7c,0xfa,0xff,0x52,0xe4,0xe7,0x50,0xab,0x44,0x2c,0x16,0x44,0x59,0xc8,0x67,0x33,0xce,0x4a,0xc9,0x1b,0xdb,0x4e,0x6d,0xb3,0x6b,0x4e,0x9,0x3e,0xf8,0x56,0x25,0x55,0x72,0x96,0x25,0x21,0x45,0x36,0xcb,0x9a,0x10,0x23,0x2e,0x14,0x85,0xc4,0xd8,0xb5,0xa5,0x1e,0x16,0x2,0xa6,0x71,0x90,0xf9,0x77,0x4e,0xaa,0xc2,0x64,0xde,0x5e,0xd4,0x0,0xd0,0x1,0xce,0x4f,0xcb,0x19,0x0,0xe4,0x34,0x62,0xb1,0x58,0xe2,0xb7,0x3f,0xf5,0x51,0x5c,0x71,0xf9,0x65,0x87,0xee,0xe3,0x99,0xe7,0x5e,0xc0,0xef,0x7f,0xee,0x8b,0x78,0xf4,0xa9,0x97,0x10,0x3b,0x99,0x2d,0xe7,0xbd,0x87,0xf3,0x3,0x9e,0x79,0xf1,0x2c,0x7e,0xf8,0xd8,0xb3,0x78,0xeb,0x6d,0xaf,0xc5,0x3f,0xfc,0xf8,0xfb,0xb0,0x33,0xb,0x8b,0x9c,0x73,0xf8,0xc0,0x2f,0xdf,0x8d,0xef,0x3c,0xf8,0x18,0xd6,0x63,0x6e,0x4b,0x2d,0x0,0x79,0xfc,0x7d,0xbf,0x3c,0x36,0xe7,0x79,0xcb,0xed,0x37,0xe3,0xc6,0xeb,0xae,0x46,0x29,0x5,0xf,0xfc,0xe4,0x31,0xfc,0xc9,0x5f,0x7c,0x13,0x4f,0xbf,0x78,0x4e,0x67,0xda,0x39,0xec,0x2c,0x3a,0xbc,0xe3,0x4d,0x37,0xe3,0x23,0xef,0x7f,0x27,0x2e,0x3b,0x75,0x12,0xe7,0xf7,0xf6,0xf1,0x87,0x7f,0xfa,0x65,0x38,0x1f,0xd0,0xf9,0x4e,0x2b,0x2e,0x33,0x7c,0x58,0x1e,0xd9,0x2,0x7c,0xf2,0xe4,0x2e,0xde,0xf2,0xc6,0xdb,0xe0,0x9c,0xc3,0xf3,0x2f,0xbe,0x8c,0x3f,0xfe,0xb3,0x2f,0xe3,0xbe,0x87,0x9e,0x68,0x5b,0x6d,0x73,0x4a,0x78,0xe3,0x2d,0xd7,0xe2,0xe3,0xbf,0xf6,0x4e,0xdc,0x7a,0xd3,0xf5,0xc8,0xb9,0xe0,0xb,0x5f,0xfc,0x2a,0x9e,0x79,0xfe,0x45,0xa9,0xd0,0xb4,0x56,0x55,0xb5,0x5a,0xf,0xf8,0x9b,0xfb,0x1e,0xc4,0x97,0xbe,0xf9,0x0,0x9e,0x7d,0x79,0x1f,0xa5,0x64,0xc4,0x4e,0x9e,0x9b,0xc5,0x72,0x17,0xc8,0x23,0x3e,0x74,0xef,0x9b,0xf0,0xa1,0x5f,0x79,0xfb,0xa1,0x76,0xe6,0xab,0xaf,0xba,0x12,0x37,0x5e,0x73,0x5,0x7e,0xfe,0xd4,0xb,0x70,0xce,0x36,0x4c,0xcb,0x35,0x14,0x63,0x7,0xe7,0x3,0x4a,0x49,0xc7,0xce,0x82,0x74,0x21,0xc0,0xa5,0x84,0xd8,0xd9,0x12,0x91,0xc,0x87,0x69,0x46,0xdf,0x71,0xce,0x9d,0xdf,0xc7,0x1f,0xfd,0xe9,0x5f,0xe1,0xfe,0x47,0x9e,0xd4,0x8a,0x51,0x89,0x4a,0x53,0x1a,0xb1,0xbf,0x5e,0xe3,0x4b,0xdf,0x7a,0x0,0x67,0xcf,0x9e,0xc3,0x3f,0xf9,0xf4,0x47,0x75,0x8b,0xf2,0xe4,0x96,0x9b,0xaf,0xc7,0xd,0xd7,0x5c,0x89,0x5f,0x3c,0xfd,0x3c,0x9c,0xf,0x12,0x4d,0xd6,0x8a,0x94,0x24,0x7c,0xf4,0x7e,0x33,0x70,0x46,0x95,0xed,0xd9,0xd5,0xf9,0x56,0xe9,0x8,0xab,0x74,0xac,0xb2,0xbc,0x46,0x16,0xe8,0x40,0xe6,0x1e,0x86,0x5,0x90,0x56,0x7c,0xe1,0x21,0x22,0x22,0x22,0x22,0xba,0xc8,0xd8,0x2,0x4c,0x44,0xf4,0x4a,0xaa,0x6d,0x2e,0x45,0x6b,0x55,0xac,0x35,0x6b,0x6c,0x52,0xe1,0xbc,0xcc,0x3f,0xab,0xb5,0x58,0x2a,0x8,0xef,0x65,0x5e,0x60,0xce,0x49,0x6e,0xa2,0x54,0xd,0xdf,0x74,0x26,0x5e,0x94,0x4d,0xbd,0xe3,0xb0,0x96,0xb0,0xe,0x4e,0x17,0x74,0x24,0xdd,0x1a,0x9c,0x50,0x8f,0x79,0x89,0xf6,0x21,0xca,0x8c,0xbd,0xd8,0xe9,0x72,0x91,0x0,0x6b,0x25,0xf6,0xda,0x12,0xbc,0xda,0x3f,0x8f,0xac,0x73,0x2,0x7d,0x8,0xe8,0x16,0xcb,0xb6,0x71,0xb6,0x16,0x99,0x93,0xb7,0x73,0xe2,0x14,0x6e,0xba,0xf6,0x72,0xdc,0xfd,0x96,0x37,0x1e,0xba,0x8f,0x97,0xcf,0x9c,0xc3,0xff,0xfe,0xaf,0x3f,0x8f,0x9f,0x3e,0xf9,0x62,0x9b,0x4f,0xe7,0xbd,0xdc,0x97,0x54,0xe,0x76,0xc8,0x69,0xc4,0x7d,0x3f,0x7d,0x6,0x7f,0xf2,0xe7,0xdf,0x3c,0xd4,0x72,0x7a,0xd5,0x15,0x97,0xe1,0x75,0x37,0x4a,0x95,0x5d,0xa7,0xe1,0x9f,0x6d,0x4a,0xae,0xba,0xa9,0xf7,0x20,0xe7,0x1c,0xee,0x79,0xcb,0xed,0x0,0x80,0xef,0xdc,0xff,0x13,0xfc,0xc1,0x17,0xbe,0x8e,0x67,0x5e,0xde,0xd3,0x45,0x2a,0x11,0xde,0x7b,0x9c,0xdb,0xdb,0xc7,0x5f,0x7e,0xfb,0x47,0xf8,0x1f,0xff,0xf9,0x67,0xf1,0xc8,0x63,0x4f,0xe0,0xaf,0xbf,0xf9,0x7d,0x3c,0xfd,0xc2,0x59,0x9d,0x85,0x38,0x4e,0x9b,0x86,0x35,0x64,0x3a,0xe8,0xf6,0xd7,0xdf,0x82,0xe5,0x72,0x81,0xa7,0x9f,0x7b,0x11,0xff,0xdb,0xef,0x7f,0x1,0xf7,0x3f,0xf2,0x34,0x5c,0x8,0xf0,0x31,0xa0,0x42,0x5a,0x6a,0x1f,0x78,0xf4,0x49,0xfc,0x4f,0xff,0xd7,0xbf,0xc1,0x5f,0x7e,0xed,0xbb,0x78,0xf4,0x67,0x8f,0xe3,0x1b,0xf7,0xff,0x54,0xc2,0x2e,0x9d,0xef,0x68,0xbd,0xb6,0x3f,0x7f,0xfc,0x29,0xfc,0xaf,0x9f,0xf9,0xb7,0xf8,0x83,0x2f,0x7c,0x1d,0xcf,0x9f,0x5b,0xcb,0xfc,0x3d,0x9d,0x7b,0xe8,0x9c,0x47,0xc9,0x19,0xc5,0x5,0xfc,0xbb,0xbf,0xbe,0xf,0xf,0x3d,0xfa,0x8b,0x43,0xc7,0xd2,0xc5,0x88,0x5b,0xae,0xbf,0x1a,0xa1,0xeb,0xda,0x7c,0x49,0xd9,0xda,0x9c,0xda,0x35,0x14,0x42,0x3c,0xa6,0x2a,0xae,0xb6,0x36,0x6b,0xb9,0xc6,0x1c,0xc6,0x61,0x90,0x4a,0xd2,0xf1,0xf8,0x39,0x7a,0x67,0xce,0x9e,0xc3,0xbf,0xf8,0xec,0x9f,0xe3,0xfb,0xf,0x3d,0x2e,0x8b,0x6a,0x66,0x33,0x2c,0xa5,0xe5,0x5a,0xc2,0xea,0xef,0xfe,0xe4,0x71,0xfc,0xe0,0x47,0x8f,0x1c,0xfa,0xfc,0x45,0xdf,0xe3,0x8e,0x5b,0xaf,0x97,0xa,0xc4,0xd8,0xa1,0x16,0x6d,0xdd,0xad,0xf2,0xfc,0x5a,0xb,0xbb,0x55,0xa7,0xca,0x5c,0x4c,0xfd,0x85,0x69,0x19,0x4e,0x88,0xb1,0xcd,0xff,0x9b,0x2f,0xd9,0xa9,0x69,0x8f,0xaf,0x37,0x44,0x44,0x44,0x44,0x44,0x97,0x0,0x2b,0x0,0x89,0x88,0xfe,0x36,0xea,0xac,0x2,0xd0,0x42,0x8e,0x8,0x5d,0x68,0x23,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x5a,0x11,0x75,0x7e,0x5f,0x88,0x51,0x36,0xee,0x6a,0x9b,0xa3,0x2d,0xbb,0x28,0x25,0x4f,0x3b,0x3d,0xb4,0x62,0x2f,0x84,0x28,0x9b,0x7a,0x35,0xdc,0xb2,0xaa,0x29,0xa7,0xb7,0x33,0xcd,0x9,0x3c,0x7c,0x10,0xb2,0x31,0xb5,0xc2,0xc5,0xe,0x25,0x4,0x8c,0xe3,0x20,0xf7,0x3d,0x4c,0x2d,0xaa,0x21,0xc6,0x16,0xca,0x94,0x9c,0xd1,0x2d,0x96,0x40,0xa9,0x38,0x71,0xd9,0x15,0x2d,0xc8,0xfc,0xd0,0xaf,0xdc,0x8b,0xee,0x40,0xeb,0x6f,0xad,0x15,0xff,0xe1,0x2b,0xdf,0xc1,0xd3,0x2f,0x9c,0xc1,0x62,0x79,0x42,0xb7,0x5,0xeb,0xf6,0xe3,0x18,0x51,0x53,0x9a,0x5a,0x38,0x1,0x7c,0xf3,0x81,0x47,0xf1,0xee,0x7b,0x6e,0xc7,0xcd,0x37,0x5c,0xdb,0x6e,0xc3,0x7b,0x8f,0x77,0xdf,0x75,0x1b,0x7e,0xf8,0xf0,0xcf,0xd1,0xf5,0x4b,0xa9,0xa,0xb,0x6e,0x5a,0xaa,0x72,0xcc,0xc,0x40,0xe7,0x1c,0x7e,0xfe,0xc4,0xd3,0xf8,0xc3,0x2f,0x7c,0xd,0x43,0xca,0xed,0xdc,0x15,0x6b,0xb5,0x76,0x1e,0xa1,0xeb,0xf0,0xc2,0xd9,0x7d,0xfc,0xb3,0x7f,0xf1,0xc7,0xf2,0x39,0x5e,0x2a,0x1b,0x65,0xc9,0x48,0x94,0x25,0x14,0x7e,0x71,0xe4,0x1c,0x3c,0xef,0x1d,0xf6,0x56,0x3,0xfe,0xe0,0x4f,0xbe,0x84,0xe7,0x5f,0x3e,0x87,0x10,0x23,0xc6,0x61,0x8d,0x34,0x8e,0x2d,0x98,0xaa,0x90,0x6a,0xb4,0x3f,0xfc,0xb3,0xaf,0x62,0x67,0xb1,0x90,0x2a,0xc6,0x71,0x40,0xbf,0xdc,0x41,0x1e,0x7,0xd4,0x5a,0xf1,0xfd,0x1f,0xfe,0x4,0xbf,0xff,0xf9,0x2f,0xe3,0xfc,0x4a,0x3e,0xcf,0x5a,0xbb,0x4b,0x95,0x59,0x7e,0xa8,0x15,0x25,0x67,0x84,0xd8,0x21,0xc4,0x88,0xef,0xfc,0xe0,0x11,0xdc,0x71,0xdb,0xcd,0x87,0x1e,0xeb,0xa9,0x13,0x3b,0x12,0xa8,0x6,0x59,0xe0,0x51,0xa7,0x27,0x1,0x69,0x1c,0x34,0x7c,0x3d,0xa2,0x95,0xb9,0xda,0x7c,0x49,0xb,0xda,0x3c,0x96,0x3b,0xbb,0xd2,0xfe,0xab,0x73,0x1d,0xf,0x1a,0xc7,0x84,0xff,0xfb,0xf3,0x5f,0xc6,0x23,0x8f,0x3f,0x8b,0x5a,0xb,0x4a,0x29,0x53,0x75,0x28,0x64,0x6,0xa5,0x54,0xb2,0xca,0x35,0xfb,0xf5,0xef,0xfe,0x8,0x77,0xdf,0xf9,0x6,0xf8,0x3,0xcf,0xd5,0xcd,0x37,0x5c,0x8b,0x10,0x7f,0x84,0x34,0xe,0xb2,0x81,0x7a,0x44,0xdb,0xe8,0x1b,0xfb,0x5,0xf2,0xfe,0x1e,0xa0,0xed,0xcb,0x39,0x25,0xb8,0xe0,0x91,0x87,0x61,0x3a,0x2f,0x25,0xcb,0x35,0x1f,0x22,0x52,0x59,0xb7,0xc7,0x68,0xb3,0x35,0xe1,0xc2,0x31,0x5b,0xa2,0x89,0x88,0x88,0x88,0x88,0xe8,0x3f,0x16,0x2b,0x0,0x89,0x88,0x2e,0xf4,0x22,0xa9,0x5b,0x4b,0x1,0x2d,0xee,0xf3,0x52,0x1,0x26,0x5b,0x58,0x43,0xab,0x6e,0xb2,0xd9,0x66,0xc3,0x7a,0x25,0xad,0xb7,0x5a,0xd9,0x64,0x21,0x94,0xd7,0xcd,0xa7,0xed,0xb6,0x34,0xb8,0x29,0xa5,0xe8,0x12,0x87,0x29,0xb4,0x9,0xba,0x34,0xe3,0xb8,0x45,0x1b,0xce,0xc9,0x82,0x88,0xd8,0xf5,0xd2,0x36,0xe9,0x64,0xd9,0x42,0x4e,0x53,0x3b,0xb0,0xf7,0x5e,0x3,0xa8,0x88,0xaa,0x5b,0x59,0xbd,0xf3,0x58,0xee,0x9e,0x40,0xce,0x23,0x96,0xbb,0x27,0xb0,0xe8,0x7b,0xdc,0xf9,0xa6,0xdb,0xf,0xdd,0xfe,0x8b,0x2f,0x9f,0xc5,0xd7,0xef,0x7b,0x8,0x5d,0xbf,0x4,0x50,0xe1,0x43,0x44,0x8c,0xb2,0xc4,0x43,0x5a,0x96,0xa1,0xad,0xbc,0x8b,0x56,0x7d,0x76,0xdf,0x8f,0x1e,0x3d,0x74,0x3b,0x37,0x5c,0x77,0x35,0x76,0x77,0x4f,0xb4,0x73,0x93,0x73,0x46,0x8,0xb2,0xa1,0xd6,0x1d,0xd3,0xe0,0x9c,0x73,0xc1,0x9f,0xff,0xf5,0xf7,0x90,0xab,0x6b,0xe1,0x59,0x4e,0x49,0x3e,0xcf,0x7,0xa4,0x34,0x62,0xbd,0xbf,0x27,0xad,0xa4,0xce,0xa3,0xd4,0x2a,0x21,0xde,0x7a,0xd5,0x42,0x31,0xe7,0x3c,0x52,0x3e,0x3e,0x40,0xfa,0xc1,0x83,0xf,0xe3,0xf1,0xe7,0xce,0xca,0xbc,0xc5,0x34,0x6a,0x78,0x18,0xda,0xf9,0xb7,0xb6,0xea,0x10,0x3a,0x9c,0xdf,0x5f,0x69,0xb5,0xa5,0x4,0x85,0xde,0x7,0xdc,0xf7,0xc0,0x43,0xf8,0x97,0xff,0xe6,0x2f,0x71,0xe6,0xdc,0x5e,0x5b,0x76,0xb1,0x5e,0xed,0x49,0xc8,0xb,0xe8,0x35,0x21,0x2d,0xaf,0xa5,0x24,0x78,0x1f,0xf0,0xdc,0x4b,0xe7,0x8f,0x3c,0xa6,0x3e,0x3a,0xd,0xde,0x2a,0xbc,0x56,0xd5,0x79,0xe7,0xa5,0x6a,0xb3,0x5f,0xb4,0xea,0xcb,0xc3,0xd7,0x80,0x54,0x80,0xc6,0xd8,0xc1,0x39,0x87,0x10,0xa4,0xf2,0x2e,0xc6,0x1e,0xb1,0x5f,0xe0,0xa8,0xd0,0xb0,0xd4,0x82,0x67,0x5e,0x3c,0xa7,0xd7,0x75,0x44,0xc9,0x49,0x5b,0x76,0xb3,0xb6,0x78,0x6b,0x28,0x98,0xe5,0x7c,0xff,0xec,0xc9,0x67,0xb1,0xb7,0x7f,0xb8,0x1d,0xf7,0xaa,0xd7,0x5c,0x1,0x87,0xa9,0xfd,0x5d,0x2a,0x5a,0x83,0x56,0x3d,0x26,0xdd,0x42,0x8c,0xa9,0xba,0x30,0x49,0x45,0x62,0x29,0x65,0xaa,0x2,0x2d,0xa5,0xb5,0xcd,0xdb,0xec,0x42,0xe7,0x3c,0x5c,0xe8,0x0,0x14,0xbe,0xf0,0x10,0x11,0x11,0x11,0x11,0x5d,0x64,0xac,0x0,0x24,0x22,0xba,0x0,0x99,0xc3,0x66,0x4b,0x3f,0x30,0x6b,0x57,0x74,0x28,0x59,0xaa,0xbd,0x6a,0x91,0x76,0xcc,0x8a,0xda,0xaa,0xa8,0x24,0xf4,0xf2,0xb2,0xc5,0x75,0xcc,0xd2,0xea,0x88,0x8c,0xae,0x93,0xb0,0xc7,0xb6,0xd5,0xb6,0xb9,0x81,0x1a,0x16,0x76,0x8b,0x65,0x5b,0xf2,0xe1,0xfc,0xd1,0xe1,0x4f,0x45,0x45,0xd7,0xf7,0x5a,0xb5,0x16,0xb0,0xda,0x3b,0x87,0x9d,0x13,0xa7,0xe0,0x7d,0x68,0x33,0xf0,0xaa,0x55,0x25,0x6a,0x90,0x64,0x1,0xb,0x0,0xa9,0xea,0x3,0x70,0xdd,0x35,0x57,0xe1,0xca,0x2b,0x4e,0x1f,0xba,0xfd,0x1f,0x3f,0xfc,0x18,0x86,0x54,0xd1,0xeb,0xb1,0xd4,0x5a,0x30,0x8e,0x6b,0xd4,0x5a,0xd1,0xf7,0x4b,0x5d,0xf8,0x10,0xb0,0x5e,0xed,0xb7,0xb0,0xe7,0xa7,0x8f,0x3f,0x8f,0x94,0xd2,0xc6,0x42,0x90,0xcb,0x4e,0x9e,0xc0,0x6b,0x4e,0x9f,0xc0,0xe3,0xab,0x95,0x6c,0xb6,0xf5,0x1,0xce,0x3b,0xe4,0x31,0x21,0x8d,0x47,0xcf,0x79,0x7b,0xee,0xf9,0x17,0xf0,0xe0,0x63,0xcf,0xb4,0x2d,0xbe,0xb6,0x11,0x77,0xbd,0xda,0xc3,0x72,0xf7,0x44,0x9b,0x8d,0x38,0xc,0x6b,0xc4,0xd8,0xa1,0x94,0x82,0xb4,0xbf,0x87,0xd8,0xf5,0x12,0xd0,0x85,0x80,0x92,0x13,0x62,0x58,0x1e,0xd9,0x2,0x3c,0x8c,0x23,0xbe,0xf2,0xed,0x7,0x90,0x73,0x6e,0x95,0x85,0x3e,0x4,0x84,0xae,0x3,0x46,0xb4,0xf6,0xd9,0x92,0x33,0xa,0x32,0x52,0x1a,0xd0,0x87,0x25,0x0,0xd7,0x42,0xc2,0xcf,0x7d,0xf1,0xdb,0x80,0xf3,0xe8,0x3a,0x39,0xaf,0xe3,0xb0,0x42,0xd7,0x4f,0xf7,0x67,0x6d,0xc0,0xa8,0x5e,0x2b,0x45,0x2b,0xc6,0x94,0xb4,0x92,0xf2,0xc0,0xf5,0xe5,0xa4,0x2d,0xdc,0x39,0x27,0x4d,0xb0,0xda,0xb6,0xbd,0xb3,0x3c,0x89,0x9c,0xac,0x9d,0xf9,0x88,0xb0,0x54,0x2b,0x30,0x73,0x4e,0x88,0x5d,0xdf,0x2,0xdf,0xb1,0xc,0xd2,0x7e,0xee,0x8f,0xfe,0xf2,0x9e,0x4b,0x69,0xd7,0xb1,0x73,0x41,0x3,0x4a,0x9,0xee,0x8a,0x56,0x31,0xca,0xc,0xc3,0x11,0xeb,0xe2,0xb1,0x5a,0x8f,0x38,0x79,0x60,0x59,0xf2,0xa2,0xef,0xda,0xfc,0x4b,0xdb,0xe6,0x1b,0x42,0x44,0x2a,0x12,0xbe,0xd6,0x92,0x74,0xe9,0x4d,0x46,0xd1,0x6b,0xa5,0xb8,0x2,0x67,0xed,0xdf,0xa5,0xb6,0x78,0xd2,0x2,0x74,0x1d,0x2,0xd8,0x66,0x65,0x12,0xd1,0xc5,0x77,0xd5,0xd,0xb7,0xe1,0xb5,0x37,0xbd,0x1e,0xfd,0x72,0x47,0xb7,0xd6,0xcb,0x6b,0x9d,0xf7,0xf2,0x77,0xaf,0x96,0xa,0xe7,0x80,0x9c,0x65,0x96,0xa9,0x85,0xf5,0x25,0x67,0x78,0x7d,0xed,0xb5,0x19,0x9f,0xde,0xbb,0xf6,0x75,0xcb,0xaa,0xe1,0xdb,0x8c,0x59,0xe7,0x64,0x61,0x56,0xc9,0xfa,0xfa,0xd0,0xb5,0xaf,0x9b,0x4e,0x2b,0x9d,0xa5,0x3a,0xdd,0xeb,0xd7,0x6,0x1d,0x47,0x10,0xa2,0xbc,0x9e,0x76,0x8b,0xf6,0x3,0x15,0x1b,0x89,0x61,0x5b,0xe1,0xe5,0xb5,0xcb,0xb5,0xff,0xba,0xb6,0xfc,0xa9,0xd3,0x1f,0x60,0xc8,0xf,0xbc,0xb2,0x3e,0x2e,0xd9,0x4e,0x2e,0xaf,0x87,0xb5,0x64,0xf9,0xba,0x5a,0xd1,0xee,0xdb,0xe6,0xf4,0x7a,0xbf,0x39,0xb3,0xb7,0xe4,0xac,0x3f,0x3c,0xeb,0xa6,0x1f,0x8c,0xc4,0x8,0xb4,0x2d,0xe7,0x68,0x3f,0xa4,0xb3,0x63,0x91,0xc7,0xe2,0xda,0xf,0x36,0x0,0xe8,0xf,0xa,0xed,0x7,0x42,0xfa,0x7e,0xfd,0x5a,0x1d,0xbb,0x1e,0x79,0x1c,0xdb,0xf,0x7a,0x72,0x4e,0x8,0xfa,0x6f,0x8e,0xf6,0x9c,0xe8,0xf,0x52,0xa4,0x6a,0xbb,0xea,0xc6,0x78,0xa7,0x3f,0x4c,0x73,0xed,0xcb,0x41,0x3b,0xf6,0xd9,0x71,0x39,0xe7,0xf4,0xdf,0x28,0x3a,0x97,0x58,0xc7,0x78,0xd8,0xf3,0xe2,0x74,0xe4,0x83,0x7c,0x6d,0x9b,0x96,0x94,0xc9,0x22,0xa7,0x3c,0x3d,0x9f,0x55,0xb7,0x79,0xe9,0x63,0xb7,0x31,0x15,0xf6,0xc3,0xa7,0x71,0x18,0x64,0x61,0x95,0xf7,0x48,0xc3,0x20,0x3f,0xdc,0xf1,0x1,0x75,0xf6,0xc3,0x25,0xfb,0x77,0xc3,0xfc,0xd8,0xec,0xfe,0x2a,0xa6,0xb1,0x20,0x55,0xbf,0xe6,0xe7,0x24,0xe3,0x53,0xba,0x7e,0x81,0x71,0x58,0xc9,0xb9,0x4a,0x9,0xa5,0x16,0x4,0xfd,0xb7,0x84,0x7c,0x9d,0xd1,0x1f,0xa6,0xe6,0xa2,0xff,0xb6,0x8a,0x5a,0x5,0xaf,0xf7,0xa3,0x95,0xe7,0x32,0x63,0xd7,0xb5,0xe7,0x33,0xe8,0x8c,0xe6,0x36,0xe2,0x45,0x3f,0x4e,0xce,0x59,0x40,0x1a,0xd7,0xf2,0x43,0x42,0x3d,0xf,0xf3,0x6b,0xbc,0x96,0x82,0x34,0xe,0x78,0xfe,0x99,0xc7,0xf1,0xf2,0xb,0xcf,0x62,0xff,0xcc,0xf3,0x7c,0x71,0x21,0x22,0x6,0x80,0x44,0x44,0xdb,0x20,0x8f,0x2b,0x38,0x5b,0xfc,0xa1,0xdf,0xfc,0x58,0x8,0x28,0xff,0x10,0xce,0x88,0x31,0xca,0x66,0xe0,0x3,0xf3,0xed,0xbc,0x6,0x46,0x56,0xa5,0x57,0x72,0xd2,0xad,0xc1,0x5,0x1,0x51,0xbf,0x61,0x48,0x1a,0xfa,0x49,0x60,0x62,0xff,0xa0,0x95,0x99,0x70,0xc7,0x6f,0x1,0xb6,0x6d,0xb7,0xeb,0xd5,0x1e,0xfa,0xe5,0xe,0xf6,0xcf,0x6b,0x65,0x97,0xf7,0xfa,0x8f,0xf0,0x35,0x86,0xd5,0x3e,0x4e,0x9e,0xbe,0x12,0x0,0xd0,0x2f,0x76,0x5a,0x5,0xa2,0xdd,0xec,0x8d,0xaf,0xbd,0xa,0xdd,0x11,0xb,0x23,0xc6,0x54,0xf0,0xee,0xbb,0x6e,0x93,0x7f,0x28,0xe7,0x4,0xef,0x23,0x72,0x1e,0xe1,0xbc,0x54,0xcc,0xd5,0x5a,0xe0,0xb5,0x2,0xd2,0xb2,0x9a,0x45,0xe7,0xf,0xe5,0x36,0xb1,0x8b,0xb8,0xfa,0xf2,0x53,0x78,0xf2,0xb9,0x97,0xe0,0x43,0x6c,0x9b,0x6a,0xe5,0x1b,0xbd,0xee,0xc8,0xc7,0xf6,0xe8,0xe3,0xcf,0x61,0xd0,0x8a,0xbf,0x61,0xbd,0xdf,0x5a,0x7a,0x17,0x3b,0xbb,0xad,0x52,0xd2,0xfe,0x41,0xee,0xbc,0x87,0xaf,0x41,0x17,0xc8,0x16,0x94,0x5a,0xe4,0x9b,0xd6,0x52,0xa4,0x95,0xf6,0x88,0x20,0xe9,0xe5,0x33,0xe7,0xf0,0xf4,0xcb,0x7b,0x12,0xea,0xea,0x3f,0xf4,0xb3,0x1e,0x53,0x1a,0x7,0xfd,0x1e,0xc7,0xc9,0xf1,0x55,0x59,0x8f,0x51,0x52,0xd6,0xb7,0xc9,0x86,0x66,0x1f,0xe5,0x3e,0x73,0x4e,0x40,0x71,0x88,0xb1,0x6f,0x55,0xa0,0xb6,0x9c,0x65,0xfa,0xe6,0x6,0xe8,0x3a,0x8f,0x1b,0xae,0x3e,0x7d,0xe4,0xdc,0x43,0xe8,0x35,0x15,0xf4,0x1b,0x5f,0x1f,0x23,0x42,0xad,0x18,0xd6,0x2b,0x9,0x12,0x4b,0x3d,0xb2,0x12,0xb4,0xa2,0x2,0x3a,0xcb,0xb1,0xe4,0x8c,0xac,0xdf,0x34,0xc5,0xda,0x21,0x25,0x5b,0x5c,0x73,0xf0,0x93,0xf4,0x9b,0x37,0xfd,0xc6,0xcf,0x2a,0x15,0x73,0x1a,0xe5,0x9b,0x74,0xad,0x26,0xb4,0x6f,0xa2,0x6b,0x8,0xba,0x51,0xf8,0xc0,0xf3,0xaa,0xcb,0x4c,0x4a,0x29,0xed,0x76,0xac,0x3a,0xd2,0xda,0x92,0x25,0xd4,0x96,0xf7,0x57,0x5b,0x7e,0xa3,0xdf,0x4c,0x4a,0x85,0x66,0xd2,0x6f,0x4a,0xcb,0xf4,0x4d,0x60,0xc9,0xa8,0x69,0xe4,0x8b,0xe,0xd1,0x45,0x76,0xfa,0xea,0x1b,0xf0,0xa6,0xb7,0xff,0xa,0xae,0xb8,0xea,0x3a,0xd,0x32,0xa,0x70,0x5c,0xce,0xee,0x70,0xfc,0xfb,0x66,0xaf,0x3f,0xe,0xae,0xfd,0xb7,0xbd,0xcd,0x82,0xb9,0x59,0x5,0xf2,0xfc,0x63,0x2f,0x70,0x83,0x80,0x3b,0xe6,0xed,0xb3,0x63,0x6a,0xaf,0xab,0x7,0x8f,0xd5,0xa1,0xbd,0xd6,0x1c,0x7d,0x83,0x75,0xf3,0x83,0x8f,0xbc,0xc3,0x7a,0xe4,0x49,0x98,0x7f,0xa4,0x66,0x63,0x98,0x7f,0x79,0x99,0x7f,0x99,0x3e,0xf8,0x52,0x7d,0xf0,0x4b,0xf8,0xa1,0x97,0x72,0x67,0x3f,0x58,0xbc,0xc0,0x79,0xdf,0xf8,0x80,0xd9,0xdb,0xe,0xdd,0xa0,0x7b,0x85,0x93,0x79,0xd4,0xb9,0x38,0xea,0x49,0x77,0x47,0x9c,0x8f,0xbf,0xe5,0xf3,0xf6,0xb7,0x64,0xe7,0x75,0x7e,0x7e,0xf,0xbf,0xaf,0x6e,0xfc,0x50,0x4f,0x1e,0xba,0x86,0xca,0x7a,0xd8,0xf5,0xc0,0x89,0xb4,0x71,0x2d,0xce,0xe1,0xd8,0x8e,0x8a,0xe3,0x4e,0xfc,0xf1,0xd7,0xec,0xf4,0xf1,0xd7,0xde,0xf4,0x3a,0x9c,0x7d,0xe9,0x5,0x3c,0xfc,0xc3,0xef,0xe0,0x85,0x27,0x1f,0xe5,0xb,0xd,0x11,0x31,0x0,0x24,0x22,0xda,0xe,0x6e,0x9a,0x79,0xe7,0x3c,0xac,0x45,0xb1,0x55,0x22,0xe8,0x3f,0x16,0x9d,0xf7,0x12,0x22,0x5,0xf9,0xe9,0x7c,0xc9,0xa9,0x6d,0x46,0xad,0xb5,0xa2,0x5f,0xec,0xa0,0x96,0xdc,0xfe,0xd5,0xef,0x42,0x40,0xd5,0xc5,0x1f,0xb6,0xcc,0xa3,0x64,0x9,0xb9,0xfa,0x65,0x7f,0xfc,0x3f,0xbf,0xf5,0xa7,0xdc,0x39,0x8d,0xe8,0xfb,0x25,0x56,0xfb,0xe7,0x61,0xcb,0x45,0x24,0xc4,0x92,0xe3,0x8c,0xfd,0x2,0xa5,0x24,0x38,0xbf,0xd3,0x7e,0xd2,0xdd,0xc5,0x5,0xba,0xae,0x47,0xec,0x16,0xb8,0xfa,0x35,0x57,0x1c,0x59,0x25,0xf7,0xfe,0x77,0xdf,0x7d,0x91,0xce,0x1a,0x70,0xd9,0x89,0x5,0x42,0x94,0x2d,0xb5,0x12,0x8e,0x4d,0xb3,0xfc,0x8e,0xf2,0xf8,0x53,0x32,0x9f,0x2e,0xe7,0x24,0xb3,0x3,0x73,0x42,0xbf,0xd8,0xc1,0x7a,0x7f,0xaf,0x55,0x7b,0xc8,0xbf,0xe3,0xb,0xce,0x9f,0x79,0x9,0xfd,0x62,0xa9,0x55,0x88,0x1e,0x28,0xb2,0xd9,0xd8,0xaa,0x3d,0x8e,0x7a,0x6c,0x2f,0x9d,0x39,0x8f,0xa4,0x95,0x9b,0x0,0x30,0xc,0x7b,0x12,0xe0,0xea,0x22,0xb,0xe8,0x3c,0x41,0xa9,0xde,0xa8,0xfa,0x31,0x2b,0xf4,0x8b,0x1d,0xa4,0x61,0x2d,0x33,0xc,0xf5,0xf9,0xb3,0xca,0x8c,0x52,0xb,0xf2,0x90,0xb4,0x62,0xa6,0x20,0x8f,0x19,0xbb,0xbb,0xbb,0xb8,0xfe,0xca,0x13,0x78,0xfb,0x9b,0x6f,0xc3,0x1d,0xb7,0xdd,0x8c,0x2b,0x2f,0x3f,0x75,0xe4,0xf1,0xd8,0xfc,0xc2,0x5a,0x25,0xcc,0x5b,0xed,0x9f,0x97,0xb0,0xd6,0xb9,0x56,0xb5,0x71,0xe4,0xb9,0x75,0x56,0xb1,0x23,0x55,0x15,0x59,0xdb,0x76,0xed,0xed,0xfe,0xc8,0x19,0x8b,0xda,0x7a,0x9b,0xb,0x7c,0xd7,0x49,0x20,0x5b,0x8a,0xb4,0x87,0x57,0x69,0x71,0xb6,0x63,0xec,0x17,0x4b,0xac,0x57,0x7b,0x47,0x7f,0xd3,0xe4,0xbc,0x54,0x4f,0x64,0xbd,0x5f,0x6d,0x61,0x96,0x85,0x33,0x5a,0x31,0xe1,0x1c,0x5c,0x90,0x79,0x98,0x15,0xb2,0x8,0x26,0xeb,0xb5,0xd,0x40,0xaa,0x5c,0x20,0x55,0x36,0xe,0xd2,0x9e,0x2c,0x8f,0xb5,0xc2,0xf9,0x88,0x5a,0x12,0x5f,0x76,0x88,0x2e,0x82,0x2b,0xaf,0xbb,0x15,0xf7,0xbc,0xe7,0xd7,0xa5,0x92,0x6a,0xbd,0x92,0x4a,0xb2,0x5a,0x5a,0xae,0x64,0x15,0x6f,0x55,0x83,0x7b,0xb,0xd2,0xe4,0x6b,0x5b,0x9d,0xc2,0x10,0xad,0x92,0xaa,0x5a,0x11,0x6f,0x15,0x74,0xf6,0x5a,0x6b,0xcb,0x7f,0xe,0x7,0x75,0x75,0x76,0x3f,0xfa,0x96,0x52,0x37,0x5e,0xa3,0xed,0xbe,0x6a,0xa9,0x9b,0x61,0x1f,0xaa,0xbe,0xc,0x5b,0xf5,0xa0,0x6b,0x1b,0xe1,0xa7,0x1c,0x66,0x96,0x1e,0xcd,0xc2,0xab,0x3a,0xcb,0xb3,0x9c,0x96,0x1d,0xca,0xf,0xd7,0x5c,0x3b,0x9e,0xa9,0x1a,0x6d,0x9e,0xa5,0xcd,0x2a,0x15,0xeb,0xa1,0x8,0xf0,0x70,0xc2,0x37,0xab,0x48,0x3c,0xe2,0x85,0xfa,0x98,0xa0,0xee,0x3f,0xa1,0xca,0xf9,0x55,0x84,0x6e,0x2d,0x2c,0xab,0xf3,0x60,0xc,0xff,0x2f,0x7b,0x6f,0xf6,0x6c,0x59,0x76,0x97,0x89,0x7d,0x6b,0xd8,0x7b,0x9f,0x7b,0x6f,0xe,0xa5,0x92,0xaa,0x4a,0x25,0x55,0x21,0x9,0x4a,0x8,0x34,0x20,0x9,0x31,0x8,0x59,0x4d,0xcb,0x80,0x1a,0x1a,0xe8,0x6,0x37,0xa6,0x9,0x88,0xee,0xb0,0x1f,0xdc,0xd1,0xd1,0x1d,0x61,0x3f,0x3a,0xec,0x7f,0xc2,0xf,0x76,0xd8,0x2f,0x84,0x1d,0x61,0x87,0x1d,0x6d,0xbb,0x3,0x1b,0xd3,0x74,0xe3,0xa6,0x45,0x33,0xa,0x21,0x9,0x9,0x84,0x84,0x24,0x24,0xa1,0x79,0xa2,0x54,0x43,0x66,0xde,0x7b,0xce,0xd9,0xc3,0x1a,0xfc,0xf0,0x1b,0xf6,0xda,0xe7,0xec,0x93,0x59,0xaa,0x4a,0xc2,0x2a,0x62,0xfd,0x14,0xa9,0xca,0xbc,0xf7,0x9e,0x3d,0x9d,0x73,0xd7,0x5a,0xbf,0x6f,0x7d,0xc3,0x82,0x31,0x68,0xa,0xac,0x4f,0xbf,0x5f,0xcc,0x6d,0xf3,0x2d,0xf0,0xb3,0xc3,0xe9,0xfb,0x2c,0x7f,0xe6,0xff,0xd7,0x5a,0x43,0x65,0x9f,0xf7,0xa1,0xf2,0xcc,0x4e,0x3f,0xf1,0x16,0xa4,0x9c,0xd0,0x76,0x1b,0x3c,0xf1,0x86,0xb7,0xe1,0xf3,0x4d,0x8b,0x27,0xbf,0xf8,0xa9,0x3a,0xe0,0xd4,0xaa,0x55,0xab,0x2,0x80,0xb5,0x6a,0xd5,0xaa,0xf5,0x62,0xaf,0x2c,0xec,0x3e,0xe,0xf2,0x28,0x99,0x6,0x39,0x27,0xe4,0xc4,0xf2,0xcd,0x9c,0x29,0xd4,0x83,0xe5,0x3e,0x84,0x53,0x25,0x24,0x13,0x69,0xd,0xa9,0xec,0x39,0x7,0x38,0xa7,0xd2,0x1f,0x49,0x48,0x15,0x99,0x8a,0xf3,0xcd,0xf1,0x8e,0xff,0x21,0x0,0xe8,0x1a,0x65,0x2,0x3a,0xe7,0x99,0x41,0x36,0xa0,0xed,0xce,0xb0,0xdf,0x5e,0x52,0x98,0x88,0x31,0x0,0x36,0x8,0xd3,0x40,0xa0,0x5f,0xdb,0x8a,0x91,0x21,0x72,0x4a,0xd8,0x6c,0xba,0xbf,0xf6,0x67,0x77,0xed,0xbc,0x43,0x9c,0x26,0xbe,0xb7,0xa8,0x80,0xd5,0xa9,0xba,0xda,0xed,0xe1,0x7d,0xcb,0x9,0xc9,0x3d,0x31,0xe,0x41,0xbe,0x88,0x14,0x28,0xe1,0x0,0x66,0x55,0x9e,0x5d,0x5c,0x7,0x0,0x66,0x25,0x66,0x78,0xf1,0x4d,0xcc,0x19,0x61,0x9a,0x56,0x5b,0x91,0x7d,0xcf,0xa9,0xcb,0xc2,0xa2,0xf4,0xd,0x42,0x18,0x49,0x1a,0xe5,0x1c,0x72,0xca,0x9c,0xc6,0x3c,0xe9,0xd7,0xe8,0x1c,0x23,0x3d,0xb7,0x18,0x10,0x23,0xf4,0x1e,0x1c,0x33,0x28,0xd,0x7,0xb1,0x3c,0xfe,0xc8,0xcb,0xf0,0xbd,0xaf,0x7f,0xd,0xde,0xf0,0x9d,0xaf,0xc1,0xc3,0x2f,0x7b,0x9,0x9c,0xbb,0xb7,0xd5,0xae,0x0,0xc4,0x31,0x6,0xb4,0xed,0x6,0x61,0x1c,0xd1,0x9d,0x9d,0x63,0x9a,0x26,0x18,0x96,0x8f,0xad,0x7d,0x26,0x49,0xc6,0x95,0xd1,0xb4,0xc4,0xa6,0x8c,0x89,0xe4,0xcc,0x26,0x4c,0x24,0xa7,0x3d,0x86,0xff,0x58,0xe,0xe7,0xe8,0xb3,0xd2,0x76,0xea,0xfb,0x27,0xb2,0xab,0x9c,0x13,0xbc,0x6b,0x58,0x4e,0xed,0xd7,0x81,0x44,0x95,0x8,0xb6,0x1a,0x26,0x42,0xf7,0xe1,0x10,0x13,0x7d,0x1e,0x89,0xd,0x1b,0x39,0xac,0xc6,0x30,0x93,0xd4,0xa9,0x5c,0x9a,0xa4,0xc3,0xa3,0x36,0x6b,0x92,0x82,0xac,0xbf,0x6f,0xb5,0x6a,0xd5,0xba,0x2f,0xf5,0xea,0xef,0x7c,0x13,0x9c,0xa7,0xdf,0x69,0x91,0xa1,0xca,0xef,0x99,0x30,0xce,0x69,0xce,0x62,0x30,0xcf,0xda,0x2,0x28,0xcb,0xfc,0x33,0x59,0x7d,0x3f,0x25,0x38,0x28,0x70,0x12,0x79,0xce,0x22,0xad,0xb5,0x33,0x98,0x24,0x6c,0x78,0xb6,0x9e,0x10,0xd6,0xa1,0x8c,0x7,0x59,0xe7,0x53,0xd9,0x2c,0xe3,0xb9,0x95,0xcf,0x55,0xc2,0x64,0x99,0x43,0x83,0xe8,0xfa,0xb2,0xca,0x77,0x65,0x53,0x2e,0xa7,0x62,0x43,0xce,0x5a,0x7e,0x5d,0x66,0x60,0x6e,0x3e,0x5e,0xc6,0x2c,0xdf,0xd4,0xeb,0x34,0xc2,0x1f,0x2b,0x98,0x63,0xc6,0xce,0x12,0xd2,0x15,0x86,0xe1,0x2,0x84,0x3c,0x9,0xe,0xd2,0xf7,0xe4,0xde,0xe5,0xdf,0xa,0x84,0x22,0x63,0x5,0x79,0xbc,0x7,0xce,0xb7,0xe,0x1c,0x96,0xb8,0xa5,0x29,0x1,0xbd,0x2,0x0,0x5c,0x23,0xc,0xae,0x9e,0xda,0x1c,0x1c,0xf0,0x88,0x45,0xf9,0x2d,0xb7,0x38,0x53,0x3b,0x8a,0xe7,0xc,0x10,0x1e,0x51,0x36,0xcd,0x31,0x48,0x5a,0x0,0xa7,0x25,0xab,0xf5,0x10,0xe0,0x94,0x4d,0xba,0x18,0x3,0x6e,0xbe,0xe4,0x21,0x7c,0xe3,0xcb,0x9f,0xd1,0xcf,0x57,0xad,0x5a,0xb5,0x6a,0x55,0x0,0xb0,0x56,0xad,0x5a,0xb5,0x5e,0x84,0x65,0x5d,0xa3,0xac,0x2a,0x9,0x39,0x48,0x29,0x91,0xff,0x5c,0x4e,0xb0,0x98,0xd9,0x57,0xd6,0x92,0x27,0x5b,0x42,0xd4,0xd0,0xf,0xf5,0xa6,0x61,0xf0,0xc5,0x59,0x47,0xaf,0xe3,0x85,0x63,0x6,0x35,0x2d,0xc4,0x5a,0xcb,0x33,0x90,0x12,0x23,0x52,0x18,0x57,0xaf,0x89,0xc2,0x30,0x46,0x95,0xc1,0x82,0x65,0x94,0xe2,0x9b,0x23,0x1e,0x37,0x4d,0xd3,0x6a,0x23,0x43,0xbe,0x80,0x49,0x1,0x47,0xf2,0xd1,0xf9,0xeb,0xcf,0x81,0xea,0xda,0x96,0x7d,0xea,0x28,0x30,0x24,0x32,0x2b,0xf2,0x14,0x53,0x20,0x26,0x90,0xdf,0x8f,0x6f,0x91,0x8c,0x81,0x67,0x2f,0x28,0x92,0xb9,0xce,0xe9,0xc3,0x40,0xc6,0x34,0xe,0xea,0xd5,0xd4,0x76,0x1b,0x92,0xad,0x22,0x33,0x68,0xb5,0x7e,0xfc,0x91,0xfd,0x89,0x72,0x36,0xea,0x21,0x24,0x52,0xe7,0x69,0x1c,0xd4,0x7,0xc9,0x5a,0x8b,0x71,0xd8,0x93,0x77,0x95,0xa1,0x86,0xd3,0x1a,0xe8,0xfb,0xdf,0x6d,0xce,0xc8,0x7f,0x70,0x9a,0xb0,0xd9,0x6c,0xf0,0xd6,0xd7,0x3d,0x8e,0x1f,0x78,0xf3,0xeb,0xf0,0xf8,0x2b,0x1f,0x41,0xd7,0xb6,0x7,0x3d,0x47,0xc6,0x9d,0xab,0x1d,0xae,0x5f,0x9c,0x1f,0x25,0x3b,0x4b,0x83,0x98,0x62,0x84,0xf7,0xd,0x86,0x7e,0xf,0xdf,0x34,0xb0,0xd6,0x92,0xe7,0x51,0x8a,0xab,0xf7,0x62,0x58,0xa6,0xac,0x16,0x4d,0xa0,0x10,0x11,0x3,0x43,0xe1,0x2d,0x79,0x5d,0xd2,0xe4,0x5c,0x3,0xdf,0x90,0x97,0xd5,0xd5,0x9d,0x5b,0xf0,0x9c,0x0,0x6d,0xad,0xc3,0xd8,0xef,0xe0,0x5d,0x83,0x7e,0xbc,0xa2,0x0,0x16,0x6d,0xba,0xf,0x2a,0x51,0x63,0x1b,0xa6,0x51,0x3,0x3c,0x72,0x4a,0x7c,0xad,0xf4,0x4c,0x8d,0x85,0x32,0xfe,0xe8,0xfd,0x98,0xfd,0xa,0x85,0xd5,0x98,0x72,0xe2,0xf7,0x92,0x1,0x1,0x63,0x60,0xfc,0x6,0x18,0xee,0xd4,0x81,0xa7,0x56,0xad,0xfb,0x50,0xaf,0xfc,0x8e,0x37,0xe1,0x65,0x8f,0x3e,0xae,0xd6,0xb,0xa,0x9a,0x14,0xa0,0x18,0x79,0xf5,0xa5,0x19,0x0,0x2,0x16,0x8c,0x2f,0x1a,0x1f,0xac,0x8e,0xaf,0xea,0x95,0x26,0xd2,0x5f,0xf6,0x9c,0x45,0xc1,0x20,0x34,0xce,0x29,0xab,0x3a,0xc6,0x9,0xd6,0x31,0x10,0xc8,0x1e,0x7c,0xe4,0x63,0xc7,0x60,0x5c,0x86,0x8e,0x21,0x3a,0x2f,0xe4,0xc,0x23,0x9b,0x64,0xcc,0x34,0x34,0xec,0x51,0x8,0x63,0x96,0xe3,0x92,0x1,0x1,0x98,0x39,0x29,0xc8,0x36,0x3,0x80,0xf3,0x18,0x4c,0x1b,0x3c,0x49,0x99,0x88,0x39,0xce,0x9b,0x78,0xe2,0xe5,0xcb,0x3,0x5c,0x1,0x1e,0x26,0x41,0x82,0x68,0xe,0x7,0xa,0xe6,0x64,0xe9,0xff,0x77,0x20,0xf,0x46,0x56,0xbf,0x44,0x7a,0x26,0xe5,0x8c,0x97,0x67,0x66,0x61,0xc1,0x60,0x34,0x38,0x66,0x21,0x2e,0xe7,0xc9,0x3,0xef,0xbc,0x15,0xe4,0x6e,0xf1,0x65,0x7d,0xbf,0xc1,0x57,0x93,0x4f,0xff,0xec,0x1,0xc6,0x37,0xcb,0x6d,0x57,0x0,0xc7,0x9c,0xb,0x58,0xd0,0xac,0x2a,0xaa,0x55,0x6,0xbe,0xc2,0x3e,0x2c,0x99,0x82,0x4b,0xd1,0xb2,0x42,0xb7,0x77,0xad,0xb5,0xfb,0x3f,0xf2,0x15,0xbc,0x17,0x8,0x78,0x78,0xd3,0xf9,0xf8,0x58,0xe5,0xb3,0xc0,0x5d,0xae,0x4c,0x0,0x6f,0x63,0xcd,0xb7,0x24,0x46,0x5a,0xab,0x56,0xad,0x5a,0x15,0x0,0xac,0x55,0xab,0x56,0xad,0x6f,0xa2,0x52,0x9c,0x66,0xa3,0x73,0x6e,0x88,0xac,0xb5,0xe4,0xff,0xc6,0xa0,0x85,0x55,0xc6,0x84,0x53,0xe9,0x66,0x69,0x14,0x9e,0x8a,0x14,0x5e,0xcb,0xbe,0x6a,0x62,0x3a,0x4e,0x0,0x1e,0xf9,0xcf,0x59,0x4b,0x60,0x94,0x95,0xa4,0x61,0xd7,0x9e,0x5e,0x70,0x82,0x1,0x96,0x34,0x4b,0x27,0x53,0x4c,0x98,0x86,0x1e,0x6,0x94,0xd2,0x6b,0x0,0x6c,0x2e,0xae,0xc3,0x5a,0xf2,0x68,0x6b,0xda,0x4e,0x81,0x9b,0x6e,0x73,0x8e,0x7d,0xdf,0xaf,0x1e,0xfb,0x8f,0x3e,0xfc,0x71,0x5c,0x6e,0xf7,0xc5,0x4e,0xb8,0xc8,0xb4,0x96,0xcc,0x82,0x14,0x23,0xe3,0x37,0x7c,0xcf,0xc,0xe8,0x58,0xe7,0xe9,0xda,0x62,0xc4,0x97,0xbf,0x71,0x9b,0xd3,0x91,0xf7,0x70,0xce,0xc3,0xfb,0x46,0xcd,0xdc,0xd7,0xd6,0xe5,0x99,0xd,0xe6,0x5,0xe0,0xc,0x61,0x22,0xa0,0x2f,0x67,0x8c,0xfd,0x9e,0xe4,0xa6,0xda,0xc4,0x19,0x65,0x94,0x44,0x36,0x6c,0xf7,0x4d,0x8b,0x69,0x1a,0x91,0x73,0xbb,0xce,0x24,0xe3,0xc6,0x4e,0x76,0xed,0xad,0xb1,0xd8,0xef,0xb6,0xca,0x30,0x24,0xd0,0xd7,0xb1,0x81,0xbc,0x53,0xe0,0xd4,0x75,0x67,0xea,0x2f,0x64,0x60,0x30,0xe,0x3,0xac,0x31,0xf8,0xde,0x37,0xbe,0x1a,0x3f,0xf1,0xae,0x1f,0xc0,0x2b,0x5e,0xfe,0xd0,0x11,0xb,0xa1,0x1f,0x46,0x7c,0xee,0x8b,0x5f,0xc5,0x87,0x3f,0xfe,0x39,0xdc,0xba,0x1a,0xf0,0x4f,0x7f,0xe1,0xc7,0x8e,0xc2,0x39,0xe8,0xf8,0xf4,0x5e,0x8e,0xe3,0xc0,0xe9,0xcf,0x9,0xe3,0xc8,0x69,0xd2,0xce,0x61,0x8d,0x9,0x4a,0xd,0x56,0x46,0x4a,0x99,0x24,0xc8,0xc,0xb6,0x49,0xd3,0xb5,0xca,0x88,0x30,0x86,0x59,0x95,0xf4,0xb3,0x5d,0x77,0x86,0x98,0x2,0x85,0x87,0xc,0x3,0xdf,0x77,0x38,0x30,0x6a,0x5f,0x97,0x12,0x13,0x10,0x4a,0x8d,0xff,0xd4,0xef,0x17,0xac,0x1f,0x61,0x64,0xc6,0x18,0x61,0xac,0x51,0xcf,0x4c,0xdf,0x34,0xca,0xbe,0x9c,0xc6,0x91,0xee,0x2d,0x67,0x44,0x6e,0xd6,0x71,0xe0,0xf1,0x54,0xab,0x56,0xad,0xe7,0x5f,0xae,0xd9,0xe0,0xdb,0x5e,0xfb,0x6,0x38,0xeb,0x35,0x90,0x62,0x1e,0xc8,0x93,0x6e,0x6c,0x95,0xb2,0x49,0xc3,0x80,0x98,0xe8,0x43,0x45,0x92,0x2b,0xd6,0x15,0x62,0x57,0x70,0x24,0x13,0xb5,0x96,0x81,0x40,0x2,0xe3,0x20,0xac,0x62,0x6b,0xd5,0x6b,0x94,0x18,0x7a,0xcb,0xb1,0xdf,0x3a,0xc7,0xc0,0x1d,0x34,0x54,0x82,0xc2,0x2c,0x18,0xf4,0xe3,0x20,0xc,0x2b,0x60,0x1a,0x50,0x8c,0xfd,0x46,0x37,0x20,0xc8,0xd7,0x74,0x6,0xa4,0xc,0xc8,0xeb,0x36,0xa9,0xd7,0x21,0x8d,0x59,0xf3,0x71,0xcd,0xc,0xd8,0x14,0x2c,0x42,0x3a,0x82,0x65,0x46,0x7f,0x9a,0x1,0x22,0x9e,0xf3,0x8,0xd4,0x2b,0xc6,0x29,0x6,0xf7,0x14,0xcd,0xe2,0xf0,0x13,0x61,0x37,0x42,0x3d,0x12,0xe9,0x99,0xcb,0x4f,0x9b,0x42,0x7f,0x4b,0xc3,0xe3,0xa,0xbc,0x74,0xe4,0x6b,0x28,0xc0,0xdd,0xf3,0x41,0x99,0xf2,0x89,0xbf,0x63,0xd5,0x78,0x6f,0x75,0x1c,0x56,0x1b,0x94,0x75,0xb3,0xc6,0x25,0xbb,0x90,0x41,0xd3,0x7c,0xc,0xa,0x2e,0xa1,0xd0,0xd3,0x57,0x39,0xdf,0xf1,0xfa,0xfa,0xe7,0x6e,0x6b,0xa3,0xfb,0x52,0x87,0x3a,0xe9,0xf5,0xbb,0x5e,0xc7,0x14,0x6b,0xd5,0xaa,0x55,0xab,0x2,0x80,0xb5,0x6a,0xd5,0xaa,0xf5,0x22,0xae,0x22,0xe9,0x2f,0x2f,0xd8,0x13,0x80,0x15,0x1f,0xb6,0x42,0xc6,0x64,0x9d,0xd7,0xc4,0x3e,0x63,0x2c,0x1,0x1f,0xd3,0x4,0xdb,0x76,0xca,0x16,0x24,0xdf,0x3f,0xab,0x3e,0x32,0xde,0x38,0xa4,0x9c,0x61,0x52,0xd4,0xf4,0x42,0x61,0x18,0xac,0x2d,0x3b,0x29,0xbc,0x61,0xe0,0x34,0x46,0xcb,0x4c,0xb9,0x44,0xe9,0xad,0xc3,0x5e,0x93,0x63,0xfb,0xed,0x25,0x36,0xe7,0xd7,0xb0,0x39,0x3f,0x53,0xe0,0x4c,0x40,0x9a,0xcb,0x6d,0x7f,0x64,0xac,0x6d,0x8c,0xc1,0x93,0xcf,0xdc,0xc1,0xfb,0x3f,0xfe,0x45,0x4d,0xc7,0xb3,0xce,0x69,0xb0,0x88,0xf3,0xd,0xfa,0xdd,0x15,0x5c,0xd3,0xc0,0x1a,0xc7,0x12,0xdd,0x19,0x2c,0xca,0x89,0xc0,0xa8,0x30,0x8d,0xda,0xac,0xe8,0xd7,0x6d,0x50,0xf9,0xe9,0xea,0x92,0x9a,0x7d,0x11,0x9d,0x6f,0x10,0xa6,0x11,0xe3,0xd0,0x6b,0xa,0x25,0x5,0x55,0x48,0xe2,0x6f,0x43,0x8c,0xc9,0xa2,0x91,0x33,0x0,0xfa,0x7e,0x4f,0xd,0x56,0x4e,0x18,0xfb,0xfd,0xc2,0x88,0xbe,0xbc,0x3f,0x1,0xb9,0x3c,0xcb,0xe2,0x72,0x8a,0x18,0x38,0xe5,0xd8,0x39,0x8f,0xb1,0xdf,0x13,0x53,0x4d,0xe5,0x3f,0xd0,0xa6,0x34,0x4c,0x23,0x9c,0x6f,0x70,0xed,0xac,0xc5,0x2f,0xfc,0xd4,0xf,0xe3,0x6d,0x6f,0x7e,0xc3,0x91,0xcc,0xf7,0xf2,0x6a,0x8b,0xf,0x7d,0xf4,0xd3,0x78,0xdf,0x9f,0x7e,0xa,0xbb,0x60,0x31,0xc,0x3d,0x1e,0x79,0xf0,0xda,0x89,0xb7,0x92,0x58,0x2b,0x61,0x9a,0x34,0x4c,0x43,0x12,0xa5,0x8d,0x49,0xc8,0xd9,0x9e,0x48,0xf,0xb6,0x8,0x61,0x82,0x75,0xd,0x62,0x20,0x86,0x64,0xd3,0x76,0xd8,0xef,0xb6,0x68,0xda,0x16,0x71,0x2d,0x4c,0x43,0x3c,0xb,0xf9,0x73,0x20,0x8c,0xcc,0x71,0xe8,0xe1,0x9b,0x6,0x63,0xbf,0x47,0xc3,0xb2,0x60,0xc3,0x3f,0xb7,0xa,0xa2,0x72,0xe0,0x49,0x98,0x46,0x6,0xfb,0xa0,0x89,0x91,0x13,0x7f,0x46,0x6c,0x91,0xd2,0x19,0xa6,0x91,0xd9,0xb3,0x94,0x9c,0x28,0xa1,0x29,0x99,0x41,0x2,0xf5,0x1,0x3,0x90,0xc2,0x58,0x30,0x6f,0x6a,0xd5,0xaa,0xf5,0x7c,0xeb,0x81,0x87,0x5e,0x81,0xb6,0xdb,0x2c,0x1,0x17,0x4d,0x79,0x9d,0x13,0x57,0x4b,0xf9,0x6b,0xd6,0xef,0x65,0x5,0x9,0x65,0xe3,0xc3,0x72,0x6a,0xaa,0x48,0x76,0x4b,0x79,0x2d,0x81,0x79,0x7e,0x31,0x57,0x3a,0xf6,0x56,0xb5,0xba,0xe1,0x43,0x1e,0x7f,0x59,0x80,0xbf,0x14,0x61,0x8c,0x53,0x6,0x9d,0xa6,0xc0,0xe6,0xac,0x9,0xc3,0x84,0x55,0x26,0x62,0x7,0x8b,0x7,0x2c,0x1f,0xc7,0xf0,0xbc,0x44,0x63,0x87,0x48,0x6e,0x8d,0xb2,0xff,0x92,0xa4,0xe7,0x22,0x11,0x3,0x4e,0x1,0x1d,0xcc,0xc0,0x5f,0x96,0x80,0x27,0x61,0x2c,0xce,0x30,0xd4,0x7c,0x7f,0x79,0xc1,0x7a,0x93,0xf9,0x26,0xa5,0xcc,0xec,0xc5,0x12,0x28,0x9d,0xaf,0x75,0x1d,0x94,0xca,0x40,0x36,0x7,0x81,0x15,0x58,0xa4,0xf7,0x96,0x1,0x52,0xf9,0x6e,0xc0,0xdd,0x5d,0xa1,0xb3,0x13,0x3f,0xb2,0x36,0xf1,0x16,0x92,0xd7,0xf2,0x1a,0x8e,0x5f,0x67,0x56,0xd8,0x7c,0xc,0x1e,0x1e,0xea,0x89,0xb,0x40,0xb3,0x4,0xfd,0xee,0xc6,0xef,0xcb,0x77,0x91,0x37,0xbf,0x40,0xd7,0xc4,0xe7,0x57,0x8b,0x7b,0x5c,0x3e,0x87,0xa3,0x67,0x6e,0x50,0x0,0xea,0x75,0xec,0xa9,0x55,0xab,0x56,0x5,0x0,0x6b,0xd5,0xaa,0x55,0xeb,0x45,0x5d,0xd2,0x64,0x88,0x54,0xc9,0xb2,0x9c,0xd1,0x71,0x42,0x2d,0xc,0x38,0x64,0x23,0x17,0x1e,0x47,0x6,0xd6,0x59,0x6,0x5d,0x1c,0xe0,0x67,0x90,0x44,0x16,0xd8,0x86,0x19,0x6e,0x65,0x88,0x83,0x0,0x5e,0xe9,0x6e,0xb,0xde,0x42,0x36,0x24,0x1e,0x6c,0xd3,0xd8,0xa3,0xdf,0x51,0x18,0x48,0x18,0x47,0x38,0x3e,0x66,0x77,0x76,0xa1,0x4c,0xad,0x59,0xde,0xea,0x60,0x9d,0xc7,0xd7,0x9f,0xba,0x85,0x10,0x22,0x9a,0x66,0x39,0x15,0xbc,0xee,0x35,0xaf,0xc4,0x7b,0x3f,0xf2,0x19,0x0,0x50,0xaf,0x41,0x9,0x27,0x29,0xd9,0x8c,0xe3,0xb0,0x27,0xf6,0xd8,0xd8,0xeb,0x65,0x75,0x9b,0x33,0x62,0xec,0xf1,0xaa,0x38,0xc6,0x40,0xff,0xe5,0xfb,0xcc,0x39,0xa1,0xed,0xce,0xd6,0xc3,0x2d,0x44,0x46,0x56,0x48,0x9d,0x52,0x8a,0x94,0xae,0xdb,0xb4,0xd8,0xef,0xae,0x14,0xa0,0xb,0x61,0xc2,0xf9,0xb5,0x1b,0xc4,0xda,0x33,0x24,0x61,0xa5,0x9f,0xb9,0x84,0xb3,0xe,0x83,0x19,0x57,0x9b,0x1d,0xf5,0xb6,0x62,0xb9,0x99,0x4,0x86,0xc4,0x40,0xbe,0x7f,0x63,0xce,0xf0,0x2d,0x87,0x71,0xb4,0x1b,0x18,0x67,0x61,0x9d,0x25,0x40,0x91,0x65,0x6a,0xce,0x24,0xfc,0xa3,0x9f,0xfd,0x9,0xbc,0xf5,0x4d,0xdf,0x7d,0x70,0xec,0x8c,0x8f,0x7e,0xe2,0x33,0xf8,0xf5,0xdf,0xfd,0x13,0xdc,0xda,0xe,0xc,0x82,0x1a,0x95,0x97,0xe5,0x35,0x26,0x5f,0x4a,0xe8,0x77,0x5b,0xe,0x3e,0x21,0x36,0xa7,0xf7,0xd,0x0,0x83,0xb6,0xeb,0xe8,0xf9,0x9f,0x90,0x6a,0xb7,0xed,0x6,0x91,0x7f,0x7e,0x3f,0xe,0x30,0x61,0x52,0x76,0xdd,0xaa,0xcf,0xa2,0x1,0x52,0x26,0x26,0xde,0xee,0xea,0x8e,0x32,0x68,0xac,0xb5,0x4,0x4a,0x9b,0x9,0xe3,0xd8,0xa3,0x69,0x3a,0xc4,0x69,0x64,0xe6,0xe5,0x3a,0x8b,0x72,0xec,0x77,0x1a,0xe8,0x22,0xcc,0xc9,0x49,0x40,0xc7,0x9c,0x0,0x10,0xdb,0x75,0xec,0x7b,0x38,0xef,0xd4,0xbf,0x2b,0x3,0x48,0x39,0x2a,0x4b,0xa7,0xc,0x1f,0x98,0x7d,0xb,0x6b,0x7,0x55,0xab,0xd6,0xb,0x5e,0xe0,0x7b,0x7f,0xc0,0xd6,0x62,0x70,0xc9,0x18,0x62,0xe8,0x29,0xa0,0x6,0x5,0x9c,0xe4,0xf7,0xd7,0x8,0xdb,0x4f,0xe4,0x91,0x3c,0xc7,0x19,0xe,0xee,0x29,0x3d,0x70,0x1,0xc0,0x8,0xa0,0x6,0xa8,0x57,0xa0,0x6c,0x64,0x89,0xd,0x40,0xce,0x86,0xc6,0x2,0x66,0x23,0x8a,0xc5,0x0,0x6d,0x4a,0x44,0xb5,0x6e,0xa0,0x30,0x23,0xa3,0x9e,0x81,0xd6,0xcf,0xbe,0x83,0x1a,0xd6,0xc4,0x63,0xa7,0x5c,0x9f,0x75,0xcb,0xd,0x8b,0xcc,0xf3,0xb6,0x32,0x0,0xcd,0xbc,0x41,0x25,0x60,0x53,0xc9,0x80,0x9c,0xc1,0x3f,0x86,0xac,0x24,0xc5,0xdc,0x3a,0x65,0x27,0x2b,0x38,0x97,0x8,0x50,0x14,0x76,0xb3,0x30,0x1d,0x5,0x3c,0x95,0x6b,0x2f,0x81,0xb4,0xd9,0xfb,0x6f,0xe9,0x5,0x58,0xb2,0xfb,0x72,0x1,0x9e,0x1e,0x27,0x16,0xdf,0x8f,0x85,0xc,0x66,0x69,0x77,0x9,0x70,0xe9,0xf7,0x8e,0x19,0x7e,0xf9,0x20,0xe0,0x44,0xfd,0x1b,0xf3,0x81,0x84,0xf7,0xf0,0xfb,0x8b,0xbf,0xe7,0x17,0x7c,0x17,0xf9,0x39,0xfd,0x84,0x79,0x8e,0x3f,0xb3,0x40,0x3b,0x95,0xa9,0xa9,0xd4,0xcc,0x35,0x3a,0x5f,0x3e,0x58,0x7b,0xad,0xcc,0x89,0xe2,0x15,0x5d,0xab,0x56,0xad,0x5a,0x15,0x0,0xac,0x55,0xab,0x56,0xad,0x17,0x71,0x9,0x9b,0x4f,0xd6,0xcb,0x29,0x25,0xc4,0x74,0x68,0x90,0x9e,0x58,0x16,0x4c,0xe9,0xa7,0xf2,0xb3,0x39,0x51,0xe3,0x23,0x80,0x58,0xc3,0x7e,0x76,0x28,0x64,0xc2,0xd6,0x3a,0x65,0x20,0x94,0xe9,0xad,0x14,0x8a,0xb0,0xbe,0xa0,0x15,0x7f,0x25,0x49,0xab,0x35,0x6c,0xa4,0x2e,0xc0,0x8e,0xf3,0x5e,0x59,0x73,0x39,0x25,0xf8,0x6e,0xc3,0x20,0xb,0x83,0x35,0xc,0x46,0x3e,0xf9,0xec,0x25,0x76,0xfb,0x1e,0x37,0x9b,0x25,0x3b,0xed,0x55,0x8f,0xbd,0x1c,0x2f,0xbd,0x71,0x81,0x67,0xae,0x7a,0x64,0x64,0x2,0x89,0xbc,0x27,0x6,0xd7,0x38,0x22,0x30,0xd0,0x63,0x9d,0x63,0x1f,0xc1,0xcc,0xac,0xbf,0x89,0xc1,0x2c,0x5a,0xc,0x7b,0xdf,0x22,0x8c,0x23,0x33,0x3b,0xb2,0x2e,0x9c,0xa7,0x71,0x40,0x8a,0xeb,0x29,0xaf,0x29,0x93,0xaf,0x1e,0x40,0xcf,0x7a,0x1c,0x7a,0x18,0x63,0xb0,0xbd,0x73,0x8b,0xee,0x9,0x1,0xd3,0x34,0x52,0xa2,0x70,0x8,0xb3,0x31,0x3c,0xf8,0x79,0x3b,0x92,0x6f,0x79,0xdf,0x9e,0x58,0x8b,0x13,0x23,0xad,0x69,0x3b,0x8c,0x7d,0xaf,0xcf,0x7b,0x73,0x7e,0x81,0x3b,0xcf,0x3e,0x4d,0x72,0x65,0x61,0x12,0xb6,0x99,0x1,0x5a,0x2,0x7a,0xd3,0x44,0x9e,0x8c,0x3f,0xfd,0xae,0x1f,0xc2,0x5b,0xde,0xb8,0x4,0xff,0x52,0x4a,0xf8,0x9d,0x3f,0xfc,0x13,0xfc,0x9b,0x3f,0xf8,0x53,0x64,0x58,0x66,0xb7,0x18,0xf8,0xa6,0x45,0x98,0x6,0x66,0xd3,0xac,0xdf,0xaf,0xa4,0xef,0x5a,0xe7,0x90,0x63,0x42,0x34,0x91,0x19,0x8f,0x11,0x4d,0x13,0x4e,0x26,0x1,0xc7,0x18,0x10,0x38,0x45,0x77,0x73,0x76,0xce,0xc,0xd0,0x3d,0x52,0x38,0xf1,0x9a,0x4c,0x61,0x2a,0x61,0xea,0xc9,0x5f,0x30,0x4c,0x80,0xa1,0xf7,0xa3,0xdf,0x6d,0x59,0x7e,0x9c,0xb1,0x9f,0x2e,0xd1,0xb4,0x1b,0xa,0xf3,0x38,0x91,0xd6,0x1c,0xa6,0x9,0x86,0x3f,0xdb,0x39,0x67,0x8c,0xc3,0x9e,0x3e,0x6b,0x4d,0x8b,0x10,0xc,0xa5,0xfe,0x6,0x4e,0x46,0x4e,0xa9,0x0,0x1a,0x29,0xd4,0xc4,0x20,0x23,0xa6,0x48,0xcf,0x95,0x7f,0xbf,0x52,0xa,0xc8,0x29,0xdc,0x5f,0x19,0x57,0xad,0x5a,0xb5,0xa,0x90,0xa9,0x4,0x29,0x72,0x1,0x5a,0x41,0x3,0x11,0x4a,0x36,0xda,0xec,0xc9,0xa7,0xc8,0x9e,0xb2,0x76,0x25,0x41,0x7c,0x4e,0x2,0x4f,0xb,0xac,0x64,0x96,0xff,0x1a,0x6,0xfc,0x9c,0x32,0xca,0x67,0xa0,0x4d,0x6c,0x1c,0xf2,0xc,0x9a,0x1,0xb0,0xde,0x23,0x4c,0x13,0xda,0xae,0xd5,0x31,0x46,0xbd,0xfb,0x90,0xe1,0xd8,0x3e,0x83,0xc6,0x21,0xb3,0x4,0xd8,0x8c,0x1,0x38,0x89,0x3c,0x1b,0x6,0x1c,0x85,0xa9,0x97,0x67,0x66,0x9f,0x80,0x9e,0xa,0x82,0xb2,0x8f,0xaa,0x30,0x8,0x25,0xc4,0x4b,0x9f,0x9e,0xc1,0x62,0x2d,0xa0,0x8c,0x7a,0x2c,0x41,0xb1,0x25,0xe0,0xb7,0xcc,0xf3,0x92,0x63,0xeb,0xd7,0x35,0xa1,0x63,0x9e,0x1f,0x8d,0x5e,0xc3,0x31,0xd8,0x74,0xca,0xff,0x6f,0x99,0x58,0x3c,0x83,0x72,0xa,0x4c,0x16,0x40,0x9f,0xc1,0x9,0x79,0x2f,0xb0,0xf4,0xe7,0x93,0xf7,0xee,0x2e,0x32,0xde,0x5c,0xbe,0xb6,0x4,0x2,0xb1,0x64,0x3e,0xfe,0xf5,0x33,0xf9,0xd6,0x2,0x59,0xcc,0xca,0xcf,0x94,0xdf,0x2a,0xd2,0xa3,0xcd,0xf2,0xc7,0x66,0xf5,0xaf,0x39,0xf0,0x3c,0xbc,0x1b,0x32,0x69,0x2a,0x3,0xb0,0x56,0xad,0x5a,0x2f,0x8e,0xde,0xb6,0x3e,0x82,0x5a,0xb5,0x6a,0xd5,0x3a,0x5d,0x89,0x19,0x6c,0xb2,0xce,0x9d,0x17,0xd5,0x69,0xfe,0x93,0xe6,0xdd,0xfe,0xc4,0xac,0x4,0x1,0xbd,0x4,0x88,0x31,0xc6,0x20,0xa6,0xa0,0xcd,0x8f,0x84,0x7e,0x10,0x48,0xd4,0x14,0xc9,0x84,0xd2,0x64,0xe4,0x93,0x9b,0xc9,0x99,0xd9,0x86,0x2,0xb4,0x29,0x33,0x2,0x4,0x38,0xe5,0x94,0x58,0xa2,0x39,0x91,0xfc,0x38,0x6,0x50,0x8,0x31,0xb1,0xe2,0x52,0x24,0x26,0xc7,0x6e,0xdf,0xe3,0x2b,0x5f,0xff,0xc6,0xd1,0xf1,0xcf,0x36,0x2d,0xde,0xf1,0x96,0x27,0x68,0x49,0x2d,0x92,0xde,0x71,0xc0,0xd0,0xef,0x28,0xc0,0xc4,0x39,0x0,0x19,0xd3,0xd0,0x63,0x7b,0xe7,0x16,0x6,0x66,0x83,0x2d,0x64,0x9b,0xec,0x6b,0x17,0x63,0x60,0xc6,0x97,0xc1,0x38,0xf4,0xca,0x56,0xbc,0x1b,0xc8,0x63,0x9d,0x63,0xa9,0x2d,0x31,0x41,0xe8,0xf8,0x4,0x6a,0xed,0xae,0xee,0xa0,0xdf,0x5d,0x31,0x33,0x70,0x9c,0xa5,0xc1,0x61,0xe2,0x70,0x11,0xa8,0x61,0xfb,0x29,0x1f,0x3c,0xf5,0xa7,0x3,0xa5,0xd9,0xc6,0x18,0xb0,0xdf,0x5e,0x6a,0xf0,0x87,0xf8,0x3b,0x8e,0xfd,0x1e,0xd6,0x50,0xe0,0xca,0xc4,0xd2,0xdf,0xa6,0x69,0xf0,0xc3,0xef,0xf8,0xfe,0x23,0x30,0xef,0xb3,0x9f,0xff,0x22,0xfe,0xef,0x7f,0xf7,0x87,0x18,0x86,0x41,0x19,0x1c,0x29,0x12,0xb8,0x17,0x63,0x64,0x36,0xdd,0xca,0xbd,0x4a,0x4a,0x6e,0x22,0xff,0x46,0xe7,0x3d,0xa6,0x81,0xd2,0x8f,0x13,0xfb,0x2,0xe2,0x84,0x94,0x59,0xd8,0x30,0x96,0x13,0x88,0xc7,0x61,0x4f,0xec,0x41,0x83,0xf5,0x36,0x8b,0x1b,0x9b,0x18,0x26,0xf6,0xa9,0xca,0x5,0x53,0x90,0x40,0xbc,0xed,0xd5,0x2d,0x5,0x8f,0x77,0x57,0xb7,0x57,0x19,0xd,0x89,0x81,0x3e,0x2,0xf6,0x82,0x2,0x98,0x31,0x90,0x9c,0x38,0x86,0x9,0x43,0xbf,0xa3,0xe0,0x14,0x66,0xe1,0x78,0xdf,0x28,0x60,0x2e,0xde,0x8a,0x96,0x3,0x58,0x66,0x9f,0x2b,0xc3,0x6c,0xc7,0xea,0x3,0x58,0xab,0xd6,0xb,0xad,0x5c,0x62,0x33,0x8b,0xc4,0x5b,0x49,0x4,0xcf,0x33,0x80,0xc3,0xc0,0x98,0xb1,0x76,0x1,0x66,0x9,0x3,0x59,0xec,0x11,0xb2,0xf8,0xf2,0x61,0x66,0xc6,0x4b,0xea,0xfd,0x2,0x11,0x29,0xe6,0xc3,0x72,0xcc,0x25,0x5f,0xc1,0xb4,0x90,0x1e,0xcf,0x73,0x58,0x54,0x9,0x6f,0x98,0x26,0x34,0x6d,0xcb,0x36,0x7,0x56,0x6d,0x28,0x28,0x6c,0xcb,0xe9,0xcf,0x58,0x6b,0x59,0xad,0x9c,0x8a,0x39,0x25,0xab,0xd7,0x1f,0x94,0x99,0x86,0x45,0xa2,0xb1,0xe0,0x6e,0x62,0xf1,0x40,0x8c,0x47,0xbb,0xd8,0x38,0xb1,0xe2,0x5b,0x68,0x66,0x70,0x69,0xf6,0x44,0xe5,0xf0,0x22,0x6,0x3a,0x5,0xb8,0x13,0x20,0x6f,0x96,0x34,0x1b,0x2c,0xb2,0x34,0x56,0x3,0x28,0xe,0x3,0x2d,0xd2,0x71,0x5c,0xef,0x1,0xc0,0x76,0x78,0xc,0x91,0x2a,0x1f,0xc0,0x82,0xca,0x6c,0x2c,0x3,0x60,0xf4,0x38,0x19,0xc5,0x7b,0x3d,0x83,0xa0,0x25,0x0,0x7c,0x2c,0x43,0x7e,0x2e,0x31,0x1d,0xa7,0x31,0xb0,0xfc,0x9c,0x7e,0xea,0x5e,0xaf,0xcc,0xcf,0xf1,0x47,0x8a,0x67,0x9b,0xf3,0xd1,0xe7,0x53,0x7f,0x41,0xe,0xdf,0x9f,0x83,0x20,0x15,0x73,0xea,0x77,0x6b,0x6d,0x72,0xad,0xd6,0x15,0xb5,0x6a,0xd5,0xaa,0x0,0x60,0xad,0x5a,0xb5,0x6a,0xfd,0xd,0x68,0xa4,0x72,0xd2,0xb6,0x89,0x0,0x90,0xd9,0xff,0x88,0xa4,0xbc,0xb6,0x60,0x32,0x70,0x83,0x93,0x93,0x36,0xc,0x22,0xb9,0x4d,0x91,0xbc,0xda,0xca,0xe6,0x27,0x25,0x92,0x5b,0x19,0x6b,0x59,0x66,0x9b,0xa,0x79,0xd0,0xfa,0x62,0x52,0x80,0x2e,0x69,0x7a,0xa6,0x61,0x28,0x82,0x40,0x82,0x2e,0x4c,0xbb,0xb3,0x73,0x8c,0x43,0xf,0x67,0x1d,0x9c,0x73,0xf0,0x4d,0x33,0x37,0x3d,0xbc,0xfb,0xfd,0xbe,0xf,0x7f,0x9c,0xbc,0x8c,0xe,0xea,0x7,0xdf,0xf2,0xdd,0xf8,0xee,0xd7,0x3c,0x3a,0x33,0xd3,0x40,0xf2,0xde,0x38,0x4d,0x98,0x86,0x9e,0xfd,0xf9,0xc4,0x9b,0x2f,0xab,0x17,0xdc,0x34,0xf6,0x48,0x29,0xe2,0x6c,0xd3,0xe1,0xdd,0x6f,0x7f,0x23,0x1e,0x7e,0xd9,0x4b,0x61,0xc,0x49,0x68,0xa7,0x71,0xc0,0xb0,0xdf,0x21,0xa5,0x84,0x14,0xa7,0x55,0x50,0x4b,0xc0,0x4d,0x1,0x1,0xbd,0x6f,0xe0,0x3d,0xb1,0xd5,0x86,0xfd,0xe,0x99,0x19,0x82,0xbb,0xed,0x25,0xf6,0xdb,0x4b,0xec,0xae,0xee,0x10,0xa0,0x98,0x28,0x6d,0x52,0x0,0xcb,0x65,0xf7,0x7b,0x8,0x9e,0x42,0x53,0x28,0x65,0x71,0x1f,0x43,0x40,0x8,0x13,0x9c,0xf3,0xd8,0x5d,0xde,0xc1,0xc8,0x20,0xe5,0xd5,0xe5,0xb3,0xc8,0x89,0x2,0x33,0x42,0x98,0xf0,0xda,0x57,0xbd,0x2,0x2f,0x79,0xe0,0xe6,0xd1,0x71,0xff,0xf4,0x63,0x9f,0x42,0xe4,0x86,0x2a,0x4c,0x23,0x25,0xe4,0xa6,0xc8,0xc6,0xf3,0xb3,0x77,0xd5,0xea,0xfb,0xc9,0x20,0xb0,0x75,0xe,0xc3,0xb0,0x57,0x26,0x4c,0xe4,0xd7,0xae,0x35,0x15,0x92,0xe8,0x9c,0x73,0x56,0xc9,0x6f,0x8a,0xc4,0xa8,0xb,0xd3,0x78,0x57,0xa7,0x25,0x23,0x0,0x36,0x32,0xfa,0xdd,0x15,0x72,0x22,0xa0,0xd2,0x3a,0xaf,0xb2,0xb8,0x30,0x8d,0x27,0xe5,0x4c,0xc6,0xcc,0x5e,0x8a,0x29,0x25,0xc,0xfb,0x1d,0xa6,0x71,0xc4,0x34,0xd,0xd8,0x5d,0xdd,0xc1,0xd8,0xef,0x11,0xa7,0x9,0x21,0x6,0x6e,0xfa,0xb1,0xf0,0x1d,0x9c,0x26,0xf2,0xae,0x4c,0x39,0x21,0x85,0xa0,0xa9,0xa2,0xd6,0x5a,0xd8,0xe6,0x1c,0x95,0x42,0x51,0xab,0xd6,0x7d,0x99,0xb8,0xa,0x10,0xa4,0x90,0x71,0x5a,0xcb,0xf0,0x15,0xc7,0x53,0x88,0xc5,0x80,0x39,0xe0,0x86,0x19,0xb1,0x6e,0x20,0x20,0x5f,0x2,0x7c,0x66,0xa9,0xe8,0xc,0x1a,0x36,0xd,0x5,0x56,0x59,0xeb,0x8,0x10,0xe3,0x90,0x2b,0xcb,0xb6,0x9,0xc6,0x58,0x78,0xcf,0x49,0xf7,0xc6,0xc0,0x35,0xad,0x6,0x6a,0x19,0x33,0x33,0x1,0x1d,0x8f,0x41,0xc2,0x20,0x13,0x5b,0xc,0xd9,0x38,0x93,0xd,0x32,0x1,0xec,0x64,0x7e,0x32,0xd6,0x2a,0x9b,0x5e,0x80,0x2d,0x53,0x1e,0xdb,0x3a,0xdd,0x57,0x98,0x37,0x86,0xe,0x2,0x29,0x78,0x8c,0x5a,0x48,0x5e,0xad,0x51,0x66,0x61,0x66,0x16,0xb7,0x32,0xf4,0x90,0x8b,0x8d,0xb8,0x19,0x12,0x92,0xd7,0xca,0x9c,0xac,0x5e,0x86,0x38,0x8,0xd7,0x30,0xe6,0xe0,0x7a,0x0,0x98,0xbb,0xb0,0xf3,0xee,0xf9,0x76,0xe7,0xa3,0xd7,0x88,0x65,0x9d,0xde,0x53,0xe1,0xcd,0x7a,0x90,0x4b,0xbc,0x7a,0x9c,0xfc,0xd7,0x3a,0x16,0x3f,0xd7,0x8d,0x9e,0x12,0x94,0xcb,0xa7,0x9f,0x4b,0xc9,0xa4,0x54,0xb9,0x75,0x9,0xf2,0x89,0x16,0xfc,0x9b,0xbf,0xb2,0xfc,0x5c,0x7e,0xcf,0xca,0x73,0xd6,0xaa,0x55,0xab,0x56,0x5,0x0,0x6b,0xd5,0xaa,0x55,0xeb,0xc5,0xdd,0x48,0x95,0x1e,0x37,0xb6,0x30,0x7,0x97,0xef,0x2b,0x3,0xae,0x94,0xfd,0x28,0xb8,0x34,0x71,0xca,0xaf,0x83,0xf5,0x9e,0x64,0xaa,0x79,0x96,0x13,0xc5,0x18,0x30,0xd,0x3d,0x83,0x84,0x1,0xc6,0x0,0xd3,0x38,0x72,0xf2,0xe2,0xca,0xe5,0x30,0x43,0x4b,0x9a,0x1f,0xdf,0x34,0x2c,0xc3,0xec,0x35,0x74,0x24,0xa5,0x88,0xa6,0xdb,0x14,0x81,0x12,0x96,0xd3,0x5f,0xe7,0x6b,0x9a,0xc6,0x1,0x1f,0xf9,0xe4,0x67,0xf1,0xe4,0x37,0x9e,0x3e,0x3a,0x47,0xdb,0x36,0xf8,0xb9,0x1f,0xff,0x21,0xbc,0xf6,0xf1,0x87,0x58,0xb2,0x1b,0x35,0x1c,0x62,0x1c,0x7a,0x18,0x18,0x84,0x10,0x18,0x84,0x4a,0xca,0x24,0xeb,0xba,0xd,0x7e,0xf8,0x6d,0xaf,0xc7,0x7f,0xf9,0x4f,0x7f,0x1e,0x3f,0xf9,0xee,0x77,0x2,0x39,0xb2,0x4f,0xa1,0x78,0xdb,0x1,0x63,0xbf,0x5f,0xa4,0x2e,0x96,0x8d,0x47,0x6,0x10,0xc2,0x44,0xf2,0xd4,0x4c,0x12,0xd9,0x9c,0x89,0x71,0xe6,0x7c,0x83,0xdd,0xd5,0x25,0x9c,0xf7,0x8,0xe3,0x40,0x12,0xb1,0xcd,0x19,0x52,0x8c,0x70,0xde,0x69,0xc2,0xae,0x36,0x64,0x66,0x3d,0x3d,0x37,0x84,0x11,0x89,0x83,0x4a,0x72,0xc1,0xa4,0x4,0x80,0x7e,0xbf,0x5d,0x30,0x1e,0xe9,0xb9,0x4d,0xe4,0x3f,0xe8,0x3d,0x1e,0x7e,0xe9,0x4d,0x6e,0x64,0x97,0xb5,0xdb,0x12,0x2b,0x71,0xec,0xf7,0xc8,0xc8,0xf0,0x4d,0xb,0xdf,0xb4,0x18,0xfa,0x3d,0x33,0x21,0xe3,0x49,0x26,0x81,0xbc,0xa7,0x30,0x86,0x24,0xd6,0xd3,0x44,0x80,0xe4,0x34,0xad,0x87,0x79,0x80,0x9a,0xd0,0xc8,0x20,0xa3,0x65,0xf0,0x78,0x36,0xdd,0xf7,0x27,0xdb,0x90,0x14,0x49,0x5e,0x1c,0x63,0xe0,0xe7,0xd6,0xe8,0x33,0x10,0x4f,0xc7,0xdd,0xe5,0x1d,0x18,0x18,0x38,0x7e,0xbf,0x8e,0x4f,0x4e,0x8d,0x75,0xd3,0x76,0x70,0xce,0xb3,0xe4,0x3c,0x62,0x7b,0x29,0x89,0xcf,0x3d,0xa6,0x40,0x40,0xb1,0x78,0x47,0x96,0xbf,0x2b,0x56,0x58,0x34,0x7,0xd,0x5c,0xc,0x1,0x69,0xdc,0xd6,0xf1,0xa6,0x56,0xad,0xfb,0x50,0x87,0x36,0x0,0x6,0x12,0x58,0x91,0x14,0x1c,0x83,0x2,0x43,0xcc,0xc,0x67,0x69,0xad,0xb0,0xde,0x4a,0x56,0xbb,0xb2,0xf0,0x78,0xfc,0xf3,0x4d,0x8b,0x94,0xd8,0xff,0x73,0x1a,0x68,0x1c,0xe0,0xb1,0x44,0x0,0x41,0x9a,0x8f,0x8,0xec,0x4b,0x5,0x3,0x98,0x36,0x6a,0x22,0xca,0xa8,0x8,0x61,0xe0,0xc9,0xb8,0x24,0x1b,0x6,0xce,0x35,0xc8,0x91,0xc2,0x47,0xa0,0xde,0x7d,0x5,0xb,0x71,0x11,0x9c,0x41,0xa9,0xe8,0xe2,0xd7,0x9a,0x72,0x9a,0x65,0xb7,0x2a,0x63,0xc6,0x1,0x23,0x2f,0x73,0x78,0x97,0x23,0xa0,0x51,0x19,0x71,0x7c,0xbc,0x34,0xcf,0xed,0x32,0x57,0xc8,0x18,0x36,0xb3,0xfe,0xa0,0xa0,0xe7,0xbc,0x39,0x68,0x97,0x81,0x61,0xd6,0xe2,0x30,0xf,0x64,0xc1,0xb6,0x2b,0x27,0x84,0xbb,0xa6,0xa1,0x1f,0xcb,0x72,0x17,0x40,0xa2,0x84,0x72,0x98,0x59,0xa2,0xbb,0xf4,0x17,0x2c,0xe7,0x11,0xf3,0xbc,0x61,0xb9,0xfb,0xb0,0xb0,0xc2,0x92,0x4b,0x97,0x57,0x0,0xbe,0x3,0x59,0x6f,0x5e,0x3,0xdf,0x70,0xa8,0xb3,0x56,0xdf,0xc6,0xc3,0x89,0xb6,0xc,0x5e,0x59,0xc3,0x11,0xf3,0x89,0xab,0x33,0x2b,0x57,0x7b,0xc4,0x67,0xac,0xec,0xbf,0x5a,0xb5,0x6a,0x55,0x0,0xb0,0x56,0xad,0x5a,0xb5,0xfe,0x66,0x14,0x35,0x1c,0xd0,0x86,0x43,0x16,0xd5,0xd2,0xc8,0xc8,0xc2,0xff,0x70,0x35,0x29,0xd,0x8d,0x34,0x29,0x0,0x18,0x74,0x2,0xa5,0xf,0xf2,0xbf,0x1,0x10,0xd8,0x92,0x33,0x8c,0x75,0xda,0xfc,0x9c,0xa,0x7f,0xc8,0x39,0x73,0xf3,0x15,0x91,0x42,0xc4,0xc8,0x12,0x4c,0xcf,0x4d,0x97,0x0,0x6c,0xfb,0xed,0xa5,0x32,0xe6,0xa6,0x69,0xd0,0x10,0xe,0x1,0x95,0x9c,0x73,0x48,0xd9,0xe2,0x37,0x7f,0xe7,0x7d,0x2c,0x21,0x5e,0xd6,0xb5,0xf3,0xd,0xfe,0xf1,0xcf,0xbe,0xb,0xff,0xe0,0x47,0xbe,0xf,0xf,0xdf,0x3c,0x47,0x4e,0x1,0xd0,0x46,0x90,0x1a,0xc9,0x30,0x51,0xe0,0xc8,0x83,0xd7,0x37,0xf8,0xbb,0xef,0x7c,0x33,0xfe,0xeb,0x7f,0xf6,0xb,0xf8,0xa5,0x7f,0xf0,0xe3,0x78,0xc5,0xcb,0x1f,0x26,0x6f,0x42,0xeb,0xe0,0xac,0xc7,0xf9,0xb5,0x9b,0xca,0x72,0xd4,0x67,0xb2,0xd2,0x7a,0x38,0xe7,0xb9,0xd1,0x3,0x62,0x9c,0x90,0xa,0x20,0xcc,0x58,0x8b,0xa6,0x6d,0xe9,0xbe,0x0,0x65,0x5b,0x9e,0x5d,0xdc,0x40,0x9c,0x88,0x3d,0x99,0xb8,0x51,0x74,0xde,0x9f,0x60,0x4e,0xd0,0xd7,0xf6,0xbb,0x2b,0x65,0xda,0x65,0xf6,0x53,0x14,0x50,0x95,0x7c,0xec,0x28,0x14,0x84,0x98,0x8d,0x19,0x9b,0xb3,0xb,0x58,0x63,0xd1,0x36,0xeb,0xa0,0xd8,0x13,0xdf,0xf1,0x1a,0x78,0xdf,0xc2,0xb7,0x1d,0xbf,0x8f,0x56,0xbd,0x6,0xd,0xc,0xae,0x5d,0xbb,0x58,0x6d,0xb6,0x2c,0x37,0xdc,0x4d,0xdb,0xc1,0xfb,0x6,0x9b,0xf3,0xb,0x92,0x3e,0xf3,0xf3,0x21,0xb0,0x6e,0x5a,0x6d,0xee,0xad,0x6f,0x66,0x3f,0x2e,0x66,0x8e,0xd2,0xe7,0x2b,0xa9,0xd1,0xfe,0xe1,0xad,0xb,0x33,0x15,0xc6,0x10,0x60,0xc8,0x1e,0x92,0xe4,0x61,0x19,0x14,0x70,0x9d,0xa6,0x91,0x4d,0xfd,0x4f,0xb3,0x16,0x9d,0xf3,0x70,0x4d,0xa3,0xc,0x9b,0x6e,0x73,0x86,0x30,0xd,0xd8,0x6f,0x2f,0x15,0x5c,0x15,0xbf,0x47,0x95,0x5d,0xeb,0xef,0x84,0x51,0x49,0x3d,0xfd,0xe,0xd9,0xd9,0x3,0x6c,0x2d,0xc0,0xa4,0x56,0xad,0x5a,0xdf,0x1c,0xbc,0x52,0x4a,0x3f,0xb,0xc6,0xb9,0xa4,0xd5,0x96,0x29,0xa7,0x92,0x26,0x2f,0x96,0x16,0x12,0x9e,0x31,0xcb,0x7f,0x9b,0x99,0xd9,0xc6,0x63,0x86,0x30,0xf4,0x84,0x89,0x2c,0x16,0x14,0xc2,0xda,0xb,0x61,0xd4,0xd7,0x2b,0x43,0xf,0x33,0x58,0xe7,0x59,0xfe,0xaf,0x6c,0x77,0x61,0xd1,0xdb,0xd9,0x16,0x41,0xc6,0x78,0xdf,0xb4,0xb4,0x39,0x6,0x3,0xef,0x3d,0x72,0x8e,0x7a,0x5e,0x62,0x7,0xce,0xe0,0x97,0x84,0x88,0x18,0x6b,0xe1,0xac,0x57,0xcf,0x3a,0x3a,0x16,0x79,0xd8,0x41,0x42,0x3e,0x58,0xa6,0x9b,0x53,0xd6,0x4d,0x2e,0x3a,0x2f,0xa,0xa6,0xa3,0x65,0x56,0x22,0xf3,0x26,0xad,0x30,0x0,0x8d,0x3e,0x42,0x1,0x1c,0x73,0x1,0x19,0x89,0xb4,0xd9,0xf2,0xfc,0x4f,0x63,0x72,0x11,0x3e,0x62,0x64,0xfc,0x9b,0x99,0x99,0xea,0x3,0x28,0xeb,0x8e,0x43,0xa0,0x4f,0x52,0x89,0x31,0x33,0xf,0xcd,0x21,0x76,0x26,0x72,0xe8,0xbc,0x84,0xf4,0x4c,0xc1,0xf0,0x3c,0x5,0x8,0x1e,0xc3,0x5a,0xcf,0xe3,0x43,0x77,0xf2,0xeb,0x79,0xe5,0xe8,0xe6,0xe0,0x3a,0xcd,0xc,0xde,0xdd,0xcd,0x30,0x50,0xce,0x63,0xb0,0x22,0xf3,0x3d,0xc8,0xec,0x58,0x59,0x3f,0xad,0xfd,0x5c,0xbe,0xc7,0xfd,0xaf,0x43,0xa5,0xc5,0xc,0x79,0xe0,0x3,0x59,0xab,0x56,0xad,0x5a,0xdf,0xaa,0x55,0x43,0x40,0x6a,0xd5,0xaa,0x55,0xeb,0x5e,0x6b,0xda,0x62,0xe7,0x59,0x99,0x6b,0x1c,0x8,0x32,0x2f,0x3c,0xd3,0x22,0x10,0x24,0xa5,0x84,0x69,0x9a,0xd0,0xb4,0x9d,0xfa,0x6,0xaa,0x81,0x3a,0xad,0xf6,0x55,0x5a,0x95,0x13,0xc9,0x39,0x29,0x61,0xb7,0xd1,0xd0,0x10,0x63,0x4e,0x3,0x21,0xd4,0x84,0x59,0xa4,0x3c,0xe9,0x35,0xa5,0x18,0x31,0x8e,0x14,0xf0,0x40,0x12,0x51,0x32,0x68,0xf7,0x4d,0xab,0x5e,0x73,0x2,0x1e,0x52,0x18,0xc6,0x4,0xeb,0x3c,0x3e,0xf4,0xc9,0x2f,0xe1,0x90,0x26,0x6e,0xf,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x7b,0x3f,0xf5,0x39,0xbc,0xf1,0xbb,0xbe,0xe3,0xe8,0x3c,0x6d,0xd3,0xe0,0x1d,0xdf,0xf7,0x6,0xbc,0xf5,0x8d,0x4f,0xe0,0xc9,0xa7,0x9e,0xc1,0x57,0xbf,0xfe,0xd,0xdc,0xbe,0x7d,0x7,0xe3,0x34,0xe1,0x6c,0xb3,0xc1,0x4b,0x1f,0x7c,0x0,0x8f,0x3c,0xf4,0x20,0x5e,0xfa,0xe0,0x3,0xe8,0xda,0xf6,0x8,0xe4,0x72,0xbe,0x81,0xf5,0xc4,0x48,0x6b,0xbb,0xd,0x7c,0xd3,0x92,0x7c,0x38,0xa5,0xd5,0x27,0x2d,0xcc,0x44,0x4a,0x9a,0x5c,0xb2,0x1b,0x62,0xc,0x94,0x2a,0xeb,0xc8,0x27,0xcf,0xfb,0x6,0x21,0x4c,0x18,0xf6,0x5b,0xf8,0xb6,0x83,0xb5,0x16,0xed,0xd9,0x85,0x6,0xa4,0xac,0x2d,0xc6,0xd,0x27,0x13,0xb7,0xdd,0x46,0x4d,0xd3,0x13,0xcb,0x86,0xc7,0xa1,0x2f,0x3c,0x92,0xa8,0x79,0xa3,0x73,0x8c,0xc0,0x3e,0xe3,0xfc,0xda,0xd,0x3c,0x7d,0xeb,0x52,0x93,0x2b,0xcb,0x7a,0xf3,0x9b,0xbe,0x1b,0x1f,0xfc,0xb3,0x4f,0xe3,0xb3,0x5f,0x7b,0x16,0xd3,0x34,0xc2,0x4e,0xd4,0xfc,0xa6,0x10,0xf0,0xfa,0x6f,0x7f,0x5,0x7e,0xfe,0x27,0x7f,0x18,0xce,0xb9,0x15,0x20,0x8d,0xd2,0x30,0x8d,0xb5,0x78,0xec,0xc1,0x9b,0xe8,0x1a,0x87,0x8f,0xff,0xe5,0x97,0x1,0x4,0xc4,0x10,0xf8,0x33,0xb2,0xf2,0x3a,0x6b,0x95,0x21,0x9a,0x12,0x85,0xb3,0x64,0x5,0x99,0xa7,0xd5,0x36,0x46,0x53,0x30,0x39,0xf5,0x52,0x98,0x83,0x31,0x92,0xfc,0x39,0x31,0x40,0x47,0xcc,0x3f,0x92,0x93,0xdb,0x95,0x10,0x10,0x63,0xc,0x7c,0xbb,0x41,0xc,0x23,0x7c,0x6a,0xd1,0x76,0x1b,0xc,0xfb,0x1d,0x90,0x81,0xab,0x3b,0xb7,0xd1,0x76,0x1d,0xa7,0x43,0xf,0xca,0x12,0x14,0xa0,0xd2,0xb9,0x39,0xbc,0xc5,0x7b,0xaf,0x9,0xd5,0x22,0x95,0x73,0xdd,0x5,0xc2,0xfe,0x56,0x1d,0x74,0x6a,0xd5,0x7a,0xa1,0xb,0x7c,0x66,0xf0,0x96,0xe0,0x6,0x1,0x6b,0x59,0xd3,0x6d,0xd,0xc,0x8c,0xb3,0x4,0x4e,0x19,0x3,0xc3,0xbf,0x8b,0x56,0x40,0x2a,0x80,0xe5,0xbf,0xd3,0x1c,0xde,0x71,0x18,0xe,0x91,0x29,0xe0,0x6a,0x1,0xae,0x18,0xa0,0x69,0x37,0x6a,0x87,0x61,0xac,0xa3,0xdf,0xff,0xa6,0x25,0xc0,0x8b,0xa7,0x9,0x6b,0xc8,0xdf,0x2f,0xc6,0x40,0x49,0xe9,0x39,0x33,0x93,0x99,0xc6,0x22,0xcb,0xb2,0xca,0xc4,0x73,0xa4,0xa4,0xb,0x1b,0xe3,0x16,0x73,0x8d,0x86,0x60,0xe4,0xd2,0xdb,0x30,0x21,0x22,0xa9,0xf7,0xa1,0x58,0x77,0xc8,0x3c,0x20,0x20,0xa0,0x48,0x87,0x73,0x8a,0xf4,0x6c,0x44,0x9a,0x6b,0xf9,0xb9,0xf0,0x58,0x2f,0xe3,0x94,0x81,0xd5,0x73,0xc2,0x58,0xe4,0x14,0x54,0xc2,0x8c,0x7c,0xcc,0xc8,0x3b,0x4e,0xd0,0x4d,0x3a,0x1b,0xe9,0xda,0x60,0xf1,0x73,0x3c,0xb6,0x1b,0x33,0x6b,0x78,0xf,0xbc,0xf9,0x84,0x79,0x58,0x26,0xee,0xea,0x9b,0xc1,0xef,0xe3,0x1c,0xd4,0x71,0x1a,0xec,0xbb,0xd7,0xca,0xe7,0x9b,0xe6,0x3,0x9e,0x62,0x2e,0x96,0xd7,0x7,0x14,0xe9,0xbb,0x7,0xe7,0x5a,0x5c,0xa3,0xa4,0xf3,0xe6,0x63,0x64,0x4e,0xde,0xf0,0xc3,0x74,0x91,0x7c,0xa,0xac,0x7b,0x4e,0x2e,0x82,0x27,0xbf,0x9f,0xef,0xf1,0x7c,0xf2,0xc9,0xb3,0xd6,0xaa,0x55,0xab,0x56,0x5,0x0,0x6b,0xd5,0xaa,0x55,0xeb,0x45,0x88,0x0,0xe6,0x83,0x2e,0x63,0x36,0xf,0x2f,0xe2,0xe2,0x20,0xfe,0x6a,0x89,0x4d,0xce,0x9d,0x23,0x16,0x9a,0xb0,0x2d,0xc,0xf2,0x9c,0x16,0xec,0x2c,0xa6,0x91,0x0,0xb8,0x94,0x12,0x2c,0x3,0x24,0x96,0xd9,0x13,0xce,0xb9,0x55,0x9f,0xbc,0xb2,0x91,0x50,0xdf,0x19,0x83,0x2,0x48,0x21,0x90,0x72,0xe8,0xf7,0x68,0x9a,0xe,0x4d,0xb7,0xe1,0x34,0x45,0x4a,0xb4,0x55,0x36,0x83,0x9f,0xfd,0xea,0x72,0xf6,0xf8,0x17,0xff,0xea,0x77,0xf1,0x5f,0x3c,0xf8,0x0,0x1e,0x79,0xf8,0xa5,0xab,0xe7,0x3c,0xdb,0x74,0x78,0xd5,0x63,0x8f,0xe2,0x55,0x8f,0x3d,0xfa,0x4d,0xf6,0xf,0x94,0xfc,0x9a,0x53,0x86,0xf3,0x16,0x51,0xc0,0xbf,0x13,0xc0,0x12,0xa,0xf9,0x2e,0x35,0x9e,0x59,0x65,0x61,0xe2,0x17,0x97,0x91,0xd1,0xef,0xb7,0xd8,0x9c,0x5f,0x63,0x2,0x0,0x85,0x51,0x78,0xef,0xd5,0x7b,0xf,0xe6,0xda,0x89,0x66,0x84,0x1a,0x35,0x62,0xe7,0x6d,0x30,0x8d,0xbd,0x6,0x58,0x48,0x73,0x29,0x2c,0x3a,0xe0,0xc,0x29,0x27,0x34,0x4d,0x8b,0x76,0x73,0x8e,0x8c,0x8c,0xbf,0xfc,0xf2,0x93,0xb8,0xda,0xee,0x70,0xe3,0xfa,0x32,0x39,0xf9,0xe2,0x6c,0x83,0xff,0xec,0x97,0xfe,0x1e,0x7e,0xeb,0xf7,0x3f,0x80,0x4f,0x7c,0xf6,0x6b,0xc8,0x30,0x78,0xf4,0xa1,0x7,0xf0,0x3d,0xdf,0xf5,0x1a,0xbc,0xfe,0xb5,0xaf,0x46,0xd7,0xb5,0xab,0x8f,0xe8,0x55,0x8f,0xbd,0x1c,0x6f,0x7c,0xe2,0x31,0xbc,0xe1,0x89,0xc7,0xf1,0x96,0x37,0x7e,0x27,0x7e,0xeb,0xf7,0xde,0x8f,0x4f,0x7e,0xfe,0x6b,0x14,0xa2,0xe1,0x3c,0xcb,0xb6,0xf3,0xea,0xb3,0x15,0x49,0xb6,0x0,0x6d,0x43,0xbf,0xa3,0x4,0xcd,0x13,0x4d,0x58,0xca,0xf4,0x19,0x49,0xc,0x6e,0x4a,0x40,0x89,0x24,0x38,0x3,0xc0,0xd4,0xef,0x71,0x76,0x7e,0x4d,0x19,0x38,0x6b,0xcc,0x50,0x64,0x20,0xc5,0x49,0xc1,0xea,0x99,0x71,0x63,0xd0,0x6d,0x36,0xb0,0xce,0xa3,0xdf,0x5d,0xaa,0x34,0x3d,0x4c,0x23,0x31,0x5,0xd9,0x68,0x3e,0xc6,0x80,0xa6,0xed,0x48,0x16,0x5f,0xb0,0xc,0x5d,0xd3,0x1,0xdb,0x2a,0x1,0xae,0x55,0xeb,0xfe,0x4c,0x5b,0x69,0x9,0x5d,0x48,0x32,0xbd,0x4,0x64,0x48,0x3a,0x5,0x33,0xc6,0x6c,0x91,0x6c,0x2f,0x8c,0x36,0x18,0xa3,0x92,0x5c,0x9,0xa6,0x72,0x9e,0x18,0x77,0xc2,0xec,0x95,0x40,0x20,0xd,0xca,0x10,0xdf,0x3f,0x6b,0x14,0x18,0x11,0x26,0x5f,0xe4,0x31,0xcb,0x1a,0x8b,0x10,0x2,0x9c,0x73,0x88,0x21,0xb0,0xd4,0xd7,0x6b,0xd2,0xaf,0x80,0x41,0x2,0x1c,0x4a,0xd8,0x93,0x91,0x4d,0xb3,0xc2,0xcf,0x70,0xde,0x5c,0x70,0xf3,0x78,0x95,0x12,0xac,0x6f,0x18,0xd8,0x84,0x32,0x5,0x8d,0x21,0xa6,0xb3,0xc6,0x7a,0x30,0xf8,0x47,0xd6,0x1b,0x94,0x46,0x6c,0x79,0xbe,0x2a,0xe7,0x24,0x53,0x78,0xe7,0x2d,0x92,0x78,0xe5,0x79,0xf1,0xe6,0x1f,0x8e,0xc2,0xa7,0xcc,0xfc,0xec,0xf5,0x38,0x47,0xb0,0xec,0xcc,0x7e,0x66,0x36,0xe4,0x32,0x8c,0xe5,0x38,0xd0,0x6a,0x4e,0x23,0x3e,0x4,0x15,0x97,0x73,0xa9,0x80,0x9d,0xcf,0xcf,0xcb,0xcf,0x3c,0x3f,0x20,0xb0,0x5c,0x13,0x95,0x4c,0x3e,0x35,0x42,0x2c,0x90,0xe3,0x92,0xfd,0x77,0x38,0xcf,0xe5,0xbc,0xe,0xb7,0xe5,0x19,0xd6,0xd4,0x43,0x1f,0x2a,0xa8,0x71,0x9c,0x9,0x5c,0x7e,0xfd,0x6e,0x8b,0x16,0x99,0xa7,0x96,0x40,0x65,0x5e,0x39,0xaa,0x1,0x90,0x16,0xf7,0xbc,0x9e,0xd2,0x5c,0xab,0x56,0xad,0x5a,0x15,0x0,0xac,0x55,0xab,0x56,0xad,0x17,0x37,0x10,0x78,0x20,0xf5,0x30,0x9c,0x6c,0x8,0x6b,0x38,0xaf,0x21,0xab,0x1f,0x5b,0x64,0xb9,0x14,0x35,0x22,0x89,0x25,0x9f,0x46,0x83,0x3f,0xd4,0xc4,0xbc,0x68,0x9c,0x9c,0x6f,0x8a,0x6,0x6d,0xe5,0x32,0x38,0x5c,0x22,0x86,0x0,0x18,0xc0,0x59,0x8f,0x21,0xec,0x30,0xe,0x7b,0xec,0xaf,0x2e,0xd1,0x76,0x1b,0x34,0x4d,0x8b,0xa1,0xdf,0x91,0x24,0xab,0x21,0xa6,0x5c,0xc7,0xa9,0xba,0x29,0x6,0x4c,0x99,0x0,0xca,0x14,0x29,0x14,0xe3,0xd9,0x3b,0x57,0xf8,0xe5,0x7f,0xf1,0xeb,0xf8,0x27,0xbf,0xf8,0xd3,0x27,0x41,0xc0,0x6f,0xb6,0xb6,0xbb,0x3d,0xf6,0xfd,0x9e,0x2,0x2a,0x10,0x11,0x3,0xf9,0xd4,0xf9,0xa6,0x41,0xc,0xe3,0xca,0xe3,0xcd,0x2a,0x51,0x56,0x79,0x6e,0x4e,0xa,0x6e,0x8d,0xc,0xd6,0x85,0x71,0xc4,0xf5,0x9b,0xf,0x22,0x86,0x9,0x9b,0xb3,0x73,0x5d,0xac,0xc7,0x10,0xe0,0xdb,0xe,0xdd,0xe6,0xfc,0x60,0xd9,0xbf,0xec,0x69,0x62,0x8,0x68,0x1a,0x4a,0x98,0x24,0xef,0xc6,0xac,0xde,0x56,0xfd,0x7e,0x8b,0x38,0x4d,0x70,0x4d,0x83,0x69,0x1a,0xd1,0x9d,0x5d,0x43,0x8a,0x11,0x61,0x1c,0xb0,0x39,0xbf,0x86,0x29,0x1,0xef,0xff,0xd0,0x9f,0xe1,0xdd,0xef,0x7a,0xc7,0xd1,0xa1,0x2f,0xce,0xcf,0xf0,0xf7,0x7f,0xfc,0x6f,0xe3,0xef,0x4e,0xe4,0x8b,0xe5,0xbc,0x3b,0x9,0xc6,0x49,0xbd,0xfa,0xf1,0x47,0xf1,0x4f,0x7e,0xf1,0xa7,0xa,0x76,0x7,0xb4,0xa1,0x8c,0x61,0x52,0x3,0xfd,0xb5,0x46,0x25,0x86,0x11,0xc6,0x78,0x6,0x93,0x29,0x7d,0x38,0x26,0x92,0xb1,0x9d,0x62,0x3f,0x8a,0xb4,0x4d,0x58,0x23,0xe2,0xcd,0xd8,0xb4,0x1d,0xe2,0x34,0xa1,0xed,0x36,0xf4,0x2c,0x63,0x44,0x77,0xb6,0x2e,0x5b,0xce,0x9a,0xb2,0x49,0x9e,0x61,0x39,0x67,0x62,0x79,0x5a,0x7,0xdf,0xb4,0x98,0x46,0x4a,0x70,0xe,0x13,0xf9,0x38,0x9e,0x5d,0x5c,0x9b,0x59,0x7e,0xc,0x26,0x8c,0x43,0xaf,0xac,0x57,0xcb,0xcc,0xc4,0x14,0x46,0x96,0x99,0xd7,0xaa,0x55,0xeb,0xfe,0x4d,0x59,0xb2,0x31,0x94,0x97,0xa3,0xa2,0xc8,0x6e,0xad,0x55,0x3f,0xa0,0x92,0x65,0xe6,0x7c,0x43,0x41,0x4c,0x4d,0x33,0x33,0x4,0x8d,0x25,0x19,0x2d,0x83,0x1d,0x96,0x1,0x3a,0x23,0xc,0x76,0xe7,0x10,0xc2,0xc4,0x69,0xe4,0xc4,0x44,0x33,0x60,0x3b,0xc,0x60,0x96,0xc4,0x2,0xb0,0x2c,0xed,0xa5,0x73,0xb4,0xb,0xc0,0xc5,0x18,0x1a,0x83,0x74,0xf3,0xcc,0x5a,0x78,0xb6,0x86,0xd0,0x31,0x83,0x37,0xd7,0xb2,0xd8,0x71,0x8,0x8b,0xd8,0x79,0xc0,0x51,0x28,0x92,0xe5,0xff,0xa,0xd3,0x8e,0xae,0x51,0xac,0xf,0xa,0x9b,0xe,0x1,0x3d,0x63,0xd2,0xd,0x3c,0x61,0x91,0x8b,0x74,0x59,0xcf,0x1,0x6,0xdc,0x32,0x90,0x4d,0x54,0xc6,0x9e,0xb5,0xc4,0x64,0xd4,0xd1,0xd6,0xce,0x81,0x24,0xd6,0x1a,0x64,0x5e,0x7,0x94,0xe3,0xf9,0xc,0x66,0x8a,0x3c,0xd7,0x68,0x62,0x31,0xf2,0x12,0xf8,0x53,0x70,0xd6,0x2c,0x25,0xbc,0xc4,0x3c,0xcc,0xb3,0xcc,0xf9,0x90,0x71,0x88,0x17,0xca,0xfc,0x3b,0x60,0xea,0x9,0x98,0x77,0xf8,0x9a,0x23,0x8f,0xc5,0xbc,0xc0,0x0,0x17,0x4c,0x3e,0x1,0x54,0x15,0x95,0xcb,0x47,0x67,0xce,0x27,0xe0,0xc8,0x53,0x57,0xfc,0x5c,0xbe,0xbe,0x76,0xcc,0xbc,0x32,0xbf,0x95,0xc0,0xed,0x1,0xf5,0xf0,0x0,0xc,0x3c,0x58,0xbf,0xd4,0x0,0xab,0x5a,0xb5,0x6a,0xbd,0x8,0xaa,0x7a,0x0,0xd6,0xaa,0x55,0xab,0xd6,0xdd,0x6,0x49,0x6e,0x3a,0xca,0xa5,0x5d,0xe6,0xc5,0x9e,0x34,0x26,0xf2,0x7,0x99,0x17,0xf4,0x89,0x24,0x96,0xc2,0xfe,0x33,0xc6,0xc2,0xb2,0xb7,0x9d,0xb1,0x46,0x1b,0xb,0x61,0x8,0x6a,0x13,0x5,0xa,0xc0,0x90,0xd0,0x8c,0x53,0x6b,0x49,0x61,0xd,0xba,0xa6,0x41,0xc,0x13,0xc6,0x61,0xcf,0xbe,0x81,0x96,0x7c,0xd8,0xc2,0xc8,0xa9,0xbd,0xe7,0x2a,0x63,0x8a,0x21,0x50,0x5a,0xac,0x73,0xea,0x59,0x28,0xcd,0x8a,0x61,0x56,0xe2,0x97,0xbe,0xfe,0x34,0xfe,0xdb,0xff,0xf9,0x57,0xf1,0xc9,0x4f,0x7f,0x6e,0x9d,0xf9,0xf5,0x1c,0x6b,0x1c,0x27,0xfc,0xe9,0xc7,0xfe,0x2,0xff,0xcd,0x2f,0xff,0x9f,0xd8,0x8f,0x91,0xa5,0xbb,0x7b,0x6d,0xf0,0x9c,0x6b,0xd4,0xe7,0xef,0xb0,0x82,0x7a,0x15,0x66,0x5,0x50,0xc7,0x7e,0xf,0x67,0xdd,0x7c,0xcd,0xc6,0x60,0x77,0x75,0x1b,0xbe,0xe9,0xd0,0xef,0x77,0xf0,0x1c,0x64,0x21,0xfe,0x72,0x61,0x1a,0xa9,0xd1,0xc2,0x7a,0x8,0x88,0x75,0x96,0xbd,0xa2,0x1c,0x35,0x83,0x89,0x2,0x3a,0xc2,0x38,0xa2,0xdb,0x9c,0xa1,0xe9,0x36,0xf0,0x9e,0x64,0xd3,0x61,0x1c,0xe0,0xdb,0x4e,0x9b,0xe1,0x30,0x8d,0xf8,0xd5,0xf7,0xfc,0x11,0xbe,0xf0,0xa5,0xaf,0x9e,0xbc,0xff,0xa6,0xf1,0x68,0x1a,0xaf,0xe0,0xdf,0x30,0x4e,0xf8,0x9d,0x3f,0xfc,0x30,0x76,0xfb,0x7e,0xf5,0xe7,0xa5,0xc9,0x4b,0x29,0xa1,0x1f,0x49,0x8a,0xdb,0xb4,0x1d,0x3,0x64,0x69,0xb5,0xbd,0xc9,0x39,0x23,0xc5,0x84,0x69,0x1a,0xb8,0xcf,0xa2,0xe6,0xd2,0x1a,0x2,0x3,0xcd,0x29,0x16,0x60,0x4a,0x8,0x1c,0x4a,0x23,0xc1,0x35,0x43,0xbf,0x47,0x18,0x7,0x24,0x6,0x5f,0x3,0xcb,0xfd,0x2,0xfb,0x0,0xae,0x1,0x89,0xd2,0x0,0x3b,0xeb,0xe0,0xdb,0xe,0x4d,0xd3,0xc2,0xfb,0x6,0xd6,0x7a,0x8c,0xc3,0x1e,0xfd,0xf6,0xa,0x61,0x1c,0x90,0x91,0x31,0xb0,0x5c,0x5b,0x9b,0xd2,0x44,0xf7,0xa7,0x9e,0x5b,0xec,0xc5,0x65,0xac,0x55,0xb9,0x5d,0xad,0x5a,0xb5,0x5e,0x28,0xf8,0x97,0x14,0x54,0x2,0xe6,0xf4,0x6e,0xfd,0x92,0x2,0x7a,0x69,0xe,0xce,0x28,0xa4,0x99,0x31,0x4e,0xec,0x4b,0x37,0xa7,0xf6,0x4a,0x38,0x8,0xc,0xe0,0x7c,0xab,0x3e,0x7c,0x2a,0x81,0x5,0xd0,0xb6,0x1b,0x1e,0x6c,0xb2,0x82,0x84,0xce,0x37,0xe4,0x6d,0xaa,0xc1,0x23,0x50,0x86,0xb0,0xb1,0xc4,0x12,0xb7,0x32,0x8f,0x42,0x7c,0x6e,0x1b,0x9d,0x5b,0x2d,0x8f,0xff,0x64,0xa1,0x61,0xf4,0x35,0xb2,0x59,0x22,0xec,0x46,0x39,0x47,0xe6,0x73,0xd3,0x58,0xe6,0x95,0xf5,0x98,0xd3,0x9c,0xdc,0x2b,0xf7,0x2e,0xf3,0xaf,0x58,0x71,0x18,0x66,0x89,0xe7,0x92,0xd1,0x5f,0x80,0x57,0x74,0x6c,0x3a,0xa7,0x80,0x82,0xf3,0x86,0xc8,0x1c,0xa0,0x22,0x2c,0x48,0x61,0xfd,0xe9,0xeb,0x16,0x7c,0x34,0x5e,0x5d,0x70,0x58,0xc9,0xcc,0xe8,0xcb,0xba,0xce,0x30,0x5,0xe3,0xb1,0x64,0xfa,0xc9,0xfc,0x26,0xaf,0x95,0xe7,0xa6,0x60,0xd4,0x37,0xc5,0x44,0xcb,0x2b,0x50,0xdb,0x81,0x2b,0xde,0x61,0xca,0x70,0xf1,0x67,0x61,0x35,0x9,0x53,0xc8,0x97,0x31,0xb3,0x3a,0xcb,0xb9,0xa4,0x90,0x8a,0xaf,0x29,0x7c,0xf,0x79,0x76,0xe5,0x15,0xdd,0xdd,0xaf,0xef,0x0,0xe4,0xbe,0x7,0x34,0x98,0x17,0x47,0xcc,0x27,0x80,0xd0,0x83,0xb3,0xe7,0x25,0x60,0x59,0xde,0x93,0xa9,0x32,0xe0,0x5a,0xb5,0x6a,0xbd,0x8,0xaa,0x32,0x0,0x6b,0xd5,0xaa,0x55,0xeb,0xae,0x4d,0xd4,0xec,0xef,0x62,0x0,0x5,0x64,0x8c,0xb5,0xcb,0x7f,0xf3,0xa2,0x37,0xb3,0xbc,0x57,0x20,0x43,0xf1,0x37,0x92,0x0,0xe,0x63,0xc,0x22,0x37,0x1d,0xe2,0xc3,0x46,0xa1,0x1c,0xd4,0x34,0x8,0x28,0x88,0x22,0x28,0xe4,0xb0,0x24,0xc4,0x63,0xec,0xf7,0xa,0x42,0x86,0x71,0x50,0x85,0xcd,0xb0,0xdf,0x61,0x77,0x75,0x7,0xd7,0x6e,0xbc,0x44,0xfd,0x9a,0xda,0x76,0xc3,0xcc,0x3b,0x96,0xba,0x22,0xa8,0xdc,0x48,0xc0,0x1c,0xeb,0x2c,0x9e,0xb9,0x7d,0x85,0xff,0xfe,0x7f,0xfb,0xd7,0xf8,0x81,0x37,0x7c,0x7,0x7e,0xe2,0x3f,0x7c,0x3b,0x1e,0x7c,0xc9,0x8d,0x55,0xef,0xba,0x35,0x40,0x6a,0xbb,0xdd,0xe1,0x2f,0x3e,0xf3,0x5,0xbc,0xe7,0xbd,0x1f,0xc2,0x67,0xbf,0xf2,0x94,0xfa,0x46,0x85,0x69,0xd2,0xb5,0x7f,0x4a,0x9,0xe3,0xb0,0x27,0x5f,0xbd,0x15,0x20,0x4c,0x92,0x13,0xc3,0x34,0x12,0xf8,0x9a,0xf3,0xcc,0xaa,0xe0,0x66,0x43,0xe4,0xa3,0x4,0x86,0x3a,0x7e,0x2d,0xb3,0x4a,0x24,0x69,0xd9,0x9a,0xd5,0xa5,0x3f,0xf9,0xfa,0xcd,0xec,0xc8,0x71,0xd8,0xb3,0x34,0x2d,0xc2,0x7a,0x8f,0x7e,0xb7,0xc5,0xb0,0xdf,0x92,0xc,0xb6,0x21,0x16,0x4b,0xc,0x93,0xb2,0x40,0x52,0xca,0x18,0xc6,0x80,0xff,0xe9,0x5f,0xfe,0x5b,0xfc,0xd2,0xdf,0x7f,0x17,0x9e,0xf8,0xf6,0x57,0xc1,0x9d,0x0,0xad,0xa6,0x29,0xe0,0xb3,0x5f,0xfc,0xa,0xfe,0xf5,0xbf,0xff,0x0,0xbe,0xfc,0xf4,0x25,0xac,0x1,0xde,0xf9,0xf6,0xb7,0xae,0xb2,0x2,0x6f,0xdd,0xbe,0xc4,0x7b,0x7e,0xff,0x83,0x78,0xff,0x47,0x3e,0x85,0x9c,0x13,0xfa,0xdd,0xd5,0xec,0xf,0xb5,0xca,0xe6,0x3,0x22,0xcb,0xcc,0x85,0x89,0x67,0x8c,0xc1,0xd5,0x9d,0x67,0xd1,0xb4,0xdd,0x89,0x96,0x87,0x92,0x7e,0xad,0xa5,0xb4,0xcb,0xb1,0xdf,0xf1,0x7d,0x8d,0x8,0xfc,0x99,0x8a,0x61,0xc2,0xa6,0x69,0x31,0xd,0xe4,0xb5,0x68,0x4e,0x0,0xb,0x30,0x86,0x93,0xad,0x3d,0xe2,0x34,0xb2,0x9c,0x8f,0xd8,0x88,0x2,0xee,0x66,0x66,0x99,0x3a,0xe7,0x55,0x2a,0x2c,0x8c,0x9d,0x59,0xc2,0xe7,0x80,0x3c,0x69,0x70,0x89,0xb1,0x7e,0x21,0xb5,0xaf,0x55,0xab,0xd6,0xf3,0x2c,0x63,0x34,0xb0,0xaa,0x4,0x85,0x8c,0x1,0x52,0xcc,0x33,0x50,0x5,0xa8,0x17,0x6d,0x19,0xce,0x34,0x7,0x7f,0xe4,0x82,0x89,0x9c,0x67,0x86,0x3a,0xfb,0xb3,0x49,0xe8,0x87,0xb5,0x76,0xe,0xe6,0x60,0xdf,0x52,0x4a,0x19,0x4f,0x73,0x80,0x5,0x87,0x74,0x84,0x34,0xc2,0x18,0x9a,0x3,0x7d,0xd3,0x72,0x0,0x93,0x85,0xb5,0x46,0x65,0xc7,0x7a,0x1c,0x1e,0x84,0x22,0xdb,0x14,0xd8,0x62,0x3e,0x92,0x84,0xf8,0x10,0x26,0x65,0xd6,0x67,0x65,0xce,0x19,0x1d,0x1f,0x61,0xc,0x2c,0xc,0xb2,0x3,0x7,0x20,0x35,0x40,0x4e,0x48,0xec,0x77,0x18,0x39,0xe0,0x2a,0x27,0xa3,0x60,0x21,0x59,0x57,0x10,0x88,0x37,0xcb,0x74,0x51,0xc8,0x80,0xb1,0xc,0xb4,0x52,0xe0,0x91,0xff,0xc9,0x9b,0x6f,0xb3,0xcf,0xdf,0x41,0x32,0x70,0x4e,0x0,0xec,0xc2,0xd3,0x8f,0xd8,0x88,0xb3,0x7,0xa1,0x1,0x16,0x7e,0xb9,0x8b,0x8d,0x1d,0x3,0xbd,0x5f,0xf9,0x5e,0x3e,0x4,0xe9,0xcc,0x73,0x5,0xa4,0xd6,0x59,0x7e,0xf2,0x79,0x59,0x80,0x96,0x26,0x9f,0x22,0xc1,0xe9,0x79,0x97,0x4c,0xbe,0xbc,0x70,0xca,0x3b,0x5c,0x5f,0x9d,0x92,0xeb,0x9e,0x62,0xef,0xdd,0x4d,0xc6,0xbb,0x90,0xef,0x9e,0xe4,0x13,0x9a,0x7b,0x80,0x83,0x27,0xae,0x22,0x1f,0x3f,0xa6,0xc5,0x3c,0x25,0x40,0x67,0x9d,0xba,0x6a,0xd5,0xaa,0x55,0x1,0xc0,0x5a,0xb5,0x6a,0xd5,0x7a,0x51,0xf7,0x50,0xf3,0x32,0x56,0x16,0xd4,0x59,0x76,0xdd,0xc1,0x52,0x24,0x68,0xc0,0x87,0x75,0x6e,0xd1,0x70,0xc1,0x14,0x29,0x87,0xc0,0x81,0xb7,0xf,0x8a,0x66,0x25,0x2b,0x3b,0x82,0xc0,0x2f,0x87,0x3f,0xfc,0xe0,0x47,0xf1,0xd4,0x33,0x77,0x96,0x69,0x7f,0xc6,0xe0,0xeb,0x4f,0xdd,0xd6,0x54,0x5c,0xf1,0xfe,0x8b,0x2c,0x67,0x4d,0x29,0xc2,0x37,0x1d,0xda,0xee,0xc,0x43,0xbf,0xc3,0x19,0x5f,0x8f,0xb1,0xe4,0xf9,0xe6,0x7d,0xc3,0x7e,0x4e,0x50,0x50,0x72,0xec,0xf7,0xe8,0xce,0xce,0x9,0x1c,0x64,0xc6,0xc5,0xfb,0xfe,0xec,0xd3,0xf8,0xe3,0x4f,0x7c,0xe,0xdf,0xf5,0x9a,0xc7,0xf0,0xba,0xd7,0x3c,0x8a,0x57,0x3f,0xfe,0x28,0xae,0x9d,0x9f,0x11,0xb3,0x8d,0x59,0x11,0xc3,0x30,0xe2,0xf2,0x6a,0x8b,0x2f,0x7f,0xf5,0x6b,0xf8,0xd4,0x67,0xbf,0x8c,0x4f,0x7f,0xf1,0xeb,0x78,0xe6,0xf6,0x95,0xb2,0x3e,0x72,0xce,0xd8,0x5d,0xdd,0xd1,0xeb,0x76,0x1c,0x4a,0x92,0x62,0xc4,0xa7,0x3e,0xfb,0x25,0xfc,0x1f,0xbf,0xf2,0x6b,0xba,0x9c,0xb7,0x8e,0xc0,0xb6,0xcf,0x7c,0xe1,0xab,0xd8,0x6d,0xaf,0xb8,0x29,0x24,0x6f,0x28,0x63,0x2c,0x86,0x61,0x87,0xfd,0xee,0xa,0xce,0x7b,0xdc,0x7e,0xfa,0x49,0x9c,0x5f,0xbf,0x89,0x18,0x27,0xb4,0x7e,0xa3,0x52,0x2f,0x9,0xb8,0x98,0x86,0x1e,0x97,0xd6,0xe0,0x57,0x7e,0xed,0x37,0x71,0xb6,0xe9,0xa,0x3,0x7c,0xe0,0x8b,0x5f,0x79,0x92,0x24,0x67,0xbe,0x61,0x7f,0x3d,0xf2,0xa4,0x8b,0x21,0x60,0xd8,0xef,0x60,0xad,0x85,0x6f,0x28,0xcd,0x77,0xd8,0xef,0xb0,0x39,0xbb,0x60,0xdc,0x31,0xc1,0xfb,0x4e,0xd7,0xff,0x4f,0xdd,0xde,0xe2,0x7f,0xf8,0x5f,0x7f,0x1d,0xdf,0xff,0xc6,0x27,0xf0,0xd6,0x37,0xbe,0x16,0x8f,0x3c,0xfc,0x32,0xb4,0x4d,0x83,0x10,0x2,0x2e,0xb7,0x7b,0xfc,0xe5,0xe7,0xbe,0x88,0x3f,0xf9,0xe4,0x17,0xf0,0xd5,0xa7,0x2f,0x31,0x4d,0xc4,0xea,0xfb,0x95,0x7f,0xf7,0x1,0xdc,0xbe,0xdc,0xe2,0x2d,0x6f,0x78,0x2d,0x6e,0xdc,0xb8,0x6,0x93,0x81,0x5b,0x97,0x57,0xf8,0xe4,0xa7,0x3f,0x87,0xf7,0xbc,0xf7,0x4f,0x71,0xeb,0x6a,0xa7,0xf7,0xdc,0x76,0x67,0x94,0x54,0x9c,0x22,0x7e,0xe3,0x3d,0xbf,0x87,0x7,0x5f,0x72,0x13,0xd6,0x39,0x58,0xd7,0x20,0xa7,0x88,0x5d,0x3f,0x11,0x6b,0x91,0x81,0xd0,0xa1,0xdf,0x71,0x53,0x6e,0x30,0xf4,0x7b,0xfc,0xfe,0xfb,0x3e,0x84,0xaf,0x7c,0xf5,0x6b,0xd4,0x60,0xb7,0x1b,0x18,0x18,0x8c,0xd3,0x84,0x5d,0x3f,0x21,0x84,0x80,0x3c,0xf6,0xcc,0xc,0x9d,0xf8,0xbe,0x1d,0xb1,0x9,0xf9,0x98,0xd,0x87,0xaa,0xfc,0xc6,0x6f,0xfd,0x1,0x6e,0x5c,0xbf,0x58,0x74,0x3e,0xb7,0xef,0x5c,0x21,0x85,0x88,0x9c,0x32,0x42,0xa4,0xb0,0x13,0x62,0xe,0x8e,0x2c,0x4b,0xe7,0x24,0x4e,0x6,0x4d,0x91,0x13,0x72,0xb6,0xea,0xf3,0x35,0x7b,0x6e,0x2d,0x81,0x3e,0xeb,0x1c,0xd2,0xb4,0xaf,0xe0,0x5f,0xad,0x5a,0xf7,0xa1,0xd4,0x27,0xf6,0xa0,0x28,0x50,0xc3,0xea,0x26,0x94,0x6c,0x38,0x39,0xef,0x11,0x63,0x54,0x2f,0xbd,0xc4,0x21,0x43,0x2,0x7a,0x59,0xe7,0x14,0x14,0x74,0xc2,0xfc,0x53,0x9,0x2d,0x8d,0xf9,0xd6,0x58,0x64,0xb1,0x59,0x90,0x50,0x28,0x63,0x81,0x94,0xe0,0x7c,0x3b,0x3,0x76,0xd3,0xa4,0xde,0x6a,0xf3,0x79,0x98,0x59,0x58,0x24,0xb2,0x8b,0x64,0x97,0xac,0x31,0xfc,0x22,0x28,0x43,0xc6,0x71,0xb5,0xb2,0x90,0x31,0x24,0x25,0xe4,0x14,0x19,0x5c,0x32,0xbc,0x21,0x27,0xac,0xe9,0x38,0xcf,0xeb,0xc6,0x20,0xc5,0x4,0x83,0xa0,0x52,0x5c,0x1,0xd1,0x8,0xc8,0x84,0x2,0xa8,0x64,0xcf,0x81,0x39,0x29,0xf9,0x30,0x88,0xa3,0xf4,0xe0,0x33,0x16,0xce,0x3a,0x24,0xde,0x0,0x91,0xd,0xc0,0xc4,0x9,0xcb,0x2,0x8,0x8a,0x6f,0xa0,0x61,0xc9,0xb3,0x4,0x90,0xe8,0x9a,0x20,0x67,0xa4,0x9c,0x57,0xde,0xd3,0x63,0xb0,0x4f,0xe6,0xe4,0xf2,0x7b,0xe6,0x20,0x5c,0xe4,0x8,0x10,0x3c,0xf4,0xe7,0x2b,0x20,0x36,0xb5,0xeb,0x2b,0x21,0x37,0xf1,0x31,0x5c,0x0,0x62,0xbc,0x76,0x29,0xe,0x77,0x8,0xa3,0x99,0x23,0xf0,0xae,0x94,0x3c,0xdf,0x1d,0x4b,0xbc,0x1b,0x10,0xb8,0x76,0xa6,0xbc,0xc2,0xae,0x5c,0x72,0x9,0xf3,0x3a,0x1e,0xb8,0x76,0x11,0xe6,0x4,0xe8,0x27,0xd9,0x24,0xc8,0x8b,0xe7,0xa6,0x40,0x77,0xad,0x5a,0xb5,0x6a,0x7d,0xab,0xf7,0xb6,0xa8,0x7b,0x15,0xb5,0x6a,0xd5,0xaa,0x75,0xd7,0x7a,0xfb,0xdf,0xf9,0x87,0x68,0xba,0xe,0x29,0x72,0x63,0x1,0x91,0x57,0xc9,0xbe,0xf6,0xcc,0x38,0xd0,0xa5,0xa7,0x98,0x87,0x17,0xc0,0x14,0xc,0xe0,0x7d,0x4b,0xa0,0x96,0x48,0x85,0x78,0x41,0x69,0x38,0x15,0x18,0xa0,0xf4,0x46,0x91,0x1e,0x5b,0x6b,0x99,0xa1,0xe1,0x0,0x96,0x4a,0x66,0xf6,0x23,0xa,0x81,0x40,0xa0,0x61,0xd8,0x23,0xc5,0x88,0xfd,0xf6,0x12,0xe3,0xd0,0x63,0xd8,0x6f,0x29,0xfd,0xd7,0x53,0x42,0x6b,0x77,0x76,0x4e,0xbe,0x80,0xed,0x6,0x19,0x19,0xde,0xb7,0x4a,0xb2,0x12,0xd6,0x84,0xa4,0x15,0x3,0x50,0xf9,0xa9,0x0,0x36,0x89,0x83,0x22,0x72,0x18,0xa9,0x71,0x41,0xc6,0x38,0x8e,0x18,0xc7,0x91,0x52,0x10,0xf9,0x98,0x9a,0xe0,0xc8,0xd2,0xd2,0x71,0xe8,0x91,0x73,0x46,0xb7,0x39,0x57,0x69,0x69,0xd3,0x76,0x18,0xfb,0x3d,0x25,0xcc,0xa,0x3b,0x83,0x9b,0xd2,0xcd,0xd9,0x5,0x8c,0x25,0x86,0x9e,0xb0,0x3c,0x52,0x8a,0xd8,0xde,0xa6,0x64,0xdd,0xfd,0xf6,0x12,0xd6,0x79,0xec,0xb7,0x97,0xd8,0x9c,0x5f,0xa0,0x61,0xe9,0x29,0x49,0x9d,0x1d,0x8c,0x1,0x7c,0xdb,0xa9,0x24,0xd8,0x5a,0x87,0xc4,0x92,0xe1,0x39,0xf5,0x31,0x6b,0x3,0x46,0x5e,0x83,0x14,0x28,0x32,0xec,0x77,0xf4,0x67,0xd8,0xc3,0x0,0xe8,0xce,0x2e,0xb0,0x39,0xbb,0x80,0x75,0xe,0x9b,0xf3,0xb,0x18,0x18,0xf6,0x2f,0xec,0xb4,0xd9,0x6b,0xda,0xe,0xbe,0x69,0x61,0x90,0xe1,0xbd,0x7,0x32,0x49,0xb8,0xc1,0x5e,0x78,0xd2,0x70,0x36,0x6d,0x87,0x7e,0x77,0xa5,0x6c,0x48,0xe7,0x3c,0xbc,0xa5,0x56,0x65,0x9c,0x48,0xb2,0x4c,0x20,0x5a,0x40,0xce,0x49,0xfd,0xfc,0x44,0x72,0x6c,0xad,0x43,0x77,0x76,0xe,0xe7,0x89,0x4d,0x27,0xa6,0xfb,0x96,0xd,0xf4,0x8d,0x31,0x98,0xa6,0x11,0x71,0x1a,0x31,0xe,0x3d,0xa6,0x71,0xa0,0x67,0xce,0xe9,0xbe,0xe7,0xd7,0x6e,0xd0,0x75,0x1a,0xf1,0x9e,0x34,0x2a,0x6b,0x1b,0xfb,0x3d,0x76,0x57,0xb7,0x9,0x0,0x1d,0xf6,0x68,0x5b,0x2,0x4c,0xaf,0xdd,0x78,0x9,0xbc,0x27,0x9,0x1e,0x81,0x81,0x8e,0xc1,0x58,0xfa,0xac,0xc,0xfb,0x2d,0xcb,0xda,0x12,0x86,0x61,0x87,0x30,0x8e,0x18,0xfa,0x1d,0xf6,0xdb,0x4b,0x5c,0xde,0x7a,0x1a,0xd6,0x79,0x9c,0x5f,0xbb,0xe,0xe7,0x5b,0x34,0x6d,0x4b,0x69,0xd0,0xd6,0x2a,0x53,0x91,0x42,0x7,0x48,0xae,0x1c,0xc2,0x84,0x7e,0x77,0x85,0xaf,0x7c,0xfe,0xd3,0xe8,0xb7,0x5b,0x84,0xe1,0x4e,0x1d,0x74,0x6a,0xd5,0x7a,0x81,0xf5,0xf0,0xe3,0xaf,0xc5,0xeb,0xde,0xf2,0x76,0x9c,0x5f,0xdc,0xd0,0x94,0xef,0x18,0x3,0x4b,0x36,0x39,0x88,0xa9,0x48,0xe8,0x2d,0x41,0x8c,0xa6,0xe9,0x10,0x23,0x31,0xd3,0x25,0xc1,0xde,0x5a,0xb7,0x48,0xb0,0x7,0x40,0x60,0x21,0xcf,0x1b,0x96,0xe7,0xb4,0xac,0x61,0x1d,0x4e,0x37,0x66,0x94,0x9,0xce,0xac,0x38,0x91,0x85,0xe6,0x44,0x52,0x5f,0x19,0xf3,0x8c,0xb1,0xf3,0xe6,0x80,0x6,0x41,0x85,0xc5,0xf8,0x23,0xc0,0x56,0x98,0x26,0xf6,0x3,0x34,0xec,0x45,0x4a,0x2c,0xe2,0xcc,0xc,0xb6,0xc4,0xbe,0x7c,0xd2,0xe6,0x68,0xe8,0x48,0xc,0xc,0xc,0x3a,0x65,0xdf,0x9b,0x22,0x8c,0x48,0xa4,0xc6,0x0,0x34,0x30,0x29,0x27,0x9,0xf0,0xa,0xea,0x2b,0x8,0x4e,0x89,0x8f,0x2c,0x33,0x96,0xb9,0x46,0xe7,0x74,0x4e,0x1e,0x16,0xc0,0x52,0xd6,0x9,0xa6,0x4,0xe5,0xf8,0x79,0xcd,0x1e,0x85,0x33,0xd3,0x52,0x82,0x98,0x16,0xa0,0x60,0x9,0x2,0xca,0xeb,0x17,0xfa,0x5b,0xb3,0x6c,0xec,0xca,0x0,0xb3,0xa3,0x20,0x8b,0xbc,0x9e,0xac,0x7b,0xb2,0x63,0x5c,0xff,0x7e,0xc6,0xdd,0xe3,0x42,0xf2,0x37,0xdd,0x7c,0x1e,0x82,0x78,0xf7,0xfa,0x99,0x13,0x7f,0x5f,0x43,0x24,0x71,0x77,0x50,0x6f,0xf5,0xc2,0xee,0x42,0x18,0x4c,0x89,0x2,0xc8,0x42,0x18,0x71,0xe7,0xd6,0x33,0xf8,0xcb,0x3f,0xfb,0xa3,0xda,0x56,0xd7,0xaa,0x55,0xeb,0x5b,0xbe,0xaa,0xd9,0x4e,0xad,0x5a,0xb5,0x6a,0xdd,0xa3,0x16,0x7e,0x78,0x92,0xd2,0x57,0x9a,0x6d,0x17,0xb2,0x23,0x61,0x6,0x1e,0x6,0x86,0xc8,0x4f,0x6,0x66,0xee,0x21,0x43,0xd9,0x5e,0xb2,0xc8,0x97,0x8a,0x31,0xaa,0x17,0xa0,0x34,0x6e,0xc4,0x92,0xf3,0xa,0x62,0x4d,0xe3,0x80,0x9c,0xa2,0x9a,0xb2,0xd3,0xa5,0x51,0xc3,0x21,0xaf,0xc9,0x39,0x69,0xd3,0x14,0xc2,0xc4,0x7e,0x71,0x6c,0x9c,0x9e,0x8,0x60,0x92,0x9d,0xec,0x69,0x1c,0x54,0xd6,0x15,0xa6,0x11,0x43,0x4f,0x4c,0xac,0x30,0x8e,0x6a,0xb6,0x3e,0x4e,0x13,0xf6,0xfd,0x80,0x67,0x9f,0x7d,0x16,0xfd,0x38,0x92,0xf0,0xd9,0x5a,0x18,0xcc,0xac,0xc5,0xc4,0x2c,0x44,0x63,0x88,0x49,0xd7,0x6d,0xce,0x30,0x8d,0x43,0xf1,0x2c,0x89,0xad,0xe7,0x9a,0x16,0xd3,0x34,0x3,0x5d,0xce,0x79,0xf5,0xff,0x93,0x7b,0x91,0x86,0xe,0x85,0x9c,0x6b,0x1a,0x7b,0xc4,0x30,0xaa,0xec,0x2c,0x48,0x32,0x30,0xcb,0xb3,0xe4,0xbe,0x84,0x19,0x57,0xca,0xad,0x72,0x9a,0xff,0x24,0xe,0x5b,0x9,0xd3,0xa4,0xcf,0xcf,0x3a,0xa7,0xe6,0xf5,0x29,0x6,0x4a,0x1f,0xe6,0x50,0xd,0x3a,0x7,0xb4,0xa1,0x13,0xf6,0xcc,0xd8,0xef,0xd1,0xf7,0x3d,0xf6,0xfb,0x1e,0x21,0x25,0x44,0xf6,0x7f,0xdc,0x6f,0xaf,0x30,0xe,0x7b,0x95,0xe5,0xca,0x7d,0xa6,0x14,0xb1,0xdb,0xde,0xc1,0xd5,0x76,0x8b,0xed,0x76,0xab,0x72,0xe8,0x30,0xe,0x88,0x61,0xd4,0x6b,0x1f,0xfb,0x1d,0xa6,0xa1,0x67,0xe0,0x8e,0x18,0x7e,0x72,0x3f,0xd3,0xd0,0x13,0x20,0xcb,0x80,0xab,0x0,0x8d,0x89,0x1b,0xed,0x8c,0x8c,0xed,0xd5,0x2d,0x4c,0xd3,0x40,0xcc,0xd0,0x30,0x61,0xec,0xf7,0x1a,0x1a,0x33,0x8d,0x23,0x49,0xab,0xd9,0xb,0xb0,0xdd,0x9c,0x11,0x93,0x34,0x46,0xf4,0xbb,0x2d,0xac,0xb1,0x18,0xfb,0x9d,0x3e,0x7f,0x69,0xc8,0xe5,0x13,0xda,0xef,0xb6,0xca,0x2e,0xa,0xfc,0x5e,0x84,0x30,0x61,0xbf,0xbd,0xc2,0xd0,0xef,0xe1,0xdb,0xe,0x4f,0x7d,0xed,0x4b,0x88,0x21,0xa0,0xed,0x36,0xf4,0x59,0xf0,0xd,0x7c,0xd3,0xc1,0x59,0xf2,0xd8,0xb2,0xca,0x5e,0x4d,0xc,0x6c,0x53,0x13,0x9f,0xe2,0x50,0x7,0x9c,0x5a,0xb5,0xee,0xd3,0xbc,0x95,0x53,0xd6,0xf9,0x48,0x98,0x7b,0xd6,0x39,0x96,0xde,0xe7,0x5,0xf8,0x57,0x8e,0xdb,0xc2,0xbc,0x76,0xde,0x43,0x92,0xd3,0x73,0x4e,0xec,0x65,0xeb,0x14,0xf0,0x73,0xbe,0x61,0xef,0x4f,0x3a,0xae,0x6f,0x5a,0xfa,0x3d,0xf7,0x8d,0xfa,0xdc,0x8a,0x8f,0x5e,0xd3,0x75,0xb,0xaf,0x3f,0xf1,0xde,0x13,0x7f,0x58,0x5b,0x7c,0x4f,0x82,0x36,0x24,0x65,0xd8,0x3a,0xa7,0xd6,0x6,0x14,0x5c,0x45,0xc0,0x61,0xd3,0x76,0xb,0x56,0x1b,0x49,0x7b,0xa1,0x1,0x1f,0x96,0xfd,0x6d,0x65,0x7e,0x4e,0x6c,0x9b,0xa0,0xe0,0x1a,0x5f,0x37,0xf9,0xc0,0x9a,0x25,0x68,0xc7,0xf6,0xb,0xf2,0x1c,0x52,0x4e,0x7c,0x7c,0xba,0x2f,0x27,0x9e,0x84,0x96,0x41,0x4b,0xeb,0xf8,0xdc,0xb4,0x1e,0x50,0x8f,0x5d,0x59,0x2b,0x64,0xe8,0x79,0xd9,0x90,0x51,0x37,0xe,0x45,0x19,0x20,0x52,0xe1,0x72,0xee,0x9a,0xb1,0xbc,0x19,0xe8,0x13,0xa9,0xeb,0x32,0xfd,0x77,0xe6,0xd7,0x29,0xf8,0x57,0x78,0xf1,0x1d,0x51,0xda,0x44,0xb9,0xb0,0xf8,0xf9,0x35,0xbc,0x6c,0x66,0xff,0xc9,0xcb,0xf2,0x9,0xf0,0xef,0x10,0x67,0x7b,0xae,0xac,0xbe,0xd3,0x10,0xe1,0x9a,0x20,0xf8,0xc4,0xdf,0x73,0x9,0x68,0x96,0x49,0xc4,0x58,0x37,0xf,0xcc,0x58,0x3e,0x8b,0xbb,0x61,0x8d,0xf9,0x1e,0xf7,0x90,0x51,0x24,0x61,0xd7,0xaa,0x55,0xab,0xd6,0xb7,0x76,0x55,0x9,0x70,0xad,0x5a,0xb5,0x6a,0xdd,0xa3,0x2c,0x3,0x76,0xb2,0xc8,0xa4,0xd4,0x5f,0x4e,0xdd,0x9b,0xb3,0xfb,0x8e,0x58,0x81,0x22,0x83,0x35,0xdc,0x4c,0x8,0x90,0x98,0xb,0xc6,0x84,0x34,0x24,0xd2,0x80,0x21,0x3,0xbe,0x9d,0x25,0x50,0xe2,0x61,0x14,0x43,0xc0,0x94,0xd8,0x47,0x4d,0x98,0x80,0x19,0x98,0xc6,0x1e,0xc6,0x0,0xe3,0x30,0x68,0xb3,0x41,0x6c,0x83,0x84,0xfd,0xee,0xa,0xd7,0x6f,0x3e,0x88,0x89,0x25,0x9d,0xc4,0x8a,0x48,0x30,0x26,0x32,0x43,0xb0,0x41,0x8,0x23,0x9f,0xa7,0x61,0xc6,0x87,0x87,0x73,0x96,0xe5,0xa5,0x4,0x56,0x9a,0x94,0x19,0x8,0xcb,0x98,0xc6,0x9e,0xae,0xa7,0xf,0xea,0xbd,0xd4,0x9d,0x9d,0x23,0x5,0x92,0xd1,0x5a,0x67,0x55,0x66,0x15,0xc3,0x84,0xc0,0x8d,0x67,0x98,0x46,0xe4,0x9c,0xd0,0x76,0x1b,0x4c,0xc3,0x80,0x14,0x3,0xba,0xcd,0x5,0x52,0xc,0xf0,0x4d,0xa3,0xcd,0x88,0x48,0x84,0x9d,0x6f,0x34,0x31,0x31,0x4c,0x23,0x79,0x6,0xb2,0x37,0xd4,0x34,0x8e,0x98,0xc6,0x1,0xd6,0x39,0x9c,0x5f,0xbb,0x81,0x69,0x1c,0xd0,0xb4,0x1b,0x18,0x4b,0x7e,0x7d,0x30,0x80,0x73,0x1e,0x43,0xbf,0xa3,0x6,0x2b,0x1a,0x34,0x6d,0xab,0x40,0x66,0x8c,0x1,0xce,0x78,0x8c,0xc3,0xc8,0x40,0x1a,0x1,0x5d,0x74,0x9e,0x89,0xc1,0xb8,0x9,0x6d,0x47,0x81,0x20,0x29,0x46,0x24,0x9,0x4e,0x9,0xd4,0xfc,0x25,0x7a,0xc3,0xa0,0xe9,0x90,0x29,0x2a,0xc3,0xc6,0xc1,0xab,0xbf,0xe0,0xb0,0xdf,0xa3,0xed,0x3a,0xe,0xdd,0x8,0xda,0x64,0x4f,0xc,0x7a,0xaa,0xf4,0x8c,0x3f,0xb,0xc2,0x84,0xc9,0x99,0xfc,0xfa,0xa6,0x89,0x58,0x97,0x72,0x1d,0x94,0x22,0xcd,0x1,0x1d,0xa0,0x40,0xd,0xeb,0x1c,0x9c,0xa7,0xf0,0xd,0x91,0x40,0xd3,0xe3,0x74,0xb0,0xce,0x63,0x1c,0x7a,0x7a,0xee,0x2c,0xf1,0x15,0xa3,0x7c,0x7a,0x4f,0x8,0xe4,0xd,0xd3,0x48,0x81,0x1d,0xfd,0x4e,0x25,0xe2,0xe2,0x51,0x9,0x90,0x7c,0x5c,0x12,0x41,0x43,0x18,0xe1,0x5d,0x83,0xcc,0x9e,0x95,0xc2,0x40,0x75,0x9e,0xee,0x27,0x4c,0x3,0x1e,0x78,0xe8,0xe5,0x48,0x29,0x12,0x1b,0xf1,0xec,0x9c,0x3f,0x77,0x9,0x31,0x4e,0x70,0xae,0x29,0x3e,0x8b,0x96,0x25,0xd6,0x19,0x29,0x4e,0xb0,0xcd,0x39,0x52,0xa8,0x20,0x60,0xad,0x5a,0xf7,0x63,0xde,0x3a,0xc,0x3,0x92,0xe0,0x1f,0x83,0x22,0xd0,0x83,0xe7,0x2c,0xf2,0x9f,0xc5,0x2c,0x93,0xe5,0xcd,0x1d,0x98,0xe3,0x63,0xf9,0xa6,0xd1,0x8d,0x2b,0xf2,0xf1,0x6b,0xe6,0x54,0x60,0x4f,0xc0,0x59,0xb3,0xe9,0xf0,0xc0,0xc5,0x19,0xae,0x5f,0x3b,0x47,0xe3,0xd,0x9c,0xf5,0xd8,0xee,0xf7,0x78,0xf6,0xf6,0x25,0xb6,0x43,0x42,0xe0,0xf3,0x8,0x3b,0x78,0x1c,0xf6,0x70,0x7c,0x9c,0x52,0x8e,0x9b,0x73,0x52,0x6,0x60,0xd3,0x75,0x34,0xf7,0xf2,0xd7,0x53,0x8c,0x68,0x9a,0x56,0xc7,0xd3,0x18,0x83,0xb2,0xd0,0x45,0x9e,0x2c,0xff,0xf6,0xbe,0xa1,0xf1,0x9e,0x1,0x38,0x5f,0x30,0xd0,0x75,0xe3,0xc9,0x3a,0x58,0x43,0x73,0x57,0x8e,0x59,0x37,0xfc,0x88,0x9,0xe9,0x20,0x82,0x57,0x61,0x2,0xb2,0xff,0x7,0x16,0xcc,0x3b,0xb6,0xc9,0x2b,0xfd,0x14,0x69,0x83,0x83,0x6d,0x42,0x94,0xe9,0x37,0x7b,0xec,0x25,0x4d,0x1d,0x4e,0x8b,0x20,0x90,0x52,0x26,0x5c,0x82,0x63,0x99,0xfd,0x17,0x51,0x60,0x58,0xfa,0xf,0x5,0xfe,0x4e,0x8,0x72,0x8b,0xef,0x97,0xcf,0xb9,0xf4,0x84,0x34,0xb,0x82,0xa0,0x59,0x55,0xce,0x1e,0x42,0x73,0x66,0x5,0x2b,0x7b,0xee,0x4c,0xbf,0xf2,0xef,0x7,0x52,0x5d,0xb3,0x42,0xcd,0xcb,0xc7,0x78,0xe6,0xe2,0x2,0x4c,0xf1,0xda,0x92,0xb9,0x68,0xe,0x1e,0xc3,0x21,0xa3,0x31,0x9f,0xba,0xd2,0x65,0xc0,0x47,0x3e,0x9,0x4c,0x56,0x61,0x5d,0xad,0x5a,0xb5,0x2a,0x0,0x58,0xab,0x56,0xad,0x5a,0x7f,0x83,0x2a,0x2f,0x16,0x7f,0xa5,0xac,0xd4,0x5a,0x4b,0x7e,0x42,0x96,0x40,0x19,0xc0,0x20,0xa6,0x59,0xea,0x2b,0x26,0xe8,0x86,0x59,0x9,0xb9,0x48,0x8,0x46,0xce,0x8,0x31,0xc0,0x59,0xa7,0xcd,0x8a,0x2d,0xc,0xc4,0x53,0x8a,0x68,0x1a,0x5a,0x18,0x27,0x36,0x25,0x4f,0x2,0x64,0x39,0x7,0x44,0xc3,0x6c,0xbf,0x88,0x38,0x4d,0x2c,0xbf,0xdd,0x23,0xb3,0x24,0xd5,0x8e,0x16,0xde,0xb7,0xda,0xc,0x91,0x27,0x91,0x55,0x96,0x7,0x4c,0x46,0x32,0x51,0x59,0x1b,0x30,0x6,0xd3,0xd8,0xa3,0xdb,0x9c,0x33,0x8b,0x84,0xe4,0xbc,0x22,0x1b,0x95,0x66,0x24,0x86,0x49,0x3d,0xa4,0xda,0x6e,0x43,0xbe,0x50,0x85,0xa7,0x13,0x81,0x78,0xc4,0x8c,0xb0,0xad,0xd1,0xf4,0x59,0x63,0x2d,0x2c,0x58,0x32,0x5,0xc0,0x1a,0x87,0xbe,0xdf,0xaa,0xd4,0x56,0x18,0x15,0x81,0xef,0x45,0x80,0xbf,0x71,0xd8,0x63,0xbf,0xbd,0xc4,0xb5,0x1b,0xf,0xe8,0x39,0xa4,0x79,0x8b,0x61,0x82,0x6f,0x5a,0x1c,0xea,0x7b,0xe8,0xf9,0x5,0x98,0x49,0xfc,0xa6,0xc4,0x27,0x70,0x60,0xc0,0xca,0x21,0x22,0xe8,0x7d,0x4d,0x3,0x25,0xf5,0xaa,0x3c,0x39,0x25,0x18,0x2f,0xbe,0x50,0x5e,0x19,0x96,0x25,0x38,0x9b,0x5d,0x46,0xce,0x56,0x9b,0xc5,0x18,0x83,0x86,0x6d,0xe4,0x9c,0xb0,0xbb,0xba,0xa4,0x44,0x4d,0x69,0x1c,0x2d,0x31,0x4e,0x22,0x7f,0xdf,0x37,0x1d,0x42,0x18,0xe8,0xf9,0x37,0x19,0xe3,0xd0,0x33,0xf8,0x4a,0x8c,0xc4,0x7e,0xbf,0x55,0xe9,0xb4,0xb0,0x6a,0x7c,0xd3,0x50,0xd0,0x89,0x71,0x9a,0xfa,0xeb,0x7c,0x83,0xfd,0xd5,0x1d,0x38,0x96,0xa5,0xed,0xb7,0x97,0x38,0xbf,0x7e,0x3,0x80,0x2d,0x92,0x9f,0x29,0x90,0x25,0xc6,0xc8,0x4c,0x9f,0x48,0xd,0xbe,0x1a,0xf9,0x3b,0xa4,0x44,0x52,0xb6,0x61,0xbf,0x45,0xbb,0x39,0x87,0xe1,0xf7,0x8c,0x40,0xc3,0x49,0x1,0x4c,0x20,0xab,0x8f,0x60,0x98,0x6,0xfe,0xcc,0x65,0x92,0x39,0xfb,0x6,0x29,0x12,0x23,0x71,0x1a,0x6,0x6c,0xce,0x2f,0x18,0x30,0x9c,0x83,0x5,0x28,0x10,0x27,0xea,0xef,0x96,0x80,0x9b,0xb5,0x6a,0xd5,0x7a,0xe1,0x25,0xfe,0xb0,0xb3,0xf7,0x5b,0xc1,0x4a,0x97,0xb1,0xb3,0x8,0xa5,0x30,0xc6,0xc0,0x7a,0xc7,0x8c,0xec,0x46,0x90,0x2b,0x66,0xea,0x31,0x20,0x68,0xac,0x7a,0xf2,0x9,0x23,0x8f,0xac,0x9,0x1c,0x0,0x83,0x9b,0x17,0x1b,0xbc,0xe5,0xf5,0xdf,0x8e,0x37,0xbd,0xee,0x35,0x78,0xf9,0x23,0x2f,0xc3,0xb5,0x8b,0x73,0x78,0x66,0xf6,0xd1,0x58,0x9c,0x31,0x4e,0x13,0x6e,0xdf,0xb9,0xc4,0x17,0xbe,0xf4,0x55,0x7c,0xe4,0x13,0x9f,0xc5,0x9f,0x7f,0xe6,0xcb,0x98,0x62,0xe2,0x24,0x7b,0x96,0xfe,0x96,0xa0,0x14,0x6f,0x64,0x7c,0xcf,0x77,0xbe,0xa,0xef,0xfe,0xe1,0xef,0x27,0x4f,0x51,0x70,0xf0,0x53,0x4e,0xf8,0xb5,0x7f,0xfb,0x7b,0xf8,0xf8,0x67,0xbf,0xa2,0x0,0xa4,0xb0,0xcc,0x73,0x4a,0x30,0x6c,0x61,0x21,0x12,0x5f,0xeb,0x1c,0x52,0xa0,0x8d,0x18,0x19,0x8b,0x5,0xec,0xcc,0x29,0xd1,0x26,0x84,0xf3,0x3a,0x17,0xa,0xc3,0x8f,0x40,0x43,0x86,0x81,0xac,0x81,0x5,0x87,0x78,0x99,0x25,0xcb,0x90,0xc6,0xc4,0xa4,0xc7,0x9d,0x7d,0x18,0x33,0xac,0x71,0x8,0x39,0xa9,0xe5,0x47,0x9,0x18,0x95,0xe1,0x20,0xe5,0xbc,0x46,0x60,0xa2,0x55,0x1f,0xda,0x12,0x8,0x2c,0xd3,0x81,0xe5,0x7d,0x95,0x50,0xb0,0x43,0x8f,0xe1,0xd9,0x43,0x78,0x76,0xcb,0x13,0x46,0x22,0xa,0x5f,0xbf,0x99,0x4,0x68,0x34,0xbc,0x23,0xe3,0xb9,0x5,0x70,0xe4,0x5,0x8,0x76,0xfa,0x6b,0x58,0xfd,0x9a,0x39,0x86,0x14,0x15,0x89,0xc4,0x7a,0x5a,0xc8,0xdd,0x2e,0x68,0x81,0xcb,0xad,0xd3,0xf7,0x56,0x5,0xc6,0x85,0xbf,0x5f,0x9,0xf8,0x3d,0x97,0x74,0x5f,0x53,0x43,0x40,0x6a,0xd5,0xaa,0x55,0x1,0xc0,0x5a,0xb5,0x6a,0xd5,0xfa,0x9b,0x8,0xfe,0xd1,0x72,0x90,0x52,0x66,0x8b,0x5d,0xfa,0x54,0x2e,0xb8,0xed,0xc,0x14,0xe6,0xac,0xbb,0xfd,0x2a,0xb5,0x62,0xb9,0x26,0x31,0xff,0x8a,0x94,0x5b,0x5,0xac,0x92,0xb2,0x6,0x9d,0x21,0x8f,0x25,0x61,0x4,0xa4,0x94,0x60,0x12,0x9b,0x97,0xb3,0xf7,0x9b,0x1c,0x2f,0xc5,0x88,0x94,0x13,0x27,0x3a,0x66,0xf8,0xb6,0x65,0x4f,0xa4,0x42,0x7a,0x54,0xa4,0x19,0xa,0x70,0xd6,0xb0,0x4c,0x73,0xd8,0x6f,0xe1,0xbc,0xc7,0x34,0xf4,0x30,0xd6,0x62,0xbf,0xbd,0x54,0x2f,0x3b,0x91,0x6a,0x85,0x30,0x2a,0xd3,0xcd,0x30,0x30,0x77,0xed,0xe6,0x83,0x4,0xee,0xb1,0xbc,0xd9,0x18,0x5b,0x98,0xc3,0x13,0x83,0x4f,0x1a,0x8d,0x10,0xc8,0x3,0xcf,0x35,0x6d,0x21,0x3,0xcd,0xea,0x6b,0x97,0x78,0x57,0x3e,0x70,0x70,0x49,0x8e,0xb3,0xb4,0x59,0xd2,0x19,0xfb,0xfd,0x16,0xbe,0xe9,0x70,0x71,0xfd,0x5c,0x3,0x50,0x7c,0xdb,0x29,0x58,0x68,0x0,0xf4,0xbb,0x2b,0x2,0xaf,0xa,0x80,0xd0,0x79,0xaf,0xc,0x40,0x1,0x58,0x53,0xc,0xe8,0xf7,0x57,0x1a,0xa2,0xd2,0x34,0xad,0x4a,0xe6,0x62,0x8c,0x98,0xa6,0x1,0xd6,0xf9,0xd9,0x73,0x91,0xef,0x59,0x80,0x54,0x69,0xe,0xc7,0x69,0x84,0xe7,0xaf,0x87,0x40,0x72,0xe8,0x7e,0xbf,0xd5,0x80,0x12,0x61,0x18,0xce,0x80,0x30,0x85,0x6d,0x48,0xa3,0x19,0xd8,0x8f,0x90,0xce,0x4d,0x26,0xfd,0xd3,0x14,0xb1,0xbb,0xda,0xc1,0xb7,0x1d,0xf6,0xdb,0x4b,0x5c,0xdc,0x78,0x9,0xa6,0xb1,0x47,0x6e,0xba,0xd9,0xf,0x8b,0xbd,0xac,0xa6,0x71,0x40,0xbf,0xdf,0x12,0x83,0x10,0x59,0x59,0x79,0xc3,0x7e,0x87,0xeb,0x37,0x1f,0x44,0x18,0x47,0x4d,0xe9,0xc,0xc2,0xb8,0x4b,0x74,0x4d,0x22,0xa9,0x1b,0xf6,0xbb,0xe2,0x33,0x4d,0x9f,0x97,0x69,0xe8,0x91,0x99,0xe1,0x13,0x26,0x2,0x59,0xe5,0x7d,0x13,0x7f,0x2e,0x4a,0x90,0xf6,0xc4,0x36,0xec,0x9,0x40,0x1d,0x87,0x3d,0xa5,0x35,0x8f,0xe3,0x9c,0x84,0x9d,0x1d,0x3,0x5,0x59,0x81,0x9,0x6b,0x2d,0x22,0x32,0xf7,0x68,0x6,0xb9,0xb2,0xff,0x6a,0xd5,0xba,0x3f,0x33,0x56,0x21,0xe9,0x2c,0x59,0xe7,0xb0,0x34,0x26,0xc3,0xcc,0x1b,0x4a,0xd6,0xd2,0x5c,0x94,0x13,0xcb,0x76,0xd,0x54,0x26,0x2c,0xa9,0xf6,0x22,0xdd,0x37,0xc6,0xc0,0xb7,0x34,0x6,0x89,0x4,0xf7,0xac,0x71,0xf8,0xb1,0x77,0xbc,0x19,0xef,0xf8,0xfe,0xef,0xc1,0xcd,0x1b,0xd7,0x8f,0x98,0x87,0xa,0x30,0x5a,0xc0,0x7b,0x87,0xf3,0xb3,0xd,0x1e,0x7d,0xe4,0x21,0x7c,0xff,0x5b,0xdf,0x84,0x27,0xbf,0xf1,0x14,0xde,0xfb,0xc7,0x1f,0xc5,0x6f,0xff,0xd1,0x47,0x91,0x8c,0x85,0x95,0xb9,0x14,0x89,0x25,0xb8,0x64,0xc9,0xf0,0xe0,0xcd,0xb,0x7c,0xd7,0x6b,0x5f,0x73,0x74,0x8f,0xd7,0xdf,0xfb,0xc7,0xa,0xf8,0x39,0xef,0x91,0x27,0x7a,0x4d,0x48,0x9,0x49,0x13,0xdc,0x85,0xc5,0x46,0x9b,0x70,0x8d,0xf5,0x85,0x3d,0x5e,0xc9,0xe8,0x73,0x9a,0x1a,0x2c,0x32,0x64,0xb,0x9e,0x83,0x99,0x39,0xe8,0x9c,0x7,0x6c,0x86,0x83,0x55,0x30,0x55,0xa4,0xcb,0x61,0x8a,0x2a,0x13,0x16,0x6,0x75,0xca,0x4,0x14,0x4a,0xd2,0xba,0x31,0x56,0xc7,0x6f,0xde,0x43,0x9c,0xd9,0x77,0x9,0xa,0xd6,0x92,0x3d,0xc2,0x7c,0x9f,0x65,0x38,0x88,0x29,0x52,0x9b,0x73,0x4a,0x5,0x2e,0x96,0x75,0x2d,0x82,0xe2,0x6b,0xe6,0x8,0xc,0x33,0x47,0xf0,0x5c,0x9,0x26,0x96,0x72,0xdf,0x53,0xb8,0xda,0x9,0x18,0xec,0xae,0xeb,0xa7,0xf9,0x42,0xf,0xe5,0xc8,0xf2,0x59,0x3d,0x64,0xe4,0xe5,0x3,0x83,0x41,0x73,0x17,0xf4,0xee,0x1e,0x40,0xe0,0xa9,0x1b,0x28,0x43,0x3d,0x38,0x38,0x66,0xe1,0xef,0x5c,0x84,0x8b,0x98,0x45,0xd0,0x48,0x71,0x48,0x83,0x93,0xdf,0xaf,0x55,0xab,0x56,0xad,0x6f,0xb5,0xaa,0x1e,0x80,0xb5,0x6a,0xd5,0xaa,0x75,0xcf,0x46,0x2a,0x61,0xb1,0xa,0x65,0xf0,0x44,0xcc,0xbb,0x35,0xe1,0x57,0xc3,0x26,0x64,0xc7,0x9d,0xd9,0xc,0x6e,0x96,0x4f,0xa9,0xbc,0xa7,0x48,0x59,0x14,0x3f,0xa4,0x18,0x83,0x2,0x7a,0xb2,0xf3,0x2d,0xc0,0x50,0xe0,0x24,0x59,0x62,0x5c,0x5,0x95,0x70,0x8a,0xa1,0x7b,0xf9,0x6f,0xf2,0x68,0x4b,0xe4,0xe3,0x87,0xac,0xac,0x8,0x0,0x88,0x71,0xe2,0xbf,0xe7,0xa2,0x9,0x64,0x8f,0x41,0x61,0x26,0x32,0x48,0x99,0x33,0x49,0x42,0x51,0x78,0xf,0x79,0x4f,0xe9,0xbc,0xbb,0xcb,0xdb,0x24,0xc3,0xb5,0xe,0x63,0xbf,0x57,0xd6,0x81,0x73,0x5e,0x25,0xa6,0x4d,0xd3,0x1,0x2c,0x13,0x25,0x36,0x83,0xa1,0xa0,0xf,0x6e,0xb8,0xc2,0x44,0xa9,0xb1,0xe2,0x9d,0x93,0x32,0x35,0x34,0x21,0x4c,0x2a,0xd5,0x22,0x70,0x8a,0xfc,0x75,0xc6,0xb1,0x9f,0x7d,0x6,0x19,0x50,0x93,0x66,0x47,0x19,0x81,0x1c,0x6c,0xd1,0xb4,0x9d,0x9a,0x73,0xe7,0x4c,0x9e,0x7f,0xe3,0xd0,0xeb,0xfb,0x30,0xb1,0x24,0x99,0x82,0x59,0x1a,0xf5,0x11,0x1c,0xc7,0x1e,0xdb,0xcb,0x5b,0x64,0xec,0xce,0x0,0x97,0x48,0x77,0x5,0x3c,0x14,0x50,0x54,0xae,0x4f,0xe5,0x5c,0xfc,0x7e,0x49,0x63,0x1d,0x26,0xba,0x8f,0xa1,0xdf,0x13,0xab,0x2f,0x4c,0xf4,0xb5,0x10,0x0,0x4e,0xc3,0xa4,0xfb,0x99,0x4d,0xee,0x63,0x98,0xc8,0x8f,0x91,0xd9,0x9c,0xc2,0x7e,0xa4,0xfb,0x1d,0xd4,0x37,0x4b,0x1,0x5d,0x6b,0x14,0x88,0x94,0xcf,0x92,0x3c,0x57,0xef,0x1b,0x84,0x71,0xc0,0x7e,0x77,0x35,0xb3,0x62,0xd8,0x9b,0x4a,0x83,0x64,0xa6,0x11,0xe3,0xb0,0x47,0x4c,0x11,0xbe,0x25,0x10,0xd6,0x33,0x73,0x93,0xcc,0xff,0xa1,0x32,0x60,0xb9,0xd6,0x69,0xe8,0x89,0xed,0x29,0xe6,0xfe,0x61,0x24,0x46,0x90,0xdc,0xf,0x27,0x77,0x52,0xb3,0x6d,0x34,0x44,0x84,0x1a,0xdf,0x38,0x7,0xe4,0x88,0x2c,0xde,0x58,0xf6,0x2e,0x4,0x52,0x1c,0xeb,0x80,0x53,0xab,0xd6,0x7d,0x28,0xd9,0x88,0x82,0x2,0x4c,0x33,0xb8,0x63,0xc,0xcd,0x49,0xae,0x69,0x94,0x5d,0x36,0xb3,0xbb,0x69,0x83,0x42,0x36,0x3a,0x32,0x7b,0x5,0x4a,0x8,0x91,0xf8,0xb3,0xfa,0x86,0xc6,0xcd,0x47,0x5e,0x72,0xd,0xff,0xf9,0x7f,0xfa,0xb3,0xf8,0xc9,0x1f,0x7b,0x27,0x1e,0xb8,0x79,0x63,0x15,0xfc,0x3b,0x55,0xce,0x59,0x3c,0xfa,0xf2,0x87,0xf1,0x73,0x3f,0xf5,0x23,0xf8,0xaf,0xfe,0xf9,0x2f,0xe2,0x15,0x2f,0xbd,0xce,0x7e,0x7b,0x11,0x6d,0xdb,0xc1,0xb7,0x14,0x64,0x45,0xe7,0x5a,0x67,0x7,0x3b,0x4e,0xb6,0xd7,0x50,0x24,0x4b,0xd7,0xe7,0xbc,0x57,0x3b,0x3,0xd9,0x94,0x2,0x7b,0xfc,0xc5,0x18,0x75,0xde,0x90,0xfb,0x96,0xfb,0xb2,0xce,0x6b,0xf0,0x96,0x11,0x16,0x1e,0x6f,0x6c,0xa9,0xa7,0x6f,0xa6,0xf9,0x5b,0x99,0x83,0xec,0x17,0x2b,0xde,0xb4,0x12,0xf8,0x91,0x72,0x52,0x30,0x10,0x98,0xa5,0xc6,0x32,0x27,0x9a,0xc5,0x1a,0x3,0x7c,0xed,0x99,0x97,0x19,0x79,0xf1,0xde,0x9,0xf8,0x97,0x1,0x5,0x23,0x85,0xb1,0xbf,0x78,0xe6,0x12,0xb0,0x22,0x7f,0xcf,0x4b,0xb,0x3c,0x53,0xfe,0x5c,0x1,0xf4,0x99,0xe7,0x60,0x87,0x67,0xee,0x89,0xb0,0x1,0x47,0x42,0xe0,0x43,0xbf,0xbd,0x5,0x10,0x79,0xf8,0x77,0x1c,0xab,0x81,0x17,0x40,0x5d,0x3e,0x6d,0xd,0xf8,0x7c,0xd6,0x76,0x7,0xa7,0x57,0x6f,0x45,0xfe,0xdf,0x9c,0x2c,0x3c,0x3,0x82,0xc7,0x17,0x56,0x5a,0x3e,0xa7,0x3a,0xf0,0xd4,0xaa,0x55,0xab,0x2,0x80,0xb5,0x6a,0xd5,0xaa,0xf5,0xa2,0x6e,0xa2,0xac,0x5b,0x2a,0x48,0x16,0x6,0x37,0x56,0x7d,0x93,0x66,0xe3,0xf2,0x62,0x17,0xbd,0x30,0x32,0xcf,0xa0,0x44,0x41,0x49,0x4,0x26,0x7f,0x25,0x5a,0x38,0xc6,0x69,0x9a,0xc1,0x40,0xcc,0xd2,0x1e,0x61,0xf5,0x95,0xd,0x6,0x35,0x1f,0x50,0xb0,0xac,0xfc,0x19,0xe7,0x3d,0xc0,0x8d,0x8e,0x6b,0x5a,0x18,0x0,0xfb,0xed,0x95,0x7a,0xbd,0x9,0x98,0x26,0x6c,0x36,0x69,0x20,0xe2,0x34,0xb1,0xdc,0x96,0xae,0x5b,0x0,0x48,0x69,0x98,0xc6,0xb1,0xc7,0x38,0xf4,0xb0,0xd6,0xb1,0x17,0x1c,0x87,0x75,0x64,0xa0,0xdf,0x6f,0x11,0xa6,0x11,0xfb,0xab,0x4b,0x4d,0xd6,0x25,0x80,0x92,0xbd,0x8b,0xa4,0xe1,0xf1,0x5e,0xc3,0x40,0x32,0x8,0x74,0x73,0xde,0x73,0xa,0x23,0x54,0x52,0x9b,0x53,0xa2,0x64,0x49,0xe,0xea,0x10,0x86,0x8a,0x24,0xfb,0xfa,0xa6,0x55,0x49,0x2c,0x1,0x6d,0x4,0x9a,0x5a,0x63,0xb9,0x71,0x25,0x39,0xf2,0x34,0xe,0xc,0xac,0x7a,0x2,0xdc,0x18,0xb8,0x15,0x16,0x86,0x63,0xc0,0x4d,0x42,0x4e,0xc6,0xa1,0x47,0xc,0x41,0x93,0x7d,0x73,0xa6,0xe0,0xd,0xeb,0x3c,0x82,0xa4,0xf2,0x6,0x4a,0xe4,0x1d,0x7,0x4a,0x31,0x8e,0x2c,0x7f,0x2d,0xa5,0x75,0x61,0x1c,0x89,0x55,0xb8,0xa3,0x10,0x90,0x18,0x2,0xa6,0xb1,0xc7,0x34,0xf6,0xfc,0xbd,0xa8,0x6c,0xc9,0x10,0x26,0xe,0xdb,0x98,0x19,0xd,0xc6,0x18,0x4d,0x40,0x16,0x66,0x1f,0x79,0xfa,0x91,0x6c,0x79,0x1a,0x7,0xa,0x8,0x19,0x7,0x2,0x45,0xfb,0x3d,0x3,0x7e,0x93,0x4a,0xaa,0x85,0x55,0xb8,0xbd,0xbc,0x4d,0xbe,0x8a,0x81,0xc2,0x47,0x28,0x48,0x64,0x66,0x5c,0x88,0xcf,0x24,0x1,0xac,0x91,0xc1,0xc0,0x1e,0xfb,0xed,0x25,0x7f,0x8e,0xd,0xb3,0x32,0x13,0x83,0x93,0x41,0xa5,0x6e,0x31,0x46,0x95,0xf,0x3b,0xd7,0xa8,0xdf,0x9f,0x4,0xba,0x10,0x33,0x33,0x14,0x7f,0x26,0x4d,0xe,0x4d,0x21,0x28,0xc8,0x2c,0x4c,0x97,0x14,0x2,0xb3,0x68,0x9a,0x3a,0xe8,0xd4,0xaa,0x75,0x1f,0x2a,0x6b,0x30,0x1,0xa,0x26,0x5d,0x54,0x7f,0x3c,0x0,0x9c,0xb0,0x6b,0xf5,0x4f,0x69,0xf3,0x60,0x38,0x81,0x9e,0x80,0x2b,0x1a,0x5f,0xe7,0x4,0x7b,0xb,0xdf,0x74,0x78,0xe5,0x43,0xf,0xe0,0x9f,0xfd,0xe3,0x9f,0xc1,0x6b,0xbe,0xed,0x95,0x2f,0x10,0xac,0x34,0x78,0xfc,0x15,0x8f,0xe0,0xf5,0x4f,0xbc,0x4a,0x37,0x92,0xac,0xf3,0xb,0x30,0xb3,0xfc,0x77,0x59,0x31,0x26,0x1d,0xcb,0x8c,0x35,0x9a,0x94,0xee,0x7d,0x3,0xb1,0x7d,0x88,0x31,0x92,0x35,0x87,0xa1,0xf9,0x8f,0xfe,0xd0,0x3d,0xcb,0x26,0x1b,0xb,0x63,0x57,0x51,0x25,0x19,0x97,0xc9,0x66,0x82,0x8e,0xe1,0xfd,0x2c,0x93,0x16,0xfb,0x4,0x81,0x87,0x8,0x3c,0x24,0x26,0xbe,0xe3,0xb9,0x4e,0x98,0xec,0xc4,0xd8,0x63,0x98,0x69,0x1,0xf2,0xcd,0x9e,0x87,0x9a,0x18,0x7c,0x0,0xee,0xe5,0x12,0xd0,0x2d,0x94,0x1,0xa,0xc,0xe6,0x19,0xe6,0x13,0x66,0x61,0x2e,0x19,0x80,0x5,0xe0,0x28,0xeb,0x92,0x39,0x5d,0x58,0x48,0x78,0x87,0x52,0xdc,0xbc,0xb2,0xfc,0x39,0x34,0xdb,0xc3,0x8a,0xd4,0x36,0x1f,0x7f,0xed,0x48,0x22,0x9b,0x4f,0x63,0x89,0x6b,0xc1,0x1d,0x27,0x5f,0x7a,0x7c,0x9e,0x8c,0x7c,0x4f,0x98,0x12,0x85,0xcc,0xb9,0xfc,0x1a,0xee,0x2,0x74,0x9a,0xa3,0x9f,0x91,0x4d,0xc8,0xb4,0xe2,0xbb,0x58,0xab,0x56,0xad,0x5a,0x15,0x0,0xac,0x55,0xab,0x56,0xad,0x17,0x1f,0x8,0x58,0x4a,0x53,0x8a,0xbf,0x2b,0x43,0xcd,0xcc,0x1,0x1e,0x46,0x77,0xd5,0x45,0x32,0xe5,0x16,0x4d,0x8c,0x82,0x5a,0xc6,0x20,0xf1,0xcf,0x59,0xe7,0xd4,0xbf,0x8,0x86,0x3c,0x4,0x89,0x5d,0x98,0xd8,0x7b,0xce,0x15,0x8b,0x74,0x6a,0x10,0xc8,0xeb,0x6f,0x6,0x18,0xa5,0x71,0x23,0x5f,0xbe,0x88,0xed,0x9d,0x67,0xd1,0x74,0x1b,0xf2,0xd5,0x63,0x56,0x98,0xf8,0xd3,0xe5,0x9c,0x35,0xc1,0xd0,0x39,0x4a,0x37,0x8c,0x9c,0x3a,0x4c,0x60,0x19,0xdd,0x23,0xc9,0x43,0x3,0xac,0xa1,0xf3,0xb,0xf3,0xd0,0x35,0x2d,0x1,0x7a,0x1c,0x2a,0xb1,0xdb,0xde,0x41,0x4a,0x91,0x83,0x48,0x8c,0xb2,0xc0,0x62,0xc,0xa,0x76,0x4a,0x22,0xac,0xb0,0x12,0x45,0xf6,0x9c,0xa,0xbf,0xc2,0x18,0x88,0x99,0x16,0x43,0x80,0x1,0x98,0x9,0x17,0x30,0xe,0x3d,0x6,0x96,0xa2,0xee,0xaf,0x6e,0xc3,0xfb,0x16,0xe3,0xb0,0x3,0xc4,0x4,0xbe,0xed,0xf8,0x7c,0x4,0x3e,0x8a,0x14,0x39,0x86,0xa0,0xc9,0xbb,0xda,0x28,0x81,0xde,0xab,0xc8,0xef,0x97,0x30,0x33,0x1a,0x6e,0xec,0x62,0x8c,0xd8,0x5d,0xdd,0x81,0xf3,0x9e,0x7c,0x13,0x63,0x54,0x63,0x7a,0xc3,0x61,0x18,0xf2,0x5e,0xa,0x3,0x51,0xcf,0x13,0x23,0x27,0x2a,0x8f,0xca,0xa6,0x1c,0xf6,0x5b,0xf4,0xbb,0x2d,0x62,0x88,0xca,0x2c,0x94,0x94,0xe5,0xc8,0x20,0x6c,0xc,0x13,0xa6,0x61,0xd0,0x64,0xe1,0xc0,0x80,0xac,0x3c,0xbf,0x91,0xe5,0xbc,0x56,0x59,0x77,0xe4,0x3d,0x98,0xd8,0xf0,0x7e,0x1a,0x29,0x60,0x24,0x46,0x2,0xe1,0x86,0xfd,0x56,0x53,0x7c,0xe9,0x7d,0xa7,0x67,0x9b,0xf8,0x33,0x25,0x40,0xa8,0x7c,0x16,0x84,0x11,0x94,0xc4,0x17,0x90,0xdf,0x3b,0x91,0x8a,0xc7,0x69,0x5a,0xb8,0x3a,0xa5,0x94,0x14,0xb8,0x15,0x70,0x4f,0x19,0xab,0xd3,0x88,0xfd,0xf6,0x72,0xd1,0xdc,0xca,0xf3,0x57,0x4f,0x32,0xb3,0x64,0x53,0x58,0x63,0x17,0x6c,0x96,0x5a,0xb5,0x6a,0xdd,0x87,0x5,0xbe,0x65,0x50,0xa9,0xe0,0x33,0x9,0x98,0x27,0xe3,0xd9,0x9c,0x0,0x9c,0x16,0x56,0x15,0xca,0xf6,0x83,0xa1,0xd,0x99,0x38,0x5b,0x35,0x10,0x9b,0xce,0xa0,0x75,0xc0,0x3f,0xfa,0x8f,0x7e,0xc,0x8f,0x3c,0x9,0x39,0xb1,0x5,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xf4,0xd2,0xfb,0x76,0xcd,0x91,0x59,0x75,0xb2,0x81,0x24,0xcc,0xb1,0x18,0x23,0x6f,0xf2,0x1c,0x3,0x73,0x0,0xd0,0xb4,0x1b,0x65,0xdd,0x5b,0xeb,0xd4,0xba,0x20,0x67,0xa,0x2c,0x69,0x9a,0x96,0x18,0xd7,0xc2,0x4,0xe4,0xe0,0xd,0x63,0x2d,0x85,0x50,0x61,0xf6,0xf2,0x15,0x30,0xf,0x30,0xca,0x80,0x24,0x69,0x6d,0x9a,0x93,0xd6,0x85,0x49,0x2d,0x73,0x3d,0x27,0x6,0xdb,0x22,0x7c,0x83,0x18,0x81,0x8e,0x2d,0x42,0x24,0x41,0xd9,0x13,0x98,0x69,0x1d,0x31,0x9f,0x85,0x59,0x88,0xa5,0x4c,0x5b,0x36,0x4b,0x64,0x6e,0x47,0xe9,0xd3,0x68,0xad,0x6e,0xd0,0x29,0x48,0xa8,0x21,0x2d,0x86,0x81,0x3c,0x2,0x33,0xc5,0xf6,0x3,0x47,0x20,0xe2,0x2c,0x72,0x2d,0x1,0xbf,0xbc,0x90,0xe2,0x9a,0x55,0xff,0xc8,0xf9,0x7b,0x38,0x46,0xe7,0x72,0x3e,0xc6,0x7,0x17,0x88,0xf4,0x31,0xc0,0xb7,0x4a,0xe2,0x5b,0xb5,0xed,0x5b,0xc2,0x73,0xf9,0x28,0x6e,0x64,0xf9,0x7a,0xb3,0x60,0xed,0x95,0xff,0x7f,0x8,0xe,0xe6,0xc3,0x18,0x97,0xe2,0x9,0xe5,0x93,0xd7,0xa1,0xd7,0x92,0xe7,0xf5,0xdd,0xaa,0xdf,0x60,0xad,0x5a,0xb5,0x6a,0x7d,0x8b,0x55,0xf5,0x0,0xac,0x55,0xab,0x56,0xad,0xbb,0x81,0x7f,0x90,0x26,0x6a,0xfe,0x77,0xe6,0x9d,0x7a,0x5d,0xb4,0xe7,0xd9,0x0,0x5a,0xfc,0x7e,0x64,0x51,0x2f,0xc,0xb,0x11,0x95,0x18,0x6b,0xb4,0x21,0x30,0xec,0x1b,0x24,0xa9,0x8b,0x30,0xe4,0xdf,0x43,0x18,0x62,0x52,0x70,0x64,0x1a,0x7,0x95,0xeb,0x88,0xbf,0x90,0x31,0x86,0x65,0x40,0xb3,0x5c,0x37,0xb1,0x54,0x35,0x5,0x4a,0x8b,0x1d,0xf6,0x5b,0x6e,0xe2,0xc0,0x8d,0x4e,0xcb,0x0,0x65,0x42,0xe4,0x6b,0xde,0xef,0x2e,0xe1,0x7d,0x3,0xeb,0x1b,0x6d,0x34,0xb2,0xa1,0x63,0xc1,0x10,0xf3,0x6e,0x9a,0x6,0x58,0x6b,0xe1,0x1a,0x4f,0x21,0x1f,0xcc,0x4,0xdb,0x6f,0x2f,0x39,0x59,0x31,0xe2,0xe2,0xfa,0x3,0xd8,0x6f,0xef,0x20,0x4c,0x94,0xc8,0x2b,0xd2,0x5a,0xd,0x3f,0x61,0x1f,0x38,0x62,0xfd,0x11,0xb8,0x44,0x4d,0x5a,0xa6,0x64,0x58,0xdf,0x0,0x30,0x8,0x13,0x35,0x80,0x12,0x52,0x31,0x8d,0x3d,0x52,0x8c,0xd8,0x9c,0x5f,0x60,0xbf,0xbd,0x3,0xdf,0xb4,0xd8,0xef,0xb6,0x38,0xbf,0x76,0x3,0x29,0x26,0x65,0x36,0x1a,0x63,0x60,0xd4,0xf,0xb0,0x25,0xd9,0x55,0x8e,0x70,0xc,0xaa,0x8d,0x43,0xcf,0xfe,0x50,0x81,0x4d,0xe6,0xe5,0x1c,0xd,0x76,0x57,0x7b,0x7e,0xaf,0x48,0x7e,0xdb,0x76,0x1b,0xf5,0xeb,0xf3,0x4d,0x83,0x61,0xbf,0x83,0xb5,0x8e,0x82,0x38,0x86,0x1e,0xb6,0xed,0xc8,0xcb,0xd0,0x53,0x33,0x17,0x98,0xdd,0x26,0x49,0xc5,0x30,0xc0,0x38,0xf4,0xa,0xee,0xe6,0x21,0x61,0x18,0x7b,0x0,0x6,0x43,0xbf,0xc3,0xc5,0xf5,0x9b,0x68,0xbb,0xcd,0x2c,0xf5,0x42,0xa6,0x26,0x54,0xd2,0x27,0xb,0xc6,0x5d,0x19,0x4,0x23,0xe0,0xac,0x75,0x8e,0x9b,0x58,0xc3,0xac,0xc5,0x96,0x83,0x43,0x88,0x7d,0x37,0x70,0x8a,0xf2,0xe5,0xad,0x67,0x34,0xdc,0x43,0x4c,0xe0,0x63,0x98,0x60,0x9d,0xa3,0xfb,0x47,0xd2,0xd4,0xe4,0x7e,0xbf,0x55,0x9,0xb2,0x0,0x9f,0xc3,0x7e,0x87,0xee,0xec,0x82,0x80,0x3d,0x66,0xc9,0x90,0x94,0x37,0x23,0x86,0x88,0x8c,0xa0,0x6c,0x22,0xc3,0x48,0xb9,0x6f,0x1a,0xb4,0x9b,0x73,0x8c,0x43,0x8f,0xcd,0xf9,0xb5,0x39,0x65,0x93,0x9b,0x66,0xe9,0xa,0x25,0x41,0x33,0x9b,0x34,0xb7,0x52,0xa4,0x6d,0xab,0x83,0x4e,0xad,0x5a,0xf7,0xa1,0x4a,0x66,0xb1,0xfc,0x8a,0x59,0x66,0x57,0x83,0xfd,0x52,0xc5,0xeb,0xb4,0xdd,0x6c,0x90,0x39,0xed,0xdd,0xf1,0x5c,0x60,0xd9,0x9a,0x22,0x63,0xe,0xaf,0xb2,0xd6,0x31,0x43,0x3a,0xe1,0xef,0xbc,0xe3,0xcd,0x78,0xd5,0x63,0x8f,0xae,0x9e,0x3b,0x84,0x80,0x27,0x9f,0x7a,0x16,0x5f,0xf8,0xca,0x93,0xf8,0xf2,0xd7,0xbe,0x81,0x29,0x44,0x74,0x5d,0x8b,0x7,0x6f,0x5e,0xe0,0xf1,0x47,0x1f,0xc2,0xa3,0x8f,0x3c,0x84,0x8b,0xf3,0xcd,0x2a,0xf0,0xd3,0x34,0xed,0xec,0xd,0xdb,0xb6,0xc,0x98,0x19,0x4e,0xa9,0x3f,0x2e,0xc7,0x92,0x5f,0xda,0x8,0x4a,0x73,0x2a,0xbc,0xb3,0x68,0xd9,0x1a,0xc3,0x35,0x1e,0x61,0x9a,0x16,0xcf,0xc1,0x30,0xe0,0x8,0xa0,0x90,0x36,0x67,0xf5,0xe7,0x93,0x8d,0x11,0x6b,0xb3,0xce,0x59,0xce,0x35,0x3a,0xa7,0x1b,0xe3,0x74,0x85,0xe0,0x9a,0x6,0xd3,0x34,0xc2,0x7b,0xcf,0xcc,0xcb,0xa8,0x81,0x56,0x74,0xdd,0x14,0x6c,0x12,0x53,0x64,0xf6,0xbc,0xa4,0x1b,0x5b,0xf5,0xf3,0xa5,0xcd,0x95,0xac,0x60,0x92,0x58,0x7b,0xc8,0x7b,0x51,0x7a,0xb3,0x16,0x79,0xbd,0xa,0xe0,0xa2,0x0,0x78,0x13,0x7,0x91,0xc9,0xb8,0x7c,0x64,0x63,0x52,0xac,0x69,0x16,0xb2,0x56,0x73,0xb4,0x0,0x3a,0x6,0x1,0x5,0xcc,0x2b,0x6d,0xfc,0xca,0xff,0xe6,0x93,0x8b,0xa9,0xd5,0xef,0x99,0x13,0xdf,0x3b,0x8e,0xe,0x31,0x8b,0x70,0xe,0x73,0xf0,0xef,0x63,0x80,0xee,0xf0,0xa0,0x87,0x92,0xde,0x7c,0xf0,0x1a,0x73,0x12,0xe8,0x3b,0x5,0x50,0x2e,0x60,0xd5,0x22,0xb5,0xb9,0x56,0xad,0x5a,0xb5,0x2a,0x0,0x58,0xab,0x56,0xad,0x5a,0x2f,0xd2,0x4a,0x29,0x2c,0xfc,0xe5,0x74,0xc5,0x77,0xd0,0x58,0xe9,0x2,0x3b,0xb3,0x79,0xb9,0xb2,0x2b,0xb2,0x4a,0x61,0x2d,0x2f,0xe,0x55,0x7e,0x93,0x66,0x1f,0x22,0x6b,0x2d,0x52,0x48,0x2a,0xc3,0x52,0x0,0x91,0x93,0x84,0x5,0xe4,0x12,0x29,0x65,0x96,0x4d,0xf8,0x98,0x14,0x38,0x1a,0xfa,0x1d,0x62,0x20,0x90,0xad,0xc1,0x66,0x1,0xbc,0x48,0xda,0xa3,0x32,0xb,0x58,0xae,0x22,0x20,0x9d,0x80,0x47,0x92,0x42,0x9c,0x99,0x69,0x40,0xfe,0x77,0x49,0x43,0x38,0xac,0xb5,0x98,0x26,0x92,0x7a,0x5a,0x4b,0x41,0x17,0x6,0x6,0x97,0xb7,0x9e,0xa6,0xf4,0x59,0x65,0x45,0x0,0x93,0xe9,0x35,0xec,0xa4,0x6c,0x66,0xa4,0x28,0x59,0x38,0xc2,0xfb,0x16,0xfb,0xed,0x25,0xda,0xee,0x8c,0xd8,0x27,0x1a,0xe,0x92,0xb8,0xf7,0x30,0xd8,0x5d,0xde,0x26,0xe9,0x72,0x1e,0xe1,0x9c,0xc3,0x38,0xf4,0xf0,0x6d,0xab,0xd,0xad,0x63,0xb0,0xd5,0x68,0x30,0x45,0x86,0x6b,0xda,0xc5,0xf5,0xc4,0x69,0x52,0x36,0xa5,0x24,0x20,0x8f,0x1c,0x78,0x32,0xb2,0x4f,0x9e,0x30,0x2e,0x62,0xc,0x38,0x6f,0x3b,0x95,0x14,0x8b,0x6f,0x94,0x0,0x57,0x14,0xe0,0xe1,0x35,0xe9,0x17,0xb0,0xb3,0x17,0x20,0x3,0x6e,0x61,0x9a,0xd0,0xef,0xb6,0x1a,0x9c,0x62,0xc,0x31,0x8,0xf7,0xdb,0x2b,0x74,0x9b,0x33,0xb4,0x67,0xe7,0x2a,0xf7,0x8d,0x31,0x22,0x8d,0x24,0xf1,0x95,0x67,0x34,0xf4,0x3b,0x4d,0x60,0x6e,0xba,0xd,0xc6,0x61,0x8f,0x8d,0xbd,0xa0,0x67,0xef,0x3c,0x42,0x9e,0xc8,0x1b,0x8b,0xdf,0x2b,0xeb,0x1c,0xfa,0xdd,0x55,0xe1,0xab,0x48,0xef,0x73,0xe6,0x6,0x52,0xc5,0x4b,0x29,0x21,0xf2,0xd7,0xc5,0x63,0x90,0xfa,0x44,0x62,0x8f,0x58,0xf5,0xfd,0x22,0xe0,0x3a,0xe5,0x4,0x9b,0x85,0x81,0x5a,0x78,0x57,0x1a,0xb,0x63,0x33,0x72,0x8c,0x48,0x39,0x63,0xe2,0xa4,0x68,0x61,0x78,0xe6,0x22,0x74,0x46,0x8c,0xfc,0x85,0x11,0x4b,0xde,0x89,0x4b,0x66,0x60,0xce,0x11,0xc6,0xd6,0x65,0x49,0xad,0x5a,0xf7,0x5,0x0,0x94,0x39,0x4b,0x19,0x4a,0x40,0x4a,0x9c,0xbe,0xcd,0xe3,0x91,0x73,0xd,0x8c,0x9d,0xbd,0x4c,0xbd,0x6f,0x54,0x3a,0x2a,0x73,0x90,0x1,0xcd,0x13,0xc2,0xd2,0x9d,0xc6,0x1,0xf,0xdc,0xb8,0x8e,0x1f,0x7c,0xdb,0x9b,0x56,0xcf,0xfb,0x8d,0xa7,0x6f,0xe1,0xd7,0xff,0xfd,0xfb,0xf1,0xc9,0x2f,0x3c,0x89,0xc0,0xe7,0x1,0xc0,0xac,0x61,0x9a,0x17,0x1f,0xbc,0x71,0x81,0xef,0x79,0xed,0x63,0xf8,0xa1,0xb7,0x7d,0x37,0x1e,0x7a,0xe9,0x83,0x33,0x98,0xe7,0x24,0xc5,0xd7,0xeb,0x6b,0x8c,0x35,0x34,0x7f,0xba,0x66,0x1d,0xe4,0xb4,0x9e,0x8f,0x6b,0x61,0xcc,0xbc,0x49,0x36,0xe,0xbd,0x8e,0xf7,0x61,0xa4,0xc0,0x25,0x18,0xc0,0xb0,0x5,0x81,0x24,0x1c,0xcb,0xd8,0x27,0xe3,0x2e,0x5,0x52,0x45,0xbd,0x7f,0x6b,0x1d,0xb2,0xa7,0xd,0xad,0x69,0x1c,0xf4,0x1a,0x9d,0x6f,0x78,0xc,0xa5,0x4d,0x20,0xef,0xe7,0x24,0xf5,0x71,0x1a,0xe1,0x9b,0x46,0xff,0x3d,0xcf,0xeb,0xf3,0x38,0x6a,0x99,0x85,0xcf,0x1e,0x22,0xa,0xde,0xc9,0x98,0x28,0x7e,0xb7,0xb3,0x3f,0x61,0x5e,0xcc,0x31,0xa2,0x28,0x90,0x39,0x5d,0xee,0x41,0x58,0x7f,0xb2,0x49,0x28,0xcc,0xc0,0x79,0x3d,0x72,0x80,0x62,0x29,0xf6,0x55,0xb2,0xfe,0xe,0x10,0x38,0xf9,0x9a,0x39,0xc0,0xd6,0x56,0xc2,0x7b,0x17,0xdf,0x3f,0x65,0x9f,0x72,0x2,0x50,0x5b,0x2,0x7c,0xcb,0x98,0x92,0xf9,0x90,0xf9,0x0,0x14,0x3c,0x5,0xd7,0x1d,0xdc,0xcf,0xe2,0x22,0xee,0x15,0x1d,0x5c,0xdc,0x48,0xf9,0x3c,0xb0,0x5c,0xff,0xe5,0x62,0xff,0x2a,0xf1,0xda,0xae,0x56,0xad,0x5a,0xb5,0x2a,0x0,0x58,0xab,0x56,0xad,0x5a,0x2f,0xf2,0x12,0xbf,0xa4,0xd9,0x30,0x3a,0x2f,0x8d,0xaa,0xa5,0xbb,0xe2,0xef,0xe5,0x22,0xb9,0xcf,0xf0,0xe2,0x5f,0x2,0x43,0x92,0x30,0x0,0xc0,0x3e,0x74,0x29,0xaa,0x7f,0x9d,0xae,0x26,0x19,0x44,0xb4,0x86,0x3c,0x85,0x66,0x16,0x21,0x14,0xe0,0xb2,0xec,0x9f,0x47,0x81,0xd,0x86,0x19,0x6a,0x1b,0x8c,0x7d,0xaf,0xac,0xb8,0x30,0x8d,0xf0,0xbe,0xc1,0xf9,0xb5,0x1b,0xc,0xf4,0x84,0x45,0xc3,0x23,0x8d,0x81,0x30,0x2b,0x72,0x1e,0x55,0x26,0x6a,0xad,0x43,0xd4,0x94,0xc1,0xc8,0xff,0x8e,0x98,0xa6,0x11,0xe7,0xd7,0x6e,0xb0,0xb7,0x20,0x49,0x55,0x37,0x67,0x17,0xb8,0xbc,0xfd,0xc,0x2e,0xae,0x3f,0x40,0x1e,0x80,0x13,0x49,0x70,0x9b,0x6e,0x3,0xef,0x3c,0xfa,0xfd,0x15,0x9c,0xf3,0x6c,0xbc,0x9e,0x95,0xf5,0x97,0x53,0x56,0x26,0xe0,0xd9,0xc5,0x75,0x62,0x8,0x3a,0xb7,0x90,0xa6,0x89,0xf4,0x98,0xae,0x3b,0xab,0x44,0xd6,0xdf,0x68,0x94,0x49,0x99,0xc,0xb3,0xe3,0xc,0xe0,0x7d,0x4b,0xa0,0xa8,0xe5,0x50,0x14,0x64,0x6a,0x6a,0xb,0x60,0x2e,0xb1,0xc4,0x38,0x23,0x69,0x53,0x27,0xd,0x58,0x98,0x46,0x4c,0xe3,0x80,0x6e,0x73,0x46,0x4d,0xb1,0xb5,0xcc,0x4e,0x9c,0x99,0x86,0x65,0x8a,0x70,0xc,0x14,0xa,0x42,0x1e,0x89,0xf4,0xb3,0xf4,0x73,0x4,0x96,0xb6,0x5d,0x47,0xc1,0x2b,0x9c,0x28,0xdc,0xb4,0x1d,0xa6,0x69,0x20,0x60,0x35,0x67,0x65,0x9e,0x88,0x3f,0x54,0xc,0x93,0x6,0xc1,0x38,0xe7,0x11,0x12,0xf9,0xfb,0xe5,0x44,0x72,0xde,0x5d,0x22,0xa6,0x4b,0xb7,0x39,0x83,0xf3,0xf4,0xc,0xd4,0x77,0x11,0x86,0x59,0x93,0x23,0x3,0xba,0xf4,0xcc,0xa6,0x91,0xd8,0x78,0xf2,0x7c,0x25,0x74,0x23,0xa4,0xc8,0x5e,0x80,0x1,0xc3,0x7e,0xc7,0x60,0x2c,0x5,0x87,0x64,0x66,0xf1,0x35,0x6d,0x7,0x93,0xa1,0xe6,0xfa,0xe2,0x23,0x66,0x9d,0x67,0xc9,0x9b,0xc5,0x6e,0xb8,0x52,0x46,0xab,0xc8,0xef,0x9c,0xf3,0x2a,0x4b,0xb3,0x96,0x40,0x65,0xef,0x1b,0x2,0x13,0x55,0x92,0x36,0xff,0x31,0x58,0x82,0xc3,0xb5,0x6a,0xd5,0x7a,0x81,0x0,0x60,0x91,0x2e,0x5f,0x2,0x66,0x59,0x19,0xe4,0x19,0xd9,0xca,0x66,0x53,0xa6,0xcd,0x9f,0x44,0x96,0xa,0x73,0xc0,0x55,0x56,0xc9,0x29,0x8d,0x1d,0x34,0x6,0xbc,0xe1,0x3b,0x5e,0x89,0x7,0x6e,0x5e,0x5f,0x1,0xff,0x9e,0xc5,0xff,0xf8,0x2f,0xdf,0x83,0x27,0x6f,0x5d,0xc1,0x39,0x7,0xef,0x3d,0x2,0xfb,0x80,0xfa,0xa6,0x51,0xe0,0xff,0xa9,0x5b,0x97,0x78,0xcf,0xfb,0x3f,0x86,0x3f,0xfa,0xc8,0xa7,0xf0,0x63,0x3f,0xf4,0x26,0xbc,0xf3,0x7,0xde,0x8c,0xb6,0x65,0xc0,0xcc,0x79,0x9d,0xbb,0x74,0xfe,0xcd,0xa7,0x69,0x65,0xd6,0x5a,0x1e,0xeb,0x88,0x9,0x27,0xa0,0x9a,0xc8,0x98,0x27,0x96,0x15,0x4b,0x2a,0x3d,0x31,0x1c,0x69,0x7c,0x25,0x9f,0x57,0x57,0x84,0x2b,0x59,0xdd,0x1c,0x22,0x42,0x72,0xa4,0x40,0x10,0x66,0x12,0x8a,0xfc,0xd9,0x16,0x48,0x98,0x6f,0x1a,0xb6,0x6b,0x20,0xb9,0x71,0xc,0xb4,0x31,0x63,0x9d,0xe7,0xb9,0x60,0x7e,0xee,0xde,0x53,0x80,0x14,0x9c,0x43,0xa,0x41,0x2d,0x38,0x72,0x4a,0xc4,0x68,0x33,0xd0,0xd,0x9b,0x9c,0xb2,0x5e,0x93,0xac,0x1b,0x64,0xf3,0x50,0xd7,0x17,0x62,0x9d,0xb0,0xc2,0xd2,0x5b,0x84,0x5b,0xa8,0x62,0xc0,0x28,0xb4,0x26,0xf3,0xa7,0x86,0x81,0x8,0x8,0x28,0x94,0xbc,0xf2,0xdf,0x2b,0x96,0x7f,0x38,0x80,0xe9,0x4e,0x62,0x69,0x87,0xe4,0xc1,0x3,0x40,0x6f,0x89,0x35,0x9a,0x3,0x20,0xf0,0x98,0xe1,0x57,0x1e,0xf0,0x18,0x97,0x33,0xc7,0xc,0xc0,0xf5,0x13,0xad,0x5f,0xe7,0xe1,0xd7,0x4d,0x5e,0xbf,0xf,0xd5,0xfe,0xce,0xdf,0x17,0xb,0x97,0x2a,0x3,0xae,0x55,0xab,0x56,0x5,0x0,0x6b,0xd5,0xaa,0x55,0xeb,0xc5,0x5e,0x29,0x15,0xb,0xbf,0xac,0xec,0xbb,0x85,0xc7,0x8c,0x2c,0xc0,0xb3,0x2c,0x6,0xed,0x2c,0xa9,0x15,0xef,0x20,0x6,0x44,0x8,0x18,0x34,0x85,0xe4,0xb6,0x58,0x63,0x8b,0xac,0x37,0x65,0xa4,0x38,0x69,0x82,0xb0,0xfa,0x13,0xa5,0xb9,0x1,0x20,0x2f,0x38,0x66,0x7a,0xe5,0x84,0xfd,0xf6,0xe,0x60,0x48,0x66,0x3a,0xf6,0x7b,0x65,0x51,0x90,0x37,0xe0,0x8,0x63,0x3a,0x62,0x70,0x45,0xa,0xc,0xa1,0x40,0x7,0x92,0x35,0x91,0x5c,0xd5,0x2f,0x58,0x5b,0x0,0x90,0x2,0x85,0x72,0xc8,0x3d,0x3a,0x96,0x4e,0x19,0x63,0x71,0x7e,0xed,0x6,0x7c,0xd3,0xe2,0xf2,0xd6,0xd3,0x94,0x76,0xbb,0xdf,0xaa,0x67,0xde,0xb5,0xeb,0xf,0x60,0xec,0x77,0xd8,0x4d,0x13,0x31,0x0,0x9b,0x8c,0x69,0x1a,0xd0,0xb6,0x1b,0x6c,0x2f,0x6f,0xc3,0x79,0x8f,0x71,0xd8,0x93,0x5c,0x98,0x81,0x37,0x32,0x7f,0x3f,0xc7,0x34,0xd,0x2a,0x2d,0xce,0x89,0x92,0x28,0xc3,0x34,0xf2,0xbf,0x93,0xfa,0x1a,0xa,0x6b,0xc5,0x79,0x2,0xcf,0x88,0xb9,0x91,0x88,0x81,0xa9,0xb,0x74,0xc3,0xb2,0xaa,0xac,0x1e,0x7d,0x86,0x3d,0xe7,0xc4,0xb,0x4f,0x53,0x1d,0x59,0x3a,0x1b,0x39,0xe9,0xd6,0x5c,0x7f,0x80,0x80,0x4b,0xf6,0xbb,0x6b,0x3a,0x3f,0x33,0xeb,0xa,0x39,0xac,0x80,0x8c,0xf2,0xec,0xad,0x75,0xc4,0xec,0x63,0x46,0x46,0xc,0x1,0xfb,0xed,0x25,0x42,0x18,0x61,0x0,0xa4,0x18,0x70,0xed,0xc6,0x83,0x18,0xfa,0xdd,0xdc,0xe4,0x32,0x3b,0x54,0xbc,0xfd,0xc8,0xcf,0xaf,0xd7,0xcf,0xd3,0xd0,0xef,0x61,0xad,0x81,0x6f,0x3a,0x6,0x83,0xcf,0x0,0x64,0x4,0x96,0x87,0x5b,0xe7,0x90,0xa7,0x8c,0x7e,0x77,0xa5,0xe6,0xf0,0x22,0xff,0xf5,0x4d,0xcb,0xef,0xbf,0xc5,0xc4,0xcc,0x45,0x69,0x58,0x84,0xd5,0x48,0x9,0x9a,0x13,0xb6,0x97,0xb7,0xd1,0xb4,0x1d,0xae,0x19,0x83,0xb6,0x3b,0x53,0x20,0x32,0xa5,0x0,0x8b,0xa6,0x8,0xb9,0x99,0xd3,0x30,0xad,0x75,0x88,0x8,0x48,0xcc,0xb6,0x34,0xd6,0x61,0x77,0x75,0x1b,0x9b,0xf3,0x6b,0xcc,0x30,0x9d,0x3,0x5d,0xc4,0x1f,0xd2,0xe4,0x59,0x8e,0x26,0x9,0xca,0xe2,0x9f,0x69,0x8c,0x43,0xce,0xb1,0x8e,0x3b,0xb5,0x6a,0xbd,0xa0,0x32,0x8b,0x3c,0x7,0xb1,0x1,0xc8,0x59,0xec,0x27,0xe8,0x77,0xd0,0xe9,0x58,0xc5,0x1e,0xa0,0xc,0xd6,0x9,0xb,0xd8,0x38,0xb7,0x0,0x39,0xac,0xb5,0x78,0xe2,0xd5,0xaf,0x3c,0x4a,0xfb,0xcd,0x39,0xe3,0x3d,0xef,0xfd,0x13,0x3c,0x7d,0xb9,0x57,0xc0,0x69,0xa,0x13,0xac,0xf3,0xc4,0x8e,0x4b,0xcb,0xd,0x2e,0xe4,0x8c,0xab,0xfd,0x80,0xff,0xe7,0xb7,0x3f,0x84,0x4f,0x7d,0xee,0xab,0xf8,0x87,0x3f,0xfd,0xb7,0xd9,0x4e,0x80,0x82,0x3c,0xc8,0x52,0xa0,0x63,0xe0,0xce,0xac,0x45,0xd0,0xd2,0x1c,0xc5,0x89,0xea,0x92,0x4a,0x2f,0xc1,0x1e,0x62,0x79,0xe0,0x7c,0xc3,0xc,0xf1,0x49,0x25,0xbe,0xd6,0x39,0x4c,0xd3,0x88,0xa6,0xdb,0x20,0xc7,0xa4,0x1b,0x39,0x22,0xff,0x15,0x60,0xd1,0x78,0x92,0xe,0xd3,0x58,0x3a,0xaa,0xbf,0x9e,0x75,0xcc,0xd0,0xcf,0x1,0xd3,0x38,0xe8,0xe6,0x6,0xcd,0x61,0xd,0x32,0x12,0xc,0x2c,0x1,0xac,0xa0,0xb0,0x2a,0xcf,0x73,0x8b,0x30,0xf8,0x8d,0xb5,0x7a,0x3e,0x49,0xff,0x35,0x59,0xec,0x11,0xe8,0x41,0x11,0xe8,0x47,0xf3,0xae,0x24,0x17,0x6b,0x62,0xb0,0x78,0xce,0x49,0x60,0x8b,0x78,0x26,0xae,0x24,0xe7,0x66,0x14,0x9,0xc3,0xfa,0x7e,0xa5,0x42,0xe2,0x8b,0xe5,0xa6,0xe6,0xa9,0xf0,0x8e,0x2,0x48,0xcb,0x0,0xcc,0x41,0x40,0xc8,0xea,0x5b,0xb4,0x12,0xd6,0x61,0xb0,0x94,0xea,0x96,0x92,0xe6,0x43,0x9f,0xbe,0x5c,0x82,0x9b,0xcb,0x65,0xd6,0x82,0xf7,0xb7,0x0,0xff,0xf2,0xa,0x78,0x77,0x4,0xee,0x9d,0x2,0xf6,0xd6,0x5e,0x73,0xf2,0xee,0xf4,0x65,0xb9,0x6e,0x60,0xd5,0xaa,0x55,0xeb,0x45,0x52,0x35,0x4,0xa4,0x56,0xad,0x5a,0xb5,0xee,0xd9,0x47,0x1d,0xec,0x33,0xb,0x60,0xa7,0x69,0x7d,0xf3,0x22,0x51,0x98,0x4,0xea,0xdb,0x83,0xcc,0x92,0xc9,0xac,0x29,0xc1,0xca,0xbe,0x60,0x6f,0x25,0x1,0x48,0x8c,0x81,0x4a,0x6e,0xa5,0x29,0x20,0x9f,0xbb,0xa4,0xc9,0xab,0xe2,0xb9,0x26,0x89,0xb2,0x12,0xee,0x60,0xac,0x45,0xb7,0xb9,0x50,0x40,0x66,0x7b,0xe7,0x96,0x6,0x8b,0xa8,0xa1,0x39,0x3,0x86,0x56,0x53,0x76,0xa3,0x2,0x34,0x21,0x4c,0x98,0x86,0x9e,0x1a,0x2a,0x6,0xd6,0x88,0xe9,0x25,0xcd,0x14,0xc9,0xb0,0x28,0x61,0x16,0x68,0xbb,0x8d,0x6,0x5a,0x58,0xe7,0xe0,0x9c,0xc7,0x6e,0x7b,0x7,0xd3,0x34,0xa2,0xed,0x36,0xe8,0xfb,0x1d,0xae,0xee,0xdc,0x62,0x46,0xdb,0x80,0x67,0x9f,0xfa,0x3a,0xc6,0x7e,0x8f,0xdb,0xcf,0x7c,0x43,0x83,0x39,0x90,0xa1,0x29,0xba,0xc4,0xae,0xa0,0xc4,0x61,0x62,0x2f,0x4e,0xfc,0xef,0x81,0x31,0xd8,0xa4,0x72,0xd8,0x69,0x1c,0x48,0xba,0x6b,0x96,0x3a,0xa3,0x9c,0x93,0xca,0xcc,0x62,0x88,0x2a,0x7f,0xa2,0x84,0xdc,0xa8,0x9,0x91,0x74,0xbc,0x88,0x74,0x20,0xd7,0xf1,0x85,0xf7,0x94,0xe1,0x94,0x60,0x7a,0xbe,0x91,0xc3,0x59,0x8,0xcc,0x15,0x46,0xa6,0xc8,0xbe,0x25,0x4,0x64,0x1a,0x7,0x6,0xf2,0xb2,0xb2,0xf6,0x88,0x5d,0x62,0x61,0x1d,0x25,0x46,0x6f,0xaf,0xe8,0x19,0xf5,0xfb,0x2d,0xa6,0xa1,0xc7,0xb0,0xdf,0xe9,0xbd,0xb,0xd3,0x31,0xe7,0x8c,0x7e,0x47,0x60,0xea,0xf6,0xf2,0x16,0x84,0xc5,0x37,0xec,0xf7,0xf4,0xba,0xb1,0xe7,0x73,0x4e,0x2a,0xc9,0x8b,0xfc,0xfe,0x49,0x9f,0x12,0x63,0xc0,0xee,0xea,0xe,0x44,0x1a,0x17,0x26,0x92,0xd2,0x9,0xf8,0x97,0x62,0xe2,0x40,0x13,0xa,0x2a,0xa1,0x70,0x17,0x62,0x4a,0x36,0xdd,0x46,0xcf,0x43,0x40,0x71,0xa0,0xe7,0xc1,0xbe,0x56,0xfa,0x2c,0xf8,0x73,0xeb,0x7c,0xc3,0x8c,0x3f,0x36,0xdf,0xcf,0x19,0x6d,0x77,0x36,0x1b,0xef,0x4b,0xe2,0x35,0x66,0x7f,0x2b,0x5,0x2d,0x17,0xb2,0x29,0x49,0x1e,0xad,0x8d,0x54,0xad,0x5a,0x2f,0xb4,0x66,0xf9,0x64,0x3e,0x98,0xcb,0xb0,0xb0,0x8,0x20,0x8b,0x82,0xc0,0x56,0x0,0x86,0x19,0x72,0x73,0xa,0xb8,0x58,0x5c,0xc8,0xd8,0x66,0x8c,0xc5,0xc3,0x2f,0x7b,0xc9,0xd1,0xf9,0xf6,0xfd,0x88,0xbf,0xf8,0xc2,0x5f,0x29,0x23,0x2d,0x84,0x30,0xb3,0xd1,0x8b,0x70,0x29,0xf1,0xbe,0x13,0x86,0x70,0x8,0x13,0x3e,0xf1,0xf9,0xaf,0xe1,0x97,0xff,0xf7,0xff,0x17,0x9f,0xff,0xf2,0x5f,0x11,0x23,0xdd,0x8,0x2b,0x98,0x82,0x34,0x9c,0xf3,0x77,0x49,0x8b,0x20,0x76,0x5e,0xd3,0x76,0x3c,0x97,0x4c,0x9a,0x1a,0x6c,0xec,0x6c,0x7d,0x61,0x8c,0x45,0xd3,0x6e,0xe0,0x7c,0x83,0xa6,0x21,0x16,0x35,0xd3,0xfb,0xe0,0x98,0xc5,0xd7,0x76,0x1b,0xe,0x63,0x8a,0xa,0x94,0xca,0x71,0x3d,0x87,0x5f,0xa5,0x14,0x79,0xce,0x75,0x94,0x2a,0xcc,0x1b,0x64,0xba,0xc1,0xc7,0x4c,0x75,0x4a,0x48,0xf7,0xcc,0xc,0xf7,0x34,0x4f,0xf2,0x46,0x91,0x0,0x88,0xba,0x51,0x14,0xe7,0xb1,0x95,0x58,0x7f,0xf2,0xac,0x72,0xc1,0xfa,0xa3,0xb5,0x83,0x35,0xc4,0x92,0x9f,0x81,0xbb,0x39,0xc8,0x9,0xb,0x38,0x4c,0x40,0x60,0x9,0x2d,0xcb,0xc5,0xc7,0xc1,0xcc,0xff,0xe5,0xc7,0xa8,0x80,0xee,0xdd,0xd4,0xb1,0xc5,0x52,0xe8,0x14,0x2f,0x6f,0x19,0xb6,0x71,0x4a,0x9c,0x3b,0xfb,0xe,0x2e,0x7e,0x26,0xe7,0xa3,0x3b,0xc0,0x41,0x8,0x5b,0x3e,0x91,0x1c,0x9c,0xf,0x95,0x19,0x87,0x9,0xc2,0x77,0x63,0xff,0xad,0xdd,0xb2,0xc8,0xe7,0xcd,0xf1,0xdd,0x2d,0x40,0xf6,0x12,0xb0,0xac,0xec,0xbf,0x5a,0xb5,0x6a,0x55,0x0,0xb0,0x56,0xad,0x5a,0xb5,0x5e,0xe4,0x83,0xa4,0xf3,0xa7,0x17,0x87,0x58,0x2e,0xbe,0x45,0xc6,0x29,0x8b,0xf5,0x94,0xa2,0xfa,0x29,0xe9,0x72,0xb1,0xf0,0xb7,0x33,0x98,0xbd,0x7c,0xa0,0x86,0xe3,0xb3,0x44,0x57,0x16,0x9f,0xba,0xb0,0xe7,0x73,0x9,0x4b,0x70,0x36,0xe,0xf,0x9c,0xe0,0xda,0xa8,0x8f,0xdf,0x83,0xf,0xbf,0x82,0x43,0x2a,0xc,0xa6,0xb1,0x67,0x39,0x2c,0x98,0x15,0x11,0x34,0x5,0x32,0x30,0x38,0x26,0xac,0xb5,0xc0,0x29,0xc2,0x2,0x88,0x45,0x6e,0xe2,0x42,0x98,0x14,0xd4,0x72,0xde,0xc3,0x37,0xd,0xba,0xcd,0x39,0x2e,0xae,0xdf,0xc4,0xcd,0x7,0x1f,0xc2,0xe6,0xfc,0x2,0x6d,0x77,0x6,0xdf,0x34,0x78,0xf6,0x1b,0x5f,0xa7,0x24,0x5d,0xe7,0x31,0xc,0x7b,0x84,0x69,0xe2,0xa6,0x29,0xa2,0x3b,0x3b,0x83,0xf3,0x4,0x40,0x76,0x67,0xe7,0xe8,0x36,0xe7,0x68,0x3b,0x92,0xb3,0x8a,0x8c,0x36,0x17,0x69,0xb5,0x6d,0xbb,0xe1,0x46,0x91,0xee,0xf7,0xe2,0xfa,0xcd,0xb9,0x79,0x45,0x46,0x8a,0x69,0xe9,0xad,0xc4,0xcf,0x59,0xd2,0x17,0xc5,0x4b,0x89,0x64,0x64,0xd0,0xf7,0x44,0xe5,0xc0,0x2c,0x5,0x43,0x86,0xfa,0xd6,0xa9,0x3c,0x3a,0x17,0x8d,0x8a,0x26,0x36,0xfb,0x39,0x5,0xb2,0x78,0x56,0xe2,0x97,0x67,0x0,0xf6,0x6,0xf4,0x7a,0xc,0xdf,0xb4,0xe8,0x36,0xe7,0x4,0xd2,0x76,0x67,0x98,0xfa,0x1e,0xbb,0xab,0xdb,0x18,0x87,0x3d,0x81,0x79,0x31,0x60,0x1a,0xe9,0xde,0x49,0xba,0xdb,0x68,0x2a,0x31,0xa5,0xf3,0x26,0x8c,0xfd,0x1e,0x30,0xc0,0xe6,0xec,0x2,0xc6,0x3a,0x4a,0x6,0x4e,0x71,0x21,0x95,0xf3,0x4d,0x4b,0xc0,0x2c,0x4b,0xd8,0xba,0xb3,0x33,0x6e,0xb0,0x47,0x4e,0x82,0x9e,0x10,0xc6,0x91,0x8d,0xfc,0xc9,0x27,0x2b,0xc5,0x88,0xa6,0x3b,0xd3,0x4,0x4d,0x9,0x8a,0x11,0x20,0x7b,0xd8,0xef,0x16,0x3d,0x58,0x8c,0x91,0x3,0x56,0x92,0x7e,0x4e,0x63,0x98,0x28,0xc8,0xc4,0x37,0xb0,0xde,0xf1,0x67,0x61,0xa3,0xcf,0x37,0xb1,0xcc,0xcc,0x60,0xf6,0x1b,0xcc,0x2a,0xd5,0x63,0xf,0x27,0xf1,0xc5,0xac,0x43,0x4e,0xad,0x5a,0xf7,0x9,0x1,0xcc,0xb3,0xe4,0x53,0x7d,0xe3,0xc,0x1,0x63,0xc6,0x22,0x31,0xc0,0xe5,0x5c,0xa3,0x69,0xf3,0x29,0x6,0xe,0xb0,0xa0,0x5f,0x78,0x99,0x43,0xac,0xb1,0x1a,0x28,0x5,0x3,0x6c,0xba,0x76,0xe5,0x74,0x9,0xd3,0x34,0xfb,0x83,0x92,0x3f,0x29,0xcd,0x5d,0x29,0x6,0x9d,0x83,0x20,0xfe,0x82,0x7c,0x7d,0x32,0xe7,0x7d,0xe5,0x1b,0xcf,0xe2,0x73,0x5f,0x7b,0x86,0x81,0x2a,0x1e,0x9b,0x79,0x43,0xc4,0x18,0x73,0x22,0x21,0x9c,0x60,0x22,0xdf,0xb6,0x7a,0x7c,0xc7,0x3e,0xad,0x2,0xfe,0x11,0x3,0x3f,0x73,0xc2,0xfc,0x4,0xa7,0xf3,0x5c,0xe2,0x30,0x10,0xba,0x3f,0xa,0x37,0xa1,0x73,0xf9,0xb6,0x83,0xe7,0x31,0x58,0xe6,0x8,0x19,0xf3,0x9b,0xb6,0xa3,0x8d,0x14,0xde,0x6c,0x53,0x70,0x92,0xaf,0x4f,0xbe,0xa6,0x32,0x6a,0xbe,0x52,0x92,0x9,0x27,0xd,0x16,0x93,0x75,0x84,0x4,0x4c,0xa1,0x9c,0x77,0xc4,0x83,0xd5,0x94,0xf7,0x69,0x66,0xbf,0x61,0x3,0x2,0x20,0x79,0xd3,0x44,0x8e,0x65,0x6c,0x91,0x67,0x5b,0x80,0x86,0x38,0x4c,0x58,0xcf,0xc7,0xec,0xb8,0xbc,0xc6,0xfa,0x3b,0xc4,0xcb,0xee,0x9a,0x8b,0x91,0x61,0x8e,0x90,0xb5,0x99,0xd5,0xb7,0xee,0xd1,0x77,0x8,0x50,0xcf,0x27,0x5e,0xb0,0xf9,0x4e,0x63,0xbf,0x27,0x1,0xca,0xa3,0xef,0x1,0xeb,0xc,0xbf,0x23,0xf6,0xdf,0x32,0x27,0x79,0xfe,0xba,0xb9,0xcb,0x8b,0xf2,0x12,0x50,0xad,0x55,0xab,0x56,0xad,0x6f,0xe1,0xaa,0x12,0xe0,0x5a,0xb5,0x6a,0xd5,0xba,0x6b,0xf,0x95,0x97,0xb2,0x99,0xd2,0x51,0x3d,0xcf,0x7f,0x17,0x86,0x84,0xf8,0xfd,0x8,0x28,0xb4,0x90,0x85,0xf0,0xa,0xda,0x70,0xf2,0x1f,0xb1,0x8,0x8c,0xfa,0xa7,0x9,0x1b,0x6a,0x5e,0xd0,0x93,0xc1,0x38,0xc9,0x5a,0xb3,0x32,0xc,0xa5,0x49,0x89,0x9c,0x44,0x9b,0x52,0xd2,0xe6,0x65,0x73,0x7e,0x41,0x9,0xc0,0x6e,0x7,0xef,0x5b,0x4a,0x46,0x8c,0x11,0x2d,0x83,0x3c,0xd2,0x14,0x44,0xf1,0x87,0x4a,0xd0,0x6b,0x48,0x12,0x56,0x62,0x5d,0xd1,0xb0,0xe4,0xc2,0x5f,0x29,0xce,0xec,0x44,0x63,0x70,0x7e,0xfd,0x26,0x86,0x7e,0x8f,0xfd,0xf6,0xe,0xce,0xaf,0xdd,0xd4,0x66,0xa6,0xdb,0x9c,0x63,0xd8,0xef,0xd0,0xef,0xae,0x88,0x1d,0xe6,0x3d,0x7c,0x6a,0xf9,0x98,0x11,0xd6,0xfa,0x99,0xad,0xe7,0xe9,0xb8,0x4d,0xb7,0x61,0xaf,0xbe,0x82,0x19,0x1,0x4e,0xad,0x35,0xe4,0x27,0xd8,0x6,0xf2,0x1c,0x3c,0xbf,0x76,0x3,0x4d,0xb7,0xa1,0xc4,0x48,0xe,0xea,0x88,0x9c,0x5a,0x2c,0xac,0x91,0x9c,0xb2,0xfa,0x28,0x65,0x24,0x4d,0x67,0x16,0xbf,0x25,0xcb,0xec,0xd,0xe7,0x3c,0xa6,0x38,0xa0,0x69,0x5b,0x34,0xed,0x83,0x68,0x9a,0xe,0x43,0xbf,0x43,0xd3,0x76,0x2a,0xbf,0x26,0x76,0xc6,0xfc,0x3c,0x60,0xc,0xf9,0x8,0x5a,0xa7,0xa1,0x2b,0x28,0x12,0x7d,0xc5,0x3,0xd1,0x3a,0xf,0xf,0xa,0x92,0xe9,0x36,0xe7,0x9c,0x18,0x3c,0x22,0x83,0x8c,0xea,0x67,0xb9,0x1d,0x3f,0x1b,0xf6,0xaa,0xa,0xd3,0x8,0xeb,0x3d,0x5c,0x6a,0xb1,0x39,0x7,0x86,0xfd,0xe,0x9b,0xf3,0x6b,0x33,0xd8,0x96,0xc5,0xac,0x9f,0xc0,0xb3,0x59,0x46,0x46,0xfe,0x56,0x6d,0xbb,0x51,0x6f,0x40,0x5,0x8c,0x45,0xce,0xc7,0x40,0xa0,0xb0,0x51,0x9a,0xb6,0x83,0x61,0x1f,0xc7,0x89,0xd9,0x96,0xde,0xb7,0x9c,0x4a,0x6c,0x58,0x1a,0x1c,0x60,0x9a,0x56,0xfb,0x47,0x39,0x66,0x66,0x50,0x56,0xbc,0xa9,0xac,0xb5,0xb8,0xb8,0x76,0x53,0x25,0x71,0xdd,0xd9,0x39,0x85,0xc,0xa8,0x89,0x7d,0x9a,0x65,0xe6,0xc,0x96,0x4b,0x7a,0x22,0x7d,0xa6,0xb9,0xed,0x32,0xb6,0x4a,0x80,0x6b,0xd5,0x7a,0x81,0x65,0xac,0x21,0xfb,0xa,0x9e,0x7c,0x74,0x2c,0x2b,0x80,0xaa,0x9c,0x12,0x42,0x1a,0x39,0xd0,0x22,0xc3,0x3a,0xd9,0x34,0x31,0x45,0x9a,0x3d,0x8d,0x79,0x81,0xc1,0x2f,0x3,0x83,0xb8,0x22,0x77,0xec,0xda,0x16,0xf,0xbf,0xe4,0x1a,0xbe,0xfc,0xd4,0x1d,0xf5,0xdb,0x93,0x4d,0x31,0x49,0x4c,0x27,0x8b,0x83,0xb8,0xf0,0x4,0xa4,0xf1,0x2f,0x63,0x9a,0x46,0xda,0xe8,0x61,0x2f,0x35,0xef,0x3d,0x31,0xe0,0x85,0x51,0x97,0xd7,0xa9,0x69,0xd6,0xd2,0x5c,0x4c,0x52,0x5f,0x9,0xf,0x9,0x88,0x31,0x60,0x73,0x7e,0xd,0x81,0x19,0xe3,0x92,0x5e,0x4c,0x63,0xdc,0x6c,0x4d,0x50,0x2,0x63,0xb2,0xc1,0x35,0xfb,0xc5,0xce,0x16,0x9,0x94,0xa,0xdf,0xea,0x6,0x55,0xce,0x19,0x4d,0xd3,0xf0,0xe3,0xb1,0x48,0x31,0xe8,0x46,0x10,0x0,0x7a,0xa6,0x3c,0x1f,0xd8,0x42,0x46,0x2d,0x73,0xa9,0x48,0x7d,0x53,0xa,0xc8,0x79,0xe,0xdd,0x22,0x10,0xcb,0x2c,0x36,0xa3,0x12,0xcf,0xd,0x90,0xcd,0x14,0x33,0xdb,0x74,0xcc,0xeb,0x87,0xac,0xbe,0x81,0x92,0x0,0xad,0xa9,0xb4,0xb,0x10,0x30,0xaf,0x4a,0x78,0x8f,0x0,0x34,0xdd,0xfb,0xca,0x7,0x8e,0x7d,0xe5,0x5a,0xc8,0x2c,0xd8,0xdd,0xa5,0xa8,0x37,0x1f,0x82,0x64,0x87,0xa9,0xd4,0x38,0x1,0xd6,0x99,0xbc,0xee,0x21,0x68,0xee,0x2,0x4,0xae,0x2,0x7d,0x77,0x97,0xed,0xde,0x7b,0xb7,0x69,0x3d,0x4d,0x38,0x1f,0xdd,0x1f,0x74,0xbd,0x87,0xba,0x85,0x55,0xab,0x56,0xad,0xa,0x0,0xd6,0xaa,0x55,0xab,0xd6,0x8b,0xbc,0x89,0xd2,0xdd,0x74,0xfa,0x3f,0x53,0xf8,0xe3,0xe9,0xe2,0x30,0x1f,0x80,0x83,0x98,0x13,0xf9,0xa,0xee,0x9f,0x82,0x6f,0xe0,0x9d,0x7a,0x73,0xd0,0x10,0x98,0x22,0x10,0x21,0x86,0x49,0x1b,0x36,0xe7,0x5c,0xe1,0xcd,0x37,0xcb,0x79,0x48,0xaa,0x94,0xb4,0x99,0x6b,0xdb,0xe,0x29,0x6,0x74,0x67,0x67,0xf0,0x4d,0x8b,0x30,0xd,0x94,0x8,0xdc,0x8,0x48,0x46,0x7e,0x7c,0x64,0x4e,0x1e,0xa,0x90,0x92,0x98,0x1e,0x31,0x64,0x95,0xfd,0x96,0x40,0x1a,0x5d,0xdf,0x2c,0x69,0xca,0xac,0x33,0xcd,0x39,0xa1,0x69,0x5a,0x84,0xb6,0x53,0xc6,0x83,0xb0,0xd9,0x9c,0xf7,0xd8,0x9c,0x5f,0x63,0xa9,0x6f,0x46,0xc3,0x0,0xa5,0x18,0xa5,0x37,0xdd,0x6,0xc3,0x7e,0xc7,0x6c,0x39,0xcb,0x52,0x29,0xa7,0x6c,0x8b,0x14,0x67,0xe6,0x9e,0xa4,0x53,0x76,0x67,0x17,0xf0,0x7e,0xd2,0xe6,0xcb,0x72,0xc8,0x85,0xc8,0xac,0xe4,0xb9,0x13,0x18,0xb,0x5,0x95,0x84,0xad,0x46,0xa0,0x27,0xb3,0x4f,0xc,0x90,0x42,0x0,0x98,0xf9,0x21,0xc0,0x96,0x6f,0x3b,0x66,0xc9,0x38,0x6,0x2a,0x33,0x3,0x94,0x1d,0x7,0x80,0x24,0x6a,0x8e,0x99,0x19,0xaa,0xef,0x33,0xff,0xd7,0x37,0x8d,0x32,0x3f,0xac,0x0,0x84,0xae,0x1,0x3a,0xc3,0xd2,0xeb,0xd,0x1b,0xc9,0x5b,0x6e,0x20,0xa9,0xa1,0x6c,0xda,0x4e,0x8f,0x13,0xa7,0x9,0x6d,0xb7,0x41,0xdb,0x76,0xd8,0x5e,0xdd,0xc1,0xcd,0xf3,0xb,0x80,0xdf,0xf,0x63,0x2c,0x5,0x7a,0x30,0xeb,0x8e,0x1a,0xfa,0xd9,0x47,0xd0,0xfb,0x6,0xe6,0xec,0x9c,0x80,0x4d,0x4e,0x6a,0x96,0xb4,0xe4,0x39,0xf8,0x25,0x2b,0x13,0xcf,0x5a,0x87,0xb6,0x23,0xff,0x3f,0x77,0xde,0x28,0xcb,0x13,0x19,0x70,0xae,0xe1,0x50,0x0,0x5f,0x18,0xcf,0x47,0x38,0xd7,0x30,0x0,0x60,0xd8,0x54,0x9f,0x58,0x86,0xbe,0x69,0x29,0x2c,0xc0,0x37,0xc5,0x33,0x89,0x68,0xdc,0xa6,0x90,0xfc,0x66,0xd,0x96,0x29,0x7e,0x59,0xd8,0xc7,0xca,0x23,0x85,0xdb,0xcb,0xef,0xd5,0xaa,0x55,0xeb,0x79,0xcf,0x5e,0xca,0xb1,0xca,0xb3,0x97,0x9a,0xc8,0x4a,0x8d,0x71,0xa,0x54,0xd1,0xef,0x76,0x42,0x4a,0x34,0x3e,0x58,0x66,0x50,0xcb,0x46,0x91,0xc8,0x69,0x25,0x8c,0xe2,0x99,0x67,0xef,0xe0,0x55,0x8f,0x3d,0xba,0x6c,0x28,0xbc,0xc3,0xf,0xbe,0xf9,0x3b,0xf1,0xa5,0xf7,0x7c,0x70,0x61,0xc1,0x56,0x26,0xd5,0xca,0x1c,0xe8,0x38,0xc4,0xca,0x58,0x87,0x30,0xd,0x3a,0xef,0xa5,0x18,0xd0,0x74,0xcd,0x1c,0x40,0xe2,0x2c,0x52,0x22,0xf9,0xad,0x6c,0x8c,0xad,0x20,0x9d,0x7c,0x8d,0x8e,0x2,0x8c,0x8a,0xb0,0xad,0x18,0x26,0x58,0xeb,0x74,0x2e,0x6a,0xda,0x73,0xf2,0x5e,0x6d,0xc8,0x63,0xd6,0x39,0xda,0x94,0x12,0x3f,0x44,0x5,0xdd,0x78,0x7c,0x2e,0xc1,0x1d,0x93,0xa1,0x81,0x59,0xe2,0x17,0x48,0x0,0x1e,0x85,0x8e,0x8,0x7b,0x3a,0x83,0x3c,0x80,0xc7,0xa1,0x67,0xb6,0x7c,0xab,0xbe,0x84,0x12,0x1e,0x25,0xa1,0x48,0x93,0x4,0x8b,0x18,0xf2,0xaa,0x9d,0x55,0x1,0x46,0x83,0x48,0x12,0x87,0x67,0x19,0x0,0x91,0x7d,0x1c,0x4b,0x40,0x2f,0x3,0xc8,0x31,0x2e,0xc6,0x58,0xdd,0x90,0xca,0xe9,0x98,0x39,0x99,0x71,0x62,0x3,0x73,0x5e,0x5f,0x2c,0xd8,0x6f,0x19,0xc8,0xe6,0x78,0x8d,0x33,0x43,0x63,0x79,0x6,0xc4,0x18,0xe4,0x5b,0xe5,0x72,0xaf,0x1,0x79,0x6b,0xf8,0x5c,0xe9,0xb7,0xb7,0x2,0x48,0x9e,0xc0,0xe5,0x70,0xfa,0x84,0x87,0x27,0xcf,0xc0,0xc2,0x75,0xf0,0x5e,0xe0,0x1f,0x56,0xef,0xf9,0xf8,0xb2,0xab,0x75,0x45,0xad,0x5a,0xb5,0x2a,0x0,0x58,0xab,0x56,0xad,0x5a,0x2f,0xfa,0x4a,0x29,0xcc,0xeb,0x65,0xcc,0xec,0x3e,0x5d,0x42,0x16,0xcc,0xa5,0x59,0x76,0x34,0x1b,0xae,0x1f,0x9a,0xd1,0x88,0x14,0x55,0x76,0xe8,0xa9,0xe1,0xe0,0xaf,0x19,0x91,0x3e,0xcd,0xec,0x41,0x6b,0x67,0xb6,0x86,0x48,0x87,0xe5,0x98,0x24,0x61,0xf2,0x70,0xce,0x28,0x3b,0xcf,0x32,0x90,0x66,0x5d,0x42,0xd3,0x75,0xb,0x76,0x56,0x99,0x52,0xa7,0x20,0x14,0xfb,0xdb,0x4d,0xe3,0xc8,0x4d,0x1f,0x98,0x3d,0x46,0xcc,0x36,0xe3,0xa8,0x1,0x29,0x13,0x7,0x93,0x4a,0x74,0xa9,0x71,0xe9,0x36,0x17,0x18,0x87,0x3d,0xba,0xb3,0x73,0x66,0x1b,0x6e,0x16,0xcc,0xc9,0x30,0x8d,0xec,0x99,0x97,0xd9,0xb,0xc9,0x73,0xd2,0xee,0x39,0xa7,0x26,0x92,0x41,0xba,0x34,0x78,0x72,0x9d,0xd2,0x4,0x59,0xb,0xc0,0x5a,0xb8,0x48,0xe9,0xbd,0x2,0x2e,0x9,0x3b,0x2d,0xe7,0xc,0xd3,0x74,0xb0,0xd6,0xa8,0x24,0x57,0xce,0x95,0xe2,0xfc,0xfe,0x88,0x11,0x3a,0xbd,0x41,0xb3,0x74,0xca,0x30,0xd3,0x25,0xc6,0x89,0x65,0xd4,0x4e,0xcd,0xda,0xad,0xf7,0xa,0xc0,0x4a,0xa2,0xb3,0xbc,0xad,0x2,0xa2,0x49,0xa3,0x66,0xc,0x18,0x34,0x4d,0xca,0x8,0x11,0xe6,0x8d,0x78,0xf,0x9a,0x48,0xe1,0x29,0xce,0x37,0x18,0xfb,0xbd,0x4a,0xec,0x48,0xbe,0x46,0x12,0x5c,0xdf,0xb6,0x4,0xca,0x3a,0x8f,0x8b,0x6b,0x37,0xd8,0x5b,0x6f,0x4f,0xa9,0xbf,0x80,0xa6,0x14,0xcf,0x8d,0x62,0x91,0x9f,0x58,0x34,0x8e,0x24,0x55,0xa3,0xd7,0xe4,0x94,0xc8,0xd0,0x3e,0x4c,0x4,0xd4,0xf1,0xfb,0x23,0xa1,0x27,0x6d,0xb7,0xc1,0xc4,0x72,0xe2,0x94,0xc9,0xd7,0xf,0x85,0xc7,0x21,0xa9,0xea,0x66,0xcf,0xca,0x52,0x76,0x96,0x52,0x42,0xd3,0x6e,0x34,0x2c,0x85,0xfc,0x16,0x9,0x44,0x14,0x49,0x77,0x52,0x73,0x7d,0x50,0xc8,0x87,0x34,0x99,0x79,0x6e,0xf8,0x52,0x9c,0xe8,0x9c,0x35,0x49,0xb1,0x56,0xad,0x17,0x5c,0xa,0x48,0xf0,0x86,0x88,0xfc,0xfe,0xc5,0x18,0xd5,0xb,0x94,0xa6,0xad,0xa4,0x5e,0xb1,0x2,0x20,0xd1,0xc6,0x93,0xe1,0xf4,0x5f,0xcf,0x29,0xb5,0x73,0x3d,0xf5,0xcc,0xb3,0xab,0xe7,0x7c,0xdb,0x9b,0x5e,0x8b,0x4f,0x7c,0xe6,0xb,0xf8,0xf3,0xcf,0x3f,0xa9,0x6c,0x43,0xe7,0x9c,0x6,0x12,0x21,0x12,0x98,0x18,0xd9,0x13,0x30,0xf2,0xdc,0x20,0xe3,0x66,0xbb,0x39,0xc3,0x34,0xf4,0x6c,0x4b,0x40,0xe3,0xb5,0x6f,0x3c,0xcd,0x53,0x27,0x0,0x16,0xda,0x8c,0xa1,0xf3,0x4,0x80,0x13,0xe7,0x3,0xac,0x33,0xf0,0xb6,0x61,0x3f,0xdb,0x80,0x6e,0x73,0x86,0x69,0x18,0xe0,0xac,0x53,0x56,0xb7,0x24,0xa9,0xb,0xe0,0x97,0x4c,0x54,0xbf,0x40,0x99,0x4b,0x24,0x8,0xca,0x18,0x8b,0xa6,0xe9,0x74,0x73,0xce,0x1a,0x7,0xe3,0x2d,0xc,0xdb,0x22,0x18,0xeb,0x54,0x3e,0x2d,0x3e,0xa8,0x60,0x76,0x7a,0x6,0xe8,0xb5,0x31,0x90,0x5d,0x42,0xd3,0x42,0x7c,0x79,0x5,0xb0,0x94,0xf5,0x83,0x35,0x96,0x6d,0x3d,0xa,0xdf,0x3f,0xeb,0x10,0x26,0x66,0xfc,0x73,0x18,0x16,0x34,0x1c,0xcc,0xa9,0x65,0xc6,0x2a,0x53,0xb2,0xfc,0x37,0xcf,0x19,0x49,0xa4,0xc8,0x2,0xfe,0x15,0x1b,0x99,0xc2,0x2c,0x5f,0x9a,0xfd,0xe5,0xe2,0x7b,0x7,0x20,0x61,0x9,0x88,0xdd,0x8b,0xa5,0x77,0xb7,0x4,0xde,0x7c,0x80,0xa,0x9a,0x95,0xef,0x1f,0xab,0x8b,0xf,0x2,0x3a,0x4a,0x85,0xc6,0xa9,0xb,0x31,0x77,0xc5,0x1f,0x4f,0x41,0x7d,0xe6,0x4,0xe,0x59,0x6,0xc4,0xd5,0xaa,0x55,0xab,0x56,0x5,0x0,0x6b,0xd5,0xaa,0x55,0xeb,0x45,0x5e,0x86,0xe5,0xb0,0xf9,0x68,0x69,0x48,0x49,0x20,0xd6,0xcc,0xac,0x6,0xea,0xb5,0x8a,0xa5,0xb3,0x30,0xfd,0x54,0xc6,0x8b,0x42,0x92,0x65,0x94,0x91,0xa1,0x1e,0x76,0xb2,0xfb,0x6e,0xc,0xb1,0x12,0x94,0xad,0x11,0xf5,0x5a,0x68,0xb1,0x9e,0x75,0xe1,0xaf,0xb2,0x23,0xe,0x6f,0xb0,0xce,0x91,0x97,0x9e,0x71,0xca,0x92,0xb3,0xa6,0x61,0xe6,0xc2,0x72,0x91,0x2e,0xd,0xe,0x58,0x2e,0x2b,0xd,0x56,0x2e,0xbc,0x6,0x25,0x81,0x51,0xd8,0x76,0x12,0xb2,0x21,0x80,0x24,0x79,0x38,0x59,0xb4,0x9b,0x33,0x6,0xb4,0x1a,0xd8,0xec,0x34,0x1c,0x44,0x9a,0xba,0xc3,0x25,0x77,0xdb,0x6e,0xa8,0x9,0x35,0x6,0x4d,0x47,0x32,0x65,0x93,0xd3,0xcc,0x30,0xcc,0x9,0x31,0x73,0x10,0x4a,0x60,0x46,0x1a,0x37,0x6b,0xae,0x8,0x93,0x20,0xb6,0x86,0x53,0xc6,0x9f,0x48,0xa4,0x53,0x9a,0xf8,0xbd,0xc8,0x88,0x51,0x0,0x2b,0x83,0xcc,0x21,0x2a,0xf2,0x9c,0x45,0x2,0xe6,0x9b,0x46,0xaf,0x37,0x30,0x90,0x25,0x0,0x2d,0x24,0x4d,0x19,0x4b,0xd3,0x75,0x92,0x4a,0x67,0x5,0x2b,0x63,0x8,0x70,0xdc,0x4c,0x82,0x59,0x9c,0xda,0xa0,0x32,0x13,0xd1,0x19,0xb,0x4,0x6a,0xba,0x9b,0x6e,0x3,0xcb,0xe9,0x96,0x86,0x3d,0xf7,0x90,0x33,0xbc,0x6f,0x15,0x60,0x6c,0x37,0xe7,0x18,0xfb,0x1d,0xa5,0x55,0x32,0xeb,0xce,0x31,0x2b,0xd2,0x72,0x63,0x2d,0x89,0x9b,0x96,0x93,0x36,0x53,0x4e,0x38,0x3b,0xbf,0xa6,0xfe,0x8e,0xc2,0xc,0x91,0x67,0x5b,0x3e,0x3,0x95,0x79,0x37,0xcd,0xc2,0x44,0x3d,0xb1,0x3c,0xce,0xb7,0xad,0x36,0x7d,0xf3,0xe7,0xb1,0x60,0x50,0x48,0xc3,0x69,0xe6,0x90,0x19,0xdf,0xb4,0x1a,0x1c,0x33,0x9b,0xe3,0xcf,0x3e,0x97,0xc2,0x76,0x4d,0x39,0x1d,0x8,0xab,0x8,0x1c,0xac,0x8d,0x54,0xad,0x5a,0xf7,0x3,0x1,0x2c,0x40,0x9,0xf9,0x8f,0xf8,0xd2,0xb1,0x15,0x82,0x6c,0x0,0xc8,0xf8,0x21,0xa9,0xb9,0x32,0xde,0xe5,0x18,0xd9,0x87,0xd5,0xf0,0x9c,0x41,0x63,0xf4,0x1f,0x7f,0xec,0xb3,0xf8,0x5b,0x6f,0xff,0xde,0x23,0x2f,0xc0,0xa6,0x69,0xf0,0xf3,0x3f,0xf5,0x2e,0x98,0x7f,0xf3,0x7b,0xf8,0xf3,0xcf,0xfd,0x15,0xac,0xf7,0xd8,0x6f,0x2f,0xe1,0xf2,0xbc,0xa9,0x25,0x4c,0xb9,0xa8,0xc1,0x20,0x6c,0x25,0xe0,0x1b,0xf4,0xbb,0x2b,0x18,0x63,0xd1,0x32,0x88,0x23,0x16,0xe,0xf9,0xd0,0xc3,0xae,0x98,0x4f,0x44,0xb6,0x4b,0x72,0x61,0xf6,0x72,0x65,0xb6,0x3e,0x49,0x98,0x69,0x63,0x6c,0xec,0xf7,0x70,0x4d,0x83,0x27,0x5e,0xf1,0x30,0x1e,0x7f,0xe5,0x23,0x34,0xde,0xa6,0x8,0x58,0x7,0xa4,0x84,0x7e,0x18,0xf1,0x81,0x8f,0xfd,0x25,0xbe,0xe7,0x75,0xaf,0xc6,0x4b,0x6e,0x5e,0xd3,0xb1,0xce,0x64,0x72,0xb0,0xfb,0xc6,0xd3,0xb7,0xf0,0xe1,0x4f,0x7c,0x4e,0xc7,0x77,0xeb,0x89,0x49,0xef,0xbc,0x47,0x9c,0x26,0x9d,0xb,0x0,0xa8,0x8d,0x86,0x75,0xe,0x4d,0xe3,0xf0,0xc3,0xdf,0xf7,0x7a,0x58,0x9e,0x2b,0x13,0x7b,0xb4,0xa6,0x9c,0xf0,0x7,0x1f,0xfc,0x28,0xee,0x6c,0xfb,0x22,0x68,0x2a,0xe9,0xfd,0x1a,0x6b,0xe7,0x4d,0x95,0x42,0x9a,0xac,0x20,0x54,0xce,0xb0,0xcc,0xd2,0x34,0x90,0xcd,0xc5,0x99,0xf1,0xb7,0x8,0x57,0x9a,0x1f,0x74,0x11,0xc6,0x54,0x0,0x81,0x58,0x32,0xf9,0x68,0x2e,0x32,0xb,0xa4,0x2b,0x1f,0x38,0xf9,0x65,0x4d,0xe5,0x35,0x78,0xce,0xee,0xad,0xa7,0x3c,0xf8,0xf2,0xa,0x48,0x57,0x9a,0xe,0x66,0xf3,0x1c,0xf,0x2e,0x12,0xe7,0x39,0x64,0x64,0x1d,0x39,0x7c,0x2e,0x47,0xcb,0x8b,0xa0,0xe0,0xf2,0xe5,0xf9,0xe8,0xb,0x2b,0x1e,0x8a,0xb5,0x6a,0xd5,0xaa,0x55,0x1,0xc0,0x5a,0xb5,0x6a,0xd5,0x7a,0x11,0xf6,0x50,0xbc,0x33,0x5f,0x6e,0xf7,0x2a,0x10,0x92,0x78,0xc9,0x6c,0x66,0x43,0x6f,0x59,0x6c,0x8a,0x14,0x8,0x99,0x25,0xa8,0x45,0xff,0x92,0x17,0xbe,0x7a,0x89,0x18,0x67,0x12,0x26,0xc1,0xc0,0x1c,0xb1,0xd9,0x92,0x2,0x5c,0x99,0x19,0x12,0xe5,0x8e,0xb4,0x26,0xd6,0x72,0x63,0x17,0xf9,0xe7,0x9b,0xb6,0xe3,0x14,0xc6,0x49,0xcf,0xd7,0x6e,0xce,0xd5,0x8f,0x50,0x98,0x6b,0x4,0xe4,0x59,0x24,0xa4,0xe2,0xda,0xd,0x9b,0x9b,0x5b,0x5,0xff,0xc0,0xe0,0xd,0xf9,0x16,0x79,0x4e,0x9,0x66,0x89,0x55,0xc,0x6a,0xa4,0xde,0x32,0x48,0x15,0x13,0xd0,0x9d,0x5d,0xa8,0x64,0x15,0x0,0xc9,0x91,0x1d,0x81,0x4c,0xe4,0x9f,0x67,0xb5,0xd1,0x4,0x0,0xef,0x2d,0x20,0x80,0x5e,0x61,0xf8,0x4e,0x52,0x67,0x2,0xb9,0xc,0x3,0x47,0x19,0xb9,0x8,0xe8,0x60,0xe9,0x9a,0x30,0x4b,0x72,0x84,0xe5,0x30,0x15,0x61,0x4b,0x3a,0xef,0x9,0xc,0x9c,0x31,0x4e,0x7d,0x76,0x1a,0x3a,0xc2,0x40,0xa0,0xf5,0x1e,0x5e,0x8c,0xe9,0x15,0xec,0x63,0x69,0x5c,0x9a,0x83,0x2f,0x14,0xc8,0x52,0x3f,0xa6,0xcc,0xcc,0x93,0xb8,0x60,0x8b,0x8a,0x3f,0x60,0xce,0x19,0x9b,0xcd,0x39,0xa6,0x69,0x84,0xa4,0x3b,0x8a,0x7,0xa0,0xb0,0x2e,0x29,0x25,0x1a,0x68,0xda,0x16,0x29,0x6,0xd8,0xc6,0x69,0xc3,0x4c,0xac,0x1d,0xf2,0xd,0xc,0xe3,0xc0,0xcd,0x67,0x54,0xe9,0x74,0x14,0x89,0xba,0x31,0xcc,0x34,0x21,0x96,0x8a,0xa4,0x4f,0x2a,0xb0,0x97,0x22,0xbc,0x6f,0xe7,0xf0,0x12,0xea,0x1c,0x41,0x5e,0x5a,0x4e,0xc1,0x1,0xef,0x1a,0x2,0x79,0xd9,0x70,0xde,0x59,0x3a,0x8f,0x9a,0xe7,0xb,0x8,0xc9,0x9,0xbf,0x2,0x34,0x7a,0xdf,0xb0,0xec,0xce,0xf2,0xef,0x85,0x61,0x6,0x8b,0x65,0x99,0xaf,0x5,0x52,0x9c,0x9b,0xcc,0x83,0xb2,0xcd,0x19,0xe2,0xb4,0xab,0x3,0x4f,0xad,0x5a,0xf7,0x1,0x1,0x14,0x39,0xa8,0x8c,0x85,0xc4,0xf2,0xf3,0x88,0x71,0xa2,0xb1,0x9c,0xfd,0x50,0x65,0xf3,0xc1,0x3a,0xaf,0x4c,0xb2,0xb6,0xdb,0x70,0x82,0xef,0xa8,0x63,0x90,0xfc,0xde,0x7f,0xed,0xe9,0xdb,0xf8,0xc2,0x97,0xbe,0x86,0xd7,0x3d,0xf1,0xaa,0xa3,0xb3,0x5e,0xbb,0x38,0xc3,0x2f,0xfd,0xcc,0x8f,0xe0,0x77,0xdf,0xff,0x11,0xfc,0xd6,0x7,0x3e,0x89,0x6e,0x73,0xae,0xde,0x7f,0x29,0x45,0xec,0x77,0x57,0xca,0x64,0x6e,0xba,0xd,0xc2,0x34,0x61,0x64,0x86,0xb3,0xf3,0x1e,0x29,0x4,0xc,0xc3,0x7e,0x66,0xad,0xfb,0x86,0x37,0xa1,0x9a,0xf5,0x7b,0x4c,0x34,0x36,0x12,0x78,0x68,0x10,0x19,0x94,0xa3,0xd0,0x8e,0x11,0xae,0xa1,0xd7,0x39,0xef,0xf1,0xa6,0x27,0x1e,0xc3,0x7f,0xf2,0xf3,0x3f,0x81,0xb3,0xcd,0x66,0x79,0x94,0x9c,0xf1,0xbe,0xf,0x7e,0x4,0x1f,0xfc,0xf8,0x17,0x70,0xf3,0xfa,0x5,0x7e,0xee,0xa7,0x7e,0xe4,0x68,0x7c,0xba,0x7d,0xe7,0x12,0x5f,0xfc,0xef,0xfe,0x17,0xdc,0xd9,0x73,0xa0,0x9,0xcf,0xb5,0x29,0xc6,0x85,0x85,0x83,0x30,0x98,0x33,0x4f,0xfa,0xef,0xfe,0xf,0xbe,0x17,0xff,0xf1,0xdf,0xfb,0xd1,0xa3,0x2b,0x7f,0xf6,0xd6,0x6d,0xbc,0xef,0xc3,0x9f,0x50,0xb0,0xd2,0x7a,0x4f,0x89,0xf0,0xc,0xe6,0xc9,0xfc,0x24,0xe0,0x1f,0x31,0x19,0xa3,0xce,0x41,0x2a,0xa7,0x76,0x8e,0x59,0xf9,0x99,0x15,0xb8,0x99,0x37,0x5e,0xdc,0xd2,0x83,0x98,0xd9,0x9e,0x46,0x8d,0x4d,0x4a,0x46,0x5f,0x11,0x70,0x91,0xf,0x2,0x38,0xd6,0xa4,0xb7,0xc0,0x12,0xfc,0xbb,0x5b,0xf0,0xc6,0xbd,0x58,0x81,0x77,0xd5,0x5,0xaf,0xe9,0x7c,0x73,0x79,0x43,0x7,0x5f,0xcb,0x47,0xff,0x6f,0xbe,0xa9,0xdf,0x98,0xf5,0xdb,0xc8,0x4b,0xcc,0x79,0x26,0x1e,0xea,0x24,0x8a,0xd5,0xf9,0xac,0x56,0xad,0x5a,0xb5,0xbe,0x15,0xab,0xa6,0x0,0xd7,0xaa,0x55,0xab,0xd6,0x73,0xa8,0x59,0x51,0x62,0x16,0xc9,0x7e,0x86,0x17,0xd5,0xd4,0x60,0x15,0x72,0x53,0xf5,0xbd,0xe6,0x0,0x86,0x22,0xdd,0x4e,0xbc,0xd1,0x44,0xd2,0x2b,0x3b,0xf8,0xb6,0x90,0xa4,0x66,0xcc,0x41,0x18,0x73,0x38,0xc8,0x32,0x4d,0x98,0xe4,0xb1,0x24,0x1f,0x26,0xcf,0xba,0xf9,0x6b,0xd6,0x51,0xd2,0xab,0xb5,0x16,0x9e,0x1,0x25,0x91,0x1a,0x53,0x18,0x84,0x9b,0x9,0x15,0xec,0xb5,0x44,0x86,0xe1,0x73,0x2,0xe3,0xc,0x82,0x26,0xd,0x9a,0x50,0x59,0x2b,0x37,0x26,0xe0,0x64,0x57,0x61,0x1b,0x58,0xef,0x55,0x4a,0x26,0xc,0x39,0x6b,0x2d,0x7c,0xd3,0x31,0x50,0x48,0x8d,0x98,0xf3,0x8d,0xfa,0xd2,0x59,0xeb,0x60,0x9c,0x63,0xb9,0xf3,0xcc,0x4e,0x11,0xc0,0x53,0x80,0x2b,0x65,0x2c,0x30,0xcb,0x4e,0x92,0x7e,0x9d,0xf3,0xb,0x73,0x73,0x1,0xf7,0xb4,0x81,0xe2,0xeb,0x4b,0x21,0x14,0x4d,0xe,0x1,0x76,0x2,0xd4,0x59,0xf1,0x11,0xe4,0xfb,0xb7,0xce,0xc1,0x3b,0x8f,0xb6,0x3b,0xa3,0x40,0x10,0x96,0xff,0x1a,0x6b,0xf5,0xfd,0x54,0x16,0x5d,0x8,0x88,0xd3,0xc4,0xd7,0x36,0x3f,0x33,0x4a,0xd5,0x8c,0xca,0xa6,0xc,0x9c,0xbe,0x6c,0x9d,0xe3,0xf0,0x92,0xc4,0xf2,0x38,0x47,0xd,0x9b,0x2,0xa0,0xf2,0xfe,0x1a,0xe,0x13,0x71,0x68,0x1a,0xa,0xe6,0x10,0x56,0xa7,0x1,0x81,0x6d,0xe0,0x64,0xca,0x39,0x7c,0xc6,0x20,0xa5,0xc0,0x49,0xbf,0x2d,0x25,0xf3,0x72,0x83,0x9f,0x12,0x7,0xa1,0xa4,0x58,0x34,0x2c,0xa6,0x48,0x9c,0x26,0x16,0x9f,0x24,0x52,0x4a,0x62,0xb2,0xb2,0x2a,0xb,0x49,0x33,0x1d,0x8b,0xde,0xfb,0x28,0x2c,0x54,0x66,0xad,0x38,0xef,0xd5,0x6b,0x52,0xde,0x6b,0x94,0xa0,0x35,0x8a,0xdf,0x8d,0x19,0x85,0x84,0x59,0x6d,0xf0,0x6b,0xd5,0xaa,0xf5,0x7c,0x2a,0xb1,0x15,0x41,0x96,0x39,0x85,0xe7,0x9c,0x30,0xd,0xb,0x2f,0x5b,0x61,0x10,0x8b,0xcf,0xa8,0x30,0x86,0xa7,0x71,0x54,0x89,0x3f,0xd9,0x0,0x38,0xf6,0x31,0x25,0xc0,0xed,0x57,0x7f,0xf3,0xbd,0xd8,0xee,0xfa,0xd5,0x73,0xb7,0x6d,0x83,0x77,0xff,0xad,0xef,0xc3,0x3f,0xff,0x85,0x1f,0xc5,0xb7,0x3f,0xfa,0x0,0xc2,0x34,0x62,0x1c,0xf6,0x88,0x2c,0x5f,0x8d,0x71,0xe,0x3c,0x12,0x79,0x2d,0x0,0x8c,0xfb,0x3d,0x8c,0xb1,0x18,0x87,0x3d,0x72,0xca,0x9c,0x60,0x3f,0x90,0x87,0x1e,0x87,0x14,0x2d,0xe7,0x65,0xa3,0xc1,0x42,0x62,0x6d,0x0,0x18,0x4c,0x43,0xaf,0x73,0xa6,0xcc,0xb3,0xaf,0x7b,0xd5,0x2b,0xf0,0x8b,0x3f,0xf3,0xa3,0x47,0xe0,0x1f,0x0,0x7c,0xf4,0xe3,0x9f,0xc6,0xff,0xf5,0x9e,0xf,0x20,0x1,0xf8,0xc0,0xc7,0x3e,0x8b,0xa7,0x9e,0xb9,0x75,0xf4,0x33,0x37,0x6f,0x5c,0xc7,0xbb,0xdf,0xf9,0x7d,0x3a,0x6,0x3b,0x1e,0xdf,0x85,0x81,0x7f,0x78,0x4d,0x4d,0xbb,0xc1,0xa6,0xeb,0xf0,0xce,0x1f,0x78,0xf3,0xea,0x33,0x7a,0xef,0x7,0xfe,0x4,0x57,0x43,0xd0,0x31,0x53,0x36,0x70,0x64,0x4e,0x8a,0x21,0xcc,0x9b,0x2d,0x22,0xfb,0x5,0x16,0x9,0xbf,0x28,0x2,0x52,0xe,0xf1,0x27,0xb5,0xc3,0x10,0xe6,0x5e,0x2e,0xc0,0xbd,0xc2,0x1b,0xd7,0x2c,0xcc,0x4a,0xf2,0x12,0xe0,0x83,0x59,0xda,0xe6,0x1d,0x20,0x63,0xb,0xe9,0xef,0x1a,0xd9,0xee,0x8,0x5e,0xcb,0x27,0xe0,0xb6,0xc3,0x44,0xe0,0x55,0xe8,0xd,0xeb,0x1a,0x60,0x73,0x70,0x71,0xc7,0x97,0xa4,0x67,0xcf,0xeb,0x47,0x3b,0xd8,0xe3,0x5d,0x42,0x92,0x87,0x97,0x95,0x67,0x80,0x31,0x17,0x2f,0x4c,0xa9,0x7a,0x0,0xd6,0xaa,0x55,0xab,0x2,0x80,0xb5,0x6a,0xd5,0xaa,0xf5,0xe2,0x7,0xfe,0x94,0x15,0x95,0x8f,0x96,0x9d,0xc0,0xba,0xec,0xe3,0x70,0x21,0x5e,0x32,0x4,0xe7,0x30,0x85,0x7c,0xf4,0x3d,0x5,0x8b,0x58,0x5a,0x99,0xb,0x69,0xb0,0xb5,0x7e,0xf1,0x3a,0x91,0xe7,0x4a,0x18,0x87,0x48,0xbb,0x24,0xe8,0x82,0x98,0x85,0x8d,0x36,0x77,0x4e,0xc1,0x15,0x39,0x36,0x1,0x31,0xb2,0x68,0xa5,0x66,0x83,0xcc,0xc6,0x45,0x7e,0x4c,0x80,0x20,0x4f,0x16,0x6e,0xe,0x1c,0x11,0x40,0x8b,0x80,0xaa,0xc2,0x7,0xa8,0x0,0xcf,0x52,0x8c,0xea,0x2b,0x65,0xac,0x55,0x70,0xcd,0x70,0xe8,0xc6,0xdc,0x74,0x42,0xc3,0x4e,0x84,0xc5,0xb0,0x58,0xc2,0x9b,0x62,0x9,0xcf,0xc,0x33,0x2b,0xc7,0xc3,0x1c,0x38,0x31,0x83,0xa7,0x4b,0xe3,0xf3,0x74,0x10,0x36,0x31,0x27,0x24,0x1a,0x5,0x67,0xa5,0x91,0x51,0xf,0x42,0x6,0xae,0x44,0x4e,0x26,0x20,0x97,0xb2,0x2d,0xb5,0x6d,0x62,0xf0,0x92,0x9f,0xf,0xbd,0x7,0xe5,0xb3,0x80,0x26,0x37,0x8b,0x77,0x9e,0x86,0x90,0x80,0xbc,0xa5,0x44,0x4e,0xe6,0x19,0x24,0x2b,0xd9,0x1c,0xea,0xcb,0xc5,0x9e,0x88,0x99,0xc1,0x4d,0x23,0x0,0x2b,0x4b,0xa8,0x5,0x40,0xa3,0xcf,0x45,0xd4,0xa6,0x7d,0xf6,0xa4,0x2c,0x59,0xa9,0xf3,0x67,0x4b,0x3e,0x5f,0xd2,0xc4,0xce,0x40,0x2a,0xdf,0x1b,0x4b,0x8c,0x15,0x84,0x66,0x20,0x41,0xdf,0xb3,0x9c,0x66,0xcf,0x41,0x69,0x7e,0xf2,0x1c,0x20,0xe0,0x54,0x9e,0x4c,0xcc,0x51,0xe5,0x9d,0xe4,0xa2,0xe9,0x14,0x2a,0x45,0x4e,0xc8,0x31,0x20,0xa7,0x50,0x7,0x9d,0x5a,0xb5,0xee,0xc7,0x2,0xdf,0xba,0x82,0x25,0xcd,0x63,0x81,0x80,0x81,0x12,0x12,0xc1,0xac,0xb2,0x8c,0xd9,0xb,0x50,0x3c,0xe9,0xc4,0xeb,0xd3,0x33,0x33,0x2f,0x84,0x49,0xc1,0xba,0x10,0x26,0x7c,0xe5,0xa9,0x3b,0xf8,0x8d,0xdf,0x7e,0x3f,0x42,0x3c,0x1d,0xda,0xf3,0x6d,0x8f,0x3d,0x8a,0xff,0x8f,0xbd,0x37,0x6d,0x96,0xe4,0x3a,0xcf,0xc4,0x9e,0xf7,0x9c,0x93,0x99,0x75,0xef,0xed,0x6e,0x34,0x76,0x62,0x21,0xc1,0x9d,0x4,0x29,0x2e,0xa0,0x48,0x4a,0x5c,0x44,0x4a,0x43,0x69,0x28,0x6a,0xb4,0x58,0x33,0x1a,0x72,0x42,0x1e,0x79,0x34,0xd2,0xc8,0xe3,0x70,0x78,0x1c,0x72,0xf8,0xa3,0xbf,0xf8,0x1f,0xd8,0xe1,0xf,0x76,0xd8,0x9a,0xb0,0x3c,0xe,0x4b,0x23,0xcf,0x48,0x63,0x6d,0x23,0x93,0x22,0x41,0x41,0x24,0x1,0x82,0x20,0x41,0x80,0x20,0x16,0x12,0xe0,0x2,0x70,0x1,0xb1,0xa3,0xbb,0xef,0xbd,0x55,0x95,0x79,0x36,0x7f,0x78,0xcf,0x39,0x79,0x32,0xab,0x6e,0x37,0x40,0x40,0x34,0xfa,0xc6,0xfb,0x20,0x1a,0x7d,0x6f,0x55,0x2e,0x27,0x4f,0x65,0x57,0x55,0x3e,0xf9,0x2c,0xbf,0xfd,0xb1,0x8f,0xe0,0x9f,0xfd,0xca,0x7,0x71,0xcd,0x15,0x97,0xc2,0xa4,0xd2,0x27,0xe7,0x86,0x52,0xd2,0x61,0xed,0x80,0x10,0x3c,0x86,0xf5,0xa,0xde,0x3b,0x56,0x19,0x3b,0xf,0x6b,0xfb,0xf4,0x7e,0x43,0x49,0x11,0xa8,0x37,0x29,0xa5,0xba,0xd8,0x24,0x29,0xe5,0xa8,0xa8,0xe7,0x55,0x69,0xb5,0xbf,0xee,0x8a,0xd3,0xf8,0xf5,0x5f,0xf9,0x69,0x5c,0x72,0xea,0xe4,0xc6,0x36,0x1e,0xf9,0xde,0xf,0xf0,0x7f,0xfd,0xf9,0x2d,0x58,0xf,0x7c,0xe3,0xa4,0xb7,0x1e,0x9f,0xb9,0xfd,0xee,0xad,0x9f,0xed,0xef,0x7e,0xc7,0x8f,0xe1,0xf4,0xc9,0xbd,0x92,0xe1,0xc7,0x37,0x87,0x78,0x8e,0x94,0xd6,0x1c,0xeb,0x90,0x15,0x95,0x88,0xb8,0xe9,0x8d,0xaf,0xc0,0x55,0x57,0x5e,0xb6,0xb1,0x9d,0x73,0xfb,0x7,0xf8,0xe4,0x67,0xef,0xe4,0xcf,0x49,0x52,0x93,0x28,0x90,0x92,0x95,0xaa,0xa8,0x7c,0x46,0xc4,0x9c,0xdb,0x9b,0xde,0xef,0x79,0x1f,0xaa,0x7c,0xfe,0xe7,0x9b,0x38,0xf9,0x26,0x55,0xad,0x46,0xa3,0xea,0xc6,0x63,0xfe,0x5c,0xaf,0x49,0xad,0x89,0xd5,0x95,0x68,0x93,0xe0,0x3b,0x8a,0x8b,0x9b,0x5b,0x78,0xe3,0xb6,0x1c,0xc0,0xa3,0xb2,0x1,0xe3,0x16,0xc6,0x90,0xa6,0xa4,0xe2,0x11,0xe4,0x61,0x9c,0xc,0x20,0x16,0x8a,0x13,0x55,0x3a,0x21,0x8e,0xa0,0x13,0x4b,0xec,0xec,0x54,0x5b,0x84,0xae,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xfc,0xb9,0x2d,0x92,0xbf,0x38,0x59,0x31,0x5e,0xc0,0x45,0x1c,0x45,0x1,0x28,0x10,0x8,0x84,0x0,0x14,0x8,0x4,0x82,0xe3,0xc3,0x2,0xce,0xbe,0xc1,0xce,0x8,0x41,0xda,0x64,0xfc,0xb6,0x7d,0x43,0x9c,0x58,0x80,0xe7,0xe4,0xa1,0xaa,0x1b,0xe,0xab,0xfc,0x9a,0x4c,0xba,0x85,0xa2,0x88,0x43,0x45,0xfa,0x54,0x2a,0x8f,0x44,0xfa,0xa8,0x92,0x13,0x38,0xed,0xb8,0xcb,0xe4,0x1e,0x30,0x1f,0xc3,0x78,0xd1,0x51,0x37,0x1f,0xe6,0x8b,0x40,0x22,0x24,0x5,0x42,0xd8,0x42,0x6a,0x72,0xa6,0x5e,0xfd,0x5,0x3e,0x13,0x4f,0x7c,0xe1,0x92,0xac,0x50,0x59,0x71,0x96,0xd4,0x6c,0x75,0x79,0x45,0x56,0x43,0x96,0x86,0xc7,0x6a,0xff,0x6c,0xed,0xf5,0x23,0xa9,0x56,0x1d,0x6b,0xfe,0xc3,0x56,0x64,0x55,0x54,0x69,0xe5,0xc2,0xf,0xf5,0x3a,0x5b,0x2,0xc2,0xf3,0x9c,0xc6,0x58,0x48,0x56,0x67,0x6d,0x69,0x74,0x1c,0xe7,0x68,0xbc,0x22,0xa8,0x55,0x85,0xde,0xbb,0x42,0xa,0xc6,0xb2,0xad,0x50,0x96,0xd3,0x3a,0x67,0x24,0xf2,0xdc,0xe7,0x52,0x11,0xce,0x84,0xa4,0x62,0x87,0x9b,0x5e,0x42,0xc4,0xa2,0xbc,0xcb,0xca,0x8e,0x5a,0xad,0xa7,0x93,0x2a,0x51,0x97,0xa6,0xc7,0x91,0x8c,0xcd,0xcb,0xe7,0x62,0x8f,0xfa,0x82,0xae,0x64,0xf0,0x61,0x24,0x73,0xb3,0x6a,0x25,0x5b,0x77,0xf3,0x36,0xa,0x91,0x9a,0xc2,0xe8,0x47,0xa2,0x5a,0x8d,0x4d,0x91,0xe9,0x35,0x8e,0x21,0x11,0x77,0x75,0x29,0x8,0x62,0x3a,0x57,0x12,0xa1,0x1d,0xe2,0xb8,0x9f,0x42,0xea,0xa6,0x8b,0xce,0x74,0x1,0x5b,0x8f,0xd,0x72,0x11,0x25,0x10,0xbc,0x28,0x98,0xb6,0x92,0xc6,0xf1,0x7d,0x91,0x50,0x8,0x3d,0xaa,0x32,0xeb,0xca,0x8d,0x99,0x38,0xbe,0x2f,0x7a,0xc7,0x84,0xdc,0xd0,0xaf,0xcb,0xfb,0x49,0x2e,0xac,0x0,0x11,0x6e,0xbd,0xfb,0x41,0x7c,0xe2,0x6f,0xbe,0x0,0x6b,0x8f,0x26,0xee,0xdb,0xc6,0xe0,0x1d,0x6f,0x79,0x3,0x7e,0xf7,0xb7,0xfe,0x21,0x7e,0xe1,0xfd,0x6f,0x85,0xa,0x16,0xde,0x5a,0x38,0x3b,0xc0,0xe,0x3d,0x7f,0xd2,0x91,0x42,0xdb,0x2d,0x60,0x9a,0x16,0x43,0xbf,0x2a,0x1f,0xb7,0x43,0xbf,0xc2,0xd0,0xaf,0xd2,0x7b,0xb3,0x3d,0xe2,0xe3,0x99,0x8a,0xf5,0xd7,0xda,0x1,0xc3,0x7a,0x85,0xa6,0xe9,0x60,0x93,0x62,0xf0,0xd4,0x6e,0x8b,0xdf,0xfa,0xd8,0x47,0x70,0xc5,0xe5,0x9b,0x44,0xdc,0xd3,0xcf,0x9c,0xc5,0xef,0xfd,0xdb,0xbf,0xc2,0x10,0x38,0x6f,0x36,0x93,0x8c,0x5f,0xf8,0xea,0xb7,0xf0,0xf4,0x16,0x15,0xe0,0xa9,0x93,0x7b,0x78,0xdf,0x3b,0xde,0x50,0x3e,0x27,0x22,0x0,0xd3,0x74,0x0,0x50,0x54,0x7c,0x39,0x4f,0xb6,0x6d,0x5a,0xfc,0xf4,0x7b,0x7e,0x7c,0xfa,0xd9,0x9e,0x70,0xd7,0x3d,0xf,0xe0,0xdc,0xe1,0x9a,0x3f,0x5b,0xd3,0x8d,0x28,0x55,0x7d,0x6,0x8e,0x37,0xe0,0x62,0xc9,0x15,0xe,0xe9,0x33,0x84,0x3f,0xd7,0x52,0xd9,0x54,0x6e,0x4f,0x4e,0xaf,0x59,0x7e,0x6f,0xae,0x6d,0xbe,0x11,0x71,0xe3,0x33,0x7f,0x7e,0xa3,0x2d,0x56,0x9f,0x6f,0x53,0xa2,0x6b,0x4b,0xa1,0x48,0x66,0xc6,0xe6,0xcb,0x4e,0xc8,0xb1,0xf1,0x3b,0xc1,0xb8,0xcd,0xf3,0x5b,0x7b,0x63,0xa9,0x86,0x1a,0x4b,0x48,0xb6,0x91,0x78,0x54,0x2d,0x3f,0x89,0xb9,0x9c,0xab,0x12,0x71,0x3e,0xc2,0xe,0xdb,0x99,0xc0,0x6d,0x25,0x25,0xf3,0xef,0x7f,0x33,0xa,0xf2,0xb9,0x66,0xa,0xa,0x4,0x2,0x81,0x10,0x80,0x2,0x81,0x40,0x70,0xd1,0xf0,0x7f,0x53,0x23,0xc9,0x9c,0xf0,0x9b,0x2b,0x5,0xe2,0x16,0x2b,0xc8,0x51,0x1,0xd1,0x11,0x55,0x19,0x45,0x21,0x40,0xa8,0x90,0x49,0x59,0x91,0x31,0xc9,0x73,0xaa,0xd4,0x5d,0x45,0xf1,0x96,0xd4,0x69,0x99,0x30,0xca,0xf6,0xe1,0xac,0x94,0x2b,0xdf,0xdd,0xd3,0xfa,0x39,0xbb,0xad,0x90,0x69,0x15,0x59,0xa6,0x93,0x1d,0x36,0x8f,0xcb,0x39,0xb,0x55,0x95,0x99,0x8c,0xf9,0x43,0x0,0x94,0xe2,0xe2,0x6,0xa2,0xa2,0x58,0xa8,0x2f,0x1e,0xb3,0xdd,0xb8,0xbe,0x8,0xca,0xeb,0x8e,0x39,0x7c,0xba,0xe4,0x18,0x32,0x61,0x16,0x26,0x6a,0xc9,0x9a,0x38,0xcd,0x36,0xd4,0xdc,0xbe,0x9c,0xdb,0x85,0xe7,0xf6,0x9b,0xbc,0x8d,0x50,0x48,0xc4,0x0,0xa2,0x64,0xc9,0xf5,0x7e,0x7a,0x21,0x11,0xc7,0xed,0x11,0x46,0x4b,0x9c,0x9a,0xbc,0x16,0xe3,0xbe,0x6a,0x62,0x90,0x15,0x97,0x28,0x64,0x56,0xb6,0x4f,0x17,0x22,0xb2,0x22,0xd1,0x38,0x6c,0xdf,0x17,0x45,0x20,0xe5,0x0,0x77,0xa2,0x12,0xae,0x9f,0xf3,0xa0,0xf8,0xfa,0x2a,0x14,0x12,0x94,0x33,0x7,0x43,0xa,0x86,0xe7,0xe2,0x8e,0x90,0xc2,0xfb,0x31,0x2b,0xa2,0xc9,0xf3,0x9e,0xad,0x64,0xa3,0xaa,0x23,0x8e,0x17,0x85,0x31,0x24,0x3b,0x6e,0x2c,0xaa,0x92,0x18,0x2a,0x62,0x3b,0xcd,0x5d,0xf9,0xb9,0x6a,0x57,0x2e,0xb9,0x4f,0xd9,0x39,0xc,0x2a,0xaf,0x65,0xce,0x85,0x2a,0xa5,0x26,0xb4,0xa9,0x80,0xcd,0x17,0xa7,0xe5,0xf8,0xc2,0xd8,0xa6,0x6c,0xda,0x1d,0x79,0xc3,0x11,0x8,0x5e,0x8c,0xcf,0x2d,0xa5,0x26,0x9f,0x45,0x35,0x51,0xcf,0xcd,0xdd,0x5d,0xe1,0x3f,0x42,0xf0,0xac,0x2,0xcf,0x8d,0xb6,0xa0,0x42,0xde,0x64,0xb5,0x70,0x56,0xa,0xe6,0xcc,0xcf,0x5c,0x98,0xf4,0xe9,0x3b,0x1f,0xc4,0x9f,0x7f,0xf2,0x36,0xf4,0xbd,0x3d,0xef,0x78,0x4e,0xec,0xed,0xe0,0x23,0x1f,0x7a,0x3f,0xfe,0xbb,0x7f,0xf5,0x4f,0xf1,0xbe,0x1f,0x7f,0x33,0x82,0x1b,0x60,0x4c,0x5b,0x94,0x85,0xcb,0xc3,0x7d,0x80,0x80,0xb6,0xdb,0x41,0xc,0x1,0xc3,0x7a,0x55,0xde,0x33,0xbc,0xb3,0x1b,0x37,0xa1,0x6a,0xf2,0xca,0x98,0x86,0x1b,0xcc,0xbd,0x47,0xdb,0xed,0x40,0x69,0x7e,0xdf,0xdd,0xed,0x5a,0xfc,0x17,0xbf,0xfe,0x4b,0xb8,0xf6,0x65,0x57,0x6d,0xac,0x79,0xb8,0x5c,0xe3,0xf7,0xff,0xf8,0x13,0x38,0xbb,0xec,0x39,0x4f,0x35,0x29,0x26,0x4d,0xd3,0xc0,0x45,0xe0,0x96,0xcf,0xdf,0xb5,0xf5,0x73,0xfb,0xfd,0xef,0x7e,0x3b,0x4e,0xec,0x74,0x68,0xda,0xae,0xa8,0xbf,0x1,0x94,0xd8,0x83,0xac,0xa6,0x7e,0xed,0xf5,0x57,0xe1,0x86,0x97,0x5f,0xb3,0xb1,0xfe,0x72,0xb5,0xc6,0xa7,0x6e,0xfd,0x72,0xf9,0x6c,0xc8,0xef,0xbf,0x25,0xe,0x43,0x8d,0x51,0x1c,0x53,0xce,0x8c,0xca,0xf7,0x85,0x7c,0x3,0x27,0x22,0x96,0x46,0xe7,0x7c,0x3,0x9,0x75,0x26,0x71,0xbe,0xd1,0x56,0x91,0x7c,0x99,0x30,0xcd,0x37,0x62,0x6a,0x92,0xaf,0x7c,0xd7,0x29,0xae,0x5a,0xda,0x98,0xef,0xf1,0x6f,0xc2,0x36,0xcb,0x6e,0x9c,0x49,0xe5,0xa6,0x7a,0xbc,0x5a,0xb5,0xb7,0x6d,0xcb,0xe3,0xfa,0x5b,0xba,0x7d,0xb,0xe1,0x37,0xcf,0xe4,0x3b,0x92,0xbc,0xdb,0xf6,0x73,0x45,0xfa,0xd5,0x31,0x28,0x53,0xd9,0xdf,0x44,0x22,0x89,0xa3,0xac,0xc9,0x13,0xfe,0x50,0x4a,0x40,0x4,0x2,0x81,0x10,0x80,0x2,0x81,0x40,0x70,0x3c,0x30,0xb7,0xff,0xc6,0xb8,0x3d,0xf0,0xb9,0x26,0x7b,0xb6,0xad,0x5f,0x1c,0x32,0xb4,0xa9,0x26,0x2c,0x8f,0x25,0x25,0x59,0x6d,0xc5,0x9a,0xda,0x82,0xd4,0x48,0xa6,0x94,0xac,0xbb,0xf1,0xe2,0x40,0x55,0x17,0x78,0xa3,0xc5,0x16,0x13,0x75,0x1a,0x25,0x5,0x5b,0xb6,0xce,0xf2,0x77,0xdf,0x80,0x3a,0xdf,0xd,0x55,0xe3,0x6b,0xce,0x25,0xaa,0x49,0xa0,0x90,0x72,0x1,0xb3,0x2,0x30,0x93,0x56,0xbe,0x14,0x8f,0x4,0x98,0xa6,0x29,0x8a,0xc0,0x50,0x29,0xf1,0x46,0x2b,0x17,0x8d,0x4a,0xbf,0x10,0x26,0x56,0x56,0x9a,0xcd,0x67,0x51,0x9d,0xa5,0x67,0x55,0x35,0xf,0x85,0x1c,0xcd,0x17,0x10,0xd5,0x45,0x6f,0xce,0xc0,0x2a,0xd9,0x78,0x5a,0x8f,0xc7,0x52,0xac,0xab,0xd9,0x2a,0xcb,0xf3,0x5b,0xf2,0x96,0xd2,0x1c,0x64,0x3b,0x6b,0x26,0xfb,0x72,0xd6,0x9e,0x2a,0x39,0x84,0x94,0x32,0x16,0x13,0xf1,0x95,0x9a,0x29,0x73,0x2e,0x5f,0xac,0x82,0xf6,0x63,0xc9,0x28,0x64,0x82,0xb2,0x6d,0x17,0xe5,0xf8,0x6a,0x85,0x27,0x29,0x5d,0x94,0xa0,0xac,0x9a,0x1c,0xe7,0x31,0xdb,0x97,0xc7,0x9c,0xc8,0x91,0x90,0x65,0xfb,0x2d,0x2a,0x65,0xa4,0x2a,0x17,0xfe,0x79,0x9d,0x58,0x4a,0x69,0x46,0x62,0xb0,0xb4,0x83,0x56,0x41,0xf3,0x99,0x14,0x8d,0x35,0x21,0x10,0xc2,0xd8,0xfe,0x8,0x9a,0x9c,0xdf,0xd9,0xe,0x9e,0x2f,0x2a,0x73,0xe0,0x7c,0x6e,0x63,0xa6,0xe4,0xff,0x9d,0x36,0x9,0x63,0x9c,0x27,0x22,0xd8,0xf5,0xa1,0xbc,0xe1,0x8,0x4,0x2f,0x2,0x8a,0xea,0x36,0xdf,0xe0,0x49,0xff,0x26,0x73,0x1c,0x44,0x5d,0xe2,0x43,0xc8,0xed,0xb9,0x7c,0xe3,0x82,0x63,0x1c,0x5c,0xc9,0xd0,0x33,0x4d,0x3b,0xbe,0x37,0x16,0xd5,0xb3,0x2f,0xf9,0x7b,0xb7,0x7e,0xe5,0x1b,0xf8,0xbd,0x3f,0xfa,0x2b,0x3c,0xfe,0xd4,0xb3,0x17,0x1c,0xd7,0x35,0x2f,0xbb,0x1a,0xbf,0xf9,0xb1,0x5f,0xc2,0xbf,0xfc,0xa7,0xbf,0x82,0x2b,0xaf,0xb8,0x1c,0x8b,0xdd,0x13,0x68,0xbb,0x5,0x4e,0x5e,0x72,0x19,0x93,0x8a,0x76,0x80,0x73,0x36,0xa9,0x1,0xd7,0x18,0xfa,0x75,0x19,0xfb,0xe6,0x67,0x2e,0x4a,0xc1,0x10,0x88,0xb0,0xd8,0x3d,0x91,0x6e,0xa4,0x0,0xad,0x51,0xf8,0xad,0x7f,0xf4,0x21,0xbc,0xf2,0x15,0xd7,0x6e,0xac,0xd7,0xf7,0x3,0xfe,0xf0,0xcf,0x3e,0x85,0xef,0x3c,0xf6,0x4c,0x22,0xc,0x35,0x42,0xba,0x19,0xe5,0x9d,0x83,0xf7,0x1e,0xb7,0xdd,0xfd,0x20,0x9e,0x7a,0x7a,0x53,0x5,0x78,0xe9,0xe9,0x53,0x78,0xdf,0x4d,0x6f,0x4,0x0,0x34,0xdd,0x22,0xbd,0xf7,0xf1,0xfb,0x70,0x26,0xf1,0x82,0x77,0xf8,0xd0,0xfb,0x6e,0x2a,0x65,0x5f,0x35,0xee,0xfe,0xea,0xfd,0x78,0xfc,0xd9,0x83,0x14,0x8d,0xa1,0x47,0x95,0xb6,0xd2,0x85,0xcc,0x1b,0x6f,0xf0,0x51,0xb9,0xc1,0x53,0xe7,0xf3,0x8e,0x2a,0x6c,0xfe,0xec,0xd4,0xca,0x8c,0xc4,0x5e,0x8a,0x11,0xc9,0x4,0x70,0x2c,0x44,0x62,0x26,0xe,0x31,0xb9,0xd1,0x34,0xb2,0x6d,0x63,0x21,0x48,0x9c,0xb5,0x47,0xcf,0x7f,0x99,0x7e,0xff,0x89,0x13,0x62,0x90,0x66,0xcb,0x6f,0x5a,0x76,0xa7,0x54,0xe2,0x5c,0x88,0xb7,0x75,0x8f,0x71,0x93,0x7e,0xdc,0xaa,0xe0,0x8b,0xd3,0xe1,0xd0,0xc6,0xae,0xe3,0x84,0x38,0xdc,0x88,0x1c,0x99,0xc8,0xfe,0x8,0x47,0x18,0x89,0xb7,0x10,0x97,0xf4,0xfc,0xda,0x46,0x4,0x2,0x81,0x40,0x8,0x40,0x81,0x40,0x20,0x78,0x89,0x92,0x7f,0x13,0x9b,0xe6,0xd4,0xe,0xba,0x49,0xf4,0x85,0xea,0xcb,0xf1,0xa8,0xa4,0x2a,0x5f,0xca,0xd3,0xf3,0x93,0x3b,0xc6,0x34,0x25,0x51,0xea,0x86,0xdf,0x9a,0x40,0x1c,0x55,0x73,0xa1,0x52,0xd3,0x4d,0x9,0x94,0xf9,0xb2,0x85,0x8,0x8c,0xe3,0x97,0xfa,0x39,0x9,0x97,0x2f,0xac,0xb2,0x82,0x2d,0x5b,0x59,0xeb,0xd0,0x71,0xbe,0xd8,0xc0,0xa8,0x14,0xab,0x2e,0xc4,0x72,0x19,0x48,0x29,0x41,0xa9,0x32,0x13,0x9d,0xb5,0x93,0x1c,0xba,0x4c,0x1c,0x4e,0x2c,0x48,0x29,0xfb,0xb0,0x94,0x72,0x54,0x8a,0xc4,0x5c,0x42,0x51,0x32,0xfd,0x8,0x13,0x8b,0xda,0x78,0x9c,0xd3,0xf9,0xad,0x89,0x2d,0x64,0x52,0x34,0xcf,0x9f,0x1f,0xd5,0x66,0xd9,0xf2,0x4a,0xd9,0xca,0x9c,0xc9,0x3a,0xad,0xb,0xf9,0x57,0xbf,0x6,0x8a,0xd4,0x8c,0xd0,0x1d,0x83,0xda,0x73,0xeb,0x64,0x8,0x1e,0xa4,0x75,0xc9,0xa1,0x9a,0x12,0xc8,0x54,0x15,0x6f,0xf0,0xc5,0x19,0xdb,0xd4,0x22,0x2f,0x5f,0x5b,0x9b,0x8b,0xb2,0x70,0x7a,0x91,0x12,0x32,0xe1,0x9a,0x8e,0xa9,0xd8,0x72,0x63,0x98,0x59,0xc6,0x28,0x29,0x74,0x86,0xd4,0x1e,0xe9,0x8a,0x35,0x3d,0x86,0xb8,0x61,0xf7,0xce,0x73,0xab,0x74,0x65,0x15,0x4e,0x63,0x8c,0xd5,0xb9,0x5c,0x24,0x13,0xb3,0xac,0x28,0x3e,0x4f,0xe2,0xb4,0x11,0xbb,0x6a,0xaa,0xcc,0x19,0x86,0x1b,0xaa,0x91,0x4a,0x80,0x12,0xbd,0x83,0x6e,0x3a,0xc8,0x95,0x94,0x40,0xf0,0x22,0x60,0x94,0x34,0x4f,0xe2,0x2,0x98,0x40,0xf2,0xe5,0x7d,0x3,0x40,0x22,0xbf,0xd4,0x24,0x37,0x50,0xa5,0xbc,0x3e,0x6d,0x9a,0xd1,0xae,0x4b,0xc4,0xed,0xf2,0x15,0x41,0x64,0x6d,0x8f,0x18,0x23,0xbe,0xf5,0xe8,0xd3,0xf8,0xd7,0x7f,0x72,0xb,0x6e,0xbf,0xf3,0x3e,0xc,0xf6,0xfc,0x6a,0xc0,0xa6,0x31,0xf8,0x89,0x77,0xbc,0x5,0xbf,0xfb,0xcf,0x7f,0x15,0xaf,0xbf,0xe1,0x9a,0xd4,0xa6,0xeb,0xd0,0x2e,0x76,0xb0,0xd8,0x3d,0x81,0xbd,0x93,0xa7,0xa1,0xb5,0xc1,0x89,0x53,0x97,0x72,0xf4,0x81,0x69,0x38,0xa3,0x74,0xe3,0x33,0x37,0x42,0xe9,0xa6,0x90,0x65,0x9c,0xc5,0xa7,0x60,0x14,0xe1,0x37,0x7f,0xed,0xc3,0x78,0xd3,0x1b,0x5f,0xbb,0xb1,0x8e,0xf7,0x1e,0x7f,0xfa,0x89,0xcf,0xe2,0xfe,0x6f,0xfd,0xa0,0xe4,0xd5,0xda,0x61,0x28,0xf9,0xa5,0x39,0xa6,0x22,0x90,0xc1,0x6d,0x77,0xde,0xbb,0xf5,0xb3,0xfe,0x7d,0xef,0x7e,0x2b,0x4e,0xec,0xed,0x15,0x35,0xbd,0x31,0x6,0x4d,0xdb,0x96,0xe7,0x5f,0x75,0xfd,0xd5,0x78,0xf5,0xd,0xd7,0x6d,0x12,0x8f,0x83,0xc5,0xa7,0x6e,0xbd,0xbb,0x7c,0x5f,0xe0,0xd7,0x82,0x3f,0x47,0x86,0x7e,0x5,0x3b,0xf4,0x93,0xf8,0x8b,0xfa,0x6,0x61,0x56,0xa0,0xe7,0x79,0xc8,0x2a,0xfd,0x9a,0x1c,0x2d,0x25,0x4b,0x11,0x93,0x6c,0xc0,0x18,0x92,0x12,0xaf,0x7c,0x3e,0xc4,0x49,0xfc,0x47,0x61,0xd4,0x62,0xc5,0x65,0xc5,0x39,0x2d,0x97,0x83,0x45,0xb6,0x91,0xb1,0xdb,0x48,0x32,0x9a,0xa9,0xf8,0xe2,0xc6,0x1a,0xe7,0xab,0xf8,0xa8,0xfb,0x48,0x30,0x76,0x7c,0xcd,0x88,0xbb,0xb8,0x9d,0x91,0xcb,0x82,0xbe,0xba,0xe5,0x63,0xae,0x29,0xdc,0xda,0x20,0x4c,0x47,0x52,0x7c,0x93,0x7f,0x57,0x1b,0xc7,0x11,0xc5,0x9,0x2c,0x10,0x8,0x2e,0x1a,0x68,0x0,0xff,0xbd,0x4c,0x83,0x40,0x20,0x10,0x6c,0x87,0x52,0x6,0x57,0x5c,0x7b,0x3,0x4c,0xdb,0xb1,0x45,0xb2,0x52,0x6a,0xd5,0x77,0xe5,0x27,0x3f,0x57,0xc4,0x5a,0xbe,0xb8,0xaa,0x73,0x78,0xe6,0x64,0x5d,0x2e,0x87,0xc8,0x17,0x13,0x25,0xaf,0x6f,0xd2,0x24,0x3c,0x7e,0x91,0x65,0x5,0xd9,0x68,0x35,0xe,0x31,0x60,0x7e,0xeb,0x3b,0x86,0x50,0x7b,0x67,0xcb,0x17,0xf0,0xac,0x5e,0xcc,0xd9,0x6f,0xc5,0x26,0xb6,0x25,0x97,0x90,0x2a,0xdb,0x6e,0x88,0x63,0xb9,0x4,0x61,0xaa,0xe,0x1c,0xed,0x9f,0x11,0x11,0xa1,0x8c,0x2d,0x26,0xcb,0x6a,0xad,0x28,0x1b,0xad,0xa5,0x4,0x64,0xf2,0xa,0x99,0xd8,0xf3,0x25,0x3f,0x2e,0x5f,0xa4,0xb0,0x25,0x38,0x8e,0xb9,0x54,0x59,0x51,0x96,0xbe,0xe4,0x67,0x5b,0x6c,0xb9,0xe8,0x9,0x71,0xf2,0x65,0xbc,0x14,0xa4,0x24,0xb2,0x8f,0x49,0x45,0xbe,0x98,0xf2,0xce,0x4d,0x48,0xd2,0x7c,0x31,0x55,0x88,0xbb,0xac,0x78,0xcc,0x4a,0xcb,0x50,0x85,0x8d,0x87,0x50,0xed,0xab,0x52,0x67,0xf8,0xf1,0xb5,0xcb,0x65,0x2b,0xa5,0x30,0xa3,0x3a,0x2f,0x8a,0x3a,0x2e,0x65,0xe6,0xe5,0x9f,0x89,0x50,0xce,0x83,0x92,0xcb,0x14,0x62,0x39,0xce,0x7c,0xe1,0x12,0xaa,0xd6,0xce,0xdc,0x20,0x9c,0x55,0x9d,0x3c,0xe7,0xae,0x22,0xa5,0x93,0x8a,0x24,0x8c,0xe7,0xa4,0xf7,0xac,0x10,0x2c,0xca,0xbf,0x34,0x81,0x7c,0x5e,0x8c,0xf6,0xe3,0xc9,0xf9,0x8d,0x71,0x1b,0x45,0xb5,0x59,0x5f,0x40,0x65,0xdb,0x72,0xa8,0xaf,0xbe,0x46,0xf2,0x70,0x4e,0xdc,0x66,0x6b,0xb6,0xf7,0xe,0xfd,0x7a,0x8d,0xfd,0x33,0xcf,0x20,0x38,0x8b,0xe0,0xd6,0xf2,0xc6,0x23,0x10,0xbc,0x40,0x74,0x3b,0x27,0x71,0xe5,0xcb,0x5e,0x8e,0xa6,0x5b,0x4c,0x9,0x9b,0x42,0x90,0x84,0x92,0xd1,0xa9,0x72,0xb6,0x27,0x8d,0x59,0xab,0xf9,0xfd,0x21,0xb7,0xae,0x13,0x11,0x97,0x6c,0xe4,0x9b,0x27,0xa4,0x11,0xa2,0x4f,0x2d,0xf4,0xfc,0xfc,0xba,0x1f,0x70,0xcf,0xd7,0x1f,0xc6,0xf7,0x1f,0x7d,0x1c,0x2f,0xbb,0xe2,0x34,0x4e,0x9d,0x3c,0x71,0xde,0x31,0x9e,0x3c,0xb1,0x87,0x37,0xbd,0xee,0x95,0x78,0xf8,0xbb,0x8f,0x62,0x1d,0x74,0x8a,0x3a,0xf0,0x30,0x4d,0x93,0xb8,0x16,0x4a,0xfb,0x6d,0xf0,0xf2,0xab,0x2f,0xc3,0x5b,0x6e,0x7c,0xed,0x6,0x39,0x73,0xd7,0x7d,0xf,0xe1,0xcc,0x21,0x93,0x92,0xfd,0xea,0x10,0x31,0x46,0x7c,0xf4,0x23,0xef,0xc7,0x7b,0xde,0xf5,0xb6,0xd4,0x2c,0x3f,0x22,0x84,0x80,0x9b,0x3f,0xf7,0x65,0xdc,0xfc,0x85,0x7b,0xcb,0xe7,0x74,0x21,0xd3,0xd2,0xfb,0x26,0x17,0x2f,0xf1,0x67,0xc4,0x63,0x4f,0x9d,0xc3,0xdb,0x6f,0xbc,0x1,0xbb,0x3b,0xd3,0x68,0x82,0xdd,0x9d,0x5,0xce,0x9c,0x3d,0x8b,0xef,0x3d,0x71,0xa6,0xbc,0x37,0x76,0x8b,0xdd,0xa2,0xbc,0xfe,0x7,0x1f,0xb8,0x9,0xaf,0x7c,0xf9,0xa6,0xf2,0xf0,0x81,0xaf,0x7f,0xb,0x37,0x7f,0xfe,0x9e,0x92,0x7b,0xab,0x94,0x82,0xb5,0xc3,0xe4,0xc6,0x89,0x52,0xba,0x2a,0x4,0x19,0xdb,0xd5,0xa9,0x7c,0x27,0xd1,0x93,0xef,0x1a,0xe3,0xfb,0xeb,0x78,0x63,0x88,0x67,0x26,0x59,0x8b,0xd3,0x6b,0x5e,0xab,0xc1,0xf9,0x9e,0x8c,0x9a,0xde,0xdc,0xd9,0xaa,0x80,0xab,0x1f,0xa1,0xc9,0xe9,0x53,0x48,0x3a,0xda,0xda,0x89,0x1,0x3a,0x2a,0x4f,0xaf,0xbe,0x8f,0xb4,0xf5,0xf9,0xb9,0xf9,0x97,0xb6,0x14,0x8b,0xd0,0x16,0x72,0x2e,0x1e,0xf1,0x18,0xe1,0xe8,0x9b,0x4a,0x74,0x81,0xdf,0xcf,0x8f,0x5a,0x35,0xdf,0xaf,0x97,0x38,0xfb,0xd4,0xf,0xe4,0x8d,0x47,0x20,0x10,0xbc,0xe4,0x61,0x64,0xa,0x4,0x2,0x81,0xe0,0x68,0x84,0xe0,0xf0,0xc8,0x37,0xee,0xc5,0xf5,0xaf,0xba,0x11,0x4d,0xb2,0xb4,0x86,0xd2,0x1e,0x4b,0xb3,0x2f,0xad,0xf9,0x3b,0xe4,0x94,0x78,0xc3,0xac,0x92,0x63,0xde,0x22,0x4c,0x44,0x93,0x2c,0xa0,0xda,0xaa,0x12,0xd3,0x76,0xea,0x65,0x26,0xe4,0xde,0xfc,0xeb,0x6b,0x5d,0xd6,0x90,0xec,0xab,0xb1,0x52,0x8a,0xd5,0x2a,0xae,0x32,0x9e,0xd9,0x38,0xf3,0x17,0x67,0xaa,0x15,0x6f,0x25,0x4f,0x48,0x4d,0x2f,0x26,0x93,0x7a,0x4c,0x29,0xb6,0x50,0xa5,0xa0,0xc1,0x49,0xd6,0x14,0xa5,0x39,0x19,0xad,0xcd,0xa3,0x5a,0x8d,0x94,0x2a,0x99,0x7c,0x99,0xa4,0xcc,0x17,0x98,0xd3,0xdb,0xfe,0xe3,0x8c,0x10,0x69,0xc4,0xe0,0xc6,0xf2,0x8,0x52,0x88,0xd1,0x27,0xdb,0x2c,0xc6,0x62,0x8a,0x6c,0x21,0xce,0x17,0x1d,0x93,0x26,0x5e,0x2a,0x17,0x50,0x75,0xa6,0xe1,0x58,0x4c,0x12,0xca,0x18,0x8a,0x8a,0x2,0xa1,0x28,0x30,0x72,0x3,0x73,0x21,0x6c,0x93,0x85,0x2a,0xcf,0x67,0xbd,0xaf,0x6c,0x91,0xce,0x64,0x21,0xa5,0xd6,0xc7,0xa9,0x12,0xb2,0x52,0x2e,0x56,0x17,0xe1,0xe5,0xf7,0x38,0x55,0xd7,0x95,0xd7,0x26,0xf8,0x72,0x21,0x47,0x55,0x66,0x21,0xcd,0x14,0x9f,0xf5,0xf1,0x45,0x6c,0x66,0x3e,0xc5,0xd9,0x15,0x5d,0x39,0x7f,0xf2,0xf6,0x94,0x9e,0x58,0x87,0xcb,0xd9,0x19,0x51,0x7,0x29,0x55,0x3e,0x77,0x35,0xfb,0x37,0x90,0x96,0x2b,0x84,0x24,0xdb,0xa6,0xbd,0xb3,0xe8,0xfb,0x1e,0x4f,0x3d,0xfe,0x28,0xa0,0xc,0x48,0x7c,0x9,0x2,0xc1,0x8b,0x2,0x95,0x5b,0xbd,0xe3,0xb4,0x9,0xd8,0x25,0x75,0x9e,0x4a,0x19,0xb2,0x2a,0xdf,0x30,0x48,0xff,0xe6,0xb5,0x36,0x25,0xe7,0x8f,0x6f,0x94,0xd8,0x62,0x55,0xb5,0x43,0x9f,0xb2,0xee,0x74,0x29,0x36,0x82,0x52,0xb0,0x43,0xf,0xd3,0xb4,0x68,0x92,0x3a,0xed,0x9e,0x7,0x1f,0xc1,0xd7,0xbf,0xfd,0x3d,0xfc,0xfc,0xfb,0x6f,0xc2,0x7b,0xdf,0xf5,0x16,0x9c,0xd8,0xdb,0x3b,0x72,0x9c,0x97,0x9e,0x3e,0x85,0xdf,0xf9,0xf5,0x5f,0xc4,0xef,0xff,0xfb,0xbf,0xc6,0xc3,0x3f,0x78,0x1a,0x66,0xf7,0x4,0xe7,0x98,0x36,0x2a,0x15,0x6b,0xf0,0xd,0x28,0x52,0xdb,0xdf,0x1c,0x48,0x29,0xc,0xeb,0x15,0x4c,0xdb,0xa2,0xb1,0x2d,0x7e,0xfa,0xc7,0x5f,0x87,0x9f,0xfa,0xc9,0xb7,0x6f,0x90,0x7f,0x31,0x46,0xdc,0xfe,0xe5,0xfb,0xf0,0x89,0xdb,0xef,0x3,0x29,0x85,0xa6,0xed,0xd0,0xaf,0x96,0xa5,0x4d,0x3d,0xcf,0x4b,0xd3,0x76,0x9c,0x4b,0xe8,0xf9,0xb8,0xbf,0x78,0xcf,0x43,0xf8,0xf9,0xf,0xbe,0x6b,0xda,0xac,0x4b,0x84,0xf7,0xbe,0xe3,0x4d,0xf8,0xd2,0x7d,0xf,0xc3,0x25,0xc5,0x75,0xf0,0xe,0x5a,0x1b,0x9c,0xde,0xeb,0xf0,0xd6,0x37,0xbd,0x6e,0x63,0x9c,0xd6,0x5a,0x7c,0xf2,0xb3,0x5f,0x4c,0xad,0xbb,0xfc,0x3e,0x6c,0x87,0xa1,0xbc,0x44,0x5c,0xee,0xa4,0x4a,0x79,0x54,0x26,0x43,0x6b,0x52,0x2a,0xdb,0x7f,0x55,0x6a,0x8b,0xaf,0xb,0x43,0x7c,0x70,0xfc,0x6e,0x5e,0xc9,0xe6,0x8a,0x83,0x81,0xa8,0xba,0xa1,0x15,0xeb,0x2f,0x20,0x93,0xe8,0x8d,0xf1,0x7b,0xc1,0xd4,0xee,0x3b,0x59,0xa7,0xfe,0xb6,0x50,0xe5,0xc0,0x4e,0x34,0x7e,0x5b,0x2c,0xb8,0x33,0xc1,0xfe,0x84,0xb2,0xdb,0x58,0xb8,0x7c,0x15,0xa1,0x4d,0xc6,0x71,0x2b,0x49,0x77,0xbe,0x8a,0xde,0xf3,0x49,0xf3,0x2e,0xbc,0x6c,0x8c,0xcf,0xad,0x9b,0x4a,0x32,0x0,0x5,0x2,0x81,0x10,0x80,0x2,0x81,0x40,0x70,0x4c,0x70,0xe6,0xf1,0xef,0xe2,0xf0,0xec,0xb3,0x38,0x7d,0xe5,0xb5,0x68,0x9a,0x76,0xcc,0xe9,0xa9,0xbf,0x99,0x12,0xcd,0x2c,0x25,0xd3,0x3b,0xd8,0x85,0x3c,0x29,0xd6,0x5b,0x3f,0x69,0x3f,0x1d,0xb3,0xfe,0xd8,0x52,0xab,0xb4,0x2e,0xe4,0x4e,0x79,0x3e,0x97,0x65,0xd4,0x64,0x4e,0x9c,0xe6,0xdd,0x15,0x8b,0x6b,0x75,0xb1,0x94,0x49,0x43,0x26,0x71,0xfc,0xc8,0xcb,0x94,0x50,0x78,0x9a,0x12,0x91,0x95,0xbd,0x34,0xab,0xcc,0x88,0x14,0x54,0x69,0xec,0xcd,0xa,0x84,0x71,0xfd,0xfc,0x5,0x38,0x13,0x62,0x31,0x78,0x28,0xdd,0x24,0x32,0xae,0xba,0xe4,0x89,0x1,0x4a,0xb7,0x88,0xc1,0x55,0x3c,0x67,0x48,0xa5,0x11,0x23,0x59,0xc9,0x24,0xa2,0x2e,0x76,0xea,0xf1,0x98,0x75,0x52,0xe4,0x25,0x82,0x2c,0x93,0xaf,0xa4,0xd3,0x9c,0xea,0xca,0x12,0x8b,0x9,0x9,0x9a,0xbf,0xc9,0xe7,0xbc,0x3e,0x24,0xa2,0x91,0xe7,0xcd,0x71,0x9e,0x55,0x1a,0xaf,0x52,0xba,0x28,0xff,0xf2,0xe3,0xac,0xc6,0x18,0x2d,0xd5,0xa8,0xac,0xb7,0x99,0x50,0xc,0x31,0x95,0x87,0xd0,0xa8,0xc2,0xe3,0x8b,0x6d,0x3d,0xcd,0x5e,0xca,0x17,0x64,0x39,0xdb,0x31,0x35,0x39,0x8e,0x17,0x99,0x54,0xd9,0xf4,0xb2,0xd5,0xda,0x43,0xd1,0x98,0x41,0x39,0xaa,0x57,0xf4,0xb8,0x6e,0x1c,0x2f,0xb0,0xb2,0xf5,0x39,0x93,0xc8,0x39,0x3,0x90,0xcf,0x43,0xaa,0xce,0x19,0x37,0x66,0x41,0x22,0x80,0xd3,0x41,0xaa,0xb,0xc3,0x18,0x40,0xca,0x20,0x78,0x3b,0x69,0x70,0xe6,0xf3,0x43,0x25,0x15,0xe9,0x78,0xa1,0xc9,0x39,0x5a,0xb6,0xcc,0x71,0x26,0x11,0xa,0xe5,0x98,0x6c,0x89,0x21,0x44,0xf4,0xab,0x25,0xac,0x8f,0x88,0x64,0xc0,0xfc,0xad,0xd8,0x7f,0x5,0x82,0x17,0x5,0x71,0xb3,0xb9,0xbd,0x44,0x1c,0xc4,0x98,0xde,0x3,0x98,0xf8,0x52,0xa9,0xf5,0x1b,0x31,0x96,0x76,0x60,0x6d,0xc,0xbc,0xe3,0x72,0x22,0xd3,0x34,0x70,0xce,0x95,0xe2,0xa2,0x72,0x23,0x4,0x11,0xd1,0x3b,0xb4,0xdd,0x2,0xde,0xb9,0x52,0x12,0xa5,0x94,0xc6,0x7a,0x70,0xf8,0xf3,0x5b,0xee,0xc4,0xed,0x77,0x7f,0xd,0x1f,0xfd,0x85,0x9f,0xc2,0xeb,0x5e,0xf3,0xca,0xad,0x99,0x78,0x0,0x70,0xc9,0xc9,0x13,0xf8,0xd5,0xbf,0xff,0x5e,0xfc,0xaf,0xff,0xf7,0x27,0x30,0x78,0x60,0xcc,0xa1,0xe3,0x92,0x8b,0x46,0x77,0xd0,0xa6,0x3d,0x82,0xc0,0x21,0x28,0xc3,0xc7,0xf4,0x9e,0xb7,0xbe,0x16,0x1f,0xf9,0xd0,0xfb,0xb6,0x36,0xef,0x7e,0xed,0x1b,0x8f,0xe0,0x4f,0x6f,0xfe,0x52,0x6a,0x2f,0x8f,0x58,0x2f,0xf,0xb0,0xb3,0x77,0xa,0xce,0xe,0x8,0xde,0xc3,0x98,0x6,0xd6,0xf6,0x70,0xd6,0xc2,0x7,0xc7,0x59,0x89,0x4,0xdc,0xfe,0x95,0x87,0xf0,0x93,0x37,0xdd,0x88,0x4b,0x2f,0x39,0x39,0xd9,0xde,0x35,0x57,0x5f,0x89,0x1f,0x7b,0xed,0x75,0xb8,0xe7,0x9b,0x8f,0x1,0x31,0xc2,0xa7,0xcf,0x8b,0xf,0xbe,0xfb,0xc7,0xb0,0xb3,0xe8,0x36,0xf6,0xff,0xf0,0x77,0x7f,0x80,0x6f,0x7c,0xef,0xc9,0xf2,0x59,0x99,0x95,0xfe,0x2a,0x11,0xae,0x79,0x5e,0xcb,0x67,0x49,0xba,0xc9,0xe5,0x83,0x2b,0x9f,0xad,0xf9,0xb3,0xc6,0x97,0x9b,0x66,0xe3,0xf7,0xb,0xaa,0x32,0xfc,0xf8,0xfd,0xde,0x23,0xdf,0xc0,0x8a,0x71,0xfb,0x77,0x92,0xca,0x33,0x80,0xd1,0xb2,0x5b,0x2d,0x97,0x3e,0x53,0x28,0x37,0xb7,0x97,0x1b,0x5a,0x23,0x31,0xc6,0x9b,0x8e,0x1b,0x1c,0xdd,0x79,0x39,0x3b,0xda,0xf2,0x35,0x29,0x1e,0x41,0xee,0x6d,0x6c,0xe8,0xa8,0xdc,0xbe,0xbf,0x1b,0xd4,0x25,0x64,0x35,0x9,0x3c,0xb9,0x69,0x86,0xed,0x19,0x95,0x2,0x81,0x40,0x20,0x4,0xa0,0x40,0x20,0x10,0x5c,0xa4,0xb0,0xeb,0x3,0x3c,0xf9,0xdd,0x7,0x1,0x10,0x4c,0x77,0x12,0x7a,0xb1,0x7,0x3f,0xf4,0x20,0x2,0x7c,0xbf,0xf,0xd5,0x9e,0xe4,0x8b,0x95,0xa6,0x83,0x5b,0xef,0x43,0x99,0xe,0xde,0xae,0x4a,0x13,0x2c,0x48,0x41,0xb7,0xb,0x44,0xef,0x11,0x5c,0x9f,0x88,0xb0,0x6,0xc1,0xf5,0xd0,0xed,0x2e,0xbc,0x1b,0xa0,0x74,0x53,0x88,0x14,0x52,0x26,0x39,0x57,0x14,0x10,0x3c,0x48,0x1b,0x56,0xba,0xd9,0x15,0x62,0x24,0x0,0xbc,0x7e,0x4c,0x4,0x4d,0xf0,0xe,0xca,0xb4,0x40,0xf4,0x8,0x76,0xd,0xdd,0x9d,0x0,0x62,0x80,0xb7,0x3d,0x10,0x3,0x54,0xb3,0x60,0xf5,0x47,0x7f,0xc8,0xcf,0xd5,0x19,0x83,0xc1,0x81,0x54,0x83,0xe0,0xd6,0x20,0xd3,0x81,0xf2,0xc5,0x43,0x56,0xd2,0xa9,0x26,0x7d,0xe1,0x65,0x22,0x88,0x88,0xe0,0x87,0x25,0x94,0x59,0x20,0x6,0x5b,0xf2,0x3,0x33,0x31,0xc8,0x56,0x2a,0x5b,0x94,0x8c,0xa4,0x5b,0x20,0x3a,0x20,0x2,0xba,0xdb,0x45,0x70,0x16,0xa4,0x88,0xe7,0xa9,0xdd,0x4b,0xa,0x94,0x44,0x76,0x5,0xf,0x65,0x5a,0x26,0xdf,0xd2,0xcf,0xa4,0x14,0x82,0xb3,0xa9,0xb4,0xc3,0x41,0xe9,0x6,0x7e,0x58,0xa5,0x6d,0x37,0x0,0xa5,0x46,0x63,0xef,0xa0,0xda,0x1d,0x20,0xfa,0x32,0x2f,0xf9,0x42,0x47,0x29,0x8d,0x60,0x57,0x3c,0x9f,0xa4,0x46,0x92,0xab,0x52,0xad,0x29,0xdd,0x30,0x69,0x17,0x3,0xc8,0x34,0xbc,0x3d,0xd3,0x30,0x99,0x96,0xf2,0x9,0x7d,0xbf,0x64,0x92,0xcb,0x34,0x69,0x55,0x26,0x3a,0x63,0x8c,0x8,0x76,0x5,0xd2,0x2d,0xbf,0xa6,0xcd,0xe,0x82,0x5b,0x31,0x61,0x9,0x82,0x6e,0x3b,0x84,0x61,0xd,0x28,0x8d,0x98,0x8e,0x95,0x52,0x81,0x87,0x32,0x2d,0x5f,0x5c,0xc5,0x8,0x3f,0xac,0x40,0x69,0x7b,0x4a,0x37,0x20,0x6d,0x10,0xec,0x8a,0xc7,0xd2,0x2c,0x2a,0x32,0xd9,0x43,0x35,0x3b,0x70,0xeb,0x7d,0xce,0xcd,0x23,0xcd,0xaf,0x9f,0x6a,0xa6,0x41,0xf0,0xba,0x81,0x22,0xe2,0xf3,0x80,0x8,0x61,0x58,0xa2,0xd9,0xbd,0x4,0xae,0x5f,0x41,0x69,0x93,0x54,0x24,0x1e,0xca,0x2c,0x10,0xfc,0x80,0x76,0xe7,0x24,0xdc,0x90,0x2c,0xb8,0x59,0x4d,0x8a,0x94,0x21,0xa5,0x59,0x79,0xa9,0x94,0x49,0xe7,0x5b,0x53,0xce,0x1f,0x40,0x55,0x25,0x1f,0xac,0x4c,0xd4,0xed,0x4e,0x22,0x5b,0x91,0x8e,0xa3,0x2f,0x17,0x52,0x88,0x1,0xa6,0x3b,0x1,0x52,0x84,0xe8,0x7a,0x98,0x6e,0x2f,0x65,0x8b,0xc9,0x7b,0x8d,0x40,0xf0,0xa2,0xf0,0x7f,0xb1,0xce,0x92,0x4d,0xef,0x87,0xe9,0x6,0x88,0x22,0x85,0xe0,0x3,0x94,0x56,0x25,0x6e,0x20,0x33,0x1d,0xaa,0x44,0x13,0x30,0x29,0xa6,0x8c,0x86,0xb5,0x43,0xca,0x9e,0x9b,0xaa,0xca,0x83,0x7,0x8c,0x69,0x46,0x55,0x72,0xca,0x8,0xcc,0x37,0xa3,0x9c,0x1d,0xf0,0xe8,0x93,0x3,0xfe,0x87,0xdf,0xff,0x7f,0xf0,0xd3,0xef,0x7e,0xb,0x7e,0xe9,0xef,0xff,0x14,0x4e,0xec,0xed,0x6e,0x1d,0xef,0xd,0xd7,0xbf,0xc,0x3f,0xf7,0x9e,0xb7,0xe2,0xe3,0x9f,0xbf,0x9f,0x6f,0x82,0x1,0xe9,0x66,0xdb,0xf8,0x1e,0xbe,0x8d,0x9d,0xc9,0x9f,0xb1,0x6f,0xba,0xe1,0x4a,0xfc,0x27,0x3f,0xff,0x1,0xb4,0xcd,0xe6,0x72,0xdf,0xf9,0xfe,0xe3,0xf8,0x37,0xff,0xe1,0x66,0xb8,0xa8,0x4a,0x99,0x53,0xb7,0xd8,0x85,0x1d,0xfa,0xa4,0x6a,0xd4,0xe5,0x26,0x14,0x29,0x5,0x8a,0x4c,0x20,0x7a,0xe7,0x70,0xce,0x39,0xdc,0x76,0xe7,0x7d,0xf8,0x85,0x9f,0xf9,0xc9,0x89,0x12,0x8c,0x8,0xf8,0xe0,0x4f,0xbc,0x15,0xf,0x3c,0xf2,0x14,0x5c,0x8,0x80,0x77,0xb8,0xe4,0xe4,0x9,0xbc,0xfd,0x4d,0xaf,0xd9,0xd8,0xbf,0x73,0xe,0x7f,0x73,0xdb,0x97,0x93,0x4a,0xdd,0x22,0xc7,0x48,0x90,0xd2,0xa0,0x44,0xba,0x22,0xb5,0xa3,0x87,0x62,0xd3,0x1d,0x6f,0x7c,0xa9,0x72,0x73,0xd0,0x4d,0x22,0x41,0x4a,0x24,0x45,0x15,0xb7,0xa0,0x52,0xd1,0x47,0xf0,0xbc,0xde,0x98,0xc7,0x1a,0xca,0xcd,0xa7,0x51,0xbc,0x4d,0x13,0x22,0x8d,0x36,0xce,0xa1,0xca,0x4e,0x1c,0x23,0x22,0xc5,0x91,0xbb,0xa3,0x71,0x1b,0x1b,0x9d,0xbe,0x73,0x37,0xee,0x44,0xf2,0x57,0x2b,0xc6,0x6b,0x26,0x90,0x66,0xec,0xe1,0x51,0x37,0x57,0x5f,0x5c,0xf2,0xef,0x42,0x9a,0xc2,0xf1,0x78,0x69,0x46,0x4,0x4e,0x1b,0x94,0x5,0x2,0x81,0xe0,0x62,0x81,0x98,0x6d,0x4,0x2,0x81,0xe0,0x79,0x7e,0x5d,0x74,0xfd,0x39,0xc,0xfb,0x4f,0x20,0x7a,0xb,0x32,0x1d,0x54,0xb3,0x83,0xe8,0x99,0x68,0xb3,0xcb,0x33,0x20,0xb3,0x80,0x1f,0x96,0xfc,0x16,0x4b,0x29,0xcf,0x47,0x37,0x8,0x21,0xc2,0xbb,0x9e,0xd7,0x69,0xf7,0x10,0x62,0x84,0x5e,0x9c,0x82,0xb7,0x3,0x94,0xe9,0x10,0x9c,0x63,0x82,0xcd,0xb4,0x7c,0xe1,0x96,0xf2,0xf6,0xf2,0x17,0xe8,0xe0,0x2c,0xa0,0xda,0xf4,0x2b,0xc1,0xd,0xab,0xf2,0xe5,0x9e,0xb4,0x49,0x44,0x61,0x3,0x32,0x1d,0x5b,0x95,0x53,0x16,0x9b,0xde,0xb9,0x4,0x0,0x5b,0xba,0xcc,0xe2,0x14,0xa2,0x4f,0xe4,0x5a,0xb3,0x60,0xf2,0x4c,0xb5,0xa0,0x44,0xe6,0xa8,0x44,0x34,0x2,0xa,0x50,0xd,0x54,0xbb,0x7,0x80,0xa0,0xdb,0x1d,0x28,0x52,0x4c,0x4c,0x2,0x68,0x76,0x2f,0x5,0x69,0x3,0x32,0xb,0xa8,0x76,0x87,0x9,0xc6,0x44,0xd6,0x81,0x14,0x74,0xd3,0x81,0x94,0x82,0x59,0xec,0x71,0x98,0x7c,0xb3,0x60,0x95,0x1e,0xc6,0x82,0x8,0xdd,0x9d,0x44,0x51,0x7a,0x4,0x26,0x34,0x91,0x14,0x90,0xa4,0x1b,0xe8,0x76,0xa7,0xa8,0xf0,0x8a,0x2d,0x35,0x15,0x5a,0xa8,0x66,0x1,0xdd,0x9d,0x0,0xe9,0x96,0xd5,0x89,0xcd,0x2,0x11,0xc4,0x24,0x13,0x69,0x44,0xcf,0xea,0x89,0xe8,0x7a,0xbe,0x70,0x72,0x49,0xbd,0xa6,0x1b,0x28,0xd3,0xa5,0xb2,0xb,0x3e,0x2e,0x52,0x9a,0xc9,0xd3,0x6c,0x99,0xd3,0x6,0xa4,0x5b,0xe8,0x6e,0x37,0x65,0xde,0x25,0x35,0xa2,0xd2,0x30,0xbb,0xa7,0x60,0xda,0x1d,0xa4,0xca,0xe5,0x62,0x2d,0x26,0xa5,0xa0,0xcc,0x2,0x44,0x40,0xb3,0x73,0x12,0xd1,0x5b,0xfe,0xdd,0x74,0x7c,0xf1,0xe5,0x3d,0x54,0xbb,0xcb,0xa,0x1c,0x63,0x78,0xbe,0xb3,0x9a,0x31,0x59,0x88,0x23,0x0,0xd5,0xee,0xf2,0x6b,0xa8,0x4d,0x51,0x6b,0x92,0x6a,0xf8,0x38,0x95,0x6,0xa2,0x2b,0x56,0x5f,0xdf,0x33,0x99,0x97,0x4b,0x3d,0xcc,0xe2,0x4,0x54,0xd3,0xa5,0xf9,0xee,0x40,0xa4,0xc7,0x8b,0x48,0xd2,0xd0,0xa6,0x41,0xb3,0x77,0x39,0x80,0x8,0xb3,0x38,0x1,0x32,0x2d,0x4c,0xb7,0xb,0xbd,0x38,0x5,0x28,0x26,0x22,0xbd,0x1b,0xd2,0xb1,0x34,0x50,0xda,0xf0,0xb1,0x2a,0x3,0xd3,0x75,0x30,0x4d,0x9b,0x2,0xf7,0x51,0x8,0x42,0xd2,0x86,0xe7,0x2e,0xe5,0x17,0x36,0x8b,0x3d,0xe8,0xa6,0x4b,0x73,0xc7,0x4d,0xcb,0xaa,0x59,0xc0,0xad,0xe,0xa1,0x9a,0x1d,0x98,0x6e,0xf,0xba,0x59,0x40,0x35,0x4c,0x7a,0xc7,0xe0,0xa0,0x9b,0x1d,0xc,0xfd,0x1a,0xbe,0x3f,0x84,0x3d,0x7c,0x52,0xde,0x62,0x4,0x82,0x17,0x1,0x63,0x2b,0x37,0xc6,0x26,0xd9,0x10,0x58,0xe9,0x47,0x18,0x8b,0x8a,0x72,0x84,0x83,0x1f,0x55,0xbc,0xa5,0xdd,0x3c,0xbd,0x7f,0xe4,0xdc,0xb9,0xac,0x16,0xc,0xde,0x15,0xa5,0x60,0x6e,0x9c,0xd,0xde,0xf3,0x67,0x18,0xb1,0xe2,0x37,0x17,0xd,0x5,0xef,0x99,0x0,0xbb,0xe3,0x5e,0xfc,0xde,0x1f,0xfc,0x19,0x1e,0x7b,0xe2,0xe9,0x23,0xc7,0xfc,0xe3,0x6f,0x79,0x3d,0x16,0xad,0x46,0xdb,0x76,0x68,0x3b,0xbe,0xe1,0xa1,0x52,0x9,0x88,0xda,0xa6,0x1e,0x4c,0xc4,0xd7,0xab,0xaf,0xbd,0x1c,0xbf,0xfa,0xe1,0xf7,0x6d,0x25,0xff,0x9e,0x7c,0xea,0x19,0xfc,0xef,0xff,0xee,0xe3,0x58,0x59,0x2e,0x95,0x52,0x4a,0x97,0x86,0xe1,0x18,0x3c,0xb4,0xe6,0xf7,0xc6,0x3a,0x83,0x37,0x93,0x3d,0xc6,0x34,0x50,0x4a,0xe1,0x8b,0xf7,0x3d,0x8c,0xb3,0xe7,0xf6,0x37,0xb6,0x7d,0xed,0xd5,0x97,0xe3,0x75,0x2f,0xbf,0x12,0x31,0x4,0x98,0xa6,0xc5,0x3b,0x6f,0x7c,0x39,0x2e,0x39,0xb5,0x99,0x7b,0xf8,0xe8,0x63,0x4f,0xe2,0xbe,0x6f,0x3d,0xca,0x64,0xa3,0x69,0xa,0x59,0x9a,0x33,0x57,0xc7,0xc3,0x9,0xac,0xa4,0x8c,0x63,0x36,0xac,0xd6,0x26,0xdd,0x2c,0x42,0xb2,0x62,0xab,0x49,0x9,0xd3,0xc4,0xc0,0x9b,0xb2,0x67,0x43,0x18,0xe3,0x36,0xf2,0x76,0xb,0x61,0x38,0x21,0xf5,0x50,0x59,0xc4,0xf3,0x9f,0xb0,0x41,0x8b,0xc5,0xaa,0x91,0x23,0xce,0x8,0xbd,0x18,0x43,0xf5,0x7b,0x3c,0x82,0x9f,0x23,0x6c,0xf6,0xfe,0xce,0xa,0xa1,0x26,0xd4,0x5b,0x9c,0xbd,0xc6,0x38,0xf,0x45,0xf7,0x42,0x48,0xf2,0xb8,0x75,0x14,0xa5,0x38,0xb9,0xca,0x59,0x9c,0xb7,0xd7,0x63,0xa3,0xef,0x58,0x20,0x10,0x8,0x2e,0xe,0x48,0x9,0x88,0x40,0x20,0x10,0xfc,0x70,0xdf,0x1c,0x11,0xfd,0xc0,0x64,0x9a,0x77,0xac,0xda,0xa,0x59,0xa5,0x95,0x88,0xb7,0x44,0x14,0x29,0x63,0x58,0x65,0x87,0x31,0x4f,0x2f,0x3a,0x26,0xaa,0x88,0xbf,0xd5,0xa7,0x82,0x56,0x57,0xbe,0x98,0x67,0x9b,0x6b,0x6e,0xd6,0xd,0xde,0xf1,0x17,0xf6,0x60,0xd3,0x7e,0x5a,0xb6,0xd2,0x3a,0x56,0x76,0xc5,0x44,0x2c,0x86,0xfe,0x90,0x89,0x25,0xbb,0x62,0x62,0xce,0x74,0xf0,0xc3,0x21,0xdb,0x49,0x95,0x82,0x1f,0x56,0xac,0x18,0x53,0x1a,0xc1,0xf6,0x49,0x71,0x18,0x11,0x6c,0xf,0x52,0x6,0xde,0xae,0x99,0x64,0xd2,0xdd,0x68,0xb5,0x45,0x52,0x79,0x91,0x2,0x82,0x83,0x1f,0x96,0xf0,0x76,0xc9,0xca,0xb7,0x44,0xe2,0x50,0x52,0xe7,0x91,0x22,0x26,0x3d,0x6d,0x9f,0xc8,0x27,0x20,0xd8,0x75,0x22,0xaf,0x22,0xdc,0xfa,0x1c,0x5b,0x44,0x6d,0xcf,0x17,0x63,0xc9,0x8e,0x16,0x7d,0x9f,0x1c,0x40,0xc4,0x64,0x6a,0x60,0x72,0xd5,0xf7,0x4b,0xb6,0xf5,0xaa,0xa4,0x62,0x8b,0x11,0xba,0x59,0x20,0x7a,0x9b,0x6c,0xb4,0x8e,0x55,0x91,0x81,0x15,0x28,0x7e,0x38,0x48,0xc4,0x57,0x0,0x94,0x86,0xef,0xf,0x10,0xfd,0x0,0xe4,0xb,0xa7,0x9c,0xd5,0x97,0xd7,0xf5,0x6e,0xb4,0xda,0x26,0x55,0x5b,0xce,0x3f,0xa,0x76,0xcd,0x4,0xa5,0xe7,0xb,0xdd,0x60,0x7b,0xc4,0x74,0x61,0xcb,0xcf,0x29,0x90,0xa2,0x72,0x6c,0x7c,0x21,0x40,0xf0,0xeb,0x3,0x40,0xf1,0xf9,0x40,0x5a,0x43,0x37,0x6d,0xd9,0xd6,0x68,0xab,0x8d,0xa3,0x45,0x9a,0x8,0x48,0x85,0x21,0x31,0x4,0x26,0x8f,0x43,0x2a,0x28,0xb1,0x3d,0x93,0xbb,0xd1,0x97,0x6,0xcf,0x60,0x87,0x72,0x91,0x1e,0xdc,0xf8,0x1a,0xf9,0xf4,0x7a,0xb2,0x5a,0x32,0x29,0x43,0xed,0x8a,0x49,0xe5,0xac,0xb2,0x84,0x4f,0x56,0xbd,0x54,0xea,0x32,0xac,0x81,0x18,0xa0,0xb5,0x86,0xb7,0xc3,0xd8,0x22,0x1c,0x3,0xfc,0xb0,0x62,0x72,0x1a,0x40,0x70,0x9c,0xd7,0x7,0x6f,0xa1,0x94,0x41,0x24,0x5,0xbf,0x3e,0x80,0xd2,0xa,0xc3,0xc1,0x33,0x85,0xec,0xf6,0x43,0x9f,0xd4,0x97,0x11,0x31,0x5b,0xac,0xd3,0x39,0xec,0xd6,0x7,0x70,0xfd,0xa,0xed,0xce,0x1e,0x82,0x77,0xe9,0xfc,0xb,0xf0,0xc1,0xc3,0x1e,0x3c,0xc9,0xa,0x4d,0x51,0x54,0x8,0x4,0x2f,0xa,0x9a,0x6e,0x7,0x57,0xbc,0xec,0x15,0x68,0x17,0x8b,0x92,0x9,0x5a,0xe7,0xc9,0x22,0xc5,0x4,0x14,0xf5,0x5e,0x9c,0xe5,0x7f,0x26,0x6b,0xbf,0x4e,0xef,0x53,0x63,0x4e,0x69,0x22,0xa5,0x92,0x25,0x55,0x6b,0x3,0x67,0x87,0x44,0xd8,0xc5,0xa4,0x2a,0xd4,0xe8,0x57,0x4b,0x6e,0xd,0x1e,0x7a,0x44,0x0,0x5a,0x1b,0x9c,0x39,0x58,0xe3,0x81,0x6f,0x3d,0x8a,0xd7,0xbf,0xf2,0x1a,0x9c,0x3c,0xb1,0x99,0xb,0xd8,0xb6,0xd,0x9e,0x7a,0xfa,0xc,0x1e,0x7d,0xf2,0x6c,0x6a,0x31,0x66,0x3b,0xb1,0x6e,0x1a,0x5c,0x75,0xc9,0x2,0x6f,0x7e,0xfd,0xd,0x1b,0xeb,0x7c,0xff,0xf1,0x67,0xf1,0x91,0xf,0xbc,0x1d,0xa7,0x4e,0x6e,0x6e,0xef,0xe0,0x70,0x89,0xdf,0xff,0xf7,0x1f,0xc7,0xf,0x9e,0xde,0x87,0x31,0x3c,0x4e,0x67,0x7,0x98,0xa6,0x2d,0x45,0x46,0x21,0xf0,0x7b,0x22,0x14,0xa5,0x9b,0x5c,0x89,0xfc,0xf4,0xae,0x58,0x6b,0x5d,0x88,0xd8,0x31,0x84,0xd7,0xcc,0x9a,0x7d,0x95,0x52,0x38,0x7d,0x6a,0xf,0x5f,0xfe,0xda,0x77,0x61,0x34,0xf0,0x8f,0x3e,0xfc,0x5e,0xec,0xed,0x2e,0x26,0xcb,0x84,0x10,0xf0,0x17,0x9f,0xbc,0x15,0xdf,0xfe,0xde,0xe3,0x25,0x3f,0xb6,0x14,0x28,0xd1,0x58,0x20,0x5,0x0,0xde,0x5b,0x44,0xa4,0xa6,0xdf,0x2a,0xea,0xc3,0xa7,0xd8,0x8a,0x58,0x22,0x38,0x2,0xdf,0xac,0xab,0xf2,0x66,0xc7,0xcc,0xde,0x54,0x20,0x92,0x69,0xaa,0xa4,0x56,0xcb,0x11,0x11,0x2a,0x95,0x49,0xc5,0x6d,0xcc,0x15,0xd5,0x19,0xaf,0x28,0xf6,0x5f,0xaa,0x7e,0xde,0xb4,0xea,0xd2,0x84,0x14,0xcb,0x4a,0xf0,0x4d,0x5d,0xdd,0x96,0x9d,0xfd,0xe8,0xbe,0xae,0x6d,0x44,0x33,0xe7,0x28,0xa,0x9a,0x1d,0x67,0xb9,0xe1,0x58,0x8f,0x74,0xa6,0x94,0x9c,0x7c,0xf,0x4c,0x6d,0xce,0xab,0xc3,0x7d,0x9c,0x7b,0xe6,0x71,0x79,0xe3,0x11,0x8,0x4,0x2f,0x79,0x88,0x5,0x58,0x20,0x10,0x8,0x5e,0x0,0x82,0x5b,0xf1,0xf,0xbe,0x67,0xf5,0x9a,0x5d,0x96,0xe7,0xfc,0x70,0x38,0xfd,0xba,0x9b,0x72,0xe5,0x6a,0xf8,0x1f,0x72,0xbf,0xf3,0x6d,0x3,0x40,0xf0,0x89,0xd0,0x4b,0x63,0x8,0x87,0xc3,0x46,0xe,0x14,0x0,0xc,0xd5,0x18,0x8f,0xc4,0x96,0xed,0x83,0x34,0x10,0xc7,0x11,0xdb,0xe5,0xb3,0xe3,0xbe,0x69,0xcc,0x17,0xdc,0x3e,0xde,0x83,0xf2,0xb3,0xf3,0x43,0x22,0xb7,0x66,0xb,0xd9,0xd5,0xf4,0xf7,0xfe,0x20,0x2d,0x77,0x78,0xe4,0xb6,0xb6,0xad,0xeb,0xd6,0x67,0xd2,0xfa,0xf9,0x2a,0xcd,0x20,0xf4,0xe7,0xce,0x3f,0x9f,0x17,0x9c,0xef,0xfd,0xb,0x4e,0x19,0xd5,0x73,0x90,0xce,0x8b,0x74,0xa8,0x2f,0x8,0x5b,0xf7,0x6d,0x9f,0xc7,0xb9,0xd3,0x1f,0x5c,0x70,0x11,0xcb,0x27,0xe8,0xd6,0xf3,0xc5,0x83,0x95,0xa1,0x39,0xd3,0x30,0x4f,0x35,0x29,0x8d,0xfe,0xdc,0x41,0xba,0x70,0x1d,0xe0,0xfb,0xf3,0x4d,0xe,0x9f,0x3b,0x44,0x1a,0x87,0x4f,0xed,0xcb,0x1b,0x87,0x40,0xf0,0x77,0x8c,0xf1,0xc6,0xc4,0x98,0x15,0x4b,0x8a,0x52,0xfb,0x76,0x2c,0xed,0xe4,0xdc,0x7a,0xab,0xe0,0x53,0xce,0x5c,0xc,0x1,0xa4,0x59,0x11,0xd8,0xb4,0x5d,0xb1,0xfb,0x66,0x5,0x1e,0x11,0x61,0xe8,0x57,0x58,0xec,0xec,0xa5,0x6,0x78,0xbe,0x94,0x58,0x1e,0x9c,0xc3,0x62,0x77,0x8f,0x33,0xf4,0x9c,0x43,0xd3,0x2d,0xb0,0xdc,0x3f,0x8b,0xa6,0x65,0x45,0xba,0x1d,0x7a,0xb4,0xdd,0xe,0xce,0xec,0x2f,0xf1,0x87,0x7f,0xf9,0x39,0xfc,0xce,0x47,0x7f,0x6e,0x43,0x2d,0x47,0x44,0x78,0xdb,0x1b,0x5f,0x8d,0xbb,0x1e,0xfa,0x41,0xc9,0x19,0xcd,0x2d,0xf5,0xdb,0x32,0x0,0x89,0x8,0x97,0x9c,0xe8,0x70,0x62,0x77,0x67,0xeb,0x1c,0x9c,0x39,0x77,0x80,0xa7,0xcf,0xad,0x12,0xe9,0xa6,0xa1,0xb4,0xc1,0x62,0x77,0xf,0x87,0xfb,0x67,0xa1,0x93,0xba,0x2f,0x4,0x8f,0xa6,0xeb,0x8a,0x52,0x51,0x29,0x56,0xf3,0x65,0xfb,0x31,0x29,0x5,0xef,0x3d,0x3e,0x7b,0xd7,0x43,0x78,0xf7,0xdb,0xdf,0x84,0x4b,0x4e,0x4d,0x89,0xc6,0x97,0x5f,0x73,0x25,0x5e,0x7b,0xed,0xa5,0x38,0x7d,0x62,0x7,0x97,0x5f,0x7a,0x6a,0x63,0xc,0x8f,0x3f,0xf9,0xc,0xbe,0xf8,0xd5,0x6f,0xc0,0x98,0x16,0xce,0xdb,0xb4,0x1f,0xfe,0x3b,0x6,0x5f,0xb2,0xff,0x9c,0xb5,0x25,0x5f,0x78,0xe8,0xd7,0x29,0x7,0x98,0x49,0x4a,0x2e,0x8,0x49,0x6d,0xf0,0x18,0x33,0x6a,0x41,0x28,0xcd,0xc3,0x99,0x54,0xcc,0x44,0x5f,0x40,0x28,0x25,0x4e,0xd9,0x46,0xab,0x12,0x59,0x18,0x27,0xc4,0x56,0xac,0x4a,0x80,0x53,0xd2,0x1f,0x4d,0x6d,0xbe,0xbc,0x70,0x26,0xcf,0xce,0xd7,0xbc,0x3b,0x2b,0x94,0x9a,0xbe,0x5a,0xa8,0xcb,0xd0,0x9e,0xbb,0x6e,0x6e,0x4a,0xba,0x3d,0x97,0x52,0x8e,0x49,0x1,0x56,0x3e,0x8e,0xb2,0xe2,0x38,0x2,0xc2,0xb4,0x88,0xd,0x95,0xe3,0x22,0x56,0xb6,0xe4,0xb8,0xd5,0x82,0x3c,0xfb,0x4d,0x6e,0x5e,0x9,0x4,0x82,0x8b,0x4,0x62,0x1,0x16,0x8,0x4,0x82,0x17,0xb,0x17,0x8,0x81,0x9e,0x93,0x7f,0x2f,0xfe,0xee,0xfd,0xf3,0x1a,0xcf,0xf3,0xdf,0x81,0x3f,0xcf,0x17,0x6e,0xff,0x12,0x7e,0x59,0xdc,0x8f,0x66,0x3f,0x2f,0xe1,0x39,0x78,0xa1,0xe7,0x6f,0x5d,0x68,0xf2,0x43,0x9d,0xcf,0xa5,0x7c,0xc6,0xcb,0xfb,0x84,0x40,0xf0,0x23,0x79,0x3f,0x8a,0x53,0x6f,0x28,0x80,0x51,0x85,0x9c,0x7e,0x4e,0xff,0xb6,0xbd,0xe3,0x6,0xdb,0x98,0x5a,0xee,0xd9,0x2a,0x5b,0x95,0x32,0x61,0x2c,0xa8,0xa,0x81,0x89,0x41,0x52,0x9a,0xad,0xc3,0x81,0x8b,0x42,0x74,0xca,0x4b,0xa5,0xa4,0x4e,0xf6,0x29,0xeb,0xb5,0x5f,0x2f,0x99,0x80,0xf3,0x1e,0x43,0xbf,0x82,0xf7,0x16,0xdf,0x7f,0xe2,0x19,0x7c,0xee,0x8b,0x5f,0xdd,0xda,0x9c,0x7a,0xea,0xe4,0xe,0x7c,0x22,0xc8,0x0,0x26,0x32,0x99,0x24,0xdb,0xfe,0xde,0xf1,0xc8,0xf,0x9e,0xc5,0x27,0x3f,0xf7,0x65,0x38,0xbf,0xf9,0xfe,0x75,0xfd,0x35,0x57,0xe1,0xb7,0x7f,0xed,0x43,0xb8,0x64,0x6f,0xa7,0xb4,0xfc,0x3a,0x6b,0x8b,0xb5,0xd7,0x7b,0x37,0x92,0x9c,0x88,0x68,0x9a,0x26,0x29,0x2,0x2d,0x86,0x7e,0xcd,0xd1,0x4,0xce,0x82,0x0,0x2c,0x7b,0x8b,0x2f,0xdf,0xf7,0xd0,0xc6,0x3e,0xb4,0x56,0xf8,0xc0,0x3b,0x6f,0xc4,0xbb,0xde,0xf6,0xfa,0xad,0xe5,0x23,0xb7,0x7d,0xe9,0x5e,0xc,0xce,0xc3,0xda,0x21,0xb5,0xe9,0x12,0x4c,0xd3,0x30,0x19,0x9b,0x6c,0xa5,0x99,0xbc,0x1b,0xfa,0x15,0xab,0xba,0x43,0x48,0x4,0x61,0x18,0x8b,0xa0,0x72,0xd9,0x14,0xd8,0xe6,0x1b,0x11,0xa1,0x94,0x49,0xb6,0xdf,0xb8,0xd1,0x52,0x3c,0x46,0xeb,0x51,0x51,0xc8,0xa7,0x27,0xd3,0xab,0x4f,0xe9,0xf5,0xc5,0xb4,0x75,0x17,0x71,0x62,0x85,0x2d,0x36,0xe1,0xf1,0x97,0xea,0xe8,0x68,0xda,0x2,0x5f,0x9d,0x57,0x5b,0xce,0xc8,0xf3,0x3e,0x7b,0xf4,0x1a,0xd3,0x73,0xa4,0x2e,0xe5,0x40,0x35,0x4e,0xfe,0x13,0xcb,0x5e,0xca,0xb1,0x4d,0xdc,0xc5,0xa9,0xe6,0x24,0x5b,0xe2,0xe3,0x7c,0x5b,0x47,0x59,0x91,0xe7,0x8a,0xc7,0x8d,0x7f,0x6c,0xcf,0xad,0x2a,0x58,0x20,0x10,0x8,0x5e,0x2,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x46,0x28,0xea,0xad,0xba,0x35,0x3e,0x84,0xa2,0x7a,0xca,0xa5,0x10,0x4c,0xe2,0x71,0x94,0x40,0x88,0x1,0x4d,0xd3,0x15,0x52,0x2a,0xc6,0x0,0xef,0x1d,0xb4,0x31,0x25,0xe7,0x2e,0xa4,0x7c,0x55,0x67,0xfb,0xa2,0x20,0xb,0x21,0xa0,0x69,0x3b,0xd8,0x61,0x5d,0x5a,0xec,0xb5,0x36,0x8,0xde,0x63,0xb1,0xb3,0x57,0x8,0x45,0xa5,0x34,0x5c,0x8a,0x20,0xf8,0xd2,0xfd,0xf,0xe3,0x70,0xb9,0xda,0x18,0xf7,0xde,0xee,0x2e,0xba,0x6e,0x1,0x97,0x72,0x5b,0x79,0xbd,0xb1,0x6d,0xbe,0x46,0x8c,0xdc,0x9e,0xfb,0x99,0xbb,0xbe,0x89,0x4f,0xdf,0xfa,0x65,0x38,0xb7,0x49,0x12,0xbe,0xfa,0x86,0xeb,0xf1,0xdb,0x1f,0xfd,0x30,0xae,0xbc,0xec,0x54,0x51,0xd8,0x71,0x8b,0x2e,0x6f,0x6f,0xe8,0xd7,0x70,0xc3,0x0,0x22,0x85,0xe5,0xe1,0x7e,0x22,0x2a,0xd7,0xf0,0xce,0xc1,0xbb,0xa1,0x10,0x98,0x31,0x4,0xdc,0x72,0xc7,0xbd,0x38,0x7b,0x6e,0x53,0x51,0xfd,0x9a,0x57,0x5e,0x87,0x97,0x5f,0x7b,0xd5,0xc6,0xe3,0xcf,0x3c,0x7b,0x6,0x77,0xdc,0xfb,0x4d,0x28,0xa5,0xa0,0x35,0x2b,0x2d,0xdd,0xd0,0xc3,0xdb,0x2c,0x7f,0x8f,0x25,0x8b,0x90,0xdb,0x88,0x3,0xfa,0x7e,0xc5,0xa,0xc1,0x64,0xf7,0x25,0x52,0x50,0x3a,0xb5,0xc0,0x6b,0xd,0x95,0x73,0x85,0x41,0x8,0xf5,0xcd,0xad,0x38,0x36,0xf8,0x16,0x55,0x5b,0xc8,0x7e,0x57,0xa6,0xf5,0x42,0x56,0x54,0xa2,0x2a,0xf8,0xa0,0xf1,0x7c,0xe1,0xd5,0xeb,0x6c,0xc0,0x3a,0xaf,0xf,0xd8,0xcc,0xf1,0xab,0x89,0xc1,0x6a,0x20,0x69,0x83,0x2f,0x58,0x13,0x57,0x11,0x74,0xd3,0x2c,0xbe,0xf1,0xf5,0xcf,0xdc,0xdb,0x26,0xff,0x46,0xc0,0xa4,0x24,0x65,0xdc,0xe8,0x51,0x8a,0xbe,0xb,0xe,0x64,0xcb,0x3a,0xb1,0x64,0x28,0x8a,0x2,0x50,0x20,0x10,0x5c,0x1c,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x6e,0x48,0xca,0x36,0xfe,0x91,0xc9,0x90,0x10,0x23,0x8c,0x69,0x98,0xa0,0x8b,0x1,0x31,0xc6,0x94,0x89,0x17,0xa1,0x4d,0x93,0x1a,0x69,0x39,0xb3,0x8f,0x40,0x30,0xa6,0xe1,0xfc,0xcf,0x44,0xb0,0x98,0xa6,0xc3,0x4d,0x6f,0x7c,0x5,0x4e,0x9e,0xd8,0x2b,0xa4,0x47,0xf0,0xe,0x43,0xbf,0xe2,0x75,0x12,0xd1,0x8,0x0,0x4d,0xdb,0xc1,0x39,0xcb,0x76,0x56,0x44,0x56,0xb8,0x79,0x87,0xa1,0x5f,0xe3,0xec,0xfe,0x21,0xe,0x97,0xeb,0x8d,0x21,0x6b,0x5,0x2c,0x1a,0x2a,0xb6,0xd7,0x61,0xbd,0x42,0x29,0x8b,0xda,0x82,0xac,0x6c,0xfb,0xf4,0x9d,0xf,0xe1,0xd3,0xb7,0xdd,0x95,0xc8,0xbd,0x29,0x5e,0x7d,0xc3,0x75,0xf8,0x67,0xbf,0xfa,0x21,0x9c,0xde,0x6d,0xe1,0x9d,0xe5,0xbc,0xc2,0x74,0xdc,0x79,0x1e,0xe,0xcf,0x9d,0x29,0x45,0x20,0x76,0xe8,0xb9,0x88,0x2b,0x65,0x10,0x6,0xcf,0x39,0x81,0xcb,0x3e,0xe0,0x8e,0xbb,0xbf,0xb6,0x79,0x31,0xa5,0xd4,0x44,0x81,0x97,0xa6,0x1e,0xb7,0xdd,0x79,0x1f,0x96,0xeb,0x1,0xd6,0xe,0x8,0x31,0xc0,0xd9,0x1,0x4a,0x33,0x81,0xe7,0xec,0x0,0x37,0xc,0xf0,0xde,0x61,0x79,0xb8,0x8f,0x61,0x58,0xe3,0x70,0xff,0xc,0x13,0x8e,0x49,0x95,0xc9,0xd6,0x65,0x9f,0x88,0xbc,0xaa,0xcd,0xb7,0xa8,0x33,0x47,0x95,0x67,0x48,0x76,0xe1,0x5c,0xa,0x85,0x54,0xce,0x82,0x94,0xf7,0x98,0x73,0x1f,0xcb,0x63,0xd5,0x38,0xcb,0xf9,0xb1,0x41,0xe6,0x95,0xa5,0x2a,0xfb,0xec,0x64,0xf6,0xcf,0x7b,0xee,0x1d,0xa9,0x5,0x8c,0x33,0x95,0x21,0x36,0xb5,0x85,0x35,0xe1,0x97,0xa9,0xcd,0x58,0xa9,0x14,0x6b,0xc6,0x6f,0x52,0xd0,0xb1,0x55,0xa9,0xf8,0x77,0xf6,0xf,0x4c,0xde,0x63,0x4,0x2,0xc1,0x45,0x7,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0x63,0x4,0x52,0xa6,0x6a,0x78,0xad,0xa4,0x52,0x31,0xc2,0x7b,0x7,0xef,0x5d,0x22,0xb7,0x5c,0x79,0x3e,0x38,0x56,0x94,0x29,0xc5,0xc5,0x4b,0x2a,0xb5,0x1,0x3,0x4c,0xc1,0x10,0x31,0xd9,0xf7,0x8e,0xb7,0xdc,0x88,0x7f,0xf2,0xf,0x3e,0x80,0x46,0xb3,0x3a,0x4f,0x9b,0x26,0xfd,0x31,0xd0,0xda,0xc0,0xb4,0xdc,0x2,0xdf,0xed,0xec,0xc1,0x34,0xd,0xd6,0xab,0x31,0x77,0xd6,0xe,0x5c,0x5c,0x65,0xad,0xc5,0x6a,0xb5,0x99,0x47,0x1b,0x42,0x84,0x75,0xa1,0xa8,0x17,0x9b,0xae,0x2b,0x56,0xd8,0x4d,0x70,0xc9,0x10,0x88,0x6d,0xb1,0x1f,0xff,0xdc,0xdd,0xf8,0xd4,0x67,0xee,0xd8,0x4a,0x2,0xbe,0xf2,0xe5,0xd7,0xe0,0x9f,0xff,0xda,0xcf,0xe1,0xaa,0x2b,0x2f,0x87,0x69,0x1a,0x78,0xef,0x46,0x95,0x63,0xb2,0x2b,0x6b,0xd3,0xa0,0x5f,0xaf,0xe0,0xbd,0x83,0xb3,0x43,0x69,0x34,0xce,0xe4,0x28,0x69,0x85,0x5b,0xef,0x7e,0x8,0xe7,0xf6,0x2f,0x9c,0xab,0x7a,0x6e,0xff,0x0,0xb7,0xdd,0xfd,0x20,0x80,0x88,0xae,0x63,0xb,0xb2,0xaf,0xf2,0x17,0x9d,0x1d,0x4a,0x1,0x9,0x81,0x60,0xfb,0x35,0x82,0x67,0x2b,0x36,0xbf,0x36,0xbc,0xef,0xdc,0xe6,0x1b,0x43,0x4,0xc2,0x58,0x1a,0x92,0xcb,0x5b,0x28,0xd5,0x56,0xa9,0xf4,0x5a,0xe4,0xec,0xc4,0x91,0xc,0x4b,0x84,0x59,0x2e,0x71,0xd9,0x28,0xf1,0xd8,0x62,0xf,0x2f,0x4f,0x4f,0x2a,0x8a,0xb7,0xce,0xff,0xc6,0x72,0xdb,0x96,0xaa,0x15,0x7b,0xc0,0x2c,0x5c,0x70,0x6a,0xd5,0x1d,0x79,0xc8,0x6d,0x16,0xf6,0xfc,0x33,0x4d,0x77,0xbd,0x61,0x43,0xc6,0xb,0xb3,0xe4,0x9e,0xf7,0x58,0x8f,0xf8,0xf7,0x26,0x16,0x60,0x81,0x40,0x70,0x91,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x18,0x21,0x78,0x57,0xf2,0xd0,0xb8,0xd9,0x75,0x6c,0x9b,0x55,0xa5,0x15,0x3d,0xa4,0x72,0x2a,0x26,0xdc,0xb4,0x31,0x50,0x4a,0x3,0x88,0x8,0x3e,0x14,0x55,0x19,0x11,0x95,0x9f,0x4d,0xdb,0x1,0x88,0x78,0xf7,0x3b,0xde,0x8a,0xdf,0xfc,0x87,0x3f,0xb,0xc4,0x0,0xe7,0x2c,0xda,0x76,0x51,0x8,0x33,0x44,0x6e,0xb2,0x35,0xa6,0x41,0xf0,0x1,0x8b,0x9d,0xbd,0xd2,0x1c,0x6c,0x4c,0x3,0x67,0x7,0xec,0x75,0x1a,0x97,0x5f,0x76,0xd9,0xc6,0xb8,0xd7,0xfd,0x80,0xb3,0xe7,0xce,0xf2,0x31,0xe4,0x86,0x5e,0xe0,0xc8,0x92,0x85,0x18,0x23,0xdc,0x30,0x70,0x66,0x1e,0x80,0xbf,0xfc,0xec,0xdd,0xf8,0xd4,0x67,0xbe,0x30,0x36,0xed,0x56,0xb8,0xfe,0x9a,0x2b,0xf1,0x1b,0xbf,0xf8,0x3e,0xec,0x18,0xa4,0x9c,0x41,0x56,0xda,0x79,0xef,0xe0,0x86,0x1,0x43,0xbf,0xc2,0xd0,0xaf,0x8a,0xa2,0xac,0x5f,0x2d,0xe1,0xbd,0x4f,0xc7,0xce,0xcb,0x1c,0xf6,0x16,0x5f,0xba,0xe7,0xeb,0x17,0x9c,0xff,0x3b,0xef,0xf9,0x1a,0xce,0xee,0x1f,0xc2,0x7b,0x8f,0x61,0x58,0xc3,0x18,0xc3,0xc4,0x5c,0x22,0x60,0x89,0x54,0x21,0xf3,0x86,0x61,0xd,0x3b,0xf4,0x18,0x86,0x9e,0x55,0x82,0xca,0xc0,0x39,0x9b,0x88,0xc2,0xbe,0x58,0xb6,0x43,0x6a,0x6f,0x7,0xb8,0xd0,0x65,0x6c,0xf3,0xd,0x99,0xe3,0x1b,0x8b,0x53,0x4a,0x1b,0x6f,0x5d,0xf6,0x11,0x8b,0x12,0x74,0xde,0x66,0x8b,0xea,0xfc,0x40,0x65,0x91,0x9d,0x12,0x5b,0xe7,0xcf,0xf7,0xab,0x37,0x37,0xb7,0xdd,0xe6,0xd5,0xc7,0x76,0xe2,0x71,0x9b,0xc5,0xc2,0x7b,0x54,0x35,0x71,0x19,0x52,0x6d,0x5b,0xae,0xc6,0xbc,0xed,0xdc,0x78,0x21,0x96,0xdc,0x39,0x99,0x17,0xb7,0xb4,0x1a,0x17,0x36,0xf3,0x45,0xd8,0x9f,0x40,0x20,0x10,0xfc,0x8,0x21,0x4,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x8c,0x10,0x2a,0xd5,0x5c,0x56,0x8b,0x21,0xd9,0x65,0x73,0xc6,0x9c,0xf7,0xdc,0x20,0x9b,0xc9,0xa2,0x18,0x63,0x51,0x4,0x52,0x52,0x93,0x11,0x11,0x4c,0xc3,0xd,0xbc,0x3a,0x91,0x58,0x8a,0x8,0x4a,0x11,0xde,0x79,0xd3,0x8f,0xe1,0xbf,0xfa,0x8d,0x5f,0xc6,0xeb,0x9a,0x9c,0x41,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x55,0x97,0x5d,0x82,0x7e,0xbd,0x84,0xb3,0x3,0x9a,0x6e,0x1,0xef,0x3d,0x93,0x86,0xde,0xa3,0xed,0x16,0xe8,0x16,0x3b,0x68,0xba,0x45,0xb2,0xdb,0x32,0x99,0xf5,0x53,0xef,0x7c,0x13,0x4e,0x9e,0xd8,0xdd,0x18,0xf7,0x63,0x4f,0x3c,0x5,0x22,0x95,0x14,0x71,0xdc,0x98,0xeb,0x83,0xab,0xaa,0x29,0xa6,0xf0,0x6e,0x28,0x56,0x63,0x67,0x2d,0x6c,0xdf,0xe3,0x4f,0x3f,0xf5,0x5,0x7c,0xfa,0xb3,0x77,0x6c,0x25,0x1,0x5f,0x71,0xfd,0x35,0xf8,0x9d,0x8f,0x7e,0x18,0x57,0x5e,0x7a,0xaa,0x58,0x7d,0x73,0x8b,0xae,0xb3,0x16,0x4a,0x1b,0x34,0x4d,0xcb,0x16,0x56,0x42,0xb2,0x22,0x7,0x56,0x0,0xa6,0x96,0xe4,0x5b,0xef,0x7a,0x10,0xfb,0x7,0xcb,0x23,0xe7,0xfe,0x70,0xb9,0xc2,0x2d,0x77,0xdc,0xcb,0xea,0xbe,0x64,0x23,0xb6,0x89,0xa4,0xb4,0x96,0x6d,0xbf,0xde,0xb9,0xb2,0xff,0xf5,0xf2,0x0,0xb6,0x5f,0x27,0xb,0xb2,0x46,0xbf,0x3e,0x44,0xc,0x1,0xde,0x7b,0x68,0x63,0xe0,0x9d,0x2b,0x4a,0x40,0xa4,0x2c,0x3f,0x2e,0x9,0x19,0x95,0x9d,0x4c,0x26,0x56,0xc7,0x3b,0x2b,0xf5,0x20,0xa2,0x9,0x87,0xc5,0xaf,0x6d,0xb6,0x50,0x53,0xf5,0x7,0xa8,0x17,0xac,0x33,0xf7,0x70,0xe4,0xab,0x30,0xe5,0xbf,0x28,0x97,0x8f,0x60,0x46,0x4,0x56,0x4,0xe3,0x48,0x12,0xc6,0xd9,0x3e,0xe6,0x1b,0xdd,0xcc,0xeb,0x7b,0xd1,0xf2,0xf6,0x9e,0xeb,0x76,0x36,0xd4,0x7d,0x71,0x32,0x5d,0x51,0x4a,0x40,0x4,0x2,0xc1,0x45,0x4,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0x63,0x84,0x4c,0x56,0x21,0x56,0xf6,0xd9,0x54,0xaa,0x41,0x44,0xa9,0xa8,0x83,0x73,0xf6,0x72,0x66,0x5f,0x26,0xac,0x6a,0x3e,0x83,0x52,0x5b,0x2e,0x29,0x2e,0x95,0xc8,0x99,0x79,0x0,0x93,0x48,0x6f,0x7e,0xe3,0x6b,0xf1,0xdf,0xfe,0xce,0x3f,0xc6,0x7,0xdf,0x79,0x23,0x4e,0x9c,0x38,0x51,0x48,0x1d,0x6d,0x1a,0x98,0xb6,0xc5,0xee,0x89,0x53,0x0,0x80,0x6e,0xb1,0xb,0x80,0xd0,0xb6,0x1d,0x7e,0xf2,0x2d,0xaf,0xc5,0x87,0xde,0xff,0xae,0xad,0xe3,0xfe,0xca,0xfd,0xdf,0xc0,0xd0,0xaf,0x93,0x3d,0x37,0xb5,0xd5,0xfa,0x23,0x1a,0xca,0x89,0x40,0x4a,0x63,0xe8,0xd7,0xe5,0xb8,0x88,0x0,0x28,0x8d,0x3f,0xfa,0x8f,0xb7,0xe0,0xe6,0xcf,0xdc,0xb1,0x95,0x2c,0xba,0xfe,0xda,0xab,0xf0,0x2f,0x3e,0xf6,0xf3,0xb8,0xe2,0x92,0x3d,0x0,0x84,0x61,0xbd,0x4e,0xc4,0x67,0x40,0xc,0x1e,0xd6,0xf6,0x20,0xa5,0xd0,0x76,0x3b,0x7c,0xb1,0xa4,0x34,0xab,0xc,0x53,0x2e,0xdf,0xb9,0x95,0xc5,0x1d,0x77,0xdf,0x7f,0xe4,0xdc,0xdf,0x7d,0xef,0x83,0x78,0xe6,0xdc,0x1,0x4c,0xd3,0xc0,0x26,0x55,0x1f,0x88,0x55,0x7b,0xa4,0x14,0x9c,0xb5,0xdc,0x88,0xec,0x2c,0x9c,0x1d,0x98,0xe0,0x4b,0xf6,0xe9,0xf5,0xea,0xb0,0x14,0xb3,0xf8,0x44,0x6a,0xe6,0xcc,0x3b,0x6d,0x1a,0x3e,0x66,0x8c,0x36,0x6d,0x56,0x2,0x66,0x45,0x20,0xff,0xc9,0x8a,0x3f,0x52,0x34,0x29,0x82,0x99,0x66,0xff,0xc5,0x42,0xc6,0x4e,0x4a,0x3d,0xb0,0xc9,0x65,0x15,0xe7,0x30,0x36,0x35,0x80,0x71,0xf6,0x53,0x9d,0xef,0x37,0xcf,0x1a,0x24,0xa2,0xad,0x5,0x1c,0x44,0x84,0xa9,0x2a,0xf1,0x47,0xa4,0xa6,0x3b,0x2f,0x69,0x37,0x1b,0xc3,0xac,0x14,0x65,0xae,0x72,0xc,0x5e,0x1a,0xee,0x5,0x2,0xc1,0xc5,0x1,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0x63,0x6,0x56,0xc0,0xf1,0x57,0x7d,0x2,0x52,0xa9,0x4,0x17,0x5d,0xc4,0x10,0x8a,0xb5,0x14,0x60,0x72,0x4f,0x69,0x9d,0xa,0x26,0x42,0x69,0x2,0x6,0x80,0xe0,0x43,0x21,0xa5,0x42,0xd5,0xa0,0x9b,0x71,0xd9,0xa5,0xa7,0xf1,0xd1,0x5f,0xfe,0x59,0xfc,0x37,0xbf,0xf9,0xcb,0xf8,0xd0,0xbb,0x6e,0xc4,0xf5,0xd7,0x5c,0xd,0xa3,0xb8,0xa1,0x17,0x60,0x12,0x91,0x82,0xc3,0xab,0xaf,0xbd,0x1c,0xbf,0xf5,0x6b,0x3f,0x8b,0xdf,0xf8,0xc7,0xbf,0x88,0xc5,0xa2,0xdb,0x18,0xef,0xd3,0xcf,0x9c,0xc1,0x57,0xbe,0xfe,0x8,0xec,0xb0,0x2e,0x85,0x21,0x21,0x35,0x11,0x7,0x67,0x37,0xf,0x30,0xd9,0x3f,0x49,0x51,0x39,0x36,0xe7,0x5c,0x22,0xce,0x1c,0xfe,0xe4,0xaf,0x6f,0xc3,0xa7,0x3f,0x73,0xfb,0x56,0x25,0xe0,0xcb,0xaf,0x7b,0x19,0xfe,0xcb,0xff,0xec,0x57,0x71,0x7a,0x47,0x17,0x85,0x63,0xf0,0xbe,0xd4,0xe1,0x2e,0x76,0x4f,0x94,0x9c,0x40,0xfe,0xdb,0x33,0x1,0x97,0xa,0x49,0x1e,0x7a,0xe4,0x71,0xf8,0x2d,0xdb,0x5d,0xf7,0x3,0x3e,0x7d,0xeb,0x9d,0x18,0xfa,0x1e,0x76,0xe8,0x8b,0xfd,0x9a,0xd2,0x1c,0x7b,0x3b,0xc0,0xd9,0xbe,0x64,0xb,0xe,0x43,0x8f,0xa6,0xed,0xd0,0xaf,0x96,0x50,0x5a,0xc3,0x34,0xd,0xda,0xc5,0xe,0x94,0x62,0x3b,0x76,0xb6,0x6b,0x7b,0x67,0x8b,0x12,0x90,0x4a,0x73,0x33,0xa,0x81,0x1b,0xc3,0xb4,0xf0,0x85,0xd5,0x9c,0xd9,0xe,0x4c,0x53,0xb1,0x5b,0x52,0x76,0x52,0x39,0x33,0xca,0x13,0xe3,0x36,0x4b,0x7e,0x24,0x26,0x65,0x23,0xe3,0xf3,0xe3,0x6b,0x30,0x2d,0xec,0x40,0xd5,0x22,0x3c,0x79,0xb1,0x8e,0x54,0xee,0xfd,0xdd,0x35,0xe8,0xc6,0xe7,0xff,0x7c,0xac,0xc2,0x5,0x63,0x9c,0xe6,0x67,0x56,0xd,0xc9,0x2c,0x72,0xac,0x99,0x51,0x51,0x0,0xa,0x4,0x82,0x8b,0x3,0x46,0xa6,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x3e,0x8,0x6e,0x18,0x73,0xe2,0x12,0x99,0xc7,0x36,0xe0,0xac,0xf4,0x3,0x94,0x6a,0x92,0xb2,0x8f,0xb3,0x0,0x33,0xb4,0xe6,0xcb,0x3,0x95,0x1a,0x63,0xa9,0x34,0x0,0xb7,0x47,0xa6,0xc0,0x29,0xa5,0x70,0xcd,0xd5,0x57,0xe0,0x97,0x3f,0xfc,0x1,0xfc,0xfc,0x30,0x60,0xff,0x70,0x89,0x73,0xe7,0xf6,0xe1,0x7c,0x40,0xd3,0x34,0x38,0x79,0x62,0x17,0x97,0x9c,0x3a,0x81,0xc6,0x6c,0xbf,0xf4,0x88,0x31,0xe2,0x53,0x7f,0x7b,0x1b,0x9e,0x7c,0xf2,0x49,0x34,0x6d,0x87,0x18,0x23,0xd6,0xa9,0xb1,0x98,0x7f,0x3f,0xe2,0x38,0x3d,0x5b,0x69,0xbd,0x77,0x70,0x6e,0x48,0x16,0x65,0xce,0xd0,0xf3,0xde,0xe3,0x8f,0xff,0xfa,0x76,0x34,0x6d,0x87,0xf7,0xff,0xc4,0xdb,0xf9,0x78,0x2a,0x5c,0x77,0xcd,0x55,0xf8,0xaf,0xff,0xc5,0xc7,0xf0,0x3f,0xfd,0xeb,0x3f,0xc2,0x77,0x97,0xfb,0xd8,0x3b,0x71,0x9,0x93,0x76,0xa9,0x9,0x98,0x88,0xd0,0xb4,0xb,0x98,0xa6,0x49,0x63,0xc,0x68,0xda,0xe,0x21,0x78,0xfc,0xc4,0xdb,0x5e,0xf,0xad,0x36,0x75,0x14,0xf7,0x3f,0xf0,0x20,0xbe,0xfd,0xfd,0xc7,0x4b,0x3b,0x31,0x0,0x80,0x52,0x9e,0xa1,0x77,0x8,0x3e,0xab,0x27,0x15,0xbc,0x1f,0x0,0x0,0xcb,0x83,0x73,0xd8,0xd9,0x3b,0x9,0x22,0x82,0xd6,0x86,0xad,0xd4,0x6d,0x57,0x32,0xf1,0x88,0x14,0x88,0xb8,0x49,0x99,0x5f,0x4b,0x56,0x9b,0xb1,0x72,0x33,0xd9,0xb5,0x73,0xe9,0x7,0x11,0x40,0xa,0x31,0xf8,0xa4,0xac,0x9b,0x16,0x64,0x30,0x97,0x57,0x91,0x76,0x18,0xdb,0x7a,0x8b,0x25,0xb7,0xa8,0x8,0xb3,0xfa,0x8f,0xa,0xd1,0xc7,0x84,0x26,0x15,0x1b,0xef,0x54,0xd5,0x57,0x5e,0xcd,0x23,0x1e,0xff,0x3b,0x46,0xac,0xdb,0x8a,0xeb,0x63,0x47,0x35,0x7,0xf3,0x4c,0xc3,0x58,0xf2,0x13,0xe7,0x36,0x69,0x56,0x5b,0xc6,0xaa,0xa0,0x24,0x6e,0x9c,0xb3,0xd5,0xe4,0xc9,0x9b,0x8e,0x40,0x20,0xb8,0x28,0x20,0x4,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x9c,0x90,0xb2,0xdd,0x62,0xb2,0xeb,0x32,0x79,0x14,0x4a,0x1b,0x6c,0xc9,0x7,0xc,0x71,0xb4,0xb,0x2b,0x5e,0x27,0x84,0x0,0xd3,0x34,0x15,0x9,0xc4,0x7f,0xbb,0xa1,0x47,0xd3,0x2d,0xce,0xcb,0x75,0x10,0x1,0x5d,0xd7,0xa2,0xeb,0x5a,0x5c,0x71,0xd9,0xe9,0xe7,0x3c,0xdc,0xaf,0xde,0xff,0x75,0x7c,0xfc,0x33,0x77,0x22,0x92,0x42,0xdf,0xaf,0x0,0x10,0x16,0x3b,0x7b,0x70,0x88,0xe8,0xd7,0x4b,0x28,0xfd,0x9a,0xad,0xeb,0xd5,0x45,0x1e,0x8a,0x14,0xbc,0x73,0x58,0xf7,0x7,0x45,0x25,0xe7,0x1c,0xf0,0xef,0x3e,0x7e,0x2b,0x42,0x8c,0xf8,0xe0,0x7b,0xde,0xb1,0xd1,0xd6,0x7a,0xdd,0x35,0x57,0xe3,0x77,0xff,0xf3,0x5f,0xc7,0xff,0xf2,0x6f,0xfe,0x4,0x8f,0x3c,0xfa,0x44,0x29,0x2a,0x69,0x9a,0x96,0xdb,0x7f,0x75,0x2e,0x4c,0x61,0xf2,0xcd,0xda,0x1,0x97,0x5f,0xb2,0x87,0x1b,0x5f,0x77,0xc3,0xc6,0x58,0x6,0x6b,0xf1,0xc9,0xbf,0xbd,0x9d,0x1b,0x84,0x95,0x2,0x91,0xe2,0xf2,0x13,0x10,0x86,0xbe,0x2f,0xaf,0x3,0x37,0x2,0x3b,0xac,0x97,0x87,0x18,0xd6,0xab,0x42,0xb4,0x9a,0xa6,0x5,0x29,0x85,0xa6,0xed,0x60,0xc,0x93,0x8e,0xda,0x34,0xa9,0xe0,0x24,0xb7,0xfe,0x32,0xd9,0x4a,0xa0,0x54,0x26,0xc2,0x4,0x6e,0x24,0x2,0x91,0x42,0xf0,0x7e,0x26,0x46,0xab,0x1b,0x77,0x9,0x44,0x89,0x8,0xc4,0x48,0x91,0xe5,0x66,0x62,0x5e,0x8f,0x4a,0xe7,0xc5,0x68,0x1f,0xde,0x56,0x8a,0x91,0x7f,0xdc,0x4e,0xf6,0x1d,0x4d,0xfe,0x6d,0xd9,0xde,0xf3,0x44,0xde,0xe7,0xb6,0xfd,0xd1,0xb6,0x65,0xeb,0x93,0x33,0x8f,0x9f,0xea,0xbc,0xc3,0x38,0x1b,0xf3,0xe6,0x31,0x89,0xbe,0x4f,0x20,0x10,0x1c,0x17,0x88,0x5,0x58,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x4e,0x28,0x36,0x4e,0xa6,0x2e,0x46,0xf5,0xdb,0x48,0x65,0xb0,0x6d,0xd6,0xb3,0x2a,0x2d,0xd9,0x19,0x43,0xb2,0xed,0x3a,0xcb,0xea,0x34,0xef,0x3d,0x28,0xad,0xab,0xb4,0x41,0xf0,0x1e,0x9f,0xba,0xf5,0x2e,0x7c,0xfd,0xa1,0x6f,0xc1,0x1f,0x95,0xcd,0xf7,0x3c,0xf1,0xd0,0x37,0xbf,0x8d,0xdf,0xfb,0xc3,0xbf,0x40,0x0,0x60,0x87,0x1e,0xeb,0xe5,0x21,0xb4,0x52,0x38,0x38,0xfb,0xc,0x96,0xfb,0xe7,0xb8,0x21,0x77,0xb9,0xbf,0x65,0x4d,0xce,0xd4,0x63,0x3b,0x6c,0xc0,0x7a,0x79,0x50,0xa,0x4c,0x96,0xfb,0x67,0xe0,0x2c,0xdb,0x6c,0xbd,0xf,0xf8,0xb3,0x9b,0xbf,0x88,0x2f,0xde,0xfd,0xc0,0x56,0x62,0xea,0x9a,0xab,0xaf,0xc4,0xbf,0xfc,0x4f,0x7f,0x19,0xd7,0x5f,0x75,0x29,0x8c,0x69,0x41,0x44,0xc5,0xbe,0x9c,0xed,0xc3,0x4a,0x2b,0xb6,0x0,0xc7,0x88,0x9f,0x79,0xf7,0x9b,0xb1,0xe8,0xda,0x8d,0xed,0x7c,0xf3,0x5b,0xf,0xe3,0x4b,0x5f,0xfd,0x1a,0xd6,0xab,0xc3,0x94,0xbf,0x18,0xe1,0xec,0x90,0x32,0x5,0x9,0xce,0xe,0x58,0x1e,0x9c,0xe3,0x72,0x93,0x94,0x33,0x48,0x8a,0x4b,0x56,0x22,0x58,0x79,0x99,0xf3,0x18,0x73,0xb1,0x44,0x6e,0x41,0x8e,0x21,0x35,0x1,0xa7,0xd7,0x95,0x73,0x19,0x15,0x42,0x88,0xc5,0xd2,0x1b,0xb2,0xea,0x2f,0x91,0x57,0x63,0xbe,0x5f,0x39,0x29,0xca,0x39,0x91,0x89,0xbf,0x51,0xc5,0x87,0x49,0x4b,0x70,0xac,0x5a,0x6e,0x6b,0xae,0x6d,0x5b,0xe1,0xc5,0xf3,0x53,0xfa,0x6d,0x53,0xe6,0x6d,0x3f,0x7f,0x8f,0x62,0x9a,0x47,0xf2,0x6f,0x6c,0x2,0xae,0x73,0x2e,0x63,0xb1,0x20,0x27,0x22,0xaf,0xcc,0xc2,0xb8,0xcd,0x58,0xff,0x5d,0xec,0xd0,0xe7,0x39,0xa6,0x23,0xed,0xcb,0x98,0xee,0x5f,0x20,0x10,0x8,0x5e,0xe2,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x46,0x88,0xc1,0x63,0x52,0xcc,0x10,0xb2,0x95,0xb4,0x5e,0x6a,0xfc,0x85,0x8b,0x41,0x4c,0xb2,0xff,0x56,0x76,0x51,0x1a,0x15,0x64,0x21,0x78,0x28,0xad,0xf1,0xfd,0x27,0xcf,0xe0,0x7f,0xfc,0x3f,0xfe,0xc,0x7f,0xf2,0x97,0x37,0xe3,0x99,0x67,0xcf,0xfe,0xd0,0x63,0x74,0xde,0xe3,0xce,0xaf,0xdc,0x87,0xff,0xf9,0xf,0xfe,0x23,0x56,0x36,0xa6,0x8c,0x3b,0x5,0xad,0x35,0xe,0xf,0x98,0xf8,0x8b,0x60,0xcb,0x2b,0x69,0xbd,0xed,0x28,0x27,0x8d,0xc3,0x4d,0xb7,0x80,0xb7,0x3,0x62,0x8,0xd8,0x3b,0x75,0x9a,0x6d,0xc1,0x76,0xc0,0xd0,0xaf,0x71,0xee,0xdc,0x59,0xfc,0xfe,0x1f,0x7f,0x2,0x5f,0xb8,0xf3,0x9e,0xad,0xc9,0x70,0xd7,0x5d,0x77,0x2d,0xfe,0xd5,0x6f,0xff,0x13,0x5c,0x79,0xfa,0x4,0x4c,0xcb,0xf9,0x84,0x85,0xf8,0x4c,0x6a,0x3e,0xef,0x2c,0x2e,0x3b,0xb5,0x87,0xb7,0xdd,0xf8,0xea,0x8d,0xf5,0xbd,0xf,0xb8,0xf9,0x73,0x5f,0x2a,0xad,0xba,0xcb,0x83,0x73,0xe8,0xd7,0x4b,0x26,0xed,0xbc,0x2f,0x2d,0xc3,0xa6,0x69,0x93,0x1d,0x38,0x20,0x78,0x87,0xa6,0x5d,0xa4,0x82,0xf,0x3,0x9b,0xf2,0x0,0x6b,0xf2,0x49,0x69,0xcd,0xea,0x3c,0x95,0xf3,0xe7,0xb2,0x8a,0x33,0x65,0x3b,0x12,0xa,0x59,0xa6,0x92,0xc5,0x9b,0x40,0x25,0x3b,0x30,0xab,0x3d,0xc7,0x46,0xde,0x51,0x15,0x9a,0xe7,0x30,0xd6,0xb9,0x77,0xf5,0xdf,0x95,0x60,0x6e,0x3a,0xed,0x3f,0x44,0xb6,0xde,0x4,0xcf,0x81,0x38,0x4e,0x44,0xe6,0x91,0xfb,0x8a,0x53,0x9b,0x6f,0x51,0x5,0x56,0xea,0xd6,0x62,0xa1,0xae,0x56,0x19,0x6b,0x3c,0xea,0xcc,0xc2,0x78,0x41,0x5d,0x62,0x3c,0xe2,0xb8,0xa6,0x4,0xa3,0x40,0x20,0x10,0xbc,0xf4,0x21,0x16,0x60,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x38,0x81,0x54,0xc9,0x88,0xe3,0xdf,0x39,0xcf,0x2c,0x4,0x2e,0xa4,0x0,0x11,0x5b,0x66,0x3d,0xe7,0x1,0x72,0xb9,0x7,0x93,0x70,0x6d,0xb7,0x48,0x19,0x75,0x36,0x11,0x49,0x6c,0x33,0xd5,0xa6,0x61,0x32,0xe,0x1,0xaa,0x69,0x71,0xcb,0x97,0x1e,0xc0,0x17,0xef,0xfd,0x26,0xde,0xf7,0x8e,0x37,0xe2,0x5d,0x6f,0x7f,0x13,0xae,0xbc,0xfc,0x52,0xb4,0x6d,0x73,0xc1,0xa1,0x39,0xe7,0xf1,0xfd,0xc7,0x9e,0xc0,0xcd,0x9f,0xbb,0x13,0x5f,0xbc,0xef,0x9b,0x0,0x0,0x6d,0xc,0x16,0x3b,0xbb,0x18,0xfa,0xa4,0x8c,0xf3,0x1e,0x3e,0x78,0xac,0xe,0xf6,0xa1,0xb4,0x82,0x1b,0xfa,0xcd,0x43,0x24,0x42,0xf0,0x36,0x29,0xf6,0x3c,0x9c,0x1d,0xa,0xa9,0x73,0xf6,0x99,0x27,0x71,0xea,0xf4,0xe5,0x9c,0x97,0xe7,0x93,0x42,0x2e,0x46,0xfc,0x6f,0xff,0xf6,0x2f,0x10,0x63,0xc4,0x4f,0xbe,0xf3,0x6d,0x1b,0xaa,0xad,0x97,0x5d,0x7d,0x25,0x7e,0xf7,0x5f,0x7c,0xc,0xff,0xe7,0x7f,0xf8,0x4,0xbe,0xf1,0x9d,0xc7,0xb,0xa9,0xe4,0xbd,0xe3,0xa2,0x90,0x18,0xf1,0xbe,0x9b,0xde,0x80,0xbd,0xdd,0x9d,0x8d,0xb1,0x3c,0xf2,0xdd,0xef,0xe1,0xf3,0x77,0x3d,0xc0,0x84,0x65,0x6a,0x53,0x76,0xd6,0x22,0x86,0x80,0xa6,0x5b,0xf0,0xf8,0x9,0x18,0xd6,0x2b,0x38,0x67,0x81,0x18,0xb8,0x60,0xc4,0xd,0x50,0x4a,0x41,0x25,0xeb,0x2f,0xdb,0x86,0x1b,0x28,0xa5,0x4b,0x9e,0xdd,0xa8,0xe4,0xe4,0xe6,0x5e,0x45,0x48,0x99,0x8e,0x54,0xa9,0xf7,0x80,0x18,0x3d,0x88,0x14,0x22,0xc2,0x86,0x35,0x97,0xcb,0x5d,0x46,0x55,0x5c,0xb1,0xbe,0x52,0x56,0x3,0x2,0x1b,0x2d,0xbc,0xf1,0x87,0x6d,0xe5,0x9d,0x48,0x6,0xb7,0x14,0x64,0xd0,0x64,0x7c,0xf3,0xbf,0xf3,0x6b,0x5b,0xd6,0xad,0xf2,0x7,0x8b,0x82,0xf,0x0,0xcd,0x89,0xbb,0xb4,0x7c,0x4c,0xb9,0x95,0xf1,0x8,0x66,0x8e,0x30,0xd7,0x45,0x3e,0x97,0xa3,0xdc,0x4e,0x11,0x8e,0x24,0x62,0x90,0xf7,0x1c,0x81,0x40,0x70,0x51,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x98,0x81,0x94,0xae,0xc8,0x23,0x26,0x9c,0x48,0x29,0x4,0xef,0xa0,0xc8,0x30,0xb1,0x65,0x1a,0x38,0x37,0x70,0xcb,0xaf,0xf7,0x30,0xa6,0x49,0x4d,0xc1,0x48,0x8f,0x39,0xd8,0x44,0xac,0x4,0xef,0xa1,0x9b,0x6,0xda,0x18,0xf8,0xd4,0xca,0x7b,0x8,0xe0,0xaf,0x3e,0x73,0x27,0x3e,0xf5,0x85,0x7b,0x71,0xd5,0xa5,0x27,0xf1,0xd6,0x37,0xbe,0x6,0xd7,0xbf,0xec,0x72,0x5c,0x76,0xfa,0x14,0xf6,0x76,0x17,0xd0,0x49,0x3d,0x37,0xc,0x3,0xce,0xec,0x1f,0xe0,0xd1,0xc7,0x9f,0xc6,0x57,0xee,0xff,0x26,0xbe,0xf3,0xc4,0x19,0x38,0xe7,0x60,0x4c,0x9b,0xa,0x3b,0x5c,0x69,0x28,0x76,0x36,0x42,0x69,0x3,0xbf,0x5e,0x21,0x4,0xf,0xd3,0x34,0xb8,0xfb,0xbe,0x7,0x81,0x3f,0xfa,0x33,0x44,0x44,0x6e,0xc8,0x35,0xd,0x62,0xf0,0xf8,0xf6,0xf7,0x9e,0x40,0xbf,0x5e,0xc1,0xdb,0x1,0xc3,0x7a,0x9,0x6d,0x1a,0xf4,0xab,0x25,0x88,0x14,0x13,0x6d,0x44,0xc0,0xd0,0xa7,0xc7,0xf,0xd1,0x74,0xb,0xfc,0xde,0x1f,0xfc,0x29,0xee,0xb9,0xef,0xeb,0xe8,0xda,0xa6,0x58,0x6f,0x95,0xd2,0xa9,0xfd,0x18,0x70,0xd6,0xb2,0xe5,0x57,0x8f,0x97,0x49,0x31,0x6,0xec,0x76,0x6,0x6f,0xbb,0xf1,0x55,0x1b,0xf3,0x1c,0x42,0xc4,0x5f,0xdf,0x72,0x3b,0x93,0x8d,0x49,0x35,0xc9,0x63,0x20,0xb4,0x8b,0x1d,0xc4,0x18,0xe1,0x9c,0xc5,0xd0,0xaf,0x99,0x50,0xb4,0x3,0xef,0x43,0x29,0xc0,0x18,0xb4,0xdd,0xa2,0x34,0xfe,0x2a,0xad,0xc1,0xc5,0x1e,0x4c,0xd2,0x95,0xa2,0x89,0x64,0xcf,0xa5,0x94,0xd1,0x98,0x5b,0x99,0xa9,0x22,0xbc,0x6a,0x22,0xd,0xb9,0xe8,0x23,0x33,0x61,0x95,0x42,0x8e,0x9d,0xb0,0x21,0x1f,0xd8,0x36,0x5d,0x1b,0x7e,0x58,0x4d,0xdb,0x9c,0xd0,0xcb,0xe4,0x5f,0x2c,0x65,0x32,0x55,0xae,0x64,0xbd,0xec,0x11,0xdb,0xa9,0x87,0x13,0xe7,0x56,0xdf,0xbc,0x6c,0xfd,0x77,0xd5,0x5e,0x7c,0xe4,0x18,0x7f,0xa8,0x23,0xdc,0x56,0x28,0x52,0x8f,0x57,0xde,0x6f,0x4,0x2,0xc1,0xc5,0x1,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0x63,0x84,0x69,0x89,0x41,0x2c,0xb6,0xd1,0x6c,0x7,0xe,0xd1,0x25,0x7b,0x6d,0x0,0x51,0xb6,0xd7,0x12,0x42,0xc,0x20,0x70,0x99,0x4,0x92,0x52,0x4c,0x25,0x22,0x8c,0x6d,0xa8,0x91,0x33,0x3,0x15,0xff,0xee,0x9c,0x85,0xd6,0x6,0x21,0x44,0x7c,0xef,0xb1,0xa7,0xf0,0xd8,0xd3,0xe7,0x8a,0x12,0xab,0xeb,0x3a,0x10,0x71,0x1,0x86,0xf,0x1e,0x4d,0xd3,0xc1,0x7b,0xf,0xa5,0x98,0x4c,0x8c,0x31,0x22,0xc2,0x43,0x91,0x42,0xd7,0xed,0xe0,0x60,0xff,0xc,0x94,0xd2,0xd0,0xa6,0xc1,0x7a,0xb9,0xf,0xad,0x99,0xa4,0xf4,0xce,0xe1,0x91,0xef,0x3f,0x86,0x87,0xbe,0xf5,0x30,0x2e,0xbb,0xf2,0x1a,0x34,0x6d,0xc7,0x6d,0xbc,0x9e,0x2d,0xc9,0xde,0x71,0x1e,0x1e,0x88,0x92,0xa,0x90,0xc9,0x2d,0xef,0x1d,0xda,0x76,0x81,0x8,0xa0,0x5f,0x2f,0xd1,0x34,0x2d,0x6c,0xdf,0x63,0xe5,0x6,0xfc,0xcd,0xed,0x77,0x23,0x4,0x8f,0x6e,0xb1,0xcb,0xb6,0x63,0xd3,0xa0,0xed,0x16,0x85,0x84,0x6c,0xda,0x45,0x22,0x4,0x23,0x9c,0x65,0xb5,0xdd,0x7b,0xde,0x76,0x23,0x2e,0x3d,0x7d,0x6a,0x63,0xae,0x1f,0x7d,0xec,0x9,0xdc,0xf5,0xc0,0xb7,0x61,0x4c,0x3,0xef,0x1c,0xfa,0xe5,0x12,0xd6,0xf6,0xa5,0xd8,0x83,0xb3,0x8,0x3,0x9c,0x1d,0xe0,0x9d,0x1d,0xb3,0x9,0xad,0x45,0xbb,0xd8,0x2d,0xc7,0x5c,0x5e,0xbb,0x62,0x39,0x76,0x55,0xb6,0x9f,0xc2,0x28,0x8a,0x53,0x88,0xb1,0x52,0x64,0x16,0x4e,0x6c,0x93,0x7c,0xab,0x33,0x5,0x33,0xe9,0xb6,0x99,0xd9,0x57,0x18,0xb6,0xaa,0x45,0x77,0x13,0x35,0xb9,0x78,0x94,0xca,0x6f,0x5e,0x1c,0x93,0x9f,0x27,0xd4,0x82,0xbe,0x69,0xf3,0x70,0xd9,0x63,0xa5,0xfe,0x8b,0x55,0x6,0x60,0x9c,0xe,0x62,0x6c,0x23,0x7e,0x1,0xac,0xdb,0x7c,0x9b,0xa8,0xc8,0xc9,0x29,0x45,0x78,0x4,0xf1,0x27,0xbe,0x5f,0x81,0x40,0x70,0x91,0x42,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x18,0xc1,0x3b,0x5b,0xe5,0xa4,0x85,0xd2,0x2,0x1c,0x2,0x97,0x7a,0x28,0xa5,0xe1,0x9d,0x4d,0x44,0x4a,0x80,0x52,0x66,0x6c,0xc,0xe,0x1,0xca,0x70,0xe1,0x7,0x67,0xd6,0x39,0x10,0x8,0x44,0x26,0x59,0x5c,0x7,0x44,0x6d,0x0,0x97,0x8,0xae,0x38,0x40,0x1b,0x56,0x6,0xc6,0xa4,0x32,0x8c,0x31,0x60,0xbd,0x5e,0x21,0x86,0x8,0x63,0x9a,0xd2,0x5a,0xcb,0xc5,0x23,0x94,0xf6,0xcd,0xd6,0xd7,0x88,0x0,0x6b,0x7,0x34,0xd,0x93,0x7a,0xa4,0x8,0x4d,0xbb,0xc0,0xd0,0xaf,0xf8,0x60,0x88,0xb0,0x3a,0x38,0x87,0xc5,0xde,0xc9,0xf2,0x58,0x2e,0xac,0xd0,0x91,0x95,0x7b,0xc3,0x7a,0x5,0xdb,0xaf,0x11,0x63,0x44,0xbf,0x5e,0x55,0x16,0xdc,0xd4,0xae,0x4b,0x8a,0x7f,0x47,0xe4,0xd6,0xdc,0x10,0x61,0x9a,0x6,0x43,0xbf,0xc6,0x62,0x67,0x2f,0xd9,0x89,0x43,0x29,0xfb,0x8,0xc1,0x3,0xe0,0x16,0x5e,0xa5,0x14,0x16,0x6d,0x83,0x77,0xbf,0xed,0xd,0x5b,0xdb,0x67,0x3f,0x77,0xc7,0x57,0xe0,0x52,0x49,0x87,0x4a,0x8d,0xca,0x4,0x26,0x47,0xfb,0xf5,0x32,0xe5,0x2b,0xf2,0x7c,0xe7,0x72,0xe,0x52,0x1a,0x8a,0x4c,0xc9,0xea,0xd3,0xc6,0x40,0xeb,0xa6,0x64,0xfa,0x31,0x41,0x1a,0xf8,0xf5,0x2b,0x56,0xdf,0xb1,0xa0,0x43,0xa5,0xf2,0x13,0xaa,0x8a,0x50,0xb2,0x1d,0x58,0xa9,0x54,0x2,0x12,0xd2,0xfa,0x55,0x16,0xe4,0x64,0xfc,0x13,0x9f,0x2c,0x5d,0xb0,0x9b,0x83,0x68,0x96,0x11,0x38,0x9d,0x88,0xa9,0x5d,0x37,0x6f,0x1f,0x23,0x4f,0x36,0xc9,0xdd,0xc3,0x54,0xb9,0x57,0xd3,0x8e,0x13,0x52,0x70,0xbe,0x9b,0x6a,0x99,0xe7,0x8e,0xb,0x24,0xfc,0x6d,0x6b,0x7,0x2e,0xa4,0x60,0xb5,0xd7,0x58,0x2d,0x3b,0x61,0x0,0xa5,0x4,0x44,0x20,0x10,0x5c,0x3c,0x90,0x12,0x10,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x18,0x81,0x74,0x22,0xf4,0x12,0x89,0x44,0xa4,0xc6,0xf2,0x88,0x44,0x42,0x29,0xad,0x4b,0x49,0x5,0xb7,0xde,0xb2,0x32,0x8f,0xc9,0x25,0x26,0xb,0xed,0xd0,0x23,0xf8,0x80,0x8,0xc0,0xb9,0x1,0xde,0xbb,0x8a,0x5c,0x62,0x2b,0x69,0xc,0xdc,0x76,0xeb,0x2c,0xdb,0x82,0x9d,0x1d,0x10,0x7c,0x48,0x76,0x55,0x8f,0x7e,0xbd,0x84,0x1d,0x7a,0x5e,0x37,0xf0,0xfe,0x72,0xb6,0x9e,0x1d,0x7a,0x78,0xe7,0x10,0xab,0x6,0xdb,0x4c,0xbe,0xc4,0xa4,0xa0,0x5b,0x2f,0xf,0x40,0x4a,0x71,0xa3,0xee,0xd0,0xc3,0x27,0x62,0x2d,0x4,0xf,0xef,0x98,0x54,0xf4,0xc1,0x43,0xe9,0xb1,0x48,0xc3,0xd,0x7d,0xc9,0xdd,0x73,0x6e,0x48,0x8a,0x46,0x26,0x37,0x63,0x8c,0xb0,0xc3,0x1a,0xce,0xe,0x68,0x52,0x29,0x7,0xe5,0x2,0xd,0xa5,0x99,0xa8,0xf4,0xae,0xb4,0xf2,0xc6,0x10,0x70,0xd3,0xeb,0xaf,0xc7,0x15,0x97,0x5f,0xba,0x31,0xcf,0x4f,0x3d,0xfd,0x2c,0xbe,0x74,0xff,0xc3,0x68,0xda,0xe,0x4a,0x69,0xd8,0xa1,0x67,0xb2,0x2f,0xcd,0x93,0x77,0xae,0x34,0x1b,0x33,0xc9,0xe8,0xa0,0x94,0x86,0x1b,0xfa,0x42,0x80,0x6a,0x63,0xa,0x11,0xe7,0x9d,0x4b,0x85,0x1d,0xb9,0x7d,0x58,0x33,0x85,0x1b,0x7c,0x51,0xbe,0xd5,0xa5,0x1e,0x31,0x6,0xf8,0xe0,0xb,0x21,0x9a,0x15,0x76,0x99,0x9a,0xca,0xed,0xcf,0x54,0x59,0x71,0xd3,0x19,0x2,0xa4,0x1c,0x41,0xc6,0x96,0xd6,0xdd,0xaa,0x29,0xb7,0x6e,0x8,0x9e,0x23,0x5b,0x8d,0x63,0x45,0xfe,0x95,0xd2,0x91,0x44,0x3a,0xe6,0x31,0xd3,0x8c,0x14,0x9c,0x6c,0x63,0xeb,0xef,0x3f,0xac,0xcc,0x2e,0x5e,0x60,0x2f,0x5b,0xc,0xc4,0x59,0xdd,0x38,0x23,0xfa,0x6a,0x8e,0x74,0x73,0x9e,0x62,0xb1,0x27,0xb,0x4,0x2,0xc1,0xc5,0x0,0x51,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0x8,0xd1,0x7b,0x80,0xd4,0x58,0xf2,0x50,0x17,0x3e,0x0,0xdc,0xb8,0xab,0x39,0x23,0x90,0x94,0x62,0x82,0xcd,0x59,0xce,0x0,0x4c,0xe4,0x13,0x5b,0x7b,0x3,0x40,0xac,0x28,0x34,0xa6,0x45,0x4c,0xea,0x34,0xd5,0x6a,0x38,0x67,0x79,0xd9,0xc8,0x44,0x95,0x52,0x1a,0x36,0x84,0xb2,0x9d,0xa1,0x5f,0xa1,0x69,0xda,0x94,0x3b,0xc8,0x64,0x1d,0x90,0x1a,0x8a,0x33,0x11,0x89,0x88,0x61,0x58,0x27,0x45,0x22,0x2b,0x9,0x33,0x59,0xa9,0x8d,0xc1,0xb0,0x5e,0x17,0x8e,0xc6,0x3b,0x7,0xa7,0x2d,0xac,0xe5,0xcc,0x42,0x63,0x1a,0x38,0x3b,0x40,0x6b,0xc3,0x8a,0x3b,0xdb,0x23,0xc6,0x88,0x83,0xb3,0xcf,0xb0,0x25,0xd8,0x59,0x74,0x40,0xd9,0x56,0xb6,0xd5,0xf6,0xab,0xc3,0x44,0x26,0xe,0xf0,0xce,0xa1,0xe9,0x3a,0x84,0xe0,0xb1,0xb3,0x77,0x12,0x2a,0xea,0x9,0x49,0xa,0x10,0x14,0x1,0x1f,0x7c,0xcf,0xdb,0xb7,0xaa,0xbc,0x6e,0xfd,0xe2,0x57,0x70,0xb8,0x5c,0xc1,0x7b,0x56,0xc,0x32,0x61,0x79,0x58,0xe6,0x76,0xbd,0x3a,0x4c,0xc7,0xcc,0x84,0xab,0xb3,0x7c,0x8c,0x4d,0xb7,0x60,0xcb,0xb1,0xf7,0x40,0xc3,0x56,0xeb,0x9c,0x19,0x98,0x4b,0x57,0x22,0x72,0x1e,0xa1,0x4e,0xc5,0x2d,0xd8,0x50,0xa9,0x91,0x52,0x89,0x83,0xca,0xd,0xbf,0xe9,0xb1,0x44,0xd0,0x66,0x25,0x63,0xb1,0x7,0x87,0x90,0x48,0xd6,0x30,0x92,0x76,0xb3,0xbc,0xbe,0x4c,0x7a,0xd5,0x8a,0xbd,0x5a,0xc,0x17,0x31,0x2a,0xf4,0xa8,0x94,0x88,0x54,0xe5,0x1d,0x69,0x6c,0x69,0xf1,0x62,0x1,0x9e,0x2b,0x0,0x8f,0x38,0x73,0x31,0x55,0xeb,0xd1,0x11,0x8f,0x9f,0x6f,0x9d,0xbc,0xde,0xb6,0x76,0xe3,0x38,0xdd,0x66,0x2e,0x3f,0xa9,0x89,0x67,0x9e,0xc9,0xb1,0x3f,0xa7,0xde,0x4d,0xbd,0xd7,0x38,0xce,0x47,0x26,0xc4,0x5,0x2,0x81,0xe0,0xa5,0xe,0x51,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0x8,0x31,0x78,0x44,0xef,0x58,0xa1,0x87,0x51,0xc5,0x15,0xbc,0x47,0xc,0x1,0xa6,0x6d,0x27,0xea,0xac,0x5c,0x0,0xe2,0x9c,0x2d,0x16,0x59,0xdb,0xf7,0xc5,0x8e,0x1a,0x2,0xdb,0x74,0x63,0x52,0x8d,0x45,0x44,0x26,0xb9,0xc2,0xa8,0xb4,0x1a,0xfa,0x15,0x2f,0xeb,0x3d,0x86,0x7e,0x5,0xa5,0xd4,0xa8,0x18,0x8c,0x31,0xe5,0xdf,0xd,0x79,0x80,0x6c,0x89,0xd,0x21,0xed,0xc3,0xc1,0xda,0xbe,0xd8,0x94,0xb3,0xb2,0x90,0x14,0x5b,0x5c,0xad,0x1d,0xb0,0x5e,0x1e,0x94,0x1c,0xbd,0xbc,0x3d,0x22,0xb6,0xbf,0x82,0x80,0xb6,0x63,0xf2,0xac,0xed,0x16,0xd0,0x4a,0xb3,0x7d,0xd9,0xfb,0x62,0x8f,0xcd,0xa,0x3b,0x6d,0x1a,0x6e,0x41,0x56,0xa,0x67,0x9f,0x7d,0x12,0x76,0x60,0xc5,0xa2,0x1d,0x7a,0xb6,0x11,0x27,0xd2,0xcc,0x27,0x65,0xe4,0xdb,0x5e,0x77,0x3d,0xae,0xba,0xe2,0xf2,0x8d,0x39,0x7e,0xf6,0xec,0x39,0x7c,0xfe,0xae,0xaf,0x55,0xe4,0x97,0x2,0x81,0x55,0x77,0x39,0x97,0x30,0x67,0xff,0x29,0xad,0xb1,0x3c,0x38,0x7,0x0,0xe5,0xf8,0x9c,0x1d,0x12,0xe1,0xc7,0xeb,0x98,0xa6,0x2d,0x73,0xc4,0xf6,0x5e,0x8c,0xa4,0x1d,0xb2,0xa,0xf,0xa5,0xd4,0x83,0xb7,0x15,0xc6,0x42,0x8f,0x6c,0xf5,0xd,0x63,0xc1,0x47,0x29,0x12,0xa9,0x1f,0xc7,0x94,0xcb,0xaa,0x89,0xcd,0xbc,0x8f,0x6c,0xe1,0xad,0x15,0x7b,0x13,0xfe,0xab,0x22,0xfe,0x26,0x7a,0xb8,0xad,0x19,0x83,0xa3,0x4a,0xf0,0x3c,0x67,0xec,0x5,0xce,0x68,0x3a,0xff,0x73,0x1b,0xaa,0xbc,0x8a,0xe8,0x1b,0x6b,0x92,0x37,0x77,0x39,0x86,0x11,0x96,0x82,0x94,0x22,0xf4,0xdb,0x32,0xba,0xc9,0x3c,0xd0,0xf6,0x39,0x14,0x8,0x4,0x82,0x97,0x32,0x44,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x1c,0x23,0x50,0xb1,0x7e,0xa6,0xbf,0x41,0x50,0x5a,0xc1,0xc7,0x50,0x6c,0xb8,0x11,0x49,0x99,0x96,0x96,0xf5,0xde,0x25,0xd2,0xce,0x43,0x6b,0xd,0xd2,0xb9,0x34,0xc4,0x43,0x29,0xd,0xc4,0x80,0x91,0x5b,0x62,0xf2,0xb0,0x69,0xbb,0xd4,0xe2,0xdb,0x73,0xe1,0xc7,0xb0,0x46,0xf0,0xac,0xf4,0xb3,0x3,0x3f,0x66,0x9a,0x16,0x4a,0x1b,0x4,0xef,0x46,0x35,0xa0,0xb7,0x68,0xbb,0x9d,0x94,0xf9,0xc7,0xf6,0x5e,0xa5,0xc,0x86,0xbe,0xe7,0x46,0xde,0x64,0xd5,0x3d,0xdc,0x3f,0x5b,0x8a,0x2b,0x9c,0x1b,0x92,0x8a,0xcf,0x16,0x42,0x4f,0x79,0x57,0x14,0x72,0xcb,0xc3,0x7d,0x1c,0x9c,0x7d,0x86,0xd5,0x84,0xc1,0xa3,0x3,0xb0,0xd8,0xd9,0xe3,0x62,0x93,0x52,0x68,0xa2,0x1,0x68,0x18,0xd3,0x42,0x69,0xd,0x9d,0x6c,0xc3,0xdd,0x62,0x17,0xc3,0x6a,0x5,0x2c,0x58,0xc5,0xa7,0xb5,0x82,0xd2,0x1a,0x4d,0xd3,0xe2,0xef,0xbd,0xef,0x26,0x28,0xb5,0x49,0xf0,0xdc,0x79,0xf7,0xfd,0x38,0xb7,0xb2,0xb0,0x36,0x1f,0x67,0x83,0xa1,0x67,0x4b,0xaf,0x69,0x1a,0xac,0xe,0xf6,0xd3,0x1c,0x28,0xac,0x96,0x7,0xe8,0x57,0x87,0xbc,0x6d,0x52,0xd0,0x4d,0xc3,0xd9,0x80,0x4a,0x41,0x25,0xbb,0x76,0x26,0x57,0xb5,0x6e,0x4a,0x1,0x9,0xe7,0xfd,0xe9,0xd,0x95,0x59,0x69,0xd1,0x55,0x2a,0x71,0x57,0x54,0x65,0x6,0xd6,0xa3,0x8c,0x85,0xa8,0xab,0x73,0xf9,0xb6,0x61,0x9e,0xcf,0xc7,0x44,0x58,0x9c,0x14,0x6e,0xfc,0x70,0x19,0x7c,0x47,0xad,0x53,0x33,0x70,0x17,0x22,0x7,0x6b,0x7b,0x2e,0x36,0x7f,0xdf,0x96,0x3f,0xb8,0x6d,0x8c,0xb1,0x3e,0xa,0x4c,0xe3,0xfd,0x62,0x25,0xf9,0x8b,0x93,0xa7,0x37,0x34,0x89,0x71,0xc6,0x10,0x8a,0x1,0x58,0x20,0x10,0x5c,0x2c,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x4e,0xa0,0x2a,0x87,0xad,0xa8,0xc7,0x12,0x11,0xa6,0x98,0xd8,0x53,0x44,0x8,0x59,0xb1,0x15,0x63,0x21,0xa2,0xea,0xdc,0xb8,0x5c,0x8c,0x81,0x18,0x8b,0x2a,0x4d,0xa5,0xf5,0x43,0x8,0x40,0x52,0xf4,0x5,0xef,0x4b,0x9,0x48,0x48,0xb9,0x79,0x79,0x99,0x10,0x2,0x93,0x80,0x4a,0xa7,0xed,0x30,0x51,0x65,0x7,0xb6,0xec,0x6a,0xad,0xe1,0xac,0x85,0x69,0xb8,0x45,0x77,0xd5,0xaf,0x38,0x7f,0xb0,0xef,0x13,0x41,0xa9,0x11,0xa3,0x2f,0x64,0x64,0x8c,0x26,0x3d,0xc6,0x74,0x4f,0xf0,0x1,0xab,0xe5,0x1,0xec,0xd0,0x43,0x37,0x2d,0xbc,0xb5,0x29,0xbb,0xd0,0xa3,0xed,0x16,0xa9,0xd1,0x37,0x42,0x29,0x26,0xe9,0x72,0x1,0x48,0x4c,0xd6,0xe5,0x18,0x3,0xec,0xb0,0x46,0xf0,0x1e,0x4d,0xdb,0x61,0x75,0x78,0x80,0xb6,0xeb,0xd0,0xb4,0xb,0xbc,0xf9,0xd5,0xd7,0xe2,0xba,0x6b,0xae,0xde,0x98,0xde,0xc3,0xe5,0xa,0xb7,0xdc,0x71,0x6f,0x2a,0xfc,0x60,0x22,0xd5,0x27,0xe2,0x53,0x69,0x83,0xa6,0xe9,0x30,0x98,0x15,0xdc,0x21,0x67,0x23,0x86,0xc0,0x85,0x2a,0x43,0xbf,0xc6,0x62,0x77,0xf,0x31,0x4,0xe8,0xa6,0x4d,0x73,0xe1,0x4b,0xa9,0x47,0x8c,0x59,0x21,0xc8,0xf6,0xe8,0x9c,0x4d,0x88,0x80,0x42,0x62,0xe6,0x2c,0xc1,0x9c,0x93,0x58,0x32,0xf6,0x42,0x9c,0x90,0x57,0x54,0xe7,0xf2,0xa5,0xe6,0xe0,0x8d,0xa6,0x5d,0x54,0x6a,0x3f,0x60,0xd2,0xb0,0x1b,0x67,0xe4,0xdf,0xe4,0xf4,0x7a,0x81,0x2d,0xbc,0x18,0xf7,0x5c,0x21,0x13,0x7a,0xdb,0x68,0xb7,0x8d,0xaa,0x90,0xd9,0x53,0x73,0xab,0xf2,0xd1,0x63,0xdb,0xd6,0x81,0x3c,0xd9,0x53,0x9c,0x3e,0x37,0xee,0xb1,0x98,0x83,0x9f,0xc3,0x56,0x5,0x2,0x81,0xe0,0xa5,0x9,0xb1,0x0,0xb,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0xec,0x2b,0xfe,0xb4,0xb5,0x75,0x6c,0x2a,0xcd,0x7f,0x87,0x10,0xc0,0xd1,0x6f,0x94,0x94,0x64,0xa3,0x95,0xb5,0x10,0x79,0x49,0x89,0xe6,0xbd,0x2b,0x8a,0x41,0x26,0xba,0xd8,0x9e,0x6b,0x87,0x3e,0x91,0x7d,0x4c,0xfa,0xb9,0x64,0x13,0x1e,0xfa,0x35,0x96,0x7,0x67,0xb1,0x5e,0xee,0xc3,0x3b,0xb,0xef,0x1d,0x96,0x7,0x67,0x31,0xa4,0x12,0x8f,0x6c,0x3b,0x76,0xd6,0x72,0x7e,0x1e,0x1,0xfd,0x6a,0x59,0x59,0x84,0x59,0x91,0xd8,0xb4,0x1d,0x86,0x7e,0x89,0x18,0x2,0xda,0x6e,0xc1,0xa,0x40,0xef,0xb0,0x5e,0x1d,0xa6,0x12,0x91,0x35,0x37,0xb,0x3b,0xb,0xef,0x1c,0xef,0xcb,0x59,0xf4,0xab,0x65,0xc9,0xd8,0x53,0x4a,0x25,0x92,0x4c,0xa1,0x69,0x3a,0x34,0x6d,0x8b,0x6e,0xb1,0xb,0x4a,0xb6,0xe1,0x18,0x23,0xce,0x3d,0xfb,0x14,0x7c,0xf0,0xac,0x66,0x74,0xb6,0x90,0x40,0x7f,0xef,0xbd,0x37,0x41,0x6b,0xbd,0x31,0xbb,0x5f,0xbe,0xe7,0x1,0x3c,0x75,0xe6,0xa0,0x94,0xa7,0x78,0xcf,0x8d,0xbc,0xa6,0x69,0xd1,0x34,0x2d,0x2b,0xff,0x12,0x91,0x1a,0x92,0x82,0xb2,0xe9,0x16,0x20,0x2,0x9a,0xb6,0x43,0xdb,0xed,0xc0,0x34,0x6d,0x69,0xf4,0xcd,0xf3,0x4f,0x8a,0xca,0xbc,0x73,0xf3,0x32,0x46,0x35,0x5a,0x21,0x73,0x43,0xc9,0xfe,0xcb,0x59,0x83,0x21,0x59,0xbd,0xc7,0xe5,0x90,0xc8,0xc5,0xac,0x16,0xc,0x25,0xaf,0x2f,0x2f,0x43,0x95,0xc5,0x17,0x95,0x95,0x77,0xa2,0x4,0xac,0x7e,0xae,0xc5,0x83,0xcf,0x89,0xfc,0x8b,0x73,0xe3,0xec,0xec,0x4f,0xfd,0xfc,0x5c,0x7d,0x57,0x5b,0x9d,0x8b,0xef,0x76,0x46,0xfa,0x6d,0x76,0x71,0x4c,0x9e,0x3e,0xa,0x34,0x5b,0xaa,0x26,0xf8,0xe2,0xec,0xf9,0x58,0x3d,0x43,0x5b,0xf2,0x8,0xf3,0x12,0x21,0x65,0x40,0xa,0x4,0x2,0xc1,0x4b,0x1d,0xa2,0x0,0x14,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x8e,0x11,0x72,0x96,0x5b,0x6e,0x86,0x5,0x50,0x14,0x66,0xb9,0x90,0xa2,0x28,0x9a,0x92,0x5a,0x8f,0x49,0xa5,0x88,0x0,0x56,0x1,0x66,0xab,0xa3,0x52,0x9a,0x73,0xf6,0x22,0x10,0x22,0x93,0x59,0x3e,0x11,0x6b,0x5c,0xe8,0xc1,0x99,0x7a,0xce,0x71,0xb,0xf0,0x30,0xf4,0xe8,0xd7,0x4b,0xc4,0xc8,0x44,0xa0,0xb5,0x3,0xda,0x76,0x1,0x52,0xa9,0xa4,0x82,0x14,0xb4,0x77,0xa9,0xd,0x58,0x61,0x9d,0x2c,0xb4,0x76,0x18,0x92,0x4a,0x51,0xa1,0x5f,0x1d,0xc2,0xe,0x3d,0x9c,0xb3,0x68,0xbb,0x5,0x56,0xcb,0x3,0x74,0x8b,0x5d,0x44,0x44,0x74,0xed,0x2,0xde,0xbb,0x62,0xa1,0xcd,0xc7,0x63,0x1a,0xce,0x30,0x24,0xa5,0x58,0x65,0x17,0x23,0xec,0xd0,0xa3,0x5d,0x2c,0x10,0x42,0xc0,0xee,0x89,0x93,0x9c,0xcd,0x47,0xa,0x11,0x11,0xda,0x34,0x68,0x8d,0xc1,0xb0,0x5e,0x41,0x27,0x75,0x62,0xbf,0x3e,0xe4,0x76,0x5e,0xad,0x71,0xe3,0xab,0xae,0xc1,0x2b,0x5f,0x71,0xed,0xc6,0xdc,0xae,0xd7,0x3d,0x6e,0xbe,0xf5,0x2e,0xb6,0x24,0x83,0x12,0x59,0xc7,0x99,0x81,0xb1,0x52,0x3c,0x5a,0x3b,0x14,0x82,0x31,0x4,0xf,0x6f,0x2d,0xba,0xdd,0x3d,0xce,0x25,0x34,0x1e,0x1a,0x1a,0x4d,0xb7,0x3,0x20,0x72,0xf9,0x4a,0x52,0x46,0x2,0x21,0xf1,0x61,0x1,0x5a,0x1b,0x38,0xc7,0x45,0x20,0xd1,0xa3,0xb0,0x70,0x31,0x59,0xb8,0x43,0xca,0x50,0xa4,0x54,0xf8,0x52,0x67,0xf3,0xd5,0xb6,0xe0,0xdc,0xe,0x3c,0x3f,0x47,0x80,0x69,0x35,0xc6,0x84,0x2,0x8b,0xd3,0xe2,0x98,0xe9,0xea,0x47,0x95,0x72,0xa4,0xc7,0xeb,0xb2,0x92,0x9,0x71,0x56,0xef,0x11,0x18,0x3,0x7,0xb1,0x29,0xea,0xa3,0x2d,0xab,0x10,0x36,0xcb,0x38,0xb6,0x2c,0x72,0x9e,0xc5,0xab,0x65,0xab,0xd2,0x93,0x4a,0x7,0x18,0xe7,0x45,0x21,0xa8,0x9b,0x8b,0xb7,0xa4,0x1,0x46,0xc9,0x0,0x14,0x8,0x4,0x17,0xf,0x84,0x0,0x14,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x8e,0x11,0xd8,0x22,0x9b,0x2c,0x9f,0xa4,0x30,0x52,0x3d,0xa1,0xa8,0x96,0x72,0xdb,0x6d,0xc9,0x4f,0x4b,0x6a,0x34,0x2e,0xe6,0x0,0x7c,0xe0,0x2c,0xc0,0x98,0xac,0xbf,0xd9,0x92,0x4a,0x69,0x99,0xc0,0x1b,0x81,0x77,0xae,0x90,0x70,0x1,0x91,0x1b,0x66,0x63,0xc4,0xe1,0xb9,0x33,0x50,0xda,0x60,0xbd,0x3c,0x80,0xd2,0x6,0xbb,0x7b,0x27,0x31,0xf4,0x6b,0x34,0x4d,0x7,0xd3,0xb6,0xb0,0xfd,0x1a,0x6d,0xb7,0x3,0xef,0x5d,0x2a,0xe7,0x30,0xa5,0x9d,0x97,0xcb,0x40,0xb8,0xfc,0x62,0x79,0x70,0xe,0x3b,0x7b,0x27,0xd1,0x76,0x8b,0xa2,0xc,0x4,0x90,0xd6,0x5f,0xc0,0x7b,0xcf,0xeb,0xd9,0xa1,0xb0,0x54,0x43,0xbf,0x86,0xc9,0x8d,0xc2,0x20,0x84,0xe0,0x52,0xa3,0x31,0x93,0x86,0x26,0xb6,0xd0,0xba,0x81,0x1d,0xd6,0xdc,0xdc,0xeb,0xe,0x11,0xad,0x83,0xf7,0xe,0x6d,0xbb,0xc0,0xd0,0xaf,0xf1,0x73,0x1f,0x78,0x37,0xda,0xa6,0xd9,0x98,0xdb,0xaf,0x3e,0xf0,0x20,0xbe,0xf7,0xf8,0x53,0x20,0xa5,0x13,0x1,0xe8,0xa,0x61,0x45,0xa9,0xcc,0x23,0x84,0x80,0xa6,0x6d,0xd1,0xaf,0x8,0x4d,0xd3,0xc1,0xe,0x6b,0x34,0x5d,0x87,0xa6,0x69,0x61,0xda,0x2e,0xb5,0xfa,0x12,0xbc,0xb7,0x25,0x47,0x31,0xcf,0xfd,0x48,0xdc,0x29,0x38,0xc7,0xa,0x43,0x2e,0x5b,0x41,0x55,0xc2,0x82,0xa4,0x6c,0x54,0xf0,0x8,0xa5,0xb8,0xa4,0x90,0x81,0xe5,0x15,0xa7,0x9,0x79,0xc7,0x2e,0x62,0x6e,0x9,0xde,0x34,0xd5,0xce,0x48,0x3d,0x9a,0x3f,0x1e,0x2b,0x66,0x6e,0x8b,0x7d,0x77,0x6e,0xa6,0xdd,0xe6,0xa5,0x25,0x1c,0x5d,0xc6,0x11,0x67,0xbf,0xc6,0x79,0xfb,0x70,0xe5,0xe,0xc6,0xac,0xc8,0x64,0xcb,0xe6,0xe6,0xcb,0x4c,0x77,0x19,0xb1,0xd9,0xa,0x5c,0x6d,0x6d,0x42,0x4c,0xc6,0x19,0x1b,0x39,0x5b,0x36,0x67,0x10,0xa,0x4,0x2,0xc1,0x45,0x0,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0x63,0x84,0xe0,0x6,0xd4,0xc4,0x6,0x25,0x75,0x58,0xc,0x28,0x6a,0xb7,0x10,0x2,0xab,0xf2,0xbc,0x4f,0x2a,0xbf,0xc0,0xf4,0x60,0x8,0x88,0x3a,0x65,0xcd,0x5,0x56,0xe9,0xe5,0xcc,0x37,0x22,0xc0,0xd9,0x81,0xf3,0xfe,0x12,0xd1,0xc7,0xea,0xc0,0x88,0x18,0x55,0x22,0xaa,0xd8,0x52,0xac,0x94,0xc6,0xd0,0xaf,0xe1,0x9d,0x85,0x1,0xd0,0xaf,0x97,0x0,0x8,0xea,0x84,0x46,0x58,0x33,0x69,0xc7,0xa,0xbf,0x1d,0xf4,0xeb,0x25,0x94,0xd2,0x70,0xb6,0x7,0x29,0xd,0x20,0x62,0xe8,0x57,0x30,0x89,0x80,0xcb,0x6a,0x42,0xd3,0xb4,0xd0,0xc6,0x80,0x94,0x42,0xdb,0x2e,0xb8,0x0,0x84,0x14,0xfa,0xaa,0x8,0x63,0xe8,0x57,0x5c,0x5c,0xa2,0xd,0x8c,0x31,0xb0,0xfd,0x1a,0xba,0x69,0x31,0xac,0x97,0xd0,0xa6,0x1,0x51,0xc3,0x99,0x7c,0xa6,0x41,0x30,0x6,0x21,0x4,0xec,0xec,0x9e,0xc0,0xf2,0xe0,0x5c,0x51,0xdc,0xbd,0xe5,0xd,0xaf,0xc2,0x1b,0x5e,0xfb,0xaa,0x8d,0x79,0xed,0x87,0x1,0xb7,0x7c,0xfe,0x2b,0x29,0x37,0x31,0xc0,0xfb,0x0,0x3b,0xc,0x0,0x78,0x3e,0x87,0x7e,0x95,0xca,0x3e,0x1a,0xac,0xe,0xd7,0x20,0xa5,0xd2,0x71,0x70,0x11,0x8a,0x4e,0x7f,0x94,0x52,0xd0,0xda,0x94,0xbc,0xc4,0x4c,0x54,0x12,0xb1,0x92,0x50,0x69,0x5d,0xec,0xcb,0x9c,0x7d,0x18,0x4a,0x3e,0x5f,0x6e,0xe7,0x65,0x95,0xe7,0xd4,0x7a,0x5a,0xb2,0xfe,0x12,0xe6,0x24,0x19,0xbb,0x88,0xe7,0xcf,0xcf,0x49,0xb0,0xac,0xe2,0x43,0x62,0xdc,0xa8,0x7a,0x78,0x46,0xf0,0x4d,0x98,0xb6,0xb8,0x29,0xb9,0x9b,0x33,0x71,0x5b,0x8,0x3c,0xaa,0x87,0x10,0xa7,0xb5,0x20,0x1b,0xe3,0x3f,0xe2,0x7c,0x8f,0xe7,0xfd,0x7d,0xdc,0xd3,0xa8,0x72,0xdc,0x36,0xa8,0x3a,0x40,0x71,0x7e,0xc,0x47,0x30,0x8f,0xc9,0xa6,0xfc,0xc2,0xf3,0x10,0x5,0x2,0x81,0xe0,0x47,0x3,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0xe3,0x84,0x4a,0xb1,0xc4,0x44,0xdd,0x68,0xf9,0xf4,0xde,0x57,0xf9,0x6f,0x54,0x2c,0xb1,0x11,0x11,0x14,0x9,0x94,0xa,0x36,0x72,0xf6,0x9d,0x4b,0xea,0x3c,0x24,0x42,0x50,0x9b,0xb6,0x10,0x29,0x99,0x9c,0x62,0x62,0x8d,0x46,0xf2,0x89,0x8,0xda,0x34,0x30,0xc1,0x63,0x7d,0xb8,0x5f,0x4a,0x39,0x9a,0x6e,0x81,0x33,0x4f,0x3d,0x8e,0x76,0xb1,0xe0,0x32,0x8e,0xb6,0xc5,0xb0,0x5e,0x15,0x52,0xcb,0xe,0x3,0x94,0xe6,0x66,0xdb,0xac,0x8c,0x33,0xa6,0x1,0x40,0x5c,0x22,0x2,0x30,0x1,0x8,0x2e,0xc2,0xb0,0xb6,0x2f,0x4a,0x41,0x80,0x2d,0xb1,0xc1,0xb3,0xd5,0xd9,0xe,0xac,0x2,0xd4,0x4d,0xc3,0x19,0x78,0x4a,0xc3,0x7b,0x56,0x2,0xea,0x54,0x78,0xd2,0x2d,0x76,0xd9,0x6a,0x6c,0x7,0xec,0xec,0x9d,0x4c,0x6a,0x46,0x8f,0xf,0xff,0xcc,0x7b,0xb1,0x58,0x74,0x1b,0xd3,0xfa,0xcd,0x6f,0x7f,0x7,0x5f,0xfb,0xf6,0xf7,0xd8,0xd6,0x6b,0x6d,0xb2,0x22,0x23,0x65,0x19,0xba,0xa2,0x9e,0xec,0xfb,0x25,0x2b,0x15,0xd3,0x9c,0x9b,0xa6,0x65,0x45,0xa2,0x52,0x49,0xc1,0x68,0xa0,0xd,0xa5,0x39,0xa6,0xca,0x2d,0x4b,0xa5,0x5,0x39,0x8f,0x31,0xbf,0x16,0x21,0xcd,0x35,0xb2,0x65,0xbb,0x90,0xb2,0x55,0x6a,0x5d,0x4d,0xee,0x4d,0x32,0xf8,0xaa,0xf2,0x8a,0x89,0x3d,0x17,0x98,0x12,0x7c,0x1b,0x27,0xd2,0xb8,0xce,0x7c,0x5d,0xa2,0x4d,0x75,0xdc,0x4c,0xc5,0x57,0x67,0xf3,0x51,0xbd,0xc9,0x6d,0x7c,0x59,0x3c,0x7f,0x76,0xdf,0x9c,0xd4,0xa3,0x49,0x21,0xc7,0x85,0xd,0xbf,0x35,0xf5,0x77,0xd4,0xf3,0x5b,0x37,0x35,0x77,0x3,0x4f,0x76,0xc3,0xf,0x2a,0x92,0x58,0x7d,0x81,0x40,0x70,0x71,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x18,0x81,0xb4,0x29,0xb6,0x50,0x2,0x21,0x20,0x8c,0x99,0x6e,0x8a,0x2d,0xa5,0x94,0x88,0x1b,0x6e,0xfe,0x35,0x50,0xc4,0xd,0xb6,0xde,0xdb,0x49,0xce,0x9f,0x52,0xa,0xd1,0xfb,0x44,0xd2,0xb1,0x6d,0xd8,0x7,0x5f,0xf2,0xe7,0x78,0x1d,0x7,0x67,0x43,0x21,0x13,0x8d,0x69,0xd1,0xed,0xec,0xc2,0xb9,0x1,0x27,0x2f,0xbd,0x2,0xfb,0x67,0x9e,0x66,0x85,0xdd,0x6a,0xc9,0x59,0x83,0x89,0xf0,0xeb,0xfb,0x55,0xb2,0xea,0x12,0x6c,0xcf,0x85,0x1e,0xd6,0x6,0x2c,0x76,0xf6,0x40,0x44,0x68,0xdb,0xe,0xa6,0x69,0x59,0x29,0xb8,0xe0,0x36,0x5f,0xce,0xf1,0x23,0xb4,0xdd,0xe,0x13,0x8d,0x1a,0x70,0x89,0x60,0xf4,0xde,0x95,0xcc,0xbd,0x21,0x5b,0x8c,0x9d,0x43,0xd3,0xb4,0x0,0x2a,0x6b,0x34,0xa1,0x14,0x8a,0x50,0x22,0x2b,0x73,0x39,0xc9,0x75,0x57,0x5f,0x8a,0xb7,0xbf,0xf5,0xcd,0x1b,0x73,0xea,0x9c,0xc3,0xff,0xfb,0xa9,0xcf,0xc2,0x59,0xb,0x6d,0x4c,0x99,0x83,0x52,0xba,0xe1,0x43,0x69,0xcf,0x75,0x76,0x40,0x48,0x63,0x71,0x8e,0x5b,0x89,0x4d,0xd3,0x40,0x29,0xd,0xdd,0x34,0xd0,0xda,0xf0,0xdc,0x35,0x4d,0x51,0x90,0xb1,0xda,0x92,0x8a,0xca,0x2f,0x2b,0x2b,0xb3,0xa,0x10,0x93,0x42,0xe,0x2a,0xa5,0x20,0xa4,0x74,0x79,0x7d,0xca,0x31,0x6,0x3f,0xb1,0x7a,0xe7,0x65,0xd3,0x81,0x97,0x9c,0xc0,0x54,0x1,0x9c,0x36,0xa,0x4c,0xb2,0xf9,0x0,0x1c,0x99,0xf5,0x17,0x2b,0xed,0xe0,0xbc,0xc0,0xa3,0x5e,0x6c,0xcb,0xcf,0xb4,0xa5,0xb0,0xe3,0x7c,0xea,0xbe,0xcd,0x2d,0x32,0xb,0xb7,0x41,0xe7,0xd5,0xe4,0xe4,0xe4,0xd8,0xe2,0x91,0x22,0xc7,0xc9,0xb2,0xdb,0xca,0x87,0x8f,0x38,0x88,0x58,0x2d,0x1c,0x11,0x8b,0x2d,0x5d,0x20,0x10,0x8,0x5e,0xea,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x38,0x46,0x60,0xcb,0x28,0x55,0x84,0x8,0xd8,0xd5,0xe9,0x53,0x6,0x20,0xa1,0xb2,0xf7,0x2a,0x2e,0xe4,0x50,0x4,0x67,0x7b,0x28,0x6d,0x8a,0xb2,0x2f,0x0,0x9c,0x2b,0xa7,0x14,0x42,0xe0,0x72,0x90,0xa1,0x5f,0x41,0x6b,0x93,0x94,0x79,0x55,0x99,0x44,0x52,0xb7,0xb5,0xdd,0xe,0x56,0x87,0xfb,0x68,0xda,0xe,0x27,0x4e,0x5d,0x8a,0xe5,0xe1,0x3e,0x4e,0x9d,0xbe,0x1c,0xc3,0xb0,0x86,0x1d,0xfa,0x64,0xdb,0xa5,0x52,0xa2,0x31,0xf4,0x6b,0x10,0x0,0x65,0xc,0x16,0x8b,0x5d,0x6e,0xe2,0xf5,0xe,0x3b,0x7b,0x27,0x71,0x78,0xee,0x59,0x34,0xdd,0x2,0xdd,0xce,0x5e,0xb2,0x17,0x8f,0xa5,0x24,0xce,0xd,0x4c,0x54,0x3a,0x57,0xb2,0xf7,0x16,0x49,0xd1,0x68,0x92,0xb5,0x38,0x5b,0x69,0xd1,0x62,0xb4,0x6a,0xa6,0x29,0x71,0xce,0x32,0x11,0x97,0x8,0x40,0xad,0x35,0x9c,0x76,0xd8,0xdb,0x3b,0x81,0x4f,0x7e,0xfa,0x33,0x95,0xb2,0x8e,0x49,0xb6,0xfd,0x83,0x15,0xee,0x7d,0xe8,0x3b,0x88,0x91,0x8b,0x53,0xbc,0xb5,0x85,0x48,0x8c,0x20,0xb6,0x34,0x27,0x5b,0x73,0xc,0x11,0xce,0x32,0xf1,0xb7,0x77,0xf2,0x34,0x94,0xd2,0xa5,0x6d,0x39,0x93,0x77,0x5a,0x1b,0x9e,0xfb,0xc0,0xe4,0x51,0x3e,0x2e,0x9d,0x6c,0xc9,0xb9,0xc5,0xb7,0xb6,0x98,0x32,0x19,0x58,0x9,0xf8,0x22,0x10,0xbc,0x9b,0x90,0x7c,0x99,0x48,0xcc,0xb6,0xdc,0x91,0xfc,0x1b,0x4f,0x84,0x8,0x4c,0xc9,0x32,0xa0,0x8a,0xc4,0xa3,0x91,0xa5,0xab,0xda,0x77,0xf3,0xff,0x69,0x16,0xed,0x37,0x9e,0x74,0x47,0x57,0x83,0xd4,0x8a,0xbd,0xa9,0x6a,0xf,0x18,0xc9,0xbc,0xed,0xa6,0xdf,0x51,0xe9,0x77,0x9e,0x16,0x90,0x9c,0xc3,0x97,0x5f,0x5f,0xc2,0xd4,0x96,0xbc,0xd9,0xe9,0x71,0x84,0xa2,0x2f,0xcf,0xc7,0xf3,0xcc,0xf4,0x93,0x8,0x40,0x81,0x40,0x70,0x91,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x18,0x21,0x7a,0xcb,0xc4,0x49,0x8,0x89,0x74,0x2,0x72,0xc9,0x2c,0x45,0x26,0x5c,0x94,0xe6,0xcb,0x80,0xac,0x88,0xcb,0xcb,0xe6,0x26,0x5e,0xa5,0xd9,0x32,0xab,0x52,0x26,0x1f,0x11,0x25,0xbb,0xaf,0x41,0xc,0xb1,0x34,0x3,0xf3,0xfa,0x94,0x5a,0x79,0x35,0x67,0xfe,0x19,0x53,0x9a,0x85,0x9b,0xa6,0x83,0xa7,0x1,0x9d,0xda,0xc1,0xee,0x89,0x53,0x18,0xfa,0x75,0x21,0xbb,0xba,0xc5,0x6e,0xc9,0x14,0xc,0xde,0xc3,0x79,0x7,0x10,0xc1,0x98,0x6,0xb6,0x67,0xf2,0xcc,0xd9,0x1,0xad,0xd2,0xd0,0x8d,0x49,0xea,0x41,0x24,0x65,0xa2,0x6,0x22,0xb8,0x1,0x38,0x36,0x18,0xbc,0x87,0x69,0xc,0x82,0x6f,0x81,0x18,0xa1,0x8d,0x81,0x4a,0x99,0x78,0x4,0xc5,0x5,0x24,0x6d,0x97,0xac,0xb5,0x99,0xd4,0xf4,0x29,0xaf,0x50,0x81,0xdd,0xb5,0x1e,0xf,0x3f,0xf6,0xc,0x1e,0xf9,0xcb,0xbf,0x85,0x77,0x16,0xde,0x31,0x39,0xa7,0x8d,0x29,0x59,0x88,0xa6,0x6d,0x8b,0x5a,0xd0,0x7,0x8f,0x18,0x1c,0x2b,0xfc,0xda,0x16,0xfd,0xea,0x10,0xce,0xe,0xf0,0xde,0xc2,0xda,0x1,0x4a,0x6b,0x74,0x8b,0x5d,0x20,0xb5,0xe,0x13,0x11,0xbc,0xb3,0x68,0xdb,0x5,0x0,0x14,0x95,0x20,0x0,0x90,0xa2,0xf4,0xbc,0x9b,0x91,0x76,0x6a,0x9c,0xff,0x3c,0xdf,0x55,0x33,0x2d,0x17,0x91,0x54,0xc5,0x2e,0xe0,0xd7,0x92,0x1f,0xc8,0x27,0x44,0xfa,0x9b,0x8e,0x2e,0xe9,0x28,0xdc,0x68,0xdc,0x4c,0xd0,0xab,0xd2,0x24,0x67,0x89,0x79,0x79,0x4,0xd3,0xe5,0x6b,0x64,0x1a,0x6f,0x7b,0xf1,0xc6,0x85,0x42,0x3,0xe7,0xc6,0xdd,0x2d,0x2c,0x23,0x1d,0x51,0x23,0xbc,0x6d,0xf3,0x9b,0x3,0x3b,0xe2,0x9,0x4c,0xf6,0x4f,0xb3,0xc7,0x2a,0x83,0xbd,0xbc,0xd9,0x8,0x4,0x82,0x8b,0xa,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0x9,0xc4,0xe4,0x56,0x46,0x2e,0x90,0x88,0x49,0xe1,0x45,0x59,0x39,0x36,0xb3,0x97,0xea,0x54,0x6,0x2,0x44,0x84,0x18,0x2a,0x3b,0x29,0x0,0x50,0x51,0xef,0x5,0x30,0x31,0xe6,0x3,0xab,0xcf,0x28,0x46,0x84,0xb4,0x1d,0x52,0xdc,0x14,0x4c,0x11,0x30,0x4d,0xca,0xb4,0x8b,0xbb,0x38,0x3c,0xf7,0x2c,0x94,0x36,0x58,0xec,0xec,0xc1,0x7b,0x87,0xc5,0xce,0x1e,0x62,0xc,0x68,0xda,0x8e,0xc9,0xbc,0x6,0xf0,0xce,0xa1,0x5d,0xec,0x20,0x78,0x8f,0xc5,0xce,0x2e,0xec,0x30,0xa0,0x69,0x17,0xd0,0x49,0x6d,0xc8,0x96,0x63,0xd,0xa5,0x46,0xab,0x72,0x2e,0xc8,0x68,0xbb,0x45,0x6a,0x13,0x76,0x85,0xd4,0xd3,0xa9,0x44,0x84,0x89,0x3e,0x56,0xe0,0x65,0x15,0xa2,0x52,0xac,0xe,0xd4,0xc6,0x20,0x10,0x93,0x99,0x4d,0xdb,0xb1,0xf2,0x31,0x78,0x70,0x36,0x1f,0xab,0x28,0xb9,0xa5,0x57,0xa3,0x69,0x17,0x3c,0x3f,0x81,0xd9,0x32,0xa5,0x35,0x7c,0x6a,0x40,0x5e,0x2f,0xf,0xe0,0x83,0x4f,0xa,0x46,0xcf,0xdb,0x89,0x11,0x76,0x58,0xa3,0xdb,0xd9,0x2b,0xb6,0xdf,0xb6,0xdb,0x41,0x96,0xd7,0x85,0x30,0x16,0xb0,0x20,0x91,0x76,0x39,0xd7,0x4f,0x55,0xaf,0x5,0x2b,0xf9,0x30,0x16,0x78,0x64,0xb5,0x5b,0x8c,0x88,0xe9,0xe7,0x4c,0xde,0xd6,0x64,0x5f,0x26,0x6d,0xcb,0xf2,0x45,0xa,0x1a,0xa7,0xee,0xd8,0x78,0xfe,0xd2,0x8d,0xcd,0xc7,0xa7,0xad,0xbf,0x9b,0x34,0x18,0xd3,0x66,0xe3,0x73,0xf3,0xaa,0xdf,0x5a,0xc6,0x38,0xcb,0xe0,0x2b,0x8b,0x1f,0x41,0xe8,0x6d,0xb0,0x8d,0xb9,0xc9,0x7a,0xcb,0xbf,0x83,0x58,0x8f,0x86,0xa6,0xdb,0x7a,0x8e,0xdc,0x1d,0x6d,0x69,0xb,0x8e,0xe9,0x75,0x8a,0x78,0x7e,0xdb,0x12,0x8,0x4,0x82,0xff,0xbf,0x21,0x4,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x8c,0x10,0x43,0x9c,0x74,0x3b,0xd4,0x36,0xd2,0x98,0xac,0xbf,0x99,0x80,0xa1,0x62,0x15,0xe6,0x2c,0x33,0x6d,0x1a,0x56,0xfe,0xa5,0xbc,0xbf,0xac,0xf1,0xe2,0x72,0x8e,0x4c,0x5c,0x5,0x28,0x62,0x25,0x1a,0x11,0x8d,0x8d,0xb5,0xa8,0x32,0xe7,0x92,0xda,0x50,0x29,0x5,0x67,0x2d,0x4e,0x9e,0xbe,0x9c,0x55,0x75,0x69,0x1f,0x4a,0x29,0xd8,0x21,0x65,0xe5,0x81,0x55,0x7d,0xd4,0x28,0x10,0x80,0xa6,0x6d,0xe1,0xec,0x0,0xd3,0xb4,0x4c,0x8,0x3a,0x9b,0x8e,0x8c,0xf3,0xb,0x5d,0xb0,0x89,0xfc,0x4a,0xd,0xba,0xd1,0x1,0x4a,0x81,0x14,0x95,0xcc,0xc0,0x6c,0xbb,0xcd,0x6a,0xb8,0x4c,0xf8,0x31,0x69,0x18,0x1,0xc5,0x4,0x5e,0x8c,0x11,0xc1,0x73,0x23,0x32,0xcf,0x85,0x2,0x10,0x4a,0x36,0x60,0x2e,0x22,0x21,0xa5,0x78,0xac,0x9e,0xed,0xbb,0x6e,0xb0,0x25,0x47,0x71,0xe8,0xd7,0xc5,0xf2,0x1b,0x83,0x87,0xed,0xd7,0x68,0xda,0x16,0x0,0x8f,0x7,0x60,0xe2,0x12,0x40,0x6a,0x57,0x66,0x92,0x8f,0x9b,0x80,0x63,0x19,0x7,0x67,0xf9,0xf1,0x71,0x66,0x6b,0x73,0x29,0xf6,0xa8,0xa,0x3f,0x26,0x44,0x5f,0x22,0xc0,0xea,0x2,0x10,0xd4,0xaf,0x79,0x21,0xff,0xea,0xe5,0xb1,0xb5,0x74,0xa3,0x76,0x5,0xd7,0xa,0xb7,0x6c,0xc3,0xa5,0xea,0x91,0x4d,0x45,0xdf,0x36,0x85,0xdf,0x11,0xea,0x3d,0x9a,0xfd,0x3e,0xc7,0x73,0xd9,0xdc,0x64,0xd9,0xf3,0x33,0x70,0xb4,0x75,0x27,0xdb,0x76,0x3e,0x27,0xfa,0xe6,0x16,0xe4,0x2d,0xc3,0x95,0x6,0x60,0x81,0x40,0x70,0x11,0x41,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x98,0x81,0x33,0xf3,0x32,0x9f,0x54,0x17,0x3f,0x64,0x53,0x26,0x4a,0x19,0x48,0xb6,0xfd,0x2,0x48,0xb6,0xd7,0x88,0xc8,0x9,0x80,0x20,0x64,0x6b,0xaa,0x4f,0xf6,0x5b,0x26,0xb2,0x72,0x86,0x60,0xce,0xf,0x44,0x22,0xdb,0x72,0xb6,0x1f,0x92,0xcd,0xd8,0xbb,0x8,0xd3,0xb4,0xa9,0x6c,0x44,0x43,0x37,0x2d,0xbc,0x1d,0xa0,0x4d,0x53,0x32,0xef,0x88,0x78,0x2c,0x6c,0x4b,0x4e,0x63,0x52,0x80,0x36,0xba,0x58,0x84,0x33,0xcf,0x43,0x89,0xd0,0xca,0x47,0xe7,0x9c,0xcd,0xa3,0x4,0x91,0xe2,0xf6,0xe1,0xa6,0x83,0xf7,0x16,0x5a,0x37,0x80,0x46,0x3a,0xbe,0x44,0x6c,0x6a,0x3d,0x25,0x44,0x63,0x80,0x31,0xfc,0x98,0x4f,0xaa,0x48,0x2,0xa0,0x93,0xd5,0x37,0x93,0x7f,0x31,0x84,0x49,0xd9,0x43,0xdd,0x7a,0x3c,0xf4,0x6b,0x78,0xc7,0xa4,0xe4,0xd0,0xaf,0x4b,0xa3,0x71,0xce,0x49,0xcc,0x85,0x23,0xc6,0x34,0x85,0x24,0x5,0xc0,0xf9,0x84,0x44,0x8,0x2e,0x95,0x78,0x54,0x16,0xdd,0x4c,0x5e,0x16,0x4a,0x8a,0x0,0x90,0xaa,0x2c,0xc0,0x71,0x92,0x75,0x97,0x55,0x9e,0xc8,0x8d,0xce,0x89,0xc0,0x9d,0x16,0x76,0x54,0xe7,0x47,0xfa,0x3f,0xd5,0x64,0x5e,0xdc,0xc6,0xc7,0x8d,0x4,0xd8,0x56,0xaa,0x6b,0xb2,0xe1,0xa3,0xe4,0x75,0xb4,0x9d,0x28,0xbb,0x50,0xfb,0x24,0xe9,0x18,0x34,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x47,0x11,0xc,0x8e,0xe3,0xdc,0x20,0xf3,0x62,0xa5,0xf0,0xdb,0x1a,0x11,0x78,0xd4,0xba,0xb4,0x71,0x54,0xf9,0xdf,0x8,0x51,0x9a,0x93,0x8,0x44,0x8a,0x47,0x8e,0xeb,0x3c,0xf,0x8,0x4,0x2,0xc1,0x4b,0x12,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0x9,0xc1,0x22,0x17,0x40,0xc4,0xf2,0x37,0x90,0xc2,0xfe,0xd8,0x36,0xa,0x0,0x89,0x28,0x8a,0x60,0x32,0x2b,0x46,0x8c,0xad,0xb3,0xe9,0x31,0x52,0xe3,0xdf,0x88,0x11,0x21,0xab,0x3,0x53,0x91,0x8,0x5b,0x7c,0x23,0x62,0x4c,0x4,0x21,0x54,0xc9,0xd7,0xab,0x55,0x6b,0x80,0x2,0x69,0x62,0x92,0x2f,0x11,0x53,0x4d,0xbb,0x28,0x44,0x1c,0xdb,0x58,0xa9,0xca,0xba,0xe3,0xb1,0x99,0xc6,0xb0,0xb5,0xb7,0x69,0xa,0x9,0x39,0x36,0xef,0x26,0x52,0x2d,0x8e,0xea,0xc5,0x98,0x9a,0x79,0xb9,0x5d,0x78,0xe4,0xc0,0x62,0xc,0xac,0xdc,0x73,0x96,0xb9,0xb6,0xa0,0x52,0x77,0x84,0x82,0xb3,0x43,0xda,0x77,0xca,0xd0,0x8b,0x11,0x6e,0x18,0x4a,0xe6,0x60,0x2c,0x6d,0xbf,0x23,0xb1,0x96,0xc7,0x60,0x87,0x3e,0xcd,0x1d,0xb7,0xff,0x2a,0xa5,0xe0,0xbc,0x87,0xd2,0x1a,0x4d,0xb7,0x80,0x69,0x5a,0xfe,0x63,0x9a,0x54,0x4a,0xe2,0x58,0xf9,0x97,0x95,0x8f,0xc4,0xd6,0xea,0x10,0xc2,0x38,0x57,0xf9,0xf5,0xa2,0x91,0xb2,0x1a,0x5b,0x9b,0x33,0x41,0x35,0x76,0x75,0x8c,0xa2,0xba,0x38,0x21,0xba,0xea,0x24,0xbd,0x5a,0xc5,0x97,0x36,0xcd,0x85,0x26,0xc0,0x96,0xa2,0x8d,0xe7,0x8a,0x78,0xb4,0x88,0x2e,0x1e,0xb1,0xdc,0xb6,0xc8,0xbf,0xf2,0x54,0xdc,0x6a,0xb9,0xcd,0xc7,0x43,0x47,0x8c,0x8d,0x8e,0xa8,0xf8,0x3d,0x82,0xb2,0x9c,0x90,0x82,0x93,0xc7,0xb,0xf,0x3a,0x16,0xa3,0xcc,0x97,0xdb,0x96,0xfd,0x47,0x4a,0xc9,0x7b,0x8e,0x40,0x20,0xb8,0x28,0x20,0xef,0x56,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0xb1,0xfa,0x86,0x6f,0x66,0x5f,0xf3,0x67,0xc5,0x6,0x21,0x96,0xf2,0x88,0x18,0x23,0x54,0x2a,0xb8,0x18,0x99,0x24,0x2a,0xab,0x14,0x72,0xa8,0x88,0xc9,0x46,0x6f,0xb1,0x52,0x7a,0x24,0x47,0x62,0x1c,0xd5,0x81,0xde,0x41,0x2b,0x83,0x90,0x9,0x40,0x2,0xb4,0xd6,0x45,0x7d,0x8,0x24,0xd2,0xa4,0xe4,0xdd,0xa9,0x94,0x2f,0xa8,0x8a,0xca,0x4f,0x29,0x5d,0x32,0xfe,0xb2,0xad,0x98,0xed,0xc6,0xa1,0x8c,0x9d,0x14,0x2b,0x4,0xb9,0x9,0x97,0xad,0xc8,0x0,0x97,0x76,0xb0,0x5,0x98,0x8f,0x4b,0x69,0x5,0xef,0x1c,0xab,0x2,0x95,0x66,0x65,0x5e,0x64,0x2b,0xb3,0x4f,0xc5,0x23,0x88,0xe0,0x6d,0x55,0x65,0x28,0xac,0x1c,0xa4,0x94,0xf7,0xa7,0x92,0xa2,0xd1,0x71,0x53,0x72,0x8,0x70,0x76,0x80,0x1d,0x7a,0x78,0xe7,0xd0,0xaf,0x96,0x8,0x21,0xa0,0x5f,0xaf,0x98,0x8c,0xd4,0x86,0xdb,0x8e,0xed,0x80,0x18,0x39,0x57,0xd0,0x3b,0x7e,0x5c,0x29,0x5d,0x72,0xa,0x63,0x6a,0xfc,0x2d,0xca,0xc6,0x44,0xe2,0x55,0xcc,0x65,0x99,0xfc,0x52,0xee,0x81,0xf2,0x12,0x8c,0x5c,0x1b,0x8d,0x45,0x22,0xfc,0x72,0x8c,0x6a,0xbc,0x42,0xfe,0x11,0x55,0xca,0xc7,0x79,0xd1,0xc6,0xb4,0xed,0x77,0xaa,0xe6,0x8b,0xe3,0x4e,0xb0,0xf9,0x54,0x56,0xf,0x6e,0x9c,0x6a,0x73,0x5e,0x6e,0xbe,0xcc,0x8c,0x9f,0xa3,0x49,0x39,0xc8,0x26,0xe6,0x85,0x20,0x71,0xae,0x4d,0x8c,0xf5,0x23,0x9b,0x45,0x22,0x71,0xbe,0x4e,0xac,0xf6,0x19,0xb7,0xca,0x1f,0xa7,0xfb,0xac,0x8f,0x37,0xaf,0x3,0x20,0xf8,0x20,0xef,0x39,0x2,0x81,0xe0,0xe2,0xf8,0x7a,0x20,0x53,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x1c,0x23,0xd4,0x99,0x70,0x89,0xbd,0xcb,0xc4,0x10,0x11,0xb1,0x9a,0xaf,0x3c,0xc6,0x44,0x58,0x51,0xff,0xa5,0xfc,0xc0,0x4c,0x6a,0x84,0xe0,0x47,0xb,0x2a,0x46,0xdb,0x6c,0x5d,0x3a,0x91,0xad,0xaa,0x6c,0xb,0x66,0xb2,0xc9,0x7b,0x97,0x54,0x6e,0x11,0xc1,0x7b,0x56,0xb,0x92,0x42,0x8,0x81,0x1b,0x71,0x95,0x4a,0x44,0x9d,0x2a,0xca,0x3b,0x95,0xa,0x44,0xf8,0x31,0x62,0x15,0x61,0x52,0xc8,0xe5,0x71,0xc5,0x34,0x5e,0x4a,0x25,0x17,0x9c,0xa3,0x17,0x52,0x14,0x1e,0x15,0xbb,0x6e,0x51,0x28,0xa6,0xe2,0x92,0xa2,0x1c,0x24,0x82,0x1d,0xfa,0x34,0xa6,0x50,0x88,0xc3,0x4c,0xfc,0x5,0xef,0x52,0x51,0x8,0x93,0x7c,0x31,0x6d,0x3b,0x84,0x80,0xe0,0x3d,0x9a,0x6e,0x91,0x8e,0x37,0x16,0x4b,0xf0,0xd0,0xaf,0xe1,0x9c,0xc5,0x7a,0x79,0xc0,0x65,0x22,0x4d,0xb,0xd3,0x34,0x45,0x89,0xa8,0xb4,0xe1,0xdc,0xc3,0x94,0xa3,0xe8,0x53,0xfb,0x6f,0x1e,0xef,0xc4,0x9e,0x9d,0x64,0x68,0xc5,0x56,0x8d,0x31,0x57,0xb1,0x10,0x7e,0x15,0xb9,0x17,0x2b,0x56,0x2d,0x24,0xa5,0xe2,0xd4,0xd6,0x3a,0x36,0xf7,0xe6,0xc6,0xe6,0xad,0xcd,0xba,0xe9,0xc7,0x5a,0x77,0x57,0xce,0x9f,0x71,0x3,0xdb,0x15,0x7e,0x55,0xa9,0xc8,0x6,0x77,0xb8,0x5,0x71,0xa3,0x69,0xf8,0xc2,0xbf,0xe7,0x5a,0x91,0x38,0xd1,0x2a,0xd6,0x7d,0xbc,0xf1,0xf9,0xf6,0x7b,0x4c,0xd4,0xa4,0xd3,0x86,0x64,0x6c,0xc4,0x17,0x6e,0x25,0x38,0xcb,0x3f,0x37,0x92,0xf7,0x1c,0x81,0x40,0x70,0x51,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x38,0xa1,0xca,0xfa,0xcb,0x54,0x49,0x21,0x7f,0xb2,0xca,0x2c,0xab,0x97,0xc2,0xa8,0x74,0x8b,0x21,0xb2,0xf2,0x2d,0x4,0x56,0xec,0x25,0x50,0x22,0xee,0x6a,0x65,0x60,0xf0,0x2e,0x3d,0x96,0x96,0x1,0xc6,0xe6,0xda,0xda,0xfa,0x5b,0x14,0x53,0x84,0x10,0xc3,0xd8,0x5e,0x5b,0x95,0x54,0x64,0xc5,0x5f,0x26,0x21,0x51,0xd9,0x5d,0x63,0x35,0xbe,0x90,0xda,0x75,0x33,0x91,0xc6,0x4d,0xbb,0x61,0x62,0x8f,0xf5,0xce,0x8e,0xe4,0x1a,0x11,0x67,0xf3,0xa5,0xfd,0x13,0xa8,0xb4,0x7,0xe7,0x79,0xa,0xc1,0x8f,0xa,0x42,0xe7,0xa,0xe1,0xe6,0xec,0xc0,0x63,0x4b,0x76,0xe6,0x58,0xc8,0x42,0xc7,0x8a,0x3e,0xef,0x31,0xf4,0x6b,0xc4,0xc8,0x4a,0x40,0x22,0x80,0x94,0x46,0x8c,0x1,0xdd,0xce,0x1e,0x2b,0x2b,0x95,0x86,0x69,0xbb,0x72,0xcc,0x54,0xac,0xd6,0x63,0x99,0x4a,0x9e,0x7,0x9a,0xb4,0xf9,0x46,0x84,0x90,0x1e,0xcf,0xaf,0x11,0x30,0x5a,0x7f,0xcb,0x9c,0x57,0x85,0x15,0x31,0xcc,0x14,0x74,0x53,0xb3,0x2a,0xe5,0xa6,0xdc,0x79,0x21,0x8,0x3f,0x59,0xfe,0xce,0xca,0xb8,0xaa,0x9,0x64,0x3b,0xe6,0x62,0xbd,0xad,0x51,0x79,0xf1,0x88,0x55,0xa7,0x16,0x5d,0xda,0x12,0xde,0x17,0xab,0xff,0xf2,0x32,0x71,0xb6,0xdd,0x78,0xe4,0x1e,0x36,0x6,0xf2,0xfc,0x9e,0xdc,0x7a,0x4c,0x71,0xf6,0x58,0xa5,0x95,0x8c,0xa2,0x0,0x14,0x8,0x4,0x17,0x7,0x84,0x0,0x14,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x8e,0x11,0x32,0x19,0x94,0xb3,0xfc,0xb2,0xca,0x2b,0x5b,0x48,0x73,0xa1,0xc6,0xc4,0x6,0x1a,0xc3,0x4c,0x4,0x35,0x92,0x74,0x45,0xd9,0x97,0xc8,0xc1,0xbc,0x9e,0x4a,0x19,0x79,0xd9,0x5a,0x9a,0xc9,0x37,0x60,0x2c,0x9,0xc9,0xe4,0x5c,0xce,0xd2,0xcb,0x44,0x60,0x6d,0x2d,0x66,0x32,0x8c,0xcb,0x47,0xea,0x71,0x33,0x89,0xa7,0x26,0x63,0xd0,0xc9,0x86,0x1b,0xa3,0x67,0x5,0x5e,0x44,0xb1,0xf,0x3,0xb1,0x64,0x12,0xf2,0x32,0x95,0xaa,0x2e,0x6d,0x3,0x40,0x51,0xe0,0xe5,0x9c,0xc1,0x52,0xe8,0x91,0x8b,0x37,0x92,0xfd,0x37,0x38,0x97,0x2c,0xbc,0x71,0x52,0x2,0x62,0x87,0x1,0x43,0xdf,0x83,0x88,0xb0,0x5e,0x1e,0x8e,0x2a,0x42,0xef,0xd0,0xed,0xec,0xa1,0x5f,0x2d,0x41,0x44,0x68,0x12,0xf9,0xa7,0x34,0x5b,0x7e,0x39,0x2b,0x2e,0xab,0x2f,0xf9,0x32,0x8c,0x2a,0x45,0xde,0x48,0xcc,0xa6,0xbc,0x41,0x54,0x19,0x7f,0x34,0x7d,0xbd,0x88,0xca,0xff,0x30,0x92,0xbc,0xe3,0xbc,0x4d,0x88,0xaa,0x18,0x27,0x76,0xe6,0xd,0xb,0x6f,0x95,0xc3,0x38,0xd,0x15,0x3c,0xdf,0x49,0x6,0xd4,0xea,0xc1,0xe7,0x42,0xc5,0xc5,0xd9,0x7f,0xd3,0xc7,0x2a,0x8b,0xee,0xf3,0x20,0x13,0xcf,0x3f,0xbe,0x6a,0x9c,0x93,0xe3,0xad,0xfe,0x10,0x6d,0x7f,0xae,0x9e,0xda,0xf2,0xaf,0x66,0x5c,0x30,0xd6,0xaa,0x48,0x51,0x0,0xa,0x4,0x82,0x8b,0x4,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0xa,0xc4,0xa5,0x1c,0x71,0xa6,0x5a,0xa2,0x9a,0xf8,0x1b,0xd5,0x77,0xe5,0xc9,0xf4,0x37,0x91,0x2a,0x8a,0xb7,0x82,0x38,0x6a,0xcf,0x26,0x39,0x73,0x95,0x9a,0x30,0xef,0x4c,0x69,0x8d,0x6c,0x63,0xd,0x39,0xc3,0x2f,0x70,0x9,0x47,0x26,0xc,0x73,0x81,0x48,0x56,0xee,0x65,0xe2,0x8e,0x2d,0xc7,0xbc,0xfd,0x3a,0x63,0x30,0x96,0xcc,0x3e,0x3f,0xe,0x27,0x91,0x5d,0xa1,0x3c,0x96,0x49,0x4b,0x26,0xf3,0xb4,0x36,0xc5,0xbe,0x5b,0xb2,0xef,0xd2,0x38,0xe6,0xb6,0xe0,0x7a,0x1b,0x7c,0x8c,0xa,0x21,0x13,0x81,0xc9,0x8a,0x1c,0x43,0x2c,0x85,0x21,0x59,0xf9,0x97,0xf7,0x39,0xf4,0x6b,0x68,0x63,0xe0,0x6c,0x8f,0xa6,0xeb,0xa0,0xb4,0x1,0x29,0xb6,0x2f,0xe7,0xe3,0xf1,0xde,0x31,0x69,0x5a,0x32,0xc,0x59,0x59,0x49,0x18,0xed,0xce,0x63,0x23,0x33,0x55,0xb4,0x58,0x2e,0x45,0xa9,0x68,0xa8,0x50,0xe5,0x3,0x96,0x56,0x60,0x2a,0xc7,0x38,0x5a,0xb6,0x47,0x82,0xab,0x10,0xc2,0xf3,0x9e,0x8d,0x9,0x61,0x88,0x4d,0xb,0xec,0x1c,0x11,0x63,0x73,0xf0,0xd6,0xa7,0xa7,0x96,0xdd,0x78,0x1,0xad,0x5e,0xd6,0x67,0x4e,0x1e,0xa8,0xc7,0x71,0x21,0x6f,0x6f,0x3c,0xe2,0xf7,0x49,0x85,0x32,0x36,0xb7,0x5f,0xd4,0x8e,0xb3,0x95,0x8b,0x78,0x36,0x6e,0x19,0x4,0x36,0xf3,0x14,0x83,0xb4,0x0,0xb,0x4,0x82,0x8b,0x3,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0xe,0x54,0xec,0x89,0xb1,0xa8,0x99,0x12,0x89,0x94,0xd4,0x67,0x35,0x79,0x97,0x9,0x36,0x56,0x9a,0x85,0xf2,0xd8,0xb4,0xe1,0x34,0x3d,0x5e,0x3d,0x32,0xaa,0xd6,0xa8,0xb2,0xcf,0x72,0xb,0x71,0xf0,0x7e,0x6c,0x10,0x6,0xe0,0x9c,0x4d,0x4d,0xc2,0x3e,0xe5,0xed,0x79,0x64,0x32,0x2c,0x13,0x60,0xd9,0x92,0x3c,0x96,0x4f,0xc4,0x49,0x13,0x2e,0x11,0x41,0x1b,0x53,0x7e,0xe,0xc1,0x17,0xd2,0x8f,0x8b,0x3f,0x50,0xac,0xce,0xce,0x59,0x80,0x90,0x94,0x7b,0x63,0xf9,0x88,0x4f,0xf6,0xe5,0xd2,0xfa,0x9b,0x8a,0x38,0x32,0x9,0xc8,0xb6,0x60,0x3f,0x5a,0x85,0x41,0xa9,0x20,0x84,0xb3,0x2,0x6d,0xcf,0xc5,0x1f,0x5c,0xfe,0x71,0x88,0xb3,0xcf,0x3c,0x59,0xc6,0xb3,0x7b,0xe2,0x12,0x68,0x6d,0xb8,0x68,0x24,0xcf,0x11,0x62,0x21,0x3c,0xbd,0x73,0xe5,0x58,0x62,0x7a,0x8c,0x8b,0x4a,0x4c,0x3a,0x6e,0x2a,0x6a,0xcc,0x71,0xff,0x18,0x9,0xbc,0x4c,0x3c,0x11,0xa6,0x6a,0xb9,0x62,0xdb,0x9d,0xa9,0xdd,0x26,0xc1,0x7e,0x71,0x6b,0x8e,0x5f,0x6d,0x61,0x2d,0x74,0x5d,0xdc,0x64,0xd5,0xe2,0x66,0x6b,0x47,0x79,0xa6,0x5e,0xaa,0xda,0xdb,0xf3,0x38,0x57,0x67,0x64,0xf5,0xd4,0xeb,0x3c,0x1d,0xf3,0x36,0x5e,0x6e,0xa2,0x66,0xac,0x9e,0x98,0x36,0xd8,0x4c,0x1f,0xdb,0x3c,0x9b,0xcb,0x39,0x8d,0xb,0x10,0x96,0x71,0xb,0x21,0x2e,0x10,0x8,0x4,0x2f,0x75,0x18,0x99,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0xf8,0x80,0x74,0x3,0xe7,0x2c,0xe,0xf,0xf6,0xb1,0xb3,0xb3,0xb,0x95,0x48,0xaf,0x58,0x95,0x44,0xb0,0x30,0x2a,0x29,0xd1,0x12,0x1,0x53,0xb2,0xd8,0x48,0x15,0x52,0x88,0x30,0xaa,0xd2,0xf2,0x32,0xd9,0xb6,0x9a,0x8b,0x39,0x72,0x7e,0x60,0x86,0x36,0x6,0x76,0xe8,0x91,0x15,0x7a,0xb1,0x52,0xee,0x79,0xde,0x68,0x2a,0x4,0xf1,0x95,0xfa,0x2c,0x26,0x55,0x15,0xe0,0x8b,0x3a,0x91,0x6d,0xbd,0x59,0x69,0xc8,0x84,0x98,0xc7,0xd0,0x73,0x13,0xaf,0xa2,0xb1,0xc5,0xd7,0x59,0x56,0xfd,0x31,0xff,0xa7,0x26,0xd9,0x71,0x44,0x80,0xf3,0xe,0x44,0x3c,0xf,0x75,0x21,0x4a,0xce,0xdf,0x53,0xda,0xf0,0x78,0x22,0xb7,0xe9,0x2a,0xa5,0xe1,0xdc,0x90,0x72,0x3,0x5d,0x69,0xee,0xb5,0xc3,0x1a,0xc3,0x7a,0x8d,0x10,0x3c,0xd6,0xab,0x43,0x38,0x67,0x61,0x9a,0x6,0x21,0x4,0xa8,0x10,0xb1,0x5e,0x1e,0xa0,0x5d,0xec,0x82,0x94,0x2f,0x16,0xe3,0xe8,0x3d,0xbf,0x6,0xc4,0xaa,0x4c,0x8a,0xaa,0x90,0x8d,0x54,0xcf,0x75,0x35,0x9e,0x51,0x9,0xc8,0xf3,0xac,0xb4,0x9e,0x64,0x37,0xa2,0xb6,0x37,0x6f,0x21,0xa0,0x8,0xe0,0x16,0xe6,0xfc,0xb,0x4f,0x71,0x55,0x34,0xb2,0xf9,0xf3,0x34,0x47,0xb0,0x3e,0x3f,0x50,0x9d,0x1f,0xd5,0xe,0xe2,0xb4,0x1b,0x63,0xe4,0xe8,0xaa,0x65,0xcb,0x72,0xb1,0xca,0xf1,0x9b,0x49,0x52,0xa9,0xde,0x28,0xaa,0xe3,0xc3,0x94,0x87,0x9b,0x1c,0x7,0xa6,0xa,0xbf,0x72,0x1c,0xd5,0xc2,0x89,0x50,0xdd,0x18,0x7,0x8d,0x2d,0xbe,0xa5,0x4c,0x64,0x46,0x32,0x6e,0x2b,0x52,0xa9,0x13,0x18,0xbd,0xb3,0xf0,0xde,0x61,0xbd,0x3c,0xc4,0xd9,0xa7,0x1f,0x97,0x37,0x1d,0x81,0x40,0x70,0x71,0x7c,0x3f,0x0,0x20,0x9a,0x65,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x98,0xc0,0x2c,0x2e,0xc1,0xa9,0x2b,0xae,0x5,0x29,0x85,0x9d,0xdd,0x3d,0xec,0xed,0xee,0x94,0x56,0x5a,0xce,0xb3,0xf3,0xc9,0x5e,0x8b,0x51,0x31,0x45,0xc9,0x8e,0x1b,0x58,0xb1,0x47,0xc4,0x8d,0xb8,0x89,0xe1,0x83,0x4a,0x6a,0x3b,0x22,0x55,0xac,0xbd,0x31,0x46,0xa8,0x94,0xd1,0xc7,0x60,0xf2,0x70,0x24,0x5e,0xe6,0x36,0xd1,0x64,0x67,0xd,0xa1,0x94,0x7d,0xc4,0xc0,0x2a,0xc3,0xac,0x88,0x3,0x29,0xc4,0xa4,0xea,0xcb,0x4d,0xbc,0x39,0xff,0x8e,0xc9,0x32,0x9f,0xf6,0x91,0xad,0xba,0x34,0xb1,0xed,0x66,0xfb,0x6f,0x26,0x2e,0xeb,0x65,0x28,0x29,0xc,0xf3,0xb8,0x74,0x22,0xd5,0xea,0x4b,0xa3,0x51,0x7d,0x48,0x65,0x7b,0x39,0x8b,0x30,0x4,0xf,0x67,0x2d,0xec,0xc0,0xad,0xbf,0xb6,0x5f,0xc3,0x5a,0xb,0xef,0x6,0x0,0xc0,0xce,0xde,0x25,0xd0,0x5a,0xa1,0xe9,0x16,0x6c,0x3f,0x6,0x93,0xa1,0x3a,0x91,0x8b,0x99,0xe0,0x2c,0x63,0xca,0x25,0x2a,0x34,0x12,0xa5,0x20,0xe2,0x36,0xe6,0xdc,0xb0,0x9c,0x8f,0x27,0x1d,0x73,0xac,0x8,0xbf,0x92,0xeb,0x57,0x1d,0xfb,0xe6,0x6b,0x52,0x5e,0x99,0xb4,0x5a,0x22,0xc6,0xf2,0xf6,0x26,0x45,0x1c,0x98,0x12,0x5d,0xe9,0x35,0x21,0x52,0x85,0x2c,0xac,0x5b,0x87,0x9,0x28,0xaa,0xc5,0x42,0x5a,0xe6,0x16,0x66,0x8c,0x44,0x6c,0x21,0x88,0xe9,0x88,0x4b,0xd1,0xb1,0xde,0x78,0x96,0x6b,0x88,0x42,0x50,0x8f,0x23,0xab,0xc6,0x4b,0xe3,0xeb,0x55,0xab,0x5a,0xe7,0xcb,0x65,0xfb,0x74,0xb6,0xee,0x96,0x3,0xc5,0x8c,0x44,0x9d,0xaf,0x5b,0xbd,0x46,0x63,0x4e,0x64,0x6a,0x72,0xb6,0x16,0xab,0xe5,0x3e,0x9e,0x7d,0xe2,0x51,0xd8,0xf5,0x81,0xbc,0xe9,0x8,0x4,0x82,0x8b,0x2,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0xc7,0xc,0x8b,0xcb,0x6e,0x80,0x36,0xd,0x9a,0xb6,0x63,0xd2,0xe,0x11,0x9a,0xc2,0x48,0x2,0x1,0x8,0xde,0x2,0x44,0x68,0xda,0x5,0xbc,0xf,0x20,0xe2,0x72,0x83,0x90,0xca,0x2e,0x48,0x69,0x20,0xf8,0x14,0xd2,0xa6,0x41,0x88,0x85,0x4,0x2c,0x16,0xc8,0xe8,0x11,0x62,0x48,0x24,0x17,0x97,0x84,0x90,0x36,0x40,0xf0,0xa5,0xf4,0xc2,0xbb,0x1,0x4a,0x1b,0x98,0x66,0x81,0x61,0x7d,0x0,0xad,0x9b,0xd4,0xac,0xeb,0x60,0xba,0x3d,0x44,0xef,0x10,0x62,0x84,0x56,0x94,0x14,0x7a,0xa,0xa4,0xc,0x37,0xf6,0x26,0xd2,0x4e,0x29,0x42,0x4,0x21,0xb8,0x1,0xda,0xb4,0xf0,0xce,0x8e,0xa4,0x13,0x0,0x28,0xd,0xc4,0x50,0xa2,0xa,0xb5,0x36,0x70,0xd6,0xa2,0x69,0x3b,0xce,0xe,0x74,0xac,0x48,0xd4,0x5a,0x23,0x4,0xf,0x6f,0x79,0x3b,0x11,0x60,0xf5,0x9f,0xe3,0x3c,0x3f,0xdd,0x74,0x89,0x7c,0x8b,0x50,0x29,0xa3,0x4f,0x29,0x8d,0xe0,0x1d,0x94,0x69,0x92,0xb2,0x11,0x70,0xb6,0x47,0xc,0x5c,0x36,0x2,0xa5,0x41,0xe0,0xf9,0x53,0xba,0x5,0xa2,0x87,0x69,0x3a,0xc4,0x18,0x61,0xda,0x5,0x10,0x43,0x69,0xf,0xd6,0xa6,0xe3,0xb9,0xf,0xae,0x58,0x49,0x49,0x19,0x28,0xad,0xe1,0xfa,0x65,0x22,0x0,0xcd,0x48,0x5e,0x6a,0xc3,0xc4,0x5b,0xf0,0xd0,0xa6,0x85,0x1d,0xd6,0xd0,0xa6,0x1,0x62,0x48,0x8d,0xc6,0xd,0x88,0x8,0xce,0xf5,0x20,0x52,0xbc,0xfd,0x9c,0x5b,0xb8,0xa1,0xdb,0x23,0x4,0x6f,0x41,0x4a,0xf1,0xb1,0xd7,0xc4,0x6d,0xc5,0xd5,0x6,0xef,0x41,0xc4,0xe7,0x81,0xd2,0x6,0x99,0xc,0xac,0x55,0x7d,0x39,0x23,0xb2,0xb4,0x1a,0xa7,0xb9,0xf3,0x8e,0xb7,0xef,0x9d,0x85,0x56,0x7a,0x24,0x11,0x95,0x2e,0x4,0x67,0x4c,0xe7,0x46,0x6e,0x97,0xd6,0x5a,0x17,0x45,0xe4,0xd8,0x5e,0xad,0x10,0xa3,0x3,0x51,0xca,0x93,0x24,0xa4,0x63,0x62,0x2,0x93,0xe7,0x25,0x80,0x94,0x46,0x70,0x16,0x4a,0xb7,0x69,0x79,0x55,0xd9,0xda,0x43,0x21,0xf5,0xb4,0x69,0xe1,0x7d,0xcf,0xdb,0xd,0xe,0x20,0x8d,0x98,0xd4,0xa3,0xda,0xb4,0xe9,0xb8,0x5d,0xb2,0xab,0x2b,0x20,0x3a,0xe4,0xb4,0x2c,0xb6,0x97,0x2b,0x84,0xc8,0xff,0x66,0x94,0x36,0x18,0x96,0x7,0x70,0x76,0x35,0x6b,0x55,0x16,0x8,0x4,0x82,0x97,0x36,0x84,0x0,0x14,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x8e,0xdb,0x97,0x7c,0xdd,0xa2,0xbb,0xe4,0x1a,0x34,0xdd,0xe,0x14,0x29,0x26,0x98,0x9c,0x4d,0x5c,0x5e,0xc3,0x6d,0xba,0xde,0x2,0x11,0xd0,0x86,0x9,0x2e,0xef,0x99,0x74,0x6a,0x9a,0x26,0xe5,0xdd,0x45,0x10,0x2,0x74,0xb3,0xc0,0xd0,0xaf,0x59,0xb5,0x17,0x1c,0xa0,0xc,0x82,0x77,0x4c,0x44,0x21,0xa6,0xa2,0xc,0x0,0x88,0x68,0xbb,0x5d,0x4,0x6f,0x11,0xbc,0x85,0x77,0x8e,0x49,0x44,0x0,0x5d,0xd7,0xa0,0xef,0x2d,0x6c,0xbf,0xc4,0x62,0x67,0xf,0xd6,0xe,0x50,0xa6,0x85,0x52,0x4c,0x2c,0xb9,0x61,0x85,0xa6,0xdb,0x65,0x72,0x2e,0xb5,0xef,0x36,0xdd,0x2,0x6e,0x58,0x17,0x92,0x26,0x24,0x22,0x31,0x46,0xc0,0xf5,0x87,0x30,0x6d,0x87,0x10,0x81,0xe8,0x7a,0x98,0xa6,0x43,0x7f,0x78,0xe,0xba,0xdb,0x5,0x0,0x84,0x61,0x9,0xbd,0x73,0xa,0x61,0x58,0x23,0x46,0xf,0xa5,0x5b,0xf8,0x61,0xd,0xd2,0x4c,0x3c,0x29,0x6d,0x30,0x1c,0x3e,0xb,0xdd,0x9e,0x0,0x14,0xab,0xbf,0x7c,0x7f,0x0,0xd5,0xee,0x22,0xba,0x1,0xaa,0xdd,0x61,0xf2,0x33,0xe7,0xee,0x5,0xb,0x90,0x61,0x6b,0x6d,0x70,0x50,0x66,0x81,0xe8,0x7,0xa8,0x76,0x81,0xe8,0x98,0x48,0x8d,0x89,0xe4,0x63,0x85,0xa5,0x41,0x8,0x16,0xba,0xdd,0x83,0xd2,0x9a,0x9,0xc6,0x30,0x66,0xed,0x51,0x2e,0x40,0x9,0x11,0x31,0x8c,0xed,0xc9,0xa6,0xdd,0x61,0x95,0x22,0x29,0x20,0x7a,0xf8,0xfe,0x0,0xcd,0xee,0xa5,0x0,0x8,0x6e,0x7d,0x16,0xa4,0x17,0x50,0x4d,0x8b,0x60,0xd7,0x50,0xba,0x81,0x5b,0x9f,0x83,0x6e,0xf7,0x40,0xba,0x41,0x70,0xc3,0xa8,0xa4,0x44,0x44,0xf4,0x96,0x8f,0x27,0x30,0x91,0x46,0x4a,0x23,0x7a,0xb,0x28,0x83,0xe8,0x7a,0xde,0x7,0x0,0x95,0x8,0x30,0x10,0x21,0xd8,0x1,0xba,0x5d,0xc0,0xf7,0x87,0x20,0xd3,0xa5,0xe5,0xd8,0xfe,0x9c,0xd5,0x99,0xca,0xb4,0x8,0xae,0x47,0x74,0x3d,0x48,0x1b,0x90,0x6a,0x41,0xba,0x61,0xe5,0x66,0xf0,0x4c,0xa8,0xda,0x25,0x93,0x8f,0xa4,0xf8,0x58,0x75,0x3,0x8a,0x21,0x11,0x90,0x1a,0x61,0x58,0x42,0xb5,0x27,0x98,0x8c,0x4b,0x73,0x96,0x6d,0xe0,0xaa,0xdd,0x83,0x1f,0x56,0xa9,0xcd,0x38,0x0,0xaa,0x1,0x10,0x26,0x6d,0xc6,0x59,0x21,0xa9,0x9a,0x5,0xa2,0x1b,0x46,0x2b,0x70,0x56,0x4b,0x2a,0x83,0xe8,0x87,0xa2,0x70,0x25,0xd5,0xb0,0x6d,0xdd,0xf5,0x20,0xd3,0xa5,0x62,0x1a,0x7,0x84,0x90,0xc8,0xe3,0x54,0xb8,0x12,0x1c,0x48,0xb7,0x69,0xce,0x14,0x6f,0x43,0x69,0x10,0x69,0x5e,0x1e,0x84,0xe0,0xd6,0x72,0x9,0x2d,0x10,0x8,0x2e,0xce,0xef,0x6,0xf2,0xee,0x25,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x1c,0x4f,0xa8,0xe6,0x4,0x54,0xbb,0x3,0xdd,0xee,0x24,0x35,0x17,0x98,0xec,0x72,0x3,0xda,0xc5,0xff,0xc7,0xde,0x9b,0x7e,0x59,0x76,0x95,0x67,0x9e,0xcf,0x1e,0xce,0xb9,0x37,0x22,0x23,0x95,0x52,0x2a,0x35,0xcf,0xb3,0x40,0x2,0x9,0x9,0x21,0x61,0x81,0x1,0x31,0xba,0x8d,0x29,0xe3,0x2a,0xdc,0x65,0xf7,0x50,0xdd,0x65,0x77,0xf7,0xdf,0xd2,0x7f,0x40,0x7f,0xa8,0xb5,0xaa,0xbb,0x56,0xaf,0x5e,0xe5,0xb2,0xbb,0x5c,0x6e,0x8f,0x60,0x30,0x98,0xc1,0x98,0x41,0x20,0x81,0x90,0xd0,0x8c,0xe6,0x1,0x9,0x49,0xa9,0x4c,0x65,0x66,0xdc,0x7b,0xce,0xd9,0x7b,0xf7,0x87,0x77,0xd8,0xfb,0x44,0x44,0x8a,0x4,0x9,0xd6,0xea,0xec,0xf7,0x57,0x8b,0x4a,0x65,0xc4,0xbd,0x67,0xd8,0x67,0xdf,0x74,0xe4,0x93,0xcf,0xf3,0x3e,0xfb,0x74,0x26,0x5e,0xd1,0x78,0x6f,0x40,0x9a,0xa8,0xc4,0xa3,0xe4,0x84,0x7e,0x63,0x3f,0xc6,0xf5,0x9,0x12,0x80,0x9a,0x99,0x69,0x6d,0x8b,0xaf,0xf3,0x1,0xc3,0x89,0xa3,0xe8,0x96,0x5b,0x58,0x1f,0x7d,0x19,0xdd,0xe6,0x99,0x70,0xec,0xea,0x72,0xe,0x8,0x91,0x9c,0x61,0x12,0xf3,0xa4,0x32,0x8c,0xa1,0x46,0x59,0xa7,0x9,0x4e,0x66,0xdc,0xe5,0x84,0xd0,0x2f,0xa9,0x2c,0x64,0x5c,0x23,0x2c,0x36,0x90,0x86,0x35,0xbb,0xfb,0xb2,0xc6,0x51,0xc9,0x75,0x96,0x39,0x42,0xcc,0xf1,0xd4,0x3c,0xc1,0x89,0x7b,0x2e,0x27,0xe4,0x34,0xd0,0xef,0x33,0xdd,0xa3,0xef,0x36,0x51,0xf2,0xc8,0x5f,0x2b,0xa0,0x52,0x93,0xc2,0xbf,0xcf,0x7c,0xbc,0x9,0x2e,0xf6,0xf4,0x37,0x24,0x11,0x83,0x40,0xc7,0xa3,0x8b,0xcd,0x70,0x71,0x89,0x34,0x1c,0x3,0x9c,0x47,0xe8,0x36,0xc8,0x9d,0x36,0xd,0x80,0xeb,0x90,0xa7,0x15,0x42,0xbf,0x64,0xc1,0xcd,0x21,0x4d,0x13,0xf2,0xfa,0xd,0xf8,0xb8,0x20,0xe1,0x74,0xdc,0x46,0xe8,0x36,0x59,0x6c,0xdb,0x66,0xf7,0xa0,0x3,0x7c,0x24,0x71,0x15,0x5,0x3e,0xf6,0x48,0xc3,0x71,0x5e,0x1f,0x4f,0xd7,0x90,0xd6,0x70,0x9e,0x45,0xbe,0xd0,0x21,0x8f,0xc7,0x11,0x37,0xcf,0x46,0x1e,0x49,0x8c,0xf2,0xa1,0x43,0x29,0x8e,0x9d,0x6b,0x40,0x1a,0x8e,0x21,0xf4,0x5b,0xbc,0x16,0x3,0x5c,0xdc,0x54,0xf1,0x32,0x74,0x4b,0xe4,0x71,0x5d,0xe3,0xbb,0x9e,0xa3,0xd5,0x20,0xd1,0xd1,0xf9,0xe,0x25,0x93,0x5b,0x8e,0x4,0xb5,0x40,0x6b,0x1f,0x16,0x40,0x9e,0x78,0x9d,0xa5,0xcd,0x98,0xc4,0xd5,0x92,0x33,0x8b,0x79,0xbc,0x4e,0xa1,0x87,0x2b,0x9,0xa5,0x48,0x7c,0x38,0xb3,0x3e,0xc7,0x73,0xd,0xd3,0x88,0x2,0x20,0x74,0xfb,0x68,0x2d,0xf9,0x39,0xd0,0xdf,0x50,0xc9,0x1,0xea,0x9c,0x43,0x1a,0xb7,0x11,0xfa,0x2d,0xa4,0xf5,0x51,0xda,0xcf,0x71,0x9,0x71,0x1,0x16,0xde,0xa3,0xce,0x77,0xbc,0x6,0x91,0x4,0x46,0x17,0x48,0x54,0xcd,0x89,0x9f,0xb1,0x83,0xf3,0x1d,0xb9,0xe,0x7d,0x87,0x3c,0xad,0xf9,0x51,0xd2,0x5e,0x20,0x61,0x91,0x67,0x32,0xfa,0x8,0x94,0x44,0x1e,0xc4,0xb8,0x44,0x49,0x23,0xf2,0xb4,0x9a,0xcd,0x6a,0x34,0xc,0xc3,0xf8,0xff,0x2a,0x26,0x0,0x1a,0x86,0x61,0x18,0x86,0x61,0x18,0x86,0x61,0x18,0x86,0x61,0x18,0xc6,0x69,0x8c,0xb7,0x25,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x17,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0xc6,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x38,0x8d,0x31,0x1,0xd0,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x63,0x4c,0x0,0x34,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x18,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0xc6,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x38,0x8d,0x31,0x1,0xd0,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x63,0x4c,0x0,0x34,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x18,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0xc6,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x38,0x8d,0x31,0x1,0xd0,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x63,0x4c,0x0,0x34,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x18,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0xc6,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x38,0x8d,0x31,0x1,0xd0,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x63,0x4c,0x0,0x34,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x18,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0xc6,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x38,0x8d,0x31,0x1,0xd0,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x63,0x4c,0x0,0x34,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x18,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0xc6,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x38,0x8d,0x31,0x1,0xd0,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x63,0x4c,0x0,0x34,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0x8c,0xd3,0x18,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xc3,0x30,0xc,0xe3,0x34,0x26,0xda,0x12,0x18,0x86,0x61,0x18,0x86,0xf1,0x8b,0x72,0xd9,0xf5,0xb7,0xe0,0xfc,0x4b,0xae,0xc4,0xc6,0xbe,0xfd,0x28,0xa5,0xa0,0x94,0x2,0xe7,0x1c,0x4a,0x29,0xf0,0x9e,0xfe,0x7d,0x31,0xa7,0x4,0x38,0x0,0x70,0x70,0x0,0x9c,0xf7,0x28,0xa5,0xf0,0x11,0xe8,0x6b,0x5,0x45,0x8f,0xe9,0xbd,0x47,0x4a,0x9,0xce,0x39,0x7a,0x85,0xf7,0x28,0x29,0xa1,0x0,0xf0,0x3e,0xa0,0x94,0xc,0xf0,0xb9,0x20,0xaf,0x71,0xe,0x25,0x67,0x38,0xef,0xe9,0x7b,0xfc,0x35,0xb9,0x16,0x0,0x28,0x39,0xf3,0x31,0x3c,0x72,0xce,0x74,0x49,0xf2,0xde,0x9d,0xc7,0x2a,0x5,0xe,0x8e,0xaf,0xab,0xc0,0xc1,0xcf,0xae,0x51,0xae,0x4d,0x48,0x69,0x42,0x8,0xf4,0xe3,0x54,0xbd,0x37,0x86,0x8f,0x5d,0x72,0x82,0xf3,0x1,0x39,0x27,0xba,0x8f,0x9c,0xe9,0x7e,0x3,0xff,0xf7,0x8e,0xf3,0x3,0x5,0x25,0x17,0x5d,0x2f,0xbd,0x5e,0xb9,0x7e,0xe7,0x74,0x1d,0xf4,0x35,0xce,0xa1,0x94,0x8c,0x92,0x33,0x62,0xd7,0x23,0xa7,0xc4,0xdf,0xcb,0x0,0xdc,0xec,0x38,0xe0,0xd7,0x7a,0x1f,0x90,0x73,0x86,0x77,0xe,0xb9,0x14,0xbe,0xc,0xfe,0x9e,0xf3,0xc8,0x7c,0x2d,0x74,0x6c,0xb9,0x1f,0x0,0x45,0xae,0x25,0x1,0x5,0x8,0x21,0x20,0xe5,0xc4,0xef,0xc9,0xbc,0xfe,0x1e,0xe,0xe0,0xdf,0x7b,0x7a,0x53,0x81,0xae,0xd3,0x6c,0x2f,0xe8,0x33,0x68,0xd7,0x1e,0xfc,0x3e,0x7e,0x7e,0x25,0xc3,0xf9,0xc0,0xdb,0x69,0x7e,0xfd,0xbb,0x9e,0x4d,0x29,0x74,0x5f,0x21,0xe8,0xfb,0x33,0xbf,0xbe,0xee,0x39,0xa7,0x6b,0x26,0xe7,0x99,0xaf,0x29,0xaf,0x5b,0xce,0x75,0xdf,0x38,0xbe,0xa6,0x66,0xfd,0x79,0x87,0xcd,0x9e,0x2b,0x9a,0xe3,0xe6,0x9c,0x68,0x7f,0xe8,0xbe,0xa5,0x63,0xd0,0x9e,0x2c,0x0,0x3f,0x3b,0xef,0x23,0x52,0x9a,0x68,0xed,0xbc,0xd7,0x7d,0x51,0x72,0x82,0xf,0xb1,0x39,0x36,0x78,0x8d,0xea,0xfd,0xca,0xb3,0xcd,0x85,0x5f,0x53,0xa0,0xeb,0xe3,0x9c,0xa3,0x67,0xc0,0xeb,0xea,0x50,0x3f,0x17,0x8e,0x6e,0x48,0xf7,0x85,0xec,0xde,0x9c,0x12,0xaf,0x5d,0x7d,0xe,0x3b,0xd7,0x70,0xe7,0x31,0xe5,0x58,0xf4,0xac,0xe8,0xcf,0x80,0xb2,0xe3,0x99,0xcb,0xde,0xf1,0x21,0xd0,0xda,0xc9,0x5e,0xe6,0xf5,0x74,0xce,0x61,0x18,0x56,0x78,0xed,0xe5,0x17,0xf1,0xb3,0x17,0x9f,0xc1,0xe1,0x9f,0x3e,0x6d,0x7f,0xd0,0x1a,0x86,0x61,0x18,0xc6,0xdb,0x88,0x6b,0xfe,0xef,0xbd,0x61,0x18,0x86,0x61,0x18,0xc6,0x9b,0x72,0xe0,0x9c,0x8b,0x70,0xe3,0x6d,0x1f,0xc2,0x81,0x83,0xe7,0x20,0xa7,0xc4,0x2,0x4c,0x69,0x7e,0xa4,0x68,0x7f,0xb4,0x68,0xa5,0x85,0x56,0x38,0x2b,0xf5,0x2b,0x8d,0x68,0xb3,0xfb,0xc7,0x93,0x56,0xac,0x78,0x93,0x97,0xa9,0x18,0xc2,0x82,0xcc,0x5e,0x5f,0xd3,0x37,0x3b,0xd6,0x1b,0xa,0x9,0x1b,0x2c,0x58,0xcd,0xb5,0xbb,0xf9,0xeb,0x44,0xa0,0xc0,0x2e,0xa9,0x64,0xf,0xa,0x54,0xcc,0x3a,0x65,0x9a,0x43,0x37,0x7a,0xe4,0xfc,0x25,0x7a,0x4f,0x27,0x39,0x44,0xf3,0xfd,0x7a,0xc9,0xa5,0x11,0x89,0xea,0xd7,0x4e,0xfe,0x6c,0xca,0x1e,0x6b,0xb1,0xf3,0x7e,0x77,0xbe,0x6f,0xaf,0x75,0xd9,0x6b,0x2f,0xbc,0xd9,0x8f,0xa1,0x6e,0x8f,0x73,0xfc,0xbc,0xf7,0xff,0xa2,0x3f,0xc2,0xba,0x3d,0xae,0xef,0x97,0xe4,0x64,0xf,0xe9,0xed,0xe2,0xe7,0x1c,0xbf,0x7d,0xae,0xa7,0xfa,0x3d,0x15,0x80,0x9d,0x3b,0xf9,0xa3,0x73,0xcd,0x5a,0x95,0xdc,0x7c,0xe8,0xde,0xe4,0xa3,0xfc,0x73,0xce,0x43,0x2,0x61,0xb3,0x6f,0x64,0x5f,0xc2,0xc1,0x79,0x37,0x13,0x4d,0xe5,0xfd,0xa5,0x64,0xac,0x4e,0x1c,0xc7,0x8b,0x4f,0x3f,0x8e,0xa7,0x1e,0xbe,0x17,0x25,0x27,0xfb,0x83,0xd7,0x30,0xc,0xc3,0x30,0xde,0x6,0xcc,0x1,0x68,0x18,0x86,0x61,0x18,0xc6,0x29,0x73,0xd3,0xfb,0x3f,0x86,0x8d,0xcd,0x2d,0xac,0x57,0xdb,0xea,0xcc,0xaa,0x2,0x59,0xd5,0x8,0xc8,0x25,0x56,0xbf,0x4e,0x9a,0x6,0x3b,0x86,0x9c,0x43,0xc9,0x73,0x61,0x4f,0x4,0x82,0xc2,0x4e,0xb4,0xaa,0x33,0x54,0xe5,0xa1,0xc8,0x31,0x1,0x72,0xc8,0xa9,0x63,0xad,0xc0,0x79,0xa7,0x9e,0xc2,0xac,0xdf,0x83,0x8a,0x7c,0x33,0xdf,0xa1,0x43,0x15,0x1e,0x0,0x75,0xac,0x89,0xbb,0x8e,0xdc,0x66,0xec,0x50,0xdb,0xa9,0xac,0xb5,0xc2,0xa0,0x8a,0x1e,0x73,0xbd,0xc6,0x79,0xf,0x7,0xd7,0xb8,0xd3,0x8a,0xba,0xc1,0x5a,0xd7,0x56,0x7b,0xfe,0x52,0xe4,0x75,0x6e,0xe6,0xa6,0x54,0x97,0x55,0xf3,0x75,0x15,0x56,0xd4,0x31,0x58,0xdd,0x73,0xe2,0x3e,0xdb,0x49,0xeb,0x88,0x44,0xb3,0x16,0xe5,0xed,0xf8,0x77,0x60,0x5e,0x80,0x9d,0xe7,0xd8,0x75,0xce,0x5f,0x56,0x38,0x3b,0x95,0xf7,0xed,0xa5,0x90,0xca,0xda,0xb8,0x9f,0x7f,0xc,0x71,0x92,0xea,0x5e,0xdc,0xf3,0xa5,0x2c,0x8c,0xf1,0x79,0x5a,0xb1,0x6b,0x26,0xbc,0xcd,0x44,0x63,0x0,0x8d,0x3,0xb2,0xa,0x62,0xf5,0x7d,0xc0,0x9b,0x4b,0xa1,0xc0,0x6e,0xb9,0x52,0x85,0xde,0xbd,0xbe,0x87,0x3d,0xa4,0x58,0x71,0x2d,0x2,0x7b,0xee,0x41,0xcc,0x5c,0x99,0xf3,0x4f,0xdf,0x49,0x34,0xf7,0x37,0x39,0xd7,0xce,0x6b,0xdb,0x4b,0x35,0x2c,0xcd,0x1e,0x6c,0x2f,0xa3,0xe8,0x73,0x38,0xf7,0xa2,0xcb,0x30,0xc,0x2b,0x3c,0xff,0xf8,0xfd,0xf6,0x7,0xaf,0x61,0x18,0x86,0x61,0xbc,0xd,0x98,0x0,0x68,0x18,0x86,0x61,0x18,0xc6,0x29,0x71,0xc9,0xb5,0x37,0x61,0xb1,0xdc,0xc4,0x38,0xac,0x91,0x73,0x42,0x29,0x99,0x44,0xae,0x99,0xe3,0xae,0x7a,0xee,0x5c,0xae,0x22,0xd6,0x4e,0xf1,0x45,0x62,0xbb,0x12,0x75,0xf4,0x8e,0x5,0x33,0x89,0x82,0x3a,0xaf,0xd1,0x59,0x11,0x5,0x51,0x0,0x57,0x28,0xea,0x2b,0x51,0x53,0x3a,0x4e,0x80,0x87,0xc7,0x38,0x8d,0x35,0xf6,0x98,0x29,0x86,0x38,0x4d,0x43,0x8d,0xc7,0x96,0x2,0xef,0xbc,0xc6,0x3c,0x45,0xa0,0xa1,0x68,0xa3,0x87,0xc4,0x5f,0x4b,0x29,0x8,0x3e,0x20,0xa5,0x44,0x5f,0xe7,0x6b,0xa7,0x68,0xa4,0x6f,0xc4,0x3a,0x89,0x3a,0x4f,0x74,0x3c,0x16,0x34,0xf2,0x38,0xb0,0xf0,0xd8,0x44,0x66,0x45,0x20,0x6b,0xa2,0xba,0x73,0x31,0xb1,0xde,0x37,0xe9,0x4c,0xa5,0x89,0xa8,0xba,0x5d,0x2,0x4a,0x3d,0xf6,0x6e,0x21,0x90,0x1f,0x46,0xa3,0xc4,0xb6,0xe2,0xe1,0xc9,0x1d,0x77,0x5,0x98,0x9,0x8e,0xd5,0x4e,0xe9,0xb0,0x97,0x6d,0x6c,0x26,0x66,0xe9,0x71,0xf8,0x3b,0x65,0xa7,0x16,0x57,0xc5,0x53,0x3d,0x5f,0x69,0x2e,0x13,0xcd,0xa5,0x7b,0xc7,0x11,0xe8,0x2a,0x5a,0xc9,0xff,0x47,0xcf,0xad,0xd9,0x65,0xa5,0x75,0x3d,0xba,0x5d,0x6b,0x83,0x1d,0xd7,0xd7,0x9e,0xbf,0x46,0x4f,0x6b,0x5c,0x95,0xe2,0xab,0xad,0x78,0xeb,0xea,0x72,0x36,0xf6,0x52,0x8d,0x35,0xeb,0xbd,0xec,0x10,0x57,0x1b,0x51,0xb7,0x5d,0xef,0x1a,0x95,0x2d,0x7a,0xd3,0xb2,0x37,0x74,0xff,0xcf,0x44,0x54,0xbf,0x43,0xd0,0xfd,0x5,0xdd,0x8b,0xce,0x1,0x4d,0xcc,0x7c,0x76,0x4c,0x52,0xd4,0xeb,0x35,0xa6,0xa9,0x79,0x60,0x60,0x51,0x17,0x7b,0x8b,0xb8,0x3b,0x44,0x68,0x89,0x49,0xd7,0x3f,0x7,0xe6,0xd7,0xd9,0x8a,0xd7,0xd5,0xed,0xba,0x43,0xfc,0x6c,0x3e,0x67,0x29,0x4d,0x48,0xd3,0x88,0xcd,0xad,0x3,0xb0,0xc0,0x92,0x61,0x18,0x86,0x61,0xbc,0x3d,0x98,0x0,0x68,0x18,0x86,0x61,0x18,0xc6,0x29,0xe1,0x43,0x9c,0x9,0x4,0xe4,0x90,0xc3,0x7c,0x8e,0x58,0x33,0x5f,0x4c,0x44,0x8e,0xe2,0xd8,0x49,0x57,0x5a,0x3f,0x50,0x8d,0x4,0xfa,0x9d,0xe,0x2a,0x76,0xcb,0xc5,0xd8,0x21,0xa7,0x54,0x67,0xfc,0x35,0x2e,0x26,0x3d,0x8f,0xf,0x24,0x8,0xa6,0x4,0xf1,0x0,0xa6,0x69,0x42,0x8,0x1,0x80,0xe3,0xb9,0x82,0x53,0x9d,0x53,0xa6,0xf7,0x51,0x78,0x66,0x1a,0x8b,0x19,0x5,0x32,0x59,0x6d,0x36,0x8b,0x4f,0xe6,0xb0,0x15,0x0,0x21,0xd2,0x9c,0x36,0x40,0x84,0xb2,0xcc,0x2f,0xf1,0x3a,0x77,0xad,0x80,0x1d,0x80,0xce,0xa3,0xa4,0x89,0x75,0xb,0xc7,0xf3,0xe2,0xd8,0xd1,0x97,0x73,0x23,0xec,0xb0,0x0,0x23,0xe6,0x32,0x57,0xe0,0xf8,0x58,0x70,0xbe,0x3a,0x18,0x4b,0x99,0x39,0x2a,0xdb,0xeb,0xae,0xe2,0x48,0xeb,0x73,0xa4,0xeb,0x13,0x61,0x49,0x84,0xb3,0x2a,0xcc,0xb9,0x1d,0xc7,0x14,0x2f,0x16,0xb,0xb6,0x5,0xfa,0x7d,0x71,0x5b,0xee,0x35,0xe7,0x51,0xbf,0xc6,0x51,0x70,0x39,0x8f,0xdb,0x33,0x6,0xcd,0x82,0x53,0x69,0xaf,0xd7,0x55,0x17,0x9d,0x8,0x8a,0x32,0x37,0xae,0x11,0x94,0xa,0xcf,0xbe,0xd3,0x59,0x7a,0x2,0xb,0x6d,0xb3,0x38,0x29,0x76,0x3a,0xcb,0x5c,0x23,0x2,0xd3,0x9,0x5c,0xe3,0xe0,0xcb,0x3b,0x22,0xa6,0x3b,0xe3,0xe0,0x22,0xee,0xa2,0x54,0xd1,0xba,0x3a,0x5f,0x5b,0xa1,0x70,0x8f,0xfb,0x6d,0xbe,0xa5,0x2,0x65,0xae,0x73,0x11,0x4b,0x11,0xd7,0x5b,0xd1,0xcf,0x51,0x9e,0xc5,0x78,0x9b,0x67,0xea,0x50,0xc5,0x43,0x16,0xd2,0xea,0xe7,0x66,0xc7,0xf9,0x1b,0xb7,0x61,0xeb,0xe7,0xa3,0xe7,0x98,0xeb,0x91,0x4b,0x75,0xbd,0xd6,0x25,0xf5,0x80,0x2b,0x3a,0x7,0x51,0x45,0xd8,0x3d,0x16,0x48,0x9e,0x45,0x2b,0xfe,0x55,0x17,0x21,0xf4,0x6b,0xb3,0x7f,0x1c,0x28,0xf3,0x59,0x9a,0xbb,0x1c,0x80,0x8d,0x6b,0x18,0x3b,0x8e,0x65,0x18,0x86,0x61,0x18,0xc6,0x5b,0xf8,0x59,0xde,0x96,0xc0,0x30,0xc,0xc3,0x30,0x8c,0x53,0xfa,0xa1,0xc1,0xd7,0x62,0x80,0xa2,0x91,0x53,0xcc,0xb,0x11,0x6a,0xc3,0x6,0x8b,0x76,0x55,0x4,0x20,0xb7,0x11,0x89,0x1c,0x52,0x80,0x21,0x4e,0xb9,0x52,0x8a,0x96,0x18,0x90,0xf8,0xd7,0x23,0x73,0xa1,0x80,0x26,0x2b,0xf9,0xf7,0x99,0xb,0x27,0x9c,0xf3,0x54,0x34,0x2,0x2e,0xc,0x61,0xc1,0xce,0x7,0x2a,0x87,0x48,0x69,0x22,0xd7,0x9e,0xf3,0xf0,0x21,0xd4,0xb2,0x7,0x90,0x60,0x18,0x63,0x7,0xe7,0x1c,0x62,0xd7,0xb1,0x3,0x91,0x22,0xba,0x6e,0x87,0x70,0xe1,0x9c,0x47,0x8c,0x9d,0x96,0x34,0x78,0xef,0xf9,0xfa,0x4b,0x15,0xba,0x9a,0x82,0x88,0x92,0x59,0x90,0xe4,0xdf,0xab,0x28,0x52,0xc4,0xd9,0x57,0xb,0x30,0xa,0xe6,0xbf,0xa7,0x2,0x8b,0xa2,0x45,0x9,0x59,0xc4,0x22,0x5e,0x6a,0xb9,0x87,0x5a,0x94,0xe2,0x66,0xf2,0x5f,0x9d,0x7b,0xd8,0xce,0x50,0x14,0x31,0x96,0xaf,0xd7,0x61,0xe6,0xaa,0x54,0x11,0xaa,0x15,0x6f,0xc1,0x22,0x5f,0xd9,0x4b,0xd4,0x2a,0x5c,0x0,0xb2,0x33,0xce,0xed,0x54,0xc8,0xda,0xe9,0x8a,0x6b,0xc5,0xaf,0xb9,0x7e,0xe7,0x55,0x0,0x73,0x40,0x23,0xbc,0x42,0xd7,0x1a,0x68,0x4,0x63,0x60,0x7e,0x4c,0x89,0x8c,0xe7,0xbc,0xeb,0x98,0xbb,0xaf,0x7b,0x87,0x4b,0xb0,0x89,0x9b,0xb6,0xe,0xcb,0x32,0x9b,0xf7,0xc8,0xc2,0xa2,0x88,0x56,0xed,0xb5,0xb7,0xd7,0xb4,0xe3,0xf2,0x44,0x98,0x73,0x4d,0xc1,0x85,0xac,0x33,0x7d,0x3f,0xcf,0xd6,0xdb,0x79,0xa7,0x8e,0x5a,0xdd,0x47,0x33,0xb1,0x93,0xae,0x55,0xf6,0x7b,0xfb,0xb9,0xd2,0x35,0x6b,0xb5,0x32,0x87,0x46,0xac,0xd,0xf4,0x4c,0x1c,0x9a,0x58,0x7b,0xdd,0xdb,0xb3,0xfd,0xa4,0xc2,0xe4,0x8e,0x48,0xff,0x1e,0x9c,0x74,0xd6,0xa0,0x73,0xb3,0xf5,0xa9,0xf7,0x5c,0x66,0x5,0x36,0xb3,0x3f,0x2e,0x9a,0x67,0xd2,0xba,0x37,0xdd,0xaf,0x72,0xd6,0xa2,0x61,0x18,0x86,0x61,0xfc,0xff,0xed,0x67,0x79,0x5b,0x2,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x85,0x34,0xd,0x40,0x33,0x37,0x6e,0xf6,0x17,0x76,0xb1,0x6e,0x35,0x8e,0xb4,0x36,0xbe,0x2a,0xaf,0x25,0x51,0xd0,0x37,0xed,0xaa,0x89,0x1d,0x73,0x4e,0xe3,0xbb,0xde,0x7,0x64,0x76,0xda,0x69,0x74,0xd4,0x57,0x31,0x2d,0x84,0xa8,0xef,0x9,0x31,0x90,0xa3,0xaf,0x14,0xfa,0x7a,0xd3,0xec,0xeb,0x59,0x58,0x11,0x5,0xd1,0x3b,0x5f,0xa3,0xba,0x2c,0x56,0x89,0xe8,0x52,0x50,0xd0,0xf5,0x8b,0x59,0x3,0xb1,0xf3,0x41,0xa4,0x17,0xa4,0x69,0x84,0x6f,0x66,0xfb,0x69,0xcb,0x2c,0xdf,0x9f,0x88,0x1d,0x5e,0x4,0x15,0x3e,0xaf,0x8,0x2a,0x21,0xc6,0xaa,0x74,0xf0,0x75,0x91,0x28,0x59,0x9d,0x68,0x21,0x4,0x3e,0x2f,0x5d,0x9b,0x1c,0x2b,0x17,0x12,0xa0,0xb2,0x44,0x9f,0x9b,0x6,0x5d,0x11,0xce,0xb4,0x55,0x59,0x22,0xad,0xb9,0x71,0x5b,0x36,0xe,0x2c,0x27,0x42,0xa2,0x6f,0xe7,0xe,0x42,0x1b,0x6e,0x75,0x6c,0x1d,0xdf,0x67,0x8d,0xd6,0x4a,0x44,0xd9,0x35,0x42,0x2a,0x9a,0x28,0x6b,0x13,0x15,0x6d,0x23,0xe1,0x6d,0x53,0xad,0x5e,0x7,0x3f,0x1f,0x6e,0x46,0x6e,0xdf,0xe4,0x58,0x24,0xae,0xae,0xb3,0x1d,0x8d,0xce,0x3b,0xf6,0xe4,0xde,0x73,0x7,0x73,0x73,0x2c,0xec,0x72,0xac,0xcd,0x44,0xa5,0x76,0x5d,0xf8,0xf5,0xb2,0xf,0xe5,0xba,0x48,0x40,0xab,0x5,0x15,0xf5,0x58,0xb5,0x75,0xb7,0x6d,0x6a,0x6e,0x8f,0x2b,0x73,0x25,0xa5,0x2c,0x67,0x26,0x90,0xb5,0xce,0x38,0x11,0x51,0x45,0x34,0xe7,0xfd,0xbc,0x47,0x23,0x4b,0x73,0x7c,0x37,0x6f,0xbc,0x76,0x4d,0xfc,0xbe,0x8d,0xa4,0xb3,0x58,0x3b,0x2f,0xdc,0x28,0xbb,0xe2,0xc5,0x4e,0x22,0xbf,0xb3,0x28,0x2f,0x76,0x7c,0xdf,0xed,0x6a,0xd9,0x6e,0xbf,0xdf,0x32,0x8f,0x88,0xbb,0xbd,0x5b,0xb7,0x9b,0xa7,0x3f,0x2f,0x29,0x91,0xf5,0x4b,0xb3,0xfd,0x66,0x18,0x86,0x61,0x18,0xc6,0x2f,0x8f,0xfd,0x5f,0x54,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x9,0x11,0xc4,0x0,0xa8,0x33,0x4b,0xc5,0x2f,0x4d,0xcc,0xba,0xb9,0x18,0x50,0xda,0xc8,0x21,0x89,0x10,0xd5,0xa3,0x46,0x22,0x97,0x8,0x70,0xc0,0x7c,0xde,0x18,0xb9,0xe8,0x1c,0x42,0x8c,0x24,0x18,0xb2,0x60,0x90,0x73,0x6e,0xdc,0x80,0x19,0x69,0x1a,0x1b,0x81,0xc2,0xc3,0x7b,0x8f,0x10,0x2,0x72,0xd1,0x9c,0x24,0x4a,0x29,0x48,0x79,0x62,0x17,0x23,0x9,0xc,0x39,0x27,0x84,0x10,0xe9,0xf8,0x7c,0x2c,0x39,0x8e,0xcc,0x38,0x14,0xd1,0xf,0x8d,0x90,0x19,0x38,0xa,0x9d,0x75,0x46,0x60,0xbd,0x1f,0x71,0xce,0x55,0xf7,0x13,0xcd,0x28,0x24,0xb7,0x23,0x6b,0x3b,0x7c,0xed,0x25,0x97,0x59,0xbc,0x36,0xe5,0x34,0x5b,0x47,0x11,0x8f,0x9c,0x6a,0x36,0x24,0x1e,0xe5,0x94,0xeb,0xb1,0x45,0x9c,0x53,0x81,0xaa,0x71,0xf7,0xd5,0x6c,0xb3,0xa,0x2f,0x59,0xee,0x53,0x5e,0xa3,0x42,0x52,0xfd,0x91,0x90,0x44,0xb9,0x7a,0xc,0x72,0xab,0x89,0x3b,0x73,0xa7,0xe8,0x23,0xf2,0x8d,0xec,0x91,0x3a,0xdf,0x4f,0xef,0xb1,0x29,0x98,0x28,0x8d,0x6b,0x50,0xae,0xdf,0x79,0x5f,0x9f,0xb,0x1a,0xa7,0x62,0xa9,0x2,0xad,0xba,0xd2,0xf6,0x10,0xf0,0x66,0x71,0x52,0x16,0x40,0xe5,0x19,0x2,0x80,0xb,0x55,0x30,0xf5,0x3c,0x53,0x72,0xe7,0x4c,0xca,0xcc,0xb1,0x5e,0x11,0xc5,0xda,0xc2,0x96,0x9c,0x39,0x86,0x2e,0xae,0x56,0x3d,0xb5,0x53,0xb7,0x64,0x69,0xf6,0x9a,0xcc,0x97,0x94,0xbd,0x32,0x8f,0x4e,0x7,0x7d,0x6f,0xdd,0x73,0x3b,0x8a,0x4b,0x34,0x56,0x9b,0xaa,0xab,0xd3,0xb9,0x99,0x9b,0x54,0x22,0xd7,0xf2,0xfe,0xf6,0xba,0x80,0xc6,0x11,0xd9,0xcc,0xdb,0x6b,0x9f,0x81,0x1c,0xdf,0x35,0x4e,0xc3,0xd2,0x14,0xa9,0xec,0x2d,0xf0,0xf9,0x99,0x9b,0x6f,0xd7,0x9f,0xf,0x3b,0xca,0x45,0x66,0xc7,0x28,0xbb,0xe7,0x24,0x6a,0x89,0xa,0x3f,0xf3,0xdd,0x47,0xac,0xff,0x90,0x60,0x18,0x86,0x61,0x18,0xc6,0x5b,0xc7,0x66,0x0,0x1a,0x86,0x61,0x18,0x86,0x71,0x4a,0x88,0xe8,0x40,0xe2,0x41,0x6e,0x66,0x96,0xb1,0x70,0xa6,0x2d,0xb4,0xa8,0xb3,0xf2,0x9c,0xa3,0xe2,0xd,0x54,0x47,0x1b,0x9c,0x83,0x6b,0xe2,0x8a,0xde,0xcf,0x23,0xb1,0xe0,0xb2,0xe,0x1f,0x1a,0xc1,0x91,0xff,0x3b,0x4f,0x93,0xc6,0x63,0xc9,0xd,0x48,0xd1,0x5c,0x71,0x10,0x89,0x63,0xa8,0xe4,0xc4,0x73,0x0,0xd1,0x88,0x3f,0x71,0x2e,0x5e,0xb0,0x38,0x32,0x8d,0x3,0x5d,0x63,0xce,0x62,0x43,0xd2,0x7b,0x49,0x29,0xa9,0xa0,0x23,0xd1,0x63,0xbd,0x66,0xc7,0xf3,0x6,0x63,0x64,0x21,0x26,0x37,0xb3,0xfe,0x30,0x8b,0x0,0x43,0xa,0x4f,0x0,0x2e,0x99,0x48,0x8d,0xe8,0x59,0xcf,0x29,0xb3,0xe5,0xe8,0x57,0x8e,0x36,0xe7,0xc4,0x8e,0x46,0x16,0x1b,0x5d,0x51,0xa1,0x4b,0x5d,0x65,0xea,0xb0,0xc2,0xbc,0xb,0x44,0x66,0xf2,0xf1,0xac,0xbf,0xda,0xfc,0xeb,0x9a,0x67,0x5a,0x8d,0x66,0x22,0x50,0xe9,0xdc,0x41,0xe7,0x67,0x31,0xef,0x36,0x1e,0x5a,0x66,0x31,0x4d,0xa7,0xcf,0x8e,0x9f,0x4,0x76,0x96,0x86,0xb8,0x59,0x11,0xc5,0xbc,0x98,0xa4,0x34,0xee,0xb8,0x52,0xda,0x28,0xf3,0xdc,0x49,0x38,0x2f,0x91,0x80,0xc,0x4e,0x44,0x73,0x60,0x9d,0x5d,0xa7,0xe2,0x28,0x5f,0x93,0xf7,0xbe,0xd9,0xab,0x3b,0x6a,0x50,0x5c,0x23,0xd8,0x36,0xa5,0x1c,0x35,0xea,0xcd,0x6e,0x4b,0x5f,0x37,0x4e,0x66,0x17,0xab,0x14,0x60,0xd0,0x3e,0xce,0x33,0x91,0x92,0x62,0xe3,0xf4,0x9c,0x76,0xcf,0x45,0x7c,0x13,0xc7,0x5d,0x53,0xb2,0x31,0x7b,0x40,0x70,0x8,0xc1,0xd3,0xbe,0x6c,0x85,0xba,0x2c,0x6b,0xe5,0x81,0x1d,0x62,0xba,0x9c,0xb5,0x15,0x31,0xeb,0x73,0x2f,0x7b,0x3e,0x93,0x56,0x18,0x6c,0x85,0x50,0x11,0xb0,0xb1,0xc7,0xb3,0x54,0x37,0x67,0x33,0x9f,0x10,0x3b,0xce,0x57,0xe3,0xf0,0x3c,0x5f,0x93,0xaf,0x59,0x3f,0x7b,0xad,0x60,0x2d,0xfb,0x71,0x47,0x31,0x8a,0x61,0x18,0x86,0x61,0x18,0xbf,0x1c,0xe6,0x0,0x34,0xc,0xc3,0x30,0xc,0xe3,0xd4,0x7e,0x68,0x68,0x1c,0x80,0x3b,0x1b,0x7f,0xbd,0xf,0xea,0x30,0x12,0x51,0xa4,0x75,0xc,0xb5,0x73,0xcd,0x44,0x78,0x50,0x27,0x52,0x4a,0x55,0x14,0xe0,0x52,0xd,0x11,0x93,0x2,0x8b,0x7d,0x22,0xee,0x84,0x18,0x69,0x26,0x5f,0xd7,0xa9,0x2e,0xe2,0x64,0x1e,0x60,0xae,0x85,0x6,0x12,0x11,0x96,0xf3,0xf8,0x50,0x85,0xad,0xd8,0x75,0x2a,0xd0,0xe5,0x9c,0x49,0x3c,0x53,0x17,0x9a,0xab,0x4d,0xad,0x2c,0xe6,0x88,0x3,0xad,0x8d,0x86,0xca,0x3c,0x38,0x72,0xe4,0x25,0x75,0x8f,0x85,0x10,0xe9,0xde,0x7d,0xa0,0xb8,0x2e,0x8b,0x7a,0x69,0x1a,0xf5,0x5a,0x52,0x33,0xb7,0x50,0xe3,0xc9,0x21,0xd4,0xb9,0x7d,0x52,0x8,0xc1,0x25,0x13,0x22,0xf0,0x89,0xf3,0xcb,0xa1,0xce,0xc6,0xab,0x11,0x5b,0xe8,0x7b,0xda,0xd9,0x6b,0x74,0x2c,0xcc,0x4,0x3c,0x5a,0xb,0x71,0xda,0xc9,0xb3,0x72,0xbc,0x1e,0xa9,0xae,0x99,0x67,0x31,0x69,0x47,0x9,0x84,0xe7,0xb5,0x92,0x5f,0x5b,0x3d,0x55,0xce,0x21,0x73,0xed,0x6a,0xac,0xb4,0x34,0xf3,0xe6,0x6a,0xf4,0x54,0x84,0xc6,0xfa,0x8c,0x9a,0x86,0xe1,0x56,0xf8,0x91,0x36,0x69,0x11,0xa0,0x9a,0xd9,0x90,0x68,0x1a,0x66,0x7d,0x33,0xe7,0x71,0xd6,0x7a,0xec,0xd0,0xcc,0x2d,0xe4,0x98,0xf1,0xe,0xf7,0xe0,0x1c,0x8a,0x28,0x53,0x1,0x8d,0xab,0xe,0x3a,0xb9,0xba,0xa6,0x39,0x3a,0xe7,0xcc,0xfb,0x74,0x2e,0xe4,0x89,0x90,0x49,0xae,0x48,0x68,0x59,0x8a,0xcc,0xb6,0x54,0x31,0xd5,0xd5,0x58,0xbd,0xab,0x95,0xc6,0xba,0xc6,0x75,0x96,0x23,0xad,0x17,0xb5,0x53,0x7,0xbd,0xce,0xb9,0xa3,0xb1,0xcc,0x5c,0x90,0xad,0x6b,0x51,0xf6,0x90,0xce,0xcd,0xdc,0xc3,0x3d,0xa9,0xf3,0x3c,0x73,0xd9,0xf5,0x7d,0xf0,0xae,0x91,0xcf,0x52,0xbb,0xcf,0xe4,0x3a,0x65,0x5d,0x5b,0x27,0x6b,0x49,0xa9,0x39,0x47,0xfd,0x47,0x4,0xbd,0x5e,0x71,0x2b,0xee,0x9c,0x15,0x8,0x79,0x66,0xf6,0x67,0xaf,0x61,0x18,0x86,0x61,0xbc,0x2d,0x3f,0xcb,0xdb,0x12,0x18,0x86,0x61,0x18,0x86,0x71,0x2a,0x14,0x8e,0x76,0xb6,0x62,0x1,0x40,0xa2,0x4b,0x4e,0xa9,0x46,0x25,0xd1,0x44,0x3c,0xd9,0x75,0x25,0xe,0xbb,0xc2,0x5,0x1c,0xce,0x57,0xf7,0x1a,0x9,0x50,0x60,0x11,0xae,0x8a,0x51,0xe2,0xf4,0x53,0x11,0x87,0x63,0xa5,0x3e,0x4,0xa4,0x69,0x62,0xe7,0xd5,0xc4,0xc2,0x5c,0x15,0x34,0xaa,0x8b,0x8d,0x4,0x44,0x9a,0xa5,0x56,0xbf,0x9f,0xa6,0x69,0x36,0xb,0x50,0x84,0x9,0x1f,0xc2,0x2c,0xa2,0xa9,0xa2,0x66,0x3b,0xb,0xaf,0x89,0x60,0xea,0x2c,0xbe,0xc6,0xd8,0x25,0xaf,0xcd,0x39,0x69,0xdc,0xb4,0x94,0x5a,0xa0,0x42,0xe7,0xf1,0xb5,0x51,0x99,0xdd,0x7f,0x39,0x4d,0xdc,0x86,0x9c,0xd5,0x11,0x59,0x63,0xc0,0x5e,0x63,0xbd,0xb2,0x14,0x74,0x7c,0xaf,0x42,0x4f,0x15,0x50,0xd8,0x89,0xc5,0x6b,0xa8,0x45,0x1f,0xa8,0x73,0xe1,0x24,0x42,0x2c,0xf7,0xdd,0x3a,0x22,0x5b,0x97,0x5a,0x9e,0x35,0xcc,0x56,0xa1,0x55,0xee,0x2f,0x97,0x1a,0x79,0x46,0xb3,0xfe,0x3a,0xb7,0x11,0x35,0x96,0x5d,0xa3,0xc2,0x4e,0x45,0x46,0x3d,0x29,0x23,0x42,0xb0,0xa,0x4f,0x33,0x27,0x1a,0x3b,0xd0,0x7c,0x9d,0x15,0xd9,0x16,0xa1,0xc8,0xec,0x3c,0x5a,0xbf,0x30,0x73,0x94,0x96,0x42,0xf1,0x71,0x59,0x2b,0xf9,0x5a,0x2d,0x24,0x69,0xe6,0x14,0xfa,0x46,0x48,0x16,0xb9,0x2f,0xe7,0x46,0xbc,0x9a,0xbf,0x1e,0xe,0x33,0x91,0xba,0xdd,0x23,0xde,0xd7,0xf2,0x17,0xfe,0x26,0x9,0x68,0xcd,0xfe,0x94,0xb5,0xf1,0x8d,0x60,0x5d,0xcf,0xd5,0x88,0xc5,0xce,0xcf,0x4a,0x51,0xda,0x35,0x9c,0x47,0x6d,0xe7,0x2,0xeb,0xcc,0xd5,0xe7,0x5d,0xf3,0xf9,0x6a,0x4a,0x46,0x76,0xb4,0x2a,0x4b,0x51,0x8c,0x5c,0xa3,0xac,0x95,0x88,0x93,0x12,0x21,0x6f,0x45,0x4b,0x89,0xeb,0xa3,0x11,0xeb,0xdb,0x7b,0x94,0xfd,0xa9,0xe2,0xab,0xee,0xd7,0xa6,0xad,0xd9,0x69,0xf,0xf7,0xee,0xe2,0x10,0xc3,0x30,0xc,0xc3,0x30,0xde,0x32,0x26,0x0,0x1a,0x86,0x61,0x18,0x86,0x71,0x4a,0xe8,0xbc,0xae,0xf6,0x2f,0xf9,0x22,0x8,0x48,0x6b,0x6b,0x68,0x66,0xac,0x15,0x68,0x83,0xaa,0x34,0xe8,0xca,0x6b,0xe4,0xef,0xff,0x8e,0x45,0x2c,0x11,0x45,0x66,0x82,0x7,0x8b,0x6f,0x8e,0xa3,0x95,0x22,0xa8,0xa4,0x71,0xd0,0xd7,0xcc,0xc5,0x29,0x37,0x77,0xb4,0x79,0x4f,0x62,0x9f,0xba,0xa0,0x48,0xcc,0xf2,0x1c,0x8b,0xf5,0xde,0x23,0x76,0x3d,0x3b,0xad,0xe2,0x7c,0xe6,0x9f,0x50,0xa8,0xc0,0x23,0xc6,0xd8,0x68,0x24,0xe,0x8e,0x1d,0x5f,0xa1,0xeb,0xf8,0x3e,0xe8,0xb8,0x22,0x88,0xb5,0xd7,0x20,0x33,0xf4,0x9c,0xf3,0x8,0xdc,0x3c,0x2c,0xd1,0x68,0xfd,0x81,0x8c,0xd7,0x44,0xe3,0xcd,0x72,0xee,0x10,0xb5,0x60,0xa5,0x6d,0xee,0xd5,0x39,0x85,0x39,0x91,0x64,0xe2,0xab,0x68,0x52,0x1b,0x96,0xeb,0x63,0xaa,0xfa,0x9b,0x53,0xa7,0x9d,0xce,0x33,0xdc,0x11,0x95,0x15,0xc1,0x52,0x1c,0x7d,0x5a,0xe6,0x30,0xbb,0xe,0xdf,0xf4,0xbe,0x14,0x75,0xb6,0x39,0x2d,0x5a,0x29,0x5a,0x96,0x22,0x22,0xa3,0x8,0x6b,0x7a,0xcf,0xbe,0xa,0x4d,0xd5,0x7d,0xd9,0xc6,0x8f,0xdd,0x8e,0xf2,0x10,0xa8,0xdb,0x72,0xa7,0x38,0x54,0x72,0x9e,0x89,0x67,0xda,0x1e,0xac,0xf3,0x0,0x33,0xa,0x8b,0x66,0x22,0x30,0xa9,0xc3,0x11,0xb5,0x71,0x78,0xd6,0xec,0xdc,0x8a,0x57,0xc0,0xac,0x48,0x45,0x1d,0x98,0x7c,0x5f,0xad,0x90,0x46,0x5,0x37,0xa1,0x29,0x0,0x49,0xf0,0x21,0x6a,0xf1,0x8d,0x8,0xe3,0x54,0xc,0x53,0x45,0xd6,0x2a,0x3c,0xd6,0x19,0x90,0xb2,0xa7,0x24,0x1a,0xad,0x2d,0xc1,0xa8,0xe2,0xdc,0xac,0x98,0xa3,0x5a,0xef,0x54,0xcc,0x94,0x7d,0x2f,0xa5,0x2e,0x6d,0xb4,0x57,0xf6,0xa8,0x3,0x9a,0x35,0x73,0x33,0x61,0x58,0x84,0xf0,0xf6,0x33,0x2f,0xef,0xd1,0xb5,0x51,0x31,0xdc,0xa9,0x10,0x5d,0x9d,0xa7,0x79,0x26,0x8c,0x62,0x8f,0x19,0x8c,0x65,0xe7,0x9f,0x31,0xcd,0x9a,0x17,0x8b,0xff,0x1a,0x86,0x61,0x18,0xc6,0xdb,0x82,0x9,0x80,0x86,0x61,0x18,0x86,0x61,0x9c,0x12,0xad,0x98,0xa0,0x7f,0x39,0xe7,0xbf,0xb5,0xb7,0xf1,0x4c,0x75,0xc8,0x35,0xf1,0xd6,0x3a,0xb7,0xcf,0x6b,0xd1,0x81,0x67,0x11,0xad,0x75,0x12,0x49,0xe1,0x87,0x73,0x34,0xef,0x4f,0xa2,0xbc,0x72,0xfe,0x10,0x22,0x1c,0xb7,0xe5,0xc2,0x39,0xc4,0xae,0x23,0x21,0xc5,0x1,0xb1,0xeb,0x91,0xd2,0xa4,0xee,0x3b,0x94,0x82,0xd0,0xf5,0xdc,0xa2,0x5b,0x85,0x88,0x52,0x40,0x51,0x62,0x6e,0xa1,0xa5,0x58,0xb1,0xab,0xa2,0x8d,0xa7,0xa6,0x61,0xcf,0x45,0x22,0x52,0x12,0x22,0xc2,0x7,0xb5,0x14,0x27,0x84,0xd0,0xa1,0xf0,0x35,0xcd,0xae,0x4f,0xe2,0xb4,0xec,0x8a,0x22,0x81,0x31,0xa8,0xae,0x64,0x29,0xea,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x20,0x92,0x52,0x42,0x4e,0x9,0x89,0x1d,0x6f,0x21,0x46,0x8d,0xd9,0x96,0x1d,0x82,0x89,0x16,0x76,0x48,0x14,0x74,0x26,0x44,0xf9,0xda,0x4c,0x5b,0x9a,0x98,0x75,0xce,0x35,0x9a,0xcb,0xd7,0x22,0x91,0x53,0x6a,0x83,0x4d,0x3a,0x5f,0xb0,0x8d,0x58,0x8a,0x58,0xe9,0x76,0x44,0xb5,0x77,0x3e,0xdb,0x2a,0x2c,0xd6,0x88,0x70,0x15,0x58,0x4b,0x33,0x73,0x2f,0x34,0xe,0x45,0xb7,0x63,0x6,0xa0,0x47,0xce,0x4d,0xb4,0xb9,0x14,0x6d,0x26,0xf6,0x21,0x6a,0xb,0xb1,0x5c,0x83,0x2a,0x90,0xad,0xb,0xb3,0x71,0x28,0x96,0x82,0x59,0xe3,0x6c,0xfd,0x7e,0xfd,0x5a,0x75,0x14,0xb2,0x40,0xe8,0x6a,0x44,0x59,0xef,0xd5,0xbb,0x46,0x84,0xf3,0xb3,0xeb,0xe5,0x17,0x35,0x45,0x2b,0xae,0xce,0x6f,0x74,0x8e,0x4b,0x72,0x1c,0x42,0xec,0x54,0xf0,0x95,0xfd,0x2f,0x42,0xb6,0x8,0x69,0x25,0x17,0xa4,0x89,0xe6,0x64,0xe6,0xd4,0x3e,0x8f,0xea,0xce,0x94,0x7d,0xb7,0x33,0x5a,0xd,0x94,0x1d,0xd1,0xdd,0xe6,0xfa,0x5b,0x41,0x34,0x37,0x42,0xa8,0x77,0x33,0x77,0x67,0xd9,0x21,0xc6,0xd6,0x39,0x7d,0x8e,0xbf,0xe7,0x6b,0xe9,0x4c,0x23,0xe2,0xb6,0xaf,0xcd,0xba,0x6,0x75,0xe6,0xa2,0x43,0x33,0x77,0xd2,0xd5,0x88,0xbb,0xc4,0xb6,0x77,0x5d,0xb4,0xcc,0xcb,0xe4,0xff,0xde,0x29,0xf5,0x99,0xf8,0x67,0x18,0x86,0x61,0x18,0x6f,0x1f,0x26,0x0,0x1a,0x86,0x61,0x18,0x86,0x71,0x6a,0x3f,0x34,0xa8,0x63,0xaa,0x34,0x42,0x41,0x8d,0x56,0x7a,0x71,0xed,0x35,0x42,0x8a,0xf3,0x12,0xf,0xce,0x2a,0x84,0xb0,0xa2,0xa2,0xe,0x37,0x15,0x96,0x64,0xe,0x9f,0xab,0x73,0xcd,0x4a,0xd3,0xa6,0xea,0x7d,0x68,0x66,0x3,0x46,0xa4,0x69,0x84,0xf7,0x14,0x7,0x96,0x39,0x7e,0xb1,0xeb,0x49,0x80,0xa9,0xb2,0xf,0x62,0xec,0xe0,0x43,0x40,0x88,0x9d,0x46,0x36,0x43,0xec,0x74,0xae,0x9c,0x5c,0x5b,0xe6,0xe2,0xd,0x72,0xae,0x51,0x9c,0x39,0x76,0x1d,0xd2,0x34,0x91,0x98,0xc2,0xe2,0x5e,0x4e,0x93,0xce,0x87,0x93,0x79,0x7a,0x12,0xf1,0x15,0xd1,0x82,0x5c,0x5f,0x1,0x39,0x4d,0x0,0x8a,0x96,0x4f,0xe4,0xc2,0x22,0xa1,0xba,0xad,0xc0,0xa2,0xa5,0x14,0x79,0xf8,0x3a,0xb,0x4f,0xb,0x2f,0x5c,0x15,0x80,0x54,0x18,0x73,0xb3,0x48,0xea,0xcc,0x39,0xa8,0x73,0x10,0xe9,0x18,0x99,0x5d,0x82,0x12,0xa5,0x55,0xb7,0x5f,0x41,0xb3,0xd6,0x74,0xf9,0xea,0x44,0xd4,0x18,0xb2,0x9f,0x9f,0x87,0x85,0x45,0x8a,0x0,0x37,0xae,0xbb,0x5c,0x66,0x42,0x2d,0x50,0x6a,0xe4,0xb8,0x11,0x13,0xc5,0x9,0x2a,0x2d,0xc3,0x32,0x1f,0x4f,0x72,0xca,0x5a,0xa,0xc2,0x6d,0xd1,0x73,0x45,0xa8,0xa8,0x78,0x2c,0xc2,0x30,0x39,0x46,0x8b,0xba,0x32,0x65,0x4d,0x9b,0x77,0xf0,0x3d,0x37,0x82,0x26,0x3b,0xfd,0x44,0xa8,0x94,0x56,0x62,0x7e,0x41,0x8d,0xb8,0x72,0xc,0x57,0xd6,0xa0,0x46,0x6e,0xd1,0x8,0x9b,0x74,0x1f,0xb5,0xb0,0xa6,0x68,0x2b,0xb5,0xca,0x59,0xea,0xa4,0xf3,0xf3,0xb8,0xb5,0xf7,0xba,0x17,0x24,0x3a,0x8f,0x5d,0xb7,0x5b,0xdf,0x3b,0x8b,0xed,0xa2,0xba,0x67,0x45,0xb4,0x6d,0xa3,0xcf,0x24,0x4a,0xcf,0x5b,0x78,0x85,0xea,0xd2,0xac,0xef,0xa9,0x9f,0xcf,0xa4,0xc7,0xad,0xaf,0x77,0xf0,0xbe,0xa,0xdb,0xed,0x22,0xb7,0x65,0x34,0xb9,0x69,0xe6,0xd6,0x22,0xf,0x11,0x87,0x5d,0xfd,0xcc,0x17,0xd9,0xa3,0xfa,0x9,0xad,0x5b,0x72,0xd7,0x23,0xc7,0x6e,0xb7,0xa0,0x61,0x18,0x86,0x61,0x18,0xbf,0xe4,0xcf,0xf2,0xb6,0x4,0x86,0x61,0x18,0x86,0x61,0x9c,0xa,0x1a,0x3,0x6c,0xe4,0x8d,0x92,0x8b,0x46,0x2b,0x53,0x4e,0x3c,0xdf,0x4f,0x84,0xa7,0x1a,0xe5,0xf4,0x2c,0x72,0xf8,0x10,0xe6,0x2,0x95,0xfe,0xe5,0xbf,0xd4,0x32,0xd,0x3e,0x43,0x8c,0x1d,0xbc,0xf,0xea,0xb0,0x3,0x68,0xde,0xa0,0xb4,0xfc,0x76,0xfd,0x82,0x1d,0x7c,0x1d,0xc5,0x7d,0xc7,0x51,0xcf,0x23,0xc2,0x8a,0xb8,0xf5,0x74,0xee,0x9a,0x38,0x14,0x79,0xe6,0x9f,0x88,0x13,0xe3,0xb0,0x22,0x1,0xa6,0x90,0x93,0x50,0xde,0x2b,0x91,0x65,0xcf,0x6e,0x2c,0x8d,0x43,0x96,0x2,0x1f,0xb9,0x99,0x58,0x63,0x99,0x3c,0x63,0x50,0x9b,0x5f,0xc9,0xcd,0x86,0xc2,0x82,0x4c,0xeb,0x80,0x4,0x54,0x94,0x6c,0xe7,0xf8,0x49,0xf1,0x88,0xcc,0xb3,0xab,0xa2,0x18,0xaa,0x70,0x24,0xdf,0x43,0x9d,0xe9,0x56,0x9a,0xf8,0x28,0xf8,0x3a,0x45,0x88,0x23,0x57,0x9d,0xd7,0x79,0x73,0x22,0x24,0x55,0x41,0x56,0x22,0xbc,0x49,0x85,0x30,0xbd,0xa7,0xd6,0x1d,0xe7,0xf8,0xa9,0x3b,0xa8,0xc3,0x52,0x4,0x24,0x99,0x83,0x97,0x73,0x51,0xc7,0x61,0x9a,0x46,0xe9,0xdf,0xe0,0xc6,0xe6,0xa8,0xce,0x3b,0xbd,0x19,0x38,0x7d,0xce,0x12,0x23,0x4f,0x69,0xd2,0x48,0x73,0xdb,0x4,0x5d,0x4a,0x15,0x15,0x51,0xaa,0x8,0x47,0x3a,0x53,0x66,0x27,0x5d,0x75,0xe,0x4a,0x21,0x8a,0xc6,0x5c,0xb5,0x58,0xa5,0x54,0xd,0x54,0x9c,0x7a,0x8d,0xab,0xb2,0xa,0x75,0x4e,0xb,0x3a,0x44,0x80,0x96,0xd7,0x48,0x19,0x87,0x20,0x7b,0xb7,0x16,0xd1,0xb4,0x85,0x1a,0xe4,0x68,0x9d,0xc6,0x51,0xaf,0xbd,0xa8,0xc8,0xd8,0x46,0x9c,0xab,0x78,0x27,0x5,0x35,0xd2,0x30,0x2c,0xc7,0x6,0x50,0xb,0x76,0xf8,0x99,0x79,0x75,0xe,0x36,0x4e,0xd1,0x59,0xd9,0xc6,0x8e,0xe6,0x66,0x9e,0xe9,0x97,0x73,0xc2,0x34,0xc9,0x35,0x15,0x6d,0xf6,0x56,0xc7,0x1f,0xea,0xdc,0xc3,0x9c,0xa6,0x59,0x71,0x49,0xbb,0x96,0x3a,0xab,0x52,0xcf,0x58,0xe0,0x5c,0xbb,0x56,0x65,0xa6,0xea,0xed,0x74,0x98,0x16,0xec,0x35,0xeb,0xaf,0x71,0x3,0x96,0x6c,0x7f,0xf8,0x1a,0x86,0x61,0x18,0xc6,0xdb,0x40,0xb4,0x25,0x30,0xc,0xc3,0x30,0xc,0xe3,0x54,0x28,0x7b,0x44,0xf8,0xe6,0xb1,0x4e,0x6e,0x7e,0x85,0x43,0x71,0x5,0xde,0x5,0x2e,0x2b,0xc8,0x70,0x2e,0x52,0x69,0x44,0x4e,0x2c,0x62,0x84,0x5a,0xe6,0xe0,0x3d,0xf2,0x34,0x91,0xd8,0x53,0x80,0xe2,0x4a,0x75,0x8b,0x89,0x60,0xc4,0x62,0x13,0x5c,0x15,0x60,0xaa,0x40,0x47,0x6e,0xc0,0xd0,0xf5,0xf4,0xc3,0x4d,0x17,0x1a,0x41,0x7,0xe8,0xc2,0x42,0x67,0xf3,0xf5,0x8b,0x2d,0xac,0xb7,0x4f,0xcc,0xc4,0x14,0x11,0x5d,0x64,0xde,0xdf,0x34,0x8e,0x75,0x76,0x5b,0x13,0x63,0x4d,0x79,0x52,0x11,0xaf,0x20,0x6b,0x99,0x49,0xec,0x3a,0x75,0xb,0x96,0x52,0x10,0x63,0xf,0x71,0x44,0x79,0x1f,0x90,0xca,0x4,0x5f,0x9c,0x16,0x7f,0x94,0x9c,0x6b,0x69,0x82,0x77,0x4d,0xe4,0x17,0x5a,0xa,0xd2,0xa,0x4d,0x65,0x36,0x9b,0xcf,0xf3,0x72,0x94,0x2a,0x52,0x21,0x57,0x97,0x5b,0xa9,0x6d,0xbe,0x5e,0x5,0x41,0x16,0x12,0x59,0xb8,0x94,0x7b,0x4f,0xe3,0x38,0x8b,0xbc,0xaa,0x18,0xd8,0xb4,0xc8,0xca,0x22,0x8a,0x20,0x15,0xb8,0xd4,0x45,0xe6,0xd8,0x89,0xb3,0x4b,0xa,0x3a,0x44,0xe4,0x75,0x20,0x21,0x4f,0xe3,0xa4,0xa8,0xee,0x3f,0xbd,0x77,0x16,0x1e,0x8b,0x96,0xc1,0x4,0x15,0xe4,0x44,0xc0,0x4c,0x69,0x6a,0xca,0x4e,0x78,0xdd,0xe4,0xc1,0xa2,0x8a,0x9a,0x39,0x17,0x75,0x9b,0xea,0xbc,0xb9,0x46,0x3c,0xaa,0x5,0x26,0x45,0x45,0x2d,0x15,0x4f,0xb5,0xd5,0x37,0x34,0xf7,0x5b,0x1b,0x95,0x75,0xe6,0xa0,0x94,0xa3,0xe4,0x34,0x73,0xb7,0x6a,0x49,0xb,0xcf,0xc5,0x53,0x31,0xb6,0x54,0xb7,0xa0,0xec,0x5,0x47,0xea,0x29,0xcf,0x72,0x2c,0x5a,0xe6,0x21,0x22,0x79,0x8d,0xd4,0xea,0xa7,0x6a,0xd6,0x3c,0xad,0x71,0x6a,0xef,0xe0,0xf9,0xdf,0xf1,0x93,0xac,0x9,0xa0,0xb1,0x5f,0x3a,0xe7,0x34,0xdb,0xe3,0xb4,0xa7,0xc5,0xc1,0xdb,0x44,0xc9,0xbd,0x9f,0xb5,0x2d,0xfb,0x18,0x51,0x72,0x99,0x95,0xd1,0xf0,0xe0,0x43,0xbd,0x37,0x9d,0x4f,0xc8,0xfb,0x50,0x9c,0xb2,0x9e,0xf7,0x6c,0xce,0x24,0x82,0x8b,0xf3,0xb5,0x4d,0x62,0xb7,0x7f,0x8e,0xb4,0xc7,0xd0,0xfb,0x96,0x4b,0xdc,0x31,0x6b,0xd4,0x30,0xc,0xc3,0x30,0x8c,0xb7,0x86,0x39,0x0,0xd,0xc3,0x30,0xc,0xc3,0x38,0x25,0x26,0x2e,0xdf,0x68,0x45,0x92,0x9d,0x3,0xfb,0x65,0x4e,0x5d,0x4e,0x49,0xa3,0x90,0xce,0x79,0x12,0x72,0x58,0x18,0x92,0xbf,0xdc,0xe7,0x9c,0x30,0x8d,0x83,0x8a,0x46,0x25,0x93,0x38,0x15,0x23,0xcd,0xf5,0x13,0xf7,0x9f,0xcc,0xd5,0x2b,0x28,0x88,0xb1,0xab,0x22,0x1,0xc0,0x11,0xe0,0x91,0x8a,0x3a,0xba,0x4e,0x5,0x29,0x2d,0x35,0xd0,0x36,0x59,0x2a,0xe0,0x10,0x97,0x53,0x8c,0x1d,0x2,0xbb,0xcb,0xe4,0x57,0x17,0x2,0xa6,0x71,0x44,0xd7,0x2f,0xa8,0xe0,0x83,0x23,0xc3,0x72,0xf,0x21,0x4,0x38,0x1f,0xe0,0x3d,0x1d,0x4b,0xee,0xc7,0xfb,0x0,0x1f,0x22,0x72,0xaa,0x42,0x9e,0x8,0x51,0x24,0x16,0xf9,0x59,0x53,0xac,0xf,0xb5,0x69,0x58,0xfe,0x9f,0x88,0x9f,0x5a,0xf0,0x90,0x4b,0x33,0x3b,0xcf,0xeb,0x75,0x56,0xf7,0x54,0xd1,0x72,0x91,0xd6,0x3d,0xe7,0x9c,0x43,0x6e,0x66,0x8,0xfa,0xa6,0x14,0x45,0xe2,0xd7,0xe4,0xbc,0x74,0xfa,0xab,0x76,0x36,0x70,0x34,0xd4,0x35,0x4d,0xb0,0x29,0x4d,0xb3,0xe7,0x2b,0xe2,0x57,0x88,0x9d,0xc6,0xb7,0x51,0xca,0x7c,0xbc,0x1b,0x3b,0xc8,0x74,0x1e,0xa2,0xf7,0x2c,0x86,0x71,0xc3,0xae,0xba,0x0,0xe9,0xbe,0xf5,0xba,0xb5,0x44,0x44,0x5c,0x94,0x98,0xcd,0xb4,0x13,0xc1,0x48,0xa3,0xe2,0xba,0x6,0x45,0xe3,0xdc,0xda,0xde,0x8c,0xda,0x26,0xdb,0xba,0xe5,0xea,0xbd,0x78,0x15,0xdf,0xb4,0x28,0xa6,0xe,0xa3,0x53,0x27,0xa9,0xdc,0xbf,0x88,0x99,0x54,0x1a,0xc3,0x82,0x5e,0xb3,0xb6,0x5a,0x78,0xc1,0xfb,0x4b,0x36,0xa9,0x46,0xa8,0x4b,0x53,0x94,0xd1,0xcc,0xf0,0xa3,0xbd,0x11,0x9b,0xf9,0x93,0x5e,0xe7,0x47,0x4a,0x61,0xc8,0xec,0x9a,0x9b,0x12,0x14,0xd9,0x1f,0xb2,0x1f,0x25,0x2a,0x5f,0x85,0xd3,0xea,0x50,0xad,0x91,0xdb,0xba,0xc7,0xd4,0xed,0xd8,0xcc,0x1d,0x54,0x77,0x6b,0xd3,0x86,0x9c,0x52,0x9a,0xcd,0x9e,0x94,0x2,0x15,0x89,0xe9,0xe7,0x9c,0x91,0xa7,0xba,0xdf,0xdb,0x73,0xd4,0x19,0x84,0xbe,0x29,0x77,0xa9,0x6d,0xd3,0xf3,0x7b,0x1,0x54,0xf0,0x6c,0xe3,0xe4,0x26,0xfe,0x19,0x86,0x61,0x18,0xc6,0xdb,0x82,0x39,0x0,0xd,0xc3,0x30,0xc,0xc3,0x38,0x25,0x9c,0xce,0x14,0xd3,0x5c,0xa8,0xa,0x2,0x55,0xc0,0xa9,0xae,0x31,0x71,0xe8,0x89,0x28,0x20,0x8e,0xba,0x92,0x5a,0xd7,0x13,0x17,0x6a,0xc4,0xe,0xce,0x3,0x31,0x74,0xc8,0x69,0x52,0x41,0x43,0x5,0xa7,0xae,0xa3,0xf3,0x83,0x5,0x34,0x15,0x5e,0x1c,0xfa,0xb8,0xa1,0x42,0x4e,0x8c,0x5d,0x35,0x33,0xe5,0x84,0xe0,0xa3,0xea,0x31,0x22,0x26,0xf4,0x8b,0x25,0x9,0x2c,0x21,0xea,0xb5,0x95,0x52,0xd0,0xf1,0x5c,0x40,0x89,0x7c,0x92,0x68,0x21,0xaa,0x50,0x51,0xb1,0xa,0x3e,0x22,0xa5,0xa4,0xf7,0x27,0x31,0xcf,0x18,0x3b,0x4c,0x69,0xd4,0xb9,0x67,0x25,0x67,0xc4,0xbe,0x6f,0x84,0xa4,0x3a,0x3,0x4d,0xe2,0xb4,0x14,0xa5,0xe5,0xf8,0x2a,0xb8,0xc1,0x56,0xc4,0x29,0xc8,0xcc,0xc5,0x2a,0x8a,0x14,0x9e,0xaf,0x96,0x53,0x9d,0x3b,0x98,0x39,0xd2,0x59,0x4a,0x41,0xe8,0x3a,0x4,0x44,0x75,0xca,0x15,0x8e,0x0,0x17,0x64,0x3d,0xbe,0x73,0x1e,0x2e,0x38,0x2d,0xa6,0x0,0xc0,0xb3,0xa,0x1d,0x90,0xd9,0x8d,0x17,0x1c,0xaf,0x51,0x98,0xb9,0xf6,0xe4,0x39,0x23,0xa7,0x99,0x88,0xa5,0xbf,0xba,0x42,0x42,0xab,0xc4,0xb9,0x39,0xf2,0x4c,0xe2,0xf,0xc5,0xab,0x6b,0xc,0xbb,0xf0,0x79,0xc1,0xe7,0xf1,0x2a,0x32,0x3b,0x57,0x4b,0x3b,0x74,0x46,0x9e,0xab,0xd,0xba,0x55,0x68,0xe2,0xc2,0xe,0x2d,0x59,0x81,0xee,0x43,0x99,0x59,0x29,0xa5,0x1f,0xd2,0xd6,0x5c,0x52,0x5d,0x7,0x11,0xb3,0x44,0x9c,0x84,0x2b,0x3a,0x4f,0xd2,0xc7,0x2a,0x9a,0x16,0x8e,0x62,0xcb,0xdc,0xc9,0x18,0xfd,0xac,0xd9,0x5a,0xe6,0x37,0xa2,0x71,0xbc,0xe9,0xf1,0x25,0xc6,0x2c,0x33,0x26,0x53,0x82,0x7,0x8b,0xd7,0xba,0x4e,0x14,0x91,0x26,0xf7,0x5c,0x22,0x17,0x5e,0x2b,0x20,0x8a,0xb,0x96,0xb,0x63,0x64,0x3f,0x93,0xe0,0x47,0xa2,0xa2,0x38,0x28,0x5b,0xe1,0x31,0x84,0xa0,0x85,0x26,0x69,0x1a,0xb8,0xf5,0xd9,0x3,0x8d,0x50,0xe7,0xbd,0x9b,0x35,0x2b,0xd3,0xaf,0x49,0xf7,0x76,0x68,0x3e,0x27,0x6d,0x23,0xb3,0x8a,0x9d,0xa5,0xa0,0xb8,0x2,0x57,0x6a,0xd4,0xbf,0x60,0xee,0xe,0x6e,0x85,0xc1,0xda,0xd2,0xec,0x67,0x6e,0xcc,0x52,0x92,0xf8,0x59,0xad,0xfc,0xc3,0x30,0xc,0xc3,0x30,0x7e,0x5,0x98,0x3,0xd0,0x30,0xc,0xc3,0x30,0x8c,0x53,0xfb,0xa1,0x21,0xc6,0x59,0x4d,0x41,0xdb,0xec,0x5b,0xc5,0x2c,0x12,0xa,0xbd,0xf3,0xea,0xf2,0x3,0x8b,0x1d,0x24,0xc6,0xb1,0x83,0x4b,0x9c,0x5f,0xde,0x35,0x6d,0xa7,0xec,0x26,0xca,0x52,0xf,0x40,0x4e,0x3d,0xe7,0x1c,0xba,0x6e,0xd1,0x94,0x30,0x90,0x70,0x28,0xed,0xbd,0x72,0x2d,0xb1,0xef,0x59,0x14,0xa1,0xd6,0xe1,0xc0,0xff,0x93,0xf9,0x7c,0xde,0x79,0x74,0xfd,0x82,0xdd,0x80,0x74,0x2f,0x5d,0xd7,0xab,0xd3,0x30,0x4b,0x2b,0x6f,0x88,0xe4,0xfe,0x13,0xc1,0x22,0x27,0x9d,0x75,0xd6,0x96,0x32,0x78,0x9e,0xd5,0xa6,0x6b,0x81,0x8c,0xbe,0x5f,0xaa,0xa0,0x44,0x25,0x20,0x6d,0x81,0x86,0x9f,0x89,0x70,0x12,0xc7,0x15,0x51,0x85,0xae,0x39,0x72,0x8c,0xb8,0x6b,0x12,0xc1,0xae,0x8a,0x31,0x5d,0xc7,0xf1,0x4c,0xb9,0xef,0xa8,0xeb,0xeb,0xf9,0xbd,0x59,0x8a,0x36,0xb8,0x45,0x43,0x9a,0x7e,0x65,0x2d,0x64,0xde,0xa2,0x88,0x38,0xa5,0x11,0xf3,0xc0,0x4d,0xcc,0xd4,0x50,0xeb,0x54,0xfc,0xd3,0xd9,0x87,0xce,0xd7,0x32,0x8,0x6e,0xbe,0x6d,0x1d,0x5d,0x0,0xcd,0xba,0x73,0x9e,0x5,0xbc,0xa6,0xc5,0x39,0x76,0xbd,0xa,0x89,0xa5,0x64,0xc4,0x18,0x6b,0x34,0x97,0x1d,0x7a,0xe2,0xee,0x13,0x41,0x57,0x4,0x67,0xc7,0xe2,0x96,0xec,0x37,0x79,0xfe,0xb2,0x1f,0x68,0x76,0x64,0x6d,0xf5,0x15,0x17,0xa1,0xac,0x8d,0xcc,0xb3,0xd3,0x48,0x32,0x3b,0x4a,0xb5,0xd0,0xc3,0x93,0x1b,0xe,0xd2,0x1c,0xcc,0xf7,0x5d,0x64,0x7e,0x63,0xdb,0xbc,0xdb,0xc4,0xc3,0x81,0xd6,0xa1,0x58,0xd4,0x69,0x59,0x58,0x48,0xd6,0x98,0x30,0x6a,0x13,0x72,0x8c,0x3d,0x9c,0xf,0x98,0xa6,0xb1,0xa,0x88,0x9e,0x5,0x45,0x3e,0xa6,0x43,0x13,0xa7,0x66,0x27,0xa7,0x8,0xc0,0x59,0x5,0x74,0xbf,0x63,0x96,0x5e,0x61,0xa1,0x32,0x68,0xc4,0x3e,0xe7,0x42,0xb1,0x5c,0x76,0xa2,0x92,0x8,0x9e,0xd5,0x5d,0xe8,0x58,0x24,0x8d,0x5d,0x3f,0x9b,0xd5,0x29,0xce,0xd3,0xd6,0xf5,0xd7,0x7e,0x6,0x64,0xde,0x22,0x40,0xa2,0xa4,0x38,0x74,0xc5,0x6d,0xe8,0x54,0xf8,0x93,0x59,0x84,0xb5,0x81,0x59,0xaf,0xa3,0xb6,0xdc,0x68,0x9,0x4a,0x1,0x5d,0x2f,0x7d,0x11,0x35,0x96,0x6d,0x18,0x86,0x61,0x18,0x86,0x9,0x80,0x86,0x61,0x18,0x86,0x61,0xfc,0x9a,0x7e,0x68,0x68,0x84,0x13,0xb0,0x8,0x20,0xcd,0xbc,0xe,0xec,0x22,0x73,0xd0,0x68,0xa5,0xb8,0xba,0x50,0x40,0x82,0x92,0x43,0x33,0x57,0xaf,0xce,0x33,0xf3,0x4d,0xc4,0x97,0x84,0x22,0x9e,0x27,0xc6,0x2,0xa3,0xf,0x11,0xc3,0x7a,0x5,0x1f,0x2,0xba,0x7e,0xc1,0x2d,0xbe,0x91,0xe2,0xb8,0x81,0x22,0xb9,0x12,0xf9,0x8c,0x5d,0xaf,0xee,0xc2,0xd8,0xf5,0xe4,0x44,0xd4,0xd7,0xbb,0x59,0x14,0x11,0x2c,0xa0,0x4,0x3e,0x6,0x1c,0xd0,0xf5,0xb,0x8e,0x14,0x77,0xdc,0x1e,0xec,0xb1,0xd8,0xd8,0x24,0xe1,0xad,0x80,0x85,0xa8,0x42,0x31,0x61,0x29,0x4b,0x28,0x75,0x6e,0xde,0x34,0xd,0x33,0xe7,0x9a,0xe3,0xb6,0x57,0x11,0x8b,0x64,0x4d,0x28,0xb2,0xdc,0xab,0x38,0x27,0xd7,0xdc,0xba,0xe3,0xe0,0x80,0x18,0x22,0x89,0x7d,0xec,0xb4,0x22,0xe1,0xa5,0x71,0x5d,0x8a,0xa0,0x86,0xea,0x3a,0x14,0x2b,0x9c,0x88,0x67,0x22,0xa2,0xca,0x6b,0x54,0xb0,0x73,0xd5,0x59,0xe8,0xbc,0x88,0xa2,0x4e,0xe3,0xc7,0xce,0x3b,0x9d,0x73,0x28,0x45,0xe,0x3b,0xb,0x2b,0xa8,0x0,0x6,0xb3,0xd9,0x7d,0xde,0x7b,0xe4,0x94,0x91,0x53,0x2d,0x5c,0x91,0x72,0xf,0x89,0x68,0x7b,0x2f,0xad,0xcb,0x52,0x8,0x43,0x11,0x70,0x7,0x6e,0xc7,0xe5,0x6b,0x96,0xb2,0x11,0x11,0xa1,0x68,0x8d,0x48,0xbc,0x4c,0xd3,0xc4,0x73,0xf7,0x6a,0x81,0x8a,0xd3,0x26,0xdc,0x79,0xa1,0xc4,0xce,0x78,0xb3,0x73,0xe,0x81,0x9f,0x49,0x4a,0x93,0xc6,0x5e,0xa5,0x44,0xa3,0x46,0x9d,0x63,0xf3,0x7c,0xeb,0x73,0xf0,0x2c,0xa,0x6a,0x39,0x46,0x29,0xdc,0x2c,0xc,0xdd,0xa7,0x22,0xae,0xea,0x2c,0x3d,0x8d,0xcd,0x8a,0x8e,0xe8,0x6b,0xa1,0x87,0xb4,0x5e,0x37,0x73,0x18,0xc9,0x2d,0x49,0x9f,0xa5,0xcc,0xe5,0x38,0x22,0x9e,0x7,0x16,0xc6,0x76,0x46,0xb4,0x81,0x26,0x9e,0xcb,0x2,0x27,0x9,0xab,0x41,0xdf,0x5b,0x8b,0x49,0x3c,0x3f,0x13,0x72,0x36,0xca,0xba,0xd1,0x6b,0x92,0x3e,0xe3,0x94,0xc6,0x26,0x6e,0x1c,0xe6,0xa5,0x2a,0x3c,0xd7,0x50,0x3e,0x57,0xf2,0xfd,0x76,0x6,0x67,0x15,0x12,0xe7,0xa2,0x22,0x44,0x16,0x9d,0xcd,0x22,0x84,0xfe,0x79,0xd2,0x96,0x90,0x18,0x86,0x61,0x18,0x86,0xf1,0xd6,0xb1,0x8,0xb0,0x61,0x18,0x86,0x61,0x18,0xa7,0x44,0x3b,0x43,0x4d,0x5,0x19,0xef,0x80,0xcc,0x33,0xbe,0x90,0xd5,0xd,0x48,0x62,0x5f,0xe6,0x78,0x6f,0x54,0x77,0x9f,0xce,0x8d,0xe3,0x59,0x6f,0x2a,0x5e,0xb0,0xa0,0x40,0xf3,0xf8,0xaa,0x5b,0xae,0xeb,0x17,0x2a,0xba,0xc4,0xd8,0x21,0x4f,0x13,0xc5,0x81,0xd9,0x85,0x26,0x6d,0xb8,0x12,0x53,0x94,0x22,0x86,0xc4,0x6d,0xc4,0x12,0xb5,0xa4,0xf9,0x6a,0x24,0x56,0xf4,0x8b,0xd,0x75,0x23,0x49,0xe4,0x34,0xc4,0x6e,0xe6,0x3e,0x2a,0x25,0x23,0xb3,0xe0,0xe6,0x9c,0x47,0xec,0x16,0x18,0xf3,0x8a,0x84,0xc5,0x7e,0xa1,0x6d,0xb9,0xce,0x7b,0xf4,0x2c,0xe4,0x95,0x5c,0x85,0xc0,0xe2,0xa4,0x3d,0x35,0xb1,0x93,0x89,0xd6,0xa5,0x34,0x2d,0xb1,0xda,0x2a,0xec,0x1c,0x72,0x9a,0x34,0x52,0x2a,0xf7,0x9e,0xa6,0xa4,0xeb,0x41,0xa5,0x1e,0xdc,0xa4,0xcc,0xed,0xbc,0x99,0xe3,0xc0,0xc1,0x77,0x34,0x4b,0x11,0x89,0x23,0x9e,0x3c,0xfb,0xe,0x85,0x1c,0x88,0xd2,0xae,0xcb,0x82,0x19,0xdd,0x63,0xeb,0xc4,0xe2,0x16,0xe6,0x32,0x21,0x84,0xa0,0x73,0xb,0x51,0x68,0x5d,0xa4,0x35,0x37,0xe7,0x84,0x3c,0x25,0x8e,0x47,0xc7,0xea,0x50,0x2c,0x12,0x43,0x4e,0xb5,0xc,0xc3,0x39,0xb8,0x22,0x62,0x21,0xc7,0x4c,0xa5,0x44,0x23,0x25,0x3d,0x4f,0x69,0x84,0x44,0x71,0x84,0xb5,0x2,0x15,0x78,0x3d,0xe8,0x3d,0xb1,0xb6,0x1f,0x87,0xa0,0x73,0xf7,0x44,0x51,0xb,0x81,0x8a,0x66,0x44,0x58,0xa,0xb1,0x43,0x9a,0x46,0x12,0x8a,0x9d,0x43,0x71,0x1,0x69,0x9a,0x10,0x2,0x1d,0x6f,0x2a,0x9,0x31,0x76,0xe8,0xfa,0x5,0xc6,0x61,0xad,0x2e,0xb8,0xa2,0x2d,0xca,0x1c,0xa3,0x76,0xe,0x5d,0xd7,0x53,0xec,0x3b,0xd0,0x7c,0x41,0x69,0xb8,0x16,0x91,0x39,0xf8,0x5e,0x3e,0x14,0x80,0x73,0x98,0x38,0x2a,0x4c,0xa5,0x32,0x43,0x15,0x12,0x73,0x41,0xe2,0x82,0x8c,0xd8,0xd1,0x73,0xf3,0x3e,0x50,0xec,0x1b,0x19,0x12,0xe5,0x85,0xab,0x71,0x7b,0x8a,0x54,0x4f,0x28,0xda,0xf6,0xec,0x91,0x78,0xbd,0x44,0x58,0xa3,0x68,0x71,0x9e,0xb5,0x20,0xb,0x21,0x44,0x4c,0xd3,0xa8,0xf3,0x1,0x45,0x9c,0xcf,0x29,0xb3,0x28,0x1c,0x58,0xdc,0xf6,0xfa,0x6c,0x5a,0xa1,0x4e,0x3f,0xb3,0x0,0xa6,0x69,0x50,0xd7,0x66,0x4a,0xa3,0xce,0x9f,0x14,0xd1,0xb8,0x15,0xec,0x24,0x62,0xde,0x36,0x19,0x3,0x6e,0x36,0x73,0x50,0x23,0xc4,0xa5,0xc0,0x71,0x36,0xbe,0xf0,0xcc,0x41,0x20,0x63,0x2e,0xe4,0x1a,0x86,0x61,0x18,0x86,0xf1,0x56,0x30,0x7,0xa0,0x61,0x18,0x86,0x61,0x18,0xa7,0xf6,0x43,0x83,0xce,0x32,0x63,0xa9,0xa6,0x71,0xec,0x80,0xe7,0xa0,0x81,0x5d,0x66,0xd2,0x38,0xa0,0xe5,0x17,0x8e,0xfe,0x3b,0x4d,0x63,0x75,0x7,0x35,0x62,0xf,0xb9,0xf0,0x82,0x3a,0xf6,0x72,0xe6,0x12,0xe,0x76,0xb0,0xa9,0x9b,0x2f,0x46,0x75,0x1e,0x86,0x48,0x51,0x5d,0x99,0xf5,0x26,0x91,0x60,0xe7,0xa9,0x74,0xc3,0x73,0xf1,0x47,0xec,0x3a,0x15,0x7a,0x20,0x11,0x51,0x16,0x4e,0xa8,0xcc,0xa2,0xa3,0xf7,0xf8,0x38,0x13,0x23,0x63,0xec,0xb0,0xd8,0xd8,0x87,0xae,0x5f,0x20,0xa7,0x9,0xb1,0xeb,0x10,0x38,0x2e,0xec,0xbc,0xa3,0xe3,0x86,0x4e,0x45,0x42,0x71,0x23,0xb2,0xa5,0x8f,0xdc,0x85,0x31,0x2,0xe,0x5a,0x72,0x92,0xd2,0x34,0x8b,0xdf,0x8a,0x23,0x4b,0x45,0x17,0x54,0x1,0x27,0x4,0x16,0x82,0x72,0xe2,0x56,0xdd,0x3a,0x2f,0x4e,0x9e,0x7,0xb9,0xfb,0xa0,0x8e,0x48,0x38,0xcf,0x73,0xf5,0x8a,0x96,0x92,0x88,0xe0,0xd2,0xf5,0xb,0x75,0x8e,0x39,0x5f,0x63,0xaf,0xe2,0x7c,0x6b,0x23,0xce,0x1a,0x3b,0xce,0x19,0x89,0x85,0xba,0xae,0x5f,0x90,0x8,0x9b,0x53,0xfd,0x3a,0x7f,0x8f,0xda,0x5f,0x29,0x92,0xdc,0x3a,0xe1,0xe6,0xcd,0xd1,0xd0,0x96,0x58,0x71,0x60,0x4a,0xf4,0x59,0x1b,0x92,0xd9,0x89,0x27,0xe2,0x96,0x77,0xd5,0xdd,0xc7,0xf5,0xbf,0x14,0x97,0x9d,0x46,0x2e,0x8d,0x21,0x87,0x61,0xec,0x7a,0x12,0xff,0x74,0x1e,0x25,0x89,0x77,0x12,0xdf,0x15,0xf1,0xb5,0x63,0x87,0x68,0x8,0x91,0xc4,0x3c,0x1f,0x90,0xb9,0x30,0x43,0x4,0x4c,0x89,0xaf,0xeb,0xbc,0x43,0x8e,0x6a,0x87,0x10,0x38,0xaa,0x9c,0x6b,0x54,0xb9,0x8d,0x6,0xcb,0x99,0x38,0xce,0x4e,0xcf,0x80,0x67,0x4d,0xf2,0xb3,0x93,0xc2,0xe,0x69,0x5f,0x76,0x8d,0xb,0x53,0x1d,0x78,0xcd,0xfd,0x57,0x47,0x6d,0x23,0xa8,0x71,0x2c,0x38,0xc6,0xbe,0x46,0x96,0x79,0x3f,0xe8,0x67,0x90,0x8b,0x73,0x4b,0x29,0x1a,0x35,0x16,0x31,0xd5,0x79,0xaf,0x51,0xdd,0x2a,0xaa,0x96,0x2a,0xf6,0xf1,0xfa,0x48,0x13,0xb7,0xb8,0x13,0x9d,0x77,0xea,0x2,0xd5,0x59,0x92,0x33,0x67,0xa0,0xaf,0xfb,0x9f,0xf7,0x90,0x36,0xfc,0x4a,0xc1,0x4b,0x53,0xec,0xa2,0x17,0x29,0x8d,0xca,0x39,0xed,0x6a,0x40,0xde,0xf9,0x8f,0xe,0x86,0x61,0x18,0x86,0x61,0xfc,0xf2,0x98,0x3,0xd0,0x30,0xc,0xc3,0x30,0x8c,0x53,0x62,0x1a,0x87,0x1d,0xd1,0xc2,0x3c,0x73,0xac,0x89,0x40,0xe3,0x39,0x66,0x9a,0x78,0x56,0x99,0xf7,0x9e,0x9c,0x57,0x2c,0xc6,0x65,0x89,0x41,0xb2,0x4b,0xac,0x15,0x10,0x7d,0xd3,0x8a,0xea,0xf8,0x78,0x5a,0x40,0xe1,0x43,0x3d,0x17,0xa0,0xe7,0x3e,0x78,0xd6,0x1,0x9c,0x7f,0x70,0xb,0xfb,0xf7,0x6d,0x60,0x63,0xd9,0x63,0x73,0x73,0x3,0xc1,0x3b,0xc,0xc3,0x88,0xd5,0x30,0xe1,0xd5,0xc3,0x47,0xf1,0xea,0x91,0x63,0x78,0xe9,0xd5,0x23,0x28,0xd9,0x23,0x76,0x3d,0xa6,0x71,0x40,0xbf,0x58,0x60,0x1a,0x47,0xa4,0x34,0x91,0x4b,0x6a,0x5c,0xc3,0xf9,0x80,0xbe,0x5b,0x22,0xe7,0x4c,0xae,0x30,0x9e,0xb,0x17,0x62,0xa4,0xe6,0x60,0xb0,0x7b,0xb1,0x8b,0x98,0xd2,0x84,0xcc,0x6e,0x2a,0x69,0x89,0xa5,0x8,0xf1,0x84,0xec,0x92,0xce,0x4a,0xab,0x33,0xf0,0x3a,0x8d,0x44,0xca,0xf5,0xd7,0x32,0x14,0xaf,0x62,0x49,0xd7,0xf7,0x2a,0x9c,0x65,0x2d,0x54,0xa0,0xf7,0x63,0x87,0x40,0x47,0xaf,0x49,0x5a,0x90,0x92,0xa6,0x41,0xe7,0xc8,0xc5,0xae,0x53,0x51,0x4d,0xe2,0xc2,0x68,0xc4,0x9b,0x94,0xb8,0x34,0x45,0xa,0x44,0x62,0x64,0x91,0x29,0xa2,0xe4,0xc4,0xfe,0x2b,0x71,0xbf,0x4d,0xec,0x12,0xac,0x4d,0xb3,0x41,0xe2,0xb6,0x12,0x45,0xf6,0x52,0x2c,0xc2,0x2,0xa5,0xf7,0x33,0x37,0x9a,0x34,0xe8,0x4a,0xd3,0x2c,0x40,0xae,0x35,0x1f,0xbd,0x7e,0x3f,0xcb,0x2c,0x40,0x16,0x54,0xc7,0x61,0xad,0x42,0xa8,0xea,0x4a,0x0,0x42,0xe3,0xba,0x74,0x3a,0x1b,0x6f,0x42,0xec,0x7a,0x8a,0x70,0xcb,0x3c,0xc4,0x92,0x11,0x63,0x8f,0x94,0xa8,0x91,0x9a,0xe6,0xec,0xf9,0x5a,0x6e,0x91,0x46,0x15,0x1f,0x73,0x4a,0x34,0x3f,0x31,0xf0,0x6c,0xc5,0x52,0xe0,0x83,0x57,0x97,0x9e,0xb8,0xeb,0x2,0x17,0x71,0x48,0xd1,0x85,0xc4,0xda,0xa5,0xb9,0x57,0x9c,0x74,0x12,0x13,0x2e,0xb9,0xa8,0x5b,0x51,0xe6,0x1d,0x8a,0x38,0xd8,0xa,0x89,0x22,0xc6,0xc9,0xe7,0x86,0x84,0x44,0xf6,0x33,0xba,0xda,0x5c,0xc,0x9e,0xef,0x57,0x50,0xe0,0x64,0x6d,0xd8,0xd,0x4a,0xe,0x58,0xcf,0x1f,0x45,0xa7,0x31,0x75,0x80,0x5d,0x96,0x2c,0x32,0x43,0x9d,0xa0,0xe0,0x35,0x9b,0x9a,0x39,0x98,0x68,0xda,0xab,0xbd,0x8a,0xce,0x25,0xf3,0xc,0xca,0x76,0x5f,0x6b,0xc,0x9d,0x67,0x4b,0xf2,0xbd,0x85,0x18,0x91,0xc6,0x91,0xcb,0x7c,0x78,0xf,0x34,0x6b,0xe6,0xf8,0xf7,0xf2,0x75,0x6d,0xeb,0x2e,0xd5,0x55,0x2a,0xe5,0x2a,0x2a,0x14,0x1a,0x86,0x61,0x18,0x86,0x61,0x2,0xa0,0x61,0x18,0x86,0x61,0x18,0xbf,0x7a,0xbc,0xf,0x3a,0x6f,0x4d,0xca,0x3e,0xd2,0x94,0x6a,0xa1,0x0,0xff,0xc5,0xbe,0xe4,0xc4,0x71,0x45,0x6e,0xf7,0x75,0x1e,0x91,0xdd,0x60,0x29,0x65,0x75,0x8,0xe6,0x9c,0xd8,0x51,0x36,0x9f,0x6f,0x26,0x82,0x8a,0xf,0x41,0xe7,0xad,0xd1,0x3c,0xb6,0xe,0xe,0x5,0x7,0xf,0xec,0xc7,0x75,0x97,0x9f,0x87,0x9b,0xde,0x71,0x15,0xce,0x3d,0x74,0x10,0xfb,0xf7,0x6f,0xa1,0xef,0xe2,0x4c,0x1c,0x6c,0x21,0x17,0x54,0xc2,0x89,0xed,0x15,0x5e,0x7e,0xe5,0x35,0x3c,0xf9,0xec,0x8b,0x78,0xf8,0x27,0xcf,0xe1,0x89,0xe7,0x5e,0x42,0xf2,0x1e,0x1,0xd4,0xb8,0xea,0x43,0x64,0x11,0xac,0x60,0x1a,0x7,0x44,0x16,0x3b,0x1c,0xb,0x13,0xff,0xf3,0xef,0x7f,0x12,0x57,0x5e,0x7e,0x9,0x54,0x89,0x2,0x70,0xe4,0xe8,0x31,0xfc,0xaf,0xff,0xee,0xcf,0x30,0x8e,0x34,0xff,0x4f,0xa2,0x94,0xe,0x40,0x9e,0xc6,0x5a,0x82,0x21,0x2e,0x32,0x8e,0xa5,0x4a,0xcc,0x74,0x1a,0xd7,0x24,0x90,0xa6,0xa4,0xa2,0x19,0x89,0x89,0x45,0x85,0x26,0x89,0x60,0x8a,0x50,0x7,0x7,0x75,0xa9,0x25,0x2d,0xa3,0x20,0x8d,0x49,0x66,0x20,0xa,0xe2,0x60,0x83,0xaf,0x25,0x12,0xb2,0x9e,0x28,0xd8,0x25,0x10,0xea,0x8c,0xb8,0x26,0x9e,0x4c,0xd1,0x64,0x12,0xf3,0xba,0xae,0xc7,0x7a,0xb5,0x4d,0x22,0x25,0xbb,0xc8,0x4a,0x23,0x8a,0x89,0x8,0x45,0x6b,0x3e,0xb1,0x8,0x58,0x45,0xd0,0x69,0x1a,0xd1,0x75,0x3d,0xc6,0x71,0x8d,0x10,0x58,0x7c,0xcc,0x85,0x1a,0x60,0x79,0xde,0x9f,0xc4,0x6f,0xa5,0xc,0x5,0x8e,0xa2,0xdc,0x32,0xfb,0x50,0x66,0x4a,0xca,0xdc,0x46,0x89,0x7b,0x4b,0x5c,0xd9,0xfb,0xa0,0xe7,0xf6,0xdc,0x7e,0xeb,0x43,0x54,0x7,0x5d,0x9d,0xa3,0x98,0x11,0xa2,0x5c,0x4b,0xd0,0xf5,0x47,0x13,0x7f,0x9d,0xa6,0x11,0xdd,0x62,0x49,0x31,0x5e,0x9e,0x93,0x8,0xd4,0x67,0xc,0x40,0xdf,0xab,0x6e,0x39,0x5e,0xf,0x5a,0x47,0xf0,0x3c,0x3d,0x87,0xd8,0x2d,0x78,0x6f,0x7b,0x2d,0x2c,0x19,0x87,0x15,0x15,0x96,0x8c,0x13,0x97,0xaf,0x90,0xd3,0x30,0x71,0xe4,0x39,0xc4,0x88,0xf5,0xf6,0x9,0x15,0x13,0xa5,0x45,0x79,0xe2,0x39,0x95,0x35,0x52,0xef,0x58,0x27,0xe3,0xf9,0x9c,0x4d,0x39,0xcf,0xac,0x41,0xba,0x69,0x9,0xce,0xb9,0x36,0x61,0x3b,0xef,0x34,0xe,0x5f,0x35,0x39,0xa7,0x73,0xfd,0xe0,0x78,0xe6,0x62,0xa9,0x33,0x35,0xd1,0x14,0xe2,0x50,0x74,0x17,0xb5,0x44,0x44,0x4,0x65,0x8e,0xfd,0xaa,0xc0,0xb7,0x23,0x6,0x2f,0x6e,0xdf,0x56,0xd8,0x96,0x5f,0x5b,0xe1,0xd0,0x30,0xc,0xc3,0x30,0xc,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0xf8,0x35,0xa2,0x6e,0x22,0x16,0x8e,0x74,0x96,0x5b,0xa1,0x18,0x6a,0x2e,0x34,0xa3,0x4e,0xe7,0xc8,0x41,0xa,0x22,0x48,0x34,0xf0,0xde,0x63,0x58,0xaf,0xea,0xcc,0x3d,0x76,0x56,0xd1,0x1c,0x3f,0x12,0x52,0x22,0x37,0xf3,0x8a,0xa3,0xb,0xce,0xa1,0xef,0x7b,0x5c,0x75,0xe1,0x41,0x7c,0xe4,0xfd,0xef,0xc1,0x15,0x97,0x5d,0x84,0x7d,0x9b,0x1b,0xa7,0x7c,0xcd,0xd4,0x22,0x1c,0x71,0xa0,0xdb,0xc2,0x81,0x33,0xb6,0x70,0xcd,0x95,0x97,0xe2,0xae,0x3b,0xdf,0x8b,0xd7,0x5e,0x3f,0x82,0xc7,0x9e,0x78,0x16,0xf7,0x3d,0xfc,0x24,0x1e,0x79,0xf2,0x39,0xac,0x8b,0x94,0x45,0x14,0x75,0xab,0x89,0x20,0x59,0x72,0xc6,0xbe,0xcd,0x25,0xe,0x9c,0xb1,0xb5,0x63,0x3d,0x80,0xe0,0x3d,0xd6,0x79,0x4d,0x62,0xc,0x80,0x9c,0xb8,0x88,0x41,0xa,0x31,0x74,0x36,0x5e,0x75,0xfc,0x89,0x28,0xd3,0x2f,0x37,0x30,0x8d,0x3,0x1c,0xbb,0xa0,0x24,0x4a,0x99,0x40,0x2d,0xbc,0xe2,0x4e,0xb,0x7d,0xd4,0xe8,0xb0,0x88,0x85,0x70,0x1e,0xc1,0xd7,0x58,0x75,0xd0,0x56,0x66,0x9a,0x8f,0x98,0xa6,0x91,0x5,0xa0,0x1a,0x69,0x75,0x1c,0x63,0x2d,0x8d,0x83,0xd0,0x69,0x49,0x45,0x9d,0xf9,0x46,0xef,0xa1,0x98,0xaf,0xb6,0xb2,0x2,0x48,0xd3,0x88,0xae,0xef,0x55,0xa4,0x71,0xa0,0x76,0x68,0x11,0xc0,0x9c,0xf3,0xfc,0xfc,0x27,0x75,0xe6,0x49,0x54,0x54,0xa2,0xa6,0x14,0x49,0x25,0x41,0x51,0xd6,0x37,0xc4,0x4e,0x1d,0x89,0x99,0x1b,0x61,0xbd,0xf3,0x28,0x8e,0x4,0x23,0x88,0x43,0x32,0x97,0x99,0x83,0x90,0xd6,0xcc,0x91,0xe0,0xd7,0x79,0x12,0xbe,0xbc,0x47,0x88,0x24,0x2c,0x79,0x1f,0x50,0x12,0x1d,0x83,0x9e,0xcd,0x44,0xc7,0x95,0xbd,0x7,0x50,0x8c,0xda,0x7b,0x64,0x4c,0x8,0xbe,0xd7,0x75,0x96,0xf6,0x5d,0x72,0xc7,0x75,0x2a,0xac,0x76,0x5d,0xcf,0x33,0xf,0xb9,0xdc,0x64,0x1a,0xd1,0xf5,0xb,0xf4,0xfd,0x52,0x3f,0xb,0x0,0x66,0xcf,0x82,0xd6,0x67,0xe4,0xa8,0x31,0x89,0xb0,0xe3,0xb8,0x46,0xc7,0xef,0x69,0x85,0x45,0xcf,0x9f,0xa3,0x9c,0x13,0x5c,0xf2,0xba,0x17,0xd3,0x34,0xf1,0x4c,0x43,0xcf,0x8d,0xca,0x13,0x32,0x47,0xad,0xbd,0x23,0x17,0x6a,0x60,0x47,0x67,0x4a,0x23,0xba,0xbe,0xd3,0xf8,0xad,0x77,0x1e,0x25,0xd0,0x7e,0x9a,0x86,0x35,0xc7,0xe4,0x79,0x46,0x22,0xc7,0xc6,0xa5,0xa0,0x46,0xef,0x8b,0x5,0x4d,0x29,0x90,0xa1,0xfd,0x5d,0x6a,0x5b,0x2f,0xcf,0xd6,0x2c,0x0,0xa,0x3b,0x2,0x7d,0x8,0x48,0x8d,0x7b,0xd5,0x73,0xa9,0x8a,0x88,0xf3,0x39,0x97,0x5d,0xfb,0x4e,0x67,0xa,0x0,0xea,0xc,0xae,0xc5,0x2f,0x56,0x2,0x62,0x18,0x86,0x61,0x18,0x6f,0x17,0x26,0x0,0x1a,0x86,0x61,0x18,0x86,0x71,0x6a,0x42,0x1a,0x3b,0xae,0x58,0xde,0x68,0x66,0xd1,0xc5,0x3a,0xe7,0x8b,0xff,0xa2,0xef,0x43,0x44,0x9a,0x46,0xe4,0xec,0x38,0xd2,0x4b,0x22,0x43,0xc9,0x14,0xf1,0x8d,0x3d,0xc5,0xe,0xa9,0x8d,0x35,0x4a,0x1f,0x28,0xa5,0x19,0x59,0x4c,0xe8,0xfa,0x25,0xe0,0x80,0xab,0x2e,0x3c,0x1b,0x9f,0xf9,0xc4,0x9d,0xb8,0xfc,0x92,0xb,0x11,0xe3,0xdb,0xf3,0xa3,0x4b,0x8c,0x1,0xe7,0x1e,0x3a,0x88,0x73,0xf,0x1d,0xc4,0xed,0xb7,0xde,0x88,0x9f,0xbd,0x72,0x18,0xf7,0xfc,0xe8,0x21,0x7c,0xeb,0x87,0x8f,0xe1,0xf0,0xd1,0x63,0x3a,0x4f,0x90,0x6f,0x95,0x1d,0x89,0x7b,0x9d,0x5b,0x9c,0x7d,0x7d,0x6d,0x93,0xd,0x11,0x69,0x1c,0xd0,0x2f,0x96,0x18,0xd6,0xdb,0x24,0x80,0x45,0x69,0x43,0x1e,0x79,0xee,0x5c,0x2,0x90,0x91,0x53,0xd1,0xd8,0x30,0x50,0x90,0xa6,0x91,0x67,0x2d,0x16,0xa4,0x34,0x92,0x3,0xe,0xec,0xbe,0x82,0x53,0xc1,0x8b,0xca,0x32,0x6a,0x74,0x97,0x4,0x1b,0x29,0xd7,0xc8,0x0,0x64,0x86,0xe2,0x1e,0xe5,0x2d,0x28,0x8,0x2c,0xde,0x4,0x76,0xdb,0x85,0x10,0x31,0xc,0x2b,0x38,0x57,0x1b,0x6f,0x43,0xec,0xe0,0x4b,0xe0,0x59,0x7b,0x9,0x91,0x9d,0x7b,0x5e,0x4a,0x5f,0x4a,0x26,0x27,0x28,0xcf,0x6f,0x74,0x5d,0x3b,0xa7,0x10,0x10,0x1,0xb3,0x94,0xac,0x25,0x14,0x22,0x86,0x91,0xdb,0x6d,0x42,0x9a,0x26,0x74,0xba,0x17,0xc8,0x9,0x29,0x73,0x1c,0xd5,0xbd,0xc6,0xae,0x32,0x72,0x69,0x6,0x16,0xa4,0xf8,0x1a,0x12,0xb9,0xeb,0xba,0x7e,0x41,0xfb,0x8e,0xbf,0xa7,0xb3,0xfc,0x50,0x67,0x57,0x7a,0xe7,0x90,0xb3,0x53,0x47,0xa6,0x88,0x4f,0x39,0x25,0x1e,0x8a,0x5d,0xf7,0xb3,0x73,0xc0,0x34,0x4d,0x1a,0xbb,0x6e,0xa3,0xcc,0xd3,0x34,0x22,0xe7,0x84,0xae,0x5b,0xd0,0x5a,0xc6,0x6e,0x16,0xd9,0x8e,0xb1,0xc3,0x34,0xd,0xf0,0x9e,0x66,0x45,0x6,0x8e,0xcf,0x66,0x71,0xc9,0xf2,0x1c,0xc4,0xc0,0x9f,0x11,0x75,0x89,0x92,0x6f,0x54,0x67,0x25,0xfa,0x40,0xf3,0x23,0xf3,0x54,0xe3,0xc2,0x51,0xe6,0x70,0xf2,0x75,0x8a,0x63,0x95,0x3e,0x9f,0x1,0x39,0x4f,0x3c,0x77,0xb2,0x8a,0x68,0x12,0x9f,0xcf,0xd3,0x88,0x5c,0x26,0x15,0x63,0x6b,0xd1,0x6f,0x8d,0x26,0xe7,0x92,0xd0,0xf5,0x4b,0xba,0x3e,0xc4,0x2a,0x5e,0x3b,0x7,0xc7,0x71,0x68,0x4,0xdf,0xc4,0xbf,0xc1,0xae,0xc0,0xa8,0xed,0xe0,0x12,0xdf,0xa7,0xf3,0x80,0xae,0xa9,0x11,0xa7,0x1,0x9e,0x7f,0xa9,0x2,0x20,0x66,0xdf,0x53,0x31,0xb0,0x80,0x9a,0xa2,0x6b,0xdd,0x8c,0x61,0x18,0x86,0x61,0x18,0x6f,0xe5,0xe7,0x5f,0x5b,0x2,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x85,0x34,0x4d,0xfc,0xf7,0x70,0x12,0x51,0x52,0x4e,0x3a,0xd7,0x8b,0x66,0x9f,0xcd,0x1b,0x3b,0x43,0xec,0x38,0xc6,0xb,0x6d,0x50,0xd5,0x88,0x67,0x33,0x1b,0x4f,0x4,0x21,0x11,0x35,0x0,0x9a,0x77,0xb7,0xb9,0xec,0xf1,0x99,0x8f,0xbc,0x17,0x77,0xdc,0xfa,0x6e,0x74,0xdd,0xaf,0xee,0x47,0x96,0x18,0x2,0x2e,0x38,0xef,0x10,0x3e,0xfd,0xf1,0xf,0x62,0x73,0xb9,0xc4,0x5f,0x7c,0xf9,0x6e,0x4c,0xd3,0x40,0xed,0xab,0x99,0xae,0xbb,0x8d,0x47,0xb6,0xc8,0xcc,0xbe,0x69,0xb5,0x46,0xf0,0x1,0xd3,0x34,0x20,0xc6,0x85,0x16,0x6f,0x78,0x1f,0x30,0x8e,0x3,0x62,0x24,0xf1,0xcb,0xc7,0x88,0x3c,0x4d,0x5c,0xdc,0xea,0x74,0xc6,0x9c,0xac,0x81,0xb8,0xcf,0x42,0xa0,0x79,0x81,0xd4,0xdc,0xcb,0xeb,0xd6,0x91,0xd0,0xea,0x41,0xb1,0x58,0x71,0x6f,0x89,0x23,0x4e,0x4,0x15,0xc7,0xe5,0xe,0xd4,0x44,0x5b,0xe7,0xd,0xca,0xdc,0x3f,0x2a,0x31,0xf1,0x88,0xbe,0xce,0x2e,0xf4,0x2c,0x42,0x79,0x16,0x76,0x28,0x9e,0x3c,0x68,0xdb,0xae,0x8,0x3c,0xb1,0xeb,0x49,0xf4,0xf3,0x32,0x7f,0x30,0xab,0xa0,0x25,0xef,0x25,0xe1,0xc7,0x69,0xbb,0xb1,0xf3,0x1e,0x3d,0x8b,0x4a,0x94,0x50,0x25,0x87,0x5f,0x88,0x51,0x1d,0x73,0xdd,0x62,0xd9,0x44,0xa3,0xbd,0xee,0xb1,0x69,0x1a,0x79,0x5f,0x4,0x9d,0xbf,0x97,0x25,0x46,0x2e,0x42,0x61,0x92,0x46,0x5c,0xaf,0x42,0x99,0xcc,0x29,0x4,0xe6,0x65,0x2b,0x32,0x6f,0xae,0x5f,0x2c,0x75,0xad,0x65,0x6e,0x60,0xbb,0x4e,0x24,0x78,0x76,0xfc,0x1c,0x9d,0x46,0x6f,0x75,0x36,0x1e,0x37,0xf3,0x4a,0xbb,0xb2,0x38,0x18,0x3,0xc7,0x63,0xc5,0xd5,0x97,0xa6,0x9,0x3e,0xf0,0x67,0x83,0x67,0xfb,0x41,0x67,0x13,0x76,0x70,0x91,0x9a,0x80,0x9d,0xf7,0x28,0x99,0xd6,0x3d,0xa5,0xa9,0x8a,0x63,0x1c,0x93,0x9d,0x39,0x29,0x1b,0x1,0x57,0xce,0x4d,0x73,0xa,0x3d,0x3f,0xb,0x72,0x35,0x26,0x76,0x3b,0xca,0xbc,0x4e,0x6a,0xfe,0x4d,0x75,0xcf,0xc8,0xfd,0xf2,0xfe,0xe1,0xa0,0x35,0xcf,0xa,0x74,0xda,0x68,0x3d,0xff,0x9c,0xb2,0x20,0x9d,0x12,0x39,0x41,0x53,0xd2,0x35,0x2d,0x69,0x2,0x1c,0x95,0x80,0xe4,0xb6,0x49,0xb9,0x99,0x75,0x29,0x9f,0x19,0x75,0xd6,0x4a,0x6b,0x33,0x5f,0xc3,0xac,0x34,0xc6,0x1,0xde,0x91,0x18,0x6e,0x18,0x86,0x61,0x18,0xc6,0xdb,0xf0,0x33,0xaf,0x2d,0x81,0x61,0x18,0x86,0x61,0x18,0xa7,0x42,0x8d,0xe3,0x15,0x1e,0xf7,0xe6,0x50,0x1c,0xd0,0xc5,0xe,0x29,0x25,0x64,0x9e,0x5b,0xe6,0x58,0xc0,0x11,0x87,0x9a,0xcc,0x3b,0x53,0x87,0x20,0xc7,0xfc,0xa4,0xec,0xa3,0x94,0xa6,0x55,0x95,0x5,0xa0,0xb3,0xf6,0x2d,0xf0,0xc7,0x7f,0xf0,0xdb,0xb8,0xfc,0x92,0xb,0x7f,0x89,0xeb,0xac,0x42,0xc2,0xc9,0xe6,0x2,0x9e,0xc,0xe7,0x48,0x9c,0xe9,0xfa,0x25,0xc6,0x61,0xa5,0x33,0xf5,0xfa,0xc5,0xc6,0x9e,0x42,0x4,0x39,0x3,0x3b,0xf8,0x90,0x50,0x7c,0x41,0x1f,0x3,0xa6,0x61,0xe0,0x7b,0x77,0x2c,0x7e,0x2d,0xb8,0xa0,0x63,0xac,0x62,0x8,0x6a,0xc,0x98,0x1c,0x6a,0x34,0x93,0x2f,0x76,0xbd,0xbe,0x96,0xda,0x71,0xe9,0x7b,0xa1,0xa3,0xd8,0xad,0xcc,0x10,0x4,0xa0,0x91,0xcc,0xd2,0xb4,0xd2,0x92,0x8b,0x70,0x52,0xd7,0x9f,0xf,0x11,0xde,0xd7,0x72,0x86,0x18,0xa3,0xa,0x47,0x2a,0xc8,0x0,0x3a,0x73,0x8e,0x66,0xe5,0x25,0x12,0xb0,0xba,0x4e,0x1d,0x62,0x80,0xd3,0x68,0xa8,0x14,0x3e,0xc4,0xd8,0x61,0x1c,0x7,0xba,0xd6,0xc8,0xe,0x30,0x60,0xd6,0x22,0xb,0xef,0x54,0x78,0xf2,0xc1,0xc3,0xd1,0x88,0x3c,0x72,0xe9,0x65,0x69,0xe3,0xa5,0x6b,0xcf,0x3e,0xc1,0xd1,0xa9,0x66,0xf3,0xe5,0x64,0x16,0x21,0x1c,0x8b,0x4d,0xdc,0xb4,0x4b,0x82,0x51,0xe6,0x86,0xe9,0xb8,0xa3,0x95,0x56,0x9e,0xbb,0x43,0xec,0x3b,0x2d,0xb0,0x21,0xa1,0x99,0xe6,0xdd,0x69,0xeb,0x31,0x97,0xb7,0x4c,0xd3,0x8,0xef,0x3c,0xa6,0x69,0x52,0x57,0x65,0x46,0x9d,0xb7,0x48,0xe7,0x72,0xb3,0x42,0x15,0xe7,0x3,0xba,0x3e,0xec,0x6a,0xd8,0x8d,0xb1,0xa7,0x76,0x62,0x11,0x91,0xbd,0x43,0x61,0x57,0x65,0xce,0x19,0x48,0x24,0x2,0x7b,0x6e,0x95,0x2e,0x7c,0x7c,0xfa,0x3d,0xb5,0x13,0xcb,0x7e,0xd1,0x2,0x1c,0x16,0x2,0x1,0x2a,0xe4,0x9,0x5d,0x7,0xf,0x12,0x3d,0x3,0xb,0xcc,0x52,0xfe,0x31,0xae,0x57,0xea,0x24,0x2d,0xc5,0x69,0x91,0x48,0x10,0x57,0xa1,0xcc,0xdd,0x63,0x21,0x5a,0xdc,0x96,0x39,0x25,0x78,0x16,0x14,0x43,0xe3,0xb6,0x95,0x46,0x60,0x2a,0x6,0x9,0x5a,0x56,0x22,0xd,0xca,0xad,0xf4,0x1f,0xbb,0x8e,0xcb,0x44,0xa,0x37,0x20,0x4f,0xf4,0xeb,0x34,0x6a,0x9,0x88,0xcc,0xb3,0x94,0xfd,0x54,0x5d,0x89,0x85,0x4b,0x81,0xa0,0x62,0xb1,0x61,0x18,0x86,0x61,0x18,0x6f,0xf,0x26,0x0,0x1a,0x86,0x61,0x18,0x86,0x71,0x4a,0xc8,0x8c,0x3b,0x11,0x66,0x32,0x68,0xa6,0x1a,0xcd,0xc8,0xe3,0x26,0xd4,0x52,0x80,0x94,0x10,0x78,0xbe,0x1a,0x6b,0x47,0x2c,0x2,0x89,0xfb,0xcc,0x35,0x5a,0x5a,0x99,0x39,0xcf,0x42,0x8,0xb8,0xfe,0xf2,0xb,0xf0,0xdf,0xfd,0xcb,0x4f,0xe0,0xac,0x33,0xf,0xfc,0xdc,0x6b,0x5a,0xad,0xd6,0xf8,0xd9,0x6b,0x47,0xf0,0xec,0xf3,0x2f,0xe1,0xa7,0x3f,0x7b,0x15,0xc7,0x4e,0xac,0x70,0x7c,0x7b,0x8d,0x2,0x87,0x18,0x3c,0xe,0x6c,0x6d,0xe2,0xe0,0x99,0xfb,0x71,0xde,0xa1,0x33,0x71,0xee,0xa1,0xb3,0x70,0xf0,0xcc,0x3,0xe8,0xfb,0xee,0xa4,0xc7,0xf3,0x3e,0xa8,0x7b,0x8a,0x44,0x3f,0x96,0x91,0xa4,0x91,0x74,0x7,0x59,0x4a,0x15,0x58,0x78,0x21,0xc7,0x57,0x54,0x67,0xd5,0xb0,0x5e,0x91,0x78,0xa3,0xd1,0x66,0x68,0x6b,0xb0,0x44,0x44,0x33,0x75,0x52,0x20,0x25,0x72,0x9d,0x8d,0xc3,0xba,0x89,0xa9,0x82,0x22,0xbf,0x3c,0x93,0x8d,0xa,0x1b,0xc8,0x65,0xe5,0xbc,0x87,0x87,0x43,0xf1,0xe4,0x52,0x53,0x7,0x60,0xc7,0x6e,0xbe,0x52,0xb,0x17,0xa4,0xe1,0x57,0x1a,0x63,0xd5,0x65,0xe7,0x5d,0x15,0x25,0x25,0x8a,0xea,0x3c,0x9c,0x23,0x91,0x72,0x9c,0xd6,0x58,0x2c,0x37,0xc9,0x7d,0xe7,0xc2,0xbc,0xf5,0x15,0x3c,0x7f,0x2e,0x76,0x3c,0x13,0xaf,0xa,0x3e,0x22,0x88,0x69,0xc3,0x2b,0xa,0xdd,0xaf,0x3,0xd2,0x6a,0x5b,0x67,0x10,0x86,0xd8,0x6b,0x5b,0xb0,0xcc,0xa4,0xf3,0x4e,0xca,0x3d,0xa6,0xea,0xf2,0xe3,0xfb,0xd0,0xb9,0x88,0x2a,0x98,0x75,0xec,0x12,0x74,0xea,0xce,0x2b,0x3c,0x3f,0x4f,0x66,0xfc,0x65,0x76,0xb4,0xb5,0xfb,0xcc,0xb9,0x2a,0x36,0x3b,0xef,0x69,0x2e,0xa1,0x1c,0xc3,0xd3,0xb5,0x4f,0x23,0x37,0x7,0x63,0x42,0xec,0x16,0x70,0xa0,0x58,0x31,0x3d,0x3b,0x7a,0x26,0xb1,0xeb,0x90,0xa6,0xa9,0x96,0x5d,0xb0,0xd3,0xe,0x0,0x72,0xa2,0x67,0xe7,0x5d,0xe4,0xfb,0x27,0x67,0x22,0x30,0x21,0x76,0x1b,0x98,0x86,0x41,0x1d,0x92,0x99,0xe3,0xc6,0xc3,0x7a,0x8d,0xae,0xeb,0xeb,0xcc,0x46,0x27,0xf3,0xe,0xc9,0x85,0xb8,0xde,0x3e,0x4e,0xd1,0xdf,0xae,0x23,0x27,0xa4,0x73,0x8,0x31,0xd4,0x26,0xe4,0x92,0xe1,0x8a,0x9b,0xad,0x9b,0xf,0x5e,0xb,0x5e,0xe4,0xf3,0x28,0x7b,0x5d,0x1a,0xa1,0x91,0x69,0x2f,0x84,0x10,0x59,0x0,0x5f,0x54,0x41,0x57,0xa,0x49,0x42,0x40,0xe1,0x18,0x3b,0x35,0x4c,0x37,0xce,0xbe,0xc6,0x39,0x99,0xd6,0x55,0x5c,0xd6,0x96,0x70,0x16,0x4f,0x65,0x3e,0x68,0x29,0xe4,0x62,0x4c,0x39,0x51,0x1,0x4c,0xfb,0xd9,0x2a,0xa5,0x46,0x93,0x7d,0xb0,0x3f,0x78,0xd,0xc3,0x30,0xc,0xe3,0x6d,0xc2,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x89,0xd6,0x61,0x25,0x22,0x8f,0xb6,0x79,0x72,0x53,0xa8,0x63,0xa7,0x58,0x61,0xc1,0x23,0x37,0xd1,0xc5,0xd8,0x2d,0x20,0x3,0xff,0x63,0xbf,0xa8,0xd,0xbf,0x22,0xbe,0x5,0x8f,0xcb,0xce,0x3b,0xb,0xff,0xf6,0x5f,0xff,0x36,0xb6,0xf6,0x6d,0x9e,0xf4,0x3a,0x72,0x2e,0x78,0xf9,0x95,0xc3,0xf8,0xe7,0xef,0xfd,0x8,0x3f,0x7e,0xe2,0x5,0x1c,0x39,0xbe,0xe2,0xd6,0xd7,0x50,0xaf,0xb,0xd2,0x5e,0x2b,0xb1,0x43,0x72,0x63,0x9d,0x73,0xe6,0x3e,0xdc,0x70,0xf5,0xa5,0xb8,0xf1,0xba,0xcb,0x71,0xd1,0x5,0xe7,0x62,0xb9,0xe8,0x67,0xc7,0x16,0xe7,0xa0,0x94,0x51,0x48,0x6c,0x35,0xc6,0x8e,0xc4,0xcd,0x9d,0x6b,0x2,0x9e,0x7b,0x7,0x31,0x36,0xf2,0xdc,0xb9,0xae,0xc7,0x38,0xac,0xc8,0x21,0xe8,0x3d,0x17,0x3e,0xf4,0x0,0xa8,0xf9,0x35,0x70,0xd4,0x59,0x1c,0x60,0x69,0x1a,0xd1,0xb1,0x30,0x18,0xb8,0x99,0x35,0x76,0x8b,0x99,0x3,0x4a,0xe6,0x1,0x4a,0xa9,0xa,0x4a,0xe6,0x78,0x32,0xb9,0xeb,0x4,0x15,0xfb,0xc0,0x7a,0x8f,0xf,0x48,0x13,0xc5,0x4c,0x49,0x5c,0x73,0x8,0x3e,0xd4,0x36,0x66,0x47,0x73,0xf4,0xbc,0xaf,0x42,0x91,0x88,0x45,0x1b,0xfb,0xf6,0x73,0x9,0x6,0x3b,0xb9,0x54,0x24,0xac,0x25,0x19,0x72,0x1f,0xf5,0x7e,0x42,0x8d,0x32,0xb3,0x3,0xae,0xeb,0x17,0x3a,0xdf,0x2f,0xf6,0x8b,0x26,0x96,0x4b,0x4e,0x49,0xdd,0x53,0x2c,0xfa,0x94,0x92,0x75,0xbf,0x68,0xac,0x38,0x53,0x29,0x49,0x8c,0x1d,0xb,0x88,0x22,0xc6,0x5,0x8d,0x8b,0x4a,0xbb,0xb0,0xcc,0x35,0x94,0x18,0x70,0x88,0x9d,0x36,0x2c,0x83,0xb,0x6b,0x28,0xe2,0xdc,0xa9,0xc3,0x50,0x9c,0x8a,0x60,0x31,0xd4,0x7,0x72,0xb6,0xa9,0xbb,0x8e,0x9d,0x73,0x1d,0xbb,0x42,0xa5,0x64,0x4,0x1,0xb5,0xbd,0xda,0x79,0x64,0x9e,0xef,0xe7,0xdc,0x54,0x5d,0x86,0x0,0x7c,0xec,0x90,0x44,0xa4,0xcc,0x99,0x8a,0x3c,0xd8,0xa9,0x19,0x23,0x89,0xeb,0x8b,0xe5,0x86,0x96,0x72,0xa4,0x94,0x10,0xa3,0x14,0xb3,0x4,0xac,0xb7,0x4f,0xd0,0x5c,0x4c,0x71,0xeb,0xf9,0xac,0xee,0xbf,0x34,0x4d,0x24,0xfe,0xb1,0xb3,0x34,0x76,0x1d,0x9,0x9a,0x8e,0x3e,0x6f,0xe4,0x1e,0x2c,0xb2,0x23,0x1a,0xd7,0x21,0xb,0xcc,0xa0,0x8,0xb0,0xcc,0x26,0x4,0x50,0xdb,0x92,0x5d,0x9d,0xc1,0x57,0xf4,0xde,0xf8,0x33,0xcd,0xcf,0x57,0xf6,0x9d,0x2f,0x55,0x54,0x94,0x39,0x8c,0xe3,0xb8,0xd6,0x3d,0xa5,0x71,0xf3,0x48,0x7b,0x3e,0xf8,0xa8,0xef,0xa7,0x7f,0x18,0x70,0x80,0x8a,0xdc,0xe6,0x0,0x34,0xc,0xc3,0x30,0x8c,0xb7,0x13,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x38,0x25,0x72,0x49,0xb5,0xb5,0xb3,0x81,0x22,0x80,0x8e,0x5c,0x60,0x32,0xf,0xac,0x54,0x87,0x1a,0x40,0x73,0xd8,0x5c,0x90,0x46,0x54,0x76,0xcc,0xb1,0xf0,0xe2,0x9c,0x87,0xf7,0x1e,0xe7,0x9f,0x7d,0x0,0x7f,0xf4,0x7,0x9f,0x7e,0x53,0xf1,0xef,0x67,0xaf,0xbe,0x8e,0x7f,0xf8,0xc6,0xdd,0xf8,0xe1,0xe3,0x2f,0x62,0x18,0xc8,0xa1,0x85,0x92,0xb9,0x60,0x24,0x73,0x69,0x42,0xaa,0x42,0x85,0xf7,0xe4,0xa8,0x3,0x30,0x96,0x82,0x17,0x5f,0x99,0xf0,0xd2,0xe1,0x7,0xf1,0xc5,0x6f,0xde,0x8b,0xcb,0x2e,0x3c,0x17,0x77,0xde,0x72,0x3d,0x6e,0xba,0xe1,0x1a,0xec,0xdf,0xda,0x47,0x22,0x44,0x33,0xa7,0x2c,0xb3,0xd8,0x44,0x22,0xe6,0xc9,0xd7,0xa5,0xef,0x17,0x18,0x27,0x72,0x31,0x75,0x3d,0x9,0x4b,0xd2,0xbc,0x9a,0x30,0x71,0x2b,0x6d,0x87,0x34,0x52,0xe1,0x43,0xbf,0xd8,0x20,0x77,0xe0,0x6a,0x9b,0x5,0xe,0x5f,0xc5,0xb2,0x94,0xe1,0x2,0x89,0x74,0x85,0x67,0xde,0xc9,0xb5,0x8,0x21,0x76,0x8,0xa1,0xc3,0x34,0xae,0x29,0x9e,0xbc,0xdc,0x40,0x4e,0x9,0xd3,0x34,0xa0,0xeb,0x16,0x70,0xde,0x23,0xb1,0xf0,0xd5,0x2f,0x37,0x48,0x24,0x63,0x57,0x62,0x16,0x77,0x26,0x47,0x2e,0x29,0xd2,0xd9,0xa9,0xab,0xf,0x48,0x2c,0x84,0x65,0x84,0x2e,0x62,0x5c,0x6f,0x23,0x74,0x3d,0x95,0x3e,0xb0,0x73,0x2b,0xf6,0xb,0x9d,0xd7,0x27,0xcf,0xba,0x63,0xd7,0xa4,0x1c,0xd3,0x7,0x99,0xef,0x97,0xd5,0x19,0xd6,0xb1,0xe0,0xe5,0x9c,0x3,0x42,0x40,0xce,0x54,0xa0,0x21,0xae,0x30,0x20,0x20,0x84,0x85,0xce,0xc4,0x8b,0x5d,0x87,0x69,0x1c,0x39,0xb6,0x2c,0xb3,0x11,0xa5,0x70,0xa6,0xfe,0x3e,0xb1,0x68,0xe7,0x43,0x44,0xcf,0xc5,0x31,0x9d,0xa7,0x6b,0xd4,0x39,0x7c,0x2c,0x28,0x75,0x1d,0x95,0x85,0xe4,0x9c,0xc8,0xd9,0x28,0xa5,0x23,0x2e,0xa8,0x78,0x96,0x4b,0x41,0x66,0x57,0x61,0x60,0x61,0x6e,0x1a,0x7,0x84,0x10,0xd0,0xf7,0x4b,0x12,0xb4,0x7c,0x9d,0xf5,0xe7,0xbc,0x47,0xd7,0x2f,0xb0,0xda,0x3e,0xae,0x51,0x5a,0x71,0x80,0x86,0x10,0x30,0x8d,0x63,0x9d,0xe3,0x7,0x7,0x78,0x20,0x27,0x2a,0x6a,0xf1,0xea,0x70,0x2b,0xbc,0xcf,0x38,0xa,0x8b,0x82,0x7e,0xb1,0xd4,0xfb,0x2,0xa,0x97,0xa5,0xd0,0x3d,0x51,0xb9,0xa,0xff,0xb7,0xf,0xc8,0x2e,0x21,0x84,0x4e,0x9d,0x89,0xe,0xe,0xe3,0x38,0xf0,0x7c,0x40,0x3a,0xbf,0xf3,0xdc,0x6a,0x9c,0xa7,0x2a,0x4a,0x86,0x40,0x82,0x65,0xec,0xf8,0x5c,0x24,0x32,0x8f,0xeb,0x15,0x96,0x9b,0x5b,0x18,0xc7,0x1,0xfd,0x82,0x4a,0x4e,0x28,0x36,0x4d,0xf7,0x4,0x8d,0xf1,0xe6,0xc6,0x49,0xc8,0xe7,0x2e,0x4e,0x5,0xe0,0x29,0x8f,0x3a,0xdf,0x2f,0xb3,0x20,0x38,0x4d,0x23,0x1c,0xff,0xc3,0x80,0xcc,0x6c,0x2c,0x99,0x1c,0xa4,0x24,0x2c,0x4b,0x8b,0xb4,0xb7,0x3f,0x74,0xd,0xc3,0x30,0xc,0xe3,0x6d,0xc4,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x89,0xc0,0x6e,0x3d,0xe7,0x3d,0x15,0x1a,0xb0,0x60,0x41,0xa2,0x44,0xa7,0xf3,0xd9,0x42,0x23,0x36,0xc9,0xc,0x3d,0x71,0x59,0x15,0x8e,0x17,0xa2,0x99,0xb,0x18,0xfa,0xe,0x31,0x4,0xfc,0xb7,0x9f,0xfd,0x18,0xe,0x9d,0x7d,0xd6,0x9e,0xe7,0x4e,0x29,0xe3,0xde,0xfb,0x1f,0xc6,0x5f,0x7d,0xed,0x7,0x38,0x7e,0x62,0xa5,0xc2,0x4d,0x29,0x59,0x9b,0x42,0x49,0x24,0xaa,0xb3,0x6,0x4b,0x29,0xc8,0xec,0xc,0x94,0x18,0x25,0x0,0x75,0xb9,0x3d,0xff,0xb3,0xd7,0xf1,0x9f,0xfe,0xee,0x9b,0xf8,0xe2,0x37,0x7f,0x88,0x8f,0xdc,0x7e,0x3,0x6e,0xbb,0xf9,0x9d,0xc8,0x39,0x6b,0x79,0x46,0x3b,0x93,0x90,0xa2,0xa7,0x7b,0xc4,0x11,0x59,0x19,0x8c,0xb1,0xd3,0xf9,0x6f,0x21,0x72,0x1,0x7,0x8b,0x47,0x22,0xb6,0x74,0x8b,0xa5,0xde,0xb3,0xcc,0xa0,0xcb,0x25,0x43,0xba,0x53,0xd2,0x34,0x72,0x3b,0xf2,0x58,0xe7,0xcc,0x25,0x12,0xfc,0x22,0x17,0x91,0x88,0x20,0x39,0xb1,0xb8,0x23,0xb3,0xd4,0x7c,0x8,0xe8,0x3,0x45,0x96,0xe5,0xb9,0x78,0x1f,0x30,0xae,0x57,0x34,0x2b,0x8e,0x5,0xb0,0xd8,0xd1,0xfb,0x49,0xdc,0xec,0xeb,0x1a,0x85,0x80,0x89,0x85,0x2d,0x89,0x5f,0x96,0x9c,0xd1,0x2d,0x36,0x68,0xde,0x5b,0x26,0x97,0xa3,0x7,0x3f,0xef,0x10,0x59,0x4,0x4a,0x7a,0x3c,0x71,0x8e,0x89,0x8b,0x51,0x62,0xdf,0x75,0x16,0x5e,0xd6,0x32,0xd,0x12,0x9,0x8b,0xc6,0x6e,0x49,0x6c,0xa3,0x62,0x8d,0xae,0x5f,0x60,0x1c,0xd6,0xe4,0x8a,0xec,0x48,0x58,0x4,0xef,0xbb,0xae,0x5f,0x60,0x58,0x6f,0xab,0x3b,0x32,0x73,0x6c,0x5a,0xe7,0xca,0x1,0xda,0x42,0x2c,0x2,0x62,0xeb,0x68,0x14,0xc1,0x4a,0x4,0xd1,0xc0,0xef,0x95,0x99,0x7e,0x21,0x76,0x70,0x39,0xa1,0xe4,0xa2,0x25,0x20,0x52,0xee,0x11,0xbb,0x85,0x16,0xac,0xe4,0x9c,0xe0,0x4a,0xe0,0x72,0x13,0x6e,0x6f,0x66,0x51,0x50,0xe2,0xac,0x1b,0x1b,0x3d,0xa2,0x3,0x8e,0xcb,0x4c,0x4a,0x11,0x6,0x67,0x73,0xef,0xe8,0xbd,0x14,0xab,0xed,0xf5,0xb9,0x91,0x8b,0xaf,0xd7,0xa2,0x17,0x9a,0xf5,0x58,0xb0,0xd8,0xd8,0x9c,0x9,0x6f,0x75,0x1b,0x36,0x25,0x3c,0x5,0x98,0xd2,0xa8,0x22,0x24,0x39,0x4f,0xc1,0x5,0x23,0x49,0xf7,0x73,0x4a,0x13,0x48,0xa2,0xaf,0x73,0x6,0xc5,0x71,0xd7,0x2d,0x96,0x54,0x84,0xc3,0x2d,0xce,0x80,0x53,0xa1,0x59,0x84,0xbe,0x89,0x3f,0x47,0x74,0x2f,0x1d,0x4a,0x49,0x48,0x53,0xd2,0xcf,0x4a,0xce,0x1c,0x47,0xe6,0xcf,0x40,0xc9,0x19,0xc5,0x43,0x5d,0xa4,0xb9,0x29,0x67,0x71,0xde,0x71,0x5a,0xdc,0x1,0x48,0xba,0xaf,0x45,0x48,0x34,0xc,0xc3,0x30,0xc,0xc3,0x4,0x40,0xc3,0x30,0xc,0xc3,0x30,0x7e,0x4d,0xc,0xeb,0x15,0xa,0xca,0x4c,0x7c,0x2b,0x5,0xb3,0x39,0x5d,0x14,0x79,0xd,0x1a,0xcd,0x24,0x7,0x57,0xd7,0x38,0xc3,0x9a,0xd7,0x3a,0xf,0x1f,0x3,0x62,0x8c,0xf8,0xf4,0x87,0x6e,0xc5,0x15,0x97,0xee,0x5d,0xf8,0x31,0x8e,0x23,0xbe,0xfc,0xcd,0x7b,0xf1,0xf,0xdf,0x7d,0x10,0x39,0x25,0x8e,0x5a,0x92,0x70,0x34,0x17,0xeb,0x50,0xe7,0xbf,0x39,0x60,0x1c,0x48,0x64,0xeb,0xfa,0x25,0xcd,0xae,0xcb,0x9,0xd3,0x38,0xd1,0xdc,0x3b,0x11,0x20,0x51,0xf0,0xda,0xd1,0x63,0xf8,0xf3,0x2f,0x7d,0x7,0xdf,0xf8,0xde,0x83,0x38,0xeb,0x8c,0x4d,0x6e,0xba,0xad,0x45,0x22,0x24,0xea,0x49,0x84,0x72,0x7,0x25,0xd3,0x4c,0xb6,0x28,0x22,0x1e,0xdd,0x77,0xf0,0x59,0xc5,0x16,0x69,0x53,0x95,0x78,0x28,0x0,0x15,0xef,0xbc,0x8a,0x58,0xdc,0x44,0x2b,0x71,0x6a,0x80,0xe6,0xb0,0xe5,0xac,0x2d,0xaf,0xce,0x7b,0x38,0x1f,0x78,0xbe,0x22,0x5d,0x8b,0x63,0x1,0x46,0x94,0x1f,0x11,0x37,0x73,0x2,0xbf,0xde,0xab,0xb8,0x26,0xa2,0x23,0x3d,0xa7,0x2a,0xd0,0x81,0x63,0xdd,0xb1,0x5b,0x90,0xc,0x45,0x38,0xb7,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x38,0xe4,0x80,0xbe,0x5b,0x92,0x78,0xe6,0x1c,0xa6,0x44,0x6e,0xca,0x18,0x7b,0x88,0x53,0x4d,0x1a,0x8b,0x7d,0xec,0x11,0xb8,0x81,0x37,0x25,0x9a,0xa3,0x27,0x85,0x29,0x34,0xd3,0x71,0xc1,0xa5,0x24,0x19,0x21,0xd0,0xde,0x98,0x72,0xd6,0x75,0xf3,0xde,0xc3,0x17,0xcf,0x6b,0x15,0xd4,0x4d,0xd6,0x2f,0x36,0x90,0x4b,0x82,0xf3,0x1,0x2e,0x67,0xc0,0x91,0x6b,0x74,0x58,0xaf,0xe0,0x39,0x36,0x2a,0xb3,0xd,0xdb,0xb9,0x83,0xae,0xd4,0xb9,0x71,0x69,0x22,0x31,0x51,0x44,0x2d,0x12,0xd7,0xa2,0x8a,0xba,0x12,0x47,0x25,0x81,0xaf,0xd3,0xe8,0x6f,0xec,0x3a,0x2e,0x19,0x1,0x72,0xe1,0x67,0x55,0xa,0xc5,0xac,0xb,0xc8,0x99,0x7,0xe8,0x8c,0x40,0xd9,0xdb,0x8b,0x45,0x8f,0x94,0x13,0xba,0xae,0x43,0x70,0x5,0xff,0xd3,0x7f,0xfd,0x5b,0xf8,0xf6,0x3d,0xf,0xe0,0x7b,0xf,0xfc,0x4,0x9e,0xdd,0xaf,0x22,0xe2,0x8e,0xc3,0x5a,0x5,0x54,0x29,0xc3,0x1,0x8a,0xee,0xb,0x29,0x7b,0x71,0x4d,0x64,0xbb,0xb8,0xac,0x42,0x28,0xcd,0x8,0x4,0xcf,0x5a,0xc,0xb3,0x99,0x7b,0x6d,0xa1,0x48,0xe1,0xe7,0x25,0x11,0x65,0x29,0x89,0xe9,0x17,0x4b,0x75,0x53,0x8a,0x93,0xb1,0x8a,0xe4,0x8e,0x9d,0x93,0xe3,0xec,0x9a,0x24,0xa,0x2e,0x33,0x28,0x63,0xdf,0x23,0x4f,0x13,0x47,0x9a,0x93,0x16,0x7c,0x10,0xe,0xce,0x15,0x12,0xc1,0x45,0xfc,0xe3,0xcf,0x41,0x29,0xa9,0xf9,0xb5,0xb9,0x5e,0x8e,0xd,0xeb,0xbc,0x47,0x8b,0xff,0x1a,0x86,0x61,0x18,0x86,0x9,0x80,0x86,0x61,0x18,0x86,0x61,0xfc,0xfa,0xa1,0x42,0x2,0xb0,0x48,0x50,0xea,0xaf,0xfc,0x97,0x76,0xfe,0x6b,0x3f,0x9,0x4c,0x21,0xb0,0xa0,0xe2,0xb4,0xed,0x34,0xe7,0x84,0xc5,0x62,0xc9,0x73,0xcb,0x82,0x96,0x4e,0x9c,0x7f,0xf6,0x1,0x7c,0xe0,0xf6,0x9b,0x1a,0xf1,0xa0,0x92,0x72,0xc6,0xd7,0xbe,0xf5,0x3,0x7c,0xf9,0xbb,0xf,0xd2,0x39,0x4a,0x26,0x7,0x1d,0x37,0x7,0xcb,0x7b,0xc4,0xc1,0x45,0xa2,0x64,0x46,0x29,0x35,0x5e,0x38,0xac,0xb7,0xb9,0xd8,0x23,0xd1,0x7c,0xba,0x42,0x4d,0xbf,0x65,0x1c,0x79,0xd6,0x5c,0x8f,0x9c,0x33,0x5e,0x7b,0x63,0x1b,0xaf,0x1c,0x39,0x6,0x71,0x13,0x92,0x78,0x7,0x12,0xa3,0x58,0x3c,0xd9,0xa5,0xff,0x91,0x2,0x84,0x61,0xbd,0xad,0x2,0xa7,0x38,0xf2,0xc4,0x5,0x45,0x4e,0x26,0x16,0x4a,0x12,0x50,0xa,0x89,0x3e,0x63,0x5a,0xb1,0x38,0x53,0xe7,0x1,0x92,0x50,0x16,0x6b,0x91,0x44,0x1,0x47,0x6b,0xb,0x36,0xf7,0xed,0xc7,0x38,0xac,0x59,0xb4,0xa1,0x48,0xb1,0x44,0x84,0xc5,0x51,0x15,0x58,0xbc,0xf4,0x8d,0xf0,0x97,0xa5,0xad,0x95,0x5,0x38,0x38,0x8a,0x36,0xaf,0x57,0xdb,0x33,0x37,0xa6,0x3c,0x37,0x87,0x1a,0xe1,0xce,0xfc,0x6b,0x88,0xdd,0xae,0x7d,0x20,0xf3,0xd,0x3d,0xc7,0x5c,0x43,0x88,0x2a,0x64,0x86,0xd8,0x63,0x58,0xaf,0x0,0xb0,0x83,0xd1,0x39,0x4c,0x1c,0x1b,0xe,0x2c,0x5a,0xca,0x5a,0xe5,0x54,0xb4,0x78,0x85,0xc4,0xdc,0x1e,0xe3,0xb0,0xae,0xc5,0x30,0xd2,0x7c,0xec,0x1c,0xfa,0x5,0x39,0xee,0x7c,0x21,0xc1,0x4c,0x66,0xcd,0x95,0x52,0xb8,0x7d,0x96,0x63,0xe8,0xa0,0x59,0x83,0xf4,0x90,0x48,0xf0,0x95,0x56,0x5b,0xe7,0x3d,0x8b,0x60,0x24,0x54,0x8a,0x1b,0x50,0x9a,0x87,0x4b,0x41,0x75,0x29,0xc6,0xc0,0xc2,0x57,0xe0,0x92,0x13,0x12,0xb7,0x9d,0xa7,0xef,0x89,0x0,0x27,0xe,0xc3,0x18,0x23,0xf6,0x6d,0x6e,0xe0,0xdf,0x7c,0xf6,0x2e,0xdc,0x70,0xdd,0x55,0xb8,0xfb,0xbe,0x87,0xd1,0x2f,0x16,0x24,0xa6,0xfa,0x80,0x7e,0xb1,0xa4,0x73,0x2f,0x37,0x90,0xa6,0x49,0xd7,0x3c,0x8d,0x23,0xc4,0xa1,0x2a,0xee,0xd5,0xae,0x5f,0xce,0x8a,0x4d,0xe8,0x19,0x50,0x4,0x5b,0x5a,0x76,0xc5,0x79,0x59,0x58,0x50,0x95,0x52,0x91,0xae,0x5f,0xa2,0x94,0xac,0xe,0xc8,0xae,0x93,0xf7,0x54,0x37,0xa6,0xf,0x81,0x84,0xc8,0x9,0x3a,0x8f,0x51,0xe6,0x1e,0x6a,0xac,0x38,0x46,0x75,0x3c,0xd2,0x5a,0x5,0xfe,0x9c,0x7b,0xe4,0x22,0xe,0x40,0x7,0x17,0x7a,0x2a,0xa9,0x1,0xaa,0x3,0x37,0x4d,0x5a,0x2,0x23,0x51,0x63,0x69,0x88,0x1e,0xc5,0x1,0x2b,0x82,0x75,0x66,0x61,0x33,0x67,0x72,0x22,0xb2,0x2b,0xf4,0xcd,0xa2,0xf7,0x86,0x61,0x18,0x86,0x61,0x98,0x0,0x68,0x18,0x86,0x61,0x18,0xc6,0xaf,0x44,0x0,0x84,0x96,0x3f,0x24,0x9e,0xb7,0xe7,0x40,0x73,0xc5,0x44,0xec,0xca,0x25,0x23,0x8f,0x89,0xc4,0xa,0x57,0xdb,0x7e,0x49,0xc0,0x88,0x2c,0xfe,0x75,0x33,0x2d,0xed,0xae,0x3b,0x6e,0xc4,0xe6,0xc6,0x72,0xb7,0xb8,0x56,0xa,0xee,0xb9,0xef,0x11,0xfc,0xfd,0xb7,0xee,0x47,0xca,0x6d,0xdb,0xa8,0x43,0x29,0x4e,0x5d,0x49,0x6d,0xd1,0x2,0x35,0x12,0x93,0x78,0xd3,0x2d,0x96,0x18,0x56,0xdb,0x24,0x74,0x8c,0x23,0xa4,0x3c,0x81,0x66,0x8e,0x15,0x72,0xf,0x86,0x88,0x71,0x18,0x0,0x14,0xc,0x25,0x93,0xd3,0x8a,0x5d,0x51,0x2a,0x52,0x71,0xac,0x79,0x2f,0x1,0xd0,0x3b,0xcf,0x73,0xfd,0x96,0xec,0x40,0x2c,0x0,0x32,0x8a,0x73,0x28,0xb9,0xb0,0x58,0x96,0x34,0x32,0x9b,0xd9,0x29,0x85,0x52,0x68,0xc6,0xda,0xb0,0xe6,0xb5,0x75,0x18,0x56,0xd5,0x61,0xe5,0xb8,0xf5,0x57,0xdc,0x8a,0x1d,0x8b,0x3e,0x41,0x67,0x12,0x3a,0x74,0xb,0x12,0x79,0x4a,0x96,0xf8,0x2a,0x39,0xea,0x86,0xd5,0x36,0xcd,0xd6,0x63,0x61,0x2e,0x76,0x1d,0x72,0xe0,0xd8,0xe7,0x34,0x92,0x23,0xb2,0x14,0x6d,0x9b,0x25,0x11,0x2f,0x6a,0x73,0xae,0x94,0xa7,0x74,0x5d,0x5f,0x1f,0x3c,0x8b,0x9a,0x14,0x59,0x9d,0x54,0x90,0x12,0x21,0xaa,0xeb,0xfb,0x66,0xa6,0x5b,0xc0,0x38,0xc,0x1a,0xb,0x17,0xc7,0x5a,0x60,0x51,0x54,0x1c,0x9b,0x0,0x30,0xe,0x2b,0x74,0x5d,0xcf,0xcd,0xbb,0x2c,0x2e,0x79,0x12,0xef,0x24,0x6e,0x3b,0x4d,0x23,0x42,0x53,0x90,0x92,0x72,0xc2,0x34,0xc,0x1a,0xf1,0x5,0x28,0x82,0x2d,0x2,0x9d,0x88,0xa9,0x40,0xe1,0x66,0xe5,0x5a,0xb6,0x21,0xe7,0x88,0x7c,0x4e,0x6a,0xc0,0xcd,0xd5,0xc5,0xc6,0x62,0x6a,0xe8,0xfa,0x2a,0x6a,0x6e,0xf4,0x1c,0x45,0x25,0xc1,0x5b,0x4,0xe3,0x76,0xed,0x4a,0x4e,0xf0,0x31,0x62,0xdf,0xc6,0x12,0xff,0xc3,0x67,0x3f,0x82,0x1b,0xae,0xbf,0x9a,0x8e,0x5,0xba,0xaf,0xc5,0xb2,0x63,0xb7,0x6a,0x50,0x37,0x5c,0x29,0x5,0x5d,0xb7,0x40,0xe2,0xd8,0x73,0x9d,0x1,0x58,0x10,0xbb,0x88,0x61,0xbd,0xd2,0xe7,0x2e,0x22,0xa3,0x73,0x5e,0x9d,0x78,0x12,0x81,0x16,0xf1,0x4f,0x3e,0xb,0x34,0x17,0x91,0x5c,0x8d,0x52,0xda,0xc3,0xaa,0x9d,0xfe,0xb7,0x8,0x77,0x22,0x48,0x7a,0xef,0xa9,0xa4,0x84,0xd7,0x18,0x28,0xe8,0x16,0xe4,0x40,0xcd,0xfc,0xbf,0x56,0x4,0x6e,0xe3,0xdc,0xf2,0x79,0xa1,0xe3,0xf2,0xfe,0x60,0x97,0xa8,0xf7,0x1,0x69,0x1a,0xe9,0xf5,0xec,0x7c,0x4c,0xa9,0xa8,0xfb,0x90,0x4,0xd6,0xb1,0xa,0xab,0x22,0xfa,0x15,0x76,0xb0,0x3a,0x6b,0x1,0x36,0xc,0xc3,0x30,0xc,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0xf8,0xb5,0x42,0x2e,0x3f,0xc7,0x2e,0x22,0x12,0x55,0x72,0x4a,0xc8,0x28,0x40,0x6e,0x62,0x96,0xa1,0xb6,0xaa,0x6a,0xac,0x35,0xd0,0x6c,0xb4,0x10,0xa2,0xa,0x86,0xa5,0x14,0x5c,0x78,0xce,0x59,0xb8,0xf9,0xc6,0xeb,0xf7,0x3c,0xdf,0xcb,0xaf,0x1c,0xc6,0x5f,0x7f,0xed,0x1e,0x64,0x9e,0xd,0x36,0xae,0x57,0x70,0x9e,0x9c,0x6e,0xe,0x14,0xdf,0x15,0xf1,0x40,0xa2,0xa3,0x32,0x6b,0x6d,0x1c,0x7,0x15,0xe7,0x64,0x46,0xa1,0xb8,0xfa,0xa6,0xf5,0x80,0x94,0x26,0x2c,0x96,0x9b,0x3a,0x4b,0x4f,0x8b,0x12,0xa4,0x40,0x61,0x18,0x58,0x4,0x64,0x71,0xd1,0x53,0x6c,0x76,0xd7,0x9a,0xb0,0x18,0x52,0xa,0xcd,0x9c,0x4b,0xd3,0x88,0x9c,0x24,0xb2,0xc9,0xa2,0xa4,0x27,0x21,0x34,0xe7,0x84,0x7e,0xb1,0xc4,0xb0,0x5a,0x21,0xf6,0x7d,0x9d,0x3,0xc8,0x33,0xdd,0xaa,0x2b,0x8c,0x44,0x33,0x57,0x48,0x28,0x1b,0x87,0x35,0x42,0xec,0xd0,0xf5,0xb,0x4c,0xd3,0x84,0x7e,0xd1,0xab,0xa3,0x6d,0x58,0xaf,0x74,0x76,0x9c,0x94,0x34,0xf4,0xcb,0x4d,0x72,0xef,0xa5,0x9,0xb1,0x63,0xb1,0xb5,0x50,0xc1,0x82,0x88,0x72,0xe2,0xf6,0xe2,0xe5,0x2,0x0,0x74,0x1d,0xb9,0xb8,0x62,0xd7,0xe9,0xbc,0xb8,0x18,0x3b,0x84,0x10,0x30,0xc,0x6b,0x5a,0x3b,0x16,0x14,0x65,0xde,0xdf,0x88,0x7a,0xf,0x40,0x56,0xf7,0x57,0xb7,0x58,0xc0,0xf1,0xda,0x80,0x63,0xb9,0x8b,0xd,0x2a,0xdd,0x48,0x69,0x42,0x9a,0x46,0x2a,0x43,0x59,0x6c,0xa8,0xa8,0x9b,0xb3,0xc4,0x40,0x65,0x2f,0x79,0x6e,0x43,0xee,0x48,0xdc,0xf2,0x14,0x87,0xf5,0x8e,0x66,0x1,0x16,0xd0,0x3d,0x45,0x8e,0xe8,0xb6,0xb3,0xf,0x8b,0xec,0x39,0x2e,0x98,0xa1,0x19,0x7e,0xbd,0xba,0x29,0xb5,0xb5,0xda,0x79,0x4,0x16,0x84,0xbb,0xe5,0x86,0xa,0x8a,0x2a,0xf4,0xa5,0x89,0xda,0x9f,0x59,0x95,0xd2,0x59,0x8a,0xdc,0x2a,0xc,0x3e,0x7e,0x29,0x11,0x1b,0x8b,0xe,0x7f,0xfc,0xb9,0x8f,0xe3,0x9a,0x2b,0x2f,0xab,0x1b,0x84,0x3f,0x7,0x21,0xf6,0xea,0x1c,0xa4,0xeb,0x48,0x70,0x1d,0x35,0x2f,0x3b,0xcf,0xb3,0xff,0x4a,0xd6,0x67,0x8,0x76,0x7c,0x4a,0x94,0x3e,0xf0,0xc,0x48,0x7a,0x86,0x51,0x9b,0x7d,0x3b,0x16,0xc5,0x4b,0x2e,0x88,0x4b,0x8a,0x79,0xb7,0xb3,0x2b,0x4b,0xae,0xf3,0xf6,0xaa,0x5b,0xb0,0x3e,0x73,0xc7,0xb1,0x6b,0x11,0x1f,0xc5,0x61,0x29,0xb3,0x19,0xb,0xc7,0x8f,0x1,0x3a,0xef,0xb8,0x5e,0xc1,0xc7,0x88,0x8e,0x1b,0x96,0x5d,0x70,0x8d,0x63,0x92,0x5,0xd5,0x48,0xff,0x30,0x30,0xac,0x57,0xea,0xaa,0x54,0xb7,0x1f,0x5f,0x9b,0x63,0x31,0x52,0x9c,0xa9,0xd2,0xa0,0x4c,0x9f,0xe9,0xc4,0x22,0x63,0x9a,0x95,0xdf,0x18,0x86,0x61,0x18,0x86,0x61,0x2,0xa0,0x61,0x18,0x86,0x61,0x18,0xbf,0x6,0x9c,0xb6,0x7d,0x7a,0xfe,0xcb,0xb9,0x8,0x35,0x34,0x6f,0x2d,0xc4,0xc0,0xdf,0xcb,0x70,0xae,0xe8,0xcc,0x2f,0x80,0xca,0x16,0xd2,0x34,0xd5,0x38,0x60,0xce,0xe8,0x16,0xb,0xdc,0x71,0xf3,0xb5,0xd8,0x58,0x2e,0x76,0xb,0x6b,0xa5,0xe0,0x4b,0xdf,0xbc,0x17,0xc7,0xb7,0xd7,0x40,0x21,0xb7,0x5e,0xd7,0x2f,0xb0,0x5e,0x9d,0x80,0xf3,0x1e,0xeb,0xf5,0xb6,0xc6,0x4f,0x45,0xbc,0x98,0xa6,0x69,0xd6,0xfc,0x5a,0xb8,0x79,0x35,0xe7,0x84,0xc4,0xa5,0x25,0xd3,0x30,0x0,0x0,0xb6,0x8f,0xbf,0xa1,0x82,0xc5,0xf6,0xf1,0x37,0x10,0xfb,0x5e,0xdd,0x59,0x53,0x4a,0x3a,0x23,0xcd,0x87,0x88,0x69,0x5c,0xab,0xd3,0x6a,0xd7,0x9a,0x34,0x45,0xb,0x24,0x8e,0xf5,0xd8,0x1e,0x8f,0xa1,0xe4,0x82,0x3,0x5b,0x1b,0x38,0xb0,0xb5,0x1,0xef,0x3c,0xb6,0x57,0x2b,0x1c,0xdd,0x1e,0x71,0xe2,0xc4,0x9,0x74,0x8b,0x5,0x35,0xd7,0xb2,0xe8,0x56,0x0,0x75,0x5a,0x95,0x92,0xb1,0xd8,0xd8,0xa7,0xee,0xb2,0x52,0x80,0x7d,0xfb,0xf,0x20,0xa7,0x84,0x71,0x1c,0xd8,0x75,0x45,0x51,0xea,0x65,0x1f,0x70,0xd1,0xa1,0x73,0x28,0x9e,0xea,0x3c,0x5e,0x7d,0xed,0x8,0xb6,0xd7,0x3,0x52,0x41,0xe3,0xb4,0xa4,0xb8,0x73,0xf4,0xbd,0x68,0x31,0x14,0x2b,0x85,0x67,0xb1,0x8c,0x5a,0x92,0xfb,0x25,0x47,0xb3,0x1d,0x39,0x7,0xbd,0xf3,0x70,0xce,0x53,0x5c,0x94,0x8b,0x5b,0x72,0x4e,0x54,0x4,0x21,0x65,0x1b,0x39,0x21,0x7a,0x87,0x73,0xf,0x1d,0xc4,0xd6,0xc6,0x12,0xaf,0x1f,0x3d,0x8a,0x57,0x8f,0x6e,0x93,0x2c,0xda,0x44,0x6a,0xa9,0xd,0x97,0x9f,0x49,0x29,0x5a,0xc,0xe3,0xbc,0x43,0xf4,0x1,0x9b,0xcb,0x1e,0x9b,0x8b,0x1e,0x1b,0x4b,0x12,0xf5,0x86,0x61,0xc2,0xeb,0x6f,0x9c,0xc0,0xf1,0xd5,0x8a,0xc4,0x3d,0xf9,0xa1,0xb5,0x89,0xae,0xe,0xeb,0x15,0x16,0x1b,0x9b,0xea,0x30,0x74,0x2a,0x0,0x7a,0x75,0xc4,0x79,0x8e,0x30,0x4b,0x8c,0x58,0x5c,0x77,0x81,0xbf,0x57,0x0,0xf4,0xd1,0xe3,0x8c,0x7d,0x9b,0xd8,0xe8,0x3,0xba,0x2e,0x62,0x3d,0x4c,0x38,0xbe,0x1a,0x71,0x6c,0x35,0xd0,0x9e,0x91,0xa6,0x5f,0x38,0x8d,0xe6,0x6,0x15,0x4e,0x49,0x45,0xb,0x21,0x62,0xa3,0xf7,0xf8,0x37,0x9f,0xbd,0xb,0xd7,0x5d,0x7d,0xf9,0xfc,0x7,0xed,0x6e,0x1,0xe7,0xb9,0x60,0x25,0x4,0x72,0x78,0x76,0x1e,0x8e,0xa3,0xdc,0xf4,0xbf,0x44,0xed,0xcf,0x9e,0x9c,0x9e,0xde,0x7,0x4c,0xd3,0x48,0x5,0x31,0x2c,0x7a,0x6a,0xac,0x97,0x1b,0xb4,0x73,0x29,0x38,0xb0,0x6f,0x3,0x5b,0x9b,0x4b,0x6c,0x2c,0x7b,0x8c,0xa9,0xe0,0xc8,0x91,0x23,0x38,0xb6,0xa,0xc8,0x2c,0xe,0x36,0xbb,0x14,0x3e,0x14,0x2d,0xdf,0x10,0x91,0x3c,0x4,0x3a,0xf,0xad,0x5f,0x66,0xd1,0x98,0x44,0x3a,0xe7,0x3d,0x62,0xa8,0xa5,0x20,0xe0,0x75,0xed,0x17,0x1b,0x70,0xc1,0x63,0x62,0x81,0xfc,0xe0,0xfe,0xd,0xec,0xdf,0x5c,0x62,0x9a,0x26,0xbc,0x7c,0xf8,0xd,0x1c,0x3f,0xb1,0x4d,0x7b,0x8e,0x1d,0x84,0x39,0x65,0x6e,0xfc,0x2d,0x18,0xa7,0x9,0x3e,0x78,0xe4,0x71,0x2,0x58,0x54,0x24,0xb1,0x11,0x3a,0xc7,0x30,0x71,0x21,0xd,0x0,0xb8,0xd1,0xed,0x39,0x16,0xc0,0x30,0xc,0xc3,0x30,0xc,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0xf8,0x55,0x8b,0x80,0x94,0xfb,0x25,0x97,0x8e,0x64,0xf5,0xa,0x7d,0x4d,0x9c,0x45,0x52,0x3e,0xd0,0xf4,0x1,0x68,0x39,0x46,0xc9,0x9,0xd3,0x44,0xc2,0x57,0x1f,0x3,0xde,0x79,0xed,0x15,0x7b,0x9e,0xe7,0xb9,0x17,0x5e,0xc6,0x7d,0x8f,0x3c,0x43,0xae,0x33,0x6e,0x9d,0x5d,0xaf,0xb7,0x49,0x30,0x91,0x26,0x52,0x69,0x32,0xf5,0x54,0x22,0x81,0x42,0x45,0x13,0xab,0x13,0xc7,0xb1,0xdc,0xd8,0xa7,0x33,0xd0,0xc6,0x71,0x8d,0xd0,0xb8,0x9c,0xd6,0xab,0x6d,0x2c,0x96,0x1b,0x58,0x9d,0x38,0x46,0xf1,0xcd,0x52,0x30,0x1e,0x5f,0x23,0x2f,0x13,0x86,0xf5,0xa,0x9b,0x5b,0xfb,0xb1,0xde,0x3e,0x1,0x80,0xa,0x1f,0x48,0x10,0x21,0xb7,0xd2,0x2e,0xa1,0x32,0x67,0xf4,0xfd,0x12,0xab,0x35,0x9,0x3c,0x5b,0x1b,0x3d,0xee,0xba,0xf5,0x66,0xdc,0x78,0xfd,0x55,0x38,0x74,0xf0,0x0,0xc5,0x5e,0x59,0x14,0x3d,0x76,0xfc,0x4,0x9e,0x79,0xee,0x45,0x7c,0xf3,0xfb,0xf,0xe0,0xb1,0xe7,0x5e,0xc1,0x30,0xc8,0xac,0xbd,0x40,0xe,0x43,0x14,0x2c,0x36,0xf6,0x21,0xa7,0x9,0xd3,0x38,0x62,0x63,0xdf,0x7e,0x3d,0x67,0xd7,0x2f,0x10,0xc6,0x8c,0xf7,0xde,0x78,0x25,0xde,0x73,0xc3,0xd5,0xb8,0xe8,0xfc,0x73,0xb1,0xb5,0x6f,0x13,0x31,0x46,0x4d,0x78,0xe,0xc3,0x88,0xd5,0x6a,0x8d,0xe7,0x5e,0x7c,0x19,0xf7,0xde,0xff,0x8,0xee,0x7b,0xf4,0x19,0xc,0x63,0x86,0x7,0x50,0x1c,0xb5,0xfd,0x92,0x10,0xd7,0xb8,0x1d,0x9d,0xe7,0x48,0x30,0x3d,0xa8,0x2b,0x2f,0x3a,0x7,0x9f,0xfa,0xd0,0x6d,0x2c,0x6e,0x6a,0x21,0x30,0xbe,0xf2,0xed,0x1f,0xe1,0xa9,0x17,0x5f,0xe1,0x62,0x97,0x1,0xde,0x7b,0xdc,0x79,0xeb,0xf5,0xf8,0xe0,0xed,0x37,0xe1,0xdc,0x43,0x7,0xd9,0x65,0x56,0xf0,0xea,0x6b,0xaf,0xe3,0x7,0xf,0x3c,0x8a,0x7f,0xba,0xe7,0x41,0x1c,0x39,0xb6,0xcd,0xf1,0xd8,0xcc,0x85,0x1d,0x14,0x19,0xee,0xba,0x1e,0x7,0xf7,0x2f,0x71,0xfb,0xbb,0xaf,0xc6,0x75,0x57,0x5d,0x86,0x73,0xe,0x1d,0x44,0x17,0x23,0x97,0x6c,0x14,0xe4,0x52,0x30,0xc,0x23,0xe,0xbf,0xfe,0x6,0x1e,0x7d,0xf2,0x59,0x7c,0xeb,0xde,0x87,0xf0,0xf2,0x6b,0x47,0x51,0x0,0x4c,0xe3,0xb0,0x63,0x6,0x22,0xb7,0x4f,0x73,0x84,0x38,0x97,0x4c,0x33,0xff,0xf8,0xde,0x62,0x57,0x85,0xb0,0x9c,0x13,0x16,0xcb,0xd,0x1c,0x3a,0x63,0x89,0x3b,0xde,0xf3,0x4e,0x5c,0x73,0xc5,0xc5,0x38,0xfb,0xac,0x33,0xb1,0x5c,0xf6,0x88,0x1c,0x7b,0xcd,0xa5,0x60,0x9a,0x12,0x8e,0x1f,0x3f,0x81,0xe7,0x5f,0x7c,0x9,0xf,0x3d,0xfe,0x2c,0xee,0x7e,0xe0,0x71,0xac,0x87,0x9,0x5,0x60,0x47,0x65,0x99,0x9,0x53,0xfb,0x36,0x7a,0xfc,0xd1,0xbf,0xfa,0x18,0xae,0xbc,0xec,0xa2,0xf9,0x67,0xc5,0x39,0x7c,0xf0,0xb6,0x1b,0x70,0xeb,0x8d,0x57,0xcb,0x6e,0xd1,0xa6,0x62,0xf9,0xef,0xf5,0x30,0xe2,0x4f,0xfe,0xe6,0x1b,0x18,0xa6,0xa4,0x65,0x18,0xe0,0x18,0x6f,0xe1,0x22,0x95,0x18,0x3b,0x0,0xe,0xdd,0xa2,0xc7,0xd9,0x5b,0x3d,0xee,0xb8,0xf9,0x7a,0x5c,0x7b,0xc5,0x45,0x38,0xeb,0xcc,0x3,0x58,0x2c,0x16,0xea,0x4a,0x9c,0xa6,0x9,0x27,0xb6,0xb7,0xf1,0xd2,0xcf,0xe,0xe3,0xfb,0x3f,0x7a,0x4,0xf7,0x3d,0xfa,0x34,0xb6,0x57,0xe0,0xd9,0x98,0xa5,0x3a,0x2a,0x63,0x84,0x6c,0x1a,0x71,0xf2,0x76,0xfd,0x12,0x9b,0x8b,0x88,0x3f,0xfc,0xcc,0x5d,0xe8,0xbb,0xc0,0xd7,0x42,0x2f,0x7b,0xf8,0xf1,0x67,0xf1,0x8d,0x7b,0x1f,0xd6,0xa6,0x63,0x0,0xb8,0xfa,0xe2,0x73,0xf1,0x7b,0xbf,0xfd,0x61,0x5c,0x72,0xe1,0xf9,0xe8,0xfb,0xe,0xb9,0x14,0x1c,0x3d,0x7a,0xc,0x8f,0x3c,0xf6,0x4,0xbe,0xf0,0xb5,0xef,0xe2,0xd9,0x9f,0xbe,0x4a,0x6b,0x9e,0xc8,0xd1,0x5a,0xa,0x78,0x5e,0x25,0x97,0xda,0xf0,0xb1,0xa4,0x39,0xbb,0x5d,0x4f,0x99,0x59,0x29,0x5,0x26,0x75,0xe6,0xa8,0x61,0x18,0x86,0x61,0x18,0x26,0x0,0x1a,0x86,0x61,0x18,0x86,0xf1,0x2b,0x47,0x84,0x6,0x38,0xa8,0x5b,0xc8,0x79,0x69,0x1f,0xa5,0x28,0x64,0xce,0x19,0x5d,0x17,0x59,0x70,0xc9,0xf0,0x81,0x67,0xbb,0x71,0xec,0x4f,0xda,0x70,0x1,0xe0,0xfc,0xb3,0xb6,0x70,0xce,0xa1,0x83,0x7b,0x9e,0xeb,0xbe,0x87,0x9e,0xc0,0xd4,0xb8,0x81,0xa6,0x69,0x40,0xdf,0x2f,0x31,0xac,0xb7,0xd9,0x95,0x37,0x0,0x9e,0x63,0xc9,0xdc,0xdc,0x9a,0x26,0x87,0xf5,0xf6,0x9,0x38,0xe7,0x70,0xec,0xe8,0x61,0x76,0x7d,0x65,0x4c,0xc3,0x1a,0xeb,0x94,0xa8,0xf0,0x42,0xb,0x33,0x12,0x86,0xd5,0x36,0x37,0xc6,0x92,0x2b,0x6d,0xb5,0x7d,0x1c,0xc1,0x7,0x12,0xff,0x9c,0xc3,0x62,0xb9,0x49,0xe2,0x84,0xf,0x70,0x28,0xb3,0xb6,0xe3,0x56,0xe4,0x49,0x69,0x82,0x77,0xe,0xef,0xbf,0xe9,0x6a,0x7c,0xe4,0xfd,0x37,0xe1,0xcc,0x33,0xb6,0x76,0xbd,0x2e,0x4,0x8f,0xb3,0xce,0x3c,0x3,0x67,0x9d,0x79,0x6,0x6e,0x7c,0xc7,0xd5,0xb8,0xef,0xc7,0x8f,0xe1,0x4f,0xfe,0xf6,0x9f,0x30,0x72,0x69,0xc5,0x34,0x26,0x8d,0xac,0x86,0x10,0xd0,0xf5,0x4b,0x8c,0xc3,0xa,0xa5,0x14,0xf4,0xfd,0x2,0xb7,0x5c,0x7f,0x29,0x3e,0xf9,0xa1,0xdb,0x70,0xfe,0xb9,0x87,0x4e,0xea,0x8a,0x8a,0x1b,0x1,0x9b,0x1b,0x4b,0x1c,0x3c,0xeb,0x0,0x6e,0xbc,0xfe,0x2a,0x3c,0xf7,0xc2,0x4b,0xf8,0xeb,0xaf,0xdc,0x8d,0x47,0x9f,0x7e,0x91,0xc5,0xda,0x35,0xb9,0xfd,0x16,0x4b,0x24,0x16,0x16,0x25,0x16,0x9a,0x73,0x46,0xbf,0x58,0xe2,0x82,0x73,0xcf,0xc6,0xcd,0xef,0xda,0x1d,0xc9,0xbe,0xff,0x91,0xa7,0xf0,0xcc,0x4b,0x87,0x31,0x4d,0x13,0xe,0x9c,0xb1,0x85,0xdf,0xff,0xd4,0x9d,0x78,0xf7,0x3b,0xaf,0xae,0x7b,0x82,0xb9,0xe0,0xfc,0x73,0x70,0xfe,0x79,0x87,0x70,0xeb,0x4d,0xd7,0xe3,0xcf,0xff,0xee,0xeb,0x78,0xf0,0xc9,0x17,0x10,0xfa,0x9e,0xbb,0x62,0xa,0xb6,0x36,0x7b,0x7c,0xe6,0xae,0xdb,0x71,0xcb,0xbb,0xae,0xc3,0xc6,0x1e,0x73,0x1f,0x85,0xbe,0xeb,0xb0,0xb5,0x6f,0x13,0x97,0x5c,0x74,0x1e,0xee,0xbc,0xed,0xdd,0xf8,0xd6,0xf7,0xee,0xc3,0xdf,0x7c,0xf5,0xfb,0x28,0xb9,0xe3,0xf8,0xf6,0x82,0x67,0xcb,0xa5,0x2a,0x98,0x95,0xc,0xef,0xa2,0xc6,0x90,0x29,0x4a,0x9b,0x1,0xe7,0x11,0x63,0xc4,0xd9,0xfb,0xcf,0xc0,0xef,0x7c,0xf4,0x7d,0x78,0xd7,0x3b,0xae,0x45,0xdf,0x77,0x7b,0x9e,0x37,0x0,0xe8,0x62,0xc4,0xc6,0x72,0x81,0x43,0x67,0x9f,0x85,0x77,0xdf,0x70,0x1d,0x3e,0xfd,0xf1,0x3b,0xf1,0xa3,0x1f,0x3f,0x8a,0xcf,0x7f,0xe3,0x7,0x78,0xf5,0xc8,0x1b,0xd8,0xd8,0xb7,0x45,0x8e,0xd0,0x9c,0xb1,0x7f,0xa3,0xc7,0x1f,0x7d,0xee,0x63,0xb8,0xe2,0xd2,0x8b,0xf6,0x3c,0xde,0x55,0x97,0x5f,0xfc,0xa6,0x9f,0xa9,0x13,0xdb,0x2b,0x6c,0xfc,0xc3,0x77,0x31,0x1c,0x3b,0xc1,0x7b,0x5d,0x4a,0x35,0x82,0x7e,0xa6,0x4a,0x29,0x38,0x74,0xc6,0x6,0x7e,0xef,0x93,0x77,0xe2,0xba,0x6b,0x2e,0x47,0xdf,0xed,0x7d,0xed,0x31,0x6,0x2c,0x97,0xb,0x1c,0x3c,0xeb,0x4c,0xbc,0xe3,0xda,0x2b,0xf0,0xf1,0x97,0x5f,0xc5,0x97,0xbe,0xfe,0x5d,0xdc,0xfd,0xc0,0x13,0x14,0x39,0x96,0x46,0x6c,0x6e,0x8b,0x9e,0xd8,0x2d,0x2b,0x65,0x2e,0x5d,0x8c,0xb8,0xf1,0x1d,0x57,0x61,0xb9,0x98,0x3b,0x72,0x87,0x61,0xc2,0xb7,0xef,0x7f,0x2,0xde,0x7,0xc4,0xe0,0xf0,0xe1,0x5b,0xaf,0xc3,0x6f,0x7d,0xf4,0x4e,0x2c,0x9a,0xd7,0x5,0x0,0x67,0x1f,0x3c,0x13,0xbf,0x71,0xfb,0x2d,0x78,0xf7,0xd,0xd7,0xe1,0xcb,0xdf,0xf8,0xe,0xfe,0xe6,0x2b,0xdf,0xc6,0xe4,0x3d,0xf2,0x94,0x58,0x38,0x9e,0xb8,0x29,0x18,0xb3,0x99,0x9a,0x72,0x8f,0x0,0x34,0xba,0x9c,0x33,0xef,0xf1,0x52,0x60,0xe2,0x9f,0x61,0x18,0x86,0x61,0xbc,0x3d,0x98,0x0,0x68,0x18,0x86,0x61,0x18,0xc6,0x29,0xa1,0x45,0x1b,0x5c,0x12,0x21,0x5,0x15,0x52,0x1c,0xe0,0xbc,0x87,0x7,0xb5,0xd6,0x7a,0x6e,0xb2,0x15,0xd7,0x91,0x88,0x4c,0x21,0x76,0x24,0xce,0x78,0x8f,0x2b,0x2e,0x3e,0xf,0x5d,0xdc,0xfd,0xa3,0xc8,0x6a,0x3d,0xe0,0x87,0x8f,0x3c,0xd,0xe7,0x3,0xb5,0xba,0x72,0xd4,0x78,0x1c,0xd7,0xc8,0x25,0x63,0x38,0x71,0xc,0x5d,0xbf,0xc0,0x8a,0x7f,0x2d,0x39,0x63,0x7d,0xe2,0xb8,0x16,0x59,0x48,0x5c,0xf7,0xf8,0x1b,0xaf,0x63,0xb1,0xdc,0xa0,0x6b,0xcf,0x19,0xe3,0xb0,0xe2,0x32,0x7,0x60,0xbd,0x3a,0xa1,0xd7,0x45,0x38,0xf4,0xcb,0x25,0xc6,0x71,0xd,0x9f,0x48,0x10,0xc9,0x5a,0x72,0x50,0xa3,0xa5,0x7b,0xd1,0xc7,0x88,0xdf,0xfd,0xc4,0x7b,0xf0,0xae,0xeb,0xaf,0x82,0xf7,0x3f,0x3f,0xb2,0x18,0x42,0xc0,0x7b,0xde,0x75,0x1d,0xce,0x3c,0x63,0x1f,0xfe,0xdd,0x9f,0x7d,0x9,0xdb,0x6b,0x8a,0x37,0x8f,0xe3,0x0,0x20,0xab,0x8,0xe2,0x7d,0x40,0x17,0x23,0x7e,0xf7,0x63,0xef,0xc3,0x6f,0xde,0x71,0xb,0x62,0x3c,0xf5,0x42,0x4,0xef,0x3d,0x2e,0xbd,0xf8,0x2,0xfc,0xdb,0xdf,0xff,0x4,0xfe,0xfa,0x4b,0xdf,0xc2,0x77,0x1e,0x78,0x82,0xdc,0x88,0xcb,0xd,0x0,0xe,0x5e,0xf2,0xc0,0xe0,0xc2,0x13,0x6d,0xa,0x3e,0xc9,0x8f,0x86,0x3c,0x6b,0xee,0xc0,0xfe,0x2d,0xfc,0xe1,0xa7,0x3f,0x80,0x1b,0xae,0xbb,0xf2,0xa4,0x42,0xa4,0x73,0xe,0xe7,0x9d,0x73,0x36,0xfe,0xf8,0xf,0x3e,0x8d,0x2f,0x7c,0xf5,0x3b,0xf8,0xf2,0x77,0xee,0x87,0xf,0x11,0x97,0x9d,0x77,0x10,0xff,0xcd,0x67,0x3e,0x8c,0xb,0xce,0x3f,0xe7,0x17,0xda,0x77,0xcb,0x45,0x8f,0x8f,0xdc,0x79,0x1b,0x2e,0xbe,0xe0,0x1c,0xfc,0x1f,0x7f,0xfe,0x15,0x1c,0xdb,0x5e,0xf1,0x8c,0xc2,0x51,0x8b,0x28,0xa4,0xc0,0x84,0x22,0xe6,0x5e,0xe3,0xb3,0x3e,0x74,0x8,0x3e,0xe0,0x3,0x37,0x5f,0x8d,0x4f,0x7c,0xf8,0x76,0x9c,0xb1,0xb5,0xef,0x17,0x3a,0xb7,0x73,0xe,0x5b,0xfb,0x36,0xf1,0xfe,0xdb,0x6e,0xc2,0x3,0x8f,0x3d,0x83,0x23,0xc7,0x57,0x24,0x3e,0xc3,0xe1,0xe0,0x19,0x5b,0xf8,0xe3,0xcf,0x7d,0x1c,0x17,0x5f,0x78,0xee,0x5b,0xfa,0x4c,0x49,0x31,0x8a,0x14,0xe7,0x38,0xe7,0xb4,0x5c,0x23,0xf6,0x3d,0x6e,0xba,0xea,0x2,0xfc,0xee,0x27,0x3f,0x80,0x3,0x67,0xec,0xff,0x85,0x8e,0x7d,0xfe,0xb9,0x67,0xe3,0xf,0x3f,0xfb,0x49,0x5c,0x74,0xfe,0x3d,0xf8,0xeb,0xaf,0xfd,0x40,0x63,0xe7,0x25,0xd7,0x8,0x30,0x0,0x9e,0xfb,0x97,0xb1,0x58,0x6e,0x68,0x4c,0x7c,0xb6,0x97,0x78,0x46,0x5f,0x29,0x19,0x1f,0xbb,0xfd,0xdd,0xf8,0xd4,0x5d,0xbf,0xc1,0x2e,0xc2,0xbd,0xd9,0xda,0xda,0x87,0xdf,0xf9,0xe4,0x87,0x71,0xc1,0xb9,0x67,0xe3,0x7f,0xff,0xd3,0xbf,0xc5,0x9,0x8e,0x3a,0xcb,0x5c,0xca,0x52,0x80,0x2c,0x33,0x1d,0x67,0x6b,0x91,0xab,0x93,0x18,0x8e,0x8b,0x40,0x2,0x9c,0xb,0x28,0xc5,0x66,0x1,0x1a,0x86,0x61,0x18,0xc6,0x5b,0xc5,0xdb,0x12,0x18,0x86,0x61,0x18,0x86,0x71,0x2a,0xe4,0x94,0x38,0xda,0xeb,0x75,0x7e,0x59,0xce,0xec,0x5c,0xf3,0x1e,0x25,0x51,0x2b,0xa9,0x94,0x52,0x90,0x70,0xe6,0x74,0x8e,0x99,0x38,0x1,0x29,0xb2,0x3b,0xe1,0x92,0x8b,0xce,0xdf,0xf3,0x3c,0xaf,0x1f,0x39,0x86,0xc3,0x6f,0xac,0x48,0x14,0x40,0x61,0x51,0x8a,0x4,0x1,0x69,0x43,0x1d,0x86,0x15,0xfa,0xe5,0x26,0xd6,0xeb,0x6d,0x8c,0xe3,0x1a,0xeb,0xd5,0x36,0x8e,0xbe,0xfe,0x2a,0xb6,0x8f,0xbf,0xa1,0x31,0x51,0xef,0x3d,0xc6,0xf5,0x1a,0xc3,0x9a,0x44,0x9b,0x37,0x5e,0x7f,0x8d,0x23,0xc1,0x3,0xbb,0xee,0x6,0xc,0xeb,0x6d,0x9a,0x2d,0xb8,0x7d,0x1c,0xc7,0x8f,0xbe,0x8e,0x69,0x18,0xa8,0x99,0xd7,0x79,0xac,0x4e,0x1c,0xa7,0xd7,0xac,0xb6,0xd9,0xe9,0xb6,0x5b,0xf0,0x72,0xde,0xe1,0x73,0x9f,0x78,0x2f,0x6e,0x7a,0xe7,0xd5,0xa7,0x24,0xfe,0xe9,0xfb,0x9c,0xc3,0x95,0x97,0x5f,0x82,0xcf,0x7d,0xea,0x37,0x54,0x88,0x91,0xe6,0xe1,0x18,0x3b,0x6d,0x20,0xfe,0xe4,0x7,0x6e,0xc6,0x87,0xef,0x7c,0xef,0x2f,0x24,0xfe,0xb5,0x6c,0x6e,0x6c,0xe0,0x33,0x9f,0xb8,0x13,0x57,0x5c,0x70,0x36,0x42,0x88,0x34,0xdb,0x30,0x46,0x74,0xfd,0x2,0xb1,0xeb,0xb9,0x99,0x98,0x5c,0x8e,0xe4,0x40,0x2b,0x27,0xb9,0x5e,0x8a,0xe7,0x7e,0xfa,0x43,0xef,0x79,0x53,0xf1,0xaf,0x65,0xb1,0xe8,0x71,0xe3,0x75,0x57,0xa0,0xeb,0x3a,0x6c,0x2c,0x7a,0xfc,0xf7,0xbf,0xf7,0xd1,0x5f,0x58,0xfc,0xab,0xe7,0x7,0xae,0xbd,0xea,0x72,0xfc,0xc1,0xa7,0x3f,0x88,0x9a,0x2c,0x77,0xea,0xe8,0xec,0xb8,0x35,0x18,0x1a,0x9b,0xe5,0x6,0xe3,0x2,0x7c,0xf4,0x7d,0xef,0xc4,0x67,0x7f,0xeb,0x43,0xbf,0xb0,0xf8,0xb7,0xeb,0x87,0x66,0xe7,0xb4,0x54,0xe5,0xe0,0x19,0x5b,0xf8,0xa3,0xb7,0x28,0xfe,0x81,0x77,0x54,0xca,0x99,0xc5,0xeb,0x8c,0xc4,0xc5,0x30,0x8e,0xe7,0x5b,0x7e,0xe0,0xa6,0xab,0xf0,0x7,0xbf,0xfb,0xb1,0x5f,0x58,0xfc,0x13,0x62,0xc,0xf8,0xc8,0x9d,0xef,0xc5,0x7f,0xf5,0xc1,0x9b,0x10,0x63,0x87,0x94,0x46,0x38,0xef,0xb0,0x58,0x6e,0xa0,0xeb,0x65,0xce,0x65,0x40,0xe0,0xb2,0x97,0x3d,0x15,0x40,0x50,0x9c,0xfa,0x37,0x6f,0x7d,0x27,0x3e,0x75,0xd7,0x9d,0x6f,0x2a,0xfe,0x9,0x21,0x4,0x5c,0x7f,0xed,0x55,0xd8,0xda,0x58,0xe8,0x9f,0x15,0xea,0xfe,0xe5,0x19,0x85,0x85,0x6a,0xb3,0xf9,0x39,0x71,0xde,0xb8,0x50,0xa1,0x50,0xce,0x22,0x6,0x26,0x13,0xff,0xc,0xc3,0x30,0xc,0xe3,0x6d,0xc2,0x1c,0x80,0x86,0x61,0x18,0x86,0x61,0x9c,0x12,0x54,0x40,0xe0,0xc0,0x7f,0x55,0x57,0x71,0xa0,0x70,0x5b,0x28,0x1c,0xe0,0x63,0xc4,0x38,0xac,0xd5,0xd5,0x44,0x85,0xc,0x9d,0xa,0x82,0x40,0xd0,0x26,0xd9,0xf3,0xcf,0x39,0x6b,0xcf,0xf3,0xbc,0xfc,0xca,0x6b,0xe4,0x2e,0xd4,0x59,0x6e,0xe4,0x68,0x9b,0x38,0xb6,0x2a,0x22,0xe0,0xea,0xc4,0x71,0x6e,0x8d,0x25,0x11,0x21,0x4d,0xa3,0xb6,0xf,0x6f,0x1f,0x3f,0x86,0xf5,0xea,0x4,0x35,0xde,0xa2,0x60,0x1a,0x47,0x9e,0xf,0x78,0xc,0xdd,0x62,0x81,0x69,0x58,0xeb,0xfc,0xbf,0x63,0x47,0xf,0x93,0x38,0x32,0x91,0x93,0x6c,0xb9,0xb1,0xf,0xe3,0x7a,0x45,0xad,0xa7,0xc3,0x9a,0x1c,0x8b,0xdb,0xc7,0x29,0x4e,0xba,0x83,0x33,0xb6,0xf6,0xe1,0x1d,0xd7,0x5c,0xae,0xbf,0x1f,0xc6,0x9,0xcf,0xbd,0xf0,0x53,0x3c,0xfc,0xd8,0x53,0x38,0xf2,0xc6,0x71,0xf4,0xd1,0xe3,0x1d,0xd7,0x5e,0x85,0xab,0x2e,0xbf,0x18,0x8b,0x45,0xbf,0xeb,0xfd,0x37,0xdf,0x70,0xd,0x7e,0xf0,0xe3,0x9f,0xe0,0xfe,0xc7,0x9f,0x3,0xa,0xcd,0xfa,0x9b,0xc6,0xb5,0x16,0xa6,0x5c,0x78,0xde,0x21,0xf8,0x93,0x88,0x6d,0x24,0xc0,0xd2,0x8c,0x34,0x59,0xa3,0xbd,0xd8,0xdc,0x58,0xe2,0x93,0x1f,0xbc,0x5,0xff,0xdb,0x9f,0x7c,0x9e,0x8a,0x2d,0x4a,0x26,0xc7,0x26,0x8b,0xb2,0x1a,0x9f,0xd,0x11,0xa5,0xb8,0x93,0x3e,0xfb,0xf7,0xdf,0x74,0xd,0xde,0x77,0xcb,0xd,0xf3,0x79,0x6d,0x59,0xa2,0xdd,0xbb,0xdf,0x37,0x8e,0x13,0x3e,0xff,0x8f,0xdf,0x41,0x2e,0xc0,0xd6,0xb2,0xc3,0x99,0x7,0xce,0x38,0xe9,0xde,0x92,0x26,0xe5,0x82,0x82,0x18,0x4e,0x2e,0x76,0xde,0x70,0xdd,0x95,0xb8,0xf1,0xea,0x4b,0xf1,0xf0,0x33,0x2f,0x51,0x39,0x7,0x3b,0x4c,0x9d,0x73,0xe8,0x16,0x4b,0xa4,0x69,0x44,0xc9,0x34,0xb,0x32,0x17,0x87,0x3b,0xde,0x75,0xd,0x7e,0xeb,0xae,0x3b,0x54,0x64,0xdd,0x7b,0x1d,0x81,0x71,0x1c,0x91,0x12,0xb5,0x44,0x77,0x5d,0x77,0x52,0x31,0xb7,0x94,0x82,0xfd,0x9b,0x4b,0xfc,0x8f,0xff,0xf2,0x2e,0x5c,0xf2,0x16,0xc5,0x3f,0xfa,0xf8,0x50,0x83,0x6f,0x88,0x91,0xdc,0xa9,0x2c,0x8e,0xc7,0xae,0xc7,0xf5,0x97,0x9e,0x8b,0xdf,0xfa,0xc8,0x1d,0x27,0x8d,0xfc,0xae,0xd6,0x3,0x5e,0x3f,0x7a,0xc,0xdb,0xdb,0xb4,0x57,0xf7,0x6f,0x6e,0x60,0xff,0xfe,0xcd,0x5d,0xeb,0xe7,0xbd,0xc7,0x47,0xee,0xbc,0x15,0xcf,0xbc,0xf8,0xa,0x1e,0xf8,0xc9,0xb,0xe4,0xda,0x9d,0x46,0x6e,0x39,0xa6,0xd9,0x98,0x52,0x42,0xb3,0x57,0xcc,0xbd,0x94,0x8c,0xb,0xe,0x9d,0x89,0x4f,0x7d,0xf8,0xb6,0x99,0x10,0x4d,0xfb,0xaf,0x20,0x4,0xbf,0xe7,0x3a,0x7d,0xe5,0x6b,0xdf,0xc2,0xcb,0xaf,0x1f,0x63,0x47,0x70,0x80,0x77,0xe,0x29,0x15,0x2e,0x53,0xc9,0x3a,0x32,0x40,0x5e,0xef,0x40,0x42,0x73,0x1,0xcf,0xf8,0x2c,0x16,0xfd,0x35,0xc,0xc3,0x30,0x8c,0xb7,0x13,0x13,0x0,0xd,0xc3,0x30,0xc,0xc3,0x38,0x25,0x42,0x8,0xd5,0xf9,0x57,0x32,0x82,0xf,0x3a,0xa7,0x2f,0x84,0x40,0xe2,0xd2,0x34,0xa1,0x5b,0x2c,0x51,0x4a,0xe1,0x66,0xe0,0xe,0xb9,0x89,0x8,0xc3,0x39,0x72,0xb8,0x79,0x8f,0x8d,0x8d,0x8d,0x3d,0xcf,0xf3,0xda,0x91,0x63,0x34,0xa3,0x6c,0xa4,0xc6,0xde,0x9c,0xc9,0x1,0xa4,0xae,0xa1,0x9c,0x90,0xc6,0x89,0xe3,0xbc,0xd4,0x10,0x5c,0x72,0x46,0xe2,0x16,0xe0,0x69,0x1a,0xb1,0xda,0x3e,0x8e,0x18,0x23,0xb5,0xf2,0x9e,0x38,0x86,0xd8,0xf5,0x18,0x56,0x27,0xb0,0x75,0xc6,0x59,0xc8,0x25,0x63,0xb9,0xb9,0x85,0x61,0xb5,0xd,0x0,0x3c,0xb,0xad,0xd7,0xc2,0xd,0x8a,0x65,0x7a,0xc,0xeb,0x15,0x62,0xd7,0x63,0xb1,0xdc,0xd4,0xfb,0xde,0xb,0x11,0xbf,0x9e,0x7d,0xe1,0x65,0x7c,0xfe,0x6b,0xdf,0xc7,0xc3,0x4f,0x3e,0x8f,0x71,0x18,0x28,0xae,0xbc,0xda,0xc6,0x17,0xbe,0xf9,0x3,0xbc,0xe7,0x9d,0xd7,0xe0,0xf,0xff,0xc5,0x5d,0x38,0xeb,0xcc,0x3,0xf3,0x1f,0xc4,0x62,0xc4,0x6f,0xbe,0xef,0x6,0xfc,0xf8,0xc9,0x17,0x35,0xea,0x1c,0x42,0xa7,0x71,0xd6,0xbd,0x84,0x95,0xc3,0x47,0x8e,0xe1,0xa1,0xc7,0x9e,0xc2,0x93,0xcf,0xbd,0x8c,0xc3,0x47,0x8f,0x63,0x9c,0x12,0xf6,0x6f,0x2e,0x70,0xd5,0x65,0x17,0xe0,0xd6,0x1b,0xaf,0xc1,0x81,0x3d,0x66,0x10,0x5e,0x79,0xd9,0x85,0xb8,0xe2,0xa2,0xf3,0xf1,0xd4,0x8b,0x3f,0x83,0xf7,0xd4,0x88,0x3b,0xe,0x6b,0x74,0x5d,0xf,0xe7,0x3d,0xd2,0x94,0xb9,0x6c,0x42,0xdc,0x5a,0xf3,0x73,0xef,0x5b,0x2e,0xf0,0xe1,0xdf,0xb8,0x19,0x91,0x5b,0x97,0x9f,0x7d,0xe1,0x65,0xdc,0xff,0xc8,0x93,0x78,0xee,0xc5,0x57,0x10,0xbc,0xc3,0xbb,0xae,0xbd,0x14,0xef,0x7a,0xe7,0x35,0xd8,0xb7,0x59,0x9f,0xe9,0xf7,0x7e,0xf8,0x20,0x1e,0x7f,0x9e,0xca,0x20,0xbc,0xf7,0xbb,0x4,0x9d,0x61,0x9c,0xf0,0xcc,0xf3,0x2f,0xe1,0xd1,0x27,0x9f,0xc7,0x33,0xcf,0xbf,0x8c,0xe3,0xdb,0x6b,0xf4,0x7d,0xc4,0x39,0x7,0xcf,0xc4,0xbb,0xaf,0xbb,0x14,0xd7,0x5e,0x75,0xe9,0x2e,0x31,0x2b,0xc6,0x88,0xf,0xde,0x76,0x3,0x1e,0x7a,0xfa,0x25,0x6d,0x8e,0x95,0x8e,0x8,0x7a,0x7e,0x34,0xe7,0x2e,0xa5,0x9,0xe7,0x9c,0xb5,0x1f,0xbf,0xf3,0xb1,0x3b,0x4e,0xea,0x58,0x3b,0x76,0xfc,0x4,0x1e,0x7a,0xfc,0x19,0xdc,0xf7,0xe3,0xc7,0xf0,0xb3,0x23,0xdb,0x78,0xe3,0xd8,0x31,0xf4,0x5d,0x8f,0x3,0x5b,0x4b,0x5c,0x75,0xc9,0x79,0xb8,0xe1,0xba,0x2b,0x70,0xc9,0x45,0xe7,0xa3,0xe7,0x99,0x96,0x29,0x4d,0x5c,0xe2,0x51,0x70,0xff,0x43,0x3f,0xc1,0xc3,0x4f,0x3c,0x4f,0xf3,0x6,0x1,0x1c,0x3a,0x78,0x6,0x6e,0x7d,0xf7,0xee,0xd9,0x89,0xdf,0xfb,0xe1,0xc3,0x38,0x7c,0xf4,0x18,0xed,0x63,0x89,0xe0,0x72,0xd1,0x87,0xf7,0x1,0xdb,0xdb,0xdb,0x18,0x33,0xc5,0x72,0x1d,0xc7,0x80,0x4b,0xce,0xd8,0xda,0x58,0xe2,0xf7,0x3e,0x79,0xe7,0x9e,0xd,0xd9,0xc7,0x8e,0x6f,0xe3,0x9b,0xdf,0xbb,0x1f,0xf7,0x3d,0xfa,0x2c,0xe,0x1f,0x5b,0x63,0x18,0x56,0xe8,0xba,0x5,0x16,0x9d,0xc7,0x79,0x67,0x6d,0xe1,0xe3,0xbf,0x71,0x13,0xae,0xb9,0xf2,0xd2,0xd9,0xf6,0xe9,0xbb,0xe,0x9f,0xfa,0xd0,0x6d,0x78,0xf0,0x27,0x7f,0xa5,0xe7,0x9e,0xc6,0x81,0x9c,0x9f,0x3e,0xc0,0xc7,0x8e,0x9c,0xb6,0x7b,0x88,0xdc,0xde,0x79,0xfc,0xee,0xc7,0xef,0x50,0x17,0xe2,0x2b,0xaf,0xbd,0x8e,0xfb,0x1f,0x7a,0x2,0x8f,0x3f,0xfd,0x3c,0x86,0xf5,0x1a,0x57,0x5e,0x7a,0x3e,0x6e,0xbb,0xf9,0x6,0x1c,0x3a,0xbb,0xa,0xfa,0xcf,0x3c,0xf7,0x2,0xbe,0xf4,0xcf,0x3f,0xa0,0x18,0x7b,0xbf,0xe0,0x3f,0xf,0x46,0x3d,0x2f,0x1c,0x8d,0xf,0x98,0x7d,0x86,0xd8,0xc1,0xe9,0x9c,0x7,0x5c,0xaa,0x8d,0xc5,0x86,0x61,0x18,0x86,0x61,0xbc,0x2d,0x98,0x0,0x68,0x18,0x86,0x61,0x18,0xc6,0x29,0xd1,0xb6,0x75,0x3a,0xe7,0x91,0x72,0xe2,0xf2,0x8d,0x49,0x4b,0x6,0x0,0x60,0x1c,0xd6,0x88,0x5d,0xa7,0xe5,0x2,0xd4,0x0,0x1b,0xf5,0x2f,0xfa,0xd3,0x34,0x62,0xd1,0x2f,0xb4,0x2c,0x64,0x27,0xdb,0xdb,0x2b,0x38,0xe7,0x10,0xbb,0x1e,0xd3,0x38,0x20,0x76,0x3d,0x17,0x73,0x0,0xe3,0x9a,0x1c,0x79,0xc3,0x7a,0x85,0x52,0xb2,0x96,0x79,0xc,0xeb,0x15,0xc6,0x61,0x35,0x9b,0x39,0x38,0xc,0x6b,0x94,0x52,0xa8,0x41,0x37,0x44,0x6c,0xec,0xdb,0x8f,0x61,0xb5,0x8d,0xc0,0x2e,0xa6,0xd8,0xf5,0x28,0xa5,0x60,0xb9,0xb9,0x45,0x51,0x48,0x69,0x24,0xf5,0x1e,0x69,0x1c,0xd1,0x2f,0x96,0x88,0x5d,0x8f,0x34,0x8d,0x2c,0x4c,0xec,0xbd,0x2e,0xa5,0x14,0x3c,0xf0,0xf0,0x93,0xf8,0x8b,0xaf,0x7c,0xf,0x47,0x8f,0x9d,0x80,0xe3,0x16,0xe4,0xf5,0xea,0x84,0x8a,0x7a,0xf,0x3c,0xf6,0x34,0xfe,0xaf,0xbf,0xfc,0x47,0xfc,0x2f,0x7f,0xf8,0xdb,0x58,0xf4,0x73,0x27,0xe0,0xa5,0x17,0x5f,0x88,0x33,0xb7,0x36,0xf1,0xfa,0xb1,0x13,0x18,0x87,0x15,0xba,0x7e,0x81,0x3c,0x15,0x78,0x9e,0x7,0x27,0x1c,0x3e,0xf2,0x6,0xfe,0xf1,0x9f,0xef,0xc5,0xdd,0x3f,0x7e,0x1a,0xc3,0x48,0x5,0xe,0x21,0xd0,0xff,0x7e,0x7a,0xf8,0x38,0x7e,0xf2,0xe2,0xeb,0xb8,0xfb,0xfe,0x27,0xf0,0xc7,0x9f,0xfb,0x18,0xe,0x1d,0x9c,0xb,0x8d,0x7d,0xdf,0xe3,0xba,0xcb,0xcf,0xc7,0x53,0x2f,0xbe,0x4c,0x85,0x1c,0x39,0x53,0x29,0xa,0x23,0xf3,0xe7,0xb0,0xe3,0x9c,0xc2,0xfb,0xde,0xf3,0xe,0x1c,0x3c,0xf3,0x0,0xc6,0x71,0xc4,0x97,0xbe,0x7e,0x37,0xfe,0xf1,0xee,0x7,0x31,0x26,0x72,0xda,0x4d,0xe3,0x88,0x87,0x9e,0x7e,0x19,0xff,0xf0,0xed,0x7,0xf0,0xaf,0x3e,0x79,0x7,0xae,0xbb,0xfa,0x72,0xbc,0x7a,0xf8,0x8,0xfe,0xf2,0xcb,0xdf,0x61,0xf1,0xd6,0xb1,0xd3,0x8b,0x9d,0x9a,0x39,0xe3,0xc1,0x47,0x9e,0xc0,0x17,0xbf,0x71,0xf,0x9e,0x7b,0xe5,0xa8,0xa,0x4f,0xd4,0x48,0x9b,0xf1,0xf4,0x4b,0xaf,0xe3,0xbe,0xc7,0x5f,0xc0,0x87,0x6e,0x79,0x15,0x1f,0xff,0xc0,0x2d,0xbb,0x1c,0x66,0x17,0x5f,0x78,0x1e,0x36,0x96,0x3d,0xb6,0x57,0x24,0xfa,0x95,0x5c,0xd8,0x51,0x16,0xe0,0x3d,0x39,0x4d,0x63,0xd7,0xe3,0x33,0x1f,0xbd,0x1d,0x67,0xec,0xdf,0xda,0xf3,0x79,0x3d,0xf6,0xe4,0xb3,0xf8,0x8b,0x2f,0x7d,0x7,0x2f,0xbf,0x7e,0x8c,0xb,0x3d,0xe8,0x18,0x6e,0x3d,0xe1,0xf0,0xb1,0x13,0x78,0xea,0xa7,0xaf,0xe1,0x2b,0x77,0x3f,0x88,0xab,0x2e,0x3a,0x1b,0x9f,0xf8,0xcd,0xdb,0x70,0xcd,0x15,0x97,0xd0,0x73,0x2d,0x5,0xc7,0x57,0x23,0xbe,0x72,0xf7,0xc3,0x55,0x90,0x6,0x70,0xfb,0xbb,0xae,0xde,0x53,0x0,0xfc,0xf1,0x63,0xcf,0xe0,0xc7,0x4f,0xfe,0x54,0x9b,0xb0,0x1,0x12,0x43,0xd3,0x34,0x91,0x88,0x1e,0x3b,0xc,0xc3,0x1a,0xfd,0x62,0x3,0x8d,0x96,0x89,0xdf,0xbc,0xe5,0x9a,0x3d,0xb,0x72,0x5e,0x7a,0xe5,0x30,0xfe,0xcf,0xbf,0xfc,0x3a,0xe,0xbf,0xb1,0xa2,0x46,0xdf,0xae,0x43,0x57,0x68,0x3f,0x6d,0xaf,0x47,0x3c,0xf9,0xe2,0x6b,0xf8,0xf7,0x7f,0xf1,0x55,0x7c,0xee,0x13,0x77,0xe0,0xb6,0x9b,0xae,0x9b,0xbd,0xf7,0xa2,0xf3,0xcf,0xc1,0x2d,0xef,0xb8,0xc,0xdf,0x7f,0x88,0xe6,0x6b,0x7a,0x0,0x81,0x3f,0xbf,0xe3,0x30,0xc0,0xef,0xdf,0xdc,0x53,0x74,0xbe,0xe4,0xe2,0xf3,0x71,0xf6,0x59,0x67,0xa0,0x94,0x82,0x7b,0x7f,0xf4,0x8,0xfe,0xf3,0x17,0xbe,0x81,0xe3,0xeb,0xc4,0x25,0x2c,0x19,0xf,0x3f,0xf3,0x32,0xbe,0xf8,0x4f,0xf7,0xe2,0x5f,0x7c,0xf4,0x76,0xdc,0x79,0xc7,0x2d,0x70,0x0,0xfe,0xfc,0xaf,0xbe,0x88,0x63,0x27,0xb6,0xa9,0x28,0x88,0x4b,0x77,0xe8,0x73,0x35,0x68,0x4b,0xb8,0xb8,0xfe,0x0,0x20,0x97,0xc,0x7,0x4f,0xf3,0x9,0xc1,0xd1,0x60,0xe7,0x4f,0x29,0x6a,0x6e,0x18,0x86,0x61,0x18,0xc6,0xa9,0x61,0x2,0xa0,0x61,0x18,0x86,0x61,0x18,0xa7,0x84,0x3a,0x72,0x4a,0xd1,0xf9,0x7e,0x39,0x25,0xf8,0x40,0x31,0xdc,0x10,0xa9,0x81,0x35,0xf8,0xa0,0x25,0x6,0x9d,0x5f,0x20,0xe7,0x84,0x94,0x92,0x8a,0x80,0xde,0x7b,0xf4,0x7d,0x87,0x18,0xf6,0x8e,0xac,0x66,0x36,0xfd,0x64,0x76,0x5b,0xa5,0x69,0x42,0xbf,0x58,0x52,0xa4,0xd7,0x1,0xd3,0xb0,0x46,0x29,0x14,0x5b,0x1c,0x56,0xdb,0x98,0xc6,0x91,0xaf,0x23,0xaa,0xcb,0xca,0x39,0xa0,0xe3,0x19,0x77,0xfd,0x62,0x83,0xc4,0x9a,0x9c,0x11,0x62,0xc0,0xc6,0xe6,0x7e,0x8c,0xc3,0x1a,0xcb,0xcd,0x2d,0xbd,0x2f,0x71,0x20,0x75,0xb1,0x23,0x61,0x70,0x59,0xb4,0xdc,0xa4,0xeb,0x16,0x74,0xbe,0x3d,0xdc,0x48,0xa5,0x14,0xfc,0xf8,0xd1,0xa7,0xf0,0xa7,0x5f,0xfc,0x2e,0xc6,0x29,0x21,0xa5,0x89,0x22,0xd0,0x9e,0xc4,0xc,0xef,0xb9,0x40,0x1,0xc0,0x4f,0x9e,0xfb,0x19,0x1e,0x7c,0xf4,0x29,0xbc,0xe7,0xc6,0x6b,0x67,0xc7,0x58,0x2e,0x7a,0x5c,0x7e,0xd1,0x39,0xf8,0xd1,0x63,0xcf,0xa2,0x5f,0x6c,0xb0,0x80,0x4a,0xc2,0x23,0x39,0xf,0x81,0x87,0x1f,0x7b,0x2,0x7f,0xf9,0x8f,0xf7,0xe2,0x95,0x23,0xc7,0xe0,0xc0,0x73,0x15,0xb,0x54,0x60,0x29,0x3c,0x43,0xed,0xf5,0xe3,0x6b,0xfc,0xc3,0x3f,0xff,0x10,0xff,0xfa,0xd3,0xbf,0xb9,0x4b,0x3c,0xb9,0xe8,0x82,0xf3,0x10,0x7c,0xd4,0xc8,0x2c,0xc5,0x2c,0xc1,0x65,0xb,0x9e,0xdc,0x6c,0x27,0x11,0x5c,0x2e,0xbe,0xe0,0x5c,0xa4,0x94,0xf1,0xf9,0xaf,0xde,0x8d,0xaf,0xdf,0xf3,0x8,0xe0,0x2,0x62,0x24,0x37,0xa0,0xf7,0x1,0x69,0x1a,0xf1,0xe2,0xcb,0xc7,0xf0,0xef,0xff,0xcb,0x57,0xf1,0xd1,0xf7,0x5d,0x8f,0xd7,0x5e,0x3f,0x86,0x35,0x19,0x34,0xd1,0x2d,0x7a,0xc0,0x79,0x94,0x2,0x6c,0xaf,0xd6,0xf8,0xdb,0x2f,0x7f,0x1b,0xdf,0x7f,0xe4,0x39,0x4c,0xd3,0x44,0xad,0xb4,0xa5,0x20,0xa5,0xa2,0xb9,0x72,0x89,0x36,0x7f,0xf5,0x7b,0xf,0xe1,0x5d,0xd7,0x5d,0x8e,0x8b,0xce,0x3f,0x34,0xbb,0x96,0x8d,0xe5,0x2,0x7,0xf7,0x6f,0xe0,0xa5,0x54,0x30,0x1,0x8,0x11,0x7a,0x1d,0x52,0xd8,0x72,0xce,0x99,0x5b,0x78,0x67,0x13,0xcd,0x6e,0xf9,0xd1,0xc3,0x4f,0xe0,0x4f,0xfe,0xfa,0xeb,0x98,0x8a,0x43,0x49,0x99,0xf7,0x1a,0xcf,0xae,0xf4,0xe,0xc3,0x6a,0x9b,0xf6,0x73,0x88,0x78,0xf4,0x99,0x97,0xf1,0x93,0xff,0xf8,0x77,0xb8,0xe5,0x9d,0x57,0xe2,0xf0,0xd1,0xe3,0x34,0x27,0x91,0xab,0x6c,0x27,0x76,0xb4,0x85,0x18,0x75,0x6f,0xef,0xdc,0x1b,0x71,0xb1,0x84,0xf,0xb4,0x3e,0xd2,0x9c,0x4d,0xf3,0xed,0xd8,0x1,0x57,0xc4,0x79,0x49,0x9a,0x57,0x29,0x19,0xfb,0x36,0x16,0xb8,0xed,0xa6,0xdd,0x62,0xe2,0xf6,0x6a,0x8d,0xff,0xfc,0x85,0x6f,0xe1,0xe5,0x57,0x8f,0xa0,0xeb,0x17,0xe4,0x48,0x2c,0xb4,0x4f,0x63,0x24,0xc1,0x9d,0x8e,0x5f,0xf0,0x57,0x5f,0xbd,0x7,0x17,0x9c,0x77,0x36,0x2e,0x6e,0xd6,0xce,0x7b,0x8f,0xdb,0x6f,0xbe,0x1e,0xf7,0x3d,0xf6,0x2,0x72,0x29,0xc8,0x1c,0xe9,0x8f,0xb1,0x83,0x5f,0x2c,0x4f,0xda,0xb5,0x7b,0xee,0xd9,0x67,0x2,0x0,0x7e,0xf0,0xc0,0x23,0xf8,0x4f,0x5f,0xf8,0x16,0xb6,0x4f,0xc,0xfa,0xac,0x7c,0x20,0x17,0xf0,0x7a,0x1a,0xf1,0x1f,0xff,0xf6,0xeb,0x78,0xf4,0x89,0xa7,0x71,0xd9,0xc5,0x17,0xe0,0x81,0x9f,0x3c,0x4f,0xf3,0xfe,0x3c,0xb9,0x85,0xb,0xcf,0xf6,0xa3,0x3d,0x46,0x6e,0x50,0x7,0xa0,0xb8,0x79,0x1c,0xd8,0x79,0xf,0xb0,0xe3,0x57,0x9a,0x96,0xd,0xc3,0x30,0xc,0xc3,0x78,0x7b,0xb0,0x12,0x10,0xc3,0x30,0xc,0xc3,0x30,0x4e,0x89,0x69,0x1a,0xe9,0x3f,0x1c,0x95,0x2,0x38,0x88,0x20,0xc8,0x65,0x6,0xd3,0xc8,0x2,0x44,0xe2,0x12,0x8e,0x80,0x94,0xa8,0xed,0x53,0xa,0x40,0x32,0xb,0x83,0x34,0x8b,0x6e,0xef,0xf3,0xf4,0x5d,0x60,0xb7,0x21,0x15,0x3d,0x38,0xe7,0x30,0x8e,0x83,0xce,0xb,0x1b,0x87,0x35,0x52,0x9a,0xb0,0x5e,0x6d,0xeb,0xdc,0xb6,0x9c,0x49,0x2c,0x98,0xd8,0x61,0xd4,0x2f,0x37,0xb0,0xdc,0xd8,0x87,0x7e,0xb1,0x24,0xc7,0xd5,0x38,0x20,0x84,0x88,0xe5,0xe6,0x96,0x46,0x80,0xc5,0x9d,0x58,0xb8,0x9d,0x78,0xb1,0xdc,0xa4,0x26,0x54,0x9e,0x21,0xd7,0xf5,0xbd,0xb6,0xe2,0xfa,0x40,0x5,0x1d,0x3b,0x79,0xe3,0xf8,0x36,0xfe,0xef,0xbf,0xff,0xe,0x26,0x6e,0x2b,0xd6,0xa6,0x64,0x9e,0xeb,0x26,0x22,0x4d,0xf0,0x1,0xd3,0x30,0xe0,0x87,0x3f,0x7e,0x7c,0x97,0x90,0xe8,0x9c,0xc3,0x85,0xe7,0x9c,0x49,0xee,0xc5,0x44,0xee,0xc5,0x92,0x33,0x3b,0xcc,0x32,0x7e,0xf0,0xc0,0x23,0xf8,0xf,0xff,0xcf,0xd7,0xf0,0xf2,0xe1,0x23,0xc8,0xd3,0x44,0x4d,0xc7,0xdc,0xca,0xea,0x63,0x44,0x1,0xc8,0x89,0x99,0x48,0x64,0x7a,0xea,0x85,0x57,0xb0,0x1e,0xc6,0x5d,0xd7,0xba,0xb1,0xec,0x0,0x7,0x84,0xae,0x67,0xf7,0x1f,0xcd,0x4b,0x94,0x8,0x37,0x5f,0xcd,0x49,0x63,0x97,0xf,0x3d,0xf6,0x24,0xbe,0xf9,0xc3,0xc7,0x69,0x1f,0x38,0xc7,0xf7,0x46,0x22,0xed,0x34,0x51,0x93,0xf1,0x94,0x12,0xfe,0xfe,0x5b,0xf7,0xe3,0x5b,0x3f,0x7c,0x84,0xa,0x61,0xfa,0x5,0x46,0x16,0x6c,0x8f,0x9d,0xd8,0xc6,0x7f,0xf8,0xb3,0xcf,0xe3,0x1b,0xf7,0x3c,0x84,0xf5,0x6a,0x1b,0x21,0x44,0xa4,0x69,0xa4,0x19,0x71,0x3e,0x20,0x4d,0x13,0x62,0xdf,0xd7,0xd2,0x98,0xd8,0xe1,0x89,0x67,0x5e,0xdc,0x75,0x1d,0x21,0x4,0x6c,0x2c,0x97,0x5a,0x0,0x22,0x7b,0xb1,0x6d,0x75,0xbe,0xf3,0x96,0xeb,0xd1,0xf7,0xbb,0x67,0xe7,0xbd,0xf0,0xd3,0x9f,0xe1,0x4f,0xff,0xe6,0xeb,0x18,0x12,0x9,0x86,0xd3,0x34,0xa8,0x43,0x75,0x58,0x6f,0x63,0x1a,0x6,0x6a,0xb0,0xe6,0x59,0x7c,0x40,0x41,0x2a,0xc0,0x3d,0xf,0x3d,0x85,0x67,0x7e,0xfa,0x2a,0x0,0xa7,0xe2,0x57,0xd7,0x2d,0xaa,0x73,0x34,0xed,0x2e,0xaa,0xa0,0xbd,0x95,0x30,0xe,0x6b,0x76,0xb8,0x91,0x63,0x71,0x1c,0xd6,0xf4,0x2,0x16,0x70,0xc5,0x75,0x19,0x3b,0x12,0x9f,0x6f,0xb8,0xea,0xc2,0x3d,0x4b,0x3f,0xee,0xb9,0xff,0x71,0xbc,0xf8,0xda,0x71,0x12,0xc5,0x59,0x9c,0x16,0xb7,0x5c,0xec,0xc8,0x5,0xd8,0x2d,0x16,0xf0,0xc1,0x63,0x4c,0x5,0xdf,0xb8,0xfb,0x1,0xe4,0x3c,0x7f,0x96,0x17,0x5d,0x70,0xe,0x36,0x96,0x9d,0xce,0x81,0x14,0x71,0x9a,0x84,0xe0,0x82,0x93,0xf9,0xed,0x5e,0x7b,0xfd,0x28,0xfe,0xcb,0xdf,0xff,0x33,0x56,0xab,0x15,0x9,0xfe,0xbc,0x3f,0x25,0x76,0x4f,0x51,0x68,0x87,0xef,0xfc,0xe8,0x71,0xfc,0xd9,0xe7,0xff,0x9,0x59,0x66,0x6f,0x4e,0x23,0xff,0x83,0x41,0xd1,0x3f,0xb,0x12,0x47,0xb5,0x4b,0xce,0x34,0x6b,0xb1,0xf9,0x73,0x41,0x5e,0x4b,0x7b,0xb0,0xe8,0x9e,0x34,0xc,0xc3,0x30,0xc,0xe3,0xad,0x63,0x2,0xa0,0x61,0x18,0x86,0x61,0x18,0xa7,0x44,0x2b,0x80,0xe9,0xec,0x35,0xcc,0x9b,0x7a,0xb,0xff,0xa5,0x5d,0xda,0x45,0x73,0x4a,0xc8,0x89,0xe2,0x82,0x5,0x40,0x61,0xf7,0xd9,0x34,0x4d,0xd8,0x5e,0xad,0xf6,0x3c,0xcf,0x19,0xfb,0xf7,0x71,0x23,0x2d,0xc5,0x80,0x25,0x7a,0xec,0x79,0x5e,0x99,0x14,0x26,0x94,0x52,0x34,0xfe,0x5b,0x4a,0x41,0xbf,0x58,0xa2,0xeb,0x7a,0xf4,0xcb,0xd,0x38,0x38,0x8c,0xe3,0xfa,0xff,0x65,0xef,0x4d,0x7f,0x25,0x3b,0xef,0x3b,0xbf,0xef,0xb3,0x9c,0xa5,0xea,0x2e,0xbd,0xb1,0xbb,0xd9,0x6c,0xb2,0xb9,0x8a,0x8b,0x5a,0x12,0x29,0x51,0xa2,0x65,0xd2,0x12,0x35,0x63,0x49,0x96,0x26,0xb6,0xc7,0x96,0xc6,0xe3,0x19,0x18,0x13,0xd8,0x18,0x3,0x83,0xbc,0x49,0x30,0x79,0x91,0xd7,0xf9,0x13,0x2,0x24,0x40,0x80,0xac,0x40,0x26,0x46,0x26,0xe3,0xc0,0xe,0xe4,0x78,0xc6,0x96,0x46,0x92,0x25,0xd9,0xda,0x69,0x53,0x5c,0x24,0x91,0x14,0x49,0x71,0x51,0x37,0xc9,0x66,0x6f,0xf7,0xde,0xaa,0x73,0xce,0xb3,0xe6,0xc5,0xef,0xf7,0x3c,0xe7,0xd4,0xbd,0x75,0x69,0xda,0xa2,0x0,0xd,0xf0,0xfc,0x0,0x5b,0xdd,0xb7,0x6f,0x55,0x9d,0xbd,0x78,0x3e,0xe7,0xbb,0x64,0x1b,0x72,0x33,0xdb,0x80,0x90,0x12,0x4d,0x3b,0x47,0x55,0x35,0xa8,0xea,0x6,0x52,0x69,0x68,0x5d,0x61,0xbe,0xb9,0x9d,0x41,0x63,0x88,0x1,0x55,0xd3,0x2,0x20,0x8b,0x70,0x3b,0x9b,0xa3,0x6a,0x5a,0x6a,0x99,0x5d,0x57,0x90,0x10,0x2,0x1c,0x43,0x16,0x21,0x25,0x94,0x52,0xac,0xc4,0x22,0x78,0x24,0xa5,0xcc,0x9f,0x15,0x63,0xc0,0x4f,0x2e,0x5d,0xc7,0x60,0xcc,0x81,0xf7,0x39,0x7e,0xec,0x8,0x67,0xc0,0x69,0x2e,0x4b,0xa1,0xcf,0xff,0xce,0x53,0x2f,0xe0,0xdf,0xfd,0xd9,0x37,0x31,0x58,0x47,0x90,0x2b,0x6,0x28,0xad,0xd9,0x32,0x4a,0x86,0xd1,0xa4,0x94,0x12,0xdc,0xe8,0xdb,0x19,0xf,0xb3,0x6,0x0,0x6a,0xad,0x33,0x88,0x75,0xce,0x42,0xeb,0x6a,0x54,0xf0,0x71,0x9e,0x62,0x2a,0x7,0xd9,0x3f,0xd6,0x3a,0x7c,0xf1,0x1b,0x4f,0x50,0xe6,0x63,0xca,0x71,0x63,0x34,0xe3,0xb9,0x55,0x39,0x4,0xf,0x3b,0xf4,0x70,0x86,0x40,0xa4,0x10,0x82,0x6c,0xd9,0x52,0x62,0xd1,0xd,0xf8,0x3f,0xff,0xf8,0x4b,0xf8,0xe1,0x4b,0xaf,0x93,0xc5,0x39,0x84,0x9c,0xd,0x9,0x20,0x83,0xc8,0x4,0x70,0x11,0xa9,0x51,0x7a,0x6f,0x39,0xac,0x3d,0x46,0x9a,0xba,0x5a,0x81,0x4a,0xba,0xae,0x9,0xa8,0x5,0xda,0x3e,0x77,0xdd,0x7a,0xe6,0xc0,0x6b,0x42,0x8,0xf8,0xe2,0xd7,0x1f,0x47,0x67,0xa9,0x3c,0xa4,0xef,0x16,0xa8,0x9a,0x19,0xe5,0x35,0x86,0xc0,0x2d,0xb9,0xe,0x31,0xf8,0xc,0x9b,0xc1,0x6a,0x4b,0xa5,0x75,0x2e,0xcf,0x48,0xd9,0x75,0xd4,0x16,0x4d,0x4a,0xbf,0x18,0xe,0x2,0xc0,0x18,0x63,0x56,0x68,0xa,0x88,0x5c,0xee,0x1,0x1,0x38,0x4b,0x19,0x91,0x9,0xfe,0x25,0x35,0x6d,0x8c,0x1,0xf7,0xdd,0x79,0xee,0xc0,0x3e,0x30,0xc6,0xe2,0xbb,0xdf,0xff,0x31,0x9c,0xb3,0x10,0xe0,0xc6,0x68,0x56,0x99,0xd6,0xed,0xc,0xde,0x91,0x25,0xdc,0xe,0x3,0x1,0x51,0x21,0xf0,0xc3,0x17,0x2f,0x60,0xd9,0x75,0x2b,0xef,0x33,0x9f,0xcd,0x70,0xc7,0x99,0x13,0x93,0xf7,0x1f,0x8f,0xfb,0xb7,0xca,0xdc,0xfb,0xc6,0x63,0x4f,0x63,0x61,0xd8,0xc2,0x9d,0xce,0x3d,0xb6,0xe1,0x27,0x3b,0xb3,0x4d,0x99,0x9d,0xc,0xbd,0x1d,0x43,0xf7,0x74,0xfe,0xa,0x6e,0x0,0x56,0x4a,0xe7,0xed,0xe6,0x1c,0xed,0x3f,0xde,0x60,0x93,0xcf,0x4f,0x56,0xf4,0x64,0x8a,0x2e,0x53,0xa6,0x4c,0x99,0x32,0x65,0xca,0xfc,0xb4,0x53,0x0,0x60,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0xe6,0x6d,0x4d,0x6a,0xf2,0x4d,0x37,0xe9,0x91,0xc1,0x97,0x14,0x12,0xce,0x19,0x80,0x6d,0x93,0xfc,0xcb,0x2b,0x96,0x52,0xa9,0x34,0xa2,0xf,0xac,0xae,0x52,0x10,0xba,0xc2,0x62,0xd9,0xad,0xfd,0x9c,0x53,0x27,0x8e,0x64,0x25,0xa1,0x35,0x3d,0xa4,0x52,0xc,0x48,0x1c,0x96,0x7b,0x3b,0x70,0xd6,0x92,0xaa,0xca,0x3b,0x56,0x25,0x52,0xce,0x9f,0xae,0x48,0xb1,0x67,0xcd,0x80,0xaa,0x69,0xb1,0xb1,0x75,0x94,0x9b,0x71,0x5,0x65,0xe5,0x69,0x4d,0xa,0x2f,0xb6,0x1b,0x6a,0xad,0x9,0x9e,0x78,0x7,0x5d,0x55,0x19,0x80,0x24,0x60,0x98,0xac,0x99,0x4a,0x6b,0x2a,0x32,0x58,0xb,0x79,0x2,0xab,0x1f,0x5d,0x6e,0x52,0xb5,0x66,0x20,0xdb,0xb3,0x23,0xb5,0x97,0x10,0x82,0x60,0x88,0xd6,0xe8,0x6,0x43,0x76,0xd7,0x7d,0xd3,0x54,0xe3,0x76,0x83,0x10,0xd9,0x92,0xfb,0x83,0x17,0x2f,0x60,0xb0,0x2e,0xab,0x1c,0x2b,0x6,0xa2,0xa9,0x69,0x39,0x6,0x52,0xc1,0x91,0xc5,0xba,0x62,0x15,0x22,0x70,0x98,0x6a,0x4a,0x71,0x1,0x8b,0xae,0x6a,0xce,0x4c,0x14,0x8,0x81,0xc0,0x94,0x10,0x2a,0xc3,0xc7,0xfd,0xf3,0xc6,0xe5,0xab,0x78,0xf5,0xd2,0x4e,0xde,0xf,0xce,0x1a,0x2a,0x5e,0xf1,0x94,0xed,0x6,0x2e,0x7d,0x91,0x52,0x21,0x15,0x89,0x78,0x47,0xd6,0xd4,0xe8,0x3,0xba,0xc1,0xe2,0x85,0xb,0x97,0xb8,0x6d,0x58,0xa1,0x69,0xe7,0x4,0xb3,0x78,0x5f,0x24,0xf5,0x68,0x3a,0xce,0x84,0x54,0x50,0xba,0x82,0xf3,0xeb,0x96,0x27,0x66,0x85,0xa9,0xae,0x2a,0x2,0x47,0x21,0x40,0xd7,0x35,0xb4,0xae,0x70,0x6c,0x6b,0x3,0x27,0x8e,0x1f,0x3d,0xf0,0xaa,0x4b,0x97,0xaf,0xe2,0xa9,0xe7,0x2f,0x4c,0xf2,0x1e,0x3d,0xc3,0x4b,0x82,0x91,0x7d,0xb7,0x84,0x80,0xc0,0xc0,0xe5,0x30,0x52,0xd2,0x71,0x6d,0x4c,0x8f,0xa1,0xef,0x72,0x7b,0xad,0x73,0x96,0x95,0x73,0x91,0x14,0x7d,0xc3,0x90,0x95,0xa2,0xfb,0xce,0x18,0xca,0x40,0x14,0x2,0x8a,0x4b,0x36,0x42,0x8,0x6c,0x29,0x8f,0xbc,0x1d,0x2d,0xaf,0x11,0x97,0xcf,0x8,0x89,0x9b,0x4e,0x1f,0xcc,0xfe,0xbb,0xfd,0x1b,0xef,0xa6,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x74,0x75,0x7,0x17,0xdf,0xbc,0xc6,0x6a,0xc5,0x2a,0x97,0x9e,0xd4,0x2d,0x29,0x5c,0x9d,0x35,0x18,0xba,0x25,0x84,0x14,0xdc,0xbe,0x1d,0xd1,0x19,0x8f,0xbd,0x45,0x77,0xe0,0x1c,0xbe,0xe5,0xcc,0xd,0x39,0x2b,0x33,0x15,0xec,0x28,0x6e,0xd6,0x5e,0x97,0x1,0xd8,0xf5,0x3,0xbe,0xfd,0xbd,0x67,0x19,0xce,0xca,0x7c,0x6e,0xa6,0x9,0xc1,0xe7,0x5c,0x49,0x52,0x65,0x8e,0x76,0xf2,0x64,0xc9,0xa6,0xeb,0x45,0xe0,0x6d,0x18,0xe1,0xed,0x8,0x89,0x9,0x92,0xca,0xbc,0x7d,0x13,0xd8,0x8e,0x1c,0x35,0x50,0xa6,0x4c,0x99,0x32,0x65,0xca,0x94,0x79,0x67,0xa6,0x64,0x0,0x96,0x29,0x53,0xa6,0x4c,0x99,0x32,0x65,0xde,0xd6,0xa4,0x3c,0x2e,0x21,0x4,0x17,0x1a,0xc4,0xac,0xf0,0x51,0x5c,0x90,0x10,0xbc,0xcf,0xc5,0x2,0x40,0x84,0xd2,0x15,0x94,0xae,0xe0,0x9d,0xe5,0x5c,0x3b,0x97,0x41,0xdb,0xc5,0xd7,0x2e,0xe1,0xce,0xdb,0x6e,0x39,0xf0,0x39,0xc7,0x8e,0x6c,0x63,0xde,0x54,0xe8,0x8c,0xc8,0xa0,0xc7,0xb1,0xca,0xc,0x31,0xc2,0x9a,0x3e,0xc3,0xa2,0x8d,0xcd,0x6d,0x58,0x6b,0x32,0xac,0xdb,0xd8,0x3e,0x9a,0xcb,0x20,0x92,0x62,0x30,0xc1,0xa,0xad,0x6b,0xe8,0x56,0x3,0x42,0x30,0x40,0x23,0xe8,0xd7,0xce,0x36,0x30,0xf4,0x4b,0xd4,0xdc,0x88,0xdb,0xcc,0x36,0xd8,0xa6,0x8,0xce,0x76,0x23,0xa8,0xb2,0x4e,0x1,0x48,0xd9,0x76,0x31,0x97,0x9b,0xa4,0x66,0x5a,0x67,0x2d,0x5b,0x5c,0x9,0x10,0xd5,0x6d,0x4b,0xca,0xa9,0x10,0x56,0xe0,0x49,0xfe,0xf,0x32,0xad,0xd9,0x2,0x6c,0xd1,0xb4,0x73,0x82,0x33,0xc,0xf5,0xd2,0xf6,0xb2,0x43,0x8f,0x98,0xfe,0x4e,0x1f,0x9e,0xd5,0x63,0xde,0x53,0x1b,0xf3,0xe9,0xa3,0x1b,0x78,0xff,0xbd,0xb7,0xa2,0x6d,0xf,0xda,0x5f,0x5,0xa8,0xc9,0x36,0x29,0xd8,0xda,0x8d,0x2d,0xb8,0xc,0x12,0x9,0x68,0xc5,0x43,0xd4,0x56,0x2f,0xbe,0x74,0x1,0xde,0x53,0xc6,0x21,0xa9,0x14,0xa9,0xb5,0x36,0x7a,0xbf,0xb2,0xde,0x64,0x43,0x56,0x19,0xfa,0x38,0x6b,0xe9,0x5d,0x3d,0xa0,0xc0,0xe5,0x31,0xce,0xc1,0x7b,0x87,0xaa,0xaa,0xe1,0x9c,0x61,0x60,0x15,0xa0,0x34,0xd9,0x7f,0x23,0x22,0x6a,0x29,0xf0,0xae,0x5b,0x4e,0xe0,0xdd,0x77,0x9e,0x5d,0xbb,0x3c,0x8c,0x88,0x50,0x55,0x94,0x85,0x17,0x82,0x7,0x42,0x44,0x54,0x2,0xc7,0xb7,0xda,0xdc,0xdc,0x3b,0x9d,0x57,0x2e,0x5e,0x46,0x88,0xc,0xb8,0x58,0x95,0x97,0xb2,0xfe,0xc8,0x3e,0xac,0xe0,0xd9,0x46,0xec,0x9d,0x83,0xf5,0xe,0xba,0x6e,0x32,0xf0,0xa2,0x75,0x22,0x6b,0xea,0x68,0xd1,0x4e,0x45,0x1a,0x7,0x55,0x9d,0x42,0x0,0x52,0x8,0x4,0x2e,0xff,0x0,0x0,0x33,0x74,0x4,0x2c,0x41,0x0,0x4f,0xb1,0xa,0x33,0xf8,0x1,0x75,0xd3,0x62,0xde,0x6a,0x6c,0x6e,0xcc,0xf,0xbc,0xd7,0x7c,0xd6,0xe2,0x3f,0xff,0xb5,0x5f,0xca,0x9f,0x4d,0xc7,0x80,0x60,0xcd,0x2d,0x59,0x8d,0x95,0x52,0x23,0x48,0xe4,0x8c,0xc8,0x69,0x2b,0x73,0x9a,0x93,0x27,0x8e,0xe6,0x7d,0xd7,0xb4,0x73,0x82,0xaf,0x31,0xc0,0xc,0xc3,0x5a,0x5,0xe0,0x95,0xab,0xd7,0x71,0xbd,0x33,0x70,0x76,0x0,0x78,0xbf,0x86,0x10,0xe8,0x98,0x61,0xf0,0x17,0x26,0x36,0x5e,0x67,0x7,0x44,0x70,0xf3,0x33,0x80,0xe8,0x43,0x6e,0x3e,0x76,0x76,0xb4,0x5c,0x7,0x3e,0x17,0x24,0x67,0x86,0xe6,0x2c,0x4a,0x56,0x18,0x2,0x58,0x6b,0xbb,0x2f,0x53,0xa6,0x4c,0x99,0x32,0x65,0xca,0xfc,0xfd,0xa6,0x0,0xc0,0x32,0x65,0xca,0x94,0x29,0x53,0xa6,0xcc,0xdb,0x1a,0xb2,0xee,0x9,0xc4,0xac,0xfa,0xa,0xf0,0xc1,0x8f,0x59,0x80,0x69,0x58,0xb9,0x23,0x53,0xae,0x5c,0x56,0x6,0xa6,0x9b,0x7a,0x82,0x56,0x2f,0xbe,0xfa,0x3a,0x7e,0x69,0xcd,0xe7,0x6c,0x6d,0x6e,0xe0,0xae,0x73,0xa7,0xf1,0xbd,0x67,0x5f,0x61,0x98,0x36,0x64,0x35,0x9d,0xaa,0x2a,0xe8,0xe0,0x21,0xa4,0x82,0x35,0x3,0xba,0xe5,0x82,0x14,0x6c,0xc,0xc6,0x48,0x3d,0x26,0x72,0xc6,0xa0,0x54,0xa,0x15,0xc3,0x35,0x82,0x64,0x2d,0x29,0x4,0xab,0x9a,0x5b,0x5d,0x43,0xb6,0x66,0x46,0xce,0x53,0xeb,0x97,0x7b,0x54,0xfe,0xc1,0xb6,0x5f,0x31,0xb1,0x69,0xee,0x9f,0x18,0x3c,0x1,0xf,0x41,0x10,0xc3,0x7,0x2,0x62,0x4a,0xd7,0xe8,0x97,0x7b,0xc,0x45,0x2c,0x84,0x91,0x98,0x6f,0xb5,0xdc,0x6c,0xba,0xe,0x6a,0xa4,0x36,0xe,0x91,0x4b,0x44,0x80,0x64,0xa7,0x4,0xac,0xe9,0xc9,0x3e,0xca,0xf9,0x89,0x79,0xdb,0x2,0x38,0xbe,0x35,0xc3,0x7d,0xb7,0x9d,0xc6,0x7b,0xef,0xbd,0x1d,0x67,0xcf,0x9c,0x42,0xa5,0xd5,0xda,0xfd,0x17,0x18,0x54,0x26,0x5,0xe4,0xd0,0x2d,0xb2,0xfd,0x57,0x80,0x20,0x64,0xf4,0x6e,0xed,0x6b,0xaf,0xec,0x2c,0x0,0x0,0x52,0x2a,0x98,0xa1,0x47,0xd3,0xce,0xb0,0xb7,0x73,0x35,0x2f,0x13,0x62,0x2a,0x7b,0x0,0x22,0x2f,0xb3,0xae,0x2a,0x44,0xc4,0x49,0x93,0x32,0xb2,0xf2,0x2d,0xa9,0xd4,0xc8,0x7e,0x4a,0x5,0x1c,0x4a,0x0,0x77,0xdd,0x72,0x12,0xef,0xbb,0xeb,0x2c,0xde,0x75,0xe7,0x39,0x1c,0xdd,0xde,0x5c,0x5f,0x4a,0x22,0x4,0x20,0x24,0x97,0x7e,0x90,0xf5,0x58,0xb3,0x2a,0xce,0x79,0x87,0x93,0xc7,0xb7,0xf2,0xf6,0x9b,0xce,0xcb,0x17,0xde,0x80,0xf3,0x64,0xe1,0x1d,0x96,0x7b,0x14,0xe7,0x27,0x25,0xec,0x40,0x8d,0xba,0x35,0xc3,0xb0,0xc8,0x8a,0x44,0xb0,0x3a,0x8d,0xf2,0x15,0x3d,0xdb,0xba,0x81,0xaa,0x66,0x0,0xca,0x56,0xdb,0xa9,0xca,0x6d,0xdd,0x7e,0x25,0xcb,0xb3,0x27,0x15,0x21,0xdb,0xb4,0xc9,0x62,0x2c,0x72,0x8e,0x61,0xca,0xbd,0x6b,0x6b,0xbd,0xb6,0x1c,0xe7,0xd8,0xf6,0x6,0x8e,0x6d,0x6f,0xbc,0x23,0xe7,0xf1,0xf6,0x26,0xad,0xa7,0xd6,0x1a,0x66,0x20,0x15,0xa8,0x4,0xa0,0xab,0x76,0xed,0xf6,0xde,0xdd,0x5b,0xb2,0xdd,0x59,0x42,0x29,0xd,0xeb,0xc9,0xba,0x2f,0x95,0x26,0x28,0x1d,0x23,0xdb,0xfd,0x5d,0xb6,0xee,0xb,0x1,0x4,0x1f,0x18,0x76,0x26,0x75,0xa8,0x64,0xfb,0x3e,0xad,0xbf,0xf7,0xe,0x2a,0x1,0x7a,0x86,0x7f,0xa3,0xa,0x54,0x1e,0x6a,0x47,0x2e,0x53,0xa6,0x4c,0x99,0x32,0x65,0xca,0xfc,0xfd,0xa6,0x0,0xc0,0x32,0x65,0xca,0x94,0x29,0x53,0xa6,0xcc,0xdb,0x9a,0x10,0xe9,0x86,0x3e,0x41,0xc0,0xc8,0x1a,0x24,0x21,0xb9,0x80,0x41,0x57,0xb9,0xc1,0x55,0x4e,0x8a,0x3f,0x48,0x21,0x46,0xff,0x9e,0xb1,0x48,0x8c,0x78,0xe6,0xc7,0x17,0xd1,0xf5,0x3,0x66,0x6d,0xb3,0xf2,0x39,0x4a,0x49,0xbc,0xef,0x9e,0x5b,0xf1,0xc4,0x8f,0x5e,0x45,0x64,0xb1,0x5c,0xca,0x0,0x8c,0x88,0xac,0x22,0x92,0x90,0x52,0x62,0xeb,0xc8,0x31,0xca,0xc5,0x93,0x54,0x1c,0x42,0x65,0x8,0x91,0xac,0xa7,0x11,0x90,0x92,0xec,0xa4,0x49,0xa1,0x66,0x86,0x1e,0x55,0x5d,0x13,0xa4,0x3,0x8,0x6a,0x70,0xf6,0x1b,0x80,0x9c,0x39,0xa8,0xeb,0x6,0x11,0x94,0xd5,0x56,0x37,0x33,0x24,0x4b,0xe2,0xfe,0x91,0x4a,0x13,0x48,0xf4,0xa4,0x70,0x4a,0x6d,0xc8,0xce,0x1a,0xce,0x7a,0x1b,0x50,0xd5,0xd,0xe5,0xb3,0x99,0x1,0xa1,0x6d,0xb0,0x2e,0xd3,0x2c,0xd9,0x87,0x23,0x67,0xe3,0x1,0x69,0x99,0x55,0xce,0x31,0x4c,0x6a,0x48,0x21,0x25,0xe6,0x6d,0x83,0xf3,0x77,0xdc,0x84,0x7,0xee,0xbb,0x1d,0xe7,0xce,0x9e,0x42,0xdb,0xd4,0x87,0x36,0xf8,0x8e,0x3b,0xd0,0x67,0xf8,0x17,0xbc,0x47,0x55,0x35,0x30,0xa6,0x67,0xe5,0x98,0xa0,0xd6,0x62,0x5d,0xaf,0x7d,0xe9,0xde,0x62,0x99,0x55,0x9d,0x42,0x8,0xec,0x5e,0xbb,0x8c,0x66,0x36,0x67,0xb0,0x47,0xea,0xc7,0x94,0x1f,0x98,0xec,0xb0,0xe9,0x73,0xbc,0xb3,0x39,0x63,0x2f,0xc6,0x88,0xd9,0xc6,0x66,0x2e,0x6f,0x1,0x80,0x73,0xa7,0x8f,0xe3,0x81,0x7b,0x6f,0xc5,0xf9,0xbb,0x6f,0xc7,0x89,0xe3,0x47,0xa1,0xd4,0xdf,0xa2,0xfa,0x8a,0x11,0xde,0x5b,0x98,0xa1,0xcb,0x96,0x58,0xcf,0xe5,0x29,0x88,0x1,0x5b,0x9b,0x1b,0x6b,0x5e,0x12,0xb1,0xbb,0xe8,0xa9,0x88,0x23,0x78,0xd4,0xcd,0x8c,0xac,0xbf,0x9c,0x81,0x18,0x42,0x80,0x33,0x94,0x9f,0x27,0x95,0x82,0xc,0x3a,0x37,0x4e,0x7,0xce,0x4,0xd4,0x15,0x59,0xac,0xcd,0xd0,0xe5,0x75,0xac,0x9b,0x96,0x14,0x8e,0x6b,0xac,0xaa,0x54,0x7c,0x4b,0x39,0x85,0xc9,0xaa,0x4e,0x3f,0x9b,0x2a,0xdc,0xaa,0xc,0x19,0x85,0x10,0x50,0x88,0x2b,0x70,0xf7,0x67,0x31,0x4d,0x53,0x67,0xf0,0xab,0x14,0x1,0x38,0xa9,0x52,0xe,0xe4,0xfa,0x7d,0x9f,0x94,0xb4,0x7d,0xb7,0xa0,0xfd,0x18,0x1c,0xbc,0xa7,0x82,0x93,0xaa,0x6e,0x60,0xfa,0x2e,0x1f,0xd7,0x29,0xcb,0x31,0x59,0xe1,0x53,0xdb,0x74,0x86,0xa6,0x52,0x20,0x38,0x7a,0x28,0x90,0xca,0x4c,0xbc,0xb3,0x10,0x51,0x70,0xc7,0xa,0xe9,0x3b,0x95,0xd2,0x87,0x2a,0x52,0xcb,0x94,0x29,0x53,0xa6,0x4c,0x99,0x32,0x7f,0xf7,0x29,0x0,0xb0,0x4c,0x99,0x32,0x65,0xca,0x94,0x29,0xf3,0xb6,0x26,0x87,0xf2,0xc7,0x8,0x8e,0xe9,0x82,0xf7,0x16,0x52,0x35,0x2b,0x5,0x2,0xe9,0xf7,0x2,0x3,0xa7,0xd4,0xea,0x2a,0x0,0x82,0x65,0x21,0x2,0x2a,0xe2,0xca,0xce,0x2,0xaf,0xbc,0x7a,0x11,0x77,0xdf,0x75,0xdb,0x81,0xcf,0xba,0xef,0x5d,0xb7,0xe1,0xcc,0xf1,0x27,0xf1,0x93,0x37,0xae,0x40,0xe9,0xa,0xd6,0x18,0x52,0xc7,0xd,0x3d,0xa4,0xd2,0xe8,0x16,0xbb,0xd4,0xf6,0xdb,0xb4,0x88,0xce,0x42,0x28,0x5,0xcd,0xe0,0x24,0x41,0x32,0x25,0x24,0xa4,0x26,0x3b,0xe7,0x34,0x5b,0x4c,0x57,0xd,0x67,0xd5,0x8d,0x90,0x2a,0x41,0xb6,0xb4,0xfc,0x9,0xe8,0x48,0xa9,0xd8,0x3a,0xeb,0xc7,0xb2,0x82,0xfd,0x13,0x63,0xb6,0x5d,0xe,0xc,0xc2,0xac,0x19,0xd0,0x34,0x33,0xb6,0x4d,0xb,0x38,0x63,0xd0,0xcc,0xe6,0x93,0x86,0xd3,0x7d,0xdb,0x56,0x2a,0xc,0xdd,0x32,0x37,0x7,0x57,0x4d,0xbb,0xa2,0x9a,0x3,0xa8,0xe4,0xe4,0xf8,0xd6,0xc,0xf,0xdf,0x7f,0x17,0xce,0xdf,0x73,0x1b,0x8e,0x1d,0xd9,0x3a,0x0,0xfd,0xfa,0xc1,0xe2,0xe2,0xeb,0x6f,0xe2,0xc6,0x53,0xc7,0xf,0x80,0xd5,0x18,0x23,0xac,0x31,0xd9,0x32,0x9c,0x94,0x73,0x9,0x40,0x85,0x18,0xb2,0xca,0xed,0xc0,0x2a,0x42,0x72,0x53,0x6e,0xf,0xc9,0x19,0x82,0xcb,0xdd,0x1d,0xca,0x71,0x93,0x4,0xf,0xc9,0xb2,0xac,0x73,0x4e,0xa4,0xf7,0xe,0x52,0x48,0xb2,0x83,0xa,0x2,0x8f,0x52,0x91,0x5,0x38,0x4,0x8f,0xf3,0x77,0x9e,0xc1,0x23,0x1f,0x7a,0x2f,0x6e,0x3f,0x77,0x16,0x4d,0xb3,0xa,0x1e,0x43,0x88,0xb8,0x72,0xf5,0x1a,0xf6,0xba,0x1,0xb7,0xdd,0x7c,0xe3,0x81,0xe3,0x30,0x1d,0x63,0xa6,0xef,0x50,0x35,0xdc,0x38,0x1d,0x49,0x79,0xd9,0x54,0xeb,0xf3,0xf8,0x8,0x3a,0x6a,0x48,0x19,0x31,0xf4,0x4b,0x82,0x93,0xde,0xa1,0x6e,0xe7,0xd0,0x5c,0x58,0xa2,0x74,0x85,0xc5,0xce,0x35,0x68,0x5d,0xd1,0x71,0xc2,0x76,0x60,0x20,0xc2,0xe,0x4,0xee,0xda,0xf9,0x66,0xde,0x9e,0x66,0xe8,0x50,0xd5,0xed,0xda,0x63,0x43,0x8,0xb2,0xc1,0x5a,0x6b,0x10,0xbc,0xa3,0x6d,0xc7,0xcd,0xb9,0x64,0x3,0xa7,0x7d,0x47,0xad,0xd3,0x47,0x60,0x83,0x81,0x90,0x9b,0x6b,0x3b,0x2f,0x42,0x8,0x8,0xa9,0xae,0x37,0xf2,0x9b,0xd3,0x1f,0x90,0x9a,0x80,0x47,0xd5,0x1c,0x41,0xfa,0x95,0x12,0xdd,0x5c,0xf5,0x4b,0x93,0x6c,0xdb,0x9e,0x4b,0x4a,0x28,0x27,0x53,0x1d,0xb2,0xef,0xc1,0x8a,0x5f,0x3a,0xd6,0x87,0x6e,0x91,0x9b,0xb9,0xc1,0x50,0x1d,0x0,0x74,0xd5,0x50,0x96,0xe2,0x72,0x8f,0x54,0xb5,0xc,0xd6,0xed,0xd0,0xe7,0x6c,0x41,0x21,0x24,0xea,0xba,0x61,0xdb,0x70,0xc8,0xb9,0x95,0x69,0xd9,0x5,0x0,0xcf,0x51,0x3,0xde,0x3b,0x5e,0x15,0x85,0x18,0x7d,0xb9,0x0,0x97,0x29,0x53,0xa6,0x4c,0x99,0x32,0x3f,0xe5,0x14,0x0,0x58,0xa6,0x4c,0x99,0x32,0x65,0xca,0x94,0x79,0x5b,0x93,0xc1,0x95,0x10,0x10,0x90,0x88,0x31,0xa9,0xae,0x56,0xe1,0xc,0x29,0x8b,0x28,0xfb,0xb,0x8a,0xda,0x53,0xa5,0xd2,0xf0,0xde,0x43,0xcb,0xd1,0x16,0x8c,0x18,0xf1,0xf5,0xbf,0xfe,0x3e,0xee,0xba,0xe3,0xdc,0x1,0xcb,0xe6,0x7c,0xd6,0xe2,0x53,0x1f,0xfd,0x0,0xfe,0xcd,0xe7,0xbe,0x8a,0xc5,0xde,0x6e,0x2e,0x6d,0x48,0xa3,0x94,0x46,0xd5,0xb4,0xa4,0x64,0xab,0x1b,0x68,0x5d,0x73,0x8e,0x1b,0xb5,0xa3,0x4a,0xa5,0x10,0xb9,0x81,0xb8,0x6e,0x5a,0xc,0xdd,0x82,0x8a,0x2e,0xa4,0x84,0x35,0x64,0x5b,0xd4,0xba,0x42,0xdd,0xb4,0xb9,0x84,0x22,0xa9,0xfe,0xa6,0xcd,0xad,0x52,0x4a,0x18,0xd3,0x53,0x9,0x88,0x5f,0x5f,0x2,0xe2,0x9c,0x45,0x84,0x84,0x77,0x96,0x7e,0xbf,0xef,0x60,0xfa,0x2e,0x97,0x1e,0xe8,0xaa,0x82,0xae,0x6b,0x86,0x7a,0x6e,0xbd,0x95,0x38,0x6,0x6a,0x86,0xe5,0x4c,0x34,0x6f,0x2d,0x7f,0x6e,0xb,0x29,0x5,0xea,0xba,0xc6,0x47,0xee,0xbf,0x1d,0x1f,0xf9,0x85,0x7,0xb0,0xb5,0x39,0x3f,0xb0,0x5f,0x2e,0x5d,0xbe,0x86,0xc7,0x9e,0x7c,0x16,0x8f,0x3f,0xf3,0x32,0x7a,0x7,0xfc,0xeb,0x7f,0xf1,0xa9,0x3,0x0,0x30,0x95,0x91,0x0,0x91,0xf2,0xc,0x63,0x84,0x8f,0x4,0xfc,0x9c,0x35,0x90,0x6c,0x95,0x5e,0xbf,0xf3,0x3,0xab,0x3c,0x9,0x2,0x86,0xe0,0x79,0x5b,0x92,0x9d,0x9a,0xec,0xd5,0x1a,0xd1,0x1a,0xd4,0xed,0xc,0xb6,0xef,0x21,0x24,0x41,0x22,0x21,0x4,0xaa,0xd9,0x6,0xb7,0x4,0xf,0xb8,0xfd,0xa6,0x1b,0xf0,0x99,0x4f,0x3d,0x8a,0xdb,0xcf,0xdd,0x74,0x40,0xed,0xd7,0x75,0x3d,0x5e,0x78,0xe5,0x35,0x7c,0xf7,0xa9,0xe7,0xf1,0xec,0xcb,0x6f,0xe0,0xa1,0x77,0x9f,0x3b,0x0,0x0,0xd3,0xf2,0x6,0xef,0x50,0xd5,0xd,0xbc,0x73,0x70,0xd1,0x64,0xf5,0xa6,0x31,0xeb,0xf3,0xf8,0x66,0xac,0xbe,0x34,0x6c,0xa7,0x36,0xbe,0x83,0xae,0x1a,0xca,0x41,0xd4,0x9a,0x15,0xa2,0x1d,0x65,0x2,0x7a,0xf,0x13,0xba,0xc,0x87,0x8d,0xe9,0x9,0xce,0x72,0xd9,0x8b,0xae,0x6a,0xe8,0xba,0xc9,0xe0,0xcd,0x5b,0xbb,0x76,0xb3,0x11,0x8,0xd3,0xb0,0x9c,0x19,0xa8,0x75,0xd,0x6f,0x2d,0x41,0x45,0xe6,0xe9,0xf3,0xcd,0x6d,0x74,0xcb,0x5d,0x68,0x5d,0xc1,0xc,0x3,0x29,0x6d,0xb1,0xa,0xe3,0x1e,0xff,0xfe,0xb,0xf8,0xea,0x77,0x7f,0x40,0xc7,0xb6,0x10,0xb0,0xc6,0xe4,0xd2,0x8e,0xe8,0x1d,0x82,0x77,0xc,0x75,0x23,0x4,0x22,0x20,0x28,0xf3,0xd2,0x9a,0x81,0x60,0x76,0x1c,0xb5,0x74,0xc6,0x58,0xda,0x87,0xde,0x61,0xbe,0xb9,0x4d,0xdb,0x64,0xe8,0x80,0x19,0x15,0xaa,0x1c,0xdc,0x76,0x32,0x2b,0xfa,0x22,0x5b,0xbd,0x9d,0xb1,0x70,0x66,0x80,0xd2,0x15,0x74,0x55,0xc1,0x9a,0x81,0x4b,0x65,0x64,0x6,0x77,0x66,0x18,0x10,0x82,0x83,0xe5,0xc2,0x98,0x18,0xc9,0xe,0xbd,0xb4,0x6,0x55,0x5d,0x73,0x1e,0xa4,0x65,0x2b,0xf7,0xd8,0xba,0x9c,0x0,0x26,0x41,0xc1,0x50,0xe0,0x5f,0x99,0x32,0x65,0xca,0x94,0x29,0xf3,0xe,0x4d,0x1,0x80,0x65,0xca,0x94,0x29,0x53,0xa6,0x4c,0x99,0xbf,0xc3,0xc4,0x9c,0x63,0x96,0x6e,0xf6,0x95,0xae,0x10,0x9c,0x7,0x62,0x80,0x0,0x1,0xa,0xa9,0x34,0xa0,0x90,0xc3,0xff,0x1,0xb2,0x6,0x92,0x9d,0x52,0x42,0x49,0xca,0x51,0x7b,0xfc,0x99,0x97,0xf0,0xa9,0xcb,0xd7,0x70,0xe3,0xc9,0x83,0xcd,0xa7,0xe7,0xef,0xbe,0x1d,0xef,0xbf,0xfb,0x5,0x7c,0xfd,0x7b,0xcf,0xc2,0xe,0x3,0x37,0xcd,0x5a,0x68,0x5d,0x41,0xce,0xa9,0xdd,0x57,0x8,0x1,0x5d,0x35,0xd0,0x5a,0x43,0xca,0x96,0xb3,0xd5,0x48,0x55,0x55,0x73,0x99,0x86,0x19,0x7a,0xcc,0x37,0x8f,0xc0,0xda,0x81,0x94,0x68,0xde,0xa3,0xaa,0x2b,0x24,0x95,0x62,0xb2,0xe,0x87,0x10,0xb2,0xb2,0x2a,0x46,0x82,0x28,0xc9,0x22,0x9a,0x4a,0x2f,0xd6,0x6c,0xe,0xe8,0xaa,0x46,0x3f,0xc,0xb9,0xb0,0xa3,0xf,0x94,0xad,0x17,0x79,0x3b,0x21,0x92,0x6d,0x79,0xb9,0x7b,0x1d,0x6a,0x73,0x3,0x6b,0xa3,0xcd,0x38,0xcb,0x2e,0x95,0xf7,0xe,0xfd,0x32,0x17,0x2a,0x9c,0x38,0x7a,0xa,0xbf,0xf5,0xc9,0xf,0xe1,0x9e,0xbb,0x6e,0x5d,0x81,0x87,0x31,0x46,0x5c,0x7c,0xfd,0x32,0xfe,0xe2,0x5b,0x4f,0xe0,0x7b,0xcf,0xfd,0x84,0xed,0xa6,0x16,0x75,0x55,0xad,0x5f,0x56,0x56,0xce,0x51,0xc6,0x20,0x65,0xb5,0x59,0xd3,0xa3,0x6e,0x67,0xd4,0x8c,0x1b,0x15,0xc4,0x21,0x96,0x4b,0xef,0x5d,0x86,0x97,0xce,0x1a,0x18,0x6e,0xc5,0x75,0xd6,0x50,0x81,0x4a,0x33,0xcb,0x16,0xe0,0x94,0xa9,0x27,0xa1,0xe8,0x7d,0x95,0x82,0x73,0xe,0xce,0xe,0xf8,0xd8,0x43,0xef,0xc5,0x67,0x7f,0xf5,0x1f,0x62,0x63,0xbe,0xa,0x31,0xfb,0xc1,0xe2,0x89,0x1f,0x3c,0x8f,0xbf,0xf8,0xf6,0xd3,0x78,0xfd,0xca,0xe,0xe5,0xef,0xb9,0x43,0xd4,0x88,0x91,0x20,0x6d,0x44,0xcc,0xd9,0x7c,0x4,0x34,0x49,0x91,0xba,0xec,0xcd,0xda,0xd7,0x9d,0x3a,0xbe,0xc9,0xfb,0x83,0x1a,0xac,0xc9,0x2e,0x4e,0xc7,0xa8,0x1d,0x6,0x2a,0xb5,0x8,0x21,0x2b,0xf4,0x34,0x17,0x74,0x18,0xd3,0xaf,0xe4,0x58,0x52,0x61,0x46,0x47,0xb0,0xd8,0x39,0x6e,0xc0,0x5e,0xdf,0x56,0x1b,0x43,0x80,0x31,0x3,0x9c,0x31,0x50,0x4a,0xc1,0xf4,0xcb,0xdc,0x20,0xec,0xd,0xe5,0x11,0xee,0x5d,0xbf,0x4a,0x76,0xea,0xe0,0x71,0x7d,0xd1,0xc3,0x18,0xda,0x87,0xd3,0x39,0x79,0x7c,0x1b,0x17,0xdf,0xbc,0xe,0x55,0x55,0xd9,0x62,0x4f,0xea,0xc7,0x16,0xdd,0xde,0x2e,0x74,0x55,0x65,0x25,0x1e,0x0,0x3e,0x3f,0x81,0xa1,0xef,0x46,0x85,0xa7,0xf,0x64,0xb1,0x15,0x82,0xf7,0x15,0xbd,0x87,0xd4,0x3a,0x17,0xed,0x60,0x6d,0xce,0xa5,0x83,0x52,0xd4,0xb8,0xbc,0xd8,0xb9,0xe,0x21,0x5,0xf6,0xae,0x5f,0x41,0xdd,0xb4,0xb0,0x9d,0x81,0xe8,0xc5,0x68,0xd1,0x8f,0x1,0x2,0x2,0x8b,0xbd,0x6b,0xd9,0x76,0x6f,0x87,0x9e,0xca,0x67,0x38,0x53,0x31,0xb5,0x2e,0xeb,0xaa,0xce,0xad,0xe1,0x94,0xd,0x48,0x8d,0xc9,0x8,0x82,0x95,0xb3,0xb1,0x94,0x80,0x94,0x29,0x53,0xa6,0x4c,0x99,0x32,0xef,0xe0,0x14,0x0,0x58,0xa6,0x4c,0x99,0x32,0x65,0xca,0x94,0x79,0x5b,0x93,0x14,0x78,0xc9,0x66,0x48,0x19,0x7b,0xa,0xce,0xda,0xc,0xa6,0x72,0xb1,0x83,0x77,0x74,0xf3,0x2e,0x40,0x6a,0x27,0x4d,0xff,0x46,0x85,0xa,0x8e,0x4b,0x42,0x34,0x8c,0x95,0xf8,0xf2,0x5f,0x7e,0x7,0xff,0xec,0x37,0x7e,0xe5,0x0,0x7b,0x50,0x4a,0xe2,0xd7,0x3e,0xf1,0x8,0x5e,0x7b,0xf3,0x2a,0x9e,0x7e,0xf6,0x85,0xac,0x20,0xa2,0x5c,0x39,0x6a,0x68,0x55,0x4a,0x41,0x4e,0x4a,0x14,0xa4,0x52,0xb9,0xd5,0xd5,0x59,0x43,0xea,0xbb,0xaa,0x42,0x8c,0x1,0x5a,0xd7,0xa4,0xde,0x6a,0xaa,0x6c,0x53,0x95,0x4a,0xa3,0xaa,0x55,0xce,0x15,0x24,0x9b,0xaa,0xce,0xb9,0x65,0x10,0x31,0xdb,0x14,0xe3,0x21,0xea,0xa8,0xa9,0xdd,0x71,0x18,0x3a,0x48,0x49,0xca,0xa6,0x88,0x8,0x6f,0x2d,0x3,0xc7,0x1a,0xa2,0x4e,0xc5,0x17,0x6b,0x40,0x51,0xa4,0x8c,0x3c,0x8,0x1,0xc7,0xb9,0x6a,0xd6,0xc,0x98,0xb5,0x2d,0x3e,0xf3,0xf1,0xf,0xe0,0xde,0x77,0xdd,0xb6,0xf2,0xfb,0xd6,0x79,0x7c,0xed,0xdb,0x4f,0xe0,0xb,0xdf,0x78,0xa,0xce,0x53,0xce,0xa2,0xf7,0x16,0x31,0x44,0x88,0xb8,0x7e,0x59,0x11,0x3,0xba,0xe5,0x1e,0x2f,0xb7,0xe7,0x6c,0xc2,0x8a,0xed,0xba,0x1e,0x11,0x26,0x3,0xd4,0x75,0x53,0x37,0x2d,0xba,0xc5,0x6e,0xb6,0xe0,0x6,0xef,0xb8,0x4d,0x59,0x22,0x78,0x87,0xe5,0x22,0x6d,0x6f,0xda,0xce,0x9e,0x1b,0x9b,0x1,0xa0,0x69,0xe7,0x78,0xff,0xbd,0xb7,0xe3,0xb7,0x7f,0xe3,0x93,0x68,0xea,0x55,0xbb,0xef,0xeb,0x97,0xae,0xe0,0xf,0xff,0xfd,0xd7,0xf0,0xc2,0x85,0xcb,0xf9,0x18,0xa3,0x63,0x47,0xac,0xb5,0x24,0x13,0xa3,0xd,0x18,0x96,0x4b,0xa8,0x4a,0xc3,0x19,0x43,0x39,0x74,0xac,0x0,0xbd,0xf0,0xda,0x25,0x78,0x1f,0xe,0xa8,0xb,0x6f,0xbb,0xf9,0x34,0xa4,0x94,0xa8,0xdb,0x19,0xfa,0xe5,0x82,0x41,0x36,0xe7,0xdf,0xf5,0x1d,0xe7,0x3,0x12,0x4,0x1e,0xfa,0xe,0x5e,0x3b,0x44,0x44,0x48,0x21,0xe1,0x9c,0xc9,0xeb,0x12,0xb8,0x85,0x57,0xb2,0xba,0x55,0x40,0x1e,0xba,0xdd,0x92,0x92,0x54,0x8,0x81,0x61,0xe8,0x61,0x87,0x7e,0xb4,0x82,0x87,0x98,0x9b,0x70,0x83,0xf7,0xa8,0x9a,0x6,0x3b,0xbb,0x7b,0xb8,0x72,0xf5,0xda,0x81,0x26,0xe0,0x93,0xc7,0x8f,0xe0,0xc6,0x1b,0x8e,0xe0,0x8d,0x6b,0xb,0x82,0x7f,0x43,0x4f,0x99,0x7d,0x43,0x4f,0x8a,0x3c,0xce,0x59,0xa4,0xd2,0x18,0x6e,0x68,0x66,0x98,0xd9,0xb4,0x33,0xf4,0x6c,0x2f,0x47,0x88,0x70,0xde,0x61,0xf0,0x4b,0x8,0x29,0x51,0xd7,0x2d,0x34,0x0,0xa1,0xc5,0xe1,0xb0,0x4d,0x24,0xdb,0x36,0x59,0xb8,0x9d,0x25,0xa5,0xeb,0xde,0xce,0x35,0xcc,0xe6,0x9b,0xdc,0xf8,0xab,0xb0,0x5c,0xec,0x40,0x4a,0x9,0xe7,0xa8,0xc,0xc4,0x1a,0x43,0x80,0xb8,0x5b,0x40,0xf0,0x39,0x41,0xb9,0x7e,0x64,0x41,0xde,0xd8,0x3a,0xa,0xa9,0x22,0x83,0x6e,0xbe,0x86,0xc4,0x98,0xdb,0x96,0x53,0x46,0x63,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0xe6,0x9d,0x99,0xf2,0x58,0xad,0x4c,0x99,0x32,0x65,0xca,0x94,0x29,0xf3,0xb6,0x46,0x29,0x9d,0x73,0xba,0x92,0x55,0x8f,0x60,0x10,0x72,0x78,0x7f,0xe4,0xd8,0xfe,0xd4,0xce,0x9a,0xf2,0xf7,0x52,0x8e,0x5a,0x52,0x5,0x49,0xa5,0x73,0xfe,0xde,0x5f,0x3d,0xfe,0x1c,0x9e,0xf9,0xd1,0xb,0x6b,0x3f,0x73,0x6b,0x73,0x8e,0xdf,0xfd,0x27,0x9f,0xc4,0x5d,0xb7,0xdc,0xc8,0x4d,0xbf,0x94,0xeb,0xa7,0xeb,0x86,0x73,0xda,0xea,0x6c,0xf9,0xad,0xf8,0x67,0x9,0x2,0x56,0x75,0x3,0x52,0x9,0x4a,0x56,0xe7,0x21,0x97,0xa,0x88,0xdc,0xb2,0x4b,0xc0,0x49,0x4a,0x85,0xed,0x8d,0x16,0xbf,0xf6,0xb1,0x7,0xa1,0x25,0x13,0x3a,0x31,0xfe,0x1e,0xe,0x29,0xd8,0x88,0x8,0x50,0x4a,0xc3,0x39,0x8b,0xa1,0x5b,0x92,0x5d,0xd2,0x59,0xa8,0xaa,0xa2,0xe6,0x62,0x6b,0x32,0x9c,0x74,0xc6,0x40,0xbe,0x45,0x51,0x47,0x88,0x64,0x45,0x76,0xce,0xa1,0x5b,0x2e,0x20,0x95,0xc6,0x2f,0xbe,0xef,0xe,0xbc,0xfb,0xee,0x3b,0xf6,0xfd,0x5e,0xc4,0x17,0xff,0xf2,0x31,0x7c,0xe1,0x5b,0xcf,0x20,0x40,0xe4,0x6c,0xc3,0xaa,0x6e,0xb3,0x12,0x6b,0x9d,0x22,0x8d,0x32,0xfe,0x7c,0x56,0xf2,0x91,0x95,0x37,0xa0,0x5f,0xee,0xc1,0x39,0x43,0xaa,0xb6,0x78,0x38,0xc8,0x1a,0xfa,0x8e,0xac,0xd0,0x21,0xa0,0x6a,0x9a,0xfc,0x3e,0x64,0xff,0x1c,0x0,0x6e,0x7b,0x4d,0xea,0x45,0x3b,0xf4,0x5c,0xa0,0x2,0xd4,0x4a,0xe2,0x37,0x3f,0xfd,0xe8,0x1,0xf8,0x77,0xe9,0xf2,0x55,0xfc,0x4f,0xff,0xf7,0xe7,0xf1,0xe2,0xc5,0x2b,0x94,0xbd,0xc8,0x8a,0x4b,0x33,0x74,0x64,0x4b,0x5d,0xb7,0xcd,0x19,0x70,0x29,0xad,0x79,0x9b,0x53,0x9,0x49,0xf0,0x4,0x7d,0x2f,0x5e,0xba,0xa,0xbb,0xc6,0x92,0x7b,0xcb,0xd9,0x33,0x38,0x79,0x64,0xe,0x67,0x2d,0x35,0x3c,0xb,0x41,0x60,0x8b,0x2d,0xdf,0xc6,0xf4,0xb0,0xa6,0x87,0x33,0x43,0x2e,0x9,0x11,0x24,0x99,0xa3,0xbc,0x3b,0x8,0x38,0x6b,0x31,0x9b,0x6f,0x12,0xac,0x5,0xb5,0x33,0x7b,0x6f,0xe1,0x9d,0x59,0xbb,0x9c,0x0,0xd0,0x71,0x26,0x9e,0x0,0x78,0x99,0x17,0x64,0x5b,0xb6,0x3,0xc1,0x70,0x56,0xbb,0x29,0x45,0xe5,0x31,0x3f,0x7e,0xe5,0xe2,0x81,0xf7,0x6a,0xdb,0x6,0xef,0xb9,0xe3,0xc,0xbc,0x25,0xd5,0x60,0x55,0xb7,0x9c,0x17,0xe9,0x51,0x25,0xe0,0xea,0x1d,0x22,0x0,0xcb,0xd0,0x2d,0x78,0x52,0x31,0x52,0x41,0x8b,0x22,0x0,0xc7,0xaa,0x46,0x30,0xfc,0x1c,0x86,0xe,0xdd,0x62,0x17,0xce,0x59,0x38,0x3b,0x1c,0xd2,0x74,0x1d,0xb2,0x82,0x2f,0xad,0xb3,0xae,0x6a,0xd4,0x4d,0x8b,0xcb,0x6f,0x5c,0xc0,0xd0,0x2d,0xb0,0xdc,0xbb,0xe,0x6f,0x2d,0x86,0xae,0xcb,0xc5,0x30,0xb4,0xc,0x4,0x3,0x9d,0x31,0xb0,0xc6,0x60,0x6f,0xf7,0x1a,0x1d,0x23,0xdd,0x12,0x66,0xe8,0x48,0x95,0xc8,0xe7,0xdf,0xb8,0xdd,0x2,0x20,0x92,0xc2,0xb7,0x5c,0x77,0xcb,0x94,0x29,0x53,0xa6,0x4c,0x99,0x77,0x6a,0xa,0x0,0x2c,0x53,0xa6,0x4c,0x99,0x32,0x65,0xca,0xbc,0xed,0x11,0x6c,0x12,0x8d,0x88,0x59,0x71,0x24,0x84,0xcc,0x16,0x56,0x91,0x3c,0xac,0x49,0x91,0x27,0xe4,0x58,0xb0,0xc1,0xd,0xa8,0xce,0xda,0x6c,0x8d,0xa5,0x4c,0xb6,0x1,0x9f,0xfb,0xe2,0xb7,0xb1,0x58,0xae,0x7,0x3e,0xc7,0x8f,0x1d,0xc5,0x7f,0xf5,0xfb,0xbf,0x8d,0x47,0x3e,0x70,0xf,0x81,0x45,0x6,0x1b,0xa9,0x1,0xb6,0x6e,0x67,0xac,0x9e,0x3,0x29,0xc,0x9d,0xcd,0xff,0x6,0x90,0x72,0x8d,0x40,0x24,0x72,0xd6,0xa0,0xd6,0x64,0x3f,0xac,0xdb,0x16,0x1b,0xb3,0x19,0x3e,0xf1,0xf0,0xfd,0xf8,0x6f,0xfe,0xd5,0x6f,0xe3,0x23,0x1f,0xfe,0x0,0xda,0xb6,0xcd,0xcb,0xcc,0xfa,0x2d,0x6,0x88,0xeb,0x2d,0xc0,0x91,0xdb,0x7b,0x25,0x43,0x96,0xba,0x69,0xe1,0xad,0x45,0xdd,0xce,0xd0,0xce,0x37,0xe0,0xec,0x0,0x33,0xf4,0x50,0x4a,0xa3,0xeb,0xf6,0xd6,0xab,0xf3,0x4,0x15,0x69,0x28,0x5d,0x8d,0x65,0xc,0xd1,0xe1,0xc3,0xf,0xbe,0xf7,0x0,0x94,0xb9,0xf8,0xfa,0x25,0x7c,0xe5,0xb1,0x67,0x39,0x2b,0x8e,0xec,0xb9,0xd6,0xc,0xe8,0x97,0xb,0x52,0x21,0x76,0xb,0x64,0x2f,0xf1,0xca,0x47,0x28,0xb4,0xf3,0x4d,0xd4,0x4d,0x43,0xa0,0xd1,0xc,0x30,0xfd,0x92,0xe0,0x99,0x73,0xd4,0x78,0x7b,0x48,0x13,0x6c,0xc,0x23,0x24,0x4b,0x40,0xc7,0x7b,0x7,0x67,0xd,0x2d,0x33,0xb7,0x1c,0xf7,0xdd,0x82,0xad,0xb8,0x2e,0xab,0xb,0xdb,0xd9,0x26,0x1e,0xb8,0xef,0xe,0xdc,0x74,0x66,0x35,0xcb,0x2f,0xc6,0x88,0x3f,0xff,0xf2,0x37,0xf0,0xc6,0xe5,0xab,0x4,0xc,0xed,0x0,0xa9,0x14,0xfa,0xe5,0x1e,0x6f,0x6b,0x71,0x88,0x2,0x4c,0xac,0x6c,0x43,0xe7,0x2c,0x62,0x8,0x39,0xa3,0xee,0xf5,0x37,0xaf,0xe0,0xe2,0x1b,0x6f,0x1e,0x78,0x55,0x5d,0x69,0x7c,0xfa,0xa3,0x1f,0x40,0x5d,0xd7,0x39,0x7b,0xe,0x0,0xa9,0xcf,0x0,0x54,0x75,0x3,0x29,0x35,0x5c,0xce,0x69,0x14,0x79,0xdd,0xdb,0xf9,0x6,0x94,0xd6,0x68,0xe7,0x1b,0xb0,0x66,0xa0,0x63,0xd8,0x3b,0x52,0x6c,0xba,0xf5,0xf9,0x7f,0x82,0x8b,0x6f,0x66,0xf3,0x4d,0xb2,0xba,0x4e,0xa0,0x6b,0xb2,0x10,0x2b,0xad,0xd1,0x6e,0x6c,0xa2,0x65,0xa8,0xa8,0xab,0x1a,0x4f,0x3e,0xf3,0xe2,0xda,0xf5,0xfe,0xf0,0x7,0xde,0x8d,0xed,0x79,0x8d,0xbe,0x5f,0xc2,0x9a,0x1e,0xc1,0xfb,0xac,0x74,0x75,0xd6,0xc0,0xe,0x1d,0x9c,0x19,0xa0,0xb5,0x46,0x33,0xdb,0x80,0xaa,0x2a,0x8,0x45,0xe7,0x1d,0x1,0xd3,0xa,0xde,0xe,0xa8,0x59,0x39,0x4b,0x10,0xd2,0xe4,0xdc,0x4b,0x2,0xc0,0x6b,0xfd,0xe9,0x79,0xfb,0xe,0x7d,0x87,0x10,0x2,0x86,0x7e,0x89,0xa1,0xef,0xd0,0xce,0xe6,0x18,0xfa,0x8e,0xdf,0x27,0xa2,0xaa,0x6b,0x6a,0x16,0xf6,0xe,0xdb,0xc7,0x6e,0x80,0x54,0xa,0xcd,0x6c,0x3,0x75,0x3b,0x43,0xdd,0xce,0x10,0x3c,0x5d,0x33,0x9a,0x76,0x46,0xcd,0xc2,0xac,0xf0,0xcc,0xaa,0x4a,0xa9,0x18,0x88,0x4e,0x4e,0xb0,0x32,0x65,0xca,0x94,0x29,0x53,0xa6,0xcc,0x3b,0x32,0x5,0x0,0x96,0x29,0x53,0xa6,0x4c,0x99,0x32,0x65,0xde,0xd6,0x8,0x41,0xa,0x3f,0x42,0x23,0xa4,0xac,0x13,0x29,0xf7,0x2b,0x59,0x80,0x27,0xd6,0x3d,0x29,0x24,0xa9,0xce,0x2,0xb5,0xa7,0x3a,0x67,0xb3,0x52,0x2c,0xb2,0xd5,0xd3,0x31,0xac,0x7b,0xe1,0xd5,0xd7,0xf0,0x27,0x5f,0xf8,0x2b,0x38,0xb7,0x1e,0x40,0xcd,0xe7,0x33,0xfc,0x8b,0x7f,0xfa,0x6b,0xf8,0x2f,0x7f,0xf7,0x37,0x70,0xd3,0xc9,0x63,0x8,0x9e,0x6c,0x88,0xd9,0x62,0x29,0x25,0x59,0x35,0xad,0x45,0x55,0x35,0xd9,0x6a,0xab,0x34,0xd9,0x81,0xeb,0xa6,0x85,0x90,0x2,0x75,0x33,0x23,0x85,0xa0,0xd6,0xd8,0xde,0xdc,0xc0,0xc7,0x1f,0x3a,0x8f,0x7f,0xfd,0x7b,0xbf,0x8e,0xdf,0xf8,0xd4,0xa3,0x38,0x7e,0xec,0x48,0x2e,0x1f,0x10,0xd9,0x56,0x1c,0xe0,0xbc,0x85,0x1d,0xfa,0x43,0xcb,0x8,0x2,0xaf,0xaf,0x52,0x9a,0xd5,0x52,0x9e,0x5a,0x56,0x85,0x44,0xbf,0x5c,0x0,0x9c,0xb9,0xe6,0x83,0x43,0xf4,0xe1,0xd0,0x36,0x61,0xa9,0xc8,0xb6,0xa9,0xb4,0x86,0x52,0xa,0x5b,0xb3,0x6,0x27,0x4f,0x1c,0x3b,0xf0,0x7b,0x17,0x5e,0xbf,0x6,0x63,0x53,0x43,0x30,0x81,0xb4,0xba,0x9d,0x41,0x4a,0xb2,0x18,0x37,0xf3,0x8d,0x75,0xfc,0x2f,0xdb,0x76,0x53,0xfe,0x9b,0xe0,0x16,0x58,0x29,0x15,0x97,0x75,0xc8,0x43,0x1,0x60,0x82,0x6e,0x82,0xa1,0x9c,0x19,0xfa,0xc,0xff,0xf6,0xae,0x5f,0xc5,0xf5,0xab,0x6f,0x66,0x25,0x5d,0x8c,0xa4,0xe2,0x23,0x90,0x49,0x0,0xe7,0xce,0x5b,0x6f,0x82,0x94,0xab,0xb,0x65,0xad,0xc3,0x33,0xcf,0xbf,0x9c,0x8f,0xf,0x21,0x24,0x86,0x6e,0x49,0xd9,0x70,0x5a,0xa3,0x66,0x95,0xde,0x9a,0x45,0x21,0x20,0xcb,0x76,0x5e,0xa5,0x74,0x5e,0x9e,0xa1,0x27,0x6b,0xeb,0xdf,0x3c,0xf5,0xdc,0xda,0xb5,0x38,0x7f,0xcf,0xed,0xf8,0xe8,0x3,0x77,0x42,0x4a,0x91,0x81,0x55,0xf0,0x64,0xf5,0xd,0xde,0xb3,0x92,0xb4,0x86,0x64,0x85,0xa1,0x64,0x70,0x96,0xb2,0xea,0xea,0x66,0x86,0xa6,0x9d,0x67,0xfb,0x74,0xca,0x3e,0x3c,0xec,0xb8,0x3d,0x7e,0x6c,0x7b,0xdc,0xbf,0x42,0x72,0x2b,0x36,0x65,0x4a,0x56,0x29,0x3,0x2f,0xa6,0xfd,0xaf,0x20,0x95,0xc2,0xf3,0x3f,0xb9,0x8c,0xd7,0x2f,0x5d,0x3e,0xf0,0x5e,0x5b,0x9b,0x73,0xfc,0xf3,0x5f,0xfd,0x28,0xda,0x9a,0xd5,0xa5,0x66,0xa0,0x76,0x61,0x33,0x0,0x10,0x68,0x67,0x9b,0x5c,0x9c,0x41,0x25,0x29,0xc9,0x4e,0x1b,0xf8,0xfc,0x3c,0x71,0x64,0x13,0xbf,0xfb,0xd9,0x4f,0xe0,0xe1,0x7,0xee,0x86,0x77,0x2e,0xaf,0x5f,0x64,0x20,0x29,0xd2,0x1,0xb5,0x66,0x14,0x5b,0xdc,0xeb,0xa6,0x25,0xb0,0x1e,0x91,0x95,0x97,0xa6,0xef,0x60,0x86,0x1e,0x31,0x44,0x56,0x4a,0x4a,0xb6,0xd3,0x7b,0xd4,0xcd,0x3c,0xc3,0xcf,0x18,0x2,0x66,0xf3,0x4d,0x34,0xb3,0xd,0xce,0x84,0x24,0xd5,0x64,0x8,0x1,0xde,0x93,0x6a,0x30,0x95,0xcb,0xa4,0x87,0x3,0xc5,0x2,0x5c,0xa6,0x4c,0x99,0x32,0x65,0xca,0xbc,0x73,0x53,0x32,0x0,0xcb,0x94,0x29,0x53,0xa6,0x4c,0x99,0x32,0x6f,0x6b,0x3c,0xab,0x75,0x52,0xce,0x5f,0x32,0xd4,0xa,0x46,0x82,0x21,0x78,0x28,0xbe,0xf1,0x17,0x42,0x64,0x85,0x5a,0x52,0xfe,0x69,0x6,0x29,0x94,0x7b,0x16,0x0,0x50,0x99,0x41,0x10,0x1,0x4a,0x48,0xfc,0xe5,0x5f,0xff,0x0,0xa7,0x8e,0x6f,0xe3,0xd1,0x47,0x3e,0x8,0xb5,0x6,0x92,0x55,0x5a,0xe3,0x83,0xef,0x7f,0x1f,0xee,0xbb,0xfb,0x4e,0x7c,0xef,0xa9,0x1f,0xe2,0x6b,0xdf,0x7e,0x12,0x2f,0xbf,0x7e,0x15,0x50,0x8a,0xd4,0x44,0x21,0xa0,0x6a,0xc8,0xe,0xa9,0x44,0x45,0xad,0xb4,0xd1,0x41,0x4a,0xca,0x21,0x94,0x52,0x43,0x4b,0xe0,0xde,0x73,0x37,0xe2,0x83,0xef,0xbb,0x7,0xf7,0xdc,0x79,0x1b,0x8e,0x1c,0xd9,0x5a,0xfd,0x10,0x6,0x95,0x0,0x1,0xe,0x30,0x60,0x54,0x95,0x3e,0x44,0x1d,0x5,0xb6,0xad,0x4a,0xf4,0xdd,0x2,0x4a,0x57,0xe8,0xbb,0x5,0x62,0x8c,0xe8,0x97,0x7b,0x59,0xd1,0x97,0x0,0xe5,0x6c,0x63,0x73,0x9f,0xc2,0x69,0x84,0x43,0x4d,0x3b,0x47,0xf0,0x1e,0x7b,0x3b,0x57,0xa1,0xab,0x1a,0x5b,0xf3,0x16,0x4a,0xab,0x83,0xdb,0xa1,0x26,0x9b,0x73,0xc,0x3e,0xc3,0x23,0x3b,0xc,0x0,0x80,0x76,0xb6,0x41,0xb6,0xca,0x43,0x96,0xb5,0x6e,0x67,0x94,0x8d,0x58,0x37,0x80,0x19,0x20,0x44,0x93,0xb3,0xfc,0xe,0xcb,0x27,0xa4,0x8d,0x1,0x8,0x29,0x10,0x2c,0x59,0x88,0xe7,0x9b,0xdb,0x64,0x99,0x1d,0x6,0x34,0xed,0x8c,0xb3,0x0,0x13,0xc,0x96,0xac,0xec,0x22,0xcb,0xb7,0xf7,0x16,0x37,0xac,0x1,0x99,0x40,0x84,0xae,0x5b,0x88,0x6e,0xc1,0xd6,0x67,0x9b,0x21,0x58,0x2,0xc6,0x62,0x7d,0x60,0x22,0x65,0x39,0xea,0xa,0xce,0x1,0x51,0x85,0xfc,0x7e,0x88,0x11,0xa6,0xef,0xf0,0xb5,0xef,0x3c,0x89,0x8f,0xfd,0xe2,0x3,0x38,0x7e,0xec,0xe8,0xca,0x4b,0x95,0x52,0xf8,0x95,0x8f,0x3d,0x84,0x8d,0x59,0x8d,0x3f,0xfd,0xda,0x13,0xb8,0xbe,0xb7,0x43,0x9b,0x30,0xd0,0x6b,0xb5,0xd6,0xf9,0x18,0x48,0x99,0x8c,0x31,0x4,0x1c,0xdd,0xde,0xc4,0xbd,0x77,0xdc,0x8c,0xc7,0x9f,0x79,0x9,0x36,0x59,0x88,0x59,0x21,0x1a,0x62,0xc0,0xf5,0x45,0xcf,0xed,0xd7,0xab,0xfb,0xeb,0xde,0x3b,0x6f,0xc1,0x97,0xbf,0xfd,0x34,0xcc,0xa4,0x9c,0xa6,0x1f,0x48,0x25,0xe9,0xac,0x41,0x33,0x9b,0xe3,0xc4,0xf6,0x6,0x66,0xb3,0x39,0x5e,0x7d,0xed,0x12,0x66,0x9b,0xdb,0x70,0x21,0xe2,0xaf,0xbe,0xfb,0x34,0x3e,0xfb,0x8f,0x1e,0x3d,0xb0,0xfe,0x77,0x9c,0xbb,0x11,0xbf,0xf7,0x1b,0x8f,0xe2,0xf,0x3e,0xf7,0x65,0xbc,0x79,0xdd,0x70,0x21,0x8a,0xc3,0x60,0x6,0xcc,0xe6,0x9b,0xa8,0x9a,0x86,0xce,0xb7,0x48,0xe5,0x36,0x31,0x6,0x9c,0xbe,0xe1,0x38,0x1e,0x79,0xff,0xdd,0x78,0xe4,0xa1,0xf7,0xe3,0xc8,0xf6,0x26,0x5e,0xb9,0x78,0x89,0x40,0xbe,0x90,0x70,0xde,0xb2,0x45,0xb8,0x3a,0x14,0x4c,0x23,0x46,0xb6,0x30,0x93,0x15,0xda,0x3b,0xb,0x63,0x86,0x5c,0xee,0x11,0x82,0x87,0x16,0x15,0xfd,0x6f,0x55,0x33,0x98,0x27,0x5b,0x7c,0x55,0xd7,0x18,0xfa,0x25,0x9a,0xa6,0x45,0xcd,0xb9,0x96,0xde,0xb9,0x6c,0xd7,0xa7,0xb7,0xf,0x7c,0xfe,0xfa,0xfc,0x77,0x82,0xef,0x18,0x15,0xc5,0x65,0xca,0x94,0x29,0x53,0xa6,0x4c,0x99,0x9f,0x7a,0xa,0x0,0x2c,0x53,0xa6,0xcc,0xcf,0x7c,0xda,0xcd,0x63,0xb8,0xf9,0xce,0xfb,0x70,0xea,0xa6,0x5b,0x51,0x37,0x2d,0xfd,0x47,0x7e,0x4,0xdd,0x58,0xa5,0x8c,0x25,0x8c,0x79,0x49,0xe9,0xe6,0x2f,0x86,0xa4,0x94,0x89,0x59,0x4d,0x20,0x72,0xde,0x15,0xdd,0x91,0xc6,0x18,0xf8,0x46,0x46,0xf0,0xfd,0x6e,0xcc,0xca,0x84,0x38,0x6d,0x10,0x4c,0x37,0xc3,0x7c,0x33,0x27,0xa4,0xe0,0x9b,0xa4,0xc0,0xea,0x21,0xb2,0xdf,0x9,0x39,0xbe,0x77,0xb2,0x30,0xa,0x29,0xb3,0xcd,0x31,0xa9,0x5b,0xc0,0xea,0xa0,0x64,0xad,0x4a,0xef,0x9f,0xfe,0x1c,0x62,0xc8,0x59,0x56,0x10,0xd3,0xf7,0x12,0x39,0x27,0x2d,0xdd,0x38,0xa,0x21,0x9,0x9f,0xf0,0x7b,0x86,0x49,0x6,0x97,0xd8,0x67,0x75,0xa3,0x55,0x17,0x2b,0xea,0x24,0xb0,0xfa,0x29,0xab,0xb0,0x18,0xb6,0xa4,0x2,0x6,0x81,0x31,0xe8,0x1e,0x7c,0x53,0x35,0xb6,0x9c,0x32,0xba,0x11,0x72,0xbc,0x71,0xe7,0xf7,0xa1,0x40,0xfc,0x98,0x55,0x45,0xd3,0x75,0xa7,0xfb,0xec,0xc0,0xad,0xae,0xa4,0xf4,0xca,0xaa,0x2f,0x56,0xb7,0xa4,0xd7,0x25,0x42,0x91,0x3e,0x23,0x6d,0x8f,0xf1,0xde,0x32,0x66,0xf5,0x4f,0xfa,0xc,0x7a,0xbd,0x1a,0x55,0x4c,0xfc,0xfb,0xe9,0xe7,0xe9,0xb3,0x72,0x19,0x1,0x37,0xd2,0xd2,0x7e,0x25,0x24,0x95,0x6e,0x24,0x79,0x23,0xf0,0xb6,0xe4,0x80,0xff,0xe5,0x2,0x7d,0xb7,0x87,0xab,0x97,0x5e,0xc3,0xd5,0x37,0xdf,0x40,0xb7,0xfb,0xe6,0x5a,0x28,0x53,0x66,0x1f,0x3,0xe2,0x7d,0x14,0x26,0xe7,0x59,0x3a,0x66,0xa8,0xe0,0x83,0xe1,0x1b,0x97,0x68,0x84,0x98,0x54,0x80,0x1e,0x4a,0x55,0xf0,0xc1,0x23,0x3a,0xca,0x12,0xc,0xde,0xb3,0x3a,0x2f,0x0,0xa0,0x73,0xdb,0xc6,0x88,0x3f,0xf9,0x8b,0xc7,0xe0,0xbc,0xc7,0xc7,0x3f,0xfa,0xe1,0x3,0x8a,0xb1,0x34,0x1b,0x1b,0x1b,0x78,0xf8,0x17,0x1e,0xc4,0x43,0xf,0xde,0x8f,0x2b,0x57,0xaf,0xe3,0x85,0x97,0x2f,0xe0,0xc2,0x6b,0x97,0xf0,0xda,0xe5,0x5d,0xec,0x75,0x6,0x5d,0xdf,0xc3,0x5a,0x8b,0xb6,0x69,0xd0,0x54,0x12,0xa7,0x6e,0x38,0x8e,0x53,0xc7,0xb7,0x71,0xfb,0x2d,0x67,0x70,0xe6,0xf4,0xd,0xd8,0xdc,0x98,0x1d,0x0,0x35,0x53,0x28,0x25,0xa4,0x82,0xed,0xa8,0x6c,0x81,0xf2,0x5,0x75,0x2e,0x7,0x59,0x37,0xa9,0xc8,0x1,0xe0,0x4c,0x38,0xe7,0xb0,0xb1,0x75,0x4,0x57,0xde,0xb8,0x80,0x8d,0xed,0x63,0xa4,0x74,0x72,0xd4,0xa4,0xba,0x2e,0x9b,0x2e,0x9f,0x7,0xfc,0x3e,0x1b,0x5b,0x47,0x29,0xcf,0x4d,0xae,0x87,0x8e,0x37,0x9f,0x3e,0x86,0x5a,0x4b,0x18,0x17,0x72,0x8e,0x62,0xd3,0xce,0xe0,0xbd,0x87,0xb5,0x3,0xee,0xba,0xe9,0xf8,0x81,0xac,0xbd,0x74,0x1,0x9,0xde,0xe5,0x82,0x11,0x29,0x80,0xc8,0x9b,0x58,0x69,0xcd,0x40,0xe7,0x90,0xe5,0xb,0x94,0xe9,0x97,0x40,0x8d,0x65,0xf8,0x17,0x82,0x83,0xb3,0xe,0x21,0x38,0x74,0x8b,0x5d,0xcc,0x36,0xb6,0x21,0xa5,0xcc,0xad,0xca,0x42,0x8,0xd4,0xed,0xc,0xd6,0x1d,0x3c,0xbf,0xea,0xba,0xc6,0x83,0xe7,0xef,0xc0,0xe7,0xbf,0xf9,0x7d,0xe8,0xaa,0x42,0xd3,0xce,0xd1,0xf7,0xb,0x52,0xae,0x41,0x40,0x6b,0x85,0xb3,0x67,0x4e,0xad,0x5d,0x8f,0x74,0xd,0xa4,0xc,0x42,0x83,0xaa,0xae,0x61,0x86,0x1e,0xd6,0x52,0x21,0xc8,0xf5,0xdd,0x3d,0xfc,0x87,0x2f,0xfe,0x15,0xfe,0xf9,0x67,0x3e,0x9d,0x6d,0xdf,0x19,0xa0,0x56,0x15,0x3e,0xf6,0xc8,0x7,0x71,0xf7,0x9d,0xe7,0xf0,0xcd,0xc7,0x9e,0xc2,0x63,0x4f,0xfc,0x10,0x17,0xde,0xbc,0x46,0x10,0x77,0xb9,0x80,0xae,0x6a,0x34,0x4d,0x83,0x63,0xdb,0x9b,0xb8,0xe3,0xe6,0xd3,0x78,0xe8,0xfd,0xef,0xc6,0xdd,0x77,0xdd,0x1,0x63,0x2d,0x7e,0xf8,0x3f,0xfc,0x5f,0x80,0xe8,0x46,0x8b,0x39,0xef,0x9f,0xab,0xbb,0x1d,0xfa,0x7e,0xc0,0xc6,0xbe,0xf2,0x8e,0x3b,0x6f,0xbb,0x5,0x1f,0xff,0xf0,0x7b,0xf0,0x85,0xaf,0x7f,0xf,0x83,0x31,0x68,0x66,0x1b,0xd0,0x55,0xd,0xef,0x3d,0x6e,0xbe,0xf1,0x6,0x3c,0xfa,0xd0,0x7b,0xf1,0xb,0x1f,0xbc,0x1f,0x7f,0xf1,0xf5,0xc7,0xf0,0xda,0x95,0x1d,0xb6,0xc7,0xce,0xf1,0xad,0xa7,0x7f,0x8c,0x87,0x1f,0x3c,0x8f,0x9b,0x6e,0x3c,0xb9,0x6f,0xd5,0x5,0xee,0xba,0xfd,0x66,0xfc,0xd7,0xbf,0xff,0x59,0x7c,0xf7,0xf1,0xef,0xe3,0x3b,0xdf,0x7b,0x6,0x2f,0x5f,0x34,0x0,0xef,0x53,0x82,0xbc,0x2d,0x8e,0xcd,0xe6,0xb8,0xe7,0xf6,0xb3,0x78,0xff,0x7b,0xee,0xc2,0xed,0xe7,0xce,0x62,0x6b,0x73,0x63,0x84,0xcd,0x52,0x65,0xf8,0x16,0x94,0x42,0x8c,0xd4,0xe6,0x6c,0xba,0xc5,0xda,0xc,0xc8,0x10,0x3,0xad,0xab,0x60,0x95,0x65,0xb7,0x84,0x14,0x82,0xad,0xe7,0x7d,0xce,0x2e,0xd4,0x75,0xc3,0xd7,0x6f,0xfa,0x1e,0xa8,0x2a,0x52,0x8,0x26,0xb0,0x9d,0x0,0x63,0xdd,0xce,0x72,0xc9,0xcb,0xca,0xf1,0x9d,0x4a,0x40,0xa6,0xd0,0x4f,0x16,0xb3,0x52,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0x0,0x60,0x99,0x32,0x65,0xfe,0x93,0x98,0x9b,0xee,0x38,0x8f,0x7b,0x1f,0xf8,0x45,0x34,0xb3,0x39,0xd9,0xbc,0x42,0x4c,0xdd,0x1,0xfb,0x6e,0xe8,0xf0,0xd3,0x45,0xfd,0x1c,0x78,0x7d,0x9c,0xfc,0xc3,0xea,0xcf,0x46,0xc5,0x12,0xf6,0xbd,0x68,0xfc,0x59,0x42,0x48,0xcc,0xc8,0x8,0x36,0x22,0xae,0xbe,0x2a,0xae,0xf9,0xfc,0x7d,0x6f,0x2b,0xc4,0x2a,0x7f,0x5c,0x5d,0x16,0x71,0xc8,0xdf,0xf7,0xff,0xdb,0xf4,0x67,0xf1,0xed,0x6e,0x80,0xc9,0xb2,0x1f,0xf2,0x96,0x23,0x2f,0x5d,0x59,0xce,0xc4,0xe7,0x46,0x4e,0x37,0xbe,0xf8,0xe0,0xfa,0xac,0xdb,0x7e,0x38,0x64,0x39,0x7f,0xda,0x9d,0xbc,0x7f,0xa5,0xde,0x62,0x93,0xee,0xfb,0xbd,0xb1,0xb8,0x82,0x7e,0xad,0x6d,0xe7,0xd8,0xa,0x27,0x70,0xe4,0xf8,0x69,0x9c,0x3a,0xbb,0x83,0xcb,0xaf,0xff,0x4,0x17,0x5e,0xfc,0x3e,0x1c,0xb7,0x7c,0x96,0x39,0x7c,0xfb,0x47,0x6,0xac,0x31,0x7a,0x2e,0xfa,0xa0,0x72,0x3,0x70,0xcb,0x67,0xca,0x4e,0x13,0x42,0x65,0x58,0xcb,0xad,0x20,0x4,0x13,0xbc,0xcf,0xfb,0x47,0xb1,0xda,0x2a,0xb2,0x4d,0x18,0xd1,0xa3,0xeb,0x5,0xfe,0xe8,0xb,0xdf,0x82,0xf3,0x1,0x1f,0xff,0xc8,0x43,0xa8,0xeb,0xea,0xf0,0xff,0x88,0xd1,0x1a,0xa7,0x4e,0x9e,0xc0,0xa9,0x93,0x27,0xf2,0x7e,0xf6,0xde,0xc3,0x87,0x90,0x1,0xa5,0x94,0x12,0x4a,0xc9,0xf5,0x4a,0xb2,0x43,0xd7,0xd3,0x73,0xe1,0x49,0xc8,0xf6,0x45,0x67,0xcd,0x21,0x90,0x38,0x12,0xe0,0x13,0x32,0x83,0x10,0xc4,0x88,0xbd,0xeb,0xa4,0xe2,0x33,0xfd,0x92,0x0,0x9b,0x52,0x10,0x42,0x42,0x73,0x2e,0xde,0xc1,0x77,0x19,0x8f,0x59,0xa9,0x14,0x16,0xbb,0xd7,0x70,0x15,0xe,0xcb,0x65,0x8f,0xfa,0xc8,0xea,0x36,0x38,0x71,0xec,0x8,0x7e,0xed,0xd1,0xf,0xe0,0x8f,0xbf,0xf4,0x5d,0x8,0xb6,0x1d,0x4b,0xa5,0xa0,0x25,0xf0,0x4b,0xf7,0xdf,0x87,0x5f,0xf9,0xd8,0x43,0x98,0xcd,0xda,0x83,0xdb,0x4b,0x69,0xd4,0xcd,0xc,0xde,0xe,0x78,0xf0,0xbe,0xdb,0x71,0xf6,0xd4,0x11,0xfc,0xe1,0x9f,0x7d,0x9d,0x94,0x76,0x52,0x66,0xf5,0xd8,0xba,0x91,0xac,0xb2,0x4c,0x65,0x10,0x29,0xeb,0xb0,0x5b,0xee,0xa2,0x99,0xcd,0x60,0x86,0x9e,0xad,0xd7,0xa9,0x8c,0x22,0x92,0x1a,0x91,0x21,0xe0,0xc5,0xd7,0xdf,0x5c,0xfb,0xbe,0x8f,0x3e,0xfc,0x20,0x5e,0x7a,0xed,0x2a,0x5e,0xb8,0x70,0x5,0x21,0x78,0x34,0xcd,0x1c,0xce,0x1a,0x9c,0x3c,0x32,0xc3,0x3f,0xfe,0xc4,0xc3,0x38,0x7f,0xcf,0xed,0x6b,0xae,0x24,0x2,0x4d,0x3b,0x83,0x90,0x12,0x37,0x6c,0x6f,0xe0,0xe3,0x9f,0xfa,0x45,0xfc,0xf9,0x57,0xbe,0x85,0x17,0x5e,0xd9,0x65,0xd8,0xe4,0xa0,0xab,0x6,0xdf,0x7c,0xe2,0x79,0xbc,0xf7,0xdd,0xcf,0xe3,0x7d,0xef,0x7e,0xd7,0x1a,0x86,0x28,0x70,0xf6,0xcc,0x69,0x7c,0xf6,0x57,0x4f,0xe3,0xd3,0xbf,0xfc,0x30,0x76,0xf7,0x3a,0xec,0x5c,0xbf,0x8e,0x7e,0xe8,0xd1,0x34,0x2d,0xb6,0x36,0x37,0xb0,0xb5,0xb9,0x81,0xf9,0x7c,0x96,0x1,0xe2,0x95,0xab,0xd7,0xe1,0xac,0x81,0xf7,0x1e,0xba,0xaa,0xe0,0xac,0xe1,0x7,0x2b,0xc0,0xa5,0xab,0xbb,0xb8,0xf0,0xfa,0x9b,0x78,0xd7,0x1d,0xe7,0xf6,0x1d,0xa3,0xa,0x9f,0xfe,0xe5,0x87,0xf1,0x9e,0x7b,0xef,0xc4,0xb3,0x3f,0x7a,0x11,0x7d,0xdf,0xe3,0xc8,0xf6,0x26,0xce,0xdd,0x7c,0x13,0x4e,0x9f,0xba,0x1,0x73,0xde,0x4f,0x42,0x90,0x5d,0x5a,0x57,0xd4,0x72,0xed,0x5c,0xc0,0x1f,0x7f,0xe1,0x9b,0xf8,0x97,0xbf,0xf5,0x49,0xb4,0x6d,0x73,0x60,0xf9,0xb7,0x36,0xe6,0xf8,0x7,0x8f,0x7c,0x10,0x8f,0x7c,0xe8,0x7e,0x2c,0xbb,0xe,0x7b,0x7b,0x4b,0x18,0x6b,0xa1,0xab,0xa,0xf3,0xb6,0xc1,0xc6,0xc6,0xc,0xb3,0xb6,0x5d,0xbb,0xcd,0x43,0x8,0x68,0xda,0x39,0xcc,0xd0,0x41,0x2a,0xd,0xef,0x2c,0xb4,0xd6,0x6c,0xdf,0x5d,0xc7,0x5b,0xa9,0x94,0x25,0x72,0x79,0x88,0xae,0x1b,0x2c,0x76,0xaf,0xb1,0x85,0x97,0x40,0xa8,0xae,0x6a,0x82,0xb6,0xfc,0xbf,0x52,0x4a,0x78,0x1f,0x72,0x31,0x4d,0x6a,0xd2,0x9e,0x6f,0x6e,0xc3,0x39,0xc7,0xf,0xd5,0x4,0x95,0xca,0xa4,0xf3,0x21,0xee,0xfb,0xe2,0x4,0x72,0x54,0x40,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0xa6,0x0,0xc0,0x32,0x65,0xca,0xfc,0x1c,0xcf,0xcd,0xef,0x7a,0x1f,0xce,0x3f,0xf8,0x11,0x84,0xe0,0x39,0x1f,0xc8,0x1f,0xe6,0x4a,0x3b,0x40,0x71,0x92,0xbd,0x30,0x5,0xe3,0xa7,0x3f,0xaf,0x90,0x39,0x8c,0x99,0x63,0xe9,0xe6,0x5e,0xf0,0xef,0xa7,0xbf,0x87,0xac,0x8a,0x63,0xa8,0x97,0x72,0xca,0x42,0x52,0xec,0x89,0x55,0x9a,0xc7,0xca,0xb7,0xf4,0xf6,0x49,0xb5,0x36,0x7d,0x4f,0x21,0x45,0x6e,0x2e,0xdc,0xbf,0xcc,0xd3,0x1b,0xfb,0xa4,0x80,0x4b,0x6a,0xb8,0x90,0x6f,0x64,0x56,0x41,0x58,0x56,0xc6,0xbd,0x15,0xdf,0xdc,0xaf,0x94,0x78,0x2b,0xa8,0x37,0x85,0x5e,0x13,0x95,0xcc,0x68,0xdb,0xc4,0x5a,0x0,0xb1,0xff,0x33,0xd6,0x7e,0xe6,0x21,0x30,0xef,0xad,0x7f,0xf7,0xef,0x4c,0x99,0xd8,0xfa,0x95,0xdf,0x3c,0xbf,0xb7,0x98,0x7e,0xbe,0xc0,0x7e,0x52,0x79,0x90,0x2b,0xb,0x0,0x51,0xe4,0xe6,0xd7,0xf1,0x6,0xd8,0xe7,0x30,0x7a,0x67,0xd,0x9c,0x73,0x68,0xb7,0x8e,0x63,0x79,0xed,0x12,0xc2,0x21,0xa,0xa8,0x32,0xc8,0x79,0x5c,0x42,0x0,0x91,0xad,0xb1,0x21,0x58,0x3a,0x6f,0x58,0x2d,0x2b,0x40,0x70,0x48,0xd4,0x6a,0x72,0x22,0x51,0x3b,0xac,0xaa,0xaa,0xac,0x9a,0x4d,0x10,0x9,0x42,0x40,0xb,0xcd,0xa,0xb8,0x8,0x68,0x82,0x4d,0xff,0xe1,0x6b,0x8f,0xe3,0xc2,0xeb,0x57,0xf0,0x99,0x4f,0x7f,0x94,0xb2,0xf9,0xde,0xc6,0x8,0x21,0xa0,0xb5,0xfe,0xa9,0xfe,0xe3,0xc6,0xfb,0x80,0x10,0x68,0x5d,0xbc,0xa3,0x96,0x54,0xa5,0xaa,0xdc,0x5e,0xbc,0xee,0x92,0xa5,0x94,0xc6,0x60,0xd9,0xc2,0x2a,0x15,0x65,0xfd,0x21,0x62,0xe8,0x97,0xa8,0xea,0x6,0x55,0xdd,0x42,0x2a,0x4d,0x45,0xc,0x87,0xc0,0x48,0xc9,0xb6,0x59,0x29,0x15,0x9c,0xb5,0x68,0xe7,0x9b,0xd8,0x5d,0xee,0xe1,0x85,0x1f,0xbf,0x8c,0xf,0xdc,0x7f,0xfe,0xc0,0x7a,0x3e,0xf4,0xc0,0x7d,0xb8,0xf5,0xe6,0x1b,0xf1,0xd4,0xf,0x9f,0xc7,0xb2,0x1b,0x70,0xfc,0xe8,0x16,0xee,0xbe,0xfd,0x66,0x9c,0xbc,0xe1,0xf8,0xa1,0xca,0xc9,0x9b,0xcf,0x9c,0xc4,0x6f,0x7d,0xe2,0x83,0x38,0x7d,0xf2,0x4,0xce,0xdd,0x7c,0x23,0x9e,0xfa,0xfe,0x73,0x18,0xfa,0x25,0xa8,0xb1,0x75,0xc9,0xd0,0xc6,0xad,0xdf,0xf7,0xce,0xc1,0x7b,0x97,0x5b,0x73,0x63,0x4c,0xe7,0x91,0x87,0xf1,0x4,0x87,0x44,0xd,0x6e,0x7d,0xd5,0x59,0xe5,0xa9,0xab,0x1a,0x5a,0xd7,0x78,0xea,0xb9,0x57,0xf0,0x2b,0xff,0x60,0x38,0x0,0xb3,0xb6,0x36,0x37,0xf0,0xfb,0xff,0xec,0x1f,0xe1,0x87,0xcf,0xfd,0x18,0x2f,0x5f,0xb8,0x4,0x21,0x22,0x6e,0x3d,0x7b,0xa,0x77,0xdd,0x7e,0xe,0xb3,0x35,0xe0,0x2b,0x1d,0x7f,0x9f,0xfc,0xa5,0x7,0x70,0xfe,0xae,0xb3,0xb8,0xef,0xee,0x3b,0xb0,0x31,0x6b,0xf1,0xe5,0xaf,0x3f,0x86,0xd9,0x7c,0x13,0xdd,0x62,0x97,0xc0,0x33,0x80,0x5e,0x4a,0xfc,0x1f,0x7f,0xfc,0x25,0xfc,0x17,0xb3,0x16,0x77,0xde,0x7e,0xcb,0xa1,0xfb,0x7c,0x3e,0x9b,0x61,0x3e,0x9b,0xe1,0xf4,0xc9,0xe3,0x6f,0x7d,0x65,0xe2,0x63,0xbc,0x66,0xfb,0xaf,0x8f,0x8e,0xb2,0xfc,0x6a,0x2,0xa7,0xff,0xf1,0x6b,0xdf,0xc5,0x1d,0xb7,0x9e,0x3d,0xa0,0x2e,0x55,0x52,0xe2,0xb6,0x5b,0xce,0xe0,0xb6,0x5b,0xce,0x1c,0x7e,0x6e,0xb1,0xf2,0xcf,0x7b,0x9b,0x95,0xdf,0xcf,0xfe,0xf8,0x2,0xfe,0xe4,0x8b,0xdf,0xc0,0x6f,0xfe,0xca,0x47,0xa0,0xf5,0x7a,0xc5,0x6a,0x5d,0x57,0xa8,0xeb,0xa,0x47,0x8f,0x6c,0xbf,0xed,0x63,0x5c,0x4a,0x99,0xb3,0x2e,0xa5,0x54,0xb0,0x81,0xb2,0x4,0x63,0xd4,0xeb,0x1f,0xb0,0xa4,0xf6,0x68,0xde,0xff,0x3,0x5b,0xdd,0x95,0xf7,0x20,0xc5,0xac,0xcc,0x2a,0xd4,0x9c,0xfb,0x19,0x23,0xc1,0xd8,0x54,0xee,0xa1,0x14,0xcc,0xd0,0x3,0x11,0x4,0xc1,0xb5,0x86,0x92,0xa,0x3e,0xf8,0x9c,0xaf,0x48,0xdb,0x38,0xe4,0x7,0x36,0xa4,0x30,0x56,0xe5,0xc2,0x5b,0xa6,0x4c,0x99,0x32,0x65,0xca,0x14,0x0,0x58,0xa6,0x4c,0x99,0x9f,0xf7,0x39,0x79,0xe6,0x1c,0xbc,0xb3,0x9c,0x11,0x14,0xc6,0xff,0xb0,0xe7,0xc6,0xd0,0x98,0xe4,0x67,0x99,0x28,0x44,0x4c,0x29,0x4f,0xb2,0xca,0x26,0xbd,0x5e,0x9c,0xfc,0xbb,0x20,0x3a,0xb7,0x2,0xb7,0xc0,0x10,0x4d,0xe9,0xa,0x21,0xc4,0x7c,0x33,0x91,0x80,0x43,0xba,0x11,0x49,0x39,0x57,0x52,0x2a,0x78,0xeb,0x32,0x18,0x9c,0xda,0x56,0xf3,0xd,0x7a,0xa4,0x96,0xc7,0x64,0x3f,0x4e,0x98,0x29,0x7d,0x3e,0xdd,0x1b,0x85,0x6c,0xfd,0x9d,0x2e,0x8f,0xe7,0x65,0x95,0x52,0xc1,0x1a,0x7b,0x40,0x20,0x37,0x82,0x41,0x9b,0x79,0x9a,0x98,0x42,0x47,0x8c,0x16,0xe0,0x55,0xc0,0x76,0x50,0xdd,0xb8,0xaa,0xd6,0x9b,0x0,0xb9,0x15,0x39,0x1f,0xb2,0xf5,0x78,0x5,0xb4,0x8a,0x9,0x10,0x4d,0x36,0x5f,0x88,0x95,0x9c,0xb7,0xe9,0x87,0x4c,0x3f,0x7d,0x3f,0x30,0x4,0x56,0xc5,0x77,0xe3,0x22,0xac,0x93,0x7c,0xf2,0xb6,0x9c,0x40,0xc9,0xbf,0x15,0x24,0x66,0x30,0x9b,0xf6,0xf9,0x78,0x84,0x4c,0x41,0xf0,0xca,0xd,0xfb,0x1a,0x30,0x98,0xc0,0x85,0x77,0x94,0x5f,0xb5,0xb7,0x73,0xd,0x43,0x3f,0x0,0x42,0x1,0x28,0x0,0xf0,0x50,0x70,0xc0,0x19,0x6f,0x69,0xdb,0x27,0xeb,0x75,0x2,0x47,0x82,0x15,0x42,0x92,0x5b,0x40,0xc9,0x8a,0x8f,0xac,0xa6,0x4b,0x30,0x3f,0xd9,0x1,0x93,0xb2,0x2a,0x78,0x7,0x21,0xa9,0x98,0x3,0x88,0x70,0xc6,0x20,0x6a,0x8d,0xbf,0x79,0xe6,0x25,0xbc,0xf0,0xd2,0x1f,0xe0,0x53,0x8f,0x3e,0x84,0xf,0x3e,0x70,0x1e,0xf3,0xf9,0xec,0x67,0xb6,0x6e,0x83,0x31,0x78,0xee,0xf9,0x97,0xf1,0x67,0x5f,0xf9,0x36,0xba,0x7e,0x60,0x98,0x49,0xc7,0x6a,0xc,0x1e,0x1,0x31,0x37,0x96,0xee,0xa7,0x51,0x11,0x91,0x60,0x66,0x24,0x35,0xa0,0xd6,0x15,0xbc,0x25,0xeb,0xa3,0x77,0xe,0x66,0xe8,0x50,0xb1,0x3d,0xda,0x1d,0x52,0xb2,0x31,0x16,0x70,0xd0,0xf5,0xc4,0xc,0x3,0x94,0xd2,0xf8,0xdc,0xe7,0xbf,0x86,0xfb,0xee,0xb9,0xf3,0x80,0x9a,0x4b,0x4a,0x81,0x33,0xa7,0x8e,0xe3,0xcc,0xa9,0x83,0xd0,0xca,0x39,0xc7,0x2d,0xc6,0xab,0xe7,0x83,0xd6,0xa,0x1f,0x7e,0xf0,0xbd,0x2b,0xd7,0xd,0x5d,0xd5,0xe8,0x97,0xb,0x54,0x75,0xd,0x44,0xda,0xc7,0xeb,0xc1,0x28,0x35,0xed,0xc6,0x48,0x85,0x11,0xf4,0x33,0x7,0x5d,0xd5,0x40,0x8c,0xe8,0x96,0x7b,0xa8,0x62,0x44,0xd3,0xcc,0x72,0x39,0x8b,0xaa,0x6a,0x7a,0x0,0x64,0x7a,0xbc,0xf2,0x86,0xc5,0xe3,0x4f,0x3f,0xbb,0xf2,0xf9,0x69,0x9a,0xba,0xc2,0xfd,0xe7,0xdf,0x85,0xfb,0xcf,0x1f,0x54,0xea,0x19,0x63,0xd7,0xaa,0x40,0x6f,0x39,0x7b,0x23,0x6e,0x39,0x7b,0x23,0x2f,0x87,0x87,0x0,0x60,0x6,0x2a,0xc3,0x88,0x9,0x58,0x6a,0x87,0xbd,0x65,0x87,0xff,0xf9,0xf,0xbf,0x80,0xdf,0xf9,0xd5,0x8f,0xe0,0xfc,0xbd,0x77,0x1d,0xa,0x47,0xdf,0xee,0x8,0x8,0x38,0x67,0xf8,0xd8,0xa5,0xd6,0x5a,0x3b,0xf4,0xd0,0xba,0xc6,0xf7,0x5f,0xbc,0x88,0xbf,0x7e,0xe2,0x87,0xf8,0xd0,0xfb,0xcf,0xff,0xbd,0xde,0xbb,0x5f,0xee,0x41,0xa9,0x8a,0x94,0xa7,0x15,0x65,0xf2,0x7d,0xe3,0xc9,0x17,0x11,0x43,0xc4,0xaf,0x7e,0xfc,0x17,0xb3,0x5a,0xf0,0xa7,0x99,0x4b,0x6f,0x5e,0xc1,0x8f,0x5e,0x78,0x9,0xdd,0x62,0x37,0x67,0xfb,0xe9,0xaa,0x82,0xe3,0xc6,0xee,0x75,0x99,0x7b,0xf9,0x94,0xc,0xa7,0x21,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xfb,0x2d,0x84,0x6c,0x1f,0xef,0xbb,0x5,0xcc,0xd0,0x51,0xe,0xa3,0xb5,0xd8,0xd8,0x3a,0x92,0x23,0x20,0x92,0xbd,0xd8,0xc,0x3d,0xea,0xb6,0xa5,0x92,0xf,0x2e,0x1d,0x49,0xa0,0x3f,0x95,0x7d,0x28,0x31,0x1e,0xff,0x39,0xee,0xc3,0x5b,0x16,0xd,0xc7,0xbf,0xf5,0xe1,0x58,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0xa6,0x0,0xc0,0x32,0x65,0xca,0xfc,0x1c,0x4c,0xdd,0xb4,0x39,0xc8,0x3b,0x5b,0x7,0x23,0x26,0xff,0x41,0x3f,0xb1,0x96,0x82,0xb3,0xa8,0xe2,0x8,0x5,0x63,0xba,0x43,0xcd,0xd6,0x38,0x31,0xc2,0x24,0x81,0xc,0xe5,0x98,0xc2,0xe5,0x2c,0xb2,0x10,0x42,0xce,0xe1,0xd3,0x9a,0xda,0x12,0x11,0x29,0xa4,0x3f,0xfd,0x1c,0x51,0xc0,0x7,0x47,0x37,0x20,0xc,0x7,0xd3,0x32,0xe6,0x9b,0x8e,0x9c,0x91,0x37,0xde,0x14,0x65,0xd1,0x99,0x1a,0xdb,0x32,0x23,0x22,0x22,0xb7,0x5f,0x26,0xe8,0x94,0xf2,0x7,0x63,0x8,0xf0,0xc1,0xf2,0x9f,0x63,0x86,0xa,0x1,0x1,0x29,0x87,0x8f,0xf2,0x7,0xe9,0xa6,0x3f,0x86,0x74,0xc3,0x33,0x81,0x6f,0x19,0xa0,0x8d,0x8a,0xc8,0x11,0xcc,0xad,0x1,0x75,0x40,0x86,0x9d,0xbc,0x11,0xf3,0x6b,0x4,0xd6,0x6c,0xff,0x38,0x2,0xba,0x18,0xd3,0x36,0xe,0x18,0x73,0xf4,0x12,0xf4,0x9c,0xfc,0x59,0xc8,0x6c,0x5,0x9d,0xc2,0xb6,0xe9,0x6d,0x72,0x5a,0xae,0xbc,0x2c,0x53,0x28,0x27,0xa6,0x0,0x34,0xec,0xfb,0x37,0x71,0xe0,0xef,0x59,0x1,0x28,0xc6,0xec,0xc6,0x55,0x2e,0x18,0xd7,0x2c,0xc3,0x2a,0x2e,0x9d,0xbc,0xe9,0xea,0xf,0x63,0xc4,0xd0,0x2f,0x10,0x9c,0x83,0xac,0x37,0x10,0x5c,0xb1,0x1,0x1f,0xa,0x3f,0xf8,0x3c,0xdc,0xff,0x33,0xcf,0xca,0x35,0x52,0xf5,0x39,0xc8,0x8a,0xce,0x3b,0xa9,0xc8,0xe2,0x3b,0x36,0xcb,0x92,0x45,0x37,0xc6,0x8,0x9,0x95,0xc1,0x1f,0x14,0x20,0x82,0x47,0x8,0xe,0x51,0x53,0x89,0x80,0x35,0x3,0x84,0x10,0xb8,0x6c,0x15,0xfe,0xb7,0xff,0xe7,0xcf,0xf0,0x85,0xaf,0x7c,0x13,0xff,0xd9,0xc7,0x1f,0xc1,0xf9,0xfb,0xee,0x5e,0xc9,0x33,0xfb,0x69,0xc6,0x7b,0x8f,0xeb,0x3b,0x7b,0xf8,0xde,0xd3,0xcf,0xe0,0x9b,0xdf,0x7b,0xe,0xaf,0xbe,0x71,0x95,0x6d,0xbe,0x74,0x1e,0x4a,0x21,0xb9,0x88,0x42,0x42,0x84,0x70,0xa8,0x81,0xdd,0xf4,0x1d,0xa9,0xce,0x84,0x84,0x90,0x16,0xc3,0x72,0xf,0x21,0x78,0x2c,0xf7,0x76,0xa0,0xab,0x9a,0x14,0x62,0x0,0x15,0x6d,0x4,0xbf,0xb6,0xa0,0x23,0x4,0x37,0xa,0x9c,0x83,0x47,0x55,0x37,0x30,0x7d,0x87,0x17,0x2f,0x5c,0xc2,0x1f,0x7d,0xee,0xf3,0xf8,0xa7,0xbf,0xf9,0x69,0x54,0x55,0xf5,0xb7,0xae,0xd3,0xe5,0xab,0xd7,0xf1,0xa7,0x5f,0xfc,0x6,0x1e,0xfe,0xe0,0x7b,0x70,0xd7,0x6d,0x37,0x1f,0xfa,0x7b,0xce,0x39,0xbc,0xf4,0xea,0x45,0x6e,0x37,0xe,0xe8,0x97,0x3,0x5f,0x23,0xd7,0x3,0x97,0xa4,0xaa,0xf3,0x8e,0x9a,0x60,0x17,0xbb,0x3b,0x10,0xac,0x1c,0xf4,0x9e,0xb6,0x91,0x14,0x72,0x5,0xfe,0x7a,0x6e,0x16,0x96,0x52,0x21,0x86,0x88,0x7f,0xfb,0xff,0x7d,0x5,0x37,0x1c,0x3b,0x82,0xbb,0xf6,0xd9,0x64,0xd7,0x2f,0x9f,0xc7,0xf,0x9e,0xfb,0x31,0xfe,0xfa,0xa9,0xe7,0xf0,0x3b,0x9f,0xf9,0x4,0xb4,0x3a,0x5c,0x9,0x76,0xe9,0xf2,0x15,0xec,0x2e,0x96,0x8,0xde,0x11,0x88,0x5,0x50,0x35,0x6d,0x7e,0xf0,0xb4,0xbb,0xb7,0xc4,0xff,0xf2,0x87,0x9f,0xc7,0xc7,0x1e,0xba,0x80,0x7f,0xf8,0xc8,0x83,0x38,0xb2,0xbd,0xf9,0xf7,0x3a,0x5e,0x42,0x88,0xb9,0xad,0x36,0xad,0x97,0xe7,0x63,0xd8,0x7b,0x7,0xa9,0x14,0xfe,0xed,0x9f,0x7e,0xd,0x95,0x56,0xb8,0xff,0x3d,0xf7,0xbc,0x6d,0xdb,0xb9,0xf7,0x1e,0xbd,0xb1,0xf0,0xde,0xa3,0xaa,0x5b,0xc4,0x28,0xc8,0x6,0x6c,0xc,0x94,0xd6,0xf8,0xab,0xc7,0x9f,0xc5,0xe5,0xab,0xd7,0xf1,0xeb,0x9f,0x78,0x18,0x37,0xdd,0x78,0xf2,0xef,0x66,0x67,0xe7,0x4b,0xde,0xde,0xde,0x1e,0xbe,0xf1,0x9d,0xbf,0xc1,0xff,0xfb,0xe7,0x5f,0xc5,0xc2,0xc4,0x6c,0x67,0xb7,0xc6,0x50,0x46,0xac,0x94,0x39,0x97,0xf7,0xc0,0xeb,0x43,0xc8,0xca,0xd0,0x54,0xfc,0xa1,0xd4,0xd8,0x90,0x5c,0x4d,0x72,0xfa,0x48,0x39,0xeb,0x72,0xd3,0x36,0xe5,0x86,0x2,0x11,0x94,0x8b,0x9b,0xd4,0x80,0x49,0x39,0x18,0x5d,0xe0,0x4b,0xca,0xe4,0xa1,0xdd,0xe4,0xda,0x52,0x2a,0x40,0xca,0x94,0x29,0x53,0xa6,0x4c,0x99,0x2,0x0,0xcb,0x94,0x29,0xf3,0x9f,0xc0,0xc4,0xa9,0x14,0x8c,0xc1,0xd,0x41,0xae,0x90,0x41,0x42,0xe4,0x96,0x48,0x82,0x40,0x22,0x5b,0x70,0x57,0x0,0x10,0xbf,0x26,0xbf,0x7,0xc3,0x25,0xc9,0x21,0xe2,0x60,0x55,0x61,0x4,0xff,0x8c,0x3f,0x4f,0x44,0xc1,0xc1,0xfd,0xa9,0x5d,0x90,0x20,0x16,0xa9,0x91,0xe2,0xa4,0x48,0x83,0x6f,0x34,0xb8,0x7c,0x24,0xab,0x4,0xa5,0xe2,0xf7,0x16,0xd9,0xa6,0xb4,0x6a,0xe7,0x4d,0x6a,0x46,0x0,0xe9,0x63,0x31,0x2a,0xd3,0x48,0xfd,0x27,0x57,0x95,0x8e,0xfb,0xb6,0x49,0x44,0x84,0x88,0x62,0x9f,0x8d,0x75,0x5c,0x8f,0x4,0xfe,0xa6,0xd,0x89,0x7,0x1,0xc,0x56,0x60,0xdc,0x98,0xd1,0x16,0x21,0xa5,0xd8,0x97,0xd7,0x27,0x56,0x80,0xe3,0x34,0xd3,0x6d,0x2c,0xe0,0xc0,0xc4,0xa,0x1d,0xc6,0xf,0x99,0xe0,0xb4,0xd4,0xf2,0xba,0xe,0xe,0x25,0xf5,0xe2,0x14,0x44,0xee,0x57,0x57,0xc6,0x49,0xa9,0xc7,0x8a,0x3d,0x39,0xae,0xc2,0xc4,0xfd,0xa,0xc8,0xc3,0x2c,0xca,0x6f,0xa5,0x1c,0x1c,0x95,0xa4,0x38,0xa0,0x32,0x4d,0xe8,0x50,0xe9,0x86,0x54,0x67,0x6e,0x28,0x27,0xee,0x5b,0x2,0x40,0xb9,0x4f,0x25,0x1a,0x0,0xc8,0xc,0x84,0xc7,0xd2,0x1c,0x3a,0x56,0xbd,0x23,0x75,0x91,0x35,0x3,0x17,0x0,0x5,0x48,0x3e,0xd6,0xd3,0xef,0x28,0x2e,0xd9,0x91,0x4a,0x41,0x49,0xc5,0xb9,0x62,0x74,0xad,0xa8,0xaa,0x86,0xd5,0x5d,0x2,0x2f,0xbd,0x76,0x19,0xff,0xdd,0xff,0xfa,0xef,0x70,0x7c,0xab,0xc5,0x87,0xee,0xbf,0xf,0x1f,0xfe,0xe0,0x3,0x38,0x7d,0xea,0x24,0xb6,0xb6,0xb6,0x50,0x55,0x6f,0xef,0x3f,0x67,0x7c,0x8,0x18,0x7a,0x83,0xeb,0xbb,0x7b,0xf8,0xd1,0x8b,0xaf,0xe2,0x6f,0x9e,0x7e,0x16,0x2f,0x5e,0xb8,0x82,0xae,0xef,0x20,0xa4,0xca,0x6a,0x51,0xef,0x3,0x9d,0x3b,0x72,0xcc,0xbe,0xf4,0xde,0xc1,0x39,0x7,0xc3,0x25,0x1e,0xe9,0x1a,0x64,0xcc,0x0,0xad,0x2b,0xc,0xd6,0xc2,0x3b,0x9b,0xe1,0x97,0x35,0x3,0x74,0x55,0xc3,0x31,0xc8,0xec,0xbb,0x5,0x66,0x1b,0x5b,0xf4,0x1a,0x6b,0xf3,0xfb,0xa4,0x43,0xd3,0x39,0x8a,0x4a,0x68,0xda,0x19,0x9c,0x25,0x18,0x94,0x72,0xd7,0xfe,0xe4,0x4b,0xdf,0xc0,0xde,0xde,0x2e,0x3e,0xf3,0xeb,0x9f,0xc2,0xd,0x37,0x9c,0x38,0x0,0x45,0x42,0x8c,0xb8,0x7e,0x7d,0x17,0x8f,0x3d,0xf9,0xc,0xbe,0xf5,0xc4,0xb,0x78,0xe3,0xea,0x75,0x5c,0xba,0xba,0x8b,0xdf,0xfb,0x27,0x9f,0x3c,0x60,0x9f,0xf6,0x21,0xe0,0x95,0x57,0x2f,0xe2,0x8f,0xff,0xfd,0x97,0xf1,0xf8,0x33,0x2f,0x72,0xc9,0x89,0x82,0x6,0x29,0xb6,0xcc,0x30,0xc0,0x18,0xb3,0x6a,0x5,0xe5,0x56,0xdc,0xe0,0x1d,0x3d,0x64,0x71,0xe,0x75,0xd3,0xa0,0xef,0x68,0x5d,0x9d,0xb5,0xa8,0xdb,0x19,0xe7,0xbc,0x6,0x44,0xde,0x8f,0x4a,0x69,0x28,0xad,0x19,0x10,0x4b,0x18,0x1f,0xf1,0x3f,0xfe,0xc1,0x9f,0xe0,0x77,0xfe,0xf1,0xc7,0x71,0xfe,0x9e,0xdb,0xd1,0x34,0xf5,0x1,0x50,0x35,0x98,0x1,0x3f,0xb9,0xf0,0x3a,0xbe,0xf4,0xf5,0xc7,0xf1,0xe4,0xf3,0x17,0x20,0x4,0x70,0xe7,0x77,0x9f,0xc0,0x2f,0x7c,0xe0,0xbd,0x7,0xf6,0xf3,0xde,0x62,0x89,0x6f,0x3d,0xf6,0x4,0x3e,0xf7,0xf9,0xbf,0xc4,0x1b,0x97,0xaf,0xc0,0x59,0x4b,0x2a,0xb3,0x10,0x60,0x87,0x1e,0x4a,0x6b,0x38,0x4b,0xc0,0xce,0xb9,0x88,0xff,0xf8,0xcd,0x27,0xf1,0xed,0x27,0x9e,0xc5,0x23,0xef,0xbf,0x7,0xf,0xbe,0xef,0x5e,0x1c,0x3f,0x7e,0x74,0x7d,0x59,0xca,0xe4,0xfb,0xc7,0x5a,0x8b,0x2b,0xd7,0x76,0xf0,0xe3,0x97,0x7f,0x82,0xaf,0x7e,0xfb,0x49,0xf8,0x10,0xe1,0xec,0x0,0xef,0x4,0x74,0xd5,0x50,0xfe,0x22,0xc7,0x16,0x28,0x5d,0xa1,0xb7,0xe,0xff,0xfb,0x1f,0x7d,0x9,0x8f,0xbc,0xf0,0x32,0x1e,0x7d,0xf8,0x41,0xdc,0x70,0xfc,0xe8,0xda,0xc2,0x99,0x10,0x2,0x96,0xcb,0x25,0x7e,0xf4,0xc2,0x4b,0xf8,0xea,0xb7,0x9e,0xc0,0x53,0xcf,0xbf,0xa,0xa5,0x74,0x86,0xe9,0xb9,0x54,0x89,0xb7,0xfd,0x33,0x2f,0x5f,0xc2,0x7f,0xff,0x6f,0xfe,0x14,0x1f,0x7e,0xef,0x1d,0x78,0xf0,0xfe,0x7b,0x71,0xe6,0xd4,0xd,0x87,0xda,0x82,0xd3,0x74,0xfd,0x80,0x37,0xde,0xb8,0x84,0xc7,0x1e,0x7f,0x1a,0x5f,0xfd,0xce,0x93,0x78,0xe3,0xf2,0x55,0x82,0xb9,0x4a,0x93,0xe5,0x5b,0x29,0x6,0xa6,0x2,0xd6,0x3b,0x88,0x63,0x5b,0x30,0xc6,0xd2,0xf2,0x8a,0x31,0x1e,0x63,0x5a,0x5c,0x23,0x39,0x73,0x32,0x78,0xcf,0xca,0x3e,0xb,0x3d,0xdb,0x40,0xf0,0x1e,0xb2,0x55,0xb0,0xd6,0xa0,0x6d,0xe7,0xb4,0xfc,0xac,0x88,0x9d,0x5e,0xa7,0x53,0xfb,0x77,0x7a,0x40,0xa6,0x74,0x85,0x5c,0x4a,0x5,0xca,0x1b,0xc,0xde,0xe7,0xef,0xd9,0x77,0x2e,0x5a,0xa2,0x4c,0x99,0x32,0x65,0xca,0x94,0x29,0xf3,0xe,0x24,0xb2,0x97,0x29,0x53,0xa6,0xcc,0xfa,0xf9,0xd0,0x2f,0x7f,0x6,0xdb,0xc7,0x6e,0x80,0x77,0x8e,0x2c,0x74,0xa9,0xc,0x0,0x13,0x20,0xb5,0xf,0xe0,0xed,0xcf,0xe3,0x23,0x68,0xc8,0x10,0x28,0xc1,0x20,0xbe,0x31,0x50,0xac,0x48,0x49,0x1,0xf8,0xb9,0x39,0x38,0x67,0xf5,0xc9,0x15,0xab,0x62,0xba,0x9,0x8b,0x7c,0xa7,0x49,0xf6,0x57,0x91,0xed,0xc8,0x19,0x4,0x4e,0x80,0x54,0xf0,0x9e,0x97,0x2b,0xf2,0x8d,0xa,0x95,0x18,0xa4,0xdf,0x4b,0x16,0x38,0x67,0x2d,0xdd,0xb0,0xc4,0xb1,0x7c,0x20,0x35,0xce,0xa,0xce,0x4a,0x4b,0x6a,0xc6,0x30,0x29,0x28,0x18,0x6f,0xe0,0xc7,0xac,0xc2,0xc,0x7,0x53,0xb3,0xed,0xa4,0x4d,0x75,0x55,0x9d,0x21,0x72,0x73,0xef,0xb4,0xb8,0x64,0x54,0xdf,0x61,0xb4,0x5c,0xaf,0xb9,0xd4,0x67,0xb0,0xa,0x1c,0x72,0x93,0x35,0xc2,0xc2,0xe9,0xd7,0xc5,0xf8,0x7e,0x22,0x37,0xf,0x8f,0xaf,0x1f,0x7f,0x36,0x5,0x7c,0xf9,0xe7,0x58,0xad,0x33,0xc9,0xdb,0x3a,0xad,0xf3,0xbe,0xe5,0x10,0xd3,0xdc,0xc7,0x29,0x18,0x9c,0x6c,0x8b,0xb7,0xca,0x35,0x3c,0x40,0x17,0x78,0x13,0xc7,0xe0,0xa9,0x2c,0xc2,0x3b,0xf4,0xcb,0x5,0x5e,0xfc,0xe1,0xf7,0xe0,0x5c,0x84,0x54,0x12,0xc3,0xee,0xa5,0x72,0xf2,0x1e,0x32,0x67,0xef,0x7c,0xf,0xee,0x3c,0xff,0x20,0x9f,0xcf,0x31,0x67,0xd6,0x65,0x35,0x6c,0x8c,0xd9,0xee,0x9b,0x1a,0x3f,0x63,0x8c,0x64,0x9,0xcc,0xc7,0x34,0x9d,0xb,0x8a,0x4b,0x25,0x8c,0x19,0x50,0xd5,0xd,0xc1,0x79,0xad,0xf3,0x79,0x98,0x4a,0x27,0x42,0xf0,0x59,0xd5,0xe5,0xac,0x81,0xe9,0x3b,0x58,0x6b,0xd1,0xb4,0x2d,0x9a,0xaa,0xc2,0x6d,0xb7,0xdc,0x84,0xdb,0xce,0xdd,0x84,0xd3,0x27,0x4f,0x60,0x6b,0x73,0x13,0x4d,0x5d,0x61,0x63,0x3e,0x43,0x44,0x84,0x73,0x1e,0x7d,0x3f,0x60,0x6f,0xb1,0xc4,0xe5,0x6b,0x7b,0x78,0xed,0xcd,0xab,0x78,0xed,0xf2,0x2e,0x76,0x16,0xcb,0x95,0x73,0x2d,0xb0,0x62,0xc9,0x7b,0xc7,0x96,0x46,0x83,0x90,0xec,0x8e,0x76,0xc8,0xeb,0x71,0xf2,0xd8,0x51,0xd4,0xa,0xdc,0xe,0x4c,0xcb,0x36,0xf4,0x3d,0xae,0x2d,0x2d,0x2c,0xbf,0xc6,0x3b,0x87,0xa1,0x5f,0xc2,0x59,0x3,0x6b,0x6,0x2a,0xc4,0x8,0x1e,0xf3,0xcd,0x23,0xa8,0x9a,0x16,0x1b,0x9b,0xdb,0x38,0x7d,0xfc,0x8,0xa4,0x94,0xa8,0xea,0x86,0x80,0x8f,0x0,0xf6,0x96,0x3,0xae,0xef,0x2d,0x9,0xb0,0xc4,0x8,0x67,0x6,0x58,0x3b,0x60,0xe8,0xbb,0xdc,0x9c,0x7e,0xfc,0xd8,0x11,0x7c,0xe0,0xfc,0xdd,0x78,0xcf,0xbb,0xef,0xc6,0xe6,0xc6,0x1c,0xce,0x7b,0xbc,0x79,0xf9,0x2a,0x5e,0xba,0x78,0x19,0xcf,0xbf,0xf2,0x6,0x96,0xbd,0xc9,0xd7,0x56,0xef,0x3d,0x4e,0x1d,0xdd,0xc4,0x7,0xce,0xdf,0x81,0x9b,0x4e,0x1d,0x47,0xd3,0x34,0xb8,0x7a,0x6d,0x7,0x4f,0xfe,0xe0,0x47,0xf8,0xee,0xd3,0xcf,0x43,0x48,0x89,0xa1,0x5b,0x72,0x6,0x26,0xc1,0x3d,0xef,0x1d,0x8e,0x6c,0x6f,0xe3,0xe6,0x9b,0xce,0x40,0xea,0xa,0x9a,0xb3,0xd9,0xbc,0x77,0x78,0xe3,0xea,0x2e,0xac,0x23,0xdb,0xbc,0xe9,0x97,0x6c,0x1,0x1d,0x60,0xd,0x35,0xc3,0x2a,0x5d,0x41,0xeb,0xa,0x1b,0xdb,0x47,0x51,0x37,0x2d,0x95,0x41,0x8,0x9,0xa5,0x35,0x5b,0x82,0xc9,0xf2,0xad,0xaa,0xa,0x4a,0x2a,0xdc,0x7c,0xea,0x18,0xce,0xdf,0x75,0x33,0x6e,0xbe,0xe9,0x34,0x94,0x52,0x58,0x76,0x3,0x2e,0xbc,0x76,0x9,0xdf,0x7f,0xfe,0x15,0x5c,0x78,0xf3,0xfa,0x8,0x90,0x19,0x10,0xbd,0xf7,0xae,0xb3,0x38,0xff,0xae,0x5b,0xb1,0xb5,0x49,0xd,0xb2,0x2f,0xbd,0x7a,0x11,0x5f,0xf9,0xe6,0xdf,0xe0,0xea,0xde,0x0,0x6b,0x6,0x38,0x6b,0xd1,0x77,0x7b,0x19,0xa2,0xcd,0x37,0xb6,0xa1,0x34,0xd9,0x68,0x9b,0x76,0x6,0xc4,0x8,0x5d,0x37,0x94,0x51,0xc7,0x2d,0xc6,0xe7,0x4e,0x1f,0xc7,0xb9,0x1b,0x8f,0xe1,0xa6,0x1b,0x4f,0x62,0x7b,0x6b,0xb,0x6d,0xdb,0x20,0x46,0x60,0xd1,0xf5,0xb8,0x7c,0x6d,0x17,0x3f,0xb9,0xf0,0x3a,0x2e,0x5d,0xdb,0xc3,0xcb,0x17,0x2f,0x41,0xb1,0x9a,0x9c,0x1e,0xc4,0x88,0x3,0xcd,0xc2,0x4a,0x57,0xf9,0x7b,0x41,0x4a,0x52,0x8e,0x6e,0xcc,0x5a,0xdc,0x76,0xf6,0x14,0xde,0x75,0xeb,0x19,0x9c,0x3c,0x7e,0x4,0x5a,0x2b,0x18,0x6b,0xf1,0xfa,0xeb,0xaf,0xe3,0x47,0x2f,0xbe,0x82,0xa7,0x9e,0xfd,0x31,0x8c,0xa7,0xf3,0xa1,0x6e,0x66,0x8,0xde,0x51,0x43,0xee,0xe4,0xda,0x5c,0x37,0x6d,0xbe,0xa6,0x9b,0x7e,0x9,0xa9,0x35,0xdc,0xd0,0xe3,0xdc,0x99,0x1b,0x70,0xeb,0x99,0x13,0x38,0x77,0xd3,0x29,0xcc,0xe7,0x73,0xb4,0xb3,0x96,0xb6,0x81,0xb1,0x78,0xf3,0xf2,0x55,0xbc,0x76,0xe9,0xa,0x5e,0x78,0xe9,0x2,0x2e,0x5d,0xdd,0x85,0x71,0xa4,0xde,0xf3,0xd6,0x22,0x22,0xe6,0x8,0x84,0xc,0xf4,0xb8,0xb5,0x5e,0x2b,0x89,0x33,0x27,0xb6,0xe9,0x7c,0x54,0x1a,0x52,0x8,0x8,0xa9,0xb0,0xbb,0xe8,0x70,0x6d,0xb7,0xc3,0x30,0x2c,0x61,0x86,0x1e,0xcb,0xdd,0x1d,0xf4,0xcb,0x5d,0x86,0xab,0xc0,0x6c,0x73,0x1b,0x2,0x40,0xd5,0x50,0xde,0xa5,0xd2,0x7a,0xfc,0xce,0x8b,0x31,0xb7,0xd2,0xa7,0x87,0x58,0xe9,0x3b,0x64,0xbf,0x3a,0x1c,0x42,0x0,0xac,0x36,0xf4,0xce,0xc1,0x98,0x1e,0x6f,0x5e,0x7c,0x5,0x6f,0xbc,0xf2,0x5c,0xb9,0xf8,0x96,0x29,0x53,0xa6,0x4c,0x99,0x32,0x5,0x0,0x96,0x29,0x53,0xe6,0xe7,0x79,0x1e,0xfa,0xf8,0x67,0xb1,0x75,0xe4,0x38,0xdd,0xc0,0x27,0x40,0x10,0x92,0xdd,0x67,0xdf,0xe5,0x27,0x62,0x5,0x10,0x24,0x75,0xda,0x14,0xec,0x24,0xc8,0x97,0x60,0x4e,0x52,0xf,0x8e,0x7c,0x87,0x6d,0x7b,0x52,0xad,0x0,0xbc,0x94,0x19,0x27,0xa5,0xe6,0xa0,0xf3,0x8,0xa5,0x35,0xdb,0x9e,0x54,0xfe,0xdc,0xdc,0x56,0x2a,0x4,0xc1,0x36,0x8c,0x36,0x29,0xc1,0x37,0x42,0x42,0x50,0xfe,0x93,0x52,0xd5,0x4,0x1c,0xb2,0x3d,0x77,0x92,0x67,0x98,0x6e,0x78,0x62,0x8,0x59,0x5,0x48,0x2a,0x38,0x95,0xd7,0x71,0x4,0xa2,0x93,0x82,0x13,0x4c,0x8b,0x49,0xb0,0x4f,0xe1,0x36,0xb5,0x46,0xc9,0xc,0xda,0xd2,0x9f,0xa9,0xb8,0x40,0x4c,0x36,0xeb,0x24,0x93,0x10,0x60,0x50,0xe3,0x26,0xd0,0x75,0x9d,0x7d,0x97,0x5b,0x48,0x93,0xca,0x51,0x8c,0xf9,0x8b,0xa9,0x60,0x65,0x5a,0x8e,0x32,0x55,0xe6,0x8d,0xf6,0xd0,0x43,0x94,0x78,0xfb,0xec,0xc0,0x2b,0xb6,0xde,0x15,0x4e,0x77,0x78,0x2e,0xe0,0xa1,0x4a,0xbf,0xc3,0xda,0x81,0xa7,0xbf,0x3b,0xb5,0x68,0x47,0x2,0x35,0xde,0x39,0xf4,0xdd,0x2,0x2f,0x3e,0xf3,0x14,0x20,0x15,0xfa,0x9d,0xcb,0x88,0xbe,0xa8,0x0,0xf,0x9b,0x1b,0x6f,0xbb,0xf,0x77,0xbf,0xef,0x21,0x52,0x0,0xb1,0xda,0x2b,0x17,0x83,0x48,0x41,0xc5,0xf,0x13,0x85,0xaf,0x77,0xa3,0x22,0x4b,0x6a,0x9d,0xcf,0x81,0x4,0x4a,0x32,0x68,0xe6,0xac,0xcc,0x4,0xb4,0x35,0xe7,0xe5,0x25,0x1b,0xa1,0x77,0x54,0xd6,0x32,0xf4,0x4b,0x84,0x10,0xe0,0xac,0xc9,0xc7,0xf5,0xc6,0xe6,0x36,0xda,0xd9,0x6,0x84,0x52,0xa8,0x18,0x3a,0x4d,0x15,0xa7,0xf9,0xda,0xc1,0x16,0x5e,0xef,0x2c,0x74,0x55,0x67,0xe5,0x13,0xc5,0x2,0xf8,0xf1,0x1,0x82,0x54,0xb9,0xcd,0x58,0xca,0xf1,0xf3,0xc9,0xae,0x2c,0x33,0xfc,0xf1,0xde,0x23,0x6,0x3f,0x2a,0xa2,0x18,0xa2,0xc,0xfd,0x12,0x66,0xe8,0x20,0x20,0xd0,0x77,0x4b,0x7a,0x58,0xa1,0x14,0xe6,0x9b,0x47,0xa0,0x94,0x46,0xdd,0xb6,0xf9,0x5a,0xa2,0xb4,0x86,0x52,0x15,0x29,0xeb,0xf8,0x21,0x85,0xaa,0x6a,0xc,0xcb,0x5,0xbc,0xa7,0xec,0x40,0x21,0x4,0x86,0x9e,0xc0,0xa0,0xd6,0x35,0x9a,0xd9,0xc,0x8a,0xff,0x4c,0xdb,0xa7,0xca,0x9f,0x1f,0x9c,0x63,0xb,0xa6,0xcd,0xa0,0x8a,0x0,0xa3,0xcc,0x50,0x56,0x8,0x49,0xed,0xaf,0x52,0x61,0xe8,0x16,0x8,0x81,0x32,0xfd,0x2,0x5f,0xab,0x84,0x94,0x98,0x6f,0x92,0x6a,0xb0,0xaa,0x1b,0x68,0xde,0x6f,0xde,0xb9,0x7c,0x7a,0xc7,0x18,0xb1,0x7b,0xed,0x32,0x1c,0x67,0xbc,0x2e,0x77,0xaf,0x43,0x2a,0x85,0x76,0xbe,0x9,0xad,0x6b,0x6c,0x6c,0xd1,0xeb,0x75,0x55,0xe5,0x96,0x57,0xef,0x1d,0xaa,0xaa,0x46,0x8,0x81,0x60,0x17,0xab,0xaa,0xd3,0x75,0x38,0xa9,0x8a,0x45,0xba,0x4e,0x71,0xf6,0x22,0xd8,0x56,0x9e,0x94,0x64,0xd3,0x6b,0x0,0xd9,0x8d,0x59,0x29,0x19,0x3,0xfa,0xc5,0x1e,0x2b,0xbe,0x23,0x74,0xa5,0xd1,0xcc,0x36,0xa8,0x84,0xa5,0x22,0xb,0xb6,0xae,0x6b,0x82,0xce,0x7d,0x47,0x8a,0x4e,0x6b,0x60,0x87,0x9e,0xd6,0xc3,0x39,0xb4,0x73,0xfa,0x7d,0x3d,0x39,0x8e,0x34,0xef,0x7f,0x2,0xc4,0xa4,0xfc,0xd6,0x55,0x9d,0x2d,0xea,0x4,0x6,0x6d,0x56,0xb2,0x51,0x86,0xdf,0xfe,0xe2,0x27,0xb6,0x7f,0xc7,0x8,0x67,0x2d,0x43,0x53,0xda,0x47,0xed,0x6c,0x83,0xf3,0x12,0x69,0x3f,0xb6,0xb3,0x8d,0xfc,0x1d,0x95,0xad,0xb4,0xc,0x35,0x95,0xae,0xe0,0x33,0x58,0xf6,0xcc,0xcb,0x2,0xcc,0xd0,0xd3,0xb1,0xa3,0xc7,0xcf,0x96,0x52,0x21,0xc4,0x0,0x6f,0xed,0x98,0xc1,0x1b,0x2,0x9a,0xd9,0x1c,0x66,0xe8,0x33,0x90,0xed,0xbb,0x45,0xb6,0x32,0x27,0x38,0x9a,0xd6,0xaf,0x9d,0x6f,0xd0,0xef,0xf1,0x77,0x6f,0x82,0x7e,0xce,0x1a,0x2c,0xf7,0x76,0xd0,0x2d,0xf7,0xe0,0x9d,0xc5,0x6c,0xbe,0xc9,0xfb,0xbe,0x82,0xaa,0xea,0x6c,0xf,0x4e,0x20,0x93,0x9a,0xa3,0x27,0x19,0x7f,0x93,0xed,0x92,0x96,0x17,0x18,0x4b,0x86,0x42,0xf0,0x79,0x3b,0x5d,0xba,0xf0,0x32,0x2e,0xbd,0xfa,0xa3,0x72,0xf1,0x2d,0x53,0xa6,0x4c,0x99,0x32,0x65,0xde,0x81,0x29,0x16,0xe0,0x32,0x65,0xca,0xfc,0xcc,0x26,0xc6,0x35,0xb9,0x6c,0x62,0xa,0x65,0x92,0xf2,0x2f,0x95,0x5f,0x8,0xf8,0x1c,0xe9,0x17,0x56,0x20,0x60,0x86,0x87,0xc,0x72,0x84,0x24,0x55,0x5d,0xb2,0x6,0x8f,0x37,0x11,0x64,0x3f,0x4c,0x61,0xe3,0x9a,0x43,0xe8,0x5,0x5b,0x6a,0x15,0x67,0x93,0x25,0x10,0x1,0x90,0xca,0x84,0xd4,0x81,0x32,0x5b,0x45,0x43,0xf0,0x94,0x53,0xc4,0x30,0x32,0x78,0xf,0xc4,0x0,0xef,0xe9,0x66,0xd5,0x3b,0x3,0xa9,0x74,0xbe,0x51,0x25,0x30,0x10,0xf3,0x72,0x2a,0x86,0x90,0xc8,0x10,0x62,0xbc,0xc9,0xc9,0xeb,0xc5,0xea,0x46,0x81,0x71,0x1b,0x84,0x49,0x53,0xf2,0x2a,0xa0,0xb,0xc8,0x36,0x5d,0x4c,0x55,0x70,0x11,0x11,0xa3,0xa2,0x50,0x40,0x50,0xbe,0xe0,0xa4,0x91,0x35,0x81,0xc3,0x54,0x60,0x20,0x88,0xf0,0x71,0x26,0xe1,0x8,0x3,0x33,0xc8,0xc4,0x68,0xf1,0xcd,0x76,0x60,0x91,0x91,0x62,0xbe,0x49,0xcc,0xa,0x4b,0x8c,0xff,0xce,0x1,0x87,0xac,0x1c,0xa4,0xf7,0x1f,0x6d,0xc0,0xf8,0x5b,0xe1,0xdf,0x41,0x20,0xb9,0xa,0xf1,0xe,0x34,0x15,0xf3,0xf1,0x90,0x3b,0x80,0xd3,0x86,0xdc,0xf,0x4,0x53,0x46,0xe2,0xc4,0x8a,0x9d,0x73,0x13,0x63,0x84,0xd4,0xd,0x7c,0xf0,0xd0,0xf5,0x1c,0xb6,0x2b,0x0,0xf0,0xb0,0x49,0x59,0x76,0xe9,0x18,0x94,0x4a,0x65,0x25,0xe7,0x14,0xb8,0x25,0x10,0x9f,0x8a,0x12,0x74,0x55,0x67,0x6b,0x23,0x56,0x2c,0xdd,0x4,0x10,0xb5,0xd2,0xf0,0xac,0x1e,0x94,0x52,0xc1,0xda,0x1,0x6d,0xbb,0x41,0x4a,0xa5,0x10,0x18,0x88,0x54,0xdc,0x90,0x6b,0xc8,0xe2,0xe9,0xc,0x74,0xd5,0xa0,0xef,0x16,0x80,0x10,0x4,0x79,0x22,0xd0,0xce,0x37,0x32,0x30,0xa2,0x42,0x20,0x7a,0xe8,0xe0,0x6d,0x82,0x34,0x7c,0xdd,0x88,0x94,0x4b,0x66,0x86,0x1e,0x5a,0x6b,0x2e,0x26,0x51,0xd9,0xfa,0x1e,0x3,0x9d,0xcb,0xce,0x1a,0x86,0x4a,0x1,0xd1,0x7b,0x28,0x5d,0xc1,0x98,0x9e,0xd6,0x4f,0xa9,0x51,0xdd,0xc4,0x9f,0x9,0xbe,0xb6,0x38,0x6b,0x31,0xf4,0x4b,0xce,0x41,0x43,0x2e,0x43,0x92,0x5a,0x41,0x8,0x8f,0xba,0x21,0xab,0x2f,0xe5,0xbc,0x55,0x74,0xae,0xc4,0x8,0xdf,0x2f,0x69,0xfb,0x32,0x30,0x8f,0x7c,0xdd,0xb1,0xc3,0x0,0xbd,0x5d,0xb1,0x3d,0x32,0x65,0xcf,0x49,0x56,0x73,0x11,0xcc,0x76,0x6e,0x2c,0xea,0x48,0x99,0xab,0x42,0xd1,0xf5,0x25,0xc4,0x0,0x38,0x2e,0x4a,0x52,0x9a,0x14,0x8b,0x31,0xc2,0xda,0x21,0x43,0x55,0x0,0x98,0x6f,0x6e,0x67,0xfb,0xae,0x33,0xc3,0x8a,0x75,0x3f,0xbd,0xbf,0xf,0x9e,0x5e,0xef,0x1d,0x86,0x6e,0x9,0x20,0x66,0x28,0x9b,0xf2,0x1b,0x2b,0xb6,0xd6,0x1a,0xb6,0xe2,0x7a,0x37,0xe6,0x44,0x12,0xd8,0x94,0x19,0xf2,0x3a,0x67,0x20,0x85,0x62,0x40,0xd6,0xe7,0x7,0x37,0x9,0xd2,0xa6,0xeb,0x11,0x29,0xce,0x48,0xc9,0x27,0xf8,0x3c,0x1e,0xd5,0xa1,0x16,0x31,0x46,0x2c,0x76,0x49,0x3d,0xd8,0xb4,0x73,0xce,0xd3,0xa3,0xdf,0xa9,0xdb,0x19,0xbc,0xb3,0xb0,0x61,0xc8,0xdf,0x1d,0x66,0xe8,0xf9,0x81,0x87,0x82,0xf1,0x7d,0x3e,0xde,0x8,0xc6,0x52,0x76,0x9d,0x90,0x12,0x52,0x2b,0xc,0x5d,0x47,0x25,0x35,0x31,0x52,0xb,0x2e,0xab,0x23,0xad,0xa1,0xb2,0x16,0xef,0x52,0x46,0xde,0x0,0x5d,0x55,0x8,0x42,0xae,0x3c,0xf0,0xf0,0xdc,0xa2,0x6c,0xfa,0x8e,0xf7,0xa9,0xcd,0xcb,0x5f,0xb3,0x42,0x31,0xd9,0xa5,0xd3,0x32,0xeb,0x9a,0x2c,0xc6,0x3e,0x5a,0xde,0x36,0x86,0xf7,0x2f,0x35,0x4c,0xb,0x41,0x99,0xb2,0x43,0xb7,0x40,0x3b,0xdf,0x84,0xeb,0xa8,0x75,0x1a,0x4a,0xc1,0x9a,0x21,0x97,0xf6,0xd0,0xf7,0x9b,0x82,0x73,0x36,0x43,0x5b,0xa5,0x34,0x9c,0xa5,0x3c,0xc7,0xb4,0xe,0x9,0xfe,0x1,0xe0,0x87,0x64,0x1,0x42,0xc4,0xac,0x76,0x8f,0xac,0xe6,0xeb,0xbb,0x25,0x3c,0x1f,0xb,0xf4,0xbd,0x5a,0xe7,0xef,0xca,0xf4,0xb0,0x4a,0x8,0x35,0x82,0xfa,0x18,0x1,0x90,0xdd,0x37,0x30,0xc,0x4c,0xdf,0x4b,0x74,0x7c,0x81,0x61,0x6f,0x52,0x68,0x8f,0xf,0x11,0x84,0x90,0x2b,0x8a,0xc8,0x32,0x65,0xca,0x94,0x29,0x53,0xa6,0x4c,0x1,0x80,0x65,0xca,0x94,0xf9,0x79,0x4,0x80,0xf9,0x3f,0xd8,0xc7,0xb6,0xdc,0xc,0xaf,0xf8,0xff,0x27,0xeb,0x6b,0x88,0x11,0x8,0x63,0x66,0x5e,0xba,0x39,0x4c,0x36,0xc2,0x31,0x1f,0xf,0x10,0x31,0x22,0x84,0x38,0x51,0xf9,0x84,0x15,0x75,0xdb,0x14,0x12,0x8d,0x4a,0x3,0xfe,0xbb,0xf,0xf9,0x26,0x35,0x81,0x6,0xc5,0x37,0xf7,0x32,0x1,0x33,0x0,0x10,0x11,0x52,0xe9,0x7c,0xe3,0x95,0x9a,0x31,0xa5,0x60,0x2b,0x1b,0xdf,0x2c,0xad,0x34,0xf1,0x26,0xb0,0x37,0xf9,0xfc,0xf4,0xde,0xc1,0x3b,0xb2,0x44,0x4d,0x55,0x83,0xc,0x43,0xc3,0x44,0xad,0x94,0xd4,0x8b,0x19,0x52,0xa5,0xfc,0xba,0xe9,0x7a,0xb1,0x25,0x36,0x2b,0x66,0x26,0x6a,0xbc,0x15,0x28,0x96,0x21,0xea,0x34,0xbb,0x2d,0x8e,0x2d,0xba,0x88,0xb9,0xfd,0x37,0x5b,0x36,0x57,0x60,0x9b,0x24,0x9a,0xb7,0x92,0xcf,0x24,0xf2,0xb6,0xda,0x6f,0xd9,0x15,0x52,0x22,0x7a,0xcf,0xd0,0x13,0xb9,0xbc,0x64,0xcc,0x1a,0x64,0xbb,0x72,0xc,0x6b,0x41,0xdf,0x14,0x6,0xae,0xe4,0x4,0x4e,0x8e,0xa9,0x69,0xa6,0x60,0xfe,0xb7,0xe9,0x8d,0xa1,0x18,0x3b,0x8e,0x57,0x8e,0x99,0x29,0x8,0x9c,0x80,0xe9,0xf4,0xde,0x6e,0x58,0x40,0x56,0x2d,0x8a,0x28,0xfe,0xad,0x67,0xaa,0xdc,0xa1,0xf3,0x69,0x54,0xf6,0x3a,0x2e,0xb7,0x20,0x15,0x12,0x38,0x7f,0x53,0xb3,0x2,0x78,0xba,0xbf,0x23,0x42,0x14,0x23,0x3c,0x90,0xa,0x21,0x46,0x28,0x6e,0x12,0x4e,0xbf,0x43,0xd6,0x5b,0x1,0xc9,0x16,0x7e,0xc7,0xa0,0x2a,0x84,0x0,0xc7,0x60,0xc8,0x59,0x6a,0x63,0x35,0x7d,0x7,0x67,0xd,0x6a,0x6e,0xa0,0x4d,0xe7,0x8b,0x31,0x3d,0x10,0x1,0x15,0x75,0x2e,0xf3,0x20,0x58,0x66,0xa8,0xad,0xb7,0x6a,0x72,0x5e,0x9f,0xd2,0x35,0x62,0xc,0xb0,0xd6,0x65,0x9b,0x3f,0x40,0x56,0x4e,0x8d,0x51,0x6d,0x66,0x87,0x8e,0x80,0x1d,0xab,0xeb,0x84,0x90,0xe8,0x97,0xbb,0x6c,0x7d,0xac,0x10,0x1,0x98,0xc5,0xe,0x59,0x2a,0x75,0x85,0xbe,0x5b,0x90,0xa5,0x52,0xec,0x61,0xbe,0x79,0x24,0xb7,0xa4,0x4a,0x56,0xea,0x25,0xf5,0x58,0x82,0x5b,0x19,0x72,0xb2,0xb2,0x96,0xd4,0x80,0x1e,0x75,0xdb,0x92,0x72,0x4f,0x29,0x8,0x21,0xe1,0xa2,0xc9,0xb0,0x85,0x32,0x3,0x9,0x40,0x52,0x36,0x9b,0xcf,0x16,0x4c,0x1d,0x35,0x5c,0xca,0x42,0xe5,0xf6,0x65,0xa5,0x34,0x4c,0xbf,0x24,0xa0,0xe3,0x29,0x7b,0x50,0x72,0x16,0x60,0xbf,0x5c,0xa0,0x99,0xcd,0xa1,0x94,0x82,0x60,0x98,0x97,0x1e,0x20,0x4,0xce,0x3d,0x4c,0xca,0x66,0xef,0x2,0x6f,0x33,0xb,0xad,0x2b,0xd8,0x61,0x40,0x5d,0xb7,0x54,0x68,0x12,0xab,0xac,0x2a,0xf3,0x6e,0x54,0x97,0x9,0x7e,0x60,0x12,0x82,0x3,0x84,0x86,0x1b,0x2c,0xea,0xba,0x85,0xb5,0x3,0xc3,0x43,0xc3,0xf0,0x56,0xe7,0xf5,0xaa,0xaa,0x9a,0x54,0xcc,0x4a,0x31,0x21,0xa2,0x6b,0xe2,0x72,0x6f,0x7,0x55,0xdd,0xd0,0xb2,0x79,0x7,0x33,0x10,0x3c,0xa4,0x6,0x5d,0x52,0xa0,0x7a,0xab,0x1,0xd,0x74,0x8b,0x5d,0x28,0x5d,0x31,0xf8,0x32,0x39,0x1e,0x62,0xe8,0x97,0xe3,0xf5,0x35,0x44,0x2a,0x45,0x9,0x1,0x4e,0xa,0x34,0xb3,0xd,0xf4,0xcb,0x5,0x43,0x5c,0x91,0x55,0x74,0x0,0x95,0xa8,0xa4,0x6b,0x67,0x3a,0xf6,0xd2,0x35,0xc6,0x7b,0xf,0xad,0x25,0x2b,0x1f,0x6d,0x7e,0x0,0x95,0xa,0x9e,0xbc,0x77,0x70,0xc6,0x10,0x44,0xe3,0xb,0x54,0x55,0x35,0x8,0x21,0xa0,0x69,0x35,0x4c,0xdf,0x41,0xd7,0xd,0xb5,0xb,0x57,0x35,0x86,0x7e,0x89,0x66,0xb6,0x91,0x33,0x5b,0x53,0xa6,0xa2,0x73,0x96,0x4b,0x5c,0x58,0xa1,0x99,0xbe,0xe7,0x38,0x7b,0xd3,0x39,0x4b,0xcb,0x13,0x3c,0xa2,0xf7,0xf9,0x18,0x40,0x44,0x3e,0xee,0xec,0x30,0x20,0x82,0x14,0x93,0x61,0x70,0x39,0x6e,0x82,0x60,0x9d,0xcf,0x20,0x30,0x78,0x52,0x6c,0xe,0x7e,0x9,0x29,0x45,0xce,0xe7,0x73,0x86,0x54,0x94,0x42,0x8,0x28,0xa9,0x48,0xbd,0xcb,0x0,0x9a,0xe0,0x9d,0x80,0x62,0x80,0xe8,0xbd,0xe3,0xeb,0xef,0xc1,0xc2,0xaa,0xe9,0xc3,0xad,0x49,0xe6,0xc3,0x24,0x86,0xa2,0x4c,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0x0,0x60,0x99,0x32,0x65,0x7e,0x6e,0x47,0xec,0x2b,0x8e,0xc8,0xd6,0x53,0x4c,0x4a,0x21,0x42,0xcc,0xd9,0x7f,0x39,0xeb,0x2f,0x29,0x89,0x12,0x40,0x2,0x20,0x59,0x39,0x90,0x40,0x93,0x62,0xb,0x9e,0xe0,0xcc,0xa0,0x94,0x2b,0x96,0x54,0x7d,0x22,0xe5,0xd7,0xed,0x2b,0x8e,0x98,0x42,0xac,0xa4,0x2e,0x98,0xbe,0xe,0x22,0x52,0x49,0x1,0x24,0xbc,0x35,0x74,0x23,0x57,0xd5,0x2b,0x16,0xdc,0x74,0xa3,0xa8,0xab,0x3a,0x97,0x19,0x44,0x6,0x66,0x21,0xfa,0x6c,0x73,0xce,0xad,0xbf,0xc,0xe9,0x42,0xf0,0xd4,0x92,0x29,0x24,0x62,0x52,0x3c,0x3a,0x4b,0x39,0x86,0x31,0xae,0xb4,0x1b,0x67,0x1b,0x72,0x52,0xfe,0x25,0x85,0x61,0x9c,0x96,0x7e,0x24,0xd0,0x3a,0x66,0x28,0x8a,0x5c,0xa7,0x8c,0xc9,0xef,0xcb,0xc9,0x8d,0x15,0xb2,0x6a,0x72,0x54,0xe3,0xad,0xc2,0xbf,0x64,0xc7,0xcb,0x2a,0x22,0x4c,0xa1,0xaa,0xc8,0x6a,0xcd,0x74,0x83,0x97,0x97,0x3d,0xc4,0xc,0xe4,0xf6,0xdb,0x30,0x57,0x14,0x86,0x42,0x42,0x30,0x8,0xdd,0xf,0xfe,0x46,0x8,0x3a,0xbd,0xe1,0x9b,0xa4,0x1b,0x8a,0x51,0xf5,0x99,0xc1,0xf0,0x44,0xf1,0xb7,0x62,0x33,0x8e,0x63,0x2e,0xe2,0x58,0x2a,0x42,0xcb,0x30,0xde,0x66,0x72,0x11,0x8d,0xaa,0x10,0x6c,0xf,0xa1,0xeb,0x72,0xe2,0xbe,0x25,0xd5,0x8f,0x7,0x5a,0x94,0x29,0xc8,0x5f,0xb3,0x52,0xc9,0xb3,0x7d,0x56,0x66,0x9b,0xfd,0x34,0xef,0x4b,0x4a,0xc1,0x60,0xc7,0xf0,0xb1,0x46,0xc7,0xb8,0xae,0x1b,0xf8,0x54,0xae,0x21,0xc8,0x4a,0x4c,0xf,0x1,0x3c,0xac,0xb1,0x39,0x47,0x4e,0x2a,0x95,0x55,0xbd,0xfd,0x72,0x81,0xa1,0x5f,0x62,0x36,0xdf,0x44,0xdd,0xcc,0xa0,0xb4,0x86,0xae,0x6a,0x74,0x8b,0x5d,0x54,0x4d,0x9b,0x73,0xe7,0x7c,0x70,0x80,0xa3,0x63,0xd5,0x65,0x6b,0x2c,0xb2,0x82,0x2b,0xa9,0x53,0x63,0xf0,0x18,0x86,0xe,0x5a,0x55,0xd9,0xf2,0x48,0x50,0x4a,0x65,0x78,0x11,0xb8,0xc1,0xd8,0x4f,0xb2,0xcc,0xa4,0x94,0x50,0xaa,0x82,0x73,0x26,0x67,0xc4,0x29,0x55,0xa1,0x37,0xb,0x2c,0xf7,0x76,0xf2,0xc3,0x83,0xa4,0xd6,0x33,0x7d,0x87,0x58,0x87,0x1c,0x8d,0x10,0x1,0x58,0x56,0x14,0x6,0xb6,0xa6,0x47,0x56,0x99,0x25,0x55,0x1f,0x20,0x60,0xfa,0x1e,0xb3,0x8d,0x2d,0x2c,0x77,0x77,0xb0,0x75,0xe4,0x38,0x3,0x2e,0xfa,0xbc,0xa1,0x5b,0x72,0xa4,0x0,0xed,0x18,0x6b,0x7a,0xb6,0xbd,0xa,0xf4,0xfd,0x92,0xa0,0x97,0xb3,0x68,0xda,0xd9,0xa8,0x44,0x94,0xa,0xc6,0xf4,0x8,0xde,0x51,0x61,0x9,0xef,0x97,0xa4,0x0,0x8b,0x91,0x54,0x75,0x10,0x5c,0x9c,0x94,0xaf,0x9d,0x63,0x26,0xa3,0x19,0x6,0x44,0x0,0x5a,0x6b,0x54,0x75,0x3,0xa9,0x24,0x96,0x8b,0x1d,0x6c,0x6e,0x1d,0x85,0x73,0x16,0x2d,0x5b,0xad,0x95,0xa6,0xed,0x53,0x49,0x82,0x5c,0x2,0x9c,0x15,0x19,0x42,0x5e,0xb6,0x18,0x2,0x8c,0xb3,0x18,0xba,0x25,0x4,0xc0,0xdb,0x93,0x94,0xd7,0x31,0x12,0x80,0x4a,0xd6,0x5c,0x21,0x25,0x9c,0xb5,0xd0,0x75,0x4d,0x50,0xd6,0x18,0x58,0x6b,0xd0,0xcc,0xe6,0xf4,0x6f,0x66,0x80,0x35,0x6,0x55,0xdd,0xc2,0x5a,0xc3,0xf6,0xda,0x98,0x41,0x21,0x4,0xc1,0x63,0xcf,0x8a,0x3f,0xc4,0xc8,0x19,0x8e,0xa4,0xae,0x9c,0x49,0x9,0x19,0x53,0x21,0xd,0x6d,0x53,0x67,0x9,0x12,0x8b,0x1c,0x81,0xe0,0x9,0x2a,0xf3,0xf5,0xd9,0x9a,0x7e,0x2c,0xf1,0x50,0x9a,0x15,0x7a,0x2,0xba,0x6e,0xe0,0x38,0xa3,0x30,0x65,0xcd,0x5a,0x33,0x60,0xb1,0x77,0x1d,0x55,0x45,0x36,0x6e,0x67,0x4c,0xb6,0x29,0x9b,0xa1,0x5f,0x69,0x30,0x4e,0x5,0x3a,0x49,0x5d,0x9a,0xa0,0x2d,0xb5,0x2c,0x53,0xf6,0xa4,0x77,0xb4,0xf,0xe7,0x9b,0xdb,0x59,0x69,0xeb,0x87,0x3e,0x3f,0x8,0x92,0x52,0x1,0x6c,0x61,0x26,0x65,0x7c,0x95,0x21,0xa8,0xe2,0x66,0xe9,0x10,0x3c,0x29,0x2b,0x79,0xdb,0x80,0x2d,0xda,0x74,0xcd,0xf5,0x19,0x74,0xa6,0xeb,0x34,0x29,0x2e,0x43,0x86,0xb2,0xed,0x6c,0x9e,0x1f,0x28,0xd1,0xf7,0x2a,0x3,0xcf,0x20,0xf2,0xb5,0x59,0xa6,0x86,0xe0,0xc9,0x35,0x7e,0x54,0xc,0xa,0x20,0x8a,0xf1,0x1a,0xbd,0x2f,0x96,0xa2,0x4c,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0x0,0x60,0x99,0x32,0x65,0x7e,0xbe,0x9,0xe0,0xf8,0x47,0x20,0x17,0x79,0xe4,0x1c,0x29,0xc4,0xfc,0x67,0xca,0x4b,0x4a,0xe0,0x6c,0x54,0x89,0x8c,0x16,0xdf,0xb0,0xd2,0x2a,0x1c,0x2,0x29,0x31,0x54,0x55,0x21,0x75,0xce,0x26,0x7b,0x59,0x64,0xb8,0x24,0x20,0x19,0x2e,0xb1,0xcd,0x30,0x95,0x78,0x70,0xd6,0x56,0xb2,0x41,0x1,0x64,0x8f,0x1b,0x6f,0x66,0x38,0x8b,0x48,0x8,0xca,0xaf,0xe2,0xd0,0xf4,0x4,0x94,0xe8,0xf7,0x34,0xbc,0xb3,0x74,0x23,0x83,0xd1,0xbe,0x2b,0xa5,0x44,0xae,0xcc,0x50,0xc8,0xd6,0x29,0xb2,0xe3,0x22,0x2b,0xfe,0xa8,0x10,0x43,0xe4,0xfc,0x30,0x82,0x77,0x22,0x5b,0x77,0x25,0xdb,0xc7,0xc6,0xcd,0x18,0xb3,0x65,0x72,0xb4,0x45,0xa9,0xc,0x60,0x22,0x67,0x9,0xa,0x21,0x11,0x45,0x9c,0x6c,0x53,0x56,0xfc,0x1,0xb9,0x54,0x64,0x15,0xac,0x4d,0x60,0x6d,0x2a,0x36,0x71,0x8e,0xad,0x6e,0x40,0x8c,0x7e,0x5f,0x6b,0x6f,0xe0,0xb2,0x93,0x38,0x51,0xf5,0x89,0xd5,0x9b,0xb8,0x4,0x15,0xd9,0x9a,0x1b,0x27,0x60,0x91,0x7e,0x9e,0x60,0x70,0x52,0x86,0x7a,0x5e,0x97,0xd1,0x1a,0xbe,0x6a,0x1,0x4e,0xeb,0x26,0x56,0xe0,0xe5,0x78,0x3c,0x8c,0x4d,0xd1,0x21,0x26,0x8,0xba,0xf,0xfa,0xf2,0xdb,0xc4,0x75,0x37,0x94,0xcc,0xb3,0x8,0xc6,0xfa,0x72,0xde,0xbe,0xc5,0x84,0x6c,0xc3,0xc7,0xc4,0x71,0x2d,0x18,0x2c,0x84,0x83,0xb9,0x92,0x31,0x22,0x82,0x72,0xf2,0x24,0x58,0x11,0xeb,0xfd,0x6a,0x51,0x4f,0x20,0xc8,0xa1,0x18,0xb4,0x65,0x5,0x70,0xb4,0xf9,0xbc,0xf,0x7c,0x8c,0x48,0x19,0x19,0xb2,0x78,0x2a,0xeb,0x50,0x3a,0xe7,0xd7,0x9,0x3e,0x5f,0xa9,0xf1,0xd5,0x62,0xb6,0xb1,0x85,0x18,0xe9,0xbc,0xf5,0x29,0x77,0x93,0xa1,0x4a,0x52,0x16,0x7,0x6b,0x32,0xa0,0x74,0xe9,0x7c,0x8e,0x1,0xde,0x93,0xea,0x57,0x80,0x5f,0xc3,0x96,0x77,0xca,0x71,0xb,0x59,0x1d,0x55,0xd5,0x4d,0x56,0x71,0x69,0x5d,0x21,0x8,0x9f,0xa1,0x9d,0xf7,0x94,0x99,0x97,0xca,0x36,0x9a,0xd9,0x3c,0x2b,0xb7,0x92,0x2a,0x90,0xca,0x12,0xc0,0x4a,0xc6,0xd1,0x4e,0x9d,0x4a,0x2d,0x8,0x7c,0xaa,0x6c,0xa3,0xed,0x96,0xbb,0xa8,0x9b,0xa4,0x4,0xd4,0x8,0x9a,0xae,0x59,0x9e,0x4b,0x1d,0x9c,0x25,0x55,0x99,0x63,0x28,0x44,0xc5,0x12,0x9e,0x14,0x74,0xc,0x8e,0xbc,0x73,0x80,0x9a,0xee,0xd3,0x8,0xa5,0xa8,0xbd,0x35,0x1,0x1f,0xb2,0xf4,0xe,0xf9,0xe1,0x88,0x4c,0xa,0xe2,0x9c,0xd1,0x16,0x60,0xfa,0x2e,0x67,0xaa,0x76,0x8b,0xdd,0xac,0x5c,0xdc,0x3a,0x7a,0x2,0x52,0x69,0xb6,0xc5,0x8e,0xea,0xb7,0x94,0x4f,0x27,0xa4,0xc8,0xcb,0x91,0x62,0x11,0xb4,0xae,0xa8,0x94,0xc7,0x59,0x8,0x0,0x36,0x29,0x20,0x43,0xa0,0x62,0x9e,0x6e,0x81,0xa6,0xdd,0xc8,0xd7,0x78,0x9f,0x9a,0x96,0xed,0x80,0x18,0xc8,0x3a,0xeb,0x9c,0x85,0x19,0x7a,0x6e,0x9f,0xd,0x79,0x3b,0x54,0xc,0xe0,0x0,0x40,0x54,0x4d,0x6e,0x69,0x4e,0x8a,0x35,0x0,0x18,0xfa,0xe,0x43,0xb7,0xc0,0x7c,0xeb,0x8,0x3c,0x8,0x50,0x35,0xb3,0x79,0x56,0xbd,0x59,0x33,0xe4,0x6b,0x94,0x73,0x94,0xfd,0x28,0x84,0xcc,0xeb,0x28,0x21,0x39,0x17,0xd2,0x8d,0x2d,0xf0,0x7c,0x9d,0xf6,0xdc,0xe8,0x4c,0xff,0x46,0xa,0x40,0x82,0x93,0xd,0x2b,0x31,0x3b,0x34,0xb3,0x39,0x86,0x7e,0xc9,0x10,0x55,0xb3,0x45,0x3d,0xe4,0xdc,0xca,0x6e,0xb1,0x47,0xad,0xd8,0x6c,0xc1,0x4f,0xa0,0x30,0x4,0xcf,0x19,0x7f,0x1e,0x42,0x68,0xf4,0xcb,0x3d,0xca,0x3d,0xac,0x6a,0x28,0x5d,0xa1,0x6e,0x5a,0x2c,0x17,0xbb,0x19,0xd2,0xa5,0x76,0x5d,0xc1,0xa,0xbf,0xd5,0x5c,0xd6,0x51,0xa9,0x4f,0x25,0x3c,0x9a,0x8f,0x6d,0x7e,0x90,0xc5,0xaa,0x79,0x2,0xe1,0x74,0xe,0x2c,0xf7,0xae,0xa3,0x6e,0xe7,0x1c,0xad,0xe1,0x33,0xec,0x46,0x8c,0xe3,0x3,0x30,0x7e,0xdf,0x30,0xb1,0xf6,0xe6,0x58,0x8a,0xc0,0xdf,0x7,0x18,0xf3,0x63,0x57,0x1e,0x56,0x21,0x96,0x16,0xe0,0x32,0x65,0xca,0x94,0x29,0x53,0xe6,0x1d,0x1c,0x5,0xe0,0xbf,0x2d,0x9b,0xa1,0x4c,0x99,0x32,0x3f,0x8b,0x39,0x7b,0xc7,0x7d,0x68,0xda,0x39,0x97,0x6b,0xc4,0x51,0x29,0x36,0x72,0x9e,0xd5,0xd6,0x5d,0x56,0xa1,0x65,0x25,0x20,0x37,0x81,0x12,0x3c,0x92,0xf9,0x7f,0x93,0xaa,0x48,0xf0,0xd,0xd7,0xb4,0xf4,0x23,0xe7,0x6,0x49,0xc1,0x37,0xad,0xa0,0x1b,0xb7,0x89,0x6a,0x4d,0x6b,0x4d,0x37,0xb6,0x5c,0xc,0x10,0x42,0x80,0x66,0xcb,0xd8,0x98,0x5b,0x46,0xcd,0xa5,0x9,0x5a,0x2a,0xa5,0xd9,0x7a,0x47,0xea,0x6,0x82,0x87,0x55,0x66,0x9c,0x2,0x94,0x13,0x35,0x5a,0x22,0xc7,0x12,0x90,0xb1,0x15,0x38,0x66,0x90,0x95,0x1,0x28,0x46,0x3b,0x6e,0x86,0xa4,0x9,0x94,0xa5,0xcc,0xc0,0x49,0x2b,0xf1,0x2a,0xd4,0x4a,0xa,0x47,0xe4,0xf5,0x4b,0x37,0x70,0x89,0x71,0x25,0x4b,0xf5,0x6a,0xee,0x5a,0x6a,0x6a,0x8d,0x63,0xce,0x5f,0xea,0x31,0x49,0x80,0xcf,0x53,0x71,0x41,0x56,0x69,0x70,0xe6,0x62,0x86,0x85,0x31,0xae,0x14,0x89,0x88,0x69,0xe1,0x2,0x5b,0x30,0xf3,0x96,0x91,0xe3,0xcd,0x9d,0x60,0xd5,0x27,0xbd,0xcf,0x2a,0x8c,0x4c,0x5,0x29,0x71,0xa,0x25,0x93,0xb2,0x4f,0x4a,0xb6,0x66,0x8f,0xd9,0x87,0xe9,0x46,0x73,0xff,0x64,0xd5,0xe1,0xa,0x8b,0x16,0xab,0xd8,0x2f,0xa6,0x9c,0x37,0xca,0x32,0xbb,0xfa,0xe6,0xeb,0x74,0xc3,0xa,0x20,0xb8,0xbe,0x9c,0xbc,0x87,0xcc,0xf6,0x89,0xd3,0x38,0x76,0xf2,0xc6,0x5c,0x4,0x81,0x18,0x72,0xde,0xa3,0xda,0x57,0xd2,0x93,0xf6,0x53,0xca,0x5b,0xcb,0x8d,0xda,0x40,0xb6,0x16,0x42,0x10,0x20,0x90,0x62,0xb4,0xed,0x2a,0xce,0xd6,0x8c,0x88,0xfb,0xa,0x66,0xe2,0x4a,0x1,0x88,0x90,0x8a,0x94,0x6e,0x75,0x43,0xe0,0xa3,0x9d,0xc1,0x1a,0xc3,0x90,0xc2,0x92,0x15,0x96,0x2d,0x87,0x42,0xa,0x56,0xc,0x4b,0x86,0xf5,0x11,0xce,0x99,0x8c,0x1c,0x52,0x71,0x86,0x92,0x9a,0x1,0xcd,0x90,0x97,0xd3,0x39,0x3,0x67,0x5d,0x56,0xbd,0x79,0x4f,0xd,0xb2,0x74,0xd,0x20,0xfb,0xb2,0x54,0x4,0xbf,0x9c,0xa5,0x36,0xdd,0xc8,0xaa,0xb2,0x10,0x3c,0x96,0xbb,0xd7,0xd1,0xb4,0x33,0x8,0x21,0x50,0x37,0x6d,0xb6,0xe3,0xb,0x99,0x32,0xe2,0xb8,0xc5,0x3b,0x89,0x59,0xf9,0x7a,0x84,0x18,0xd1,0x2d,0xf6,0x58,0x1d,0x47,0x0,0x49,0xf0,0xb1,0xac,0xab,0x9a,0xce,0xb3,0x48,0xd9,0x72,0x81,0xf3,0xe5,0x3c,0xab,0xf9,0xc6,0x73,0x8f,0xae,0xa9,0xa4,0x4a,0x53,0x2b,0xd6,0x51,0xad,0x6b,0x58,0x86,0x48,0xa9,0xb4,0x24,0x81,0x35,0xa9,0x34,0xa4,0xd6,0xa8,0x58,0xd,0x8,0x81,0xac,0x7e,0x4c,0x8a,0xc1,0x14,0x81,0xd0,0x2f,0xf6,0x48,0x51,0x67,0x6,0x6c,0x1d,0x3d,0xc1,0xa0,0x48,0x64,0x76,0x9f,0x32,0x1c,0xa7,0xd,0xb0,0x21,0x4,0x56,0x5a,0xa7,0x63,0xa1,0x82,0x1d,0xba,0xdc,0x9a,0x9c,0x5a,0x7a,0x13,0xb8,0xd3,0xac,0x8e,0x73,0xd6,0x8c,0xb1,0x6,0x4a,0xa2,0x62,0xdb,0xbe,0xe9,0x7b,0x0,0x31,0xc3,0x30,0x6b,0x6,0x34,0xcd,0xc,0x55,0xd3,0xe6,0xac,0x3a,0xa5,0x2b,0x8a,0x7c,0xd0,0xd4,0x2e,0xed,0x39,0x3b,0xd1,0xc,0xe3,0xe7,0xf8,0x9,0x44,0x14,0xf9,0xa1,0x45,0xcc,0xdb,0x2e,0xc5,0x39,0xa4,0x96,0xf5,0xd4,0x82,0xab,0xb4,0xa6,0x62,0xd,0x8,0x3e,0x76,0x1,0xa5,0x18,0x8,0x86,0x38,0xda,0x65,0xad,0xe1,0x2,0xe,0x5a,0x97,0xc5,0xf5,0xab,0x98,0x6f,0x1d,0xc9,0x25,0x55,0xe9,0x1a,0x45,0x85,0x32,0x71,0xc5,0xee,0xec,0xec,0x90,0x21,0x6e,0xfa,0x8e,0x89,0x31,0x66,0x38,0xe9,0xd9,0xe,0xaf,0x14,0x3d,0xbc,0xf1,0xde,0xf2,0x83,0x2f,0x3a,0x9f,0x8,0x68,0x63,0x8c,0xd5,0xe0,0xa7,0x4b,0x54,0x96,0xe5,0xb2,0x4a,0xdd,0xda,0x81,0xbf,0x13,0x62,0x3e,0xde,0xd3,0xd5,0xbf,0xef,0x16,0x8,0xde,0x8f,0x45,0x37,0x9c,0x7d,0x99,0xac,0xd5,0x9a,0x8b,0x4c,0x12,0x2c,0xcd,0xe5,0x5a,0x88,0x2b,0xc5,0x3f,0xf9,0xbb,0x82,0xbf,0xb,0x45,0xce,0x71,0x1d,0xcf,0x81,0xb4,0xae,0x8b,0xbd,0x1d,0x2c,0x77,0x2e,0x97,0x8b,0x6f,0x99,0x32,0x65,0xca,0x94,0x29,0xf3,0xe,0x4c,0x51,0x0,0x96,0x29,0x53,0xe6,0x67,0x38,0x71,0xca,0xfa,0xf2,0x8d,0xe4,0x14,0x80,0x11,0x10,0xf2,0xd9,0x56,0xa,0x99,0x32,0xe2,0x22,0x5b,0x66,0x19,0x75,0x4d,0x6e,0x1e,0xb4,0xa6,0x22,0xf,0xa9,0x35,0xb4,0x4c,0x21,0xe7,0xac,0xe4,0xb,0x9c,0x59,0xe4,0x49,0x29,0x46,0x6a,0x23,0x6,0x8,0x6c,0x65,0xcb,0xad,0x98,0xa0,0xbf,0x2b,0x8d,0x9c,0x9b,0x55,0xd5,0x7a,0xa2,0x72,0xa2,0xd7,0x24,0x30,0x95,0xad,0xa8,0x13,0xd8,0x96,0xf2,0xf0,0xb2,0x5a,0x45,0x8e,0x2d,0x8a,0x29,0x97,0x89,0x20,0xc8,0x98,0x81,0x47,0xb6,0x44,0xb3,0x7a,0xd3,0xb3,0x92,0xf5,0x7,0xb6,0x42,0x61,0x54,0xd0,0x65,0x60,0x28,0xc6,0xf2,0x8a,0x4,0xde,0x82,0x67,0xfd,0x84,0xe0,0x52,0xf,0x31,0xc2,0xb3,0xc,0xc5,0x46,0x85,0x5d,0x86,0x76,0x42,0x4e,0xa0,0xa4,0x64,0x46,0x37,0xaa,0x33,0x7c,0xca,0x54,0xe4,0x9b,0xf4,0x9c,0x2d,0x18,0xe3,0x1,0xe8,0x97,0xf2,0x6,0x53,0x3b,0xac,0x94,0x3a,0xab,0x7d,0x28,0xdc,0x9d,0x7f,0x37,0x84,0xc,0x78,0x53,0xab,0xaa,0x98,0xb6,0x30,0xb,0xb1,0xb2,0x8c,0x19,0xfe,0xf1,0x3e,0xd9,0xdf,0xed,0x11,0xf7,0xff,0x2e,0x30,0x69,0xa5,0xe5,0x1c,0x49,0x60,0x1f,0x10,0x8c,0xab,0x19,0x82,0x9,0x50,0x7,0x8f,0x18,0x6c,0x39,0x6d,0xdf,0x62,0xc6,0x9c,0x4c,0x56,0x5a,0xca,0x49,0x21,0x4c,0x18,0xb3,0x15,0x29,0x93,0xd3,0xaf,0x94,0x42,0xa7,0x92,0x1,0xa1,0x54,0x6e,0xd1,0x5,0xc6,0x42,0x8b,0x8a,0x8b,0x4,0xc2,0xa4,0xd8,0x27,0x86,0x80,0xaa,0xae,0x61,0xad,0x1d,0x1f,0x2,0x28,0x85,0x4a,0x4a,0x74,0xcb,0x3d,0x84,0x10,0xd0,0x2f,0xf7,0x50,0xd5,0xd,0x96,0x7b,0xa4,0x74,0xb2,0xa6,0x47,0x3b,0xdb,0x60,0x1b,0x24,0xb5,0xdd,0xa6,0x36,0x5a,0x6b,0x86,0xc,0xcf,0x12,0x28,0x71,0x8e,0x32,0xcc,0x94,0xd6,0x58,0xee,0xed,0x8c,0xc5,0x1a,0x21,0x50,0xe,0x61,0x8c,0xd9,0x86,0x9b,0xc0,0xb8,0x9f,0x64,0xa3,0xa5,0x87,0x14,0x8a,0x1,0xb,0x10,0xb1,0xb7,0x73,0x95,0xb2,0xe9,0xc2,0x8,0x3f,0x62,0x20,0xa8,0x13,0x4,0xa9,0x91,0xc7,0x7,0x10,0x3e,0x43,0xa6,0xc0,0x39,0x6d,0xd6,0xf4,0xc,0x19,0xa9,0x9,0x55,0xe9,0xa,0x43,0xb7,0x40,0x6c,0x66,0xa8,0xdb,0x79,0x56,0x5d,0x2,0xac,0x84,0xb4,0x6,0x7d,0xbf,0xcc,0x76,0xcf,0xa1,0x5f,0x72,0xb9,0x43,0x8f,0xd9,0x7c,0x8b,0x61,0x6a,0xc8,0xc5,0x45,0x9a,0x9b,0x6b,0xa5,0x52,0x70,0xb,0xda,0x26,0xfd,0x62,0x97,0xd7,0x2b,0x15,0x25,0x75,0x50,0x5c,0x74,0x42,0x59,0x74,0xd,0x5d,0x97,0x39,0x47,0x35,0x86,0x4,0x9f,0x4,0x82,0x71,0xd9,0x62,0x4d,0xd,0xcb,0xf4,0x80,0x24,0xb7,0xbe,0x32,0x9c,0xac,0x9b,0x19,0xac,0x37,0x74,0xd,0x0,0xa9,0xe3,0x54,0x55,0x61,0xe0,0x3c,0xc2,0x64,0x79,0xd,0xde,0xe5,0x76,0x5a,0x33,0x90,0xf5,0xb9,0x99,0xcd,0x73,0xe3,0x6e,0x33,0xdb,0xa0,0x9c,0xc0,0x66,0x7c,0x90,0x41,0x96,0x6a,0xcb,0x10,0xd6,0xc3,0x7,0xcf,0xa,0xc0,0x96,0xe1,0x25,0x6d,0xf7,0xc0,0x8a,0x69,0x2a,0x78,0xa1,0xdc,0xc5,0xaa,0x69,0xe1,0x16,0xbb,0x58,0x2e,0x76,0xd1,0xb4,0x33,0x2,0x75,0x7d,0x87,0xba,0xa5,0xb6,0x62,0xc7,0xad,0xd0,0x4,0xa8,0x55,0x8e,0x43,0x48,0xed,0xd6,0x66,0xe8,0x9,0x4e,0x36,0xe3,0xb5,0xcd,0xf0,0xf5,0x53,0x4d,0x72,0xb,0x47,0xb0,0x69,0xe0,0xbc,0x83,0xae,0x6a,0x2c,0xf7,0x76,0xa0,0xb5,0xc6,0x6c,0x63,0x1b,0x52,0x52,0x69,0x49,0xf4,0x7e,0xa5,0xcc,0x8a,0xf6,0x47,0x80,0x7,0x17,0xd9,0x70,0x21,0x4a,0x56,0x9a,0x82,0x2d,0xcc,0x91,0xf2,0x31,0x9b,0xd9,0x6,0xaf,0xc7,0x0,0xef,0x25,0xb4,0xae,0x72,0xce,0x63,0xca,0xe1,0x4b,0x51,0xf,0x80,0x80,0x35,0xfd,0xca,0x31,0x58,0xd5,0x3a,0x5f,0xd7,0x53,0xd1,0x4d,0x52,0xc7,0xab,0xaa,0xca,0x76,0x5e,0x17,0x23,0xfa,0x7e,0x89,0x8d,0xad,0x23,0x59,0x21,0x3b,0x9b,0x6f,0xf2,0x83,0xa7,0x31,0x1e,0x20,0xa9,0x7e,0x3,0x5b,0xbe,0xfd,0x24,0xce,0x23,0xc1,0xbe,0x1c,0xd7,0x80,0xf1,0x21,0x42,0x3c,0xe4,0x21,0x4f,0x99,0x32,0x65,0xca,0x94,0x29,0x53,0xe6,0xef,0x37,0x45,0x1,0x58,0xa6,0x4c,0x99,0x9f,0xd9,0x9c,0xbd,0xe3,0xdd,0xa4,0x0,0xc,0xa9,0x48,0x22,0x4c,0x7c,0x98,0x31,0x2b,0x5f,0x48,0xa9,0xa2,0xc6,0x52,0x0,0xe,0xd2,0x4f,0xb0,0x6f,0xc,0x14,0x17,0xf9,0x46,0x3a,0x3,0xc1,0xc,0xe3,0x8,0x36,0x91,0xea,0x2e,0x66,0x5,0x5d,0x56,0xfc,0xc5,0x51,0x5,0x26,0xa5,0x1e,0x5b,0x4b,0x19,0xda,0x65,0xe5,0xdf,0x34,0xb7,0x4e,0x2a,0x2e,0xf1,0xf0,0xb9,0x30,0x23,0xdd,0xcc,0xa4,0xd7,0xc4,0x38,0xb6,0x18,0xa6,0x1b,0x26,0x80,0xd5,0x85,0x9e,0xac,0x8f,0x31,0xfa,0xfc,0xfe,0x29,0xf7,0x4f,0x29,0x52,0x3f,0xc5,0x40,0xbf,0x93,0x6e,0x10,0x25,0x43,0x9,0x52,0xdc,0x50,0x9b,0x70,0xce,0x43,0xf,0x31,0xab,0x13,0x81,0x11,0x90,0x4c,0x33,0x1,0x43,0x60,0xa0,0x87,0x31,0x57,0x70,0xaa,0x90,0x24,0x58,0x91,0x2c,0xd2,0x62,0xb4,0xe3,0x4e,0xe0,0x58,0xda,0xb6,0x72,0x6a,0xd7,0x4c,0x37,0x68,0x93,0xbc,0xc4,0x69,0x17,0x6f,0xda,0xb6,0xa3,0x95,0x6c,0x6c,0x27,0xde,0xf,0xf5,0x56,0xca,0x5d,0x56,0xde,0x33,0x1e,0x28,0x2,0xc9,0xf2,0xc4,0xc9,0xfb,0x1c,0x6c,0x10,0x8e,0x99,0x33,0xc9,0x49,0xeb,0xf2,0xfa,0xc,0x29,0xb6,0xa1,0x63,0xcc,0xd2,0x72,0xd6,0x62,0x67,0xe7,0xda,0x8,0x9d,0xbc,0x29,0x27,0xef,0x21,0xb3,0x75,0xfc,0x54,0x56,0x0,0xd2,0xbe,0xf4,0xfb,0x32,0x1,0xa9,0x24,0x22,0xed,0xdf,0x51,0xed,0x29,0x32,0x28,0xa4,0xd2,0x9f,0x90,0xcf,0x87,0x98,0xb3,0xeb,0x44,0xce,0x63,0x9b,0xe6,0x77,0x26,0x7b,0xfc,0xa,0x78,0xe,0x31,0x2b,0x52,0x63,0x8c,0x30,0xac,0x48,0x4b,0xd,0xb3,0xce,0x98,0x9c,0x11,0x9a,0x0,0x83,0x35,0x3,0xbc,0xb3,0xb9,0x31,0xd7,0x7b,0xcb,0x4a,0x41,0x87,0x18,0x81,0xe5,0xde,0xf5,0xdc,0x5c,0x9b,0x81,0x14,0x2b,0xe,0x83,0xa7,0xfc,0x4e,0x33,0x74,0x18,0xb8,0x88,0x43,0xeb,0x2a,0x2b,0xf3,0x28,0x36,0x80,0x6c,0xad,0x86,0xa1,0x23,0x59,0x9b,0xfb,0xdc,0x4e,0x9b,0x33,0xc,0x19,0xe0,0x64,0xc0,0x91,0x9a,0xba,0x27,0x4a,0xe1,0xe0,0x3,0x15,0x2b,0x48,0x82,0x64,0xfd,0x72,0xf,0x52,0x2a,0x7a,0x60,0xa1,0x58,0xd1,0xcc,0xed,0xca,0xd6,0xe,0xb9,0x4,0x45,0x4a,0x85,0xbe,0x5b,0xf0,0x32,0x48,0x68,0x4d,0xed,0xcb,0x9,0x24,0x4d,0x55,0xbd,0x76,0xe8,0x31,0xc,0xdd,0xca,0xb5,0xab,0xef,0x16,0xfc,0xbb,0x21,0x97,0x6b,0xc4,0x18,0xb3,0xba,0x92,0x94,0x94,0xb4,0xed,0x9c,0xb3,0x18,0xba,0x8e,0xce,0x25,0xde,0xcf,0x5a,0x33,0x5c,0xe5,0xeb,0x76,0x7a,0x40,0x91,0xb2,0x54,0xa7,0xd6,0x4f,0x0,0x70,0xde,0xd2,0x32,0x85,0xc0,0xdb,0x6e,0x40,0x60,0xe5,0x1a,0x29,0xf3,0x38,0x93,0x90,0xf3,0xe4,0x8,0x22,0x87,0xbc,0xbc,0xce,0x59,0x98,0xbe,0xe3,0xe2,0x10,0x2a,0x89,0x49,0x79,0x78,0x82,0xbf,0x4b,0xa4,0x52,0xd4,0xa8,0xab,0x6b,0xbe,0x8e,0x87,0xc9,0x43,0xe,0x2,0x83,0xc9,0x62,0x6b,0x59,0xfd,0x97,0x8e,0xb3,0x74,0xac,0x8,0x41,0xdb,0x4b,0x2a,0x2,0x92,0x60,0xf5,0x9f,0xb3,0x6,0xd6,0x98,0xdc,0xc4,0x1c,0x73,0x26,0xec,0x18,0x7b,0x90,0xa2,0x26,0x8c,0xe9,0xf3,0xb6,0xf0,0x9e,0xca,0x3b,0xfa,0xe5,0xde,0xd8,0x0,0xcd,0xca,0x39,0xcd,0x80,0x2d,0x78,0xcf,0x56,0xe8,0x11,0x22,0x2b,0x5d,0xf3,0x77,0x83,0x5b,0xd9,0x67,0x9,0x2e,0x7a,0xe7,0x38,0x13,0xd0,0x8e,0xe7,0x12,0xb7,0x28,0x23,0x46,0x18,0x93,0x54,0x8a,0x54,0xfc,0x92,0x8a,0x43,0x92,0x75,0x3c,0x78,0xc7,0xd0,0x7b,0xcc,0x8e,0x15,0x10,0x2b,0xf,0x69,0x4c,0xbf,0xcc,0xc0,0x30,0x6,0x4f,0xc5,0x1f,0x75,0x8d,0xa6,0x9d,0x41,0x2a,0xc5,0x4d,0xde,0xf4,0xa0,0x40,0x69,0xc5,0x39,0x8f,0x63,0xd1,0x56,0x2,0xde,0xe3,0xb3,0x81,0xd5,0xea,0x8f,0x11,0x96,0x93,0x6a,0x78,0xb9,0x77,0x1d,0xcb,0x9d,0x2b,0xe5,0xe2,0x5b,0xa6,0x4c,0x99,0x32,0x65,0xca,0xbc,0x3,0x53,0x14,0x80,0x65,0xca,0x94,0xf9,0x99,0x4d,0xb2,0x51,0x41,0xa,0x44,0x17,0x27,0xd,0xad,0xac,0x64,0xe3,0x9b,0xc3,0xc4,0x4,0x13,0xd0,0xf3,0xce,0x65,0x66,0xe3,0xbd,0xcf,0x6a,0xa2,0xa4,0x86,0x4b,0x39,0x5d,0x63,0x1b,0xed,0x58,0x90,0x91,0xb2,0x4,0x63,0x4c,0x4d,0xbf,0xa3,0x8d,0x56,0x65,0x98,0x38,0x81,0x51,0x98,0x96,0x4e,0x50,0x63,0x61,0xba,0xf9,0x4b,0xb6,0x3c,0x25,0xb9,0xf1,0x57,0x33,0x40,0xe4,0x6c,0x30,0x21,0x25,0x44,0x8,0x63,0x61,0x49,0x60,0x80,0x7,0xb0,0x92,0x47,0xb3,0xaa,0x6d,0x52,0x0,0xa2,0x34,0xa2,0xa,0x79,0x9d,0x92,0xdd,0x91,0x32,0xd2,0x64,0x6,0x6b,0x54,0xec,0x21,0x56,0xda,0x82,0x95,0x5e,0x55,0x9e,0x80,0x95,0x94,0x80,0xc8,0x37,0xed,0xd3,0x2,0x8e,0xa9,0x1d,0x3a,0x38,0x8f,0x18,0x5,0x54,0x52,0x66,0xa4,0xf7,0xc5,0x98,0xd,0x38,0x16,0x6f,0xd0,0xfb,0x25,0x85,0x50,0xde,0x1e,0x29,0x80,0x3e,0x8c,0x50,0x30,0x17,0x28,0xac,0x28,0x4a,0xc0,0x37,0xbf,0x7a,0x84,0xb7,0x2b,0xfb,0x58,0x64,0x8b,0x68,0x6e,0xad,0xe4,0xd7,0x25,0x50,0xb2,0xa2,0xc2,0xc4,0xa8,0xe,0xd9,0x9f,0x31,0x37,0xb6,0x20,0xc7,0x9c,0x73,0x8,0x8c,0x65,0x25,0x29,0x1b,0x71,0xa,0x1,0x3,0xe7,0x28,0x62,0x52,0x70,0x12,0xbc,0x87,0x1f,0x16,0x80,0x28,0x5f,0x8b,0x6f,0x35,0x63,0xf3,0x35,0x43,0x9,0x29,0xe9,0x8f,0xbc,0x97,0xb2,0xbd,0x33,0xd2,0xf9,0x21,0xf9,0x7c,0x49,0xaa,0xd0,0x4,0x7f,0xc4,0x4,0x60,0x4b,0xa9,0xc6,0xde,0x1a,0xde,0x57,0xde,0x79,0x86,0x80,0x1,0x31,0xca,0xb1,0x78,0x86,0x81,0x39,0x41,0x23,0x82,0x25,0x9,0xc,0x5d,0x7e,0xe3,0x27,0xa8,0x9b,0x19,0xa9,0xb5,0x66,0x54,0xca,0x30,0xf4,0xb,0xcc,0x36,0xb6,0xa1,0x18,0x98,0x78,0x86,0xf7,0x55,0xdd,0x50,0xd1,0x2,0xdb,0x75,0x93,0x4d,0xd5,0x39,0x9b,0xa1,0x8c,0xe9,0x96,0xb0,0x5c,0x7a,0xa0,0xab,0xa,0x8b,0xdd,0x6b,0x9c,0xf,0xe8,0xb9,0xad,0x76,0x40,0x33,0x9b,0xa3,0x69,0x48,0x69,0x95,0xca,0x33,0x94,0xaa,0xa8,0x9c,0xc1,0xc,0xe8,0xf6,0x76,0x11,0x82,0x47,0xa1,0x82,0x73,0x7a,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xdd,0xce,0x32,0x6c,0x32,0xa6,0xe7,0x68,0x4,0xc9,0x20,0x47,0x70,0x76,0x28,0x29,0xb3,0xaa,0xba,0xcd,0x96,0xf7,0x94,0x77,0x67,0x4c,0xcf,0xcd,0xac,0x54,0x2e,0x51,0xb7,0x33,0xb6,0x91,0xe,0xc,0x5c,0xa9,0x19,0xb8,0x5b,0xec,0x2,0x10,0xb0,0x43,0xcf,0xf,0x14,0x54,0x7e,0xf8,0xa0,0xab,0x26,0xdb,0x45,0xed,0xd0,0xe5,0xed,0x6f,0x4d,0x9f,0xdb,0x73,0xeb,0x86,0x54,0x7e,0x52,0x2a,0x5a,0xbf,0x76,0x6,0xef,0x2c,0x86,0x1e,0xb9,0xc,0x9,0x18,0x6d,0xc7,0x75,0xd3,0x60,0xf7,0xfa,0x55,0x78,0xef,0xd0,0xb4,0xf3,0x9,0x98,0x33,0xa8,0x9b,0x36,0x3f,0xb4,0x90,0xdc,0xc8,0x5b,0xd5,0x4d,0xbe,0x56,0x78,0x6f,0xa9,0x21,0xd8,0x5a,0x84,0x18,0x73,0xf1,0x10,0x20,0xd0,0x2f,0x17,0x94,0x7b,0xc8,0xc0,0x2d,0xf2,0x76,0x49,0x2a,0x36,0xa5,0x36,0x60,0xc3,0x0,0x6f,0x1d,0x35,0xc2,0x73,0x86,0x63,0xc8,0xc0,0xd6,0x41,0x71,0xd1,0x5,0x59,0xaf,0x67,0xe8,0xfb,0x25,0xaa,0xaa,0xce,0x2d,0xc8,0xe9,0x61,0x8f,0x10,0x12,0x75,0x3b,0x83,0xe9,0x97,0xc,0xfd,0x3c,0x6c,0x1c,0xf2,0xba,0x2a,0x2e,0xa0,0x52,0xba,0x62,0xb5,0x69,0xb,0x3b,0x4c,0x81,0x73,0xcf,0xd7,0x3b,0x7a,0x28,0x94,0xde,0x23,0xc7,0x2f,0xf0,0x71,0x57,0x37,0x33,0x74,0xac,0x24,0xcc,0xf1,0xb,0xc,0x62,0xd3,0x75,0xb7,0x5f,0xec,0xae,0xb4,0xd9,0x27,0x6b,0x77,0x33,0x9b,0xe7,0xed,0xa4,0x39,0x7f,0x52,0x48,0x5,0xa9,0x34,0x36,0x36,0x8f,0xa0,0x5b,0xee,0xc2,0xe,0x3,0xfa,0x7e,0x41,0x65,0x22,0xbc,0x3d,0x8d,0xae,0xd0,0xce,0x36,0x72,0x8e,0x61,0x33,0x9b,0xc3,0xf4,0x1d,0x35,0x3,0x3b,0x83,0x18,0x22,0x9c,0x95,0x13,0xdb,0x38,0x72,0x7b,0x70,0x88,0x81,0xb2,0x23,0x43,0xe0,0x66,0xf7,0xd5,0x7,0x2f,0xa6,0xef,0x8,0xdc,0xb2,0x7d,0xd8,0x9a,0x1,0xb3,0x8d,0x2d,0x3a,0xff,0x38,0x33,0x30,0xfa,0xc8,0xaa,0x5e,0x3f,0xc9,0x6e,0x94,0xe3,0x77,0xaf,0x90,0xa3,0xaa,0x7b,0x8d,0xe2,0x2f,0x95,0xa6,0x94,0x29,0x53,0xa6,0x4c,0x99,0x32,0x65,0xde,0x99,0x29,0xa,0xc0,0x32,0x65,0xca,0xfc,0xcc,0xe6,0xa6,0xdb,0xef,0xe5,0x20,0xf5,0x90,0x1,0xdd,0x3e,0x42,0xb8,0xda,0xdc,0xcb,0x20,0x46,0x2a,0xb6,0xfa,0x9,0x99,0x6d,0x72,0x49,0x39,0x4,0x56,0x4,0x25,0xa5,0x97,0x94,0x8a,0x83,0xf4,0x45,0x56,0x0,0xe6,0x9b,0x8f,0x10,0x50,0x35,0xed,0x8a,0x8a,0x48,0x24,0x28,0xc8,0x1,0xee,0x92,0x2d,0x6e,0x9,0x3c,0x69,0x56,0x1f,0x26,0x70,0x98,0x8a,0x41,0x52,0x66,0x5e,0x4,0xe5,0x16,0xe5,0xfc,0x41,0xb6,0x33,0x66,0x85,0x8f,0x94,0xac,0xe6,0x88,0x19,0xa8,0xa5,0xa6,0x4b,0x6a,0xf7,0x1d,0xb,0x51,0x24,0xe7,0x87,0xa5,0x36,0xcc,0xb1,0x9d,0x78,0xf2,0xf9,0xdc,0x96,0x99,0x15,0x19,0x21,0x70,0xb6,0xe1,0xa4,0x65,0x97,0xed,0x98,0x54,0xb0,0x42,0x40,0x4e,0x48,0xc5,0x10,0x91,0x6e,0x2c,0x33,0x58,0xf3,0x3e,0xc7,0xad,0x8f,0x99,0x8b,0x4,0xe2,0x48,0x95,0x48,0xeb,0x97,0x6e,0xdc,0x23,0xc3,0x1a,0x5a,0x26,0xca,0x40,0x9c,0x2a,0xa,0x63,0x8c,0x4,0x56,0xc3,0x8,0xe3,0x90,0xcb,0x2,0x26,0x6d,0xae,0xb4,0x14,0x63,0x98,0x3c,0x67,0xb1,0x65,0x15,0xe3,0x4,0xd4,0x8a,0x49,0xc3,0xaf,0x98,0x6c,0xdb,0x4,0xfd,0xd2,0xef,0xc9,0x74,0x3c,0xc4,0x7d,0x65,0x26,0x13,0x33,0x19,0x26,0xb0,0x97,0x0,0xa2,0x1c,0x8b,0x1d,0xd8,0x66,0x6e,0xcc,0x80,0xdd,0x6b,0x57,0x20,0x94,0x86,0xf7,0xb6,0x28,0x0,0xdf,0x62,0x36,0x8f,0xdc,0x80,0x13,0xa7,0x6e,0x42,0xce,0xf7,0x2,0xb2,0x75,0x53,0x8a,0x49,0x66,0xe5,0x44,0xa5,0x3a,0x55,0x7e,0x52,0xc6,0xa4,0xca,0xc0,0x4d,0x48,0x99,0xdb,0xbe,0xc7,0x7f,0x5b,0x85,0x27,0x74,0xbc,0x70,0x39,0x8d,0xd2,0x70,0x6e,0x2c,0x71,0x48,0xe7,0x1,0x65,0x9d,0xd5,0x18,0x86,0x8e,0xed,0xfc,0x64,0x25,0x35,0x43,0x87,0xaa,0xaa,0x33,0x44,0x1a,0x96,0xb,0xb6,0x7b,0x7,0x74,0x8b,0x5d,0x78,0x6b,0xb1,0xdc,0xdb,0x41,0x2a,0x1,0x19,0xba,0x25,0x4c,0xbf,0xcc,0x65,0xe,0xa4,0x1c,0x24,0x15,0x9f,0x1d,0xfa,0xfc,0xd9,0x9,0xda,0x69,0x2e,0x52,0x48,0xc7,0x7d,0x5a,0xcf,0xbe,0x5b,0x60,0xe8,0x16,0xd0,0x55,0x85,0x2b,0x97,0x2e,0x62,0x36,0xdf,0x84,0xd6,0x1a,0x2d,0x37,0x16,0xc7,0x89,0x4d,0x5d,0x4a,0x1,0xa5,0x2a,0x6e,0x1c,0x26,0x10,0xef,0xcc,0xc0,0x2a,0xb1,0x1,0xce,0x59,0xd4,0x75,0x8b,0xc5,0xee,0x35,0x34,0xed,0x1c,0x75,0x4b,0xb9,0x77,0x55,0xd5,0x64,0xc5,0x59,0xca,0x6e,0xb3,0x66,0x40,0xb7,0xdc,0x81,0xd2,0x3a,0x2b,0xb9,0x2,0x5b,0x4d,0x53,0xa1,0x3,0xe5,0xde,0x75,0x9c,0x67,0x47,0xf6,0xd6,0xe0,0x1c,0xd9,0x88,0xbb,0x45,0xb6,0xf0,0x46,0xce,0xa1,0xd3,0x55,0x9d,0x1f,0x54,0xf8,0xbc,0xfe,0xc8,0xad,0xb9,0xde,0x59,0x98,0xbe,0x47,0xd5,0x34,0x64,0x6d,0x96,0x12,0x75,0xd3,0xe6,0x7,0x4,0xc9,0x3a,0x9a,0xce,0x47,0x3f,0xc9,0x65,0x9c,0x7e,0x17,0xc4,0x9,0x4,0xc,0xc1,0xc3,0x99,0x1,0xcb,0xc5,0x6e,0xfe,0x3b,0xb5,0x2b,0xd3,0xf7,0xc1,0xd0,0x2f,0xb9,0xfd,0x37,0xa9,0xf1,0x48,0xc1,0xe6,0xad,0xc5,0xd0,0x93,0xfa,0x71,0xe8,0x96,0xc,0xb,0x9,0x36,0xa6,0xd2,0xd,0xba,0x16,0xa4,0x7,0x3d,0x9,0x2a,0x53,0x23,0xb2,0xe9,0x3b,0x56,0xf3,0x79,0x86,0x5a,0x4,0x46,0xbd,0x77,0xfc,0xbe,0xa,0xa6,0x5f,0xe6,0xfc,0xc8,0xbe,0x5b,0x64,0xe0,0xe5,0xb8,0x35,0x3e,0x1d,0xf3,0xd6,0xc,0xac,0x8c,0xa6,0xb2,0x12,0xcf,0x76,0x5d,0xef,0x1d,0xef,0x5f,0x97,0xd5,0x9b,0x4a,0x13,0xc0,0xb5,0x49,0x6d,0xca,0x85,0x2a,0x43,0xbf,0x24,0x7b,0xf6,0x72,0x41,0xd6,0x79,0x41,0xd6,0xf9,0xb4,0x3f,0x10,0x23,0x86,0x61,0x99,0x15,0x98,0x49,0x19,0x98,0xa,0x3f,0xf2,0xff,0xb1,0xfa,0x36,0xb5,0xf8,0x7a,0x6b,0x30,0x30,0x60,0xb5,0x66,0xc0,0xd0,0x2f,0x31,0xf4,0x4b,0x52,0xc5,0x3a,0xb,0x44,0xda,0xef,0xd3,0x58,0x7,0x2,0xbf,0x96,0x95,0x82,0xf4,0xf7,0xb4,0x1f,0xda,0xd9,0x9c,0x1e,0x62,0x29,0x45,0x45,0x26,0x32,0x65,0xfb,0xfa,0x49,0x49,0xd5,0x34,0x7e,0x2,0xf9,0x21,0x4c,0xce,0xbf,0xe5,0x7,0x8,0x53,0xd5,0xae,0x77,0x16,0xdd,0x62,0xa7,0x28,0x0,0xcb,0x94,0x29,0x53,0xa6,0x4c,0x99,0x2,0x0,0xcb,0x94,0x29,0xf3,0xf3,0x3e,0x67,0xef,0x78,0x37,0x9a,0x66,0x96,0x43,0xbd,0x31,0x16,0xd,0x12,0xf4,0xe2,0x1b,0xb1,0xa4,0xc8,0x22,0x98,0xc4,0x39,0x61,0x18,0xf3,0xf7,0x12,0x7c,0x2,0x48,0x8d,0x41,0x37,0xe,0x80,0xae,0xeb,0x31,0x58,0x9e,0x95,0x1c,0x62,0x62,0xeb,0x4d,0x37,0xbd,0x4a,0xab,0xac,0x42,0xa2,0xb0,0x72,0x95,0x95,0x1f,0x19,0x62,0xa9,0x8a,0x55,0x29,0x3e,0x83,0xc7,0xd1,0x92,0x1b,0xb2,0xd5,0x38,0x65,0xf8,0xa5,0x1b,0x36,0x0,0x39,0xd7,0x8,0x13,0x80,0x47,0x37,0xab,0x7a,0xcc,0xc9,0x13,0x63,0x66,0x5e,0xb6,0x1f,0xc7,0xb8,0xa6,0x61,0x57,0x8d,0x96,0x47,0x86,0x6a,0x9,0x34,0x46,0xb6,0xf7,0x86,0x30,0x2d,0x4a,0x19,0xb7,0x77,0x82,0xa4,0x54,0x66,0x22,0x27,0x4a,0xbb,0x4c,0xc7,0xb2,0x8a,0x4e,0x4a,0x95,0x8b,0x30,0x4,0xb7,0x55,0x8e,0xca,0x3e,0x4c,0x9a,0x1a,0x45,0xde,0x27,0xb9,0xd5,0x92,0x33,0xa7,0x30,0x29,0x2c,0x51,0x5a,0xe5,0x9b,0xe6,0xdc,0xd6,0x31,0xb1,0xe1,0x66,0x7b,0xf6,0x24,0xd4,0x1e,0x13,0xb0,0xb7,0x2,0x85,0x27,0x37,0x8a,0xb4,0x4d,0xf4,0xa4,0xbc,0x44,0x8d,0x79,0x7e,0x62,0xb4,0x90,0x61,0x5f,0x41,0x89,0x90,0x49,0xfd,0x28,0xf7,0x39,0x80,0x27,0xea,0x92,0x4,0x1a,0xac,0xc5,0xd5,0x2b,0x97,0x20,0x10,0x11,0x7c,0x44,0xf4,0x43,0x39,0x79,0xf,0x99,0xad,0xe3,0xa7,0x71,0xfc,0xd4,0x99,0x95,0x46,0xec,0xb4,0x7f,0xf3,0xae,0xc0,0x58,0x4c,0x33,0xee,0x2b,0xb6,0xee,0xcb,0x11,0x96,0xc9,0x49,0x9e,0x1a,0x81,0x19,0xce,0x3a,0xe3,0x63,0x2b,0x1d,0x1b,0x4,0xb3,0xc,0x42,0x70,0xd9,0xd2,0x9f,0x5b,0xb3,0xf9,0xb3,0x82,0x27,0x95,0x9d,0xe4,0x86,0x59,0xad,0x2b,0x2c,0xf7,0x76,0x48,0xbd,0xc5,0xaa,0x41,0x2a,0x51,0x20,0xd0,0x4e,0x96,0x59,0x2,0x84,0xba,0xaa,0x73,0xe6,0x5b,0x55,0xd7,0xdc,0xda,0xea,0x8,0x6,0xe,0x1d,0x37,0xb5,0x2e,0xa1,0xb4,0x26,0x55,0x1b,0x22,0x95,0x74,0xf0,0xf5,0x88,0x40,0x5c,0xc8,0xb9,0x86,0xd6,0xa4,0x62,0x8d,0x3e,0x5f,0x1b,0x84,0x10,0x2b,0xad,0xb2,0x4a,0x29,0x2,0x2c,0x7c,0xfd,0x8,0xc1,0x43,0xeb,0x3a,0x97,0x82,0x38,0xb6,0x26,0x3,0x11,0x43,0xb7,0x40,0x88,0x14,0x7,0x20,0xa5,0x42,0xd5,0x34,0xe3,0x75,0x91,0xb7,0x5f,0xb2,0xb6,0x52,0xf3,0x2d,0xbd,0xb6,0x5f,0x2e,0xb8,0x55,0x56,0x61,0xe8,0xa9,0xb0,0xc1,0x3b,0xb,0xe7,0xa8,0x38,0x89,0xd4,0x8e,0xbb,0x94,0x23,0xe7,0x28,0x73,0x4f,0xb0,0xcd,0x39,0x65,0xbe,0x51,0x53,0x2c,0xc7,0x1d,0xf0,0x43,0x81,0x4,0x88,0x9c,0xb3,0x30,0xa6,0x27,0xe8,0xc8,0x2d,0xc0,0x4a,0x6b,0xca,0x5f,0x54,0x12,0x4a,0xd7,0xa4,0x4c,0x4e,0x56,0xec,0xf4,0x40,0x64,0x52,0xa0,0x21,0x79,0xbf,0xa7,0x6b,0xa3,0x52,0x8a,0xad,0xc0,0x7d,0xce,0xcb,0x8b,0x93,0xe2,0x97,0x74,0x1d,0xf0,0x6c,0x77,0xf5,0x6c,0x6d,0x75,0x96,0x72,0x1c,0x23,0x22,0x96,0xbb,0xd7,0xf2,0x77,0xc,0xd9,0xbe,0x1d,0xaa,0xaa,0xe2,0x87,0x38,0x81,0x23,0x26,0x62,0x56,0xea,0xa5,0xe3,0x48,0x4a,0xfa,0xec,0xaa,0x6e,0xd9,0x56,0xdc,0xc3,0x1a,0x3,0xef,0xa8,0x5c,0xc3,0x59,0x43,0x16,0xe3,0xac,0x26,0x75,0x19,0xea,0xd,0x5c,0x8e,0x21,0x55,0x7a,0xa0,0x44,0xfb,0x31,0x7d,0xef,0x0,0x93,0x78,0x7,0x3e,0x6e,0xfa,0x6e,0x91,0x41,0xf3,0xb4,0x60,0x26,0x78,0x82,0xb1,0x31,0x46,0x52,0xd9,0x21,0x66,0x1b,0x71,0x7a,0xd8,0x35,0xb5,0x29,0xa7,0x3f,0xa7,0xed,0x19,0x2,0xef,0x4b,0x29,0xc8,0x42,0xcc,0xf0,0x94,0xa0,0xf7,0x1e,0x95,0x78,0x64,0x9b,0x3c,0xdb,0xe1,0x9d,0x45,0x55,0x35,0xb9,0x8d,0xb9,0x6e,0xda,0x31,0x2,0x22,0x7d,0x57,0xf2,0xf7,0x5a,0x8,0x1,0x43,0xdf,0x65,0x58,0xaa,0x75,0x95,0x1b,0x87,0x53,0xee,0x65,0x6a,0x7c,0xa6,0xaf,0xbe,0xd5,0xf2,0x8f,0x51,0x1,0x39,0x29,0x8b,0x5a,0xb1,0xfd,0x87,0x6c,0x1,0xf6,0x21,0x72,0x9,0x48,0x1,0x80,0x65,0xca,0x94,0x29,0x53,0xa6,0x4c,0x1,0x80,0x65,0xca,0x94,0xf9,0xb9,0x9e,0x33,0xb7,0xdd,0x8d,0x76,0xb6,0x91,0x9f,0xe6,0x67,0xe0,0x94,0x2c,0x52,0x62,0x2c,0xcc,0x20,0xc8,0x27,0x73,0x38,0xf9,0xd8,0x4e,0xe8,0x73,0x31,0x6,0xdd,0x88,0xca,0x6c,0x9d,0x4a,0x20,0x8d,0xda,0x79,0xb9,0x20,0x84,0x3,0xc6,0xb5,0xae,0x18,0xfe,0x88,0xdc,0xb0,0x28,0x85,0x80,0xe6,0x1b,0x14,0x7a,0x1f,0x86,0x77,0x5a,0x67,0x68,0x98,0x40,0x84,0xe4,0x9b,0xf6,0x54,0x2a,0x92,0x6e,0x1c,0x33,0x3c,0x62,0xeb,0x62,0x56,0xf4,0x31,0xec,0x4a,0x2a,0xbc,0xd4,0xb4,0x9,0x90,0xa5,0x2a,0x29,0x26,0xe8,0x26,0x9c,0xa,0x4c,0x92,0x22,0x2d,0x4c,0x94,0x51,0x23,0xab,0x13,0xb9,0xed,0x18,0x49,0x61,0xc4,0x37,0x47,0xba,0xaa,0x79,0x1d,0x54,0x6,0x83,0x63,0x9b,0x72,0xc8,0xaa,0xbd,0xc0,0xd,0xc9,0x48,0x8a,0x3e,0x2e,0xfa,0x48,0xcb,0x98,0xb2,0xd4,0x14,0xb7,0x44,0x4e,0xf3,0xd,0x93,0xc5,0x5a,0x29,0xc5,0x4a,0x13,0xe4,0x36,0x5f,0x52,0x1,0x4a,0x84,0xd4,0xd0,0x9b,0xb3,0xd8,0x30,0xc9,0xab,0x92,0xbc,0x4e,0xac,0x48,0xc4,0xa8,0xf6,0x9b,0x4e,0x98,0xe4,0x39,0x8a,0x89,0x65,0x3b,0xa9,0xff,0xa6,0xd6,0xe3,0x74,0xe3,0x98,0xda,0x2c,0xe3,0xc4,0x46,0x9c,0x5b,0x7e,0xf7,0xe7,0x19,0x62,0x54,0xd,0x62,0x9f,0x7d,0x38,0xad,0xa3,0x35,0x3d,0xae,0x5f,0xbd,0xc,0x1f,0xc8,0x66,0xed,0xcd,0xb2,0x9c,0xbc,0x87,0xcc,0xf6,0xb1,0x53,0x38,0x7e,0xf2,0xc,0xc6,0x86,0xcf,0x64,0x7f,0xf,0x93,0x56,0x68,0x3a,0x23,0xd4,0xb4,0x78,0x6,0x23,0xfc,0x27,0x45,0x27,0x95,0x58,0x44,0x56,0x62,0x66,0x75,0x60,0xb2,0x9c,0x13,0x31,0xa7,0x7d,0xe4,0x5c,0xce,0xe3,0x4c,0xef,0x4f,0xad,0xc3,0x9a,0x14,0x69,0x29,0xc3,0x53,0x49,0x4,0x1f,0xc8,0x6e,0xcb,0xd7,0x15,0x29,0x15,0xfa,0xe5,0x1e,0xf6,0xae,0x5f,0x41,0xc,0x3e,0x2b,0xf8,0x28,0xcb,0x8c,0xac,0x90,0x43,0xbf,0xcc,0x56,0x4e,0x6a,0x39,0x75,0xb9,0x2c,0x44,0x30,0xb8,0x57,0xc,0x10,0x53,0x96,0x5e,0xdb,0x6e,0x10,0xc,0x4c,0xe7,0x0,0xb7,0x12,0x27,0xc0,0x63,0x19,0xe0,0xf4,0xcb,0x3d,0xc4,0xe0,0xd1,0xb4,0x73,0x8,0x1,0xb4,0x5c,0x90,0xb0,0xba,0x2d,0xc6,0x12,0xa1,0xb1,0x18,0x89,0x40,0x13,0x65,0xcc,0xd,0x59,0xdd,0x56,0x37,0x2d,0x65,0x8,0x32,0x18,0x1d,0x73,0x45,0x5d,0x2e,0xb8,0x10,0x2,0xe8,0x97,0xa4,0x3e,0x1c,0xfa,0x8e,0xc1,0xe9,0x8,0x8c,0x92,0xb5,0x7f,0xda,0xb8,0xbc,0x5c,0xec,0x62,0xe8,0x16,0xdc,0xaa,0xdc,0x42,0x71,0xb1,0x8,0x4,0x48,0xcd,0x87,0xd4,0x6c,0x4e,0xd0,0xd6,0x5a,0x43,0xed,0xc8,0xc6,0xe4,0xa2,0x87,0x8a,0x1,0x90,0xd8,0x67,0x85,0x4d,0x6a,0xe9,0xa4,0xbe,0x9b,0x3e,0xb0,0xa0,0x52,0x11,0xca,0xc4,0x4b,0x6d,0xc5,0x40,0x24,0x38,0xc5,0xb0,0x32,0x95,0xb7,0x8c,0xf,0x4d,0x18,0x46,0x45,0x4f,0x9f,0xc7,0xc7,0x44,0xca,0x6d,0xb4,0x76,0xa0,0x3c,0x40,0x1f,0xd0,0xb4,0x73,0x34,0x2d,0x29,0x2e,0x55,0x55,0x73,0x61,0xd2,0xd8,0x7c,0x9b,0x4a,0x82,0x42,0xc8,0x3e,0x54,0xb2,0x61,0xf3,0xbe,0x4d,0x56,0x75,0xe7,0x2c,0xa4,0x50,0x19,0x48,0x7a,0xb6,0x8a,0xa7,0xeb,0xb3,0xe3,0x7,0x4d,0xc1,0x7b,0x54,0x55,0x8d,0xe0,0xdc,0xc4,0x12,0xae,0x56,0xae,0xf3,0x69,0x7f,0x99,0xa1,0x23,0x4b,0x77,0x47,0xd7,0x9b,0x4,0x6f,0xff,0x7f,0xf6,0xde,0xf4,0xc9,0x96,0xb3,0x3e,0x13,0x7c,0xde,0x2d,0xf3,0x9c,0xaa,0xba,0x8b,0xee,0xa2,0xe5,0x6a,0x5f,0x90,0xd0,0x86,0x4,0x88,0x45,0x60,0xcc,0xe,0x36,0x6,0x6,0x43,0x77,0xbb,0xc3,0xf6,0x78,0x3a,0x66,0xa2,0xbb,0xe7,0xcb,0xfc,0xf,0xfe,0xb,0xe6,0xc3,0xc4,0xc4,0x84,0x63,0xa6,0x27,0x3a,0x3c,0xee,0xee,0xb1,0xc7,0xb8,0xdd,0xb4,0x31,0x66,0x6b,0x30,0x8b,0xd,0x18,0x21,0x4b,0x20,0x90,0x40,0x8,0xb4,0x2f,0xf7,0xea,0xae,0x75,0xab,0xce,0xc9,0xcc,0x77,0x99,0xf,0xbf,0x25,0xf3,0x54,0xd5,0x15,0xc2,0xe6,0x46,0xe0,0x1b,0xef,0x43,0x8,0x55,0x9d,0x3a,0x27,0xd7,0x37,0xf3,0xe8,0x7d,0xf2,0x59,0xe2,0x40,0xf6,0x69,0x22,0xa4,0x83,0x36,0x3d,0xcb,0x77,0x82,0x3c,0xb0,0x9a,0x5e,0x73,0xd3,0xef,0xa2,0xc8,0x19,0xb3,0x5b,0xe7,0x4e,0x6b,0x89,0x8e,0x2c,0x9f,0xe9,0x79,0x2a,0x50,0xe1,0x32,0x1b,0x29,0x6e,0x91,0xac,0xc4,0xa6,0x9d,0xe9,0x3,0x22,0x51,0x6b,0x13,0xa9,0x9,0xce,0xe5,0x8b,0x9a,0x31,0xb8,0x79,0xe6,0x24,0x9c,0xf7,0xf0,0xd,0x95,0xec,0xf8,0x10,0x68,0xdb,0xe4,0x61,0xd6,0x84,0xf4,0x9f,0xb6,0x79,0x4f,0x9e,0x16,0x8c,0xdf,0x79,0x30,0x2b,0xf,0x8e,0x72,0xe1,0xc,0xc0,0xcd,0x33,0xd8,0xde,0x3c,0x5d,0x6f,0xbe,0x15,0x15,0x15,0x15,0x15,0x15,0x95,0x0,0xac,0xa8,0xa8,0xf8,0x65,0xc6,0x35,0x5c,0x2,0x92,0x35,0xe4,0x7f,0x65,0xfa,0xb7,0xa2,0xf0,0x1b,0x9b,0x0,0xc7,0x5c,0x36,0xe7,0x1c,0xe5,0x1c,0xf1,0x44,0x92,0x26,0x2c,0x11,0xc6,0x1a,0xd,0x1a,0x97,0x96,0x42,0x23,0x45,0x22,0x28,0x9a,0xf3,0x4,0x50,0x89,0x88,0x28,0x70,0xc8,0xaa,0x2a,0x96,0x5e,0x9a,0x9c,0x84,0xd0,0x12,0xf1,0x67,0x3d,0x11,0x75,0x39,0xf1,0x44,0xbe,0xa8,0x1d,0x56,0xb3,0xaf,0x98,0x94,0x72,0x6c,0xc5,0x5a,0xb5,0xe0,0x12,0x59,0x41,0xb9,0x46,0xa3,0x3d,0x51,0x26,0xba,0x42,0x54,0x69,0x6e,0x9d,0x2a,0x1f,0x9,0x96,0x27,0xb5,0xa2,0xa8,0x33,0xc6,0xc0,0xf1,0x4,0x52,0xa6,0x46,0x62,0xd1,0xd5,0xe5,0x1a,0x4c,0x88,0x2f,0xb1,0xd,0x2b,0x23,0x49,0x8d,0x99,0xac,0x1e,0xcc,0x29,0x69,0xb8,0xfc,0x98,0x95,0x37,0x2a,0x48,0xec,0x84,0x6c,0x95,0xe5,0x58,0xc7,0x99,0x88,0x9c,0x3b,0x45,0x25,0xbe,0x99,0x49,0x11,0x3a,0x2f,0x96,0x15,0x81,0xc6,0xec,0x6c,0x17,0xce,0x93,0xdf,0xc7,0x63,0x31,0x12,0x9f,0x46,0xed,0xdd,0x63,0x6e,0x63,0x61,0x32,0xb6,0xa8,0xa,0xc,0x13,0xc5,0x24,0x0,0xfd,0xcc,0x98,0x21,0x38,0x99,0x48,0x4e,0x8f,0xcb,0xe4,0x77,0x7d,0x41,0x3b,0x5a,0x1,0x94,0x4c,0x36,0x6d,0x6e,0x2,0x3d,0xfd,0xf2,0x71,0xb2,0x6e,0x17,0x83,0xdc,0x6f,0xd5,0x8b,0xf7,0x2,0xd8,0xb8,0xec,0x72,0x5c,0x76,0xe4,0x4a,0x55,0x72,0x96,0x15,0x95,0xe7,0xc4,0xa6,0x3d,0x55,0xfc,0x58,0xb3,0x43,0xf9,0x33,0x8e,0xb,0x39,0xf7,0x74,0xde,0x93,0xaa,0x6,0x85,0x54,0xb4,0x86,0xaf,0x7,0x6b,0x28,0x3f,0x33,0x67,0x2d,0xf7,0x90,0x2c,0x3e,0x51,0xad,0x92,0x45,0x9d,0x14,0xb0,0x8e,0x7f,0x86,0x31,0x4c,0x9a,0x79,0x78,0x56,0x38,0x49,0xe1,0x46,0x2e,0x49,0x33,0xce,0x44,0x1d,0xe7,0xb8,0x2d,0x38,0x27,0x22,0x5c,0x84,0x44,0xc,0x4d,0xab,0x84,0x9b,0xe4,0x7c,0xd2,0x43,0x1,0xaf,0x64,0x9a,0x28,0xb3,0x32,0x93,0x1f,0x63,0xc9,0x90,0x63,0x22,0x6d,0xae,0xa,0xb1,0x69,0xf1,0x90,0xe6,0x5d,0xf2,0x71,0xd3,0x22,0x9,0x56,0x91,0xb9,0x40,0x99,0x82,0x80,0x41,0x68,0x5a,0x5a,0xe,0x5f,0xa3,0x74,0x8f,0xb4,0x4c,0xf0,0x44,0x6e,0x10,0xee,0xc6,0x87,0x18,0x4c,0x60,0x79,0x17,0x54,0x3d,0x16,0x9a,0x76,0x24,0x83,0x98,0x5c,0x6f,0x42,0xab,0xf7,0xbe,0xa6,0x69,0xe1,0x43,0x43,0xcd,0xae,0x0,0x7c,0x33,0xe6,0x2,0x96,0x49,0x63,0xf8,0x48,0xf0,0xd0,0xb6,0x18,0x4b,0xc7,0xcb,0xb3,0x4a,0x5b,0x33,0x58,0xd,0x94,0x9c,0xc4,0xe4,0xde,0x83,0x52,0x34,0x2,0x1,0xa0,0x76,0xd9,0x91,0xec,0x1f,0x33,0x7,0x53,0x1c,0xb0,0xbe,0xef,0x0,0xfa,0xe5,0x2,0xed,0x7c,0xae,0xea,0xea,0xc2,0x24,0xb3,0xb5,0x16,0x7d,0xbf,0x44,0xd3,0xce,0x99,0xa8,0x25,0xf2,0x75,0xb6,0xbe,0x41,0x44,0x34,0x17,0x81,0x8c,0xe3,0x63,0x8c,0x98,0xd0,0xa2,0xa8,0x10,0x38,0x7b,0xd6,0xb0,0x22,0xb4,0xa3,0xe3,0x94,0x13,0x9c,0xb,0xaa,0xc4,0x6,0x17,0x6a,0x58,0x37,0x3e,0x8c,0x12,0x75,0x9d,0xf,0xd,0x93,0xc2,0xa3,0xfa,0x4f,0xca,0x9e,0x44,0x5,0xaf,0xcd,0xe4,0x4c,0xbe,0x1a,0xeb,0xd0,0xb6,0x73,0x6e,0xa0,0x6f,0x91,0x62,0x44,0xd3,0xce,0xe8,0x7b,0x33,0x45,0x6e,0x2,0xe,0xe3,0x98,0x71,0x5e,0x23,0x21,0x7c,0x18,0x95,0x8c,0x42,0x42,0x7b,0xdf,0xe8,0xb6,0xb5,0x6b,0xeb,0xac,0xca,0xc,0x5a,0x28,0x92,0xd8,0xae,0x4c,0x16,0xe3,0xe,0x21,0xd0,0x58,0x6f,0x9a,0x16,0x86,0x15,0x9f,0xd3,0xef,0x4b,0x22,0x9a,0x83,0x7e,0x7f,0x4b,0xc6,0xea,0x74,0xfc,0x84,0xd0,0x60,0xc6,0x16,0xf7,0xcc,0xfb,0xe8,0xe5,0xa1,0x9a,0x73,0x2b,0xd7,0xfc,0x18,0xcb,0x60,0xc7,0xc2,0xf,0xac,0x3e,0xa0,0x91,0xef,0xda,0xcc,0x44,0xeb,0xd6,0xb9,0x33,0x58,0x9c,0x3f,0x53,0x6f,0xbe,0x15,0x15,0x15,0x15,0x15,0x15,0x95,0x0,0xac,0xa8,0xa8,0xf8,0x65,0xc6,0xb1,0x1b,0x6e,0x43,0xbb,0xb6,0xa1,0xca,0x3f,0xb5,0xac,0xae,0xe4,0x1,0x15,0x25,0xb8,0xa6,0x16,0x5b,0x21,0x15,0xd4,0x22,0xc8,0x93,0xb,0xa7,0x13,0xa0,0xc2,0xc1,0xf0,0xad,0x66,0xf,0x49,0x9b,0xae,0xf5,0x9e,0x9,0x0,0xab,0x61,0xfa,0xd3,0x30,0x7c,0xb1,0xfe,0x8a,0xca,0x8f,0x26,0x4c,0x4e,0x6d,0x6f,0x81,0x5b,0x27,0xa5,0x9d,0x58,0x27,0x3f,0x5,0x6a,0x87,0xcb,0xda,0x1e,0x3c,0x92,0x1e,0x32,0xa9,0x2b,0x20,0xf5,0xc2,0x34,0xcb,0x4e,0xca,0x28,0x9c,0xf7,0x2b,0x93,0xe3,0x69,0xc3,0x2e,0x91,0x5b,0x49,0x9,0xcd,0xcc,0xea,0x14,0x9d,0x24,0x95,0xa2,0xc7,0x46,0x32,0x5,0x8d,0xb1,0xda,0xb0,0x48,0xaa,0x28,0xa7,0xa5,0x26,0xa5,0x80,0x15,0x55,0x44,0x14,0x64,0x6e,0x6d,0xd4,0xbc,0x3d,0xde,0x86,0x92,0xd3,0x6a,0xb,0xaf,0x19,0xf3,0x18,0x65,0x9d,0xd2,0x1e,0x2c,0x39,0x84,0x1a,0xe8,0xce,0x24,0x20,0xc,0x4f,0x48,0x85,0x90,0x35,0x63,0x6e,0xa0,0x75,0x74,0xcc,0x73,0x19,0xf3,0x4,0x35,0x1f,0xe,0xa3,0x42,0x4f,0x1a,0x33,0xa7,0x61,0x91,0xa2,0x9e,0x51,0xb,0x39,0x93,0x7f,0x65,0xa2,0xee,0x1b,0x1b,0x85,0xb,0xcc,0xa,0x25,0x8,0x8c,0xf2,0xc3,0xd5,0x7c,0x41,0x6d,0x98,0x9d,0x28,0x0,0x4b,0xce,0xc8,0x43,0x57,0x2d,0xc0,0xaf,0x44,0x0,0x1e,0x38,0x8c,0xc3,0x57,0x5c,0xd,0x0,0xc8,0x93,0xf3,0x37,0x92,0x7b,0x50,0x72,0xdd,0x4c,0xc8,0xeb,0x29,0xe1,0x87,0x15,0x35,0xb0,0x51,0xb5,0xf,0x71,0x3,0x13,0xa5,0xea,0xc4,0xa2,0x49,0x76,0xe3,0xa4,0x96,0x76,0x6a,0x35,0x9d,0x5e,0x77,0x4e,0x6d,0xb8,0x42,0x2e,0x7b,0x1f,0xd0,0xce,0xd6,0xe0,0xac,0x43,0x68,0x67,0x80,0x81,0x12,0x79,0xa1,0x69,0x11,0x9a,0x19,0x96,0xdb,0x5b,0x58,0xdf,0x77,0x40,0x55,0x4e,0x3e,0x34,0x40,0x1,0xda,0xd9,0x9c,0x1f,0xe,0x90,0x55,0x96,0x8a,0x43,0xe8,0xc1,0x42,0xd3,0xcc,0xb8,0xd1,0xb6,0xe8,0x7a,0xe4,0xa1,0x84,0xe1,0x6c,0x51,0x6a,0x57,0x85,0x12,0x84,0xd6,0x58,0x55,0x56,0xc9,0xe7,0x2c,0x5f,0xb7,0x44,0x46,0x19,0xb6,0x29,0xf,0xe3,0x35,0x8,0x51,0xfe,0x66,0xce,0x64,0xb,0x7c,0xef,0xa1,0xd2,0x20,0x18,0xe8,0x3d,0xac,0x94,0x2,0x58,0xb9,0xe6,0xac,0x46,0x20,0xe4,0x52,0x88,0xdc,0x61,0xf2,0x28,0x34,0xd,0xad,0xc3,0xd1,0x75,0x99,0x12,0xd9,0x53,0x73,0x4e,0xd8,0x38,0x70,0x8,0x4d,0x3b,0x43,0x8c,0x3,0x91,0x52,0x25,0xed,0x20,0xff,0xa0,0x4,0x9a,0xe4,0xc2,0x49,0xe6,0x9d,0xe3,0x7b,0xae,0xf3,0x1,0x2e,0x50,0xcc,0x42,0x8,0x8d,0x3e,0xcc,0x91,0x7,0x20,0xa2,0x30,0x16,0x5,0x32,0xf4,0xa1,0xf,0xf4,0xc1,0x49,0xd1,0x56,0xe1,0x49,0x51,0x10,0xaf,0x43,0x48,0x55,0xe7,0xe9,0x58,0x87,0xb6,0x65,0x15,0x79,0xe0,0x16,0x64,0xba,0xe7,0x37,0x5c,0xf0,0x22,0x4,0x58,0xd3,0xb4,0x6a,0x57,0xa5,0xfc,0xd0,0xd5,0xc2,0x22,0xc9,0x9d,0x24,0x65,0xba,0x61,0xeb,0xb3,0xa1,0x42,0xd,0x69,0xc2,0x65,0x62,0x8b,0x88,0x36,0x22,0xc7,0x72,0x4a,0xf0,0x4d,0xa3,0xcd,0xce,0x52,0x48,0x63,0x9d,0xd7,0x66,0x5f,0xe7,0xbd,0x5a,0x7d,0xa7,0x24,0x79,0xce,0x99,0x88,0x47,0x56,0x56,0x5a,0xe7,0xb0,0xef,0xe0,0x61,0x6a,0x5a,0x66,0xa2,0xce,0xf3,0x3e,0xc7,0xbe,0x87,0x75,0x76,0x45,0x2d,0x9f,0x58,0xb9,0x27,0xa,0x70,0x60,0x54,0x9b,0xcb,0x31,0x77,0x9e,0xbe,0x2f,0xbb,0xc5,0x16,0xe6,0xeb,0xfb,0x48,0xad,0xc7,0x24,0xb8,0x6f,0x5a,0x18,0x3,0x34,0xb3,0xb9,0x3e,0xb0,0xa1,0xeb,0xc0,0xc2,0x18,0x52,0x59,0xfb,0x40,0x96,0x60,0xc3,0xdf,0x59,0x72,0x4d,0x82,0xc7,0x7b,0x33,0x9b,0x1,0xfc,0xbd,0x27,0xff,0x78,0x1f,0x58,0xfd,0x3b,0x46,0x49,0x4c,0xb3,0xfd,0xf4,0x18,0xf0,0xfd,0x59,0xc6,0xc1,0xa4,0x16,0x58,0xd5,0x92,0x39,0x45,0x6c,0x6d,0x6d,0x62,0x51,0x15,0x80,0x15,0x15,0x15,0x15,0x15,0x15,0xbf,0x10,0xd4,0xba,0xc3,0x8a,0x8a,0x8a,0x8b,0x87,0x89,0x6d,0x55,0xd4,0x23,0x44,0x7e,0x1,0x39,0x8d,0xb6,0x60,0xe3,0xca,0xa4,0x0,0xa3,0xa8,0xba,0xc5,0x60,0x6c,0xf,0x14,0x85,0x83,0xda,0x54,0x99,0xd8,0x52,0x25,0x52,0xce,0xf0,0x81,0xda,0x3d,0x53,0x8a,0x80,0x77,0xaa,0x48,0x90,0x9,0x8f,0x64,0xf2,0xc9,0x4,0x43,0xad,0xab,0x20,0x62,0xcc,0xb3,0xa,0x46,0x8a,0x49,0x9c,0xf,0xda,0x8e,0x48,0x8a,0x43,0x21,0xc0,0x12,0x4f,0xbc,0xf2,0xa8,0xd2,0x71,0x46,0xb3,0xa1,0x88,0x90,0xa0,0x9,0xa2,0x28,0x49,0xe2,0x30,0x50,0x76,0x9f,0xe4,0x37,0x9,0xa9,0xc5,0x44,0x5c,0xc9,0x64,0x75,0x2c,0x0,0xac,0xec,0xd3,0xe4,0x7d,0x6a,0x8d,0xe5,0x6d,0x13,0xb,0x97,0x1c,0x1f,0xc3,0x2a,0x93,0x14,0x7,0x7e,0xcf,0x98,0xa9,0x36,0x12,0x69,0x44,0x18,0x48,0x6e,0x5e,0x1c,0x7a,0x9d,0x48,0xe7,0x9,0x31,0x28,0xeb,0xd1,0x92,0x5,0xce,0xa0,0x22,0x32,0x34,0xeb,0x4,0x5e,0xcb,0x4f,0x8c,0xd5,0xf3,0x67,0x59,0xa5,0x69,0xd9,0x1a,0x97,0x73,0x86,0x85,0xd5,0x92,0x12,0xb1,0xb0,0x89,0x5d,0xd7,0x87,0x46,0x43,0xea,0x77,0x96,0x79,0x88,0x75,0x50,0x14,0x47,0xc6,0x18,0x9e,0x2c,0x5b,0x98,0x82,0x49,0x56,0x62,0xd6,0x36,0xe2,0x51,0x41,0x66,0x94,0xd0,0x1c,0x55,0x68,0x42,0x36,0x8e,0xad,0xc2,0x45,0xc7,0x4e,0x83,0x6e,0xfb,0x3c,0x7c,0x33,0x43,0xea,0xce,0xd5,0x6b,0xf7,0x42,0x28,0xd0,0x6c,0x2f,0x4c,0xc8,0xdb,0xe9,0xbf,0xf3,0x24,0xeb,0xd,0xd2,0x44,0x8d,0xb2,0x42,0xbc,0x12,0x39,0x16,0xd8,0xda,0x38,0xc6,0x46,0x5a,0x1e,0x6f,0xc8,0x5,0x5,0x5c,0xfe,0xc3,0xd7,0xa9,0x10,0x11,0xf2,0x3e,0x19,0xa7,0xc0,0x68,0x6f,0x34,0xc6,0x50,0x4b,0x6b,0xdf,0x8d,0x31,0x1,0xce,0xc1,0x14,0xb,0x3b,0xa3,0xc6,0xd1,0x14,0x7,0xb5,0xf8,0xae,0x6d,0xec,0xa7,0x5c,0xb3,0x42,0x85,0x41,0x54,0xfb,0xd,0x6e,0x8,0x26,0xc2,0x48,0xca,0x10,0xb4,0xc5,0x9b,0xaf,0x39,0x22,0x11,0xe9,0x7e,0xe3,0xac,0x67,0x9b,0x3f,0xed,0x9b,0xf7,0x1e,0x5d,0x12,0xe2,0x70,0x86,0x9c,0xa3,0x92,0x4a,0x42,0x94,0x48,0xc6,0x26,0x50,0x90,0x72,0xe6,0xc6,0x64,0xcb,0x43,0x77,0x24,0xc8,0xe5,0xa1,0x83,0x28,0xca,0x72,0xe1,0x7b,0x1a,0xdf,0xb7,0x74,0x3f,0xd,0xd9,0xf5,0x43,0x33,0x53,0x45,0xe3,0xf4,0xda,0x16,0xb5,0xa1,0x28,0xa0,0x49,0xe5,0xeb,0xd0,0xb4,0x33,0xa4,0xa6,0x45,0xe2,0xc,0xb9,0x3,0x87,0x8e,0xa2,0xef,0x96,0xf0,0xa1,0x21,0x3b,0x6b,0xc9,0xfa,0x70,0x45,0x55,0xb9,0x4c,0xb4,0x86,0xa6,0xd5,0xfb,0x9c,0x64,0xfe,0x59,0x6b,0x39,0x7b,0x91,0xee,0x8d,0xc8,0x5,0x43,0x5c,0x8e,0xca,0x4f,0x6e,0x7,0x27,0xb,0x78,0xd1,0xbc,0xd5,0x3e,0x45,0x25,0x8e,0x24,0x63,0x31,0xfb,0x8c,0xd9,0xda,0x6,0x11,0x68,0x39,0x23,0x34,0x33,0xa4,0x14,0x99,0xcc,0x63,0x5,0x65,0xa4,0x7b,0x68,0x3b,0xa3,0x86,0xdb,0xd9,0x7c,0x1d,0x7d,0xb7,0x50,0x22,0x50,0x62,0x17,0x88,0xe8,0x12,0x12,0x92,0xbe,0xb,0x54,0x4d,0xc8,0x25,0x1a,0x54,0x60,0xc1,0x5,0x22,0xed,0x4c,0x9,0xab,0xbe,0x5b,0xa0,0x69,0x67,0x18,0x7a,0x2a,0x3e,0xa1,0x76,0xe4,0xa8,0x25,0x48,0x2,0x55,0x83,0xf2,0x39,0xa3,0x63,0x33,0xa8,0xba,0x9c,0x2c,0xeb,0x46,0x89,0x3c,0xf9,0xe,0x90,0xdf,0x25,0xfb,0xb5,0x99,0xcd,0x11,0x87,0x1e,0xed,0x8c,0xf6,0xa5,0x9d,0xcf,0x61,0x39,0xde,0xc2,0xc1,0x21,0x27,0xab,0xd7,0x8f,0x10,0x99,0xce,0x53,0xe6,0xe1,0x7c,0x63,0x1f,0x36,0xcf,0x9c,0xd4,0xc6,0xe5,0x9c,0x33,0xd6,0x36,0xf6,0x13,0x99,0xcb,0xbf,0xcb,0xbd,0x37,0xd,0x3,0x9d,0x33,0x6e,0xd4,0xd6,0x48,0x5,0xfe,0xe,0x26,0xb5,0x35,0xf8,0x1a,0xa3,0xef,0x12,0xeb,0x3d,0x3c,0xa,0x32,0xbf,0x97,0x94,0xa6,0x6c,0x95,0x67,0x8b,0x7c,0x9e,0x5a,0x80,0x31,0x89,0xf2,0x10,0x5,0xe4,0x94,0xf4,0x9b,0x7c,0x7,0x96,0x49,0x59,0x18,0x6d,0x8b,0x99,0x28,0xbd,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x1,0x58,0x51,0x51,0xf1,0xcb,0xcb,0xff,0x4d,0x7e,0xce,0xa2,0x0,0x64,0xf2,0x4d,0x26,0xb4,0x89,0xb3,0xf1,0xc4,0x3a,0xa4,0x56,0x4f,0x21,0x97,0x64,0xa2,0xcc,0xb9,0x47,0x62,0x89,0x92,0x66,0xd0,0x5c,0xa,0xda,0x76,0x8e,0xbe,0x5b,0x90,0x75,0xd4,0x14,0xce,0x85,0xb2,0x2b,0x8a,0x20,0x18,0x52,0x8,0xd2,0xa4,0xd8,0x60,0xd6,0xb6,0x1c,0x8e,0x9e,0x91,0x8a,0x5,0x24,0xb7,0x8a,0x89,0xad,0x84,0xc8,0x93,0xf7,0x56,0x27,0x69,0x12,0xd6,0x2f,0x93,0xdb,0x2,0x3,0x9a,0x4b,0x11,0xa1,0xe4,0x7d,0x83,0x94,0x23,0x9c,0x21,0xe2,0xd0,0x32,0xe1,0x38,0xc,0xbd,0x6,0xff,0x47,0x5e,0x7f,0x1c,0x6,0x6a,0xdb,0xe5,0x9,0xa4,0x31,0x34,0xe9,0x1a,0xfa,0x7e,0xb4,0x3e,0x83,0x95,0x4e,0x4c,0xb8,0x91,0x8d,0xb7,0x61,0xb2,0x83,0xa,0x38,0x1c,0x68,0xf9,0x6d,0x3b,0x67,0xbb,0xaf,0x5f,0xb1,0xab,0x11,0xf9,0xd8,0x8d,0x8d,0xbf,0x13,0xc5,0xa1,0xf3,0xab,0xa1,0xf4,0x92,0xd7,0x85,0x89,0xa5,0x93,0xc8,0x36,0x52,0xdf,0x8,0x29,0x90,0x86,0x8,0x63,0xa1,0x41,0xef,0x29,0x45,0x78,0xde,0xd7,0x18,0x7,0x38,0x3b,0x21,0x26,0xdd,0x48,0xe0,0xa8,0x62,0xd1,0x8f,0xa,0xca,0xd8,0xf7,0x6a,0x43,0xf6,0x6c,0x47,0x93,0xcc,0x42,0x52,0x13,0x7a,0x64,0x9e,0x78,0x62,0x6a,0x25,0xe6,0xac,0xb8,0xc4,0xdb,0x2c,0xa,0x96,0x82,0x32,0x19,0x78,0x66,0x62,0x27,0x1d,0x1b,0x9c,0x73,0x2e,0xab,0xa5,0xd4,0x9c,0xe1,0x65,0x7c,0x40,0x4e,0x43,0xbd,0x70,0x5f,0x91,0xd3,0xb7,0xc2,0x9c,0x8e,0x84,0xc5,0x24,0x5f,0x4e,0xc8,0x78,0x21,0xed,0x75,0x52,0xcf,0xe4,0xa1,0x5a,0xb1,0xd,0xb7,0xc1,0x12,0xc3,0x45,0x63,0x26,0x45,0x2d,0x8b,0xd5,0x82,0x9d,0x34,0x2a,0x69,0xb5,0x1,0x95,0x49,0x6,0x18,0x3,0xc3,0x63,0x59,0x54,0x48,0xd2,0x30,0x4b,0x79,0x9e,0x33,0x26,0x51,0xd6,0x48,0x41,0xc8,0xb9,0x7a,0xce,0x79,0xcc,0xd6,0xd6,0x47,0x42,0x83,0x8b,0x27,0x24,0x13,0x4d,0xda,0x7d,0x33,0x2b,0x69,0x49,0x39,0xd7,0xb2,0xa2,0xcc,0xc2,0x78,0xaf,0xf7,0x28,0x2d,0xe8,0x91,0xe2,0x99,0xc2,0x79,0x70,0xce,0x21,0x84,0x96,0x9,0x6c,0x83,0x18,0xa5,0x68,0x82,0x8b,0x81,0x50,0x90,0x23,0xab,0x7d,0x39,0xdb,0x74,0x65,0xec,0x73,0xd1,0xc8,0xd0,0x51,0xee,0x60,0x3b,0x5f,0x1b,0x2d,0xaa,0x8e,0xae,0x3b,0xdf,0xd0,0x3d,0x6c,0x3c,0xf6,0x79,0x25,0x76,0x40,0x72,0xdd,0x86,0xbe,0x53,0xb5,0xb4,0xe4,0xba,0xd,0x7d,0x87,0x76,0x36,0x1f,0xb3,0x52,0x99,0xa6,0x5,0xdf,0x5b,0xe4,0xf8,0xe4,0x42,0x31,0x9,0x54,0xa6,0x44,0x36,0x62,0xd9,0xc6,0xb1,0x20,0xc4,0x62,0xc6,0x5,0x27,0x42,0xd0,0xa3,0x14,0x18,0x27,0xea,0x69,0xab,0xaa,0x64,0xb9,0xd6,0x84,0xad,0xa7,0xdb,0x51,0xd6,0x76,0x6e,0xb2,0x77,0x43,0xd5,0x71,0x74,0xec,0x28,0x67,0xd0,0x4,0xb6,0xfd,0x3a,0xb2,0x29,0xe7,0xc2,0xf,0x38,0xf8,0x7a,0x97,0x82,0x94,0x92,0xb,0xd6,0x36,0xc8,0x32,0x2c,0x4a,0xcd,0xa2,0xe3,0xd4,0xae,0xe4,0xcb,0x7a,0xce,0x3a,0xb4,0x1c,0x3d,0x20,0xf,0xc,0x3c,0x13,0xa2,0x98,0x10,0xbd,0x71,0xe8,0x69,0x3f,0xf9,0xc1,0x8f,0x2c,0x9b,0x32,0x51,0x89,0xf8,0x4c,0x39,0xc1,0x4d,0xca,0x5d,0xe4,0xe1,0x93,0x28,0x0,0xc5,0xda,0x5e,0xc,0xab,0xb8,0x11,0x69,0x7c,0x72,0x76,0x6b,0x4a,0x9,0xed,0x7c,0xd,0x3e,0x30,0xf1,0xc,0xc3,0xd6,0x66,0xca,0x72,0xd,0x7c,0x4e,0xe5,0xde,0x47,0x84,0x2b,0x95,0xaf,0xc4,0x81,0xee,0x5d,0xfd,0x72,0x89,0x76,0xb6,0xae,0x44,0x5e,0xb7,0xbd,0x85,0xf5,0xfd,0x7,0xf5,0xef,0x4e,0xc9,0xfc,0x2,0xd7,0xd2,0xd8,0xd,0x2d,0xd9,0x8f,0x7d,0x18,0xc7,0x36,0x5d,0x1b,0x5e,0xad,0xe9,0xf2,0x9d,0xc,0xb1,0xb5,0x3,0xf0,0xa6,0xd5,0xef,0x75,0x21,0xa7,0xad,0x9b,0x3c,0x64,0xd3,0xe8,0x5,0x7e,0xa0,0x55,0xc,0xab,0xb7,0xcb,0xe4,0x81,0x42,0xd2,0xff,0x5a,0xa0,0x47,0x5,0xa3,0x55,0xbc,0x94,0x8c,0x14,0x6b,0x2b,0x7b,0x45,0x45,0x45,0x45,0x45,0x45,0x25,0x0,0x2b,0x2a,0x2a,0xfe,0x9,0x90,0x5,0xa3,0xa,0x4b,0x54,0xa,0xa2,0xc4,0x93,0x20,0x72,0xfa,0x9b,0xb4,0xc4,0x9a,0x49,0x68,0x7c,0x1a,0xc3,0xee,0x39,0xa8,0x9e,0xd4,0x40,0x63,0x31,0x4,0x84,0x4,0xcc,0xd4,0x0,0x2a,0x93,0x40,0xb1,0x5,0xfa,0xd0,0xe0,0xda,0x2b,0xe,0xe3,0xda,0x2b,0xe,0xe1,0x9a,0x2b,0x8f,0xe0,0x9a,0x63,0x57,0x60,0x3e,0x9f,0x21,0x4,0x87,0x26,0x34,0x0,0xa,0xfa,0x21,0x22,0xc6,0x84,0xc5,0x62,0x89,0x13,0x27,0xcf,0xe0,0x99,0x17,0x8e,0xe3,0xc9,0xe7,0x5f,0xc6,0x73,0xc7,0x4f,0x23,0xe6,0x2,0x67,0x88,0xc,0x14,0x42,0x43,0xa,0x43,0x8c,0xe5,0xd0,0xff,0x4,0xd,0x4f,0x7,0x87,0xa4,0x17,0xcb,0x79,0x83,0x25,0x93,0x3a,0xce,0x59,0x55,0xd0,0x49,0x60,0xbb,0xb5,0x99,0xd5,0x73,0x66,0xa5,0x18,0xa5,0x99,0xcd,0x58,0x49,0x34,0x99,0xcc,0x3,0x9a,0x53,0x45,0xf6,0x3f,0x22,0x4f,0xe9,0x98,0x39,0x98,0x61,0x50,0xbb,0xae,0xaa,0xee,0x78,0x52,0x48,0xb6,0xe9,0xa0,0xaa,0xb,0x9,0xa0,0xa7,0x9,0x96,0x58,0x92,0x47,0x2,0x56,0xf6,0x73,0x6a,0xd5,0xcb,0x39,0x2b,0xf9,0x28,0x6a,0x39,0x22,0x67,0x12,0x7f,0x6e,0xb4,0x2b,0x3b,0xb6,0xa,0xfa,0xc0,0xc4,0x23,0xcc,0x48,0xf2,0xb0,0x55,0x5b,0x32,0xb3,0x1c,0x4f,0x70,0x25,0x6c,0x3f,0x33,0x81,0x89,0x52,0x98,0x80,0x75,0x5a,0x58,0x0,0x60,0xc5,0x32,0xac,0x8a,0x92,0x9,0xdd,0xac,0xf9,0x64,0x3c,0xb9,0x55,0x45,0x21,0x49,0xa4,0xc8,0x4a,0x29,0x96,0x44,0x6b,0x80,0x3c,0xb6,0x2f,0xa3,0x14,0x94,0x14,0x91,0x86,0x3a,0xd9,0x7c,0x25,0x8c,0xa,0xbe,0xc9,0x91,0x5f,0xb1,0xba,0x8f,0x63,0x50,0x55,0x44,0x62,0xd7,0x66,0x65,0x9f,0x9d,0xd8,0x3,0xa5,0x55,0x54,0x15,0xa4,0x56,0xd4,0x84,0x42,0x40,0x58,0xce,0xeb,0xcb,0x13,0xdb,0xfb,0xd8,0xb6,0x2d,0x2a,0x50,0xe7,0x3c,0x17,0x35,0x10,0x41,0x49,0xe4,0x14,0x60,0x4c,0xa3,0xe3,0x1d,0x60,0x4b,0x23,0x13,0x93,0x81,0x15,0x5e,0xa5,0x14,0x6e,0xe8,0x8d,0x70,0xa1,0xd1,0x72,0x22,0x52,0x72,0x39,0x2d,0xc5,0x19,0xb3,0x46,0x47,0x92,0x2d,0x89,0x65,0x17,0x0,0xca,0x68,0x4f,0x55,0xf2,0x84,0x1f,0x7e,0x48,0x2e,0x69,0x61,0x1b,0x7e,0x1c,0xa8,0xcd,0xd8,0xc0,0x10,0x89,0xc7,0xc7,0x24,0xc5,0xc8,0xa,0x3a,0x56,0x2f,0x37,0xd,0x86,0x8e,0x8,0x7c,0x52,0x74,0x65,0x8d,0x36,0x88,0x7d,0xa7,0xf6,0x52,0x24,0x22,0x4d,0x9b,0xd9,0x1c,0xfd,0x72,0x41,0x84,0x11,0xe7,0x22,0x8a,0x1a,0x98,0x32,0x56,0xe9,0x58,0x37,0xed,0x4c,0xcf,0x8f,0x58,0x49,0xb3,0x9d,0xc4,0x3,0x88,0x1d,0x94,0xf7,0xa5,0x9d,0xad,0x11,0x11,0x57,0xb8,0xdc,0xc5,0x62,0x52,0xda,0xc2,0x8a,0x5a,0xeb,0x10,0xf8,0x1a,0x97,0x66,0xde,0x10,0x1a,0x2d,0x79,0x91,0xd7,0xa5,0x4c,0xa2,0x99,0xad,0x21,0xe,0x1d,0x13,0xf5,0x3c,0x6,0x34,0x2a,0x62,0xbc,0x87,0x9a,0x64,0x31,0x5b,0xdb,0xd0,0x8,0x81,0x94,0xb8,0x29,0x1a,0x44,0xa2,0xd,0x43,0xbf,0x62,0xc9,0xce,0xac,0xc4,0x6e,0xe7,0xeb,0xac,0x8a,0x8e,0x68,0x37,0x36,0x30,0xc,0x3d,0xc,0x9f,0x17,0x51,0xfe,0xa5,0x44,0x85,0x4c,0x4a,0xce,0x4d,0xf3,0x1b,0xad,0x85,0x75,0x41,0xb3,0x15,0x25,0xf3,0xd5,0x70,0x11,0x86,0x9c,0x5f,0x33,0x29,0x17,0x72,0x9c,0x53,0xe9,0x94,0x1c,0xa4,0x32,0x1b,0xe7,0x29,0xc7,0x51,0xc6,0x3a,0xdd,0x8f,0x9d,0xaa,0x14,0x63,0x1c,0x34,0x8b,0x52,0x8,0x6e,0x6b,0xc7,0x12,0xaa,0x9c,0x13,0xbc,0x6b,0x50,0x0,0xc4,0x18,0xe1,0x3d,0xdd,0x27,0xd,0xc,0x86,0xd8,0x73,0x16,0xa0,0x81,0x37,0x1,0xd9,0x24,0x58,0x4f,0xf,0xbb,0x52,0x24,0x8b,0xb2,0x58,0xd3,0xa9,0x28,0x27,0xa9,0xa5,0x9b,0xda,0x8d,0x49,0xa9,0xea,0x66,0x73,0x2d,0xe1,0xd2,0x16,0x75,0x2e,0xb7,0xd1,0xf3,0xc3,0x51,0xc,0x94,0xdb,0x68,0x60,0x2d,0x17,0xb7,0xf0,0x3d,0xd6,0x80,0xb3,0xfd,0xf8,0xba,0x97,0x62,0x28,0x8d,0x5f,0x28,0x58,0x51,0xb3,0xab,0x6c,0x5b,0xfa,0x57,0x30,0xbd,0xb7,0x48,0x34,0x44,0x9d,0xaa,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x2,0xb0,0xa2,0xa2,0xe2,0x97,0x1e,0xa2,0x38,0xd0,0x49,0x12,0xab,0xae,0xb4,0xf9,0x75,0xa2,0x30,0x1b,0x2d,0x41,0x52,0xf0,0x91,0x21,0xaa,0x81,0x9c,0x26,0x4a,0x40,0x9e,0x80,0xcb,0xc4,0x5d,0xc2,0xe5,0xa7,0x36,0xac,0xeb,0xae,0x3c,0x8c,0x37,0xde,0x75,0x33,0xee,0xbc,0xed,0x16,0x5c,0x7e,0xe4,0x32,0x34,0x4d,0x78,0x55,0xdb,0x7b,0xe3,0xf5,0x57,0xe3,0xcd,0xb8,0x13,0x31,0x26,0x9c,0x3e,0x73,0xe,0x4f,0x3c,0xf5,0x1c,0x1e,0xfc,0xfe,0x13,0xf8,0xc9,0xf3,0x2f,0x63,0xb9,0x58,0x8e,0x39,0x79,0xd6,0xa1,0x24,0x51,0x45,0xc8,0xcc,0x8f,0x3,0xfc,0x99,0xd8,0x24,0xb2,0xcf,0x69,0xd3,0xa9,0x34,0xfc,0xca,0x44,0x35,0xc5,0xa2,0xe4,0x86,0x10,0x50,0xb2,0x5f,0x62,0x35,0x13,0x92,0x41,0x26,0x7a,0x44,0x7a,0xd0,0xf4,0x2a,0xc6,0x5e,0xf3,0xa9,0x24,0x2c,0x5f,0x54,0x39,0x89,0x27,0x93,0x71,0x4a,0x4e,0xb0,0x7a,0x8e,0x2c,0xc2,0xd0,0x60,0x7b,0x21,0x3a,0x68,0xd2,0x1a,0x56,0xad,0x5a,0xc4,0xc,0x2a,0x1,0x97,0x39,0x2b,0x50,0x54,0x98,0x40,0x44,0x8,0xd,0x62,0x1a,0xd4,0x4e,0x27,0xe7,0x19,0x76,0xcc,0x64,0x2c,0x0,0x9c,0xb4,0x6,0xf3,0xbc,0x8e,0x82,0xf6,0x7b,0xb5,0x54,0xea,0x24,0x59,0x42,0xea,0x35,0xfb,0x31,0xa8,0x3a,0x6,0x3a,0x89,0x24,0x45,0x8f,0x66,0x9f,0x29,0x5,0x38,0x69,0xf9,0x95,0x7d,0xc6,0x68,0xfb,0x35,0x13,0x45,0xa0,0x90,0x7f,0x32,0xc1,0x24,0xd5,0xcf,0xc,0xb9,0xaa,0x4d,0x5e,0x11,0xd6,0xda,0x49,0x9f,0x4a,0xd9,0xa3,0xe0,0x67,0x72,0xe,0x26,0xc7,0x78,0xaa,0x1a,0x14,0x8c,0xb6,0x6f,0xa3,0x19,0x8d,0x63,0x63,0xf3,0xb8,0xc,0x63,0x89,0x8c,0x92,0xf1,0x92,0xd9,0x16,0x2e,0x79,0x81,0x62,0xe3,0xd6,0xfb,0x42,0x1e,0x6d,0x99,0xc6,0x3a,0xf8,0x40,0xe3,0xbe,0x88,0xda,0xae,0x71,0x4a,0x58,0xc3,0x39,0xba,0x4f,0x15,0x2a,0xe9,0xd0,0x4c,0x3e,0x8c,0x76,0x4e,0xc9,0x1e,0x95,0x8c,0x50,0xcd,0x25,0x9c,0x5a,0xf3,0xf9,0xe1,0x43,0x86,0x28,0x97,0xc0,0xd,0xd8,0x16,0xb6,0xc8,0xb1,0x30,0xaa,0xe4,0x32,0x90,0xcc,0xbf,0x5e,0xd5,0x7f,0xa4,0x8a,0x66,0x22,0x24,0x17,0x7d,0x18,0xe2,0x38,0x77,0x4e,0x49,0x70,0x29,0x40,0x99,0x14,0x2c,0x94,0x9c,0x1,0xb,0xb2,0xae,0x3a,0x7,0x8b,0x51,0x85,0x25,0xf,0x28,0x2c,0x17,0x27,0xe5,0x4c,0xa5,0x3f,0x42,0x48,0x5a,0xdb,0x6a,0xdb,0xb1,0xb7,0x74,0x2f,0x19,0xfa,0x8e,0x8e,0xa1,0x19,0x55,0x9e,0x42,0x6e,0xf5,0xa9,0x83,0xb5,0x14,0xb1,0x20,0xa,0xc8,0x38,0xc,0xda,0x1c,0x6c,0xdd,0x98,0x53,0xaa,0x64,0x3d,0x80,0xa2,0x8d,0xdd,0x16,0x19,0x60,0x22,0x8f,0x28,0x62,0x94,0x82,0xc8,0xe4,0xa7,0x31,0x4e,0xd5,0xa3,0x44,0xe4,0xd2,0x7e,0x96,0x44,0xf,0x3a,0xda,0xd9,0x7c,0x8c,0x6,0x0,0x54,0xc9,0x28,0x6d,0xb6,0x71,0xb0,0xac,0xee,0xe6,0x87,0x16,0x5,0x4a,0xf8,0x1,0xd0,0x87,0x38,0x2,0x29,0xde,0x48,0x71,0x40,0xe1,0xdf,0xa5,0x8,0x43,0xef,0xc1,0x20,0x7b,0x70,0xce,0x9,0x8e,0x95,0x78,0x7d,0xdf,0x8d,0x8a,0x40,0x7e,0x10,0xb2,0xf2,0xa0,0x62,0x12,0x9d,0x10,0x87,0x5e,0x9,0x3e,0xb1,0x64,0xcb,0x83,0x90,0x82,0x32,0x2a,0x5,0xa5,0xd,0x9d,0x1f,0xd4,0xd0,0x76,0x45,0xcc,0xd6,0x36,0x10,0xfb,0x4e,0xd7,0x13,0x63,0xd4,0x76,0xfa,0xa6,0x6d,0x11,0x99,0xe4,0x96,0x18,0x3d,0xb9,0xf6,0x7c,0xd3,0x0,0x25,0x4c,0x1a,0xe5,0x1,0x67,0xdc,0x98,0xa7,0xa,0x6a,0x79,0x26,0x82,0xd1,0x23,0xe5,0x71,0x5c,0x91,0x52,0xd1,0x90,0x3a,0x1d,0xd0,0xfb,0xb7,0x28,0x3c,0xad,0xb6,0x3b,0x7,0x55,0x1,0xbb,0x49,0x16,0xef,0xce,0xc2,0x1f,0xba,0xd4,0x39,0xdf,0xd1,0x4c,0xb2,0x5f,0xf9,0x5a,0xd6,0xeb,0x99,0xc9,0xdd,0xf1,0x5e,0x5e,0xea,0x8d,0xb7,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0x12,0x80,0x15,0x15,0x15,0xbf,0xec,0x50,0x12,0x49,0x26,0x24,0x93,0x90,0xef,0xd5,0xff,0xd8,0x1f,0xdb,0x5d,0xd,0xa0,0x24,0x94,0x58,0xc0,0x64,0x32,0xe2,0x42,0x80,0xb3,0x14,0xb0,0xef,0x7c,0xd0,0xbf,0x3b,0x4f,0xb6,0xba,0xeb,0xae,0xb8,0xc,0xbf,0xf6,0xce,0x37,0xe1,0xf6,0xd7,0xdc,0x88,0xd9,0xac,0xfd,0x87,0xdf,0x18,0xbd,0xc3,0xd1,0x23,0x97,0xe1,0xe8,0x91,0xcb,0x70,0xdf,0x3d,0xb7,0xe3,0xc9,0x67,0x9e,0xc3,0x57,0xbf,0xf5,0x3d,0x7c,0xef,0x89,0xe7,0x69,0xe2,0x15,0x3c,0x4c,0xb4,0x4a,0x56,0x49,0x46,0x96,0x10,0x60,0x9a,0xef,0xc4,0x1,0xfc,0x62,0x79,0xb3,0x3c,0x21,0x36,0x86,0x26,0x5d,0xc3,0xd0,0x11,0xb9,0x66,0xc8,0xea,0x28,0xea,0x95,0xc4,0x56,0x43,0x18,0xc0,0xb3,0x2,0x85,0xb2,0x9c,0x8a,0x96,0x6a,0xb8,0xe2,0x95,0x30,0xcb,0x13,0x75,0x61,0x4e,0x91,0x3,0xf1,0x87,0x51,0x31,0x65,0x2d,0xa9,0x88,0x1a,0xab,0xec,0x98,0x90,0xa9,0xde,0x53,0xc8,0xbb,0x14,0x78,0x8c,0xa,0x20,0xbb,0x32,0x9,0x13,0x82,0x83,0x94,0x88,0xd,0x13,0x72,0x64,0x79,0xf3,0xbe,0x21,0xf5,0x94,0xa5,0xa2,0x11,0x98,0x42,0x76,0x4e,0x26,0xde,0xa4,0x34,0x65,0x1a,0x2,0x6f,0x40,0x84,0x4b,0xdf,0x2f,0x99,0x10,0x29,0x3a,0x89,0x24,0xd2,0xc7,0x2a,0xd1,0x63,0x58,0x41,0x8,0x90,0xed,0xd,0xd3,0x30,0x7d,0x26,0x6b,0xa4,0x3d,0x55,0xb6,0x7a,0x85,0x30,0x99,0x34,0x6f,0xaa,0xd2,0x84,0x49,0x55,0x5a,0x5f,0x42,0xea,0x17,0x88,0xb0,0x30,0x7e,0x6,0xd4,0x16,0xe0,0xb,0x62,0x9a,0xf5,0x67,0x76,0xa8,0x0,0x73,0x2e,0x64,0x87,0xcf,0xe3,0xf5,0x2c,0x44,0x58,0x66,0xa2,0x4f,0xc8,0x21,0xc9,0xee,0xe4,0x53,0xa7,0x84,0x8e,0x16,0x3,0x89,0x45,0x74,0x72,0xee,0xe8,0x9c,0x17,0xbd,0x7f,0x48,0x39,0x48,0x2e,0x19,0x86,0x33,0xf3,0x2c,0x5b,0xce,0x53,0x1c,0xb8,0x7d,0xd7,0xe8,0xfd,0x85,0xc8,0x97,0xac,0xcb,0x29,0x4c,0x3a,0x8e,0x39,0x98,0x93,0xe6,0x6a,0x6e,0xab,0x1e,0x63,0xb,0x38,0x77,0x54,0x14,0x4c,0xa2,0x56,0x9e,0x5c,0x27,0x42,0x2a,0x9,0xf1,0xa1,0xf,0x3a,0x8c,0x83,0xf5,0xb4,0xfc,0x94,0x22,0x2b,0x9b,0xa9,0x49,0x55,0x94,0x8b,0x62,0x3f,0x16,0xb2,0x2d,0xb3,0x1d,0x55,0x14,0xb9,0xd3,0xe5,0x8a,0x72,0x58,0xf2,0x11,0x8d,0x31,0xb0,0x7c,0x1d,0x5b,0x3b,0x36,0x5d,0x8f,0xe4,0xf8,0x58,0x78,0x24,0xf7,0x56,0x4c,0x72,0xd5,0x8c,0xe6,0x7d,0x16,0x8d,0x49,0x90,0x32,0x89,0x10,0x5a,0xc,0x7d,0xcf,0xa4,0xe,0xd8,0xae,0x3d,0x92,0x8b,0x52,0x94,0xe4,0x83,0x51,0x32,0x9,0xc6,0x20,0x95,0xc8,0xe4,0x22,0x93,0x9a,0x98,0xee,0x43,0xd1,0x76,0x5f,0x21,0xa5,0xe4,0x58,0xc9,0x79,0x4a,0x71,0x20,0xdb,0x6e,0xa4,0x66,0x62,0x51,0x79,0x6a,0x9b,0x70,0x11,0x1,0x59,0x61,0x55,0x1c,0xb5,0x24,0xd3,0x43,0xf,0xc0,0xfa,0x80,0x32,0x14,0x6d,0x8f,0x17,0xf5,0x9e,0x3c,0xc0,0x30,0xc6,0x60,0x18,0x7a,0xcd,0x55,0x8c,0xc3,0xb0,0x42,0x4a,0x49,0x16,0x2c,0x11,0x9f,0x4e,0xa3,0xe,0xe4,0x1e,0x28,0xdf,0x4f,0x42,0xd2,0x96,0xc9,0x3d,0x53,0xee,0x77,0xd4,0xea,0x9b,0xf4,0x1e,0x3c,0x55,0xc2,0xcb,0xcf,0x42,0x54,0xc7,0x48,0x31,0x11,0xf0,0x46,0xaf,0x1,0x33,0x29,0xfc,0x98,0x16,0x9a,0x88,0xa2,0x52,0x6c,0xc6,0x62,0xd,0x97,0xef,0x83,0x91,0xac,0xf6,0x3a,0x2e,0x2d,0x97,0x62,0x15,0x6d,0x9e,0xa7,0x31,0x50,0xb8,0x0,0xc6,0x70,0x9c,0x86,0x3e,0x24,0x91,0xef,0xe4,0x42,0xeb,0x49,0x59,0xf2,0x37,0x27,0x25,0x4a,0x28,0x1a,0xe5,0x21,0xc7,0x94,0xff,0xc8,0x25,0x58,0x52,0xe0,0x2,0x25,0xd6,0x55,0x11,0xe,0xc3,0x11,0x1e,0x79,0x6c,0x12,0x67,0xa5,0x2f,0x2f,0x2,0x65,0x8f,0x7,0x3b,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x95,0x0,0xac,0xa8,0xa8,0xf8,0x65,0x25,0x0,0x77,0x4c,0x5c,0x1,0xc0,0x5,0x9a,0xf0,0x6,0xcf,0x85,0x1b,0x4c,0xd0,0xc4,0xbe,0x27,0xc2,0xcb,0x37,0x6a,0x53,0x1b,0xb3,0x87,0x1c,0xc,0x5b,0xcb,0x44,0x15,0x26,0xea,0x1c,0x6b,0x1d,0xe6,0xb3,0x6,0x9f,0xf8,0xc0,0xfd,0x78,0xd3,0xbd,0x77,0xbe,0x6a,0xb5,0xdf,0xcf,0x43,0x6,0xde,0x72,0xe3,0x75,0xb8,0xe9,0xfa,0x6b,0xf0,0xd8,0xe3,0x3f,0xc5,0xa7,0xbe,0xf4,0x0,0x5e,0x3a,0x75,0x4e,0xb7,0x23,0xe7,0xc,0xc4,0xac,0x59,0x5f,0xce,0x13,0x91,0x96,0x4b,0x46,0x61,0x82,0x80,0x4a,0x0,0x12,0x17,0x77,0x10,0xd9,0x10,0xd9,0x32,0x2c,0x44,0x47,0x60,0x9b,0x56,0x66,0xc5,0x5f,0x8c,0x83,0xe6,0xee,0x89,0xcd,0x4e,0x1a,0x71,0x65,0x32,0xac,0xaa,0x9d,0xa6,0x45,0x4e,0x49,0x95,0x84,0xa2,0xa6,0x12,0xd2,0xe,0x80,0x96,0xa7,0xf8,0xd0,0xe8,0xc4,0x33,0xe,0x3d,0x62,0x1c,0x54,0x65,0x92,0xa4,0x6d,0x99,0x97,0xa5,0xa4,0xac,0xa8,0x9c,0x12,0xa9,0x4f,0x24,0x47,0x4d,0xe6,0xf5,0x79,0xd2,0x70,0xe9,0xd8,0xe6,0x47,0xfb,0xd8,0x93,0xf5,0x2c,0x84,0x15,0x4b,0x6e,0x4e,0x9,0xb9,0x14,0xe4,0xa1,0x23,0x8b,0x34,0x2b,0x49,0xca,0x24,0x5b,0x4a,0xb2,0xbe,0x44,0xbd,0xe3,0x39,0x6f,0x70,0x4a,0x42,0x29,0xa9,0xc8,0x33,0x46,0xb1,0x10,0x8a,0x4a,0x94,0x14,0x66,0x98,0x28,0xd6,0x26,0x13,0x51,0x63,0x90,0x64,0xb2,0x9,0xc0,0xfa,0x96,0xf6,0x25,0xa6,0x7a,0xe1,0xbe,0x8a,0x6b,0x5a,0x8e,0x9b,0x58,0xfd,0x88,0xb0,0x9a,0x90,0x5f,0xac,0xfa,0x92,0x31,0x24,0x8a,0xa1,0x9c,0xb2,0x12,0x66,0x42,0xea,0xe5,0x9,0xf1,0x55,0x98,0x60,0x53,0x32,0x2e,0x17,0x3d,0x67,0x23,0x9,0xd,0xa0,0x64,0x55,0x79,0xa,0xb9,0x23,0x4d,0xe3,0xaa,0x32,0x2b,0x19,0x25,0x4d,0xce,0x37,0x97,0x72,0x50,0x14,0x1d,0x17,0xd3,0xf0,0x3d,0x44,0xb2,0xd9,0x46,0xa2,0x8a,0x8,0x6e,0x21,0x2c,0xc7,0x26,0xf0,0xb1,0xb8,0x43,0xc8,0x2c,0xd9,0x4f,0xda,0x67,0x33,0x36,0xe5,0xea,0x7e,0x41,0xed,0xa9,0x52,0xca,0x20,0xc4,0x63,0x62,0xa2,0x9e,0xf6,0xcd,0x28,0x91,0x5a,0xa,0x56,0x15,0x65,0xc6,0xe8,0xf8,0xd,0x4d,0x83,0x14,0x69,0xd9,0x69,0x18,0xf8,0xfa,0x31,0xfa,0xd0,0x0,0x5,0xa3,0x1a,0x17,0x2b,0xb5,0xeb,0x13,0xf5,0xdb,0x68,0xb5,0x1c,0x95,0x97,0x42,0x9c,0x4a,0xfe,0xaa,0xe1,0xec,0xc0,0x46,0xf7,0x41,0x73,0xf4,0x0,0x14,0xd0,0x3d,0x6e,0x5a,0x18,0x4,0x8c,0x6a,0xcc,0x69,0xb1,0x13,0x7d,0x8e,0x32,0x10,0x25,0x67,0x91,0xb2,0xf4,0x12,0x90,0xa1,0xc5,0x4f,0x39,0x25,0xa4,0xd4,0x8f,0x4a,0xd3,0x49,0xbe,0x27,0x59,0x9f,0x29,0xf7,0x91,0x4f,0x1e,0x3f,0xb8,0x28,0x4c,0xac,0x15,0x2d,0xa8,0x71,0xce,0xaa,0x72,0x79,0x6c,0xa8,0x36,0xfa,0x70,0xc5,0x58,0xb,0xcb,0xf,0x96,0x62,0x89,0x9a,0x65,0x28,0xef,0x1d,0xc9,0x5b,0xab,0xc4,0x6c,0x8,0x8d,0x6e,0x3b,0x7d,0x37,0x84,0x15,0x35,0x7b,0x59,0x89,0x18,0x60,0xb5,0xb5,0x28,0x31,0x59,0xb1,0xe9,0x26,0xaa,0x4d,0x5a,0x76,0xe4,0x31,0xe8,0x47,0x4b,0xec,0xa4,0xd4,0x69,0xaa,0x6e,0xb7,0xde,0x71,0xfb,0x72,0x56,0x15,0xa8,0xf7,0x1,0xb1,0xc,0xfc,0x70,0x24,0xf2,0x57,0xa,0x65,0xd5,0x1a,0xbe,0x77,0x8b,0x92,0x9b,0x32,0x50,0xa7,0x4d,0xbe,0x96,0x15,0xde,0x5e,0x55,0x77,0x52,0xe2,0x24,0xad,0xc7,0x0,0x13,0x83,0xd2,0x46,0x2d,0x94,0x1c,0x9f,0x1f,0x51,0x67,0x4b,0xfe,0xaa,0xb5,0x6e,0x25,0xee,0x63,0xea,0xe8,0x15,0x95,0xba,0x19,0x6b,0xd9,0x57,0x1f,0x26,0x18,0xac,0x90,0xfb,0x3b,0xf4,0xdc,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0xbf,0x0,0x38,0x0,0xbf,0x5f,0xf,0x43,0x45,0x45,0xc5,0xc5,0xc0,0xb1,0x1b,0x5e,0xcb,0x1,0xe7,0x4c,0xd8,0x70,0x86,0x93,0xd1,0x76,0xc1,0xa2,0x93,0xc7,0x52,0x8a,0x12,0x45,0xc6,0x58,0x55,0x57,0x68,0xe6,0x15,0x4f,0x8a,0x9c,0xf3,0xda,0x34,0x69,0xad,0xc3,0x1d,0x37,0x1d,0xc3,0xbf,0xfd,0xed,0xf,0xe3,0xf6,0x5b,0x6f,0xe2,0x66,0xcb,0x8b,0x47,0x7c,0x1c,0x3d,0x72,0x8,0x6f,0xb8,0xe3,0x26,0xc4,0xbe,0xc7,0x73,0x27,0xce,0xa8,0x42,0x44,0xb6,0x4b,0xac,0x8a,0xc6,0xb2,0x7d,0x8d,0x15,0x14,0x99,0x33,0xa3,0x64,0x32,0x3e,0x2d,0x36,0x18,0x27,0xcf,0x46,0x9,0x51,0x37,0x9,0xe6,0x17,0xd5,0x91,0xf3,0x81,0x55,0x3f,0x4e,0xd7,0xa5,0x59,0x7e,0x4c,0x2e,0xd0,0xb1,0x9,0xfc,0xba,0xd1,0x49,0x71,0xe6,0x49,0x23,0x1d,0xd3,0xc,0xef,0x79,0xc2,0x27,0x24,0x66,0x9a,0x34,0x49,0x8a,0x6a,0x84,0xd5,0x3b,0x42,0xa0,0x15,0x56,0x67,0x88,0x52,0x50,0x2c,0x7e,0x79,0x45,0x9d,0x35,0x69,0xd6,0x2d,0x45,0x2d,0x95,0xd3,0xd7,0x64,0x42,0x28,0x4d,0xc9,0x32,0x79,0x14,0xc2,0x6e,0xcc,0xf2,0xd3,0xde,0x58,0x9d,0x28,0x53,0xb8,0xfc,0x38,0x2d,0x1c,0x33,0xc5,0xa,0x13,0xb2,0x5e,0x5b,0x2b,0xcb,0xc4,0x82,0x26,0x44,0xa,0x1d,0x6e,0x29,0x39,0x29,0x6a,0xdd,0x1b,0xfa,0x25,0x36,0xcf,0x9e,0xa1,0xd0,0x7f,0x18,0xe4,0xb8,0xac,0x17,0xef,0x5,0xb0,0xb6,0xff,0x10,0xe,0x1d,0x3d,0x46,0x67,0x86,0xf3,0xc0,0x46,0x3b,0xa5,0x59,0x21,0x8,0xa7,0x64,0xed,0x78,0xfc,0x77,0x3c,0x1c,0x58,0x21,0x50,0x76,0x5a,0x6,0x57,0x7f,0x1f,0x97,0x37,0xb1,0x6f,0x6b,0xb3,0xe8,0xf4,0xb5,0x49,0x86,0x1f,0xc,0xa9,0xe2,0xa6,0xad,0xd6,0x65,0x42,0x1c,0x4f,0xc6,0x53,0xe6,0x71,0x3d,0x92,0x75,0x79,0xa5,0x14,0x7,0x7a,0x4d,0x4c,0xf7,0x17,0xe3,0xb8,0xd6,0xeb,0xc6,0x8e,0x56,0x62,0xdd,0x2f,0xab,0x9f,0x97,0xa6,0x73,0x51,0xe3,0x11,0xe1,0x94,0x76,0x28,0xb4,0x8a,0xda,0xe7,0xa7,0xcb,0x25,0x4b,0x6d,0x54,0x52,0x92,0x48,0x77,0x51,0xfa,0x4a,0x23,0x36,0x26,0x4d,0xbd,0xd0,0xeb,0x5a,0x8,0x52,0x52,0x83,0xed,0x3e,0x37,0x40,0x99,0x58,0xe6,0xa1,0xfb,0x9d,0xb5,0xc8,0x45,0xb6,0xdf,0xac,0x9c,0x3,0x29,0x6f,0x32,0x93,0xfb,0xa1,0x90,0x71,0x40,0x5e,0x3d,0x6,0x93,0x66,0x6e,0x39,0xaf,0x76,0x12,0x1f,0x30,0x5d,0xb7,0x1c,0x7b,0x29,0xc,0x92,0xc8,0x8,0x21,0x18,0x35,0x23,0x94,0x89,0x2a,0x79,0x60,0x40,0x8d,0xdf,0x79,0x72,0x5f,0xcd,0x5a,0xe6,0x24,0xc7,0x3f,0xc7,0x51,0x35,0x5d,0x72,0x56,0x3b,0xf3,0xca,0xba,0xd,0xe5,0x33,0xca,0x43,0x9,0x21,0xeb,0xe8,0x78,0x3a,0x2d,0x56,0x91,0xfc,0xd5,0xa2,0xe7,0xda,0xc6,0x7b,0xd5,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x3b,0x6b,0x51,0xc6,0x78,0x3e,0xa1,0xf6,0x5f,0xb9,0x1f,0xcb,0xbd,0x8d,0xc6,0x40,0x1a,0xd5,0xca,0xd3,0xfc,0xd2,0xf1,0x42,0x5a,0x39,0x66,0xa5,0xe4,0xc9,0xbd,0x1e,0xda,0xce,0xac,0xd,0xdb,0xce,0xad,0x8c,0x9d,0xb1,0xef,0x7e,0x72,0xf,0x34,0xe3,0x3,0xa2,0xe9,0x36,0x12,0xb7,0x6a,0x57,0x48,0x62,0x94,0xd5,0x6c,0x3e,0xb5,0x9d,0xf3,0xfd,0x55,0x1e,0x4,0xc8,0xd8,0x98,0x66,0xf1,0xee,0x7a,0x78,0x30,0x4a,0xfb,0xa6,0x43,0x6f,0xf5,0xe1,0x2,0x93,0xb3,0x29,0x25,0x6c,0x9f,0x3f,0x83,0xe5,0xd6,0xe6,0xae,0x8,0x81,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x9f,0x1f,0x55,0x1,0x58,0x51,0x51,0x71,0xd1,0x30,0xb6,0x7f,0x8e,0x64,0x8c,0xbc,0x36,0x9d,0x1c,0x48,0xc1,0x45,0x29,0x98,0x10,0x52,0x62,0x9,0x63,0x62,0x8d,0x9,0x2e,0x51,0xb,0x58,0xe7,0x71,0xff,0xdd,0xb7,0xe0,0x13,0x1f,0x7e,0x37,0xd6,0xd7,0xe6,0x3f,0x7b,0x5b,0x4a,0x41,0x4c,0x19,0x5b,0x5b,0xdb,0x58,0x2c,0x97,0x88,0xa9,0x50,0xe3,0x62,0xd3,0xa0,0x6d,0x1c,0xd6,0xd7,0xd7,0xd1,0x4,0xbf,0x8b,0xc0,0xd8,0x89,0xf5,0xf5,0x35,0x7c,0xf4,0x3,0x6f,0xc7,0xe1,0x83,0xfb,0xf0,0xe9,0xaf,0x3e,0x84,0x65,0x4a,0x80,0x65,0x8b,0x55,0x36,0x4c,0x5a,0x8e,0x8a,0x3b,0x9a,0x50,0x15,0x26,0xed,0x1c,0x4a,0x4e,0x28,0xb6,0x50,0x33,0x30,0x7,0xb9,0xf,0x7d,0x7,0xd7,0xce,0x58,0x51,0x92,0x74,0xf2,0xaa,0x93,0x5f,0xe7,0x65,0x86,0xc4,0xaa,0xc0,0x5,0xd9,0x8,0x8d,0x81,0xf7,0x1e,0x7d,0xd7,0x51,0xc6,0x1e,0xab,0x3a,0x9a,0xb6,0x55,0x6b,0x98,0x63,0x45,0x87,0x34,0x9b,0x16,0x3b,0x2a,0x41,0x24,0x9b,0x4a,0x2,0xdd,0xa9,0x4,0xb4,0x83,0xb5,0x9e,0xb7,0x9f,0xb,0x3e,0xd8,0xe6,0x46,0xd6,0x5f,0x9e,0xdc,0x61,0x9c,0x6c,0xda,0x1d,0x93,0x56,0x29,0x79,0x51,0xb5,0x8d,0x28,0x77,0x98,0x4c,0x90,0xf6,0xe3,0x52,0x32,0xe7,0x6a,0x65,0xb5,0xd7,0xa9,0x4a,0x2a,0x25,0x2e,0x7f,0x49,0x1a,0xcc,0x5f,0x72,0x19,0xc3,0xe8,0xd3,0xa8,0xd4,0x9b,0xaa,0x87,0x84,0x65,0x1a,0xd7,0x51,0xc6,0x76,0xcf,0xb,0x11,0x53,0x5,0xc8,0x69,0x80,0xf5,0x1,0x39,0xd6,0x16,0xe0,0x57,0x26,0xc2,0xed,0xd8,0xa7,0x32,0x21,0x89,0xa6,0xe4,0xde,0x68,0x55,0xc5,0x9e,0x44,0xd3,0xb4,0x21,0x58,0x27,0xfb,0x31,0x8e,0x24,0xe0,0x84,0x74,0xa3,0xc6,0xe6,0xac,0x45,0x4,0x3b,0xc9,0xab,0xa9,0x22,0xcb,0x18,0xb2,0x4a,0x66,0x3b,0xb5,0x7d,0xd3,0xd8,0x10,0xca,0x4a,0x73,0x2c,0x73,0xe2,0x71,0xcb,0x77,0xaa,0x5c,0x56,0x88,0x2b,0xcd,0x14,0x2c,0xa3,0x55,0x98,0x6c,0xa0,0xd4,0x52,0x2b,0x4a,0x2b,0xca,0xa7,0xcb,0x80,0xa8,0x96,0xb9,0xc9,0x56,0x90,0xa4,0x70,0x41,0xf2,0xe,0x4d,0x9e,0xa8,0xfc,0xca,0xd8,0x5c,0xcc,0x65,0x20,0xda,0xce,0xcd,0x64,0xa4,0x28,0xb7,0x84,0xe4,0x13,0xe6,0xc4,0x39,0xaf,0xd1,0x1,0x29,0xd,0xac,0x3c,0x96,0x46,0xf5,0x71,0x1f,0x85,0xc0,0x4f,0x1c,0xa1,0x90,0x62,0x5c,0x21,0xdb,0xa6,0x19,0x86,0x7a,0x5e,0xd4,0x26,0x6c,0x26,0xe7,0x62,0x24,0xfd,0xa6,0x24,0x65,0x29,0x5,0x48,0x89,0xb2,0xeb,0xcc,0xd8,0xf6,0x3d,0x12,0x55,0xac,0xba,0x95,0x82,0x8e,0x9c,0xf5,0x9e,0x48,0xdb,0xe1,0x94,0x38,0x9a,0x5a,0xb0,0x85,0x27,0x92,0xeb,0xdd,0x5a,0x6a,0x50,0xb7,0xd2,0x34,0xd,0x20,0x67,0xc9,0x82,0x24,0xb,0xad,0x92,0x59,0xa2,0xac,0x9e,0x94,0x57,0xc8,0x7e,0x97,0x92,0xb4,0x44,0x49,0x5a,0x97,0x8d,0xe4,0x22,0x4e,0xec,0xbd,0xa2,0xb0,0x33,0x80,0x36,0xd,0x53,0x53,0x31,0xd,0x74,0x51,0x5,0x76,0xcb,0xed,0xb1,0x50,0x43,0x5b,0x8f,0xa1,0xcb,0x94,0xcc,0x3e,0x21,0x1e,0xcb,0xc4,0x82,0x6e,0x8c,0x9b,0x7c,0x7,0x42,0x9,0xdc,0xd1,0x8a,0x6c,0x27,0xf,0x5a,0xe2,0x8e,0x6b,0xab,0x60,0xe8,0x96,0x44,0x2,0xa6,0xa8,0xca,0xbe,0x95,0x71,0x9b,0x13,0x9c,0x6f,0x46,0x65,0xb8,0x3e,0x14,0x1a,0xaf,0x97,0x51,0xb1,0x1b,0x95,0xb0,0xdc,0x49,0xb2,0xcb,0x77,0xf,0x95,0x92,0x8c,0x6a,0xce,0x29,0x71,0x6e,0xad,0x85,0x29,0x66,0x85,0x2c,0x5f,0xb1,0xee,0x96,0x71,0x8c,0xe9,0x7f,0x3,0xe4,0x32,0xb1,0xb8,0x17,0x7d,0x28,0x35,0xde,0x9f,0x59,0x15,0x2c,0x45,0x39,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x95,0x0,0xac,0xa8,0xa8,0xf8,0x25,0x26,0x0,0x45,0x19,0xc4,0xa5,0xb,0x5,0xa3,0x9a,0xa3,0x4c,0x72,0xdc,0xa6,0x79,0x59,0x71,0xe8,0xe1,0x7d,0xd0,0xf6,0x41,0xc7,0xad,0xb1,0xa2,0xca,0xb0,0x6c,0x7f,0x7d,0xdf,0x5b,0xef,0xc2,0x47,0x3e,0xf0,0xab,0x8,0xc1,0xbf,0x22,0xe9,0x77,0x6e,0x73,0xb,0x4f,0x3d,0xfb,0x2,0xbe,0xfb,0xd8,0x4f,0xf1,0xcc,0x4b,0xa7,0x71,0xf2,0xec,0x16,0x72,0x81,0x5a,0xb4,0x8c,0xb1,0xf0,0xce,0xe2,0xc8,0x81,0x75,0x1c,0xbb,0xe2,0x30,0x6e,0xbb,0xf1,0x18,0x6e,0xb9,0xfe,0x18,0x2e,0x3b,0xb8,0xff,0x82,0x64,0xa0,0x77,0xe,0xef,0x78,0xcb,0x3d,0x98,0xcf,0x5a,0x7c,0xf2,0x8b,0xf,0x60,0x18,0x7a,0xb5,0x31,0x5a,0xef,0x81,0xc8,0x76,0x43,0x26,0xb3,0x9a,0x66,0x86,0xbe,0x5f,0x22,0x71,0x8b,0xa6,0x61,0x32,0x4e,0xe6,0x45,0x4d,0x3b,0x87,0xf,0x1,0x43,0xdf,0x8d,0x13,0x7c,0x4f,0x5,0x1,0xa2,0xae,0x91,0x89,0x59,0x4e,0x11,0x21,0xb4,0x4a,0x86,0xe4,0x5c,0xd0,0xb4,0xad,0xe6,0xe6,0x69,0xd8,0x3a,0xc0,0xa4,0x6a,0x81,0x6f,0x5a,0xa4,0x61,0x50,0xeb,0xae,0xe4,0x44,0x19,0x63,0x35,0xb3,0x2b,0x77,0x1d,0x9a,0x66,0xc6,0x21,0xfe,0x6c,0xfd,0x75,0x6c,0xb3,0xf3,0x1,0x43,0xdf,0xd3,0xb9,0x50,0x42,0xce,0x6a,0x99,0x87,0x10,0xe,0x56,0x5b,0x22,0xa9,0xb,0x52,0xf2,0xd6,0xd4,0xd6,0xcb,0xd,0xa9,0x94,0x2b,0x65,0x91,0x62,0x51,0xd5,0x15,0x40,0xed,0x9c,0x62,0x5,0xa6,0xed,0x2,0xb7,0x6d,0x4e,0x72,0xc1,0x54,0xed,0x17,0x74,0x5c,0x4c,0xc9,0x66,0x51,0xb7,0x48,0x46,0x95,0xaa,0xb9,0x78,0x62,0x3d,0x55,0x20,0xea,0xcc,0xdb,0x5a,0x94,0x62,0x60,0xd,0x11,0x39,0x15,0xaf,0x8c,0xa9,0x25,0x77,0x4a,0x48,0x4c,0x89,0xbe,0xd1,0xae,0x3d,0x99,0xf8,0x4f,0x88,0x41,0x94,0x3c,0x21,0x1c,0xb0,0xa2,0xd2,0x9c,0x16,0x34,0x10,0x99,0x42,0xad,0xa4,0x16,0x4e,0x97,0x39,0xb5,0x7d,0x8f,0xab,0xcd,0xaa,0xa8,0x9b,0x92,0x51,0x9a,0xfd,0xa6,0xa4,0x5f,0x9e,0x10,0x64,0x93,0x5c,0x3d,0x6e,0x3e,0x95,0x72,0x3,0xbd,0x7d,0x19,0xb3,0xda,0x82,0x4a,0xc,0xcd,0x58,0xe8,0x60,0x56,0xa5,0x4c,0x2b,0xea,0x28,0x33,0xb5,0x3b,0x4e,0x15,0x8d,0x50,0x82,0x63,0x24,0x1a,0xb3,0x8e,0x73,0x22,0xc9,0x2c,0x72,0x49,0xba,0x3d,0x4a,0xd2,0x9,0xb9,0x18,0xc7,0xd7,0x32,0xab,0xd3,0xe8,0xc1,0x81,0x51,0xa2,0x4d,0xd4,0x8f,0x25,0x67,0xe4,0x49,0x1b,0x72,0x66,0x85,0xb2,0xb6,0x82,0x4f,0x95,0x5a,0x76,0xb4,0x3d,0xe7,0x69,0xb9,0xa,0x30,0x96,0x49,0x40,0x38,0x42,0x37,0x21,0x98,0x26,0xe2,0xae,0x49,0xde,0xe7,0x74,0x9d,0xd3,0xe2,0x21,0x25,0x78,0xd8,0xe6,0x2a,0xd7,0xbe,0x99,0x64,0x2c,0xaa,0xd2,0x2f,0x25,0x5d,0x86,0x58,0x4b,0x45,0x19,0x5e,0xb8,0xa4,0x45,0xee,0x6f,0x65,0x92,0x2d,0x69,0xac,0xd3,0x56,0x75,0x19,0x27,0x79,0x4a,0x1a,0xb,0xf5,0x54,0xb0,0x62,0x25,0x17,0xd2,0x12,0x6c,0x75,0xd5,0xed,0xd3,0x1,0x38,0xc6,0x53,0xd0,0x43,0x8,0x87,0x1c,0xe3,0x4a,0x8b,0xfa,0xa8,0x22,0x2c,0x80,0x85,0x66,0x1,0x4e,0x6,0xba,0x12,0xc1,0x5a,0xbc,0xc1,0x83,0x7b,0xda,0x3a,0x9c,0x38,0xe,0x42,0x23,0xf,0xa4,0x70,0x83,0xb7,0xc9,0x59,0xa7,0x2a,0x52,0x4c,0x8,0x57,0xb0,0xed,0x7d,0xca,0xe5,0xd1,0xf2,0xe2,0x98,0xb1,0xa,0x83,0x62,0x30,0x96,0x6c,0x65,0xe8,0x4d,0x92,0x94,0xd8,0xd0,0xf1,0x4e,0xa7,0x39,0x73,0xd3,0x36,0xef,0xe7,0x64,0x9d,0x86,0xcf,0x27,0xa6,0xf7,0x3,0x91,0x8f,0xb,0xc9,0x37,0xba,0xec,0x47,0xc2,0xb9,0xe4,0xc9,0x7b,0xa6,0x57,0x12,0x15,0x6e,0x55,0xe5,0x5f,0x45,0x45,0x45,0x45,0x45,0x45,0x25,0x0,0x2b,0x2a,0x2a,0xfe,0x9,0x60,0xc,0xf5,0x37,0x3c,0x81,0xe7,0x5c,0xae,0x3c,0xda,0x35,0x29,0xa7,0xc9,0xe8,0xe4,0xdc,0x18,0xab,0x41,0xf4,0xce,0x1b,0x9d,0xe8,0x48,0x3,0xa3,0xb5,0x1e,0x6f,0xb9,0xfb,0x26,0x7c,0xf8,0xfd,0xbf,0xf2,0x8a,0xe4,0xdf,0xa9,0x33,0xe7,0xf0,0x8d,0x7,0x1e,0xc1,0x37,0x1f,0xf9,0x9,0x16,0x7d,0x62,0x3b,0x51,0x54,0x12,0x4a,0x88,0xb6,0x94,0x22,0xe2,0x90,0xf1,0x62,0xce,0x78,0xf1,0xd4,0x26,0xfe,0xfe,0xb1,0xa7,0x10,0x1c,0xf0,0xc6,0xdb,0x6f,0xc4,0xbb,0xee,0xbf,0x17,0x47,0xf,0x1f,0xdc,0x93,0x8,0xb4,0xd6,0xe2,0xbe,0x7b,0x6e,0xc7,0xf6,0xa2,0xc3,0x5f,0x7c,0xe5,0xef,0x1,0x47,0x93,0xa8,0xa1,0x5f,0xb2,0xa5,0x8d,0x33,0xb1,0xfc,0xd4,0xe6,0xe8,0x48,0xcd,0x64,0x2c,0x4a,0x49,0xfa,0x3b,0x4d,0x5e,0x99,0x44,0x93,0x89,0x98,0x94,0x6d,0x94,0x4c,0xb9,0x74,0xc6,0xac,0x58,0x9c,0xad,0xf5,0x3a,0x51,0x97,0x32,0x12,0x6f,0x9c,0x4e,0xe0,0xd,0xc,0xba,0x6e,0x5b,0xb,0x49,0x7c,0x8,0x44,0x6e,0x38,0xa7,0xd6,0xb7,0x81,0x1b,0x48,0x4b,0xa6,0x9c,0x2f,0x69,0xf7,0x35,0xc6,0x20,0x4f,0x54,0x17,0x94,0x35,0xe5,0x27,0x93,0x42,0xab,0xe1,0xfd,0x0,0x5b,0x2e,0x4b,0x6,0xcc,0xa8,0xe0,0x93,0x8c,0xc0,0xa4,0x65,0x20,0x50,0xb,0x1f,0x4d,0xc2,0x23,0xb5,0x57,0x72,0x86,0x99,0xf3,0x54,0xee,0x62,0xad,0x85,0xf1,0x94,0x13,0xc9,0x54,0x9,0xcd,0xb7,0x59,0xed,0x63,0x50,0x38,0xbf,0x9e,0xc7,0x13,0x13,0x13,0xca,0xc,0x99,0x49,0xd3,0x2f,0x38,0x9b,0x6d,0x62,0xaf,0x1c,0x55,0x29,0x6,0x13,0x8f,0x1c,0x35,0x20,0xe7,0x8c,0x9c,0x16,0xf5,0xc2,0x7d,0x25,0x52,0x5f,0xec,0xb3,0xbb,0xc8,0xbe,0xa9,0x45,0x70,0xd7,0x87,0x26,0x65,0x40,0x19,0xc6,0xb9,0x49,0x6e,0x9b,0x90,0x43,0x65,0xfc,0xb4,0x90,0x78,0x13,0x72,0x66,0x2c,0xf9,0x60,0x42,0x80,0x9,0x36,0x4c,0x68,0x27,0x51,0x34,0xc9,0xf8,0x12,0x32,0xf,0x3c,0xe,0xe5,0xbc,0x93,0x9a,0x2a,0xe9,0x75,0x20,0xfb,0x30,0x55,0x1d,0x4d,0x2d,0x8c,0x63,0x8e,0xdd,0x48,0xe8,0x9,0x45,0x32,0xbd,0x37,0x28,0xe9,0xc3,0xfb,0xb0,0xab,0x74,0x1,0x98,0x90,0x86,0x63,0x54,0xc0,0xce,0xfb,0xa5,0x31,0xa2,0xf6,0xe3,0xf5,0x32,0x49,0x6e,0x99,0x70,0xca,0x39,0x71,0x9b,0xf7,0x68,0xa3,0xc6,0x94,0x70,0x33,0x63,0xc4,0x42,0x99,0x10,0x38,0x98,0x6c,0xb9,0x92,0x8e,0x18,0x55,0x59,0x6,0x52,0xd6,0x52,0xc6,0x2c,0xc6,0x94,0x90,0x98,0xf0,0xa2,0x6b,0x9b,0x95,0xbc,0x25,0x73,0x96,0xe2,0x98,0xc7,0x37,0x5a,0x60,0xc7,0xe6,0x5f,0x4c,0xb,0x51,0x2c,0x17,0xa2,0x58,0xab,0x4a,0x4a,0x2a,0x36,0xb2,0x4a,0x54,0x15,0x26,0xc6,0xc4,0x12,0x2a,0xf,0x85,0x20,0x56,0x61,0xc9,0x55,0x9c,0x8c,0x27,0x21,0xfb,0x49,0x3d,0x9e,0xb4,0xec,0x47,0xb,0x4f,0x26,0xf6,0xdc,0x31,0x9f,0x8e,0x8a,0x2a,0xac,0x99,0xb6,0x38,0x8f,0xe7,0x5a,0xf2,0xf0,0x64,0x74,0xc9,0xc3,0x7,0xb9,0x8f,0xc1,0x4c,0xdf,0xb,0xb5,0x8b,0x4b,0x99,0x8b,0xb5,0x63,0xc1,0x15,0xb8,0xe4,0xc6,0x5a,0x37,0xc9,0xb7,0x64,0x2,0x1a,0x65,0xd2,0xa0,0x6e,0x35,0xb0,0x94,0x48,0x3c,0x52,0xbf,0x49,0x49,0xca,0xf4,0xc1,0x86,0xe5,0xd2,0x1a,0x8d,0x61,0xe0,0xd,0x25,0x2,0x31,0x8f,0xad,0xf0,0xd6,0xa1,0x98,0xf1,0x38,0xf1,0x80,0xe0,0xf3,0x34,0x16,0xca,0x10,0x69,0xc9,0x8d,0xdb,0xd6,0x4f,0x5a,0x96,0xc5,0x8a,0x3e,0xb1,0x1f,0xf3,0x98,0x9c,0xfe,0x3e,0xbd,0xc6,0xe9,0x3c,0xf2,0xf5,0xc9,0xf,0xdb,0x88,0x40,0x36,0x4a,0x8,0x4a,0x8b,0x37,0x26,0x45,0x35,0x98,0x10,0xfb,0x7b,0xdd,0x3b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x1,0x58,0x51,0x51,0xf1,0xcb,0x4c,0x0,0x4e,0x73,0xbd,0x8a,0x94,0x35,0x8c,0x93,0xdd,0x8c,0xac,0x93,0x18,0xb2,0x65,0x79,0xcd,0xa3,0x9b,0x2a,0x25,0xac,0xb5,0x18,0xfa,0x1e,0x21,0x34,0xb8,0xf1,0xd8,0x61,0x7c,0xfc,0x43,0xef,0x46,0xd3,0x34,0x7b,0xae,0x33,0xa5,0x8c,0xef,0x7c,0xef,0x87,0xf8,0xc2,0x37,0x1e,0xc1,0xa9,0xb3,0xe7,0xc9,0xe2,0xca,0x85,0x17,0x32,0x89,0x4,0xc,0xba,0xc5,0x36,0xe7,0xd9,0xd1,0x84,0x30,0xf6,0x9d,0xb6,0xf4,0xa6,0x64,0xf0,0xb5,0x7,0x1f,0xc3,0x83,0x8f,0x3d,0x89,0xf7,0xbe,0xe5,0x2e,0xbc,0xf3,0xfe,0xd7,0xa3,0xd9,0x83,0x6c,0xb4,0xd6,0xe0,0xed,0x6f,0xbe,0x1b,0x2f,0x9c,0x38,0x85,0x7,0x7f,0xf4,0x1c,0x6,0x5e,0x86,0x64,0x9a,0xc5,0xd8,0xd3,0x64,0xdb,0x7b,0x80,0xad,0xa5,0x6,0xd2,0x1e,0x69,0x35,0xc3,0x29,0x71,0x59,0x46,0x3b,0x5f,0x47,0xb7,0xd8,0xd2,0x16,0x5f,0xcb,0x64,0x28,0xd8,0x52,0x3c,0x36,0xa5,0x4e,0x9a,0x71,0xf9,0xf8,0x61,0x47,0x7e,0x92,0x16,0x75,0x30,0x99,0x2a,0x64,0x18,0x85,0xc8,0xa7,0x91,0x54,0x4d,0x9,0xce,0xd1,0x32,0x13,0x6,0xb5,0xfc,0x39,0xef,0x61,0x92,0xe1,0xd6,0x52,0x3f,0x66,0x9b,0x25,0x43,0x59,0x8d,0x86,0x14,0x48,0xd4,0x72,0x1c,0x1,0x5e,0x66,0xd1,0xd6,0x47,0xfa,0xdd,0xdb,0x86,0x27,0x9f,0x19,0x3e,0x34,0xa3,0xc2,0x90,0x27,0x81,0xa2,0x74,0xb4,0x3e,0xe8,0xa4,0x94,0xb2,0xa9,0xac,0x12,0x79,0x34,0x27,0xa6,0xe2,0x14,0xef,0x3,0x72,0xc9,0x4a,0x56,0x96,0x32,0xec,0x2a,0x7,0x31,0x6a,0x13,0x2c,0x23,0x3f,0x64,0x30,0x36,0x5c,0x1a,0x29,0x79,0xc0,0x98,0xe3,0x68,0x1d,0x72,0xb7,0x80,0x6b,0xd6,0x90,0x87,0xed,0x7a,0xf1,0x5e,0x0,0xa7,0x8f,0xbf,0x80,0xb3,0x57,0xbd,0x8c,0xf9,0xfa,0x86,0x12,0x3d,0xab,0x4,0xe0,0x8e,0x80,0x2f,0x83,0x51,0x19,0x2a,0x18,0x76,0x2a,0x2,0xcb,0xae,0xcc,0xbf,0x69,0x51,0x82,0x64,0x43,0xc2,0x0,0x86,0xdb,0x5e,0x35,0xe3,0x4f,0x14,0x44,0x92,0x6b,0xb6,0x23,0x57,0x74,0x77,0xae,0x20,0x94,0xc4,0x8b,0xb9,0xd7,0xfb,0xcc,0xd4,0x5e,0x2b,0xd9,0x7e,0x4a,0x28,0x4f,0xc8,0xc6,0x95,0xc,0xc1,0x1d,0xea,0x47,0x69,0xb1,0x4d,0x13,0x25,0x98,0x66,0xb3,0x31,0x71,0x5e,0xca,0x52,0x49,0xf0,0x1d,0x2c,0x29,0x93,0x8f,0x45,0x2d,0xc3,0x23,0x91,0x68,0x56,0x14,0x82,0x65,0x92,0x25,0x38,0xcd,0x1a,0xdc,0xf1,0xf4,0x5,0x25,0xa5,0xc9,0x59,0xa1,0x2,0xe,0x52,0x5c,0x8e,0x2a,0x46,0xeb,0xe8,0x1,0x0,0x17,0xfc,0x2a,0x9,0x2a,0xc7,0x6b,0x94,0x70,0x2,0x65,0x28,0x9a,0xc1,0xa7,0xd7,0xd8,0x24,0xb7,0xce,0xf0,0x67,0x72,0x29,0xbb,0x48,0xe2,0xa9,0x72,0x6d,0x6a,0x3d,0x95,0x56,0x74,0x22,0xf3,0x8a,0x5a,0x6d,0x45,0xf1,0x9d,0x39,0xd3,0x70,0xcc,0x10,0x64,0x52,0x48,0xa,0x37,0x98,0x5c,0xa2,0xe3,0x34,0x28,0x61,0x24,0x24,0xa5,0x3c,0xe0,0x90,0x7b,0x8a,0x10,0xcd,0x5a,0x84,0xa1,0x43,0x75,0x6a,0x71,0xa6,0xc,0xbd,0x21,0xf7,0xbb,0x8,0x4c,0x21,0xb4,0xf2,0x8a,0x25,0xd5,0xb0,0x4d,0xdd,0xae,0x14,0x5a,0xc8,0xc3,0x6,0xcd,0xbe,0xe5,0x92,0xa2,0x95,0x72,0x96,0x32,0x9e,0xe3,0x95,0xe2,0x96,0x1d,0xc7,0x6e,0x85,0x18,0x37,0xd0,0x38,0x4,0x79,0x5d,0xbe,0x5c,0xc5,0x2a,0x2f,0xeb,0x1e,0x58,0x91,0xa7,0xc4,0x23,0xef,0x65,0x1c,0xfa,0x71,0xdf,0xa7,0xf9,0x82,0x32,0xf6,0x84,0xc0,0xde,0xb1,0x9f,0xd3,0x5c,0x45,0x1d,0xb7,0x7c,0x8d,0x68,0xe6,0xe1,0x54,0x5d,0x3d,0x21,0x60,0xe5,0x81,0x8e,0x64,0x8,0x48,0x51,0x8f,0xd5,0x7f,0x1b,0xb5,0xe4,0xc7,0x18,0x11,0x87,0x1e,0x9b,0x67,0x4e,0x62,0xf3,0xf4,0xa9,0x7a,0xe3,0xad,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x4,0x60,0x45,0x45,0xc5,0x2f,0x3f,0x98,0x6c,0xc9,0xa3,0x72,0x41,0x8,0x9a,0x14,0x89,0x8,0x72,0xbe,0xa1,0xa0,0x75,0x9e,0x58,0x3b,0x1f,0x48,0xd5,0x50,0x32,0x35,0x2,0xb3,0x4d,0xcf,0x39,0x6a,0xfb,0xfd,0x97,0x1f,0x7d,0x2f,0xf6,0x6d,0xac,0xef,0xb9,0xb6,0xae,0x1f,0xf0,0x99,0x2f,0x7d,0xb,0x5f,0x7d,0xf0,0x31,0x9e,0xa0,0xa,0x29,0x38,0x6,0xa5,0xc7,0x61,0x80,0xb5,0x69,0xb4,0xe9,0x29,0x99,0x60,0x91,0x86,0x81,0x1a,0x67,0x59,0x35,0xb7,0x58,0xe,0xf8,0xcc,0xd7,0x1e,0xc2,0xd3,0xcf,0x9f,0xc0,0xbf,0xf8,0xf0,0x3b,0xf7,0x5c,0x6f,0xf0,0x1e,0x1f,0x7e,0xef,0xfd,0xf8,0xf1,0x33,0x9f,0xc2,0xd9,0x9c,0x31,0xf4,0x9d,0xaa,0x23,0x48,0xf1,0xe1,0x34,0xcf,0x2e,0x34,0x63,0x8b,0xe3,0xb4,0x2d,0xb1,0x69,0x29,0xc3,0x30,0xc6,0x1e,0xbe,0x69,0x75,0xe2,0x14,0x5a,0x22,0xe8,0x4c,0xa0,0x89,0x6f,0x68,0x66,0x4a,0xa6,0x89,0xa2,0x30,0xa5,0x71,0x82,0x27,0x64,0x89,0x73,0x9e,0x32,0xb9,0x58,0xe1,0xa8,0xcd,0xc9,0xd6,0xc2,0xf8,0x80,0xa1,0x5b,0xf2,0xe4,0x97,0x42,0xec,0x85,0x30,0xd4,0xc,0x2c,0x3e,0x56,0xa1,0x6d,0x51,0x96,0x44,0x36,0xf4,0xdd,0x12,0xa6,0xb1,0xdc,0x48,0x59,0x90,0x62,0x22,0x25,0x52,0x8a,0x28,0x39,0xa1,0x69,0x67,0x6a,0x27,0x2c,0x60,0x52,0x52,0x6c,0xde,0xd6,0xc0,0xbb,0x56,0xcb,0x52,0xc6,0x42,0x92,0xc4,0x3f,0x37,0xaa,0xfe,0xc3,0x64,0xb2,0x2d,0xfb,0x22,0xf6,0x36,0x3a,0x2f,0x5,0x16,0x16,0xc5,0x19,0xb6,0x4a,0xae,0x12,0x46,0x42,0x48,0x64,0xb6,0x96,0x16,0x2e,0x42,0xc1,0x64,0x8e,0x6f,0x74,0x12,0x3a,0x16,0x38,0xa4,0x7e,0x1,0x17,0x1a,0x24,0x26,0x8a,0xab,0xed,0x6c,0x6f,0xf4,0x8b,0x73,0xf8,0xe1,0x43,0x7f,0x8b,0xa3,0xc7,0xae,0xc7,0xfa,0xfe,0xcb,0x56,0xda,0xba,0x55,0xb5,0x27,0x45,0x10,0x13,0xe2,0xa6,0x88,0xa,0x53,0xee,0xb,0x13,0xe2,0x43,0x55,0x5f,0x30,0xbb,0x4a,0x13,0x44,0x8d,0x36,0x5d,0x8f,0x66,0xf6,0x59,0x33,0x96,0x7f,0x30,0x71,0x24,0xaa,0x62,0xb1,0x89,0xea,0x78,0xe0,0x7b,0xc,0x30,0x69,0xf2,0x9d,0x7c,0x6,0x93,0xed,0xd6,0x46,0x57,0xe5,0x8f,0xcb,0xe8,0x64,0xb4,0x23,0x41,0xb3,0xf3,0x75,0xcd,0x9a,0x5c,0x29,0xf,0x31,0x64,0xe3,0x35,0x4e,0xc9,0x8e,0x32,0xd9,0x7f,0x4c,0xb3,0x51,0x47,0xff,0x2c,0x56,0x7c,0x9b,0x3b,0xec,0xa9,0xd3,0xe3,0x34,0x25,0x1a,0xcb,0x84,0x74,0x19,0xc9,0xb2,0x51,0x81,0x38,0xb6,0xd4,0xae,0x2a,0xad,0x56,0x88,0x9b,0x9,0x1,0x28,0x65,0x3c,0xc2,0xde,0x14,0x6d,0x18,0x1f,0xb7,0x7d,0xea,0xdc,0x2c,0x93,0xff,0x9b,0x5e,0x97,0xf2,0x60,0x7,0x46,0x72,0x40,0x47,0x1b,0xf1,0x94,0xbc,0x9a,0x5e,0x77,0x2b,0x84,0xb0,0x8e,0x2d,0xb6,0x9c,0xf2,0x72,0xd4,0x46,0xbc,0xa2,0x24,0x1b,0x23,0x25,0xac,0x66,0xfb,0xd9,0x15,0x3e,0x6a,0x9a,0x3f,0x29,0x6a,0xec,0x91,0x98,0x2a,0x58,0x7d,0x6a,0xb0,0x63,0x3f,0x45,0x69,0x89,0xf1,0xe1,0xc1,0xb4,0x28,0xc3,0x68,0x6b,0xb1,0x5d,0x39,0xee,0xa2,0x5c,0x1d,0xcb,0x3f,0x8c,0x12,0xa1,0x3b,0x89,0x6f,0xfa,0x6e,0x88,0x63,0x41,0x88,0x10,0xe0,0x42,0x8,0xd3,0x80,0xc3,0xd8,0xae,0x6c,0x76,0x90,0xaa,0x79,0x24,0x46,0x61,0x60,0x4c,0xd1,0xf3,0x30,0xdd,0x6f,0x7a,0xd0,0xc6,0xd9,0x9a,0x53,0xae,0x57,0x2c,0xbe,0xc0,0x24,0x97,0x91,0x8f,0xc1,0xa4,0x61,0x7b,0x6c,0xf3,0xb5,0x13,0x5b,0xb6,0x58,0xdd,0x47,0x2b,0xb5,0x44,0x53,0x50,0x9c,0x83,0xd7,0x7,0x31,0x92,0x6b,0x68,0xc,0x29,0xe1,0xa7,0x79,0x8c,0x7d,0xb7,0x44,0xb7,0x58,0x62,0xf3,0xec,0x69,0xc4,0xe5,0xd9,0x7a,0xe3,0xad,0xa8,0xa8,0xa8,0xa8,0xa8,0xf8,0x5,0x61,0xc7,0x7f,0x65,0x56,0x54,0x54,0x54,0xfc,0xe2,0xf0,0x86,0x77,0x7e,0x4,0x7,0xe,0x1d,0xd5,0x92,0x7,0x67,0x1d,0x67,0xc4,0x4d,0xf2,0x9b,0xd8,0x2,0xab,0x76,0x3d,0xce,0x9c,0x13,0x5,0x99,0xe5,0x96,0x4b,0xeb,0x3c,0x3e,0xf6,0xde,0x37,0xe1,0x83,0xef,0x7e,0xdb,0x9e,0x96,0xdc,0xae,0xef,0xf1,0x9f,0xfe,0xfc,0x8b,0x78,0xe4,0xa7,0x2f,0xe9,0xa4,0x2d,0xa7,0x44,0xe1,0xf0,0x5c,0x26,0x91,0x52,0x84,0xc1,0x98,0xaf,0x94,0xb8,0x9,0x52,0x32,0xec,0x64,0xc2,0x9b,0x53,0x42,0x68,0x5a,0x9e,0x24,0x45,0x38,0xdf,0xe0,0xe6,0xab,0xf,0xe3,0x7f,0xf8,0xc4,0x7,0xb0,0x7f,0xdf,0xde,0xe4,0xe3,0x23,0x8f,0x3d,0x81,0x3f,0xfc,0xd4,0x57,0x91,0x26,0x4d,0xa2,0x71,0x18,0x94,0x28,0x48,0x71,0x60,0xa5,0x4d,0xd1,0x7c,0x2d,0x51,0x89,0xa4,0x94,0x38,0xe7,0x6e,0xd2,0x8c,0xca,0xf6,0x60,0x2d,0xec,0xe0,0x32,0xf,0xe2,0x9,0xb8,0x54,0x64,0xa2,0xc,0x92,0xbf,0x1,0xe3,0x64,0x4f,0xf9,0x3,0x6e,0xf1,0xf4,0xbe,0x41,0xdf,0x2d,0x60,0x8c,0xd1,0xec,0xbe,0xa9,0x72,0xc3,0x48,0xab,0x26,0x5b,0x34,0x8d,0x66,0x59,0x19,0x78,0xdf,0x60,0xb9,0xdc,0x42,0x8,0x8d,0xda,0x76,0xc5,0x16,0x18,0x87,0x41,0x4b,0x4f,0x1c,0xab,0x5,0x77,0xe6,0x58,0x61,0x32,0xf1,0x37,0xc6,0x20,0x72,0xe,0x61,0x41,0x41,0xe2,0xe5,0xa5,0x61,0x80,0x71,0x16,0xb1,0xef,0x55,0x19,0x18,0x59,0x4d,0x25,0xcb,0x88,0x43,0xaf,0xd6,0x4d,0x21,0x2d,0xe3,0x84,0x8,0x14,0x45,0xda,0x34,0x5f,0xb2,0x68,0x8b,0xa9,0x4a,0x8d,0x90,0x73,0x41,0x4a,0x3,0x62,0xdf,0xe3,0xfc,0xb9,0xd3,0x78,0xee,0xc9,0x1f,0x23,0xa6,0x8c,0x3c,0x2c,0xab,0x2,0xf0,0x55,0xc2,0x35,0xeb,0xf0,0x4d,0xb,0xdf,0xcc,0x50,0x72,0x54,0x85,0x95,0xe4,0xa2,0x11,0x89,0xe1,0x80,0x92,0x60,0x5c,0xe0,0xf7,0x10,0xb9,0x6f,0x5d,0x40,0x1a,0x96,0x4c,0x48,0x14,0x18,0xcb,0x5,0x3c,0xfc,0x7e,0x52,0x21,0xd9,0x89,0x75,0xbe,0x20,0xc5,0xe,0xd6,0x85,0xf1,0xda,0xe0,0x2c,0x41,0x29,0xa,0x98,0x16,0x44,0x40,0x32,0xf4,0x52,0xd4,0x96,0x52,0x21,0xf9,0x84,0x24,0x94,0x7c,0x49,0xc0,0x22,0xe7,0x81,0xaf,0xc9,0x51,0x89,0x2c,0xdb,0x9d,0x75,0x7c,0xb1,0x86,0xc9,0x1a,0xce,0xea,0xeb,0x98,0x40,0xb,0x23,0x79,0xc4,0x84,0xd2,0xb8,0x8e,0xa4,0xb1,0x6,0xb4,0xee,0x34,0x92,0x3c,0x4c,0xe4,0x3b,0xdf,0x22,0x27,0x52,0x36,0x96,0x9,0x29,0x43,0x43,0xda,0x52,0x41,0xd,0x13,0xe1,0xa2,0xee,0x1a,0xd5,0x80,0x64,0x15,0x35,0x2e,0xf0,0x75,0xc7,0xca,0x48,0x1b,0x54,0x3d,0x67,0xe5,0xbe,0x5b,0x12,0x8c,0xd,0x0,0x48,0x41,0x2b,0xfb,0x6f,0xad,0x3,0xac,0x43,0x8e,0x3d,0x13,0x58,0x74,0x7e,0xad,0xb,0xba,0x2f,0x44,0x6e,0x89,0xcd,0xd8,0x23,0xc7,0xe,0xd6,0xb7,0x63,0x96,0x1c,0x5,0xee,0x1,0x39,0xf2,0x79,0x49,0x70,0x61,0xa6,0xb9,0xa5,0x72,0x2f,0x73,0x3e,0x20,0x71,0xb6,0x29,0xa6,0x6a,0xca,0x94,0x48,0x29,0xd,0x5e,0x4e,0xc9,0xba,0xdc,0xb2,0x52,0x84,0x64,0x51,0x52,0xa4,0xf3,0x6b,0x2d,0x6f,0x33,0x97,0x43,0xd9,0x51,0x71,0x99,0x73,0x82,0xe3,0x7,0x26,0xd8,0xa1,0x68,0x33,0xbe,0x41,0x89,0x3d,0x95,0x84,0xa4,0x38,0xda,0x52,0xed,0x98,0x15,0x6a,0x8c,0x1b,0xc9,0x3e,0x47,0xef,0xd3,0x2,0x1c,0xc8,0xf7,0x56,0xe0,0xa8,0x8a,0x6,0x29,0x76,0x70,0x61,0x8e,0x52,0x22,0x93,0x93,0x9c,0x59,0xa,0x6e,0xaa,0x96,0x52,0x15,0xe3,0x38,0xfe,0xc1,0xc2,0x18,0x87,0x38,0x2c,0x39,0xce,0xc1,0x21,0xf6,0xb,0x25,0xa0,0x53,0xec,0x61,0xad,0x47,0x68,0x5a,0xc4,0x44,0xd7,0x83,0x75,0x1,0x39,0xf6,0x14,0x57,0xc0,0xf7,0x39,0xb9,0xc7,0x8a,0xa,0xd1,0xfa,0x86,0xc6,0xab,0xf5,0x48,0xc3,0x42,0x89,0x46,0x18,0xca,0xd1,0xc,0xa1,0x41,0xca,0x5,0xb1,0x5b,0x50,0x36,0x6c,0x8a,0x5a,0xb2,0x62,0xac,0xc7,0xb0,0x3c,0xf,0x17,0x5a,0x1d,0x8b,0x39,0x47,0xf8,0x66,0x8d,0x54,0xea,0xfc,0x40,0x2b,0xf6,0x4b,0xb8,0xd0,0xc2,0x18,0x20,0xf6,0xb,0xf8,0x30,0x3,0xac,0x47,0x4e,0x3,0x3c,0xc7,0x37,0xf8,0xd0,0xc2,0x0,0xe8,0x97,0x5b,0xf0,0xcd,0x1c,0x28,0x69,0x7c,0xf0,0x53,0x38,0xd3,0x36,0x45,0x2a,0x65,0xe1,0x31,0x67,0xf8,0x7c,0x64,0x63,0x91,0x63,0x44,0xbf,0x75,0x6,0x25,0xd5,0x46,0xf6,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x5f,0x24,0xaa,0x2,0xb0,0xa2,0xa2,0xe2,0xa2,0x61,0x54,0x39,0xd0,0xa4,0x34,0x31,0xd1,0x6,0x14,0xe,0x76,0x1f,0xb8,0x59,0x96,0xed,0x55,0x13,0xe5,0x8a,0x31,0x63,0x70,0xbf,0xf,0x16,0x87,0xf7,0xcf,0xf1,0xb6,0x37,0xdd,0xb3,0x27,0xf9,0x97,0x52,0xc6,0x5f,0x7c,0xe1,0x1b,0xf8,0xfe,0x53,0x27,0x34,0xdc,0x3e,0x4a,0x68,0xbe,0xe4,0x58,0xc5,0x41,0x8b,0x23,0x6,0x26,0x98,0x84,0x50,0x72,0x81,0xac,0xab,0x7d,0xb7,0x64,0x62,0xd,0xaa,0x88,0xc9,0x39,0x3,0x71,0xc0,0x8f,0x9f,0x39,0x8e,0x3f,0xf9,0x8b,0x2f,0xe3,0x77,0x7e,0xf3,0xfd,0x58,0x9b,0xb7,0xbb,0xb6,0xe1,0xb5,0xaf,0xb9,0x1,0xaf,0xb9,0xee,0x47,0x78,0xfc,0xd9,0x13,0x4a,0xfc,0x79,0xef,0x31,0xc,0xbd,0x92,0x7,0xa4,0x4,0xb2,0xb0,0xce,0xaa,0x85,0x95,0x28,0x3b,0x20,0x84,0x66,0x2c,0xc3,0x68,0x84,0x9c,0xa0,0x5c,0x3e,0x21,0x12,0x80,0xd1,0xa,0x4c,0xca,0xf,0x8b,0x38,0x74,0xf0,0x4d,0xb,0x5b,0x9c,0xaa,0x3a,0x38,0xb9,0x69,0xcc,0xea,0x2a,0xa3,0x2a,0x6a,0x36,0x5f,0xc7,0xc0,0xf6,0x2f,0x22,0x21,0xc0,0xa,0x42,0x22,0xdc,0x7c,0x68,0x60,0x60,0x10,0xf3,0xc0,0x44,0x21,0x6d,0xa3,0x2a,0x32,0xd9,0x1e,0xac,0xcd,0x97,0x3c,0x79,0x4c,0x9c,0x7f,0x26,0x39,0x86,0xd6,0x5a,0x52,0xd,0xaa,0xaa,0x23,0x8d,0xf9,0x86,0xa2,0x58,0xb4,0x6,0xa6,0x18,0x64,0xb6,0xce,0x39,0x9e,0x3c,0x36,0xed,0xc,0xc3,0xd0,0xd3,0x24,0xd2,0x8c,0x5,0x8,0x29,0x8d,0xca,0xa1,0x94,0x47,0xd5,0xce,0x94,0xfc,0x13,0x35,0x95,0xd8,0x4e,0xa9,0x10,0x54,0x2c,0xaa,0x45,0x9,0x55,0x94,0x41,0xed,0x7c,0xc6,0x18,0x14,0xe3,0x61,0xd0,0xc3,0xcf,0xd6,0xd1,0x57,0x2,0xf0,0x55,0x21,0xf5,0x5b,0x48,0xfd,0x16,0xba,0x57,0x75,0x33,0xb0,0xaa,0x46,0x13,0x12,0x64,0x72,0xa3,0xd8,0xa5,0xb8,0x5c,0x79,0xcf,0xe4,0xb3,0xbb,0xef,0x31,0x3b,0x96,0xf5,0xaa,0xee,0x4b,0xab,0x9f,0x31,0xd6,0xa3,0xe4,0xf8,0x6a,0x3e,0x89,0x9f,0xf5,0xcc,0xd4,0x4c,0xed,0xbb,0x42,0x40,0x93,0x1,0xf4,0xe7,0xde,0xce,0xe9,0xf6,0x42,0x46,0x6f,0xc9,0x7b,0xaf,0xcf,0xd8,0x9,0xc9,0x99,0x7e,0xee,0x63,0xb0,0xe3,0x8f,0x3f,0x5b,0x1,0xcb,0xe7,0xe4,0x82,0xcb,0x31,0x16,0x28,0xa7,0x2f,0xb0,0x4c,0x51,0x89,0xb9,0x7f,0xd0,0x31,0xd1,0xcf,0x31,0x59,0x7c,0xc1,0xf7,0x2d,0xce,0xef,0x18,0x67,0xab,0xe3,0x68,0x5c,0xce,0x1e,0xe3,0xeb,0x15,0xc6,0xdc,0xae,0x73,0x63,0xcc,0xab,0x1c,0x3f,0x3f,0xcf,0x58,0xa2,0xbf,0x2f,0x77,0xbd,0x77,0xef,0xcf,0x5d,0x68,0xc,0xef,0x7a,0x7d,0x8f,0xfd,0xda,0xf9,0x1e,0x22,0xd8,0x57,0xc7,0x91,0x71,0xd,0x4a,0xea,0x57,0x3e,0x23,0x56,0xe4,0x65,0x49,0x7b,0x1e,0x7,0x25,0xd2,0x77,0xac,0x8b,0x14,0x95,0x44,0x46,0xd3,0x7f,0x1b,0x78,0x94,0xdc,0x8f,0xdb,0xf1,0x2a,0x8f,0x7d,0x45,0x45,0x45,0x45,0x45,0x45,0xc5,0xcf,0xf,0x7,0xe0,0xf7,0xeb,0x61,0xa8,0xa8,0xa8,0xb8,0x18,0x38,0x76,0xe3,0x6b,0xd1,0xcc,0xe6,0x6a,0xdf,0x13,0x95,0x1b,0x91,0x57,0x54,0x72,0xa1,0xed,0xb9,0xac,0xd8,0x12,0xcb,0xa7,0x65,0x62,0xc6,0xb1,0x6d,0xe9,0x23,0xef,0x79,0x33,0x6e,0xbf,0xf5,0xe6,0x3d,0xd7,0xf3,0xdd,0x47,0x9f,0xc0,0x5f,0x7e,0xed,0xe1,0x31,0x24,0xbd,0x14,0x52,0x4c,0x58,0x22,0xd2,0xa,0xab,0xe6,0x8a,0x6,0xc0,0x93,0x35,0x4a,0x88,0x34,0xb2,0x11,0x16,0x6d,0xe6,0x25,0xa2,0x30,0x6b,0x76,0x9e,0xa8,0xe4,0x5e,0x3a,0x79,0x16,0xf3,0x60,0x70,0xd3,0xf5,0x57,0xef,0x22,0x22,0xad,0xb5,0x58,0x9f,0x5,0x3c,0xf8,0x83,0x9f,0x32,0xb1,0x26,0x93,0x72,0x26,0xa0,0x8c,0x41,0xd3,0xb4,0x6a,0x1b,0x23,0x75,0xa3,0x94,0x7a,0xd0,0xb1,0xf1,0x3e,0x68,0x1e,0x15,0xe5,0x89,0x79,0x6d,0x1,0x4e,0x29,0xb2,0x2a,0x91,0x8e,0x89,0xf3,0x94,0xfb,0xd7,0xb4,0x73,0xb5,0x5d,0xd2,0xf6,0x9b,0x95,0x46,0x55,0x17,0x2,0x42,0x68,0xb4,0xdc,0x23,0x4d,0xda,0x42,0x8d,0xb1,0xfa,0x19,0x1f,0x82,0xb2,0x86,0xd6,0xd2,0xb6,0x88,0x3a,0xc8,0x5a,0x56,0xf9,0x49,0x9,0x89,0x99,0xb4,0x41,0xf2,0xe4,0xde,0x39,0x87,0x10,0x5a,0x3e,0x5e,0x5c,0x5a,0x12,0xbc,0x5a,0xde,0xbc,0x27,0x85,0x52,0xd3,0xce,0x90,0x53,0x42,0x3b,0x9b,0x6b,0xb0,0xbd,0xda,0xd7,0x98,0x40,0x1c,0x58,0xe5,0x47,0xaa,0x17,0x37,0x66,0xf5,0x4d,0x72,0xa7,0x48,0xb1,0x62,0x75,0x82,0x99,0xb5,0x50,0x86,0x8f,0x1f,0xab,0x49,0xad,0x31,0x2b,0xd6,0x4e,0x2d,0x43,0x60,0x62,0x34,0xe7,0x84,0x6e,0xb1,0x8d,0x73,0xa7,0x4f,0xd2,0xa4,0x37,0x67,0xe4,0x58,0x8b,0x40,0x7e,0xf1,0x28,0x17,0xf8,0xf9,0x1f,0xfb,0xfe,0xf2,0x8f,0xdc,0x16,0xfc,0x62,0xc9,0x86,0x3d,0x89,0xb3,0x82,0x7f,0x9c,0xd9,0xa2,0x5c,0x78,0x19,0x2b,0x96,0xd5,0x9f,0x67,0x3d,0xe5,0x17,0x74,0x3e,0xcb,0x3f,0x62,0xf9,0xe5,0x22,0xad,0xfb,0x42,0xcb,0x2f,0x3f,0xc7,0x72,0x7e,0x8e,0xe3,0xf8,0xcb,0x40,0x56,0x5d,0x68,0x1b,0x76,0xbd,0x5e,0x7e,0xf6,0x7b,0xca,0x1e,0xe3,0x68,0x27,0xd1,0xaa,0x59,0x92,0xe5,0x82,0xc7,0xa1,0xec,0xb5,0x4d,0xd3,0xcf,0xc8,0xcf,0xb2,0xec,0x92,0x7f,0x41,0x63,0xb3,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xe2,0x42,0xb0,0xf5,0x10,0x54,0x54,0x54,0x5c,0xb4,0x39,0x9,0x5b,0x41,0x85,0x0,0x13,0x25,0x1e,0xa9,0xb8,0x46,0x45,0x88,0x73,0x1e,0x39,0x65,0x6d,0x69,0x74,0x42,0x3c,0x31,0xa1,0xb3,0x6f,0x7d,0xd,0xf7,0xdd,0x7b,0xd7,0x9e,0xeb,0x38,0x7d,0x76,0x13,0x7f,0xf6,0xf9,0x6f,0x8c,0xd9,0x71,0x5c,0x87,0x68,0x9d,0xc3,0x72,0xfb,0x3c,0x0,0x56,0x22,0xf2,0xf6,0x50,0xce,0x5f,0x46,0x1c,0x3a,0x2a,0xbb,0x70,0x81,0x88,0xa0,0x94,0x30,0xc,0x3d,0x96,0xdb,0x54,0x1c,0x92,0x53,0x42,0xdf,0x2d,0xc8,0x5e,0x6a,0xad,0x6,0xfb,0x7f,0xf6,0x6b,0x7f,0x8f,0xe7,0x5e,0x78,0x69,0xcf,0x6d,0xb9,0xe9,0x86,0x6b,0x70,0xd5,0x91,0x3,0x0,0x37,0x52,0x1a,0x3,0xcd,0x34,0x74,0xce,0xab,0x95,0x31,0x34,0x33,0xe2,0xda,0xac,0x45,0xd3,0xce,0x10,0x9a,0x99,0x36,0x44,0x92,0xdd,0xcd,0x92,0xaa,0xcf,0x39,0x5d,0x56,0x3b,0x9b,0xf3,0xbe,0x58,0xb5,0xff,0x7a,0x1f,0xa8,0xac,0x63,0xd2,0xe8,0x29,0xf9,0x4b,0xa1,0x69,0x69,0x1b,0x98,0xc,0x93,0x66,0x4c,0xb1,0xcf,0x52,0x9,0x48,0x3,0xeb,0x1c,0xe5,0x0,0xe6,0x8c,0x66,0x36,0x23,0x5,0xa0,0xa5,0xc2,0x8d,0x3c,0x21,0xe0,0x42,0xdb,0xb2,0x2,0x8f,0x6c,0x64,0xaa,0xf4,0x73,0x8e,0x2c,0xda,0xbc,0xe,0x2a,0x39,0x69,0x68,0xd9,0xc6,0x22,0x84,0x80,0xa6,0x9d,0x53,0x21,0x8,0x13,0xac,0x21,0x34,0x93,0xf2,0x17,0xf,0x1f,0x2,0x9a,0x76,0xa6,0xc4,0xe3,0xda,0xfa,0x3e,0x3a,0x6,0xfc,0x3e,0xc3,0xff,0x73,0xde,0x23,0xb4,0x33,0xb6,0x76,0x26,0x3a,0x27,0xb2,0xde,0x1d,0xff,0x8,0xb9,0x27,0xc7,0xd9,0x4c,0xf2,0xba,0xca,0x18,0xe8,0x35,0xaa,0x0,0xd5,0x32,0x9d,0xea,0x85,0x5b,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0xc9,0xa1,0x5a,0x80,0x2b,0x2a,0x2a,0x2e,0x1a,0x44,0x87,0xa6,0xd9,0x76,0xc6,0xc0,0x1a,0xa7,0xc4,0xdf,0x18,0x30,0xe,0xb5,0xc5,0xfa,0xd0,0x68,0xb6,0x1b,0x92,0x81,0xf7,0x1e,0x77,0xde,0x7c,0xec,0x82,0xd9,0x7b,0xdf,0x7e,0xf8,0x87,0xd8,0x5a,0xf6,0xd3,0xb5,0x71,0x31,0x45,0xa6,0xfc,0xa4,0x38,0x68,0xfa,0xbb,0x34,0xd0,0xe6,0x48,0xaa,0xc0,0x76,0x36,0xc7,0x72,0xb1,0x8d,0x52,0x32,0xe2,0x30,0xa0,0x9d,0xcd,0x39,0xd3,0xae,0xd7,0xc6,0xd9,0x38,0xf4,0xe8,0x97,0xb,0xb4,0xf3,0x35,0xa4,0x14,0x91,0xbc,0xc7,0x97,0xbf,0xf1,0x30,0x7e,0xe7,0x37,0xaf,0x80,0xb5,0xab,0x2a,0xc0,0x26,0x78,0xdc,0x75,0xcb,0xd5,0x78,0xf1,0xd4,0x79,0x58,0x90,0xd5,0xb4,0xef,0x97,0x2b,0x4d,0x9e,0x42,0xd6,0x35,0x52,0xbe,0xc1,0x25,0x15,0xc6,0x5a,0xa4,0x94,0x70,0xe0,0xc0,0x7e,0xac,0xcd,0x5a,0x94,0x14,0xe1,0xc,0x60,0xfd,0x7e,0xb2,0xc6,0xf6,0x1d,0xdb,0x7f,0xa9,0x2d,0x11,0xc6,0xa0,0xeb,0x96,0x68,0xdb,0x19,0x86,0x7e,0x89,0x33,0x5b,0xd,0xfa,0x18,0x11,0x42,0x83,0x61,0xe8,0xd1,0x36,0xd,0xe,0xed,0x9b,0xc1,0x3a,0x2a,0xed,0x40,0xc9,0x88,0x31,0xe1,0xd4,0xf9,0x25,0x52,0x4a,0x1c,0x95,0x45,0x79,0x85,0xb3,0xd6,0xe3,0x9e,0xbb,0x6e,0xc2,0xad,0x37,0x1c,0xc3,0xc6,0xfa,0x1c,0x9b,0x5b,0xb,0xfc,0xe8,0xa7,0xcf,0xe2,0x91,0xc7,0x9f,0xc5,0xd9,0xcd,0x4d,0x22,0xea,0x8c,0x65,0x92,0x6e,0x54,0x23,0x96,0x52,0xb4,0xd9,0x57,0x54,0x77,0x4d,0x68,0x60,0x90,0x71,0xcd,0xe5,0x97,0xe1,0x86,0xab,0x2f,0xc7,0x55,0x47,0xf,0x61,0x63,0x63,0xd,0xc1,0x7b,0xf4,0x31,0xe2,0xe5,0x97,0x4f,0xe3,0x99,0x17,0x4f,0xe2,0xf1,0xa7,0x9e,0xc7,0xb9,0xad,0x25,0x7c,0xa0,0x26,0xe4,0xd0,0x34,0x30,0xc6,0x60,0xe8,0x7b,0x88,0x2,0x24,0x4f,0xf2,0x9,0xa5,0x44,0x42,0x82,0xf6,0xdd,0x24,0x3,0x30,0xe5,0xc2,0xcd,0xc9,0xbd,0x66,0xc,0xe6,0x24,0xc5,0xe,0xdc,0xae,0x4a,0xbf,0x70,0x3e,0x1c,0x56,0x44,0x26,0x6,0x40,0x5c,0x9c,0x87,0xd,0xd,0x4a,0xe5,0xff,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2e,0x41,0x54,0x2,0xb0,0xa2,0xa2,0xe2,0xe2,0xc1,0x50,0xe3,0x64,0xce,0x45,0xad,0xbe,0xd3,0x2c,0xa8,0xc2,0x65,0x0,0xda,0x5e,0x8,0x9,0xce,0x87,0x5a,0x56,0x8d,0xb1,0x78,0xe3,0x3d,0xb7,0xab,0x45,0x78,0x8a,0xed,0xc5,0x12,0xdf,0xfc,0xee,0x13,0xb4,0x2a,0x6b,0x81,0x4c,0xcd,0xb4,0x6,0x64,0x7d,0x1d,0xfa,0x6e,0x5c,0x76,0xce,0xda,0xba,0xeb,0x43,0x8b,0x6e,0xb9,0x8d,0xcd,0xb3,0xa7,0x60,0x8c,0x41,0xd3,0xce,0xd0,0x77,0x4b,0x6c,0x6d,0x9e,0x41,0x3b,0x5b,0x43,0xdf,0x11,0x31,0xb5,0xd8,0x3a,0x4f,0x8a,0xb7,0xb6,0xc5,0xf9,0xb3,0xa7,0xd1,0xb4,0x33,0xb4,0xf3,0x35,0xfc,0xcd,0x83,0xdf,0xc7,0x7,0xdf,0xf9,0x26,0x5c,0x7e,0xe4,0xd0,0xae,0x6d,0xba,0xeb,0xb6,0x1b,0xf1,0xc5,0x6f,0x3d,0x8a,0x62,0x2c,0x52,0x26,0x82,0x4a,0xa,0x2d,0x68,0xdf,0x48,0xd9,0xd8,0x2f,0x17,0xb0,0xd6,0xe1,0xe0,0xc6,0x1a,0xee,0xb8,0xe9,0x18,0xee,0x78,0xcd,0xf5,0xb8,0xe2,0xe8,0x61,0x6c,0xac,0xcf,0xe1,0xbd,0x87,0x63,0xb,0xab,0x91,0xae,0xd1,0x5d,0x19,0x69,0x46,0xb,0x55,0x50,0x80,0x7f,0xff,0xa7,0x9f,0xc5,0xf7,0x9f,0x78,0x4e,0xf3,0x4,0xef,0xba,0xe5,0x5a,0xfc,0xee,0xc7,0xdf,0x4f,0xed,0x8e,0x74,0xb0,0x61,0x8c,0xc1,0x9f,0x7c,0xfa,0x2b,0xf8,0xf6,0x23,0x3f,0x81,0xb1,0xd4,0xd8,0x7b,0xe3,0xb1,0xc3,0xf8,0xc4,0xaf,0xfd,0xa,0xae,0xbe,0xea,0xa,0x38,0x37,0x1e,0xe3,0xb7,0xbe,0xf1,0x6e,0x9c,0x3e,0xbb,0x89,0xaf,0x7d,0xeb,0x61,0x7c,0xe1,0x6f,0x1f,0x6,0x38,0xd4,0x9e,0x6c,0xc3,0xd,0x67,0xce,0x53,0xeb,0x31,0xc,0xad,0x33,0x38,0x83,0x5f,0x79,0xfd,0x6d,0x78,0xf3,0x1b,0xee,0xc4,0x15,0x47,0xe,0x23,0x84,0xbd,0xbf,0x62,0x4a,0x29,0x38,0xbf,0xb5,0x8d,0x47,0x1f,0x7f,0x12,0x9f,0xfb,0xea,0x3,0x78,0xf1,0xe4,0x26,0x86,0xbe,0x47,0xe1,0xa6,0xdf,0x18,0x89,0x50,0xb4,0x8e,0x14,0xa1,0xc8,0x64,0x7b,0x16,0xcb,0xb6,0x36,0xc7,0xc2,0x68,0x91,0x1,0xb5,0x23,0xf3,0xf0,0x92,0xe6,0x49,0x69,0xd8,0xe4,0x1c,0xc8,0xd5,0xc6,0xd7,0x32,0x5a,0x8b,0x4b,0x81,0xd,0x33,0x2a,0x4c,0x70,0x55,0x3,0x58,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0xe9,0xa1,0x12,0x80,0x15,0x15,0x15,0x17,0xf,0x13,0xd2,0x4a,0x2d,0x98,0xc5,0xb0,0x8a,0x8c,0x1b,0x63,0x33,0x37,0x78,0x3a,0xc7,0x6d,0x8a,0x64,0xb9,0x2d,0x39,0xc3,0x86,0x0,0x1f,0x3c,0xae,0x39,0x76,0xc5,0x9e,0x8b,0x7f,0xfa,0xb9,0x97,0x70,0xe6,0xfc,0xb6,0x96,0x50,0x48,0xcb,0x6f,0x4a,0x89,0x88,0x29,0x40,0x5b,0x1d,0x73,0xce,0x8,0xcd,0xc,0xfd,0x72,0x9b,0x54,0x79,0x85,0xac,0xb5,0xdd,0x62,0x4b,0xdf,0x3b,0xf4,0x1d,0xd9,0x5f,0x87,0x5e,0x9,0x3b,0x63,0xc,0xba,0xc5,0x36,0x59,0x56,0xbd,0xc7,0xf6,0xf9,0x4d,0x84,0xa6,0xc1,0x23,0xdf,0x7f,0xc,0xef,0x79,0xe7,0xdb,0x76,0x6d,0xd3,0x91,0x43,0x7,0xb1,0x6f,0xde,0xe0,0xf4,0xe6,0x16,0xbc,0x6f,0x90,0xd,0xb5,0x8e,0x52,0x2b,0x64,0x64,0xbb,0xac,0xc3,0x65,0x7,0xf6,0xe3,0xdd,0xf7,0xbd,0x16,0xf7,0xbd,0xfe,0xe,0xec,0x5b,0x5f,0xdb,0xb3,0xdc,0xe4,0x67,0x83,0xcb,0x1,0x4a,0xe1,0x9c,0x3f,0xcf,0xfb,0x5c,0x90,0x63,0x8f,0x66,0xf,0x2,0xce,0x6a,0x49,0x86,0xc3,0x3d,0xb7,0x5e,0x87,0xdf,0xfa,0xc8,0xbb,0xb1,0xb1,0x3e,0xdf,0xf5,0x3e,0x63,0xc,0xe,0x1d,0xdc,0x8f,0x8f,0xbc,0xff,0xed,0xb8,0xfd,0x96,0xeb,0xf0,0xef,0x3f,0xf9,0x5,0x6c,0x2e,0xc6,0xf3,0x98,0x12,0x11,0xad,0xa1,0x25,0xfb,0xf0,0xad,0xd7,0x1e,0xc5,0x27,0x3e,0xf4,0x4e,0x5c,0x75,0xc5,0xd1,0x9f,0xb9,0x2f,0xc6,0x18,0xec,0xdb,0x58,0xc7,0x9b,0x5f,0x7f,0x27,0xee,0xbc,0xed,0x26,0xfc,0xe5,0x17,0xbe,0x8e,0xbf,0x79,0xe8,0x71,0xf4,0x3,0x65,0x2e,0x7a,0x17,0xe0,0x5d,0x20,0xf5,0x26,0x0,0x58,0x22,0x4c,0x29,0xd7,0xf,0x80,0x29,0x48,0x43,0x4f,0x96,0x69,0x14,0xb5,0xfb,0xca,0xb2,0x33,0xef,0x67,0x8c,0x91,0xb,0x4b,0x2c,0x13,0x84,0x63,0x23,0x71,0x41,0x81,0xe1,0x7c,0x42,0x52,0x32,0x6,0xc,0xcb,0x5,0x8c,0xe6,0x8,0x56,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x3a,0xa8,0x19,0x80,0x15,0x15,0x15,0x17,0xd,0x92,0xb5,0x46,0xf9,0x74,0x85,0x2c,0xbf,0xac,0x6c,0x93,0x3c,0x38,0x7e,0x27,0xac,0xa5,0x76,0x5c,0x0,0xd4,0x66,0x69,0x80,0x14,0x7,0x5c,0xb6,0x6f,0x1d,0xfb,0xf7,0x6d,0xec,0xb9,0xec,0x47,0x7e,0xf4,0x14,0xd9,0x37,0xe3,0x0,0x29,0x86,0xe0,0x10,0x40,0x2a,0x94,0x70,0xd4,0x22,0x2c,0x44,0x52,0xce,0x9,0x7d,0xb7,0xe4,0xb2,0x10,0x60,0xb9,0xb5,0x9,0x63,0x28,0xef,0x6e,0xe8,0x3b,0xc4,0x61,0xc0,0xd0,0x2d,0x89,0x98,0x2c,0x19,0xdd,0x72,0x1b,0xdd,0x72,0x81,0xed,0xf3,0xe7,0x90,0x52,0x44,0xbf,0x5c,0x0,0x6,0xe8,0x96,0xdb,0xf8,0xce,0xf7,0x7e,0x88,0x94,0x77,0x87,0x9c,0x7,0xef,0x70,0xc5,0xa1,0x75,0xa4,0x18,0x99,0x90,0x64,0xa5,0x1e,0xa0,0xa5,0x19,0xb7,0x1c,0x3b,0x84,0xff,0xe5,0x77,0x7f,0x3,0xef,0x79,0xc7,0x9b,0xb0,0x7f,0x63,0xfd,0x1f,0x48,0xfe,0xad,0xc2,0x0,0x93,0xac,0x41,0xca,0xf8,0x2b,0x65,0xaf,0xb6,0x48,0xca,0x7,0xbc,0xf6,0xe8,0xbe,0xb,0x92,0x7f,0x2b,0x5f,0x12,0xd6,0xe2,0xd6,0x9b,0xaf,0xc7,0xff,0xf4,0x2f,0x3e,0x8,0xe7,0x58,0x2d,0x67,0x9d,0xe6,0x7,0x5a,0x63,0xf1,0xf6,0x7b,0x5e,0x83,0x7f,0xfd,0xdb,0x1f,0xc5,0xb1,0x2b,0x2f,0xff,0xb9,0xf7,0x65,0x7d,0x6d,0x8e,0x8f,0x7f,0xf8,0x3d,0xf8,0xd0,0x3b,0xee,0x45,0x68,0x67,0x93,0xd2,0xf,0x50,0x99,0x89,0x34,0x23,0x3b,0x37,0x92,0x77,0x39,0x4f,0x1a,0x7c,0x2d,0x37,0x2e,0x7,0x55,0x7a,0xa,0xe1,0x27,0x65,0x28,0x29,0x45,0x3d,0x7,0x34,0x76,0x32,0x4a,0x4a,0xdc,0x90,0x4c,0x99,0x89,0xfd,0xf6,0x26,0x5c,0x68,0x91,0x63,0xac,0x17,0x6e,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0xc5,0x25,0x87,0x4a,0x0,0x56,0x54,0x54,0x5c,0x34,0x48,0x23,0xef,0x98,0xf3,0xe7,0xd4,0xd6,0xab,0xe4,0xb,0x37,0xbf,0x52,0xeb,0x6e,0xd4,0x92,0xa,0x69,0xbb,0xbd,0xfa,0xe8,0x7e,0x34,0x21,0xec,0x5a,0x76,0x4a,0x9,0x4f,0x3d,0x77,0x9c,0x8,0x45,0x40,0xed,0x9d,0x71,0xe8,0x49,0xd,0xc6,0x4,0x91,0xf7,0x1,0x6,0x16,0x71,0x18,0xb0,0xdc,0xde,0x2,0x8c,0xc1,0xd0,0x77,0xd8,0x3a,0x77,0x1a,0xc3,0xd0,0x63,0xb1,0xb5,0x89,0x14,0x23,0x16,0x5b,0x9b,0xc8,0x39,0x21,0xa5,0x84,0xad,0x73,0x67,0x74,0xfb,0x9b,0x76,0x6,0x1f,0x2,0x66,0xb3,0x35,0x18,0x56,0xa2,0x95,0x2,0xbc,0xf0,0xd2,0xcb,0x58,0x6c,0x2f,0x77,0xdf,0x54,0xad,0xc5,0x95,0x87,0xf,0xf0,0x36,0x46,0xc,0xfd,0x12,0xce,0x39,0x18,0x6b,0x10,0x66,0x33,0x5c,0x73,0xf9,0x1,0xfc,0xce,0x6f,0xbe,0x17,0x97,0x1f,0x3d,0xf4,0xb,0x38,0xbe,0xdc,0xfb,0x59,0x80,0x94,0x6,0xb6,0x4d,0x5b,0xb6,0x1d,0x37,0x7b,0x92,0x71,0x25,0x27,0x6c,0xcc,0x67,0xf8,0x9d,0x8f,0xbd,0xef,0x67,0x92,0x7f,0xd3,0xf3,0xf8,0xd3,0x67,0x5e,0x0,0x8c,0x83,0xf7,0x9e,0x72,0xf6,0x60,0x10,0x9a,0x16,0x6f,0xbd,0xfb,0x26,0x7c,0xe2,0xc3,0xef,0xc6,0x6c,0xd6,0xfe,0xcc,0x65,0x5c,0x8,0xde,0x39,0xbc,0xf7,0x9d,0x6f,0xc1,0x5b,0xef,0xbc,0x81,0x8f,0x21,0xa9,0xf0,0xc,0xc,0x5c,0x68,0x94,0x74,0xcc,0xac,0xe2,0x73,0xdc,0x50,0x5c,0x4a,0xd1,0xa2,0x8f,0x98,0x22,0x11,0x84,0x3c,0x76,0xc0,0x85,0x24,0xa5,0x14,0xe4,0x44,0xe5,0x30,0x56,0xca,0x52,0xd4,0x2b,0x2c,0xe3,0x26,0xc1,0x35,0x33,0xe4,0x34,0xc0,0x85,0xb6,0x5e,0xb8,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x97,0x1c,0xaa,0x5,0xb8,0xa2,0xa2,0xe2,0xa2,0x41,0xd4,0x59,0x80,0x81,0x35,0x76,0x42,0xf2,0x59,0x52,0xa8,0x81,0x18,0xac,0x94,0xa9,0x54,0x42,0x8,0x1c,0x21,0x69,0x4a,0xc9,0x38,0x78,0x60,0xff,0x9e,0x44,0x56,0x1f,0x13,0xce,0x6d,0x77,0x6a,0xab,0xa5,0xb6,0x5e,0xca,0xf3,0x1b,0x86,0x9e,0xda,0x7e,0xfb,0xc4,0xc4,0x53,0x61,0x8b,0x68,0x41,0x8a,0x44,0xca,0x59,0xef,0xa9,0xf9,0xb7,0x5f,0x52,0xb3,0x2e,0x2b,0xc8,0xbc,0xf,0x38,0x7f,0xf6,0x34,0x42,0x3b,0xa3,0xdc,0xc0,0x14,0x61,0xad,0xe7,0xfd,0x1,0x42,0x33,0x87,0xb5,0x16,0xa7,0x36,0x17,0xd8,0x5a,0x6c,0x63,0x63,0x63,0x6d,0xd7,0xb6,0x1d,0xdc,0xbf,0x4e,0x5,0x15,0x85,0x14,0x6a,0x3d,0xab,0xa,0xe7,0xc1,0xe1,0x77,0x3e,0xfa,0x2e,0xec,0x5b,0xdf,0xfd,0x99,0x52,0xa,0x16,0xcb,0xe,0x9b,0xe7,0x17,0x48,0x39,0x61,0x6d,0xd6,0xe2,0xc0,0xfe,0x8d,0x5d,0xfb,0xbe,0xbd,0x58,0xe2,0xaf,0xbe,0xfa,0xf7,0xd8,0x3c,0x77,0x4e,0x55,0x7e,0x39,0x27,0x3c,0x7b,0xfc,0xac,0x36,0x1f,0x87,0xa6,0x65,0x6b,0x6c,0xd9,0xf5,0x79,0xe7,0x3c,0x3e,0xfa,0xce,0x7b,0x71,0xf9,0x91,0xcb,0x0,0x10,0x91,0x7a,0x7e,0x6b,0x81,0x73,0x9b,0x5b,0x30,0x86,0x2c,0xcc,0x3b,0xc9,0xbc,0xe3,0x27,0x4e,0xe1,0xbf,0x7d,0xe3,0x7b,0x4a,0xd8,0x1a,0x0,0xc6,0x3a,0x5c,0x7d,0x64,0x1f,0x3e,0xf2,0xfe,0xb7,0xef,0x49,0xd0,0xc6,0x98,0xf0,0xec,0xb,0x2f,0xe1,0xd1,0x27,0x9e,0xc7,0x4b,0x27,0x4e,0x62,0x48,0x5,0xfb,0x36,0xd6,0x70,0xdd,0x95,0x87,0x70,0xe7,0xad,0x37,0x60,0xff,0xbe,0x55,0xe5,0xa3,0x77,0xe,0xbf,0xf1,0xbe,0xb7,0xe1,0xc7,0xcf,0x1c,0xc7,0x8b,0x2f,0x9f,0xa6,0x2c,0x40,0xf4,0x88,0x3,0x95,0xb1,0x90,0x8a,0x8f,0x6c,0xbe,0xd4,0x94,0xec,0x50,0x72,0x41,0x8a,0x3,0xb5,0x48,0x23,0xb3,0xb2,0xb3,0x90,0xfa,0x8f,0xc9,0xe6,0xb1,0x19,0x1a,0xda,0x92,0x2c,0x2f,0x58,0x6b,0x11,0x87,0x8c,0x2,0xca,0x9c,0x4c,0x31,0x22,0xd,0x5d,0xbd,0x70,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2e,0x39,0x54,0x2,0xb0,0xa2,0xa2,0xe2,0x22,0xc3,0x20,0xe7,0x48,0xcd,0xb5,0x28,0x70,0xce,0x31,0xc9,0x97,0x57,0x2d,0xc2,0xfc,0x4f,0xe6,0xdc,0x36,0x51,0x71,0xcd,0xdb,0xb0,0xe7,0x52,0xe3,0x10,0x31,0x70,0x5b,0x43,0x4a,0x44,0x2,0x96,0x92,0x11,0xe3,0x80,0xc2,0xf9,0x82,0xdd,0x62,0x9b,0x1b,0x6a,0xa1,0x36,0x5f,0x52,0x84,0x25,0x98,0x52,0x10,0xf9,0xf7,0x94,0x7a,0x52,0x95,0x59,0x6a,0x0,0x9e,0xaf,0x6f,0xa0,0x94,0x8c,0xf9,0xfa,0x3e,0x26,0x7,0x3d,0x86,0x6e,0x89,0xd0,0xce,0x0,0x14,0xcc,0xd6,0xc8,0xe2,0xdb,0x75,0x7b,0xdb,0x45,0x37,0xd6,0xd7,0x69,0xb9,0x31,0xc2,0x58,0x7,0x6b,0x69,0x1f,0xdf,0x7c,0x7,0x15,0x7d,0xec,0xc4,0x62,0xd9,0xe3,0xeb,0xdf,0x7e,0x4,0x7f,0xf7,0x83,0xa7,0xb0,0xb9,0xbd,0x44,0xc9,0x9,0xeb,0x6b,0x6b,0xb8,0xf5,0xda,0x23,0x78,0xcf,0xfd,0xf7,0xe0,0x72,0x56,0x14,0x2,0xc0,0xda,0x7c,0x86,0xb7,0xdc,0xf3,0x1a,0xfc,0xbb,0x4f,0x7e,0x19,0x5d,0x4c,0xc8,0x89,0x8a,0x4f,0x42,0xd3,0x22,0xc5,0x1e,0xcd,0x6c,0xd,0x94,0x6b,0x87,0x3d,0x89,0xd3,0x63,0x97,0x1f,0xc2,0xeb,0xee,0xb8,0x5,0x0,0x70,0xea,0xf4,0x39,0x7c,0xf6,0x2b,0xdf,0xc6,0xf7,0x7f,0xf2,0x3c,0xfa,0x4,0x94,0x1c,0x71,0xf4,0xc0,0x1a,0xde,0xf5,0x96,0xd7,0xe1,0xde,0x3b,0x6e,0x46,0xdb,0x36,0x88,0x31,0xe1,0x2f,0xbf,0xf4,0x4d,0x6c,0x2d,0x7b,0xb6,0x46,0x17,0xa0,0x14,0x58,0x0,0x1f,0x7b,0xff,0xfd,0xd8,0xd8,0x83,0xcc,0x3c,0x71,0xf2,0x34,0x3e,0xf5,0xf9,0x6f,0xe0,0x47,0xcf,0x9d,0xd2,0xf6,0x63,0x39,0xdf,0xdf,0x79,0xf4,0x49,0xfc,0xd5,0xd7,0x1e,0xc2,0x6f,0xbe,0xef,0x3e,0xbc,0xfe,0xae,0xdb,0x56,0xb6,0xf1,0xc0,0xfe,0x7d,0x78,0xef,0xfd,0x77,0xe3,0x3f,0xfd,0xe5,0xd7,0x55,0xd,0x6a,0x6d,0x42,0xce,0x99,0x33,0x18,0x69,0x2c,0x94,0x52,0x80,0x9c,0x91,0x4b,0x62,0xcb,0xb0,0xa1,0x71,0xe3,0x2,0x4a,0x8e,0x54,0x50,0xc2,0x56,0x5e,0xe7,0x3d,0x86,0x14,0x61,0x9d,0x57,0xeb,0x37,0x65,0x7,0x26,0x2d,0x2,0xb6,0xd6,0x21,0xd,0x1d,0x17,0x84,0x94,0x7a,0xc9,0x56,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x72,0xa8,0x16,0xe0,0x8a,0x8a,0x8a,0x8b,0x6,0x6a,0x6c,0x95,0x9f,0xb,0xdb,0x55,0xb,0x72,0x8a,0xc8,0x89,0x1a,0x5f,0xc5,0xa6,0xb,0x56,0xb2,0x59,0xce,0x7d,0x23,0xa2,0xc6,0x61,0x7d,0x6d,0x6f,0x9b,0xea,0x10,0x23,0xba,0xbe,0x23,0x35,0xa1,0xf3,0x63,0xbb,0x6b,0x2e,0xb0,0xde,0x23,0xe,0x3,0x9c,0xf7,0x8,0x4d,0x4b,0xb6,0x60,0x26,0xca,0xe2,0xd0,0x93,0x9a,0x2c,0x45,0xc4,0x14,0xc9,0x52,0xea,0x2,0x66,0xf3,0x75,0xce,0x21,0x74,0xfc,0xb3,0x58,0x91,0xc9,0x8a,0x1a,0xda,0x19,0xbc,0xf,0x98,0xad,0x6d,0x20,0xa7,0x4,0x6b,0x1d,0x6,0x2e,0xad,0xd8,0x89,0xe0,0x49,0xf5,0x97,0x52,0x42,0x91,0xdc,0xc1,0x9c,0x70,0xef,0x9d,0x37,0xef,0x7a,0xef,0xf9,0xad,0x5,0xfe,0xf0,0x3f,0x7f,0x11,0x5f,0xfa,0xce,0x8f,0xb0,0xb9,0xb5,0xe0,0xec,0x3a,0x87,0xad,0xed,0x5,0x1e,0x7a,0xfc,0x39,0xfc,0xc1,0x1f,0x7f,0x1e,0x4f,0x3f,0xf7,0xe2,0xca,0x67,0xae,0xbe,0xe2,0x8,0x3e,0xf8,0xb6,0x3b,0x91,0xe2,0xa0,0xc4,0xda,0xd0,0x53,0x73,0xae,0x31,0x46,0x1b,0x97,0xf7,0x72,0xdd,0xbe,0xe9,0xde,0xdb,0xe0,0xbd,0xc3,0xb3,0xcf,0x1f,0xc7,0x1f,0xfc,0xf1,0xe7,0xf0,0xed,0x1f,0x3c,0x89,0x6e,0xc8,0x48,0x69,0x80,0xb1,0xe,0xcf,0xbf,0x7c,0x16,0x7f,0xf4,0xa9,0x2f,0xe3,0xff,0xfa,0xe3,0xcf,0xe0,0xc4,0xc9,0xd3,0xf8,0xfe,0x63,0x3f,0xc6,0x23,0x3f,0x79,0x41,0x89,0x3c,0x63,0xc,0x8c,0x75,0xb8,0xfd,0xc6,0x63,0xb8,0xf1,0xba,0x63,0xbb,0x96,0x7f,0xf2,0xf4,0x59,0xfc,0xdf,0x9f,0xfc,0x12,0x1e,0x7f,0xe1,0xc,0x95,0xbd,0xc4,0x81,0x73,0xf9,0x1c,0x42,0xd3,0x2,0x30,0x58,0xc6,0x8c,0x3f,0xfb,0xd2,0x43,0x78,0xec,0xc7,0x4f,0xef,0xfa,0xfc,0xeb,0xee,0xb8,0x15,0x7,0xd6,0x5a,0x84,0xa6,0xe1,0x75,0xd1,0x39,0x91,0x73,0x2c,0x4a,0x3d,0xcd,0x93,0x2c,0xe0,0x71,0x43,0x4d,0xcb,0xce,0x7,0x2a,0x5a,0x71,0x4e,0x9,0x61,0x52,0x4a,0x4a,0x6,0x60,0xe1,0xf6,0x64,0x33,0x2a,0xa,0x4b,0x6,0x60,0x50,0x8c,0xad,0x16,0xe0,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x4b,0x12,0x95,0x0,0xac,0xa8,0xa8,0xb8,0xa8,0xc8,0x5c,0xca,0x20,0x99,0x6b,0x30,0x6,0xd6,0x3a,0xca,0x6d,0x1b,0x7a,0xb5,0x6d,0x2,0x80,0x31,0x8e,0x55,0x5f,0x96,0xde,0x5e,0x32,0x16,0xcb,0xe5,0xde,0x37,0x2f,0x3,0x34,0x21,0xc0,0x58,0x8b,0x9c,0xc7,0x42,0x7,0x6b,0x2d,0x72,0x22,0x42,0x8b,0x8a,0x38,0x28,0xd7,0x4f,0xf2,0xe3,0x84,0x30,0x8b,0x31,0x62,0x36,0x5b,0x43,0xd3,0xce,0xd0,0xb4,0x33,0xb2,0x9a,0x86,0x86,0xb6,0xc3,0x5a,0xb4,0xf3,0x35,0x84,0xa6,0x25,0x65,0xa0,0x27,0x52,0xd0,0x71,0xfe,0x9d,0xf3,0x1,0xa1,0x6d,0xe1,0xfd,0xde,0x22,0xea,0x7e,0x88,0xf0,0xde,0x23,0xa5,0x48,0x84,0x63,0x1c,0x30,0xf,0x16,0x47,0xe,0xaf,0xe6,0xfe,0x95,0x52,0xf0,0xa5,0x6f,0x3c,0x8c,0xa7,0x8e,0x9f,0x43,0x4e,0xa4,0x48,0xf3,0x21,0x20,0xc7,0x48,0xdb,0x52,0xa,0xb6,0xbb,0x1,0x7f,0xfe,0xc5,0x6f,0xa3,0xeb,0x47,0xb2,0xd1,0x18,0xe0,0x9e,0xdb,0x6f,0xc6,0xa1,0xfd,0x1b,0x9c,0x6f,0x67,0xb8,0x5d,0xd8,0x8e,0x6f,0x28,0x7b,0xab,0xd9,0xda,0xa6,0xc1,0xe6,0xf9,0x5,0xfe,0xe3,0x7f,0xfd,0xa,0x4e,0x9f,0xa7,0x52,0x13,0x1f,0x2,0x4a,0x2e,0x58,0x2e,0xb6,0x88,0x64,0x73,0xe,0x3f,0xf8,0xf1,0xd3,0xf8,0xdf,0xff,0xe8,0x2f,0xf0,0xff,0xfd,0xd5,0xd7,0x31,0xc,0xc3,0x58,0x64,0x62,0x1d,0x50,0x32,0xde,0xfe,0x86,0xdb,0x49,0xcd,0x39,0x41,0x4a,0x19,0x9f,0xfb,0xda,0x43,0xd8,0xec,0x32,0xc,0x9f,0xfb,0xa6,0x9d,0xa3,0x99,0xcf,0x91,0xe2,0xa0,0x24,0xac,0xb5,0x16,0x7d,0x3f,0xe0,0x2f,0xfe,0xfa,0x41,0x6c,0x2f,0x56,0xcf,0xef,0xc6,0xfa,0x1c,0x77,0xdf,0x76,0x23,0xd9,0x7b,0x53,0xa2,0x42,0x18,0x0,0x39,0x47,0x18,0x6b,0x28,0xaf,0x8f,0xcb,0x5d,0xac,0x19,0xc9,0x41,0x18,0xc0,0x3a,0xaf,0xca,0xcb,0xd1,0xae,0x4c,0x6a,0x53,0xf9,0xb7,0xe4,0xb,0x4a,0xf9,0x87,0x1c,0x23,0x63,0x1d,0xac,0x73,0x48,0xfd,0xb2,0x5e,0xb4,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x97,0x1c,0xbc,0x44,0x91,0x82,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x2a,0x1,0x58,0x51,0x51,0x71,0x11,0xc1,0x4,0x94,0xe4,0xb2,0xb1,0xea,0x2a,0x97,0x42,0x4,0x11,0x2b,0xf0,0x44,0xad,0x65,0x8c,0x41,0xe2,0xbf,0x67,0x26,0xed,0x96,0xdd,0xde,0x2a,0xbb,0xa6,0x69,0x46,0xc2,0x8b,0x95,0x6f,0x62,0x1b,0xf6,0x21,0x70,0xfb,0x6e,0x62,0xdb,0x6f,0x46,0x8a,0xd4,0xf0,0x3b,0xf4,0x1d,0x65,0xd8,0x19,0x83,0xed,0xad,0x73,0x6c,0x2f,0x4d,0xaa,0x16,0x24,0x85,0x1f,0xe5,0xfe,0x59,0xeb,0xd0,0xb4,0x73,0x84,0xd0,0xa0,0x14,0x22,0xb3,0xa4,0x64,0x24,0x84,0x6,0x4d,0xb3,0xb7,0x3d,0xb9,0x8f,0xf4,0x5e,0xef,0x3d,0x91,0x50,0xd6,0xe1,0xca,0xc3,0xfb,0x11,0x76,0x10,0x86,0x9b,0xe7,0xb7,0xf1,0xd0,0x8f,0x9e,0x3,0x8a,0x34,0xf8,0x3a,0xa4,0x94,0x34,0x9f,0xd0,0xf9,0x0,0x63,0x1d,0x8e,0x9f,0x5d,0xe0,0xf9,0x97,0x4e,0xae,0x7c,0x76,0x3e,0x6b,0x71,0xc3,0x95,0x97,0xc1,0x3a,0x7,0x1f,0x1a,0x58,0x47,0x44,0x68,0xc9,0x19,0xa1,0x69,0xa9,0xa8,0xe3,0x2,0x8d,0xbc,0x5f,0x7f,0xe0,0x11,0x9c,0xdc,0x22,0xfb,0xb3,0x81,0x21,0xab,0xb2,0xe1,0xcc,0x46,0x63,0x90,0x4b,0x46,0x33,0x9b,0xe3,0xc4,0xc9,0x33,0xd8,0x5c,0x46,0x6a,0x53,0x4e,0x51,0x15,0x75,0xfb,0xd7,0xe7,0xb8,0xee,0x9a,0xab,0x76,0x2d,0xf7,0xd9,0x17,0x4f,0xe0,0x91,0x9f,0x3c,0x4f,0xa4,0xaf,0x73,0x44,0x2c,0x72,0xee,0x22,0x6d,0x93,0x81,0xf,0xd,0x86,0xbe,0x87,0x75,0xe,0x2f,0x9d,0x3c,0x43,0xe5,0x22,0x13,0x18,0x63,0x70,0xe7,0xad,0xd7,0xa3,0x99,0xcd,0xd1,0xb4,0x94,0x65,0x38,0x66,0x34,0x5a,0x56,0xef,0xd1,0xf1,0xca,0x39,0x21,0x27,0xb2,0xfa,0x66,0xb6,0x7d,0x3,0x44,0xfc,0x89,0xaa,0x2f,0x97,0x4c,0x59,0x8e,0x65,0xb5,0xb1,0x99,0x88,0x60,0x56,0x8d,0x8a,0xad,0xd9,0x35,0x28,0xa5,0xb6,0x0,0x57,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x7a,0xa8,0x4,0x60,0x45,0x45,0xc5,0x45,0x43,0x51,0xfe,0x6f,0x2c,0xf5,0x20,0x4e,0x90,0xfe,0x60,0x9d,0x67,0x65,0x59,0x1,0xc,0xdd,0x8e,0xc8,0xd2,0xeb,0x54,0xbd,0x75,0x6e,0x6b,0xb1,0x67,0x83,0x6c,0x13,0x2,0x8e,0x1c,0x58,0x47,0x1c,0x6,0x0,0x64,0x4d,0x1d,0xfa,0x1e,0x25,0x67,0x74,0x8b,0x6d,0x5a,0x76,0x4a,0xf0,0x21,0x70,0x6b,0xac,0xe5,0x22,0x89,0x8c,0x94,0x13,0x52,0x1c,0xb0,0xb6,0xb1,0x1f,0xa1,0x69,0x11,0xda,0x19,0x9a,0xd9,0x5c,0xb,0x35,0xe6,0xeb,0xfb,0xe1,0xbd,0x87,0x75,0x1e,0xc6,0x1a,0x58,0xe7,0x11,0x9a,0x19,0x72,0x4a,0x98,0xaf,0x6f,0x60,0xbe,0xbe,0x1f,0xfb,0x36,0xd6,0xb1,0x6f,0x63,0x7d,0xcf,0xfd,0x3e,0x7b,0x6e,0xb,0x86,0x8b,0x4e,0x72,0xa2,0x22,0x92,0xe0,0x2d,0xd9,0x9b,0x27,0x58,0x2c,0x3b,0x6c,0x77,0x3d,0x42,0xdb,0xc2,0x5,0x22,0xb8,0xbc,0xf,0xb0,0xc6,0xaa,0xb2,0xb1,0x64,0xca,0xf9,0x3b,0x73,0x6e,0x6b,0xe5,0xb3,0xc6,0x0,0x47,0xf,0xed,0x47,0x68,0x1a,0x2e,0x33,0xe9,0x10,0xe3,0xa0,0x36,0x67,0x98,0xbd,0x9b,0x77,0xcf,0x6f,0x2f,0xf1,0x9d,0x47,0x9f,0x46,0xc9,0xb4,0xaf,0xa2,0x9e,0xcc,0x39,0xeb,0x9,0x33,0x30,0x64,0xa7,0xd,0x1,0xfd,0x72,0x81,0x38,0xf4,0x4a,0x2a,0x5a,0x6b,0x71,0xc3,0xb1,0xa3,0x58,0x5f,0x9b,0xed,0x5a,0xf6,0xc3,0x8f,0xfe,0x14,0x85,0x2d,0xb9,0x54,0xc6,0x41,0x76,0xef,0x38,0xf4,0xa4,0xba,0x64,0x2b,0xb6,0xf,0xd,0x72,0x8c,0x30,0xd6,0xe2,0x27,0x4f,0x3d,0xbf,0x6b,0x39,0x57,0x1e,0x3d,0x84,0x14,0x3b,0xb6,0x5a,0xd3,0x71,0x88,0x3d,0x29,0x29,0x75,0x5c,0x19,0xb0,0xd,0x98,0xc8,0x49,0x1f,0x2,0xe2,0xd0,0xeb,0x31,0x30,0xc6,0x8e,0x8a,0x3f,0x43,0x25,0x34,0x5,0xd0,0xf1,0x46,0xea,0xbf,0xd1,0x26,0x9d,0x86,0x5,0x72,0xec,0x61,0x4c,0x8d,0xc6,0xad,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xb8,0xf4,0x50,0x67,0x3a,0x15,0x15,0x15,0x17,0xd,0xa2,0x40,0x23,0xbb,0x25,0xc6,0x2,0x86,0x52,0x50,0xc,0x54,0x89,0x27,0xc5,0x1c,0xce,0x39,0xe4,0x94,0x51,0x72,0xcf,0xe4,0x60,0xc2,0xb,0xc7,0x4f,0x63,0x88,0x71,0x57,0xd3,0x6c,0x8,0x1e,0x97,0x5f,0xb6,0x81,0x67,0x4f,0x9c,0x41,0x8e,0x51,0x95,0x7f,0x39,0x25,0x18,0x6b,0xb5,0xfc,0x63,0xe8,0x3b,0x56,0x2,0xf6,0x70,0xce,0x63,0xbe,0xbe,0x86,0x34,0xf4,0x18,0x86,0x1e,0xc6,0x58,0x34,0xb3,0x39,0x11,0x5b,0xc6,0x20,0x21,0xa1,0x9d,0xad,0xf1,0x76,0x1b,0xb2,0xf8,0x1a,0xa3,0x36,0xe5,0xd0,0xb6,0xdc,0x4a,0xdb,0xe0,0xb2,0x8d,0x19,0x66,0x6d,0xb3,0x6b,0x9f,0x4b,0x29,0x38,0x7e,0xfa,0x3c,0xc,0x8c,0x2a,0xd7,0xac,0x73,0x18,0x62,0x46,0x2e,0x85,0xcb,0x50,0x8,0xce,0x59,0x4,0x67,0x89,0xc4,0x64,0x26,0x2a,0x97,0x2,0x18,0x20,0x84,0x6,0xfd,0x72,0xc1,0xc7,0xd1,0xee,0x59,0x86,0x62,0x9d,0x45,0xdf,0x75,0x94,0xa1,0xc8,0xd9,0x7f,0xd6,0x79,0xa4,0x38,0x8c,0x8a,0xc8,0x1d,0x78,0xee,0x85,0x13,0x38,0xb7,0xbd,0x60,0xf5,0x24,0x15,0x63,0xe4,0x94,0x94,0xa8,0x1c,0xb3,0x18,0xc9,0x2a,0x2b,0xca,0x3d,0xe2,0x6d,0x33,0xbc,0x6f,0x71,0xc5,0xe1,0xdd,0xcd,0xcc,0x29,0x67,0x6c,0x6e,0x75,0x38,0x7a,0x60,0x8d,0x2c,0xde,0x4c,0x2a,0x1a,0x6b,0x49,0xd5,0x68,0x2d,0x4a,0x9e,0x3,0x52,0xfc,0x92,0x13,0x60,0xc,0xb6,0x17,0xcb,0x5d,0x6d,0xc5,0x1b,0x1b,0xeb,0x58,0xb,0x16,0x27,0xb7,0x7,0xe4,0x34,0x0,0xc6,0x22,0x34,0xa4,0x1c,0xcc,0x39,0xc2,0x39,0x87,0x18,0x33,0xb7,0x11,0x5b,0xa4,0x42,0xed,0xd2,0x6,0xd4,0xe2,0x2c,0x79,0x90,0x96,0x49,0xe5,0xa2,0x63,0xd0,0x30,0x29,0xca,0x83,0xd1,0x68,0x21,0x30,0x8c,0x9f,0x71,0x3,0x30,0x93,0xd1,0x3b,0x14,0x83,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0xff,0x94,0x51,0x9,0xc0,0x8a,0x8a,0x8a,0x8b,0x6,0x21,0xa1,0xc8,0xe2,0x4b,0xb6,0x5f,0xb0,0xe5,0x57,0xec,0xaa,0x3e,0x8c,0x65,0xf,0x42,0x14,0x51,0x73,0x2e,0x95,0x70,0x9c,0x38,0x7d,0xe,0x8b,0xc5,0x72,0x17,0x1,0x8,0x0,0x77,0xde,0x7a,0x3,0xbe,0xf3,0xc3,0x67,0x50,0x50,0x28,0xf,0xce,0x7a,0x5d,0x8f,0x10,0x4a,0x43,0xdf,0x63,0xe8,0x97,0x54,0x6,0x61,0x1d,0x91,0x79,0x28,0xd8,0xd8,0x7f,0x10,0xdd,0x72,0xc1,0x85,0x19,0x19,0x61,0xb6,0x86,0xd0,0xce,0x11,0x87,0x8e,0xad,0xbf,0x33,0xe4,0x52,0xd0,0x84,0x6,0x31,0xe,0xaa,0x24,0x74,0xce,0xc3,0x85,0x80,0x3b,0x6e,0xbe,0x1a,0xde,0xbb,0x5d,0xdb,0xd4,0xf,0x3,0x8e,0x9f,0x3a,0x7,0xdf,0x34,0xc8,0x25,0x63,0x16,0x36,0xb0,0x38,0x7f,0xe,0xe7,0xb6,0x3b,0xc4,0x61,0x40,0xd3,0x8c,0xa4,0xe1,0xc1,0xfd,0xfb,0x70,0x64,0xff,0x1c,0xc7,0xcf,0x75,0xab,0x4,0xa6,0x31,0x6a,0xc7,0x75,0xce,0x63,0xde,0x6,0x5c,0x75,0xc5,0x91,0x5d,0xeb,0x3a,0x7b,0xee,0x3c,0x6d,0x67,0x4e,0x4c,0x38,0x52,0xce,0x1d,0x2e,0x50,0x0,0x2,0x0,0x4f,0x3f,0x7f,0x2,0x25,0x17,0x14,0x64,0x26,0xfd,0xb8,0x44,0xc3,0x79,0xc4,0xa1,0x3,0x38,0x73,0x2f,0xe,0x1d,0x72,0x2e,0x4c,0x14,0x16,0xb4,0xf3,0x75,0xe4,0x4c,0x16,0xe0,0x2b,0x2f,0xdf,0xdd,0x64,0xec,0xac,0xc5,0x6f,0x7d,0xf8,0x57,0xe8,0x17,0x56,0x79,0x8a,0xd8,0x73,0x24,0xf7,0x8a,0xfe,0xbf,0x64,0xfb,0x91,0xf5,0x78,0x95,0x4c,0x6c,0x42,0xc0,0xfe,0x8d,0x75,0x9c,0xdd,0xea,0x90,0x8c,0xa1,0xd2,0x18,0xde,0x21,0xb5,0x49,0x5b,0x87,0x6c,0xc6,0x6c,0x47,0x6b,0x2d,0xb2,0x58,0xcd,0x2d,0xa9,0x3d,0x65,0x1d,0x28,0x50,0xbb,0x33,0xc,0x8d,0x41,0x63,0x2d,0x4a,0x1c,0x40,0x9c,0x67,0x46,0xee,0xb7,0xe0,0x9a,0x39,0x4a,0x31,0x48,0xfd,0xf9,0x7a,0xf1,0x56,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x52,0xa8,0x16,0xe0,0x8a,0x8a,0x8a,0x8b,0x6,0x51,0x95,0x95,0x9c,0xd9,0xca,0x1a,0x55,0xed,0x57,0x32,0x29,0xc1,0x62,0x1c,0x10,0x7,0x69,0x8a,0xb5,0x44,0x7c,0x95,0x82,0x94,0x22,0xa,0xa,0xba,0x3e,0xe2,0xc5,0x97,0x4e,0xec,0xb9,0xfc,0x1b,0xaf,0xbd,0x12,0xb3,0xe0,0xd8,0xee,0x59,0xd4,0xc6,0x6a,0xb8,0x48,0xa4,0x0,0x68,0xda,0x16,0xce,0x7b,0xc,0xdd,0x12,0x3e,0x34,0x58,0x6e,0x9f,0xc7,0x7c,0x7d,0x1f,0x0,0xa0,0x9d,0xcd,0xb9,0x4,0x64,0x8e,0x9c,0x13,0x9a,0xd9,0x4c,0xed,0xc0,0x30,0x6,0x81,0xc9,0x3f,0xeb,0x88,0x90,0xa4,0xd6,0xdd,0x82,0x1c,0x7,0xdc,0x75,0xdb,0x4d,0x7b,0x6e,0xd3,0x99,0xb3,0xe7,0x71,0x66,0xbb,0x9f,0x94,0x72,0x14,0x84,0x76,0x86,0x17,0x4e,0x9c,0xc6,0xa9,0xd3,0x67,0x57,0xde,0xeb,0xbd,0xc3,0x7b,0xde,0x7a,0xb7,0xaa,0xd1,0xa4,0xbc,0x22,0xa5,0x84,0xd8,0x77,0x94,0x5d,0x97,0x13,0xde,0x7a,0xe7,0xb5,0xd8,0xbf,0xb1,0xda,0x86,0x3c,0xc4,0x88,0x67,0x8f,0x9f,0x43,0xb7,0xd8,0x42,0xec,0x7b,0x55,0x3c,0xfa,0xd0,0x70,0xf3,0x6e,0xda,0x93,0x4,0x3c,0xbb,0x79,0x1e,0x39,0x27,0xa4,0x14,0xc9,0x36,0x3c,0xf4,0xb4,0x6f,0x69,0x0,0x60,0x90,0xe2,0xc0,0x99,0x80,0x94,0x21,0x38,0xc,0x3d,0x9c,0x6f,0xb0,0xdc,0x26,0xb,0xf2,0xd0,0x2d,0x31,0x6b,0xf7,0x7e,0x76,0xe4,0x9d,0xa3,0x7f,0xbc,0x83,0xf7,0x1e,0xc1,0x7b,0x84,0xe0,0xf9,0x77,0x7a,0x4d,0x5e,0x97,0xd7,0x76,0x16,0x89,0x0,0xa4,0x12,0x3d,0xb8,0x6f,0xd,0x0,0x90,0x52,0xd4,0xed,0x21,0xd2,0xb8,0x90,0xe2,0x11,0xd0,0x6d,0xb4,0xd6,0x51,0x46,0x20,0x2b,0xfb,0xa4,0xb0,0x4,0x4c,0x40,0x17,0x88,0xc2,0xb0,0xb0,0xb2,0xd1,0x8c,0xef,0x61,0x3a,0xd2,0x86,0x39,0xc8,0x1d,0x9c,0xea,0x85,0x5b,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0xc9,0xa1,0x12,0x80,0x15,0x15,0x15,0x17,0xef,0x6,0x23,0xa5,0x17,0x24,0xc9,0x9b,0x64,0x1,0x16,0x26,0xfb,0x48,0xe1,0x26,0x90,0xa2,0x89,0xc2,0xaa,0xb1,0x9c,0x12,0x52,0x8e,0x78,0xe0,0xbb,0x8f,0xed,0xb9,0xfc,0x7d,0x1b,0x6b,0x78,0xf3,0x9d,0x37,0x70,0xe9,0x43,0x81,0xf3,0x1e,0x91,0xc9,0x2f,0xc9,0x6,0x24,0x92,0x6b,0xc0,0xfa,0xbe,0x83,0xf0,0xa1,0xc1,0x81,0xc3,0x97,0x93,0xba,0xd0,0x3a,0xb4,0xf3,0x75,0xb4,0xb3,0x35,0xf8,0x10,0xb0,0xb6,0x71,0x0,0x69,0x18,0x58,0x49,0xe8,0x54,0xbd,0x68,0x8c,0x41,0xd3,0xcc,0x34,0x4f,0xce,0x39,0x8f,0xd7,0xde,0x78,0x6c,0x4f,0x15,0x1c,0x0,0x3c,0xf1,0xf4,0x4b,0xe8,0x3b,0xca,0xbc,0xb,0xa1,0xd5,0xec,0xc3,0x98,0x12,0xbe,0xfd,0xf7,0x8f,0xec,0x7a,0xff,0x5d,0xb7,0xdd,0x88,0x8f,0xbd,0xf3,0x6e,0x1c,0x58,0x9f,0x11,0xe9,0xc9,0xac,0x5d,0xca,0x9,0xde,0x59,0xbc,0xeb,0xd,0xaf,0xc1,0x3b,0xdf,0x7a,0xcf,0x2e,0x95,0xdc,0xb,0xc7,0x4f,0xe1,0x99,0xe3,0xa7,0xb4,0xc4,0x24,0xa7,0x84,0xbe,0xef,0xb0,0xbd,0x49,0x24,0xa3,0xd8,0xae,0x77,0x62,0x18,0x6,0x2e,0x39,0xa1,0x9c,0x45,0xcb,0x76,0xe9,0x9c,0x12,0xfa,0x6e,0x81,0xbe,0x5b,0x2,0x28,0xdc,0x9c,0x9c,0xd0,0xb6,0xb3,0x95,0x8c,0x3d,0x1f,0x9a,0x15,0x1b,0xf3,0x45,0x19,0x37,0xd6,0xc0,0x94,0xc8,0xad,0xc4,0x64,0x15,0xee,0x96,0xdb,0x44,0xf4,0x82,0x8f,0xe7,0xd0,0x43,0x14,0x85,0x39,0x27,0x74,0xcb,0x5,0xe5,0x35,0x7a,0x4f,0xe3,0xca,0x7,0x56,0x7b,0x42,0x15,0x80,0x30,0x56,0xc7,0x98,0x8c,0x3f,0x29,0x90,0x29,0x69,0x0,0x72,0x8f,0x52,0xbf,0x16,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2e,0x41,0x54,0xb,0x70,0x45,0x45,0xc5,0xc5,0x83,0x2a,0xd0,0x8c,0x36,0x37,0x88,0x12,0x8b,0xda,0x71,0x49,0xd5,0xa5,0x6f,0x2f,0x52,0xe,0xe2,0x50,0x72,0x66,0x12,0x7,0x78,0xf8,0xb1,0x27,0xf1,0xb1,0xed,0x5,0xd6,0xd7,0x56,0x55,0x70,0xd6,0x5a,0xdc,0xff,0xc6,0xbb,0xf0,0xc0,0xa3,0x4f,0x63,0xd1,0x1,0xcb,0xc5,0x16,0xac,0xb5,0xe8,0x87,0x9e,0x88,0x44,0xb1,0xb0,0x96,0x2,0x63,0xa9,0x15,0xd8,0x9b,0x80,0x9c,0x33,0xe6,0x6b,0x1b,0xe8,0xbb,0x5,0x59,0x90,0xad,0x45,0x1c,0x3a,0xf8,0xd0,0x6a,0xb3,0xf0,0xd0,0xf,0xf0,0xa1,0x41,0xb0,0x2d,0xfa,0x6e,0x89,0x76,0xbe,0x46,0xa4,0x9a,0xb5,0x78,0xef,0xfd,0xf7,0xc0,0xb9,0xdd,0x44,0xd1,0x10,0x23,0x1e,0x7a,0xf4,0x9,0x38,0xef,0xc7,0x9c,0x43,0x26,0xcb,0xbc,0xf,0xf8,0xea,0x77,0x1e,0xc3,0x5b,0xee,0xbb,0x7,0x97,0x1f,0x39,0xa4,0x9f,0x31,0x6,0xb8,0xef,0x9e,0xdb,0x71,0xeb,0xcd,0xd7,0xe1,0x89,0x27,0x9f,0xc7,0xf1,0xd3,0xe7,0x51,0x4a,0xc1,0x81,0x7d,0x6b,0xb8,0xf9,0xba,0x2b,0x70,0xf4,0xd0,0xc1,0x5d,0xe5,0x21,0xb9,0x14,0x7c,0xed,0x5b,0xdf,0x25,0xd2,0xcb,0x58,0x74,0xcb,0x5,0x91,0x66,0xac,0x84,0x2c,0x29,0x21,0xc6,0xbd,0xdb,0x93,0x73,0x22,0x85,0x5f,0x4e,0x49,0x49,0xd9,0x7e,0xb9,0x80,0xb,0x1,0xb1,0xa7,0xe3,0xb6,0xbd,0xb9,0x84,0x6f,0x1a,0x38,0xe7,0x31,0xa8,0x42,0x30,0x1,0xdc,0xe8,0x3b,0xb0,0xda,0x70,0x8a,0xbe,0x1f,0xf0,0xc4,0x53,0xcf,0x71,0xd0,0x23,0x59,0xad,0xa5,0x95,0x99,0xce,0x3d,0xfd,0x9e,0x52,0x4,0xca,0xa4,0x8c,0xc3,0x3a,0xca,0xdb,0x63,0xb2,0x4e,0xde,0x7e,0x76,0x73,0xb,0x25,0x13,0x71,0x9a,0x53,0x44,0x4a,0x49,0x89,0xbb,0x64,0xc,0xfd,0x3b,0x8d,0x4a,0xc5,0x92,0x13,0x4a,0xa6,0xaf,0x34,0xe7,0xbc,0x16,0xa1,0xa8,0xd,0xdd,0x5a,0x2a,0xe,0x81,0x3,0x72,0x42,0x8a,0x71,0x32,0xee,0x32,0x6c,0x20,0xa2,0xf3,0x82,0xde,0xe9,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x7f,0xc2,0xa8,0x4,0x60,0x45,0x45,0xc5,0x45,0x43,0x11,0x62,0x27,0x27,0xc0,0x58,0x58,0x67,0x89,0x94,0x73,0x8e,0x88,0xa0,0x4,0x38,0x56,0xa2,0x95,0x9c,0x1,0xeb,0xd8,0x22,0x1c,0xe1,0x9c,0xa7,0xcf,0xc3,0xe2,0xcc,0xe6,0x36,0x1e,0x79,0xf4,0x71,0xbc,0xe5,0x8d,0xaf,0xdb,0xb5,0x8e,0xcb,0x8f,0x1c,0xc2,0x7b,0xdf,0x7c,0x3b,0xfe,0xcb,0x97,0xbf,0x3,0x67,0x9d,0x12,0x8a,0xa4,0xe2,0x8b,0xac,0xf4,0x5b,0x23,0xa5,0x21,0x93,0x71,0xa1,0x69,0x91,0x52,0xc4,0x6c,0xbe,0x8e,0x2,0xc0,0xfb,0x46,0xc9,0xc7,0xbe,0x5f,0x52,0x13,0xaf,0x23,0x1b,0x71,0x8c,0x11,0xce,0x7b,0xb6,0xa1,0x1a,0xdc,0x7f,0xf7,0x4d,0xb8,0xf1,0xba,0x63,0x7b,0xee,0xef,0xb3,0xcf,0x1f,0xc7,0x33,0xc7,0xcf,0x22,0x67,0xb2,0x30,0x87,0xa6,0x25,0xb2,0x2b,0x25,0x2c,0xfb,0x2d,0x9c,0x3d,0x3f,0xe0,0x3f,0xfc,0xd9,0xe7,0xf0,0x6f,0x7e,0xf7,0xbf,0xc3,0xc6,0xfa,0x9a,0x7e,0xce,0x18,0xe0,0xc0,0xbe,0x75,0xbc,0xe1,0xee,0xd7,0xbc,0xaa,0xe3,0xfa,0xc3,0x1f,0x3f,0x85,0xbf,0x7b,0xe4,0xc7,0x80,0xb1,0x88,0xc3,0x92,0x4a,0x3f,0x42,0xc3,0xb9,0x7d,0x99,0x8,0x2f,0x83,0x5d,0xe5,0x1a,0x74,0x5c,0xe8,0x38,0x14,0x14,0x20,0x17,0x56,0xcb,0xd1,0xfe,0x59,0xef,0xd0,0x6d,0x77,0x88,0xb1,0x87,0x61,0x22,0xb4,0xc4,0x32,0xb1,0x15,0x67,0xf8,0xa6,0xc5,0xf9,0xad,0xc5,0x5e,0x67,0x1b,0x9f,0xfe,0xf2,0x77,0xf0,0xc2,0xa9,0x73,0xf0,0xce,0x23,0x97,0xac,0x56,0xdd,0x61,0xe8,0xd5,0x4e,0x1d,0xfb,0xe,0x5,0x40,0x12,0xeb,0x77,0x29,0x70,0xce,0xa1,0x5b,0x6e,0xc3,0x5a,0x87,0x6e,0xb9,0x40,0x68,0x1a,0x2c,0x17,0xdb,0x30,0x0,0xba,0x6e,0xa1,0xb6,0x5e,0xe7,0xa9,0xb4,0x44,0x95,0xa5,0xa0,0x7c,0x40,0x18,0x6a,0x6a,0x2e,0x28,0xda,0x1c,0xac,0x39,0x80,0x86,0xc8,0x47,0x21,0x30,0xc1,0xaa,0x3f,0x68,0x21,0x8,0xb8,0x25,0x84,0xb2,0x3,0x4b,0x1a,0xea,0x85,0x5b,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0xc9,0xa1,0x7a,0x9d,0x2a,0x2a,0x2a,0x2e,0x1e,0x58,0xd5,0x55,0x40,0x6a,0x3d,0x69,0x85,0xd5,0xd2,0x8a,0x9,0x11,0x63,0xd8,0x92,0x99,0x52,0xa4,0xcc,0x40,0x6e,0xa4,0x15,0xf2,0xe7,0x73,0x5f,0x7d,0x0,0x8b,0xe5,0x72,0xd7,0x2a,0x8c,0x1,0xee,0xbf,0xef,0x6e,0xbc,0xee,0x96,0x6b,0xc8,0x9e,0x6a,0x49,0x3d,0x28,0x19,0x82,0x71,0xe8,0x57,0x54,0x60,0xce,0x7,0x6e,0xa4,0x1d,0xcb,0x23,0x24,0xaf,0xaf,0x94,0x8c,0x10,0x5a,0x18,0x63,0x95,0x14,0xc,0xa1,0xe1,0xd7,0x80,0xeb,0xaf,0x3a,0x8c,0xf,0xbc,0xe3,0x8d,0x7b,0xaa,0xff,0x72,0x29,0xf8,0xda,0x3,0x3f,0x40,0xdf,0xf7,0x88,0xb1,0xa7,0xa6,0xda,0xa1,0x47,0x2e,0x19,0x2e,0x4,0x78,0x2e,0x10,0x79,0xec,0xc9,0xe7,0xf1,0x7f,0xfe,0xe1,0x9f,0xe2,0xf8,0xf1,0x97,0xff,0x41,0x87,0xf4,0xe9,0xe7,0x5e,0xc4,0x1f,0xfd,0x97,0x2f,0x21,0xe7,0x82,0x6e,0xb1,0x85,0x6e,0xb1,0x8d,0x14,0x7,0xc,0xfd,0x12,0x29,0x46,0x74,0xcb,0x6d,0x26,0xd7,0xfa,0x3d,0x3f,0x2f,0x4,0x69,0x4e,0x6c,0x1d,0xe6,0x63,0xd5,0x77,0xb,0xc,0x5d,0x87,0x6e,0xb9,0x8d,0x52,0xa4,0x3d,0x99,0xda,0x75,0xfb,0x6e,0x81,0x38,0xc,0x18,0x86,0x1e,0x7d,0xb7,0xc0,0x4b,0x27,0x4e,0xee,0x5a,0x6e,0xd3,0x34,0xb8,0xe1,0xd8,0x21,0x55,0x16,0x1a,0x50,0x73,0x70,0xce,0x19,0x21,0x10,0xa1,0x17,0xfb,0xe,0x96,0x2d,0xdf,0x39,0x67,0xc4,0xa1,0x83,0x31,0x40,0x8c,0xb4,0xec,0x38,0xf4,0xb0,0xce,0x61,0xb1,0x7d,0x1e,0x69,0xe8,0xb1,0x5c,0x6c,0xc1,0xf0,0x7b,0x33,0xab,0xf6,0xfa,0x6e,0x89,0x6e,0x7b,0x6b,0xa2,0x42,0xa4,0xc,0x40,0x39,0xef,0x40,0xd1,0x8c,0x43,0xfd,0xbb,0xf3,0x30,0xac,0x90,0x14,0x25,0xa0,0xe,0x1e,0x29,0x2b,0x91,0xb6,0xe7,0x5c,0xdb,0x7f,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2e,0x3d,0x54,0x2,0xb0,0xa2,0xa2,0xe2,0xe2,0x81,0xd5,0x67,0x56,0xb,0x1c,0xa8,0xc,0x24,0xc5,0x81,0x73,0x1,0xe9,0x6d,0x25,0x67,0x25,0x63,0xac,0x19,0xd5,0x5b,0x31,0x46,0x22,0xb,0x8d,0xc1,0x33,0x2f,0x9e,0xc4,0xc3,0x8f,0xfc,0x68,0xcf,0xd5,0xcc,0xda,0x6,0xff,0xec,0x43,0xbf,0x8a,0x23,0xfb,0xe7,0x48,0x29,0xc2,0x85,0x40,0x2d,0xb1,0x29,0xc1,0x7,0x56,0xf7,0x31,0x9,0x18,0x9a,0x16,0xed,0x6c,0x1d,0xf3,0x8d,0xfd,0x68,0xe7,0xeb,0x70,0xce,0x53,0x16,0x9e,0x73,0xb0,0xce,0x53,0xd3,0xaf,0xf,0x70,0x9e,0x7e,0xe6,0x2d,0xc4,0xb1,0xcb,0xf,0xe3,0xf7,0x3e,0xfe,0x3e,0x1c,0x38,0xb0,0x6f,0xcf,0x6d,0xf8,0xc9,0x53,0xcf,0xe1,0xd1,0x27,0x5f,0x22,0x92,0xc9,0x58,0x55,0xe2,0xa5,0x38,0x10,0xc1,0xe8,0xbc,0x92,0x6f,0x8f,0x3d,0x7d,0x2,0xff,0xeb,0xbf,0xfb,0x53,0x7c,0xe3,0x3b,0xdf,0xc3,0x62,0xd9,0xbd,0xaa,0x43,0xb9,0x5c,0x76,0x78,0xe0,0xe1,0xc7,0xf0,0xbf,0xfd,0xe1,0x7f,0xc5,0xe6,0x36,0xb5,0x1a,0x93,0x92,0x8f,0x8e,0x73,0xdf,0x2d,0xa9,0xd,0xd9,0x52,0xa9,0x46,0x8a,0xfd,0x2e,0xf5,0x1f,0xed,0x4a,0xe1,0xa2,0x8f,0x41,0xb7,0x4f,0x4e,0x44,0xce,0x89,0xed,0xd0,0x3d,0x7c,0x8,0x18,0xba,0x5,0x7a,0xce,0xde,0xeb,0xbb,0xa5,0xda,0xa9,0x9f,0x78,0xea,0x79,0x56,0xd4,0xad,0xe2,0xde,0x3b,0x6e,0x42,0x8a,0x3d,0x86,0xa1,0x43,0xce,0x9,0x91,0xad,0xd8,0xa4,0xee,0x33,0xba,0xec,0x7e,0xb9,0x40,0x1a,0x6,0x2e,0xf6,0xc8,0x40,0x1,0x2b,0x3e,0x8b,0x96,0x7a,0xe4,0x92,0xe1,0x9c,0x47,0xdf,0x77,0x58,0x6c,0x6d,0x52,0x46,0xe1,0x72,0x81,0xbe,0x5b,0x20,0x97,0x8c,0xa1,0x5b,0x2a,0xc9,0x47,0xfb,0x20,0xd6,0x5d,0xa3,0xcb,0x31,0x30,0x9c,0x71,0x38,0x68,0xa1,0x8a,0xb4,0x6,0x97,0x92,0xa9,0x10,0x18,0xd0,0xa2,0x1a,0xca,0x2,0xec,0xea,0x75,0x5b,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0xc9,0xa1,0x12,0x80,0x15,0x15,0x15,0x17,0xd,0x42,0x40,0x91,0xad,0x37,0x6b,0xbe,0x9e,0x75,0x5e,0xd5,0x56,0x42,0xe2,0xe4,0x24,0xe4,0x4c,0x66,0xd5,0x9e,0x1d,0x3f,0x5b,0x48,0x95,0xf5,0x67,0x9f,0xfd,0x3a,0x5e,0x3e,0x75,0x7a,0xcf,0x75,0x1d,0xd8,0xbf,0x81,0xff,0xf9,0xb7,0x3f,0x84,0xdb,0xae,0xbf,0x12,0x29,0x46,0x56,0xf5,0x51,0x43,0xf0,0x6c,0x6d,0x3,0xed,0x6c,0xe,0xc3,0xbf,0x1b,0x4b,0xd6,0x51,0x22,0x17,0x59,0x15,0x56,0x0,0xe7,0x1c,0xcc,0x24,0xb7,0x2f,0xa7,0x8,0xeb,0x3c,0xae,0x3e,0x7a,0x0,0xff,0xea,0xe3,0xef,0x59,0xc9,0xee,0x9b,0x62,0x7b,0xb1,0xc4,0x9f,0x7f,0xfe,0x9b,0x18,0x86,0x8,0xb1,0x99,0x4a,0xa3,0xaf,0xb5,0xe,0x43,0xdf,0x31,0x29,0x65,0x49,0x21,0x7,0xe0,0xec,0xb9,0x73,0x78,0xe1,0xc5,0x97,0x71,0x72,0x47,0x33,0xb0,0xa0,0x94,0x82,0x65,0xd7,0xe3,0x85,0xe3,0x27,0xf1,0x95,0x6f,0x3e,0x8c,0xff,0xe3,0x3f,0x7e,0x6,0xff,0xe1,0xd3,0x5f,0x43,0xcc,0xcc,0x9c,0x96,0x2,0x67,0xbd,0x2a,0xb,0x43,0xd3,0x2a,0xe1,0x16,0xe3,0x80,0xb,0xd5,0x74,0xa4,0x4c,0x65,0x26,0xb2,0x8d,0x0,0x35,0xed,0x3a,0xe7,0x89,0x44,0x2c,0x5,0x29,0xf6,0x58,0x6e,0x9f,0x47,0x4a,0x44,0x8,0xe,0xdd,0x12,0xde,0x13,0x89,0x19,0x9a,0x19,0x9e,0x78,0xfa,0x45,0x6c,0x9e,0xdf,0xda,0xb5,0xec,0xeb,0xaf,0x3d,0x86,0x5b,0xae,0xbd,0x2,0x39,0x26,0x38,0x1f,0x98,0xec,0x8d,0x70,0x3e,0x50,0x39,0x4b,0x29,0x28,0x28,0x54,0x34,0xc2,0x16,0xe5,0x38,0xc,0xc8,0x25,0xa9,0x5d,0x58,0x8e,0x8f,0xf,0xd,0x8d,0x15,0x63,0xe1,0xf9,0xf3,0x7d,0xbf,0xc4,0xd0,0xf7,0x58,0x6c,0x9d,0xc7,0x72,0xb1,0x8d,0x81,0xb,0x4b,0xe4,0x78,0x59,0x4b,0xe4,0xeb,0xca,0x71,0xcc,0x19,0x3e,0x4,0x3e,0xcf,0xa4,0x12,0x34,0xbc,0x5c,0x8a,0x26,0xe4,0xb2,0x94,0x92,0x91,0xd3,0x0,0xdb,0xac,0xd7,0xb,0xb7,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xa2,0xe2,0x92,0x43,0xcd,0x0,0xac,0xa8,0xa8,0xb8,0x68,0x10,0x95,0x98,0x34,0xd2,0x1a,0x43,0xca,0x3e,0xef,0x3,0xa9,0xad,0x40,0xaa,0xb3,0x5c,0x32,0xbc,0xb,0x44,0x2,0x82,0x4a,0x40,0x72,0x4e,0x70,0x4e,0xd4,0x6c,0x11,0xc6,0x7,0x9c,0xd9,0xdc,0xc2,0x7f,0xfe,0xf4,0x17,0xf1,0xaf,0xfe,0xe5,0xc7,0xd0,0x34,0x61,0xd7,0xfa,0x2e,0x3b,0xb8,0x1f,0xff,0xfa,0xb7,0x3f,0x8c,0x2f,0xfc,0xf5,0x37,0xf0,0xd9,0xaf,0x3f,0x44,0xcb,0x61,0xa2,0x2f,0xe7,0x8c,0xa6,0x69,0xd1,0xb4,0x2d,0x62,0x8c,0x68,0x67,0x54,0xea,0xa1,0x24,0xa0,0xb3,0xf0,0xa1,0xc1,0xd0,0x93,0x2d,0xd5,0x58,0x7,0x67,0x1c,0xde,0x7c,0xe7,0xf5,0xf8,0xf5,0x77,0xbf,0x15,0x7,0x2f,0xa0,0xfc,0xcb,0xa5,0xe0,0x6f,0x1e,0xf8,0x3e,0x5e,0x3c,0x7d,0x1e,0x29,0xe,0x68,0xda,0x99,0xe6,0xd0,0xa5,0x18,0xa9,0x99,0xd6,0x39,0xd8,0x94,0xb0,0xec,0x3b,0xf8,0xd0,0xe0,0xe6,0xab,0xf,0xe3,0xf7,0xfe,0xf9,0x87,0x70,0xc5,0xe5,0x47,0x94,0xa8,0x2b,0xa5,0xe0,0xf4,0xd9,0x4d,0xbc,0x78,0xe2,0x34,0x9e,0x79,0xf1,0x14,0x5e,0x78,0xe9,0x65,0x3c,0x7f,0xe2,0xc,0xce,0x9c,0x5f,0xa0,0xe7,0x26,0xe3,0x10,0x1a,0xf4,0x3,0x29,0xdf,0x42,0x68,0x41,0xd9,0x76,0x85,0x9,0xd6,0x44,0xa2,0x4a,0x4b,0x6a,0x3d,0x69,0x14,0xde,0xa9,0x2,0x34,0xc6,0xa0,0xef,0x16,0xdc,0x0,0xec,0x90,0x72,0x2,0x4a,0xc1,0xf6,0xd6,0x39,0xc,0xfd,0x12,0xce,0x8d,0xb9,0x7d,0x71,0x7b,0xb,0xed,0x6c,0xe,0xef,0x3,0x9a,0xf9,0x1a,0xdb,0xb1,0x13,0xfa,0x62,0xf1,0xc3,0xc7,0x7f,0x82,0xb7,0xdc,0x77,0xef,0xca,0xb2,0x9b,0x10,0xf0,0xb1,0xf,0xbc,0xd,0x7f,0xf0,0xc7,0x9f,0xc7,0x36,0x2b,0x7,0xf5,0xbc,0xc7,0x8,0xe3,0xd,0x96,0x5b,0xe7,0xd1,0xce,0xe6,0xac,0xf0,0xec,0x81,0x2,0x78,0x3f,0xa3,0x2c,0xc0,0x10,0xe0,0x4a,0xc6,0x5d,0x77,0xdc,0x84,0x6f,0x7d,0xf7,0x87,0x80,0x31,0x70,0x21,0xd0,0x7b,0x97,0xdb,0x18,0x7a,0xb2,0x9,0x87,0xa6,0x41,0x68,0x67,0x6c,0x5d,0xee,0xe0,0x59,0xf1,0x29,0xb6,0x67,0xef,0x3,0x86,0x9e,0x5a,0x82,0xad,0xa5,0x42,0x10,0x6b,0xad,0x6a,0x4,0xa5,0x89,0x5a,0x33,0x1,0xb,0x28,0x7f,0xb2,0x5f,0xa2,0xe4,0x5a,0x2,0x52,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0xe9,0xa1,0x12,0x80,0x15,0x15,0x15,0x17,0xd,0xc2,0x3d,0x59,0xce,0xfd,0x8b,0x43,0x4f,0x6d,0xb3,0x43,0x4f,0xc5,0xd,0xd6,0xa1,0xb0,0xd5,0x33,0xa5,0xc8,0x8a,0x3d,0x83,0x92,0xb,0x8c,0x33,0xc8,0x39,0xc3,0x5a,0x70,0x6b,0x2c,0xa9,0xf3,0x1e,0x78,0xf4,0x69,0x5c,0xf5,0xe5,0xbf,0xc5,0x87,0xde,0xf7,0x2b,0x4a,0x10,0x4e,0x31,0x6b,0x5b,0xfc,0xc6,0xfb,0x7f,0x15,0x77,0xde,0x76,0x33,0x3e,0xf7,0xe5,0xbf,0xc5,0xb7,0xbf,0xf7,0x38,0x52,0xce,0x8,0x4d,0xb,0x1f,0xa8,0x1,0xd8,0x71,0xe,0x9d,0x31,0x86,0xc8,0x48,0x6b,0x60,0x40,0x96,0x61,0xe7,0x2,0x8c,0xb5,0xb8,0xe1,0x8a,0x3,0xf8,0xc0,0x3b,0xde,0x80,0xdb,0x6e,0xb9,0x61,0xcf,0xf5,0x0,0x44,0x24,0x7d,0xe7,0xe1,0xc7,0xf0,0xd9,0xbf,0x79,0x18,0xd6,0x7a,0x18,0x26,0x9e,0x86,0x9e,0x48,0x29,0x0,0xc8,0x43,0xe6,0x8e,0x89,0x8c,0xd9,0xda,0x3a,0xf6,0xb5,0x16,0xff,0xf6,0xbf,0xff,0x38,0xe,0xec,0xdf,0xd0,0xe5,0xc,0x43,0xc4,0x67,0xfe,0xfa,0xdb,0x78,0xf0,0x47,0xcf,0xa1,0xeb,0x7,0x18,0x18,0xb5,0x4c,0x27,0x56,0x46,0x7a,0x4f,0x16,0x62,0xeb,0x9c,0xda,0x65,0x4b,0x26,0x55,0xa1,0xf,0x1e,0xde,0x37,0x48,0x69,0xe0,0x46,0x60,0xa7,0xa,0xba,0x9d,0xb0,0x56,0x14,0x75,0x11,0xc5,0x14,0xa0,0x80,0x9b,0x79,0xb,0xac,0xf3,0x18,0xfa,0x25,0x59,0xb0,0x63,0x54,0x72,0x32,0xe7,0x4c,0x96,0xdd,0xa6,0x61,0xbb,0x76,0xc1,0xd7,0xfe,0xee,0x7b,0x78,0xfd,0xeb,0xee,0xdc,0x45,0xc4,0x5e,0x77,0xf5,0x95,0xf8,0xad,0x5f,0xbb,0x1f,0xff,0xef,0x67,0xfe,0x6,0x9,0xa4,0x78,0x1c,0x3a,0x5a,0x26,0x91,0xab,0x46,0xb,0x3f,0xa6,0x2a,0x4d,0x98,0x82,0x37,0xbc,0xe6,0x7a,0x7c,0xf0,0xdd,0x6f,0xc5,0xda,0xac,0xc5,0xc3,0x3f,0x7a,0x1a,0x83,0xf7,0x74,0xc,0x62,0xc4,0xda,0xbe,0x3,0x38,0x7d,0xe2,0x45,0x0,0x5,0xdb,0x5b,0x9b,0x58,0xe3,0xc,0xc9,0xe9,0xd8,0x21,0xc2,0x37,0x61,0xe8,0x7b,0xb6,0x43,0x73,0x11,0x8,0xe7,0x4f,0x3a,0xe7,0x91,0x4d,0xa1,0x68,0x49,0x14,0x2d,0xa9,0xc9,0x39,0x1,0x25,0xc3,0x35,0xeb,0x88,0xdd,0x56,0xbd,0x70,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2e,0x39,0x54,0x2,0xb0,0xa2,0xa2,0xe2,0xa2,0x81,0xa2,0xf7,0x8c,0x2a,0xae,0x8c,0xb5,0x28,0xa5,0xc0,0x37,0x2d,0xb7,0xb7,0x42,0xcb,0x22,0xe8,0xfd,0xd4,0xfa,0xb,0x2e,0xef,0xf0,0x3e,0x70,0x96,0x1e,0xbd,0x96,0x73,0x81,0xc9,0x9,0x7f,0xf9,0xd7,0xdf,0xc6,0xa1,0x83,0xfb,0xf1,0xb6,0x37,0xdf,0xbb,0x67,0xce,0x9d,0xb5,0x16,0x37,0xdd,0x70,0x2d,0xfe,0xcd,0xef,0xfd,0x33,0x7c,0xe8,0xf9,0x17,0xf1,0xd0,0xf7,0x1e,0xc5,0xf,0x7e,0xfc,0xc,0x9e,0x3f,0x4d,0x65,0x16,0xb3,0xb5,0x39,0x86,0x7e,0xa9,0xf9,0x80,0x25,0x17,0x34,0x21,0xe0,0xf0,0x81,0x75,0xbc,0xf6,0xc6,0x63,0xb8,0xfb,0xb5,0x37,0xe1,0xfa,0xab,0xaf,0x40,0x8,0xfe,0x15,0xf6,0xad,0xe0,0x87,0x4f,0x3c,0x8d,0x4f,0x7e,0xfe,0x5b,0x28,0x85,0x6d,0xad,0xa0,0x86,0x63,0x0,0x9c,0x39,0x47,0xa5,0x27,0x42,0x32,0x95,0x52,0xf0,0x8e,0xfb,0xee,0x5e,0x21,0xff,0x0,0xe0,0xe4,0x99,0x73,0xf8,0xe6,0x23,0x3f,0x85,0xf3,0x8d,0x5a,0x61,0x91,0x80,0xae,0xa7,0x3c,0x3a,0x6d,0xf9,0x8d,0x3,0x42,0xd3,0x72,0x6e,0x5e,0x81,0x6f,0x1a,0x94,0x9e,0xd4,0x7f,0xce,0x7b,0x18,0xdb,0x22,0xa7,0x84,0x64,0xd3,0x5,0xcb,0x2c,0xc,0x37,0xe6,0x6,0xeb,0x38,0x9f,0x90,0x8,0xb8,0x52,0xa,0xc,0xc,0x7c,0xd3,0x62,0xb9,0x7d,0x9e,0x6c,0xbf,0x4d,0xab,0xdb,0xdd,0xd8,0x39,0x4a,0xce,0x70,0x2d,0xbd,0xf6,0xf8,0x33,0xc7,0xf1,0xa3,0x27,0x9e,0xc2,0x5d,0xb7,0xdf,0xb2,0x6b,0xf9,0xf7,0xdc,0xf9,0x1a,0x5c,0x76,0x60,0x1f,0x3e,0xf7,0xd5,0x7,0xf0,0x83,0x9f,0xbe,0x40,0x59,0x85,0x4c,0xe4,0xe5,0x92,0x61,0xac,0x43,0xdf,0x77,0x68,0xda,0x19,0xf6,0xcd,0x5b,0xdc,0x75,0xeb,0xf5,0xf8,0xd5,0xb7,0xde,0x8b,0x1b,0xaf,0xbf,0x6,0xce,0x5a,0xbc,0xf8,0xd2,0x9,0x52,0xff,0x59,0x87,0x62,0x2c,0x42,0xd3,0xa0,0x5f,0x2e,0x31,0x5f,0xdf,0x87,0xf3,0x67,0x4f,0xc1,0x5a,0x8b,0xe5,0x62,0x8b,0x8e,0xf5,0x12,0x8,0xed,0x8c,0xa,0x65,0xf8,0xbc,0x58,0xe7,0x78,0x2c,0x41,0xb,0x49,0xc0,0xfb,0xa8,0xcd,0xbf,0x80,0x8e,0x2b,0xeb,0xc8,0x1a,0x5c,0x50,0x60,0xac,0x3,0x8c,0x5,0x4a,0x2d,0x3,0xa9,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xb8,0x74,0x50,0x9,0xc0,0x8a,0x8a,0x8a,0x8b,0x6,0x3,0x22,0xf5,0x48,0xc9,0x67,0x29,0x53,0xe,0x46,0xb,0x28,0x4,0x99,0x73,0x0,0x7d,0x68,0x56,0x8,0xc3,0x94,0x12,0x60,0x80,0x10,0x5a,0xc4,0x38,0xc0,0xfb,0x40,0xb9,0x75,0xce,0xe3,0xff,0xf9,0xd4,0x97,0xd0,0xf,0x3,0x7e,0xf5,0xfe,0xfb,0xf6,0x6c,0xe5,0x5,0x28,0xd3,0xef,0xfa,0x6b,0xaf,0xc6,0x75,0xd7,0x1c,0xc3,0xaf,0xf,0x11,0x5b,0xdb,0xb,0x9c,0x3a,0xb3,0x89,0x73,0x9b,0x9b,0xe8,0x7a,0xca,0xa4,0x9b,0xb5,0x2d,0xf6,0x6d,0xac,0xe3,0xe0,0x81,0xd,0xec,0x5b,0x5f,0x43,0xdb,0x36,0x3f,0x73,0xbf,0x4a,0x1,0x1e,0xfc,0xee,0x63,0xf8,0xd3,0x2f,0x7c,0x1b,0x43,0x22,0x42,0xb,0x88,0x70,0xde,0x23,0xe,0x3,0x11,0x53,0x5c,0x3a,0x62,0xc,0x29,0x19,0x9d,0xf,0xe8,0xbb,0x25,0xd6,0xd6,0xd6,0x76,0x2d,0xef,0xe0,0xbe,0x75,0xdc,0x76,0xed,0x51,0x3c,0xfe,0xfc,0x19,0x52,0x4b,0xb2,0x6a,0xe,0x28,0xe8,0xbb,0x4e,0xf3,0xeb,0x9c,0xf3,0x5c,0xa4,0x92,0xc7,0x66,0x63,0xe7,0xe0,0x42,0x43,0xa5,0x19,0xd6,0x21,0xa7,0x6,0x29,0x2d,0xe0,0x2e,0xa0,0x0,0x14,0xdb,0x33,0x0,0x55,0x65,0x92,0xb2,0xd0,0xc3,0xe6,0x8c,0xed,0xf3,0x67,0xb1,0xd8,0xda,0x24,0xb2,0xcf,0x79,0xe4,0x94,0xd0,0xce,0x67,0xb4,0x4e,0xe7,0x31,0x30,0x71,0x7,0x63,0xf0,0xc9,0xcf,0x7c,0x5,0xd7,0x5d,0x73,0x25,0xf6,0xef,0x5b,0x25,0x34,0x8d,0x31,0xb8,0xfe,0xda,0xab,0xf0,0x3f,0xfe,0xd6,0xaf,0xe3,0xf9,0x17,0x4f,0xe0,0x27,0x4f,0x3f,0x8f,0x67,0x5f,0x38,0x81,0xb3,0xe7,0xce,0x63,0xe8,0x3b,0x6c,0x6c,0xac,0xe1,0xc8,0xc1,0x7d,0xb8,0xf9,0xc6,0xeb,0x70,0xed,0xd5,0x57,0xe2,0xc0,0xfe,0x7d,0x2b,0xe3,0xc1,0x18,0x3,0xe7,0x9c,0xe6,0xfa,0x35,0xd,0xad,0xbf,0x5b,0x6e,0xc3,0x3a,0x47,0xaa,0x3e,0x63,0x30,0xf4,0xdd,0xa8,0xe6,0xe4,0x7c,0x49,0x30,0xf1,0x69,0xc,0x11,0xaf,0x10,0xa5,0x1f,0xab,0x2a,0xc7,0x3,0x1,0x6e,0x9a,0xa6,0x9f,0x8d,0xb5,0x30,0xce,0x23,0x47,0x3,0xf4,0x55,0x5,0x58,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x71,0x69,0xa1,0x12,0x80,0x15,0x15,0x15,0x17,0xd,0x86,0xcb,0x35,0xac,0xb5,0xd4,0xba,0x6a,0x8c,0xb6,0xfa,0x4a,0x4b,0x2e,0x0,0x56,0xa0,0x65,0xca,0xb1,0xb3,0x56,0x5f,0x17,0xb,0x67,0x4a,0x64,0x47,0xcd,0xc6,0xaa,0xba,0x2b,0x27,0x83,0x3f,0xf9,0xcc,0xd7,0x71,0xe6,0xdc,0x16,0x3e,0xf8,0xae,0xb7,0x62,0x6d,0x6d,0x7e,0xe1,0xed,0x30,0x6,0x4d,0x13,0xd0,0x34,0x1,0x97,0x1d,0xdc,0xff,0x8f,0xda,0xa7,0x7e,0x18,0xf0,0xb7,0xf,0x7c,0x1f,0x9f,0xfa,0xf2,0x3,0xb4,0xf,0x0,0x90,0x88,0x47,0x4a,0x31,0xea,0x7e,0xe5,0x42,0x44,0x9d,0xf5,0x1e,0xd6,0x5a,0xc,0x43,0x8f,0x14,0x7,0x3c,0xf8,0xbd,0x1f,0xe2,0xed,0x6f,0xbe,0x77,0xc5,0x3a,0x3b,0x9b,0xb5,0xf8,0xdd,0x8f,0xbd,0x7,0x3f,0x78,0xfc,0x49,0x3c,0xf4,0xd8,0xd3,0xf8,0xf1,0x33,0xc7,0x39,0x3f,0xaf,0xc0,0x7,0x22,0x3d,0xc5,0x36,0xdb,0xb4,0x33,0x38,0x80,0x4a,0x31,0xba,0x25,0x42,0xd3,0x12,0x19,0x98,0xa8,0x50,0xc3,0x18,0x8b,0xd0,0xb4,0x28,0x7c,0x9c,0x77,0x42,0xb6,0x4f,0x84,0x70,0xa5,0x14,0x38,0xe7,0xd0,0x71,0x56,0x22,0x40,0xc4,0x62,0x33,0x5b,0x83,0x6f,0x1a,0x7e,0x4f,0x66,0x1b,0x2d,0x11,0x68,0x94,0x6d,0x68,0xf1,0xe2,0xa9,0x4d,0x7c,0xfa,0xb,0x5f,0xc7,0x3f,0xff,0xe8,0xfb,0x10,0xfc,0xee,0xaf,0x13,0xef,0x3d,0xae,0xbb,0xe6,0x2a,0x5c,0x77,0xcd,0x55,0xa4,0xf2,0x64,0x62,0x57,0xca,0x60,0x5e,0xe9,0x7c,0x9,0x69,0xdc,0x77,0x1d,0x37,0x28,0x53,0x79,0x49,0x3b,0x5b,0x43,0xbf,0x5c,0x60,0x88,0x9c,0xf7,0x17,0x1a,0x98,0x9e,0xb2,0x6,0x9d,0xf,0xaa,0x36,0x14,0x5,0x60,0xe1,0xe5,0x19,0x63,0x60,0x8a,0xd3,0x7d,0x20,0x5b,0xba,0xa1,0xf7,0x97,0x8c,0x1c,0x7b,0x52,0x1c,0xa6,0xa1,0x5e,0xb8,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x97,0x1c,0x1c,0x80,0xdf,0xaf,0x87,0xa1,0xa2,0xa2,0xe2,0x62,0xe0,0xca,0xeb,0x6e,0x41,0x3b,0x23,0xc5,0x1b,0xe5,0xb4,0x11,0x21,0x98,0x72,0x84,0x35,0x8e,0x2c,0x97,0xc6,0x8c,0xcd,0xbb,0x62,0x9,0x2e,0x59,0x1b,0x73,0xad,0x73,0xb0,0xc6,0x22,0x73,0xa1,0x45,0x51,0x12,0xc9,0x21,0x97,0x82,0x9f,0x3c,0xfb,0x12,0x1e,0x7f,0xe2,0x19,0x5c,0x7d,0xe5,0x61,0x1c,0xdc,0xa1,0x24,0xfb,0x45,0xe3,0xb9,0x17,0x8e,0xe3,0x4f,0x3f,0xfd,0x15,0x7c,0xf5,0xc1,0x1f,0xc2,0xc0,0x90,0x7a,0xae,0x94,0x91,0xf4,0xe3,0xdc,0x3e,0xc9,0xa2,0x13,0x2,0x34,0x46,0x2a,0xa1,0x30,0xc6,0xe0,0xc5,0x13,0x27,0xe1,0x4d,0xc6,0x2d,0x37,0x5e,0xb7,0x42,0x84,0x59,0x6b,0x71,0xc5,0xd1,0x43,0xb8,0xfb,0xb6,0xeb,0x71,0xdf,0x9d,0x37,0xe1,0xd6,0xeb,0x8e,0xe2,0xe0,0xfa,0xc,0xa6,0x64,0x6c,0x6f,0x6f,0x23,0xb1,0xc9,0xd5,0x5a,0x8b,0x38,0xf4,0x98,0xcd,0xd7,0x49,0x15,0xe8,0x3,0x5b,0x5c,0xa5,0xbd,0x98,0xec,0xd3,0x57,0x1d,0xbd,0xc,0xf7,0xdd,0x73,0xc7,0xae,0x7d,0xf8,0xde,0xf,0x1e,0xc7,0x93,0xcf,0x9d,0x60,0x15,0x26,0x91,0x85,0x43,0xb7,0x44,0x41,0xc1,0xe2,0xfc,0x26,0xd9,0x7f,0x7b,0x2e,0xda,0x8,0x2d,0xbd,0x27,0x34,0xc8,0x39,0x23,0x84,0x96,0xb3,0x5,0xc9,0x2a,0x9b,0x53,0xc4,0x33,0x2f,0x9d,0x82,0x47,0xc6,0xd,0xd7,0x1d,0xbb,0x60,0x56,0x22,0x40,0x6a,0x50,0x21,0xe2,0x7e,0x16,0x4e,0x9d,0x3e,0x83,0x2f,0x7e,0xfd,0x1,0xf4,0xcb,0x5,0x4a,0xce,0x88,0xb1,0x27,0xd2,0x91,0x9b,0x83,0xfb,0xe5,0x82,0xc8,0xbe,0x52,0xe0,0x43,0x83,0xff,0x9f,0xbd,0x37,0x7b,0x96,0x24,0xbb,0xcf,0xc3,0xbe,0xb3,0x65,0x56,0xdd,0xdb,0xdd,0x33,0xd3,0x33,0x8d,0xc1,0x60,0xb0,0xc,0x89,0xc1,0x42,0x82,0x10,0x0,0xe,0x9,0x83,0x24,0xc8,0x7,0x4a,0xa4,0x28,0xca,0xb2,0x64,0x85,0x6c,0x49,0x8e,0x30,0x1d,0xe1,0x27,0xf9,0xc1,0xff,0x83,0xff,0x1,0x87,0x23,0xfc,0x66,0x5b,0xe,0x87,0xc2,0x11,0x92,0x6d,0xd1,0x21,0x2b,0x2c,0x6,0x69,0x86,0xc5,0x45,0x12,0x9,0x8,0x24,0x41,0x2,0x20,0xb1,0x2f,0x3,0xc,0x87,0x83,0xd9,0xbb,0xfb,0xde,0x5b,0x55,0x99,0x79,0x16,0x3f,0xfc,0x96,0x73,0xb2,0xee,0x6d,0x6c,0xc6,0x10,0x13,0x3d,0xe7,0x63,0x80,0x3d,0xb7,0x6e,0x55,0x65,0xd6,0xc9,0xbc,0x95,0x27,0xbf,0xf3,0x2d,0xc3,0xb8,0x61,0xc2,0xd4,0xb2,0xf5,0xb9,0x96,0x9f,0x58,0x63,0x61,0x40,0x85,0x34,0x72,0x9e,0x9,0xc1,0x98,0x73,0x42,0x4a,0x11,0xd3,0x7e,0x87,0x8b,0x8b,0x3d,0x90,0x13,0xe0,0x3c,0xf2,0xb2,0xef,0x7f,0xbc,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0xf7,0x15,0xba,0x2,0xb0,0xa3,0xa3,0xe3,0xb5,0x3,0xc9,0xaf,0x90,0xd9,0xb2,0x99,0xb8,0x1d,0xd7,0x5a,0x7,0x63,0x45,0xa9,0xc5,0x2a,0x34,0x2e,0x7c,0xc8,0xc8,0x5a,0x6,0x42,0x24,0x13,0xc9,0xeb,0x28,0x5b,0xaf,0x70,0x61,0x4,0x29,0xe0,0x9c,0x73,0x88,0x39,0xe1,0xcb,0xdf,0xf8,0xb,0xfc,0xb7,0xff,0xf8,0x57,0xf1,0xb3,0x3f,0xfe,0x23,0xf8,0xb9,0x8f,0x7c,0x10,0x6f,0x7e,0xf4,0xd6,0xf7,0x8d,0x8,0x2c,0xa5,0xe0,0xe5,0x57,0x6e,0xe3,0xdf,0x7e,0xe2,0xd3,0xf8,0xc4,0x9f,0x3d,0x8d,0xf3,0x8b,0x1d,0x11,0x91,0x96,0xd4,0x63,0xc6,0x1a,0xe4,0x18,0x51,0x78,0x73,0xd4,0x6e,0x4b,0x6d,0xc0,0x29,0x46,0x1e,0x2,0x2a,0xd5,0x28,0xa5,0x20,0xc,0x23,0x7e,0xfd,0x77,0xfe,0x0,0x39,0x45,0xfc,0xad,0x5f,0xfa,0xab,0x97,0xec,0xcb,0xd6,0x5a,0xdc,0xb8,0x7e,0x8a,0x1b,0xd7,0x4f,0xf1,0x9e,0x27,0x9f,0x40,0x4a,0x9,0x87,0xc3,0x84,0x57,0xee,0xdc,0xc5,0xd7,0x9f,0xf9,0x26,0x3e,0xf5,0xf9,0xa7,0xf1,0xf5,0xe7,0x6f,0x63,0x59,0x66,0x18,0x63,0x10,0x97,0x5,0xa5,0x64,0xcd,0xe,0xcc,0x9,0x70,0xce,0xe3,0x5e,0x9f,0x5e,0xec,0xd7,0x86,0x95,0x6f,0xb,0x37,0x6,0x4f,0x87,0x3d,0x7c,0xa0,0x76,0xe6,0x61,0xdc,0xa0,0x64,0xb2,0x60,0x8f,0x9b,0x1,0x30,0x96,0x2d,0xb9,0xf4,0xfc,0x30,0x6e,0x91,0xb9,0x78,0x63,0x59,0x66,0xfc,0xdf,0xbf,0xfd,0x7,0xb8,0x73,0xbe,0xc3,0x7f,0xf4,0x8b,0x3f,0x8b,0x6b,0xa7,0x27,0xdf,0xf3,0x58,0xa7,0x94,0xf0,0xc5,0x2f,0x7f,0x15,0xff,0xf4,0x5f,0xfc,0x26,0x72,0x4a,0x98,0xf6,0x17,0x30,0xce,0x71,0x59,0xaf,0xc5,0x61,0xbf,0x43,0x8a,0xb,0xfc,0x30,0x60,0x7f,0x71,0x8e,0x9c,0x13,0xc2,0xb8,0xc1,0xb2,0x4c,0x8,0x66,0x4,0x0,0x84,0x30,0x20,0xc6,0xb8,0xfa,0x8c,0xa2,0x72,0xcc,0x6c,0xf,0x2e,0x85,0xf2,0xfe,0x9a,0x83,0x8c,0x92,0x26,0x58,0x37,0xbe,0xa6,0x4,0x72,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0xc7,0xf,0xa,0x9d,0x0,0xec,0xe8,0xe8,0x78,0xcd,0x10,0xe3,0x52,0x4b,0x17,0xd8,0xfa,0x59,0x5a,0x25,0x5f,0x2e,0xf0,0x43,0xa0,0x96,0x5f,0x26,0x7,0xb,0x28,0x13,0xb0,0x64,0x22,0xfa,0xa4,0x29,0x38,0x2e,0x49,0x9b,0x6d,0x8d,0x25,0x55,0x17,0x35,0xbb,0xd2,0xef,0xf,0x87,0x9,0xff,0xfa,0xdf,0x7f,0x6,0xbf,0xfb,0x89,0x4f,0xe3,0xc3,0xef,0x7f,0x27,0x3e,0xfc,0xa1,0xf7,0xe1,0x89,0x77,0xbc,0xd,0x27,0xdb,0xed,0xf7,0xb4,0xef,0xbb,0xfd,0x1,0x7f,0xfe,0x17,0xcf,0xe3,0x8f,0xff,0xec,0x4b,0xf8,0xf4,0x17,0xff,0x1c,0x77,0xce,0x77,0x0,0x88,0x40,0x83,0x1,0x9c,0xf5,0x30,0xce,0x22,0x47,0xb2,0xce,0x8a,0xa2,0x4c,0xf6,0x37,0xe7,0xac,0x9f,0x5,0x20,0x12,0x74,0x13,0x1c,0x7e,0xe1,0xa3,0x3f,0x8e,0xff,0xe0,0xa9,0xbf,0x82,0x9b,0xf,0xde,0xb8,0x67,0x76,0x61,0xb,0xe7,0x1c,0x4e,0x4f,0x4f,0x70,0x7a,0x7a,0x82,0xb7,0xbd,0xe5,0xcd,0xf8,0xc8,0x4f,0xbc,0x1f,0x2f,0xbe,0xf4,0x2a,0x7e,0xfb,0xe3,0x9f,0xc6,0xa7,0xbe,0xfc,0x17,0x58,0xe6,0x19,0x30,0x8e,0xb3,0xfc,0x88,0xec,0x4a,0x71,0x51,0xb2,0xeb,0xf2,0xfb,0x79,0x6d,0xfd,0x5,0x80,0x65,0x9e,0x90,0x52,0x22,0x9b,0xf1,0xfe,0x2,0xce,0x7,0x4c,0xfb,0x1d,0x12,0x16,0x8c,0xdb,0x53,0xa4,0x18,0x61,0x9d,0x53,0x72,0xd0,0x38,0x8f,0x9c,0x28,0xef,0x30,0xa5,0x4,0xef,0x3d,0x96,0xb8,0xe0,0xdf,0xfc,0xe1,0xe7,0xf0,0xd5,0x6f,0x7c,0x13,0x7f,0xfb,0x17,0x7e,0x1a,0xef,0x7d,0xf7,0xf,0x5d,0x69,0x9,0xbe,0x17,0xe6,0x79,0xc1,0x57,0x9f,0xfe,0x3a,0x7e,0xeb,0xdf,0xfd,0x1,0x7e,0xff,0x93,0x9f,0x45,0xe2,0xd6,0x61,0xcb,0xfb,0x7a,0xd8,0x9d,0x53,0xd6,0x5f,0xc9,0x44,0xfc,0xfa,0x0,0xe7,0x9c,0xaa,0x2a,0x73,0x22,0xe5,0x65,0x31,0x94,0x33,0xe9,0xbc,0x47,0x8a,0xb,0xac,0x25,0x45,0x62,0x3d,0xef,0xac,0xe6,0x1,0x56,0x35,0xa2,0xe1,0xfc,0xbf,0x81,0x8e,0xdb,0x32,0xf5,0x3f,0xdc,0x8e,0x8e,0x8e,0x37,0x4,0x5c,0xd8,0xe0,0xb1,0x27,0xde,0x8d,0x47,0xde,0xfc,0x76,0x5c,0x7f,0xf0,0x26,0x65,0xbd,0xea,0xf7,0x6a,0xe4,0x12,0x25,0x2e,0xf4,0x92,0x28,0xf,0x92,0x9b,0xf3,0x75,0x20,0x70,0x44,0x87,0xd1,0xeb,0x3a,0x5d,0xb7,0x3d,0x2d,0xb4,0xe4,0x8c,0x5c,0x32,0x29,0xb1,0xad,0x41,0x4e,0xb9,0x5e,0x83,0x0,0x7a,0x2e,0x17,0x34,0x59,0x6b,0x91,0x72,0xa2,0x9f,0xc1,0xf9,0xac,0xa0,0xc6,0x76,0x67,0x29,0xfb,0xd5,0x39,0xaf,0xf1,0x1a,0xf2,0x3d,0x4e,0x65,0x5b,0x46,0x1f,0x3b,0x8e,0x98,0x90,0x8,0xb,0xf9,0x6c,0xb4,0x59,0xa3,0x73,0x11,0xf0,0xa2,0x4f,0xd1,0xfc,0x58,0x71,0x1a,0x64,0x58,0xe7,0x51,0x72,0xa2,0x62,0x28,0x14,0xce,0xdf,0xb5,0xaa,0xb6,0x6f,0xa3,0x4c,0xe4,0x1a,0xc3,0x2b,0x9f,0x1a,0x7b,0x22,0xb1,0x14,0x32,0x77,0x29,0x99,0xe7,0x42,0xfc,0x7e,0x80,0x44,0xa1,0xc8,0x2b,0x79,0x1f,0xd0,0xcc,0x8b,0x9a,0xf2,0xaa,0x7a,0x2d,0x2b,0xaa,0x8a,0xbf,0xbc,0x70,0xd5,0x6c,0x1f,0xcd,0x73,0xa,0x68,0xac,0x74,0x5f,0xc1,0x63,0x5d,0xb,0xb2,0xe4,0xdf,0x95,0x62,0xbf,0xd0,0xf3,0xc4,0x6d,0x50,0x9a,0x38,0x8f,0x7a,0x4d,0xa5,0xf7,0xa3,0x79,0xd0,0x7a,0xae,0x27,0xef,0x77,0x3c,0x5e,0xd0,0xf7,0x34,0xab,0xe7,0x8a,0x93,0x2,0x32,0x6,0xec,0xaa,0x0,0x8f,0xbb,0xb5,0x5c,0xdc,0x45,0x4d,0x73,0x9a,0x9d,0x6c,0x9a,0x39,0x81,0x6c,0x53,0xc6,0xbd,0x75,0x6a,0x18,0x63,0xd8,0x85,0x92,0x51,0x72,0x91,0x8f,0xc8,0xe7,0x4e,0x1,0x9f,0xc6,0x74,0x9e,0xe7,0xa4,0xfb,0x28,0xdb,0xd1,0x73,0x86,0xff,0x1e,0x72,0x4e,0xd8,0x9d,0x9f,0x61,0x99,0xf,0x38,0xbf,0xfb,0x2a,0xe6,0xc3,0x1e,0x2f,0x3c,0xf3,0xa5,0xfe,0x5,0xd3,0xd1,0xd1,0xf1,0xba,0x84,0x1,0x5a,0x19,0x44,0x47,0x47,0x47,0xc7,0xf7,0xf,0x1f,0xfc,0xe8,0x2f,0xe3,0xfa,0x43,0x8f,0x70,0x23,0x6e,0x6a,0x26,0xa1,0x3a,0xbb,0x52,0x82,0x46,0x66,0xc0,0x85,0xb3,0xde,0xa4,0x3d,0xb7,0xa0,0xc0,0x1a,0x4b,0x56,0x57,0x9e,0x20,0x6a,0x36,0x5d,0x2e,0x30,0xd6,0x20,0x84,0x81,0x73,0xe2,0x68,0xd2,0x77,0xd8,0x5d,0x20,0xa7,0x88,0x9b,0x37,0x4e,0xf0,0xd4,0x8f,0xbd,0xb,0x4f,0xfe,0xf0,0x13,0x78,0xec,0xd1,0x5b,0x78,0xf8,0xe1,0x87,0x31,0x8e,0x3,0x9c,0xb3,0x70,0xd6,0xaa,0xfa,0x30,0xc6,0x88,0x69,0x5e,0x70,0xf7,0xec,0x1c,0xcf,0x3e,0xf7,0x2,0xbe,0xfe,0xec,0xf3,0xf8,0xec,0x57,0x9e,0xc5,0x9d,0xdd,0x8c,0x18,0x17,0x25,0xe2,0x52,0x4a,0xab,0x9b,0x17,0xf9,0x5c,0x32,0x99,0x1d,0xc6,0x8d,0x16,0x4b,0xa4,0xb4,0xb0,0xf2,0x8c,0xf2,0xeb,0xde,0xf5,0xf8,0x4d,0xfc,0x67,0x7f,0xf7,0x97,0xbe,0x6f,0xea,0xc4,0x5c,0xa,0x3e,0xf3,0xd9,0x2f,0xe1,0x7f,0xff,0x8d,0x8f,0x63,0x3f,0xcd,0x4a,0x40,0x1e,0x2e,0xce,0x51,0x4a,0xc6,0x93,0x6f,0x7f,0x33,0x7e,0xf1,0x67,0x7f,0x42,0x27,0xe4,0xe0,0x16,0xe6,0xdf,0xfa,0xbd,0x4f,0xe2,0xb,0xdf,0x78,0x1e,0xde,0x7,0xc4,0x65,0x41,0x4e,0x9,0xe7,0x67,0xb7,0xe1,0xbd,0xc7,0xee,0xe2,0xc,0x17,0x77,0x5f,0xc5,0x61,0xbf,0xc3,0xb8,0xd9,0x62,0xdc,0x9c,0x20,0x8c,0x1b,0xc,0xc3,0x88,0x61,0xdc,0xd2,0xd,0x98,0xf,0xa4,0x30,0xe4,0xe3,0x63,0x9d,0xd3,0xb6,0x66,0xe7,0x3d,0xac,0x31,0x78,0xeb,0xa3,0x37,0xf1,0x91,0xf,0xbe,0x17,0xef,0x7c,0xe2,0x71,0x3c,0x7c,0xf3,0x21,0x8c,0x3,0x8d,0x79,0x61,0xbb,0x74,0x4c,0x9,0xbb,0xdd,0x1,0x2f,0xbe,0xf4,0x32,0x3e,0xff,0xc5,0xaf,0xe0,0x13,0x7f,0xf2,0x59,0x7c,0xed,0xd9,0x17,0x94,0x0,0x16,0x32,0x52,0xb2,0x1f,0x7d,0x18,0x31,0x1d,0x2e,0x50,0x72,0xc1,0x61,0x7f,0x1,0x63,0xc,0xe,0xfb,0x1d,0x2,0x9f,0x7,0xce,0x7,0x6c,0xb6,0xa7,0xf0,0x61,0x80,0xf,0x41,0x8f,0x1,0xdd,0x60,0x95,0xd5,0x65,0x8e,0x14,0x81,0x34,0x26,0x39,0x46,0x2c,0xf3,0x84,0xbb,0xb7,0x5f,0xc2,0x37,0x9f,0xf9,0x3a,0x8c,0x75,0x88,0xd3,0x39,0x72,0xec,0x24,0x60,0x47,0x47,0xc7,0xfd,0x8d,0x87,0xde,0xfc,0xe,0xbc,0xf7,0x3,0x3f,0x85,0x9b,0x6f,0x7a,0xb,0xc2,0x38,0x52,0x53,0x7b,0x9b,0x5,0x2b,0x24,0x8d,0x41,0x65,0xa6,0x4a,0x25,0xc8,0x5a,0xc2,0x46,0x6f,0x2a,0x58,0x75,0x4d,0xff,0x6d,0x2f,0xfd,0xbe,0xbe,0x51,0x25,0xf7,0x8c,0x10,0x56,0x42,0x6,0xc9,0x6f,0x4a,0xfb,0xbe,0x3c,0x6d,0x30,0x58,0x3d,0xae,0xec,0x64,0xf3,0xba,0xe3,0xff,0x16,0x92,0xec,0xff,0x37,0x4a,0xdd,0x5e,0x11,0x12,0xb1,0x1d,0x98,0xe6,0x96,0xaa,0xfe,0xee,0x7,0x78,0xbb,0x75,0xd5,0x0,0x5e,0xba,0xb,0x34,0xdf,0xf2,0x79,0xeb,0xa3,0xb5,0xfe,0x94,0xe6,0x8a,0xe7,0xe2,0x68,0x34,0xf0,0x1d,0x7f,0xea,0xe3,0x2d,0x5d,0xf1,0x59,0xda,0x93,0xe0,0xd2,0xd6,0x2e,0x1d,0x82,0xf5,0x67,0x39,0x7e,0x9,0x5e,0xdb,0xc3,0x41,0xae,0x8a,0x1d,0x5e,0x7a,0xee,0x19,0x7c,0xf1,0x53,0x1f,0x43,0xea,0xb,0x8b,0x1d,0x1d,0x1d,0xaf,0x23,0x74,0x2,0xb0,0xa3,0xa3,0xe3,0x35,0xc3,0x7,0x7e,0xe6,0x6f,0xe0,0x81,0x87,0x6f,0x91,0x42,0xab,0x60,0xb5,0x22,0x2d,0xc4,0x94,0xb5,0x1e,0xad,0xb5,0x17,0xbc,0x32,0xad,0x6d,0xaf,0x30,0x64,0xf,0xe6,0x15,0x67,0xe7,0xa8,0xd,0x17,0x4d,0x81,0x88,0xf,0x3,0xac,0x95,0x55,0x7b,0x60,0x7f,0x71,0x17,0xd6,0x3a,0xec,0x77,0xe7,0x8d,0x5,0xd4,0xe3,0xc6,0xb5,0x53,0x3c,0xf0,0xc0,0x3,0x38,0x3d,0x3d,0xc1,0xb5,0xd3,0x6b,0x30,0xc6,0x62,0x3f,0xcd,0x38,0xcc,0xb,0xe6,0x25,0x61,0xc9,0xd0,0x7d,0x91,0xd5,0xed,0x65,0x99,0x91,0xb9,0xf4,0x42,0xf7,0x53,0x89,0xa4,0xa2,0x2a,0xc4,0x9c,0xb3,0xee,0xbb,0x71,0x44,0x8e,0x89,0xed,0xf7,0xbd,0x4f,0x3c,0x86,0x7f,0xf4,0x2b,0x7f,0x17,0xd7,0xae,0x9d,0x5e,0x39,0x4e,0x39,0x67,0x4c,0xf3,0xc2,0x39,0x75,0x6,0xde,0x39,0x38,0xe7,0xe0,0xbd,0xfb,0xb6,0x63,0xfc,0xe9,0xcf,0x7e,0x9,0xff,0xc3,0xff,0xf6,0xeb,0x0,0x8c,0x92,0x95,0x33,0xdb,0x7a,0xa5,0x71,0x39,0x97,0xc,0x1f,0x6,0x6d,0xcc,0x95,0xd5,0x7e,0x63,0x2d,0x72,0x8a,0xd8,0x5f,0x9c,0x61,0x99,0x67,0x1c,0x76,0xe7,0x38,0xec,0x2f,0xb0,0xcc,0x13,0xc6,0xed,0x9,0xb6,0xa7,0xd7,0xb1,0xd9,0x9e,0x22,0xe7,0x84,0x93,0xd3,0x1b,0xac,0xc4,0x20,0x2,0x74,0xd8,0x6c,0xb1,0xcc,0x13,0xbd,0xaf,0xaf,0xed,0xc4,0x2e,0x4,0x55,0xde,0xe5,0x9c,0x71,0x7d,0x3b,0xc0,0x96,0x5,0x27,0x83,0x7,0xc,0xb0,0x2c,0x9,0xe7,0xbb,0x3,0xce,0xf6,0x13,0x62,0x22,0x82,0x37,0x2d,0xb,0x7c,0x18,0x90,0xe2,0x82,0xc4,0xab,0xed,0x29,0x45,0xcc,0xdc,0x84,0x6c,0x8c,0x81,0xb5,0xe,0xf3,0x74,0x40,0xce,0x89,0x1f,0x7,0xe,0xbb,0x73,0xc,0xe3,0x6,0xc3,0xb8,0x25,0xf2,0xcf,0x7,0x52,0x0,0x70,0xf6,0x62,0x29,0x89,0xcf,0x2b,0x51,0x9c,0x26,0x38,0x17,0x28,0xfb,0x2f,0x46,0xc4,0x38,0x23,0xce,0x33,0xee,0xbc,0xfa,0x12,0x5e,0x7c,0xfe,0x79,0xa4,0xf9,0x80,0x1c,0xf7,0x9d,0x0,0xec,0xe8,0xe8,0xb8,0xaf,0xb1,0xb9,0xf6,0x10,0x3e,0xf4,0xd1,0xbf,0x8e,0x47,0x1e,0x7d,0x2b,0xac,0x77,0xf4,0x7d,0xc8,0x6a,0xf0,0x4a,0xe0,0x9,0xc1,0x67,0x1a,0x2e,0xa5,0x5c,0x6a,0x6c,0x3f,0x56,0x9b,0xaf,0x15,0x5e,0x57,0xdf,0x6e,0xb4,0xef,0x71,0xe5,0xf3,0x94,0xe8,0xc1,0xd5,0xc4,0x15,0x2b,0xd1,0x94,0x8c,0xe3,0x1d,0x2c,0xed,0xfb,0x97,0x72,0x25,0x2f,0xf4,0x3d,0x93,0x69,0xed,0xc2,0xdd,0xf1,0xfe,0x99,0x63,0x22,0xea,0x1e,0x84,0x9b,0x10,0x53,0x97,0x8,0xba,0xe6,0x3f,0x5a,0xd2,0xf5,0x88,0x98,0xbb,0x17,0x87,0x65,0xbe,0x3,0x6a,0xad,0x1c,0x3d,0x4a,0x24,0xe5,0xe5,0x67,0xd2,0x73,0x5b,0x32,0xb6,0xfe,0x5c,0xae,0x24,0xea,0xca,0xe5,0x7d,0x3d,0xde,0xb3,0x2b,0x3f,0xd3,0x3d,0x76,0xf6,0xbb,0xb9,0x63,0xfd,0x2e,0xf,0xec,0xf1,0xe7,0xfa,0x76,0x8f,0xdf,0xeb,0x79,0x2d,0xb9,0xdb,0xfe,0x2c,0xef,0x21,0xea,0xce,0x9c,0x12,0xce,0xee,0xbc,0x82,0x2f,0x7e,0xfa,0x13,0xb8,0xb8,0xfd,0x42,0xff,0xe2,0xe9,0xe8,0xe8,0x78,0x5d,0xa0,0x5b,0x80,0x3b,0x3a,0x3a,0x5e,0x33,0xac,0x15,0x2,0xd5,0x5e,0x22,0x25,0x1f,0xa4,0xc4,0x8a,0x6a,0x9b,0x15,0x2b,0x86,0x31,0x45,0xad,0x1c,0x25,0x67,0xa4,0x48,0x96,0x53,0x69,0xaf,0x4d,0x29,0xd2,0xeb,0xd9,0xa,0xb2,0xcc,0x44,0x8,0x59,0xe7,0xd9,0xb6,0x42,0xed,0xc1,0x61,0x18,0x59,0x49,0x96,0x90,0xe2,0x82,0x57,0xe3,0x82,0x29,0x16,0x8c,0x17,0x13,0x5c,0xb8,0xc0,0x30,0x6e,0x10,0xe7,0x9,0x7e,0x18,0x57,0x13,0xfb,0x9c,0x17,0x9a,0xc2,0xb1,0x4d,0xd9,0x3a,0xab,0xb6,0x16,0xc9,0x1e,0xa4,0xc,0x3e,0x8b,0x92,0x13,0xdb,0x4d,0xa,0xac,0xf3,0xf4,0x5c,0xb6,0x5,0x1b,0xeb,0xb0,0x19,0x3c,0xfe,0xe1,0xdf,0xf9,0x85,0x2b,0xc9,0xbf,0x3b,0x67,0xe7,0xf8,0xd4,0x9f,0x7e,0x9,0x9f,0x7b,0xfa,0x9b,0x78,0xee,0x85,0x97,0x51,0x6c,0x20,0x35,0x23,0x32,0xae,0x9d,0x8c,0x78,0xe8,0xda,0x6,0xef,0x7c,0xdb,0x9b,0xf0,0xee,0x77,0xbe,0x1d,0x37,0x1f,0xbc,0x71,0x65,0x7b,0xee,0xfb,0xde,0xf3,0x4e,0xfc,0xf4,0x7,0x9e,0xc4,0xc7,0x3e,0xf3,0x35,0xcc,0x87,0x3d,0x86,0xcd,0x9,0x96,0xe9,0x0,0x1f,0x6,0x2c,0xf3,0x1,0xd6,0x79,0x38,0x58,0x94,0x94,0x60,0x7c,0xc0,0xcc,0xbf,0x13,0x2b,0x54,0xce,0x64,0x73,0x82,0x99,0x1,0x3,0x2e,0xd5,0xd8,0x62,0x9e,0x76,0x98,0x76,0x34,0x46,0x42,0x2e,0xe6,0x9c,0x90,0x1d,0xb5,0xf3,0x2e,0xf3,0x81,0xd4,0x8d,0x29,0xa2,0xe4,0x4,0x1f,0x46,0x64,0xd0,0x84,0x37,0x47,0xb2,0xc8,0x84,0x30,0xe0,0xe5,0x57,0x6f,0x63,0x9e,0xe,0x5a,0xde,0xe1,0x87,0x81,0x95,0x83,0x5e,0x2d,0xb8,0xa4,0xe8,0x34,0xda,0x14,0x2c,0x76,0x20,0xeb,0x1c,0x9c,0x75,0xb0,0xce,0x61,0x77,0x4e,0xa4,0x6e,0x4e,0x9,0x9b,0xed,0x29,0x96,0x79,0xc2,0x66,0x7b,0xaa,0x84,0x5f,0xe1,0xf7,0xcc,0x39,0x2,0x59,0x6c,0xbf,0x7c,0xfe,0xe9,0x4d,0xac,0x6d,0xac,0x67,0x46,0xff,0x55,0x72,0x79,0xd8,0x20,0xc7,0x3,0x8c,0x71,0x28,0x25,0xf5,0x3f,0xe0,0x8e,0x8e,0x8e,0xfb,0x12,0x37,0x1f,0x7d,0x1c,0x9b,0xed,0x29,0xa,0xa,0xe6,0xc3,0x1,0xcb,0x7c,0xa0,0xef,0x6e,0xb6,0xd7,0x8a,0x5d,0x54,0x88,0xd,0xb1,0x56,0x3b,0xa6,0x4,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x74,0xde,0x4b,0x49,0x57,0xe3,0x15,0xd6,0xff,0x2d,0xca,0xf3,0x6a,0x17,0xad,0xd6,0x4f,0xa5,0xa6,0x9a,0xef,0x7c,0x7a,0x49,0x6e,0x2c,0xae,0x6c,0x9f,0x6d,0xad,0xac,0x80,0x5e,0xbf,0xf4,0xfb,0xbd,0x51,0x25,0xa,0x21,0x55,0x9a,0xfd,0xae,0x97,0xf7,0xac,0x44,0x8d,0x39,0xfa,0x5d,0xfb,0x3e,0x95,0x5b,0x2a,0x95,0xd0,0x3b,0xe6,0x9c,0xd4,0xc9,0x50,0x89,0x3b,0x63,0xdb,0xcf,0x8e,0xcb,0x2a,0x49,0xd3,0x90,0x7c,0x57,0x11,0x83,0xaa,0x58,0x33,0xea,0x80,0x50,0x62,0xaa,0xfd,0x8c,0xab,0x6d,0x5f,0xfa,0x71,0x35,0x5e,0xdf,0xe2,0x49,0x95,0xbc,0xe3,0x71,0xd3,0x71,0x17,0xb2,0xab,0x39,0xf,0x84,0xe8,0x5a,0xd9,0x7a,0x85,0xfc,0x92,0xdd,0xb6,0x56,0xed,0xce,0x97,0x6,0xcc,0x34,0x84,0x59,0xab,0xcc,0x6b,0xc6,0x4a,0xf7,0xf9,0x5b,0x11,0xa8,0x47,0x73,0xcc,0x2c,0xb6,0xf4,0x63,0xca,0x73,0x45,0xe,0x96,0x15,0xbd,0xd9,0x6e,0xb8,0xfe,0xa4,0x47,0xfc,0xa,0xee,0xb1,0x55,0xa8,0x96,0xf5,0x73,0x8f,0xb8,0x4e,0x11,0xa5,0x96,0x42,0x8a,0x5a,0x1f,0x6,0x3c,0xf6,0x8e,0x27,0xf1,0xe5,0x4e,0x0,0x76,0x74,0x74,0x74,0x2,0xb0,0xa3,0xa3,0xe3,0x7e,0x87,0x92,0x2d,0xa8,0xb6,0x20,0x9d,0x1c,0x72,0x23,0x2b,0x65,0xb9,0x90,0x3d,0xd8,0x87,0x41,0xed,0x47,0x62,0xad,0x15,0x35,0x57,0x66,0x6b,0xb0,0x66,0xb4,0xb0,0x72,0xcc,0x8e,0x4e,0x9f,0x97,0xe2,0xc2,0x2a,0x3c,0x3,0xe7,0x3c,0x2e,0xce,0xef,0x20,0x2e,0xb,0x15,0x5f,0x70,0xf9,0xc8,0xc5,0xd9,0x6d,0x94,0x92,0x11,0x72,0x42,0x4e,0x11,0x61,0xd8,0xe0,0xb0,0xbb,0xe0,0xa6,0xdb,0x44,0x99,0x46,0x9c,0x5d,0x48,0x2a,0xc4,0x5,0xcb,0x92,0x99,0x90,0xf2,0xa4,0x92,0x90,0x6c,0x9a,0x52,0x73,0x66,0x52,0x8a,0xb0,0x9c,0x45,0x27,0x37,0x41,0xf3,0xb4,0xc7,0x87,0x7f,0xf4,0xbd,0x78,0xcb,0x63,0x8f,0x5e,0x1a,0x9b,0x2f,0x7f,0xed,0x1b,0xf8,0x67,0xff,0xea,0xdf,0xe1,0xa5,0x3b,0xe7,0x8,0x4c,0x40,0x3a,0x6f,0x71,0x58,0xa8,0xf9,0xf6,0xce,0xc5,0x1,0x4f,0x3f,0xfb,0x2,0xfe,0xe8,0xb3,0x5f,0x83,0xc1,0xc7,0xf1,0xa1,0xf7,0xbe,0xd,0x7f,0xf3,0xe7,0x3f,0x82,0x87,0x6f,0x3e,0xb4,0x7a,0x1f,0xe7,0x2c,0x7e,0xea,0xa9,0xf7,0xe3,0xb7,0x3e,0xf6,0x29,0x38,0xef,0x31,0x1d,0x2e,0x54,0x3d,0x49,0x24,0x5b,0x25,0x2f,0x69,0xfc,0x88,0x54,0x9b,0xe7,0x3,0x8c,0xa1,0x46,0xe1,0xaa,0xe2,0x20,0xa2,0xcf,0x98,0x88,0x9c,0x69,0x12,0x4e,0xed,0xbb,0x16,0x71,0x9e,0xb0,0xbd,0x76,0x83,0x6f,0xc6,0x28,0x9b,0x31,0x71,0xce,0x8e,0x73,0x9e,0xde,0x87,0x1b,0x8a,0x7d,0x18,0x1,0x14,0xcc,0x4c,0xcc,0xd2,0x76,0xe,0x48,0x71,0xc1,0x32,0x1f,0xf8,0xf7,0x13,0x36,0x27,0xd7,0x60,0x8c,0xe4,0x1c,0x39,0x55,0x50,0xc6,0xb8,0x68,0xe3,0xb1,0xb1,0x16,0xd3,0x61,0xa7,0x63,0x4,0x90,0x65,0xdb,0x79,0x4f,0xc5,0x27,0xc6,0x68,0xfb,0xb0,0x5a,0xd7,0xa4,0x11,0xb8,0x44,0x55,0x6c,0xa2,0xe4,0x46,0x8c,0x90,0x6b,0x96,0x15,0xff,0x2e,0xc7,0x5,0x25,0x2f,0x28,0x69,0xae,0x37,0x70,0x1d,0x1d,0x1d,0x1d,0xf7,0x21,0x84,0x6c,0xa1,0xef,0xe4,0x19,0x29,0x45,0x55,0x2c,0xd1,0xb5,0x6d,0x4d,0x83,0x68,0xee,0xd9,0x15,0xc4,0xd,0x5f,0xed,0xf5,0x7d,0xb,0xb2,0x52,0x2b,0xc6,0x18,0x6d,0x9c,0x2f,0xf9,0x72,0xf9,0x92,0x2e,0xe4,0xc1,0x36,0x25,0x4d,0x5,0x40,0xd6,0xac,0xb9,0x36,0x5f,0xd0,0x48,0x4e,0x60,0x13,0xf,0x92,0x38,0x23,0x4e,0x54,0xde,0xa6,0xc9,0x10,0x4c,0x9a,0xd1,0x96,0x35,0x3b,0xb8,0xf0,0x6b,0xc1,0xd7,0x32,0x30,0x59,0x23,0xd7,0x20,0x79,0x6d,0x66,0x7b,0x72,0x69,0x48,0x24,0x22,0x9c,0x1a,0x96,0xe7,0x88,0xbc,0x33,0x4a,0x92,0x1e,0x59,0x54,0x99,0xc8,0x94,0x45,0xaf,0x86,0x45,0x5c,0x8d,0x73,0xab,0xb8,0x84,0xaa,0xc9,0xf2,0x9a,0x17,0x6c,0xf8,0xbc,0x86,0xeb,0xa3,0x63,0x66,0x1a,0xeb,0x76,0xb3,0xfd,0x6a,0xc7,0x2e,0x8d,0x85,0xdb,0x56,0x8b,0x77,0x2e,0x7a,0x1c,0x25,0x7f,0xf0,0x78,0xef,0x32,0xbf,0x26,0x97,0x36,0x73,0xb1,0xdd,0xa9,0x42,0xd7,0xd9,0x9c,0x1,0xce,0x7c,0x6c,0xc9,0xc0,0xe3,0x3c,0xc0,0xca,0xf3,0x5d,0x61,0x23,0x4f,0x79,0xad,0xb8,0xc4,0x3a,0xeb,0xb0,0xcd,0x34,0xc4,0x6a,0x4c,0x8a,0x66,0xf7,0x29,0x71,0xd9,0x10,0xa7,0xb9,0x94,0x6f,0x6d,0x61,0xbf,0x64,0xdd,0xfe,0xde,0x21,0x7f,0x4f,0x99,0xb3,0x2b,0x57,0xc4,0x78,0x47,0x47,0x47,0xc7,0xf,0x10,0xb6,0xf,0x41,0x47,0x47,0xc7,0x6b,0x76,0x93,0xc1,0xe4,0x9d,0x4e,0xea,0xe4,0x6,0x40,0x27,0x5e,0x55,0xd,0x68,0xac,0x45,0x8c,0x33,0x2b,0xf8,0x2a,0x29,0xd4,0x6,0x73,0x2f,0xf3,0x1,0x31,0x2e,0x58,0xe6,0x89,0x42,0xc5,0x9b,0xc9,0x6e,0x8a,0xa4,0xda,0xcb,0x25,0xeb,0xcd,0x0,0x98,0x44,0x2,0xdf,0x84,0x1c,0x76,0xe7,0x88,0xb,0xbd,0x7e,0x99,0x26,0x2c,0xf3,0x44,0x4d,0xb3,0xd6,0x68,0xf6,0xd1,0x32,0x4f,0x9a,0xa7,0x97,0x96,0xa5,0x4e,0xa,0x65,0x1b,0x4c,0x96,0xa5,0x18,0xb9,0x6c,0x23,0xc1,0x3a,0x8f,0x10,0x6,0xc0,0x18,0x2e,0xe3,0x48,0x4a,0x9c,0xbd,0xef,0x3d,0x3f,0x7c,0x29,0xf3,0xef,0xec,0xfc,0x2,0xff,0xe4,0x57,0x7f,0x13,0x2f,0xde,0x3e,0x5b,0xa9,0xfa,0x4a,0x4e,0x0,0xdb,0xa4,0x97,0xf9,0x80,0x30,0x8c,0xf0,0xc3,0x80,0x5c,0xa,0x3e,0xf9,0xf9,0x67,0xf0,0xdf,0xff,0x2f,0xff,0x2,0xaf,0xdc,0xbe,0x73,0x69,0x9c,0x1f,0x7d,0xd3,0x23,0xb8,0xb6,0x1d,0x90,0x62,0xd4,0x1b,0x38,0xcf,0x99,0x89,0x42,0x8a,0x8a,0x85,0x96,0x6c,0xb8,0x93,0x92,0x96,0xf2,0x59,0xc,0x13,0x69,0x29,0x2e,0xd8,0x9f,0xdf,0x45,0x5c,0x26,0x84,0x61,0xe0,0xdf,0x1,0x30,0x56,0xad,0xc5,0xd4,0x3c,0x5c,0x74,0x32,0xbb,0xcc,0x13,0xad,0x76,0x2f,0x33,0x91,0x88,0xcb,0x84,0xb8,0xcc,0x88,0xcb,0x8c,0x65,0x9e,0x70,0xd8,0x9f,0xab,0x6d,0x37,0xe7,0x8c,0x79,0xda,0xd3,0xeb,0xf8,0xfd,0x72,0xa6,0x72,0x8f,0xcc,0x2b,0xe6,0xce,0x79,0x56,0x6f,0x10,0xb1,0x17,0xc2,0xa8,0xca,0x4e,0x63,0x2d,0x86,0x71,0x83,0x30,0x8c,0x70,0x3e,0xc0,0x87,0xa0,0xa4,0x5f,0x69,0x5a,0x7e,0x89,0x9c,0xe4,0x9b,0x2d,0x55,0x98,0x90,0xb5,0xdc,0x34,0xeb,0xf8,0x74,0x3,0x44,0x8f,0x5b,0xeb,0xe1,0x86,0x6b,0xfd,0xf,0xb7,0xa3,0xa3,0xe3,0x3e,0x27,0x0,0xdb,0xe9,0x3f,0x2b,0xe6,0x5a,0x25,0x9e,0xc1,0xfa,0x7f,0x68,0x63,0x7b,0x8f,0xec,0x92,0x86,0xd4,0x74,0x44,0xc4,0x94,0x15,0xc9,0x21,0x8b,0x31,0x4a,0x6e,0xad,0xf2,0xfa,0x8c,0x5e,0xff,0x33,0x47,0x6a,0x8,0x31,0xa3,0xaa,0x41,0xbe,0xce,0xd3,0xbc,0x81,0x58,0x2f,0xcb,0xb1,0xe,0x2d,0x81,0x55,0x4a,0xae,0x4a,0x6f,0x76,0xf,0xd4,0xcd,0x98,0x6a,0x11,0x2e,0x4c,0x2c,0xc9,0xa5,0x21,0xaf,0x49,0x31,0x21,0xe0,0x4a,0x9d,0xb8,0xa8,0xaa,0x50,0x4b,0xa3,0x84,0xec,0x33,0x56,0xb7,0x57,0x54,0x3d,0x78,0x59,0xfd,0x26,0x9f,0x5f,0x5c,0xf,0x6a,0x71,0xd6,0x31,0xa8,0x73,0x24,0x1a,0xaf,0x4a,0xdc,0x55,0xc2,0xac,0xf2,0xaf,0x12,0x75,0x52,0xfb,0x4b,0xa4,0xa0,0xc2,0xd5,0xe3,0x8,0x73,0x74,0xac,0x2b,0x29,0xa9,0x9f,0x51,0x4b,0x38,0x84,0x45,0x34,0x4a,0x2c,0xca,0x58,0xb4,0xdb,0xab,0x9f,0xaf,0xac,0xc8,0x4f,0xa1,0x29,0x85,0x7c,0x4,0xcf,0xe1,0x8e,0x95,0x80,0xed,0x7e,0xdd,0x8b,0x80,0x6b,0xb7,0x75,0x25,0xf9,0x57,0x2a,0xc9,0xb7,0x22,0x5a,0xf5,0xdc,0xb1,0x6b,0x96,0x74,0x45,0x1c,0x1e,0x15,0x8d,0x5c,0xa1,0x30,0x3c,0xb6,0xf2,0x7e,0xb,0x7a,0x6f,0xcd,0xc2,0x5e,0xfa,0xf5,0xe5,0x6c,0xc4,0x9e,0xb8,0xd5,0xd1,0xd1,0xd1,0x9,0xc0,0x8e,0x8e,0x8e,0xfb,0x1e,0xa2,0x16,0x13,0xa2,0xaf,0x5a,0x4a,0x2a,0xf1,0x97,0x52,0xd4,0x6c,0x40,0x3,0x43,0xc5,0x14,0x9c,0xa7,0x17,0x97,0x59,0x2d,0xbf,0xcb,0x3c,0xe9,0x24,0xca,0x72,0x23,0x60,0x41,0xc1,0xe1,0xb0,0x43,0x5c,0x66,0xce,0xdb,0xa3,0x39,0x96,0x73,0xd4,0x40,0x38,0xc,0x1b,0x58,0xef,0xd5,0x8a,0x41,0xc4,0x55,0xc6,0xed,0x97,0x5f,0xc0,0x7c,0xd8,0x61,0x77,0x7e,0x97,0x8,0xbf,0x94,0x88,0xb4,0xe3,0x7f,0x65,0x62,0x28,0x84,0x60,0xca,0x91,0xdf,0x3f,0xeb,0xbe,0x2a,0x71,0x57,0x40,0xa4,0x5f,0xca,0xda,0x98,0x7b,0xd8,0x9d,0x63,0x9e,0xf6,0x48,0x71,0xc1,0xc3,0x37,0x1f,0xbc,0x34,0x2e,0x5f,0x7f,0xe6,0x59,0xbc,0x72,0x7e,0x20,0xfb,0x30,0x67,0xe7,0xa1,0x14,0xce,0x5f,0xa2,0x49,0x68,0xce,0xf4,0xf9,0x97,0xe9,0x0,0x63,0x1d,0x52,0x4e,0x78,0xe9,0xce,0x5,0x3e,0xf6,0x7,0x9f,0xbe,0xf4,0x7e,0xc1,0x3b,0x3c,0xf4,0xc0,0x75,0x8c,0xdb,0x13,0x26,0xc9,0x1c,0x37,0xfd,0xd6,0x36,0xc1,0x79,0xda,0xeb,0xe7,0x91,0xbb,0x1f,0x5a,0x99,0x76,0x3c,0x36,0x33,0xf6,0xbb,0xb,0x52,0xf0,0xd,0x23,0x11,0x79,0x31,0x2a,0x81,0x2a,0x37,0x36,0xb4,0x8f,0x5,0x71,0x9e,0x49,0x61,0xc1,0x6a,0xc9,0xe9,0xb0,0x47,0xca,0x75,0x1c,0x55,0x91,0xc1,0xaf,0x93,0x86,0xc7,0xb8,0x90,0xda,0x24,0xc5,0xa8,0x2d,0x87,0xc6,0x18,0x78,0x1f,0xe0,0x7d,0x20,0x62,0xcf,0x39,0x84,0x30,0x68,0xb,0xa1,0xb1,0xa4,0xbe,0x14,0x62,0xd3,0x5a,0xcb,0xd9,0x83,0xe,0x39,0x65,0x58,0x67,0xf5,0xa6,0x4e,0x27,0xf8,0x7c,0x9c,0xa8,0xc1,0x11,0x9a,0xd7,0x98,0x34,0xcf,0xb1,0xb9,0x79,0x29,0x19,0x69,0xbe,0x80,0x1b,0x46,0xa4,0x38,0xc1,0x18,0xd7,0xff,0x78,0x3b,0x3a,0x3a,0xee,0x5b,0x64,0x29,0xb2,0x2a,0x42,0x20,0x41,0x17,0xd4,0x44,0x89,0x67,0x74,0xa9,0x4,0x95,0x84,0x6b,0x89,0xae,0xd2,0x90,0x3d,0xfa,0x3d,0xef,0xd6,0x19,0x77,0x4d,0x53,0x2c,0xc5,0x35,0x38,0x56,0x77,0x3b,0x18,0x6b,0x94,0x4,0xb4,0xd6,0xe9,0x77,0xbd,0xbc,0x56,0x7e,0x2e,0xd,0x91,0x58,0x1a,0x4b,0xb1,0x7c,0xa7,0xd3,0x6b,0xad,0x5e,0x2f,0x24,0x73,0x58,0x3e,0x43,0x5d,0x78,0x94,0x45,0xc9,0xbc,0x22,0xc8,0x60,0x2c,0xd3,0x63,0x54,0x2a,0x6,0x26,0x13,0x4d,0x23,0x2d,0x13,0xc5,0x1a,0xed,0x5a,0x5e,0x91,0x45,0x39,0xe5,0xe6,0xb9,0x55,0xbd,0x57,0x1d,0xb7,0x45,0x55,0x86,0x97,0xfb,0xbf,0xca,0x95,0x91,0x80,0x2d,0x19,0xda,0x92,0x66,0xd,0xe7,0x5a,0x5f,0xc3,0x64,0x5b,0xcd,0x58,0x6e,0x8e,0xa7,0xce,0xbf,0x4a,0x43,0xc8,0xb6,0x84,0x66,0x6b,0xab,0x5e,0x93,0x9d,0x35,0xf7,0x98,0xdf,0x67,0xa5,0xde,0x93,0x98,0x96,0xc6,0x46,0xdd,0x12,0xa8,0x47,0xd,0xcb,0xf5,0x83,0x57,0xf2,0xb0,0x75,0x4b,0x5c,0x22,0xa6,0x4b,0xd1,0xf1,0x6c,0xad,0xd4,0xa5,0xd9,0x37,0x6b,0x9d,0x2e,0xe2,0x5d,0x55,0x5b,0xb2,0x7a,0xb4,0x94,0x2b,0xd5,0x77,0x72,0xce,0x1f,0x93,0x7e,0x3a,0x57,0xd5,0x92,0x9a,0x4b,0xaf,0xbc,0x9c,0xb,0x79,0x4f,0x32,0x71,0xbd,0x5f,0x1d,0x1d,0x1d,0x1d,0x3f,0x68,0x74,0xb,0x70,0x47,0x47,0xc7,0x6b,0x86,0x5a,0xc6,0xc0,0x2b,0xb3,0xbc,0xca,0x4f,0x2a,0xac,0x82,0x9c,0x28,0xff,0xcf,0x7a,0xca,0x92,0x3,0xe7,0xbe,0x1,0x85,0x6e,0x14,0xc,0x94,0xc,0xf4,0x61,0xdd,0xfc,0x2b,0x39,0x80,0xd6,0x3a,0x6d,0xa0,0x4d,0x91,0x14,0x68,0xf3,0x74,0x80,0x75,0x8e,0x8,0x44,0xb6,0x61,0x18,0x18,0xc4,0x34,0xe3,0xee,0xed,0x97,0x10,0xc2,0x88,0x8b,0xf3,0xbb,0x94,0x6f,0x57,0xa,0xe5,0xfa,0x79,0xcf,0x85,0x23,0xa1,0xc9,0xd,0xe2,0x5c,0xb9,0x14,0xc9,0x96,0x9a,0x68,0xf2,0x6c,0x7,0xa7,0x96,0xd7,0x94,0x22,0x4c,0x36,0x88,0x7c,0xb3,0xb3,0x9f,0xc9,0xea,0x2a,0x84,0xd5,0x95,0x37,0x5f,0xc5,0x70,0x29,0x87,0x63,0x82,0x33,0x61,0xdc,0x6c,0x89,0xa8,0x8c,0xb,0xac,0x73,0x18,0xc6,0xd,0x52,0xa4,0x72,0x8c,0xc3,0xfe,0x42,0xd5,0x13,0xaf,0x5e,0xa1,0x0,0x24,0x5,0x6,0x59,0x72,0xc3,0x30,0x62,0x9e,0xf6,0x7a,0x73,0x54,0x72,0x86,0xf,0x1,0x99,0x6f,0x8c,0x42,0x18,0x57,0x21,0xef,0x92,0xed,0x27,0x24,0x5d,0x8,0x23,0x96,0x65,0xa2,0x96,0xe0,0x79,0x82,0x39,0xb9,0x6,0x3,0x26,0x3c,0xf9,0x66,0xe,0xa5,0x20,0xe5,0xc8,0xd9,0x3b,0x34,0xb5,0xd,0xc3,0xa8,0x79,0x8d,0xd6,0x59,0x5c,0x9c,0xdd,0xe1,0xcf,0x40,0xc7,0xf8,0x30,0x1d,0xb0,0x3b,0xbf,0x4b,0xf6,0xe3,0xfd,0x85,0xde,0x4,0x84,0x71,0x83,0x9c,0x33,0xbc,0x37,0x9c,0xe7,0x38,0xd1,0xb1,0x9b,0x27,0xb8,0x10,0x98,0x60,0x4d,0x7c,0x93,0x48,0x76,0xaf,0x92,0x13,0xa,0xff,0x2b,0x5,0x31,0x62,0x17,0x16,0x32,0xd5,0x38,0x47,0x9f,0x8b,0x15,0x9b,0xa2,0x26,0x94,0x1b,0xf,0x55,0x20,0xe8,0xb9,0x46,0xf9,0x82,0xd6,0xd,0x48,0xa9,0x97,0x80,0x74,0x74,0x74,0xdc,0xbf,0x70,0xde,0x33,0xc9,0xb1,0x62,0x2c,0xd6,0x64,0x9f,0xd8,0x33,0xb,0xd8,0xd6,0x6b,0x56,0x79,0x69,0x64,0xdd,0xad,0xc4,0xd7,0xa5,0x6b,0x12,0x98,0x58,0x4b,0x89,0x54,0x7b,0x2d,0xb9,0xc2,0xa4,0x94,0x75,0x4e,0x17,0xe0,0x0,0xc0,0x14,0x53,0xf3,0x69,0x53,0xa4,0xed,0xf0,0xf7,0xf8,0x2a,0x13,0x90,0xff,0xdb,0x3a,0x87,0xcc,0x64,0xa4,0xb9,0x94,0xdf,0x7,0x75,0x1c,0xe0,0x92,0xcd,0x14,0x40,0x61,0xbb,0x72,0x6b,0x33,0xce,0xd,0x6d,0xc4,0xc4,0x5a,0x4b,0xfe,0x9,0xc9,0xa9,0x36,0x62,0x1e,0x43,0x51,0xc9,0x83,0xcb,0x1f,0xaa,0x82,0x4f,0x48,0xad,0xbc,0x52,0x42,0x1e,0xf7,0x87,0x94,0x2,0x58,0xcb,0x56,0x65,0x63,0x60,0x4c,0x93,0x33,0xd7,0x58,0x5f,0x8f,0x2d,0xb0,0x46,0x55,0x8c,0x6d,0x7e,0xa2,0xa9,0xc4,0xa0,0x66,0xeb,0x15,0x55,0x2,0xb6,0x8f,0xad,0xb6,0x81,0x75,0x6e,0x62,0x5b,0x12,0x72,0x4c,0x4e,0x5e,0xfe,0xef,0xa6,0x1,0x59,0x9,0xd0,0xb5,0x4a,0xb0,0xac,0x28,0x3a,0x53,0x95,0x9b,0xc8,0xd5,0x42,0x2d,0xfb,0x6c,0xe9,0xfa,0xdd,0xe6,0x30,0xae,0x54,0xfb,0x68,0xb9,0xc5,0xe3,0x42,0x99,0xef,0x5c,0x69,0xb7,0xfa,0x2c,0x57,0xd9,0xb1,0xb,0x50,0xae,0x2c,0x2b,0x29,0xf7,0xe0,0xf3,0xae,0xf0,0x6a,0xcb,0x8,0xf4,0xda,0xcd,0x8e,0x8e,0x8e,0x4e,0x0,0x76,0x74,0x74,0xdc,0xf7,0x68,0x26,0x3b,0xa4,0x2a,0xa0,0x29,0x56,0x62,0x65,0x99,0xe1,0xf2,0x8f,0xb4,0x2c,0x6c,0x61,0xe1,0x2c,0x3d,0xeb,0x74,0xa2,0x2a,0x2b,0xd0,0x91,0x73,0x84,0x8c,0xa5,0xff,0x96,0x9,0xb0,0xf,0x54,0x2a,0x91,0x96,0x85,0x9,0x20,0xce,0x30,0x8a,0x9,0xce,0x79,0xf8,0x30,0x60,0xdc,0x9e,0x60,0x7f,0x71,0x8e,0x14,0x23,0xbc,0xb,0xc8,0x29,0x61,0x62,0x12,0x2a,0xc5,0x5,0x6e,0x99,0xb5,0x41,0xd6,0x5a,0x87,0x61,0xb3,0xe1,0x3c,0xa1,0x4c,0xd9,0x2d,0xd6,0xc2,0x1a,0xca,0x28,0xca,0xfc,0x78,0xce,0x94,0xf7,0xe7,0x7c,0xc0,0x12,0x67,0x58,0xeb,0xb5,0x18,0x83,0x48,0xc3,0x84,0x18,0x17,0x9c,0x9d,0x9d,0x5f,0x1a,0x96,0xc7,0x1f,0x7b,0x13,0x6,0x5b,0x70,0x98,0x67,0x58,0xe7,0x10,0x86,0x51,0xad,0xb0,0x46,0x73,0xf7,0x68,0x2,0xbd,0xcc,0x13,0xdb,0x5b,0xe9,0xf7,0x4f,0xfe,0xd0,0xdb,0x2e,0xbd,0xdf,0x34,0xcd,0xb8,0x7d,0xb6,0x53,0x45,0xa1,0xf,0x23,0x52,0x22,0xeb,0xaf,0x1b,0x37,0x58,0x96,0x9,0x61,0xd8,0x20,0x62,0xa6,0xd2,0xe,0x21,0x61,0x65,0x15,0x3d,0x4b,0xa3,0x71,0xc2,0xb2,0x50,0x1b,0xf0,0xb8,0x39,0xc1,0xb8,0x39,0xc1,0x74,0xd8,0x63,0xb3,0x3d,0x81,0x2d,0x44,0xb4,0x8a,0x99,0xa8,0x55,0x5b,0x18,0xb6,0x3e,0x93,0x22,0x0,0x4a,0x34,0xe6,0x44,0x99,0x8a,0x36,0x67,0x9c,0x9c,0x5e,0xc7,0x7c,0xd8,0x63,0x7f,0x71,0x6,0xeb,0x1c,0x1d,0xf,0x51,0x5e,0xc6,0x5,0x71,0x99,0x11,0x86,0x91,0x9,0x60,0xc0,0x85,0x41,0x4f,0x20,0x22,0x88,0xa9,0x68,0x25,0x67,0xca,0xaa,0x9a,0xa7,0x9,0xc6,0x1a,0x4,0x6e,0x89,0xce,0x39,0xc1,0x59,0xb2,0xf2,0xc6,0x9c,0x99,0x14,0xe,0x6a,0xc5,0xae,0x16,0x2f,0x56,0xaa,0x38,0x8f,0x14,0xf7,0xc2,0x54,0xc3,0xb8,0x40,0xe7,0x94,0xeb,0x97,0xc5,0x8e,0x8e,0x8e,0xfb,0x1b,0x29,0xa6,0x66,0x71,0xe,0x9a,0x97,0x56,0x70,0x94,0xaf,0x26,0xd,0xc0,0xcc,0x5e,0x58,0x26,0xf5,0x60,0x0,0xe5,0xa8,0x50,0xa3,0x38,0x8a,0x2a,0xb7,0x8a,0x12,0x52,0x4a,0xa6,0xb1,0xd2,0xaf,0xe4,0x4a,0x5a,0xe5,0x94,0xb4,0x38,0xc3,0x36,0xc5,0x1f,0x89,0x49,0x43,0xb9,0xbe,0xd0,0x77,0x36,0xcf,0xb,0x72,0x25,0xe,0x89,0x6b,0xb1,0x95,0xc4,0x6a,0xec,0xb8,0x42,0x3a,0xe6,0x4c,0x73,0x81,0x9c,0xd3,0x4a,0x55,0xd6,0x5a,0x46,0xd,0xef,0xab,0xec,0x3a,0x2d,0x58,0xd6,0x9,0x4c,0xbb,0xbd,0xd2,0x7e,0x2e,0x54,0x15,0x9e,0xe5,0xfd,0xae,0xd,0xc4,0x6,0x2b,0x35,0x9c,0x16,0x49,0xa0,0x21,0xeb,0x2c,0x73,0x43,0x4c,0x88,0xb2,0xe2,0xb1,0x64,0x5a,0xd4,0xa2,0x39,0x81,0xad,0x2e,0x89,0x23,0xdb,0xac,0x66,0x6,0x6a,0xde,0x1e,0x93,0xb4,0xfc,0xb3,0x14,0xac,0xad,0x9,0xbf,0x9a,0x29,0x68,0xad,0x45,0x4e,0x5,0x60,0xe5,0xa5,0x6d,0x5a,0x9d,0x4b,0x49,0xd,0xb9,0x56,0x9a,0xfd,0x68,0x88,0x4e,0x26,0x7a,0xeb,0x7c,0xed,0x48,0xa9,0x68,0x6d,0xcd,0x8f,0xe4,0xed,0xd1,0x18,0x41,0xe7,0x3b,0xc0,0x7a,0x5f,0xe9,0x1c,0x32,0x97,0xb2,0xfa,0xa,0x9a,0x7d,0x6e,0x17,0xf1,0xee,0x59,0x4c,0xd3,0x2a,0x1c,0xd,0xdb,0xd3,0xbf,0x4b,0x6,0xee,0x5e,0xa,0xbf,0xab,0x1e,0x6f,0x9b,0x8e,0x4d,0x59,0x95,0x42,0x57,0xfb,0x7b,0x47,0x47,0x47,0xc7,0xf,0x1e,0xdd,0x2,0xdc,0xd1,0xd1,0xf1,0x9a,0x41,0x56,0xf5,0xdb,0x59,0xb2,0xe5,0xac,0x20,0x99,0x74,0xcb,0xa4,0xdf,0x5a,0x47,0xb6,0xd0,0x5c,0xd8,0x16,0x5c,0xed,0x24,0x59,0xec,0x3e,0x6c,0x1d,0xa5,0x46,0x60,0xcb,0xa5,0x21,0x59,0x73,0x80,0x74,0x82,0x9c,0x33,0x9c,0xb,0xaa,0x8,0x73,0x6c,0x2f,0x75,0xce,0x3,0x6,0x98,0xe,0x3b,0x4c,0xfb,0x1d,0x76,0xe7,0x77,0x28,0x7,0xf0,0xb0,0xc3,0x74,0xd8,0x21,0xb3,0x45,0x75,0x77,0x76,0x17,0x71,0x9e,0x91,0xe2,0x82,0x79,0x3a,0x60,0x9e,0xe,0x58,0x96,0x59,0x27,0x90,0xcb,0x32,0x21,0x45,0x52,0x5,0x92,0xd5,0x37,0xaa,0xea,0x8e,0x9e,0xbf,0xc7,0x3c,0x1d,0x60,0x8c,0xc1,0xa7,0xff,0xec,0xf3,0x97,0xe6,0x7d,0xf,0x3f,0xf4,0x0,0xfe,0xfe,0x2f,0x7f,0x14,0x27,0x63,0xa0,0xcf,0xcd,0x45,0x25,0x0,0x94,0xc0,0x94,0x3c,0x41,0x2a,0xef,0xa0,0x62,0x8c,0x9f,0xfb,0xd0,0x93,0xf8,0x89,0xf,0xfe,0xd8,0xa5,0x71,0x7e,0xee,0xf9,0x17,0x71,0x76,0xb1,0xa7,0x16,0x62,0xe,0x32,0xa7,0xc9,0xb7,0xd3,0x19,0xe8,0x32,0x1f,0xb8,0xe1,0x98,0xac,0x42,0x39,0x27,0xb2,0xf1,0xf2,0xa1,0x11,0xf5,0x5e,0xce,0x9,0xc3,0xb8,0xc5,0xb0,0x39,0xa1,0x1b,0xae,0x92,0x75,0x8c,0xe5,0x46,0x22,0xa7,0x88,0x9c,0x48,0x59,0x99,0x12,0x59,0x6a,0x97,0x79,0xc2,0x7c,0xd8,0x93,0xcd,0x56,0x1e,0x67,0x85,0xe6,0x3c,0x1d,0x70,0xd8,0x5f,0xe8,0xcd,0x99,0x31,0x16,0x87,0xfd,0x5,0xa6,0xfd,0x5,0xce,0xef,0xbe,0xca,0xd9,0x8c,0x33,0x2e,0xee,0xde,0xc6,0xfe,0xe2,0xc,0x87,0xfd,0x5,0x72,0x5c,0x90,0x53,0xc6,0xb2,0x4c,0x58,0xa6,0x3,0xa6,0xc3,0xe,0x71,0x9e,0x71,0xd8,0x5d,0x60,0x3a,0xec,0x95,0x80,0x4d,0x69,0xd1,0x9b,0x7,0x30,0xb9,0xec,0x9c,0x53,0x22,0xd5,0xaa,0x9a,0x24,0xd5,0xc,0xa2,0x52,0xb,0x43,0x78,0xd0,0x81,0xc2,0x45,0x29,0x3e,0xf4,0x3f,0xdc,0x8e,0x8e,0x8e,0xfb,0x1a,0x62,0xf7,0xd4,0x46,0x56,0x83,0x95,0xca,0xac,0x6d,0xf1,0xad,0xdf,0x91,0x50,0xd5,0x5b,0x91,0x5,0xbd,0x52,0x88,0xe0,0x91,0xf2,0x85,0xab,0x8a,0x31,0x8c,0x51,0x3b,0xb1,0xe6,0xc,0xb2,0x92,0xbc,0xda,0x4e,0x85,0x80,0x2c,0x1a,0xb7,0x21,0xcc,0xa4,0xe6,0xfc,0xe5,0x9a,0x17,0xac,0xf1,0x22,0xed,0x36,0x38,0xf2,0xa1,0xc6,0x8c,0x94,0x55,0x96,0xf0,0x3a,0xf7,0x50,0x27,0x26,0x75,0xcb,0x5,0x70,0x8d,0x52,0x9c,0x6c,0xca,0xa4,0xd2,0x97,0x5,0xa8,0x96,0xb8,0x93,0x7d,0x11,0x7b,0x6c,0x61,0x45,0xbc,0xa8,0x9,0x8d,0xee,0x7f,0x5e,0x59,0x75,0x45,0x32,0xa8,0x64,0x65,0x53,0x1c,0x22,0xed,0xc2,0x54,0xcc,0x55,0x6a,0x9e,0x21,0x13,0x7b,0x5a,0x66,0xa2,0xb9,0x82,0x75,0xce,0x53,0x1b,0x90,0x8b,0x92,0x98,0x39,0x27,0x4d,0xff,0x53,0x75,0x5c,0x3b,0x5e,0xab,0x42,0x93,0x4a,0xfe,0xb5,0x64,0x63,0xcd,0xee,0x3b,0xb2,0x0,0xb,0x49,0x2a,0x24,0xb0,0xb1,0xab,0x36,0x5f,0x40,0x88,0xde,0x7a,0x5e,0x64,0xfe,0xb9,0x0,0x57,0x92,0x8b,0xad,0x75,0x78,0x6d,0x79,0x36,0xcd,0xbc,0x72,0x4d,0x86,0x1e,0x67,0x2c,0xb7,0xc4,0x5f,0xab,0xf4,0xbf,0xea,0x39,0xeb,0xf3,0xa0,0xfd,0xf7,0x88,0xd8,0xd3,0x7f,0x2f,0xe7,0xe,0xea,0xeb,0x44,0xf9,0x78,0xf4,0x67,0x70,0xa9,0xad,0xa5,0xa3,0xa3,0xa3,0xe3,0x7,0x8c,0x2e,0x75,0xe8,0xe8,0xe8,0x78,0xcd,0x20,0x8d,0xbd,0x35,0x8b,0xae,0x59,0xb9,0xce,0x89,0xb3,0x77,0x24,0x47,0x27,0xf2,0x2a,0xba,0xd5,0xc6,0x3c,0x9,0xe9,0x36,0x86,0x54,0x5e,0x64,0xcf,0x29,0x88,0xac,0xf6,0x93,0x6,0xdb,0x52,0xa,0x9c,0xf7,0x4c,0x98,0x39,0x7d,0xbf,0x9c,0x33,0x86,0x71,0x83,0x18,0x23,0xc2,0xb8,0x81,0xb5,0x16,0x67,0x77,0x5e,0xd1,0xf7,0x9a,0xa7,0x83,0x4e,0x44,0xb7,0x27,0xd7,0x34,0xb,0xcf,0x87,0x41,0x9,0xaf,0x9c,0x13,0x86,0x61,0x83,0x2,0x20,0x2e,0x13,0xdf,0x8,0x70,0x2e,0x9d,0xf5,0x3a,0x19,0x8c,0xcb,0xa2,0xa5,0x19,0x72,0x93,0xe0,0xbc,0xc7,0xc7,0xfe,0xf8,0x73,0xf8,0xa5,0xbf,0xf6,0xfc,0xa5,0x26,0xe0,0xa7,0x3e,0xf0,0x3e,0x3c,0xf1,0xf6,0xb7,0xe2,0xe3,0x7f,0xf4,0x19,0x7c,0xe1,0xe9,0x6f,0xe2,0xa5,0xdb,0xe7,0xc8,0xc6,0x21,0xb1,0x65,0xb9,0x94,0x82,0xcd,0x38,0xe0,0xc6,0x76,0xc0,0x93,0x6f,0xbb,0x85,0x9f,0xfc,0xd0,0xfb,0xf0,0xc4,0xdb,0x1e,0xd3,0xc6,0x5b,0x41,0xca,0x19,0xbf,0xfd,0xfb,0x9f,0x84,0x1f,0x6,0xa4,0x85,0xec,0xbc,0xc6,0x1a,0xd8,0x62,0x61,0x82,0x25,0x42,0x2c,0x4,0x55,0xf9,0x15,0xce,0x3f,0x2a,0xac,0xbc,0x20,0xa5,0x9c,0xc3,0x61,0x47,0x63,0xea,0xac,0xc3,0xc5,0xf9,0x1d,0xb5,0x55,0x8f,0x9b,0x13,0x9a,0xe8,0xe6,0xc,0xeb,0x83,0xde,0x48,0xe4,0x1c,0xeb,0x58,0xe7,0x4,0xef,0x83,0x36,0x49,0x96,0x9c,0xc8,0x92,0xcc,0xd6,0x6a,0xeb,0x1c,0x1c,0x2,0x42,0x48,0x18,0xc6,0xd,0xee,0xbc,0xf2,0x22,0x35,0x7,0xc7,0x5,0x9b,0x30,0x20,0xc6,0x5,0xe9,0xec,0xe,0xb6,0xa7,0xd7,0x31,0x1d,0x76,0xd4,0x4,0xec,0x6a,0xcb,0xb0,0x31,0x6,0xcb,0x32,0x69,0x33,0xa0,0x10,0xb5,0xd6,0x3a,0xf8,0x4c,0xc4,0x6e,0x49,0x89,0x89,0x61,0x9e,0xfc,0xf3,0xf9,0x93,0x35,0x1b,0xa9,0xaa,0x17,0xa,0x0,0xe4,0xa6,0xed,0x51,0xac,0x66,0xa5,0x20,0x4d,0xe7,0xfd,0xf,0xb7,0xa3,0xa3,0xe3,0xbe,0x46,0x29,0xd0,0x5c,0xde,0x63,0xde,0x43,0x1b,0x62,0xf5,0xe7,0xc6,0xbe,0xda,0x70,0x7b,0xb5,0xf4,0x1,0x95,0xac,0x63,0x75,0x9e,0xe6,0xbb,0x59,0xc7,0x8a,0xad,0x54,0xb3,0xe6,0x78,0x7,0x44,0x55,0x67,0x5c,0x55,0xdc,0xc9,0xf7,0xb4,0x5c,0x5b,0xa8,0xc9,0xde,0xa8,0x83,0x80,0x8,0x3d,0x8b,0xd2,0xd8,0x7a,0xd,0xbf,0xbf,0xd1,0x32,0xa8,0xc4,0xb1,0xe,0x35,0x83,0x4e,0xf2,0xb,0x4d,0x9b,0xf,0x67,0x0,0x6b,0xbd,0x2a,0xfb,0xe4,0x5a,0x26,0x31,0x7a,0x4a,0x52,0xb1,0xb3,0xc0,0xb0,0xb,0xc0,0xf1,0xb5,0xc9,0x5a,0xdb,0x14,0x5d,0x54,0xc5,0x64,0x5b,0x32,0x61,0x99,0x20,0x2c,0x25,0x2b,0x19,0x56,0xc9,0xc8,0xa2,0x76,0x59,0xb5,0xcd,0xaa,0xe5,0xb8,0x28,0xef,0x4a,0x73,0xd,0x5b,0x5d,0x14,0xf9,0xa8,0x15,0xb8,0x5c,0x6e,0xf6,0x6d,0x63,0x3e,0xda,0x8c,0xbe,0xc6,0xaf,0xcc,0xe3,0x4a,0xaa,0xc8,0xba,0x38,0xd7,0x92,0x7e,0xf5,0x60,0xab,0xf5,0x1a,0x75,0x61,0x57,0x48,0xda,0x55,0xd9,0xc7,0xa5,0x56,0xdf,0xa6,0xd4,0x85,0xf7,0x5f,0x2c,0xd4,0xeb,0xf3,0x31,0xeb,0x62,0x9d,0xa8,0x52,0x8f,0xf7,0xe5,0xaa,0xf6,0xde,0xab,0x48,0xc0,0xab,0x8a,0x45,0x5a,0xe2,0x4f,0x9,0xd9,0x15,0xf9,0x77,0x55,0xa6,0x5f,0xd1,0x9c,0xcb,0x4a,0x2,0x62,0x45,0xf8,0x19,0x1c,0xdb,0xcb,0xef,0xa5,0xf2,0xeb,0x19,0x80,0x1d,0x1d,0x1d,0x9d,0x0,0xec,0xe8,0xe8,0x78,0x43,0xdc,0x64,0xf0,0xa4,0x47,0xe6,0x3d,0x9c,0xaf,0x63,0x9a,0xc7,0x24,0xd3,0x4f,0x1e,0x5f,0x59,0x25,0xa,0x67,0xf0,0x65,0x56,0x94,0xa1,0xc9,0x7,0x62,0xa2,0x8d,0x42,0xc7,0xa1,0xe5,0xe,0x32,0xd9,0x94,0x42,0xe,0x29,0x21,0x71,0x9c,0x33,0xb8,0x39,0xb9,0x6,0xa0,0x60,0xda,0x93,0x8a,0x6c,0x77,0x76,0x7,0x3e,0xc,0x48,0x71,0xc1,0x30,0x6e,0x51,0x72,0xa6,0xb2,0x90,0x5c,0x10,0xe3,0xc,0xef,0x7,0x18,0x18,0x2c,0xcb,0xc,0xe7,0x1c,0x5b,0x47,0x17,0xe4,0x58,0xb0,0xe4,0x49,0x27,0x8d,0xce,0x5,0xec,0xce,0xef,0x22,0x8c,0x1b,0xec,0xcf,0xef,0xe2,0xf4,0xc6,0x43,0x0,0xa,0x6e,0xdf,0x3d,0xc7,0xff,0xf1,0x7f,0xfd,0x3a,0xfe,0xd1,0x7f,0xf9,0xf,0xb1,0x19,0xc7,0x76,0x4e,0x8d,0x47,0x6e,0x3e,0x80,0xff,0xf0,0x17,0x3e,0x8a,0x5f,0x8a,0x9,0x87,0x69,0xc6,0xe1,0x30,0x61,0x5e,0xc8,0x4e,0x6c,0xad,0xc1,0x10,0x3c,0x4e,0xb6,0x1b,0x84,0xe0,0xaf,0x58,0xb1,0xa6,0xf1,0xfd,0xe4,0xa7,0x3e,0x87,0x3f,0xfd,0xf2,0xb3,0x44,0x1a,0x32,0xe9,0x2a,0x6b,0xd4,0x99,0x9,0x4d,0xba,0x81,0x70,0xab,0x96,0x5c,0x22,0x49,0xe9,0xa6,0x2c,0xa5,0x4,0x1f,0x46,0x9c,0xdf,0x79,0x15,0xc6,0x5a,0x78,0x1f,0x30,0x6e,0xb6,0xf0,0x3e,0x10,0x39,0x36,0x8c,0x48,0x39,0x1,0xb1,0x2a,0x3,0xe4,0xa6,0xce,0xb9,0x80,0x65,0x9e,0xe0,0xd8,0x42,0x1d,0x97,0x59,0x1b,0x1a,0x63,0x5c,0x90,0x52,0x84,0xf7,0xf4,0x1c,0x39,0x3e,0xdb,0xd3,0xeb,0x38,0xbf,0xf3,0xa,0xb5,0xfe,0x2e,0xf4,0x9c,0xed,0xe9,0x75,0x1c,0xf6,0x17,0x18,0xc6,0xd,0x59,0x77,0x93,0xa5,0x56,0x61,0xb6,0x81,0xc9,0xd,0x42,0x8c,0xb,0x91,0xac,0xa5,0x20,0x99,0x8,0x1f,0x82,0x96,0x8e,0xa8,0xea,0x83,0x15,0x5,0x75,0xcc,0x58,0x2d,0x81,0x46,0x21,0x81,0x26,0xf4,0xdb,0x58,0x58,0x3f,0x50,0xb6,0xa0,0xe9,0x97,0xc5,0x8e,0x8e,0x8e,0xfb,0x1b,0xb5,0x69,0xd6,0x5c,0x62,0x6,0xc5,0x92,0x5b,0xd5,0x5c,0x47,0x25,0x14,0xdc,0xf6,0x6b,0xa,0xd8,0x3a,0x2a,0x16,0x4e,0x8b,0x62,0x9a,0x36,0x61,0xde,0x90,0xaa,0xc5,0x6c,0x51,0xd5,0x5f,0x4e,0xb5,0x4c,0xeb,0xd8,0x1e,0xe9,0x38,0xf2,0xa1,0x14,0xb2,0xa6,0xe6,0x94,0x95,0xb0,0x12,0x2b,0x2f,0x95,0x75,0x18,0xbe,0x8e,0x45,0x58,0x2e,0xfe,0xb2,0xd6,0x21,0x27,0xfa,0x1c,0xa5,0x21,0x7,0xad,0x75,0x3c,0xbf,0xc8,0x7a,0x9d,0xcc,0x29,0x69,0x41,0x88,0x6d,0x62,0x22,0x64,0x5e,0x2,0x9b,0xf5,0x35,0x92,0x67,0xec,0x38,0x5b,0xd6,0x79,0xba,0x4e,0x94,0x74,0x9c,0x21,0xd7,0x36,0x19,0x1b,0xdd,0xb6,0xe,0x9c,0x8e,0x7d,0x63,0x59,0x66,0x5,0x7b,0x75,0x4c,0x50,0x1c,0x4a,0x25,0x12,0xf3,0x8a,0xf0,0x12,0x42,0xca,0x3a,0xcb,0xb,0xa4,0xf2,0x78,0x69,0x94,0x80,0x47,0x44,0x9e,0xb9,0x7c,0xac,0x55,0xed,0x67,0xab,0xba,0x4f,0xdc,0x18,0xad,0x7b,0x43,0x6c,0xc1,0xa6,0xf9,0x97,0xde,0xd2,0xea,0x82,0xa2,0x3e,0xb7,0x21,0x2a,0xe5,0x39,0x32,0xd7,0xa8,0xef,0x9b,0x95,0x1c,0xcd,0xb9,0x12,0x7f,0xb4,0xcf,0x49,0xaf,0xdd,0xed,0xb6,0x8e,0xc7,0xa5,0x7e,0xc6,0xbc,0x3e,0x37,0x5b,0x12,0xaf,0xf9,0xef,0x35,0xf1,0x67,0x56,0xe1,0x8b,0x66,0x45,0xe4,0x36,0xc,0x79,0x4b,0xde,0xb5,0x16,0xea,0x86,0xc,0x2c,0x4d,0x8b,0xb2,0x12,0xdc,0xa6,0xaa,0x6a,0x57,0x6d,0xc0,0xad,0x23,0xa6,0xa3,0xa3,0xa3,0xe3,0x7,0x8,0x7,0xe0,0xbf,0xe9,0xc3,0xd0,0xd1,0xd1,0xf1,0x5a,0xe0,0x4d,0x6f,0xfd,0x61,0x6c,0x4f,0x4e,0x49,0xb9,0x27,0x56,0x17,0x9d,0x54,0xf2,0xaa,0xbd,0x5a,0x81,0xac,0xce,0x91,0x85,0xc4,0x33,0x1c,0x0,0xae,0x6d,0x73,0x4c,0xec,0x90,0xd,0xc6,0xb0,0xc5,0xd4,0xea,0x64,0x52,0x8b,0x3b,0x38,0x4b,0xc6,0x5a,0x22,0xeb,0x64,0xb5,0xbd,0xcd,0x98,0x71,0x3e,0xe8,0xcd,0x40,0xe6,0x46,0xe1,0x18,0x97,0xe6,0x39,0xf4,0xbf,0xb8,0xcc,0x38,0x1c,0x76,0x0,0xc8,0x3a,0xbc,0x4c,0x7,0x94,0x9c,0xb1,0xcc,0x7,0x78,0x3f,0x60,0x59,0x26,0x58,0x26,0xbb,0x24,0x94,0xfb,0xf4,0xfa,0x3,0x94,0xb4,0xc3,0xc4,0xda,0x37,0x5f,0x39,0xc3,0xd9,0x9d,0xdb,0x78,0xd7,0x3b,0x9f,0xc0,0x38,0xc,0x97,0xc6,0xc9,0x5a,0x8b,0x61,0x8,0x38,0x39,0xd9,0xe0,0xfa,0xb5,0x53,0x5c,0x3b,0xdd,0xe2,0xf4,0x64,0x8b,0xcd,0x66,0x54,0x3b,0xeb,0x31,0x72,0xce,0xf8,0xb3,0xcf,0x7f,0x19,0xff,0xd3,0x3f,0xfd,0x97,0x58,0x32,0x30,0xed,0x77,0x28,0x25,0x63,0x61,0xeb,0x72,0x5c,0x66,0xcd,0x62,0x22,0x8b,0x16,0xd4,0xca,0x6b,0x9d,0xd3,0x72,0x95,0x52,0x32,0x72,0x22,0xb,0xb3,0x63,0xa2,0x8e,0x5a,0x7a,0x17,0x58,0x6b,0xe1,0xc2,0x0,0xcf,0x65,0x1c,0x32,0x66,0x32,0x9e,0x72,0xf3,0x65,0x38,0xcb,0x89,0x5a,0xf9,0x68,0x6c,0xe3,0x32,0x6b,0x9e,0x9f,0x36,0x6,0x36,0x2b,0xfc,0x29,0x45,0x6d,0xa2,0xc,0x3,0x11,0xa3,0x96,0x55,0x9c,0xd4,0xcc,0x4c,0x39,0x88,0xd3,0xe1,0x42,0xad,0x5d,0xd3,0x61,0x47,0x64,0x23,0x37,0x4d,0x96,0x9c,0xe1,0x87,0x71,0xa5,0xa2,0xa0,0x1b,0x41,0xd4,0xec,0x23,0x60,0xad,0xaa,0x68,0x72,0x8a,0x68,0x3f,0x16,0xcc,0x87,0x3d,0x2e,0xce,0x6e,0xc3,0xd,0x27,0x34,0x5e,0xcb,0xbe,0xff,0xf1,0x76,0x74,0x74,0xdc,0xb7,0xb8,0x71,0xf3,0x51,0xdc,0xbc,0xf5,0x16,0x84,0x61,0xe0,0x38,0x85,0xa4,0xd7,0xe8,0xdc,0x34,0xfa,0xa,0x59,0xd6,0x2a,0xf8,0x2d,0x67,0xe2,0xb6,0xc4,0x8b,0x7c,0xb7,0x5b,0xb3,0x56,0x52,0xd1,0x57,0xb3,0x5d,0xd9,0x8b,0xab,0x8d,0xb5,0x5e,0xe7,0x9b,0x20,0x42,0x2e,0x97,0x32,0xaa,0xfe,0x23,0x52,0xb0,0x5e,0xaf,0x69,0x81,0x2f,0x69,0x21,0x55,0x41,0x81,0x67,0x42,0x4e,0x32,0x5,0x85,0x90,0x11,0x72,0xc9,0xf0,0x22,0x21,0x15,0x90,0xa1,0xda,0x90,0x1b,0x62,0x4e,0xc8,0x1a,0x52,0x26,0xd6,0xb6,0x78,0x52,0x15,0x66,0x58,0xe7,0x90,0x52,0x64,0x12,0x52,0x2c,0xd0,0x19,0xd6,0x9a,0x15,0x51,0x24,0xef,0x8f,0xd2,0xb8,0x20,0xf4,0xb1,0xb5,0x9d,0x56,0xf3,0x6,0x5b,0xc2,0xcc,0xb4,0x8d,0xb4,0xa6,0x5e,0xdb,0x64,0x5e,0xc3,0xb,0x6c,0x44,0xa6,0x15,0x6d,0x17,0x56,0xe2,0xd5,0x54,0x5b,0xb5,0x1c,0x43,0x69,0x21,0xae,0xef,0x59,0xf7,0xc9,0x48,0x63,0xb1,0x5d,0x2b,0xfd,0xcc,0xf1,0x31,0x6e,0xc7,0xb4,0xc9,0x67,0x5e,0x6d,0xbf,0x55,0xcd,0x31,0x79,0xd9,0x46,0x7f,0xa8,0x63,0xc3,0xf9,0x4b,0x73,0x32,0x60,0xbd,0xef,0xc7,0x20,0xc5,0x61,0x4b,0xd4,0x56,0x2b,0xb3,0x9e,0x5f,0x5c,0x1e,0x77,0x89,0x8,0x5c,0xd3,0xdf,0x55,0xdd,0xd9,0x10,0x77,0x2d,0x21,0xd8,0xbe,0x5e,0x9f,0x5b,0xd6,0x3a,0xbe,0xe3,0xfa,0x93,0xf6,0x71,0x29,0x2f,0x29,0x9c,0x47,0x3c,0x1d,0xf6,0x78,0xf5,0xf9,0x67,0xd1,0x5b,0x40,0x3a,0x3a,0x3a,0x3a,0x1,0xd8,0xd1,0xd1,0x71,0x5f,0xe3,0xd1,0xb7,0x3d,0x89,0xf1,0xe4,0x54,0x27,0xa9,0x68,0x56,0xfa,0x25,0x3f,0x47,0x26,0xa1,0xa2,0xf0,0xca,0x39,0x51,0x83,0x6e,0x5b,0x8f,0xc7,0x93,0x7c,0x51,0x8,0x2a,0x11,0x28,0xe1,0xd2,0xdc,0xfa,0x5a,0x57,0x71,0xa9,0x14,0x44,0xac,0x24,0x32,0x69,0x6f,0xb3,0x6f,0xc8,0x56,0x1c,0x38,0x2f,0xd0,0x69,0x6,0xdf,0xb4,0xbf,0xc0,0x61,0x77,0xe,0x1f,0x6,0x2c,0xd3,0x1,0x17,0x67,0x77,0xe0,0xf9,0x26,0x49,0xac,0xa2,0xd3,0x81,0x8,0xa2,0xf9,0xb0,0x57,0x3b,0xb2,0x16,0x56,0x18,0xab,0xaa,0xc5,0x30,0x8c,0x8,0xc3,0x6,0x0,0xf0,0xdc,0xcb,0xe7,0xf8,0xea,0xd7,0xbe,0x86,0x5b,0xf,0x3f,0x84,0x87,0x1e,0xb8,0xd1,0xac,0x7a,0x7f,0xf7,0x38,0x3b,0x3b,0xc3,0xff,0xfb,0x3b,0xbf,0x87,0x7f,0xfc,0xcf,0xfe,0x15,0x2e,0x76,0x7,0xc4,0xa5,0x92,0x7e,0x39,0x53,0xb1,0x46,0x8e,0x44,0xe2,0x25,0x2e,0x4c,0xd1,0xb1,0x37,0x46,0x6f,0x94,0x88,0xf8,0x4,0x67,0x16,0xee,0x1,0x3,0x1c,0xf6,0x17,0x5a,0x66,0x32,0x8c,0x5b,0x58,0xce,0x5a,0x14,0x97,0x17,0x35,0xeb,0x2,0xcb,0x34,0x35,0x59,0x3b,0xd4,0x34,0xdc,0x2a,0x15,0x4a,0xe1,0x1b,0xa6,0xb8,0xc0,0x80,0x94,0x13,0x25,0x27,0xc4,0x18,0x1,0x50,0xab,0xb3,0xb5,0x96,0xd4,0x94,0x7c,0x63,0x72,0xf7,0x95,0x17,0x39,0xd7,0x31,0x21,0xc5,0x19,0xa5,0x0,0x87,0x1d,0x35,0x20,0xef,0x2e,0xee,0x72,0x51,0x8c,0xd5,0x1b,0x4e,0x6b,0x2d,0x91,0x93,0x5c,0x4,0xa2,0x36,0x32,0xdb,0x34,0x1b,0x72,0xe6,0x64,0xc9,0x6b,0x7b,0x4f,0x29,0x40,0xce,0x11,0x39,0x25,0x1c,0x76,0x17,0xb8,0xb8,0x38,0x27,0x35,0x48,0x9c,0x91,0x7b,0xb,0x70,0x47,0x47,0xc7,0x7d,0x8c,0xeb,0xf,0xde,0xc2,0xc3,0x6f,0x7e,0x2b,0x42,0x18,0x34,0x4f,0xb5,0xb4,0xca,0x68,0x5a,0x39,0x51,0x62,0x2e,0x73,0x29,0x87,0x69,0xaf,0x5b,0x4c,0x54,0xd5,0x85,0x1d,0xfa,0xce,0x97,0x48,0xe,0x21,0xee,0xe4,0xfd,0x5b,0xf5,0xb8,0x28,0xc7,0x2c,0x5f,0x17,0x8c,0x6b,0x2d,0xbb,0xd5,0x32,0x6a,0x0,0xbd,0x9e,0xb6,0xb9,0x6f,0x12,0xf7,0xb0,0x26,0xe9,0x6a,0x9b,0x3d,0x56,0xb6,0x58,0x21,0xb8,0x6c,0x43,0x8,0x15,0x5d,0x58,0x92,0xcf,0x21,0x8b,0x88,0xb2,0x48,0x56,0x2f,0x16,0x52,0xaa,0x91,0xe8,0xfa,0x94,0x52,0x63,0x6c,0x30,0x55,0x48,0x59,0x6b,0x69,0x75,0xc,0x2b,0xb9,0x66,0x57,0xc4,0x9a,0xb5,0x6d,0x86,0x1d,0x56,0x59,0x72,0xaa,0x3a,0x14,0x72,0xcd,0x36,0xd,0xc0,0x4a,0x52,0x19,0xb6,0x14,0x97,0x95,0x22,0xcf,0xe0,0xb8,0xa5,0x37,0xeb,0xe7,0xd2,0xf8,0x10,0x21,0x52,0x95,0x38,0x13,0xfb,0x76,0x53,0x4a,0xb2,0x2a,0x1e,0xb1,0xba,0x8f,0x74,0xfd,0x35,0xd,0xf1,0x57,0x49,0x36,0xcb,0xc7,0xb0,0x94,0xc,0xe7,0xea,0x79,0x62,0x1b,0xbb,0x73,0x39,0x3a,0x2e,0xc2,0xaa,0xd5,0x73,0xa2,0x2d,0x36,0xb1,0x4d,0xc3,0xb4,0x59,0x15,0x79,0x55,0x32,0x31,0x1f,0xd3,0x84,0x4a,0xc4,0xae,0x48,0x40,0x3d,0x34,0xbc,0x2f,0xc0,0x9a,0xa4,0x6e,0x7e,0x96,0xd7,0xad,0x54,0x97,0x28,0x57,0x92,0x7c,0xb8,0x4c,0xa9,0xb6,0x8c,0x25,0x72,0xc9,0xb4,0x60,0x3c,0x1d,0xf0,0xca,0xb,0xcf,0xf4,0x22,0x90,0x8e,0x8e,0x8e,0x4e,0x0,0x76,0x74,0x74,0xdc,0xe7,0x4,0xe0,0xdb,0x9f,0xc4,0x66,0x73,0xaa,0xe4,0x5f,0xbb,0xca,0xab,0x41,0xe2,0xa5,0x54,0x35,0x81,0x4c,0x16,0xaf,0xb4,0x5f,0x60,0x95,0xf9,0x53,0xe7,0xda,0x75,0xd5,0x3a,0x37,0x4a,0x2f,0x21,0xf6,0x62,0x5c,0x28,0x23,0x8e,0x27,0x9c,0x4e,0x5a,0x5e,0xf9,0x46,0xc4,0x5a,0xb,0xe7,0x7,0xc,0x23,0x11,0x75,0x61,0xdc,0xac,0x1a,0xff,0xac,0xb5,0x6a,0x3b,0x9a,0xa7,0x3,0xd9,0x80,0x79,0x42,0xed,0xc3,0x80,0x61,0xdc,0x2,0xa5,0x60,0xd8,0x9c,0x20,0x84,0x81,0x54,0x69,0x3e,0x60,0x1c,0xb7,0x80,0xa1,0x56,0xe3,0x61,0xa4,0x56,0xe1,0x57,0xee,0xee,0xf0,0xf1,0x3f,0xf9,0x3c,0x9e,0x7d,0xf6,0x9b,0xd8,0x8c,0x1,0xdb,0xcd,0xbd,0xed,0xbd,0xeb,0x79,0x64,0xc1,0xb2,0x2c,0x78,0xe1,0xc5,0x97,0xf0,0xfb,0x1f,0xff,0x43,0xfc,0x8f,0xff,0xeb,0xaf,0xe2,0x77,0xff,0xfd,0xa7,0x90,0x33,0x15,0x92,0x48,0xb,0x2f,0x0,0x1c,0xf6,0x3b,0x56,0xce,0xed,0xd4,0xe2,0x4,0xd,0xc3,0xb6,0x9a,0xfb,0x43,0xa,0x3d,0xaf,0x16,0x1c,0xe7,0x3c,0x67,0x2a,0xd2,0xd,0x80,0xf7,0x3,0xfc,0x30,0x62,0xdc,0x6c,0x55,0x31,0xd9,0x6,0x7d,0x4b,0x8e,0x22,0x59,0xb1,0x6a,0x86,0x50,0xc9,0x49,0x6f,0x34,0x28,0x3,0x30,0xe8,0x3e,0xe4,0x52,0x30,0x8c,0x23,0xc,0x8c,0xe6,0x37,0xb6,0xcf,0x91,0x9c,0x28,0x0,0xf0,0x61,0xc0,0x61,0x77,0x81,0x30,0x10,0x51,0x68,0x9d,0xa3,0x62,0x17,0x63,0x35,0x57,0xd0,0x72,0x36,0xa4,0x73,0x9e,0x55,0x2a,0xb6,0xae,0xde,0x4b,0xe1,0x8c,0xe4,0x2a,0x35,0x24,0xad,0x64,0xff,0x51,0x89,0x48,0xc4,0x61,0x77,0x8e,0xdd,0xf9,0x19,0xdf,0xb0,0xe,0x48,0xf3,0x45,0xff,0xe3,0xed,0xe8,0xe8,0xb8,0x6f,0xf1,0xc0,0x23,0x8f,0xe1,0xe6,0xad,0xc7,0x2a,0x1,0xd8,0x14,0x26,0x8,0xd9,0xa7,0x2a,0x2b,0x21,0xe4,0x50,0x2a,0x51,0xc3,0x56,0xd1,0xf6,0x1a,0x6c,0x9d,0xa7,0xeb,0x6e,0x8,0xaa,0xf2,0x3,0x68,0x11,0xc6,0x39,0xaf,0x4,0x9d,0xd8,0x4c,0x55,0x6d,0x66,0xcc,0x8a,0xb8,0xa2,0x6b,0x4b,0xd6,0x6b,0x34,0xd9,0x68,0xbd,0xee,0x9b,0xbb,0xd4,0xd4,0x6e,0x94,0x8,0xb3,0xde,0xb3,0x42,0xae,0x96,0x9c,0xa8,0x72,0xed,0x48,0x4d,0x4f,0x19,0x7e,0xd5,0x8a,0xa,0x43,0xea,0x3f,0x59,0x6c,0x54,0x5,0xbd,0x28,0x16,0x61,0xd4,0x7d,0x80,0x46,0x6d,0x57,0x72,0x86,0x63,0x7b,0x6b,0x4b,0xa,0xb6,0x16,0xd9,0xb6,0xe1,0x18,0x4d,0xf9,0x8a,0x73,0x5e,0x55,0x96,0xb5,0xd0,0x44,0x32,0x93,0xb1,0x8a,0xb6,0x68,0x15,0xec,0x86,0xad,0xd7,0x8e,0xad,0xcf,0x4a,0x1e,0x36,0x8a,0xca,0xd2,0x38,0x2b,0x5a,0x65,0x5f,0x3b,0xbb,0x6a,0xaf,0x8b,0x4a,0xa8,0x95,0xb5,0x7d,0xb7,0xcd,0xc,0xac,0xa4,0x5b,0x59,0xed,0x73,0xbb,0x58,0xbb,0xca,0xe8,0xb3,0x44,0x4a,0x66,0xb5,0x39,0x57,0x52,0x51,0x1d,0x9,0x7c,0x9d,0xd6,0xfd,0x29,0x85,0x35,0x7a,0x4d,0x4b,0xf5,0x11,0x1,0x5a,0x89,0xb9,0x66,0x9e,0xd8,0x92,0xbc,0x2d,0x11,0xdb,0x7e,0xbe,0x86,0xc0,0xab,0x4f,0x33,0x2b,0x35,0xdf,0x6a,0x1b,0x47,0x64,0xdf,0x15,0x41,0x2c,0xdc,0x30,0xbc,0xda,0xac,0xee,0x8f,0x94,0xa8,0x4d,0x87,0x3d,0x5e,0x79,0xfe,0x99,0xfe,0xc5,0xd3,0xd1,0xd1,0xf1,0xba,0x40,0xf,0x3b,0xea,0xe8,0xe8,0x78,0xcd,0x50,0x9a,0x2c,0x18,0xf9,0xff,0x6d,0x3e,0x8d,0xcc,0x96,0x32,0x7,0x6c,0x53,0x6,0xdb,0xba,0xd5,0x4e,0xf3,0x74,0x78,0x15,0x9a,0x42,0xab,0xb,0x17,0xdd,0x35,0xea,0x40,0xb6,0x3,0xeb,0xc4,0x5f,0x72,0x0,0xad,0x53,0x5b,0x90,0x14,0x43,0xd0,0xf3,0x2,0x62,0x5c,0x70,0x72,0xed,0x6,0x2e,0xce,0xee,0x60,0xd8,0x9e,0x22,0x25,0x52,0x19,0x84,0x30,0x0,0xc6,0x60,0x99,0xe,0xf0,0x21,0x20,0x2e,0x64,0x7,0x1a,0xb7,0x9e,0x6f,0x64,0x32,0x86,0x71,0x64,0x55,0x60,0x82,0xf,0x81,0x8a,0x2a,0xe6,0x9,0xe3,0xf6,0x14,0xd6,0x7b,0x9d,0x44,0x12,0xb9,0x95,0xb8,0xc9,0x38,0x23,0x97,0x8c,0x3f,0xfa,0xdc,0x57,0xf1,0xc7,0x9f,0x7f,0x1a,0xf,0x3f,0x74,0x3,0x8f,0xbf,0xe9,0x26,0x9e,0x7c,0xc7,0x5b,0x70,0xf3,0xc1,0x1b,0xb8,0x76,0xba,0x25,0x42,0x10,0x40,0x4c,0x9,0xbb,0xdd,0x1e,0xaf,0xde,0xbe,0x8b,0xaf,0x7d,0xfd,0x19,0x7c,0xe5,0xe9,0x67,0xf0,0x8d,0xe7,0x5e,0xc4,0xbc,0x50,0x53,0xef,0xb8,0x39,0xc1,0xb4,0xdf,0x61,0x59,0x66,0x2c,0xd3,0x1,0x0,0x10,0x23,0x35,0xe2,0x1e,0xf6,0x17,0x44,0x7e,0x2e,0xb,0xc6,0xed,0x9,0xf6,0x17,0x7b,0x84,0x71,0x3,0xe7,0x3d,0x7d,0x36,0x0,0xc3,0x66,0x8b,0xf9,0xb0,0xa7,0xf1,0x6f,0x1a,0x72,0xc3,0x38,0xc2,0x3a,0x87,0x61,0xdc,0x50,0xa3,0x6f,0x4e,0x4a,0xa0,0x5a,0x67,0xb4,0x94,0x85,0xc8,0x54,0xc7,0x6d,0xbf,0x44,0x74,0xa,0x91,0xab,0xad,0xc1,0x60,0xa5,0x21,0xe7,0x49,0x11,0xc9,0x48,0x8a,0xc9,0x71,0x73,0x82,0x94,0x22,0x42,0x18,0x75,0x1f,0xa8,0xb0,0x65,0xa1,0x9c,0xa5,0x94,0x31,0x6e,0x4f,0xd8,0xa,0xe6,0x60,0x32,0x65,0x13,0x96,0x52,0xe0,0x87,0x11,0x99,0x55,0x9d,0xb2,0x6f,0x80,0xd5,0xbc,0x47,0x99,0x98,0xe7,0x5c,0xed,0x48,0x42,0x2,0x16,0x64,0xb5,0x43,0xe9,0xd,0x95,0x31,0x54,0x70,0x92,0x12,0xd2,0xdc,0xd5,0x7f,0x1d,0x1d,0x1d,0xf7,0x37,0x44,0xf1,0xae,0x39,0x65,0x65,0x9d,0x5d,0x56,0x8b,0x18,0x28,0x53,0x56,0x52,0x54,0xdb,0xbc,0x3d,0x59,0x3c,0x52,0x55,0x57,0xce,0x4a,0x2,0xd2,0xf5,0x9f,0x72,0xea,0x24,0x2b,0xcd,0x72,0xb6,0x1f,0xa9,0x0,0xe9,0xda,0xa1,0xf3,0x4,0xb1,0x10,0xf3,0xf5,0xba,0xf0,0xe3,0x99,0x1f,0x93,0x5,0x43,0xe7,0x69,0xdb,0x5a,0x3a,0xd5,0xcc,0xf,0x6a,0x63,0x70,0x55,0xac,0x49,0x14,0x88,0xf7,0x44,0x3e,0xd1,0x75,0x80,0x2c,0xbe,0x3a,0xc7,0x0,0x48,0xe5,0xaf,0x59,0xb3,0x6e,0x95,0x9,0x27,0xf9,0x81,0xaa,0x22,0x83,0x21,0xd,0x19,0xcf,0x3d,0x64,0x1,0x4b,0xc9,0x3d,0x99,0xcb,0x94,0xc4,0x1c,0x62,0x46,0xce,0x45,0xf3,0x3,0xa9,0xcc,0x8c,0x33,0xf5,0x98,0x70,0xcb,0x4d,0x4b,0x71,0x5b,0x64,0x25,0x51,0x1d,0xb5,0x48,0x43,0xa2,0x37,0x88,0x4c,0x4d,0x29,0x57,0xb5,0x64,0x6b,0x67,0x2d,0x46,0x33,0xf7,0xa4,0x74,0xc3,0x34,0xa,0xc5,0x36,0xfb,0xae,0x1d,0x3f,0x79,0xd,0x8d,0x1d,0xd9,0xac,0xd,0xc,0x72,0x91,0xfc,0x3a,0xab,0x51,0x1f,0x12,0xfb,0x61,0xd8,0x12,0x9e,0x52,0xa4,0x3c,0x64,0xeb,0x58,0xf9,0x56,0xea,0xb1,0x6f,0xc8,0x3f,0x22,0xf6,0x72,0x93,0x25,0x9c,0x6b,0x69,0x89,0x90,0xa1,0xb8,0xac,0x16,0x2c,0xd,0x31,0x59,0x74,0xcc,0xaa,0xfa,0x51,0xd4,0xaa,0x97,0x8b,0x41,0xaa,0x95,0xf7,0x52,0x4e,0x1f,0x70,0x59,0x95,0xa7,0x19,0x96,0xe5,0x72,0xf7,0x47,0xcb,0xa,0x5e,0x41,0x26,0xd2,0x39,0xd8,0xe4,0x13,0x36,0xae,0xef,0xae,0xfd,0xeb,0xe8,0xe8,0xe8,0x4,0x60,0x47,0x47,0xc7,0x7d,0x8f,0xd5,0xca,0xae,0xa1,0x49,0x73,0x4b,0x7,0x12,0x31,0x23,0x96,0x8d,0xba,0xe2,0xbb,0x9e,0x69,0x81,0x83,0xba,0xb3,0xe6,0xd9,0xb4,0x2b,0xd5,0xa5,0x24,0x5e,0xed,0xa6,0x9c,0xbb,0xe0,0x3d,0x62,0x8c,0x97,0x26,0x91,0xcd,0xdb,0xc1,0xf9,0x1,0x39,0x45,0x78,0x4f,0x64,0xd5,0xf6,0xf4,0x3a,0x72,0x4e,0xb8,0x76,0xe3,0x21,0x6e,0xa1,0x25,0x65,0x5a,0x18,0x36,0x18,0xc6,0xd,0xac,0x9d,0xa8,0x65,0x97,0xf3,0x4,0x25,0x20,0x7b,0x18,0xb7,0x80,0x81,0x92,0x82,0x92,0x1d,0x34,0x9c,0x5e,0xe7,0x4c,0x40,0x22,0x24,0x63,0x8c,0x8,0x61,0xa0,0x9,0x2f,0x5b,0x97,0x8d,0x33,0x78,0xf1,0x95,0xdb,0x78,0xe5,0xce,0x39,0x3e,0xfd,0x85,0xa7,0xd9,0x72,0x64,0x30,0x4f,0x7b,0x6d,0xd3,0x35,0xc6,0x62,0x99,0xf,0x9a,0x75,0xe7,0xc2,0x6,0x58,0xce,0x55,0x3d,0xe1,0x99,0xcc,0x23,0x45,0xdf,0x82,0x30,0x8c,0x98,0xa7,0x3d,0xc,0x5b,0x67,0x61,0x0,0xec,0x69,0xbc,0xf7,0x17,0x67,0x18,0xb7,0x27,0x88,0xcb,0x8c,0x10,0x46,0xc4,0x65,0xa9,0x8a,0x8,0x63,0x10,0x86,0x91,0xac,0x2a,0xcb,0xc,0x78,0x9a,0xe1,0x8a,0xba,0x8e,0xf6,0x85,0x6f,0xce,0x90,0xf4,0xe6,0xae,0xf0,0xd,0x97,0xaa,0xfc,0xc,0x60,0x40,0xc4,0x2b,0xad,0xec,0x9b,0xa6,0x31,0xb0,0x20,0x9b,0xc4,0x8a,0xcb,0x8d,0xde,0xc0,0x50,0x7b,0xf3,0xa2,0x96,0xab,0xcd,0xe6,0x84,0xf2,0x18,0xb1,0x28,0x81,0x2a,0x96,0xe1,0x36,0x4,0x3e,0x4,0x22,0x2a,0xc9,0xa,0xec,0x9a,0x9b,0x18,0x0,0xa6,0x12,0xcd,0x60,0xd2,0xd8,0x28,0x21,0x7d,0x15,0x51,0x4d,0x8d,0xd4,0xc6,0x7b,0x58,0x37,0x0,0xd3,0x9d,0xfe,0xc7,0xdb,0xd1,0xd1,0x71,0xdf,0x22,0xa7,0xac,0x8b,0x20,0xaa,0x8b,0x5e,0x29,0xab,0xe4,0xfb,0xd3,0xc0,0x34,0x96,0xc8,0x56,0x61,0xa5,0xb9,0x7b,0x8d,0xbd,0x97,0x22,0x3c,0x9c,0x92,0x2a,0x85,0x17,0xeb,0xb4,0x64,0xc3,0x8,0x51,0x46,0xea,0x36,0x6b,0x25,0x7e,0x83,0xad,0xc6,0x6c,0xf5,0x75,0xda,0x2,0xdf,0x58,0x54,0x65,0x2e,0x90,0x33,0xe6,0x9c,0x75,0xfb,0xea,0x28,0x28,0x35,0x43,0x4f,0x88,0x32,0xeb,0x3c,0x93,0x30,0x74,0xd,0xcb,0x47,0x24,0x93,0xb5,0x16,0x29,0x25,0x25,0x26,0x85,0xe4,0x94,0x6b,0x87,0xb8,0xa0,0xb5,0x45,0x98,0x95,0xe6,0x10,0x1b,0x2a,0x2b,0xcc,0x6b,0xbd,0x59,0x55,0xc4,0x59,0xce,0x2d,0xa6,0xeb,0xe,0xa9,0x7,0x25,0xde,0x24,0x35,0xf1,0x25,0xaa,0x4,0x2c,0xa4,0x3d,0xcc,0xd2,0x56,0x2c,0xca,0x48,0xd4,0xa2,0x95,0xda,0x2c,0x2c,0x39,0xb8,0x89,0x3f,0x33,0x93,0x6c,0x4c,0xbc,0x19,0x53,0x1a,0x5,0x21,0xf4,0x38,0x59,0x51,0xe4,0x15,0x2e,0x71,0x91,0xed,0x18,0x83,0x9c,0x4a,0x53,0xc2,0x51,0x9,0x2d,0xba,0x86,0x4b,0xe,0x61,0x9d,0xff,0x98,0xa6,0xf9,0x39,0xdb,0x1a,0xeb,0x52,0xb,0x44,0xea,0x39,0x55,0x95,0x9c,0x4c,0x3a,0x72,0x64,0x4b,0xce,0x95,0x1c,0x44,0x93,0x1f,0xac,0x16,0xea,0xb6,0xc4,0xa3,0x1d,0xe7,0x56,0xfd,0x27,0x85,0x2f,0x8d,0xc5,0xb8,0xcd,0x9b,0x3e,0xe6,0xee,0xb4,0x44,0xa5,0x55,0xfe,0x95,0x5a,0xf4,0x71,0x45,0x7f,0x87,0x72,0x7e,0x5a,0x62,0x87,0xbc,0x52,0x5a,0x5e,0xd6,0x6,0x16,0x5e,0xb0,0xe6,0xf9,0x6e,0xb9,0x87,0x4d,0xb8,0xa3,0xa3,0xa3,0xa3,0x13,0x80,0x1d,0x1d,0x1d,0xf7,0x13,0x68,0x2,0x5f,0x94,0xc4,0x3,0x6a,0x13,0xab,0xd8,0x30,0xa9,0xc9,0x8e,0x26,0xad,0xb2,0x42,0x5e,0x83,0x98,0xb1,0x6a,0x83,0x2b,0x32,0x31,0x66,0x2,0x4a,0x27,0xf1,0xce,0x69,0xc0,0xf7,0x32,0xcf,0x4a,0xa6,0x69,0x7e,0x51,0x66,0x25,0x0,0x5b,0x45,0x65,0x65,0x56,0xb2,0xe3,0xc4,0xe,0x5a,0x90,0x31,0x8c,0x5b,0x22,0xed,0x9c,0x83,0xf,0x3,0xe6,0xc3,0x5e,0x6d,0x29,0xce,0x51,0xce,0x9c,0x75,0xe,0xde,0xf,0x35,0x50,0x1c,0x40,0xb6,0x19,0x26,0x67,0xc,0x9b,0xad,0x36,0x6,0x57,0x15,0xa0,0xe7,0x1b,0x81,0x82,0x58,0x16,0x6a,0xc5,0x5d,0x26,0xb2,0xa0,0x3a,0xaf,0x56,0xe5,0x9c,0x12,0x96,0x79,0x42,0x18,0x6,0x94,0x52,0x30,0x1d,0x2e,0x54,0x25,0x67,0xad,0xc5,0xee,0xec,0x8e,0x66,0x2c,0x9,0xc9,0x6,0x26,0xe6,0xc2,0x68,0xb1,0x4c,0x7,0x58,0xeb,0x58,0x19,0x48,0xef,0x3f,0x95,0x1d,0x86,0xcd,0x96,0x72,0x2,0x53,0xc4,0xe9,0xb5,0x1b,0x98,0xe,0x3b,0x6c,0x4e,0xae,0x69,0x46,0x5f,0x8,0x3,0x29,0xfd,0x42,0x50,0xdb,0x72,0x55,0xd6,0x71,0x2b,0x23,0xab,0x11,0xae,0xca,0x17,0x8a,0xcb,0x82,0x6a,0x3f,0xaa,0x61,0xe0,0xc6,0x3a,0x59,0x76,0x27,0x35,0x84,0x28,0x4d,0xd8,0x3e,0x9d,0x4c,0xe4,0x1c,0x40,0xda,0xde,0xe9,0x8d,0x7,0xf9,0xe6,0x88,0x7e,0x6e,0x3f,0xab,0x14,0x85,0x90,0x65,0xaa,0xcd,0xaa,0xa2,0x33,0xc2,0xd8,0xc6,0x46,0x76,0xb4,0xba,0xbf,0xa,0x59,0xbf,0xb4,0x14,0x4f,0xbf,0x2f,0xcb,0x81,0x14,0x83,0xc6,0xf5,0x3f,0xdc,0x8e,0x8e,0x8e,0xfb,0x1a,0x57,0x95,0x2d,0x48,0x33,0xae,0xc6,0x26,0x34,0x4a,0x2a,0xfa,0x8e,0x76,0xc8,0xa5,0x30,0xf9,0xd5,0xb4,0xb4,0xb2,0xea,0x8e,0x94,0x81,0xb,0x5b,0x86,0x79,0x71,0xcf,0x0,0xce,0x59,0x76,0x87,0xd2,0xf7,0xbe,0x2a,0xdb,0x4c,0x2d,0xa6,0xa8,0x59,0x72,0x68,0xc8,0x32,0xc7,0x8a,0x3d,0x83,0x38,0x2f,0xa4,0xd2,0x8b,0x91,0xd4,0xda,0x7c,0x3d,0x4e,0xac,0x70,0x23,0x45,0xb8,0xab,0xca,0x7f,0x47,0x56,0x60,0x52,0x8a,0xd5,0x45,0x28,0x7a,0x8e,0x43,0xc9,0x46,0x4b,0xc8,0xbc,0xb1,0x88,0x71,0x86,0x35,0x1e,0x29,0x2d,0xaa,0x30,0x6b,0x73,0xea,0xac,0x71,0x48,0x25,0xc1,0xb0,0x7a,0xdc,0xb2,0x32,0xb2,0xe6,0x17,0x3b,0xcd,0xd4,0x95,0x39,0x8a,0xa8,0xd9,0xc5,0xee,0xa,0x53,0x95,0x7b,0xa6,0xed,0xe1,0x60,0x12,0xd2,0x18,0xa8,0x95,0xb8,0xb6,0xf2,0xd6,0x6b,0x94,0xa8,0x4,0x45,0x55,0x48,0x24,0xa7,0x41,0xe6,0xc2,0x2e,0x21,0xea,0x74,0x1e,0x85,0x5a,0x8a,0xd2,0xe6,0x2e,0xc2,0x40,0x33,0x14,0x6b,0x39,0x58,0x66,0xd2,0xcf,0x72,0x86,0x1f,0x8d,0xad,0x1,0x39,0x22,0x62,0x9c,0x79,0x3f,0xe3,0xca,0x13,0x4b,0x64,0x61,0x69,0xda,0x93,0x93,0x16,0xa0,0xa8,0x95,0xb9,0xa0,0xc9,0x70,0xb4,0x28,0x16,0xaa,0x6a,0x54,0x76,0x8d,0x49,0xdb,0xb8,0xcc,0x70,0xde,0x23,0xc5,0xd8,0xac,0x13,0x1b,0xa8,0x58,0x9f,0x17,0x91,0xb,0x17,0xc5,0x14,0x14,0x8d,0x1f,0xd1,0x79,0x62,0xe6,0xa6,0xe7,0xe6,0x1c,0xad,0x76,0xf3,0xe6,0x34,0xe3,0xf7,0x93,0x7d,0x5b,0xe7,0x12,0x4a,0x4e,0x60,0x4b,0x4,0xb6,0xc7,0x44,0x1d,0xe2,0x95,0x1e,0xd4,0xf6,0x8f,0x72,0x85,0xe2,0xef,0xa8,0xfc,0xa5,0xa3,0xa3,0xa3,0xa3,0x13,0x80,0x1d,0x1d,0x1d,0xf7,0x23,0xec,0x51,0x60,0x38,0x0,0xb5,0x83,0x5a,0x2e,0x67,0xd0,0x9,0x1a,0x2e,0xb7,0xd4,0x9a,0x46,0x3d,0x28,0x20,0x35,0x57,0x59,0xfd,0x2c,0x13,0x5b,0xb1,0x1c,0x27,0x6e,0xe4,0x75,0x61,0x20,0xf2,0xc9,0x64,0xe4,0xc,0x5e,0xd9,0x67,0x3b,0xf,0x5b,0x4b,0x25,0xa8,0x99,0x4a,0x2c,0x68,0x65,0x5e,0x32,0xe7,0xe2,0x32,0x31,0xf1,0x64,0x78,0x35,0x97,0xf6,0xcf,0x7b,0xf,0x6b,0x9d,0x66,0xe6,0xf9,0x61,0x80,0x2b,0x16,0x36,0x50,0x4e,0x5d,0x8a,0xb,0xe0,0x1c,0xac,0xb1,0x1a,0x82,0x8e,0x5c,0x50,0x5c,0xd1,0x6,0x41,0x5d,0xf1,0x76,0x5e,0x15,0x7f,0xa5,0x64,0xc4,0x38,0xeb,0xfe,0xc7,0xb8,0x68,0x20,0xf8,0x74,0x20,0x1b,0x6f,0xce,0x99,0xec,0x58,0xbc,0xbc,0xec,0xc3,0x88,0x69,0x7f,0xa1,0xc4,0x24,0xa,0xd9,0x7b,0x8d,0xb5,0x38,0xec,0xce,0x11,0x97,0x19,0xd3,0x61,0x8f,0x52,0x48,0xe9,0x78,0xd8,0x5f,0x60,0x73,0x72,0x8d,0xca,0x41,0xf2,0x3a,0x60,0x5c,0x48,0x3f,0xcf,0xe3,0x26,0x6a,0x2,0x69,0x63,0x14,0x25,0x60,0x21,0x49,0x7,0xac,0xf5,0xac,0xf8,0x60,0x55,0x23,0x6a,0x4b,0x20,0x11,0xb9,0xd5,0x6,0x2e,0x56,0x1f,0xbd,0x81,0x61,0xe2,0x96,0x8,0xc6,0x50,0x15,0x1f,0x9c,0xf,0x55,0x2,0x9d,0x32,0x29,0x45,0x38,0x1f,0xb4,0x35,0x1a,0x80,0x86,0xd1,0xb,0x49,0xbc,0x52,0x7b,0x8a,0xc2,0xc0,0x56,0xbb,0x72,0x3e,0xa,0xa,0x17,0x35,0x47,0x6b,0x4f,0xcf,0xc5,0xb0,0x6d,0x6b,0xe9,0x7f,0xb8,0x1d,0x1d,0x1d,0xf7,0x37,0x1,0x28,0xb9,0x77,0xd,0x68,0xa1,0xac,0x68,0xa1,0x43,0x61,0x75,0x33,0xc9,0x1d,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x82,0xc,0x0,0x93,0x7f,0xb9,0x2a,0xc2,0x9b,0xef,0x5c,0xbd,0xc6,0xf1,0x77,0xb9,0x52,0x22,0xb6,0xb9,0x96,0x6b,0x8c,0x6f,0xd1,0x6c,0x3f,0xa1,0x44,0xd4,0xe2,0xb,0x3,0xc7,0x56,0xdd,0x94,0x12,0x2c,0x3f,0xdf,0xf2,0x35,0x56,0xec,0xbb,0xa4,0x8,0xe7,0x26,0xde,0x52,0x89,0x28,0x34,0xa,0x44,0xb9,0x16,0x58,0x63,0x90,0x97,0xac,0x25,0x60,0x89,0x63,0x3b,0x24,0xff,0x57,0xd8,0x1c,0xef,0x7,0xfe,0x2c,0x3,0xb4,0x40,0x4a,0xb2,0x85,0x4b,0x5e,0xb5,0xdf,0xd6,0xcf,0x53,0x73,0x6,0x8b,0x58,0x6d,0x59,0xf1,0x67,0x9d,0xd7,0xfc,0x41,0x51,0x51,0x4a,0x5e,0xae,0x94,0x58,0x94,0x26,0x47,0x31,0x21,0x2,0xb0,0x1a,0xa9,0x21,0x17,0x26,0x7a,0x4d,0x6d,0x4e,0x96,0x45,0x51,0xb2,0x98,0xa6,0x55,0x9e,0x9e,0x55,0x55,0x9d,0x5c,0xe8,0xf8,0xfd,0x4d,0xcd,0xe0,0x93,0x7c,0xe4,0x72,0x34,0xaf,0x92,0xf1,0x32,0xe0,0x1c,0xdc,0xb8,0xa8,0x15,0x3a,0x65,0x5a,0x6c,0x2c,0xa2,0x92,0x6c,0xa,0x40,0xa,0xa,0x5b,0x7e,0xb,0x35,0x27,0x9b,0xda,0x10,0x5c,0xca,0xda,0xd5,0x51,0x73,0x82,0x73,0x73,0x5e,0x70,0x34,0x4b,0x43,0xf6,0xe5,0x54,0x89,0x3c,0x69,0x74,0x36,0xb2,0x50,0x7,0x56,0xeb,0x61,0xad,0xbc,0x3b,0xb6,0x38,0x9b,0x56,0xbe,0x27,0x8b,0x82,0x32,0xa6,0x66,0x3d,0x17,0x30,0xad,0x8d,0x9d,0x89,0x3f,0xad,0xfc,0x90,0x6d,0x35,0xed,0xc6,0x2b,0xfb,0xb0,0x66,0x0,0x9a,0x1a,0x41,0xb2,0xe2,0xf9,0x1a,0x25,0x6c,0x27,0xff,0x3a,0x3a,0x3a,0x3a,0x1,0xd8,0xd1,0xd1,0x71,0xff,0xe3,0x28,0x28,0x45,0x5b,0x80,0x65,0x85,0xdf,0xea,0x4,0x3a,0x73,0x26,0x8e,0x35,0x4e,0xb3,0x65,0xda,0x80,0xe9,0x5a,0xf2,0x61,0x75,0x62,0x4b,0xe4,0xdf,0xda,0x2,0x24,0xcf,0x25,0x6b,0x51,0x4,0x4a,0x9d,0x8c,0xc3,0xd6,0xe6,0x60,0xef,0x29,0xa8,0x9c,0x26,0x80,0x46,0x2d,0xb7,0xce,0x19,0x25,0xf9,0x24,0x8c,0x3c,0xa5,0xc4,0xcf,0x97,0xdc,0x9d,0x8,0xef,0x3,0xe7,0x18,0x2d,0x70,0xbc,0xaf,0xb2,0x1f,0xc3,0x66,0x8b,0x9c,0xa2,0x66,0x1c,0xc9,0x8d,0x91,0x4,0x98,0xc7,0x38,0x3,0x5,0x94,0x2f,0x18,0x67,0xb5,0x41,0xe7,0x9c,0x91,0x62,0x64,0x35,0x60,0xc4,0xfe,0xe2,0xc,0xdb,0xd3,0x1b,0xb4,0xd,0x3f,0x0,0x6c,0xc9,0x8d,0x71,0x86,0x5,0x35,0xe0,0xa6,0x18,0xb1,0x39,0xb9,0x86,0x38,0x4f,0xb5,0x79,0x97,0xf7,0x6f,0x7b,0x7a,0x1d,0x0,0x30,0x9f,0xdd,0x41,0x29,0x99,0x14,0x84,0xd6,0xc1,0xb9,0x9,0x76,0x63,0x91,0x1,0x78,0x17,0x88,0x28,0x63,0x35,0x9d,0xf,0x75,0xf2,0x9f,0x67,0xb2,0x15,0x17,0xbd,0x21,0xcc,0xbc,0x9a,0x9f,0x61,0x61,0x50,0x90,0x9a,0xb1,0xab,0x59,0x8e,0xa2,0xec,0x48,0x69,0x51,0x5,0x3,0xe4,0x46,0xcf,0x60,0xd5,0x86,0x98,0x33,0x65,0x28,0x96,0x4c,0x4a,0x49,0xc9,0x80,0x12,0x72,0xd7,0x99,0xa0,0x8a,0x4,0x7,0xaf,0x99,0x4d,0xa6,0xb9,0x91,0x45,0xd3,0xa2,0x68,0x94,0x4,0xa4,0xe3,0x9c,0xb5,0xa9,0xb0,0x69,0xc,0x14,0xbf,0x90,0x9c,0x9a,0xac,0x7e,0x2c,0xce,0x21,0x2d,0x13,0x2b,0x44,0x52,0xff,0xf3,0xed,0xe8,0xe8,0xb8,0x7f,0x49,0x40,0xb4,0x85,0x18,0xe,0x39,0x2f,0x4a,0xa0,0x50,0xfb,0xac,0x5b,0x95,0x7d,0x58,0x6d,0x61,0x2d,0xaa,0xe4,0x27,0x52,0x89,0xae,0xb1,0x42,0xac,0xe9,0x2,0x11,0xab,0xeb,0xe5,0xda,0x29,0xe4,0x8f,0xe1,0x5,0xb6,0xc4,0x25,0x55,0x72,0xbd,0x92,0x45,0x27,0xc9,0xe9,0x25,0xe2,0x51,0x16,0x9f,0x78,0x8f,0xad,0x81,0x31,0x8e,0x17,0xa6,0xdc,0x8a,0x54,0xa4,0x4c,0xb9,0xb0,0x22,0x9f,0xa8,0xc,0xaa,0x79,0x5e,0x43,0x0,0xc9,0xe2,0xa3,0xe5,0x82,0x12,0xb1,0x44,0xb7,0x19,0x7c,0xf2,0xaf,0xe5,0xe2,0x91,0x98,0x22,0x37,0xcf,0x3,0x29,0x46,0x56,0xf6,0x19,0xcd,0xba,0x3,0xc0,0xe4,0x56,0xe2,0xec,0xbc,0xc,0xe4,0xda,0x72,0x5b,0x74,0xac,0x13,0xab,0xed,0x59,0xf9,0x27,0x8a,0x7b,0x63,0xd5,0xfe,0x5a,0x52,0xae,0x24,0x60,0x46,0xa3,0x66,0x87,0x16,0xb2,0x80,0x2d,0xc3,0x32,0x16,0xa6,0x21,0x35,0xc5,0xd5,0x9a,0x53,0x86,0xb5,0x46,0x89,0x47,0xe7,0x87,0x4b,0xa5,0x5b,0x42,0xe,0x66,0x14,0x18,0x29,0x1d,0x49,0x91,0xb7,0x59,0xad,0xd6,0x92,0xdd,0x28,0x79,0x84,0x6,0x85,0xe3,0x4e,0x8c,0x5e,0xb3,0x85,0x30,0x36,0x9c,0xb,0x28,0x73,0x7,0xda,0x8e,0x6d,0xf2,0x23,0x69,0x9f,0x23,0xab,0x4b,0x29,0x69,0xb2,0x69,0x68,0x66,0x5,0x9f,0x6c,0x5b,0x49,0xd8,0xe6,0xf1,0xba,0x5f,0xb6,0xb6,0x37,0x97,0xa2,0x73,0x88,0x7a,0x3e,0xb7,0x39,0x82,0x32,0x3e,0x79,0x55,0xd4,0xd2,0x6e,0x47,0x27,0xa,0x3a,0xd9,0xa8,0x26,0xe0,0xfa,0x16,0xfc,0x3e,0xa6,0x92,0x83,0x2b,0x75,0xe4,0xd1,0x14,0xb8,0xf3,0x7f,0x1d,0x1d,0x1d,0xaf,0x17,0xd8,0x3e,0x4,0x1d,0x1d,0x1d,0xaf,0xe5,0x2d,0x46,0x69,0x56,0x76,0x5b,0x92,0xcc,0xb0,0x1d,0x46,0x26,0xa2,0x92,0x9d,0x53,0xed,0xbe,0x99,0xca,0x33,0x38,0x34,0x5b,0x66,0x50,0x35,0x6b,0x48,0x26,0x86,0x4d,0xa1,0x83,0x64,0xbb,0xf0,0x4d,0x9,0x8a,0x64,0xef,0xa4,0x1a,0xce,0xdd,0x58,0x9a,0x74,0xc2,0xc7,0xe4,0x1f,0x4d,0xa2,0x45,0x5d,0x90,0x9a,0x1b,0x8,0x21,0xaa,0x6,0x0,0x6,0x21,0x8c,0x4a,0xee,0xd,0xe3,0x56,0xdf,0x47,0x54,0x74,0xd2,0x70,0xeb,0xc3,0x80,0x94,0x22,0x13,0x7b,0x8b,0x4e,0x4c,0x73,0xca,0xda,0x2a,0x1c,0x97,0x5,0xcb,0x32,0x21,0x2e,0xb,0x97,0x96,0x90,0x95,0x57,0xda,0x84,0x49,0x8d,0xe1,0x91,0xe2,0x8c,0x99,0x95,0x7c,0xa2,0x42,0x88,0xcb,0xac,0xf9,0x76,0xd6,0x79,0x6c,0xd9,0xd6,0xeb,0x7c,0x40,0x18,0x37,0xfa,0x7b,0xe7,0x3d,0x96,0x69,0xa2,0xc9,0x2b,0xdf,0xe8,0xc4,0x58,0x57,0xeb,0x65,0x75,0x5a,0xc6,0xde,0xb3,0x2,0x40,0x72,0xb,0x4d,0x5b,0x14,0xd2,0x34,0x33,0x1a,0x2b,0x8f,0x43,0x6f,0xc,0x57,0x36,0x32,0xb6,0x69,0x51,0x46,0x9f,0xd5,0x36,0x60,0x6d,0x80,0x6e,0x6e,0x62,0xc8,0x4e,0xcd,0xc7,0xbd,0x54,0x75,0x64,0x18,0x6,0xcd,0xff,0xb3,0x6c,0xc1,0xd6,0x52,0x18,0xbe,0x91,0x6c,0xc3,0xd3,0xb3,0xbc,0x5e,0x94,0x8,0x85,0xf3,0xa,0x99,0xfc,0xbb,0x1c,0xfc,0x6d,0x78,0x7c,0xe9,0x3c,0xb3,0xe1,0xa4,0x93,0x7f,0x1d,0x1d,0x1d,0x6f,0x84,0xcb,0xb3,0x22,0xaf,0xbe,0x1f,0xe5,0x7b,0x99,0x8,0xb9,0x9c,0x53,0xfd,0x5e,0x5,0x2d,0x66,0xc9,0xa2,0x8c,0x92,0x66,0x4c,0xfa,0x58,0x5d,0xc,0x23,0x22,0x8b,0xe2,0x23,0x92,0xe6,0xf3,0x59,0xdf,0x34,0xb6,0x73,0xb1,0xc5,0x30,0x6e,0x74,0xa1,0x46,0xfe,0xcf,0x5a,0xa7,0x5,0x13,0x42,0xf0,0x18,0x5e,0xb8,0x93,0x9f,0xf5,0x1a,0xc3,0xa,0x71,0x51,0x72,0x9,0xa1,0x25,0x8b,0x3e,0x5a,0x54,0x62,0x49,0x91,0x6f,0x9a,0xfc,0x3f,0xe7,0x3c,0x59,0x77,0x1b,0xe2,0x4f,0xf7,0x8d,0x2d,0xcf,0xce,0x7,0xcd,0x7f,0xf3,0x5c,0x64,0x42,0xf3,0x7,0x22,0x9c,0x1c,0xab,0x12,0x65,0xbf,0x4b,0xe3,0x5e,0x10,0x75,0x23,0x91,0x73,0x4e,0x55,0xf2,0xd2,0xd6,0x2b,0xb,0x5a,0x49,0xc8,0xb8,0xb6,0x84,0xc5,0x92,0xf3,0xa0,0x68,0x49,0x86,0xa9,0xd7,0xce,0x66,0x11,0xcb,0x31,0x51,0xab,0xa3,0x27,0x8f,0xf3,0x62,0xa0,0xb5,0x96,0x16,0xb5,0xd8,0xe,0x4d,0x71,0x20,0x89,0x9,0x33,0xaf,0xad,0xca,0xe2,0xc4,0x48,0x91,0x54,0xf7,0x3e,0xc,0x44,0xe2,0x2a,0xd1,0x4b,0x73,0x4,0xef,0x79,0xd1,0xd0,0x1a,0x9d,0x37,0x19,0xce,0xe1,0x75,0x9c,0x2b,0x5c,0xcf,0x23,0xa7,0xd9,0x85,0x42,0x10,0xca,0x71,0xcd,0x3c,0xf7,0x13,0x42,0xd5,0xb4,0xea,0x3a,0x43,0x73,0x2,0xe7,0x7c,0xa3,0x42,0xf5,0x47,0xc7,0x17,0xd5,0x5e,0xcd,0xd,0xc0,0x39,0x25,0x5e,0xd8,0xc5,0xaa,0xe0,0xa4,0xaa,0x1d,0xcb,0xd5,0x44,0xb8,0x28,0x23,0x9b,0x5,0x43,0x70,0xfb,0x75,0x4d,0xff,0x43,0x9d,0x3b,0x5c,0x55,0xb,0xac,0x73,0xd0,0xa3,0x29,0x86,0x4c,0x54,0x4d,0xff,0xca,0xe9,0xe8,0xe8,0xe8,0x4,0x60,0x47,0x47,0xc7,0x7d,0x8e,0xe3,0xd5,0x56,0x9,0xbc,0x6e,0x67,0x4e,0x6d,0x2b,0x9c,0x34,0xf,0xca,0x6b,0x57,0x19,0x3c,0xd6,0x35,0x13,0xb8,0x3a,0xc9,0xad,0xa1,0xe4,0x46,0xc3,0xad,0x45,0x4d,0x57,0x4a,0x63,0x3b,0x29,0x99,0xf3,0x6b,0x8a,0xda,0x70,0xd6,0xfb,0x83,0xa6,0xfd,0xe,0xab,0xf0,0x6a,0xc7,0xd9,0x81,0x39,0xb1,0xbd,0x88,0xc9,0x29,0xa,0x31,0xb7,0x1a,0x56,0x9d,0x52,0xc2,0xb2,0x4c,0xba,0x97,0xd4,0x5a,0x18,0x34,0x73,0x30,0x25,0x52,0xf7,0xc5,0x65,0x52,0x2,0x52,0x56,0x99,0x97,0x65,0xc2,0x7c,0xd8,0x61,0x9e,0xe,0x30,0xc6,0x60,0x9e,0xe,0x38,0xec,0x2e,0xb0,0x3b,0xbf,0x8b,0xfd,0xc5,0x19,0x8c,0x75,0x74,0x33,0x95,0xd2,0x6a,0xc5,0xdd,0x87,0x1,0x33,0xab,0xff,0xa6,0xc3,0x5e,0x27,0xd8,0xa4,0xf4,0xf3,0xf0,0x61,0x44,0xe6,0x6c,0xc2,0xe9,0xb0,0xc7,0x3c,0x1d,0x94,0x90,0x34,0xc6,0x60,0x9e,0x27,0xc0,0x80,0xda,0x79,0x99,0xe8,0x13,0xb2,0xd3,0xf0,0xd,0xdd,0xa5,0x20,0x6e,0xb6,0xf0,0xa4,0x18,0xf9,0x26,0xae,0x5a,0x67,0x54,0x71,0xc7,0x6a,0x85,0x72,0x69,0x8c,0xb3,0x66,0x17,0xe2,0xa8,0xad,0xcf,0xf9,0xc0,0xa,0x85,0x20,0x1,0x42,0xb4,0x2d,0xce,0x97,0x12,0xcb,0x91,0xa8,0xc,0x51,0xa0,0x44,0xec,0x2a,0x23,0x52,0x72,0x7,0x1b,0xc2,0xf8,0x38,0xfb,0xaf,0x35,0x0,0xe7,0x94,0x48,0xf1,0x19,0x6,0x94,0x1c,0xfb,0x1f,0x6e,0x47,0x47,0xc7,0x7d,0x7f,0x6d,0x96,0xeb,0xe2,0xea,0xa6,0x80,0x63,0x24,0xf2,0xaa,0x70,0xc2,0x28,0xe1,0x77,0x1c,0xd3,0x21,0xd7,0x1a,0xb5,0xa8,0x1a,0x20,0xc,0xa3,0x7e,0x8f,0x4b,0xbe,0xda,0x30,0x6e,0xe0,0x98,0xd0,0x11,0x25,0x78,0x8d,0x9d,0xa8,0x25,0x21,0xf2,0xdd,0x6f,0x2d,0x2d,0x64,0x49,0x26,0xac,0x6c,0x33,0x2e,0x33,0x34,0x6f,0x96,0xf3,0x6f,0x51,0xa,0xac,0xa7,0xf9,0x41,0x18,0x6,0x25,0xa5,0x9c,0x73,0x4a,0x70,0x49,0x7e,0xaf,0x10,0x49,0xb2,0x2d,0x21,0xc1,0xe8,0x77,0xa6,0x21,0xdb,0xc0,0x96,0x56,0x9d,0x90,0xac,0xf8,0x1b,0x6b,0x2d,0x7c,0x18,0x9b,0xa9,0x4c,0xa3,0x8e,0x64,0x3b,0x72,0x5b,0x88,0xd1,0x92,0x7b,0x0,0x94,0x14,0x93,0xec,0x5a,0x27,0x2a,0x4b,0x1e,0x4b,0x51,0x4b,0x82,0xc9,0x28,0x1f,0x6,0x55,0xbf,0xc9,0xbc,0x47,0x54,0x75,0xba,0xd,0x26,0x6c,0x85,0x6c,0x84,0x81,0x92,0x6b,0x85,0xe3,0x42,0x84,0x7c,0xb5,0xd6,0x68,0xa3,0x72,0x1,0x74,0x5f,0xe9,0x77,0x96,0x1c,0x5,0xb9,0x96,0xc4,0xc8,0x62,0xad,0x5e,0x3b,0x4b,0x86,0x13,0xf5,0x27,0xff,0x2b,0xc4,0x1b,0xcd,0xcf,0xec,0xca,0xfa,0xab,0x8b,0x99,0x32,0x8f,0x6b,0x14,0x74,0x6,0x6b,0xc2,0x50,0x8e,0x93,0xcc,0x45,0x84,0xf0,0x4c,0x62,0x31,0x86,0x69,0x88,0x3a,0xb1,0xf0,0x66,0x65,0xdc,0x84,0xc8,0x84,0x2a,0x56,0x73,0x43,0xee,0xd9,0xc6,0x95,0xc0,0xfb,0xd9,0x94,0xd2,0x99,0xc6,0xde,0x6c,0x80,0xe6,0xef,0xc3,0x54,0x11,0x60,0xab,0xf4,0x6b,0xb9,0x41,0x63,0x8e,0x58,0xbf,0x52,0x65,0x80,0xea,0x7e,0xe9,0xe8,0xe8,0xe8,0xe8,0x4,0x60,0x47,0x47,0xc7,0x1b,0xe3,0x6e,0x83,0x27,0x63,0x75,0xa2,0xa4,0x19,0x32,0xe5,0x72,0x16,0x4d,0x9d,0x25,0x17,0x25,0xe4,0x54,0xa1,0xa0,0x64,0x21,0x4d,0x4e,0x25,0xe4,0x5a,0x6d,0x3f,0x47,0xc4,0x61,0x66,0x82,0x28,0xa7,0x4,0x6b,0xc8,0x96,0x54,0xb8,0xda,0x4f,0xc8,0xa4,0x76,0x52,0x2a,0xd,0xc0,0x35,0x57,0xae,0x99,0x0,0x8a,0x32,0xa2,0x21,0x97,0x96,0x79,0xa2,0x55,0xe8,0xc6,0xca,0x23,0xab,0xf4,0x71,0x99,0xd9,0x9a,0x5b,0xb0,0x4c,0x53,0x55,0x1e,0xb8,0xda,0x9e,0x98,0x13,0x2b,0xe1,0x38,0xdf,0x26,0x2e,0x33,0x97,0x6a,0x40,0x73,0x7a,0xe2,0xb2,0x60,0x9e,0xf6,0xaa,0xc2,0xb,0x61,0x50,0xc5,0x5e,0x5c,0x44,0xa9,0x67,0x11,0x86,0x91,0x33,0xb,0x29,0x4c,0xdb,0x58,0x4b,0xa,0x3a,0xef,0x31,0x4f,0x7,0x6a,0xff,0x8d,0x8b,0xaa,0x0,0x25,0x6f,0xa8,0x36,0x20,0xe2,0x12,0x69,0x47,0x2a,0x42,0x5a,0xa9,0x27,0xd5,0x40,0xae,0xc7,0x54,0x54,0x83,0x3c,0xf7,0x35,0xd6,0x22,0x2d,0x8b,0xda,0xa2,0x64,0x52,0xaf,0x37,0x46,0xb6,0xaa,0x3,0x8a,0x58,0xc2,0x51,0x5b,0x9d,0xf5,0x46,0x46,0xb,0x63,0xf8,0xc6,0xa,0x6b,0xdb,0x70,0x93,0x8,0xde,0x90,0xcb,0xa8,0x84,0xb0,0x46,0x1,0x19,0xae,0x9b,0x29,0x7a,0xb3,0x85,0xe3,0xa6,0x40,0x39,0x29,0x39,0xc4,0xdd,0xd8,0x5e,0x2,0xd2,0xd1,0xd1,0x71,0x9f,0x4f,0xfe,0xf9,0x5a,0xa4,0xea,0xa7,0x23,0xe2,0xc2,0x60,0xbd,0x68,0x22,0xc4,0x94,0x13,0xab,0xa9,0x94,0x25,0x30,0x69,0x12,0x86,0x71,0x95,0xe7,0x1b,0x86,0x51,0x15,0x62,0x61,0xd8,0xac,0xec,0x99,0x42,0xf0,0x15,0x59,0x88,0x43,0x6d,0x17,0x2e,0x5c,0x80,0x41,0xb9,0x73,0xb9,0x12,0x5e,0x86,0x8,0x2b,0xeb,0x3c,0xc5,0x61,0xa8,0x22,0xdc,0xf0,0x75,0x6e,0x3,0xc7,0xca,0x32,0x21,0x1b,0xa5,0xf4,0x4b,0x16,0x8c,0x3c,0xab,0xf,0xd1,0x14,0xa0,0x50,0xfe,0x6e,0x2d,0xca,0x70,0xde,0x57,0xc5,0xa0,0xb1,0xcc,0xdf,0x14,0x6d,0x9c,0x77,0x3e,0x54,0x1b,0x2a,0x13,0x52,0x52,0x26,0x22,0xfb,0x2a,0x4a,0x41,0x99,0x47,0xf8,0x30,0xc0,0x58,0xb3,0x5a,0xac,0xd2,0xec,0xba,0x26,0x17,0x57,0xc6,0x56,0x8f,0x8b,0x28,0xef,0x39,0xd7,0x58,0xae,0x73,0xa2,0x68,0x93,0xc5,0x39,0x21,0xc5,0xac,0xb1,0x3a,0x6,0xa4,0x68,0x2b,0x48,0x31,0xd1,0x76,0xd,0xc8,0x85,0xc0,0xe3,0xd8,0xba,0x21,0x84,0x9c,0x92,0x31,0x10,0x22,0xb8,0x0,0x55,0xc5,0xef,0xa9,0x14,0x8d,0x4a,0xd3,0xa,0x11,0x7a,0xc6,0xc0,0xd8,0x5a,0x38,0x42,0xe,0x9,0xc0,0x79,0xb7,0x22,0x2b,0x8b,0x64,0x4b,0xf2,0xa2,0x9e,0x96,0x9c,0xf0,0xb1,0x93,0xcf,0xd2,0xda,0x7d,0xc5,0x3a,0x2e,0x9f,0x91,0x16,0x5d,0x5d,0x3d,0xef,0x74,0x2a,0x69,0x57,0x44,0xa9,0xb8,0x1a,0xc,0x93,0x92,0x3a,0xdf,0x68,0xc6,0x55,0xb2,0x1c,0xdb,0x1c,0x60,0x9d,0xd3,0x94,0x86,0x20,0xd7,0x1c,0x40,0x68,0x74,0x4d,0x9d,0xfb,0xb4,0xc4,0x1f,0xd6,0x8f,0x9b,0x35,0x7,0xa8,0x6f,0x6b,0xba,0x4,0xb0,0xa3,0xa3,0xa3,0x13,0x80,0x1d,0x1d,0x1d,0xf7,0x39,0xcc,0x3a,0x6d,0xb9,0xce,0x98,0x9a,0x49,0x96,0x61,0xf6,0xc8,0x36,0x4a,0x3e,0x5d,0x81,0xb5,0x75,0xc2,0x27,0x96,0x51,0x1c,0xb7,0xbc,0x32,0xb9,0x57,0x38,0x3f,0xa8,0x55,0xab,0xc9,0x4a,0xbc,0x28,0xf1,0x34,0xe4,0x5c,0xa,0x43,0xa,0xdd,0x70,0x8,0x99,0x27,0x6d,0x7b,0x6a,0xfd,0x60,0xcb,0x4b,0x41,0x55,0xac,0x11,0xe1,0x48,0x56,0x9e,0xb8,0xcc,0x3a,0xa1,0x95,0x55,0xfb,0xa4,0xf6,0xd7,0xc,0xc3,0x4d,0xc0,0xd6,0x39,0xf8,0x61,0x64,0xeb,0xd0,0xc2,0x37,0x5c,0x19,0xcb,0x7c,0x50,0x22,0x53,0x8a,0x29,0xa8,0x14,0x64,0xc1,0x61,0x77,0x8e,0x79,0xda,0x63,0x3a,0xec,0x31,0xed,0x2f,0x38,0x6f,0x88,0xd4,0x7f,0xd3,0x61,0xa7,0x39,0x87,0xd6,0x39,0x2c,0xcb,0x8c,0x9c,0xa2,0x16,0x88,0xa4,0x94,0xa8,0xb5,0xcf,0x58,0x4c,0xfb,0x1d,0x60,0xc,0x4e,0x6f,0x3c,0x0,0x1f,0x6,0x8c,0x9b,0x13,0xc4,0x65,0xa9,0xd,0x8b,0xa2,0x90,0x6b,0x94,0x98,0x7a,0x83,0xd2,0x64,0x2b,0x51,0x3e,0xa2,0x5b,0xcd,0x7b,0x65,0xa6,0x9b,0xb9,0xc5,0x39,0xc5,0xc8,0xa1,0xe5,0x95,0xf4,0x13,0x55,0x65,0xce,0x9,0x39,0xc5,0x9a,0x3b,0x24,0x8f,0xf1,0xcf,0x62,0x5d,0x92,0x9b,0x29,0xa3,0x2d,0xce,0x68,0x1a,0x3,0x8b,0xaa,0x29,0x4b,0x9b,0xf3,0xd4,0x46,0xf6,0xf0,0xbe,0x28,0xe9,0x27,0x56,0x60,0xd3,0x64,0x40,0x59,0x73,0x49,0x89,0x9a,0x23,0x29,0x4b,0x72,0xec,0x25,0x20,0x1d,0x1d,0x1d,0xf7,0x37,0x8a,0xea,0x9f,0x9b,0x76,0x74,0x40,0xed,0xba,0xf2,0xdf,0xf2,0xf5,0xda,0x5e,0x2b,0x84,0x20,0x94,0x62,0xd,0x59,0x74,0x21,0xbb,0xa6,0xab,0x24,0x99,0x90,0x38,0xac,0x94,0x17,0xd5,0x9d,0x44,0x48,0x88,0x5a,0xf,0xa0,0xd7,0xe6,0x52,0xd8,0x22,0xec,0xd8,0x9a,0x9b,0x56,0x16,0x4e,0x51,0xcd,0x67,0x2e,0xc7,0xca,0x9c,0x2f,0x17,0xc2,0x40,0x2d,0xc0,0x81,0xac,0xc0,0x0,0x11,0x40,0x9a,0xd5,0xeb,0x1c,0xbc,0x1f,0xc8,0xce,0xcb,0x24,0x92,0x10,0x4f,0x61,0xd8,0x68,0x26,0x30,0x11,0x60,0x6e,0x25,0xd4,0xd2,0xa6,0x5f,0x26,0xa7,0x12,0x67,0x8,0x5b,0x29,0xa1,0x62,0xd5,0x5a,0x55,0x4a,0xd2,0x2,0x5d,0x4a,0x89,0x3f,0xab,0xd3,0x48,0xc,0x1f,0xc6,0xda,0x5c,0xcf,0xaf,0x6d,0xe3,0x2b,0x12,0x3b,0xc,0x48,0xb1,0x48,0x73,0xc,0xcf,0xf6,0x66,0xd9,0x2f,0x89,0xbd,0x80,0xcc,0x35,0x4c,0x6d,0xd8,0x2d,0xcd,0xb1,0xaa,0xb,0x9c,0x9c,0x81,0xd8,0x14,0x73,0x88,0x95,0xb7,0x8d,0xff,0x90,0xb2,0x15,0xf9,0x6c,0x52,0x4,0x46,0x76,0x5f,0xb6,0x7b,0xf3,0xf5,0xd7,0x28,0x1,0x9a,0x78,0x5a,0x64,0xeb,0xb8,0x1b,0x69,0x7f,0x36,0x9a,0x65,0xd8,0x66,0x2a,0xa6,0xb8,0xa8,0xd2,0xdf,0xb2,0x4d,0x5c,0xb3,0x18,0x99,0xb4,0x73,0xde,0xaf,0x2c,0xc2,0x12,0xc3,0x22,0xce,0xf,0x51,0x9d,0x4a,0x64,0x4b,0x6d,0x38,0x66,0xb5,0x1f,0x47,0x9d,0xc8,0xfe,0xc8,0xb1,0x11,0x22,0x58,0xcf,0x2b,0x7d,0x5d,0xb3,0x8f,0x52,0x36,0x22,0x8b,0x8a,0x6d,0x79,0x87,0x2c,0x22,0xca,0xf3,0xdb,0x62,0x9b,0xf5,0x1f,0xd7,0xea,0x3f,0x8d,0x92,0x8b,0x5d,0x1,0xd8,0xd1,0xd1,0xf1,0xfa,0x40,0x2f,0x1,0xe9,0xe8,0xe8,0x78,0xed,0x6e,0x32,0x4a,0x39,0x9e,0xf,0x1d,0x33,0x84,0x8d,0x75,0xb4,0x5c,0x9a,0x3d,0xd5,0xb6,0x56,0xe,0xd6,0x4e,0x49,0x9f,0xdf,0x92,0x8c,0x32,0xa9,0x75,0xce,0x21,0xc7,0x48,0xc4,0x1b,0x93,0x59,0x32,0x19,0x16,0xcb,0x6b,0xab,0x10,0x6c,0x73,0xe1,0x64,0x22,0x2b,0x13,0x46,0xdd,0x96,0xa9,0xcd,0x7d,0xd6,0x3a,0x25,0x19,0x25,0x8,0x5b,0x26,0x86,0x34,0xd7,0xa5,0xed,0xf8,0x30,0x20,0xe7,0x2,0x5b,0x68,0x12,0x2a,0x99,0x80,0xa2,0x5e,0x2b,0x8e,0x48,0xb3,0x30,0x50,0x4e,0x9f,0x75,0x5e,0x33,0x6c,0x62,0x5c,0x30,0x8c,0x1b,0x2c,0xac,0x1c,0xdc,0xef,0xce,0xa8,0xbd,0x77,0x77,0x4e,0x4d,0xbe,0x27,0xd7,0x90,0x62,0xd4,0xb6,0x62,0x29,0x35,0x11,0x35,0x82,0x58,0x90,0x51,0xa,0xf6,0x17,0xe7,0xb4,0xfd,0x79,0xae,0x36,0x1c,0x0,0x9b,0x93,0x6b,0x4d,0xee,0x5f,0x62,0x2b,0x56,0x68,0xc8,0x38,0xc0,0xb8,0xda,0x38,0xd8,0x5a,0x8d,0x64,0x72,0x2c,0x79,0x85,0xd4,0xea,0x6c,0xd6,0x64,0x9c,0x58,0x70,0x8a,0xd8,0x6c,0x50,0x1b,0x83,0x65,0xa5,0xff,0x28,0x3b,0x47,0x94,0x84,0x72,0xdc,0xa4,0x48,0x44,0x6d,0x39,0x4c,0xec,0x55,0xbb,0xcf,0x9a,0xc8,0x2b,0x8d,0xbd,0x4a,0x1f,0x2f,0x40,0x41,0x56,0xab,0x8e,0x28,0x9,0x74,0xe5,0xbf,0x21,0x7d,0x4b,0x4a,0xf0,0xdb,0x6b,0x48,0xcb,0x9d,0xfe,0x87,0xdb,0xd1,0xd1,0x71,0x7f,0x5f,0x9b,0xc5,0xea,0x5a,0x9a,0xef,0x5c,0x21,0x73,0x7c,0x6d,0x58,0x3d,0x26,0x4a,0x84,0x8c,0x11,0x55,0x15,0xd9,0x48,0x79,0x1,0xc7,0x1a,0x8d,0xbc,0x30,0xc6,0xe1,0x3d,0x4f,0x3c,0x86,0xc7,0x6e,0xdd,0x6c,0x4a,0x11,0xe8,0x7d,0x9f,0x79,0xee,0x45,0x7c,0xe1,0x6b,0x7f,0xe,0xeb,0x1d,0xb2,0x49,0x9a,0xed,0x16,0xc2,0x80,0x65,0x9e,0xf4,0x7a,0x4f,0x25,0x59,0x8b,0xfe,0x5e,0x8,0x47,0xb1,0x75,0x4a,0xe3,0xb0,0x92,0x99,0x39,0xe3,0xe4,0x64,0x8b,0xf,0xbd,0xf7,0x9,0x78,0xef,0x39,0x3f,0x8f,0x9e,0xbf,0xc4,0x88,0x3f,0xf8,0xcc,0x97,0x91,0xa,0x90,0xa6,0x58,0x89,0x2a,0x14,0x38,0x17,0x34,0x56,0xc3,0x58,0x8b,0xc2,0xc4,0xa1,0x28,0xf6,0x54,0x45,0x8,0xb0,0x4a,0x8d,0xc8,0x1f,0x6b,0x4c,0x93,0x59,0x5c,0xf4,0x35,0xf2,0x5e,0x9a,0x8b,0xab,0x73,0x97,0xa4,0x4,0x94,0x75,0xe,0x90,0xec,0x3e,0x89,0xcc,0xb0,0x96,0x88,0x43,0xe7,0x74,0x91,0x8e,0x16,0xc4,0x1c,0x5f,0x3b,0xad,0x96,0xa8,0x14,0x25,0x33,0x1d,0x9c,0x37,0x7a,0x3d,0x96,0x85,0x4a,0x6a,0xf3,0xd,0x6a,0x9b,0x2d,0x39,0xf1,0xe2,0x62,0x64,0x2b,0xae,0x55,0xd2,0x6f,0x35,0x8f,0xe1,0x79,0x99,0xc4,0x7b,0xc4,0x65,0xae,0xea,0x4e,0x54,0xeb,0x2b,0x2d,0xaa,0x7a,0xce,0x34,0xa6,0x7d,0xa6,0xeb,0xa9,0xd5,0x6c,0x60,0x69,0x26,0x96,0x6b,0xad,0xe4,0xf9,0x49,0x59,0x4c,0x56,0x45,0xa3,0x51,0xc5,0xa1,0xaa,0x51,0x39,0xbb,0x11,0xc6,0x22,0xc5,0xa4,0x96,0xf3,0xb6,0x30,0x4d,0x8e,0x57,0x66,0xb2,0xb5,0x34,0xc7,0xc2,0x38,0x87,0x92,0x62,0xb5,0x2d,0xf3,0x38,0xe7,0x66,0x4e,0xaa,0xa5,0xbd,0x4d,0xee,0xa0,0xd8,0x7e,0x69,0x7c,0xa0,0xd9,0x8a,0x32,0x2e,0x39,0x73,0x4b,0xb0,0xba,0x40,0xac,0xfe,0xac,0x73,0xd2,0x63,0x9,0x20,0xff,0x5b,0xb,0x47,0x3a,0x3a,0x3a,0x3a,0x3a,0x1,0xd8,0xd1,0xd1,0x71,0x9f,0x42,0xb2,0x7b,0xae,0xe0,0xfd,0x56,0x16,0xd0,0x96,0xc4,0x59,0x67,0x2,0x42,0x27,0xaa,0xd2,0xea,0x76,0xac,0xdc,0x82,0x12,0x77,0x50,0x3b,0x30,0x91,0x7e,0xb6,0x4e,0xbf,0x74,0xc2,0x4b,0x8f,0x90,0x2,0xa1,0xe6,0x1f,0xd5,0x1b,0x1a,0x6a,0xb7,0xa5,0x9,0xba,0x47,0x29,0x89,0x27,0xfc,0x4d,0x31,0x49,0x29,0x80,0xac,0x2e,0xa3,0x2a,0x4,0x8c,0x4c,0x8,0xa5,0xed,0x2f,0x27,0xc4,0x9c,0xe1,0xc2,0xa0,0xf6,0x5e,0x1a,0x93,0x4,0x63,0x23,0xdb,0x87,0xf,0xdc,0x4e,0x9c,0x91,0xb9,0xe8,0xc4,0x87,0xa1,0xb6,0x20,0x97,0x82,0x79,0xda,0x3,0x5,0x38,0xbd,0xfe,0x0,0xe,0xbb,0xb,0xcd,0xea,0x13,0xdb,0xd5,0xb2,0xcc,0x9c,0x91,0xe7,0x30,0x1d,0xce,0x61,0x2d,0xb5,0x4,0x67,0xe,0x29,0x2f,0xa5,0xc0,0x87,0x81,0x6e,0xb0,0x6,0xca,0x2c,0x5a,0xe6,0x3,0xfd,0x77,0x29,0xb0,0x4e,0x5a,0x13,0xd7,0xb9,0x43,0x79,0xa9,0x37,0x31,0xb4,0xea,0xdd,0x4,0x74,0x2b,0x99,0x6,0x6d,0x3a,0x14,0xf5,0x80,0x90,0xae,0x56,0xb2,0x75,0x9a,0xb6,0x46,0x9,0x12,0x2f,0x4d,0xe0,0x3b,0x4c,0xcd,0xd,0x5c,0xd9,0xad,0xd5,0x96,0x56,0x50,0x84,0xc0,0xb3,0x46,0xdb,0x7d,0xe5,0x26,0xa4,0xcd,0x1a,0x52,0xc2,0xf,0x6d,0x46,0x4f,0x51,0x35,0x4,0x56,0xb7,0x8b,0xa6,0x69,0xa4,0x4e,0x30,0xce,0x21,0xcd,0x13,0x4a,0xea,0xa,0xc0,0x8e,0x8e,0x8e,0xfb,0x1d,0x66,0xad,0xb2,0xe6,0xab,0x99,0x16,0x72,0x19,0xa8,0xd2,0x4b,0x22,0x1b,0x6a,0xe6,0x9a,0x14,0x5d,0x40,0xaf,0x59,0x86,0x8b,0x9c,0x52,0x5c,0xc8,0x7a,0xeb,0x3c,0xfe,0xea,0xcf,0x3c,0x85,0xa7,0x3e,0xf8,0xbe,0x4b,0x5b,0xfe,0xd8,0x27,0x3e,0x89,0xaf,0xfe,0xc5,0x4b,0x28,0x39,0x23,0xc,0x23,0xe6,0xe9,0xa0,0x96,0xd1,0x30,0x6e,0x48,0x25,0xf,0x22,0xef,0x5a,0xe5,0x5b,0x59,0x15,0x73,0x39,0x2d,0x21,0x91,0xc2,0x2d,0xe7,0x3c,0x1e,0xbd,0xf9,0x0,0xfe,0xf3,0xff,0xf4,0x6f,0xc1,0xbb,0xb5,0xc1,0xe9,0x70,0x98,0xf0,0x85,0xa7,0xff,0x67,0xbc,0xf8,0xf2,0xab,0x1a,0xc1,0x61,0xbc,0xe1,0x1c,0x43,0xcb,0x11,0x1d,0x74,0x9d,0x93,0xac,0x43,0x52,0xa2,0x53,0x3e,0x61,0x5d,0xf0,0xe3,0x6b,0xaa,0xb,0x14,0xff,0xc1,0xea,0x3a,0xe7,0x5c,0x53,0x1c,0x46,0x90,0x26,0x5c,0x21,0x35,0x69,0x9e,0x0,0x58,0x67,0x35,0x7a,0xc3,0xb2,0xd2,0xcd,0x58,0xb,0xcb,0xa,0xc9,0x4a,0x3c,0x3a,0xe4,0x66,0xa6,0x93,0xb3,0xcc,0x4b,0xa,0x37,0x2f,0x7,0x52,0xd4,0x39,0xa7,0x11,0x1c,0xba,0x10,0x9a,0x33,0x93,0x64,0xa2,0x88,0xb4,0x6a,0xe9,0xb5,0x8e,0xae,0xc3,0x16,0x46,0x55,0x7d,0xd6,0x7a,0xc0,0x14,0x9d,0x6b,0x51,0x79,0x4b,0x25,0x59,0x89,0x94,0xa5,0x82,0x33,0xcb,0x84,0x5d,0x3b,0x46,0xa5,0x55,0xb8,0x19,0x3,0x1f,0x2,0x39,0x1e,0x72,0xe2,0x16,0x68,0xb6,0x7a,0x1b,0xa3,0xef,0x2d,0xfb,0x25,0xf3,0x3a,0x6b,0xea,0xf9,0x68,0xf8,0x18,0x49,0xde,0xb0,0xa8,0xf1,0xac,0xf3,0x9a,0x51,0x2c,0xdb,0xc,0x61,0x40,0x8c,0xb,0x64,0xb1,0x51,0x16,0x31,0x57,0xb6,0x62,0xdb,0x58,0x9e,0xdb,0x96,0x67,0xcd,0x7,0xae,0x8b,0x82,0x6,0xe2,0x80,0x38,0x22,0xeb,0x4a,0x55,0xcd,0x9a,0xd6,0xe,0x2c,0xc4,0xe1,0xf1,0xe2,0x35,0x9f,0xab,0xcd,0x54,0xb7,0xa3,0xa3,0xa3,0xa3,0x13,0x80,0x1d,0x1d,0x1d,0xf7,0x37,0x6e,0xbf,0xf4,0x4d,0x9c,0x9c,0xde,0xa0,0x36,0xba,0x5c,0x43,0xa4,0xd7,0x21,0xce,0xed,0xdc,0xaa,0x54,0xd2,0x89,0x6d,0xa8,0x89,0x9,0x43,0xc9,0x95,0x33,0x4d,0xd0,0x72,0x1b,0x32,0xdd,0x2a,0xd5,0xd0,0xda,0x49,0x8f,0xec,0xc2,0xd6,0x5a,0x44,0xd9,0x16,0x5b,0x7e,0x96,0x79,0xae,0xa4,0x14,0xaf,0xf2,0xda,0x9c,0xd4,0xba,0x63,0x2d,0x4d,0x1a,0x63,0xa4,0x55,0xfe,0x65,0x9e,0x75,0xfb,0xde,0x57,0xf5,0x80,0x73,0x1e,0xa9,0xc9,0xb1,0xb,0x61,0xc4,0x74,0xd8,0x31,0x39,0xc6,0xa,0x8,0xc9,0xe7,0x63,0x12,0x4b,0x48,0x4b,0xef,0x29,0x3f,0x27,0xc5,0xc8,0x59,0x74,0xd4,0xdc,0x37,0x8c,0x5b,0x1c,0x76,0xe7,0x88,0x71,0xc1,0xe6,0xe4,0x14,0x76,0x3a,0x68,0xeb,0xef,0xc5,0xd9,0x6d,0x58,0xeb,0x10,0x86,0x11,0xfb,0xdd,0xf9,0x6a,0x4c,0x64,0x12,0x1f,0x97,0x19,0x3e,0xc,0xdc,0xfc,0x17,0xb1,0xd9,0x9e,0x72,0x3b,0x71,0x2,0x96,0x19,0x31,0x2e,0xd5,0xf6,0xd4,0x4e,0x78,0xc5,0xa6,0xd4,0xe4,0xf9,0xb5,0xaa,0x6,0x51,0x2e,0xc8,0x94,0x58,0x56,0xb7,0xd5,0xae,0x55,0xa2,0x12,0xb9,0x26,0x92,0xda,0xc2,0x79,0x4f,0x36,0xae,0x36,0xc7,0xa7,0xc8,0x84,0x1a,0xdc,0xdc,0xdb,0xac,0x98,0xf3,0xcd,0x91,0xdc,0xc,0x21,0x4a,0xc8,0x79,0x7d,0x7d,0xbb,0xda,0x2e,0xea,0x3e,0x1a,0xdb,0x56,0x29,0x68,0xeb,0x3e,0x5b,0x3a,0x4f,0x52,0xa2,0x4c,0xc3,0xdd,0xf9,0x5d,0x9c,0x9f,0x9d,0x21,0x6c,0x4e,0x71,0xb8,0xfb,0xa,0x72,0x9a,0xfa,0x1f,0x6e,0x47,0x47,0xc7,0x7d,0x8d,0x75,0x96,0x2b,0x54,0x2d,0x27,0xb,0x4f,0xb9,0x64,0xb2,0xd6,0xf2,0xf5,0xcc,0x39,0xaf,0x4c,0x14,0x5d,0xb3,0x38,0x83,0xcf,0x9a,0xe6,0xba,0x90,0x6b,0xf9,0x46,0x93,0xc5,0x7a,0xc,0xeb,0x3c,0x91,0x3d,0xde,0x57,0x25,0x59,0x4e,0x48,0xcb,0xa2,0x96,0x5d,0x2d,0x86,0xd0,0x96,0x61,0xdb,0xe4,0xec,0xd5,0x82,0x29,0x29,0xf2,0x10,0x82,0xc,0x4c,0x4e,0xe2,0x88,0x0,0x2c,0x28,0xf0,0xde,0xd3,0xb5,0x2f,0x46,0x58,0x67,0x31,0xcf,0x13,0xac,0xb1,0x88,0xcb,0x82,0x94,0x22,0x1c,0x1c,0x13,0x65,0x45,0xc9,0xbe,0x9c,0x32,0xe0,0xa0,0x16,0x64,0x9d,0x23,0x94,0x8c,0x71,0x7b,0xc2,0x6a,0x7c,0xca,0x8e,0x2d,0x29,0xa9,0x75,0x59,0x2d,0xb2,0xa6,0x68,0x36,0x5e,0x3b,0xee,0x39,0x27,0x55,0xd0,0xd,0xe3,0x48,0x73,0xa,0xb6,0x46,0x6b,0xd3,0x2e,0x3f,0x37,0xa6,0x58,0xb3,0x85,0x9b,0x16,0xdc,0xcc,0x63,0xa7,0x79,0xc5,0xa0,0xec,0xc1,0x36,0x57,0x59,0xda,0x83,0x85,0xd4,0xf4,0x3e,0xe8,0xfe,0xd5,0xc,0x47,0xcb,0x76,0x6a,0xf,0x6b,0xab,0xd5,0x5a,0x14,0x83,0xc6,0x58,0x78,0xcf,0x96,0xea,0x40,0xb6,0x66,0xc9,0x18,0x6,0xa8,0xc0,0x44,0x55,0x98,0x3c,0x3f,0xa0,0x38,0x10,0xab,0x2d,0xbd,0xa2,0x6a,0xcc,0xc8,0x3c,0x7f,0x71,0xc8,0xb1,0xd4,0x58,0x91,0x5c,0x90,0xf5,0xb8,0x26,0x14,0xc9,0x46,0x76,0x1,0x28,0xa9,0x21,0x83,0xb3,0xda,0x87,0x63,0x9a,0xd9,0xf5,0x30,0xeb,0x39,0x23,0x2e,0x85,0x76,0xbe,0x27,0xf6,0x6a,0x2d,0xf8,0x68,0x9a,0x98,0xc9,0xa,0xbd,0x66,0xe7,0x8c,0x28,0x3b,0x9b,0xa2,0x95,0x1a,0x47,0xd2,0xfc,0xac,0xd1,0x2d,0x3c,0x5f,0x41,0xcd,0x1c,0x5e,0xdb,0x5e,0xca,0xd1,0x2,0x67,0x47,0x47,0x47,0x47,0x27,0x0,0x3b,0x3a,0x3a,0xee,0x53,0x7c,0xf3,0xe9,0xcf,0x63,0x77,0x7e,0x86,0x9b,0xb7,0x1e,0x43,0x18,0x47,0x25,0xf5,0x84,0x6c,0x5b,0xad,0x50,0xf3,0xd,0x8,0x34,0x7a,0xd9,0x68,0xbb,0x9e,0xac,0xb2,0xae,0x5a,0xe3,0x24,0xe3,0x4d,0x54,0xc,0xbc,0x82,0x4b,0x93,0xb6,0xd2,0x4,0x33,0x1f,0xad,0xd8,0xa2,0xda,0x45,0xf5,0x26,0xc3,0xd0,0x2a,0x7f,0x55,0xa7,0x59,0x9d,0xc4,0x89,0xa2,0x4f,0x14,0x6e,0x39,0x45,0x14,0xa0,0xaa,0xfa,0x4a,0x5d,0xd5,0x5e,0xe6,0x79,0x75,0x43,0x64,0xd9,0xd2,0x63,0xf9,0xa6,0xa4,0xa0,0x34,0x76,0xa2,0x9a,0xff,0x13,0x86,0xd,0xee,0xee,0x5f,0xaa,0xa4,0x67,0x5c,0xc8,0xb6,0x34,0x1f,0xb4,0x64,0xe4,0xb0,0xbb,0x60,0x65,0x4,0x8d,0xe,0xe5,0xe8,0xd0,0xbf,0xaf,0xbc,0xf0,0x1c,0xa9,0x1a,0x38,0x87,0x29,0xf1,0x6a,0xb8,0x64,0xe9,0x1c,0x76,0x17,0x8,0xe3,0x6,0x79,0xbf,0x23,0x6b,0x51,0x93,0x89,0x23,0xe4,0xa9,0x40,0x9a,0x1b,0xe5,0xb3,0xab,0xaa,0x41,0x8e,0x1,0xdb,0xbb,0x74,0x8d,0x5b,0x6f,0x20,0x6d,0xb5,0xe1,0x96,0x4a,0x8,0xca,0x44,0x9b,0x72,0x17,0x59,0xc1,0xd0,0x28,0x39,0xe4,0x3d,0xef,0x9,0x26,0x76,0xd7,0xe5,0x1c,0xf5,0x46,0x48,0xd4,0x7,0x74,0xa,0x88,0x5d,0x38,0xd5,0x6d,0xe2,0x72,0xf6,0x4e,0xe1,0xd6,0xe5,0x69,0xbf,0xc7,0xd9,0xd9,0x19,0x50,0x32,0xa6,0xbb,0xcf,0xa1,0xa4,0xb9,0xff,0xd1,0x76,0x74,0x74,0xbc,0x1,0xd0,0x2c,0x8c,0x49,0xe6,0x2b,0xad,0xb4,0xe9,0x82,0x4c,0x2d,0x63,0x32,0x1a,0x81,0x1,0x2e,0xe4,0xf2,0x7e,0x40,0x5a,0x16,0xb2,0x87,0xa6,0x84,0x30,0x8c,0x4c,0x0,0x7a,0x2e,0xe0,0x70,0x7c,0x9d,0xb8,0xea,0x2b,0xdd,0xb0,0xdd,0x35,0x6a,0xe,0x9d,0x73,0x42,0x2c,0x2d,0x64,0x2b,0xd6,0xb6,0x61,0xba,0x4d,0x49,0xcd,0x22,0x9b,0xf3,0xb4,0xa0,0xe5,0xc2,0xc8,0x25,0x5e,0x5c,0xac,0xc5,0x84,0xe1,0x55,0xc4,0xa3,0x51,0x47,0x40,0x81,0x1f,0x6,0x6a,0xc5,0x75,0x81,0xca,0x25,0xb8,0x51,0x58,0x8,0xa1,0xaa,0x66,0x27,0xd5,0xbc,0x28,0x12,0x25,0xeb,0x8f,0x94,0x8e,0x11,0x71,0x59,0x74,0x3f,0x65,0xc1,0x8d,0xae,0x55,0x86,0xf7,0xc7,0x69,0xfe,0xad,0x7c,0x6e,0xf0,0xb8,0x7a,0x3f,0xb0,0xfa,0xb0,0x68,0xf6,0x9f,0x6c,0x63,0x95,0xcb,0x67,0x2d,0xc,0xbc,0xda,0x80,0x9d,0xab,0x8a,0x77,0xc7,0x8f,0x49,0xfe,0xb0,0xcc,0xa9,0x88,0xb8,0x5b,0x2f,0x86,0x26,0xce,0xeb,0xb3,0xce,0xeb,0x2,0x63,0xbb,0x50,0x2a,0x9f,0x2d,0xa5,0x48,0xc7,0x32,0x67,0xe4,0x92,0x6a,0xee,0x63,0x93,0xad,0x2c,0xd7,0x74,0xca,0x11,0x2e,0xab,0xc5,0x5c,0x21,0x4a,0x2d,0x67,0x2d,0x52,0x4c,0x49,0x24,0x37,0x4,0xe7,0x3b,0xaa,0xb2,0x1f,0x50,0x8b,0x77,0x66,0x65,0xbf,0x28,0xfc,0xc3,0x10,0x10,0xd9,0xc5,0x60,0x8c,0x5,0x6c,0xae,0x11,0x2a,0xcd,0x98,0xd2,0xf1,0xa0,0x63,0x94,0xa5,0xdc,0xad,0x71,0x6,0xac,0xac,0xb9,0x6c,0x51,0x56,0x62,0x94,0xc7,0xac,0x5d,0x74,0x2e,0xda,0x64,0x8c,0x26,0xff,0xaf,0x5a,0x83,0x65,0x5e,0xba,0x26,0xf3,0x38,0x6e,0xc4,0x34,0xf3,0x53,0x53,0x56,0xb9,0xd7,0x25,0xaf,0x17,0x2e,0x3b,0x3a,0x3a,0x3a,0x3a,0x1,0xd8,0xd1,0xd1,0x71,0x5f,0xa2,0x94,0x82,0x3b,0x2f,0xfe,0x39,0xee,0xbe,0xf4,0x17,0x70,0xc3,0x86,0x9a,0xfa,0x42,0x40,0x13,0xd7,0xd6,0xac,0xa4,0x42,0x2d,0x1e,0x92,0x4f,0x44,0xab,0xb3,0x99,0xdb,0xf7,0x86,0x9a,0x5b,0x64,0x2c,0x72,0x22,0xe5,0x1a,0xa9,0xe8,0x78,0xb5,0xd8,0xba,0x23,0x32,0xd0,0xd5,0x89,0x71,0x4a,0xb0,0x2e,0x20,0xe7,0xa8,0x13,0xc9,0x9c,0x16,0xb6,0xab,0x8c,0xc8,0x69,0x21,0x9a,0x90,0xed,0x1c,0xc6,0x5,0x2d,0x84,0x90,0x1b,0x9b,0x36,0x53,0x50,0x26,0x94,0xb4,0x72,0x1e,0x74,0xc2,0x28,0xa4,0x59,0xd,0x92,0xae,0x8a,0xb6,0x61,0xdc,0xf2,0x4a,0x34,0xb4,0x90,0x84,0xec,0x3a,0x3c,0xa1,0x2d,0xb5,0x40,0xc4,0xfb,0x1,0x87,0xdd,0x19,0xbf,0xf,0xd9,0x5f,0xcf,0xef,0x72,0x58,0xb6,0x1,0x52,0x9c,0xe1,0xc2,0x6,0x28,0x9,0x29,0x26,0x94,0xbc,0xc0,0xe,0xd7,0x50,0xe2,0x1,0xc6,0x7a,0x52,0xff,0x4d,0x3b,0x18,0x37,0xd0,0x64,0xdc,0x79,0x98,0x92,0x48,0x19,0x7,0x68,0xae,0x12,0x4d,0x7a,0x49,0xc1,0xd0,0x66,0xe9,0x0,0xdc,0x4,0x58,0x40,0xd9,0x45,0x6c,0x17,0x2e,0x0,0x65,0xeb,0x0,0x5a,0x94,0x62,0x9d,0x47,0x5a,0x26,0xc0,0x58,0xb5,0x53,0x83,0x57,0xe9,0x53,0x9c,0x28,0xf0,0x7d,0x3c,0x45,0x9c,0x2e,0xe0,0xc2,0x6,0xa5,0x24,0xb6,0x2f,0xcd,0x70,0x9e,0x6e,0x1c,0x73,0x9c,0x60,0x6c,0xd0,0x1b,0x12,0x94,0x4,0x18,0xc7,0x37,0x7b,0x13,0x3c,0xdf,0x94,0x48,0x5e,0xa0,0xd8,0x9c,0x34,0xd7,0x2f,0x67,0xd1,0x11,0xf2,0x8d,0x93,0x81,0xf5,0x3,0xd2,0x32,0x29,0xd1,0x49,0x8d,0xd0,0x74,0x33,0x93,0x96,0x85,0x6e,0x1a,0xe6,0xb,0xfa,0x7c,0x1d,0x1d,0x1d,0x1d,0x6f,0x94,0x6b,0xb3,0x16,0x7c,0xd4,0x4c,0xbd,0xd2,0xc4,0x2e,0xc0,0x18,0xc4,0xb4,0xc0,0xb9,0xa0,0x5,0x4a,0xd6,0x58,0x14,0x3,0x38,0xcb,0x99,0xa9,0x21,0xa8,0x4a,0x4a,0x88,0x23,0xf9,0xfe,0xa5,0x6b,0x6c,0xbe,0xc7,0xbc,0x0,0xac,0x2a,0xb,0x48,0x31,0x32,0xc9,0x46,0xd7,0x65,0xe7,0xbd,0xee,0x57,0x18,0x28,0x13,0x50,0xec,0xbe,0xa2,0x38,0x13,0x62,0xa9,0x46,0xb3,0xc9,0x42,0xda,0x48,0xcf,0xbb,0x8a,0x1,0x64,0x1b,0xb3,0xf7,0x81,0x17,0xc1,0x1c,0xcd,0x45,0x78,0xdf,0x49,0x5,0x97,0xb8,0xc4,0xb,0xd5,0x42,0xca,0x64,0x99,0x77,0x44,0x3a,0xd2,0x38,0x59,0x55,0x2d,0x1a,0xe3,0xe0,0x1d,0x29,0xfc,0x96,0x79,0x62,0x12,0xb0,0xa8,0xbd,0x57,0x4b,0xb4,0x78,0x9c,0xc4,0xd6,0x9b,0xb8,0xc0,0xc4,0x3a,0x72,0x14,0x58,0x2e,0x3d,0x93,0x7d,0xa1,0x60,0xe4,0xcc,0xa4,0x9f,0xd7,0xcc,0x5f,0x99,0x1f,0x88,0xe5,0x78,0x95,0x5f,0xc7,0xdb,0x13,0x47,0x2,0x0,0x8d,0xe2,0x10,0xab,0xb1,0x94,0x70,0xc8,0x2,0xa8,0xbc,0x3f,0xd9,0x8b,0x9d,0x12,0x62,0x4b,0xa6,0x5c,0xbf,0x65,0x9e,0x35,0x3b,0x58,0x7e,0xaf,0x5,0x64,0xc6,0x22,0x9b,0xa4,0x73,0xb6,0x94,0xc8,0xee,0x5b,0x5c,0x2d,0x1f,0x89,0xcb,0xc,0x3f,0x50,0xf9,0x49,0x4a,0x91,0xcf,0x93,0xd,0x96,0x69,0x8f,0xc0,0xca,0x48,0x52,0x72,0x1a,0x6d,0x54,0x6,0x13,0x99,0xed,0xa2,0xab,0x69,0xa,0xc1,0xc4,0x75,0x21,0x64,0xa2,0x38,0x35,0x44,0x65,0x47,0x85,0x32,0xd,0x29,0xc9,0x63,0x2f,0x2e,0x0,0x9a,0x1f,0x38,0x8d,0x2f,0x91,0xf9,0x59,0x69,0x82,0x1,0x8b,0xfc,0xcc,0xf,0x9,0x75,0x57,0x0,0xb5,0x4e,0xcb,0x79,0xa6,0x25,0x71,0xd0,0x27,0x5c,0x51,0x2e,0xdc,0x89,0xbf,0x8e,0x8e,0x8e,0x4e,0x0,0x76,0x74,0x74,0xbc,0xa1,0x88,0xc0,0x8c,0x38,0xed,0x10,0xa7,0xdd,0x77,0xf8,0x8a,0xbf,0x84,0x95,0x52,0xe3,0x98,0x70,0xfb,0x36,0x4f,0xb3,0x1e,0x25,0xc7,0xef,0xcb,0x26,0x77,0xdf,0xdb,0x8e,0xde,0x73,0x2c,0xd2,0x72,0x58,0xfd,0x9c,0xf7,0xaf,0xea,0x6b,0xe2,0xc4,0xaf,0x89,0xdf,0x81,0xa5,0x55,0x2c,0x33,0x25,0x7f,0xc7,0xe3,0xb2,0x7a,0xb9,0x71,0x57,0x92,0x68,0xed,0xe3,0xd3,0xf9,0xab,0xdf,0x97,0xcf,0x6c,0xdd,0xd0,0x90,0xa5,0xeb,0xe3,0x49,0xab,0xf4,0xe9,0x5b,0x1f,0xb7,0xc6,0x42,0xde,0xd1,0xd1,0xd1,0xf1,0xc6,0xbd,0x2e,0xaf,0x8b,0xb7,0xac,0x25,0x82,0x2f,0x45,0x29,0x86,0x72,0x48,0x71,0x56,0x45,0x18,0x11,0x4b,0xb4,0xc8,0x63,0xd8,0x6a,0x4a,0xdf,0xc9,0x54,0xb8,0x21,0xc4,0x95,0x95,0x28,0x7,0x63,0xee,0x71,0xbd,0x30,0x1c,0x7,0xb1,0xd4,0x7c,0x37,0x90,0x9d,0x17,0x91,0xb3,0x5d,0x59,0xa1,0x28,0x96,0xdd,0x9c,0x13,0x6,0xbf,0xa5,0xfc,0xb7,0x61,0xd4,0x5,0x39,0x30,0xf9,0x92,0x62,0xe4,0x26,0x5f,0x77,0x4f,0xb2,0xc5,0xb3,0x5d,0x98,0x94,0x6b,0x59,0x9,0x31,0x21,0xcf,0x9c,0xb4,0x0,0x83,0x15,0x7d,0xce,0x23,0x96,0x85,0xaf,0x37,0x85,0x9f,0x13,0xb8,0xd1,0x3e,0xa9,0xe2,0x5d,0x62,0x3c,0x44,0xa1,0x58,0x6c,0xc1,0x32,0x1d,0x60,0xdd,0x8,0x6b,0xc,0x12,0x93,0x59,0xc9,0x1c,0x29,0xd7,0xd8,0x6e,0xed,0x24,0x93,0xcf,0x39,0xa4,0x98,0xd9,0x71,0xc0,0x76,0xe4,0x52,0x5d,0x4,0x42,0xe2,0x89,0xfd,0x57,0x88,0x45,0x6b,0x24,0xf7,0x98,0x79,0xc3,0xe6,0xfd,0xe3,0x32,0x6b,0xae,0xa0,0xf3,0x5e,0x2d,0xca,0xb4,0xef,0x65,0x45,0x96,0x2d,0xf3,0x4c,0x79,0x82,0xd6,0x52,0x11,0xd9,0x32,0x63,0x18,0x37,0x1a,0xf3,0x21,0x45,0x61,0x42,0x48,0x46,0x5e,0x20,0x75,0xdc,0x52,0x2c,0x76,0x5f,0xc3,0x24,0xe4,0xb8,0x61,0xd2,0xb6,0x0,0x31,0x2d,0xea,0x7e,0x88,0x71,0xe6,0xec,0x64,0x3e,0x7f,0x1a,0x75,0xbf,0x93,0xe7,0x2c,0x33,0xa,0xb2,0x3a,0x3c,0x24,0xfb,0x4f,0x1c,0x19,0x92,0x47,0x49,0xe5,0x27,0xae,0x12,0xac,0x8e,0x2d,0xe1,0xb9,0x68,0xbe,0xa3,0xe6,0xf3,0x29,0xc1,0x57,0x2d,0xeb,0x12,0x9,0x22,0xd3,0xe,0x21,0xaf,0x57,0xf1,0x34,0xb9,0x29,0x8e,0x13,0x62,0xb0,0x80,0xb3,0x89,0xcb,0xaa,0x74,0x4c,0xde,0x43,0x94,0xad,0xd2,0x35,0x66,0xee,0xf1,0xb7,0xd0,0xd1,0xd1,0xd1,0xf1,0x83,0x80,0xed,0x43,0xd0,0xd1,0xd1,0xf1,0x3a,0xbc,0x35,0xf9,0x4b,0xd8,0xc4,0x77,0x46,0x72,0x7d,0xbf,0xc8,0xbf,0xbf,0xdc,0xb1,0xf8,0x2e,0x5f,0x53,0x72,0x55,0x6b,0x7c,0xf,0x6a,0xb8,0x7b,0x29,0xe8,0xbe,0x77,0x65,0xdd,0xbd,0xf7,0x3f,0xa7,0xf9,0xea,0x7d,0x2c,0x69,0xb5,0xbd,0x7b,0x1e,0xb7,0x4e,0xfe,0x75,0x74,0x74,0xbc,0xd1,0x27,0xff,0x62,0xc5,0x6c,0x98,0x18,0x69,0xc6,0x15,0xa5,0x17,0x0,0x56,0x84,0xd7,0xe2,0x24,0xcd,0x7d,0x2d,0x58,0x91,0x59,0xb5,0x18,0x84,0x94,0x6c,0xc6,0xd9,0x7b,0x12,0x80,0xf4,0x35,0xcc,0x84,0x1f,0xab,0xa9,0x9c,0xf,0x4a,0x8,0x4a,0x8c,0x86,0x12,0x6a,0x9c,0xb7,0x27,0xf1,0x1c,0x71,0x99,0x41,0x84,0x94,0x57,0x5b,0xf2,0x30,0x6e,0x88,0x28,0xb2,0xee,0x5b,0x7c,0xea,0x4c,0xcf,0x2b,0x85,0xcb,0xb8,0xa8,0x3c,0x84,0x48,0x22,0x22,0x71,0x28,0xe7,0x6e,0x20,0x55,0x3b,0xdb,0x7a,0x25,0x37,0xd7,0xfb,0x80,0x30,0xc,0xf0,0x61,0xc0,0x30,0x6e,0xe0,0xc3,0x80,0x10,0x46,0x8e,0xe3,0xb0,0xd8,0x6c,0x4f,0x75,0xfb,0x61,0xdc,0xac,0xb6,0x9c,0x12,0x11,0x55,0x3e,0xc,0xf4,0x7c,0xeb,0xd4,0xb6,0x2a,0x71,0x1e,0x12,0x61,0x42,0xad,0xb8,0x96,0xf7,0x83,0xec,0xc9,0x52,0x9c,0x41,0x63,0x83,0x26,0xf,0xcf,0x70,0x1e,0x9f,0xe1,0x18,0x13,0xce,0x6b,0xe4,0xe3,0x49,0x79,0xbf,0xa4,0xb2,0xd4,0xb6,0x61,0x51,0x25,0xf2,0xc2,0x9f,0x35,0x96,0xc7,0xb2,0x12,0x5f,0x29,0x46,0x84,0x30,0x68,0xd3,0xb3,0xf7,0x3,0x35,0xf3,0x1a,0x83,0xc4,0xf9,0x85,0xd6,0x39,0x22,0x8,0x9b,0xcf,0x40,0xc4,0xa3,0x45,0x8,0x3,0x29,0x3a,0x59,0xb9,0x49,0xe3,0xcc,0xc7,0x16,0x44,0xc6,0x8a,0xb,0x21,0x73,0x5b,0xaf,0x1,0xb4,0xd0,0xc4,0x79,0xc7,0x84,0xa5,0xd3,0x73,0x95,0xde,0xb3,0x16,0x92,0x81,0x15,0x9d,0x6d,0x46,0x31,0x54,0xe5,0x97,0x6b,0x81,0x9c,0x58,0xd9,0x5d,0x2d,0x6c,0xd1,0x5c,0x3e,0xce,0x26,0x96,0xf1,0x92,0xf7,0x20,0xa5,0x67,0x6d,0x29,0x6e,0x45,0xa5,0x5,0xe5,0x72,0x16,0xb5,0x3c,0xaf,0xd4,0xe9,0x4b,0xcd,0x61,0x84,0xee,0x43,0x47,0x47,0x47,0xc7,0xeb,0x1,0x5d,0x1,0xd8,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xd1,0xf1,0x6,0x1,0xd9,0x47,0x1,0x70,0x70,0x2,0x45,0x24,0x24,0x55,0x59,0x19,0x6e,0x2f,0xb5,0xfc,0x38,0x91,0x56,0x66,0x45,0xa0,0xa8,0x25,0x94,0x55,0x6c,0x6a,0xd1,0xb5,0x44,0xac,0xdc,0x7b,0x1d,0x87,0x88,0x91,0xcc,0xd9,0x77,0xcb,0xbc,0x20,0xc5,0x88,0x61,0xdc,0x90,0xb5,0x93,0xb,0x2b,0xc0,0xe4,0x96,0x73,0x1e,0x71,0x26,0x25,0xa2,0x58,0x43,0x53,0x8c,0xf0,0xdb,0x61,0x45,0x5a,0x12,0x59,0x19,0xaf,0xb6,0x0,0xf3,0x27,0x95,0x7c,0xba,0x81,0xb3,0x72,0xb,0xb2,0x16,0x64,0xe4,0x99,0xf2,0xe8,0x12,0x67,0xfb,0x51,0xbb,0xec,0x8c,0xc,0x51,0x95,0xdb,0x26,0x6b,0x2f,0x69,0x13,0x6f,0xbb,0x35,0x6b,0x29,0xff,0x30,0xc6,0x5,0xd6,0x18,0xe4,0xe6,0x73,0x51,0x84,0x8,0x94,0x3c,0xa,0xc3,0x6,0x31,0xce,0x55,0x5d,0xe8,0x3c,0x4a,0x5e,0xe0,0x7,0xc9,0xb4,0x4b,0x4a,0xa2,0x65,0x6e,0xd3,0x8d,0x69,0x61,0xb2,0x89,0x15,0x79,0x29,0x2b,0x29,0x46,0x84,0xac,0xd1,0x2c,0x42,0x51,0xbb,0x4b,0x4b,0x73,0xc9,0x5,0xc9,0x90,0x82,0xf,0x6c,0x89,0x6d,0xc9,0xaf,0xac,0x99,0x8b,0x5,0xc3,0x66,0xbb,0xca,0x80,0x6c,0x73,0x0,0xc7,0xcd,0x89,0xc6,0x71,0x88,0x9d,0x56,0x94,0x94,0xe2,0xa3,0xd5,0x2,0xd,0x3,0x2d,0xfa,0xa8,0x91,0x1d,0x46,0x49,0x3b,0x29,0x3f,0xa3,0xec,0xc0,0x85,0xf9,0x3b,0x22,0x84,0xd,0xc,0x97,0x98,0xd5,0xa2,0x17,0x21,0x34,0x2d,0x3c,0xb2,0xc9,0xb0,0xd6,0xa0,0x70,0x71,0x5a,0x81,0x51,0xd2,0x4f,0x22,0x63,0x6c,0xd3,0x2b,0x26,0xe7,0x36,0xe5,0x21,0xd6,0x7d,0x20,0x3b,0xb1,0x5d,0x29,0x1,0x4d,0x31,0x4d,0x71,0x1b,0x9a,0x3c,0x40,0xac,0x33,0x3,0xf9,0x77,0x74,0x7e,0x95,0xd5,0xd9,0xd6,0xe6,0x14,0xab,0x65,0xbd,0xaf,0x3f,0x76,0x74,0x74,0xbc,0xe,0xd0,0x9,0xc0,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x8e,0x37,0xa,0x24,0x3b,0x4e,0xa,0xb5,0x72,0x51,0x22,0x4a,0x2c,0x90,0x42,0x88,0x14,0x14,0x55,0xe7,0x89,0x85,0xd4,0x87,0x41,0x4b,0x33,0x9c,0x33,0x35,0x73,0xce,0x39,0xe4,0x18,0x11,0xc6,0x8d,0xb6,0xd3,0x1e,0xa3,0x94,0xc4,0x76,0x63,0xa3,0x6a,0x35,0xef,0x13,0xe2,0xb2,0xb0,0x75,0x92,0x48,0xb9,0x2,0x22,0xaf,0x72,0xa6,0x76,0x61,0xb2,0xe7,0x46,0x6d,0xa3,0x25,0x72,0xcc,0xc1,0x4,0x22,0x24,0x73,0x8a,0x70,0xc3,0xe6,0x4a,0xb,0x70,0xe1,0x32,0x9,0x63,0x2d,0x2c,0xa0,0x2d,0xaf,0x6,0xa4,0x28,0x4c,0x31,0x62,0xdc,0x6c,0xa9,0x74,0xcb,0x5a,0x8c,0x9c,0x4b,0x38,0x6c,0x4e,0x90,0xb9,0xd1,0x36,0xa7,0xa8,0x24,0x96,0xf7,0x1,0xc5,0x56,0xfb,0x6c,0xce,0x9,0xb9,0x14,0xa0,0x50,0x76,0x9e,0x81,0x81,0xb3,0xe,0x26,0x18,0xe4,0x94,0xe9,0x73,0xa4,0x8,0xe7,0x3,0xe6,0xc3,0x9e,0xc6,0x29,0x27,0x58,0x43,0x65,0x1a,0xa6,0x58,0xb6,0xba,0xd2,0x67,0x91,0x7c,0x42,0x0,0x30,0x3c,0xe6,0xb9,0x24,0x78,0x17,0x90,0x38,0xbb,0x58,0x6c,0xda,0xc6,0x78,0xcd,0x1,0x74,0x7e,0x58,0x29,0xf2,0x12,0x68,0x9b,0x91,0xf3,0x9,0xb5,0xb4,0x2c,0xc,0x95,0xa0,0x52,0x32,0x2e,0xa8,0xa,0x2e,0xc5,0x85,0xb3,0x97,0x89,0x1c,0x6d,0x73,0x83,0xc5,0xf2,0x6c,0x59,0xdd,0xa7,0x79,0x87,0xa0,0x82,0x98,0x1c,0xa3,0xee,0x9f,0xe5,0x2,0x12,0xc9,0x2c,0x74,0xd6,0x6b,0x89,0x8a,0x1b,0x6,0x26,0x6f,0x2d,0x72,0xca,0x55,0x35,0xc9,0x25,0x1f,0xc5,0x34,0x84,0x9f,0x64,0xb,0x73,0x16,0x25,0x8d,0x3b,0xb4,0xf1,0xd8,0x71,0x6b,0x72,0x29,0x4c,0x5a,0xe7,0x44,0xb9,0x7f,0xac,0x4a,0x4c,0x29,0x69,0xd6,0xb4,0x90,0xda,0x9a,0x15,0x6d,0x28,0x5b,0x51,0xb2,0xff,0xc,0x38,0x37,0x11,0x46,0x8f,0xb7,0x94,0xa2,0x9,0xb1,0xa7,0xd9,0x8b,0x72,0xaa,0xb5,0x2c,0xb0,0x1,0xfb,0x83,0x8d,0xe6,0x3,0xca,0xdf,0x57,0x47,0x47,0x47,0xc7,0xeb,0x1,0x9d,0x0,0xec,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0x78,0xa3,0x40,0x1b,0xf,0xd6,0xa4,0x84,0x34,0xfe,0x96,0x4c,0xa,0x33,0x2a,0xad,0xb2,0x9c,0xd5,0x57,0x9a,0x97,0x33,0x19,0x63,0x85,0x3c,0x31,0x18,0xc6,0xd,0x95,0x58,0x30,0xc1,0x72,0xaf,0xdc,0x33,0x63,0x49,0xad,0xb7,0xcc,0x93,0x16,0x67,0x1c,0xe6,0x83,0x36,0x9,0x4b,0xab,0xad,0x77,0x1e,0x71,0x99,0xaa,0x35,0x13,0x85,0x2c,0xa7,0x92,0x83,0x97,0x22,0xe7,0x4,0x92,0xd5,0xb5,0x48,0x2e,0xde,0x15,0xdb,0x14,0x65,0x9e,0xb5,0x54,0x88,0x35,0x4f,0x7b,0xfd,0xbc,0x62,0x4f,0x4d,0x4d,0xd9,0x44,0x9b,0x15,0xe8,0x3c,0x91,0x91,0x26,0x5b,0x84,0x71,0xc0,0x7c,0xd8,0xd3,0x76,0xbc,0x43,0x10,0x32,0x8b,0xcb,0xbc,0xa8,0x38,0x83,0x3e,0x93,0x10,0x65,0x0,0x97,0x77,0xf1,0xfb,0xd,0x9b,0x2d,0x11,0xaa,0xdc,0xe2,0x2b,0xe5,0x65,0x71,0x99,0x75,0x3f,0x51,0xa,0x8a,0xa5,0x3d,0xa4,0xdc,0x43,0x56,0xb4,0x31,0x31,0xaa,0xc7,0x4a,0xda,0x82,0x9d,0x3,0xe0,0x6a,0x39,0x9,0x2a,0x21,0x5b,0x72,0x46,0xe0,0xdc,0xc4,0x69,0x7f,0x1,0x67,0xa5,0x71,0xd8,0x6a,0x16,0x9e,0xf3,0x3,0x8c,0x1,0x91,0xb0,0xa6,0x96,0xb4,0x10,0x19,0x9c,0x74,0xc,0xb5,0x24,0x6,0x6,0x19,0x91,0x49,0x4b,0x5b,0xc7,0xf,0x50,0xd2,0x56,0x88,0x48,0xda,0xf,0x8f,0xc0,0xa5,0x1e,0xde,0x7b,0x26,0x56,0x17,0x64,0x64,0x2d,0x79,0x11,0x68,0x19,0x59,0xa3,0xb6,0x34,0xd6,0xc1,0x48,0x6e,0x1f,0x0,0xb,0x8f,0x18,0x67,0x18,0x18,0x26,0x14,0xa9,0xb0,0x66,0x99,0x27,0xdd,0x7f,0x58,0xb0,0xad,0x9b,0xc7,0x18,0x95,0xbc,0x84,0x66,0x5c,0x46,0x6d,0xbc,0x96,0x52,0x33,0x51,0x2e,0x16,0xa0,0xaa,0xfc,0xe4,0xbc,0xcf,0xa5,0x21,0x23,0x81,0x1a,0xfc,0xd7,0x3e,0x49,0xd4,0x80,0xdc,0xa6,0x4d,0x6f,0xd4,0xbf,0x73,0x3a,0x3a,0x3a,0x5e,0x37,0xe8,0x4,0x60,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0xc7,0x1b,0x5,0x9c,0x6b,0xd6,0xaa,0x98,0x44,0xe5,0x56,0x4a,0x51,0x72,0xc9,0x87,0x50,0x2d,0xb5,0xd6,0x68,0xce,0x9e,0xd8,0x58,0x85,0x58,0x1,0xa,0x96,0x65,0x82,0x48,0xa1,0x42,0x18,0xef,0x99,0x7b,0x66,0x60,0x48,0x45,0xe8,0x3,0x65,0xed,0xc5,0x5,0xce,0x7a,0xfd,0x2d,0x6d,0xca,0x62,0x99,0xf,0xf0,0x7e,0x80,0xf5,0x8e,0xec,0xab,0xdc,0x6e,0x2b,0x6d,0xb1,0xce,0x7,0x78,0xef,0x1,0x54,0xab,0x30,0x60,0xae,0x74,0x59,0x4a,0xd6,0x1c,0x4c,0xcd,0xe3,0x33,0x96,0xd4,0x8a,0xf5,0xb5,0xc0,0xb0,0xa1,0xac,0x41,0x21,0x30,0xc5,0xd6,0xec,0x8c,0x83,0x1b,0x49,0x21,0xb7,0x39,0x39,0x5,0x0,0x2e,0x11,0x89,0x9c,0x5f,0x38,0x23,0xc,0x3,0x59,0xa4,0x7d,0x80,0x75,0x56,0x3f,0x8b,0x58,0x5a,0xd3,0x32,0x3,0xd6,0x20,0x2e,0xb,0x1c,0xdb,0x84,0x37,0xdb,0x13,0x22,0xa9,0xb4,0xc4,0xc4,0xaa,0x52,0x4d,0xd4,0x7c,0xb2,0x1f,0x99,0x3f,0x83,0x1,0x11,0x7b,0x30,0x94,0xfb,0x97,0xb9,0xd0,0x24,0xc,0x3,0xe2,0x3c,0xc3,0x5,0x26,0xdd,0x58,0xf9,0x46,0x76,0xe5,0xa2,0xc4,0xa4,0xa8,0xf3,0x84,0x30,0xb5,0x2e,0xa0,0xe4,0x44,0x8a,0x4c,0x1f,0xd4,0x42,0xac,0x39,0x90,0xce,0x23,0x29,0xd9,0x1a,0x1a,0x15,0xa0,0xe3,0x53,0xc9,0xaa,0x6a,0x33,0x2e,0xb,0x59,0xc5,0xd9,0x46,0x9c,0x96,0x5,0xc3,0xb8,0x21,0x72,0x34,0xc,0xd4,0xba,0xcb,0x9f,0xc3,0x3a,0xf,0x17,0x8c,0x36,0x40,0x5b,0x21,0x4f,0x43,0x0,0xa,0x94,0x90,0x6d,0xdb,0xa5,0x45,0x21,0x2a,0xad,0xc8,0x25,0x13,0x49,0x18,0xc2,0x48,0x45,0x27,0xce,0xd5,0xe3,0x9f,0x1,0x6b,0x29,0xb3,0x90,0xa,0x3f,0x68,0x1b,0xa2,0x7c,0x94,0xc6,0xe7,0x22,0xe7,0x3e,0xe7,0x10,0x8a,0xd2,0x4f,0x4b,0x43,0xb2,0xa8,0xf8,0xa8,0x74,0xa6,0x34,0x76,0x60,0xb2,0x3b,0xb3,0xe5,0x9d,0x5f,0xa0,0xea,0x40,0x40,0xb,0x54,0xba,0xfa,0xaf,0xa3,0xa3,0xe3,0xf5,0x84,0x4e,0x0,0x76,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0xbc,0x41,0x50,0x2d,0x90,0x46,0xd5,0x4a,0x42,0xfc,0x9,0xe9,0x25,0x84,0x9b,0xd8,0x85,0x89,0x70,0xb,0x58,0x96,0x9,0xa5,0x38,0x2d,0x96,0x90,0xcc,0x3e,0x6b,0x1d,0x95,0x37,0x38,0xf,0x7c,0xb,0xc1,0x93,0xd8,0x30,0x89,0xf8,0xe2,0x26,0xd9,0x10,0xb8,0xc,0x82,0xf6,0x81,0x9a,0x7e,0xa9,0xf9,0xb6,0x0,0xc8,0x65,0x51,0x5b,0xb1,0x6c,0x8b,0xde,0x3,0xb0,0xce,0xd4,0xd6,0xdc,0x9c,0xae,0xde,0x34,0x67,0xee,0xb9,0x3,0x91,0x3e,0x4b,0x8a,0xb4,0x9f,0xce,0x62,0xb0,0x1b,0xb2,0x92,0x5a,0x4b,0xf6,0x62,0xce,0x9f,0x33,0x96,0x3e,0x9b,0x64,0xdd,0xc9,0xb8,0x29,0x89,0x54,0x8a,0xaa,0x1e,0x89,0xc8,0xe4,0xb2,0x8d,0x9c,0x0,0xb6,0xa2,0x2,0x60,0x8b,0x6b,0xe4,0xe2,0x11,0x8b,0x30,0xc,0x4c,0xd8,0x11,0x49,0x4a,0xd9,0x85,0xb9,0x16,0x59,0xb0,0xc5,0x78,0x99,0xf,0xaa,0x58,0x2c,0x99,0x94,0x98,0x3e,0x84,0x3a,0x66,0xfc,0x3a,0xe7,0x2d,0x10,0x99,0xa0,0x1b,0x6,0x55,0xfd,0x9,0xd1,0xb7,0x39,0x39,0xc5,0x3c,0x1d,0xf4,0x78,0x19,0x63,0xa8,0x18,0x84,0xb3,0x9,0x3d,0xdb,0x81,0xb5,0x78,0x85,0xdf,0x57,0xd4,0x89,0xc6,0x5a,0x98,0x65,0xe6,0xcc,0x47,0xab,0xaa,0xcc,0x76,0x5f,0x72,0xca,0x70,0x61,0x80,0x31,0x11,0xd6,0x18,0x18,0x1f,0x74,0xc,0x96,0x79,0xaa,0xb6,0xf2,0x92,0x75,0x7b,0x42,0x50,0x4a,0x31,0x8a,0xe4,0x2e,0xda,0x56,0x3d,0xc9,0x63,0x2f,0x4,0x23,0x0,0xce,0x89,0x64,0x45,0x1f,0xb8,0x9,0x9a,0xb3,0x3,0xd,0x2b,0x43,0x39,0x6c,0x51,0x15,0x83,0xe0,0xac,0x48,0xca,0xbe,0x34,0xb5,0x19,0x98,0x89,0x6c,0xb5,0xfa,0x1a,0x39,0x43,0xa9,0x6c,0x45,0x8a,0x6e,0xc4,0x16,0x4c,0xa7,0x52,0x56,0x6e,0x90,0xca,0x6f,0x12,0x93,0xa0,0x4d,0xdb,0xf0,0xa5,0xd3,0xaf,0x34,0x19,0x89,0x1d,0x1d,0x1d,0x1d,0x3f,0x58,0x74,0x2,0xb0,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xe3,0xd,0x2,0xc9,0x73,0x53,0x8d,0x52,0xd3,0x68,0x6a,0x4c,0x25,0xba,0x52,0x8c,0xd4,0x96,0xeb,0x29,0xc3,0x6e,0x66,0x62,0xc6,0x58,0xca,0xce,0xa3,0xf2,0x88,0x8c,0x71,0x73,0x82,0x14,0x17,0x78,0x33,0x7c,0xdb,0x6d,0x97,0x4c,0xa4,0x4f,0x64,0x52,0x29,0xa7,0xc4,0xea,0xb2,0x11,0x42,0x44,0x66,0x56,0x7f,0x15,0x7e,0xbe,0x61,0xe5,0xe1,0x32,0x4f,0x8,0xc3,0xc0,0xb6,0x53,0xf,0x94,0x4c,0xf9,0x71,0x83,0xd7,0x5c,0xc2,0x7b,0x21,0x4b,0xbb,0x6b,0xa6,0x36,0xe1,0xa2,0x45,0x18,0x1,0x71,0x59,0x28,0xd7,0xf,0xa4,0xf4,0xb2,0xdc,0x40,0x2b,0x76,0x64,0x70,0x96,0x9c,0x64,0xe2,0x79,0xe7,0x10,0x23,0x97,0x41,0x58,0x8b,0xe0,0x7,0x25,0x8b,0x42,0x18,0x48,0xd5,0x18,0x2,0x72,0x4a,0x69,0x1b,0xd7,0x18,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x8,0x18,0xb5,0x9,0x57,0x89,0xad,0x48,0x79,0x87,0x64,0x7b,0x2e,0xb5,0x34,0x43,0x8e,0x4d,0x4e,0x8,0xc3,0x86,0xad,0xc2,0x16,0xa9,0x64,0x2a,0x1,0x89,0xb3,0xe6,0x34,0x92,0xf3,0x54,0x8,0xd3,0xa1,0x66,0x36,0x66,0xb6,0x5,0x1b,0x6a,0xe3,0xcd,0x29,0xa9,0x75,0x9a,0xf6,0xb1,0xf9,0x1c,0x4c,0xd4,0x9,0x69,0xda,0x5a,0x6f,0xbd,0xf,0xc8,0x39,0x63,0x3e,0xec,0x31,0x6e,0xb6,0xfa,0x78,0x8,0xa3,0x92,0xa5,0xc6,0xb0,0x9a,0x73,0x3b,0xea,0xf1,0xb4,0xcd,0xb9,0x65,0x9d,0xa7,0xf7,0x44,0x2d,0x3,0xf1,0x61,0x20,0xab,0x2e,0xa8,0xbd,0x39,0xa7,0x8,0x0,0xdc,0x20,0x3c,0x20,0xa5,0x44,0xe4,0x68,0x8a,0xc8,0x29,0x33,0xf1,0xe6,0x10,0xe7,0x59,0x49,0xcd,0x24,0x4,0xae,0x49,0x9a,0x6b,0x28,0x8a,0x53,0x22,0x26,0x23,0x29,0x54,0xbd,0xc7,0x3c,0x1d,0x30,0xc,0x1b,0xcc,0xf3,0xbe,0x2a,0x57,0xe5,0xd8,0x6a,0x16,0x24,0x2b,0xfc,0xa,0x95,0xd8,0xe4,0xc4,0x25,0x2a,0xa8,0xd,0xc0,0x44,0x60,0xf2,0x43,0xf2,0xf7,0xc2,0xc7,0x5c,0x54,0x81,0xac,0xf9,0x6c,0x4e,0x76,0xfe,0x57,0xbd,0xc0,0x1d,0x1d,0x1d,0x1d,0x3f,0x78,0x74,0x2,0xb0,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xe3,0xd,0x82,0xb6,0x28,0x83,0xd4,0x59,0x85,0x5b,0x6d,0x9d,0x12,0x52,0x4a,0x10,0x71,0xe,0x9d,0x31,0x56,0x5b,0x63,0x4b,0xa2,0x2c,0x3b,0xe7,0xbd,0x92,0x40,0x62,0xd,0xa6,0xf2,0x88,0x70,0x4f,0x32,0xce,0x8,0xb1,0x68,0x28,0x2b,0x30,0xc6,0x85,0x89,0x3c,0x52,0xc9,0x59,0x67,0xf5,0xb5,0xd6,0x39,0x58,0x2e,0xa7,0x10,0x12,0x4e,0x94,0x54,0x6,0x0,0xb8,0x3d,0x97,0x48,0xbc,0x19,0xd6,0x5e,0x7,0xcc,0x15,0xdb,0x6d,0xb2,0x1,0xa5,0xf0,0x62,0x9e,0xf6,0x9a,0x25,0x68,0x1d,0x15,0x4b,0x78,0x1f,0x50,0xb8,0x64,0x42,0x8,0xa2,0xc0,0x6a,0xc4,0xc4,0x65,0x20,0xc6,0x64,0x25,0xc2,0x62,0x5c,0x60,0xe9,0x4d,0x39,0xfb,0x2e,0x61,0x5e,0x66,0x84,0x71,0x83,0x65,0x22,0xcb,0xad,0x66,0xed,0xe5,0x75,0xb9,0x89,0x5a,0x7f,0x43,0x40,0xb6,0x16,0xce,0x54,0x92,0xd0,0x3a,0xcf,0xd,0xb8,0x44,0x26,0x6a,0x89,0x88,0x23,0xd5,0x9d,0x71,0x46,0xed,0xaf,0x32,0x8e,0x4a,0x9a,0xe5,0xa2,0x4,0xaf,0x94,0x77,0x80,0xc7,0xca,0x73,0xcb,0x2f,0x91,0xae,0x19,0xc6,0x10,0x71,0x9a,0x4b,0x12,0x27,0xb7,0x2a,0x17,0x8d,0x31,0xb0,0x0,0xb6,0xa7,0xd7,0x90,0x73,0xa6,0x36,0xe3,0x65,0xa6,0xd7,0xe6,0xcc,0x4d,0xba,0x16,0xce,0x1b,0x56,0x32,0x7a,0x38,0x78,0x56,0x92,0xb2,0xca,0x94,0x55,0x74,0x61,0xd8,0xf0,0x2e,0x58,0x56,0x2d,0x56,0xf5,0xa0,0xaa,0xc,0xf9,0xdc,0x9,0xe3,0x6,0x28,0x5,0xb1,0x0,0xc6,0x64,0xce,0xf1,0x8b,0x18,0xb6,0x94,0x9d,0x98,0x53,0xc2,0xa0,0xe4,0x28,0xa9,0x1d,0xe3,0x32,0xab,0x2d,0xdc,0x18,0xca,0x27,0x2c,0x0,0x9f,0x67,0x6,0x5,0x44,0xfa,0x52,0x8e,0x61,0x55,0x5b,0x16,0x56,0x9,0xd2,0xcf,0xb4,0x6f,0xd2,0x0,0x4c,0xc5,0x31,0xf4,0xfb,0x8c,0xd2,0x64,0x51,0x82,0x7e,0x6,0xe8,0x5c,0x6b,0xc8,0x3f,0xd6,0xe,0x5e,0x22,0xfb,0x88,0x9c,0xed,0x35,0xc0,0x1d,0x1d,0x1d,0xaf,0xf,0x74,0x2,0xb0,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0xe3,0x8d,0x2,0xb6,0xb0,0x8a,0xfa,0xab,0x70,0x36,0x5b,0x29,0x5,0x59,0x5a,0x78,0x59,0xfd,0x66,0xad,0x69,0xf2,0xde,0x8c,0x96,0x41,0xe4,0x9c,0x60,0x12,0x91,0x36,0xd6,0x1a,0x25,0x7,0xe9,0xed,0xbf,0x15,0xd1,0xc1,0x99,0x76,0x39,0x55,0x62,0xce,0x10,0x49,0x26,0xaa,0xbb,0x30,0x6,0xcc,0xd3,0x81,0x88,0x24,0x4b,0xaa,0x2e,0x94,0x82,0x5c,0x8a,0x66,0xed,0x11,0x81,0x65,0xb5,0x70,0x43,0x8,0xb8,0x2b,0x95,0x56,0x4c,0x86,0xd5,0x3c,0xbc,0x3,0x8c,0x31,0x94,0x5b,0x58,0x88,0x68,0x74,0x3e,0x70,0x36,0x62,0xc1,0x38,0x6c,0x11,0xe3,0xc,0x1b,0x6,0xb6,0xe3,0x4e,0x8,0xc1,0xe3,0x91,0x1b,0x27,0x78,0xfb,0x5b,0x6e,0xe1,0xd6,0x43,0xd7,0x71,0xb2,0xdd,0x60,0x18,0x2,0x96,0x25,0xe2,0xee,0xf9,0x5,0x5e,0x7c,0xe5,0xc,0xcf,0xbd,0xf0,0x32,0x5e,0xbc,0xe3,0x11,0x53,0xd1,0xb2,0x92,0x85,0xcb,0x3d,0x52,0x29,0x88,0x71,0x41,0x18,0x6,0xcd,0x9f,0xa3,0x46,0x5a,0x7a,0x9e,0x90,0x7f,0x37,0x1f,0xbc,0xe,0x53,0x32,0xa,0xb6,0x6c,0x79,0x2e,0x88,0x31,0xe2,0x95,0x3b,0x67,0xa4,0x7e,0xb4,0xdc,0x82,0xb,0x83,0x18,0x17,0x38,0xc7,0x4a,0xbf,0x4c,0xc4,0x61,0x18,0x3c,0x72,0x8a,0x78,0xf0,0xc6,0x29,0xd9,0x71,0xb9,0xfd,0x38,0xe7,0x8c,0xf3,0xdd,0x1,0xb9,0x0,0x8,0x52,0x2a,0x42,0xb6,0x5e,0x67,0x83,0x12,0x6a,0xd2,0xa2,0x1b,0xc2,0x80,0xc7,0x1f,0xb9,0x81,0x77,0x3c,0xfe,0x26,0xdc,0xbc,0x71,0x82,0xed,0x66,0x84,0x73,0x16,0x17,0xbb,0x9,0xcf,0xbf,0xf4,0xa,0xbe,0xf6,0xe7,0xcf,0xe3,0xa5,0xdb,0xe7,0xd8,0x1d,0x66,0xa0,0x24,0xb6,0xc3,0x66,0xca,0xe1,0xe3,0xf3,0xcb,0x7,0xb2,0x24,0xcf,0x87,0x3d,0x36,0x27,0xd7,0x38,0x87,0x30,0xc0,0xa0,0xc0,0x8d,0x5b,0x3d,0xa7,0x4a,0x29,0xb8,0xf5,0xe0,0x29,0xde,0x72,0xeb,0x1,0xbc,0xfd,0x2d,0x8f,0x62,0xbb,0xdd,0x60,0xf0,0xe,0xbb,0xfd,0x1e,0xb7,0xef,0x9e,0xe3,0xeb,0xcf,0xbe,0x88,0xa7,0x9f,0x7b,0x9,0x87,0x94,0x1,0x67,0x48,0x21,0xca,0x96,0x6f,0x1,0xa9,0x9,0x13,0x37,0x18,0x3b,0x94,0x14,0x1,0xb6,0xf9,0x8a,0x3a,0xb0,0xc8,0x39,0xce,0x79,0x7e,0x64,0xf5,0xa5,0xa2,0x16,0x51,0x6,0xca,0xdf,0x46,0x81,0x94,0xa8,0x14,0xae,0xb9,0x31,0x6a,0xf1,0x15,0x13,0x31,0x1a,0x15,0xad,0xd8,0x86,0x45,0x91,0x48,0xb9,0x80,0xcd,0xaf,0x3b,0xf9,0xd7,0xd1,0xd1,0xf1,0x3a,0x41,0x27,0x0,0x3b,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0x3a,0xde,0x20,0x10,0x75,0x58,0x1,0x11,0x7e,0x0,0xd3,0x13,0xc6,0xc0,0xbb,0xb0,0xca,0xba,0x73,0x8e,0x9a,0x65,0x89,0x40,0xcb,0x9a,0x5f,0x67,0xd9,0x6,0xea,0xe0,0x61,0x3,0x65,0xb8,0x19,0x2f,0x54,0x9,0xd4,0x10,0x79,0xc,0xc3,0xd,0xac,0x94,0xf9,0x47,0x85,0xe,0x62,0xf,0x85,0xb4,0xe5,0xb2,0x1a,0xd1,0x58,0x7,0xeb,0xac,0x5a,0x5a,0xc7,0xcd,0xd0,0x58,0x3d,0x47,0x6e,0xbc,0x5,0xfc,0x38,0x72,0x8e,0x9b,0xc5,0x55,0x44,0xb,0xd9,0x3c,0x49,0xe5,0x45,0x7b,0x65,0xb4,0x9,0x58,0xb2,0xf1,0x7c,0x8,0x28,0xb9,0x20,0x84,0x91,0x2d,0xc9,0x44,0xb6,0x5d,0x3f,0x19,0xf1,0x93,0x3f,0xf1,0x6e,0x7c,0xf0,0xc7,0xde,0x8d,0x5b,0x37,0x1f,0xc4,0x30,0x84,0x7b,0x36,0x1c,0x4f,0xf3,0x8c,0x97,0x5e,0xbe,0x83,0x3f,0xfd,0xc2,0x57,0xf1,0xb1,0x3f,0xfe,0x1c,0x5e,0xbe,0xbb,0x27,0x62,0x94,0x55,0x87,0x64,0x5b,0x35,0xf0,0xc6,0x22,0xc5,0x5,0x9b,0x93,0x6b,0xc8,0x29,0x21,0x97,0xc,0x6b,0x2c,0xac,0x2b,0xf8,0xaf,0x7f,0xe5,0x6f,0xe3,0xe6,0xcd,0x7,0xe5,0x40,0x1,0x6,0xf8,0xc6,0x33,0xcf,0xe1,0xbf,0xfb,0x27,0xff,0x52,0xb,0x4b,0x2c,0x9c,0x6e,0x53,0xda,0x8d,0x5d,0x53,0x3e,0xf1,0xae,0xb7,0xbf,0x19,0xff,0xd5,0xaf,0xfc,0xc7,0xa4,0xa6,0xa4,0x5a,0x5c,0xa0,0x14,0xfc,0xda,0xbf,0xfe,0x3d,0xfc,0xce,0x1f,0x7e,0x81,0x9b,0x75,0x2d,0xd9,0x75,0x73,0x52,0xb2,0x12,0x86,0x8a,0x33,0x7e,0xe6,0x3,0xef,0xc1,0xcf,0xfc,0xe4,0xfb,0x71,0xeb,0xe1,0x7,0x31,0xc,0x57,0xdb,0xba,0x63,0x8c,0x78,0xf9,0xd5,0x3b,0xf8,0xdc,0x17,0xbf,0x86,0xdf,0xff,0xe3,0xcf,0xe3,0x1b,0xcf,0xbd,0x4,0x2b,0x8a,0xd0,0x9c,0x61,0x9d,0xa9,0x24,0xaf,0xb5,0x38,0xec,0xcf,0x31,0x6e,0x4e,0xb8,0x2c,0x64,0x86,0x75,0x16,0x27,0xdb,0xd,0xfe,0xca,0xbb,0x1e,0xc7,0x47,0x3e,0xf4,0xa3,0x78,0xcb,0x9b,0x6f,0x61,0xbc,0xc7,0xd8,0xa6,0x94,0xf1,0xca,0xab,0xaf,0xe2,0x33,0x9f,0xfb,0xa,0xfe,0x9f,0xdf,0xfb,0x13,0xdc,0xbe,0x7b,0x8e,0x69,0xbf,0xe3,0x32,0x94,0x4a,0x22,0x1a,0x5b,0x50,0xa2,0x9c,0xd9,0xd4,0x3e,0x8c,0x14,0xa5,0xd2,0x17,0x29,0x2e,0x28,0xa8,0xe7,0xb4,0x6d,0xac,0xcc,0x24,0xdc,0x63,0x1b,0x30,0x17,0x9b,0x90,0x15,0x9d,0x9,0x57,0x1e,0x43,0x51,0xf9,0x49,0xc1,0x87,0xe5,0xe7,0xca,0xf1,0x22,0x9b,0x30,0x67,0xfe,0xad,0xce,0xc5,0xae,0x0,0xec,0xe8,0xe8,0x78,0x7d,0xa0,0x13,0x80,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x6f,0x10,0x68,0xe1,0x4,0xa0,0x9c,0x4,0xa9,0xb6,0x32,0x97,0x6e,0x64,0x25,0x99,0xa6,0xc3,0xe,0xce,0x5,0x2a,0xc5,0x60,0xb,0xa7,0xb4,0xe4,0x3a,0xe7,0x89,0xa8,0x83,0x51,0xdb,0xaf,0xb5,0x46,0x15,0x60,0xf7,0x82,0xe1,0x72,0xf,0x0,0x70,0xde,0x63,0x99,0x26,0x25,0x72,0x1c,0x67,0xcf,0x39,0x47,0xf6,0xd4,0x94,0x16,0xb5,0x6e,0x52,0xbe,0xdc,0xa2,0xed,0xc1,0x42,0x12,0x8a,0xea,0x4b,0xac,0xc2,0x57,0x7d,0x5e,0xb2,0xf4,0x26,0x2c,0xf3,0x84,0xc8,0xed,0xbd,0x25,0x27,0xca,0x88,0x1b,0xb7,0x4c,0xfc,0x90,0xca,0xab,0x94,0x8c,0xc1,0x8f,0xf8,0xf9,0xf,0xff,0x28,0x7e,0xfa,0xa9,0x1f,0xc5,0x8d,0xeb,0xd7,0xee,0x49,0xfa,0xb5,0x18,0x87,0x1,0x8f,0x3f,0x76,0xb,0x8f,0x3f,0x76,0xb,0x1f,0xfd,0xf0,0xfb,0xf1,0x47,0x9f,0xfa,0x1c,0x7e,0xe3,0xdf,0xfe,0x9,0xce,0xf6,0x13,0x4a,0x21,0x5,0x62,0x8a,0xd4,0x56,0x3b,0x6c,0xb6,0x98,0xa7,0x3,0x60,0x0,0x67,0x3d,0x93,0x94,0x6,0x9b,0xcd,0x88,0xed,0x66,0x5c,0xbf,0xef,0x38,0x6a,0xa6,0xdf,0xb2,0xcc,0xda,0xcc,0x2c,0xa5,0x28,0x61,0xe0,0xc,0x3e,0xce,0x67,0xf4,0xde,0x63,0xbb,0xdd,0xa8,0x9d,0x57,0x6f,0xfa,0x58,0x61,0xe9,0x7c,0x50,0x2,0xd6,0xb2,0xda,0xd3,0x58,0x8b,0x7,0xae,0x5f,0xc3,0xdf,0xff,0xeb,0x1f,0xc6,0x8f,0xbc,0xfb,0x87,0x2f,0xbd,0xf6,0xd2,0xd,0xa4,0xf7,0x78,0xf4,0xd6,0xc3,0x78,0xf4,0xd6,0xc3,0xf8,0xc8,0x53,0xef,0xc7,0x67,0x3e,0xfb,0x45,0xfc,0xf3,0xdf,0xf8,0x3d,0x5c,0x1c,0x24,0x4f,0x51,0x72,0xf2,0x28,0x23,0x52,0x32,0x1,0xc1,0xb9,0x8b,0xef,0x78,0xec,0x61,0xfc,0xbd,0x5f,0xfa,0x28,0xde,0xf6,0xd6,0x37,0xc3,0x7e,0x9b,0xb1,0x75,0xce,0xe2,0xd6,0x23,0xf,0xe3,0xe7,0x7f,0xf6,0x61,0x3c,0xf5,0x81,0x1f,0xc1,0xff,0xf9,0x6b,0xbf,0x85,0x8f,0xfd,0xc9,0x17,0x55,0xd1,0x89,0xa6,0xd5,0x18,0x80,0x5a,0xa7,0xa5,0x30,0x46,0xca,0x3f,0x2c,0x5b,0xa0,0xc5,0xae,0xae,0xe4,0xdf,0xea,0xef,0x80,0x73,0x1,0x4b,0x2d,0xc8,0x1,0xff,0x4d,0xa8,0x12,0x50,0xce,0x6d,0x43,0xa4,0x38,0x35,0x1f,0xb3,0x35,0x9d,0xdf,0x2e,0xeb,0xf9,0x2f,0x7f,0x6b,0x9d,0xfc,0xeb,0xe8,0xe8,0x78,0x7d,0xa0,0x13,0x80,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x6f,0x10,0x90,0x62,0xa9,0x2d,0x2b,0xa0,0xff,0x36,0xd6,0x21,0x31,0x59,0x2,0x54,0x75,0x99,0x10,0x72,0xb9,0x21,0x59,0xa4,0xbc,0x3,0x0,0x12,0x5b,0x83,0xa9,0x5d,0x18,0xb0,0xde,0xe1,0x5e,0x84,0x87,0x64,0xd2,0x39,0xe7,0x50,0xac,0xc5,0x74,0x76,0x41,0x79,0x6d,0xb,0x65,0xdd,0x79,0xcf,0xe5,0x19,0xc3,0x80,0x52,0x0,0xef,0x7,0x56,0x95,0x51,0x33,0xb1,0xf3,0x9e,0x89,0x40,0xca,0xec,0x23,0xd2,0xcf,0x5e,0x22,0x72,0xae,0xda,0x2e,0x29,0xa,0x1d,0xe2,0x61,0xc7,0x2a,0x44,0xb2,0x39,0xb,0x79,0xe6,0xc3,0x0,0x3,0x83,0x47,0x6f,0xdd,0xc4,0x3f,0xf8,0xe5,0x9f,0xc1,0xf,0xbd,0xfd,0x2d,0xdf,0x11,0xf1,0x77,0x15,0x4e,0x4f,0x4e,0xf0,0x73,0x3f,0xf5,0x14,0xde,0xf3,0xe4,0x13,0xf8,0xe7,0xbf,0xf6,0x6f,0xf0,0xa5,0x67,0x5e,0x20,0x25,0x20,0x17,0x6a,0x0,0x85,0xf2,0xff,0xd8,0x8a,0x9b,0x73,0xc2,0x38,0x6e,0xee,0xf9,0x7e,0xb,0xab,0xff,0xc,0xc,0x13,0xa3,0x44,0xe0,0x8d,0xe3,0x6,0x71,0x59,0xf8,0xf3,0xd9,0x86,0xe8,0xba,0x62,0xc,0xbc,0xaf,0x64,0x21,0x93,0x71,0x99,0xed,0xc8,0x83,0xf,0xf8,0x7,0x7f,0xe3,0xa7,0xf0,0xa3,0xef,0xfe,0xa1,0xef,0xfa,0xb3,0x6e,0x36,0x23,0x9e,0xfa,0xe0,0xfb,0xf0,0xbb,0x9f,0xf8,0x53,0x7c,0xe5,0xd9,0x17,0xe1,0x9d,0x41,0xc9,0xa4,0x26,0x34,0x7c,0xde,0x48,0x5e,0xa4,0xf3,0x1,0x3f,0xfe,0xde,0x77,0xe0,0xef,0xfc,0xe2,0x4f,0xe1,0xf4,0x64,0xfb,0x5d,0x6f,0xeb,0x81,0x1b,0xd7,0xf1,0x2b,0xff,0xc9,0xdf,0xc4,0x8d,0x6b,0xa7,0xf8,0xcd,0xdf,0xff,0x14,0xe2,0x3c,0x2b,0xa9,0x9a,0xb,0x65,0x15,0x1e,0xf6,0x3b,0x22,0x43,0x39,0x9f,0x52,0xf2,0xfd,0x80,0xc2,0x36,0x71,0xd4,0x72,0xf,0x2e,0xfa,0x10,0x95,0x5f,0xc9,0x40,0xe1,0xd7,0xc8,0xb9,0x24,0xe7,0x0,0xd9,0x7a,0xe9,0x41,0x6a,0xa8,0x66,0xb5,0xa1,0x3c,0xde,0x58,0x80,0xf5,0x4f,0xb,0xdf,0xce,0x12,0xdf,0xd1,0xd1,0xd1,0xf1,0x97,0x8b,0x4e,0x0,0x76,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0xbc,0x41,0x20,0xa4,0x1e,0x0,0x2e,0x5f,0x70,0xb0,0x39,0xa1,0xb0,0xa5,0x11,0x40,0xcd,0x0,0x74,0x8e,0x32,0xf8,0x50,0x1b,0x72,0x1,0xf0,0x73,0xc9,0xb2,0xb,0x80,0x2d,0x93,0x50,0x92,0xea,0x5e,0x70,0x16,0x78,0xd3,0x43,0xd7,0xb1,0x4c,0x7,0x0,0xc0,0xb2,0xa1,0x46,0xdb,0x14,0x23,0xbf,0x97,0x81,0xf,0x27,0x70,0x7e,0xe0,0xed,0x0,0x21,0x8c,0x48,0x69,0x1,0x8c,0x83,0x35,0x64,0xb3,0x74,0x6e,0x3,0x63,0x1d,0x32,0x97,0x4e,0xf8,0x10,0xf0,0xf0,0x8d,0xd3,0x7b,0x92,0x2d,0x39,0xb3,0x82,0xcb,0x18,0xc,0x5c,0x4a,0x1,0x3,0x78,0x17,0xe0,0x43,0xe0,0x3c,0x3c,0x83,0xc7,0x1f,0xb9,0x8e,0xff,0xe2,0xef,0xfd,0x35,0xbc,0xe9,0x91,0x9b,0xff,0x1f,0x7b,0xef,0x15,0x2c,0x5b,0x76,0x9e,0x87,0x7d,0x2b,0xed,0xdd,0xdd,0xe7,0xdc,0x38,0x79,0x30,0x39,0x62,0x80,0x19,0x24,0x22,0x88,0x4,0x48,0x81,0x14,0x68,0x1,0x10,0xb3,0x29,0x9a,0x34,0x6d,0x52,0x2e,0xc9,0x32,0x4b,0x55,0x2c,0xdb,0x8f,0x2e,0xbf,0xf8,0xc9,0xaf,0x72,0x49,0x65,0xab,0xca,0x2e,0x8a,0xb6,0x44,0xca,0x34,0x3,0x48,0xa,0x4,0x41,0x82,0x0,0x18,0x90,0x89,0xcc,0x21,0xd2,0x60,0x30,0x39,0xdc,0x3b,0x33,0x37,0x9d,0xd0,0xbd,0xf7,0x5e,0xc9,0xf,0xff,0xbf,0xd6,0xde,0x7d,0x4e,0x9f,0x41,0xa0,0x41,0x9e,0xf2,0xfd,0xbf,0xaa,0x99,0x7b,0x4f,0x77,0xef,0xb0,0xd6,0x5e,0xdd,0xe7,0xee,0xaf,0xbf,0xf0,0xff,0xc9,0x5c,0xdf,0x70,0xdd,0x35,0xf8,0xa7,0x3f,0xfb,0x6e,0xfc,0xc6,0xef,0x7f,0x8,0x9f,0xfb,0xea,0x13,0x30,0xd6,0x22,0x27,0xca,0x3,0x4,0x50,0xcb,0x3b,0xda,0xd9,0x1c,0xf6,0x28,0xd5,0x9d,0x2,0x59,0x88,0xad,0x85,0x31,0x16,0x31,0xb2,0xca,0x8e,0x73,0x5,0x4b,0xb9,0x8,0x52,0x42,0x33,0x5f,0x30,0xc1,0xab,0x36,0xee,0x48,0x29,0xf0,0x7e,0xc6,0x96,0x63,0xad,0x35,0xde,0xf4,0xea,0x3b,0xf1,0xca,0x7b,0x6e,0xff,0x8e,0xc7,0x59,0x2c,0xb7,0x9a,0xad,0xc5,0x5a,0x93,0xea,0xb2,0x64,0x33,0x52,0x9,0x87,0xc6,0x6b,0xee,0xbe,0x9,0x3f,0xfd,0xae,0xb7,0xa1,0x6d,0x9b,0xef,0xf8,0x58,0xd6,0x5a,0xfc,0xf8,0x3b,0xdf,0x8e,0x4b,0x57,0xf6,0xf0,0x97,0x7f,0xfd,0x28,0xd9,0xd8,0x33,0x11,0x71,0x29,0x45,0x22,0x86,0xb5,0x62,0x62,0xd0,0xb2,0x15,0x19,0x50,0xd0,0x50,0x48,0xa3,0x22,0xb0,0xbc,0xf,0x12,0xb5,0x29,0x2b,0xa5,0xa1,0xd,0xaa,0xc2,0xb5,0x94,0x80,0xac,0xb5,0xf9,0xf2,0x1f,0x29,0xa5,0x9,0xe1,0xc7,0xef,0x19,0xae,0x9,0xce,0x19,0x6b,0xa5,0x20,0xea,0x9b,0xa8,0x29,0x5,0x2,0x81,0xe0,0x6f,0x13,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0x9,0x8a,0xea,0x8b,0x32,0xcb,0x48,0x19,0x55,0xa,0x40,0x14,0xd8,0xa2,0x5b,0xcb,0xc,0x12,0xbc,0xf7,0xb0,0x4d,0x53,0x9b,0x5a,0x15,0x2b,0xee,0xc8,0x46,0x9b,0xa0,0x38,0x2f,0xd0,0x3a,0x4b,0x4,0xe1,0x1,0x15,0xd4,0x14,0xf,0xbd,0xf2,0x2e,0xbc,0xea,0xde,0x3b,0x38,0xb3,0x8d,0xcb,0x12,0x54,0xad,0x58,0x20,0x21,0x15,0xdb,0x88,0xb,0x91,0x58,0xac,0xb9,0x64,0xb3,0x4c,0xb5,0x7d,0xb5,0xd8,0x86,0xa9,0x9b,0x81,0x88,0x18,0x6b,0x36,0x93,0x2d,0xd6,0x39,0xb6,0x7c,0x6a,0x2e,0x90,0xa0,0x3c,0x43,0xe4,0x8c,0xcc,0x96,0xd8,0x6b,0x4f,0x6d,0xe3,0x9f,0xfc,0xe3,0x77,0xe2,0xba,0x6b,0x4e,0x6f,0x9e,0xb7,0x94,0xb1,0xb3,0xb7,0x8f,0x17,0x5e,0xba,0x84,0x97,0x2e,0x5e,0x41,0xdf,0xf7,0xd8,0xda,0x5a,0xe0,0xda,0x33,0x27,0x70,0xfd,0xb5,0x67,0xb1,0xb5,0x98,0x6f,0x1c,0xf7,0x7c,0xd6,0xe2,0x67,0x7e,0xe4,0xed,0xe8,0x87,0xf,0xe2,0xcb,0x4f,0x3c,0xcf,0x6a,0x3d,0x5,0x6b,0x9b,0xda,0x88,0x1c,0x43,0x80,0x76,0x9b,0x33,0xf0,0xca,0xb5,0xf0,0x43,0xcf,0xf6,0x55,0xd,0x3f,0xf4,0x58,0x6c,0x9f,0x44,0x8c,0x81,0x88,0xb6,0x62,0x99,0xe,0x1,0x19,0xba,0x92,0x51,0x6b,0xfb,0x61,0xc2,0xcf,0x58,0x5b,0x93,0x1a,0xad,0x73,0x70,0xce,0xe1,0xef,0xbd,0xfe,0x95,0x1b,0x6d,0xbf,0xab,0xae,0xc7,0x97,0x1f,0x79,0x2,0xcf,0x9e,0x7b,0x9,0x21,0x46,0x9c,0xdc,0x9a,0xe1,0xb6,0x57,0xdc,0x88,0x1b,0xae,0x3b,0xb3,0x66,0x8d,0x2e,0xe4,0xaa,0x31,0xb6,0x66,0x48,0x52,0x7b,0xb2,0x47,0xd3,0x92,0xea,0xf1,0xa6,0x6b,0x4e,0xe0,0x27,0xdf,0xb9,0x99,0xfc,0x8b,0x31,0xe1,0xfc,0x8b,0x17,0xf1,0xe8,0x13,0xcf,0xe0,0xfc,0x85,0x2b,0x18,0x6,0x8f,0xed,0xad,0x5,0xee,0xbc,0xf5,0x6,0xdc,0x73,0xc7,0x2b,0xb0,0x98,0xaf,0xab,0x23,0x9d,0xb3,0xf8,0xc9,0x77,0xfd,0x7d,0x3c,0xfa,0xd4,0x39,0x5c,0xb8,0x9c,0xa8,0xa8,0xa5,0x69,0x11,0x7c,0x8f,0xae,0xef,0xa8,0x4d,0x18,0x44,0x4c,0xf,0x43,0x7,0xd7,0xb4,0xb4,0x7c,0x22,0x59,0x84,0x43,0xf0,0x0,0x37,0x3d,0x2b,0xcd,0x65,0x20,0x5c,0x8c,0x53,0x88,0x41,0xa5,0xa6,0x76,0x5f,0x55,0x95,0x83,0xb9,0x2c,0x54,0xce,0x57,0xcc,0x6c,0xfd,0xa5,0x98,0x40,0x26,0x1,0xcb,0x9c,0x23,0x4b,0xb,0xb0,0x40,0x20,0x38,0x56,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0xb8,0x4a,0xa0,0x8c,0x61,0xd2,0x8c,0x40,0x64,0x9c,0x86,0xce,0xaa,0xaa,0xc7,0x8a,0xc2,0x8f,0x88,0x3e,0xcb,0x12,0x2f,0xc5,0xb6,0x4a,0x22,0xad,0x2,0x6,0x34,0xed,0x8c,0x4a,0x28,0x58,0x25,0x58,0xd4,0x53,0x99,0x15,0x86,0x7,0xa1,0xb5,0xfe,0xa6,0xf9,0x72,0x2f,0xf,0xf3,0x9d,0x8d,0x59,0x69,0xb8,0x66,0x86,0x6e,0xb9,0x47,0x24,0x1a,0x93,0x53,0xa5,0x99,0x76,0x36,0x3b,0x81,0x9f,0xfd,0xd1,0xbf,0xbf,0x91,0xfc,0xcb,0x39,0xe3,0xf9,0xf3,0x2f,0xe2,0xcf,0x3f,0xf5,0x30,0xfe,0xfa,0x1b,0xcf,0xa1,0xf,0x89,0xc9,0x38,0x5d,0x1b,0x92,0x4f,0x2e,0x66,0x78,0xcd,0xbd,0xb7,0xe0,0xfb,0xdf,0xfc,0xd0,0xc6,0x7d,0x6c,0x6d,0x2d,0xf0,0x9f,0xbe,0xfb,0xfb,0xf1,0xfc,0xaf,0xbd,0x1f,0x97,0x77,0xf9,0x1c,0xd8,0x76,0x9c,0x73,0x1a,0xb3,0xec,0xf2,0xd1,0xe7,0xaf,0xd,0x29,0xf7,0x74,0xb1,0x32,0x7,0xcf,0xf3,0x59,0xb2,0x10,0x3,0x5c,0x3b,0x83,0xb5,0x76,0x53,0x14,0xe2,0xd8,0xe2,0x9c,0x88,0x3c,0x35,0xc6,0xc0,0xb9,0x6,0xad,0x1,0xae,0xbf,0xe6,0xcc,0xa1,0xd7,0xef,0x2f,0x3b,0xfc,0xca,0x6f,0x7d,0x0,0x4f,0x9d,0xbb,0x58,0x1f,0x4b,0x39,0x21,0xa7,0x87,0xb1,0x98,0xb7,0x78,0xed,0x3d,0xaf,0xc0,0x5b,0x5e,0xf7,0x4a,0xdc,0x72,0xf3,0xd,0x3c,0x4f,0x9c,0x2f,0x98,0xa8,0x8d,0xb7,0x9d,0x91,0x1a,0x31,0xc6,0x0,0xa3,0x35,0xde,0xf5,0x3,0xaf,0xc7,0xc9,0x13,0xdb,0x87,0x8e,0x73,0xe9,0xf2,0x2e,0x7e,0xf7,0x8f,0x3f,0x8a,0xaf,0x3c,0xf9,0x62,0xe5,0x2c,0x33,0x97,0xba,0x7c,0xe4,0xf3,0x8f,0xe0,0xf4,0x56,0x83,0xff,0xec,0x1f,0xfd,0x0,0xee,0xbd,0xf3,0x96,0xb5,0xed,0xae,0xbd,0xe6,0xc,0xde,0xf1,0xd6,0xd7,0xe2,0x37,0xdf,0xff,0x31,0x6a,0x57,0x66,0x32,0xb5,0x99,0xcd,0xc6,0x16,0x5e,0xa5,0xd0,0xb4,0x73,0x22,0x7f,0x81,0x3a,0x6f,0xc6,0xd0,0x7c,0x95,0x16,0xe9,0x42,0x82,0x2b,0xa5,0x28,0xbf,0x4f,0x1,0xc0,0xa8,0xee,0xa3,0x7d,0x95,0xea,0x8f,0xa9,0x7d,0x9e,0x1f,0xc9,0x8a,0xb7,0x39,0x4a,0xfd,0x2a,0xe4,0x9f,0x40,0x20,0x38,0x1e,0x10,0x4d,0xb2,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x95,0x20,0x85,0x80,0x35,0x5f,0x63,0xce,0x54,0xaa,0xa1,0x34,0x0,0x22,0xf8,0x34,0xab,0x0,0x33,0x37,0x9b,0x96,0x62,0x8f,0x18,0x42,0x6d,0xeb,0x2d,0x8d,0xaf,0x39,0x93,0x92,0x2a,0x83,0x5e,0x53,0xca,0x39,0x8e,0xf,0x88,0xd4,0x29,0x5,0xf,0x5a,0x6b,0xf4,0x1d,0xb5,0x0,0x37,0xb3,0x5,0xb4,0xb1,0x78,0xeb,0xeb,0xef,0xc5,0xfd,0x77,0x1f,0xb6,0xc0,0xe6,0x9c,0xf1,0xd9,0x87,0x1f,0xc1,0xbf,0xf9,0x7f,0x3e,0x84,0xcf,0x7f,0xfd,0x39,0xec,0xed,0x2f,0x2b,0x69,0x18,0x63,0x24,0x45,0x22,0x80,0x9d,0xfd,0x15,0x3e,0xf1,0xf0,0xe3,0xf8,0xd7,0xbf,0xf6,0x7e,0x7c,0xfa,0x8b,0x5f,0x45,0x4a,0x87,0x9,0x9f,0x6b,0xcf,0x9e,0xc1,0x3b,0xdf,0xf6,0x1a,0x68,0x4d,0x85,0x1e,0xba,0x14,0x98,0x28,0x5,0xd7,0xcc,0x26,0x85,0x12,0x7,0xce,0x9e,0x95,0x97,0xd,0xe7,0xf7,0xf5,0xdd,0xaa,0xaa,0xf9,0xc8,0xe,0x6d,0xa0,0xb5,0x26,0x2b,0x70,0x69,0xa4,0xc5,0x46,0x6,0x90,0x49,0x40,0xcd,0xd,0xba,0xa,0x21,0x78,0x9c,0x3e,0xb9,0xd,0xeb,0xe,0x6b,0x42,0x1e,0x7f,0xea,0x39,0x3c,0xfb,0xd2,0xe,0x91,0x60,0x4a,0x4d,0x72,0xf1,0x32,0xba,0xde,0xe3,0xe3,0x7f,0xf5,0x28,0xfe,0xe5,0xff,0xf5,0x5e,0xfc,0xda,0xef,0xbc,0x1f,0xcf,0x9f,0x7f,0x1,0x64,0x7f,0x25,0xcb,0xec,0x6c,0xb1,0xcd,0xdb,0x69,0xb8,0xa6,0xc5,0x3d,0xb7,0xdd,0x80,0xfb,0x37,0x58,0x8c,0x2f,0x5d,0xd9,0xc5,0xaf,0xfc,0xf6,0x7,0xf1,0xd5,0xa7,0x2f,0xd4,0xb1,0x2b,0x8c,0xeb,0x2a,0xa5,0x84,0xcb,0xfb,0x1e,0xbf,0xf2,0xdb,0x1f,0xc2,0x37,0x9e,0x78,0xf6,0xd0,0xf6,0x6f,0x7e,0xfd,0x43,0x58,0xb4,0xe,0x7e,0xe8,0xc7,0x66,0x5e,0x6d,0x2a,0x11,0x59,0x14,0x8a,0xc6,0x58,0x6a,0x3a,0xe6,0xf5,0x99,0xf3,0xa8,0x74,0x85,0x1a,0x49,0xf0,0x62,0x29,0xaf,0x56,0xf8,0xd2,0x92,0x9d,0x53,0x7d,0x3f,0x68,0x6d,0xf8,0x7d,0x43,0xc7,0xab,0x6c,0xeb,0x94,0x38,0xe4,0xa7,0x84,0xf7,0x13,0x8,0x4,0xc7,0xd,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0x9,0xa,0x71,0x54,0xa1,0xa8,0x58,0x82,0x1c,0xb6,0x91,0x8,0x3e,0x3d,0xe6,0x9a,0x29,0x85,0x35,0xd5,0xde,0x54,0xdd,0xe7,0x5c,0x3,0xc5,0xaa,0x32,0xa5,0x34,0x52,0x8a,0x8,0x7e,0xc0,0x71,0x62,0x3e,0x28,0x9f,0x30,0x12,0x31,0xc4,0xa5,0x14,0xed,0x6c,0x51,0xc7,0xd9,0x5a,0x85,0x1f,0x78,0xf3,0x6b,0x36,0x2a,0x13,0xbf,0xf8,0xe5,0x6f,0xe0,0x37,0xde,0xff,0x9,0xec,0xed,0xed,0x63,0xe8,0x3a,0x26,0x10,0xa9,0xf9,0xd8,0xb9,0xa6,0x5a,0x45,0x5d,0xd3,0x22,0xa5,0x88,0x55,0xef,0xf1,0xdb,0x7f,0xf2,0x69,0x7c,0xfe,0xaf,0x1f,0x39,0x94,0x47,0xa8,0x14,0xf0,0xba,0x57,0xdf,0x87,0x1b,0xce,0x9e,0xa4,0xb6,0xe5,0x18,0xd1,0xb4,0x73,0x68,0x63,0x31,0xf4,0x2b,0xcc,0xda,0xd9,0x84,0xc0,0x5b,0xdb,0x12,0x39,0x27,0x4,0x4f,0x85,0x17,0x4d,0x3b,0x23,0xcb,0x76,0x8c,0xb0,0x96,0xc6,0x93,0x62,0x64,0x55,0x63,0x60,0xd5,0xda,0xe1,0xf9,0xd7,0x5a,0xc3,0x38,0x57,0x8b,0x4f,0xa8,0x4,0x24,0x10,0x39,0xba,0x41,0xb1,0x79,0xfa,0xd4,0x9,0x58,0xa3,0x27,0x8d,0xcf,0x1a,0x4d,0x3b,0x83,0xb1,0x8e,0xc7,0x43,0x76,0xf0,0x2f,0x3c,0x7a,0xe,0xff,0xea,0xdf,0xff,0x21,0x9e,0xbd,0xb0,0x77,0xc0,0x62,0x4d,0xe7,0xa7,0xb5,0xc6,0xdb,0xde,0xf0,0x4a,0x98,0x3,0xf3,0x1b,0x53,0xc2,0xfb,0x3e,0xf4,0x29,0x9c,0xbb,0xb0,0xc3,0x76,0x5b,0x22,0xe5,0x8c,0x73,0x55,0x1d,0x69,0x8c,0x5,0x14,0xd0,0xfb,0x80,0xf7,0x7e,0xf8,0x53,0x18,0x7c,0x58,0xdb,0xc7,0xc9,0x13,0x5b,0x78,0xf0,0x9e,0x5b,0x61,0x5d,0x8b,0xa2,0xe2,0xcb,0x3c,0x2e,0x52,0x4a,0x52,0x6,0x60,0xb1,0x7c,0x17,0xdb,0x3a,0xad,0x89,0xc0,0xeb,0x63,0x5c,0xd7,0xa,0xac,0x72,0xc4,0x48,0xa,0x16,0x25,0x60,0xc9,0xf2,0x4b,0xb5,0x44,0x27,0xaf,0xbd,0x47,0xc8,0x8e,0xce,0xd6,0x79,0x7a,0xa6,0x92,0x8b,0x2,0x81,0x40,0x70,0x5c,0x20,0x4,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x95,0xa0,0x90,0x1a,0xc0,0x54,0xe1,0x34,0x92,0x14,0x35,0x1f,0xf,0xdc,0x76,0x9a,0x41,0x24,0xa,0x2b,0xfc,0xea,0x7e,0x38,0x97,0x2e,0xfa,0x1,0x29,0x47,0x56,0x1,0x96,0xa6,0x5f,0x75,0x7c,0xc6,0xab,0x14,0x8c,0xa5,0x9c,0x42,0x52,0x82,0x4d,0x5a,0x5a,0x73,0xc6,0xeb,0x5f,0x75,0xf,0x6e,0xb8,0xfe,0xda,0x43,0xdb,0xbd,0xf0,0xd2,0x25,0xfc,0xe6,0xfb,0x3f,0x86,0xc,0xc0,0x87,0x81,0x55,0x8f,0x34,0x77,0x29,0x5,0x78,0x3f,0x54,0xbb,0x73,0xc,0x9e,0x54,0x6b,0xc8,0x8,0x31,0xe2,0x3d,0x1f,0xfa,0xc,0x9e,0x79,0xfe,0x85,0x43,0xfb,0x9c,0xcf,0x1a,0xbc,0xe5,0xa1,0x7b,0x90,0xb9,0xac,0x22,0xb1,0x62,0xae,0x69,0xe7,0xf0,0x21,0x6c,0x2c,0x50,0xc9,0x39,0xa1,0xe5,0xf6,0x60,0xd7,0xce,0x90,0x52,0x44,0x33,0x9b,0x53,0x11,0x8,0xa8,0x20,0x44,0x6b,0xca,0xb0,0xa3,0xeb,0x95,0x36,0xd3,0xaf,0x4a,0x23,0x7a,0x5f,0x55,0x80,0x54,0xf2,0x62,0x71,0x79,0x77,0x89,0xae,0xf7,0x87,0x5e,0x7e,0xcb,0x4d,0xd7,0xe1,0xa7,0x7f,0xf8,0xcd,0x30,0x9a,0xc8,0x4a,0x3f,0xc,0x9c,0x39,0x48,0x24,0xaf,0x52,0xa8,0x2a,0xbb,0xde,0x7,0x56,0x55,0xe6,0x4a,0xa4,0x1a,0x6e,0x74,0x9e,0x3b,0x8d,0xdb,0x6f,0xb9,0xf1,0xd0,0xfe,0x9f,0x7b,0xfe,0x45,0x7c,0xe9,0xa9,0x97,0x0,0x45,0x65,0x28,0xae,0x69,0xa0,0x15,0x9d,0x97,0x65,0x85,0x65,0x4a,0xb1,0xee,0xeb,0xe9,0x17,0xae,0xe0,0xa9,0x67,0x9e,0x3f,0x74,0x6d,0x5f,0xf3,0xc0,0xdd,0x1c,0xc7,0x47,0xc7,0xd5,0x9c,0x49,0xa9,0xb5,0x26,0x22,0xb0,0x92,0x77,0x19,0xc1,0xf7,0x75,0x3b,0x6d,0x2c,0x2b,0x4,0xd9,0x7e,0x8d,0xb1,0xd,0x18,0xfc,0xa7,0x82,0xaa,0xd6,0x60,0x5,0xc5,0xe4,0xef,0x78,0x6c,0xa0,0x74,0x81,0xe4,0xfa,0x1e,0x1a,0x33,0x2,0xe9,0xf,0x21,0x0,0x5,0x2,0xc1,0x71,0x82,0x64,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0xd,0xc6,0x36,0x3,0xa5,0x34,0x52,0xf4,0x64,0x7,0xf5,0x3,0x29,0xb0,0x58,0x35,0x65,0x8c,0x3,0x94,0xaa,0x6a,0x2a,0xa4,0xc,0xe5,0x48,0xf5,0x15,0xfc,0x80,0x66,0x36,0xaf,0xcd,0xbd,0x60,0xa2,0xa4,0xaa,0xe8,0xf2,0xe6,0xc,0xc0,0x27,0x9e,0x39,0x8f,0x47,0x9f,0x78,0xb6,0x12,0x66,0x29,0x7a,0x6e,0x70,0x8d,0xd4,0x46,0xcc,0xe4,0x61,0x29,0x8,0xb1,0xae,0x45,0x4a,0xa1,0x5a,0x50,0xb5,0xd6,0x48,0x29,0x91,0xb2,0x2b,0xc,0xac,0xf0,0x22,0x6b,0xef,0xa2,0x6d,0xf0,0xbd,0xdf,0xf3,0xaa,0x8d,0x4a,0xbe,0xcc,0x4a,0xbd,0xbe,0x5f,0x21,0x3,0x8,0x61,0x40,0xd3,0xcc,0x90,0x91,0xf1,0xe6,0xd7,0x3d,0x70,0xa8,0x7c,0x23,0xe7,0x8c,0x8f,0x7c,0xfa,0xaf,0xb1,0x1a,0x2,0xa0,0x80,0xa6,0x69,0xb9,0x44,0x44,0xd5,0x9c,0x43,0xad,0x35,0xfc,0x30,0x60,0xbe,0xd8,0xae,0xea,0x30,0xb2,0xe2,0x3a,0x84,0x9c,0xf0,0x91,0xcf,0x7c,0x5,0x3f,0xfb,0x23,0xd7,0xaf,0x11,0x8e,0x0,0x70,0xff,0xdd,0xb7,0xe2,0x8f,0x3e,0xf1,0xd7,0x44,0x20,0x6a,0x53,0xcb,0x4c,0xb4,0x36,0xc0,0x11,0xe5,0x29,0x65,0xcc,0x39,0x67,0x34,0x4d,0xcb,0x2a,0x34,0x6a,0x4f,0x56,0xd6,0x4d,0x2c,0xaf,0x9a,0xc9,0xaa,0xd,0xfb,0xe0,0xe6,0x61,0xa5,0x35,0x34,0xc,0x59,0xa2,0x41,0xe4,0xdd,0x97,0xbe,0xf6,0x28,0xbe,0xf7,0x8d,0xaf,0x39,0xb4,0xcd,0xeb,0x5e,0x7d,0xf,0x4e,0x9d,0x58,0xe0,0x3d,0x1f,0xf8,0x14,0xce,0x5f,0xda,0x45,0x8a,0x11,0x39,0xb1,0x8d,0x96,0xff,0x4c,0x29,0x42,0x41,0x71,0xf6,0xde,0xd8,0xfc,0x6b,0x8c,0x41,0xd6,0xa,0xb7,0xde,0x70,0xe6,0x50,0x89,0x7,0x0,0x7c,0xee,0xcb,0x8f,0x1,0xa0,0x79,0xc,0xc1,0x23,0xc,0x3,0x65,0x13,0x5a,0x2a,0x6c,0xa1,0x92,0x14,0xf,0xcd,0xa,0xc8,0x94,0x22,0x1e,0x7d,0xe2,0x59,0xdc,0x73,0xe7,0xad,0x6b,0xfb,0xb9,0xfd,0xb6,0x57,0xf0,0xa,0xa4,0x82,0xf,0x3f,0xf4,0x80,0x2,0x7c,0x3f,0x54,0x32,0x90,0x8,0x3d,0xd,0xa5,0x32,0x2b,0x14,0x33,0x72,0x8e,0xe0,0x9e,0x5e,0x5e,0x7f,0x9a,0x3a,0x66,0x94,0xa2,0xf9,0x9d,0x90,0x83,0x89,0x95,0xb1,0x23,0xb3,0xaa,0xd6,0x49,0x73,0x94,0x97,0xf2,0xe3,0x19,0xf5,0x5a,0x1e,0x55,0x88,0x23,0x10,0x8,0x4,0x7f,0x17,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0xb8,0x4a,0x90,0x62,0x64,0x95,0x18,0xb7,0x0,0x2b,0x45,0x99,0x67,0xd6,0xd5,0x66,0x60,0xad,0x34,0x11,0x6f,0x89,0xed,0xc0,0x6a,0x24,0x37,0xb4,0x66,0xcb,0x70,0x26,0x62,0x8d,0x48,0x40,0x80,0xe5,0x4e,0xac,0x84,0xdb,0x8c,0x97,0x2e,0x5c,0xc6,0xfb,0xfe,0xe2,0xf3,0x0,0x80,0xbe,0x5b,0x2,0x0,0xf6,0x77,0x2f,0x3,0x99,0x88,0x1f,0xad,0x29,0x33,0x4e,0x69,0xb2,0x9b,0x2a,0x45,0x8a,0x36,0x6a,0xce,0xd5,0x9c,0x99,0xa7,0x61,0xac,0x85,0x73,0x2d,0x37,0x17,0x53,0x46,0xde,0xb5,0x27,0x5a,0xbc,0xe5,0xf5,0xf,0xe0,0x20,0xff,0x57,0x14,0x5a,0x40,0x26,0xfb,0x6a,0xc,0x40,0xce,0xf0,0xbe,0x87,0x33,0x1a,0x37,0xdd,0x70,0xcd,0xa1,0xf3,0xdc,0x5f,0xae,0xf0,0xa5,0xc7,0xce,0x11,0xc1,0x15,0x23,0x7c,0x18,0xa0,0xa0,0x10,0x13,0x91,0x46,0xc6,0x18,0x4,0x3f,0xc0,0x31,0x89,0x98,0x23,0x91,0x94,0x7e,0xe8,0x61,0xe6,0x64,0x33,0xfd,0xca,0xe3,0xe7,0x70,0xf1,0xd2,0x15,0x5c,0x7b,0xa0,0x14,0xe4,0xec,0xe9,0x93,0x38,0xb9,0x98,0x61,0xb7,0xb3,0x88,0x31,0x54,0x52,0xc9,0xf,0x3,0x59,0xb0,0xf,0x40,0x6b,0xc3,0xb9,0x73,0x1e,0x5a,0x2b,0x74,0xdd,0x12,0xc6,0x5a,0x68,0x63,0xe0,0x87,0x1e,0xd6,0x3a,0x84,0xe0,0xe1,0x5c,0x3b,0xb1,0x9c,0x1e,0x26,0x9d,0xb4,0x31,0x88,0x31,0x10,0xf9,0xc7,0x44,0x9d,0x52,0x1a,0x31,0x6,0x7c,0xfc,0x8b,0x8f,0xe1,0xa1,0x7,0xee,0xc5,0xf6,0xd6,0xfc,0xd0,0xdc,0xdd,0x75,0xdb,0xcd,0xf8,0xa5,0x9f,0x7b,0x27,0xfe,0xec,0x93,0x5f,0xc4,0x27,0x1f,0x7e,0x1c,0xfd,0xe0,0x2b,0x31,0x5c,0x88,0x63,0xd7,0xb4,0xdc,0xa8,0x4b,0xe7,0xa4,0x94,0xc2,0x10,0x23,0xac,0x6b,0x70,0xd3,0xf5,0x67,0xf,0x91,0xa0,0x21,0x46,0x9c,0xbf,0xb8,0x87,0xed,0xd6,0xc0,0x2c,0xb6,0x79,0xee,0x34,0x11,0x99,0xc1,0x3,0xad,0x45,0x4c,0x9,0x27,0x17,0xa7,0x10,0x42,0x0,0x72,0x44,0x4a,0xe,0x97,0xae,0xec,0x1e,0x1a,0xd7,0xf6,0xd6,0x2,0xdb,0xf3,0x19,0x2e,0xef,0xec,0x22,0xb1,0xdd,0x3b,0x23,0xa3,0x69,0x67,0xf0,0xbe,0x7,0x29,0x36,0x33,0x94,0x1a,0x1b,0x79,0x95,0x2,0xb4,0x32,0xa4,0x5c,0x2d,0xa,0x40,0x5e,0x23,0x99,0x73,0x4,0x13,0x67,0x5b,0x8e,0x15,0xbf,0xa4,0xc6,0xa4,0x96,0x60,0x26,0xf,0xa7,0xf9,0x7f,0xe5,0x3d,0x50,0x72,0x1,0xb3,0x84,0x0,0xa,0x4,0x82,0xe3,0x7,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0xab,0x4,0xa5,0x54,0xa2,0x28,0xf7,0xb4,0xd6,0x88,0x31,0xd6,0x6c,0x34,0x0,0x50,0x56,0xd7,0xdc,0xbc,0x9c,0x33,0xc,0x17,0x47,0x18,0x63,0xc9,0x2a,0x19,0x2,0x60,0xf2,0x68,0x25,0x55,0x8a,0x55,0x68,0x89,0x15,0x78,0x47,0xab,0x9e,0x72,0x4e,0x88,0x21,0x20,0xa7,0x84,0xd5,0xfe,0x2e,0x67,0x6,0x2,0x31,0x52,0xbe,0x5d,0x4a,0x11,0x5a,0x1,0x43,0xb7,0xaa,0x36,0x4d,0xa5,0x14,0x12,0x17,0x66,0x0,0x54,0xc8,0x10,0xc2,0x80,0x9c,0x32,0x65,0xc6,0x81,0x95,0x5d,0x47,0x10,0x2e,0xa4,0x2c,0x4,0x17,0x6f,0x4,0xb8,0x66,0x86,0x18,0x3c,0xae,0x3f,0x7b,0x12,0x5b,0x5b,0x8b,0x43,0xaf,0x7f,0xe1,0xa5,0x4b,0xb8,0xbc,0xb3,0xb,0xa5,0xc9,0x3e,0xaa,0x95,0x41,0x21,0x10,0x8d,0xb1,0xf0,0x43,0x7,0x40,0xc1,0xf,0x1d,0x62,0x30,0x70,0x4d,0x5b,0x15,0x95,0x31,0x92,0xba,0xb1,0x1b,0x32,0x9e,0x3d,0x7f,0xe1,0x10,0x1,0xd8,0x34,0xe,0xd7,0x9e,0x5a,0xe0,0xd2,0xee,0x5,0x68,0xc3,0x5,0x1b,0x5a,0xa1,0x69,0x5b,0x28,0x65,0x8e,0xbc,0x66,0xd6,0x35,0x88,0x61,0x20,0x32,0x94,0xdb,0x99,0x15,0x6f,0x6b,0x4c,0x69,0xdf,0xd,0x30,0xae,0xd9,0xb8,0x8f,0x18,0x7c,0x25,0x13,0x43,0x8c,0x9c,0x5f,0x48,0xf6,0xd6,0x67,0x5f,0xb8,0x88,0xdf,0xff,0xc0,0xc7,0xf0,0x33,0x3f,0xfa,0x76,0x38,0x7b,0xf8,0xf6,0x70,0x7b,0x6b,0x8e,0x77,0xff,0xe0,0x9b,0xf1,0xe0,0x7d,0xb7,0xe1,0xf,0xff,0xe2,0xb,0x78,0xfc,0xd9,0x17,0x47,0x6b,0xac,0xd2,0xb5,0xcc,0x44,0x69,0x9a,0x8b,0x18,0x88,0x24,0x34,0xd6,0xe2,0xe6,0xd,0x4,0xab,0xd1,0x1a,0xbf,0xf8,0x93,0x6f,0x67,0xd2,0x90,0xec,0xcb,0x54,0x34,0x4d,0x5,0x20,0xd5,0xd2,0x9b,0x6b,0x9a,0x1e,0xcf,0xc3,0xe1,0x71,0xb5,0x6d,0x83,0x93,0xb,0x87,0x2b,0x7b,0x1a,0x3a,0x1,0xe0,0x5c,0xc4,0x30,0xf4,0x70,0xcd,0xc,0xbe,0xef,0x88,0xc3,0xd3,0xa,0xe0,0xf5,0x49,0xad,0xc0,0x74,0xee,0x39,0x51,0x6e,0x62,0xe6,0xac,0x3f,0xb2,0xb2,0xab,0x3,0x8d,0xc4,0x9c,0x51,0x38,0x51,0x5,0xaa,0x4a,0xa,0x8e,0xe4,0x5f,0xce,0xeb,0x84,0x60,0x16,0x12,0x50,0x20,0x10,0x1c,0x33,0x48,0x6,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x95,0x20,0xa3,0x14,0x79,0xe4,0x83,0x8f,0x56,0xb,0x30,0x72,0x66,0x85,0x98,0xe2,0x56,0x56,0x2e,0x57,0x48,0x9,0x39,0x45,0x68,0xa3,0xeb,0xf3,0x29,0x92,0x6a,0x6d,0xe8,0xbb,0x35,0xb5,0xdd,0x26,0x94,0xcc,0x38,0xca,0x92,0xe3,0xf2,0xa,0xce,0xa6,0x2b,0x79,0x6f,0x85,0xa8,0xa2,0x63,0x11,0xf9,0x12,0x43,0x40,0xe6,0xb6,0x62,0x63,0x1d,0x59,0x88,0x27,0x19,0x71,0x80,0xe2,0xd7,0x6e,0xb0,0xff,0x72,0xc9,0x45,0xe2,0x62,0x8a,0xa9,0x4a,0xee,0xd4,0x89,0xed,0x8d,0x84,0xd7,0x85,0x8b,0x97,0x91,0x73,0x86,0xef,0x3b,0x68,0x4d,0xb6,0xda,0x10,0x3c,0x72,0xce,0x18,0xfa,0x6e,0x24,0x14,0x8d,0x85,0x1f,0x7a,0x2c,0xf7,0x76,0x10,0x63,0x64,0x95,0x62,0xa8,0xea,0xaf,0xe7,0xce,0xbf,0x74,0xf8,0xe6,0x4b,0x6b,0x9c,0x3a,0xb9,0x5d,0x5b,0x94,0x43,0xf0,0x48,0x21,0x92,0xd2,0x6d,0xe3,0x5,0xa3,0xd7,0x50,0xee,0x9e,0xe6,0x2,0x8b,0x84,0xe5,0xde,0x2e,0x17,0x7a,0x90,0xb5,0xd7,0xf,0x1d,0xda,0xd9,0xbc,0x96,0x5b,0x1c,0x84,0x62,0xb,0x71,0xc,0x1,0x7e,0xe8,0xa9,0x39,0x97,0xc7,0x3,0xa5,0xf0,0x85,0xaf,0x3f,0x87,0xdf,0xf9,0xc3,0xbf,0xc0,0x72,0xd5,0x6d,0xbe,0x69,0xd4,0x1a,0x77,0xdc,0x7a,0x33,0xfe,0xe9,0x3f,0xfe,0x61,0xfc,0xd4,0x3f,0x78,0x13,0xe6,0xe,0x55,0x31,0x9a,0x62,0x44,0x8c,0x11,0x61,0xe8,0x11,0x83,0x47,0xd3,0xce,0x48,0x99,0xe8,0x7,0xb4,0x8d,0x3b,0x7c,0x2e,0x4a,0xa1,0x6d,0x1c,0x66,0xb3,0x16,0x6d,0xe3,0xd0,0xb6,0xd,0x66,0x6d,0x83,0x86,0x1f,0x9b,0xb5,0xe3,0xe3,0xe5,0xb9,0x59,0xdb,0xa0,0x6d,0xe,0x93,0x9b,0xd6,0x18,0x9c,0x3a,0x79,0xa2,0x5e,0x6b,0xd6,0x7c,0x22,0xf3,0x5a,0x2a,0x24,0x6e,0x59,0x4b,0xbc,0x48,0xab,0x2,0xb6,0x16,0x7e,0x14,0x5b,0x6f,0x21,0xf9,0x72,0x39,0x57,0x5d,0xad,0xd5,0xf5,0x18,0xa5,0xf0,0x17,0x53,0xe5,0x1f,0xff,0xc9,0x79,0x82,0xb9,0x5a,0x82,0xe5,0x33,0x47,0x20,0x10,0x1c,0x1f,0x8,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x2d,0xc8,0x13,0x12,0x63,0x42,0x6a,0x90,0xfa,0x89,0x88,0x11,0xe3,0x5c,0x6d,0x33,0x25,0x8b,0x6f,0xae,0xad,0xb1,0x85,0x64,0x49,0x4c,0xb8,0x69,0x63,0x91,0x62,0xa8,0xd,0xbb,0xc1,0xf,0xd0,0x47,0xe4,0x9e,0x8d,0x76,0x61,0x10,0x1,0xc5,0xa5,0x11,0x45,0x81,0xb8,0xda,0xdf,0x5,0x40,0x84,0x1f,0x14,0xa9,0x2,0x89,0x78,0x8c,0x28,0x95,0xb,0x7d,0xb7,0x64,0x32,0x2f,0xd5,0x71,0x10,0x11,0xb8,0x5e,0x52,0x52,0xa1,0xd4,0xa8,0x50,0x63,0x6b,0x66,0x51,0xaf,0x35,0x4e,0x6f,0xcc,0x68,0x5b,0x75,0x3,0xbb,0x38,0x89,0x30,0xb,0xac,0xbc,0xcb,0xdc,0x6c,0x1b,0x83,0x47,0xc,0xd4,0xca,0xeb,0x5a,0xca,0xb7,0x4b,0x91,0x88,0xb5,0xbe,0x5b,0x61,0xe8,0x3b,0xc4,0x18,0xb1,0xb7,0xbf,0xdc,0x38,0xf,0x6d,0xe3,0xb8,0x25,0xd7,0xc1,0xda,0xa2,0x4e,0xd4,0x1b,0x69,0xd3,0xcc,0xe5,0x13,0x39,0x27,0xc,0x3d,0xed,0x5b,0x6b,0xb2,0x21,0x7b,0xce,0x6d,0x8c,0x21,0x60,0xbe,0x75,0xa2,0xda,0x57,0x37,0x12,0xb0,0x6c,0x69,0x8d,0x9c,0x5,0x98,0x62,0xc0,0xd0,0x2d,0x89,0xe0,0x8d,0x1,0x29,0x27,0x7c,0xfa,0xcb,0x4f,0xe2,0xdf,0xfe,0xd6,0x7,0x70,0xee,0x85,0xb,0x47,0x2e,0x9f,0xb6,0x71,0xf8,0x7b,0x6f,0x78,0x0,0xbf,0xfc,0xb,0x3f,0x8e,0xdb,0xae,0xdb,0xae,0x36,0xd9,0x42,0xd2,0xe,0x7d,0x87,0x6e,0xb5,0x5f,0x89,0x52,0x95,0xc2,0x77,0x7d,0x49,0xcf,0x1b,0x52,0x65,0x52,0xe3,0x2f,0x91,0x91,0x0,0xad,0x1f,0x1a,0x7a,0xac,0x4,0x76,0x18,0x6,0x56,0xfb,0x8d,0x39,0x7e,0x53,0x1b,0xfb,0xf8,0x9e,0x48,0x28,0x7c,0x20,0xbd,0x7e,0x7c,0x9f,0x0,0x18,0xd7,0xdf,0xda,0x52,0x53,0x13,0xe2,0x10,0x75,0x3f,0x2,0x81,0x40,0x70,0x5c,0x20,0x16,0x60,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x2a,0xc1,0x94,0xb4,0x48,0x29,0x56,0xd2,0x6c,0x6c,0x35,0x55,0x8,0x43,0x5f,0x55,0x6e,0x85,0x44,0x49,0x29,0xc1,0x3a,0x57,0x4b,0x30,0x52,0x8a,0x8,0x81,0xc8,0x13,0xcb,0x25,0x14,0xc6,0x58,0x18,0xeb,0x8e,0x54,0x3d,0x15,0xd5,0x5f,0xce,0x19,0xc6,0x5a,0xc4,0x60,0x30,0xf4,0xab,0xd1,0x7a,0xac,0x35,0xef,0x97,0x4a,0x3a,0x94,0xa1,0x26,0xd7,0xc,0x40,0x69,0xb2,0x28,0x93,0x35,0x14,0x8,0x7e,0x80,0x75,0xa4,0x32,0x33,0xf6,0xe5,0x6f,0x69,0x9a,0x76,0x6,0xec,0xaf,0x0,0x80,0x94,0x7c,0x29,0x21,0xc6,0x80,0x7e,0x8,0x95,0xc,0x5c,0x7f,0x7d,0x8b,0x9c,0x1,0x63,0xc,0x62,0xf0,0x94,0x71,0x97,0x33,0xb4,0x6e,0xd0,0xaf,0x96,0x0,0x13,0x6d,0x5a,0x6b,0xf4,0xab,0x7d,0xca,0x44,0xe4,0x5c,0xbc,0xa2,0x70,0xc,0x4b,0x8f,0xb6,0xd9,0x7c,0x5e,0xdd,0x6a,0xc5,0x6d,0xba,0x1e,0xc6,0x1a,0xc4,0x44,0xa5,0x17,0x9b,0xc8,0xc8,0x92,0x39,0x57,0xc8,0x56,0x63,0x1d,0xfa,0x55,0xc9,0x1,0xb4,0x48,0x31,0xc2,0x35,0x2d,0x5d,0x1f,0xeb,0x70,0x94,0xfd,0x3a,0xe7,0x62,0x83,0xa5,0x6b,0x4d,0xc7,0xb6,0x48,0x69,0x80,0xb5,0xae,0xaa,0x1c,0x9f,0x78,0xfe,0x12,0xfe,0x8f,0xdf,0xf9,0x33,0xbc,0xfd,0xd,0xf7,0xe2,0x8d,0xaf,0xbd,0x1f,0xf3,0x59,0x7b,0x68,0x5f,0x4a,0x29,0xdc,0x78,0xfd,0x35,0xf8,0x67,0x3f,0xf7,0x23,0xf8,0x83,0x3f,0xf9,0x28,0x3e,0xfa,0x85,0xaf,0x3,0x8a,0xf2,0x25,0xb5,0xb5,0xdc,0x8a,0x9b,0xa8,0xc,0x46,0x1f,0x9e,0x3,0xef,0x3,0x9e,0x7b,0xe1,0x22,0x93,0xb1,0x11,0x28,0x76,0x5f,0xb6,0x2,0x4f,0x2d,0xb4,0x65,0x4a,0x52,0xce,0x34,0x32,0x56,0xef,0x15,0xb2,0x2d,0xe5,0x88,0x2b,0x3b,0x3b,0xf0,0xc3,0x50,0x49,0x5e,0xa5,0x35,0xac,0x75,0x18,0xfa,0xc8,0xd,0xc9,0x86,0xf3,0x1b,0x4b,0x3,0xb0,0x41,0x64,0x8b,0x3b,0x80,0xba,0xa6,0x73,0xce,0xc8,0x4c,0x1e,0x1a,0x63,0x2b,0x91,0x48,0x4a,0xd7,0x69,0x63,0x36,0x91,0xe0,0xb4,0x4d,0xaa,0xaf,0x39,0xb8,0x96,0x72,0x96,0x12,0x10,0x81,0x40,0x70,0xbc,0x20,0x4,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x95,0xa0,0x2a,0x93,0x98,0x44,0x89,0x89,0x8a,0x34,0x88,0x10,0x51,0x35,0x7f,0x8d,0x14,0x50,0x19,0xc8,0xa,0xb6,0x69,0xc8,0x72,0x1b,0x23,0xe7,0xf4,0x25,0xce,0xa5,0x73,0xa4,0xd6,0x63,0xc4,0x18,0xc8,0x6e,0x79,0x4,0x3,0xa8,0x0,0x2e,0xd6,0x8,0x88,0xc1,0x93,0xfd,0x14,0x44,0xc0,0xac,0xf6,0x77,0xe1,0x9a,0x16,0xce,0x35,0xb0,0xb6,0x41,0xb7,0xda,0x47,0x3b,0x5b,0x54,0x62,0xa9,0x90,0x34,0xd6,0x39,0x64,0x95,0x2a,0x89,0xd5,0xcc,0x2c,0x82,0x1f,0x90,0xf3,0x16,0x8e,0xb2,0x1e,0xf,0x43,0x3f,0x9e,0x9f,0xd2,0xc8,0x8a,0x8,0xbc,0xdd,0xbd,0x7d,0x84,0x18,0xd1,0x1c,0x68,0xe,0x39,0x73,0x6a,0x9b,0x14,0x79,0x5a,0x43,0xe7,0xcc,0xf6,0x5b,0x85,0xae,0xef,0xaa,0x82,0x90,0xc6,0xdd,0x23,0x83,0xec,0xcf,0xda,0xf,0x64,0x87,0x56,0xa,0xae,0x69,0x61,0x8c,0xc1,0xc9,0x3,0xa5,0x1a,0x0,0x11,0x48,0x7b,0xcb,0x15,0x72,0xca,0x80,0x21,0xc5,0x5c,0x3b,0xdf,0xaa,0x76,0xda,0x83,0x8,0x61,0x20,0x92,0xd3,0x90,0xf2,0x30,0x2b,0x5,0xef,0x7,0x64,0x0,0x2d,0x2b,0x8,0x29,0xdb,0x70,0x80,0xe7,0x46,0xe5,0x4d,0xb3,0x60,0xc,0xd9,0xaa,0x23,0xcf,0x7d,0xce,0x60,0xfb,0x30,0xcd,0xc5,0xd0,0xad,0x60,0x5d,0x3,0x63,0xd,0x76,0xf6,0x96,0xf8,0xfd,0x3f,0xfb,0x1c,0xbe,0xf8,0xe8,0xf3,0x78,0xe7,0xf7,0xbd,0xa,0x77,0xdd,0x7e,0xcb,0xa1,0x22,0xf,0x0,0xd8,0x5a,0xcc,0xf1,0x53,0xef,0x7e,0x3b,0xb6,0x17,0x33,0xfc,0xc1,0x9f,0x7f,0x16,0x50,0x1a,0xc9,0xa7,0x4a,0xac,0xf5,0x5d,0x87,0xdd,0xbd,0xbd,0x43,0xdb,0xa5,0x9c,0xf1,0x7f,0xbf,0xef,0x63,0xb8,0xb8,0xb3,0x7,0xad,0x2d,0xb7,0x42,0xc7,0x51,0x41,0xaa,0x35,0xba,0xd5,0x12,0x8a,0x8b,0x55,0x94,0xd6,0x64,0x2f,0x8e,0x11,0x31,0x7a,0x28,0x70,0xe1,0x8a,0x25,0x2,0xd4,0xf,0x3d,0x9a,0xd9,0xbc,0x92,0xd0,0x29,0x4,0x52,0x43,0x72,0xf1,0x89,0xe2,0xd6,0xeb,0x9a,0xff,0x97,0x75,0x2d,0xac,0xd1,0xc6,0xd4,0xe6,0x5f,0x22,0xeb,0x54,0x25,0xb8,0x15,0x17,0x80,0xa8,0x52,0xf8,0xa1,0x14,0xdb,0xe7,0x4b,0xcf,0xc7,0x61,0xf2,0x2f,0x97,0x4a,0x60,0x7e,0x97,0xa5,0x24,0xa,0x40,0x81,0x40,0x70,0x7c,0x20,0x16,0x60,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x2a,0x41,0x9e,0x12,0x4d,0x99,0xac,0xa7,0x5a,0x9b,0x9a,0x49,0x97,0x52,0xaa,0x65,0xa6,0xc8,0xe0,0xfc,0xb4,0x5c,0x1b,0x63,0x3d,0x97,0x76,0x0,0xa4,0xa6,0x2b,0xf6,0xc9,0x18,0x43,0xdd,0xcf,0xd1,0xa2,0xa7,0x8c,0xa1,0xef,0xa1,0x94,0xc6,0x72,0x6f,0x7,0xae,0x69,0x6a,0x79,0x87,0x6b,0x66,0x6c,0x9f,0xed,0xb1,0x7b,0xe5,0x2,0x12,0x5b,0x82,0x7d,0xdf,0xc1,0xf,0x3d,0x86,0x8e,0x54,0x73,0x43,0x4f,0x7f,0x1f,0xfa,0xe,0x31,0x78,0xf4,0xab,0x25,0x82,0x1f,0x90,0xa2,0x27,0x25,0xd9,0xa6,0xf1,0x72,0x41,0x86,0xd6,0x4c,0x8,0xb1,0x4a,0xec,0xd2,0xce,0x1e,0xba,0xae,0x3f,0xb4,0xcd,0x99,0x53,0x94,0xd1,0x17,0x39,0x5f,0xcf,0xba,0x86,0x8,0x27,0x63,0x48,0xe9,0xc7,0x39,0x88,0x39,0x67,0x22,0x2f,0xf7,0x76,0x28,0x3f,0xd1,0x3a,0x52,0x43,0xc6,0x88,0xa1,0xef,0x70,0xe3,0xf5,0x67,0xf,0xed,0x3b,0x84,0x88,0x67,0x9e,0x7d,0x1e,0x43,0xbf,0xe2,0x26,0x64,0x85,0x7e,0xb5,0x4f,0xea,0xc1,0xd,0x33,0x66,0xad,0xab,0xa,0x3f,0x1a,0xff,0xa,0xd6,0x51,0x63,0xf2,0xd0,0xad,0xe0,0xfd,0x0,0x3f,0x74,0xd4,0x70,0x9c,0x73,0x55,0xba,0x1d,0x3e,0xee,0x48,0xd4,0x1a,0xeb,0x6a,0xe,0xa0,0x36,0x96,0xb3,0x11,0x15,0xba,0xe5,0x1e,0x72,0x22,0xcb,0xb5,0xb1,0x16,0x4f,0x3c,0x73,0xe,0xff,0xfb,0x6f,0xff,0x29,0x7e,0xfd,0xf7,0xfe,0x4,0x2f,0xbc,0x74,0x69,0xe3,0x7e,0x9d,0x73,0xf8,0x87,0x3f,0xf4,0x7d,0x78,0xc3,0xfd,0xb7,0x21,0x7a,0xca,0x2a,0x1c,0xfa,0x15,0x52,0xc,0xe8,0xbb,0x25,0x5e,0x78,0xe9,0xf2,0xa1,0x6d,0x1a,0x67,0x71,0xc7,0x8d,0xa7,0xa1,0xb4,0x41,0x8,0x3,0xb5,0xf7,0xa6,0x58,0xd5,0x96,0x64,0xa1,0xa6,0xed,0x63,0xf4,0x4c,0x58,0x66,0x18,0x63,0xe0,0x5c,0x4b,0xcd,0xd0,0xd6,0x62,0xe8,0x3b,0xf4,0xdd,0x12,0x19,0x40,0xbf,0xda,0x47,0xc,0x1,0xcb,0xbd,0x1d,0x84,0xe0,0x99,0x83,0xcb,0x9c,0x4f,0x18,0xb8,0xf8,0x86,0xd6,0x34,0x11,0xb5,0xa8,0x19,0x96,0xc5,0x62,0x5e,0x4a,0x3e,0x32,0x93,0xbc,0x0,0xe5,0x47,0xc6,0xc4,0xcd,0xd9,0x95,0xcc,0x1b,0xaf,0x54,0xb5,0x12,0x4f,0xb6,0x1,0xd4,0x91,0x24,0xb8,0x40,0x20,0x10,0xfc,0x5d,0x42,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x2a,0x2,0x29,0xa2,0x0,0xb0,0xaa,0x2b,0xa6,0x40,0xf6,0x5a,0x2e,0xbc,0x28,0x79,0x69,0xa5,0xed,0x94,0xd4,0x80,0x9,0xa5,0x39,0x38,0x70,0x8e,0x5c,0x51,0x46,0xc5,0xe0,0x61,0x34,0x5b,0x3f,0x99,0x40,0xda,0x84,0x52,0xc4,0x90,0x62,0x40,0x3b,0x5b,0xc0,0xf,0x3d,0xf6,0xae,0x5c,0x42,0xe0,0x12,0x10,0x22,0x75,0x56,0x64,0x7b,0xad,0x2a,0xc1,0x1e,0xc1,0xf,0x88,0x29,0x60,0xb5,0xbf,0x47,0x96,0xe0,0x94,0xd1,0xad,0xf6,0x91,0x38,0x1f,0x30,0x84,0x40,0x56,0xe5,0x23,0xf2,0xd6,0x14,0x50,0x9,0x2e,0x6b,0x6d,0x55,0xc1,0xad,0x7c,0xc4,0x85,0x8b,0x87,0x9,0xaa,0x33,0xa7,0x4f,0xe2,0xb6,0x1b,0x4e,0xc3,0xb0,0x9d,0x75,0xe8,0x3b,0x28,0x6d,0xb0,0xda,0xdf,0x43,0xf4,0x1e,0x91,0x5b,0x74,0x8b,0xea,0x6b,0xeb,0xe4,0x19,0x74,0xcb,0x7d,0x40,0x1,0xde,0xf,0x48,0x31,0xe0,0xd4,0xd6,0xc,0xb7,0xdc,0x7c,0xe3,0xa1,0x7d,0xef,0xed,0xef,0xe3,0xf9,0x97,0x2e,0x23,0x4,0x5f,0xdb,0x90,0x63,0x8,0x8,0x5c,0x8c,0xb2,0x79,0xe2,0x68,0xee,0xac,0x25,0x75,0x64,0x66,0x55,0x22,0xd8,0x6e,0x8c,0xc,0xf8,0x61,0x80,0xb1,0x8e,0xa,0x2b,0x8e,0x98,0x83,0xcc,0xc5,0x2a,0x9e,0x95,0x97,0x4a,0x81,0x5b,0x72,0x49,0x21,0x37,0xdf,0x3a,0x81,0xc4,0x73,0x98,0x62,0x2,0x9b,0x6d,0xf1,0xd9,0xaf,0x3c,0x89,0xff,0xf9,0x7f,0xfb,0xd,0xfc,0xe9,0x47,0x3f,0xd,0xcf,0xa4,0xe8,0x14,0xd6,0x18,0xfc,0xc4,0xbb,0xdf,0x8e,0xed,0xed,0x2d,0x6a,0x28,0x2e,0x6d,0xd1,0x31,0xe0,0xf1,0xa7,0x9f,0x3f,0x34,0x2e,0xa5,0x14,0x5e,0xfb,0xc0,0x9d,0x40,0x4e,0xa3,0x6d,0x3a,0x4,0xce,0x5b,0xf4,0xb5,0x48,0x44,0x6b,0x8d,0xa6,0x99,0x41,0x1b,0x3,0x6d,0x4c,0x25,0xae,0xb5,0xb1,0x95,0xa4,0x8b,0x31,0x62,0xe8,0x96,0xd8,0xdf,0xbd,0x82,0xe5,0xee,0x15,0xf8,0xa1,0xab,0x16,0x6f,0x22,0xb8,0x4d,0x2d,0xb6,0x49,0xdc,0x3a,0x5c,0x48,0x6d,0x6d,0xc,0x11,0x81,0x4c,0xe,0x66,0xde,0xf7,0x94,0xc0,0xde,0x34,0x9f,0x7a,0xa2,0x18,0xad,0x6d,0xc8,0x6b,0x2a,0xd2,0x49,0x96,0xa0,0x28,0x0,0x5,0x2,0xc1,0x31,0x82,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x2,0x6a,0x3e,0x1d,0xd5,0x4d,0x39,0xa5,0xaa,0x5e,0x4a,0x5c,0xc6,0x1,0x70,0x56,0x9a,0xd6,0x64,0x93,0xd4,0xa6,0xe6,0x99,0xc5,0xe8,0xc7,0xac,0x3f,0xe4,0xda,0x7e,0xeb,0x7d,0x8f,0x9c,0x22,0x52,0x8e,0x35,0x3f,0x70,0xc3,0xd1,0x89,0xd8,0xe3,0xff,0x2a,0x79,0xc2,0x24,0xa2,0x1f,0x7a,0x74,0xcb,0x3d,0x2c,0xf7,0x77,0xd0,0xaf,0x96,0xe8,0x56,0xfb,0x5c,0xb8,0x11,0x2a,0x69,0x95,0x12,0x95,0x61,0x90,0xfa,0x6f,0x9f,0x94,0x81,0x31,0x20,0xd7,0x82,0x92,0x75,0x28,0x0,0xfd,0x6a,0xf,0xab,0xbd,0x9d,0x51,0x49,0x17,0x88,0x74,0xf2,0x7d,0x87,0xaf,0x7d,0xe3,0xa9,0x43,0xdb,0x38,0x6b,0xf1,0xb6,0xef,0x79,0xd5,0x1,0xf2,0xa6,0x58,0x48,0xc9,0x36,0xeb,0x87,0xbe,0xe6,0x19,0x6a,0xa3,0x99,0xb0,0x32,0x64,0xff,0xb5,0xe,0xdf,0xf7,0xfa,0x7,0xb0,0xbd,0xb5,0x38,0xb4,0xef,0x27,0x9e,0x7a,0x16,0x7d,0xdf,0x57,0xb,0xf4,0x72,0xef,0xa,0xb5,0x22,0xc7,0x8,0x1f,0xe2,0x86,0x73,0x31,0x94,0x69,0xd7,0x34,0x30,0xd6,0x22,0x78,0x6a,0xef,0xf5,0x6c,0x6b,0x26,0xfb,0x76,0x20,0x75,0x22,0x26,0x39,0x7a,0x7,0x60,0x6a,0xd9,0x88,0x81,0xe2,0x5c,0xc1,0x18,0x2,0xbc,0xef,0x69,0x9e,0x63,0x40,0xf0,0x34,0xd7,0x25,0xd3,0xb1,0x96,0x64,0x68,0x8d,0x8,0xe0,0x37,0xff,0xf8,0x13,0xf8,0xf,0xef,0xf9,0xe3,0x8d,0xaa,0xc9,0x6b,0xce,0x9e,0xc1,0x7d,0xb7,0x5d,0x3f,0xaa,0x49,0x39,0x3b,0xf2,0xc9,0xe7,0x5f,0xc2,0xfe,0xf2,0x70,0xb3,0xf0,0x5d,0xb7,0xdf,0x82,0x9b,0xaf,0x3d,0x9,0x63,0x9b,0x5a,0x20,0x62,0x9b,0x86,0x9b,0x7b,0xd,0xfa,0xd5,0x12,0xd6,0x35,0xb0,0x4d,0xb,0xf0,0x3a,0xd1,0xc6,0x2,0x4a,0x55,0xa2,0xd3,0x5a,0x7,0xe7,0x1a,0x68,0xce,0xeb,0x8b,0x31,0xa2,0x5b,0x2d,0xb1,0xdc,0xdf,0x41,0x4a,0x9,0x7d,0xbf,0x42,0xca,0x54,0x7c,0x12,0x63,0x64,0x1b,0xb0,0x21,0x3b,0xb9,0x56,0x64,0x1d,0x67,0x22,0x37,0xa5,0xc4,0x5,0xc1,0x44,0x12,0x92,0x8d,0x59,0xad,0xcd,0x3,0xbf,0x31,0xaa,0x62,0xb2,0xae,0x8c,0x5a,0x8,0xa2,0x38,0xcb,0x10,0x95,0xa0,0x2c,0xb6,0x62,0x81,0x40,0x20,0x38,0xe,0x10,0x2,0x50,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0xb8,0x5a,0x50,0x5c,0x8a,0xc,0x52,0xfd,0x91,0x7d,0xd5,0x18,0x53,0x4b,0x27,0xc0,0xad,0xa7,0xc5,0x42,0xa9,0xb5,0x9a,0xa8,0xbb,0x58,0x21,0x38,0x29,0x3d,0x30,0xc6,0x2,0x50,0x23,0xa9,0xb8,0x11,0x54,0xc0,0x50,0xa,0x2b,0x88,0xcc,0xeb,0x10,0xfc,0x80,0xbd,0x9d,0x4b,0x58,0xed,0xef,0x42,0x1b,0xb,0xdf,0x77,0x58,0xee,0xef,0xc0,0xfb,0x1,0xab,0xe5,0x2e,0x11,0x83,0xab,0x7d,0xec,0x5e,0xb9,0x80,0x6e,0xb5,0x47,0x96,0x4d,0xad,0x11,0x83,0x47,0x8,0x64,0x3b,0xd,0x4c,0xea,0x1d,0x1e,0x6e,0x46,0x28,0xe4,0xd0,0x72,0xf,0xcb,0xbd,0x9d,0x4a,0xf8,0xe4,0x9c,0xf1,0xc9,0xcf,0x7f,0x5,0x5d,0x3f,0x1c,0xda,0xee,0xc1,0xfb,0xef,0xc4,0xdd,0xaf,0xb8,0x86,0x1b,0x8e,0x4d,0xcd,0x8b,0xf3,0xc3,0x0,0x3f,0xf4,0x68,0x67,0xb,0x52,0xa6,0x71,0xb,0x6f,0x21,0xbe,0xb4,0xd2,0xb8,0xf1,0xba,0xb3,0xf8,0xc1,0xb7,0xbd,0xe9,0xd0,0x3e,0x53,0xce,0x62,0x4a,0x41,0xe6,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xf8,0xcc,0x17,0xbf,0x5c,0xed,0xab,0x31,0x6,0xc,0x3d,0x29,0xd6,0x42,0x8,0xd8,0xd9,0xd9,0x39,0xb4,0xcd,0xd6,0x62,0x8e,0xb9,0xd3,0xd0,0x4a,0x53,0x66,0x22,0x5f,0x3,0x28,0x2a,0x6b,0x21,0x15,0x5c,0xe0,0x1c,0x44,0xc0,0x39,0xbb,0x91,0x6e,0x2a,0x4d,0xc8,0x45,0xfd,0x8,0x56,0x4f,0x9e,0x98,0xcf,0xd0,0x18,0xcd,0x44,0x57,0x62,0x15,0x23,0x11,0x7c,0x29,0x6,0x26,0x5b,0x43,0xcd,0x28,0xfc,0xf4,0x97,0x1f,0xc7,0x27,0x3e,0xfd,0x85,0xc3,0x37,0x95,0x4a,0xe1,0x15,0x37,0x5e,0x7,0xd7,0xb4,0xb0,0xae,0x41,0xd3,0xce,0xa1,0x94,0xc2,0x6a,0x88,0x78,0xfc,0xa9,0xe7,0xe,0xbd,0xbe,0x6d,0x2c,0x7e,0xec,0x7,0xdf,0x8,0x3,0x52,0xfd,0xf9,0xa1,0x67,0x42,0x74,0x7,0xdd,0x72,0xaf,0xce,0x6b,0xc9,0x2b,0x34,0xc6,0xc2,0xba,0x86,0xec,0xdc,0x7e,0xc0,0x6c,0xb1,0x85,0x76,0x36,0xc3,0xab,0xef,0xbd,0xa3,0x92,0x9f,0x81,0x49,0xe8,0x6e,0xb9,0x8f,0x7e,0xb5,0xf,0xa5,0x34,0x93,0x7d,0x9a,0x54,0x7b,0x8a,0xe7,0x41,0xd3,0x75,0x2a,0xaa,0x3d,0x85,0xa2,0xe0,0xa3,0xf5,0x5b,0xec,0xd6,0x40,0xae,0xaa,0xd8,0x71,0x41,0x71,0x41,0xc9,0x44,0x21,0x3b,0x6,0x6b,0xa6,0x35,0xf2,0xb5,0x2a,0x3,0x85,0xff,0x13,0x8,0x4,0xc7,0x4,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0x9,0x4a,0x49,0x7,0x29,0xfa,0x34,0x93,0x69,0x8a,0xd5,0x6c,0xa8,0x8d,0xb3,0xc8,0x44,0x96,0x68,0xad,0x99,0xdc,0xa3,0x2,0x8f,0x18,0x7c,0xcd,0x7a,0xb,0x6c,0x61,0x2d,0x4a,0x38,0x22,0x4d,0xd4,0xc6,0x32,0xb,0x3a,0x38,0x95,0x37,0xc4,0x18,0xa8,0xdc,0x62,0xe8,0x29,0x2b,0x6e,0xb5,0x44,0xc,0x1,0xc6,0x58,0xf4,0xdd,0x12,0x21,0x78,0xf4,0xdd,0xa,0xbe,0xef,0x30,0xf4,0x1d,0x76,0xaf,0x5c,0xa0,0xcd,0xa1,0x30,0x74,0x1d,0x76,0x2e,0x5f,0x84,0xef,0x7b,0x2a,0x8a,0x0,0x68,0x9f,0xbe,0xdf,0xdc,0x3e,0x9c,0x81,0x1c,0x43,0x25,0xd,0x5d,0x43,0xad,0xb6,0x61,0x20,0xc2,0xec,0xdc,0xc5,0x5d,0x3c,0xfa,0xf8,0xd3,0x87,0x36,0x6b,0x1a,0x87,0x9f,0xfb,0xf1,0x1f,0xc2,0xd,0x67,0xb6,0x11,0x82,0xa7,0xc6,0xe1,0xe0,0x61,0x5d,0x83,0xf9,0xd6,0x9,0x74,0x4b,0x2a,0xb7,0x30,0x5c,0xc2,0x51,0x6c,0xcf,0x5b,0x73,0x87,0x5f,0xfc,0xa9,0x7f,0x80,0x53,0x27,0xb7,0xf,0xed,0xf3,0xf9,0xe7,0xcf,0xe3,0xf3,0x5f,0x7d,0xaa,0xe6,0x29,0xd2,0x1c,0x7a,0x56,0x0,0x6,0xbc,0xf0,0xd2,0xc5,0x43,0xdb,0x6c,0x2d,0xe6,0xb8,0xfd,0xe6,0xeb,0x28,0x6f,0x91,0x95,0x69,0xc6,0x18,0x34,0xcd,0xc,0xf3,0xed,0x93,0xb0,0xce,0x91,0xfa,0xd0,0x58,0x6c,0xcf,0x1b,0xfc,0xc3,0xef,0x7f,0xfd,0x9a,0x45,0xb5,0x4e,0x3d,0x28,0xb3,0xb1,0x28,0x2e,0xcb,0xa3,0x6f,0x7e,0xed,0x7d,0xf8,0x1f,0xfe,0xc5,0xcf,0xe3,0xc1,0xbb,0x6f,0x81,0xb3,0x6,0xc8,0x80,0x31,0x8e,0x49,0xad,0x92,0x77,0x48,0x84,0xa5,0xd6,0x6,0x29,0x3,0x4f,0x3c,0x73,0x6e,0xe3,0xe5,0xb5,0x6c,0x99,0x4e,0x29,0xd6,0xc2,0x95,0x94,0x13,0x3e,0xf2,0x97,0x5f,0x44,0x8c,0x87,0xd7,0xc4,0x1d,0xb7,0xde,0x84,0x9f,0x7a,0xc7,0x5b,0xe0,0x4a,0x3c,0x1f,0x13,0xc3,0x63,0xeb,0xb2,0x41,0xc,0x1,0xb3,0xc5,0x16,0x17,0x7e,0x4,0xb4,0xf3,0x2d,0x34,0xed,0x1c,0xaf,0xbc,0xe3,0x66,0xfc,0x8f,0xbf,0xfc,0xb,0xf8,0xe7,0xbf,0xf8,0x33,0x70,0xcd,0xac,0x12,0xca,0xab,0xfd,0x3d,0xca,0x46,0x1c,0x58,0x91,0xca,0xd6,0xea,0xcc,0x4a,0xd6,0x42,0x6c,0x93,0x45,0x38,0xd7,0xf7,0x3,0xa7,0xff,0x55,0xcb,0xaf,0x3e,0x50,0x66,0xa3,0x36,0xcc,0x69,0xb1,0x66,0xd7,0x85,0xa7,0xd4,0x84,0xeb,0xcb,0xa3,0x95,0x5e,0xf2,0x0,0x5,0x2,0xc1,0x31,0x81,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x82,0xa2,0x6c,0x22,0xb,0x70,0x64,0xbb,0x66,0x62,0x12,0x90,0x6c,0x9b,0x99,0x4b,0x19,0x8c,0xb1,0xd4,0xc0,0x1a,0x3c,0xa9,0xa2,0x62,0x64,0x12,0x28,0xb1,0xe8,0x29,0xd7,0xd7,0x4e,0xf7,0x7b,0x14,0x32,0xdb,0x29,0x15,0x67,0x9,0xc6,0x18,0x60,0x9b,0x16,0xc6,0x92,0xa5,0x78,0xb5,0xbf,0x8b,0xa1,0xe3,0x86,0x5c,0xb6,0x54,0x6a,0x4d,0xaa,0x44,0x5,0xc5,0x56,0xce,0x80,0x76,0x36,0x47,0xb7,0xdc,0x23,0xc2,0xb0,0x5f,0x71,0x41,0x43,0xdc,0xa8,0x0,0x54,0xdc,0xdc,0xda,0x77,0x4b,0xda,0x7f,0x79,0x3d,0xe7,0xcf,0x5,0x3f,0xe0,0xbd,0x7f,0xf2,0x31,0x2c,0x57,0x87,0x6d,0xaa,0xd7,0x9c,0x39,0x85,0x7f,0xfe,0x73,0xef,0xc6,0xab,0xee,0xb8,0x11,0xbe,0xef,0x29,0x37,0x4e,0x6b,0xf8,0xbe,0x43,0x3b,0x5b,0xc0,0x3a,0xb2,0xa2,0x36,0xed,0xc,0xb3,0xd9,0x1c,0xf7,0xdd,0x7e,0x33,0x7e,0xf9,0x17,0x7e,0x1c,0xb7,0xdf,0x72,0xd3,0xa1,0x7d,0xc5,0x98,0xf0,0xe1,0x8f,0x7f,0x1e,0x81,0x89,0xb0,0x42,0x58,0x69,0xad,0x71,0xf9,0xc2,0x79,0xec,0xef,0x5e,0xc1,0xd7,0x1e,0x3f,0x87,0x94,0xd6,0xe7,0xcf,0x18,0x8d,0x77,0xff,0xe0,0x9b,0x31,0x6b,0x48,0x85,0xe8,0x9a,0x96,0xc8,0xd1,0xa1,0xc3,0xde,0x95,0x4b,0x48,0x31,0x22,0x78,0x8f,0x45,0x63,0xf0,0xf3,0xff,0xe8,0xad,0xb8,0xe3,0xd6,0x9b,0x36,0x4f,0xbe,0x52,0xb0,0xd6,0xd5,0x12,0x14,0x6a,0xfc,0xb5,0xd0,0x5a,0xe3,0xd6,0x5b,0x6e,0xc2,0x7f,0xf3,0x5f,0xfc,0x4,0xfe,0xc9,0x4f,0xbc,0x1d,0x77,0xde,0x74,0x96,0x32,0x1d,0x8d,0x85,0x31,0x6,0x39,0x25,0xac,0xf6,0x77,0xa8,0x75,0x79,0xe8,0xe1,0xfb,0x15,0x1e,0x7c,0xe5,0xdd,0x1b,0xf,0x71,0xf1,0xca,0xee,0x48,0x20,0x83,0x8,0x63,0x5,0x85,0x47,0x9e,0x7e,0x11,0x8f,0x3f,0xf5,0xfc,0xc6,0x6b,0xf3,0xc6,0xd7,0x3e,0x80,0x5f,0xfa,0xb9,0x77,0xe1,0xce,0x9b,0xaf,0xa9,0x24,0xad,0x75,0x4d,0x6d,0xf5,0x6d,0xda,0x19,0x32,0x5b,0x6e,0x1b,0xe7,0xf0,0x9a,0x7b,0x6e,0xc5,0x7f,0xfb,0x5f,0xfd,0x4,0xfe,0xfb,0x5f,0xfa,0x79,0xbc,0xf2,0xbe,0x7b,0x60,0x8c,0xe6,0x52,0x10,0x22,0x42,0xad,0xa3,0x8c,0xc4,0x72,0xad,0x4b,0xce,0x62,0x21,0xf0,0xb4,0x22,0x5b,0xbb,0x31,0x96,0x2c,0xc5,0x39,0x8f,0xcd,0xd7,0x29,0x71,0x6,0x22,0xdb,0x76,0x27,0xad,0xbf,0x39,0xc6,0x7a,0xce,0xa3,0xf2,0x35,0xb3,0xc2,0x6f,0x2d,0x34,0x50,0x3e,0x64,0x4,0x2,0xc1,0xb1,0x85,0x95,0x29,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0xae,0xe,0xa8,0x69,0x43,0xa9,0x52,0xdc,0xf4,0xcb,0x8f,0x71,0x13,0x30,0x65,0xfe,0x11,0x29,0x48,0x2f,0x53,0xdc,0x12,0x1c,0xa1,0x8d,0xa9,0x16,0x54,0xa5,0x34,0x82,0x27,0x75,0x5c,0x4e,0x9,0xe0,0x2c,0x36,0x75,0x24,0x9,0xa2,0xd6,0x8b,0x43,0xac,0xad,0x59,0x76,0x39,0x27,0xcc,0x16,0xdb,0xd0,0x5a,0xc3,0xb5,0x2d,0x86,0x6e,0x85,0x10,0x6,0x58,0xe7,0xe0,0xda,0x19,0x91,0x36,0xac,0xe,0xf3,0x43,0x8f,0x66,0x36,0xaf,0xd6,0xdc,0x72,0x2e,0xf9,0x8,0xf2,0x31,0xa5,0x48,0x16,0xda,0xa1,0x83,0x56,0xba,0x16,0x4e,0xcc,0xe6,0xb,0xa4,0x94,0xf0,0xc4,0x73,0x2f,0xe1,0xcf,0x3e,0xf6,0x59,0xbc,0xfb,0x1d,0x6f,0x3d,0xb4,0xed,0xb5,0xd7,0x9c,0xc1,0x3f,0xfb,0xcf,0x7f,0xc,0x5f,0xfd,0xfa,0x63,0xf8,0x8b,0x4f,0x7e,0xe,0x8f,0x3d,0xf3,0x22,0x96,0x5d,0xf,0xdb,0xb4,0xd0,0x48,0x38,0xb1,0x68,0x71,0xe7,0x2d,0x37,0xe0,0x2d,0xaf,0x7b,0x25,0xee,0xbb,0xe7,0xe,0xcc,0xda,0x76,0xe3,0x39,0xfc,0xd5,0x97,0x1f,0xc1,0x27,0xbe,0xf8,0x8,0x0,0x52,0x97,0x29,0xa5,0xa1,0x35,0xa9,0xe5,0x52,0xa4,0xd2,0x8a,0xcf,0x3c,0xfc,0x15,0xfc,0xd4,0xbb,0xde,0x86,0xb3,0x67,0x4e,0xaf,0x6d,0x7b,0xcb,0x4d,0xd7,0xe3,0x17,0x7f,0xf2,0x1d,0xf8,0xad,0x3f,0xfc,0x73,0x9c,0xbf,0x70,0x85,0x94,0x6c,0x96,0xda,0x89,0x9d,0x35,0x78,0xd3,0x83,0x77,0xe3,0x1d,0xdf,0xff,0x3d,0xb8,0xf1,0xfa,0x6b,0x8f,0xbc,0xee,0x31,0x6,0xce,0xfa,0xa3,0x2c,0xbc,0x42,0xa6,0xd6,0xa6,0x63,0x6b,0xf0,0xd0,0xab,0xee,0xc5,0xfd,0xf7,0xdc,0x81,0x27,0x9f,0x3d,0x87,0xcf,0x3e,0xfc,0x75,0x3c,0xf2,0xc4,0x39,0x5c,0xf4,0x3d,0x94,0x6a,0xd1,0xaf,0x96,0x38,0xb5,0xd5,0xe2,0x27,0xfe,0x93,0xb7,0xe1,0xd,0xaf,0x79,0xe0,0xd0,0xfe,0x87,0x61,0xc0,0xe3,0x4f,0x9f,0xe7,0x8c,0x41,0xd,0xab,0xdc,0x58,0x1e,0xa3,0x1c,0x7e,0xf7,0x3,0x1f,0xc3,0xbf,0xf8,0x2f,0x7f,0x14,0x5b,0x8b,0xf9,0xda,0x76,0x5a,0x2b,0xdc,0x77,0xf7,0xed,0xf8,0xef,0xfe,0xeb,0x9f,0xc5,0x13,0x4f,0x3e,0x8d,0x2f,0x3f,0xf2,0xd,0x3c,0x77,0xfe,0x12,0x76,0x97,0x1d,0x72,0x3e,0x85,0xed,0xc5,0xc,0xd7,0x9c,0xde,0xc6,0xdd,0x77,0xdc,0x82,0x3b,0x6f,0x7b,0x5,0xce,0x9e,0x39,0x5,0x6b,0xc7,0x5b,0x58,0xa5,0xc8,0xa2,0xdb,0xce,0x17,0xbc,0x96,0x32,0x86,0x7e,0x85,0x56,0x6f,0x61,0xe8,0x3a,0xb4,0xb,0xc3,0x96,0xf5,0x8,0x5,0x85,0x94,0x89,0xfc,0x4b,0x4c,0xf6,0x95,0x84,0x3e,0x2a,0xa1,0x71,0x9c,0xe7,0x47,0x56,0xde,0xb2,0x8e,0x4b,0x89,0x89,0xe2,0xbf,0x97,0x6c,0xcc,0x69,0x3,0xf0,0x5a,0x26,0x20,0xc6,0x1c,0x40,0x51,0xff,0x9,0x4,0x82,0xe3,0x4,0x21,0x0,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x82,0xab,0x4,0x6b,0x74,0x44,0xce,0x55,0xf5,0x54,0x72,0xd0,0x88,0xe4,0x8,0xd5,0x7e,0x69,0xb8,0x10,0xa2,0x10,0x3b,0x45,0x89,0x7,0xa0,0x2a,0x4,0xb,0x69,0x18,0x43,0x20,0xd5,0xd7,0x91,0x4,0x20,0x5b,0x2f,0xf9,0x69,0x3f,0xf4,0x30,0xd6,0x62,0xb9,0xb7,0x3,0xeb,0x1c,0xb6,0x4e,0x9c,0xc2,0xd0,0x91,0x6a,0xab,0x9d,0x2d,0xb8,0x14,0x22,0x40,0x65,0x40,0x19,0xb2,0x22,0x53,0xfe,0xde,0x9c,0xec,0x95,0x6c,0x37,0x35,0x4c,0x58,0x1e,0x45,0xb6,0x18,0xd7,0xd4,0xdc,0xc1,0xcc,0xe4,0x57,0xce,0xd4,0x24,0xac,0x8d,0x81,0xb5,0x16,0x1f,0xfc,0xd4,0x97,0x70,0xfd,0xb5,0xa7,0xf1,0xc6,0xd7,0xbd,0xfa,0xd0,0xf6,0x6d,0xdb,0xe0,0xb5,0xf,0xbe,0x12,0xaf,0x79,0xf5,0xfd,0x58,0xad,0x56,0x58,0xae,0x3a,0x64,0x28,0x18,0xad,0x31,0x9f,0xb5,0x68,0xdb,0x66,0xa3,0xed,0xb6,0xe0,0xb1,0x27,0x9f,0xc5,0x6f,0xfe,0xd1,0x27,0x60,0x6c,0x83,0xc,0xc0,0xf7,0x7d,0x25,0x8f,0x72,0x6,0x5c,0xd3,0x22,0xc6,0x80,0x2b,0x97,0x2e,0xe1,0x2f,0x3f,0xfb,0x57,0x78,0xe7,0x3b,0x7e,0x60,0x6d,0x7b,0xa5,0x80,0x7,0x5f,0x79,0x17,0xee,0xba,0xed,0x46,0x3c,0xf9,0xcc,0x39,0xbc,0xf0,0xe2,0x4b,0xf0,0x21,0xe2,0xe4,0xf6,0x16,0x6e,0xbf,0xf5,0x66,0x5c,0x73,0xf6,0xc,0xac,0x35,0xdf,0xe4,0xc2,0x67,0x18,0x63,0x31,0x74,0x2b,0x2e,0x70,0x41,0x25,0x4f,0xa7,0x68,0x1a,0x87,0x7b,0xef,0xbc,0x15,0xf7,0xdc,0x71,0x2b,0xba,0xae,0xc3,0x95,0xdd,0x7d,0x2c,0x97,0x4b,0xcc,0x66,0x33,0x9c,0x3e,0xb9,0x8d,0xc5,0x1,0x2,0xaf,0xe0,0x89,0xa7,0xcf,0xe1,0x85,0x4b,0x94,0xe1,0xd8,0xaf,0x96,0xa4,0x36,0x64,0x15,0x69,0x8a,0x11,0x4f,0x3c,0xf7,0x2,0xfe,0xf4,0x63,0x9f,0xc5,0xbb,0x7e,0xe8,0x7b,0x39,0xb3,0xef,0xc0,0x1c,0x37,0xe,0xf7,0xdf,0x7b,0x17,0xee,0xbf,0xf7,0xae,0x9a,0xcf,0x48,0x36,0x60,0xfd,0xb2,0x73,0x4b,0xe5,0x2c,0x6,0xa,0xb4,0xf6,0x0,0xc5,0xe4,0xaa,0x86,0xf7,0x3,0xac,0x6f,0x90,0xac,0xab,0xd7,0x3e,0xa7,0x84,0xc,0x26,0xb9,0xa7,0xe3,0x57,0x8a,0xf2,0x5,0x63,0xa4,0xf3,0xe3,0xd7,0x96,0xf9,0x2f,0x5,0x1f,0x8a,0x49,0x72,0x12,0x0,0x66,0x60,0x53,0x23,0x30,0xd4,0x84,0x40,0x14,0x2,0x50,0x20,0x10,0x1c,0x1f,0x8,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x35,0xc8,0x95,0x5c,0x1,0x98,0xa4,0x48,0x19,0x99,0xed,0xbc,0x50,0x1a,0xa,0xa3,0xc2,0xa9,0x92,0x7f,0xa5,0xd9,0x35,0xe7,0x6a,0x97,0x8c,0xf0,0x30,0x70,0x54,0xc8,0xc1,0x99,0x6f,0x39,0x27,0x2a,0x8d,0xd8,0x4,0x56,0xfe,0x45,0xef,0xd1,0xad,0x96,0x40,0x6,0xf6,0x77,0x2f,0x23,0xa7,0x4,0x3f,0xc,0xe8,0xbb,0x15,0x14,0x50,0x9,0xbe,0x18,0x3c,0x66,0x8b,0x6d,0xe4,0x44,0xed,0xc1,0x39,0x27,0xcc,0xe6,0x5b,0x35,0x6f,0x4f,0x29,0x5,0x6b,0x9b,0x8d,0x44,0xd6,0x14,0x94,0x2f,0x68,0x10,0xfc,0x80,0x18,0x63,0xb5,0x80,0xc6,0xe0,0xe9,0x9c,0x62,0xc4,0xce,0x95,0xcb,0xf8,0xf5,0xff,0xf8,0xe7,0x70,0xae,0xc1,0x43,0xf,0xdc,0xbd,0x39,0x47,0x4f,0x29,0x2c,0x16,0xb,0x2c,0x16,0x8b,0x6f,0x6d,0xa6,0x33,0xf0,0xf8,0x53,0xcf,0xe0,0x57,0x7f,0xeb,0x3,0xd8,0xdd,0x5b,0xb1,0xda,0x2f,0xc2,0x36,0x64,0x53,0xd,0x7e,0x0,0x90,0xd1,0x77,0xcb,0x6a,0x61,0x7d,0xef,0x87,0x3f,0x89,0x7,0x5f,0x75,0x1f,0x6e,0xb9,0xf9,0xc6,0x43,0xfb,0x5b,0x2c,0x16,0x78,0xe0,0xbe,0xbb,0xf0,0xc0,0x7d,0x77,0x1d,0x71,0xbc,0x8c,0xaf,0x3f,0xf6,0x14,0xee,0xb9,0xf3,0xd6,0x43,0xe7,0xaf,0xd,0x5d,0x27,0xe3,0x1a,0x2c,0xf7,0xae,0xc0,0xb9,0xb6,0xae,0x87,0x23,0x2e,0x15,0xe6,0xf3,0x19,0xe6,0xf3,0x19,0x80,0x6b,0x5e,0x76,0x9c,0xab,0xae,0xc3,0x7f,0xfc,0xc0,0x47,0x10,0x62,0x44,0xf6,0x9e,0x8b,0x31,0x30,0x92,0x6e,0x99,0x54,0x73,0x1f,0xfc,0xcb,0xaf,0x62,0x3e,0x6b,0xf1,0xf6,0xef,0xfb,0x1e,0x18,0x73,0x34,0xa9,0xf7,0xf2,0x84,0xdf,0x3a,0x42,0x20,0x5b,0x79,0x8,0xbe,0x1e,0xaf,0x69,0x67,0xb8,0x7c,0xe1,0x5,0x9c,0xbd,0xfe,0xe6,0xda,0xe2,0x3b,0xb6,0xf2,0xea,0xba,0xae,0x15,0x2b,0x47,0x8b,0x2d,0x3a,0x83,0x32,0x1d,0x63,0x29,0x94,0x61,0xb,0x70,0x21,0xb4,0x33,0x5f,0xd4,0xaa,0xfc,0x3,0xe5,0x69,0xd1,0x7b,0x67,0xf3,0x2,0x50,0xda,0xc8,0x47,0x8e,0x40,0x20,0x38,0x36,0x90,0xc,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x2a,0xc1,0xb4,0xa1,0x97,0x88,0x8c,0x92,0x79,0x86,0xaa,0x8a,0xa2,0x32,0x4,0x26,0x3d,0x98,0xd9,0x88,0x9c,0xff,0x97,0x39,0x33,0x4d,0x1b,0x53,0x6d,0x8e,0x53,0x92,0xf0,0x50,0x26,0xda,0xf4,0xd8,0x31,0x56,0x9b,0xb1,0xe1,0x76,0x54,0xeb,0x1a,0x44,0x6e,0xda,0x5,0x32,0x8c,0x6b,0x88,0xa8,0x32,0x16,0xb3,0xf9,0x36,0x37,0xec,0xea,0x9a,0x59,0x57,0xca,0x30,0x88,0xec,0x49,0x4c,0xa6,0x25,0xca,0x9d,0xdb,0x74,0x5c,0xa5,0xd0,0xb4,0x33,0x1a,0x3,0x37,0xdd,0x52,0x7b,0xf0,0x0,0x63,0x5d,0x2d,0x8c,0x30,0xd6,0x61,0xd5,0xf,0xf8,0xd5,0xdf,0xf9,0x20,0x3e,0xfc,0xd1,0xcf,0x6c,0x6c,0x6,0xfe,0x76,0x30,0x78,0x8f,0x4f,0x7e,0xf6,0xaf,0xf0,0xbf,0xfe,0xfb,0xf7,0xe2,0xc5,0x4b,0x3b,0x95,0x88,0x8a,0xc1,0x23,0x6,0x2a,0xfd,0x88,0x29,0x22,0xf8,0xa1,0xe6,0xca,0xf5,0xdd,0x12,0x3b,0x7b,0x4b,0xfc,0xca,0x6f,0xbc,0xf,0x17,0x2f,0x5d,0xf9,0xb6,0x8e,0xe7,0x7d,0xc0,0x87,0x3e,0xf2,0x97,0xf8,0xe0,0x47,0x3f,0xbf,0x91,0x8c,0x4a,0xd1,0xd3,0x58,0xfb,0x8e,0xf2,0xef,0xb4,0xa6,0xf6,0xe5,0xdd,0x3d,0xf4,0x7f,0x83,0xb1,0x76,0x5d,0x8f,0xf7,0xbe,0xff,0xc3,0xf8,0xfc,0x97,0xbe,0x6,0xdf,0x77,0xb5,0xd1,0x37,0x78,0x4f,0xa4,0x2d,0x93,0x9e,0x0,0x11,0xc8,0x7f,0xf8,0xd1,0xbf,0xc2,0xfb,0x3f,0xf4,0x31,0xc,0x83,0xff,0x1b,0xcd,0x6f,0xca,0x19,0x8f,0x3d,0xfe,0x24,0xfe,0xdd,0x6f,0xbc,0x7,0x9e,0xcb,0x64,0xba,0xd5,0x3e,0xda,0xd9,0x1c,0x7e,0xe8,0x61,0x9d,0x43,0xc,0x9e,0xa,0x49,0x82,0x47,0x64,0xfb,0xba,0x66,0xf5,0x61,0xc9,0x4,0x2c,0x2a,0xc3,0xd2,0x14,0x5c,0xc8,0x6b,0x22,0xc6,0x53,0x7d,0xd,0x91,0x87,0x45,0xd5,0xa7,0xd6,0xde,0x1f,0xe4,0x0,0x56,0xa3,0xaa,0xb3,0x90,0xaa,0xa,0x3c,0x76,0x81,0x40,0x20,0x38,0x1e,0x10,0x5,0xa0,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x95,0x60,0x4a,0x48,0x10,0x59,0x41,0xbc,0x59,0x4a,0xb9,0x92,0x17,0x2a,0xa3,0x5a,0x7b,0x91,0x32,0x42,0x1a,0xa0,0x8d,0x19,0x95,0x83,0x19,0x55,0x25,0x95,0x53,0x84,0xb6,0xe,0x43,0xbf,0xa2,0x86,0xda,0x6c,0x8f,0xb4,0xe2,0x96,0xed,0x8b,0xa,0x2f,0x78,0x8f,0xe0,0x3d,0x72,0x4a,0x8,0xc1,0xc3,0xa5,0x84,0x76,0x36,0x27,0x95,0x9c,0x6b,0x60,0x9d,0x83,0x36,0xa6,0x9e,0xb3,0x31,0x96,0xec,0x9d,0xac,0x1e,0x33,0x9a,0x9a,0x61,0x8d,0x65,0xb,0xee,0x11,0x6e,0xcb,0xcc,0x4a,0x2c,0xad,0x35,0xa9,0xd4,0x0,0x26,0x16,0xd,0xc,0x6c,0x2d,0x3,0x71,0x4d,0x83,0xae,0xef,0xf1,0xbb,0x1f,0xfc,0x24,0x3e,0xf5,0x85,0xaf,0xe0,0xc7,0x7f,0xf8,0xad,0xb8,0xf7,0xae,0xdb,0xd0,0xb6,0xcd,0xb7,0x3c,0xbf,0xc3,0xe0,0xf1,0xe4,0x33,0xe7,0xf0,0xbe,0xf,0x7f,0x1c,0x5f,0x7d,0xfc,0x59,0x28,0x6d,0xab,0x42,0x8d,0x14,0x7f,0x80,0x56,0xa,0x89,0xcb,0x50,0x8a,0x1a,0x71,0xe8,0x3b,0x6a,0x1a,0xf6,0x3,0x9e,0x3e,0x77,0x1,0xff,0xfa,0x57,0x7f,0x1b,0xbf,0xf0,0xd3,0xef,0xc2,0xed,0xb7,0xdc,0x4,0xad,0x5f,0xbe,0x58,0xe2,0xdc,0xf9,0x97,0xf0,0x7b,0x7f,0xf4,0xe7,0xf8,0xd2,0xe3,0xe7,0x70,0xf7,0xad,0x37,0xe0,0xa8,0x89,0x88,0x91,0x4a,0x35,0x56,0xcb,0x3d,0xc4,0x48,0xc4,0xea,0x87,0x3e,0xf1,0x39,0x9c,0xbf,0xb8,0x83,0x77,0xfd,0xd0,0xf7,0xe1,0xc1,0x57,0xdd,0x8f,0xed,0xad,0xc5,0xcb,0x58,0xb8,0xd7,0x71,0xe1,0xe2,0x25,0xfc,0xe6,0x7b,0xfe,0x0,0x1f,0xf9,0xfc,0xd7,0x10,0xbd,0xc7,0x6e,0xf0,0x68,0xda,0x39,0x12,0x97,0xbb,0xb4,0xb3,0x39,0xb4,0xb1,0x75,0xdc,0x60,0xe5,0xdd,0xfb,0x3e,0xf2,0x39,0x7c,0xe5,0xd1,0x27,0xf0,0x63,0x3f,0xfc,0x36,0xdc,0x7d,0xe7,0xad,0x6b,0x99,0x7e,0xdf,0xc,0x21,0x4,0x3c,0xfb,0xdc,0x39,0xfc,0xd1,0x9f,0xfc,0x29,0x3e,0xf2,0x99,0x2f,0xe1,0xca,0x95,0x2b,0x75,0x6c,0x65,0x7d,0x37,0x33,0x2a,0x3,0xb1,0xd6,0x8d,0xa4,0x76,0x8c,0x48,0x4a,0x41,0x69,0x6a,0xb2,0xd6,0xd6,0xd6,0x16,0x6c,0x14,0xb2,0x4f,0xa9,0x9a,0x7f,0x99,0xb9,0x21,0xb8,0xac,0xe5,0x91,0xe8,0x3,0x8a,0x8a,0x56,0xad,0xad,0xb1,0x91,0x48,0x1f,0xc9,0x41,0xf9,0xbc,0x11,0x8,0x4,0xc7,0xb,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0x9,0x6a,0xf3,0x29,0x72,0xa9,0xe4,0x40,0x64,0x3b,0x64,0xce,0xb9,0xda,0x28,0x53,0xe2,0x5c,0x40,0x5,0xb2,0x31,0x32,0xe9,0x67,0xac,0xa5,0x38,0xb4,0x54,0x2c,0xc3,0xa,0x39,0xf8,0x49,0x51,0x48,0xc2,0x33,0xcf,0x9d,0xc3,0xd6,0x62,0x46,0x24,0x62,0x8c,0x95,0x48,0x79,0xea,0xd9,0xe7,0x91,0x62,0x1c,0xdb,0x80,0xb5,0x86,0xd2,0xd4,0x6,0x9c,0x52,0xc2,0x7c,0xeb,0x44,0x6d,0x6c,0xcd,0x39,0x11,0x71,0xa4,0x14,0x29,0xb7,0xb4,0xae,0xdb,0x18,0xe3,0x40,0x24,0x97,0xe2,0x2,0x92,0x8c,0xfd,0x55,0x8f,0x47,0xbe,0xf1,0x4,0x8c,0xd1,0xac,0xa8,0x3,0x52,0x4e,0xf0,0x3e,0xa0,0xeb,0xfa,0xaa,0x44,0x53,0x4a,0xa1,0x5f,0xed,0x3,0xa0,0x62,0x8c,0xa1,0xef,0xb0,0x7d,0xf2,0x4c,0xb5,0x2e,0x2b,0xad,0xa1,0x14,0xf0,0xd4,0xb9,0x8b,0xf8,0x57,0xff,0xee,0xf7,0x71,0xe3,0x99,0x6d,0xbc,0xe9,0xa1,0xbb,0xf1,0xd0,0xab,0xee,0xc7,0xd9,0x33,0xa7,0x31,0x9f,0xcf,0xe8,0x7c,0x94,0x42,0x4a,0x34,0x4f,0xcb,0xd5,0xa,0x97,0x2e,0x5f,0xc1,0x63,0x4f,0x3e,0x87,0xcf,0x3c,0xfc,0x8,0x1e,0x7f,0xee,0xa5,0x9a,0x63,0x17,0x87,0x15,0x5b,0x60,0xb9,0x3c,0x85,0x8f,0x8b,0x9c,0x61,0xac,0xc5,0x6a,0xb9,0x4b,0xcd,0xca,0x29,0x42,0xa9,0x16,0x80,0x42,0xdf,0x2d,0xf1,0xcc,0xb,0x1a,0xff,0xf2,0xdf,0xbe,0x7,0x6f,0x79,0xe8,0x1e,0xbc,0xe5,0xd,0xaf,0xc6,0x8d,0xd7,0x5f,0x83,0xf9,0xac,0xe5,0x2,0x8a,0x8c,0xae,0x5b,0xe1,0xdc,0xb,0x2f,0xe2,0x93,0x9f,0x79,0x18,0x1f,0xff,0xe2,0xa3,0xd8,0xdf,0xdf,0xc7,0x7c,0xeb,0x4,0xf6,0x96,0x1d,0x1e,0xf9,0xc6,0x93,0xd4,0xe0,0x3b,0xb9,0xce,0x2f,0x5e,0xbc,0x82,0x9c,0x22,0x96,0xab,0x7d,0x78,0x3f,0x50,0x83,0x72,0xb7,0x44,0xd3,0x2e,0xf0,0xd8,0xb3,0x2f,0xe2,0xdf,0xfc,0xfa,0x7b,0x71,0xe3,0xf5,0x9f,0xc0,0x1b,0x5e,0x7d,0x2f,0x1e,0xbc,0xff,0x4e,0xdc,0x7c,0xd3,0xd,0x58,0xcc,0x5a,0x38,0x67,0xeb,0xdc,0xe7,0xc,0x74,0x5d,0x87,0x17,0x5f,0xba,0x80,0xcf,0x7e,0xe1,0x61,0xfc,0xd1,0x9f,0x7d,0xa,0x17,0xaf,0xec,0x56,0x15,0xa3,0x75,0x6d,0x55,0x63,0x2a,0xad,0xd1,0xaf,0x68,0x8c,0xda,0x58,0x1a,0x33,0xf9,0x82,0x1,0x28,0x3c,0x71,0xfe,0xa,0xfe,0x97,0xff,0xf3,0xf7,0x70,0xef,0x2d,0xd7,0xe0,0x7b,0xbf,0xe7,0x41,0xdc,0x75,0xc7,0x6d,0x38,0x7d,0xea,0x24,0x8c,0x31,0x95,0xf0,0xcc,0x39,0x23,0xa6,0x84,0xae,0xeb,0x71,0xe9,0xd2,0x25,0x3c,0xfa,0xf8,0x53,0xf8,0xf4,0xe7,0x1e,0xc6,0xc3,0x5f,0x7b,0x1c,0xfb,0xcb,0x25,0xe7,0x53,0x52,0x9b,0xb3,0xd2,0xa,0x86,0x9,0x3f,0xa5,0x35,0xfc,0xd0,0x41,0x19,0xc3,0x65,0x33,0xae,0x52,0xa2,0x39,0x27,0x52,0x9d,0xa6,0x48,0x5,0x38,0x6c,0x5b,0x7,0x30,0xc9,0xf7,0x53,0xf5,0xfa,0x15,0x32,0xaf,0xe4,0xf9,0x4d,0xad,0xf3,0x44,0x86,0x17,0x45,0x6d,0xa1,0x3,0x33,0xb5,0x58,0x97,0x47,0xa5,0x15,0x58,0x20,0x10,0x1c,0x23,0x48,0x32,0xa9,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x70,0x95,0x60,0xeb,0xf4,0xf5,0xb8,0xf7,0xa1,0x37,0xe1,0xc4,0xe9,0x6b,0x38,0xd7,0x2f,0x32,0x69,0xa3,0x10,0xd8,0x6e,0xb,0x4c,0x88,0x8b,0x4c,0xb9,0x68,0xd4,0x92,0xda,0x50,0x71,0xf0,0x84,0x18,0x21,0xf2,0x2a,0xc1,0x3a,0xc7,0x3f,0x6b,0x28,0x6d,0x28,0x73,0x2f,0x78,0x7a,0x3e,0x86,0xaa,0x4,0x23,0xe5,0xdf,0x80,0xfd,0xdd,0xcb,0x8,0xc3,0x80,0x61,0xe8,0x2a,0x21,0x38,0x5b,0x6c,0xa3,0x6d,0xe7,0x30,0xd6,0xc1,0x38,0xc7,0x19,0x7f,0x44,0xf0,0x29,0xa3,0xe1,0x5c,0x33,0x36,0x18,0x67,0x70,0x53,0xb1,0x26,0x22,0x88,0xc9,0x3d,0x63,0x6d,0x55,0x29,0x6a,0x43,0xd,0xb0,0x39,0x25,0x2c,0xf7,0x76,0xe0,0x87,0x1e,0xfd,0x6a,0x9,0xcd,0xc4,0x90,0xd2,0xba,0x1e,0xaf,0x99,0xcd,0x39,0x7b,0x10,0x70,0x4d,0x3,0x3f,0xc,0x8,0x7e,0x80,0xd6,0x1a,0xcb,0x3d,0x22,0xcf,0xce,0x9c,0x3a,0x89,0x33,0x27,0x17,0x38,0x75,0xea,0x34,0xda,0xb6,0x41,0x88,0xc0,0xde,0xb2,0xc3,0x72,0x88,0xd8,0x5b,0xf6,0x4c,0x9c,0x92,0xb2,0x30,0x30,0x29,0xa,0x90,0xcd,0x3a,0xc5,0x8,0x28,0x22,0x9c,0x0,0xb2,0x62,0xf7,0xab,0x25,0x56,0xcb,0xbd,0x9a,0x93,0x97,0x52,0xc4,0x62,0xeb,0x24,0xda,0xf9,0x2,0xc6,0x3a,0xb4,0xb3,0x5,0x42,0x18,0xe0,0x5c,0x8b,0xd6,0x24,0xdc,0x70,0xf6,0x24,0xac,0xca,0x8,0x31,0xe2,0xb9,0x17,0x2e,0xe0,0xc2,0x95,0x7d,0x58,0xd7,0xd4,0xf3,0x56,0x8a,0xae,0x87,0xb6,0x96,0x8,0x50,0xb6,0x66,0x97,0xb1,0xa6,0x14,0xd1,0x2d,0xf7,0xe9,0x3a,0xc4,0x88,0xd5,0x72,0xf,0xce,0x35,0x58,0x9c,0x38,0x45,0x6a,0x39,0x63,0x60,0x5d,0x3,0xa5,0x14,0x1a,0xe7,0x70,0x6a,0x7b,0x86,0x33,0x27,0x4f,0xc0,0xa8,0x4,0x6d,0x1c,0x56,0xcb,0x7d,0x5c,0xdc,0xd9,0xc7,0xd3,0xcf,0x3d,0x5f,0x9,0xc4,0x14,0x13,0x82,0xef,0xd1,0xad,0x96,0x98,0xcd,0xb7,0xe8,0x1c,0x8c,0x85,0xd6,0xa6,0x66,0x39,0xda,0xa6,0x41,0xdb,0x2e,0xc8,0x3a,0xce,0x8a,0xbc,0x18,0x3d,0x52,0x4a,0x58,0xed,0xef,0xc2,0x35,0x2d,0xba,0xe5,0x1e,0xae,0x3f,0x73,0x12,0x67,0x4f,0x9f,0xc4,0x62,0x31,0x87,0xb3,0x16,0xcb,0x7e,0xc0,0xfe,0xb2,0xc3,0xf9,0x17,0x2f,0x60,0xd9,0xd3,0x5a,0xea,0x56,0x7b,0x30,0xda,0x20,0xe5,0x8c,0x6e,0xb9,0x7,0x80,0x4a,0x54,0xfa,0xd5,0x12,0x39,0x27,0xb8,0x76,0x86,0x7e,0x45,0x63,0xd4,0x6c,0x75,0x6e,0xf8,0x1a,0x6b,0xb6,0x96,0x87,0xe0,0x79,0xd,0x84,0x35,0x82,0xae,0xa8,0x4d,0x2b,0x71,0xaa,0x34,0xcd,0x5f,0x1c,0x33,0x2d,0xd7,0xad,0xf1,0x19,0x58,0xd7,0x1,0x92,0xaa,0x30,0x46,0x84,0x30,0xc0,0xf,0x3,0x2e,0xbe,0xf0,0x1c,0x9e,0x7f,0xfc,0xcb,0xf2,0xc1,0x23,0x10,0x8,0x8e,0x5,0x44,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x45,0xc8,0x39,0x11,0x6d,0x51,0x89,0x3c,0xaa,0x32,0xd8,0xa8,0x55,0xe2,0x7,0x53,0x4a,0x40,0x20,0x2b,0x27,0xd9,0x70,0x29,0xf3,0xaf,0x14,0x28,0xa0,0x34,0xf2,0x9a,0x19,0x7c,0xdf,0x21,0x59,0x4b,0xa4,0xa2,0x1f,0xc8,0x6e,0x5a,0x2d,0xc3,0x9,0x61,0xe8,0x1,0x2e,0xc1,0x18,0xba,0x25,0x56,0xfb,0x7b,0x68,0xe7,0xb,0xb8,0x66,0x86,0x68,0xc9,0x92,0x69,0xac,0x85,0x75,0x2d,0x91,0x58,0xc6,0x40,0x41,0x21,0x78,0x22,0xb2,0x22,0x5b,0x4d,0x63,0x88,0x40,0x8c,0x9c,0x4f,0x48,0x39,0x81,0x0,0xd9,0x92,0x95,0xd2,0x35,0x3,0xae,0xe4,0xbc,0x91,0xfa,0xcb,0x21,0x86,0x40,0xff,0x45,0xca,0xa1,0x5b,0x38,0xc7,0x45,0x24,0x3d,0x5c,0x33,0x43,0xf0,0x94,0x33,0x8,0x85,0xaa,0x42,0x1c,0x86,0x1,0xcf,0x3d,0xff,0x3c,0xae,0xec,0x9d,0x86,0x3e,0x7f,0x19,0xae,0x69,0xab,0xcd,0xb4,0xe4,0x20,0x2,0xac,0x96,0x64,0x2b,0x69,0x4a,0x91,0xcf,0x85,0xc9,0x52,0x45,0x84,0x64,0xc,0x1,0x43,0xb7,0xa4,0x9b,0x31,0xb6,0xfd,0xfa,0x61,0xa8,0xc7,0x2c,0x2d,0xcb,0x64,0xab,0xd6,0xf0,0xbe,0x87,0x1f,0x32,0x2e,0x3e,0xf6,0xc,0x62,0xc,0xe8,0xf6,0xf7,0x10,0x82,0xc7,0x7c,0xb1,0x8d,0xa0,0x3c,0x54,0x4f,0x99,0x88,0x28,0x4a,0xbd,0x94,0x6a,0xd3,0x71,0xc8,0x43,0x6d,0x4f,0x4e,0x31,0xc0,0xf,0x3d,0x72,0x4a,0xd8,0xdb,0xb9,0x84,0x66,0x36,0x87,0xf7,0x3,0x7c,0xdf,0x1,0x39,0x43,0x27,0x53,0xed,0xd7,0x41,0x1b,0x9c,0xbf,0x70,0x5,0x2f,0x5e,0xdc,0x9d,0x8c,0x4d,0xa3,0x5f,0x2d,0xe1,0x9a,0x16,0x29,0x46,0x38,0xd7,0xa0,0x8f,0x1d,0x94,0xd2,0x68,0x67,0x73,0x9e,0x2b,0xc0,0xc4,0x8,0xb0,0xb2,0xce,0x35,0x2d,0x72,0xca,0xf0,0x43,0x47,0x4a,0x40,0x15,0x6a,0xe,0x65,0x60,0x25,0xe2,0xfe,0xce,0x65,0xc4,0x18,0xf1,0xdc,0x8b,0x17,0xf1,0xf4,0xf3,0xe7,0xd1,0xb4,0x33,0x22,0x21,0x67,0xb,0x5a,0x27,0xdc,0x2e,0x1d,0x86,0x1e,0x89,0xb3,0x28,0x8d,0xb5,0xf4,0x3a,0xad,0x31,0x74,0xab,0x9a,0x25,0x49,0xaa,0x55,0x3,0xd7,0xcc,0x90,0x73,0x82,0x31,0xe,0xc6,0x58,0x56,0xf9,0xb1,0xe5,0x17,0xb4,0xe,0xf5,0x81,0x6,0xdf,0x62,0x35,0x1f,0xad,0xbf,0xa,0x31,0xfa,0x5a,0x7a,0x73,0x38,0x63,0x52,0x8d,0x3e,0x5f,0x2e,0x14,0x29,0x19,0x9a,0xbc,0x57,0x88,0xd6,0x46,0x20,0x10,0x1c,0x27,0x8,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x25,0xc8,0x98,0x64,0xfd,0x4d,0x6c,0x8b,0x29,0x25,0x28,0xad,0xaa,0x1d,0x92,0xa,0x81,0xf5,0x1a,0xc9,0x57,0xec,0x92,0x94,0xe3,0x17,0x6a,0x5e,0x9a,0x73,0x2d,0x42,0x8,0x50,0x13,0xf2,0xaa,0x34,0xae,0x1a,0xb6,0x1c,0x2b,0x63,0x38,0xeb,0x8f,0x48,0xc4,0x18,0xc9,0x4e,0x5c,0x14,0x71,0xb3,0xc5,0x36,0xdb,0x5b,0x23,0xac,0x6e,0xd8,0x82,0xc9,0x44,0xd1,0x30,0x90,0xa,0x31,0x46,0x18,0x4b,0x4a,0xc3,0xa1,0xef,0x60,0x8c,0x41,0x8c,0x11,0x8e,0x5b,0x75,0xa9,0x65,0x37,0x70,0xb3,0xeb,0xc0,0x85,0xf,0xa,0x4a,0x2b,0x26,0xf5,0xc,0x96,0x7b,0x3b,0x88,0x81,0x88,0x30,0x0,0x64,0xf,0x4d,0x34,0x1e,0xd7,0xce,0x48,0x2d,0xc7,0x59,0x71,0x29,0x4,0x78,0x3f,0xa0,0x5b,0x52,0xb9,0xc4,0x90,0x33,0xf6,0x76,0x2e,0x61,0xeb,0xc4,0xe9,0x35,0xe5,0x58,0x4e,0x89,0xd4,0x63,0x29,0xc1,0x6a,0x53,0x49,0xcf,0x72,0xbe,0xc1,0x7b,0x56,0x44,0xe,0x6c,0x59,0x8d,0x55,0x21,0xd8,0xb1,0x1d,0xb9,0x90,0x4f,0x43,0xb7,0x82,0xd9,0xb2,0x44,0xca,0x1,0x70,0xcd,0xc,0x29,0x78,0x64,0x64,0xf4,0xdd,0xaa,0x2a,0xf7,0x16,0x5b,0x27,0xa8,0xec,0x22,0x27,0xb2,0x13,0x17,0x92,0x34,0x78,0x20,0x78,0x26,0xac,0x88,0xac,0xd,0x7e,0x20,0x2a,0x8a,0xc9,0x2a,0x3f,0x74,0x9c,0xd5,0x17,0xe1,0x87,0xe,0xd8,0x3a,0x31,0xda,0xbe,0x99,0x44,0x2c,0x63,0x88,0xac,0x60,0xb4,0xd6,0xb1,0x9d,0x96,0xae,0x43,0x19,0x2f,0x11,0xb5,0xe,0xab,0xbd,0x1d,0xc,0x43,0x7,0xad,0x34,0x86,0x44,0xb6,0xef,0xa1,0x37,0x68,0xe7,0xb,0xf8,0xa1,0x47,0x3b,0x5b,0x40,0x1b,0xb,0xd7,0x94,0x3c,0x45,0xb2,0xd0,0xe,0xfd,0x8a,0x33,0x12,0x7,0xa8,0xc0,0xcd,0xbb,0x4c,0x62,0x96,0xd6,0x64,0xe4,0x4c,0x5,0x32,0xa0,0x42,0x17,0x6d,0x2c,0xa2,0x1f,0x78,0x6e,0x49,0xe9,0x7,0x0,0x3a,0x1b,0x5e,0x4b,0x5b,0x40,0xce,0x6c,0xf3,0xe5,0x52,0x8e,0x3c,0x29,0xf3,0xd0,0xba,0x92,0x90,0x45,0xcd,0x3a,0x5a,0x7a,0xf3,0x24,0xcf,0x2f,0xd5,0xf5,0x89,0xe9,0x6b,0x68,0x43,0x70,0x2b,0x8,0x78,0xe7,0x44,0xf5,0x29,0x5,0x24,0x1a,0x5f,0x39,0xa6,0x40,0x20,0x10,0x1c,0x17,0x18,0x0,0xff,0x93,0x4c,0x83,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0xf0,0xff,0x7f,0xd8,0x66,0x8e,0x6b,0xae,0x7f,0x5,0x66,0x8b,0x2d,0x28,0x26,0x61,0xa,0xf1,0x91,0x52,0x21,0x93,0x2c,0x32,0x72,0xcd,0x7e,0xab,0xd9,0x67,0xac,0xf4,0xd3,0x5a,0x43,0x73,0xeb,0x6e,0x51,0xd6,0x21,0xa7,0x31,0xeb,0x8d,0x95,0x7e,0x95,0xc0,0x1,0x2a,0xa1,0x64,0xac,0x23,0x85,0x60,0x4a,0x58,0x2d,0xf7,0x30,0xf4,0x1d,0x94,0x22,0x52,0xca,0xb8,0x6,0xae,0x9d,0x41,0x41,0xc1,0xb9,0x76,0xa2,0x9d,0xa2,0xf6,0x5c,0xc3,0x96,0xde,0xd1,0x7e,0xcc,0xca,0x45,0xad,0x6b,0xeb,0x6c,0xb1,0x24,0x97,0xe2,0xd,0x22,0x99,0x3a,0xa4,0xe0,0x2b,0x29,0x37,0x74,0x2b,0x22,0x1a,0x6d,0x3,0xd7,0xb4,0x64,0x1d,0x36,0xb6,0x2a,0xe5,0x0,0xd4,0x46,0xe3,0x18,0x2,0x13,0x68,0x19,0xdd,0x72,0x9f,0xa,0x24,0xb8,0x49,0x56,0x6b,0xcd,0xa4,0x28,0xcd,0x8d,0x2,0x95,0x51,0x4,0x3f,0x4c,0xa,0x4f,0x7c,0x55,0xa0,0x15,0x22,0x95,0x32,0xf,0x23,0x8f,0x5d,0xd7,0xfd,0x2,0x64,0x83,0x2e,0xc7,0x4e,0x21,0x40,0x71,0xe1,0x49,0x8,0x1e,0xc8,0x99,0x1a,0x76,0xc3,0x80,0xc4,0x96,0xe1,0x76,0xb6,0x18,0x33,0xfa,0x52,0x82,0xd1,0x86,0xc9,0x29,0x70,0x8e,0x63,0x21,0x39,0x23,0x37,0xf4,0xe,0xd0,0x8a,0x6c,0xcd,0x21,0x78,0xb6,0xc4,0xe,0x9c,0xa5,0x98,0x58,0x35,0x67,0x91,0x33,0xc6,0x7c,0x3d,0x26,0xba,0xfc,0xd0,0x53,0x56,0x61,0xb1,0x15,0xf3,0x7a,0xc8,0x3c,0xdf,0x0,0x11,0xbb,0x39,0x93,0xb5,0x77,0xcc,0x80,0x54,0xa3,0x42,0x6f,0x42,0xf0,0xc5,0x48,0xeb,0x23,0xe5,0xc8,0xaa,0x4c,0x5f,0xd7,0x22,0x91,0x7a,0xf4,0x67,0x25,0x1e,0x73,0x42,0x62,0xfb,0x30,0xa9,0x3d,0xc1,0x99,0x90,0x94,0x77,0x68,0x5d,0x53,0xe7,0x8b,0x96,0xd,0x65,0x2f,0x42,0xd1,0xeb,0xac,0x73,0x94,0x7f,0x15,0x23,0xc0,0xea,0xbf,0xa2,0x2,0x24,0x45,0xa0,0xa9,0xc4,0xf5,0x94,0xe0,0x9d,0xaa,0x65,0xcb,0x98,0x79,0x91,0x80,0x9f,0x1a,0x5f,0xab,0x28,0x7b,0x32,0x33,0xd1,0xdb,0x2d,0xf7,0xb0,0x77,0xf9,0x25,0xf9,0xe0,0x11,0x8,0x4,0xc7,0xe3,0xdf,0x0,0x32,0x5,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x2,0x56,0x44,0x8d,0xca,0xa7,0xb1,0x1,0xb8,0x28,0xc6,0x32,0xdb,0x1f,0x13,0x5b,0x69,0x73,0xca,0x55,0x79,0x57,0xb2,0xe4,0xa6,0x8d,0xa9,0x9a,0xb7,0xf1,0xbe,0x87,0x31,0x25,0x8f,0x8f,0x6c,0x94,0xa9,0x94,0x26,0xb0,0xed,0xd2,0x7,0x5f,0x73,0x0,0x3d,0x5b,0x3a,0x53,0x8c,0x98,0x6f,0x9d,0xa8,0x24,0x90,0x73,0xd,0x35,0xc9,0xea,0xa6,0x96,0x38,0x18,0xa3,0x88,0x10,0xcc,0xa9,0xaa,0x13,0x13,0x2b,0x4,0x2b,0x19,0xc5,0x96,0xdd,0x42,0x1a,0x95,0xbc,0x39,0x6b,0x1d,0x93,0x73,0x1,0x7d,0xb7,0x24,0xa5,0x61,0x54,0x8,0x61,0x80,0xf1,0x16,0xb3,0xc5,0x76,0x55,0x10,0xd2,0x38,0x33,0x72,0x8a,0xf0,0xc3,0x40,0x67,0xae,0x34,0x96,0xbb,0x44,0x98,0xb9,0xa6,0x25,0x2b,0x32,0x17,0x5d,0x8c,0x45,0x24,0x9,0x21,0x6,0x22,0x1e,0x87,0x1e,0x4a,0x6b,0x68,0x26,0x15,0xbb,0xe5,0x1e,0xab,0xb,0x89,0x80,0xa4,0xf2,0x91,0x15,0x62,0xf0,0x18,0xba,0xe,0xae,0x6d,0x11,0x0,0xb6,0x35,0x93,0x6d,0xd9,0xb9,0x16,0xcd,0x6c,0x5e,0xc9,0xbc,0xe0,0x87,0xfa,0x9f,0x52,0x9a,0x54,0x91,0xce,0x61,0xb5,0xbf,0xb,0xeb,0x88,0xc8,0x9c,0x2f,0xb6,0x31,0xb0,0x72,0x50,0x15,0x62,0xcb,0xd0,0x75,0x2c,0xaf,0xcb,0x89,0x8e,0x4f,0x4,0x63,0x84,0x8f,0x3d,0xcd,0xbd,0x27,0xb2,0xb1,0xd8,0xb6,0x8b,0xd2,0x2f,0xc6,0x0,0x63,0xf2,0x24,0xd3,0x10,0x95,0x68,0xd,0xbe,0xaf,0xca,0x38,0xa5,0xc9,0x6,0x9c,0x52,0x84,0x8a,0xaa,0x92,0xc3,0x7e,0xe8,0x61,0x9b,0x66,0xb4,0x24,0x73,0x49,0x47,0x21,0xd5,0xbc,0xef,0x2b,0xf1,0x18,0x82,0xaf,0x84,0x63,0x4c,0x11,0xb3,0xf9,0x16,0x90,0x51,0xcb,0x45,0x9c,0x6b,0x11,0x15,0xcd,0x4f,0x64,0x72,0x34,0x71,0xb9,0x48,0x21,0x39,0xcb,0xb9,0x84,0x40,0x44,0x34,0xa9,0x5a,0xc1,0xb6,0xe8,0x30,0xe6,0x57,0x96,0x76,0x5f,0x26,0x2f,0xa9,0xe5,0x3a,0x8d,0xca,0xbe,0x3c,0x51,0xf5,0x61,0x3d,0xed,0xaf,0x34,0x67,0xd3,0x10,0xe,0xb6,0x1,0x1f,0x7a,0xbb,0x9,0x4,0x2,0xc1,0xb1,0x81,0x96,0x29,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0xae,0x22,0x70,0x49,0x6,0x11,0x81,0x5c,0x4c,0x51,0x9,0xbd,0x92,0x67,0x97,0x6b,0xd1,0x46,0xb1,0x65,0xc6,0x18,0x2a,0xd9,0x96,0xb9,0x2d,0xb5,0x5a,0x6f,0xb9,0x48,0xa4,0x14,0x7a,0x14,0xc2,0xa7,0x3c,0x4f,0x8d,0xbf,0x9a,0x15,0x5c,0x1,0x21,0x4,0x38,0xd7,0x40,0x6b,0x8d,0xc8,0xd9,0x74,0x89,0x2d,0x9b,0x29,0xc5,0x6a,0x59,0x35,0xc6,0xae,0x29,0xcc,0xb4,0x26,0xf5,0x5d,0x62,0x42,0x47,0x6b,0x3,0x6d,0x2c,0x52,0xc,0x48,0x4c,0xb0,0x5,0x4f,0x36,0x63,0xca,0x98,0xa3,0x42,0x8e,0x10,0x3c,0x86,0xbe,0x27,0x32,0x50,0x69,0x2a,0x1f,0xc9,0xb9,0x92,0x84,0x45,0xad,0x98,0x52,0xa8,0xaa,0x45,0x80,0x72,0xf8,0x52,0xa,0x95,0x54,0x24,0xfb,0x70,0x87,0xe0,0x7,0xac,0xf6,0x77,0xb9,0x50,0x23,0xd5,0xc2,0x10,0xa5,0x34,0x9a,0xd9,0xbc,0xce,0x45,0xf0,0x9e,0xc8,0x3f,0x1e,0x63,0xcd,0x54,0x8c,0xa4,0x0,0xd4,0xc6,0xd4,0x62,0x92,0xa1,0x5f,0xb1,0x4a,0x4e,0x57,0x55,0x5f,0x4a,0xa4,0x7a,0x2b,0xe3,0xc9,0x39,0x55,0x5,0x63,0xa,0xa4,0xb6,0xf3,0x43,0x4f,0x44,0xe3,0x6a,0xbf,0x5a,0x78,0x8b,0xb2,0x6d,0xe8,0x3a,0xf4,0xab,0xfd,0x5a,0x7c,0x92,0x72,0x42,0xdf,0xad,0x10,0x2b,0xb9,0x67,0x30,0x74,0x2b,0x44,0x1e,0x37,0x8d,0x33,0xa0,0x5f,0xad,0x48,0xb5,0x19,0xa8,0x29,0x99,0x32,0x13,0x43,0xbd,0xe,0x65,0x8e,0x15,0x14,0x5b,0x81,0x1d,0x52,0x4e,0x44,0xde,0xa6,0x8,0xa3,0xd,0xf6,0xae,0x5c,0xc2,0xfe,0xee,0x65,0x5c,0xb9,0xf0,0x2,0xf6,0x76,0x2e,0xd3,0xf9,0xb3,0xaa,0xb0,0x5c,0xdf,0x72,0x6d,0x53,0x8a,0xf5,0xba,0x2f,0xf7,0x76,0xa8,0x24,0xa5,0x5b,0x51,0xd1,0x48,0x8a,0xac,0xa0,0xf4,0x5c,0xf4,0xe2,0x6a,0x61,0x87,0x6d,0x5a,0x28,0xad,0xd8,0x3e,0x4e,0xd7,0xa1,0x5b,0x2d,0xe9,0x18,0x89,0x54,0xa9,0x4a,0x81,0x4a,0x65,0xb8,0x4,0x64,0xcd,0xfe,0x3b,0x59,0x97,0x79,0x4a,0xa,0xd2,0xe0,0xe8,0x72,0x55,0xa5,0x1f,0x29,0xfb,0x88,0xbc,0xa4,0xeb,0x58,0x88,0xe7,0x31,0x1f,0xb0,0xbc,0xb7,0xb0,0xa6,0x56,0x15,0x8,0x4,0x82,0xe3,0x0,0x51,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0x9,0x12,0x67,0xf8,0x11,0xb9,0xa1,0x0,0x95,0x2b,0xc1,0x44,0xe4,0x86,0x1a,0x33,0xd3,0x90,0xa1,0x59,0x2f,0x90,0x73,0xaa,0x24,0x4b,0xb1,0xa,0x27,0xb6,0xfb,0x6a,0x6d,0xd8,0xf6,0x98,0x91,0x32,0x95,0x34,0x54,0xa5,0x20,0x80,0x9c,0x28,0x53,0x4e,0xb1,0x5d,0x38,0x45,0x2a,0xc7,0xf0,0x9e,0xec,0xb6,0x7e,0x18,0xa8,0xcd,0x56,0xeb,0x6a,0xe1,0x2d,0x14,0xa,0x65,0xb,0xb2,0xd5,0x37,0x27,0xa4,0x44,0xcd,0xc5,0xc6,0x58,0x22,0x7c,0x94,0xaf,0xad,0xbb,0xc6,0xd8,0xb5,0xac,0x42,0xa5,0x35,0xba,0xd5,0x92,0xbb,0x1a,0x52,0xb5,0xdf,0x16,0x2b,0xb0,0x6b,0x5a,0x26,0x23,0xc9,0x7e,0x3b,0x80,0x32,0xf7,0xc,0xe7,0xdb,0x25,0x56,0x94,0x35,0xed,0x1c,0x7e,0xe8,0xab,0x3a,0x72,0x7f,0xf7,0xa,0x86,0xa1,0xc7,0x7c,0x71,0x2,0x1d,0x37,0xce,0xda,0xa6,0xad,0x24,0xa9,0xb1,0xae,0xce,0x13,0xe5,0x0,0xda,0x4a,0x9e,0xad,0xf6,0x77,0x91,0x53,0x26,0xb2,0x4e,0x95,0xc6,0x65,0x8d,0x7e,0xb9,0x8f,0xed,0xd3,0x67,0x69,0x5c,0x31,0x20,0x46,0x8b,0x9c,0x7b,0xb2,0xba,0x72,0x66,0x9d,0xd6,0x6,0xdd,0xb0,0x57,0xc9,0xc4,0x62,0xab,0x75,0x4d,0x8b,0xa1,0x5f,0xa1,0x99,0x2d,0x58,0x21,0xa8,0x30,0xc,0x3d,0x13,0xb4,0x9,0x39,0x83,0x15,0x87,0xa1,0x2a,0x2f,0xb,0x99,0xb5,0x73,0x79,0x17,0x67,0xaf,0xbb,0xa9,0x12,0x5a,0x6b,0xc4,0x6e,0x8c,0xa4,0xa4,0xe3,0x8c,0x48,0x63,0xc,0x37,0x2e,0xd3,0x75,0x77,0xae,0x65,0xeb,0xad,0xc3,0xd0,0x13,0xa1,0x3a,0xc,0x7d,0x9d,0x63,0xd7,0xb6,0xe8,0xbb,0x15,0x91,0x8f,0x4c,0x6c,0xe,0x43,0x87,0xa6,0x9d,0x55,0x72,0xd6,0x36,0x2d,0x95,0xc2,0x40,0x91,0x25,0x1a,0x80,0x75,0xd,0xfc,0xd0,0x43,0xeb,0x50,0x5f,0x5b,0xce,0xc9,0x72,0xe3,0x33,0x15,0x7e,0x0,0xd1,0x13,0xd1,0xec,0x3,0xd9,0xca,0x87,0xae,0xa3,0x35,0x36,0x21,0xfb,0x48,0x8d,0x8a,0x4a,0x36,0x6b,0xce,0xa3,0xa4,0x75,0x9d,0x47,0x1b,0x3c,0x26,0x84,0x1f,0xbf,0x47,0xa,0xca,0xf1,0x15,0x40,0xaa,0xc2,0x54,0xac,0xf1,0xc0,0x58,0xf6,0xb1,0xde,0x8,0xc,0x60,0x8d,0x4c,0x16,0x8,0x4,0x82,0xbf,0x6b,0x8,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x35,0xd0,0x6c,0xa5,0xcd,0xc8,0x6a,0x9d,0xf8,0xc8,0x8a,0x8,0x11,0xad,0x46,0x7b,0x2d,0x11,0x85,0xba,0x2a,0x1,0x15,0x5b,0x3b,0x63,0x8c,0x94,0x31,0xa7,0x14,0x42,0x62,0xb2,0x84,0x15,0x75,0xd3,0xd2,0x90,0x62,0x17,0x56,0x4a,0x91,0x4a,0x2f,0x92,0x42,0x70,0x24,0xc9,0x22,0xac,0xa3,0xa6,0x56,0x80,0x6c,0xba,0xb6,0x69,0x41,0xd,0xac,0xb1,0x2a,0xe9,0xc,0x13,0x3f,0xda,0x1a,0x34,0xad,0xe3,0x86,0xdd,0xcc,0xd9,0x78,0xc3,0x5a,0x59,0x43,0x8c,0x9e,0x6d,0xc8,0x63,0xf6,0x5c,0x51,0x25,0x2a,0x28,0xac,0xf6,0xa9,0xd9,0x76,0xef,0xca,0x25,0x2c,0xb6,0x4f,0x22,0xa7,0x8,0xc0,0x55,0xa2,0x91,0x8a,0x4a,0xe8,0x9c,0x9d,0x6b,0xd0,0x75,0x4b,0x28,0x6d,0xa0,0x8d,0x41,0xb7,0xdc,0x1b,0xf3,0xc,0x8d,0x21,0xb,0x35,0x13,0x52,0xb9,0xa5,0x6,0x61,0xd7,0x90,0x9d,0xb5,0x90,0x69,0x31,0x64,0xb6,0xb7,0xc6,0x5a,0x40,0x92,0x53,0x82,0x32,0x64,0xb7,0xd,0xc1,0x63,0x36,0xdf,0x46,0xf4,0x54,0xa0,0xd2,0xce,0xe6,0xc8,0x4c,0xba,0x69,0xad,0x11,0x38,0x77,0x90,0x54,0x72,0x9,0x7d,0xb7,0xac,0xc4,0x5b,0x64,0x5b,0x32,0x29,0x28,0xa9,0x75,0xb7,0x14,0xa8,0x4,0xef,0xa9,0xca,0x82,0x73,0xfb,0x8a,0xe2,0x10,0xc8,0x8,0xde,0x63,0xb5,0xbf,0x8b,0xc5,0xf6,0x9,0xf4,0xdd,0x3e,0x80,0x8c,0x66,0xb6,0xa8,0x6a,0xcd,0xc8,0x73,0xe0,0xfb,0x55,0xcd,0x42,0x1c,0x38,0x53,0x8f,0xc8,0x4e,0x22,0x8b,0xbd,0x1f,0xd0,0x34,0x2d,0xa9,0x1f,0x41,0x6b,0x83,0xd6,0x40,0x1c,0x8b,0x50,0x8c,0x85,0xd6,0x6,0xde,0x53,0x19,0x48,0xb9,0x16,0xc6,0x58,0x28,0xa0,0x36,0x4a,0x5b,0xeb,0xb0,0xdc,0xdb,0xa9,0x64,0x62,0x3b,0x5f,0xd0,0xd8,0x57,0xfb,0x98,0x6f,0x9d,0xe4,0xb9,0xf4,0x80,0x52,0xf5,0xfa,0x96,0xe6,0xdf,0x62,0xb,0xce,0x39,0xa2,0x5f,0xad,0x60,0x9c,0x83,0x5d,0x34,0x64,0xcd,0xf6,0x3,0x5c,0x3b,0xaf,0x5,0x36,0x65,0x9d,0x14,0x7f,0xae,0xaa,0xa,0xbf,0x5c,0x15,0x94,0x45,0x15,0xa8,0x30,0x29,0xa,0xa9,0xef,0x21,0x22,0xc9,0x35,0x13,0xcd,0x23,0xc4,0xef,0x2b,0x10,0x8,0x8e,0x37,0xa4,0x4,0x44,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0xb8,0x4a,0x60,0x9b,0xd9,0x5a,0x9,0x8,0x80,0x4a,0x8c,0x14,0xa2,0xa3,0xb4,0x4,0x6b,0xce,0xff,0x83,0x1a,0x6d,0x8d,0x7,0xcb,0x10,0x36,0x15,0x23,0x90,0xb2,0x50,0x21,0x85,0xc0,0x84,0x10,0x65,0xe5,0x81,0xb3,0x5,0x8b,0x95,0x36,0xc5,0x80,0xdd,0x2b,0x17,0xc9,0xee,0xa,0x60,0x36,0xdf,0x82,0x6b,0x5b,0x18,0x6d,0x90,0x1,0x68,0xa5,0xd9,0xba,0x1a,0xe8,0xc6,0x85,0x4b,0x46,0xfc,0xd0,0x13,0x91,0x95,0x1,0xa3,0x4d,0x6d,0xf,0x2e,0x36,0x57,0xeb,0x1a,0x7a,0x8e,0x6d,0xa2,0x31,0x6,0xce,0xcf,0xeb,0xe1,0x99,0xbc,0x53,0x4a,0x55,0xd5,0xa0,0xd6,0x6,0xae,0x69,0x60,0x39,0xe7,0xb0,0xcc,0x89,0xb1,0x16,0x50,0xa,0x46,0x1b,0x84,0x61,0x40,0x62,0xd2,0x6f,0xb5,0xdc,0x43,0xc,0x1e,0x6d,0x3b,0xc7,0xd0,0xaf,0x2a,0xd9,0x9,0xa8,0x49,0x4e,0x9f,0x82,0xf7,0xa4,0x86,0xeb,0x57,0x4b,0x7e,0x9c,0x32,0xee,0xa8,0x68,0x24,0x23,0x45,0x6a,0xf,0x36,0x25,0xab,0xb0,0x69,0x58,0xc5,0x48,0x24,0x9a,0xe6,0x12,0x8d,0xc,0xd4,0xe6,0xdd,0x62,0xf7,0xa5,0x76,0x5c,0xc0,0xb3,0xad,0x96,0xec,0xd9,0xa1,0x66,0x17,0x2a,0x28,0x56,0xf0,0xd,0xf0,0xc3,0x80,0xbe,0x5b,0xd6,0x92,0x93,0xd5,0xfe,0x6e,0x2d,0x26,0x19,0xfa,0x15,0x66,0x5b,0x27,0xa8,0xb1,0xd9,0x52,0x63,0x73,0x99,0xc3,0xbe,0x5b,0x41,0x29,0x8d,0xd5,0xfe,0x2e,0xfa,0x7e,0xc5,0x2d,0xce,0xfe,0x80,0xd,0x38,0xd7,0xa6,0xe4,0x18,0x3c,0x95,0x94,0xf8,0x1,0x4d,0x3b,0xc3,0xd0,0xad,0x28,0xc7,0x10,0x54,0xac,0xe1,0x9a,0x59,0x9d,0x5f,0xa5,0x74,0x25,0x83,0x63,0x8c,0x35,0x9f,0x2f,0xa7,0x84,0x6e,0xb5,0x4f,0x24,0x33,0x37,0x4a,0x8f,0x76,0xea,0xbe,0x12,0x9b,0xc5,0x6,0x1d,0xfc,0x0,0xdf,0x77,0xdc,0xb0,0xcc,0x65,0x22,0x29,0xf2,0xf8,0xc9,0x22,0xed,0xda,0xb6,0xae,0xeb,0xb1,0xd8,0xa6,0x5e,0x68,0x8c,0xea,0xbd,0x22,0x83,0xac,0x4f,0xd6,0x3f,0x2a,0xf9,0xc7,0x6a,0xd2,0xd2,0x62,0x5c,0xb6,0x55,0xdc,0xfa,0x5b,0x9e,0xcf,0x39,0x23,0x85,0x80,0xd5,0xfe,0x2e,0xf6,0xaf,0x5c,0x90,0xf,0x1e,0x81,0x40,0x70,0x3c,0xfe,0xd,0x20,0x53,0x20,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x1d,0xd0,0x6c,0xb,0x2d,0xc8,0x9c,0x7,0x58,0xf8,0x8f,0xb1,0x24,0x81,0x5f,0x5f,0x94,0x50,0x13,0x92,0xaf,0x36,0xe1,0x96,0x22,0x84,0x94,0x58,0x39,0x55,0x2c,0x8f,0x19,0x4a,0x19,0xa8,0x92,0xd7,0x17,0x8b,0xa5,0x57,0x8d,0xd6,0x4b,0xce,0x7c,0x9b,0x2f,0x4e,0x60,0xe7,0xf2,0x4b,0x38,0x7d,0xcd,0xd,0x18,0xfa,0xe,0xae,0x69,0x49,0x65,0x56,0xb2,0xd9,0xd8,0x42,0xb,0x56,0x7f,0x69,0x63,0x2a,0xb9,0x45,0x2a,0x3c,0x5b,0xcf,0x39,0x6,0xf,0xa5,0x35,0x86,0xbe,0xe3,0x76,0xdb,0xb0,0xd6,0x90,0x5b,0xb3,0x9,0xd9,0x9e,0x4b,0xb9,0x7d,0x86,0xb3,0xff,0x98,0xc,0x9b,0x6f,0xd5,0x26,0xd8,0xa1,0x23,0xf5,0x5b,0x51,0x12,0x52,0x99,0xc6,0xe,0x9a,0x76,0x86,0x7e,0xb5,0xc4,0xe5,0xb,0x2f,0x60,0xb6,0xd8,0x42,0xc,0x1,0xae,0xe9,0xd9,0x8a,0x5b,0xc6,0xa0,0xab,0x5,0xb8,0xd8,0xa1,0x4b,0xe1,0x89,0xe6,0xd6,0xda,0xe0,0xfb,0x9a,0x51,0xb8,0x7d,0xf2,0xc,0x37,0xdf,0x8e,0x8a,0xb4,0x32,0xfe,0x42,0xa2,0xc6,0x48,0x16,0xd8,0x6e,0x7f,0xf,0x40,0xc6,0xde,0xce,0xa5,0x7a,0x5e,0x2e,0x4,0xcc,0xb7,0x4f,0x12,0x41,0x68,0x1b,0xac,0x96,0x7b,0x4c,0xea,0x16,0xcb,0x75,0x42,0xc8,0x19,0x7d,0xb7,0x42,0x8a,0x9,0xab,0x61,0x17,0x7d,0xb7,0xc4,0x62,0xfb,0x24,0x9d,0x97,0x52,0x88,0xde,0x43,0x6b,0x4d,0xaa,0xc9,0xe0,0xb9,0x90,0x24,0xd5,0xf9,0x1b,0x2,0x6d,0x5b,0x88,0x39,0x6d,0x2c,0x9a,0x76,0xb6,0x96,0xf9,0x58,0x8,0xd0,0x3c,0x10,0xb1,0x67,0x62,0xc4,0x9c,0x4b,0x56,0xa6,0x84,0x9e,0x6d,0x5a,0x22,0x54,0xad,0xe5,0x52,0x13,0xca,0x67,0x34,0xd6,0xd6,0xf9,0x51,0x4a,0x61,0xb5,0xb7,0x83,0xbc,0xd8,0xae,0xea,0x4d,0xca,0xda,0xa3,0x76,0xe0,0xe9,0x71,0xfb,0xd5,0x3e,0x5c,0x33,0x43,0xdf,0x2d,0x61,0xad,0x43,0xc,0x1,0xb3,0xf9,0xa2,0x66,0x45,0xc2,0x82,0xed,0xe5,0x11,0x4a,0x19,0xa4,0x44,0xe5,0x21,0x45,0xd9,0x47,0xc5,0x1e,0x13,0x72,0x30,0x67,0xb6,0xc3,0x3,0xda,0xe8,0x6a,0x93,0x1f,0x1f,0x5f,0x57,0xfb,0x65,0xac,0x5b,0x86,0x39,0x61,0x13,0xa2,0xa,0x14,0x8,0x4,0xc7,0x9,0x42,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0x9,0x88,0xe8,0x50,0xb5,0xec,0x74,0xed,0x89,0xc3,0x7f,0x1d,0x9b,0x80,0x27,0x2d,0xc1,0xa,0x54,0x76,0x41,0x84,0xdb,0x48,0x12,0x96,0x9d,0x12,0xf1,0x14,0xd9,0xf6,0x4b,0xe4,0xe0,0x5a,0xa3,0x2a,0xab,0xb8,0xc8,0xde,0x4a,0xf9,0x7f,0x94,0x9,0x47,0x19,0x7e,0xe5,0x1c,0x1,0x54,0x6b,0x6f,0xe6,0x2c,0xb5,0x14,0x23,0xdb,0x37,0x1,0x63,0x1d,0xbd,0x9e,0x9f,0xcb,0x39,0x3,0x89,0x88,0xa3,0x94,0x52,0x2d,0x8a,0x28,0xfb,0x9a,0x92,0x54,0x45,0xa9,0x58,0xa,0x26,0x8a,0x55,0xb5,0x90,0x8a,0x29,0x8f,0xdb,0x43,0x6b,0xb8,0xa6,0x59,0x93,0x81,0x69,0x63,0xd1,0xaf,0xf6,0xb1,0x73,0xe9,0x2,0x16,0xdb,0x27,0xd1,0xad,0xf6,0xd1,0xce,0x16,0x70,0x4d,0x53,0x73,0xf6,0xa,0xe1,0x4,0x0,0xb6,0x69,0x49,0x11,0x18,0x2,0xe6,0x8b,0xed,0x6a,0x7b,0x55,0x4a,0x63,0xbe,0x38,0x51,0xc9,0xba,0x4a,0x9a,0xa6,0x8,0x15,0xc1,0x6d,0xc2,0x86,0xed,0xb4,0x1,0xd6,0x35,0x30,0xce,0xb1,0x4d,0x19,0xd8,0xdf,0xbd,0x8c,0xad,0x13,0xa7,0xa0,0xb5,0xc6,0x6a,0x6f,0x87,0xc9,0xd2,0x25,0x8c,0x9e,0x10,0xb4,0x9c,0x53,0x47,0x39,0x7e,0x16,0xd1,0x18,0x84,0x30,0xf0,0x79,0xd8,0x9a,0xc7,0x97,0x72,0x2,0x32,0x11,0xb6,0x31,0x46,0xb4,0xf3,0x5,0xa9,0x0,0xb5,0xae,0x84,0x22,0xcd,0x6d,0xe4,0xb1,0xad,0xea,0xbc,0xd3,0x78,0xc7,0xe2,0x12,0xa5,0x15,0xda,0xf9,0x1c,0xd6,0x3a,0x4,0x3f,0x60,0xbe,0x75,0xa2,0xda,0xc7,0xa1,0x50,0xc9,0xc0,0x18,0x42,0x25,0x4,0x95,0x36,0x88,0xd1,0xd7,0x76,0xe8,0xd5,0x72,0xf,0xae,0x69,0xb1,0xbf,0x7b,0x19,0x4d,0x3b,0x3,0xa0,0xe0,0xd8,0x7e,0xac,0x4d,0x29,0x41,0xc9,0x94,0x1d,0xa8,0x35,0x62,0xd8,0xe3,0xf1,0x3,0xd6,0x58,0x6e,0x1,0x2e,0x4d,0xc1,0x80,0x72,0xba,0xae,0xf0,0x42,0xee,0x1,0xa5,0xa9,0x5a,0x41,0x73,0xa1,0x47,0x2d,0x3,0xe1,0xff,0xad,0xbd,0x7,0x70,0x4,0xa5,0x57,0xaa,0x81,0x27,0xea,0xc2,0xf1,0x18,0x2,0x81,0x40,0x70,0x3c,0x20,0x16,0x60,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x6a,0xf9,0xc7,0xbf,0x6b,0x70,0xe6,0xda,0x1b,0x30,0xdf,0xda,0x26,0x52,0x3,0x79,0xcd,0xfe,0xb,0xfe,0x79,0xb4,0x3a,0x4e,0xa1,0x2a,0x69,0x48,0x39,0x69,0x54,0x86,0x90,0x53,0x84,0xd2,0x44,0xba,0x55,0x92,0x50,0x4d,0xb2,0xd3,0x74,0x29,0xbb,0x28,0x59,0x6d,0x7e,0x62,0xed,0x2d,0xcd,0xab,0x99,0xce,0x89,0xd5,0x6e,0x45,0xd9,0xa7,0x8d,0xae,0xea,0xbd,0xba,0x2f,0xce,0x68,0x3,0x17,0x55,0x28,0xce,0x1f,0xa4,0x83,0x52,0xb9,0x45,0xca,0x11,0x39,0xc6,0x7a,0x9c,0x98,0x4a,0x56,0x5c,0xa8,0x4a,0x3b,0xe3,0x1c,0x72,0xce,0x58,0x6c,0x9f,0x82,0x36,0x86,0xca,0x4b,0xf8,0x1c,0x4b,0x9e,0x61,0xce,0xa9,0x12,0x4d,0xa,0x8a,0xda,0x8e,0x51,0x22,0xf,0x13,0xac,0x6b,0x26,0xa,0xc8,0xc4,0x4d,0xbd,0x19,0xde,0x13,0x89,0xe5,0xda,0x96,0xc9,0x45,0xb2,0xf9,0x36,0xed,0x9c,0x4a,0x43,0x5c,0x3,0xe4,0xc,0xeb,0x5a,0x58,0xe7,0x46,0x4b,0x35,0x48,0x6d,0x58,0x4a,0x4e,0x4a,0x9b,0x6d,0xf0,0xc3,0x84,0x34,0x24,0x25,0x9c,0xb1,0xe,0xd,0xdb,0x90,0x73,0xca,0x70,0x4d,0xcb,0xaa,0x42,0x22,0x32,0xb5,0x1a,0x1b,0x81,0x4b,0xc6,0x62,0x9a,0xe4,0xe0,0x75,0xfb,0x7b,0xd0,0xc6,0x60,0xbe,0xd8,0xa6,0xec,0x45,0xd7,0x0,0x0,0xac,0x73,0xd5,0x56,0x5c,0x38,0xcf,0xc8,0x63,0x48,0x31,0xc2,0xf,0x1d,0xc0,0x44,0xea,0xd0,0xad,0xd6,0xdb,0x9f,0x53,0x80,0x73,0x2d,0xa9,0x20,0xf9,0xf8,0xc6,0x58,0x18,0xeb,0xea,0x31,0xca,0x5c,0xe7,0x9c,0x60,0xad,0x43,0x66,0xbb,0xb6,0xd2,0xaa,0x16,0xc2,0x94,0x79,0x1e,0xb8,0xb1,0xb8,0x94,0x89,0xd0,0x39,0xd3,0x58,0xfa,0x15,0xa9,0xfd,0x86,0x61,0xc5,0x6d,0xd0,0x54,0x3e,0xd3,0x70,0xde,0x5f,0x51,0x77,0xda,0xa6,0xa9,0xd9,0x84,0xbc,0x7a,0x2b,0xd1,0x9a,0x33,0xea,0xb9,0xa0,0x76,0x7f,0xa8,0xfa,0xda,0x31,0xf9,0x2f,0x6f,0x64,0xfe,0xd4,0xb4,0x30,0x24,0x8f,0xef,0x8d,0xcc,0xca,0x43,0xb1,0x0,0xb,0x4,0x82,0xe3,0x4,0x51,0x0,0xa,0x4,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x57,0xb,0x94,0x82,0xd2,0x96,0xcd,0x89,0x79,0xad,0x8,0xa1,0x16,0x82,0x4c,0xc8,0xbb,0xb1,0x34,0x81,0xa,0x32,0xc6,0xdd,0xa8,0xaa,0x8c,0x52,0x9c,0x61,0x47,0x44,0x50,0x42,0xc6,0x98,0xd,0x18,0x53,0x84,0x1,0x90,0x72,0xae,0xfb,0xb5,0xae,0x5,0x40,0xa,0x3e,0xd7,0xce,0x90,0x12,0x11,0x7d,0xed,0x7c,0xab,0x96,0x4b,0x28,0x6d,0x60,0xac,0x1d,0x15,0x7c,0x8a,0xc8,0x37,0x44,0x22,0x76,0x62,0x8,0x55,0x19,0xe7,0x4c,0x4b,0x99,0x85,0x5c,0x4e,0xa2,0xb4,0x46,0x4e,0x91,0x94,0x85,0xc1,0x3,0x8a,0x49,0x1e,0x64,0x38,0xd7,0x92,0xea,0x2d,0x78,0x68,0x28,0x6c,0x6d,0x9f,0xe2,0xe1,0x8d,0xd6,0x68,0x2a,0xe8,0xa0,0x1c,0xc2,0xcc,0x6a,0x36,0xad,0x2d,0x42,0x18,0xe0,0x5c,0x4b,0xc4,0x5d,0xd3,0x92,0xad,0xd7,0x46,0xb6,0xfd,0xce,0xf8,0x7c,0x3,0x95,0x71,0xb8,0x6,0xaa,0x10,0x50,0xae,0xa9,0xca,0x45,0x22,0xaa,0x2c,0x72,0xca,0x44,0x1e,0xb2,0x62,0xae,0x69,0x5a,0x18,0xeb,0xaa,0xb5,0xb4,0x34,0x10,0xc7,0x98,0x60,0xac,0x83,0xb1,0xd,0x13,0xad,0x9a,0x8b,0x3e,0x22,0xac,0x8d,0x8a,0xcb,0x97,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x75,0x9c,0x1,0x48,0xfb,0x5e,0xee,0xef,0x90,0xa2,0x4e,0x93,0x4d,0xda,0x67,0x22,0x1c,0x1,0x20,0x4,0xca,0xe5,0xf3,0xc3,0x68,0x7b,0x3e,0x7d,0xed,0xd,0xf0,0x7e,0x80,0xf7,0x3,0xa9,0x29,0xf9,0xba,0x6,0x56,0xe5,0x19,0x63,0x1,0x4d,0x24,0x6b,0x3b,0x9b,0x43,0x69,0x5d,0xc9,0x4b,0xa5,0xb8,0x1f,0x3a,0x67,0xb6,0x40,0xb7,0x6c,0x57,0x1e,0xb3,0xb,0x29,0x5f,0x91,0xca,0x4a,0xc8,0x5a,0xec,0xb8,0x5d,0x38,0x71,0xf4,0x5e,0xe6,0x32,0x99,0x58,0x5b,0x89,0xad,0x75,0x88,0x50,0x68,0xda,0x59,0x6d,0x4,0xe,0x93,0x9c,0x43,0xd7,0xb4,0x74,0xed,0x4a,0xd3,0x74,0x4e,0xd8,0x3e,0x79,0xa6,0x16,0x77,0x94,0x35,0x6b,0xac,0xab,0xaf,0xa1,0x3c,0xc8,0x62,0xaf,0xd6,0x4c,0x10,0x73,0xbb,0x74,0xce,0x13,0x45,0x63,0x1c,0xd7,0xfc,0xa4,0x19,0xf8,0xe0,0xfb,0x7,0x3c,0xee,0xa9,0x5a,0xb0,0xbe,0x35,0x26,0xb2,0xda,0x4a,0x4c,0xb,0x4,0x2,0xc1,0x31,0x81,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x82,0x1c,0x13,0x11,0x46,0x79,0x54,0x34,0x29,0x5,0xa4,0x94,0xc7,0xa6,0x5f,0x4c,0x8,0xc1,0x4a,0x78,0x30,0x39,0xc6,0xfb,0xa1,0x86,0x5a,0xc3,0x24,0xe,0x67,0xf1,0xa5,0x34,0xbe,0x5e,0x91,0xda,0x4c,0x2b,0x5d,0xdd,0x91,0xa3,0x8d,0x92,0x32,0xf6,0x66,0x8b,0x6d,0x58,0xef,0xe0,0x5c,0xcb,0x65,0x10,0x1,0xd6,0x3a,0xd8,0x86,0x89,0xb1,0x38,0x16,0x7b,0x14,0x12,0x50,0x71,0x89,0x8,0x29,0xe4,0xc6,0x76,0xe0,0xcc,0xe7,0x34,0x2d,0xd7,0xf0,0x43,0xbf,0xa6,0xd2,0x33,0xda,0x40,0x39,0x8d,0xec,0x7,0x6a,0xda,0x65,0x12,0x27,0xf8,0x81,0xb2,0xe7,0xb4,0xad,0x63,0x2e,0xd,0xb6,0x50,0x8a,0x5a,0x91,0x53,0xa4,0xb1,0xa8,0x51,0x19,0xb8,0x75,0xe2,0x34,0x86,0x6e,0x5,0x6d,0x6c,0x25,0x2b,0xb,0x99,0x14,0x63,0x84,0x66,0x12,0x4d,0x6b,0x3,0x18,0x20,0x46,0x8f,0x18,0x3,0x16,0x5b,0x27,0xe0,0xfd,0x50,0x73,0xf0,0xc8,0x5e,0xac,0xaa,0x42,0xae,0x28,0xf8,0x12,0x5b,0x9b,0x63,0x20,0x35,0x5f,0x21,0xe0,0x62,0x8c,0x70,0xd,0x95,0x6c,0x58,0xeb,0xd0,0xce,0xb7,0x88,0x44,0x6c,0x67,0xd5,0x9a,0xad,0x8d,0xe1,0x9f,0x49,0xaf,0xa8,0x94,0x42,0xf0,0x1e,0xed,0x6c,0x5e,0x8f,0x13,0x7c,0x8f,0xa6,0x21,0x32,0x96,0xc8,0x39,0x20,0x78,0x8f,0x19,0xe7,0xa,0x8e,0x8d,0xcd,0xb6,0x92,0x98,0xc6,0x3a,0x26,0x51,0x29,0x23,0x31,0x3,0x70,0x4c,0x64,0x2a,0xad,0x2a,0x1,0x6b,0xb8,0x39,0xb8,0x9d,0x2f,0x78,0xd1,0xd0,0x7a,0xb2,0x76,0xcc,0x39,0x24,0xa5,0x1c,0x65,0x46,0x6a,0x6d,0x90,0x72,0x26,0x92,0x52,0x71,0xc9,0xb,0x80,0x56,0x1b,0xc,0xdd,0xa,0xde,0xf7,0x30,0xc9,0xf1,0xe3,0x44,0x34,0xb7,0x33,0x26,0x37,0x99,0x94,0x74,0xae,0xa9,0xcd,0xd1,0xc6,0x5a,0x58,0xdb,0x10,0xb1,0x38,0x4a,0xf3,0x26,0xad,0xd7,0xaa,0xaa,0xfe,0x6a,0x5b,0x35,0x9f,0xa3,0x2a,0xed,0xbe,0x65,0xe1,0xf2,0xb6,0x28,0xef,0x80,0x3,0x9d,0x21,0x6b,0xef,0xaf,0xaa,0xb0,0xe4,0x4,0x40,0x21,0x0,0x5,0x2,0xc1,0x31,0x82,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x82,0x91,0x9a,0x98,0x42,0x71,0x5e,0xdc,0xd8,0xe8,0x4b,0x3c,0x58,0x31,0xbb,0x62,0x6c,0x5,0x9e,0xd8,0x85,0xb,0x41,0x55,0x33,0xdd,0x4a,0xae,0x5e,0x4e,0xdc,0x6c,0x9b,0xab,0xb2,0x8e,0x1e,0x67,0x2b,0x6c,0xd6,0x55,0x51,0xa7,0xa3,0x45,0xd3,0xd2,0xdf,0x8b,0xea,0xac,0x28,0xc9,0x62,0xc,0x4c,0xc0,0x30,0x89,0x55,0x48,0x1b,0x3e,0x6,0x9,0x18,0x89,0xfc,0x2b,0xed,0xb9,0x31,0x92,0x2,0x8e,0x32,0x2,0x6d,0x25,0xb1,0xb4,0x36,0x68,0x66,0x73,0x6a,0xe0,0xcd,0x16,0x5a,0x6f,0xd1,0xa8,0x72,0x42,0xbb,0xd8,0xe2,0x52,0x11,0xf,0xc5,0x6a,0xc1,0x62,0x41,0xce,0xac,0x70,0x33,0xd6,0x21,0x44,0xca,0x29,0x74,0xed,0xac,0xda,0x72,0xdb,0xf9,0x56,0x25,0x2c,0xc9,0xaa,0x9c,0x60,0x2d,0x59,0x58,0xb,0x49,0x99,0x39,0x7b,0xcf,0xb8,0x5,0x5b,0x87,0x89,0xe8,0x42,0x4e,0x95,0xfc,0xd4,0x5a,0xd5,0x7d,0x84,0x3c,0xd4,0x79,0x2f,0xcd,0xc4,0xd4,0x92,0x9b,0xd8,0x42,0x9b,0x6a,0x53,0x6f,0xc,0x1e,0xd9,0xb1,0x8d,0x9a,0x8f,0xe9,0x39,0x5b,0x90,0x2c,0xc3,0x6c,0xc3,0xd5,0x44,0xd0,0x6a,0x63,0xc8,0xea,0xab,0x80,0x30,0x50,0x96,0xa0,0xb1,0x8e,0x14,0x72,0xa,0xb0,0x4d,0x83,0xa1,0xef,0x88,0x88,0xb4,0x16,0x7e,0xa0,0x76,0x5d,0xa5,0x35,0xb4,0x52,0x38,0x71,0xf2,0xc,0xff,0x6c,0x28,0xdf,0x8f,0x4b,0x55,0x5c,0x3b,0x5b,0x23,0xc,0x53,0x8c,0xa4,0x3e,0x64,0xb2,0xcc,0xb0,0x3d,0x17,0x20,0x75,0x23,0x38,0x1b,0x51,0x6b,0x53,0xdb,0x98,0xc1,0xd7,0x57,0x1b,0xb,0xa8,0x48,0x5,0x23,0x29,0x61,0xb1,0x7d,0x12,0x19,0x94,0x33,0x18,0x3d,0x8d,0xdb,0xfb,0xfe,0x40,0x6b,0x33,0xad,0x6a,0xd7,0xb4,0x64,0x31,0x56,0x94,0x35,0x68,0x6d,0x53,0xd5,0xa3,0xc5,0x8e,0x9c,0x73,0x22,0xe5,0x6a,0x46,0xb5,0xc0,0x97,0x77,0x87,0x2a,0xed,0xbe,0x63,0x60,0xe5,0xf8,0x2e,0x99,0x2a,0x62,0x4b,0x40,0x60,0x25,0x8,0x69,0x5f,0xaa,0xbc,0x87,0x26,0xdb,0x8,0x4,0x2,0xc1,0x71,0x81,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x2,0xb2,0xe9,0xe6,0x35,0x62,0x83,0xec,0x97,0x44,0xd,0xa6,0x4c,0x44,0x1f,0xf1,0x16,0x79,0x8d,0x2c,0x2c,0x6d,0xc0,0x4a,0x4d,0xb2,0xf0,0x6a,0xa1,0x88,0xe6,0x26,0x54,0x5,0xcd,0x44,0xce,0x94,0xfb,0x28,0x65,0x18,0x45,0x5d,0xa5,0x94,0x26,0x32,0xd0,0xda,0x6a,0xed,0x4,0x14,0x91,0x6b,0x4c,0xbc,0x59,0xe7,0xca,0x49,0xd7,0xf3,0x54,0xda,0x0,0x93,0xc2,0x91,0x42,0xc,0xc6,0x18,0x2a,0x29,0x43,0xad,0xbb,0xa4,0x28,0xd4,0xda,0x20,0xc7,0x50,0xcb,0x44,0x5c,0x33,0xab,0x79,0x71,0xd4,0x98,0x6b,0xab,0x4d,0x77,0x4a,0xd6,0xd4,0xb2,0x11,0x1e,0x7f,0x8c,0x9e,0x89,0xd1,0xc4,0xca,0x44,0xcb,0x39,0x7c,0x96,0x2d,0xc7,0x64,0x51,0x9d,0x6f,0x9d,0xac,0x44,0x5c,0x8c,0x1,0x3a,0x99,0x9a,0x47,0x47,0x4,0x64,0x57,0x49,0x22,0xa5,0x4c,0x55,0xba,0xd5,0x7c,0x43,0x45,0x25,0x1c,0xd6,0x39,0xc4,0xe0,0x11,0x3c,0x1d,0xab,0xcc,0x3d,0x91,0x6c,0xa9,0xe6,0x1,0x42,0x51,0x96,0x61,0xf4,0xbe,0x5e,0x97,0x66,0x36,0x9f,0x34,0xe,0x2b,0x26,0x5d,0x33,0x66,0x8b,0x2d,0x4,0xef,0x6b,0x5e,0x61,0x3b,0x9b,0x43,0xf5,0x74,0x5c,0x6b,0x5d,0x2d,0x57,0x71,0x4d,0x83,0x30,0xc,0xa4,0xe4,0x33,0x16,0x19,0x19,0x26,0x67,0xb6,0x53,0xeb,0xda,0xac,0x6b,0x2c,0x91,0x80,0x75,0xcd,0x18,0x54,0xb2,0x75,0x24,0xe7,0x14,0xb4,0x56,0x63,0x21,0x7,0xdb,0xc6,0xeb,0x5a,0xac,0x59,0x8b,0xc5,0x8a,0xab,0x6b,0xb,0x75,0x3b,0x9b,0x23,0x86,0xc8,0x59,0x84,0x19,0xce,0x35,0x74,0x3c,0xb6,0x77,0x2b,0x5e,0x1b,0x7a,0x62,0x17,0x37,0xd6,0x1,0x20,0xb,0x30,0x65,0x4c,0xa2,0xae,0xd9,0x62,0xff,0xad,0x24,0xf7,0xf8,0x6,0x18,0x17,0xaa,0x6,0xad,0xaf,0x49,0xa5,0x6f,0xae,0xc4,0x60,0x22,0x2b,0x7c,0xce,0xf5,0xb1,0x2a,0x2e,0x1c,0x19,0xc3,0x4a,0x46,0xa,0x4,0x2,0xc1,0x71,0x83,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0xc1,0x55,0x82,0x14,0x3d,0x46,0xba,0x62,0xa2,0x66,0x62,0xae,0xab,0x56,0x1e,0xb0,0x1d,0x38,0x17,0x32,0x84,0x45,0x82,0x4a,0x69,0x26,0xff,0x54,0x2d,0x1,0x29,0x96,0xde,0xa9,0x42,0xaf,0xec,0x23,0xa5,0xc0,0xb9,0x70,0xd4,0x32,0x9b,0x31,0x66,0xb5,0x21,0x51,0xab,0xab,0xf2,0x8a,0x1f,0xd3,0xd5,0x46,0x5c,0x72,0xea,0xa,0x2a,0x59,0xc4,0xd6,0x62,0xc3,0xed,0xb2,0x85,0xd8,0x51,0x50,0x50,0x46,0xd7,0x1c,0x3f,0xa5,0x15,0x54,0x36,0xb5,0x11,0x18,0x2a,0xd7,0xa6,0xdd,0x92,0xdd,0xa6,0xb5,0x26,0xe2,0xca,0xd2,0x71,0xb5,0xb5,0x95,0x44,0x33,0xb5,0x8d,0x77,0x2c,0x78,0x20,0xe2,0x8c,0xe7,0x91,0x49,0x28,0x0,0x50,0x31,0xc0,0x73,0x4e,0x5e,0xb1,0xee,0x16,0x62,0xb,0x3a,0x43,0x29,0xc7,0x4a,0x42,0x5f,0x8b,0x46,0xc,0x13,0x64,0x39,0x67,0xb8,0xa6,0x41,0xc,0x91,0xdb,0x94,0xc9,0x12,0x1b,0x82,0x67,0xdb,0x2f,0x59,0xb2,0x8d,0x35,0x6c,0x75,0xce,0x9c,0x2d,0x18,0x6a,0xab,0x6f,0xce,0x19,0xba,0xa1,0xeb,0x92,0x39,0xbf,0xaf,0x94,0x58,0x94,0xb2,0x91,0x72,0xee,0x94,0x3b,0x98,0x90,0x12,0x28,0x9f,0xd1,0xb9,0x6a,0x81,0xcd,0x19,0x30,0x2d,0x93,0x8d,0x9a,0x4a,0x39,0xca,0x9a,0x88,0x9c,0xcf,0x47,0x6a,0x4b,0xca,0x47,0xc,0x43,0xf,0x6d,0x1d,0x72,0xf0,0x68,0x66,0x33,0xc4,0x18,0xa9,0x61,0x19,0xa8,0x96,0x64,0x6a,0x5c,0xa6,0x8c,0x48,0x18,0x53,0x9f,0x2b,0x24,0xe6,0x48,0xbe,0xa9,0x9a,0xd3,0xa7,0xb5,0x82,0x72,0x34,0x86,0x6c,0x32,0x94,0xb2,0xb5,0xad,0xb8,0x90,0xc3,0x99,0x33,0x25,0x63,0x8,0x93,0xc2,0x18,0xcb,0xa4,0x28,0x67,0x10,0x5a,0x4b,0x24,0x9d,0x42,0x25,0x15,0xb,0x49,0x5d,0x55,0x7e,0xa,0x35,0xb3,0x92,0x14,0xa5,0xf4,0xde,0xd0,0xd5,0x2,0xf,0xa8,0xac,0xea,0x3b,0x46,0x4d,0xc8,0xbf,0x4a,0x2,0x4e,0x30,0x8e,0x6,0xbc,0xbf,0x24,0x1f,0x3a,0x2,0x81,0xe0,0xd8,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x2a,0x41,0xb5,0x38,0xf2,0x4f,0xf4,0x87,0x2,0x52,0xf9,0x79,0x7c,0x2e,0xa7,0x3c,0x51,0xc5,0x29,0x6e,0x79,0x8d,0x55,0xf9,0x57,0x50,0xf2,0xfb,0xca,0x63,0x44,0xd6,0x4d,0xd4,0x82,0x55,0xf5,0x95,0xeb,0xeb,0x33,0x50,0x4b,0x3b,0x8c,0xa5,0x52,0x8c,0x42,0x8,0x95,0xed,0xe9,0xe7,0x72,0xc,0xfa,0x39,0xf8,0xc0,0xc4,0x8f,0xaf,0x2a,0xc0,0x42,0x3a,0x4e,0x95,0x7e,0xb5,0xcd,0x18,0x8a,0x1f,0x53,0xf5,0x78,0xda,0x58,0xe4,0x89,0x5a,0x4c,0x41,0x41,0x5b,0x5b,0xb,0x39,0xb4,0x31,0x5c,0x34,0x41,0xdb,0x11,0xf9,0x47,0x44,0x62,0x66,0x95,0x5a,0x21,0x47,0x29,0xb,0x51,0x73,0x93,0xaf,0xae,0x8d,0xb7,0x45,0xa9,0x57,0xda,0x83,0x33,0x93,0x96,0x4a,0xeb,0x31,0xd3,0x10,0xa,0x4a,0x65,0x4,0xef,0xe9,0x8c,0x13,0xa0,0x95,0x46,0x4c,0x91,0x5a,0x75,0x15,0x65,0xe6,0x65,0x90,0x2a,0xb0,0xa8,0x37,0xb5,0x5,0x1f,0x4b,0x97,0x3a,0x62,0xa4,0x94,0x60,0x95,0xa9,0x45,0x2c,0x80,0xaa,0x2a,0xc1,0xc,0x22,0x2f,0x8b,0xf2,0x30,0x45,0x52,0x6f,0x96,0xdc,0x46,0x6d,0xc,0x60,0x28,0xb7,0x30,0xc5,0x0,0x14,0x95,0x66,0x66,0x22,0x36,0x4d,0xc8,0xba,0xcc,0x2a,0x51,0xad,0x61,0x9b,0x16,0x39,0x25,0xcc,0x17,0x6d,0x25,0x2c,0x2d,0xab,0xf4,0xa8,0xc0,0x24,0xf2,0x7c,0x58,0x9e,0xbb,0x54,0x1b,0xa2,0x53,0x1a,0x8b,0x36,0x8a,0x82,0x32,0x67,0x54,0x2,0xb8,0x28,0x45,0xb5,0x36,0x48,0xbc,0x4e,0x8b,0x2d,0x5c,0x17,0xb2,0x38,0x27,0xe8,0xc6,0x30,0xb9,0x99,0x2b,0xd9,0x47,0x73,0x64,0xea,0x5a,0x1f,0xd7,0x81,0x82,0x82,0x26,0xd2,0x5a,0xa1,0x6e,0x87,0x89,0xd,0x58,0xd7,0x9c,0x4a,0x5e,0xc7,0x98,0x10,0xc0,0x4c,0xa,0x72,0x57,0xf6,0x48,0x9c,0x4f,0x31,0xc6,0xd,0xf2,0x7e,0xe5,0x33,0x47,0x20,0x10,0x1c,0x1f,0x8,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x25,0x50,0xc6,0x31,0xf9,0x94,0xc7,0xff,0xf2,0x41,0xfb,0x62,0xaa,0x44,0x1c,0x6d,0xc4,0xb9,0x66,0x69,0x7c,0xcd,0x48,0x34,0xa1,0x36,0xad,0x2,0x23,0x79,0x47,0x9b,0xe9,0x5a,0xca,0xc0,0xae,0x4b,0x14,0x4b,0x68,0x25,0x5c,0x38,0x17,0x4e,0xdb,0xf1,0xb1,0xda,0xc6,0x9a,0xa,0x39,0x43,0xa7,0x41,0x8a,0x40,0xd6,0x5d,0x29,0xc5,0xd6,0xd8,0xa9,0xa5,0x54,0x57,0x35,0xd7,0x1a,0xc1,0xa4,0x14,0x72,0x4c,0xd5,0xb2,0x5b,0x32,0xfd,0x4a,0x91,0x49,0x46,0x46,0x2e,0xc4,0x60,0x3e,0x6c,0x79,0x26,0xc6,0x8a,0x5e,0x53,0xda,0x81,0x51,0x89,0x2a,0xf0,0x38,0x4c,0x25,0x9f,0x8a,0x2,0x2f,0x86,0x92,0xf1,0x47,0x84,0x5c,0x8c,0x1e,0x46,0x69,0xca,0xa5,0x9b,0xcc,0xe3,0x78,0x1c,0x5d,0xe7,0x24,0xf1,0xd8,0x23,0x8f,0xb9,0x10,0x99,0x4a,0x81,0x9,0x43,0x9e,0x83,0xa2,0xc8,0x9c,0xd8,0xa1,0x95,0x36,0xdc,0x5f,0xa1,0x26,0xd7,0x2a,0x42,0xb1,0x2d,0xb9,0x5e,0xcf,0xa2,0xb4,0xe4,0xe2,0x12,0x12,0xe8,0x95,0xcc,0x46,0xd4,0x79,0xcd,0x99,0xc6,0x4e,0x4a,0x3b,0x6a,0x1f,0x2e,0xd7,0xd8,0x70,0x91,0x89,0xb5,0xd,0x34,0x13,0x6a,0x85,0xc,0x2e,0xc7,0x4f,0x6c,0xd9,0xa6,0x52,0x8c,0x58,0xf7,0x59,0x9,0xe2,0x10,0x78,0xd,0xb1,0x85,0xbc,0x10,0x82,0x45,0x11,0x5a,0xd6,0xae,0x52,0xb5,0x8c,0xa4,0x58,0xa8,0xc1,0x63,0xd3,0x53,0x5b,0xb1,0xc9,0xd5,0x9a,0x3e,0x5a,0xd2,0x59,0xc3,0x97,0x47,0x12,0x1a,0x48,0xeb,0xc4,0x61,0xce,0x44,0x1e,0x56,0x95,0xeb,0x7a,0xcf,0x47,0x59,0x1b,0x63,0xfc,0x9f,0xaa,0x44,0x60,0xfd,0x7b,0x3d,0x59,0x8c,0xef,0xd,0x81,0x40,0x20,0x38,0x26,0x90,0x4f,0x24,0x81,0x40,0x20,0x10,0x8,0x4,0x2,0x81,0xe0,0x2a,0x41,0xa,0x7d,0xb5,0x3f,0xe6,0x89,0xe5,0x71,0x14,0x3,0xea,0x89,0xb2,0xe,0xb5,0x98,0xa2,0xd8,0x5a,0x95,0xd2,0x4c,0x50,0xa5,0xb5,0xe7,0x31,0x31,0x15,0xe7,0x49,0x2e,0xda,0x7a,0xfb,0x2f,0x9f,0x43,0x4a,0x6b,0xaa,0xac,0x52,0x56,0x51,0x4e,0x82,0xa,0x2c,0x6c,0x25,0x8b,0x4a,0x1e,0x61,0xb1,0xcf,0x2a,0xa0,0xaa,0xef,0x14,0x13,0x46,0xd5,0xca,0x9,0x52,0xb8,0xd5,0xd7,0xb2,0x2,0xae,0xe6,0x8,0xb2,0x62,0xf,0x7c,0x6e,0x65,0x22,0xe8,0xbc,0x13,0x59,0x6e,0x99,0x18,0x2b,0x24,0x19,0xb5,0xfb,0x72,0x39,0x5,0xca,0x0,0x55,0xcd,0x4,0x2c,0xea,0xc4,0xd2,0x5a,0x5c,0x14,0x83,0xda,0x10,0xb9,0x46,0x96,0x5a,0xcd,0xb6,0x5c,0xde,0x86,0xcf,0x69,0x24,0x48,0x89,0xc8,0x4a,0x29,0xae,0x15,0x53,0x64,0x26,0x38,0x4b,0x9b,0x6d,0x8,0xbe,0xda,0x5f,0xd5,0x84,0x48,0x2d,0xb9,0x7e,0x4a,0x13,0x29,0x66,0xd8,0x6e,0xab,0xb5,0x61,0x95,0x9f,0xad,0x8a,0xc6,0x32,0xf7,0xa5,0x58,0xa4,0x6c,0x5b,0xd4,0x70,0x0,0xe5,0xa,0x16,0x2b,0x72,0x99,0xe3,0x92,0x9,0x58,0x1b,0x82,0x53,0xaa,0xe5,0x2f,0x44,0x56,0x86,0x35,0xf2,0xaf,0x96,0x87,0x70,0xc3,0x6f,0x51,0xfb,0xa9,0x9a,0xe9,0x88,0x3a,0x37,0x0,0xaa,0x85,0x77,0x54,0x5,0xc6,0x7a,0xcd,0x6a,0x46,0x22,0xa8,0xa8,0x44,0x4d,0xdb,0x79,0x79,0xd,0x15,0x12,0xf,0x50,0x95,0x74,0xa4,0x97,0xe4,0x8d,0x44,0xdc,0xc1,0x86,0xde,0xa2,0x18,0x2c,0x16,0xf7,0xf2,0xf4,0x9a,0xc8,0x6f,0x22,0x9e,0x9d,0x12,0x7e,0x63,0x71,0xc8,0x68,0xab,0xa7,0xc7,0xc4,0x2,0x2c,0x10,0x8,0x8e,0xf,0x44,0x1,0x28,0x10,0x8,0x4,0x2,0x81,0x40,0x20,0x10,0x5c,0x25,0x98,0xaa,0xba,0xa,0x59,0xc1,0x2e,0xd2,0xaa,0xca,0x2a,0xe4,0x16,0x94,0x82,0x56,0xa6,0x2a,0xf2,0x68,0x3b,0x52,0xbe,0xa1,0x10,0x71,0xcc,0x1e,0x56,0x25,0x1b,0xc0,0xd9,0x71,0x13,0xe5,0x57,0x9e,0x66,0xf9,0x8d,0xf6,0x61,0x6a,0x16,0x56,0x13,0x95,0xd7,0xa8,0xa,0x24,0xb5,0x9f,0x9a,0x9c,0xab,0x1a,0x6d,0xc6,0x4a,0x55,0xb2,0x25,0x67,0xca,0x4,0x2c,0x44,0x19,0x95,0x4d,0xb0,0xe2,0x8d,0xb3,0xf2,0x2a,0x85,0xc3,0x44,0x5f,0x1d,0xa3,0x5a,0x2f,0x36,0x1,0x50,0x1b,0x88,0x2b,0x21,0xc6,0xa4,0x27,0xd9,0x56,0x47,0xf5,0xda,0xd8,0x3a,0x4c,0xe7,0x1c,0xfc,0x40,0xa4,0x24,0xef,0x3f,0xc5,0x54,0xed,0xa2,0xc6,0x3a,0x52,0xa9,0x19,0x83,0x14,0x99,0x2c,0x9d,0xa8,0x13,0x8b,0xa,0xaf,0x20,0x33,0x41,0xaa,0xd6,0x8a,0x33,0xd4,0x58,0x60,0xc1,0xa0,0x92,0x8b,0xc,0xad,0x49,0xd5,0x58,0x9,0xc6,0x94,0xf9,0x3a,0xd3,0xb1,0x8a,0x42,0xd3,0xf7,0x7d,0x25,0xf3,0x72,0x26,0x7b,0x31,0x5d,0xb3,0xf1,0xda,0xe6,0x44,0x44,0x5c,0x29,0x41,0xb1,0x76,0x6c,0x43,0xe,0x7e,0x80,0x2,0x6a,0x3,0xb3,0x71,0xe,0x39,0x46,0x80,0xf3,0xf7,0x2,0xdb,0xb2,0x33,0xb0,0xd6,0xa4,0x9b,0x52,0x1c,0x73,0x8,0x63,0xac,0x96,0x5f,0x68,0x26,0xeb,0xf8,0x58,0x69,0xa2,0xf6,0x23,0x95,0x28,0xaf,0x97,0x42,0x38,0xa7,0x8,0x28,0xcd,0x63,0xe5,0x42,0xf,0x5e,0xd3,0x69,0x4d,0x29,0x8,0x0,0xba,0x96,0x84,0x28,0xad,0xd7,0x2c,0xea,0x28,0xca,0xc9,0x18,0x27,0xa1,0x97,0xa8,0x6b,0x6f,0xbd,0x19,0x18,0xe3,0xfb,0x1,0xeb,0xaf,0xad,0xaa,0xd6,0x3,0xfb,0x40,0x2e,0xb9,0x98,0xea,0x10,0xc9,0x28,0x10,0x8,0x4,0x7f,0x97,0x10,0x5,0xa0,0x40,0x20,0x10,0x8,0x8e,0xf7,0xcd,0xaa,0x36,0xa4,0x68,0x98,0xfe,0xf2,0xd2,0x76,0xe3,0xeb,0xbe,0xd5,0xed,0xa7,0x8f,0x6d,0x7a,0xbe,0x3c,0x5e,0x8e,0x73,0xd4,0xbe,0xf,0x87,0xff,0xe0,0x65,0x8f,0xf5,0x72,0x63,0x5c,0xdb,0xb6,0xe4,0x68,0xbd,0xcc,0x98,0xe,0xbe,0xfe,0xd0,0x63,0x50,0xdf,0xf2,0x71,0x8f,0xda,0xef,0x37,0xdb,0x7e,0xd3,0x7e,0xe,0xef,0x53,0x6f,0x78,0xbd,0x5e,0xfb,0xfb,0x51,0xdb,0xd3,0xdc,0xe9,0xef,0xf8,0x78,0x2f,0x77,0xfe,0xe5,0x75,0x9b,0xc6,0x5a,0xae,0x59,0x39,0xb7,0xf5,0xbf,0xeb,0x23,0x8f,0xb3,0xf6,0xbc,0xd2,0xdf,0x7c,0xae,0xe,0xbc,0x66,0xba,0xef,0xa3,0xc6,0xfe,0xed,0xbc,0x5f,0x94,0x36,0xd0,0xc6,0xd5,0xb5,0x5c,0x6d,0x92,0x7,0xf6,0xab,0x8d,0x3b,0x74,0x1e,0x2f,0x37,0x8f,0x9b,0xc7,0xae,0xbf,0xa5,0x6b,0x7f,0xd4,0x79,0xa,0xfe,0xf6,0x10,0xe3,0xc0,0x39,0x6b,0x7,0x89,0x41,0xd4,0x56,0x59,0x35,0x36,0x81,0x30,0x31,0x35,0x5a,0x28,0xb,0x29,0x86,0x9c,0x27,0x59,0x69,0x13,0x7b,0x64,0x55,0x4,0xa2,0xda,0x88,0x49,0x35,0x68,0xc6,0x26,0xd6,0x69,0xde,0x5a,0xd9,0x66,0x93,0xf5,0x16,0x98,0x28,0xdc,0xd4,0xd8,0x16,0xcb,0xb6,0xd8,0xa9,0x72,0xae,0x16,0x38,0xe4,0x54,0x8f,0x1f,0xb9,0x24,0xa4,0xa8,0xee,0x4a,0xe6,0x5b,0x7d,0x5d,0x8c,0x95,0xc,0x2c,0xa5,0x19,0xc5,0x1a,0x3c,0xcd,0x81,0x2b,0x6a,0xb6,0xf2,0xba,0xa2,0xc8,0x2b,0xc4,0x5c,0x29,0xb5,0x28,0x65,0x13,0x79,0x4a,0xb0,0x2a,0xc5,0x24,0x64,0x51,0xb2,0x1d,0xbe,0x26,0xe5,0xf9,0xfa,0x79,0x3e,0x69,0x1f,0x2e,0x84,0x64,0xcd,0xb9,0x9b,0x64,0xf,0x16,0x72,0xb2,0x14,0x87,0xd4,0xb1,0x2b,0x22,0x4b,0x8b,0x52,0x6f,0x3c,0x3f,0x35,0xc9,0x4c,0x4c,0x6c,0x2f,0x2e,0x65,0x2d,0x89,0x95,0x97,0x86,0xb7,0x25,0xc2,0xad,0xcc,0x77,0x21,0x77,0x49,0x5d,0x68,0xeb,0x6f,0xc0,0xf2,0x3e,0xf,0x61,0xa8,0x6a,0xce,0x72,0x6d,0xa,0xc1,0x9a,0x6b,0x63,0x33,0xa0,0xb9,0x91,0xb8,0x2a,0x25,0xf9,0x98,0x65,0xcc,0x45,0x9d,0x39,0x66,0x1e,0xa6,0x9,0xa9,0x36,0x32,0x6d,0xb1,0xcc,0x29,0x32,0x13,0xa6,0x25,0xf7,0x50,0xd7,0xf2,0x8d,0xf2,0x5c,0xc,0x61,0xcc,0x3,0xc4,0xa8,0xda,0x24,0x35,0xe9,0x7a,0xdb,0x6f,0xda,0xa0,0xd8,0x2b,0x65,0x20,0x87,0x1f,0x3f,0xf8,0xc3,0x44,0x5,0xb,0x54,0xc5,0xac,0x40,0x20,0x10,0x1c,0x17,0x88,0x2,0x50,0x20,0x10,0x8,0x4,0xc7,0x6,0xd7,0xbe,0xe2,0x2e,0x5c,0x7f,0xf3,0x1d,0x38,0x79,0xf6,0x5a,0x6e,0x75,0x9c,0x96,0x53,0xe6,0x49,0x43,0x24,0xdd,0x20,0xe4,0x92,0xdf,0x94,0xd3,0x7a,0x6e,0x50,0xb9,0xf1,0x64,0x15,0x89,0xd2,0xa,0xa3,0xb5,0x6c,0xc,0x8c,0x2f,0xb9,0x47,0xe5,0x6,0xa3,0xdc,0x98,0x64,0x56,0x37,0x14,0x9b,0x5b,0xb9,0xc1,0xa9,0x37,0xcd,0xb9,0x4,0xaa,0x8f,0x6d,0x86,0x4a,0x9b,0x51,0xe1,0xc0,0x76,0xb8,0xa2,0x4a,0x28,0x8f,0x15,0xe5,0x4a,0xb1,0x35,0x95,0xe7,0xb5,0xa1,0x50,0xf2,0xcc,0x16,0xb7,0x9c,0x8a,0x42,0x62,0xcc,0xe5,0x2,0xdf,0xa8,0x24,0x56,0x91,0xe4,0x94,0xeb,0xd,0xcc,0x54,0xb5,0x53,0x1a,0x2c,0x8b,0x32,0x47,0x6b,0xca,0xc2,0x9a,0x2a,0x5c,0xca,0xf8,0xc7,0xec,0x29,0xd4,0xc6,0xca,0xaa,0x7a,0x61,0x69,0x43,0x99,0x83,0x29,0xa9,0x33,0xde,0x90,0xaa,0xb5,0x96,0xce,0xa9,0x62,0x65,0x9a,0xdb,0x34,0xce,0x7b,0x3e,0x90,0x49,0x35,0xde,0x90,0x17,0x85,0x4a,0xd,0xcd,0xe7,0xf9,0x9d,0x6,0xc4,0x8f,0xf3,0x97,0x6a,0x83,0x67,0xc9,0xff,0x52,0x13,0xf5,0xc8,0x34,0x3f,0xab,0x28,0x6b,0x4a,0x63,0xe9,0xda,0xd,0x5d,0xb9,0xd9,0xe6,0x9b,0x6c,0x54,0x22,0x60,0x5c,0x5f,0xe5,0x26,0x4e,0x97,0x20,0x7d,0x4c,0x1c,0x60,0x13,0xc5,0x50,0x9,0xd8,0xcf,0x18,0x6f,0x2,0x4b,0x78,0x7e,0x55,0x1d,0x61,0x54,0xb2,0x68,0xa5,0x28,0x48,0x5f,0xe9,0x7a,0x93,0x8c,0xd2,0x38,0x59,0xad,0x90,0x79,0x6d,0x5e,0xb,0xa1,0xa0,0x6b,0x3b,0xe9,0xb8,0x7e,0xf,0xce,0x7d,0x39,0x4e,0x25,0x3f,0x26,0x6b,0x20,0x4d,0xae,0xff,0xda,0x5c,0x14,0x42,0x50,0x8f,0xca,0x98,0x92,0x8f,0x45,0xb6,0x48,0x5d,0xc7,0xba,0xae,0x14,0x9b,0xb4,0xc5,0x1e,0xb0,0x91,0x2a,0x6d,0xa8,0xf9,0x94,0xed,0x88,0x79,0xfa,0x7e,0xe0,0xf7,0x55,0x21,0x1a,0x5e,0x3a,0xf7,0xc,0xce,0x3f,0xf3,0x18,0xfa,0xfd,0x2b,0xf2,0x61,0xf8,0x5d,0x44,0xa,0x1e,0x5d,0xb7,0xa4,0xcf,0x17,0x33,0x12,0x1f,0xb5,0x59,0x75,0xc3,0x9a,0x58,0x53,0xa,0x16,0xb,0xe9,0x44,0x85,0xb7,0x46,0xd4,0x29,0xb5,0x46,0xe8,0x95,0x75,0x9b,0x52,0xae,0xea,0xaa,0x91,0xe8,0x3b,0xfc,0xf9,0xb1,0xf6,0x79,0x51,0x3f,0x6f,0x26,0x9f,0xed,0x93,0xf7,0xde,0x5a,0x99,0x89,0x9a,0x34,0x5,0x73,0xe3,0xed,0x58,0xf2,0xb0,0x6e,0x43,0x9e,0xbe,0xff,0x8b,0x9d,0xb6,0x10,0x9c,0x31,0xf8,0xf5,0xf7,0x1d,0xd8,0x86,0xcb,0xd9,0x78,0x39,0x17,0x42,0x11,0x55,0x71,0x47,0xeb,0x3d,0x1d,0x52,0xb1,0xa9,0x49,0x2e,0x5d,0x2c,0xe3,0x98,0xcc,0x6d,0x39,0x5f,0x63,0x4c,0x25,0xca,0x14,0xcf,0x9d,0xe1,0xac,0xc6,0xc4,0x24,0x6c,0xd9,0x57,0xb5,0xc,0x3,0xc8,0x6a,0x32,0x6f,0x53,0x5,0xe7,0x64,0x5e,0x4a,0x8b,0x70,0xc,0x93,0xec,0xbf,0x5c,0x58,0xdb,0x34,0x66,0xd8,0x69,0xfe,0x6c,0x55,0x63,0x2e,0x63,0x79,0x7f,0x42,0x81,0x33,0xf6,0x14,0x28,0x37,0xf,0x35,0x67,0x71,0x4a,0xa4,0x95,0x6b,0x34,0xfe,0xe,0x50,0x7,0xd4,0x95,0x1,0x40,0x29,0x5b,0x19,0x95,0x96,0x23,0x39,0xaa,0xc6,0xe2,0x8f,0x42,0xce,0xf2,0xe7,0xbc,0xb5,0x8e,0x8,0xcb,0x49,0x76,0xe4,0xb4,0xc9,0xb7,0xac,0xc5,0x18,0x46,0x1b,0x77,0x59,0xcf,0xe3,0xe7,0x92,0x9a,0x90,0x72,0x79,0xad,0xc8,0x43,0x4d,0x88,0xbc,0x7c,0x20,0xdf,0xf,0xf5,0x4f,0x85,0xc9,0x1b,0x61,0xfc,0x6d,0x90,0x55,0xfd,0x9d,0x99,0x71,0xb0,0x20,0x47,0x3e,0x73,0x4,0x2,0x81,0x10,0x80,0x2,0x81,0x40,0x20,0x10,0x54,0xb8,0xd9,0x36,0x5e,0xff,0xfd,0xef,0xc4,0xd9,0x6b,0x6f,0xe4,0xdc,0x21,0xac,0x27,0x6f,0xaf,0xdd,0x86,0xe6,0x89,0x5d,0x29,0x4f,0x94,0x12,0x93,0x7f,0xac,0x57,0x6b,0x1a,0x11,0x73,0x85,0xd0,0x1b,0x83,0xd4,0xbf,0x15,0x5b,0x4e,0x3e,0xe0,0xef,0x99,0x34,0x63,0x1e,0xb8,0xd1,0xfd,0xa6,0xfb,0x81,0x5a,0x53,0xc8,0xd4,0x3b,0x88,0xa9,0xaa,0x60,0x7a,0x18,0x75,0xe0,0x86,0x38,0xe7,0xb5,0x1b,0xdf,0x9c,0xd7,0xe8,0xa1,0x9,0xf1,0xf4,0x5d,0x42,0x3e,0xf4,0x97,0xf1,0x8e,0x69,0xad,0x4d,0x34,0x4f,0x6e,0xa8,0x8f,0xf2,0x46,0xd5,0x81,0x8c,0xf9,0x4c,0xd8,0x3c,0xd,0x9b,0x70,0xe8,0xb9,0x89,0xb2,0xe4,0xd0,0x9e,0xca,0x4d,0xee,0xa6,0x1,0x6d,0x7c,0x2e,0x63,0x6a,0x7d,0x3c,0xf4,0xf3,0xf4,0xfa,0x1d,0xfc,0xf9,0x88,0x93,0xad,0x1,0xf3,0x7,0xd7,0x6f,0x69,0x49,0x85,0x1a,0x35,0x23,0x79,0xb2,0x5f,0xa5,0x36,0x5c,0xdb,0x3,0xe7,0x34,0x9d,0x94,0xa3,0x9e,0xfb,0x56,0xa1,0xbe,0xbd,0xed,0xc6,0xf7,0x61,0x79,0xef,0x4d,0x88,0xfa,0x4a,0x10,0xa1,0x9e,0xbf,0x1a,0x4f,0xf4,0xc0,0xb6,0xac,0x94,0x49,0x19,0xdb,0xa7,0xce,0xe2,0xcc,0x75,0x37,0xe1,0xb1,0xaf,0x7c,0x1,0xbb,0x17,0x9e,0x93,0xf,0xc6,0xef,0x22,0x9e,0x7e,0xe4,0x8b,0x58,0x6c,0x9d,0xc4,0x99,0xeb,0x6e,0x5c,0x63,0x29,0xf2,0x9a,0xaa,0x4f,0x1d,0x20,0x9f,0x27,0x9f,0x61,0x85,0x98,0x2f,0x4a,0xc0,0x49,0xe1,0x3,0x91,0xbb,0xd3,0x2f,0x32,0xc6,0xa2,0x90,0xfa,0xbc,0x52,0x13,0xd2,0x7d,0xf2,0xd9,0x96,0xd6,0xc9,0xe4,0x1c,0x73,0x25,0xa1,0xa6,0x65,0x19,0xd3,0xd7,0x1e,0xfe,0x1c,0x60,0x92,0xec,0x0,0xd9,0x46,0x44,0x9d,0x41,0xce,0xb1,0xbe,0x27,0x53,0x21,0x3c,0x27,0x5f,0xec,0x94,0x2f,0x21,0xe,0x5a,0x44,0xe9,0x4b,0x9e,0x54,0x1b,0x7c,0xa7,0xd6,0x5c,0x94,0x4c,0xbf,0xc9,0x97,0x1a,0xd5,0x2,0x5d,0xe7,0x66,0x24,0xce,0x46,0x2,0x8d,0x88,0xff,0x90,0xd2,0xf8,0xde,0x51,0xe3,0x97,0x33,0x65,0xe,0xcb,0xef,0x33,0x6a,0xc0,0x35,0x35,0xa7,0x6e,0x6a,0xf9,0x9d,0x7e,0x76,0x4e,0x89,0xd5,0xa2,0xb2,0xac,0x4,0xe9,0x84,0xa0,0x4c,0xdc,0xf4,0x4b,0x3f,0x8c,0xd7,0x9f,0xbe,0x33,0x1b,0x33,0x13,0xe9,0xf3,0x2a,0x8e,0xbf,0x3,0x53,0xac,0x36,0xeb,0xe9,0x17,0x56,0x8a,0x3f,0x8b,0xf2,0xe4,0x8b,0xa1,0x92,0xa7,0x47,0x99,0x79,0x85,0x20,0xcd,0x6b,0xeb,0xa5,0xe4,0xf7,0xa5,0xfa,0xbb,0x9a,0x15,0x9c,0x85,0xb4,0x64,0xfb,0x77,0x21,0x15,0x81,0xc,0x24,0x5d,0xc9,0xc3,0xfa,0x7b,0xb9,0xe6,0x26,0xae,0x2b,0xf1,0xc6,0x8f,0xc6,0xb1,0x10,0x5,0xd3,0xcf,0xd6,0x94,0x6b,0xf3,0x71,0x25,0x39,0x27,0x9f,0xdc,0x7,0xd7,0x11,0xf2,0x21,0xcf,0xef,0xda,0x2f,0xa6,0xa2,0xc4,0x4c,0x29,0xc2,0xf,0x9d,0x7c,0xe0,0x8,0x4,0x82,0x63,0x83,0x97,0xfb,0x37,0xb6,0x40,0x20,0x10,0x8,0x4,0xdf,0x55,0x18,0xdb,0xe0,0xbe,0xd7,0xbf,0x15,0xb7,0xdd,0xf3,0x6a,0xb8,0xa6,0x99,0x7c,0xc3,0x3e,0x65,0xb8,0xbe,0x2d,0x3a,0x68,0x3,0x89,0x94,0x2b,0xc9,0x72,0x50,0x51,0xb8,0xc6,0xab,0x6c,0x22,0x4e,0x36,0xed,0xfe,0x5b,0xfa,0xcd,0x39,0x12,0x92,0x85,0xc,0xa9,0x4a,0x2c,0xa2,0x3,0x27,0x37,0xa,0x1b,0x48,0x40,0xbc,0xc,0x1b,0x76,0x98,0x1,0x3b,0x44,0x50,0x7e,0xb,0x4c,0xde,0x77,0xfd,0x9f,0x6,0x79,0x42,0xfe,0x4d,0xef,0xd1,0xf,0x72,0x87,0x6a,0x8d,0x5f,0x9b,0xa8,0x56,0xd6,0xb6,0xd9,0x44,0x11,0xbe,0xdc,0x4,0xbd,0x1c,0x95,0xf8,0xcd,0x1e,0xfb,0x2e,0xff,0xd3,0xe8,0xe5,0xae,0xa5,0x2,0x36,0x2c,0xd4,0xf5,0x51,0xab,0x72,0xaf,0xb9,0xde,0x5c,0x59,0xb5,0x59,0xa5,0xc0,0x1,0x53,0x3e,0x71,0xa2,0x10,0xaa,0x4a,0x2e,0xb5,0xf6,0xfe,0xc0,0x46,0xa,0xf9,0xf0,0x89,0xa8,0xe9,0xba,0xfe,0x1b,0xcd,0x93,0xe2,0x9b,0x7c,0x8d,0xa9,0xd5,0x71,0xe8,0x57,0xb8,0xf8,0xe2,0x39,0x7c,0xed,0xb,0x1f,0x17,0x25,0xe0,0x77,0x19,0xcd,0xfc,0x4,0x6e,0xbf,0xef,0x21,0x6c,0x9f,0x3a,0x5b,0xe7,0x7f,0xad,0xd1,0x74,0x8d,0xf8,0x9e,0x2a,0xfe,0x30,0xfe,0x7c,0xf8,0x5b,0xb,0x26,0xcb,0xd4,0xa8,0x0,0xd3,0xaa,0x2a,0x9c,0xd5,0xe4,0x8b,0x82,0x91,0x37,0xc9,0x55,0x71,0x5d,0xbe,0xb4,0x49,0x31,0x8c,0xd6,0xf0,0x3,0xaa,0xe4,0x75,0x15,0xd6,0x54,0x21,0xac,0x27,0xaa,0xb2,0x5c,0x15,0x5c,0x55,0x49,0xac,0x46,0xb,0xe8,0xfa,0x97,0x48,0xba,0x8e,0xe9,0xa0,0x3a,0x6f,0x4a,0x3a,0x8e,0x45,0x12,0x53,0xd5,0xeb,0x38,0x37,0xb6,0x64,0xe0,0xf1,0x87,0x9e,0xaa,0xfb,0xd1,0x6b,0x24,0x18,0xf2,0x44,0x6d,0xa9,0xd6,0xbf,0x90,0x2a,0xd6,0xe2,0xaa,0xb2,0x9d,0x9c,0x63,0x7d,0x9c,0xc7,0x9a,0x73,0xac,0x63,0x2e,0x8a,0xb6,0xe9,0xe7,0x7f,0x39,0xf7,0xda,0xf2,0x6b,0xcc,0x44,0x95,0x37,0xb5,0x59,0xab,0x43,0x16,0x6e,0x63,0xcc,0x9a,0xf5,0x7b,0x24,0x7c,0x53,0xfd,0x2c,0x51,0x53,0x5,0x76,0x51,0xf3,0xc6,0xb8,0xf1,0xbb,0x4,0xa5,0x46,0xb2,0x6e,0x54,0xf4,0x8f,0x44,0xe8,0x48,0x12,0x1b,0x26,0x1a,0xd5,0x9a,0x22,0xb4,0x1e,0x17,0xeb,0xbf,0xab,0xab,0x42,0x74,0xa2,0x30,0xc6,0x44,0xf9,0x37,0x7e,0xcf,0x33,0xf9,0xc2,0xa5,0x28,0xf6,0xcb,0xef,0xe9,0x3c,0x5a,0xa9,0xf,0x7f,0x31,0x83,0xb1,0xd,0x7b,0xfa,0x3b,0xaa,0xd6,0x0,0xf3,0xbc,0x97,0x75,0xc9,0x83,0x8f,0xd1,0xc3,0xf,0x3d,0x2e,0xbd,0x78,0xe,0x97,0xce,0x3f,0x2d,0xb7,0xdb,0x2,0x81,0x40,0x8,0x40,0x81,0x40,0x20,0x10,0x5c,0xdd,0x38,0x73,0xc3,0x6d,0x78,0xf5,0x1b,0xbf,0x1f,0x27,0x4e,0x5f,0xc3,0x4a,0x87,0x74,0x4,0x99,0x75,0x14,0xc1,0xb5,0x46,0xe5,0xad,0x11,0x13,0x95,0xcc,0xa8,0xd6,0x1e,0xb5,0x46,0xb6,0xa9,0x89,0x12,0x69,0xfc,0x87,0xbc,0x1a,0xff,0xa1,0x3f,0x21,0xab,0xd6,0x6f,0x66,0x36,0xc8,0xf4,0xbe,0x65,0x86,0xf0,0x9b,0x32,0x79,0x6b,0xe4,0x99,0x3a,0xa0,0x4e,0xdb,0x24,0x74,0xab,0x37,0x8d,0xd3,0x9b,0x95,0xd,0x24,0xd9,0x78,0x83,0x79,0x34,0xe3,0x34,0xa5,0x80,0x36,0x93,0x3b,0xdf,0xce,0x78,0xd5,0xdf,0x60,0x5e,0xfe,0x16,0x71,0x40,0x35,0x74,0x98,0xa8,0x3b,0xf0,0xfc,0xcb,0xbe,0x7e,0x7c,0x6e,0x4d,0x1,0x59,0xed,0x76,0x7,0x88,0x3b,0xac,0xaf,0xbb,0xf5,0xd7,0xe5,0x75,0x3b,0xd9,0x74,0x21,0x1e,0x20,0xf2,0xa6,0x37,0xfb,0x6b,0xe4,0xc5,0xe1,0xc5,0x7b,0xc4,0x15,0xfd,0xd6,0x89,0xbc,0xb2,0xcf,0xcd,0x6b,0xe9,0x6f,0xca,0x8a,0x8e,0x6a,0xa0,0x61,0xe8,0xf0,0xec,0xe3,0x5f,0xc3,0x13,0x5f,0xfe,0x8c,0x7c,0x50,0x7e,0x97,0xa1,0xb5,0xc5,0xe2,0xf4,0x35,0x38,0x79,0xfa,0x3a,0xb8,0xa6,0x3d,0x64,0xcb,0x1c,0x3f,0x17,0x99,0xc4,0xe2,0xc,0xbf,0x69,0x29,0x48,0x55,0xf3,0x95,0x7d,0x1a,0x5b,0x49,0x95,0x42,0x8a,0x64,0xde,0x6f,0xc9,0x57,0x2b,0xa,0xbb,0x42,0x2a,0x8d,0x85,0x18,0x4c,0xc2,0xa4,0xc0,0x6a,0xbd,0x75,0xb2,0x6b,0x6a,0x1d,0x87,0xd2,0x93,0x38,0x85,0x91,0xa8,0xca,0x85,0x98,0xa9,0xa4,0x5f,0x82,0xd6,0x76,0xb4,0x9a,0x4e,0x8e,0x53,0xc8,0xc5,0x31,0x86,0x20,0xd7,0x63,0xae,0x29,0x81,0x33,0x0,0xad,0x27,0x64,0x90,0xe6,0x73,0xe4,0xf3,0x9f,0x58,0xde,0x29,0x37,0x8f,0x63,0x24,0xac,0xad,0xe4,0xd6,0x68,0x47,0x9d,0x90,0x61,0x4c,0xc0,0x8d,0x4,0x17,0x93,0x8b,0x1c,0x89,0x90,0x52,0xa8,0xad,0xbb,0x95,0xe0,0x34,0xb4,0xcf,0x52,0x72,0x32,0xc6,0x29,0x98,0x4a,0x4a,0xe5,0xe8,0x99,0x9c,0xc2,0x38,0x1e,0x4c,0x9a,0x79,0x27,0x8a,0x44,0xb2,0xfc,0x87,0xda,0xce,0x5b,0x55,0xcb,0xa,0x50,0xda,0x22,0x27,0x2a,0x51,0xc9,0x6b,0x6a,0x46,0xb6,0x4d,0xa7,0x3c,0x92,0x9d,0x93,0x78,0x8d,0x69,0xf3,0x6d,0x21,0x72,0xa9,0x4,0xc5,0x91,0x82,0x52,0x8f,0x64,0x1e,0x8d,0x2b,0x8c,0xe4,0x5c,0x89,0xb1,0x50,0xba,0xc6,0x3b,0xd0,0xf1,0x3,0xa0,0xf4,0x38,0x87,0xac,0x3c,0x4,0xab,0x21,0x31,0x25,0x51,0xa7,0x64,0xaa,0x52,0x88,0x61,0x80,0xb1,0x4d,0xcd,0x34,0x2c,0x6b,0xaa,0x7c,0xee,0x18,0x63,0x6b,0x56,0x63,0xb9,0xbe,0x25,0x6,0xa2,0x5c,0x1f,0x63,0x2c,0x12,0xb7,0xfa,0x52,0xeb,0xb3,0x43,0x4a,0x1,0x5a,0x3b,0x1e,0xef,0x48,0x20,0x77,0xab,0x15,0x96,0xbb,0x97,0x30,0x2c,0xe5,0x4b,0xc,0x81,0x40,0x70,0xbc,0x20,0x16,0x60,0x81,0x40,0x20,0x10,0xfc,0xed,0xdf,0x74,0x1a,0x87,0x57,0xbf,0xf1,0x7,0xb0,0x75,0xe2,0x14,0x86,0xbe,0x1b,0xad,0x52,0x6b,0x34,0xc5,0xba,0xca,0xa3,0xc8,0xc6,0x72,0xca,0xd4,0xe,0xb8,0x99,0x43,0x18,0xed,0x87,0x18,0x73,0x8c,0xa6,0xa,0x8e,0x3c,0xc9,0xb2,0xaa,0xa,0x4,0xce,0x37,0x8b,0x21,0xf0,0xd,0x2e,0x38,0x37,0x6f,0xfd,0x6,0xb8,0x86,0xa8,0x3,0xa3,0xf2,0x63,0x8d,0x68,0xd3,0x6b,0xa4,0xc8,0x41,0xfb,0xdc,0x5a,0xee,0x1a,0xf2,0xe4,0x86,0x65,0xbd,0xe9,0xf2,0xe5,0x88,0x95,0x75,0x55,0xc4,0x24,0xcb,0x68,0x72,0xd3,0x76,0x90,0xab,0xdc,0xa8,0xed,0x52,0xeb,0x56,0xe6,0xb2,0xcd,0xf4,0xb5,0x7,0x5f,0x53,0x8e,0x91,0x5f,0x86,0x54,0xfc,0x4e,0x5a,0xf,0xf,0x91,0x57,0xdf,0xd6,0x3e,0xe,0xca,0x26,0xbf,0x13,0xb2,0x2f,0x1f,0x69,0x25,0xfc,0xa6,0xaf,0x3d,0x40,0xb4,0xe5,0x23,0xe8,0xd2,0x51,0x8d,0x32,0x99,0xd3,0x83,0xc4,0xde,0x94,0x24,0xc0,0xff,0xcb,0xde,0x9b,0x3e,0xdb,0x76,0xd7,0xe7,0x9d,0xcf,0x6f,0x5a,0x6b,0xef,0x73,0xce,0x9d,0x34,0xf,0x8,0x24,0x24,0x10,0x8,0x81,0x40,0x8,0x81,0x99,0x8c,0x8c,0x65,0x8c,0xd,0xb6,0x69,0xc7,0xed,0x76,0x95,0xe3,0x94,0x53,0x7e,0x99,0xae,0xce,0x1f,0xd2,0xd5,0x55,0xdd,0x55,0xa9,0xee,0x74,0xa5,0x93,0xb8,0xd2,0xe9,0xc4,0xb1,0x3b,0x8e,0x8d,0x13,0x3,0xe,0xc6,0xc6,0x18,0xcc,0x8c,0x11,0x20,0x1,0x32,0x42,0x12,0x9a,0xa5,0x7b,0x75,0xa7,0x73,0xf6,0x5e,0xeb,0x37,0xf4,0x8b,0xef,0xb0,0xd6,0x3e,0x67,0x5f,0xe2,0x98,0x9b,0x4b,0xbf,0xf8,0x3e,0x2e,0x5b,0xd2,0xbd,0xe7,0xec,0xbd,0xa6,0x7d,0x74,0xf5,0xf1,0x33,0x4c,0xbd,0x97,0x9b,0x11,0x70,0x6c,0xa4,0xcd,0xdc,0xa1,0xe3,0x9e,0x7f,0xff,0x61,0x27,0xcc,0xe1,0xeb,0x3b,0xef,0xc3,0xdc,0x6,0xf9,0x2e,0x75,0x5f,0x8e,0xbc,0xfe,0x25,0xce,0x69,0x8e,0x1e,0x15,0x52,0xb7,0x2d,0x51,0x70,0xfe,0x75,0x19,0x1b,0x28,0x25,0xe3,0xc4,0x55,0xd7,0x23,0xf6,0x3b,0xc8,0xeb,0x7d,0xfb,0x81,0xf9,0xdf,0x50,0xb5,0x66,0x5c,0x38,0xfd,0x1c,0x2e,0x9c,0x7e,0xe,0x3e,0xed,0x1,0x6d,0x9c,0x45,0x53,0xb,0x9c,0xb,0xa,0x92,0xd0,0x68,0x81,0x55,0xa0,0x50,0xe3,0xaf,0xf1,0x69,0x89,0x9a,0xf,0xe0,0xd3,0x1e,0x5a,0x5e,0xc1,0x5,0x5e,0xbc,0x4d,0xb,0xd4,0xe1,0x22,0x43,0xb1,0xcc,0xc3,0xf,0x9,0xd,0x9e,0x3b,0xde,0x6,0x38,0x9f,0x50,0xf3,0x1,0x9c,0x8f,0x70,0xbe,0x23,0xd0,0xe7,0x3,0x50,0x33,0xe0,0x23,0x83,0x2c,0x87,0x9a,0x57,0x88,0xfd,0x71,0x94,0x71,0x1f,0x3e,0xf4,0x74,0x2c,0x70,0x80,0x6b,0xbc,0xfe,0x4b,0xc7,0xe4,0x42,0x42,0x2d,0x23,0x1c,0x1a,0x9c,0xef,0x0,0xc7,0x3f,0x67,0x5,0x64,0x49,0x3c,0x59,0x46,0x2a,0x20,0xa0,0xa7,0x6c,0x38,0xd2,0xe0,0x13,0x80,0x8a,0x56,0xd6,0xf0,0x61,0x41,0xc7,0xea,0x0,0xf0,0xf5,0x70,0xce,0xa3,0xe6,0x35,0xc1,0x20,0x1,0x53,0xde,0x3,0x2e,0xd0,0x39,0xd,0x17,0xe0,0xe3,0x82,0x41,0x60,0x45,0x6b,0x5,0x3e,0x2e,0xd1,0xca,0x48,0xe7,0x18,0x7a,0xfe,0x57,0x1b,0x43,0xa8,0x3a,0xc2,0xb9,0x0,0xdf,0x2d,0x51,0xc7,0x15,0x5c,0xe8,0xd0,0xca,0x8,0x1f,0x3b,0x2,0x75,0x79,0x5,0xf8,0x38,0xfd,0xb8,0xab,0x72,0xdd,0xd7,0xc,0x1f,0xb9,0x1b,0xcf,0x7,0x6,0x70,0x5,0x80,0x87,0x73,0xd,0xb5,0x8c,0x80,0x8b,0x74,0xaf,0x62,0xbf,0xd1,0xb5,0x27,0xae,0xe2,0x5a,0x32,0x1d,0xbb,0x3,0x5c,0xe8,0x51,0xf3,0xa,0x3e,0xf6,0x74,0xad,0x4a,0x46,0x2b,0x3,0x5a,0xcb,0x70,0x3e,0x11,0x63,0xc,0x89,0xa3,0xd4,0x1e,0xb5,0xac,0xd1,0x5a,0x41,0x48,0x7b,0x68,0x75,0x80,0x8f,0x4b,0xd4,0xbc,0xa2,0xe7,0xa4,0x15,0x3a,0x7f,0x6,0x92,0x2e,0x74,0x68,0xf9,0x0,0x2e,0x74,0xf0,0x71,0x81,0xbc,0x3e,0x7,0x1f,0x7a,0xb4,0x32,0xc0,0xa7,0x1d,0x75,0xdf,0xc1,0x7,0x7d,0xd,0xd4,0x2,0x17,0x3b,0xa0,0x55,0x38,0x4f,0xef,0x5b,0xc7,0x3,0xfa,0x77,0x7c,0x5a,0xa2,0x95,0xc,0x17,0x22,0x5a,0x19,0x50,0xf3,0x9a,0x9f,0x25,0xba,0xf,0xad,0x8e,0x70,0xfc,0xfa,0xad,0xc,0xf4,0x93,0xd0,0x27,0x2,0x91,0xc3,0x3e,0xd,0x90,0xa4,0x25,0x6a,0x59,0x23,0xf6,0xc7,0x90,0x57,0xe7,0xf4,0xbe,0x39,0x1f,0x51,0xc7,0x7d,0x86,0x7b,0x2,0x44,0xa7,0xf3,0x56,0xb0,0x1d,0x17,0x34,0x1e,0x32,0x5e,0xa4,0xcf,0x8b,0xfc,0xd4,0xab,0xd9,0x7e,0xc0,0x98,0x4c,0xa6,0xff,0xdf,0xc9,0x1c,0x80,0x26,0x93,0xc9,0x64,0xba,0xe2,0xba,0xfa,0xa6,0xdb,0x70,0xef,0xbb,0x3f,0x80,0x92,0xa7,0xa5,0xc1,0xaa,0xf1,0x20,0x37,0x79,0xfa,0xe,0xd,0xb,0xc8,0xef,0x6b,0xaf,0x94,0xdb,0x8c,0x2,0x1d,0xee,0xcc,0x9b,0x2f,0x37,0xa,0x98,0x70,0x87,0x9d,0x55,0x2,0x32,0xa4,0x83,0x89,0x1d,0x56,0xb5,0x55,0x4,0xf9,0xf,0x45,0xee,0x2d,0xf2,0x61,0x1a,0x94,0x68,0xe0,0x1,0x87,0x43,0x70,0xae,0xcd,0x8e,0xe7,0x70,0xaf,0x16,0x8d,0x8c,0x88,0x43,0xa2,0x6d,0x12,0x1d,0x3e,0xca,0x5a,0x2b,0x42,0x8,0x5a,0xf4,0x2e,0xd0,0x53,0x0,0xa3,0xf6,0xa9,0x89,0xeb,0x63,0xc3,0xe5,0xe1,0x8e,0x14,0xde,0x4f,0x45,0xe6,0xdb,0x22,0xae,0x6e,0x13,0xb0,0x62,0x8a,0xc3,0xb5,0xcd,0x42,0xa3,0x8d,0x8,0xd7,0xd1,0x8c,0x97,0xd3,0x98,0x95,0x1c,0xcb,0x74,0x69,0xfd,0x6,0x64,0xda,0xd6,0x85,0x38,0x8f,0x1d,0x1e,0x86,0x89,0x75,0x16,0xb1,0x73,0x47,0x7a,0x7,0x8f,0xfe,0x71,0xc6,0x1d,0x72,0xd7,0xc8,0xd0,0xc6,0x14,0x6f,0x3b,0x34,0xca,0xb2,0x31,0xb6,0x31,0x8f,0x8b,0xb5,0x8d,0xf8,0xec,0x61,0x57,0xe6,0xa5,0x0,0xd9,0x9c,0x13,0x4e,0x63,0x20,0x7e,0x33,0x46,0x38,0x1f,0x14,0x39,0x2,0xd8,0x70,0x18,0xd7,0xcd,0x18,0xd9,0x1c,0xf8,0xca,0xc0,0x4b,0xdd,0x7c,0xae,0x67,0xd1,0xc2,0x8d,0x66,0xfb,0x99,0xab,0x70,0xde,0x51,0xb6,0x31,0xc8,0xc1,0xe5,0xf7,0x2,0x94,0xbd,0x7e,0xa6,0x66,0xf7,0xbe,0x1,0xe0,0x51,0x81,0xaa,0xcf,0xdf,0x25,0xb,0x3b,0x27,0x88,0x49,0xff,0x45,0xbc,0xb1,0xc2,0x7a,0x18,0x2c,0xb6,0x56,0x9,0x0,0xe6,0x8c,0x71,0x5c,0xe3,0xbb,0xf,0x7d,0x9,0xfb,0x67,0x5f,0xb0,0x1f,0x98,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0x97,0x41,0xb6,0x4b,0x6e,0x32,0x99,0x4c,0xa6,0x2b,0xaf,0x86,0xa3,0x8e,0x3f,0xee,0xfb,0xd3,0x55,0x3f,0x6,0x14,0x3e,0x4,0x2,0x3f,0xf2,0x6b,0x98,0xd6,0x1a,0x25,0xee,0x25,0x60,0x4e,0x0,0x2,0x0,0x5d,0x8d,0x94,0x38,0x92,0xf4,0x20,0xd5,0x19,0xe8,0xa3,0xb7,0x9c,0xad,0x14,0xb6,0xa6,0xdd,0x46,0xc1,0xcb,0x22,0xf0,0x14,0x1d,0x96,0xd5,0x61,0xc6,0x16,0x14,0xc5,0xd2,0xb3,0x98,0x62,0x64,0x4d,0xa3,0x43,0xf3,0x9e,0x25,0x3e,0xde,0x59,0x21,0xbe,0xf,0x54,0x2a,0x8f,0x6,0x5,0x90,0x0,0x50,0x4a,0xc6,0x7c,0xa1,0x50,0x7b,0xa2,0xe6,0x63,0xa,0x5c,0x6e,0xa4,0xab,0xc5,0x98,0x3b,0x8,0xb9,0x8b,0xc8,0xcd,0x9d,0x86,0x6e,0x3,0x36,0xea,0x45,0xdf,0x18,0x52,0x91,0xf3,0xa8,0x4,0x1d,0xdb,0x64,0x35,0x93,0xfb,0x45,0x83,0xd,0xf3,0x85,0x5f,0x59,0xc4,0x24,0x17,0x67,0x9d,0xbb,0x24,0xa7,0xbd,0x80,0x23,0x8e,0x3e,0xe9,0x6b,0x17,0x17,0xca,0x91,0x9e,0x40,0x38,0x65,0x56,0xb2,0x8,0xad,0xcb,0xbc,0x47,0x5e,0x6b,0x5a,0x7,0xad,0x1c,0xf1,0xa2,0xe3,0x69,0x1a,0xe9,0x93,0xf3,0xd2,0x18,0xe1,0x2c,0x7a,0xa7,0x40,0x4a,0x96,0x40,0x25,0xce,0x5,0x1c,0x1a,0x40,0x80,0x5e,0xe7,0xa3,0x2e,0x45,0x37,0xdb,0xff,0x9d,0xc7,0xb5,0xdb,0xf,0x81,0x7f,0x87,0x3e,0x16,0x6d,0x7a,0x85,0x9,0x92,0x35,0x5d,0x22,0xde,0xf8,0x75,0x5d,0xe,0x86,0xae,0x18,0xb7,0xd9,0xfd,0x12,0x27,0xab,0xd3,0x3,0x77,0xa,0xcf,0xe5,0xb8,0x4,0xfe,0x49,0x37,0xd8,0x76,0x98,0xe9,0x36,0x80,0xae,0x7c,0xe,0x4,0x10,0x62,0xb6,0x1e,0xab,0xe7,0x20,0x6e,0x44,0x5,0xea,0x55,0xef,0x51,0x9d,0xbf,0xcf,0x91,0x61,0x89,0xd9,0xb5,0xe0,0x75,0x6a,0x93,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xe5,0x91,0x1,0x40,0x93,0xc9,0x64,0x32,0x5d,0x71,0x39,0x71,0x73,0x6d,0xe9,0x31,0x73,0xde,0x6d,0xac,0xe0,0xca,0x52,0xa4,0x2,0x9,0x85,0x55,0xc,0x7,0x1d,0xad,0x3,0x86,0x10,0xc9,0x91,0xc7,0xfd,0x41,0x2,0xa3,0xbc,0xf7,0xf0,0xdc,0xa1,0xe4,0xd9,0xad,0xe4,0x7d,0x98,0x15,0xbf,0x4b,0xf9,0x3d,0x10,0x53,0x47,0x60,0xce,0x7b,0x94,0x52,0x10,0x62,0x54,0x98,0xe1,0xe7,0xb1,0x31,0x37,0x75,0x29,0x51,0xe1,0x37,0x45,0x7d,0xc4,0x45,0xe5,0x7d,0xa0,0xe2,0xfb,0x36,0xb9,0x17,0x29,0x56,0x5c,0xe8,0x38,0x19,0xbc,0xd4,0x92,0x21,0x88,0x87,0x16,0x26,0x1b,0x9c,0x77,0xda,0x47,0x34,0x8f,0xe4,0x6a,0x34,0xd,0x33,0x50,0xb4,0x11,0xe1,0x75,0xdc,0x97,0xc4,0x90,0x88,0x8f,0x6d,0xa2,0x4c,0xed,0x48,0xbc,0x55,0x60,0xd0,0x66,0x77,0xdc,0x66,0x29,0xfc,0x66,0xef,0xbe,0xd3,0xdf,0x9f,0xf7,0x22,0xa,0xe0,0x73,0xbc,0x32,0x39,0x4d,0x4e,0x4e,0xce,0x44,0x7a,0xdb,0x86,0x19,0x1f,0xd2,0xaf,0x17,0xd0,0xba,0x1,0x22,0xf,0xc1,0x30,0xf9,0xeb,0xfc,0x1a,0x6c,0x38,0xc9,0x8e,0x44,0x77,0xdd,0xec,0x1f,0xe7,0x6b,0x8e,0xd2,0xe9,0xd4,0x36,0xc1,0x16,0xa0,0xc7,0x2d,0x3d,0x67,0x38,0xe2,0x54,0x3b,0xa,0xff,0xb4,0x7,0x8d,0x5d,0x71,0x2,0xfc,0xf4,0x58,0x79,0x34,0xa0,0xcd,0x0,0xb7,0x5c,0xc3,0xe9,0xf5,0x67,0xe5,0xf6,0x52,0xb0,0x2f,0xcf,0xbc,0x73,0x47,0x2,0xce,0x9b,0x31,0x5c,0x6c,0x1c,0x7,0x36,0xae,0xe9,0x1c,0x98,0x36,0x2,0xe0,0xa5,0x28,0x24,0xaf,0x85,0x7b,0xd9,0xca,0xbc,0x74,0xff,0xf0,0x7b,0x4d,0xd7,0x4b,0x9e,0x7b,0x3f,0x73,0xf1,0xe9,0x90,0x81,0xf7,0x1b,0xcf,0x95,0x42,0xd6,0x99,0x1b,0x77,0xdb,0xcf,0x81,0x8d,0xcf,0xfe,0xe1,0xfb,0xe7,0xad,0xa9,0xc6,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0x72,0xc9,0x0,0xa0,0xc9,0x64,0x32,0x99,0xae,0xb8,0xc6,0x71,0xad,0xff,0x91,0xf,0x60,0xd6,0xc7,0x84,0xc9,0x79,0xc6,0x20,0x61,0xce,0x46,0x0,0x81,0x6e,0x40,0x8,0x11,0xa5,0x64,0x8d,0x28,0x56,0x2e,0x83,0xf7,0xc,0x17,0xe7,0x40,0xa1,0xcd,0x62,0x8f,0x12,0x8d,0xa5,0x12,0xef,0x20,0xf4,0x1,0x40,0x43,0x61,0x30,0x52,0x72,0x86,0xf7,0x1e,0x79,0x1c,0x19,0x6c,0x10,0xb4,0x89,0xb1,0x53,0x78,0xa2,0x70,0x5,0xd,0x21,0x26,0x1e,0xca,0x6c,0xa,0x6,0x1b,0x3b,0xf4,0x3c,0xc7,0x76,0x85,0x78,0x35,0x7e,0xfd,0xe9,0x7d,0xc5,0xd,0xc6,0x4e,0xb4,0xda,0x50,0x24,0x66,0xcc,0xb0,0x68,0xbe,0x46,0x49,0x5d,0x53,0x12,0xa7,0x9d,0xf5,0xff,0xf1,0xaf,0x55,0x85,0x38,0x72,0x6d,0x31,0xbb,0x80,0x6e,0x16,0xb5,0x75,0x73,0x86,0xa8,0xee,0x35,0x85,0x96,0x5a,0xf6,0xcf,0xf1,0x63,0x39,0x67,0x34,0xee,0x4c,0xc4,0x74,0x8e,0x1b,0x90,0x8b,0x5f,0x4f,0x4a,0xd9,0x8f,0xc4,0x67,0xdb,0x6,0xe0,0xa5,0xf3,0x70,0xa,0x4c,0x5,0xcc,0xce,0xa3,0xc2,0xf4,0x7b,0x47,0x1,0xdf,0x5c,0x9b,0xce,0xbe,0xc3,0xb0,0xae,0x6e,0x5d,0x18,0x9e,0xde,0x6b,0xbe,0x56,0xdc,0x36,0xe0,0xe0,0x14,0x13,0x86,0x1e,0x83,0xc0,0xbc,0x8d,0x81,0x8d,0x5a,0xd5,0xa9,0xe7,0x8e,0xf4,0xf9,0x35,0x5,0x9e,0x12,0x79,0x96,0xeb,0xec,0xb0,0x59,0xea,0xe7,0x0,0xf8,0xe0,0xf5,0x39,0x45,0xad,0x9b,0xd1,0xf2,0xf9,0xb5,0x53,0xf8,0xe8,0xe7,0x17,0x7e,0xe3,0x5c,0xa1,0x25,0xfa,0x13,0x64,0x9b,0xff,0xb3,0xc2,0xeb,0x8d,0x2a,0xc1,0xc9,0xc1,0xe9,0x79,0x58,0xc0,0xcd,0xbe,0x9f,0xbe,0xe6,0xd0,0xb5,0xd3,0x6b,0xeb,0x67,0xf1,0xe1,0xba,0xb1,0xc2,0x3a,0x3f,0x6,0x1,0x83,0x5e,0x1d,0x89,0xe2,0x3e,0x9d,0x8d,0xd1,0x98,0x5,0xd0,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0xb2,0xc9,0x0,0xa0,0xc9,0x64,0x32,0x99,0x7e,0x3c,0x72,0x9b,0x3d,0x73,0x3a,0xa1,0xc0,0x6e,0x22,0xed,0xff,0x3,0xe,0xf5,0x9a,0x41,0xe3,0x8f,0x12,0xc7,0x15,0xc7,0x96,0xe3,0xd8,0xee,0xdc,0x89,0x37,0x87,0x7e,0xe2,0x18,0xd4,0x65,0x41,0x76,0x18,0xc6,0x94,0xe0,0x9c,0x47,0x4a,0x9d,0x76,0xaa,0x1,0x40,0x88,0xe4,0xd6,0xf3,0x3e,0x0,0xe,0x28,0x85,0x80,0x60,0x8,0x41,0x1,0x87,0x77,0x7e,0x5a,0xc0,0x64,0x70,0xe6,0x3d,0x45,0x56,0xbd,0xf7,0xb3,0x68,0x71,0x9b,0xad,0x38,0x6,0x6c,0x40,0x1f,0xcf,0x6b,0x87,0xc,0x43,0xa4,0x5b,0x50,0xdc,0x90,0x8d,0xa1,0x99,0x67,0xc8,0xd5,0x18,0x4,0xb6,0x8d,0x95,0xcd,0x3a,0xab,0x7c,0x73,0x33,0x48,0xe8,0x66,0xaf,0xcd,0x7e,0x43,0x89,0x96,0xb6,0xba,0x1,0x83,0x34,0x56,0xac,0xd1,0x59,0x1a,0x5c,0xd9,0x0,0x48,0x7c,0x9b,0xf4,0x35,0x6a,0x9d,0x5e,0xc7,0x4d,0xbf,0x3e,0x39,0x25,0xbd,0xe,0xdc,0x2a,0xc8,0x3a,0xec,0xb4,0xa3,0x9b,0xbc,0x11,0x91,0xd5,0xe7,0xa2,0x41,0xc1,0x9e,0x80,0xa4,0xb9,0x53,0x50,0xae,0xdd,0xe1,0x31,0x90,0x4d,0x63,0xe0,0x51,0x20,0x4c,0x7f,0xad,0xba,0x18,0x9,0x6c,0xf6,0x27,0x4e,0x5f,0xe7,0x30,0x5f,0x77,0x84,0x2c,0x49,0xb,0xd0,0x9d,0x83,0x2d,0xbd,0x8e,0x6d,0x6b,0x2d,0x9e,0x3a,0xec,0xe6,0xae,0x42,0x3f,0x75,0xf5,0x9,0xe8,0x2c,0xa5,0x50,0xd7,0xa4,0xf7,0x3c,0xc0,0x30,0xb9,0x0,0xeb,0xec,0x33,0x21,0xcf,0x38,0x1,0xeb,0xa0,0xd7,0x2e,0x84,0x30,0x73,0x50,0xb6,0xd,0x47,0xa0,0xdc,0x13,0x7a,0x6,0x37,0x9d,0x7b,0x2,0xfb,0x2a,0xdf,0xd3,0x9,0xd4,0xd2,0x67,0xa2,0x49,0xcc,0x78,0x23,0xec,0x7c,0x78,0xbc,0x66,0x72,0x6b,0x6a,0x5c,0x5e,0xaf,0x7d,0xe3,0x67,0xa7,0x6a,0xac,0x7b,0x2,0xea,0x15,0x1b,0xd3,0xdd,0xc0,0x96,0xae,0x47,0x93,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xdf,0x55,0x6,0x0,0x4d,0x26,0x93,0xc9,0x74,0xc5,0x15,0x42,0x9c,0x16,0x65,0x5,0x1e,0x30,0x34,0xf1,0xec,0x74,0x3b,0xc,0x20,0x1c,0x26,0xa0,0x24,0xa0,0x40,0x3a,0xf9,0x14,0x22,0xd4,0x32,0xeb,0xc5,0x6b,0x33,0xe8,0x33,0x73,0x14,0xb5,0x9,0x82,0x95,0x9c,0x11,0x52,0x42,0x2d,0x4,0x5b,0x26,0x37,0x94,0x63,0x57,0x5f,0xe3,0xa8,0x2e,0xbd,0xbe,0xb8,0xf1,0xf2,0x38,0x6e,0xe4,0x58,0x25,0x36,0xc,0x38,0x76,0xf7,0x39,0x1e,0x35,0x11,0xe7,0x9a,0xd7,0x48,0xa9,0x97,0x3e,0x3b,0x89,0x53,0xce,0x60,0xe4,0x46,0xe7,0x1b,0x8f,0x8c,0xb4,0xda,0xd4,0x19,0x28,0xbf,0xa3,0xb1,0xd0,0x43,0x91,0x5b,0x82,0x9f,0x61,0xe3,0xda,0xb4,0xd6,0x50,0xa5,0x83,0xad,0x61,0x4b,0x9c,0x7a,0xd6,0xdb,0x76,0xa8,0x73,0xd0,0xe9,0xda,0xf2,0xe6,0xf8,0x5,0x1c,0x34,0x46,0x3d,0xc5,0x88,0xf9,0x1e,0xcd,0x22,0xad,0x53,0xcc,0xdb,0xf1,0xf1,0x30,0xe0,0xf4,0xd3,0x3d,0xa9,0xd2,0xd3,0xc8,0x30,0xaa,0x8a,0x73,0x70,0x7a,0xc7,0x23,0x4e,0x30,0x71,0xe5,0x49,0x94,0x5a,0x9e,0xa1,0xcd,0x5e,0xbe,0x9,0x14,0xce,0xe1,0xd7,0xfc,0x35,0x28,0xaa,0x5a,0xa6,0x73,0xc7,0xc6,0x65,0x51,0xc8,0x2b,0xef,0xc5,0x2f,0x3b,0x5b,0xcf,0xe5,0xb3,0x54,0x57,0xe9,0xf4,0x2,0x9b,0x4b,0xc9,0xd3,0xab,0x6f,0xba,0x51,0x67,0xf0,0x15,0x53,0xb7,0xe2,0x86,0x4b,0x8e,0xfb,0x8,0x5,0x6e,0xb,0x54,0x96,0xef,0xa9,0xb5,0x4c,0x6e,0xbb,0xd6,0xd8,0x19,0x5b,0x66,0xc7,0x24,0x83,0x21,0x9e,0xc1,0x34,0x3b,0x10,0x6b,0x9b,0x5c,0x9a,0x98,0xfa,0x10,0x81,0x9,0xaa,0x4e,0xc7,0xc3,0x10,0xf2,0x30,0x70,0x9f,0xc1,0x7a,0x71,0xe0,0x4e,0x90,0xb7,0xf1,0x75,0xb,0xfc,0x8c,0xf0,0x7b,0xa0,0xc1,0xc1,0x4f,0xf0,0x7f,0x16,0x75,0xd6,0xf7,0x6a,0x4d,0xfb,0x3a,0x4d,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0x97,0x47,0x6,0x0,0x4d,0x26,0x93,0xc9,0x74,0xc5,0x15,0x62,0xba,0xe4,0xef,0x49,0x6c,0x52,0x0,0x83,0x77,0x5e,0xfb,0xf7,0x74,0xd0,0x81,0xdd,0x74,0x2,0x52,0x24,0xca,0x2b,0x91,0x42,0xef,0xbd,0x42,0x7,0xc7,0xf0,0x2d,0xcc,0xbe,0x46,0xe0,0xb,0xd,0x8c,0x30,0xb4,0x28,0x4,0x1c,0x62,0x4a,0xb4,0xc2,0x9b,0xc7,0x8d,0xbe,0xbf,0x39,0xdc,0x20,0x67,0x1e,0xc7,0x72,0x4b,0x9e,0x0,0xc,0x2f,0xf8,0x7a,0xe7,0x11,0x43,0x52,0x48,0x38,0xbd,0xf7,0xe6,0x50,0x82,0xc,0x67,0x50,0xf4,0x78,0xd6,0xa5,0x76,0x68,0x1c,0x41,0xdc,0x84,0x0,0x8e,0x74,0xd3,0xd5,0x79,0x54,0x75,0x76,0x7d,0x0,0xf0,0x62,0x31,0x1,0x57,0xc8,0x68,0xc3,0x6c,0xdb,0x63,0xe,0x78,0xd4,0x39,0x39,0x8f,0x98,0xaa,0x93,0x6d,0x1a,0x9e,0x90,0x8b,0x48,0xc0,0xe7,0x70,0xf,0x61,0xa3,0x61,0x14,0x71,0xd6,0xf1,0x28,0x8b,0xb8,0xc1,0xea,0x6c,0x18,0x45,0xe4,0x9c,0xc4,0x9f,0xd9,0xd9,0xc8,0x90,0x72,0x5b,0xc4,0x77,0x3a,0x56,0xe9,0x54,0xac,0xfa,0xbe,0xf2,0x3a,0xd3,0xb1,0x6c,0x79,0xb6,0x74,0x51,0xda,0x6d,0x8c,0x55,0x4c,0x2e,0x38,0xb7,0x71,0x9c,0x6d,0x76,0x5e,0x1a,0x8d,0x65,0x7,0xdf,0x34,0xea,0xa1,0x47,0x38,0xdd,0x43,0x81,0x8b,0x33,0xc8,0x47,0xcf,0xb1,0x57,0x77,0x28,0x5d,0xe3,0x59,0x5f,0x23,0xe,0xbb,0x13,0x37,0x1d,0x76,0x12,0x59,0x6f,0xb3,0xf5,0xe8,0xc3,0x7f,0x3f,0x8f,0xf4,0xfa,0x79,0x2c,0x78,0x6,0x41,0x5b,0xab,0x1a,0x2b,0x9e,0x1c,0xb2,0x72,0xb6,0xd0,0xd8,0xfa,0x86,0x6b,0xb2,0xc9,0x92,0x71,0x61,0x17,0xeb,0xd4,0x71,0xa8,0x43,0x3b,0x87,0x9e,0xd7,0x36,0x7b,0x16,0x15,0xa0,0xcf,0xc6,0x6c,0x30,0x1f,0xf2,0xd9,0x28,0x86,0x84,0x7e,0x36,0x61,0x9,0x60,0x93,0xc9,0x64,0x32,0x99,0x4c,0xa6,0xcb,0x26,0x3,0x80,0x26,0x93,0xc9,0x64,0xba,0xe2,0xca,0x79,0x94,0x60,0xa5,0x10,0xe,0x75,0x0,0xd5,0x56,0x19,0x22,0x11,0x7c,0x12,0xc0,0xe5,0xbd,0x3f,0x34,0x42,0x50,0x37,0x60,0xc9,0x61,0x67,0x14,0xfd,0x7a,0xd5,0x21,0xa,0xf9,0x5a,0xaf,0xf1,0xdd,0xd9,0x88,0x1,0x2f,0xf2,0xa,0xb8,0xa8,0x75,0xea,0x7,0x9c,0x43,0x40,0xf9,0x3a,0xef,0xe5,0x7f,0x23,0xc1,0x4c,0x76,0x2d,0x3a,0x86,0x24,0xa5,0x16,0x1a,0x22,0x61,0xb0,0x55,0x72,0xd6,0x78,0xae,0xf,0x61,0xea,0x4,0x4,0xaf,0x1,0xf3,0xeb,0x51,0xd2,0x57,0x20,0xa0,0x74,0x23,0xf2,0xe5,0x61,0x70,0x74,0x78,0xa9,0x55,0x86,0x4d,0xc4,0x81,0xb5,0x1,0x6e,0xb4,0xc7,0xaf,0xc8,0x15,0x81,0x80,0x1e,0xef,0x3c,0x83,0x58,0x8e,0x89,0x32,0x78,0x94,0x18,0xab,0x2e,0x2d,0x3b,0xa8,0xf3,0x4b,0x60,0xec,0xe4,0xae,0x3b,0xdc,0xc9,0xe7,0x66,0xf0,0xb2,0x2a,0x58,0x93,0x1,0x14,0xb9,0x77,0xe2,0x28,0xd3,0xeb,0xb,0xcc,0xee,0xdf,0xd4,0x89,0xb8,0x6d,0xf0,0x83,0x5e,0xd7,0x7f,0xde,0xd1,0x70,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x61,0x72,0xad,0xb1,0xc3,0x70,0xa3,0x7f,0x10,0x47,0xdc,0x7e,0x12,0x91,0x45,0xdb,0xec,0x20,0x74,0xda,0x19,0x49,0xd7,0x51,0x6,0x65,0xe,0x4b,0xba,0xef,0xe6,0xae,0x3a,0x75,0xca,0xb5,0xba,0xd1,0xcd,0x27,0xcf,0xee,0xfc,0xf8,0x65,0x9d,0x98,0xe0,0x19,0x34,0x8e,0x3e,0x3d,0x3,0x4e,0xc1,0xe2,0xb6,0xff,0x5,0x66,0x51,0xe8,0x43,0xc3,0x20,0xed,0x10,0x58,0xf5,0x21,0xa0,0x30,0x98,0x16,0x90,0x2e,0xcf,0xa9,0x44,0x9e,0x9d,0x9b,0x9f,0xd7,0xe4,0xd6,0x43,0xad,0xdc,0xad,0x29,0x9f,0x39,0xe8,0xca,0xb6,0x0,0xd0,0xc0,0x11,0x76,0x71,0x1a,0x62,0xf6,0xd9,0x52,0xb0,0x3e,0x73,0x67,0x4e,0x10,0xb5,0x6e,0x7e,0xde,0x5,0x3a,0xf3,0x35,0x10,0x8,0xac,0xfd,0x9a,0xe6,0x0,0x34,0x99,0x4c,0x26,0x93,0xc9,0x64,0xba,0x6c,0x32,0x0,0x68,0x32,0x99,0x4c,0xa6,0x2b,0xae,0x18,0xe3,0xd1,0x8a,0x34,0xe9,0x9c,0x9b,0xad,0xf3,0x8a,0x13,0x6c,0x1e,0xaf,0x74,0xb3,0xa8,0xa0,0x40,0x90,0x10,0x22,0xf5,0xd6,0x61,0xf3,0x6b,0xbc,0xf,0x70,0x70,0xa,0x74,0x8,0xb4,0xd1,0xeb,0x87,0x18,0x91,0xba,0x8e,0x7e,0x8d,0xfb,0x3,0x7d,0x8c,0x1a,0x6d,0x55,0x28,0xc7,0xaf,0x3f,0xd,0x76,0xd0,0xeb,0x35,0x34,0xd4,0x92,0xc9,0xe1,0x56,0x2b,0x42,0x88,0x33,0xd0,0x34,0x45,0x73,0xbd,0x13,0xb0,0x41,0xae,0xc5,0x92,0xb3,0x42,0x99,0x5a,0xab,0x2e,0x9,0x57,0xed,0xd1,0x23,0x57,0x15,0x2d,0x10,0x4f,0x2e,0xb4,0x92,0x47,0x68,0x6f,0x9e,0x74,0xab,0xcd,0x22,0xb6,0x1b,0x31,0x52,0xe7,0xe0,0xf9,0x78,0x36,0x7b,0xed,0x26,0xa7,0x18,0x2d,0xc2,0xe6,0x59,0x7,0xde,0x14,0xad,0xa5,0x58,0x69,0xd0,0xe6,0x39,0x81,0x79,0x2,0xb2,0xe4,0xef,0xe7,0xb1,0x59,0x71,0x4,0x36,0x4c,0xce,0xb2,0x56,0xeb,0x86,0x13,0xae,0x61,0xde,0x61,0x47,0x20,0xac,0xd6,0xc6,0xe0,0xb4,0x61,0xa3,0x87,0x4f,0xdf,0x63,0x72,0xde,0x39,0x59,0x79,0x2e,0x85,0x1c,0x71,0x12,0x2d,0x9d,0xb9,0xff,0x70,0x68,0x9d,0x57,0xe0,0xd6,0x4,0x48,0xf,0x39,0x2c,0x67,0x91,0xf3,0xf9,0xaa,0xf4,0xec,0xb1,0x9c,0x8d,0x70,0xcc,0xe2,0xc8,0xad,0x29,0xa8,0x9c,0xee,0xc5,0x14,0x15,0x96,0x5f,0xaf,0xb5,0x6e,0x38,0xfe,0xe4,0x1e,0xc9,0x39,0xc8,0x71,0x14,0x5e,0xa2,0x16,0x7,0xa2,0x8e,0x80,0x60,0x73,0x70,0x43,0x8e,0x47,0x5e,0xf7,0xf0,0xb8,0x86,0xc4,0xa2,0xa9,0xb7,0xd2,0xa1,0xd5,0xc2,0xce,0xca,0xa6,0x2b,0xd3,0xe,0x9b,0x5d,0x82,0xd3,0xb8,0x47,0x9d,0x3a,0x2c,0x65,0x74,0x66,0x3e,0xc8,0x3,0xe8,0x73,0x3c,0x45,0xae,0x2b,0x7c,0xa4,0xcf,0x97,0x74,0x4,0x8a,0x5b,0x72,0x3,0x72,0x3a,0xb7,0xe1,0x34,0x95,0xbf,0x6e,0x1c,0x7,0xdc,0xc6,0x3a,0xb7,0x6d,0x80,0x98,0x4c,0x26,0x93,0xc9,0x64,0x32,0x5d,0x3e,0x19,0x0,0x34,0x99,0x4c,0x26,0xd3,0x15,0x97,0x2c,0xe6,0x6e,0x50,0x40,0x37,0xc5,0x6,0xc5,0x4d,0x27,0xe0,0xc0,0xcf,0x48,0x80,0x80,0xd,0x80,0x1c,0x47,0x21,0x46,0x5,0x54,0x73,0x37,0xd3,0xb4,0xc6,0x4b,0xa0,0xc1,0x1d,0xea,0x70,0x43,0x3,0xc3,0x38,0x8e,0x1b,0x6e,0x74,0xd8,0x4d,0x92,0xb8,0x72,0xea,0x7a,0xc4,0xd4,0xc1,0x79,0xa7,0xf0,0x25,0xc4,0xb8,0x11,0x67,0xd6,0x8,0x2f,0xa6,0xe3,0x73,0x21,0x20,0x76,0x3d,0x39,0xa7,0x78,0x54,0x84,0x4e,0xd7,0xc1,0x7,0x8f,0x18,0x22,0x2a,0x3,0x44,0x85,0x31,0xa,0x48,0x1c,0x36,0xbc,0x5e,0xa,0x9f,0xea,0x86,0x3b,0x30,0xcc,0x40,0x8b,0x18,0xdc,0x8,0x4c,0xf2,0x6a,0x2f,0x66,0xbd,0x8a,0x98,0x7a,0xf7,0xa4,0x6b,0xd0,0x61,0x8a,0x72,0x36,0x34,0x75,0x63,0x69,0xdc,0x55,0xdb,0xfc,0x18,0xda,0xc8,0xe8,0x9,0xa0,0xbd,0x83,0xe2,0xd0,0x4,0x7f,0x5d,0x88,0x91,0x5d,0x8b,0x8e,0xef,0xd1,0xdc,0x5d,0x58,0xd5,0x91,0xe7,0xfc,0xd4,0xd3,0x38,0x1,0x3d,0x37,0xb9,0xdd,0xf8,0x75,0xe9,0x9f,0x67,0xf1,0x50,0x4c,0xd1,0x61,0xe8,0x5a,0xad,0xb8,0x1e,0xb1,0xd1,0x41,0x27,0xee,0xb5,0xc3,0x63,0x32,0x53,0xcf,0x5d,0xd3,0xa8,0xea,0xe4,0x20,0x75,0xa,0xcc,0xe6,0x50,0x77,0x8a,0xab,0x4e,0xf7,0x7c,0x2,0xb0,0xd3,0x92,0xb4,0x9f,0xc1,0x2d,0x30,0x18,0x9e,0xa6,0x6e,0xda,0xe6,0xfb,0xc8,0x73,0xd,0xcc,0xc6,0x3f,0xa6,0x7b,0xde,0x78,0x38,0xa6,0xd6,0xba,0xf1,0xbe,0xf3,0xb1,0x9c,0x5a,0x8a,0xc2,0x4c,0x79,0x1d,0xf9,0xfe,0x23,0x9d,0x83,0xc,0xb9,0x65,0xdd,0x7a,0x1e,0xd7,0x25,0x97,0x6b,0x3c,0xf2,0x2c,0xcb,0x39,0xc9,0xe7,0xca,0x39,0x2,0xe3,0xd2,0xa3,0xb8,0x71,0xff,0x5b,0x9d,0x5d,0xeb,0x69,0x7d,0x5b,0xae,0xf9,0xfc,0xd9,0x91,0x87,0x56,0x16,0xa6,0xa5,0xf3,0x50,0x7a,0x2f,0x4d,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0x97,0x47,0x6,0x0,0x4d,0x26,0x93,0xc9,0x74,0xc5,0x25,0x2e,0xb5,0xf9,0x9a,0x2a,0x1a,0x18,0x14,0x1,0x53,0x51,0x5d,0xdb,0x88,0x1,0x7a,0x19,0xea,0x50,0x60,0x30,0xc5,0x22,0x27,0xa8,0x34,0xb9,0x8b,0xc8,0xc9,0xc7,0x8b,0xbe,0x21,0xe9,0x60,0x42,0x8,0x4,0xed,0x62,0xea,0xd0,0x5a,0x43,0x1e,0x47,0x84,0xd4,0x6d,0x38,0xa0,0x1a,0x1a,0xfd,0x3e,0xbb,0xf1,0xd6,0x7,0x7,0x98,0x56,0x4c,0xdb,0x66,0xbc,0x76,0x5a,0x7f,0xa0,0xb8,0x65,0x8,0xa,0x96,0x9c,0x73,0xa8,0x39,0x2b,0x84,0x13,0x18,0xc3,0x98,0x12,0xb5,0x11,0x2c,0x2b,0x25,0x6b,0xc7,0x9b,0x80,0x2d,0x2f,0x6b,0xad,0x8e,0x20,0x9a,0x97,0xfe,0xb4,0x59,0xe7,0x9a,0xf,0x53,0x27,0x1b,0xd4,0xc9,0x5,0x5,0x29,0xea,0xac,0x64,0x68,0x26,0xe0,0xcd,0xb3,0x13,0x6c,0xea,0x7b,0xf3,0xda,0xcd,0x6,0x4c,0xb1,0xdf,0x89,0x87,0x6e,0xe,0x55,0xcc,0x5f,0xf,0xec,0xe6,0x23,0x77,0x98,0x63,0xc7,0x62,0x9e,0xdd,0x9b,0xa9,0xbb,0xaf,0xcd,0xfa,0xe4,0xa4,0x2b,0xb0,0x96,0x32,0x8b,0x2a,0x13,0xf8,0x11,0xf0,0x37,0x5f,0x50,0x9e,0xed,0x7b,0x1c,0x72,0xc7,0x91,0x1b,0x93,0xae,0xb7,0x67,0x67,0x61,0x55,0x47,0xdc,0x1c,0x90,0xfa,0x19,0x58,0xd6,0x38,0xb4,0xf7,0x8,0x21,0xaa,0x53,0xb4,0xcd,0x3a,0xfe,0xe6,0x4e,0x3d,0xc7,0x3d,0x7e,0xd3,0x75,0x6e,0xea,0x92,0x53,0xd8,0x3c,0x73,0xad,0x4e,0xae,0xbc,0xb0,0x11,0x57,0xdf,0x70,0xc3,0xf1,0x67,0x40,0x23,0xb6,0x7c,0x6c,0xd2,0x9d,0x8,0xfe,0xac,0x94,0x9c,0xd9,0xe9,0x3a,0x8d,0x92,0x8,0x64,0xa3,0x78,0x2f,0x36,0x9c,0x8d,0xe2,0x36,0x8d,0xa9,0x3,0x40,0x40,0x50,0x3f,0x4b,0xcc,0xf4,0x6a,0x25,0xf7,0x9e,0x9c,0x37,0xb9,0x6a,0xa9,0xd7,0x52,0xba,0x0,0x2b,0x3f,0xff,0x32,0xc2,0x43,0xcf,0x86,0x3f,0xb4,0x80,0x3c,0x39,0x2,0x37,0x7,0x4a,0xa6,0x85,0x68,0x8a,0x15,0x4f,0x31,0xe0,0x69,0x10,0xc6,0x63,0x3e,0x1b,0x33,0xff,0x1c,0xc9,0x33,0x66,0x32,0x99,0x4c,0x26,0x93,0xc9,0x64,0xfa,0xd1,0x65,0x0,0xd0,0x64,0x32,0x99,0x4c,0x57,0x5c,0xd,0x9b,0x3,0x7,0x2,0x33,0xc4,0x81,0xe5,0xfd,0xf4,0x1f,0xfe,0x13,0x20,0x6c,0xc,0xd7,0xa2,0x3a,0xce,0xe6,0xc0,0xc1,0x87,0xc8,0x7d,0x75,0x1e,0x91,0xa3,0xbc,0x4,0x10,0xa6,0x71,0x8c,0x98,0x7a,0xea,0x17,0xe4,0xe,0xbe,0xd6,0x8,0xf2,0xc5,0x48,0x23,0x19,0x21,0x24,0x78,0xe7,0x10,0xbb,0x1e,0xc1,0x47,0x94,0x3c,0x22,0xc4,0xc4,0x1d,0x6a,0x1,0x25,0x13,0xa8,0x8a,0x31,0x22,0x8,0xd4,0x69,0x34,0x7c,0xe1,0xb9,0xc7,0xad,0x56,0x8a,0xfb,0x7a,0x1f,0x10,0x63,0x87,0x5a,0x8a,0x3a,0x15,0x5,0x96,0xc8,0xb1,0x83,0xdd,0x8d,0x6d,0x8b,0xeb,0xd0,0x6d,0xc,0x2b,0x34,0xd4,0x52,0xf9,0xb5,0xc5,0xfd,0xe7,0xa7,0xfe,0x3b,0x8e,0xdd,0x4e,0xe,0x2f,0xa7,0xe7,0x27,0xce,0x42,0x81,0x6d,0xd2,0xb3,0x27,0x31,0xd3,0xf9,0x7b,0xcc,0xd7,0x89,0x31,0x5f,0x6,0xe6,0xbb,0xe6,0x39,0x82,0x3b,0x45,0xae,0xe7,0x2e,0x4b,0x89,0x9f,0x4a,0xff,0x1d,0x9d,0x67,0x6d,0xf3,0x63,0xe6,0xbb,0x3f,0x87,0x8a,0x4d,0xdc,0x8f,0x75,0xe6,0x4c,0x63,0xb0,0xab,0x91,0x50,0x89,0xd6,0x36,0x5d,0xb1,0x3d,0x3c,0xc2,0xa1,0x91,0x61,0x7e,0x8f,0xc0,0x5d,0x8b,0xa5,0x64,0x8d,0xd7,0xd2,0xb9,0xce,0x6,0x48,0x66,0xf7,0xa1,0xd6,0x42,0x5f,0x57,0x67,0x3,0x2a,0xb3,0x18,0xab,0xc0,0xac,0xe9,0x75,0x26,0x37,0x9b,0x38,0x23,0xb5,0xdf,0xf0,0x10,0xe4,0x13,0xf8,0xe5,0x7d,0x50,0x18,0x29,0x60,0x4c,0x62,0xd1,0x53,0x37,0x22,0x14,0x78,0xba,0x43,0xcf,0x46,0x9d,0xf5,0x22,0x16,0x1,0x84,0xc0,0x86,0xd3,0x4e,0x1,0x6f,0xf0,0x1b,0x63,0x36,0x8e,0x41,0x5b,0x19,0x47,0x5d,0x64,0x26,0x78,0x2b,0xf1,0x73,0x8f,0x79,0x1f,0xa4,0x3a,0x3e,0x9d,0x53,0x57,0xa3,0x9b,0x2f,0x5,0xcf,0xe2,0xc6,0xd3,0xf9,0x87,0xc9,0xc5,0x89,0xcd,0xe1,0x9a,0xc3,0xd1,0xeb,0xa3,0x4e,0x45,0x6c,0x2c,0x48,0xd3,0x7a,0xb5,0x39,0x0,0x4d,0x26,0x93,0xc9,0x64,0x32,0x99,0x2e,0x97,0xc,0x0,0x9a,0x4c,0x26,0x93,0xe9,0x8a,0x4b,0x5d,0x55,0xfc,0xdf,0xf7,0xa5,0x64,0x85,0x56,0x2,0x63,0xda,0x6c,0x51,0x55,0x62,0x91,0x95,0x7,0xa,0x4,0x2a,0x60,0x16,0x33,0x84,0xac,0x8d,0xce,0x6,0x45,0xbc,0xf7,0x48,0x5d,0xaf,0xae,0x3e,0x81,0x70,0xde,0x7,0xa4,0xd4,0xa9,0x33,0x29,0x76,0x3d,0x42,0x88,0xf0,0x81,0x1d,0x77,0xad,0xc1,0xc7,0x80,0xd4,0x2f,0x50,0xd5,0xb9,0xd4,0xf8,0xb5,0xe8,0xb0,0xb,0xc7,0x20,0x63,0xea,0x8,0x36,0x35,0x72,0xcd,0x91,0x8b,0xaf,0x22,0x76,0x1d,0x6a,0x2d,0x1a,0x85,0x15,0x96,0x21,0xfd,0x7a,0x73,0x8,0x28,0x6e,0x3f,0x1,0x2b,0xe0,0xe8,0xae,0x5e,0x3,0x4c,0xab,0xa8,0x4,0x91,0xa2,0xe,0x80,0x48,0x9c,0x59,0xae,0xa7,0xf3,0x4e,0x47,0x28,0x24,0x2e,0x3d,0xd,0x5d,0xc8,0xb5,0x9d,0x22,0xa7,0xf3,0x75,0xdf,0x8d,0x3e,0x36,0x75,0xba,0x79,0x1d,0xae,0x28,0xa5,0xb0,0x93,0x91,0x63,0xaa,0x12,0x65,0xd5,0x31,0x12,0x4c,0xdd,0x71,0x68,0xa8,0x75,0x6,0xa4,0x34,0xb2,0xea,0x67,0x10,0x89,0xfe,0x4f,0xd1,0xe8,0x6d,0xd3,0xf3,0x14,0x48,0x56,0xf9,0xd9,0x90,0xd8,0x32,0x39,0x2e,0xf,0x1d,0x3f,0xa6,0x18,0xae,0x44,0x5a,0xeb,0x6c,0xe9,0x56,0x6,0x29,0xa6,0x28,0xac,0x9f,0x3d,0x87,0x14,0x5,0x27,0xd1,0x79,0x87,0x98,0x10,0x19,0xfc,0x92,0xb8,0x17,0x4f,0x86,0x5a,0x4,0x6e,0x32,0x24,0xa4,0x95,0xe5,0x9,0xa4,0x4a,0x9c,0x5d,0x62,0xcd,0x74,0xaf,0x81,0x92,0xc7,0x8d,0x5,0x64,0x89,0x45,0xcf,0x87,0x53,0xa6,0xbe,0xcb,0xf9,0x2a,0x34,0x36,0xbe,0x4e,0x3e,0x38,0x1b,0xdd,0x7d,0x98,0x9e,0xaf,0xd6,0x1a,0x6a,0x2e,0xec,0xb6,0xc,0xfc,0xb9,0x0,0x9d,0x93,0x80,0xe2,0xc9,0xd0,0xc7,0x60,0x17,0xfa,0xc,0xb,0x7c,0xe,0x21,0x52,0xcc,0x5d,0xe2,0xda,0xce,0x21,0xc4,0x4e,0xc7,0x6a,0xe0,0xbc,0x3e,0x8b,0x75,0xd6,0xff,0x87,0xd9,0xf3,0x85,0x59,0xc4,0xd8,0xcd,0x87,0x75,0x20,0xd7,0x27,0x6c,0xba,0xff,0x38,0xde,0x4e,0x7f,0x5b,0xec,0x87,0xa5,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0x65,0x92,0x1,0x40,0x93,0xc9,0x64,0x32,0x5d,0x71,0x4d,0xbd,0x6f,0x98,0x40,0x6,0x7b,0x8e,0x18,0xe5,0x10,0xcc,0xe0,0x48,0xae,0x9b,0x8d,0x43,0x8,0x70,0x60,0x12,0xc3,0xce,0x3f,0xea,0x92,0xf3,0x21,0x4e,0x4b,0xa4,0xb3,0x88,0x21,0x81,0x8c,0xa4,0xae,0x2b,0xf9,0xfd,0x18,0x13,0x7d,0x9d,0x40,0xc3,0x59,0xaf,0x9a,0xc4,0x84,0x53,0xd7,0xc3,0x39,0x87,0x94,0x7a,0x8d,0x19,0xa7,0xd4,0x21,0xc6,0x4e,0xdd,0x84,0x39,0x8f,0xea,0xb8,0xf2,0x9e,0x3a,0xff,0x4a,0x99,0xc6,0x3e,0x9a,0xc6,0x51,0xa7,0xde,0x3b,0xe9,0x1f,0x74,0xce,0xf3,0x8,0xc9,0xac,0x1b,0x8d,0x9d,0x6e,0xb3,0x75,0x8e,0x69,0x24,0x41,0x3a,0xf8,0x18,0x72,0x49,0xac,0x58,0xde,0x4b,0xce,0x79,0x8a,0xd9,0x8a,0xab,0x8b,0x40,0x9b,0xf7,0x81,0x97,0x56,0xab,0x76,0x23,0x8a,0xd3,0x4e,0x3a,0xf1,0xa8,0x53,0x2e,0x4f,0xa3,0x11,0x3c,0xb2,0x11,0x62,0x9c,0x8d,0x60,0xd4,0x8d,0x35,0x5f,0x5,0x4f,0xe2,0x6c,0x6b,0x8d,0x1c,0x91,0xec,0x80,0xa4,0x88,0xf0,0xac,0xc3,0xce,0xcf,0xff,0x8,0x42,0x3d,0x82,0x72,0x5c,0x74,0x8f,0xc5,0xd1,0xe7,0x39,0x4e,0x5c,0xa6,0x88,0x36,0xaf,0xd2,0x4a,0x64,0x3a,0xa6,0xb4,0xb1,0xe,0xad,0xa0,0x4f,0xdc,0x82,0x98,0xd6,0x9f,0xa7,0x88,0xaa,0xc4,0x6d,0xe7,0xcf,0xa5,0xf4,0x33,0x6e,0xf6,0xd3,0x69,0x94,0xbb,0x64,0x8d,0x67,0xd3,0xfd,0x9d,0x46,0x53,0x9c,0x9b,0xf7,0xdb,0x39,0x1d,0x2b,0x99,0xdc,0x83,0x4d,0xe3,0xdc,0x73,0x48,0x56,0x6b,0x41,0x48,0x49,0x6f,0xb5,0xae,0x2c,0xfb,0xc9,0x9d,0x29,0x70,0x5c,0x9f,0x1f,0x71,0x72,0xce,0xe2,0xcc,0xf3,0xe1,0x1b,0x2,0x7d,0x3c,0xf4,0xd2,0xaa,0x46,0x84,0xa9,0x6b,0x32,0xb0,0xe3,0x90,0x8e,0xa5,0xca,0x5a,0xb3,0x44,0xb3,0xb9,0x4b,0x70,0x5a,0xe2,0xe6,0x85,0x69,0x8e,0x9f,0x87,0x10,0xa8,0x23,0xd0,0x7b,0xd4,0x3a,0xc5,0xd6,0x53,0xea,0xb4,0xbb,0x70,0x72,0xf8,0xf2,0xb3,0xc3,0xa0,0x74,0xea,0x58,0x74,0x1b,0xcf,0xce,0x7c,0x50,0x46,0x9e,0x47,0x5,0xfa,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0xa6,0xcb,0xa2,0x68,0x97,0xc0,0x64,0x32,0x99,0x4c,0x57,0x5a,0x2,0xd7,0x36,0xe4,0x1c,0xdc,0x6c,0xf5,0x16,0x75,0x8a,0x95,0xc2,0x87,0x8d,0x8,0x6b,0x6b,0x15,0x31,0x76,0x28,0x65,0xd4,0xf8,0xa8,0xf7,0x71,0x73,0xa9,0xd5,0x39,0x1d,0xd8,0x48,0x5d,0x4f,0xa0,0x25,0x4c,0xff,0xda,0x2b,0x25,0x23,0xf8,0x88,0xae,0x5f,0x68,0x5f,0x1c,0x30,0xb9,0xa1,0x6a,0xad,0x88,0x31,0x61,0x1c,0xd6,0x34,0xb4,0x11,0x9,0x20,0xe5,0x3c,0x2a,0xfc,0x11,0xf7,0x97,0x38,0xc0,0xf2,0x38,0xc2,0x79,0x87,0x3c,0x8e,0xfc,0x9e,0x55,0x1d,0x5f,0xce,0xb,0x8,0x24,0x47,0x5d,0xec,0x7a,0x78,0xe7,0x31,0xc,0x2b,0x84,0x10,0x35,0xa,0x29,0x4e,0xb5,0x10,0xd3,0x14,0x43,0xe5,0xf3,0x6f,0xb3,0x3e,0xbf,0x92,0x47,0x76,0x6b,0x1,0x5e,0xbe,0x9f,0x57,0x94,0xb5,0x1b,0x2e,0xd0,0xda,0xb2,0xe3,0x68,0xae,0xc,0x5a,0xc8,0xf5,0x96,0xbe,0x3d,0xe9,0xa5,0xf3,0xde,0xa3,0xd4,0x79,0x14,0x78,0x72,0x59,0x52,0x2c,0x19,0x68,0xce,0x4d,0x1d,0x7d,0x20,0x67,0x1f,0x41,0xc8,0x40,0x8e,0x2d,0x86,0x80,0x21,0x26,0x8e,0xb2,0x2,0x79,0x1c,0x38,0x8e,0x3d,0x2d,0xd4,0xd2,0xf5,0x68,0xda,0x1b,0x48,0x70,0x88,0x17,0x72,0x51,0x27,0x77,0x23,0x66,0xc0,0x88,0xb9,0x2f,0x2d,0x22,0x63,0x3,0x5a,0xcd,0x63,0xe5,0x21,0x44,0x20,0x60,0x5a,0x39,0x66,0x90,0x55,0x8a,0x38,0x13,0xb,0x64,0x20,0x44,0x3a,0xf8,0x14,0x3c,0x79,0x68,0x64,0x37,0xc6,0xc4,0x51,0xdb,0xba,0x11,0xc9,0x9d,0x3,0x37,0x71,0x19,0xca,0x33,0x24,0x70,0xba,0xd6,0xa,0x1f,0x22,0x75,0xf7,0xc5,0xc4,0x60,0xd,0x1b,0x3d,0x8e,0x4,0x2c,0xbd,0x46,0xbb,0x7d,0x8,0xa,0xbd,0xbc,0x23,0x87,0x9d,0x7,0xb4,0xd3,0xb1,0xb5,0x69,0x7d,0xb9,0xe9,0xbd,0x2e,0xa8,0xec,0x6a,0x94,0xf7,0xc9,0x79,0xd4,0xb8,0xb1,0x7e,0xbc,0x40,0xb0,0xaf,0x94,0x82,0xc8,0x5f,0x57,0x4a,0x46,0xd7,0x2f,0x14,0x46,0xc7,0x44,0xae,0xd5,0x92,0x33,0xa,0xc3,0xee,0x6,0xb0,0x73,0x56,0x42,0xc1,0x4d,0x41,0xfa,0x7c,0xb8,0x46,0x7b,0x3c,0x65,0x7d,0x98,0x5d,0xad,0xad,0xd2,0xf3,0xda,0x2a,0xc7,0xb2,0xf5,0x33,0xea,0xf5,0x3c,0xc0,0xcf,0x14,0x1c,0x50,0xf9,0x1e,0x29,0xdc,0x37,0x99,0x4c,0x26,0x93,0xc9,0x64,0x32,0x5d,0x16,0xd9,0x9f,0xac,0x4c,0x26,0x93,0xc9,0x74,0xc5,0x45,0x43,0x1e,0xfc,0xf,0x12,0xe3,0x65,0xbc,0xe0,0xbd,0xf4,0x96,0x79,0x75,0x2,0xe6,0x3c,0x28,0x90,0x1,0x28,0x8a,0x49,0xa3,0x19,0x91,0xc7,0x1f,0x80,0x36,0x1b,0xb3,0xf0,0xda,0xb3,0x36,0x2d,0x9f,0xce,0x7,0x1e,0x5a,0xab,0xe8,0xba,0xc5,0x14,0x15,0x6,0x41,0xb4,0x0,0x30,0x80,0x21,0x47,0x93,0x38,0xe6,0x4,0xc6,0xf9,0x10,0xd1,0x47,0x82,0x3a,0x12,0x47,0x96,0x51,0x88,0x5a,0x33,0x62,0x47,0xa3,0x21,0x5d,0x1f,0x26,0x0,0x57,0xb,0x1a,0xc7,0x97,0x43,0x88,0x1c,0xa3,0x9d,0xae,0x43,0xe0,0xd7,0x13,0x98,0x12,0x7b,0x7a,0x8d,0x5a,0xb,0x52,0xb7,0x40,0xc9,0xa3,0x2,0xa8,0xd6,0xca,0xc6,0x60,0x84,0xe7,0xf8,0xac,0xf,0x6d,0x8a,0xde,0x4a,0xdf,0x9b,0x44,0x5e,0xc5,0x85,0xd6,0x8,0x7a,0xe5,0x3c,0x4c,0xf0,0x85,0x9d,0x69,0x21,0x26,0x8e,0x5b,0x3a,0x5,0xaa,0x53,0x6f,0xa0,0xd3,0xeb,0x4c,0xce,0x3c,0xe8,0xb1,0x8a,0xd7,0x6b,0x1e,0x95,0x75,0xde,0xc1,0x91,0xdd,0x4f,0x9d,0x66,0x5e,0x46,0x51,0x4,0x3a,0x2,0x70,0xf0,0xc,0x1,0xa9,0x57,0xd1,0xf1,0x8,0x8c,0xae,0xd9,0x96,0xac,0xe3,0x19,0xce,0x11,0x30,0x94,0xb1,0x10,0xef,0xe3,0xe4,0x6e,0x64,0xa0,0x56,0xb,0x1,0xde,0x2a,0xc7,0x2e,0xab,0xc6,0x1c,0x5f,0xa6,0x98,0xac,0x53,0xd8,0xea,0xbc,0xd3,0xdf,0x9f,0x3,0x52,0xb1,0xe7,0xf9,0x10,0xd8,0xcd,0x8,0x75,0xc3,0x39,0x86,0xca,0x6a,0xe1,0x63,0x70,0x29,0x70,0x99,0xc0,0x9b,0xdf,0x88,0x52,0xfb,0x48,0xef,0xe7,0xf9,0xdc,0x7c,0x8,0x34,0xec,0x1,0x8a,0x91,0xab,0xab,0x6f,0xf6,0xfd,0xd2,0xc1,0x38,0xef,0xca,0x9b,0xdc,0x7f,0x41,0x5d,0x92,0x85,0xaf,0x95,0x8c,0xce,0xc8,0xc8,0xc7,0x14,0xf1,0xf5,0x1b,0xbf,0x16,0x2,0xc5,0xa1,0xe5,0xf3,0x95,0xba,0x7e,0x82,0xca,0xde,0x63,0x1c,0xd6,0xe4,0x94,0x9c,0x45,0x75,0xe9,0xfe,0x4d,0x31,0xf0,0x56,0x8a,0x1e,0xe3,0xdc,0x95,0xab,0xb,0xd3,0xad,0xc2,0xbb,0x30,0x8d,0x98,0x40,0x46,0x43,0xa6,0xc1,0x14,0x17,0x2,0x3d,0x97,0xb3,0x18,0xb9,0x8c,0xe2,0x4c,0x9f,0xd1,0x79,0xff,0xa4,0xc9,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0x47,0x95,0x1,0x40,0x93,0xc9,0x64,0x32,0x5d,0x71,0xb5,0x2a,0xa3,0xc,0xbc,0x5c,0x8b,0xa9,0x17,0x4e,0x1c,0x55,0xd,0x80,0xb,0x1,0x39,0x8f,0x70,0x70,0x1b,0xf1,0xd3,0xca,0xf0,0xf,0xc0,0xe6,0x52,0xa8,0x76,0xc7,0x4d,0xee,0x2d,0xa0,0x2a,0xa4,0x3,0x80,0x20,0x83,0x23,0xc,0x4c,0x62,0x4a,0x68,0xb2,0x80,0xb,0xea,0xf4,0x13,0xa8,0xe3,0xbd,0x87,0x93,0x81,0x90,0x18,0x31,0xae,0x57,0xc,0x4,0x23,0xc0,0xae,0xb3,0x94,0x28,0x22,0x3c,0xe,0xeb,0x69,0xd5,0x97,0x81,0x51,0x1e,0x7,0x85,0x71,0x12,0xb9,0x24,0x17,0x58,0x98,0xf5,0xe8,0x49,0xb7,0x5a,0xd4,0x2e,0xba,0x69,0x49,0xb6,0x4c,0x23,0x9,0x98,0x8d,0x57,0xb0,0x3b,0x4c,0xc6,0x23,0x74,0x3c,0x85,0xfb,0xb,0x65,0x1c,0x43,0xe2,0xc1,0xf2,0xba,0x31,0x6,0x85,0x2b,0xce,0x79,0xd4,0x56,0x74,0xe4,0xa4,0xd4,0xa,0xef,0x79,0x9c,0x82,0x8f,0xa9,0xb1,0xb3,0x4f,0x1c,0x62,0xb4,0xba,0xdc,0x78,0x2d,0x18,0x7a,0xcc,0xf3,0xf5,0x62,0xef,0x2,0xc7,0x43,0x8b,0xba,0x0,0x15,0x4c,0xc2,0xa1,0xc9,0xf2,0x33,0xff,0xfa,0x4,0x50,0x8b,0xde,0x6b,0x71,0x20,0xa,0xfe,0xa9,0xa5,0xc0,0xb5,0x69,0x24,0xa3,0x30,0x84,0xa2,0xe7,0x85,0xae,0x8b,0x38,0x14,0x1d,0xc7,0x80,0xc9,0x4d,0x97,0x37,0x7a,0x0,0x5,0x16,0xcf,0xe3,0xc6,0x12,0x1b,0xa6,0xb5,0xe8,0xa6,0xf7,0x43,0x6,0x29,0xe6,0xc3,0x1c,0x4,0xe3,0xea,0xb4,0x5e,0x5d,0x9,0x9e,0x96,0x92,0x91,0xf3,0x48,0xce,0x3a,0x7e,0x6f,0x7,0x90,0x33,0x8f,0x8a,0x1b,0xe9,0x18,0x67,0xeb,0xd0,0x72,0x1f,0xa5,0x87,0x52,0xa0,0xb5,0xac,0x21,0xb,0xa8,0xf4,0x21,0xa8,0xab,0xb3,0x32,0x2c,0x95,0xcf,0x89,0xc4,0x79,0x5,0xae,0x3a,0xe7,0xe0,0xda,0xe6,0xa,0xaf,0xfc,0x55,0xa0,0x61,0x63,0x67,0xa2,0x3,0xd4,0x75,0x18,0x13,0xaf,0x62,0xc7,0x88,0x5a,0x28,0x26,0x5c,0x4a,0x51,0x30,0x4c,0xc3,0x37,0x74,0x8f,0xc5,0x79,0x4a,0xf1,0x70,0x28,0xe8,0xd3,0x6b,0xc6,0xae,0xd1,0x10,0x13,0x3d,0xff,0xfc,0x1c,0xc9,0xf9,0xea,0xd8,0x8f,0x1e,0xdf,0xec,0x7b,0x37,0x7e,0x48,0xb4,0xc9,0xe9,0x69,0x32,0x99,0x4c,0x26,0x93,0xc9,0x64,0xfa,0x91,0x65,0x1d,0x80,0x26,0x93,0xc9,0x64,0xba,0xe2,0x12,0x58,0x23,0xda,0xe8,0x64,0x3,0x26,0x18,0x2,0x87,0x18,0x3b,0x85,0x77,0x6d,0xf6,0xfd,0xe4,0x6,0xc4,0xe4,0xcc,0x4a,0x1d,0x75,0xfa,0xf1,0xe2,0x2e,0x45,0x5f,0x1d,0x52,0xd7,0x23,0x76,0xfd,0xf4,0x5e,0xc,0x63,0x52,0xd7,0x23,0xf5,0xb,0x72,0x94,0xc5,0xa8,0xdf,0xeb,0xd9,0x25,0x15,0x53,0x87,0x90,0x12,0xc8,0x35,0x47,0x91,0xca,0x7e,0x67,0x17,0x21,0x46,0x78,0xcf,0x5f,0xcf,0xae,0xac,0x3c,0xe,0x80,0xa3,0xe3,0x12,0xa7,0x61,0xc9,0xa3,0xf6,0xce,0x11,0x70,0x71,0xec,0xf4,0xa3,0x3e,0x36,0xcf,0xb1,0x61,0xcf,0xc7,0x7e,0x18,0x80,0xf8,0x59,0x2f,0x9b,0x1c,0xb3,0x80,0x1a,0x87,0x69,0xd4,0xc4,0x79,0x4f,0x1d,0x72,0xd2,0x99,0xc6,0x30,0xc5,0x6b,0x6c,0x9a,0x16,0x8c,0x5,0xd2,0xa9,0x43,0xb0,0x4d,0x4b,0xba,0xa,0xcc,0x6a,0x81,0x67,0x7,0x25,0x45,0x73,0x3d,0x83,0xa3,0xc0,0x80,0x94,0x62,0x9a,0x2,0x8,0xe5,0x5e,0x48,0x67,0x20,0x81,0xdb,0x36,0x8d,0x8c,0xcc,0xdc,0x65,0x72,0xed,0x3d,0x3b,0x3b,0x65,0xf8,0x25,0xe7,0x91,0xdd,0x7c,0x14,0x19,0x2d,0x25,0x53,0xf7,0x23,0x3f,0x17,0x8d,0x87,0x41,0xa8,0x7,0xf,0xa,0xed,0xe6,0x63,0x1a,0xf3,0x38,0xa9,0xe7,0x4e,0x45,0x1,0x57,0xd2,0x73,0x47,0xc0,0x2a,0x30,0xc4,0x2c,0xba,0x16,0x2c,0xeb,0xb5,0x85,0x1d,0x69,0x65,0x6,0x97,0x5b,0xab,0x53,0xb7,0x21,0x3b,0x38,0xbd,0xf7,0x1b,0x23,0x19,0x25,0x8f,0x1c,0x3,0x9f,0x62,0xea,0xe2,0x3a,0x94,0xe7,0x53,0x62,0xcb,0xb5,0x4e,0x3,0x17,0xe2,0x70,0x9d,0x20,0x24,0x1,0x47,0x81,0x81,0xe4,0xac,0xe4,0xe8,0xae,0xc2,0xca,0x30,0xad,0x5,0x33,0x20,0xf5,0xb3,0xbe,0xc3,0x5a,0xa6,0xb1,0x9c,0x6,0xe9,0x3d,0xc,0xfa,0x5c,0xcb,0xf3,0x82,0xa6,0x77,0x53,0x1d,0xa5,0x2,0x12,0xe9,0xb3,0xd3,0x18,0xb8,0xcf,0x87,0x4f,0xe8,0x9e,0x4b,0x27,0x66,0x88,0x91,0x87,0x73,0xe2,0xac,0xdb,0xd2,0xeb,0xf1,0x88,0xb3,0x72,0xde,0xf3,0x27,0x51,0xe1,0xf9,0xba,0xb2,0xb8,0x3c,0x43,0x4a,0xb3,0x42,0xc6,0x69,0x30,0xc6,0x64,0x32,0x99,0x4c,0x26,0x93,0xc9,0x74,0x79,0x64,0x7f,0xb2,0x32,0x99,0x4c,0x26,0xd3,0x8f,0x45,0xf3,0xce,0x36,0x19,0x9c,0xf0,0x9e,0x62,0x97,0xd2,0xa7,0x56,0x18,0xe,0x1d,0x1e,0xb7,0xa0,0xef,0x29,0x88,0x89,0x86,0x38,0x8,0xba,0x11,0x40,0x49,0xdd,0x82,0x1c,0x83,0x3c,0x24,0x21,0x80,0x2a,0xc6,0x44,0xf0,0x2,0x4e,0x9d,0x69,0x12,0xef,0x15,0x20,0x11,0x42,0xe2,0x28,0x69,0x40,0x4c,0x1d,0xf7,0x97,0x79,0xf4,0x8b,0x1d,0xea,0x85,0xab,0x8d,0xe1,0x10,0x1d,0x7b,0xd7,0x2d,0x78,0x45,0xb8,0x53,0x90,0x12,0x79,0xc,0xc1,0x7,0x1a,0x63,0x10,0x30,0x29,0x50,0xa5,0x94,0x51,0xe1,0x50,0x88,0x11,0x3e,0x4e,0x66,0x7c,0x1d,0xb3,0x60,0x8,0x39,0xc5,0x73,0x2b,0xba,0xc5,0x52,0x57,0x5d,0xdd,0xcc,0xd1,0x48,0x8b,0xaf,0x99,0xa1,0x62,0xd0,0xa1,0xc,0x71,0xbe,0x1,0x33,0x40,0x46,0x53,0xb5,0x3a,0x80,0xe2,0xbc,0xa7,0x85,0x57,0x38,0x5,0x45,0xf3,0xf1,0xa,0x59,0x1d,0x6,0x68,0x41,0x96,0x80,0xa5,0x9f,0xee,0xa0,0xb8,0xd9,0x38,0x6e,0x1a,0x2,0x81,0x51,0x19,0xec,0x90,0xe3,0xf4,0x31,0x2a,0x10,0x4,0xa0,0xeb,0xc8,0xde,0x79,0x86,0x9f,0xd0,0xf7,0xa7,0x55,0xe5,0xc8,0xa0,0x70,0x6,0x1b,0x1b,0xa6,0xef,0x67,0x28,0x29,0xef,0x3b,0xb9,0x24,0x9,0x32,0xe5,0x3c,0x2,0x3c,0x0,0xe2,0x79,0xa1,0x58,0xa1,0x14,0x8,0xbe,0xa,0x7c,0x12,0x7,0x1b,0x5d,0xe7,0x36,0xeb,0x89,0x74,0xd3,0xe0,0x6,0x3b,0x50,0xab,0x8e,0xc8,0xf0,0x18,0xd,0x43,0xaa,0x3c,0xe,0x82,0xf5,0x36,0x46,0x3a,0x3c,0x83,0x32,0x81,0x77,0x2,0x64,0xc1,0xae,0xbf,0xc6,0x5d,0x78,0x14,0x8d,0xa5,0xe3,0xf7,0xc,0xdc,0xd4,0xe5,0x2a,0xce,0xce,0xf9,0x22,0xb6,0x73,0x1c,0xd9,0x9e,0xba,0x18,0xd5,0xd5,0x59,0xca,0xcc,0x1,0x58,0x74,0x34,0xa6,0x71,0x1f,0x25,0xc1,0xde,0xa8,0x9d,0x8f,0xe3,0xb0,0x86,0xae,0x1c,0xf3,0x31,0x8b,0xcb,0xd5,0xcb,0x58,0xf,0xaf,0x1a,0xcb,0xe7,0x2d,0x32,0x70,0x96,0x6e,0xc5,0x79,0x7,0xa0,0x8c,0xe9,0x80,0x3b,0x2,0x3d,0x3,0xd6,0x69,0x94,0x27,0x6c,0xfc,0x1c,0xa8,0x7c,0x4f,0x28,0xc2,0x5c,0x36,0x46,0x5a,0xe6,0x43,0x41,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0xa6,0x1f,0x4d,0x16,0x1,0x36,0x99,0x4c,0x26,0xd3,0x8f,0x55,0xb4,0x6c,0x3b,0xc1,0x21,0x1,0x3e,0x2,0x40,0x36,0x56,0x4b,0x5b,0x83,0x63,0x78,0xe1,0xd4,0xe9,0xe6,0x15,0x36,0xc4,0x94,0x74,0x60,0x3,0xad,0x21,0xf1,0xd0,0x6,0xa2,0xe7,0xee,0x38,0x76,0x4e,0xcd,0xdc,0x63,0xe4,0x26,0x23,0x48,0xe2,0xbd,0x87,0x4b,0x9d,0x82,0x1a,0xe9,0x48,0xa3,0x78,0x28,0xc5,0x83,0x4b,0x1e,0xe1,0x7d,0x7,0xc7,0x6e,0xb5,0xce,0x2f,0x68,0x5,0xb5,0x5b,0xa8,0xe3,0x4d,0x80,0x52,0x2d,0x19,0x31,0x4,0xd,0xef,0x4a,0x2f,0xa0,0xf6,0xc5,0x85,0x88,0x61,0x75,0x40,0xb0,0x51,0x3a,0xd4,0xb8,0x17,0x4e,0xc6,0x3e,0x9c,0xa7,0xae,0x36,0x81,0x38,0xd2,0x65,0x27,0xe7,0xa0,0x71,0xcd,0x10,0x91,0x73,0xd6,0xa1,0x5,0x7,0x37,0xf5,0xae,0x1,0x33,0x0,0x45,0x91,0x60,0x19,0xbd,0xa0,0x1e,0xc2,0xa4,0x91,0x5d,0xe9,0x40,0x14,0x48,0x24,0x10,0x49,0x1c,0x5d,0xf3,0xd8,0xae,0x38,0xff,0x9c,0xf,0x80,0xe7,0x81,0x8,0x86,0xa4,0x34,0x40,0x41,0x2e,0xce,0x3c,0xac,0x35,0x76,0xab,0x8e,0x48,0x6,0x8d,0x12,0xed,0xd6,0x28,0x6f,0x8,0x3a,0xa6,0x42,0x11,0x66,0x1e,0x88,0x90,0xa7,0xc3,0x3b,0x1d,0x8,0x11,0x27,0x1f,0xc1,0xda,0x8a,0x8a,0xf9,0xf8,0x9,0xfd,0x55,0xc6,0x37,0xe6,0x8e,0x47,0x87,0xa9,0x27,0x2f,0xf8,0x88,0x61,0xbd,0x9a,0xee,0xc1,0xc6,0xd0,0xc7,0x14,0xbd,0x25,0x50,0xdc,0xd4,0x86,0x2a,0xc3,0x26,0xce,0x7b,0x24,0xee,0xf7,0x13,0x37,0x25,0xd4,0xd0,0xea,0x15,0x34,0x7b,0xef,0x41,0x6,0x4d,0x87,0x5a,0xa6,0x51,0x91,0xc9,0xc9,0xb8,0x19,0xb,0x16,0xf0,0x2b,0x20,0x3c,0xc4,0x84,0x32,0x8e,0xec,0x88,0xe4,0xe,0xc6,0xda,0x50,0xdb,0x4,0xcd,0x9c,0x9f,0xe2,0xef,0x39,0x8f,0x87,0x5c,0x9a,0x34,0xd0,0x92,0x52,0x8f,0x71,0x1c,0xf8,0xb9,0xc9,0xba,0x90,0x4d,0x11,0x6d,0xf0,0x70,0xc9,0x48,0xf7,0x2a,0x26,0x4,0x1,0xbe,0xea,0xd2,0xa5,0x7b,0x1c,0x62,0xe2,0xe3,0x9a,0xba,0xb,0x1b,0x68,0x8,0x47,0x9d,0xa0,0x3c,0x8,0x43,0x6e,0x52,0xba,0x7f,0xa5,0x64,0x8a,0x4a,0xb,0xc8,0x9c,0xdd,0x97,0xa9,0xb3,0x51,0x86,0x4e,0xec,0xe7,0xa3,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xe5,0x92,0x39,0x0,0x4d,0x26,0x93,0xc9,0x74,0xc5,0xa5,0x8e,0x2e,0x8,0x53,0x68,0xa,0x99,0x1a,0x3b,0xcb,0x22,0x77,0xeb,0x91,0xf1,0x4b,0xc6,0x4,0x2,0x83,0x92,0x69,0x80,0x42,0x1c,0x46,0xe4,0x98,0x63,0x27,0x99,0xf,0x48,0x5d,0xaf,0x2e,0xad,0xd4,0x2d,0x26,0x67,0x1e,0x47,0x6a,0x63,0xea,0x28,0x52,0x2b,0x8b,0xc1,0xfc,0xf5,0x61,0xe6,0x28,0x94,0xaf,0x69,0xb5,0xa9,0x3b,0x4f,0xbe,0x56,0x80,0xd5,0x14,0xcb,0xa4,0x63,0x95,0xef,0x27,0x47,0x1b,0xf,0x35,0x0,0x58,0x2c,0x77,0xd4,0x11,0xd8,0x5a,0x43,0xd7,0x2f,0xf8,0x3c,0xc9,0x3d,0x18,0x39,0x3e,0xdc,0xf7,0x3b,0xda,0xe1,0x27,0x9d,0x6d,0xb4,0x4a,0x5b,0xf5,0x78,0xd5,0x69,0xe8,0x8,0x9e,0xa,0x4c,0xf3,0xb2,0xcc,0xeb,0x3d,0xbb,0xd5,0x66,0x6e,0xbd,0x26,0xcb,0xb3,0xe4,0xee,0x9a,0x3a,0x8,0xc1,0xa3,0x10,0xe,0x95,0xc7,0x48,0x9c,0x8e,0x6f,0x88,0xdb,0x32,0xab,0x63,0x4e,0x4d,0x59,0xc,0x28,0x43,0x4c,0x1c,0x8b,0x85,0x3a,0x2,0x9d,0x73,0x18,0xc7,0x1,0xb5,0x64,0x5,0x54,0xe2,0x0,0x93,0x5b,0x3e,0x5f,0x91,0x45,0x9b,0xd6,0x88,0xb,0x3,0x3b,0x89,0x97,0x6e,0xc6,0x8d,0xe3,0x6,0x80,0x73,0xe2,0xee,0xe3,0xe,0x3c,0x79,0xbd,0x79,0x6f,0x9e,0x38,0xd,0xe5,0xfb,0x74,0xe0,0x82,0x29,0x5d,0x2d,0x65,0x5a,0x89,0x8e,0x89,0x17,0xaa,0x65,0x9d,0x16,0x1a,0x11,0x6,0x47,0x79,0x3d,0x1f,0x57,0x4c,0x9d,0xbe,0x77,0xab,0x15,0x79,0x1c,0xd8,0xed,0xd7,0xf4,0xbe,0x39,0x7e,0x76,0x9d,0xf7,0xc,0x24,0x83,0xae,0xdd,0xce,0xe3,0xb9,0xf3,0xe7,0x8e,0x62,0xba,0x7a,0x91,0xe9,0x79,0x13,0x17,0x6b,0xc7,0x6e,0x52,0xee,0xf3,0x23,0xc7,0xa0,0xc4,0x9f,0xa9,0x7f,0xd1,0x7b,0xea,0xcd,0x14,0x78,0x28,0x90,0x56,0x22,0xce,0xa3,0xf4,0xf2,0xf1,0xb3,0xdb,0x2f,0x77,0x9,0xe0,0x49,0x14,0x9d,0xaf,0x51,0xe0,0xee,0xcb,0x98,0xc8,0x39,0xab,0xef,0x23,0xbd,0x81,0xfc,0x2c,0x3,0xb4,0xfc,0x2b,0x8e,0xd3,0xc8,0xd7,0xb2,0xc9,0x80,0x8a,0x2c,0x2d,0x7b,0xcf,0xf7,0x35,0x68,0xb7,0x9f,0x80,0xfd,0xc6,0xcf,0x93,0x9c,0x2f,0x66,0xcf,0x92,0xc9,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0xf2,0xc8,0x1c,0x80,0x26,0x93,0xc9,0x64,0xba,0xe2,0x92,0xce,0x3c,0x34,0x72,0x7e,0x35,0xd0,0xba,0x28,0xd8,0x75,0x45,0xee,0x24,0x5a,0x2a,0xf5,0x1c,0x81,0xa4,0x71,0x8a,0x29,0x46,0xd8,0x18,0x34,0x79,0x1f,0xe0,0x9d,0xc3,0xdb,0xdf,0x78,0x3b,0xba,0x4e,0x0,0xc6,0xe4,0x12,0x6c,0x4d,0x40,0x4a,0xa0,0x50,0xa8,0x80,0xb1,0x59,0xac,0xb8,0x56,0x5a,0xad,0x5d,0xf,0x23,0x2e,0xec,0xaf,0xb0,0x1e,0xb,0xce,0x5d,0x38,0xc0,0xc1,0x90,0xb1,0x7f,0x70,0x80,0xd4,0x2f,0x74,0x39,0xd5,0x73,0x87,0x5a,0x4c,0x9d,0x8e,0x7c,0x94,0xd2,0xf4,0xd7,0x9d,0x44,0x29,0x15,0x98,0x70,0xf4,0x96,0xe3,0xae,0xe3,0xb0,0xd6,0xe1,0x7,0x1,0x46,0x4,0x43,0xa,0xd,0x6b,0x4,0x87,0x7e,0xb1,0x43,0x3,0x16,0xc0,0xe4,0x90,0xab,0x95,0x41,0x8d,0x47,0x73,0x53,0x47,0x9e,0xc0,0xbb,0x10,0x13,0x72,0xce,0xec,0xc8,0x9b,0x3a,0xf1,0xa6,0x9e,0x35,0xba,0xe,0x79,0x1c,0x66,0x51,0xdd,0x29,0x92,0xda,0xb8,0x37,0x6e,0xbe,0xa,0x9b,0xf3,0x0,0xc0,0x4d,0x4e,0x4c,0x86,0x82,0xf3,0x5,0x58,0xf9,0xeb,0xdc,0xf5,0x25,0x2e,0xb4,0x5a,0x2b,0x62,0xec,0x38,0x92,0xcb,0x1d,0x86,0x8d,0x22,0xbc,0x3a,0xf4,0x51,0xeb,0x34,0x60,0xa2,0x20,0x88,0x60,0x6f,0x1d,0x57,0x74,0x8d,0x78,0x3d,0x57,0x56,0x97,0x9d,0xf,0x68,0x81,0x57,0x69,0x51,0xb5,0x93,0x4f,0xa0,0x24,0xb9,0xf1,0x2a,0xba,0x7e,0xa9,0x4e,0x38,0xc7,0xd0,0xd,0xc,0xf6,0x8,0x14,0x46,0x8d,0xf,0x7,0x8e,0x3,0x4b,0xd4,0x56,0x1d,0x84,0xec,0x84,0x93,0xaf,0x53,0xa7,0x26,0x7f,0x6d,0x4c,0x9,0x79,0x1c,0x39,0xa2,0xdd,0x10,0x4,0x16,0xca,0xf3,0xa5,0xb,0xc8,0xb3,0x45,0x5e,0x86,0xb4,0x79,0x1c,0xb5,0x9b,0xd1,0xb3,0xd3,0x15,0xc,0xc1,0x9d,0xf3,0x68,0x87,0x9c,0xae,0xba,0xca,0xec,0x39,0x56,0x4c,0x24,0x55,0xa1,0x32,0x1c,0xd0,0xa,0x2f,0x4,0xb7,0x69,0x69,0xdb,0x79,0x8f,0x28,0x63,0x31,0x1c,0x2d,0xef,0x52,0x8f,0x92,0x47,0x94,0x42,0x8e,0x3d,0x19,0xdc,0x49,0xa9,0x43,0x6b,0x2,0x53,0xe9,0x3e,0xbc,0xe9,0xf6,0x1b,0x71,0xf2,0xc4,0x9,0x5d,0x49,0x6e,0xad,0xe1,0xc2,0xfe,0xa,0x5f,0xfe,0xd6,0x63,0x4,0x1c,0xc7,0x1,0xad,0xe4,0xcd,0xfe,0x49,0x8d,0x88,0x33,0xfc,0x6b,0x3c,0x20,0xd3,0xaa,0x5e,0x1b,0x71,0x7e,0xb6,0x19,0xac,0x56,0x77,0x2f,0xaf,0x4f,0x9b,0x4c,0x26,0x93,0xc9,0x64,0x32,0x99,0x2e,0x8f,0xec,0x4f,0x56,0x26,0x93,0xc9,0x64,0xba,0xe2,0xd2,0x8,0x23,0xda,0x2c,0xbe,0xe8,0x35,0x42,0x59,0xb,0xe0,0x7d,0x54,0xd7,0x95,0x83,0x83,0xe3,0xd1,0x0,0x72,0x40,0xf1,0xd8,0x3,0xc7,0xe,0x17,0x5d,0xc4,0xaf,0xfc,0xc2,0xcf,0xe0,0xd8,0xde,0xce,0x8f,0x7c,0x6c,0xb5,0x56,0xd4,0xda,0x90,0x4b,0xc5,0xb9,0xf3,0xe7,0x71,0xfa,0xcc,0x59,0x7c,0xef,0x89,0x67,0xf1,0xcd,0xbf,0x79,0xa,0xcf,0xbe,0x74,0x56,0xdd,0x75,0xb5,0x14,0x84,0x94,0x34,0x26,0xea,0x9c,0x47,0xea,0x1c,0xc6,0x61,0x50,0x8,0xe5,0x7d,0x40,0x73,0x1c,0x85,0x2c,0x19,0x25,0x67,0xf4,0xcb,0x1d,0xee,0x19,0x8c,0x18,0xc7,0x35,0x83,0x96,0xaa,0xa0,0x27,0x76,0x3d,0x3b,0xca,0xaa,0xc6,0x2c,0x63,0xea,0xe8,0xb8,0x86,0x35,0x6a,0xc9,0x14,0x4d,0xe6,0x35,0x57,0xb8,0xb2,0x31,0xae,0xe0,0x62,0xe4,0x75,0xda,0xe,0x85,0x57,0x6f,0xc5,0x95,0x56,0x4a,0xa6,0x18,0x73,0x19,0xe1,0x9a,0x53,0x50,0x4a,0x5f,0x53,0x79,0x80,0xc2,0xa3,0xb5,0x9,0xb4,0x4a,0x74,0x58,0x21,0x5e,0xec,0x66,0x5d,0x78,0xe,0x8e,0xc1,0xe2,0x38,0xe,0xea,0x62,0x2c,0xbc,0xbe,0xeb,0x66,0xa0,0xc7,0xb1,0x4b,0xb0,0x94,0x8c,0x90,0x28,0xce,0xea,0x7d,0xd0,0x31,0x17,0x89,0xd4,0x36,0x76,0xf5,0x89,0xfb,0x8c,0xc6,0x5c,0xbc,0x8e,0xc2,0x78,0x8e,0x16,0xd3,0x90,0x8c,0xc3,0x30,0xac,0x10,0x43,0xe4,0xe1,0x10,0xa7,0x23,0x32,0xad,0x91,0xdb,0x8d,0x1c,0x9c,0x55,0x61,0x1f,0x41,0x5c,0x82,0x8d,0xad,0x52,0xdf,0xa3,0xf4,0x8,0xb6,0x59,0xbc,0x19,0x2d,0xcf,0x20,0x27,0xbb,0xd1,0xd8,0x1,0x28,0xeb,0xbc,0x60,0xc7,0x62,0xea,0x7a,0xee,0x88,0xac,0xda,0xb9,0xe7,0x7d,0x40,0x8,0x81,0x80,0xaf,0xf,0x48,0x31,0x21,0x37,0x8a,0xcc,0x8a,0xdb,0x31,0x75,0x3d,0x80,0x86,0xe6,0x3,0xbf,0x7f,0x81,0xd7,0xe5,0xe4,0x2,0x89,0xc4,0xa,0x1c,0x15,0xb8,0xdb,0x6a,0x41,0x29,0x5,0x31,0x25,0x3a,0x47,0xfe,0x3c,0x35,0x1d,0xe2,0x8,0x68,0xbe,0xce,0x20,0x37,0xdd,0xc3,0x56,0x8a,0x7e,0x7e,0xc6,0x61,0x45,0xd1,0x5f,0x0,0x5d,0xdf,0xd3,0xeb,0xf1,0xa2,0xb1,0x80,0x4f,0xe9,0x3e,0xfc,0xe5,0xf,0x3f,0x88,0x9b,0x6e,0xb8,0x6e,0xe3,0x73,0xf2,0xec,0xf3,0x2f,0xe2,0xcb,0xdf,0x7a,0x8c,0x7,0x78,0xd2,0xec,0x9e,0x43,0x63,0xc1,0xa,0x78,0x25,0xce,0xcd,0x8e,0xc0,0x52,0xa6,0xd8,0x72,0x2d,0x45,0x9f,0x51,0x89,0x5f,0xcb,0xbd,0x68,0x96,0x1,0x36,0x99,0x4c,0x26,0x93,0xc9,0x64,0xba,0x6c,0x32,0x0,0x68,0x32,0x99,0x4c,0xa6,0x2b,0xae,0xc6,0x70,0x41,0xe2,0xac,0xb4,0x4a,0xba,0xe9,0x1c,0x13,0xc8,0xd2,0xf8,0xf7,0x2,0xbc,0x46,0x44,0xbb,0xbe,0xd7,0xa1,0x10,0xef,0x3d,0x42,0xea,0x70,0xb9,0xe2,0x82,0x14,0x29,0x6,0x62,0xc,0x58,0xf4,0x57,0xe1,0xba,0x6b,0xae,0xc2,0xeb,0x5e,0x73,0x1b,0x7e,0xfa,0xbd,0x23,0x9e,0x7b,0xfe,0x34,0xbe,0xfc,0xf5,0x87,0xf1,0xd9,0xaf,0x7f,0xf,0x2b,0x5e,0x4c,0xad,0x3c,0x30,0x52,0x6b,0x45,0xe6,0x31,0xe,0x7,0xa7,0x43,0x9,0x14,0x33,0xcd,0xe4,0x40,0xe4,0xe,0x3d,0x72,0xd6,0x1,0xe0,0x15,0x58,0x1,0x7d,0xf3,0x1,0x8e,0x29,0x86,0x4c,0xe,0x33,0x71,0xbf,0xc5,0xb8,0x24,0x20,0x25,0x71,0x66,0x0,0x2e,0x4,0x8c,0xeb,0xd5,0xd4,0x35,0x87,0xac,0x31,0x5a,0x71,0xb2,0x89,0xf3,0x4f,0x5c,0x8b,0x0,0x14,0x56,0xc9,0xb5,0x8b,0xb1,0xdb,0x18,0x91,0x98,0xdc,0x80,0x41,0x97,0x5e,0x6b,0x2d,0x1c,0xcb,0x5,0x8f,0x4a,0x34,0xed,0x4b,0xac,0x39,0xa3,0xf2,0xeb,0xca,0xa6,0xb3,0xf3,0x1e,0xbe,0x89,0x7b,0x2f,0xa8,0x1b,0x4c,0x6,0x3f,0x28,0xca,0xcb,0x63,0x2d,0x98,0x46,0x38,0xc8,0x25,0x39,0x81,0x46,0xf9,0x7e,0x60,0xea,0x49,0x74,0xde,0xa1,0x93,0x9e,0xc6,0xe6,0x74,0x81,0x56,0xbe,0x36,0x84,0x80,0x32,0x8e,0x3a,0xd6,0x11,0x23,0x45,0xc8,0x9d,0x23,0x88,0xeb,0x39,0xe6,0x5a,0x39,0x42,0x3c,0x8d,0x59,0x34,0x8d,0xe8,0x96,0x92,0xd9,0xf5,0xe8,0x15,0x84,0x7a,0x8e,0x5e,0x97,0x3a,0x4e,0x7d,0x8e,0xde,0x3,0x7c,0x5d,0x43,0x8c,0x0,0x1c,0x86,0xf5,0x5a,0x1d,0x9c,0xd3,0x78,0xc7,0xcc,0xbd,0xc9,0x2e,0x57,0x79,0xee,0xe6,0x4f,0xb0,0x44,0x98,0xe5,0x3e,0xc8,0xe7,0xa6,0xf1,0x35,0xd,0x91,0x6,0x42,0x2,0xbb,0xf7,0x3c,0x9c,0x3e,0x43,0x12,0xf1,0x4d,0xdc,0x5,0x28,0x91,0x61,0x7a,0xfe,0x18,0x5e,0x56,0x6c,0xac,0x6,0xcb,0xaa,0xb5,0x74,0xf,0xd2,0x70,0x8b,0x47,0xab,0x6d,0x63,0x71,0x19,0xfa,0xe4,0xd2,0xff,0x29,0x99,0xc0,0x67,0x98,0x75,0x46,0xe,0xeb,0x95,0x2,0xd2,0x21,0x8f,0x8,0x3e,0xcd,0x86,0x50,0x9a,0xf6,0x7a,0xf2,0x8a,0xcb,0xb4,0x80,0xad,0x6b,0xc3,0x5e,0x7,0x5e,0x4c,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0x97,0x47,0x6,0x0,0x4d,0x26,0x93,0xc9,0x74,0xc5,0x55,0xb9,0xdf,0x4b,0x7,0x0,0x18,0x2,0x8,0x6c,0xa8,0x12,0xf9,0xcc,0x19,0xa9,0xeb,0x80,0xa,0x85,0x7d,0xb4,0xba,0x3a,0x41,0x1d,0x89,0x10,0x3,0xff,0x6d,0x17,0x43,0xbb,0x94,0x70,0xcb,0xcd,0xd7,0xe3,0x15,0x37,0x5d,0x87,0x77,0xdd,0xff,0x66,0x7c,0xf6,0x4b,0xf,0xe1,0x73,0x5f,0x7f,0x14,0x43,0x76,0x18,0x72,0xe6,0x2e,0x37,0xea,0x33,0x1b,0x87,0x35,0x1c,0x80,0x61,0x58,0x73,0x97,0x1d,0x81,0x8f,0x3c,0xc,0xd4,0x4d,0x18,0x13,0x39,0xd8,0x6a,0xc1,0x1d,0xaf,0xb8,0x16,0x3f,0x71,0xef,0x5d,0xd8,0xdb,0xdd,0xc5,0x23,0x8f,0x7e,0x1f,0x9f,0x7f,0xe8,0x6f,0x70,0xb0,0x1e,0xe0,0x83,0x87,0xf7,0x11,0x79,0x5c,0xb3,0xcb,0xaa,0xe3,0x58,0x70,0xd3,0x21,0x8e,0xca,0xb1,0xdd,0x32,0xac,0xd1,0xf5,0xb,0x6,0xa7,0x55,0x9d,0x57,0x5d,0xbf,0x44,0x1e,0x7,0xc,0xeb,0x3,0x76,0x51,0x46,0x84,0x44,0xae,0xaf,0x69,0x14,0x4,0x80,0x0,0xae,0x5a,0xa8,0xb7,0x70,0x1c,0x74,0x14,0x63,0xe,0xa1,0x24,0xbe,0xe9,0x66,0xe0,0x52,0xee,0x61,0x65,0x77,0x21,0x39,0xf9,0xa2,0x82,0x50,0x52,0xd3,0x18,0x6e,0xe4,0xe8,0x29,0xe0,0x90,0xc7,0x91,0xe3,0xaf,0x93,0x3b,0xb0,0xf1,0xb2,0x6d,0x65,0x60,0x24,0xd1,0x5b,0xe9,0x9b,0xa3,0xc8,0xf0,0xb4,0x4,0xd,0x60,0xb6,0x7a,0x5b,0xd9,0x25,0xca,0x40,0x58,0x9c,0x87,0xb2,0xac,0x4c,0x4f,0x1d,0x41,0x2b,0x8d,0x47,0x7b,0x72,0xb0,0xe5,0x8c,0xc0,0x51,0xda,0xca,0xd0,0x4f,0x21,0x6a,0x6b,0x28,0x65,0x44,0x8,0xd4,0x7b,0x97,0x87,0xb5,0x46,0x81,0xe9,0xd8,0xe8,0xfb,0x69,0xa4,0x86,0xc0,0x57,0x8,0x1,0x35,0x46,0x6,0x89,0x5e,0xa3,0xce,0x55,0x1c,0x7d,0x8d,0x20,0x73,0xad,0x85,0x0,0x5c,0xea,0x34,0x6,0x1e,0x53,0xa4,0xe3,0x89,0x91,0x8f,0x95,0xe1,0x19,0x3b,0xc,0x5,0x7e,0x8e,0xfc,0x7c,0xd1,0xe7,0x26,0x4f,0xcf,0x59,0x26,0x37,0x66,0xa9,0x45,0x3f,0x33,0x85,0x3f,0x53,0x12,0xe3,0xd,0xec,0x9a,0x8c,0x31,0x91,0x63,0x6f,0xa4,0x67,0x53,0x60,0x26,0x81,0x45,0x7f,0x49,0xae,0x2e,0x43,0x33,0xa9,0xeb,0x91,0x87,0x35,0xe0,0xe8,0x7e,0x2,0x40,0xea,0x7a,0x5e,0x17,0x6,0xfa,0xc5,0xe,0x86,0xf5,0x81,0xba,0xa,0xe9,0x19,0xf2,0x1a,0xc5,0xa6,0x18,0xb0,0xd3,0x67,0x4b,0x61,0x63,0x3,0x5a,0x2b,0xf6,0xc3,0xd2,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0x32,0xc9,0x0,0xa0,0xc9,0x64,0x32,0x99,0xae,0xb8,0x4,0x0,0xf1,0x7f,0xe5,0x93,0xb,0xab,0x55,0xa4,0x8e,0xa2,0xae,0x21,0x25,0x80,0x87,0x37,0xc4,0x9d,0x94,0x19,0x4a,0x85,0x48,0x0,0x64,0xde,0xd7,0x26,0xee,0xb4,0x2b,0x21,0xe7,0x1c,0xae,0xbd,0xfa,0x24,0x7e,0xe1,0x67,0xde,0x8d,0xb7,0xbc,0xe1,0x35,0xf8,0x37,0x7f,0xf4,0x69,0x3c,0xff,0x32,0x2d,0xeb,0xc2,0x1,0x35,0x67,0x1d,0xbc,0xe8,0xfa,0xc5,0xe4,0x30,0x6b,0x15,0xcb,0xdd,0x3d,0xe4,0x9c,0x91,0x22,0xad,0x9,0xbf,0xfd,0x9e,0xd7,0xe2,0xd7,0xff,0xbb,0x9f,0xc5,0x62,0xd1,0x3,0x0,0xde,0xf2,0xa6,0xd7,0xe3,0x9e,0xbb,0x1e,0xc5,0x3f,0xfd,0xb7,0x7f,0x8c,0x83,0x55,0x45,0xa9,0x19,0x70,0x1e,0xde,0x13,0xc8,0x2a,0x79,0xa4,0xc1,0x5,0x57,0x39,0xca,0x3a,0xad,0xa8,0xa,0xfc,0xa2,0xfe,0x44,0x72,0x4a,0x16,0x1e,0xef,0x8,0x21,0x6d,0xc4,0x30,0x4b,0xa9,0x1a,0x5f,0xed,0xfa,0x85,0xba,0xb,0x1b,0x9d,0xa0,0x8e,0x80,0x84,0xd8,0xb1,0x7b,0xd1,0x21,0x86,0x88,0x71,0x58,0xa9,0xb,0xcf,0xbb,0xa0,0x0,0xca,0x71,0x2f,0x9f,0xc,0xa4,0xc8,0x39,0x37,0x34,0x1a,0x97,0x88,0x9d,0x82,0x4b,0x5a,0xfe,0x4d,0x1a,0xbb,0x15,0xa7,0xa0,0x0,0x45,0xef,0xbd,0x2,0x3a,0x5a,0xf8,0xe5,0xde,0xc0,0x99,0x73,0xae,0x32,0x4,0xf4,0x21,0xa2,0xd5,0x32,0x8b,0x38,0x17,0x38,0xef,0xa6,0xa5,0x5d,0x8e,0xc,0xb7,0x42,0x43,0x1d,0x2e,0x4,0x8e,0x47,0x47,0x5,0xa0,0xe2,0x62,0xf4,0x81,0xa0,0x54,0x88,0xd4,0x8f,0x58,0x39,0xd2,0x5a,0xaa,0x44,0x62,0xfd,0x34,0xce,0xe1,0xe8,0xef,0x1d,0x9f,0xa7,0x38,0x2a,0x8f,0x2e,0x4c,0x13,0x74,0x4,0x8f,0xd3,0xd4,0x2a,0x83,0x23,0xbc,0x6e,0xdc,0x28,0x9a,0xec,0x7d,0x63,0x57,0x23,0x1,0xb7,0x71,0xbd,0x42,0xec,0x7a,0xc,0xeb,0x3,0xc4,0xd8,0x21,0xc6,0x1e,0x45,0x96,0x88,0xb9,0x6b,0x32,0x8f,0x23,0x62,0x9c,0x22,0xe8,0x9e,0x21,0x24,0x45,0xb8,0x9b,0xc6,0xe4,0x75,0x9c,0x86,0x9d,0x88,0xf4,0x59,0x9b,0x1c,0x9f,0x70,0x50,0x17,0x66,0xce,0xa3,0x2,0xc1,0xd6,0x68,0x21,0xb9,0xd4,0x7c,0x49,0x27,0x5e,0xe0,0xc8,0x30,0x30,0x3d,0x5b,0x4,0x76,0x7,0x8d,0x13,0x4b,0xcc,0x5d,0x9c,0x94,0xa,0xea,0x35,0x1e,0xcc,0x9f,0xe7,0xda,0x26,0x77,0xa0,0x80,0xee,0x9c,0xed,0x87,0xa5,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0x65,0x92,0x65,0x2b,0x4c,0x26,0x93,0xc9,0x74,0xc5,0x95,0xba,0x5e,0x23,0xbf,0xb2,0xb4,0xea,0xc4,0x11,0xc6,0xab,0xaa,0xd4,0xb3,0x97,0xe1,0x1d,0x1,0x21,0xef,0xfd,0xb4,0x1a,0xcb,0x40,0xa3,0xb0,0x5b,0xc9,0x7b,0x7,0xb4,0xba,0xf5,0xbd,0x6a,0x6b,0xa,0x17,0x6a,0xad,0xfc,0xcf,0x55,0xbb,0xfe,0xe4,0xaf,0xff,0xb5,0x1,0x62,0xe7,0x1c,0x5e,0xf9,0x8a,0x1b,0xf0,0x8f,0x7e,0xe3,0xc3,0x78,0xd7,0x3d,0xb7,0xeb,0x3a,0xae,0xc,0x72,0x38,0xe7,0x91,0xd8,0xb5,0xe6,0xbc,0x63,0xe0,0x23,0x11,0x67,0xea,0x6f,0xfb,0xd0,0xfb,0xdf,0xa9,0xf0,0x4f,0xbe,0xf7,0xae,0xd7,0xdd,0x81,0xfb,0xef,0xbe,0x5d,0xaf,0x9,0x97,0x20,0xd2,0xf7,0xc4,0x84,0x90,0x92,0xc6,0x2d,0xa5,0x77,0x2d,0xa6,0x8e,0xae,0xf,0xc7,0x37,0x53,0xea,0xd1,0x2f,0x96,0xa,0x45,0x69,0xcd,0x98,0x16,0x8d,0x7d,0x88,0x48,0x1d,0xfd,0xb3,0x7c,0x8d,0x8c,0x89,0xd0,0xea,0x2e,0xa6,0xce,0xc1,0x9a,0x39,0xce,0xa,0x5,0xad,0xd2,0xf3,0x47,0xeb,0xca,0xbd,0x46,0x84,0xbb,0x7e,0x81,0xc0,0xb1,0x59,0xb9,0x3f,0x5d,0xbf,0xd0,0x95,0xd7,0x10,0x13,0xfa,0xc5,0xe,0x2f,0xed,0xd2,0x6b,0x7a,0x4f,0xc3,0x22,0x39,0x8f,0x48,0xfc,0xb5,0x3a,0x2,0x1,0x19,0xd4,0x0,0xd,0x42,0x30,0x64,0x23,0x60,0xe6,0xb5,0xb,0x4f,0x57,0x63,0x41,0x10,0x4f,0x96,0x79,0x75,0x9d,0x59,0x62,0xc8,0xb2,0x54,0xdc,0x2a,0x3b,0x18,0x9b,0x8e,0xba,0x48,0x2f,0x9f,0xf3,0xf4,0xfd,0xe3,0xb8,0x26,0x10,0x1d,0x79,0x1,0x37,0x44,0xa4,0x44,0x2b,0xd1,0x2,0x9,0x1d,0x80,0xae,0xeb,0xd1,0xf5,0xb,0xbd,0x36,0xf2,0xf5,0x91,0x5d,0x96,0x3a,0x78,0xc1,0xcf,0x78,0x4c,0xbd,0x2e,0xdf,0x4e,0x31,0x6f,0x6c,0x9c,0xab,0x44,0xa3,0x1,0xa0,0xeb,0x97,0x0,0xa0,0x2b,0xd0,0x6d,0xb6,0x94,0x1b,0x19,0x6,0xd2,0x78,0x48,0x61,0xe7,0x25,0x1,0xc4,0xc0,0x51,0x6b,0x1f,0x2,0xf7,0x7,0x8a,0x47,0xd6,0xe9,0xf3,0x12,0xbb,0xe,0xa9,0xef,0x35,0x7e,0xdd,0x2d,0x96,0x48,0xbc,0x2c,0xad,0x1b,0x26,0xe,0x48,0xa9,0x9f,0x22,0xba,0x1b,0xcf,0xff,0xb4,0xb2,0x2c,0x10,0xcf,0x4b,0x77,0xa0,0xf3,0xbc,0xd1,0xed,0x36,0x16,0x87,0xe5,0x59,0xe1,0x8b,0xa3,0x8e,0x45,0x59,0x5,0xa6,0xc5,0xeb,0x32,0xad,0x7e,0xdb,0x8,0x88,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0x65,0x93,0xfd,0xc9,0xca,0x64,0x32,0x99,0x4c,0x3f,0x16,0x39,0x50,0xf4,0xb7,0x95,0xa2,0x8e,0x24,0x1,0x35,0xad,0x4d,0xdd,0x77,0x39,0x8f,0x14,0x9b,0xe5,0x58,0x29,0x18,0xda,0xa5,0xae,0xd7,0xce,0xb6,0x5a,0xca,0x56,0x80,0xd7,0x5a,0xc3,0xef,0x7f,0xec,0x33,0x78,0xfe,0xa5,0x97,0x69,0x55,0xb6,0x14,0xea,0xae,0x2b,0x55,0x57,0x4a,0x23,0x3,0xae,0xbe,0x4b,0x58,0xf4,0x1d,0xf6,0x76,0x3a,0xdc,0x74,0xfd,0xb5,0xb8,0xfe,0xda,0xab,0x71,0xf5,0xa9,0x63,0x58,0x2e,0xfa,0x1f,0xea,0x2e,0xdc,0xdd,0x59,0xe2,0xc3,0xf,0xbe,0x13,0x5d,0x4a,0xf8,0xd3,0x2f,0x7e,0x8b,0x20,0x48,0xc9,0x68,0x1c,0xed,0x4,0x8f,0x5a,0x54,0x38,0xb4,0x9c,0x51,0x2a,0xc1,0xcc,0x93,0xbb,0x3d,0x4e,0x9d,0x3c,0x71,0xf4,0xba,0x38,0x87,0x5b,0x6f,0xb9,0x1,0x7f,0xf1,0xd5,0xef,0xc0,0xb1,0xd3,0x4f,0x86,0x42,0x4a,0xa1,0x65,0x57,0x71,0x5e,0x9,0xb0,0x13,0xc8,0x15,0x53,0xc7,0x8b,0xb3,0x4,0x68,0xca,0x38,0x2a,0x2c,0x14,0x57,0x58,0xad,0x55,0x3b,0xd8,0xbc,0x8c,0x6b,0x38,0x8f,0x86,0x4a,0x8b,0xc2,0xde,0xc3,0x35,0xea,0x37,0x94,0xce,0x40,0xcf,0x83,0x25,0x29,0xf5,0x7a,0x9f,0xca,0x38,0xc0,0x7b,0x8f,0xae,0x5f,0x50,0xec,0x94,0x23,0xa4,0xa5,0x64,0x44,0xdf,0xe9,0x7d,0xf1,0xc1,0xc3,0x11,0xc3,0xe4,0xce,0x3b,0xc7,0x91,0x57,0x72,0x75,0xa6,0xd4,0xa1,0x86,0x42,0x8b,0xb8,0x34,0x6b,0xab,0xee,0x43,0x1,0x7c,0x21,0x10,0xec,0x25,0xf7,0x5c,0x51,0x8,0x98,0x1b,0x2f,0xfc,0x6e,0x39,0xc7,0xd4,0x25,0xed,0x33,0x9c,0xbb,0x1b,0x43,0x48,0x1c,0x2f,0x1f,0xd9,0x11,0x48,0xeb,0xb4,0x2,0xed,0x68,0x9,0xb7,0xe7,0x15,0xe4,0x51,0x9f,0x47,0xe7,0xdd,0x14,0x4d,0x67,0x17,0xa3,0x3c,0x63,0x68,0xc,0xb5,0xdb,0xb4,0xd4,0xc,0x5,0xa6,0x9d,0x82,0x6a,0x5a,0xfd,0x8d,0xea,0xaa,0x24,0xe0,0xe6,0xd5,0x89,0xa8,0xb,0xc6,0xc,0x4,0x1b,0xaf,0x4a,0x4b,0xc7,0x24,0x30,0xf5,0x1f,0x6a,0xa7,0x60,0x6b,0x3c,0x88,0xc2,0x10,0x94,0xe3,0xd3,0xe,0x74,0xbc,0x4,0x87,0xa7,0x7e,0x3e,0x2,0x70,0x4d,0x9d,0x86,0xf2,0xd9,0x2a,0x65,0x8a,0x5a,0x7b,0x1e,0xdc,0x51,0xa7,0xed,0xd6,0xf,0xb0,0xd3,0xe7,0xc8,0x79,0x47,0xd7,0x91,0x3b,0xfc,0x3c,0x2f,0xa,0xcb,0x7a,0xb7,0xc,0x7a,0x78,0xee,0x20,0x14,0xb7,0xaa,0xc4,0x9c,0xe5,0x3d,0x64,0x20,0x64,0xfa,0x0,0x57,0xfb,0x41,0x69,0x32,0x99,0x4c,0x26,0x93,0xc9,0x74,0x99,0x64,0x0,0xd0,0x64,0x32,0x99,0x4c,0x57,0x5c,0xe2,0xfc,0x11,0xab,0x91,0xe7,0x38,0x60,0x65,0xf7,0x8f,0xf7,0x1e,0xe3,0xb0,0x9e,0xd6,0x6e,0x7d,0x98,0xba,0xc9,0x42,0xd4,0x68,0xa5,0x73,0x9e,0x63,0x8e,0xdb,0xd,0xed,0xad,0x1,0xcf,0xbd,0xf8,0x32,0xbe,0xf7,0xf4,0x4b,0x70,0xc,0x60,0xe6,0xc0,0x41,0xe0,0x4b,0x29,0x19,0x21,0x26,0xe4,0x71,0xcd,0x4e,0xa5,0x87,0x19,0xd2,0x2d,0x70,0xfb,0x2d,0xd7,0xe1,0xbe,0x37,0xbe,0x6,0xb7,0xdf,0x7a,0xb,0x52,0xda,0xfe,0xaf,0xcd,0x14,0x23,0x3e,0xf8,0xc0,0xfd,0x48,0xd1,0xe3,0x63,0x9f,0xfd,0x6,0x3,0xcc,0x7e,0x8a,0x75,0x3a,0x87,0xf5,0xc1,0x45,0xc4,0xae,0xa3,0xa8,0x30,0x1a,0x8a,0xeb,0x30,0x8c,0x19,0x7d,0xdf,0x1d,0x79,0xbd,0xf3,0x17,0x57,0xe4,0x1a,0xac,0x8e,0xfb,0xd9,0x78,0x81,0x37,0x75,0x3a,0xda,0x21,0xbd,0x73,0xd2,0x5,0x28,0xb0,0x46,0x80,0x94,0xf4,0x6,0x6,0xee,0x52,0x14,0xd8,0x17,0x82,0xc,0x2d,0xf0,0xb2,0x2d,0x26,0x67,0xdf,0x4,0x97,0x2a,0x1c,0xa8,0xf3,0x2f,0xf5,0xb,0x2,0xa5,0x89,0xdc,0x68,0xe4,0xca,0xc,0xea,0x7c,0xab,0xb5,0xc2,0x3b,0x7,0xe4,0xa6,0x51,0x5c,0xb9,0xce,0x0,0x2f,0x9,0xbb,0x0,0x38,0xc0,0xb7,0x69,0x5c,0x44,0x8e,0xd9,0x87,0x80,0xd4,0x2f,0x30,0xac,0xe,0xd0,0xf5,0xb,0xc,0xeb,0x15,0x92,0xba,0xea,0x16,0x18,0xc7,0x35,0x9c,0xe7,0xe,0x3f,0xef,0x11,0xa5,0xfb,0xb0,0x35,0xa4,0xd4,0x73,0x5c,0x14,0xa,0x20,0xe9,0xbe,0x12,0xec,0x12,0x77,0x1a,0x45,0x88,0x9,0x86,0x41,0x63,0xbb,0x41,0xbf,0x56,0xa2,0xe6,0x9e,0xa1,0x97,0x2c,0xd2,0xa,0x60,0x8e,0xc,0x23,0xe5,0xda,0x42,0xdc,0x83,0x1c,0x57,0xad,0xd2,0x1b,0xe8,0x3,0x82,0xf,0x48,0xdd,0x2,0x39,0x8f,0xc4,0xab,0xeb,0xb4,0x12,0xec,0x43,0x20,0xe0,0xcc,0x2b,0xb9,0x8d,0x5d,0x70,0xb5,0x2,0x31,0x50,0xdf,0x9f,0x74,0x1,0x6,0x59,0x3,0x6e,0x95,0xdd,0x7f,0x53,0xf7,0x21,0x1c,0x10,0x63,0xc2,0xc8,0x5d,0x84,0xe2,0xfc,0x54,0x57,0x1e,0xbf,0xd6,0x62,0x67,0x57,0xbb,0xf8,0xe4,0x79,0xd0,0xd8,0xad,0xe,0x6d,0x90,0x43,0x4f,0x3a,0x24,0x9d,0xa3,0x75,0xe4,0x6e,0xb9,0xab,0x83,0x21,0x72,0xad,0x36,0x3f,0x5b,0x8d,0xef,0xaf,0xe7,0x51,0x15,0x8a,0xeb,0xa6,0x7e,0x41,0x83,0x34,0xce,0xeb,0x67,0xb4,0x39,0x79,0x2e,0xd6,0xea,0x1a,0x6c,0xad,0xc1,0x43,0x9c,0x91,0x9,0xa5,0x14,0xd4,0x56,0xd4,0xfd,0x29,0x9f,0x5f,0x93,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xe5,0x91,0x1,0x40,0x93,0xc9,0x64,0x32,0x5d,0x71,0xb5,0x43,0xab,0xa2,0xce,0x79,0x94,0x96,0x19,0xc,0x10,0xec,0x8,0x3e,0xaa,0xa3,0x4b,0x57,0x4c,0x1d,0x8f,0x5,0x88,0x63,0xa,0xe,0x4d,0xe0,0xd0,0x25,0x5c,0x7a,0xce,0x71,0x3f,0x9d,0x44,0xe,0x67,0x4e,0x2a,0xb0,0xeb,0x6d,0x3a,0x30,0xe8,0x8,0x4,0x5a,0xc0,0x8b,0x2f,0x9f,0xc7,0xcb,0x17,0xd7,0xf8,0xf2,0x23,0x4f,0xe0,0x96,0xeb,0x4e,0xe2,0x3,0xef,0x79,0xb,0xee,0xbc,0xe3,0x56,0xc4,0x70,0x14,0x88,0x84,0x10,0xf0,0xc0,0x3b,0xef,0xc5,0xd3,0xcf,0x9f,0xc1,0x37,0x1e,0x7b,0x96,0x86,0x22,0xc0,0x4d,0x87,0xad,0x91,0x5b,0x8f,0xa1,0x11,0x5a,0xc3,0xc5,0xfd,0x7d,0x7c,0xe9,0x6b,0xdf,0xc0,0x3,0xef,0xbe,0x7f,0xe3,0x75,0xce,0xbc,0xfc,0x32,0xfe,0xea,0x6b,0xdf,0x26,0xc8,0x19,0xe9,0x7c,0xd8,0xf1,0x3e,0x78,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x9d,0x77,0xea,0xc6,0x4b,0xdd,0x2,0xeb,0xd5,0x3e,0x62,0x4c,0xe4,0x9e,0xab,0x15,0xad,0x4d,0xce,0xae,0x6e,0xb1,0x40,0x1e,0x6,0x38,0x8e,0x99,0x52,0x4,0x94,0xfd,0x61,0x32,0xfe,0xc0,0xc3,0x1a,0xe2,0xd2,0x3,0xa0,0x7d,0x74,0xe,0x50,0x27,0x9a,0x5c,0x53,0x2,0x57,0x89,0xde,0x97,0x21,0x52,0x88,0x51,0xaf,0x17,0xe0,0xd0,0xf5,0x4b,0xbd,0x5f,0xe4,0xa,0xac,0x8,0x1c,0x31,0x25,0x47,0x1a,0x0,0x50,0x6c,0x59,0x60,0xa3,0xf4,0x0,0x36,0x76,0x4,0x96,0x92,0x69,0x3d,0x59,0x9c,0x93,0x7e,0x72,0x3f,0xca,0x98,0x8a,0x0,0x50,0x1a,0xe1,0x70,0x8,0x29,0xa1,0xe4,0x82,0x7e,0xb1,0x84,0x46,0x4e,0x7d,0x9b,0x22,0xd2,0xea,0x28,0x73,0x53,0xc7,0x5c,0x6b,0xd4,0x37,0x59,0xa,0x42,0x8a,0xf4,0x7e,0xb3,0x1,0x8f,0x9a,0x33,0x47,0xa1,0x7b,0x72,0x2d,0x7a,0x7,0xe7,0x22,0x2,0x3b,0xf2,0x28,0xde,0xda,0x14,0xba,0x39,0xdf,0x74,0xf8,0x22,0xa6,0x4e,0x7b,0xef,0x1a,0xc7,0xc1,0xc7,0x61,0x85,0xe5,0xce,0x1e,0x86,0xf5,0x4a,0xdd,0x8f,0x89,0x23,0xcd,0x79,0x1c,0x34,0xea,0xdb,0xd8,0xd9,0x5a,0x5b,0x65,0x50,0x4c,0xee,0x4e,0x1f,0x13,0x7c,0xe3,0x63,0xf4,0x3c,0xc2,0xc2,0xc3,0x2a,0xa9,0x5f,0xa2,0xe6,0x2,0x3f,0xeb,0xc9,0xf4,0xfc,0x7c,0xe6,0x71,0x50,0x77,0xa2,0x2c,0x0,0x43,0x16,0x84,0xf9,0xd7,0x75,0x5d,0x99,0x97,0x9c,0x4b,0x1e,0x75,0xc1,0x5a,0x60,0xee,0xb6,0x7d,0x1d,0x82,0x7b,0x3c,0xda,0xc1,0xd1,0x64,0xc7,0x71,0xfd,0xca,0xcf,0x47,0x1e,0x7,0xfd,0x7a,0x7a,0xdd,0xe,0x79,0x1c,0x19,0x30,0x93,0x6a,0x11,0xb8,0xc9,0x4f,0x88,0x64,0x8f,0xa1,0xe9,0x6e,0x93,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0x65,0x90,0x75,0x0,0x9a,0x4c,0x26,0x93,0xe9,0x8a,0x4b,0x7a,0xbe,0xc4,0xb1,0x54,0xf2,0xa0,0xfd,0x7e,0xe,0x4,0xbb,0x1a,0xf8,0xef,0x63,0x52,0xd7,0x1c,0x0,0x84,0x90,0xa6,0x15,0xdd,0x99,0x1b,0xec,0x52,0xa2,0xc8,0x61,0xe1,0x35,0xd6,0xa0,0xee,0x33,0x19,0x2b,0x70,0xdc,0x27,0x27,0x3d,0x78,0x79,0x58,0x23,0x8f,0x23,0x56,0x7,0x17,0x91,0xc7,0x1,0xad,0x56,0xc,0xeb,0x15,0xbe,0xff,0xcc,0x4b,0xf8,0xa7,0xbf,0xf3,0x27,0xf8,0xdd,0x3f,0xfa,0x73,0xec,0xef,0xaf,0xb6,0xbe,0x57,0xd7,0x25,0xfc,0xd2,0xcf,0xbc,0x13,0x27,0x76,0x17,0xe8,0x16,0x4b,0xa0,0x35,0x44,0x8e,0x2a,0xa7,0xd4,0xf1,0xca,0x6e,0xe0,0x95,0x5c,0x87,0x3f,0xfc,0xb3,0xaf,0xe0,0x93,0x9f,0xfe,0x2,0x4e,0x9f,0x39,0x8b,0x8b,0xfb,0xfb,0x78,0xec,0x89,0xa7,0xf0,0x2f,0x7e,0xe7,0x8f,0xf1,0xe2,0xd9,0x7d,0x0,0x13,0x60,0x49,0xa9,0x47,0x4c,0x1d,0x52,0xea,0x31,0xe,0x2b,0x44,0x1e,0xcb,0x70,0x3e,0x68,0xd7,0x5e,0x8c,0x9,0x31,0xf5,0xd4,0xc7,0xb7,0xd8,0x41,0x8,0x81,0xdd,0x8e,0xec,0x12,0x2c,0x45,0x9d,0x69,0x12,0x65,0x15,0xf7,0x1b,0x5d,0xd7,0x48,0xae,0x2d,0xee,0xca,0xf3,0x21,0x50,0xff,0xdd,0x6c,0x71,0x97,0xe2,0xa4,0x1,0xb1,0xeb,0x75,0xc1,0x97,0x7a,0xef,0x3a,0xed,0x9c,0x73,0xc,0x98,0xbc,0xf,0x74,0xaf,0x52,0x22,0x88,0xe5,0x29,0xc2,0x2d,0xfd,0x8f,0x0,0xbd,0x77,0xd7,0x2f,0xb5,0x6f,0x4f,0xfa,0xef,0x64,0xc,0x44,0x5c,0x7c,0x31,0x76,0x7a,0x2d,0xe8,0xeb,0x8,0xa6,0x52,0x87,0x5f,0xd0,0xd1,0xa,0xcf,0x43,0x29,0xa9,0xeb,0x14,0x4c,0xf6,0x8b,0x1d,0x3a,0xa6,0x10,0xf4,0x5c,0x23,0xbb,0xeb,0x68,0xbc,0xc3,0x21,0x70,0x3f,0x22,0xc1,0xdf,0x82,0xe5,0xee,0x9e,0x5e,0x63,0x5a,0xd9,0xad,0x74,0x2c,0xc,0x21,0x9d,0xf3,0xda,0xbb,0x28,0x20,0x53,0xd7,0x89,0xa5,0xdb,0xcf,0x4d,0x10,0x2b,0xc6,0x84,0x9c,0xd9,0x15,0xc9,0xf1,0x6c,0xb9,0x96,0x72,0xfe,0xce,0x39,0x2c,0xd8,0x75,0x37,0xae,0xd7,0xda,0xb5,0x28,0x31,0x5a,0x82,0xb9,0x14,0xcb,0x16,0x17,0xab,0x8f,0x91,0x3e,0x23,0x29,0x1,0x68,0x3a,0x52,0x22,0xb0,0xd,0x20,0x7,0xa9,0x44,0x83,0x65,0xdd,0x37,0xc6,0x44,0xb1,0x63,0xee,0xd8,0x6c,0xad,0xaa,0xdd,0x2e,0xf2,0x12,0xb2,0xfc,0x73,0xd7,0xf7,0xdb,0x3f,0x5f,0xec,0x8e,0x14,0x97,0x28,0x39,0x42,0xf9,0xf,0x97,0x72,0x5d,0xa4,0xf,0x92,0x1d,0xbf,0xf3,0xb1,0x15,0x1,0xb2,0xb4,0x76,0x1d,0xf8,0x18,0xa0,0x71,0x61,0xc0,0x1c,0x80,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0x97,0x53,0xe6,0x0,0x34,0x99,0x4c,0x26,0xd3,0x15,0x17,0x2d,0x92,0x82,0xa0,0x85,0x73,0x80,0xf,0xda,0x7,0x26,0xb,0xb0,0xe2,0x62,0x6a,0xec,0xd6,0xca,0xe3,0x48,0xa0,0xc3,0x11,0xe0,0x28,0xa5,0x20,0x75,0x1d,0x52,0xb7,0x0,0x5a,0xbd,0x4,0x2c,0x68,0x70,0x9e,0x0,0x4e,0x1e,0x87,0x59,0xff,0x98,0xa7,0x48,0x6e,0x4a,0xd4,0x33,0x7,0x87,0xf5,0x7a,0x45,0x40,0xb1,0x14,0xee,0xb6,0x5b,0xd2,0x18,0x84,0xc4,0x12,0xd9,0xc5,0xf7,0xf9,0x6f,0x7c,0xf,0x2f,0xbd,0x7c,0x1e,0xff,0xe0,0x97,0x1f,0xc4,0xb1,0xbd,0x9d,0x23,0xef,0x78,0xea,0xe4,0x71,0xfc,0xc2,0x3,0xf7,0xe1,0x5f,0x7d,0xf4,0xd3,0xda,0x8f,0xe7,0xd9,0x81,0x18,0x52,0x47,0xce,0xc0,0xd6,0x10,0xbb,0xe,0x15,0x1e,0xff,0xe1,0x53,0x5f,0xc2,0xc7,0xfe,0xf2,0x6b,0xc8,0xe3,0x88,0xb1,0xca,0xe8,0x87,0x3,0x18,0x84,0x4,0x1e,0x56,0xa0,0x73,0xce,0xe8,0x7a,0x1a,0xee,0x18,0xc7,0x35,0xa2,0x8b,0x33,0x88,0x3a,0x72,0x2f,0xdd,0xe4,0xda,0x93,0x68,0x6f,0xce,0x23,0xfa,0xe5,0xe,0x47,0x73,0x13,0x77,0xab,0x39,0x5a,0x11,0x6,0xb0,0xd8,0xd9,0xc5,0xb0,0x5e,0x1,0x68,0x88,0x21,0xa1,0x31,0xf4,0x93,0x2e,0xc6,0xca,0xce,0x39,0x19,0x31,0x11,0x98,0x45,0x51,0x6c,0x7,0x34,0x2,0x47,0xc3,0xfa,0x0,0xfd,0x62,0x87,0xc0,0x92,0x38,0x36,0x6b,0xa5,0x73,0x2d,0x5,0xc1,0x73,0x2c,0xd8,0x79,0x34,0x4f,0xe7,0xd7,0x6a,0x21,0x27,0x63,0xab,0x87,0x22,0xaa,0x93,0x53,0xb1,0xa1,0x22,0x75,0xb,0xc,0xc3,0x8a,0xc7,0x40,0xa2,0xc6,0x70,0xe9,0x3c,0x3c,0xc5,0xc8,0x1,0x72,0x4,0x32,0xe0,0x94,0x9e,0xbe,0x18,0x29,0xa,0x2d,0x83,0x1c,0xe4,0x24,0xe4,0x78,0x2a,0x18,0x58,0xb5,0x86,0xae,0xef,0xd4,0x95,0x38,0x8d,0x9f,0x50,0x94,0xbb,0xb5,0x46,0xe,0xc5,0x90,0xd0,0x12,0x39,0x12,0x11,0x9d,0x42,0xae,0xd6,0xa8,0x4f,0xb2,0x29,0x58,0xa4,0x38,0x2c,0xc5,0x89,0xe7,0xc3,0x1f,0x4d,0x1d,0x95,0xb4,0x9f,0xeb,0x10,0x13,0x43,0x38,0xd0,0x75,0xa4,0x28,0x33,0x1,0x69,0xe7,0xc2,0x86,0x53,0xd3,0xb9,0xa0,0xae,0x3d,0x27,0x3d,0x85,0xc,0x95,0x9d,0xde,0xb7,0xa9,0x5f,0x4f,0x9e,0x9f,0x5a,0xb,0xba,0x7e,0x49,0x50,0xbb,0x35,0xf4,0xcb,0x5d,0xba,0xf,0x20,0xf7,0x62,0x1e,0x6,0xfe,0x3c,0x34,0xb4,0xe6,0x18,0x20,0x36,0x86,0xf2,0xdb,0x3e,0x5a,0xe4,0x80,0xc,0x21,0x61,0x18,0x56,0xa8,0xa5,0x6c,0xf4,0x5,0xd2,0x75,0x24,0x17,0x23,0xad,0x33,0xcb,0x73,0x5a,0x74,0xe0,0xc6,0x39,0xee,0x45,0xf4,0x5e,0xaf,0xa1,0x0,0x68,0x5a,0x7,0x2f,0xf6,0xc3,0xd2,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0x32,0xc9,0x1c,0x80,0x26,0x93,0xc9,0x64,0xba,0xe2,0xa2,0xee,0x32,0x70,0x14,0xd0,0xcd,0x96,0x68,0xa9,0x3,0xcd,0xe9,0x58,0x40,0xa1,0x48,0x66,0xa9,0xbc,0xbc,0x3a,0x75,0xb4,0x49,0x7,0xde,0x4,0x9b,0xb6,0xbd,0x93,0xdb,0xf8,0x75,0xe7,0x3c,0x8f,0x87,0x80,0x7,0x25,0x68,0x21,0xb8,0x48,0x1f,0x9b,0x27,0x97,0x98,0xe3,0xe,0x42,0x34,0xa0,0xe4,0xac,0x1d,0x7c,0x34,0x20,0x92,0xf1,0xdd,0x27,0x9e,0xc5,0xbf,0xfc,0xbd,0x8f,0x63,0xff,0x60,0xbd,0xf5,0xfc,0xde,0x70,0xe7,0xad,0x78,0xdd,0xab,0x6e,0xd0,0xf7,0xa4,0x35,0x58,0x0,0xa0,0xfe,0x33,0xe9,0x77,0xa3,0xe8,0x6b,0x87,0x8b,0xfb,0x2b,0x14,0x17,0xa8,0x7f,0x8d,0xcf,0xcd,0xb3,0x23,0x52,0xc6,0x3a,0x16,0x3b,0x7b,0x7a,0x6c,0x12,0xd7,0x4,0xa0,0x2b,0xb6,0xfd,0x92,0x9c,0x6e,0xd2,0xcd,0x47,0xf0,0xab,0x21,0x8f,0x32,0x9e,0x41,0x23,0x13,0x21,0xc4,0x69,0xa9,0xd6,0xd1,0xce,0x70,0xc9,0x59,0x7f,0x5d,0x86,0x3a,0x68,0xd1,0x97,0x5d,0x7d,0x7c,0x1e,0x12,0xab,0x95,0x71,0x8b,0x10,0x13,0xb9,0xd0,0x2,0x39,0xe0,0x16,0xcb,0x5d,0x3a,0x67,0xee,0x68,0x24,0xb0,0x43,0x10,0x33,0xf0,0x22,0x6d,0x8c,0x9,0xfd,0x72,0x57,0xc7,0x27,0xfa,0xe5,0x8e,0xc2,0x3f,0x71,0xbc,0xc9,0xc0,0x8b,0xe7,0xf7,0x8c,0x91,0x0,0x61,0xd7,0x2f,0xe1,0x3c,0xfd,0xbe,0x38,0xdb,0x62,0x4a,0xfa,0x4c,0x4,0x76,0xe7,0xc9,0x4a,0x6f,0x88,0x4,0xe7,0x7c,0x98,0x5c,0x6e,0xea,0x86,0x63,0x27,0x5d,0xc7,0xc7,0x21,0x3d,0x74,0xe2,0xb4,0x9b,0x47,0xca,0x9d,0x23,0xd7,0x1a,0x8d,0x65,0x8c,0xec,0x40,0x8d,0x7a,0xfd,0xc5,0xe1,0xe9,0x38,0x4a,0x2b,0xee,0x3d,0x1a,0xf7,0x28,0xe8,0xfa,0x5,0x47,0x94,0x69,0xc0,0x25,0xc6,0xa4,0x2b,0xc0,0x2,0xba,0xc5,0xcd,0x48,0xc7,0xd5,0xa1,0xb5,0x8a,0x7e,0xb1,0xa3,0xc7,0x12,0xd9,0xe5,0xd7,0x5a,0xd5,0xb5,0x5e,0x59,0x5d,0x4e,0x89,0xae,0x97,0x38,0x59,0x9d,0x77,0x58,0xee,0xee,0x6d,0x7c,0x56,0xa4,0x5b,0x50,0xfe,0x5e,0xd6,0xa5,0x13,0xf7,0x22,0xf6,0xcb,0x1d,0xea,0x8a,0xc,0xbc,0x26,0xdd,0x1a,0xc0,0xb,0xc1,0x97,0xca,0x0,0x8b,0x73,0x2f,0xf1,0xca,0xb4,0xbc,0x3f,0x40,0xcb,0xc5,0x0,0xf4,0xba,0x47,0x8e,0xf7,0x7b,0x7e,0x56,0xc8,0x11,0x48,0x71,0x6e,0x60,0xaa,0x5,0x68,0x3a,0x41,0x6c,0x32,0x99,0x4c,0x26,0x93,0xc9,0x64,0xba,0x9c,0x32,0x0,0x68,0x32,0x99,0x4c,0xa6,0x2b,0xae,0xae,0x5b,0x10,0x43,0xf0,0x1e,0xb5,0x15,0x8e,0x4f,0xba,0x8d,0xd5,0x50,0xed,0xcc,0xe3,0x55,0x53,0x2,0x3,0xd0,0x81,0x4,0x71,0xea,0xd5,0x5a,0x35,0x52,0xbc,0xd,0x52,0x40,0xfa,0xda,0x5a,0x43,0xad,0x5,0x7,0x17,0xce,0xa1,0xe4,0x4c,0x10,0xb2,0x16,0x94,0x3c,0xe8,0xf2,0x68,0x1e,0x7,0x1c,0x5c,0xbc,0x80,0xfd,0xb,0xe7,0xb4,0x1b,0x90,0xe2,0xc2,0x4d,0x7f,0x8f,0x1c,0x5e,0x1,0x8f,0x3e,0xf9,0x3c,0xfe,0xe0,0xe3,0x9f,0x46,0xad,0x47,0xdf,0x37,0xc5,0x88,0xf7,0xde,0x7f,0x37,0xf,0x80,0x4c,0x70,0x27,0x84,0xa4,0xe7,0xe4,0xb9,0x8b,0xaf,0xd6,0xaa,0x4e,0x31,0x89,0x78,0xd6,0x52,0xd0,0x2a,0x39,0xa5,0x8,0xd6,0x75,0x18,0xd7,0x6b,0xed,0x41,0xf4,0xce,0xa1,0x96,0xaa,0x2e,0x37,0x89,0x53,0x27,0x8e,0x95,0xa6,0x7e,0xc1,0x5f,0xeb,0xa7,0x3e,0xb7,0x98,0x66,0xb1,0xd5,0xa6,0x2b,0xb5,0x3e,0xd0,0x40,0x7,0x39,0xd8,0x12,0x16,0xcb,0x5d,0xed,0x91,0x13,0x60,0x28,0x91,0x5c,0x89,0xad,0x92,0xfb,0x8f,0xce,0xa3,0xef,0x97,0xe8,0xfa,0x25,0xf5,0xc5,0xe5,0x91,0xee,0x1d,0x47,0x61,0x69,0x8d,0x77,0x2,0x92,0x29,0xf5,0xf0,0x91,0x1c,0x99,0xdd,0x62,0x7,0x2,0x7,0xfb,0x7e,0x9,0xef,0x1c,0xf2,0x38,0xd2,0xe0,0x6,0x3b,0x40,0x53,0xd7,0x53,0x5c,0x17,0xd0,0xd8,0xaa,0x38,0x11,0xe5,0x5a,0xd1,0xb9,0xf3,0xb3,0x3,0x4c,0xcf,0x46,0xa0,0x9e,0x3b,0x82,0x8e,0x1d,0x62,0x22,0x68,0x98,0x12,0xc1,0x50,0xea,0xdd,0x73,0x3a,0x14,0x12,0x53,0x47,0x43,0x18,0x7c,0x1d,0xe4,0xf9,0xb,0x71,0x82,0x92,0x0,0xf4,0x7d,0x5,0xa,0x8b,0x5b,0x90,0xce,0xb5,0x43,0xd7,0x4d,0xae,0xcf,0x10,0x3b,0x7d,0x3f,0x8a,0x3c,0x77,0x53,0x6f,0x23,0x8,0x92,0xc9,0xb1,0xeb,0x60,0x9,0xc0,0xcf,0x9e,0x43,0x61,0xe7,0xa1,0xc0,0xd6,0x98,0x7a,0x8d,0xf,0xa7,0xae,0xd7,0x58,0x76,0xad,0x45,0xa1,0xa3,0xf3,0x41,0xbb,0xf6,0xd0,0x9a,0xc2,0xdf,0x56,0x1b,0x52,0xb7,0xe0,0xe7,0x90,0xa0,0xa1,0xf4,0x4a,0x52,0x8c,0x9e,0x80,0xa3,0xc0,0x78,0x89,0x88,0xcf,0xe3,0xf7,0x47,0x3e,0x5c,0x1c,0x3,0x2e,0x25,0x23,0x8f,0x6b,0x94,0x92,0x51,0x38,0x62,0x4e,0x7c,0xd1,0xf1,0xbd,0x8f,0x7c,0xc,0xfc,0xd9,0xf6,0x5e,0xc7,0x7d,0xe4,0x79,0x9f,0xc3,0x43,0xfd,0x2c,0x3b,0xfb,0x63,0xaa,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xe5,0x92,0x45,0x80,0x4d,0x26,0x93,0xc9,0x74,0xc5,0x25,0xff,0xb1,0xdf,0x5a,0x55,0x97,0xd2,0xc6,0x30,0x8,0x47,0x47,0x9d,0x27,0xa8,0xa3,0x60,0xa0,0x56,0x54,0x4c,0x4b,0xb5,0xe4,0x64,0xc2,0xd6,0x51,0xe,0x5,0x9,0x8d,0xa0,0xd,0x41,0x35,0x1a,0x97,0xa0,0x5,0xd6,0x8a,0xf5,0x6a,0xc5,0xae,0xae,0xcc,0x4b,0xc3,0x83,0xb2,0x8e,0x61,0xbd,0x82,0xe7,0xe5,0x61,0x88,0x1b,0xcd,0x7b,0xac,0xe,0x2e,0x50,0x27,0x9d,0xf7,0xf8,0xcc,0x57,0x1e,0xc1,0x7d,0xf7,0xbc,0x1e,0xaf,0xb9,0xed,0x15,0x47,0xde,0xfb,0xb6,0x57,0xde,0x84,0x9b,0xaf,0x3b,0x85,0x1f,0x3c,0x7f,0x46,0xd7,0x62,0x13,0x2f,0x3,0xa7,0xae,0xc7,0xfa,0x60,0x1f,0x5d,0xbf,0xd4,0xbe,0xb6,0x71,0x6c,0xa,0x45,0x6a,0xab,0x28,0x63,0x41,0xd7,0x4d,0x4b,0xbb,0xb1,0xa3,0xf8,0xb0,0x74,0xd0,0x75,0x31,0xa2,0x55,0x2,0x65,0x9e,0xaf,0x85,0xf4,0x18,0x82,0xa1,0x18,0xf5,0xb9,0x11,0x4c,0xcd,0xe3,0xa0,0x6b,0xb1,0xf2,0x9e,0xc3,0xfa,0x0,0x9e,0xa1,0x24,0xc5,0xa5,0xbd,0xe,0x4d,0x48,0xa6,0x5a,0x9c,0x83,0x31,0x25,0x5,0x35,0xa9,0xeb,0x91,0xc7,0x1,0x3e,0x44,0x8a,0x22,0xa7,0xe,0x2e,0x78,0x2c,0xfb,0x63,0xb4,0xca,0xdb,0x1a,0x5c,0xf3,0xea,0x98,0x9b,0xc7,0x81,0xbd,0xf,0xf0,0x89,0xc6,0x22,0x52,0xb7,0xd0,0xfb,0x38,0x8e,0x6b,0xf4,0x8b,0x25,0x77,0x1e,0x76,0x68,0x20,0xb7,0x65,0x88,0x34,0x98,0x51,0x39,0x1a,0x2c,0xb0,0x98,0xdc,0x9c,0x91,0xd7,0xa1,0x3,0x3f,0x53,0xf4,0x5c,0x65,0x34,0x84,0x90,0xb4,0xb7,0x4f,0x86,0x37,0x0,0x71,0x25,0x3a,0x5d,0xd2,0x25,0x20,0x2b,0xe,0xc7,0x86,0xc5,0x62,0x17,0xb5,0x55,0x78,0x80,0xc7,0x31,0x80,0xe0,0x3,0xa,0xaf,0xc,0x13,0x78,0xa6,0xfb,0x29,0x40,0x2f,0xe7,0x51,0xbb,0xd,0x4b,0xcd,0xbc,0x9c,0x5c,0x74,0xe9,0x78,0xd1,0x2d,0xc9,0x29,0x17,0x7b,0x82,0x98,0x70,0xfa,0x1c,0x8,0xb0,0x74,0xde,0xe9,0xf0,0x4a,0xec,0x7a,0x5,0xd6,0x8e,0x63,0xcb,0x72,0x6e,0x31,0x75,0x3c,0x96,0xd2,0xf1,0xf7,0x66,0x38,0x4f,0x6e,0x58,0xe7,0x3d,0xfd,0x7f,0x76,0x1d,0x74,0xd9,0xb8,0xe4,0x91,0xae,0x27,0x3f,0x13,0x81,0xdd,0x95,0x34,0xc6,0xd2,0xf1,0xb5,0x73,0x7a,0xae,0xce,0x79,0x4,0xb9,0xd7,0xec,0x66,0xdc,0xb6,0x2,0x2c,0xce,0x47,0xb9,0x17,0xf2,0x19,0x2e,0x39,0x63,0x1c,0x7,0x75,0x70,0x4a,0x7c,0xba,0x61,0x1a,0xf4,0x91,0xb1,0x16,0xe9,0x3e,0x94,0xee,0x4f,0xe8,0xc8,0x4f,0xe3,0x81,0x70,0x73,0x2,0x9a,0x4c,0x26,0x93,0xc9,0x64,0x32,0x5d,0x2e,0x19,0x0,0x34,0x99,0x4c,0x26,0xd3,0x15,0xd7,0x38,0x50,0xdf,0x1c,0x40,0xfd,0x60,0xe0,0xfe,0x33,0x34,0x1a,0x64,0xa0,0xd1,0x3,0x3f,0x2d,0xf2,0x3a,0x87,0x94,0x7a,0xe4,0x3c,0xea,0xaf,0x13,0xe0,0xa0,0x78,0x65,0x66,0xc7,0xd4,0x36,0x35,0x5e,0xc,0x16,0xb7,0x53,0x6b,0xd,0xab,0xfd,0xb,0x18,0x87,0x35,0xba,0x7e,0x89,0x83,0xfd,0xb,0xc,0x41,0x32,0xd6,0x7,0xfb,0xec,0x8a,0xa3,0xe,0xc0,0xb,0xe7,0xce,0xa0,0xeb,0x16,0x14,0x8d,0x8c,0x53,0xd4,0xd2,0xbb,0x80,0x71,0x75,0x80,0x7e,0xb1,0xc4,0x47,0xff,0xe4,0x33,0xf8,0x1f,0x7f,0xf3,0xef,0x21,0xa5,0xcd,0x7f,0xa5,0x76,0x29,0xe2,0xde,0xd7,0xdd,0x42,0x0,0xd0,0x7b,0xa0,0x5,0x1a,0x23,0xf1,0x81,0xe2,0xc5,0x68,0xe8,0x52,0xc0,0x62,0x87,0x80,0x8e,0xeb,0x7a,0xed,0x31,0xbc,0x38,0x14,0x84,0xb0,0xc7,0xee,0xc6,0xc,0xd4,0xc6,0x50,0xa7,0xe3,0xf1,0x7,0xea,0xde,0xeb,0x97,0x9,0xd7,0x9f,0xdc,0xc5,0x2b,0xae,0xbf,0xa,0xd7,0x5e,0x75,0x1c,0x7b,0x7b,0x7b,0x68,0xb5,0x60,0x18,0xb,0x4e,0x9f,0xbd,0x80,0xa7,0x9e,0x7b,0x11,0x4f,0x3c,0x77,0x6,0xeb,0xb1,0x4e,0x80,0xd3,0x91,0x4b,0x2e,0x8f,0x83,0x42,0xa5,0x10,0xa6,0x5e,0xb9,0x5a,0x32,0x45,0x69,0xd1,0x70,0xf2,0xd8,0x2e,0xb9,0xcc,0x3a,0x2,0x97,0xae,0x1,0x67,0x2f,0x5c,0xe4,0xa8,0x36,0x45,0xa9,0xd1,0x1a,0xae,0x3d,0xbe,0x83,0x3b,0x5f,0x7d,0x13,0x6e,0xbe,0xe1,0x3a,0x74,0x29,0xe0,0xfc,0xf9,0xb,0x78,0xfe,0xcc,0x45,0x7c,0xeb,0x7b,0x4f,0xe3,0x2,0xc7,0xa4,0x5b,0x6b,0x28,0xc8,0xb4,0x14,0x5b,0x46,0xed,0xcb,0x6b,0xbc,0x20,0x7b,0xfd,0x35,0xa7,0xf0,0x9a,0x57,0xde,0x80,0x1b,0xaf,0xbb,0xa,0x7b,0xcb,0x5,0x86,0x71,0xc0,0x4b,0x2f,0x5f,0xc0,0xa3,0xdf,0x7f,0xa,0x4f,0x3e,0xff,0x32,0x7c,0x60,0x27,0x63,0xea,0x30,0xe,0x6b,0x75,0xa9,0x25,0x86,0x96,0xb2,0xb8,0x3c,0xe,0x6b,0xa4,0xd4,0x6b,0x5f,0x61,0x88,0x11,0xe0,0x5e,0x49,0x89,0x91,0x3b,0x47,0xfd,0x87,0x37,0x5e,0x7b,0xa,0x37,0x5d,0x7b,0x2,0x37,0x5c,0x77,0x15,0x76,0x96,0xb,0xa4,0x94,0xb0,0x5a,0xad,0x71,0xee,0xe2,0xa,0xcf,0xbe,0x70,0x6,0x3f,0x78,0xee,0x45,0x9c,0xb9,0x30,0x10,0x54,0xe5,0x75,0x5a,0x19,0x1c,0x9,0xc,0xd5,0xb4,0x7b,0xd1,0x1,0x65,0xa0,0xf3,0xa,0x21,0xa0,0x79,0x8f,0x8,0xe0,0xc4,0xde,0xe4,0x74,0x6c,0xb5,0xa0,0x94,0x82,0xe2,0x22,0xe,0xd6,0x34,0x30,0x53,0xd9,0x5,0xb8,0xbb,0xe8,0x70,0xc7,0x2b,0x6f,0xc4,0x2b,0x6f,0xbc,0x6,0x27,0x8f,0xed,0x2,0xe,0x38,0xfd,0xf2,0x39,0x3c,0xf9,0xcc,0x8b,0xf8,0xee,0xe3,0xcf,0xe0,0xe2,0x6a,0x9c,0x39,0xe9,0x28,0xee,0xab,0x3d,0x91,0x3e,0xa0,0xfa,0xaa,0x6e,0x49,0xb9,0xde,0xf4,0xbc,0x64,0x5d,0xfd,0x5,0x68,0xcc,0x45,0xe0,0xe7,0x55,0xc7,0x16,0xb8,0xe5,0x86,0x6b,0x70,0xfd,0x35,0x27,0x70,0x7c,0x6f,0x7,0xcb,0xbe,0x47,0x69,0xd,0x67,0xcf,0x5d,0xc4,0x33,0x2f,0x9c,0xc1,0x93,0xcf,0x9d,0xc1,0x85,0x75,0x3e,0xb2,0xda,0xd,0x80,0x5d,0x87,0x1,0xe3,0xd8,0x14,0xf2,0xe5,0x71,0x44,0x43,0xe3,0x7e,0xcd,0x8e,0xd7,0x9e,0xeb,0x46,0x87,0xa6,0x9c,0x6f,0x8,0x11,0xc3,0xb0,0xd6,0x58,0x7e,0xad,0x15,0x75,0x5c,0xeb,0x90,0xa,0x20,0x63,0x3d,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0xa6,0xcb,0x21,0x3,0x80,0x26,0x93,0xc9,0x64,0xfa,0x31,0x89,0xe3,0x81,0x1,0x70,0x3e,0x61,0x58,0x1d,0x50,0x74,0x31,0x13,0xa4,0x8b,0x81,0xfa,0xee,0xbc,0xa7,0xa1,0x6,0x89,0x5a,0xca,0xd2,0x6c,0x63,0x67,0x5a,0x29,0x5,0x61,0xd1,0x6d,0xc5,0x7f,0xd2,0x6f,0x7,0x1e,0x70,0x98,0x2b,0x75,0x3d,0x2e,0x9c,0x3b,0x83,0x94,0x3a,0x8c,0x3c,0x62,0x0,0x7,0x8c,0x3,0xc1,0x9e,0x71,0x18,0x90,0x52,0x8f,0xf5,0xea,0x0,0xa9,0xef,0xe1,0xe0,0x30,0xe,0x6b,0xf4,0xcb,0x1d,0x5c,0x38,0xff,0x32,0x62,0x8c,0x70,0x6e,0x7,0xdf,0xf9,0xfe,0x53,0x78,0xe2,0xa9,0x67,0x70,0xfb,0xad,0xb7,0x1c,0x79,0xff,0x3b,0x6e,0xbd,0x5,0xf5,0x53,0x5f,0x25,0x47,0x99,0xf,0xec,0xb4,0xcb,0x3a,0xce,0xf1,0x91,0xf7,0xbf,0xd,0x6f,0x7a,0xfd,0xed,0xea,0xa4,0x6a,0xad,0x62,0xb5,0x1e,0xf1,0xbf,0xfe,0xf6,0x1f,0xe1,0xc5,0xd3,0x67,0x28,0x7a,0xeb,0x3c,0xaa,0x23,0x20,0x9a,0x87,0x35,0x9c,0xf7,0x58,0xa6,0x80,0x7,0xee,0x7f,0x3,0xde,0x7a,0xcf,0x9d,0x38,0x79,0xfc,0x38,0x62,0xdc,0xee,0x80,0xac,0xb5,0xe2,0xfc,0xc5,0x7d,0x7c,0xfd,0x5b,0x8f,0xe2,0xcf,0xbe,0xf4,0x8,0x5e,0xbe,0x40,0x80,0x2f,0x8f,0x3,0x0,0xa0,0xeb,0x17,0x28,0x25,0xeb,0xba,0x6e,0x6b,0xe4,0x34,0x74,0x70,0xb8,0xe7,0xb5,0xb7,0xe0,0xd7,0x7e,0xf1,0xa7,0xe0,0xe0,0x14,0xae,0x35,0x0,0xbf,0xf3,0xd1,0x4f,0xe1,0xa1,0xef,0x3d,0x8b,0x5a,0x32,0x6e,0x38,0xb5,0x8b,0xf,0xbe,0xef,0x6d,0x78,0xed,0xab,0x5f,0x89,0x45,0xdf,0x6d,0xbc,0x77,0x6b,0xc0,0xfe,0xc1,0x1,0xbe,0xfd,0xdd,0xef,0xe3,0x4f,0xbf,0xf8,0x30,0x9e,0x79,0xf1,0x2c,0x3,0xa1,0x82,0x7e,0xb1,0xc4,0x38,0xe,0x8,0x31,0xe2,0x96,0x6b,0x4e,0xe0,0xfd,0xef,0x78,0x3,0xee,0xbc,0xe3,0x36,0x2c,0x17,0x8b,0x23,0xf5,0x6f,0xb9,0x14,0x3c,0xf3,0xdc,0x8b,0xf8,0xe3,0x4f,0x7d,0x1e,0x8f,0x3c,0xfe,0x3c,0xa,0x3b,0x1,0x63,0xa0,0x21,0x10,0x38,0xe8,0x6a,0x2d,0xd,0xc3,0xf4,0x3c,0xee,0x31,0x39,0x18,0x53,0xd7,0xeb,0x90,0xc6,0x55,0x27,0x76,0xf0,0xde,0xfb,0xee,0xc2,0x1b,0xee,0x7c,0x35,0xae,0x3e,0x75,0xe2,0x8,0xb8,0x9d,0x6b,0xbd,0x1e,0xf0,0xfc,0x8b,0x67,0xf0,0x8d,0xef,0x7c,0x1f,0x9f,0xfd,0xda,0x77,0x71,0xee,0xc2,0x45,0x85,0xd0,0x31,0x26,0x1a,0x65,0x59,0xec,0x68,0x6c,0x3d,0x76,0x3d,0x22,0x8f,0xa3,0x94,0x92,0xb1,0xbb,0xb3,0xc4,0x3f,0xfe,0xcd,0x5f,0xc2,0xde,0xee,0xe,0x3b,0xf9,0xe8,0x3e,0x7f,0xeb,0xdb,0xdf,0xc3,0x6f,0xff,0xc1,0x9f,0xa3,0x80,0x0,0xe1,0x7,0xdf,0xfb,0x56,0xdc,0x7d,0xe7,0x6d,0x38,0x7e,0x6c,0x57,0x7,0x31,0xa6,0x7b,0xd8,0x70,0xee,0xfc,0x79,0x7c,0xf1,0x6b,0xf,0xe3,0x93,0x9f,0xff,0x26,0xf6,0x57,0x3,0x43,0xed,0x6,0x1f,0xa7,0xcf,0x87,0xb8,0xe5,0xbc,0xf,0x28,0x35,0x53,0x64,0x1a,0xd,0x31,0x71,0x74,0x39,0x52,0xbc,0xfe,0xe4,0xf1,0xe3,0x78,0xd3,0x1d,0x37,0xe1,0xad,0x6f,0xbc,0x13,0x37,0xdd,0x70,0xd,0xba,0x94,0xe0,0xfd,0xd1,0x4f,0x4f,0x6b,0xd,0xc3,0x30,0xe2,0x99,0xe7,0x5f,0xc2,0x89,0xe3,0x7b,0x5b,0x3f,0x5d,0xd,0x4e,0x1d,0x99,0xb5,0x16,0x94,0x32,0xaa,0x2b,0x35,0x8f,0x83,0x3a,0x46,0xbd,0x73,0x80,0xf3,0x70,0x3c,0xf2,0x1,0xe9,0xb6,0xc,0x1,0xad,0x14,0x64,0xfd,0x6c,0xd2,0x53,0x26,0x11,0x60,0x7,0x9b,0x1,0x36,0x99,0x4c,0x26,0x93,0xc9,0x64,0xba,0x5c,0x32,0x0,0x68,0x32,0x99,0x4c,0xa6,0x2b,0xff,0x2f,0x1f,0x86,0x13,0x2,0xf,0xa,0x2f,0x99,0x96,0x92,0xe1,0x40,0x83,0xa,0x8d,0x5d,0x6f,0x0,0xb4,0x43,0x4e,0xe2,0x81,0x4,0x9,0x30,0x75,0xbd,0x71,0xa4,0x73,0xab,0x18,0x10,0x95,0x3c,0xd2,0x6a,0x2a,0x47,0x61,0x2f,0x9e,0x3b,0x43,0x2e,0xa4,0xf5,0x8a,0xd6,0x87,0x39,0xba,0x4a,0xc3,0x24,0xc0,0x58,0x57,0xd8,0x97,0xc1,0x8b,0x94,0x30,0x94,0x51,0x1d,0x66,0x8e,0x87,0x37,0x2e,0x9c,0x3b,0x83,0x7e,0xb9,0x83,0xaf,0xfc,0xf5,0xb7,0xb6,0x2,0xc0,0x6b,0xae,0x3a,0x81,0x6b,0x8f,0x2f,0xf0,0xdc,0xcb,0xfb,0x4,0xa8,0x6a,0xe6,0xa8,0x25,0x81,0xa0,0x2e,0x6,0x2c,0x17,0xfd,0xc6,0xf7,0xd4,0xda,0x30,0xac,0x57,0x93,0xb3,0x91,0x7,0x26,0x8,0xe6,0x74,0x78,0xf3,0x6b,0x6e,0xc6,0x2f,0x7e,0xe0,0x3d,0xb8,0xfa,0xaa,0x93,0xff,0xc5,0xeb,0xec,0xbd,0xc7,0x89,0x63,0x7b,0x78,0xcf,0xdb,0xdf,0x8c,0x7b,0xee,0x7a,0xd,0x7e,0xff,0xe3,0x9f,0xc1,0xd7,0x1f,0x7d,0x9a,0x22,0xc4,0x8b,0xa5,0xc6,0x30,0xbb,0x45,0x8f,0x3c,0xae,0x75,0xf9,0x98,0xa0,0xd,0xb0,0x5c,0x2c,0x8e,0xbc,0x66,0x8,0xb4,0x68,0xfc,0xe0,0x3b,0xee,0xc6,0x4f,0xbe,0xe3,0x1e,0xec,0xee,0x2c,0xb7,0x5f,0x76,0x7,0xec,0xee,0x2c,0x71,0xef,0x3d,0xaf,0xc7,0xab,0x6f,0xbb,0x5,0x7f,0xf8,0x9f,0x3f,0x8f,0x87,0x1e,0x7d,0x4a,0x41,0x58,0xdf,0xf7,0x78,0xe0,0xad,0x77,0xe2,0x81,0x77,0xdd,0x7b,0x4,0x1e,0x6e,0x3c,0x2b,0x21,0xe0,0x96,0x9b,0xae,0xc7,0x3f,0xfc,0xd5,0x9f,0xc7,0x17,0xbe,0xf6,0x30,0x7e,0xff,0x4f,0xbf,0x4,0xef,0x3d,0x81,0x59,0xee,0xd3,0xab,0x0,0xca,0x38,0xea,0xa0,0x46,0xce,0xa3,0x8e,0x83,0x48,0x8c,0x76,0xd1,0x45,0xfc,0xfc,0x4f,0xbe,0x1d,0xf7,0xdd,0xf3,0x3a,0xec,0x2c,0x17,0x7f,0xab,0xe7,0xb4,0xef,0x3b,0xdc,0x72,0xf3,0xf5,0x78,0xc5,0x4d,0xd7,0xe1,0x5d,0xf7,0xdd,0x8d,0xcf,0x7c,0xfe,0x6b,0xf8,0xb3,0x2f,0x3d,0x8c,0xa1,0x34,0xd4,0xc2,0xeb,0xc5,0xb5,0x10,0xd8,0xe5,0x8,0x72,0xe6,0xee,0x48,0x89,0xc4,0x2e,0x16,0xb,0x2c,0xf,0xbd,0xdf,0x62,0x41,0x40,0xf2,0x6d,0x77,0xdf,0x81,0xf,0xbd,0xff,0xed,0xb8,0xea,0xe4,0xf1,0x1f,0x72,0xf,0x1d,0x4e,0x9e,0x38,0x8e,0x7,0x7f,0xf2,0xed,0xb8,0xeb,0xce,0x57,0xe3,0x5f,0xfc,0xee,0xc7,0xf1,0xdc,0xe9,0xf3,0x68,0xad,0x4c,0x31,0xd9,0x5a,0xd5,0xed,0x48,0x11,0xea,0x5e,0x1d,0x9d,0xe4,0xfe,0xa3,0xce,0xc7,0x7b,0x5f,0x77,0x1b,0x7e,0xee,0x7d,0xf7,0xe3,0xda,0x6b,0x4e,0xfd,0x17,0xe3,0xb5,0xce,0x39,0xf4,0x7d,0x87,0x5b,0x6f,0xb9,0xf1,0x12,0x5f,0xd1,0x36,0xfa,0x31,0x69,0x90,0xa7,0x62,0x58,0x1f,0xc0,0x39,0xc7,0x7f,0xd,0x58,0xee,0xec,0x72,0x27,0x22,0xa6,0xe3,0xf5,0x9e,0x9c,0xbd,0x70,0xc,0xb,0x47,0xfd,0x9c,0x4e,0xfd,0x7f,0x4,0x18,0x4d,0x26,0x93,0xc9,0x64,0x32,0x99,0x4c,0x97,0x47,0xd6,0xae,0x6c,0x32,0x99,0x4c,0xa6,0x2b,0x2e,0x81,0x6c,0xd2,0xff,0x55,0xb,0xf5,0x82,0x35,0x1e,0xe3,0x90,0xbe,0x37,0xc7,0x0,0x40,0xc7,0x8,0xc8,0xea,0xc4,0xe0,0x2f,0x20,0x70,0xaf,0x9b,0x8c,0x2c,0x6c,0xfd,0x17,0xdd,0xc,0x74,0x48,0xfc,0x90,0x1c,0x70,0xe,0xe3,0xb8,0x46,0x6b,0xd4,0x5b,0x26,0x90,0xb0,0x8c,0x3,0x86,0xf5,0x1,0x4a,0xe1,0x8e,0xba,0x52,0x70,0xf6,0xf4,0xb,0x18,0xd6,0x7,0x0,0x28,0x86,0xeb,0x0,0xac,0xf7,0x2f,0xa2,0x96,0x82,0x83,0x8b,0x17,0xf0,0xcd,0xef,0x3c,0x86,0xf5,0x7a,0x38,0xf2,0xde,0x31,0x6,0xdc,0x74,0xdd,0x29,0x1d,0x5a,0x10,0xf8,0xe5,0x3d,0xb9,0xf9,0xb6,0xad,0x9d,0x7a,0x1f,0xd0,0xf5,0x3d,0xa,0x77,0xcd,0x85,0x10,0x30,0xac,0x57,0x58,0x1f,0xec,0xe3,0xbd,0xf7,0xde,0x89,0x5f,0xff,0xe5,0x9f,0xfd,0x5b,0xc1,0xbf,0xc3,0x3a,0x7e,0x6c,0x17,0xbf,0xfa,0xe1,0x7,0x70,0xcf,0x1d,0x37,0xe9,0xa0,0x85,0x5c,0xc7,0xc6,0xc3,0x2a,0xc3,0xea,0x80,0x1c,0x7f,0xad,0x1d,0x71,0xa2,0x89,0xba,0x18,0xf0,0x6b,0x3f,0xf7,0x2e,0xfc,0xec,0xfb,0xee,0xbf,0x24,0xfc,0x3b,0xac,0x93,0xc7,0xf7,0xf0,0x2b,0x3f,0xf7,0x1e,0xdc,0x75,0xdb,0xd,0x80,0x73,0xe8,0x82,0xc3,0xaf,0x7d,0xf0,0x1d,0xf8,0xc0,0x3,0x6f,0xff,0xa1,0xf0,0xef,0xf0,0xb5,0x7c,0xc7,0xbd,0x77,0xe1,0x43,0xef,0x79,0x13,0x8f,0x78,0x2c,0x8,0x54,0x32,0x90,0x4c,0x5d,0xcf,0x83,0x26,0xe,0xdd,0x62,0x41,0xf1,0x66,0x4f,0x4e,0xbd,0x5b,0x6f,0xbc,0x1a,0xff,0xf8,0x1f,0xfc,0x2,0xde,0xfb,0x8e,0x37,0xff,0xad,0xe1,0xdf,0x5c,0xce,0x39,0x1c,0x3f,0xb6,0x8b,0xf,0xbe,0xff,0x9d,0xf8,0x47,0x7f,0xff,0x43,0x38,0xb5,0xb7,0xe0,0x28,0x30,0x8d,0x7d,0xa4,0x6e,0xa1,0x63,0x2c,0xb4,0xd0,0x3b,0xd,0x75,0x6c,0x73,0xd7,0xd5,0x5a,0xf1,0xae,0x37,0xdd,0x81,0x5f,0xfd,0xf0,0xfb,0x7e,0x28,0xfc,0x3b,0xac,0x9b,0x6f,0xb8,0x16,0xff,0xf0,0x57,0x3e,0x80,0x53,0xc7,0x77,0x69,0xd0,0x84,0xdd,0x8e,0x0,0xb4,0x1b,0xd2,0xcb,0x48,0x8a,0xf7,0x3c,0xb0,0x91,0xd1,0x77,0x1d,0x7e,0xe5,0x67,0xde,0x8e,0x5f,0xff,0xc8,0x83,0xb8,0xee,0xda,0xab,0x2e,0x53,0xb7,0x1e,0x7d,0xe,0xe5,0x1a,0x50,0x67,0x27,0xbd,0xee,0x7a,0xb5,0x3f,0xd,0xd0,0xcc,0x3e,0xcf,0x4,0x28,0x8b,0x7e,0xe,0x5b,0xab,0xc8,0xe3,0x40,0xeb,0xd6,0xce,0xc3,0x7,0x1a,0xc7,0x91,0x91,0x10,0x93,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xe5,0x93,0x1,0x40,0x93,0xc9,0x64,0x32,0x5d,0x79,0xb9,0x69,0xe9,0x93,0xa2,0xbc,0xf4,0xaf,0x23,0x19,0x36,0x68,0xb5,0xf2,0x52,0x6a,0xd3,0x78,0x27,0x30,0xb9,0xaa,0xe,0x8f,0x86,0x50,0xac,0x70,0x3b,0x30,0xa0,0x91,0xb,0xea,0x4c,0xb,0x21,0xb2,0x53,0x89,0xfe,0xb7,0xe4,0x91,0x17,0x81,0x57,0xbc,0xc8,0xea,0xb1,0xd8,0x3d,0x46,0x4b,0xaf,0x7c,0x1c,0xcb,0xdd,0x63,0xd8,0xd9,0x3d,0x86,0x9d,0xbd,0xe3,0xec,0x12,0xa4,0xe8,0x62,0xd2,0xee,0x41,0xe0,0xf1,0xa7,0x5f,0xc0,0xfe,0xc1,0xea,0xe8,0x69,0x3a,0x87,0x1b,0xaf,0x39,0x81,0xd6,0xa8,0x17,0x6d,0x75,0x70,0x11,0xe3,0x7a,0x85,0x56,0x2b,0xfa,0x9d,0xbd,0xad,0x20,0xa6,0xb5,0xa,0xe7,0x23,0xf7,0xb9,0x35,0x82,0x93,0x68,0x58,0xf6,0x1d,0x3e,0xf0,0xbe,0xfb,0xd1,0x75,0xe9,0xef,0x7c,0xd9,0x17,0x7d,0x87,0x5f,0x78,0xf0,0x9d,0x38,0xbe,0x4c,0x14,0x2f,0xe,0x91,0xfb,0xf,0x9,0x1a,0x75,0xcb,0x1d,0x1d,0x68,0xf1,0x61,0xfb,0xfb,0x3c,0xf0,0xae,0xb7,0xe2,0xde,0xbb,0xef,0xd8,0x0,0x84,0xb4,0x68,0x5b,0x51,0xca,0xa5,0xa1,0xcd,0x72,0xd1,0xe1,0x23,0x3f,0xf3,0x13,0xb8,0xfe,0xd4,0x31,0xfc,0xfd,0xf,0xbf,0x17,0x6f,0x7e,0xc3,0x6b,0x37,0xe0,0x2c,0x80,0x4b,0xaf,0x39,0xcb,0xbd,0xf4,0x1e,0x3f,0x71,0xdf,0x1b,0x71,0xd7,0x6d,0x37,0x72,0xaf,0x1c,0x74,0x31,0x3a,0x84,0x40,0xe7,0xc2,0xff,0x13,0x22,0x85,0x1c,0x5e,0xfb,0xca,0xeb,0xf0,0x5b,0xff,0xc3,0xcf,0xe1,0xc6,0x1b,0xae,0xfd,0xd1,0x1f,0x5b,0xe7,0xf0,0xca,0x9b,0x6f,0xc0,0xff,0xf4,0x9b,0x1f,0xc1,0xad,0x37,0x5d,0x4b,0xc3,0x22,0xc,0x75,0xe5,0xf8,0x4,0xc2,0x9,0x98,0xdb,0x76,0x3a,0x37,0x5c,0x7b,0x15,0x7e,0xf1,0x3,0xef,0x46,0x3f,0xbb,0x97,0xa5,0x56,0xec,0x1f,0xac,0x70,0xf6,0xdc,0x5,0x1c,0xac,0xd6,0x97,0xbc,0xe,0x37,0xdd,0x70,0x2d,0xfe,0xde,0x7,0xde,0x89,0x2e,0xf5,0xfa,0x19,0x90,0xf7,0x93,0x31,0xd,0x5a,0x4,0x4e,0xf0,0x21,0x60,0x6f,0xef,0x38,0x7e,0xf5,0x83,0x3f,0x81,0x77,0xde,0xf7,0xc6,0x4b,0x46,0xc5,0xff,0xae,0xd7,0x42,0x80,0x9e,0x73,0x6e,0x36,0x90,0xe2,0x79,0x39,0x18,0x38,0xb8,0x78,0xe,0xc3,0xea,0x0,0xd,0xd,0xe3,0x7a,0xa5,0x3,0x2a,0x74,0x6d,0x9c,0xae,0x16,0x37,0x59,0xd2,0x6e,0xe0,0x1,0x90,0x69,0xb9,0xdb,0x64,0x32,0x99,0x4c,0x26,0x93,0xc9,0x74,0x79,0x64,0x11,0x60,0x93,0xc9,0x64,0x32,0x5d,0x71,0xe9,0x7f,0xf0,0x73,0xcb,0x57,0xab,0x95,0xba,0xc3,0x62,0x84,0x73,0xd0,0x9e,0x3f,0x89,0x2e,0x3a,0x86,0x4d,0xde,0x4f,0xe,0xa1,0x5a,0x2b,0x2,0x83,0x82,0x52,0xca,0xf,0x69,0xb,0x6b,0xba,0x36,0x2c,0xcb,0xb5,0xce,0x7b,0x54,0x6,0x86,0xfb,0x17,0xcf,0x21,0x84,0x88,0xe5,0xee,0x31,0x39,0x38,0xc4,0x98,0x34,0x82,0x5b,0x19,0x38,0x7a,0xe7,0xb1,0xd8,0xd9,0xa3,0x55,0xd5,0x6e,0x81,0x9c,0x7,0xf4,0xcb,0x1d,0x72,0x29,0x7a,0x8f,0x33,0x2f,0x9f,0xc1,0xa9,0x2d,0x6e,0xae,0x6b,0xaf,0x3e,0x89,0x71,0x58,0x91,0x23,0x8a,0xd7,0x54,0x87,0xf5,0xa,0xa1,0x14,0xd4,0xba,0xe5,0xa8,0x5b,0x3,0x5a,0xd1,0x5,0xdb,0xd6,0x1a,0xea,0x7a,0x85,0xb8,0xe8,0x8e,0x0,0x33,0x80,0xdc,0x55,0xeb,0x21,0xe3,0xec,0xb9,0x73,0x58,0xad,0x6,0x38,0xef,0x71,0xfc,0xd8,0x1e,0x8e,0xef,0xed,0x20,0x84,0xa3,0xff,0x7f,0xbe,0x93,0x27,0x8e,0xe1,0xc1,0x77,0xbd,0x5,0xbf,0xfb,0x89,0xbf,0xa2,0xf1,0x8f,0x5a,0x34,0x32,0xda,0x5a,0x85,0xe3,0x58,0x66,0x61,0xb8,0x79,0x58,0xd7,0x5d,0x7d,0x82,0xf,0xb3,0xe1,0xcc,0xd9,0xf3,0xf8,0xf6,0xa3,0x4f,0xe0,0xbb,0x4f,0x3c,0x87,0x73,0xe7,0x2f,0xc0,0x87,0x88,0xeb,0xaf,0x3e,0x8e,0xfb,0xef,0xb9,0x13,0xaf,0xb8,0xf1,0xda,0x23,0x80,0xf3,0xe4,0x89,0x63,0xf8,0xad,0xff,0xfe,0x41,0x9c,0x3c,0x3e,0xc1,0xcf,0x52,0x2b,0x1e,0x7b,0xfc,0x29,0x7c,0xe1,0xaf,0xbf,0x8d,0xd3,0xe7,0xe,0xb0,0x48,0x1,0xb7,0xdc,0x74,0x2d,0xee,0x7b,0xd3,0x9d,0xb8,0xfa,0xd4,0xd1,0xeb,0xd9,0xa5,0x84,0xf,0xbc,0xf7,0x3e,0x7c,0xe7,0x5f,0x7f,0xc,0x63,0x91,0x65,0xe3,0x82,0x71,0x1c,0x34,0x6,0x2b,0xce,0xd2,0x57,0x5e,0x77,0x2,0xbf,0xf1,0xcb,0x1f,0xc0,0xb1,0xbd,0x9d,0xad,0xe7,0x92,0x4b,0xc1,0xb9,0x73,0x17,0xf0,0xcc,0xf3,0xa7,0x71,0xe6,0xdc,0x45,0x8c,0xc3,0x1a,0x8b,0x3e,0xe1,0xe6,0x1b,0xaf,0xc7,0x35,0x57,0x9d,0xb8,0xa4,0x5b,0xf0,0xe4,0xf1,0x3d,0xfc,0xc6,0x47,0x1e,0xc0,0x3f,0xff,0xbd,0x4f,0xe2,0x7,0xcf,0x9d,0xa6,0x27,0xd9,0x79,0x1a,0x67,0x61,0x67,0x9b,0xe3,0xa5,0x6a,0x6c,0x79,0x32,0xe7,0xe,0xce,0x61,0x1c,0xf1,0xad,0x47,0xfe,0x6,0x5f,0x7c,0xe8,0x51,0x3c,0x73,0xfa,0x22,0xf6,0xf,0x56,0xe8,0x93,0xc7,0x5d,0xaf,0xbe,0x19,0xef,0x7f,0xf7,0xbd,0xb8,0x66,0x8b,0xdb,0xf3,0xf5,0xaf,0xb9,0x15,0xaf,0xbe,0xf9,0x9b,0x78,0xf4,0x7,0x2f,0x0,0x99,0xc0,0x75,0xad,0x45,0x97,0x9a,0x5b,0xa3,0x4e,0xc7,0x14,0x23,0x7e,0xfa,0xfe,0xd7,0xe1,0x2d,0x77,0xdf,0xb9,0xd5,0x89,0x8,0x10,0xb8,0x3d,0x73,0xf6,0x1c,0x9e,0x79,0xfe,0x25,0x9c,0x3d,0xbf,0x8f,0xf5,0x7a,0xc0,0xee,0xce,0x12,0xd7,0x5c,0x75,0x2,0xd7,0x5c,0x75,0x12,0xc7,0x8f,0xed,0x6c,0x7d,0xee,0x68,0xa8,0x87,0x56,0x89,0xc7,0xb6,0xa6,0x35,0xe6,0x40,0xb1,0x78,0x1f,0x2,0xf6,0x2f,0x9c,0xc3,0x72,0xf7,0x98,0x7e,0x1d,0x3d,0xcb,0x15,0x53,0xc2,0xd7,0x31,0x74,0x77,0xba,0x14,0x5d,0x2a,0x2f,0x75,0x37,0x6a,0x9d,0x74,0x6,0x0,0x4d,0x26,0x93,0xc9,0x64,0x32,0x99,0x2e,0x9b,0xc,0x0,0x9a,0x4c,0x26,0x93,0xe9,0x8a,0x4b,0x80,0x9e,0x93,0xea,0x3e,0xe7,0xe1,0x23,0x50,0x5b,0xc3,0xb8,0x3a,0xa0,0xe5,0xdd,0x71,0x24,0x27,0x5a,0x74,0x1c,0x13,0xec,0x90,0xf3,0x88,0xe4,0x3d,0x4a,0xa9,0xa,0x1,0x53,0x97,0xa8,0x97,0x6e,0x4b,0x4,0xb8,0x81,0x5e,0x53,0xe4,0xd9,0x29,0x58,0x4b,0x41,0xbf,0xd8,0x41,0xab,0xd,0x31,0x76,0xda,0x9d,0x26,0x23,0x15,0x8b,0x9d,0x3d,0x8a,0x50,0xa6,0x4,0x34,0x1a,0x20,0x11,0x20,0x19,0x53,0x87,0x6e,0xb1,0x44,0x2c,0x1d,0x0,0x5a,0x36,0x8d,0x29,0x61,0x18,0xb7,0xbb,0xdf,0x16,0x8b,0x85,0xf6,0xb1,0xe5,0x2,0x78,0x5e,0x38,0xe,0x71,0xfb,0xf8,0x2,0x9c,0x43,0x6b,0xd4,0x93,0x58,0x78,0x5d,0x35,0x75,0x3d,0xc1,0xbc,0x79,0x9c,0xb9,0x56,0x3c,0xfe,0x83,0x67,0xf1,0x57,0x5f,0x7d,0x4,0xf,0xff,0xcd,0x13,0xb8,0xb0,0x26,0xe8,0x53,0x6b,0xc1,0xa2,0x5f,0xe0,0xd5,0x37,0x9e,0xc4,0x7,0xdf,0x77,0x1f,0x6e,0xba,0xfe,0x9a,0x23,0x6f,0xf1,0xda,0xdb,0x6f,0xc1,0xb2,0xff,0xa,0xe,0xd6,0x3,0x2,0xf,0x36,0x0,0x14,0xe5,0x74,0x89,0x87,0x55,0x52,0x12,0xfe,0x7a,0x44,0xb9,0x14,0x7c,0xf1,0x6b,0x8f,0xe0,0x13,0x9f,0xfb,0x26,0xce,0xef,0x1f,0xf0,0xca,0x32,0xc5,0x40,0x1f,0x7b,0xfa,0x25,0x7c,0xe1,0x9b,0x8f,0xe1,0x23,0x3f,0x75,0x2f,0xde,0xfe,0x96,0x37,0x1c,0x81,0x80,0xa7,0x4e,0x1c,0xd3,0xbf,0x3f,0x73,0xf6,0x2,0xfe,0xd3,0xa7,0xbe,0x80,0xaf,0x3c,0xfc,0x7d,0x5e,0xf7,0x5d,0xa1,0x5b,0xec,0xe0,0x91,0x27,0x5f,0xc0,0x97,0xbe,0xf5,0x38,0x7e,0xf1,0x81,0xb7,0xe0,0xee,0xd7,0xdd,0x7e,0xe4,0xfd,0x5f,0x71,0xd3,0x75,0xb8,0xf9,0x9a,0x63,0x78,0xea,0xa5,0xb,0xb4,0x52,0x9c,0x7a,0x38,0x1f,0xe0,0xbd,0xa7,0x15,0xe0,0x7e,0x81,0x45,0xf4,0xf8,0xd5,0xf,0xbd,0x6f,0x2b,0xfc,0x6b,0xd,0x78,0xe2,0xa9,0xe7,0xf0,0x89,0xbf,0xf8,0x32,0x1e,0xf9,0xfe,0x33,0x70,0x3e,0x62,0xbd,0xde,0x47,0xf0,0x81,0x23,0xb4,0xc0,0xa9,0xbd,0x5,0xde,0xf2,0xba,0x57,0xe2,0x27,0xdf,0xf9,0x56,0x1c,0xdf,0xf2,0x1a,0xa7,0x4e,0x1c,0xc7,0x47,0x7e,0xfa,0x7e,0xfc,0xb3,0xdf,0xfb,0x24,0x86,0xd2,0x90,0x4b,0x86,0x73,0x41,0x47,0x42,0x3c,0x2a,0xd2,0x62,0xf9,0x43,0x67,0x2c,0x5e,0x3e,0x7b,0x1e,0xbf,0xff,0x89,0xcf,0xe1,0x6b,0x8f,0x3c,0xb6,0x31,0x54,0x32,0xe4,0x82,0x2f,0x3c,0xfc,0x4,0x1e,0x79,0xfc,0x39,0xfc,0xd6,0xaf,0x3c,0x88,0x9b,0x6f,0xd8,0xbc,0x87,0x29,0x45,0xbc,0xfd,0x9e,0x3b,0xf1,0xbd,0xa7,0x4f,0xc3,0x25,0x82,0x7f,0xde,0x5,0x94,0x9c,0x69,0x91,0x18,0x4,0xe8,0x5e,0x71,0xcd,0x2e,0xde,0xf9,0xb6,0xbb,0x2f,0x19,0x43,0x7e,0xfc,0xc9,0x67,0xf0,0xc9,0xcf,0x7f,0x13,0x8f,0x3e,0xf9,0x3c,0x2a,0xaf,0xf8,0xca,0x42,0xb4,0xf,0x1,0x5d,0xc,0xb8,0xf3,0xd6,0x9b,0xf1,0x4b,0x3f,0xfd,0x36,0x9c,0x9c,0xdd,0x37,0x7e,0x50,0x75,0x40,0x86,0xfe,0xc9,0x51,0xdc,0xb8,0x5f,0x62,0xb5,0xda,0x87,0x73,0x34,0x9a,0xb3,0xdc,0xd9,0xe3,0xc7,0x9a,0x40,0xbe,0x6b,0xc0,0x38,0xae,0xc9,0xfd,0xc7,0x10,0x50,0x62,0xdc,0xde,0x7b,0x8c,0x25,0x4f,0xdd,0x9f,0xde,0x3a,0x0,0x4d,0x26,0x93,0xc9,0x64,0x32,0x99,0x2e,0x97,0x2c,0x2,0x6c,0x32,0x99,0x4c,0xa6,0x2b,0xae,0x92,0x47,0xea,0xdc,0xe3,0xe,0x3a,0xcf,0x71,0x4e,0x89,0x12,0x96,0x32,0x12,0xd4,0xd0,0x5e,0x33,0x8a,0xee,0xa6,0xae,0xa3,0x88,0x60,0xad,0xe4,0xc,0xd4,0x1e,0xb2,0xba,0x15,0x54,0x39,0x6e,0x11,0xf4,0x3e,0xa8,0xab,0xc8,0x73,0x54,0x74,0xb5,0x7f,0x1,0x40,0x43,0x4c,0x89,0xfb,0xfe,0x3a,0x7e,0xff,0x5,0x8d,0x63,0xb0,0x43,0x30,0xa6,0x84,0x7e,0xb1,0x83,0x52,0x32,0x62,0xd7,0x23,0x75,0x3d,0x5a,0xab,0x48,0x7d,0x8f,0x7e,0xb9,0x4b,0x90,0xd2,0x7,0xac,0xd7,0xeb,0xad,0xe7,0x1a,0x3d,0xbd,0x7f,0xe5,0x88,0x71,0xc9,0x19,0x21,0x4,0x8d,0x2,0x1f,0x39,0x66,0xe7,0xe0,0xbc,0x43,0xce,0x3,0xbc,0xf3,0xf0,0x8e,0xfa,0xd0,0xa,0xf7,0x23,0x2,0xc0,0x4b,0xa7,0x5f,0xc6,0x6f,0xff,0xdb,0xff,0x80,0xff,0xe5,0x9f,0xff,0x3e,0x3e,0xfd,0xc5,0x87,0x70,0x71,0x4,0x2d,0x15,0x3b,0xc0,0x3b,0x8f,0x61,0x1c,0xf0,0xed,0x27,0x5f,0xc0,0xbf,0xfa,0xe8,0x5f,0xe2,0xe2,0xfe,0xd1,0x68,0xf2,0x89,0xbd,0x1d,0x9c,0x3c,0xb6,0x83,0x18,0x13,0x9c,0xf,0x88,0x32,0xa6,0xc1,0xc0,0xd1,0xe9,0xfd,0x38,0x7a,0x3e,0xe3,0x98,0xf1,0x1f,0x3f,0xf9,0x57,0xf8,0xc3,0x4f,0x7f,0x1d,0x17,0xf6,0x57,0xec,0xee,0xa2,0xfb,0x54,0x4a,0x41,0x1e,0x7,0x34,0x38,0xfc,0xf1,0x67,0x1e,0xc2,0x8b,0x2f,0xbd,0x7c,0xc9,0x67,0xe0,0xb1,0x27,0x9e,0xc1,0xff,0xf9,0xef,0x3e,0x81,0xaf,0x3c,0xf2,0x4,0x62,0xd7,0x33,0xe4,0xed,0x75,0x91,0xf9,0xcc,0xf9,0x8b,0xf8,0xdd,0x3f,0xf9,0x22,0x9e,0x7c,0xea,0xd9,0xa3,0xd7,0x34,0x4,0xbc,0xf1,0xce,0xdb,0xf4,0xfa,0x95,0x32,0x42,0x46,0x29,0x4,0x26,0x3d,0xf8,0xce,0x37,0xe2,0x15,0x37,0x5d,0x7f,0xf4,0xd9,0x2b,0x15,0x9f,0xfa,0xdc,0x57,0xf1,0xbf,0xff,0xce,0x9f,0xe0,0xdb,0x4f,0x10,0xf8,0x1a,0x87,0x15,0x42,0x88,0x80,0xf3,0x7a,0x1d,0x5e,0xbe,0xb8,0xc6,0x7f,0xfe,0xc2,0xc3,0xf8,0xdf,0xfe,0xe5,0x1f,0xe0,0xdb,0x8f,0x3e,0xbe,0x35,0x8e,0x7a,0xdb,0x2b,0x6f,0xc2,0xbb,0xdf,0xf2,0x5a,0x0,0xe0,0x38,0x2b,0x75,0xe,0x52,0x84,0x3a,0x90,0xdb,0xf4,0x12,0xe7,0xff,0xdc,0xb,0xa7,0xf1,0xcf,0xfe,0xdd,0xc7,0xf1,0xcd,0xc7,0x9e,0x21,0x30,0xe6,0x9,0xe0,0xf9,0x10,0x38,0xa2,0x5e,0x70,0xfa,0xec,0x79,0xfc,0xfb,0x8f,0x7d,0x6,0xc3,0x70,0xd4,0x8d,0x79,0xfb,0xad,0x37,0x23,0x6,0x8a,0xfd,0x86,0x98,0xd0,0xf7,0x4b,0xee,0x4,0xa4,0xf7,0x8e,0x21,0xe2,0xe7,0x7f,0xea,0xed,0x5b,0x87,0x5c,0x6a,0x6d,0xf8,0xd4,0x67,0xbf,0x86,0x7f,0xf2,0x6f,0x3e,0x86,0x87,0xbe,0xfd,0x18,0x1a,0x9c,0x7e,0x16,0x6b,0xc9,0x1c,0x21,0xe,0x18,0xc6,0x8c,0x6f,0x3c,0xfa,0xc4,0xd6,0x78,0x3b,0x39,0x55,0xa1,0xc3,0x39,0x21,0x25,0x84,0x10,0x91,0xf3,0xc8,0xd7,0xd2,0xa1,0xeb,0x17,0x58,0xaf,0xf,0xe8,0x99,0x68,0xd,0xad,0x4e,0x6e,0x5c,0xf0,0x72,0xb0,0xb8,0x35,0x1b,0xd3,0x66,0xcf,0xf1,0x60,0x79,0x5d,0x93,0xc9,0x64,0x32,0x99,0x4c,0x26,0xd3,0xe5,0x91,0x1,0x40,0x93,0xc9,0x64,0x32,0x5d,0x71,0x49,0x3f,0x9b,0x8c,0x7b,0x54,0x6,0x7a,0xad,0x55,0xd4,0x42,0x2e,0xa6,0x10,0x13,0x3,0xb3,0x51,0xa1,0x46,0xc9,0x5,0x85,0xa1,0x81,0x3,0x1,0x4,0xef,0x3d,0x1,0x85,0xad,0x22,0xb0,0x10,0x53,0x87,0xd4,0x2f,0xf8,0xeb,0x83,0xae,0xc5,0xca,0x7b,0x38,0x38,0xb4,0xda,0x90,0xf3,0x88,0xae,0x5f,0xc0,0x2b,0xc8,0xe1,0xae,0xb2,0x18,0xd1,0x2f,0x76,0xd0,0x2f,0x96,0x14,0xad,0x4c,0x3d,0xd0,0x8,0xfa,0x44,0x76,0x5c,0xa5,0xb4,0x7d,0xcc,0xa2,0x54,0x5a,0x8c,0x75,0xce,0xa3,0xb0,0xd3,0x6e,0x1c,0xd6,0x68,0x97,0x20,0x6c,0x2,0x3e,0x62,0xea,0x1,0x7,0xc4,0xae,0xe7,0xc1,0x87,0x5,0x1c,0x1c,0xbe,0xf7,0xd8,0x13,0xf8,0x9f,0xff,0x8f,0xff,0x7,0x7f,0xf5,0x8d,0xc7,0xb1,0x5a,0x1d,0x20,0x75,0x3d,0x86,0xd5,0x3e,0x4a,0xce,0x28,0x85,0x62,0xa0,0x14,0xa1,0xe,0x78,0xf9,0xc2,0x1,0xbe,0xf5,0xdd,0xef,0x1f,0x79,0x8f,0x18,0x3,0xae,0x39,0x75,0x1c,0xb1,0xeb,0x50,0x39,0xfa,0x1b,0xb8,0xf,0x50,0xee,0xcb,0xa5,0xf4,0x99,0x2f,0x3e,0x84,0xcf,0x7d,0xe3,0x71,0x14,0x76,0x6a,0xe5,0x71,0xc4,0x38,0xc,0x28,0x79,0x44,0x88,0x91,0x5f,0xb3,0xe0,0xc2,0xfe,0xa,0x5f,0xfc,0xeb,0x87,0xb7,0xbe,0xc6,0xd3,0xcf,0xbd,0x88,0xff,0xeb,0xff,0xfd,0x24,0x5e,0x3c,0x73,0x1,0x0,0x78,0x24,0xa5,0x80,0x89,0x12,0x1c,0x8f,0x40,0x1c,0xac,0x33,0x3e,0xf1,0x99,0xaf,0x6d,0xed,0x16,0x7c,0xd5,0x4d,0xd7,0x72,0x67,0x24,0xf5,0xc8,0xa1,0xd1,0x73,0x15,0x63,0x87,0xeb,0xaf,0x3a,0x86,0xb7,0xdd,0xf3,0xfa,0x23,0xdf,0x53,0x6b,0xc5,0x5f,0x7c,0xe1,0x21,0xfc,0xc7,0x3f,0xff,0x2a,0x56,0xab,0x3,0xe4,0x3c,0xd2,0x7b,0x33,0x94,0xa2,0x65,0x5a,0x86,0xb0,0xc,0xa3,0x5e,0x38,0x73,0xe,0xbf,0xfd,0x7,0x7f,0x8e,0xef,0xfc,0xcd,0x13,0x47,0x5e,0xcf,0x39,0x87,0x77,0xdc,0x7b,0x17,0x76,0x17,0x74,0x1c,0xad,0x56,0x54,0x8e,0x90,0xcb,0x79,0x6d,0xd3,0xb9,0xf3,0x17,0xf1,0xaf,0x3f,0xfa,0x69,0x3c,0xf5,0xc2,0x59,0x7a,0x1e,0x67,0x6b,0xc5,0x12,0x53,0xaf,0x25,0x23,0xa6,0xe,0xdf,0x7f,0xf6,0x34,0xbe,0xff,0xe4,0xd3,0x47,0x5e,0x63,0x6f,0x67,0x81,0xeb,0x4e,0x1d,0xe3,0xc1,0x8c,0x82,0x52,0xb2,0x76,0x52,0xa2,0x35,0xdc,0x7a,0xe3,0x55,0x78,0xd5,0x2b,0x6e,0xda,0xfa,0x7c,0xfd,0xc5,0x17,0xbe,0x8e,0x8f,0x7d,0xf6,0x21,0x34,0x90,0x13,0xf5,0xe0,0xe2,0x79,0x94,0x71,0x64,0xf8,0x59,0x91,0xf3,0xa0,0x6e,0x40,0x1f,0xe2,0x76,0x17,0xa3,0x9b,0x3e,0x7f,0x12,0xf1,0xad,0xad,0xa2,0x5f,0xec,0x60,0x58,0xaf,0xd0,0x2f,0x96,0xb4,0xb8,0x1d,0xe4,0xfc,0x2a,0x83,0x7a,0xea,0xe2,0x44,0x6b,0xfa,0xd9,0x73,0xce,0x93,0xeb,0xaf,0xb5,0x19,0x84,0x26,0x28,0x6a,0x32,0x99,0x4c,0x26,0x93,0xc9,0x64,0xba,0x3c,0x32,0x0,0x68,0x32,0x99,0x4c,0xa6,0x2b,0xae,0x92,0xf3,0x4,0x99,0x1c,0x81,0x99,0x56,0xb,0xbc,0xf3,0xb3,0xf1,0x4,0x82,0x77,0xb4,0x64,0x4a,0x7d,0x78,0xd2,0x8b,0x47,0x31,0x4d,0x5a,0x16,0x2d,0x3c,0xe6,0x71,0xc9,0xba,0x30,0x27,0x51,0xc5,0xc2,0x91,0x43,0x7a,0x8d,0x10,0x13,0xad,0x95,0x7a,0x7,0x1f,0x68,0x31,0x56,0x96,0x65,0x65,0xc1,0xb5,0xeb,0x17,0xec,0x42,0x74,0xe8,0xba,0x5,0x6a,0xad,0xe8,0x17,0x4b,0x82,0x55,0x8e,0x0,0x50,0xbf,0xdc,0xc5,0x62,0xb9,0x8b,0xbd,0xbd,0xdd,0xad,0x6f,0xbf,0x5a,0x8f,0x48,0x5d,0xa7,0xee,0xb4,0x61,0x75,0xa0,0xd1,0xc9,0x3a,0x73,0xf5,0x4d,0x87,0x4b,0xf0,0x31,0x8f,0x6b,0x1e,0x3c,0xa9,0xda,0x59,0xf8,0xe8,0x63,0x4f,0xe0,0x9f,0xfc,0xdf,0x1f,0xc5,0xd9,0x55,0x21,0x28,0x98,0x3a,0xee,0x48,0x24,0xf7,0x58,0xe2,0x98,0x74,0xc9,0xe4,0xe2,0x2a,0x39,0xe3,0x89,0xa7,0x5f,0xdc,0xf2,0x1e,0xe,0x7d,0x97,0x74,0x94,0xa1,0x9,0x74,0xe3,0x45,0xd7,0x98,0x28,0xde,0xbc,0x4d,0xcf,0xbe,0x74,0x5e,0x57,0x94,0xb,0x43,0x2a,0x80,0x80,0x4d,0x1e,0x6,0x75,0x85,0x1,0xc0,0xa3,0x4f,0x3c,0x8b,0xbc,0xe5,0x1c,0x5f,0x7c,0xe9,0xc,0xc6,0xea,0xd0,0xd0,0x74,0xb9,0x37,0xc6,0x84,0x71,0x58,0xd3,0xeb,0xe6,0x91,0x7a,0x1d,0x6b,0xc5,0x63,0xcf,0x9e,0xc1,0xc5,0xfd,0x83,0x23,0xaf,0x71,0xe2,0xf8,0xae,0xe,0xbf,0xd0,0x7d,0x73,0xec,0x64,0x2c,0x78,0xd3,0x9d,0xaf,0xc2,0xee,0xce,0x51,0xe7,0xdb,0xe3,0x3f,0x78,0x16,0xff,0xe9,0x2f,0xbf,0xe,0x8,0x34,0x6e,0x80,0xf7,0x11,0x7d,0xbf,0x83,0xcc,0xae,0x54,0x71,0xb6,0xe5,0x3c,0x12,0x80,0x4d,0x1d,0x2e,0x1e,0xac,0xf0,0x7b,0x1f,0xff,0x1c,0xce,0x9e,0xbf,0x78,0xe4,0x35,0x4f,0x9d,0x38,0x8e,0xbb,0x6e,0xbb,0x11,0xd4,0x67,0xd9,0x90,0x62,0x37,0x45,0xdc,0x3d,0x1,0xe4,0xc3,0x7a,0xea,0xd9,0x17,0xf0,0xec,0xe9,0xb,0xe4,0x34,0xe5,0xe7,0x52,0x96,0x71,0x15,0xc2,0xf2,0xa,0x76,0x6b,0xc0,0x63,0x4f,0x6e,0x71,0x41,0xc6,0x88,0x93,0xc7,0x76,0x18,0xfa,0x39,0xbd,0x86,0xf2,0x7a,0xf7,0xdd,0x7d,0xc7,0xd6,0xe,0xc8,0x67,0x9e,0x7b,0x11,0x1f,0xfb,0xcb,0xaf,0xc3,0x31,0x4,0x97,0x8e,0xcd,0xd6,0x2a,0x3b,0x2a,0x27,0x37,0xde,0xb8,0x5e,0xd1,0xfa,0xf5,0x25,0x9c,0x78,0xfa,0x19,0xe6,0xcf,0xaa,0x3,0x70,0xb0,0x7f,0x1,0x8b,0xe5,0xe,0x8f,0xed,0x14,0x74,0xec,0xa8,0x15,0x90,0x5f,0xf2,0x88,0x9c,0x7,0x6,0xdd,0x45,0x3b,0x40,0xe9,0x71,0x73,0x0,0x9c,0x5e,0x97,0x56,0x46,0xfb,0x61,0x69,0x32,0x99,0x4c,0x26,0x93,0xc9,0x74,0x99,0x64,0x0,0xd0,0x64,0x32,0x99,0x4c,0x3f,0x56,0xc9,0x9a,0x28,0xc0,0x63,0x1f,0x6e,0x8a,0xf5,0xb6,0x56,0x51,0xf2,0x88,0xda,0x2a,0xc6,0x71,0xad,0xcb,0xb3,0x14,0x33,0x94,0xae,0xb3,0x6,0x17,0x22,0xb6,0x3,0x2b,0x47,0x3,0x11,0xeb,0x95,0xba,0xb1,0x9c,0x3,0x86,0xf5,0x1,0x8d,0x12,0xd4,0x86,0x5a,0x2a,0x7f,0x1d,0x1,0x90,0x3c,0xe,0x4,0x45,0x1c,0x39,0x9b,0x62,0x4c,0x9c,0x1e,0x96,0xbf,0xa7,0xc8,0x65,0xd7,0x2d,0x34,0x2e,0xeb,0x1d,0x70,0x7c,0x6f,0xb9,0xf5,0xfc,0xce,0x5f,0x3c,0x40,0x4c,0x3d,0xba,0x9e,0x3a,0xde,0x22,0xaf,0xa5,0xb6,0x4a,0xe7,0x78,0x58,0xe4,0x80,0x2,0x39,0xfe,0xbc,0x27,0xf8,0x19,0x13,0x86,0x5c,0xf1,0xcf,0xff,0xfd,0x27,0x91,0x41,0xf1,0xcc,0x18,0x13,0x52,0xd7,0x23,0xa5,0xe,0x31,0xd1,0xf8,0x5,0xad,0xaf,0x3a,0x85,0xa5,0x8b,0xe5,0x2e,0x86,0x7c,0x89,0x75,0x64,0x59,0xf1,0x75,0x50,0xc7,0x9a,0x5c,0xa0,0x56,0xeb,0x25,0xdd,0x57,0xb5,0x8c,0xa,0x8c,0xa4,0xf7,0x4d,0xfa,0x19,0x75,0x0,0x83,0xaf,0xdd,0xcb,0xe7,0xf,0x90,0xf3,0x51,0x0,0xe8,0x43,0x82,0x63,0x8,0x27,0x8b,0xcc,0xd3,0xfb,0xb5,0x69,0x4d,0xb6,0x64,0x5c,0xbc,0xb8,0x8f,0x33,0x2f,0x9f,0x3d,0xf2,0x1a,0x7d,0x4f,0xe7,0xee,0xbd,0x47,0x19,0xe9,0x79,0x20,0xc8,0x4,0xbc,0xf1,0xb5,0xb7,0x1e,0xf9,0xfa,0x52,0x2b,0xfe,0xe4,0x2f,0xbf,0xca,0xa0,0x8f,0x9e,0x2b,0xe7,0x69,0xb1,0x77,0x18,0x56,0x7c,0x5c,0x14,0xdb,0x95,0x73,0x91,0x8,0x6a,0x4a,0x3d,0x5e,0x3c,0x7b,0x1,0x9f,0xfd,0xd2,0x37,0x8f,0x80,0x66,0xe7,0x80,0x37,0xbd,0xee,0x56,0x1a,0xe1,0x88,0x9,0xb1,0xeb,0xd5,0x15,0x77,0x29,0x51,0xfc,0x3d,0xf3,0xfd,0xcd,0xa,0xf1,0x86,0xf5,0xc1,0xf4,0x4c,0x79,0x4f,0x4e,0xbc,0x3c,0xe2,0xd9,0x17,0xcf,0x1e,0x89,0x20,0x3b,0xe7,0x70,0x6c,0x77,0x81,0x98,0x3a,0x85,0xd4,0xf4,0x98,0x7a,0x78,0xef,0xf1,0xea,0x57,0xdd,0x78,0xf4,0xde,0xb5,0x86,0x3f,0xfb,0xfc,0x43,0x58,0x8f,0x4,0xe7,0x4a,0xce,0x3a,0x7a,0x13,0x62,0xe2,0x85,0x6b,0x72,0xe7,0x6,0x1f,0xe0,0xbc,0xd3,0x68,0xf3,0x96,0x93,0x98,0xdc,0xb3,0xad,0xb1,0x7b,0xd2,0x21,0x72,0x9f,0x66,0xc9,0x23,0x75,0x68,0xb2,0x9b,0x32,0x75,0x3d,0x7f,0xc6,0x39,0xd6,0xef,0x83,0xc2,0x7d,0xb9,0x56,0xf4,0x99,0x6f,0xa,0x31,0x1,0xeb,0x0,0x34,0x99,0x4c,0x26,0x93,0xc9,0x64,0xba,0x5c,0x32,0x0,0x68,0x32,0x99,0x4c,0xa6,0x1f,0x8b,0x4,0xae,0xb4,0xda,0x14,0x98,0x10,0x90,0x68,0xe4,0xe6,0x8a,0x14,0xa9,0x8d,0xc,0x79,0x1c,0xbb,0x3,0x5b,0xad,0x48,0xa9,0x47,0x3,0x75,0x1,0x52,0x5f,0x5d,0xdd,0xa,0xb,0x1a,0xf7,0x5,0x52,0x6f,0x5f,0xd3,0xbe,0x31,0xef,0x3,0x8d,0x45,0x74,0x3d,0x62,0xd7,0xb1,0x83,0x90,0x9c,0x76,0x12,0xe5,0x15,0x0,0x44,0xb1,0xda,0xe,0x21,0x4,0x84,0x18,0x79,0xbc,0x83,0xe0,0x14,0xf5,0xce,0x15,0x5c,0x77,0xd5,0x71,0xec,0xed,0x6e,0x77,0x0,0x3e,0xfd,0xe2,0x59,0x85,0x19,0x79,0x18,0x90,0x87,0x35,0xbb,0x16,0xf3,0x4,0xe1,0x66,0x72,0xce,0x93,0xfb,0x8f,0x63,0xb9,0x2,0x96,0x1a,0x3c,0xe0,0x13,0xa4,0xeb,0xe,0x12,0x8b,0x2e,0x19,0xc1,0x47,0xee,0x4a,0x24,0x67,0x24,0xb8,0xc3,0x6f,0x58,0x1f,0x20,0x5c,0x72,0x48,0xa1,0x29,0x84,0x13,0xd7,0x65,0x8,0x11,0x25,0x8f,0x18,0x86,0x35,0x2e,0xe5,0x0,0xd4,0xfb,0xd0,0x1a,0xf2,0x48,0xd1,0xdf,0x71,0x58,0xc3,0x39,0xa0,0xd4,0x8c,0x3c,0x92,0xc3,0xab,0xb6,0x86,0xe6,0x23,0xca,0x36,0xf7,0x58,0x6b,0x18,0x56,0x7,0xd4,0x83,0x8,0x1a,0x62,0x19,0x87,0x35,0xc7,0x61,0x69,0x54,0x85,0x22,0xc1,0xa4,0xf5,0x98,0x8f,0xfe,0x1,0xc6,0x39,0x38,0x54,0xee,0x95,0xe3,0x7b,0x5b,0x1b,0x4e,0x1d,0xdb,0xdd,0x58,0xd9,0x15,0xbd,0xf8,0xd2,0x19,0x3c,0xfa,0x83,0x17,0xb9,0x53,0x91,0xfb,0x20,0x67,0xe,0x52,0xb4,0x46,0xce,0xcb,0x3c,0xf5,0x9,0xd6,0x5a,0x28,0x26,0x9c,0x7,0xa4,0xae,0xc7,0x97,0x1f,0x7e,0x1c,0x7,0x7,0x47,0xdd,0x88,0xd7,0x5f,0x73,0x15,0x82,0x3,0x77,0x4b,0x9e,0xe7,0xe7,0x18,0x5b,0x7b,0x3,0xa7,0xeb,0x38,0x39,0x1d,0xbd,0xf7,0xda,0x8b,0x59,0x6b,0xe1,0x48,0x34,0x3d,0xbb,0xc1,0x7,0xec,0xaf,0x56,0x5b,0x5f,0xa3,0xef,0xc8,0xe5,0xe9,0xe0,0x90,0x52,0xaf,0x20,0xed,0xf8,0x4e,0x87,0x63,0x7b,0x7b,0x47,0xbe,0xfe,0xe2,0xc5,0x3,0x7c,0xef,0xe9,0xd3,0xa,0xba,0x1b,0x9a,0x46,0xc7,0xe9,0xd9,0x69,0xc8,0x3,0x3b,0x4f,0x9,0x27,0x5e,0xba,0x87,0x8f,0x3f,0x77,0xd,0xd,0x21,0x25,0x8c,0x1c,0xe3,0x76,0x3e,0x50,0xa4,0x74,0xdf,0x15,0x60,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xb8,0x64,0x8c,0xeb,0x15,0x5d,0xb,0xfe,0x2c,0x85,0x10,0xf4,0x63,0x2a,0x3d,0x87,0x32,0xe6,0xd3,0xf4,0x33,0x2c,0x3f,0xf,0x70,0xc9,0x67,0xd0,0x64,0x32,0x99,0x4c,0x26,0x93,0xc9,0xf4,0x5f,0x2f,0x3,0x80,0x26,0x93,0xc9,0x64,0xba,0xe2,0x9a,0x43,0x5,0x71,0xb9,0x51,0xec,0x50,0xa2,0x8f,0x5e,0xbb,0xc0,0xc8,0xd,0x44,0xb,0xbc,0xe2,0xe2,0xab,0xb5,0x62,0x5c,0xaf,0x36,0xe2,0xaf,0xdb,0x60,0x81,0x73,0xa0,0xe,0x33,0x8e,0x76,0xfa,0x10,0xc9,0xe1,0xe4,0x1c,0x52,0xbf,0x0,0xb9,0xcd,0x32,0x16,0xcb,0x3d,0xc4,0xd4,0xb1,0xf3,0xcd,0xd3,0xa8,0x85,0xf7,0xd4,0xf9,0x17,0x2,0x6a,0xcd,0xda,0x1b,0x38,0xae,0x57,0x28,0xa5,0x20,0x75,0xb,0xea,0xe9,0x83,0xc3,0xeb,0x5e,0x75,0x1d,0x62,0x3c,0xea,0x98,0x1b,0x73,0xc6,0x33,0x2f,0x9c,0x45,0x4c,0x1d,0xad,0x7,0xf7,0xb,0xa4,0x7e,0xc1,0x31,0xc8,0x71,0x3,0x72,0x4d,0x22,0x87,0xa1,0x74,0x12,0xa6,0xae,0xa7,0x18,0x26,0x30,0x1,0xc8,0x10,0x8,0x95,0x54,0x5e,0xfe,0x65,0xb7,0xa4,0xb8,0xa9,0x76,0x17,0x3d,0xee,0xba,0xf5,0x5a,0xfc,0xe6,0x2f,0xbe,0x7,0x1f,0xfa,0xa9,0xb7,0x6d,0xff,0x3,0x80,0xf,0x28,0x23,0xc1,0xbb,0x52,0x32,0x81,0x31,0x34,0x74,0xfd,0x82,0x1c,0x81,0x97,0x80,0x57,0xd2,0x19,0xe8,0x9d,0x67,0x7,0x1d,0x75,0xdf,0x49,0x97,0x5d,0xce,0x23,0xf5,0xf1,0x79,0x8e,0x69,0x6f,0x7b,0x8d,0xc6,0xe,0x2f,0x7,0xd4,0x52,0xb0,0x5e,0xed,0x3,0x8d,0x96,0x9d,0x1b,0x1a,0xc6,0x61,0xd0,0x8,0xf8,0xa5,0x9c,0x60,0xce,0x7b,0x86,0x8d,0x23,0x7c,0xf0,0x1a,0xd9,0xbd,0xfa,0xc4,0x2e,0xba,0x2e,0x1e,0xf9,0xfa,0x27,0x9e,0x7a,0xe,0xa5,0x54,0x8c,0xc3,0x80,0x9c,0xa9,0x8b,0xb1,0x94,0xa2,0xe0,0xcf,0x39,0x87,0x71,0x1c,0xe8,0x9a,0x86,0x88,0x71,0xbd,0x82,0x77,0x5e,0x7b,0x1,0xd7,0xab,0x3,0x3c,0xff,0xd2,0x69,0x3c,0xbf,0x65,0xd8,0xe4,0xd8,0xde,0xe,0x4e,0x9d,0x38,0x4e,0xd7,0x21,0x44,0x82,0x9a,0xa9,0xa3,0x71,0x9b,0xad,0x22,0xf8,0xe8,0x20,0xb1,0x5d,0xea,0xde,0x73,0xec,0xbe,0x9c,0xc3,0xdd,0xc2,0xce,0xba,0xad,0xb7,0xa3,0x35,0xc8,0xe5,0x19,0xc7,0x35,0x47,0xe8,0x1d,0xae,0x39,0x75,0x62,0xeb,0x35,0x78,0xfe,0xc5,0xd3,0x78,0xf9,0xfc,0x45,0x2c,0x77,0x8f,0xe9,0x5a,0xb0,0xf3,0xf4,0x2c,0x1d,0x5c,0x3c,0xaf,0xe3,0x1d,0xf2,0x99,0x2c,0xfa,0x8c,0x6e,0x3f,0x8f,0xcc,0x51,0xf6,0xe1,0x60,0x5f,0x3b,0x33,0xc5,0xed,0xe7,0xe0,0x18,0xc,0xae,0xe9,0xa3,0xd9,0x1a,0xc6,0x91,0x86,0x6d,0x1a,0x7f,0x16,0x9d,0x38,0x25,0xf9,0x73,0x2c,0x4b,0xd4,0x68,0x40,0x2d,0x15,0x2e,0x74,0xf6,0xc3,0xd2,0x64,0x32,0x99,0x4c,0x26,0x93,0xe9,0x32,0x29,0xda,0x25,0x30,0x99,0x4c,0x26,0xd3,0x95,0x16,0xc1,0xf,0x92,0xb8,0xf2,0xe8,0xef,0xc9,0xe1,0x7,0xe9,0x50,0xd3,0x78,0x21,0xd,0x44,0x74,0x8b,0x1d,0x86,0x24,0x5,0xa9,0xeb,0x9,0xce,0x95,0x2,0xe7,0x3a,0x75,0xb1,0x1d,0x96,0x38,0xf9,0x62,0xea,0xb0,0xda,0xbf,0xa0,0x80,0x47,0x16,0x7f,0x87,0xf3,0x67,0xe1,0x12,0x39,0xc1,0xfa,0x5,0x75,0x97,0xf9,0xbe,0x57,0x97,0xa0,0x80,0x3f,0xe9,0x59,0xf3,0x21,0x72,0xcc,0xb1,0x28,0x4,0x7b,0xe3,0xeb,0xef,0xd8,0xfa,0xde,0x67,0xcf,0x5d,0xc4,0xb,0x67,0xf7,0xe9,0x9c,0x43,0x20,0xd0,0x5,0x60,0xb9,0x7b,0x9c,0xbb,0xe6,0xb6,0x50,0x9d,0xc6,0xff,0x87,0x47,0x28,0xf2,0x38,0x60,0x75,0xb0,0x4f,0xdd,0x83,0x32,0x88,0xc2,0x8b,0xbb,0x31,0x26,0x3d,0x9f,0xc5,0xa2,0xc7,0xad,0x37,0x9c,0xc4,0xbd,0xaf,0xbf,0xd,0xb7,0xdf,0x7a,0x33,0x8e,0xed,0xed,0xfc,0xd0,0x18,0x6a,0x2d,0x99,0xd7,0x73,0x81,0x3c,0xae,0x11,0x23,0x1,0xd0,0x5a,0x69,0x48,0xe4,0x92,0xf1,0x4b,0x6,0x38,0xc3,0xfa,0x0,0x21,0x46,0xac,0xf6,0x2f,0xc0,0xfb,0x80,0xfd,0xb,0xe7,0x10,0xbb,0x4e,0x5d,0x8d,0x7,0xfb,0xe7,0xb1,0xe8,0x4e,0x6e,0xbf,0x2f,0xad,0x61,0x58,0xaf,0x28,0x3a,0x3c,0x92,0xf3,0xcf,0xf9,0x80,0xfd,0x8b,0xe7,0xd1,0x2f,0x96,0x7a,0x7c,0x97,0xba,0xa7,0xf2,0xfb,0xf4,0x52,0x15,0x7,0x17,0x2f,0x10,0xbc,0x2,0x70,0xea,0xc4,0xde,0x56,0xf0,0xf6,0xc2,0x99,0xf3,0x14,0xf1,0xad,0x5,0xbe,0x11,0x30,0x4c,0x29,0x21,0x8f,0x75,0x1a,0x1e,0x69,0x55,0xc6,0xa2,0x39,0x12,0xdb,0xd0,0x1a,0xad,0x56,0x4b,0x5c,0xf9,0x85,0x97,0xce,0xe0,0xd6,0x5b,0x36,0xe3,0xb5,0x3e,0x78,0x74,0xbe,0x52,0x34,0x5d,0xc6,0x40,0x6a,0x1,0xb8,0xdf,0xf0,0xe8,0xe9,0x57,0xed,0xd9,0xa3,0x2e,0xc8,0xac,0xf1,0xe9,0x52,0xc8,0x9,0xe8,0xc7,0x1,0x51,0x60,0xaf,0xf3,0xfc,0x60,0x6c,0xbe,0x56,0xad,0x99,0xd7,0xa1,0x47,0x7e,0xd6,0x81,0x10,0x3b,0xf4,0x51,0xf6,0xaf,0x37,0xf5,0xdc,0x4b,0xe4,0x46,0xdd,0x3f,0x7f,0x56,0xe1,0x1b,0x39,0x5f,0x3,0x47,0xc8,0x47,0x3d,0xae,0xcc,0x30,0xb9,0xa9,0x3b,0xef,0xd0,0x63,0x0,0x72,0xef,0xb6,0x5a,0xe0,0x63,0xc2,0x30,0x90,0x6b,0x75,0x58,0xf3,0x32,0x34,0xc7,0xe4,0x5,0xf6,0xd7,0x5a,0xd1,0x75,0xbd,0xba,0x76,0xf3,0xb8,0x56,0x18,0xef,0xb9,0x7,0xb4,0xd6,0xa9,0xef,0x12,0xe,0xa8,0xe3,0xca,0x7e,0x58,0x9a,0x4c,0x26,0x93,0xc9,0x64,0x32,0x5d,0x26,0x19,0x0,0x34,0x99,0x4c,0x26,0xd3,0x15,0x17,0xad,0x7e,0x72,0xef,0x17,0x2f,0xa7,0xa,0xec,0xf3,0xc,0x25,0x5a,0x3,0x62,0x4a,0x3a,0x4c,0x10,0x13,0xc3,0x3,0x8e,0xe2,0x4a,0x87,0x9a,0xf,0x81,0xbe,0xae,0x6d,0x8b,0x2a,0x3a,0x60,0x36,0x2a,0x12,0x53,0x7,0xb8,0x11,0xeb,0xd5,0x3e,0x42,0x88,0xb4,0x52,0x1a,0x29,0xfa,0xd8,0x2f,0x76,0x8,0xee,0xa5,0x84,0x5a,0x2a,0x8a,0xcb,0x58,0x2c,0x77,0x31,0x8e,0xeb,0xc9,0x89,0xd6,0x1a,0x52,0xea,0x78,0x9c,0x84,0xa2,0xb0,0x77,0xbe,0xea,0x6,0xdc,0x7c,0xc3,0xb5,0x5b,0xcf,0xf3,0xbb,0x8f,0x3d,0x89,0x83,0x83,0x3,0x3a,0xce,0xe6,0x91,0xba,0x1e,0x25,0x67,0x1e,0xbb,0x20,0x78,0x72,0x54,0x8d,0xaf,0x45,0x45,0xad,0x34,0x92,0x41,0x4b,0xbf,0x7,0x58,0xec,0xec,0xd1,0x82,0x70,0xad,0x88,0x1d,0xb9,0xa,0xaf,0x3b,0xb1,0x83,0x77,0xbc,0xf9,0xb5,0xb8,0xfb,0xb5,0xb7,0xe2,0xc4,0x89,0x63,0x8,0x87,0x62,0xc5,0xb5,0xd6,0xad,0x51,0xe3,0x5a,0xb,0xa,0xf7,0xc0,0x85,0x18,0x71,0xf1,0xc2,0x59,0x2,0xa0,0xeb,0x35,0x82,0x44,0x89,0xb7,0x1d,0x5d,0x2b,0xa8,0xa5,0xa0,0x5f,0xd2,0xda,0x6b,0x48,0x1d,0xf2,0x38,0xd0,0x20,0xcb,0x38,0xc2,0xf9,0x80,0x71,0xa4,0xc8,0x2c,0x5a,0xdd,0xea,0x72,0xd4,0xae,0x45,0x80,0xd6,0x6b,0xc7,0x11,0xa1,0x64,0x84,0x10,0x30,0xe,0x3,0xad,0x30,0x77,0xb,0xb4,0x5a,0x8,0xf4,0x5d,0xe2,0xde,0x16,0x1e,0x3c,0x19,0xd6,0x7,0xd4,0x99,0x58,0x32,0xe2,0x25,0x22,0xcf,0xeb,0xf5,0xc0,0x30,0xca,0xa1,0xb6,0xc2,0xc7,0xc7,0x30,0xda,0x7b,0x82,0xbd,0xdc,0x9f,0xd7,0xf8,0xeb,0xa,0x2f,0x52,0x93,0xeb,0x93,0x7a,0x23,0xd7,0x43,0xde,0x72,0x24,0xe,0x8b,0x2e,0x30,0xdc,0xf2,0x9a,0xaf,0xa0,0x75,0xe2,0xed,0x11,0xe8,0xff,0x8f,0xbd,0x37,0x7b,0xb2,0xe5,0x3a,0xaf,0xfc,0xd6,0x9e,0x32,0xf3,0x9c,0xaa,0xba,0x17,0xf7,0x2,0x20,0x0,0x8a,0xa0,0x8,0x8e,0x10,0x69,0xce,0xe2,0x20,0x99,0x82,0xcc,0x16,0x43,0x41,0xb9,0x49,0x59,0x76,0x87,0xa3,0xa3,0x15,0x72,0x33,0xa2,0xdd,0x2f,0xed,0x7e,0x72,0xd8,0x7e,0xef,0x3f,0xc0,0xe1,0xb0,0xdf,0xdc,0x6e,0x87,0x1d,0xdd,0x76,0xb8,0x43,0xe,0xdb,0x6a,0x49,0xec,0x70,0xb3,0x25,0x9b,0x14,0x45,0xd3,0x14,0xc5,0x41,0x9c,0x40,0x12,0x0,0x31,0x90,0x20,0x0,0x62,0xb8,0x43,0x55,0x9d,0x93,0xc3,0x9e,0xfc,0xf0,0x7d,0x7b,0x67,0x9e,0xaa,0x53,0x20,0x25,0x5e,0xdd,0x36,0x11,0xdf,0x8f,0xf,0xbc,0xb7,0xea,0x9c,0x3c,0x99,0x3b,0x77,0xd6,0x65,0x2d,0xae,0xf5,0xad,0x52,0x0,0xa3,0x78,0xde,0xe4,0xd8,0x6f,0x49,0x78,0x34,0x96,0xda,0xa2,0xad,0x3,0x2c,0xed,0xc5,0xe0,0xc7,0xfd,0xf7,0x22,0x25,0x8a,0xec,0x5a,0x6a,0xee,0xa5,0xf8,0x74,0x44,0xd3,0xb4,0xfb,0x74,0x47,0x6c,0x7b,0x2a,0x69,0x31,0xce,0x41,0x2b,0xcd,0xee,0xbc,0x85,0xf8,0x9e,0x13,0x3d,0x1b,0xec,0xe,0x2c,0x91,0xe8,0x7d,0x42,0x72,0x71,0x27,0x46,0x3f,0xd5,0x99,0x7f,0x31,0x6,0x34,0xed,0xa,0xa7,0xc7,0xd7,0x30,0xf4,0x1b,0xb4,0xdd,0x8a,0xca,0x68,0x58,0x5c,0x2f,0x42,0x3e,0x4a,0xf9,0x4b,0x39,0x56,0x8,0xf3,0x9c,0xc1,0xea,0xfa,0x84,0x8c,0x0,0x14,0x4,0x41,0x10,0x4,0x41,0xb8,0x85,0x88,0x0,0x28,0x8,0x82,0x20,0xdc,0xfe,0x7f,0x7c,0xd8,0x61,0x96,0x53,0x64,0x71,0x8c,0x74,0x88,0x14,0x23,0xb2,0xe2,0x56,0x5e,0x9e,0xe9,0x56,0xc4,0x89,0x14,0x3,0x95,0xa,0xe4,0x8c,0x10,0x2,0xbb,0xf8,0x48,0x84,0xdb,0x69,0x15,0xde,0x21,0x43,0xb1,0xd8,0x50,0x4,0x27,0x0,0x24,0x70,0xb1,0x2b,0x70,0x1a,0xfb,0x59,0x67,0xe0,0xb9,0x7b,0x30,0x40,0xb7,0x3a,0x40,0xbf,0x39,0x81,0x6d,0x1a,0x2e,0x2b,0xa0,0xa2,0x8a,0x8c,0xcc,0xe2,0x98,0x81,0xd6,0xa,0xf,0xbd,0xef,0xad,0x70,0xee,0xfc,0x3f,0xa7,0x3e,0x4,0xfc,0xf9,0x37,0x1e,0x25,0xa1,0x91,0x9d,0x55,0x24,0x7c,0x2,0x4a,0x2b,0xa4,0x90,0xa0,0x97,0xe5,0x1b,0x5,0x8e,0x60,0x22,0xd3,0x2c,0xb4,0xc4,0x31,0x55,0x28,0x85,0xa1,0xdf,0x54,0xa1,0xe6,0xbe,0xab,0x87,0xf8,0xe8,0xaf,0xbe,0xf,0xf,0xbe,0xf1,0xe7,0xd1,0x36,0xbb,0xc7,0x49,0x29,0xe1,0xa5,0xeb,0xc7,0x78,0xf8,0x91,0x27,0x70,0xfd,0xc6,0xd,0xfc,0xd6,0x6f,0x7c,0xf8,0xdc,0xc7,0xc4,0x40,0xf3,0xfb,0xe8,0xcf,0xe4,0x70,0x9b,0xc6,0x1,0xa,0x40,0xd4,0xfa,0x82,0x78,0x32,0x50,0xe6,0xb4,0x95,0xb6,0x61,0x63,0x2c,0x2,0x50,0x85,0xc9,0x94,0x22,0xba,0xf5,0x21,0xc2,0x34,0x62,0xec,0x2f,0x88,0x11,0x27,0xba,0x5f,0xd3,0xd8,0xf3,0x8c,0x38,0xd4,0x58,0xb4,0x75,0xd,0xba,0xf5,0x1,0x89,0x60,0xb5,0xa1,0x76,0x7f,0xbc,0x3b,0x4,0x5f,0x5,0xda,0x94,0x68,0x9e,0xdc,0xd0,0x6f,0xf7,0xef,0x39,0xa3,0xeb,0x3c,0xc8,0x10,0xfc,0xec,0x20,0x4,0xb5,0xd7,0xc6,0x10,0x90,0xb4,0x42,0xe8,0xc7,0x1a,0x65,0xd,0xc1,0xa3,0x69,0x57,0x54,0x74,0xd2,0xb4,0x40,0xce,0x30,0x48,0x7b,0x76,0x59,0xc6,0xb6,0xef,0x11,0x53,0xc4,0x78,0xf3,0x1a,0xda,0xd5,0x1,0x94,0x8e,0xd0,0x39,0xec,0x75,0x0,0x2,0xe4,0x2,0x44,0xa6,0x59,0x83,0x7e,0x1a,0x29,0x7e,0x9c,0xe9,0xcf,0xab,0xf5,0x61,0x5d,0x8b,0x12,0x85,0xde,0x7f,0x2b,0x68,0x7e,0x1e,0x8a,0x43,0x31,0x5,0xa4,0xa4,0x71,0x7a,0x72,0x73,0x11,0x9f,0xde,0xbd,0xe7,0x89,0xdb,0x7e,0xa7,0x38,0x51,0x11,0xe,0xdf,0xcf,0x9c,0x12,0xa6,0xb1,0x87,0xb5,0x4d,0x6d,0xcd,0xe,0x7e,0xa2,0x79,0x9b,0x69,0x5f,0x5b,0xb5,0xc2,0xd8,0x6f,0x59,0x48,0xe,0xdc,0x2,0x4c,0xce,0xbe,0xa6,0xa1,0x98,0x7b,0x4c,0x11,0x2a,0x1b,0x98,0x4c,0xad,0xbe,0xda,0x18,0xe4,0x98,0xd9,0x4d,0x19,0x1,0x95,0x79,0x6,0x28,0x45,0xee,0x93,0x8a,0x34,0x3b,0x32,0x65,0x36,0xc1,0x1a,0xf9,0x61,0x29,0x8,0x82,0x20,0x8,0x82,0x70,0xab,0x7e,0x7,0x93,0x25,0x10,0x4,0x41,0x10,0x6e,0x37,0x65,0x66,0x5f,0x69,0x41,0x4d,0x29,0xc3,0x58,0x3,0xcd,0x8e,0xbe,0x2a,0xb6,0xb1,0x7b,0x2a,0x6,0xf,0xd7,0x52,0xeb,0x6e,0xca,0x89,0xa2,0x9c,0x2c,0x92,0x51,0x4,0x78,0x7f,0xe1,0x42,0x69,0xef,0xd5,0x4a,0xd7,0x59,0x6b,0x9a,0xa3,0x86,0xa5,0xed,0xd6,0x18,0x9a,0xab,0x47,0x31,0x4b,0x6a,0x20,0x56,0x5a,0x61,0xd8,0x9e,0xc2,0x35,0x2d,0xc5,0x12,0xad,0x46,0x2,0x45,0x18,0x63,0xf0,0xb0,0x4d,0x3,0x5,0x85,0xf7,0x3e,0xf8,0x5a,0xbc,0xe5,0xd,0xaf,0xdd,0x7b,0x8d,0xdf,0x7f,0xfa,0x39,0x3c,0xfd,0xfc,0x4d,0xf8,0x40,0x73,0xd2,0xca,0xbc,0xb6,0x12,0x33,0x86,0x4a,0x48,0x21,0xec,0x7d,0x2f,0x35,0xff,0x5a,0x4,0x76,0x46,0x95,0xb2,0xe,0x2a,0xf5,0xd0,0xf8,0x9b,0xbf,0xfa,0x1e,0xfc,0xda,0x43,0x1f,0xc4,0xaa,0x6b,0x77,0xde,0xe7,0xbd,0xc7,0x53,0x3f,0x7c,0x1e,0x9f,0xfd,0xe2,0x37,0xf1,0xed,0x27,0x9e,0x41,0x88,0x11,0xef,0x79,0xcb,0xfe,0xf3,0x2b,0xeb,0xa1,0xb8,0x75,0x99,0xae,0x8b,0xae,0xd7,0x99,0xf6,0x42,0xf3,0x15,0x15,0x93,0x70,0x3b,0x6e,0xd3,0x60,0xe8,0xb7,0x18,0xb6,0xa7,0x68,0xda,0x15,0xc6,0x71,0x40,0xce,0x19,0x9b,0xe3,0x1b,0x74,0x9d,0x4e,0xef,0x3f,0x4e,0x26,0xc1,0x30,0xa5,0x58,0xe7,0xfd,0x19,0x8e,0xcb,0x2a,0x0,0x63,0xbf,0x85,0x73,0x2d,0x52,0x9e,0xe3,0xda,0xe7,0x21,0x1,0x19,0xb9,0xcc,0x8d,0xcb,0x18,0xb6,0x1b,0x6c,0xfa,0x61,0x4f,0x58,0x16,0xb8,0xf3,0xca,0x65,0x34,0xdd,0xa,0xd3,0x40,0x4d,0xbb,0xae,0xe9,0xe0,0xa7,0x1,0xce,0xb5,0xe4,0x4,0x65,0x47,0x9a,0xb1,0x8e,0x4b,0x4d,0xa8,0x58,0x83,0x84,0x2b,0x5b,0xb,0x6a,0x2e,0x5d,0x3a,0x5f,0xae,0x91,0x52,0xc2,0xe9,0xa6,0xaf,0x22,0xa6,0x9e,0x6,0x0,0xa,0xdd,0xd1,0xe1,0x5,0xe2,0x25,0xb9,0xfe,0x62,0x9a,0x38,0x6,0x4c,0x71,0xdb,0x71,0xe8,0xa9,0x99,0x9a,0x63,0xb7,0xfd,0xe6,0x4,0xd6,0x39,0xbe,0x96,0xf3,0x6b,0x90,0x78,0x46,0x9f,0x52,0xa,0x13,0xbb,0x5a,0xa3,0xa,0x38,0xde,0xf4,0x88,0x29,0xc1,0x9a,0x5d,0x1,0xad,0xec,0x97,0xf2,0xf9,0x65,0xbe,0x9f,0xe6,0x3f,0x1b,0x63,0xab,0x40,0x58,0x5c,0x80,0x21,0x4c,0x17,0x8,0x90,0x34,0x3f,0x73,0x1a,0x7,0xde,0x9f,0xba,0xee,0xb,0x12,0x76,0xc9,0x5d,0x6a,0xad,0x5b,0xc4,0x8d,0x33,0x62,0xa,0xb0,0xba,0xa9,0xcf,0x5f,0x4a,0x89,0x9d,0x86,0x3c,0xdf,0x73,0x11,0x87,0xce,0x39,0xca,0xf,0x4b,0x41,0x10,0x4,0x41,0x10,0x84,0x5b,0x84,0x8,0x80,0x82,0x20,0x8,0xc2,0x6d,0xa7,0x44,0x52,0x73,0x19,0xb8,0x6,0x76,0xfd,0x28,0x8a,0x16,0x6a,0x4d,0xc2,0x45,0x29,0xe5,0xd0,0x86,0x22,0xbf,0x6,0x96,0xa3,0xbc,0x8e,0x84,0x93,0x9c,0x60,0x8d,0xa5,0xd9,0x78,0xfb,0x8a,0x22,0xe8,0xd0,0x5c,0x2c,0x92,0xa1,0xd8,0x29,0xe6,0x9a,0x16,0xe3,0xd0,0x43,0x1b,0x83,0x76,0x75,0x50,0x5,0x2c,0xa5,0x35,0x9,0x2e,0x5a,0x43,0x2b,0x4d,0x5,0x1b,0x89,0x5,0x47,0x16,0x26,0xad,0xa3,0x79,0x83,0xaf,0xba,0xbc,0xc6,0x6f,0x7c,0xf8,0x3,0x7b,0xe3,0xb5,0x21,0x44,0x7c,0xe6,0xb,0x5f,0xc7,0xe4,0x3,0xac,0xb5,0x0,0x42,0x9d,0x29,0x58,0xdc,0x76,0x3e,0x8d,0x5c,0x7c,0x70,0x1e,0x72,0xb4,0xcd,0xce,0x34,0x80,0x22,0xbb,0xce,0x35,0xf8,0x3b,0x7f,0xf3,0x43,0xf8,0xe5,0xf7,0xbd,0x73,0xe7,0x73,0x73,0xce,0xf8,0xc1,0x33,0xcf,0xe3,0xff,0xfc,0xec,0x57,0xf1,0xf8,0x33,0x2f,0x91,0xab,0x91,0x9d,0x91,0x17,0x45,0x79,0x83,0x2f,0xee,0x3f,0x2a,0x38,0x31,0xd6,0x61,0x1a,0xfb,0xea,0xba,0x2c,0xee,0xc0,0xb3,0xc4,0x48,0xd,0xb7,0xa9,0x88,0xb3,0xde,0x23,0x78,0xf,0x3f,0xe,0x68,0xba,0x35,0xa6,0x71,0xcb,0xad,0xbe,0x3,0x26,0xbb,0xdf,0xbd,0x66,0x5c,0x53,0x1d,0x6e,0xd6,0x65,0xc,0xdb,0x53,0x20,0xd3,0x3c,0x38,0xaf,0x14,0xcf,0x6,0x9c,0x6a,0xd4,0x7b,0xaf,0xfc,0x54,0x5d,0x69,0x8a,0x1a,0x75,0x23,0xb9,0x49,0x9f,0xf9,0xd1,0x8b,0xf0,0xde,0xa3,0x71,0xbb,0xae,0xc8,0x7b,0xee,0xba,0x4c,0x45,0x17,0xd6,0xc1,0x5a,0x8b,0x69,0xd8,0x92,0xfb,0x2e,0x8d,0x55,0x8,0x25,0xc7,0x1b,0xcd,0x31,0x9c,0xc6,0x11,0x43,0xbf,0x41,0x4a,0x11,0x7,0x47,0x97,0x1,0x64,0xb8,0xa6,0xc1,0x9d,0x57,0x2e,0x9d,0x3b,0x97,0x61,0x98,0x70,0xf3,0x64,0x83,0x7e,0x73,0x8a,0xd5,0xfa,0x10,0xd3,0xd0,0x93,0x78,0x1c,0xc3,0x85,0x65,0x2a,0x45,0xd8,0x9d,0xc6,0xa1,0x46,0xa8,0x1,0x5,0xd7,0x34,0x18,0x87,0x2d,0x9c,0x6b,0x10,0x62,0xac,0xb3,0x7,0xf7,0xcd,0x0,0x54,0x5a,0x55,0xe7,0x66,0x4a,0xb1,0xf6,0xe0,0x5c,0xbb,0x71,0xc,0xef,0xc3,0x39,0x1,0xf0,0xf2,0xd1,0x7a,0x8e,0xfc,0xf2,0x39,0xf8,0x69,0x82,0x4f,0x9,0x7e,0xec,0xa1,0x34,0xc5,0xcd,0x83,0x9f,0xa0,0xb9,0x95,0x57,0xd5,0x82,0x8e,0x73,0x57,0x40,0x2,0x7e,0x8a,0x40,0x8a,0x18,0x26,0x8a,0x29,0xa7,0x18,0x31,0x8d,0x3,0x2e,0x5d,0xb9,0xb,0xb1,0x94,0xfb,0xf0,0x1e,0x2d,0x25,0x25,0xc1,0x8f,0x24,0x36,0x3,0x50,0xc8,0x2c,0x32,0xa2,0xce,0x1f,0xcc,0x20,0xb7,0xac,0xd2,0xd,0x80,0x51,0x7e,0x60,0xa,0x82,0x20,0x8,0x82,0x20,0xdc,0x2,0x44,0x0,0x14,0x4,0x41,0x10,0x6e,0x3b,0x25,0x32,0x8,0x8e,0xd3,0x2a,0xfe,0xa5,0x1f,0x89,0xca,0x32,0x8a,0x23,0xac,0x14,0x6,0xd4,0xc6,0xd8,0x14,0x49,0x5c,0xf2,0x13,0x9c,0x52,0x3c,0x2b,0xf,0xd0,0xb6,0xb9,0x60,0x5e,0x18,0x1d,0x37,0x6,0xbf,0x88,0x62,0x92,0xf3,0xc8,0x5a,0x57,0x5b,0x4e,0xbb,0xf5,0x21,0x80,0x5c,0x63,0xc5,0x0,0x60,0xd9,0xfd,0xe5,0x9a,0xa6,0x8a,0x18,0xd4,0x28,0x9c,0x70,0xa9,0x6b,0xf0,0x89,0xbf,0xf5,0x11,0xdc,0xb1,0xc7,0xd,0x6,0x0,0xdf,0x7e,0xec,0x29,0x7c,0xfb,0xc9,0xe7,0x6a,0x59,0x48,0x29,0x38,0x88,0x31,0x54,0x11,0x30,0xa7,0xb8,0xbf,0x20,0x22,0x25,0xe4,0x14,0x6b,0x3c,0x5a,0x51,0x36,0x1a,0x5a,0x1b,0x7c,0xe4,0xfd,0xf,0xee,0x11,0xff,0x80,0x2f,0x7e,0xf5,0x61,0xfc,0xfe,0x9f,0x7c,0xd,0x21,0xce,0x62,0x9f,0xe1,0x82,0x90,0x9c,0x2e,0x9a,0xe5,0x97,0xe6,0xc6,0xdb,0x69,0xc4,0x34,0xd,0x34,0xa3,0x30,0x52,0x2b,0xf0,0x45,0x2,0xa0,0xd1,0x1a,0xc6,0x39,0xe4,0x89,0x84,0x33,0xdb,0x34,0x58,0xab,0x23,0x6c,0x4f,0x8f,0x31,0xe,0x1b,0xc4,0x10,0x78,0xae,0xa0,0x83,0xb1,0x87,0x7b,0xdd,0x7b,0x29,0x25,0x18,0x4b,0xb1,0xea,0xe2,0xc8,0x4b,0x39,0xc3,0xf1,0x39,0x53,0x14,0x95,0x5c,0x61,0xe6,0xa2,0x46,0x62,0x9e,0xd7,0x17,0x82,0x27,0xc1,0x8e,0x8f,0xf3,0xc3,0xe7,0x23,0x4e,0x4f,0xb7,0xb8,0x7a,0xe5,0xf2,0xce,0xcb,0xef,0x7d,0xd5,0xdd,0xb8,0xeb,0xca,0x65,0xdc,0x3c,0xed,0x69,0xe6,0xa0,0x75,0xb0,0xbc,0x8e,0xd3,0xd0,0x63,0x73,0x72,0x13,0xd6,0x5a,0x16,0xfd,0x68,0xdf,0xad,0xf,0x2f,0x21,0xe7,0x84,0xe0,0xa9,0x8d,0xf9,0xbe,0xab,0x87,0xb8,0x7a,0xe5,0xca,0xb9,0x53,0xb9,0x7e,0xe3,0x6,0x4e,0xb6,0x3d,0x94,0x52,0x38,0xbe,0xf1,0x12,0x5c,0xd3,0x92,0xdb,0x6d,0xd5,0x5e,0xf8,0xc,0x8c,0xfd,0x6,0xc6,0x50,0xd1,0x88,0xd6,0x86,0xc4,0x6c,0xde,0x93,0xde,0x4f,0x8,0x7e,0x42,0xdb,0xad,0x10,0xfc,0x84,0xfc,0x32,0xcf,0x52,0x4a,0xdc,0xd6,0xcb,0xc5,0x22,0x39,0x67,0xbc,0x78,0xed,0x3a,0x6e,0xdc,0xb8,0x81,0xd5,0xbd,0xf7,0xec,0xbc,0xf6,0xbe,0x7b,0xee,0x86,0xd6,0xa,0xd3,0x34,0xf1,0x4c,0xcb,0x79,0xbf,0x1,0x24,0xcc,0x8f,0x3,0xc5,0x7a,0x87,0x7e,0x82,0x2,0x28,0xfa,0xbc,0x77,0xff,0x50,0x5b,0xf5,0xfa,0xf0,0x12,0xb6,0x9b,0x13,0x8a,0xd3,0xf,0x7d,0x8d,0xda,0x1f,0xdf,0x78,0x9,0xeb,0xc3,0x4b,0x88,0x31,0xc1,0xa9,0x8e,0x9f,0x79,0xda,0x6f,0x31,0xf3,0xfe,0xca,0x3c,0xf3,0x10,0x1,0x86,0x5d,0x88,0x91,0x45,0xd3,0xc,0x20,0x5,0x29,0x1,0x11,0x4,0x41,0x10,0x4,0x41,0xb8,0x55,0x68,0x59,0x2,0x41,0x10,0x4,0xe1,0xb6,0xff,0xe3,0x63,0x2c,0x47,0x62,0x75,0xb5,0xe9,0xe5,0x94,0xaa,0x88,0x97,0x8b,0x68,0xc6,0x82,0x46,0x4a,0x54,0x3c,0xa1,0xb9,0xd,0x55,0x81,0xe6,0x3,0x96,0xe6,0xd6,0xc4,0x51,0xd0,0x7d,0x28,0x45,0x2e,0x29,0xc5,0xf3,0xe4,0x8a,0xa3,0x29,0xa5,0x44,0xc5,0x11,0xa0,0x8,0x66,0xd3,0xae,0x60,0x2c,0xc5,0x4d,0x69,0xf6,0x5a,0xaa,0x33,0xf8,0xb4,0xa6,0xc8,0x71,0xce,0x19,0xf,0xbc,0xfa,0x2e,0xfc,0x83,0xdf,0xfe,0x77,0x71,0xef,0xdd,0x57,0xf7,0x7e,0xde,0xcd,0x93,0x53,0x7c,0xf2,0xd3,0x5f,0x82,0xf,0x1,0xe3,0xd0,0x23,0x84,0xc0,0x65,0x15,0xe4,0xfc,0x33,0xd6,0xc1,0xba,0x86,0xce,0x9,0xfb,0xe3,0xa1,0x31,0x6,0x14,0xa1,0xb2,0x5c,0xd7,0xaa,0x31,0xf8,0xf0,0x87,0xde,0x77,0xce,0x71,0xf8,0xf8,0x53,0x3f,0xc4,0xef,0x7d,0xfa,0xab,0x8,0x91,0x22,0x9c,0x13,0xc7,0x70,0xa7,0xb1,0xe7,0xb8,0xb4,0xbd,0xe0,0x1e,0x38,0x74,0xeb,0x43,0x5a,0x3b,0x85,0xda,0xa8,0xc,0x90,0x3b,0xb0,0xcc,0xc8,0x3b,0x4b,0xe4,0x2,0x8f,0xc4,0xc2,0x51,0x98,0x26,0xba,0x4e,0x4f,0x33,0x1,0x4b,0x14,0xd4,0x18,0x83,0xe8,0xfd,0x5e,0x7,0xa0,0x56,0xa,0x46,0x5b,0x5e,0xf,0xcb,0x25,0x18,0x1b,0x4c,0x63,0x4f,0xf3,0xf0,0xa6,0x11,0x63,0xbf,0xad,0xee,0xc7,0x8b,0x62,0xb4,0x19,0x8a,0x9a,0x90,0x73,0x86,0xb1,0x16,0xc6,0x5a,0x8c,0x43,0x8f,0x27,0xbe,0xff,0xcc,0xb9,0xd7,0xaf,0x57,0x2d,0x7e,0xe9,0x1d,0x6f,0x80,0xd2,0xa6,0x8a,0xcc,0x31,0xf8,0x2a,0x5a,0x95,0x52,0x8a,0x52,0x9a,0x62,0xac,0xc3,0x38,0xf4,0xd4,0x66,0xdb,0x91,0x3b,0xf4,0x23,0xbf,0xf2,0x3e,0x34,0xcd,0xf9,0xb9,0x8d,0xdf,0x7e,0xe4,0x9,0x16,0x52,0xe7,0xb9,0x8a,0xd3,0x38,0x60,0xec,0x37,0x17,0xee,0xc9,0x9c,0xc9,0xf9,0x56,0xee,0xb7,0x56,0x9a,0x63,0xd1,0x65,0x7d,0xd9,0xe1,0xa8,0xe8,0x79,0xd8,0x27,0xa4,0x6a,0xa5,0x61,0x8c,0xc5,0xea,0xe0,0x8,0xd6,0x36,0x75,0xae,0xa2,0xf7,0x1,0xdf,0x7b,0xe2,0xfb,0xe7,0x5e,0x7f,0xe7,0x95,0xcb,0xf8,0xf9,0x7b,0xae,0x70,0xd9,0x89,0x1,0xa0,0xa0,0xad,0xc5,0x38,0xf6,0x34,0x17,0x31,0x45,0x8c,0xfd,0xa6,0x46,0x77,0x9b,0x6e,0xc5,0xfb,0x6f,0xcf,0xfa,0xd7,0x39,0x95,0x6,0x4d,0xd3,0x92,0xa3,0x54,0x1,0x50,0xa,0x7,0x47,0x77,0xc0,0x18,0x8b,0xfe,0xf4,0x18,0x8a,0xff,0xa3,0x79,0x5e,0x61,0x8a,0x11,0xae,0xed,0x0,0x7e,0xee,0x82,0x27,0x21,0x90,0x4,0xf2,0xe2,0x62,0x54,0x54,0x9e,0xa2,0xa4,0x5,0x44,0x10,0x4,0x41,0x10,0x4,0xe1,0x96,0xfd,0xe,0x26,0x4b,0x20,0x8,0x82,0x20,0xdc,0x6e,0x52,0x9c,0x5b,0x3f,0xb5,0x9a,0xdb,0x3f,0x33,0xb7,0x89,0x66,0xca,0x3,0x72,0x23,0x70,0xae,0x33,0xf0,0x62,0xc,0xb5,0x48,0xa3,0x88,0x82,0xc5,0x3d,0x86,0xb,0x4a,0x40,0x12,0x47,0x43,0x53,0xc,0x48,0x21,0x40,0x69,0xc5,0xe2,0x1e,0x45,0x11,0xa1,0xc0,0x22,0x52,0xda,0x11,0x36,0x68,0x6,0x1a,0x1d,0x33,0xa5,0x8,0x6b,0xc,0x7e,0xfd,0x97,0xde,0x8e,0xbf,0xff,0xb7,0x3f,0x8a,0x7b,0x2e,0x10,0xff,0xc6,0x69,0xc2,0x27,0xff,0xf8,0xb,0x78,0xf6,0xc5,0x6b,0xe4,0x6c,0xe4,0x46,0x59,0x9a,0x51,0x47,0xc7,0xf1,0xe3,0x40,0x62,0x19,0x8b,0x9c,0x67,0x29,0x51,0xd0,0xcc,0x8e,0x2e,0x80,0x5c,0x52,0xf,0xbe,0xee,0x3e,0x5c,0x3a,0xda,0x75,0x1c,0xa6,0x94,0xf0,0xb9,0x2f,0x7d,0xb,0x93,0x9f,0x10,0x63,0x44,0x8,0x1e,0xc6,0x58,0x12,0x36,0x15,0xcd,0xdf,0x4b,0x17,0x38,0x0,0x35,0xaf,0x49,0xbb,0x5a,0xc3,0xba,0x6,0xae,0xe9,0x6a,0x14,0x98,0x4,0xa7,0xb,0x6e,0x1e,0xb,0xb7,0x39,0x67,0x12,0x6c,0x14,0xd0,0x76,0xab,0x2a,0x90,0x2a,0xa5,0xc9,0xdd,0x97,0xf2,0xde,0x72,0x14,0x3a,0x44,0xe6,0x58,0xb5,0x85,0xd2,0xba,0xa,0xaf,0x9b,0x93,0x9b,0xe8,0xb7,0x27,0x18,0xb6,0x9b,0x5a,0x62,0x11,0xfc,0x74,0x81,0xb8,0x4b,0x8e,0x4d,0xeb,0x1c,0xb4,0xd6,0x88,0x31,0xc2,0x8f,0x23,0x52,0xc,0xf8,0xfc,0x17,0xbf,0x72,0xee,0xba,0x95,0x52,0x78,0xff,0xbb,0x7e,0x1,0x87,0x6e,0x16,0xd4,0xc2,0x34,0xb1,0xe8,0x38,0xb0,0x73,0x4d,0xc1,0x58,0x7,0x6d,0x2c,0x52,0x8c,0x68,0xda,0xae,0x8a,0xa2,0x6f,0x79,0xed,0xbd,0x78,0xe7,0xdb,0xde,0xb4,0xf7,0x9e,0xff,0xc5,0xc3,0x8f,0x23,0x67,0xc0,0x58,0xb,0xeb,0x5a,0x6a,0x79,0x56,0xa8,0xb3,0xec,0xce,0xed,0x7f,0x16,0x66,0xcb,0x1c,0xbe,0x12,0xd7,0xe,0x61,0xc2,0xd0,0xd3,0xec,0x49,0xcd,0x6b,0x9c,0x33,0xcd,0xda,0xdb,0xb7,0x4,0x99,0xaf,0xb,0x4a,0x91,0xeb,0x90,0x23,0xf3,0x31,0x78,0x7c,0xe5,0x1b,0x8f,0x9c,0x5b,0x3,0x63,0x34,0x3e,0xfc,0xc1,0xb7,0xcf,0x33,0x33,0x73,0x46,0xf0,0x13,0x9a,0x76,0x85,0xb6,0x5b,0x61,0x1a,0x7,0x58,0xd7,0xa0,0x6d,0x57,0xd0,0xc6,0xcc,0xa2,0x63,0xde,0xbf,0x7f,0x9a,0x76,0xc5,0xcf,0x9d,0xaa,0x6d,0xda,0x31,0x6,0xc,0xfd,0x29,0x35,0x2,0x77,0x2b,0x6a,0x5b,0xe6,0xb5,0x30,0x7c,0xbf,0xcb,0x3d,0x35,0xc6,0xf2,0xbe,0x49,0xd5,0x9,0xbc,0xb8,0x61,0x90,0x1a,0x60,0x41,0x10,0x4,0x41,0x10,0x84,0x5b,0x87,0x8,0x80,0x82,0x20,0x8,0xc2,0x6d,0x47,0xa9,0x5d,0x77,0x5b,0x5e,0xfc,0xc2,0x5f,0x9c,0x7a,0xf4,0x25,0xcd,0x11,0xc5,0x5c,0x5b,0x44,0x8b,0x8,0x48,0xe2,0x56,0xac,0x31,0xc6,0x8b,0x28,0x51,0x62,0x63,0x1d,0x6c,0xd3,0x40,0x2b,0xb3,0x53,0xfc,0x61,0x6d,0x83,0xa6,0x5b,0x51,0xf1,0x6,0x3b,0x13,0xa9,0xc,0x24,0xc0,0x35,0x2d,0xee,0xb8,0x7c,0x9,0xbf,0xfc,0x8e,0x37,0xe2,0x3f,0xfd,0xc4,0xc7,0xf0,0x1b,0x1f,0x7e,0x3f,0xd6,0xab,0x6e,0xef,0xe7,0xc4,0x94,0xf0,0xaf,0xff,0xe4,0x8b,0xf8,0x7f,0xbf,0xf6,0x8,0x89,0x7d,0x31,0xb2,0xa8,0x94,0xab,0xbb,0x8a,0x2f,0xaa,0xa,0x5e,0xfb,0x28,0x91,0xcc,0xc4,0x8d,0xba,0xc5,0xcd,0x77,0xff,0xab,0x5f,0x75,0xee,0x3d,0x19,0xc0,0x4b,0x37,0x4e,0x60,0x8c,0x43,0xd3,0x92,0x80,0xa7,0xb4,0xaa,0x8e,0x48,0xe3,0x9a,0xea,0x6c,0xdb,0xf7,0x39,0x65,0x2e,0xa1,0x75,0x8e,0xcb,0x40,0x2,0x6c,0xd3,0x54,0x7,0xe2,0x7e,0x72,0xbd,0x96,0xcc,0x2d,0xb6,0xc3,0x96,0x66,0xe5,0x59,0x9e,0xed,0x97,0xd9,0x1,0x98,0xd3,0x7e,0x17,0x97,0x62,0x87,0x9d,0xd6,0x1a,0xae,0xe9,0x48,0x8,0x32,0x16,0xed,0x6a,0x5d,0x45,0x21,0xc5,0xa2,0x9e,0x31,0x16,0x7b,0x1d,0x68,0x4a,0x23,0x65,0x72,0x8d,0x69,0x9e,0x5d,0xe7,0xda,0x16,0x4d,0xb7,0xc6,0x57,0x1e,0x7e,0x1c,0x3f,0xf8,0xe1,0xb3,0xe7,0xde,0x73,0xe9,0xe8,0x0,0xbf,0xf3,0x5b,0x1f,0xc6,0xe5,0xc3,0x3,0x12,0x9c,0x8c,0xe6,0xf7,0xad,0xe0,0x5c,0x43,0xeb,0x9d,0x12,0xa2,0xf7,0x68,0xda,0xae,0x8a,0x52,0xf7,0xdd,0x75,0x7,0x7e,0xfb,0xb7,0xfe,0x6,0xba,0xb6,0x39,0x77,0xcc,0x27,0x9e,0xfa,0x21,0x9e,0x7c,0xee,0x1a,0x80,0x8c,0x66,0x21,0xa2,0xa6,0x98,0xe0,0xc7,0xa1,0xce,0xb3,0xdc,0x39,0x77,0xde,0x5f,0x14,0xc3,0xa6,0xb8,0x7b,0x8c,0x81,0xef,0x9,0xc5,0xcc,0x6d,0xd3,0xd4,0x7b,0xa0,0x2f,0x58,0x83,0xf9,0x19,0x89,0x8,0x9e,0xa2,0xdb,0x61,0x22,0x77,0xe6,0x5f,0x7c,0xe7,0x9,0x3c,0xf7,0xa3,0x17,0xce,0xbd,0xfe,0xad,0x6f,0x7e,0x0,0xf,0xbd,0xfb,0x4d,0x88,0xc1,0x63,0x1c,0x7b,0x20,0x67,0x44,0x3f,0x21,0xa5,0x5c,0xdd,0xa5,0x81,0x5d,0x8c,0x4a,0x1b,0x72,0xeb,0xed,0x8b,0x71,0xb3,0xb0,0xae,0x16,0x9b,0xd1,0xda,0x6,0x46,0x1b,0x28,0xa5,0xd1,0x76,0x2b,0x0,0xa,0xde,0x4f,0x88,0xde,0x57,0x31,0xb2,0x8,0xaa,0x99,0x6a,0x7e,0x69,0xaf,0xb1,0x4b,0x97,0x9e,0x63,0x9e,0x3,0x98,0xf2,0x5e,0x87,0xac,0x20,0x8,0x82,0x20,0x8,0x82,0xf0,0x57,0x43,0x4,0x40,0x41,0x10,0x4,0xe1,0xb6,0x13,0x39,0x5e,0x9a,0xd8,0xf9,0x43,0xe5,0x0,0x14,0xcf,0x2d,0xf3,0xd7,0xf2,0xc2,0xd5,0x97,0x52,0x20,0x57,0x56,0x15,0x11,0xc8,0x41,0x48,0xcd,0xad,0x19,0xd6,0x5c,0xfc,0xcf,0x99,0x52,0xa,0x4d,0xd3,0xc0,0x68,0x8d,0x1c,0x3,0x9c,0x33,0x68,0xbb,0xe,0xce,0x5a,0x34,0xce,0xc2,0x68,0x85,0x1c,0x3c,0xd6,0x7,0x7,0x58,0xb7,0xe,0x97,0xf,0x3a,0xfc,0xc2,0x3,0x3f,0x87,0x5f,0xff,0xa5,0xb7,0xe3,0x13,0x1f,0xff,0x65,0xfc,0xe7,0x7f,0xef,0x37,0xf1,0x1f,0x7e,0xec,0xdf,0xc1,0x7d,0xf7,0xdc,0x75,0xe1,0x67,0xa4,0x94,0xf0,0xe9,0xcf,0x7d,0x9,0x7f,0xfc,0x85,0x6f,0x55,0x31,0x67,0xbe,0xd6,0x58,0x85,0xbc,0xe0,0x27,0x68,0x45,0xe,0x2d,0xc5,0xe5,0x27,0x7b,0x4e,0x98,0xa3,0xcd,0xb9,0xce,0x23,0x4c,0x29,0x9d,0x6b,0xfc,0x5,0xc8,0x3d,0xf9,0xaa,0xab,0x97,0x90,0xd9,0x59,0x18,0x3d,0xcd,0xcc,0x8b,0x81,0x5,0xac,0x94,0x2e,0x94,0xf1,0x94,0xb5,0xc8,0xc8,0xe4,0xfe,0xe3,0x79,0x87,0xd6,0xb5,0x18,0x36,0xa7,0x24,0xc6,0x5c,0x50,0x1e,0x42,0x71,0x66,0xbe,0x7f,0x71,0x8e,0x5e,0xe7,0x9c,0x11,0xca,0x7c,0x43,0x16,0x6,0xd3,0x5,0xb1,0x6c,0x9a,0xed,0xb8,0xf8,0x3b,0x72,0x75,0xdb,0x8d,0x43,0xf,0xe7,0x5a,0x8c,0xfd,0x16,0x21,0x4c,0x24,0x28,0xee,0x3b,0x6,0xcf,0xc,0x2c,0x62,0xa1,0x66,0x17,0xdd,0x34,0x6c,0x91,0x72,0xc6,0xa7,0xfe,0xf8,0xb3,0x8,0xf1,0x7c,0x8b,0xec,0x1b,0x5e,0xf7,0x1a,0x7c,0xe2,0xb7,0x7e,0x15,0xf7,0xdf,0x7d,0x19,0xd6,0x50,0xe3,0xef,0xb8,0xdd,0xd4,0x52,0x13,0x3f,0x8d,0x1c,0x51,0x5,0xba,0x6e,0x8d,0xf7,0xfc,0xc2,0xeb,0xf0,0xf,0x7e,0xe7,0x63,0xb8,0xfb,0xae,0x3b,0xcf,0x1d,0x6b,0x1c,0x27,0x7c,0xea,0x4f,0xbf,0x42,0x31,0xd8,0xb6,0x83,0xb1,0x16,0xae,0x69,0x59,0xa8,0xcd,0x88,0x61,0xda,0x2b,0x4e,0x97,0xfd,0x9d,0x52,0x82,0xd2,0x24,0x82,0xd1,0x7b,0xbb,0xea,0xa4,0x9b,0x86,0x1,0x29,0x86,0x85,0x13,0x4f,0xed,0x3d,0xe,0x14,0xcf,0x7b,0x64,0xd7,0x6a,0xc3,0xe7,0x3e,0x8e,0x23,0xfe,0xf0,0x53,0x9f,0xd9,0xeb,0x84,0xfc,0xf8,0xaf,0xff,0xa,0x3e,0xfe,0xab,0xef,0xc6,0xd1,0xba,0x5b,0xdc,0xa7,0xcc,0xa2,0xac,0xa1,0x92,0x1d,0x70,0x6b,0x6f,0xd8,0x5f,0x64,0x42,0x33,0x4,0x33,0x5c,0xdb,0xb1,0x6b,0x92,0xf6,0x8c,0x65,0xd1,0x79,0x1a,0x28,0xce,0x9d,0x62,0xe0,0x53,0xa7,0x79,0x9f,0xc6,0x92,0xc8,0x6e,0x5d,0x43,0xcd,0xd3,0xae,0xa9,0xcf,0x44,0xe6,0xfb,0x4a,0x73,0x3f,0x71,0x41,0xfb,0xb0,0x20,0x8,0x82,0x20,0x8,0x82,0xf0,0x57,0x41,0x4a,0x40,0x4,0x41,0x10,0x84,0xdb,0x8e,0x6b,0xba,0xda,0xf4,0x19,0x53,0x80,0xd6,0xaa,0x6a,0x61,0x4a,0x69,0x72,0xf5,0xe5,0x5c,0x63,0xb4,0x9a,0xa3,0xb4,0xc6,0xce,0xff,0x6c,0xe5,0x94,0xe0,0x83,0x87,0x6b,0x3b,0x84,0x10,0xf6,0xcf,0x9a,0xd3,0x1a,0x7f,0xfb,0x63,0xf,0x21,0xa5,0x3c,0x47,0x7c,0x1,0xa4,0x9c,0xa1,0x55,0x89,0xc7,0x92,0xd8,0x60,0x8d,0x81,0x75,0x16,0xd6,0x58,0x38,0x67,0xf7,0xb6,0xfb,0xee,0x63,0x1c,0x27,0x7c,0xf2,0x8f,0xfe,0x14,0x9f,0xfb,0xda,0xe3,0x34,0x83,0x6d,0x1a,0xab,0xe8,0x93,0xb9,0x49,0x35,0xb1,0x6b,0x31,0x72,0xb9,0x47,0x99,0x73,0xb7,0x3f,0xd7,0x49,0x42,0x61,0x8a,0x11,0x31,0x66,0x76,0x85,0x69,0xdc,0xb8,0x79,0x7c,0xee,0xa5,0x4a,0x1,0x1f,0x78,0xf7,0x83,0xf8,0xda,0xa3,0x3f,0x44,0x2a,0xef,0x9d,0x46,0x0,0xa,0x21,0x78,0xbc,0xea,0xea,0x25,0x3c,0xf4,0x81,0xb7,0xef,0x3d,0x6f,0x12,0x7a,0xa8,0x6d,0xf7,0xb0,0xd5,0x48,0x8d,0xc5,0x10,0x32,0x32,0x32,0xcf,0x3c,0x34,0x17,0xbc,0x8f,0xe6,0x30,0xe6,0x94,0x59,0x88,0x35,0xb5,0x70,0xa4,0x44,0x90,0xe9,0xba,0x73,0x15,0x68,0xf7,0x9d,0xb8,0x9f,0xa8,0x2c,0x82,0x8a,0x2f,0xa8,0x1c,0xc5,0x35,0x24,0xfc,0x6d,0x4e,0x6f,0xa0,0x69,0x57,0xdc,0x80,0x1b,0xa1,0x2f,0x70,0x4b,0x4e,0xe3,0x0,0xcb,0xb3,0xfa,0x62,0x8a,0x24,0x7e,0xc6,0x80,0xa1,0xdf,0xe2,0x33,0x5f,0xfc,0x3a,0xde,0xf9,0x8e,0xb7,0xe2,0x3,0xef,0x7d,0xe7,0xb9,0xf7,0xbd,0xee,0xfe,0xfb,0xf0,0x9f,0xfc,0x47,0xbf,0x89,0xaf,0x7f,0xfb,0x31,0xfc,0xf9,0xd7,0xbe,0x83,0xc7,0xbf,0xff,0xc,0xb6,0x7d,0x8f,0x29,0x66,0x1c,0x1e,0x1e,0xe0,0x8e,0xa3,0x35,0xde,0xf6,0xe6,0xd7,0xe1,0x17,0xdf,0xf1,0x20,0xde,0xf8,0xc0,0x6b,0xf8,0x3a,0xce,0xde,0xa6,0x8c,0xcf,0x7d,0xf1,0x6b,0x78,0xec,0x7,0xcf,0x73,0xac,0x3c,0xd7,0x3d,0x9b,0xd8,0x41,0x39,0xcf,0xb8,0xdc,0x25,0xa5,0x8,0xcd,0xd,0xbc,0xc3,0xf6,0x14,0x4a,0x6b,0x6c,0x4f,0x8f,0x29,0xa6,0x1e,0x23,0xbc,0x1f,0x71,0x78,0xe9,0x4a,0x8d,0xa3,0xd3,0x36,0x39,0xdf,0x2,0x9c,0x51,0x8a,0x71,0x5c,0xbd,0x37,0x63,0xbf,0xad,0x2e,0xd9,0xcf,0x7d,0xe9,0x1b,0xf8,0xd0,0x7,0xdf,0x83,0xb7,0xbe,0xe5,0x4d,0x3b,0xa7,0x61,0x8c,0xc6,0x47,0x1e,0xfa,0x0,0xde,0xf3,0xf6,0x7,0xf1,0xad,0xef,0x3e,0x8a,0x47,0x1f,0x7f,0x1a,0x3f,0x7a,0xf1,0x3a,0x86,0x61,0x44,0x88,0x1,0xae,0x5d,0x21,0x84,0x0,0xe7,0x1a,0x72,0xe7,0x5d,0x20,0xb0,0x6b,0x9e,0x1b,0xd9,0xb4,0x2d,0x86,0x6d,0x29,0x65,0x99,0x90,0x73,0xc6,0xb0,0xdd,0xe0,0xf0,0xf2,0x15,0x58,0xe7,0x38,0x4e,0x4f,0x27,0x5c,0xdc,0xa5,0x61,0x9a,0x66,0x51,0x9c,0x9b,0xbe,0x93,0x9f,0x16,0xb1,0x69,0x6e,0x1f,0x8e,0x5e,0x7e,0x60,0xa,0x82,0x20,0x8,0x82,0x20,0xdc,0x2,0x44,0x0,0x14,0x4,0x41,0x10,0x6e,0x3b,0x54,0x94,0xa0,0x78,0xce,0x1f,0x89,0x1c,0x31,0x86,0x3a,0x47,0xe,0x25,0xfa,0xcb,0xe,0x24,0x65,0x2d,0x94,0xd1,0xf0,0xe3,0x50,0x5b,0x49,0x63,0x8a,0xb0,0xc6,0xbd,0xac,0xcb,0xd,0xc0,0x85,0x4d,0xbd,0xb7,0x82,0x67,0x9f,0x7b,0x1e,0xbf,0xff,0x47,0x9f,0xc7,0xc3,0x4f,0x3c,0x7,0x3f,0x8d,0x3c,0x7f,0x2d,0xcc,0x22,0x46,0x6,0xa0,0x32,0xb4,0xb5,0xc8,0x29,0xd7,0xd9,0x67,0x31,0x92,0xdb,0xee,0x22,0xc8,0xd,0x99,0x6a,0x43,0xac,0x9f,0x46,0x3c,0xf6,0xd4,0x33,0x8,0x21,0xc2,0xda,0x5d,0x31,0xea,0x4d,0xf,0xdc,0x8f,0xdf,0xf9,0xd8,0xbf,0x8d,0x4f,0x7e,0xfa,0x8b,0xb8,0xd9,0x7,0xc4,0x18,0x71,0xd7,0xe5,0x3,0xbc,0xfb,0xc1,0x9f,0xc7,0x43,0x1f,0x7c,0x17,0x8e,0xe,0xd7,0x7b,0x3f,0xe3,0xde,0xab,0x87,0x68,0xc,0xf0,0x8b,0x6f,0x7e,0x1d,0x3e,0xf2,0xd0,0xfb,0xf0,0xbf,0xfe,0xe1,0xa7,0xf1,0xd5,0x87,0x1f,0x3,0x40,0xc2,0x9a,0x9f,0xc6,0xbd,0xef,0x4b,0xa9,0x88,0x36,0x74,0x1e,0x63,0xbf,0x41,0x8,0x13,0x47,0x9b,0x1d,0x82,0x1f,0xb9,0x74,0x45,0x2f,0x4a,0x1d,0xce,0x5e,0x9f,0xaa,0xe5,0x2c,0x31,0x52,0x8b,0xaf,0xd6,0x6,0xe3,0x34,0x62,0x75,0x70,0x84,0x7e,0x7b,0x52,0x9d,0x60,0xcb,0x59,0x88,0xfb,0x98,0xc6,0x81,0xdc,0x67,0xd3,0x50,0x9b,0x8d,0x73,0x4a,0x98,0x42,0xc2,0x3f,0xfe,0x67,0xff,0x3b,0xee,0xba,0x7a,0x15,0x6f,0x78,0xe0,0xfe,0x73,0xef,0xeb,0xba,0x16,0xef,0x7f,0xf7,0xdb,0xf0,0x8b,0xef,0x7a,0x2b,0x36,0x9b,0xd,0xa6,0x89,0xd6,0xae,0x69,0x1c,0xd6,0xab,0xe,0x8e,0x63,0xd1,0x17,0xf1,0xad,0xef,0x3e,0x8e,0x7f,0xf9,0x27,0x5f,0x3e,0xb3,0x36,0x14,0x59,0x8e,0xda,0x20,0xc5,0x9,0x31,0xbc,0xfc,0x79,0x3,0x40,0xbb,0x5a,0x63,0xec,0xb7,0x68,0x9a,0x16,0x9b,0x93,0x1,0xde,0x4f,0x58,0xad,0xf,0xe1,0xa7,0x91,0x8e,0x15,0x42,0x6d,0xc3,0xde,0x87,0xe6,0x75,0x6e,0xbb,0x35,0xfa,0xcd,0x9,0x32,0x47,0xb4,0xad,0x35,0x88,0x9,0xf8,0x27,0xff,0xf3,0xbf,0xc0,0x7f,0xf1,0xf,0xff,0x2e,0x7e,0xee,0xbe,0x7b,0xce,0xdc,0x3,0xe0,0xce,0xab,0x97,0xf1,0xd0,0x2f,0xfd,0x22,0x7e,0xe5,0x83,0xef,0x45,0x8,0x91,0x62,0xb9,0x2c,0x36,0xce,0x72,0xa3,0x82,0xdd,0x33,0xcb,0x31,0xf3,0x73,0x5c,0xf6,0x89,0x52,0x24,0x3a,0x6b,0x63,0xd1,0x6f,0x4e,0xb1,0x3a,0x3c,0x2,0x40,0x85,0x32,0xd6,0x96,0x98,0x2f,0xdd,0x53,0x6d,0xc,0xb2,0xa2,0x7d,0x4e,0xe2,0x22,0xed,0x7,0xb,0x87,0x69,0x24,0xb7,0x2c,0x45,0x84,0x25,0xa8,0x22,0x8,0x82,0x20,0x8,0x82,0x70,0xab,0x10,0x1,0x50,0x10,0x4,0x41,0xb8,0xed,0xe4,0x4c,0xe2,0x42,0x5e,0xc4,0x47,0x35,0x37,0xf4,0x2,0xa8,0x65,0x6,0x34,0x83,0xd,0x3c,0x13,0x6c,0x6e,0xb4,0x4d,0x29,0xc2,0x28,0x45,0xee,0xc1,0xac,0x2f,0x2c,0xba,0xf8,0xeb,0xa2,0x1f,0x46,0x7c,0xe9,0x2f,0xbe,0x85,0x3f,0xf8,0xbf,0xbe,0x88,0xd3,0x81,0x44,0xbd,0x94,0x22,0xac,0x36,0x50,0x8a,0x84,0x91,0x32,0xb7,0xad,0xc4,0x65,0x1,0x20,0x4c,0x23,0xbb,0xa6,0x2,0xb6,0x27,0x37,0x6b,0xc4,0x77,0x7,0x8e,0x4b,0xfa,0x69,0x84,0xb1,0x16,0x31,0x6,0x78,0x3f,0xe2,0xd1,0xa7,0x9e,0xc3,0xb3,0xcf,0xbf,0x88,0xfb,0x5f,0x7d,0xcf,0xb9,0xb7,0xbc,0xf3,0x6d,0x6f,0xc2,0x5b,0xde,0xf8,0x5a,0xdc,0x3c,0xde,0x40,0x1,0x38,0x3a,0x5c,0xa3,0xeb,0xda,0x97,0x15,0xb0,0x3e,0xf4,0xfe,0x77,0xe2,0x7d,0xef,0x7a,0x2b,0xe,0xd6,0x1d,0x32,0x80,0x30,0x6e,0x1,0x50,0xe1,0x48,0x98,0x46,0x72,0x65,0xee,0xbd,0x77,0x69,0x16,0xe6,0x40,0x5,0x2d,0x7e,0x9a,0x28,0xfe,0x1b,0xc9,0x89,0x69,0x1d,0xb8,0x9d,0xf9,0x22,0x1,0x8c,0xd6,0x2b,0x4,0x5f,0xdb,0x6f,0x83,0x9f,0x60,0x8c,0xc5,0xe6,0xe4,0x26,0x8a,0x6b,0x72,0x1a,0x7,0x18,0x6b,0xf7,0xa,0x80,0x25,0x22,0x1e,0x23,0xed,0x1,0x6d,0x2c,0xbc,0xdf,0x72,0xac,0x94,0x5c,0x85,0x27,0xdb,0x1e,0xff,0xf5,0x7f,0xff,0xcf,0xf1,0xf,0x3f,0xf1,0xb7,0xf0,0xe0,0x9b,0xdf,0xb0,0xf7,0x4c,0xb4,0x52,0x38,0x3a,0x3c,0xfc,0x4b,0xec,0xdd,0x8c,0x6f,0x7e,0xfb,0x51,0xfc,0x4f,0x7f,0xf0,0x59,0xf4,0xe3,0xc4,0xa5,0x28,0x54,0xc4,0x61,0x8c,0xad,0xf3,0x11,0x43,0xf0,0x80,0x6b,0xf7,0xba,0x3c,0x8b,0x5b,0xb0,0xec,0xf5,0x69,0x1c,0xe0,0xfd,0xc8,0xa2,0x68,0x69,0xb6,0xa6,0xf9,0x89,0xcb,0x59,0x90,0x67,0xef,0x67,0xe2,0xe2,0x17,0x7a,0x26,0x48,0x28,0xf5,0x2c,0x2c,0x6,0x3f,0x41,0x69,0x8d,0xe7,0x5e,0xbc,0x86,0xff,0xf6,0x9f,0xfd,0x1e,0xfe,0xfe,0x6f,0xff,0x26,0x5e,0xfb,0x9a,0xfb,0xf6,0xee,0x9,0xa5,0xd4,0x85,0x85,0x2d,0x2f,0xf7,0x10,0x53,0x83,0xb4,0x42,0xf4,0x9e,0x66,0x1f,0x1a,0x4b,0x45,0x3b,0xdc,0x32,0x6c,0xac,0x83,0x6b,0x5a,0x4c,0xe3,0x80,0xa6,0x5b,0xd5,0x36,0xee,0x14,0x13,0x47,0x97,0x69,0xbd,0x14,0x50,0xf7,0x4e,0x89,0x16,0x73,0x1e,0x58,0x7e,0x58,0xa,0x82,0x20,0x8,0x82,0x20,0xdc,0x22,0xe4,0xff,0x5a,0x15,0x4,0x41,0x10,0x6e,0xff,0x3f,0x3e,0x5a,0xb3,0xc7,0x8,0xec,0x58,0x2a,0x2e,0x2f,0x55,0x67,0xe0,0x69,0x76,0x1,0x96,0x79,0x78,0xf4,0xfa,0xcc,0xe5,0x21,0xac,0x11,0xf0,0xf7,0xa1,0x2e,0x98,0xa7,0x77,0xb,0xc9,0x39,0xe3,0xe4,0x64,0x83,0x2f,0x7c,0xf9,0x1b,0xf8,0x2f,0xff,0xf1,0xef,0xe2,0x7f,0xf9,0x97,0x7f,0x8a,0xed,0xe8,0x91,0x78,0xc6,0x5f,0x8c,0x1,0x21,0xf8,0x2a,0xbc,0xf8,0x69,0xc0,0x34,0xd,0x98,0xc6,0x81,0xbe,0x1f,0x3c,0x94,0xd6,0x18,0x79,0x36,0x1a,0x89,0x3c,0x71,0xcf,0x27,0x29,0x4,0xef,0xf9,0x3d,0x81,0x1d,0x54,0xe,0x7d,0xbf,0xc5,0xef,0xfd,0xe1,0xa7,0x30,0x8e,0xd3,0xde,0xf3,0xeb,0xda,0x16,0xf7,0xdc,0x7d,0x15,0xaf,0xba,0xfb,0x2a,0x56,0xab,0xe,0x4a,0x29,0xc4,0x18,0xf1,0xbd,0x27,0x9f,0xde,0xfb,0x7a,0xe7,0x2c,0xe,0xf,0x56,0xe4,0xc6,0xa3,0x9b,0x82,0xcd,0xe9,0x4d,0xf4,0xa7,0x27,0xb5,0x5,0x77,0x1f,0xb3,0x80,0xa4,0xaa,0xab,0xb1,0xcc,0xe1,0x2b,0xe5,0x2e,0x5a,0x1b,0x5a,0x87,0xb,0xf4,0xc7,0x52,0x90,0x52,0x4,0xac,0xe2,0x74,0x1c,0xb6,0xa7,0x70,0xae,0x41,0xf4,0x13,0xa0,0x74,0x75,0x6,0x5e,0x4,0xb9,0xd,0xc9,0x1,0x57,0xe6,0x11,0xc6,0x18,0x31,0xd,0x3d,0x15,0xaf,0xc4,0x80,0x1b,0x27,0x5b,0xfc,0x37,0xff,0xe3,0xff,0x86,0x3f,0xfd,0xc2,0x57,0xe0,0x7d,0xf8,0xa9,0xf6,0xc0,0x30,0x8c,0xf8,0xd4,0xa7,0x3f,0x8f,0xff,0xee,0x77,0x3f,0x85,0x9b,0xc7,0x27,0x48,0x31,0x60,0x1c,0xb6,0xc8,0xc8,0x88,0xc1,0xf3,0xbd,0x4e,0x34,0xd3,0x8f,0xb,0x65,0x32,0xf6,0xc7,0xbc,0x63,0x28,0x71,0xdf,0x89,0x8a,0x5a,0x32,0x95,0xc5,0x94,0x38,0x34,0x9,0x83,0x3d,0x8c,0x21,0x51,0x79,0x9f,0x70,0x57,0xe6,0x8,0xc6,0xe0,0x79,0x66,0xa2,0xaf,0xe2,0x5b,0x8,0x13,0xfc,0x44,0x6e,0xcc,0x1f,0x3c,0xf7,0x22,0xfe,0xab,0x7f,0xf2,0xbb,0xf8,0xfc,0x9f,0x7d,0x5,0xe3,0x34,0xdd,0xb2,0x67,0x42,0xf1,0xbd,0x9,0x61,0x42,0xf0,0x13,0xc6,0xa1,0xaf,0xb3,0x0,0x37,0x27,0x37,0x31,0x8d,0x7d,0x9d,0x6f,0x58,0x4,0xdb,0x32,0xe3,0x53,0xf3,0x33,0x92,0x79,0xbd,0x72,0x46,0x9d,0x47,0x58,0x74,0xbf,0x8b,0xe6,0x50,0xa,0x82,0x20,0x8,0x82,0x20,0x8,0x7f,0x79,0xc4,0x1,0x28,0x8,0x82,0x20,0xdc,0x76,0x66,0x47,0x93,0x86,0x2a,0xfa,0x48,0x9e,0x9b,0x7e,0x33,0xb,0x1,0x34,0x3,0x6d,0x1e,0xa3,0x96,0x62,0x84,0x71,0x86,0x5e,0x87,0x8c,0x94,0x48,0x48,0xf1,0x7e,0xe2,0x52,0x8d,0x5b,0xcb,0xe4,0x3d,0xfa,0x7e,0xc0,0x33,0xcf,0xbd,0x80,0xaf,0x7d,0xeb,0x51,0x7c,0xf9,0xe1,0xc7,0x71,0xbc,0x19,0xf8,0x7c,0x14,0xa6,0x38,0xce,0x85,0x25,0x39,0x2f,0x4,0x8d,0x8,0xa5,0x34,0xfc,0xd8,0xa3,0xe9,0x56,0x34,0xeb,0x2c,0x78,0xf8,0x71,0xa8,0x71,0x4e,0x6b,0x1b,0xe4,0x7d,0x2,0x60,0x2e,0x42,0x67,0x46,0x42,0x44,0xce,0x9,0xfd,0x29,0x39,0xdb,0x3e,0xff,0x95,0x87,0x71,0xd7,0x1d,0x9f,0xc4,0xbf,0xf7,0xf1,0x8f,0xe2,0x60,0xbd,0xbe,0xf0,0xbc,0x73,0xce,0x78,0xfe,0x85,0x97,0xf0,0xaf,0x3f,0xfb,0xe7,0xf8,0xc6,0xa3,0x3f,0xc0,0x7f,0xf6,0x1f,0xff,0x7,0xb8,0xe7,0x55,0xfb,0x4b,0x4c,0xc6,0x69,0xc2,0xe7,0xff,0xec,0x2b,0x78,0xec,0xa9,0x67,0xd1,0xb4,0x2b,0x6c,0x4f,0x6e,0x22,0xe,0xe1,0x42,0xf1,0x25,0xa7,0xc4,0xae,0x34,0x9a,0xf3,0x57,0xc4,0xcf,0xf2,0x35,0x6d,0x2d,0xb,0x7c,0xd4,0xfc,0x7a,0x41,0xd,0x8,0x0,0x12,0xb5,0xfc,0x34,0x72,0xf9,0x4b,0xe4,0xd8,0x30,0xdd,0x4f,0xcb,0x62,0xaa,0x31,0xb6,0xb6,0x42,0x2f,0x21,0xcd,0x97,0x23,0xe2,0x5a,0x63,0x1a,0xfb,0xda,0x44,0x3c,0xf6,0x1b,0xe4,0x9c,0x10,0xbc,0x87,0x6b,0x3a,0xc,0xd6,0xe1,0x9f,0xfe,0x1f,0x7f,0x84,0x6f,0x7e,0xe7,0x31,0x7c,0xe4,0xa1,0xf,0xe0,0xf5,0x3f,0xbf,0x7f,0xae,0xdf,0x45,0xf4,0x7d,0x8f,0xef,0x3c,0xfa,0x4,0x3e,0xf5,0xd9,0x2f,0xe1,0x89,0x67,0x5e,0x24,0x41,0x9a,0x1d,0x7a,0xd6,0x35,0x48,0x31,0x62,0x1a,0x7,0x6a,0xe4,0xcd,0x99,0xdc,0x88,0xd3,0x8,0xdd,0xad,0xf7,0xee,0xcb,0x12,0xd3,0x9d,0xb,0x54,0x12,0x3c,0xcf,0xc4,0x33,0xd6,0xa2,0xdf,0x9e,0xa2,0x5b,0x1d,0xc0,0x44,0x2a,0x6a,0x29,0x6e,0xd9,0xb3,0x22,0xa0,0xd1,0x1a,0xd1,0x93,0xe3,0x11,0x6a,0x76,0xd5,0xf6,0xdb,0x13,0xf8,0x71,0xc4,0xc1,0xa5,0x3b,0xb8,0xd4,0xa4,0xc5,0xf1,0xa6,0xc7,0x3f,0xfd,0x17,0x9f,0xc1,0xff,0xf3,0xe5,0x6f,0xe1,0x23,0x1f,0x7a,0x2f,0x5e,0xff,0xba,0xfb,0x71,0xe9,0xe8,0xf0,0x27,0x9e,0x75,0x79,0xfe,0x6,0x0,0xd3,0xb0,0xad,0xd7,0x5b,0xca,0x42,0xe8,0xef,0x24,0x5a,0x6a,0x6d,0x90,0x52,0x82,0x6b,0xc,0xb4,0x52,0xdc,0x1c,0xcc,0x25,0x37,0x2c,0x14,0x53,0xd9,0x48,0x84,0x31,0xe,0x4a,0x71,0xc1,0xf,0xb,0xfa,0xd2,0x2,0x2c,0x8,0x82,0x20,0x8,0x82,0x70,0xeb,0x10,0x1,0x50,0x10,0x4,0x41,0xb8,0xed,0x4,0x3f,0xb7,0xe0,0xce,0xb3,0xde,0x72,0x75,0x90,0xd5,0xbf,0x67,0x20,0x2b,0x7e,0xd,0xbf,0x37,0x6,0x5f,0x1d,0x66,0x25,0x72,0xd9,0xf,0x23,0xbe,0xfb,0xd8,0x93,0x38,0x38,0x58,0x21,0xa7,0x39,0x92,0x59,0x1a,0x86,0x8b,0x8c,0xb0,0x33,0x53,0x8e,0x5,0x47,0x72,0xc0,0x29,0x40,0x69,0x8c,0xd3,0x88,0x6d,0x3f,0xe2,0x74,0xd3,0xe3,0x85,0xeb,0x27,0x78,0xea,0xe9,0xe7,0xf0,0xcc,0xb,0xd7,0x91,0xa0,0xab,0xb3,0x4f,0x73,0xc9,0x45,0xf4,0x9e,0xe6,0x9e,0xf9,0x89,0x8f,0xad,0x91,0x52,0x84,0x73,0x2d,0xa6,0x69,0x40,0x4e,0x1e,0xc6,0x3a,0x2e,0xf3,0x88,0x48,0x29,0xc1,0xfb,0x89,0xa2,0xaf,0x13,0xb9,0xbe,0x9e,0x7c,0xea,0x7,0x38,0x3c,0x3a,0xac,0x51,0x60,0xad,0xd,0x26,0x1f,0x30,0x8c,0x13,0x52,0x8e,0xd0,0xd9,0x40,0x71,0xac,0x38,0x83,0x84,0x95,0x3f,0xf8,0xbf,0xff,0xc,0x8f,0x3f,0xf5,0x34,0x3e,0xfe,0x1b,0xbf,0x86,0x37,0x3c,0xf0,0x3a,0x74,0x5d,0xcb,0xcd,0xc3,0x9,0xc3,0x38,0xe2,0xd9,0x1f,0xbd,0x80,0xaf,0x7e,0xe3,0x11,0x7c,0xe1,0xeb,0x8f,0x61,0xb3,0xed,0x1,0x5,0xfc,0xf,0xff,0xfc,0xf7,0xf1,0x77,0xfe,0xfd,0x8f,0xe2,0xbe,0x7b,0xef,0x46,0xe3,0xa8,0x31,0x76,0x1c,0x27,0x3c,0xf2,0xbd,0x27,0xf1,0xa9,0xcf,0x7c,0x1,0xf,0x3f,0xfe,0x34,0xa2,0xf7,0x18,0xc7,0x1,0x4a,0x29,0x8c,0xc3,0x16,0x2f,0xbc,0x78,0xd,0xf,0x7f,0xe7,0x91,0xda,0x40,0x5b,0x44,0xcf,0x17,0xaf,0x5d,0x7,0x72,0x66,0x77,0x9a,0x5,0x32,0x15,0x79,0xf8,0x71,0x40,0xf0,0x1e,0x7e,0xa2,0x62,0x8e,0xd5,0xc1,0x11,0xfa,0xbe,0xc7,0xa3,0xdf,0x7b,0x2,0xab,0x6e,0x55,0xd7,0x5e,0x69,0x8d,0x27,0xbf,0xff,0xc,0xbb,0xff,0x48,0x34,0xb,0x7e,0xc4,0xd8,0x6f,0x0,0xa5,0x30,0x8d,0x3d,0xb9,0x17,0x83,0x47,0xce,0x2b,0x78,0x3f,0xe1,0xf1,0x27,0x9e,0xe2,0x7d,0xc1,0xb1,0x70,0x6d,0x70,0xba,0xd9,0x60,0x9a,0x26,0xe4,0xac,0x90,0xb8,0x4d,0x76,0xd8,0x9c,0x22,0x46,0x72,0xe2,0x41,0xd1,0x79,0xe5,0x94,0x30,0xe,0x5b,0xb4,0xdd,0x1a,0x7f,0xfe,0xcd,0xc7,0xf1,0x17,0x8f,0xfc,0x10,0xaf,0xbb,0xf7,0xa,0xde,0xfb,0x6f,0xbd,0x11,0x6f,0x7d,0xf0,0x8d,0xb8,0x7c,0xe9,0x10,0x6d,0xdb,0xc2,0xf0,0x3a,0x93,0x83,0x2f,0xa1,0xef,0x7,0xbc,0x74,0xe3,0x18,0xdf,0xfc,0xce,0xf7,0xf0,0xa5,0xaf,0x7f,0x17,0x2f,0xde,0xdc,0x70,0xd9,0xcc,0xec,0x56,0x35,0xc6,0xf0,0xf9,0x16,0xf7,0x63,0xc4,0xe4,0x27,0xfa,0xbb,0xd6,0x38,0x3d,0x3d,0xc1,0x77,0x1f,0x79,0x14,0xeb,0x83,0x3,0xce,0xbd,0xd3,0x7d,0x7e,0xf2,0xa9,0x1f,0xb0,0x18,0x46,0x85,0x2a,0x31,0x44,0x94,0x96,0x5c,0x3f,0x4d,0xe8,0x56,0x6b,0x24,0x2e,0x8b,0x19,0xfb,0x2d,0xae,0xdf,0x3c,0xc1,0x77,0x1f,0x7d,0x7c,0xd1,0x6,0x4c,0x9f,0xff,0xec,0xf3,0x2f,0x21,0x46,0x8f,0x94,0x23,0x14,0x17,0xbf,0x90,0xbb,0x94,0x1a,0x7d,0xa7,0xa1,0x87,0x6b,0x3b,0xf4,0x9b,0x13,0xac,0xe,0x8e,0x10,0x53,0xc0,0x77,0x9f,0x7c,0x16,0x8f,0x3d,0xfd,0xaf,0xd0,0x59,0x8d,0x37,0xbf,0xf6,0x6e,0xbc,0xf6,0x35,0xf7,0xe2,0xee,0xab,0x77,0x60,0xbd,0x5e,0x2d,0xe6,0x1e,0xd2,0xf3,0x43,0xcf,0x4e,0x86,0x2,0x39,0xf7,0x34,0x8b,0xa6,0x29,0x45,0x5c,0xbb,0x7e,0xb3,0x46,0x79,0xfd,0x34,0xb2,0xa8,0x4f,0x6b,0x3d,0x6c,0x37,0xb0,0xd6,0xd6,0x79,0x8c,0xc1,0x7b,0xb4,0xdd,0x8a,0x44,0xe5,0xa4,0x11,0xa2,0x7,0x32,0x89,0xc3,0xc6,0xd8,0xfa,0xec,0x94,0x58,0x74,0x69,0x3,0xcf,0x49,0x1c,0x80,0x82,0x20,0x8,0x82,0x20,0x8,0xb7,0x8a,0xbf,0xfe,0xcc,0x94,0x20,0x8,0x82,0x20,0x9c,0xe1,0xd2,0x5d,0xaf,0xc6,0x3b,0x3f,0xf8,0x6b,0x35,0x1e,0x19,0x43,0xa8,0x4d,0xbf,0xc5,0xee,0xa7,0x35,0xcd,0xf6,0x33,0x1c,0x47,0x35,0xce,0x91,0x8,0x58,0xbf,0x6f,0x6a,0x74,0x52,0x71,0x54,0xb4,0xb8,0x7,0xdb,0x8e,0x4,0x94,0xe2,0x1c,0xa3,0x56,0x5b,0xd,0xef,0xa9,0x75,0xd5,0x18,0x8b,0xa1,0xdf,0x0,0x0,0xc2,0x34,0x1,0xc8,0x50,0xda,0xa0,0x5b,0x1f,0x52,0x6b,0xa9,0x31,0x30,0xb6,0xe1,0x98,0xe2,0x58,0x67,0xca,0x1,0x80,0xd2,0xba,0xc6,0x63,0x8b,0x83,0xcd,0xb0,0xeb,0xd,0x2c,0x5c,0xcd,0x65,0x20,0x9a,0x44,0xa1,0x69,0xa4,0xf6,0x61,0x16,0xa3,0x4a,0x5c,0xb4,0x5b,0x1f,0x20,0xc5,0x88,0xd5,0xc1,0x25,0x74,0xeb,0x3,0x68,0xad,0x61,0x6d,0x53,0x63,0x93,0xc5,0x51,0x16,0xfc,0x88,0x7e,0x7b,0xa,0x5,0x55,0x45,0x44,0xad,0xd,0x5e,0xfb,0x73,0xf7,0xe1,0xde,0xbb,0xaf,0xa2,0xeb,0x56,0x18,0x7d,0xc4,0xb5,0x93,0x1,0x37,0x4e,0x4e,0x17,0xe2,0x9,0x45,0x6b,0xc7,0x61,0x8b,0xb6,0x6d,0x71,0xf7,0xa5,0xe,0x77,0x5c,0x3a,0x84,0x32,0x16,0x2f,0xdd,0x38,0xc5,0x33,0xcf,0xbf,0x44,0x2e,0xad,0x9c,0xa8,0x3d,0x36,0x78,0x72,0xf3,0xc5,0x48,0xf3,0x7,0x3,0x45,0x59,0x57,0x7,0x47,0x80,0x2,0x9a,0x76,0xc5,0x33,0xdc,0x22,0x34,0xcf,0xa,0x1c,0xc7,0x1e,0x63,0xbf,0xc1,0x38,0x6c,0xe1,0x9a,0xe,0x9b,0xe3,0x1b,0x68,0x57,0x2b,0xb4,0xab,0x3,0x58,0xdb,0xc0,0x3a,0x57,0xdf,0x47,0xf3,0x1,0x1b,0x4c,0x63,0x4f,0xf3,0xe0,0x34,0xb5,0xc1,0xc6,0x14,0xb1,0x39,0xbe,0x51,0x9b,0x80,0x3,0x8b,0x58,0xae,0xed,0x70,0x78,0xf9,0xa,0x72,0x4a,0x70,0x4d,0xb,0xeb,0x9a,0x1a,0xf9,0x2d,0xfb,0xa3,0x8,0xc6,0xd3,0x34,0xd6,0xf3,0x29,0x11,0xe3,0xa6,0xed,0x10,0x63,0xc0,0x1d,0x77,0xd2,0xdc,0x44,0x6b,0x1d,0x39,0xf6,0x52,0x82,0xf7,0x23,0x90,0x22,0xd6,0x4e,0xe1,0xd2,0xba,0xc1,0xe1,0xe1,0x1,0xba,0x6e,0x8d,0xcd,0x30,0x61,0xf4,0x1,0xdb,0x29,0x61,0x3b,0x7a,0x2e,0x2c,0xa1,0x7d,0x44,0x62,0x6e,0xa8,0x25,0x26,0xc1,0x53,0xb,0x35,0xcd,0xdd,0x63,0xd7,0x66,0xa6,0xe2,0x93,0xcd,0xc9,0x8d,0x3a,0x9f,0xf,0x19,0x30,0xce,0x21,0x7a,0x8f,0xc3,0xcb,0x57,0xa0,0x94,0x86,0xb1,0xe,0xc6,0x52,0xc1,0x8b,0xe7,0xd2,0x95,0xa1,0xdf,0x20,0xa7,0xb9,0xfd,0xfa,0xf0,0xd2,0x15,0x40,0x29,0x34,0x4d,0x47,0x7b,0x92,0xdd,0x86,0xc6,0x98,0x3a,0x17,0xb3,0xc4,0xc8,0x73,0xce,0xe8,0x37,0xa7,0x8,0x7e,0xe4,0x3d,0xe3,0x31,0xe,0x5b,0xdc,0x79,0xcf,0xcf,0x21,0xa7,0x84,0x83,0xa3,0xcb,0x48,0x39,0xb1,0xf3,0x94,0x84,0xbb,0xed,0xe9,0x31,0x17,0xb1,0x4,0x8c,0xfd,0x16,0xae,0x69,0xe1,0x9a,0x6,0x39,0x3,0xab,0x3,0x12,0xa6,0xad,0x73,0x14,0xd3,0x8e,0x89,0x67,0x52,0x46,0x6a,0x39,0x56,0x24,0xe4,0x3,0x19,0x63,0x4f,0xb1,0xf6,0x7e,0x7b,0x82,0x69,0x1c,0x30,0x6c,0x4e,0xe8,0x99,0x36,0x6,0x47,0x77,0xdc,0xc9,0xf7,0x8e,0xda,0x80,0x15,0xef,0xa,0x80,0x86,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x54,0x5d,0xc3,0xf2,0xd9,0xf4,0x2c,0x69,0xc4,0x48,0x71,0xf0,0xb1,0xdf,0x62,0x7b,0x7a,0x8c,0x27,0xbf,0xfd,0x65,0x6e,0x54,0x16,0x4,0x41,0x10,0x4,0x41,0x10,0x7e,0x5a,0xc4,0x1,0x28,0x8,0x82,0x20,0xdc,0x76,0xd4,0xc2,0x59,0x94,0x91,0x61,0xd8,0x55,0x97,0x91,0x61,0x8d,0x63,0x37,0x10,0x95,0x4,0x0,0xa,0x4a,0xab,0x2a,0x12,0x5a,0xe7,0xea,0x9c,0x35,0x9a,0x3b,0xc7,0xb3,0x0,0x8d,0xe5,0xf8,0x20,0x9,0x9,0x24,0x12,0xd1,0x3c,0x32,0xad,0x4d,0xa9,0x34,0x25,0xb1,0x88,0x45,0xa2,0x18,0x3,0x86,0xed,0x6,0xeb,0xc3,0x23,0x16,0xf,0x23,0x82,0xcf,0x48,0x91,0x9c,0x77,0xc5,0x21,0x38,0xe,0x34,0x8b,0x2d,0xa5,0x8c,0xbc,0x70,0x20,0x96,0xe8,0x2a,0x42,0x29,0x76,0x48,0xb5,0xe0,0x84,0xe6,0xbf,0x25,0xf4,0xdb,0xd3,0xda,0x72,0x9c,0x33,0xcd,0x75,0x2b,0xe,0x44,0x32,0x72,0x29,0xc4,0xe8,0x6b,0x43,0xb0,0x5a,0x6b,0x12,0xa7,0x0,0x72,0xf6,0x95,0xb8,0x34,0x3b,0xbc,0x0,0xba,0xde,0xc,0xe0,0xf9,0xeb,0xc7,0xb8,0x76,0xd2,0xa3,0x69,0x3b,0x12,0x95,0x78,0x1d,0x4b,0x81,0x6,0x80,0x3a,0x7,0xce,0x4f,0x23,0xfa,0xbe,0xc7,0x93,0xcf,0xbe,0x8,0x6b,0x1d,0xb,0x2f,0x8a,0xe2,0x9b,0x3e,0x20,0x6,0x8a,0xec,0x6e,0x4f,0x8e,0xd1,0x74,0x1d,0x86,0xe3,0x53,0xb4,0xab,0x3,0x9a,0x7,0xc8,0xd1,0xec,0xc8,0xf3,0xfa,0x72,0xce,0x50,0x31,0xcc,0x62,0xa1,0xa1,0xfb,0xd4,0x6f,0x4e,0x58,0x90,0x22,0x17,0x59,0xf0,0x23,0xb,0x48,0x13,0xac,0x6d,0x0,0x5,0xc,0xdb,0x53,0x16,0xe1,0x22,0x54,0x26,0x71,0x2d,0x7a,0x8a,0x46,0xa7,0x18,0xb0,0x39,0xee,0x11,0xc2,0x44,0xa2,0x63,0xce,0x38,0xbd,0x79,0x1d,0x87,0x97,0xae,0x90,0x68,0xc7,0x71,0x61,0x63,0x5d,0x6d,0x9f,0x2d,0xf7,0x22,0x6,0x8f,0x10,0x3c,0x26,0x9e,0x43,0x17,0x3c,0x45,0x6a,0xbb,0xd5,0x1,0x17,0x83,0x34,0x54,0x92,0xe1,0x27,0xfa,0x7f,0x3f,0x53,0xc2,0xf6,0xf4,0x4,0x27,0x31,0xe2,0x79,0xad,0x31,0xd,0xdf,0x47,0xd3,0xad,0xd0,0x34,0x2d,0x8c,0x6b,0x60,0xad,0x63,0x61,0x99,0x5a,0x6a,0x53,0xa,0xd0,0xda,0xd6,0x7b,0x11,0x63,0xa8,0xe7,0x43,0xd,0xb8,0x81,0xd6,0x75,0xa2,0x8,0xb3,0x6b,0x3b,0xfa,0x2c,0xa5,0xe0,0xfd,0x58,0xe3,0xc9,0x24,0x6a,0xab,0x1a,0x75,0x2d,0x31,0x59,0x72,0x17,0xd2,0x3e,0x89,0x31,0x60,0xb5,0x3e,0x44,0x8,0x1e,0xd6,0x36,0x1c,0xa9,0xd5,0xd4,0x9e,0x9d,0x81,0xc0,0x31,0x71,0xbd,0x10,0xb8,0xfb,0xed,0x29,0x52,0xa,0x55,0x94,0x53,0x5a,0x51,0x1,0x7,0xaf,0xc7,0x34,0xe,0xb0,0xae,0x21,0xb1,0x92,0x23,0xb6,0x5a,0xd3,0x3d,0xf5,0x7e,0x82,0xf7,0x23,0xef,0xdf,0x54,0x45,0xe3,0xfa,0x5c,0xf2,0x7e,0x8d,0x31,0x50,0x2b,0x71,0xce,0x73,0x7c,0x9d,0x9f,0xd3,0x71,0xd8,0xd2,0x3c,0xcc,0xc8,0xae,0x5a,0x4d,0x22,0x67,0x79,0xe6,0x94,0x36,0x24,0x1c,0x6b,0x5d,0x5,0xd5,0x39,0x66,0x4e,0xc7,0x2b,0x6e,0xd0,0x3a,0xf7,0x53,0x4a,0x40,0x4,0x41,0x10,0x4,0x41,0x10,0x6e,0x19,0x6,0xc0,0x3f,0x92,0x65,0x10,0x4,0x41,0x10,0x6e,0x27,0xed,0xfa,0x10,0xf7,0xbe,0xe6,0x81,0x2a,0x20,0xe4,0x4c,0x45,0x6,0xb3,0x30,0x90,0xeb,0xdc,0x3f,0xa5,0xe6,0x79,0x61,0x8a,0x5b,0x5f,0x8d,0x31,0x3c,0x1f,0x70,0x2e,0xe,0x59,0xa,0x7d,0xc5,0x19,0xa5,0x39,0x4a,0x48,0x9,0x5f,0x4d,0xe,0x2d,0x16,0x6e,0xfc,0x34,0x92,0x13,0x8d,0x63,0x9c,0xc6,0x3a,0xa4,0x1c,0x39,0xa,0xca,0x11,0x44,0x9e,0x23,0x37,0x7f,0x2e,0xc5,0x1a,0x63,0xa,0x24,0x5a,0x20,0x73,0x7c,0x31,0xd5,0xf3,0x6,0x17,0x33,0x94,0x8,0x67,0xce,0x89,0xca,0x1d,0x62,0x40,0x98,0x26,0xf8,0x71,0x60,0xb7,0x22,0xcd,0xb6,0x73,0xae,0xad,0xa5,0x8,0xa5,0xfc,0xc4,0x5a,0x3b,0x97,0x22,0xc4,0x8,0xcf,0xe2,0xcd,0x38,0xf4,0x18,0xfa,0x53,0xc4,0x18,0xd1,0x74,0x2b,0x72,0x7b,0xa5,0x4,0x63,0x5c,0xbd,0xe6,0x69,0x1c,0x80,0x4c,0xf3,0xd9,0x4a,0x6c,0x39,0x6,0x4f,0x11,0x62,0x16,0x56,0x8a,0x98,0x63,0x39,0xa2,0x6c,0x9d,0xab,0xae,0x3b,0x20,0x23,0x4c,0x23,0x8b,0x31,0x1e,0x9a,0x85,0x9c,0xc4,0xf7,0xa0,0x14,0x73,0x14,0xe1,0x6b,0x1a,0x7b,0xc4,0x14,0x11,0x26,0x2a,0xc0,0x48,0x21,0x70,0x40,0x15,0xd0,0x1c,0x3,0xb5,0xb6,0xa9,0x11,0xcf,0xe2,0xdc,0x23,0x17,0xa3,0x85,0x2,0xe0,0xfd,0x88,0x18,0x49,0x20,0xcb,0x89,0x22,0xd3,0x80,0x82,0x71,0xe,0x6d,0xbb,0xa2,0x7d,0xa0,0x55,0x15,0x84,0xa3,0x27,0xd7,0x20,0xcd,0x8f,0x23,0xa1,0x88,0x4,0x62,0x12,0x3a,0xb7,0xa7,0xc7,0x7c,0x9c,0x80,0xa6,0x5d,0xf1,0x75,0xa3,0x16,0x8a,0xc4,0x48,0x42,0x59,0x66,0xb5,0x36,0xb0,0x90,0x7,0x94,0x8,0x32,0xe8,0xf3,0x39,0x9e,0x1a,0xd8,0xd5,0x59,0xc4,0xad,0x10,0x26,0x12,0xa0,0xcb,0x2c,0x3f,0xbe,0xde,0xc8,0xa2,0x72,0xf4,0x53,0x75,0xcd,0x6d,0x37,0xc7,0x8,0x13,0x9,0xb7,0xd6,0xba,0xda,0xf2,0xcb,0xb2,0x57,0x8d,0x4e,0xd3,0x39,0xcd,0xfb,0x43,0x69,0x3,0xd7,0xb4,0xac,0x5b,0xcf,0xd1,0x58,0xc5,0xc3,0xfe,0xa8,0xfc,0x23,0x40,0x69,0xda,0xbf,0x0,0xf8,0x39,0x51,0xe8,0x4f,0x4f,0xd0,0x6f,0x4e,0x58,0x5c,0x8c,0x68,0xbb,0x15,0xca,0x49,0xe6,0x9c,0x58,0x0,0xe6,0x73,0xd,0xe4,0x14,0x2c,0xe5,0x3a,0x89,0x8b,0x75,0x8c,0x75,0x74,0xdf,0x72,0xae,0xd7,0x5d,0x44,0xec,0x22,0xa,0x66,0x8e,0xb5,0x47,0x2e,0xad,0x9,0x7e,0xc4,0x34,0xf4,0x18,0x87,0x2d,0x0,0x85,0xa6,0xed,0xa0,0x8d,0xe6,0xfb,0x5a,0xf6,0x41,0xaa,0x4d,0xd2,0xe0,0xc6,0x5f,0xa5,0xf8,0xd9,0xe,0xa1,0xc6,0xbf,0xa7,0x61,0x8b,0xe3,0x6b,0xcf,0x4b,0x11,0x88,0x20,0x8,0x82,0x20,0x8,0xc2,0x2d,0x42,0x1c,0x80,0x82,0x20,0x8,0xc2,0x6d,0x87,0xe2,0xa0,0xb3,0x20,0x41,0xe,0x33,0xcb,0x22,0x11,0x4b,0x1e,0x39,0x21,0x25,0x40,0x2d,0x67,0x8f,0xb1,0xc8,0x47,0x2e,0x2a,0xc3,0x26,0xba,0x44,0x45,0x22,0x4a,0x23,0x24,0x9a,0xad,0x67,0xc,0x9,0x4b,0xc5,0x31,0xa7,0x34,0xcd,0xf0,0x8b,0xde,0x57,0x1,0xc8,0x58,0x8b,0x10,0xc,0x26,0x8e,0xae,0x6,0x3f,0x61,0xdd,0x1e,0x21,0xf8,0x9,0x4e,0xb5,0x55,0xf4,0xa2,0x73,0x24,0xb7,0x5e,0x89,0x57,0x92,0x50,0x12,0x91,0x72,0x82,0x82,0x82,0x36,0xa6,0xce,0x5e,0xa3,0x76,0x5c,0x8a,0xa0,0x52,0x19,0x8,0x30,0xd,0xe4,0xfa,0xdb,0x6e,0x8e,0x49,0x5c,0x64,0x11,0x6e,0x6d,0x2f,0x21,0xe7,0x4,0x67,0x57,0xd5,0x59,0x96,0x72,0x4,0x12,0xaa,0xb0,0x64,0x8c,0xa5,0x76,0xe1,0x40,0xf3,0xf5,0x90,0x81,0x69,0xdc,0xc2,0x35,0xd,0x9a,0x76,0x85,0x10,0x2,0xc7,0x8e,0xd,0x2c,0x37,0xf1,0xe,0xdb,0xd3,0xea,0x48,0xf4,0x93,0x27,0x31,0x8b,0x65,0x24,0x12,0xfa,0x0,0xcb,0xf3,0xde,0x72,0x4a,0x1c,0x83,0xa6,0xd8,0x75,0xf0,0x53,0x8d,0x32,0x1b,0x76,0x63,0x56,0x71,0x96,0xc5,0x4d,0xa5,0x48,0xf8,0x4a,0x21,0xd6,0x16,0xda,0xcc,0x25,0x28,0x65,0x26,0xe2,0xfa,0xf0,0x88,0x7c,0x80,0x1c,0x93,0x76,0x4d,0x8b,0x14,0x43,0x15,0xe1,0x72,0x4a,0x98,0x86,0xed,0xc2,0xed,0x45,0xe,0xbf,0x10,0xc8,0xbd,0x68,0x2d,0xc5,0xae,0x43,0x24,0x41,0x51,0x1b,0x8b,0xc4,0x85,0x1f,0x89,0x67,0x3b,0x26,0x16,0xf8,0x42,0xa2,0x73,0x9e,0x86,0x9e,0xe2,0xa6,0x83,0xa5,0x36,0x69,0xbe,0x8e,0xe0,0x49,0x8,0x33,0xc6,0xa0,0xe9,0x56,0x48,0x63,0x29,0x39,0xa1,0xcf,0x9d,0xa6,0xa1,0xce,0xe4,0x2b,0x22,0x55,0x89,0x71,0x27,0x93,0x28,0x76,0x5c,0xe2,0xbc,0x89,0x5a,0x86,0x8d,0x73,0x54,0x50,0xc3,0xd7,0x52,0x1a,0x79,0x83,0xf7,0x88,0xfc,0x9a,0x69,0x1c,0x90,0x53,0xa6,0x58,0x2d,0x8b,0x85,0x14,0x29,0x6f,0x48,0x4c,0x65,0x71,0xb1,0x8,0x7c,0xe5,0x7b,0xdb,0xcd,0x9,0xb4,0x31,0x18,0xfb,0x2d,0x3b,0x18,0xc9,0x7d,0x48,0x7b,0xd7,0xd7,0x59,0x88,0x54,0xbe,0x52,0xca,0x53,0x26,0xf8,0x69,0x60,0xd7,0x6b,0xae,0x6e,0xbc,0xb6,0x5b,0xf3,0xbd,0x19,0xa1,0xd,0x89,0x8a,0xc5,0x15,0x4a,0xcf,0x18,0x3d,0x53,0x24,0xdc,0xf5,0xd0,0x5a,0xe3,0xca,0xdd,0xf7,0x61,0xec,0x37,0x88,0xde,0xcf,0xd7,0xa9,0x15,0xcf,0x3a,0xd4,0x5c,0xd6,0x41,0xfb,0x42,0x2b,0x5,0x9f,0x2,0x3b,0x32,0xc9,0x11,0x9b,0x1,0xa8,0x9c,0x31,0xe,0x5b,0x34,0x6d,0x7,0x3f,0x8d,0x68,0xda,0x8e,0xa3,0xc3,0x1a,0x5a,0xab,0xba,0xdf,0x73,0x4e,0xb5,0xcd,0x9b,0x9e,0xa3,0x81,0x1d,0x83,0x76,0x7f,0x49,0x8e,0x20,0x8,0x82,0x20,0x8,0x82,0xf0,0x57,0x42,0x4,0x40,0x41,0x10,0x4,0xe1,0xb6,0x13,0x63,0xac,0x91,0xdc,0x92,0xf2,0x2b,0x3,0xff,0x8b,0x10,0x93,0x73,0xe2,0x92,0x9,0x9a,0xad,0xa6,0x8c,0xa2,0x52,0x90,0x4c,0x4e,0x25,0xcf,0x71,0xc2,0xd2,0x3a,0xab,0x8d,0xaa,0x42,0xd,0xb5,0x8,0x93,0x48,0x64,0xac,0xad,0xe2,0x87,0xb1,0xe,0x43,0xbf,0x41,0x8a,0x11,0xe3,0xb0,0xad,0x31,0xd2,0xed,0xe9,0x31,0x56,0x7,0x87,0x18,0x7,0x4b,0xaf,0xe7,0xf8,0xa8,0x2e,0xb1,0x62,0x76,0xbd,0xc5,0x48,0x65,0xb,0x31,0x91,0x1b,0x50,0x45,0x6a,0xf7,0x55,0x91,0x1a,0x50,0x27,0x16,0x60,0x8a,0x20,0x36,0x8d,0x43,0x2d,0x2d,0xd1,0xc6,0xb0,0xdb,0xae,0x81,0xd1,0x6,0xae,0xed,0x48,0xc8,0xb4,0x8e,0x4,0xa0,0x4c,0xc2,0x64,0xca,0x9,0x4a,0x5,0x18,0xeb,0x38,0xde,0xea,0x39,0x3a,0x3c,0x2c,0xca,0x4d,0x72,0x15,0x15,0x57,0xeb,0x23,0x8a,0x51,0x6b,0x12,0xc4,0xbc,0x9f,0x90,0x41,0x25,0x1d,0x21,0x78,0x8e,0x71,0x66,0xa4,0xa8,0xab,0xfb,0xca,0x5a,0x7,0x63,0x2c,0xc6,0xa1,0xaf,0x22,0xa3,0xd2,0x6,0xfd,0xe9,0x4d,0xe4,0x94,0x31,0xe,0x1b,0x28,0x55,0x9c,0x7e,0xdc,0x6c,0xab,0x4b,0x64,0xb3,0xfc,0xdd,0x20,0x24,0x2a,0xbc,0x70,0xae,0xc5,0xb0,0xa5,0xd9,0x83,0xd6,0x35,0x5c,0xe6,0x31,0xa0,0x5b,0x1d,0xb0,0x60,0xa8,0x39,0x96,0x1b,0x69,0x96,0x22,0xb,0x48,0x25,0x42,0x9d,0xb8,0x35,0xb9,0x44,0x4b,0x9b,0xb6,0x63,0x47,0x19,0x15,0x62,0x50,0x91,0xc4,0x4,0xa5,0x5a,0xa8,0x1a,0xc1,0x2d,0xa5,0x13,0x3d,0x4a,0x99,0xcc,0xd0,0x9f,0xd6,0xa6,0x5c,0x72,0x3d,0x2,0xc6,0x3a,0x64,0xb0,0x63,0x2e,0x45,0xf4,0x9b,0x53,0x50,0x44,0x96,0xdc,0xa6,0x24,0x7e,0x52,0x64,0xb5,0xb4,0x34,0x1b,0x16,0x91,0x73,0xce,0xb4,0x2f,0xc6,0x9e,0xdb,0x7e,0x29,0x9e,0x6b,0x9b,0x66,0x21,0xfa,0xe5,0x7a,0x6f,0xfd,0x38,0xd4,0x68,0x70,0x28,0x85,0x2f,0x9e,0xdc,0x82,0x7,0x47,0x97,0xa9,0x24,0xc6,0x74,0xd5,0x89,0x49,0xf7,0xc7,0x20,0xe4,0x4,0x3f,0x8e,0xf5,0x9e,0xa4,0x3a,0x17,0x8f,0xae,0x93,0x8e,0x1f,0xea,0x1c,0xc5,0x9c,0x63,0x15,0xfa,0x8c,0x35,0xe4,0x1a,0x64,0xb7,0xe2,0xb0,0xdd,0xb0,0xd8,0x98,0x70,0x7a,0x72,0x3,0xb6,0x69,0x1,0x0,0xae,0x6d,0x31,0x8d,0x63,0x2d,0x28,0x49,0x99,0x23,0xb7,0xec,0x86,0x2d,0x25,0x26,0xa6,0x69,0xb0,0x3d,0xb9,0x49,0xed,0xd5,0x89,0xd6,0x89,0xc4,0xf6,0x8c,0x18,0xa6,0x9d,0xb2,0x1e,0x0,0xf0,0xb5,0x4,0xa7,0x44,0xd4,0x49,0x78,0x3d,0xbe,0xf1,0x22,0xae,0xdc,0x75,0x2f,0x9,0x88,0xf4,0x2,0xc4,0x14,0xd1,0x34,0x14,0x3f,0xcf,0x29,0x21,0xab,0x5c,0x5,0xfd,0x94,0x12,0xbb,0x1,0x29,0x72,0x9d,0x73,0x24,0x11,0x30,0x4e,0xf2,0x3,0x53,0x10,0x4,0x41,0x10,0x4,0x41,0x4,0x40,0x41,0x10,0x4,0xe1,0x67,0xf2,0x1f,0x1f,0xeb,0xea,0x2f,0xfb,0x5a,0x2b,0xa4,0x44,0xce,0xb5,0x98,0x68,0xce,0x5f,0xca,0x89,0x44,0x0,0x9e,0x75,0xa7,0x55,0x46,0xf4,0x1e,0xb6,0x69,0x90,0x62,0x22,0x37,0x12,0xcf,0xf,0x2c,0x42,0x4c,0x71,0xbb,0x69,0xb3,0x70,0x8,0xb2,0x40,0xe1,0x5c,0x83,0x18,0x2,0x22,0xa8,0x70,0xa4,0xb8,0xb9,0xbc,0x9f,0x6a,0xfb,0x2b,0x89,0x64,0x24,0xbc,0x68,0x57,0x62,0xaa,0x53,0x2d,0x1,0xc9,0x55,0x9c,0x20,0xb1,0xc9,0x8f,0x54,0xfe,0x41,0xc2,0x88,0x5f,0xb8,0x4,0x27,0x84,0x1a,0x89,0x9c,0x48,0xa4,0xea,0xb7,0x14,0x47,0xed,0x56,0x98,0x46,0x72,0xa9,0x69,0x63,0xe0,0x5c,0x53,0xe7,0xa3,0x65,0x2e,0x2d,0x51,0x4a,0x91,0x88,0x6,0x20,0x73,0xb3,0xaa,0xd6,0xb6,0xba,0xf0,0xfa,0xcd,0x9,0xb9,0xfc,0xfa,0x6d,0x15,0xf,0xa7,0xa1,0x7,0x5a,0xd4,0x62,0x88,0xe8,0x69,0xae,0x5b,0xc,0x1e,0xc3,0xe6,0x94,0xa2,0xa4,0x5a,0x63,0x65,0x1d,0x9a,0xa6,0x23,0x1,0x71,0x1a,0xaa,0x13,0x2d,0xf8,0x9,0x99,0x8b,0x45,0x8c,0xb5,0x55,0xf8,0x1c,0xfa,0xd,0x95,0x55,0x18,0xfa,0x9f,0xb,0x3a,0x46,0x68,0x9d,0x59,0xa8,0x23,0x51,0x2f,0xf6,0x1,0xe3,0xb0,0x25,0x81,0x12,0x40,0xbf,0x39,0x45,0xb7,0x3a,0xa0,0x59,0x74,0x2b,0xd4,0xa8,0xb0,0x1f,0x7,0xf6,0xb9,0x65,0x28,0x16,0x11,0x8b,0x90,0xa4,0x8d,0x45,0x1a,0x87,0x3a,0x6f,0x6f,0x73,0x7c,0x1d,0xab,0x83,0xa3,0xb9,0x88,0xc4,0x52,0x5c,0xba,0xcc,0x17,0x34,0xc6,0xd4,0x98,0x6e,0xc,0x1e,0xe0,0xe3,0xb7,0xdd,0x9a,0x4a,0x28,0x86,0x6d,0x9d,0x99,0x58,0x62,0xb7,0x0,0xc8,0xd1,0xc6,0xf7,0xc,0x79,0x6e,0xa0,0x4e,0x31,0x60,0x7b,0x7a,0x13,0xab,0x83,0xa3,0x2a,0xa,0x87,0xe0,0xb1,0x3a,0x38,0xa2,0xeb,0x62,0x71,0xb5,0x44,0x57,0x8b,0xdb,0xaf,0x1c,0xc3,0xf3,0x2c,0xc4,0xc4,0xd1,0xd8,0x12,0x31,0x7,0x48,0x34,0x6d,0x9a,0x8e,0x1c,0x95,0xd6,0x55,0x17,0xaa,0x31,0x80,0xce,0x34,0xfb,0x2f,0x78,0xcf,0xb1,0xde,0x48,0xe,0x3f,0x8e,0x49,0x4f,0x63,0x8f,0xa6,0x5d,0x55,0x1,0x2d,0xf3,0xde,0x2b,0xb1,0x75,0x6d,0x6c,0x8d,0x3e,0x87,0x69,0xac,0x5,0x34,0xe0,0x75,0x76,0xae,0x1,0x90,0xf9,0x79,0x42,0x6d,0x39,0x56,0x7c,0x8c,0x52,0xd4,0x61,0xac,0x45,0x7f,0x7c,0x4a,0xe,0x51,0xef,0xe9,0x19,0xab,0xf7,0xc6,0x40,0xa9,0x96,0x4d,0x8a,0xd4,0x6,0x1d,0x63,0x80,0xd1,0xf4,0x7c,0x95,0xa2,0x9c,0x94,0x62,0x75,0x43,0x46,0xef,0xab,0xf3,0x70,0xec,0x37,0xe8,0x56,0x7,0x50,0x2c,0xb2,0x52,0x6c,0x5e,0x1,0x5c,0xd8,0x13,0xb9,0xd4,0x84,0x1c,0xb5,0x79,0xd1,0x4,0x5c,0x3c,0xab,0x82,0x20,0x8,0x82,0x20,0x8,0xc2,0x2d,0xf9,0x1d,0x4c,0x96,0x40,0x10,0x4,0x41,0xb8,0xdd,0xe4,0x9c,0xaa,0x93,0xad,0x38,0x0,0x53,0x8a,0xa8,0xc3,0xe3,0x8a,0x58,0x51,0x22,0xbf,0x31,0xb2,0xf8,0x47,0xf3,0xe1,0x54,0x52,0x3c,0x8b,0xce,0xd6,0x17,0x27,0x16,0x2b,0x22,0xc7,0x4c,0x69,0xc6,0x1c,0x35,0xc6,0x96,0x19,0x82,0x34,0x6b,0x2e,0xcc,0xae,0x25,0x90,0x60,0x97,0x91,0xa1,0xc6,0x9e,0x85,0x3c,0xe0,0xf2,0x9d,0x77,0x23,0xb0,0x73,0xaf,0x88,0x85,0x54,0x3e,0xa1,0xd0,0x6f,0x4e,0xe1,0x1a,0x8a,0x89,0xe,0x27,0xd4,0x28,0x5c,0xc4,0xa0,0x52,0x4c,0x32,0x8d,0x7d,0x75,0x39,0x1,0x14,0x41,0x36,0x8a,0xe6,0xe1,0x75,0xab,0x3,0xb4,0xdd,0x8a,0xe2,0xcb,0x3c,0x47,0xad,0x14,0x8a,0x28,0x15,0xa1,0xb8,0x80,0xc1,0x35,0xed,0x4e,0x93,0xb0,0x75,0xd,0x86,0xed,0xa6,0xba,0xc7,0x4a,0xc3,0xed,0x38,0xf4,0x68,0xbb,0x55,0x8d,0x23,0x97,0x32,0x8c,0xcc,0xa5,0x19,0xc8,0xa8,0x33,0xec,0x28,0x22,0x4a,0xc2,0x9d,0x35,0x24,0xc2,0xc6,0xe0,0xeb,0x5c,0xc4,0xd2,0x50,0x9c,0x53,0xc2,0xc9,0x8d,0x6b,0x38,0xba,0x7c,0x95,0x8e,0xd5,0x6f,0xd0,0xae,0xd6,0xd0,0xd1,0x20,0x45,0x2a,0x97,0x8,0xc1,0xb3,0x20,0x47,0x11,0xd7,0x61,0xab,0x80,0x22,0xb4,0x5,0xf,0xa5,0xd6,0xd5,0xf9,0x57,0xe3,0xdc,0x5a,0xd7,0xf9,0x8e,0xa5,0xa8,0x83,0x4,0xc8,0x1,0x21,0x78,0xc,0x5b,0x6a,0x8f,0x6d,0x57,0x6b,0x84,0x10,0xb0,0x62,0xd7,0x25,0xcd,0xfe,0xcb,0x75,0xef,0xc4,0x90,0x6a,0x4c,0x19,0x0,0xcd,0x40,0x64,0x51,0x8e,0x1a,0x8f,0x57,0xb4,0x86,0xae,0x41,0xce,0x9,0xc3,0x76,0xc3,0xed,0xce,0x16,0x31,0x86,0x2a,0x50,0xd2,0xcc,0x48,0xc5,0x2d,0xb5,0x2d,0x36,0xc7,0x37,0xaa,0x0,0x45,0xeb,0x7d,0x5a,0xe3,0xa9,0xce,0x35,0x75,0xe6,0x63,0x98,0x46,0x8a,0x20,0x27,0x72,0x66,0x6a,0xad,0x30,0x8d,0x63,0x75,0x8b,0x52,0x5c,0x7b,0xac,0xd,0xca,0xde,0x4f,0x68,0xda,0x15,0x9a,0x6e,0x45,0xb3,0x11,0x59,0x48,0x4e,0x29,0x93,0x3,0xd0,0xf3,0xcc,0x46,0x6e,0x9a,0xce,0x29,0x61,0xd8,0x9e,0x56,0xd7,0xa0,0xce,0xbc,0xf,0x33,0xcd,0x9d,0xdc,0x89,0x64,0x67,0xda,0x7b,0xde,0x4f,0x50,0xda,0x60,0x38,0xb9,0x59,0xe7,0xff,0x4d,0x61,0x80,0xde,0x9c,0xe0,0xd2,0x95,0xbb,0xea,0xac,0xc4,0x9c,0x22,0x62,0x4e,0x50,0x41,0xcd,0x5,0x1f,0xb4,0xb0,0x50,0x8a,0x8a,0x5c,0xa8,0x54,0x86,0x66,0x14,0x52,0xdb,0xef,0x54,0xc5,0x61,0x5a,0xe7,0x8,0x1f,0x7,0x5e,0xcf,0xc8,0x7b,0x86,0x9a,0x87,0xe3,0x62,0x5f,0xcc,0xd,0xca,0x34,0x3f,0xd0,0x99,0xb6,0xce,0xf9,0x53,0x4a,0x41,0x19,0x43,0x73,0x39,0x13,0x95,0xe7,0x68,0xa5,0x11,0x39,0x96,0x2d,0xf1,0x5f,0x41,0x10,0x4,0x41,0x10,0x84,0x5b,0x8b,0x8,0x80,0x82,0x20,0x8,0xc2,0x6d,0x27,0x78,0xbf,0x30,0xf7,0xb0,0x30,0xc1,0x82,0x41,0x75,0x39,0x71,0x69,0x47,0x11,0x2e,0x52,0x24,0x81,0x50,0x73,0x19,0x3,0x58,0xe4,0x3,0xb,0x2a,0x31,0x45,0xa4,0xa4,0x48,0x60,0xd1,0xa6,0x36,0xd4,0xea,0x32,0xcb,0x4d,0x93,0xab,0xb0,0x8,0x60,0xfd,0xe9,0x31,0x9,0x38,0xec,0x84,0x9b,0xc6,0x1,0x4d,0xdb,0xc1,0x5a,0x87,0xed,0xc9,0x4d,0x76,0x27,0x92,0xa0,0xd5,0x6f,0x4e,0x60,0xac,0x85,0xb1,0xd,0xfc,0xd4,0x73,0x51,0x4,0x7d,0x7f,0x1c,0xe8,0xef,0xce,0xb5,0x14,0xf9,0x8d,0x1,0xd6,0x39,0xf8,0x71,0xa4,0x28,0x26,0xc7,0x7e,0x4b,0xd3,0x69,0xbb,0x5a,0xc3,0xfb,0x9,0x5a,0x69,0x64,0x6b,0xb8,0xd,0x19,0x1c,0x1,0xa6,0xa2,0x8c,0xd2,0xd6,0x6a,0xac,0x43,0xc,0x53,0x6d,0xb9,0x8d,0x81,0x66,0xbe,0xf5,0x9b,0x13,0x1c,0x5e,0xbe,0xa,0xd7,0xb4,0x24,0xdc,0x68,0xc3,0xb1,0xe7,0xb9,0x94,0x82,0x22,0xc3,0x1a,0xc3,0xf6,0x4,0xda,0x5a,0x4,0x4f,0x71,0x60,0xe7,0x5a,0x72,0x2d,0x22,0xd4,0x88,0x69,0x99,0xed,0x57,0x22,0xd7,0x9b,0xe3,0x1b,0x68,0xda,0xe,0x21,0x78,0xb8,0x94,0x90,0x55,0xc4,0xd8,0x6f,0xc8,0x9d,0x68,0x17,0x11,0x4e,0x16,0x6f,0x22,0x17,0x6a,0x24,0x6e,0xf2,0x4d,0xd6,0x92,0x13,0xaf,0x3f,0x45,0xa7,0xe,0xf9,0x7d,0x4d,0x9d,0xf,0x98,0x4d,0xe6,0xfb,0xa4,0x6b,0x5b,0xaf,0x73,0xd,0xbc,0xa1,0xf3,0x1c,0xb6,0x1b,0x0,0x80,0x5f,0x1f,0xc0,0xb5,0x1d,0x42,0x8,0x30,0x96,0xa2,0xc2,0xce,0xb5,0x34,0x67,0xae,0xcc,0x8d,0x2b,0x22,0xad,0x2,0x39,0x38,0x59,0xc,0x2b,0x73,0xee,0x9a,0x6e,0x85,0xd2,0x98,0x1b,0xb8,0xd,0x78,0xd8,0x6e,0x38,0x1a,0x9c,0x59,0x68,0x25,0xa7,0xe0,0xc0,0xc7,0x2c,0xd,0xca,0xdd,0xfa,0x0,0x9b,0x93,0x1b,0x68,0xd8,0xcd,0x46,0x42,0x98,0x66,0x57,0x2a,0x89,0xce,0x7e,0x1c,0xe0,0xda,0xae,0xce,0xe4,0x33,0xa0,0x59,0x85,0xda,0x98,0x2a,0x48,0x3b,0xd7,0x72,0x44,0x98,0x66,0xe1,0xc5,0x14,0x61,0xb5,0xe6,0x42,0x19,0x72,0x8a,0x6a,0x63,0xa1,0x53,0x42,0xe4,0xfd,0xb6,0x3a,0x38,0xaa,0x6e,0xbe,0xf2,0x3c,0x94,0x75,0x27,0x21,0x35,0x56,0x81,0x35,0x45,0xfa,0xbc,0x91,0xd7,0x8d,0xda,0x84,0xfd,0x5c,0x9c,0xc3,0x2e,0xc1,0xf2,0xcc,0x19,0x43,0x31,0x77,0x63,0x2c,0x9a,0xb6,0xc3,0x10,0x23,0x9a,0x6e,0x4d,0x65,0x20,0xbc,0x7e,0xc1,0x7b,0xac,0x30,0x37,0x4e,0x5b,0xeb,0xa8,0x34,0x86,0x67,0xe,0xa6,0x3c,0xb7,0x32,0x17,0xc7,0x2b,0x3f,0xcd,0x24,0x24,0x6e,0xb7,0x38,0x38,0xba,0x83,0x9e,0xab,0x6e,0x55,0xa3,0xd9,0x73,0x9,0x4c,0x99,0xe3,0x49,0xb3,0x18,0xc9,0x89,0x19,0xeb,0x7c,0xc3,0xf2,0x7f,0x4,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0xb7,0x6,0x11,0x0,0x5,0x41,0x10,0x84,0xdb,0x4e,0xf9,0x25,0x9f,0x84,0xab,0x5c,0xe7,0xfa,0x65,0x95,0x59,0xe4,0x33,0x48,0x91,0x84,0x1,0x70,0x5c,0x91,0x66,0xc9,0x29,0x68,0xc5,0x73,0xff,0x52,0xe0,0x39,0x68,0x40,0x44,0xa8,0xc2,0x59,0x8,0x1e,0xc1,0x4f,0xb3,0x5b,0x89,0x67,0xcd,0x15,0x87,0x53,0xc,0x1e,0x63,0x4f,0x2d,0xa5,0x34,0x67,0xd0,0x71,0xac,0x56,0xd7,0x19,0x6a,0x4d,0xdb,0xa1,0xed,0xd6,0xf0,0x89,0xe2,0xc6,0x39,0x67,0x4c,0x1b,0x2a,0xd6,0x70,0x2d,0xc5,0x21,0xfd,0x54,0x4,0x3a,0x9a,0x7b,0x36,0x8e,0x3d,0xfc,0xd8,0xa3,0xed,0xd6,0xb5,0x39,0xd8,0x18,0xb,0xbb,0x3a,0xe0,0x12,0x84,0x15,0x8b,0x66,0x34,0xf7,0xaf,0xb4,0xac,0x16,0x57,0x5c,0x11,0x66,0x8a,0x80,0xa3,0xd8,0xf9,0x8,0xa5,0xa0,0x8d,0x85,0xdf,0x9c,0xb0,0x80,0x62,0x60,0x8c,0xab,0x5,0x12,0xda,0x18,0x8e,0xbf,0xae,0xc8,0xd9,0x97,0x1b,0xf8,0x71,0xac,0x6d,0xb3,0xde,0x4f,0x58,0xb7,0x5d,0x8d,0x3e,0x9f,0xdc,0xbc,0x6,0xeb,0x1a,0x58,0xe7,0x50,0xe2,0xb4,0xc1,0x7b,0x78,0x4f,0x82,0x19,0x35,0xb8,0x2,0xe3,0xd0,0xc3,0x18,0x3a,0xbe,0x2,0x70,0x70,0xe9,0xa,0xb9,0xb7,0xb8,0x79,0x17,0xa0,0x38,0x69,0x2e,0xa5,0xf,0x50,0xd8,0x9e,0x1e,0x93,0x98,0x18,0x3,0x9a,0xa6,0xe5,0xa2,0x88,0x40,0x5,0x20,0x2c,0x30,0x96,0x36,0xe0,0x7a,0x3f,0xd9,0x9,0xe8,0xa7,0xe2,0xce,0xa4,0x38,0xe9,0xea,0xe0,0x88,0x4a,0x3d,0x5c,0x8b,0xd5,0x1,0x95,0xb3,0x14,0x7,0x5f,0x69,0x7c,0xe,0xc1,0x3,0x6,0x28,0x6d,0xc0,0xe3,0xb0,0xad,0xc5,0x2d,0x21,0x78,0xb4,0xdd,0xec,0x1c,0x8c,0x31,0xc2,0xf0,0x7c,0x3a,0x28,0x85,0x71,0xd8,0x92,0x98,0xc9,0x62,0x94,0x36,0x6,0xd6,0xb9,0xba,0x4e,0xd7,0x8f,0xaf,0x63,0x75,0x78,0x89,0x66,0x2c,0xf2,0xcc,0x45,0xeb,0x1c,0x2,0x5f,0x7b,0x69,0x9c,0x56,0x5a,0x63,0xe8,0x37,0x54,0x6a,0x32,0xe,0x55,0xb8,0xb5,0xec,0x3e,0xa4,0x59,0x82,0x9,0xc6,0x36,0xbc,0x97,0x52,0xbd,0xcf,0x4a,0x6b,0xe8,0x9c,0xeb,0xcc,0xc1,0x18,0x68,0xb6,0xe4,0xfa,0xf0,0x12,0x37,0xf4,0x16,0x11,0xdb,0xa0,0x74,0xe1,0x96,0xb8,0x78,0x6,0x90,0x73,0x80,0x85,0x43,0x8,0xa1,0xb6,0x40,0x2b,0x45,0xed,0xbb,0xc1,0x7b,0xc,0xfd,0x6,0xdd,0xfa,0x10,0xe0,0x99,0x90,0xf4,0xe7,0xb9,0x4,0x87,0x1c,0xaa,0xd4,0x2a,0xdc,0xb2,0x50,0xaa,0x0,0xde,0x23,0xe,0x9e,0xaf,0xa7,0xe9,0xd6,0x54,0x6c,0x53,0x8a,0x50,0x58,0x68,0xb6,0xae,0xa1,0xfb,0x11,0x13,0xbc,0x1f,0x11,0xc2,0x54,0x45,0xfb,0x6e,0x75,0x0,0xef,0x27,0xdc,0x71,0xe9,0xa,0xbb,0x7,0x5d,0x8d,0xea,0x97,0x39,0x81,0x29,0x25,0x28,0x0,0x29,0x65,0x28,0x8d,0x2a,0xfe,0xcf,0x73,0x0,0xa5,0x1,0x58,0x10,0x4,0x41,0x10,0x4,0xe1,0x56,0x21,0x2,0xa0,0x20,0x8,0x82,0x70,0xdb,0xd1,0x46,0x57,0x51,0xe,0x40,0x9d,0xab,0x46,0xe2,0x2,0xc7,0x7f,0x91,0xa1,0x4b,0x61,0x41,0x24,0x77,0x91,0x62,0x21,0xb0,0xcc,0x26,0x2b,0x2,0x99,0xd2,0x9a,0x66,0xbe,0xf9,0x9,0x89,0xb,0x2a,0x8a,0x5b,0xae,0xc4,0x10,0x29,0x62,0x4c,0x91,0xe3,0x22,0x24,0xf5,0x9b,0x53,0x68,0x7e,0xef,0xd0,0x6f,0x10,0x3,0xcd,0x2e,0x4b,0x29,0xa2,0xdf,0x9e,0xd4,0xb2,0x8b,0x52,0x5c,0x61,0x5d,0x83,0xed,0xe9,0x31,0xc7,0x3f,0x23,0xc7,0x3f,0x75,0x9d,0xe1,0x66,0xad,0xe3,0x79,0x68,0x89,0x9d,0x5f,0x4d,0x75,0x59,0x29,0xa5,0xa0,0x5d,0x43,0x5,0x1c,0x35,0x4a,0x99,0x60,0xb8,0x64,0xa1,0x8,0x31,0xa,0x8a,0xaf,0x97,0x64,0xb5,0xe8,0xfd,0xec,0xb8,0xe3,0xc6,0xd4,0x94,0x22,0x86,0xfe,0x14,0x6d,0xb7,0x86,0xe2,0x63,0xc7,0x14,0xa1,0x38,0xe2,0x59,0xda,0x5e,0x8f,0xaf,0xbf,0x88,0x9c,0x13,0xae,0x3d,0xff,0xc,0xe,0x2f,0x5f,0xc1,0x76,0x73,0x4c,0xf3,0x10,0x63,0x40,0xf0,0xb6,0xce,0x34,0x2c,0xe2,0xc,0x9,0xa3,0x24,0x40,0x1a,0x63,0x61,0x9d,0xc3,0xe9,0xcd,0xeb,0x68,0x57,0x6b,0xb8,0xb1,0xa7,0x6b,0xe0,0x59,0x7c,0x4a,0x93,0x30,0xa8,0xb4,0x41,0xe,0x1,0x19,0x19,0xab,0xf5,0x21,0x36,0xc7,0x37,0x60,0xba,0x15,0x32,0x0,0xd7,0x74,0xd5,0xe5,0x57,0x8a,0x3d,0xa8,0x75,0x96,0x9c,0x6d,0x29,0x25,0xe8,0x5a,0x1e,0x1,0x76,0x3a,0x6,0x72,0xc9,0x85,0x80,0x6e,0x7d,0x0,0xd7,0x34,0xf3,0xfb,0x73,0x42,0x66,0x17,0x5e,0x48,0x54,0x66,0x12,0x78,0xfe,0x62,0x4e,0x9,0xed,0xea,0x0,0xe3,0xf0,0x62,0x15,0xf1,0xb6,0xa7,0x1,0xd6,0xb5,0x70,0x4d,0xb7,0xb3,0xff,0x62,0xf0,0x14,0x63,0x2e,0x2e,0x38,0x76,0xa8,0x75,0xeb,0x43,0xf8,0x71,0xc4,0xcd,0xeb,0x2f,0xa0,0xe9,0xd6,0x8,0xd3,0x88,0xc9,0x18,0x0,0xab,0x9d,0x59,0x8f,0xc1,0x4f,0x24,0x7e,0xf1,0xdf,0x8d,0x73,0x34,0x87,0x11,0x14,0x3,0x6f,0x57,0x6b,0xb8,0xb6,0xe5,0x52,0x90,0x48,0x45,0x26,0x39,0xf3,0x7a,0xe9,0x2a,0x7c,0x99,0xb2,0x9f,0x39,0x3e,0x1e,0x82,0x47,0x98,0x46,0x8c,0xfd,0x96,0x1c,0x80,0x5c,0x92,0x32,0x8d,0x3,0xba,0xf5,0xc1,0x3c,0x83,0x92,0x9f,0x19,0x63,0x48,0xb0,0xac,0xf3,0xc,0xd9,0xf9,0x1a,0x63,0xa4,0x12,0x18,0x3f,0xd6,0xb9,0x8a,0xf4,0xbc,0x24,0x38,0x47,0x4e,0x42,0xd,0x9a,0xe1,0x97,0x22,0x89,0x8e,0xc1,0x53,0x4c,0x5c,0x69,0xd,0xd7,0xb4,0xe8,0xb7,0xa7,0x34,0xd7,0x90,0x1d,0x8a,0x50,0xa,0x4d,0xd3,0x41,0x1b,0x5d,0xe3,0xd3,0x39,0xd1,0xc,0x43,0x8a,0x9a,0x27,0xc,0xfd,0x96,0xe6,0x3d,0xfa,0x9,0xeb,0x83,0x23,0xba,0xbe,0x18,0x90,0x73,0x53,0x67,0x20,0x16,0x32,0x97,0xf4,0xd0,0x79,0x53,0x2b,0x78,0x71,0x9,0x96,0xfb,0x59,0xe7,0x3,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x3f,0x35,0x6,0xc0,0x3f,0x92,0x65,0x10,0x4,0x41,0x10,0x6e,0x27,0xcd,0xea,0x0,0xf7,0xbc,0xe6,0xf5,0x35,0xe5,0xb7,0x9c,0x43,0x56,0xdc,0x5c,0x65,0xc6,0x5a,0x11,0x4d,0x8a,0x68,0x34,0x47,0x20,0xd3,0x4e,0x47,0x40,0x4e,0x24,0x6,0x96,0xc6,0xd2,0x94,0x62,0x75,0x5a,0x19,0x43,0xb3,0xde,0x3c,0x97,0x72,0xc4,0x30,0xcd,0x25,0xd,0x29,0x61,0x9a,0x46,0x9a,0xeb,0xc7,0x42,0x9b,0x9f,0x26,0x84,0x69,0xe2,0x48,0x6b,0xac,0x82,0x44,0xc,0x13,0xcd,0x11,0xc,0x81,0xcd,0x89,0x19,0xe0,0xe2,0x8e,0x9c,0x32,0xc7,0x16,0x49,0x6c,0x69,0x5b,0x9a,0xcb,0x47,0x25,0xa,0xec,0x6,0xe4,0x42,0x8a,0x12,0xe9,0xa4,0x2e,0x4,0x3b,0xb,0x8d,0xa5,0x4c,0x82,0x67,0x16,0xd6,0xd6,0x57,0x16,0xfd,0x82,0xf7,0x18,0xc7,0x9e,0x85,0x47,0x83,0xf5,0xe1,0x25,0x76,0x4f,0x69,0x16,0x93,0x2,0x2d,0x61,0x46,0x8d,0xab,0x96,0xf6,0xe0,0xd3,0x9b,0xd7,0xa0,0xa0,0xe9,0xf3,0x12,0xb5,0xc7,0xc6,0x40,0x8d,0xb6,0xb4,0x56,0xe4,0x4,0xc,0x7e,0xc2,0xd8,0x53,0x14,0x74,0x73,0x72,0x3,0x77,0xdc,0x75,0xf,0x8b,0xab,0x9e,0x4b,0x43,0x34,0xb,0x84,0x74,0x7e,0xd3,0x38,0xd4,0xa2,0x13,0x6a,0xc9,0xf5,0x88,0x31,0xee,0x44,0x58,0xad,0x73,0x34,0x3b,0x8f,0x9d,0x91,0xe0,0x19,0x70,0x60,0x21,0x8b,0x44,0xae,0x7e,0x6e,0x3c,0x1e,0x6,0xac,0xf,0x8f,0xa0,0xcb,0xfd,0xb3,0x16,0xa8,0x11,0x52,0x72,0xde,0x51,0x71,0x72,0x9e,0xdb,0xa3,0x53,0xa2,0xf7,0x27,0x8a,0xda,0x2,0x19,0x4d,0xbb,0x82,0x31,0xb6,0xa,0x70,0x25,0xc2,0xaa,0xb5,0x99,0xb,0x64,0x38,0x1e,0x5c,0x4a,0x69,0x72,0x8a,0x68,0xbb,0xf5,0xdc,0xe4,0x3c,0xc,0x3c,0x3b,0x32,0xe2,0xf4,0xf8,0x3a,0xca,0xcc,0xc3,0x7e,0x73,0x52,0xf7,0x2d,0xc5,0x84,0x57,0x35,0x92,0x8c,0xcc,0x73,0x1f,0xad,0xad,0xf3,0x22,0xa9,0xa5,0x57,0x41,0x2b,0x72,0x1a,0xd6,0xf9,0x7d,0x8a,0xe2,0xda,0xb4,0xdf,0xe8,0x33,0x2c,0x97,0xbb,0x34,0x4d,0xc7,0x6d,0xd0,0x8a,0x8f,0x5b,0x4,0x73,0x50,0x43,0x2f,0xb,0xbf,0x85,0x30,0x51,0xe3,0x70,0xe2,0xf2,0x18,0xeb,0x1a,0x28,0xa5,0x59,0x74,0x76,0xa0,0xa5,0xa7,0x22,0xe,0xcd,0xa2,0x73,0x4e,0x34,0x4f,0xb1,0x1c,0x3f,0x6,0xcf,0xa2,0x69,0x83,0xa1,0xdf,0x50,0x64,0x1c,0xa8,0xb1,0xeb,0x69,0x24,0x87,0xa6,0x9f,0x46,0x6e,0xba,0xde,0x22,0x85,0xc0,0xd7,0xa2,0xe0,0x27,0x2a,0x4d,0x89,0xc1,0xa3,0xe9,0xd6,0x70,0x4d,0x57,0x9b,0xa7,0x15,0x4a,0x79,0xf,0xaa,0x93,0x94,0xce,0x63,0x4e,0xfc,0x96,0x56,0xe8,0x69,0x1a,0x71,0xf3,0xa5,0x1f,0x1,0xe2,0x2,0x14,0x4,0x41,0x10,0x4,0x41,0xb8,0x25,0x88,0x0,0x28,0x8,0x82,0x20,0xdc,0x76,0x9a,0xee,0x0,0xf7,0xde,0xff,0x7a,0x16,0x1,0x52,0x15,0x71,0xa0,0xe6,0x99,0x67,0x6c,0x88,0x43,0x19,0x90,0x57,0x5c,0x7c,0xc5,0x21,0x47,0x2,0x94,0x86,0xd2,0xb3,0x90,0x54,0xc4,0x29,0x12,0x9,0x8b,0x80,0x46,0x82,0x5e,0x11,0xd9,0x8a,0x6b,0xaf,0x3a,0xb,0xc9,0x4e,0x55,0x9d,0x7a,0xc5,0x6d,0x65,0x9b,0x6,0xd6,0x36,0x24,0x50,0x54,0xe1,0x85,0x4,0xb4,0x12,0x49,0xe6,0xfc,0x22,0xac,0x73,0x35,0x42,0x9a,0x52,0x82,0x73,0xd,0xc6,0xa1,0x47,0xb7,0x5a,0xc3,0x58,0x87,0xb6,0xce,0x40,0xa3,0x59,0x87,0x25,0xe,0x4c,0xa2,0x8c,0xaa,0xc2,0x87,0x52,0xa8,0xe2,0x18,0xcd,0x94,0x8b,0xf5,0x9a,0x12,0x97,0x27,0xa4,0x18,0x59,0x14,0x32,0x2c,0xf0,0x28,0x12,0x69,0x16,0x82,0x27,0xf8,0x38,0x45,0x4,0xf3,0xd3,0x48,0xf3,0xf3,0x9a,0x86,0x67,0x6,0x92,0x18,0xb7,0x3a,0xbc,0x34,0xb7,0xf1,0xe6,0x79,0xe,0x5b,0x29,0xd3,0xe8,0xd6,0x87,0x55,0x24,0xa3,0x88,0xa8,0xaa,0x6e,0xc6,0xe2,0x16,0x3,0x28,0x2e,0x5c,0x4a,0x32,0x0,0xa0,0x5b,0x91,0x73,0x4f,0x1b,0xb,0xc3,0x45,0x1b,0x14,0x2f,0x55,0x55,0xbc,0x2b,0x82,0x1e,0xb9,0xfe,0x22,0x8c,0x21,0x71,0xae,0x38,0xef,0xc8,0x41,0xd8,0x42,0x6b,0x8d,0x6e,0x75,0x0,0x0,0x55,0x2c,0x42,0x6,0x37,0xe0,0xfa,0xfa,0xb5,0xe2,0xf0,0x4,0xb,0x8a,0xd6,0x35,0xb0,0x4d,0x53,0x9d,0x99,0x0,0x38,0xf6,0x9a,0xab,0xf3,0x2e,0xa5,0x44,0x4d,0xc3,0x31,0xb0,0x8,0x66,0x91,0x72,0x69,0x90,0xa6,0xf8,0xf8,0x6a,0x7d,0x48,0xe,0x45,0x76,0xe9,0x35,0x4d,0x57,0xc5,0xe5,0xd2,0x80,0x6b,0x5d,0xcb,0x22,0xac,0xad,0xc2,0xad,0x6b,0x28,0x8e,0x5e,0x44,0x48,0x5b,0xbf,0x47,0xbb,0x20,0xc6,0x40,0x22,0x77,0x8c,0x1c,0x59,0x77,0xd5,0xd9,0xea,0x5c,0x5b,0x5d,0x89,0xc6,0x58,0x28,0x6d,0xa0,0xed,0x1c,0x39,0x56,0x4a,0xd7,0x22,0x1b,0x63,0x2c,0x95,0xd9,0x4,0x2a,0x92,0x29,0x73,0xe,0x8b,0x8,0xdd,0x76,0xab,0x1a,0x15,0x6f,0x9a,0x15,0xdf,0xe3,0x54,0xdb,0xb3,0x67,0x15,0x1e,0x3c,0xdf,0x90,0xa,0x66,0x90,0x1,0x6d,0xd,0x89,0xa6,0x39,0xc1,0x35,0x34,0xe3,0xb2,0x5b,0xad,0xab,0xf0,0x4e,0x65,0x3b,0xb3,0xc8,0x6d,0x1d,0xcd,0xa4,0x2c,0xcd,0xce,0x6d,0xb7,0x5a,0xec,0x53,0x5d,0xf7,0x2b,0x3f,0x4c,0xf4,0x3c,0xa4,0x5c,0xb6,0x42,0xbd,0x27,0x29,0x45,0x4c,0xc3,0x16,0xc7,0xd7,0x5e,0x40,0xce,0x52,0x6,0x22,0x8,0x82,0x20,0x8,0x82,0x70,0x2b,0x10,0x1,0x50,0x10,0x4,0x41,0xb8,0xed,0xb8,0x8e,0x1d,0x80,0x4a,0xcd,0xe2,0x1f,0xab,0x10,0x25,0xde,0x48,0x4e,0x31,0xd4,0x28,0x60,0x4e,0x89,0x5,0x24,0x5,0xcd,0x2e,0x32,0x0,0x73,0xd3,0x2e,0x66,0x27,0xa1,0x2e,0xf3,0xcd,0x32,0x17,0x45,0xb0,0x40,0x1,0x14,0xa1,0x90,0xa2,0x89,0x4a,0x69,0xa4,0x18,0xb0,0x5a,0x1f,0x56,0xc7,0x56,0xb7,0x3e,0x84,0x63,0xa1,0x82,0xc4,0xa1,0x88,0xa6,0x69,0xc9,0xbb,0xa4,0x55,0x3d,0x37,0xad,0x35,0xd6,0x87,0x97,0xb9,0xbc,0x83,0x62,0xab,0xda,0x58,0xb8,0xa6,0x45,0xd3,0x74,0x70,0x5c,0x28,0x52,0x9c,0x4e,0xd6,0x35,0x50,0x50,0x54,0x8,0xc2,0x4e,0xac,0xa5,0xab,0xb1,0x8,0x59,0x9a,0x5,0x9e,0xcc,0xe2,0x54,0x8a,0x91,0xe6,0x1e,0x1a,0xb,0xcd,0x9f,0x6f,0x8c,0x41,0xb7,0x3a,0x20,0xc1,0xac,0xed,0x48,0xdc,0xe9,0x56,0xd5,0xc5,0x56,0xae,0xb3,0x94,0xad,0x28,0xa5,0xd0,0xae,0xd6,0xb0,0xb6,0x81,0x6b,0x1a,0x3e,0x17,0x5a,0x33,0xeb,0x5c,0x6d,0x78,0xa5,0xb2,0x8,0xd,0x6d,0x34,0xda,0x6e,0x55,0x1d,0x7f,0xd6,0x36,0xec,0x66,0x6b,0xb9,0x95,0x97,0x67,0x34,0xf2,0xfd,0x29,0xad,0xc0,0xd1,0x4f,0xb0,0x4d,0xc3,0x33,0x1e,0xc9,0x71,0xa7,0x8c,0x86,0xd1,0x54,0x2e,0x62,0x8c,0x81,0x36,0x16,0x21,0x4c,0x28,0x2a,0x52,0x11,0x70,0x69,0x4e,0x9e,0x3,0x32,0x89,0x47,0xd6,0x36,0xd0,0xda,0x70,0x64,0x39,0xc2,0x35,0x6d,0x9d,0xc7,0xa8,0x8d,0xa9,0x2d,0xb1,0x45,0x2c,0x2d,0xb3,0x1e,0x73,0x2a,0xd1,0xd2,0x84,0x30,0x4d,0x5c,0x2,0x2,0x3e,0xa6,0xdd,0x71,0x9d,0xa1,0xcc,0x86,0x64,0x7,0x60,0x4e,0x91,0xe3,0xd0,0x74,0x4d,0xae,0x69,0x69,0xbf,0xba,0xa6,0x3a,0x2e,0x95,0x2,0x62,0x88,0xb3,0x88,0x9c,0x12,0x9a,0xb6,0xa5,0x92,0xc,0x47,0x2,0x6b,0x99,0xb5,0xe7,0x9a,0x96,0xd6,0xd8,0x3a,0x18,0xfe,0x5e,0x11,0x78,0x97,0x7b,0xdc,0x18,0x5b,0xf7,0x63,0x89,0xa7,0xaf,0xd6,0x87,0x74,0x1e,0x6d,0xcb,0x8d,0xd7,0x86,0x85,0x6d,0x72,0x9b,0x6a,0x76,0xba,0xd2,0x3a,0xd0,0x1a,0x96,0x16,0x6a,0x80,0x22,0xdc,0x21,0xfa,0xfa,0x67,0xdb,0xb4,0xb5,0x74,0xa3,0x14,0xa7,0x50,0xc,0x1f,0xf5,0x3e,0x94,0x73,0x4a,0x31,0xf0,0x9a,0x19,0xb8,0xa6,0x83,0xb5,0x16,0x4a,0xab,0xba,0x6f,0xc0,0xcf,0x46,0x71,0xe6,0x96,0x79,0x94,0xc6,0xba,0x1a,0x3f,0xbf,0x74,0xc7,0x9d,0xdc,0x56,0xdd,0x56,0xa1,0x7b,0x29,0x34,0x53,0xd,0x36,0x76,0xdc,0x9c,0x65,0x2e,0x60,0x4a,0x1,0xde,0x7b,0xdc,0x7c,0xe9,0x39,0x99,0x3,0x28,0x8,0x82,0x20,0x8,0x82,0x70,0x8b,0x10,0x1,0x50,0x10,0x4,0x41,0xb8,0xed,0xb8,0x76,0x8d,0x7b,0xef,0x7f,0x7d,0x75,0x1,0x55,0x1,0x80,0x24,0xbe,0x4a,0x71,0x9a,0xd5,0x88,0xb0,0x2,0x4c,0x99,0x41,0xc7,0xee,0x29,0xd6,0x4,0xb9,0x54,0x42,0xcf,0x8e,0xba,0x18,0xd9,0x2d,0x35,0x8b,0xe,0x65,0x8e,0xde,0xd2,0x49,0xd6,0xae,0x56,0x54,0x3a,0xb1,0xa6,0xb6,0x5a,0xc3,0x8e,0xa5,0x22,0x9c,0x39,0xc7,0x11,0x59,0x6b,0x61,0x5d,0xc3,0x73,0xed,0xc,0xb7,0x2,0x93,0xe0,0x71,0x70,0x74,0x19,0xd4,0x30,0x6c,0xd0,0xb4,0x2b,0x9e,0x49,0xc8,0x71,0x55,0x70,0x4,0x19,0x60,0xe7,0x9e,0x66,0x7,0xa3,0x65,0xb7,0xda,0xdc,0x82,0x5a,0xdc,0x8b,0xd4,0xe8,0x4b,0x11,0x67,0x63,0x2c,0x52,0x8e,0x75,0x4e,0x5c,0x59,0x8a,0xea,0x72,0x63,0x77,0x55,0x71,0x74,0x15,0x17,0x5f,0x11,0x96,0x82,0x1f,0xab,0x10,0x69,0xac,0x85,0x56,0x24,0x24,0x59,0xd7,0x90,0xd3,0xab,0x14,0x63,0x64,0x12,0x3,0x49,0x74,0xe4,0x52,0xc,0x4b,0xa2,0xa5,0x6b,0xbb,0x3a,0x2b,0x11,0x0,0x8c,0xb6,0xe4,0xae,0xe3,0xb9,0x73,0x21,0x78,0x28,0xad,0xaa,0xd0,0x43,0xeb,0xd4,0x2c,0xd6,0xa1,0xb8,0x5,0x15,0x72,0x9e,0x9b,0x8e,0x4b,0xe1,0x43,0x89,0x68,0x17,0x1,0xab,0x44,0x60,0x8b,0xb3,0x52,0x29,0xbd,0x10,0xea,0xaa,0xf6,0xbb,0x73,0xaf,0x8b,0x53,0xb3,0x36,0xfb,0xc6,0x80,0xb6,0x5b,0x93,0xf0,0xc7,0x22,0x67,0x11,0xaf,0xca,0x1c,0xc3,0x22,0x36,0x92,0x3b,0x54,0x55,0xf1,0xb4,0xb8,0x4,0x33,0x32,0xac,0xb5,0x70,0x6d,0x37,0x3b,0x33,0x91,0xb1,0x3a,0x38,0x24,0xe7,0x1a,0x9f,0x6b,0xdb,0xad,0x6a,0x5b,0x35,0x5d,0xb7,0xaa,0xa5,0x27,0x4d,0xb7,0x42,0x8c,0xe4,0x5c,0xd5,0x86,0x84,0xe9,0x12,0xb7,0x2d,0xf1,0x67,0x5a,0x1f,0x33,0xc7,0xdd,0x8d,0x41,0x8c,0x91,0x84,0x37,0x68,0xfa,0xfc,0xf2,0x3c,0x70,0x34,0x9e,0x4e,0x74,0x16,0x51,0x15,0x48,0x8c,0x35,0xfc,0x19,0x25,0xd6,0x4d,0x31,0xdc,0x96,0x4d,0xa1,0x8a,0x9b,0x83,0x2d,0x52,0x5e,0xb4,0x6e,0x73,0x21,0x4b,0x69,0x15,0x36,0xc6,0xf1,0xc,0xc8,0x86,0x22,0xf0,0xc8,0x30,0x86,0xee,0xad,0xb6,0x96,0x5d,0x7d,0x14,0xeb,0x2e,0xa5,0x3c,0xc5,0xad,0x99,0x53,0x42,0xd3,0xad,0x77,0x5a,0xa5,0xcb,0xf7,0x4a,0xb,0x77,0xbd,0x81,0x40,0x75,0x8d,0x96,0xe7,0xb1,0xb8,0x5d,0xc7,0x61,0x8b,0xe3,0x1b,0x37,0x90,0x93,0x97,0x1f,0x98,0x82,0x20,0x8,0x82,0x20,0x8,0xb7,0x0,0x11,0x0,0x5,0x41,0x10,0x84,0xdb,0x4e,0xb3,0x3e,0xc4,0x7d,0xf7,0xbf,0x61,0x16,0xae,0xb8,0xed,0xb7,0xb8,0x81,0xaa,0xfb,0x2f,0x67,0x12,0xa3,0x4a,0xcc,0x97,0x5,0xb5,0x2a,0xfe,0x14,0x21,0x88,0xdd,0x79,0x69,0x29,0xb4,0xe4,0x54,0xc5,0x36,0x2a,0x47,0xf0,0xb3,0xcb,0x28,0x46,0x2e,0xcb,0xb0,0xd5,0x5d,0x5,0x28,0x34,0xdd,0x9a,0xe3,0xbd,0x11,0xed,0xea,0x80,0x5c,0x56,0x0,0xd6,0x7,0x47,0xc8,0x19,0x68,0xda,0x96,0x1d,0x5e,0x7,0x75,0x6,0x9b,0x6b,0xa8,0x54,0xa3,0x6d,0x29,0x22,0x5b,0x22,0xcd,0xda,0x18,0x2a,0x54,0x60,0xf7,0x98,0xd2,0x6,0xd6,0x59,0x12,0xf5,0xac,0x65,0xe1,0x83,0x8b,0x21,0x14,0x17,0x33,0x9c,0x69,0x4,0x56,0xaa,0x88,0x5b,0xa5,0xf5,0x98,0x5a,0x74,0xdb,0x76,0x35,0x3b,0xa9,0x80,0xea,0x3c,0xd3,0xdc,0x1c,0x4c,0x82,0xd0,0xbc,0x66,0x5a,0x6b,0x18,0x47,0xcd,0xc1,0xe4,0x6c,0xa4,0x48,0x6c,0x99,0xa7,0x58,0x44,0x27,0xad,0x54,0x75,0xd9,0x39,0x47,0x42,0x56,0x89,0xd0,0x16,0x61,0xcf,0xba,0xb6,0xba,0xc8,0x32,0x8b,0x86,0xe4,0x1c,0x24,0x61,0xb1,0xe3,0x75,0x5b,0x8a,0xb1,0x86,0xa3,0xc0,0x39,0xc5,0xea,0x38,0x2b,0x8e,0x3d,0xad,0x15,0x52,0x4e,0xb3,0x18,0xc5,0xe,0xbd,0x72,0xc,0x6a,0x3d,0xb6,0x74,0xaf,0x94,0x66,0xd3,0x5e,0xe6,0x75,0x2a,0x2,0x98,0xae,0xc2,0x5a,0x99,0xf,0x69,0x17,0xc2,0x6d,0x11,0xac,0x42,0xc,0xb5,0x54,0xc4,0x1a,0x8b,0xc,0x12,0x27,0x63,0x8,0x73,0xc4,0x5c,0x1b,0x0,0xb9,0xa,0x83,0x45,0x50,0x73,0x4d,0xbb,0x23,0x5c,0x36,0xed,0xaa,0x3a,0xe1,0x8a,0xc0,0x68,0x5d,0x53,0x23,0xba,0xd,0x17,0xa0,0xcc,0x28,0x64,0x16,0xae,0xab,0xf5,0x8d,0x85,0x6b,0x63,0x1d,0xa2,0xf7,0xec,0xc2,0x23,0xb1,0xd3,0x5a,0xba,0xe6,0xb2,0x57,0x2c,0x3b,0x13,0x67,0xcb,0x1e,0x6a,0x81,0x48,0x79,0x66,0xca,0xb9,0x6a,0x6b,0xeb,0xb3,0x55,0xf6,0xb7,0xb1,0xae,0x8a,0xe4,0xe4,0xa0,0xcc,0x3b,0x45,0x3c,0x39,0x53,0xfc,0x96,0x84,0x49,0x50,0x1c,0x3f,0x27,0xa4,0x18,0xd8,0x1,0x4a,0xa2,0x37,0x30,0x47,0xb3,0xcb,0x3c,0xc7,0xa6,0xa3,0x98,0x73,0x11,0xd,0x15,0xaf,0x37,0x89,0xe4,0x76,0xc7,0x95,0x5a,0xdc,0xa1,0xf5,0xd9,0xe5,0xf5,0x28,0xe3,0x0,0x52,0x8c,0x48,0x39,0x62,0xea,0xb7,0x38,0xbe,0xfe,0x2,0x72,0xa,0xf2,0x3,0x53,0x10,0x4,0x41,0x10,0x4,0xe1,0x16,0x20,0x2d,0xc0,0x82,0x20,0x8,0xc2,0x6d,0xa7,0x3a,0xad,0xe6,0xca,0xdf,0x2a,0x10,0xe4,0xcc,0xa2,0x6,0x54,0x15,0x23,0x72,0x15,0x79,0x22,0x12,0xb,0x68,0x69,0x47,0x4c,0x41,0x15,0x71,0x68,0xe6,0xdf,0xc0,0xa2,0x6,0x39,0xb9,0x42,0x98,0xaa,0x23,0xaf,0x88,0x10,0x74,0x3c,0x6e,0xcd,0x65,0x17,0x5b,0x71,0x2c,0x35,0xed,0x8a,0xdc,0x68,0x4a,0xb1,0x4b,0xe,0xd5,0x8d,0x6,0xa0,0x36,0xbd,0x52,0xcc,0x76,0x82,0x73,0x1c,0x8d,0x65,0xd1,0x4f,0x29,0xc5,0x8e,0x34,0x20,0x46,0x5f,0x5,0xca,0xcc,0xc5,0xf,0x3a,0xa1,0x8a,0x5e,0x7c,0xa2,0x34,0x2b,0xf,0xb9,0x46,0x1e,0x73,0xa2,0xb5,0x50,0xec,0x56,0x2b,0xc2,0x4e,0x89,0xfe,0xb6,0xab,0xf5,0x4e,0x9c,0x93,0x4,0xaa,0x54,0x5d,0x77,0xe5,0xcf,0xae,0x69,0xe0,0xa7,0x11,0x3a,0x65,0x98,0xa6,0x85,0xf7,0x54,0x7e,0x2,0x6d,0x6a,0x24,0x97,0xe2,0xbf,0x1e,0x50,0x1a,0x46,0x1b,0x74,0xeb,0x83,0x3a,0x6f,0xd1,0xa6,0x58,0x63,0xa6,0x86,0x8b,0x2c,0x22,0xe6,0xfb,0x54,0xb,0x4d,0x74,0x11,0x96,0x52,0x2d,0xef,0x28,0x6b,0x5b,0x9c,0x8e,0x24,0x18,0x69,0x68,0xd6,0x9d,0x62,0xf0,0x0,0xf8,0x98,0x29,0x50,0x49,0x4a,0x15,0x43,0x4d,0x8d,0x61,0x2b,0x28,0x36,0x8d,0x65,0x12,0xa6,0x52,0xac,0x9,0x52,0xcd,0xfb,0x82,0xf6,0xf,0x47,0xbc,0x8d,0xa5,0x32,0xf,0x2e,0xff,0x28,0xb1,0x5a,0x63,0x6c,0x8d,0xef,0x52,0x2b,0xaf,0xa2,0x42,0x97,0x22,0x40,0x43,0xd1,0x5c,0x41,0x4d,0xf1,0xda,0x52,0x9c,0x81,0xc5,0x7c,0xc9,0xe2,0x4a,0x4d,0x21,0xa0,0x69,0x5b,0x28,0x45,0xf7,0x4d,0x19,0x12,0xc3,0xc8,0x5d,0xd9,0x22,0x86,0x9,0xae,0x69,0x91,0x12,0x9,0x95,0x5a,0xab,0x3a,0xe3,0xb2,0x14,0xcb,0x14,0x11,0x2d,0xc5,0x50,0xc5,0x3f,0xfa,0x5c,0xcb,0xeb,0x6d,0xea,0xcc,0xc7,0x39,0x22,0x4b,0xf3,0x12,0x6b,0x79,0x9,0x66,0x41,0xb4,0xc4,0xd8,0x49,0x38,0x8f,0x68,0xd7,0x7,0xd5,0xdd,0x57,0x9e,0x3b,0xa5,0x14,0xfc,0x38,0x50,0x4c,0x1e,0xb9,0xbe,0x1f,0xbc,0x96,0x89,0x4b,0x41,0xca,0x73,0xd7,0x74,0x6b,0xbe,0x97,0x24,0x6,0xba,0xf5,0x21,0xa2,0x9f,0x10,0x53,0x46,0xd3,0xad,0xb8,0x70,0x24,0xef,0x88,0x8e,0x8a,0x67,0x23,0x6a,0x63,0xa0,0xb5,0xad,0x51,0x7c,0xd4,0xb6,0xef,0x22,0x80,0x9e,0x99,0xd,0xa9,0x96,0x33,0x22,0x21,0xe2,0x9f,0x20,0x8,0x82,0x20,0x8,0xc2,0x2d,0x44,0x4,0x40,0x41,0x10,0x4,0xe1,0xb6,0x43,0x42,0x1f,0xaa,0x9b,0xab,0x94,0x7c,0x94,0x98,0x67,0x4e,0xb9,0x3a,0x93,0xca,0x9c,0x36,0x6a,0xbb,0x55,0xd0,0xa,0x35,0x36,0x39,0xb,0x29,0x2c,0xbc,0x71,0x3,0x2f,0x9,0x20,0x1,0x19,0x99,0xb,0x10,0x48,0xd8,0x2b,0x8d,0xa9,0x8a,0xa3,0x88,0x21,0xfa,0xfa,0x7a,0xc3,0xae,0xc1,0x22,0xf6,0x90,0xc8,0x98,0xd8,0x15,0xa6,0x61,0x94,0xe2,0x98,0x26,0x8b,0x7b,0xb5,0x90,0xc3,0xb2,0x3b,0xb0,0xab,0xed,0xab,0xc6,0x90,0xc3,0x8e,0xa2,0xa0,0x9a,0xc5,0x15,0x53,0xe7,0x18,0xe6,0x9c,0xc8,0x11,0xc7,0x91,0xd5,0x9c,0x32,0x32,0xc8,0x9d,0x45,0x62,0x5c,0x24,0x81,0x10,0xa0,0xf9,0x77,0xae,0x1,0x1c,0xb5,0x14,0x27,0x8e,0x8,0x1b,0xeb,0x90,0x62,0x69,0x4f,0x6,0xcd,0xe4,0xab,0x8e,0x38,0x3a,0x36,0x52,0x5e,0xcc,0xd6,0x9b,0xc5,0xb1,0xd2,0x70,0x5b,0x84,0xd4,0x65,0x21,0x49,0x71,0xbb,0x4d,0x63,0x5f,0x8b,0x21,0xc0,0x33,0x13,0x43,0x98,0xa8,0xd4,0xa2,0x34,0xf9,0x2,0xb5,0x88,0xa3,0xc6,0x48,0x8d,0xa9,0x5,0x17,0xda,0xba,0x79,0x4e,0x9d,0xd2,0x7c,0x4b,0x53,0x15,0xe8,0x8a,0x80,0x45,0x82,0x9f,0xad,0xe,0x3c,0x3,0x20,0xa6,0x58,0xe7,0xff,0xb1,0xa2,0x49,0x2e,0xbd,0xe0,0xe7,0x46,0x60,0x6e,0xed,0x2d,0x42,0x70,0x2a,0x2e,0xc8,0x14,0x90,0x39,0x92,0x1d,0x82,0xa7,0x48,0x34,0x69,0x4a,0xd0,0x66,0xfe,0xcc,0x32,0xf,0x12,0x35,0x56,0x9b,0x77,0x5c,0x98,0x5a,0x2b,0x16,0x33,0xcb,0xec,0xc5,0x34,0xaf,0x1f,0x32,0xac,0x69,0x6a,0xe3,0x6d,0xb9,0xf,0xf4,0xf9,0x91,0x44,0xc0,0x32,0x97,0x30,0x67,0x12,0x40,0xd9,0xa9,0x88,0x85,0x7b,0x13,0x0,0x17,0xc7,0xb4,0x55,0xf8,0x2c,0xe5,0x1a,0x39,0x3,0xc6,0x39,0x3e,0x76,0xde,0x69,0x8b,0xae,0xf3,0x4,0x8b,0x30,0xc9,0xb3,0xf8,0x22,0x48,0x14,0x2e,0x8e,0x41,0xa5,0xd,0xef,0x71,0x8a,0x94,0x27,0x16,0x92,0xcb,0x31,0xeb,0xf3,0xc8,0x7b,0xbd,0x1e,0x1f,0x8a,0xf7,0x71,0x9e,0x9b,0x82,0x59,0xd8,0xb5,0x4d,0x3,0x9d,0x12,0x72,0xca,0x35,0x26,0x5c,0x23,0xd2,0x3c,0x4f,0x91,0x84,0x6a,0x9a,0xe7,0x57,0x1a,0x90,0xeb,0x67,0xf1,0x33,0x50,0xa3,0xef,0x3c,0x6,0x80,0x54,0xdd,0x12,0x9,0x56,0x50,0xda,0x8a,0x8,0x28,0x8,0x82,0x20,0x8,0x82,0x70,0x8b,0x10,0x1,0x50,0x10,0x4,0x41,0xb8,0xed,0x54,0xd1,0xf,0x25,0x1a,0x58,0xe6,0xfa,0x91,0xa8,0x56,0x1c,0x58,0x24,0x32,0x29,0xa4,0x1a,0x97,0x55,0x75,0x6e,0x5c,0x8a,0x89,0x9d,0x5d,0x71,0x11,0x49,0xcd,0x35,0x82,0x5b,0xe3,0x86,0x6a,0x51,0x14,0xb2,0x2c,0xe,0x49,0xaa,0x16,0x87,0x94,0x66,0x5f,0x72,0x9a,0x2d,0x84,0x34,0xa5,0xd0,0x34,0xdd,0x2c,0xd2,0xb1,0xd3,0xa9,0x94,0x92,0x94,0x36,0xd9,0xe2,0xdc,0x23,0x41,0xc9,0x55,0x57,0x54,0x89,0x45,0xa6,0xe2,0xea,0xcb,0xc5,0xa5,0xc6,0x33,0xe8,0xca,0x5a,0xa8,0x12,0xd9,0xcd,0x2c,0xfc,0x24,0x18,0x4d,0x2,0xa4,0x61,0x87,0x1f,0xb9,0xdd,0x58,0x68,0x63,0x41,0x47,0x99,0x22,0x48,0x82,0x1d,0x86,0xa5,0x98,0x38,0x56,0xd7,0x5b,0x39,0x76,0x46,0xa2,0x86,0x58,0xeb,0x0,0x6b,0xd9,0xc1,0x97,0xe8,0xef,0x2c,0xe6,0x15,0x41,0x33,0xf8,0xa9,0xba,0x24,0xc1,0x6d,0xb8,0xae,0xe9,0x50,0x7,0xf0,0xf1,0xb5,0x95,0xef,0x29,0xa5,0xa1,0xcc,0x2c,0x74,0xcd,0xe2,0x93,0x6,0x52,0x62,0x31,0x47,0x57,0x97,0x5d,0xe6,0xf5,0x21,0x66,0x27,0x21,0x9,0xc0,0x24,0x22,0x16,0x81,0x75,0x79,0xcf,0xb2,0x52,0x74,0x67,0x8a,0x98,0x96,0x39,0x48,0x9d,0x16,0xaf,0xcb,0xe4,0x12,0x34,0x56,0x93,0xa8,0x59,0x1d,0x91,0xb9,0x46,0xca,0x8b,0xf0,0x5c,0xc4,0x2e,0xb5,0x70,0x28,0x16,0x97,0x1d,0xcd,0x21,0x2c,0xfb,0x51,0x73,0xf9,0x9,0x3b,0xf3,0xd8,0xed,0x56,0xdd,0x9e,0x45,0x64,0x2b,0x71,0xde,0x18,0xf8,0xfe,0xd2,0xf5,0x1a,0xfe,0x5e,0x75,0xe3,0x55,0xd7,0x62,0xf9,0x5c,0xf0,0x7c,0xc7,0x3c,0xcf,0x3c,0x64,0x91,0x91,0xd6,0x29,0x21,0xe7,0x22,0x18,0xce,0x65,0x1a,0x75,0x5d,0x72,0x86,0xca,0x19,0xc1,0x4f,0x7c,0xfd,0x3c,0x13,0x11,0xba,0xc6,0x7a,0x8d,0xb1,0xb3,0x70,0x1e,0x2,0x3b,0x8,0xd,0xcf,0xea,0x33,0x50,0xbc,0x5f,0x72,0x15,0x51,0x63,0x8d,0xd1,0x43,0x53,0x1c,0x18,0x69,0xf1,0xfc,0x66,0x12,0x53,0x15,0x3b,0x43,0x49,0xb0,0xe6,0xe8,0x3e,0x3d,0x3c,0x50,0x5a,0xa1,0xb1,0x1d,0x42,0x9c,0x45,0xbc,0xf2,0x2c,0x14,0xb7,0x6e,0x11,0xa6,0xe9,0xf9,0xa2,0xeb,0xab,0x73,0x1,0x45,0xfc,0x13,0x4,0x41,0x10,0x4,0x41,0xb8,0x65,0x88,0x0,0x28,0x8,0x82,0x20,0xdc,0x7e,0x4a,0x1,0x41,0x15,0xc6,0x48,0xe2,0xab,0xe,0xc0,0x3c,0x97,0x1c,0xa4,0x12,0x11,0xd4,0x6a,0x21,0x7e,0xa4,0x3a,0x37,0xaf,0x8,0x12,0x45,0xfc,0x53,0xb9,0x88,0x72,0xa,0x5a,0x97,0xff,0xd6,0x48,0x35,0x5a,0xc,0x16,0x79,0xe6,0x36,0xd8,0x22,0x48,0x66,0x50,0x61,0x47,0x2a,0xc7,0xf,0x9e,0xcb,0x38,0xf2,0xc2,0x59,0x18,0xd9,0x71,0x58,0xa2,0x9b,0x1a,0x46,0xf1,0xf1,0x6b,0xa1,0x7,0x5d,0x43,0x11,0x97,0x0,0x20,0x26,0xfa,0x73,0x8c,0x91,0x5d,0x53,0xb3,0x10,0x42,0xee,0xc4,0x54,0x85,0xa2,0xb2,0x6,0xf5,0x9a,0x16,0xc7,0x2b,0x2,0x24,0x16,0xa5,0x26,0x45,0x3c,0x43,0x6,0x95,0x3b,0x68,0xc5,0x2,0x14,0xbf,0x6,0xa8,0xf3,0xf4,0x94,0xd6,0xd0,0x50,0x80,0x22,0xf1,0x90,0xa,0x2a,0x72,0x2d,0x85,0x8,0xbe,0x34,0xc7,0xba,0x1d,0x51,0xad,0x8,0x9c,0x45,0x94,0xa3,0xe8,0x6c,0x62,0xb7,0x61,0xe2,0x52,0x8d,0xf9,0x16,0x2f,0xe3,0xa0,0x34,0x9b,0x11,0x28,0x33,0x12,0x77,0x8f,0x5b,0x5c,0x77,0x2c,0xf3,0x2e,0x84,0x38,0x6d,0x2d,0xcf,0xc6,0x33,0x80,0xca,0xf5,0xfe,0x97,0x38,0x69,0x6d,0x87,0x5e,0x14,0x63,0xd4,0x7b,0x98,0x32,0xb,0x99,0xa,0xa9,0x44,0x64,0x8b,0x53,0x90,0xe7,0x5,0x26,0x16,0x48,0xcb,0x67,0xd6,0x52,0x12,0x4b,0x73,0xd,0xc1,0x51,0xee,0xe5,0xf9,0xd3,0xb5,0x19,0x58,0x67,0xf8,0xda,0xe6,0xf3,0x45,0x89,0x6b,0x67,0xda,0x77,0xd6,0xba,0xea,0xb0,0x44,0x4d,0x7b,0xe7,0x62,0x68,0xe4,0xb5,0xc0,0x22,0x11,0x5b,0x8a,0x60,0x42,0x9d,0xe3,0x58,0xe6,0x3a,0x56,0xc1,0x2f,0xc7,0xb9,0x1,0xb8,0x44,0x92,0x6b,0x99,0x88,0xa9,0x25,0x3a,0x73,0xc4,0xb8,0xcc,0x98,0x8c,0x50,0xa,0x35,0xea,0x5e,0x9c,0x88,0xa5,0xfd,0xb9,0x94,0x84,0xcc,0xcf,0x88,0x66,0xe7,0x6d,0xaa,0x51,0xfa,0xac,0x72,0x2d,0xd7,0x81,0x4a,0xf5,0x7e,0x40,0x29,0xa8,0xc4,0xef,0xcb,0xf3,0x6c,0x4e,0xad,0xd,0x22,0x97,0x91,0x94,0xbd,0xa8,0x8a,0x88,0xbb,0xd8,0x2c,0x99,0xa3,0xfe,0x6a,0x51,0xa,0x4,0xa5,0x0,0x6d,0x44,0x4,0x14,0x4,0x41,0x10,0x4,0x41,0xb8,0x45,0x68,0x59,0x2,0x41,0x10,0x4,0xe1,0xb6,0xc3,0x5,0x6,0x55,0x29,0xe0,0x79,0x7f,0xd5,0x5,0x56,0xe2,0xa2,0x6a,0x76,0xe9,0x95,0x57,0x96,0xd9,0x7f,0xc5,0x61,0x56,0x9c,0x76,0x55,0x40,0x41,0xde,0x69,0xff,0x5,0xbb,0xab,0x34,0xb7,0x6,0x57,0x41,0x8c,0x67,0xf2,0x15,0xd7,0x15,0x58,0x44,0x89,0x3c,0xfb,0x2e,0x6,0x4f,0xe2,0x4a,0x11,0x61,0x38,0xf2,0x58,0xdc,0x51,0x25,0x56,0x5a,0x9a,0x67,0xcb,0xeb,0x8a,0x58,0x56,0xe6,0xbb,0x55,0x81,0x64,0xd1,0x46,0x9c,0x8a,0x23,0xaa,0x44,0x59,0x8b,0xeb,0x8b,0x1d,0x8e,0x65,0x24,0x1d,0xc5,0x55,0x49,0xa4,0x9b,0xa3,0x91,0x65,0xbd,0xe6,0xbf,0x55,0x81,0x25,0x2f,0x5d,0x6c,0x9,0x39,0xc7,0x1a,0xed,0x25,0x7d,0x6a,0x2e,0x5d,0xc9,0x89,0xe2,0xd1,0xd5,0x3d,0xc7,0x6e,0x3a,0xcd,0x25,0x16,0x65,0x2d,0xf2,0xe2,0x73,0x53,0x39,0xf,0x8e,0x49,0x97,0x99,0x72,0x45,0x50,0x2b,0x8e,0xbb,0x5c,0x85,0x5c,0x6a,0x74,0x2d,0xeb,0x84,0xc5,0xcc,0xb9,0x72,0x4e,0xc8,0x79,0xe1,0xf4,0x5b,0x88,0x81,0x65,0x3f,0xf0,0xd7,0x8b,0xc8,0x58,0xd6,0x31,0xf2,0x71,0x29,0x32,0xab,0xea,0x75,0xd7,0x16,0x64,0xa0,0x1e,0xa7,0x14,0x5f,0x94,0x7b,0x5e,0xdc,0x70,0xb4,0xc5,0xe6,0xd9,0x7c,0x75,0x6,0x65,0x9a,0x9b,0xa2,0x4b,0x8b,0xf1,0x72,0xd,0x4a,0x7a,0x97,0xca,0x4f,0xf4,0xa2,0xcd,0x79,0x76,0xc7,0xa9,0xba,0x57,0xd5,0x8e,0x83,0x54,0x2d,0x9a,0x9f,0xeb,0xac,0x4b,0x5e,0x87,0x12,0xed,0x2d,0xe7,0x5c,0x9d,0xa2,0xa,0x3b,0xa2,0x69,0x64,0x91,0xb6,0x3c,0xf,0x67,0xdd,0x80,0x3b,0xe7,0x2,0x70,0x81,0x8c,0xe6,0xc6,0x65,0x5b,0x5d,0x8d,0x69,0xe9,0x96,0xe5,0x75,0xaf,0x22,0x64,0x4e,0xfc,0x58,0xa6,0x7a,0xad,0x29,0xcd,0x80,0x5e,0x93,0xea,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x5f,0xab,0xee,0xd0,0x9c,0x77,0xdc,0xac,0x39,0x67,0xe8,0x2a,0x1e,0x2e,0xbf,0x3e,0x9f,0x5b,0x5e,0x88,0xf1,0x55,0x18,0xc5,0xfc,0x7f,0x4,0x94,0x48,0xf2,0xce,0x26,0x17,0x4,0x41,0x10,0x4,0x41,0x10,0x7e,0x2a,0x44,0x0,0x14,0x4,0x41,0x10,0x6e,0x3f,0x35,0xce,0xb8,0xfb,0xb,0x7e,0x11,0x39,0x4a,0x7c,0xb2,0x44,0x77,0x49,0x2c,0xc1,0xec,0x42,0x5b,0xc6,0x67,0x81,0x5d,0x71,0x61,0x39,0x63,0x8d,0x1a,0x1c,0x0,0x28,0x4,0x2e,0x9,0x29,0x62,0x57,0x29,0xca,0xa8,0xa7,0xc4,0xad,0xa8,0x39,0xe5,0x2a,0xdc,0x14,0x11,0xab,0xce,0x5c,0x43,0xde,0x11,0xaf,0x96,0x65,0x12,0xa9,0xb8,0xe0,0x16,0xc2,0x4c,0x11,0x32,0x4b,0x4c,0xb4,0x1c,0xaf,0xcc,0x6e,0x63,0x69,0x8b,0x67,0xa8,0x2d,0x96,0x87,0xc5,0x97,0x14,0x23,0xcf,0xc5,0x5b,0x8a,0x87,0x91,0xa2,0x9a,0xc5,0x36,0xb6,0x7c,0xf,0x50,0xa3,0xa8,0x85,0x32,0xef,0xaf,0x46,0x60,0x59,0x24,0xd2,0x9a,0xc4,0x20,0xb5,0x28,0x7e,0xc8,0x29,0x2e,0x9a,0x60,0xd5,0x4e,0x74,0xb6,0xb4,0x1a,0x97,0x28,0x6f,0xe4,0x79,0x84,0x73,0x64,0x1b,0xd5,0x91,0x89,0x1a,0xe7,0xd5,0x1c,0x57,0xce,0xf5,0xcb,0xe5,0xbe,0x45,0x8e,0xe,0x2f,0xe7,0x29,0x96,0xeb,0xa1,0xd7,0xcd,0xc2,0x60,0x5e,0xc4,0x88,0x97,0xe7,0xf,0x50,0xc9,0xa,0x15,0x6d,0xa8,0x2a,0x3a,0x2d,0x5d,0x6c,0xd5,0x25,0xc9,0x25,0x16,0xe0,0xcf,0xae,0xd1,0xd3,0x32,0x2f,0x72,0x21,0x3a,0x16,0xe7,0x22,0x1d,0x9f,0xe7,0x4c,0x96,0x86,0x5d,0x16,0x6,0x67,0x27,0xa4,0x9f,0x67,0x9,0x2e,0x5a,0x89,0xb1,0x98,0xfd,0x57,0xa,0x4b,0xb0,0x74,0xaa,0x2a,0x3d,0xcf,0xe0,0x83,0xaa,0xb1,0xed,0xaa,0x2e,0xa2,0xbc,0x16,0x3c,0xe3,0x31,0xd6,0x7b,0x52,0x9a,0x86,0x81,0x33,0xe2,0x24,0xb,0xcf,0x25,0xde,0x5d,0xd6,0xba,0xa,0xd1,0xe0,0x19,0x80,0x65,0x26,0x20,0x7f,0xee,0xec,0x22,0x65,0x7,0x66,0x79,0x34,0xab,0x66,0xcb,0xf7,0x1f,0xf3,0x63,0x3b,0x8b,0x78,0xf3,0x33,0xac,0x95,0xae,0xed,0xdd,0xe5,0xb9,0xa8,0xff,0x29,0xae,0xce,0x12,0x5,0xe7,0xb7,0xd2,0xbc,0xcf,0x33,0x3f,0x1e,0xf8,0x67,0x41,0x8e,0xe2,0xfe,0x13,0x4,0x41,0x10,0x4,0x41,0xb8,0x55,0x88,0x0,0x28,0x8,0x82,0x20,0xdc,0x76,0x8c,0x9d,0xc5,0x92,0x3a,0xb8,0xe,0x45,0x37,0xca,0xbb,0x85,0x1,0x2c,0x24,0x2d,0xcb,0x8,0x76,0xe6,0xbd,0x1,0xbb,0xa2,0x55,0x11,0x3a,0x62,0xa8,0xe2,0xcf,0xae,0xa2,0x81,0xfa,0xde,0x22,0xd0,0x95,0x88,0x66,0xc6,0xec,0xba,0xcb,0x5c,0x98,0x0,0x85,0x79,0xde,0xdc,0xa2,0x6d,0x35,0x63,0x57,0x80,0x5c,0x16,0x3b,0x14,0x91,0x2a,0x16,0x61,0x29,0x25,0x12,0x92,0x52,0xaa,0x2,0x48,0x9d,0x4b,0x8,0xd4,0xf9,0x70,0xb9,0x46,0xa3,0x73,0xfd,0x1a,0x0,0x64,0x8e,0x5d,0xd6,0xb9,0x73,0xa8,0x52,0xd9,0x62,0x1d,0x96,0x91,0x58,0x55,0x1d,0x85,0x50,0x6a,0x27,0x2e,0x5a,0x8e,0xbd,0x14,0x6,0xe7,0x75,0x53,0xb5,0xd1,0xb7,0x88,0x57,0xd4,0x6,0x8c,0x1d,0x27,0x9f,0x5a,0x88,0x4e,0x8a,0x85,0x43,0xf0,0x1a,0x14,0xf1,0x2c,0xc6,0x50,0x5,0x37,0xcd,0x2,0xdf,0x32,0xda,0xad,0xf9,0x35,0xf5,0xfe,0xb2,0x70,0x94,0xca,0x1a,0x61,0x6e,0xae,0xc5,0x8e,0xb3,0xef,0xcc,0xec,0x3b,0x45,0xf3,0xe9,0x32,0x3b,0xfa,0x48,0x88,0xa3,0xb5,0x29,0xc2,0x65,0x4a,0x71,0xd1,0x1a,0x8d,0x2a,0xa2,0x15,0xa7,0x9c,0xd2,0xe5,0xda,0xe7,0xd9,0x93,0x55,0x44,0xad,0xc2,0x69,0xac,0x5f,0xaf,0xe,0x43,0x2e,0xd4,0x28,0xeb,0x99,0xd2,0xdc,0xa6,0x8b,0x45,0x6c,0xba,0x8a,0xa9,0xe0,0xf2,0x11,0x2c,0xda,0x70,0x33,0xc7,0xaf,0xab,0xb8,0x99,0x58,0x4,0xd4,0x3b,0xb1,0xdc,0xb2,0xe6,0xa5,0x11,0xbb,0xc6,0xe8,0x53,0xae,0xf1,0x64,0xad,0x34,0xbb,0x12,0x4d,0xdd,0x7f,0x8a,0xf7,0x63,0x71,0x6f,0x2a,0x3e,0x87,0x52,0xba,0x41,0xfb,0x61,0xde,0x37,0x58,0x38,0x55,0xb9,0xa2,0xa6,0xee,0xe9,0x94,0x17,0xae,0xdd,0xfa,0x38,0xcd,0x6e,0xd4,0xbc,0x7c,0x9e,0x17,0x91,0xe7,0x94,0x13,0x52,0x4c,0x67,0xf6,0x1b,0x16,0xcf,0xe5,0x82,0x85,0xa8,0xa8,0xec,0x4a,0x7e,0x58,0xa,0x82,0x20,0x8,0x82,0x20,0xdc,0x22,0x44,0x0,0x14,0x4,0x41,0x10,0x6e,0x3b,0xd3,0x38,0xec,0x44,0x3c,0x8b,0xfb,0x6e,0x16,0xb4,0x66,0xf1,0x40,0xd5,0x59,0x77,0xb9,0xba,0xd4,0x96,0xdf,0xc3,0x22,0x6e,0xa,0x60,0x8e,0xe6,0xb2,0xcb,0x2e,0xc5,0x48,0x2,0xda,0x8e,0x68,0xa8,0xea,0x6b,0xc0,0xad,0xc2,0x45,0x8f,0x28,0x22,0x13,0x35,0xe,0xeb,0x1d,0x51,0xad,0xc4,0x51,0x53,0x8,0xd0,0x4b,0xa1,0x64,0x29,0x44,0x2,0x3b,0xf1,0xdf,0xf2,0x79,0x35,0xee,0x5a,0xdc,0x76,0xe5,0xfa,0xe9,0xd,0x14,0xc9,0xac,0xee,0xb5,0xb9,0xd9,0xb8,0x44,0x73,0xab,0x13,0x11,0xa8,0xe5,0x10,0x45,0x40,0x83,0x52,0xf5,0x7b,0x31,0x78,0x8e,0x6b,0xc6,0xea,0x88,0xd4,0xb,0x37,0x5b,0x15,0xa4,0xea,0xac,0x45,0x3a,0xa7,0xc8,0x73,0xee,0x48,0xf4,0x4b,0xbb,0x8e,0xad,0xb2,0x56,0x7c,0x87,0xd2,0xb2,0xd4,0x81,0xaf,0xa7,0xcc,0xcb,0x2b,0x73,0xfc,0x48,0x7,0x52,0x55,0xe0,0x2a,0xd1,0xd1,0x22,0xa4,0xa5,0x14,0xe1,0x5c,0x5b,0xc5,0x5b,0x7e,0x75,0x3d,0xa6,0x52,0xba,0xc6,0x68,0xe7,0xfb,0x96,0xab,0x73,0xaf,0xc4,0xbc,0x17,0xcd,0x2a,0x3b,0x6b,0x98,0x16,0x73,0xfd,0x4a,0xb3,0x6e,0x5e,0xcc,0x9,0x2c,0xef,0x2f,0xce,0xc3,0x22,0x16,0x17,0xf1,0xae,0x9e,0x57,0x89,0x5,0x2f,0x62,0xe8,0x45,0x16,0xd3,0xc6,0x20,0x85,0x40,0x33,0x23,0x59,0x98,0xa5,0x7b,0x10,0x78,0x76,0x24,0xdd,0x8f,0xda,0xd8,0xcb,0xf3,0xf8,0x32,0x72,0x15,0xfa,0xf8,0xee,0xee,0x26,0xbc,0x73,0xa6,0x26,0xe3,0x22,0x14,0xf3,0x1e,0xad,0x85,0x25,0x31,0xd0,0x5c,0xc3,0xf2,0x3d,0xbe,0x8f,0xd5,0x3d,0x58,0x1d,0x9c,0xbb,0x7b,0xb3,0xb8,0x19,0x15,0xe6,0x18,0x32,0xdd,0x5a,0x55,0x63,0xcc,0xd5,0xd,0x59,0x62,0xed,0x4a,0xef,0xac,0xfd,0x72,0x4d,0x0,0x2c,0xe6,0x1b,0xce,0xb3,0x39,0xe7,0x75,0x9e,0x45,0xce,0x59,0x37,0xe4,0x22,0x18,0x3e,0x8f,0xba,0xaf,0xd2,0xe2,0x79,0xc8,0x60,0x97,0xa6,0x97,0x1f,0x96,0x82,0x20,0x8,0x82,0x20,0x8,0xb7,0x88,0xf9,0xb7,0x2d,0x41,0x10,0x4,0x41,0xb8,0x8d,0x3c,0xf0,0xb6,0xf7,0xe1,0xce,0x7b,0x5e,0x53,0x63,0xa6,0xa9,0xba,0xe8,0xf4,0x4e,0x34,0xf7,0xec,0x3f,0x57,0x24,0x32,0x18,0x16,0x28,0x30,0x97,0x38,0x54,0xd7,0x55,0x9e,0x1b,0x80,0x17,0x33,0xcd,0x4a,0xfb,0x6c,0x9d,0xbb,0xc7,0x2e,0x33,0x8a,0x44,0xea,0x2a,0x1c,0x6a,0x76,0x62,0xd5,0xf7,0x95,0x4e,0x2,0xad,0xea,0xf9,0x51,0x6b,0x6b,0xaa,0x7a,0xcb,0xb2,0x40,0x42,0xd5,0x8,0x24,0x2b,0x19,0x24,0x63,0x61,0x27,0xe3,0xb,0x76,0x8f,0x95,0x66,0x56,0x2e,0x9a,0x28,0x2,0x56,0x11,0x51,0x34,0xb7,0xc,0x2f,0xaf,0x27,0x2f,0xe2,0xb5,0x73,0x81,0x6,0xaa,0xd3,0x8d,0x17,0xa9,0x46,0x3c,0xf5,0xc2,0xe9,0xa6,0x17,0x4e,0x46,0x55,0x44,0x9b,0x45,0xa3,0x6e,0x39,0xd7,0xe2,0x94,0xa3,0xcf,0x5b,0x46,0x9d,0x51,0x63,0xd5,0xa5,0x74,0xa2,0x58,0xc1,0x52,0x4a,0x3b,0x82,0xe,0xbd,0x96,0xc5,0xae,0xea,0x60,0x54,0x73,0x61,0xc9,0x62,0xee,0x60,0x9d,0xf3,0xa8,0xe7,0x58,0x2c,0x16,0x85,0x10,0xb9,0xb4,0x3,0x2f,0xca,0x3e,0xe8,0x58,0xb4,0xc6,0xa,0x24,0x82,0x19,0x63,0x77,0xe2,0xac,0xf4,0xdd,0xb9,0xfc,0xa3,0x8,0xb1,0x79,0x21,0x64,0xd1,0x5a,0x1a,0x94,0x36,0x62,0xc5,0x2d,0xb4,0x65,0xfe,0x5e,0x99,0xf9,0xb8,0xbc,0xc7,0xd5,0xdd,0xa7,0x4d,0x6d,0x2e,0xce,0x8b,0xd9,0x7d,0xa5,0x5d,0x99,0x8a,0x44,0xb0,0xf3,0xf5,0x72,0x9c,0xd2,0xd2,0xac,0xf9,0x18,0x24,0x8,0xf2,0x6b,0x16,0xe7,0x50,0x1d,0x71,0x8b,0x36,0x64,0xa5,0x96,0xfe,0xcf,0xc5,0x53,0x52,0x4,0xcf,0xfa,0xc,0xa9,0x9d,0x98,0xae,0x5a,0x88,0x79,0xb4,0xd6,0xf4,0x9e,0x32,0xf7,0x92,0xca,0x63,0xd2,0x7c,0x9f,0x6b,0x71,0xa,0x76,0x67,0xf6,0x65,0xcc,0xcf,0x1f,0x70,0xee,0x99,0x9b,0xa3,0xdc,0x79,0xa1,0x49,0xe6,0x7a,0xcf,0x96,0x5f,0xab,0xe7,0xc5,0x91,0xef,0x18,0x3c,0x86,0xed,0x6,0xcf,0x3c,0xf5,0x8,0xa6,0xed,0xb1,0xfc,0xa0,0x14,0x4,0x41,0x10,0x4,0x41,0xb8,0x45,0x88,0x0,0x28,0x8,0x82,0x20,0xfc,0x9b,0xf9,0x7,0x48,0x29,0xdc,0xf9,0xea,0x37,0xe0,0xd2,0xd5,0xbb,0x60,0x6d,0x53,0x8b,0x5,0x96,0x73,0xe7,0x58,0x26,0xe0,0xc6,0x5a,0x16,0xbe,0x8c,0xa5,0xb8,0x67,0x31,0x7e,0x69,0x43,0x33,0xd2,0x52,0x60,0x21,0x81,0xde,0x53,0x66,0xfc,0x29,0x65,0xce,0x35,0xcf,0x62,0x31,0xd7,0xae,0x8a,0x10,0x7c,0x9c,0x9c,0xe3,0xce,0x3f,0x91,0xb9,0x44,0x47,0xb9,0x2c,0xa2,0xb8,0xd2,0xb4,0x9e,0xe7,0xa8,0x81,0xdd,0x5c,0x31,0x78,0x18,0xdb,0xd0,0x7b,0x34,0x3b,0x1b,0x4b,0x74,0x93,0x85,0x36,0x12,0x96,0x2,0xb4,0xb6,0x3b,0x82,0x9d,0x62,0x21,0x8f,0x5a,0x84,0xd5,0x2c,0xfc,0x41,0xd5,0x18,0x26,0x40,0xee,0xbb,0x52,0x5c,0x51,0xe2,0xb7,0xda,0x58,0x8e,0x4f,0xc7,0xda,0x1a,0x5b,0xd6,0x4e,0x29,0x3,0x68,0x8d,0xcc,0xef,0xcb,0xe5,0x7c,0x6b,0x44,0xd6,0xf1,0x7a,0xce,0x71,0xd9,0x39,0xb0,0xaa,0xea,0xff,0x52,0x50,0x5c,0x20,0x52,0xa,0x5c,0xb4,0x36,0x73,0xa1,0xc5,0x42,0x4,0x2b,0x91,0x5c,0x94,0x68,0x6e,0x9e,0xc5,0x53,0x28,0x8d,0x14,0x7d,0x8d,0xe9,0xe6,0x8c,0x45,0xab,0x73,0x89,0xba,0x1a,0x5e,0x3f,0x5d,0xdf,0x53,0x5c,0x9f,0xaa,0x8a,0x8f,0xb,0xf1,0x55,0x6b,0xe4,0x18,0xc9,0xaf,0x46,0xd9,0x5e,0xbe,0x7b,0x99,0xcf,0x81,0xdc,0x74,0x4a,0xdb,0x33,0xb1,0x5c,0x16,0x5b,0xb5,0x39,0x73,0x4e,0xf9,0xcc,0x67,0x95,0xcf,0x46,0x6d,0xa7,0x2d,0xf7,0x7d,0xb7,0xc1,0x97,0x3e,0x97,0x4,0x34,0x3e,0xef,0x65,0x9c,0xbd,0xec,0x6b,0x54,0xc3,0x1c,0xad,0x23,0x8b,0x5f,0xe5,0x5a,0x17,0x46,0xd8,0xea,0xc2,0xab,0xff,0x5d,0x1b,0x9e,0x53,0x15,0xf9,0xca,0xbe,0xa9,0xaf,0xaa,0xc2,0x6a,0xae,0xf7,0xb1,0x38,0x48,0xd5,0xc2,0xc3,0x8,0xb5,0x14,0xe9,0xca,0x39,0xaa,0xea,0x2e,0xad,0xf7,0xa3,0x5e,0x3c,0xe6,0xd7,0xb3,0x58,0x58,0x9d,0xb9,0x8b,0x67,0x7a,0xb9,0x86,0xc5,0x7d,0x39,0x5f,0xdf,0x1c,0xed,0x47,0x15,0x9c,0x67,0x27,0xb0,0x1f,0x7,0xc,0xfd,0x16,0x27,0xd7,0x9e,0x87,0x1f,0x37,0xf2,0x43,0x52,0x10,0x4,0x41,0x10,0x4,0xe1,0x56,0xfe,0xfe,0x5,0x11,0x0,0x5,0x41,0x10,0x84,0x7f,0x83,0x68,0xe3,0xd0,0x5d,0xba,0x1b,0xae,0x69,0x51,0x62,0x84,0x39,0x5,0x40,0x19,0xc4,0x18,0x60,0xb4,0x42,0x86,0x86,0x56,0x19,0x29,0x3,0x39,0x6,0x68,0xd7,0xc1,0x18,0xd,0x3f,0x8d,0x70,0xae,0x41,0xca,0x80,0x35,0x1a,0xda,0x58,0xc,0x7d,0xf,0x20,0x21,0x86,0x80,0xa6,0x3b,0xa0,0x63,0x21,0x23,0xc6,0x44,0x2d,0xb5,0x28,0xed,0xb7,0x9,0xed,0xea,0x10,0x7e,0x3c,0x85,0x36,0xd,0x45,0x47,0x53,0x84,0x6b,0xd7,0x35,0x5e,0x9b,0x82,0x27,0xa1,0x28,0x27,0x68,0xa5,0xd0,0x74,0x6b,0x4c,0xc3,0x0,0x63,0xd,0xbb,0x9,0xd,0x62,0x18,0xc9,0xcd,0x95,0x32,0xda,0x6e,0x85,0x69,0x1c,0x91,0x52,0x80,0x6b,0x3a,0xa4,0xe0,0x61,0x9b,0xb6,0xce,0xdb,0x3,0x14,0x5c,0xd3,0xa0,0x3f,0xb9,0x8e,0xee,0xf0,0xa,0x32,0x8b,0x96,0xda,0x18,0xf8,0x69,0x24,0xa1,0x26,0x4c,0x24,0x78,0x56,0x81,0x2d,0x54,0xb7,0xa0,0x52,0x1a,0x31,0x78,0x58,0xd7,0xc0,0x8f,0xa7,0x80,0x6e,0x60,0x8c,0x85,0xb1,0x16,0xd3,0x38,0xc0,0x5a,0x5b,0x54,0x1a,0x40,0x93,0x1b,0xae,0x69,0x5a,0x6c,0x4f,0xae,0x41,0x9b,0x6,0xd6,0xb9,0xea,0xea,0x33,0xd6,0x21,0xc5,0x88,0xe0,0x27,0x34,0xdd,0xa,0x61,0x1a,0x11,0xa3,0x87,0xb1,0xe,0x50,0x1a,0x71,0xea,0x1,0x0,0xae,0x5d,0x43,0x1b,0x83,0x61,0x73,0x2,0x63,0x1b,0x9a,0xdd,0x97,0x22,0xac,0x75,0x0,0x14,0xc2,0xd4,0x3,0xda,0x42,0xab,0xc,0x40,0x23,0x4c,0x5b,0x28,0xbb,0x82,0xd1,0x24,0xc3,0x36,0x6d,0x87,0x69,0xd8,0xb2,0xb8,0xab,0x38,0x9a,0x9c,0xa1,0xad,0x43,0x8e,0x1,0x29,0x8c,0x68,0x56,0x87,0x8,0x9e,0x3e,0x3b,0x73,0xf4,0xb5,0x8,0x62,0x40,0x46,0xc,0x53,0xbd,0x2e,0xe3,0x3a,0x16,0xb7,0x32,0x94,0xb6,0x55,0x10,0xcd,0x4a,0x43,0x71,0x8b,0x6c,0x29,0x3,0x51,0x0,0x94,0xb1,0x35,0xc6,0x9d,0xa2,0x87,0xb6,0xe,0x80,0x86,0x73,0xe,0x21,0x44,0x3a,0x5f,0xa5,0x60,0x9d,0x43,0x8c,0x11,0xc6,0xb6,0x88,0x7e,0x60,0xc1,0x30,0x20,0x43,0xc1,0x18,0xb,0x3f,0x6e,0x61,0x5c,0x87,0x14,0x3,0x39,0x37,0xc3,0x4,0x6d,0x1c,0x52,0xe4,0x98,0xaa,0xd2,0xd0,0x5a,0xf1,0xac,0xbb,0x80,0x14,0x69,0x2f,0x95,0xd9,0x87,0xda,0x36,0x48,0x61,0xe2,0xfd,0x48,0xfb,0x1e,0x4a,0xf3,0x71,0x2c,0xb4,0xd6,0x8,0x7e,0x64,0xf7,0x67,0x20,0x31,0x50,0x53,0xbb,0xb3,0x2a,0x85,0x20,0x29,0x70,0x33,0xb6,0xa2,0xfb,0x9b,0x3c,0x68,0x9a,0xb,0x37,0x4f,0x9b,0x6,0x39,0x7a,0x12,0x75,0x73,0x42,0x4e,0x9e,0xae,0xa3,0x88,0xa8,0x99,0x8b,0x56,0xd4,0x3c,0x53,0x53,0xbb,0x15,0xcf,0x6f,0xa4,0xd6,0x68,0x72,0xfd,0x19,0x16,0x3a,0x63,0x15,0xd,0xf3,0x42,0x10,0x2f,0xd7,0xad,0xb4,0xe5,0x48,0xf2,0x4,0x6d,0x5b,0xba,0x77,0x29,0xf1,0xe7,0x83,0x3e,0x4f,0x69,0x0,0x69,0x9e,0x17,0x88,0x44,0xe7,0x84,0x59,0x48,0x2f,0xe7,0x13,0x86,0xd3,0x3d,0xee,0x5f,0x41,0x10,0x4,0x41,0x10,0x4,0xe1,0x56,0x20,0x2,0xa0,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0xbc,0x82,0x91,0x12,0x10,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x78,0x5,0x23,0x2,0xa0,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0xbc,0x82,0x11,0x1,0x50,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x5e,0xc1,0x88,0x0,0x28,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0xaf,0x60,0x44,0x0,0x14,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x84,0x57,0x30,0x22,0x0,0xa,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0xc2,0x2b,0x18,0x11,0x0,0x5,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0xe1,0x15,0x8c,0x8,0x80,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0xf0,0xa,0x46,0x4,0x40,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x78,0x5,0x23,0x2,0xa0,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0xbc,0x82,0x11,0x1,0x50,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x5e,0xc1,0x88,0x0,0x28,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0xaf,0x60,0x44,0x0,0x14,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0x10,0x84,0x57,0x30,0x22,0x0,0xa,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0xc2,0x2b,0x18,0x2b,0x4b,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x3f,0x7b,0x68,0x63,0xb1,0x3a,0xba,0x82,0xcb,0x57,0x5f,0x85,0x9c,0x33,0x7f,0xcd,0xc0,0x58,0x8b,0x30,0x4d,0xc8,0x39,0xc1,0x58,0x87,0xe0,0x27,0x0,0xa,0x4a,0x1,0x50,0xa,0x4a,0x69,0xe4,0x14,0x61,0x6c,0x83,0x14,0x3,0x94,0xd6,0x48,0x31,0xc2,0x58,0xb,0xad,0xd,0xa6,0xb1,0x87,0x75,0xd,0x72,0x4a,0x74,0x5c,0xa5,0xa0,0xf8,0x33,0x63,0xc,0x70,0x4d,0x87,0x18,0x7c,0xfd,0x4c,0xa5,0xe9,0x78,0x4a,0x69,0x58,0xe7,0x10,0x43,0x80,0xb1,0xe,0xde,0x4f,0x70,0xae,0xe1,0xcf,0x47,0x7d,0xbd,0x6b,0x1a,0xf8,0x69,0x2,0x14,0x80,0xc,0x28,0x45,0x47,0x4f,0x31,0xf2,0xb1,0x12,0xb4,0xd1,0x74,0x8c,0x71,0xe4,0x73,0x6,0x94,0x9a,0xbd,0xb,0xc6,0x3a,0xe4,0x14,0x11,0x53,0xa4,0x2f,0x64,0x20,0xe7,0x4,0xeb,0x5a,0xc4,0xe0,0xf9,0xf3,0x12,0x0,0x85,0xa6,0x69,0xe1,0xa7,0x11,0xca,0x18,0xa4,0x18,0xe0,0x5c,0xb,0xef,0x47,0x20,0x3,0xe0,0xe3,0xa6,0x14,0xa1,0xea,0xda,0xd0,0x75,0x2b,0x3d,0x7f,0x1e,0x9d,0xa2,0x82,0xd6,0x1a,0x99,0xcf,0xb5,0x7c,0x86,0x52,0xa,0xae,0xe9,0x90,0x73,0x46,0xf0,0x23,0x1d,0x23,0x27,0x68,0x63,0xa1,0x0,0x4,0xef,0xa1,0x94,0x42,0xca,0x9,0x5a,0x69,0x40,0x61,0xbe,0x2f,0x39,0xc3,0x35,0x1d,0x42,0xa0,0xd7,0xcc,0x6b,0xd4,0xc2,0x8f,0x3,0xad,0x11,0x14,0x9d,0x9b,0x9e,0xcf,0xcd,0x3a,0x57,0xd7,0xab,0xde,0x8b,0x9c,0xf9,0x1e,0x34,0x7c,0xed,0x74,0x9e,0x19,0x79,0xfe,0xbe,0xd6,0x70,0xae,0xc5,0x34,0x8d,0xd0,0x7a,0xfe,0x3c,0x40,0xc1,0x3a,0x47,0xeb,0xa4,0x34,0x9d,0x6f,0x8a,0x8b,0x63,0x3a,0x24,0xfe,0x6c,0xad,0xd,0x62,0xf4,0xf5,0xf3,0xcb,0xbd,0xa5,0xf5,0x53,0x48,0x31,0x42,0x6b,0x3,0x6d,0x6d,0x3d,0xb7,0x72,0x8f,0x15,0x2d,0x38,0x9f,0x5b,0x80,0xd6,0x6,0x50,0xe5,0xfd,0xb4,0x6e,0xe5,0x9c,0x8c,0xb5,0x40,0xce,0x48,0x31,0xc1,0x3a,0x87,0x10,0x2,0xdd,0x68,0x86,0xd6,0xa1,0x81,0x2,0x10,0x43,0x40,0x46,0x86,0x31,0x16,0x21,0x78,0xba,0x4f,0x39,0xf3,0xf9,0xd2,0x9f,0xe9,0xb3,0x69,0x4d,0x9a,0xb6,0xc3,0x34,0xe,0x75,0x4d,0x95,0xd6,0x40,0xce,0x30,0xd6,0x21,0xc6,0x40,0xf7,0xc0,0x35,0xbc,0x87,0x5b,0xa4,0x14,0x77,0xee,0x91,0x73,0x2d,0x80,0x8c,0x10,0x3c,0x8c,0xb1,0x48,0x29,0xcd,0x7b,0x88,0xef,0x89,0x31,0x96,0xce,0x21,0x25,0x28,0xa5,0x61,0xac,0x41,0x8c,0x91,0xf6,0xb7,0x36,0xbc,0xaf,0xe7,0x75,0x36,0xd6,0x21,0xe7,0xc,0x3f,0xd,0x68,0xbb,0x35,0xa6,0x69,0x98,0xd7,0x8b,0xef,0x9d,0x2,0xbd,0x7e,0x1a,0x7,0xdc,0x7c,0xe1,0xe9,0xc5,0xfd,0x13,0x4,0x41,0xf8,0xf1,0x88,0x0,0x28,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x3f,0x63,0xbc,0xea,0xb5,0x6f,0xc6,0x3,0x6f,0x79,0x7,0xba,0xf5,0x21,0x89,0x9,0x40,0x15,0xd4,0xaa,0x5a,0x97,0xcf,0x7c,0x2d,0x9f,0xff,0x62,0x46,0x86,0x5a,0xbc,0x39,0x57,0x41,0x2e,0x57,0xf1,0xaf,0x92,0xab,0x16,0x81,0x59,0x88,0x59,0x7c,0x1f,0xb3,0x58,0x48,0x82,0xd3,0x99,0x6f,0xcf,0x27,0xb1,0x43,0x11,0x88,0xf2,0xf2,0x90,0xb,0x61,0x63,0x29,0x8c,0xfd,0x38,0xe6,0x63,0xcd,0xa2,0xd3,0xee,0x62,0xf0,0x6b,0xe8,0xc0,0xb3,0x88,0x79,0xe6,0xcc,0xca,0x9a,0xe4,0xfa,0x55,0x12,0x90,0xea,0x79,0x94,0x85,0x50,0x7b,0xae,0x2d,0x63,0x77,0xdd,0x76,0xd6,0x2a,0xd7,0xef,0x97,0xf3,0xc8,0x7c,0x8d,0xe5,0x9a,0x73,0x3d,0x7c,0xb9,0x86,0x72,0xde,0x24,0x68,0xf2,0xdd,0x99,0xcf,0x47,0x2d,0x97,0xbf,0x9c,0xf3,0xe2,0xfc,0x76,0xbe,0x7e,0xe6,0x7e,0xd4,0x7b,0x9c,0xcf,0xed,0x8f,0xbc,0x58,0xff,0xf9,0xad,0x45,0x35,0x3d,0x7f,0x2b,0x77,0xb7,0x5e,0xae,0xfb,0xa5,0x9e,0x3f,0x9f,0xf3,0xce,0x67,0xd4,0xc3,0x2d,0xce,0xef,0xfc,0x8d,0x38,0xb3,0x94,0x67,0xd6,0x73,0xf9,0xdf,0x7b,0xf7,0xf9,0xbc,0x9d,0x94,0x3a,0xbb,0x5f,0xce,0x6d,0xf1,0x9d,0xcf,0x29,0x7b,0x28,0xe7,0xb3,0xfb,0x3d,0x2f,0xf6,0xe6,0xd9,0xbf,0xef,0xdb,0xab,0xea,0x82,0xb,0xbb,0x60,0x5f,0xe7,0xc5,0x7a,0xed,0xec,0x5,0x54,0x61,0xb3,0xdf,0x9c,0xe0,0xd9,0xa7,0x1e,0xc3,0xb,0x3f,0xfc,0x1e,0x12,0x8b,0x96,0x82,0x20,0x8,0x2f,0x87,0xba,0xf8,0xa7,0x8e,0x20,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0xff,0x7f,0xe3,0xfe,0x37,0xbf,0xb,0x6f,0x78,0xeb,0xbb,0xd1,0x76,0x6b,0x68,0x63,0xaa,0x28,0x70,0x21,0x67,0xc5,0x8b,0x22,0xb0,0x2d,0x44,0xa7,0xaa,0x82,0xe4,0x7c,0x46,0x3a,0x29,0x6f,0x59,0x88,0x29,0x3f,0xe9,0x2f,0x13,0x67,0xc5,0xb2,0x97,0x79,0xc3,0x2c,0x76,0xec,0xa,0x61,0x55,0x58,0xc1,0x2c,0xea,0xed,0x8,0x45,0xcb,0xe3,0xfd,0x44,0xbf,0xd9,0x2c,0x84,0xc0,0x85,0x88,0x56,0x2f,0x1f,0xbb,0xe2,0xdf,0x3e,0x19,0x6f,0xfe,0xb,0xbd,0xfa,0xbc,0x48,0x74,0xc1,0x6f,0x5c,0x67,0x34,0x9f,0xfd,0x62,0x51,0xbe,0xf8,0xd,0x2f,0xbb,0xea,0x17,0x5d,0xfc,0x59,0xa1,0x72,0x8f,0x2e,0xbb,0xb8,0x5d,0x4a,0x2d,0xff,0xfb,0xbc,0xc8,0x3b,0x7f,0xfd,0xe5,0xd4,0xe6,0x9f,0x80,0xb3,0x1f,0x76,0x6e,0xaf,0xd6,0xd5,0x3d,0x7b,0xa,0xbb,0xe2,0x6e,0xde,0x23,0x58,0xee,0x6c,0x89,0xf9,0x5e,0xff,0x95,0x58,0x9e,0xdf,0xd9,0x7b,0xb5,0xdc,0xd7,0x17,0xfe,0xb6,0x3d,0xb,0xbd,0xfb,0x6e,0x55,0x3e,0xb7,0xeb,0xce,0x3e,0x65,0xe7,0x14,0xfc,0x1d,0xb1,0x34,0xc5,0x88,0xeb,0x2f,0x3c,0x87,0x27,0x1f,0xf9,0x6,0x6e,0xbe,0xf0,0xb4,0xfc,0x70,0x14,0x4,0xe1,0xe5,0x7f,0x24,0x41,0x4,0x40,0x41,0x10,0x4,0x41,0x10,0x4,0x41,0xf8,0x99,0xc0,0x75,0x87,0x78,0xcf,0xaf,0x7c,0x14,0x77,0xdc,0x75,0x2f,0x9c,0x6b,0xa0,0xb4,0x61,0x3d,0x2f,0x9d,0xf9,0x1f,0xf5,0x17,0xc9,0x3c,0xe5,0xdb,0xfb,0xc4,0xb9,0x7d,0x42,0x87,0x2,0x54,0x9e,0xd,0x62,0xd8,0x6f,0xca,0xda,0xfd,0xa5,0x22,0x5f,0xf0,0xaa,0x97,0xf9,0xcd,0x63,0xb6,0xc2,0xed,0x7e,0xfe,0x85,0xbf,0xad,0x9c,0xb7,0x37,0xee,0x88,0x77,0xfb,0xc4,0xc2,0x97,0x65,0x9f,0xe0,0xa6,0x7e,0xcc,0xf5,0xa8,0x1f,0x7f,0xbd,0x2f,0xf3,0x6b,0xd8,0x52,0x78,0x7c,0xb9,0xdb,0x52,0xdf,0x71,0xee,0xb5,0xf3,0xb5,0xef,0x3a,0xd1,0xd4,0xcb,0xae,0xd3,0x5f,0xeb,0xaf,0x81,0x2f,0xb3,0x54,0x79,0xe9,0xaa,0xab,0x42,0xf3,0x79,0x81,0xee,0xa7,0x16,0xed,0xfe,0x52,0xe7,0x7b,0x91,0x68,0xab,0xce,0x8b,0xe4,0xf5,0xeb,0x38,0xb3,0xdf,0x2e,0x94,0x5e,0x7f,0xe2,0xdd,0xb0,0x77,0xb1,0x76,0x5c,0xa6,0x67,0x44,0xd2,0x1d,0x11,0x31,0x63,0xea,0x7b,0xfc,0xe0,0xf1,0x6f,0xe3,0x7b,0xdf,0xf8,0x82,0xfc,0x90,0x14,0x4,0xe1,0x42,0x24,0x2,0x2c,0x8,0x82,0x20,0x8,0x82,0x20,0x8,0x3f,0x23,0x18,0xeb,0x60,0x5d,0x3,0x6b,0x1d,0x8c,0xb5,0x75,0x2e,0x5e,0x4a,0xa,0x48,0x71,0x21,0xe2,0xed,0x7a,0x89,0x16,0x1e,0x2e,0x2c,0xb2,0x99,0xf4,0x8a,0xc5,0x7c,0xb6,0x8c,0x7c,0x5e,0x69,0xe2,0x18,0xe2,0x45,0x72,0xa2,0x2,0x68,0x46,0xd9,0xee,0x57,0xf8,0x8f,0x6a,0xe1,0xd2,0xc2,0xfe,0xc8,0xec,0xd9,0xb7,0x2d,0xcf,0xad,0x1c,0xe2,0x9c,0xdc,0xa2,0x17,0x57,0xa6,0xe6,0x4b,0x5a,0x44,0x4a,0xcb,0x35,0x9d,0x3d,0xa5,0x97,0xb9,0xa,0xec,0x7f,0xf1,0xee,0xdf,0xe7,0x28,0x2b,0x7d,0x6f,0xc7,0xa9,0x76,0xee,0x7d,0x1c,0xb5,0xde,0x11,0xfb,0x96,0x8e,0xba,0x33,0xa2,0x9c,0x9a,0x5,0xcb,0x3a,0xf2,0x70,0x7f,0xfa,0x94,0xde,0x5b,0xc4,0xa1,0xf2,0xfa,0x7c,0xd1,0xb9,0xab,0xf3,0x7,0x51,0x7a,0x6f,0x2c,0x1c,0x67,0xae,0xf6,0xfc,0x1a,0xe4,0xb,0xaf,0xb3,0x9e,0xff,0x9e,0x53,0x58,0xc6,0x81,0x97,0x73,0x25,0xcb,0x7e,0x3d,0xb7,0xed,0xf8,0x5a,0xf6,0x19,0x5,0x79,0xcb,0xfd,0x18,0x5e,0x26,0x2a,0x8c,0xa5,0xe8,0xbd,0x4f,0xc8,0x5d,0x7c,0xe0,0xd9,0xf,0x56,0x38,0x77,0xc7,0xd5,0x5f,0x62,0x77,0xed,0x3d,0xcd,0x73,0xda,0x73,0x3e,0xe7,0x86,0xfd,0xff,0xd8,0x7b,0xb7,0xdf,0xcb,0xb6,0xec,0x3c,0xe8,0x9b,0x97,0xb5,0xf6,0xef,0x57,0xe7,0x9c,0xee,0xd3,0xa7,0x2f,0x6e,0xdf,0xfa,0x74,0xb7,0xfb,0xe2,0x6e,0xbb,0xdd,0xb6,0xe9,0xf8,0x46,0x12,0x62,0x90,0x23,0xe4,0xc8,0x8,0x11,0x4,0x42,0x11,0x3c,0xc0,0x13,0x20,0xf1,0x6f,0xf0,0xc8,0x63,0xc4,0x3,0x12,0xf,0x4,0x9,0x21,0x45,0x44,0x31,0xb2,0x1c,0x2,0x91,0xd,0xe,0xc4,0x8e,0x21,0x10,0xdb,0x89,0x1c,0xe3,0x76,0x1c,0x5f,0xbb,0xdb,0x7d,0x3d,0xa7,0xea,0xb7,0xf7,0x9a,0x73,0xe,0x1e,0xc6,0x65,0x8e,0xb9,0xf6,0xda,0x75,0xea,0x34,0xf6,0x29,0xb9,0x3c,0x87,0x54,0xaa,0xaa,0x7d,0x5d,0x97,0xbd,0xe6,0x5c,0xe3,0x9b,0xdf,0x25,0xb8,0x6b,0x91,0xf,0x4f,0x97,0xaf,0xdf,0xbd,0xf4,0x32,0x3e,0xf6,0x3d,0xff,0x12,0xde,0xf7,0xc1,0xef,0xc0,0x6f,0xfc,0xca,0x2f,0xe3,0x8f,0x7e,0xff,0xf3,0x73,0xb0,0x9c,0x35,0x6b,0xd6,0x55,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x66,0xcd,0x9a,0x35,0x6b,0xd6,0xac,0x3f,0x25,0x65,0x61,0xa,0x21,0x20,0xc4,0x4,0xa2,0x86,0xba,0x6d,0xa8,0xb5,0x58,0x30,0xc5,0xf5,0x9b,0x30,0x60,0x36,0xc7,0x30,0xf,0x5d,0x81,0x58,0x6f,0xf5,0x18,0x3d,0xc5,0xbf,0xc,0xe1,0xc6,0xff,0x8f,0x70,0x98,0x80,0xd1,0xcf,0xee,0x9b,0x94,0xf4,0x8e,0x8f,0xed,0x77,0xfe,0x29,0x20,0xd0,0xe1,0x27,0xdd,0x96,0x0,0x87,0x9d,0xe4,0xd4,0x7f,0x93,0xbd,0xce,0x85,0x9b,0xe8,0xe7,0xd0,0x2d,0xed,0xf4,0xe,0x7b,0xbb,0x61,0x63,0x67,0xe7,0x9d,0xe,0x19,0x92,0x6f,0xc1,0xf8,0xbc,0x79,0xdc,0x1c,0xb4,0x34,0xf8,0x3b,0x3e,0x8d,0xdd,0x78,0xb4,0x71,0x6f,0x97,0x1,0xf9,0xe,0xd6,0x5b,0x11,0x38,0xf,0xfe,0x7f,0xed,0x21,0xa9,0x8f,0x5f,0x13,0x65,0x47,0x92,0xe0,0x5e,0x7c,0xdc,0xf,0xf,0xd1,0xf1,0x97,0x76,0xb,0x46,0x3a,0xbc,0xde,0xdf,0x4e,0xd0,0xc7,0xcb,0xef,0x7e,0xd,0x9f,0xfe,0xdc,0x5f,0xc0,0xef,0xfd,0xd6,0xb7,0xe0,0x37,0x7f,0xf5,0x97,0x40,0xad,0xce,0x41,0x73,0xd6,0xac,0x59,0x56,0x13,0x0,0x9c,0x35,0x6b,0xd6,0xac,0x59,0xb3,0x66,0xcd,0x9a,0x35,0xeb,0x4f,0x49,0x69,0x10,0x4,0x11,0xa1,0x6e,0x17,0x5c,0x2e,0xe7,0x21,0x5,0xf6,0x9b,0x4a,0x5,0x1d,0x40,0xa6,0xe,0x60,0x90,0xf3,0x1c,0xe3,0x67,0x68,0x84,0x8c,0x42,0xe8,0x1,0x13,0xb2,0x5d,0xca,0x8e,0xf2,0xc9,0xaa,0x3e,0x64,0x62,0xf0,0xdd,0xd3,0x14,0x5a,0xc2,0x10,0xdc,0xa1,0x89,0xb9,0xde,0xf7,0x6f,0x0,0x42,0xe4,0xfb,0xae,0x3c,0x3,0xc9,0x5,0x31,0x80,0x2c,0xd1,0xd7,0x3,0x8c,0x21,0x6,0x50,0x23,0xf8,0xd0,0x88,0xc1,0x5f,0x50,0xf7,0x3,0x7b,0x43,0x3c,0x1c,0x90,0xe0,0x34,0xb9,0x96,0xc6,0x20,0xb,0x4d,0xb4,0xdd,0x85,0x38,0xc8,0x46,0x4a,0xf2,0xac,0xf,0x8d,0xe0,0x94,0x58,0x84,0x0,0x6a,0x9c,0xa0,0xab,0xaf,0x6f,0xad,0xb9,0xd7,0x11,0x62,0x8a,0x68,0xad,0x31,0xef,0xd1,0x7,0xa7,0xb8,0xd,0x23,0xc7,0x10,0xf4,0x20,0x16,0x7f,0xe6,0xfe,0x58,0x45,0x17,0xd8,0x11,0x2c,0xd5,0xf8,0xda,0xe7,0xaf,0xcb,0x8c,0xaf,0x7d,0x0,0x61,0xe7,0x5,0x37,0x65,0xc8,0xcf,0xfa,0x5b,0xc,0xbb,0xa0,0x8f,0xb7,0xba,0x20,0x70,0xad,0x8e,0x3d,0xf8,0x6a,0xc2,0x31,0xa0,0xf7,0xb4,0xf7,0x29,0xf7,0xce,0x7e,0x9b,0xa,0xa,0xfb,0x50,0x14,0x77,0x6e,0xf7,0xc0,0xf8,0x1e,0xbc,0xdb,0xff,0x16,0x86,0xe0,0x93,0xb7,0x7d,0xc9,0x1e,0xbf,0x97,0x5a,0x43,0xab,0x5,0xef,0xff,0xd6,0xf,0xe1,0x72,0x7e,0xc0,0xbf,0xf8,0xf5,0x7f,0x34,0x7,0xcd,0x59,0xb3,0x66,0x59,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x66,0xcd,0x9a,0x35,0x6b,0xd6,0xac,0x3f,0x25,0x15,0xd3,0x2,0xa2,0x86,0x56,0x2b,0xb6,0xcb,0x3,0xca,0xb6,0xa1,0x51,0x3,0xb5,0x26,0x60,0x57,0x38,0x4a,0x73,0x50,0xd4,0xc0,0xa3,0x77,0xd7,0xe0,0x81,0xa6,0xcc,0xa,0x60,0x17,0x63,0x42,0x6b,0x15,0x3e,0xa0,0x0,0x80,0x81,0x73,0xfa,0xd9,0x6,0x74,0x4,0x1,0xfe,0x94,0xa5,0x18,0xe3,0x0,0x3a,0xf1,0xe7,0xf5,0xe7,0x5b,0xa9,0x8,0x21,0xf2,0xfb,0x5,0xe8,0xe2,0x8f,0x1d,0x81,0x2d,0xdd,0x2f,0x53,0xbb,0x36,0xf5,0xf7,0x73,0xc2,0xd6,0x28,0xc0,0x98,0x3c,0xc0,0x20,0xd9,0x28,0x37,0x55,0x90,0xaf,0x9,0xc8,0x35,0x24,0xad,0xca,0xeb,0x20,0x0,0x9e,0x26,0xf3,0x2a,0xd0,0x42,0x8d,0x10,0x65,0x7f,0x42,0xc,0x68,0xb5,0x21,0xc4,0x60,0xc7,0x21,0x84,0x80,0xd6,0xaa,0x80,0x6e,0x11,0xb5,0x5c,0x10,0x62,0x1c,0xd2,0x7d,0x1,0x18,0x30,0x19,0x63,0x44,0x2d,0xa5,0x1f,0x8b,0x56,0x11,0x53,0x16,0x40,0x74,0xe3,0xef,0x68,0x2,0xc,0xa,0xc0,0x48,0xad,0x21,0xb5,0x8c,0xe6,0xce,0x13,0x51,0x93,0xe3,0xc1,0x7,0xc7,0x40,0x57,0xf9,0x4c,0x7e,0xac,0x83,0x9e,0x21,0x4,0xc4,0x98,0x50,0x8d,0x2d,0x4a,0x8,0x31,0x1,0xce,0x43,0x32,0xb8,0xd4,0xe1,0xe,0x46,0x92,0xcb,0xdb,0x78,0x8a,0x51,0xe1,0xfe,0x37,0x5,0x17,0x20,0x73,0xf5,0xfa,0xe,0x98,0xf6,0x73,0xe4,0xbf,0x63,0xa7,0x3b,0xdf,0x7b,0x1e,0xe,0x8f,0xf9,0x6f,0xf4,0xbf,0xd6,0xb7,0x62,0x46,0xbe,0x95,0x29,0xe5,0xb3,0xd4,0xb3,0xbe,0xf6,0x6d,0xfa,0x2e,0x1e,0xe9,0x9e,0x87,0xa7,0xaf,0x41,0x4d,0x6a,0xd,0xb5,0x16,0x94,0xb2,0xe1,0xa5,0x57,0xde,0x8d,0x69,0xf9,0x3f,0x6b,0xd6,0x2c,0x5f,0x13,0x0,0x9c,0x35,0x6b,0xd6,0xac,0x3f,0x13,0xd,0x63,0xc6,0xfb,0xbe,0xfd,0xa3,0x78,0xf7,0x6b,0xef,0x47,0xce,0xab,0xdd,0x10,0xa7,0x9c,0x51,0xb6,0xd,0xcb,0xba,0xa2,0xd6,0x2,0x80,0x1b,0x98,0x24,0x4d,0x8,0xb5,0x8a,0x10,0x13,0x62,0x8c,0x68,0xb5,0x5a,0x83,0xd5,0x6a,0x41,0x4c,0x69,0x60,0x4d,0xb4,0xd6,0x90,0x92,0x34,0x8b,0xd2,0x0,0x51,0xab,0x20,0x22,0xa4,0xbc,0xa0,0x96,0x2,0xa2,0x86,0x94,0x32,0x37,0x49,0xda,0x18,0x21,0xa0,0x96,0x6d,0xb8,0x89,0xe5,0xd7,0x6f,0x76,0x83,0x1b,0x53,0x6,0xb5,0x8a,0xd6,0xb8,0x19,0x1,0xf8,0x33,0xcb,0x76,0xb1,0xd7,0xb4,0x5a,0x70,0xb9,0x5c,0xd0,0xea,0x86,0x10,0x12,0x4a,0xb9,0x80,0x1a,0xf1,0x7e,0x11,0xd0,0xa8,0x4a,0x23,0x17,0xb0,0x2c,0xdc,0xfc,0xb4,0xca,0xd,0xe7,0xb2,0xae,0xb8,0x5c,0xce,0x88,0x1,0xa8,0xb5,0x22,0x49,0x83,0x5d,0x6b,0x43,0x8c,0x1,0x44,0x1,0x29,0x27,0xb4,0xb2,0x21,0xa6,0x5,0x79,0xc9,0x28,0x65,0x43,0x0,0xb0,0x6d,0x45,0xf6,0xbb,0x61,0x59,0x16,0xd4,0x5a,0x10,0x62,0x46,0x0,0x31,0x73,0x23,0x4,0xc4,0xc8,0xc7,0xa3,0x94,0xd,0xd4,0x1a,0xf2,0xb2,0x1a,0xe3,0xa3,0x96,0xd,0x31,0x66,0x94,0xed,0x8c,0x65,0x3d,0x81,0x49,0x21,0xcd,0x7c,0xbd,0xb6,0xf3,0x3,0x96,0xd3,0x3d,0x6a,0x2d,0xa8,0xdb,0x5,0xeb,0xe9,0x1e,0xb5,0x6e,0x48,0x79,0x91,0x63,0x42,0xc8,0x4b,0xe6,0xed,0x88,0x91,0x1b,0xaa,0xb6,0x21,0xa6,0x15,0xdb,0x76,0xc1,0xb2,0x2c,0xd6,0x44,0x12,0x15,0xc4,0x98,0xe5,0x1c,0x45,0x40,0x9b,0x60,0x69,0xbc,0x94,0x95,0x52,0x6b,0xe1,0xe3,0x1e,0x93,0x3d,0xc7,0xc7,0x81,0x8f,0x35,0x11,0xa1,0xb5,0xc2,0x4d,0x64,0xd9,0x90,0x97,0x95,0x9b,0xd9,0x5a,0x80,0x10,0xf9,0x1c,0x97,0xd,0x4d,0x1a,0xd4,0xba,0x5d,0x90,0x72,0xb6,0xdf,0x41,0x4c,0xdc,0x6c,0x42,0xf6,0x5f,0xc5,0x74,0x29,0x25,0x10,0x1,0xb5,0x36,0x24,0x65,0xb9,0xc8,0x6f,0x64,0xdb,0xce,0x48,0x31,0x21,0xe6,0x85,0xdf,0xeb,0x7e,0x2b,0x65,0xbb,0xd8,0x6f,0x8b,0xa8,0xa1,0x94,0x2a,0xfb,0x4d,0xf2,0x78,0x92,0xdf,0x6d,0xb5,0xe6,0x38,0x2f,0xb,0x42,0xcc,0xd8,0xce,0x8f,0xb9,0x19,0x4f,0x99,0x7f,0xe7,0xad,0xb9,0x6b,0x80,0xff,0x4d,0x8d,0x70,0x7e,0x78,0x13,0x97,0xc7,0x6f,0xa0,0x96,0xf3,0x1c,0x50,0x66,0x3d,0xd7,0xea,0x69,0xb5,0x64,0xd7,0xa3,0x67,0xfe,0x19,0x90,0x46,0x34,0xc0,0x20,0x10,0x80,0x2a,0x6,0x61,0x9f,0x5,0xc7,0x54,0x53,0x0,0xc6,0x31,0xbf,0x5a,0x13,0x60,0x29,0x46,0x6,0x6,0xa9,0x83,0x57,0x96,0x53,0x20,0xec,0x3a,0xfe,0x3c,0x58,0x88,0x47,0x10,0x70,0x2b,0xda,0xe7,0x31,0xc8,0xd6,0x4,0xa4,0x6c,0x3,0x33,0xae,0x81,0x9a,0x8e,0xf5,0x3c,0xbe,0x53,0x23,0xfb,0x7f,0x13,0x26,0x21,0x5f,0x8f,0xd,0x31,0x65,0x0,0x4d,0xc6,0xa3,0x86,0x90,0x32,0x83,0x9f,0xb5,0x22,0xa6,0x84,0x5a,0xb,0xa2,0x99,0xe7,0x29,0x28,0xc2,0x63,0x9e,0x67,0x72,0x5,0x4,0x50,0x0,0xa2,0xcc,0x5f,0x1,0xcc,0xbe,0x53,0x26,0x5e,0x90,0x63,0x19,0x52,0x2,0x55,0x6,0xfd,0x14,0x58,0xcc,0x31,0x3b,0xc6,0x1f,0x80,0xd6,0xcc,0x72,0x91,0x88,0x40,0xa8,0x48,0x39,0xf1,0x71,0x21,0x92,0xed,0x4e,0x9d,0x5d,0x48,0xc4,0xe0,0x5f,0x54,0xb0,0xb0,0x20,0xa5,0x6c,0xc,0x40,0x3e,0x64,0x81,0xc7,0xbc,0x94,0x50,0x36,0x99,0x23,0x5,0x40,0x85,0xb,0xd1,0x20,0x63,0x14,0x36,0x19,0xd6,0xab,0x3b,0x9f,0xd1,0x31,0x7,0x93,0x49,0xc4,0x6b,0x2d,0x76,0xde,0xf9,0xf7,0xd3,0x1c,0x70,0x1b,0x40,0x81,0x8c,0xc1,0xc9,0xaf,0xd,0x1d,0x8f,0x82,0x67,0xb0,0x29,0x8,0x25,0xbf,0x11,0xf,0x3a,0x37,0x39,0x66,0x44,0x2e,0x88,0x85,0x6e,0x82,0x6f,0xfc,0xbb,0xd,0xd7,0x6c,0x54,0x3a,0x6,0xec,0x74,0xdb,0x83,0xf8,0xe,0xee,0x99,0xaf,0x6,0x16,0x3b,0x0,0x3a,0xb8,0xed,0x3b,0x62,0xca,0x6,0x7,0x58,0x12,0xda,0xdb,0x80,0xf3,0x9e,0x15,0x60,0xfb,0x26,0x80,0xb8,0xb7,0x2,0x58,0x77,0xcf,0xf3,0x71,0xe9,0xbf,0xc5,0xb7,0x2b,0x21,0x9e,0x35,0x6b,0xd6,0x4,0x0,0x67,0xcd,0x9a,0x35,0x6b,0xd6,0x9f,0xe2,0xfa,0x96,0xf,0x7d,0x2,0x1f,0xfe,0xee,0xcf,0xe2,0xe5,0x57,0x5e,0x1d,0xbb,0x47,0xf8,0x74,0xb9,0xeb,0x1b,0xc9,0x2b,0xfb,0xf8,0x41,0x5a,0x75,0xfd,0xaa,0xe1,0xfe,0x56,0x57,0xef,0xbd,0xf9,0x7b,0x38,0xbe,0x91,0xbd,0x65,0x89,0xc4,0xef,0x4f,0x0,0x5a,0x4f,0x86,0x54,0xa6,0x0,0xbc,0xf1,0x39,0x83,0x3c,0xa,0x4e,0x1,0xcd,0x40,0xca,0x94,0x57,0x94,0xed,0xc2,0x60,0x65,0x88,0xa8,0x75,0x63,0x36,0x83,0xb2,0x2a,0x2,0xac,0x21,0x52,0x96,0x3,0x33,0x25,0xda,0x98,0x56,0x88,0x80,0xd6,0x8a,0x1,0x83,0x44,0xa,0x2c,0x2d,0xc6,0x40,0x20,0x62,0xb0,0x94,0x9a,0x32,0x26,0xfa,0xeb,0x82,0xb0,0x32,0xbc,0xc4,0xcc,0x4b,0xbc,0xba,0xf,0x50,0x30,0xb9,0x17,0xc0,0xc0,0xa1,0x82,0x60,0x5d,0x6,0x16,0xc5,0xb3,0xbc,0x33,0x66,0x18,0xac,0xb,0x6e,0x9b,0x93,0x34,0x6d,0x10,0x9f,0xf7,0x24,0xdf,0x21,0x5c,0x17,0xea,0xc2,0x21,0x6e,0x4a,0x45,0x9a,0x47,0xd5,0xbe,0xa3,0xff,0x1e,0xb4,0xc1,0x62,0xc3,0x7d,0x3,0x86,0x83,0x7f,0x4c,0xfd,0xc8,0x2,0xa8,0x36,0x34,0x22,0xc4,0x10,0x1c,0xa0,0xc0,0xfb,0x50,0x6b,0x35,0x0,0xd7,0x4b,0xa0,0x62,0x12,0x26,0x8c,0x80,0xc2,0xfd,0x18,0xf0,0xb1,0x8d,0x29,0xa3,0x69,0xc3,0xaa,0x0,0x84,0x42,0x20,0xa,0x6e,0x9a,0xec,0x2e,0xa0,0x19,0xd3,0x25,0xe,0x66,0xed,0x24,0x8d,0xa8,0x36,0xfc,0x57,0xec,0x25,0x61,0xc2,0xf4,0xd7,0xc2,0x3e,0xe7,0xf2,0xf0,0x4,0x5f,0xff,0xca,0x17,0xf1,0x85,0xdf,0xfb,0xe7,0x78,0xe3,0xcb,0x7f,0x30,0x1b,0xaa,0x59,0xcf,0xad,0x6a,0x29,0x37,0x50,0x8,0x1a,0x25,0xb0,0x16,0x1e,0x20,0x63,0xa6,0x80,0x5c,0x8d,0x1c,0xab,0xc,0x30,0x20,0x4b,0xaf,0x3d,0x65,0xe3,0x45,0xbb,0x7e,0xfc,0x75,0x58,0xfb,0xf4,0xe1,0x40,0x1d,0xbb,0x6,0x65,0xbc,0x50,0xa0,0x5f,0x1,0xc7,0xd6,0x1a,0x10,0xa3,0x8d,0x85,0x2a,0x94,0x54,0xf6,0x5c,0x6b,0x15,0x29,0xf6,0x71,0x5a,0x25,0xce,0xd4,0x1a,0x7f,0x77,0x4c,0xa8,0xd4,0xc,0xb4,0x52,0xef,0x43,0x5e,0x84,0x6a,0x26,0x25,0xd6,0xed,0xf3,0x12,0x4d,0x1b,0xab,0x88,0x43,0x2f,0xa2,0xb0,0xe1,0xec,0xf8,0x50,0x7f,0x7d,0x8c,0x89,0xd9,0x75,0x4d,0xc7,0x34,0x5e,0xfc,0xd2,0xc7,0xa3,0x1b,0xa3,0xc2,0x2e,0xb5,0x41,0x1,0x2c,0x5,0xa,0x41,0xc,0x16,0xa6,0x9c,0x65,0xcc,0x91,0xcf,0xa9,0x15,0x21,0x25,0x6,0x6,0x6b,0x45,0x88,0x3a,0x36,0x93,0x9b,0x23,0x79,0x9c,0x6d,0x32,0xd6,0xf1,0x76,0xc8,0xe2,0x89,0x5,0xb5,0xc8,0xb1,0x17,0xe0,0x52,0x65,0xd7,0x0,0x64,0x81,0xa8,0xd,0xa0,0x6c,0xab,0xfa,0xbb,0xd1,0x71,0xbb,0xd9,0x67,0xeb,0x18,0x4f,0xd4,0x58,0x62,0xac,0xe7,0x99,0xc6,0xfb,0x83,0xdb,0x12,0xda,0xf1,0x3e,0xa1,0xff,0x46,0x46,0x20,0xab,0x33,0x42,0xaf,0xdf,0x1a,0xb0,0xf3,0x97,0xa4,0x6b,0xe9,0xed,0x8,0x84,0x7,0x77,0x2b,0x73,0x2c,0xa9,0x3d,0x2,0xc7,0x46,0x70,0x7c,0xf7,0xfa,0x7e,0xf4,0x9f,0x9,0xcc,0xa3,0xb7,0xe5,0xb9,0xf8,0xb6,0x91,0x3f,0xbc,0xa5,0xa7,0xe3,0x4d,0x86,0x60,0x7,0x5d,0xe7,0x5c,0x35,0x6b,0xd6,0xac,0x9,0x0,0xce,0x9a,0x35,0x6b,0xd6,0x9f,0x91,0xfa,0xe8,0xf7,0xfe,0x30,0x3e,0xf6,0xbd,0x9f,0x63,0x66,0xc1,0x4d,0xf3,0xf3,0xa7,0x3d,0xd6,0xef,0xe4,0x8f,0x4c,0xcc,0x3b,0x2b,0x40,0x41,0x18,0x38,0x76,0x56,0xff,0xc,0x63,0x15,0x98,0xb7,0x12,0xae,0x9d,0xb4,0x7d,0x7c,0xe3,0xee,0xa6,0x56,0x19,0xe,0xf0,0xef,0x87,0xbf,0x8f,0xef,0xb7,0xed,0x31,0xa,0x7b,0xd1,0x18,0x7f,0xa,0x68,0x35,0xf3,0x5c,0x52,0xe0,0xca,0x64,0x67,0xe,0x14,0x1d,0x3d,0xa0,0x9a,0x61,0xa4,0x2a,0xc7,0x52,0x49,0x5c,0xb0,0x4,0x4a,0x98,0x54,0x4c,0x1b,0x1c,0xf5,0x67,0x32,0x0,0xcc,0x18,0x2c,0xbd,0xe9,0x8c,0x31,0xe,0xdf,0xad,0x2c,0x1e,0xee,0x87,0xe3,0x6e,0xe5,0xbe,0x1f,0x17,0x65,0xb0,0xd,0x82,0x32,0x65,0xeb,0x11,0x71,0x93,0x1a,0x22,0x42,0x4c,0xd6,0xf0,0x59,0xd3,0xa5,0x9f,0xa5,0x0,0x1a,0x5d,0x27,0x84,0x76,0x9,0xa0,0x80,0x8c,0xde,0xdf,0x4b,0xd9,0x3d,0xba,0xbd,0x72,0x1c,0xf7,0x20,0xda,0x61,0x82,0xa8,0x3,0x6f,0xc9,0x98,0x87,0xfa,0x7e,0x98,0xec,0x4f,0x65,0x75,0x57,0x0,0xb2,0x6d,0x9b,0xdf,0x86,0x86,0x10,0xb3,0x0,0x1,0x70,0x72,0x30,0xd8,0xf9,0x3,0xe2,0xe0,0x69,0x15,0x82,0x6f,0x2e,0xfb,0xef,0xa0,0xcb,0x1c,0x47,0x0,0x45,0xff,0xde,0xee,0x1e,0x61,0x59,0x4f,0xc8,0xcb,0x9,0xbf,0xd3,0x1a,0xde,0xfc,0xca,0x1f,0xce,0x1,0x66,0xd6,0x73,0x29,0x2f,0xc9,0x55,0xf0,0x5e,0xa2,0x7c,0x87,0x71,0x9b,0xaf,0x23,0x18,0x40,0x86,0xd0,0xc7,0x30,0x1e,0x93,0xe4,0xfa,0x46,0x40,0x3,0xd,0xe3,0x54,0x97,0xd7,0x6,0xbb,0x56,0xfd,0x82,0x43,0x4f,0x47,0xe5,0x5,0x7,0x46,0xbb,0x78,0xac,0xb1,0xeb,0x47,0xd9,0x86,0x6e,0x6c,0x1d,0xc6,0xb8,0x46,0xcc,0x4,0x74,0x0,0x4f,0xab,0xc5,0x0,0xa9,0x2a,0xac,0x6f,0x4d,0xba,0x55,0x96,0x59,0x8,0x30,0x96,0xee,0x0,0x54,0x51,0x97,0x19,0x93,0x24,0x12,0xf7,0x5,0x2b,0x81,0x97,0x64,0xcc,0x55,0xb6,0x9a,0x8e,0x9d,0x9a,0xd0,0xab,0xe3,0x64,0x4c,0x72,0x8c,0x10,0x41,0x2,0x9a,0x2,0xcc,0x10,0xef,0xc1,0xb0,0xc1,0xac,0xea,0x18,0x38,0xcb,0xe3,0xfb,0x3d,0x60,0x46,0xc4,0xac,0x62,0x1,0x4,0x3b,0x18,0xc7,0x2c,0xbd,0x98,0x33,0xb3,0xd7,0x65,0x5b,0x94,0x7d,0xad,0xbb,0xc6,0xec,0x64,0x3e,0x5f,0x39,0x2f,0x68,0xc2,0xd2,0xe,0x29,0xca,0xb1,0x58,0x8c,0xad,0xcc,0x8b,0x2c,0x1d,0x34,0x44,0x10,0xc0,0x35,0x44,0xf9,0xed,0xb8,0xc5,0xf,0x99,0x27,0x42,0xea,0x8b,0x57,0xf6,0x1b,0x1,0x81,0x4,0xac,0xb4,0x45,0x33,0x99,0x6f,0x74,0x5c,0x24,0xea,0x9,0xc7,0x57,0x46,0x7c,0x44,0xe3,0x5c,0xee,0x41,0x69,0xda,0xf9,0xe8,0x39,0x38,0xce,0xcb,0x81,0x3d,0xa0,0xb5,0x67,0xb2,0x11,0x5d,0x3,0x5c,0xbb,0x99,0xf1,0x1a,0x23,0x3f,0x80,0xc9,0xbe,0xf9,0xa,0xdf,0x4,0x30,0xf7,0x76,0x80,0xbf,0xb7,0x90,0x30,0xf,0xdf,0xe1,0xe6,0x49,0x8c,0xcc,0x5f,0x66,0x87,0xce,0x20,0x90,0x59,0xb3,0x66,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x5e,0xe8,0xfa,0xe4,0xf,0xfe,0x45,0x7c,0xfc,0x7b,0x3f,0x27,0xec,0x2f,0x74,0x0,0xc6,0x9a,0x30,0x7,0xbe,0x18,0x47,0xc4,0x1b,0xbd,0x87,0xe1,0x1e,0x77,0xf4,0x71,0x77,0x3e,0x3c,0xde,0x3c,0x1d,0x7e,0xa5,0x7e,0x7,0x2c,0x12,0x1,0x61,0x71,0xe0,0x4a,0x73,0x51,0x89,0xcc,0x6a,0x53,0xb9,0x59,0x6b,0xd5,0xbd,0xae,0xdf,0x14,0xc7,0xb0,0x18,0x19,0x50,0x1,0x1c,0xf5,0x7c,0xa,0xfb,0xe6,0x2,0x79,0x20,0x39,0x92,0x4b,0xdb,0xd3,0xf7,0x7a,0x56,0x98,0xbf,0xd9,0x8e,0x71,0xe5,0xc6,0xd2,0x35,0x21,0x2c,0x2d,0xab,0x0,0x8,0x59,0xf6,0xc3,0xfb,0x50,0xf5,0xa6,0xaf,0x59,0x33,0xa4,0xf2,0x37,0x6d,0xc4,0xb8,0xb9,0xd6,0x66,0x26,0x76,0x40,0xcb,0xb6,0x6b,0xdc,0x56,0x6b,0x7c,0x0,0x34,0x69,0x20,0x5b,0x6b,0xee,0x7d,0x18,0x99,0x84,0x1e,0xe0,0x2,0x4b,0x83,0x61,0xe7,0x7,0xe6,0x1,0xa5,0xe7,0x52,0x19,0x3d,0xbd,0x51,0x15,0x66,0x8d,0x0,0xc,0xea,0xf3,0x15,0x7,0x1f,0xaf,0xe0,0xe4,0x67,0x64,0x4d,0x7d,0x73,0x92,0xb0,0xce,0xe2,0xb,0xc6,0xcc,0x19,0x98,0x23,0xd6,0xe0,0x85,0x41,0x36,0x16,0x42,0x40,0x4b,0x5e,0x36,0x16,0x44,0x2a,0x1c,0x84,0x5,0xd4,0x8f,0x5f,0x7,0xf0,0x46,0x89,0xd7,0x60,0xca,0xef,0xc0,0x5f,0x3d,0xb2,0x4d,0xce,0x99,0x81,0x0,0xfa,0x5b,0x8,0xc1,0x8c,0xf0,0xf5,0x33,0x19,0x4,0xa8,0x26,0xa1,0x6e,0xb5,0xe0,0xfe,0xa5,0x57,0xf0,0xf2,0xbb,0x5e,0xc5,0xe3,0xaf,0x7d,0x69,0x36,0x55,0xb3,0x9e,0x4b,0xa5,0xbc,0x74,0xa0,0x4,0x1d,0x2b,0x8,0x2e,0xb4,0x60,0xb8,0x5c,0xe3,0x78,0x3d,0xe8,0x98,0xc7,0x8b,0x18,0x40,0x55,0xc9,0xbb,0xc8,0xdf,0xa3,0x63,0xd8,0x76,0x50,0xa1,0x93,0xae,0x3,0x7a,0xa,0x71,0x55,0xcf,0xbd,0x3e,0x30,0x33,0x8,0xa8,0x8b,0x7,0x31,0x2,0xad,0x21,0xe6,0x6c,0x92,0x57,0xbe,0x1c,0x85,0xa9,0x26,0x40,0x53,0xad,0x5,0x11,0xa,0xc8,0x2b,0x8,0x16,0x8d,0xfd,0x65,0xcc,0x44,0x19,0x27,0x75,0x7b,0x21,0xfb,0x41,0x80,0xcd,0x75,0xc1,0xc0,0xa6,0x3e,0x27,0xf0,0xb5,0xec,0x81,0x23,0x9,0x2f,0x41,0xd8,0x1,0x49,0x1e,0xbc,0x8b,0x6e,0xc,0x96,0xb1,0x26,0x50,0x67,0x9,0xa2,0x3,0x81,0x31,0xad,0xe2,0xf9,0xc7,0xdb,0x50,0xcb,0x66,0xf6,0x19,0x2a,0xcf,0x8e,0x32,0x57,0xd8,0xdc,0x12,0x22,0x3f,0x26,0xd2,0x5d,0x65,0x65,0xe6,0xe5,0x24,0xf6,0x1b,0x6c,0x1b,0xb1,0x2c,0xab,0x58,0x6c,0x64,0x80,0x8,0x65,0x3b,0xdb,0xf8,0x59,0xb6,0xb,0x52,0x5e,0xd0,0x6a,0xe5,0xbf,0xc1,0xc0,0x62,0xab,0xd5,0x18,0x87,0x3d,0x34,0xa6,0x4b,0x7c,0xfd,0x62,0x92,0xb2,0x5,0x75,0x2e,0x49,0x31,0x89,0x25,0x88,0xcc,0x11,0xb6,0x80,0xc2,0xe3,0xa0,0x2,0xcb,0x3c,0x5f,0x74,0x60,0xf8,0x1a,0x1f,0xb,0x6,0xc4,0xee,0x13,0x6e,0xf7,0x52,0xdc,0x2e,0x7,0xc7,0x30,0x97,0xd,0x40,0xe1,0x53,0x98,0x6c,0x47,0x32,0x57,0xcf,0xee,0x7b,0xc7,0x39,0x70,0xe1,0x19,0xc0,0xc1,0xc3,0x45,0xd0,0xfd,0x4d,0x97,0x5e,0x5b,0x74,0x2d,0x97,0x8,0xe,0xd6,0x3c,0x78,0xcd,0xa0,0xa6,0x98,0x35,0x6b,0xd6,0xac,0x9,0x0,0xce,0x9a,0x35,0x6b,0xd6,0x8b,0x5b,0xdf,0xf3,0x43,0xff,0x1a,0x3e,0xfa,0xe9,0x1f,0x90,0x7b,0xbf,0x76,0x7d,0xf3,0xc9,0xe8,0x95,0xdd,0x47,0xe,0xb2,0x17,0x6d,0x86,0xc2,0xfe,0x2e,0x12,0x8e,0x41,0x27,0xec,0x2a,0x12,0x9f,0x9c,0xd0,0x8d,0xbc,0xc9,0x68,0x82,0xda,0x32,0xb6,0xdd,0x2a,0x35,0x39,0x92,0xa0,0xde,0xd8,0x37,0x98,0x85,0x54,0xeb,0xdb,0x65,0x4d,0x86,0x74,0xb8,0x4d,0x98,0x5e,0xcd,0x40,0x9a,0xda,0xb7,0x6b,0x67,0x8,0xef,0x6f,0x83,0x8d,0xa1,0xe7,0xf6,0x9f,0xc4,0xab,0x50,0x7b,0xc1,0x18,0x3b,0x8b,0xa1,0x37,0x34,0xfd,0xa6,0xbc,0xd5,0x6a,0x9e,0x79,0xe4,0x64,0xba,0x26,0x3d,0x35,0x69,0x18,0x99,0xcc,0x8e,0xa0,0xd,0x5f,0x19,0xf6,0x8d,0x77,0xab,0xe,0x60,0x68,0xf3,0x5e,0x5c,0xda,0xcd,0xbb,0x66,0x20,0x4,0x38,0xd6,0x48,0xf7,0x5e,0xd2,0xfd,0xf0,0x7,0x4d,0xe5,0xab,0x1,0x30,0x53,0x7a,0x72,0x7e,0x40,0x7a,0xd8,0x9b,0xf8,0x3e,0xaa,0xec,0x59,0xa8,0x35,0x6,0x18,0x6a,0xeb,0xdf,0x6,0xa0,0x8b,0x9b,0x61,0x6e,0xe4,0x3b,0x6b,0x28,0xa,0xe3,0x87,0x81,0xe5,0xd0,0xa5,0xca,0x80,0x3,0x65,0xdd,0x19,0x12,0xf,0xc0,0x7e,0x4e,0x94,0x49,0x54,0xba,0xa4,0xd8,0x31,0x2a,0x55,0xe6,0xe5,0x25,0x8e,0xfe,0x97,0xdb,0x1f,0xdb,0x3,0x8e,0xbe,0x91,0xf,0x8,0xa1,0xda,0xfe,0x72,0x43,0xde,0x3,0xf,0x18,0xc,0xa8,0x26,0x99,0x56,0xa9,0xb6,0x26,0x89,0xe6,0x65,0xc5,0xe9,0xee,0x1e,0xf7,0x2f,0xbd,0x6b,0xca,0xaa,0x66,0x3d,0xb7,0x22,0xc7,0x0,0xb6,0x20,0xb,0x7,0xc8,0x77,0xa9,0x7b,0x4f,0x77,0xf5,0x29,0xbb,0x8,0x18,0x3c,0xf2,0x7c,0x60,0x47,0xd0,0x64,0x5a,0x1,0x87,0xec,0x39,0x79,0x8c,0x6a,0x5,0x62,0x30,0x90,0xcd,0x3e,0xc7,0xc9,0x88,0x75,0xd4,0x8d,0xc2,0x6,0x54,0xf6,0x38,0x7b,0x80,0x5e,0x0,0x4,0x3,0xd9,0x6a,0x2b,0x8,0x60,0xaf,0x3b,0x88,0xb7,0x60,0x8,0xec,0xb,0x9b,0xf2,0x8a,0x80,0xc6,0xd6,0x1,0xe2,0x5,0xa8,0x8b,0x20,0xb6,0xdd,0x21,0x19,0xdb,0x50,0x17,0x64,0x20,0xb,0x2e,0x4,0xd8,0x31,0x50,0x40,0x4e,0x81,0x96,0x6e,0x3,0x80,0xc1,0xde,0x82,0xc7,0xff,0x2e,0x9d,0x6e,0xad,0x21,0x2f,0x8b,0xd8,0x42,0x50,0x97,0x33,0xcb,0x7e,0x26,0x61,0x84,0xb3,0x8f,0x6d,0xec,0xfb,0xdc,0xfc,0xb1,0x70,0x56,0xb,0xf0,0x40,0x69,0x5f,0x20,0xd2,0x5,0x87,0x5a,0xab,0x78,0xdb,0x12,0x96,0x74,0x42,0x4a,0xb,0x8a,0x4,0x85,0xe8,0x62,0x53,0x4c,0x59,0xd8,0xd2,0xc,0xfa,0x31,0x88,0x27,0x4c,0x68,0xfd,0xfe,0x5a,0xb1,0xac,0x27,0xfe,0x2c,0x4b,0x55,0x1e,0xfd,0x20,0x6d,0x1,0x4b,0xc7,0xfc,0x18,0x7,0x7f,0x3f,0x3f,0x96,0xf2,0xb9,0xa5,0xee,0xb,0x19,0x1c,0xa3,0xd3,0x2d,0xac,0x19,0xb0,0xe5,0x58,0xdd,0x7b,0xa0,0xce,0xe6,0x83,0x61,0x82,0x80,0xb,0x7f,0xa1,0x9b,0xc0,0x5e,0x70,0xa0,0x22,0xed,0xae,0x89,0xe3,0x99,0xff,0xb9,0x5e,0xa8,0xbb,0xb0,0x1d,0xb7,0x80,0x6,0x1a,0xe4,0xf5,0x57,0x60,0x9e,0xbf,0x39,0x1b,0x57,0x7,0xdd,0x6b,0xe8,0xf8,0xeb,0xb0,0xbb,0xd7,0x99,0x1,0x20,0xb3,0x66,0xcd,0x9a,0x0,0xe0,0xac,0x59,0xb3,0x66,0xbd,0xb8,0xf5,0x99,0x1f,0xfd,0xcb,0xf8,0xf0,0x27,0x3e,0xc3,0xc9,0x90,0x6a,0x6,0xee,0x8d,0xb4,0xf7,0x37,0x95,0xd8,0x3d,0x7e,0xeb,0xdf,0x47,0x37,0xa1,0x4f,0x53,0xd,0x1f,0xdf,0x11,0x8f,0xc0,0x9f,0xbf,0x29,0xf6,0xe0,0xd0,0x10,0x5,0xb8,0x7f,0xdd,0xf8,0x1e,0xda,0x35,0x5,0xa3,0x89,0x38,0xd,0xdf,0xa5,0xcd,0x70,0x97,0x13,0xfb,0x97,0x8d,0xec,0x47,0x72,0xfe,0x88,0x3e,0x11,0x31,0xec,0x7c,0xef,0x8e,0x3c,0xb7,0x82,0x93,0x33,0x7b,0x96,0x1c,0xd1,0x75,0x13,0x74,0xdd,0x1c,0x8d,0xaf,0x1b,0x65,0x4c,0x61,0xe7,0x1b,0x38,0xbc,0xf9,0xea,0x10,0x36,0x4b,0x86,0x54,0xf0,0x2b,0xb8,0x7d,0xc0,0x28,0x7b,0x73,0xd2,0xeb,0x10,0x8e,0xb6,0x2d,0x8e,0x12,0xee,0x81,0xdd,0xc9,0x80,0xb1,0x2,0x0,0x24,0x0,0x6b,0x4f,0xfc,0x1c,0x3e,0xa9,0x4b,0xc6,0x87,0xc6,0xe,0x0,0xce,0xce,0xc3,0xf,0x96,0x6a,0xd9,0xbf,0x97,0x9c,0xbf,0xa2,0x82,0x7b,0xc1,0x2,0x4d,0x7a,0xcf,0xd3,0x65,0xd6,0x6,0x16,0xec,0x18,0x26,0x61,0xc7,0x62,0xa4,0x41,0x3a,0xbc,0x39,0x50,0x31,0x3a,0x56,0x27,0x37,0xda,0x1c,0xdc,0x92,0x2c,0x44,0x66,0xd6,0xac,0x77,0xb2,0x7c,0x50,0x87,0x62,0x7,0xc,0xe4,0xf4,0x6b,0x55,0x41,0x31,0xbb,0x52,0x9d,0x27,0x27,0x1c,0xd8,0x34,0x48,0x39,0x1d,0xd8,0xa3,0xd7,0xf,0xb5,0x9e,0xc,0xab,0xc0,0x97,0xbe,0xa7,0x95,0x22,0xaf,0xa9,0x12,0xa4,0xd3,0x53,0x6d,0xfd,0x18,0xa7,0xb6,0x9,0x31,0x46,0x63,0x99,0x75,0x19,0x69,0x97,0xd,0xeb,0xb8,0xd0,0x5a,0xe3,0x40,0x24,0xf9,0xee,0xbc,0xac,0xec,0xb,0xa8,0xb,0x3,0xe,0xf4,0xe1,0xb0,0x11,0xe,0x22,0x32,0x79,0x6f,0x6b,0xcc,0x86,0x93,0xed,0x52,0x6,0x35,0x9c,0xb4,0x59,0xc7,0x77,0x5,0xf5,0xd4,0xeb,0xcf,0xc6,0x48,0x91,0x21,0xc7,0xd8,0xc3,0x2d,0x62,0xc,0xa8,0x85,0x17,0x10,0x94,0x9d,0xd8,0xa8,0x1a,0x5b,0x91,0x81,0xcb,0x62,0x20,0x60,0x7,0x9,0xa3,0x30,0xb7,0xf9,0x64,0xe5,0xc4,0x21,0x52,0x7d,0x9f,0x93,0xd9,0x3a,0xa4,0x94,0x81,0xa4,0xc1,0x57,0x1c,0x42,0xa5,0x27,0x36,0x3a,0x26,0xa7,0x32,0xff,0xfa,0x18,0x45,0xdd,0x33,0xd1,0x0,0x5c,0x60,0x59,0xef,0x50,0x36,0x4e,0x23,0xce,0x81,0x65,0xd5,0x41,0xce,0xa5,0x8d,0xa5,0x2,0x94,0xf6,0x85,0x98,0x38,0x8e,0x7b,0xe4,0x7e,0x43,0xe2,0xd9,0xaa,0x2c,0x46,0xde,0xc6,0x38,0x58,0x2a,0xa8,0x1a,0x7d,0xf,0xdc,0x79,0xb5,0xc0,0xd5,0x7c,0x39,0x48,0x89,0x71,0x73,0x7e,0x24,0x7a,0x4e,0x8c,0xbe,0x67,0x6,0xfc,0xc2,0xe,0xe8,0xdb,0x23,0x7a,0x80,0xb7,0xbd,0x80,0xbb,0x53,0xb8,0xda,0x31,0x7b,0xd,0xe1,0xd6,0x4e,0xd3,0xad,0xed,0x50,0x90,0x57,0xaf,0xbf,0x5a,0xe6,0xc0,0x39,0x6b,0xd6,0xac,0x9,0x0,0xce,0x9a,0x35,0x6b,0xd6,0x8b,0x56,0xaf,0x7f,0xf7,0xf,0xe2,0x3b,0x3e,0xfa,0xdd,0x78,0x78,0xf2,0xa6,0xa5,0x2d,0xd2,0x5e,0x13,0xe2,0x40,0xad,0x6b,0x49,0xce,0x68,0xec,0xbe,0x7,0x95,0xec,0x26,0xbc,0xed,0x41,0xaf,0xce,0x94,0xf3,0xb2,0xce,0x51,0xe2,0xe9,0xa4,0xbf,0x61,0x94,0x10,0xa9,0x87,0x12,0x9c,0xb4,0xcc,0x3,0x76,0x1d,0xd7,0xdb,0xcb,0x7c,0x46,0x90,0xc6,0x3,0x41,0x43,0xe3,0xeb,0xc0,0x9d,0x4e,0x50,0xa0,0xc1,0xc4,0x7d,0xaf,0xca,0x19,0x5c,0x11,0x77,0x6c,0x85,0x2e,0x97,0xa6,0xee,0x3b,0xb7,0x6f,0x4c,0x9d,0x3f,0x94,0x6d,0xa7,0xa4,0xec,0x6,0x77,0xe3,0x8f,0x41,0x5,0xd4,0xd9,0x14,0x9d,0x5d,0xb8,0x7,0x3f,0x47,0xd5,0xd0,0xe8,0x8d,0x14,0x6e,0x2,0xa5,0x83,0x77,0xdf,0xd8,0x56,0x3d,0xad,0x95,0x70,0xe0,0x22,0x5d,0xfd,0x16,0xcc,0x3c,0x7f,0xe7,0xb,0x35,0x2,0x9c,0xc1,0x7d,0x44,0x97,0x9d,0xed,0x1b,0xbc,0xe1,0xf8,0x5e,0xb1,0x1b,0xc2,0x70,0x8c,0xae,0x1,0xbb,0x7e,0x66,0x6e,0x81,0xab,0xdf,0x5c,0x23,0xd7,0xbf,0x93,0x5a,0x43,0xad,0x5,0x65,0xbb,0x60,0x3d,0xdd,0xcd,0x8e,0xb5,0xef,0x8f,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xc1,0x66,0xd6,0x73,0xab,0xed,0xe1,0xb1,0x13,0xe6,0x52,0xf,0x40,0x72,0x9e,0xa6,0x96,0x66,0xeb,0xd2,0x77,0x19,0xb8,0x69,0x3d,0xd,0x96,0xc8,0x58,0x70,0xc1,0xd,0x44,0x3a,0xa6,0x35,0x61,0xde,0x41,0x59,0xbe,0x26,0xf7,0xe4,0xd9,0x23,0x26,0x66,0xfb,0xc6,0xc8,0xed,0x4,0xed,0x1,0x42,0x8c,0xe1,0x3f,0x9e,0x59,0x17,0xa0,0x52,0x58,0x7f,0xd1,0x8b,0x75,0x82,0xf3,0x11,0x34,0x40,0x8e,0x69,0x8b,0x43,0x90,0x10,0x4,0x78,0x52,0x9,0xac,0x32,0x98,0x31,0xf8,0xd3,0x89,0x17,0xa0,0x84,0xfb,0x18,0xe8,0xe9,0x3e,0x3f,0x68,0x7a,0xba,0x2e,0x10,0x85,0x68,0xfe,0xb1,0xc3,0x3c,0x41,0x30,0xa6,0x5d,0xad,0xc5,0x16,0x15,0xd4,0x2f,0x90,0x40,0x58,0xd6,0x95,0xad,0x22,0xdc,0x38,0x55,0x6b,0xc5,0xba,0xde,0x61,0xdb,0xce,0x66,0x71,0x91,0x97,0xc5,0xc2,0x45,0xc8,0x92,0x8d,0x99,0x6d,0x9d,0xf3,0xc2,0x80,0x5c,0xa,0x9c,0x4e,0x1f,0x13,0x5a,0x2b,0xec,0xd7,0x27,0xc0,0xe1,0x72,0xba,0xeb,0xa9,0xb9,0x8c,0xce,0x8a,0xf,0x2f,0x1f,0x73,0x3b,0x57,0x34,0x7a,0xc0,0x6,0xc0,0x42,0xb1,0x9a,0xce,0xd3,0xd4,0xe7,0x40,0xde,0x86,0x22,0xc7,0x38,0xba,0xc5,0x1a,0x97,0x2c,0x4d,0x32,0xb7,0xab,0x2c,0x9b,0x30,0x7a,0xd9,0xa2,0x83,0x96,0x7b,0xeb,0x7,0x3d,0xe6,0x26,0xe9,0x76,0xac,0xee,0xb7,0x9b,0x76,0xfb,0xc7,0x88,0xdc,0x3d,0x65,0xee,0x7c,0x8b,0xd7,0xf,0x6f,0xf5,0x49,0xc9,0x4e,0x9e,0x7f,0xb4,0xe0,0xea,0x8f,0x9,0x76,0x64,0x41,0xba,0x81,0xf0,0xed,0x72,0xdb,0xf6,0xeb,0xb2,0x47,0xb3,0xf8,0x4c,0x0,0x9e,0x35,0x6b,0xd6,0x4,0x0,0x67,0xcd,0x9a,0x35,0xeb,0x5,0xae,0xf,0x7c,0xdb,0xeb,0xd8,0x2e,0x67,0xd4,0x52,0xc4,0x10,0xbc,0xd,0x7e,0x72,0x3,0xeb,0xe9,0xca,0x62,0xbb,0x3,0x74,0x9c,0xfe,0xe8,0x64,0xa1,0x44,0x3,0xe7,0x2e,0x38,0x31,0xa7,0x97,0x35,0xe9,0xbd,0xab,0x32,0x2,0xd8,0xc7,0x28,0xd,0x52,0x94,0x0,0xef,0x25,0x14,0x81,0x5a,0x59,0xfe,0xa,0x98,0xd7,0x50,0xf0,0xe0,0x57,0x18,0x60,0xba,0x21,0x21,0xd0,0x8b,0x5b,0x4c,0xaa,0xa6,0xcd,0x8a,0x36,0x16,0x8e,0xd1,0x72,0x80,0x82,0xee,0x6c,0xa,0x3d,0x33,0xad,0x27,0xf3,0xd2,0x60,0x23,0x3f,0x12,0x14,0x83,0x3,0xc2,0xae,0x5f,0xb7,0xfb,0xde,0x81,0xe9,0xd0,0xe,0x0,0xac,0xf1,0x75,0xbd,0x71,0x73,0x0,0xa8,0x85,0xb1,0x90,0x33,0xc5,0xbf,0x75,0x93,0x1f,0x70,0x15,0xca,0x41,0xd7,0xcc,0xc4,0xc3,0x83,0x61,0xa8,0x1d,0x9e,0xa,0x10,0xfa,0xdf,0x41,0x7,0x0,0xa3,0xf4,0xe2,0xcd,0x1,0x72,0x7d,0xf7,0x39,0xdd,0x98,0x6,0x20,0x53,0x13,0x8f,0xf7,0xcd,0x8b,0xfd,0xea,0xc8,0x7b,0x3f,0x8e,0x80,0xe7,0x35,0xe8,0x77,0x1d,0xe6,0xf1,0x74,0xb0,0xf3,0x20,0xf4,0xc6,0x35,0xb0,0x24,0x40,0x49,0x2b,0x1b,0x6a,0x63,0x50,0x24,0x2d,0x27,0xb4,0xba,0xcd,0x41,0x67,0xd6,0x3b,0x5e,0x69,0x39,0xed,0x7e,0xc5,0x3e,0xa1,0x9d,0x24,0x69,0xb7,0x27,0xf0,0x2a,0x43,0x8d,0x31,0xb3,0xe8,0x42,0x3d,0x8a,0x5,0x6,0x31,0x80,0x27,0xb6,0x4,0x8e,0xd,0xa7,0x72,0xdd,0x5a,0xb,0x4b,0xf2,0x85,0x21,0xdc,0xcc,0x83,0xb5,0x2,0x88,0x9d,0x61,0xa8,0xe3,0x74,0x8c,0x20,0x9,0xa0,0xd0,0xef,0xb4,0xb9,0xa1,0xb0,0x9f,0x69,0xa1,0xd,0x51,0xc0,0xaa,0x5a,0x8a,0xf9,0xe2,0xb5,0x56,0x8d,0xa5,0x8,0x1,0xa,0xa3,0xf8,0xa,0xaa,0x7,0xaa,0x82,0x9b,0xa,0xbe,0xa5,0xbc,0xa0,0x94,0xd,0x29,0x75,0x86,0x61,0x14,0x90,0x2b,0xc4,0x4,0xaa,0x15,0x69,0x61,0xf,0x59,0xb5,0x45,0x50,0x8f,0x53,0x6a,0xd5,0xfc,0x0,0xfd,0x71,0x4,0xc1,0x3e,0xcf,0x18,0x7f,0x72,0x8c,0x92,0xf3,0x1,0x24,0x67,0x1,0x51,0x4b,0x11,0x90,0x70,0x5c,0xdc,0xb8,0x9c,0x9f,0xd8,0xe3,0xbc,0xcd,0x64,0xac,0x49,0x5d,0x78,0x23,0x2,0x96,0xf5,0xc4,0xa1,0x43,0x1b,0xb3,0xa1,0x53,0xca,0x20,0xf4,0x0,0x11,0x5,0xdd,0x38,0xa4,0x23,0x18,0xcb,0x91,0xe4,0x38,0x86,0xb0,0x8,0xfe,0x46,0x1d,0xd8,0x74,0xc0,0x6c,0x8c,0xd9,0x58,0xd9,0x31,0x24,0x4b,0x57,0xe7,0xf3,0xe,0x66,0x38,0x7a,0xef,0x43,0x3d,0x77,0xb5,0xf,0x95,0x7a,0xfc,0x52,0xec,0x9e,0xb4,0x3d,0x5d,0x5a,0x7f,0x1f,0xd7,0xb,0x76,0x7a,0x7c,0x9b,0xf,0x93,0xb9,0x31,0x2,0xe3,0x4f,0x12,0xc8,0xba,0x92,0xe6,0x86,0x83,0xb9,0xf8,0xc8,0x9b,0x8f,0x6,0xa0,0x6f,0x30,0xc6,0x54,0xb,0x14,0x5c,0x39,0x9e,0xd8,0xe7,0xc,0x90,0xe2,0xa0,0x5a,0x70,0x8f,0xd3,0x53,0xa0,0x49,0x3a,0x58,0xda,0xa3,0xa7,0xcc,0xce,0x2,0xfa,0x5e,0xd9,0xc0,0xcc,0x9a,0x35,0x6b,0x2,0x80,0xb3,0x66,0xcd,0x9a,0x35,0xeb,0x5,0xa9,0x21,0x35,0xd6,0x49,0x5e,0x83,0xb,0xbb,0xd0,0xd5,0xfe,0xe0,0x56,0xb0,0x1d,0x38,0x8,0x82,0x35,0x36,0x51,0x3,0x39,0xa4,0xd9,0x6a,0xe4,0x7c,0xa5,0x20,0xdc,0x92,0xa8,0x52,0xa1,0x66,0x9e,0x50,0x44,0xcd,0x1a,0x1c,0x5,0x21,0xd5,0x2b,0xaa,0x49,0xfa,0x64,0xa3,0x86,0x50,0xdb,0xb0,0x6a,0xce,0x52,0x95,0x2a,0x77,0xba,0x51,0x12,0x26,0x47,0xef,0x41,0x63,0xe,0x58,0xfa,0x6c,0x1c,0x9a,0x89,0x0,0x1a,0xbd,0x96,0xec,0x5e,0x98,0x6,0xb0,0x48,0x1b,0x92,0x26,0x60,0xe1,0x98,0x34,0xbb,0x7f,0xdf,0x8,0xf0,0xf9,0x3e,0x84,0x76,0x1e,0x89,0x21,0x6,0xd7,0x2b,0x34,0x77,0xb3,0x1e,0x1c,0x3b,0x71,0xc,0xb1,0xf0,0x8d,0x3b,0x27,0x8,0x7,0xfb,0x3c,0x4b,0xe5,0x85,0x34,0xdd,0x31,0x18,0xf2,0x48,0x43,0x5a,0xe0,0x98,0xae,0xa8,0xf2,0x5e,0xf3,0x71,0x1a,0xf6,0xa5,0x33,0x39,0x7,0xb9,0xef,0x10,0xf3,0x4c,0xc3,0x71,0x19,0x65,0xc1,0x3e,0x2d,0xd9,0x35,0x1f,0x47,0x2c,0xc8,0x41,0xd2,0x5,0xf9,0xd,0x5c,0x1f,0xc7,0xfe,0xd8,0x1e,0xd0,0xbb,0x7e,0x7f,0x37,0xed,0x77,0xc,0x14,0xec,0x58,0x24,0xe,0xd4,0xed,0x20,0x31,0x6e,0x48,0xb6,0xb1,0x6b,0x48,0xe9,0x98,0x9d,0xe2,0xfc,0x1f,0x83,0xf3,0x50,0x9b,0x35,0xeb,0x9d,0xac,0x98,0x92,0x5f,0xfa,0xe8,0x63,0x57,0xeb,0x7e,0xac,0x1,0xdd,0x9f,0xcf,0xbc,0xdd,0xe4,0x77,0xac,0xe0,0x5e,0x14,0xb0,0x4d,0x3,0x2e,0x38,0xc5,0xb6,0x9,0x90,0xe4,0xc6,0x75,0x30,0xe0,0xa4,0x60,0x5b,0xad,0xa5,0x87,0xf,0xe9,0xfc,0x22,0xe3,0x7c,0x4a,0xd9,0x5,0x6f,0xe4,0x3e,0xe6,0x87,0x1e,0xe,0xc4,0x7e,0x7e,0x55,0x0,0xbc,0xac,0x3,0x92,0x30,0xff,0x18,0x6c,0x4b,0x29,0xa3,0x4a,0x90,0x45,0x88,0x91,0xc3,0x28,0x5a,0x33,0x40,0x4e,0x3d,0x3a,0xd9,0x62,0x36,0x38,0xaf,0xd3,0x1e,0x28,0x11,0x24,0x88,0xa9,0x8f,0x31,0xec,0x21,0xcb,0xbe,0x9e,0xfd,0xfa,0x8e,0xa,0x78,0x46,0x1e,0x13,0xf5,0x38,0xf8,0x45,0x16,0x1d,0x6f,0x2c,0x61,0x37,0x4,0x24,0x74,0x66,0x1d,0x6f,0x6f,0x41,0x5a,0x96,0x2b,0x28,0x89,0x69,0x82,0x5d,0x76,0xb,0x17,0x64,0xc4,0x39,0x26,0x6a,0x2d,0x50,0xc,0x64,0x8c,0x29,0x21,0x86,0xc8,0xc0,0xab,0xce,0xbf,0xad,0x22,0x65,0xe,0x76,0x52,0x49,0x67,0x8c,0x89,0x2d,0x9,0x12,0x7,0x8e,0x94,0xb2,0xf5,0xf3,0x9a,0x12,0x6a,0xdd,0x58,0xb2,0x9c,0x32,0xea,0xb6,0x21,0xe6,0x5,0x21,0x34,0x37,0x1f,0x46,0x4b,0x58,0x56,0xf6,0x21,0x79,0xb0,0x8b,0x3a,0xc0,0x69,0xf3,0xb0,0x8d,0xc7,0xcd,0xe6,0x98,0x7e,0xbf,0xd0,0x9c,0x47,0xdf,0x35,0xc3,0xdb,0x40,0x2f,0x3f,0xfe,0xda,0xf9,0xc2,0x4d,0xff,0xbf,0xb7,0x7,0xfe,0xdd,0xb2,0xf,0xd9,0x49,0x73,0x7,0xda,0x3f,0xae,0x41,0xc0,0x21,0xa4,0x4,0x2e,0x5,0x6d,0x9f,0xb4,0x31,0x2,0x99,0x57,0xa2,0xb,0x5d,0xd0,0x73,0x4f,0x5,0x7,0xfe,0x1d,0xf1,0xf,0xfd,0xc7,0xec,0x79,0x89,0x47,0x7b,0x75,0x8,0xfe,0xd9,0xf7,0x47,0xf3,0x4b,0x9e,0x35,0x6b,0xd6,0xac,0x79,0xf7,0x3a,0x6b,0xd6,0xac,0x59,0x2f,0x60,0x91,0x25,0xe6,0xed,0x98,0x51,0xb6,0x9a,0xdd,0xc1,0xbe,0x10,0x3d,0xa0,0xa7,0x52,0x55,0x35,0xd,0x97,0x54,0x58,0x4d,0x4b,0x75,0x8d,0x95,0x2,0x5a,0xfa,0x5c,0x14,0xcf,0x24,0xfd,0x3e,0xda,0xdd,0x14,0x2b,0x23,0x43,0xe5,0x5d,0x51,0x7c,0x86,0xf4,0x65,0x2a,0x59,0xd2,0x4,0x49,0xf3,0x96,0x6b,0xa3,0x59,0x76,0x88,0x23,0xf8,0xc7,0xcd,0x59,0xdf,0x3f,0x63,0xcc,0x49,0x63,0x66,0xb2,0x66,0xd7,0xa8,0xe8,0x7b,0x9a,0xa6,0x48,0x4a,0xe2,0x45,0x8c,0x89,0xd9,0x30,0xc1,0x37,0x2d,0x64,0xcd,0x1a,0x88,0x1c,0x18,0xa9,0xa1,0x14,0x2c,0xa1,0x6b,0xda,0xc,0xf9,0x84,0x65,0xdf,0xa2,0x5b,0x40,0x85,0xf7,0x53,0x22,0x6b,0xec,0x46,0x5f,0xac,0xee,0x79,0x37,0x0,0x96,0x2,0x86,0x36,0xf1,0x71,0xd2,0xe3,0xdc,0x5a,0x75,0xdc,0xc3,0x70,0xd8,0xc8,0x90,0xf7,0x39,0x24,0x58,0x82,0xa6,0x82,0x59,0x9d,0xd,0x28,0x8d,0xa1,0x32,0x85,0xfc,0xfe,0xef,0x1a,0x39,0x38,0xaf,0x2f,0x88,0x4c,0x96,0x14,0x74,0xdb,0x5,0x76,0x74,0x86,0xe6,0xb5,0x44,0x57,0xd9,0x43,0xfe,0x79,0xfb,0x1d,0xdd,0x68,0x0,0xf7,0xfe,0x81,0xde,0xab,0x8a,0x2c,0x8,0x85,0xe,0x40,0xe0,0xe3,0x7f,0x93,0x4b,0x31,0xbe,0x42,0x27,0xf7,0xaf,0x23,0x60,0x3b,0x3f,0x9e,0x3,0xcd,0xac,0xe7,0x52,0xad,0x94,0x91,0x99,0x1b,0xb0,0xbb,0x76,0x3c,0x50,0xcd,0xe0,0x98,0xb1,0x6b,0x95,0xa9,0x27,0xe3,0xac,0x82,0x5d,0xc,0x90,0x55,0x3,0x8,0x15,0x5c,0x57,0x16,0x9e,0x2d,0xe6,0x88,0xa7,0x98,0xbf,0x9e,0x15,0x20,0xb2,0x5,0x1c,0x7f,0xcd,0xb4,0x86,0x94,0x96,0x2e,0x75,0x95,0x71,0x25,0x20,0x20,0x2f,0xab,0xc9,0x6d,0xa3,0x7c,0xbe,0x7e,0x2e,0x7b,0xe4,0x91,0x1,0x82,0xec,0x21,0x18,0xec,0xbb,0x53,0xce,0x32,0x5e,0xf7,0xf7,0xa5,0x94,0x46,0xaf,0x43,0x63,0xc5,0xf5,0xfd,0x40,0xe8,0xc9,0xc2,0xde,0x4f,0x70,0xc,0xe2,0xd8,0x6c,0x2c,0xd6,0xfd,0xd1,0x24,0x70,0x7d,0x8d,0x26,0xec,0xc6,0x94,0x38,0x95,0x39,0x46,0x93,0x56,0xeb,0x71,0x2,0x98,0xc1,0x17,0x2,0xef,0x2b,0x3,0x9b,0x7d,0x7e,0x49,0x29,0x33,0x3,0x52,0xde,0x17,0x25,0x81,0x3d,0xc6,0x68,0xe0,0x2d,0x9,0x38,0xa8,0x1,0x23,0xfa,0xfd,0xa,0xae,0x22,0x0,0x41,0x25,0xbd,0x2,0x82,0x86,0x10,0x5,0x28,0x44,0x7,0x64,0xdd,0x76,0x53,0xe3,0x73,0x98,0x52,0x16,0xe0,0x30,0x19,0x20,0x6c,0x1e,0x81,0xb5,0x2f,0x56,0xc5,0x18,0xdd,0xdc,0xe0,0xbc,0x5e,0xd5,0x77,0xd0,0xfd,0xf1,0x61,0x25,0x7e,0xec,0x1f,0xe6,0x8f,0x9d,0xff,0xab,0x8d,0xd7,0x4f,0x19,0xe3,0x9f,0x1d,0xf8,0x1b,0x6e,0x82,0x8e,0xe1,0x31,0xbd,0x37,0xb8,0x42,0xdb,0x82,0xbb,0x6f,0xa0,0x3,0x34,0x8f,0x8e,0xbe,0x9,0x38,0xc0,0xe,0x47,0x40,0x90,0xe,0xc1,0x3b,0xc2,0x3e,0xc6,0x6a,0x7c,0x3c,0x1c,0xbc,0xfe,0x68,0x4e,0x3a,0x3a,0x6,0x3,0x17,0x7e,0x32,0x0,0x67,0xcd,0x9a,0x35,0x1,0xc0,0x59,0xb3,0x66,0xcd,0x7a,0x31,0x6b,0xf0,0xdb,0x19,0xe4,0x9d,0x74,0xfd,0x58,0xe8,0xac,0x11,0x95,0xf4,0xea,0x5d,0x67,0x97,0xf5,0xb0,0x2c,0x2c,0x74,0x47,0x1b,0x93,0xc0,0x98,0xb4,0xaa,0x69,0x72,0x2e,0x99,0x69,0x7b,0x8c,0xc9,0x24,0x52,0x41,0xd8,0x24,0x7a,0xb3,0xca,0x8c,0x3b,0x60,0x97,0xc,0x61,0xcc,0x3e,0x2f,0xe5,0xf5,0xff,0xf7,0xb7,0xd4,0xc1,0x98,0x87,0xd4,0x93,0x7c,0x77,0x40,0x93,0x3f,0xc,0xfe,0xe6,0xdd,0xd8,0xc,0xd6,0x3c,0x77,0x3f,0x28,0xde,0xb6,0xe6,0xf0,0xc4,0x76,0x25,0x21,0x65,0x6,0x1e,0x19,0x2b,0xc0,0x1a,0x64,0xf9,0x32,0x65,0x44,0x76,0x50,0x2b,0x18,0x50,0x68,0xf,0x59,0xb3,0x23,0x12,0x3b,0xf1,0xa7,0xda,0xb7,0x8,0x44,0x76,0xb,0xdf,0xbf,0x3f,0x60,0x64,0x30,0xd0,0xfe,0x46,0x9f,0xd0,0x33,0x3d,0x8,0x83,0x78,0xdb,0x9a,0x77,0x18,0x0,0xd0,0x1,0xbb,0x6e,0x1e,0x1f,0xc2,0x8,0x20,0x1c,0x37,0x5a,0x23,0x13,0x22,0x98,0x6f,0xd7,0x1,0x58,0xd7,0xc8,0xb1,0xff,0x5a,0x67,0xf9,0x39,0x46,0x1f,0xfb,0x55,0x8d,0x4d,0x60,0x30,0x50,0x39,0xc,0x0,0x1c,0xed,0x28,0x98,0xf4,0xc7,0x98,0x76,0x38,0x24,0x62,0x1f,0x34,0x7e,0x6,0xd0,0xce,0xa6,0x6a,0xd6,0xf3,0x1a,0xe7,0x9d,0xa7,0xdb,0x7e,0x6c,0x63,0x86,0xd9,0xe8,0xaf,0x66,0x60,0x92,0x48,0x48,0xa3,0x4f,0xf8,0x55,0xe0,0x5c,0x17,0x71,0x74,0x81,0x46,0x40,0x25,0xb8,0x45,0x89,0x28,0x60,0x92,0x82,0x4a,0xdd,0x3f,0xaf,0x5f,0xc3,0xba,0x6d,0x1a,0xa0,0xa1,0xcc,0x34,0x4,0xe,0xf3,0xf0,0xe1,0x13,0xad,0x56,0x34,0x6a,0xcc,0x6c,0x5b,0x16,0xc4,0x9c,0x77,0x63,0x37,0x83,0x8a,0x29,0x67,0xe,0xc7,0x90,0xed,0x52,0x76,0xa0,0x8e,0x4d,0x31,0xe5,0x9e,0xd6,0xed,0x24,0x8f,0x96,0x76,0x2e,0xf3,0x99,0x2e,0x7a,0x44,0x5d,0xf4,0xba,0x2,0x9d,0x82,0x1,0x68,0x39,0x2f,0x76,0x3c,0xfc,0xbc,0x62,0x6c,0x41,0x4d,0x3,0x96,0xb9,0xac,0x96,0xcd,0x40,0x33,0x65,0x2c,0xea,0x2,0x44,0x67,0x35,0x7,0x3,0x12,0x19,0xfc,0xc,0x48,0x79,0x15,0x6f,0x41,0x6,0x11,0x53,0x5e,0xc4,0xcb,0x8f,0x3f,0x27,0x2f,0x6b,0xf,0x56,0x89,0xbc,0x5d,0x2a,0xeb,0x54,0x36,0x61,0xc,0xd1,0x80,0x3c,0x4e,0x49,0xe6,0xed,0xd3,0x63,0x96,0xf3,0x3a,0xcc,0x19,0x29,0x67,0xf3,0x7f,0x54,0x49,0xb3,0x82,0xa8,0x39,0x2f,0x32,0x47,0x6,0xb3,0xe9,0x68,0xe4,0x59,0xcf,0xc1,0xd2,0x8b,0x21,0xf3,0xb0,0x1e,0x27,0xa2,0x63,0xdf,0xbc,0x61,0x11,0xe7,0xff,0x97,0x24,0xf5,0x8,0x6,0xa3,0x1,0x9c,0xbc,0x82,0xdf,0xc,0x51,0x73,0xb,0x83,0x83,0x44,0xf7,0x6,0x9d,0xdf,0x7d,0x5d,0xb8,0x1,0xee,0x5d,0x6d,0x15,0x8d,0x0,0x1e,0xed,0x36,0xe3,0xe9,0x98,0x21,0x3d,0xd,0xce,0xbc,0xfd,0x4c,0xb8,0xbd,0x61,0x7a,0xbf,0x15,0x9e,0xb6,0xf1,0xb3,0x66,0xcd,0xfa,0x33,0x57,0x53,0x2,0x3c,0x6b,0xd6,0xac,0x59,0x2f,0x54,0xed,0x6e,0x66,0xc3,0x28,0x8d,0xed,0xde,0x6f,0x1c,0x96,0xa1,0xec,0x9,0x48,0xa3,0xa7,0xa0,0x56,0x50,0x99,0x4c,0x0,0x2,0xa2,0xbb,0x89,0x14,0x7,0x3a,0x69,0x3e,0x3a,0x63,0x83,0xc4,0x64,0x9d,0x6,0xef,0x3d,0x6d,0x3c,0xcd,0x18,0x5e,0x25,0x50,0xc2,0x5a,0xeb,0x12,0xd8,0xd8,0xc1,0x38,0x69,0x1e,0x5b,0x2d,0xe6,0x1f,0x68,0xde,0x7f,0x61,0x6c,0x76,0x47,0x8b,0xbb,0xce,0xc,0xbc,0xa,0xbd,0x8,0x5e,0xf6,0x13,0x8c,0x59,0xd8,0xd3,0x1a,0x61,0x80,0x17,0x61,0x4c,0xb0,0x64,0xd9,0x59,0x46,0x53,0x49,0x98,0x82,0x97,0x8d,0x80,0x18,0xba,0x29,0xbe,0xb0,0x11,0xb5,0xc1,0x6b,0xa0,0x51,0x51,0xeb,0xfe,0xdd,0x93,0x6c,0x7b,0x33,0xbc,0x7,0x1a,0xb5,0x99,0xb7,0xe6,0xd1,0x7b,0x19,0x52,0xf7,0xe0,0x32,0x3f,0xc5,0x10,0x0,0x31,0x80,0x6f,0x8d,0x6,0x13,0x7a,0xcf,0x3e,0x34,0xc9,0xb3,0x4f,0x1a,0xa6,0xce,0x4,0x3c,0x6a,0x8a,0xbd,0xc7,0xd8,0x21,0xe0,0xac,0xa1,0x2a,0xb2,0x3d,0xd1,0x83,0x2,0xf6,0xfd,0xfe,0x33,0xc2,0xd0,0x59,0x19,0x60,0x6a,0x7,0x69,0x94,0x5a,0xf9,0x86,0xf1,0x8a,0x21,0x78,0xd0,0x9b,0xdd,0x92,0x8e,0x8d,0xc7,0x78,0xef,0xe7,0xf4,0xc,0x9d,0xde,0x70,0x95,0x4d,0x63,0xf5,0x59,0xcf,0x69,0x94,0xbf,0xba,0x5e,0x3a,0x78,0x65,0x8c,0x35,0xf1,0x72,0xb5,0x85,0x8,0x1,0x7b,0x8c,0xbd,0x26,0xf2,0xd2,0x2c,0x49,0xb2,0xba,0x10,0xa0,0x4c,0x31,0xf5,0x1b,0xed,0x63,0x15,0xa1,0x39,0xe9,0x6f,0x97,0xa5,0x36,0x63,0x9b,0xd,0x4c,0xda,0x38,0x5e,0x83,0x65,0xbb,0x30,0x1b,0xe,0xdd,0x23,0x50,0x17,0x73,0x9a,0xa5,0x6c,0xcb,0xc2,0x4f,0xd4,0x10,0x93,0x80,0x10,0x92,0xd9,0x22,0x68,0xd8,0x87,0x5a,0x4a,0x34,0x1,0x33,0x79,0x9f,0x1a,0xa8,0x55,0x3,0xbd,0xcc,0x1b,0xaf,0x35,0x64,0x49,0x4,0xee,0x63,0xeb,0x68,0x5d,0x60,0xc9,0xc7,0xb1,0x3,0xa1,0xb5,0x6c,0xc6,0x20,0xb4,0x80,0x11,0x8c,0x29,0xe2,0x1a,0x82,0xa2,0x23,0x6,0x33,0xf5,0x82,0xa4,0x12,0x2f,0x48,0xc2,0xec,0x33,0x1f,0xc1,0x14,0x91,0xd2,0x62,0xc7,0x52,0xe7,0x45,0x4e,0x39,0xe6,0xf4,0xe0,0xbc,0xac,0x28,0xdb,0xc5,0xcd,0x13,0x2,0xea,0xa,0xf3,0x5e,0xd9,0x99,0xfa,0x5d,0xad,0xb6,0x3e,0x8e,0xa,0x40,0x99,0x23,0x27,0x22,0x6b,0x6a,0xb3,0x2,0x97,0x4,0x80,0xfc,0xe2,0x8e,0x80,0xa7,0x96,0x50,0xc,0x74,0xf0,0x8f,0x2,0x4a,0xd9,0x86,0x90,0x14,0x3,0x95,0x9b,0xa6,0xa7,0xf3,0x7c,0xda,0xa5,0xd4,0xe2,0xd9,0xe8,0xbc,0x5c,0x87,0x74,0x60,0x1b,0xaf,0xc3,0xf5,0x62,0xd,0xd,0x69,0x58,0x2,0x82,0x1e,0x19,0xe2,0xed,0xe5,0xbb,0xdd,0x1f,0xcf,0x5e,0x14,0xc2,0x78,0xef,0xa3,0xe3,0xfa,0xd3,0x18,0x85,0x6e,0x9d,0x6d,0x2f,0xc9,0xb5,0xb0,0xae,0x1b,0x73,0xc1,0x91,0x94,0x77,0x78,0x9e,0x9e,0xe5,0x8e,0x2d,0x3c,0xc3,0xac,0xf3,0x34,0xa7,0xc4,0x63,0xa1,0xf0,0xc,0x0,0x99,0x35,0x6b,0xd6,0xbe,0x26,0x3,0x70,0xd6,0xac,0x59,0xb3,0x5e,0xa4,0xc6,0xb0,0xed,0x56,0xc2,0xbd,0xec,0xd3,0xdd,0x17,0x92,0x80,0x7f,0x5d,0xd6,0xd4,0x6,0x58,0x43,0xa5,0x51,0xca,0xe8,0x53,0x40,0xd0,0x2,0x3d,0xb4,0x9,0x12,0x26,0x85,0x2,0x47,0xea,0xaf,0x43,0x20,0x97,0x10,0x48,0x6,0x76,0x59,0x2,0x2c,0xc1,0xa4,0x51,0x31,0xa5,0x1,0xac,0xd4,0x66,0x93,0x1,0xc4,0x30,0x0,0x66,0xd8,0x65,0x39,0xc,0x52,0x24,0xf5,0x6d,0xd3,0x24,0x49,0xc7,0xa2,0x50,0xc9,0x72,0xd4,0x46,0x4,0x9d,0xd5,0xa2,0x7e,0x85,0x57,0xf0,0x8e,0x34,0x21,0x96,0x48,0xa9,0xb2,0x67,0xf5,0xf3,0xe9,0xe9,0x1f,0x3,0xfb,0xc1,0xd8,0x32,0xd6,0x34,0x75,0x96,0xa0,0x35,0x41,0xa,0x26,0xc6,0x2e,0x85,0x6a,0x6d,0x4,0xaa,0xfa,0x73,0xfd,0x73,0x55,0x2a,0x8c,0x80,0xc1,0x83,0x4f,0xbd,0xb5,0x7c,0x27,0xa3,0x6c,0xd,0x7f,0xc0,0x54,0xe6,0x35,0x9a,0xbc,0x87,0x21,0x6d,0x13,0x3b,0x69,0x9f,0x7f,0xff,0x28,0x3,0xe,0x23,0x10,0xeb,0x58,0x86,0x43,0x33,0xb9,0xf7,0xd2,0xb,0x61,0x0,0xf4,0x3c,0x60,0xd8,0x25,0xc5,0x3b,0x90,0x17,0xc7,0xb2,0x33,0x1c,0x0,0x7f,0xf6,0x3e,0xda,0xcb,0xa7,0xc3,0x1,0xb0,0x39,0x9a,0xb2,0x8f,0xb2,0x69,0xe0,0x56,0x1c,0x63,0x0,0x10,0xf3,0x4c,0x2,0x9e,0xf5,0x7c,0xca,0x8f,0x1b,0xfe,0xe7,0xdb,0xdc,0xd8,0xa9,0xc,0xaf,0x2a,0x63,0x6,0xb3,0xc7,0x56,0x6,0xd2,0x84,0xc1,0x97,0xf3,0x6a,0x80,0x4d,0x4a,0xcc,0xb4,0xb,0xc2,0xe6,0x32,0xaf,0xd6,0x56,0x1,0x1,0xdf,0xfc,0x78,0x18,0x53,0xb4,0x71,0x5f,0x1,0x24,0x9d,0x4f,0xc2,0x30,0x6e,0xf3,0x62,0xcf,0xb2,0xae,0x92,0x98,0x9b,0xd1,0x84,0xd1,0x16,0x53,0xea,0xb,0x18,0xe0,0x60,0xd,0x1d,0x87,0x52,0x5e,0x78,0x8e,0x88,0x11,0x49,0x58,0x80,0x6a,0x14,0xa7,0x81,0x20,0x29,0x67,0xf9,0x8c,0xce,0xc6,0x8e,0x49,0x25,0xc2,0xcb,0x30,0xaf,0x31,0x38,0x25,0xe3,0xb1,0xcc,0x43,0x29,0x65,0x93,0x21,0x8f,0x81,0x47,0x12,0x66,0xa5,0x9f,0xad,0x32,0xe2,0x98,0x90,0x73,0x36,0xa0,0x2e,0xa5,0xdc,0x17,0xce,0x82,0xc8,0x7b,0x89,0x90,0x97,0x15,0x4,0xe2,0x60,0x13,0x39,0x5f,0x29,0x75,0x76,0x9e,0x32,0xe6,0x52,0xce,0xb6,0x3f,0x29,0x65,0xa4,0xbc,0x60,0x3b,0x9f,0x91,0x52,0xc6,0xb2,0x9e,0xba,0xc4,0x58,0x0,0x59,0x95,0x19,0x2f,0xeb,0xc9,0xce,0xa1,0x7a,0xe,0xaa,0x5d,0x84,0x32,0xee,0x99,0x51,0xd8,0xc7,0xb3,0x5a,0x8a,0x6c,0x47,0x16,0xe9,0x77,0x1a,0xd8,0x89,0x36,0x3e,0xa,0xc0,0x57,0x6b,0xe1,0x6d,0xd2,0xf0,0x11,0x65,0x1d,0xa6,0x4,0xc4,0x2e,0xad,0xf6,0x5e,0x89,0xea,0xcb,0x68,0xe9,0xca,0xc1,0x5b,0x6e,0xf8,0x63,0xdb,0xae,0xc6,0xd4,0x31,0x7f,0x43,0xe7,0xf1,0xbd,0xaf,0xeb,0x91,0x77,0xdf,0x1,0xbf,0xcd,0x25,0x1e,0xab,0x8a,0x57,0xc1,0x47,0xff,0x71,0xbb,0x8c,0x8e,0xfd,0xed,0xc5,0x61,0x2e,0xf0,0xd3,0x64,0xbb,0xb8,0x1,0xcf,0x11,0xf0,0xec,0x1c,0xbc,0x9b,0xd2,0x65,0xbf,0x55,0xe1,0x60,0xb,0x8e,0x5e,0x8b,0xbe,0x8,0x3b,0x6b,0xd6,0xac,0x59,0x52,0x93,0x1,0x38,0x6b,0xd6,0xac,0x59,0x2f,0x54,0x67,0x78,0x74,0x3f,0x49,0x63,0x30,0x43,0xec,0x4c,0x35,0x65,0xf1,0x79,0xe0,0xcf,0x83,0x69,0x29,0x65,0x33,0x8c,0x37,0x4f,0x24,0x91,0x10,0x35,0x49,0x4e,0x8c,0xd6,0x3c,0xf5,0x9b,0x75,0x65,0x2,0xe8,0x63,0xf6,0x7f,0xc0,0xfc,0xea,0x12,0xa2,0x25,0xe3,0xa9,0xac,0x8c,0xdf,0x12,0xd1,0xa4,0xf9,0xe0,0xa6,0xc5,0xa5,0x18,0x6a,0x28,0x89,0x2,0x9b,0x2e,0x1d,0x57,0xcd,0xcc,0x75,0x7f,0x2c,0x2c,0xc4,0x7b,0x5f,0xf9,0x54,0x61,0x27,0x1d,0xde,0xb3,0xd3,0xd4,0x83,0x8f,0x9b,0x1b,0x20,0xc4,0x66,0xc,0x44,0xd,0xce,0xb0,0xcf,0x23,0x62,0x83,0x6d,0x9f,0x42,0x5c,0xeb,0x0,0xc6,0xb6,0xca,0xd,0xb6,0x36,0xd5,0xfe,0x58,0x75,0x2f,0x3d,0x31,0x74,0xaf,0x5,0x4a,0x6b,0x60,0x70,0x14,0x76,0x8c,0x4c,0x52,0x2c,0xc7,0x83,0x3d,0xa1,0xe0,0xd8,0x94,0x9d,0x59,0xd2,0x25,0xc4,0x9e,0x31,0x44,0x6,0x14,0x72,0x3,0xbe,0x18,0x63,0x88,0xe4,0xd8,0x78,0x1f,0x2e,0xdf,0x14,0xea,0xef,0x4b,0x3d,0x19,0xa3,0xa4,0x8c,0x6a,0x8,0x87,0x36,0x83,0xc1,0xf9,0x1f,0x5a,0x8a,0x68,0xec,0xc0,0x9d,0xf7,0xd8,0x23,0xf7,0xbb,0xb4,0xe7,0x9c,0xf1,0xba,0xef,0x6d,0x8,0x64,0x4c,0x8a,0xa7,0xf9,0x4,0xda,0x36,0x5f,0x5,0x90,0xd0,0x2e,0xd1,0xd1,0x37,0x9a,0x61,0x8,0x49,0x18,0x9a,0xcd,0x3d,0xc,0x28,0xcd,0x64,0x2b,0xe7,0x39,0xde,0xcc,0x7a,0x2e,0xd5,0x4a,0x1d,0x7e,0x9b,0x7b,0xbf,0x4d,0xf5,0x89,0xeb,0xbe,0x7d,0x8d,0x99,0xcf,0x66,0xc7,0xd0,0x3d,0xf1,0x48,0x16,0x63,0x6a,0xab,0x68,0xb5,0x62,0x11,0xf0,0x2a,0xa6,0x28,0xec,0xbe,0xc5,0xec,0x20,0xf4,0x9a,0x48,0x59,0x40,0xa1,0x40,0x58,0xd6,0x13,0x7,0x55,0xc4,0x88,0x14,0x14,0x1c,0x5c,0x0,0x1,0xc0,0xfa,0x18,0xc5,0x9f,0xd5,0x24,0x19,0x3e,0x25,0x4e,0xed,0xcd,0xb,0xb3,0xd5,0xf2,0xb2,0x62,0xbb,0x9c,0x99,0x39,0xa7,0x21,0x17,0x31,0x18,0xd3,0x4f,0x96,0xa4,0x90,0x97,0xd5,0x25,0xa9,0xfb,0xa0,0x23,0x96,0xf8,0xea,0x78,0xa6,0x12,0x5e,0x65,0x36,0xd6,0xb2,0xd,0x6c,0x46,0x3f,0x1f,0xf1,0x3e,0x75,0x69,0xad,0xb2,0xbe,0x8d,0xb1,0x2e,0x21,0x19,0xb5,0x6c,0x20,0xb5,0x74,0x68,0xd,0xa4,0xc9,0xba,0x99,0xe7,0xc9,0xa6,0x49,0xc3,0x22,0x85,0x56,0xc0,0x4f,0x8f,0x73,0x4c,0x9,0x51,0x64,0xc0,0x29,0x2f,0x32,0x77,0x3a,0xf9,0x75,0x88,0xc8,0xcb,0xc2,0x20,0xa9,0x8e,0xe3,0xca,0x42,0xcf,0x72,0x4c,0x25,0x44,0x25,0x48,0x7a,0x73,0xd9,0xce,0xf6,0x9c,0x85,0xbb,0xa4,0xc4,0x69,0xc4,0x29,0x23,0x46,0xc2,0x76,0xb9,0x60,0x59,0x4f,0x36,0xf7,0xe6,0xbc,0xa0,0x56,0xe,0x1c,0xd1,0xe3,0xaf,0x89,0xc2,0xca,0xfa,0xb4,0x60,0x90,0x5a,0x5d,0x6a,0xb1,0x32,0xf3,0xd9,0xbb,0x57,0x7d,0x10,0x81,0x31,0xd5,0xd7,0x7,0x69,0xd9,0x1c,0xac,0x80,0x20,0xed,0xc7,0xd9,0x6b,0x40,0x6f,0xb8,0xa1,0x51,0xd6,0x20,0x1d,0xa5,0xd9,0x63,0x4c,0xd7,0xdd,0xcd,0x7b,0xb7,0x82,0x33,0xf6,0xb7,0x4b,0xc7,0x2e,0x7a,0x7f,0x5c,0xa5,0xca,0x8b,0x23,0x38,0x90,0xae,0x1f,0xa,0x1,0x57,0xf1,0x1f,0x44,0xb7,0x11,0x44,0xbf,0x10,0x10,0x9c,0xe7,0x31,0xfa,0xdc,0x3f,0x59,0x80,0xb3,0x66,0xcd,0xf2,0x35,0x97,0x5,0x66,0xcd,0x9a,0x35,0xeb,0x45,0xc2,0xff,0x2c,0x54,0xa3,0xdf,0x2c,0x3b,0x9b,0x73,0x1,0x9f,0xda,0xee,0xc6,0xbc,0x4b,0xa0,0x8,0x5d,0x6e,0xea,0x3d,0x9d,0xe0,0x58,0x84,0x2a,0xf7,0xa,0xe2,0x3b,0x14,0xf6,0x2b,0xf0,0xbb,0x90,0x88,0xe8,0x93,0x7b,0x1b,0xfb,0x48,0xc5,0xd0,0x65,0x55,0x1a,0xc0,0xa1,0x9,0x88,0xfa,0xd9,0x6c,0x8a,0x1e,0x2d,0xc9,0x55,0x43,0x26,0xbc,0xec,0x54,0xff,0xd6,0xd5,0xfb,0x2a,0xcd,0x8a,0xf,0xb0,0x8,0x12,0xec,0x11,0x54,0x6a,0x2a,0x37,0xe3,0x1a,0xde,0xe1,0x6f,0xd0,0x4d,0x6,0x27,0x80,0x1c,0xb3,0x59,0xae,0x3b,0x2,0x7f,0x3f,0x1e,0x9c,0x97,0xa2,0x82,0x7d,0xca,0x44,0x24,0x22,0x4b,0xa8,0x6d,0x3,0xb0,0xd6,0x3d,0x93,0x82,0x3,0x26,0x9,0xdd,0xf0,0x5d,0x81,0xbe,0xd6,0x78,0xbf,0x35,0x40,0xc5,0x1a,0x34,0xea,0x29,0xb9,0x9d,0x8d,0x41,0x23,0x83,0x47,0x36,0x92,0x1b,0xdf,0x2e,0xcd,0xd2,0xe3,0xc3,0xc7,0xfc,0x20,0x70,0x44,0xc1,0xd1,0xe0,0xa4,0xba,0xee,0x39,0x65,0xee,0xf4,0xa6,0x6f,0xe7,0xbb,0xe5,0xd8,0x90,0xbe,0x31,0xc,0xce,0xfc,0xfd,0x26,0x2b,0xc2,0x81,0x8f,0xfa,0xdb,0xb0,0xdf,0xab,0x7,0xa9,0xaf,0x58,0x80,0xd7,0x89,0x93,0xe1,0x86,0x3f,0x52,0x38,0x6a,0x32,0x69,0x9f,0x1e,0x3d,0xfa,0x1c,0xf6,0xa6,0x95,0xac,0xf9,0x9e,0x35,0xeb,0xb9,0xdc,0xbc,0x2b,0x78,0x87,0xd1,0x87,0x6f,0xcf,0x94,0xf6,0x40,0x94,0x82,0xfb,0x64,0xc1,0x43,0x12,0x80,0x14,0x83,0x31,0xb3,0x73,0x5e,0xec,0x77,0x1d,0x63,0xc6,0x92,0x57,0x97,0xaa,0x1b,0x4,0x50,0x8a,0xdd,0x6b,0xaf,0xf1,0xa7,0x29,0x58,0x66,0x1,0x42,0x80,0x0,0x71,0x64,0xb,0x15,0xf6,0x1a,0x2,0x4b,0x62,0x41,0xb6,0x1f,0x31,0x25,0x94,0xed,0x82,0xf5,0x74,0x27,0x63,0x68,0x71,0xe1,0x14,0xd1,0xc2,0x3d,0x82,0x3,0xc4,0x0,0x12,0xd6,0xe2,0x62,0xa0,0x9d,0x2e,0x12,0xf1,0x2,0x95,0x6,0x12,0x71,0xb0,0xc9,0xb2,0x9e,0x86,0x63,0x95,0x96,0x85,0xc1,0x2c,0xf1,0xfc,0xab,0x65,0xc3,0xb6,0x9d,0x6d,0x31,0x43,0x19,0x70,0xca,0x6a,0xd4,0xe3,0xab,0xde,0x7a,0x2a,0xb7,0x55,0x1b,0x8d,0x28,0xbe,0x7f,0x76,0x1e,0x5a,0x67,0xbd,0x33,0x93,0x8e,0x7d,0x5e,0x53,0xce,0x26,0xdf,0xb5,0x6d,0x91,0x30,0x8e,0xe0,0x16,0xb9,0xd4,0xd7,0x30,0xe5,0x8c,0xf5,0x74,0x67,0xc3,0xaf,0xee,0x7,0xbf,0x9e,0x81,0x4b,0x65,0x37,0xe6,0x65,0xb5,0x30,0x15,0x9d,0xa7,0xf3,0xb2,0x22,0xe5,0x64,0x56,0x15,0x31,0x74,0x7b,0x9,0x3,0xff,0xa8,0xa1,0xc9,0x22,0x96,0x2e,0xfa,0x41,0x82,0xa2,0x3a,0x50,0xdc,0x7a,0xc8,0xc8,0x60,0xdb,0xa0,0x13,0x70,0x1b,0x12,0xdc,0x75,0xd1,0x6f,0x5c,0x8c,0x9,0xce,0xce,0x43,0xf7,0x9f,0xae,0x81,0x2c,0xc0,0x5,0x71,0x4,0x9f,0x71,0xdf,0x27,0x5f,0xcf,0xee,0xf6,0x40,0xe2,0x5b,0x80,0x7b,0x3,0x70,0x8e,0xdb,0xc9,0xbb,0xcf,0xe,0x8,0xde,0x82,0xf,0x69,0xa4,0x15,0x5e,0xb1,0xfa,0x1c,0xdf,0xd0,0x76,0x60,0xc7,0x39,0x7c,0x2b,0xed,0xb1,0xdf,0xd9,0x2b,0xed,0xf1,0xa8,0xe8,0x98,0x35,0x6b,0xd6,0x2c,0xad,0xc9,0x0,0x9c,0x35,0x6b,0xd6,0xac,0x17,0xa8,0x98,0x3d,0x86,0xe1,0xc6,0xdb,0x98,0x56,0xda,0xc8,0x9,0x28,0x68,0xe9,0xba,0xd4,0xef,0x9d,0x79,0xa5,0xbf,0xd9,0x4d,0xb6,0x7a,0xff,0x99,0x44,0xa,0xa3,0xbc,0x92,0x76,0x32,0x4b,0x98,0x5c,0x2a,0x42,0x59,0x1,0x21,0x46,0x4,0x61,0x65,0x70,0x83,0x44,0x68,0x2,0x74,0xb1,0x9f,0x91,0xa6,0x11,0xfb,0xb0,0xc,0x6,0xbb,0xd4,0x17,0x29,0x20,0xd,0x81,0x11,0x2a,0xef,0x55,0xf9,0x6e,0x4f,0x96,0xd4,0x5e,0xc4,0xfb,0x50,0x35,0xe7,0x39,0x14,0x1c,0x30,0xd6,0x99,0x78,0xe6,0x1,0xc5,0x6d,0x5d,0xf7,0xf,0x52,0xe9,0x52,0x80,0xf9,0x67,0xd,0x86,0x3e,0x81,0xa5,0xbb,0x2a,0xb5,0x52,0xd6,0x5f,0x8,0x9,0xde,0xb3,0x47,0x4d,0xdd,0xf5,0x18,0x35,0x3,0xee,0x84,0x45,0x27,0x32,0x65,0x65,0xaf,0x18,0x78,0x19,0x12,0xcb,0xf0,0x6a,0x11,0xf9,0x2f,0x8c,0x4d,0xa7,0x7f,0xc3,0x1,0xb6,0xfe,0xf8,0x8c,0xde,0x82,0xcd,0xfc,0x1c,0xd,0xac,0x14,0x70,0x53,0x41,0xcf,0xce,0x96,0xc,0xc6,0xf6,0x80,0x79,0x3b,0xc5,0x51,0xe6,0x25,0xcd,0xb5,0x31,0x6,0x63,0xec,0x7e,0x8b,0xd2,0x18,0xf7,0x44,0xca,0x20,0xb9,0x2a,0x3e,0xd1,0xd3,0xb3,0x32,0xaf,0xd9,0x97,0xdd,0xdb,0xf0,0x3a,0xc1,0xb7,0x6f,0xf,0x7,0xd4,0x78,0xe6,0xa5,0x36,0xaa,0x37,0xd3,0xaf,0x95,0x21,0xd2,0x76,0x8c,0x93,0xe0,0xe4,0xc0,0x83,0xa1,0xfc,0xae,0xab,0x1a,0xbc,0x21,0xcb,0x1c,0x70,0x66,0x3d,0x97,0x22,0x12,0x20,0x4f,0x31,0xea,0xa6,0x36,0x2,0x9d,0x65,0xd7,0xaf,0x65,0xf6,0xfb,0xb,0x0,0x2a,0x35,0x24,0x88,0x77,0x5e,0x88,0xc2,0xfe,0x4b,0xcc,0xb8,0x56,0x7f,0x3d,0x61,0x75,0xf9,0xf1,0x3d,0x4b,0x40,0x45,0x2d,0x5b,0xbf,0x46,0x63,0x44,0xd2,0x71,0xab,0x15,0x63,0x70,0x87,0x18,0xb1,0x5d,0xce,0x6,0x2,0xe9,0x18,0xa7,0xdb,0xad,0xde,0x6e,0xba,0x8,0x14,0x44,0x8a,0xaa,0x8b,0x16,0x51,0x64,0xbf,0x66,0x53,0xa0,0xc0,0x95,0x80,0x84,0x2c,0x47,0xce,0xf2,0xbd,0x15,0x68,0x95,0xe5,0xc2,0x36,0xae,0xf1,0x3e,0x8f,0xdf,0x27,0x73,0x4a,0x92,0x14,0x75,0x34,0x37,0x56,0x31,0x18,0x89,0x16,0x4c,0x12,0x4d,0xbb,0x45,0x34,0x66,0xa8,0x27,0x20,0x46,0xf3,0x3c,0xf4,0x2c,0x4b,0x3e,0x7e,0x6b,0x97,0xba,0x12,0x21,0xa,0xe8,0x67,0xe3,0x94,0x1c,0x1b,0x5d,0x4,0x83,0xcc,0x81,0xbc,0x8b,0x15,0x31,0x32,0xeb,0x2f,0xe7,0x65,0xc7,0x96,0x23,0x63,0x22,0x2a,0x4b,0x32,0xa6,0xcc,0x7e,0x87,0x79,0x41,0xa8,0x95,0x41,0x5c,0xc1,0x5b,0x63,0x5e,0x3a,0x40,0x9a,0x99,0x8d,0xb8,0x2c,0x27,0xf1,0x7b,0x64,0x56,0x7d,0x13,0xaf,0x44,0xbf,0x80,0xa4,0x9,0xd0,0x65,0xbb,0x20,0xe7,0x95,0xff,0x6f,0xe3,0x65,0x97,0xf5,0xb6,0xda,0x80,0xd8,0xed,0x3c,0xbc,0x95,0x85,0xce,0x1,0xde,0xf3,0x6f,0xf0,0x83,0xd5,0xb4,0x7a,0xd3,0xe5,0x62,0x67,0xb8,0x17,0x46,0x46,0x9f,0x1b,0xbb,0x83,0x26,0xd9,0xbb,0xf3,0x33,0xc4,0x63,0xed,0x70,0xc4,0x63,0x17,0xdb,0xdb,0xac,0x40,0xf5,0xa6,0xbc,0x21,0xa3,0x70,0x8b,0x42,0xb7,0xe0,0xc2,0x3,0x66,0x5f,0xd8,0x1b,0xb,0x86,0x11,0x8,0xf4,0x36,0x13,0xc6,0x84,0x74,0xc7,0xe6,0x7a,0x3,0x8f,0x77,0x82,0xe,0xb6,0x17,0x7d,0x11,0x60,0xa6,0x0,0xcf,0x9a,0x35,0x6b,0x2,0x80,0xb3,0x66,0xcd,0x9a,0xf5,0x82,0xd6,0x95,0xdf,0xb,0xb5,0x21,0xdd,0xb7,0x4b,0xa6,0x60,0x40,0xa0,0xad,0x3e,0xeb,0xa,0x3f,0x1c,0x4b,0x4d,0xfc,0xf2,0x4c,0xda,0x69,0x92,0xd5,0x2e,0x1d,0xb,0xa,0x82,0x85,0xee,0x4d,0xe5,0xd9,0x61,0xea,0x5d,0xc4,0x40,0x10,0x7f,0x9e,0x4a,0x90,0xe0,0x58,0x1d,0x1d,0x40,0xa,0xd6,0x14,0x5,0xa8,0xf4,0xaa,0xd8,0x8d,0xaf,0x31,0xb,0x34,0x5,0x52,0x8c,0xdb,0x83,0x7a,0x19,0xf1,0x81,0x60,0x26,0x1e,0x4,0xe4,0xb2,0x60,0x8e,0xd6,0x7d,0x91,0x4c,0x7a,0x1b,0x7b,0xe2,0xb1,0x6c,0xbb,0x25,0x2f,0xaa,0x44,0x9a,0x78,0xdf,0xba,0x1c,0xaa,0xd9,0x31,0x83,0xf7,0x40,0xc,0xe8,0xef,0x71,0xab,0xf9,0x4d,0x80,0x41,0xf5,0x24,0x84,0xf7,0xbd,0x43,0x30,0x9,0x96,0x49,0xad,0x62,0x37,0xed,0x57,0xc6,0x1d,0x27,0x4c,0x92,0x79,0x5,0x86,0x90,0x8c,0x19,0xa9,0xfb,0x1,0x69,0xae,0x8d,0xc9,0x89,0xe,0xf2,0x5,0x61,0xfb,0x90,0x6f,0x70,0x15,0xfc,0xc,0xd1,0x9a,0xf4,0xb0,0xf3,0xe8,0xb,0x8e,0xbd,0xa1,0xfb,0xaa,0x92,0xe3,0x10,0x80,0xa6,0x49,0xa1,0xce,0x7,0x71,0x90,0xef,0xa,0x3b,0x21,0x20,0xb8,0xc3,0x1e,0x76,0xe1,0x1c,0xd1,0x25,0x11,0x2b,0x88,0x1a,0x1c,0xe0,0x97,0xac,0x41,0x35,0x26,0xd3,0x4e,0x12,0x76,0x2d,0x73,0x3a,0x6a,0xd6,0x5c,0x62,0xf4,0x4e,0x76,0x66,0x12,0xe4,0xa1,0x67,0x23,0x4b,0x67,0xe,0x43,0x63,0xa5,0x81,0x27,0x75,0xe,0x3a,0xb3,0xde,0x79,0x0,0xd0,0xd2,0x67,0xe1,0xae,0x75,0x66,0x2d,0xd7,0xb2,0xf5,0xd0,0x6,0x1,0x9c,0x48,0x7c,0xe6,0xb2,0x48,0x4e,0xf9,0x7a,0x6a,0x48,0x29,0xe,0x40,0x57,0xca,0xd9,0x42,0x9a,0x3a,0xb3,0x6d,0xb5,0x74,0x74,0x3,0x81,0x5a,0x7,0x8d,0x14,0x70,0x37,0x29,0x6d,0x8c,0x58,0x96,0x93,0x1,0x57,0x40,0x67,0x8,0x46,0x1,0x12,0x9b,0x8c,0xe7,0x79,0x59,0x7a,0xea,0xad,0x8c,0x75,0xa,0x20,0x29,0x8b,0xad,0xa1,0x8f,0x1d,0x6,0xaa,0xb9,0x45,0x97,0xa4,0x73,0x9,0x1c,0x33,0xd2,0xc6,0xcc,0xda,0x2d,0x2e,0xa8,0xb1,0x54,0x19,0x81,0xc1,0x3c,0x7e,0xb3,0x63,0x13,0x32,0x20,0xd6,0xbd,0xef,0x4e,0xb2,0xd,0xc9,0x12,0x7f,0xf9,0xf1,0x68,0x63,0x38,0x8f,0x19,0xe2,0x15,0x9b,0x22,0xca,0x56,0x91,0x97,0x5,0x20,0x5e,0x8c,0x53,0xdf,0xbd,0x98,0x33,0x52,0xcc,0x66,0x67,0x51,0x6b,0xb1,0xe0,0xf,0x95,0x34,0x2f,0xeb,0x9,0x84,0x93,0x85,0xa5,0x58,0x28,0x48,0x5a,0xb0,0x5d,0xce,0x66,0xdd,0xc1,0x6c,0x4e,0x6,0xfa,0xec,0xfd,0xf0,0xe3,0xee,0x8,0xba,0x35,0xa0,0x33,0xb6,0x9d,0xf7,0xae,0x6d,0x47,0x5e,0x50,0x4a,0x41,0x12,0xd9,0x76,0xa4,0xee,0x7b,0xa8,0x80,0xaa,0x7,0x24,0xbb,0xff,0x6c,0xf,0xfe,0xa8,0xb5,0x20,0xe5,0x8c,0xba,0x6d,0x1d,0xc4,0xd3,0x5,0x39,0xbf,0xd8,0x23,0x8a,0x0,0x3b,0x27,0x43,0x7a,0x46,0x1f,0x83,0xc3,0x30,0x1e,0xef,0xbc,0x5b,0x77,0x98,0x1a,0x9e,0x82,0x93,0xed,0xe7,0x81,0xdb,0x11,0x1a,0x7d,0xa4,0x3f,0xac,0x70,0x3,0xe0,0xb3,0x87,0xf,0x80,0x43,0x7d,0x7c,0x60,0xf1,0xd1,0x35,0x76,0xd8,0x57,0xe1,0xae,0xa7,0xad,0x3,0x35,0x30,0x9e,0xb2,0x3e,0xe5,0x26,0x54,0xfb,0xc,0xb3,0x2,0x98,0x20,0xe0,0xac,0x59,0xb3,0xb4,0x57,0x9c,0x87,0x60,0xd6,0xac,0x59,0xb3,0x5e,0x9c,0xf2,0xe9,0x7b,0xee,0xce,0x55,0xa4,0xbf,0xfd,0xb1,0x2e,0xbf,0xd2,0x55,0xf8,0x66,0x80,0xa0,0x4a,0x48,0xb5,0x69,0x62,0x20,0xd0,0xcb,0x4b,0xd9,0x97,0x29,0x86,0x80,0x5a,0x37,0xfe,0x4e,0x7,0xf8,0x91,0xf8,0x35,0xa9,0xbf,0x90,0x86,0x4c,0xe8,0xfb,0x75,0x1b,0x98,0x1d,0xc2,0x8d,0x2a,0x4b,0xaa,0xba,0x5c,0x4c,0x81,0xbf,0x10,0x7b,0x7a,0xa2,0x4a,0xc2,0x4c,0x6a,0x2a,0xd,0xa0,0x82,0x9e,0xca,0x1a,0xd1,0xa0,0x8c,0xa8,0x46,0xe5,0xca,0x60,0x4,0xba,0x81,0xbd,0x2,0xa5,0x6e,0x7b,0x9b,0xb,0xbc,0xb0,0x24,0xcd,0x5a,0x44,0x72,0x1b,0x87,0x40,0x15,0x3d,0xd6,0x26,0xaf,0xf1,0x3e,0x7d,0xe,0x24,0x22,0x4b,0xc7,0x85,0x49,0xbc,0x94,0x5d,0xa7,0x60,0xa3,0xb2,0x40,0x62,0xc,0xb6,0x5a,0xaf,0xaf,0xe9,0x72,0xab,0x2e,0x97,0x33,0x8f,0xa7,0x5a,0xcc,0x70,0xdf,0xbc,0x11,0x65,0x9f,0x82,0x0,0xa8,0x2c,0xdb,0x12,0x70,0x56,0x83,0x42,0xfc,0x7e,0x4,0xcf,0xba,0xc,0x57,0xfe,0x78,0xfe,0xdf,0xca,0xdc,0xb3,0x44,0x50,0x65,0x88,0x84,0x7e,0x3c,0x14,0xa8,0xeb,0x9f,0x87,0xa1,0x51,0x24,0xf5,0x4b,0x74,0x40,0xa3,0xca,0x9a,0xf5,0xfc,0xf4,0xd7,0xf5,0x4,0x61,0x6f,0x9c,0xef,0xbd,0x3,0x3b,0x18,0xb7,0x4b,0x10,0x26,0x3b,0x21,0x6e,0x5f,0xba,0xcc,0x39,0xec,0xfd,0xfd,0xa8,0xb3,0x49,0x88,0x70,0xed,0xff,0x77,0x65,0x22,0xdf,0x8c,0xd5,0x33,0x6b,0xd6,0x3b,0x5d,0x49,0x41,0x1f,0xc7,0x8a,0xf5,0x52,0x5d,0x5d,0xb0,0xd0,0x45,0x9,0x65,0xf0,0x36,0xaa,0x6,0x24,0x79,0x60,0x3f,0xc5,0xdc,0xaf,0x45,0x6a,0x8,0x31,0x21,0x86,0x64,0xe0,0x5c,0x80,0xfa,0x7c,0x46,0xa4,0xbc,0x1a,0x3,0x2e,0xb8,0x14,0xdb,0x24,0xf2,0xe1,0x56,0x2b,0x5a,0xab,0xa8,0x65,0x33,0x16,0xb0,0x8e,0xa7,0xd1,0x2d,0xa2,0x68,0xa8,0x86,0x2d,0xc0,0xc8,0xf8,0xad,0x8c,0xc3,0xb4,0x2c,0xc8,0xcb,0x9,0x1,0x1,0x79,0x5d,0x7b,0x0,0x89,0x84,0x7f,0x30,0x80,0xb8,0x22,0xc6,0x28,0xa1,0x18,0x49,0x58,0x88,0x12,0x0,0xd5,0xc8,0xe4,0xb6,0x66,0x49,0x60,0x40,0x62,0xb2,0x31,0xd5,0xec,0x13,0xd0,0xc7,0x63,0xb,0xb7,0xb2,0x71,0x3f,0x9a,0x1c,0x98,0xc7,0xa8,0x68,0xbe,0xb5,0x49,0x41,0xcd,0xda,0x90,0xc5,0xff,0x4f,0x3f,0x73,0xbd,0xbb,0xc7,0xb2,0x9c,0xcc,0x2f,0x4f,0x41,0x59,0xd,0x38,0xc9,0x79,0x65,0x50,0x4e,0x92,0x98,0x55,0x6,0x1d,0x42,0xc0,0x7a,0xba,0xe7,0xf3,0x20,0xe1,0x2c,0xfc,0x1a,0xde,0x77,0x66,0xe8,0x35,0x39,0x3f,0xc1,0x98,0x9c,0x29,0x26,0xd9,0xa6,0xec,0x82,0xa7,0x60,0xac,0xc3,0x3e,0xb7,0xf3,0x76,0x2c,0xeb,0x5d,0xf,0x53,0x31,0xbf,0xc4,0x6e,0x7d,0x10,0xf5,0xd8,0xe9,0xc0,0x18,0xae,0x83,0x51,0x2c,0x50,0xab,0x91,0x5,0x7a,0xe9,0x6f,0x4f,0xe7,0xfb,0x1e,0x12,0xe6,0xc6,0x51,0xf3,0x1b,0x1e,0xc1,0x3f,0x1b,0x8f,0xc5,0xf2,0xc1,0x18,0xe2,0x6e,0x4e,0x3d,0x6,0xf0,0x8e,0x49,0x72,0x9d,0xfd,0x4f,0x3b,0x1f,0xbe,0x3d,0xe4,0xe7,0x29,0x84,0xb4,0xfb,0x3b,0xf4,0x79,0x65,0x8f,0xb8,0x59,0x78,0xcc,0xc1,0x73,0xb4,0xbb,0x17,0x3b,0xca,0xf6,0xa0,0x67,0x88,0x8,0xde,0xc7,0xc,0xbf,0xa5,0xbe,0x99,0x6,0x1b,0x80,0x99,0x58,0x3f,0x6b,0xd6,0xac,0x9,0x0,0xce,0x9a,0x35,0x6b,0xd6,0x8b,0x3a,0xa8,0xa7,0x71,0x58,0xd7,0x6,0x46,0xfd,0xd8,0xbc,0x7f,0x1e,0x35,0xcf,0xf2,0x52,0xa6,0x58,0x63,0xd0,0x4b,0x99,0x58,0xce,0xfb,0xcf,0x58,0x5,0xad,0xcb,0x26,0xcd,0x13,0xca,0x6e,0xf4,0x83,0x35,0x44,0xcb,0x7a,0x12,0x8f,0xa5,0x68,0x6c,0xad,0x2e,0x3d,0xf2,0xc,0x41,0xfe,0x86,0x94,0x96,0x21,0xac,0x4,0xfb,0xf0,0x92,0x41,0xea,0x49,0xe,0x24,0xe2,0x6d,0x55,0x3f,0x3b,0xf5,0xfb,0x6b,0x8d,0x41,0xaa,0xda,0x6a,0x7,0xc3,0x34,0xd0,0x64,0x8,0xa9,0xa0,0xbe,0xfe,0xaf,0xc1,0x1a,0x20,0xe7,0x8d,0x28,0xcd,0x5b,0xf0,0x37,0xd4,0x86,0xa,0xf5,0xfd,0x33,0x66,0x9b,0x34,0x34,0x2,0x52,0x2a,0xc8,0xa9,0xcd,0x82,0xca,0x8f,0xbb,0xf7,0x54,0x71,0xcc,0x49,0x7f,0xf,0xaf,0xac,0xe,0xf5,0x3f,0xec,0x72,0x57,0x6a,0xc2,0x58,0x69,0xa,0x54,0x76,0x50,0x4d,0xd9,0x3d,0xda,0x2c,0x6b,0xa3,0xaf,0x1e,0x59,0xda,0x14,0x69,0xa3,0xa0,0xc0,0x1e,0xcb,0x2,0x43,0x7,0x14,0x6b,0xed,0x80,0x97,0xb0,0x11,0xb5,0x51,0xed,0x8d,0x3b,0x39,0x9,0x6f,0x14,0xa3,0xfd,0xe,0xf2,0xc2,0xf9,0x5c,0x29,0x88,0xe7,0x19,0x82,0xc6,0x3c,0x74,0x0,0x9b,0x9e,0xa3,0x2e,0xe9,0xed,0xf2,0x46,0x52,0xd0,0xd5,0x7c,0x29,0x69,0xdc,0x8e,0x80,0x1d,0xd0,0x8c,0xc1,0x2c,0xde,0xcb,0xc8,0x7,0x66,0xc9,0xde,0x4f,0x6a,0x90,0x25,0xfb,0x67,0x7a,0x47,0x16,0xe2,0x14,0x51,0xcc,0x7a,0x3e,0x55,0xb7,0x6d,0x40,0x6,0xf4,0x67,0xda,0x64,0x41,0xc3,0xfb,0x75,0x2a,0xeb,0x55,0x1,0xb6,0x5a,0x78,0x4c,0xce,0xe2,0x1d,0xa7,0x72,0xdf,0x65,0x39,0x31,0xb8,0x28,0xd7,0x78,0x93,0xc4,0xd7,0x94,0x35,0x91,0x36,0xca,0x67,0xf0,0xf5,0xa1,0x5e,0xa5,0x7e,0xf1,0x81,0xd3,0x71,0x17,0xf6,0xad,0xbb,0xbb,0x47,0x5e,0x56,0x5b,0x34,0x50,0x16,0x73,0x36,0xcf,0x3a,0xc,0xe3,0x70,0x90,0xb1,0x77,0x3d,0xdd,0x49,0x42,0x31,0x33,0xd2,0x4e,0xf7,0x8f,0x64,0x5e,0xc9,0x6,0xc4,0xa9,0xef,0x5d,0x13,0xfb,0x81,0x28,0xa0,0x1a,0x81,0x38,0x44,0x23,0x67,0x59,0x9b,0x8,0x28,0x6e,0x4c,0x4a,0xc2,0x38,0x24,0xa2,0x21,0xf4,0xc3,0xfc,0x6,0xdd,0xb8,0xa6,0x73,0x8e,0x6,0x6c,0x30,0x68,0xda,0x3,0x97,0xd6,0xf5,0x6e,0x38,0x76,0xc,0xfe,0x91,0x7d,0x7e,0xce,0xab,0x4,0x66,0x30,0x10,0xa8,0xcc,0xca,0x26,0x81,0x27,0x51,0xc0,0xba,0xf5,0xee,0x4e,0xbc,0xfe,0x16,0xdc,0xbf,0xf4,0x8a,0x79,0xeb,0x32,0xc0,0xc9,0x0,0x6c,0x5e,0x4f,0x38,0xc9,0xf1,0xd4,0x24,0xe0,0xd3,0xdd,0x3d,0x7b,0x26,0x6,0x60,0x59,0xf9,0xf3,0xd4,0x1f,0x50,0xe7,0x65,0x3e,0x77,0x77,0x96,0xe6,0xab,0xc0,0x64,0xce,0x1a,0xb8,0xd5,0x6c,0x5f,0x9b,0xcc,0xa3,0xea,0x27,0x48,0xa,0x2,0x6,0xf1,0xe,0x76,0x0,0x56,0xc7,0xc1,0x64,0xd1,0xaa,0xb5,0x21,0x7c,0x49,0xcf,0x8b,0xe1,0x5e,0x9a,0x2e,0xef,0x24,0xc1,0x3e,0xa5,0xd7,0xfb,0xc2,0x1e,0x7b,0xb9,0x1a,0x5f,0x7d,0xc0,0xc3,0xc6,0xb1,0x19,0x3,0xc0,0x47,0xc3,0xdf,0x23,0xf0,0xa7,0xfb,0x42,0x57,0x88,0x5c,0x70,0x61,0x61,0xc3,0x84,0x70,0x1d,0xc4,0x61,0x6f,0x3d,0x8a,0x14,0xde,0x6d,0xda,0xce,0x9f,0xf0,0xa,0xd8,0xbb,0x5,0xfc,0x1d,0xbd,0x9e,0x6e,0xe3,0x79,0x4e,0x67,0xd0,0xc1,0xd3,0x7d,0xba,0xfd,0xac,0x59,0xb3,0xfe,0xcc,0xd7,0xbc,0x7b,0x9d,0x35,0x6b,0xd6,0xac,0x17,0xa9,0x76,0x26,0xd0,0x7a,0x53,0x4f,0xc2,0x3e,0xd0,0x9b,0xe9,0x2e,0x11,0x42,0x7,0x42,0x42,0x44,0x74,0xbe,0x7f,0xfe,0x73,0x94,0xad,0xa5,0xac,0xa,0xf5,0x7d,0xeb,0x7e,0x3f,0x70,0xd2,0x9d,0x66,0xf2,0x26,0x6d,0x90,0x52,0xce,0x7c,0xf,0x1d,0xfb,0x5d,0x75,0x97,0x90,0x91,0x31,0x24,0x54,0x9a,0x55,0xc4,0x13,0x49,0x93,0x1d,0xd5,0x83,0xaf,0x4b,0x85,0x1c,0xdb,0xc,0x9d,0x95,0xc0,0x8d,0x8,0x19,0x4b,0xe,0xd0,0x6,0x26,0x75,0xd9,0xaa,0xf8,0x0,0xf6,0x64,0xbe,0x60,0xf7,0xf7,0x49,0x81,0x38,0x35,0x7e,0xf,0xa3,0x74,0x48,0xfd,0xab,0xd4,0xb3,0xb0,0x3,0x5b,0x9c,0x9a,0x18,0x5d,0xf3,0x18,0x55,0x76,0xa3,0xe9,0xb8,0x94,0xc4,0xd7,0xb0,0x3a,0xb6,0x99,0x0,0xad,0xe6,0x7f,0xd4,0xc,0x1c,0x34,0x66,0x9e,0x3,0xb3,0x92,0x48,0xf8,0x5a,0x6d,0x8e,0x35,0x13,0xc,0x78,0xec,0x69,0x92,0x2,0x44,0x6a,0xa2,0xb3,0xc8,0xb9,0xb2,0xa4,0x52,0x52,0x37,0x62,0xb2,0x70,0x12,0x95,0xf6,0xc1,0x79,0xf5,0xc1,0x5,0xb8,0x20,0x4,0x96,0x17,0x1a,0x88,0x49,0x68,0xb5,0x39,0x66,0x60,0xed,0xcc,0x1a,0x67,0x0,0x6f,0x9e,0x8e,0x29,0x9a,0x44,0x4c,0xa5,0xce,0x1a,0xd2,0xa2,0x40,0xaa,0x97,0x12,0xc7,0x18,0xd0,0x93,0x3e,0xf9,0xdf,0x8d,0xaa,0x49,0x0,0x3b,0x80,0xd8,0x9c,0x5c,0xb8,0x33,0x1d,0x3d,0x2b,0x70,0x9f,0x90,0xba,0x97,0x98,0xed,0x93,0x24,0x3b,0xb,0x46,0x2e,0xaa,0xb0,0x7,0x66,0x67,0xcd,0x7a,0xce,0x43,0xbd,0x63,0x28,0xe9,0xb5,0xae,0xc1,0x45,0xd1,0xa7,0xa5,0x8b,0x5c,0xb5,0x6e,0xd5,0x58,0xd7,0x21,0x0,0xb5,0xf6,0x54,0x5c,0x5,0xf7,0x62,0x48,0xe,0x4,0xec,0x8c,0x42,0xd,0x83,0x88,0x31,0xa2,0x5c,0x2e,0xf6,0x7c,0x8c,0x11,0x65,0xbb,0x8,0x8,0x97,0x70,0x79,0x78,0x2,0x28,0xb8,0x54,0x35,0x14,0xa9,0x8a,0xcf,0x20,0x7,0x5b,0x4,0x27,0x5,0xd5,0x6d,0x41,0x60,0xd9,0xb0,0xfa,0xfc,0xa5,0x9c,0x4d,0x6,0xab,0x73,0x4,0x4b,0x57,0xa3,0x5,0x88,0x90,0x3,0x21,0x75,0x8c,0xd1,0xd4,0x5d,0x65,0x12,0xb2,0x6c,0x77,0x19,0x12,0xd6,0x4b,0x65,0x8f,0xbb,0xa2,0x52,0x69,0x9d,0x4b,0x64,0x5c,0x6,0xb0,0x5b,0xa4,0xe2,0xe7,0x3d,0xa3,0xce,0xe4,0xb8,0x2,0x1a,0xea,0x58,0xa5,0xb,0x17,0x69,0x3d,0xf1,0xe7,0x35,0x49,0x41,0xf,0x11,0xf1,0xc4,0xf2,0x5e,0x66,0x2b,0xe6,0xee,0xa9,0x48,0x40,0xcc,0xc9,0xd8,0x73,0x31,0x25,0x4,0xf4,0xe7,0x95,0xc1,0xd8,0xd4,0xeb,0xf,0xc9,0x7c,0x6f,0x75,0x5b,0x79,0xbe,0xcb,0x3,0x80,0x1b,0x88,0xa0,0x53,0x47,0xa3,0x20,0xc1,0x26,0xdd,0xfb,0x90,0x3d,0x1c,0x13,0xca,0xe5,0xcc,0xe1,0x53,0x29,0x83,0xa2,0x8c,0x8d,0x9b,0xf3,0x6a,0x15,0x76,0x5f,0xbf,0x17,0x88,0x6,0xea,0x59,0x28,0x93,0xce,0xd,0x6e,0x21,0x70,0x40,0xbf,0x4,0x0,0xb3,0x70,0x2a,0x37,0xce,0x6,0xf1,0xf7,0x83,0x3d,0x86,0x2b,0xd9,0xef,0xc8,0xc7,0xe,0xc3,0x5c,0xe9,0xef,0x53,0xfa,0x8b,0x83,0x9b,0x57,0xe9,0x1a,0x40,0xb,0xde,0xfe,0xc1,0x7f,0x34,0xbd,0x75,0x2a,0x8,0xbd,0x8d,0x7b,0xb0,0xb7,0x7a,0xf,0x3d,0xeb,0x6d,0x9d,0x5c,0x8b,0x74,0xfd,0xd8,0xe8,0x5f,0xa8,0x8c,0xc7,0x36,0x7a,0x28,0xce,0x9a,0x35,0x6b,0xd6,0x4,0x0,0x67,0xcd,0x9a,0x35,0xeb,0xc5,0x6d,0xa,0xf7,0x2b,0xe5,0xe4,0x64,0xc0,0xc6,0x9a,0x43,0xb3,0xa4,0xc2,0xa8,0x8c,0x38,0x62,0x6,0x9,0x42,0x97,0x8f,0xa9,0x8f,0x52,0x0,0x3f,0x67,0x37,0xf8,0x31,0x59,0xda,0xab,0x49,0x64,0xe5,0xe6,0x3a,0x25,0x6d,0x12,0xb3,0x81,0x5f,0x29,0x66,0xd4,0x56,0xc,0x18,0x8a,0xc2,0xac,0x8b,0x31,0x71,0x23,0x16,0x2,0x96,0xf5,0x84,0x72,0x39,0x1b,0x1b,0xc3,0xe4,0x9a,0xda,0x78,0x39,0x40,0x33,0x99,0x87,0x55,0x36,0xc0,0x4e,0xef,0x8f,0x93,0x0,0x77,0x54,0xab,0xf8,0x50,0x11,0x62,0x6c,0xe6,0x7f,0xa8,0x7f,0xb7,0xd6,0x7d,0x7,0x15,0xa8,0xd4,0x66,0xb3,0x83,0x6a,0xcd,0x2,0x3a,0xa8,0x55,0x34,0xea,0xfb,0xaa,0x8c,0xb8,0xe6,0x40,0x2e,0xf3,0xec,0x8b,0x9d,0xf5,0x68,0xec,0x8,0x10,0xa8,0xb6,0xc1,0x9f,0xc9,0x0,0x28,0xc0,0x3c,0xaf,0x54,0xfe,0xdb,0xac,0xc9,0xb,0xe6,0xb3,0x55,0x5b,0x31,0xa6,0x8b,0x32,0x0,0x95,0xdd,0x67,0x80,0x9d,0x4f,0x79,0xa6,0x9e,0xa8,0xec,0xe5,0xd1,0x2c,0x9,0xd7,0x84,0x45,0x96,0x75,0x37,0xe7,0x95,0xa5,0x80,0x9b,0x7a,0x46,0x69,0xd3,0x16,0x4,0xe8,0x54,0x80,0x34,0x4,0x1a,0xd8,0x99,0x3d,0x31,0xd3,0x7b,0xe5,0xf1,0xef,0xae,0x96,0x62,0x4d,0x6a,0x73,0x20,0xa8,0x2,0xc7,0x4d,0xc3,0x67,0xdc,0x6f,0x39,0xc4,0x8,0xb4,0x7e,0xee,0x54,0x4e,0xa8,0x8c,0x54,0x4b,0x35,0xe,0xc1,0x7d,0x56,0x4,0xa8,0x87,0x0,0x1c,0xb1,0x46,0xba,0xdc,0x8c,0x46,0xf,0xf6,0xa1,0x61,0x1a,0xfd,0x1,0x9f,0x2d,0x2f,0x72,0xd6,0xac,0x3f,0xf9,0xd2,0xeb,0x98,0x5c,0xc2,0x28,0x83,0xfc,0xd5,0x7e,0xdf,0x31,0x44,0x54,0xaa,0x58,0x16,0x66,0xa2,0x65,0x1,0xe7,0x3b,0x23,0x50,0xd3,0x7e,0xa3,0x81,0x68,0x29,0x2d,0x1c,0x34,0x14,0x94,0xe1,0xda,0x3d,0xde,0x62,0x4c,0xc,0x48,0x2d,0x2b,0x7,0x85,0xa4,0xcc,0x81,0x11,0xe2,0x97,0x4a,0xad,0x62,0x59,0xd7,0x21,0xf5,0x5c,0xc7,0xd5,0xf5,0xee,0x91,0x4,0x83,0xf4,0x39,0x25,0x9a,0x7d,0x1,0x33,0xd7,0xe0,0x43,0x39,0x1c,0xfb,0xf0,0x72,0x3e,0xe3,0x74,0x77,0x27,0x60,0x54,0x7,0xe0,0xd7,0xbb,0x7b,0x1e,0x33,0x53,0x46,0x6d,0x55,0xbe,0xff,0x64,0x8c,0xea,0x4b,0xab,0xc8,0x62,0x2d,0x51,0xcb,0x86,0x2a,0x21,0x4e,0xb1,0xa5,0x21,0x50,0x28,0x80,0xc1,0x2b,0x22,0x96,0x14,0xab,0x7,0x9f,0x26,0xb1,0xeb,0xb8,0xea,0x17,0x11,0xe0,0x93,0x91,0x73,0xf7,0xd4,0x53,0xfb,0x82,0x5a,0xd8,0x9b,0x2f,0x81,0x41,0x4c,0x1d,0x87,0xd6,0xd3,0xbd,0xb0,0x25,0x49,0xe6,0xbc,0x3b,0x7b,0x2f,0xb3,0x29,0x31,0xb0,0x2a,0xd9,0x17,0x50,0xfc,0x6e,0x63,0x42,0x82,0x58,0x5a,0x2c,0xd1,0x6c,0x18,0x72,0x5e,0x6c,0x64,0xaa,0xad,0x22,0x10,0x4b,0x79,0xf3,0xca,0x80,0xe2,0x76,0xb9,0xd8,0xb9,0x4e,0x21,0x48,0x20,0x57,0xf7,0x55,0x4d,0x79,0x41,0x50,0x76,0x3c,0x5c,0xc8,0x92,0xf7,0x7b,0xd5,0x39,0xc8,0x12,0x84,0x65,0x7e,0xd3,0xe4,0x65,0x4,0x50,0xc0,0x75,0x28,0x18,0xdc,0xfc,0xe0,0x17,0x5f,0xdc,0x38,0xbb,0x97,0xfe,0xfa,0x71,0xbb,0x7,0x51,0x39,0xf0,0x4f,0xee,0x39,0x3a,0xf2,0x45,0xdd,0x8a,0xc2,0xb3,0xf2,0x2c,0x29,0x78,0x37,0xc0,0x7,0x37,0x7e,0xbb,0x10,0xaa,0xe1,0x45,0xb7,0x18,0x7a,0xf4,0x16,0x0,0xdd,0xd,0x90,0x8f,0x76,0x9b,0xf2,0xac,0x9f,0x71,0xcd,0x5f,0xec,0x20,0x5f,0xb8,0xd2,0x5,0x8f,0xaf,0x51,0x4b,0x15,0x22,0x9a,0x73,0xd5,0xac,0x59,0xb3,0x26,0x0,0x38,0x6b,0xd6,0xac,0x59,0x2f,0x6c,0x85,0xe,0x70,0x28,0xb8,0xa3,0x9e,0x6b,0x6c,0x9c,0x2e,0x3e,0x79,0xe6,0x61,0x26,0xa0,0x1a,0xf5,0xe0,0x5,0x35,0x60,0xf,0x8e,0x1,0xd0,0x84,0xfd,0x87,0xe8,0xc,0xb5,0x63,0x2,0x24,0x4d,0x32,0x68,0xe8,0x86,0x48,0x3e,0xd3,0xb2,0x48,0xf3,0x7,0x94,0xd2,0xac,0xb1,0x63,0x90,0xb1,0x5a,0xa3,0x14,0x63,0x44,0x6c,0xd,0xcb,0xb2,0xa2,0x94,0x8b,0xb0,0x1d,0x64,0x57,0xc4,0x18,0xbe,0xb6,0x8a,0x14,0x93,0x81,0x3e,0xb5,0x55,0x36,0xf,0xf,0x30,0xd0,0x48,0x3d,0xf1,0x52,0x4c,0x3,0x20,0x18,0xe4,0xce,0x9b,0x99,0x27,0x3d,0x39,0x93,0x13,0x8f,0x7b,0x22,0xae,0x36,0x28,0x81,0xc2,0xc0,0x88,0xf3,0xd2,0x5d,0x0,0xc6,0x3e,0xe9,0x0,0x5b,0x33,0x46,0x44,0x8,0x11,0xad,0x70,0x63,0x6b,0xac,0x40,0xea,0x52,0x3a,0xf3,0xc8,0xab,0x15,0x51,0x7d,0x11,0xed,0xb4,0x5,0xa4,0xc4,0xfb,0x6,0x49,0xe5,0xd5,0xc6,0x27,0xa6,0x8,0xaa,0xca,0xc8,0x20,0x63,0xec,0xd4,0x52,0xc,0x4c,0xcc,0x92,0xfc,0xa8,0x8d,0x5a,0xcf,0xc7,0x8,0xce,0x6b,0x2b,0x98,0x27,0xd7,0x1e,0xe4,0xec,0x4d,0x7f,0x44,0x6b,0xa1,0xe3,0x5f,0xad,0xf1,0x79,0x95,0xe3,0xaa,0xc4,0x8b,0x1,0xf0,0x8b,0x11,0x54,0xab,0x63,0xf6,0x71,0xc2,0xb0,0x5,0x75,0x74,0xd4,0xcd,0xfe,0xaf,0x4c,0x1d,0x95,0x1c,0x57,0xd,0x74,0x71,0x60,0xa8,0xbe,0x67,0x48,0x22,0x76,0xbe,0x8b,0xe4,0x80,0x4e,0x6b,0x24,0xd9,0x75,0xbe,0x33,0x4e,0x42,0x1c,0x19,0x7f,0x34,0x26,0xfa,0x6,0xf2,0xd,0xd3,0xe8,0x2e,0x3f,0x9e,0x9f,0x51,0x9e,0x66,0xe1,0x2b,0xb3,0x66,0x3d,0x8f,0x61,0x5e,0xc7,0x27,0x5,0x39,0xd4,0x67,0x8f,0xe0,0x24,0xf8,0x5c,0x9c,0xdc,0xab,0xc0,0x5a,0x45,0xce,0xd9,0x16,0x32,0x78,0x9c,0x4f,0x6,0xee,0xeb,0xbf,0x63,0xce,0x78,0xfd,0x83,0xef,0xc5,0x7b,0x5f,0x7d,0x85,0x81,0xa5,0x5a,0x5,0x14,0x2,0xbe,0xf0,0xa5,0xaf,0xe0,0x77,0xbf,0xf4,0xf5,0xce,0x6,0x96,0x5,0x91,0x80,0x68,0x81,0x1a,0x9e,0xf5,0x1d,0x63,0xb7,0x6,0xd0,0xc5,0x84,0xbc,0xac,0x3,0x58,0x54,0x2e,0x67,0xa4,0xbc,0xe0,0x94,0x2,0x3e,0xf5,0xf1,0xf,0x8b,0x8c,0x35,0x99,0x44,0xf5,0x72,0xb9,0xe0,0x9f,0xfc,0xd6,0x1f,0x30,0x40,0x27,0x8b,0x4b,0xb5,0x56,0xe4,0x75,0x45,0xdd,0x36,0xa4,0x94,0xf0,0xe1,0x6f,0x7b,0x1f,0x5e,0x79,0xe5,0x91,0xb1,0xb0,0xd5,0x1e,0xe0,0xb7,0x7f,0xef,0xb,0xf8,0xc2,0x57,0xbe,0x81,0x10,0x8b,0x59,0x25,0xd8,0xf1,0x68,0x15,0x31,0x67,0x94,0x6d,0x13,0x5f,0x42,0xc8,0x67,0x17,0x2c,0xcb,0xa,0x84,0x20,0xa9,0xb8,0x8b,0x24,0xc0,0xf3,0xa2,0x13,0x9f,0xd3,0x7d,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x88,0x7a,0xf,0xc6,0x94,0xf1,0xfa,0xb7,0xbc,0x8a,0x57,0x5f,0x79,0x24,0x63,0x9e,0x30,0xed,0x43,0xc0,0x17,0xbf,0xfa,0x26,0xfe,0xe0,0x8f,0xbe,0xc6,0x0,0x9d,0xd8,0x51,0x84,0x10,0x70,0xba,0x7b,0x84,0xd6,0x1a,0xde,0xf3,0xca,0x23,0x7c,0xe8,0x83,0xef,0xed,0xe3,0x8f,0x97,0x6e,0x23,0x20,0xb8,0x60,0x9,0x5d,0x54,0xe1,0xb1,0x58,0x82,0x34,0x88,0xf0,0x70,0xd9,0xf0,0xf0,0x70,0x46,0xa9,0x15,0x8f,0x1f,0x36,0xbc,0xf1,0xe4,0x8c,0x4b,0xe9,0xbe,0x8b,0xb5,0x35,0xb6,0xe2,0x10,0x60,0x58,0xcf,0x3,0xfb,0x34,0x32,0x78,0x5a,0x68,0x43,0xa0,0xd0,0xd9,0x93,0x0,0xb6,0xed,0x82,0xb4,0x2c,0xf6,0xbe,0x65,0x3d,0xa1,0x98,0xa7,0x23,0x5c,0xc8,0x95,0x32,0x0,0xc9,0x6c,0x29,0x94,0x81,0xa9,0xe7,0x6e,0x4,0x4,0xbb,0x84,0xfa,0x1a,0x63,0xbb,0x5e,0x60,0xa1,0x2b,0x70,0xe,0x16,0x28,0x45,0x81,0xe0,0x6d,0x4a,0x86,0xf,0xb3,0xf5,0x1a,0xba,0x6,0xf5,0xfc,0x57,0xd1,0x8,0xe,0x12,0xed,0x7c,0x1,0x9f,0x65,0x88,0x27,0xc,0xc0,0xdd,0x11,0x90,0xb7,0xf,0xf6,0xd,0x87,0xaf,0xb,0x57,0xef,0x57,0xff,0xc2,0xee,0x63,0x78,0xf4,0x1d,0xc7,0xaf,0x31,0xab,0x8d,0x30,0xa7,0xaa,0x59,0xb3,0x66,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x5e,0xdc,0xf2,0x66,0xd4,0xce,0xf7,0xcd,0x16,0xc7,0xe5,0xff,0x51,0x40,0xc0,0x18,0x93,0xad,0x14,0xc3,0xa5,0xb3,0x76,0xb0,0x45,0x99,0x66,0x0,0x25,0xf1,0xe9,0xd3,0x55,0x65,0x95,0x9b,0xca,0x6b,0xb5,0xd1,0x50,0x66,0x98,0xb2,0xba,0xd4,0xb0,0x5c,0x41,0x2a,0x34,0x74,0x0,0x2b,0x65,0xa4,0x4c,0x3,0x28,0xd8,0x93,0x55,0x59,0x1e,0xba,0x4a,0xda,0xa1,0xb2,0x13,0x34,0x51,0xd2,0x8c,0xc5,0x45,0xf2,0xea,0x65,0xa7,0xca,0xe,0x8b,0xc2,0x10,0x34,0x6,0x9b,0x80,0x95,0x9a,0x1a,0xd9,0x3d,0x8e,0xc4,0x9c,0x3e,0xb2,0x54,0x75,0x48,0xe8,0x43,0x40,0x93,0x64,0xc8,0x2a,0xec,0x9,0x66,0xe1,0x39,0x3,0x74,0x49,0xb0,0x55,0x6,0x5f,0xca,0x8b,0x5,0x7a,0xf8,0x3b,0xf0,0x56,0x3b,0xb,0xb2,0xd5,0xc6,0xe0,0x5e,0x23,0x6e,0x66,0x84,0x49,0x61,0x12,0xa6,0xd8,0x4d,0xf3,0x43,0x64,0x10,0xd6,0x92,0x76,0x89,0xba,0x14,0x4e,0x9a,0x4b,0x9f,0xc4,0xa9,0x8d,0x19,0xb3,0x6d,0x8a,0xf3,0xe9,0xa,0x1d,0x80,0x53,0x86,0x24,0x75,0x46,0xa5,0x4f,0x2,0x56,0x76,0x4e,0x35,0xf6,0x5d,0xe2,0x6d,0x8,0xda,0x5c,0x34,0x97,0xba,0x1c,0x2d,0xc,0x65,0x1f,0x74,0xa2,0xc7,0xa4,0x39,0x18,0x8d,0xe5,0x62,0xc9,0xfc,0xd5,0x7d,0x93,0x18,0x42,0xb4,0x64,0x67,0x5,0xa2,0x15,0x84,0xd0,0xef,0xeb,0x0,0xa6,0x36,0x8a,0x23,0x10,0x8,0x35,0xa7,0x77,0xe0,0xa3,0x97,0x4,0x7b,0x10,0x74,0x24,0x88,0x4,0x74,0xf6,0x8,0x46,0x8f,0x27,0xf7,0xcf,0x80,0x80,0x7c,0xff,0x6e,0x6c,0x8f,0xbf,0x32,0xc7,0x9c,0x59,0xcf,0x1,0x0,0x8c,0x96,0xea,0xaa,0xd7,0x84,0xb2,0xb4,0x95,0x61,0x7,0xe7,0xa3,0xc9,0xcc,0x6d,0xfe,0xf1,0x96,0xb2,0x99,0x4f,0xab,0x6,0x1e,0x31,0xa0,0x15,0x84,0x85,0xcc,0xde,0x78,0x3f,0xf9,0xe3,0x3f,0x8c,0xef,0xfb,0xf4,0xc7,0xa1,0xe9,0xc2,0x7a,0x6d,0xfd,0xaf,0xff,0xfb,0x2f,0xe3,0x6f,0xfc,0xed,0x9f,0xe7,0x71,0x44,0xc6,0x39,0x95,0xa1,0x6,0x1d,0x43,0x88,0x7d,0xa,0x17,0xf1,0xa8,0xe3,0xf1,0x8e,0x3,0x48,0x16,0x4b,0x58,0xf,0xc8,0xcb,0x9d,0x80,0x71,0xbc,0x9d,0xdf,0xf6,0xfe,0xf7,0xe0,0x3f,0xfa,0xf7,0x7e,0x4a,0xac,0x20,0xc8,0x58,0xcc,0x8f,0x9f,0x3c,0xc1,0x7f,0xfe,0xd7,0xff,0x3b,0x7c,0xe3,0xf1,0x19,0xcb,0xe9,0x8e,0xb7,0x59,0x80,0x35,0xd,0xb6,0xf8,0xb7,0xff,0xca,0x5f,0xc2,0xeb,0xdf,0xf9,0xad,0x3b,0x40,0x85,0xf0,0x3f,0xfe,0xdd,0x5f,0xc0,0xdf,0xfe,0x7b,0xbf,0x8,0x66,0xbd,0x31,0x0,0x57,0xca,0x86,0xb2,0x6d,0xc,0xda,0xb9,0xc4,0xdb,0x26,0xc7,0x2c,0x26,0x1e,0x2f,0x35,0x68,0x43,0xe7,0x81,0x14,0x73,0xf,0x2c,0x4a,0x19,0x20,0xc2,0xbf,0xf9,0x97,0x7f,0xc,0x1f,0xfb,0xe8,0x87,0xaf,0xd0,0xa2,0x9f,0xf9,0x9f,0x7f,0x1,0x3f,0xf3,0xb,0xff,0xf,0x7f,0x5e,0xe,0x8,0x8d,0xbf,0x8b,0x25,0xce,0xb,0x3e,0xf9,0xe1,0x6f,0xc5,0xbf,0xfb,0x53,0x3f,0x7e,0xed,0xf,0x87,0x3,0xab,0x82,0xdd,0xd8,0xe6,0x7d,0xf3,0x78,0xdc,0xe6,0x39,0xee,0xcd,0x27,0x4f,0xf0,0xe5,0xaf,0x7c,0x3,0xff,0xe2,0xf7,0xbf,0x88,0x5f,0xff,0xfc,0xef,0xe0,0x37,0x7e,0xfb,0xf,0xf0,0x70,0xd9,0xba,0x97,0x9e,0xcc,0xbb,0xea,0xdf,0xdb,0x88,0x17,0xac,0x90,0xba,0x3a,0xa0,0xd5,0x82,0xbb,0x47,0x2f,0x1b,0x13,0xd2,0xd2,0x93,0x43,0x67,0x9d,0xe9,0x2,0x1b,0xa0,0xc7,0x2b,0xf4,0x60,0x28,0x37,0x50,0x2a,0xcb,0x70,0x60,0xb2,0xf7,0x54,0x25,0xf3,0xca,0x85,0x93,0xb3,0x76,0x80,0xee,0x88,0x32,0x47,0xce,0xbb,0xf,0x23,0xf8,0x77,0x84,0x74,0x19,0x8,0x88,0x6b,0xff,0x3c,0xc2,0xc1,0xb8,0x7e,0xf5,0xf3,0xb9,0xfe,0xb8,0xb7,0xba,0x36,0x1d,0x90,0xd7,0x41,0x3c,0xb8,0x34,0xf9,0x3d,0x5b,0xcf,0x2f,0x2f,0x85,0x3,0x20,0xef,0x9a,0x9,0xd8,0x8f,0x15,0xdd,0xfc,0xac,0x71,0x31,0x6b,0x82,0x80,0xb3,0x66,0xcd,0x9a,0x0,0xe0,0xac,0x59,0xb3,0x66,0xbd,0xa0,0x9d,0xe1,0xad,0x87,0xdc,0x4d,0x26,0x11,0x80,0xe6,0xfe,0xd,0x1,0x88,0x8a,0xdd,0xd0,0xfb,0xb0,0x8,0x4d,0x4b,0x54,0x3f,0x37,0x72,0xec,0x28,0xf5,0x74,0x8a,0x79,0x11,0xd9,0x56,0x46,0x90,0xc6,0xb0,0x83,0x3a,0x64,0xde,0x7e,0xd6,0xec,0x29,0x5b,0x8c,0x7a,0xc2,0x6e,0xa9,0x17,0x4b,0xe,0xae,0xa5,0xa0,0x6c,0x17,0x6,0xa,0x5,0x68,0x6a,0x55,0x64,0x6f,0x1,0x88,0x22,0x4f,0xab,0xd2,0x54,0xaa,0xec,0x2b,0x68,0x43,0x24,0xec,0x18,0x3,0xfe,0xa4,0x59,0x68,0xb5,0x74,0x70,0x4e,0xb6,0x3f,0xa5,0xd4,0x8d,0xe2,0x43,0x0,0x55,0x6,0x3e,0x63,0x88,0xe6,0x4d,0xe8,0xd9,0x73,0xcc,0xe2,0x2b,0x63,0x12,0x22,0xc9,0x71,0xa,0x9,0xb5,0x5d,0x3a,0x40,0x25,0x12,0x56,0x9f,0x40,0xab,0x77,0xe3,0x29,0x25,0x1,0xb5,0x98,0x3d,0xa3,0x52,0x68,0x4e,0x62,0xe,0x40,0xeb,0xec,0x35,0xbf,0xda,0x1f,0x2,0xb3,0x75,0xc8,0xe4,0xaf,0xfb,0xc6,0xa4,0xb3,0xea,0xe0,0x4d,0xf6,0x5d,0x18,0x89,0xfa,0x35,0x29,0x90,0xda,0x13,0x30,0x17,0x91,0xc3,0x11,0xa8,0xc2,0x7c,0xbf,0xb4,0xd1,0xec,0x19,0x32,0x34,0xec,0x93,0x97,0x21,0x6b,0xca,0x27,0x9,0xd0,0x68,0xa1,0x31,0x4e,0xe,0xa6,0x69,0xd2,0xad,0x56,0xa0,0x39,0x26,0x9,0xe0,0x18,0x9c,0xc1,0x98,0x93,0xc1,0x40,0x8c,0x2e,0x17,0x26,0x97,0xe,0xc9,0xf2,0xf6,0x66,0x4d,0xa1,0x32,0x80,0xae,0x80,0x41,0x74,0xc0,0x70,0xdf,0xc8,0x92,0x37,0x73,0xf,0xbb,0xbf,0x87,0xa6,0x90,0xf7,0xa3,0x9e,0xdf,0x98,0xe3,0xcd,0xac,0xe7,0x52,0x1e,0x48,0x19,0x12,0xb3,0x63,0x14,0xc0,0x3f,0xc9,0xb8,0xd1,0x41,0x8,0xb3,0x14,0x10,0x50,0x50,0x41,0x34,0x5d,0x1c,0x8,0x91,0xc7,0x42,0x10,0x21,0xa4,0x84,0x80,0x6b,0xf6,0x96,0x6,0x4c,0xf0,0x58,0x4b,0x43,0x60,0x8f,0x32,0x93,0x75,0xfb,0x9a,0xf8,0xb7,0xea,0xb5,0x9c,0x97,0x55,0xc6,0xa5,0x82,0xbc,0x2c,0x16,0x50,0xa4,0x32,0x5a,0xb,0xe6,0x40,0x67,0x2f,0xeb,0xbf,0x43,0x8,0x28,0xdb,0x86,0x52,0x8a,0x24,0xaa,0x67,0x4b,0x37,0xcd,0xf2,0x1e,0xec,0xd2,0xbd,0x3d,0x1c,0x53,0xb6,0xb,0xbf,0x7,0xcd,0xc0,0x2f,0x5d,0x20,0xab,0x75,0x43,0x5e,0x16,0x94,0xcb,0x5,0xad,0x56,0x9c,0xee,0x4f,0x92,0x60,0xcc,0x8b,0x4d,0xcb,0xb2,0xca,0x42,0x4b,0x1b,0xbc,0xec,0xca,0x76,0xc1,0x7a,0x77,0x8f,0x94,0xd7,0x61,0x7b,0xb5,0x92,0x4,0x7d,0x98,0x87,0xab,0x2c,0x92,0x65,0x49,0x70,0x66,0x16,0x38,0xe,0x80,0xac,0x7e,0xac,0xfd,0xdf,0xb7,0xfe,0xcd,0xe9,0xc7,0xfc,0xd8,0xe9,0xb4,0xe2,0xb5,0x57,0xdf,0x8d,0x8f,0x7d,0xe4,0x3b,0xf0,0x17,0x7f,0xe4,0xb3,0xf8,0xfa,0xd7,0xdf,0xc0,0x3f,0xfb,0xfc,0xef,0xe0,0xe7,0x7e,0xf1,0x1f,0xe3,0xb7,0xff,0xf0,0xcb,0x48,0x58,0x8c,0xd,0x7e,0x39,0x3f,0xb0,0xc5,0xc3,0xb2,0x48,0xa8,0xc,0x8f,0x99,0x79,0x59,0x71,0xb9,0x3c,0xf4,0xfd,0xc8,0x19,0xb5,0xb0,0xc4,0x5a,0xad,0x41,0x52,0xce,0x36,0x5f,0x71,0x70,0x53,0xeb,0xa9,0xd3,0xbb,0xb1,0x76,0xbc,0xe7,0x8,0x7d,0xce,0x54,0x36,0x21,0xd1,0x10,0x4a,0xe5,0xc7,0xd9,0x7e,0x48,0x83,0x3,0x9,0x47,0xe4,0x6e,0x48,0xbf,0xb6,0xd3,0xe0,0x10,0xaf,0x23,0xc0,0xef,0x99,0x2e,0xb2,0x67,0xba,0xbd,0x1a,0xd8,0x78,0x84,0x6b,0x4,0x91,0x6,0x70,0x73,0x4,0x7,0x7,0x80,0xf2,0x10,0xea,0xbb,0x75,0xfd,0xd3,0x8d,0x8d,0x3a,0x36,0x20,0x9c,0xe0,0xdf,0xac,0x59,0xb3,0x26,0x0,0x38,0x6b,0xd6,0xac,0x59,0x2f,0x2a,0xfe,0x17,0x46,0xf6,0x9a,0x49,0x25,0x83,0x7b,0x5e,0xc2,0x2a,0x8a,0xb0,0xe0,0x7c,0xf3,0x15,0xe,0x58,0x64,0xad,0x56,0xd4,0xc2,0xc0,0x59,0xca,0x89,0x25,0x56,0x2,0x22,0xa5,0x85,0xa5,0x41,0x79,0x61,0x63,0x72,0xa2,0x86,0xf5,0x74,0xcf,0x72,0xdc,0x94,0x51,0x7d,0xa,0x6c,0x29,0xe6,0x97,0xb4,0x5d,0x2e,0xc6,0xa0,0xe0,0x20,0xf,0x12,0xb6,0x5e,0x4f,0x25,0x5c,0xef,0xee,0x51,0xb6,0x4b,0xdf,0x17,0x69,0x30,0x48,0x80,0xa8,0x5a,0x7b,0x2,0xa4,0x82,0x61,0x4,0x95,0xe9,0x3a,0x99,0x28,0xc1,0x80,0x4b,0x4e,0xa5,0xac,0x22,0xf7,0xe2,0x46,0xa4,0x88,0x44,0xae,0x49,0x80,0x48,0xf,0x18,0x61,0xe9,0x6e,0x4e,0xca,0xd8,0x2b,0x1d,0xb4,0x14,0x6,0x1d,0xfb,0x62,0x15,0xf3,0xd4,0x53,0x3f,0x41,0xef,0x3d,0x97,0x84,0xc1,0x18,0x6d,0xfb,0xc5,0x3b,0x50,0x18,0x87,0xdc,0x60,0x15,0x66,0x48,0xca,0x77,0xa8,0x9c,0xb9,0xe9,0xf6,0x83,0xac,0x69,0x4f,0x39,0x19,0xbb,0x90,0xb7,0xb3,0x33,0x68,0x42,0xcc,0x68,0x95,0x81,0x5c,0x36,0xa6,0xef,0xa1,0x24,0xca,0xf2,0xf3,0x9e,0x87,0x14,0x83,0x33,0xd4,0x5f,0xcc,0xdb,0x4b,0x59,0x72,0xb5,0xf2,0x76,0x71,0xb3,0x27,0x2c,0x22,0x36,0x50,0x34,0xe0,0x58,0xc3,0x51,0x42,0xe8,0xe9,0xd0,0x64,0xe0,0xb1,0x78,0x4b,0x79,0x0,0x38,0xf1,0x31,0x4b,0x21,0x9a,0xa4,0xbc,0xd5,0x82,0x90,0x32,0x20,0xe7,0x9f,0x8f,0x73,0xf,0x28,0xe9,0x6c,0xa7,0xd1,0xf7,0x6f,0x6c,0x8a,0x46,0x59,0x36,0xd,0x29,0xd2,0x6d,0x44,0xf3,0x94,0x5d,0x13,0x4c,0xfb,0xd5,0xd9,0x95,0x62,0x4,0x4f,0x8e,0x39,0x42,0xae,0x99,0x24,0xc0,0x7c,0x16,0x67,0xcd,0x7a,0x1e,0xa5,0x72,0x54,0xd,0xfe,0x61,0xab,0x80,0x7e,0xed,0x37,0xb1,0x4d,0x0,0x80,0xda,0x8a,0x84,0x78,0x88,0xff,0xa6,0x78,0xba,0xf9,0x50,0x8b,0x45,0x24,0xb9,0x2a,0x6b,0x65,0x90,0x2f,0x1d,0xcf,0x31,0x3a,0xe6,0x12,0x21,0x2f,0x9,0xa5,0x5c,0xc,0x1c,0xa,0x31,0x21,0x34,0xea,0xbe,0x7e,0xe8,0xac,0x6d,0x95,0xd1,0x9a,0xfc,0x34,0x33,0x9b,0x2e,0x88,0x1f,0xa1,0x40,0x87,0x47,0x58,0x98,0x80,0x4e,0xb,0x42,0x60,0xb9,0x6f,0x93,0x45,0xa1,0x24,0xec,0xf2,0xf0,0x16,0x60,0xc9,0xb2,0xde,0x89,0x6f,0x62,0x90,0x60,0x8d,0xa5,0xcb,0x94,0x41,0xa8,0x26,0x1,0x8e,0xd8,0x2e,0x67,0x49,0x2a,0xe6,0x79,0xe7,0x72,0x79,0x60,0x20,0x70,0x3d,0x89,0xcf,0x1f,0xef,0x8b,0xc9,0x94,0x6f,0x1a,0xc3,0xc9,0x22,0x86,0x1c,0xc7,0xb0,0xf0,0x79,0x69,0xb5,0xa0,0x94,0x82,0x3f,0xe9,0x64,0xd6,0x14,0x23,0xde,0xf3,0xea,0xbb,0xf0,0x43,0x3f,0xf0,0x69,0x7c,0xf6,0x7b,0x3e,0x8e,0x5f,0xfb,0xf5,0xcf,0xe3,0x67,0x7f,0xee,0x97,0xf0,0x3b,0x5f,0xfc,0x2a,0x9a,0xd8,0x6e,0x70,0xc8,0x4a,0x43,0x5a,0x16,0xb3,0x6c,0x20,0x22,0x2c,0xb,0xb3,0xf9,0xcb,0x76,0x41,0x2d,0x3d,0x8c,0x2a,0xc6,0x68,0xc7,0x2a,0x7,0xa0,0x6c,0x9b,0x59,0x89,0x40,0xce,0x7b,0x5f,0x7c,0xe9,0x90,0x97,0x82,0xc0,0x9a,0x20,0x6d,0xf3,0x43,0x13,0x89,0xaa,0x5,0x6b,0xc5,0xee,0xf1,0x17,0x3a,0x80,0xdb,0x53,0x82,0xe9,0xa,0xe0,0x33,0x25,0x80,0x7,0xd5,0xe,0xb2,0x7f,0x6f,0x1e,0x6d,0x9f,0x17,0x62,0x1f,0x4b,0xb6,0xf8,0xe9,0xe7,0x99,0xeb,0x73,0x1d,0xae,0x1e,0x3f,0x94,0xe2,0xba,0x6d,0xa3,0xa3,0x60,0xf9,0x70,0xf0,0x5e,0xba,0x7e,0xfe,0x4a,0x37,0xfd,0xc,0xd6,0xb4,0x13,0xfc,0x9b,0x35,0x6b,0xd6,0xd5,0x3d,0xc4,0x3c,0x4,0xb3,0x66,0xcd,0x9a,0xf5,0xe2,0x54,0x67,0x34,0x61,0x30,0x55,0x7,0x91,0xc3,0x3e,0x68,0xf0,0x80,0xd3,0xa6,0x84,0x81,0xb8,0x36,0xf8,0xb4,0x85,0x10,0x25,0x91,0x31,0x89,0x5c,0xb5,0x61,0xdb,0x2e,0xbd,0x21,0x13,0x49,0x57,0x40,0x40,0xce,0x2b,0x56,0x31,0x61,0x57,0x40,0xca,0x7f,0xb7,0xbe,0x9e,0xc1,0xbd,0x3b,0x63,0x82,0xc5,0xc4,0x2c,0x89,0x9c,0x17,0x27,0xef,0xd,0x83,0xb4,0x8c,0x9b,0xc6,0x2a,0xdb,0x91,0xec,0xdf,0xca,0xe,0x31,0x23,0x71,0x3,0xb8,0x7a,0xd0,0x46,0x95,0x60,0x8e,0x2c,0x40,0x1c,0xa8,0x3,0x40,0x20,0x66,0x90,0xa4,0x98,0x8c,0xad,0xa6,0xb2,0x68,0xff,0x19,0xd6,0x70,0x37,0x6,0xb4,0x34,0x15,0xb3,0xd6,0x62,0x92,0x61,0xcf,0x80,0x30,0x26,0xb,0x76,0xbe,0x7b,0xd2,0x60,0xd7,0x52,0x4,0xf4,0x4c,0xec,0x3f,0x65,0xe0,0x93,0x48,0xb4,0x3c,0xa0,0xab,0xfe,0x5e,0x72,0xb7,0xaf,0xc0,0xa4,0xb2,0x2f,0xf3,0xb2,0x18,0x20,0x96,0x84,0xb1,0x97,0x97,0xc5,0xfa,0x80,0x98,0xe2,0xc0,0x44,0xc9,0xcb,0xd2,0x43,0x49,0x94,0x49,0x24,0xc0,0xaa,0x7,0xcd,0x54,0x72,0x5b,0x45,0x22,0xa8,0x9e,0x5a,0x41,0x58,0x1c,0x1a,0x22,0xa3,0xfb,0xa8,0xe7,0x2e,0xc6,0x64,0x2c,0x46,0x96,0x87,0x65,0xa8,0x48,0x51,0x7d,0x11,0x43,0x8,0x7c,0x5e,0x4,0x90,0xe8,0xc,0x53,0x1a,0xc0,0x3c,0x58,0xf3,0x37,0x76,0x38,0x7b,0xc9,0x30,0x69,0x8,0x8a,0xf3,0xfd,0xeb,0xbd,0x10,0x61,0x94,0x87,0x85,0x41,0x7a,0x66,0xa9,0xcb,0xa,0x2c,0xc2,0x25,0xa,0x5b,0xf2,0xe2,0xc8,0xbc,0x9,0xbb,0x94,0xca,0x59,0xb3,0xde,0xd9,0x81,0xde,0xa5,0x0,0xbb,0x3f,0xe6,0x5f,0xaa,0x8c,0x23,0x49,0xc6,0xcd,0xcb,0x62,0xb,0x6,0x39,0x65,0xa4,0x9c,0x99,0xe1,0xac,0xd7,0xba,0xc8,0x42,0xd5,0xa3,0x94,0x65,0xbc,0xc7,0xbf,0xef,0x26,0x72,0xd0,0x1e,0xfc,0x44,0x88,0x79,0x91,0x0,0x8e,0xcd,0x18,0xd9,0x9c,0x8c,0xce,0xe1,0x4e,0xa,0xe2,0x30,0x13,0x8f,0xc7,0xda,0x94,0x17,0xac,0xeb,0x9d,0xf8,0x1,0x36,0x99,0x7,0xd2,0x31,0x54,0x23,0xe0,0xd1,0xe9,0xee,0x5e,0x52,0x77,0x13,0x2f,0x48,0xc9,0x62,0x45,0x5e,0x4f,0x7,0xec,0xbf,0x7e,0xb0,0x18,0xdc,0xb,0xb6,0xdd,0x4d,0x16,0x3a,0x78,0xf1,0x26,0x21,0x4b,0x8,0x49,0x8c,0x91,0xf7,0xa3,0x16,0xe,0xc4,0x2,0xb0,0xae,0x77,0x3d,0x25,0x58,0x53,0x88,0xa9,0x19,0xc3,0x9c,0xdc,0x82,0xd9,0x1e,0x1c,0xb2,0xe3,0x24,0xe3,0x94,0x32,0xa3,0x57,0x49,0x2,0x7e,0xa7,0xea,0xb4,0x2e,0xf8,0x81,0xef,0xfd,0x4,0xfe,0xb3,0xff,0xf0,0xaf,0xe2,0xdf,0xf8,0xf1,0xcf,0x61,0x5d,0x16,0x1,0x66,0x17,0x4b,0x8d,0x57,0x20,0x4b,0xe7,0x63,0x9d,0x1b,0xcd,0xea,0x41,0xe6,0x21,0x5d,0x18,0x2,0xd8,0x7b,0x56,0x11,0x5b,0x4b,0x78,0x76,0xf7,0x1e,0x36,0x57,0xa4,0x24,0x3e,0x78,0xdd,0x71,0x15,0xce,0x67,0x57,0xe7,0x39,0xb,0x31,0xb3,0x9f,0x74,0x67,0xb6,0x3a,0xfa,0x79,0x5f,0xd4,0xf4,0x81,0x1f,0x34,0x2a,0x7c,0x3d,0xc8,0x16,0x82,0x72,0xf1,0xe,0x40,0xbc,0x3,0xd2,0xa1,0x1,0x71,0x3a,0x4f,0xda,0xbb,0xaf,0xc1,0xbf,0xdd,0x19,0x3f,0xbe,0x58,0x71,0x0,0xdc,0x1d,0x82,0x75,0x37,0x53,0x46,0x9e,0xe,0xf4,0xdd,0xcc,0xf9,0xf8,0x66,0xe9,0x8f,0xb3,0x66,0xcd,0x9a,0x0,0xe0,0xac,0x59,0xb3,0x66,0xcd,0xfa,0xd3,0xd1,0x17,0x12,0x5d,0x49,0x16,0x95,0x31,0x65,0xab,0xf2,0x3e,0xcd,0x10,0xe4,0x12,0x5d,0xe3,0x35,0x30,0x68,0xa9,0xb1,0xc9,0x0,0xbd,0x94,0x72,0xf,0xe4,0x50,0x83,0x79,0x61,0x42,0x84,0x98,0x90,0x96,0xc5,0x9a,0x9d,0x94,0x17,0xe4,0x65,0xc5,0xb2,0xb2,0xfc,0x2b,0xe7,0x55,0x9a,0xa9,0x66,0x9f,0xa5,0x26,0xda,0xd5,0x31,0x12,0x35,0xd5,0x52,0xd3,0xa,0x43,0x8,0x58,0xd7,0x3b,0x6b,0x70,0x63,0xe8,0x6,0xf1,0xa,0xb8,0xf9,0xd5,0x7a,0x4b,0x65,0xc,0x11,0x51,0x3c,0xf,0x35,0x3b,0xf,0xe,0x58,0x62,0xf9,0x52,0x75,0xf2,0xde,0xe,0x5c,0xaa,0x14,0xd5,0x82,0x30,0x20,0x1,0x21,0xb1,0xdf,0x85,0x33,0x53,0x24,0x89,0xe1,0x3d,0x37,0x9,0x6a,0x22,0x6f,0xb2,0x5b,0x1,0x90,0x94,0x9,0x2,0x49,0xe1,0x35,0xa3,0x6f,0x1,0xff,0x14,0xf8,0xcc,0xcb,0xe2,0xc0,0xda,0x26,0xac,0x1c,0x6e,0x8e,0x93,0x7c,0x9f,0xbe,0xb6,0xc9,0xf6,0x29,0x8,0xa8,0x32,0xd8,0x52,0x36,0x6,0x35,0x73,0xb6,0xfd,0x53,0x49,0xf5,0x76,0x39,0x5b,0xaa,0xa7,0x31,0x42,0xad,0x79,0xeb,0x92,0xbc,0x98,0xe2,0x20,0x4d,0x53,0x86,0xa6,0xca,0xa0,0x39,0x35,0x34,0xf,0xa9,0xc7,0xc,0x34,0x76,0x30,0x4d,0x1b,0x77,0xdd,0xf,0x4d,0xa2,0xee,0xe9,0x8e,0x2,0xae,0x4a,0xda,0xa6,0x26,0x40,0xeb,0xa6,0x28,0xd3,0x26,0x84,0x28,0xe7,0xc6,0x1b,0xe3,0x6b,0x43,0xd8,0xd3,0x29,0xc9,0x12,0x99,0x7b,0x80,0xb,0x35,0x27,0x83,0xe,0xd1,0x1a,0x51,0xbd,0x40,0x88,0x9a,0xf3,0xc1,0x24,0xf8,0x1c,0xed,0xbd,0x94,0xd,0xe,0x34,0x8d,0x69,0x99,0x3,0xce,0xac,0xe7,0x52,0x4d,0x3c,0x51,0x1,0x1e,0xdb,0xfa,0xb8,0x15,0x8d,0xd9,0x36,0x84,0x14,0xc9,0x58,0xd5,0x64,0x41,0x24,0xc6,0x84,0x90,0x62,0xf7,0xb3,0xcb,0x9,0x79,0x59,0x2c,0xa0,0x43,0xe7,0x83,0xc3,0xc6,0x41,0x93,0xd7,0x89,0x84,0x91,0xdc,0xd9,0x63,0xcc,0xfa,0x23,0x2c,0xa7,0x53,0x1f,0x87,0x15,0xa0,0x13,0xb,0x2,0x4e,0x4e,0x6f,0x28,0x97,0x33,0xb6,0xcb,0x99,0x43,0x2d,0xdc,0xfc,0x72,0x4,0x56,0xb0,0x54,0x38,0xda,0xf5,0xad,0x32,0xd4,0xcb,0xf9,0xc1,0xc6,0x7a,0x1b,0x73,0xf6,0xef,0x15,0x96,0xb6,0x4a,0x90,0xd5,0xf7,0xb0,0x9,0x6b,0x51,0x19,0x6c,0xca,0x88,0x67,0x69,0x34,0x27,0x1d,0xd7,0x5a,0x24,0xfc,0xa2,0x21,0xaf,0x1c,0xa,0x52,0x6b,0xb5,0xe3,0xa3,0xb,0x22,0x87,0xc7,0x49,0x42,0x4f,0xf4,0x33,0x35,0x80,0xeb,0x74,0xba,0xe7,0x45,0x9d,0x9b,0xc0,0x21,0x86,0xc5,0x90,0x2b,0xac,0x87,0xfa,0x9f,0xb7,0x5b,0x8f,0xee,0xef,0xf0,0x13,0x7f,0xf1,0x87,0xf0,0x9f,0xfe,0xb5,0x9f,0xc4,0xfb,0x5f,0x7b,0x55,0xe4,0xd8,0x27,0xb3,0x7a,0x48,0x69,0xb1,0xf1,0xd1,0x18,0x9d,0x16,0xe,0xd5,0xd9,0xd9,0x3a,0xa7,0xf1,0xe2,0x61,0x35,0xc6,0x7c,0x6b,0x5d,0x2a,0x1c,0x23,0xfb,0xc,0x37,0xc7,0xce,0x57,0x66,0x3e,0x8,0xbb,0x5,0x1f,0x1a,0x77,0x6e,0x90,0xf3,0x8e,0xa1,0x4b,0x26,0xb9,0xa5,0xeb,0x7b,0x1e,0x6f,0xdd,0x4a,0x4e,0x7e,0xac,0x8b,0x39,0xbb,0x88,0x91,0x1,0xd8,0xeb,0xf0,0xa0,0x3,0xfb,0x88,0x76,0x89,0xbb,0x78,0xa,0xea,0x16,0x6e,0x0,0x85,0x87,0xd8,0xf0,0xb8,0xc1,0xc0,0x31,0xd3,0xef,0xc0,0x2,0x71,0xb4,0xa5,0xd8,0x99,0x17,0xba,0x5,0x34,0xf,0xa2,0xce,0x9a,0x35,0x6b,0x96,0xaf,0x29,0x1,0x9e,0x35,0x6b,0xd6,0xac,0x17,0xa8,0x7c,0x2,0xa4,0xf,0x63,0x30,0xd6,0x93,0x98,0x9a,0xf3,0x8d,0x7a,0x37,0x7c,0xb7,0x1b,0x69,0xd,0xb4,0x90,0x9b,0x7d,0x95,0x6,0x45,0x65,0x3d,0xa0,0x4b,0x86,0x43,0x8c,0x9c,0x0,0x2c,0xc0,0x4a,0x16,0xe0,0x4e,0x1,0x1d,0xef,0x77,0x47,0xd4,0x4c,0x7e,0x9b,0x25,0xf1,0xd7,0xa7,0xc4,0xe6,0x65,0xc1,0x76,0x51,0x9,0x6d,0x30,0x6,0x5d,0x73,0x6c,0x44,0x95,0x92,0xa9,0x64,0x18,0x8,0xf6,0xb8,0x31,0xa,0x64,0x3f,0x5a,0x63,0xf,0xaa,0x2c,0xd,0x4d,0x97,0xe1,0x26,0x93,0x6f,0x1a,0x80,0x64,0x80,0xe2,0xf8,0x19,0x9a,0x68,0xcb,0x3e,0x83,0x6d,0x90,0xcc,0x45,0xf1,0xd,0x34,0x50,0x49,0x2,0x33,0xac,0xe1,0x15,0x89,0xaf,0x1e,0x3b,0x5,0xea,0xb8,0x9,0xd4,0xe6,0xa9,0x80,0x88,0xbd,0xb3,0xf2,0x7a,0xb2,0xd7,0xf,0xc7,0x58,0x40,0x47,0xe,0x20,0x29,0x1d,0x98,0x94,0xb8,0x8a,0xb4,0x2c,0x9c,0xa0,0x29,0xd3,0x39,0x89,0x4c,0x96,0x41,0xd6,0xd,0x51,0xf6,0x31,0x4b,0x93,0x5e,0xe5,0xf8,0xb3,0xcf,0x9f,0xa4,0x33,0x2b,0x28,0x16,0x23,0x92,0xf3,0xfb,0x53,0xe0,0xac,0x37,0x60,0x7c,0x1e,0x4a,0x2d,0x9c,0x42,0x9,0xf1,0xde,0x13,0x23,0xfe,0xe6,0x2,0x3b,0x14,0x4,0x54,0xf6,0x9e,0x85,0x90,0x4,0x4e,0xb0,0x44,0x88,0x92,0xc8,0x1b,0x2c,0x85,0xba,0x6f,0x7b,0x1c,0x80,0x4c,0x5,0x22,0x7c,0x2,0xb0,0xca,0x90,0xcd,0xf3,0x4c,0xe4,0xc9,0xde,0x47,0x50,0xe5,0x5c,0xc1,0x31,0x4b,0x6,0x92,0x90,0x3d,0x76,0x2d,0x21,0xf3,0x61,0x2b,0xfa,0x18,0x39,0xe9,0x1a,0x27,0x72,0x5e,0xe6,0x80,0x33,0xeb,0xf9,0x8c,0xf3,0x29,0xcb,0xd8,0x48,0x36,0xde,0x29,0x10,0xd0,0x5a,0x45,0x2b,0x65,0x60,0x6,0x87,0x10,0x39,0xd9,0x35,0x67,0xbb,0x9e,0x35,0xb5,0x95,0x17,0x14,0x18,0xcc,0x5b,0x84,0x49,0xa7,0xc,0xe1,0xa3,0xaa,0x62,0x53,0xc0,0xc,0xba,0xcd,0xc0,0xc6,0x5a,0x95,0x35,0xc8,0xe0,0xcc,0x7a,0xba,0x47,0xd9,0xce,0x36,0xa6,0x6,0x91,0xfc,0x2b,0x18,0x97,0x52,0xc6,0x7a,0x3a,0xb1,0x8c,0x94,0x1a,0x1a,0xfa,0x2,0xc6,0x11,0x20,0x96,0x72,0x46,0x2c,0x64,0xe3,0xe3,0xe5,0xfc,0x80,0xbc,0xae,0x48,0x31,0xf3,0xf4,0x16,0xe3,0x2d,0x34,0x4d,0x24,0xce,0x8d,0x99,0xd7,0xd4,0x3,0xa9,0xa8,0x15,0xb3,0x63,0x58,0xd7,0xbb,0x3e,0xf6,0x99,0x14,0x76,0xe5,0xf1,0x72,0xdb,0x6c,0xd1,0x25,0x19,0x2b,0x6e,0xb9,0xb9,0xbd,0x3a,0x77,0x99,0xfd,0x42,0xce,0x36,0xdf,0x3e,0x3c,0xbc,0x89,0xd3,0xe9,0x5e,0xe4,0xda,0xd7,0xf5,0x95,0xaf,0x7e,0x3,0x7f,0xeb,0x7f,0xfa,0xfb,0x43,0x8a,0x7b,0xab,0xc5,0xe6,0x6f,0x1e,0x9b,0x80,0x25,0x27,0xac,0x4b,0xc2,0xa3,0xfb,0x3b,0xbc,0xff,0xb5,0x57,0xf1,0xfe,0xd7,0xde,0x85,0xf7,0xbc,0xe7,0x5d,0x78,0xf9,0xa5,0x47,0x58,0xf2,0xed,0xf6,0x2e,0x84,0x80,0x8f,0x7f,0xf4,0x43,0xf8,0x8f,0xff,0xda,0x4f,0xe2,0xaf,0xff,0x37,0x3f,0x8d,0x3f,0xfa,0xda,0x9b,0x32,0xe6,0x25,0xc4,0xd4,0x50,0xb7,0x1e,0x4,0xd5,0x6a,0x1b,0x41,0x4e,0xea,0xc,0x74,0x9d,0x3b,0x75,0x91,0xa9,0x9f,0xa7,0xa5,0x2f,0x1c,0x86,0x30,0x2c,0x38,0xfa,0x39,0x9f,0x17,0x83,0x30,0x3e,0x1f,0xfa,0x7d,0x8b,0xfd,0xa0,0xc3,0x68,0xe1,0x70,0x9d,0xb0,0x3b,0xa6,0xe7,0x1e,0x59,0xb7,0x2,0x9e,0xf9,0x77,0xfd,0x7e,0xda,0x7,0x3d,0x39,0x80,0xee,0xfa,0x39,0x27,0x4b,0x1e,0x24,0xba,0xf4,0x74,0xb0,0xee,0x16,0x86,0x68,0x21,0x30,0xe1,0x9a,0xe5,0x77,0x23,0x7,0xe5,0xa,0x49,0xf4,0xa1,0x65,0x7,0x9f,0x61,0xa1,0x41,0xb3,0x66,0xcd,0x9a,0x35,0x1,0xc0,0x59,0xb3,0x66,0xcd,0x7a,0xb1,0x8a,0xdc,0x4d,0x7e,0x93,0x14,0xdf,0xbe,0x48,0x2c,0xc1,0x13,0xd2,0x4,0xa9,0x2c,0x4a,0x7d,0x80,0x96,0xf5,0xe4,0x64,0xaa,0xc9,0xfc,0xa5,0xba,0xf4,0x7,0x3d,0x58,0x23,0xf4,0x75,0x71,0x6d,0xa6,0x2c,0xa4,0x41,0xe4,0xbc,0xde,0x93,0x4d,0x7d,0xec,0x52,0xce,0x28,0xdb,0x85,0x3d,0x86,0x24,0xa9,0xd2,0x80,0x49,0x91,0x47,0xa9,0xef,0x9f,0xca,0x49,0xe1,0xe4,0x47,0x9e,0xa9,0xa7,0xdb,0x1,0x60,0x60,0x2e,0x6a,0x10,0x8,0x9b,0xc3,0x8b,0x6c,0x57,0x1a,0x92,0x98,0x12,0xda,0x65,0x13,0x19,0x17,0x19,0x8b,0x4d,0x3d,0x8a,0x7a,0xcf,0x11,0xc,0xe8,0xeb,0xde,0x5a,0xdc,0x78,0x6e,0xdb,0x5,0xa8,0xec,0x9b,0xc5,0x49,0xba,0x30,0xe0,0x4e,0xe5,0xc9,0x2a,0x9d,0x2e,0x1b,0x83,0x70,0x96,0xaa,0xac,0x20,0x63,0x80,0xb1,0x5e,0x72,0x5e,0xba,0x7,0x95,0x6c,0x97,0x9e,0x97,0x18,0x13,0x96,0xbc,0xe0,0x72,0x79,0xe0,0xd7,0x95,0x22,0xe7,0x4d,0x7d,0x9,0x2b,0x52,0x5e,0x3b,0x28,0x20,0xec,0xb,0x95,0xb8,0xa9,0x34,0xd7,0x98,0x93,0xc2,0xd4,0x48,0xc2,0x70,0xf1,0x49,0x93,0xca,0xbc,0x50,0x66,0x8a,0x32,0x38,0x92,0x48,0xe5,0x20,0x3e,0x8d,0x31,0x26,0x6,0xf1,0x88,0x50,0x4b,0x35,0xb0,0x4c,0x9b,0xdc,0xe6,0x42,0x4f,0x14,0x6c,0x8c,0x21,0x82,0x12,0x3,0xa5,0x2a,0x13,0x54,0xff,0xc7,0x24,0xde,0x87,0x6a,0xe,0xaf,0xfe,0x91,0x5d,0x3a,0xdd,0xc,0x60,0xa5,0x56,0xcd,0xcf,0xac,0x1,0x8,0x22,0xf9,0xb5,0x56,0x4e,0xbc,0x18,0xf5,0xb7,0x50,0x2d,0xd,0x55,0x59,0x42,0xd4,0xc1,0x2,0x47,0xa5,0xf1,0x46,0xee,0x8,0xb0,0x4,0x6c,0xdc,0xe4,0xf7,0xcc,0x9a,0xf5,0x1c,0xc7,0x79,0x6a,0xc0,0xc0,0x5c,0xa,0x83,0x8c,0x33,0xe7,0x64,0x7e,0x80,0x14,0x1b,0xb6,0xcb,0xc6,0x49,0xbf,0xa9,0x33,0xed,0x2c,0x8c,0x47,0xc2,0x76,0x6c,0x1c,0x47,0x40,0x5c,0x6e,0xb3,0x5b,0xbb,0x64,0x34,0xc8,0xc2,0xcd,0xc5,0x58,0xdd,0x21,0x45,0x1b,0xf,0xaa,0x80,0xf7,0xd5,0x92,0xcf,0xfb,0xf5,0xae,0xd7,0x37,0x7b,0xc1,0xb2,0x5f,0xe0,0xe5,0xe1,0x89,0x5c,0xcb,0xb7,0x91,0x92,0xed,0x72,0xc6,0xb2,0x32,0x68,0x98,0x64,0xa1,0x89,0xbc,0x81,0xdb,0x4d,0xc0,0x34,0xe1,0x72,0xd9,0xb0,0x9c,0xf8,0x7b,0x9a,0x31,0xa8,0x2b,0x50,0x83,0xf8,0x9c,0x5e,0x5c,0xb8,0x49,0xc3,0x7a,0x77,0xdf,0xd9,0x93,0xeb,0x6a,0xc4,0x34,0x1d,0xbb,0x5b,0x2d,0xe6,0x73,0x78,0xf8,0x9d,0xb2,0x10,0xa3,0xf3,0xec,0xe5,0xf2,0x0,0x6a,0x15,0xa7,0xbb,0x47,0x32,0x3f,0x1c,0x1f,0xe3,0xf3,0xe5,0x82,0x5f,0xf9,0xfc,0x1f,0x30,0x2b,0xbe,0x15,0xb4,0x22,0x1e,0xb9,0xb2,0xf8,0xd3,0x17,0xef,0xb2,0x5,0x2f,0x81,0x80,0x6d,0x3b,0xe3,0xd1,0xdd,0x9,0xdf,0xf9,0x2d,0xaf,0xe1,0xfb,0x3e,0xf9,0x61,0xfc,0xc0,0x67,0x3e,0x89,0x77,0xbd,0xf2,0xf2,0xcd,0xc3,0xf2,0xc1,0xf,0xbc,0xf,0xff,0xc9,0xbf,0xff,0x53,0xf8,0x2f,0xff,0xc6,0x4f,0xe3,0xf7,0xbf,0xf4,0x55,0x9e,0xdf,0x62,0x6,0x16,0x4e,0x70,0xe,0x21,0x99,0xe4,0x57,0xe7,0x15,0xb,0x7c,0xaa,0xa5,0x5b,0x3b,0xe8,0x3d,0x42,0xf3,0x8b,0x36,0xc1,0x31,0xf6,0x70,0xcd,0x42,0x53,0x90,0xcf,0xc7,0xd3,0x86,0x0,0x34,0xba,0xa,0xf9,0x0,0x1d,0x63,0x61,0x47,0x41,0xc1,0xb4,0xcb,0xc6,0xa5,0x1d,0x95,0x2e,0x18,0x4b,0xcf,0x31,0x8,0xc3,0xce,0x73,0xef,0xc8,0x77,0xcf,0x33,0xf6,0x8e,0x42,0x35,0x8e,0xb0,0xf2,0x80,0xa7,0x3,0x82,0xc3,0x7b,0xc3,0xed,0x9d,0x7c,0xe6,0x3b,0xbf,0xe0,0x12,0x96,0xdd,0x33,0xed,0x19,0x59,0x89,0xb3,0x66,0xcd,0x9a,0x0,0xe0,0xac,0x59,0xb3,0x66,0xcd,0xfa,0x53,0xd8,0x18,0x36,0x5d,0x89,0x97,0x9b,0xc9,0x46,0xe,0xe4,0x41,0x97,0xb0,0x12,0xb3,0xf7,0xaa,0x30,0xb,0x92,0x32,0x22,0x48,0x1a,0x40,0x61,0x77,0x50,0x23,0xf1,0x7f,0xb,0x8e,0xed,0xe5,0x3d,0x7f,0x60,0xc0,0x98,0x4a,0xcf,0xfe,0xe5,0xcf,0x7e,0xc,0xdf,0xf5,0xe1,0xef,0x30,0x40,0xe9,0xe1,0x7c,0xc1,0xcf,0xfc,0x6f,0xff,0x37,0x1e,0x3f,0x39,0x9b,0x9f,0x5c,0x95,0x40,0x90,0xcb,0xe5,0xc1,0xd8,0x55,0x69,0x59,0xb0,0x9d,0xb9,0xc1,0x6b,0xb5,0xa2,0x5,0xf1,0x88,0xab,0x5,0x24,0xdb,0xea,0xe5,0xa0,0x83,0x35,0x9c,0xc8,0x4f,0x6b,0x95,0xa0,0x11,0x93,0xa8,0x15,0xa4,0x65,0x31,0x9,0x70,0x71,0x2c,0x18,0x7e,0x2c,0x59,0x7a,0x71,0x37,0x2e,0xef,0xd2,0xa6,0x94,0x33,0x62,0xec,0x86,0xf9,0xa5,0x6c,0xec,0x79,0x28,0x2b,0xea,0x16,0x36,0xa2,0x87,0x5b,0x12,0x70,0x1,0xf6,0xd5,0x5a,0xef,0xee,0x45,0xde,0x5b,0x51,0xa9,0x99,0xef,0x56,0x8c,0x9,0x14,0x3c,0x3,0x72,0xb5,0xc6,0x4e,0xa5,0x65,0xab,0x18,0xd7,0x6f,0x62,0x42,0x1f,0x63,0x2,0xc4,0x22,0x4b,0xd9,0x81,0x31,0xc9,0x71,0x40,0x90,0xf0,0xa,0x72,0x8c,0x1b,0x96,0x5c,0xb3,0xe9,0x3f,0xbf,0x46,0x7d,0x1c,0xd5,0xd4,0x9d,0x5a,0xed,0xac,0x3a,0xf9,0x9b,0xc1,0x4a,0x61,0xda,0xc4,0x24,0xc7,0x8c,0x59,0x32,0xea,0x15,0x8,0xf5,0x74,0x12,0xb0,0x4c,0x81,0x37,0x65,0x84,0xc0,0xc9,0xab,0x15,0x8c,0x83,0x48,0x6,0x55,0xb6,0x58,0x5b,0x7,0x6,0xcc,0x3,0xb0,0x31,0xc8,0xa8,0x2c,0x23,0x12,0x79,0x99,0xea,0x99,0x7c,0xca,0xe8,0xc0,0xfa,0x6b,0x5d,0x6,0xac,0xff,0x6f,0x1d,0x2d,0x19,0x1a,0x4f,0x65,0xa4,0xda,0xff,0x9d,0xe1,0x7b,0x17,0x8a,0xd1,0x41,0xf7,0xd7,0x1f,0x69,0xad,0x21,0xe6,0x3b,0xd4,0xcb,0x9b,0x73,0xd0,0x99,0xf5,0x1c,0xc6,0xf9,0xe6,0x0,0x6c,0x98,0x3c,0x9e,0xd4,0x8b,0x34,0x74,0x5f,0xb5,0xb2,0x71,0xca,0xad,0x8e,0x9f,0x1a,0x8a,0xa1,0x63,0xb7,0x86,0x5f,0x34,0xf1,0x8,0x24,0x38,0xef,0xd6,0x63,0x68,0xb,0x40,0xf,0xd3,0xd0,0x45,0xf,0x38,0x3f,0xd6,0x18,0x22,0xb6,0xb6,0x21,0xc6,0x84,0xd3,0xdd,0x23,0xf9,0xee,0x88,0xf5,0xee,0xde,0xc0,0xb3,0x2c,0xe9,0xba,0x39,0x2f,0x28,0xdb,0x5,0x79,0x59,0xcc,0x6b,0xf4,0xe8,0x3b,0x5b,0xab,0x38,0xdd,0xdd,0x33,0xd0,0x44,0x24,0x1,0x20,0x55,0xac,0x24,0xd2,0xed,0x83,0x15,0x2,0x2f,0x60,0xc8,0x62,0x1,0x7f,0x7,0x1f,0x43,0xd,0xf6,0xa8,0x75,0x93,0x50,0x8a,0x66,0x9,0xed,0x39,0x2f,0x78,0x78,0xf2,0xa6,0xd9,0x3c,0xc4,0x94,0x8d,0xcd,0xbd,0x2c,0x27,0x63,0x5e,0xde,0xf4,0x1e,0xd4,0xc5,0x2f,0x44,0x4b,0x14,0xb6,0x5,0x87,0xa7,0xb0,0xb1,0x6c,0x2c,0x8e,0x1,0x54,0xc8,0xd8,0xe6,0x97,0xf3,0x13,0x9b,0xd8,0x63,0x62,0x9f,0x45,0xb5,0x7a,0x40,0xe0,0x39,0xe4,0xe1,0xb2,0xe1,0x37,0x7e,0xe7,0x8b,0xf8,0x8d,0xdf,0xfd,0x12,0xfe,0xce,0xff,0xf1,0x2b,0xf8,0x91,0xef,0xfb,0x38,0x7e,0xfc,0x47,0x3f,0x8b,0x57,0x5e,0x7e,0xe9,0xf0,0xbb,0xbe,0xe5,0xfd,0xef,0xc5,0x7f,0xf0,0x6f,0xfd,0x4,0xfe,0x8b,0xff,0xfa,0x6f,0xe1,0xe1,0xe1,0x81,0x17,0xe9,0xc4,0x96,0x63,0xbb,0x3c,0xf0,0x5c,0x5d,0xb,0x22,0x65,0xb4,0x56,0x50,0x4b,0xb1,0x5,0x9e,0x5a,0x36,0x99,0x6b,0x82,0x1b,0x9b,0xf9,0x3e,0x81,0xbd,0x15,0x7b,0x10,0x53,0x70,0xb,0x4b,0x96,0x3e,0x1f,0xa3,0x63,0x3,0xf6,0xf9,0x14,0xfb,0x10,0xe,0xf5,0x8,0x54,0xa9,0x6f,0x70,0x6c,0x3f,0xcb,0x4,0x9,0x63,0xf8,0xc7,0x8d,0xd4,0x8f,0xe,0x16,0xd3,0x35,0x48,0x77,0xf4,0xef,0x67,0x1,0xfa,0x9e,0x86,0xc9,0x19,0xa8,0xe7,0x1,0xba,0xa7,0x6d,0xe0,0xe,0x25,0xc,0xe1,0x20,0x85,0x1e,0x38,0xd6,0xb,0xef,0xf7,0xb4,0x2f,0x76,0x5d,0x7,0x93,0xcc,0x9a,0x35,0x6b,0x2,0x80,0xb3,0x66,0xcd,0x9a,0x35,0xeb,0x85,0x28,0xd,0xb0,0xf0,0x37,0x85,0xc1,0xc2,0x11,0xd4,0x29,0x3b,0x48,0x68,0x5f,0xeb,0x80,0x91,0x7a,0xe6,0x69,0x72,0xa4,0x30,0xd2,0x48,0x58,0x1b,0x44,0x40,0x82,0xa4,0x19,0x86,0x64,0x37,0xec,0xca,0x4a,0x48,0x22,0x6d,0x7d,0xe9,0xfe,0x84,0x7f,0xfd,0xc7,0x7f,0x14,0xaf,0xbd,0xe7,0xdd,0xf6,0xfd,0xad,0x35,0xfc,0xde,0x17,0xbe,0x8a,0x7f,0xf0,0x2b,0xff,0xaf,0x1,0x30,0xe9,0xc4,0xac,0xb2,0x65,0x61,0xc3,0x75,0x14,0xe1,0x5a,0x5,0x38,0x19,0x2c,0xa7,0xd2,0xb6,0x16,0xc5,0x1b,0x6f,0x35,0xcf,0xc1,0x5a,0x6b,0xf,0xb0,0x10,0x7f,0xbd,0x10,0x23,0x50,0x21,0xb2,0x67,0x6,0x9,0x95,0xe9,0xc2,0xc0,0xe0,0x22,0x2c,0xc6,0x7e,0x53,0xad,0x40,0x9f,0x9a,0xbb,0xfb,0xd4,0xd9,0x45,0x3c,0x9f,0xa8,0x36,0x6b,0xc2,0x94,0x55,0xc8,0xf7,0xea,0xc4,0x8d,0x75,0xa9,0x88,0xb1,0x1b,0x9a,0x73,0xd2,0x65,0xb1,0x46,0x47,0xef,0xdc,0x2d,0xd,0x52,0x99,0x6e,0x5b,0x1b,0x98,0x88,0x66,0x76,0x2e,0xcd,0x95,0x35,0x9b,0x2,0x4,0xd6,0x5a,0x51,0xca,0x5,0x8b,0x36,0xb0,0x20,0x4,0x44,0xc4,0xd8,0x9b,0x71,0x24,0xf5,0x4f,0x4c,0x96,0x6a,0x6c,0xac,0x8d,0x56,0x99,0xe1,0x21,0xbf,0x93,0xd6,0x2a,0xb3,0x18,0x5d,0xa2,0x30,0x33,0xf4,0x9a,0x4b,0xda,0x8c,0x38,0xdd,0x3f,0x62,0x26,0x63,0x4a,0xd6,0x98,0xc2,0xf9,0x0,0xb6,0x5a,0x4d,0x8a,0xad,0x5e,0x5c,0x6a,0xfa,0x1e,0x85,0xa5,0xd2,0xf5,0xb8,0x40,0x16,0xf9,0x62,0x14,0xbf,0xc8,0x72,0x39,0xb,0xe0,0x7c,0x31,0xa6,0xa4,0xca,0xca,0x58,0xee,0xb,0xb4,0xda,0xe4,0x58,0xf7,0xf4,0x4c,0x6b,0x28,0x95,0x45,0x2a,0x26,0xfe,0x64,0x41,0x20,0x9e,0x21,0xda,0xe,0x1b,0x74,0x65,0xff,0x59,0x20,0x82,0x35,0xed,0xd8,0x35,0x62,0xae,0xd7,0x52,0xa6,0xe4,0xf6,0x30,0x7,0x9c,0x59,0xcf,0x67,0x9c,0x4f,0x19,0xd0,0xa0,0xf,0xa9,0x5a,0x8b,0x2d,0xd0,0xa8,0x5c,0x3d,0x2,0xbc,0xa0,0xd2,0xaa,0x78,0x70,0x46,0x61,0xee,0x6e,0x58,0xef,0xee,0xc5,0xa,0x80,0x50,0xcb,0x5,0xeb,0xe9,0xce,0x3c,0x37,0x99,0xf1,0x95,0x6e,0x7c,0x77,0x67,0xaf,0x11,0x38,0xd8,0xe3,0xee,0xfe,0x25,0x63,0x6e,0x47,0x61,0x54,0xaf,0xe9,0x1e,0xe5,0x72,0x31,0xe6,0xb6,0xb2,0xe5,0x58,0xa,0x2c,0x9f,0x25,0xa9,0xde,0x16,0xbc,0x21,0x8c,0xea,0x23,0x40,0x23,0xa5,0x8c,0xfa,0xf0,0x84,0x3,0x9d,0x4,0xb8,0x83,0xc8,0x63,0x43,0xb8,0x1d,0xa0,0x40,0xc2,0x24,0x3e,0xdd,0x3d,0xc2,0x9b,0x6f,0x7c,0xad,0x83,0x21,0x84,0x1e,0xe6,0x24,0xa1,0x25,0xa,0x28,0x22,0x30,0xdb,0x70,0x5d,0xef,0x6c,0x81,0x47,0xfd,0x49,0x75,0xec,0x37,0x3b,0xd9,0x1b,0x0,0xa0,0xb2,0xa2,0x8b,0xb,0xc5,0xa,0x51,0xac,0x23,0x62,0x7c,0x2a,0x6e,0x14,0x63,0x42,0xd9,0xce,0x8,0xb2,0x1d,0x3a,0x67,0x5c,0x64,0x9b,0xca,0xb6,0xd9,0x62,0x97,0x1e,0x83,0xb2,0xb1,0x1c,0x3b,0x65,0x1e,0x97,0xbf,0xf1,0xe6,0x63,0xfc,0x2f,0xbf,0xf8,0xab,0xf8,0x3f,0x7f,0xed,0x37,0xf1,0xef,0xfc,0xe4,0x5f,0xc0,0xa7,0x3e,0xfe,0xfa,0x21,0xb7,0xf2,0xc3,0x1f,0xfa,0x36,0xfc,0xd5,0x9f,0xf8,0x61,0xfc,0xb7,0x3f,0xfd,0x73,0x48,0x69,0xc1,0xe5,0xfc,0xc0,0xcc,0xf8,0xbc,0xf2,0xe2,0x9b,0x8c,0xab,0x65,0x63,0x1b,0x8f,0xed,0xfc,0x0,0xc4,0x88,0x80,0x68,0x4c,0x69,0x5d,0x30,0xe4,0x44,0xe5,0x86,0x9c,0x33,0xcf,0xd1,0x66,0x81,0x51,0xe5,0xf7,0xda,0x0,0x61,0x2d,0xd6,0xb6,0x1b,0x9f,0x35,0xf8,0x49,0x41,0xb0,0x10,0x64,0x4d,0x8b,0xc,0x10,0xf4,0x92,0xdc,0x2e,0xf9,0xa5,0xeb,0xe4,0xdf,0x80,0x21,0xc5,0x97,0xf6,0x41,0x1c,0x1e,0x44,0x7b,0x16,0x5c,0xec,0x56,0xc0,0x6,0x85,0x63,0x30,0x6f,0xbf,0x86,0x74,0x85,0x8,0xde,0x62,0xab,0x86,0xab,0xdf,0x50,0xf0,0x93,0x8f,0xfb,0x3e,0xb5,0x1,0x81,0x7b,0x64,0x8,0xab,0x82,0xf3,0xc5,0x9d,0xe0,0xdf,0xac,0x59,0xb3,0xfc,0x3c,0x3e,0xf,0xc1,0xac,0x59,0xb3,0x66,0xbd,0x38,0xe5,0x43,0xb,0x14,0x8,0xf1,0x8b,0xe2,0xea,0xa9,0x63,0xa1,0xd,0x22,0xe3,0x31,0x46,0x98,0x0,0x45,0xfa,0x67,0x10,0x40,0x86,0x68,0x69,0x8b,0xec,0xab,0x97,0x85,0x51,0x21,0xc,0x89,0x98,0xf0,0xb9,0x4f,0x7f,0x64,0x0,0xff,0x18,0x6c,0x8a,0xf8,0x57,0x7e,0xf8,0xfb,0xb0,0x2c,0x6b,0xf7,0x98,0xd2,0x66,0x54,0x80,0x3e,0x65,0x83,0x2c,0xcb,0x6a,0x4c,0xb,0x5,0x24,0x93,0xa5,0xfe,0x66,0x87,0xdd,0x84,0xc1,0x4b,0x28,0xa,0x9b,0xad,0xa7,0xd5,0xf6,0xed,0xe6,0xa6,0x28,0x3b,0xaf,0xa1,0x68,0x6c,0x15,0x4e,0xc8,0x5c,0xa5,0x69,0x6e,0xd0,0xf0,0x11,0xf5,0x7a,0xe2,0x6d,0xe5,0x86,0x38,0xba,0x84,0x5e,0xf5,0x32,0xe4,0x6d,0xc,0x2e,0xc5,0xb6,0x19,0xe8,0xa9,0xbe,0x7d,0x1a,0x32,0x91,0xa4,0x69,0xb7,0x24,0x5d,0x4d,0x40,0x34,0xc6,0x4e,0xb0,0x34,0xdb,0x28,0x1e,0x80,0xda,0xb4,0xeb,0xbf,0x35,0x3d,0x32,0x8a,0xcc,0x3a,0x44,0xf6,0xd0,0x33,0xcf,0x40,0x95,0x16,0x4b,0x22,0x30,0x33,0x18,0x93,0x25,0x3a,0x6,0xc0,0x92,0x95,0xf5,0x37,0x90,0x52,0x42,0x92,0x40,0xb,0x35,0xf5,0xd7,0x94,0x5f,0x10,0xa1,0x6c,0x9b,0x79,0x3c,0xc5,0x98,0x2c,0xc8,0x45,0x7d,0x99,0x14,0x1c,0x4d,0x29,0x23,0xa,0x3,0x50,0xcf,0x8d,0x35,0xd4,0x2,0x7c,0x46,0xd9,0xd7,0x9c,0xb3,0x31,0x1e,0x21,0x1,0x30,0x9a,0x18,0xcc,0x0,0x2a,0x37,0x8c,0x4d,0x82,0x5c,0xba,0x2f,0x54,0x30,0x6,0xa7,0x82,0x15,0xba,0x5d,0x9d,0x65,0x42,0x2,0x5e,0x86,0x2b,0xf6,0x9f,0x2,0x8a,0xa3,0xf1,0xbb,0xb7,0x73,0x77,0x81,0x21,0xda,0x73,0x79,0x49,0x95,0x37,0x5b,0xf,0x53,0x1c,0x3c,0xeb,0xf9,0xd4,0xde,0x3f,0x4e,0x6d,0x7,0x34,0x34,0xa9,0x16,0xf6,0xe9,0x6c,0xd4,0xf8,0xb5,0xf2,0x7b,0xe5,0xa0,0x7,0x1e,0x4f,0x2f,0xf,0x8f,0xd,0x28,0xd0,0x71,0x99,0xa8,0x5b,0x21,0xdc,0x2,0xd,0x38,0xf4,0x21,0x9a,0xd,0x84,0x82,0x77,0x1d,0xb0,0x80,0x25,0x1,0xaf,0xa7,0x3b,0xe4,0x65,0xc1,0xfd,0xa3,0x57,0x24,0x50,0x81,0x3f,0xb9,0xb3,0xc0,0x17,0x93,0x8f,0x72,0x38,0xc6,0xd,0x58,0xc4,0x25,0xcd,0x2e,0xcb,0xca,0xe0,0x58,0x14,0xb,0xa,0xd,0xf7,0xb8,0x81,0x71,0x44,0x49,0xaa,0xd,0x1a,0x72,0xe1,0xac,0x6,0x94,0xa5,0xc,0xfb,0x3f,0x59,0xca,0x3d,0x33,0x3,0x85,0xb9,0xb8,0x9e,0xb0,0x29,0x30,0x26,0xe9,0xef,0x37,0x71,0x21,0xa9,0x2c,0x8b,0x2b,0x7c,0x6c,0x63,0xf,0x37,0xa2,0x9e,0xee,0x7e,0x63,0x12,0xc7,0x76,0x79,0x40,0xad,0xd5,0x12,0x97,0x59,0xa6,0xcd,0xfb,0x2e,0x94,0x3a,0x9c,0xee,0x1e,0x59,0x3a,0xbc,0xee,0x93,0x5a,0x2c,0xf8,0xfb,0x81,0xaf,0xbd,0x79,0xc6,0x7f,0xf5,0xdf,0xff,0x2c,0x7e,0xe1,0x17,0xff,0xb1,0xb,0x4,0x1b,0xeb,0x47,0x3f,0xf7,0x7d,0xf8,0xcc,0xc7,0x5f,0xe7,0xed,0x3d,0xdd,0xf1,0x71,0xa,0x7d,0x3f,0xaa,0xb0,0xe1,0xcb,0x76,0x39,0x64,0x3d,0x6e,0x97,0x7,0x9b,0xdb,0x0,0x8,0xa0,0x1a,0xbb,0xf7,0xab,0x0,0x6e,0xd1,0x79,0xcc,0x6,0x1,0xfe,0x54,0xc2,0xee,0x53,0x80,0x2d,0xa1,0xde,0x9d,0x7b,0xff,0x7b,0xdc,0x7,0x73,0x4,0x87,0xb1,0x59,0xc8,0x88,0x30,0xe0,0xc8,0xdf,0x0,0xf9,0xb5,0xd1,0x5b,0xbf,0x99,0x70,0x88,0xc5,0xbd,0xbd,0x17,0x1e,0x45,0x11,0xf,0xfa,0x62,0xff,0x42,0x3a,0x40,0xb,0x3d,0xb8,0xef,0x23,0x80,0xf7,0x22,0x67,0x87,0xd,0xee,0x8e,0x51,0xf,0x41,0x99,0xde,0x7f,0xb3,0x66,0xcd,0x9a,0x0,0xe0,0xac,0x59,0xb3,0x66,0xbd,0xb8,0x8d,0xa1,0x81,0x76,0xc1,0x56,0x80,0x7d,0x30,0x8,0x49,0xea,0xaf,0x36,0x7,0x44,0xc,0x96,0xb0,0x9,0x7c,0xb1,0x77,0x66,0x49,0xed,0x55,0xf,0xbc,0x98,0x24,0x25,0x52,0x58,0x59,0x29,0x33,0x70,0xc8,0xe0,0xe,0xdf,0xbc,0x2f,0x4b,0xc6,0x8f,0x7e,0xee,0x33,0x87,0xdb,0xf5,0xc1,0xf,0xbc,0x86,0x4f,0x7d,0xf8,0x83,0x22,0x91,0xcd,0x66,0x24,0x9e,0x4,0x94,0xb2,0x30,0x8d,0x9d,0x24,0xb4,0x51,0x43,0xd9,0x36,0xf6,0xc,0x74,0xe9,0x82,0xea,0x45,0xa7,0xc1,0x14,0xea,0xad,0x7,0x6a,0x58,0x4f,0x77,0xd6,0x38,0x68,0x18,0x87,0x7a,0x31,0x69,0xda,0x6d,0x16,0xe9,0x5a,0x4c,0x22,0x1f,0x23,0x66,0x15,0xb6,0x46,0xce,0xc8,0x5c,0xd3,0x5e,0xb3,0x1d,0x3,0x95,0x3a,0xc7,0x98,0xb0,0x5d,0xce,0x5d,0x1a,0x16,0x13,0xb2,0x18,0xc6,0xef,0xc1,0x2f,0xd,0x5a,0x31,0x16,0x8e,0x0,0x55,0x6,0xe4,0xa5,0x1e,0xc4,0x12,0x53,0x36,0x66,0x43,0x4a,0xd9,0x64,0x63,0x79,0x59,0x6d,0xbf,0x95,0xcd,0xa8,0x4c,0x11,0x95,0x6c,0x9b,0x41,0x3d,0x7a,0xf0,0x8b,0x86,0x88,0xe8,0xf3,0xea,0xb,0x69,0x69,0xa1,0x29,0x5b,0x62,0xb3,0xfd,0x11,0x6,0x91,0x26,0xfc,0xea,0xf9,0x60,0xe0,0xa0,0x88,0xf4,0xb,0x96,0xf8,0xb,0x4,0x93,0x2b,0x47,0x61,0xee,0xa9,0xef,0x95,0x82,0xb6,0x24,0x80,0xa8,0x36,0xc2,0xdb,0x76,0xe1,0x40,0x91,0x22,0xde,0x64,0xe2,0x99,0xc8,0xbf,0x2b,0xd8,0xfe,0x6a,0x73,0x9f,0x52,0xe6,0x86,0x5f,0xfd,0x28,0x85,0x81,0xaa,0xf2,0x3c,0xfd,0x6d,0x24,0x39,0x57,0x1e,0xcc,0xb0,0x46,0x52,0xb6,0x43,0x1,0x58,0x12,0xbf,0x33,0x3,0xf4,0x40,0xc3,0x75,0xa3,0xd,0xa4,0x35,0x93,0xbb,0xbe,0x2b,0x4c,0x0,0x70,0xd6,0x73,0x2a,0xf,0x90,0x0,0x5d,0xb2,0xab,0xac,0x3d,0xbe,0x5e,0xba,0x7,0xdd,0x72,0xba,0x13,0xe6,0x5f,0xc1,0xe5,0x7c,0x1e,0x16,0x23,0x3c,0xeb,0x5a,0x3d,0x53,0x63,0x7c,0x5a,0xba,0x6d,0xb2,0xc5,0x23,0x65,0xf6,0x19,0xc8,0xef,0xfc,0x44,0x59,0xfa,0x5b,0x5d,0x58,0xc8,0xe2,0x16,0x9d,0x38,0xf8,0x49,0xbd,0x68,0x1,0x30,0xf0,0xf6,0x14,0xcf,0x4d,0xbe,0xd6,0xa3,0xd9,0x48,0x28,0x58,0x54,0xc5,0xeb,0xf0,0xe6,0xe5,0x28,0x2c,0xb0,0xed,0x72,0x66,0xb0,0x2c,0x44,0xd4,0x52,0x6d,0x7c,0x26,0x39,0x2e,0x3c,0x9e,0xac,0x1c,0x9e,0xe2,0xfc,0x11,0x1,0xa0,0x88,0x9d,0x83,0x26,0xdd,0x2e,0xa7,0x93,0x31,0xcc,0x6f,0xd5,0x76,0x7e,0x2,0xf5,0x2d,0x54,0x16,0x62,0x75,0x16,0x11,0x7e,0x41,0x6b,0x4,0x3b,0x65,0x9f,0x64,0xf1,0xc5,0xb6,0x4f,0x3c,0x5b,0x95,0x69,0xcd,0xb2,0xe0,0x7,0xbc,0xf9,0xf5,0xaf,0x9a,0xa4,0xf6,0xfc,0xf0,0xc4,0x16,0x56,0xf8,0x3d,0x8d,0x59,0xf4,0x48,0xf8,0x1f,0xfe,0xde,0x3f,0xc4,0x2f,0xfd,0xa3,0x7f,0x7a,0xc8,0x94,0x5c,0x96,0x8c,0xbf,0xf2,0xaf,0xfe,0x30,0xd6,0x25,0x77,0x69,0x6f,0x88,0x2,0xe4,0x6e,0xc3,0x2,0x1a,0x2f,0xf0,0x88,0x9d,0x85,0x8c,0x8f,0x7c,0x6e,0x78,0xb1,0x2c,0x2f,0x8b,0x85,0x42,0x69,0x8a,0xae,0x2d,0x70,0x91,0xcb,0xd9,0xd5,0x39,0x4f,0x17,0x93,0x9c,0x5c,0x38,0x88,0x4d,0x84,0x97,0xfb,0xf2,0xb1,0x89,0xee,0xf7,0x4f,0x9d,0xc9,0xe9,0x5e,0x33,0x4,0xb7,0x5f,0x5,0xf5,0xde,0xf0,0xda,0xdb,0xfd,0x5e,0x6e,0xa3,0xbb,0xf4,0xc,0x0,0x1e,0xdd,0xf8,0x72,0xf,0xe4,0xdd,0xfa,0xec,0x9e,0x46,0xac,0xd3,0xcf,0xfe,0x99,0xa3,0xad,0x91,0x75,0xad,0xae,0x36,0x76,0x4f,0xce,0x79,0x6a,0xd6,0xac,0x59,0x57,0xf3,0xe9,0x3c,0x4,0xb3,0x66,0xcd,0x9a,0xf5,0xe2,0x35,0x87,0xc3,0xff,0xa8,0x1b,0x60,0xf3,0x1d,0x77,0xe8,0x7e,0x4f,0xd4,0xe5,0x8f,0x41,0xc0,0x2a,0x4e,0xa3,0xe5,0x46,0x4d,0x65,0x45,0x51,0x1a,0x1,0xf5,0x4f,0xd2,0x15,0x6a,0xf6,0x70,0xca,0xc8,0x79,0xc1,0x27,0x5e,0xff,0x20,0xbe,0xf5,0x3,0xef,0xbb,0xd1,0x34,0x46,0xfc,0xd8,0xf,0x7e,0xa,0xff,0xf4,0x9f,0xff,0x21,0xaa,0x48,0x4e,0x8d,0xb1,0x96,0xc4,0x67,0xce,0x85,0x56,0xd4,0x5a,0xb1,0xac,0x2b,0xb6,0xcb,0xd9,0x18,0x65,0xfa,0x9a,0x1e,0xa2,0x11,0x11,0xd7,0xd5,0x3c,0xe8,0xa8,0x36,0x10,0x2,0x8a,0x24,0x60,0x2a,0x9b,0x31,0xc4,0xc4,0x3e,0x7a,0x79,0x11,0xc9,0x6b,0x35,0x10,0x29,0x84,0xc8,0xb2,0xa4,0xa0,0x8c,0xb2,0xe8,0x52,0x86,0x21,0x46,0xeb,0x55,0x7c,0xa1,0xb2,0x3b,0x6e,0x2,0x60,0xa,0x20,0xc7,0x7d,0x43,0x13,0xc0,0x35,0x21,0xae,0xa7,0x9e,0x22,0x5c,0xd8,0x2c,0xbe,0x8,0x70,0xa6,0x69,0x90,0xda,0xd8,0xf5,0xc6,0xa6,0x75,0x86,0x4,0x7a,0xa8,0x8a,0x7a,0x2b,0x41,0xe4,0x76,0xa,0x8a,0x2d,0xcb,0x2a,0x3e,0x4d,0x8b,0xa5,0xe5,0x2a,0xb,0x44,0xd9,0x99,0xad,0x55,0x44,0xd,0xc5,0xd0,0xed,0x56,0xa0,0xb5,0x55,0xdb,0x76,0xf5,0x1,0xd3,0x65,0x41,0x65,0x6e,0x64,0xd,0x3a,0x11,0xb6,0x5f,0x92,0x34,0x61,0x35,0xa8,0xd7,0xf7,0x46,0x93,0x0,0x13,0x96,0xd3,0x9d,0x35,0x91,0xa5,0x14,0x61,0x2a,0x76,0xd6,0x25,0x6f,0x3b,0x1f,0x1f,0x9c,0x1f,0x10,0x42,0x4f,0x3d,0xae,0x85,0x65,0x80,0x81,0x68,0x8,0x78,0xd1,0xa6,0x57,0xd9,0x90,0x2c,0xf3,0xee,0xbf,0x75,0x6,0x81,0x9b,0x93,0x10,0x8a,0x28,0x4a,0xce,0x57,0xf3,0x9,0xc2,0xd6,0x78,0xc6,0xab,0x6,0x92,0x1c,0xbb,0x45,0xe5,0x65,0xca,0x28,0x69,0xe4,0xa4,0x67,0xea,0x3b,0x38,0x6b,0xd6,0x73,0x19,0xe4,0x7b,0xc2,0x2a,0xf5,0x4e,0x1f,0xd4,0x2a,0xca,0x56,0xed,0xf7,0x59,0x5b,0x5,0x90,0x11,0xe5,0xfa,0xd,0xc2,0xc,0xae,0xb5,0x8a,0x6f,0x5e,0xf,0x97,0xe0,0x34,0xe0,0x86,0x28,0x8c,0xee,0x5b,0x88,0x5a,0x48,0x9,0xeb,0xe9,0x84,0x87,0x27,0x8f,0x91,0x52,0x66,0x89,0xaa,0x2,0x33,0xce,0xd3,0xd,0x80,0x2d,0xc6,0x28,0x60,0xa9,0xd2,0xdd,0xb0,0x2c,0x48,0x32,0x1e,0xe9,0x75,0x6d,0x36,0xe,0x37,0xbe,0xb7,0x88,0xe7,0x5d,0x4f,0x92,0x55,0xdf,0xd7,0x3a,0x78,0xcc,0x1d,0xe1,0x39,0xa5,0x5c,0x0,0x2,0x2e,0xf,0x4f,0xc4,0x5f,0x94,0x1,0x50,0x4d,0x43,0x57,0xf0,0xaf,0x94,0xb,0x72,0x5e,0xed,0x3b,0xf8,0xf3,0x37,0x5b,0x54,0x60,0x59,0xf0,0x9,0xe5,0x72,0x91,0x5,0x32,0xdc,0x3e,0x4e,0xe2,0xcb,0x8,0x22,0x59,0x5c,0x62,0x0,0xaf,0x50,0xf,0xc3,0x3a,0xdc,0xde,0xc6,0x63,0xdd,0x56,0x8a,0x1,0xa7,0x65,0x3b,0xdb,0x5c,0x51,0xb6,0xcd,0x18,0x8c,0xeb,0xe9,0x1e,0xdb,0xe5,0x1,0x8f,0xdf,0xfc,0x6,0x87,0x36,0x89,0xec,0xb6,0x46,0xde,0xe6,0x4b,0xad,0x1c,0xc8,0x5,0x9e,0x3b,0xff,0xe6,0xdf,0xfd,0x7,0xf8,0xc0,0x7b,0xdf,0x85,0x8f,0xbc,0xfe,0x1d,0x57,0xdf,0xfb,0x9d,0xdf,0xfe,0x41,0x7c,0xff,0x27,0x5f,0xc7,0x2f,0xfd,0xea,0x6f,0x8a,0x37,0xb0,0x3b,0x9f,0xce,0x23,0x56,0x95,0x5,0x6a,0x11,0x41,0xa1,0x32,0x30,0xea,0xc0,0x4d,0x1d,0xaf,0x95,0xcd,0xad,0xb,0x36,0xfd,0xd6,0x84,0x3d,0x6b,0x3d,0x38,0x65,0xa9,0xba,0x6d,0x1c,0x67,0xbd,0x7f,0x9d,0x4a,0x62,0xf5,0xfc,0x73,0x6c,0x30,0x6,0xc6,0xdf,0x21,0x72,0x47,0x6f,0x1,0xee,0x5d,0x1,0x82,0x47,0xc6,0x7b,0xe1,0x2d,0xfe,0x7f,0xfd,0x95,0xde,0x4f,0xb6,0x93,0xc6,0xe9,0x2d,0x37,0xc1,0xe7,0x82,0xe8,0x3,0x64,0xec,0xd1,0x6b,0x55,0x31,0xdd,0xb2,0x3,0xd4,0x70,0x96,0xa9,0x0,0x9e,0x35,0x6b,0x96,0xef,0xc9,0xe6,0x21,0x98,0x35,0x6b,0xd6,0xac,0x17,0x68,0x50,0x17,0x56,0x1c,0x4,0x34,0x31,0xd0,0x47,0x1a,0x3a,0x3,0x52,0x0,0x5b,0x6d,0xaf,0xb5,0x1a,0x33,0xb0,0x5c,0xce,0x26,0xff,0xf5,0xc,0xac,0xa1,0x9,0x70,0xcc,0xc2,0x94,0x7b,0xb3,0xf8,0xe7,0x3f,0xf7,0x69,0xe4,0x7c,0x9b,0x11,0xf1,0xd1,0xf,0x7d,0x2b,0xbe,0xed,0x7d,0xaf,0x1a,0x73,0x22,0xa5,0xd4,0xc1,0xac,0xd3,0x9d,0x31,0xbc,0x6,0xa9,0xe8,0xb2,0x8a,0x71,0xbc,0x32,0xff,0x92,0x49,0xb3,0x94,0x3d,0xa8,0xe1,0xd,0xcb,0x7a,0x77,0xd5,0xac,0xa8,0x2c,0x6e,0x3d,0xdd,0x77,0x20,0xa,0x3d,0xb4,0x44,0x93,0x32,0x73,0x5e,0xac,0x79,0x58,0xd6,0x13,0x52,0x5a,0x90,0x62,0x16,0x26,0xdc,0x22,0x9,0xbd,0xd1,0x85,0x64,0x34,0x63,0xb0,0x69,0x83,0xc3,0x40,0xd4,0x62,0xe7,0xa0,0xd5,0xea,0x9e,0xb,0x16,0xe4,0xa1,0x80,0x96,0x9a,0xcd,0x6b,0x3a,0xb1,0x4a,0x6f,0x53,0xe6,0xe6,0x98,0x8f,0x6f,0x1e,0x1a,0x2a,0x66,0xc6,0xf5,0x26,0x2b,0x2f,0x27,0x84,0x18,0xb1,0xac,0x27,0x63,0x3b,0x6a,0x88,0x8,0x9f,0xc7,0x66,0x32,0x2b,0x96,0x64,0x25,0x3,0x2b,0x63,0x4c,0x58,0x96,0xd5,0xd8,0x9c,0x44,0x8d,0x9b,0xf2,0x46,0xf2,0x38,0x33,0x13,0x63,0x8a,0xc2,0x98,0xe4,0x70,0x10,0x65,0x5c,0xda,0xfe,0xb4,0x86,0xb2,0x9d,0xaf,0x64,0x5b,0x39,0x2f,0x38,0x9d,0xee,0x8c,0x49,0xaa,0xcc,0x22,0x7d,0x9d,0x36,0x8c,0x45,0x41,0x3f,0x1,0x2e,0x3b,0xbb,0xa6,0x33,0x6c,0x34,0x29,0x94,0x8f,0xe3,0x22,0xc7,0xad,0xfb,0x43,0x75,0x39,0x31,0x8c,0xc5,0xaa,0xa6,0xf1,0x5d,0xb2,0x46,0x66,0xdc,0xf,0xa8,0x7,0x66,0x7,0x25,0xf7,0xcc,0x18,0x92,0xf7,0xdb,0xf9,0xb2,0x4e,0x8c,0xc1,0xc0,0xa7,0xf9,0x78,0xcd,0x9a,0xf5,0x27,0x59,0x41,0xc6,0x11,0xad,0xd6,0xa8,0xa7,0x5c,0x3b,0xb,0x4,0x95,0xeb,0x2b,0x0,0x10,0x85,0x19,0x98,0x73,0x16,0x7f,0xd7,0xd6,0xbd,0x32,0x3,0x7b,0x76,0x9a,0x75,0xc1,0x4e,0x66,0xdc,0x1,0xaa,0x66,0x60,0x54,0x2d,0x5,0xb5,0x16,0x94,0xed,0x2c,0xb,0x1c,0xc1,0x16,0x6d,0x74,0xe1,0x48,0xfd,0xf7,0x74,0x7c,0xce,0x12,0xa2,0xc4,0x1,0x22,0x19,0x59,0xc6,0xae,0xa8,0xb,0x32,0x74,0x43,0x97,0x49,0xcd,0x30,0x91,0xb2,0x5d,0xd0,0x6a,0xeb,0x6c,0xb7,0x5a,0xcc,0xc6,0xe0,0x8,0xfd,0x9,0x88,0x78,0xfc,0xc6,0xd7,0x10,0xc5,0x12,0xa1,0xd5,0x82,0x87,0xc7,0x6f,0x98,0x6f,0x62,0xce,0xb,0xd2,0xb2,0x20,0x20,0x60,0xdb,0xce,0x6e,0x41,0x28,0x20,0x65,0xb6,0xae,0x20,0xe2,0x71,0xb1,0xaa,0x1d,0x82,0x0,0xa1,0xb7,0xc3,0x52,0x78,0xe,0xa8,0xb5,0xe0,0x22,0x20,0x29,0xd,0x6c,0xc4,0x5b,0x27,0x17,0x12,0x5c,0xc2,0x52,0xde,0x37,0xbe,0xf6,0x65,0xb4,0x5a,0x71,0x39,0x3f,0x58,0x30,0xd5,0x76,0x39,0x4b,0xe8,0x14,0x3,0x75,0x97,0xf3,0x13,0xe,0x5,0xd9,0x2e,0x78,0xf2,0xe6,0x37,0x70,0x7e,0x78,0x2,0xa2,0x86,0x52,0x2e,0xb8,0x9c,0x9f,0x80,0x88,0xb0,0x5d,0xce,0x78,0xf3,0xf1,0x63,0xfc,0xcd,0x9f,0xfd,0x5,0x9c,0x2f,0xdb,0xd5,0xd7,0xa6,0x94,0xf0,0xe7,0xff,0xdc,0x67,0x10,0x25,0xe4,0xab,0x9,0x78,0xb8,0xac,0x77,0xd8,0x2e,0x17,0x6,0xb4,0x9c,0xd4,0xd8,0x8e,0xad,0x82,0x82,0xca,0x98,0x54,0xb9,0x76,0x76,0xcc,0x7c,0x8f,0xfb,0xb9,0xf0,0x26,0x5,0x8e,0xfb,0x67,0x76,0xb6,0x20,0x3c,0x13,0xdb,0x8,0x75,0x6e,0x2c,0x36,0x4f,0xe3,0x1d,0x58,0x47,0x47,0x48,0xd8,0xf5,0xff,0x87,0x84,0xe0,0xfd,0x67,0x1c,0x82,0x7d,0x74,0x0,0xd3,0x39,0x80,0xef,0x90,0xdd,0xd7,0xdd,0xf9,0xfc,0x53,0xfb,0x57,0xfa,0x4f,0xf,0x7b,0x70,0x6f,0xc0,0x98,0x77,0x2c,0xc0,0xbd,0xaa,0x38,0xdc,0x58,0x28,0x98,0x24,0xc0,0x59,0xb3,0x66,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x5e,0xcc,0x22,0xa7,0x1b,0xf1,0x37,0xea,0xa3,0xa,0x26,0x58,0xa0,0x1e,0x83,0x4a,0x8b,0xb1,0x2f,0xa2,0xb0,0x42,0x2c,0x89,0x57,0x3d,0x88,0xa4,0x39,0x53,0xef,0xa2,0x10,0x18,0x70,0x53,0x1f,0x9f,0xd7,0x5e,0x3e,0xe1,0x60,0xe3,0x39,0xdc,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x13,0xdf,0xf5,0xfa,0x53,0xb7,0x6d,0x5d,0x17,0xfc,0xd8,0xf7,0x7f,0x5c,0xe4,0xc4,0xab,0x81,0x61,0x1a,0x22,0xc1,0x1e,0x49,0xd1,0xa4,0x47,0xa,0xa,0xe9,0xdf,0xca,0xda,0x48,0x39,0x9b,0x4,0xac,0x49,0xe0,0x7,0x87,0x84,0x2c,0x58,0x4f,0x77,0xec,0xb9,0x24,0xe0,0xd1,0x7a,0x77,0x27,0x52,0x2b,0x52,0xfb,0x43,0x93,0xf7,0xa6,0x94,0xd,0x78,0xac,0xb2,0xd,0xfa,0x3e,0x92,0x54,0x4b,0x9f,0x52,0x6b,0x72,0x63,0x90,0x49,0x6d,0x35,0xb9,0x92,0xf7,0x61,0x31,0x3,0xfe,0x94,0x59,0x32,0xc,0x1,0xc2,0x54,0x9e,0xcb,0xdf,0x79,0x62,0x90,0x71,0x59,0x7a,0x53,0xee,0x3c,0xf9,0xf4,0x78,0x93,0x7c,0x5f,0x14,0x76,0x9b,0xb2,0x63,0x94,0x71,0xc7,0xde,0x89,0xcb,0xd0,0x2c,0xb0,0x1c,0x2f,0x1a,0xc0,0xa6,0x72,0x5a,0x5,0xb2,0xba,0xf7,0x23,0x1f,0xeb,0xb4,0xac,0x6,0x70,0x46,0x39,0xee,0x49,0xc,0xdc,0xab,0x98,0xd5,0x2b,0x20,0xd0,0x6a,0x33,0xd3,0x79,0x48,0x33,0x98,0x4,0x30,0x50,0x4f,0x42,0x5,0x84,0xd5,0xff,0xaa,0x8a,0xa7,0xa0,0x4a,0xa1,0x9,0x6c,0xfc,0xcf,0xde,0x8b,0x7c,0x3c,0xd6,0xd3,0x9d,0xfc,0xf6,0xb2,0x0,0x90,0x6d,0x68,0xe,0xb5,0xb8,0xc9,0x4f,0x20,0xaa,0x62,0xca,0x3f,0x7a,0x3,0x9a,0xa4,0x4c,0x8e,0xbb,0x1e,0x2b,0x95,0xfe,0x1a,0xd3,0x4f,0x9e,0x53,0x53,0x79,0x96,0x3d,0x8e,0x61,0x1f,0xbd,0x69,0x72,0x66,0xff,0xa,0x7f,0x8b,0xce,0xaa,0xdd,0x0,0x48,0x66,0xcd,0x7a,0x47,0xc6,0x7a,0xea,0x60,0x40,0x4c,0xfd,0xda,0x55,0x3f,0x56,0x9b,0x11,0x48,0x7c,0xed,0x0,0x17,0xa2,0x54,0x90,0xf3,0xea,0x16,0x50,0x64,0x31,0xc8,0xc2,0x25,0x16,0x63,0x73,0x5d,0x83,0x5a,0xc5,0xc6,0x9c,0x2c,0xa0,0x19,0x4b,0x68,0x79,0x2c,0x3f,0xdd,0x3d,0x12,0x86,0x6e,0x70,0xb,0x5,0x6e,0x6c,0x13,0x49,0x7f,0xd9,0x3a,0x8,0xd6,0xed,0x19,0x22,0xe2,0x21,0xa3,0x4e,0x6d,0x15,0x9a,0x4,0x22,0x15,0x94,0x72,0x61,0xaf,0xb9,0x9c,0x65,0xc1,0xa5,0xdc,0x9c,0x15,0x5b,0x2b,0xc,0x64,0x9d,0xcf,0xd8,0x2e,0x67,0x9c,0x9f,0x3c,0xb6,0xd0,0x11,0x1e,0xff,0xb,0xb6,0xf3,0xb9,0x87,0x17,0xc5,0xd8,0x43,0x36,0x9c,0xf,0x6a,0x90,0xb0,0x2b,0x4d,0xa1,0xbf,0x5c,0xce,0xb8,0x89,0xae,0x38,0x3f,0xdd,0xf5,0x74,0xc2,0xe3,0x37,0xbe,0x2e,0x12,0xec,0x7,0x19,0x73,0xea,0x4d,0x4,0x30,0x8,0x3b,0xb1,0x89,0x7,0xe1,0xc3,0xe3,0x37,0xb1,0x5d,0xce,0x78,0xf2,0xe6,0x37,0xf0,0xf0,0xf8,0xd,0x50,0x6b,0x78,0xf2,0xf8,0xd,0x7c,0xe3,0xab,0x7f,0x84,0xed,0x72,0xc6,0x76,0x7e,0xc0,0xf9,0xe1,0xb1,0x1,0xb2,0x44,0xd,0xdf,0xf8,0xea,0x97,0x71,0x39,0xb3,0x97,0xe0,0x93,0x37,0xbe,0x8e,0x5a,0x39,0xc5,0xf7,0x37,0x7f,0xf7,0x8b,0xf8,0x95,0x5f,0xfb,0xf5,0xc3,0x6f,0xfe,0xf0,0x87,0xbe,0x1d,0xdf,0xf9,0x81,0xd7,0xe0,0xbd,0x5d,0x81,0x31,0x15,0xda,0x18,0xd9,0xd4,0x6c,0xa1,0xa5,0xdb,0x3d,0x84,0x81,0x9d,0x6a,0xe9,0xef,0xea,0x3,0x48,0x18,0x2c,0x48,0xf4,0xf8,0x18,0xf0,0xe7,0xc1,0xb9,0x1d,0xb0,0x6a,0x21,0x66,0x3,0xcb,0x4f,0x41,0x43,0x43,0xa7,0x47,0x24,0xec,0x8,0x51,0x73,0xc7,0xf8,0x1a,0x82,0xf3,0x7f,0xf6,0xe0,0xde,0x15,0x6c,0x8,0x27,0xd8,0x1d,0x9,0x7b,0x34,0xbe,0xdb,0xcb,0x73,0x7,0x32,0xe2,0x1,0x21,0x91,0xdc,0xae,0x19,0xd1,0x91,0xae,0x90,0xc0,0x63,0x92,0xe2,0x9e,0xe9,0xa8,0xd7,0x37,0x4d,0xa,0xe0,0xac,0x59,0xb3,0x26,0x0,0x38,0x6b,0xd6,0xac,0x59,0x2f,0x6a,0x57,0x68,0x86,0xd0,0x70,0xc,0xb7,0x6e,0x4,0xf,0x63,0xdf,0x29,0xcb,0xaa,0x8a,0xac,0xca,0x3c,0xeb,0x94,0x49,0x21,0xa0,0x15,0xd0,0x65,0xab,0xb5,0x16,0x9,0xdd,0x60,0x90,0x4c,0x1b,0xce,0xbf,0xf4,0xc3,0x9f,0xc5,0xdd,0x69,0x7d,0xcb,0xcd,0xfb,0xf4,0x27,0x5e,0xc7,0xcb,0x77,0x1c,0xd4,0x51,0xab,0xb2,0xc,0x4f,0xc6,0xd2,0xea,0xe6,0xf2,0x9a,0x5e,0xd9,0x6,0xd0,0x8a,0xfd,0x85,0x58,0x7a,0x9b,0x72,0x46,0xce,0x99,0x53,0x29,0x45,0x36,0xac,0x5e,0x42,0x5d,0x2a,0x2c,0xec,0x38,0x1,0x1c,0xd5,0x7b,0x30,0x2f,0x92,0xf0,0xdb,0x98,0xf5,0x76,0x77,0xff,0x92,0xdd,0x49,0x37,0xaa,0xcc,0x6,0x51,0x80,0x2b,0x2f,0x92,0xfe,0xcb,0xe0,0xa1,0xfa,0xd5,0xe9,0x67,0x32,0xb0,0x27,0x7e,0x78,0xd4,0xbd,0xad,0x52,0x5a,0x18,0x90,0x93,0x63,0x6d,0xc0,0x9e,0xee,0x53,0x23,0xe4,0xf5,0x84,0x94,0x93,0xb0,0x43,0x60,0x8c,0xbf,0x65,0x3d,0x61,0x11,0x79,0x33,0x88,0xe4,0xff,0x77,0xb6,0x1d,0x8b,0x78,0xe4,0x99,0x84,0x58,0xd8,0x9a,0x10,0xa9,0x6f,0x4a,0x19,0xa7,0xbb,0x47,0x6,0xbe,0x31,0x28,0x1a,0x8c,0x55,0x47,0xad,0x61,0x39,0x9d,0xe4,0x27,0x23,0xa9,0xcb,0xb,0x27,0x1c,0x47,0x3,0x4f,0xef,0xc5,0x8b,0x11,0xcc,0xa0,0x5c,0x57,0xde,0xcf,0x10,0xc,0x68,0xc,0x21,0x20,0x2d,0xb,0x92,0x48,0xc3,0xb3,0xf8,0x43,0xe9,0x71,0x57,0x70,0x21,0x2f,0x8b,0xa5,0xe,0xab,0x2c,0x89,0xdc,0xef,0xd1,0x42,0x8,0x44,0xd6,0x17,0x24,0x1d,0x34,0xa5,0xe4,0xa4,0xc3,0xca,0xb2,0x74,0x1e,0x54,0x2,0x1e,0x58,0x78,0x41,0xe8,0xc9,0x8f,0x49,0x58,0x87,0x9e,0x85,0xd2,0xe5,0x64,0xbd,0xf3,0xf2,0xb2,0x5f,0x63,0xfc,0xa9,0x7f,0x95,0x49,0x1b,0x3b,0xc0,0xae,0xcc,0xc3,0x94,0x4f,0x73,0xbc,0x99,0xf5,0xdc,0xc6,0x79,0x72,0x72,0x46,0xd,0xe9,0xb1,0xdf,0x7a,0x80,0xb1,0x7d,0xf5,0x5a,0xd0,0x5,0x4,0x22,0x12,0x30,0x68,0xb3,0xf1,0x5d,0xd3,0x6c,0xf3,0xba,0x32,0x93,0xb8,0x14,0xb4,0x76,0xc,0x1a,0xa4,0xbc,0xa,0x40,0x18,0xd9,0x96,0x21,0x67,0x61,0xcf,0x31,0xc0,0xd8,0x5a,0x31,0xf0,0x8f,0x53,0xe9,0x65,0xce,0xc9,0x99,0x17,0x3e,0x84,0x7d,0xbd,0x48,0xc2,0xae,0x97,0xde,0xeb,0xe2,0xd4,0x11,0xd8,0xa9,0x7e,0x86,0x9a,0x8,0xf,0x0,0xe7,0x87,0xc7,0xc,0x6e,0x3d,0x25,0x59,0xd7,0x2,0x9d,0x62,0x30,0x7f,0xbd,0x52,0x36,0x54,0xf7,0x87,0x24,0x2c,0x85,0x8f,0xd5,0x82,0xb2,0x6d,0x58,0x4f,0xf7,0xb8,0x9c,0xcf,0x16,0x2c,0x94,0x5c,0xe8,0x10,0x8f,0x43,0x49,0x0,0xb0,0x76,0x73,0x2a,0x4e,0x99,0x93,0xcb,0x9f,0xbc,0xf9,0x86,0xf9,0xe9,0x6d,0x97,0x7,0x49,0xd7,0x6d,0x37,0xe0,0x3f,0x1e,0x93,0x2f,0xe7,0xb3,0x90,0xde,0x9a,0x30,0xf4,0x19,0x80,0xdc,0x2e,0x67,0x6c,0xdb,0x19,0x79,0x59,0xb1,0x9c,0xee,0x50,0x2e,0x97,0xe1,0xcd,0xad,0x56,0x94,0xed,0xc2,0xf3,0x47,0xad,0xc,0xc,0x56,0x66,0x7,0x96,0xb2,0xe1,0xfc,0xe4,0x31,0xfe,0xce,0xcf,0xff,0x12,0x2e,0xdb,0x35,0xb,0x70,0x5d,0x17,0x7c,0xea,0xbb,0xbe,0x5d,0x52,0xed,0x75,0x31,0x68,0x13,0xb9,0x38,0x6c,0xee,0xd2,0x71,0x58,0xbd,0xfe,0x74,0x61,0x4c,0x6d,0x30,0x9a,0x93,0x3c,0x9b,0xbc,0xdb,0x7,0x77,0x9,0x53,0xcf,0x7b,0x47,0x9a,0x5d,0x89,0x3,0xc0,0x3c,0x48,0xa7,0x9f,0x65,0x29,0xc1,0x84,0x63,0x30,0xcc,0x1e,0x10,0xe0,0x8b,0xae,0xe9,0x71,0xb4,0xf3,0xe8,0x3b,0x62,0xef,0xd1,0x95,0x99,0xca,0x48,0xb8,0x3b,0x8e,0xf3,0xd8,0x1,0x84,0xd4,0x83,0xe3,0xdd,0xc9,0x1d,0x11,0xc3,0x3d,0x11,0x31,0x1c,0xfc,0x20,0xf6,0x29,0xf4,0x76,0xed,0xd3,0x81,0xcf,0xe1,0x75,0xa0,0xd5,0xc,0xac,0x9a,0x35,0x6b,0xd6,0x4,0x0,0x67,0xcd,0x9a,0x35,0xeb,0x45,0x1d,0xd4,0x85,0xed,0x16,0xc4,0x27,0xcf,0x27,0x43,0x5a,0x42,0x2d,0x35,0x94,0x52,0xcc,0xa7,0x4d,0x19,0x23,0xea,0xc1,0xa7,0x20,0x95,0x82,0x43,0x49,0x53,0x79,0x25,0x74,0x41,0xd9,0x5b,0xa,0x80,0xbd,0x7c,0xbf,0xe2,0xb3,0xdf,0xf3,0xb1,0x67,0xda,0xbe,0x97,0x5f,0x7a,0x84,0x1f,0xfb,0xec,0xc7,0x2d,0x30,0x23,0xa6,0x8c,0xb4,0x48,0x4a,0x2f,0xc2,0xc0,0x80,0x63,0xe0,0x68,0x35,0x66,0xa2,0xb2,0x1,0xbb,0x7f,0x60,0x30,0xf,0xc3,0x26,0x26,0xeb,0x79,0x39,0x19,0xf3,0x4b,0x99,0x77,0x96,0x8,0x2b,0xc0,0x9a,0x9a,0x96,0x6b,0x63,0xa8,0x2c,0xc0,0xbc,0xac,0xec,0x59,0x25,0x7a,0x1d,0x5,0x42,0xb5,0xe1,0xc9,0x2b,0x3,0x97,0xca,0x9e,0xe3,0x14,0xcb,0x8c,0x18,0x5,0x28,0x25,0x98,0x21,0xbe,0x26,0x3e,0xe,0x9,0xb8,0x81,0x99,0x79,0xc,0xa4,0x56,0x91,0xc5,0xf6,0xa4,0xe5,0x94,0x99,0x1,0xa7,0x72,0x60,0x4d,0x51,0xd4,0x26,0x5d,0xbd,0x0,0x55,0xae,0xac,0xa0,0x5f,0xc,0x51,0xa4,0x69,0x1b,0xbf,0xd7,0x3c,0xef,0xc8,0x31,0x27,0x45,0x9e,0x9c,0x32,0xf2,0xba,0x9a,0x5f,0x54,0x2d,0x9b,0x35,0x67,0x9a,0xfc,0x18,0x53,0x96,0x64,0xe0,0xcc,0x7e,0x54,0xa4,0x69,0x98,0xc,0x2e,0xb2,0x14,0x97,0x4c,0xda,0x1c,0x63,0x12,0xc9,0xb2,0x80,0xa1,0xc2,0x4c,0x8c,0x31,0x76,0xf,0x30,0x22,0x9,0x72,0xa1,0xce,0x14,0x54,0xdf,0x41,0x79,0xde,0x58,0xa0,0x2,0xbc,0x72,0x22,0x74,0x32,0xb9,0xa0,0x4a,0xe8,0xb4,0xe1,0x54,0x39,0x99,0x79,0x45,0xed,0xfe,0xd4,0x52,0x5c,0xe0,0xa3,0x51,0xfb,0x2c,0x24,0x47,0xa5,0x76,0x70,0xef,0xef,0xec,0x92,0xd0,0xc1,0xd1,0x3,0x44,0x82,0x93,0xa1,0xb7,0x39,0xe0,0xcc,0x7a,0x6e,0x65,0x7e,0x96,0x6a,0xed,0xa0,0xb6,0xf,0x2,0xb0,0x2b,0xe0,0xc3,0x60,0x13,0xbf,0x47,0x41,0xae,0xf5,0x74,0xef,0x80,0x35,0x6,0x71,0x48,0xfe,0x94,0xb2,0x21,0xc4,0x9e,0xb6,0xbd,0xaf,0x46,0x3d,0x1d,0x77,0x39,0xdd,0x71,0x18,0x88,0x78,0x6f,0xf6,0xc4,0x72,0x9,0xba,0x58,0x16,0x1b,0x6b,0x7d,0x8,0x8f,0x6e,0xa7,0xb2,0x9f,0x83,0x1,0x44,0xed,0x6,0x58,0x11,0x50,0xeb,0xe6,0x7c,0x42,0x8b,0x81,0x1e,0xca,0x36,0xbe,0xe5,0xc9,0x19,0x42,0x34,0x6,0x33,0x64,0x5c,0x0,0x11,0xb6,0xf3,0x59,0xc0,0x2a,0x9e,0x4f,0xd2,0xb2,0xb2,0xc7,0xea,0xba,0x9a,0x2f,0xad,0x5a,0x51,0xb4,0xd6,0xcc,0x57,0x35,0x48,0xf0,0x13,0xc4,0xb2,0xe0,0x16,0xb8,0xe2,0x7d,0x73,0x43,0xe4,0xb9,0x8b,0x65,0xd2,0x71,0x18,0xfb,0xae,0xa1,0x2b,0x5e,0x64,0xb8,0x7b,0xf4,0x12,0x7b,0x1,0x9e,0x1f,0xf8,0xdc,0x80,0xa5,0xcf,0x4f,0x1e,0xbf,0xc1,0x6c,0xc0,0xc7,0x6f,0xe0,0x8d,0xaf,0x7f,0x5,0xad,0x55,0xbc,0xf9,0xf5,0xaf,0xe2,0xf1,0x37,0xbe,0x86,0x87,0x27,0x8f,0x51,0xcb,0x86,0x52,0x36,0x1,0xa,0x2f,0xb2,0x1f,0x49,0x12,0x7c,0x19,0x98,0xfb,0xad,0xdf,0xfb,0x22,0xfe,0xf0,0xb,0x5f,0x3a,0xfc,0xfe,0x4f,0x7d,0xe2,0x23,0xb6,0x38,0x47,0x8d,0x3d,0xf7,0x6a,0x2d,0xc,0xf2,0x6a,0x7a,0xb1,0x63,0x3,0x6a,0x70,0x55,0x13,0x16,0x68,0x1f,0x6f,0xbb,0x4f,0xaa,0x82,0x81,0x9a,0x44,0x6d,0xfb,0xaa,0xcf,0xd7,0xea,0xa4,0xbb,0x64,0x0,0xe1,0xe0,0x1b,0x18,0xd0,0x99,0xda,0x57,0xc8,0xdf,0x80,0xb0,0xe1,0x98,0x95,0x79,0x15,0x3,0x3c,0x0,0x7b,0x7c,0xfd,0x8c,0xe0,0xdd,0xf8,0xc9,0xa1,0xbf,0x9b,0x76,0x3e,0x7c,0xb7,0xc0,0xc8,0xb0,0xfb,0x1c,0x9f,0xd8,0xb1,0xc3,0x25,0xc3,0x15,0xc8,0xb7,0xff,0x7c,0x2f,0x7d,0xde,0xef,0xa7,0x5f,0xd4,0xa2,0x83,0xdd,0x9e,0xc,0xc0,0x59,0xb3,0x66,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x5e,0xc8,0x52,0x46,0x18,0xec,0x1e,0x92,0xfa,0x4d,0x7b,0xe8,0xec,0xae,0x9c,0xd9,0x7b,0xc9,0x3,0x1a,0xa,0xae,0x84,0x0,0x63,0xca,0x29,0x5b,0x44,0x65,0x96,0x76,0xb3,0x2a,0x21,0x11,0x0,0xf0,0xd9,0x4f,0x7e,0x18,0xef,0x7a,0xf9,0xa5,0xab,0x6d,0x29,0xf5,0xb8,0x21,0xfb,0xbe,0x4f,0xbe,0x8e,0x1c,0x61,0x49,0x93,0x39,0x2d,0x68,0xb5,0x98,0xfc,0x58,0xc1,0x3b,0x6d,0x10,0x7c,0x72,0xeb,0xe9,0xfe,0x25,0x49,0xc7,0x4d,0xc6,0x8,0x59,0xef,0xee,0x91,0xf3,0x6a,0x52,0x5f,0x4d,0x86,0xd,0x2e,0xe9,0x36,0x2f,0x27,0x9c,0xee,0xee,0xd,0xfc,0xea,0xb2,0x66,0x58,0x83,0xa4,0x2c,0xc3,0xd3,0xfd,0x23,0x1,0xc0,0x92,0xbb,0x43,0xf,0xc6,0x8,0x33,0x89,0x6f,0x8,0x28,0x5b,0x97,0x48,0xdd,0x3d,0x7a,0x89,0x4d,0xcf,0x5b,0x33,0xa0,0x4c,0x13,0x83,0x53,0xca,0x8,0x29,0xd9,0x76,0x2a,0x20,0x95,0xf2,0x62,0x8d,0x64,0x8,0x1,0xc1,0x35,0x86,0x6,0xf0,0xc5,0x68,0xc,0x3a,0x6d,0x42,0x6b,0xe1,0x6,0x6d,0x39,0x9d,0x4c,0xd2,0xbc,0xae,0x77,0x96,0xe0,0xac,0x49,0x8d,0x79,0x5d,0xc5,0xef,0x2f,0xba,0x6,0x83,0x3d,0x11,0xd3,0xc2,0xfe,0x4e,0xcc,0x66,0x3c,0xc9,0xb1,0xcf,0x83,0x74,0x3c,0x4,0x74,0x0,0x58,0x9a,0x2f,0xf3,0x19,0x84,0x3,0x9,0x44,0x82,0x1d,0x42,0xe4,0x90,0x81,0x52,0x86,0x94,0x65,0x95,0x4,0x86,0xe8,0x12,0x21,0x5b,0x97,0xec,0x7a,0x20,0x4f,0xbd,0xc0,0x94,0xa1,0xa9,0xc7,0x71,0x59,0x7b,0x22,0x70,0x14,0xaf,0x42,0x6a,0xcd,0x0,0x6,0x38,0x89,0xb3,0xfe,0x7e,0x47,0x16,0x4,0x2c,0x38,0x84,0x9c,0x31,0xba,0x1a,0xda,0x5b,0xb3,0x39,0xec,0x7f,0x3c,0x6c,0x26,0xa9,0xb6,0x9b,0xc,0x9e,0x59,0xb3,0xde,0x1,0xf4,0xcf,0x31,0x0,0x5b,0xf7,0x61,0x3,0x33,0xdc,0x74,0xac,0x50,0x59,0x7f,0x7,0xb2,0x83,0x3,0xa8,0x92,0xbc,0xb6,0x2f,0xa6,0xb4,0x56,0x65,0xec,0xd,0xc6,0x2a,0x3c,0x2,0xb6,0xc,0x40,0x6c,0x8d,0x17,0x92,0x94,0xf5,0x65,0xfe,0x78,0x51,0x16,0x10,0x44,0x36,0xab,0x12,0xff,0xcc,0xec,0xe8,0xbc,0xc8,0x2,0x0,0x2,0x62,0x12,0x4f,0x38,0x61,0xa4,0x1f,0x3,0x79,0x84,0x98,0x24,0x31,0x3e,0x76,0x8f,0xd3,0x18,0x13,0xce,0xf,0x8f,0x9f,0x9a,0x74,0x4a,0x92,0x28,0xbb,0xac,0x27,0xf3,0xaf,0x7d,0x78,0xf2,0x98,0x83,0x38,0xca,0x86,0x52,0x37,0xd4,0x52,0x70,0x7e,0x78,0x8c,0x18,0x13,0x1e,0x1e,0xbf,0x81,0xb2,0x5d,0xfa,0x82,0x80,0x80,0x95,0x97,0x87,0x2e,0x1b,0x86,0xfa,0x98,0x3e,0x25,0x8,0x48,0xe7,0x13,0x10,0x21,0x86,0x2e,0xa7,0xde,0xce,0xf,0x32,0xaf,0x6e,0x37,0x1,0xcb,0x28,0x4c,0x37,0x66,0x58,0x2e,0x78,0x78,0xf2,0xa6,0xc9,0xb3,0x95,0xad,0xde,0x4a,0xc1,0xfd,0xa3,0x97,0x71,0x39,0x3f,0xe0,0xfe,0xe5,0x77,0xe1,0x74,0xff,0x92,0x1,0x96,0xe7,0x27,0x8f,0x6d,0x1b,0x52,0x5e,0xd8,0x23,0xb0,0x16,0x5c,0x9e,0x3c,0x66,0x49,0x78,0x29,0xf8,0xf5,0xdf,0xf8,0xfc,0xe1,0xf7,0xbf,0xff,0xbd,0xef,0x41,0x82,0xce,0xbb,0x63,0x38,0x98,0xf7,0x6f,0xf4,0x5e,0xb6,0x75,0xdb,0x6c,0x91,0x46,0xe7,0xaf,0x68,0x96,0x22,0x3c,0x87,0x92,0x78,0x38,0x12,0x94,0xcd,0x17,0xba,0x8c,0x18,0x70,0xe3,0x69,0xe8,0xb,0x33,0x2,0xc,0x87,0xe0,0xbd,0xfd,0xba,0x50,0xf8,0x1a,0x73,0xdb,0x4b,0x76,0xf,0xe0,0x3f,0x93,0xe7,0x3a,0xb6,0x1e,0x75,0xeb,0x94,0xbe,0x68,0x84,0xa7,0x4,0x83,0xec,0x40,0xb5,0x70,0x0,0x4,0xe,0x6f,0x39,0x2,0xf4,0x46,0x80,0xce,0x82,0x4d,0x6e,0xd1,0x3,0xed,0x73,0x9e,0x46,0x7d,0xbc,0x3e,0x12,0x8d,0xea,0x1c,0x2f,0x67,0xcd,0x9a,0x35,0xd4,0x4c,0x1,0x9e,0x35,0x6b,0xd6,0xac,0x17,0xaa,0xba,0x44,0x91,0x1a,0xcb,0x24,0xcd,0x4f,0x87,0x80,0x56,0x1b,0x42,0x60,0x26,0x44,0xac,0x10,0xb6,0x5c,0xb6,0x14,0x59,0x95,0x95,0xa6,0x9c,0xcd,0x9b,0xcf,0xfb,0x38,0x29,0x4b,0xaf,0xd5,0x82,0xd3,0xfd,0xcb,0x88,0x1,0xf8,0x91,0x1f,0xfc,0xb4,0x19,0x87,0xfb,0x7b,0xe3,0xbf,0xff,0xf,0x7f,0x15,0x3f,0xf2,0x83,0x9f,0xc2,0xba,0x8c,0x53,0xcd,0x7b,0x5f,0x7b,0x15,0xdf,0xff,0x89,0xf,0xe1,0x17,0x7f,0xf5,0xf3,0x2,0xc6,0x10,0xb2,0xb0,0x2f,0xd8,0x70,0xfc,0x3c,0xfa,0xb9,0x51,0x34,0x6,0xc6,0x76,0x79,0xb0,0x6d,0x82,0xa4,0xc9,0xb6,0x5a,0xb1,0xde,0xdd,0x31,0x6b,0x21,0x70,0x53,0xe9,0xc1,0x32,0x5,0x2a,0x89,0xb8,0x69,0xca,0xeb,0x89,0x99,0x6f,0x81,0x9b,0x52,0x94,0x8d,0x1d,0x81,0xd4,0xbc,0x5c,0xbd,0x8,0x63,0x44,0xa,0x8b,0xd8,0xc4,0x31,0x80,0xd6,0xc4,0xd3,0x8e,0x83,0x4b,0xee,0xd,0x4c,0x6c,0xc4,0xc6,0xf8,0xa7,0xd3,0xbd,0x49,0x54,0x4b,0xd9,0xfa,0x31,0x93,0xb4,0xe4,0xba,0x6d,0xf2,0xef,0xc5,0xe4,0x5c,0xfa,0x6f,0x6d,0x68,0x15,0xc4,0x2,0x9,0x50,0x26,0x3e,0x82,0xc8,0x64,0x6c,0x3e,0x6d,0xea,0x43,0x88,0x58,0xef,0xee,0x51,0x4b,0x91,0xed,0x67,0x76,0x4b,0xca,0xb,0x32,0x16,0x34,0x6a,0x38,0xdd,0x3d,0xb2,0x6d,0xa1,0xed,0x62,0x20,0x1f,0x8c,0x6c,0xc3,0xc,0x9c,0x9c,0x33,0xb6,0xcb,0x85,0x1b,0x2f,0xf3,0x55,0x5c,0xd,0x20,0x5,0xc0,0xd2,0x33,0x69,0xf4,0xf2,0xc2,0x52,0x39,0x65,0x5f,0x32,0x13,0xa8,0xd8,0x73,0x16,0xb0,0x21,0x9e,0x80,0xb5,0x56,0x2c,0xa9,0xcb,0xb0,0xa9,0x55,0x2c,0xeb,0x9d,0x98,0xcd,0xe7,0xde,0xb4,0x88,0x2f,0x25,0xb3,0x8c,0x16,0x6c,0xe7,0x7,0x3,0xa3,0x73,0x5e,0x51,0xea,0x66,0x81,0x21,0x9c,0xae,0xd9,0xb8,0xa9,0x13,0xb9,0x72,0x8c,0x49,0x7e,0xcf,0xc1,0xc0,0x6d,0xec,0xe4,0x67,0xd,0xcd,0xa1,0xe4,0x34,0xb0,0x2a,0xc,0x38,0xd7,0xa6,0xd4,0xc7,0x2e,0x4a,0x13,0x1a,0x62,0xb8,0x91,0xfd,0x38,0x6b,0xd6,0x3b,0x30,0xca,0xcb,0x35,0x47,0xb8,0x66,0x55,0xa1,0x36,0x1b,0x23,0xc3,0xce,0x57,0x34,0xca,0x75,0x5d,0xb,0xfb,0x69,0xc6,0x94,0x1,0x6a,0xa8,0x85,0x8c,0x91,0xcd,0xe0,0x47,0x0,0x6e,0x30,0xd4,0x72,0xc,0x78,0xf7,0xa3,0x13,0xd6,0x50,0x40,0xb4,0x2,0xad,0xe2,0xfc,0xc0,0xd7,0xe2,0xba,0x2c,0xcc,0xdf,0x8a,0x1,0x29,0x45,0x84,0xc4,0xac,0x6a,0xa2,0xa,0xb2,0xb1,0x13,0xa8,0x2,0x26,0xc5,0xb4,0xe0,0xe1,0xc9,0x63,0xdc,0x3f,0x7a,0x19,0x44,0x84,0xfb,0xbb,0xd3,0x31,0x98,0x27,0x73,0xce,0x76,0xb9,0x18,0x70,0xa4,0x89,0xea,0x31,0x26,0xf1,0xd5,0xbb,0x81,0x95,0xca,0x31,0x3a,0x3f,0x3c,0xe6,0xc0,0xa4,0xd3,0x9,0x21,0x0,0x5f,0xfe,0xc2,0xef,0xe3,0xd5,0xf7,0x7d,0x8b,0x1d,0x93,0x75,0xbd,0x43,0xa3,0x86,0x45,0x82,0x95,0xba,0x57,0xaa,0xc8,0x55,0x8d,0xa1,0x1c,0x6,0x90,0xeb,0x56,0xc5,0x18,0x51,0x2e,0x17,0xf6,0x2d,0x14,0x10,0xa6,0x6c,0x1b,0x96,0x75,0x95,0x85,0xa3,0x63,0xd0,0xb2,0xb5,0x6a,0xe3,0x2a,0x0,0x19,0xbb,0x19,0xac,0x5,0x11,0xaa,0x84,0x41,0xe5,0x7b,0x1e,0x23,0x55,0x56,0x5d,0x25,0x71,0xbd,0xd6,0x8a,0x97,0x5e,0x79,0x15,0x65,0xbb,0x60,0xbd,0xbb,0x17,0x7b,0xc,0x20,0x2f,0x27,0xb3,0x36,0x20,0x22,0x7c,0xfe,0xb7,0x7f,0xff,0xf0,0xfb,0x5f,0x7e,0xe9,0x11,0x5e,0x7d,0xe5,0x11,0xfe,0xf0,0x8f,0xbe,0x26,0x8b,0x59,0xd1,0x82,0x62,0x94,0x15,0xd9,0xd0,0x17,0x83,0x74,0x3e,0xea,0x3,0x64,0x7,0xa3,0x15,0x54,0x8e,0x21,0xa2,0xc1,0x8d,0xc3,0x36,0x78,0x86,0x1,0xd4,0xee,0x18,0x57,0x13,0xe6,0xa5,0x30,0xe4,0x8d,0xa9,0x1d,0x45,0x12,0x8d,0xbe,0x88,0x14,0xc8,0x0,0x3d,0x1d,0xdf,0xbb,0xa8,0xd7,0x1,0xe5,0x3e,0xd7,0xe3,0x0,0x50,0x1f,0x80,0xbc,0xb0,0xdb,0x3c,0x72,0x32,0x61,0x9b,0x2a,0xc2,0x31,0xd0,0xe7,0x91,0xc4,0x70,0xe3,0x39,0xec,0x1f,0xb,0xcf,0x4,0xea,0xd9,0xb6,0x3e,0x15,0x4,0xdc,0xed,0x6e,0x98,0x5c,0x9f,0x59,0xb3,0x66,0x4d,0x0,0x70,0xd6,0xac,0x59,0xb3,0x5e,0xdc,0xc6,0x50,0x1a,0xa3,0x0,0xa0,0x81,0x8c,0xad,0xc5,0x60,0x5a,0x97,0x5b,0x12,0x11,0x1a,0x69,0x2a,0x2b,0x37,0x14,0xea,0x8f,0x16,0x10,0x2c,0xf0,0x81,0x93,0x66,0x57,0xe8,0x7a,0x79,0x72,0xfe,0x7b,0xb5,0x6c,0xf8,0xc4,0x47,0xbe,0xd,0xdf,0xfe,0xc1,0xf7,0x5f,0x6d,0xc7,0x57,0xbf,0xfe,0xd,0xfc,0xfc,0xff,0xf5,0xcf,0xf0,0xc1,0xf,0xbc,0x86,0x4f,0x7c,0xe4,0xdb,0x77,0x8d,0x51,0xc0,0x9f,0xfb,0xcc,0x47,0xf1,0xcb,0xff,0xe4,0xf3,0x68,0x31,0x99,0x17,0x55,0xd9,0xb6,0x21,0x31,0x96,0x43,0x1f,0xb2,0x3c,0x2f,0x8d,0xa9,0x48,0xdb,0x4e,0x77,0x8f,0x70,0x39,0x3f,0x1,0x0,0xe,0x8e,0x10,0x20,0x27,0xa,0x33,0x30,0xb4,0xe8,0x0,0xa0,0x88,0x9c,0x57,0xf1,0x89,0xe2,0xc4,0xdb,0x16,0x22,0xb2,0x78,0x16,0x26,0x61,0xaa,0xe5,0x55,0x5e,0x23,0x1e,0x77,0x6c,0x5c,0x4e,0x9c,0x66,0xd8,0x18,0xf4,0x59,0x17,0xf6,0xe5,0x53,0x3f,0x27,0x65,0xf8,0xa1,0x1,0x41,0xa4,0x5e,0xa1,0x5,0xc4,0xa8,0x81,0x25,0xb,0x6a,0xb9,0x74,0x26,0xc3,0x12,0x6c,0xa5,0xbf,0x96,0x62,0x5e,0x56,0x49,0x64,0x74,0xea,0x5,0x8,0x40,0x82,0x4e,0x9a,0x49,0x8a,0x8d,0xc5,0x13,0x82,0x0,0xae,0xd9,0xfe,0x9f,0xc5,0xe3,0xaa,0x9,0xe3,0xc2,0x82,0x53,0xa8,0xd,0xcd,0x0,0xcb,0x70,0x99,0x95,0x13,0x1,0x4b,0x95,0xd4,0x64,0xcc,0x65,0x3d,0xa1,0x94,0xb,0x7,0x9e,0x8,0x5b,0x47,0xbf,0x3b,0xe5,0x5,0x6b,0xb8,0x93,0x26,0xb5,0x71,0x12,0x65,0x88,0x16,0xc8,0x12,0x43,0x4,0x12,0xfb,0x7c,0x15,0x49,0xb9,0x54,0xcf,0x26,0xf5,0x72,0xe4,0x66,0x92,0xc1,0x66,0xa8,0x84,0x38,0x25,0x4b,0x4,0x26,0x4e,0xf7,0x10,0x6,0x21,0x3,0xa9,0xcb,0x7a,0x42,0xad,0xd5,0xd8,0x7b,0x5d,0xa5,0x1b,0xba,0xfc,0x3b,0x76,0xc9,0x58,0x8,0x9,0xca,0xd0,0x31,0x89,0xb1,0xc8,0x86,0x59,0x1a,0xdd,0xc6,0x44,0xeb,0xd0,0x41,0x41,0x4b,0x10,0x6,0xec,0x5a,0x20,0x1a,0xdc,0xd5,0xed,0x1a,0x42,0x48,0x0,0xcd,0x20,0x90,0x59,0xef,0x7c,0x99,0x17,0x9a,0xa9,0xfe,0x78,0xfc,0x33,0xab,0x81,0xa6,0xc9,0xdf,0x9a,0xde,0xdd,0x65,0xfc,0xcc,0xa8,0xd5,0x45,0x15,0x5,0x8,0x78,0x1,0x83,0x7d,0x52,0x2b,0x5f,0x7b,0xed,0xf8,0xb7,0xfd,0xfd,0xdf,0xfb,0x71,0x7c,0xcf,0x27,0x3f,0x62,0x60,0x8c,0x85,0x33,0xc8,0xe6,0xc4,0x10,0xd0,0x6,0x29,0x68,0xdf,0xc6,0xf1,0xff,0x7a,0xad,0xf6,0xeb,0x2a,0x80,0x81,0xc3,0xa3,0xfd,0x4d,0x92,0x58,0x6e,0x73,0x98,0x30,0xad,0x63,0x8c,0xd8,0xce,0xf,0x37,0x81,0x10,0x4d,0xb4,0x5f,0x4f,0x77,0xec,0xc5,0x17,0xfe,0x3f,0xf6,0xde,0xb3,0xd9,0xae,0xeb,0x3c,0x13,0x7c,0xd6,0x5a,0x3b,0x9c,0x73,0x6e,0x40,0x26,0x32,0x11,0x8,0x6,0x30,0x83,0x41,0xc,0xa2,0x44,0x89,0x94,0x6d,0x5,0x7,0xb5,0xdb,0xee,0x50,0x5d,0xed,0xea,0x71,0x7b,0xc2,0xd7,0xa9,0xae,0xe9,0xaf,0xfd,0x7,0xa6,0x6b,0x66,0xba,0xa6,0xda,0x33,0x5d,0x1d,0xdc,0xe,0x63,0xcb,0x1a,0x4b,0x2d,0x39,0x28,0x51,0x89,0xa4,0x28,0x31,0x83,0x60,0x0,0x41,0x80,0x0,0x88,0x9c,0x2e,0x80,0x1b,0xce,0xd9,0x69,0x85,0xf9,0xf0,0xbe,0x6b,0xed,0x7d,0x12,0x48,0xc9,0x12,0xe9,0x81,0xf7,0xcb,0x62,0xe1,0xde,0x73,0xcf,0xd9,0xf9,0xac,0xbd,0xdf,0x67,0x3d,0x41,0x60,0xb0,0xb2,0x84,0x55,0x6b,0x37,0xa0,0x2c,0x32,0xc4,0x31,0xfb,0x1e,0x5a,0x66,0x36,0x27,0xb4,0x7e,0xab,0x9,0xa4,0xd4,0xba,0xa,0xa1,0x50,0x71,0x97,0x6d,0x9,0x78,0xfc,0xf7,0x4c,0xeb,0x89,0xf7,0x62,0xd0,0x4,0x4a,0x9e,0xf5,0x61,0x8d,0xd,0xa9,0xee,0x11,0x33,0xf2,0xa6,0x2,0x37,0x42,0x22,0x4a,0x62,0xe4,0x3,0xcb,0x1,0x22,0x1d,0xa,0xfe,0xe0,0x14,0xe2,0x10,0xae,0x12,0x45,0x21,0xa8,0x44,0x40,0xa0,0xdb,0x9b,0xa5,0x49,0x31,0x6,0x4c,0x7b,0x73,0xf3,0x4,0xd0,0x9,0xa0,0xd3,0x9d,0x85,0xd6,0x4,0x3e,0x12,0x98,0x68,0x70,0xe1,0xf2,0x12,0xb4,0xd6,0x61,0xf2,0xc5,0x97,0x52,0xa,0x6b,0xe7,0x3a,0x38,0x7d,0xee,0x22,0xb1,0x2d,0x9d,0x18,0x4a,0x43,0xf,0x72,0x5e,0x20,0x1c,0x37,0xc3,0x89,0xcc,0x42,0x88,0x70,0x9d,0xd5,0xe7,0xbf,0xb6,0xea,0x8,0xd7,0x2a,0x1c,0xe1,0x67,0xc2,0x33,0xff,0x44,0xc0,0xc2,0xbc,0x14,0x5c,0x48,0x15,0xfc,0x15,0xfd,0x75,0xe6,0x1a,0x8c,0xee,0x21,0x3f,0xc1,0x30,0x61,0x33,0xc,0xda,0x41,0xb8,0xa1,0xf9,0x9b,0x0,0xe6,0x8d,0x12,0xec,0x46,0x25,0xb9,0x6e,0x34,0xf9,0xb7,0x71,0x17,0x6d,0x26,0x1b,0xbb,0x49,0x48,0xdf,0x68,0x8a,0x7,0xa6,0x0,0x7c,0x62,0x2,0x80,0x27,0xae,0x9,0xea,0x85,0xf5,0xbf,0xff,0x93,0xe0,0xfb,0x2d,0xa5,0xad,0xb6,0xda,0x6a,0x1,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xb6,0xae,0x87,0xf2,0xbe,0x75,0x7e,0xf6,0x1b,0x2c,0xf9,0xd,0x7e,0x46,0xf0,0xc9,0xbf,0xc4,0xec,0x12,0x32,0xe,0x9,0x7d,0xce,0x9b,0x70,0xb,0x17,0x3c,0xe8,0x88,0x51,0x55,0xb3,0xd3,0x4,0x37,0x35,0xe,0xe,0x71,0x92,0xe0,0xb1,0x7,0xee,0x40,0x14,0x8d,0xa7,0x45,0xbe,0x7d,0xf4,0xc,0xb2,0xd2,0xe0,0xf9,0x3,0xef,0xe2,0xa6,0x1b,0x37,0x8f,0x35,0x75,0x5b,0x36,0x6d,0xc0,0x8e,0x8d,0xab,0xf1,0xce,0xc9,0x8b,0x30,0x5a,0xd7,0x5e,0x55,0xc,0xd2,0x48,0x4e,0x9f,0x15,0x92,0x0,0x22,0x2,0xef,0x54,0xf0,0xbb,0xd3,0xba,0x62,0x19,0x1a,0x3d,0xe2,0xaa,0x28,0x86,0x8b,0x5c,0xd8,0x3f,0xf,0x24,0xfa,0x66,0x41,0x4a,0x89,0xca,0x5a,0xc4,0x51,0xc,0xc0,0x21,0xe9,0x74,0x60,0x35,0x79,0x32,0x45,0x2c,0xa1,0xa5,0x6,0x9a,0xbd,0xa8,0xc0,0xc6,0xf5,0x71,0xca,0xfe,0x47,0x11,0xcb,0xdd,0x34,0x99,0xab,0x73,0x30,0x86,0xd1,0x9a,0x1b,0x66,0x55,0xfb,0xd3,0xb1,0x5c,0xca,0xfb,0x48,0x29,0xa5,0x82,0x99,0xbb,0x90,0x12,0xb0,0x6,0xd6,0xba,0x10,0x72,0xe2,0x3d,0xd,0xe3,0xb4,0x13,0xe4,0x66,0x9e,0xe1,0xa8,0x54,0x12,0x7c,0x18,0xad,0x25,0xa3,0x7a,0xa,0xe8,0xe8,0xd5,0xa0,0x19,0x3,0x92,0xc4,0xd8,0x94,0xd,0x46,0x9e,0x82,0xd1,0x24,0xe3,0x8a,0xd9,0x8b,0x4f,0x0,0xb0,0x96,0x18,0x33,0x49,0xda,0x81,0xe6,0x46,0xd2,0x59,0x62,0x17,0x1a,0x5d,0x41,0xc9,0x8,0xd6,0x99,0xda,0xaf,0x50,0x13,0x30,0x8,0x21,0x50,0xf1,0xfe,0x4b,0x96,0xfc,0x45,0xdc,0x90,0xfa,0x4,0x47,0xeb,0x1c,0x8c,0xae,0x10,0x27,0x1d,0x40,0x20,0x78,0xc,0x52,0x93,0x48,0xd2,0xb9,0x90,0x4c,0xdd,0x68,0x9e,0xbc,0xac,0x4f,0x72,0x22,0x67,0x1d,0x86,0xd2,0x61,0x69,0x5e,0xcd,0xe4,0xf4,0xc0,0x9f,0x31,0x9a,0x40,0xe,0x15,0x1,0x46,0xc3,0x58,0x1d,0xe4,0xbc,0x3e,0xe8,0x44,0x48,0x92,0x11,0x5b,0x2f,0xf,0x66,0xc9,0x9e,0x6f,0x32,0xad,0x7,0xf9,0xe0,0x18,0x84,0xd5,0x41,0x8a,0xac,0x4,0x35,0xca,0x3e,0x29,0xb8,0xd9,0x5a,0x35,0x83,0x45,0xda,0x6a,0xeb,0x43,0x2f,0x87,0xfa,0xfb,0xc0,0xd7,0xa3,0xb1,0x6,0xc2,0xd9,0x30,0x29,0x41,0x40,0x8d,0x65,0xbb,0x80,0x28,0x48,0xf3,0x89,0xfd,0x17,0xb1,0x8f,0xa5,0x83,0x54,0xae,0x4e,0x14,0x17,0x8,0x40,0xe0,0x54,0x6,0xa0,0x52,0x88,0xa6,0x24,0x4,0xff,0xc2,0x76,0xd7,0x1,0xce,0x68,0x54,0x65,0x1,0xef,0x69,0x5b,0xd9,0x2,0x4a,0x8,0x94,0x79,0x81,0x28,0x49,0x42,0xe8,0xc9,0x78,0xd1,0xd8,0xe2,0xef,0x81,0x55,0x59,0x40,0xa9,0x8,0xd9,0x60,0x19,0x69,0x77,0x6,0xce,0x39,0x2,0xc2,0xe2,0x3a,0x55,0x9d,0x64,0xae,0xe4,0x3b,0x18,0xc5,0x31,0x9c,0x8d,0xd8,0x67,0x95,0x12,0x88,0x7d,0xc0,0x14,0x31,0x3,0x27,0x87,0x5f,0x79,0x96,0x26,0x49,0xa1,0x2d,0xca,0x22,0xf,0x0,0x59,0x92,0x76,0x1a,0xe0,0xe7,0xf8,0xc9,0xf5,0x13,0x20,0x7e,0xf2,0xc7,0x4b,0x8f,0x29,0x84,0x4a,0xf0,0xf9,0x4a,0x2,0xb8,0xe6,0x3d,0x6c,0x1d,0x1c,0xca,0x3c,0x43,0xd2,0xe9,0xc2,0x6a,0x13,0x18,0x8c,0x3e,0x6d,0x5d,0x57,0x15,0x54,0x1c,0x43,0x2a,0x8b,0xac,0x34,0xc4,0x26,0x1c,0x3d,0x5a,0x52,0x62,0xae,0x97,0x22,0x67,0xb9,0x70,0x9c,0xa6,0xc1,0x76,0x3,0xce,0x41,0xeb,0x32,0x58,0x61,0xf8,0x9f,0xfd,0x49,0xa,0xac,0x3b,0x56,0x1d,0x10,0xe3,0xd0,0xc2,0xb1,0x8f,0xa2,0x97,0x55,0x4b,0x19,0x85,0x4,0xe6,0x26,0x30,0x2c,0x84,0xa0,0xeb,0x98,0x25,0xc3,0x43,0x60,0x98,0x4f,0xbd,0x6e,0xe8,0x78,0x9b,0xf7,0x12,0x92,0xa,0x37,0xa5,0xb4,0x62,0x98,0x7c,0x87,0x3a,0x20,0x7,0xa3,0xb8,0xdd,0x68,0xfa,0xc6,0x18,0x6a,0x8,0x8c,0xb1,0xfb,0x30,0x9,0xfc,0x9b,0x4,0x4,0xe2,0x3,0xfe,0xfe,0xf3,0x84,0xec,0x1a,0x61,0x3a,0xad,0xff,0x5f,0x5b,0x6d,0xb5,0xd5,0x2,0x80,0x6d,0xb5,0xd5,0x56,0x5b,0xd7,0x73,0x5f,0x58,0xb3,0x42,0x68,0xf6,0xde,0x5,0xc0,0xf,0xc,0x6a,0x51,0xa8,0x83,0x9,0xc,0x2b,0xa5,0xa8,0xc1,0xf0,0x4c,0x0,0xef,0x87,0xe7,0x53,0x69,0x3d,0xb,0xd0,0xcb,0x5d,0xc1,0x60,0xc9,0xfa,0x55,0x33,0xb8,0xe5,0xa6,0x1b,0xc7,0xb6,0xa1,0xac,0x2a,0x3c,0x7f,0xe0,0x30,0x9c,0xb5,0x78,0xe7,0xc4,0x39,0x5c,0x58,0xb8,0x82,0xcd,0x37,0xac,0x1b,0x6,0x2a,0xa5,0xc4,0x27,0xee,0xdf,0x8b,0x77,0xde,0x3b,0xcf,0xb2,0xa0,0x7a,0xa6,0xdf,0x7b,0xc0,0x25,0x69,0x7,0x65,0x91,0x5,0xbf,0x21,0xcf,0xf0,0x33,0xc6,0x21,0xe6,0x44,0x62,0xef,0xa7,0xe7,0x65,0xc9,0x51,0x9c,0x40,0x30,0x23,0x62,0x34,0xcc,0x84,0x98,0x2f,0xdc,0x7c,0x58,0x83,0x28,0x8e,0x49,0xea,0x6c,0xd,0x94,0x8a,0x3,0x63,0xcc,0xe8,0xa,0x31,0x83,0x78,0x10,0x8,0x29,0xbe,0x16,0x2,0x11,0x33,0xf5,0x24,0x1f,0x2b,0xef,0xcd,0xe7,0x1a,0xc9,0xc3,0x86,0xe5,0x5b,0x2a,0x8a,0x10,0x75,0xba,0x28,0x8b,0x3c,0xac,0x47,0x4a,0x62,0xbe,0xb9,0xaa,0xa,0xe7,0x47,0xca,0x28,0x30,0x24,0xb4,0xa9,0x90,0x76,0xa9,0x79,0xa3,0xc6,0x88,0x65,0xdb,0xb1,0x84,0xf2,0xe9,0x8b,0x51,0x14,0x0,0xb1,0xa6,0xf,0x93,0x4f,0x4d,0x1c,0xa,0xd3,0x50,0x11,0xca,0x32,0x87,0x14,0x82,0x1b,0x5f,0xc5,0xfe,0x84,0x49,0xf0,0x1f,0xa4,0x65,0x2a,0x96,0x60,0x93,0x2f,0xa4,0xb0,0xde,0x77,0xd0,0xa2,0xd3,0x9b,0x85,0x31,0x2c,0x11,0x57,0x75,0x43,0x1a,0xc5,0x49,0x90,0x43,0x53,0x53,0x2c,0xa1,0x4,0x25,0x1,0x7b,0x96,0x9,0x49,0xc,0x49,0xba,0x15,0xc7,0xd4,0xf0,0x1a,0x49,0x80,0x6f,0xcc,0x7e,0x52,0xc6,0x68,0x38,0x27,0x3,0x40,0x1d,0xab,0x34,0x34,0x85,0x24,0x6d,0x96,0xc1,0x47,0x8c,0x52,0xad,0x23,0xf6,0xfb,0xab,0xaf,0x65,0x9f,0x12,0xec,0x99,0x22,0x96,0x1,0xba,0xa6,0x8f,0x99,0x1b,0x69,0x84,0xc8,0xc7,0x10,0x21,0x24,0x86,0xce,0xb7,0x8,0xb2,0x60,0xc3,0xac,0x1f,0x6a,0x68,0x6d,0x83,0x71,0xe2,0x1b,0xfc,0x96,0xfd,0xd7,0xd6,0x47,0x34,0xce,0x3b,0x3,0x4,0xa0,0x85,0xc0,0x8f,0x88,0xc7,0x2c,0x1,0xc1,0xc9,0xb6,0x80,0x8a,0x88,0x65,0x5b,0xa7,0xf2,0x4a,0xf6,0x29,0x35,0x88,0x54,0xcd,0x26,0x23,0x16,0xae,0x45,0x14,0x2,0x9f,0x1c,0xc4,0xdf,0xb1,0x3b,0x9b,0xf4,0x20,0x96,0xae,0x2,0x98,0x66,0xd9,0x67,0x56,0xa,0x75,0xd,0x4f,0x4e,0xf2,0xd2,0x73,0xe,0x3c,0x89,0x42,0xdf,0xf3,0xb4,0x3b,0x43,0xac,0x34,0xfe,0xce,0xd3,0x64,0x47,0x15,0x42,0x4c,0x3c,0x18,0x18,0xc7,0x9,0xaa,0xb2,0xc,0xc7,0x8d,0xd8,0x97,0x80,0x8c,0xf8,0x3e,0x69,0xcd,0x34,0xc,0x86,0xd8,0x83,0xae,0xf6,0xb5,0xb5,0xce,0x32,0xd3,0x5d,0x2,0xd3,0xbc,0xd9,0xf8,0x9e,0xed,0x83,0x56,0xb2,0xfe,0x32,0xb1,0xaa,0x2b,0x62,0x22,0x26,0xbd,0x19,0xa,0x5d,0xb1,0x8e,0xe5,0xd5,0x36,0x9c,0x63,0x6b,0x2c,0xba,0x33,0x73,0x34,0x39,0x26,0xea,0x90,0xd,0xef,0x97,0xab,0xf8,0xde,0xed,0x4,0x81,0x7f,0x76,0x8a,0x4f,0x6f,0x92,0xd0,0xb1,0x0,0x80,0x7c,0x50,0x61,0x66,0x76,0x15,0x1d,0x3,0x29,0x21,0x4,0xd9,0x37,0x4,0x75,0x80,0x73,0x30,0xc6,0xd5,0xb2,0x5c,0xe,0x5a,0x12,0x42,0xd0,0x4,0x8b,0xa0,0x49,0x48,0xeb,0x4c,0x60,0x12,0x6,0xd6,0xb6,0x7,0xdb,0xf8,0xd9,0x85,0x2c,0x4a,0x9a,0xc,0xbf,0x7a,0xcc,0xf5,0x20,0x9f,0x13,0x35,0x33,0xdb,0x89,0xfa,0xfa,0xf,0xec,0xf0,0xa6,0x3c,0x77,0x48,0x61,0x2b,0x86,0x11,0xe5,0xa1,0xd1,0x7c,0x48,0xeb,0xfb,0x1,0x80,0x39,0xf7,0x1,0x7e,0xfe,0xdb,0x3,0x7b,0x43,0x84,0xc6,0x11,0x6,0x6d,0xf3,0xb5,0xf1,0xf9,0xa8,0x16,0xf4,0x6b,0xab,0xad,0xb6,0x5a,0x0,0xb0,0xad,0xb6,0xda,0x6a,0xeb,0xef,0x45,0x35,0xe5,0x30,0x9e,0x5d,0x16,0x64,0x5d,0x2c,0xb7,0x5,0x27,0x3,0x7b,0x19,0x98,0xf7,0x7a,0xa3,0x66,0x27,0xae,0x53,0x76,0x65,0x9d,0x4e,0xeb,0x1f,0x36,0x89,0x61,0x48,0xaf,0x3f,0x72,0xcf,0xcd,0xe8,0xa4,0xe3,0xec,0x87,0x13,0xa7,0x2e,0x60,0x61,0xb9,0x60,0xc6,0x5b,0x7,0x2f,0x1c,0x78,0x17,0xbf,0xfe,0xe4,0xba,0x31,0xc2,0xd4,0x4d,0xbb,0xb6,0xe3,0x86,0xd5,0x5d,0x9c,0xbe,0xb8,0x48,0x12,0x4c,0xe7,0x1a,0x3e,0x51,0x22,0x6c,0xb3,0xf,0x82,0x20,0x3f,0x25,0x53,0x7,0x68,0xa8,0x8,0x91,0x12,0x21,0x80,0x84,0x80,0xce,0x14,0xc6,0x1a,0x94,0xc6,0x41,0x1b,0x7,0x48,0x9,0x5d,0x55,0x88,0xe2,0x14,0x49,0x1c,0x61,0xdb,0xfa,0x39,0xdc,0xbe,0x67,0x3b,0x66,0xba,0x29,0x96,0xfa,0x5,0xe,0x1e,0x39,0x8e,0x63,0x67,0x2f,0x43,0x6b,0xf2,0xa1,0x23,0x96,0x5a,0x2d,0x2f,0xf2,0x29,0xc7,0x71,0x1c,0xb3,0xaf,0x1c,0xb3,0xd9,0x20,0x51,0x14,0x15,0x8c,0xd5,0x0,0x87,0x61,0x48,0x1,0x6c,0x5c,0x33,0x8b,0xbb,0x6e,0xde,0x8e,0xb5,0x6b,0x56,0xa3,0x28,0x4b,0x9c,0x3a,0xbb,0x80,0x37,0xde,0x3d,0x85,0x7e,0x56,0x30,0x60,0x87,0x86,0x6c,0xe,0xc1,0x6b,0x31,0x49,0xbb,0xb0,0xd6,0x20,0x8d,0x22,0xda,0x5e,0x1f,0x82,0x2,0x87,0xd5,0xf3,0x73,0xd8,0x7c,0xc3,0x5a,0x6c,0x5e,0x3b,0x8b,0x75,0x6b,0xd7,0xa0,0x93,0x12,0x2b,0xb0,0xa8,0x34,0x16,0x2e,0x2f,0xe1,0xec,0xa5,0x2b,0x38,0x79,0x6e,0x1,0xda,0xc5,0xa8,0xaa,0x22,0xf8,0x62,0xd1,0x72,0x6b,0x30,0xd,0x89,0x4f,0x5b,0xa4,0x10,0x90,0x99,0x4e,0xc,0x29,0xbb,0x24,0x17,0x74,0x16,0x40,0xa,0xe7,0x80,0xac,0x22,0x86,0xa2,0xe6,0x6,0xd0,0xb3,0xe,0xfd,0xf5,0xd5,0xf4,0x21,0x14,0x1c,0xd4,0xa1,0x94,0xc2,0x4c,0x87,0x8e,0x13,0xf9,0x48,0x1a,0x2c,0xf,0xf2,0x46,0xc2,0xa8,0x9,0xcc,0xbc,0x58,0xa6,0xdc,0xb4,0xd5,0xe9,0xce,0xbe,0x7,0xb3,0xda,0x60,0xa6,0x93,0xa0,0x93,0x26,0xa8,0xca,0xa,0x2,0xe4,0x8f,0xa8,0xb5,0xc1,0xd5,0xe5,0x15,0x68,0xdb,0x48,0x2d,0x45,0x13,0xfc,0x14,0xc1,0xcf,0xd0,0xb3,0x56,0x1d,0xfd,0x10,0xcc,0xec,0xa5,0x10,0x70,0xcc,0x98,0xf4,0x2c,0x3f,0x1f,0x4e,0xe2,0x1b,0x53,0x81,0xda,0xdb,0xaf,0x29,0x39,0x9b,0xd4,0x5a,0x5,0xa6,0x4b,0x5b,0x6d,0x7d,0xe8,0x0,0x20,0x42,0xa8,0x82,0x4f,0xa9,0xf5,0xcc,0x67,0x13,0xbe,0xaf,0x6e,0x48,0x2a,0xe9,0x98,0x59,0xed,0xbd,0x5d,0xe9,0x5f,0x2,0xce,0x7c,0xd8,0x44,0xd3,0x32,0xe2,0xef,0x12,0xc3,0x95,0x12,0x84,0x4d,0xd8,0xf,0x2f,0xe0,0x97,0x91,0x84,0xab,0x6c,0xb0,0x6b,0x98,0xf6,0x59,0xa5,0x22,0xc4,0x49,0x2,0x6b,0x34,0x3a,0xbd,0x19,0x64,0x83,0x15,0x44,0xce,0xc1,0x82,0x92,0xdb,0x8d,0x33,0x10,0x0,0x22,0x4e,0x81,0xf,0x9e,0x7a,0x71,0x82,0x32,0xcf,0xa1,0xe2,0x38,0x8c,0xa3,0x71,0x9c,0x86,0x34,0xe2,0x88,0x6d,0x12,0xa6,0x9d,0x24,0x1f,0x94,0x94,0xf,0x56,0x98,0xd9,0x6,0xbe,0xbf,0x5a,0x8,0x19,0x4d,0x5,0x7d,0x22,0x96,0x3b,0x47,0x71,0x82,0x7c,0xb0,0x82,0x24,0xed,0xf2,0xfd,0x57,0x85,0x65,0x5a,0x67,0x11,0x4b,0x9,0xeb,0x88,0xe1,0xae,0xab,0x12,0x9d,0xde,0x2c,0xac,0xd1,0xc8,0x6,0x2b,0xe8,0x74,0x67,0x42,0x38,0x94,0x9f,0xdc,0x4a,0xd3,0x1e,0xdd,0x43,0x79,0x22,0x67,0xda,0x39,0xae,0x38,0x70,0xc4,0x27,0x4a,0x67,0x83,0x15,0x7a,0x46,0x10,0x51,0xf0,0xf4,0x93,0x82,0x80,0x55,0xf0,0x58,0x29,0x55,0x4,0x5d,0x15,0x34,0xb6,0x4b,0x11,0x40,0x49,0x0,0xb0,0xce,0xc,0x8d,0x97,0x3e,0x89,0xdd,0xb3,0x58,0x83,0xff,0xae,0xaa,0x13,0xa9,0xfd,0x40,0xec,0xc7,0x75,0x8,0x9e,0xe4,0x72,0xfe,0xf,0x35,0x90,0x37,0x9c,0xcc,0x3b,0x1a,0xd6,0xd1,0x58,0x90,0x1b,0x61,0xea,0xb9,0xe6,0xeb,0xa3,0xe9,0xba,0x93,0xe2,0x7c,0xa7,0x44,0xfc,0xfe,0x42,0x20,0xef,0x26,0xf0,0x89,0x89,0xde,0x98,0xcd,0xb0,0xae,0x1a,0xd7,0x6c,0x6c,0xbf,0xc3,0xd4,0x74,0xec,0xb6,0xda,0x6a,0xab,0x5,0x0,0xdb,0x6a,0xab,0xad,0xb6,0xda,0xba,0x2e,0x1a,0xc3,0x86,0x47,0x99,0x7,0x48,0x80,0x46,0x20,0x83,0xc,0x8f,0xe0,0x14,0xaa,0x40,0x80,0x13,0xc9,0x2a,0x99,0x39,0x2,0xc7,0x92,0x31,0x6a,0x40,0x88,0x2d,0x97,0x30,0xab,0x8e,0x9e,0x34,0x67,0xbb,0x29,0xee,0xb9,0xfd,0xe6,0xb1,0xf5,0x5b,0x6b,0xf1,0xc2,0x1b,0x47,0xc9,0xb8,0x5c,0x29,0x14,0x45,0x86,0xd7,0xe,0x9f,0xc2,0x63,0xf7,0xdd,0x8a,0x75,0x6b,0x57,0xd,0xbd,0x37,0x89,0x23,0x3c,0xf1,0xe8,0x3e,0xfc,0xc1,0x5f,0x3c,0x5,0x6b,0x4d,0x48,0x54,0xd4,0xf9,0x0,0x9d,0xee,0xc,0x33,0xba,0x34,0xa7,0xdc,0x9a,0x46,0xa2,0x20,0xdf,0xc0,0x92,0x4,0x77,0xee,0xde,0x8c,0xdf,0xf9,0xad,0xcf,0x8d,0x3c,0x8a,0x3b,0x7c,0xe9,0x2f,0x7f,0x80,0xfd,0xef,0x9c,0xc,0xac,0xb2,0x2d,0xeb,0xe6,0xf0,0xc5,0x5f,0x7a,0x18,0xbb,0x6e,0xdc,0x3a,0x24,0x59,0x7e,0xf2,0xb1,0xfb,0x70,0xe1,0xd2,0x65,0x7c,0xf3,0xfb,0xcf,0xe3,0xf5,0xa3,0x67,0x1,0x11,0x43,0x5a,0x62,0x88,0x38,0x21,0x30,0xd3,0x4d,0xf0,0xaf,0x7e,0xef,0x1f,0xa2,0xd7,0xed,0xd4,0xf,0xfd,0xce,0xe2,0xc0,0xc1,0xc3,0xf8,0xd2,0xb7,0x5e,0xc,0x5e,0x5c,0x91,0x12,0xf8,0xe2,0x93,0xf,0xe2,0xbe,0xbb,0x6e,0x41,0xb7,0xd3,0x19,0x3a,0x1f,0xcb,0x2b,0x7d,0xbc,0xf4,0xda,0xdb,0xf8,0xc6,0x33,0xfb,0xa1,0x1d,0x50,0x16,0x39,0xa2,0x24,0x45,0x55,0x16,0x88,0x93,0x94,0x59,0x7c,0x36,0x0,0xb4,0x69,0xda,0x85,0xd6,0x25,0x6e,0xde,0xbe,0x9,0x8f,0x3d,0x78,0x7,0x76,0xdd,0xb8,0x19,0xab,0xe6,0x66,0xa7,0x1a,0xce,0x5b,0x6b,0x31,0xc8,0xa,0x1c,0x3f,0x71,0x1a,0xcf,0xbd,0x72,0x10,0x87,0x4f,0x5d,0x44,0xa5,0xd,0xb3,0xe,0x6d,0x60,0xf2,0x49,0xa7,0x2,0x63,0x3,0x0,0xfe,0xc7,0x7f,0xfa,0x39,0x6c,0x5c,0xbf,0xb6,0x21,0x77,0x22,0x83,0xf9,0xdf,0xff,0xc3,0xff,0x86,0x93,0x17,0x97,0x90,0x76,0xba,0xd0,0x55,0x19,0x40,0xe2,0x20,0x5,0x66,0x46,0x5f,0x14,0x25,0xb0,0x56,0x43,0x46,0x11,0x76,0x6d,0x5e,0x8b,0xff,0xfe,0x9f,0x7e,0xa1,0x4e,0x4e,0x76,0xe,0xdf,0x7f,0xee,0x15,0x7c,0xfb,0x27,0x6f,0x22,0x8a,0x13,0x54,0x55,0x1,0x18,0x4a,0x18,0xd5,0xba,0x62,0x23,0x7e,0x19,0x18,0x37,0x42,0x8,0x48,0xa1,0xd0,0xe9,0x48,0xfc,0xeb,0xff,0xe9,0x9f,0x60,0xd5,0xfc,0x5c,0xdd,0x6,0x39,0x60,0x90,0xe5,0xf8,0xb7,0xff,0xe1,0xcf,0x70,0xee,0xd2,0x15,0x92,0xb1,0x71,0xc8,0x81,0x65,0xd9,0xb6,0xf7,0x59,0x84,0xb3,0x70,0x8e,0x18,0x9d,0xd6,0x9a,0x90,0x46,0xec,0x8f,0x53,0xe8,0x96,0xac,0x63,0xe6,0xa9,0x61,0x50,0x93,0x18,0x8b,0xde,0x7c,0x3e,0x0,0x27,0xd,0xf3,0x77,0xd1,0x20,0x89,0x90,0x31,0xbd,0xc,0x1e,0x55,0x6d,0xb5,0xf5,0xa1,0x2,0x62,0x9e,0xf1,0x4a,0x88,0x58,0x90,0xa4,0x3b,0x70,0xb2,0x38,0x88,0x65,0x6d,0x98,0x1,0xeb,0xd9,0x64,0x3e,0xac,0xc1,0x39,0xc7,0x56,0x6,0xae,0x6,0xf7,0x19,0xec,0x91,0xd6,0x40,0x70,0x82,0xef,0xdf,0xa1,0x1d,0x86,0x13,0x22,0x30,0xea,0x3c,0x3b,0xda,0x54,0x15,0x5,0x6b,0x4,0x26,0xdc,0xa4,0xcf,0xd2,0x7e,0xeb,0xaa,0x22,0x9f,0x57,0xa3,0xd1,0x9b,0x99,0x47,0x55,0xe6,0xc,0x3a,0x29,0xb6,0x58,0x30,0x50,0x2e,0xe,0x56,0xe,0x60,0x30,0xd5,0xfb,0xee,0x1,0xe,0x2a,0x4a,0xea,0xb0,0x26,0xcf,0x8,0x9c,0x1a,0xb2,0x20,0x98,0xa1,0x4c,0x40,0xa2,0x35,0x59,0x18,0x8b,0xbc,0xbf,0xeb,0x34,0xc0,0xd2,0x33,0x9f,0xcb,0x22,0xb,0x3e,0x82,0x83,0x95,0x25,0xcc,0xaf,0x5e,0xc7,0xcc,0x77,0x4a,0x57,0xa7,0x40,0xa5,0x8,0x51,0x14,0xd,0x25,0x97,0x27,0x29,0x79,0xbd,0xc6,0x71,0x12,0xbc,0x7e,0x85,0x24,0xb6,0xb5,0xdf,0x86,0x55,0xab,0x57,0x4f,0xbc,0xa7,0x58,0x6b,0xb1,0xb8,0xb8,0xc4,0xd6,0x1c,0x65,0x48,0xf6,0x75,0xce,0xc2,0xd9,0x24,0x78,0xf,0x36,0x43,0x9e,0x4c,0x55,0x42,0x34,0x82,0xbb,0x28,0xe5,0x58,0xf,0xfb,0xa,0x33,0x80,0xe6,0x9f,0x21,0x42,0xea,0x3a,0x6a,0xa4,0xcb,0x36,0xd2,0xe2,0x9d,0xb3,0x70,0x62,0x94,0xb9,0xcd,0xd7,0xf9,0x50,0x36,0x93,0x98,0xe0,0xd9,0xe7,0x26,0x23,0x6a,0x93,0x7e,0x71,0xd3,0x24,0xbb,0xf8,0x19,0x5f,0x9f,0x8a,0x7,0x7,0xac,0x51,0x8c,0x10,0x14,0xa7,0x5d,0x7,0xa3,0x9b,0x38,0x4,0xf4,0x8d,0x4,0x8c,0xc,0x3,0x84,0xf5,0x3e,0x9,0xd9,0x86,0x80,0xb4,0xd5,0x56,0x5b,0x2d,0x0,0xd8,0x56,0x5b,0x6d,0xb5,0x75,0xfd,0x2,0x80,0xa8,0x9f,0x14,0x85,0x50,0x80,0xb5,0x81,0x2d,0xe5,0x13,0xf5,0x7c,0xa,0xab,0x52,0x8a,0xbd,0x8e,0x22,0x9a,0xfb,0x66,0x43,0x75,0xa0,0x96,0x1,0xeb,0xb2,0x84,0x8a,0x63,0x7a,0xe2,0xe4,0xf4,0x43,0xa5,0x14,0xee,0xda,0xb3,0xd,0x6b,0xd7,0xcc,0x8f,0xad,0xff,0xca,0xe2,0xa,0xe,0x9d,0xb8,0xc0,0x4c,0x14,0x62,0x9a,0xe4,0x45,0x85,0x3,0x87,0xde,0xc3,0xa7,0x1f,0xb9,0x7b,0xec,0xfd,0xb7,0xdd,0xb4,0x1d,0x6b,0x57,0xcf,0xe2,0xca,0xf2,0xa0,0x96,0xb4,0x5a,0x4b,0x89,0x8d,0x42,0x20,0x8a,0xa8,0xf9,0xf2,0x7e,0x86,0xfe,0x49,0x98,0x3c,0xfb,0x80,0x48,0x0,0xdd,0x4e,0x3a,0xb6,0xdc,0x98,0x41,0x2f,0x40,0x60,0xef,0xee,0xad,0xf8,0x67,0x5f,0x7c,0x2,0xab,0xe6,0x66,0xc7,0xde,0xa7,0x94,0xc2,0xe6,0x8d,0x1b,0xf0,0x3b,0xbf,0xfd,0x79,0xbc,0x72,0xe0,0x2d,0x7c,0xed,0xfb,0x2f,0xe3,0xea,0x52,0x41,0xc7,0x87,0xa5,0xb6,0x9d,0x34,0x19,0x5b,0x47,0xb7,0xdb,0xe3,0x26,0x5c,0x60,0xa6,0x9b,0xe2,0x5f,0x7c,0xf1,0x71,0xec,0xde,0xb1,0x75,0x62,0xa3,0x3e,0x3f,0x37,0x8b,0x27,0x1e,0x7b,0x0,0xb7,0xec,0xde,0x8e,0x3f,0xfb,0xab,0xa7,0x71,0xf4,0x54,0x46,0x49,0xbc,0xb2,0xe2,0x63,0x2d,0xd9,0x2f,0x90,0xfc,0x99,0x6e,0x58,0x33,0x83,0x2f,0x7e,0xe6,0x49,0xec,0xd9,0x7d,0x23,0xe2,0xe8,0xfd,0xbd,0xb6,0xa4,0x94,0x98,0x9d,0xe9,0xe2,0xce,0xbd,0x7b,0xb0,0xf7,0x96,0x5d,0x38,0x7d,0xf6,0x22,0xbe,0xf1,0xc3,0x97,0xf0,0xce,0xc9,0x8b,0xdc,0x2c,0xd9,0x21,0xf,0x46,0xf,0xc,0xee,0x7f,0xf3,0x30,0xbe,0xf8,0xd9,0xc7,0xc7,0x96,0xf7,0xe4,0x63,0xf,0xe0,0x8f,0xff,0xf2,0xe9,0xc0,0x44,0x21,0xaf,0x26,0x19,0x80,0x58,0xb0,0x1f,0x97,0x90,0x2,0x71,0xdc,0x85,0xb3,0x6,0x8f,0xde,0x7f,0x3b,0x66,0x67,0x7a,0x43,0xcb,0x79,0xe0,0x9e,0xbd,0xf8,0xe1,0xcb,0xef,0xa0,0xa8,0x2a,0x66,0xad,0xc4,0x81,0x9d,0x54,0x1b,0xbd,0x4b,0xf2,0x65,0x64,0xb9,0xda,0xc7,0xef,0xbf,0x3,0x1b,0x37,0xac,0x1b,0x63,0x3b,0x1c,0x3a,0x72,0xc,0xb,0x8b,0x7d,0x78,0x56,0x9,0x79,0x62,0x69,0xf6,0xc8,0x2,0x8c,0xa9,0x42,0xf3,0xe9,0x81,0x6f,0x6b,0xc,0x54,0x1c,0xc3,0x6a,0x1d,0x18,0x30,0x1e,0xd8,0xb,0x92,0x5f,0x6e,0xb3,0xac,0x21,0x56,0x8b,0x13,0x9e,0x2d,0xc5,0xcd,0x2a,0x37,0xf7,0x3e,0x69,0x38,0x0,0xeb,0x40,0xf0,0x8a,0x6c,0xab,0xad,0xf,0x7d,0x9c,0xb7,0x36,0x0,0xd4,0xa3,0xaf,0xdb,0x6,0xf3,0xcf,0x8f,0xe7,0x4,0xe2,0xbb,0x9a,0x45,0xc6,0xbe,0xb0,0x21,0x11,0x9d,0xfd,0x48,0x95,0xf,0x2b,0xba,0x6,0xfb,0xef,0xd4,0x99,0xb,0x38,0x7e,0xfa,0x2,0x1,0x84,0xce,0x12,0x88,0xcf,0x93,0x26,0x64,0xf,0x11,0x87,0xf4,0x58,0xe9,0x3d,0x69,0x7d,0x6a,0xb1,0x73,0x6c,0x3d,0xc1,0xdb,0xd6,0x48,0xd3,0xb5,0xd6,0xa2,0x93,0xc6,0xd8,0x77,0xc7,0xcd,0x63,0xa9,0xf2,0x0,0xd8,0xfb,0x8e,0xfd,0xf4,0xca,0x3c,0xc8,0x40,0x69,0x32,0x61,0x7a,0x6a,0x31,0x98,0x71,0x17,0xc5,0x31,0x8a,0x6c,0x0,0x5d,0x96,0xbc,0xed,0xe,0x69,0x77,0x6,0xde,0x83,0xd4,0xa7,0x26,0x2b,0x66,0xd,0xd3,0x3d,0x20,0xa6,0x63,0xaa,0x35,0x8c,0x20,0x70,0xcd,0xfb,0xa1,0xa,0x21,0x20,0x54,0x34,0x3d,0x9,0x98,0xb7,0x17,0xa0,0x4,0x62,0x1f,0x76,0x44,0xd6,0x14,0x6e,0x3a,0x70,0xe8,0x13,0xe8,0x15,0xfb,0xe,0x6a,0xd,0x67,0x2d,0x66,0xe7,0x56,0x87,0xc4,0x67,0x15,0xc5,0x88,0x12,0xe,0x45,0xe1,0x40,0xa4,0x28,0x22,0xb0,0xcf,0x7f,0xd6,0xfb,0xb3,0x92,0x57,0x6b,0xc,0x21,0x15,0x9c,0xac,0x3d,0x22,0xd7,0xcc,0xa6,0x48,0x58,0xe6,0x3c,0xa,0x0,0xf6,0xb,0x4d,0xa0,0x21,0x4,0xb3,0x43,0x23,0x78,0xeb,0xf,0x6b,0x2d,0x4f,0xfe,0x18,0x18,0xed,0x2,0x28,0x67,0xf9,0x9a,0xc,0xac,0x3e,0x1e,0xab,0xc9,0xef,0x4f,0x13,0x3,0xdb,0x7b,0xfb,0xf1,0x7d,0xdc,0x83,0x98,0xce,0xd5,0x93,0x2c,0xc4,0x90,0xac,0x3d,0x1,0x5d,0x23,0x94,0xc3,0xb9,0x1a,0xd,0x73,0xae,0x89,0x88,0x89,0x9,0x70,0x9a,0x18,0x4f,0xe1,0x1d,0x4b,0xd0,0xc5,0x35,0xc1,0xbd,0xb1,0x4c,0x91,0xf,0x8,0xf4,0x8d,0x3,0x72,0xf5,0x12,0x9a,0x2f,0x4f,0x7a,0x47,0xd8,0xcc,0x91,0xdd,0xa0,0x65,0x37,0x3,0x46,0x86,0x41,0xc8,0x21,0xa0,0xd4,0x35,0xcf,0xa7,0xf9,0x29,0xf6,0xbb,0xad,0xb6,0xda,0x6a,0x1,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xb6,0xfe,0x7f,0x55,0x46,0xeb,0xa1,0x7,0x42,0xc1,0x21,0x20,0xce,0x91,0xf7,0x91,0x7,0x5f,0x48,0x16,0x6c,0x1,0xd8,0x21,0x1f,0x3d,0xa,0xad,0x88,0x0,0x7e,0x4d,0x70,0xb8,0x83,0x90,0xb2,0x4e,0x90,0x15,0xa,0x8f,0x3e,0x70,0xc7,0xc4,0xf5,0xbf,0x76,0xf0,0x38,0x2a,0x4d,0xeb,0x69,0x3e,0xc8,0x3e,0xff,0xfa,0x51,0x7c,0xec,0xde,0x5b,0x31,0xd3,0x1d,0x6,0xd2,0x66,0x67,0x7a,0x78,0xec,0xbe,0xbd,0xf8,0xda,0xf7,0x5e,0x8,0x5e,0x6e,0x46,0x13,0x53,0x83,0xbc,0x97,0x8,0x8c,0x93,0x11,0x49,0x9f,0xaa,0xaa,0x44,0x14,0xc5,0x90,0xce,0x6,0x1f,0xbf,0x69,0xf,0xe1,0x4a,0x2a,0xec,0xdc,0xba,0x1,0xff,0xfc,0x1f,0x3c,0x89,0x39,0x96,0x9,0x4f,0x2b,0xa5,0x24,0x1e,0xdc,0x77,0x27,0x7a,0xdd,0x2e,0xfe,0xef,0x3f,0xff,0x36,0x27,0x21,0x1b,0x0,0x71,0x48,0x85,0x5,0x46,0x1e,0xdc,0x85,0x40,0x12,0xc7,0xf8,0x9d,0x5f,0xff,0xe4,0x44,0xf0,0x6f,0xb4,0xb6,0x6d,0xd9,0x88,0x7f,0xf9,0x8f,0x7e,0x5,0xff,0xe7,0x1f,0x7e,0x1d,0x17,0x17,0xfb,0xb4,0x5f,0x4a,0xc1,0x59,0x6a,0x3e,0xd3,0x34,0xc5,0x3,0x7b,0x77,0xe0,0xd7,0x7f,0xf9,0x31,0xcc,0xf4,0x3a,0x3f,0xd3,0xf9,0x57,0x4a,0xe1,0xc6,0x6d,0x9b,0xf0,0xbb,0xff,0xe8,0xb3,0x78,0xf9,0xc0,0xdb,0xf8,0xda,0xd3,0x7,0x90,0x67,0x59,0x48,0x5,0xf6,0x64,0x9,0x29,0x15,0x5e,0x78,0xfd,0x5d,0x3c,0xf1,0xf1,0xfb,0x31,0x3f,0x2,0x8c,0xde,0x7a,0xd3,0x76,0xcc,0xf6,0x3a,0xe8,0xe7,0x55,0xb8,0x1e,0x8c,0xd1,0x24,0xf9,0x85,0x80,0x8c,0x8,0x28,0x8e,0x38,0x11,0x79,0xd5,0x6c,0xf,0x77,0xdc,0xb2,0x7b,0x6c,0x5b,0x36,0xac,0x5b,0x8d,0xbb,0xf6,0x6c,0xc5,0xab,0xef,0x9c,0xa,0x92,0x44,0xdb,0x30,0xe1,0x17,0x52,0x41,0x31,0xe8,0x4c,0x4c,0x9b,0x18,0x1f,0xdb,0xb7,0x77,0xac,0x71,0x32,0xc6,0xe0,0xe9,0x9f,0xbc,0xc6,0xc1,0x2c,0x12,0x9a,0x59,0x4b,0x56,0x32,0xb0,0x6d,0xbc,0xb7,0x94,0xa1,0xb0,0xf,0xa5,0x60,0x2a,0x66,0x16,0x72,0xd7,0x26,0x85,0xa,0x60,0x68,0x93,0xe5,0x27,0x25,0x85,0x86,0xd0,0xeb,0xdc,0xb8,0x86,0x86,0x5e,0x4,0xb9,0x36,0x5,0x88,0x98,0xe1,0xa6,0xaa,0xad,0xb6,0x3e,0xaa,0xa,0xe9,0xa9,0x1e,0x6a,0x41,0x60,0xfb,0x79,0xf9,0xbb,0xb5,0x26,0x0,0x59,0x75,0xb8,0x90,0x85,0xb5,0x2,0x4a,0xc8,0xe0,0xcf,0x49,0xdf,0x63,0x7,0x11,0x89,0x1a,0x57,0x10,0x98,0x1a,0xaa,0x71,0xf2,0xec,0x45,0x7c,0xf5,0xbb,0x2f,0xa2,0x2c,0x73,0x64,0x2b,0x4b,0x1,0x6c,0x37,0x86,0xee,0x3d,0x3e,0xa0,0x22,0xf1,0xc1,0x43,0x1c,0x5a,0x61,0x8d,0x46,0x9c,0xd2,0x84,0x81,0xb,0x0,0x21,0xf9,0x85,0x2a,0x66,0xb0,0x6d,0x5d,0x3f,0x8f,0x7b,0x6f,0xbf,0x9,0x80,0x1a,0x1b,0xcf,0x9b,0x80,0xa7,0xc,0x29,0xc6,0x4,0x8,0x7a,0x6b,0x83,0xc9,0x78,0x9a,0xa2,0x9,0x17,0x41,0xbe,0xab,0x10,0x2,0x71,0xda,0x81,0x61,0xd6,0x79,0xcc,0x20,0x54,0xda,0xe9,0x36,0x92,0x6c,0xd,0xba,0x69,0x97,0xfc,0x53,0xa5,0xc,0xa1,0x46,0xe0,0xbf,0x79,0x2f,0xd7,0x60,0x35,0x30,0xf1,0x1e,0x64,0x43,0xc0,0x15,0x1d,0x7b,0xba,0x7f,0x49,0x29,0x91,0x24,0x1d,0x98,0xaa,0x98,0x8a,0x20,0xd1,0x58,0xe3,0x90,0x67,0x7d,0xb2,0x4d,0x48,0x52,0xf2,0x31,0x64,0xf0,0xcd,0x5b,0x63,0x84,0x40,0x17,0x66,0xf7,0x47,0x90,0xb0,0x96,0xfc,0xc,0x75,0x55,0x92,0x64,0x39,0xed,0xc0,0x18,0x83,0x48,0xaa,0x30,0x9,0x62,0xad,0xc5,0xee,0x6d,0x37,0x4c,0x54,0x0,0xe7,0x79,0x81,0xf7,0x4e,0x9d,0xd,0x4c,0x41,0xa3,0x2b,0x54,0x45,0xe,0xcb,0xd6,0x1c,0x9d,0x6e,0x14,0x96,0xdd,0x9c,0x50,0xa1,0x6b,0x2f,0x62,0x5f,0xd7,0xaa,0xe,0xef,0xe2,0x7,0x1,0xba,0x87,0x28,0xb6,0x1e,0x31,0x23,0xc7,0xce,0x5,0x8f,0x3f,0x8f,0xda,0xf9,0xa0,0x91,0x51,0x0,0x6d,0x54,0xe2,0x3a,0xc,0xa5,0x8d,0xc0,0x74,0x93,0x24,0xbf,0x3f,0xdd,0xd7,0xec,0x83,0x1,0xf2,0x8d,0xf7,0x8a,0xd1,0xd0,0xa8,0x86,0x84,0xd7,0x33,0x75,0x87,0xf6,0xc2,0xd,0x83,0x7c,0xc0,0x78,0x9a,0xb1,0xc3,0xa8,0xc9,0x9f,0xfb,0xc0,0x5b,0x47,0x7e,0x93,0x2d,0xf8,0xd7,0x56,0x5b,0x6d,0xd5,0xd5,0xf2,0x82,0xdb,0x6a,0xab,0xad,0xb6,0xae,0xa7,0xbe,0x30,0xa4,0xe2,0x39,0xa0,0x91,0x86,0x6a,0x8d,0xad,0xbd,0xd3,0x9c,0x83,0xae,0x8a,0xf0,0x0,0x6f,0xad,0xe1,0x14,0x54,0x45,0xcd,0x5,0x7,0x56,0xf8,0xc6,0xcd,0x3f,0x84,0x7b,0x53,0xf0,0x9b,0xb6,0xdd,0x80,0xcd,0x1b,0xd7,0x8f,0xad,0x3b,0xcb,0xb,0xec,0x3f,0xf4,0x1e,0x9b,0x82,0x6b,0xe,0xca,0x20,0x7f,0xc1,0xa5,0x41,0x81,0x23,0xc7,0xcf,0x4e,0xdc,0xe6,0xfb,0xee,0xbc,0x5,0x69,0x24,0x59,0x2,0x44,0x8d,0x61,0x55,0xe4,0x28,0x8b,0x1c,0x92,0xa5,0x59,0x4d,0x80,0x8b,0x7e,0x17,0x2c,0xc3,0x8a,0xa6,0x36,0x5f,0x33,0xbe,0x19,0x43,0x4f,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x33,0x3d,0xfc,0xd6,0xaf,0x3c,0xf2,0xbe,0xe0,0x5f,0xb3,0xce,0x5f,0xba,0x8c,0x38,0xe9,0x50,0x63,0xda,0xf0,0x8b,0x1b,0x5f,0x3e,0xf9,0x2c,0x7e,0xfe,0xe3,0x77,0x60,0xcf,0xae,0x6d,0x1f,0x78,0xf9,0xfd,0x41,0x86,0xab,0x2b,0x19,0xb3,0xf2,0x48,0x7e,0x4d,0xc,0x4c,0x87,0xcf,0x7f,0x72,0x1f,0x7e,0xfb,0x57,0x3f,0xfd,0x33,0x83,0x7f,0xcd,0x8a,0xe3,0x8,0xf,0xdd,0x77,0x7,0xfe,0xc5,0xaf,0x3d,0x8a,0x55,0xf3,0xf3,0xdc,0xf8,0x72,0x5a,0x32,0x33,0x62,0xfa,0x85,0xc6,0x81,0xb7,0xde,0x1d,0xfb,0xec,0x4c,0xaf,0x8b,0x4f,0xdc,0x7f,0x5b,0x83,0xed,0x42,0xa0,0x98,0x97,0x61,0x7b,0xc6,0xa2,0xf,0x97,0xb9,0x6f,0xef,0x4e,0xcc,0xce,0x74,0x27,0x5e,0x8b,0xf,0xed,0xbb,0x2d,0xc8,0x82,0xad,0xa5,0xe3,0x18,0x45,0x31,0x33,0x57,0x7c,0x4a,0x24,0x35,0x90,0x7b,0xb6,0x6d,0xc0,0x96,0x4d,0x1b,0xc6,0x1,0x87,0xd3,0xe7,0xf0,0xc6,0xbb,0xa7,0xc2,0x75,0xe8,0x83,0x57,0x7c,0xaa,0xa9,0x67,0x13,0x5,0xb3,0x79,0x63,0x3,0xb8,0x6a,0x59,0xaa,0xe6,0x7d,0xa5,0x1c,0x6a,0x50,0xdc,0xb7,0x51,0x43,0x8d,0x52,0xa3,0x69,0x14,0xdc,0xf0,0x7b,0x49,0x60,0xf3,0x3a,0x10,0x0,0x7,0x92,0xb4,0xd5,0xd6,0x47,0x83,0x0,0x36,0x43,0x12,0xc8,0xb6,0x81,0xbc,0x5d,0x2d,0x7f,0xbf,0xfd,0x77,0xd5,0xa7,0x74,0x7b,0xc0,0xcf,0x7b,0x7b,0x7a,0xc0,0xce,0x39,0x47,0x2c,0x6f,0x10,0x13,0xd6,0x1a,0x4d,0xc,0xd8,0xa9,0xc0,0x56,0x93,0x25,0x4b,0xc0,0x4e,0x55,0x16,0x21,0x70,0xc7,0x8f,0x6d,0x46,0x53,0x72,0x6d,0x9c,0xa4,0xc8,0xfa,0xcb,0x0,0x40,0x40,0x92,0x31,0x80,0x90,0x1c,0x64,0x61,0x20,0x4,0xa0,0xcb,0x22,0x2c,0x6f,0x22,0xfb,0x30,0xc8,0x9c,0x69,0x6c,0x4f,0xbb,0x33,0x88,0x62,0x62,0x14,0x53,0xc2,0xb8,0x9e,0xa,0xc4,0x81,0xbd,0x12,0xbd,0x74,0x17,0xf0,0xe3,0xe,0x42,0x8,0x56,0xc4,0x4c,0xbf,0x28,0x4a,0x78,0x8c,0x49,0x98,0x49,0xa7,0x78,0x5c,0x70,0xc1,0x63,0x91,0x2,0x49,0x6a,0x99,0xab,0x97,0x5c,0x8f,0x96,0xb5,0x2e,0x24,0xda,0x43,0x88,0x90,0x8,0x9f,0x76,0xd8,0x87,0x6f,0x5a,0x6a,0x71,0xe3,0xbe,0xeb,0x43,0x40,0x2,0xb3,0xce,0x39,0x94,0x65,0x1e,0xa4,0xc7,0xfe,0xfe,0x4d,0x80,0x9c,0xe4,0x4,0x67,0x9,0x5d,0xd1,0xc4,0x59,0x9c,0x76,0x82,0xf7,0xa3,0x7,0x8e,0x28,0x15,0x58,0xe1,0xa6,0x5d,0x37,0x4e,0x5c,0xfd,0xc5,0x4b,0xb,0x18,0x14,0x4,0x8e,0xd2,0x4,0x5c,0x84,0x95,0xa5,0xab,0x9c,0xc0,0xc,0x14,0xf9,0x80,0x15,0x5,0x74,0x9d,0x99,0x8a,0xbd,0x62,0x19,0xd8,0xd,0x76,0x16,0xcc,0xd0,0xe,0xe1,0x49,0x9e,0x81,0xcd,0x1,0x20,0x5e,0x66,0x1d,0x3c,0x87,0x45,0xf3,0x3a,0x46,0x78,0xad,0x66,0xce,0x8d,0x52,0xe7,0x26,0x49,0x5e,0x9b,0x3f,0x4f,0x7a,0x4d,0x4c,0xc3,0x5c,0xa7,0x2,0x7b,0xd3,0xde,0xdf,0x70,0x57,0x19,0xa,0x13,0x6e,0xae,0xdd,0x83,0xe9,0x35,0x7b,0x5c,0x34,0xd2,0x8c,0x1b,0x89,0xc5,0x7e,0x79,0xe1,0x3b,0xed,0x1a,0x2b,0x71,0x53,0x20,0xc9,0xf7,0x7,0xf5,0x5a,0xd8,0xaf,0xad,0xb6,0xda,0x6a,0x1,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xeb,0xbc,0x9a,0x49,0xa5,0x3e,0x19,0xd7,0xb3,0x98,0x9c,0xa3,0x44,0x43,0xcf,0xde,0x12,0x61,0x6,0x9e,0xc2,0x10,0x8c,0xd6,0x21,0x1c,0x81,0x1a,0xa5,0x5a,0x86,0x43,0x8c,0x2d,0x92,0x16,0x3d,0xf6,0xc0,0xed,0x88,0xa3,0x71,0xe0,0xed,0xd8,0xc9,0x73,0xb8,0xbc,0x92,0xf3,0xc,0xb7,0x8,0x8d,0x87,0x67,0xf4,0x3d,0xbb,0xff,0x30,0x4a,0x6e,0x16,0x9a,0xb5,0x76,0xcd,0x3c,0xee,0xbb,0xed,0x46,0x96,0x9b,0xea,0x20,0x33,0xf2,0xfe,0x7a,0x41,0x2,0x8c,0x3a,0x9,0x90,0x4c,0xc7,0x15,0x87,0x92,0x8c,0x97,0x8a,0x12,0x7c,0xe1,0x13,0x77,0x63,0xeb,0xe6,0x1b,0x86,0xc0,0xb7,0xb,0x97,0x2e,0x63,0xe1,0xf2,0x55,0x68,0x3d,0xe,0xde,0x5c,0xb8,0xb8,0x80,0x6f,0x3c,0xfd,0xa,0x1c,0x8,0x20,0xf5,0xcc,0x8d,0x49,0xdd,0x81,0x10,0x2,0x77,0xed,0xd9,0x8a,0x47,0xee,0xbf,0x2b,0xbc,0x56,0x69,0x8d,0x85,0xcb,0x57,0x71,0x71,0xe1,0x2a,0xf2,0xa2,0x1c,0xfb,0x4c,0x55,0x55,0xf8,0xea,0xb7,0x9e,0x83,0x85,0x8,0x66,0xfc,0x11,0xb3,0x2a,0x7e,0xe9,0x91,0xbb,0xf1,0xf8,0xc3,0xf7,0xc,0xf9,0x13,0x36,0xab,0x2c,0x2b,0x9c,0xbb,0xb0,0x80,0xfd,0x6f,0x1e,0xc1,0xd3,0x3f,0x79,0x15,0xcf,0xbe,0x70,0x0,0xaf,0x1f,0x3c,0x82,0xf3,0x17,0x17,0xa0,0xb5,0x99,0xa,0x6,0xdf,0xba,0x67,0x27,0xfe,0xf1,0xaf,0x3c,0x88,0x34,0x89,0xe9,0x1c,0x72,0x23,0xe6,0x93,0x82,0x9f,0x7f,0xfd,0xdd,0x89,0xe7,0xe4,0xbe,0x3b,0x6f,0xc1,0x4c,0x2f,0xd,0x9e,0x62,0x71,0x92,0x12,0xb,0x6,0x80,0x54,0x24,0x27,0x53,0x51,0xc,0x25,0x81,0xfb,0xef,0xba,0x79,0xea,0xf5,0x78,0xe3,0xd6,0x4d,0xd8,0xb6,0x71,0x3d,0xa2,0x38,0x41,0x9c,0xa4,0xe1,0x5f,0xcb,0xe0,0xa1,0x4f,0x12,0x96,0x42,0xe1,0x53,0xf,0xdf,0x8d,0x48,0x8d,0x33,0x7f,0x7e,0xfc,0xf2,0x1b,0x75,0x17,0x5,0x4,0x56,0x62,0x48,0x93,0x4,0x1,0x1c,0x9e,0xa9,0xd8,0x10,0xc2,0xf3,0x35,0x6e,0xa9,0xa1,0x66,0x69,0xb0,0x67,0x2c,0x51,0x53,0x6f,0x42,0xa2,0x70,0x70,0x94,0xa,0x52,0x61,0x34,0xd8,0x9f,0xe3,0x9,0xc2,0x52,0xaa,0x76,0xc0,0x69,0xeb,0x23,0x1a,0xe8,0xed,0x48,0x9b,0x2f,0x2,0x6b,0x2f,0xc8,0x4c,0x19,0x58,0x69,0x86,0x80,0x38,0xe7,0xa0,0x58,0xfe,0xeb,0xc,0xcb,0xda,0x3d,0x90,0xa3,0x2b,0x4f,0x55,0xba,0x66,0x70,0x80,0x97,0xe0,0x3b,0x6b,0x89,0xe5,0xc7,0xc,0xa5,0xaa,0x2c,0x90,0xf5,0x57,0xa0,0x75,0x85,0x22,0x1f,0xa0,0x2a,0xb,0x18,0xa3,0x29,0x5,0x9d,0xbf,0xaf,0xc4,0x40,0xf4,0x21,0x18,0x2a,0xa4,0xf2,0x4a,0x15,0xb1,0x1f,0xa8,0x9d,0xc,0xc6,0x30,0x33,0xac,0xcc,0x32,0x58,0x4b,0xa1,0x25,0x46,0x57,0xc4,0x80,0x8b,0x62,0x2,0xbf,0xec,0x64,0xb8,0xa3,0xdb,0xeb,0x31,0x6b,0x4f,0x5,0xf6,0x31,0x81,0x53,0x92,0x6d,0x1e,0x54,0x8,0xb1,0xb0,0x96,0x0,0x4b,0x15,0x45,0xc8,0xb3,0x3e,0x4b,0x8c,0x3b,0x70,0x96,0x99,0x92,0xd,0xd4,0xc7,0x33,0xdf,0x22,0xe9,0xa6,0x8c,0xd9,0x65,0x3d,0x6e,0xf8,0xfb,0x58,0x23,0xc9,0x7d,0x1a,0x3c,0xd3,0xf4,0xf2,0x8b,0xe3,0x34,0xf8,0x5,0xaa,0x28,0x9,0xe3,0x5c,0x14,0xc5,0x3c,0x29,0x43,0xa9,0xbf,0x34,0xf1,0xa1,0x11,0x7b,0xd6,0x25,0xdf,0xe3,0x35,0xa7,0xcd,0xfb,0x60,0x2d,0x1f,0xfc,0xb5,0x65,0xdd,0x3c,0x36,0xdf,0xb0,0x6e,0xe2,0xfa,0x8f,0x9f,0x38,0x1d,0xac,0x14,0x0,0x20,0xcf,0xfa,0x80,0x73,0xc8,0x7,0x2b,0xf4,0xb3,0x7,0x8a,0xd9,0xb2,0xc3,0xab,0x9,0x22,0xde,0xbe,0xe0,0xff,0xe7,0x19,0x7c,0x1e,0xdc,0x63,0xa6,0xb5,0xa7,0x99,0xa,0x81,0x90,0xaa,0x4c,0x40,0x21,0x78,0x12,0xb0,0xe,0x6,0x19,0x66,0x8,0xba,0xfa,0x5a,0x1f,0x3,0xc6,0x3e,0xf0,0x17,0x67,0xec,0x59,0xc9,0x5f,0x5e,0x4d,0x40,0xaf,0x9,0xec,0x4d,0x82,0xde,0xf8,0x6b,0x32,0xf4,0xac,0x55,0x27,0x91,0x34,0xbd,0x97,0xdd,0x90,0x54,0xb7,0xf6,0x91,0x75,0x53,0xb6,0x4d,0x4c,0x7,0x2a,0x7f,0x8a,0x7d,0x76,0x8d,0xcf,0xb8,0xd6,0xa7,0xb6,0xad,0xb6,0xda,0x1a,0xa9,0x56,0x2,0xdc,0x56,0x5b,0x6d,0xb5,0x75,0x1d,0x95,0x60,0xd3,0x6c,0xa9,0x14,0x7b,0xd,0x71,0xb0,0x86,0xa6,0xe0,0x4,0xef,0x11,0x14,0x9a,0x21,0x6e,0x44,0x9a,0xc0,0x9a,0xb3,0x64,0x10,0xdf,0x64,0xde,0x51,0x60,0x48,0x8c,0xf5,0xab,0xe7,0x70,0xeb,0xee,0x1d,0x63,0xeb,0xd5,0xc6,0xe0,0x47,0xaf,0x1c,0x6a,0xc8,0x78,0xe8,0x31,0xd4,0xfb,0xf0,0xe9,0xaa,0xc2,0xb9,0x85,0x45,0xbc,0x77,0xfa,0x22,0x6e,0xde,0xb9,0x65,0xe8,0xb3,0x52,0x4a,0x7c,0xe2,0xe1,0x7d,0xf8,0xc9,0x1b,0xc7,0x42,0xd3,0x12,0x45,0x31,0x74,0x59,0x20,0x4e,0x3a,0x35,0x3,0xb1,0x91,0x4a,0x8,0x58,0xe,0x97,0xc8,0x27,0x1e,0x87,0x4d,0xeb,0xe7,0xf1,0xe0,0xbd,0xb7,0x3,0x0,0x16,0x97,0x96,0xf1,0x83,0x1f,0x1f,0xc0,0xab,0x6f,0x1f,0xc7,0xa0,0xb2,0xb0,0xba,0xc2,0x8e,0x4d,0x6b,0xf1,0xc4,0xc3,0x77,0x61,0xef,0x2d,0xbb,0x58,0x82,0x6a,0xf0,0xad,0xa7,0x5f,0x46,0x5e,0x59,0x48,0xc5,0xcc,0x18,0xeb,0xd0,0xe9,0xcd,0x4e,0x64,0x6a,0x44,0x51,0x84,0x5f,0x7d,0xe2,0x21,0x44,0x91,0x42,0x51,0x56,0x78,0x69,0xff,0x9b,0xf8,0xc1,0xf3,0x6f,0x60,0x61,0xa9,0xf,0x27,0x22,0xac,0xe9,0x45,0xf8,0xc4,0x3,0x77,0xe0,0xa1,0xfb,0xef,0xc,0x1,0x22,0x7,0xe,0xbe,0x8b,0x77,0x4e,0x9c,0xb,0x72,0x37,0xdf,0xe4,0xdc,0xb4,0x75,0x1d,0x3e,0xf3,0xd8,0xfd,0x63,0xe0,0x97,0x7,0xfe,0x5e,0x7b,0xf3,0x30,0x9e,0x79,0xf9,0x2d,0x9c,0xba,0x70,0x15,0x32,0x8a,0x99,0x6d,0x43,0x72,0xaa,0x24,0x8e,0xb0,0x79,0xed,0x3c,0x3e,0xf5,0xf0,0x9d,0xb8,0x7b,0xef,0x1e,0xc4,0x13,0x24,0xd1,0xb7,0xed,0xd9,0x81,0x27,0x1e,0xdc,0x8b,0xa7,0x5e,0x78,0xbb,0x96,0xb8,0x31,0x83,0xee,0xdc,0x95,0x3e,0xe,0x1f,0x3d,0x89,0x3b,0x6e,0x1d,0x96,0xf0,0xae,0x59,0x35,0x8b,0xbd,0x3b,0x37,0x63,0xff,0x91,0x33,0x30,0xdc,0x44,0x2,0x80,0x52,0x24,0xe1,0x8e,0xe3,0x18,0x52,0x45,0xd8,0xbd,0x69,0x35,0x36,0x6e,0x58,0x3b,0xf5,0x7a,0x4c,0x93,0x18,0xf7,0xed,0xbd,0x11,0xa7,0x2f,0x5d,0x85,0x70,0xe,0xce,0x91,0xc4,0x3b,0x8e,0x89,0x59,0xe8,0x25,0xeb,0x1b,0xd6,0xcc,0xe2,0xa6,0x9d,0xdb,0xc7,0x3e,0x7f,0x65,0x71,0x11,0x2f,0xbe,0x7e,0x18,0x2a,0x8a,0x50,0x64,0xc4,0x3c,0xf1,0x69,0xa5,0xba,0x2c,0x9,0xd0,0x88,0x22,0xe8,0x3c,0x83,0x15,0x2c,0x2b,0x6b,0x80,0x74,0xd6,0x54,0xd4,0xd8,0xb3,0x21,0x3d,0x79,0xd,0xba,0x86,0xfc,0x8c,0x93,0x29,0xd9,0x23,0xd0,0xc1,0xc2,0x7a,0x73,0xfa,0x20,0xb3,0x14,0x63,0x52,0x39,0x7,0x7,0xc8,0x8,0xb0,0x2d,0xb,0xb0,0xad,0x8f,0x0,0xff,0xe3,0xa6,0xde,0xb3,0xc4,0x3c,0x23,0x79,0x98,0xed,0x45,0xd7,0x3b,0x1,0x6c,0x8a,0x27,0x77,0x24,0xfb,0xc8,0x29,0x62,0xd2,0x1a,0xd,0x21,0xa2,0xc0,0xd4,0xf3,0x9e,0x9f,0xc6,0x4e,0x67,0xd4,0x39,0x6,0x7e,0xac,0x33,0x28,0xb2,0xc,0x5a,0x57,0x30,0x55,0x45,0xc,0x31,0x21,0x98,0x75,0x9b,0xf0,0x58,0x5e,0x84,0x14,0xf7,0x3c,0x1b,0xa0,0xd3,0xe9,0x51,0x22,0xac,0xa4,0x0,0x1d,0xa9,0x14,0xb2,0xc1,0xa,0x7a,0xb3,0xf3,0x24,0x13,0x9d,0x30,0x19,0xe1,0xc7,0x49,0x5d,0x95,0xc4,0x4e,0xd7,0x1a,0xc6,0x54,0x50,0x2a,0x86,0x73,0xb4,0x7f,0x51,0x12,0x21,0xcf,0x27,0x4b,0x6a,0x7b,0xdd,0x94,0xbd,0xf4,0x2a,0x74,0x7a,0x33,0x18,0x2c,0x2f,0x6,0x10,0xcd,0x23,0x39,0x21,0x9d,0xd7,0x2,0xba,0x2c,0x11,0xa7,0x29,0x85,0x31,0x99,0x8a,0x19,0x8b,0x34,0x19,0x10,0x45,0x31,0x8c,0xae,0x98,0x81,0x4c,0x41,0x59,0x9d,0x9,0x1e,0xb4,0x0,0xd0,0xcf,0x35,0xdf,0x7b,0x35,0xcb,0xb3,0x1d,0x0,0x89,0x3c,0xeb,0xa3,0x27,0xe7,0x31,0x9d,0x8d,0x66,0xd9,0x53,0x8f,0x98,0x72,0x42,0xc8,0xc0,0x1a,0xf4,0xa1,0x46,0x5a,0x57,0xe8,0x75,0xba,0xd0,0x15,0x8d,0xa1,0x2a,0x8e,0x19,0x94,0x23,0x59,0xb4,0x8,0x69,0xcf,0x24,0xc3,0x5,0x7b,0x2f,0xfa,0x80,0x8d,0x87,0xef,0xd9,0x83,0x24,0x19,0xbf,0x57,0x18,0x63,0xf0,0xc2,0x81,0x43,0x1,0x2c,0xa4,0x74,0x7b,0x9,0x91,0x44,0xc1,0x13,0xb0,0xaa,0x4a,0x44,0xa0,0xc9,0x44,0xaf,0x28,0x90,0xc,0x38,0xd7,0x60,0x99,0x8,0x63,0x27,0x82,0x9d,0x46,0xcd,0xea,0xab,0x7d,0xf2,0x64,0x8d,0x5f,0xf,0x1,0x7e,0xcd,0xb1,0x57,0xd0,0x73,0x4b,0x8,0x14,0xf9,0xe0,0x20,0xd8,0x24,0x89,0x6d,0xed,0x37,0x28,0x26,0x3,0x67,0x8e,0xd6,0x12,0x2,0x47,0x9a,0xfe,0x84,0x4d,0xc0,0x6f,0xf8,0xa,0x1d,0x7,0xe7,0x26,0x84,0x8b,0x34,0x3d,0xfc,0xc4,0x50,0xc0,0xc9,0xb4,0x7f,0x7f,0xe6,0x11,0xa2,0xc1,0xbc,0x14,0xed,0x80,0xd9,0x56,0x5b,0x6d,0xd,0xf7,0x5d,0xed,0x21,0x68,0xab,0xad,0xb6,0xda,0xba,0xae,0x20,0xc0,0xc0,0xd0,0xd0,0x55,0x5,0x6b,0x6d,0x1d,0xbc,0xc0,0x8c,0xba,0x66,0x32,0x21,0x40,0xc1,0x9,0xc4,0x7a,0x20,0x50,0xc7,0x3f,0x29,0x93,0xf4,0x49,0x84,0xf7,0x9,0x29,0xf1,0xe8,0xbe,0x5b,0xd1,0xed,0x8e,0x37,0x3c,0x17,0x17,0x16,0x71,0xf2,0xd2,0x4a,0x0,0x11,0x55,0x1c,0xc3,0x5a,0x87,0x8a,0x1b,0x40,0x0,0x30,0xda,0xe0,0xd9,0x97,0xde,0x84,0x31,0xe3,0x33,0xd2,0x5b,0xb7,0x6c,0xc2,0xed,0xbb,0xb7,0xc2,0x68,0xcd,0xd2,0x2e,0x6a,0x32,0xb5,0xae,0xc8,0x47,0x48,0x8,0xa4,0x1d,0xa,0x99,0x88,0x93,0x94,0x25,0x5b,0x86,0xcd,0xbf,0xc7,0xeb,0xa1,0x7b,0x6e,0x45,0xa4,0x24,0xce,0x9e,0x5f,0xc0,0xff,0xf5,0xff,0xfc,0xd,0xbe,0xf7,0xe2,0x9b,0x58,0xb8,0xba,0x8,0x5d,0x95,0x28,0x8a,0x1c,0x87,0x8e,0x9f,0xc6,0xef,0xff,0xe9,0x37,0xf0,0xc7,0x5f,0xf9,0x36,0x96,0x96,0xfb,0x38,0x7c,0xec,0x14,0x9e,0x7f,0xfd,0x70,0x58,0x17,0x40,0x32,0xa9,0xaa,0xcc,0x83,0x37,0x5c,0xb3,0x76,0xdd,0xb8,0x19,0xeb,0xd6,0xcc,0x23,0x2f,0xa,0x7c,0xf9,0xaf,0xbe,0x8f,0xaf,0x7c,0xef,0x55,0x5c,0x5a,0x2e,0x60,0x41,0x12,0xe5,0x85,0x95,0x2,0x5f,0xfd,0xde,0x4b,0xf8,0x3f,0xfe,0xe3,0x97,0xf0,0xde,0xc9,0x33,0xb8,0xba,0xb8,0x84,0xbf,0xfc,0xde,0xb,0x50,0x51,0x14,0x1a,0xe5,0x28,0x4e,0x10,0x47,0x12,0xbf,0xf6,0xc4,0x43,0x48,0xd3,0x64,0x6c,0x1d,0x4b,0x2b,0x7d,0xfc,0xc9,0x7f,0xfb,0x2e,0xbe,0xfc,0xd4,0x4b,0x38,0x71,0xfe,0x2a,0xa7,0xdd,0xea,0x20,0x77,0x8d,0xa2,0x8,0x16,0x2,0x67,0x2e,0xaf,0xe0,0xf,0xbf,0xf6,0x34,0xfe,0xf0,0x2f,0xbe,0x8d,0xc5,0xe5,0x95,0x89,0xcd,0xf3,0x27,0x1f,0xbe,0x7,0x9b,0xd7,0xcd,0x5,0x3f,0x48,0xc9,0x9,0xa2,0xce,0x5a,0x3c,0xfb,0xd2,0x5b,0x30,0x23,0x8c,0x1f,0x29,0x25,0x1e,0xbe,0xf7,0x66,0x58,0x5d,0x85,0xeb,0xc7,0xcb,0xd2,0x92,0xb4,0x83,0xb2,0x28,0x60,0xad,0xc5,0xc7,0xef,0xdf,0x5b,0x27,0xff,0x4e,0xa9,0x7b,0xf6,0xee,0xc6,0x5c,0x8f,0x12,0x85,0xbd,0x97,0xa0,0x97,0x8b,0x45,0x31,0xa5,0x72,0x3e,0x76,0xdf,0x5e,0x74,0x26,0x1c,0x83,0x57,0x5f,0x3f,0x84,0x7e,0x5e,0xa2,0xaa,0x4a,0xc4,0x49,0x4a,0xe0,0x86,0x73,0xd0,0xba,0x24,0x2f,0xaf,0x38,0x41,0x59,0xe6,0x1,0x0,0xa1,0x24,0x60,0xc7,0xb2,0x5f,0x53,0xa7,0x9e,0xf2,0x7f,0x2,0xb5,0xef,0x9f,0xf,0x2d,0xa8,0x49,0x3a,0xb4,0xc,0x34,0xd9,0x1b,0xcd,0x66,0xaa,0xf1,0x3e,0xa6,0x4e,0xb5,0xc3,0x4d,0x5b,0x1f,0xcd,0x28,0x2f,0xa3,0x21,0x50,0x41,0xa9,0x61,0xa9,0xa5,0x35,0x26,0x24,0x6c,0x7b,0xf9,0x7b,0xb0,0x58,0xe0,0xeb,0xde,0x83,0x49,0x1e,0xc4,0x31,0x46,0x7,0x16,0x9e,0x14,0xd7,0x68,0xf,0x84,0xe0,0x20,0xd,0x4a,0x74,0x35,0x5a,0x7,0x6f,0x3d,0xbf,0x3d,0x46,0x6b,0x54,0x65,0x8e,0x22,0x1f,0xf0,0x3d,0xc8,0x50,0xca,0x3c,0x33,0xef,0x9c,0x25,0x6,0x59,0x55,0x16,0x48,0xbb,0x3d,0x66,0x2,0xea,0x21,0xe0,0x62,0x7c,0xb5,0x14,0x4a,0x65,0x9d,0x85,0x14,0x2a,0xb0,0x7d,0x2d,0x4b,0x7c,0xfb,0xd9,0x64,0x0,0x70,0xf5,0xfc,0x6c,0x90,0x9,0x5b,0x6b,0x90,0x76,0x7b,0x21,0x90,0xc8,0xfb,0xe7,0x49,0x6,0xf3,0xd2,0xee,0xc,0x92,0x6e,0x37,0x30,0xdc,0xbc,0x24,0x58,0x8,0x19,0x12,0x88,0xe3,0xa4,0x83,0x28,0x8e,0x21,0x95,0xc2,0x4c,0x1a,0x61,0xa6,0x37,0x6e,0x7f,0x60,0xac,0xc5,0xc5,0x85,0x5,0x62,0x63,0x2,0xb0,0xc,0xa8,0x6a,0x3f,0x8e,0x29,0x19,0xd2,0x70,0x27,0x20,0x80,0x34,0xde,0x32,0x4b,0x3b,0xe9,0x74,0x50,0x95,0x5,0xf2,0x41,0x1f,0x71,0xda,0xe1,0x70,0xac,0x98,0xd2,0xe4,0x99,0x95,0xa8,0x54,0x1c,0xc6,0x47,0x1f,0x90,0xa5,0x98,0xa5,0x9f,0xa4,0x5d,0x96,0xa7,0x12,0xcb,0x73,0xdd,0x5c,0x17,0xf7,0xdc,0x71,0xcb,0xc4,0x55,0x5f,0x5a,0xb8,0x82,0x13,0x67,0x17,0x2,0x4b,0x5c,0x30,0x4b,0x12,0x70,0xe8,0x2f,0x2f,0x22,0xcf,0xfa,0xa8,0xa,0xba,0xa7,0x9b,0x86,0xa7,0xb0,0xf,0x1b,0x9,0x72,0x5e,0x29,0xc2,0x7d,0x44,0x48,0x11,0x26,0x1d,0x3,0xe8,0x25,0xbc,0xd7,0xaa,0xf,0xf5,0x32,0x53,0x98,0x6a,0x2e,0x28,0x18,0xc0,0xb0,0x1c,0x3e,0x20,0x44,0x36,0xe4,0xc9,0xe7,0x5c,0x83,0x74,0x37,0xa,0xbe,0x61,0x48,0x4e,0xdf,0x5c,0xba,0x67,0x79,0x6,0xd0,0xd2,0xb3,0xfb,0x86,0xe4,0xc8,0xe2,0x1a,0x6b,0x7f,0x7f,0x80,0xee,0x67,0x9c,0x1,0xf8,0xc0,0x6f,0xb5,0xb6,0x15,0x2,0xb7,0xd5,0x56,0x5b,0x2d,0x0,0xd8,0x56,0x5b,0x6d,0xb5,0x75,0xfd,0xe,0xea,0xdc,0x8,0xa,0x8,0x48,0x25,0x83,0x1f,0xf,0x85,0x80,0x68,0x6e,0x16,0xa2,0xf0,0xf0,0x59,0x7b,0xfc,0xd5,0xf,0x89,0x11,0xbf,0xe6,0x67,0xeb,0x49,0xee,0x28,0xd1,0x89,0x15,0xf6,0xdd,0xb1,0x67,0xe2,0xb3,0xe8,0xab,0x6f,0x1d,0xb,0xa6,0xea,0x5e,0xd6,0x15,0x45,0x11,0xd2,0x4e,0x8f,0xc2,0x23,0x38,0x80,0xe2,0xf0,0xc9,0x8b,0x38,0x73,0xfe,0xe2,0xd8,0x32,0x22,0xa5,0xf0,0xc4,0xa3,0xf7,0x91,0xe7,0x9c,0x73,0x90,0x9c,0x5a,0x2b,0x78,0x1b,0xd,0x37,0x8c,0x71,0xd2,0x9,0xc,0xc,0x34,0x24,0x55,0xa3,0x35,0x33,0xd3,0xc3,0xf2,0xca,0x0,0x7f,0xfc,0xb5,0xef,0xe1,0xfc,0xd5,0x3e,0x19,0xaf,0xa7,0x5d,0xf6,0x8c,0xa3,0x65,0xaa,0x38,0xc1,0x4b,0x6f,0x1d,0xc7,0xbf,0xff,0xaf,0x5f,0xc5,0x9f,0xfe,0xd5,0xf,0xd9,0x30,0x9f,0x7c,0xf9,0x0,0x62,0x4d,0x5a,0x37,0x39,0xad,0xb1,0x93,0x26,0xb0,0xce,0xe1,0xaf,0x9e,0xfa,0x31,0x5e,0x79,0xfb,0x4,0xfb,0x5d,0xe9,0xe0,0xb,0x57,0x95,0x4,0x90,0x9d,0xbd,0x92,0xe1,0xdf,0xfd,0xd7,0xaf,0xe3,0xf,0xbe,0xfc,0x4d,0x5c,0xbc,0xb2,0x14,0x40,0x30,0xdf,0x68,0x3f,0x78,0xc7,0x2e,0x6c,0xdb,0xb2,0x71,0x6c,0xf9,0x59,0x5e,0xe0,0x4f,0xbe,0xfa,0x3d,0x1c,0x38,0x72,0x8a,0xa5,0x64,0xf5,0xc1,0x56,0x2a,0x66,0xdf,0xad,0x12,0x65,0x96,0x21,0x1b,0xac,0xc0,0x5a,0x83,0x37,0x8e,0x9e,0xc3,0x7f,0xfe,0xf3,0x6f,0x63,0x71,0x69,0x79,0x6c,0x79,0xdd,0x4e,0x8a,0xc7,0x1f,0xbc,0x1d,0x10,0xe0,0x4,0x47,0x1b,0xfc,0xa3,0x8e,0x9e,0xbd,0x8c,0x33,0x67,0x2f,0x8c,0x7d,0x66,0xfb,0x96,0x8d,0xd8,0xb3,0x6d,0x3,0x92,0x4e,0x37,0x0,0x89,0x51,0x9c,0xa0,0x2c,0x72,0xa4,0xdd,0x1e,0x6e,0x58,0xd5,0xc3,0xae,0x1b,0x37,0xbf,0xef,0x35,0x39,0x3b,0xd3,0xc5,0xbd,0xb7,0xde,0x88,0x24,0xed,0x90,0xff,0x9f,0x8a,0x98,0x5,0x49,0x1e,0x83,0xab,0x66,0x67,0xb0,0x6f,0x82,0x8c,0x78,0x90,0xe5,0xf8,0xd1,0xcb,0x6f,0x87,0x10,0xe,0x7f,0x4e,0xaa,0xaa,0xc,0x40,0x5e,0x2d,0xa9,0x53,0xd,0x10,0x1,0x30,0xba,0xc,0x1e,0x83,0x5e,0x76,0x16,0xd2,0x7f,0x59,0x36,0xec,0xc2,0xb9,0x75,0xdc,0x20,0xb3,0x74,0x58,0x88,0x21,0x23,0xf7,0xc0,0xa0,0x68,0xb0,0x36,0x5d,0x0,0x10,0xdb,0x6a,0xeb,0x23,0xa8,0x86,0x9,0xd9,0x50,0x10,0x83,0x20,0xaf,0x56,0xe1,0x7d,0x3a,0x99,0x21,0x4b,0xcc,0x2f,0x15,0xa4,0x98,0x7e,0x8c,0x6,0x6a,0x66,0x35,0x79,0xdc,0xc9,0x30,0x3e,0x4e,0x93,0xe,0x7a,0xe0,0x90,0x52,0xe2,0xb,0x28,0xa5,0x82,0x24,0x57,0x57,0x25,0xca,0x3c,0x83,0x31,0x1a,0x45,0x9e,0xa1,0x2a,0xe9,0xf5,0x22,0xeb,0xa3,0x2c,0xb,0x38,0x67,0xb1,0x74,0x75,0x1,0x65,0x51,0x20,0xcf,0xfa,0x28,0x8b,0xc,0xba,0x2c,0x91,0xf,0x56,0x82,0x34,0x78,0xb2,0xfa,0xd1,0x71,0xb8,0x85,0xa,0xe0,0x1c,0x81,0x9c,0x1a,0xce,0x58,0x68,0x5d,0xe1,0xcc,0xf9,0x4b,0x13,0xb7,0x77,0xdd,0xea,0x39,0x44,0x4a,0xb2,0xfd,0x0,0x5,0x62,0x18,0x5d,0x21,0xed,0xce,0xd0,0x44,0x2,0x7,0xa1,0x78,0x30,0xd4,0x83,0x9f,0x49,0xa7,0xcb,0x49,0xe3,0x75,0x52,0xb1,0x8a,0xa2,0x60,0x25,0x60,0xad,0xc5,0xf6,0x1b,0x56,0x21,0x89,0xc7,0xc5,0x54,0x45,0x51,0xe2,0xf2,0x52,0xc6,0xb2,0x62,0x1b,0xbc,0xf0,0xea,0x80,0x16,0x8b,0xaa,0x98,0xcc,0x5e,0x97,0x51,0xc,0xa3,0xcb,0x21,0xff,0x5b,0x2f,0x4b,0x36,0xba,0x22,0xb,0x8f,0x24,0x41,0xb7,0x47,0xc0,0xa6,0xf2,0x9e,0xbd,0x7e,0x4c,0xf4,0xc7,0x8b,0x53,0xd0,0x8b,0x7c,0x10,0x6c,0x3c,0x54,0x14,0xe1,0x37,0x9e,0x7c,0x68,0xa2,0xcf,0xac,0x73,0xe,0x3f,0x7c,0xee,0x25,0xe4,0x65,0x15,0xf6,0x59,0x40,0xb0,0x57,0x2d,0x1,0x97,0x82,0x1,0x3d,0xff,0x6c,0xe0,0xb7,0x8f,0x2c,0x3b,0x6a,0x5f,0xca,0x70,0x7f,0xe1,0x89,0x3c,0x3f,0x21,0xe3,0x53,0xa0,0xfd,0x36,0xba,0x89,0x12,0xd5,0x49,0x17,0xc0,0xf8,0xe5,0x1f,0x98,0x78,0x9c,0xc6,0x3e,0x3a,0x6f,0x33,0x26,0x98,0x15,0xe3,0xe0,0x5b,0x53,0x22,0x5f,0x2f,0x58,0x8c,0x1d,0x97,0x6b,0x2,0x70,0x23,0xcf,0x4f,0x1e,0xac,0xfc,0x85,0xd6,0xb5,0xee,0x3d,0xa3,0xe9,0xe0,0x6d,0x0,0x48,0x5b,0x6d,0xb5,0xd5,0x2,0x80,0x6d,0xb5,0xd5,0x56,0x5b,0xd7,0x71,0x5f,0xc8,0x4c,0x2e,0x2f,0xe5,0xf5,0xfe,0x3c,0xde,0xd7,0xcf,0x39,0x87,0x92,0x1b,0xf,0xad,0x2b,0x96,0x9,0x45,0xb5,0x99,0xba,0xae,0x82,0x7,0x9a,0x37,0x90,0x27,0xaf,0xbd,0x8,0xf7,0xdc,0xb2,0x1d,0xab,0x57,0xcd,0x8d,0xad,0x73,0xa5,0x3f,0xc0,0x81,0x23,0x67,0x20,0x20,0x42,0x23,0xe9,0x1b,0x4b,0x2,0xeb,0x8,0x98,0x29,0xb2,0x1,0xaa,0x4a,0xe3,0x85,0xfd,0xef,0xc0,0x4e,0x78,0x28,0xdd,0xb9,0x7d,0x33,0xb6,0xdf,0x30,0x4f,0xe6,0xf5,0xcc,0x3e,0xf4,0x52,0x26,0x67,0xa9,0xa1,0x69,0x86,0x97,0xf8,0xa6,0x6c,0x5a,0x3d,0xfb,0xe2,0x1b,0x38,0x73,0x71,0x11,0xce,0xba,0xb0,0xdf,0x46,0x6b,0x38,0x36,0x4d,0x2f,0xd8,0xe3,0xe9,0xd4,0xa5,0x45,0x2c,0x5c,0x5d,0x86,0x75,0x2e,0xc8,0xa5,0x9c,0x73,0x24,0x53,0xe5,0xa6,0x65,0x52,0xbd,0x77,0xea,0x1c,0x5e,0x7e,0xfb,0x14,0x8c,0xf,0x97,0xf0,0x81,0x11,0xbe,0xa1,0x76,0x16,0x65,0x91,0xa3,0x9f,0x65,0x38,0x72,0xf2,0x62,0xf0,0x8d,0x4b,0xd3,0x2e,0x94,0x8a,0x91,0x24,0x9,0x1e,0xba,0xf7,0xb6,0x89,0xcf,0xf2,0xdf,0xff,0xf1,0x7e,0xbc,0x7b,0x66,0x21,0x0,0x54,0x60,0xf6,0x48,0x59,0x16,0x28,0xf2,0x1,0x1,0xa5,0x0,0x84,0x24,0x50,0x4e,0x33,0x0,0x79,0xfc,0xcc,0x45,0x7c,0xf3,0x87,0x2f,0x8d,0x31,0xfa,0x0,0x60,0xef,0xcd,0x3b,0x30,0x93,0xc6,0x81,0xf1,0xe9,0xd9,0x7c,0xc6,0x3a,0xbc,0x78,0xe0,0xf0,0xd8,0x7e,0x2a,0xa5,0xf0,0xf0,0xbd,0xb7,0xf8,0x96,0x29,0x34,0x12,0x1e,0xc4,0x7b,0xe8,0xee,0x9b,0x27,0xb2,0xf6,0xc6,0x7b,0x15,0x81,0x7b,0xf7,0xee,0x40,0xc2,0xac,0x19,0xf,0xda,0x45,0x71,0x8c,0xb2,0xc8,0x70,0xcf,0x2d,0xdb,0x30,0x3f,0x21,0xa8,0xe5,0xed,0xc3,0xc7,0x70,0xee,0xf2,0x62,0xe8,0xdc,0xf2,0x6c,0x5,0x51,0x94,0xb0,0x7f,0xa5,0xa,0x3e,0x64,0x81,0xa9,0xca,0x3e,0x57,0xa1,0xc9,0x64,0x56,0x92,0x83,0x83,0xc,0x81,0x37,0x96,0x1b,0x43,0x3e,0x5f,0xdc,0xc,0xca,0x86,0xd1,0xbf,0xf,0xd,0x19,0xeb,0x9f,0x46,0x1a,0x3d,0x67,0xaa,0x76,0xc0,0x69,0xeb,0xa3,0x19,0xe7,0x1b,0x7e,0x96,0x35,0x8b,0x8a,0x58,0x7e,0x2a,0x8e,0x3,0x40,0xe8,0xaf,0x6b,0x30,0x18,0x43,0x72,0x78,0xcb,0x8c,0x70,0xfa,0x3e,0x44,0x8a,0x12,0x63,0x1,0xf2,0xd7,0x14,0xfc,0xef,0xd4,0xc6,0x81,0xe5,0x9e,0x5a,0x97,0x0,0x44,0xd,0x9c,0x49,0x89,0x22,0xeb,0xc3,0x5a,0x8b,0x95,0xa5,0x2b,0xc8,0x56,0x96,0x0,0x0,0x55,0x55,0x22,0xcf,0xfa,0xb0,0x46,0xa3,0xbf,0xbc,0x8,0xa3,0x35,0xf2,0xc1,0xa,0xca,0x22,0x87,0xb5,0x16,0x65,0x91,0x71,0xe0,0x44,0x4e,0xec,0xe8,0x89,0xf6,0x68,0x16,0xb6,0x2a,0xa0,0xab,0x8a,0x27,0x51,0x68,0xc,0xef,0x2f,0x2f,0x6,0x30,0xf0,0xf0,0xb1,0x93,0xa8,0x26,0x78,0xbb,0xae,0x5a,0x35,0x87,0x5d,0x5b,0xd6,0xd3,0x3d,0x20,0x1f,0x90,0xfc,0x97,0xfd,0x66,0xd3,0xb4,0x7,0x7,0xa,0xf4,0x51,0x51,0xcc,0x1,0x1a,0x55,0xb8,0xef,0x50,0x8,0x92,0x40,0x9c,0xd0,0x38,0x47,0xf2,0x66,0x17,0x92,0x6c,0xef,0xbc,0x75,0xe7,0x44,0x89,0xe5,0xd5,0xc5,0x65,0x2c,0xf6,0xf3,0xc0,0x76,0x16,0x42,0x20,0xe9,0x74,0x83,0x27,0x2e,0xb1,0x9f,0xd3,0x29,0xf7,0x70,0xc3,0xe1,0x56,0x4,0x4c,0x56,0x45,0x81,0xaa,0x2c,0x90,0x74,0xba,0x48,0xd2,0xe,0x9c,0x43,0x60,0x5d,0x26,0x49,0x87,0x52,0x97,0xa3,0x8,0xce,0x11,0xa3,0x3a,0xed,0xcd,0x6,0xd0,0xd7,0xfb,0xcc,0x7a,0x5f,0xdd,0xc7,0xee,0xbd,0x19,0x7b,0x6f,0xde,0x39,0x71,0xbd,0x97,0x16,0x2e,0xe3,0xe9,0x97,0xf,0x86,0x60,0x25,0xcf,0xe4,0x2f,0xcb,0x1c,0x83,0xe5,0x25,0x94,0x45,0xc6,0xdb,0xee,0x2,0xb0,0xd7,0xf4,0x41,0x75,0xd6,0x85,0x7b,0xad,0xf4,0xfe,0x7f,0x81,0x7d,0x57,0xa7,0x3e,0x7,0x6f,0x4a,0x3b,0xe,0xb6,0x85,0xfb,0x5d,0x73,0xc8,0xf5,0x13,0x2e,0xd,0x2c,0xb0,0x9e,0x93,0x11,0x75,0xfa,0xc6,0xe8,0xe7,0x46,0x96,0x31,0xcc,0x2,0x9c,0x2,0x34,0x4e,0x1,0xcc,0x86,0xfc,0x7,0xdf,0x17,0x9b,0xff,0x5,0x0,0x6e,0xd7,0x5a,0xa6,0x1b,0x9,0xec,0x11,0xb5,0xde,0xb9,0xc9,0xc6,0x6c,0xab,0xad,0xb6,0xda,0x6a,0x1,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xeb,0xb0,0x7c,0x3a,0xa0,0x6b,0x80,0x2f,0x75,0xa,0xab,0xd,0xcd,0x0,0x1,0x5c,0x9,0x46,0xd3,0xf1,0xa4,0x62,0x60,0x85,0x9b,0xf,0x62,0x84,0x10,0x80,0xf8,0xf1,0x7,0xee,0x9a,0x8,0xb8,0x9d,0xbd,0x78,0x5,0xab,0x67,0x12,0x6c,0x5b,0x37,0x8b,0x1d,0x9b,0xd6,0x60,0xc7,0xa6,0xb5,0xd8,0xbe,0x7e,0xe,0xbb,0xb6,0x6c,0xc0,0x8e,0x8d,0x6b,0xb0,0xe3,0x86,0x79,0x6c,0xdf,0x30,0x87,0x9b,0xb6,0xdd,0x80,0x9d,0x9b,0x56,0xe3,0xd2,0x95,0x45,0xac,0xac,0xf4,0xc7,0x96,0xd3,0xe9,0xa4,0xf8,0xd4,0x23,0xf7,0x91,0x21,0xbc,0xd1,0x94,0xe,0x59,0x95,0xdc,0x8c,0x52,0x63,0x11,0xc5,0x29,0xa4,0x8a,0x88,0x11,0xd1,0x60,0x32,0x8e,0x56,0x7f,0x90,0xe1,0xc5,0x37,0x8f,0x87,0x4e,0x81,0x58,0x7d,0x8e,0xd3,0xb,0xa9,0x79,0x94,0x2a,0x42,0x59,0x64,0xa8,0xca,0x2,0x45,0x36,0xa8,0x81,0x45,0x66,0xc9,0xe4,0xd9,0x4a,0x60,0xc9,0x4c,0x7a,0xc8,0x7f,0xfa,0xf9,0xd7,0x51,0x94,0x45,0x60,0x8,0x6a,0x66,0xf5,0x79,0xdf,0x43,0x7f,0x58,0xa5,0x8a,0x2,0x83,0xd1,0xcb,0xc8,0x1c,0x1c,0xd6,0xcf,0x75,0xb0,0x71,0xc3,0xb8,0x11,0xfb,0xe5,0xab,0xcb,0x78,0xe6,0xe5,0xb7,0xa9,0x11,0xd,0xcc,0x1c,0x11,0xa4,0x7e,0x51,0x9c,0x40,0x7,0x56,0xa0,0x80,0x62,0x3f,0x2f,0x8,0x81,0x38,0xed,0xe0,0x95,0x43,0xa7,0x70,0xea,0xcc,0x38,0xa3,0xaf,0xdb,0x49,0x71,0xdb,0xce,0x8d,0xb5,0xdc,0x2a,0xc8,0xfe,0x34,0x5e,0x3d,0x74,0x2,0xb,0x97,0xaf,0x8e,0x7d,0xe6,0x96,0xdd,0xdb,0xb1,0x7e,0xd5,0x6c,0x60,0x62,0xfa,0x6,0xa3,0x9b,0x44,0xb8,0xf3,0xd6,0x9d,0x13,0xc0,0xe0,0xc,0xc7,0x4e,0x9e,0x1b,0x7b,0x7d,0xf3,0xd,0x6b,0xb1,0x7d,0xc3,0x7c,0xf8,0x3d,0x4e,0x3a,0xdc,0xc0,0x26,0x78,0x68,0xdf,0xde,0xb1,0xf7,0x6b,0x63,0xf0,0xa3,0x97,0xde,0x1c,0xa,0x23,0x50,0x11,0xb1,0x59,0x74,0x55,0x86,0x24,0x63,0xa9,0xd8,0xa3,0x4a,0x88,0x70,0xbc,0xfc,0x35,0x6a,0x8d,0x9,0x5e,0x56,0xde,0xff,0xcc,0x39,0xb,0x25,0x55,0x30,0xf1,0x77,0x9c,0x44,0x49,0x92,0x73,0x40,0x71,0xe3,0x5d,0xa7,0x69,0x8f,0xf6,0x8b,0x82,0x1b,0x4a,0x39,0x31,0x1d,0xba,0xad,0xb6,0x3e,0x1c,0x4,0xd0,0xd,0x25,0xbe,0x7b,0x90,0x9,0x10,0xd,0x50,0xdc,0x73,0x5b,0xeb,0xb4,0x77,0xff,0x19,0x9f,0x88,0x2b,0xf8,0x3d,0xb2,0x39,0x96,0x7a,0x5f,0xbc,0xa9,0x93,0x2b,0x2e,0xb0,0xcc,0x55,0x14,0x63,0x65,0xe9,0xa,0xf2,0xc1,0xa,0x16,0xce,0x9f,0x1,0x20,0x28,0x25,0x96,0xed,0x1b,0xaa,0x22,0x47,0x99,0xf,0xe0,0x2c,0x4d,0x86,0x38,0x9e,0x64,0xb1,0x9c,0xfe,0x9b,0xad,0x2c,0x21,0x1f,0xf4,0x51,0xe6,0x59,0x98,0x98,0x9a,0xec,0xcd,0x26,0x90,0x65,0x3,0x9a,0xb4,0xb2,0x6,0x70,0x16,0xc6,0x6a,0xc4,0x49,0x12,0xc0,0xfc,0x53,0x17,0x17,0xb1,0xbc,0x32,0x18,0xfb,0x6c,0xa4,0x14,0x9e,0x7c,0xf4,0x5e,0x74,0xe2,0x28,0x80,0x7c,0x7e,0x2,0xc5,0xa1,0x11,0x2a,0xe5,0x83,0x8d,0x98,0x9d,0xec,0x1,0x30,0x2,0xed,0x74,0x98,0x34,0x1,0x88,0x65,0xb9,0x69,0xcd,0x1c,0x6e,0x9f,0x2,0xa6,0x1d,0x39,0x7e,0x3a,0x48,0x62,0xa3,0x28,0x86,0xb5,0x96,0xf6,0x93,0x41,0x4f,0x3b,0xe4,0xd5,0x38,0x5a,0xc3,0x63,0x58,0xd2,0xe9,0xa2,0x37,0xb7,0x6a,0x68,0x72,0x8f,0xbc,0x8,0x35,0xa4,0x92,0xb0,0xcc,0x6a,0x8f,0x92,0x34,0x24,0x2f,0xb,0x51,0xb3,0xa3,0xbd,0xf7,0xdf,0x9d,0xbb,0x36,0xe2,0xf3,0x4f,0x3c,0xc,0xa5,0xc6,0xd7,0xab,0xb5,0xc6,0xdf,0x3c,0xf5,0x2c,0x6,0x59,0xc1,0xd7,0x3,0x4d,0xd4,0x18,0xad,0xd1,0xe9,0xce,0xa0,0x3b,0x33,0x7,0x21,0x24,0xb1,0x3b,0xd9,0x96,0xc3,0x68,0x1d,0x26,0xcc,0xfc,0xb5,0xe6,0x3,0xbb,0x2c,0x7b,0xaa,0x86,0x9,0x17,0xe,0x54,0xa2,0x94,0x69,0x1b,0xbc,0x8,0x47,0x87,0x50,0x62,0x14,0x8a,0x31,0x56,0x9e,0x68,0x24,0x3,0x8f,0xb1,0x1,0x1b,0xe3,0x75,0x13,0xd7,0x6b,0xda,0x39,0x88,0x21,0xf8,0x70,0xd2,0xcf,0xf8,0x40,0xe0,0xde,0xcf,0xcf,0xa3,0xef,0xa7,0xac,0x49,0xdf,0x9,0x6,0xfe,0xdc,0x28,0xf0,0xd8,0x38,0x46,0xb5,0x67,0x72,0x5b,0x6d,0xb5,0xd5,0x56,0xe3,0xbe,0xd8,0x1e,0x82,0xb6,0xda,0x6a,0xab,0xad,0xeb,0xa7,0x3c,0xc8,0x11,0x7c,0x73,0x4,0x19,0x7b,0x7b,0x79,0x50,0x55,0x15,0x9c,0xde,0x4a,0xf,0xd4,0x4,0xf6,0x81,0x40,0x24,0xf6,0x0,0xa4,0x50,0xc,0xd,0x99,0xca,0x90,0xf6,0xba,0x7b,0xcb,0x5a,0x6c,0xd9,0xb4,0x61,0xe2,0x3a,0xf7,0xec,0xd8,0x8c,0x3d,0x3b,0xb6,0x34,0xdb,0xcd,0x20,0x11,0x1a,0x35,0xc7,0xae,0x3d,0x75,0x26,0x3f,0x6c,0xdf,0x7b,0xe7,0xad,0xf8,0xeb,0xef,0xbf,0x88,0x8b,0x65,0x41,0xcd,0x5,0x83,0x92,0xce,0x5a,0x68,0x6b,0x10,0xc5,0x31,0x87,0x40,0x68,0x48,0x29,0x20,0xa3,0xc9,0x29,0xc0,0x27,0x4e,0x9f,0xc3,0xd5,0x95,0x7e,0x68,0x32,0x9c,0xb5,0x30,0xce,0x4,0x76,0x97,0x94,0x64,0x8e,0x6e,0x8c,0x46,0x14,0x25,0x50,0xb1,0x64,0x89,0x34,0x1d,0xaf,0x38,0xa1,0xb4,0x5a,0x6d,0xcc,0xc4,0x6d,0x5d,0xe9,0xf,0x70,0xe4,0xe4,0x5,0x32,0x5d,0x57,0x11,0xca,0xa2,0xc,0x4c,0x4a,0x6a,0x72,0xcb,0x90,0x8e,0xe9,0x1b,0x6d,0x62,0x0,0xa,0x94,0x45,0x86,0x38,0xe9,0x60,0xeb,0xd,0xab,0x27,0x7a,0xff,0xbd,0xf1,0xf6,0x51,0x68,0x27,0x10,0xa7,0x29,0x79,0x5e,0xd9,0xda,0x14,0x5e,0x45,0xc4,0x9a,0x93,0x8a,0xa4,0x70,0xe4,0xc7,0x47,0x8d,0x75,0xd4,0x89,0x91,0xf5,0x57,0x10,0x45,0x11,0x5e,0xd8,0x7f,0x10,0x3b,0xb6,0x6d,0x1a,0xb9,0x36,0x4,0x76,0x6f,0xdf,0x84,0xe7,0xdf,0x38,0x86,0x38,0x21,0x26,0x9d,0xf7,0xc9,0xcb,0x4a,0x8d,0x3,0x6f,0x1f,0xc3,0x13,0x1f,0x5f,0x33,0xc,0xca,0xa6,0x9,0x1e,0xbc,0x63,0x17,0xbe,0xf1,0xa3,0x3,0x2c,0x23,0xa7,0x73,0xb0,0x77,0xc7,0x6,0xac,0x9a,0x1b,0x67,0xed,0x1d,0x3c,0x72,0x12,0x47,0x4e,0x9e,0xc7,0x8e,0xad,0x1b,0x21,0x1b,0xcc,0x3,0x25,0x25,0x1e,0xba,0xe7,0x66,0x1c,0x39,0xfd,0xe3,0x90,0xf8,0x29,0xa4,0xc4,0xcd,0xdb,0xd6,0x63,0xe3,0xfa,0x35,0xe3,0xe7,0xef,0xe4,0x19,0x1c,0x3e,0x79,0x21,0x98,0xed,0x57,0x25,0xf9,0x7b,0x25,0x69,0x17,0x55,0x99,0x33,0xb0,0x4d,0xc7,0xc2,0x7b,0x9b,0x39,0x38,0x36,0xdb,0xaf,0x1b,0x43,0xb8,0x9a,0xad,0xe2,0x1b,0x7b,0xef,0x69,0xe8,0x25,0xbf,0xd,0xb5,0xef,0x10,0x78,0xeb,0x3c,0x57,0xb0,0xd1,0xf3,0x5,0x26,0x88,0xb3,0x10,0x42,0xc1,0xb9,0x36,0x4,0xa4,0xad,0x8f,0xa6,0xec,0x48,0xe8,0x2,0xfd,0xee,0x78,0x9c,0x90,0x80,0xab,0xd3,0xd8,0x11,0x6c,0x20,0x4c,0xb0,0x64,0xa8,0xca,0x2,0x51,0x9c,0x30,0xab,0xcc,0x2,0x90,0xc,0x86,0x6b,0x92,0xba,0x4e,0x99,0xfc,0xf0,0xa1,0x4e,0xde,0x53,0x4e,0x4a,0x2,0xd6,0xe6,0x56,0xaf,0x23,0x36,0x5f,0x49,0xf2,0x5f,0xf,0xb2,0x59,0x66,0xb4,0xe9,0xaa,0x24,0xa9,0xad,0x67,0xe6,0x86,0x54,0x60,0x3,0xe9,0x28,0x94,0xca,0x59,0x33,0x15,0xf0,0x4,0x33,0xf8,0x9c,0x43,0x8,0xb8,0x72,0xe,0x14,0x40,0x22,0x48,0xf2,0xfc,0xc6,0x5b,0x87,0xf1,0xc9,0x47,0xef,0x1f,0xfb,0xf8,0xad,0x37,0xef,0xc4,0xe3,0x1f,0xbb,0x13,0xdf,0xf9,0xf1,0x1,0x14,0xd9,0x80,0x26,0x33,0x18,0x70,0xf4,0x9e,0xb2,0x82,0x83,0x3e,0x1c,0x78,0x72,0x8c,0x27,0x5f,0xa4,0x8a,0x20,0x63,0x66,0x2d,0x73,0xd2,0x6d,0xac,0x4,0xbe,0xf0,0xa9,0xfb,0xd0,0x9b,0xe0,0x87,0xab,0xb5,0xc1,0x2b,0x6f,0xbe,0xb,0x21,0x4,0xb2,0xfe,0x4a,0x90,0xe7,0xfa,0x14,0x60,0xcf,0xe,0xf7,0xf7,0xb7,0x69,0xf7,0xf1,0xaa,0x2c,0x88,0x9,0xc8,0xa0,0xa7,0x3,0xa0,0x14,0x1,0x94,0xd6,0x39,0xc4,0x9e,0x79,0xa9,0x14,0xb1,0xe9,0x0,0x5e,0x7e,0x3d,0xb9,0x11,0xc5,0x9,0x9c,0x35,0x78,0xe4,0xce,0x5d,0xf8,0xc2,0x67,0x1e,0x99,0xca,0xd8,0x7e,0xeb,0xed,0x23,0x78,0xee,0xb5,0x23,0xf0,0xc1,0x1c,0xd6,0xd6,0x81,0x22,0x64,0x67,0x61,0x60,0xd9,0x37,0xb8,0x2a,0xb,0x4a,0x46,0x6e,0xf8,0xe1,0x9,0x6,0x84,0x21,0x6b,0x32,0x9e,0xb5,0xba,0xf6,0xe1,0x6b,0xc8,0x86,0x9d,0x9f,0x7c,0x19,0xb3,0xd2,0xf3,0xf1,0x1e,0xd,0x40,0x4f,0xa0,0x91,0x24,0x2c,0x86,0xb0,0xb0,0xf0,0x2c,0x11,0x70,0x3e,0x31,0x14,0xb2,0x31,0x9c,0x20,0x3c,0x1e,0x32,0x32,0xb4,0xde,0x9f,0x9a,0xb5,0xf7,0xb7,0x64,0xd5,0x8d,0xee,0xfc,0xfb,0xfc,0x1e,0x24,0xfe,0xae,0xe,0x26,0x9,0xd2,0xff,0xc6,0x16,0x35,0x7f,0x6f,0xee,0x5f,0x5b,0x6d,0xb5,0xd5,0x56,0xb3,0x5a,0x6,0x60,0x5b,0x6d,0xb5,0xd5,0xd6,0xf5,0x54,0xfc,0x20,0xeb,0xa5,0x39,0x9e,0x69,0x40,0xd,0x84,0xb,0xa6,0xe7,0x42,0x8,0x68,0x5d,0x21,0x8a,0x12,0x8,0x6,0xd9,0xe8,0x73,0x24,0x7d,0x4a,0x3b,0x5d,0x36,0x59,0x27,0x16,0xc2,0xc7,0xef,0xbf,0x1d,0x51,0x34,0x39,0xec,0x41,0x4a,0x2,0xb6,0xa4,0x94,0x50,0xfc,0xb3,0x52,0x72,0xe8,0x75,0xff,0xbf,0x52,0x2a,0x48,0x8b,0x27,0xd5,0x4c,0xaf,0x8b,0xc7,0x3f,0x76,0x57,0x78,0x70,0x95,0x52,0xa1,0x2c,0x72,0x68,0x5d,0x41,0x80,0xe4,0x59,0x8e,0x9b,0x13,0xd3,0xf0,0xdc,0x1b,0xad,0xd3,0xe7,0x2e,0x53,0xca,0x23,0x3,0x7e,0xe,0x2e,0x34,0xbf,0xba,0x2a,0x83,0x31,0x3e,0xf9,0xe1,0x99,0xc0,0xa2,0x90,0x8a,0x42,0x24,0x8c,0xd6,0xc8,0xb3,0x41,0x0,0x53,0x47,0xeb,0xca,0xe2,0x32,0xfa,0x79,0x19,0x3c,0x9d,0xbc,0x49,0x7c,0x55,0x16,0x30,0x15,0x49,0xbc,0x3c,0x0,0x65,0xb4,0xe,0x32,0x68,0x6a,0xaa,0x12,0x54,0x55,0x81,0x9d,0xdb,0xc6,0xbd,0xff,0xac,0xb5,0x38,0x74,0xec,0x54,0x90,0x89,0x79,0xf9,0x93,0x97,0xb5,0x4a,0xef,0xed,0xc5,0xac,0xc0,0xb2,0xc8,0xa1,0xa2,0x98,0xd8,0x19,0x45,0xe,0xa9,0x88,0xb5,0xf1,0xc6,0xa1,0x63,0x28,0xca,0xf1,0x6,0x73,0xd3,0xd,0xeb,0xc8,0x4b,0xca,0x98,0xc0,0x46,0x11,0x20,0x46,0xcb,0xf3,0x7,0x8e,0x20,0xcb,0xc6,0x7d,0xa9,0xee,0xd9,0xbb,0x13,0x49,0x24,0x59,0x3e,0x4d,0xc7,0xed,0xc1,0xbb,0x6f,0x1e,0x23,0x25,0x94,0x65,0x85,0x17,0xdf,0x3c,0x8a,0x37,0x8f,0x9e,0xc1,0xc5,0x85,0x2b,0x63,0xcb,0xb9,0x69,0xc7,0x16,0xcc,0xf5,0xd2,0xb0,0x3f,0xd6,0x18,0x3c,0x7c,0xef,0x2d,0x88,0xa2,0x68,0xec,0x18,0x3c,0xfb,0xc2,0x1,0x18,0x6b,0x1b,0xe6,0xf1,0xd4,0x8c,0xfb,0xa6,0xb9,0x2c,0x72,0x54,0x65,0xe,0x5d,0x96,0xc8,0x6,0x7d,0x62,0x6a,0x72,0xd3,0xeb,0x1b,0x25,0xcf,0x82,0x52,0x51,0x14,0xc2,0x43,0x8,0x50,0x26,0x1f,0x2f,0x8,0x10,0x7b,0x90,0xcf,0x61,0xed,0x47,0xc5,0x92,0xb5,0xd0,0x40,0x79,0x38,0x70,0xb4,0x49,0x6c,0x19,0x80,0x6d,0x7d,0x44,0xd5,0xb0,0x5a,0x18,0x2,0x43,0x58,0x12,0xe9,0xe5,0x97,0x9e,0x1d,0xa8,0xab,0x32,0x8c,0xa5,0x5e,0xe2,0x1b,0xc5,0x94,0x68,0x5b,0x95,0x5,0xfb,0xe2,0xd1,0x78,0xea,0xbf,0xe3,0xd3,0x18,0x80,0xae,0xe1,0xfb,0x56,0x16,0x59,0x18,0x1f,0xb5,0x2e,0x3,0xb,0x31,0x49,0x52,0x58,0xa3,0xc9,0xe3,0xaf,0x2a,0xd1,0x5f,0xba,0xc2,0xdb,0x51,0xc0,0x18,0x8d,0xe5,0xab,0xb,0x18,0x70,0xa8,0x44,0x91,0xd,0x1a,0xcc,0xb2,0x72,0x22,0xb3,0x56,0x48,0xc1,0x36,0x15,0x16,0x45,0x3e,0x40,0x99,0xf,0x60,0x39,0xcd,0x5b,0xb0,0xef,0x9d,0x10,0x2,0xcf,0xbc,0x7c,0x10,0x79,0x3e,0x3e,0x86,0x49,0x21,0xf0,0xab,0x9f,0x79,0x14,0x9f,0x7d,0x94,0x58,0xec,0x5a,0x13,0x18,0xd9,0x9b,0x9d,0xf,0xc0,0x93,0x94,0x51,0x60,0x6c,0xab,0x38,0xe,0xdf,0x6f,0xf,0xb4,0xe8,0xaa,0x42,0x59,0xe6,0x48,0x22,0x81,0x7f,0xf0,0xc4,0xfd,0xb8,0x6d,0xcf,0x8e,0x89,0xc7,0xe7,0xf8,0xc9,0x33,0x38,0x7a,0x8a,0x58,0xd0,0x4a,0x29,0x28,0xa9,0x42,0xe8,0x51,0x1c,0x27,0x94,0x66,0x6e,0xa7,0x7b,0x88,0x52,0xea,0xbc,0xe3,0xd0,0x2b,0x17,0x6c,0x3a,0xe2,0x24,0xd,0x3e,0x7a,0x1e,0xa0,0x94,0x8a,0x26,0xee,0xe2,0x38,0x21,0xf6,0x32,0x8f,0x7b,0x52,0x45,0x90,0x4a,0x61,0xb6,0x9b,0xe0,0x9f,0x7c,0xf6,0x11,0xfc,0xe6,0xe7,0x3f,0x89,0xee,0x94,0xb4,0xe2,0xf3,0x17,0x2e,0xe1,0x8f,0xbe,0xf2,0x6d,0x94,0x65,0x41,0xec,0x6a,0x7f,0x7e,0x8d,0x86,0x2e,0x4b,0xe8,0xaa,0x40,0x9c,0xa4,0x30,0xc6,0xa0,0x2a,0xb2,0xda,0xe,0xa2,0x99,0x32,0x1b,0x40,0x47,0x9e,0x70,0x81,0xe3,0xfd,0xe0,0x31,0xdd,0xd8,0xda,0x6e,0xa1,0xe1,0x15,0xe8,0x13,0xac,0xfd,0x68,0x2a,0x50,0xb3,0x5a,0x47,0x73,0x39,0x6a,0x39,0xb0,0x1b,0x1a,0x81,0x43,0xa8,0x88,0x98,0x30,0x36,0xbb,0x49,0x9,0xbc,0xa3,0x8f,0x4c,0x1f,0x12,0xab,0x6f,0x54,0xa6,0x8b,0x46,0xa0,0x54,0xf3,0xef,0x13,0x42,0xa8,0x42,0x90,0x49,0x13,0xc,0x1c,0xc1,0x23,0xdd,0x94,0x7d,0x73,0xad,0x7,0x60,0x5b,0x6d,0xb5,0xd5,0x2,0x80,0x6d,0xb5,0xd5,0x56,0x5b,0x7f,0x5f,0x7a,0x44,0x96,0xe3,0x18,0x1b,0x0,0x10,0xd7,0xf0,0x8b,0x22,0xef,0x26,0x92,0x82,0x39,0xcb,0x39,0xa9,0xec,0xd5,0x53,0x9b,0x78,0x6b,0xac,0x99,0xeb,0xe2,0xb6,0x9b,0x77,0x7d,0x68,0xdb,0x7d,0xff,0xdd,0xb7,0x62,0x7e,0xa6,0x4b,0xdb,0xc5,0xdb,0x1b,0xc7,0x4,0x9a,0x41,0x20,0xb0,0xee,0x84,0x90,0x43,0x4d,0x70,0xb3,0x2e,0x5d,0x59,0x6a,0xc8,0x77,0x89,0x9d,0x10,0x27,0x29,0xf9,0x18,0xb1,0x7f,0x54,0x9e,0xf5,0xc9,0x20,0x9d,0xda,0xc7,0x60,0x62,0xaf,0xd,0x35,0x7a,0x4a,0x29,0x14,0x59,0x1f,0x93,0x66,0xfb,0x57,0x56,0x6,0xcc,0xc2,0x23,0x56,0x8d,0x31,0x1a,0xf9,0xa0,0xcf,0x5e,0x83,0x19,0x2a,0x96,0x2e,0xe7,0x59,0x1f,0xc6,0x54,0x28,0xf3,0xac,0x6,0x1f,0xb9,0xb1,0x9a,0x9f,0x9d,0x90,0x1e,0x69,0x2c,0x2e,0x2c,0x2c,0x92,0x27,0x56,0x55,0x6,0x9,0xf,0xc9,0xbe,0x22,0x6,0x42,0xfd,0x6b,0xd4,0x3c,0x99,0x8a,0x4c,0xf6,0xad,0x31,0x28,0xb2,0x1,0xac,0x35,0xe8,0x17,0x7a,0x22,0x98,0xd7,0x49,0x63,0xe8,0x92,0x3c,0xa5,0x74,0x55,0x90,0x5f,0x21,0xa7,0xa,0x5f,0x5e,0xc9,0x71,0xe8,0xdd,0xf7,0xc6,0x3e,0xb3,0x6a,0x7e,0x16,0x77,0xdf,0xb4,0x89,0x98,0x87,0x51,0x84,0x6d,0xeb,0xe7,0xb0,0x75,0x2,0x1b,0xf4,0xc4,0xe9,0xf3,0x38,0x79,0xe1,0x2a,0xf9,0x3c,0x1e,0x38,0x3c,0xf6,0xf7,0x5e,0x37,0xc5,0xa3,0xf7,0xec,0x41,0x55,0xe4,0xd0,0x55,0x89,0xd,0x73,0x9,0xf6,0xec,0xdc,0x3a,0xe,0xae,0x5e,0x5d,0xc2,0x6b,0x87,0x4f,0x32,0xc0,0x6b,0x30,0xe8,0x2f,0x53,0x13,0x1c,0xc5,0xc1,0x4,0xdf,0xe8,0x8a,0x1,0x4c,0x3,0xc0,0x21,0xcf,0xfa,0xc8,0x6,0x2b,0xc1,0xf7,0x2a,0xb0,0xa3,0x42,0x98,0x8d,0x8,0xd,0x92,0xf7,0x68,0x24,0xa6,0x6a,0xcd,0x8a,0x6a,0x36,0xfb,0x63,0x4d,0x1a,0xc4,0xd8,0xdf,0xa5,0x4a,0xda,0x41,0xa6,0xad,0x8f,0xa4,0xc6,0x98,0x72,0x21,0xdc,0x83,0x98,0xae,0x5e,0x6,0x6c,0xc2,0xf7,0x5b,0x70,0x82,0x6d,0x4a,0xc,0x58,0x15,0xa1,0xaa,0xca,0x21,0x4f,0xce,0x10,0xfc,0xc0,0x63,0xac,0xbb,0x86,0x74,0xd0,0x3,0x51,0x3e,0x71,0xde,0x5b,0xa,0xf8,0x50,0x8,0xb2,0x90,0x88,0x39,0x29,0x58,0x22,0xed,0xf4,0x60,0x8d,0xa1,0x4,0x59,0xe,0xa2,0x52,0x51,0xc4,0x13,0x1b,0x2a,0x7c,0xd7,0xac,0xd1,0x13,0xb9,0x55,0xe4,0x7b,0x57,0xd5,0xf7,0x2d,0x43,0xdf,0xfb,0x41,0x7f,0x9,0x45,0x9e,0x41,0x6b,0x4a,0xbd,0x3f,0x75,0x7e,0x1,0xaf,0xbd,0x75,0x64,0xe2,0x36,0x47,0x51,0x84,0x2f,0xfc,0xd2,0x27,0xf0,0xdf,0xfd,0xe6,0x93,0x58,0xbb,0x6a,0x9e,0xf6,0x93,0x59,0x6d,0x92,0x13,0x69,0xa3,0xa8,0x96,0xfc,0x5a,0x4e,0xb9,0x25,0x50,0xcc,0x42,0x29,0x85,0x5d,0x5b,0x37,0xe2,0xf7,0xfe,0xe1,0xa7,0xf1,0xc0,0x3d,0x7b,0x27,0x4a,0x78,0xab,0x4a,0xe3,0xa9,0x67,0x5f,0x41,0x59,0x56,0x7c,0x5c,0xc8,0x3,0xd1,0x7,0x96,0xe4,0xd9,0x80,0x83,0x44,0x30,0xf5,0xf8,0x3a,0x47,0x56,0x11,0x9e,0xa9,0x4c,0x7e,0x85,0x86,0x8f,0x59,0x8c,0x84,0x93,0x80,0x69,0x62,0x44,0x6,0x80,0x34,0xcf,0xfa,0xb0,0xcc,0xa8,0x5c,0x33,0x93,0xe0,0xb3,0x8f,0xde,0x8d,0x7f,0xf5,0xbb,0xbf,0x81,0x8f,0xdd,0x77,0xc7,0x54,0xb9,0xf1,0xe2,0xd2,0x32,0xfe,0xf0,0xcb,0x7f,0x8d,0xcb,0xcb,0x19,0xcb,0x9e,0x25,0xac,0x75,0xc1,0x62,0xc2,0xdf,0x7f,0xab,0xb2,0x40,0xda,0xe9,0x22,0xe9,0xf4,0x68,0x62,0x8d,0xcf,0x7b,0x7d,0xfe,0xeb,0xeb,0x47,0x2a,0xc9,0xcf,0x1d,0x1a,0x5e,0xce,0x2c,0x99,0x89,0x2f,0x84,0x64,0xe0,0x32,0x62,0x5f,0x42,0x13,0xc6,0x56,0xcf,0x62,0x1c,0x2,0xe4,0x4,0x1a,0xc8,0x9e,0x7,0xcb,0xc4,0x38,0xa8,0x36,0xd,0xe8,0xfa,0x85,0xb0,0xdf,0xa6,0x3,0x86,0x6e,0xd4,0x8f,0xcf,0x6f,0xe3,0x90,0x3c,0xb7,0xfe,0x3f,0xb0,0xcf,0x59,0x76,0x3f,0x9,0xdc,0x6c,0x2,0xa1,0x62,0x4,0xd8,0x13,0xf0,0xa0,0xe8,0xf8,0xd6,0x85,0x18,0x94,0x16,0x0,0x6c,0xab,0xad,0xb6,0x46,0xef,0x87,0xed,0x21,0x68,0xab,0xad,0xb6,0xda,0xba,0x7e,0x2a,0x34,0x60,0xd6,0x86,0x9f,0x45,0x30,0x85,0x26,0xd0,0x3,0xdc,0x74,0x39,0x6e,0x16,0xc1,0x5e,0x47,0xfe,0xd1,0x31,0x8a,0xe3,0x60,0xf0,0xed,0xe0,0xf0,0xc9,0x7,0x6e,0x47,0xaf,0xdb,0xf9,0xd0,0xf6,0x61,0xdd,0xda,0xd5,0xb8,0xff,0xce,0x3d,0x78,0xfa,0xe5,0x83,0x70,0x25,0x31,0x57,0x8a,0x3c,0x23,0x26,0x17,0x27,0x12,0xfb,0x26,0x75,0x1a,0x93,0xb0,0xd2,0x55,0x48,0xc4,0xb4,0x8e,0x12,0xa,0x7,0x2b,0x4b,0xc,0x22,0x91,0xef,0x9d,0x31,0x55,0x30,0x3c,0x8f,0xe3,0x4,0x5a,0x97,0xec,0x1,0xc7,0x26,0xf8,0xce,0xa1,0x37,0xdb,0x9b,0xf8,0x0,0x5d,0x96,0x25,0xb2,0xfe,0x32,0x35,0xd4,0x5a,0x87,0x46,0xcc,0xa7,0x59,0xfa,0x86,0xdb,0x37,0xc1,0x2a,0x8a,0x2,0x98,0x68,0x6d,0x8e,0x38,0xe9,0x20,0x4d,0xc7,0x19,0x19,0xc6,0x1a,0x64,0x79,0x1e,0xc0,0x4b,0x11,0x93,0x5f,0x55,0x9c,0x90,0x1c,0xd8,0x59,0x47,0xdb,0x19,0xc5,0xc8,0x7,0x2b,0xe4,0x7,0xc8,0x2c,0xc8,0xb2,0xc8,0x49,0xf2,0x5,0x87,0xac,0x28,0x87,0xd3,0x83,0xfd,0x4d,0x5f,0x49,0x12,0xb9,0x71,0xf3,0xa9,0xab,0xa,0x45,0x36,0x40,0x6f,0x76,0x1e,0xd6,0x5a,0x3c,0xf3,0xd2,0x41,0xdc,0x7e,0xeb,0x6e,0x24,0x71,0xdc,0xc4,0x16,0xf0,0xc8,0xfd,0x77,0xe0,0xa5,0x83,0x4,0xca,0x3d,0xba,0xef,0x96,0x31,0x1f,0x29,0x6b,0x2d,0x5e,0x7e,0xf3,0x28,0x9b,0x8e,0x4b,0x1c,0x38,0x7c,0x1a,0x9f,0x7e,0x38,0xc3,0xec,0xcc,0x30,0xc8,0x79,0xd7,0xad,0x3b,0xf1,0xd4,0x8f,0xf,0x60,0x90,0x1b,0x3c,0xb2,0xef,0xd6,0x89,0x9,0x9a,0x2f,0xbf,0xfe,0xe,0x6,0x59,0x41,0xec,0xbc,0x88,0x40,0xc,0x38,0x4,0xe0,0x62,0x65,0xe9,0x6a,0x38,0x47,0x14,0x1e,0x50,0x40,0x45,0x11,0xe2,0x38,0x45,0x59,0xe4,0x88,0xd3,0xe,0x4c,0x55,0x11,0xb8,0x1,0x1,0x38,0x4b,0x9e,0x7d,0xcc,0x86,0x1d,0x6,0x8e,0x45,0x30,0x49,0x17,0x23,0xd2,0xaa,0xa1,0x6,0x7d,0x8,0xc,0xa4,0xfd,0x35,0x3a,0x6f,0x7,0x9c,0xb6,0x3e,0x92,0x92,0x2a,0x1e,0x2,0x40,0xa4,0x54,0x30,0xce,0x51,0xc0,0x91,0xb6,0xe1,0x1a,0xf7,0x8c,0x6f,0xf,0xe4,0x68,0x5d,0x21,0x4d,0xbb,0x81,0x1,0x67,0xad,0x85,0x64,0xa9,0xa7,0x7,0xf2,0x44,0x9c,0xd2,0xf8,0x37,0x35,0x23,0xc1,0x5,0x36,0x6e,0x55,0x16,0x70,0xc,0x94,0x9,0xa9,0xa0,0x84,0x80,0xa9,0xaa,0x60,0x87,0x10,0x27,0x49,0x0,0xae,0x9c,0xb3,0x50,0x69,0x27,0x84,0x6b,0x18,0xad,0x59,0xa2,0x6a,0x83,0x3c,0x16,0x9c,0x42,0x3c,0x86,0xe3,0x30,0x80,0x87,0x6,0x93,0x3b,0x1f,0xac,0x90,0x54,0xb6,0xc8,0xc8,0x13,0xcf,0xc4,0x50,0x36,0xc2,0xd7,0xbf,0xfb,0x2,0x6e,0xda,0xb1,0x15,0xeb,0xd7,0x8d,0x5b,0xb,0x48,0x29,0xf1,0xc8,0xc7,0xf6,0xe1,0xb6,0x9b,0x77,0xe1,0x47,0x2f,0xbc,0x82,0x1f,0xbd,0xfc,0x36,0x16,0x96,0x32,0x44,0x71,0x4c,0x13,0x2e,0x52,0x5,0x0,0xcb,0x83,0xa3,0xab,0xe6,0xe7,0xb0,0x7d,0xfd,0x1c,0x1e,0xb9,0x6f,0x2f,0x6e,0xd9,0x7d,0x23,0x92,0x24,0x9e,0x7a,0x5e,0x5e,0x7c,0xed,0x20,0xde,0x38,0x72,0x82,0xec,0x36,0xca,0x22,0x1c,0x2b,0xef,0xab,0x67,0x42,0x4a,0xb9,0xc6,0x34,0xc6,0x19,0x9d,0x37,0xba,0x6f,0x94,0x3a,0xb,0x41,0x5c,0xba,0x2a,0x81,0x88,0xce,0xa1,0x3f,0x9e,0x49,0x14,0x23,0x8e,0x22,0x44,0x52,0x60,0xf7,0x96,0xed,0xd8,0xb5,0x6d,0x23,0xf6,0xec,0xd8,0x82,0x1d,0xdb,0x37,0xa1,0x93,0xa6,0xd7,0xbc,0x86,0x96,0x57,0xfa,0xf8,0xa3,0x2f,0xff,0xd,0xe,0x1e,0x23,0xef,0x46,0xef,0xcd,0xe8,0xbd,0xb,0x1d,0xb3,0xd7,0xbd,0x6f,0x63,0x91,0x67,0x98,0x99,0x5f,0x5d,0x4b,0x51,0xe1,0x3,0x96,0x58,0x8e,0x2d,0x6a,0x6f,0x49,0x62,0xe4,0x11,0x5b,0xdd,0x68,0xba,0x1e,0x84,0x14,0x4,0x5c,0x3b,0xc,0x1,0x7f,0x5e,0xb2,0x2c,0x79,0xe2,0x71,0xc,0x3c,0xc3,0xa8,0x4c,0xf7,0xfd,0xc2,0x38,0x7e,0xe,0x29,0xbc,0xd,0xa9,0x6d,0x78,0x86,0x6a,0xbc,0x1e,0x7e,0x84,0x6b,0x6a,0x92,0xc7,0xe4,0xc9,0x61,0x6b,0xc5,0xb0,0x4,0x7a,0x68,0x4b,0x1d,0xbd,0x4b,0x4c,0x80,0x15,0xc3,0x9e,0x4,0xff,0x59,0x37,0xe,0x45,0x4e,0x58,0x6e,0x7d,0xe8,0x44,0x78,0x36,0x69,0xab,0xad,0xb6,0xda,0x6a,0x1,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xeb,0xb0,0x54,0x14,0xd7,0xac,0x27,0x96,0xf3,0xaa,0x48,0xc1,0x68,0x83,0x28,0x89,0x9,0x58,0x12,0x3c,0xdb,0xce,0x33,0xcf,0xde,0x93,0x48,0x4a,0x5,0x63,0xc,0xa4,0xb2,0x1,0xe4,0x98,0x99,0xe9,0x61,0xdf,0x5d,0xb7,0x7e,0xa8,0xfb,0x20,0x84,0xc0,0x27,0x3e,0x76,0x2f,0x7e,0xf8,0xc2,0x1b,0xb4,0x7d,0xcc,0x4c,0x34,0x5a,0xa3,0xaa,0x4a,0xa0,0x2,0x3a,0xdd,0x1e,0x3a,0xdd,0x99,0x6b,0xfa,0xdb,0x78,0x10,0xcd,0x59,0x1b,0x8c,0xd1,0xf3,0xfe,0x72,0x30,0xa8,0x2f,0xb2,0x3e,0x66,0x57,0xad,0xa5,0x66,0x96,0x41,0xa6,0xe0,0xa7,0x17,0xc7,0xc8,0xb3,0x3e,0x66,0x52,0x35,0x91,0x45,0x20,0x24,0x31,0x30,0xfc,0xf1,0x4,0x7b,0xcc,0x15,0xb9,0xe5,0x66,0x89,0xd2,0x26,0x8d,0x4e,0x90,0x76,0x7b,0x28,0xb,0x1d,0x42,0x34,0x9c,0x35,0x1c,0x3e,0x32,0xe,0xd0,0x49,0x21,0x21,0x9d,0x9,0x5e,0x82,0x43,0xa0,0x2e,0x37,0x49,0x2a,0xed,0xa0,0x2c,0x9,0x7c,0xaa,0x2a,0xf,0x5a,0x9a,0x90,0xe2,0x5c,0x16,0x1a,0xdd,0x6e,0x2f,0x84,0xbf,0xc,0x3,0xa3,0x1a,0x83,0xc1,0xa,0x11,0x10,0xac,0x65,0x93,0x7b,0x85,0x8a,0x59,0x2e,0xef,0x9d,0xbb,0x8c,0x13,0xa7,0xce,0x63,0xcf,0xae,0x6d,0x43,0x9f,0xdb,0xb4,0x61,0x1d,0x6e,0xde,0xb6,0x1e,0x27,0xcf,0x5d,0xc4,0x2d,0xbb,0xb7,0x8f,0x2d,0xf7,0xf2,0xd5,0x25,0xbc,0x7d,0xe2,0x52,0x0,0xcd,0x2e,0x5f,0x5d,0xc4,0x9b,0x87,0x8e,0xe1,0xa1,0xfb,0x6e,0x1f,0x7a,0xdf,0xfa,0xb5,0xab,0x70,0xe7,0xee,0xcd,0x78,0xf3,0xe8,0x59,0xdc,0x79,0xeb,0x38,0xab,0xb4,0x3f,0x18,0xe0,0xb9,0xfd,0x87,0x98,0x59,0x62,0x50,0x95,0x5,0x84,0x24,0xcf,0x31,0xf,0xfc,0x4a,0x29,0x91,0xf5,0x57,0xa8,0x39,0x65,0xcf,0x33,0x54,0xd4,0x68,0xc7,0x69,0x87,0xa5,0xd6,0xe4,0x55,0x28,0x39,0x2d,0x58,0x29,0x5,0xc3,0xd7,0x91,0x54,0x32,0xf8,0x2,0x52,0x53,0xea,0xfd,0x32,0x45,0xed,0xa3,0x34,0x2,0xf8,0xd5,0x60,0xa0,0x6f,0x8,0xe5,0xcf,0xa7,0xd1,0x6c,0xab,0xad,0x9f,0x5,0x9f,0x60,0x6,0x9e,0x43,0xed,0xfd,0xe5,0xaf,0x51,0x29,0x23,0x4a,0x92,0x95,0xb5,0xdf,0x25,0x31,0xe7,0x4,0xcb,0x5f,0xab,0xda,0x2b,0xd6,0x92,0x7f,0x26,0xb4,0x66,0xdb,0x8,0x41,0x49,0xc0,0x52,0x5e,0xe3,0xd2,0x76,0x8d,0x30,0x11,0x1b,0x0,0xa2,0xac,0xbf,0x4,0x5d,0x96,0x98,0x5d,0xb5,0x26,0xf8,0xce,0xa6,0xdd,0x99,0x30,0x7e,0x45,0x49,0xa,0x38,0xa0,0x37,0x33,0x13,0x82,0x90,0xe0,0x0,0x15,0xc7,0xec,0xd1,0x6a,0x21,0x46,0x75,0x9f,0x61,0x8d,0x4,0xb4,0xe8,0xaa,0x9,0x52,0x91,0x9c,0x54,0xb0,0x9f,0xab,0x73,0x16,0x65,0x9e,0x61,0xe1,0xaa,0xc0,0x57,0xbe,0xf9,0x2c,0x7e,0xe7,0xb7,0x7e,0x79,0x2a,0x8,0xb6,0x66,0xcd,0x6a,0xfc,0xea,0xaf,0x3c,0x81,0x27,0x1f,0x7f,0x14,0x17,0x2e,0x5e,0xc6,0x99,0xf3,0x97,0xb0,0xb8,0xd4,0xc7,0xca,0x20,0x43,0x1c,0x27,0xe8,0xa4,0x9,0xe6,0x67,0x7b,0xb8,0x61,0xfd,0x1a,0xac,0x5f,0xbb,0xa,0xf3,0x46,0xc1,0x47,0xf5,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0x73,0x33,0xef,0xeb,0xa5,0x76,0xec,0xbd,0xd3,0xf8,0xfa,0x77,0x9f,0x87,0xd6,0x86,0x2d,0x35,0x4,0xaa,0x32,0xa7,0xa0,0xa5,0x46,0x62,0x39,0xdd,0x97,0xf5,0x54,0x10,0x6b,0xdd,0xda,0xd5,0xf8,0xd7,0xff,0xf2,0xd7,0x3,0xd6,0x44,0xf7,0x18,0x11,0x2,0x5b,0x4,0x4,0x4,0x5b,0x55,0xa4,0x69,0xa,0x29,0x80,0x34,0x4d,0x90,0x26,0xc9,0x35,0x82,0x45,0x86,0xeb,0xe2,0xa5,0x5,0xfc,0xc9,0x5f,0x7c,0x13,0xaf,0x1d,0x3a,0x4e,0x80,0x64,0xd3,0x17,0x95,0x81,0x3f,0x6f,0xb7,0x41,0x60,0x28,0x25,0x27,0x17,0xd9,0x0,0x9d,0xee,0x4c,0x90,0xdd,0x1a,0x4d,0x7e,0x91,0x7e,0x9f,0x3c,0x4b,0x5b,0x8,0x11,0xac,0x26,0xbc,0xa7,0xe0,0x28,0x98,0x46,0x63,0xaf,0xf,0x62,0x92,0xd7,0xc,0xab,0x68,0x2,0x5f,0xef,0xef,0xd9,0x67,0x31,0xc6,0x12,0x6c,0x2,0x78,0x35,0xea,0x38,0x99,0x21,0xe8,0x5f,0x6f,0x4c,0x6,0x8d,0xfe,0xdd,0x35,0x46,0x7f,0xe1,0x3d,0x6,0x31,0x9a,0x3e,0xec,0x86,0x18,0x7b,0xc0,0xa8,0xa,0x78,0x9c,0xf1,0x37,0x7e,0xdd,0x37,0x37,0xdb,0x5d,0x13,0xaf,0x1c,0xfd,0xbe,0x8c,0xde,0xc3,0xda,0x6a,0xab,0xad,0xb6,0x5a,0x0,0xb0,0xad,0xb6,0xda,0x6a,0xeb,0xba,0xec,0xc,0x5d,0xf0,0x6,0xf2,0x29,0xa8,0x46,0x6b,0x96,0x9f,0x72,0xa8,0x6,0x24,0x1c,0xc,0x87,0x69,0x18,0x32,0x15,0x67,0x16,0x47,0x90,0x8c,0x30,0x30,0xf8,0xc0,0xed,0x3b,0xb1,0x66,0xd5,0xfc,0x4,0xa0,0x26,0xc7,0x37,0x7f,0xf0,0xc2,0x50,0x83,0xe9,0x99,0xa,0x46,0x57,0xb4,0x3c,0x15,0x51,0x18,0x6,0x5b,0xab,0x5b,0x2f,0x15,0x63,0xe9,0xa5,0x8c,0x12,0xcc,0xcd,0xce,0xe0,0xb3,0x4f,0x3c,0x82,0x78,0xc4,0x7,0x6e,0xf3,0xc6,0xf5,0xb8,0x7d,0xd7,0x66,0xbc,0xfe,0xee,0xa9,0x0,0x72,0x45,0x71,0x34,0x4,0x54,0xda,0x7c,0x30,0xb5,0x89,0xa,0xfb,0x2,0xcf,0x44,0xa0,0xe6,0x37,0xe9,0x74,0xb1,0x78,0xf9,0x12,0xbc,0x31,0x78,0x7f,0x79,0x11,0xbd,0xd9,0x79,0x14,0xf9,0x0,0xc6,0x68,0x74,0x7b,0xb3,0xc4,0x6c,0xb1,0x16,0x69,0xa7,0x7,0x63,0xec,0x64,0x15,0x91,0x73,0xd4,0x28,0x73,0xa3,0x43,0x6,0xf6,0xe4,0xf3,0x67,0x74,0x85,0x24,0xed,0x6,0x36,0xa0,0x97,0xdd,0xd9,0x6,0x88,0xa4,0x94,0xc3,0xf2,0x84,0x24,0xe4,0x28,0x52,0x98,0xed,0xa5,0xb8,0xb8,0x38,0x60,0x89,0x94,0xe5,0xe0,0x8b,0x82,0x40,0xc9,0x1,0x7d,0xc6,0xb3,0x40,0x74,0x55,0xa2,0x2a,0x32,0x18,0x6e,0xd4,0x8c,0xa3,0x75,0xcf,0x74,0x92,0x89,0x9e,0x4f,0x55,0xa9,0x51,0x16,0x64,0xfe,0x5f,0x55,0x25,0xb3,0x6,0x69,0x39,0x71,0x9c,0xa2,0x92,0x12,0x3f,0x7a,0xf9,0x2d,0xdc,0xb4,0x73,0xeb,0x50,0xc3,0xab,0x94,0xc4,0x23,0xf7,0xed,0xc5,0xa6,0x13,0xf3,0x98,0xe9,0x75,0xc7,0x9a,0x94,0x57,0x5e,0x3f,0x82,0x41,0x96,0x71,0xf3,0x27,0x11,0xc5,0x9,0x5e,0x7e,0xf3,0x28,0xee,0xbb,0xeb,0x16,0xc4,0x23,0x2c,0xbf,0x7,0xee,0xbe,0x5,0x9d,0x34,0xc6,0xaa,0xf9,0xb9,0xb1,0xed,0x7b,0xeb,0x9d,0xe3,0x24,0xdf,0x66,0x2f,0x3e,0xc5,0xac,0x19,0x21,0x65,0x90,0x6e,0x7b,0xe6,0x89,0x8a,0x63,0x2c,0x5f,0xb9,0x44,0xd7,0xba,0x3,0x12,0xd5,0x85,0x33,0x6,0xa5,0xcd,0x83,0x7,0x26,0x9d,0x23,0xc9,0xc9,0xc1,0x8e,0xc3,0x5f,0x74,0xf0,0x4b,0x13,0x74,0xb1,0x8c,0x79,0x5a,0xb9,0x89,0xcc,0x13,0xa0,0x96,0xab,0x51,0x38,0x80,0xd5,0x65,0x3b,0xe6,0xb4,0xf5,0x51,0xc,0xf4,0xf5,0xbf,0x42,0xc2,0x31,0xb3,0xcc,0x4f,0xe6,0x8,0xa5,0xa0,0xd9,0x2f,0x93,0x2,0xa1,0x10,0xc6,0x5e,0x6b,0xd,0xa2,0x28,0x86,0x66,0xa6,0x5e,0x8,0x8d,0x70,0x16,0xc6,0x30,0xa3,0xd0,0xa9,0xa9,0x80,0x97,0x60,0x50,0x9d,0xc2,0x3d,0x14,0x1c,0xc0,0x60,0x91,0x43,0x67,0x66,0xe,0x55,0x59,0x60,0x76,0xd5,0x5a,0x4e,0xbf,0xad,0x27,0x2f,0x7c,0xc8,0x14,0xdd,0x5b,0x0,0x29,0x54,0x90,0x82,0x6,0x20,0x5e,0x4d,0x5e,0x2f,0x85,0x99,0x38,0x44,0x51,0x84,0x22,0xaf,0x38,0x4,0x4a,0x5,0x16,0x74,0x92,0x76,0xa0,0xab,0xa,0x69,0xa7,0xb,0xe7,0x1c,0x5e,0x7b,0xe7,0x4,0xbe,0xf4,0xb5,0xef,0xe2,0xb7,0x7f,0xed,0x89,0x6b,0xb2,0xd7,0xbb,0x9d,0xe,0x76,0x6c,0xdf,0x82,0x1d,0xdb,0xb7,0xfc,0xad,0xce,0xc6,0xc9,0xd3,0x67,0xf1,0x5f,0xbe,0xfc,0x2d,0x2c,0x2e,0xaf,0xd0,0x3d,0x80,0xe5,0xb1,0x0,0x1,0x78,0x4a,0x2a,0x14,0x65,0x49,0x13,0x47,0x4e,0xc1,0x48,0x39,0xd1,0x5b,0x16,0x0,0xe2,0x28,0xc2,0xe6,0x8d,0x1b,0x7e,0x21,0x57,0x8d,0xb5,0x16,0x6f,0xbf,0x73,0x14,0x5f,0xfa,0xfa,0x53,0x38,0x79,0xe1,0xa,0x84,0x24,0xef,0x58,0x4a,0x51,0x2f,0x83,0x8f,0xad,0x75,0x16,0x15,0x4f,0x32,0x69,0x5d,0xa1,0xbf,0x7c,0x15,0x4a,0x45,0x98,0x5d,0xb5,0x36,0x5c,0x67,0x3e,0x7d,0xdd,0x7,0x9c,0x40,0x88,0xc0,0xf6,0xb,0x20,0x6d,0x83,0xa5,0x2f,0x1a,0x3e,0xac,0x7e,0xc,0x15,0xd,0xe9,0x2b,0x4d,0xaa,0x5c,0x43,0xca,0x3b,0x1,0x44,0x9b,0x5c,0x62,0xd8,0x27,0x6f,0xcc,0x2f,0xaf,0x31,0xbe,0x37,0xc0,0x3e,0xcf,0xd4,0x1b,0xa2,0xd3,0x31,0x88,0xe7,0x9a,0x69,0xc2,0x8d,0xbf,0x37,0x41,0xbf,0xb1,0x4c,0xe1,0x66,0x48,0xc7,0x44,0x86,0x9e,0xfb,0x5,0x8c,0x9,0xc3,0xc1,0x21,0x1,0x99,0x6c,0xab,0xad,0xb6,0xda,0x6a,0x1,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xeb,0xb7,0x2d,0x6c,0x86,0x19,0x10,0xd0,0x21,0xeb,0xd4,0x44,0xd4,0x33,0xe0,0xb5,0x97,0x12,0x2,0x30,0x12,0x27,0x9,0x7b,0x34,0x29,0x8,0x1,0x3c,0x7c,0xdf,0x1d,0x43,0x69,0xae,0xbe,0xe,0x1e,0x3e,0x8e,0x67,0xf7,0x1f,0x1e,0x5a,0xb3,0xb3,0xbc,0x5e,0x4e,0xac,0xb5,0xcc,0xd8,0xab,0xca,0x22,0x3c,0xc,0xe7,0x59,0x1f,0x11,0xfb,0x18,0xc5,0x49,0xa,0xa5,0x22,0xdc,0x7e,0xcb,0x2e,0xdc,0xb4,0x73,0xdb,0x18,0x10,0xf6,0xe9,0x47,0xf7,0xe1,0xe0,0x89,0xb,0xe4,0x9d,0x34,0x58,0x9,0x4d,0x44,0xda,0xe9,0x11,0x13,0xa1,0x37,0x33,0xb5,0x89,0x22,0x3f,0xbf,0x8a,0xa5,0x9a,0xc4,0x1a,0xc9,0xb3,0x3e,0x54,0x14,0x43,0x2a,0x89,0xaa,0xc8,0x51,0x96,0x39,0xba,0xbd,0x59,0xc,0x56,0x16,0x21,0x84,0x44,0x92,0x76,0xea,0x63,0x61,0xd,0x8a,0x62,0x80,0x5e,0x32,0x13,0xbc,0x89,0x46,0x1b,0x29,0x9f,0x80,0x48,0xfb,0xed,0x2,0xcb,0xc1,0x18,0x83,0x92,0x13,0x36,0xb,0xe,0x12,0x51,0x2a,0x42,0xd2,0xe9,0x85,0x30,0x14,0x8,0x81,0xb3,0xe7,0x2f,0x4d,0x0,0x2e,0x25,0x76,0xdf,0xb8,0x5,0x47,0xcf,0x2c,0xb0,0xf1,0xbd,0x9,0xcd,0x64,0x55,0x96,0xa8,0xca,0x1c,0x49,0xa7,0x7,0x5d,0x95,0xe4,0x87,0xa7,0xc8,0x47,0x2b,0x49,0x3a,0x30,0x46,0x23,0x49,0x3b,0x90,0x52,0xe1,0x86,0xb5,0xf3,0x13,0xa5,0x6a,0x97,0xaf,0x2e,0x6,0xb6,0x8c,0x4f,0xc6,0xa5,0xf3,0x23,0x61,0xa4,0x6,0x4a,0x87,0xfd,0x87,0xde,0xc3,0xe7,0x16,0xae,0xe2,0x86,0x91,0x74,0xde,0x9b,0x76,0x6e,0xc1,0xd6,0x4d,0xeb,0xc7,0x96,0x39,0x18,0x64,0x78,0xf5,0xd0,0x9,0x2,0x16,0xd8,0xfc,0x5f,0xeb,0xa,0x47,0xcf,0x2e,0xe0,0xbd,0x53,0x67,0xb0,0x67,0xd7,0x8d,0x43,0xef,0xbf,0x71,0xeb,0x46,0x6c,0x58,0xb7,0x66,0xac,0xd1,0xd7,0x5a,0xe3,0x99,0x17,0x5e,0x27,0x89,0x60,0x9c,0x20,0x1f,0xf4,0x1b,0xfb,0x4f,0x6c,0x26,0x1f,0x8e,0x22,0x85,0xa4,0x4,0x60,0x70,0x6a,0x73,0x9c,0xa2,0xcc,0x33,0x24,0xab,0xbb,0x14,0xee,0x92,0x24,0x30,0xba,0x66,0xb5,0xf8,0xa0,0x0,0xcf,0xd4,0xa4,0xbf,0xd5,0x5e,0x97,0x9e,0xa5,0xe2,0x1b,0xb7,0x89,0xe0,0x9f,0x6b,0x7a,0x2a,0x39,0x38,0x53,0xb5,0x3,0x4e,0x5b,0x7f,0x37,0x8a,0xc3,0x37,0x7c,0xfa,0xbb,0xe3,0xa4,0x73,0xf,0xfa,0xd5,0xc9,0xb3,0x24,0xa3,0xf7,0xe3,0x9c,0xb5,0x16,0x9a,0x1,0x71,0xe7,0x24,0x94,0x8a,0x20,0xa3,0x28,0x24,0x98,0x4f,0x4,0x91,0x18,0x6c,0x74,0xd6,0xc1,0x6a,0x4d,0x1,0x23,0x2c,0x97,0x75,0xd6,0x20,0x4e,0x3a,0x6c,0x7d,0x40,0x29,0xb4,0x8,0xdf,0xa7,0x3a,0xfc,0x29,0x8a,0x12,0xf6,0x1e,0xac,0x99,0x59,0x5e,0xe,0x3c,0x5,0xd3,0xe1,0xef,0x2b,0x81,0xf8,0x88,0xc8,0x6e,0x41,0x46,0x11,0x84,0x52,0xc8,0x7,0x7d,0x74,0x66,0x66,0xc9,0x22,0xa1,0x22,0x6,0xda,0x8b,0x6f,0x1d,0x43,0x56,0x7c,0x1b,0xbf,0xfd,0x85,0x4f,0x62,0xdd,0xda,0xd5,0xbf,0x38,0x40,0xed,0xf0,0x31,0xfc,0xa7,0x3f,0xff,0x26,0xfa,0x79,0x49,0xc,0x7a,0x66,0x57,0x1a,0x5d,0x41,0x97,0x5,0xa4,0x52,0xc8,0xfa,0xcb,0x88,0x62,0xa,0x40,0xd2,0x55,0x49,0x9,0xc9,0x1f,0x32,0x33,0xeb,0xea,0xe2,0x12,0xbe,0xf3,0x83,0x9f,0xe0,0x3b,0x3f,0x3e,0x0,0xc3,0x63,0xb4,0x7,0x69,0x7d,0x78,0x8c,0xbf,0x77,0x92,0xf4,0xd7,0xc2,0x81,0x58,0xf1,0x69,0xa7,0x57,0x3f,0x57,0xf0,0xa4,0x17,0xdd,0x7b,0x48,0x2e,0x6c,0x35,0xa7,0x4b,0xab,0x28,0xbc,0x27,0xf8,0x3b,0x72,0x4a,0xbb,0xf,0x6a,0x71,0x74,0xe0,0x80,0x11,0x69,0xaa,0xbf,0x76,0x9b,0x60,0x56,0x18,0x83,0x87,0x8e,0xd5,0x78,0x18,0x53,0x4d,0xec,0x13,0x35,0x50,0x87,0x66,0xd2,0xb0,0x18,0x82,0xc8,0xc4,0x84,0x10,0x8e,0x51,0xb6,0x5e,0xd3,0x12,0x62,0x52,0x98,0x88,0x7,0xc,0x85,0x73,0x53,0x3,0x38,0xc2,0xd6,0xfe,0x42,0x4f,0xb5,0x9b,0xf6,0x95,0xa9,0x53,0x94,0xdb,0x6a,0xab,0xad,0xb6,0x9a,0xbd,0x46,0x7b,0x8,0xda,0x6a,0xab,0xad,0xb6,0xae,0x23,0x0,0xd0,0x3,0x1a,0xf0,0xe0,0x91,0x19,0x96,0x87,0x71,0x70,0x84,0x62,0xc6,0x5d,0x0,0xd0,0x4,0x82,0x29,0x3b,0x4,0x81,0x2a,0x37,0x6d,0xdd,0x80,0x1b,0xb7,0x6e,0x1a,0x5b,0x47,0x55,0x69,0x3c,0xfd,0xd2,0x5b,0xd4,0x28,0x70,0x12,0x6f,0x91,0xd,0x50,0x55,0x5,0x34,0x87,0x33,0xe8,0x92,0x2,0x30,0xbc,0xf9,0xb9,0xf7,0x43,0xaa,0x7d,0x7e,0xe8,0xe1,0xba,0x2a,0xb,0x3c,0xf3,0xc2,0xeb,0x13,0x1f,0x52,0x6f,0xbb,0x65,0xf,0x6e,0xda,0xba,0x1,0x52,0x2a,0x62,0xe3,0x69,0x1d,0x40,0xc6,0x38,0x49,0x59,0xc6,0x66,0xa6,0xf4,0xc3,0x92,0xa4,0x49,0x42,0xd4,0x9e,0x86,0x4a,0x41,0x97,0x5,0x74,0x45,0xd,0x4e,0xa7,0xd3,0x83,0xb3,0x16,0x45,0x96,0x31,0xc0,0x56,0xa0,0xc8,0x9,0x54,0x4a,0xd3,0x2e,0x94,0x8a,0x11,0xc5,0xc9,0xc4,0x34,0x4c,0xc1,0xc,0xe,0xd1,0x60,0x2f,0x58,0x6e,0x78,0xa3,0x28,0x86,0x10,0x82,0x8e,0x49,0x99,0xa3,0xcc,0x73,0x4a,0xda,0x64,0xf0,0xca,0x5a,0xb,0x25,0x23,0x9c,0x3c,0x73,0x1,0x76,0x2,0xb8,0x78,0xc7,0x2d,0x3b,0xf8,0x78,0x1,0x49,0x92,0x86,0x66,0x42,0x4a,0x89,0xee,0xcc,0x3c,0x35,0xcb,0xcc,0xfe,0x2b,0xf3,0xc,0x2a,0x8a,0x11,0xc5,0x31,0x92,0xe,0x5,0xa7,0x94,0x65,0x81,0xbb,0x6f,0xdb,0x39,0x96,0xae,0xb,0x0,0x27,0x4e,0x9d,0x25,0x50,0x94,0xbd,0xff,0x28,0x91,0xd2,0x71,0x28,0x48,0x89,0xa2,0xc8,0x61,0x8c,0xc1,0x8b,0xaf,0x1d,0x1c,0xfb,0x6c,0x9a,0x24,0x58,0x35,0x3f,0x3b,0xf6,0xfa,0xa1,0x23,0xc7,0x71,0xf6,0xc2,0x42,0xf0,0xe3,0x33,0xd,0xe9,0xf5,0xb3,0x2f,0xbe,0x31,0xb6,0x8f,0x69,0x9a,0x62,0xf5,0xaa,0x71,0xf6,0xdf,0xd1,0xe3,0x27,0x71,0xec,0xcc,0x45,0x18,0xa3,0x89,0x95,0xc2,0x92,0x5f,0x1,0x3a,0x37,0x3e,0x6c,0x45,0xeb,0xa,0x55,0x55,0x86,0x9f,0x95,0x54,0x30,0xa6,0x82,0x83,0x43,0x99,0x67,0xe1,0xd8,0x90,0xd9,0xbe,0xb,0xdf,0x7,0x9f,0x8e,0xea,0xbf,0xb,0x96,0x9b,0x3f,0xf,0xde,0x36,0x9b,0xc2,0x26,0xf8,0x57,0x5f,0x9b,0x62,0x88,0x64,0xd1,0x36,0x56,0x6d,0x7d,0x94,0xe5,0x27,0x21,0xea,0xa4,0x4f,0xc7,0x41,0x20,0x66,0x8,0xac,0xa1,0x7f,0x87,0x20,0xe,0x6,0xcf,0x7d,0x12,0xab,0x8,0x60,0xa0,0x75,0x1c,0xfe,0x21,0xd0,0x8,0x51,0x1a,0x1f,0x5b,0x3d,0x58,0x6e,0x58,0x6a,0x3c,0x58,0x59,0xa,0x81,0x42,0x34,0xc1,0x52,0x40,0xa9,0x18,0x80,0xe0,0x60,0xd,0x15,0x24,0xf9,0x2a,0x8a,0x59,0x86,0x2c,0x38,0xc5,0x57,0x84,0xfb,0x94,0x90,0x6a,0x22,0x2e,0xe6,0x9c,0x9f,0xdc,0x22,0x0,0x4d,0x57,0x15,0xa2,0x38,0x41,0x7f,0x79,0x11,0xba,0x2c,0x3,0xe8,0x49,0x21,0x4f,0x9a,0xd9,0xc2,0x15,0x5e,0x3b,0x74,0x14,0xff,0xfb,0x7f,0xfa,0x7f,0xb1,0xff,0x8d,0x43,0x28,0xcb,0x9f,0x2f,0x60,0x7f,0x75,0x71,0x9,0x5f,0xf9,0xeb,0xef,0xe2,0xdf,0xfd,0xc1,0x57,0xb1,0x92,0xd1,0x58,0xc,0x0,0x65,0x99,0x87,0xfb,0x9d,0x60,0x2f,0x40,0x21,0x24,0x8a,0x6c,0x85,0x24,0xc1,0x9c,0x38,0x6f,0xad,0xf9,0xc5,0x3f,0xf,0x38,0x87,0x85,0x85,0x2b,0xf8,0xda,0x37,0xbe,0x87,0x7f,0xf3,0x6f,0xff,0x23,0xbe,0xf5,0xdc,0x7e,0xa,0x4d,0xa9,0x2a,0xc0,0x81,0xbc,0x75,0x15,0x85,0xc6,0x68,0xbe,0x3f,0x79,0xcf,0x38,0xe7,0x1c,0xaa,0x22,0x27,0x69,0xaf,0x8a,0x10,0x27,0x9,0x92,0xa4,0x83,0x48,0x91,0xb4,0xd7,0x5a,0x4d,0xc9,0xc9,0x1e,0xa8,0xb3,0x3e,0x41,0xdd,0x31,0xc8,0x46,0x56,0xb,0x76,0x24,0xad,0xba,0x4e,0x98,0xae,0xaf,0xdd,0x71,0xb9,0x6a,0xf3,0x77,0x87,0xe6,0xc0,0xdb,0xf4,0xe3,0xf3,0x21,0x19,0x2,0x23,0x44,0x37,0x31,0xa4,0xe4,0x1d,0xa,0xdd,0x70,0x6e,0x38,0xc5,0xb8,0x71,0x61,0x4f,0x64,0x7e,0xf,0x49,0x79,0x27,0x1c,0xdf,0x9f,0xdf,0x5d,0xc0,0xbd,0xcf,0x6b,0x4d,0xf,0xc4,0xa6,0x54,0x5e,0x34,0x8c,0x2,0xeb,0xd7,0x3,0xf0,0xd8,0xde,0xa7,0xda,0x6a,0xab,0xad,0x91,0x6a,0x19,0x80,0x6d,0xb5,0xd5,0x56,0x5b,0xd7,0x53,0x89,0x61,0x90,0xca,0x3f,0x5,0x7a,0xf,0x19,0x15,0x25,0x1,0x8,0xd1,0x15,0x19,0xc1,0x3,0xd4,0xec,0x49,0x21,0xfd,0xbc,0x3b,0xe2,0x24,0xc5,0xa7,0x1f,0xdd,0x37,0xd1,0x47,0xee,0xd8,0x89,0xd3,0x38,0x7e,0xfa,0x2,0xb3,0xdf,0x2c,0x2a,0x5d,0x35,0x24,0xb7,0xd4,0x4c,0x56,0x65,0x4e,0x4d,0x4f,0x9e,0x5,0xc6,0x48,0x91,0xd,0x20,0x84,0x40,0xd2,0xe9,0xa2,0xcc,0x33,0x58,0x6b,0xd0,0xed,0xcd,0xe2,0xd5,0x83,0x47,0xf1,0x99,0x33,0xe7,0xb0,0x6d,0xeb,0xe6,0xa1,0xf5,0x24,0x49,0x8c,0x4f,0x3c,0x78,0x27,0xde,0x39,0x7e,0x6,0xba,0xb2,0x70,0x8e,0x0,0x26,0x29,0x5,0xa4,0x8c,0xd8,0xb7,0x4f,0x4c,0x69,0x7c,0x8,0x68,0x73,0xa0,0x94,0x5c,0xa3,0x2b,0x2,0xbd,0xf2,0xc,0x4a,0x29,0xe4,0xba,0x42,0x9e,0xd,0x0,0x38,0x74,0x67,0xe6,0x60,0xb4,0x46,0xda,0x9d,0x41,0xda,0xe9,0x86,0x4,0x5e,0xc9,0xb2,0xd3,0x49,0x40,0x8f,0x6f,0x92,0x74,0x59,0x40,0xc5,0x31,0x1,0x50,0xd6,0x6,0x8f,0xaa,0x62,0xd0,0x87,0xb1,0x6,0x55,0x91,0x23,0x4e,0xbb,0xc4,0x3c,0x94,0x92,0x64,0xd7,0xd6,0xa0,0xaa,0x4a,0xbc,0x73,0xe2,0x1c,0x96,0x96,0x97,0xb1,0x7a,0x44,0x62,0xbd,0x7b,0xd7,0xe,0xec,0xda,0xba,0x11,0xa7,0x2f,0x2d,0xb1,0xe4,0x99,0xce,0x8b,0x35,0xc4,0x2a,0xc9,0x7,0x2b,0x1,0xb8,0xf5,0x8c,0xcd,0x22,0xcf,0xd1,0xe9,0xf6,0x20,0x95,0xc2,0xdc,0x4c,0xf,0xf7,0xdf,0x73,0xc7,0xd8,0x36,0x97,0x65,0x85,0x37,0xde,0x39,0x8e,0x4e,0x77,0x6,0xd9,0x60,0x5,0x49,0xda,0x41,0x91,0x67,0x70,0xae,0xc,0x69,0x8e,0x71,0x9c,0xa0,0x2c,0x72,0x3c,0xf7,0xea,0x21,0x3c,0xfe,0xf0,0x3d,0x98,0x9d,0x99,0xb9,0xe6,0xe5,0x56,0x69,0x83,0x67,0x5e,0x38,0x50,0x83,0x6f,0x71,0x42,0xbe,0x51,0x92,0x12,0xa6,0xdf,0x38,0x7a,0x16,0x17,0x17,0x2e,0x63,0xe3,0x86,0x75,0xef,0xb,0x66,0x3c,0xfd,0xdc,0x8b,0x18,0xf4,0x57,0xc8,0xe0,0x9e,0xc1,0x8d,0x32,0xcf,0x21,0x24,0x25,0x20,0x67,0x5,0x85,0xa3,0x90,0x34,0xcd,0xa1,0xc8,0x48,0x2,0x4e,0x52,0xc4,0x8,0x51,0x44,0x40,0xaf,0x61,0x89,0x63,0x55,0x50,0x38,0x88,0x68,0x7a,0xfe,0x89,0x9a,0x75,0xe4,0x8f,0x6b,0xfd,0x5d,0x71,0x8d,0x66,0x55,0xc,0x49,0xe1,0x43,0xe3,0x25,0xea,0xa6,0xcf,0xfb,0xa8,0xb5,0xd5,0xd6,0x87,0x5d,0xc3,0x6c,0x29,0x9f,0xae,0xea,0x20,0x5,0x27,0xa7,0x33,0x0,0x28,0x5,0x81,0xe0,0xc4,0xfe,0xa6,0x9,0xa0,0x66,0x1a,0x2b,0x7c,0x70,0x88,0x31,0x21,0xb0,0xc8,0x9,0x1b,0x52,0x60,0x27,0xae,0xdb,0x72,0x88,0x92,0xae,0xc2,0xe4,0x41,0x9c,0x24,0x30,0x5a,0xa0,0x2a,0x72,0x62,0x3b,0xa7,0x5d,0x18,0xab,0x11,0x47,0x9d,0x30,0xf9,0xe2,0x93,0x6c,0x5,0x40,0x16,0x4,0x65,0x89,0xb4,0xd3,0x25,0x8f,0x4e,0x9e,0x7c,0x22,0x0,0x6a,0xf2,0x7a,0x43,0x80,0xf,0x7b,0x77,0x16,0x59,0x86,0x6e,0x77,0x6,0xd6,0xd2,0x44,0x80,0x28,0x29,0x30,0xc9,0x83,0xf9,0x7e,0xdc,0xbe,0x70,0x65,0x9,0xff,0xfe,0x8f,0xbf,0x8e,0x5d,0x5b,0xd6,0xe1,0xd7,0x3e,0xf3,0x71,0xec,0xda,0xb9,0x1d,0x33,0xbd,0xde,0xcf,0x78,0xdc,0x81,0x8b,0xb,0x97,0xf1,0xe2,0xab,0x6f,0xe2,0x7,0x3f,0x79,0xd,0x57,0x57,0x32,0x40,0x0,0xba,0x18,0xd0,0x78,0xc8,0x13,0x17,0x52,0x12,0xf3,0xad,0xc8,0x6,0xc1,0xcf,0x95,0xac,0x38,0x14,0xe2,0x24,0x21,0x0,0xf6,0x17,0x4,0xcc,0x68,0xad,0xb1,0xd2,0x1f,0xe0,0xdd,0x63,0x27,0xb1,0xff,0xcd,0xc3,0x78,0xed,0xd0,0x71,0x2c,0xf7,0x7,0x34,0xbe,0x79,0x30,0x98,0x81,0x21,0xc9,0xc9,0xf4,0x1e,0xf4,0xca,0x79,0x7b,0x4b,0x1e,0x6b,0x5,0xdf,0xb3,0x8c,0xd1,0x48,0xe3,0x2e,0x4d,0xa8,0xf0,0x33,0x81,0xb3,0x16,0x4e,0xd6,0x93,0x79,0x42,0x48,0xbe,0xee,0xea,0xb1,0x72,0x68,0x8c,0xf4,0x20,0x21,0x8f,0x9f,0x92,0x3d,0x8a,0x87,0xa0,0x2d,0xf,0x1e,0x4a,0x39,0xcc,0xfc,0x13,0x3e,0xcc,0x49,0x84,0x6b,0x59,0x34,0x80,0x3a,0x37,0x2,0xda,0x89,0xc6,0xf9,0x42,0x3,0x3e,0xac,0xdf,0x57,0xfb,0x4,0xd6,0x87,0x63,0x9c,0xe5,0x37,0x19,0x9a,0x7b,0xbf,0x10,0x92,0x49,0x20,0x9e,0xf8,0x0,0x7f,0xe7,0x2d,0x71,0xbc,0xbf,0x23,0x4e,0x83,0x93,0x17,0xc7,0xbf,0x88,0xc6,0x56,0xba,0x1a,0xfd,0x6b,0xa1,0xbf,0xb6,0xda,0x6a,0xab,0x5,0x0,0xdb,0x6a,0xab,0xad,0xb6,0xfe,0x1e,0x20,0x80,0x42,0x8,0x58,0x3f,0xdb,0xcd,0xd2,0x5c,0x48,0xc9,0x49,0x89,0x34,0x9b,0xef,0x8c,0xa1,0x14,0x48,0xfe,0xd7,0x71,0x73,0x90,0xc4,0x1d,0x4a,0x3e,0xec,0x25,0xb8,0x75,0xcf,0xce,0x9,0x40,0x8d,0xc3,0xb3,0x2f,0xbe,0xce,0x9e,0x74,0x49,0x68,0x42,0x8d,0xae,0x40,0x6c,0x12,0x6a,0x28,0xca,0x22,0x67,0x19,0x6e,0x89,0xb2,0x2c,0x18,0x5c,0x31,0xe8,0xf4,0x66,0x43,0xca,0x60,0x84,0x84,0xe4,0x67,0x52,0xe2,0x85,0xd7,0xde,0x1e,0x3,0x0,0x1,0xe0,0xce,0xdb,0xf6,0x60,0xcd,0xec,0xf,0x71,0x51,0x57,0x30,0xda,0x6,0xe9,0x6a,0x55,0x64,0x0,0x3a,0x98,0xaa,0xad,0x61,0xb9,0x9b,0x7f,0x22,0x56,0x2a,0x86,0x54,0xc4,0x42,0x59,0x59,0xbc,0x82,0x28,0x4e,0x98,0xf5,0x52,0x7,0x6e,0x94,0xc5,0x0,0x52,0x91,0xc,0xce,0x1a,0x8d,0x28,0xea,0xb0,0x99,0xfb,0xf4,0xe5,0x53,0xa8,0x44,0xc4,0xac,0x19,0x11,0xc0,0x4e,0x19,0x45,0xc8,0x97,0xfb,0x88,0x92,0x14,0xce,0x52,0x40,0x47,0x59,0xe4,0x0,0x44,0x0,0xed,0x6,0x79,0x89,0x77,0x8e,0x1c,0xc3,0xc7,0xee,0xbf,0x67,0x68,0xd1,0x69,0x92,0xe0,0x37,0x3f,0xf7,0x38,0x7e,0xff,0x4f,0xbf,0x11,0x24,0xbe,0x2,0x40,0xa9,0x73,0x54,0x65,0x8e,0xee,0xec,0x3c,0x2a,0xe,0x2b,0x81,0x73,0x48,0x3a,0x1d,0x96,0x15,0x53,0xd3,0xf4,0xb9,0x4f,0x3e,0x30,0x51,0xf2,0xb6,0x70,0x65,0x11,0x27,0xce,0x2f,0x42,0x48,0x49,0xdb,0xc0,0x60,0x97,0xf7,0x7f,0x22,0xe9,0x77,0x84,0x22,0x1f,0xe0,0xf2,0x55,0x81,0xd7,0xf,0x1e,0xc5,0x23,0xf,0xdc,0x75,0xcd,0xab,0xed,0xec,0xb9,0xf3,0x78,0xfb,0xe8,0x29,0x58,0x8,0x24,0x69,0x87,0xae,0x3,0x21,0x0,0xf6,0x1f,0xcb,0xb2,0xa,0xaf,0xbe,0x7e,0x8,0x9f,0x7d,0xe2,0xd1,0x6b,0x2e,0xe7,0xe2,0xc2,0x65,0xbc,0xf8,0xc6,0xbb,0x0,0x5f,0x3f,0x41,0x2a,0x98,0x24,0x81,0x59,0x63,0x8c,0xe,0x4c,0xc5,0xb2,0xc8,0x51,0x55,0x25,0x7a,0xec,0x39,0x16,0x45,0x31,0x54,0x1c,0x93,0xdf,0x23,0x87,0x1f,0x78,0xd0,0x55,0x30,0x28,0xed,0x97,0xe1,0x82,0xd4,0xad,0xf6,0xe9,0x72,0xec,0x97,0xe9,0x65,0x93,0x42,0x0,0x3e,0x27,0xa7,0xc9,0x34,0x69,0x26,0x69,0xa3,0x21,0x9b,0x6b,0xab,0xad,0xf,0x75,0x94,0x6f,0xca,0x27,0x3,0x93,0x95,0xb0,0x0,0xc9,0x72,0x79,0x81,0x3a,0x7c,0x21,0x8a,0xa2,0x0,0xa,0x7a,0x3e,0x93,0x2e,0x29,0x4d,0xdc,0x3a,0x4a,0x72,0xa5,0x40,0x7,0xba,0x47,0x40,0x8,0x9c,0xbb,0x70,0x9,0xc7,0xde,0x3b,0xc9,0xdf,0x11,0x1,0xcf,0x16,0x3c,0x73,0xfe,0x12,0xb3,0xf0,0x4a,0x1a,0x7,0x8d,0x46,0x99,0x67,0xe8,0x2f,0x5d,0xc5,0xec,0xaa,0x35,0xc1,0xf2,0x61,0x66,0x7e,0xd,0xb1,0x2,0x11,0xd5,0x2c,0x2f,0xe,0x9e,0xf2,0x61,0x46,0x7e,0xbc,0x90,0x52,0x41,0x0,0xc8,0xf2,0x2,0x27,0x4e,0x9d,0xd,0xb6,0x13,0x1e,0x58,0xca,0xb2,0xc,0x83,0xc1,0x80,0x96,0xc7,0x6c,0x6d,0xf,0xd2,0x94,0x45,0x8e,0x4e,0x77,0x96,0x19,0x80,0x39,0x7a,0xb3,0xf3,0x28,0xf3,0x8c,0xc0,0x2b,0x96,0x3b,0x5b,0x6b,0xf1,0xce,0x7b,0xe7,0xf0,0xbf,0xfe,0x87,0x2f,0x61,0xfd,0x7c,0x7,0xf7,0xdf,0x7d,0x2b,0xee,0xb8,0xf5,0x66,0x6c,0xdb,0xb6,0x5,0x33,0xbd,0x2e,0xb3,0x14,0x47,0xee,0x9d,0xce,0xa1,0xaa,0x34,0xb2,0x3c,0xc7,0xe5,0xab,0x4b,0x38,0x72,0xf4,0x4,0xde,0x3c,0xfc,0x1e,0xe,0xbf,0x77,0x96,0xfd,0xfc,0xf8,0x98,0xb1,0xaf,0xa1,0x1f,0x4b,0x1,0x7,0x5d,0x15,0x1c,0xbc,0xa2,0x98,0x19,0x9d,0x31,0xc0,0xb6,0x2,0x21,0xe7,0x20,0xa5,0xc4,0x95,0xc5,0x25,0x1c,0x3f,0x71,0x2a,0x78,0x93,0xe,0x3,0xbb,0x22,0x30,0x31,0xe1,0x6c,0x23,0x4,0x82,0x2,0x39,0x2c,0x33,0x2f,0xb5,0x36,0x28,0xab,0xa,0xfd,0xfe,0x0,0x2b,0xfd,0xc,0xc7,0x4f,0x9e,0xc3,0x99,0x8b,0x97,0x71,0xfa,0xfc,0x25,0x64,0x5,0xdd,0x9f,0x2,0xb,0x8f,0x1,0x34,0x7f,0xbf,0xa6,0xcb,0x86,0xef,0x1,0x92,0x6c,0x31,0xa4,0x94,0x28,0xf9,0x73,0xba,0x2a,0x31,0x58,0x59,0xe,0xf7,0x44,0x38,0x20,0x4e,0x3a,0x3c,0x9e,0x4a,0x8,0xa9,0x82,0x7d,0x82,0x54,0x22,0xb0,0xdb,0x83,0xff,0x30,0xfc,0x30,0xd9,0x90,0xf1,0x86,0x70,0xd,0xb6,0x5f,0x8,0x32,0x75,0xba,0x2e,0x44,0x23,0x65,0x7d,0xf8,0xa9,0xa6,0x91,0xb2,0x31,0x21,0xc0,0x63,0xc8,0xa7,0x6f,0x4a,0x48,0x88,0x1b,0x2,0xf7,0x86,0xc1,0xbf,0x9f,0xe,0xc4,0x9b,0x12,0x30,0x32,0xf4,0x9e,0xf,0x2,0xfa,0xa1,0x1,0xf6,0xa1,0x1,0xfe,0x35,0x90,0x4b,0x51,0x83,0x79,0x1,0x14,0x6c,0x9a,0xa,0x86,0x63,0x72,0x8d,0x47,0xa1,0x96,0x1,0xd8,0x56,0x5b,0x6d,0xb5,0x0,0x60,0x5b,0x6d,0xb5,0xd5,0xd6,0xf5,0x5b,0x52,0xd6,0x32,0x45,0x29,0xa3,0xe0,0x13,0x57,0x6b,0x61,0x4,0x49,0x50,0x55,0x1d,0xdc,0xa1,0x39,0x64,0x83,0xf3,0x76,0x1,0xe7,0xf0,0xa9,0x87,0xef,0x9a,0x68,0x9e,0x7e,0xe1,0xd2,0x2,0xe,0x1c,0x3e,0x9,0xc5,0x32,0x57,0x63,0xc,0xe0,0x48,0x52,0x96,0xa4,0x9d,0x90,0xa2,0xeb,0x1b,0x19,0x6a,0x92,0x28,0xc1,0x35,0x4e,0x52,0x92,0x14,0x45,0x11,0xe2,0xb4,0xcb,0xd2,0x4b,0xd,0x6b,0x14,0x9e,0x7b,0xf5,0x1d,0x3c,0xf1,0xd8,0x3,0x58,0x3d,0x12,0xc,0x31,0x3b,0x3b,0x83,0x4f,0x3d,0x7c,0x2f,0xbe,0xfc,0xcd,0x67,0xc9,0xa3,0x30,0x4d,0x29,0x11,0x56,0x51,0x70,0x89,0x9d,0xf2,0x6c,0x2b,0xa4,0xaa,0x1b,0x28,0x8,0x96,0x3,0xcb,0x0,0xa,0x16,0x59,0x1f,0x45,0x9e,0x61,0x6e,0xd5,0x5a,0x68,0x5d,0x21,0xee,0xa5,0x88,0xa2,0x24,0x30,0x21,0xc9,0xc7,0x2a,0x21,0x90,0x73,0xca,0xe3,0x7b,0x14,0x27,0xe4,0xc5,0x67,0x98,0x11,0xc3,0x8d,0x73,0x3e,0xe8,0xa3,0x2a,0xa,0xcc,0xcc,0xaf,0x26,0xd6,0x23,0x33,0x42,0x92,0x4e,0x97,0x18,0x33,0x1c,0xb8,0x21,0xa5,0xc4,0x77,0x9e,0x79,0x9,0xf7,0xde,0x7d,0x3b,0x92,0x78,0xd8,0xaf,0xef,0xb6,0x9b,0x77,0xe2,0xd7,0x3e,0xf5,0x0,0xfe,0xfa,0x99,0xfd,0x10,0x52,0x22,0x1f,0xac,0x30,0xa0,0xa5,0x90,0xad,0x2c,0x5,0x60,0xd1,0x37,0xec,0x42,0xc4,0x0,0x2c,0x1e,0xbe,0x6b,0xf,0x1e,0x7f,0xe4,0xbe,0x31,0x7f,0x3d,0xe7,0x1c,0x7e,0xf4,0xe2,0x6b,0x30,0x96,0x8c,0xd9,0xa3,0x28,0x41,0x55,0xe6,0x90,0x42,0x42,0xeb,0x92,0x98,0x8c,0x2a,0xc2,0xf2,0xe2,0x2,0xe6,0x56,0xad,0x83,0x31,0x1a,0xdf,0x7d,0xf6,0x25,0xdc,0x7f,0xcf,0x5e,0x24,0x71,0x34,0xb5,0xb1,0x78,0xfa,0xb9,0x97,0x90,0x17,0x5,0xb1,0xe9,0xb8,0xb1,0x8b,0x3d,0xa0,0xcc,0x21,0x1,0xcf,0xbe,0xfc,0x16,0x3e,0xf1,0xf0,0xbe,0xb1,0xf0,0x90,0x66,0xfd,0xf8,0x85,0x57,0xb1,0xb4,0xbc,0xdc,0x8,0xb,0xa0,0x80,0x0,0x1,0x90,0x74,0x9b,0x59,0x2a,0x1e,0xd0,0xd0,0xec,0x53,0xe5,0xc3,0x50,0x62,0x96,0x4a,0xb,0x96,0x98,0x47,0x51,0xcc,0x3d,0x92,0x85,0x31,0x76,0x8,0x38,0x11,0xec,0x51,0xe9,0xc1,0x42,0x6b,0xd,0xfb,0x56,0xda,0xb0,0x1f,0x68,0xf4,0x65,0xce,0x37,0xa7,0x81,0xfd,0xe7,0xea,0xc6,0xb6,0x1d,0x72,0xda,0xfa,0x8,0xca,0x79,0xb6,0x6a,0x30,0xf9,0xf7,0x12,0x60,0x96,0x3,0x3b,0x4a,0x59,0x6d,0x6,0x2b,0x78,0x70,0x26,0x78,0x9e,0x29,0x15,0xd8,0x72,0x96,0xbf,0x2b,0x94,0xe2,0x4a,0x0,0xd0,0x1f,0x7d,0xe5,0xdb,0x61,0x2,0x24,0x58,0x48,0x70,0x28,0x8f,0x94,0xa,0x42,0x29,0x94,0x2b,0x79,0x0,0xd9,0xba,0xb3,0x4,0xc6,0x77,0x7a,0xb3,0x35,0xb,0x8e,0x53,0xba,0xa3,0x38,0x85,0x65,0xe6,0xa0,0x52,0x11,0xac,0x73,0xb0,0xae,0x82,0x33,0xb5,0x5f,0xa7,0x35,0x1a,0x27,0xcf,0x1b,0xfc,0x9b,0xff,0xed,0x3f,0x87,0x60,0x89,0x20,0xc7,0x87,0xb,0x21,0x56,0x2a,0x8a,0x38,0x45,0x9d,0xc2,0x7e,0x8,0x58,0xeb,0xa3,0x37,0x4b,0x4c,0xea,0xaa,0xc8,0xc9,0x8b,0x94,0x99,0xc0,0x10,0x2,0x96,0x27,0x38,0xca,0x22,0xc7,0xb1,0x53,0x57,0x71,0xfc,0xf4,0x79,0x7c,0xe9,0xeb,0x4f,0x61,0xa6,0xd7,0xc3,0xfa,0x35,0xf3,0x58,0xbf,0x76,0xd,0xe6,0xe6,0x66,0xd0,0xed,0xf6,0x20,0xa3,0x4,0xfd,0x7e,0x1f,0xda,0x58,0x2c,0xae,0xc,0x70,0x79,0x69,0x80,0xb2,0xac,0xc2,0x98,0xa1,0xf9,0x7e,0x26,0x1c,0x5,0x5b,0xf9,0xe3,0x59,0x55,0x25,0xb1,0x90,0x1b,0xe3,0x83,0x67,0xc0,0x1b,0xa3,0x19,0x30,0x45,0x60,0x8a,0xff,0xe4,0xb5,0x43,0x78,0xe5,0xd0,0x9,0x28,0x15,0x43,0x8,0xd0,0xc4,0x1c,0x98,0x8d,0x2f,0x25,0xb2,0xc1,0xa,0x8c,0xd1,0xc8,0x56,0x96,0x61,0x79,0xac,0x57,0x4a,0x1,0xe,0x48,0x7b,0x3d,0x44,0x51,0x8c,0x28,0x4e,0x1b,0xa0,0x57,0x3d,0x19,0xe5,0x13,0xe1,0x1,0xc1,0xe7,0x8b,0x0,0x3b,0x6b,0xc,0x6f,0xbf,0x82,0x73,0x26,0x78,0xab,0x6a,0x96,0xfa,0x1a,0xa3,0x51,0xe4,0x64,0xdd,0x51,0x55,0x25,0xbd,0x47,0x46,0x88,0xe3,0x34,0x8c,0xcb,0x94,0xc4,0xae,0x86,0x80,0xe8,0x70,0x3d,0x42,0x4,0xe6,0x60,0xb0,0x5a,0xb0,0x6e,0x48,0xb6,0x2b,0x1a,0x1,0x28,0xce,0x99,0x1a,0x4,0xe3,0x49,0xb4,0x20,0xd5,0xd,0x63,0xf6,0xb8,0x17,0xab,0x68,0x4,0x77,0x60,0x4,0xfb,0xaa,0x65,0xc3,0xef,0xcf,0xd2,0x73,0xef,0xff,0x45,0xb,0xfe,0x9a,0x53,0x90,0x78,0xc,0x49,0x71,0xa7,0xae,0x77,0xc8,0x3b,0xa2,0x6,0xf1,0x84,0x7,0xb9,0x31,0xc2,0xfc,0x43,0x3,0xe8,0xc4,0xb8,0x94,0x57,0x8c,0x24,0x8f,0xb8,0xd1,0x7d,0x72,0xed,0xe4,0x54,0x5b,0x6d,0xb5,0xd5,0x2,0x80,0x6d,0xb5,0xd5,0x56,0x5b,0x7f,0x3f,0x4a,0xc0,0x81,0x65,0x39,0xd6,0x30,0xc8,0x27,0xa9,0x51,0x51,0x11,0x3,0x83,0xc,0xfe,0x41,0xc0,0x9,0x70,0x30,0x6,0x35,0x52,0xba,0x2c,0xb1,0x6a,0x6e,0x16,0xf,0xdc,0x73,0xc7,0x44,0x10,0xe9,0x27,0x2f,0xbf,0xe,0x6d,0x1c,0x37,0x5f,0x12,0xd6,0x58,0x58,0x67,0x10,0x45,0x9,0xcb,0x49,0xa9,0xd9,0x2c,0xb2,0x1,0x1c,0xcb,0x34,0x25,0x27,0xd,0xe6,0x59,0x1f,0x69,0xa7,0x17,0x24,0x9b,0x65,0x91,0xa1,0x37,0x33,0x47,0xde,0x73,0xf9,0x0,0x3f,0x7e,0xf1,0x0,0x3e,0xf7,0xe4,0xc7,0xc7,0xf6,0xe8,0xa1,0xfb,0xef,0xc2,0xd7,0x9e,0x7a,0xe,0x25,0x88,0xb5,0x22,0x15,0x81,0x60,0x33,0x73,0xab,0xe1,0xac,0x9e,0xfc,0xdc,0xce,0xac,0x3b,0x6b,0x2d,0x83,0x8c,0x6,0x65,0x91,0x5,0x70,0xd2,0x39,0x47,0x89,0xbf,0xc6,0x70,0x53,0x45,0xb2,0x32,0x29,0x25,0x1,0x4f,0xdc,0x90,0x4d,0x7b,0x8e,0x16,0xd,0x80,0x28,0x48,0x8a,0x18,0xbc,0xf2,0xa9,0xba,0xd9,0xca,0x32,0x3a,0xbd,0x59,0xf2,0xab,0x8a,0x8,0x2c,0x4c,0xd2,0x6e,0x30,0xcc,0xb7,0xc6,0xe0,0xd4,0xc5,0x25,0xec,0x3f,0x70,0x10,0x1f,0xbb,0xff,0xee,0x11,0x20,0x57,0xe2,0xc9,0x4f,0x3c,0x88,0x34,0x91,0xf8,0xc6,0x33,0xaf,0xa1,0x94,0xa,0x45,0x3e,0x0,0x1c,0x1,0x8f,0x86,0x3d,0xb4,0x7c,0xe0,0x45,0x12,0x49,0xfc,0xf2,0x63,0xfb,0xf0,0xc4,0xc7,0x1f,0x40,0x9a,0x26,0x63,0xdb,0x7b,0xea,0xcc,0x39,0x3c,0xf3,0xf2,0xc1,0x9a,0x11,0xc3,0xfe,0x90,0x1,0x8,0x63,0xa3,0x7a,0xdf,0x5c,0x43,0x8,0x9c,0xbe,0xb4,0x88,0x23,0xef,0x1e,0xc7,0xed,0xb7,0xed,0x99,0x78,0x8c,0x17,0x2e,0x5f,0xc5,0xf,0x9f,0xdf,0x8f,0xb2,0xd0,0x48,0x92,0x94,0xf6,0xaf,0xd3,0x43,0x59,0x92,0x69,0xbc,0xd6,0x15,0x9c,0x73,0x38,0x7f,0xe9,0xa,0xe,0x1e,0x3a,0x82,0x7,0xf6,0x4d,0x66,0x13,0x2e,0x2d,0x2f,0xe3,0xe9,0x1f,0xbf,0x1c,0x42,0x3e,0x0,0x40,0x79,0xd0,0xc2,0x68,0x38,0x20,0x0,0xb7,0x9e,0xb1,0xe9,0x83,0x64,0x3c,0x30,0x98,0x76,0x7a,0x48,0xd2,0x4e,0x68,0xfa,0xa5,0x54,0x21,0x95,0x32,0xb0,0x6b,0xbc,0x14,0xd2,0xa1,0xe,0xc5,0x19,0x95,0x7a,0x35,0xa4,0x95,0xae,0xe1,0xde,0x3e,0x2a,0xf,0x73,0xd3,0xd2,0x2a,0xdb,0x6a,0xeb,0xc3,0x81,0x0,0xeb,0x70,0x3,0xaf,0x8e,0x94,0x12,0x56,0x6b,0x78,0xa6,0x9e,0x35,0x6,0x10,0x1e,0xd4,0xf6,0xf7,0x4,0x17,0x40,0xee,0x10,0xb8,0x21,0x5,0x7f,0x1f,0x1c,0xf2,0x1,0x85,0x55,0x8,0x6,0xef,0xb4,0xae,0x68,0x7c,0xe4,0xb1,0xa6,0x60,0x99,0xbf,0xd6,0x5,0x4c,0x55,0x51,0xda,0x70,0x3e,0x20,0x8f,0x4e,0x6,0xfa,0xaa,0xaa,0xc4,0x4c,0x67,0x15,0xb4,0x2e,0x91,0x24,0x1d,0xa8,0x28,0x66,0xa9,0xb1,0x83,0x50,0xcc,0x3a,0x13,0x4,0x10,0x3a,0x6,0x8c,0x0,0x62,0xa2,0x7b,0x4f,0xd9,0x28,0x49,0x51,0x95,0x5,0xba,0xbd,0x59,0xe4,0x83,0x3e,0x54,0x44,0x69,0xc1,0xa5,0x1d,0x20,0x1f,0xf4,0xc9,0x1f,0x35,0xed,0x62,0xe9,0xca,0x25,0xa8,0x28,0xe2,0xa4,0xf4,0x9c,0x58,0xc8,0x46,0xc3,0x95,0x80,0x14,0x2,0x85,0xcd,0x82,0x17,0x68,0x91,0xf,0xc2,0xd1,0x2b,0xf2,0x1,0xa4,0x54,0xb8,0x72,0xe5,0x32,0x56,0xfa,0x7d,0x9c,0xb9,0x78,0x5,0x69,0x77,0x6,0x71,0x9c,0x84,0xf1,0xdf,0x87,0xaa,0x34,0x3d,0x5e,0x29,0xbf,0xa9,0x66,0x4c,0x7b,0xf6,0xbc,0xb3,0x86,0xd3,0xe9,0x35,0x83,0x6e,0x15,0xb2,0xfe,0x32,0xe0,0x80,0xb2,0xe4,0x63,0xc5,0xf7,0x9,0x6b,0x2d,0x3a,0xbd,0xe,0x4d,0x60,0x19,0x13,0xb0,0x21,0x3f,0xde,0x78,0x3b,0x6,0xf0,0x39,0x52,0x4a,0xc1,0xe8,0xa,0x65,0x3e,0x40,0x77,0x66,0x8e,0x59,0xd1,0x39,0xa2,0xd9,0x24,0x2c,0x4f,0xb2,0x4f,0x6d,0x91,0xf5,0xf9,0xfe,0xc1,0xe3,0x5f,0x55,0xd1,0xa4,0x8f,0x53,0x50,0x8d,0x64,0x68,0xc3,0x4c,0x75,0x9f,0x5a,0x5f,0x16,0x59,0x98,0xc4,0xf2,0x13,0x24,0x34,0xe1,0xd6,0x85,0xd5,0x1a,0xb2,0xa3,0x28,0x1c,0x86,0x81,0x29,0x63,0x34,0xe2,0x24,0xe5,0x9,0x43,0xd4,0x1e,0x74,0x2,0x10,0x90,0x3c,0x99,0x88,0xa1,0x0,0x8d,0xa6,0x5f,0x65,0x48,0xd3,0x85,0x8,0x60,0xd6,0x28,0x7f,0xe,0x23,0x50,0x5a,0x13,0xf4,0x9b,0x14,0xce,0xd1,0x4c,0xe8,0x75,0x3f,0x6d,0xf4,0xed,0x34,0x26,0x9f,0x98,0xb2,0x65,0xe1,0x25,0x31,0x1,0xfc,0xf3,0x4c,0x3e,0xd7,0x44,0x31,0xeb,0xcf,0x87,0xb7,0x32,0x50,0x3f,0xc4,0x68,0x74,0x4d,0xaa,0xe2,0xb5,0x51,0x4a,0x31,0x61,0x73,0xc6,0xfe,0xde,0xde,0xa7,0xda,0x6a,0xab,0xad,0xf1,0x6a,0x43,0x40,0xda,0x6a,0xab,0xad,0xb6,0xae,0xa3,0xf2,0xbe,0x4c,0xc4,0xbc,0xb0,0x21,0xfb,0xae,0xc9,0xd0,0xf2,0x41,0x21,0x2e,0x30,0x46,0x6c,0x0,0x56,0xa4,0x52,0xd8,0xb7,0x77,0x27,0xd6,0xae,0x59,0x35,0xb6,0xec,0x7e,0x7f,0x80,0x97,0xdf,0x78,0x17,0x65,0x3e,0x8,0xf,0x95,0xd6,0x1a,0xf6,0x14,0xb4,0xc1,0xdf,0x4e,0x97,0x5,0xcb,0x61,0xc9,0x14,0xbc,0xc8,0x33,0xa,0x6,0xa9,0x2a,0xc,0x56,0x96,0xa0,0x35,0xfd,0x6b,0xb5,0x46,0x55,0x96,0xd4,0x2c,0x58,0x8b,0xbf,0x79,0xea,0x87,0x58,0x5e,0x5e,0x19,0x5b,0xef,0xda,0x35,0xab,0xf1,0xe8,0xdd,0x7b,0x42,0xb3,0x53,0x64,0x3,0x68,0x5d,0x31,0x20,0x66,0xa6,0x3e,0x1d,0x53,0x50,0x88,0x8,0x4d,0x7,0x25,0x5e,0x96,0x10,0x52,0x91,0x4c,0xc9,0x59,0x18,0x5d,0x42,0xc5,0x9,0x54,0x4c,0xde,0x88,0x94,0x86,0x4c,0xac,0x32,0x92,0x99,0xd9,0x31,0x20,0xd4,0x97,0x6e,0x80,0x52,0x7e,0xf9,0x65,0x91,0xd7,0x8d,0xac,0x35,0xc8,0xfa,0xcb,0x90,0x52,0xa2,0xd3,0x9b,0x65,0xe0,0xae,0x96,0x9d,0x42,0x8,0x54,0x55,0x85,0x2f,0x7f,0xe3,0x19,0x5c,0x5a,0xb8,0x32,0xb6,0x7c,0xa5,0x24,0x1e,0x7f,0xf4,0x41,0xfc,0xcf,0xbf,0xfb,0x45,0xfc,0xfa,0xa7,0x1f,0xc4,0xee,0x6d,0x9b,0x90,0xc4,0x11,0x9c,0x29,0x21,0x9c,0x43,0xb7,0x93,0xe2,0xc6,0x4d,0xeb,0xf1,0x85,0x4f,0xee,0xc3,0xff,0xf2,0x3f,0xfc,0x36,0x3e,0xff,0xe4,0xc7,0xd1,0xe9,0xa4,0x63,0xcb,0xc9,0xf2,0x2,0x5f,0xfd,0xe6,0xd3,0x28,0x35,0x79,0x22,0xfa,0xf0,0x0,0x29,0x25,0xd2,0x6e,0x2f,0x84,0xbe,0x34,0x9b,0xe4,0xaa,0xc8,0x90,0xd,0x56,0xf0,0xc3,0xe7,0x5f,0xb,0xa1,0x1e,0xa3,0x75,0xe0,0xcd,0xb7,0x91,0x95,0x6,0x65,0x9e,0x21,0xcf,0x7,0x64,0x6c,0xcf,0xa0,0x62,0x91,0xf,0x2,0x13,0xa5,0x2a,0xb,0x7c,0xf7,0x99,0x17,0xc2,0xf1,0x1a,0xad,0xfd,0xaf,0xbd,0x8e,0x77,0x4f,0x9c,0x46,0xb6,0xb2,0x1c,0x3c,0x14,0x7d,0x73,0xdc,0x64,0xad,0xe4,0x83,0x15,0x62,0xd4,0x58,0x8b,0xfe,0xf2,0x55,0x38,0x67,0x91,0x24,0x1d,0xf4,0x66,0xe6,0x9,0xc8,0x64,0xbf,0xaa,0x0,0xe0,0x79,0xc6,0x13,0x1c,0x4b,0x22,0x1b,0x4c,0x92,0xd0,0x94,0x5a,0x8f,0x18,0xf,0xf7,0x5c,0xcc,0xca,0x90,0x9c,0x1e,0xdc,0x94,0x41,0xd2,0xa9,0x93,0xc0,0x4f,0xdb,0x64,0xb6,0xd5,0xd6,0xcf,0xad,0x44,0x0,0xb0,0x9b,0x80,0xb6,0xe0,0x54,0x72,0xf0,0xf8,0xee,0xc1,0x1e,0x9f,0x4,0xef,0x19,0x79,0x4d,0x8f,0x54,0x9f,0xe6,0xb,0x38,0x62,0x90,0xc1,0x5,0xcf,0x54,0xc5,0xe9,0xf0,0x36,0x4c,0x16,0x8,0x94,0x7e,0xa2,0x87,0xfd,0x55,0xcb,0x22,0xb,0xcc,0x41,0xa3,0x4b,0x4e,0x28,0xd7,0x21,0xd,0x97,0x26,0x14,0x1a,0xf7,0x28,0x66,0x4c,0xeb,0xaa,0x8,0xf6,0xb,0x1e,0x8c,0xa,0xc1,0xb,0xc6,0x42,0x49,0xc5,0x8c,0x72,0xcb,0x81,0x56,0x14,0xfc,0xe1,0xb7,0x3f,0xeb,0x2f,0xb3,0x5d,0x83,0x9,0xd6,0xb,0x86,0x59,0x6c,0x4,0x48,0xd2,0xfd,0xc7,0x87,0x2f,0x79,0xc6,0xb6,0x7,0x47,0xf3,0xc1,0xa,0x8d,0x55,0x19,0x3,0x98,0xfc,0x39,0xa,0x17,0xd2,0x21,0x49,0x5e,0x57,0x15,0xac,0xd1,0x81,0x15,0x67,0x8d,0x9,0x13,0xf,0x46,0x6b,0x62,0xb5,0x5b,0x1b,0xde,0x53,0x16,0x3,0x96,0xd3,0x2a,0x6,0xd6,0x68,0x4c,0xd3,0x55,0x19,0x3c,0xf0,0x7c,0x80,0x96,0xb3,0x36,0x8c,0x4d,0x9a,0xa5,0xd3,0x21,0x38,0xab,0xa2,0xe0,0xa3,0xa2,0xc8,0x98,0x69,0x6e,0x90,0xd,0x56,0x50,0x16,0x19,0xa2,0x38,0xe,0x63,0x2b,0x31,0x36,0x5d,0x63,0x82,0x8b,0x7c,0x19,0xbd,0x2d,0x85,0x33,0xc4,0x6,0xd4,0x9a,0x82,0x3f,0xfc,0xf2,0x3d,0xf0,0xa7,0x75,0x45,0x63,0xad,0xa8,0xc7,0xb9,0xe0,0xdd,0xcb,0x81,0x61,0x92,0x99,0x7e,0x82,0xc1,0x45,0xa5,0xa2,0xc6,0x35,0xc7,0xd,0xa5,0xac,0xd9,0xd5,0x7e,0xe2,0x31,0x24,0xb0,0x8f,0xfa,0xf3,0x35,0xee,0xcb,0xde,0xba,0xc2,0x8f,0xbb,0xc1,0xd2,0xe,0xf5,0x58,0xdc,0x40,0x1,0xc7,0x5e,0x1f,0x5,0x6,0xdd,0x34,0xd4,0xcc,0x5d,0x23,0x50,0x43,0x4c,0x6,0xd9,0x87,0xc3,0x35,0x30,0x9c,0xbd,0x31,0xaa,0xbb,0x6d,0xb2,0xf4,0x46,0x25,0xb9,0x4d,0x3f,0x43,0x37,0x92,0xc,0x3c,0x34,0xb9,0x34,0xd,0xee,0x1f,0xd9,0xa3,0x91,0xc,0x93,0x9,0xf1,0x1f,0xb5,0x3d,0xa0,0x6c,0xef,0x53,0x6d,0xb5,0xd5,0xd6,0x70,0xb5,0xc,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xeb,0xaa,0x2f,0x14,0x43,0x4f,0x92,0x3e,0xc1,0xd6,0x9b,0x71,0x3b,0x6b,0xe8,0x81,0xdb,0x70,0x70,0x2,0x27,0xe4,0xea,0xaa,0xa4,0x19,0x7d,0x6b,0xf0,0xd8,0x43,0xf7,0x4e,0x4,0xbd,0xf6,0xbf,0xf1,0x36,0x2e,0x2d,0xf6,0xd9,0x40,0x9e,0x0,0x30,0xc3,0xc9,0x8f,0xce,0x18,0x54,0x55,0xc5,0x4a,0x1e,0x6a,0xaa,0x82,0xf4,0x49,0x53,0x3,0xa5,0xa2,0x38,0x0,0x33,0x3e,0xb8,0xae,0x64,0xf6,0x88,0x90,0x2,0x45,0x9e,0x60,0xff,0xeb,0x6f,0xe1,0x13,0x8f,0x7e,0x6c,0x64,0x97,0x4,0x3e,0xfd,0xf8,0xa3,0xf8,0xce,0x73,0xfb,0xa1,0xb5,0x86,0x63,0x40,0xd3,0x37,0x7a,0x93,0xca,0x3a,0x4b,0x20,0x14,0xcb,0xe1,0xaa,0x92,0x2,0x21,0x94,0x8e,0x50,0x15,0x39,0x81,0x5c,0x65,0x81,0x84,0x65,0xc9,0x71,0x9c,0x90,0x6c,0x18,0xe,0x69,0xb7,0x47,0xfb,0xcf,0xeb,0x98,0xe8,0x27,0xc4,0xc,0x4,0xeb,0x2c,0x4c,0xa5,0x21,0x55,0x84,0x22,0xa7,0x4,0xca,0xc1,0xca,0x52,0x0,0x3,0x57,0xad,0xdd,0x40,0x9e,0x55,0x5,0x79,0x52,0x25,0x69,0x37,0xc8,0xe0,0x1c,0x33,0x49,0xae,0x2c,0xb,0xfc,0xc9,0x57,0xbe,0x85,0xdf,0xfb,0x67,0xbf,0x31,0x51,0x26,0xbb,0x71,0xc3,0x7a,0x7c,0xee,0xc9,0xf5,0x78,0xf2,0x93,0xf,0x62,0x30,0xc8,0xc9,0x7f,0xa,0x40,0x27,0x4d,0xd1,0xed,0x76,0x10,0xc7,0xd3,0x6f,0xe5,0x5a,0x1b,0xfc,0xcd,0x77,0x9f,0xc3,0x5b,0x47,0xcf,0x86,0x64,0x4f,0x2f,0xb,0x97,0x52,0x5,0x46,0xf,0xdc,0xa,0xa4,0x90,0x88,0x3a,0x3d,0xc,0x56,0x96,0x10,0x27,0x29,0xa2,0x38,0xc1,0x2b,0x6f,0x1e,0xc1,0xb9,0xf3,0x97,0xb0,0x75,0xcb,0xc6,0xa1,0xe5,0xe6,0x79,0x8e,0xef,0x3c,0xfd,0x2,0xb2,0xfe,0x72,0x60,0x12,0x39,0x6b,0xa1,0x22,0x5,0xe1,0x24,0x83,0xa9,0x12,0x83,0x15,0x62,0x15,0xbe,0x71,0xe4,0x24,0x4e,0x9e,0x3e,0x8b,0x5d,0x3b,0xb6,0xf,0x2d,0xa7,0x28,0xa,0x7c,0xef,0x99,0x17,0x83,0x41,0xbd,0x33,0x8e,0xd3,0x9e,0x2d,0x6f,0x23,0x79,0x53,0x35,0x19,0x8f,0xfe,0x7a,0xf6,0x86,0xff,0x10,0x4,0xf6,0xfa,0x6b,0xcc,0x83,0x77,0xc4,0x20,0x24,0x19,0xb2,0x52,0x51,0x60,0xbd,0x34,0x41,0x61,0x0,0x41,0xaa,0x48,0x81,0x2b,0xaa,0x4e,0xe7,0xf4,0x1e,0x59,0xa2,0xf1,0x73,0xb8,0x0,0x2c,0x84,0x50,0x70,0xd0,0xed,0x98,0xd3,0xd6,0x47,0x52,0x5e,0xea,0x28,0xd0,0xf0,0x4c,0x73,0x2e,0x48,0xdf,0x7d,0xca,0xae,0xb3,0x60,0x7f,0xbf,0x68,0x24,0xb8,0xc6,0x85,0xa4,0x56,0x3f,0x9e,0x49,0xa9,0x20,0x9c,0x63,0xd6,0x99,0xe,0xc9,0xb0,0x52,0x89,0xc6,0x77,0x89,0x18,0xe4,0x4,0x82,0x11,0x0,0xe9,0xd9,0x65,0x51,0x1c,0xf,0xa5,0x75,0xfb,0x30,0x7,0x1f,0xf6,0x10,0xe4,0xa1,0xce,0x42,0x4a,0xf2,0x5a,0x35,0xc,0x8e,0x44,0x31,0xa5,0x6,0xb,0xb6,0x25,0x90,0xc1,0x1f,0x4e,0x4,0xff,0x42,0xef,0xfd,0x97,0x67,0x7d,0x6,0xc0,0x28,0xb5,0xbc,0xd3,0x9b,0x85,0x73,0x80,0xa9,0x2a,0xa4,0xdd,0x5e,0x48,0x34,0x96,0xfc,0x3d,0x97,0xec,0xd7,0x27,0x82,0xc7,0xa8,0x44,0x59,0x16,0x9c,0x94,0x4e,0x89,0xed,0x51,0x9c,0xc2,0x39,0x83,0xa8,0x2c,0x90,0x76,0x7b,0x43,0x0,0x93,0x4f,0x2d,0xa6,0xdb,0x9,0x4d,0x76,0x95,0x45,0x4e,0x93,0x4c,0x9c,0xf4,0xeb,0xc7,0x26,0xcd,0xe0,0x9e,0x67,0x9,0xc2,0xa1,0x66,0x2a,0x77,0x67,0x18,0x38,0xac,0xd0,0x9d,0x99,0xa3,0x63,0x16,0xc5,0xec,0x87,0x27,0x90,0xf,0x56,0x90,0x76,0x67,0xe0,0x18,0x24,0x95,0x6c,0x65,0x51,0x55,0x5,0xe2,0xa4,0x43,0xf7,0x2c,0xb6,0xda,0x0,0xa7,0x9b,0x47,0x71,0xcc,0xe3,0xa3,0xc,0xc,0x3f,0x29,0x64,0x38,0x56,0x2a,0x8a,0x51,0x55,0x45,0xf0,0xe8,0x13,0x52,0x4,0x20,0xd4,0x3,0x81,0x96,0x3d,0xff,0xaa,0xa2,0x8,0xe0,0xaf,0x67,0xfa,0xf5,0x66,0xe6,0xc3,0xf5,0xa1,0xa2,0x98,0x0,0x3d,0x66,0x9b,0xca,0x28,0xa,0x13,0x4a,0x7e,0x5c,0xf5,0xe7,0xcd,0x35,0x2,0x3c,0x1c,0xb3,0x14,0xad,0xf,0xf0,0x18,0x91,0xf4,0x8e,0x81,0xdb,0x18,0x61,0x5,0x4e,0xf4,0xf5,0xa3,0xbf,0x3a,0xe7,0xa6,0xd0,0xdf,0x86,0x96,0x80,0xe1,0x74,0x99,0x49,0xd2,0x5d,0x4f,0xc5,0xc4,0x30,0x28,0xe8,0x1a,0x60,0xa1,0x98,0xc,0xdc,0x35,0xe1,0x39,0xe7,0xae,0x31,0x35,0xe4,0x26,0xbf,0xd4,0xf4,0x30,0x9c,0xc4,0x7e,0x9c,0xf4,0x71,0xef,0xf1,0x3c,0xbe,0x2f,0xc3,0xb8,0xe5,0xb4,0x34,0xef,0xb6,0xda,0x6a,0xeb,0xef,0x6f,0xb5,0xc,0xc0,0xb6,0xda,0x6a,0xab,0xad,0xeb,0x9,0xff,0x63,0xd0,0x2f,0xc8,0x6f,0xb8,0x39,0xf4,0xfe,0x74,0x7e,0x46,0xde,0x83,0x1e,0x15,0x7,0x74,0x44,0xfc,0x60,0xbf,0x67,0xfb,0x46,0xec,0xd8,0xbe,0x6d,0x6c,0xb9,0x55,0xa5,0xf1,0xa3,0x97,0xde,0x8,0xd,0x6,0xb1,0x3c,0xaa,0xd0,0xa0,0x78,0x29,0x2d,0x35,0x14,0x1a,0x42,0x0,0x65,0x99,0x13,0x43,0xa1,0xaa,0x98,0x61,0x61,0x50,0xe4,0x19,0xaa,0xaa,0xc4,0xca,0xd2,0x15,0xc,0x96,0x17,0xd9,0x20,0x9d,0x7c,0x3,0xfb,0xcb,0x8b,0xf8,0xab,0x6f,0x3f,0x8d,0x2c,0xcf,0xc7,0xd6,0xbf,0x6d,0xcb,0x26,0xec,0xdb,0xbb,0x3b,0x34,0x93,0x94,0xec,0x4b,0xcc,0x89,0x89,0xc0,0x17,0x37,0x3f,0xc1,0xbb,0x8a,0x99,0x64,0x45,0x36,0xe0,0xe6,0x95,0xa4,0x6d,0x52,0x45,0x2c,0x25,0x65,0xa9,0x1b,0x4,0x8a,0x7c,0x40,0x7e,0x53,0xdc,0x98,0x4e,0x7b,0x98,0xd7,0xcc,0x6,0xf1,0x8c,0x19,0xc9,0xc,0x9b,0xb4,0xd3,0x85,0xd1,0x15,0x66,0xe7,0xd7,0x50,0x9a,0xa2,0xb5,0x64,0x2c,0xcf,0xd,0x90,0x10,0x82,0x3c,0xee,0x48,0x4f,0x86,0xaa,0xcc,0xb1,0xff,0xed,0xa3,0xf8,0x2f,0x7f,0xf6,0x75,0x5c,0x5d,0x5c,0x9a,0x7a,0x6e,0x93,0x38,0xc6,0xea,0x55,0x73,0xd8,0xb8,0x61,0x1d,0x6e,0xd8,0xb0,0xe,0xf3,0xf3,0xb3,0xef,0xb,0xfe,0xfd,0xf5,0x77,0x9e,0xc1,0xb7,0x9e,0x7e,0x29,0xb0,0x6e,0xc8,0x5f,0x4a,0x71,0x22,0x71,0x4,0xa9,0x24,0x85,0x6c,0xb0,0x5f,0x55,0x55,0x96,0x9c,0x32,0x4c,0xc7,0xb9,0x2c,0x4b,0x3c,0xfb,0xc2,0xab,0x63,0xcd,0xd7,0x91,0xa3,0xef,0xe1,0xbd,0x33,0x17,0x2,0xc8,0x9b,0xf5,0x97,0xa1,0x75,0x85,0xfe,0xd2,0x62,0x30,0xe3,0xcf,0x33,0x4a,0x9e,0x2c,0xf3,0x1c,0xba,0x2a,0xf1,0xed,0xa7,0x7e,0x30,0xb6,0x9c,0xa3,0xc7,0xdf,0xc3,0x5b,0xef,0x9e,0x64,0x16,0xc,0x25,0x45,0x53,0xc8,0x47,0x11,0x40,0x5a,0xef,0x43,0xd6,0x5f,0x5e,0x44,0x55,0x15,0x58,0xbe,0xba,0x10,0x98,0x3f,0x33,0x73,0xab,0xc3,0x75,0xa7,0x58,0xa2,0xe6,0xfd,0x7,0x29,0xfc,0xc5,0x7b,0x9e,0xb9,0xa1,0xef,0x3,0xd8,0xc8,0x9e,0xde,0x6f,0x3,0x98,0xe2,0x18,0xfc,0xf3,0xfe,0x7e,0x9e,0xd4,0xe1,0x46,0xa5,0x66,0x0,0x9c,0x6b,0xc1,0xbf,0xb6,0xfe,0xce,0xc0,0x81,0xd,0x50,0xb0,0x66,0x7,0x6,0xc0,0x25,0x0,0x71,0x3a,0x30,0xbe,0xfd,0x77,0xdc,0x35,0x2,0x17,0x3c,0xeb,0xab,0xaa,0xca,0xc0,0xe4,0x22,0xcf,0xcd,0x92,0xee,0x23,0x9a,0x24,0xa5,0xde,0x3a,0x80,0x7c,0xe7,0x14,0xb2,0xfe,0xa,0xcb,0x49,0xc9,0x6f,0x2e,0x8a,0x6a,0x4f,0x53,0xa9,0xea,0xb0,0x25,0x2f,0xcb,0xf7,0xe9,0xdd,0x60,0xd6,0x19,0x5,0x5b,0xd0,0xf2,0x8b,0x22,0x63,0xeb,0x6,0xfa,0x2e,0x1a,0x43,0x80,0x9a,0x1f,0xbb,0x29,0xa0,0x89,0x42,0x9c,0xb2,0x41,0x1f,0x52,0x51,0xea,0x7c,0x1d,0xb6,0x44,0x7e,0xa6,0x4a,0x45,0xcc,0x90,0xab,0x78,0xbb,0x44,0x48,0x24,0xa6,0xd0,0x8b,0x2c,0x30,0xfe,0xca,0x22,0x43,0x7f,0xf9,0x2a,0xf9,0xb7,0x56,0x5,0xf9,0xef,0x35,0x58,0x80,0x7e,0x4c,0x31,0xa6,0xa,0xaf,0x29,0x15,0xf1,0x58,0x95,0x5,0x80,0xcf,0x33,0xfe,0x74,0x59,0xd2,0xff,0xba,0xa2,0xc9,0xb2,0xaa,0xc,0xb6,0x19,0xba,0x2a,0x21,0x55,0x14,0x2c,0x18,0xaa,0xaa,0x84,0xd6,0x25,0xaa,0x8a,0xd8,0xe9,0x65,0x91,0xf3,0xfa,0x2b,0xc,0x56,0x16,0xd9,0xb7,0x54,0x22,0x5b,0x59,0xa2,0xf3,0xda,0x0,0x7b,0xbd,0x54,0xd7,0x5b,0x27,0xc0,0x39,0x38,0xe,0xfd,0x10,0x52,0xd2,0x36,0xf0,0x7d,0x4a,0xf0,0xba,0xad,0xb1,0xec,0xf5,0x97,0x21,0x1b,0x2c,0xa3,0xaa,0x88,0x45,0x58,0x64,0x59,0x58,0xb7,0x8a,0x68,0xf2,0xa5,0xdb,0x9b,0x45,0x94,0xa4,0xe8,0xf4,0x66,0x82,0x95,0x42,0xc4,0xe3,0xac,0x8c,0x22,0x56,0x1b,0xd4,0x0,0x96,0x97,0x39,0x8b,0x26,0xab,0xcf,0x4f,0x10,0x35,0x43,0x3a,0xae,0x81,0x88,0x4d,0x4a,0xe0,0x1d,0x65,0x6e,0x8f,0x8b,0x5e,0x87,0x39,0x70,0xe3,0xe0,0x1e,0xbf,0x16,0xfc,0x1,0x27,0xb0,0xfb,0x9a,0x20,0x5f,0x53,0xd1,0x2b,0x26,0x63,0x7e,0x6e,0xc,0x54,0x1c,0xce,0xed,0x75,0x13,0xf0,0x48,0x37,0x79,0x8f,0x87,0x9f,0xdf,0xae,0x8d,0x17,0x4e,0xf9,0x9b,0x98,0x8,0x44,0xd2,0x64,0xa9,0x6a,0x87,0xc7,0xb6,0xda,0x6a,0xab,0x5,0x0,0xdb,0x6a,0xab,0xad,0xb6,0xae,0xeb,0x56,0xd0,0x5a,0x7e,0xd6,0x75,0x61,0xe6,0x3d,0x3c,0x5c,0xb2,0x4,0x98,0x66,0xfc,0x2b,0x7e,0x64,0xe4,0x86,0x4f,0x6b,0x7c,0xe6,0xff,0x6b,0xef,0xdb,0x7e,0x65,0xc9,0xee,0xb3,0xbe,0xb5,0x56,0x5d,0xba,0x7b,0xef,0x7d,0xe6,0x8c,0x4d,0x1c,0xe2,0x5c,0x94,0x10,0x87,0x10,0x83,0x22,0x20,0x89,0x20,0x91,0x42,0x90,0x40,0x80,0xf8,0xab,0x78,0xe6,0xf,0x40,0xbc,0xe6,0x9,0xf1,0xc2,0xb,0xe2,0x12,0x21,0x94,0xb,0x81,0x24,0x8e,0x9d,0x4,0x32,0x51,0x70,0x6c,0x63,0xc7,0x8e,0x6f,0x33,0xe3,0x99,0x39,0x7b,0xef,0xbe,0x55,0xd5,0x5a,0x8b,0x87,0xdf,0x65,0xad,0x55,0xdd,0x7b,0x66,0x4,0x92,0x87,0xd9,0xfc,0xbe,0xc8,0x99,0x73,0xf6,0xe9,0xdd,0x5d,0x5d,0x5d,0xbd,0xaa,0x7e,0x5f,0x7d,0x97,0x5f,0xfe,0x85,0xab,0xa4,0xd2,0xd7,0xbe,0xfe,0x17,0xf8,0xca,0x5f,0xbc,0xc5,0xa4,0xd0,0x49,0x87,0x12,0xb5,0x6b,0x26,0xca,0xd8,0x9b,0xa6,0x13,0x8e,0x87,0x7,0x9c,0x8e,0x7b,0x1d,0xc2,0xa6,0xf3,0x91,0x32,0xa5,0x38,0xe3,0x66,0x3a,0x9f,0x34,0x97,0x69,0x9a,0x2a,0x6b,0xf0,0x7c,0xc6,0x17,0xbf,0xfa,0x75,0xfc,0xd9,0x97,0xbe,0x72,0x79,0xb2,0xf2,0x1e,0xff,0xe8,0xef,0xff,0x5d,0xa4,0x48,0x64,0xe2,0xf1,0xf0,0x80,0xe3,0xfe,0x1e,0x31,0xce,0xd7,0x89,0xd0,0x4a,0x2d,0x26,0x76,0x2b,0x69,0x3c,0xa6,0x61,0x72,0x8f,0x85,0x89,0xc9,0xb8,0x2c,0x1c,0x44,0x3f,0xf3,0xf0,0x4a,0x36,0x33,0x51,0x72,0x3c,0x75,0x11,0xae,0x99,0x46,0xbc,0x8f,0x65,0xb0,0x9b,0x58,0x55,0x77,0x78,0xbc,0xa7,0xb6,0x63,0x6e,0x4b,0x96,0x70,0x77,0xcf,0x43,0x1e,0xd9,0xc9,0x16,0xcd,0xe5,0xfb,0xc2,0x1b,0x5f,0xc6,0xbf,0xf8,0xd5,0x7f,0x83,0xff,0xf5,0xb5,0x6f,0xfc,0x5f,0xe7,0xf6,0x7c,0xf7,0xcd,0xb7,0xf0,0xab,0xff,0xfa,0xdf,0xe2,0xdf,0xff,0xd6,0x1f,0x70,0x9e,0x17,0xd,0xf7,0xb,0xdb,0xd1,0xa6,0xd3,0x91,0x49,0xdb,0x9e,0xd4,0x88,0xac,0x74,0x9b,0xce,0x47,0x6c,0xb6,0x37,0xa4,0x5a,0x9c,0x27,0xc0,0x1,0xbf,0xf5,0xb9,0x3f,0xc6,0xab,0xfb,0x62,0xcd,0x8e,0x31,0xe1,0x37,0xfe,0xdb,0x17,0xc8,0x1a,0xcc,0x2a,0xc6,0x69,0x3a,0xe1,0x7c,0xd8,0x97,0x86,0xde,0x33,0x91,0x7e,0x44,0x3e,0x53,0x1b,0xf4,0xef,0xfe,0xe1,0x9f,0xe2,0x9d,0x77,0x8a,0xd5,0x39,0xa5,0x84,0xdf,0xfc,0xed,0xdf,0x47,0x66,0x82,0xf6,0x74,0xdc,0xe3,0xf0,0xf8,0xa,0xa7,0xc3,0x23,0x5b,0x9,0xcf,0x98,0xa7,0x33,0xce,0xc7,0x83,0x66,0x76,0xc5,0x79,0xc1,0xcd,0x8b,0x97,0xc8,0xc8,0x18,0x36,0x5b,0xb5,0x2c,0xf7,0xe3,0xa8,0xd6,0xf7,0xa6,0x3c,0x80,0x49,0x10,0x29,0x40,0xa0,0xd6,0x4a,0xd6,0x4e,0xac,0xb2,0xa9,0xb8,0x6b,0xb2,0x1a,0x42,0xd7,0x43,0xa7,0xd3,0xb9,0xb1,0x6e,0x92,0x34,0x18,0xbe,0xef,0x6b,0xbc,0x5a,0xd7,0xa1,0x6a,0x29,0x6d,0xd9,0xe5,0xa8,0x87,0xe0,0x3b,0x2e,0x91,0x2d,0xed,0xe9,0x44,0x6,0x86,0xa6,0xc4,0x41,0xc8,0x41,0xf9,0x5f,0x64,0x52,0xb0,0x14,0x88,0x94,0x9b,0x16,0xce,0x53,0x9,0x85,0x64,0xf5,0xe5,0x2c,0x8d,0xb2,0x9,0xe3,0xf6,0x46,0xd7,0x57,0x51,0x7d,0xe7,0x9c,0xe1,0x59,0x69,0x16,0xba,0xe,0x71,0xa6,0xc,0x57,0x6a,0xa7,0x5d,0x54,0x59,0x9b,0xd2,0xa2,0xdf,0xd3,0x20,0x37,0x47,0xe0,0x30,0x4f,0x93,0x96,0x9d,0x84,0xae,0xc7,0x74,0x3a,0x22,0x74,0x3,0xb7,0xec,0x52,0xde,0xa7,0x64,0xed,0xc9,0xfb,0x4b,0x71,0xc1,0x34,0x9d,0x54,0xf1,0xe7,0xbc,0xe7,0xb5,0x9c,0xf3,0x5e,0x41,0x2a,0xf5,0xdb,0x17,0xaf,0xc3,0x7b,0x2a,0xcd,0x90,0x88,0x1,0x59,0x6f,0xe,0xf,0xaf,0xf0,0x78,0xff,0xe,0x4e,0xac,0x64,0x9f,0x4e,0x47,0x9c,0x8f,0xdc,0x46,0xbe,0x2c,0xc5,0x7e,0xcb,0x36,0x5e,0xc9,0xb1,0x9d,0xe7,0x9,0xa7,0xe3,0x1e,0x39,0x27,0x9c,0x8e,0x7b,0x2c,0xd3,0x19,0xa7,0x3,0xe5,0xf2,0x85,0x8e,0xb2,0x59,0xa5,0xb0,0x48,0x94,0x88,0xa2,0x12,0xcc,0x39,0x63,0xe1,0x1b,0x65,0x54,0x6e,0x42,0xdb,0x7e,0x66,0xb5,0x23,0x65,0x3d,0x26,0xec,0x1f,0x68,0x8d,0x3c,0x3c,0xde,0xeb,0xda,0x78,0xe6,0x16,0xe6,0xf3,0xe9,0x88,0x65,0x59,0x70,0x3a,0x3c,0xf0,0x8d,0x1c,0x52,0xf,0x2e,0x33,0xdd,0xd8,0x99,0xe7,0x33,0xce,0xa7,0x3d,0xe6,0xe9,0x84,0xd3,0xf1,0x91,0xd5,0x7a,0x94,0xd5,0xd2,0x3d,0xd1,0x3a,0x0,0x0,0x20,0x0,0x49,0x44,0x41,0x54,0xbb,0x7f,0x78,0xf,0xd3,0x44,0x11,0x16,0x0,0xf8,0xbc,0xe5,0xf9,0xa6,0x88,0xa3,0xbf,0x7b,0x5f,0x4a,0x3d,0x38,0x37,0x57,0xca,0xbe,0x44,0x71,0x4a,0xe7,0xde,0xd8,0x9e,0x23,0x57,0x19,0xaa,0xc0,0xfb,0x37,0xf6,0x3e,0x9,0xb7,0xa2,0xc7,0x72,0xbe,0xb0,0xd7,0x6a,0x1d,0xb6,0xfe,0x7b,0xcd,0xce,0xb9,0x15,0x4f,0x98,0xcb,0x7f,0xf2,0x15,0x82,0x6d,0xe5,0x10,0xbe,0xa0,0x1c,0x2b,0xcb,0xef,0x9a,0x9a,0x74,0x68,0x37,0xa9,0xfd,0x79,0xad,0xf6,0x6b,0x15,0x8f,0x6b,0x82,0xaf,0x24,0x1a,0xe6,0x27,0x29,0xc4,0xcb,0x57,0x45,0x75,0x9e,0x35,0x5,0xa0,0xc1,0x60,0x68,0x61,0x16,0x60,0x83,0xc1,0x60,0x78,0x46,0x50,0x2b,0x58,0xd5,0x2a,0x27,0x64,0x48,0xe4,0xc1,0x82,0x3c,0x63,0x59,0x9,0x11,0xa,0x86,0xf,0xf8,0xd4,0x27,0x5e,0xe0,0x67,0x7e,0xfa,0x33,0x57,0x9f,0xf3,0xd7,0xff,0xeb,0xe7,0x31,0x9d,0x4f,0x3c,0x0,0x44,0x2c,0x6c,0xf7,0x15,0x1b,0x11,0x11,0x4c,0x11,0xf3,0xf9,0xac,0x8a,0x83,0xe9,0x74,0xc4,0xfe,0xe1,0x15,0x36,0xbb,0x1b,0x48,0xa0,0x7a,0x60,0xc5,0x5d,0xd7,0x53,0x69,0x84,0x83,0xa3,0xf2,0x8d,0xd0,0x69,0xf8,0xf9,0x7f,0xf8,0x4f,0xbf,0x81,0xcf,0xfe,0xcc,0x4f,0xa3,0xef,0xda,0x53,0xd4,0x5f,0xfd,0xa9,0x9f,0xc4,0x4f,0xff,0xf8,0xa7,0xf1,0xc7,0x5f,0xfc,0x2a,0xe6,0x89,0x9a,0x8b,0xf3,0x13,0x17,0xb7,0x89,0x55,0x10,0x1a,0x6a,0x2e,0x36,0x18,0x7,0x2e,0xea,0x18,0x90,0xe2,0x82,0xfe,0xe6,0x4e,0x2d,0x54,0x81,0x43,0xdc,0x53,0x8a,0xfc,0xdc,0x69,0x75,0x29,0x7e,0xf9,0x1a,0x64,0x45,0x8e,0x25,0x57,0xea,0xb8,0x67,0x22,0xed,0xc4,0xc5,0x20,0x50,0x4b,0xeb,0xf6,0xf6,0x8e,0xc9,0x4f,0x22,0xdd,0xd2,0xb2,0x34,0xaa,0x40,0x0,0xf8,0xf2,0xd7,0xbf,0x8d,0x7f,0xfe,0x2f,0xff,0x15,0xfe,0xf1,0xdf,0xfb,0x79,0xfc,0xca,0x2f,0xfe,0x1c,0x5e,0x7f,0xf9,0xe2,0xc9,0xc,0xc2,0x6b,0x78,0xe7,0xdd,0x57,0xf8,0xfc,0x1f,0xbd,0x81,0x5f,0xfb,0x2f,0x7f,0x80,0x87,0xe3,0xa4,0x19,0x8d,0x25,0xf8,0x3f,0x22,0xe5,0xac,0x76,0x58,0x52,0xa6,0x9c,0xe1,0x7d,0x40,0xd7,0xd,0x88,0x6e,0x51,0x2b,0xf3,0xf6,0xf6,0x5,0xe,0xf,0xf7,0x40,0x6,0xbe,0xf0,0x47,0x6f,0xe0,0x1f,0xfc,0xca,0x2f,0x2,0x0,0xde,0x7c,0xeb,0x2d,0xfc,0xf1,0x17,0xbf,0xa,0xe7,0x1c,0xba,0x6e,0xc0,0x71,0x21,0x1b,0xb0,0xf3,0x1e,0xe7,0xf3,0x11,0xdd,0x30,0x2,0xc8,0x48,0x73,0xd4,0xfc,0x3e,0xb2,0x6b,0x8f,0xf8,0xbd,0xcf,0xff,0x1,0xfe,0xe9,0x3f,0xfe,0x87,0x0,0x80,0xef,0xbc,0xf9,0x16,0x3e,0xf7,0xc6,0x97,0xf5,0x98,0xa5,0x32,0x9a,0xe,0xa7,0xe3,0x1e,0xd3,0x99,0x7,0x78,0xef,0xd5,0xee,0x4d,0xb6,0x37,0xe0,0x74,0x78,0x44,0x3f,0x6e,0x10,0xe7,0x99,0xda,0x90,0x73,0x86,0xd7,0x8c,0x33,0xa8,0x35,0x4e,0x8a,0x70,0x1c,0x13,0x26,0xf5,0xa1,0xd2,0xa8,0x51,0x2a,0x9b,0x61,0x13,0xc4,0xee,0x5c,0x13,0x2c,0x2f,0x93,0x60,0xb1,0xa4,0xd9,0x60,0x65,0xf8,0x68,0x20,0xc4,0x51,0xae,0xd6,0x26,0x5a,0xe3,0xf8,0x78,0xe6,0xb5,0xd4,0x79,0xdf,0x58,0xd8,0x9d,0x73,0x65,0xdd,0x91,0x75,0x8b,0xd7,0x1f,0x7,0x7,0xdf,0x5,0x3e,0x5f,0x4,0x5d,0xbf,0x3c,0x2b,0x6c,0x73,0x9a,0x99,0x3c,0x74,0x85,0x58,0xe3,0xe6,0xdb,0xc3,0x72,0x8f,0x79,0x3a,0xa3,0x1f,0x46,0x8c,0x9b,0x2d,0xb5,0xe1,0x56,0xe4,0xa0,0x77,0xbe,0xd8,0x4a,0x17,0x52,0xfb,0x86,0x7e,0xd0,0xec,0xb9,0xd6,0x8e,0xef,0xa8,0xe9,0x9d,0xc9,0x24,0x22,0x36,0x45,0xbd,0xee,0x90,0x63,0xd2,0xc2,0x29,0x6a,0xc7,0xed,0x4a,0x9e,0x6d,0x4a,0x8,0x9b,0x51,0xbf,0xd7,0x39,0x27,0x20,0x52,0x73,0xb0,0x92,0x90,0x29,0xc2,0xc1,0x69,0xf3,0xf0,0xe9,0x74,0x20,0xc5,0xf6,0x6b,0x9f,0x50,0x5,0x1f,0x15,0x9d,0x90,0xc2,0x7d,0x9a,0xb2,0xe6,0xd9,0x2e,0xcb,0xa4,0x16,0x67,0xef,0x49,0x49,0x18,0xe7,0x89,0x1f,0x77,0x6,0x90,0x31,0x9f,0x4f,0x38,0x88,0xcd,0xf8,0x7c,0x44,0xd7,0x8f,0xe8,0x87,0x8d,0x46,0x30,0xb8,0x61,0xd4,0xe2,0x8e,0xf9,0x7c,0x22,0xfb,0x32,0x93,0x55,0x42,0x60,0xca,0x4d,0x2b,0x52,0x24,0x4e,0xbc,0x2f,0xbc,0xb6,0xce,0xd3,0x8d,0xb5,0x13,0x76,0x77,0xaf,0x21,0xb1,0x9d,0x77,0xe6,0xfc,0xd9,0x69,0x39,0x40,0x14,0xce,0xf3,0x74,0x26,0x2,0x89,0xf7,0xbb,0xec,0x67,0xb1,0x0,0x4f,0xb,0xad,0xb3,0xd3,0xf9,0x80,0x61,0xb3,0x55,0xab,0xb4,0xf,0x1d,0x15,0x2d,0x6d,0x36,0xda,0x96,0xee,0x9c,0x43,0xe0,0xfc,0xdc,0xb5,0xcd,0x77,0x7d,0x33,0x65,0xdd,0xe0,0x2b,0xf6,0x5f,0x25,0xaa,0xc5,0xc0,0x9a,0xf2,0xaa,0x4c,0x23,0x5f,0xb6,0xe1,0xae,0x49,0xad,0x35,0x61,0xe8,0xae,0x9d,0xa2,0x25,0x0,0x8f,0xb7,0x4d,0x94,0xfc,0x95,0xcd,0xd6,0xb9,0x96,0xe0,0x5b,0x3b,0x7f,0xaf,0x29,0xf1,0xda,0xaa,0x8f,0xea,0xa6,0x51,0x6e,0x5f,0xf7,0xd2,0xd4,0xcc,0x25,0x54,0xd5,0xb3,0x5e,0x57,0xf0,0xa1,0xf9,0x4e,0xb,0xa9,0x97,0xdf,0xf7,0xd,0x67,0x5c,0xcd,0x23,0xac,0x6f,0xc,0x18,0xc,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0x8c,0x7,0xc3,0xea,0xa,0x57,0x94,0x70,0x32,0x48,0x9,0x11,0x4,0xc7,0xc4,0x14,0xff,0xbd,0x1f,0x47,0xfc,0xf0,0xa7,0x5e,0xc7,0xb7,0xbe,0xfd,0x1d,0x7c,0xfb,0x3b,0xed,0x9d,0xe4,0x87,0xc7,0x3d,0x3e,0xff,0xc6,0x97,0xb5,0x18,0xc3,0x79,0x87,0xc0,0x83,0x22,0x35,0xdc,0xf6,0xa4,0xa8,0xe3,0x60,0x77,0x19,0x4e,0x32,0x80,0x9b,0x17,0x2f,0x1,0x50,0x4b,0x6b,0xe4,0x4c,0x28,0x9,0x9f,0x1f,0x36,0x5b,0x1d,0x22,0xc4,0x2,0xea,0x43,0xc0,0xef,0xfd,0xf7,0x2f,0xe2,0x73,0xbf,0xff,0x87,0xf8,0xe4,0x27,0x5e,0x3,0x65,0x42,0x95,0x21,0xf5,0xc7,0x7f,0xf4,0xd3,0xf8,0x1f,0x5f,0xfc,0x2a,0x42,0xd7,0xe1,0xf0,0x78,0x8f,0x37,0xdf,0x7a,0x1b,0x7f,0xfa,0xc5,0x3f,0x63,0x22,0x31,0xe8,0xd5,0xef,0x3b,0xef,0xdd,0x53,0xfe,0x91,0xf,0x34,0x40,0x85,0x80,0xe5,0x38,0x69,0x9e,0x1c,0xd9,0xb9,0x88,0xa4,0x74,0xce,0xa1,0xeb,0x47,0x55,0x7,0xe8,0x36,0xa6,0x88,0x69,0x9a,0xf1,0xe5,0xaf,0x7c,0xd,0x9b,0xcd,0xc8,0xfc,0x10,0xed,0x97,0x6f,0x7c,0xf3,0xdb,0xcd,0x5,0x76,0x56,0x85,0x99,0xc7,0xe1,0xf1,0x3d,0xe,0xbf,0x3f,0x61,0xdc,0xde,0x60,0x3a,0x1f,0x70,0xf7,0xf2,0x2f,0x51,0xd8,0x3e,0x87,0xc1,0x93,0xa,0x26,0x17,0x85,0xe,0x8a,0x95,0xea,0x74,0x8e,0xf8,0x77,0xbf,0xf9,0x79,0xfc,0xc7,0xdf,0xfc,0x1c,0x7e,0xfe,0x6f,0xfc,0x14,0x7e,0xee,0x67,0xff,0x1a,0x7e,0xec,0x47,0x7e,0x8,0x37,0x37,0x3b,0xf4,0x6c,0xcd,0x22,0xb2,0x34,0x61,0x9e,0x67,0x1c,0x8e,0x27,0x7c,0xf3,0xdb,0xdf,0xc5,0x1f,0xbd,0xf1,0x67,0x78,0xe3,0xcb,0xdf,0xc0,0xdb,0xef,0xbc,0xa2,0x26,0x62,0xe,0x77,0xf7,0x21,0x68,0x88,0x3c,0x45,0x1b,0x12,0xa1,0x45,0x39,0x55,0x33,0x5b,0x98,0x17,0x2c,0xb,0xdb,0x7f,0x53,0xc2,0xed,0x6b,0x9f,0xc0,0x32,0x4d,0xd8,0xdd,0x52,0xc1,0xc6,0x7f,0xfe,0xed,0xdf,0xc7,0x2f,0xfe,0xc2,0xdf,0xc4,0x76,0xbb,0xc5,0xef,0x7e,0xe1,0x4f,0x70,0x9a,0x4b,0x91,0xcc,0xb0,0xd9,0xe2,0xb8,0x27,0xc5,0x49,0xd7,0xf,0x98,0x4e,0x7,0x56,0x1d,0x38,0x1e,0x3c,0xd9,0x2a,0x8e,0x8c,0x5f,0xfb,0xf5,0xdf,0xc1,0x2f,0xff,0xd2,0xdf,0xc1,0xed,0xed,0x2d,0x7e,0xe7,0x73,0x7f,0x88,0xd3,0x99,0x6,0xfd,0x85,0x49,0xc8,0x9c,0x12,0x96,0xb8,0x50,0xde,0x15,0x2b,0x24,0x9d,0x23,0xbb,0x32,0x1c,0x59,0xbb,0xfb,0x61,0xa4,0xec,0xab,0x61,0xc4,0x30,0x6e,0xd8,0xa2,0x48,0xf9,0x63,0x52,0x28,0x43,0x47,0x81,0x53,0xc5,0x88,0xaf,0x2c,0x69,0x4d,0x20,0xbd,0x73,0x50,0x33,0x84,0xa8,0x46,0x5d,0xd5,0x4c,0xa9,0x3,0x63,0x15,0x32,0xcf,0x44,0x3,0x91,0x24,0x66,0x3,0x36,0x7c,0xff,0x91,0xb9,0x8,0xa3,0x65,0x27,0x1c,0xb0,0xce,0x2,0xac,0xf2,0xd9,0xa,0x91,0x96,0x90,0x23,0x13,0x67,0x42,0xce,0xc4,0xc8,0x99,0xa7,0x75,0x9b,0x2d,0x65,0xfb,0x49,0x46,0x20,0x1c,0xdd,0xac,0xd1,0xfc,0xd3,0x18,0xd1,0xf5,0x3d,0x2b,0x76,0x67,0xc,0xe3,0x16,0x5d,0xdf,0x63,0xe0,0xb5,0x7e,0xb3,0xbb,0xa5,0xb2,0x88,0x8a,0xc0,0xeb,0x38,0x3f,0xb0,0x26,0xa1,0x64,0x5d,0x95,0x9b,0x4b,0x72,0x1e,0xa3,0x6,0x62,0x6e,0x2d,0x67,0x7b,0xb0,0x10,0x9d,0xa1,0xeb,0xaa,0xb5,0x7b,0xd0,0x6,0xdb,0x10,0xe9,0xe7,0xc3,0xb8,0xc1,0xbc,0x50,0x5b,0xb8,0xb4,0x91,0xc3,0x41,0xb3,0xfa,0xa4,0x4c,0x44,0x89,0x3e,0xe7,0x31,0x9d,0xe,0x18,0xc6,0x2d,0x1e,0xef,0xdf,0xc3,0xed,0x6b,0xaf,0xd3,0xda,0xc8,0x56,0xe4,0x10,0x3a,0x8e,0x22,0x70,0x45,0x59,0x8c,0x85,0x72,0x63,0x73,0xc6,0xf9,0xf4,0xa8,0x31,0x17,0xf2,0xb9,0x2c,0x71,0x6,0x72,0x42,0xa,0x51,0x6f,0x3a,0x29,0x79,0x96,0x22,0x32,0xa0,0xdb,0x11,0xe3,0x42,0xe7,0xc8,0xd3,0x91,0x8,0x4a,0x6e,0x1d,0x16,0x45,0xa5,0x14,0x8d,0x8,0xa9,0xb7,0x7f,0x78,0xf,0xa1,0xeb,0xf1,0xf8,0xde,0xf7,0x68,0x98,0x1b,0x46,0x78,0xe7,0x71,0x8e,0x7,0x2c,0x53,0x39,0xbf,0x64,0x8e,0xf7,0x98,0x59,0x4d,0x2d,0x6b,0x23,0xed,0x4f,0x5a,0xf3,0x73,0xca,0xe8,0x87,0x81,0x8b,0xbb,0x22,0x86,0x91,0x72,0x68,0x37,0xbb,0x1b,0xce,0x75,0xa5,0xc2,0x8f,0xc0,0x5,0x31,0xa9,0xb2,0x8c,0xb7,0xca,0xbe,0x84,0x9c,0x79,0xbd,0x65,0x5,0xa7,0x14,0xc7,0x64,0x96,0xc1,0xd1,0xf1,0x53,0x72,0x5c,0xb5,0x65,0x37,0xaf,0xf2,0xf5,0xd6,0xa4,0x56,0x5d,0xae,0x71,0x95,0xf0,0xab,0xb2,0xf7,0xae,0xb1,0x79,0xd7,0x8,0xb9,0xe6,0x25,0xb3,0x36,0x17,0xe7,0xab,0xb4,0x5c,0xcd,0xab,0x65,0xe4,0x8a,0x54,0x6b,0x89,0xc2,0xeb,0x2f,0x78,0xdd,0xf2,0x7c,0xad,0xf7,0xf8,0xda,0x9b,0x72,0x6d,0xb0,0x60,0xf3,0xe7,0xd5,0x9b,0x29,0x75,0xd2,0x74,0x13,0x2c,0xc3,0x5a,0x80,0xd,0x6,0xc3,0xf5,0x35,0xd0,0x76,0x83,0xc1,0x60,0x30,0x3c,0xf,0xfc,0xec,0x2f,0xfd,0x13,0xbc,0xf6,0xc9,0x1f,0x20,0xb2,0x89,0xc9,0x93,0x94,0x69,0xa0,0x0,0xe7,0xd0,0xa1,0xca,0x86,0x91,0xe1,0x4c,0x6d,0xc2,0x6a,0x91,0x74,0x1a,0x1a,0x2f,0x67,0xa,0xc7,0xc5,0x1f,0x21,0x74,0x4c,0x20,0xce,0xf0,0xbe,0x43,0x5c,0x26,0x9c,0xe,0x7b,0x38,0xef,0xf1,0xf8,0xea,0x1d,0xcd,0x69,0x2,0x80,0x79,0x9a,0xd0,0x8f,0x23,0xfa,0x7e,0x44,0x3f,0x8c,0x8,0x1c,0x1a,0xee,0x1c,0xa9,0x3c,0xe0,0x80,0x9e,0x7,0xb8,0xed,0xcd,0x2d,0x5f,0xbb,0xe6,0xd2,0x22,0x98,0x22,0x7c,0xd7,0xa1,0xeb,0x6,0xec,0x1f,0xde,0xe3,0xe7,0x3c,0xa1,0xef,0x47,0x9c,0x8e,0x54,0x48,0xb2,0xbd,0xb9,0x45,0x3f,0x8c,0xe8,0xc7,0xd,0x36,0xdb,0x1b,0x25,0x14,0x3,0xab,0x32,0x1c,0x28,0x98,0x7d,0x3a,0x9f,0x70,0xda,0x3f,0x20,0xe5,0x8c,0xfd,0xfd,0xbb,0x6a,0x9,0xbe,0x7d,0xed,0x75,0xc,0x9b,0x2d,0x82,0xa7,0x52,0x14,0x22,0x9f,0xce,0x3c,0x0,0x77,0x9c,0x53,0x55,0x2c,0xcf,0x39,0x45,0x6a,0x3c,0x96,0xc1,0x18,0x64,0x89,0x9b,0x4e,0x47,0xb5,0xb1,0x8a,0xda,0x62,0xdc,0xee,0x70,0x7b,0xf7,0x12,0x8e,0x73,0xb1,0xc6,0xed,0xe,0xcb,0x32,0xa3,0xef,0x47,0x52,0xd6,0xc4,0x5,0x21,0xf4,0x40,0xce,0xf0,0xc1,0xeb,0x90,0x27,0xf9,0x5a,0x5d,0x3f,0x10,0xe9,0x9a,0x16,0xbc,0xd8,0x76,0x78,0xf9,0xe2,0x6,0x9b,0x91,0xf2,0xaf,0xa6,0x25,0xe2,0x7b,0xaf,0x8e,0x78,0x3c,0xcf,0x88,0x29,0xa3,0xef,0xc7,0xa2,0x32,0x71,0x9e,0x5a,0x29,0x59,0x5,0x29,0x9f,0xaf,0x64,0x41,0x1,0x44,0xcc,0xcd,0xf3,0x19,0xcb,0x74,0x66,0xc5,0x22,0xb5,0x0,0x3b,0xe7,0x30,0x6e,0x76,0x18,0xd9,0xa,0x3c,0x8c,0x5b,0x6c,0xc6,0x1,0x9f,0xfd,0xcc,0x8f,0xa1,0xef,0x3c,0xbe,0xf4,0xe7,0xdf,0xc1,0xc3,0xe1,0x4c,0x59,0x89,0x13,0xe5,0x65,0xcd,0xd3,0x9,0xf3,0xf9,0x4c,0xca,0x91,0x61,0x40,0xd7,0x51,0x46,0x5f,0x37,0x8c,0xaa,0x12,0x82,0x73,0x8,0xa1,0xc3,0xdf,0xfa,0xec,0x67,0x70,0xb3,0xdb,0xe1,0x4f,0xbf,0xf2,0xd,0xec,0xcf,0xb3,0xb6,0x6f,0x9e,0xe,0x7b,0xde,0x7f,0xf7,0x54,0x8,0xc0,0x64,0x6c,0xe0,0x61,0x56,0x8,0xc1,0xcd,0x96,0xf2,0xa8,0x36,0xbb,0x5b,0x1e,0x7e,0x7,0x25,0xa,0x7c,0x65,0x67,0x84,0x2a,0xa4,0xa,0x69,0xa1,0xdf,0x81,0xca,0x2,0xec,0x2e,0x14,0x16,0xc5,0xaf,0xa5,0x43,0x22,0x1f,0x53,0x32,0x8c,0xbf,0xf5,0xed,0xaf,0xe3,0x7b,0xdf,0xfe,0x6,0x72,0x9a,0x6d,0xd1,0x31,0x7c,0xff,0x2f,0xde,0x9d,0xc7,0x4f,0xfc,0xf5,0x5f,0xc0,0x5f,0xfe,0xd1,0xbf,0xa2,0x16,0x7e,0xca,0x23,0x95,0x66,0x76,0x52,0x78,0x6b,0x46,0x1b,0x17,0x6f,0x38,0x38,0x2d,0x82,0x50,0x32,0x8b,0x49,0x9e,0xc8,0x96,0x5c,0x21,0x7a,0x84,0xd4,0x91,0xc7,0x11,0x31,0x38,0xb3,0x35,0x18,0x6a,0x3f,0x7d,0xbc,0x7f,0x17,0xf3,0xf9,0x84,0xfd,0xc3,0x7b,0xd8,0xde,0xdc,0xe1,0xe6,0xee,0x25,0x36,0xbb,0x5b,0x56,0x94,0x5,0x22,0xe9,0x25,0x8b,0x55,0x2d,0xb8,0xc5,0xd6,0x2b,0x37,0x81,0xb4,0xa8,0x4a,0xb,0x4c,0x28,0xa3,0x55,0xd6,0x31,0xb1,0xda,0x2e,0xcb,0x8c,0xfd,0xc3,0x7b,0x38,0x3e,0x52,0xd4,0xc4,0x3c,0x9d,0xf1,0x83,0x3f,0xf2,0x13,0x18,0xc6,0xd,0xc6,0xcd,0x8e,0xd7,0x9f,0xbe,0xe4,0xfd,0x39,0x47,0x8d,0xc6,0x5d,0xcf,0x6a,0x38,0xaf,0x19,0xb6,0x62,0xf9,0xdd,0x3f,0xbe,0x42,0xd7,0xf5,0x94,0x2f,0xda,0xf5,0xf0,0x3e,0xa8,0x55,0x77,0x73,0x73,0xcb,0xbf,0xdf,0x71,0x99,0x54,0xcf,0x8a,0x67,0x52,0x42,0x8a,0x82,0x7a,0x9e,0x4e,0xfc,0xbb,0xb4,0x8e,0xf,0x9b,0x2d,0x96,0x69,0x62,0x15,0x1d,0xed,0xef,0xcd,0xee,0x46,0x4b,0x3f,0x24,0x1a,0x2,0x20,0xf5,0x73,0x21,0xcb,0xb2,0x96,0x71,0x2c,0xf3,0x84,0x87,0x57,0xef,0xa8,0xd5,0xf8,0x74,0xdc,0x23,0xa7,0x84,0x9b,0xbb,0x97,0x90,0xd6,0x66,0x51,0x2a,0xfb,0x50,0xf6,0x17,0x45,0x52,0xcc,0x9c,0xbf,0x98,0xb4,0x48,0x4,0xb9,0x22,0x1d,0x39,0x3b,0x90,0x88,0xbe,0xac,0xa5,0x4a,0x54,0x56,0xb5,0x41,0x8,0x3d,0xba,0x81,0x54,0x9a,0x21,0x74,0xdc,0xb0,0xde,0x96,0x56,0x88,0x4d,0x5c,0x3e,0xd3,0x72,0xbd,0x50,0x6e,0xb0,0xd4,0x84,0x61,0xbb,0xbe,0xba,0x4a,0x49,0x57,0x51,0x69,0x6b,0x82,0x4b,0xc8,0xed,0x75,0x1b,0x70,0xcd,0xe0,0xad,0x8,0x31,0xba,0xb9,0xe6,0x3e,0x90,0xcc,0xbb,0x36,0x4,0xbb,0xab,0x84,0x9d,0x5b,0xfd,0x86,0xbb,0xf2,0x2c,0xd7,0xc8,0xbc,0xa7,0xd8,0x4a,0xb4,0xef,0xe5,0x42,0xbd,0xb7,0xde,0xe0,0xea,0xfd,0xbb,0x55,0x2b,0xf1,0x15,0xa4,0x9c,0xf4,0xf8,0x7e,0xe7,0xcd,0x6f,0xe1,0x3b,0x5f,0xfb,0x9f,0xb6,0x68,0x1a,0xc,0x6,0x85,0x29,0x0,0xd,0x6,0x83,0xe1,0xb9,0xd,0x87,0x70,0xc8,0x48,0xa4,0x4e,0x60,0x25,0x56,0x1d,0x12,0x4f,0xcd,0x90,0x59,0xb3,0xd0,0x9c,0x10,0x24,0x72,0x19,0xcb,0x43,0x88,0x28,0xf6,0xbc,0xef,0x74,0x28,0x13,0x9b,0xae,0xd7,0x42,0x85,0x85,0xb3,0xe0,0x80,0xf3,0x71,0x8f,0x7e,0xd8,0xe0,0x74,0x78,0xe4,0x76,0xd9,0x5e,0xc3,0xc3,0x7d,0x8,0xdc,0x38,0x2c,0x57,0xad,0x44,0xdc,0x2d,0xcb,0xc,0x7,0x60,0xdc,0xdd,0xe0,0x7c,0x3a,0x71,0x13,0x24,0x37,0x4b,0x76,0x1e,0x61,0x18,0x39,0x78,0x7d,0xc2,0x66,0x7b,0x43,0x36,0x64,0x17,0x70,0x3c,0x3c,0x10,0xb1,0x93,0x16,0xa,0x4c,0x67,0x32,0x2e,0xa7,0x84,0x7e,0xd8,0x20,0xa7,0x88,0x39,0x46,0x20,0x27,0xc0,0x95,0xb8,0x5b,0x69,0xe7,0xed,0xfa,0x1,0x87,0xf3,0x3d,0x6e,0x5e,0xbc,0x24,0xdb,0x99,0xc,0x24,0x21,0x60,0x89,0x73,0xa5,0x12,0x21,0xeb,0x57,0x4e,0xd4,0x9c,0x5b,0x93,0x72,0x5d,0x3f,0x20,0xc7,0xa5,0x1a,0x52,0xa3,0xda,0x9a,0xcf,0xc7,0xbd,0x92,0x84,0x33,0xb7,0x4a,0x52,0x5b,0xe4,0x4,0x1f,0xb8,0x89,0x72,0x71,0x3c,0xf8,0x2d,0x3c,0x98,0x97,0xc6,0xbe,0x9c,0x63,0xd3,0x5c,0x79,0x3c,0x9d,0xf1,0xb8,0xdf,0xe3,0xcf,0xbf,0xf5,0x26,0xa6,0xd3,0x51,0xf7,0xe7,0xcd,0xdd,0xeb,0x0,0xb2,0x92,0x96,0xae,0x22,0xbb,0x52,0xa5,0x5e,0x59,0x96,0xb9,0xca,0x49,0xca,0xc8,0x99,0xda,0x80,0xa7,0x13,0xd9,0x6a,0x53,0x4a,0x38,0x1d,0x1e,0x91,0x62,0x44,0xcf,0xaa,0xba,0x9c,0x92,0xda,0x79,0xcf,0xf3,0x8c,0x2f,0xbc,0xf1,0x25,0x74,0x95,0x6a,0xa8,0xeb,0x7a,0x55,0xf1,0x78,0x4f,0x2d,0xa0,0xe9,0x7c,0xc4,0xd6,0xbd,0xc0,0x32,0x9d,0xd1,0xf5,0x23,0xa6,0xd3,0x51,0xad,0x84,0xa1,0xa7,0x62,0x80,0x3f,0xf9,0xca,0x5f,0xe8,0x31,0xb9,0xd9,0xdd,0x6a,0x19,0x8c,0xd8,0xeb,0x44,0x55,0xd4,0xf,0x1b,0xb8,0x4c,0x8d,0xa0,0x69,0x21,0x12,0x60,0xdc,0xec,0xd4,0x2e,0x9e,0x98,0x88,0xcd,0x29,0xc1,0xf5,0x5e,0x5b,0x2e,0x65,0x72,0x72,0xde,0x73,0x1e,0x66,0xd6,0xec,0x45,0x51,0x36,0xa9,0xf5,0x6c,0x95,0xa1,0x96,0xc4,0x2a,0x26,0x64,0xe1,0x7a,0xee,0xac,0xc,0x62,0x46,0xfe,0x19,0x3e,0x42,0x6,0x90,0xbf,0x57,0x55,0x76,0x18,0x2b,0x0,0x43,0xe8,0xd8,0x7a,0x5b,0xd1,0x18,0x4c,0xec,0x80,0xd5,0x76,0xde,0xf9,0xf2,0x1c,0xae,0x90,0x37,0xc4,0x53,0xd1,0xf3,0x68,0xf3,0x6b,0x3f,0x60,0x99,0xce,0x58,0xa2,0x64,0xea,0x39,0x6d,0x60,0x97,0xef,0x7f,0xca,0x9,0xc3,0xb8,0x65,0x5,0x3a,0x2b,0x72,0xe3,0x80,0x4e,0xc8,0x49,0xbe,0xb1,0x21,0x91,0xc,0xf2,0x7d,0x2b,0x37,0x7b,0xa0,0x4,0x98,0xd8,0x9b,0x69,0x4d,0x2f,0xd6,0x65,0xae,0xe9,0x21,0x9b,0x6e,0x8c,0xe8,0x86,0x1,0x23,0x17,0x9a,0xc4,0x65,0x86,0xe3,0xe6,0xde,0x14,0x23,0xd0,0xf,0x54,0x4e,0xb5,0xcc,0xdc,0x52,0xdc,0x21,0xe5,0xc4,0x8d,0xc9,0xa4,0xd2,0x73,0xde,0xa3,0x1f,0x36,0x88,0x71,0xc1,0xdd,0xcb,0x4f,0xe2,0xb4,0x7f,0xc0,0xed,0xcb,0x4f,0x92,0x1a,0x39,0x50,0x43,0xba,0xf7,0x1e,0xe9,0x81,0xd6,0xe4,0xae,0xa7,0x1b,0xd,0x13,0x9f,0xdb,0x96,0x33,0xb5,0xe0,0x52,0x3b,0x31,0xd9,0x86,0xa7,0xf3,0x9,0xc3,0xb8,0x1,0x58,0x55,0x1d,0xba,0xae,0x21,0xfc,0x64,0xd,0xa2,0x73,0x54,0x62,0x8b,0xb6,0xd3,0x32,0x29,0xca,0x57,0x9c,0x39,0x83,0x76,0xd2,0x82,0x8e,0xc4,0x5,0x27,0xde,0x7b,0x84,0x7e,0x40,0x8c,0xa5,0x80,0xcb,0xb1,0x45,0xdb,0x79,0x8f,0xe9,0x78,0xc0,0x34,0x9d,0x94,0x5c,0x95,0x7d,0x7d,0x3a,0xee,0x31,0x6e,0x76,0x98,0xa6,0xa3,0x2a,0x1f,0xb7,0x37,0x77,0x7a,0x73,0x46,0xca,0x5c,0x68,0x9f,0x8c,0x5a,0x88,0xb5,0xcc,0x13,0xc6,0x71,0x4b,0x8d,0xca,0xde,0xe9,0xeb,0xb4,0xf9,0x74,0x8e,0x5b,0x9d,0xd9,0xe6,0x9b,0x8b,0x2a,0x3e,0xaf,0x88,0x3a,0x22,0xa2,0x6b,0xae,0xaf,0x26,0xb5,0xb0,0x22,0xf5,0xda,0xeb,0x16,0xe7,0x5a,0x82,0xf,0x20,0xa1,0x76,0x6d,0xc1,0x2d,0x62,0x38,0x77,0x95,0x73,0x5b,0xaf,0xe7,0xd7,0xa,0x39,0xf2,0x13,0xe5,0x22,0x4e,0x1b,0x87,0xd7,0xc4,0xe5,0x53,0xcc,0xde,0xd3,0xb4,0x62,0x2b,0x1b,0x7c,0xea,0xe7,0xf5,0xcf,0x72,0xfb,0xe7,0xf,0x92,0xee,0x48,0xe8,0xa0,0x49,0x7c,0xc,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0xec,0xe7,0xc2,0x42,0x50,0xe4,0xa8,0xad,0xbf,0x29,0x45,0x1a,0xfa,0x98,0x4,0xf3,0x3e,0xa8,0x4d,0xd3,0xfb,0xac,0x39,0x4d,0xc8,0x19,0x51,0x6,0x13,0x38,0x64,0x26,0xd6,0x1c,0x1c,0x16,0xce,0x1e,0x4a,0x29,0x61,0x9a,0x27,0x52,0xf3,0x71,0xc6,0x1b,0x40,0x19,0x83,0xc7,0xfd,0xbd,0xb6,0xcc,0x9e,0xe,0x7b,0x74,0xdd,0x80,0x61,0xb3,0xad,0x86,0x54,0xa0,0xeb,0x47,0xcd,0xa9,0x1a,0x78,0x0,0x23,0x45,0xd7,0xd,0xe6,0xf3,0x89,0xc8,0xad,0x8e,0x6,0x36,0x7a,0x4f,0xa4,0xc,0x9,0x5d,0x87,0x10,0x3b,0xf4,0x79,0x40,0xe8,0x3a,0xbc,0xfa,0xde,0x9b,0x64,0x47,0x4e,0x3d,0xbc,0xf3,0x3a,0xb4,0x88,0xda,0x42,0xec,0x6a,0x29,0x2d,0xaa,0x76,0x20,0xc5,0x5d,0xc0,0xe3,0xfd,0x3d,0xbc,0xf7,0xaa,0x7c,0xbb,0xed,0x7,0x52,0x9f,0x48,0x4e,0x11,0xf,0xab,0x64,0xb9,0x22,0x9b,0x73,0x8a,0xb,0xdb,0x69,0x67,0x38,0x94,0xcc,0xa5,0xf9,0x7c,0x42,0xe2,0xdf,0x15,0x52,0xac,0x1b,0x46,0x2a,0xf8,0x60,0xfb,0x94,0x34,0x60,0x76,0xa1,0x47,0x2,0x94,0x48,0x8c,0x32,0x54,0x3b,0x4a,0xfa,0xd1,0x1c,0x3b,0xbe,0x72,0x3f,0x9f,0x8f,0xb4,0xef,0x97,0x99,0x86,0x78,0xe7,0xb8,0x15,0x93,0xc8,0xa7,0xe9,0x7c,0x24,0xe5,0x46,0x5c,0x10,0x5c,0x8f,0x85,0x15,0x3a,0xcb,0x3c,0x91,0xc2,0x4,0x50,0xc2,0x36,0xb1,0x32,0x2e,0xb1,0x5d,0x4e,0x8,0xae,0x79,0x9e,0xf4,0xb9,0x13,0x93,0xa,0xa2,0x4e,0xec,0x40,0xea,0xcc,0x7e,0x18,0xb,0x31,0x1c,0x17,0x64,0x4,0xce,0xd1,0xa2,0xed,0x88,0x91,0x4a,0x60,0xbc,0xf,0x78,0xbc,0x7f,0x17,0x9b,0xdd,0x2d,0xa6,0xf3,0x7b,0x70,0x3e,0xb0,0x8d,0x78,0x81,0x4f,0x41,0xdb,0x47,0x3,0xf,0x9b,0xcb,0x3c,0xa1,0x1f,0x46,0xb2,0xfb,0x75,0x3d,0xbc,0x9f,0x30,0x4f,0x13,0x9c,0xf7,0x38,0x1d,0x1e,0xb1,0xbd,0x7d,0x1,0x7,0x22,0x4a,0xfb,0x10,0xb4,0xa0,0xc5,0xfb,0xa0,0xa,0x1a,0x22,0x62,0xa3,0x36,0x89,0x96,0x19,0x28,0x2b,0x59,0x9,0x90,0x62,0x15,0x95,0xfd,0x57,0xad,0x87,0xae,0xb4,0xa6,0x7a,0x21,0xd,0x51,0xab,0xa6,0xf8,0x8b,0xc5,0x5f,0x2e,0x29,0x16,0x91,0xe3,0xd2,0x60,0xf8,0xfe,0xa3,0xce,0x5a,0xcb,0x55,0xf9,0x1,0xf4,0xa6,0x41,0x71,0x4f,0x26,0x2d,0xfa,0xd0,0x88,0x3,0x26,0xe5,0x95,0xac,0x11,0x32,0xd1,0x7b,0xe4,0xb8,0x54,0x41,0x68,0xe5,0x3b,0x2e,0xdf,0x81,0x14,0xa3,0xae,0x9,0xf3,0x74,0xc6,0xf6,0xe6,0x8e,0x6e,0x52,0xec,0xef,0xa9,0xc,0x2,0xae,0x58,0x7f,0x59,0xcd,0xec,0x83,0x53,0xd5,0x9c,0x92,0x37,0x7c,0x83,0x3,0x4a,0xfa,0x25,0xdd,0xde,0xfa,0x6,0x15,0xc5,0x43,0x38,0xe5,0x50,0xc8,0xa2,0xea,0x70,0x3a,0x3c,0x22,0x74,0x3d,0xb6,0x37,0x77,0x18,0xc6,0x2d,0x91,0x68,0x5d,0x6a,0x33,0x5f,0xe1,0xe0,0xbd,0xe3,0xb5,0xb8,0xe7,0xac,0x40,0xba,0x49,0x40,0xdb,0x7f,0xe2,0x3c,0xd8,0x88,0x61,0xb3,0xa3,0xd7,0xeb,0x7b,0xca,0x1b,0xe5,0xf5,0x40,0xec,0xc9,0x87,0xc7,0x7b,0x6e,0x78,0x27,0xeb,0x2c,0xe0,0x30,0xf0,0xda,0x12,0xba,0x1e,0x71,0x59,0xb0,0xd9,0xdd,0xd2,0x9a,0xd6,0xf,0x1c,0x95,0xd1,0x23,0x3,0x18,0xc6,0x4d,0x45,0x7c,0xfa,0x92,0xc7,0xc8,0x31,0x15,0x5a,0xd4,0xc0,0xfb,0x62,0x18,0x37,0x74,0xf3,0x24,0x25,0xba,0x79,0xc4,0x9f,0xc3,0x3c,0x4d,0xc8,0x39,0xf1,0x7a,0x39,0x10,0xa9,0xc9,0x19,0x87,0xd3,0xf9,0x84,0x10,0x3a,0x5e,0xab,0xbd,0xaa,0xfc,0xba,0xbe,0xc7,0xcd,0x8b,0x97,0x48,0x31,0xaa,0x2d,0x9b,0x4a,0x52,0x66,0xcd,0x4f,0x94,0x73,0xf2,0x30,0x6e,0xb8,0x21,0xbe,0xd7,0xf5,0x91,0xd6,0xc5,0x40,0x37,0xfa,0x78,0xe1,0xd4,0x1b,0x85,0x6c,0x65,0x5e,0xeb,0xeb,0x72,0x95,0xa7,0x5a,0x47,0x2e,0x94,0x78,0x6,0x56,0x6b,0xd7,0xa,0xed,0x15,0x1f,0xe6,0xd8,0xc2,0x5b,0xd6,0xeb,0x8a,0x24,0x6c,0xaa,0x34,0xda,0xe6,0x5d,0x57,0x51,0x79,0x6b,0xa5,0x5e,0x51,0x6,0x56,0xad,0x1c,0x17,0xca,0xbd,0xfc,0xd4,0x37,0x6e,0xf5,0xfe,0x56,0x4c,0xdd,0x5a,0xa1,0xd8,0xa8,0xfa,0xf2,0x25,0xb9,0xe7,0x3e,0x4,0x7f,0x78,0x2d,0xee,0xef,0xe9,0x15,0xa1,0xbc,0xb7,0xea,0x67,0x66,0x1,0x36,0x18,0xc,0x6b,0x4,0x0,0xff,0xcc,0x76,0x83,0xc1,0x60,0x30,0x3c,0xf,0xfc,0xe0,0x8f,0x7d,0x6,0x23,0xf,0x32,0xe9,0x4a,0xfe,0x53,0x7d,0x31,0x2a,0x76,0xc9,0x7a,0x58,0x4,0x5f,0xd8,0x43,0x6c,0x94,0x7c,0xf1,0x4e,0x77,0xf8,0x3,0xb7,0xfe,0xce,0xc5,0xbe,0x94,0x33,0x96,0xf9,0x8c,0xe9,0x7c,0xd4,0x3c,0xb9,0xd3,0x61,0x8f,0xc,0x22,0x79,0x86,0xcd,0x56,0x15,0x62,0x62,0xd3,0x94,0xff,0xe,0xe3,0x86,0x7,0xb0,0x1e,0x39,0x65,0x26,0xcb,0x68,0x68,0xa2,0x6b,0x5f,0xa7,0x2d,0x83,0x62,0xdd,0x8c,0x71,0x56,0x75,0x62,0x8c,0xb,0xe,0x8f,0xaf,0xb8,0x5,0xf1,0x40,0xdb,0x14,0x3c,0x5,0x95,0xfb,0xa2,0x8,0x8b,0xb,0x91,0x7e,0xcb,0x4c,0x99,0x78,0x87,0xc7,0x7b,0x1c,0xf7,0xf,0x6a,0xf1,0xba,0xb9,0x7b,0xd,0xb,0x13,0x9a,0xc1,0x7,0x7a,0x2c,0x2b,0x13,0x53,0xa4,0x1,0x2a,0xb1,0x42,0x2,0xac,0x30,0x71,0xde,0xc3,0x85,0x40,0x4,0xdc,0x38,0x62,0x99,0xa8,0xb5,0x56,0x5a,0x70,0xc5,0x7e,0x13,0x38,0xb3,0xf,0x70,0xe8,0xfb,0x1,0x5d,0xdf,0x15,0xd2,0xa8,0x52,0xa0,0x39,0x55,0x54,0x92,0x22,0x47,0x1a,0x9a,0x3d,0x7,0xb0,0x53,0xa3,0x6e,0xc6,0x71,0x7f,0x8f,0xe9,0x5c,0x2,0xf0,0x7d,0xe8,0xd8,0x7a,0xc6,0x41,0xf8,0x1a,0xb4,0xe,0x2d,0x27,0x89,0x71,0xd1,0x8c,0x2c,0xef,0x43,0x9,0x80,0x3f,0x9f,0x30,0x4f,0x67,0x4c,0xa7,0x23,0xe5,0x43,0xe5,0x8c,0x8e,0x9,0x4b,0x19,0xd0,0x83,0x7c,0x6e,0xde,0x69,0xa0,0xbf,0x34,0x84,0xa6,0x44,0x79,0x51,0xe7,0xd3,0x41,0x7,0x5a,0xca,0xc1,0x22,0x72,0xb1,0x1f,0x36,0xd4,0xee,0x7b,0x78,0xc4,0xb8,0xdd,0xd1,0x67,0xcf,0xc7,0x90,0xc,0x7f,0x62,0x51,0x14,0xcb,0x6e,0x8c,0xa4,0xe8,0x4c,0x91,0x5b,0x89,0x39,0xec,0xff,0xf1,0xfe,0x1d,0x1e,0xfc,0x33,0xb6,0x37,0x77,0x94,0xc9,0xe5,0x3c,0x7c,0xd7,0xe9,0xb1,0x91,0x79,0xdf,0xd1,0xf1,0xc5,0xf9,0x57,0x7d,0xaf,0x84,0x61,0xd6,0xac,0x29,0x57,0x82,0xd1,0x5d,0x69,0x54,0x75,0x95,0xd7,0x5d,0x54,0x8b,0xb9,0x1a,0x60,0xf5,0x78,0xe2,0xe3,0xee,0x78,0xd8,0x3,0x56,0x4,0x62,0xf8,0x8,0xe0,0x0,0xbc,0xfc,0x81,0x4f,0xe3,0xee,0xb5,0xd7,0xe1,0x7c,0xe0,0x5e,0xa7,0xac,0xc7,0xb8,0x16,0x6b,0x54,0xdc,0x46,0x4d,0xe,0xd4,0xe5,0xc,0xf4,0xe0,0x44,0x76,0x52,0x80,0xd5,0x5e,0xa1,0x22,0x34,0x72,0xb1,0xd0,0xeb,0x77,0x35,0x21,0xf4,0x7d,0x65,0xb9,0xa7,0x35,0x61,0x1c,0x89,0xac,0xa,0x5d,0x7,0xcf,0x2d,0xf0,0x91,0x6f,0x84,0x8,0xb9,0x57,0xb3,0x1a,0xa4,0x46,0x2c,0x4,0x90,0xdc,0x80,0x10,0x9b,0xb1,0xc4,0x53,0xf8,0xba,0xb4,0x84,0xcb,0x4d,0x64,0x9b,0x44,0xa9,0xdd,0xf,0x3,0xb0,0x2a,0x95,0x42,0xb5,0xdd,0x85,0x80,0xca,0xac,0xae,0x9e,0xb9,0x0,0xcb,0xeb,0xf7,0xdc,0xf3,0xb9,0xb0,0xeb,0x7,0x8c,0xdb,0x1b,0x20,0x43,0x33,0x47,0x37,0xbb,0x1b,0x4c,0x27,0x5a,0x6b,0xbb,0xbe,0x27,0x6b,0x33,0xa4,0x5,0x3e,0x68,0x1e,0x69,0x3f,0xc,0x70,0x21,0xa0,0xef,0xa9,0xa0,0x68,0x18,0x46,0x2a,0xbf,0xda,0x6c,0x75,0xed,0x23,0x22,0xd6,0xb5,0x5,0xd,0xd5,0xb9,0x25,0x2e,0xa4,0x38,0x97,0xf3,0x66,0x8a,0x4b,0xd9,0x46,0xb6,0x46,0x3b,0x50,0xfc,0x81,0x66,0x9f,0xe6,0xc4,0xa,0x7a,0xfa,0x48,0x43,0xe8,0xb1,0xd9,0xee,0x90,0x63,0xc4,0xb2,0x2c,0x7c,0xfe,0x19,0x95,0x60,0xdc,0x6c,0x77,0xda,0x6,0xdd,0xf5,0x3d,0xfa,0x71,0x43,0x6b,0xbe,0xa8,0xbc,0x43,0xa0,0x72,0x25,0x6e,0x97,0xe,0xa1,0xd7,0x8c,0xd4,0xf2,0xb9,0x83,0xdd,0x0,0x79,0xc5,0x7d,0xe5,0xb,0x8e,0xab,0x26,0xeb,0x5c,0x45,0x24,0xd6,0x3c,0x97,0x8,0x50,0xd7,0x2c,0x59,0xa9,0x75,0xaa,0xd5,0x7d,0x97,0x26,0xde,0x62,0xfb,0xbd,0xc6,0xb0,0xb9,0xf6,0x95,0xb4,0x2c,0x2a,0xbf,0xf,0x29,0xe7,0x2a,0x35,0x62,0x45,0xec,0xb9,0xfa,0x39,0x71,0x69,0xdb,0x75,0xcd,0x9,0xfe,0x3a,0x99,0xf7,0x7f,0x46,0xfb,0x3f,0xa1,0x6e,0x5c,0xd1,0xb0,0x52,0xf8,0x15,0x49,0xd9,0xff,0xf8,0xde,0xdb,0xb6,0x68,0x1a,0xc,0x6,0x85,0x29,0x0,0xd,0x6,0x83,0xe1,0x39,0xd,0x86,0xab,0xc6,0x37,0xb1,0x4e,0x79,0x9,0x58,0xe7,0x56,0x47,0x54,0x39,0x69,0x34,0x50,0x5,0x56,0x6,0x4a,0xeb,0x1c,0xab,0xfe,0x98,0x18,0xcb,0xdc,0x66,0x2b,0xcf,0x29,0x59,0x78,0x91,0x9b,0x6f,0x73,0xce,0x54,0x4,0xc2,0x19,0x4d,0xde,0x7b,0x6c,0x76,0xb7,0xac,0xf8,0xea,0xd1,0x8f,0xd4,0x7c,0xd8,0xf7,0x64,0x29,0x15,0x62,0xaa,0x1f,0x36,0x90,0x8a,0x5,0x7a,0xad,0x32,0x64,0xd4,0xa4,0x98,0x64,0x47,0x49,0xfb,0xa4,0x6c,0xfb,0x66,0x7b,0x8b,0x65,0xa1,0xc6,0xc5,0xf3,0xe9,0x80,0x61,0xc3,0x8a,0xc2,0x2a,0x4,0xdd,0x7,0x6a,0xa7,0x4d,0x69,0xd1,0xfc,0xb7,0x7e,0xd8,0x50,0x16,0xdf,0xb8,0xc1,0xfe,0xe1,0x15,0x76,0xb7,0xaf,0x11,0x99,0xc9,0x5,0x21,0x60,0x35,0x9c,0x77,0xa5,0xbd,0x30,0xc7,0xa8,0x84,0xa8,0x28,0xd9,0xba,0xae,0x47,0x9c,0x67,0xce,0x4e,0xa,0x44,0xfa,0x85,0xe,0xe7,0x18,0x55,0x75,0x19,0x97,0x19,0xfd,0x30,0x20,0x23,0xe3,0x7c,0x3a,0x61,0xb3,0xbb,0x61,0x45,0xe2,0xc2,0x44,0x16,0xef,0xe7,0xd0,0xb1,0x9d,0xb8,0x64,0x24,0xaa,0xa2,0xb0,0x1f,0x90,0x41,0x76,0xad,0xfd,0x3c,0xa3,0xeb,0x8b,0x6d,0x77,0x77,0xf7,0x1a,0xa6,0xd3,0x9,0xfd,0xc8,0xdb,0xc3,0x8a,0x1d,0x55,0x9c,0x30,0x1,0x19,0x40,0xad,0x94,0xd2,0x62,0x39,0x4f,0x67,0x6d,0x3d,0xce,0x39,0xe1,0x74,0xd8,0xc3,0x87,0x80,0x71,0xb3,0x83,0x73,0x9e,0x3f,0x2b,0x20,0xa6,0x88,0x78,0x66,0x5,0x4d,0x45,0xc4,0x4a,0x5b,0x67,0x8,0x1d,0x52,0x28,0x6d,0xc3,0xd3,0x89,0xda,0x87,0x4f,0x87,0x3d,0xb6,0xb7,0x2f,0x34,0x9f,0x6c,0xdc,0x8c,0x4a,0x32,0xa6,0x94,0xe0,0xf9,0x38,0xb,0x21,0x20,0xf4,0x3d,0xe2,0xfe,0x81,0x6d,0xbe,0x5b,0x1c,0xf7,0x8f,0x88,0xf3,0xc,0x17,0xe8,0x73,0xed,0x87,0xd,0xd,0xb8,0x6c,0xab,0xa6,0x52,0x10,0x57,0xd9,0x94,0x8b,0x52,0x44,0x32,0xaf,0xbc,0xf,0xda,0x3c,0x8a,0x6a,0x2c,0x14,0x12,0x30,0x23,0xc3,0x65,0xd7,0xb6,0x52,0x66,0x0,0x48,0x3a,0x20,0xa,0x67,0x98,0xaf,0x49,0x33,0x92,0x15,0x80,0x18,0x3e,0x1a,0x68,0x19,0xc1,0xda,0xe6,0x57,0x91,0xe1,0xae,0x2a,0xbe,0x69,0x8e,0xe0,0xc,0xcd,0x7a,0xcb,0x29,0x6b,0x1e,0x20,0x29,0x7,0x5d,0x69,0x76,0x77,0xa8,0xbe,0x1f,0x50,0x92,0xcf,0x39,0x22,0xd8,0x68,0xad,0x4c,0x8,0x5d,0x8f,0x91,0x73,0x39,0x65,0xbd,0x51,0x2,0x4f,0xe3,0x8,0xd8,0xde,0xb,0x22,0xdb,0xbc,0xb,0x25,0xab,0x95,0xd7,0x95,0x24,0xd9,0x7f,0xa1,0xd3,0xf5,0x15,0x4b,0x51,0xd,0xca,0xd,0x28,0xe7,0x2,0xdd,0x48,0x61,0x32,0x8f,0x1a,0x76,0x89,0x16,0xe9,0xba,0xae,0xb4,0xc3,0xaf,0xf2,0xe8,0x28,0x33,0x2f,0x34,0xc5,0x28,0x60,0xd5,0x35,0x91,0x62,0x5b,0x9c,0xe,0x8f,0xaa,0x58,0x8f,0x91,0x5a,0x82,0x43,0xe8,0x91,0xfc,0x82,0x65,0x59,0xb0,0xbb,0x7b,0xa1,0x36,0x63,0xb2,0xf6,0x6,0xf8,0x81,0x72,0x0,0xe9,0x39,0x7a,0x5d,0xd7,0x87,0x71,0xc3,0xd6,0xdf,0x9e,0x94,0x7b,0x10,0xd5,0x9b,0xf4,0xba,0x3a,0x56,0xe1,0xf5,0x4a,0x80,0x7a,0xbf,0xca,0x7e,0xe5,0x1b,0x77,0xc3,0xb8,0xc5,0x3c,0x4f,0x98,0xf3,0x9,0x1d,0x17,0x89,0x0,0xe,0x3e,0x94,0xb2,0xd,0xdf,0x75,0x25,0xba,0x22,0x2e,0xe8,0xfa,0x11,0x71,0x99,0xb0,0xbd,0x25,0xab,0x2f,0x11,0xc5,0x4c,0x7c,0x39,0x20,0x74,0x3,0x80,0x5,0xa1,0xe7,0x56,0x7a,0x21,0x27,0x5d,0x21,0xdb,0xe0,0xa0,0xe7,0x52,0x39,0x2f,0x2,0x6c,0xb3,0x76,0xa5,0x10,0xa5,0xde,0xcf,0x19,0xa4,0x98,0x84,0x14,0x2a,0xc9,0x9a,0x5b,0xd5,0x6d,0xac,0x69,0xb9,0x9a,0x94,0x76,0xf9,0x92,0xd6,0x2b,0x11,0x78,0xf9,0xe2,0x9b,0x50,0x67,0xfd,0x35,0xff,0x5a,0xb7,0xba,0x5f,0x30,0x7c,0x6b,0x25,0x60,0x29,0x7e,0x6a,0x1f,0x56,0xfd,0xee,0x85,0xd7,0x18,0x97,0xcf,0xdd,0x6c,0xc8,0xca,0xda,0x9b,0x3f,0x1c,0x99,0xf7,0x41,0xff,0x76,0x9d,0xf8,0x6b,0x55,0x8c,0x9a,0xf6,0xb1,0x2a,0x6d,0x31,0x18,0xc,0x6,0x23,0x0,0xd,0x6,0x83,0xe1,0x99,0x81,0xac,0x4f,0x62,0xfb,0xc8,0x72,0xed,0xac,0x96,0x28,0xc9,0x86,0xd3,0x3b,0xf8,0x7c,0x61,0x9b,0x35,0x7f,0x29,0x94,0x6c,0x35,0xb1,0x64,0x49,0x90,0xbc,0x3,0x11,0x85,0x31,0x2,0x29,0x21,0xc6,0x88,0xf9,0x7c,0xe2,0xfc,0xba,0xa8,0x36,0xd7,0x9c,0x12,0x10,0x2,0xfa,0x7e,0x68,0x2c,0x63,0x8e,0x7,0xf,0x6a,0x5d,0x25,0x72,0x2d,0x32,0xf9,0x48,0x73,0x9,0xf,0x67,0xf4,0x46,0x0,0x1f,0x88,0x74,0x93,0xed,0x77,0xa4,0xcc,0x10,0x2b,0x8f,0xf,0x1,0xf,0xef,0x7d,0x8f,0x2c,0x6d,0x9c,0x2d,0x75,0xdc,0x3f,0xa2,0xeb,0x6,0x9c,0x8e,0x7b,0xb5,0x22,0x3b,0x56,0x51,0x1c,0x1e,0x5e,0x71,0x91,0x43,0x79,0x4e,0xe7,0x7c,0x53,0xf4,0x21,0x3,0xac,0xfc,0x5b,0x76,0x64,0x99,0x95,0x61,0x42,0x8a,0x53,0x72,0x22,0xd5,0x4b,0xf2,0xbc,0x6d,0x19,0x1a,0x60,0x1f,0x97,0x85,0xb,0x2b,0x98,0x4,0xcc,0x41,0x15,0x64,0x85,0xc8,0x24,0x45,0x45,0xca,0x49,0xad,0x75,0x19,0x99,0x55,0x83,0x1,0x29,0x96,0xa6,0xca,0xd0,0xf5,0x3c,0x8c,0x92,0xe2,0x6f,0xbb,0xbb,0xc5,0xf9,0x4c,0xf6,0xb0,0x25,0x4,0x3c,0xbe,0x7a,0x7,0xb7,0x2f,0xea,0xd6,0x4a,0x22,0xca,0xb2,0x3,0x5b,0x87,0xb3,0x2a,0x67,0x22,0xb7,0x54,0xa,0x99,0x9b,0x98,0x88,0x4c,0x39,0x51,0x70,0xff,0xb8,0xad,0x14,0x8a,0x4c,0x1e,0x83,0x3e,0xf7,0x58,0xb5,0x72,0xd2,0x71,0x91,0xe0,0x83,0xd7,0x7c,0xbd,0x6e,0x18,0x70,0x3a,0x3e,0x62,0x73,0x73,0x87,0xe9,0x74,0xc0,0x3c,0x9f,0xf1,0x72,0x43,0x61,0xf2,0x42,0x20,0x74,0xfd,0xc8,0xf9,0x7b,0x11,0xd9,0x39,0xb5,0x1a,0x93,0x5a,0x6f,0xc0,0x90,0x28,0x33,0x31,0x2e,0x33,0xd9,0x9f,0x9d,0x23,0x5b,0x5a,0x8,0x18,0xc6,0x2d,0xb5,0x65,0x6,0xcf,0xd9,0x94,0xbe,0x34,0x87,0x32,0xb1,0x4d,0x59,0x59,0x5c,0x38,0x90,0x53,0xd1,0x88,0x30,0x59,0xa0,0x76,0x5e,0x64,0x2d,0xc6,0x91,0xe3,0xa9,0xa8,0x92,0x8a,0xaa,0x49,0x89,0xd4,0xec,0x6a,0x69,0xa,0x5b,0xd8,0x3,0x65,0x4c,0x1a,0xc,0x1f,0x5,0xaa,0x7c,0x35,0x59,0xa3,0xcb,0xb1,0x5c,0x51,0x7e,0xce,0x55,0x2e,0xc5,0xac,0xc7,0xbe,0xd8,0x21,0x8b,0xc2,0xf,0x6a,0xb9,0x94,0x78,0x7,0xe7,0x5d,0xc9,0x75,0xf3,0x4e,0xc9,0x3c,0xc0,0x61,0x18,0xc7,0xea,0xef,0x80,0x1b,0x37,0xfa,0x7a,0x5d,0xd7,0x6b,0x56,0x9c,0xe7,0x73,0x80,0x92,0x5f,0x1a,0x35,0x80,0x12,0x35,0xd0,0xd,0xc8,0x9c,0xbd,0x9a,0xaa,0x92,0xaa,0x9c,0x12,0xff,0x6e,0xd0,0xef,0x62,0x3f,0x50,0x73,0x6f,0x3f,0x6c,0x34,0x7f,0x55,0xa,0x86,0xa8,0xfc,0x88,0xc8,0x30,0xcf,0xd6,0xdd,0x79,0x9e,0x48,0x79,0x5c,0x95,0x82,0x10,0xb1,0xe6,0xe9,0x3c,0x3,0xb2,0xd0,0x3a,0x80,0x6c,0xc0,0x4c,0x4c,0x7a,0x1f,0xb0,0xbd,0x79,0xc1,0xc4,0xd8,0x56,0xcb,0xa4,0x9c,0x73,0x58,0x16,0x8a,0x87,0xe8,0xf8,0x9c,0xd0,0xf,0x23,0x6f,0x4b,0x44,0xbf,0xdb,0xe8,0xf9,0x82,0xd6,0x4b,0xc7,0xed,0xbf,0xac,0xa6,0xcb,0xd0,0x1c,0x3f,0xc7,0x37,0x88,0x64,0x7b,0x52,0x4e,0x8,0x92,0x49,0x8b,0x92,0xd9,0x3b,0x8c,0x1b,0xe4,0x7d,0x82,0x77,0x5b,0x3d,0x2f,0xc8,0x5a,0x27,0x6b,0xb6,0x64,0xe,0xa6,0x98,0x10,0x36,0x5b,0x2c,0xf3,0x44,0x8d,0xcc,0xf3,0x8c,0xae,0x1b,0x88,0xe8,0xac,0xc8,0xe1,0x14,0x17,0xc,0x9b,0x8d,0xc6,0x42,0x50,0x59,0x8b,0x10,0xa2,0xae,0x8a,0x7c,0x88,0x44,0x8,0xb2,0x32,0xbc,0x14,0xd3,0x66,0x6d,0x82,0x77,0xb9,0x34,0x3d,0x4b,0x41,0x48,0x6,0xe0,0xaa,0x22,0xa6,0x72,0xcc,0x61,0x65,0x52,0x15,0x92,0xb0,0xe4,0xb7,0xae,0xed,0xbb,0x64,0xff,0xbd,0x56,0xae,0xe1,0x2e,0xad,0xbe,0xf9,0x82,0x2a,0x6f,0xff,0x2e,0xfb,0xd6,0xbd,0x4f,0xae,0xde,0xfa,0x39,0xb2,0x6b,0x89,0xb9,0xb,0x25,0x9f,0xbb,0x24,0xef,0xd6,0xdc,0xe3,0x15,0xe2,0xf2,0x29,0x32,0xcf,0x3d,0x41,0x8,0x3a,0xb8,0xf7,0xfd,0x7b,0xbd,0x34,0x18,0xc,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0xff,0x1,0x64,0x50,0xaa,0x2f,0x92,0x33,0xd0,0xe4,0xc0,0x8,0xc1,0x25,0xa0,0x6,0xc8,0xa8,0x21,0xed,0x0,0xb0,0xcc,0x93,0x92,0x6c,0xe5,0x12,0xbd,0x28,0x2,0xeb,0x56,0xba,0xf3,0xe9,0x8,0x1f,0xbc,0x2a,0xbd,0x9c,0xa7,0xc1,0x67,0x9e,0x27,0x6c,0x6f,0x6e,0x49,0xbd,0x96,0xb3,0xe,0x48,0xa1,0x1f,0x10,0xc0,0xad,0x93,0xa0,0x1c,0x21,0xef,0xb9,0xe9,0x75,0x99,0x74,0x58,0x91,0xd6,0x4a,0xd9,0x5e,0x79,0x6f,0x3e,0x4,0x56,0x79,0x50,0x29,0xc4,0xf9,0x74,0x50,0xd5,0xc8,0xf9,0x74,0xc0,0xb8,0xdd,0x51,0xeb,0x2c,0x13,0x7f,0xd2,0x1e,0x3b,0x8c,0x5b,0x1c,0xf6,0xf7,0xd8,0x6c,0x6f,0x70,0xff,0xee,0xdb,0x88,0xac,0xf6,0x8b,0xd1,0x21,0xce,0x13,0x16,0xce,0x95,0x13,0x25,0x60,0xd7,0xf5,0x70,0x39,0xac,0x14,0x2f,0xa5,0xa9,0x91,0x27,0x9c,0x86,0x3c,0x22,0xe5,0x6,0xef,0x23,0x1e,0x9e,0xb6,0x37,0x23,0xa9,0x2f,0x38,0xdf,0x29,0xf1,0xfb,0xa6,0xa0,0xf7,0x99,0x89,0xbd,0xa0,0x4a,0x47,0x69,0x49,0x9e,0xce,0x47,0x84,0xae,0xc7,0x3c,0x9d,0x21,0xb6,0x35,0x6a,0x7a,0xc,0x48,0x71,0x21,0xc2,0x8f,0x89,0x2a,0x29,0xef,0x18,0x37,0x5b,0xa,0x92,0xef,0xa8,0xc0,0x25,0xce,0x73,0x9,0x9a,0x5f,0xc8,0x46,0x96,0xe2,0x82,0xf3,0xf1,0xa0,0xf9,0x5b,0xa7,0xe3,0x1e,0xfd,0x30,0x22,0xb3,0x8d,0x8c,0x9a,0x77,0x3b,0x25,0x30,0xbb,0x8a,0xc,0x16,0x22,0x92,0x6c,0xda,0x6c,0x1,0x13,0xcb,0x35,0x5b,0xf7,0xa6,0xd3,0x1,0x0,0x70,0x73,0xf7,0x12,0xe7,0xe3,0x11,0xfd,0x98,0x31,0x8c,0x23,0x22,0x7f,0x6,0xce,0xb3,0xb2,0x2e,0x25,0x22,0x79,0xa5,0x54,0xa4,0x97,0xc1,0x7e,0x40,0x3f,0x8c,0xd4,0x82,0xb9,0xcc,0x98,0xe7,0x89,0xc8,0xbf,0x65,0xc6,0xcd,0x8b,0xd7,0x55,0x85,0xe4,0x9c,0x67,0x8b,0x74,0xd0,0x12,0x18,0x31,0x81,0x51,0xe1,0x41,0x69,0xfe,0x95,0x2,0x1,0x5f,0xe5,0x6d,0xc9,0xf0,0xda,0xe,0x67,0xae,0xb2,0x29,0xf2,0x77,0x48,0x14,0x80,0x6b,0xb2,0xcf,0xc8,0x3f,0xc3,0x47,0xc7,0xfe,0x35,0xa5,0x3e,0xd,0xcb,0xc0,0xdf,0x43,0xcd,0x78,0xe5,0x1b,0x19,0x42,0x12,0xa,0x51,0x4e,0x6b,0x6e,0x42,0x4a,0x42,0xa,0x86,0xa2,0x76,0x96,0x63,0x3b,0x97,0x28,0x86,0x94,0x12,0x92,0x17,0xfb,0xbf,0xe4,0xf4,0x79,0x78,0x97,0xe1,0xba,0x1e,0x89,0xd7,0x67,0x39,0x87,0x38,0xfd,0x2e,0x79,0x56,0x9d,0x83,0x4b,0x2b,0x5c,0x53,0x14,0xe1,0x40,0x37,0x27,0x44,0xf9,0x2d,0x36,0x66,0xf9,0x9e,0xca,0xb9,0x41,0x94,0x8a,0xa5,0x28,0x29,0x21,0xf0,0x7a,0x18,0x58,0xc1,0x2e,0xa,0x6f,0x21,0x43,0x24,0xff,0x54,0xd6,0xe8,0xa8,0x39,0xb6,0x51,0xed,0xb4,0x42,0x62,0x7a,0x1f,0xd0,0x7b,0x8f,0x65,0xa2,0xc,0xbf,0x24,0xeb,0x7a,0xee,0x31,0x4d,0x27,0xb2,0xe3,0xb2,0x42,0x7d,0xb3,0xbb,0xd1,0xb2,0x10,0x1f,0x3a,0xbd,0x91,0x10,0xba,0xe,0x91,0xc9,0x41,0x5a,0xdf,0x88,0x34,0x1b,0x37,0x3b,0x2d,0x66,0xa1,0xec,0xd9,0x23,0xe5,0xa0,0x3a,0x8f,0x9c,0x29,0x3f,0x37,0x74,0x52,0xb2,0x15,0xe1,0x3d,0x9d,0x2f,0xfb,0x3e,0xeb,0xf9,0xb8,0x1f,0x36,0x88,0xcb,0xac,0xf9,0xb2,0x75,0xae,0x9e,0xf7,0x1,0x99,0x3f,0x9b,0xae,0xa7,0x9b,0x5e,0x1d,0xaf,0x5b,0xbb,0xbb,0xd7,0xe8,0x5c,0xc3,0xe7,0xa5,0x92,0xfd,0x5b,0xd6,0x48,0x3a,0x5f,0xf1,0x1a,0xc9,0xe4,0x9f,0xa8,0xfc,0x8a,0x7b,0x80,0x8f,0x1f,0xef,0x9b,0x52,0xb0,0x9c,0x59,0x81,0xc7,0xe7,0xeb,0x72,0x4c,0xf2,0x95,0x43,0x2e,0x24,0x9b,0x96,0x70,0xa8,0x3a,0xaf,0x31,0x84,0xaf,0xb8,0xb2,0xf,0x53,0xa8,0x51,0xce,0xc3,0x17,0x16,0xde,0x6b,0x9c,0xe1,0xfa,0xcf,0xf9,0x43,0x7e,0xd7,0xf4,0x4f,0xee,0x43,0x3c,0xda,0xbd,0xef,0x73,0xd7,0x76,0xdd,0xfa,0xda,0xca,0x35,0xe4,0xe7,0x25,0x15,0xba,0x56,0xfb,0xad,0x33,0xff,0x72,0x65,0x65,0xd6,0x7c,0x50,0x76,0x4a,0x18,0xc,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0x4c,0xd1,0xb6,0xea,0x15,0xe5,0x1e,0xb7,0x4c,0xd0,0x10,0x28,0xa,0x29,0x1f,0x90,0x72,0x64,0x45,0x80,0x53,0x42,0x4e,0x95,0xa,0x28,0xa1,0xdd,0x32,0xc,0xf5,0xfd,0x88,0xf3,0xe9,0xa0,0x17,0xef,0xd3,0xf9,0xa8,0x2d,0x8c,0x12,0x50,0xee,0xbd,0xc7,0x66,0x7b,0x53,0x5a,0x1,0x79,0x68,0x70,0x20,0x3b,0xa9,0x8b,0x4b,0xf3,0x73,0x40,0x1a,0x20,0x4b,0x53,0xab,0xe7,0x92,0x89,0x85,0xdb,0xe,0x5d,0x5d,0xce,0x0,0xca,0x3e,0xda,0xde,0xdc,0x69,0xdb,0xe4,0x61,0x7f,0x8f,0xb8,0xcc,0xd8,0xee,0xee,0xc8,0x16,0x7b,0xfb,0x1a,0x82,0x10,0x56,0x3c,0xf0,0xe4,0x4c,0xd,0xc0,0x33,0x67,0xdf,0x11,0x91,0x16,0x31,0xc,0x1b,0x52,0xd9,0xa5,0x88,0x8e,0x83,0xd9,0x3d,0x2b,0x1d,0x45,0x75,0x27,0x76,0xac,0x9a,0xa4,0x3,0x80,0xc0,0x16,0x39,0x52,0x72,0x2c,0x98,0x4e,0x27,0xcd,0xd9,0x93,0xfc,0xa4,0x9c,0x33,0x96,0xe9,0x8c,0x61,0x18,0x75,0xf0,0xc,0x5d,0x87,0x79,0x9a,0xf8,0xf3,0x21,0x22,0x4b,0xd4,0x7a,0x32,0xd8,0x16,0xa5,0xa,0xd0,0x75,0x44,0x8e,0x39,0xe,0x68,0x1f,0x36,0x3b,0x2c,0xf3,0x2b,0xcc,0xd3,0x89,0x6,0x73,0x26,0xe5,0xa8,0x25,0xd9,0x2b,0x11,0x3a,0x9d,0xa8,0x54,0x25,0x2e,0x94,0xdb,0x18,0x97,0x99,0xb2,0x10,0x53,0xc2,0x3c,0x9f,0x31,0x8c,0x5b,0x8c,0xdb,0x1d,0x17,0x70,0x10,0x89,0xe7,0xa5,0x58,0x83,0x7,0x3a,0x6a,0x3c,0xee,0x55,0xc1,0xa8,0xd,0xbc,0x92,0x3f,0xc8,0x4d,0x9f,0xde,0x79,0xc,0x1b,0xb2,0xaa,0x1d,0xf7,0xf,0x54,0xdc,0x31,0xc,0xa0,0x2e,0x80,0xc0,0x85,0x2f,0x33,0x2,0x7a,0xcd,0x99,0x92,0xc1,0x52,0x54,0x80,0x7d,0x3f,0x60,0xf2,0x94,0xdf,0xd5,0x8f,0x64,0xd3,0xe,0xa1,0xa3,0x6,0xce,0xaa,0xd5,0xb2,0xe3,0x3f,0x8b,0x3d,0x4d,0xc8,0xc,0x9d,0xbb,0x44,0x9d,0xc2,0xea,0xc0,0x32,0x97,0x12,0xb9,0xd7,0x6,0xf2,0xe7,0x66,0x4,0x55,0x85,0xb,0xd6,0x4e,0xaf,0xb6,0x95,0xb2,0x56,0x56,0x19,0xc,0xdf,0xe7,0x95,0xfe,0x89,0x70,0xff,0xac,0xa5,0x1e,0xa4,0x68,0xce,0xba,0xb6,0xca,0xb9,0x40,0x88,0x32,0x2d,0x9e,0x80,0x74,0x88,0x24,0x25,0x7b,0x72,0xca,0x28,0x37,0x8f,0x12,0x32,0x2a,0x22,0xc8,0x57,0xcf,0xeb,0x49,0x35,0x2e,0x85,0x49,0x92,0xbb,0x9,0x40,0x6f,0x24,0x48,0x6e,0xa8,0xde,0x50,0xca,0x99,0xa2,0x15,0x34,0xef,0xf,0xfa,0x9d,0xcc,0x40,0xb3,0xdd,0xd2,0xa4,0x4e,0xef,0xa7,0x43,0xce,0xbc,0x7e,0x86,0xe,0x8,0xe,0xcb,0x7c,0x2e,0x64,0x8,0x9f,0xf3,0x3a,0x8e,0x2e,0x98,0xe7,0x89,0x9,0x3e,0x34,0xa4,0x7e,0x89,0x9a,0xa0,0x96,0x61,0x51,0x65,0x4b,0x74,0x82,0xaf,0xed,0xb0,0xbc,0xd3,0x46,0xbf,0xd3,0xec,0xd9,0x9e,0xd5,0x75,0xe3,0x96,0xa2,0x1c,0xa4,0x2c,0x44,0x62,0x29,0xe8,0xfd,0x3b,0x8d,0xda,0xa0,0xd7,0x9c,0x79,0xbb,0x3,0x13,0x7c,0x1,0x8e,0x15,0x8e,0x40,0x66,0x3b,0x31,0x9d,0x6b,0xe0,0xa2,0x92,0xa0,0x9e,0xd5,0xe9,0xa9,0xca,0x7c,0x85,0x44,0x4f,0xa4,0x48,0xb4,0x11,0x37,0xa0,0x3b,0xef,0xb5,0xe8,0x8b,0x6e,0xc2,0x85,0xa6,0x9,0x1e,0x7d,0x56,0x35,0xb9,0xb4,0x40,0x83,0x89,0x55,0xe7,0x68,0xfd,0x74,0x89,0xb,0x8e,0x0,0xde,0xbe,0x58,0x72,0x82,0x19,0xe5,0xdf,0x5d,0xa3,0xe8,0xf3,0x4c,0xc2,0x82,0xcf,0x5,0x7a,0x78,0xaa,0x85,0x5c,0x8e,0x34,0x57,0x35,0xdb,0xd6,0xa5,0x15,0x6e,0x75,0xc,0xe7,0xb6,0xba,0xb7,0xb6,0xe5,0x5e,0x48,0xe4,0x72,0x95,0xd3,0x87,0x55,0x3,0x6e,0x65,0xcf,0xbd,0x8,0x25,0x6c,0x7f,0xf8,0xb4,0xf5,0xf6,0x7a,0x6b,0x47,0x4b,0xd6,0xb9,0x86,0x94,0xbb,0xcc,0x2a,0x5c,0x47,0x49,0xb4,0x3a,0xc8,0x6b,0x2f,0x51,0x6e,0x69,0x7d,0x40,0x31,0x49,0xc6,0x13,0x85,0x21,0xce,0xe4,0x80,0x6,0x83,0xe1,0x2,0xde,0x76,0x81,0xc1,0x60,0x30,0x3c,0x27,0x2,0x30,0x95,0x3b,0xbf,0x7c,0xd1,0x1b,0x97,0xc8,0x2d,0xb5,0xe5,0x4e,0x71,0x46,0x46,0x4c,0x8b,0xde,0x29,0x16,0x5b,0x90,0xe6,0xf3,0x2d,0x4b,0x19,0xca,0xaa,0x41,0x73,0x3a,0x9f,0xe0,0x3,0x91,0x37,0xcb,0x4c,0xb9,0x46,0xf3,0x74,0x26,0xf2,0x2a,0x27,0x6e,0xf1,0xed,0xa8,0xb4,0x82,0x9,0x19,0x9,0x97,0x77,0x6c,0x15,0x95,0x16,0x62,0x21,0xd4,0x68,0xb0,0x5a,0x54,0x39,0xe2,0x39,0x9b,0x2a,0xb3,0x55,0x4d,0xc9,0x43,0x56,0xa4,0xc9,0xd0,0xb1,0xcc,0x33,0xbc,0xa3,0xb6,0xe1,0x61,0xd8,0x60,0x99,0x67,0xb5,0xde,0x2e,0x4c,0x42,0x11,0xa1,0x19,0xa8,0x39,0x57,0x32,0xf7,0x7c,0xe0,0x90,0xfa,0xc0,0xe5,0x1a,0xa5,0xe9,0xb8,0x58,0xce,0xbc,0x5a,0xd8,0xc4,0x5e,0x2c,0xd6,0xa8,0x5c,0xdd,0x55,0x8f,0xcb,0xa2,0x76,0x2c,0x20,0x13,0x1,0x36,0x9d,0x10,0xe7,0x59,0x87,0x62,0xc9,0x79,0x8a,0xcb,0x42,0x6a,0xba,0xc4,0xfb,0xc9,0x79,0xb6,0x4f,0x2f,0x98,0xa6,0x93,0x5a,0xa4,0xbb,0xae,0x27,0x7b,0x1a,0x40,0x16,0x6b,0x2e,0xd7,0x10,0xa5,0x5d,0xd7,0xf5,0xd8,0xee,0x6e,0xd1,0xf,0xa3,0xda,0x6b,0xe1,0x1c,0x8e,0xfb,0x7b,0xec,0x1f,0x5e,0xe1,0xf8,0x78,0x4f,0x65,0x1a,0xfb,0x7,0xc4,0x65,0x26,0x3b,0xee,0x74,0xc2,0x74,0x3e,0x62,0x3a,0x9f,0x28,0xa7,0x91,0x33,0x7,0x97,0x79,0xd2,0x36,0xdf,0x14,0x89,0x0,0x8,0xa1,0xa3,0x42,0x14,0x2e,0xd3,0xa0,0x12,0x92,0x59,0x73,0x22,0x45,0xc5,0x48,0xfb,0x2e,0x21,0xe5,0x8c,0x71,0xbb,0x63,0x9b,0x1b,0xd,0xbd,0x21,0x4,0x2c,0x13,0x15,0x97,0x84,0xd0,0xf1,0xbe,0xcc,0xe5,0xb0,0x64,0x4b,0xb4,0x1c,0xaf,0xb5,0x2d,0x3d,0x74,0x1d,0x37,0x8b,0x92,0x95,0xb0,0xe3,0x52,0x18,0x79,0xbc,0x90,0xc4,0xd2,0x70,0x48,0xaa,0x45,0xa7,0xf9,0x84,0xe0,0xa6,0x4f,0x51,0xf5,0x94,0x5c,0xcc,0x3a,0xeb,0x2f,0xeb,0xf0,0x5d,0x5a,0x54,0x5b,0x5b,0x5b,0x11,0x99,0xb4,0x3,0xa7,0x7c,0xfe,0xd9,0xa,0x40,0xc,0x1f,0x11,0xd4,0x66,0xb9,0x22,0x1,0x55,0xed,0x5d,0x1d,0xf3,0xa4,0x9c,0x2e,0xc5,0x20,0x14,0x55,0x90,0x5b,0x61,0x50,0xce,0xcd,0xf3,0xd1,0x63,0xda,0xe3,0x3d,0xd5,0xca,0x58,0xbe,0xe9,0xa1,0x56,0xd7,0x8e,0x48,0xfd,0x7e,0x18,0x11,0x44,0x49,0x8d,0xac,0x37,0x5f,0xf4,0x65,0x58,0x39,0x58,0x93,0x8f,0x80,0x43,0xe4,0xc7,0x39,0x56,0x84,0x8b,0x12,0xb9,0x2e,0xfc,0x48,0x31,0x96,0x16,0x59,0x56,0xa0,0xf5,0xc3,0x88,0x61,0xdc,0x56,0x16,0x57,0xba,0xd9,0xb1,0x70,0x26,0x9f,0x96,0x5f,0xc9,0xd,0x30,0xfe,0x3d,0x51,0x7f,0xcb,0xba,0x4d,0xb9,0xab,0xa5,0xf1,0xd7,0x73,0x4b,0xb9,0xe4,0xe1,0x49,0x56,0x6b,0xd7,0xf7,0x7c,0x3,0xa7,0xd7,0xb5,0xaa,0xeb,0x7a,0x2a,0xe5,0xf0,0x1e,0x3e,0xd0,0xdf,0xbb,0xbe,0x47,0xf0,0xa1,0x6c,0x3,0x88,0x68,0xa3,0xd6,0x77,0x26,0xd2,0xe4,0xe6,0x14,0xdf,0x7c,0xf3,0x41,0x72,0xd,0xcb,0xf9,0x57,0xf6,0x99,0x3,0x78,0xbf,0x52,0x93,0x71,0x21,0x11,0xbd,0x12,0xab,0xb2,0xce,0xd2,0xda,0x4d,0xc5,0x20,0x5e,0x72,0xff,0x50,0xdc,0x1,0x81,0xff,0x9b,0x55,0x31,0xe9,0xca,0x39,0x90,0x49,0x4a,0xb2,0xf3,0x12,0x11,0x29,0x6b,0xaa,0x1c,0xb,0xb2,0x3e,0xae,0x8f,0x3d,0x59,0xc3,0x91,0xa1,0xe7,0xfe,0xa2,0xe9,0xcb,0x4d,0x7b,0x6f,0xbd,0xb6,0x3a,0xbd,0x91,0xa2,0x81,0xab,0x97,0xe4,0x5f,0x4d,0x68,0x55,0x4f,0x59,0x8,0x2f,0x77,0xe5,0x67,0x58,0x11,0x8b,0x68,0x9,0xc2,0x8a,0x80,0xbc,0xcc,0xd2,0xbb,0x7c,0x8e,0xfa,0x71,0xeb,0xd2,0x8d,0xb6,0xe7,0xa3,0xbd,0xce,0xca,0xd5,0x9f,0x71,0x85,0xfe,0xab,0xdf,0x42,0xfd,0xfa,0xf9,0x22,0x7f,0x10,0x57,0x48,0xc4,0x27,0xc8,0x3f,0xdd,0x38,0x53,0x0,0x1a,0xc,0x6,0x23,0x0,0xd,0x6,0x83,0xe1,0x99,0x13,0x80,0x9c,0xd,0xe3,0xbc,0x5e,0x94,0xeb,0xd,0x77,0x57,0x5f,0x1b,0x16,0xe3,0x9,0xb4,0x3c,0x21,0xb2,0x6d,0xb,0x4c,0xca,0x2c,0xaa,0xbe,0x90,0xc1,0x8d,0x54,0x84,0x89,0x49,0xb6,0x19,0xe7,0xe3,0x81,0x9a,0x56,0x63,0x54,0xa2,0xb,0xa0,0xe6,0xc4,0xbe,0x1f,0xd0,0x75,0x3,0x2b,0x24,0x6a,0xeb,0xa5,0xd7,0xcc,0x40,0xb1,0x77,0x95,0x72,0xd,0x19,0xf0,0xa2,0xe6,0x19,0x8a,0x3a,0x2c,0xc6,0x59,0xb7,0xc7,0x87,0xe,0x9b,0xdd,0xd,0xba,0x61,0xc4,0xcd,0x8b,0xd7,0x54,0x4d,0x76,0x3e,0xee,0x71,0x3a,0xee,0x89,0x1c,0x64,0x4b,0x73,0xae,0x2c,0x71,0xf2,0xbf,0xb8,0x2c,0x38,0x3c,0xdc,0x13,0x1,0x9,0x6e,0xa3,0x94,0xf6,0x5b,0x6d,0x3e,0x6e,0x6d,0x9f,0x62,0x51,0x2b,0xb9,0x5b,0xa9,0x69,0xf0,0xa5,0xd6,0x46,0x1a,0x1e,0x37,0x37,0x77,0x44,0x10,0xb2,0xbd,0x57,0x8,0x29,0x19,0xf4,0x28,0xf7,0xb0,0x1e,0xd2,0x89,0x28,0x8c,0xcb,0x82,0x65,0x99,0x79,0x40,0x4d,0x9a,0xa1,0x8,0x6d,0x73,0xf6,0xe8,0x86,0x1,0x21,0x74,0xd8,0xec,0x6e,0x49,0x49,0x97,0x12,0x96,0x79,0xc2,0xfe,0xfe,0x15,0xa6,0xd3,0x11,0xf,0xef,0x7d,0xf,0xf7,0xef,0x7e,0x4f,0x49,0xd0,0xe3,0xe1,0x11,0xf3,0x44,0xed,0xc4,0xa7,0xc3,0x23,0xe,0xfb,0x7b,0x1a,0x6c,0x7d,0x40,0x37,0x70,0x53,0xe5,0xb8,0xe5,0x16,0x4d,0xb2,0x84,0x53,0x53,0x30,0xd,0x87,0x52,0xa4,0x52,0xef,0xbf,0x10,0x7a,0xb2,0x87,0xb1,0x22,0x25,0x2e,0x54,0xe8,0xe2,0x1c,0x30,0x6c,0xb6,0xf0,0xdc,0x7a,0x49,0xa,0x40,0x5f,0xd4,0x94,0x9a,0x23,0x55,0x8a,0x54,0x12,0x2b,0x52,0x28,0xf,0xd2,0xb1,0x45,0x2f,0x61,0xd8,0x6c,0x11,0x63,0x44,0x3f,0x8c,0xd8,0x6c,0x6f,0xb8,0x75,0x34,0xe8,0xbe,0x76,0xbc,0x6d,0xce,0x79,0x25,0xf3,0x24,0xbb,0x51,0x42,0xf2,0x93,0x7e,0x46,0xbe,0x1a,0x46,0xcb,0x31,0xaf,0xd9,0x69,0x8e,0x33,0xae,0x5c,0x35,0x7c,0xa2,0xb5,0xce,0x6b,0xb3,0xa5,0x5b,0x15,0x1d,0x18,0xc,0x1f,0xcd,0x6a,0xdf,0x12,0x8,0x15,0xf9,0x21,0x4a,0x62,0x21,0xe1,0xd4,0x1e,0x5f,0x13,0x77,0x92,0x83,0xb9,0x22,0x1d,0x72,0x2e,0x59,0x81,0x59,0x48,0x1d,0x25,0x9,0x93,0xae,0x47,0xb2,0x9e,0xe7,0x94,0x9b,0x73,0x88,0xe4,0xc0,0xca,0xcd,0x1b,0xfb,0x94,0xe2,0x45,0x0,0x0,0x19,0x99,0x49,0x44,0x41,0x54,0x21,0x1c,0xb5,0xe4,0xc1,0x95,0x73,0x90,0xab,0x6c,0xa0,0x89,0xf3,0x4b,0xe5,0x3b,0x27,0xff,0x2e,0xf9,0xb4,0xb5,0x25,0x58,0x94,0x7d,0x4a,0x6,0xfa,0xda,0xd2,0xea,0x11,0xfa,0x81,0xd7,0x2c,0x3a,0x77,0x81,0x9,0x7f,0xf9,0xce,0x8a,0x42,0x52,0x54,0xe0,0x42,0x14,0x66,0x2e,0x48,0xc9,0x52,0x24,0xc4,0xaa,0xc4,0x9c,0x93,0x92,0x9e,0x72,0xae,0x68,0xd7,0xfd,0xa0,0xaa,0x64,0x27,0xe7,0xb4,0x7a,0xd8,0xe2,0x9b,0x5a,0xb2,0x2e,0x69,0x4b,0x33,0xa8,0xe9,0x5d,0x22,0xb,0x68,0xff,0x41,0x95,0xdf,0x72,0xee,0x85,0x10,0x93,0xfc,0x3a,0x4a,0xf8,0x1,0x8,0x21,0x5c,0x21,0xe3,0x62,0xb1,0xd8,0x56,0x4a,0x46,0xde,0x98,0xe6,0xbc,0x55,0x3e,0x9b,0xa4,0x9f,0xbd,0xb4,0xa0,0xeb,0x75,0x81,0xae,0x75,0x25,0x1b,0x55,0xaf,0xb,0xaa,0x3,0x2f,0xe9,0x39,0x52,0x1e,0x5b,0xab,0xef,0x1c,0x2e,0x5a,0x6b,0x38,0x4f,0xb7,0x21,0xb2,0xea,0x8b,0x95,0xbc,0x2e,0xd2,0xc8,0x4f,0xf2,0x7a,0x2d,0x39,0x96,0xaf,0x13,0x66,0x2b,0xd2,0x70,0xad,0xf8,0xcb,0xef,0xf3,0x7f,0xf5,0x63,0x9c,0x3e,0xb6,0xbd,0xf6,0xfa,0xb0,0x54,0xdb,0xd3,0x44,0x63,0xbe,0xfe,0x13,0x77,0x85,0x35,0xcc,0x57,0x48,0xc0,0xd5,0x2f,0x1a,0xf5,0x67,0x30,0x18,0xae,0xc1,0x2c,0xc0,0x6,0x83,0xc1,0xf0,0xc,0x49,0xc0,0xcc,0xf6,0x2a,0xb9,0x68,0x16,0x55,0x20,0xd,0x3c,0x9,0xf0,0xa2,0x0,0x28,0x4,0x1c,0x52,0x42,0xca,0x11,0x8e,0x89,0x2f,0xe7,0x3b,0xb5,0x81,0x66,0x57,0x48,0x94,0x25,0x2d,0x6a,0x1b,0xde,0x6c,0x6f,0x70,0x3a,0x3e,0xc2,0x7,0xaf,0xd6,0xab,0xdd,0xcd,0xb,0x55,0x52,0x84,0xae,0x55,0x29,0x50,0x80,0xfa,0x84,0x2e,0x74,0x6c,0x3b,0x9e,0xb5,0x40,0x43,0x14,0x10,0x1a,0x4e,0xcf,0x83,0xa4,0x34,0x45,0x4a,0x3,0xb0,0x58,0x63,0x29,0xef,0xa8,0xc7,0xee,0xf6,0x85,0xaa,0x21,0x44,0x25,0xb2,0x2c,0x13,0xfa,0x61,0xc4,0x7c,0x3e,0xa1,0x1f,0x46,0x55,0x6d,0x6c,0xb6,0x37,0xc8,0x39,0xe3,0x8e,0xdb,0x75,0x87,0x71,0x43,0xf6,0xdb,0x79,0xe2,0x61,0x2e,0x20,0xc5,0xca,0xa6,0x54,0xf,0x49,0x42,0x5e,0x49,0x96,0x1c,0x84,0xd0,0xc,0x38,0x9f,0x1e,0x34,0x9c,0x7d,0xdc,0xec,0xb0,0x4c,0x53,0x95,0xd7,0x17,0x91,0x42,0x42,0xd7,0x89,0x5,0xed,0xac,0x59,0x52,0xa4,0x44,0x8b,0x55,0x3,0x70,0xd4,0x36,0xc8,0x54,0xb5,0xe,0xf3,0x74,0xc5,0x3,0x38,0x37,0x6f,0x6e,0x76,0x8,0x81,0x54,0x21,0xcb,0x3c,0x3,0xdb,0x1d,0xa6,0xf3,0x9,0xe3,0x76,0x87,0xd3,0x61,0x8f,0xf3,0xf1,0x40,0x59,0x7a,0x5c,0xc2,0x22,0xed,0xc8,0x3,0xef,0xe7,0x65,0x59,0x30,0x6c,0xb6,0x6a,0xd9,0xd3,0x86,0xdf,0x79,0xe6,0x66,0x5d,0x26,0xd7,0x78,0x92,0x90,0x6c,0xc2,0x92,0x3b,0xb8,0x54,0x9f,0xab,0xe7,0x7d,0x3c,0xe0,0xe6,0xae,0xd8,0x85,0xe5,0x73,0xe9,0xfa,0x41,0xf7,0x9f,0x90,0xce,0x6a,0xeb,0x76,0x2b,0x5,0x4a,0xd7,0x63,0xdc,0x6c,0x11,0xe6,0xe,0x2f,0x3f,0xf9,0xa9,0xca,0x5a,0x38,0x14,0x92,0xd5,0x95,0xe3,0x80,0x94,0x7e,0x5d,0xa3,0x56,0x4d,0x31,0x69,0xd6,0x99,0x14,0x18,0xa4,0x9c,0xb8,0xe0,0xb7,0x62,0xc4,0x99,0xec,0x93,0x3c,0xb2,0x4a,0x24,0x78,0x31,0x49,0xd5,0xad,0x94,0x29,0x65,0x55,0x23,0x19,0xc,0x1f,0xc5,0x1a,0x4f,0x2a,0xb1,0x7c,0xf5,0xdf,0x68,0x5d,0x72,0xd,0xf1,0xa6,0xb9,0x7e,0xd2,0x7c,0xb,0xa7,0xe4,0x5c,0xf9,0xbd,0xcc,0x56,0x5f,0x65,0x5c,0xf4,0x66,0x88,0xb6,0x65,0x6b,0x1,0x84,0x57,0x26,0x42,0x96,0x28,0xfa,0xae,0x42,0x15,0x7c,0x65,0x5b,0x8a,0x5,0x59,0x88,0x20,0x21,0xe1,0x72,0xd5,0x48,0xf,0xe7,0xab,0x73,0x58,0x59,0x13,0xca,0x77,0xdb,0xa9,0xb2,0x3a,0xa5,0xc4,0x16,0x63,0xda,0x17,0x39,0x67,0xcd,0xf7,0x43,0xca,0xda,0x52,0x5b,0x97,0x57,0xd1,0x79,0x26,0x20,0x54,0xd,0xc9,0x92,0x2f,0x28,0x65,0x1c,0xce,0x39,0x2a,0x28,0xaa,0x14,0xf1,0x75,0xab,0x6b,0x21,0x53,0xe9,0x3d,0x6b,0xeb,0xbc,0xc4,0x65,0x70,0xc4,0x45,0xf6,0x59,0x2d,0xb9,0xa4,0xb2,0xa7,0xe2,0xa3,0xcc,0xa,0x69,0xf9,0x9d,0x28,0x37,0xba,0x72,0x54,0x5,0xa7,0x66,0xf0,0xf1,0x4e,0x73,0x80,0xae,0x75,0xb5,0xd2,0x59,0x9a,0x5b,0xea,0xc8,0xe,0xc9,0x19,0x5c,0xb8,0x78,0x8b,0x83,0x5a,0x11,0x78,0x9f,0xe5,0x18,0xab,0xcf,0xce,0xb1,0x92,0xd9,0x35,0xd6,0x6b,0xb9,0xf1,0x23,0x59,0xbc,0x5a,0xce,0x95,0xab,0xec,0x54,0x39,0x5f,0xca,0x3a,0xb8,0x6a,0xdd,0x2d,0x2d,0xbb,0x25,0x8a,0x24,0xa3,0xd8,0x8e,0xe9,0x86,0x62,0x7e,0xc2,0xba,0x9a,0x71,0xe1,0xa0,0xbd,0xd6,0x1,0xf2,0x3e,0xc4,0x5a,0x5b,0x94,0x91,0x1b,0xd2,0xaf,0x7d,0x9a,0xb5,0x6d,0x37,0x5f,0x3c,0xee,0x29,0x9a,0x4e,0x6e,0x42,0x15,0xe2,0xf2,0x7d,0x1f,0xfc,0x4,0x29,0x99,0xcb,0x77,0x2,0xab,0x66,0x65,0x25,0x41,0xcb,0x76,0x95,0xfd,0x21,0xe5,0x24,0xab,0x6,0xe2,0xea,0x55,0x9e,0xd8,0x4d,0x6,0x83,0xc1,0x8,0x40,0x83,0xc1,0x60,0x30,0x3c,0xb3,0xf1,0x50,0x7,0x7,0x24,0xa8,0xba,0x0,0x6c,0x71,0x15,0x52,0xa,0x72,0xd7,0x1f,0xe0,0xcc,0x1e,0x69,0x87,0xe4,0xc2,0x7,0xce,0x9c,0x13,0xa2,0x26,0xa7,0xc8,0xcf,0xc5,0x76,0x5e,0x4,0x4c,0xe7,0x13,0x42,0x37,0xe8,0x60,0xa0,0x3,0x0,0xb7,0xea,0x8a,0xda,0x24,0xf4,0xbd,0xe,0x6e,0x92,0xff,0x24,0x4a,0x2b,0x9,0x77,0x2f,0x2a,0x92,0xa4,0xf6,0x24,0x6a,0x8e,0x1d,0x54,0xfd,0x51,0x2b,0x7,0x9d,0x77,0x18,0x86,0xd,0x4e,0x31,0x62,0x18,0x37,0x4d,0x3b,0xa3,0xd3,0x42,0x8b,0xc0,0x79,0x7f,0x1d,0x97,0x59,0x50,0x8e,0xe1,0x82,0x33,0x9c,0x1b,0x1,0xe7,0x58,0xb1,0x56,0x82,0xe4,0x7b,0x56,0xc5,0x49,0x59,0x87,0xd8,0x4b,0xc1,0x4d,0x8b,0x92,0xa9,0x27,0xfb,0x78,0x59,0x26,0x8c,0x9b,0xad,0x36,0x53,0x2,0x67,0xdc,0xbe,0xfc,0x4,0xce,0xc7,0x3d,0xa9,0x20,0x7b,0xda,0x3f,0xd4,0x6a,0x99,0x2b,0xfb,0x6b,0x56,0xa5,0xc6,0x12,0x17,0x55,0x90,0xc8,0x90,0x27,0xa,0x46,0x51,0xbd,0x65,0x54,0x4d,0xc2,0x39,0xc3,0xb3,0x5a,0xae,0x1f,0x46,0x8c,0x9b,0x1d,0xab,0x2f,0x88,0x18,0xdb,0xa0,0xd8,0xb0,0x3c,0xf,0x8b,0x92,0xf3,0x27,0xaa,0x3a,0x64,0xa0,0x1f,0x6,0x25,0x80,0x25,0x5b,0x6b,0x18,0x37,0x17,0xc3,0xb1,0x7e,0x3e,0xce,0xc3,0xf9,0x32,0xc0,0x48,0x46,0x97,0x58,0xe6,0xa8,0x4,0xe5,0x84,0x71,0xb3,0xa3,0x36,0xd0,0x7e,0x20,0xb,0x2f,0x37,0x4d,0x7a,0x5f,0xb2,0xbf,0x74,0x90,0xcd,0xd0,0xc,0x43,0x19,0xa6,0xc7,0xed,0xd,0x52,0xba,0xc7,0xcd,0xdd,0x4b,0x4c,0xe7,0x23,0x7d,0x3e,0x1d,0x67,0xd,0xfa,0x4e,0xb7,0x49,0x4a,0x4,0x8a,0x52,0xd3,0x69,0x93,0x65,0x93,0x71,0x96,0xd7,0x3,0x17,0x1a,0x35,0x49,0xae,0x6c,0x66,0x97,0x39,0x50,0xd5,0x18,0xa5,0xc4,0x85,0x6b,0xed,0x69,0x6,0xc3,0xf7,0x19,0xf,0xaf,0xde,0x29,0xea,0xb6,0xc6,0xf6,0x8b,0x8b,0xe8,0x86,0xfa,0xef,0x75,0x1b,0xab,0xac,0xf,0x29,0xe5,0x92,0xff,0x57,0xa9,0xb4,0xea,0xe7,0x90,0x1b,0x0,0x8d,0xe4,0x90,0x89,0xb2,0x3a,0x73,0x50,0xc8,0x3f,0x7,0xce,0x8e,0xad,0x88,0x7a,0x25,0xda,0xf5,0x7b,0x17,0x95,0x0,0x71,0x9c,0xe3,0xe9,0xaa,0xf7,0x21,0x99,0x81,0x62,0x8d,0x2d,0xaa,0xbf,0xdc,0xa8,0x2,0x1,0xe8,0x8d,0x10,0x21,0x2a,0xf5,0x66,0x92,0x73,0xc8,0x5c,0x78,0x54,0x3f,0x5f,0x8,0x1d,0x96,0x65,0x5a,0xb5,0xa7,0x56,0xd9,0xb7,0xc1,0x6b,0x3c,0x46,0x4d,0xaa,0xd2,0xeb,0x27,0xbd,0xc9,0x95,0xa5,0x25,0x5e,0xf7,0x33,0x4a,0x26,0xa0,0x2b,0x2d,0xba,0x50,0xc5,0x60,0x50,0xa5,0x23,0x29,0x9,0x81,0x94,0xaa,0xc2,0x22,0x39,0xf7,0xf1,0x36,0x36,0xc5,0x53,0xbc,0x16,0x79,0x2e,0x62,0xa9,0xb,0xbd,0xbc,0x27,0xe5,0xa3,0x14,0x4b,0x49,0xc9,0x89,0xa8,0xf9,0x96,0xc8,0x2d,0xee,0x72,0x23,0x2b,0x65,0x38,0x5f,0x65,0xf7,0xa1,0x7c,0x2e,0x41,0xae,0x11,0xc4,0x92,0xeb,0xb2,0xbe,0xb7,0x42,0x4e,0x39,0x7d,0x9d,0xb6,0xd8,0xe2,0x72,0xcd,0x75,0xb5,0xd2,0xf,0xd5,0x73,0x5c,0xcd,0xe5,0x43,0x69,0x16,0xd6,0x3f,0xaf,0xf2,0xf0,0xf2,0x7,0x15,0x72,0x5c,0x6a,0xf4,0x1c,0x2e,0xed,0xb3,0x45,0xa0,0x58,0xde,0x67,0xcb,0xda,0x61,0xed,0xef,0xbd,0x24,0xf2,0xdc,0x7,0x13,0x7e,0x97,0xff,0x7e,0x85,0xd4,0xd3,0x6d,0x4a,0xab,0x9f,0xb9,0x2b,0x8f,0xbf,0xde,0x88,0x8c,0x6b,0xb4,0xa5,0x9d,0xa3,0xc,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0x7c,0x51,0xdb,0x7a,0xca,0x85,0x77,0x6a,0xd4,0x56,0x60,0xbb,0xa4,0x83,0x47,0x2d,0x6d,0x92,0x50,0xf2,0x7a,0xd8,0xf0,0x8e,0xac,0xa9,0x3e,0x74,0x15,0x1,0x25,0x83,0x1e,0x65,0xbf,0x2d,0xd3,0xa4,0x84,0x88,0xe7,0x1c,0xa4,0xcd,0xf6,0x46,0xb,0x38,0x34,0xb3,0x2d,0x65,0xc0,0x17,0xc5,0x81,0x10,0x89,0x34,0xf8,0x24,0x26,0x86,0x50,0x6,0x42,0x19,0x56,0x39,0x33,0x90,0x48,0xc9,0x45,0x6d,0xaf,0xf2,0xb8,0xed,0xee,0x16,0xe7,0xd3,0x1,0x31,0x46,0x8c,0x5d,0xaf,0x59,0x48,0xe0,0xdc,0x28,0x1f,0x3a,0x1e,0xe,0x69,0xe0,0x1a,0xb7,0x5b,0xf8,0xe0,0x59,0xa5,0xd7,0xb1,0x92,0x86,0xf6,0x55,0x17,0x7a,0x6e,0xbf,0x2d,0x2d,0x87,0x72,0x51,0x9e,0x16,0x54,0xf6,0xb9,0x32,0xd0,0x49,0x66,0xa2,0x77,0x1e,0x61,0xdc,0x70,0x86,0x15,0xa9,0xf9,0xfa,0x61,0xe4,0xa1,0xcf,0x57,0xa,0x9b,0x80,0xd4,0xb4,0x28,0x66,0x7d,0x4f,0xaa,0x5a,0x70,0xd4,0xb8,0x8c,0xaa,0x91,0x91,0x2c,0x60,0x3c,0x8c,0xe7,0x84,0x7e,0xdc,0xc2,0x87,0x19,0xbe,0xa3,0xd7,0xca,0x33,0x11,0x91,0xde,0x7b,0xcc,0x81,0xac,0x66,0xcb,0x3c,0x61,0x7b,0x73,0x87,0xe3,0xfe,0x1,0xe3,0x66,0xc7,0xaf,0xc5,0xa5,0x21,0xa1,0x53,0x82,0xb3,0xeb,0x7,0xb2,0x93,0x31,0x49,0x2a,0xa,0x4b,0x55,0xff,0x71,0xe,0x22,0x29,0x42,0x7d,0xa5,0xc2,0x89,0x6c,0x6f,0x6,0xba,0xae,0xa3,0x90,0xfc,0x7e,0x24,0xd2,0x96,0x87,0x43,0x52,0x70,0x72,0x91,0x47,0xa0,0xf6,0xe0,0x25,0x2e,0xe8,0xfb,0x91,0xf7,0x3,0x34,0xef,0x4b,0x14,0xa7,0x3e,0x4,0x8c,0x9b,0x1d,0xe6,0xe9,0x4c,0x61,0xfb,0x9c,0x5,0x46,0x56,0xc1,0xc,0x38,0x56,0xff,0x0,0x55,0x2e,0x58,0x95,0xcf,0x54,0xb5,0x98,0xa2,0x22,0x1d,0x94,0xdc,0xab,0x7,0xcd,0x6b,0x93,0x1a,0xf,0xb8,0xb9,0xb2,0x80,0xd7,0x43,0x7c,0x4e,0xd1,0xd4,0x15,0x86,0x8f,0x14,0xfb,0x57,0xef,0x60,0x9e,0x27,0xf4,0xe3,0xe6,0x62,0xd0,0x57,0xc5,0x5e,0xd5,0x82,0x5d,0x2b,0x1,0xeb,0xf3,0x84,0xac,0xf5,0x35,0x99,0x56,0xff,0xae,0x9c,0x3b,0x44,0xdd,0xe7,0xb9,0x11,0x58,0x88,0xb2,0xf2,0xdc,0xa9,0x22,0xd2,0x73,0x53,0xe8,0xd1,0x2a,0x6,0x57,0xe7,0xaa,0x95,0x6d,0x53,0x15,0x87,0xf5,0x79,0x8c,0x89,0xae,0x94,0xbd,0x7e,0x1b,0x4b,0x6e,0x28,0x91,0x8f,0xcb,0x3c,0xb7,0x44,0x49,0xd5,0x2,0xae,0x96,0x7d,0xb9,0xc9,0xc5,0x6b,0xa8,0xf3,0x81,0x1e,0xcd,0x99,0x7a,0x75,0x43,0x78,0x4a,0xb,0x9f,0x62,0x5c,0x51,0xcf,0xcb,0x6b,0xd6,0xf1,0xc,0x8d,0xc2,0x92,0xcf,0x3b,0x7c,0x1e,0x8b,0x52,0x7c,0x22,0x96,0x62,0xbe,0x79,0xa3,0x16,0x6b,0x8e,0xc7,0x70,0x4e,0xf6,0x8f,0xa8,0x8,0xa3,0xee,0xd3,0x9a,0xe4,0x71,0xde,0x21,0x47,0x20,0xc6,0x99,0xcf,0x8d,0x45,0xe1,0x99,0x12,0xc7,0x66,0x50,0x43,0x7,0x3c,0xbf,0x7,0x79,0x1e,0xef,0x3b,0xce,0x20,0x2c,0xfb,0x9d,0x9a,0xe0,0xe5,0xf9,0x9d,0xbe,0x57,0xb1,0xf2,0x92,0xf5,0xb9,0x34,0x31,0x97,0x62,0x31,0xdf,0xac,0xa9,0xa8,0xb2,0x5d,0xaf,0x5a,0x73,0xf3,0xda,0x42,0xeb,0xae,0x84,0xe0,0xad,0x54,0x7b,0xa2,0x34,0xc5,0xb5,0x78,0xbb,0xcb,0x26,0xdc,0xf7,0x2b,0xf6,0x6d,0x9e,0x23,0x3f,0x41,0xce,0xb9,0xf7,0xe1,0x12,0xaf,0xfd,0x39,0x7f,0xc0,0xef,0xe7,0x6b,0x44,0x9c,0x7b,0x9a,0xd4,0x6b,0xfe,0xed,0xda,0x13,0x65,0xd5,0x26,0xb6,0x4d,0x27,0xae,0x79,0x1e,0xf7,0x64,0x41,0x90,0xc1,0x60,0x30,0x18,0x1,0x68,0x30,0x18,0xc,0xcf,0xe,0x17,0x99,0x65,0xb9,0xbe,0x63,0xec,0x9a,0x3b,0xf1,0xa2,0x40,0xa0,0xac,0xa7,0x62,0x63,0xa9,0xed,0x5b,0x91,0xf3,0x7f,0x68,0x20,0xe1,0x4b,0xd1,0x4,0xd,0xb,0x77,0x0,0xdc,0x30,0x2,0x53,0x46,0xd7,0xdf,0x22,0x2e,0x13,0x11,0x50,0xd3,0x19,0xfd,0x30,0x36,0x25,0xc,0xce,0xd3,0xc0,0x94,0x41,0xce,0x9f,0x92,0x71,0x4,0xcd,0xd4,0x3,0xca,0xb0,0x21,0x43,0x9a,0x77,0x1e,0x39,0x46,0xbd,0xdb,0xbe,0xcc,0x33,0x42,0x47,0xa7,0x2f,0xc9,0xab,0xa3,0xfc,0x39,0xcf,0xa4,0x63,0xd2,0x86,0x58,0xb1,0xa6,0x16,0x8b,0x2f,0x91,0x5e,0x5d,0x97,0xd1,0x75,0x83,0x5a,0x8f,0x8b,0xfa,0x2e,0xa1,0x1f,0xfa,0x62,0x51,0x42,0x6e,0x1a,0x8b,0x4b,0x38,0xbe,0x64,0x53,0x51,0x6e,0x9c,0x34,0xec,0xe6,0x94,0xd0,0xf,0x9b,0x62,0x2f,0x66,0xb2,0x2f,0x70,0x9b,0x23,0xbd,0x2f,0x6e,0xdb,0x5c,0x16,0xb8,0x50,0x88,0x4d,0xcd,0xe4,0x72,0x9e,0xed,0xbe,0x34,0xc4,0x4a,0x9e,0x61,0xc9,0x68,0x2c,0x9f,0xa9,0xaa,0x11,0x39,0xc7,0x6f,0x59,0x66,0xb6,0x10,0x7,0xcc,0xf3,0x84,0xed,0x70,0x87,0x18,0x17,0x6c,0xb6,0x37,0x48,0x91,0x72,0xfa,0x32,0x32,0xd0,0x15,0xf5,0x5f,0x8,0x1d,0x62,0x8a,0x8,0xfd,0xa0,0x83,0x7e,0x4d,0x16,0x64,0x40,0x73,0xf9,0x68,0xb8,0x15,0x35,0x26,0xe5,0x1a,0x76,0xdd,0x40,0x4d,0x95,0xcb,0xa2,0xb6,0xeb,0xc8,0xaf,0x35,0x4f,0x27,0x52,0x1,0xf6,0x3,0xed,0x3f,0x69,0xb7,0xe4,0x61,0x5b,0x1a,0x29,0x6b,0x4b,0x15,0x91,0xbf,0x4c,0x4a,0x8a,0x6a,0xc6,0x7b,0x2d,0x40,0x1,0x5c,0xb1,0xfa,0x1,0x8d,0xa2,0x15,0x0,0x7c,0xa5,0x12,0x29,0x6d,0x93,0x97,0x56,0xaf,0xe6,0xbf,0xa2,0x62,0x42,0x4d,0xa0,0x5f,0x69,0x6c,0xb4,0xc1,0xca,0xf0,0xff,0x8,0xe2,0x7c,0xc2,0xe1,0xf1,0x1e,0xbb,0xdb,0x17,0x15,0x3d,0x50,0x29,0x81,0x56,0x24,0x1a,0xa9,0x83,0x51,0x15,0x80,0xb4,0xc7,0x72,0x5b,0x96,0x53,0x2c,0xee,0xf5,0xcd,0x16,0x21,0xfb,0xc5,0x22,0x2a,0x76,0xd6,0xa8,0xb6,0x52,0x77,0xb9,0xd,0x8e,0x8,0x73,0xc9,0xb1,0x43,0x5e,0x11,0x7d,0x55,0xe6,0x6a,0x7d,0xd3,0x5,0x58,0xe5,0xb1,0xf2,0xf7,0xaf,0xb4,0x1c,0x17,0x12,0x50,0x1f,0xef,0x43,0x45,0x4c,0x81,0x33,0xfc,0xaa,0x8c,0x5b,0x26,0xc5,0x68,0x9d,0x28,0x48,0x39,0xc3,0xe7,0x8a,0xdc,0x3,0xa,0xf9,0x57,0xf1,0x37,0xae,0xca,0xd5,0xab,0xdb,0xc7,0x65,0xfd,0xd0,0xed,0x51,0xcb,0x6c,0x2,0xbd,0x75,0xb7,0x22,0xc,0x8b,0x1d,0x3b,0xb2,0x32,0x2f,0x56,0x59,0xaf,0xa5,0xa8,0x8,0xbc,0xae,0x71,0x61,0x52,0x64,0xa2,0x8b,0x15,0x80,0x72,0x5e,0xa0,0x1b,0x64,0x1e,0x70,0x59,0x6f,0xca,0x38,0x2e,0x95,0xa0,0x42,0x2d,0x20,0xe7,0xa5,0xdc,0x10,0x11,0xc5,0xa6,0x36,0x24,0x57,0xe5,0x1b,0x57,0xd6,0x39,0x21,0xe,0x1b,0x65,0xa9,0x8a,0xfd,0x1d,0x3b,0x51,0xaf,0x37,0xd2,0x5e,0x6b,0xc6,0x2d,0xa,0xd4,0x9a,0xc8,0x6b,0x89,0x40,0x7d,0xee,0x2b,0x79,0x7e,0xcd,0xcf,0x24,0x93,0xb7,0x3a,0x87,0xac,0x5b,0x75,0xf3,0x35,0x36,0xd0,0x5d,0xe1,0xe1,0x6a,0xfe,0x2d,0x7f,0x8,0x42,0xf0,0xfd,0x8,0xbf,0x27,0xd9,0xc6,0x15,0xe1,0xb7,0x56,0xd5,0x5e,0xdd,0xa8,0xf5,0x4b,0xe7,0xa6,0x5b,0x78,0xbd,0x7f,0x70,0x41,0xf0,0x1b,0xc,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0x2c,0xd1,0xc,0x2c,0x4d,0x52,0x74,0x45,0xf4,0x55,0x77,0x94,0x93,0x64,0xfc,0xf1,0x5,0xb9,0x5c,0x3c,0xab,0xe5,0xca,0x3b,0x6e,0x48,0x84,0x12,0x53,0xe0,0x60,0x74,0xf6,0xf9,0x2,0xae,0x28,0xc7,0x86,0x71,0xab,0xc4,0x5c,0xb1,0x13,0x7b,0xb2,0xf0,0xd4,0xc1,0xf3,0xe,0x4a,0x3a,0x8a,0x32,0x44,0xa,0x44,0xc8,0xc6,0x25,0x9c,0x65,0x51,0xa6,0x88,0x12,0xa5,0xd8,0x9e,0x68,0x8b,0x85,0x30,0xc,0x5d,0x57,0x2,0xcf,0xab,0x41,0x23,0xb2,0xbd,0x96,0x6,0x25,0xaf,0xa4,0xe7,0x7a,0xc0,0xcc,0x20,0x7b,0x70,0x51,0x49,0x5c,0x6,0xab,0x97,0x1,0xa8,0x1a,0xd4,0x52,0x46,0xf6,0x65,0xb8,0xcd,0x6c,0xc9,0xa2,0x36,0x5f,0x7,0x8f,0x4e,0xad,0x73,0x32,0xe4,0x4a,0x23,0x31,0xb5,0x5c,0x6,0x6d,0xc8,0xf5,0xc1,0xab,0x6a,0x51,0x94,0x93,0x40,0x42,0x8c,0x35,0x9,0x29,0x6d,0xcf,0x8e,0x6d,0xbc,0x23,0xb5,0x11,0xe7,0xc4,0x7f,0x9e,0x10,0x3c,0x11,0x9a,0x5d,0x3f,0x60,0x3a,0x9f,0xd1,0xf5,0x44,0xe0,0x85,0xae,0x87,0x3,0x30,0x4d,0x67,0x26,0xd2,0x2,0x96,0x65,0x66,0x9b,0x72,0x6d,0xfb,0x2d,0xd9,0x4f,0xae,0xb2,0x6,0xd6,0x81,0xf0,0x8e,0x1b,0x83,0x75,0x9f,0xb0,0x9d,0x77,0xd8,0xee,0x90,0x24,0x73,0x90,0x5b,0x29,0xe3,0x3c,0xa1,0xdb,0xdd,0x54,0xea,0x4a,0x16,0xe9,0x89,0xe5,0x56,0x9a,0x4a,0x9b,0xbc,0xc8,0x8e,0x6d,0xdd,0xb3,0xb6,0x4b,0xa,0x91,0x4c,0xa4,0x4,0x94,0xa0,0x55,0xb5,0x4c,0xa5,0x5a,0xac,0xb,0x5b,0x94,0x58,0x4e,0xb5,0xa2,0xaf,0x28,0x47,0x34,0xd8,0x1e,0x55,0xd6,0x59,0xce,0x57,0x87,0xcf,0x7a,0xc0,0x32,0x18,0x3e,0x4a,0x7c,0xe7,0xeb,0x5f,0xc1,0x66,0x7b,0x83,0x71,0xbb,0x2b,0x56,0x59,0x57,0x15,0x16,0xd5,0xec,0x95,0xb6,0x41,0x15,0xb2,0x46,0x34,0x43,0x6a,0x89,0x6f,0xf2,0xee,0x5a,0x32,0x8e,0xca,0x7a,0x1c,0x62,0x95,0x9b,0x9,0x26,0xf7,0x8a,0x62,0xda,0x37,0xaa,0xd9,0xf6,0x35,0xa1,0xeb,0xbe,0x73,0xc5,0x8a,0x2c,0xeb,0xb0,0xac,0x2d,0x45,0xbd,0x88,0xa2,0xd8,0x5b,0xb7,0x1d,0xe7,0x52,0xc8,0x14,0xe5,0xbb,0x9d,0x13,0x5c,0xf2,0x4a,0xe8,0xa7,0x18,0x11,0xeb,0x22,0x8a,0xea,0xbb,0x4d,0xe7,0xb5,0xa5,0xb1,0x45,0xcf,0xcb,0x5c,0x1a,0x93,0xf9,0x6,0x45,0x6d,0x59,0x76,0x52,0xc8,0x51,0x13,0x63,0x98,0x1b,0xc5,0x74,0x4a,0x11,0xa2,0xd,0x96,0x9c,0xc2,0x35,0xe9,0xd9,0x9e,0xa7,0xf9,0x66,0x4a,0xa5,0x3a,0xd7,0x76,0x5e,0x7d,0x6d,0x57,0x65,0x27,0x16,0xc2,0xc7,0x79,0x8f,0x79,0xa2,0xb5,0x71,0x9e,0x67,0x52,0x17,0x82,0xde,0x97,0xb,0x45,0xcd,0x5f,0x48,0x52,0x5e,0x23,0xe3,0x75,0x82,0x2a,0x57,0x59,0x7d,0x65,0xfd,0xab,0xb6,0x35,0x57,0xa4,0xd3,0x9a,0xc,0x6c,0x3e,0xe0,0x2a,0xb,0x30,0x5f,0xe1,0xd7,0x2e,0x7e,0xef,0x92,0x5f,0xcb,0x1f,0x48,0xa2,0x5d,0xfb,0xf9,0x9a,0x3c,0xab,0x8e,0xe9,0xb,0x96,0xee,0x7d,0x1e,0x77,0xa1,0x62,0x74,0x4d,0x4e,0xdf,0xfa,0x2d,0x7e,0x28,0x42,0x70,0xf5,0xa6,0xe4,0xdb,0xb7,0x56,0x32,0xae,0xff,0x7c,0xf1,0x4e,0xd5,0xfd,0x9b,0x1b,0x72,0xd4,0xc1,0x35,0x2f,0x47,0x25,0x6d,0x67,0x1c,0xf6,0xf7,0x78,0xf5,0xbd,0xef,0xd8,0x42,0x69,0x30,0x18,0x8c,0x0,0x34,0x18,0xc,0x86,0xe7,0xa,0x69,0xb5,0x6d,0x2f,0xa,0x5d,0x95,0xe9,0x96,0xa,0xc1,0xc1,0x6a,0xac,0xdc,0x44,0xf0,0x25,0x48,0x2b,0xad,0x66,0xf1,0xb9,0x62,0xf9,0x71,0x95,0x42,0x42,0x2e,0xe6,0x3,0x93,0x55,0x32,0xbc,0x78,0x51,0x84,0x78,0x87,0xae,0x1b,0x10,0x97,0x42,0xe0,0x25,0x26,0xb4,0x1c,0xd6,0x25,0xe,0x25,0x57,0xaf,0xeb,0x3b,0x20,0x93,0xea,0x0,0xd5,0x80,0x26,0xb6,0x28,0x7,0x47,0x65,0x25,0x1c,0xec,0x2e,0xd6,0x50,0xe7,0x1c,0x1c,0x5b,0xa0,0x34,0xe7,0x89,0x73,0xe3,0x8a,0x5a,0x23,0x6b,0xa1,0x44,0xe2,0xc1,0x55,0xb6,0xdd,0x73,0xa0,0x3c,0x72,0xe6,0x60,0xf6,0x2a,0xcb,0x89,0x87,0x9e,0x36,0x30,0xbf,0x28,0x66,0x24,0x43,0x49,0x8a,0x4a,0x86,0xcd,0xf6,0xea,0xd0,0x2a,0xa,0x13,0xb2,0xf5,0x2e,0x85,0xf8,0x72,0x1e,0xce,0x65,0x7d,0x3f,0x54,0x5e,0x91,0xcb,0x36,0xf0,0x60,0x92,0x56,0xfb,0x5e,0xde,0x8f,0xf,0x81,0x6,0xbb,0xea,0x7d,0x74,0x61,0xc4,0x32,0xcf,0x18,0xc6,0x91,0x9a,0x7b,0xbb,0x9e,0xec,0xbc,0x39,0x61,0x60,0xdb,0x60,0x66,0xa2,0x92,0x8e,0x8b,0x50,0x9e,0x37,0x25,0x7a,0x77,0xac,0x6,0x94,0xcf,0x48,0x42,0xf7,0x33,0xd5,0x65,0x2,0x81,0xed,0xdd,0x39,0xa1,0x6e,0x19,0x75,0xde,0xc3,0x65,0x2a,0x86,0x71,0xce,0xa1,0x1b,0x46,0x2d,0x46,0xa1,0xf7,0x1b,0x88,0x1b,0x10,0xa5,0x27,0x5b,0x7c,0x6b,0xe2,0x42,0x3e,0xef,0xae,0xa3,0xcf,0x4a,0x6c,0x7c,0x39,0x65,0xb8,0x50,0x72,0x2d,0x5d,0x4d,0x5a,0xf2,0xc0,0x5c,0x72,0xa3,0x72,0x51,0x4d,0xca,0x20,0x7f,0x31,0x70,0x41,0xd5,0x28,0x59,0x49,0xbf,0x36,0xc8,0x3e,0x37,0x55,0x8c,0x80,0xca,0x56,0xd,0x86,0x8f,0x10,0xaf,0xde,0xfe,0x26,0xbe,0x34,0x9f,0xf1,0xa9,0x1f,0xfe,0x71,0x6c,0xb6,0xb7,0xd0,0x62,0x88,0x6b,0xf9,0x7f,0x62,0x87,0xad,0x6e,0x62,0xd4,0x2a,0xa4,0x5a,0x2d,0xb8,0x5e,0xbb,0x5c,0xd5,0xcc,0xda,0x7e,0xd7,0xb0,0x6a,0x93,0x45,0xd3,0x38,0xac,0x79,0x66,0x15,0x13,0x54,0x48,0x42,0x57,0x29,0xb,0xcb,0xd,0x15,0x57,0x15,0x81,0x38,0xbd,0x51,0xd4,0x2a,0xc7,0x84,0x40,0x91,0x76,0x5d,0x55,0x8c,0x79,0xdf,0x10,0x51,0xb9,0x2e,0x9c,0x40,0x61,0x51,0xea,0x16,0xde,0xf6,0x7d,0xba,0xea,0xf5,0x6a,0x45,0x5b,0xcb,0xe0,0x94,0xf2,0x92,0xa4,0xaa,0x65,0xb9,0x61,0xe0,0xeb,0x16,0xe0,0x3a,0x2e,0x62,0xd5,0x60,0x2b,0x65,0x57,0xf5,0x5a,0xa4,0x79,0xb3,0x40,0xa3,0xa0,0x93,0xbf,0x97,0xc,0xd5,0x52,0xc6,0xd1,0x90,0x45,0x35,0xf9,0x2b,0xe5,0x47,0x2b,0xdb,0xb2,0xda,0xba,0x73,0xd6,0xec,0xdf,0x75,0x69,0xcb,0x53,0x3c,0x5b,0x4d,0x3a,0xd5,0x39,0x92,0x7a,0x8e,0x16,0xc5,0xfe,0x5a,0x81,0x57,0x35,0x3b,0xe3,0x92,0xcb,0x2c,0x2f,0x74,0x25,0xb2,0xa4,0xa8,0xb4,0x5d,0x15,0x51,0xc2,0xd9,0xc1,0xeb,0xf3,0xb1,0x5b,0xdf,0xd8,0xa9,0xda,0x8e,0x51,0x1f,0x2,0xed,0xb1,0x57,0x13,0x80,0xe5,0x5c,0x90,0xf4,0xba,0xe5,0xa2,0xf0,0xc9,0xb9,0xa7,0x3f,0xdf,0xfa,0xcd,0xb9,0x55,0x69,0x47,0xf5,0xdc,0x17,0x4,0x71,0xfd,0xfe,0x9a,0xcf,0xb5,0xbc,0xff,0xba,0x10,0xa4,0x6d,0xd6,0x2e,0x56,0x7b,0x0,0x58,0xe6,0x9,0x87,0xc7,0x7b,0xbc,0xfb,0xe6,0x37,0xb1,0x4c,0x47,0x5b,0x28,0xd,0x6,0x83,0x11,0x80,0x6,0x83,0xc1,0xf0,0x5c,0x51,0x94,0x52,0xb9,0x5c,0x34,0xe7,0x92,0xc1,0xb4,0x6e,0x86,0x5c,0x67,0xc6,0x88,0x92,0xa2,0x64,0xbc,0x95,0xcc,0x3a,0x5f,0x5,0x8e,0xab,0x42,0x84,0x2f,0x5e,0xc9,0x8a,0xba,0x68,0xc8,0x3a,0x71,0x24,0xd4,0x7a,0xe8,0xc4,0x56,0xec,0xbc,0x86,0xbd,0xd7,0x84,0x8f,0x34,0x13,0x6b,0x96,0x51,0x4c,0xac,0x4c,0x2c,0xd6,0x29,0x57,0xbd,0x16,0xa9,0xe2,0x0,0xa4,0x8a,0x10,0x14,0x82,0xa8,0xba,0xe0,0xf,0x43,0xc7,0xca,0x35,0x26,0x94,0x34,0xe3,0xaa,0x5c,0x58,0x7,0x6e,0xa9,0x95,0x7f,0x17,0x2,0x4b,0x6c,0x65,0x3a,0x6c,0xa8,0x95,0xc8,0xa9,0xed,0xaa,0xa8,0x64,0x64,0x0,0xf1,0xed,0xdc,0x24,0xd6,0x61,0xce,0x8e,0x52,0x22,0xca,0x57,0x4a,0xca,0x9c,0x74,0xdf,0x34,0x19,0x59,0x95,0x52,0x24,0xc6,0x48,0xa,0xc6,0x4c,0xf9,0x8b,0x62,0xc5,0x2d,0x81,0xf7,0x59,0x1b,0x31,0xf5,0xf5,0xd8,0xa,0xdd,0xf5,0x3d,0x42,0xe8,0xe1,0xb9,0xb5,0x57,0xf6,0x7f,0x8,0x25,0x73,0x50,0x54,0x94,0xb2,0xaf,0x65,0x20,0xd4,0xf2,0x91,0x5c,0x91,0xc8,0x39,0xc3,0x85,0x40,0xc4,0x1d,0x67,0x2c,0x8a,0xf5,0x4f,0x6,0x1a,0x39,0x46,0x42,0xe8,0x90,0x10,0x35,0x37,0x32,0xb3,0x1a,0x45,0xb,0x5a,0x94,0x70,0xab,0x54,0x26,0x4d,0x59,0x81,0x53,0xb5,0x63,0xe0,0xc,0x4a,0x79,0x7f,0xb5,0xca,0x48,0x7f,0xbf,0xda,0xce,0x9a,0x34,0xd5,0x61,0x99,0xd5,0x1b,0x45,0x90,0xd4,0x4a,0x34,0xc4,0x62,0x5e,0x37,0x3b,0x16,0x4b,0x15,0xaa,0x61,0x13,0xba,0x5d,0x6,0xc3,0x47,0x8d,0xc3,0xab,0xb7,0xf1,0xb5,0x57,0x6f,0x23,0xf4,0x23,0xb6,0xb7,0x2f,0xcb,0x9a,0xc9,0x84,0x82,0xaa,0x8d,0x2a,0x75,0x5d,0xa8,0x8a,0x28,0xe4,0xbb,0x2e,0xf9,0x71,0xf5,0x9f,0x85,0xfc,0xaa,0x95,0x69,0x75,0xe9,0x84,0x92,0xf5,0x29,0x52,0xe3,0x6d,0xa3,0x1e,0x23,0x75,0xb4,0xe7,0x98,0x83,0xc4,0x37,0x85,0x24,0xb7,0xae,0xb6,0xd3,0xca,0xb9,0x43,0xc9,0x9c,0x15,0x81,0x29,0xcd,0xb4,0xaa,0xb2,0xae,0x8,0x3f,0xca,0x5,0x4d,0xcd,0x7b,0xcc,0x29,0xc1,0x5,0x5f,0xbe,0xb6,0xee,0x7a,0x43,0x6c,0x4b,0xa2,0x14,0xc2,0xb2,0x14,0x99,0xac,0xad,0x94,0xf5,0x79,0x32,0xeb,0x4d,0x2d,0x51,0xff,0xc9,0x39,0xb6,0x3d,0x9f,0xd4,0x37,0x8a,0x22,0xdf,0x44,0x49,0x4a,0xba,0x8a,0x7d,0xba,0xce,0x9b,0x95,0xf5,0x4b,0xc8,0x52,0xd9,0x67,0xf2,0xef,0x4e,0x4a,0x53,0xb4,0xe8,0x44,0xce,0x39,0xd5,0x7e,0xf3,0xb4,0x7e,0xd6,0xf9,0x85,0xce,0xa1,0xac,0xd9,0xcd,0x67,0xed,0x1a,0xa2,0x57,0x8e,0x9,0x6a,0x7b,0x8f,0x7a,0x5e,0x17,0x55,0x7a,0x5d,0x6,0x23,0xa4,0xa7,0x94,0x86,0x89,0x8a,0x52,0xd6,0x48,0x39,0x97,0x36,0xc5,0x52,0xae,0x2d,0x24,0x73,0xfa,0x3b,0x59,0xcf,0xf,0x72,0x2e,0x90,0xeb,0xe,0x57,0x9d,0x93,0xe5,0xfc,0xea,0x2a,0xfb,0x77,0xd3,0x26,0xcd,0x7f,0x2f,0xdb,0x5d,0xda,0xa6,0x25,0xe2,0x42,0xe3,0x48,0x80,0x96,0xfc,0xac,0x6e,0xaa,0xc9,0xf3,0xa5,0x18,0xe1,0xbb,0xae,0xb2,0xd5,0x53,0x7e,0x64,0xc9,0x19,0x96,0x6b,0xa4,0xd0,0xd8,0xe2,0x51,0x5d,0xf7,0x28,0x89,0x58,0xe5,0xfa,0x6,0xbe,0xf9,0x56,0xef,0x93,0x9c,0x12,0xbd,0x56,0x4a,0xd,0x51,0xee,0x82,0x47,0x5a,0x62,0xf9,0x9e,0x54,0x24,0x61,0x4a,0x91,0xe3,0x4d,0x80,0xb4,0xcc,0x58,0xa6,0x13,0x59,0xdd,0xcd,0xfe,0x6b,0x30,0x18,0x8c,0x0,0x34,0x18,0xc,0x86,0xe7,0xd,0x19,0x84,0xc0,0xd4,0x5e,0xaa,0x89,0x12,0x19,0x3a,0xbc,0x57,0x25,0x88,0xc,0x2e,0x35,0x9,0xa2,0x83,0x8d,0xb4,0x3e,0xca,0xdd,0xf4,0x54,0x86,0x96,0x9a,0x10,0x12,0x75,0x55,0xd0,0x21,0x83,0xf3,0x1,0xab,0x76,0xc8,0x94,0x22,0x32,0x2b,0xba,0x52,0xe4,0xa6,0x49,0xb6,0xba,0x8a,0x2d,0x59,0x1a,0x6,0x33,0x92,0xde,0x35,0x57,0x5b,0x54,0x35,0xc,0x96,0xa1,0x30,0xe9,0xef,0x29,0xe9,0xc7,0xc3,0x55,0xe6,0x7c,0xba,0xea,0xcd,0x37,0x56,0x32,0xb9,0x48,0x4f,0x29,0x55,0xd,0x96,0x68,0x6,0x40,0xca,0x65,0x5a,0x64,0x9a,0xd2,0x3b,0xf0,0x65,0x0,0xca,0xaa,0xd8,0x68,0x8,0x55,0x29,0x44,0xe1,0xb,0x75,0x19,0x96,0x5d,0x4d,0x80,0xd5,0x4d,0x8e,0xd5,0x6b,0xb7,0x2a,0x87,0x4a,0x1,0x98,0xeb,0xe1,0xcd,0x91,0x1d,0x1b,0xa5,0x49,0xb2,0xeb,0x82,0x12,0x85,0x42,0x8a,0x3a,0x17,0x95,0x40,0xc,0x21,0x20,0x84,0xd,0x52,0x5a,0x90,0x52,0x69,0xd,0x75,0xa2,0x9a,0x59,0x11,0x6f,0xce,0x55,0x44,0x6e,0x8e,0x3a,0xc4,0x48,0x8e,0x95,0xd3,0x3c,0x2b,0x19,0x30,0x2b,0x3b,0x73,0x8a,0x3a,0x7c,0xd2,0xe0,0x49,0xaa,0x44,0x97,0x13,0x62,0x8c,0xd5,0x40,0xd6,0xda,0x8d,0x9d,0xe4,0x1a,0x8a,0xe5,0x98,0x7,0x7e,0xc7,0xc4,0x9c,0x7,0xab,0x5f,0xd6,0x85,0x1e,0x72,0xec,0x20,0x57,0xc3,0x77,0x82,0xf3,0xae,0x21,0xf3,0xb0,0x12,0x6d,0x14,0x55,0x4b,0xab,0xb2,0xd1,0xc6,0xcb,0x75,0xb3,0xe5,0xaa,0xfd,0xf1,0x83,0xac,0x6c,0x6,0xc3,0xf7,0x13,0x71,0x3e,0xe3,0xf1,0xdd,0xef,0xda,0x8e,0x30,0x18,0xc,0x6,0x83,0xc1,0xf0,0x24,0xbc,0xed,0x2,0x83,0xc1,0x60,0x78,0x3e,0xb8,0x54,0xb9,0x95,0x3f,0xab,0x85,0x24,0xb7,0x8d,0xa9,0x42,0x4e,0x79,0x5f,0xc8,0x27,0xe4,0xd6,0x8a,0xd5,0x6,0xb6,0x17,0xeb,0xaf,0x3c,0xaf,0x94,0xf7,0x42,0x15,0xf,0xac,0xda,0xa8,0xb2,0x9d,0x8a,0x9d,0x36,0x73,0x29,0x86,0x53,0x2,0xae,0xe,0x80,0xa7,0x16,0x58,0xdf,0xda,0x77,0xb4,0xa9,0x92,0xc8,0x1f,0xb5,0xe8,0x8a,0xba,0x84,0x95,0x10,0xd4,0x36,0x9c,0xda,0xe6,0xd7,0x5c,0x48,0xcd,0x22,0x34,0x2b,0xaa,0x41,0xb1,0xcc,0x6a,0x3e,0x14,0xdb,0xd4,0x62,0x9c,0x55,0x5,0xe7,0x0,0x55,0xbe,0x68,0x8,0xbd,0xf7,0x17,0x96,0x39,0x55,0xc9,0xa1,0xbc,0x8e,0xa8,0x34,0x8a,0x8d,0x28,0x37,0x2d,0x8a,0x65,0x1b,0x4b,0x8b,0xa6,0xb6,0x6c,0xb2,0x2,0x23,0x83,0xda,0x6f,0xdd,0xca,0xb2,0x55,0xab,0x2b,0x48,0x4d,0xb2,0x60,0x9e,0x27,0xcd,0xec,0x93,0xf7,0x45,0x76,0xe7,0xc8,0x2d,0x9e,0x25,0xa7,0x4b,0x95,0xa1,0x90,0xf,0x30,0xeb,0xbe,0x2c,0x8d,0x98,0x5e,0x95,0x9,0xb9,0xda,0x2e,0xda,0x2f,0xd5,0xe7,0xe3,0xea,0x5c,0x2d,0x57,0x32,0x4,0x1d,0xb4,0x9c,0x45,0x32,0x94,0xe4,0xf3,0x13,0xcb,0x9e,0x28,0x27,0x12,0xbf,0x5f,0x55,0xb1,0xf2,0x36,0xc8,0xe7,0xc7,0x1b,0xd4,0x90,0x7d,0x4e,0x95,0x47,0xb5,0xad,0x2f,0x5f,0x16,0x79,0x64,0xe8,0x31,0x8d,0xba,0x35,0xf2,0xaa,0xeb,0x2d,0x37,0xdf,0x15,0x69,0xad,0x6c,0xd5,0x89,0xa6,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x7c,0x7c,0x60,0x4,0xa0,0xc1,0x60,0x30,0x3c,0x23,0xb4,0xad,0x85,0x42,0xc4,0x14,0x65,0x5a,0x5d,0x80,0x91,0xb9,0xb0,0xa2,0x10,0x3e,0xeb,0x9c,0x1b,0xfa,0x7f,0x62,0xeb,0x71,0xce,0x37,0xe1,0xf1,0x91,0x2d,0xa5,0x5a,0x20,0xe2,0x4b,0xee,0x92,0x58,0x4b,0x8b,0x25,0x29,0xab,0x22,0x8c,0x5e,0x5b,0x88,0xc6,0xd4,0x6c,0xa7,0x10,0x2b,0x42,0xb6,0xe5,0xbc,0xce,0xdb,0x43,0x53,0xfa,0x50,0x93,0x72,0xa2,0x1e,0x2b,0x99,0x3a,0x40,0x9d,0x71,0x45,0xe4,0x95,0xaf,0xac,0x44,0x6c,0x27,0xe3,0xbc,0x3b,0xcd,0x1e,0x62,0x65,0x1f,0x32,0x67,0xd3,0x41,0x6c,0x5a,0xe,0x39,0xc7,0x92,0x33,0xc7,0xfb,0xac,0xe,0x5b,0x2f,0x64,0x69,0x6a,0x88,0xc7,0x3a,0x50,0x5d,0x7e,0x9e,0x2a,0x6b,0x92,0x58,0xb7,0xe5,0x39,0x9c,0x5a,0x96,0x38,0x3b,0x71,0x59,0x38,0x6c,0xbf,0xfa,0xbc,0x62,0x2c,0x6a,0x4a,0x56,0xe7,0x1,0x6d,0xc8,0x7a,0xae,0xe4,0x6e,0x75,0x8b,0xa3,0xd8,0x85,0xe0,0x1c,0xe2,0x32,0x13,0x41,0xc7,0x56,0x33,0xf9,0x3d,0x55,0x6e,0x2a,0xa1,0x5a,0x5a,0x2a,0xeb,0xcf,0x80,0xb6,0x35,0x6a,0x8e,0x51,0xc9,0x52,0x5c,0x1d,0x83,0x62,0xc1,0xad,0xb2,0x96,0x48,0xa9,0xd9,0x86,0xeb,0x53,0x29,0x88,0x2b,0xca,0xcf,0x5c,0x3e,0x77,0x39,0x28,0xdc,0x8a,0xd4,0xd6,0xe3,0x2c,0x97,0x83,0xd7,0x35,0x35,0x8f,0xa8,0xf2,0xb1,0xe8,0x2f,0xe5,0xb9,0x73,0xdb,0xc2,0x98,0x9b,0x2f,0x40,0xb1,0x6a,0x57,0xe5,0x39,0xce,0xf2,0xff,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x1f,0x33,0x18,0x1,0x68,0x30,0x18,0xc,0xcf,0x8,0xaa,0x70,0x6a,0x32,0x8d,0x24,0xcf,0xc,0xab,0x12,0x9,0xdf,0x64,0xe8,0x88,0x2,0x4e,0x49,0xac,0x18,0x95,0x64,0x2b,0xcd,0xb8,0x6c,0x98,0x14,0x82,0xae,0x52,0xd9,0x35,0xdb,0x90,0xc5,0xd6,0x9b,0x34,0x84,0x29,0xe7,0x42,0x58,0xa9,0x92,0x4a,0x14,0x76,0xbe,0x10,0x6a,0x62,0x4d,0xa6,0xe7,0x42,0x95,0x71,0x44,0xbf,0x23,0xcd,0xb3,0x6b,0x4b,0xaf,0xfc,0x57,0x14,0x73,0xa2,0x42,0xac,0x49,0x4f,0x20,0x5f,0x6c,0x73,0x21,0xea,0x82,0x92,0x5d,0x69,0x59,0x1a,0x6b,0xac,0xab,0x1a,0x19,0x55,0xe5,0xc8,0x36,0x62,0xd9,0x87,0xde,0x51,0x96,0x1e,0x29,0x1b,0x8b,0x3d,0xba,0xce,0xe4,0xaa,0x6d,0xc9,0xae,0xb6,0xd3,0xa6,0xd2,0xf2,0xeb,0x9c,0xd3,0x7d,0x7f,0x11,0x60,0xce,0x24,0x6e,0x96,0x7c,0x29,0xce,0xee,0x4b,0x6c,0x55,0xce,0x29,0xb5,0x79,0x52,0x42,0x50,0x82,0x48,0xcc,0x14,0x63,0xf3,0x33,0x25,0x6e,0xe1,0x9a,0x6,0xe8,0x42,0xd2,0x49,0x68,0x5e,0xd6,0x86,0xdd,0x3a,0x1c,0xdd,0x87,0xae,0xb4,0x77,0x6a,0x79,0x46,0x56,0xbb,0x79,0x9d,0xa3,0x54,0xc8,0xc0,0x2a,0x30,0x3e,0x4,0xd,0xa2,0x6f,0x5a,0x11,0x53,0x56,0xbb,0xb4,0xe6,0x77,0xd5,0x56,0x6b,0x57,0x8e,0x97,0x24,0xa4,0x5e,0xf9,0x88,0x51,0x48,0xee,0xa4,0xef,0xd,0x75,0x30,0xff,0xba,0xe5,0x11,0x6d,0xee,0x58,0xad,0x24,0xbc,0xf0,0xc,0x3,0xc5,0x1a,0x6e,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x7c,0x4c,0x60,0x4,0xa0,0xc1,0x60,0x30,0x3c,0x27,0x54,0xe4,0x5a,0x43,0xca,0xad,0x9,0x14,0x7a,0x84,0x12,0x2f,0xeb,0x90,0x73,0xfa,0x25,0xd7,0xa8,0xb5,0xb4,0xed,0x95,0x64,0x69,0xfc,0x90,0x4a,0x71,0x98,0x8a,0xad,0x78,0xdd,0xbe,0x27,0xa1,0xd9,0x75,0x28,0xba,0x28,0xe5,0xe8,0x77,0x8b,0xd,0x38,0xc5,0x48,0x1,0xd6,0xfa,0x1e,0x72,0xb1,0xd0,0x3a,0xc7,0xdb,0xd1,0x86,0xc4,0x3,0x55,0x5b,0x9f,0xab,0xad,0x9e,0x25,0x64,0x1d,0x55,0x93,0x5e,0x13,0x34,0x9f,0xdb,0xd6,0xc7,0xda,0x42,0x5c,0xd4,0x8c,0x45,0x6d,0xa6,0x6d,0x99,0xae,0x4,0x8b,0x2b,0xb1,0xc9,0xd6,0x5b,0xe2,0x4a,0x1d,0x5b,0x89,0x97,0x96,0x40,0x5c,0x85,0x8c,0x67,0x29,0x3c,0xf1,0x95,0xed,0xd9,0xad,0xda,0x35,0xab,0x7f,0x17,0x5,0x9f,0x14,0x88,0xc8,0x63,0x24,0xcc,0x9d,0xac,0xbe,0x9c,0xf,0xd8,0x75,0xd4,0x4,0x29,0x64,0xa2,0x13,0xb2,0x35,0x69,0x3e,0x64,0xd6,0xd2,0x98,0xf2,0xf1,0x6b,0xd9,0x4b,0x45,0xa,0x2b,0x31,0x9b,0x39,0x4,0x9f,0x73,0x16,0x95,0x40,0x45,0x4d,0xe2,0x7a,0x6d,0xcb,0x90,0x43,0xc4,0x87,0x50,0x37,0x68,0x70,0x3e,0xe1,0x52,0xb6,0xa3,0x6a,0xf3,0x44,0x39,0x42,0x9b,0xb0,0x79,0x6a,0xe8,0xc4,0xca,0x4e,0xdd,0xb6,0x60,0x6a,0x6b,0xf5,0xd5,0x7c,0xbe,0xdc,0x7c,0x57,0x84,0x1c,0xd7,0xe3,0x54,0x9e,0xb3,0xe9,0x1a,0xad,0x7e,0xb7,0x6e,0x8d,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x3e,0x46,0x68,0x7b,0xed,0xd,0x6,0x83,0xc1,0xf0,0xb1,0xc6,0xdd,0x27,0x7f,0x8,0x3f,0xf9,0xd9,0xbf,0x8d,0x61,0xdc,0x30,0x29,0x95,0xae,0x10,0x21,0xa5,0xf1,0x2f,0x2b,0xeb,0xf3,0xd4,0xe9,0x80,0x4b,0x40,0xea,0x92,0xb,0x2f,0x65,0x16,0xa5,0xa5,0x17,0x95,0x65,0x94,0x9e,0xdb,0xab,0xa,0xc,0x28,0x24,0x96,0xfe,0x99,0x1b,0x16,0x55,0x11,0xc7,0xe5,0x22,0x75,0x1b,0x71,0x52,0xf5,0x60,0x5,0x26,0xb5,0xda,0x3c,0xbe,0xdc,0x94,0x83,0xa8,0x25,0x36,0x97,0xf7,0xd5,0x28,0xba,0xe0,0x9a,0xc6,0x5d,0x6d,0xda,0xab,0x5e,0xc3,0x31,0x59,0x55,0x2b,0x26,0xfd,0xaa,0x29,0xb0,0x10,0x8e,0xa5,0x5d,0x22,0xf3,0xe3,0x52,0x95,0xa5,0x58,0x9e,0xba,0x6d,0x35,0x94,0x66,0x46,0xf9,0x5d,0x70,0x63,0xb2,0x90,0x84,0xaa,0x3e,0xf4,0x1e,0x59,0x9b,0x18,0x53,0xc9,0xf1,0x63,0x82,0x52,0x5e,0x3f,0x74,0x1d,0xe2,0x42,0xe4,0x68,0xd7,0x75,0x4d,0x8e,0xa0,0x36,0x5b,0x2a,0x11,0xea,0x4b,0x5e,0x21,0x67,0x2,0x7a,0x1f,0x8a,0x9a,0xaf,0x52,0x90,0xca,0x5b,0x90,0xe2,0x12,0x29,0x88,0x11,0xa2,0x2c,0xd7,0xfb,0xad,0xfa,0x37,0x94,0x8a,0xe,0x55,0xf2,0xe5,0xca,0xbe,0x5b,0xb7,0xf0,0xea,0xf1,0x52,0xfd,0x4e,0xd9,0x6b,0x55,0x91,0x47,0xbe,0x7e,0x15,0x23,0x4d,0x94,0x59,0x8a,0x61,0xaa,0x67,0x2a,0x36,0xf5,0x2a,0x3b,0xb0,0x22,0x3d,0x5d,0xfd,0xd,0x58,0x35,0x86,0xe6,0x8a,0x14,0x8e,0x71,0xc1,0x32,0xcf,0xb8,0x7f,0xe7,0x2d,0x7c,0xf7,0x1b,0x5f,0xd2,0x7c,0x42,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xe1,0xe3,0x0,0x23,0x0,0xd,0x6,0x83,0xe1,0x99,0xe1,0xf6,0xf5,0x1f,0xc4,0x27,0x3e,0xf5,0x69,0x8c,0xdb,0x9d,0x96,0x6a,0x14,0xa2,0xa4,0x5d,0xf8,0x6b,0x82,0x46,0x49,0x9f,0xfa,0x51,0x5a,0xec,0x51,0x65,0xef,0xa5,0xd2,0x7e,0xb,0xa0,0xb2,0x70,0x12,0xa,0xe1,0xe3,0xaa,0xac,0xbf,0xfa,0x75,0x52,0xcd,0x3e,0xaa,0x1d,0x54,0x95,0x5c,0x6d,0xe4,0x1f,0xfd,0x28,0xb7,0x2a,0xbc,0x42,0xd8,0x94,0x6d,0x75,0x4d,0x93,0x2d,0x11,0x5d,0x35,0x41,0xa6,0xcf,0x8d,0x42,0x10,0xa,0x89,0x27,0x44,0xa6,0x92,0x6a,0x68,0xd5,0x8d,0x1f,0x74,0xfa,0xac,0xf7,0xdd,0x3a,0x1f,0xae,0x26,0x28,0xf5,0xbd,0xe8,0xfb,0xcf,0x8d,0x5a,0xf1,0xda,0x7b,0x96,0xd,0x97,0xc7,0x25,0xce,0x2a,0x54,0x72,0xd4,0xe1,0xa2,0x54,0xe4,0x5a,0x43,0x6d,0xb1,0x84,0x3b,0x25,0xfc,0xf2,0xca,0xf6,0xea,0x2b,0x15,0x65,0xf9,0x10,0xb2,0x66,0x2,0xb6,0x97,0xc,0xae,0xfa,0xbd,0x50,0x95,0x62,0x8,0xb1,0xfa,0xf4,0xb6,0xc8,0x3,0x88,0x4c,0xce,0x2d,0xb9,0x7a,0x71,0x0,0xe4,0xda,0x3,0xdd,0xb4,0x36,0xaf,0xd5,0x9b,0x7a,0x9c,0x49,0xbe,0x63,0x45,0xf8,0xd5,0x4d,0xbf,0xa5,0x1,0xb8,0x25,0xfa,0x1a,0xb2,0xb1,0xfe,0x86,0xa4,0x84,0xd3,0x71,0x8f,0xc3,0xe3,0x3d,0xee,0xdf,0xfe,0x96,0x2d,0x32,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x86,0x8f,0x1d,0x8c,0x0,0x34,0x18,0xc,0x86,0x67,0xa,0xef,0x3b,0xc,0xbb,0x3b,0x22,0x67,0x50,0x14,0x50,0x7a,0x2,0x60,0xd5,0x95,0x3,0x59,0x44,0x29,0x2b,0xaf,0x6a,0x37,0xad,0xac,0xaa,0x62,0x2f,0xad,0xad,0xa8,0x0,0x94,0x3c,0x13,0xe5,0x5b,0x9c,0x67,0x55,0xcf,0x35,0x44,0x8d,0xab,0x75,0x56,0xa0,0xc,0x3b,0x1f,0x5a,0x12,0xce,0x17,0x52,0x47,0x29,0xbe,0xc2,0x22,0x69,0xee,0xa0,0x28,0xd6,0xa4,0xfd,0x35,0x2d,0xb,0x7c,0xd7,0x57,0xd6,0x5c,0x34,0xcf,0xe7,0xe0,0xd4,0x86,0x2b,0x99,0x83,0xb9,0x29,0xb1,0x8,0xd5,0xdf,0x73,0x45,0x80,0x81,0xb7,0x2f,0xe8,0x36,0xfb,0x40,0xea,0x43,0x69,0xaf,0x15,0x5,0xa5,0x58,0x72,0xb5,0x54,0xa4,0xca,0x36,0x4c,0x31,0x2a,0x21,0xaa,0x45,0x18,0xde,0xc3,0xc1,0x6b,0x76,0x1f,0x3c,0x67,0x1a,0xa6,0xa8,0xcf,0x5f,0x97,0x6d,0xc8,0x67,0xa7,0x2a,0x3d,0x21,0x6c,0xbd,0x6b,0xd4,0x7c,0x25,0x6b,0x30,0xf1,0xf6,0x86,0xc6,0x9e,0x4b,0x5b,0x9b,0x5b,0x5,0xa1,0xbc,0xc7,0x8a,0x48,0x54,0x22,0x38,0x67,0x3d,0x4e,0xa4,0x90,0x44,0x2e,0x1e,0xb4,0x58,0x45,0x4a,0x35,0xb8,0x14,0xa6,0xde,0x17,0x45,0xd9,0x87,0xea,0x38,0x28,0x87,0x82,0xbb,0x66,0xa9,0xe5,0x4c,0x43,0x69,0x60,0x56,0xf5,0xa2,0x2f,0x24,0xa7,0xe6,0x27,0xae,0x32,0x2c,0xe9,0x75,0xab,0xd7,0x72,0xb4,0x5d,0xfa,0x19,0x6b,0x41,0x4c,0xa5,0xce,0x94,0x6d,0x11,0x42,0x34,0x15,0x82,0xba,0x28,0xf,0x33,0x96,0xe9,0x68,0x8b,0x8a,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xe1,0x63,0xb,0x23,0x0,0xd,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x86,0x67,0xc,0x2b,0x1,0x31,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0x8c,0x0,0x34,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0xc,0x6,0x83,0xc1,0x60,0x30,0x18,0x9e,0x31,0xfe,0x37,0xec,0xf3,0x5f,0x77,0xda,0xa1,0xab,0xd4,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
static const unsigned char option_arrow_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x14,0xd,0x1c,0x2e,0x4,0xf2,0xb6,0x87,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0x61,0x49,0x44,0x41,0x54,0x38,0x8d,0x63,0xbc,0x7b,0xf7,0x2e,0x3,0x25,0x80,0x89,0x22,0xdd,0xb4,0x36,0x40,0x82,0x81,0x81,0xe1,0x3f,0x94,0x26,0xd9,0x0,0x16,0x6,0x6,0x86,0xe7,0x50,0xf6,0x73,0x28,0x9f,0x24,0x3,0x7e,0x13,0xe0,0x13,0x34,0x80,0x68,0x80,0xcb,0x69,0xbc,0x94,0x1a,0xf0,0x19,0x8b,0x18,0x23,0x36,0x85,0x34,0x8b,0x46,0x49,0x2,0x7c,0x82,0x6,0xf0,0x30,0x30,0x30,0x70,0x40,0xd9,0x1c,0x50,0x3e,0x56,0x80,0x2b,0xc,0xee,0x40,0x69,0x46,0x34,0x3e,0xd1,0x2e,0x20,0x1a,0xc,0xbc,0x1,0x0,0x1e,0x2d,0xa,0xcc,0x68,0x85,0xc9,0x5b,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
@@ -295,7 +315,7 @@ static const unsigned char popup_unchecked_png[]={
static const unsigned char popup_window_png[]={
-0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x2a,0x0,0x0,0x0,0x46,0x8,0x6,0x0,0x0,0x0,0xba,0xf5,0x6,0x7a,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0xa,0x14,0x17,0x39,0x1b,0x27,0xff,0x2d,0x90,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x3,0x82,0x49,0x44,0x41,0x54,0x68,0xde,0xed,0x5a,0xdd,0x6a,0x13,0x41,0x14,0xfe,0xce,0xcc,0x64,0xb7,0x55,0x63,0x8b,0xb6,0x96,0xa,0x52,0x11,0x4,0xbd,0x10,0xd1,0x52,0xf0,0x42,0x1f,0x40,0xbc,0xf0,0xda,0xbb,0x8a,0x2f,0xe1,0x23,0x88,0xef,0xe0,0x73,0xf8,0x14,0xe2,0xa5,0xb7,0x2d,0xc5,0x6a,0xa4,0x96,0xc6,0x5a,0xd2,0x6c,0x33,0x73,0xbc,0xd8,0xd9,0x36,0xa6,0x9b,0xdd,0xd9,0x74,0x67,0xba,0xd1,0x1e,0x58,0x8,0x21,0x99,0xf3,0xed,0x77,0xce,0x77,0x7e,0x36,0x1,0x2e,0xec,0xc2,0x9a,0x6d,0x54,0xf6,0x81,0xef,0x5f,0xbb,0xcf,0x1,0x7c,0x0,0xb0,0xec,0x9,0xc3,0x37,0x0,0x6f,0x0,0x7c,0x3c,0x2b,0xd0,0x5f,0x5a,0x27,0x6d,0xc3,0xda,0xb,0x4a,0x41,0x12,0x52,0x46,0xfb,0x47,0x83,0xde,0xd5,0xa2,0xcf,0x29,0x87,0xb3,0xda,0x3,0x3d,0xf0,0x16,0x52,0x83,0x1,0xa4,0x8c,0xda,0xcc,0x8c,0xb3,0x2,0xd,0x62,0xc6,0xd4,0x0,0xb4,0xec,0x6e,0xeb,0xb0,0x5a,0x18,0xd,0x2,0xd4,0x98,0xe9,0x0,0x6a,0xa6,0x85,0x51,0x33,0x35,0x8c,0xd6,0x21,0xa6,0xb2,0xbb,0xfd,0xaf,0x18,0xad,0x45,0x4c,0xc6,0x3f,0xce,0x9a,0xea,0xe8,0x14,0x84,0x9e,0x42,0x85,0xfe,0xe1,0xe3,0x7b,0x0,0x80,0xcf,0x9f,0xbe,0xe4,0xcf,0x4,0x5,0x0,0xe5,0xca,0xad,0x3b,0x71,0xca,0x28,0x7b,0xbd,0x86,0xed,0xd1,0xea,0x7d,0xb0,0x31,0xa7,0xae,0x22,0x46,0xe9,0x68,0x90,0xc8,0x50,0x8c,0x96,0x15,0x7f,0x55,0x90,0x12,0x97,0xa2,0x56,0xbc,0x18,0xaa,0x3c,0xfd,0xad,0x9,0x77,0xa0,0x4,0x40,0x30,0x9b,0x56,0x28,0x46,0x97,0x6e,0x2c,0xdf,0xec,0xfc,0xf8,0xd6,0x5,0x70,0xb8,0xf6,0xe4,0x81,0x6,0x0,0x22,0x82,0x10,0x2,0x33,0x33,0xb3,0x63,0x81,0xb6,0x0,0x5c,0x11,0x42,0xde,0x6,0x80,0x10,0x81,0x57,0x4a,0x2d,0x3,0x38,0xb2,0x97,0xce,0x8,0xd2,0xda,0xa0,0xd7,0xeb,0x15,0xe7,0x68,0xa6,0xfa,0xeb,0xd7,0x16,0xbc,0x3,0x95,0x42,0xe6,0x8a,0x9b,0xd2,0xba,0x93,0xb,0x94,0xec,0x17,0x62,0x22,0x5a,0x5c,0x7f,0xbd,0xbe,0x99,0x24,0xc9,0x8a,0x31,0x9e,0x56,0x11,0x21,0x11,0x45,0xd1,0xa6,0x10,0xf2,0x2e,0x80,0x5d,0x0,0xfb,0x96,0x55,0x4e,0x59,0x4d,0xc1,0x8a,0xc6,0x6c,0x99,0x44,0x62,0x38,0x8a,0xc3,0x8c,0x12,0xa8,0x39,0x40,0x6d,0x14,0x29,0x77,0xe1,0x24,0x9a,0x6,0x46,0x9,0x44,0xd4,0x9c,0xe5,0x6e,0x14,0x24,0xa5,0x2a,0x2,0x91,0x80,0x94,0xb2,0x2,0x50,0xe,0x9c,0x7,0x42,0xa4,0x20,0x85,0x44,0xab,0x15,0x39,0x0,0x65,0x6,0x98,0xfd,0xe1,0xb4,0xe7,0x8f,0x5a,0x1c,0xc7,0x0,0x4,0x94,0x54,0x88,0xe3,0xd9,0x62,0xa0,0x26,0x3b,0xc7,0x23,0xa5,0x6c,0x7d,0x8c,0x36,0xe9,0xb5,0xd5,0x67,0x13,0x3c,0x80,0x38,0x41,0xeb,0x87,0x51,0x87,0x54,0x53,0xe5,0xe7,0x64,0x7c,0xfa,0x4b,0xd2,0xbc,0x59,0x62,0xd4,0x9f,0x38,0x6f,0x1d,0xb9,0x9e,0xed,0x1c,0x7a,0xe,0x1c,0x7a,0xae,0x14,0x7a,0x9d,0x86,0xc0,0xbb,0x98,0xc0,0x76,0x5e,0x1a,0xcf,0x75,0x9,0xa3,0xda,0xe6,0x8f,0x47,0x31,0x81,0xad,0xf,0x7d,0x36,0x31,0x9d,0x88,0x9e,0x3,0x8b,0xbe,0xa2,0x98,0xd8,0x6,0xc7,0xa7,0x9c,0x5c,0x48,0x28,0x67,0xd4,0xd8,0xc8,0xfb,0x52,0x13,0xe3,0x74,0xb5,0xcf,0x29,0x59,0xa2,0x44,0x4b,0x36,0x3d,0xd9,0x2b,0x9f,0xb9,0x5a,0xaa,0x5e,0x9e,0xd8,0x3f,0xa3,0x39,0x44,0x54,0x62,0xd4,0xb7,0x90,0x8e,0x33,0xd4,0xe1,0x78,0x7,0x46,0x4d,0xb1,0x3c,0xeb,0x79,0xe4,0x50,0x5a,0xe,0x54,0xf9,0x11,0x69,0x9d,0xf3,0xd7,0x98,0x18,0x26,0x2f,0xf4,0x55,0x19,0xe5,0x0,0x1d,0x9f,0x1d,0xde,0x55,0x4e,0x5a,0xf2,0xd8,0xeb,0x79,0xcc,0x8,0xc9,0xfc,0x6f,0x32,0x6a,0x8e,0xc7,0x6,0x9f,0xbd,0x3e,0xb7,0xea,0x57,0x9d,0x9e,0xc0,0x1,0x7a,0x7d,0xee,0x4c,0x52,0x75,0x70,0x1e,0xb3,0x7c,0xf9,0x5e,0xee,0x26,0x1b,0x9c,0x7d,0xa6,0x28,0xb9,0xf9,0x53,0x4e,0x37,0xec,0x71,0x67,0xe2,0x31,0xbd,0x64,0x82,0x9d,0x29,0x40,0xe8,0x1d,0x48,0x10,0xe7,0x17,0xf3,0x6a,0x3e,0x94,0x7b,0x78,0x3c,0x85,0x9e,0xdc,0x56,0x68,0x51,0x50,0xd8,0x78,0x6b,0x7b,0xa3,0xd3,0x8a,0x62,0x6f,0xf,0x71,0x1,0xc0,0x18,0x8d,0x56,0x14,0xaf,0x6c,0x6d,0x6f,0x74,0x32,0xbf,0x6b,0xab,0x4f,0x79,0x82,0xd0,0x37,0xc3,0x44,0x3,0x12,0xd4,0xc9,0x97,0x28,0xd9,0x64,0x42,0x3,0x1d,0xeb,0xb3,0x8,0xa8,0x6,0xd0,0xa7,0xf2,0xbf,0x46,0xd5,0x50,0xf3,0x9,0x0,0xfa,0x27,0x4d,0xdb,0x1d,0xa8,0x6,0x90,0x0,0x38,0x90,0x52,0xee,0x29,0xe5,0xef,0xc1,0xb4,0x52,0xa,0x52,0xc9,0x3d,0x0,0x7,0xd6,0xa7,0xae,0x52,0x9e,0xc,0x80,0x43,0x0,0xdd,0x9d,0x9f,0x9d,0x77,0xb,0xb,0x4b,0x6f,0xf5,0x40,0xcf,0xd7,0xdd,0x9d,0x8,0x4,0x29,0xe5,0xee,0xce,0x4e,0xe7,0x3d,0x80,0xae,0xf5,0x69,0xda,0xed,0x39,0xe7,0x4e,0x2b,0x1,0xc4,0x0,0x2e,0x3,0x98,0x7,0x30,0x67,0x5f,0xc7,0x18,0xf7,0xcb,0xc5,0x64,0xb3,0x5d,0xdf,0x32,0xd9,0x5,0x90,0xb1,0xda,0xcf,0x63,0xb5,0x88,0xd1,0xc4,0xbe,0x1e,0x0,0xf8,0xd,0x20,0xb2,0x37,0x50,0x57,0x49,0x33,0x43,0x29,0x76,0x68,0x1,0x26,0xf9,0x9b,0x5e,0x31,0x33,0xd9,0x2f,0x78,0xd9,0x25,0x6b,0x62,0x73,0x94,0x55,0x6d,0xc1,0x99,0x73,0xa8,0x34,0xe1,0xa6,0xc1,0x63,0x7b,0xf9,0xe2,0x15,0xf6,0xba,0xbb,0x8d,0xef,0x4c,0x8d,0xb1,0x3f,0x4,0x3,0x19,0xf6,0x18,0xa6,0x30,0xaf,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x2a,0x0,0x0,0x0,0x46,0x8,0x6,0x0,0x0,0x0,0xba,0xf5,0x6,0x7a,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xe0,0x3,0x3,0xc,0x31,0x2b,0xec,0x7e,0x63,0x8a,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x2,0xdc,0x49,0x44,0x41,0x54,0x68,0xde,0xed,0x9a,0xdd,0x6a,0x13,0x41,0x14,0xc7,0x7f,0xf3,0x91,0x8d,0x95,0xd2,0xa2,0x6,0x5b,0x89,0xad,0xe2,0x85,0xbe,0x40,0x41,0xd0,0x7b,0xdf,0x42,0xa9,0xaf,0xa6,0x4f,0xd5,0x5e,0x48,0x3f,0xb4,0x58,0x48,0x91,0x96,0x62,0xdb,0x4d,0x66,0x8e,0x17,0x99,0xd8,0x2a,0x36,0x3b,0xdb,0xec,0x6c,0x36,0xb2,0x7,0x6,0xb2,0xb0,0x3b,0xf3,0x9f,0xff,0xf9,0x9c,0x39,0x81,0x56,0x5a,0x69,0xb6,0xa8,0xa2,0x17,0xbe,0x7f,0x3b,0xfd,0x4,0xbc,0x4f,0x8c,0xe3,0xf3,0x7a,0x7f,0xf5,0xc3,0xac,0x40,0xc5,0xb9,0x1c,0x2f,0x2e,0x9,0x42,0xad,0xc,0xc6,0x64,0xac,0xf7,0x57,0xa7,0x62,0xb1,0x31,0x93,0x8d,0xdc,0x28,0x19,0x95,0x9e,0x11,0xc6,0x64,0xc5,0x1b,0x5a,0x14,0x1b,0x8d,0x62,0x54,0x44,0x5a,0xa0,0x2d,0xd0,0x16,0x68,0x15,0x40,0xbd,0xf7,0x2d,0xa3,0xd5,0x32,0x3a,0x7f,0x9c,0x91,0x8c,0x2e,0x80,0xea,0x4d,0xd3,0x55,0x6f,0x80,0xec,0xd9,0xc6,0x8b,0x95,0x31,0xa3,0xcd,0xb6,0x51,0x33,0x1c,0xe5,0x4b,0x4d,0x67,0x74,0x19,0xe8,0x67,0x9d,0xee,0x56,0x53,0xc2,0x93,0x9e,0xa6,0x7a,0x11,0x7f,0x7f,0xc2,0x68,0xca,0x1,0xb0,0xf6,0xf8,0xc9,0x3b,0xe0,0x39,0xb0,0x54,0x86,0xd1,0x15,0x60,0x53,0x6b,0xf3,0x6,0xa0,0xe,0xc5,0x5b,0x6b,0x5f,0x3,0xe7,0xc0,0x19,0x70,0x51,0xc6,0x46,0xd5,0x84,0xf1,0x47,0xf,0x7b,0xc9,0x81,0x1a,0x6d,0x0,0x3a,0x65,0x6c,0xd4,0x84,0xf,0x1e,0x28,0xa5,0x9e,0x6e,0x7f,0xdc,0x26,0xcf,0x73,0xbc,0x4f,0x74,0x14,0xd1,0x86,0x2c,0xcb,0xd0,0xda,0xbc,0x5,0x76,0x81,0x2f,0xc0,0x29,0xe0,0x1a,0x59,0xe1,0x2b,0xa5,0x74,0xc0,0x63,0x9a,0x7e,0x14,0x31,0x1,0x8f,0x6e,0x34,0xd0,0xc0,0xa8,0x59,0x4,0x46,0xd5,0x34,0x3c,0x36,0x7a,0x9a,0x39,0x27,0xa7,0x62,0xa0,0x22,0x20,0x92,0xe,0x67,0x98,0x7f,0x26,0xa0,0x7e,0x32,0x4f,0x42,0x4a,0x25,0xac,0xe1,0x67,0x66,0x94,0x3f,0xd0,0xa6,0x61,0xb4,0xa,0xd5,0x4f,0x72,0x71,0x42,0xe5,0x47,0x55,0x67,0x7a,0xde,0x7e,0x24,0x95,0x39,0x53,0x50,0x8f,0x34,0x5a,0xf5,0x6e,0xac,0xf2,0xe4,0xce,0x84,0xfc,0x95,0xd9,0x4b,0x33,0xea,0x82,0xfd,0x24,0x74,0x26,0x26,0x35,0xa9,0xab,0xe2,0x5c,0x9f,0xce,0x99,0x62,0x4d,0x4a,0x47,0xec,0x37,0xb9,0x3b,0xc5,0x90,0x50,0xcc,0xa8,0xf,0x9a,0x4f,0xe5,0x4d,0x42,0x71,0xb4,0x2f,0x62,0xd4,0x31,0x31,0x4f,0x49,0xca,0x67,0x84,0x2f,0xc5,0xd8,0xa8,0xa4,0x67,0x94,0xa,0x2,0xbe,0xd4,0xc0,0x68,0xc,0x7,0x11,0x8c,0xfa,0x72,0xee,0x79,0x27,0xf1,0xb3,0x3,0xf5,0x21,0xce,0xa5,0x4b,0x4c,0x82,0xaf,0xc2,0xeb,0xa5,0x86,0x8c,0x1f,0x33,0xb3,0x8d,0xf2,0xa5,0x84,0xb9,0x5e,0x22,0x4b,0xc8,0xff,0x85,0x51,0xff,0xbb,0x6c,0x48,0x99,0xeb,0x63,0xa2,0x7e,0x61,0xf5,0x84,0xd4,0x90,0xeb,0x8b,0x6b,0x92,0x88,0xc2,0x39,0xf2,0xf0,0x35,0xd7,0xc3,0x5d,0x2d,0x65,0xbe,0x8a,0x7b,0xcd,0x46,0x6d,0x38,0xe1,0x99,0x49,0x22,0x73,0x89,0x8e,0x9a,0x2a,0xb5,0xea,0x91,0x8a,0x80,0x26,0x97,0x8a,0x6c,0x54,0x48,0x57,0x3d,0x49,0xa4,0x8d,0xea,0x5b,0x82,0x92,0x3,0xfc,0xe1,0xd1,0xde,0x7e,0x27,0xeb,0x26,0xbb,0xc4,0x5,0xf0,0xde,0xd1,0xc9,0xba,0x1c,0x1e,0xed,0xed,0x87,0x60,0xea,0xfe,0x15,0xac,0x16,0xe6,0xaf,0x1a,0x45,0x40,0xeb,0xec,0xdb,0xf8,0xbb,0x0,0xf5,0xc0,0x90,0x7a,0x2f,0x1b,0x25,0xac,0xe9,0xcb,0x0,0x75,0xc0,0x15,0x70,0xae,0x62,0x23,0xf2,0x4c,0x31,0x5f,0xc1,0xb8,0x75,0x73,0x75,0x5b,0x32,0xbd,0xd,0xe8,0x25,0xe3,0x7e,0xcf,0xc0,0x18,0x83,0xb5,0x36,0x19,0x48,0x6b,0x2d,0xc6,0x1a,0x80,0x41,0x58,0xf3,0xb2,0x4c,0x78,0xca,0xc3,0x87,0x7,0x83,0x93,0xe3,0x9d,0x5e,0x6f,0xed,0x95,0x1b,0xb9,0xca,0xb3,0x93,0x42,0x61,0x8c,0x61,0x30,0x38,0xde,0x1,0xe,0xc2,0x9a,0x79,0x99,0x4c,0xbb,0x4,0xf4,0x80,0xd,0xe0,0x25,0xb0,0x19,0x9e,0x97,0x29,0xb8,0x6b,0x2f,0xe1,0x38,0x12,0xd4,0x3d,0x8,0x20,0x77,0x81,0xc3,0xf0,0x7c,0x51,0x86,0xd1,0x1f,0xe1,0xf7,0x4f,0xe0,0x2b,0xe3,0xb6,0x63,0x97,0x29,0xdd,0xb5,0x92,0x32,0xc,0x36,0x79,0x16,0xc0,0x9d,0x84,0x35,0x4b,0x31,0xa,0xa1,0x71,0x7b,0x63,0xdc,0xe3,0xba,0x17,0x54,0x55,0x38,0x72,0xc1,0x26,0xf3,0x1b,0xc3,0xd1,0x4a,0x2b,0xd7,0xf2,0xb,0x3d,0xd,0xa0,0xd0,0x7a,0xcf,0xaf,0x5e,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 4620bf567a..a72cc6a47f 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -51,7 +51,7 @@ public:
enum BGParam {
BG_PARAM_CANVAS_MAX_LAYER=VS::ENV_BG_PARAM_CANVAS_MAX_LAYER,
- BG_PARAM_COLOR=VS::ENV_BG_PARAM_COLOR,
+ BG_PARAM_COLOR=VS::ENV_BG_PARAM_COLOR,
BG_PARAM_TEXTURE=VS::ENV_BG_PARAM_TEXTURE,
BG_PARAM_CUBEMAP=VS::ENV_BG_PARAM_CUBEMAP,
BG_PARAM_ENERGY=VS::ENV_BG_PARAM_ENERGY,
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 0aae6fd978..ef5b7a3eb0 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -272,24 +272,24 @@ Error Font::create_from_fnt(const String& p_string) {
void Font::set_height(float p_height) {
-
+
height=p_height;
}
float Font::get_height() const{
-
+
return height;
}
void Font::set_ascent(float p_ascent){
-
+
ascent=p_ascent;
}
float Font::get_ascent() const {
-
+
return ascent;
}
float Font::get_descent() const {
-
+
return height-ascent;
}
@@ -349,7 +349,7 @@ void Font::add_char(CharType p_char, int p_texture_idx, const Rect2& p_rect, con
c.v_align=p_align.y;
c.advance=p_advance;
c.h_align=p_align.x;
-
+
char_map[p_char]=c;
}
@@ -411,7 +411,7 @@ bool Font::is_distance_field_hint() const{
void Font::clear() {
-
+
height=1;
ascent=0;
char_map.clear();
@@ -423,14 +423,14 @@ void Font::clear() {
Size2 Font::get_string_size(const String& p_string) const {
float w=0;
-
+
int l = p_string.length();
if (l==0)
return Size2(0,height);
const CharType *sptr = &p_string[0];
for (int i=0;i<l;i++) {
-
+
w+=get_char_size(sptr[i],sptr[i+1]).width;
}
@@ -461,9 +461,9 @@ void Font::draw_halign(RID p_canvas_item, const Point2& p_pos, HAlign p_align,fl
}
void Font::draw(RID p_canvas_item, const Point2& p_pos, const String& p_text, const Color& p_modulate,int p_clip_w) const {
-
+
Vector2 ofs;
-
+
for (int i=0;i<p_text.length();i++) {
int width = get_char_size(p_text[i]).width;
@@ -476,15 +476,15 @@ void Font::draw(RID p_canvas_item, const Point2& p_pos, const String& p_text, co
}
float Font::draw_char(RID p_canvas_item, const Point2& p_pos, const CharType& p_char,const CharType& p_next,const Color& p_modulate) const {
-
+
const Character * c = char_map.getptr(p_char);
-
+
if (!c) {
if (fallback.is_valid())
return fallback->draw_char(p_canvas_item,p_pos,p_char,p_next,p_modulate);
return 0;
}
-
+
Point2 cpos=p_pos;
cpos.x+=c->h_align;
cpos.y-=ascent;
@@ -492,7 +492,7 @@ float Font::draw_char(RID p_canvas_item, const Point2& p_pos, const CharType& p_
ERR_FAIL_COND_V( c->texture_idx<-1 || c->texture_idx>=textures.size(),0);
if (c->texture_idx!=-1)
VisualServer::get_singleton()->canvas_item_add_texture_rect_region( p_canvas_item, Rect2( cpos, c->rect.size ), textures[c->texture_idx]->get_rid(),c->rect, p_modulate );
-
+
return get_char_size(p_char,p_next).width;
}
@@ -561,16 +561,16 @@ void Font::_bind_methods() {
}
Font::Font() {
-
+
clear();
-
+
}
Font::~Font() {
-
+
clear();
}
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 61f0352992..03b1ec5191 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -36,21 +36,21 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Font : public Resource {
-
+
OBJ_TYPE( Font, Resource );
RES_BASE_EXTENSION("fnt");
-
+
Vector< Ref<Texture> > textures;
public:
struct Character {
-
+
int texture_idx;
Rect2 rect;
float v_align;
float h_align;
float advance;
-
+
Character() { texture_idx=0; v_align=0; }
};
@@ -69,10 +69,10 @@ public:
private:
-
+
HashMap< CharType, Character > char_map;
Map<KerningPairKey,int> kerning_map;
-
+
float height;
float ascent;
bool distance_field_hint;
@@ -86,20 +86,20 @@ private:
Ref<Font> fallback;
protected:
-
+
static void _bind_methods();
public:
Error create_from_fnt(const String& p_file);
-
+
void set_height(float p_height);
float get_height() const;
-
+
void set_ascent(float p_ascent);
- float get_ascent() const;
+ float get_ascent() const;
float get_descent() const;
-
+
void add_texture(const Ref<Texture>& p_texture);
void add_char(CharType p_char, int p_texture_idx, const Rect2& p_rect, const Size2& p_align, float p_advance=-1);
@@ -116,7 +116,7 @@ public:
inline Size2 get_char_size(CharType p_char,CharType p_next=0) const;
Size2 get_string_size(const String& p_string) const;
-
+
void set_fallback(const Ref<Font> &p_fallback);
Ref<Font> get_fallback() const;
@@ -125,11 +125,11 @@ public:
void set_distance_field_hint(bool p_distance_field);
bool is_distance_field_hint() const;
-
+
void draw(RID p_canvas_item, const Point2& p_pos, const String& p_text,const Color& p_modulate=Color(1,1,1),int p_clip_w=-1) const;
void draw_halign(RID p_canvas_item, const Point2& p_pos, HAlign p_align,float p_width,const String& p_text,const Color& p_modulate=Color(1,1,1)) const;
float draw_char(RID p_canvas_item, const Point2& p_pos, const CharType& p_char,const CharType& p_next=0,const Color& p_modulate=Color(1,1,1)) const;
-
+
Font();
~Font();
};
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 96b33ce129..dbd05c466f 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -41,7 +41,7 @@
class Material : public Resource {
- OBJ_TYPE(Material,Resource);
+ OBJ_TYPE(Material,Resource);
RES_BASE_EXTENSION("mtl");
OBJ_SAVE_TYPE( Material );
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 9537fa269f..09c0a21f53 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -126,7 +126,7 @@ bool Mesh::_set(const StringName& p_name, const Variant& p_value) {
add_custom_surface(p_value);
return true;
- }
+ }
//create
Dictionary d=p_value;
@@ -223,7 +223,7 @@ void Mesh::_get_property_list( List<PropertyInfo> *p_list) const {
}
for (int i=0;i<surfaces.size();i++) {
-
+
p_list->push_back( PropertyInfo( Variant::DICTIONARY,"surfaces/"+itos(i), PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR ) );
p_list->push_back( PropertyInfo( Variant::STRING,"surface_"+itos(i+1)+"/name", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR ) );
p_list->push_back( PropertyInfo( Variant::OBJECT,"surface_"+itos(i+1)+"/material", PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
@@ -238,9 +238,9 @@ void Mesh::_recompute_aabb() {
// regenerate AABB
aabb=AABB();
-
+
for (int i=0;i<surfaces.size();i++) {
-
+
if (i==0)
aabb=surfaces[i].aabb;
else
@@ -383,7 +383,7 @@ void Mesh::surface_remove(int p_idx) {
ERR_FAIL_INDEX(p_idx, surfaces.size() );
VisualServer::get_singleton()->mesh_remove_surface(mesh,p_idx);
surfaces.remove(p_idx);
-
+
triangle_mesh=Ref<TriangleMesh>();
_recompute_aabb();
_change_notify();
@@ -472,14 +472,14 @@ void Mesh::add_surface_from_mesh_data(const Geometry::MeshData& p_mesh_data) {
VisualServer::get_singleton()->mesh_add_surface_from_mesh_data( mesh, p_mesh_data );
AABB aabb;
for (int i=0;i<p_mesh_data.vertices.size();i++) {
-
+
if (i==0)
aabb.pos=p_mesh_data.vertices[i];
else
aabb.expand_to(p_mesh_data.vertices[i]);
}
-
+
Surface s;
s.aabb=aabb;
if (surfaces.size()==0)
@@ -524,60 +524,60 @@ DVector<Face3> Mesh::get_faces() const {
return DVector<Face3>();
/*
for (int i=0;i<surfaces.size();i++) {
-
+
if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES )
continue;
-
+
DVector<int> indices;
DVector<Vector3> vertices;
-
+
vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX);
-
+
int len=VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i);
bool has_indices;
-
+
if (len>0) {
-
+
indices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_INDEX);
has_indices=true;
-
+
} else {
-
+
len=vertices.size();
has_indices=false;
}
-
+
if (len<=0)
continue;
-
+
DVector<int>::Read indicesr = indices.read();
const int *indicesptr = indicesr.ptr();
-
+
DVector<Vector3>::Read verticesr = vertices.read();
const Vector3 *verticesptr = verticesr.ptr();
-
+
int old_faces=faces.size();
int new_faces=old_faces+(len/3);
-
+
faces.resize(new_faces);
-
+
DVector<Face3>::Write facesw = faces.write();
Face3 *facesptr=facesw.ptr();
-
-
+
+
for (int i=0;i<len/3;i++) {
-
+
Face3 face;
-
+
for (int j=0;j<3;j++) {
-
+
int idx=i*3+j;
face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx];
}
-
+
facesptr[i+old_faces]=face;
}
-
+
}
*/
@@ -993,17 +993,17 @@ void Mesh::_bind_methods() {
BIND_CONSTANT( NO_INDEX_ARRAY );
BIND_CONSTANT( ARRAY_WEIGHTS_SIZE );
-
+
BIND_CONSTANT( ARRAY_VERTEX );
BIND_CONSTANT( ARRAY_NORMAL );
BIND_CONSTANT( ARRAY_TANGENT );
BIND_CONSTANT( ARRAY_COLOR );
- BIND_CONSTANT( ARRAY_TEX_UV );
+ BIND_CONSTANT( ARRAY_TEX_UV );
BIND_CONSTANT( ARRAY_TEX_UV2 );
BIND_CONSTANT( ARRAY_BONES );
BIND_CONSTANT( ARRAY_WEIGHTS );
BIND_CONSTANT( ARRAY_INDEX );
-
+
BIND_CONSTANT( ARRAY_FORMAT_VERTEX );
BIND_CONSTANT( ARRAY_FORMAT_NORMAL );
BIND_CONSTANT( ARRAY_FORMAT_TANGENT );
@@ -1013,7 +1013,7 @@ void Mesh::_bind_methods() {
BIND_CONSTANT( ARRAY_FORMAT_BONES );
BIND_CONSTANT( ARRAY_FORMAT_WEIGHTS );
BIND_CONSTANT( ARRAY_FORMAT_INDEX );
-
+
BIND_CONSTANT( PRIMITIVE_POINTS );
BIND_CONSTANT( PRIMITIVE_LINES );
BIND_CONSTANT( PRIMITIVE_LINE_STRIP );
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index e0d9bdf7a8..dc1d97a49e 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -43,9 +43,9 @@ class Mesh : public Resource {
RES_BASE_EXTENSION("msh");
public:
-
+
enum {
-
+
NO_INDEX_ARRAY=VisualServer::NO_INDEX_ARRAY,
ARRAY_WEIGHTS_SIZE=VisualServer::ARRAY_WEIGHTS_SIZE
};
@@ -63,8 +63,8 @@ public:
ARRAY_INDEX=VisualServer::ARRAY_INDEX,
ARRAY_MAX=VisualServer::ARRAY_MAX
- };
-
+ };
+
enum ArrayFormat {
/* ARRAY FORMAT FLAGS */
ARRAY_FORMAT_VERTEX=1<<ARRAY_VERTEX, // mandatory
@@ -77,8 +77,8 @@ public:
ARRAY_FORMAT_WEIGHTS=1<<ARRAY_WEIGHTS,
ARRAY_FORMAT_INDEX=1<<ARRAY_INDEX,
- };
-
+ };
+
enum PrimitiveType {
PRIMITIVE_POINTS=VisualServer::PRIMITIVE_POINTS,
PRIMITIVE_LINES=VisualServer::PRIMITIVE_LINES,
@@ -87,7 +87,7 @@ public:
PRIMITIVE_TRIANGLES=VisualServer::PRIMITIVE_TRIANGLES,
PRIMITIVE_TRIANGLE_STRIP=VisualServer::PRIMITIVE_TRIANGLE_STRIP,
PRIMITIVE_TRIANGLE_FAN=VisualServer::PRIMITIVE_TRIANGLE_FAN,
- };
+ };
enum MorphTargetMode {
@@ -95,7 +95,7 @@ public:
MORPH_MODE_RELATIVE=VS::MORPH_MODE_RELATIVE,
};
-private:
+private:
struct Surface {
String name;
AABB aabb;
@@ -111,16 +111,16 @@ private:
mutable Ref<TriangleMesh> triangle_mesh;
-
+
void _recompute_aabb();
protected:
-
+
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
+
static void _bind_methods();
-
+
public:
void add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array(),bool p_alphasort=false);
@@ -174,7 +174,7 @@ public:
DVector<Face3> get_faces() const;
Ref<TriangleMesh> generate_triangle_mesh() const;
Mesh();
-
+
~Mesh();
};
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 8643e96303..76bb1c585f 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -103,7 +103,7 @@ void MeshLibrary::create_item(int p_item) {
void MeshLibrary::set_item_name(int p_item,const String& p_name) {
ERR_FAIL_COND(!item_map.has(p_item));
- item_map[p_item].name=p_name;
+ item_map[p_item].name=p_name;
emit_changed();
_change_notify();
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 9a468d5555..bf0107d7a9 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -56,7 +56,7 @@ protected:
void _get_property_list( List<PropertyInfo> *p_list) const;
static void _bind_methods();
-public:
+public:
void create_item(int p_item);
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 43196a43d4..ef04c68e8e 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -226,7 +226,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
node->add_to_group( snames[ n.groups[j] ], true );
}
- if (n.instance>=0 || n.type!=TYPE_INSTANCED) {
+ if (n.instance>=0 || n.type!=TYPE_INSTANCED || i==0) {
//if node was not part of instance, must set it's name, parenthood and ownership
if (i>0) {
if (parent) {
@@ -239,7 +239,6 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
} else {
node->_set_name_nocheck( snames[ n.name ] );
}
-
}
if (n.owner>=0) {
@@ -647,7 +646,7 @@ https://github.com/godotengine/godot/issues/3127
}
// Save the right type. If this node was created by an instance
- // then flag that the node should not be created but reused
+ // then flag that the node should not be created but reused
if (pack_state_stack.empty()) {
//this node is not part of an instancing process, so save the type
nd.type=_nm_get_string(p_node->get_type(),name_map);
@@ -964,7 +963,7 @@ Ref<SceneState> SceneState::_get_base_scene_state() const {
int SceneState::find_node_by_path(const NodePath& p_node) const {
- if (!node_path_cache.has(p_node)) {
+ if (!node_path_cache.has(p_node)) {
if (_get_base_scene_state().is_valid()) {
int idx = _get_base_scene_state()->find_node_by_path(p_node);
if (idx>=0) {
@@ -1276,7 +1275,7 @@ Dictionary SceneState::get_bundled_scene() const {
rnode_paths.resize(node_paths.size());
for(int i=0;i<node_paths.size();i++) {
rnode_paths[i]=node_paths[i];
- }
+ }
d["node_paths"]=rnode_paths;
Array reditable_instances;
@@ -1317,11 +1316,23 @@ StringName SceneState::get_node_name(int p_idx) const {
return names[nodes[p_idx].name];
}
+
+bool SceneState::is_node_instance_placeholder(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,nodes.size(),false);
+
+ return nodes[p_idx].instance>=0 && nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER;
+
+}
+
Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,nodes.size(),Ref<PackedScene>());
if (nodes[p_idx].instance>=0) {
- return variants[nodes[p_idx].instance];
+ if (nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER)
+ return Ref<PackedScene>();
+ else
+ return variants[nodes[p_idx].instance&FLAG_MASK];
} else if (nodes[p_idx].parent<0 || nodes[p_idx].parent==NO_PARENT_SAVED) {
if (base_scene_idx>=0) {
@@ -1335,6 +1346,19 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
}
+
+String SceneState::get_node_instance_placeholder(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,nodes.size(),String());
+
+ if (nodes[p_idx].instance>=0 && nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER) {
+ return variants[nodes[p_idx].instance&FLAG_MASK];
+ }
+
+ return String();
+
+}
+
Vector<StringName> SceneState::get_node_groups(int p_idx) const{
ERR_FAIL_INDEX_V(p_idx,nodes.size(),Vector<StringName>());
Vector<StringName> groups;
@@ -1578,6 +1602,8 @@ void SceneState::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_node_name","idx"),&SceneState::get_node_name);
ObjectTypeDB::bind_method(_MD("get_node_path","idx","for_parent"),&SceneState::get_node_path,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_node_owner_path","idx"),&SceneState::get_node_owner_path);
+ ObjectTypeDB::bind_method(_MD("is_node_instance_placeholder","idx"),&SceneState::is_node_instance_placeholder);
+ ObjectTypeDB::bind_method(_MD("get_node_instance_placeholder","idx"),&SceneState::get_node_instance_placeholder);
ObjectTypeDB::bind_method(_MD("get_node_instance:PackedScene","idx"),&SceneState::get_node_instance);
ObjectTypeDB::bind_method(_MD("get_node_groups","idx"),&SceneState::_get_node_groups);
ObjectTypeDB::bind_method(_MD("get_node_property_count","idx"),&SceneState::get_node_property_count);
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 7fda4392d8..6bde508d72 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -48,11 +48,7 @@ class SceneState : public Reference {
int base_scene_idx;
enum {
- FLAG_ID_IS_PATH=(1<<30),
- FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30),
- FLAG_MASK=(1<<24)-1,
NO_PARENT_SAVED=0x7FFFFFFF,
-
};
struct NodeData {
@@ -70,7 +66,7 @@ class SceneState : public Reference {
};
Vector<Property> properties;
- Vector<int> groups;
+ Vector<int> groups;
};
@@ -115,7 +111,10 @@ protected:
public:
enum {
- TYPE_INSTANCED=0x7FFFFFFF
+ FLAG_ID_IS_PATH=(1<<30),
+ TYPE_INSTANCED=0x7FFFFFFF,
+ FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30),
+ FLAG_MASK=(1<<24)-1,
};
static void set_disable_placeholders(bool p_disable);
@@ -148,6 +147,8 @@ public:
NodePath get_node_path(int p_idx,bool p_for_parent=false) const;
NodePath get_node_owner_path(int p_idx) const;
Ref<PackedScene> get_node_instance(int p_idx) const;
+ String get_node_instance_placeholder(int p_idx) const;
+ bool is_node_instance_placeholder(int p_idx) const;
Vector<StringName> get_node_groups(int p_idx) const;
int get_node_property_count(int p_idx) const;
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index e8cdec66df..1a7dc56e40 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -545,7 +545,7 @@ Vector2 PolygonPathFinder::get_closest_point(const Vector2& p_point) const {
closest_point=closest;
}
}
-
+
ERR_FAIL_COND_V(closest_dist==1e20,Vector2());
return closest_point;
diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h
index 2cbe3e949d..b23dbd0bac 100644
--- a/scene/resources/polygon_path_finder.h
+++ b/scene/resources/polygon_path_finder.h
@@ -61,7 +61,7 @@ public:
bool is_point_inside(const Vector2& p_point) const;
Vector2 get_closest_point(const Vector2& p_point) const;
- Vector<Vector2> get_intersections(const Vector2& p_from, const Vector2& p_to) const;
+ Vector<Vector2> get_intersections(const Vector2& p_from, const Vector2& p_to) const;
Rect2 get_bounds() const;
diff --git a/scene/resources/room.cpp b/scene/resources/room.cpp
index 0f9eb85244..4024e2f45c 100644
--- a/scene/resources/room.cpp
+++ b/scene/resources/room.cpp
@@ -48,7 +48,7 @@ BSP_Tree RoomBounds::get_bounds() const {
}
void RoomBounds::set_geometry_hint(const DVector<Face3>& p_geometry_hint) {
-
+
geometry_hint=p_geometry_hint;
}
diff --git a/scene/resources/room.h b/scene/resources/room.h
index c5aaea311e..a9f159cd46 100644
--- a/scene/resources/room.h
+++ b/scene/resources/room.h
@@ -38,8 +38,8 @@ class RoomBounds : public Resource {
OBJ_TYPE( RoomBounds, Resource );
RES_BASE_EXTENSION("room");
-
- RID area;
+
+ RID area;
DVector<Face3> geometry_hint;
void _regenerate_bsp();
@@ -54,10 +54,10 @@ public:
void set_bounds( const BSP_Tree& p_bounds );
BSP_Tree get_bounds() const;
-
+
void set_geometry_hint(const DVector<Face3>& geometry_hint);
const DVector<Face3>& get_geometry_hint() const;
-
+
RoomBounds();
~RoomBounds();
diff --git a/scene/resources/sample.cpp b/scene/resources/sample.cpp
index 4b25a2c490..87fcfc425d 100644
--- a/scene/resources/sample.cpp
+++ b/scene/resources/sample.cpp
@@ -151,8 +151,8 @@ void Sample::set_loop_format(LoopFormat p_format) {
if (sample.is_valid())
AudioServer::get_singleton()->sample_set_loop_format(sample,(AudioServer::SampleLoopFormat)p_format);
loop_format=p_format;
-
}
+
Sample::LoopFormat Sample::get_loop_format() const {
return loop_format;
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index d9f6beabc0..f9f7f7807d 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -389,6 +389,22 @@ Error ResourceInteractiveLoaderText::poll() {
}
}
+ if (next_tag.fields.has("instance_placeholder")) {
+
+ String path=next_tag.fields["instance_placeholder"];
+
+ int path_v = packed_scene->get_state()->add_value(path);
+
+ if (packed_scene->get_state()->get_node_count()==0) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Instance Placeholder can't be used for inheritance.";
+ _printerr();
+ return error;
+ }
+
+ instance=path_v|SceneState::FLAG_INSTANCE_IS_PLACEHOLDER;
+ }
+
if (next_tag.fields.has("owner")) {
owner=packed_scene->get_state()->add_node_path(next_tag.fields["owner"]);
} else {
@@ -720,6 +736,7 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const
fw->store_8(c);
c=f->get_8();
}
+ f->close();
bool all_ok = fw->get_error()==OK;
@@ -1124,6 +1141,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
if (packed_scene.is_valid()) {
//add instances to external resources if saving a packed scene
for(int i=0;i<packed_scene->get_state()->get_node_count();i++) {
+ if (packed_scene->get_state()->is_node_instance_placeholder(i))
+ continue;
+
Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i);
if (instance.is_valid() && !external_resources.has(instance)) {
int index = external_resources.size();
@@ -1268,8 +1288,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
NodePath path = state->get_node_path(i,true);
NodePath owner = state->get_node_owner_path(i);
Ref<PackedScene> instance = state->get_node_instance(i);
+ String instance_placeholder = state->get_node_instance_placeholder(i);
Vector<StringName> groups = state->get_node_groups(i);
+
if (instance.is_valid())
print_line("for path "+String(path)+" instance "+instance->get_path());
@@ -1298,6 +1320,14 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
f->store_string(header);
+ if (instance_placeholder!=String()) {
+
+ String vars;
+ f->store_string(" instance_placeholder=");
+ VariantWriter::write_to_string(instance_placeholder,vars,_write_resources,this);
+ f->store_string(vars);
+ }
+
if (instance.is_valid()) {
String vars;
diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp
index eabc84c41e..40ae26ba5d 100644
--- a/scene/resources/shader_graph.cpp
+++ b/scene/resources/shader_graph.cpp
@@ -1351,13 +1351,21 @@ ShaderGraph::ShaderGraph(Mode p_mode) : Shader(p_mode) {
//shader = VisualServer::get_singleton()->shader_create();
_pending_update_shader=false;
- Node out;
- out.id=0;
- out.pos=Vector2(250,20);
- out.type=NODE_OUTPUT;
+
+ Node input;
+ input.id=1;
+ input.pos=Vector2(50,40);
+ input.type=NODE_INPUT;
+
+ Node output;
+ output.id=0;
+ output.pos=Vector2(350,40);
+ output.type=NODE_OUTPUT;
+
for(int i=0;i<3;i++) {
- shader[i].node_map.insert(0,out);
+ shader[i].node_map.insert(0,output);
+ shader[i].node_map.insert(1,input);
}
}
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 71a775ee24..75e38f9701 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -37,7 +37,7 @@ void StyleBox::set_default_margin(Margin p_margin, float p_value) {
margin[p_margin]=p_value;
emit_changed();
-
+
}
float StyleBox::get_default_margin(Margin p_margin) const{
@@ -59,7 +59,7 @@ Size2 StyleBox::get_minimum_size() const {
Point2 StyleBox::get_offset() const {
-
+
return Point2( get_margin( MARGIN_LEFT), get_margin( MARGIN_TOP) );
}
@@ -94,33 +94,33 @@ void StyleBox::_bind_methods() {
}
StyleBox::StyleBox() {
-
+
for (int i=0;i<4;i++) {
-
+
margin[i]=-1;
}
}
void StyleBoxTexture::set_texture(RES p_texture) {
-
+
texture=p_texture;
emit_changed();
}
RES StyleBoxTexture::get_texture() const {
-
+
return texture;
}
void StyleBoxTexture::set_margin_size(Margin p_margin,float p_size) {
-
+
margin[p_margin]=p_size;
emit_changed();
}
float StyleBoxTexture::get_margin_size(Margin p_margin) const {
-
+
return margin[p_margin];
}
@@ -142,14 +142,14 @@ void StyleBoxTexture::draw(RID p_canvas_item,const Rect2& p_rect) const {
}
void StyleBoxTexture::set_draw_center(bool p_draw) {
-
+
draw_center=p_draw;
emit_changed();
}
bool StyleBoxTexture::get_draw_center() const {
-
+
return draw_center;
}
@@ -204,18 +204,18 @@ void StyleBoxTexture::_bind_methods() {
}
StyleBoxTexture::StyleBoxTexture() {
-
-
+
+
for (int i=0;i<4;i++) {
margin[i]=0;
expand_margin[i]=0;
}
draw_center=true;
-
+
}
StyleBoxTexture::~StyleBoxTexture() {
-
-
+
+
}
////////////////
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index d0466ed5f1..02d79bc2ac 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -36,60 +36,60 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class StyleBox : public Resource {
-
+
OBJ_TYPE( StyleBox, Resource );
RES_BASE_EXTENSION("sbx");
OBJ_SAVE_TYPE( StyleBox );
float margin[4];
-
-protected:
-
+
+protected:
+
virtual float get_style_margin(Margin p_margin) const=0;
static void _bind_methods();
public:
-
+
virtual bool test_mask(const Point2& p_point, const Rect2& p_rect) const;
-
+
void set_default_margin(Margin p_margin, float p_value);
float get_default_margin(Margin p_margin) const;
float get_margin(Margin p_margin) const;
virtual Size2 get_center_size() const;
-
+
virtual void draw(RID p_canvas_item,const Rect2& p_rect) const=0;
-
+
Size2 get_minimum_size() const;
Point2 get_offset() const;
-
+
StyleBox();
};
class StyleBoxEmpty : public StyleBox {
-
+
OBJ_TYPE( StyleBoxEmpty, StyleBox );
virtual float get_style_margin(Margin p_margin) const { return 0; }
-public:
-
+public:
+
virtual void draw(RID p_canvas_item,const Rect2& p_rect) const {}
StyleBoxEmpty() {}
-
+
};
class StyleBoxTexture : public StyleBox {
-
+
OBJ_TYPE( StyleBoxTexture, StyleBox );
-
+
float expand_margin[4];
float margin[4];
Ref<Texture> texture;
bool draw_center;
-
-protected:
-
+
+protected:
+
virtual float get_style_margin(Margin p_margin) const;
static void _bind_methods();
-
+
public:
void set_expand_margin_size(Margin p_expand_margin,float p_size);
@@ -105,12 +105,12 @@ public:
bool get_draw_center() const;
virtual Size2 get_center_size() const;
-
+
virtual void draw(RID p_canvas_item,const Rect2& p_rect) const;
-
- StyleBoxTexture();
+
+ StyleBoxTexture();
~StyleBoxTexture();
-
+
};
class StyleBoxFlat : public StyleBox {
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index bf5070fd7d..e3a02420c7 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -324,7 +324,7 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) {
w=DVector<Color>::Write();
a[i]=array;
- } break;
+ } break;
case Mesh::ARRAY_FORMAT_BONES:
case Mesh::ARRAY_FORMAT_WEIGHTS: {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 28754480f1..1893bfe524 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -163,7 +163,7 @@ bool ImageTexture::_get(const StringName& p_name,Variant &r_ret) const {
r_ret= lossy_storage_quality;
else
return false;
-
+
return true;
}
@@ -171,8 +171,8 @@ bool ImageTexture::_get(const StringName& p_name,Variant &r_ret) const {
void ImageTexture::_get_property_list( List<PropertyInfo> *p_list) const {
-
-
+
+
PropertyHint img_hint=PROPERTY_HINT_NONE;
if (storage==STORAGE_COMPRESS_LOSSY) {
img_hint=PROPERTY_HINT_IMAGE_COMPRESS_LOSSY;
@@ -207,16 +207,16 @@ void ImageTexture::_reload_hook(const RID& p_hook) {
}
void ImageTexture::create(int p_width, int p_height,Image::Format p_format,uint32_t p_flags) {
-
+
flags=p_flags;
VisualServer::get_singleton()->texture_allocate(texture,p_width, p_height, p_format, p_flags);
format=p_format;
w=p_width;
h=p_height;
-
+
}
void ImageTexture::create_from_image(const Image& p_image, uint32_t p_flags) {
-
+
flags=p_flags;
w=p_image.get_width();
h=p_image.get_height();
@@ -228,7 +228,7 @@ void ImageTexture::create_from_image(const Image& p_image, uint32_t p_flags) {
}
void ImageTexture::set_flags(uint32_t p_flags) {
-
+
/* uint32_t cube = flags & FLAG_CUBEMAP;
@@ -238,11 +238,11 @@ void ImageTexture::set_flags(uint32_t p_flags) {
flags=p_flags|cube; */
flags=p_flags;
VisualServer::get_singleton()->texture_set_flags(texture,p_flags);
-
+
}
uint32_t ImageTexture::get_flags() const {
-
+
return ImageTexture::flags;
}
@@ -252,7 +252,7 @@ Image::Format ImageTexture::get_format() const {
}
void ImageTexture::load(const String& p_path) {
-
+
Image img;
img.load(p_path);
create_from_image(img);
@@ -260,7 +260,7 @@ void ImageTexture::load(const String& p_path) {
}
void ImageTexture::set_data(const Image& p_image) {
-
+
VisualServer::get_singleton()->texture_set_data(texture,p_image);
VisualServer::get_singleton()->texture_set_reload_hook(texture,0,StringName()); //hook is erased if data is changed
_change_notify();
@@ -282,23 +282,23 @@ void ImageTexture::_resource_path_changed() {
}
Image ImageTexture::get_data() const {
-
+
return VisualServer::get_singleton()->texture_get_data(texture);
}
int ImageTexture::get_width() const {
-
- return w;
+
+ return w;
}
int ImageTexture::get_height() const {
-
+
return h;
}
RID ImageTexture::get_rid() const {
-
+
return texture;
}
@@ -458,13 +458,13 @@ ImageTexture::ImageTexture() {
texture = VisualServer::get_singleton()->texture_create();
storage = STORAGE_RAW;
lossy_storage_quality=0.7;
-
+
}
ImageTexture::~ImageTexture() {
-
+
VisualServer::get_singleton()->free( texture );
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 2627b9480a..103b425cd8 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -84,7 +84,7 @@ VARIANT_ENUM_CAST( Texture::Flags );
class ImageTexture : public Texture {
-
+
OBJ_TYPE( ImageTexture, Texture );
RES_BASE_EXTENSION("tex");
public:
@@ -97,12 +97,12 @@ private:
RID texture;
Image::Format format;
uint32_t flags;
- int w,h;
+ int w,h;
Storage storage;
Size2 size_override;
float lossy_storage_quality;
-protected:
+protected:
virtual bool can_reload_from_file();
virtual void reload_from_file();
@@ -117,24 +117,24 @@ protected:
void _set_data(Dictionary p_data);
public:
-
+
void create(int p_width, int p_height,Image::Format p_format,uint32_t p_flags=FLAGS_DEFAULT);
void create_from_image(const Image& p_image, uint32_t p_flags=FLAGS_DEFAULT);
-
+
void set_flags(uint32_t p_flags);
uint32_t get_flags() const;
Image::Format get_format() const;
void load(const String& p_path);
void set_data(const Image& p_image);
Image get_data() const;
-
+
int get_width() const;
int get_height() const;
-
+
virtual RID get_rid() const;
-
+
bool has_alpha() const;
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 685b2e07e1..74e59b09c3 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -104,67 +104,67 @@ bool Theme::_get(const StringName& p_name,Variant &r_ret) const {
}
void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
-
+
List<PropertyInfo> list;
const StringName *key=NULL;
-
+
while((key=icon_map.next(key))) {
-
+
const StringName *key2=NULL;
-
+
while((key2=icon_map[*key].next(key2))) {
list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) );
}
}
-
+
key=NULL;
-
+
while((key=style_map.next(key))) {
-
+
const StringName *key2=NULL;
-
+
while((key2=style_map[*key].next(key2))) {
-
+
list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) );
}
}
-
+
key=NULL;
-
+
while((key=font_map.next(key))) {
-
+
const StringName *key2=NULL;
-
+
while((key2=font_map[*key].next(key2))) {
-
+
list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) );
}
}
-
+
key=NULL;
-
+
while((key=color_map.next(key))) {
-
+
const StringName *key2=NULL;
-
+
while((key2=color_map[*key].next(key2))) {
-
+
list.push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) );
}
}
-
+
key=NULL;
-
+
while((key=constant_map.next(key))) {
-
+
const StringName *key2=NULL;
-
+
while((key2=constant_map[*key].next(key2))) {
-
+
list.push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) );
}
}
@@ -173,12 +173,12 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
for(List<PropertyInfo>::Element *E=list.front();E;E=E->next()) {
p_list->push_back(E->get());
}
-
+
}
Ref<Theme> Theme::get_default() {
-
- return default_theme;
+
+ return default_theme;
}
@@ -193,7 +193,7 @@ Ref<Font> Theme::get_default_theme_font() const {
}
void Theme::set_default(const Ref<Theme>& p_default) {
-
+
default_theme=p_default;
}
@@ -221,7 +221,7 @@ void Theme::set_icon(const StringName& p_name,const StringName& p_type,const Ref
bool new_value=!icon_map.has(p_type) || !icon_map[p_type].has(p_name);
- icon_map[p_type][p_name]=p_icon;
+ icon_map[p_type][p_name]=p_icon;
if (new_value) {
_change_notify();
@@ -229,7 +229,7 @@ void Theme::set_icon(const StringName& p_name,const StringName& p_type,const Ref
}
}
Ref<Texture> Theme::get_icon(const StringName& p_name,const StringName& p_type) const {
-
+
if (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) {
return icon_map[p_type][p_name];
@@ -239,7 +239,7 @@ Ref<Texture> Theme::get_icon(const StringName& p_name,const StringName& p_type)
}
bool Theme::has_icon(const StringName& p_name,const StringName& p_type) const {
-
+
return (icon_map.has(p_type) && icon_map[p_type].has(p_name));
}
@@ -266,13 +266,13 @@ void Theme::get_icon_list(StringName p_type, List<StringName> *p_list) const {
p_list->push_back(*key);
}
-
+
}
void Theme::set_shader(const StringName &p_name,const StringName &p_type,const Ref<Shader>& p_shader) {
bool new_value=!shader_map.has(p_type) || !shader_map[p_type].has(p_name);
- shader_map[p_type][p_name]=p_shader;
+ shader_map[p_type][p_name]=p_shader;
if (new_value) {
_change_notify();
@@ -311,7 +311,7 @@ void Theme::get_shader_list(const StringName &p_type, List<StringName> *p_list)
p_list->push_back(*key);
}
-
+
}
@@ -331,7 +331,7 @@ void Theme::set_stylebox(const StringName& p_name,const StringName& p_type,const
Ref<StyleBox> Theme::get_stylebox(const StringName& p_name,const StringName& p_type) const {
-
+
if (style_map.has(p_type) && style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) {
return style_map[p_type][p_name];
@@ -341,7 +341,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName& p_name,const StringName& p_t
}
bool Theme::has_stylebox(const StringName& p_name,const StringName& p_type) const {
-
+
return (style_map.has(p_type) && style_map[p_type].has(p_name) );
}
@@ -384,18 +384,18 @@ void Theme::set_font(const StringName& p_name,const StringName& p_type,const Ref
}
}
Ref<Font> Theme::get_font(const StringName& p_name,const StringName& p_type) const {
-
+
if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid())
- return font_map[p_type][p_name];
+ return font_map[p_type][p_name];
else if (default_theme_font.is_valid())
return default_theme_font;
else
return default_font;
-
+
}
bool Theme::has_font(const StringName& p_name,const StringName& p_type) const {
-
+
return (font_map.has(p_type) && font_map[p_type].has(p_name));
}
@@ -425,7 +425,7 @@ void Theme::get_font_list(StringName p_type, List<StringName> *p_list) const {
}
void Theme::set_color(const StringName& p_name,const StringName& p_type,const Color& p_color) {
-
+
bool new_value=!color_map.has(p_type) || !color_map[p_type].has(p_name);
color_map[p_type][p_name]=p_color;
@@ -440,16 +440,16 @@ void Theme::set_color(const StringName& p_name,const StringName& p_type,const Co
Color Theme::get_color(const StringName& p_name,const StringName& p_type) const {
-
+
if (color_map.has(p_type) && color_map[p_type].has(p_name))
- return color_map[p_type][p_name];
+ return color_map[p_type][p_name];
else
return Color();
-
+
}
bool Theme::has_color(const StringName& p_name,const StringName& p_type) const {
-
+
return (color_map.has(p_type) && color_map[p_type].has(p_name));
}
@@ -479,7 +479,7 @@ void Theme::get_color_list(StringName p_type, List<StringName> *p_list) const {
}
void Theme::set_constant(const StringName& p_name,const StringName& p_type,int p_constant) {
-
+
bool new_value=!constant_map.has(p_type) || !constant_map[p_type].has(p_name);
constant_map[p_type][p_name]=p_constant;
@@ -490,17 +490,17 @@ void Theme::set_constant(const StringName& p_name,const StringName& p_type,int p
}
int Theme::get_constant(const StringName& p_name,const StringName& p_type) const {
-
+
if (constant_map.has(p_type) && constant_map[p_type].has(p_name))
- return constant_map[p_type][p_name];
+ return constant_map[p_type][p_name];
else {
return 0;
}
-
+
}
bool Theme::has_constant(const StringName& p_name,const StringName& p_type) const {
-
+
return (constant_map.has(p_type) && constant_map[p_type].has(p_name));
}
@@ -635,8 +635,8 @@ void Theme::_bind_methods() {
}
Theme::Theme() {
-
-
+
+
}
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 180f55381d..36630087f6 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -40,12 +40,12 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Theme : public Resource {
-
+
OBJ_TYPE( Theme, Resource );
RES_BASE_EXTENSION("thm");
-
+
static Ref<Theme> default_theme;
-
+
HashMap<StringName,HashMap<StringName,Ref<Texture>,StringNameHasher >, StringNameHasher > icon_map;
HashMap<StringName,HashMap<StringName,Ref<StyleBox>,StringNameHasher >,StringNameHasher > style_map;
HashMap<StringName,HashMap<StringName,Ref<Font>,StringNameHasher >,StringNameHasher > font_map;
@@ -56,7 +56,7 @@ protected:
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
+
static Ref<Texture> default_icon;
static Ref<StyleBox> default_style;
static Ref<Font> default_font;
@@ -72,10 +72,10 @@ protected:
static void _bind_methods();
public:
-
+
static Ref<Theme> get_default();
static void set_default(const Ref<Theme>& p_default);
-
+
static void set_default_icon( const Ref<Texture>& p_icon );
static void set_default_style( const Ref<StyleBox>& p_default_style);
static void set_default_font( const Ref<Font>& p_default_font );
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 6f71287750..bf01929191 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -344,13 +344,13 @@ Array TileSet::_tile_get_shapes(int p_id) const{
}
Array TileSet::_get_tiles_ids() const{
-
+
Array arr;
for (Map<int, Data>::Element *E = tile_map.front(); E; E = E->next()) {
- arr.push_back(E->key());
+ arr.push_back(E->key());
}
-
+
return arr;
}
diff --git a/scene/resources/volume.cpp b/scene/resources/volume.cpp
index 8eb96cb4ad..8e056158cb 100644
--- a/scene/resources/volume.cpp
+++ b/scene/resources/volume.cpp
@@ -33,10 +33,10 @@ void Volume::_set(const String& p_name, const Variant& p_value) {
if (p_name.begins_with("shapes/")) {
-
+
int idx=p_name.get_slice("/",1).to_int()-1;
ERR_FAIL_COND( idx != get_shape_count() );
-
+
Dictionary shape = p_value;
ERR_FAIL_COND( !shape.has("type") || !shape.has("data"));
String type = shape["type"];
@@ -44,7 +44,7 @@ void Volume::_set(const String& p_name, const Variant& p_value) {
Transform transform;
if (shape.has("transform"))
transform=shape["transform"];
-
+
if (type=="plane")
add_shape(SHAPE_PLANE,data,transform);
else if (type=="sphere")
@@ -59,7 +59,7 @@ void Volume::_set(const String& p_name, const Variant& p_value) {
add_shape(SHAPE_CONVEX_POLYGON,data,transform);
else if (type=="concave_polygon")
add_shape(SHAPE_CONCAVE_POLYGON,data,transform);
- else {
+ else {
ERR_FAIL();
}
}
@@ -68,14 +68,14 @@ void Volume::_set(const String& p_name, const Variant& p_value) {
Variant Volume::_get(const String& p_name) const {
if (p_name.begins_with("shapes/")) {
-
+
int idx=p_name.get_slice("/",1).to_int()-1;
ERR_FAIL_INDEX_V( idx, get_shape_count(), Variant() );
-
+
Dictionary shape;
-
+
switch( get_shape_type(idx) ) {
-
+
case SHAPE_PLANE: shape["type"]="plane"; break;
case SHAPE_SPHERE: shape["type"]="sphere"; break;
case SHAPE_BOX: shape["type"]="box"; break;
@@ -83,15 +83,15 @@ Variant Volume::_get(const String& p_name) const {
case SHAPE_CAPSULE: shape["type"]="capsule"; break;
case SHAPE_CONVEX_POLYGON: shape["type"]="convex_polygon"; break;
case SHAPE_CONCAVE_POLYGON: shape["type"]="concave_polygon"; break;
-
+
}
-
+
shape["transform"]=get_shape_transform(idx);
shape["data"]=get_shape(idx);
return shape;
}
-
+
return Variant();
}
@@ -99,8 +99,8 @@ void Volume::_get_property_list( List<PropertyInfo> *p_list) const {
int count=get_shape_count();
for(int i=0;i<count;i++) {
-
- p_list->push_back( PropertyInfo( Variant::DICTIONARY, "shapes/"+itos(i+1)) );
+
+ p_list->push_back( PropertyInfo( Variant::DICTIONARY, "shapes/"+itos(i+1)) );
}
}
@@ -118,7 +118,7 @@ void Volume::add_shape(ShapeType p_shape_type, const Variant& p_data, const Tran
void Volume::add_plane_shape(const Plane& p_plane,const Transform& p_transform) {
add_shape(SHAPE_PLANE, p_plane, p_transform );
-}
+}
void Volume::add_sphere_shape(float p_radius,const Transform& p_transform) {
@@ -140,7 +140,7 @@ void Volume::add_cylinder_shape(float p_radius, float p_height,const Transform&
void Volume::add_capsule_shape(float p_radius, float p_height,const Transform& p_transform) {
Dictionary d;
- d["radius"]=p_radius;
+ d["radius"]=p_radius;
d["height"]=p_height;
add_shape(SHAPE_CAPSULE,d,p_transform);
@@ -179,7 +179,7 @@ void Volume::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_shape_type","shape_idx"),&Volume::get_shape_type);
ObjectTypeDB::bind_method(_MD("get_shape_transform","shape_idx"),&Volume::get_shape_transform);
ObjectTypeDB::bind_method(_MD("get_shape","shape_idx"),&Volume::get_shape);
-
+
BIND_CONSTANT( SHAPE_PLANE );
BIND_CONSTANT( SHAPE_SPHERE );
BIND_CONSTANT( SHAPE_BOX );
@@ -198,7 +198,7 @@ RID Volume::get_rid() {
Volume::Volume() {
volume= PhysicsServer::get_singleton()->volume_create();
-
+
}
diff --git a/scene/resources/volume.h b/scene/resources/volume.h
index be3cbddbbd..f03e48f1d9 100644
--- a/scene/resources/volume.h
+++ b/scene/resources/volume.h
@@ -38,16 +38,16 @@
*/
class Volume : public Resource {
- OBJ_TYPE( Volume, Resource );
+ OBJ_TYPE( Volume, Resource );
RID volume;
-
+
protected:
-
+
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
-
- static void _bind_methods();
+
+ static void _bind_methods();
public:
enum ShapeType {
@@ -59,22 +59,22 @@ public:
SHAPE_CONVEX_POLYGON = PhysicsServer::SHAPE_CONVEX_POLYGON, ///< array of planes:"planes"
SHAPE_CONCAVE_POLYGON = PhysicsServer::SHAPE_CONCAVE_POLYGON, ///< vector3 array:"triangles"
};
-
+
void add_shape(ShapeType p_shape_type, const Variant& p_data, const Transform& p_transform=Transform ());
-
+
void add_plane_shape(const Plane& p_plane,const Transform& p_transform);
void add_sphere_shape(float p_radius,const Transform& p_transform);
void add_box_shape(const Vector3& p_half_extents,const Transform& p_transform);
void add_cylinder_shape(float p_radius, float p_height,const Transform& p_transform);
void add_capsule_shape(float p_radius, float p_height,const Transform& p_transform);
-
+
int get_shape_count() const;
ShapeType get_shape_type(int p_shape) const;
Transform get_shape_transform(int p_shape) const;
Variant get_shape(int p_shape) const;
virtual RID get_rid();
-
+
Volume();
~Volume();
diff --git a/servers/audio/audio_mixer_sw.cpp b/servers/audio/audio_mixer_sw.cpp
index d1f36cb7b6..64369182b1 100644
--- a/servers/audio/audio_mixer_sw.cpp
+++ b/servers/audio/audio_mixer_sw.cpp
@@ -339,7 +339,7 @@ void AudioMixerSW::mix_channel(Channel& c) {
c.mix.old_chorus_vol[i]=c.mix.chorus_vol[i];
}
- c.first_mix=false;
+ c.first_mix=false;
}
@@ -734,7 +734,7 @@ int AudioMixerSW::_get_channel(ChannelID p_channel) const {
if (channels[idx].check!=check) {
return -1;
}
- if (!channels[idx].active) {
+ if (!channels[idx].active) {
return -1;
}
@@ -918,7 +918,7 @@ void AudioMixerSW::channel_set_filter(ChannelID p_channel, FilterType p_type, fl
if (type_changed) {
//type changed reset filter
- c.filter.old_coefs=c.filter.coefs;
+ c.filter.old_coefs=c.filter.coefs;
c.mix.filter_l.ha[0]=0;
c.mix.filter_l.ha[1]=0;
c.mix.filter_l.hb[0]=0;
diff --git a/servers/audio/audio_mixer_sw.h b/servers/audio/audio_mixer_sw.h
index f5bd4cc5ba..950ed19af6 100644
--- a/servers/audio/audio_mixer_sw.h
+++ b/servers/audio/audio_mixer_sw.h
@@ -197,7 +197,7 @@ private:
void mix_channel(Channel& p_channel);
int mix_chunk_left;
- void mix_chunk();
+ void mix_chunk();
float channel_nrg;
int channel_id_count;
diff --git a/servers/audio/audio_server_sw.cpp b/servers/audio/audio_server_sw.cpp
index d634c348dc..8b5b5e4f46 100644
--- a/servers/audio/audio_server_sw.cpp
+++ b/servers/audio/audio_server_sw.cpp
@@ -765,6 +765,8 @@ void AudioServerSW::free(RID p_id) {
void AudioServerSW::_thread_func(void *self) {
+ Thread::set_name("AudioServerSW");
+
AudioServerSW *as=(AudioServerSW *)self;
while (!as->exit_update_thread) {
@@ -807,7 +809,6 @@ void AudioServerSW::init() {
#ifndef NO_THREADS
exit_update_thread=false;
thread = Thread::create(_thread_func,this);
- thread->set_name("AudioServerSW");
#endif
}
diff --git a/servers/audio/audio_server_sw.h b/servers/audio/audio_server_sw.h
index bc6191729c..8d3d992e2b 100644
--- a/servers/audio/audio_server_sw.h
+++ b/servers/audio/audio_server_sw.h
@@ -68,7 +68,7 @@ class AudioServerSW : public AudioServer {
SelfList<Voice>::List active_list;
struct Stream {
- bool active;
+ bool active;
List<Stream*>::Element *E;
AudioStream *audio_stream;
EventStream *event_stream;
diff --git a/servers/physics/gjk_epa.cpp b/servers/physics/gjk_epa.cpp
index 229c6d3fb4..f76f8c646a 100644
--- a/servers/physics/gjk_epa.cpp
+++ b/servers/physics/gjk_epa.cpp
@@ -15,7 +15,7 @@
// Config
-/* GJK */
+/* GJK */
#define GJK_MAX_ITERATIONS 128
#define GJK_ACCURARY ((real_t)0.0001)
#define GJK_MIN_DISTANCE ((real_t)0.0001)
@@ -24,7 +24,7 @@
#define GJK_SIMPLEX3_EPS ((real_t)0.0)
#define GJK_SIMPLEX4_EPS ((real_t)0.0)
-/* EPA */
+/* EPA */
#define EPA_MAX_VERTICES 64
#define EPA_MAX_FACES (EPA_MAX_VERTICES*2)
#define EPA_MAX_ITERATIONS 255
@@ -38,12 +38,12 @@ namespace GjkEpa2 {
struct sResults {
enum eStatus {
- Separated, /* Shapes doesnt penetrate */
- Penetrating, /* Shapes are penetrating */
- GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */
- EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */
+ Separated, /* Shapes doesnt penetrate */
+ Penetrating, /* Shapes are penetrating */
+ GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */
+ EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */
} status;
-
+
Vector3 witnesses[2];
Vector3 normal;
real_t distance;
@@ -65,15 +65,15 @@ struct MinkowskiDiff {
_FORCE_INLINE_ Vector3 Support0 ( const Vector3& d ) const {
return transform_A.xform( m_shapes[0]->get_support( transform_A.basis.xform_inv(d).normalized() ) );
}
-
+
_FORCE_INLINE_ Vector3 Support1 ( const Vector3& d ) const {
return transform_B.xform( m_shapes[1]->get_support( transform_B.basis.xform_inv(d).normalized() ) );
}
-
+
_FORCE_INLINE_ Vector3 Support ( const Vector3& d ) const {
return ( Support0 ( d )-Support1 ( -d ) );
}
-
+
_FORCE_INLINE_ Vector3 Support ( const Vector3& d,U index ) const
{
if ( index )
@@ -89,7 +89,7 @@ typedef MinkowskiDiff tShape;
// GJK
struct GJK
{
- /* Types */
+ /* Types */
struct sSV
{
Vector3 d,w;
@@ -104,7 +104,7 @@ struct GJK
Valid,
Inside,
Failed };};
- /* Fields */
+ /* Fields */
tShape m_shape;
Vector3 m_ray;
real_t m_distance;
@@ -115,7 +115,7 @@ struct GJK
U m_current;
sSimplex* m_simplex;
eStatus::_ m_status;
- /* Methods */
+ /* Methods */
GJK()
{
Initialize();
@@ -135,7 +135,7 @@ struct GJK
real_t alpha=0;
Vector3 lastw[4];
U clastw=0;
- /* Initialize solver */
+ /* Initialize solver */
m_free[0] = &m_store[0];
m_free[1] = &m_store[1];
m_free[2] = &m_store[2];
@@ -145,31 +145,31 @@ struct GJK
m_status = eStatus::Valid;
m_shape = shapearg;
m_distance = 0;
- /* Initialize simplex */
+ /* Initialize simplex */
m_simplices[0].rank = 0;
m_ray = guess;
const real_t sqrl= m_ray.length_squared();
appendvertice(m_simplices[0],sqrl>0?-m_ray:Vector3(1,0,0));
m_simplices[0].p[0] = 1;
- m_ray = m_simplices[0].c[0]->w;
+ m_ray = m_simplices[0].c[0]->w;
sqdist = sqrl;
lastw[0] =
lastw[1] =
lastw[2] =
lastw[3] = m_ray;
- /* Loop */
+ /* Loop */
do {
const U next=1-m_current;
sSimplex& cs=m_simplices[m_current];
sSimplex& ns=m_simplices[next];
- /* Check zero */
+ /* Check zero */
const real_t rl=m_ray.length();
if(rl<GJK_MIN_DISTANCE)
- {/* Touching or inside */
+ {/* Touching or inside */
m_status=eStatus::Inside;
break;
}
- /* Append new vertice in -'v' direction */
+ /* Append new vertice in -'v' direction */
appendvertice(cs,-m_ray);
const Vector3& w=cs.c[cs.rank-1]->w;
bool found=false;
@@ -179,23 +179,23 @@ struct GJK
{ found=true;break; }
}
if(found)
- {/* Return old simplex */
+ {/* Return old simplex */
removevertice(m_simplices[m_current]);
break;
}
else
- {/* Update lastw */
+ {/* Update lastw */
lastw[clastw=(clastw+1)&3]=w;
}
- /* Check for termination */
+ /* Check for termination */
const real_t omega=vec3_dot(m_ray,w)/rl;
alpha=MAX(omega,alpha);
if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
- {/* Return old simplex */
+ {/* Return old simplex */
removevertice(m_simplices[m_current]);
break;
- }
- /* Reduce simplex */
+ }
+ /* Reduce simplex */
real_t weights[4];
U mask=0;
switch(cs.rank)
@@ -214,7 +214,7 @@ struct GJK
weights,mask);break;
}
if(sqdist>=0)
- {/* Valid */
+ {/* Valid */
ns.rank = 0;
m_ray = Vector3(0,0,0);
m_current = next;
@@ -234,7 +234,7 @@ struct GJK
if(mask==15) m_status=eStatus::Inside;
}
else
- {/* Return old simplex */
+ {/* Return old simplex */
removevertice(m_simplices[m_current]);
break;
}
@@ -246,7 +246,7 @@ struct GJK
case eStatus::Valid: m_distance=m_ray.length();break;
case eStatus::Inside: m_distance=0;break;
default: {}
- }
+ }
return(m_status);
}
bool EncloseOrigin()
@@ -314,7 +314,7 @@ struct GJK
}
return(false);
}
- /* Internals */
+ /* Internals */
void getsupport(const Vector3& d,sSV& sv) const
{
sv.d = d/d.length();
@@ -378,13 +378,13 @@ struct GJK
m = static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
w[i] = subw[0];
w[j] = subw[1];
- w[imd3[j]] = 0;
+ w[imd3[j]] = 0;
}
}
}
if(mindist<0)
{
- const real_t d=vec3_dot(a,n);
+ const real_t d=vec3_dot(a,n);
const real_t s=Math::sqrt(l);
const Vector3 p=n*(d/l);
mindist = p.length_squared();
@@ -451,7 +451,7 @@ struct GJK
// EPA
struct EPA
{
- /* Types */
+ /* Types */
typedef GJK::sSV sSV;
struct sFace
{
@@ -482,13 +482,13 @@ struct GJK
Touching,
Degenerated,
NonConvex,
- InvalidHull,
+ InvalidHull,
OutOfFaces,
OutOfVertices,
AccuraryReached,
FallBack,
Failed };};
- /* Fields */
+ /* Fields */
eStatus::_ m_status;
GJK::sSimplex m_result;
Vector3 m_normal;
@@ -498,10 +498,10 @@ struct GJK
U m_nextsv;
sList m_hull;
sList m_stock;
- /* Methods */
+ /* Methods */
EPA()
{
- Initialize();
+ Initialize();
}
@@ -544,7 +544,7 @@ struct GJK
if((simplex.rank>1)&&gjk.EncloseOrigin())
{
- /* Clean up */
+ /* Clean up */
while(m_hull.root)
{
sFace* f = m_hull.root;
@@ -553,7 +553,7 @@ struct GJK
}
m_status = eStatus::Valid;
m_nextsv = 0;
- /* Orient simplex */
+ /* Orient simplex */
if(gjk.det( simplex.c[0]->w-simplex.c[3]->w,
simplex.c[1]->w-simplex.c[3]->w,
simplex.c[2]->w-simplex.c[3]->w)<0)
@@ -561,7 +561,7 @@ struct GJK
SWAP(simplex.c[0],simplex.c[1]);
SWAP(simplex.p[0],simplex.p[1]);
}
- /* Build initial hull */
+ /* Build initial hull */
sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
newface(simplex.c[1],simplex.c[0],simplex.c[3],true),
newface(simplex.c[2],simplex.c[1],simplex.c[3],true),
@@ -582,10 +582,10 @@ struct GJK
for(;iterations<EPA_MAX_ITERATIONS;++iterations)
{
if(m_nextsv<EPA_MAX_VERTICES)
- {
+ {
sHorizon horizon;
sSV* w=&m_sv_store[m_nextsv++];
- bool valid=true;
+ bool valid=true;
best->pass = (U1)(++pass);
gjk.getsupport(best->n,*w);
const real_t wdist=vec3_dot(best->n,w->w)-best->d;
@@ -628,7 +628,7 @@ struct GJK
return(m_status);
}
}
- /* Fallback */
+ /* Fallback */
m_status = eStatus::FallBack;
m_normal = -guess;
const real_t nl=m_normal.length();
@@ -639,7 +639,7 @@ struct GJK
m_depth = 0;
m_result.rank=1;
m_result.c[0]=simplex.c[0];
- m_result.p[0]=1;
+ m_result.p[0]=1;
return(m_status);
}
sFace* newface(sSV* a,sSV* b,sSV* c,bool forced)
@@ -739,16 +739,16 @@ struct GJK
tShape& shape,
bool withmargins)
{
- /* Results */
+ /* Results */
results.witnesses[0] =
results.witnesses[1] = Vector3(0,0,0);
results.status = sResults::Separated;
- /* Shape */
+ /* Shape */
shape.m_shapes[0] = shape0;
shape.m_shapes[1] = shape1;
shape.transform_A = wtrs0;
shape.transform_B = wtrs1;
-
+
}
@@ -808,7 +808,7 @@ bool Penetration( const ShapeSW* shape0,
{
tShape shape;
Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);
- GJK gjk;
+ GJK gjk;
GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess);
switch(gjk_status)
{
@@ -841,7 +841,7 @@ bool Penetration( const ShapeSW* shape0,
}
-/* Symbols cleanup */
+/* Symbols cleanup */
#undef GJK_MAX_ITERATIONS
#undef GJK_ACCURARY
@@ -885,7 +885,7 @@ bool gjk_epa_calculate_distance(const ShapeSW *p_shape_A, const Transform& p_tra
bool gjk_epa_calculate_penetration(const ShapeSW *p_shape_A, const Transform& p_transform_A, const ShapeSW *p_shape_B, const Transform& p_transform_B, CollisionSolverSW::CallbackResult p_result_callback,void *p_userdata, bool p_swap ) {
GjkEpa2::sResults res;
-
+
if (GjkEpa2::Penetration(p_shape_A,p_transform_A,p_shape_B,p_transform_B,p_transform_B.origin-p_transform_A.origin,res)) {
if (p_result_callback) {
if (p_swap)
@@ -894,8 +894,8 @@ bool gjk_epa_calculate_penetration(const ShapeSW *p_shape_A, const Transform& p_
p_result_callback(res.witnesses[0],res.witnesses[1],p_userdata);
}
return true;
- }
-
+ }
+
return false;
}
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index 08f280a976..4cf7729b09 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -318,7 +318,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID& p_shape, const Transform&
}
p_closest_safe=best_safe;
- p_closest_unsafe=best_unsafe;
+ p_closest_unsafe=best_unsafe;
return true;
}
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index f1f94f3485..ab1c7ef66f 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -260,7 +260,7 @@ void Body2DSW::set_state(Physics2DServer::BodyState p_state, const Variant& p_va
if (mode==Physics2DServer::BODY_MODE_KINEMATIC) {
- new_transform=p_variant;
+ new_transform=p_variant;
//wakeup_neighbours();
set_active(true);
if (first_time_kinematic) {
@@ -396,7 +396,7 @@ void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
}
area_linear_damp += p_area->get_linear_damp();
- area_angular_damp += p_area->get_angular_damp();
+ area_angular_damp += p_area->get_angular_damp();
}
void Body2DSW::integrate_forces(real_t p_step) {
@@ -518,7 +518,7 @@ void Body2DSW::integrate_forces(real_t p_step) {
// damp_area=NULL; // clear the area, so it is set in the next frame
def_area=NULL; // clear the area, so it is set in the next frame
- contact_count=0;
+ contact_count=0;
}
@@ -597,7 +597,7 @@ void Body2DSW::call_queries() {
set_force_integration_callback(0,StringName());
} else {
- Variant::CallError ce;
+ Variant::CallError ce;
if (fi_callback->callback_udata.get_type()) {
obj->call(fi_callback->method,vp,2,ce);
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index db7869c6a6..35f19605df 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -77,7 +77,7 @@ void BodyPair2DSW::_contact_added_callback(const Vector2& p_point_A,const Vector
contact.acc_normal_impulse=c.acc_normal_impulse;
contact.acc_tangent_impulse=c.acc_tangent_impulse;
contact.acc_bias_impulse=c.acc_bias_impulse;
- new_index=i;
+ new_index=i;
break;
}
}
@@ -259,10 +259,10 @@ bool BodyPair2DSW::setup(float p_step) {
if (A->get_continuous_collision_detection_mode()==Physics2DServer::CCD_MODE_CAST_SHAPE) {
motion_A=A->get_motion();
- }
+ }
if (B->get_continuous_collision_detection_mode()==Physics2DServer::CCD_MODE_CAST_SHAPE) {
motion_B=B->get_motion();
- }
+ }
//faster to set than to check..
//bool prev_collided=collided;
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index d9bf235c86..fcc3f8067a 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -226,7 +226,7 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A,const Matrix3
concave_B->cull(local_aabb,concave_callback,&cinfo);
-// print_line("Rect2 TESTS: "+itos(cinfo.aabb_tests));
+// print_line("Rect2 TESTS: "+itos(cinfo.aabb_tests));
return cinfo.collided;
}
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index 28acf4e2d1..cd4dfc1a8b 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -258,7 +258,7 @@ public:
virtual void set_active(bool p_active);
virtual void init();
virtual void step(float p_step);
- virtual void sync();
+ virtual void sync();
virtual void flush_queries();
virtual void end_sync();
virtual void finish();
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index 3054ba8d59..8b583dd3c6 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -746,7 +746,7 @@ Variant ConvexPolygonShape2DSW::get_data() const {
dvr.resize(point_count);
- for(int i=0;i<point_count;i++) {
+ for(int i=0;i<point_count;i++) {
dvr.set(i,points[i].pos);
}
@@ -968,19 +968,25 @@ void ConcavePolygonShape2DSW::set_data(const Variant& p_data) {
ERR_FAIL_COND(p_data.get_type()!=Variant::VECTOR2_ARRAY && p_data.get_type()!=Variant::REAL_ARRAY);
- segments.clear();;
- points.clear();;
- bvh.clear();;
- bvh_depth=1;
-
Rect2 aabb;
if (p_data.get_type()==Variant::VECTOR2_ARRAY) {
DVector<Vector2> p2arr = p_data;
int len = p2arr.size();
- DVector<Vector2>::Read arr = p2arr.read();
+ ERR_FAIL_COND(len%2);
+
+ segments.clear();
+ points.clear();
+ bvh.clear();
+ bvh_depth=1;
+ if (len==0) {
+ configure(aabb);
+ return;
+ }
+
+ DVector<Vector2>::Read arr = p2arr.read();
Map<Point2,int> pointmap;
for(int i=0;i<len;i+=2) {
@@ -988,8 +994,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant& p_data) {
Point2 p1 =arr[i];
Point2 p2 =arr[i+1];
int idx_p1,idx_p2;
- if (p1==p2)
- continue; //don't want it
if (pointmap.has(p1)) {
idx_p1=pointmap[p1];
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 9ba6bdd5ba..027e218bfc 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -46,7 +46,7 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
}
-int Physics2DDirectSpaceStateSW::intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
+int Physics2DDirectSpaceStateSW::intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask,bool p_pick_point) {
if (p_result_max<=0)
return 0;
@@ -69,7 +69,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2& p_point,ShapeRes
const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
- if (!col_obj->is_pickable())
+ if (p_pick_point && !col_obj->is_pickable())
continue;
int shape_idx=space->intersection_query_subindex_results[i];
@@ -337,7 +337,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32
Vector2 sep=mnormal; //important optimization for this to work fast enough
bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*(hi+space->contact_max_allowed_penetration),col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),Physics2DServerSW::_shape_col_cbk,&cbk,&sep,p_margin);
- if (!collided || cbk.amount==0) {
+ if (!collided || cbk.amount==0) {
continue;
}
@@ -1256,7 +1256,7 @@ void Space2DSW::set_param(Physics2DServer::SpaceParameter p_param, real_t p_valu
case Physics2DServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration=p_value; break;
case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: body_linear_velocity_sleep_treshold=p_value; break;
case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: body_angular_velocity_sleep_treshold=p_value; break;
- case Physics2DServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep=p_value; break;
+ case Physics2DServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep=p_value; break;
case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias=p_value; break;
}
}
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 2bdbb8a881..5f35f224b2 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -46,7 +46,7 @@ public:
Space2DSW *space;
- virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
+ virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION, bool p_pick_point=false);
virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp
index 94e1d26329..4f9d06ee96 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -35,7 +35,7 @@ void Step2DSW::_populate_island(Body2DSW* p_body,Body2DSW** p_island,Constraint2
p_body->set_island_next(*p_island);
*p_island=p_body;
- for(Map<Constraint2DSW*,int>::Element *E=p_body->get_constraint_map().front();E;E=E->next()) {
+ for(Map<Constraint2DSW*,int>::Element *E=p_body->get_constraint_map().front();E;E=E->next()) {
Constraint2DSW *c=(Constraint2DSW*)E->key();
if (c->get_island_step()==_step)
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 08f69f98b1..25875f16d3 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -182,7 +182,7 @@ public:
};
- virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
+ virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION,bool p_pick_point=false)=0;
virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION)=0;
@@ -533,7 +533,7 @@ public:
virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value)=0;
virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const=0;
- virtual JointType joint_get_type(RID p_joint) const=0;
+ virtual JointType joint_get_type(RID p_joint) const=0;
/* QUERY API */
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 8e302bf363..9b00825d92 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -421,7 +421,7 @@ public:
BODY_STATE_LINEAR_VELOCITY,
BODY_STATE_ANGULAR_VELOCITY,
BODY_STATE_SLEEPING,
- BODY_STATE_CAN_SLEEP
+ BODY_STATE_CAN_SLEEP
};
virtual void body_set_state(RID p_body, BodyState p_state, const Variant& p_variant)=0;
@@ -648,7 +648,7 @@ public:
virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value)=0;
virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const=0;
- virtual JointType joint_get_type(RID p_joint) const=0;
+ virtual JointType joint_get_type(RID p_joint) const=0;
#endif
/* QUERY API */
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 4752210b5f..06eaa4d122 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -65,8 +65,8 @@ void register_server_types() {
Globals::get_singleton()->add_singleton( Globals::Singleton("PS",PhysicsServer::get_singleton()) );
Globals::get_singleton()->add_singleton( Globals::Singleton("Physics2DServer",Physics2DServer::get_singleton()) );
Globals::get_singleton()->add_singleton( Globals::Singleton("PS2D",Physics2DServer::get_singleton()) );
- Globals::get_singleton()->add_singleton( Globals::Singleton("SpatialSoundServer",SpatialSound2DServer::get_singleton()) );
- Globals::get_singleton()->add_singleton( Globals::Singleton("SS",SpatialSound2DServer::get_singleton()) );
+ Globals::get_singleton()->add_singleton( Globals::Singleton("SpatialSoundServer",SpatialSoundServer::get_singleton()) );
+ Globals::get_singleton()->add_singleton( Globals::Singleton("SS",SpatialSoundServer::get_singleton()) );
Globals::get_singleton()->add_singleton( Globals::Singleton("SpatialSound2DServer",SpatialSound2DServer::get_singleton()) );
Globals::get_singleton()->add_singleton( Globals::Singleton("SS2D",SpatialSound2DServer::get_singleton()) );
diff --git a/servers/spatial_sound/spatial_sound_server_sw.cpp b/servers/spatial_sound/spatial_sound_server_sw.cpp
index 1ce56a5cdd..d87d05dc4d 100644
--- a/servers/spatial_sound/spatial_sound_server_sw.cpp
+++ b/servers/spatial_sound/spatial_sound_server_sw.cpp
@@ -323,7 +323,7 @@ RID SpatialSoundServerSW::source_create(RID p_space) {
void SpatialSoundServerSW::source_set_polyphony(RID p_source,int p_voice_count) {
-
+
ERR_FAIL_COND(p_voice_count<=0); // more than 32 is too much, change this if you really need more
if (p_voice_count>32) {
@@ -378,8 +378,8 @@ float SpatialSoundServerSW::source_get_param(RID p_source, SourceParam p_param)
Source *source = source_owner.get(p_source);
ERR_FAIL_COND_V(!source,0);
return source->params[p_param];
-
-
+
+
}
void SpatialSoundServerSW::source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream) {
@@ -542,7 +542,7 @@ void SpatialSoundServerSW::free(RID p_id) {
if (space_owner.owns(p_id)) {
- Space *space = space_owner.get(p_id);
+ Space *space = space_owner.get(p_id);
free(space->default_room);
while(space->listeners.size()) {
diff --git a/servers/spatial_sound/spatial_sound_server_sw.h b/servers/spatial_sound/spatial_sound_server_sw.h
index 8a4dabdc3e..a8ae7beb59 100644
--- a/servers/spatial_sound/spatial_sound_server_sw.h
+++ b/servers/spatial_sound/spatial_sound_server_sw.h
@@ -154,7 +154,7 @@ class SpatialSoundServerSW : public SpatialSoundServer {
};
mutable RID_Owner<Listener> listener_owner;
-
+
struct ActiveVoice {
Source *source;
diff --git a/servers/visual/particle_system_sw.cpp b/servers/visual/particle_system_sw.cpp
index 00c06b9e3c..07cc6d8a2a 100644
--- a/servers/visual/particle_system_sw.cpp
+++ b/servers/visual/particle_system_sw.cpp
@@ -34,11 +34,11 @@ ParticleSystemSW::ParticleSystemSW() {
amount=8;
emitting=true;
-
+
for (int i=0;i<VS::PARTICLE_VAR_MAX;i++) {
particle_randomness[i]=0.0;
}
-
+
particle_vars[VS::PARTICLE_LIFETIME]=2.0;//
particle_vars[VS::PARTICLE_SPREAD]=0.2;//
particle_vars[VS::PARTICLE_GRAVITY]=9.8;//
@@ -89,7 +89,7 @@ _FORCE_INLINE_ static float _rand_from_seed(uint32_t *seed) {
if (s < 0)
s += 2147483647;
(*seed) = s;
-
+
float v=((float)((*seed) & 0xFFFFF))/(float)0xFFFFF;
v=v*2.0-1.0;
return v;
@@ -144,10 +144,10 @@ void ParticleSystemProcessSW::process(const ParticleSystemSW *p_system,const Tra
}
float next_time = particle_system_time+p_time;
-
+
if (next_time > lifetime)
next_time=Math::fmod(next_time,lifetime);
-
+
ParticleData *pdata=&particle_data[0];
Vector3 attractor_positions[VS::MAX_PARTICLE_ATTRACTORS];
@@ -159,13 +159,13 @@ void ParticleSystemProcessSW::process(const ParticleSystemSW *p_system,const Tra
for(int i=0;i<particle_count;i++) {
-
+
ParticleData &p=pdata[i];
-
+
float restart_time = (i * lifetime / p_system->amount);
-
+
bool restart=false;
-
+
if ( next_time < particle_system_time ) {
if (restart_time > particle_system_time || restart_time < next_time )
@@ -191,11 +191,11 @@ void ParticleSystemProcessSW::process(const ParticleSystemSW *p_system,const Tra
else
p.pos = p_transform.xform( r[_irand_from_seed(&rand_seed)%emission_point_count] );
}
-
-
+
+
float angle1 = _rand_from_seed(&rand_seed)*p_system->particle_vars[VS::PARTICLE_SPREAD]*Math_PI;
float angle2 = _rand_from_seed(&rand_seed)*20.0*Math_PI; // make it more random like
-
+
Vector3 rot_xz=Vector3( Math::sin(angle1), 0.0, Math::cos(angle1) );
Vector3 rot = Vector3( Math::cos(angle2)*rot_xz.x,Math::sin(angle2)*rot_xz.x, rot_xz.z);
@@ -204,22 +204,22 @@ void ParticleSystemProcessSW::process(const ParticleSystemSW *p_system,const Tra
p.vel=p_transform.basis.xform( p.vel );
p.vel+=p_system->emission_base_velocity;
-
- p.rot=p_system->particle_vars[VS::PARTICLE_INITIAL_ANGLE]+p_system->particle_randomness[VS::PARTICLE_INITIAL_ANGLE]*_rand_from_seed(&rand_seed);
+
+ p.rot=p_system->particle_vars[VS::PARTICLE_INITIAL_ANGLE]+p_system->particle_randomness[VS::PARTICLE_INITIAL_ANGLE]*_rand_from_seed(&rand_seed);
p.active=true;
for(int r=0;r<PARTICLE_RANDOM_NUMBERS;r++)
p.random[r]=_rand_from_seed(&rand_seed);
} else {
-
+
p.pos=Vector3();
p.rot=0;
p.vel=Vector3();
p.active=false;
}
-
+
} else {
-
+
if (!p.active)
continue;
diff --git a/servers/visual/particle_system_sw.h b/servers/visual/particle_system_sw.h
index 9a176ba0d4..4edcecaaa9 100644
--- a/servers/visual/particle_system_sw.h
+++ b/servers/visual/particle_system_sw.h
@@ -37,13 +37,13 @@
struct ParticleSystemSW {
enum {
-
+
MAX_PARTICLES=1024
};
float particle_vars[VS::PARTICLE_VAR_MAX];
float particle_randomness[VS::PARTICLE_VAR_MAX];
-
+
Vector3 emission_half_extents;
DVector<Vector3> emission_points;
Vector3 gravity_normal;
@@ -54,14 +54,14 @@ struct ParticleSystemSW {
AABB visibility_aabb;
bool sort;
bool local_coordinates;
-
+
struct ColorPhase {
-
+
float pos;
Color color;
ColorPhase() { pos=1.0; color=Color(0.0,0.0,1.0,1.0); }
};
-
+
int color_phase_count;
ColorPhase color_phases[VS::MAX_PARTICLE_COLOR_PHASES];
@@ -71,12 +71,12 @@ struct ParticleSystemSW {
Vector3 pos;
float force;
};
-
+
int attractor_count;
Attractor attractors[VS::MAX_PARTICLE_ATTRACTORS];
- ParticleSystemSW();
+ ParticleSystemSW();
~ParticleSystemSW();
};
@@ -89,7 +89,7 @@ struct ParticleSystemProcessSW {
};
struct ParticleData {
-
+
Vector3 pos;
Vector3 vel;
float rot;
@@ -102,7 +102,7 @@ struct ParticleSystemProcessSW {
bool valid;
float particle_system_time;
- uint32_t rand_seed;
+ uint32_t rand_seed;
Vector<ParticleData> particle_data;
void process(const ParticleSystemSW *p_system,const Transform& p_transform,float p_time);
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp
index 26eca478fd..32f5b80e55 100644
--- a/servers/visual/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
@@ -370,7 +370,7 @@ RID Rasterizer::fixed_material_create() {
material_set_param(mat,_fixed_material_param_names[i],fm.param[i]); //must be there
}
fixed_material_dirty_list.add(&fm.dirty_list);
- //print_line("FMC: "+itos(mat.get_id()));
+ //print_line("FMC: "+itos(mat.get_id()));
return mat;
}
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 6038054b9d..e2de20785a 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -178,7 +178,7 @@ public:
/* TEXTURE API */
virtual RID texture_create()=0;
- RID texture_create_from_image(const Image& p_image,uint32_t p_flags=VS::TEXTURE_FLAGS_DEFAULT); // helper
+ RID texture_create_from_image(const Image& p_image,uint32_t p_flags=VS::TEXTURE_FLAGS_DEFAULT); // helper
virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=VS::TEXTURE_FLAGS_DEFAULT)=0;
virtual void texture_set_data(RID p_texture,const Image& p_image,VS::CubeMapSide p_cube_side=VS::CUBEMAP_LEFT)=0;
virtual Image texture_get_data(RID p_texture,VS::CubeMapSide p_cube_side=VS::CUBEMAP_LEFT) const=0;
@@ -263,10 +263,10 @@ public:
virtual void fixed_material_set_point_size(RID p_material,float p_size);
virtual float fixed_material_get_point_size(RID p_material) const;
- /* MESH API */
-
+ /* MESH API */
+
virtual RID mesh_create()=0;
-
+
virtual void mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array(),bool p_alpha_sort=false)=0;
virtual Array mesh_get_surface_arrays(RID p_mesh,int p_surface) const=0;
@@ -287,10 +287,10 @@ public:
virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const=0;
virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const=0;
virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const=0;
-
+
virtual void mesh_remove_surface(RID p_mesh,int p_index)=0;
virtual int mesh_get_surface_count(RID p_mesh) const=0;
-
+
virtual AABB mesh_get_aabb(RID p_mesh,RID p_skeleton=RID()) const=0;
virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb)=0;
@@ -338,23 +338,23 @@ public:
virtual void immediate_set_material(RID p_immediate,RID p_material)=0;
virtual RID immediate_get_material(RID p_immediate) const=0;
-
+
/* PARTICLES API */
-
+
virtual RID particles_create()=0;
-
+
virtual void particles_set_amount(RID p_particles, int p_amount)=0;
virtual int particles_get_amount(RID p_particles) const=0;
-
+
virtual void particles_set_emitting(RID p_particles, bool p_emitting)=0;
virtual bool particles_is_emitting(RID p_particles) const=0;
-
+
virtual void particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility)=0;
virtual AABB particles_get_visibility_aabb(RID p_particles) const=0;
-
+
virtual void particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents)=0;
virtual Vector3 particles_get_emission_half_extents(RID p_particles) const=0;
-
+
virtual void particles_set_emission_base_velocity(RID p_particles, const Vector3& p_base_velocity)=0;
virtual Vector3 particles_get_emission_base_velocity(RID p_particles) const=0;
@@ -363,22 +363,22 @@ public:
virtual void particles_set_gravity_normal(RID p_particles, const Vector3& p_normal)=0;
virtual Vector3 particles_get_gravity_normal(RID p_particles) const=0;
-
+
virtual void particles_set_variable(RID p_particles, VS::ParticleVariable p_variable,float p_value)=0;
virtual float particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const=0;
-
+
virtual void particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable,float p_randomness)=0;
virtual float particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const=0;
-
+
virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos)=0;
virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const=0;
-
+
virtual void particles_set_color_phases(RID p_particles, int p_phases)=0;
virtual int particles_get_color_phases(RID p_particles) const=0;
virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color& p_color)=0;
virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const=0;
-
+
virtual void particles_set_attractors(RID p_particles, int p_attractors)=0;
virtual int particles_get_attractors(RID p_particles) const=0;
@@ -390,7 +390,7 @@ public:
virtual void particles_set_material(RID p_particles, RID p_material,bool p_owned=false)=0;
virtual RID particles_get_material(RID p_particles) const=0;
-
+
virtual AABB particles_get_aabb(RID p_particles) const=0;
virtual void particles_set_height_from_velocity(RID p_particles, bool p_enable)=0;
@@ -400,31 +400,31 @@ public:
virtual bool particles_is_using_local_coordinates(RID p_particles) const=0;
/* SKELETON API */
-
+
virtual RID skeleton_create()=0;
virtual void skeleton_resize(RID p_skeleton,int p_bones)=0;
virtual int skeleton_get_bone_count(RID p_skeleton) const=0;
virtual void skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform)=0;
virtual Transform skeleton_bone_get_transform(RID p_skeleton,int p_bone)=0;
-
+
/* LIGHT API */
-
+
virtual RID light_create(VS::LightType p_type)=0;
virtual VS::LightType light_get_type(RID p_light) const=0;
virtual void light_set_color(RID p_light,VS::LightColor p_type, const Color& p_color)=0;
- virtual Color light_get_color(RID p_light,VS::LightColor p_type) const=0;
-
+ virtual Color light_get_color(RID p_light,VS::LightColor p_type) const=0;
+
virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
- virtual bool light_has_shadow(RID p_light) const=0;
-
+ virtual bool light_has_shadow(RID p_light) const=0;
+
virtual void light_set_volumetric(RID p_light,bool p_enabled)=0;
- virtual bool light_is_volumetric(RID p_light) const=0;
-
+ virtual bool light_is_volumetric(RID p_light) const=0;
+
virtual void light_set_projector(RID p_light,RID p_texture)=0;
virtual RID light_get_projector(RID p_light) const=0;
-
+
virtual void light_set_var(RID p_light, VS::LightParam p_var, float p_value)=0;
virtual float light_get_var(RID p_light, VS::LightParam p_var) const=0;
@@ -440,10 +440,10 @@ public:
virtual float light_directional_get_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param) const=0;
virtual AABB light_get_aabb(RID p_poly) const=0;
-
+
virtual RID light_instance_create(RID p_light)=0;
- virtual void light_instance_set_transform(RID p_light_instance,const Transform& p_transform)=0;
-
+ virtual void light_instance_set_transform(RID p_light_instance,const Transform& p_transform)=0;
+
enum ShadowType {
SHADOW_NONE,
@@ -454,7 +454,7 @@ public:
SHADOW_PSSM, //parallel split shadow map
SHADOW_PSM //perspective shadow map
};
-
+
enum ShadowPass {
PASS_DUAL_PARABOLOID_FRONT=0,
PASS_DUAL_PARABOLOID_BACK=1,
@@ -463,7 +463,7 @@ public:
PASS_CUBE_TOP=2,
PASS_CUBE_BOTTOM=3,
PASS_CUBE_LEFT=4,
- PASS_CUBE_RIGHT=5,
+ PASS_CUBE_RIGHT=5,
};
virtual ShadowType light_instance_get_shadow_type(RID p_light_instance,bool p_far=false) const=0;
@@ -479,13 +479,13 @@ public:
virtual bool shadow_allocate_far(RID p_light)=0; //true on successful alloc
/* PARTICLES INSTANCE */
-
+
virtual RID particles_instance_create(RID p_particles)=0;
virtual void particles_instance_set_transform(RID p_particles_instance,const Transform& p_transform)=0;
-
+
/* RENDER API */
/* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
+
/* VIEWPORT API */
virtual RID viewport_data_create()=0;
@@ -496,19 +496,19 @@ public:
virtual bool render_target_renedered_in_frame(RID p_render_target)=0;
virtual void begin_frame()=0;
-
+
virtual void set_viewport(const VS::ViewportRect& p_viewport)=0;
virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false)=0;
virtual void clear_viewport(const Color& p_color)=0;
virtual void capture_viewport(Image* r_capture)=0;
-
+
virtual void begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug)=0;
virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass )=0;
virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint)=0;
-
+
virtual void add_light( RID p_light_instance )=0; ///< all "add_light" calls happen before add_geometry calls
-
+
typedef Map<StringName,Variant> ParamOverrideMap;
struct BakedLightData {
@@ -543,12 +543,14 @@ public:
Vector<RID> light_instances;
Vector<float> morph_values;
BakedLightData *baked_light;
+ VS::ShadowCastingSetting cast_shadows;
Transform *baked_light_octree_xform;
int baked_lightmap_id;
bool mirror :8;
bool depth_scale :8;
bool billboard :8;
bool billboard_y :8;
+ bool receive_shadows : 8;
};
@@ -560,10 +562,10 @@ public:
virtual void end_scene()=0;
virtual void end_shadow_map()=0;
-
+
virtual void end_frame()=0;
virtual void flush_frame(); //not necesary in most cases
-
+
/* CANVAS API */
enum CanvasRectFlags {
@@ -617,7 +619,7 @@ public:
CanvasLight *mask_next_ptr;
CanvasLight() {
- enabled=true;
+ enabled=true;
color=Color(1,1,1);
shadow_color=Color(0,0,0,0);
height=0;
@@ -982,7 +984,7 @@ public:
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0;
/* ENVIRONMENT */
-
+
virtual RID environment_create()=0;
@@ -1002,9 +1004,9 @@ public:
virtual RID sampled_light_dp_create(int p_width,int p_height)=0;
virtual void sampled_light_dp_update(RID p_sampled_light,const Color *p_data,float p_multiplier)=0;
-
+
/*MISC*/
-
+
virtual bool is_texture(const RID& p_rid) const=0;
virtual bool is_material(const RID& p_rid) const=0;
virtual bool is_mesh(const RID& p_rid) const=0;
diff --git a/servers/visual/shader_graph.cpp b/servers/visual/shader_graph.cpp
index 07bbf9f7b4..7fe949bec3 100644
--- a/servers/visual/shader_graph.cpp
+++ b/servers/visual/shader_graph.cpp
@@ -34,78 +34,78 @@
struct _ConnectionKey {
int node;
- int slot;
-
+ int slot;
+
_FORCE_INLINE_ _ConnectionKey(int p_node=0,int p_slot=0) { node=p_node; slot=p_slot; }
-
+
_FORCE_INLINE_ bool operator<(const _ConnectionKey& p_other) const {
-
+
if (node<p_other.node)
return true;
else if (node>p_other.node)
- return false;
+ return false;
else
return slot<p_other.slot;
}
};
Error ShaderGraph::generate(ShaderCodeGenerator * p_generator) const {
-
+
Map<int,Node>::Element *E = node_map.front();
- int i=0;
+ int i=0;
while(E) {
-
+
E->get().order=i++;
E->get().out_valid=false;
E->get().in_valid=false;
E=E->next();
- }
+ }
int worst_case=connections.size() * connections.size(); // worst bubble case
int iterations=0;
int swaps;
-
- do {
+
+ do {
swaps=0;
const List<Connection>::Element *E=connections.front();
while(E) {
const Connection &c = E->get();
-
+
const Node *src = &node_map[c.src_id];
const Node *dst = &node_map[c.dst_id];
-
+
if (src->order > dst->order) {
-
+
SWAP(src->order, dst->order);
swaps++;
}
-
+
E=E->next();
}
-
-
+
+
iterations++;
-
+
} while (iterations<=worst_case && swaps>0);
-
+
ERR_FAIL_COND_V( swaps != 0 , ERR_CYCLIC_LINK );
-
+
//node array
Vector<const Node*> nodes;
nodes.resize(node_map.size());
-
+
E = node_map.front();
while(E) {
-
+
ERR_FAIL_INDEX_V( E->get().order, nodes.size(), ERR_BUG);
nodes[E->get().order]=&E->get();
E=E->next();
}
-
+
//connection set
-
+
Map<_ConnectionKey,int> in_connection_map;
Map<_ConnectionKey,List<int> > out_connection_map;
Map<_ConnectionKey,int> in_node_map;
@@ -115,7 +115,7 @@ Error ShaderGraph::generate(ShaderCodeGenerator * p_generator) const {
i=0;
while(CE) {
const Connection &c = CE->get();
-
+
_ConnectionKey in_k;
in_k.node=node_map[c.dst_id].order;
in_k.slot=c.dst_slot;
@@ -131,11 +131,11 @@ Error ShaderGraph::generate(ShaderCodeGenerator * p_generator) const {
if(!out_node_map.has(out_k))
out_node_map[out_k]=List<int>();
out_node_map[out_k].push_back(node_map[c.dst_id].order);
-
+
i++;
CE=CE->next();
}
-
+
// validate nodes if they are connected to an output
for(int i=nodes.size()-1;i>=0;i--) {
@@ -231,9 +231,9 @@ Error ShaderGraph::generate(ShaderCodeGenerator * p_generator) const {
}
// write code
-
+
p_generator->begin();
-
+
for(int i=0;i<nodes.size();i++) {
@@ -244,35 +244,35 @@ Error ShaderGraph::generate(ShaderCodeGenerator * p_generator) const {
in_indices.resize(VS::shader_get_input_count(nodes[i]->type));
Vector<int> out_indices;
Vector<int> out_slot_indices;
-
+
for(int j=0;j<in_indices.size();j++) {
-
+
_ConnectionKey key(nodes[i]->order,j);
if (in_connection_map.has(key))
in_indices[j]=in_connection_map[key];
else
- in_indices[j]=-1;
+ in_indices[j]=-1;
}
-
+
for(int j=0;j<VS::shader_get_output_count(nodes[i]->type);j++) {
-
+
_ConnectionKey key(nodes[i]->order,j);
if (out_connection_map.has(key)) {
for(List<int>::Element *CE=out_connection_map[key].front();CE;CE=CE->next()) {
-
+
out_indices.push_back(CE->get());
out_slot_indices.push_back(j);
}
}
}
-
+
Error err = p_generator->add_node(nodes[i]->type,i,nodes[i]->id,nodes[i]->param,in_indices,out_indices,out_slot_indices);
ERR_FAIL_COND_V( err, err );
}
-
+
p_generator->end();
-
-
+
+
return OK;
}
@@ -282,7 +282,7 @@ void ShaderGraph::node_add(VS::ShaderNodeType p_type,int p_id) {
ERR_FAIL_COND( node_map.has(p_id ) );
ERR_FAIL_INDEX( p_type, VS::NODE_TYPE_MAX );
Node node;
-
+
node.type=p_type;
node.id=p_id;
node.x=0;
@@ -312,14 +312,14 @@ int ShaderGraph::node_get_pos_y(int p_id) const {
void ShaderGraph::node_remove(int p_id) {
ERR_FAIL_COND(!node_map.has(p_id));
-
+
//erase connections associated with node
List<Connection>::Element *N,*E=connections.front();
while(E) {
N=E->next();
const Connection &c = E->get();
if (c.src_id==p_id || c.dst_id==p_id) {
-
+
connections.erase(E);
}
E=N;
@@ -337,17 +337,17 @@ void ShaderGraph::node_change_type(int p_id, VS::ShaderNodeType p_type) {
}
void ShaderGraph::node_set_param(int p_id, const Variant& p_value) {
-
+
ERR_FAIL_COND(!node_map.has(p_id));
- node_map[p_id].param=p_value;
+ node_map[p_id].param=p_value;
}
void ShaderGraph::get_node_list(List<int> *p_node_list) const {
Map<int,Node>::Element *E = node_map.front();
-
+
while(E) {
-
+
p_node_list->push_back(E->key());
E=E->next();
}
@@ -363,7 +363,7 @@ VS::ShaderNodeType ShaderGraph::node_get_type(int p_id) const {
Variant ShaderGraph::node_get_param(int p_id) const {
ERR_FAIL_COND_V(!node_map.has(p_id),Variant());
- return node_map[p_id].param;
+ return node_map[p_id].param;
}
@@ -383,16 +383,16 @@ Error ShaderGraph::connect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_s
while(E) {
const Connection &c = E->get();
ERR_FAIL_COND_V(c.dst_slot==p_dst_slot && c.dst_id == p_dst_id, ERR_ALREADY_EXISTS);
-
+
E=E->next();
}
-
+
Connection c;
c.src_slot=p_src_slot;
c.src_id=p_src_id;
c.dst_slot=p_dst_slot;
c.dst_id=p_dst_id;
-
+
connections.push_back(c);
return OK;
@@ -419,12 +419,12 @@ void ShaderGraph::disconnect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst
N=E->next();
const Connection &c = E->get();
if (c.src_slot==p_src_slot && c.src_id==p_src_id && c.dst_slot==p_dst_slot && c.dst_id == p_dst_id) {
-
+
connections.erase(E);
}
E=N;
}
-
+
}
diff --git a/servers/visual/shader_graph.h b/servers/visual/shader_graph.h
index 07e4bb3540..41df0f60f1 100644
--- a/servers/visual/shader_graph.h
+++ b/servers/visual/shader_graph.h
@@ -43,7 +43,7 @@ public:
virtual void begin()=0;
virtual Error add_node(VS::ShaderNodeType p_type,int p_node_pos,int p_id,const Variant& p_param,const Vector<int>& p_in_connections,const Vector<int>& p_out_connections,const Vector<int>& p_out_connection_outputs)=0;
virtual void end()=0;
-
+
virtual ~ShaderCodeGenerator() {}
};
@@ -61,7 +61,7 @@ public:
private:
struct Node {
-
+
int16_t x,y;
VS::ShaderNodeType type;
Variant param;
@@ -74,7 +74,7 @@ private:
Map<int,Node> node_map;
List<Connection> connections;
-
+
public:
Error generate(ShaderCodeGenerator * p_generator) const;
@@ -87,7 +87,7 @@ public:
void node_set_pos(int p_id, int p_x,int p_y);
int node_get_pos_x(int p_id) const;
int node_get_pos_y(int p_id) const;
-
+
void get_node_list(List<int> *p_node_list) const;
void get_sorted_node_list(List<int> *p_node_list) const;
VS::ShaderNodeType node_get_type(int p_id) const;
@@ -95,14 +95,14 @@ public:
Error connect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot);
bool is_connected(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) const;
- void disconnect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot);
+ void disconnect(int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot);
void clear();
List<Connection> get_connection_list() const;
- ShaderGraph();
+ ShaderGraph();
~ShaderGraph();
};
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index d0e8bfccd6..0b2a282c04 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -607,7 +607,7 @@ bool ShaderLanguage::test_existing_identifier(Node *p_node,const StringName p_id
return true;
} else if (node->type==Node::TYPE_PROGRAM) {
- ProgramNode *program = (ProgramNode*)node;
+ ProgramNode *program = (ProgramNode*)node;
for(int i=0;i<program->functions.size();i++) {
if (program->functions[i].name==p_identifier) {
@@ -1138,7 +1138,7 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_vertex_builtins_defs[]={
//builtins
{ "WORLD_MATRIX", TYPE_MAT4},
{ "PROJECTION_MATRIX", TYPE_MAT4},
- { "EXTRA_MATRIX", TYPE_MAT4},
+ { "EXTRA_MATRIX", TYPE_MAT4},
{ "TIME", TYPE_FLOAT},
{ NULL, TYPE_VOID},
};
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 7ee8431e10..1db7971d3b 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -45,7 +45,7 @@ BalloonAllocator<> *VisualServerRaster::OctreeAllocator::allocator=NULL;
RID VisualServerRaster::texture_create() {
-
+
return rasterizer->texture_create();
}
@@ -340,7 +340,7 @@ VisualServerRaster::FixedMaterialLightShader VisualServerRaster::fixed_material_
-/* MESH API */
+/* MESH API */
RID VisualServerRaster::mesh_create() {
@@ -625,14 +625,14 @@ RID VisualServerRaster::particles_create() {
void VisualServerRaster::particles_set_amount(RID p_particles, int p_amount) {
VS_CHANGED;
- rasterizer->particles_set_amount(p_particles,p_amount);
+ rasterizer->particles_set_amount(p_particles,p_amount);
}
int VisualServerRaster::particles_get_amount(RID p_particles) const {
return rasterizer->particles_get_amount(p_particles);
}
-
+
void VisualServerRaster::particles_set_emitting(RID p_particles, bool p_emitting) {
VS_CHANGED;
rasterizer->particles_set_emitting(p_particles,p_emitting);
@@ -641,7 +641,7 @@ bool VisualServerRaster::particles_is_emitting(RID p_particles) const {
return rasterizer->particles_is_emitting(p_particles);
}
-
+
void VisualServerRaster::particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility) {
VS_CHANGED;
rasterizer->particles_set_visibility_aabb(p_particles, p_visibility);
@@ -650,7 +650,7 @@ AABB VisualServerRaster::particles_get_visibility_aabb(RID p_particles) const {
return rasterizer->particles_get_visibility_aabb(p_particles);
}
-
+
void VisualServerRaster::particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents) {
VS_CHANGED;
rasterizer->particles_set_emission_half_extents(p_particles,p_half_extents);
@@ -688,7 +688,7 @@ Vector3 VisualServerRaster::particles_get_gravity_normal(RID p_particles) const
return rasterizer->particles_get_gravity_normal(p_particles);
}
-
+
void VisualServerRaster::particles_set_variable(RID p_particles, ParticleVariable p_variable,float p_value) {
VS_CHANGED;
rasterizer->particles_set_variable(p_particles,p_variable,p_value);
@@ -770,7 +770,7 @@ RID VisualServerRaster::particles_get_material(RID p_particles) const {
return rasterizer->particles_get_material(p_particles);
}
-
+
void VisualServerRaster::particles_set_height_from_velocity(RID p_particles, bool p_enable) {
@@ -812,33 +812,33 @@ void VisualServerRaster::light_set_color(RID p_light,LightColor p_type, const Co
}
Color VisualServerRaster::light_get_color(RID p_light,LightColor p_type) const {
-
+
return rasterizer->light_get_color(p_light,p_type);
-
+
}
void VisualServerRaster::light_set_shadow(RID p_light,bool p_enabled) {
VS_CHANGED;
- rasterizer->light_set_shadow(p_light,p_enabled);
+ rasterizer->light_set_shadow(p_light,p_enabled);
}
bool VisualServerRaster::light_has_shadow(RID p_light) const {
return rasterizer->light_has_shadow(p_light);
-}
+}
void VisualServerRaster::light_set_volumetric(RID p_light,bool p_enabled) {
VS_CHANGED;
- rasterizer->light_set_volumetric(p_light,p_enabled);
+ rasterizer->light_set_volumetric(p_light,p_enabled);
}
bool VisualServerRaster::light_is_volumetric(RID p_light) const {
return rasterizer->light_is_volumetric(p_light);
-}
+}
void VisualServerRaster::light_set_projector(RID p_light,RID p_texture) {
VS_CHANGED;
@@ -854,13 +854,13 @@ void VisualServerRaster::light_set_param(RID p_light, LightParam p_var, float p_
VS_CHANGED;
rasterizer->light_set_var(p_light,p_var,p_value);
_dependency_queue_update(p_light,true);
-
+
}
float VisualServerRaster::light_get_param(RID p_light, LightParam p_var) const {
-
- return rasterizer->light_get_var(p_light,p_var);
+
+ return rasterizer->light_get_var(p_light,p_var);
}
void VisualServerRaster::light_set_operator(RID p_light,LightOp p_op) {
@@ -940,7 +940,7 @@ Transform VisualServerRaster::skeleton_bone_get_transform(RID p_skeleton,int p_b
return rasterizer->skeleton_bone_get_transform(p_skeleton,p_bone);
}
-
+
/* VISIBILITY API */
@@ -970,7 +970,7 @@ BSP_Tree VisualServerRaster::room_get_bounds(RID p_room) const {
return room->bounds;
}
-
+
/* PORTAL API */
RID VisualServerRaster::portal_create() {
@@ -1482,7 +1482,7 @@ void VisualServerRaster::camera_set_perspective(RID p_camera,float p_fovy_degree
camera->fov=p_fovy_degrees;
camera->znear=p_z_near;
camera->zfar=p_z_far;
-
+
}
void VisualServerRaster::camera_set_orthogonal(RID p_camera,float p_size, float p_z_near, float p_z_far) {
@@ -1500,7 +1500,7 @@ void VisualServerRaster::camera_set_transform(RID p_camera,const Transform& p_tr
Camera *camera = camera_owner.get( p_camera );
ERR_FAIL_COND(!camera);
camera->transform=p_transform.orthonormalized();
-
+
}
@@ -1562,7 +1562,7 @@ RID VisualServerRaster::viewport_create() {
Viewport *viewport = memnew( Viewport );
RID rid = viewport_owner.make_rid( viewport );
ERR_FAIL_COND_V( !rid.is_valid(), rid );
-
+
viewport->self=rid;
viewport->hide_scenario=false;
viewport->hide_canvas=false;
@@ -1730,7 +1730,7 @@ void VisualServerRaster::viewport_set_rect(RID p_viewport,const ViewportRect& p_
viewport = viewport_owner.get( p_viewport );
ERR_FAIL_COND(!viewport);
-
+
viewport->rect=p_rect;
if (viewport->render_target.is_valid()) {
rasterizer->render_target_set_size(viewport->render_target,viewport->rect.width,viewport->rect.height);
@@ -1744,7 +1744,7 @@ VisualServer::ViewportRect VisualServerRaster::viewport_get_rect(RID p_viewport)
viewport = viewport_owner.get( p_viewport );
ERR_FAIL_COND_V(!viewport, ViewportRect());
-
+
return viewport->rect;
}
@@ -1796,11 +1796,11 @@ void VisualServerRaster::viewport_attach_camera(RID p_viewport,RID p_camera) {
-
+
if (p_camera.is_valid()) {
ERR_FAIL_COND(!camera_owner.owns(p_camera));
- // a camera
+ // a camera
viewport->camera=p_camera;
} else {
viewport->camera=RID();
@@ -1833,7 +1833,7 @@ RID VisualServerRaster::viewport_get_attached_camera(RID p_viewport) const {
viewport = viewport_owner.get( p_viewport );
ERR_FAIL_COND_V(!viewport, RID());
-
+
return viewport->camera;
}
@@ -1922,7 +1922,7 @@ void VisualServerRaster::viewport_remove_canvas(RID p_viewport,RID p_canvas) {
viewport = viewport_owner.get( p_viewport );
ERR_FAIL_COND(!viewport);
- Canvas *canvas = canvas_owner.get( p_canvas );
+ Canvas *canvas = canvas_owner.get( p_canvas );
ERR_FAIL_COND(!canvas);
@@ -1954,7 +1954,7 @@ void VisualServerRaster::viewport_set_canvas_layer(RID p_viewport,RID p_canvas,i
}
E->get().layer=p_layer;
-
+
}
void VisualServerRaster::viewport_set_transparent_background(RID p_viewport,bool p_enabled) {
@@ -1976,13 +1976,13 @@ bool VisualServerRaster::viewport_has_transparent_background(RID p_viewport) con
RID VisualServerRaster::viewport_get_scenario(RID p_viewport) const {
-
+
const Viewport *viewport=NULL;
viewport = viewport_owner.get( p_viewport );
ERR_FAIL_COND_V(!viewport, RID());
-
- return viewport->scenario;
+
+ return viewport->scenario;
}
@@ -2036,38 +2036,38 @@ Variant VisualServerRaster::environment_fx_get_param(RID p_env,EnvironmentFxPara
void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb) {
Map< RID, Set<RID> >::Element * E = instance_dependency_map.find( p_rid );
-
+
if (!E)
return;
-
-
+
+
Set<RID>::Element *I = E->get().front();
-
+
while(I) {
-
+
Instance *ins = instance_owner.get( I->get() );
_instance_queue_update( ins , p_update_aabb );
-
+
I = I->next();
}
-
+
}
void VisualServerRaster::_instance_queue_update(Instance *p_instance,bool p_update_aabb) {
if (p_update_aabb)
p_instance->update_aabb=true;
-
+
if (p_instance->update)
return;
p_instance->update_next=instance_update_list;
instance_update_list=p_instance;
p_instance->update=true;
-
+
}
RID VisualServerRaster::scenario_create() {
-
+
Scenario *scenario = memnew( Scenario );
ERR_FAIL_COND_V(!scenario,RID());
RID scenario_rid = scenario_owner.make_rid( scenario );
@@ -2509,10 +2509,10 @@ void VisualServerRaster::instance_set_transform(RID p_instance, const Transform&
VS_CHANGED;
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND( !instance );
-
+
if (p_transform==instance->data.transform) // must improve somehow
return;
-
+
instance->data.transform=p_transform;
if (instance->base_type==INSTANCE_LIGHT)
instance->data.transform.orthonormalize();
@@ -2524,7 +2524,7 @@ Transform VisualServerRaster::instance_get_transform(RID p_instance) const {
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND_V( !instance, Transform() );
-
+
return instance->data.transform;
}
@@ -2634,7 +2634,7 @@ void VisualServerRaster::instance_set_room( RID p_instance, RID p_room ) {
ERR_EXPLAIN("Cycle in room assignment");
ERR_FAIL_COND( parent == room );
parent=parent->room;
- }
+ }
}
if ( (1<<instance->base_type) & INSTANCE_GEOMETRY_MASK ) {
@@ -2694,45 +2694,45 @@ real_t VisualServerRaster::instance_get_extra_visibility_margin( RID p_instance
Vector<RID> VisualServerRaster::instances_cull_aabb(const AABB& p_aabb, RID p_scenario) const {
-
+
Vector<RID> instances;
Scenario *scenario=scenario_owner.get(p_scenario);
- ERR_FAIL_COND_V(!scenario,instances);
-
+ ERR_FAIL_COND_V(!scenario,instances);
+
const_cast<VisualServerRaster*>(this)->_update_instances(); // check dirty instances before culling
-
+
int culled=0;
Instance *cull[1024];
culled=scenario->octree.cull_AABB(p_aabb,cull,1024);
-
+
for (int i=0;i<culled;i++) {
-
+
Instance *instance=cull[i];
ERR_CONTINUE(!instance);
instances.push_back(instance->self);
}
-
+
return instances;
}
Vector<RID> VisualServerRaster::instances_cull_ray(const Vector3& p_from, const Vector3& p_to, RID p_scenario) const{
Vector<RID> instances;
Scenario *scenario=scenario_owner.get(p_scenario);
- ERR_FAIL_COND_V(!scenario,instances);
+ ERR_FAIL_COND_V(!scenario,instances);
const_cast<VisualServerRaster*>(this)->_update_instances(); // check dirty instances before culling
-
+
int culled=0;
- Instance *cull[1024];
+ Instance *cull[1024];
culled=scenario->octree.cull_segment(p_from,p_to*10000,cull,1024);
for (int i=0;i<culled;i++) {
-
+
Instance *instance=cull[i];
ERR_CONTINUE(!instance);
instances.push_back(instance->self);
}
-
+
return instances;
}
@@ -2740,22 +2740,22 @@ Vector<RID> VisualServerRaster::instances_cull_convex(const Vector<Plane>& p_con
Vector<RID> instances;
Scenario *scenario=scenario_owner.get(p_scenario);
- ERR_FAIL_COND_V(!scenario,instances);
+ ERR_FAIL_COND_V(!scenario,instances);
const_cast<VisualServerRaster*>(this)->_update_instances(); // check dirty instances before culling
-
+
int culled=0;
- Instance *cull[1024];
-
+ Instance *cull[1024];
+
culled=scenario->octree.cull_convex(p_convex,cull,1024);
-
+
for (int i=0;i<culled;i++) {
-
+
Instance *instance=cull[i];
- ERR_CONTINUE(!instance);
+ ERR_CONTINUE(!instance);
instances.push_back(instance->self);
}
-
+
return instances;
}
@@ -2784,12 +2784,17 @@ void VisualServerRaster::instance_geometry_set_flag(RID p_instance,InstanceFlags
} break;
case INSTANCE_FLAG_CAST_SHADOW: {
- instance->cast_shadows=p_enabled;
+ if (p_enabled == true) {
+ instance->data.cast_shadows = SHADOW_CASTING_SETTING_ON;
+ }
+ else {
+ instance->data.cast_shadows = SHADOW_CASTING_SETTING_OFF;
+ }
} break;
case INSTANCE_FLAG_RECEIVE_SHADOWS: {
- instance->receive_shadows=p_enabled;
+ instance->data.receive_shadows=p_enabled;
} break;
case INSTANCE_FLAG_DEPH_SCALE: {
@@ -2831,12 +2836,17 @@ bool VisualServerRaster::instance_geometry_get_flag(RID p_instance,InstanceFlags
} break;
case INSTANCE_FLAG_CAST_SHADOW: {
- return instance->cast_shadows;
+ if(instance->data.cast_shadows == SHADOW_CASTING_SETTING_OFF) {
+ return false;
+ }
+ else {
+ return true;
+ }
} break;
case INSTANCE_FLAG_RECEIVE_SHADOWS: {
- return instance->receive_shadows;
+ return instance->data.receive_shadows;
} break;
case INSTANCE_FLAG_DEPH_SCALE: {
@@ -2855,6 +2865,22 @@ bool VisualServerRaster::instance_geometry_get_flag(RID p_instance,InstanceFlags
return false;
}
+void VisualServerRaster::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) {
+
+ Instance *instance = instance_owner.get( p_instance );
+ ERR_FAIL_COND( !instance );
+
+ instance->data.cast_shadows = p_shadow_casting_setting;
+}
+
+VS::ShadowCastingSetting VisualServerRaster::instance_geometry_get_cast_shadows_setting(RID p_instance) const{
+
+ const Instance *instance = instance_owner.get( p_instance );
+ ERR_FAIL_COND_V( !instance, SHADOW_CASTING_SETTING_OFF );
+
+ return instance->data.cast_shadows;
+}
+
void VisualServerRaster::instance_geometry_set_material_override(RID p_instance, RID p_material) {
@@ -3010,9 +3036,9 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
p_instance->version++;
if (p_instance->base_type == INSTANCE_LIGHT) {
-
+
rasterizer->light_instance_set_transform( p_instance->light_info->instance, p_instance->data.transform );
-
+
}
if (p_instance->aabb.has_no_surface())
@@ -3020,10 +3046,10 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
if (p_instance->base_type == INSTANCE_PARTICLES) {
-
+
rasterizer->particles_instance_set_transform( p_instance->particles_info->instance, p_instance->data.transform );
}
-
+
if ((1<<p_instance->base_type)&INSTANCE_GEOMETRY_MASK) {
@@ -3075,7 +3101,7 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
else
portal_aabb.expand_to(point);
}
-
+
portal_aabb.grow_by(p_instance->portal_info->portal->connect_range);
new_aabb = portal_aabb;
@@ -3151,7 +3177,7 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
}
if (p_instance->base_type==INSTANCE_PORTAL) {
-
+
_portal_attempt_connect(p_instance);
}
@@ -3172,18 +3198,18 @@ void VisualServerRaster::_update_instance(Instance *p_instance) {
void VisualServerRaster::_update_instance_aabb(Instance *p_instance) {
AABB new_aabb;
-
+
ERR_FAIL_COND(p_instance->base_type!=INSTANCE_NONE && !p_instance->base_rid.is_valid());
-
+
switch(p_instance->base_type) {
case VisualServer::INSTANCE_NONE: {
// do nothing
} break;
case VisualServer::INSTANCE_MESH: {
-
+
new_aabb = rasterizer->mesh_get_aabb(p_instance->base_rid,p_instance->data.skeleton);
-
+
} break;
case VisualServer::INSTANCE_MULTIMESH: {
@@ -3197,41 +3223,41 @@ void VisualServerRaster::_update_instance_aabb(Instance *p_instance) {
} break;
case VisualServer::INSTANCE_PARTICLES: {
-
+
new_aabb = rasterizer->particles_get_aabb(p_instance->base_rid);
-
+
} break;
case VisualServer::INSTANCE_LIGHT: {
-
+
new_aabb = rasterizer->light_get_aabb(p_instance->base_rid);
-
+
} break;
case VisualServer::INSTANCE_ROOM: {
-
+
Room *room = room_owner.get( p_instance->base_rid );
ERR_FAIL_COND(!room);
new_aabb=room->bounds.get_aabb();
-
+
} break;
case VisualServer::INSTANCE_PORTAL: {
-
+
Portal *portal = portal_owner.get( p_instance->base_rid );
- ERR_FAIL_COND(!portal);
+ ERR_FAIL_COND(!portal);
for (int i=0;i<portal->shape.size();i++) {
-
+
Vector3 point( portal->shape[i].x, portal->shape[i].y, 0 );
if (i==0) {
-
+
new_aabb.pos=point;
new_aabb.size.z=0.01; // make it not flat for octree
} else {
-
+
new_aabb.expand_to(point);
}
}
- } break;
+ } break;
case VisualServer::INSTANCE_BAKED_LIGHT: {
BakedLight *baked_light = baked_light_owner.get( p_instance->base_rid );
@@ -3254,24 +3280,24 @@ void VisualServerRaster::_update_instance_aabb(Instance *p_instance) {
if (p_instance->extra_margin)
new_aabb.grow_by(p_instance->extra_margin);
-
+
p_instance->aabb=new_aabb;
-
+
}
void VisualServerRaster::_update_instances() {
while(instance_update_list) {
-
+
Instance *instance=instance_update_list;
instance_update_list=instance_update_list->update_next;
-
+
if (instance->update_aabb)
_update_instance_aabb(instance);
-
+
_update_instance(instance);
-
+
instance->update=false;
instance->update_aabb=false;
instance->update_next=0;
@@ -3311,7 +3337,7 @@ RID VisualServerRaster::canvas_create() {
Canvas * canvas = memnew( Canvas );
ERR_FAIL_COND_V(!canvas,RID());
RID rid = canvas_owner.make_rid( canvas );
-
+
return rid;
}
@@ -3351,10 +3377,10 @@ void VisualServerRaster::canvas_set_modulate(RID p_canvas,const Color& p_color)
RID VisualServerRaster::canvas_item_create() {
-
+
CanvasItem *canvas_item = memnew( CanvasItem );
ERR_FAIL_COND_V(!canvas_item,RID());
-
+
return canvas_item_owner.make_rid( canvas_item );
}
@@ -3482,7 +3508,7 @@ void VisualServerRaster::canvas_item_set_rect(RID p_item, const Rect2& p_rect) {
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
canvas_item->rect=p_rect;
}*/
@@ -3490,7 +3516,7 @@ void VisualServerRaster::canvas_item_set_clip(RID p_item, bool p_clip) {
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
canvas_item->clip=p_clip;
}
@@ -3577,7 +3603,7 @@ void VisualServerRaster::canvas_item_add_line(RID p_item, const Point2& p_from,
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
CanvasItem::CommandLine * line = memnew( CanvasItem::CommandLine );
ERR_FAIL_COND(!line);
line->color=p_color;
@@ -3586,15 +3612,15 @@ void VisualServerRaster::canvas_item_add_line(RID p_item, const Point2& p_from,
line->width=p_width;
canvas_item->rect_dirty=true;
-
- canvas_item->commands.push_back(line);
+
+ canvas_item->commands.push_back(line);
}
void VisualServerRaster::canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color) {
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
CanvasItem::CommandRect * rect = memnew( CanvasItem::CommandRect );
ERR_FAIL_COND(!rect);
rect->modulate=p_color;
@@ -3624,7 +3650,7 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
CanvasItem::CommandRect * rect = memnew( CanvasItem::CommandRect );
ERR_FAIL_COND(!rect);
rect->modulate=p_modulate;
@@ -3656,7 +3682,7 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
CanvasItem::CommandRect * rect = memnew( CanvasItem::CommandRect );
ERR_FAIL_COND(!rect);
rect->modulate=p_modulate;
@@ -3682,8 +3708,8 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R
canvas_item->rect_dirty=true;
- canvas_item->commands.push_back(rect);
-
+ canvas_item->commands.push_back(rect);
+
}
void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) {
@@ -3691,7 +3717,7 @@ void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_re
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
CanvasItem::CommandStyle * style = memnew( CanvasItem::CommandStyle );
ERR_FAIL_COND(!style);
style->texture=p_texture;
@@ -3704,13 +3730,13 @@ void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_re
style->margin[MARGIN_BOTTOM]=p_bottomright.y;
canvas_item->rect_dirty=true;
- canvas_item->commands.push_back(style);
+ canvas_item->commands.push_back(style);
}
void VisualServerRaster::canvas_item_add_primitive(RID p_item,const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width) {
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
+
CanvasItem::CommandPrimitive * prim = memnew( CanvasItem::CommandPrimitive );
ERR_FAIL_COND(!prim);
prim->texture=p_texture;
@@ -3720,7 +3746,7 @@ void VisualServerRaster::canvas_item_add_primitive(RID p_item,const Vector<Point
prim->width=p_width;
canvas_item->rect_dirty=true;
- canvas_item->commands.push_back(prim);
+ canvas_item->commands.push_back(prim);
}
void VisualServerRaster::canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture) {
@@ -3941,10 +3967,10 @@ void VisualServerRaster::canvas_item_clear(RID p_item) {
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
-
-
+
+
canvas_item->clear();
-
+
}
void VisualServerRaster::canvas_item_raise(RID p_item) {
@@ -4432,7 +4458,7 @@ void VisualServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_righ
void VisualServerRaster::_free_attached_instances(RID p_rid,bool p_free_scenario) {
Map< RID, Set<RID> >::Element * E = instance_dependency_map.find( p_rid );
-
+
if (E) {
// has instances
while( E->get().size() ) {
@@ -4441,10 +4467,10 @@ void VisualServerRaster::_free_attached_instances(RID p_rid,bool p_free_scenario
instance_set_scenario( E->get().front()->get(), RID() );
else
instance_set_base( E->get().front()->get(), RID() );
-
+
}
}
-
+
instance_dependency_map.erase(p_rid);
}
@@ -4486,7 +4512,7 @@ void VisualServerRaster::free( RID p_rid ) {
VS_CHANGED;
if (rasterizer->is_texture(p_rid) || rasterizer->is_material(p_rid) || rasterizer->is_shader(p_rid) || rasterizer->is_environment(p_rid)) {
-
+
rasterizer->free(p_rid);
} else if (rasterizer->is_skeleton(p_rid)) {
@@ -4504,14 +4530,14 @@ void VisualServerRaster::free( RID p_rid ) {
rasterizer->free(p_rid);
} else if (rasterizer->is_mesh(p_rid) || rasterizer->is_multimesh(p_rid) || rasterizer->is_light(p_rid) || rasterizer->is_particles(p_rid) || rasterizer->is_immediate(p_rid)) {
//delete the resource
-
+
_free_attached_instances(p_rid);
rasterizer->free(p_rid);
} else if (room_owner.owns(p_rid)) {
_free_attached_instances(p_rid);
- Room *room = room_owner.get(p_rid);
- ERR_FAIL_COND(!room);
+ Room *room = room_owner.get(p_rid);
+ ERR_FAIL_COND(!room);
room_owner.free(p_rid);
memdelete(room);
@@ -4549,16 +4575,16 @@ void VisualServerRaster::free( RID p_rid ) {
} else if (camera_owner.owns(p_rid)) {
// delete te camera
-
+
Camera *camera = camera_owner.get(p_rid);
ERR_FAIL_COND(!camera);
-
+
camera_owner.free( p_rid );
memdelete(camera);
-
+
} else if (viewport_owner.owns(p_rid)) {
// delete the viewport
-
+
Viewport *viewport = viewport_owner.get( p_rid );
ERR_FAIL_COND(!viewport);
@@ -4583,15 +4609,15 @@ void VisualServerRaster::free( RID p_rid ) {
viewport->canvas_map.erase(viewport->canvas_map.front());
}
-
- viewport_owner.free(p_rid);
+
+ viewport_owner.free(p_rid);
memdelete(viewport);
-
+
} else if (instance_owner.owns(p_rid)) {
// delete the instance
-
+
_update_instances(); // be sure
-
+
Instance *instance = instance_owner.get(p_rid);
ERR_FAIL_COND(!instance);
@@ -4606,9 +4632,9 @@ void VisualServerRaster::free( RID p_rid ) {
instance_owner.free(p_rid);
memdelete(instance);
-
+
} else if (canvas_owner.owns(p_rid)) {
-
+
Canvas *canvas = canvas_owner.get(p_rid);
ERR_FAIL_COND(!canvas);
@@ -4640,11 +4666,11 @@ void VisualServerRaster::free( RID p_rid ) {
}
canvas_owner.free( p_rid );
-
+
memdelete( canvas );
-
+
} else if (canvas_item_owner.owns(p_rid)) {
-
+
CanvasItem *canvas_item = canvas_item_owner.get(p_rid);
ERR_FAIL_COND(!canvas_item);
@@ -4672,7 +4698,7 @@ void VisualServerRaster::free( RID p_rid ) {
}
canvas_item_owner.free( p_rid );
-
+
memdelete( canvas_item );
} else if (canvas_item_material_owner.owns(p_rid)) {
@@ -4744,22 +4770,22 @@ void VisualServerRaster::free( RID p_rid ) {
memdelete(occluder_poly);
} else if (scenario_owner.owns(p_rid)) {
-
+
Scenario *scenario=scenario_owner.get(p_rid);
ERR_FAIL_COND(!scenario);
-
+
_update_instances(); // be sure
_free_attached_instances(p_rid,true);
-
+
//rasterizer->free( scenario->environment );
scenario_owner.free(p_rid);
memdelete(scenario);
-
+
} else {
-
+
ERR_FAIL();
}
-
+
}
@@ -4781,7 +4807,7 @@ void VisualServerRaster::_instance_draw(Instance *p_instance) {
switch(p_instance->base_type) {
-
+
case INSTANCE_MESH: {
const float *morphs = NULL;
if (!p_instance->data.morph_values.empty()) {
@@ -4789,7 +4815,7 @@ void VisualServerRaster::_instance_draw(Instance *p_instance) {
}
rasterizer->add_mesh(p_instance->base_rid, &p_instance->data);
- } break;
+ } break;
case INSTANCE_MULTIMESH: {
rasterizer->add_multimesh(p_instance->base_rid, &p_instance->data);
} break;
@@ -4899,17 +4925,17 @@ Vector<Plane> VisualServerRaster::_camera_generate_orthogonal_planes(Instance *p
void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range) {
int splits = rasterizer->light_instance_get_shadow_passes( p_light->light_info->instance );
-
+
float split_weight=rasterizer->light_directional_get_shadow_param(p_light->base_rid,LIGHT_DIRECTIONAL_SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
float distances[5];
float texsize=rasterizer->light_instance_get_shadow_size( p_light->light_info->instance );
-
+
// float cull_min=p_cull_range.min;
//float cull_max=p_cull_range.max;
-
+
bool overlap = rasterizer->light_instance_get_pssm_shadow_overlap(p_light->light_info->instance);
float cull_min=p_camera->znear;
@@ -4917,7 +4943,7 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
float max_dist = rasterizer->light_directional_get_shadow_param(p_light->base_rid,VS::LIGHT_DIRECTIONAL_SHADOW_PARAM_MAX_DISTANCE);
if (max_dist>0.0)
cull_max=MIN(cull_max,max_dist);
-
+
for(int i = 0; i < splits; i++) {
float idm = i / (float)splits;
float lg = cull_min * Math::pow(cull_max/cull_min, idm);
@@ -4928,16 +4954,16 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
distances[0]=cull_min;
distances[splits]=cull_max;
-
+
for (int i=0;i<splits;i++) {
-
+
// setup a camera matrix for that range!
CameraMatrix camera_matrix;
-
+
switch(p_camera->type) {
-
+
case Camera::ORTHOGONAL: {
-
+
camera_matrix.set_orthogonal(
p_camera->size,
viewport_rect.width / (float)viewport_rect.height,
@@ -4948,7 +4974,7 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
);
} break;
case Camera::PERSPECTIVE: {
-
+
camera_matrix.set_perspective(
p_camera->fov,
@@ -4958,18 +4984,18 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
p_camera->vaspect
);
-
- } break;
- }
-
+
+ } break;
+ }
+
//obtain the frustum endpoints
-
+
Vector3 endpoints[8]; // frustum plane endpoints
bool res = camera_matrix.get_endpoints(p_camera->transform,endpoints);
ERR_CONTINUE(!res);
-
+
// obtain the light frustm ranges (given endpoints)
-
+
Vector3 x_vec=p_light->data.transform.basis.get_axis( Vector3::AXIS_X ).normalized();
Vector3 y_vec=p_light->data.transform.basis.get_axis( Vector3::AXIS_Y ).normalized();
Vector3 z_vec=p_light->data.transform.basis.get_axis( Vector3::AXIS_Z ).normalized();
@@ -4986,27 +5012,27 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
//used for culling
for(int j=0;j<8;j++) {
-
+
float d_x=x_vec.dot(endpoints[j]);
float d_y=y_vec.dot(endpoints[j]);
float d_z=z_vec.dot(endpoints[j]);
-
+
if (j==0 || d_x<x_min)
x_min=d_x;
if (j==0 || d_x>x_max)
x_max=d_x;
-
+
if (j==0 || d_y<y_min)
y_min=d_y;
if (j==0 || d_y>y_max)
y_max=d_y;
-
+
if (j==0 || d_z<z_min)
z_min=d_z;
if (j==0 || d_z>z_max)
z_max=d_z;
-
-
+
+
}
@@ -5058,10 +5084,10 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
}
//now that we now all ranges, we can proceed to make the light frustum planes, for culling octree
-
+
Vector<Plane> light_frustum_planes;
light_frustum_planes.resize(6);
-
+
//right/left
light_frustum_planes[0]=Plane( x_vec, x_max );
light_frustum_planes[1]=Plane( -x_vec, -x_min );
@@ -5069,17 +5095,17 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
light_frustum_planes[2]=Plane( y_vec, y_max );
light_frustum_planes[3]=Plane( -y_vec, -y_min );
//near/far
- light_frustum_planes[4]=Plane( z_vec, z_max+1e6 );
- light_frustum_planes[5]=Plane( -z_vec, -z_min ); // z_min is ok, since casters further than far-light plane are not needed
-
+ light_frustum_planes[4]=Plane( z_vec, z_max+1e6 );
+ light_frustum_planes[5]=Plane( -z_vec, -z_min ); // z_min is ok, since casters further than far-light plane are not needed
+
int caster_cull_count = p_scenario->octree.cull_convex(light_frustum_planes,instance_shadow_cull_result,MAX_INSTANCE_CULL,INSTANCE_GEOMETRY_MASK);
-
+
// a pre pass will need to be needed to determine the actual z-near to be used
for(int j=0;j<caster_cull_count;j++) {
-
+
float min,max;
Instance *ins=instance_shadow_cull_result[j];
- if (!ins->visible || !ins->cast_shadows)
+ if (!ins->visible || ins->data.cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
continue;
ins->transformed_aabb.project_range_in_plane(Plane(z_vec,0),min,max);
@@ -5101,23 +5127,23 @@ void VisualServerRaster::_light_instance_update_pssm_shadow(Instance *p_light,Sc
rasterizer->light_instance_set_shadow_transform(p_light->light_info->instance, i, ortho_camera, ortho_transform,distances[i],distances[i+1] );
}
-
+
rasterizer->begin_shadow_map( p_light->light_info->instance, i );
-
+
for (int j=0;j<caster_cull_count;j++) {
-
+
Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !instance->cast_shadows)
+ if (!instance->visible || instance->data.cast_shadows==VS::SHADOW_CASTING_SETTING_OFF)
continue;
_instance_draw(instance);
}
-
+
rasterizer->end_shadow_map();
-
-
+
+
}
-
-
+
+
}
@@ -5190,7 +5216,7 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light,
for(int i=0;i<caster_count;i++) {
Instance *ins = instance_shadow_cull_result[i];
- if (!ins->visible || !ins->cast_shadows)
+ if (!ins->visible || ins->data.cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
continue;
for(int j=0;j<8;j++) {
@@ -5341,7 +5367,7 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light,
Instance *instance = instance_shadow_cull_result[i];
- if (!instance->visible || !instance->cast_shadows)
+ if (!instance->visible || instance->data.cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
continue;
_instance_draw(instance);
}
@@ -5438,7 +5464,7 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light,
for(int i=0;i<caster_count;i++) {
Instance *ins=instance_shadow_cull_result[i];
- if (!ins->visible || !ins->cast_shadows)
+ if (!ins->visible || ins->cast_shadows==VS::SHADOW_CASTING_SETTING_OFF)
continue;
//@TODO optimize using support mapping
@@ -5528,7 +5554,7 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light,
Instance *instance = instance_shadow_cull_result[i];
- if (!instance->visible || !instance->cast_shadows)
+ if (!instance->visible || instance->cast_shadows==VS::SHADOW_CASTING_SETTING_OFF)
continue;
_instance_draw(instance);
}
@@ -5553,7 +5579,7 @@ void VisualServerRaster::_light_instance_update_shadow(Instance *p_light,Scenari
Rasterizer::ShadowType shadow_type = rasterizer->light_instance_get_shadow_type(p_light->light_info->instance);
switch(shadow_type) {
-
+
case Rasterizer::SHADOW_SIMPLE: {
/* SPOT SHADOW */
@@ -5576,7 +5602,7 @@ void VisualServerRaster::_light_instance_update_shadow(Instance *p_light,Scenari
for (int i=0;i<cull_count;i++) {
Instance *instance = instance_shadow_cull_result[i];
- if (!instance->visible || !instance->cast_shadows)
+ if (!instance->visible || instance->data.cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
continue;
_instance_draw(instance);
}
@@ -5617,7 +5643,7 @@ void VisualServerRaster::_light_instance_update_shadow(Instance *p_light,Scenari
for (int j=0;j<cull_count;j++) {
Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !instance->cast_shadows)
+ if (!instance->visible || instance->data.cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
continue;
_instance_draw(instance);
@@ -5701,7 +5727,10 @@ void VisualServerRaster::_instance_validate_autorooms(Instance *p_geometry) {
int pass = room->room_info->room->bounds.get_points_inside(dst_points,point_count);
- float ratio = (float)pass / point_count;
+ float ratio = pass;
+ if( point_count != 0 ) {
+ ratio /= (float)point_count;
+ }
if (ratio>0.5) // should make some constant
p_geometry->valid_auto_rooms.insert(room);
@@ -6081,7 +6110,7 @@ void VisualServerRaster::_cull_room(Camera *p_camera, Instance *p_room,Instance
}
-
+
}
void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instance *p_sampled_light,bool p_linear_colorspace) {
@@ -6413,7 +6442,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
switch(p_camera->type) {
case Camera::ORTHOGONAL: {
-
+
camera_matrix.set_orthogonal(
p_camera->size,
viewport_rect.width / (float)viewport_rect.height,
@@ -6435,19 +6464,19 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
);
ortho=false;
-
- } break;
+
+ } break;
}
rasterizer->set_camera(p_camera->transform, camera_matrix,ortho);
-
+
Vector<Plane> planes = camera_matrix.get_projection_planes(p_camera->transform);
CullRange cull_range; // cull range is used for PSSM, and having an idea of the rendering depth
cull_range.nearp=Plane(p_camera->transform.origin,-p_camera->transform.basis.get_axis(2).normalized());
cull_range.z_near=camera_matrix.get_z_near();
- cull_range.z_far=camera_matrix.get_z_far();
+ cull_range.z_far=camera_matrix.get_z_far();
cull_range.min=cull_range.z_far;
cull_range.max=cull_range.z_near;
@@ -6463,10 +6492,10 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
*/
/* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */
-
+
// compute portals
-
+
exterior_visited=false;
exterior_portal_cull_count=0;
@@ -6547,11 +6576,11 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
/* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
-
+
for(int i=0;i<cull_count;i++) {
-
+
Instance *ins = instance_cull_result[i];
-
+
bool keep=false;
@@ -6571,7 +6600,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
}
- } else if ((1<<ins->base_type)&INSTANCE_GEOMETRY_MASK && ins->visible) {
+ } else if ((1<<ins->base_type)&INSTANCE_GEOMETRY_MASK && ins->visible && ins->data.cast_shadows!=VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
bool discarded=false;
@@ -6637,7 +6666,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
}
}
-
+
}
if (!keep) {
@@ -6651,12 +6680,12 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
ins->last_render_pass=render_pass;
}
}
-
+
if (cull_range.max > cull_range.z_far )
cull_range.max=cull_range.z_far;
if (cull_range.min < cull_range.z_near )
cull_range.min=cull_range.z_near;
-
+
/* STEP 5 - PROCESS LIGHTS */
rasterizer->shadow_clear_near(); //clear near shadows, will be recreated
@@ -6683,7 +6712,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
//discard lights not affecting anything (useful for deferred rendering, shadowmaps, etc)
for (int i=0;i<light_cull_count;i++) {
-
+
Instance *ins = light_cull_result[i];
if (light_discard_enabled) {
@@ -6712,7 +6741,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
}
-
+
}
{ //this should eventually change to
@@ -6725,12 +6754,12 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
if (!rasterizer->light_has_shadow(ins->base_rid) || !shadows_enabled)
continue;
-
+
/* for far shadows?
if (ins->version == ins->light_info->last_version && rasterizer->light_instance_has_far_shadow(ins->light_info->instance))
continue; // didn't change
*/
-
+
_light_instance_update_shadow(ins,p_scenario,p_camera,cull_range);
ins->light_info->last_version=ins->version;
}
@@ -6760,17 +6789,17 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
}
/* STEP 7 - PROCESS GEOMETRY AND DRAW SCENE*/
-
+
rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug);
- rasterizer->set_viewport(viewport_rect);
-
+ rasterizer->set_viewport(viewport_rect);
+
// add lights
{
List<RID>::Element *E=p_scenario->directional_lights.front();
-
+
for(;E;E=E->next()) {
Instance *light = E->get().is_valid()?instance_owner.get(E->get()):NULL;
@@ -6792,11 +6821,11 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
// add geometry
for(int i=0;i<cull_count;i++) {
-
+
Instance *ins = instance_cull_result[i];
ERR_CONTINUE(!((1<<ins->base_type)&INSTANCE_GEOMETRY_MASK));
-
+
_instance_draw(ins);
}
@@ -6857,7 +6886,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (global_rect.intersects(p_clip_rect) && ci->viewport.is_valid() && viewport_owner.owns(ci->viewport)) {
- Viewport *vp = viewport_owner.get(ci->viewport);
+ Viewport *vp = viewport_owner.get(ci->viewport);
Point2i from = xform.get_origin() + Point2(viewport_rect.x,viewport_rect.y);
Point2i size = rect.size;
@@ -7398,7 +7427,7 @@ void VisualServerRaster::_draw_viewports() {
rasterizer->set_viewport(viewport_rect);
}
- rasterizer->canvas_begin();
+ rasterizer->canvas_begin();
rasterizer->canvas_disable_blending();
rasterizer->canvas_begin_rect(Matrix32());
rasterizer->canvas_draw_rect(E->get()->rt_to_screen_rect,0,Rect2(Point2(),E->get()->rt_to_screen_rect.size),E->get()->render_target_texture,Color(1,1,1));
@@ -7526,7 +7555,7 @@ void VisualServerRaster::draw() {
rasterizer->begin_frame();
_draw_viewports();
_draw_cursors_and_margins();
- rasterizer->end_frame();
+ rasterizer->end_frame();
draw_extra_frame=rasterizer->needs_to_draw_next_frame();
}
@@ -7608,13 +7637,13 @@ void VisualServerRaster::set_boot_image(const Image& p_image, const Color& p_col
void VisualServerRaster::init() {
rasterizer->init();
-
+
shadows_enabled=GLOBAL_DEF("render/shadows_enabled",true);
//default_scenario = scenario_create();
//default_viewport = viewport_create();
for(int i=0;i<4;i++)
black_margin[i]=0;
-
+
Image img;
img.create(default_mouse_cursor_xpm);
//img.convert(Image::FORMAT_RGB);
@@ -7631,7 +7660,7 @@ void VisualServerRaster::_clean_up_owner(RID_OwnerBase *p_owner,String p_type) {
List<RID> rids;
p_owner->get_owned_list(&rids);
-
+
int lost=0;
for(List<RID>::Element *I=rids.front();I;I=I->next()) {
if (OS::get_singleton()->is_stdout_verbose()) {
@@ -7656,19 +7685,19 @@ void VisualServerRaster::finish() {
_clean_up_owner( &room_owner,"Room" );
_clean_up_owner( &portal_owner,"Portal" );
-
+
_clean_up_owner( &camera_owner,"Camera" );
_clean_up_owner( &viewport_owner,"Viewport" );
-
+
_clean_up_owner( &scenario_owner,"Scenario" );
_clean_up_owner( &instance_owner,"Instance" );
-
+
_clean_up_owner( &canvas_owner,"Canvas" );
_clean_up_owner( &canvas_item_owner,"CanvasItem" );
rasterizer->finish();
octree_allocator.clear();
-
+
if (instance_dependency_map.size()) {
print_line("Base resources missing amount: "+itos(instance_dependency_map.size()));
}
@@ -7680,9 +7709,9 @@ RID VisualServerRaster::get_test_cube() {
if (test_cube.is_valid())
return test_cube;
-
+
test_cube=_make_test_cube();
- return test_cube;
+ return test_cube;
}
@@ -7704,5 +7733,3 @@ VisualServerRaster::VisualServerRaster(Rasterizer *p_rasterizer) {
VisualServerRaster::~VisualServerRaster()
{
}
-
-
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index deb831b167..2b72b0b900 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -44,7 +44,7 @@ class VisualServerRaster : public VisualServer {
enum {
-
+
MAX_INSTANCE_CULL=8192,
MAX_INSTANCE_LIGHTS=4,
LIGHT_CACHE_DIRTY=-1,
@@ -58,13 +58,13 @@ class VisualServerRaster : public VisualServer {
};
struct Room {
-
+
bool occlude_exterior;
BSP_Tree bounds;
Room() { occlude_exterior=true; }
};
-
-
+
+
BalloonAllocator<> octree_allocator;
struct OctreeAllocator {
@@ -116,10 +116,10 @@ class VisualServerRaster : public VisualServer {
void _update_baked_light_sampler_dp_cache(BakedLightSampler * blsamp);
struct Camera {
-
+
enum Type {
PERSPECTIVE,
- ORTHOGONAL
+ ORTHOGONAL
};
Type type;
float fov;
@@ -128,18 +128,18 @@ class VisualServerRaster : public VisualServer {
uint32_t visible_layers;
bool vaspect;
RID env;
-
+
Transform transform;
-
+
Camera() {
-
+
visible_layers=0xFFFFFFFF;
fov=60;
type=PERSPECTIVE;
znear=0.1; zfar=100;
size=1.0;
vaspect=false;
-
+
}
};
@@ -147,30 +147,28 @@ class VisualServerRaster : public VisualServer {
struct Instance;
typedef Set<Instance*,Comparator<Instance*>,OctreeAllocator> InstanceSet;
struct Scenario;
-
+
struct Instance {
-
+
enum {
-
+
MAX_LIGHTS=4
};
-
+
RID self;
- OctreeElementID octree_id;
+ OctreeElementID octree_id;
Scenario *scenario;
bool update;
bool update_aabb;
- Instance *update_next;
+ Instance *update_next;
InstanceType base_type;
RID base_rid;
-
+
AABB aabb;
AABB transformed_aabb;
uint32_t object_ID;
bool visible;
- bool cast_shadows;
- bool receive_shadows;
bool visible_in_all_rooms;
uint32_t layer_mask;
float draw_range_begin;
@@ -181,7 +179,7 @@ class VisualServerRaster : public VisualServer {
Rasterizer::InstanceData data;
-
+
Set<Instance*> auto_rooms;
Set<Instance*> valid_auto_rooms;
Instance *room;
@@ -193,9 +191,9 @@ class VisualServerRaster : public VisualServer {
uint64_t last_render_pass;
uint64_t last_frame_pass;
-
+
uint64_t version; // changes to this, and changes to base increase version
-
+
InstanceSet lights;
bool light_cache_dirty;
@@ -206,7 +204,7 @@ class VisualServerRaster : public VisualServer {
Transform affine_inverse;
Room *room;
List<Instance*> owned_geometry_instances;
- List<Instance*> owned_portal_instances;
+ List<Instance*> owned_portal_instances;
List<Instance*> owned_room_instances;
List<Instance*> owned_light_instances; //not used, but just for the sake of it
Set<Instance*> disconnected_child_portals;
@@ -231,8 +229,8 @@ class VisualServerRaster : public VisualServer {
};
struct LightInfo {
-
- RID instance;
+
+ RID instance;
int light_set_index;
uint64_t last_version;
uint64_t last_add_pass;
@@ -241,10 +239,10 @@ class VisualServerRaster : public VisualServer {
bool enabled;
float dtc; //distance to camera, used for sorting
-
+
LightInfo() {
-
- D=NULL;
+
+ D=NULL;
light_set_index=-1;
last_add_pass=0;
enabled=true;
@@ -274,10 +272,10 @@ class VisualServerRaster : public VisualServer {
resolution=0;
}
};
-
+
struct ParticlesInfo {
-
- RID instance;
+
+ RID instance;
};
@@ -289,7 +287,7 @@ class VisualServerRaster : public VisualServer {
BakedLightSamplerInfo * baked_light_sampler_info;
- Instance() {
+ Instance() {
octree_id=0;
update_next=0;
object_ID=0;
@@ -300,8 +298,8 @@ class VisualServerRaster : public VisualServer {
update_next=NULL;
update=false;
visible=true;
- cast_shadows=true;
- receive_shadows=true;
+ data.cast_shadows=SHADOW_CASTING_SETTING_ON;
+ data.receive_shadows=true;
data.depth_scale=false;
data.billboard=false;
data.billboard_y=false;
@@ -329,9 +327,9 @@ class VisualServerRaster : public VisualServer {
light_cache_dirty=true;
}
-
+
~Instance() {
-
+
if (light_info)
memdelete(light_info);
if (particles_info)
@@ -344,26 +342,26 @@ class VisualServerRaster : public VisualServer {
memdelete(baked_light_info);
};
};
-
+
struct _InstanceLightsort {
bool operator()(const Instance* p_A, const Instance* p_B) const { return p_A->light_info->dtc < p_B->light_info->dtc; }
};
struct Scenario {
-
+
ScenarioDebugMode debug;
RID self;
// well wtf, balloon allocator is slower?
typedef ::Octree<Instance,true> Octree;
-
+
Octree octree;
-
+
List<RID> directional_lights;
RID environment;
RID fallback_environment;
-
+
Instance *dirty_instances;
Scenario() { dirty_instances=NULL; debug=SCENARIO_DEBUG_DISABLED; }
@@ -459,7 +457,7 @@ class VisualServerRaster : public VisualServer {
}
Canvas() { modulate=Color(1,1,1,1); }
-
+
};
@@ -525,14 +523,14 @@ class VisualServerRaster : public VisualServer {
Map<RID,int> screen_viewports;
struct CullRange {
-
+
Plane nearp;
float min,max;
float z_near,z_far;
-
+
void add_aabb(const AABB& p_aabb) {
-
-
+
+
}
};
@@ -560,12 +558,12 @@ class VisualServerRaster : public VisualServer {
Instance *instance_cull_result[MAX_INSTANCE_CULL];
Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps
- Instance *light_cull_result[MAX_LIGHTS_CULLED];
+ Instance *light_cull_result[MAX_LIGHTS_CULLED];
int light_cull_count;
Instance *exterior_portal_cull_result[MAX_EXTERIOR_PORTALS];
int exterior_portal_cull_count;
- bool exterior_visited;
+ bool exterior_visited;
Instance *light_sampler_cull_result[MAX_LIGHT_SAMPLERS];
int light_samplers_culled;
@@ -592,7 +590,7 @@ class VisualServerRaster : public VisualServer {
void _update_instance(Instance *p_instance);
void _free_attached_instances(RID p_rid,bool p_free_scenario=false);
void _clean_up_owner(RID_OwnerBase *p_owner,String p_type);
-
+
Instance *instance_update_list;
//RID default_scenario;
@@ -600,7 +598,7 @@ class VisualServerRaster : public VisualServer {
RID test_cube;
-
+
mutable RID_Owner<Room> room_owner;
mutable RID_Owner<Portal> portal_owner;
@@ -609,20 +607,20 @@ class VisualServerRaster : public VisualServer {
mutable RID_Owner<Camera> camera_owner;
mutable RID_Owner<Viewport> viewport_owner;
-
+
mutable RID_Owner<Scenario> scenario_owner;
mutable RID_Owner<Instance> instance_owner;
-
+
mutable RID_Owner<Canvas> canvas_owner;
mutable RID_Owner<CanvasItem> canvas_item_owner;
Map< RID, Set<RID> > instance_dependency_map;
Map< RID, Set<Instance*> > skeleton_dependency_map;
-
+
ViewportRect viewport_rect;
_FORCE_INLINE_ void _instance_draw(Instance *p_instance);
-
+
bool _test_portal_cull(Camera *p_camera, Instance *p_portal_from, Instance *p_portal_to);
void _cull_portal(Camera *p_camera, Instance *p_portal,Instance *p_from_portal);
void _cull_room(Camera *p_camera, Instance *p_room,Instance *p_from_portal=NULL);
@@ -641,9 +639,9 @@ class VisualServerRaster : public VisualServer {
void _light_instance_update_lispsm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range);
void _light_instance_update_pssm_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range);
-
+
void _light_instance_update_shadow(Instance *p_light,Scenario *p_scenario,Camera *p_camera,const CullRange& p_cull_range);
-
+
uint64_t render_pass;
int changes;
bool draw_extra_frame;
@@ -652,8 +650,8 @@ class VisualServerRaster : public VisualServer {
void _draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h);
void _draw_viewports();
void _draw_cursors_and_margins();
-
-
+
+
Rasterizer *rasterizer;
public:
@@ -677,7 +675,7 @@ public:
/* SHADER API */
-
+
virtual RID shader_create(ShaderMode p_mode=SHADER_MATERIAL);
virtual void shader_set_mode(RID p_shader,ShaderMode p_mode);
@@ -765,7 +763,7 @@ public:
virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const;
virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const;
virtual PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const;
-
+
virtual void mesh_remove_surface(RID p_mesh,int p_index);
virtual int mesh_get_surface_count(RID p_mesh) const;
@@ -808,23 +806,23 @@ public:
virtual void immediate_set_material(RID p_immediate,RID p_material);
virtual RID immediate_get_material(RID p_immediate) const;
-
+
/* PARTICLES API */
-
+
virtual RID particles_create();
-
+
virtual void particles_set_amount(RID p_particles, int p_amount);
virtual int particles_get_amount(RID p_particles) const;
-
+
virtual void particles_set_emitting(RID p_particles, bool p_emitting);
virtual bool particles_is_emitting(RID p_particles) const;
-
+
virtual void particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility);
virtual AABB particles_get_visibility_aabb(RID p_particles) const;
-
+
virtual void particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents);
virtual Vector3 particles_get_emission_half_extents(RID p_particles) const;
-
+
virtual void particles_set_emission_base_velocity(RID p_particles, const Vector3& p_base_velocity);
virtual Vector3 particles_get_emission_base_velocity(RID p_particles) const;
@@ -833,16 +831,16 @@ public:
virtual void particles_set_gravity_normal(RID p_particles, const Vector3& p_normal);
virtual Vector3 particles_get_gravity_normal(RID p_particles) const;
-
+
virtual void particles_set_variable(RID p_particles, ParticleVariable p_variable,float p_value);
virtual float particles_get_variable(RID p_particles, ParticleVariable p_variable) const;
-
+
virtual void particles_set_randomness(RID p_particles, ParticleVariable p_variable,float p_randomness);
virtual float particles_get_randomness(RID p_particles, ParticleVariable p_variable) const;
-
+
virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos);
virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const;
-
+
virtual void particles_set_color_phases(RID p_particles, int p_phases);
virtual int particles_get_color_phases(RID p_particles) const;
@@ -860,32 +858,32 @@ public:
virtual void particles_set_material(RID p_particles, RID p_material,bool p_owned=false);
virtual RID particles_get_material(RID p_particles) const;
-
+
virtual void particles_set_height_from_velocity(RID p_particles, bool p_enable);
virtual bool particles_has_height_from_velocity(RID p_particles) const;
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
virtual bool particles_is_using_local_coordinates(RID p_particles) const;
-
+
/* Light API */
-
+
virtual RID light_create(LightType p_type);
virtual LightType light_get_type(RID p_light) const;
virtual void light_set_color(RID p_light,LightColor p_type, const Color& p_color);
- virtual Color light_get_color(RID p_light,LightColor p_type) const;
-
+ virtual Color light_get_color(RID p_light,LightColor p_type) const;
+
virtual void light_set_shadow(RID p_light,bool p_enabled);
- virtual bool light_has_shadow(RID p_light) const;
-
+ virtual bool light_has_shadow(RID p_light) const;
+
virtual void light_set_volumetric(RID p_light,bool p_enabled);
- virtual bool light_is_volumetric(RID p_light) const;
-
+ virtual bool light_is_volumetric(RID p_light) const;
+
virtual void light_set_projector(RID p_light,RID p_texture);
virtual RID light_get_projector(RID p_light) const;
-
+
virtual void light_set_param(RID p_light, LightParam p_var, float p_value);
virtual float light_get_param(RID p_light, LightParam p_var) const;
@@ -902,7 +900,7 @@ public:
/* SKELETON API */
-
+
virtual RID skeleton_create();
virtual void skeleton_resize(RID p_skeleton,int p_bones);
virtual int skeleton_get_bone_count(RID p_skeleton) const;
@@ -914,9 +912,9 @@ public:
virtual RID room_create();
virtual void room_set_bounds(RID p_room, const BSP_Tree& p_bounds);
virtual BSP_Tree room_get_bounds(RID p_room) const;
-
+
/* PORTAL API */
-
+
virtual RID portal_create();
virtual void portal_set_shape(RID p_portal, const Vector<Point2>& p_shape);
virtual Vector<Point2> portal_get_shape(RID p_portal) const;
@@ -971,12 +969,12 @@ public:
virtual int baked_light_sampler_get_resolution(RID p_baked_light_sampler) const;
/* CAMERA API */
-
+
virtual RID camera_create();
virtual void camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far);
virtual void camera_set_orthogonal(RID p_camera,float p_size, float p_z_near, float p_z_far);
- virtual void camera_set_transform(RID p_camera,const Transform& p_transform);
-
+ virtual void camera_set_transform(RID p_camera,const Transform& p_transform);
+
virtual void camera_set_visible_layers(RID p_camera,uint32_t p_layers);
virtual uint32_t camera_get_visible_layers(RID p_camera) const;
@@ -1010,7 +1008,7 @@ public:
virtual void viewport_set_rect(RID p_viewport,const ViewportRect& p_rect);
virtual ViewportRect viewport_get_rect(RID p_viewport) const;
-
+
virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide);
virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide);
virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable);
@@ -1021,8 +1019,8 @@ public:
virtual RID viewport_get_scenario(RID p_viewport) const;
virtual void viewport_attach_canvas(RID p_viewport,RID p_canvas);
virtual void viewport_remove_canvas(RID p_viewport,RID p_canvas);
- virtual void viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Matrix32& p_offset);
- virtual Matrix32 viewport_get_canvas_transform(RID p_viewport,RID p_canvas) const;
+ virtual void viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Matrix32& p_offset);
+ virtual Matrix32 viewport_get_canvas_transform(RID p_viewport,RID p_canvas) const;
virtual void viewport_set_global_canvas_transform(RID p_viewport,const Matrix32& p_transform);
virtual Matrix32 viewport_get_global_canvas_transform(RID p_viewport) const;
virtual void viewport_set_canvas_layer(RID p_viewport,RID p_canvas,int p_layer);
@@ -1047,10 +1045,10 @@ public:
virtual void environment_fx_set_param(RID p_env,EnvironmentFxParam p_effect,const Variant& p_param);
virtual Variant environment_fx_get_param(RID p_env,EnvironmentFxParam p_effect) const;
-
+
/* SCENARIO API */
-
- virtual RID scenario_create();
+
+ virtual RID scenario_create();
virtual void scenario_set_debug(RID p_scenario,ScenarioDebugMode p_debug_mode);
virtual void scenario_set_environment(RID p_scenario, RID p_environment);
@@ -1058,9 +1056,9 @@ public:
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
-
+
/* INSTANCING API */
-
+
virtual RID instance_create();
virtual void instance_set_base(RID p_instance, RID p_base);
@@ -1102,6 +1100,9 @@ public:
virtual void instance_geometry_set_flag(RID p_instance,InstanceFlags p_flags,bool p_enabled);
virtual bool instance_geometry_get_flag(RID p_instance,InstanceFlags p_flags) const;
+ virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting);
+ virtual VS::ShadowCastingSetting instance_geometry_get_cast_shadows_setting(RID p_instance) const;
+
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material);
virtual RID instance_geometry_get_material_override(RID p_instance) const;
@@ -1122,7 +1123,7 @@ public:
virtual bool instance_light_is_enabled(RID p_instance) const;
/* CANVAS (2D) */
-
+
virtual RID canvas_create();
virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring);
virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const;
@@ -1224,7 +1225,7 @@ public:
virtual RID canvas_item_material_create();
virtual void canvas_item_material_set_shader(RID p_material, RID p_shader);
virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value);
- virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const;
+ virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const;
virtual void canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode);
@@ -1241,7 +1242,7 @@ public:
virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom);
/* FREE */
-
+
virtual void free( RID p_rid );
/* CUSTOM SHADE MODEL */
@@ -1258,7 +1259,7 @@ public:
virtual void draw();
virtual void sync();
- virtual void init();
+ virtual void init();
virtual void finish();
virtual bool has_changed() const;
@@ -1273,7 +1274,7 @@ public:
virtual void set_boot_image(const Image& p_image, const Color& p_color, bool p_scale);
virtual void set_default_clear_color(const Color& p_color);
- VisualServerRaster(Rasterizer *p_rasterizer);
+ VisualServerRaster(Rasterizer *p_rasterizer);
~VisualServerRaster();
};
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index 478a31806c..5ea4145342 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -35,20 +35,20 @@ void VisualServerWrapMT::thread_exit() {
}
void VisualServerWrapMT::thread_draw() {
-
-
+
+
draw_mutex->lock();
-
+
draw_pending--;
bool draw=(draw_pending==0);// only draw when no more flushes are pending
-
+
draw_mutex->unlock();
-
+
if (draw) {
-
+
visual_server->draw();
- }
-
+ }
+
}
void VisualServerWrapMT::thread_flush() {
@@ -67,10 +67,10 @@ void VisualServerWrapMT::thread_flush() {
void VisualServerWrapMT::_thread_callback(void *_instance) {
VisualServerWrapMT *vsmt = reinterpret_cast<VisualServerWrapMT*>(_instance);
-
+
vsmt->thread_loop();
-}
+}
void VisualServerWrapMT::thread_loop() {
@@ -79,18 +79,18 @@ void VisualServerWrapMT::thread_loop() {
OS::get_singleton()->make_rendering_thread();
visual_server->init();
-
+
exit=false;
draw_thread_up=true;
while(!exit) {
// flush commands one by one, until exit is requested
command_queue.wait_and_flush_one();
}
-
+
command_queue.flush_all(); // flush all
-
+
visual_server->finish();
-
+
}
@@ -117,7 +117,7 @@ void VisualServerWrapMT::sync() {
}
void VisualServerWrapMT::draw() {
-
+
if (create_thread) {
@@ -155,7 +155,7 @@ void VisualServerWrapMT::init() {
visual_server->init();
}
-
+
}
void VisualServerWrapMT::finish() {
@@ -164,7 +164,7 @@ void VisualServerWrapMT::finish() {
if (thread) {
command_queue.push( this, &VisualServerWrapMT::thread_exit);
- Thread::wait_to_finish( thread );
+ Thread::wait_to_finish( thread );
memdelete(thread);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 14961338db..b6018f1c25 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -41,9 +41,9 @@ class VisualServerWrapMT : public VisualServer {
// the real visual server
mutable VisualServer *visual_server;
-
+
mutable CommandQueueMT command_queue;
-
+
static void _thread_callback(void *_instance);
void thread_loop();
@@ -52,7 +52,7 @@ class VisualServerWrapMT : public VisualServer {
Thread *thread;
volatile bool draw_thread_up;
bool create_thread;
-
+
Mutex *draw_mutex;
int draw_pending;
void thread_draw();
@@ -441,7 +441,7 @@ public:
FUNC2(viewport_set_render_target_vflip,RID,bool);
FUNC1RC(bool,viewport_get_render_target_vflip,RID);
FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&);
-
+
FUNC2(viewport_set_render_target_clear_on_new_frame,RID,bool);
FUNC1RC(bool,viewport_get_render_target_clear_on_new_frame,RID);
FUNC1(viewport_render_target_clear,RID);
@@ -542,6 +542,9 @@ public:
FUNC3(instance_geometry_set_flag,RID,InstanceFlags ,bool );
FUNC2RC(bool,instance_geometry_get_flag,RID,InstanceFlags );
+ FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting);
+ FUNC1RC(ShadowCastingSetting, instance_geometry_get_cast_shadows_setting, RID);
+
FUNC2(instance_geometry_set_material_override,RID, RID );
FUNC1RC(RID,instance_geometry_get_material_override,RID);
@@ -668,7 +671,7 @@ public:
FUNC0R(RID,canvas_item_material_create);
FUNC2(canvas_item_material_set_shader,RID,RID);
FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&);
- FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&);
+ FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&);
FUNC2(canvas_item_material_set_shading_mode,RID,CanvasItemShadingMode);
/* CURSOR */
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index fd2913cc7e..17d5b16b9f 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -73,11 +73,11 @@ DVector<String> VisualServer::_shader_get_param_list(RID p_shader) const {
VisualServer *VisualServer::create() {
ERR_FAIL_COND_V(singleton,NULL);
-
+
if (create_func)
return create_func();
-
- return NULL;
+
+ return NULL;
}
RID VisualServer::texture_create_from_image(const Image& p_image,uint32_t p_flags) {
@@ -87,7 +87,7 @@ RID VisualServer::texture_create_from_image(const Image& p_image,uint32_t p_flag
ERR_FAIL_COND_V(!texture.is_valid(),texture);
texture_set_data(texture, p_image );
-
+
return texture;
}
@@ -152,9 +152,9 @@ RID VisualServer::_make_test_cube() {
DVector<Vector3> vertices;
DVector<Vector3> normals;
- DVector<float> tangents;
+ DVector<float> tangents;
DVector<Vector3> uvs;
-
+
int vtx_idx=0;
#define ADD_VTX(m_idx);\
vertices.push_back( face_points[m_idx] );\
@@ -168,20 +168,20 @@ RID VisualServer::_make_test_cube() {
for (int i=0;i<6;i++) {
-
+
Vector3 face_points[4];
Vector3 normal_points[4];
float uv_points[8]={0,0,0,1,1,1,1,0};
-
+
for (int j=0;j<4;j++) {
-
+
float v[3];
v[0]=1.0;
v[1]=1-2*((j>>1)&1);
v[2]=v[1]*(1-2*(j&1));
-
+
for (int k=0;k<3;k++) {
-
+
if (i<3)
face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
else
@@ -218,7 +218,7 @@ RID VisualServer::_make_test_cube() {
d[VisualServer::ARRAY_INDEX]=indices;
mesh_add_surface( test_cube, PRIMITIVE_TRIANGLES,d );
-
+
test_material = fixed_material_create();
@@ -231,51 +231,51 @@ RID VisualServer::_make_test_cube() {
fixed_material_set_param( test_material, FIXED_MATERIAL_PARAM_SPECULAR, Color(1,1,1) );
mesh_surface_set_material(test_cube, 0, test_material );
-
+
return test_cube;
}
RID VisualServer::make_sphere_mesh(int p_lats,int p_lons,float p_radius) {
-
+
DVector<Vector3> vertices;
DVector<Vector3> normals;
-
+
for(int i = 1; i <= p_lats; i++) {
double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats);
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
-
+
double lat1 = Math_PI * (-0.5 + (double) i / p_lats);
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
-
+
for(int j = p_lons; j >= 1; j--) {
-
+
double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
-
+
double lng1 = 2 * Math_PI * (double) (j) / p_lons;
- double x1 = Math::cos(lng1);
+ double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
-
-
+
+
Vector3 v[4]={
Vector3(x1 * zr0, z0, y1 *zr0),
Vector3(x1 * zr1, z1, y1 *zr1),
Vector3(x0 * zr1, z1, y0 *zr1),
Vector3(x0 * zr0, z0, y0 *zr0)
};
-
+
#define ADD_POINT(m_idx)\
normals.push_back(v[m_idx]); \
vertices.push_back(v[m_idx]*p_radius);\
-
+
ADD_POINT(0);
ADD_POINT(1);
ADD_POINT(2);
-
+
ADD_POINT(2);
ADD_POINT(3);
ADD_POINT(0);
@@ -313,7 +313,7 @@ RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_
material_2d[version]=fixed_material_create();
fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_ALPHA,p_transparent);
- fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
+ fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_DISCARD_ALPHA,p_cut_alpha);
material_set_flag(material_2d[version],MATERIAL_FLAG_UNSHADED,!p_shaded);
material_set_flag(material_2d[version],MATERIAL_FLAG_DOUBLE_SIDED,true);
@@ -736,23 +736,23 @@ void VisualServer::mesh_add_surface_from_mesh_data( RID p_mesh, const Geometry::
#if 1
DVector<Vector3> vertices;
DVector<Vector3> normals;
-
+
for (int i=0;i<p_mesh_data.faces.size();i++) {
-
+
const Geometry::MeshData::Face& f = p_mesh_data.faces[i];
-
+
for (int j=2;j<f.indices.size();j++) {
-
+
#define _ADD_VERTEX(m_idx)\
vertices.push_back( p_mesh_data.vertices[ f.indices[m_idx] ] );\
normals.push_back( f.plane.normal );
-
+
_ADD_VERTEX( 0 );
_ADD_VERTEX( j-1 );
_ADD_VERTEX( j );
- }
+ }
}
-
+
int s = mesh_get_surface_count(p_mesh);
Array d;
d.resize(VS::ARRAY_MAX);
@@ -783,7 +783,7 @@ void VisualServer::mesh_add_surface_from_mesh_data( RID p_mesh, const Geometry::
#endif
-
+
}
void VisualServer::mesh_add_surface_from_planes( RID p_mesh, const DVector<Plane>& p_planes) {
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 656b998eae..c70a72ef2a 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -53,18 +53,18 @@ class VisualServer : public Object {
void _viewport_set_rect(RID p_viewport,const Rect2& p_rect);
Rect2 _viewport_get_rect(RID p_viewport) const;
void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1));
-protected:
+protected:
RID _make_test_cube();
void _free_internal_rids();
RID test_texture;
RID white_texture;
RID test_material;
RID material_2d[16];
-
+
static VisualServer* (*create_func)();
- static void _bind_methods();
+ static void _bind_methods();
public:
-
+
static VisualServer *get_singleton();
static VisualServer *create();
@@ -80,9 +80,9 @@ public:
virtual MipMapPolicy get_mipmap_policy() const;
-
+
enum {
-
+
NO_INDEX_ARRAY=-1,
CUSTOM_ARRAY_SIZE=8,
ARRAY_WEIGHTS_SIZE=4,
@@ -95,7 +95,7 @@ public:
MAX_CURSORS = 8,
};
-
+
/* TEXTURE API */
enum TextureFlags {
@@ -108,21 +108,21 @@ public:
TEXTURE_FLAG_CUBEMAP=2048,
TEXTURE_FLAG_VIDEO_SURFACE=4096,
TEXTURE_FLAGS_DEFAULT=TEXTURE_FLAG_REPEAT|TEXTURE_FLAG_MIPMAPS|TEXTURE_FLAG_FILTER
- };
-
+ };
+
enum CubeMapSide {
-
+
CUBEMAP_LEFT,
CUBEMAP_RIGHT,
CUBEMAP_BOTTOM,
CUBEMAP_TOP,
- CUBEMAP_FRONT,
+ CUBEMAP_FRONT,
CUBEMAP_BACK
};
virtual RID texture_create()=0;
- RID texture_create_from_image(const Image& p_image,uint32_t p_flags=TEXTURE_FLAGS_DEFAULT); // helper
+ RID texture_create_from_image(const Image& p_image,uint32_t p_flags=TEXTURE_FLAGS_DEFAULT); // helper
virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=TEXTURE_FLAGS_DEFAULT)=0;
virtual void texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side=CUBEMAP_LEFT)=0;
virtual Image texture_get_data(RID p_texture,CubeMapSide p_cube_side=CUBEMAP_LEFT) const=0;
@@ -237,7 +237,7 @@ public:
FIXED_MATERIAL_PARAM_SPECULAR_EXP,
FIXED_MATERIAL_PARAM_GLOW,
FIXED_MATERIAL_PARAM_NORMAL,
- FIXED_MATERIAL_PARAM_SHADE_PARAM,
+ FIXED_MATERIAL_PARAM_SHADE_PARAM,
FIXED_MATERIAL_PARAM_MAX
};
@@ -299,15 +299,15 @@ public:
ARRAY_VERTEX=0,
ARRAY_NORMAL=1,
ARRAY_TANGENT=2,
- ARRAY_COLOR=3,
- ARRAY_TEX_UV=4,
+ ARRAY_COLOR=3,
+ ARRAY_TEX_UV=4,
ARRAY_TEX_UV2=5,
ARRAY_BONES=6,
- ARRAY_WEIGHTS=7,
+ ARRAY_WEIGHTS=7,
ARRAY_INDEX=8,
ARRAY_MAX=9
- };
-
+ };
+
enum ArrayFormat {
/* ARRAY FORMAT FLAGS */
ARRAY_FORMAT_VERTEX=1<<ARRAY_VERTEX, // mandatory
@@ -319,8 +319,8 @@ public:
ARRAY_FORMAT_BONES=1<<ARRAY_BONES,
ARRAY_FORMAT_WEIGHTS=1<<ARRAY_WEIGHTS,
ARRAY_FORMAT_INDEX=1<<ARRAY_INDEX,
- };
-
+ };
+
enum PrimitiveType {
PRIMITIVE_POINTS=0,
PRIMITIVE_LINES=1,
@@ -330,10 +330,10 @@ public:
PRIMITIVE_TRIANGLE_STRIP=5,
PRIMITIVE_TRIANGLE_FAN=6,
PRIMITIVE_MAX=7,
- };
+ };
virtual RID mesh_create()=0;
-
+
virtual void mesh_add_surface(RID p_mesh,PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array(),bool p_alpha_sort=false)=0;
virtual Array mesh_get_surface_arrays(RID p_mesh,int p_surface) const=0;
virtual Array mesh_get_surface_morph_arrays(RID p_mesh,int p_surface) const=0;
@@ -358,7 +358,7 @@ public:
virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const=0;
virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const=0;
virtual PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const=0;
-
+
virtual void mesh_remove_surface(RID p_mesh,int p_index)=0;
virtual int mesh_get_surface_count(RID p_mesh) const=0;
@@ -405,9 +405,9 @@ public:
/* PARTICLES API */
-
+
virtual RID particles_create()=0;
-
+
enum ParticleVariable {
PARTICLE_LIFETIME,
PARTICLE_SPREAD,
@@ -425,16 +425,16 @@ public:
PARTICLE_HEIGHT_SPEED_SCALE,
PARTICLE_VAR_MAX
};
-
+
virtual void particles_set_amount(RID p_particles, int p_amount)=0;
virtual int particles_get_amount(RID p_particles) const=0;
-
+
virtual void particles_set_emitting(RID p_particles, bool p_emitting)=0;
virtual bool particles_is_emitting(RID p_particles) const=0;
-
+
virtual void particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility)=0;
virtual AABB particles_get_visibility_aabb(RID p_particles) const=0;
-
+
virtual void particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents)=0;
virtual Vector3 particles_get_emission_half_extents(RID p_particles) const=0;
@@ -443,13 +443,13 @@ public:
virtual void particles_set_emission_points(RID p_particles, const DVector<Vector3>& p_points)=0;
virtual DVector<Vector3> particles_get_emission_points(RID p_particles) const=0;
-
+
virtual void particles_set_gravity_normal(RID p_particles, const Vector3& p_normal)=0;
virtual Vector3 particles_get_gravity_normal(RID p_particles) const=0;
-
+
virtual void particles_set_variable(RID p_particles, ParticleVariable p_variable,float p_value)=0;
virtual float particles_get_variable(RID p_particles, ParticleVariable p_variable) const=0;
-
+
virtual void particles_set_randomness(RID p_particles, ParticleVariable p_variable,float p_randomness)=0;
virtual float particles_get_randomness(RID p_particles, ParticleVariable p_variable) const=0;
@@ -458,7 +458,7 @@ public:
virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos)=0;
virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const=0;
-
+
virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color& p_color)=0;
virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const=0;
@@ -473,7 +473,7 @@ public:
virtual void particles_set_material(RID p_particles, RID p_material,bool p_owned=false)=0;
virtual RID particles_get_material(RID p_particles) const=0;
-
+
virtual void particles_set_height_from_velocity(RID p_particles, bool p_enable)=0;
virtual bool particles_has_height_from_velocity(RID p_particles) const=0;
@@ -481,20 +481,20 @@ public:
virtual bool particles_is_using_local_coordinates(RID p_particles) const=0;
/* Light API */
-
+
enum LightType {
LIGHT_DIRECTIONAL,
LIGHT_OMNI,
LIGHT_SPOT
};
- enum LightColor {
+ enum LightColor {
LIGHT_COLOR_DIFFUSE,
LIGHT_COLOR_SPECULAR
};
-
+
enum LightParam {
-
+
LIGHT_PARAM_SPOT_ATTENUATION,
LIGHT_PARAM_SPOT_ANGLE,
LIGHT_PARAM_RADIUS,
@@ -512,20 +512,20 @@ public:
virtual LightType light_get_type(RID p_light) const=0;
virtual void light_set_color(RID p_light,LightColor p_type, const Color& p_color)=0;
- virtual Color light_get_color(RID p_light,LightColor p_type) const=0;
+ virtual Color light_get_color(RID p_light,LightColor p_type) const=0;
virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
- virtual bool light_has_shadow(RID p_light) const=0;
-
+ virtual bool light_has_shadow(RID p_light) const=0;
+
virtual void light_set_volumetric(RID p_light,bool p_enabled)=0;
- virtual bool light_is_volumetric(RID p_light) const=0;
-
+ virtual bool light_is_volumetric(RID p_light) const=0;
+
virtual void light_set_projector(RID p_light,RID p_texture)=0;
virtual RID light_get_projector(RID p_light) const=0;
-
+
virtual void light_set_param(RID p_light, LightParam p_var, float p_value)=0;
virtual float light_get_param(RID p_light, LightParam p_var) const=0;
-
+
enum LightOp {
LIGHT_OPERATOR_ADD,
@@ -567,26 +567,26 @@ public:
virtual float light_directional_get_shadow_param(RID p_light,LightDirectionalShadowParam p_param) const=0;
//@TODO fallof model and all that stuff
-
+
/* SKELETON API */
-
+
virtual RID skeleton_create()=0;
virtual void skeleton_resize(RID p_skeleton,int p_bones)=0;
virtual int skeleton_get_bone_count(RID p_skeleton) const=0;
virtual void skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform)=0;
virtual Transform skeleton_bone_get_transform(RID p_skeleton,int p_bone)=0;
-
+
/* ROOM API */
virtual RID room_create()=0;
virtual void room_set_bounds(RID p_room, const BSP_Tree& p_bounds)=0;
virtual BSP_Tree room_get_bounds(RID p_room) const=0;
-
+
/* PORTAL API */
// portals are only (x/y) points, forming a convex shape, which its clockwise
// order points outside. (z is 0);
-
+
virtual RID portal_create()=0;
virtual void portal_set_shape(RID p_portal, const Vector<Point2>& p_shape)=0;
virtual Vector<Point2> portal_get_shape(RID p_portal) const=0;
@@ -654,11 +654,11 @@ public:
virtual int baked_light_sampler_get_resolution(RID p_baked_light_sampler) const=0;
/* CAMERA API */
-
+
virtual RID camera_create()=0;
virtual void camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far)=0;
virtual void camera_set_orthogonal(RID p_camera,float p_size, float p_z_near, float p_z_far)=0;
- virtual void camera_set_transform(RID p_camera,const Transform& p_transform)=0;
+ virtual void camera_set_transform(RID p_camera,const Transform& p_transform)=0;
virtual void camera_set_visible_layers(RID p_camera,uint32_t p_layers)=0;
virtual uint32_t camera_get_visible_layers(RID p_camera) const=0;
@@ -720,14 +720,14 @@ public:
struct ViewportRect {
-
+
int x,y,width,height;
ViewportRect() { x=y=width=height=0; }
};
-
+
virtual void viewport_set_rect(RID p_viewport,const ViewportRect& p_rect)=0;
virtual ViewportRect viewport_get_rect(RID p_viewport) const=0;
-
+
virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide)=0;
virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide)=0;
virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable)=0;
@@ -854,7 +854,7 @@ public:
- virtual RID scenario_create()=0;
+ virtual RID scenario_create()=0;
enum ScenarioDebugMode {
SCENARIO_DEBUG_DISABLED,
@@ -872,9 +872,9 @@ public:
/* INSTANCING API */
-
+
enum InstanceType {
-
+
INSTANCE_NONE,
INSTANCE_MESH,
INSTANCE_MULTIMESH,
@@ -888,7 +888,7 @@ public:
INSTANCE_GEOMETRY_MASK=(1<<INSTANCE_MESH)|(1<<INSTANCE_MULTIMESH)|(1<<INSTANCE_IMMEDIATE)|(1<<INSTANCE_PARTICLES)
};
-
+
virtual RID instance_create2(RID p_base, RID p_scenario);
@@ -909,17 +909,17 @@ public:
virtual void instance_set_transform(RID p_instance, const Transform& p_transform)=0;
virtual Transform instance_get_transform(RID p_instance) const=0;
-
+
virtual void instance_attach_object_instance_ID(RID p_instance,uint32_t p_ID)=0;
virtual uint32_t instance_get_object_instance_ID(RID p_instance) const=0;
virtual void instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight)=0;
virtual float instance_get_morph_target_weight(RID p_instance,int p_shape) const=0;
-
+
virtual void instance_attach_skeleton(RID p_instance,RID p_skeleton)=0;
virtual RID instance_get_skeleton(RID p_instance) const=0;
-
+
virtual void instance_set_exterior( RID p_instance, bool p_enabled )=0;
virtual bool instance_is_exterior( RID p_instance) const=0;
@@ -946,9 +946,19 @@ public:
INSTANCE_FLAG_MAX
};
+ enum ShadowCastingSetting {
+ SHADOW_CASTING_SETTING_OFF,
+ SHADOW_CASTING_SETTING_ON,
+ SHADOW_CASTING_SETTING_DOUBLE_SIDED,
+ SHADOW_CASTING_SETTING_SHADOWS_ONLY,
+ };
+
virtual void instance_geometry_set_flag(RID p_instance,InstanceFlags p_flags,bool p_enabled)=0;
virtual bool instance_geometry_get_flag(RID p_instance,InstanceFlags p_flags) const=0;
+ virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, ShadowCastingSetting p_shadow_casting_setting) = 0;
+ virtual ShadowCastingSetting instance_geometry_get_cast_shadows_setting(RID p_instance) const = 0;
+
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material)=0;
virtual RID instance_geometry_get_material_override(RID p_instance) const=0;
@@ -1151,10 +1161,10 @@ public:
RID material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_alpha,bool p_opaque_prepass);
-
+
/* TESTING */
-
+
virtual RID get_test_cube()=0;
virtual RID get_test_texture();
@@ -1176,7 +1186,7 @@ public:
virtual bool has_feature(Features p_feature) const=0;
- VisualServer();
+ VisualServer();
virtual ~VisualServer();
};
diff --git a/tools/Godot.app/Contents/Info.plist b/tools/Godot.app/Contents/Info.plist
index cb2db17807..e2a6489782 100755
--- a/tools/Godot.app/Contents/Info.plist
+++ b/tools/Godot.app/Contents/Info.plist
@@ -19,11 +19,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>1.0.0</string>
+ <string>2.0.1</string>
<key>CFBundleSignature</key>
<string>godot</string>
<key>CFBundleVersion</key>
- <string>1.0.0</string>
+ <string>2.0.1</string>
<key>NSHumanReadableCopyright</key>
<string>© 2007-2016 Juan Linietsky, Ariel Manzur</string>
<key>LSMinimumSystemVersion</key>
diff --git a/tools/SCsub b/tools/SCsub
index f046e9ad08..5613d8a6c9 100644
--- a/tools/SCsub
+++ b/tools/SCsub
@@ -11,7 +11,6 @@ if (env["tools"]!="no"):
SConscript('collada/SCsub');
SConscript('docdump/SCsub');
SConscript('freetype/SCsub');
- SConscript('pe_bliss/SCsub');
SConscript('doc/SCsub')
SConscript('pck/SCsub')
diff --git a/tools/certs/ca-certificates.crt b/tools/certs/ca-certificates.crt
new file mode 100644
index 0000000000..862096d85a
--- /dev/null
+++ b/tools/certs/ca-certificates.crt
@@ -0,0 +1,4826 @@
+-----BEGIN CERTIFICATE-----
+MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB
+VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
+bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R
+dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw
+MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy
+dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52
+ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM
+EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj
+lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ
+znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH
+2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1
+k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs
+2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD
+VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG
+KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+
+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R
+FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
+mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE
+DNuxUCAKGkq6ahq97BvIxYSazQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE
+AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x
+CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW
+MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF
+RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
+AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7
+09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7
+XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P
+Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK
+t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb
+X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28
+MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU
+fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI
+2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH
+K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae
+ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP
+BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ
+MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw
+RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
+bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm
+fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3
+gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe
+I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i
+5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi
+ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn
+MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ
+o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6
+zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN
+GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt
+r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK
+Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx
+CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp
+ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa
+QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw
+NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft
+ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu
+QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG
+qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL
+fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ
+Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4
+Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ
+54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b
+MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j
+ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej
+YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt
+A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF
+rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ
+pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB
+lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy
+YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50
+7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs
+YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6
+xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc
+unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/
+Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp
+ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42
+gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0
+jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+
+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD
+W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/
+RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r
+MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk
+BYn8eNZcLCZDqQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
+bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
+cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
+IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
+AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
+MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
+VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
+CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
+tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
+dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
+PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
+BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
+ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
+IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
+7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
+43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
+eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
+pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
+WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
+MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
+ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
+BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
+6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
+GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
+dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
+1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
+62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
+BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
+MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
+cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
+b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
+IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
+iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
+GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
+4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
+XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
+b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
+MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
+EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
+BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
+xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
+87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
+2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
+WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
+0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
+A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
+pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
+ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
+aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
+hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
+hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
+dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
+P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
+iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
+xqE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
+Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
+ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
+MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
+yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
+VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
+nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
+XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
+vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
+Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
+N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
+nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
+YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
+kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
+QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
+6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
+yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
+QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
+tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
+QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
+Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
+olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
+x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
+dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
+A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
+cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
+qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
+JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
+s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
+HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
+70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
+V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
+qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
+5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
+C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
+OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
+FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
+KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
+Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
+8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
+MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
+0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
+u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
+u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
+YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
+GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
+RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
+KeC2uAloGRwYQw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
+cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
+BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
+VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
+0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
+ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
+A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
+aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
+flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
+MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
+b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
+AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
+aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
+j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
+f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
+IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
+FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
+QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
+/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
+k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
+MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
+seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
+hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
+DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
+B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
+rosot4LKGAfmt1t06SAZf7IbiVQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
+MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
+VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
+cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
+ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
+AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
+661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
+am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
+ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
+PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
+3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
+SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
+3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
+ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
+StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
+Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
+jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
+Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL
+MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
+VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0
+ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX
+l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB
+HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B
+5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3
+WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP
+gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+
+DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu
+BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs
+h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk
+LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
+Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL
+MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
+VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg
+isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z
+NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI
++MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R
+hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+
+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD
+AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP
+Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s
+EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2
+mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC
+e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow
+dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET
+MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE
+AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw
+CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg
+YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE
+Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX
+mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD
+XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW
+S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp
+FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD
+AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu
+ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z
+ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv
+Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw
+DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6
+yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq
+EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
+CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB
+EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN
+PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
+TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
+MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
+Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
+IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
+dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
+V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
+GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
+v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
+AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
+Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
+76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
+OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
+ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
+yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
+buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
+2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
+b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
+MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
+ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
+IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
+AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
+unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
+BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
+7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
+0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
+roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
+A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
+aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
+26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
+BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
+EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
+BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
+aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
+AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
+p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
+1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
+XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
+eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
+tGWaIZDgqtCYvDi1czyL+Nw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
+MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
+ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
+YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
+MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
+NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
+A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
+A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
+Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
+QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
+eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
+B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
+z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
+AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
+ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
+TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
+MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
+VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
+VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
+bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
+AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
+bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
+ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
+VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
+ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
+AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
+MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
+BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
+Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
+cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
+aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
+F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
+8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
+rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
+/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
+7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
+28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
+lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
+nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
+0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
+5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
+WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
+jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
+KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
+ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
+OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
+619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
+2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
+o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
+nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
+5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
+pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
+dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
+BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
+PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
+cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
+MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
+IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
+ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
+VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
+kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
+EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
+H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
+HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
+DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
+QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
+Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
+AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
+yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
+FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
+ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
+kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
+l7+ijrRU
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
+jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
+ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
+ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
+Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
+AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
+HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
+uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
+TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
+xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
+CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
+O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
+6GAqm4VKQPNriiTsBhYscw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
+IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
+MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
+dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
+EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
+MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
+28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
+VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
+DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
+5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
+ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
+Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
+UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
+Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
+ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
+hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
+HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
+YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
+L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
+ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
+IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
+HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
+DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
+PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
+5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
+glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
+FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
+pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
+xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
+tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
+jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
+fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
+OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
+d0jQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0
+MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG
+EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT
+CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK
+8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2
+98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb
+2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC
+ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi
+Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB
+o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl
+ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD
+AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL
+AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd
+foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M
+cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq
+8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp
+hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk
+Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
+AGegcQCCSA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
+PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
+MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
+GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
+MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
+HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
+gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
+v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
+Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
+9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
+6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
+MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
+Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
+ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
+hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
+iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
+dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
+kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
+hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
+OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
+ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
+fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
+BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
+cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
+HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
+CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
+3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
+6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
+HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
+EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
+Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
+Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
+DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
+5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
+Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
+gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
+aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
+izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
+aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
+MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
+BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
+VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
+fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
+TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
+fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
+1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
+kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
+A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
+ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
+dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
+Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
+HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
+pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
+jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
+xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
+dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG
+A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh
+bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE
+ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS
+b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5
+7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS
+J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y
+HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP
+t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz
+FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY
+XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
+MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw
+hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js
+MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA
+A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj
+Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx
+XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o
+omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc
+A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
+WL1WMRJOEcgh4LMRkWXbtKaIOM5V
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
+ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
+MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
+VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
+FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
+ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
+gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
+fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
+ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
+ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
+c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
+dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
+aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
+hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
+QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
+h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
+nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
+rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
+9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
+MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
+IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
+IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
+RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
+U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
+IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
+ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
+QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
+rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
+NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
+QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
+txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
+BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
+AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
+tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
+IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
+6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
+Cm26OWMohpLzGITY+9HPBVZkVw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV
+UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL
+EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ
+BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x
+ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg
+bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ
+j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV
+Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG
+SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx
+JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI
+RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw
+MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5
+fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i
++DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG
+SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN
+QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+
+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV
+UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL
+EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ
+BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x
+ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/
+k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso
+LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o
+TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG
+SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx
+JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI
+RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3
+MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C
+TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5
+WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG
+SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR
+xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL
+B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV
+BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt
+ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4
+MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg
+SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl
+a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h
+4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk
+tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s
+tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL
+dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4
+c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um
+TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z
++kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O
+Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW
+OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW
+fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2
+l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
+/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw
+FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+
+8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI
+6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO
+TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME
+wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY
+Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn
+xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q
+DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q
+Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t
+hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4
+7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7
+QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
+MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
+j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
+U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
+u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
+bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
+fF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
+UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
+dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
+MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
+dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
+BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
+cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
+AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
+MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
+aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
+ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
+IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
+MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
+A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
+7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
+1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
+ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
+MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
+dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
+c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
+UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
+58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
+o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
+aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
+A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
+Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
+8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
+ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
+MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
+LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
+KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
+RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
+WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
+Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
+AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
+eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
+zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
+/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
+R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
+9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
+fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
+iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
+1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
+MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
+ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
+uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
+Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
+tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
+PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
+hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
+5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
+IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
+R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
+PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
+Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
+TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
+5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
+S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
+2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
+FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
+EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
+EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
+/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
+A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
+abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
+I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
+4iIprn2DQKi6bA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
+MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
+R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
+MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
+AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
+ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
+7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
+kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
+mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
+KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
+6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
+4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
+oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
+UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
+AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
+MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
+KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
+MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
+BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
+NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
+BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
+So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
+tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
+CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
+qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
+rD6ogRLQy7rQkgu2npaqBA+K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
+mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
+MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
+cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
+BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
+MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
+BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
+hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
+5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
+JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
+DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
+huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
+HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
+AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
+zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
+kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
+AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
+SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
+spki4cErx5z481+oghLrGREt
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
+c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
+BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
+IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
+VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
+cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
+QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
+F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
+c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
+mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
+VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
+teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
+f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
+Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
+nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
+/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
+MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
+9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
+aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
+IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
+ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
+uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
+Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
+QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
+koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
+ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
+DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
+bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
+MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
+c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
+VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
+c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
+WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
+FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
+XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
+se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
+KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
+IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
+y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
+hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
+QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
+Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
+HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
+KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
+dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
+L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
+Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
+ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
+T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
+GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
+1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
+OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
+6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
+QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
+VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
+IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
+MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
+aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
+MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
+cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
+A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
+BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
+KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
+G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
+zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
+ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
+HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
+Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
+yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
+beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
+6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
+wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
+zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
+BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
+ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
+ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
+cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
+YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
+CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
+KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
+hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
+UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
+X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
+fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
+a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
+Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
+SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
+AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
+M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
+v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
+09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
+FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
+Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
+A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
+b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
+jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
+PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
+ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
+nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
+q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
+MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
+mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
+7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
+oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
+EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
+fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
+AmvZWg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT
+AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ
+TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG
+9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw
+MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM
+BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO
+MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2
+LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI
+s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2
+xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4
+u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b
+F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx
+Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd
+PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV
+HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx
+NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF
+AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ
+L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY
+YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
+Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a
+NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R
+0982gaEbeC9xs/FZTEYYKKuF0mBWWg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN
+AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp
+dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw
+MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw
+CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ
+MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB
+SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz
+ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH
+LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP
+PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL
+2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w
+ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC
+MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk
+AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0
+AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz
+AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz
+AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f
+BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
+FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY
+P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi
+CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g
+kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95
+HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS
+na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q
+qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z
+TbvGRNs2yyqcjg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw
+cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy
+b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z
+ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4
+NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN
+TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p
+Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u
+uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+
+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA
+vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770
+Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx
+62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB
+AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw
+LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP
+BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB
+AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov
+MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5
+ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
+AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT
+AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh
+ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo
+AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa
+AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln
+bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p
+Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP
+PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv
+Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB
+EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu
+w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj
+cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV
+HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI
+VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS
+BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS
+b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS
+8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds
+ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl
+7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
+86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR
+hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/
+MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD
+EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05
+OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G
+A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
+Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l
+dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG
+SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK
+gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX
+iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc
+Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E
+BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G
+SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu
+b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh
+bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv
+Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln
+aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0
+IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
+c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph
+biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo
+ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP
+UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj
+YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo
+dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA
+bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06
+sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa
+n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS
+NitjrFgBazMpUIaD8QFI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD
+EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X
+DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw
+DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u
+c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr
+TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA
+OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC
+2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW
+RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P
+AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW
+ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0
+YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz
+b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO
+ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB
+IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs
+b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
+ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s
+YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg
+a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g
+SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0
+aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg
+YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg
+Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY
+ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g
+pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4
+Fp1hBWeAyNDYpQcCNJgEjTME1A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV
+MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe
+TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0
+dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB
+KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0
+N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC
+dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu
+MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL
+b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD
+zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi
+3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8
+WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY
+Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi
+NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC
+ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4
+QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0
+YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz
+aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
+IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm
+ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg
+ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs
+amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv
+IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3
+Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6
+ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1
+YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg
+dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs
+b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G
+CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO
+xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP
+0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ
+QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk
+f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK
+8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx
+ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
+b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD
+EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz
+aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w
+MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G
+A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
+Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l
+dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh
+bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq
+eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe
+r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5
+3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd
+vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l
+mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC
+wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg
+hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0
+TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
+biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg
+ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg
+dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6
+b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl
+c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0
+ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3
+dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu
+ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh
+bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo
+ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3
+Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u
+ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA
+A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ
+MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+
+NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR
+VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY
+83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3
+macqaJVmlaut74nLYKkGEsaUR+ko
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
+MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
+MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
+dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
+UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
+ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
+c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
+OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
+mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
+BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
+qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
+gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
+bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
+dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
+6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
+h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
+/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
+wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
+pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
+ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
+aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
+NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
+A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
+SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
+VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
+w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
+mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
+4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
+4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
+EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
+SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
+ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
+vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
+hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
+Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
+/L7fCg0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
+MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
+IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
+dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
+li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
+rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
+WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
+F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
+xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
+Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
+dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
+ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
+IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
+c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
+ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
+Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
+KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
+KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
+y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
+dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
+VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
+fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
+7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
+cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
+mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
+xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
+SnQ2+Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
+MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
+dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
+BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
+MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
+eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
+/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
+wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
+AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
+PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
+AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
+MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
+HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
+Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
+f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
+rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
+6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
+7CAFYd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF
+UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ
+R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN
+MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G
+A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw
+JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+
+WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj
+SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl
+u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy
+A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk
+Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7
+MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr
+aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC
+IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A
+cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA
+YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA
+bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA
+bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
+aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA
+aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA
+ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA
+YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA
+ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA
+LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6
+Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y
+eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw
+CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G
+A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu
+Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn
+lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt
+b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg
+9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF
+ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC
+IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCB
+rjELMAkGA1UEBhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcp
+MRIwEAYDVQQHEwlTdHV0dGdhcnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fz
+c2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVTLVRSVVNUIEF1dGhlbnRpY2F0aW9u
+IGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0wNTA2MjIwMDAwMDBa
+Fw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4t
+V3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMg
+RGV1dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJV
+U1QgQXV0aGVudGljYXRpb24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBO
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1
+toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob4QSwI7+Vio5bG0F/WsPo
+TUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXLg3KSwlOy
+ggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1
+XgqfeN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteF
+hy+S8dF2g08LOlk3KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm
+7QIDAQABo4GSMIGPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEG
+MCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJvbmxpbmUxLTIwNDgtNTAdBgNV
+HQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAUD8oeXHngovMp
+ttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD
+pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFo
+LtU96G7m1R08P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersF
+iXOMy6ZNwPv2AtawB6MDwidAnwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0y
+h9WUUpY6RsZxlj33mA6ykaqP2vROJAA5VeitF7nTNCtKqUDMFypVZUF0Qn71wK/I
+k63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8bHz2eBIPdltkdOpQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
+MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
+A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
+MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
+Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
+QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
+i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
+h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
+MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
+UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
+8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
+h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
+VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
+AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
+KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
+X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
+QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
+pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
+QSdJQO7e5iNEOdyhIta6A/I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
+MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
+IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
+bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
+RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
+zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
+bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
+MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
+VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
+OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
+tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
+q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
+EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
+VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
+MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
+dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
+WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
+VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
+9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
+DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
+Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
+QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
+xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
+A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
+kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
+Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
+Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
+JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
+RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx
+MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG
+29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk
+oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk
+3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL
+qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN
+nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX
+ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H
+DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO
+TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv
+kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w
+zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
+MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
+MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
+BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
+Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
+5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
+3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
+vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
+8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
+DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
+MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
+zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
+3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
+FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
+Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
+ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
+TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
+MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
+ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
+ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
+9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
+hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
+tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
+BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
+SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
+OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
+cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
+7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
+/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
+eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
+u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
+7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
+iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
+DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
+qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
+uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
+Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
+pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
+5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
+UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
+GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
+5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
+6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
+eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
+B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
+BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
+L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
+SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
+CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
+5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
+IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
+gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
+vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
+bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
+N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
+Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
+ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
+ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
+ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
+dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
+OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
+8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
+Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
+hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
+6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
+AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
+bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
+ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
+qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
+0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
+sSi6
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
+MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
+U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
+cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
+pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
+OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
+Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
+Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
+HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
+Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
+Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
+26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
+AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
+FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
+ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
+LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
+BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
+Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
+dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
+cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
+YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
+dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
+bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
+YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
+TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
+9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
+jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
+FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
+ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
+ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
+EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
+L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
+yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
+O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
+um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
+NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu
+IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw
+WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD
+ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y
+IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn
+IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+
+6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob
+jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw
+izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl
++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY
+zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP
+pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF
+KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW
+ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB
+AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0
+ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
+IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA
+A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0
+uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+
+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7
+jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/
+u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D
+YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1
+puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa
+icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG
+DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x
+kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z
+Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
+BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
+IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
+RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
+U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
+Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
+YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
+nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
+6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
+eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
+c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
+MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
+HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
+jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
+5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
+rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
+wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
+cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
+AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
+WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
+xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
+2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
+IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
+aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
+em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
+dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
+OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
+tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
+m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
+FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
+TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
+EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
+kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
+HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
+vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
+19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
+L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
+bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
+JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
+BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
+K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
+ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
+Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
+sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
+3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
+ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
+mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
+b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
+rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
+hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
+zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
+MBr1mmz0DlP5OlvRHA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
+BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
+Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
+OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
+SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
+VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
+tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
+uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
+XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
+8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
+5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
+kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
+dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
+Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
+JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
+Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
+TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
+GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
+ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
+au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
+hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
+dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
+BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
+Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
+OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
+SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
+VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
+Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
+Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
+1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
+ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
+Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
+XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
+dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
+Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
+JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
+Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
+TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
+irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
+TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
+g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
+95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
+S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
+MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
+BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
+c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
+MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
+R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
+VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
+JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
+fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
+jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
+wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
+fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
+VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
+CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
+7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
+8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
+ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
+ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
+2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg
+MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
+dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz
+MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy
+dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD
+VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg
+xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu
+xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7
+XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k
+heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J
+YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C
+urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1
+JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51
+b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV
+9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7
+kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh
+fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
+B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA
+aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS
+RGQDJereW26fyfJOrN3H
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS
+S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
+SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3
+WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv
+bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU
+UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw
+bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe
+LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef
+J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh
+R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ
+Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX
+JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p
+zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S
+Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq
+ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
+Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz
+gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH
+uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS
+y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
+MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
+V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
+WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
+LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
+AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
+K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
+RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
+rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
+3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
+hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
+MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
+XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
+lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
+aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
+YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
+MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
+PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
+IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
+gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
+yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
+F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
+jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
+ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
+VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
+YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
+EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
+Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
+DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
+MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
+UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
+TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
+qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
+ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
+JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
+hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
+EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
+nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
+udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
+ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
+LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
+pYYsfPQS
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
+MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
+bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
+VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
+YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
+dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
+ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
+Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
+aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
+QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
+xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
+aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
+IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
+gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
+O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
+fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
+lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
+hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
+AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
+NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
+wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
+7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
+gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
+oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
+yZyQ2uypQjyttgI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
+kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
+IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
+EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
+VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
+dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
+E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
+D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
+4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
+lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
+bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
+o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
+MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
+LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
+BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
+AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
+Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
+j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
+KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
+2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
+mfnGV/TJVTl4uix5yaaIK/QI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB
+rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt
+Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa
+Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV
+BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l
+dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE
+AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B
+YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9
+hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l
+L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm
+SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM
+1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws
+6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw
+Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50
+aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
+AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u
+7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0
+xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ
+rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim
+eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk
+USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
+MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
+d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
+cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
+0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
+M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
+MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
+oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
+DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
+oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
+bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
+BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
+CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
+CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
+3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
+KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
+U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
+SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
+biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
+GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
+fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
+aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
+aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
+kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
+4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
+FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
+ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
+ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
+biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
+U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
+nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
+t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
+SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
+BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
+rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
+NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
+BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
+BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
+aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
+MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
+p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
+5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
+WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
+4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
+hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
+vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
+U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
+ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
+IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
+IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
+bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
+9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
+H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
+LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
+/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
+rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
+WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
+exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
+DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
+sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
+seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
+4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
+lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
+7M2CYfE45k+XmCpajQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f
+zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi
+TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G
+CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW
+NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV
+Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
+c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
+MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
+emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
+DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
+YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
+MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK
+VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm
+Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID
+AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J
+h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
+uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68
+DzFc6PLZ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
+nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
+8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
+ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
+PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
+6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
+n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
+qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
+wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
+ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
+pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
+E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns
+YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
+aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe
+Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX
+MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj
+IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx
+KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B
+AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM
+HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw
+DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC
+AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji
+nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
+rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn
+jBJ7xUS0rg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
+aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
+IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
+Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
+BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
+Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
+Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
+Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
+IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
+J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
+JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
+wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
+koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
+qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
+Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
+xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
+7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
+sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
+sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
+cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
+BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
+I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
+CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
+lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
+AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
+c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
+MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
+emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
+DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
+FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
+UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
+YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
+MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
+pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
+13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
+AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
+U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
+F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
+oJ2daZH9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
+N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
+KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
+kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
+CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
+Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
+imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
+2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
+DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
+/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
+F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
+TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
+cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
+LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
+aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
+VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
+aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
+bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
+IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
+GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
+U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
+NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
+ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
+ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
+CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
+g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
+fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
+2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
+bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
+MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
+cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
+bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
+CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
+dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
+cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
+2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
+lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
+ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
+299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
+vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
+dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
+AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
+zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
+LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
+7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
+++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
+398znM/jra6O1I7mT1GvFpLgXPYHDw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
+IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
+cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
+dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
+MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
+bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
+DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
+WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
+Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
+HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
+z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
+SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
+AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
+KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
+AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
+BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
+VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
+ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
+Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
+ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
+/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
+A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
+k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
+iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
+2G0xffX8oRAHh84vWdw+WNs=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
+qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
+BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
+NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
+LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
+A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
+W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
+3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
+6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
+Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
+NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
+r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
+DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
+YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
+xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
+/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
+LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
+jVaMaA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
+IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
+BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
+MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
+d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
+YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
+dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
+BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
+papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
+DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
+KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
+XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
+rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
+Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
+MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
+BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
+Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
+LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
+MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
+ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
+gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
+YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
+b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
+9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
+zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
+OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
+HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
+2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
+oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
+t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
+KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
+m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
+MdRAGmI0Nj81Aa6sY6A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIIDjCCBfagAwIBAgIJAOiOtsn4KhQoMA0GCSqGSIb3DQEBBQUAMIG8MQswCQYD
+VQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UEBxMMSW5kaWFuYXBvbGlz
+MSgwJgYDVQQKEx9Tb2Z0d2FyZSBpbiB0aGUgUHVibGljIEludGVyZXN0MRMwEQYD
+VQQLEwpob3N0bWFzdGVyMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkx
+JTAjBgkqhkiG9w0BCQEWFmhvc3RtYXN0ZXJAc3BpLWluYy5vcmcwHhcNMDgwNTEz
+MDgwNzU2WhcNMTgwNTExMDgwNzU2WjCBvDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
+B0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMfU29mdHdh
+cmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1hc3RlcjEe
+MBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcNAQkBFhZo
+b3N0bWFzdGVyQHNwaS1pbmMub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEA3DbmR0LCxFF1KYdAw9iOIQbSGE7r7yC9kDyFEBOMKVuUY/b0LfEGQpG5
+GcRCaQi/izZF6igFM0lIoCdDkzWKQdh4s/Dvs24t3dHLfer0dSbTPpA67tfnLAS1
+fOH1fMVO73e9XKKTM5LOfYFIz2u1IiwIg/3T1c87Lf21SZBb9q1NE8re06adU1Fx
+Y0b4ShZcmO4tbZoWoXaQ4mBDmdaJ1mwuepiyCwMs43pPx93jzONKao15Uvr0wa8u
+jyoIyxspgpJyQ7zOiKmqp4pRQ1WFmjcDeJPI8L20QcgHQprLNZd6ioFl3h1UCAHx
+ZFy3FxpRvB7DWYd2GBaY7r/2Z4GLBjXFS21ZGcfSxki+bhQog0oQnBv1b7ypjvVp
+/rLBVcznFMn5WxRTUQfqzj3kTygfPGEJ1zPSbqdu1McTCW9rXRTunYkbpWry9vjQ
+co7qch8vNGopCsUK7BxAhRL3pqXTT63AhYxMfHMgzFMY8bJYTAH1v+pk1Vw5xc5s
+zFNaVrpBDyXfa1C2x4qgvQLCxTtVpbJkIoRRKFauMe5e+wsWTUYFkYBE7axt8Feo
++uthSKDLG7Mfjs3FIXcDhB78rKNDCGOM7fkn77SwXWfWT+3Qiz5dW8mRvZYChD3F
+TbxCP3T9PF2sXEg2XocxLxhsxGjuoYvJWdAY4wCAs1QnLpnwFVMCAwEAAaOCAg8w
+ggILMB0GA1UdDgQWBBQ0cdE41xU2g0dr1zdkQjuOjVKdqzCB8QYDVR0jBIHpMIHm
+gBQ0cdE41xU2g0dr1zdkQjuOjVKdq6GBwqSBvzCBvDELMAkGA1UEBhMCVVMxEDAO
+BgNVBAgTB0luZGlhbmExFTATBgNVBAcTDEluZGlhbmFwb2xpczEoMCYGA1UEChMf
+U29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDETMBEGA1UECxMKaG9zdG1h
+c3RlcjEeMBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSUwIwYJKoZIhvcN
+AQkBFhZob3N0bWFzdGVyQHNwaS1pbmMub3JnggkA6I62yfgqFCgwDwYDVR0TAQH/
+BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAAcwCQYDVR0SBAIwADAuBglghkgBhvhC
+AQ0EIRYfU29mdHdhcmUgaW4gdGhlIFB1YmxpYyBJbnRlcmVzdDAwBglghkgBhvhC
+AQQEIxYhaHR0cHM6Ly9jYS5zcGktaW5jLm9yZy9jYS1jcmwucGVtMDIGCWCGSAGG
++EIBAwQlFiNodHRwczovL2NhLnNwaS1pbmMub3JnL2NlcnQtY3JsLnBlbTAhBgNV
+HREEGjAYgRZob3N0bWFzdGVyQHNwaS1pbmMub3JnMA4GA1UdDwEB/wQEAwIBBjAN
+BgkqhkiG9w0BAQUFAAOCAgEAtM294LnqsgMrfjLp3nI/yUuCXp3ir1UJogxU6M8Y
+PCggHam7AwIvUjki+RfPrWeQswN/2BXja367m1YBrzXU2rnHZxeb1NUON7MgQS4M
+AcRb+WU+wmHo0vBqlXDDxm/VNaSsWXLhid+hoJ0kvSl56WEq2dMeyUakCHhBknIP
+qxR17QnwovBc78MKYiC3wihmrkwvLo9FYyaW8O4x5otVm6o6+YI5HYg84gd1GuEP
+sTC8cTLSOv76oYnzQyzWcsR5pxVIBcDYLXIC48s9Fmq6ybgREOJJhcyWR2AFJS7v
+dVkz9UcZFu/abF8HyKZQth3LZjQl/GaD68W2MEH4RkRiqMEMVObqTFoo5q7Gt/5/
+O5aoLu7HaD7dAD0prypjq1/uSSotxdz70cbT0ZdWUoa2lOvUYFG3/B6bzAKb1B+P
++UqPti4oOxfMxaYF49LTtcYDyeFIQpvLP+QX4P4NAZUJurgNceQJcHdC2E3hQqlg
+g9cXiUPS1N2nGLar1CQlh7XU4vwuImm9rWgs/3K1mKoGnOcqarihk3bOsPN/nOHg
+T7jYhkalMwIsJWE3KpLIrIF0aGOHM3a9BX9e1dUCbb2v/ypaqknsmHlHU5H2DjRa
+yaXG67Ljxay2oHA1u8hRadDytaIybrw/oDc5fHE2pgXfDBLkFqfF1stjo5VwP+YE
+o2A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB
+8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy
+dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1
+YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3
+dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh
+IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD
+LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG
+EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g
+KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD
+ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu
+bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg
+ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R
+85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm
+4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV
+HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd
+QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t
+lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB
+o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4
+opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo
+dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW
+ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN
+AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y
+/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k
+SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy
+Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS
+Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl
+nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
+RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
+YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
+NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
+EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
+cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
+dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
+fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
+bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
+75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
+FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
+HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
+5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
+b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
+A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
+6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
+TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
+dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
+Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
+l7WdmplNsDz4SgCbZN2fOUvRJ9e4
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
+BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
+MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
+SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
+ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
+UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
+4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
+KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
+gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
+rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
+51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
+be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
+KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
+v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
+fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
+jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
+ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
+e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
+jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
+WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
+SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
+pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
+X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
+fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
+K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
+ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
+LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
+LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
+MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
+czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
+CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
+MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
+ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
+b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
+euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
+bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
+WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
+MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
+1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
+VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
+zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
+BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
+BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
+v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
+E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
+uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
+iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
+GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
+OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
+A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
+JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
+vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
+D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
+Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
+RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
+HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
+nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
+0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
+UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
+Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
+TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
+BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
+2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
+UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
+6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
+9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
+HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
+wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
+XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
+IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
+hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
+so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
+ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
+MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
+MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
+iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
+vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
+0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
+OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
+BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
+FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
+GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
+zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
+1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
+f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
+jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
+ZetX2fNXlrtIzYE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
+MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
+D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
+OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
+fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
+IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
+oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
+/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
+rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
+3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
+7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
+yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
+qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
+hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
+xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
+SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
+HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
+emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
+AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
+7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
+DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
+F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
+a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
+Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
+Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
+Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
+aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
+Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
+SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
+aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
+ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
+7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
+DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
+zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
+hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
+4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
+gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
+NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
+FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
+j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
+52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
+echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
+ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
+zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
+wy39FCqQmbkHzJ8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1
+dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
+YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
+dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
+aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
+IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
+KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw
+MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy
+b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx
+KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG
+A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u
+aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9
+7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74
+BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G
+ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9
+JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0
+PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2
+0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
+0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/
+6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m
+v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7
+K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev
+bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw
+MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w
+MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD
+gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0
+b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh
+bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0
+cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp
+ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg
+ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq
+hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD
+AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w
+MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag
+RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t
+UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl
+cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
+Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG
+AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN
+AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS
+1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB
+3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv
+Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh
+HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm
+pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz
+sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE
+qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb
+mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9
+opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H
+YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
+MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
+U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
+cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
+pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
+OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
+Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
+Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
+HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
+Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
+Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
+26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
+AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
+F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
+ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
+ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
+aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
+YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
+c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
+d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
+CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
+dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
+wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
+Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
+0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
+pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
+CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
+P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
+1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
+KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
+JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
+8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
+fyWl8kgAwKQB2j8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
+MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
+YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
+Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
+AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
+Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
+jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
+0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
+2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
+ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
+y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
+tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
+6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
+uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
+acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
+k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
+VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
+FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
+BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
+b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
+fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
+/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
+REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
+srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
+aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
+woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
+Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
+t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
+8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
+9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
+wSsSnqaeG8XmDtkx2Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
+ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
+dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
+IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
+VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
+dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
+MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
+UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
+1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
+oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
+HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
+5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
+idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
+OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
+NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
+46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
+UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
+7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
+A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
+MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
+bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
+XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
+PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
+Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
+WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
+Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
+7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
+nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
+vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
+WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
+fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
+I+2ksx0WckNLIOFZfsLorSa/ovc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc
+UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
+c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS
+S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
+SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx
+OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry
+b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC
+VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE
+sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F
+ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY
+KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG
++7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG
+HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P
+IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M
+733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk
+Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW
+AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
+aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5
+mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa
+XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ
+qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
+BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
+I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
+CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
+2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
+2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
+AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
+CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
+BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
+VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
+qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
+HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
+G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
+lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
+IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
+0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
+k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
+4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
+m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
+cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
+uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
+KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
+ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
+AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
+VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
+CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
+cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
+QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
+7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
+cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
+QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
+czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
+aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
+aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
+DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
+BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
+D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
+JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
+AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
+vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
+tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
+7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
+h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
+d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
+pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
+AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
+EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
+FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
+REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
+Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
+VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
+SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
+4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
+cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
+eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
+A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
+DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
+vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
+DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
+maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
+lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
+KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
+BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
+aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
+BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
+Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
+MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
+em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
+ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
+B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
+D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
+Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
+q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
+k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
+fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
+dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
+ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
+zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
+rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
+U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
+Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
+XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
+Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
+HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
+GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
+77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
+vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
+FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
+yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
+AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
+y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
+NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
+MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
+wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
+rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
+68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
+4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
+UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
+abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
+3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
+KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
+hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
+Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
+zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
+ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
+cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
+qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
+YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
+b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
+8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
+NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
+ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
+q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
+nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGGTCCBAGgAwIBAgIIPtVRGeZNzn4wDQYJKoZIhvcNAQELBQAwajEhMB8GA1UE
+AxMYU0cgVFJVU1QgU0VSVklDRVMgUkFDSU5FMRwwGgYDVQQLExMwMDAyIDQzNTI1
+Mjg5NTAwMDIyMRowGAYDVQQKExFTRyBUUlVTVCBTRVJWSUNFUzELMAkGA1UEBhMC
+RlIwHhcNMTAwOTA2MTI1MzQyWhcNMzAwOTA1MTI1MzQyWjBqMSEwHwYDVQQDExhT
+RyBUUlVTVCBTRVJWSUNFUyBSQUNJTkUxHDAaBgNVBAsTEzAwMDIgNDM1MjUyODk1
+MDAwMjIxGjAYBgNVBAoTEVNHIFRSVVNUIFNFUlZJQ0VTMQswCQYDVQQGEwJGUjCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANqoVgLsfJXwTukK0rcHoyKL
+ULO5Lhk9V9sZqtIr5M5C4myh5F0lHjMdtkXRtPpZilZwyW0IdmlwmubHnAgwE/7m
+0ZJoYT5MEfJu8rF7V1ZLCb3cD9lxDOiaN94iEByZXtaxFwfTpDktwhpz/cpLKQfC
+eSnIyCauLMT8I8hL4oZWDyj9tocbaF85ZEX9aINsdSQePHWZYfrSFPipS7HYfad4
+0hNiZbXWvn5qA7y1svxkMMPQwpk9maTTzdGxxFOHe0wTE2Z/v9VlU2j5XB7ltP82
+mUWjn2LAfxGCAVTeD2WlOa6dSEyJoxA74OaD9bDaLB56HFwfAKzMq6dgZLPGxXvH
+VUZ0PJCBDkqOWZ1UsEixUkw7mO6r2jS3U81J2i/rlb4MVxH2lkwEeVyZ1eXkvm/q
+R+5RS+8iJq612BGqQ7t4vwt+tN3PdB0lqYljseI0gcSINTjiAg0PE8nVKoIV8IrE
+QzJW5FMdHay2z32bll0eZOl0c8RW5BZKUm2SOdPhTQ4/YrnerbUdZbldUv5dCamc
+tKQM2S9FdqXPjmqanqqwEaHrYcbrPx78ZrQSnUZ/MhaJvnFFr5Eh2f2Tv7QCkUL/
+SR/tixVo3R+OrJvdggWcRGkWZBdWX0EPSk8ED2VQhpOX7EW/XcIc3M/E2DrmeAXQ
+xVVVqV7+qzohu+VyFPcLAgMBAAGjgcIwgb8wHQYDVR0OBBYEFCkgy/HDD9oGjhOT
+h/5fYBopu/O2MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUKSDL8cMP2gaO
+E5OH/l9gGim787YwEQYDVR0gBAowCDAGBgRVHSAAMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuc2d0cnVzdHNlcnZpY2VzLmNvbS9yYWNpbmUtR3JvdXBlU0cv
+TGF0ZXN0Q1JMMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEATEZn
+4ERQ9cW2urJRCiUTHbfHiC4fuStkoMuTiFJZqmD1zClSF/8E5ze0MRFGfisebKeL
+PEeaXvSqXZA7RT2fSsmKe47A7j55i5KjyJRKuCgRa6YlX129x8j7g09VMeZc8BN8
+471/Kiw3N5RJr4QfFCeiWBCPCjk3GhIgQY8Z9qkfGe2yNLKtfTNEi18KB0PydkVF
+La3kjQ4A/QQIqudr+xe9sAhWDjUqcvCz5006Tw3c82ASszhkjNv54SaNL+9O6CRH
+PjY0imkPKGuLh8a9hSb50+tpIVZgkdb34GLCqHGuLt5mI7VSRqakSDcsfwEWVxH3
+Jw0O5Q/WkEXhHj8h3NL8FhgTPk1qsiZqQF4leP049KxYejcbmEAEx47J1MRnYbGY
+rvDNDty5r2WDewoEij9hqvddQYbmxkzCTzpcVuooO6dEz8hKZPVyYC3jQ7hK4HU8
+MuSqFtcRucFF2ZtmY2blIrc07rrVdC8lZPOBVMt33lfUk+OsBzE6PlwDg1dTx/D+
+aNglUE0SyObhlY1nqzyTPxcCujjXnvcwpT09RAEzGpqfjtCf8e4wiHPvriQZupdz
+FcHscQyEZLV77LxpPqRtCRY2yko5isune8YdfucziMm+MG2chZUh6Uc7Bn6B4upG
+5nBYgOao8p0LadEziVkw82TTC/bOKwn7fRB2LhA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG
+MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV
+BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw
+MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl
+ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r
+D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1
+9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf
+v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk
+UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L
+NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb
++gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V
+qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K
+yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G
+AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK
+J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC
+AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4
+WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
+yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj
+/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6
+jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2
+ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX
+X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n
+FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D
+u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l
+O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le
+ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1
+2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV
+MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
+BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
+MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
+b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN
+rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U
+fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc
+f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2
+ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M
+x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR
+aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch
+zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar
+uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K
+mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA
+Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv
+HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H
+EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
+LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ
+MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e
+JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN
+g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp
+dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab
+R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ
+PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce
+xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+
+J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl
+OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT
+ee5Ehr7XHuQe+w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
+ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
+KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
+ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
+MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
+ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
+b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
+bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
+U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
+A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
+I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
+wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
+AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
+oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
+BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
+dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
+MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
+b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
+dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
+MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
+E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
+MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
+hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
+95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
+2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv
+bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv
+b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
+cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
+b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH
+iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS
+r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4
+04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r
+GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9
+3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P
+lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy
+NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD
+cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs
+2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY
+JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE
+Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ
+n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
+PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
+VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
+biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
+dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
+MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
+MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
+A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
+b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
+cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
+bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
+VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
+ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
+uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
+hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
+pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
+FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
+VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
+biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
+MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
+MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
+DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
+dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
+cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
+DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
+yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
+L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
+EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
+7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
+QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
+qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy
+NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y
+LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+
+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y
+TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0
+LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW
+I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
+nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
+NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
+dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
+WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
+v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
+UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
+IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD
+TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
+aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx
+MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j
+aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP
+T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03
+sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL
+TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5
+/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp
+7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz
+EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt
+hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP
+a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot
+aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg
+TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV
+PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv
+cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL
+tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd
+BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT
+ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL
+jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS
+ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy
+P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19
+xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d
+Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN
+5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe
+/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z
+AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ
+5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
+6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
+pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
+9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
+/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
+Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
+qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
+SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
+u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
+Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
+crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
+/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
+wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
+4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
+2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
+FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
+CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
+boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
+jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
+S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
+QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
+0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
+NVOFBkpdn627G190
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
+NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
+RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
+cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
+wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
+U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
+jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
+BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
+jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
+1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
+nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
+VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
+FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
+uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
+kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
+ewv4n4Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
+VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
+MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
+JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
+3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
+S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
+bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
+T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
+vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
+Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
+dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
+c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
+l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
+iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
+ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
+LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
+nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
+W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
+AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
+l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
+4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
+mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
+7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
+VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
+MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
+MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
+ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
+RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
+bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
+/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
+3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
+EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
+9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
+GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
+2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
+WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
+W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
+AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
+DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
+TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
+lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
+mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
+WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
+tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
+GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
+8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y
+MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg
+TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS
+b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS
+M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC
+UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d
+Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p
+rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l
+pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb
+j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC
+KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS
+/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X
+cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH
+1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP
+px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7
+MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
+eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u
+2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS
+v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC
+wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy
+CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e
+vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6
+Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa
+Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL
+eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8
+FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc
+7uzXLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX
+DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP
+cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW
+IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX
+xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy
+KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR
+9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az
+5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8
+6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7
+Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP
+bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt
+BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt
+XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd
+INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
+U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp
+LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8
+Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp
+gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh
+/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw
+0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A
+fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq
+4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR
+1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/
+QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM
+94B7IWcnMFk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID2DCCAsCgAwIBAgIQYFbFSyNAW2TU7SXa2dYeHjANBgkqhkiG9w0BAQsFADCB
+hTELMAkGA1UEBhMCREUxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZl
+cmxhZyBHbWJIMScwJQYDVQQLEx5TLVRSVVNUIENlcnRpZmljYXRpb24gU2Vydmlj
+ZXMxIjAgBgNVBAMTGVMtVFJVU1QgVW5pdmVyc2FsIFJvb3QgQ0EwHhcNMTMxMDIy
+MDAwMDAwWhcNMzgxMDIxMjM1OTU5WjCBhTELMAkGA1UEBhMCREUxKTAnBgNVBAoT
+IERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMScwJQYDVQQLEx5TLVRS
+VVNUIENlcnRpZmljYXRpb24gU2VydmljZXMxIjAgBgNVBAMTGVMtVFJVU1QgVW5p
+dmVyc2FsIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo
+4wvfETeFgpq1bGZ8YT/ARxodRuOwVWTluII5KAd+F//0m4rwkYHqOD8heGxI7Gsv
+otOKcrKn19nqf7TASWswJYmM67fVQGGY4tw8IJLNZUpynxqOjPolFb/zIYMoDYuv
+WRGCQ1ybTSVRf1gYY2A7s7WKi1hjN0hIkETCQN1d90NpKZhcEmVeq5CSS2bf1XUS
+U1QYpt6K1rtXAzlZmRgFDPn9FcaQZEYXgtfCSkE9/QC+V3IYlHcbU1qJAfYzcg6T
+OtzoHv0FBda8c+CI3KtP7LUYhk95hA5IKmYq3TLIeGXIC51YAQVx7YH1aBduyw20
+S9ih7K446xxYL6FlAzQvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMB0GA1UdDgQWBBSafdfr639UmEUptCCrbQuWIxmkwjANBgkqhkiG
+9w0BAQsFAAOCAQEATpYS2353XpInniEXGIJ22D+8pQkEZoiJrdtVszNqxmXEj03z
+MjbceQSWqXcy0Zf1GGuMuu3OEdBEx5LxtESO7YhSSJ7V/Vn4ox5R+wFS5V/let2q
+JE8ii912RvaloA812MoPmLkwXSBvwoEevb3A/hXTOCoJk5gnG5N70Cs0XmilFU/R
+UsOgyqCDRR319bdZc11ZAY+qwkcvFHHVKeMQtUeTJcwjKdq3ctiR1OwbSIoi5MEq
+9zpok59FGW5Dt8z+uJGaYRo2aWNkkijzb2GShROfyQcsi1fc65551cLeCNVUsldO
+KjKNoeI60RAgIjl9NEVvcTvDHfz/sk+o4vYwHg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
+eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
+JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
+VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
+I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
+o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
+A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
+zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
+RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp
index 07da72718e..8f40ec1469 100644
--- a/tools/collada/collada.cpp
+++ b/tools/collada/collada.cpp
@@ -1650,7 +1650,7 @@ Collada::Node* Collada::_parse_visual_scene_node(XMLParser& parser) {
String name;
- String id = parser.get_attribute_value_safe("id");
+ String id = parser.get_attribute_value_safe("id");
bool found_name=false;
diff --git a/tools/doc/doc_data.cpp b/tools/doc/doc_data.cpp
index 11e4797747..2d0d7617c2 100644
--- a/tools/doc/doc_data.cpp
+++ b/tools/doc/doc_data.cpp
@@ -190,7 +190,11 @@ void DocData::generate(bool p_basic_types) {
#ifdef DEBUG_METHODS_ENABLED
if (m && m->get_return_type()!=StringName())
method.return_type=m->get_return_type();
- else if (arginfo.type!=Variant::NIL) // {
+ else if (method.name.find(":")!=-1) {
+ method.return_type=method.name.get_slice(":",1);
+ method.name=method.name.get_slice(":",0);
+
+ } else if (arginfo.type!=Variant::NIL) // {
#endif
method.return_type=(arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE)?arginfo.hint_string:Variant::get_type_name(arginfo.type);
// }
@@ -210,7 +214,7 @@ void DocData::generate(bool p_basic_types) {
} else if (arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE) {
type_name=arginfo.hint_string;
} else if (arginfo.type==Variant::NIL)
- type_name="var";
+ type_name="Variant";
else
type_name=Variant::get_type_name(arginfo.type);
@@ -433,7 +437,7 @@ void DocData::generate(bool p_basic_types) {
if (i==Variant::INPUT_EVENT) {
static const char* ie_type[InputEvent::TYPE_MAX]={
- "","Key","MouseMotion","MouseButton","JoyMotion","JoyButton","ScreenTouch","ScreenDrag","Action"
+ "","Key","MouseMotion","MouseButton","JoystickMotion","JoystickButton","ScreenTouch","ScreenDrag","Action"
};
cname+=ie_type[j];
}
diff --git a/tools/docdump/doc_dump.cpp b/tools/docdump/doc_dump.cpp
index f8e035e3fa..fbf13f9e8f 100644
--- a/tools/docdump/doc_dump.cpp
+++ b/tools/docdump/doc_dump.cpp
@@ -248,7 +248,7 @@ void DocDump::dump(const String& p_file) {
}
- _write_string(f,1,"</methods>");
+ _write_string(f,1,"</methods>");
List<MethodInfo> signal_list;
ObjectTypeDB::get_signal_list(name,&signal_list,true);
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
new file mode 100644
index 0000000000..428de9d1a7
--- /dev/null
+++ b/tools/docker/Dockerfile
@@ -0,0 +1,13 @@
+FROM ubuntu:14.04
+MAINTAINER Mohammad Rezai, https://github.com/mrezai
+WORKDIR /godot-dev
+COPY scripts/install-android-tools /godot-dev/
+ENV DEBIAN_FRONTEND noninteractive
+RUN dpkg --add-architecture i386 && \
+ apt-get update && \
+ apt-get upgrade -y && \
+ apt-get install --no-install-recommends -y -q \
+ build-essential gcc-multilib g++-multilib mingw32 mingw-w64 scons pkg-config libx11-dev libxcursor-dev \
+ libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libudev-dev \
+ git wget openjdk-7-jdk libbcprov-java libc6:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386 lib32z1
+
diff --git a/tools/docker/README.md b/tools/docker/README.md
new file mode 100644
index 0000000000..7f10b46ad8
--- /dev/null
+++ b/tools/docker/README.md
@@ -0,0 +1,40 @@
+## A Docker image to build Linux, Windows and Android godot binaries.
+
+The main reason to write this, is to provide a simple way in all platforms to integrate external godot modules and build a custom version of godot.
+
+## usage
+1. Install docker on Linux or docker toolbox on Windows or Mac.
+2. Open a terminal on linux or "Docker Quickstart Terminal" on Windows or Mac.
+3. Run command:
+ - Linux: `cd`
+ - Windows: `cd /c/Users/YOUR_USERNAME`
+ - Mac: `cd /Users/YOUR_USERNAME`
+4. Get godot source code: `git clone https://github.com/godotengine/godot.git`
+5. Run command: `cd godot/tools/docker`
+6. Run command: `docker build -t godot .`(In Linux run Docker commands with `sudo` or add your user to docker group before run the Docker commands). The godot docker image will be build after a while.
+7. Run command:
+ - Linux: `docker run -it --name=godot-dev -v /home/YOUR_USERNAME/godot:/godot-dev/godot godot`
+ - Windows: `docker run -it --name=godot-dev -v /c/Users/YOUR_USERNAME/godot:/godot-dev/godot godot`
+ - Mac: `docker run -it --name=godot-dev -v /Users/YOUR_USERNAME/godot:/godot-dev/godot godot`
+ You are in the godot-dev container and /godot-dev directory now.
+8. Run `./install-android-tools` to download and install all android development tools.
+9. Run command: `source ~/.bashrc`
+10. Run command: `cd godot`
+11. Run command: `scons p=android target=release` to test everything is ok. You can set platform to x11, windows, android, haiku and server.
+
+After use and exit, you can use this environment again by open terminal and type commands: `docker start godot-dev && docker attach godot-dev`.
+
+### Windows and Mac stuffs:
+
+- Speed up compilation:
+ - Exit from container.
+ - Run command: `docker-machine stop`
+ - Open "Oracle VM VirtualBox".
+ - In settings of default VM increase CPU cores and RAM to suitable values.
+ - Run command: `docker-machine start`
+ - Run command: `docker start godot-dev && docker attach godot-dev`
+
+- ssh to VM(can be useful sometimes):
+ - `docker-machine ssh`
+
+Check docker and boot2docker projects for more details.
diff --git a/tools/docker/scripts/install-android-tools b/tools/docker/scripts/install-android-tools
new file mode 100644
index 0000000000..8a617d9942
--- /dev/null
+++ b/tools/docker/scripts/install-android-tools
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+BASH_RC=~/.bashrc
+GODOT_BUILD_TOOLS_PATH=/godot-dev/build-tools
+mkdir -p $GODOT_BUILD_TOOLS_PATH
+cd $GODOT_BUILD_TOOLS_PATH
+
+ANDROID_BASE_URL=http://dl.google.com/android
+
+ANDROID_SDK_RELEASE=android-sdk_r24.4.1
+ANDROID_SDK_DIR=android-sdk-linux
+ANDROID_SDK_FILENAME=$ANDROID_SDK_RELEASE-linux.tgz
+ANDROID_SDK_URL=$ANDROID_BASE_URL/$ANDROID_SDK_FILENAME
+ANDROID_SDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_SDK_DIR
+ANDROID_SDK_SHA1=725bb360f0f7d04eaccff5a2d57abdd49061326d
+
+ANDROID_NDK_RELEASE=android-ndk-r10e
+ANDROID_NDK_DIR=$ANDROID_NDK_RELEASE
+ANDROID_NDK_FILENAME=$ANDROID_NDK_RELEASE-linux-x86_64.bin
+ANDROID_NDK_URL=$ANDROID_BASE_URL/ndk/$ANDROID_NDK_FILENAME
+ANDROID_NDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_NDK_DIR
+ANDROID_NDK_MD5=19af543b068bdb7f27787c2bc69aba7f
+
+echo
+echo "Download and install Android development tools ..."
+echo
+
+if [ ! -e $ANDROID_SDK_FILENAME ]; then
+ echo "Downloading: Android SDK ..."
+ wget $ANDROID_SDK_URL
+else
+ echo $ANDROID_SDK_SHA1 $ANDROID_SDK_FILENAME > $ANDROID_SDK_FILENAME.sha1
+ sha1sum --check --strict $ANDROID_SDK_FILENAME.sha1
+ if [ ! $? -eq 0 ]; then
+ echo "Downloading: Android SDK ..."
+ wget $ANDROID_SDK_URL
+ fi
+fi
+
+if [ ! -d $ANDROID_SDK_DIR ]; then
+ tar -xvzf $ANDROID_SDK_FILENAME
+fi
+
+if [ ! -e $ANDROID_NDK_FILENAME ]; then
+ echo "Downloading: Android NDK ..."
+ wget $ANDROID_NDK_URL
+else
+ echo $ANDROID_NDK_MD5 $ANDROID_NDK_FILENAME > $ANDROID_NDK_FILENAME.md5
+ md5sum --check --strict $ANDROID_NDK_FILENAME.md5
+ if [ ! $? -eq 0 ]; then
+ echo "Downloading: Android NDK ..."
+ wget $ANDROID_NDK_URL
+ fi
+fi
+
+if [ ! -d $ANDROID_NDK_DIR ]; then
+ chmod a+x $ANDROID_NDK_FILENAME
+ ./$ANDROID_NDK_FILENAME
+ echo
+fi
+
+cd $ANDROID_SDK_DIR/tools
+chmod a+x android
+
+if ! ./android list target | grep -q 'android-19'; then
+ echo "Installing: Android Tools ..."
+ echo y | ./android update sdk --no-ui --all --filter "platform-tools,android-19,build-tools-19.1.0,\
+ extra-android-m2repository,extra-android-support,extra-google-google_play_services,extra-google-m2repository,\
+ extra-google-play_apk_expansion,extra-google-play_billing,extra-google-play_licensing"
+fi
+
+EXPORT_VAL="export ANDROID_HOME=$ANDROID_SDK_PATH"
+if ! grep -q "^$EXPORT_VAL" $BASH_RC; then
+ echo $EXPORT_VAL >> ~/.bashrc
+fi
+
+
+EXPORT_VAL="export ANDROID_NDK_ROOT=$ANDROID_NDK_PATH"
+if ! grep -q "^$EXPORT_VAL" $BASH_RC; then
+ echo $EXPORT_VAL >> ~/.bashrc
+fi
+
+EXPORT_VAL="export PATH=$PATH:$ANDROID_SDK_PATH/tools"
+if ! grep -q "^export PATH=.*$ANDROID_SDK_PATH/tools.*" $BASH_RC; then
+ echo $EXPORT_VAL >> ~/.bashrc
+fi
+
+echo
+echo "Done!"
+echo \ No newline at end of file
diff --git a/tools/editor/SCsub b/tools/editor/SCsub
index cd46ff8353..34651b36f2 100644
--- a/tools/editor/SCsub
+++ b/tools/editor/SCsub
@@ -26,6 +26,31 @@ def make_doc_header(target,source,env):
+def make_certs_header(target,source,env):
+
+ src = source[0].srcnode().abspath
+ dst = target[0].srcnode().abspath
+ f = open(src,"rb")
+ g = open(dst,"wb")
+ buf = f.read()
+ decomp_size = len(buf)
+ import zlib
+ buf = zlib.compress(buf)
+
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _CERTS_RAW_H\n")
+ g.write("#define _CERTS_RAW_H\n")
+ g.write("static const int _certs_compressed_size="+str(len(buf))+";\n")
+ g.write("static const int _certs_uncompressed_size="+str(decomp_size)+";\n")
+ g.write("static const unsigned char _certs_compressed[]={\n")
+ for i in range(len(buf)):
+ g.write(str(ord(buf[i]))+",\n")
+ g.write("};\n")
+ g.write("#endif")
+
+
+
@@ -47,6 +72,9 @@ if (env["tools"]=="yes"):
env.Depends("#tools/editor/doc_data_compressed.h","#doc/base/classes.xml")
env.Command("#tools/editor/doc_data_compressed.h","#doc/base/classes.xml",make_doc_header)
+ env.Depends("#tools/editor/certs_compressed.h","#tools/certs/ca-certificates.crt")
+ env.Command("#tools/editor/certs_compressed.h","#tools/certs/ca-certificates.crt",make_certs_header)
+
#make_doc_header(env.File("#tools/editor/doc_data_raw.h").srcnode().abspath,env.File("#doc/base/classes.xml").srcnode().abspath,env)
env.add_source_files(env.tool_sources,"*.cpp")
diff --git a/tools/editor/addon_editor_plugin.cpp b/tools/editor/addon_editor_plugin.cpp
new file mode 100644
index 0000000000..4dfb8ff553
--- /dev/null
+++ b/tools/editor/addon_editor_plugin.cpp
@@ -0,0 +1,1273 @@
+#include "addon_editor_plugin.h"
+#include "editor_node.h"
+#include "editor_settings.h"
+
+
+
+
+void EditorAssetLibraryItem::configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost) {
+
+ title->set_text(p_title);
+ asset_id=p_asset_id;
+ category->set_text(p_category);
+ category_id=p_category_id;
+ author->set_text(p_author);
+ author_id=p_author_id;
+ price->set_text(p_cost);
+
+ for(int i=0;i<5;i++) {
+ if (i>2)
+ stars[i]->set_texture(get_icon("RatingNoStar","EditorIcons"));
+ else
+ stars[i]->set_texture(get_icon("RatingStar","EditorIcons"));
+ }
+
+
+}
+
+void EditorAssetLibraryItem::set_image(int p_type,int p_index,const Ref<Texture>& p_image) {
+
+ ERR_FAIL_COND(p_type!=EditorAddonLibrary::IMAGE_QUEUE_ICON);
+ ERR_FAIL_COND(p_index!=0);
+
+ icon->set_normal_texture(p_image);
+}
+
+void EditorAssetLibraryItem::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_ENTER_TREE) {
+
+ icon->set_normal_texture(get_icon("GodotAssetDefault","EditorIcons"));
+ category->add_color_override("font_color", Color(0.5,0.5,0.5) );
+ author->add_color_override("font_color", Color(0.5,0.5,0.5) );
+
+ }
+}
+
+void EditorAssetLibraryItem::_asset_clicked() {
+
+ emit_signal("asset_selected",asset_id);
+}
+
+void EditorAssetLibraryItem::_category_clicked(){
+
+ emit_signal("category_selected",category_id);
+}
+void EditorAssetLibraryItem::_author_clicked(){
+
+ emit_signal("author_selected",author_id);
+
+}
+
+void EditorAssetLibraryItem::_bind_methods() {
+
+ ObjectTypeDB::bind_method("set_image",&EditorAssetLibraryItem::set_image);
+ ObjectTypeDB::bind_method("_asset_clicked",&EditorAssetLibraryItem::_asset_clicked);
+ ObjectTypeDB::bind_method("_category_clicked",&EditorAssetLibraryItem::_category_clicked);
+ ObjectTypeDB::bind_method("_author_clicked",&EditorAssetLibraryItem::_author_clicked);
+ ADD_SIGNAL( MethodInfo("asset_selected"));
+ ADD_SIGNAL( MethodInfo("category_selected"));
+ ADD_SIGNAL( MethodInfo("author_selected"));
+
+
+}
+
+EditorAssetLibraryItem::EditorAssetLibraryItem() {
+
+ Ref<StyleBoxEmpty> border;
+ border.instance();
+ /*border->set_default_margin(MARGIN_LEFT,5);
+ border->set_default_margin(MARGIN_RIGHT,5);
+ border->set_default_margin(MARGIN_BOTTOM,5);
+ border->set_default_margin(MARGIN_TOP,5);*/
+ add_style_override("panel",border);
+
+ HBoxContainer *hb = memnew( HBoxContainer );
+ add_child(hb);
+
+ icon = memnew( TextureButton );
+ icon->set_default_cursor_shape(CURSOR_POINTING_HAND);
+ icon->connect("pressed",this,"_asset_clicked");
+
+ hb->add_child(icon);
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+
+ hb->add_child(vb);
+ vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ title = memnew( LinkButton );
+ title->set_text("My Awesome Addon");
+ title->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ title->connect("pressed",this,"_asset_clicked");
+ vb->add_child(title);
+
+
+ category = memnew( LinkButton );
+ category->set_text("Editor Tools");
+ category->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ title->connect("pressed",this,"_category_clicked");
+ vb->add_child(category);
+
+ author = memnew( LinkButton );
+ author->set_text("Johny Tolengo");
+ author->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ title->connect("pressed",this,"_author_clicked");
+ vb->add_child(author);
+
+ HBoxContainer *rating_hb = memnew( HBoxContainer );
+ vb->add_child(rating_hb);
+
+ for(int i=0;i<5;i++) {
+ stars[i]=memnew(TextureFrame);
+ rating_hb->add_child(stars[i]);
+ }
+ price = memnew( Label );
+ price->set_text("Free");
+ vb->add_child(price);
+
+ set_custom_minimum_size(Size2(250,100));
+ set_h_size_flags(SIZE_EXPAND_FILL);
+
+ set_stop_mouse(false);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const Ref<Texture>& p_image) {
+
+ switch(p_type) {
+
+ case EditorAddonLibrary::IMAGE_QUEUE_ICON: {
+
+ item->call("set_image",p_type,p_index,p_image);
+ icon=p_image;
+ } break;
+ case EditorAddonLibrary::IMAGE_QUEUE_THUMBNAIL: {
+
+ for(int i=0;i<preview_images.size();i++) {
+ if (preview_images[i].id==p_index) {
+ preview_images[i].button->set_icon(p_image);
+ }
+ }
+ //item->call("set_image",p_type,p_index,p_image);
+ } break;
+ case EditorAddonLibrary::IMAGE_QUEUE_SCREENSHOT: {
+
+ for(int i=0;i<preview_images.size();i++) {
+ if (preview_images[i].id==p_index && preview_images[i].button->is_pressed()) {
+ preview->set_texture(p_image);
+ }
+ }
+ //item->call("set_image",p_type,p_index,p_image);
+ } break;
+ }
+}
+
+void EditorAddonLibraryItemDescription::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("set_image"),&EditorAddonLibraryItemDescription::set_image);
+ ObjectTypeDB::bind_method(_MD("_link_click"),&EditorAddonLibraryItemDescription::_link_click);
+
+}
+
+void EditorAddonLibraryItemDescription::_link_click(const String& p_url) {
+
+ ERR_FAIL_COND(!p_url.begins_with("http"));
+ OS::get_singleton()->shell_open(p_url);
+}
+
+void EditorAddonLibraryItemDescription::configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_version,const String& p_description,const String& p_download_url,const String& p_browse_url) {
+
+ asset_id=p_asset_id;
+ title=p_title;
+ download_url=p_download_url;
+ item->configure(p_title,p_asset_id,p_category,p_category_id,p_author,p_author_id,p_rating,p_cost);
+ description->clear();
+ description->add_text("Version: "+p_version+"\n");
+ description->add_text("Contents: ");
+ description->push_meta(p_browse_url);
+ description->add_text("View Files");
+ description->pop();
+ description->add_text("\nDescription:\n\n");
+ description->append_bbcode(p_description);
+ set_title(p_title);
+}
+
+void EditorAddonLibraryItemDescription::add_preview(int p_id, bool p_video,const String& p_url){
+
+ Preview preview;
+ preview.id=p_id;
+ preview.video_link=p_url;
+ preview.button = memnew( Button );
+ preview.button->set_flat(true);
+ preview.button->set_icon(get_icon("ThumbnailWait","EditorIcons"));
+ preview.button->set_toggle_mode(true);
+ preview_hb->add_child(preview.button);
+ if (preview_images.size()==0)
+ preview.button->set_pressed(true);
+ preview_images.push_back(preview);
+}
+
+EditorAddonLibraryItemDescription::EditorAddonLibraryItemDescription() {
+
+ VBoxContainer *vbox = memnew( VBoxContainer );
+ add_child(vbox);
+ set_child_rect(vbox);
+
+
+ HBoxContainer *hbox = memnew( HBoxContainer);
+ vbox->add_child(hbox);
+ vbox->add_constant_override("separation",15);
+ VBoxContainer *desc_vbox = memnew( VBoxContainer );
+ hbox->add_child(desc_vbox);
+ hbox->add_constant_override("separation",15);
+
+ item = memnew( EditorAssetLibraryItem );
+
+ desc_vbox->add_child(item);
+ desc_vbox->set_custom_minimum_size(Size2(300,0));
+
+
+ PanelContainer * desc_bg = memnew( PanelContainer );
+ desc_vbox->add_child(desc_bg);
+ desc_bg->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ description = memnew( RichTextLabel );
+ description->connect("meta_clicked",this,"_link_click");
+ //desc_vbox->add_child(description);
+ desc_bg->add_child(description);
+ desc_bg->add_style_override("panel",get_stylebox("normal","TextEdit"));
+
+ preview = memnew( TextureFrame );
+ preview->set_custom_minimum_size(Size2(640,345));
+ hbox->add_child(preview);
+
+ PanelContainer * previews_bg = memnew( PanelContainer );
+ vbox->add_child(previews_bg);
+ previews_bg->set_custom_minimum_size(Size2(0,85));
+ previews_bg->add_style_override("panel",get_stylebox("normal","TextEdit"));
+
+ previews = memnew( ScrollContainer );
+ previews_bg->add_child(previews);
+ previews->set_enable_v_scroll(false);
+ previews->set_enable_h_scroll(true);
+ preview_hb = memnew( HBoxContainer );
+ preview_hb->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ previews->add_child(preview_hb);
+ get_ok()->set_text("Install");
+ get_cancel()->set_text("Close");
+
+
+
+}
+///////////////////////////////////////////////////////////////////////////////////
+
+void EditorAddonLibraryItemDownload::_http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data) {
+
+
+ String error_text;
+
+ switch(p_status) {
+
+ case HTTPRequest::RESULT_CANT_RESOLVE: {
+ error_text=("Can't resolve hostname: "+host);
+ status->set_text("Can't resolve.");
+ } break;
+ case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED:
+ case HTTPRequest::RESULT_CONNECTION_ERROR:
+ case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: {
+ error_text=("Connection error, please try again.");
+ status->set_text("Can't connect.");
+ } break;
+ case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
+ case HTTPRequest::RESULT_CANT_CONNECT: {
+ error_text=("Can't connect to host: "+host);
+ status->set_text("Can't connect.");
+ } break;
+ case HTTPRequest::RESULT_NO_RESPONSE: {
+ error_text=("No response from host: "+host);
+ status->set_text("No response.");
+ } break;
+ case HTTPRequest::RESULT_REQUEST_FAILED: {
+ error_text=("Request failed, return code: "+itos(p_code));
+ status->set_text("Req. Failed.");
+ } break;
+ case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
+ error_text=("Request failed, too many redirects");
+ status->set_text("Redirect Loop.");
+ } break;
+ default: {
+ if (p_code!=200) {
+ error_text=("Request failed, return code: "+itos(p_code));
+ status->set_text("Failed: "+itos(p_code));
+ } else {
+
+ //all good
+ }
+ } break;
+
+ }
+
+ if (error_text!=String()) {
+ download_error->set_text("Asset Download Error:\n"+error_text);
+ download_error->popup_centered_minsize();
+ return;
+
+ }
+
+ progress->set_max( download->get_body_size() );
+ progress->set_val(download->get_downloaded_bytes());
+
+ print_line("max: "+itos(download->get_body_size())+" bytes: "+itos(download->get_downloaded_bytes()));
+ install->set_disabled(false);
+
+ status->set_text("Success!");
+ set_process(false);
+}
+
+
+void EditorAddonLibraryItemDownload::configure(const String& p_title,int p_asset_id,const Ref<Texture>& p_preview, const String& p_download_url) {
+
+ title->set_text(p_title);
+ icon->set_texture(p_preview);
+ asset_id=p_asset_id;
+ if (!p_preview.is_valid())
+ icon->set_texture(get_icon("GodotAssetDefault","EditorIcons"));
+
+ host=p_download_url;
+ set_process(true);
+ download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_"+itos(p_asset_id))+".zip");
+ Error err = download->request(p_download_url);
+ ERR_FAIL_COND(err!=OK);
+ asset_installer->connect("confirmed",this,"_close");
+ dismiss->set_normal_texture(get_icon("Close","EditorIcons"));
+
+
+}
+
+
+void EditorAddonLibraryItemDownload::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_PROCESS) {
+
+ progress->set_max( download->get_body_size() );
+ progress->set_val(download->get_downloaded_bytes());
+
+ int cstatus = download->get_http_client_status();
+ if (cstatus!=prev_status) {
+ switch(cstatus) {
+
+ case HTTPClient::STATUS_RESOLVING: {
+ status->set_text("Resolving..");
+ } break;
+ case HTTPClient::STATUS_CONNECTING: {
+ status->set_text("Connecting..");
+ } break;
+ case HTTPClient::STATUS_REQUESTING: {
+ status->set_text("Requesting..");
+ } break;
+ case HTTPClient::STATUS_BODY: {
+ status->set_text("Downloading..");
+ } break;
+ default: {}
+ }
+ prev_status=cstatus;
+ }
+
+ }
+}
+void EditorAddonLibraryItemDownload::_close() {
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ da->remove(download->get_download_file()); //clean up removed file
+ memdelete(da);
+ queue_delete();
+}
+
+void EditorAddonLibraryItemDownload::_install() {
+
+ String file = download->get_download_file();
+ asset_installer->open(file,1);
+}
+
+void EditorAddonLibraryItemDownload::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_http_download_completed",&EditorAddonLibraryItemDownload::_http_download_completed);
+ ObjectTypeDB::bind_method("_install",&EditorAddonLibraryItemDownload::_install);
+ ObjectTypeDB::bind_method("_close",&EditorAddonLibraryItemDownload::_close);
+
+}
+
+EditorAddonLibraryItemDownload::EditorAddonLibraryItemDownload() {
+
+ HBoxContainer *hb = memnew( HBoxContainer);
+ add_child(hb);
+ icon = memnew( TextureFrame );
+ hb->add_child(icon);
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+ hb->add_child(vb);
+ vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ HBoxContainer *title_hb = memnew( HBoxContainer);
+ vb->add_child(title_hb);
+ title = memnew( Label );
+ title_hb->add_child(title);
+ title->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ dismiss = memnew( TextureButton );
+ dismiss->connect("pressed",this,"_close");
+ title_hb->add_child(dismiss);
+
+ title->set_clip_text(true);
+
+ vb->add_spacer();
+
+ status = memnew (Label("Idle"));
+ vb->add_child(status);
+ status->add_color_override("font_color", Color(0.5,0.5,0.5) );
+ progress = memnew( ProgressBar );
+ vb->add_child(progress);
+
+
+
+ HBoxContainer *hb2 = memnew( HBoxContainer );
+ vb->add_child(hb2);
+ hb2->add_spacer();
+
+ install = memnew( Button );
+ install->set_text("Install");
+ install->set_disabled(true);
+ install->connect("pressed",this,"_install");
+
+ hb2->add_child(install);
+ set_custom_minimum_size(Size2(250,0));
+
+ download = memnew( HTTPRequest );
+ add_child(download);
+ download->connect("request_completed",this,"_http_download_completed");
+
+ download_error = memnew( AcceptDialog );
+ add_child(download_error);
+ download_error->set_title("Download Error");
+
+ asset_installer = memnew( EditorAssetInstaller );
+ add_child(asset_installer);
+
+ prev_status=-1;
+
+
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+void EditorAddonLibrary::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_READY) {
+ TextureFrame *tf = memnew(TextureFrame);
+ tf->set_texture(get_icon("Error","EditorIcons"));
+ error_hb->add_child(tf);
+ error_label->raise();
+
+ _api_request("api/configure");
+ }
+
+ if (p_what==NOTIFICATION_PROCESS) {
+
+ HTTPClient::Status s = request->get_http_client_status();
+ bool visible = s!=HTTPClient::STATUS_DISCONNECTED;
+
+ if (visible != !load_status->is_hidden()) {
+ load_status->set_hidden(!visible);
+ }
+
+ if (visible) {
+ switch(s) {
+
+ case HTTPClient::STATUS_RESOLVING: {
+ load_status->set_val(0.1);
+ } break;
+ case HTTPClient::STATUS_CONNECTING: {
+ load_status->set_val(0.2);
+ } break;
+ case HTTPClient::STATUS_REQUESTING: {
+ load_status->set_val(0.3);
+ } break;
+ case HTTPClient::STATUS_BODY: {
+ load_status->set_val(0.4);
+ } break;
+ default: {}
+
+ }
+ }
+
+ bool no_downloads = downloads_hb->get_child_count()==0;
+ if (no_downloads != downloads_scroll->is_hidden()) {
+ downloads_scroll->set_hidden(no_downloads);
+ }
+ }
+
+}
+
+
+void EditorAddonLibrary::_install_asset() {
+
+ ERR_FAIL_COND(!description);
+
+ for(int i=0;i<downloads_hb->get_child_count();i++) {
+
+ EditorAddonLibraryItemDownload *d = downloads_hb->get_child(i)->cast_to<EditorAddonLibraryItemDownload>();
+ if (d && d->get_asset_id() == description->get_asset_id()) {
+
+ EditorNode::get_singleton()->show_warning("Download for this asset is already in progress!");
+ return;
+ }
+ }
+
+
+ EditorAddonLibraryItemDownload * download = memnew( EditorAddonLibraryItemDownload );
+ downloads_hb->add_child(download);
+ download->configure(description->get_title(),description->get_asset_id(),description->get_preview_icon(),description->get_download_url());
+
+}
+
+const char* EditorAddonLibrary::sort_key[SORT_MAX]={
+ "rating",
+ "downloads",
+ "name",
+ "cost",
+ "updated"
+};
+
+const char* EditorAddonLibrary::sort_text[SORT_MAX]={
+ "Rating",
+ "Downloads",
+ "Name",
+ "Cost",
+ "Updated"
+};
+
+
+void EditorAddonLibrary::_select_author(int p_id) {
+
+ //opemn author window
+}
+
+void EditorAddonLibrary::_select_category(int p_id){
+
+ for(int i=0;i<categories->get_item_count();i++) {
+
+ if (i==0)
+ continue;
+ int id = categories->get_item_metadata(i);
+ if (id==p_id) {
+ categories->select(i);
+ _search();
+ break;
+ }
+ }
+}
+void EditorAddonLibrary::_select_asset(int p_id){
+
+ _api_request("api/asset","?id="+itos(p_id));
+
+ /*
+ if (description) {
+ memdelete(description);
+ }
+
+
+ description = memnew( EditorAddonLibraryItemDescription );
+ add_child(description);
+ description->popup_centered_minsize();*/
+}
+
+
+
+void EditorAddonLibrary::_image_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data,int p_queue_id) {
+
+ ERR_FAIL_COND( !image_queue.has(p_queue_id) );
+
+ if (p_status==HTTPRequest::RESULT_SUCCESS) {
+
+
+ print_line("GOT IMAGE YAY!");
+ Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);
+
+ if (obj) {
+ int len=p_data.size();
+ ByteArray::Read r=p_data.read();
+
+ Image image(r.ptr(),len);
+ if (!image.empty()) {
+ Ref<ImageTexture> tex;
+ tex.instance();
+ tex->create_from_image(image);
+
+ obj->call("set_image",image_queue[p_queue_id].image_type,image_queue[p_queue_id].image_index,tex);
+ }
+ }
+ } else {
+ WARN_PRINTS("Error getting PNG file for asset id "+itos(image_queue[p_queue_id].asset_id));
+ }
+
+ image_queue[p_queue_id].request->queue_delete();;
+ image_queue.erase(p_queue_id);
+
+ _update_image_queue();
+
+}
+
+void EditorAddonLibrary::_update_image_queue() {
+
+ int max_images=2;
+ int current_images=0;
+
+ List<int> to_delete;
+ for (Map<int,ImageQueue>::Element *E=image_queue.front();E;E=E->next()) {
+ if (!E->get().active && current_images<max_images) {
+
+ String api;
+ switch(E->get().image_type) {
+ case IMAGE_QUEUE_ICON: api="api/icon/icon.png"; break;
+ case IMAGE_QUEUE_SCREENSHOT: api="api/screenshot/screenshot.png"; break;
+ case IMAGE_QUEUE_THUMBNAIL: api="api/thumbnail/thumbnail.png"; break;
+ }
+
+ print_line("REQUEST ICON FOR: "+itos(E->get().asset_id));
+ Error err = E->get().request->request(host+"/"+api+"?asset_id="+itos(E->get().asset_id)+"&index="+itos(E->get().image_index));
+ if (err!=OK) {
+ to_delete.push_back(E->key());
+ } else {
+ E->get().active=true;
+ }
+ current_images++;
+ } else if (E->get().active) {
+ current_images++;
+ }
+ }
+
+ while(to_delete.size()) {
+ image_queue[to_delete.front()->get()].request->queue_delete();
+ image_queue.erase(to_delete.front()->get());
+ to_delete.pop_front();
+ }
+}
+
+void EditorAddonLibrary::_request_image(ObjectID p_for,int p_asset_id,ImageType p_type,int p_image_index) {
+
+
+ ImageQueue iq;
+ iq.asset_id=p_asset_id;
+ iq.image_index=p_image_index;
+ iq.image_type=p_type;
+ iq.request = memnew( HTTPRequest );
+
+ iq.target=p_for;
+ iq.queue_id=++last_queue_id;
+ iq.active=false;
+
+ iq.request->connect("request_completed",this,"_image_request_completed",varray(iq.queue_id));
+
+ image_queue[iq.queue_id]=iq;
+
+ add_child(iq.request);
+
+ _update_image_queue();
+
+
+}
+
+
+void EditorAddonLibrary::_search(int p_page) {
+
+ String args;
+
+ args=String()+"?sort="+sort_key[sort->get_selected()];
+
+ if (categories->get_selected()>0) {
+
+ args+="&category="+itos(categories->get_item_metadata(categories->get_selected()));
+ }
+
+ if (filter->get_text()!=String()) {
+ args+="&filter="+filter->get_text().http_escape();
+ }
+
+ if (p_page>0) {
+ args+="&page="+itos(p_page);
+ }
+
+ _api_request("api/search",args);
+}
+
+HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_page_len,int p_total_items,int p_current_items) {
+
+ HBoxContainer * hbc = memnew( HBoxContainer );
+
+ //do the mario
+ int from = p_page-5;
+ if (from<0)
+ from=0;
+ int to = from+10;
+ if (to>p_max_page)
+ to=p_max_page;
+
+ Color gray = Color(0.65,0.65,0.65);
+
+ hbc->add_spacer();
+ hbc->add_constant_override("separation",10);
+
+ LinkButton *first = memnew( LinkButton );
+ first->set_text("first");
+ first->add_color_override("font_color", gray );
+ first->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ first->connect("pressed",this,"_search",varray(0));
+ hbc->add_child(first);
+
+ if (p_page>0) {
+ LinkButton *prev = memnew( LinkButton );
+ prev->set_text("prev");
+ prev->add_color_override("font_color", gray );
+ prev->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ prev->connect("pressed",this,"_search",varray(p_page-1));
+ hbc->add_child(prev);
+ }
+
+ for(int i=from;i<=to;i++) {
+
+ if (i==p_page) {
+
+ Label *current = memnew(Label);
+ current->set_text(itos(i));
+ hbc->add_child(current);
+ } else {
+
+ LinkButton *current = memnew( LinkButton );
+ current->add_color_override("font_color", gray );
+ current->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ current->set_text(itos(i));
+ current->connect("pressed",this,"_search",varray(i));
+
+ hbc->add_child(current);
+
+ }
+ }
+
+ if (p_page<p_max_page) {
+ LinkButton *next = memnew( LinkButton );
+ next->set_text("next");
+ next->add_color_override("font_color", gray );
+ next->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ next->connect("pressed",this,"_search",varray(p_page+1));
+
+ hbc->add_child(next);
+ }
+ LinkButton *last = memnew( LinkButton );
+ last->set_text("last");
+ last->add_color_override("font_color", gray );
+ last->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ hbc->add_child(last);
+ last->connect("pressed",this,"_search",varray(p_max_page));
+
+ Label *totals = memnew( Label );
+ totals->set_text("( "+itos(from*p_page_len)+" - "+itos(from*p_page_len+p_current_items-1)+" / "+itos(p_total_items)+" )");
+ hbc->add_child(totals);
+
+ hbc->add_spacer();
+
+ return hbc;
+}
+
+
+void EditorAddonLibrary::_api_request(const String& p_request,const String& p_arguments) {
+
+ if (requesting!=REQUESTING_NONE) {
+ request->cancel_request();
+ }
+
+ error_hb->hide();
+ current_request=p_request;
+ request->request(host+"/"+p_request+p_arguments);
+}
+
+
+
+void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data) {
+
+
+ String str;
+
+ {
+ int datalen=p_data.size();
+ ByteArray::Read r = p_data.read();
+ str.parse_utf8((const char*)r.ptr(),datalen);
+ }
+
+ bool error_abort=true;
+
+ switch(p_status) {
+
+ case HTTPRequest::RESULT_CANT_RESOLVE: {
+ error_label->set_text("Can't resolve hostname: "+host);
+ } break;
+ case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED:
+ case HTTPRequest::RESULT_CONNECTION_ERROR:
+ case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: {
+ error_label->set_text("Connection error, please try again.");
+ } break;
+ case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
+ case HTTPRequest::RESULT_CANT_CONNECT: {
+ error_label->set_text("Can't connect to host: "+host);
+ } break;
+ case HTTPRequest::RESULT_NO_RESPONSE: {
+ error_label->set_text("No response from host: "+host);
+ } break;
+ case HTTPRequest::RESULT_REQUEST_FAILED: {
+ error_label->set_text("Request failed, return code: "+itos(p_code));
+ } break;
+ case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
+ error_label->set_text("Request failed, too many redirects");
+
+ } break;
+ default: {
+ if (p_code!=200) {
+ error_label->set_text("Request failed, return code: "+itos(p_code));
+ } else {
+
+ error_abort=false;
+ }
+ } break;
+
+ }
+
+
+ if (error_abort) {
+ error_hb->show();
+ return;
+ }
+
+ print_line("response: "+itos(p_status)+" code: "+itos(p_code));
+ Dictionary d;
+ d.parse_json(str);
+
+ print_line(Variant(d).get_construct_string());
+
+ if (current_request=="api/configure") {
+
+ categories->clear();
+ categories->add_item("All");
+ categories->set_item_metadata(0,0);
+ if (d.has("categories")) {
+ Array clist = d["categories"];
+ for(int i=0;i<clist.size();i++) {
+ Dictionary cat = clist[i];
+ if (!cat.has("name") || !cat.has("id"))
+ continue;
+ String name=cat["name"];
+ int id=cat["id"];
+ categories->add_item(name);
+ categories->set_item_metadata( categories->get_item_count() -1, id);
+ }
+ }
+
+ _search();
+ } else if (current_request=="api/search") {
+
+ if (asset_items) {
+ memdelete(asset_items);
+ }
+
+ if (asset_top_page) {
+ memdelete(asset_top_page);
+ }
+
+ if (asset_bottom_page) {
+ memdelete(asset_bottom_page);
+ }
+
+ int page=0;
+ int pages=1;
+ int page_len=10;
+ int total_items=1;
+ Array result;
+
+
+ if (d.has("page")) {
+ page=d["page"];
+ }
+ if (d.has("pages")) {
+ pages=d["pages"];
+ }
+ if (d.has("page_length")) {
+ page_len=d["page_length"];
+ }
+ if (d.has("total")) {
+ total_items=d["total"];
+ }
+ if (d.has("result")) {
+ result=d["result"];
+ }
+
+ asset_top_page = _make_pages(page,pages,page_len,total_items,result.size());
+ library_vb->add_child(asset_top_page);
+
+ asset_items = memnew( GridContainer );
+ asset_items->set_columns(2);
+ asset_items->add_constant_override("hseparation",10);
+ asset_items->add_constant_override("vseparation",10);
+
+ library_vb->add_child(asset_items);
+
+ asset_bottom_page = _make_pages(page,pages,page_len,total_items,result.size());
+ library_vb->add_child(asset_bottom_page);
+
+ for(int i=0;i<result.size();i++) {
+
+ Dictionary r = result[i];
+
+ ERR_CONTINUE(!r.has("title"));
+ ERR_CONTINUE(!r.has("asset_id"));
+ ERR_CONTINUE(!r.has("author"));
+ ERR_CONTINUE(!r.has("author_id"));
+ ERR_CONTINUE(!r.has("category"));
+ ERR_CONTINUE(!r.has("category_id"));
+ ERR_CONTINUE(!r.has("rating"));
+ ERR_CONTINUE(!r.has("cost"));
+
+
+ EditorAssetLibraryItem *item = memnew( EditorAssetLibraryItem );
+ asset_items->add_child(item);
+ item->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"]);
+ item->connect("asset_selected",this,"_select_asset");
+ item->connect("author_selected",this,"_select_author");
+ item->connect("category_selected",this,"_category_selected");
+
+ _request_image(item->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_ICON,0);
+ }
+ } else if (current_request=="api/asset") {
+
+ ERR_FAIL_COND(!d.has("info"));
+
+ Dictionary r = d["info"];
+
+ r["download_url"]="https://github.com/reduz/godot-test-addon/archive/master.zip";
+ r["browse_url"]="https://github.com/reduz/godot-test-addon";
+ r["version"]="1.1";
+
+ ERR_FAIL_COND(!r.has("title"));
+ ERR_FAIL_COND(!r.has("asset_id"));
+ ERR_FAIL_COND(!r.has("author"));
+ ERR_FAIL_COND(!r.has("author_id"));
+ ERR_FAIL_COND(!r.has("version"));
+ ERR_FAIL_COND(!r.has("category"));
+ ERR_FAIL_COND(!r.has("category_id"));
+ ERR_FAIL_COND(!r.has("rating"));
+ ERR_FAIL_COND(!r.has("cost"));
+ ERR_FAIL_COND(!r.has("description"));
+ ERR_FAIL_COND(!r.has("download_url"));
+ ERR_FAIL_COND(!r.has("browse_url"));
+
+
+ if (description) {
+ memdelete(description);
+ }
+
+ description = memnew( EditorAddonLibraryItemDescription );
+ add_child(description);
+ description->popup_centered_minsize();
+ description->connect("confirmed",this,"_install_asset");
+
+ description->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"],r["version"],r["description"],r["download_url"],r["browse_url"]);
+ /*item->connect("asset_selected",this,"_select_asset");
+ item->connect("author_selected",this,"_select_author");
+ item->connect("category_selected",this,"_category_selected");*/
+
+ _request_image(description->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_ICON,0);
+
+ if (d.has("previews")) {
+ Array previews = d["previews"];
+
+ for(int i=0;i<previews.size();i++) {
+
+
+ Dictionary p=previews[i];
+
+ ERR_CONTINUE(!p.has("id"));
+
+ bool is_video=p.has("type") && String(p["type"])=="video";
+ String video_url;
+ if (is_video && p.has("link")) {
+ video_url="link";
+ }
+
+ int id=p["id"];
+
+ description->add_preview(id,is_video,video_url);
+
+ _request_image(description->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_THUMBNAIL,id);
+ if (i==0) {
+ _request_image(description->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_SCREENSHOT,id);
+ }
+
+ }
+ }
+ }
+
+}
+
+
+void EditorAddonLibrary::_asset_file_selected(const String& p_file) {
+
+ if (asset_installer) {
+ memdelete( asset_installer );
+ asset_installer=NULL;
+ }
+
+ asset_installer = memnew( EditorAssetInstaller );
+ add_child(asset_installer);
+ asset_installer->open(p_file);
+
+
+}
+
+void EditorAddonLibrary::_asset_open() {
+
+ asset_open->popup_centered_ratio();
+}
+
+void EditorAddonLibrary::_manage_plugins() {
+
+ ProjectSettings::get_singleton()->popup_project_settings();
+ ProjectSettings::get_singleton()->set_plugins_page();
+}
+
+
+
+void EditorAddonLibrary::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_http_request_completed",&EditorAddonLibrary::_http_request_completed);
+ ObjectTypeDB::bind_method("_select_asset",&EditorAddonLibrary::_select_asset);
+ ObjectTypeDB::bind_method("_select_author",&EditorAddonLibrary::_select_author);
+ ObjectTypeDB::bind_method("_select_category",&EditorAddonLibrary::_select_category);
+ ObjectTypeDB::bind_method("_image_request_completed",&EditorAddonLibrary::_image_request_completed);
+ ObjectTypeDB::bind_method("_search",&EditorAddonLibrary::_search,DEFVAL(0));
+ ObjectTypeDB::bind_method("_install_asset",&EditorAddonLibrary::_install_asset);
+ ObjectTypeDB::bind_method("_manage_plugins",&EditorAddonLibrary::_manage_plugins);
+ ObjectTypeDB::bind_method("_asset_open",&EditorAddonLibrary::_asset_open);
+ ObjectTypeDB::bind_method("_asset_file_selected",&EditorAddonLibrary::_asset_file_selected);
+
+}
+
+EditorAddonLibrary::EditorAddonLibrary() {
+
+
+ Ref<StyleBoxEmpty> border;
+ border.instance();
+ border->set_default_margin(MARGIN_LEFT,15);
+ border->set_default_margin(MARGIN_RIGHT,15);
+ border->set_default_margin(MARGIN_BOTTOM,5);
+ border->set_default_margin(MARGIN_TOP,5);
+
+ add_style_override("panel",border);
+
+ VBoxContainer *library_main = memnew( VBoxContainer );
+
+ add_child(library_main);
+
+ HBoxContainer *search_hb = memnew( HBoxContainer );
+
+ library_main->add_child(search_hb);
+ library_main->add_constant_override("separation",10);
+
+
+
+ search_hb->add_child( memnew( Label("Search: ")));
+ filter =memnew( LineEdit );
+ search_hb->add_child(filter);
+ filter->set_h_size_flags(SIZE_EXPAND_FILL);
+ filter->connect("text_entered",this,"_search");
+ search = memnew( Button("Search"));
+ search->connect("pressed",this,"_search");
+ search_hb->add_child(search);
+
+ search_hb->add_child(memnew( VSeparator ));
+
+ Button * open_asset = memnew( Button );
+ open_asset->set_text("Import");
+ search_hb->add_child(open_asset);
+ open_asset->connect("pressed",this,"_asset_open");
+
+ Button * plugins = memnew( Button );
+ plugins->set_text("Plugins");
+ search_hb->add_child(plugins);
+ plugins->connect("pressed",this,"_manage_plugins");
+
+
+ library_vb->add_child(search_hb);
+
+ HBoxContainer *search_hb2 = memnew( HBoxContainer );
+ library_main->add_child(search_hb2);
+
+ search_hb2->add_child( memnew( Label("Sort: ")));
+ sort = memnew( OptionButton );
+ for(int i=0;i<SORT_MAX;i++) {
+ sort->add_item(sort_text[i]);
+ }
+
+ search_hb2->add_child(sort);
+
+ sort->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ reverse = memnew( CheckBox);
+ reverse->set_text("Reverse");
+ search_hb2->add_child(reverse);
+
+ search_hb2->add_child(memnew(VSeparator));
+
+ //search_hb2->add_spacer();
+
+ search_hb2->add_child( memnew( Label("Category: ")));
+ categories = memnew( OptionButton );
+ categories->add_item("All");
+ search_hb2->add_child(categories);
+ categories->set_h_size_flags(SIZE_EXPAND_FILL);
+ //search_hb2->add_spacer();
+
+ search_hb2->add_child(memnew(VSeparator));
+
+ search_hb2->add_child( memnew( Label("Site: ")));
+ repository = memnew( OptionButton );
+
+ repository->add_item("Godot");
+ search_hb2->add_child(repository);
+ repository->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ /////////
+
+ PanelContainer * library_scroll_bg = memnew( PanelContainer );
+ library_main->add_child(library_scroll_bg);
+ library_scroll_bg->add_style_override("panel",get_stylebox("normal","TextEdit"));
+ library_scroll_bg->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ library_scroll = memnew( ScrollContainer );
+ library_scroll->set_enable_v_scroll(true);
+ library_scroll->set_enable_h_scroll(false);
+
+ library_scroll_bg->add_child(library_scroll);
+
+
+ Ref<StyleBoxEmpty> border2;
+ border2.instance();
+ border2->set_default_margin(MARGIN_LEFT,15);
+ border2->set_default_margin(MARGIN_RIGHT,35);
+ border2->set_default_margin(MARGIN_BOTTOM,15);
+ border2->set_default_margin(MARGIN_TOP,15);
+
+
+ PanelContainer * library_vb_border = memnew( PanelContainer );
+ library_scroll->add_child(library_vb_border);
+ library_vb_border->add_style_override("panel",border2);
+ library_vb_border->set_h_size_flags(SIZE_EXPAND_FILL);
+ library_vb_border->set_stop_mouse(false);
+
+
+
+ library_vb = memnew( VBoxContainer );
+ library_vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ library_vb_border->add_child(library_vb);
+// margin_panel->set_stop_mouse(false);
+
+ asset_top_page = memnew( HBoxContainer );
+ library_vb->add_child(asset_top_page);
+
+ asset_items = memnew( GridContainer );
+ asset_items->set_columns(2);
+ asset_items->add_constant_override("hseparation",10);
+ asset_items->add_constant_override("vseparation",10);
+
+ library_vb->add_child(asset_items);
+
+ asset_bottom_page = memnew( HBoxContainer );
+ library_vb->add_child(asset_bottom_page);
+
+ request = memnew( HTTPRequest );
+ add_child(request);
+ request->connect("request_completed",this,"_http_request_completed");
+
+
+ last_queue_id=0;
+
+ library_vb->add_constant_override("separation",20);
+
+ load_status = memnew( ProgressBar );
+ load_status->set_min(0);
+ load_status->set_max(1);
+ load_status->set_step(0.001);
+ library_main->add_child(load_status);
+
+ error_hb = memnew( HBoxContainer );
+ library_main->add_child(error_hb);
+ error_label = memnew( Label );
+ error_label->add_color_override("color",Color(1,0.4,0.3));
+ error_hb->add_child(error_label);
+
+ description = NULL;
+
+ //host="http://localhost:8000";
+ host="http://godotengine.org/addonlib";
+ set_process(true);
+
+ downloads_scroll = memnew( ScrollContainer );
+ downloads_scroll->set_enable_h_scroll(true);
+ downloads_scroll->set_enable_v_scroll(false);
+ library_main->add_child(downloads_scroll);
+ downloads_hb = memnew( HBoxContainer );
+ downloads_scroll->add_child(downloads_hb);
+
+ asset_open = memnew( EditorFileDialog );
+
+ asset_open->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ asset_open->add_filter("*.zip ; Assets ZIP File");
+ asset_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
+ add_child(asset_open);
+ asset_open->connect("file_selected",this,"_asset_file_selected");
+
+ asset_installer=NULL;
+
+}
+
+
+///////
+
+
+void AddonEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+
+ addon_library->show();
+ } else {
+
+ addon_library->hide();
+ }
+
+}
+
+AddonEditorPlugin::AddonEditorPlugin(EditorNode *p_node) {
+
+ editor=p_node;
+ addon_library = memnew( EditorAddonLibrary );
+ addon_library->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ editor->get_viewport()->add_child(addon_library);
+ addon_library->set_area_as_parent_rect();
+ addon_library->hide();
+
+}
+
+AddonEditorPlugin::~AddonEditorPlugin() {
+
+}
diff --git a/tools/editor/addon_editor_plugin.h b/tools/editor/addon_editor_plugin.h
new file mode 100644
index 0000000000..9cd604a319
--- /dev/null
+++ b/tools/editor/addon_editor_plugin.h
@@ -0,0 +1,286 @@
+#ifndef ADDON_EDITOR_PLUGIN_H
+#define ADDON_EDITOR_PLUGIN_H
+
+
+#include "editor_plugin.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/line_edit.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/tab_container.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/link_button.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/progress_bar.h"
+#include "scene/gui/separator.h"
+
+#include "scene/gui/grid_container.h"
+#include "scene/gui/scroll_container.h"
+#include "scene/gui/texture_button.h"
+#include "scene/gui/rich_text_label.h"
+#include "editor_plugin_settings.h"
+
+#include "scene/main/http_request.h"
+#include "editor_asset_installer.h"
+
+class EditorAssetLibraryItem : public PanelContainer {
+
+ OBJ_TYPE( EditorAssetLibraryItem, PanelContainer );
+
+ TextureButton *icon;
+ LinkButton* title;
+ LinkButton* category;
+ LinkButton* author;
+ TextureFrame *stars[5];
+ Label* price;
+
+ int asset_id;
+ int category_id;
+ int author_id;
+
+
+ void _asset_clicked();
+ void _category_clicked();
+ void _author_clicked();
+
+
+ void set_image(int p_type,int p_index,const Ref<Texture>& p_image);
+
+protected:
+
+ void _notification(int p_what);
+ static void _bind_methods();
+public:
+
+ void configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost);
+
+
+ EditorAssetLibraryItem();
+};
+
+
+class EditorAddonLibraryItemDescription : public ConfirmationDialog {
+
+ OBJ_TYPE(EditorAddonLibraryItemDescription, ConfirmationDialog);
+
+ EditorAssetLibraryItem *item;
+ RichTextLabel *description;
+ ScrollContainer *previews;
+ HBoxContainer *preview_hb;
+
+ struct Preview {
+ int id;
+ String video_link;
+ Button *button;
+ };
+
+ Vector<Preview> preview_images;
+ TextureFrame *preview;
+
+ void set_image(int p_type,int p_index,const Ref<Texture>& p_image);
+
+ int asset_id;
+ String download_url;
+ String title;
+ Ref<Texture> icon;
+
+ void _link_click(const String& p_url);
+protected:
+
+ static void _bind_methods();
+public:
+
+ void configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_version,const String& p_description,const String& p_download_url,const String& p_browse_url);
+ void add_preview(int p_id, bool p_video,const String& p_url);
+
+ String get_title() { return title; }
+ Ref<Texture> get_preview_icon() { return icon; }
+ String get_download_url() { return download_url; }
+ int get_asset_id() { return asset_id; }
+ EditorAddonLibraryItemDescription();
+
+};
+
+class EditorAddonLibraryItemDownload : public PanelContainer {
+
+ OBJ_TYPE(EditorAddonLibraryItemDownload, PanelContainer);
+
+
+ TextureFrame *icon;
+ Label* title;
+ ProgressBar *progress;
+ Button *install;
+ TextureButton *dismiss;
+
+ AcceptDialog *download_error;
+ HTTPRequest *download;
+ String host;
+ Label *status;
+
+ int prev_status;
+
+ int asset_id;
+
+ EditorAssetInstaller *asset_installer;
+
+ void _close();
+ void _install();
+ void _http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data);
+
+protected:
+
+ void _notification(int p_what);
+ static void _bind_methods();
+public:
+
+ int get_asset_id() { return asset_id; }
+ void configure(const String& p_title,int p_asset_id,const Ref<Texture>& p_preview, const String& p_download_url);
+ EditorAddonLibraryItemDownload();
+
+};
+
+class EditorAddonLibrary : public PanelContainer {
+ OBJ_TYPE(EditorAddonLibrary,PanelContainer);
+
+ String host;
+
+ EditorFileDialog *asset_open;
+ EditorAssetInstaller *asset_installer;
+
+
+ void _asset_open();
+ void _asset_file_selected(const String& p_file);
+
+
+ ScrollContainer *library_scroll;
+ VBoxContainer *library_vb;
+ LineEdit *filter;
+ OptionButton *categories;
+ OptionButton *repository;
+ OptionButton *sort;
+ CheckBox *reverse;
+ Button *search;
+ ProgressBar *load_status;
+ HBoxContainer *error_hb;
+ Label *error_label;
+
+ HBoxContainer *contents;
+
+ HBoxContainer *asset_top_page;
+ GridContainer *asset_items;
+ HBoxContainer *asset_bottom_page;
+
+ HTTPRequest *request;
+
+
+ enum SortOrder {
+ SORT_RATING,
+ SORT_DOWNLOADS,
+ SORT_NAME,
+ SORT_COST,
+ SORT_UPDATED,
+ SORT_MAX
+ };
+
+
+ static const char* sort_key[SORT_MAX];
+ static const char* sort_text[SORT_MAX];
+
+
+ ///MainListing
+
+ enum ImageType {
+ IMAGE_QUEUE_ICON,
+ IMAGE_QUEUE_THUMBNAIL,
+ IMAGE_QUEUE_SCREENSHOT,
+
+ };
+
+ struct ImageQueue {
+
+ bool active;
+ int queue_id;
+ int asset_id;
+ ImageType image_type;
+ int image_index;
+ HTTPRequest *request;
+ ObjectID target;
+ };
+
+ int last_queue_id;
+ Map<int,ImageQueue> image_queue;
+
+
+ void _image_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data, int p_queue_id);
+
+ void _request_image(ObjectID p_for,int p_asset_id,ImageType p_type,int p_image_index);
+ void _update_image_queue();
+
+ HBoxContainer* _make_pages(int p_page, int p_max_page, int p_page_len, int p_total_items, int p_current_items);
+
+ //
+ EditorAddonLibraryItemDescription *description;
+
+ String current_request;
+ //
+
+ enum RequestType {
+ REQUESTING_NONE,
+ REQUESTING_CONFIG,
+ };
+
+
+ RequestType requesting;
+
+
+ ScrollContainer *downloads_scroll;
+ HBoxContainer *downloads_hb;
+
+
+
+ void _install_asset();
+
+ void _select_author(int p_id);
+ void _select_category(int p_id);
+ void _select_asset(int p_id);
+
+ void _manage_plugins();
+
+ void _search(int p_page=0);
+ void _api_request(const String& p_request, const String &p_arguments="");
+ void _http_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data);
+ void _http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data);
+
+friend class EditorAddonLibraryItemDescription;
+friend class EditorAssetLibraryItem;
+protected:
+
+ static void _bind_methods();
+ void _notification(int p_what);
+public:
+ EditorAddonLibrary();
+};
+
+class AddonEditorPlugin : public EditorPlugin {
+
+ OBJ_TYPE( AddonEditorPlugin, EditorPlugin );
+
+ EditorAddonLibrary *addon_library;
+ EditorNode *editor;
+
+public:
+
+ virtual String get_name() const { return "Addons"; }
+ bool has_main_screen() const { return true; }
+ virtual void edit(Object *p_object) {}
+ virtual bool handles(Object *p_object) const { return false; }
+ virtual void make_visible(bool p_visible);
+ //virtual bool get_remove_list(List<Node*> *p_list) { return canvas_item_editor->get_remove_list(p_list); }
+ //virtual Dictionary get_state() const;
+ //virtual void set_state(const Dictionary& p_state);
+
+ AddonEditorPlugin(EditorNode *p_node);
+ ~AddonEditorPlugin();
+
+};
+
+#endif // EDITORASSETLIBRARY_H
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index a247543830..091bc701cc 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -35,6 +35,7 @@
#include "scene/gui/separator.h"
#include "editor_node.h"
#include "tools/editor/plugins/animation_player_editor_plugin.h"
+#include "scene/main/viewport.h"
/* Missing to fix:
*Set
@@ -256,6 +257,28 @@ public:
//PopupDialog *ke_dialog;
+ void _fix_node_path(Variant &value) {
+
+
+ NodePath np=value;
+
+ if (np==NodePath())
+ return;
+
+ Node* root = EditorNode::get_singleton()->get_tree()->get_root();
+
+ Node* np_node = root->get_node(np);
+ ERR_FAIL_COND(!np_node);
+
+ Node* edited_node = root->get_node(base);
+ ERR_FAIL_COND(!edited_node);
+
+
+
+ value = edited_node->get_path_to(np_node);
+ }
+
+
void _update_obj(const Ref<Animation> &p_anim) {
if (setting)
return;
@@ -356,10 +379,18 @@ public:
case Animation::TYPE_VALUE: {
if (name=="value") {
+
+ Variant value = p_value;
+
+ if (value.get_type()==Variant::NODE_PATH) {
+
+ _fix_node_path(value);
+ }
+
setting=true;
undo_redo->create_action("Anim Change Value",true);
Variant prev = animation->track_get_key_value(track,key);
- undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,p_value);
+ undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,value);
undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,prev);
undo_redo->add_do_method(this,"_update_obj",animation);
undo_redo->add_undo_method(this,"_update_obj",animation);
@@ -420,7 +451,14 @@ public:
}
if (what=="value") {
- args[idx]=p_value;
+
+ Variant value=p_value;
+ if (value.get_type()==Variant::NODE_PATH) {
+
+ _fix_node_path(value);
+ }
+
+ args[idx]=value;
d_new["args"]=args;
mergeable=true;
}
@@ -441,7 +479,7 @@ public:
} break;
}
- return false;
+
return false;
@@ -616,6 +654,7 @@ public:
float key_ofs;
PropertyInfo hint;
+ NodePath base;
void notify_change() {
@@ -1630,8 +1669,9 @@ void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_trac
}
-PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx) {
+PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx,NodePath& r_base_path) {
+ r_base_path=NodePath();
ERR_FAIL_COND_V(!animation.is_valid(),PropertyInfo());
ERR_FAIL_INDEX_V(p_idx,animation->get_track_count(),PropertyInfo());
@@ -1640,9 +1680,6 @@ PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx) {
NodePath path = animation->track_get_path(p_idx);
- String property = path.get_property();
- if (property=="")
- return PropertyInfo();
if (!root->has_node_and_resource(path))
return PropertyInfo();
@@ -1650,6 +1687,15 @@ PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx) {
RES res;
Node *node = root->get_node_and_resource(path,res);
+
+ if (node) {
+ r_base_path=node->get_path();
+ }
+
+ String property = path.get_property();
+ if (property=="")
+ return PropertyInfo();
+
List<PropertyInfo> pinfo;
if (res.is_valid())
res->get_property_list(&pinfo);
@@ -1729,7 +1775,7 @@ bool AnimationKeyEditor::_edit_if_single_selection() {
key_edit->animation=animation;
key_edit->track=idx;
key_edit->key_ofs=animation->track_get_key_time(idx,key);
- key_edit->hint=_find_hint_for_track(idx);
+ key_edit->hint=_find_hint_for_track(idx,key_edit->base);
key_edit->notify_change();
curve_edit->set_transition(animation->track_get_key_transition(idx,key));
@@ -2161,7 +2207,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
if (ofsx < add_key_icon->get_width()) {
- Animation::TrackType tt = animation->track_get_type(idx);
+ Animation::TrackType tt = animation->track_get_type(idx);
float pos = timeline_pos;
int existing = animation->track_find_key(idx,pos,true);
@@ -2187,7 +2233,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
newval=d;
} else if (tt==Animation::TYPE_VALUE) {
- PropertyInfo inf = _find_hint_for_track(idx);
+ NodePath np;
+ PropertyInfo inf = _find_hint_for_track(idx,np);
if (inf.type!=Variant::NIL) {
Variant::CallError err;
@@ -2810,6 +2857,7 @@ void AnimationKeyEditor::_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
EditorNode::get_singleton()->update_keying();
+ emit_signal("keying_changed");
} break;
case NOTIFICATION_ENTER_TREE: {
@@ -2975,6 +3023,7 @@ void AnimationKeyEditor::_clear_selection() {
key_edit->track=0;
key_edit->key_ofs=0;
key_edit->hint=PropertyInfo();
+ key_edit->base=NodePath();
key_edit->notify_change();
}
@@ -3062,7 +3111,7 @@ void AnimationKeyEditor::_query_insert(const InsertData& p_id) {
if (p_id.track_idx==-1) {
if (bool(EDITOR_DEF("animation/confirm_insert_track",true))) {
- //potential new key, does not exist
+ //potential new key, does not exist
if (insert_data.size()==1)
insert_confirm->set_text("Create NEW track for "+p_id.query+" and insert key?");
else
@@ -3269,9 +3318,10 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) {
{
//shitty hack
+ NodePath np;
animation->add_track(p_id.type);
animation->track_set_path(animation->get_track_count()-1,p_id.path);
- PropertyInfo h = _find_hint_for_track(animation->get_track_count()-1);
+ PropertyInfo h = _find_hint_for_track(animation->get_track_count()-1,np);
animation->remove_track(animation->get_track_count()-1); //hack
@@ -3645,6 +3695,9 @@ void AnimationKeyEditor::_add_call_track(const NodePath& p_base) {
NodePath path = root->get_path_to(from);
+ //print_line("root: "+String(root->get_path()));
+ //print_line("path: "+String(path));
+
undo_redo->create_action("Anim Add Call Track");
undo_redo->add_do_method(animation.ptr(),"add_track",Animation::TYPE_METHOD);
undo_redo->add_do_method(animation.ptr(),"track_set_path",animation->get_track_count(),path);
@@ -3691,7 +3744,7 @@ void AnimationKeyEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_animation_loop_changed"),&AnimationKeyEditor::_animation_loop_changed);
- ObjectTypeDB::bind_method(_MD("_animation_len_changed"),&AnimationKeyEditor::_animation_len_changed);
+ ObjectTypeDB::bind_method(_MD("_animation_len_changed"),&AnimationKeyEditor::_animation_len_changed);
ObjectTypeDB::bind_method(_MD("_create_value_item"),&AnimationKeyEditor::_create_value_item);
ObjectTypeDB::bind_method(_MD("_pane_drag"),&AnimationKeyEditor::_pane_drag);
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 5e81439fe6..413c73b4b9 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -212,7 +212,7 @@ class AnimationKeyEditor : public VBoxContainer {
ConfirmationDialog *scale_dialog;
SpinBox *scale;
- PropertyEditor *key_editor;
+ PropertyEditor *key_editor;
SceneTreeDialog *call_select;
@@ -302,7 +302,7 @@ class AnimationKeyEditor : public VBoxContainer {
void _select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos);
void _curve_transition_changed(float p_what);
- PropertyInfo _find_hint_for_track(int p_idx);
+ PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path);
void _create_value_item(int p_type);
void _pane_drag(const Point2& p_delta);
diff --git a/tools/editor/call_dialog.cpp b/tools/editor/call_dialog.cpp
index edcd7371f2..c5e9cdfa0d 100644
--- a/tools/editor/call_dialog.cpp
+++ b/tools/editor/call_dialog.cpp
@@ -39,22 +39,22 @@ class CallDialogParams : public Object {
public:
bool _set(const StringName& p_name, const Variant& p_value) {
-
+
values[p_name]=p_value;
return true;
}
-
+
bool _get(const StringName& p_name,Variant &r_ret) const {
-
+
if (values.has(p_name)) {
r_ret=values[p_name];
return true;
}
return false;
}
-
+
void _get_property_list( List<PropertyInfo> *p_list) const {
-
+
for(int i=0;i<method.arguments.size();i++)
p_list->push_back(method.arguments[i]);
}
@@ -67,9 +67,9 @@ public:
void CallDialog::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_READY) {
-
+
call->connect("pressed", this,"_call");
cancel->connect("pressed", this,"_cancel");
//filter->get_path()->connect("text_changed", this,"_text_changed");
@@ -86,35 +86,35 @@ void CallDialog::_notification(int p_what) {
}
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
- get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
- }
+ get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
+ }
}
void CallDialog::_call() {
-
+
if (!tree->get_selected())
return;
-
+
TreeItem* item=tree->get_selected();
ERR_FAIL_COND(!item);
int idx=item->get_metadata(0);
ERR_FAIL_INDEX(idx,methods.size());
MethodInfo &m = methods[idx];
-
+
Variant args[VARIANT_ARG_MAX];
-
+
for(int i=0;i<VARIANT_ARG_MAX;i++) {
-
+
if (i>=m.arguments.size())
continue;
-
+
if (call_params->values.has(m.arguments[i].name))
args[i]=call_params->values[m.arguments[i].name];
}
-
+
Variant ret = object->call(m.name,args[0],args[1],args[2],args[3],args[4]);
if (ret.get_type()!=Variant::NIL)
return_value->set_text(ret);
@@ -123,7 +123,7 @@ void CallDialog::_call() {
}
void CallDialog::_cancel() {
-
+
hide();
}
@@ -132,23 +132,23 @@ void CallDialog::_item_selected() {
TreeItem* item=tree->get_selected();
ERR_FAIL_COND(!item);
-
+
if (item->get_metadata(0).get_type()==Variant::NIL) {
-
+
call->set_disabled(true);
return;
}
-
+
call->set_disabled(false);
-
+
int idx=item->get_metadata(0);
ERR_FAIL_INDEX(idx,methods.size());
-
+
MethodInfo &m = methods[idx];
call_params->values.clear();
call_params->method=m;
-
+
property_editor->edit(call_params);
property_editor->update_tree();
@@ -156,38 +156,38 @@ void CallDialog::_item_selected() {
}
void CallDialog::_update_method_list() {
-
+
tree->clear();
if (!object)
return;
-
+
TreeItem *root = tree->create_item();
-
+
List<MethodInfo> method_list;
object->get_method_list(&method_list);
method_list.sort();
methods.clear();
-
+
List<String> inheritance_list;
-
+
String type = object->get_type();
-
- while(type!="") {
+
+ while(type!="") {
inheritance_list.push_back( type );
type=ObjectTypeDB::type_inherits_from(type);
}
-
+
TreeItem *selected_item=NULL;
-
+
for(int i=0;i<inheritance_list.size();i++) {
-
+
String type=inheritance_list[i];
String parent_type=ObjectTypeDB::type_inherits_from(type);
TreeItem *type_item=NULL;
-
+
List<MethodInfo>::Element *N,*E=method_list.front();
-
+
while(E) {
N=E->next();
@@ -196,38 +196,38 @@ void CallDialog::_update_method_list() {
E=N;
continue;
}
-
+
if (!type_item) {
type_item=tree->create_item(root);
type_item->set_text(0,type);
if (has_icon(type,"EditorIcons"))
type_item->set_icon(0,get_icon(type,"EditorIcons"));
}
-
+
TreeItem *method_item = tree->create_item(type_item);
method_item->set_text(0,E->get().name);
method_item->set_metadata(0,methods.size());
if (E->get().name==selected)
selected_item=method_item;
methods.push_back( E->get() );
-
+
method_list.erase(E);
E=N;
}
}
-
-
-
+
+
+
if (selected_item)
selected_item->select(0);
}
void CallDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method("_call",&CallDialog::_call);
ObjectTypeDB::bind_method("_cancel",&CallDialog::_cancel);
ObjectTypeDB::bind_method("_item_selected", &CallDialog::_item_selected);
-
+
}
void CallDialog::set_object(Object *p_object,StringName p_selected) {
@@ -252,22 +252,22 @@ CallDialog::CallDialog() {
call->set_anchor( MARGIN_RIGHT, ANCHOR_END );
call->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
call->set_begin( Point2( 70, 29 ) );
- call->set_end( Point2( 15, 15 ) );
+ call->set_end( Point2( 15, 15 ) );
call->set_text("Call");
-
+
add_child(call);
-
+
cancel = memnew( Button );
cancel->set_anchor( MARGIN_TOP, ANCHOR_END );
cancel->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
cancel->set_begin( Point2( 15, 29 ) );
- cancel->set_end( Point2( 70, 15 ) );
+ cancel->set_end( Point2( 70, 15 ) );
cancel->set_text("Close");
-
+
add_child(cancel);
-
+
tree = memnew( Tree );
-
+
tree->set_anchor( MARGIN_RIGHT, ANCHOR_RATIO );
tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
tree->set_begin( Point2( 20,50 ) );
@@ -275,60 +275,60 @@ CallDialog::CallDialog() {
tree->set_margin(MARGIN_RIGHT, 0.5 );
tree->set_select_mode( Tree::SELECT_ROW );
add_child(tree);
-
+
tree->connect("item_selected", this,"_item_selected");
tree->set_hide_root(true);
-
+
property_editor = memnew( PropertyEditor );
-
+
property_editor->set_anchor_and_margin( MARGIN_RIGHT, ANCHOR_END, 15 );
property_editor->set_anchor_and_margin( MARGIN_TOP, ANCHOR_BEGIN, 50 );
property_editor->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.55 );
property_editor->set_anchor_and_margin( MARGIN_BOTTOM, ANCHOR_END, 90 );
property_editor->get_scene_tree()->set_hide_root( true );
property_editor->hide_top_label();
-
+
add_child(property_editor);
method_label = memnew( Label );
method_label->set_pos( Point2( 15,25) );
method_label->set_text("Method List:");
-
+
add_child(method_label);
-
+
Label *label = memnew( Label );
label->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.53 );
label->set_anchor_and_margin( MARGIN_TOP, ANCHOR_BEGIN, 25 );
label->set_text("Arguments:");
-
+
add_child(label);
-
+
return_label = memnew( Label );
return_label->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.53 );
return_label->set_anchor_and_margin( MARGIN_TOP, ANCHOR_END, 85 );
return_label->set_text("Return:");
-
+
add_child(return_label);
-
+
return_value = memnew( LineEdit );
return_value->set_anchor_and_margin( MARGIN_LEFT, ANCHOR_RATIO, 0.55 );
- return_value->set_anchor_and_margin( MARGIN_RIGHT, ANCHOR_END, 15 );
+ return_value->set_anchor_and_margin( MARGIN_RIGHT, ANCHOR_END, 15 );
return_value->set_anchor_and_margin( MARGIN_TOP, ANCHOR_END, 65 );
-
+
add_child(return_value);
-
+
/*
label = memnew( Label );
label->set_anchor( MARGIN_TOP, ANCHOR_END );
label->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
-
+
label->set_begin( Point2( 15,54) );
label->set_end( Point2( 16,44) );
label->set_text("Parameters:");
-
+
add_child(label);
*/
-
+
call_params = memnew( CallDialogParams );
set_as_toplevel(true);
}
diff --git a/tools/editor/call_dialog.h b/tools/editor/call_dialog.h
index 2d04e7b6cd..a2ca925ff1 100644
--- a/tools/editor/call_dialog.h
+++ b/tools/editor/call_dialog.h
@@ -43,39 +43,39 @@
class CallDialogParams;
class CallDialog : public Popup {
-
+
OBJ_TYPE( CallDialog, Popup );
-
+
Label* method_label;
Tree *tree;
Button *call;
Button *cancel;
-
+
CallDialogParams *call_params;
PropertyEditor *property_editor;
-
+
Label *return_label;
LineEdit *return_value;
- Object *object;
+ Object *object;
StringName selected;
-
+
Vector<MethodInfo> methods;
-
-
+
+
void _item_selected();
void _update_method_list();
void _call();
void _cancel();
-
+
protected:
- static void _bind_methods();
+ static void _bind_methods();
void _notification(int p_what);
public:
-
+
void set_object(Object *p_object,StringName p_selected="");
-
- CallDialog();
+
+ CallDialog();
~CallDialog();
};
diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp
index fe863bfebc..968d02dfa5 100644
--- a/tools/editor/code_editor.cpp
+++ b/tools/editor/code_editor.cpp
@@ -85,7 +85,7 @@ void FindReplaceDialog::popup_search() {
skip->hide();
popup_centered(Point2(300,190));
get_ok()->set_text("Find");
- search_text->grab_focus();
+ search_text->grab_focus();
if (text_edit->is_selection_active() && ( text_edit->get_selection_from_line() == text_edit->get_selection_to_line())) {
search_text->set_text( text_edit->get_selection_text() );
@@ -544,7 +544,7 @@ void CodeTextEditor::set_error(const String& p_error) {
}
void CodeTextEditor::_on_settings_change() {
-
+
// FONTS
String editor_font = EDITOR_DEF("text_editor/font", "");
bool font_overrode = false;
@@ -557,8 +557,8 @@ void CodeTextEditor::_on_settings_change() {
}
if(!font_overrode)
text_editor->add_font_override("font",get_font("source","Fonts"));
-
- // AUTO BRACE COMPLETION
+
+ // AUTO BRACE COMPLETION
text_editor->set_auto_brace_completion(
EDITOR_DEF("text_editor/auto_brace_complete", true)
);
@@ -568,6 +568,12 @@ void CodeTextEditor::_on_settings_change() {
);
enable_complete_timer = EDITOR_DEF("text_editor/enable_code_completion_delay",true);
+
+ // call hint settings
+ text_editor->set_callhint_settings(
+ EDITOR_DEF("text_editor/put_callhint_tooltip_below_current_line", true),
+ EDITOR_DEF("text_editor/callhint_tooltip_offset", Vector2())
+ );
}
void CodeTextEditor::_text_changed_idle_timeout() {
diff --git a/tools/editor/code_editor.h b/tools/editor/code_editor.h
index 5ed7ce9052..e28517c601 100644
--- a/tools/editor/code_editor.h
+++ b/tools/editor/code_editor.h
@@ -55,7 +55,7 @@ public:
void set_text_editor(TextEdit *p_text_editor);
- GotoLineDialog();
+ GotoLineDialog();
};
diff --git a/tools/editor/connections_dialog.cpp b/tools/editor/connections_dialog.cpp
index 1e530b21c2..962062ae01 100644
--- a/tools/editor/connections_dialog.cpp
+++ b/tools/editor/connections_dialog.cpp
@@ -30,7 +30,7 @@
#include "scene/gui/label.h"
-
+
#include "print_string.h"
#include "editor_settings.h"
@@ -91,11 +91,11 @@ public:
};
void ConnectDialog::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
- get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
+ get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
}
if (p_what==NOTIFICATION_ENTER_TREE) {
@@ -104,7 +104,7 @@ void ConnectDialog::_notification(int p_what) {
}
void ConnectDialog::_tree_node_selected() {
-
+
//dst_method_list->get_popup()->clear();
Node *current=tree->get_selected();
@@ -151,17 +151,17 @@ void ConnectDialog::_tree_node_selected() {
}
void ConnectDialog::_dst_method_list_selected(int p_idx) {
-
+
//dst_method->set_text( dst_method_list->get_popup()->get_item_text(p_idx));
}
void ConnectDialog::edit(Node *p_node) {
-
+
node=p_node;
-
+
//dst_method_list->get_popup()->clear();
-
-
+
+
tree->set_selected(NULL);
tree->set_marked(node,true);
dst_path->set_text("");
@@ -173,7 +173,7 @@ void ConnectDialog::edit(Node *p_node) {
}
void ConnectDialog::ok_pressed() {
-
+
if (dst_method->get_text()=="") {
error->set_text("Method in target Node must be specified!");
@@ -185,13 +185,13 @@ void ConnectDialog::ok_pressed() {
}
void ConnectDialog::_cancel_pressed() {
-
+
hide();
}
NodePath ConnectDialog::get_dst_path() const {
-
+
return dst_path->get_text();
}
@@ -207,11 +207,11 @@ bool ConnectDialog::get_oneshot() const {
}
StringName ConnectDialog::get_dst_method() const {
-
+
String txt=dst_method->get_text();
if (txt.find("(")!=-1)
txt=txt.left( txt.find("(")).strip_edges();
- return txt;
+ return txt;
}
@@ -280,7 +280,7 @@ void ConnectDialog::set_dst_method(const StringName& p_method) {
}
void ConnectDialog::_bind_methods() {
-
+
//ObjectTypeDB::bind_method("_ok",&ConnectDialog::_ok_pressed);
ObjectTypeDB::bind_method("_cancel",&ConnectDialog::_cancel_pressed);
//ObjectTypeDB::bind_method("_dst_method_list_selected",&ConnectDialog::_dst_method_list_selected);
@@ -293,17 +293,17 @@ void ConnectDialog::_bind_methods() {
}
ConnectDialog::ConnectDialog() {
-
+
int margin = get_constant("margin","Dialogs");
int button_margin = get_constant("button_margin","Dialogs");
-
-
+
+
Label * label = memnew( Label );
label->set_pos( Point2( 8,11) );
label->set_text("Connect To Node:");
-
- add_child(label);
+
+ add_child(label);
label = memnew( Label );
label->set_anchor( MARGIN_LEFT, ANCHOR_RATIO );
label->set_pos( Point2( 0.5,11) );
@@ -379,7 +379,7 @@ ConnectDialog::ConnectDialog() {
label->set_begin( Point2( 8,124) );
label->set_end( Point2( 15,99) );
label->set_text("Path To Node:");
-
+
add_child(label);
dst_path = memnew(LineEdit);
@@ -390,11 +390,11 @@ ConnectDialog::ConnectDialog() {
dst_path->set_end( Point2( 15,80 ) );
add_child(dst_path);
-
+
label = memnew( Label );
label->set_anchor( MARGIN_TOP, ANCHOR_END );
label->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- label->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
+ label->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
label->set_begin( Point2( 8,78 ) );
label->set_end( Point2( 15,52 ) );
label->set_text("Method In Node:");
@@ -420,7 +420,7 @@ ConnectDialog::ConnectDialog() {
dst_method_list->set_anchor( MARGIN_RIGHT, ANCHOR_END );
dst_method_list->set_anchor( MARGIN_LEFT, ANCHOR_END );
dst_method_list->set_anchor( MARGIN_TOP, ANCHOR_END );
- dst_method_list->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
+ dst_method_list->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
dst_method_list->set_begin( Point2( 70,59) );
dst_method_list->set_end( Point2( 15,39 ) );
*/
@@ -446,14 +446,14 @@ ConnectDialog::ConnectDialog() {
realtime->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
realtime->set_anchor( MARGIN_RIGHT, ANCHOR_END );
realtime->set_begin( Point2( 120, button_margin-10 ) );
- realtime->set_end( Point2( 80, margin ) );
+ realtime->set_end( Point2( 80, margin ) );
realtime->set_text("Realtime");
add_child(realtime);
*/
-
-
+
+
// dst_method_list->get_popup()->connect("item_pressed", this,"_dst_method_list_selected");
tree->connect("node_selected", this,"_tree_node_selected");
@@ -468,8 +468,8 @@ ConnectDialog::ConnectDialog() {
// error->get_cancel()->set_text("Close");
-
-
+
+
}
@@ -481,21 +481,21 @@ ConnectDialog::~ConnectDialog()
void ConnectionsDialog::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
- get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
- }
+ get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
+ }
}
void ConnectionsDialog::_close() {
-
- hide();
+
+ hide();
}
void ConnectionsDialog::_connect() {
-
+
TreeItem *it = tree->get_selected();
ERR_FAIL_COND(!it);
String signal=it->get_metadata(0).operator Dictionary()["name"];
@@ -534,7 +534,7 @@ void ConnectionsDialog::_connect() {
void ConnectionsDialog::ok_pressed() {
-
+
TreeItem *item = tree->get_selected();
if (!item) {
@@ -585,31 +585,31 @@ void ConnectionsDialog::ok_pressed() {
}
/*
void ConnectionsDialog::_remove() {
-
+
if (!tree->get_selected())
return;
-
+
TreeItem *selected=tree->get_selected();
if (!selected)
return;
-
+
Dictionary meta=selected->get_metadata(0);
-
+
remove_confirm->set_text(String()+"Remove Connection \""+meta["from_event"].operator String()+"\" ?");
remove_confirm->popup_centered(Size2(340,80));
}
*/
/*
void ConnectionsDialog::_remove_confirm() {
-
+
if (!tree->get_selected())
return;
TreeItem *selected=tree->get_selected();
if (!selected)
return;
-
+
Dictionary meta=selected->get_metadata(0);
-
+
undo_redo->create_action("Remove Subscription");
undo_redo->add_do_method(node,"unsubscribe_path_event",meta["from_event"].operator String(),meta["from_path"].operator NodePath(),meta["to_method"].operator String());
undo_redo->add_undo_method(node,"subscribe_path_event_persist",meta["from_event"].operator String(),meta["from_path"].operator NodePath(),meta["to_method"].operator String(),Array(),false);
@@ -628,14 +628,14 @@ struct _ConnectionsDialogMethodInfoSort {
};
void ConnectionsDialog::update_tree() {
-
+
if (!is_visible())
return; //don't update if not visible, of course
tree->clear();
-
+
if (!node)
return;
-
+
TreeItem *root=tree->create_item();
@@ -779,7 +779,7 @@ void ConnectionsDialog::update_tree() {
}
void ConnectionsDialog::set_node(Node* p_node) {
-
+
node=p_node;
update_tree();
}
@@ -806,7 +806,7 @@ void ConnectionsDialog::_something_selected() {
}
void ConnectionsDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method("_connect",&ConnectionsDialog::_connect);
ObjectTypeDB::bind_method("_something_selected",&ConnectionsDialog::_something_selected);
@@ -814,11 +814,11 @@ void ConnectionsDialog::_bind_methods() {
// ObjectTypeDB::bind_method("_remove_confirm",&ConnectionsDialog::_remove_confirm);
ObjectTypeDB::bind_method("update_tree",&ConnectionsDialog::update_tree);
-
+
}
ConnectionsDialog::ConnectionsDialog(EditorNode *p_editor) {
-
+
editor=p_editor;
set_title("Edit Connections..");
set_hide_on_ok(false);
@@ -828,28 +828,28 @@ ConnectionsDialog::ConnectionsDialog(EditorNode *p_editor) {
set_child_rect(vbc);
-
+
tree = memnew( Tree );
tree->set_columns(1);
tree->set_select_mode(Tree::SELECT_ROW);
tree->set_hide_root(true);
vbc->add_margin_child("Connections:",tree,true);
-
+
// add_child(tree);
-
+
connect_dialog = memnew( ConnectDialog );
connect_dialog->set_as_toplevel(true);
add_child(connect_dialog);
-
+
remove_confirm = memnew( ConfirmationDialog );
remove_confirm->set_as_toplevel(true);
add_child(remove_confirm);
-
- /*
+
+ /*
node_only->set_anchor( MARGIN_TOP, ANCHOR_END );
node_only->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
node_only->set_anchor( MARGIN_RIGHT, ANCHOR_END );
-
+
node_only->set_begin( Point2( 20,51) );
node_only->set_end( Point2( 10,44) );
*/
@@ -859,7 +859,7 @@ ConnectionsDialog::ConnectionsDialog(EditorNode *p_editor) {
connect_dialog->connect("connected", this,"_connect");
tree->connect("item_selected", this,"_something_selected");
get_cancel()->set_text("Close");
-
+
}
diff --git a/tools/editor/connections_dialog.h b/tools/editor/connections_dialog.h
index d5e228e799..575bcf54d7 100644
--- a/tools/editor/connections_dialog.h
+++ b/tools/editor/connections_dialog.h
@@ -47,9 +47,9 @@
class ConnectDialogBinds;
class ConnectDialog : public ConfirmationDialog {
-
+
OBJ_TYPE( ConnectDialog, ConfirmationDialog );
-
+
ConfirmationDialog *error;
LineEdit *dst_path;
@@ -69,34 +69,34 @@ class ConnectDialog : public ConfirmationDialog {
void _dst_method_list_selected(int p_idx);
void _add_bind();
void _remove_bind();
-
+
protected:
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
-
+
bool get_make_callback() { return !make_callback->is_hidden() && make_callback->is_pressed(); }
NodePath get_dst_path() const;
- StringName get_dst_method() const;
+ StringName get_dst_method() const;
bool get_deferred() const;
bool get_oneshot() const;
Vector<Variant> get_binds() const;
void set_dst_method(const StringName& p_method);
void set_dst_node(Node* p_node);
-
+
// Button *get_ok() { return ok; }
// Button *get_cancel() { return cancel; }
void edit(Node *p_node);
-
+
ConnectDialog();
~ConnectDialog();
-
+
};
class ConnectionsDialog : public ConfirmationDialog {
-
+
OBJ_TYPE( ConnectionsDialog , ConfirmationDialog );
EditorNode *editor;
@@ -104,7 +104,7 @@ class ConnectionsDialog : public ConfirmationDialog {
Tree *tree;
ConfirmationDialog *remove_confirm;
ConnectDialog *connect_dialog;
-
+
void update_tree();
void _close();
@@ -113,20 +113,20 @@ class ConnectionsDialog : public ConfirmationDialog {
UndoRedo *undo_redo;
protected:
-
+
virtual void ok_pressed();
void _notification(int p_what);
static void _bind_methods();
public:
-
+
void set_undoredo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; }
void set_node(Node* p_node);
String get_selected_type();
-
+
ConnectionsDialog(EditorNode *p_editor=NULL);
~ConnectionsDialog();
-
+
};
#endif
diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp
index 0f39d72308..35688917fb 100644
--- a/tools/editor/create_dialog.cpp
+++ b/tools/editor/create_dialog.cpp
@@ -171,6 +171,7 @@ void CreateDialog::_update_search() {
if (EditorNode::get_editor_data().get_custom_types().has(type)) {
//there are custom types based on this... cool.
+ //print_line("there are custom types");
const Vector<EditorData::CustomType> &ct = EditorNode::get_editor_data().get_custom_types()[type];
@@ -259,7 +260,33 @@ Object *CreateDialog::instance_selected() {
TreeItem *selected = search_options->get_selected();
if (selected) {
- return ObjectTypeDB::instance(selected->get_text(0));
+ String custom = selected->get_metadata(0);
+ if (custom!=String()) {
+ if (EditorNode::get_editor_data().get_custom_types().has(custom)) {
+
+ for(int i=0;i<EditorNode::get_editor_data().get_custom_types()[custom].size();i++) {
+ if (EditorNode::get_editor_data().get_custom_types()[custom][i].name==selected->get_text(0)) {
+ Ref<Texture> icon = EditorNode::get_editor_data().get_custom_types()[custom][i].icon;
+ Ref<Script> script = EditorNode::get_editor_data().get_custom_types()[custom][i].script;
+ String name = selected->get_text(0);
+
+ Object *ob = ObjectTypeDB::instance(custom);
+ ERR_FAIL_COND_V(!ob,NULL);
+ if (ob->is_type("Node")) {
+ ob->call("set_name",name);
+ }
+ ob->set_script(script.get_ref_ptr());
+ if (icon.is_valid())
+ ob->set_meta("_editor_icon",icon);
+ return ob;
+
+ }
+ }
+
+ }
+ } else {
+ return ObjectTypeDB::instance(selected->get_text(0));
+ }
}
return NULL;
@@ -310,116 +337,116 @@ CreateDialog::CreateDialog() {
//old create dialog, disabled
void CreateDialog::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_READY) {
connect("confirmed",this,"_create");
update_tree();
}
if (p_what==NOTIFICATION_DRAW) {
-
+
//RID ci = get_canvas_item();
//get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
- }
+ }
}
void CreateDialog::_create() {
-
+
if (tree->get_selected())
emit_signal("create");
hide();
}
void CreateDialog::_cancel() {
-
+
hide();
}
void CreateDialog::_text_changed(String p_text) {
-
+
update_tree();
}
void CreateDialog::add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem *p_root) {
-
+
if (p_types.has(p_type))
return;
if (!ObjectTypeDB::is_type(p_type,base) || p_type==base)
return;
-
+
String inherits=ObjectTypeDB::type_inherits_from(p_type);
-
+
TreeItem *parent=p_root;
-
+
if (inherits.length()) {
-
+
if (!p_types.has(inherits)) {
-
+
add_type(inherits,p_types,p_root);
}
-
+
if (p_types.has(inherits) )
- parent=p_types[inherits];
- }
-
+ parent=p_types[inherits];
+ }
+
TreeItem *item = tree->create_item(parent);
item->set_text(0,p_type);
if (!ObjectTypeDB::can_instance(p_type)) {
item->set_custom_color(0, Color(0.5,0.5,0.5) );
item->set_selectable(0,false);
}
-
-
+
+
if (has_icon(p_type,"EditorIcons")) {
-
+
item->set_icon(0, get_icon(p_type,"EditorIcons"));
}
-
+
p_types[p_type]=item;
}
void CreateDialog::update_tree() {
tree->clear();
-
+
List<String> type_list;
- ObjectTypeDB::get_type_list(&type_list);
-
+ ObjectTypeDB::get_type_list(&type_list);
+
HashMap<String,TreeItem*> types;
-
+
TreeItem *root = tree->create_item();
-
+
root->set_text(0,base);
List<String>::Element *I=type_list.front();
-
+
for(;I;I=I->next()) {
-
-
+
+
String type=I->get();
-
+
if (!ObjectTypeDB::can_instance(type))
continue; // cant create what can't be instanced
if (filter->get_text()=="")
add_type(type,types,root);
else {
-
+
bool found=false;
String type=I->get();
- while(type!="" && ObjectTypeDB::is_type(type,base) && type!=base) {
+ while(type!="" && ObjectTypeDB::is_type(type,base) && type!=base) {
if (type.findn(filter->get_text())!=-1) {
-
+
found=true;
break;
}
-
+
type=ObjectTypeDB::type_inherits_from(type);
}
-
+
if (found)
add_type(I->get(),types,root);
@@ -501,12 +528,12 @@ Object *CreateDialog::instance_selected() {
void CreateDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method("_create",&CreateDialog::_create);
ObjectTypeDB::bind_method("_cancel",&CreateDialog::_cancel);
ObjectTypeDB::bind_method("_text_changed", &CreateDialog::_text_changed);
ADD_SIGNAL( MethodInfo("create"));
-
+
}
@@ -520,7 +547,7 @@ void CreateDialog::set_base_type(const String& p_base) {
return;
base=p_base;
if (is_inside_scene())
- update_tree();
+ update_tree();
}
String CreateDialog::get_base_type() const {
@@ -536,14 +563,14 @@ CreateDialog::CreateDialog() {
set_child_rect(vbc);
get_ok()->set_text("Create");
-
+
tree = memnew( Tree );
vbc->add_margin_child("Type:",tree,true);
//tree->set_hide_root(true);
-
- filter = memnew( LineEdit );
+
+ filter = memnew( LineEdit );
vbc->add_margin_child("Filter:",filter);
-
+
base="Node";
set_as_toplevel(true);
diff --git a/tools/editor/create_dialog.h b/tools/editor/create_dialog.h
index 6f959fd467..a46ff5ae06 100644
--- a/tools/editor/create_dialog.h
+++ b/tools/editor/create_dialog.h
@@ -82,37 +82,37 @@ public:
//old create dialog, disabled
class CreateDialog : public ConfirmationDialog {
-
+
OBJ_TYPE( CreateDialog, ConfirmationDialog );
-
+
Tree *tree;
Button *create;
Button *cancel;
LineEdit *filter;
-
+
void update_tree();
void _create();
void _cancel();
- void add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem
+ void add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem
*p_root);
-
+
String base;
void _text_changed(String p_text);
virtual void _post_popup() { tree->grab_focus();}
protected:
- static void _bind_methods();
+ static void _bind_methods();
void _notification(int p_what);
public:
-
+
Object *instance_selected();
-
+
void set_base_type(const String& p_base);
String get_base_type() const;
- CreateDialog();
+ CreateDialog();
~CreateDialog();
};
diff --git a/tools/editor/editor_asset_installer.cpp b/tools/editor/editor_asset_installer.cpp
new file mode 100644
index 0000000000..2967abbc0a
--- /dev/null
+++ b/tools/editor/editor_asset_installer.cpp
@@ -0,0 +1,327 @@
+#include "editor_asset_installer.h"
+#include "io/zip_io.h"
+#include "os/dir_access.h"
+#include "os/file_access.h"
+#include "editor_node.h"
+void EditorAssetInstaller::_update_subitems(TreeItem* p_item,bool p_check,bool p_first) {
+
+
+ if (p_check) {
+ if (p_item->get_custom_color(0)==Color()) {
+ p_item->set_checked(0,true);
+ }
+ } else {
+ p_item->set_checked(0,false);
+
+ }
+
+ if (p_item->get_children()) {
+ _update_subitems(p_item->get_children(),p_check);
+ }
+
+ if (!p_first && p_item->get_next()) {
+ _update_subitems(p_item->get_next(),p_check);
+ }
+
+}
+
+void EditorAssetInstaller::_item_edited() {
+
+
+ if (updating)
+ return;
+
+ TreeItem *item = tree->get_edited();
+ if (!item)
+ return;
+
+
+ String path=item->get_metadata(0);
+
+ updating=true;
+ if (path==String()) { //a dir
+ _update_subitems(item,item->is_checked(0),true);
+ }
+
+ if (item->is_checked(0)) {
+ while(item) {
+ item->set_checked(0,true);
+ item=item->get_parent();
+ }
+
+ }
+ updating=false;
+
+}
+
+void EditorAssetInstaller::open(const String& p_path,int p_depth) {
+
+
+ package_path=p_path;
+ Set<String> files_sorted;
+
+ FileAccess *src_f=NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io);
+ if (!pkg) {
+
+ error->set_text("Error opening package file, not in zip format.");
+ return;
+ }
+
+ int ret = unzGoToFirstFile(pkg);
+
+
+ while(ret==UNZ_OK) {
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
+
+ String name=fname;
+ files_sorted.insert(name);
+
+ ret = unzGoToNextFile(pkg);
+ }
+
+
+ Map<String,Ref<Texture> > extension_guess;
+ {
+ extension_guess["png"]=get_icon("Texture","EditorIcons");
+ extension_guess["jpg"]=get_icon("Texture","EditorIcons");
+ extension_guess["tex"]=get_icon("Texture","EditorIcons");
+ extension_guess["atex"]=get_icon("Texture","EditorIcons");
+ extension_guess["dds"]=get_icon("Texture","EditorIcons");
+ extension_guess["scn"]=get_icon("PackedScene","EditorIcons");
+ extension_guess["tscn"]=get_icon("PackedScene","EditorIcons");
+ extension_guess["xml"]=get_icon("PackedScene","EditorIcons");
+ extension_guess["xscn"]=get_icon("PackedScene","EditorIcons");
+ extension_guess["mtl"]=get_icon("Material","EditorIcons");
+ extension_guess["shd"]=get_icon("Shader","EditorIcons");
+ extension_guess["gd"]=get_icon("GDScript","EditorIcons");
+ }
+
+ Ref<Texture> generic_extension = get_icon("Object","EditorIcons");
+
+
+ unzClose(pkg);
+
+ updating=true;
+ tree->clear();
+ TreeItem *root=tree->create_item();
+ root->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
+ root->set_checked(0,true);
+ root->set_icon(0,get_icon("folder","FileDialog"));
+ root->set_text(0,"res://");
+ root->set_editable(0,true);
+ Map<String,TreeItem*> dir_map;
+
+ for(Set<String>::Element *E=files_sorted.front();E;E=E->next()) {
+
+ String path = E->get();
+ int depth=p_depth;
+ bool skip=false;
+ while(depth>0) {
+ int pp = path.find("/");
+ if (pp==-1) {
+ skip=true;
+ break;
+ }
+ path=path.substr(pp+1,path.length());
+ depth--;
+ }
+
+ if (skip || path==String())
+ continue;
+
+ bool isdir=false;
+
+ if (path.ends_with("/")) {
+ //a directory
+ path=path.substr(0,path.length()-1);
+ isdir=true;
+ }
+
+ int pp = path.find_last("/");
+
+
+ TreeItem *parent;
+ if (pp==-1) {
+ parent=root;
+ } else {
+ String ppath=path.substr(0,pp);
+ print_line("PPATH IS: "+ppath);
+ ERR_CONTINUE(!dir_map.has(ppath));
+ parent=dir_map[ppath];
+
+ }
+
+ TreeItem *ti = tree->create_item(parent);
+ ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
+ ti->set_checked(0,true);
+ ti->set_editable(0,true);
+ if (isdir) {
+ dir_map[path]=ti;
+ ti->set_text(0,path.get_file()+"/");
+ ti->set_icon(0,get_icon("folder","FileDialog"));
+ } else {
+ String file = path.get_file();
+ String extension = file.extension().to_lower();
+ if (extension_guess.has(extension)) {
+ ti->set_icon(0,extension_guess[extension]);
+ } else {
+ ti->set_icon(0,generic_extension);
+ }
+ ti->set_text(0,file);
+
+
+ String res_path = "res://"+path;
+ if (FileAccess::exists(res_path)) {
+ ti->set_custom_color(0,Color(1,0.3,0.2));
+ ti->set_tooltip(0,res_path+" (Already Exists)");
+ ti->set_checked(0,false);
+ } else {
+ ti->set_tooltip(0,res_path);
+
+ }
+
+ ti->set_metadata(0,res_path);
+
+ }
+
+ status_map[E->get()]=ti;
+
+
+
+ }
+ popup_centered_ratio();
+ updating=false;
+
+}
+
+void EditorAssetInstaller::ok_pressed() {
+
+ FileAccess *src_f=NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ unzFile pkg = unzOpen2(package_path.utf8().get_data(), &io);
+ if (!pkg) {
+
+ error->set_text("Error opening package file, not in zip format.");
+ return;
+ }
+
+ int ret = unzGoToFirstFile(pkg);
+
+ Vector<String> failed_files;
+
+ ProgressDialog::get_singleton()->add_task("uncompress","Uncompressing Assets",status_map.size());
+
+ int idx=0;
+ while(ret==UNZ_OK) {
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
+
+ String name=fname;
+
+ if (status_map.has(name) && status_map[name]->is_checked(0)) {
+
+ String path = status_map[name]->get_metadata(0);
+ if (path==String()) { // a dir
+
+ String dirpath;
+ TreeItem *t = status_map[name];
+ while(t) {
+ dirpath=t->get_text(0)+dirpath;
+ t=t->get_parent();
+ }
+
+ if (dirpath.ends_with("/")) {
+ dirpath=dirpath.substr(0,dirpath.length()-1);
+ }
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ da->make_dir(dirpath);
+ memdelete(da);
+
+ } else {
+
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
+
+ //read
+ unzOpenCurrentFile(pkg);
+ unzReadCurrentFile(pkg,data.ptr(),data.size());
+ unzCloseCurrentFile(pkg);
+
+ FileAccess *f=FileAccess::open(path,FileAccess::WRITE);
+ if (f) {
+ f->store_buffer(data.ptr(),data.size());
+ memdelete(f);
+ } else {
+ failed_files.push_back(path);
+ }
+
+ ProgressDialog::get_singleton()->task_step("uncompress",path,idx);
+ }
+
+ }
+
+ idx++;
+ ret = unzGoToNextFile(pkg);
+ }
+
+ ProgressDialog::get_singleton()->end_task("uncompress");
+ unzClose(pkg);
+
+ if (failed_files.size()) {
+ String msg="The following files failed extraction from package:\n\n";
+ for(int i=0;i<failed_files.size();i++) {
+
+ if (i>15) {
+ msg+="\nAnd "+itos(failed_files.size()-i)+" more files.";
+ break;
+ }
+ msg+=failed_files[i];
+ }
+ EditorNode::get_singleton()->show_warning(msg);
+ } else {
+ EditorNode::get_singleton()->show_warning("Package Installed Successfully!","Success!");
+ }
+
+
+
+
+}
+
+void EditorAssetInstaller::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_item_edited",&EditorAssetInstaller::_item_edited);
+
+}
+
+EditorAssetInstaller::EditorAssetInstaller() {
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+ add_child(vb);
+ set_child_rect(vb);
+
+ tree = memnew( Tree );
+ vb->add_margin_child("Package Contents:",tree,true);
+ tree->connect("item_edited",this,"_item_edited");
+
+ error = memnew( AcceptDialog) ;
+ add_child(error);
+ get_ok()->set_text("Install");
+ set_title("Package Installer");
+
+ updating=false;
+
+ set_hide_on_ok(true);
+}
+
diff --git a/tools/editor/editor_asset_installer.h b/tools/editor/editor_asset_installer.h
new file mode 100644
index 0000000000..713c5f14f1
--- /dev/null
+++ b/tools/editor/editor_asset_installer.h
@@ -0,0 +1,28 @@
+#ifndef EDITORASSETINSTALLER_H
+#define EDITORASSETINSTALLER_H
+
+
+#include "scene/gui/dialogs.h"
+#include "scene/gui/tree.h"
+class EditorAssetInstaller : public ConfirmationDialog {
+
+ OBJ_TYPE( EditorAssetInstaller, ConfirmationDialog );
+
+ Tree *tree;
+ String package_path;
+ AcceptDialog *error;
+ Map<String,TreeItem*> status_map;
+ bool updating;
+ void _update_subitems(TreeItem* p_item,bool p_check,bool p_first=false);
+ void _item_edited();
+ virtual void ok_pressed();
+protected:
+
+ static void _bind_methods();
+public:
+
+ void open(const String& p_path,int p_depth=0);
+ EditorAssetInstaller();
+};
+
+#endif // EDITORASSETINSTALLER_H
diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp
index c872b1c3ca..f78ab93c30 100644
--- a/tools/editor/editor_data.cpp
+++ b/tools/editor/editor_data.cpp
@@ -261,13 +261,13 @@ EditorPlugin* EditorData::get_subeditor(Object *p_object) {
}
EditorPlugin* EditorData::get_editor(String p_name) {
-
+
for(int i=0;i<editor_plugins.size();i++) {
-
+
if (editor_plugins[i]->get_name()==p_name)
return editor_plugins[i];
}
-
+
return NULL;
}
@@ -422,6 +422,14 @@ void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
editor_plugins.push_back(p_plugin);
}
+int EditorData::get_editor_plugin_count() const {
+ return editor_plugins.size();
+}
+EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
+
+ ERR_FAIL_INDEX_V(p_idx,editor_plugins.size(),NULL);
+ return editor_plugins[p_idx];
+}
void EditorData::add_custom_type(const String& p_type, const String& p_inherits,const Ref<Script>& p_script,const Ref<Texture>& p_icon ) {
@@ -791,6 +799,8 @@ void EditorSelection::_node_removed(Node *p_node) {
void EditorSelection::add_node(Node *p_node) {
+ ERR_FAIL_NULL(p_node);
+
if (selection.has(p_node))
return;
@@ -814,6 +824,8 @@ void EditorSelection::add_node(Node *p_node) {
void EditorSelection::remove_node(Node *p_node) {
+ ERR_FAIL_NULL(p_node);
+
if (!selection.has(p_node))
return;
@@ -832,12 +844,25 @@ bool EditorSelection::is_selected(Node * p_node) const {
}
+Array EditorSelection::_get_selected_nodes() {
+
+ Array ret;
+
+ for (List<Node*>::Element *E=selected_node_list.front();E;E=E->next()) {
+
+ ret.push_back(E->get());
+ }
+
+ return ret;
+}
void EditorSelection::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_node_removed"),&EditorSelection::_node_removed);
ObjectTypeDB::bind_method(_MD("clear"),&EditorSelection::clear);
- ObjectTypeDB::bind_method(_MD("add_node"),&EditorSelection::add_node);
+ ObjectTypeDB::bind_method(_MD("add_node","node:Node"),&EditorSelection::add_node);
+ ObjectTypeDB::bind_method(_MD("remove_node","node:Node"),&EditorSelection::remove_node);
+ ObjectTypeDB::bind_method(_MD("get_selected_nodes"),&EditorSelection::_get_selected_nodes);
ADD_SIGNAL( MethodInfo("selection_changed") );
}
diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h
index fcc8ccef06..5814ae8f5c 100644
--- a/tools/editor/editor_data.h
+++ b/tools/editor/editor_data.h
@@ -165,6 +165,9 @@ public:
void add_editor_plugin(EditorPlugin *p_plugin);
void remove_editor_plugin(EditorPlugin *p_plugin);
+ int get_editor_plugin_count() const;
+ EditorPlugin *get_editor_plugin(int p_idx);
+
UndoRedo &get_undo_redo();
void save_editor_global_states();
@@ -228,6 +231,7 @@ public:
List<Node*> selected_node_list;
void _update_nl();
+ Array _get_selected_nodes();
protected:
static void _bind_methods();
diff --git a/tools/editor/editor_file_dialog.cpp b/tools/editor/editor_file_dialog.cpp
index a9b23767f1..8e83726f96 100644
--- a/tools/editor/editor_file_dialog.cpp
+++ b/tools/editor/editor_file_dialog.cpp
@@ -273,13 +273,11 @@ void EditorFileDialog::_action_pressed() {
String f=dir_access->get_current_dir().plus_file(file->get_text());
- if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) {
+ if ((mode==MODE_OPEN_ANY || mode==MODE_OPEN_FILE) && dir_access->file_exists(f)) {
_save_to_recent();
emit_signal("file_selected",f);
hide();
- }
-
- if (mode==MODE_OPEN_DIR) {
+ }else if (mode==MODE_OPEN_ANY || mode==MODE_OPEN_DIR) {
String path=dir_access->get_current_dir();
@@ -413,7 +411,7 @@ void EditorFileDialog::_item_dc_selected(int p_item) {
//print_line("change dir: "+String(d["name"]));
dir_access->change_dir(d["name"]);
- if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
+ if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR || MODE_OPEN_ANY)
file->set_text("");
call_deferred("_update_file_list");
call_deferred("_update_dir");
@@ -590,7 +588,7 @@ void EditorFileDialog::update_file_list() {
if (get_icon_func) {
-
+
Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
//ti->set_icon(0,icon);
if (display_mode==DISPLAY_THUMBNAILS) {
@@ -771,8 +769,9 @@ void EditorFileDialog::set_mode(Mode p_mode) {
case MODE_OPEN_FILE: get_ok()->set_text("Open"); set_title("Open a File"); makedir->hide(); break;
case MODE_OPEN_FILES: get_ok()->set_text("Open"); set_title("Open File(s)"); makedir->hide(); break;
- case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
case MODE_OPEN_DIR: get_ok()->set_text("Open"); set_title("Open a Directory"); makedir->show(); break;
+ case MODE_OPEN_ANY: get_ok()->set_text("Open"); set_title("Open a File or Directory"); makedir->show(); break;
+ case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
}
if (mode==MODE_OPEN_FILES) {
@@ -1149,6 +1148,7 @@ void EditorFileDialog::_bind_methods() {
BIND_CONSTANT( MODE_OPEN_FILE );
BIND_CONSTANT( MODE_OPEN_FILES );
BIND_CONSTANT( MODE_OPEN_DIR );
+ BIND_CONSTANT( MODE_OPEN_ANY );
BIND_CONSTANT( MODE_SAVE_FILE );
BIND_CONSTANT( ACCESS_RESOURCES );
diff --git a/tools/editor/editor_file_dialog.h b/tools/editor/editor_file_dialog.h
index 3590964a51..d37856e556 100644
--- a/tools/editor/editor_file_dialog.h
+++ b/tools/editor/editor_file_dialog.h
@@ -66,7 +66,8 @@ public:
MODE_OPEN_FILE,
MODE_OPEN_FILES,
MODE_OPEN_DIR,
- MODE_SAVE_FILE,
+ MODE_OPEN_ANY,
+ MODE_SAVE_FILE
};
typedef Ref<Texture> (*GetIconFunc)(const String&);
diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp
index ad59efc46f..05e8a559b7 100644
--- a/tools/editor/editor_file_system.cpp
+++ b/tools/editor/editor_file_system.cpp
@@ -463,7 +463,7 @@ void EditorFileSystem::scan() {
filesystem=new_filesystem;
new_filesystem=NULL;
_update_scan_actions();
- scanning=false;
+ scanning=false;
emit_signal("filesystem_changed");
emit_signal("sources_changed",sources_changed.size()>0);
diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp
index 2ece518f8d..238b2d1cb8 100644
--- a/tools/editor/editor_help.cpp
+++ b/tools/editor/editor_help.cpp
@@ -405,29 +405,98 @@ void EditorHelpIndex::select_class(const String& p_class) {
class_list->ensure_cursor_is_visible();
}
+void EditorHelpIndex::popup() {
+
+ popup_centered_ratio(0.6);
+
+ search_box->set_text("");
+ _update_class_list();
+}
+
void EditorHelpIndex::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
- class_list->clear();
- tree_item_map.clear();
- TreeItem *root = class_list->create_item();
- class_list->set_hide_root(true);
+ _update_class_list();
+
connect("confirmed",this,"_tree_item_selected");
+ } else if (p_what==NOTIFICATION_POST_POPUP) {
+
+ search_box->call_deferred("grab_focus");
+ }
+}
+
+void EditorHelpIndex::_text_changed(const String& p_text) {
+
+ _update_class_list();
+}
+
+void EditorHelpIndex::_update_class_list() {
+
+ class_list->clear();
+ tree_item_map.clear();
+ TreeItem *root = class_list->create_item();
+ class_list->set_hide_root(true);
- for(Map<String,DocData::ClassDoc>::Element *E=EditorHelp::get_doc_data()->class_list.front();E;E=E->next()) {
+ String filter = search_box->get_text().strip_edges();
+ String to_select = "";
+ for(Map<String,DocData::ClassDoc>::Element *E=EditorHelp::get_doc_data()->class_list.front();E;E=E->next()) {
+ if (filter == "") {
add_type(E->key(),tree_item_map,root);
+ } else {
+
+ bool found = false;
+ String type = E->key();
+
+ while(type != "") {
+ if (type.findn(filter)!=-1) {
+
+ if (to_select.empty()) {
+ to_select = type;
+ }
+
+ found=true;
+ break;
+ }
+
+ type = EditorHelp::get_doc_data()->class_list[type].inherits;
+ }
+
+ if (found) {
+ add_type(E->key(),tree_item_map,root);
+ }
}
+ }
+ if (tree_item_map.has(filter)) {
+ select_class(filter);
+ } else if (to_select != "") {
+ select_class(to_select);
+ }
+}
+
+
+void EditorHelpIndex::_sbox_input(const InputEvent& p_ie) {
+
+ if (p_ie.type==InputEvent::KEY && (
+ p_ie.key.scancode == KEY_UP ||
+ p_ie.key.scancode == KEY_DOWN ||
+ p_ie.key.scancode == KEY_PAGEUP ||
+ p_ie.key.scancode == KEY_PAGEDOWN ) ) {
+
+ class_list->call("_input_event",p_ie);
+ search_box->accept_event();
}
}
void EditorHelpIndex::_bind_methods() {
ObjectTypeDB::bind_method("_tree_item_selected",&EditorHelpIndex::_tree_item_selected);
+ ObjectTypeDB::bind_method("_text_changed",&EditorHelpIndex::_text_changed);
+ ObjectTypeDB::bind_method("_sbox_input",&EditorHelpIndex::_sbox_input);
ObjectTypeDB::bind_method("select_class",&EditorHelpIndex::select_class);
ADD_SIGNAL( MethodInfo("open_class"));
}
@@ -436,19 +505,25 @@ void EditorHelpIndex::_bind_methods() {
EditorHelpIndex::EditorHelpIndex() {
-
VBoxContainer *vbc = memnew( VBoxContainer );
add_child(vbc);
set_child_rect(vbc);
+ search_box = memnew( LineEdit );
+ vbc->add_margin_child("Search:", search_box);
+ search_box->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ register_text_enter(search_box);
+
+ search_box->connect("text_changed", this, "_text_changed");
+ search_box->connect("input_event", this, "_sbox_input");
+
class_list = memnew( Tree );
- vbc->add_margin_child("Class List: ",class_list,true);
+ vbc->add_margin_child("Class List: ", class_list, true);
class_list->set_v_size_flags(SIZE_EXPAND_FILL);
-
class_list->connect("item_activated",this,"_tree_item_selected");
-
get_ok()->set_text("Open");
}
@@ -650,14 +725,64 @@ Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) {
class_desc->add_text("Inherits: ");
class_desc->pop();
class_desc->pop();
+
+ String inherits = cd.inherits;
+
class_desc->push_font(doc_font);
- _add_type(cd.inherits);
+
+ while (inherits != "") {
+ _add_type(inherits);
+
+ inherits = doc->class_list[inherits].inherits;
+
+ if (inherits != "") {
+ class_desc->add_text(" , ");
+ }
+ }
+
class_desc->pop();
class_desc->add_newline();
- class_desc->add_newline();
+ }
+
+ if (ObjectTypeDB::type_exists(cd.name)) {
+
+ bool found = false;
+ bool prev = false;
+
+ for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) {
+
+ if (E->get().inherits == cd.name) {
+
+ if (!found) {
+ class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
+ class_desc->push_font(doc_title_font);
+ class_desc->add_text("Inherited by: ");
+ class_desc->pop();
+ class_desc->pop();
+
+ found = true;
+ class_desc->push_font(doc_font);
+ }
+
+ if (prev) {
+
+ class_desc->add_text(" , ");
+ prev = false;
+ }
+
+ _add_type(E->get().name);
+ prev = true;
+ }
+ }
+
+ if (found)
+ class_desc->pop();
+ class_desc->add_newline();
}
+ class_desc->add_newline();
+
if (cd.brief_description!="") {
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
@@ -1123,35 +1248,87 @@ void EditorHelp::_add_text(const String& p_bbcode) {
class_desc->push_indent(1);*/
int pos = 0;
+ String bbcode=p_bbcode.replace("\t"," ").replace("\r"," ").strip_edges();
+
+ //find double newlines, keep them
+ for(int i=0;i<bbcode.length();i++) {
+
+ //find valid newlines (double)
+ if (bbcode[i]=='\n') {
+ bool dnl=false;
+ int j=i+1;
+ for(;j<p_bbcode.length();j++) {
+ if (bbcode[j]==' ')
+ continue;
+ if (bbcode[j]=='\n') {
+ dnl=true;
+ break;
+ }
+ break;
+ }
+
+ if (dnl) {
+ bbcode[i]=0xFFFF;
+ i=j;
+ } else {
+ bbcode[i]=' ';
+ i=j-1;
+ }
+ }
+ }
+
+ //remove double spaces or spaces after newlines
+ for(int i=0;i<bbcode.length();i++) {
+
+ if (bbcode[i]==' ' || bbcode[i]==0xFFFF) {
+
+ for(int j=i+1;j<p_bbcode.length();j++) {
+ if (bbcode[j]==' ') {
+ bbcode.remove(j);
+ j--;
+ continue;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ //change newlines to double newlines
+
+ CharType dnls[2]={0xFFFF,0};
+ bbcode=bbcode.replace(dnls,"\n");
+
+
List<String> tag_stack;
- while(pos < p_bbcode.length()) {
+ while(pos < bbcode.length()) {
- int brk_pos = p_bbcode.find("[",pos);
+ int brk_pos = bbcode.find("[",pos);
if (brk_pos<0)
- brk_pos=p_bbcode.length();
+ brk_pos=bbcode.length();
if (brk_pos > pos) {
- class_desc->add_text(p_bbcode.substr(pos,brk_pos-pos));
+ class_desc->add_text(bbcode.substr(pos,brk_pos-pos));
}
- if (brk_pos==p_bbcode.length())
+ if (brk_pos==bbcode.length())
break; //nothing else o add
- int brk_end = p_bbcode.find("]",brk_pos+1);
+ int brk_end = bbcode.find("]",brk_pos+1);
if (brk_end==-1) {
//no close, add the rest
- class_desc->add_text(p_bbcode.substr(brk_pos,p_bbcode.length()-brk_pos));
+ class_desc->add_text(bbcode.substr(brk_pos,bbcode.length()-brk_pos));
break;
}
- String tag = p_bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
+ String tag = bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
if (tag.begins_with("/")) {
@@ -1201,7 +1378,7 @@ void EditorHelp::_add_text(const String& p_bbcode) {
class_desc->push_font(get_font("italic","Fonts"));
pos=brk_end+1;
tag_stack.push_front(tag);
- } else if (tag=="code") {
+ } else if (tag=="code" || tag=="codeblock") {
//use monospace font
class_desc->push_font(get_font("source","EditorFonts"));
@@ -1234,10 +1411,10 @@ void EditorHelp::_add_text(const String& p_bbcode) {
} else if (tag=="url") {
//use strikethrough (not supported underline instead)
- int end=p_bbcode.find("[",brk_end);
+ int end=bbcode.find("[",brk_end);
if (end==-1)
- end=p_bbcode.length();
- String url = p_bbcode.substr(brk_end+1,end-brk_end-1);
+ end=bbcode.length();
+ String url = bbcode.substr(brk_end+1,end-brk_end-1);
class_desc->push_meta(url);
pos=brk_end+1;
@@ -1251,10 +1428,10 @@ void EditorHelp::_add_text(const String& p_bbcode) {
} else if (tag=="img") {
//use strikethrough (not supported underline instead)
- int end=p_bbcode.find("[",brk_end);
+ int end=bbcode.find("[",brk_end);
if (end==-1)
- end=p_bbcode.length();
- String image = p_bbcode.substr(brk_end+1,end-brk_end-1);
+ end=bbcode.length();
+ String image = bbcode.substr(brk_end+1,end-brk_end-1);
Ref<Texture> texture = ResourceLoader::load(base_path+"/"+image,"Texture");
if (texture.is_valid())
diff --git a/tools/editor/editor_help.h b/tools/editor/editor_help.h
index 059a7ae11d..f6dda9f545 100644
--- a/tools/editor/editor_help.h
+++ b/tools/editor/editor_help.h
@@ -77,11 +77,16 @@ public:
class EditorHelpIndex : public ConfirmationDialog {
OBJ_TYPE( EditorHelpIndex, ConfirmationDialog );
-
+ LineEdit *search_box;
Tree *class_list;
HashMap<String,TreeItem*> tree_item_map;
void _tree_item_selected();
+ void _text_changed(const String& p_text);
+ void _sbox_input(const InputEvent& p_ie);
+
+ void _update_class_list();
+
void add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem *p_root);
protected:
@@ -92,6 +97,8 @@ public:
void select_class(const String& p_class);
+ void popup();
+
EditorHelpIndex();
};
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index 77331256f3..e02ffd337b 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -63,13 +63,30 @@ String EditorImportPlugin::expand_source_path(const String& p_path) {
}
}
+
+String EditorImportPlugin::_validate_source_path(const String& p_path) {
+
+ return validate_source_path(p_path);
+}
+
+String EditorImportPlugin::_expand_source_path(const String& p_path) {
+
+ return expand_source_path(p_path);
+}
+
void EditorImportPlugin::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("validate_source_path","path"),&EditorImportPlugin::_validate_source_path);
+ ObjectTypeDB::bind_method(_MD("expand_source_path","path"),&EditorImportPlugin::_expand_source_path);
+
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_visible_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from")));
- ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetaData")));
- ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path")));
+ ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata")));
+ ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform")));
+
+// BIND_VMETHOD( mi );
}
String EditorImportPlugin::get_name() const {
@@ -113,8 +130,8 @@ Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportM
Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) {
- if (get_script_instance() && get_script_instance()->has_method("custom_export")) {
- get_script_instance()->call("custom_export",p_path);
+ if (get_script_instance() && get_script_instance()->has_method("_custom_export")) {
+ get_script_instance()->call("_custom_export",p_path,p_platform);
}
return Vector<uint8_t>();
@@ -130,7 +147,10 @@ EditorImportPlugin::EditorImportPlugin() {
void EditorExportPlugin::_bind_methods() {
- BIND_VMETHOD( MethodInfo("custom_export:Dictionary",PropertyInfo(Variant::STRING,"name",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatformPC")) );
+ MethodInfo mi = MethodInfo("custom_export:Variant",PropertyInfo(Variant::STRING,"name"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"));
+ mi.return_val.type=Variant::RAW_ARRAY;
+
+ BIND_VMETHOD( mi );
}
@@ -141,6 +161,9 @@ Vector<uint8_t> EditorExportPlugin::custom_export(String& p_path,const Ref<Edito
Variant d = get_script_instance()->call("custom_export",p_path,p_platform);
if (d.get_type()==Variant::NIL)
return Vector<uint8_t>();
+ if (d.get_type()==Variant::RAW_ARRAY)
+ return d;
+
ERR_FAIL_COND_V(d.get_type()!=Variant::DICTIONARY,Vector<uint8_t>());
Dictionary dict=d;
ERR_FAIL_COND_V(!dict.has("name"),Vector<uint8_t>());
@@ -162,6 +185,7 @@ EditorExportPlugin::EditorExportPlugin() {
/////////////////////////////////////////////////////////////////////////////////////////////////////
+
static void _add_to_list(EditorFileSystemDirectory *p_efsd,Set<StringName>& r_list) {
for(int i=0;i<p_efsd->get_subdir_count();i++) {
@@ -170,13 +194,11 @@ static void _add_to_list(EditorFileSystemDirectory *p_efsd,Set<StringName>& r_li
}
for(int i=0;i<p_efsd->get_file_count();i++) {
-
r_list.insert(p_efsd->get_file_path(i));
}
}
-
struct __EESortDepCmp {
_FORCE_INLINE_ bool operator()(const StringName& p_l,const StringName& p_r) const {
@@ -187,7 +209,7 @@ struct __EESortDepCmp {
-static void _add_files_with_filter(DirAccess *da,const List<String>& p_filters,Set<StringName>& r_list) {
+static void _edit_files_with_filter(DirAccess *da,const List<String>& p_filters,Set<StringName>& r_list,bool exclude) {
List<String> files;
@@ -218,8 +240,17 @@ static void _add_files_with_filter(DirAccess *da,const List<String>& p_filters,S
for(const List<String>::Element *F=p_filters.front();F;F=F->next()) {
if (fullpath.matchn(F->get())) {
- r_list.insert(fullpath);
- print_line("Added: "+fullpath);
+ String act = "Added: ";
+
+ if (!exclude) {
+ r_list.insert(fullpath);
+ } else {
+ act = "Removed: ";
+ r_list.erase(fullpath);
+ }
+
+
+ print_line(act+fullpath);
}
}
}
@@ -230,13 +261,13 @@ static void _add_files_with_filter(DirAccess *da,const List<String>& p_filters,S
if (E->get().begins_with("."))
continue;
da->change_dir(E->get());
- _add_files_with_filter(da,p_filters,r_list);
+ _edit_files_with_filter(da,p_filters,r_list,exclude);
da->change_dir("..");
}
}
-static void _add_filter_to_list(Set<StringName>& r_list,const String& p_filter) {
+static void _edit_filter_list(Set<StringName>& r_list,const String& p_filter,bool exclude) {
if (p_filter=="")
return;
@@ -250,11 +281,17 @@ static void _add_filter_to_list(Set<StringName>& r_list,const String& p_filter)
}
DirAccess *da = DirAccess::open("res://");
- _add_files_with_filter(da,filters,r_list);
+ ERR_FAIL_NULL(da);
+ _edit_files_with_filter(da,filters,r_list,exclude);
memdelete(da);
+}
+static void _add_filter_to_list(Set<StringName>& r_list,const String& p_filter) {
+ _edit_filter_list(r_list,p_filter,false);
+}
-
+static void _remove_filter_from_list(Set<StringName>& r_list,const String& p_filter) {
+ _edit_filter_list(r_list,p_filter,true);
}
Vector<uint8_t> EditorExportPlatform::get_exported_file_default(String& p_fname) const {
@@ -307,6 +344,8 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
cf+="*.flags";
_add_filter_to_list(exported,cf);
+ cf = EditorImportExport::get_singleton()->get_export_custom_filter_exclude();
+ _remove_filter_from_list(exported,cf);
}
@@ -380,6 +419,9 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
cf+="*.flags";
_add_filter_to_list(exported,cf);
+ cf = EditorImportExport::get_singleton()->get_export_custom_filter_exclude();
+ _remove_filter_from_list(exported,cf);
+
}
@@ -630,7 +672,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
} break; //use default
case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: {
group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM;
- } break; //use default
+ } break; //use default
}
String image_list_md5;
@@ -1437,9 +1479,17 @@ Ref<EditorImportPlugin> EditorImportExport::get_import_plugin_by_name(const Stri
void EditorImportExport::add_export_plugin(const Ref<EditorExportPlugin>& p_plugin) {
+ ERR_FAIL_COND( p_plugin.is_null() );
+
export_plugins.push_back(p_plugin);
}
+void EditorImportExport::remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin) {
+
+ ERR_FAIL_COND( p_plugin.is_null() );
+ export_plugins.erase(p_plugin);
+}
+
int EditorImportExport::get_export_plugin_count() const{
return export_plugins.size();
@@ -1530,13 +1580,17 @@ EditorImportExport::ExportFilter EditorImportExport::get_export_filter() const{
}
void EditorImportExport::set_export_custom_filter(const String& p_custom_filter){
-
export_custom_filter=p_custom_filter;
}
+void EditorImportExport::set_export_custom_filter_exclude(const String& p_custom_filter){
+ export_custom_filter_exclude=p_custom_filter;
+}
String EditorImportExport::get_export_custom_filter() const{
-
return export_custom_filter;
}
+String EditorImportExport::get_export_custom_filter_exclude() const{
+ return export_custom_filter_exclude;
+}
void EditorImportExport::set_export_image_action(ImageAction p_action) {
@@ -1699,6 +1753,7 @@ void EditorImportExport::load_config() {
export_custom_filter=cf->get_value("export_filter","filter");
+ export_custom_filter_exclude=cf->get_value("export_filter","filter_exclude");
String t=cf->get_value("export_filter","type");
if (t=="selected")
export_filter=EXPORT_SELECTED;
@@ -1888,6 +1943,7 @@ void EditorImportExport::save_config() {
}
cf->set_value("export_filter","filter",export_custom_filter);
+ cf->set_value("export_filter", "filter_exclude",export_custom_filter_exclude);
String file_action_section = "export_filter_files";
@@ -2044,9 +2100,61 @@ bool EditorImportExport::sample_get_trim() const{
return sample_action_trim;
}
+DVector<String> EditorImportExport::_get_export_file_list() {
+
+ DVector<String> fl;
+ for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) {
+
+ fl.push_back(E->key());
+ }
+
+ return fl;
+}
+
+DVector<String> EditorImportExport::_get_export_platforms() {
+
+ DVector<String> ep;
+ for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) {
+
+ ep.push_back(E->key());
+ }
+
+ return ep;
+
+}
void EditorImportExport::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("add_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::add_import_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::remove_import_plugin);
+ ObjectTypeDB::bind_method(_MD("get_import_plugin_count"),&EditorImportExport::get_import_plugin_count);
+ ObjectTypeDB::bind_method(_MD("get_import_plugin:EditorImportPlugin","idx"),&EditorImportExport::get_import_plugin);
+ ObjectTypeDB::bind_method(_MD("get_import_plugin_by_name:EditorImportPlugin","name"),&EditorImportExport::get_import_plugin_by_name);
+
+ ObjectTypeDB::bind_method(_MD("add_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::add_export_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::remove_export_plugin);
+ ObjectTypeDB::bind_method(_MD("get_export_plugin_count"),&EditorImportExport::get_export_plugin_count);
+ ObjectTypeDB::bind_method(_MD("get_export_plugin:EditorExportPlugin","idx"),&EditorImportExport::get_export_plugin);
+
+ ObjectTypeDB::bind_method(_MD("set_export_file_action","file","action"),&EditorImportExport::set_export_file_action);
+ ObjectTypeDB::bind_method(_MD("get_export_file_action","file"),&EditorImportExport::get_export_file_action);
+ ObjectTypeDB::bind_method(_MD("get_export_file_list"),&EditorImportExport::_get_export_file_list);
+
+ ObjectTypeDB::bind_method(_MD("add_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform);
+ //ObjectTypeDB::bind_method(_MD("remove_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform);
+ ObjectTypeDB::bind_method(_MD("get_export_platform:EditorExportPlatform","name"),&EditorImportExport::get_export_platform);
+ ObjectTypeDB::bind_method(_MD("get_export_platforms"),&EditorImportExport::_get_export_platforms);
+
+ ObjectTypeDB::bind_method(_MD("set_export_filter","filter"),&EditorImportExport::set_export_filter);
+ ObjectTypeDB::bind_method(_MD("get_export_filter"),&EditorImportExport::get_export_filter);
+
+ ObjectTypeDB::bind_method(_MD("set_export_custom_filter","filter"),&EditorImportExport::set_export_custom_filter);
+ ObjectTypeDB::bind_method(_MD("get_export_custom_filter"),&EditorImportExport::get_export_custom_filter);
+
+ ObjectTypeDB::bind_method(_MD("set_export_custom_filter_exclude","filter_exclude"),&EditorImportExport::set_export_custom_filter_exclude);
+ ObjectTypeDB::bind_method(_MD("get_export_custom_filter_exclude"),&EditorImportExport::get_export_custom_filter_exclude);
+
+
ObjectTypeDB::bind_method(_MD("image_export_group_create"),&EditorImportExport::image_export_group_create);
ObjectTypeDB::bind_method(_MD("image_export_group_remove"),&EditorImportExport::image_export_group_remove);
ObjectTypeDB::bind_method(_MD("image_export_group_set_image_action"),&EditorImportExport::image_export_group_set_image_action);
@@ -2061,7 +2169,27 @@ void EditorImportExport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("script_get_action"),&EditorImportExport::script_get_action);
ObjectTypeDB::bind_method(_MD("script_get_encryption_key"),&EditorImportExport::script_get_encryption_key);
-}
+
+
+ BIND_CONSTANT( ACTION_NONE );
+ BIND_CONSTANT( ACTION_COPY );
+ BIND_CONSTANT( ACTION_BUNDLE );
+
+ BIND_CONSTANT( EXPORT_SELECTED );
+ BIND_CONSTANT( EXPORT_RESOURCES );
+ BIND_CONSTANT( EXPORT_ALL );
+
+ BIND_CONSTANT( IMAGE_ACTION_NONE );
+ BIND_CONSTANT( IMAGE_ACTION_COMPRESS_DISK );
+ BIND_CONSTANT( IMAGE_ACTION_COMPRESS_RAM );
+ BIND_CONSTANT( IMAGE_ACTION_KEEP );
+
+ BIND_CONSTANT( SCRIPT_ACTION_NONE );
+ BIND_CONSTANT( SCRIPT_ACTION_COMPILE );
+ BIND_CONSTANT( SCRIPT_ACTION_ENCRYPT );
+};
+
+
EditorImportExport::EditorImportExport() {
@@ -2090,5 +2218,3 @@ EditorImportExport::~EditorImportExport() {
}
-
-
diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h
index 272464d9b0..fc8ad58bd9 100644
--- a/tools/editor/editor_import_export.h
+++ b/tools/editor/editor_import_export.h
@@ -46,6 +46,10 @@ protected:
static void _bind_methods();
+ String _validate_source_path(const String& p_path);
+ String _expand_source_path(const String& p_path);
+
+
public:
@@ -285,7 +289,7 @@ protected:
Set<String> image_formats;
ExportFilter export_filter;
- String export_custom_filter;
+ String export_custom_filter, export_custom_filter_exclude;
Map<StringName,FileAction> files;
Map<StringName,Ref<EditorExportPlatform> > exporters;
Map<StringName,ImageGroup> image_groups;
@@ -303,6 +307,9 @@ protected:
static EditorImportExport* singleton;
+ DVector<String> _get_export_file_list();
+ DVector<String> _get_export_platforms();
+
static void _bind_methods();
public:
@@ -315,6 +322,7 @@ public:
Ref<EditorImportPlugin> get_import_plugin_by_name(const String& p_string) const;
void add_export_plugin(const Ref<EditorExportPlugin>& p_plugin);
+ void remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin);
int get_export_plugin_count() const;
Ref<EditorExportPlugin> get_export_plugin(int p_idx) const;
@@ -332,7 +340,9 @@ public:
ExportFilter get_export_filter() const;
void set_export_custom_filter(const String& p_custom_filter);
+ void set_export_custom_filter_exclude(const String& p_custom_filter);
String get_export_custom_filter() const;
+ String get_export_custom_filter_exclude() const;
void set_export_image_action(ImageAction p_action);
ImageAction get_export_image_action() const;
@@ -389,7 +399,10 @@ public:
~EditorImportExport();
};
+VARIANT_ENUM_CAST(EditorImportExport::FileAction);
+VARIANT_ENUM_CAST(EditorImportExport::ExportFilter);
VARIANT_ENUM_CAST(EditorImportExport::ImageAction);
VARIANT_ENUM_CAST(EditorImportExport::ScriptAction);
+VARIANT_ENUM_CAST(EditorImportExport::SampleAction);
#endif // EDITOR_IMPORT_EXPORT_H
diff --git a/tools/editor/editor_initialize_ssl.cpp b/tools/editor/editor_initialize_ssl.cpp
new file mode 100644
index 0000000000..e0602a88c7
--- /dev/null
+++ b/tools/editor/editor_initialize_ssl.cpp
@@ -0,0 +1,21 @@
+#include "editor_initialize_ssl.h"
+#include "certs_compressed.h"
+#include "io/stream_peer_ssl.h"
+#include "io/compression.h"
+
+void editor_initialize_certificates() {
+
+
+ ByteArray data;
+ data.resize(_certs_uncompressed_size);
+ {
+ ByteArray::Write w = data.write();
+ Compression::decompress(w.ptr(),_certs_uncompressed_size,_certs_compressed,_certs_compressed_size,Compression::MODE_DEFLATE);
+ }
+
+ StreamPeerSSL::load_certs_from_memory(data);
+
+
+}
+
+
diff --git a/tools/editor/editor_initialize_ssl.h b/tools/editor/editor_initialize_ssl.h
new file mode 100644
index 0000000000..4eaf387a0a
--- /dev/null
+++ b/tools/editor/editor_initialize_ssl.h
@@ -0,0 +1,6 @@
+#ifndef EDITOR_INITIALIZE_SSL_H
+#define EDITOR_INITIALIZE_SSL_H
+
+void editor_initialize_certificates();
+
+#endif // EDITOR_INITIALIZE_SSL_H
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 1abcb8f604..02b0e9447a 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -61,6 +61,7 @@
#include "plugins/sprite_frames_editor_plugin.h"
#include "plugins/sprite_region_editor_plugin.h"
#include "plugins/canvas_item_editor_plugin.h"
+#include "addon_editor_plugin.h"
#include "plugins/spatial_editor_plugin.h"
#include "plugins/sample_editor_plugin.h"
#include "plugins/sample_library_editor_plugin.h"
@@ -106,7 +107,7 @@
#include "tools/editor/io_plugins/editor_export_scene.h"
#include "plugins/editor_preview_plugins.h"
-
+#include "editor_initialize_ssl.h"
#include "script_editor_debugger.h"
EditorNode *EditorNode::singleton=NULL;
@@ -204,8 +205,8 @@ void EditorNode::_notification(int p_what) {
log->deinit(); // do not get messages anymore
}
if (p_what==NOTIFICATION_PROCESS) {
-
- //force the whole tree viewport
+
+ //force the whole tree viewport
#if 0
{
Rect2 grect = scene_root_base->get_global_rect();
@@ -274,13 +275,13 @@ void EditorNode::_notification(int p_what) {
}
}
-
+
}
if (p_what==NOTIFICATION_ENTER_TREE) {
//MessageQueue::get_singleton()->push_call(this,"_get_scene_metadata");
- get_tree()->set_editor_hint(true);
+ get_tree()->set_editor_hint(true);
get_tree()->get_root()->set_as_audio_listener(false);
get_tree()->get_root()->set_as_audio_listener_2d(false);
get_tree()->set_auto_accept_quit(false);
@@ -328,12 +329,14 @@ void EditorNode::_notification(int p_what) {
}
*/
+ /* // moved to "_sources_changed"
if (export_defer.platform!="") {
project_export_settings->export_platform(export_defer.platform,export_defer.path,export_defer.debug,export_defer.password,true);
export_defer.platform="";
}
+ */
}
if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
@@ -378,6 +381,10 @@ void EditorNode::_notification(int p_what) {
_menu_option_confirm(FILE_QUIT, false);
};
+ if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ scene_tabs->set_tab_close_display_policy( (bool(EDITOR_DEF("global/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY) );
+ }
+
}
void EditorNode::_fs_changed() {
@@ -391,6 +398,13 @@ void EditorNode::_fs_changed() {
E->get()->invalidate();
}
+
+ if (export_defer.platform!="") {
+
+ project_export_settings->export_platform(export_defer.platform,export_defer.path,export_defer.debug,export_defer.password,true);
+ export_defer.platform="";
+ }
+
}
void EditorNode::_sources_changed(bool p_exist) {
@@ -406,6 +420,7 @@ void EditorNode::_sources_changed(bool p_exist) {
sources_button->set_disabled(true);
}
+
}
void EditorNode::_vp_resized() {
@@ -554,12 +569,12 @@ void EditorNode::save_resource_as(const Ref<Resource>& p_resource) {
void EditorNode::_menu_option(int p_option) {
-
+
_menu_option_confirm(p_option,false);
}
void EditorNode::_menu_confirm_current() {
-
+
_menu_option_confirm(current_option,true);
}
@@ -568,27 +583,27 @@ void EditorNode::_dialog_display_file_error(String p_file,Error p_error) {
if (p_error) {
-
+
current_option=-1;
//accept->"()->hide();
accept->get_ok()->set_text("I see..");
-
+
switch(p_error) {
-
+
case ERR_FILE_CANT_WRITE: {
accept->set_text("Can't open file for writing: "+p_file.extension());
} break;
case ERR_FILE_UNRECOGNIZED: {
-
+
accept->set_text("File format requested unknown: "+p_file.extension());
} break;
default: {
-
+
accept->set_text("Error Saving.");
}break;
}
-
+
accept->popup_centered_minsize();
}
@@ -966,11 +981,6 @@ void EditorNode::_save_scene(String p_file) {
editor_data.apply_changes_in_editors();
- if (editor_plugin_screen) {
- scene->set_meta("__editor_plugin_screen__",editor_plugin_screen->get_name());
- }
-
-
_set_scene_metadata(p_file);
@@ -1134,10 +1144,10 @@ void EditorNode::_import(const String &p_file) {
}
void EditorNode::_dialog_action(String p_file) {
-
+
switch(current_option) {
-
+
case RESOURCE_LOAD: {
RES res = ResourceLoader::load(p_file);
@@ -1152,7 +1162,7 @@ void EditorNode::_dialog_action(String p_file) {
push_item(res.operator->() );
- } break;
+ } break;
case FILE_NEW_INHERITED_SCENE: {
@@ -1257,23 +1267,20 @@ void EditorNode::_dialog_action(String p_file) {
if (FileAccess::exists(p_file)) {
ml=ResourceLoader::load(p_file,"TileSet");
- if (!file_export_lib_merge->is_pressed()) {
+ if (ml.is_null()) {
+ if (file_export_lib_merge->is_pressed()) {
+ current_option=-1;
+ //accept->get_cancel()->hide();
+ accept->get_ok()->set_text("I see..");
+ accept->set_text("Can't load TileSet for merging!.");
+ accept->popup_centered_minsize();
+ return;
+ }
+ } else if (!file_export_lib_merge->is_pressed()) {
ml->clear();
}
- }
-
- if (ml.is_null()) {
-
- if (file_export_lib_merge->is_pressed()) {
- current_option=-1;
- //accept->get_cancel()->hide();
- accept->get_ok()->set_text("I see..");
- accept->set_text("Can't load TileSet for merging!.");
- accept->popup_centered_minsize();
- return;
- }
-
+ } else {
ml = Ref<TileSet>( memnew( TileSet ));
}
@@ -1438,13 +1445,13 @@ void EditorNode::_dialog_action(String p_file) {
} break;
default: { //save scene?
-
+
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
//_save_scene(p_file);
_save_scene_with_preview(p_file);
}
-
+
} break;
}
}
@@ -1538,13 +1545,13 @@ void EditorNode::_property_editor_forward() {
if (editor_history.next())
_edit_current();
-
+
}
void EditorNode::_property_editor_back() {
-
+
if (editor_history.previous())
_edit_current();
-
+
}
@@ -1574,7 +1581,7 @@ void EditorNode::_hide_top_editors() {
}
void EditorNode::_edit_current() {
-
+
uint32_t current = editor_history.get_current();
Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
@@ -1586,7 +1593,7 @@ void EditorNode::_edit_current() {
if (!current_obj) {
-
+
scene_tree_dock->set_selected(NULL);
property_editor->edit( NULL );
object_menu->set_disabled(true);
@@ -1760,7 +1767,7 @@ void EditorNode::_resource_created() {
}
void EditorNode::_resource_selected(const RES& p_res,const String& p_property) {
-
+
if (p_res.is_null())
return;
@@ -1785,6 +1792,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
//pause_button->set_pressed(false);
play_scene_button->set_pressed(false);
play_scene_button->set_icon(gui_base->get_icon("PlayScene","EditorIcons"));
+ play_custom_scene_button->set_pressed(false);
+ play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom","EditorIcons"));
String current_filename;
String run_filename;
@@ -1794,7 +1803,6 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
if (p_current || (editor_data.get_edited_scene_root() && p_custom==editor_data.get_edited_scene_root()->get_filename())) {
-
Node *scene = editor_data.get_edited_scene_root();
if (!scene) {
@@ -1903,6 +1911,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
if (p_current) {
play_scene_button->set_pressed(true);
play_scene_button->set_icon(gui_base->get_icon("Reload","EditorIcons"));
+ } else if (p_custom!="") {
+ run_custom_filename=run_filename;
+ play_custom_scene_button->set_pressed(true);
+ play_custom_scene_button->set_icon(gui_base->get_icon("Reload","EditorIcons"));
} else {
play_button->set_pressed(true);
play_button->set_icon(gui_base->get_icon("Reload","EditorIcons"));
@@ -1948,13 +1960,13 @@ void EditorNode::_cleanup_scene() {
}
}
-
+
_update_title();
#endif
}
void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
-
+
//print_line("option "+itos(p_option)+" confirm "+itos(p_confirmed));
if (!p_confirmed) //this may be a hack..
current_option=(MenuOptions)p_option;
@@ -1979,12 +1991,12 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
//_cleanup_scene();
-
+
} break;
case FILE_NEW_INHERITED_SCENE:
case FILE_OPEN_SCENE: {
-
-
+
+
//print_tree();
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
//not for now?
@@ -1992,10 +2004,10 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
file->clear_filters();
for(int i=0;i<extensions.size();i++) {
-
+
file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
}
-
+
//file->set_current_path(current_path);
Node *scene = editor_data.get_edited_scene_root();
@@ -2004,7 +2016,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
};
file->set_title(p_option==FILE_OPEN_SCENE?"Open Scene":"Open Base Scene");
file->popup_centered_ratio();
-
+
} break;
case FILE_QUICK_OPEN_SCENE: {
@@ -2071,19 +2083,19 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
// fallthrough to save_as
};
case FILE_SAVE_AS_SCENE: {
-
+
Node *scene = editor_data.get_edited_scene_root();
-
+
if (!scene) {
-
+
current_option=-1;
//confirmation->get_cancel()->hide();
accept->get_ok()->set_text("I see..");
accept->set_text("This operation can't be done without a tree root.");
accept->popup_centered_minsize();
- break;
+ break;
}
-
+
file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool());
@@ -2096,7 +2108,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
}
-
+
//file->set_current_path(current_path);
if (scene->get_filename()!="") {
file->set_current_path(scene->get_filename());
@@ -2117,7 +2129,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
}
file->popup_centered_ratio();
file->set_title("Save Scene As..");
-
+
} break;
case FILE_SAVE_BEFORE_RUN: {
@@ -2297,7 +2309,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case FILE_QUIT: {
-
+
if (!p_confirmed) {
@@ -2311,7 +2323,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
_menu_option_confirm(RUN_STOP,true);
get_tree()->quit();
-
+
} break;
case FILE_EXTERNAL_OPEN_SCENE: {
@@ -2520,13 +2532,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case OBJECT_COPY_PARAMS: {
-
+
editor_data.apply_changes_in_editors();;
if (current)
editor_data.copy_object_params(current);
} break;
case OBJECT_PASTE_PARAMS: {
-
+
editor_data.apply_changes_in_editors();;
if (current)
editor_data.paste_object_params(current);
@@ -2574,7 +2586,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case OBJECT_CALL_METHOD: {
-
+
editor_data.apply_changes_in_editors();;
call_dialog->set_object(current);
call_dialog->popup_centered_ratio();
@@ -2585,9 +2597,16 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case RUN_PLAY_CUSTOM_SCENE: {
- _menu_option_confirm(RUN_STOP,true);
- quick_run->popup("PackedScene",true);
- quick_run->set_title("Quick Run Scene..");
+ if (run_custom_filename.empty() || editor_run.get_status()==EditorRun::STATUS_STOP) {
+ _menu_option_confirm(RUN_STOP,true);
+ quick_run->popup("PackedScene",true);
+ quick_run->set_title("Quick Run Scene..");
+ play_custom_scene_button->set_pressed(false);
+ } else {
+ String last_custom_scene=run_custom_filename;
+ _menu_option_confirm(RUN_STOP,true);
+ _run(false,last_custom_scene);
+ }
} break;
case RUN_PAUSE: {
@@ -2601,10 +2620,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
break;
editor_run.stop();
+ run_custom_filename.clear();
play_button->set_pressed(false);
play_button->set_icon(gui_base->get_icon("MainPlay","EditorIcons"));
play_scene_button->set_pressed(false);
play_scene_button->set_icon(gui_base->get_icon("PlayScene","EditorIcons"));
+ play_custom_scene_button->set_pressed(false);
+ play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom","EditorIcons"));
//pause_button->set_pressed(false);
emit_signal("stop_pressed");
@@ -2642,8 +2664,9 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
String exec = OS::get_singleton()->get_executable_path();
List<String> args;
- args.push_back ( "-path" );
- args.push_back (exec.get_base_dir() );
+ //args.push_back ( "-path" );
+ //args.push_back (exec.get_base_dir() );
+ args.push_back("-pm");
OS::ProcessID pid=0;
Error err = OS::get_singleton()->execute(exec,args,false,&pid);
@@ -2808,7 +2831,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
default: {
-
+
if (p_option>=OBJECT_METHOD_BASE) {
ERR_FAIL_COND(!current);
@@ -2832,12 +2855,12 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
}
}
- }
+ }
}
Control* EditorNode::get_viewport() {
-
+
return viewport;
}
@@ -2882,7 +2905,7 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor) {
if (p_editor->has_main_screen()) {
-
+
ToolButton *tb = memnew( ToolButton );
tb->set_toggle_mode(true);
tb->connect("pressed",singleton,"_editor_select",varray(singleton->main_editor_buttons.size()));
@@ -2922,16 +2945,109 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
void EditorNode::add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
+ ERR_FAIL_COND( p_editor_import.is_null() );
editor_import_export->add_import_plugin(p_editor_import);
_rebuild_import_menu();
}
void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
+ ERR_FAIL_COND( p_editor_import.is_null() );
editor_import_export->remove_import_plugin(p_editor_import);
_rebuild_import_menu();
}
+
+void EditorNode::_update_addon_config() {
+
+ if (_initializing_addons)
+ return;
+
+ Vector<String> enabled_addons;
+
+ for(Map<String,EditorPlugin*>::Element *E=plugin_addons.front();E;E=E->next()) {
+ enabled_addons.push_back(E->key());
+ }
+
+ if (enabled_addons.size()==0) {
+ Globals::get_singleton()->set("editor_plugins/enabled",Variant());
+ Globals::get_singleton()->set_persisting("editor_plugins/enabled",false);
+ } else {
+ Globals::get_singleton()->set("editor_plugins/enabled",enabled_addons);
+ Globals::get_singleton()->set_persisting("editor_plugins/enabled",true);
+ }
+
+ project_settings->queue_save();
+
+}
+
+void EditorNode::set_addon_plugin_enabled(const String& p_addon,bool p_enabled) {
+
+ ERR_FAIL_COND(p_enabled && plugin_addons.has(p_addon));
+ ERR_FAIL_COND(!p_enabled && !plugin_addons.has(p_addon));
+
+ if (!p_enabled) {
+
+ EditorPlugin *addon = plugin_addons[p_addon];
+ memdelete(addon); //bye
+ plugin_addons.erase(p_addon);
+ _update_addon_config();
+ return;
+ }
+
+
+ Ref<ConfigFile> cf;
+ cf.instance();
+ String addon_path = "res://addons/"+p_addon+"/plugin.cfg";
+ Error err = cf->load(addon_path);
+ if (err!=OK) {
+ show_warning("Unable to enable addon plugin at: '"+addon_path+"' parsing of config failed.");
+ return;
+ }
+
+ if (!cf->has_section_key("plugin","script")) {
+ show_warning("Unable to find script field for addon plugin at: 'res://addons/"+p_addon+"''.");
+ return;
+ }
+
+ String path = cf->get_value("plugin","script");
+ path="res://addons/"+p_addon+"/"+path;
+
+ Ref<Script> script = ResourceLoader::load(path);
+
+
+ if (script.is_null()) {
+ show_warning("Unable to load addon script from path: '"+path+"'.");
+ return;
+ }
+
+ //could check inheritance..
+ if (String(script->get_instance_base_type())!="EditorPlugin") {
+ show_warning("Unable to load addon script from path: '"+path+"' Base type is not EditorPlugin.");
+ return;
+ }
+
+ if (!script->is_tool()) {
+ show_warning("Unable to load addon script from path: '"+path+"' Script is does not support tool mode.");
+ return;
+ }
+
+ EditorPlugin *ep = memnew( EditorPlugin );
+ ep->set_script(script.get_ref_ptr());
+ plugin_addons[p_addon]=ep;
+ add_editor_plugin(ep);
+
+ _update_addon_config();
+
+
+}
+
+bool EditorNode::is_addon_plugin_enabled(const String& p_addon) const {
+
+ return plugin_addons.has(p_addon);
+}
+
+
void EditorNode::_remove_edited_scene() {
int new_index = editor_data.get_edited_scene();
int old_index=new_index;
@@ -2977,9 +3093,9 @@ void EditorNode::set_edited_scene(Node *p_scene) {
if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root)
scene_root->remove_child(get_editor_data().get_edited_scene_root());
- }
+ }
get_editor_data().set_edited_scene_root(p_scene);
-
+
if (p_scene && p_scene->cast_to<Popup>())
p_scene->cast_to<Popup>()->show(); //show popups
scene_tree_dock->set_edited_scene(p_scene);
@@ -3548,7 +3664,7 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bo
if (p_set_inherited) {
Ref<SceneState> state = sdata->get_state();
- state->set_path(lpath);
+ state->set_path(lpath);
new_scene->set_scene_inherited_state(state);
new_scene->set_filename(String());
//if (new_scene->get_scene_instance_state().is_valid())
@@ -3568,26 +3684,12 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bo
*/
editor_data.set_edited_scene_import_metadata( sdata->get_import_metadata() );
-
// editor_data.get_undo_redo().clear_history();
saved_version=editor_data.get_undo_redo().get_version();
_update_title();
_update_scene_tabs();
_add_to_recent_scenes(lpath);
- if (new_scene->has_meta("__editor_plugin_screen__")) {
-
- String editor = new_scene->get_meta("__editor_plugin_screen__");
-
- for(int i=0;i<editor_table.size();i++) {
-
- if (editor_table[i]->get_name()==editor) {
- _editor_select(i);
- break;
- }
- }
- }
-
prev_scene->set_disabled(previous_scenes.size()==0);
opening_prev=false;
@@ -3699,7 +3801,7 @@ void EditorNode::animation_editor_make_visible(bool p_visible) {
if (p_visible) {
- animation_editor->show();
+ animation_editor->show();
animation_vb->get_parent_control()->minimum_size_changed();
//pd_anim->show();
top_split->set_collapsed(false);
@@ -3833,9 +3935,9 @@ void EditorNode::_quick_opened() {
}
}
-void EditorNode::_quick_run(const String& p_resource) {
+void EditorNode::_quick_run() {
- _run(false,p_resource);
+ _run(false,quick_run->get_selected());
}
@@ -3920,10 +4022,14 @@ void EditorNode::register_editor_types() {
ObjectTypeDB::register_type<EditorPlugin>();
ObjectTypeDB::register_type<EditorImportPlugin>();
+ ObjectTypeDB::register_type<EditorExportPlugin>();
ObjectTypeDB::register_type<EditorScenePostImport>();
ObjectTypeDB::register_type<EditorScript>();
+ ObjectTypeDB::register_type<EditorSelection>();
ObjectTypeDB::register_type<EditorFileDialog>();
- ObjectTypeDB::register_type<UndoRedo>();
+ //ObjectTypeDB::register_type<EditorImportExport>();
+ ObjectTypeDB::register_type<EditorSettings>();
+ ObjectTypeDB::register_type<EditorSpatialGizmo>();
//ObjectTypeDB::register_type<EditorImporter>();
@@ -4039,9 +4145,10 @@ Error EditorNode::export_platform(const String& p_platform, const String& p_path
return OK;
}
-void EditorNode::show_warning(const String& p_text) {
+void EditorNode::show_warning(const String& p_text, const String &p_title) {
warning->set_text(p_text);
+ warning->set_title(p_title);
warning->popup_centered_minsize();
}
@@ -4117,7 +4224,7 @@ void EditorNode::_dock_popup_exit() {
}
void EditorNode::_dock_pre_popup(int p_which) {
-
+
dock_popup_selected=p_which;
}
@@ -4326,6 +4433,51 @@ void EditorNode::_load_docks() {
}
+
+void EditorNode::_update_dock_slots_visibility() {
+
+ VSplitContainer*splits[DOCK_SLOT_MAX/2]={
+ left_l_vsplit,
+ left_r_vsplit,
+ right_l_vsplit,
+ right_r_vsplit,
+ };
+
+
+ HSplitContainer*h_splits[4]={
+ left_l_hsplit,
+ left_r_hsplit,
+ main_hsplit,
+ right_hsplit,
+ };
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ if (dock_slot[i]->get_tab_count())
+ dock_slot[i]->show();
+ else
+ dock_slot[i]->hide();
+
+ }
+
+
+ for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
+ bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count();
+ if (in_use)
+ splits[i]->show();
+ else
+ splits[i]->hide();
+ }
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ if (!dock_slot[i]->is_hidden() && dock_slot[i]->get_tab_count()) {
+ dock_slot[i]->set_current_tab(0);
+ }
+ }
+}
+
+
void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section) {
for(int i=0;i<DOCK_SLOT_MAX;i++) {
@@ -4510,7 +4662,7 @@ void EditorNode::_scene_tab_closed(int p_tab) {
}
else {
_remove_scene(p_tab);
- //_update_scene_tabs();
+ _update_scene_tabs();
}
}
@@ -4638,6 +4790,28 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
}
+void EditorNode::remove_bottom_panel_item(Control *p_item) {
+
+ for(int i=0;i<bottom_panel_items.size();i++) {
+
+ if (bottom_panel_items[i].control==p_item) {
+ if (p_item->is_visible()) {
+ _bottom_panel_switch(false,0);
+ }
+ bottom_panel_vb->remove_child(bottom_panel_items[i].control);
+ bottom_panel_hb->remove_child(bottom_panel_items[i].button);
+ memdelete( bottom_panel_items[i].button );
+ bottom_panel_items.remove(i);
+ break;
+ }
+ }
+
+ for(int i=0;i<bottom_panel_items.size();i++) {
+ bottom_panel_items[i].button->disconnect("toggled",this,"_bottom_panel_switch");
+ bottom_panel_items[i].button->connect("toggled",this,"_bottom_panel_switch",varray(i));
+ }
+}
+
void EditorNode::_bottom_panel_switch(bool p_enable,int p_idx) {
ERR_FAIL_INDEX(p_idx,bottom_panel_items.size());
@@ -4663,6 +4837,31 @@ void EditorNode::_bottom_panel_switch(bool p_enable,int p_idx) {
}
}
+
+void EditorNode::add_control_to_dock(DockSlot p_slot,Control* p_control) {
+ ERR_FAIL_INDEX(p_slot,DOCK_SLOT_MAX);
+ dock_slot[p_slot]->add_child(p_control);
+ _update_dock_slots_visibility();
+
+}
+
+void EditorNode::remove_control_from_dock(Control* p_control) {
+
+ Control *dock=NULL;
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+ if (p_control->get_parent()==dock_slot[i]) {
+ dock=dock_slot[i];
+ break;
+ }
+ }
+
+ ERR_EXPLAIN("Control was not in dock");
+ ERR_FAIL_COND(!dock);
+
+ dock->remove_child(p_control);
+ _update_dock_slots_visibility();
+}
+
void EditorNode::_bind_methods() {
@@ -4752,6 +4951,8 @@ EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
SceneState::set_disable_placeholders(true);
+ editor_initialize_certificates(); //for asset sharing
+
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
@@ -4768,6 +4969,7 @@ EditorNode::EditorNode() {
singleton=this;
last_checked_version=0;
changing_scene=false;
+ _initializing_addons=false;
FileAccess::set_backup_save(true);
@@ -5034,17 +5236,21 @@ EditorNode::EditorNode() {
scene_tabs=memnew( Tabs );
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_CENTER);
- scene_tabs->set_tab_close_display_policy(Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY);
+ scene_tabs->set_tab_close_display_policy( (bool(EDITOR_DEF("global/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY) );
scene_tabs->connect("tab_changed",this,"_scene_tab_changed");
scene_tabs->connect("right_button_pressed",this,"_scene_tab_script_edited");
scene_tabs->connect("tab_close", this, "_scene_tab_closed");
srt->add_child(scene_tabs);
- scene_root_parent = memnew( Panel );
+ scene_root_parent = memnew( PanelContainer );
+ scene_root_parent->set_custom_minimum_size(Size2(0,80));
+
+
+ //Ref<StyleBox> sp = scene_root_parent->get_stylebox("panel","TabContainer");
+ //scene_root_parent->add_style_override("panel",sp);
+
- Ref<StyleBox> sp = scene_root_parent->get_stylebox("panel","TabContainer");
- scene_root_parent->add_style_override("panel",sp);
/*scene_root_parent->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
scene_root_parent->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END );
scene_root_parent->set_begin( Point2( 0, 0) );
@@ -5052,13 +5258,6 @@ EditorNode::EditorNode() {
srt->add_child(scene_root_parent);
scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- scene_root_base = memnew( Control );
- scene_root_base->set_area_as_parent_rect();
- for(int i=0;i<4;i++) {
- scene_root_base->set_margin(Margin(i),sp->get_margin(Margin(i)));
- }
- scene_root_parent->add_child(scene_root_base);
-
scene_root = memnew( Viewport );
@@ -5073,11 +5272,11 @@ EditorNode::EditorNode() {
// scene_root->set_world_2d( Ref<World2D>( memnew( World2D )) );
- viewport = memnew( Control );
- viewport->set_area_as_parent_rect(4);
- for(int i=0;i<4;i++) {
+ viewport = memnew( VBoxContainer );
+ viewport->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ /*for(int i=0;i<4;i++) {
viewport->set_margin(Margin(i),sp->get_margin(Margin(i)));
- }
+ }*/
scene_root_parent->add_child(viewport);
@@ -5666,7 +5865,7 @@ EditorNode::EditorNode() {
-
+
call_dialog = memnew( CallDialog );
call_dialog->hide();
gui_base->add_child( call_dialog );
@@ -5719,7 +5918,7 @@ EditorNode::EditorNode() {
dependency_fixer = memnew( DependencyEditor );
gui_base->add_child( dependency_fixer );
-
+
settings_config_dialog = memnew( EditorSettingsDialog );
gui_base->add_child(settings_config_dialog);
@@ -5829,7 +6028,7 @@ EditorNode::EditorNode() {
property_forward->connect("pressed", this,"_property_editor_forward");
property_back->connect("pressed", this,"_property_editor_back");
-
+
file_menu->get_popup()->connect("item_pressed", this,"_menu_option");
@@ -5859,7 +6058,8 @@ EditorNode::EditorNode() {
// Ref<EditorSceneImporterFBXConv> _fbxconv_import = memnew( EditorSceneImporterFBXConv);
// _scene_import->add_importer(_fbxconv_import);
editor_import_export->add_import_plugin( _scene_import);
- editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
+ // TODO: This plugin has no code, it should be either implemented or dropped (GH-3667)
+ // editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorMeshImportPlugin>( memnew(EditorMeshImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorFontImportPlugin>( memnew(EditorFontImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorSampleImportPlugin>( memnew(EditorSampleImportPlugin(this))));
@@ -5874,6 +6074,7 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( CanvasItemEditorPlugin(this) ) );
add_editor_plugin( memnew( SpatialEditorPlugin(this) ) );
add_editor_plugin( memnew( ScriptEditorPlugin(this) ) );
+ //add_editor_plugin( memnew( AddonEditorPlugin(this) ) );
//more visually meaningful to have this later
raise_bottom_panel_item(AnimationPlayerEditor::singleton);
@@ -6029,7 +6230,7 @@ EditorNode::EditorNode() {
}
- EditorSettings::get_singleton()->enable_plugins();
+
Node::set_human_readable_collision_renaming(true);
@@ -6045,13 +6246,26 @@ EditorNode::EditorNode() {
editor_data.set_edited_scene(0);
_update_scene_tabs();
+ {
+
+ _initializing_addons=true;
+ Vector<String> addons = Globals::get_singleton()->get("editor_plugins/enabled");
+
+ for(int i=0;i<addons.size();i++) {
+ set_addon_plugin_enabled(addons[i],true);
+ }
+ _initializing_addons=false;
+ }
+
+
+
_load_docks();
}
-EditorNode::~EditorNode() {
+EditorNode::~EditorNode() {
memdelete( EditorHelp::get_doc_data() );
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index c687643d30..b8fabb4c55 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -101,6 +101,19 @@ class EditorNode : public Node {
OBJ_TYPE( EditorNode, Node );
+public:
+ enum DockSlot {
+ DOCK_SLOT_LEFT_UL,
+ DOCK_SLOT_LEFT_BL,
+ DOCK_SLOT_LEFT_UR,
+ DOCK_SLOT_LEFT_BR,
+ DOCK_SLOT_RIGHT_UL,
+ DOCK_SLOT_RIGHT_BL,
+ DOCK_SLOT_RIGHT_UR,
+ DOCK_SLOT_RIGHT_BR,
+ DOCK_SLOT_MAX
+ };
+private:
enum {
HISTORY_SIZE=64
};
@@ -182,17 +195,6 @@ class EditorNode : public Node {
OBJECT_METHOD_BASE=500
};
- enum DockSlot {
- DOCK_SLOT_LEFT_UL,
- DOCK_SLOT_LEFT_BL,
- DOCK_SLOT_LEFT_UR,
- DOCK_SLOT_LEFT_BR,
- DOCK_SLOT_RIGHT_UL,
- DOCK_SLOT_RIGHT_BL,
- DOCK_SLOT_RIGHT_UR,
- DOCK_SLOT_RIGHT_BR,
- DOCK_SLOT_MAX
- };
//Node *edited_scene; //scene being edited
@@ -258,7 +260,7 @@ class EditorNode : public Node {
TextEdit *load_errors;
AcceptDialog *load_error_dialog;
- Control *scene_root_base;
+ //Control *scene_root_base;
Ref<Theme> theme;
PopupMenu *recent_scenes;
@@ -355,6 +357,7 @@ class EditorNode : public Node {
Object *current;
bool _playing_edited;
+ String run_custom_filename;
bool reference_resource_mem;
bool save_external_resources_mem;
uint64_t saved_version;
@@ -399,13 +402,13 @@ class EditorNode : public Node {
String external_file;
List<String> previous_scenes;
bool opening_prev;
-
+
void _dialog_action(String p_file);
void _edit_current();
void _dialog_display_file_error(String p_file,Error p_error);
-
+
int current_option;
//void _animation_visibility_toggle();
void _resource_created();
@@ -420,7 +423,7 @@ class EditorNode : public Node {
void _select_history(int p_idx);
void _prepare_history();
-
+
void _fs_changed();
void _sources_changed(bool p_exist);
void _imported(Node *p_node);
@@ -447,7 +450,7 @@ class EditorNode : public Node {
void _hide_top_editors();
void _quick_opened();
- void _quick_run(const String& p_resource);
+ void _quick_run();
void _run(bool p_current=false, const String &p_custom="");
@@ -478,6 +481,10 @@ class EditorNode : public Node {
Map<String,Ref<Texture> > icon_type_cache;
+ bool _initializing_addons;
+ Map<String,EditorPlugin*> plugin_addons;
+
+
static Ref<Texture> _file_dialog_get_icon(const String& p_path);
static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog);
@@ -540,6 +547,8 @@ class EditorNode : public Node {
void _load_docks();
void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section);
void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section);
+ void _update_dock_slots_visibility();
+
void _update_layouts_menu();
void _layout_menu_option(int p_idx);
@@ -548,6 +557,9 @@ class EditorNode : public Node {
void _clear_search_box();
void _clear_undo_history();
+ void _update_addon_config();
+
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -569,9 +581,14 @@ public:
static void add_editor_plugin(EditorPlugin *p_editor);
static void remove_editor_plugin(EditorPlugin *p_editor);
+ void add_control_to_dock(DockSlot p_slot,Control* p_control);
+ void remove_control_from_dock(Control* p_control);
+
void add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
+ void set_addon_plugin_enabled(const String& p_addon,bool p_enabled);
+ bool is_addon_plugin_enabled(const String &p_addon) const;
void edit_node(Node *p_node);
void edit_resource(const Ref<Resource>& p_resource);
@@ -638,7 +655,7 @@ public:
Ref<Theme> get_editor_theme() const { return theme; }
- void show_warning(const String& p_text);
+ void show_warning(const String& p_text,const String& p_title="Warning!");
Error export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after=false);
@@ -674,8 +691,9 @@ public:
void make_bottom_panel_item_visible(Control *p_item);
void raise_bottom_panel_item(Control *p_item);
void hide_bottom_panel();
+ void remove_bottom_panel_item(Control *p_item);
- EditorNode();
+ EditorNode();
~EditorNode();
void get_singleton(const char* arg1, bool arg2);
diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp
index b7ccb452e9..dc46361251 100644
--- a/tools/editor/editor_plugin.cpp
+++ b/tools/editor/editor_plugin.cpp
@@ -29,6 +29,8 @@
#include "editor_plugin.h"
#include "plugins/canvas_item_editor_plugin.h"
#include "plugins/spatial_editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "tools/editor/editor_settings.h"
void EditorPlugin::add_custom_type(const String& p_type, const String& p_base,const Ref<Script>& p_script, const Ref<Texture>& p_icon) {
@@ -41,8 +43,33 @@ void EditorPlugin::remove_custom_type(const String& p_type){
}
+void EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) {
-void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control *p_control) {
+ EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control);
+}
+
+void EditorPlugin::add_control_to_dock(DockSlot p_slot,Control *p_control) {
+
+ ERR_FAIL_NULL(p_control);
+ EditorNode::get_singleton()->add_control_to_dock(EditorNode::DockSlot(p_slot),p_control);
+
+}
+
+void EditorPlugin::remove_control_from_docks(Control *p_control) {
+
+ ERR_FAIL_NULL(p_control);
+ EditorNode::get_singleton()->remove_control_from_dock(p_control);
+
+}
+
+void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) {
+
+ ERR_FAIL_NULL(p_control);
+ EditorNode::get_singleton()->remove_bottom_panel_item(p_control);
+
+}
+
+void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Control *p_control) {
switch(p_location) {
@@ -50,6 +77,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
EditorNode::get_menu_hb()->add_child(p_control);
} break;
+
case CONTAINER_SPATIAL_EDITOR_MENU: {
SpatialEditor::get_singleton()->add_control_to_menu_panel(p_control);
@@ -86,9 +114,13 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
}
}
-bool EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
+Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
//??
- return false;
+ if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) {
+ return get_script_instance()->call("create_spatial_gizmo",p_spatial);
+ }
+
+ return Ref<SpatialEditorGizmo>();
}
bool EditorPlugin::forward_input_event(const InputEvent& p_event) {
@@ -206,15 +238,70 @@ void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){
}
+EditorSelection* EditorPlugin::get_selection() {
+ return EditorNode::get_singleton()->get_editor_selection();
+}
+
+
+EditorSettings *EditorPlugin::get_editor_settings() {
+ return EditorSettings::get_singleton();
+}
+
+void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
+
+ EditorNode::get_singleton()->add_editor_import_plugin(p_editor_import);
+}
+
+void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import){
+
+ EditorNode::get_singleton()->remove_editor_import_plugin(p_editor_import);
+
+}
+
+void EditorPlugin::add_export_plugin(const Ref<EditorExportPlugin>& p_editor_export){
+
+ EditorImportExport::get_singleton()->add_export_plugin(p_editor_export);
+}
+void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin>& p_editor_export){
+
+ EditorImportExport::get_singleton()->remove_export_plugin(p_editor_export);
+
+}
+
+Control *EditorPlugin::get_base_control() {
+
+ return EditorNode::get_singleton()->get_gui_base();
+}
+
+
void EditorPlugin::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("get_undo_redo"),&EditorPlugin::_get_undo_redo);
- ObjectTypeDB::bind_method(_MD("add_custom_control","container","control"),&EditorPlugin::add_custom_control);
+ ObjectTypeDB::bind_method(_MD("add_control_to_container","container","control:Control"),&EditorPlugin::add_control_to_container);
+ ObjectTypeDB::bind_method(_MD("add_control_to_bottom_panel","control:Control","title"),&EditorPlugin::add_control_to_bottom_panel);
+ ObjectTypeDB::bind_method(_MD("add_control_to_dock","slot","control:Control"),&EditorPlugin::add_control_to_dock);
+ ObjectTypeDB::bind_method(_MD("remove_control_from_docks","control:Control"),&EditorPlugin::remove_control_from_docks);
+ ObjectTypeDB::bind_method(_MD("remove_control_from_bottom_panel","control:Control"),&EditorPlugin::remove_control_from_bottom_panel);
ObjectTypeDB::bind_method(_MD("add_custom_type","type","base","script:Script","icon:Texture"),&EditorPlugin::add_custom_type);
ObjectTypeDB::bind_method(_MD("remove_custom_type","type"),&EditorPlugin::remove_custom_type);
+ ObjectTypeDB::bind_method(_MD("add_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::add_import_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::remove_import_plugin);
+
+ ObjectTypeDB::bind_method(_MD("add_export_plugin","plugin:EditorExportPlugin"),&EditorPlugin::add_export_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorPlugin::remove_export_plugin);
+
+
+ ObjectTypeDB::bind_method(_MD("get_base_control:Control"),&EditorPlugin::get_base_control);
+ ObjectTypeDB::bind_method(_MD("get_undo_redo:UndoRedo"),&EditorPlugin::_get_undo_redo);
+ ObjectTypeDB::bind_method(_MD("get_selection:EditorSelection"),&EditorPlugin::get_selection);
+ ObjectTypeDB::bind_method(_MD("get_editor_settings:EditorSettings"),&EditorPlugin::get_editor_settings);
+
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"forward_input_event",PropertyInfo(Variant::INPUT_EVENT,"event")));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"forward_spatial_input_event",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera"),PropertyInfo(Variant::INPUT_EVENT,"event")));
+ MethodInfo gizmo = MethodInfo(Variant::OBJECT,"create_spatial_gizmo",PropertyInfo(Variant::OBJECT,"for_spatial:Spatial"));
+ gizmo.return_val.hint=PROPERTY_HINT_RESOURCE_TYPE;
+ gizmo.return_val.hint_string="EditorSpatialGizmo";
+ ObjectTypeDB::add_virtual_method(get_type_static(),gizmo);
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"has_main_screen"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("make_visible",PropertyInfo(Variant::BOOL,"visible")));
@@ -233,6 +320,16 @@ void EditorPlugin::_bind_methods() {
BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_MENU );
BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_SIDE );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_UL );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_BL );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_UR );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_BR );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_UL );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_BL );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_UR );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_BR );
+ BIND_CONSTANT( DOCK_SLOT_MAX );
+
}
EditorPlugin::EditorPlugin()
diff --git a/tools/editor/editor_plugin.h b/tools/editor/editor_plugin.h
index bf1e185a37..c572ab210e 100644
--- a/tools/editor/editor_plugin.h
+++ b/tools/editor/editor_plugin.h
@@ -40,9 +40,15 @@
class EditorNode;
class Spatial;
class Camera;
+class EditorSelection;
+class EditorImportExport;
+class EditorSettings;
+class SpatialEditorGizmo;
+class EditorImportPlugin;
+class EditorExportPlugin;
class EditorPlugin : public Node {
-
+
OBJ_TYPE( EditorPlugin, Node );
friend class EditorData;
UndoRedo *undo_redo;
@@ -70,11 +76,27 @@ public:
CONTAINER_CANVAS_EDITOR_BOTTOM
};
+ enum DockSlot {
+ DOCK_SLOT_LEFT_UL,
+ DOCK_SLOT_LEFT_BL,
+ DOCK_SLOT_LEFT_UR,
+ DOCK_SLOT_LEFT_BR,
+ DOCK_SLOT_RIGHT_UL,
+ DOCK_SLOT_RIGHT_BL,
+ DOCK_SLOT_RIGHT_UR,
+ DOCK_SLOT_RIGHT_BR,
+ DOCK_SLOT_MAX
+ };
+
//TODO: send a resoucre for editing to the editor node?
- void add_custom_control(CustomControlContainer p_location,Control *p_control);
+ void add_control_to_container(CustomControlContainer p_location, Control *p_control);
+ void add_control_to_bottom_panel(Control *p_control, const String &p_title);
+ void add_control_to_dock(DockSlot p_slot,Control *p_control);
+ void remove_control_from_docks(Control *p_control);
+ void remove_control_from_bottom_panel(Control *p_control);
- virtual bool create_spatial_gizmo(Spatial* p_spatial);
+ virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual bool forward_input_event(const InputEvent& p_event);
virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
virtual String get_name() const;
@@ -94,6 +116,19 @@ public:
virtual void get_window_layout(Ref<ConfigFile> p_layout);
virtual void edited_scene_changed(){}; // if changes are pending in editor, apply them
+
+ Control *get_base_control();
+
+ void add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
+ void remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
+
+ void add_export_plugin(const Ref<EditorExportPlugin>& p_editor_export);
+ void remove_export_plugin(const Ref<EditorExportPlugin>& p_editor_export);
+
+ EditorSelection* get_selection();
+ //EditorImportExport *get_import_export();
+ EditorSettings *get_editor_settings();
+
virtual void restore_global_state();
virtual void save_global_state();
@@ -103,6 +138,7 @@ public:
};
VARIANT_ENUM_CAST( EditorPlugin::CustomControlContainer );
+VARIANT_ENUM_CAST( EditorPlugin::DockSlot );
typedef EditorPlugin* (*EditorPluginCreateFunc)(EditorNode *);
diff --git a/tools/editor/editor_plugin_settings.cpp b/tools/editor/editor_plugin_settings.cpp
new file mode 100644
index 0000000000..d78e43c578
--- /dev/null
+++ b/tools/editor/editor_plugin_settings.cpp
@@ -0,0 +1,188 @@
+#include "editor_plugin_settings.h"
+#include "scene/gui/margin_container.h"
+#include "io/config_file.h"
+#include "os/file_access.h"
+#include "os/main_loop.h"
+#include "globals.h"
+#include "editor_node.h"
+
+void EditorPluginSettings::_notification(int p_what) {
+
+ if (p_what==MainLoop::NOTIFICATION_WM_FOCUS_IN) {
+ update_plugins();
+ }
+}
+
+void EditorPluginSettings::update_plugins() {
+
+
+ plugin_list->clear();
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ Error err = da->change_dir("res://addons");
+ if (err!=OK) {
+ memdelete(da);
+ return;
+ }
+
+ updating=true;
+
+ TreeItem *root = plugin_list->create_item();
+
+ da->list_dir_begin();
+
+ String d = da->get_next();
+
+ Vector<String> plugins;
+
+ while(d!=String()) {
+
+ bool dir = da->current_is_dir();
+ String path = "res://addons/"+d+"/plugin.cfg";
+
+ if (dir && FileAccess::exists(path)) {
+
+ plugins.push_back(d);
+ }
+
+ d = da->get_next();
+ }
+
+ da->list_dir_end();
+ memdelete(da);
+
+ plugins.sort();
+
+ Vector<String> active_plugins = Globals::get_singleton()->get("plugins/active");
+
+ for(int i=0;i<plugins.size();i++) {
+
+ Ref<ConfigFile> cf;
+ cf.instance();
+ String path = "res://addons/"+plugins[i]+"/plugin.cfg";
+
+ Error err = cf->load(path);
+
+ if (err!=OK) {
+ WARN_PRINTS("Can't load plugin config: "+path);
+ } else if (!cf->has_section_key("plugin","name")) {
+ WARN_PRINTS("Plugin misses plugin/name: "+path);
+ } else if (!cf->has_section_key("plugin","author")) {
+ WARN_PRINTS("Plugin misses plugin/author: "+path);
+ } else if (!cf->has_section_key("plugin","version")) {
+ WARN_PRINTS("Plugin misses plugin/version: "+path);
+ } else if (!cf->has_section_key("plugin","description")) {
+ WARN_PRINTS("Plugin misses plugin/description: "+path);
+ } else if (!cf->has_section_key("plugin","script")) {
+ WARN_PRINTS("Plugin misses plugin/script: "+path);
+ } else {
+
+ String d = plugins[i];
+ String name = cf->get_value("plugin","name");
+ String author = cf->get_value("plugin","author");
+ String version = cf->get_value("plugin","version");
+ String description = cf->get_value("plugin","description");
+ String script = cf->get_value("plugin","script");
+
+ TreeItem *item = plugin_list->create_item(root);
+ item->set_text(0,name);
+ item->set_tooltip(0,"Name: "+name+"\nPath: "+path+"\nMain Script: "+script);
+ item->set_metadata(0,d);
+ item->set_text(1,version);
+ item->set_metadata(1,script);
+ item->set_text(2,author);
+ item->set_metadata(2,description);
+ item->set_cell_mode(3,TreeItem::CELL_MODE_RANGE);
+ item->set_range_config(3,0,1,1);
+ item->set_text(3,"Inactive,Active");
+ item->set_editable(3,true);
+
+ if (EditorNode::get_singleton()->is_addon_plugin_enabled(d)) {
+ item->set_custom_color(3,Color(0.2,1,0.2));
+ item->set_range(3,1);
+ } else {
+ item->set_custom_color(3,Color(1,0.2,0.2));
+ item->set_range(3,0);
+ }
+ }
+
+ }
+
+ updating=false;
+
+}
+
+
+void EditorPluginSettings::_plugin_activity_changed() {
+
+ if (updating)
+ return;
+
+ TreeItem *ti=plugin_list->get_edited();
+ ERR_FAIL_COND(!ti);
+ bool active = ti->get_range(3);
+ String name = ti->get_metadata(0);
+
+ EditorNode::get_singleton()->set_addon_plugin_enabled(name,active);
+
+ bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(name);
+
+ if (is_active!=active) {
+ updating=true;
+ ti->set_range(3,is_active?1:0);
+ updating=false;
+ }
+
+ if (is_active)
+ ti->set_custom_color(3,Color(0.2,1,0.2));
+ else
+ ti->set_custom_color(3,Color(1,0.2,0.2));
+
+
+}
+
+void EditorPluginSettings::_bind_methods() {
+
+ ObjectTypeDB::bind_method("update_plugins",&EditorPluginSettings::update_plugins);
+ ObjectTypeDB::bind_method("_plugin_activity_changed",&EditorPluginSettings::_plugin_activity_changed);
+}
+
+EditorPluginSettings::EditorPluginSettings() {
+
+ HBoxContainer *title_hb = memnew( HBoxContainer );
+ title_hb->add_child(memnew( Label("Installed Plugins:")));
+ title_hb->add_spacer();
+ update_list = memnew( Button("Update") );
+ update_list->connect("pressed",this,"update_plugins");
+ title_hb->add_child(update_list);
+ add_child(title_hb);
+
+ plugin_list = memnew( Tree );
+ plugin_list->set_v_size_flags(SIZE_EXPAND_FILL);
+ plugin_list->set_columns(4);
+ plugin_list->set_column_titles_visible(true);
+ plugin_list->set_column_title(0,"Name:");
+ plugin_list->set_column_title(1,"Version:");
+ plugin_list->set_column_title(2,"Author:");
+ plugin_list->set_column_title(3,"Status:");
+ plugin_list->set_column_expand(0,true);
+ plugin_list->set_column_expand(1,false);
+ plugin_list->set_column_expand(2,false);
+ plugin_list->set_column_expand(3,false);
+ plugin_list->set_column_min_width(1,100);
+ plugin_list->set_column_min_width(2,250);
+ plugin_list->set_column_min_width(3,80);
+ plugin_list->set_hide_root(true);
+ plugin_list->connect("item_edited",this,"_plugin_activity_changed");
+
+
+ MarginContainer *mc = memnew( MarginContainer );
+ mc->add_child(plugin_list);
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ add_child(mc);
+
+ updating=false;
+
+}
+
diff --git a/tools/editor/editor_plugin_settings.h b/tools/editor/editor_plugin_settings.h
new file mode 100644
index 0000000000..4f3c5b8268
--- /dev/null
+++ b/tools/editor/editor_plugin_settings.h
@@ -0,0 +1,35 @@
+#ifndef EDITORPLUGINSETTINGS_H
+#define EDITORPLUGINSETTINGS_H
+
+
+#include "scene/gui/dialogs.h"
+#include "property_editor.h"
+#include "optimized_save_dialog.h"
+#include "undo_redo.h"
+#include "editor_data.h"
+
+class EditorPluginSettings : public VBoxContainer {
+
+ OBJ_TYPE(EditorPluginSettings,VBoxContainer);
+
+ Button* update_list;
+ Tree *plugin_list;
+ bool updating;
+
+
+ void _plugin_activity_changed();
+protected:
+
+ void _notification(int p_what);
+
+ static void _bind_methods();
+
+
+public:
+
+ void update_plugins();
+
+ EditorPluginSettings();
+};
+
+#endif // EDITORPLUGINSETTINGS_H
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index 4195ba97e6..1133acb48c 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -165,22 +165,33 @@ void EditorSettings::create() {
return; //pointless
DirAccess *dir=NULL;
- Object *object;
Variant meta;
String config_path;
String config_dir;
String config_file="editor_settings.xml";
+ Ref<ConfigFile> extra_config = memnew(ConfigFile);
- if (OS::get_singleton()->has_environment("APPDATA")) {
- // Most likely under windows, save here
- config_path=OS::get_singleton()->get_environment("APPDATA");
- config_dir=String(_MKSTR(VERSION_SHORT_NAME)).capitalize();
- } else if (OS::get_singleton()->has_environment("HOME")) {
+ String exe_path = OS::get_singleton()->get_executable_path().get_base_dir();
+ DirAccess* d = DirAccess::create_for_path(exe_path);
+ if (d->file_exists(exe_path + "/._sc_")) {
- config_path=OS::get_singleton()->get_environment("HOME");
- config_dir="."+String(_MKSTR(VERSION_SHORT_NAME)).to_lower();
- }
+ // editor is self contained
+ config_path = exe_path;
+ config_dir = "editor_data";
+ extra_config->load(exe_path + "/._sc_");
+ } else {
+
+ if (OS::get_singleton()->has_environment("APPDATA")) {
+ // Most likely under windows, save here
+ config_path=OS::get_singleton()->get_environment("APPDATA");
+ config_dir=String(_MKSTR(VERSION_SHORT_NAME)).capitalize();
+ } else if (OS::get_singleton()->has_environment("HOME")) {
+
+ config_path=OS::get_singleton()->get_environment("HOME");
+ config_dir="."+String(_MKSTR(VERSION_SHORT_NAME)).to_lower();
+ }
+ };
ObjectTypeDB::register_type<EditorSettings>(); //otherwise it can't be unserialized
String config_file_path;
@@ -217,13 +228,6 @@ void EditorSettings::create() {
dir->change_dir("..");
}
- if (dir->change_dir("plugins")!=OK) {
- dir->make_dir("plugins");
- } else {
-
- dir->change_dir("..");
- }
-
if (dir->change_dir("config")!=OK) {
dir->make_dir("config");
} else {
@@ -276,7 +280,6 @@ void EditorSettings::create() {
singleton->setup_network();
singleton->load_favorites();
- singleton->scan_plugins();
return;
@@ -286,12 +289,21 @@ void EditorSettings::create() {
fail:
+ // patch init projects
+ if (extra_config->has_section("init_projects")) {
+ Vector<String> list = extra_config->get_value("init_projects", "list");
+ for (int i=0; i<list.size(); i++) {
+
+ list[i] = exe_path + "/" + list[i];
+ };
+ extra_config->set_value("init_projects", "list", list);
+ };
+
singleton = Ref<EditorSettings>( memnew( EditorSettings ) );
singleton->config_file_path=config_file_path;
singleton->settings_path=config_path+"/"+config_dir;
- singleton->_load_defaults();
+ singleton->_load_defaults(extra_config);
singleton->setup_network();
- singleton->scan_plugins();
}
@@ -302,35 +314,6 @@ String EditorSettings::get_settings_path() const {
}
-Error EditorSettings::_load_plugin(const String& p_path, Plugin &plugin) {
-
- if (!FileAccess::exists(p_path))
- return ERR_FILE_NOT_FOUND;
-
- Ref<ConfigFile> cf = memnew(ConfigFile);
- Error err = cf->load(p_path);
- ERR_EXPLAIN("Error loading plugin description for: "+p_path);
- ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN);
-
- plugin.instance=NULL;
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","name"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","installs"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","author"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","version"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","script"),ERR_INVALID_DATA);
- plugin.name=cf->get_value("plugin","name");
- plugin.author=cf->get_value("plugin","author");
- plugin.version=cf->get_value("plugin","version");
- plugin.script=cf->get_value("plugin","script");
-
- if (cf->has_section_key("plugin","description"))
- plugin.description=cf->get_value("plugin","description");
- plugin.installs=cf->get_value("plugin","installs");
- if (cf->has_section_key("plugin","install_files"))
- plugin.install_files=cf->get_value("plugin","install_files");
-
- return OK;
-}
void EditorSettings::setup_network() {
@@ -361,46 +344,6 @@ void EditorSettings::setup_network() {
}
-void EditorSettings::scan_plugins() {
-
- Map<String,Plugin> new_plugins;
-
- new_plugins.clear();
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- Error err = d->change_dir(get_settings_path().plus_file("plugins"));
- if (err!=OK) {
- memdelete(d);
- ERR_EXPLAIN("Plugin dir does not exist!")
- ERR_FAIL_COND(err!=OK);
- }
- d->list_dir_begin();
-
- String base = d->get_current_dir();
- //print_line("list diring on: "+base);
- while(true) {
- String p = d->get_next();
- if (p=="")
- break;
- if (!d->current_is_dir() || p.begins_with("."))
- continue;
-
- String cfpath=d->get_current_dir().plus_file(p+"/plugin.cfg");
-
- Plugin plugin;
- Error err = _load_plugin(cfpath,plugin);
- ERR_CONTINUE(err!=OK);
-
- if (plugins.has(p))
- plugin.instance=plugins[p].instance;
-
- new_plugins[p]=plugin;
- }
-
-
- plugins=new_plugins;
-
- memdelete(d);
-}
void EditorSettings::save() {
@@ -435,7 +378,7 @@ void EditorSettings::destroy() {
singleton=Ref<EditorSettings>();
}
-void EditorSettings::_load_defaults() {
+void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_THREAD_SAFE_METHOD_
@@ -461,6 +404,11 @@ void EditorSettings::_load_defaults() {
set("text_editor/brace_mismatch_color",Color(1,0.2,0.2));
set("text_editor/current_line_color",Color(0.3,0.5,0.8,0.15));
+ set("text_editor/scroll_past_end_of_file", false);
+
+ set("text_editor/tab_size", 4);
+ hints["text_editor/tab_size"]=PropertyInfo(Variant::INT,"text_editor/tab_size",PROPERTY_HINT_RANGE,"1, 64, 1"); // size of 0 crashes.
+
set("text_editor/idle_parse_delay",2);
set("text_editor/create_signal_callbacks",true);
set("text_editor/autosave_interval_secs",0);
@@ -490,6 +438,7 @@ void EditorSettings::_load_defaults() {
hints["3d_editor/pan_modifier"]=PropertyInfo(Variant::INT,"3d_editor/pan_modifier",PROPERTY_HINT_ENUM,"None,Shift,Alt,Meta,Ctrl");
set("3d_editor/zoom_modifier",4);
hints["3d_editor/zoom_modifier"]=PropertyInfo(Variant::INT,"3d_editor/zoom_modifier",PROPERTY_HINT_ENUM,"None,Shift,Alt,Meta,Ctrl");
+ set("3d_editor/emulate_numpad",false);
set("2d_editor/bone_width",5);
set("2d_editor/bone_color1",Color(1.0,1.0,1.0,0.9));
@@ -541,6 +490,33 @@ void EditorSettings::_load_defaults() {
set("run/auto_save_before_running",true);
set("resources/save_compressed_resources",true);
set("resources/auto_reload_modified_images",true);
+
+ if (p_extra_config.is_valid()) {
+
+ if (p_extra_config->has_section("init_projects") && p_extra_config->has_section_key("init_projects", "list")) {
+
+ Vector<String> list = p_extra_config->get_value("init_projects", "list");
+ for (int i=0; i<list.size(); i++) {
+
+ String name = list[i].replace("/", "::");
+ set("projects/"+name, list[i]);
+ };
+ };
+
+ if (p_extra_config->has_section("presets")) {
+
+ List<String> keys;
+ p_extra_config->get_section_keys("presets", &keys);
+
+ for (List<String>::Element *E=keys.front();E;E=E->next()) {
+
+ String key = E->get();
+ Variant val = p_extra_config->get_value("presets", key);
+ set(key, val);
+ };
+ };
+ };
+
}
void EditorSettings::notify_changes() {
@@ -574,148 +550,9 @@ void EditorSettings::add_property_hint(const PropertyInfo& p_hint) {
}
-bool EditorSettings::is_plugin_enabled(const String& p_plugin) {
-
- if (!has("_plugins/enabled"))
- return false;
-
- StringArray sa=get("_plugins/enabled");
-
- for(int i=0;i<sa.size();i++) {
-
- String plugin = sa[i];
- if (!plugins.has(plugin))
- continue;
- if (plugin==p_plugin)
- return true;
- }
- return false;
-}
-void EditorSettings::enable_plugins() {
-
- // editor plugins
- if (has("_plugins/enabled")) {
- StringArray sa=get("_plugins/enabled");
-
- for(int i=0;i<sa.size();i++) {
-
- String plugin = sa[i];
- if (!plugins.has(plugin))
- continue;
- if (plugins[plugin].installs)
- continue; //not configured here
- set_plugin_enabled(plugin,true);
- }
- }
-
- // installed plugins
- List<PropertyInfo> pi;
- Globals::get_singleton()->get_property_list(&pi);
- for (List<PropertyInfo>::Element *E=pi.front();E;E=E->next()) {
-
- String p = E->get().name;
-
- if (p.begins_with("plugins/")) {
- load_installed_plugin(p.replace_first("plugins/",""));
- }
- }
-
-}
-
-void EditorSettings::load_installed_plugin(const String& p_plugin) {
-
- ERR_FAIL_COND( !Globals::get_singleton()->has("plugins/"+p_plugin) );
- String path = Globals::get_singleton()->get("plugins/"+p_plugin);
-
- Plugin plugin;
- Error err = _load_plugin(path.plus_file("plugin.cfg"),plugin);
-
- if (err)
- return;
-
- print_line("installing plugin...");
- EditorPlugin *ep=_load_plugin_editor(path.plus_file(plugin.script));
- ERR_FAIL_COND(!ep);
- print_line("load!");
- EditorNode::add_editor_plugin(ep);
-
-}
-
-
-EditorPlugin *EditorSettings::_load_plugin_editor(const String& p_path) {
-
- Ref<Script> script = ResourceLoader::load(p_path);
- ERR_EXPLAIN("Invalid Script for plugin: "+p_path);
- ERR_FAIL_COND_V(script.is_null(),NULL);
- ERR_EXPLAIN("Script has errors: "+p_path);
- ERR_FAIL_COND_V(!script->can_instance(),NULL);
- ERR_EXPLAIN("Script does not inherit EditorPlugin: "+p_path);
- ERR_FAIL_COND_V(script->get_instance_base_type().operator String()!="EditorPlugin",NULL);
-
- EditorPlugin *ep = memnew( EditorPlugin );
- ep->set_script(script.get_ref_ptr());
- if (!ep->get_script_instance()) {
- memdelete(ep);
- ERR_EXPLAIN("Script could't load: "+p_path);
- ERR_FAIL_V(NULL);
- }
-
-
- return ep;
-}
-
-void EditorSettings::set_plugin_enabled(const String& p_plugin, bool p_enabled) {
-
- ERR_FAIL_COND(!plugins.has(p_plugin));
- if (p_enabled == (plugins[p_plugin].instance!=NULL)) //already enabled or disabled
- return;
-
- print_line("REQUEST "+p_plugin+" to "+itos(p_enabled));
- StringArray sa;
- if (has("_plugins/enabled"))
- sa=get("_plugins/enabled");
-
- int idx=-1;
- for(int i=0;i<sa.size();i++) {
-
- if (sa[i]==p_plugin) {
- idx=i;
- break;
- }
- }
-
- if (p_enabled) {
-
-
- String ppath = get_settings_path().plus_file("plugins/"+p_plugin+"/"+plugins[p_plugin].script);
- EditorPlugin *ep=_load_plugin_editor(ppath);
- if (!ep)
- return;
- plugins[p_plugin].instance=ep;
- EditorNode::add_editor_plugin(ep);
-
- if (idx==-1)
- sa.push_back(p_plugin);
- } else {
-
- print_line("DISABLING");
- EditorNode::remove_editor_plugin(plugins[p_plugin].instance);
- memdelete(plugins[p_plugin].instance);
- plugins[p_plugin].instance=NULL;
- if (idx!=-1)
- sa.remove(idx);
-
- }
-
- if (sa.size()==0)
- set("_plugins/enabled",Variant());
- else
- set("_plugins/enabled",sa);
-
-}
void EditorSettings::set_favorite_dirs(const Vector<String>& p_favorites) {
@@ -785,6 +622,16 @@ void EditorSettings::load_favorites() {
void EditorSettings::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("erase","property"),&EditorSettings::erase);
+ ObjectTypeDB::bind_method(_MD("get_settings_path"),&EditorSettings::get_settings_path);
+ ObjectTypeDB::bind_method(_MD("get_project_settings_path"),&EditorSettings::get_project_settings_path);
+
+ ObjectTypeDB::bind_method(_MD("set_favorite_dirs","dirs"),&EditorSettings::set_favorite_dirs);
+ ObjectTypeDB::bind_method(_MD("get_favorite_dirs"),&EditorSettings::get_favorite_dirs);
+
+ ObjectTypeDB::bind_method(_MD("set_recent_dirs","dirs"),&EditorSettings::set_recent_dirs);
+ ObjectTypeDB::bind_method(_MD("get_recent_dirs"),&EditorSettings::get_recent_dirs);
+
ADD_SIGNAL(MethodInfo("settings_changed"));
}
diff --git a/tools/editor/editor_settings.h b/tools/editor/editor_settings.h
index d1a11360af..ae5bbcca89 100644
--- a/tools/editor/editor_settings.h
+++ b/tools/editor/editor_settings.h
@@ -33,6 +33,7 @@
#include "resource.h"
#include "os/thread_safe.h"
+#include "core/io/config_file.h"
class EditorPlugin;
@@ -56,7 +57,6 @@ public:
Vector<String> install_files;
};
private:
- Map<String,Plugin> plugins;
struct VariantContainer {
int order;
@@ -83,10 +83,7 @@ private:
Ref<Resource> clipboard;
- EditorPlugin *_load_plugin_editor(const String& p_path);
- Error _load_plugin(const String& p_path,Plugin& plugin);
-
- void _load_defaults();
+ void _load_defaults(Ref<ConfigFile> p_extra_config = NULL);
String project_config_path;
@@ -107,13 +104,10 @@ public:
static EditorSettings *get_singleton();
void erase(String p_var);
String get_settings_path() const;
- String get_global_settings_path() const;
+ //String get_global_settings_path() const;
String get_project_settings_path() const;
- const Map<String,Plugin>& get_plugins() const { return plugins; }
- void scan_plugins();
- void enable_plugins();
void setup_network();
void raise_order(const String& p_name);
@@ -123,11 +117,6 @@ public:
void notify_changes();
- void set_plugin_enabled(const String& p_plugin,bool p_enabled);
- bool is_plugin_enabled(const String& p_plugin);
-
- void load_installed_plugin(const String& p_plugin);
-
void set_resource_clipboard(const Ref<Resource>& p_resource) { clipboard=p_resource; }
Ref<Resource> get_resource_clipboard() const { return clipboard; }
diff --git a/tools/editor/editor_sub_scene.cpp b/tools/editor/editor_sub_scene.cpp
index e58e2c1351..c5a4f6d58b 100644
--- a/tools/editor/editor_sub_scene.cpp
+++ b/tools/editor/editor_sub_scene.cpp
@@ -147,7 +147,7 @@ void EditorSubScene::move(Node* p_new_parent, Node* p_new_owner) {
}
TreeItem *s = tree->get_selected();
if (!s) {
- return;
+ return;
}
Node *selnode = s->get_metadata(0);
@@ -219,7 +219,7 @@ EditorSubScene::EditorSubScene() {
tree = memnew( Tree );
tree->set_v_size_flags(SIZE_EXPAND_FILL);
vb->add_margin_child("Import From Node:",tree,true);
- tree->connect("item_activated",this,"_ok");
+ tree->connect("item_activated",this,"_ok",make_binds(),CONNECT_DEFERRED);
file_dialog = memnew( EditorFileDialog );
List<String> extensions;
diff --git a/tools/editor/groups_editor.h b/tools/editor/groups_editor.h
index b5bccb2766..6a897d0cbb 100644
--- a/tools/editor/groups_editor.h
+++ b/tools/editor/groups_editor.h
@@ -63,7 +63,7 @@ public:
void set_undo_redo(UndoRedo *p_undoredo) { undo_redo=p_undoredo; }
void set_current(Node* p_node);
- GroupsEditor();
+ GroupsEditor();
~GroupsEditor();
};
diff --git a/tools/editor/icons/icon_array_data.png b/tools/editor/icons/icon_array_data.png
index 494d4c71a8..447acaab2b 100644
--- a/tools/editor/icons/icon_array_data.png
+++ b/tools/editor/icons/icon_array_data.png
Binary files differ
diff --git a/tools/editor/icons/icon_array_float.png b/tools/editor/icons/icon_array_float.png
index 558be932dc..d1b78b4c3e 100644
--- a/tools/editor/icons/icon_array_float.png
+++ b/tools/editor/icons/icon_array_float.png
Binary files differ
diff --git a/tools/editor/icons/icon_array_int.png b/tools/editor/icons/icon_array_int.png
index 74925553d9..2c4ec5bafb 100644
--- a/tools/editor/icons/icon_array_int.png
+++ b/tools/editor/icons/icon_array_int.png
Binary files differ
diff --git a/tools/editor/icons/icon_array_string.png b/tools/editor/icons/icon_array_string.png
index 2aeded63df..a2e3f11c35 100644
--- a/tools/editor/icons/icon_array_string.png
+++ b/tools/editor/icons/icon_array_string.png
Binary files differ
diff --git a/tools/editor/icons/icon_array_variant.png b/tools/editor/icons/icon_array_variant.png
index 34cb83cadd..ab294898ad 100644
--- a/tools/editor/icons/icon_array_variant.png
+++ b/tools/editor/icons/icon_array_variant.png
Binary files differ
diff --git a/tools/editor/icons/icon_bool.png b/tools/editor/icons/icon_bool.png
index 3381033b00..80b3a9deb7 100644
--- a/tools/editor/icons/icon_bool.png
+++ b/tools/editor/icons/icon_bool.png
Binary files differ
diff --git a/tools/editor/icons/icon_color.png b/tools/editor/icons/icon_color.png
index 08547caa28..3ab87c98ea 100644
--- a/tools/editor/icons/icon_color.png
+++ b/tools/editor/icons/icon_color.png
Binary files differ
diff --git a/tools/editor/icons/icon_godot_asset_default.png b/tools/editor/icons/icon_godot_asset_default.png
new file mode 100644
index 0000000000..7478399e8b
--- /dev/null
+++ b/tools/editor/icons/icon_godot_asset_default.png
Binary files differ
diff --git a/tools/editor/icons/icon_h_t_t_p_request.png b/tools/editor/icons/icon_h_t_t_p_request.png
new file mode 100644
index 0000000000..6c7f1885ce
--- /dev/null
+++ b/tools/editor/icons/icon_h_t_t_p_request.png
Binary files differ
diff --git a/tools/editor/icons/icon_integer.png b/tools/editor/icons/icon_integer.png
index 32c8d9885b..b49390aeb1 100644
--- a/tools/editor/icons/icon_integer.png
+++ b/tools/editor/icons/icon_integer.png
Binary files differ
diff --git a/tools/editor/icons/icon_link_button.png b/tools/editor/icons/icon_link_button.png
new file mode 100644
index 0000000000..b6b9868e11
--- /dev/null
+++ b/tools/editor/icons/icon_link_button.png
Binary files differ
diff --git a/tools/editor/icons/icon_quat.png b/tools/editor/icons/icon_quat.png
index ebb8719d33..f09d2fcaba 100644
--- a/tools/editor/icons/icon_quat.png
+++ b/tools/editor/icons/icon_quat.png
Binary files differ
diff --git a/tools/editor/icons/icon_rating_no_star.png b/tools/editor/icons/icon_rating_no_star.png
new file mode 100644
index 0000000000..76f1127ccc
--- /dev/null
+++ b/tools/editor/icons/icon_rating_no_star.png
Binary files differ
diff --git a/tools/editor/icons/icon_rating_star.png b/tools/editor/icons/icon_rating_star.png
new file mode 100644
index 0000000000..ff52bddba0
--- /dev/null
+++ b/tools/editor/icons/icon_rating_star.png
Binary files differ
diff --git a/tools/editor/icons/icon_real.png b/tools/editor/icons/icon_real.png
index 80fbf7017c..7f5bf08ede 100644
--- a/tools/editor/icons/icon_real.png
+++ b/tools/editor/icons/icon_real.png
Binary files differ
diff --git a/tools/editor/icons/icon_rect2.png b/tools/editor/icons/icon_rect2.png
index e9293b5fad..cf3cfe3b22 100644
--- a/tools/editor/icons/icon_rect2.png
+++ b/tools/editor/icons/icon_rect2.png
Binary files differ
diff --git a/tools/editor/icons/icon_rect3.png b/tools/editor/icons/icon_rect3.png
index e1e81f84e7..8eacfff207 100644
--- a/tools/editor/icons/icon_rect3.png
+++ b/tools/editor/icons/icon_rect3.png
Binary files differ
diff --git a/tools/editor/icons/icon_reload_empty.png b/tools/editor/icons/icon_reload_empty.png
new file mode 100644
index 0000000000..d43582b2c4
--- /dev/null
+++ b/tools/editor/icons/icon_reload_empty.png
Binary files differ
diff --git a/tools/editor/icons/icon_reload_small.png b/tools/editor/icons/icon_reload_small.png
new file mode 100644
index 0000000000..957cdfcf4f
--- /dev/null
+++ b/tools/editor/icons/icon_reload_small.png
Binary files differ
diff --git a/tools/editor/icons/icon_string.png b/tools/editor/icons/icon_string.png
index 48bf753c40..4a747f7c62 100644
--- a/tools/editor/icons/icon_string.png
+++ b/tools/editor/icons/icon_string.png
Binary files differ
diff --git a/tools/editor/icons/icon_thumbnail_wait.png b/tools/editor/icons/icon_thumbnail_wait.png
new file mode 100644
index 0000000000..96a7d424e3
--- /dev/null
+++ b/tools/editor/icons/icon_thumbnail_wait.png
Binary files differ
diff --git a/tools/editor/icons/icon_vector.png b/tools/editor/icons/icon_vector.png
index 0ee33ba0b7..0bda8ff7c0 100644
--- a/tools/editor/icons/icon_vector.png
+++ b/tools/editor/icons/icon_vector.png
Binary files differ
diff --git a/tools/editor/icons/icon_vector2.png b/tools/editor/icons/icon_vector2.png
index 5920109a55..5bfd08f52a 100644
--- a/tools/editor/icons/icon_vector2.png
+++ b/tools/editor/icons/icon_vector2.png
Binary files differ
diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp
index 9b4ca246e7..ff126a8e8c 100644
--- a/tools/editor/io_plugins/editor_font_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp
@@ -540,7 +540,7 @@ class EditorFontImportDialog : public ConfirmationDialog {
return;
}
- //_import_inc(dest->get_line_edit()->get_text());
+ _import_inc(dest->get_line_edit()->get_text());
hide();
}
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index 7de9d978f2..f008c4a736 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -1372,7 +1372,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
DVector<float> tangents;
print_line("vertex source id: "+vertex_src_id);
if(md.vertices[vertex_src_id].sources.has("NORMAL")){
- //has normals
+ //has normals
normals.resize(vlen);
//std::cout << "has normals" << std::endl;
String normal_src_id = md.vertices[vertex_src_id].sources["NORMAL"];
@@ -1386,7 +1386,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
if (stride==0)
stride=3;
-
+
//read normals from morph target
DVector<Vector3>::Write vertw = normals.write();
@@ -1421,7 +1421,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
}
}
}
-
+
print_line("using built-in normals");
}else{
print_line("generating normals");
@@ -2070,7 +2070,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
animation->add_track(Animation::TYPE_TRANSFORM);
- int track = animation->get_track_count() -1;
+ int track = animation->get_track_count() -1;
animation->track_set_path( track , path );
Vector<float> snapshots = base_snapshots;
diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp
index b81c88c817..5408e43e1a 100644
--- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp
@@ -481,10 +481,10 @@ Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceI
float mu = pos-Math::floor(pos);
int ipos = int(Math::floor(pos));
- float y0=data[MAX(0,ipos-i)];
- float y1=data[ipos];
- float y2=data[MIN(len-1,ipos+1)];
- float y3=data[MIN(len-1,ipos+2)];
+ float y0=data[MAX(0,ipos-1)*chans+c];
+ float y1=data[ipos*chans+c];
+ float y2=data[MIN(len-1,ipos+1)*chans+c];
+ float y3=data[MIN(len-1,ipos+2)*chans+c];
float mu2 = mu*mu;
float a0 = y3 - y2 - y0 + y1;
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index a3b6827cd4..15e7a70111 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -57,11 +57,12 @@ void EditorScenePostImport::_bind_methods() {
}
-Error EditorScenePostImport::post_import(Node* p_scene) {
+Node *EditorScenePostImport::post_import(Node* p_scene) {
if (get_script_instance())
- return Error(int(get_script_instance()->call("post_import",p_scene)));
- return OK;
+ return get_script_instance()->call("post_import",p_scene);
+
+ return p_scene;
}
EditorScenePostImport::EditorScenePostImport() {
@@ -461,7 +462,7 @@ EditorImportAnimationOptions::EditorImportAnimationOptions() {
items.push_back(ti);
fname++;
fdescr++;
- }
+ }
TreeItem *fps_base = flags->create_item(root);
@@ -2748,8 +2749,8 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
if (post_import_script.is_valid()) {
- err = post_import_script->post_import(scene);
- if (err) {
+ scene = post_import_script->post_import(scene);
+ if (!scene) {
EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path);
return err;
}
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h
index 1f3b73fe7f..a1a090de7e 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.h
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.h
@@ -87,7 +87,7 @@ protected:
static void _bind_methods();
public:
- virtual Error post_import(Node* p_scene);
+ virtual Node* post_import(Node* p_scene);
EditorScenePostImport();
};
diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
index 29273ebd06..ea7242c185 100644
--- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -1549,7 +1549,7 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
}
uint32_t flags = rimd->get_option("flags");
- uint8_t shrink = rimd->has_option("shrink") ? rimd->get_option("shrink"): Variant(1);
+ uint8_t shrink = rimd->has_option("shrink") ? rimd->get_option("shrink"): Variant(1);
uint8_t format = rimd->get_option("format");
uint8_t comp = (format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM)?uint8_t(p_platform->get_image_compression()):uint8_t(255);
@@ -1633,7 +1633,7 @@ EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode
singleton[p_mode]=this;
editor=p_editor;
- mode=p_mode;
+ mode=p_mode;
dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS || p_mode==MODE_LARGE,p_mode==MODE_ATLAS,p_mode==MODE_LARGE) );
editor->get_gui_base()->add_child(dialog);
diff --git a/tools/editor/output_strings.cpp b/tools/editor/output_strings.cpp
index a19352f4ec..f1b49d2326 100644
--- a/tools/editor/output_strings.cpp
+++ b/tools/editor/output_strings.cpp
@@ -84,7 +84,7 @@ void OutputStrings::_notification(int p_what) {
Ref<Texture> icon_warning = get_icon("Warning","EditorIcons");
// int lines = (size_height-(int)margin.y) / font_height;
- Point2 ofs=tree_st->get_offset();
+ Point2 ofs=tree_st->get_offset();
LineMap::Element *E = line_map.find(v_scroll->get_val());
float h_ofs = (int)h_scroll->get_val();
diff --git a/tools/editor/output_strings.h b/tools/editor/output_strings.h
index 3d5deb1646..29c6ea799f 100644
--- a/tools/editor/output_strings.h
+++ b/tools/editor/output_strings.h
@@ -81,7 +81,7 @@ protected:
public:
- void add_line(const String& p_text, const Variant& p_meta=Variant(), const LineType p_type=LINE_NORMAL);
+ void add_line(const String& p_text, const Variant& p_meta=Variant(), const LineType p_type=LINE_NORMAL);
OutputStrings();
};
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 0e2977c5a1..0b06aab447 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -621,10 +621,11 @@ void AnimationPlayerEditor::ensure_visibility() {
Dictionary AnimationPlayerEditor::get_state() const {
+
Dictionary d;
d["visible"]=is_visible();
- if (is_visible() && player) {
+ if (EditorNode::get_singleton()->get_edited_scene() && is_visible() && player) {
d["player"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(player);
d["animation"]=player->get_current_animation();
@@ -637,6 +638,9 @@ void AnimationPlayerEditor::set_state(const Dictionary& p_state) {
if (p_state.has("visible") && p_state["visible"]) {
+ if (!EditorNode::get_singleton()->get_edited_scene())
+ return;
+
Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]);
if (n && n->cast_to<AnimationPlayer>()) {
player=n->cast_to<AnimationPlayer>();
@@ -727,7 +731,7 @@ void AnimationPlayerEditor::_dialog_action(String p_file) {
String current = animation->get_item_text(animation->get_selected());
if (current != "") {
Ref<Animation> anim = player->get_animation(current);
-
+
ERR_FAIL_COND(!anim->cast_to<Resource>())
RES current_res = RES(anim->cast_to<Resource>());
@@ -942,6 +946,14 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value) {
anim=player->get_animation(current);
float pos = anim->get_length() * (p_value / frame->get_max());
+ float step = anim->get_step();
+ if (step) {
+ pos=Math::stepify(pos, step);
+ if (pos<0)
+ pos=0;
+ if (pos>=anim->get_length())
+ pos=anim->get_length();
+ }
if (player->is_valid()) {
float cpos = player->get_current_animation_pos();
@@ -1298,7 +1310,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
frame = memnew( SpinBox );
hb->add_child(frame);
- frame->set_custom_minimum_size(Size2(80,0));
+ frame->set_custom_minimum_size(Size2(60,0));
frame->set_stretch_ratio(2);
frame->set_tooltip("Animation position (in seconds).");
@@ -1412,7 +1424,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
add_child(error_dialog);
name_dialog->connect("confirmed", this,"_animation_name_edited");
-
+
blend_editor.dialog = memnew( AcceptDialog );
add_child(blend_editor.dialog);
blend_editor.dialog->get_ok()->set_text("Close");
@@ -1429,7 +1441,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
updating_blends=false;
blend_editor.tree->connect("item_edited",this,"_blend_edited");
-
+
autoplay->connect("pressed", this,"_autoplay_pressed");
autoplay->set_toggle_mode(true);
diff --git a/tools/editor/plugins/animation_tree_editor_plugin.cpp b/tools/editor/plugins/animation_tree_editor_plugin.cpp
index d85553b4db..08c2a1c3ae 100644
--- a/tools/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_tree_editor_plugin.cpp
@@ -593,7 +593,7 @@ void AnimationTreeEditor::_draw_node(const StringName& p_node) {
} break;
case AnimationTreePlayer::NODE_ONESHOT:
- case AnimationTreePlayer::NODE_MIX:
+ case AnimationTreePlayer::NODE_MIX:
case AnimationTreePlayer::NODE_BLEND2:
case AnimationTreePlayer::NODE_BLEND3:
case AnimationTreePlayer::NODE_BLEND4:
@@ -1155,7 +1155,7 @@ StringName AnimationTreeEditor::_add_node(int p_item) {
anim_tree->node_set_pos(name,Point2(last_x,last_y));
order.push_back(name);
last_x+=10;
- last_y+=10;
+ last_y+=10;
last_x=last_x % (int)get_size().width;
last_y=last_y % (int)get_size().height;
update();
diff --git a/tools/editor/plugins/baked_light_baker.h b/tools/editor/plugins/baked_light_baker.h
index 8fbeeddc6a..5c172f79c6 100644
--- a/tools/editor/plugins/baked_light_baker.h
+++ b/tools/editor/plugins/baked_light_baker.h
@@ -96,7 +96,7 @@ public:
struct Triangle {
- AABB aabb;
+ AABB aabb;
Vector3 vertices[3];
Vector2 uvs[3];
Vector2 bake_uvs[3];
diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp
index 26524b2437..56aabaf6d9 100644
--- a/tools/editor/plugins/baked_light_editor_plugin.cpp
+++ b/tools/editor/plugins/baked_light_editor_plugin.cpp
@@ -131,7 +131,7 @@ void BakedLightEditor::_notification(int p_option) {
last_rays_time=rays_snap;
bake_info->set_text("rays/s: "+itos(rays_sec));
- update_timeout=1;
+ update_timeout=1;
print_line("MSUPDATE: "+itos(OS::get_singleton()->get_ticks_msec()-t));
t=OS::get_singleton()->get_ticks_msec();
node->get_baked_light()->set_octree(octree_texture);
@@ -332,7 +332,7 @@ BakedLightEditorPlugin::BakedLightEditorPlugin(EditorNode *p_node) {
editor=p_node;
baked_light_editor = memnew( BakedLightEditor );
editor->get_viewport()->add_child(baked_light_editor);
- add_custom_control(CONTAINER_SPATIAL_EDITOR_MENU,baked_light_editor->bake_hbox);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU,baked_light_editor->bake_hbox);
baked_light_editor->hide();
baked_light_editor->bake_hbox->hide();
}
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index 0afea26957..6eb26542be 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -49,10 +49,10 @@ friend class CanvasItemEditor;
SpinBox *grid_offset_x;
SpinBox *grid_offset_y;
SpinBox *grid_step_x;
- SpinBox *grid_step_y;
- SpinBox *rotation_offset;
+ SpinBox *grid_step_y;
+ SpinBox *rotation_offset;
SpinBox *rotation_step;
-
+
public:
SnapDialog() : ConfirmationDialog() {
const int SPIN_BOX_GRID_RANGE = 256;
@@ -134,7 +134,7 @@ public:
rotation_step->set_suffix("deg");
child_container->add_child(rotation_step);
}
-
+
void set_fields(const Point2 p_grid_offset, const Size2 p_grid_step, const float p_rotation_offset, const float p_rotation_step) {
grid_offset_x->set_val(p_grid_offset.x);
grid_offset_y->set_val(p_grid_offset.y);
@@ -143,7 +143,7 @@ public:
rotation_offset->set_val(p_rotation_offset * (180 / Math_PI));
rotation_step->set_val(p_rotation_step * (180 / Math_PI));
}
-
+
void get_fields(Point2 &p_grid_offset, Size2 &p_grid_step, float &p_rotation_offset, float &p_rotation_step) {
p_grid_offset.x = grid_offset_x->get_val();
p_grid_offset.y = grid_offset_y->get_val();
@@ -409,7 +409,7 @@ void CanvasItemEditor::_node_removed(Node *p_node) {
void CanvasItemEditor::_keying_changed() {
- if (AnimationPlayerEditor::singleton->get_key_editor()->has_keying())
+ if (AnimationPlayerEditor::singleton->get_key_editor()->is_visible())
animation_hb->show();
else
animation_hb->hide();
@@ -1328,7 +1328,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
first=false;
}
- BoneIK bik;
+ BoneIK bik;
bik.node=b;
bik.len=len;
bik.orig_state=b->edit_get_state();
@@ -1560,7 +1560,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
Matrix32 rot;
rot.elements[1] = (dfrom - center).normalized();
rot.elements[0] = rot.elements[1].tangent();
- node->set_rot(snap_angle(rot.xform_inv(dto-center).angle(), node->get_rot()));
+ node->set_rot(snap_angle(rot.xform_inv(dto-center).angle() + node->get_rot(), node->get_rot()));
display_rotate_to = dto;
display_rotate_from = center;
viewport->update();
@@ -2233,6 +2233,8 @@ void CanvasItemEditor::_notification(int p_what) {
p->add_icon_item(get_icon("ControlAlignWide","EditorIcons"),"Full Rect",ANCHOR_ALIGN_WIDE);
+ AnimationPlayerEditor::singleton->get_key_editor()->connect("visibility_changed",this,"_keying_changed");
+ _keying_changed();
}
if (p_what==NOTIFICATION_READY) {
@@ -2668,7 +2670,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
}
#endif
} break;
-
+
case SPACE_HORIZONTAL: {
//space_selected_items< proj_vector2_x, compare_items_x >();
} break;
@@ -3162,7 +3164,7 @@ bool CanvasItemEditor::box_selection_end() {
SWAP(bsfrom.x,bsto.x);
if (bsfrom.y>bsto.y)
SWAP(bsfrom.y,bsto.y);
-
+
if ( bsfrom.distance_to( bsto ) < 3 ) {
print_line( "box selection too small" );
box_selecting=false;
@@ -3181,7 +3183,7 @@ bool CanvasItemEditor::box_selection_end() {
box_selecting=false;
viewport->update();
-
+
return true;
}
#endif
@@ -3477,7 +3479,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
box_selecting=false;
//zoom=0.5;
singleton=this;
- AnimationPlayerEditor::singleton->get_key_editor()->connect("keying_changed",this,"_keying_changed");
+
set_process_unhandled_key_input(true);
can_move_pivot=false;
drag=DRAG_NONE;
@@ -3528,6 +3530,7 @@ CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) {
editor=p_node;
canvas_item_editor = memnew( CanvasItemEditor(editor) );
+ canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor->get_viewport()->add_child(canvas_item_editor);
canvas_item_editor->set_area_as_parent_rect();
canvas_item_editor->hide();
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h
index df24734fd7..301c67756c 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.h
+++ b/tools/editor/plugins/canvas_item_editor_plugin.h
@@ -302,11 +302,11 @@ class CanvasItemEditor : public VBoxContainer {
bool _select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag=true);
ConfirmationDialog *snap_dialog;
-
+
AcceptDialog *value_dialog;
Label *dialog_label;
SpinBox *dialog_val;
-
+
CanvasItem *ref_item;
void _edit_set_pivot(const Vector2& mouse_pos);
@@ -369,29 +369,29 @@ protected:
bool box_selection_end();
HBoxContainer *get_panel_hb() { return hb; }
-
+
struct compare_items_x {
bool operator()( const CanvasItem *a, const CanvasItem *b ) const {
return a->get_global_transform().elements[2].x < b->get_global_transform().elements[2].x;
}
};
-
+
struct compare_items_y {
bool operator()( const CanvasItem *a, const CanvasItem *b ) const {
return a->get_global_transform().elements[2].y < b->get_global_transform().elements[2].y;
}
};
-
+
struct proj_vector2_x {
float get( const Vector2 &v ) { return v.x; }
void set( Vector2 &v, float f ) { v.x = f; }
};
-
+
struct proj_vector2_y {
float get( const Vector2 &v ) { return v.y; }
void set( Vector2 &v, float f ) { v.y = f; }
};
-
+
template< class P, class C > void space_selected_items();
static CanvasItemEditor *singleton;
diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_editor_plugin.cpp
index d4198f3166..44854e655f 100644
--- a/tools/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -40,7 +40,7 @@ void CollisionPolygonEditor::_notification(int p_what) {
case NOTIFICATION_READY: {
button_create->set_icon( get_icon("Edit","EditorIcons"));
- button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
+ button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
button_edit->set_pressed(true);
get_tree()->connect("node_removed",this,"_node_removed");
diff --git a/tools/editor/plugins/collision_shape_2d_editor_plugin.cpp b/tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 7e5d52d17d..1916d55ee1 100644
--- a/tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -451,11 +451,11 @@ void CollisionShape2DEditor::_canvas_draw() {
case LINE_SHAPE: {
Ref<LineShape2D> shape = node->get_shape();
-
+
handles.resize(2);
handles[0] = shape->get_normal() * shape->get_d();
handles[1] = shape->get_normal() * (shape->get_d() + 30.0);
-
+
c->draw_texture(h,gt.xform(handles[0])-size);
c->draw_texture(h,gt.xform(handles[1])-size);
diff --git a/tools/editor/plugins/color_ramp_editor_plugin.cpp b/tools/editor/plugins/color_ramp_editor_plugin.cpp
index 42ff1b1de9..133775115d 100644
--- a/tools/editor/plugins/color_ramp_editor_plugin.cpp
+++ b/tools/editor/plugins/color_ramp_editor_plugin.cpp
@@ -13,9 +13,9 @@ ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node, bool p_2d) {
_2d=p_2d;
if (p_2d)
- add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
+ add_control_to_container(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
else
- add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
ramp_editor->set_custom_minimum_size(Size2(100, 48));
ramp_editor->hide();
diff --git a/tools/editor/plugins/control_editor_plugin.cpp b/tools/editor/plugins/control_editor_plugin.cpp
index 375622a89c..9dff5e6ce4 100644
--- a/tools/editor/plugins/control_editor_plugin.cpp
+++ b/tools/editor/plugins/control_editor_plugin.cpp
@@ -80,16 +80,16 @@ void ControlEditor::_node_removed(Node *p_node) {
// slow as hell
Control* ControlEditor::_select_control_at_pos(const Point2& p_pos,Node* p_node) {
-
+
for (int i=p_node->get_child_count()-1;i>=0;i--) {
-
+
Control *r=_select_control_at_pos(p_pos,p_node->get_child(i));
if (r)
return r;
}
-
+
Control *c=p_node->cast_to<Control>();
-
+
if (c) {
Rect2 rect = c->get_window_rect();
if (c->get_window()==current_window) {
@@ -123,9 +123,9 @@ void ControlEditor::_key_move(const Vector2& p_dir, bool p_snap) {
void ControlEditor::_input_event(InputEvent p_event) {
-
+
if (p_event.type==InputEvent::MOUSE_BUTTON) {
-
+
const InputEventMouseButton &b=p_event.mouse_button;
if (b.button_index==BUTTON_RIGHT) {
@@ -146,12 +146,12 @@ void ControlEditor::_input_event(InputEvent p_event) {
}
//if (!controls.size())
// return;
-
+
if (b.button_index!=BUTTON_LEFT)
return;
if (!b.pressed) {
-
+
if (drag!=DRAG_NONE) {
if (undo_redo) {
@@ -321,11 +321,11 @@ void ControlEditor::_input_event(InputEvent p_event) {
}
}
-
+
if (p_event.type==InputEvent::MOUSE_MOTION) {
-
+
const InputEventMouseMotion &m=p_event.mouse_motion;
-
+
if (drag==DRAG_NONE || !current_window)
return;
@@ -449,7 +449,7 @@ void ControlEditor::_input_event(InputEvent p_event) {
}
-
+
}
@@ -492,9 +492,9 @@ void ControlEditor::_update_scroll(float) {
}
void ControlEditor::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_PROCESS) {
-
+
for(ControlMap::Element *E=controls.front();E;E=E->next()) {
Control *control = E->key();
@@ -504,16 +504,16 @@ void ControlEditor::_notification(int p_what) {
E->get().last_rect=r;
}
}
-
+
}
-
+
if (p_what==NOTIFICATION_CHILDREN_CONFIGURED) {
-
+
get_scene()->connect("node_removed",this,"_node_removed");
}
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
// TODO fetch the viewport?
/*
if (!control) {
@@ -572,11 +572,11 @@ VisualServer::get_singleton()->canvas_item_add_rect(ci,m_rect,m_color);
//DRAW_EMPTY_RECT( Rect2( current_window->get_scroll()-Point2(1,1), get_size()+Size2(2,2)), Color(0.8,0.8,1.0,0.8) );
E->get().last_rect = rect;
}
- }
+ }
}
void ControlEditor::edit(Control *p_control) {
-
+
drag=DRAG_NONE;
_clear_controls();
@@ -727,9 +727,9 @@ void ControlEditor::_popup_callback(int p_op) {
}
void ControlEditor::_bind_methods() {
-
+
ObjectTypeDB::bind_method("_input_event",&ControlEditor::_input_event);
- ObjectTypeDB::bind_method("_node_removed",&ControlEditor::_node_removed);
+ ObjectTypeDB::bind_method("_node_removed",&ControlEditor::_node_removed);
ObjectTypeDB::bind_method("_update_scroll",&ControlEditor::_update_scroll);
ObjectTypeDB::bind_method("_popup_callback",&ControlEditor::_popup_callback);
ObjectTypeDB::bind_method("_visibility_changed",&ControlEditor::_visibility_changed);
@@ -781,13 +781,13 @@ ControlEditor::ControlEditor(EditorNode *p_editor) {
void ControlEditorPlugin::edit(Object *p_object) {
-
+
control_editor->set_undo_redo(&get_undo_redo());
control_editor->edit(p_object->cast_to<Control>());
}
bool ControlEditorPlugin::handles(Object *p_object) const {
-
+
return p_object->is_type("Control");
}
@@ -797,7 +797,7 @@ void ControlEditorPlugin::make_visible(bool p_visible) {
control_editor->show();
control_editor->set_process(true);
} else {
-
+
control_editor->hide();
control_editor->set_process(false);
}
@@ -805,14 +805,14 @@ void ControlEditorPlugin::make_visible(bool p_visible) {
}
ControlEditorPlugin::ControlEditorPlugin(EditorNode *p_node) {
-
+
editor=p_node;
control_editor = memnew( ControlEditor(editor) );
editor->get_viewport()->add_child(control_editor);
control_editor->set_area_as_parent_rect();
control_editor->hide();
-
+
}
diff --git a/tools/editor/plugins/control_editor_plugin.h b/tools/editor/plugins/control_editor_plugin.h
index 94cffc8d8d..6234698ee8 100644
--- a/tools/editor/plugins/control_editor_plugin.h
+++ b/tools/editor/plugins/control_editor_plugin.h
@@ -37,9 +37,9 @@
#if 0
class ControlEditor : public Control {
-
- OBJ_TYPE(ControlEditor, Control );
-
+
+ OBJ_TYPE(ControlEditor, Control );
+
EditorNode *editor;
enum {
@@ -103,13 +103,13 @@ class ControlEditor : public Control {
void _find_controls_span(Node *p_node, Rect2& r_rect);
-protected:
+protected:
void _notification(int p_what);
- void _input_event(InputEvent p_event);
+ void _input_event(InputEvent p_event);
void _node_removed(Node *p_node);
static void _bind_methods();
-public:
-
+public:
+
bool get_remove_list(List<Node*> *p_list);
void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; }
void edit(Control *p_control);
@@ -117,14 +117,14 @@ public:
};
class ControlEditorPlugin : public EditorPlugin {
-
+
OBJ_TYPE( ControlEditorPlugin, EditorPlugin );
-
+
ControlEditor *control_editor;
EditorNode *editor;
-
+
public:
-
+
virtual String get_name() const { return "GUI"; }
bool has_main_screen() const { return true; }
virtual void edit(Object *p_object);
@@ -132,7 +132,7 @@ public:
virtual void make_visible(bool p_visible);
virtual bool get_remove_list(List<Node*> *p_list) { return control_editor->get_remove_list(p_list); }
-
+
ControlEditorPlugin(EditorNode *p_node);
~ControlEditorPlugin();
diff --git a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp b/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp
index c861a5841a..ab4f14b806 100644
--- a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp
+++ b/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "cube_grid_theme_editor_plugin.h"
-
+
#include "scene/3d/mesh_instance.h"
#include "scene/3d/physics_body.h"
#include "scene/main/viewport.h"
@@ -337,7 +337,7 @@ MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) {
theme_editor->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
theme_editor->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_BEGIN );
theme_editor->set_end( Point2(0,22) );
- theme_editor->hide();
+ theme_editor->hide();
}
diff --git a/tools/editor/plugins/editor_preview_plugins.cpp b/tools/editor/plugins/editor_preview_plugins.cpp
index f3b5272571..12d50cd4b8 100644
--- a/tools/editor/plugins/editor_preview_plugins.cpp
+++ b/tools/editor/plugins/editor_preview_plugins.cpp
@@ -725,7 +725,11 @@ Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) {
} else {
half=1;
ofs=h/2;
- v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0;
+ if( (float)(h/2) != 0 ) {
+ v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0;
+ } else {
+ v = ((j-(h/2))/(float)(1/2)) * 2.0 - 1.0;
+ }
}
uint8_t* imgofs = &imgw[(j*w+i)*3];
diff --git a/tools/editor/plugins/item_list_editor_plugin.cpp b/tools/editor/plugins/item_list_editor_plugin.cpp
index 6f0db959ba..08af1a0643 100644
--- a/tools/editor/plugins/item_list_editor_plugin.cpp
+++ b/tools/editor/plugins/item_list_editor_plugin.cpp
@@ -119,7 +119,7 @@ void ItemListOptionButtonPlugin::set_object(Object *p_object) {
bool ItemListOptionButtonPlugin::handles(Object *p_object) const {
- return p_object->is_type("OptionButton");
+ return p_object->is_type("OptionButton");
}
int ItemListOptionButtonPlugin::get_flags() const {
@@ -130,23 +130,23 @@ int ItemListOptionButtonPlugin::get_flags() const {
void ItemListOptionButtonPlugin::add_item() {
ob->add_item( "Item "+itos(ob->get_item_count()));
- _change_notify();
+ _change_notify();
}
int ItemListOptionButtonPlugin::get_item_count() const {
- return ob->get_item_count();
+ return ob->get_item_count();
}
void ItemListOptionButtonPlugin::erase(int p_idx) {
- ob->remove_item(p_idx);
+ ob->remove_item(p_idx);
_change_notify();
}
ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() {
- ob=NULL;
+ ob=NULL;
}
///////////////////////////////////////////////////////////////
@@ -259,7 +259,7 @@ void ItemListEditor::edit(Node *p_item_list) {
item_plugins[i]->set_object(p_item_list);
property_editor->edit(item_plugins[i]);
-
+
if (has_icon(item_list->get_type(), "EditorIcons"))
toolbar_button->set_icon(get_icon(item_list->get_type(), "EditorIcons"));
else
diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/tools/editor/plugins/multimesh_editor_plugin.cpp
index 3f63ef706b..15df9a6262 100644
--- a/tools/editor/plugins/multimesh_editor_plugin.cpp
+++ b/tools/editor/plugins/multimesh_editor_plugin.cpp
@@ -326,7 +326,7 @@ MultiMeshEditor::MultiMeshEditor() {
options = memnew( MenuButton );
SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
-
+
options->set_text("MultiMesh");
options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MultiMeshInstance","EditorIcons"));
diff --git a/tools/editor/plugins/particles_2d_editor_plugin.cpp b/tools/editor/plugins/particles_2d_editor_plugin.cpp
index 2488c4cdd9..297145f408 100644
--- a/tools/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/particles_2d_editor_plugin.cpp
@@ -26,10 +26,11 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "particles_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
#include "io/image_loader.h"
-
+#include "scene/gui/separator.h"
void Particles2DEditorPlugin::edit(Object *p_object) {
@@ -49,12 +50,10 @@ void Particles2DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- sep->show();
- menu->show();
+ toolbar->show();
} else {
- menu->hide();
- sep->hide();
+ toolbar->hide();
}
}
@@ -164,35 +163,36 @@ Particles2DEditorPlugin::Particles2DEditorPlugin(EditorNode *p_node) {
particles=NULL;
editor=p_node;
undo_redo=editor->get_undo_redo();
- sep = memnew( VSeparator );
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(sep);
- sep->hide();
+
+ toolbar = memnew( HBoxContainer );
+ add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
+ toolbar->hide();
+
+ toolbar->add_child( memnew( VSeparator ) );
menu = memnew( MenuButton );
menu->get_popup()->add_item("Load Emission Mask",MENU_LOAD_EMISSION_MASK);
menu->get_popup()->add_item("Clear Emission Mask",MENU_CLEAR_EMISSION_MASK);
menu->set_text("Particles");
+ toolbar->add_child(menu);
- file = memnew(EditorFileDialog);
- add_child(file);
+ file = memnew( EditorFileDialog );
List<String> ext;
ImageLoader::get_recognized_extensions(&ext);
for(List<String>::Element *E=ext.front();E;E=E->next()) {
file->add_filter("*."+E->get()+"; "+E->get().to_upper());
}
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(menu);
+ toolbar->add_child(file);
+
epoints = memnew( SpinBox );
epoints->set_min(1);
epoints->set_max(8192);
epoints->set_step(1);
epoints->set_val(512);
file->get_vbox()->add_margin_child("Generated Point Count:",epoints);
- menu->hide();
-
}
-
Particles2DEditorPlugin::~Particles2DEditorPlugin()
{
}
diff --git a/tools/editor/plugins/particles_2d_editor_plugin.h b/tools/editor/plugins/particles_2d_editor_plugin.h
index f70a0e7b76..ce2056b482 100644
--- a/tools/editor/plugins/particles_2d_editor_plugin.h
+++ b/tools/editor/plugins/particles_2d_editor_plugin.h
@@ -33,7 +33,7 @@
#include "tools/editor/editor_node.h"
#include "scene/2d/collision_polygon_2d.h"
-#include "scene/gui/separator.h"
+#include "scene/gui/box_container.h"
#include "scene/gui/file_dialog.h"
#include "scene/2d/particles_2d.h"
@@ -47,14 +47,14 @@ class Particles2DEditorPlugin : public EditorPlugin {
MENU_CLEAR_EMISSION_MASK
};
+ Particles2D *particles;
EditorFileDialog *file;
EditorNode *editor;
+ HBoxContainer *toolbar;
MenuButton *menu;
- VSeparator *sep;
- Particles2D *particles;
SpinBox *epoints;
UndoRedo *undo_redo;
diff --git a/tools/editor/plugins/path_editor_plugin.cpp b/tools/editor/plugins/path_editor_plugin.cpp
index b99e632604..3c4428bdb0 100644
--- a/tools/editor/plugins/path_editor_plugin.cpp
+++ b/tools/editor/plugins/path_editor_plugin.cpp
@@ -267,17 +267,15 @@ PathSpatialGizmo::PathSpatialGizmo(Path* p_path){
}
-bool PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
+Ref<SpatialEditorGizmo> PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
- if (p_spatial->cast_to<Path>()) {
+ if (p_spatial->cast_to<Path>()) {
- Ref<PathSpatialGizmo> psg = memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
- p_spatial->set_gizmo(psg);
- return true;
+ return memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
}
- return false;
+ return Ref<SpatialEditorGizmo>();
}
bool PathEditorPlugin::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) {
@@ -538,7 +536,7 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_thin_material->set_flag(Material::FLAG_UNSHADED,true);
- SpatialEditor::get_singleton()->add_gizmo_plugin(this);
+// SpatialEditor::get_singleton()->add_gizmo_plugin(this);
sep = memnew( VSeparator);
sep->hide();
diff --git a/tools/editor/plugins/path_editor_plugin.h b/tools/editor/plugins/path_editor_plugin.h
index 18bad23bd1..0afd957af7 100644
--- a/tools/editor/plugins/path_editor_plugin.h
+++ b/tools/editor/plugins/path_editor_plugin.h
@@ -32,9 +32,9 @@
#include "tools/editor/spatial_editor_gizmos.h"
#include "scene/3d/path.h"
-class PathSpatialGizmo : public SpatialGizmoTool {
+class PathSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(PathSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(PathSpatialGizmo,EditorSpatialGizmo);
Path* path;
mutable Vector3 original;
@@ -83,7 +83,7 @@ public:
virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
// virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }
- virtual bool create_spatial_gizmo(Spatial* p_spatial);
+ virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual String get_name() const { return "Path"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
diff --git a/tools/editor/plugins/polygon_2d_editor_plugin.cpp b/tools/editor/plugins/polygon_2d_editor_plugin.cpp
index 3e9c58d604..849fe82645 100644
--- a/tools/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -69,7 +69,7 @@ void Polygon2DEditor::_node_removed(Node *p_node) {
if(p_node==node) {
edit(NULL);
hide();
-
+
canvas_item_editor->get_viewport_control()->update();
}
@@ -760,7 +760,7 @@ void Polygon2DEditor::edit(Node *p_collision_polygon) {
node=p_collision_polygon->cast_to<Polygon2D>();
if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
-
+
wip.clear();
wip_active=false;
edited_point=-1;
diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.cpp b/tools/editor/plugins/resource_preloader_editor_plugin.cpp
index 8490f63ff0..442046b069 100644
--- a/tools/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/tools/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -46,7 +46,7 @@ void ResourcePreloaderEditor::_notification(int p_what) {
}
if (p_what==NOTIFICATION_ENTER_TREE) {
- load->set_icon( get_icon("Folder","EditorIcons") );
+ load->set_icon( get_icon("Folder","EditorIcons") );
_delete->set_icon( get_icon("Del","EditorIcons") );
}
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index e6e90eb0db..03db293959 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -609,7 +609,7 @@ void ScriptEditor::_breaked(bool p_breaked,bool p_can_debug) {
void ScriptEditor::_show_debugger(bool p_show) {
- debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), p_show);
+// debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), p_show);
}
void ScriptEditor::_script_created(Ref<Script> p_script) {
@@ -711,7 +711,7 @@ void ScriptEditor::_close_current_tab() {
int selected = tab_container->get_current_tab();
if (selected<0 || selected>=tab_container->get_child_count())
return;
-
+
Node *tselected = tab_container->get_child(selected);
ScriptTextEditor *current = tab_container->get_child(selected)->cast_to<ScriptTextEditor>();
if (current) {
@@ -935,6 +935,9 @@ void ScriptEditor::_menu_option(int p_option) {
if (!_test_script_times_on_disk())
return;
+ save_all_scripts();
+
+#if 0
for(int i=0;i<tab_container->get_child_count();i++) {
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
@@ -951,7 +954,7 @@ void ScriptEditor::_menu_option(int p_option) {
editor->save_resource( script );
}
-
+#endif
} break;
case SEARCH_HELP: {
@@ -968,7 +971,7 @@ void ScriptEditor::_menu_option(int p_option) {
}
}
- help_index->popup_centered_ratio(0.6);
+ help_index->popup();
if (current!="") {
help_index->call_deferred("select_class",current);
@@ -976,7 +979,7 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case SEARCH_WEBSITE: {
- OS::get_singleton()->shell_open("http://www.godotengine.org/projects/godot-engine/wiki/Documentation#Tutorials");
+ OS::get_singleton()->shell_open("http://docs.godotengine.org/");
} break;
case WINDOW_NEXT: {
@@ -1781,7 +1784,8 @@ void ScriptEditor::_update_script_colors() {
if (h>hist_size) {
continue;
}
- float v = Math::ease((edit_pass-pass)/float(hist_size),0.4);
+ int non_zero_hist_size = ( hist_size == 0 ) ? 1 : hist_size;
+ float v = Math::ease((edit_pass-pass)/float(non_zero_hist_size),0.4);
script_list->set_item_custom_bg_color(i,hot_color.linear_interpolate(cold_color,v));
@@ -1924,7 +1928,12 @@ void ScriptEditor::edit(const Ref<Script>& p_script) {
ScriptTextEditor *ste = memnew( ScriptTextEditor );
ste->set_edited_script(p_script);
ste->get_text_edit()->set_tooltip_request_func(this,"_get_debug_tooltip",ste);
+ ste->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/scroll_past_end_of_file"));
ste->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/auto_brace_complete"));
+ ste->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/tab_size"));
+ ste->get_text_edit()->set_callhint_settings(
+ EditorSettings::get_singleton()->get("text_editor/put_callhint_tooltip_below_current_line"),
+ EditorSettings::get_singleton()->get("text_editor/callhint_tooltip_offset"));
tab_container->add_child(ste);
_go_to_tab(tab_container->get_tab_count()-1);
@@ -1938,9 +1947,7 @@ void ScriptEditor::edit(const Ref<Script>& p_script) {
}
}
-void ScriptEditor::save_external_data() {
-
- apply_scripts();
+void ScriptEditor::save_all_scripts() {
for(int i=0;i<tab_container->get_child_count();i++) {
@@ -1949,9 +1956,13 @@ void ScriptEditor::save_external_data() {
if (!ste)
continue;
+ if (ste->get_text_edit()->get_version()==ste->get_text_edit()->get_saved_version())
+ continue;
+
Ref<Script> script = ste->get_edited_script();
if (script->get_path()!="" && script->get_path().find("local://")==-1 &&script->get_path().find("::")==-1) {
//external script, save it
+ ste->apply_code();
editor->save_resource(script);
//ResourceSaver::save(script->get_path(),script);
}
@@ -2056,6 +2067,8 @@ void ScriptEditor::_editor_settings_changed() {
continue;
ste->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/auto_brace_complete"));
+ ste->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/scroll_past_end_of_file"));
+ ste->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/tab_size"));
}
}
@@ -2063,7 +2076,7 @@ void ScriptEditor::_editor_settings_changed() {
void ScriptEditor::_autosave_scripts() {
print_line("autosaving");
- save_external_data();
+ save_all_scripts();
}
void ScriptEditor::_tree_changed() {
@@ -2481,13 +2494,13 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
script_back->connect("pressed",this,"_history_back");
menu_hb->add_child(script_back);
script_back->set_disabled(true);
- help_search->set_tooltip("Go to previous edited document.");
+ script_back->set_tooltip("Go to previous edited document.");
script_forward = memnew( ToolButton );
script_forward->connect("pressed",this,"_history_forward");
menu_hb->add_child(script_forward);
script_forward->set_disabled(true);
- help_search->set_tooltip("Go to next edited document.");
+ script_forward->set_tooltip("Go to next edited document.");
@@ -2628,7 +2641,7 @@ void ScriptEditorPlugin::clear() {
void ScriptEditorPlugin::save_external_data() {
- script_editor->save_external_data();
+ script_editor->save_all_scripts();
}
void ScriptEditorPlugin::apply_changes() {
@@ -2672,7 +2685,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
editor=p_node;
script_editor = memnew( ScriptEditor(p_node) );
editor->get_viewport()->add_child(script_editor);
- script_editor->set_area_as_parent_rect();
+ script_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
script_editor->hide();
@@ -2694,4 +2707,3 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
ScriptEditorPlugin::~ScriptEditorPlugin()
{
}
-
diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h
index c52da41a43..5664b26580 100644
--- a/tools/editor/plugins/script_editor_plugin.h
+++ b/tools/editor/plugins/script_editor_plugin.h
@@ -295,7 +295,7 @@ public:
void swap_lines(TextEdit *tx, int line1, int line2);
- void save_external_data();
+ void save_all_scripts();
void set_window_layout(Ref<ConfigFile> p_layout);
void get_window_layout(Ref<ConfigFile> p_layout);
diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp
index 18d8f5efc0..2d3100ac0d 100644
--- a/tools/editor/plugins/shader_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_editor_plugin.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "shader_editor_plugin.h"
#include "tools/editor/editor_settings.h"
-
+
#include "spatial_editor_plugin.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
@@ -52,7 +52,7 @@ Ref<Shader> ShaderTextEditor::get_edited_shader() const {
}
void ShaderTextEditor::set_edited_shader(const Ref<Shader>& p_shader,ShaderLanguage::ShaderType p_type) {
- shader=p_shader;
+ shader=p_shader;
type=p_type;
_load_theme_settings();
@@ -578,9 +578,9 @@ ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node, bool p_2d) {
shader_editor = memnew( ShaderEditor );
_2d=p_2d;
if (p_2d)
- add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,shader_editor);
+ add_control_to_container(CONTAINER_CANVAS_EDITOR_BOTTOM,shader_editor);
else
- add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,shader_editor);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_BOTTOM,shader_editor);
// editor->get_viewport()->add_child(shader_editor);
// shader_editor->set_area_as_parent_rect();
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index 236d69dfb3..79ff78ca0d 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -1265,7 +1265,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
} else if (m.button_mask&1) {
if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) {
- nav_mode = NAVIGATION_ORBIT;
+ nav_mode = NAVIGATION_ORBIT;
} else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.shift) {
nav_mode = NAVIGATION_PAN;
} else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.control) {
@@ -1631,8 +1631,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
_edit.snap=true;
}
} break;
+ case KEY_7:
case KEY_KP_7: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_7)
+ return;
cursor.y_rot=0;
if (k.mod.shift) {
cursor.x_rot=-Math_PI/2.0;
@@ -1647,8 +1650,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
_update_name();
}
} break;
+ case KEY_1:
case KEY_KP_1: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_1)
+ return;
cursor.x_rot=0;
if (k.mod.shift) {
cursor.y_rot=Math_PI;
@@ -1664,8 +1670,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
}
} break;
+ case KEY_3:
case KEY_KP_3: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_3)
+ return;
cursor.x_rot=0;
if (k.mod.shift) {
cursor.y_rot=Math_PI/2.0;
@@ -1680,8 +1689,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
}
} break;
+ case KEY_5:
case KEY_KP_5: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_5)
+ return;
//orthogonal = !orthogonal;
_menu_option(orthogonal?VIEW_PERSPECTIVE:VIEW_ORTHOGONAL);
@@ -2072,7 +2084,9 @@ void SpatialEditorViewport::_menu_option(int p_option) {
count++;
}
- center/=float(count);
+ if( count != 0 ) {
+ center/=float(count);
+ }
cursor.pos=center;
} break;
@@ -2184,7 +2198,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
VS::get_singleton()->instance_set_scenario(move_gizmo_instance[i],get_tree()->get_root()->get_world()->get_scenario());
VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
//VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
- VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
VS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i],layer);
rotate_gizmo_instance[i]=VS::get_singleton()->instance_create();
@@ -2192,7 +2206,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i],get_tree()->get_root()->get_world()->get_scenario());
VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
//VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
- VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
VS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i],layer);
}
@@ -2573,7 +2587,7 @@ Object *SpatialEditor::_get_editor_data(Object *p_what) {
si->sp=sp;
si->sbox_instance=VisualServer::get_singleton()->instance_create2(selection_box->get_rid(),sp->get_world()->get_scenario());
- VS::get_singleton()->instance_geometry_set_flag(si->sbox_instance,VS::INSTANCE_FLAG_CAST_SHADOW,false);
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, VS::SHADOW_CASTING_SETTING_OFF);
RID inst = sp->call("_get_visual_instance_rid");
@@ -2594,15 +2608,15 @@ void SpatialEditor::_generate_selection_box() {
aabb.grow_by( aabb.get_longest_axis_size()/20.0 );
Ref<SurfaceTool> st = memnew( SurfaceTool );
-
+
st->begin(Mesh::PRIMITIVE_LINES);
for (int i=0;i<12;i++) {
-
+
Vector3 a,b;
- aabb.get_edge(i,a,b);
-
+ aabb.get_edge(i,a,b);
+
/*Vector<Vector3> points;
- Vector<Color> colors;
+ Vector<Color> colors;
points.push_back(a);
points.push_back(b);*/
@@ -2792,7 +2806,7 @@ void SpatialEditor::set_state(const Dictionary& p_state) {
void SpatialEditor::edit(Spatial *p_spatial) {
-
+
if (p_spatial!=selected) {
if (selected) {
@@ -2824,8 +2838,8 @@ void SpatialEditor::edit(Spatial *p_spatial) {
// should become the selection
}
-
-
+
+
}
void SpatialEditor::_xform_dialog_action() {
@@ -3260,8 +3274,8 @@ void SpatialEditor::_init_indicators() {
grid_visible[i]=false;
grid_enable[i]=false;
VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
- VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
- VS::get_singleton()->instance_set_layer_mask(grid_instance[i],1<<SpatialEditorViewport::GIZMO_GRID_LAYER);
+ VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(grid_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
+ VS::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << SpatialEditorViewport::GIZMO_GRID_LAYER);
}
@@ -3282,7 +3296,7 @@ void SpatialEditor::_init_indicators() {
origin_instance = VisualServer::get_singleton()->instance_create2(origin,get_tree()->get_root()->get_world()->get_scenario());
VS::get_singleton()->instance_set_layer_mask(origin_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER);
- VisualServer::get_singleton()->instance_geometry_set_flag(origin_instance,VS::INSTANCE_FLAG_CAST_SHADOW,false);
+ VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, VS::SHADOW_CASTING_SETTING_OFF);
@@ -3319,7 +3333,7 @@ void SpatialEditor::_init_indicators() {
cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_tree()->get_root()->get_world()->get_scenario());
VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER);
- VisualServer::get_singleton()->instance_geometry_set_flag(cursor_instance,VS::INSTANCE_FLAG_CAST_SHADOW,false);
+ VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(cursor_instance, VS::SHADOW_CASTING_SETTING_OFF);
}
@@ -3643,35 +3657,32 @@ void SpatialEditor::_request_gizmo(Object* p_obj) {
Spatial *sp=p_obj->cast_to<Spatial>();
if (!sp)
return;
- if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene())) {
-
- Ref<SpatialEditorGizmo> seg = gizmos->get_gizmo(sp);
+ if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene() || editor->get_edited_scene()->is_editable_instance(sp->get_owner()))) {
- if (seg.is_valid()) {
- sp->set_gizmo(seg);
- }
+ Ref<SpatialEditorGizmo> seg;
- for (List<EditorPlugin*>::Element *E=gizmo_plugins.front();E;E=E->next()) {
+ for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count();i++) {
- if (E->get()->create_spatial_gizmo(sp)) {
+ seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp);
+ if (seg.is_valid())
+ break;
+ }
- seg = sp->get_gizmo();
- if (sp==selected && seg.is_valid()) {
+ if (!seg.is_valid()) {
+ seg = gizmos->get_gizmo(sp);
+ }
- seg->set_selected(true);
- selected->update_gizmo();
- }
- return;
- }
+ if (seg.is_valid()) {
+ sp->set_gizmo(seg);
}
+
if (seg.is_valid() && sp==selected) {
seg->set_selected(true);
selected->update_gizmo();
}
}
-
}
void SpatialEditor::_toggle_maximize_view(Object* p_viewport) {
@@ -4158,7 +4169,7 @@ SpatialEditor::~SpatialEditor() {
void SpatialEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
-
+
spatial_editor->show();
spatial_editor->set_process(true);
@@ -4166,7 +4177,7 @@ void SpatialEditorPlugin::make_visible(bool p_visible) {
spatial_editor->grab_focus();
} else {
-
+
spatial_editor->hide();
spatial_editor->set_process(false);
//VisualServer::get_singleton()->viewport_set_hide_scenario(editor->get_scene_root()->get_viewport(),true);
@@ -4180,7 +4191,7 @@ void SpatialEditorPlugin::edit(Object *p_object) {
}
bool SpatialEditorPlugin::handles(Object *p_object) const {
-
+
return p_object->is_type("Spatial");
}
@@ -4214,11 +4225,13 @@ void SpatialEditorPlugin::snap_cursor_to_plane(const Plane& p_plane) {
SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) {
-
+
editor=p_node;
spatial_editor = memnew( SpatialEditor(p_node) );
+ spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor->get_viewport()->add_child(spatial_editor);
- spatial_editor->set_area_as_parent_rect();
+
+ //spatial_editor->set_area_as_parent_rect();
spatial_editor->hide();
spatial_editor->connect("transform_key_request",editor,"_transform_keyed");
@@ -4227,8 +4240,5 @@ SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) {
SpatialEditorPlugin::~SpatialEditorPlugin() {
-
-}
-
-
+}
diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h
index b0e366b140..54086b0031 100644
--- a/tools/editor/plugins/spatial_editor_plugin.h
+++ b/tools/editor/plugins/spatial_editor_plugin.h
@@ -278,7 +278,7 @@ public:
};
class SpatialEditor : public VBoxContainer {
-
+
OBJ_TYPE(SpatialEditor, VBoxContainer );
public:
@@ -338,7 +338,7 @@ private:
Ref<Mesh> selection_box;
RID indicators;
- RID indicators_instance;
+ RID indicators_instance;
RID cursor_mesh;
RID cursor_instance;
RID indicator_mat;
@@ -352,7 +352,7 @@ private:
Spatial *sp;
RID poly_instance;
};
-
+
Map<uint32_t,Selected> selected;
*/
struct Gizmo {
@@ -361,8 +361,8 @@ private:
float scale;
Transform transform;
} gizmo;
-
-
+
+
enum MenuOption {
@@ -457,8 +457,6 @@ private:
Ref<Environment> viewport_environment;
- List<EditorPlugin*> gizmo_plugins;
-
Spatial *selected;
void _request_gizmo(Object* p_obj);
@@ -473,7 +471,7 @@ private:
void _update_default_light_angle();
void _default_light_angle_input(const InputEvent& p_event);
-protected:
+protected:
@@ -483,7 +481,7 @@ protected:
void _unhandled_key_input(InputEvent p_event);
static void _bind_methods();
-public:
+public:
static SpatialEditor *get_singleton() { return singleton; }
@@ -518,8 +516,6 @@ public:
UndoRedo *get_undo_redo() { return undo_redo; }
- void add_gizmo_plugin(EditorPlugin* p_plugin) { gizmo_plugins.push_back(p_plugin); }
-
void add_control_to_menu_panel(Control *p_control);
VSplitContainer *get_shader_split();
@@ -545,9 +541,9 @@ public:
};
class SpatialEditorPlugin : public EditorPlugin {
-
+
OBJ_TYPE( SpatialEditorPlugin, EditorPlugin );
-
+
SpatialEditor *spatial_editor;
EditorNode *editor;
protected:
@@ -559,7 +555,7 @@ public:
SpatialEditor *get_spatial_editor() { return spatial_editor; }
virtual String get_name() const { return "3D"; }
bool has_main_screen() const { return true; }
- virtual void make_visible(bool p_visible);
+ virtual void make_visible(bool p_visible);
virtual void edit(Object *p_object);
virtual bool handles(Object *p_object) const;
diff --git a/tools/editor/progress_dialog.cpp b/tools/editor/progress_dialog.cpp
index d072ce7f83..2814101a27 100644
--- a/tools/editor/progress_dialog.cpp
+++ b/tools/editor/progress_dialog.cpp
@@ -140,6 +140,9 @@ void BackgroundProgress::end_task(const String& p_task){
////////////////////////////////////////////////
+
+ProgressDialog *ProgressDialog::singleton=NULL;
+
void ProgressDialog::_notification(int p_what) {
switch(p_what) {
@@ -237,4 +240,5 @@ ProgressDialog::ProgressDialog() {
main->set_area_as_parent_rect();
set_exclusive(true);
last_progress_tick=0;
+ singleton=this;
}
diff --git a/tools/editor/progress_dialog.h b/tools/editor/progress_dialog.h
index 539eaa8737..c254d45753 100644
--- a/tools/editor/progress_dialog.h
+++ b/tools/editor/progress_dialog.h
@@ -86,12 +86,14 @@ class ProgressDialog : public Popup {
VBoxContainer *main;
uint64_t last_progress_tick;
+ static ProgressDialog *singleton;
void _popup();
protected:
void _notification(int p_what);
public:
+ static ProgressDialog *get_singleton() { return singleton; }
void add_task(const String& p_task,const String& p_label, int p_steps);
void task_step(const String& p_task, const String& p_state, int p_step=-1, bool p_force_redraw=true);
void end_task(const String& p_task);
diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp
index 164443d001..b5e7715d93 100644
--- a/tools/editor/project_export.cpp
+++ b/tools/editor/project_export.cpp
@@ -217,6 +217,11 @@ void ProjectExportDialog::_filters_edited(String what) {
_save_export_cfg();
}
+void ProjectExportDialog::_filters_exclude_edited(String what) {
+ EditorImportExport::get_singleton()->set_export_custom_filter_exclude(what);
+ _save_export_cfg();
+}
+
void ProjectExportDialog::_quality_edited(float what) {
EditorImportExport::get_singleton()->set_export_image_quality(what);
@@ -314,6 +319,7 @@ void ProjectExportDialog::_notification(int p_what) {
export_mode->select( EditorImportExport::get_singleton()->get_export_filter() );
convert_text_scenes->set_pressed( EditorImportExport::get_singleton()->get_convert_text_scenes() );
filters->set_text( EditorImportExport::get_singleton()->get_export_custom_filter() );
+ filters_exclude->set_text( EditorImportExport::get_singleton()->get_export_custom_filter_exclude() );
if (EditorImportExport::get_singleton()->get_export_filter()!=EditorImportExport::EXPORT_SELECTED)
tree_vb->hide();
else
@@ -1083,6 +1089,7 @@ void ProjectExportDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_prop_edited"),&ProjectExportDialog::_prop_edited);
ObjectTypeDB::bind_method(_MD("_export_mode_changed"),&ProjectExportDialog::_export_mode_changed);
ObjectTypeDB::bind_method(_MD("_filters_edited"),&ProjectExportDialog::_filters_edited);
+ ObjectTypeDB::bind_method(_MD("_filters_exclude_edited"),&ProjectExportDialog::_filters_exclude_edited);
ObjectTypeDB::bind_method(_MD("_export_action"),&ProjectExportDialog::_export_action);
ObjectTypeDB::bind_method(_MD("_export_action_pck"),&ProjectExportDialog::_export_action_pck);
ObjectTypeDB::bind_method(_MD("_quality_edited"),&ProjectExportDialog::_quality_edited);
@@ -1195,8 +1202,11 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
tree->set_column_min_width(1,90);
filters = memnew( LineEdit );
- vb->add_margin_child("Filters to export non-resource files (Comma Separated, ie: *.json, *.txt):",filters);
+ vb->add_margin_child("Filters to export non-resource files (Comma Separated, eg: *.json, *.txt):",filters);
filters->connect("text_changed",this,"_filters_edited");
+ filters_exclude = memnew( LineEdit );
+ vb->add_margin_child("Filters to exclude from export (Comma Separated, eg: *.json, *.txt):",filters_exclude);
+ filters_exclude->connect("text_changed",this,"_filters_exclude_edited");
convert_text_scenes = memnew( CheckButton );
convert_text_scenes->set_text("Convert text scenes to binary on export");
diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h
index b9e49489e3..dc076ce201 100644
--- a/tools/editor/project_export.h
+++ b/tools/editor/project_export.h
@@ -75,7 +75,7 @@ private:
ConfirmationDialog *confirm;
Button *button_reload;
- LineEdit *filters;
+ LineEdit *filters, *filters_exclude;
HBoxContainer *plat_errors;
Label *platform_error_string;
@@ -155,6 +155,7 @@ private:
void _platform_selected();
void _filters_edited(String what);
+ void _filters_exclude_edited(String what);
void _update_group_tree();
void _image_filter_changed(String);
diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp
index 589d9d3d99..579eb8c7c7 100644
--- a/tools/editor/project_manager.cpp
+++ b/tools/editor/project_manager.cpp
@@ -788,7 +788,7 @@ void ProjectManager::_erase_project() {
return;
- erase_ask->set_text("Erase project from list?? (Folder contents will not be modified)");
+ erase_ask->set_text("Remove project from list?? (Folder contents will not be modified)");
erase_ask->popup_centered_minsize();
}
@@ -943,7 +943,7 @@ ProjectManager::ProjectManager() {
Button* erase = memnew( Button );
- erase->set_text("Erase");
+ erase->set_text("Remove");
tree_vb->add_child(erase);
erase->connect("pressed", this,"_erase_project");
erase_btn=erase;
@@ -970,7 +970,7 @@ ProjectManager::ProjectManager() {
erase_ask = memnew( ConfirmationDialog );
- erase_ask->get_ok()->set_text("Erase");
+ erase_ask->get_ok()->set_text("Remove");
erase_ask->get_ok()->connect("pressed", this,"_erase_project_confirm");
add_child(erase_ask);
diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp
index cbac870a6b..34bc31d20c 100644
--- a/tools/editor/project_settings.cpp
+++ b/tools/editor/project_settings.cpp
@@ -38,18 +38,18 @@
ProjectSettings *ProjectSettings::singleton=NULL;
static const char* _button_names[JOY_BUTTON_MAX]={
-"PS X, XBox A, NDS B",
-"PS Circle, XBox B, NDS A",
-"PS Square, XBox X, NDS Y",
-"PS Triangle, XBox Y, NDS X",
-"L, L1, Wii C",
+"PS X, XBox A, Nintendo B",
+"PS Circle, XBox B, Nintendo A",
+"PS Square, XBox X, Nintendo Y",
+"PS Triangle, XBox Y, Nintendo X",
+"L, L1",
"R, R1",
-"L2, Wii Z",
+"L2",
"R2",
"L3",
"R3",
-"Select, Wii -",
-"Start, Wii +",
+"Select, Nintendo -",
+"Start, Nintendo +",
"D-Pad Up",
"D-Pad Down",
"D-Pad Left",
@@ -60,6 +60,8 @@ void ProjectSettings::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
+ globals_editor->edit(Globals::get_singleton());
+
search_button->set_icon(get_icon("Zoom","EditorIcons"));
clear_button->set_icon(get_icon("Close","EditorIcons"));
@@ -97,26 +99,63 @@ void ProjectSettings::_notification(int p_what) {
}
}
-void ProjectSettings::_action_persist_toggle() {
+void ProjectSettings::_action_selected() {
+
+ TreeItem *ti=input_editor->get_selected();
+ if (!ti || !ti->is_editable(0))
+ return;
+
+ add_at="input/"+ti->get_text(0);
+}
+void ProjectSettings::_action_edited() {
TreeItem *ti=input_editor->get_selected();
if (!ti)
return;
- String name="input/"+ti->get_text(0);
+ String new_name=ti->get_text(0);
+ String old_name=add_at.substr(add_at.find("/")+1,add_at.length());
+
+ if (new_name==old_name)
+ return;
+
+ if (new_name.find("/")!=-1 || new_name.find(":")!=-1 || new_name=="") {
+
+ ti->set_text(0,old_name);
+ add_at="input/"+old_name;
+
+ message->set_text("Invalid Action (Anything goes but / or :).");
+ message->popup_centered(Size2(300,100));
+ return;
+ }
+
+ String action_prop="input/"+new_name;
+
+ if (Globals::get_singleton()->has(action_prop)) {
+
+ ti->set_text(0,old_name);
+ add_at="input/"+old_name;
- bool prev = Globals::get_singleton()->is_persisting(name);
- print_line("prev persist: "+itos(prev));
- print_line("new persist: "+itos(ti->is_checked(0)));
- if (prev==ti->is_checked(0))
+ message->set_text("Action '"+new_name+"' already exists!.");
+ message->popup_centered(Size2(300,100));
return;
+ }
+ int order = Globals::get_singleton()->get_order(add_at);
+ Array va = Globals::get_singleton()->get(add_at);
+ bool persisting = Globals::get_singleton()->is_persisting(add_at);
setting=true;
- undo_redo->create_action("Change Input Action Persistence");
- undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,ti->is_checked(0));
- undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,prev);
+ undo_redo->create_action("Rename Input Action Event");
+ undo_redo->add_do_method(Globals::get_singleton(),"clear",add_at);
+ undo_redo->add_do_method(Globals::get_singleton(),"set",action_prop,va);
+ undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",action_prop,persisting);
+ undo_redo->add_do_method(Globals::get_singleton(),"set_order",action_prop,order);
+ undo_redo->add_undo_method(Globals::get_singleton(),"clear",action_prop);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set",add_at,va);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",add_at,persisting);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_order",add_at,order);
undo_redo->add_do_method(this,"_update_actions");
undo_redo->add_undo_method(this,"_update_actions");
undo_redo->add_do_method(this,"_settings_changed");
@@ -124,6 +163,8 @@ void ProjectSettings::_action_persist_toggle() {
undo_redo->commit_action();
setting=false;
+ add_at=action_prop;
+
}
@@ -297,12 +338,24 @@ void ProjectSettings::_add_item(int p_item){
case InputEvent::JOYSTICK_MOTION: {
device_id->set_val(0);
- device_index_label->set_text("Joy Button Axis:");
+ device_index_label->set_text("Joystick Axis Index:");
device_index->clear();
- for(int i=0;i<24;i++) {
+ for(int i=0;i<JOY_AXIS_MAX*2;i++) {
+
+ String desc;
+ int ax=i/2;
+ if (ax==0 || ax==1)
+ desc=" (Left Stick)";
+ else if (ax==2 || ax==3)
+ desc=" (Right Stick)";
+ else if (ax==6)
+ desc=" (L2)";
+ else if (ax==7)
+ desc=" (R2)";
- device_index->add_item("Axis "+itos(i/2)+" "+(i&1?"+":"-"));
+
+ device_index->add_item("Axis "+itos(i/2)+" "+(i&1?"+":"-")+desc);
}
device_input->popup_centered(Size2(350,95));
@@ -310,12 +363,12 @@ void ProjectSettings::_add_item(int p_item){
case InputEvent::JOYSTICK_BUTTON: {
device_id->set_val(0);
- device_index_label->set_text("Joy Button Index:");
+ device_index_label->set_text("Joystick Button Index:");
device_index->clear();
for(int i=0;i<JOY_BUTTON_MAX;i++) {
- device_index->add_item(String(_button_names[i]));
+ device_index->add_item(itos(i)+": "+String(_button_names[i]));
}
device_input->popup_centered(Size2(350,95));
@@ -344,15 +397,6 @@ void ProjectSettings::_action_button_pressed(Object* p_obj, int p_column,int p_i
add_at="input/"+ti->get_text(0);
} else if (p_id==2) {
- //rename
-
- add_at="input/"+ti->get_text(0);
- rename_action->popup_centered();
- rename_action->get_line_edit()->set_text(ti->get_text(0));
- rename_action->get_line_edit()->set_cursor_pos(ti->get_text(0).length());
- rename_action->get_line_edit()->select_all();
-
- } else if (p_id==3) {
//remove
if (ti->get_parent()==input_editor->get_root()) {
@@ -434,15 +478,13 @@ void ProjectSettings::_update_actions() {
item->set_text(0,name);
item->add_button(0,get_icon("Add","EditorIcons"),1);
if (!Globals::get_singleton()->get_input_presets().find(pi.name)) {
- item->add_button(0,get_icon("Rename","EditorIcons"),2);
- item->add_button(0,get_icon("Remove","EditorIcons"),3);
+ item->add_button(0,get_icon("Remove","EditorIcons"),2);
+ item->set_editable(0,true);
}
item->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
- item->set_editable(0,true);
//item->set_checked(0,pi.usage&PROPERTY_USAGE_CHECKED);
-
Array actions=Globals::get_singleton()->get(pi.name);
for(int i=0;i<actions.size();i++) {
@@ -499,12 +541,23 @@ void ProjectSettings::_update_actions() {
} break;
case InputEvent::JOYSTICK_MOTION: {
- String str = "Device "+itos(ie.device)+", Axis "+itos(ie.joy_motion.axis)+" "+(ie.joy_motion.axis_value<0?"-.":"+.");
+ String desc;
+ int ax = ie.joy_motion.axis;
+
+ if (ax==0 || ax==1)
+ desc=" (Left Stick).";
+ else if (ax==2 || ax==3)
+ desc=" (Right Stick).";
+ else if (ax==6)
+ desc=" (L2).";
+ else if (ax==7)
+ desc=" (R2).";
+ String str = "Device "+itos(ie.device)+", Axis "+itos(ie.joy_motion.axis)+" "+(ie.joy_motion.axis_value<0?"-":"+")+desc;
action->set_text(0,str);
action->set_icon(0,get_icon("JoyAxis","EditorIcons"));
} break;
}
- action->add_button(0,get_icon("Remove","EditorIcons"),3);
+ action->add_button(0,get_icon("Remove","EditorIcons"),2);
action->set_metadata(0,i);
}
}
@@ -515,10 +568,10 @@ void ProjectSettings::popup_project_settings() {
//popup_centered(Size2(500,400));
popup_centered_ratio();
- globals_editor->edit(NULL);
- globals_editor->edit(Globals::get_singleton());
+ globals_editor->update_category_list();
_update_translations();
_update_autoload();
+ plugin_settings->update_plugins();
}
@@ -553,37 +606,45 @@ void ProjectSettings::_item_add() {
case 3: value=""; break;
}
- String catname = category->get_text();
+ String catname = category->get_text().strip_edges();
/*if (!catname.is_valid_identifier()) {
message->set_text("Invalid Category.\nValid characters: a-z,A-Z,0-9 or _");
message->popup_centered(Size2(300,100));
return;
}*/
- String propname = property->get_text();
+ String propname = property->get_text().strip_edges();
/*if (!propname.is_valid_identifier()) {
message->set_text("Invalid Property.\nValid characters: a-z,A-Z,0-9 or _");
message->popup_centered(Size2(300,100));
return;
}*/
- String name = catname+"/"+propname;
+ String name = catname!="" ? catname+"/"+propname : propname;
+
Globals::get_singleton()->set(name,value);
- globals_editor->edit(NULL);
- globals_editor->edit(Globals::get_singleton());
+
+ globals_editor->set_current_section(catname);
+ globals_editor->update_category_list();
+
+ _settings_changed();
}
void ProjectSettings::_item_del() {
- String catname = category->get_text();
+ String catname = category->get_text().strip_edges();
//ERR_FAIL_COND(!catname.is_valid_identifier());
- String propname = property->get_text();
+ String propname = property->get_text().strip_edges();
//ERR_FAIL_COND(!propname.is_valid_identifier());
- String name = catname+"/"+propname;
+ String name = catname!="" ? catname+"/"+propname : propname;
+
Globals::get_singleton()->set(name,Variant());
- globals_editor->get_property_editor()->update_tree();
+ globals_editor->set_current_section(catname);
+ globals_editor->update_category_list();
+
+ _settings_changed();
}
void ProjectSettings::_action_adds(String) {
@@ -635,45 +696,6 @@ void ProjectSettings::_action_add() {
}
-void ProjectSettings::_action_rename(const String &p_name) {
-
-
- if (p_name.find("/")!=-1 || p_name.find(":")!=-1 || p_name=="") {
- message->set_text("Invalid Action (Anything goes but / or :).");
- message->popup_centered(Size2(300,100));
- return;
- }
-
- String new_name = "input/"+p_name;
-
- if (Globals::get_singleton()->has(new_name)) {
- message->set_text("Action '"+p_name+"' already exists!.");
- message->popup_centered(Size2(300,100));
- return;
- }
-
- int order = Globals::get_singleton()->get_order(add_at);
- Array va = Globals::get_singleton()->get(add_at);
- bool persisting = Globals::get_singleton()->is_persisting(add_at);
-
- undo_redo->create_action("Rename Input Action Event");
- undo_redo->add_do_method(Globals::get_singleton(),"clear",add_at);
- undo_redo->add_do_method(Globals::get_singleton(),"set",new_name,va);
- undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",new_name,persisting);
- undo_redo->add_do_method(Globals::get_singleton(),"set_order",new_name,order);
- undo_redo->add_undo_method(Globals::get_singleton(),"clear",new_name);
- undo_redo->add_undo_method(Globals::get_singleton(),"set",add_at,va);
- undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",add_at,persisting);
- undo_redo->add_undo_method(Globals::get_singleton(),"set_order",add_at,order);
- undo_redo->add_do_method(this,"_update_actions");
- undo_redo->add_undo_method(this,"_update_actions");
- undo_redo->add_do_method(this,"_settings_changed");
- undo_redo->add_undo_method(this,"_settings_changed");
- undo_redo->commit_action();
-
- rename_action->hide();
-}
-
void ProjectSettings::_item_checked(const String& p_item, bool p_check) {
@@ -727,6 +749,10 @@ void ProjectSettings::_settings_changed() {
timer->start();
}
+void ProjectSettings::queue_save() {
+ _settings_changed();
+}
+
void ProjectSettings::_copy_to_platform(int p_which) {
@@ -823,6 +849,7 @@ void ProjectSettings::_autoload_edited() {
String base="autoload/"+ti->get_text(0);
String path = Globals::get_singleton()->get(base);
+ int order = Globals::get_singleton()->get_order(base);
if (path.begins_with("*"))
path=path.substr(1,path.length());
@@ -833,6 +860,8 @@ void ProjectSettings::_autoload_edited() {
undo_redo->create_action("Toggle Autoload GlobalVar");
undo_redo->add_do_property(Globals::get_singleton(),base,path);
undo_redo->add_undo_property(Globals::get_singleton(),base,Globals::get_singleton()->get(base));
+ undo_redo->add_do_method(Globals::get_singleton(),"set_order",base,order); // keep order, as config order matters for these
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_order",base,order);
undo_redo->add_do_method(this,"_update_autoload");
undo_redo->add_undo_method(this,"_update_autoload");
undo_redo->add_do_method(this,"_settings_changed");
@@ -924,10 +953,12 @@ void ProjectSettings::_autoload_delete(Object *p_item,int p_column, int p_button
if (p_button==0) {
//delete
+ int order = Globals::get_singleton()->get_order(name);
undo_redo->create_action("Remove Autoload");
undo_redo->add_do_property(Globals::get_singleton(),name,Variant());
undo_redo->add_undo_property(Globals::get_singleton(),name,Globals::get_singleton()->get(name));
undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,true);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_order",name,order);
undo_redo->add_do_method(this,"_update_autoload");
undo_redo->add_undo_method(this,"_update_autoload");
undo_redo->add_do_method(this,"_settings_changed");
@@ -935,7 +966,7 @@ void ProjectSettings::_autoload_delete(Object *p_item,int p_column, int p_button
undo_redo->commit_action();
} else {
- TreeItem *swap;
+ TreeItem *swap = NULL;
if (p_button==1) {
swap=ti->get_prev();
@@ -981,7 +1012,7 @@ void ProjectSettings::_translation_delete(Object *p_item,int p_column, int p_but
undo_redo->create_action("Remove Translation");
undo_redo->add_do_property(Globals::get_singleton(),"locale/translations",translations);
- undo_redo->add_undo_property(Globals::get_singleton(),"locale/translations",Globals::get_singleton()->get("locale/translations"));
+ undo_redo->add_undo_property(Globals::get_singleton(),"locale/translations",Globals::get_singleton()->get("locale/translations"));
undo_redo->add_do_method(this,"_update_translations");
undo_redo->add_undo_method(this,"_update_translations");
undo_redo->add_do_method(this,"_settings_changed");
@@ -1095,7 +1126,7 @@ void ProjectSettings::_translation_res_option_changed() {
ERR_FAIL_COND(!remaps.has(key));
- StringArray r = remaps[key];
+ StringArray r = remaps[key];
ERR_FAIL_INDEX(idx,r.size());
r.set(idx,path+":"+langs[which]);
remaps[key]=r;
@@ -1365,6 +1396,11 @@ void ProjectSettings::_clear_search_box() {
globals_editor->get_property_editor()->update_tree();
}
+void ProjectSettings::set_plugins_page() {
+
+ tab_container->set_current_tab( plugin_settings->get_index() );
+}
+
void ProjectSettings::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_item_selected"),&ProjectSettings::_item_selected);
@@ -1375,9 +1411,9 @@ void ProjectSettings::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_save"),&ProjectSettings::_save);
ObjectTypeDB::bind_method(_MD("_action_add"),&ProjectSettings::_action_add);
ObjectTypeDB::bind_method(_MD("_action_adds"),&ProjectSettings::_action_adds);
- ObjectTypeDB::bind_method(_MD("_action_persist_toggle"),&ProjectSettings::_action_persist_toggle);
+ ObjectTypeDB::bind_method(_MD("_action_selected"),&ProjectSettings::_action_selected);
+ ObjectTypeDB::bind_method(_MD("_action_edited"),&ProjectSettings::_action_edited);
ObjectTypeDB::bind_method(_MD("_action_button_pressed"),&ProjectSettings::_action_button_pressed);
- ObjectTypeDB::bind_method(_MD("_action_rename"),&ProjectSettings::_action_rename);
ObjectTypeDB::bind_method(_MD("_update_actions"),&ProjectSettings::_update_actions);
ObjectTypeDB::bind_method(_MD("_wait_for_key"),&ProjectSettings::_wait_for_key);
ObjectTypeDB::bind_method(_MD("_add_item"),&ProjectSettings::_add_item);
@@ -1421,7 +1457,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
data=p_data;
- TabContainer *tab_container = memnew( TabContainer );
+ tab_container = memnew( TabContainer );
add_child(tab_container);
set_child_rect(tab_container);
@@ -1592,19 +1628,13 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
input_editor->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 );
input_editor->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 5 );
input_editor->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 5 );
- input_editor->connect("item_edited",this,"_action_persist_toggle");
+ input_editor->connect("item_edited",this,"_action_edited");
+ input_editor->connect("cell_selected",this,"_action_selected");
input_editor->connect("button_pressed",this,"_action_button_pressed");
popup_add = memnew( PopupMenu );
add_child(popup_add);
popup_add->connect("item_pressed",this,"_add_item");
- rename_action = memnew( EditorNameDialog );
- add_child(rename_action);
- rename_action->set_hide_on_ok(false);
- rename_action->set_size(Size2(200, 70));
- rename_action->set_title("Rename Input Action");
- rename_action->connect("name_confirmed", this,"_action_rename");
-
press_a_key = memnew( ConfirmationDialog );
press_a_key->set_focus_mode(FOCUS_ALL);
add_child(press_a_key);
@@ -1819,6 +1849,13 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
}
+ {
+
+ plugin_settings = memnew( EditorPluginSettings );
+ plugin_settings->set_name("Plugins");
+ tab_container->add_child(plugin_settings);
+ }
+
timer = memnew( Timer );
timer->set_wait_time(1.5);
timer->connect("timeout",Globals::get_singleton(),"save");
diff --git a/tools/editor/project_settings.h b/tools/editor/project_settings.h
index b689340fdf..113cc49b7c 100644
--- a/tools/editor/project_settings.h
+++ b/tools/editor/project_settings.h
@@ -34,12 +34,17 @@
#include "optimized_save_dialog.h"
#include "undo_redo.h"
#include "editor_data.h"
-#include "editor_name_dialog.h"
+#include "scene/gui/tab_container.h"
+#include "editor_plugin_settings.h"
+
//#include "project_export_settings.h"
class ProjectSettings : public AcceptDialog {
OBJ_TYPE( ProjectSettings, AcceptDialog );
+
+ TabContainer *tab_container;
+
Timer *timer;
InputEvent::Type add_type;
String add_at;
@@ -67,8 +72,6 @@ class ProjectSettings : public AcceptDialog {
Label *device_index_label;
MenuButton *popup_platform;
- EditorNameDialog *rename_action;
-
LineEdit *action_name;
Tree *input_editor;
bool setting;
@@ -92,6 +95,9 @@ class ProjectSettings : public AcceptDialog {
LineEdit *autoload_add_name;
LineEdit *autoload_add_path;
+
+ EditorPluginSettings *plugin_settings;
+
void _update_autoload();
void _autoload_file_callback(const String& p_path);
void _autoload_add();
@@ -111,11 +117,11 @@ class ProjectSettings : public AcceptDialog {
void _action_adds(String);
void _action_add();
- void _action_rename(const String& p_name);
void _device_input_add();
void _item_checked(const String& p_item, bool p_check);
- void _action_persist_toggle();
+ void _action_selected();
+ void _action_edited();
void _action_button_pressed(Object* p_obj, int p_column,int p_id);
void _wait_for_key(const InputEvent& p_event);
void _press_a_key_confirm();
@@ -145,6 +151,8 @@ class ProjectSettings : public AcceptDialog {
void _toggle_search_bar(bool p_pressed);
void _clear_search_box();
+
+
ProjectSettings();
@@ -159,6 +167,9 @@ public:
void add_translation(const String& p_translation);
static ProjectSettings *get_singleton() { return singleton; }
void popup_project_settings();
+ void set_plugins_page();
+
+ void queue_save();
ProjectSettings(EditorData *p_data);
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 3dfc461bfe..1340670db1 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -714,7 +714,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty
RES r = v;
if (r.is_valid() && r->get_path().is_resource_file() && r->get_import_metadata().is_valid()) {
menu->add_separator();
- menu->add_icon_item(get_icon("Reload","EditorIcons"),"Re-Import",OBJ_MENU_REIMPORT);
+ menu->add_icon_item(get_icon("ReloadSmall","EditorIcons"),"Re-Import",OBJ_MENU_REIMPORT);
}
/*if (r.is_valid() && r->get_path().is_resource_file()) {
menu->set_item_tooltip(1,r->get_path());
@@ -2127,11 +2127,13 @@ void PropertyEditor::_check_reload_status(const String&p_name, TreeItem* item) {
bool has_reload=false;
int found=-1;
+ bool is_disabled=false;
for(int i=0;i<item->get_button_count(1);i++) {
if (item->get_button_id(1,i)==3) {
found=i;
+ is_disabled=item->is_button_disabled(1,i);
break;
}
}
@@ -2149,7 +2151,7 @@ void PropertyEditor::_check_reload_status(const String&p_name, TreeItem* item) {
bool changed = _is_property_different(v,vorig,usage);
- if ((found!=-1)!=changed) {
+ //if ((found!=-1 && !is_disabled)!=changed) {
if (changed) {
@@ -2158,12 +2160,10 @@ void PropertyEditor::_check_reload_status(const String&p_name, TreeItem* item) {
}
- }
+ //}
}
-
-
}
if (!has_reload && !obj->get_script().is_null()) {
@@ -2176,10 +2176,20 @@ void PropertyEditor::_check_reload_status(const String&p_name, TreeItem* item) {
}
}
+ //print_line("found: "+itos(found)+" has reload: "+itos(has_reload)+" is_disabled "+itos(is_disabled));
if (found!=-1 && !has_reload) {
- item->erase_button(1,found);
+
+ if (!is_disabled) {
+ item->erase_button(1,found);
+ if (item->get_cell_mode(1)==TreeItem::CELL_MODE_RANGE && item->get_text(1)==String()) {
+ item->add_button(1,get_icon("ReloadEmpty","EditorIcons"),3,true);
+ }
+ }
} else if (found==-1 && has_reload) {
- item->add_button(1,get_icon("Reload","EditorIcons"),3);
+ item->add_button(1,get_icon("ReloadSmall","EditorIcons"),3);
+ } else if (found!=-1 && has_reload && is_disabled) {
+ item->erase_button(1,found);
+ item->add_button(1,get_icon("ReloadSmall","EditorIcons"),3);
}
}
@@ -2348,7 +2358,7 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
if (!has_reload && found!=-1) {
p_item->erase_button(1,found);
} else if (has_reload && found==-1) {
- p_item->add_button(1,get_icon("Reload","EditorIcons"),3);
+ p_item->add_button(1,get_icon("ReloadSmall","EditorIcons"),3);
}
#endif
Dictionary d=p_item->get_metadata(0);
@@ -3092,7 +3102,9 @@ void PropertyEditor::update_tree() {
}
bool has_reload=false;
- if (_might_be_in_instance()) {
+
+ bool mbi = _might_be_in_instance();
+ if (mbi) {
Variant vorig;
Dictionary d=item->get_metadata(0);
@@ -3103,7 +3115,7 @@ void PropertyEditor::update_tree() {
if (_is_property_different(v,vorig,usage)) {
//print_line("FOR "+String(p.name)+" RELOAD WITH: "+String(v)+"("+Variant::get_type_name(v.get_type())+")=="+String(vorig)+"("+Variant::get_type_name(vorig.get_type())+")");
- item->add_button(1,get_icon("Reload","EditorIcons"),3);
+ item->add_button(1,get_icon("ReloadSmall","EditorIcons"),3);
has_reload=true;
}
}
@@ -3115,11 +3127,16 @@ void PropertyEditor::update_tree() {
Variant orig_value;
if (scr->get_property_default_value(p.name,orig_value)) {
if (orig_value!=obj->get(p.name)) {
- item->add_button(1,get_icon("Reload","EditorIcons"),3);
+ item->add_button(1,get_icon("ReloadSmall","EditorIcons"),3);
+ has_reload=true;
}
}
}
+ if (mbi && !has_reload && item->get_cell_mode(1)==TreeItem::CELL_MODE_RANGE && item->get_text(1)==String()) {
+ item->add_button(1,get_icon("ReloadEmpty","EditorIcons"),3,true);
+ }
+
}
@@ -3180,6 +3197,9 @@ void PropertyEditor::_item_edited() {
TreeItem * item = tree->get_edited();
+ if (!item)
+ return; //it all happened too fast..
+
Dictionary d = item->get_metadata(0);
String name=d["name"];
@@ -3820,14 +3840,34 @@ void SectionedPropertyEditor::_section_selected(int p_which) {
filter->set_section( sections->get_item_metadata(p_which) );
}
+void SectionedPropertyEditor::set_current_section(const String& p_section) {
+
+ int section_idx = sections->find_metadata(p_section);
+
+ if (section_idx==sections->get_current())
+ return;
+
+ if (section_idx!=-1) {
+ sections->select(section_idx);
+ _section_selected(section_idx);
+ } else if (sections->get_item_count()) {
+ sections->select(0);
+ _section_selected(0);
+ }
+}
+
String SectionedPropertyEditor::get_current_section() const {
- return sections->get_item_metadata( sections->get_current() );
+ if (sections->get_current()!=-1)
+ return sections->get_item_metadata( sections->get_current() );
+ else
+ return "";
}
String SectionedPropertyEditor::get_full_item_path(const String& p_item) {
- String base = sections->get_item_metadata( sections->get_current() );
+ String base = get_current_section();
+
if (base!="")
return base+"/"+p_item;
else
@@ -3836,17 +3876,44 @@ String SectionedPropertyEditor::get_full_item_path(const String& p_item) {
void SectionedPropertyEditor::edit(Object* p_object) {
- List<PropertyInfo> pinfo;
- if (p_object)
- p_object->get_property_list(&pinfo);
+ if (p_object) {
+ obj=p_object->get_instance_ID();
+ update_category_list();
+ } else {
+ sections->clear();
+ }
+
+ filter->set_edited(p_object);
+ editor->edit(filter);
+
+ sections->select(0);
+ _section_selected(0);
+
+}
+
+void SectionedPropertyEditor::update_category_list() {
+
+ String selected_category=get_current_section();
sections->clear();
+ Object *o = ObjectDB::get_instance(obj);
+
+ if (!o)
+ return;
+
+ List<PropertyInfo> pinfo;
+ o->get_property_list(&pinfo);
+
Set<String> existing_sections;
for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
PropertyInfo pi=E->get();
+
if (pi.usage&PROPERTY_USAGE_CATEGORY)
continue;
+ else if ( !(pi.usage&PROPERTY_USAGE_EDITOR) )
+ continue;
+
if (pi.name.find(":")!=-1 || pi.name=="script/script")
continue;
int sp = pi.name.find("/");
@@ -3865,19 +3932,9 @@ void SectionedPropertyEditor::edit(Object* p_object) {
sections->set_item_metadata(sections->get_item_count()-1,"");
}
}
-
-
}
- //sections->sort_items_by_text();
-
-
- filter->set_edited(p_object);
- editor->edit(filter);
-
- sections->select(0);
- _section_selected(0);
-
+ set_current_section(selected_category);
}
PropertyEditor *SectionedPropertyEditor::get_property_editor() {
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index 63ad090901..b870a618e9 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -174,7 +174,7 @@ class PropertyEditor : public Control {
Map<StringName,Map<StringName,String> > descr_cache;
Map<StringName,String > class_descr_cache;
-
+
CustomPropertyEditor *custom_editor;
void _resource_edit_request();
@@ -245,7 +245,7 @@ public:
void set_subsection_selectable(bool p_selectable);
- PropertyEditor();
+ PropertyEditor();
~PropertyEditor();
};
@@ -257,6 +257,9 @@ class SectionedPropertyEditor : public HBoxContainer {
OBJ_TYPE(SectionedPropertyEditor,HBoxContainer);
+
+ ObjectID obj;
+
ItemList *sections;
SectionedPropertyEditorFilter *filter;
PropertyEditor *editor;
@@ -270,8 +273,12 @@ public:
PropertyEditor *get_property_editor();
void edit(Object* p_object);
String get_full_item_path(const String& p_item);
+
+ void set_current_section(const String& p_section);
String get_current_section() const;
+ void update_category_list();
+
SectionedPropertyEditor();
~SectionedPropertyEditor();
};
diff --git a/tools/editor/reparent_dialog.cpp b/tools/editor/reparent_dialog.cpp
index 97b27603b2..2a886b85fa 100644
--- a/tools/editor/reparent_dialog.cpp
+++ b/tools/editor/reparent_dialog.cpp
@@ -47,19 +47,19 @@ void ReparentDialog::_notification(int p_what) {
}
if (p_what==NOTIFICATION_DRAW) {
-
+
//RID ci = get_canvas_item();
//get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
- }
+ }
}
void ReparentDialog::_cancel() {
-
+
hide();
-
+
}
void ReparentDialog::_reparent() {
-
+
if (tree->get_selected()) {
emit_signal("reparent",tree->get_selected()->get_path(),keep_transform->is_pressed());
@@ -68,14 +68,14 @@ void ReparentDialog::_reparent() {
}
void ReparentDialog::set_current(const Set<Node*>& p_selection) {
-
+
tree->set_marked(p_selection,false,false);
//tree->set_selected(p_node->get_parent());
}
void ReparentDialog::_bind_methods() {
-
- ObjectTypeDB::bind_method("_reparent",&ReparentDialog::_reparent);
+
+ ObjectTypeDB::bind_method("_reparent",&ReparentDialog::_reparent);
ObjectTypeDB::bind_method("_cancel",&ReparentDialog::_cancel);
ADD_SIGNAL( MethodInfo("reparent",PropertyInfo(Variant::NODE_PATH,"path"),PropertyInfo(Variant::BOOL,"keep_global_xform")));
diff --git a/tools/editor/reparent_dialog.h b/tools/editor/reparent_dialog.h
index 296102e4b9..1c0fbd2459 100644
--- a/tools/editor/reparent_dialog.h
+++ b/tools/editor/reparent_dialog.h
@@ -39,30 +39,30 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class ReparentDialog : public ConfirmationDialog {
-
+
OBJ_TYPE( ReparentDialog, ConfirmationDialog );
-
+
SceneTreeEditor *tree;
CheckBox *keep_transform;
-
+
void update_tree();
void _reparent();
void _cancel();
protected:
-
+
void _notification(int p_what);
static void _bind_methods();
public:
-
+
void set_current(const Set<Node*>& p_selection);
String get_selected_type();
-
- ReparentDialog();
+
+ ReparentDialog();
~ReparentDialog();
-
+
};
#endif
diff --git a/tools/editor/run_settings_dialog.cpp b/tools/editor/run_settings_dialog.cpp
index e8c509d79d..9dc4d703fc 100644
--- a/tools/editor/run_settings_dialog.cpp
+++ b/tools/editor/run_settings_dialog.cpp
@@ -84,7 +84,7 @@ RunSettingsDialog::RunSettingsDialog() {
run_mode->add_item("Main Scene");
run_mode->connect("item_selected",this,"_run_mode_changed");
arguments = memnew( LineEdit );
- vbc->add_margin_child("Main Scene Arguments:",arguments);
+ vbc->add_margin_child("Main Scene Arguments:",arguments);
arguments->set_editable(false);
get_ok()->set_text("Close");
diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp
index ba5cc7568b..c16152ae44 100644
--- a/tools/editor/scene_tree_editor.cpp
+++ b/tools/editor/scene_tree_editor.cpp
@@ -211,7 +211,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
}
void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
-
+
if (!p_node)
return;
@@ -230,7 +230,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
return;
}
} else {
- part_of_subscene = get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0;
+ part_of_subscene = p_node!=get_scene_node() && get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0;
}
TreeItem *item = tree->create_item(p_parent);
@@ -252,7 +252,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
else
icon=get_icon( (has_icon(p_node->get_type(),"EditorIcons")?p_node->get_type():String("Object")),"EditorIcons");
item->set_icon(0, icon );
- item->set_metadata( 0,p_node->get_path() );
+ item->set_metadata( 0,p_node->get_path() );
if (part_of_subscene) {
@@ -260,7 +260,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
item->set_custom_color(0,Color(0.8,0.4,0.20));
} else if (marked.has(p_node)) {
-
+
item->set_selectable(0,marked_selectable);
item->set_custom_color(0,Color(0.8,0.1,0.10));
} else if (!marked_selectable && !marked_children_selectable) {
@@ -344,9 +344,9 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
item->select(0);
item->set_as_cursor(0);
}
-
+
for (int i=0;i<p_node->get_child_count();i++) {
-
+
_add_nodes(p_node->get_child(i),item);
}
}
@@ -406,7 +406,7 @@ void SceneTreeEditor::_node_script_changed(Node *p_node) {
}
void SceneTreeEditor::_node_removed(Node *p_node) {
-
+
if (p_node->is_connected("script_changed",this,"_node_script_changed"))
p_node->disconnect("script_changed",this,"_node_script_changed");
@@ -419,8 +419,8 @@ void SceneTreeEditor::_node_removed(Node *p_node) {
selected=NULL;
emit_signal("node_selected");
}
-
-
+
+
}
void SceneTreeEditor::_update_tree() {
@@ -492,11 +492,11 @@ void SceneTreeEditor::_tree_changed() {
void SceneTreeEditor::_selected_changed() {
-
+
TreeItem *s = tree->get_selected();
ERR_FAIL_COND(!s);
NodePath np = s->get_metadata(0);
-
+
Node *n=get_node(np);
@@ -509,8 +509,8 @@ void SceneTreeEditor::_selected_changed() {
blocked++;
emit_signal("node_selected");
blocked--;
-
-
+
+
}
@@ -540,7 +540,7 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object,int p_cell,bool p_se
}
void SceneTreeEditor::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_ENTER_TREE) {
get_tree()->connect("tree_changed",this,"_tree_changed");
@@ -570,20 +570,20 @@ TreeItem* SceneTreeEditor::_find(TreeItem *p_node,const NodePath& p_path) {
if (!p_node)
return NULL;
-
+
NodePath np=p_node->get_metadata(0);
if (np==p_path)
return p_node;
-
+
TreeItem *children=p_node->get_children();
while(children) {
-
+
TreeItem *n=_find(children,p_path);
if (n)
return n;
children=children->get_next();
}
-
+
return NULL;
}
@@ -598,24 +598,24 @@ void SceneTreeEditor::set_selected(Node *p_node,bool p_emit_selected) {
if (selected==p_node)
return;
-
-
+
+
TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL;
if (item) {
item->select(0);
item->set_as_cursor(0);
- selected=p_node;
+ selected=p_node;
tree->ensure_cursor_is_visible();
} else {
if (!p_node)
selected=NULL;
_update_tree();
- selected=p_node;
+ selected=p_node;
if (p_emit_selected)
emit_signal("node_selected");
}
-
+
}
void SceneTreeEditor::_rename_node(ObjectID p_node,const String& p_name) {
@@ -787,10 +787,10 @@ void SceneTreeEditor::_cell_collapsed(Object *p_obj) {
void SceneTreeEditor::_bind_methods() {
-
+
ObjectTypeDB::bind_method("_tree_changed",&SceneTreeEditor::_tree_changed);
ObjectTypeDB::bind_method("_update_tree",&SceneTreeEditor::_update_tree);
- ObjectTypeDB::bind_method("_node_removed",&SceneTreeEditor::_node_removed);
+ ObjectTypeDB::bind_method("_node_removed",&SceneTreeEditor::_node_removed);
ObjectTypeDB::bind_method("_selected_changed",&SceneTreeEditor::_selected_changed);
ObjectTypeDB::bind_method("_renamed",&SceneTreeEditor::_renamed);
ObjectTypeDB::bind_method("_rename_node",&SceneTreeEditor::_rename_node);
@@ -817,7 +817,7 @@ void SceneTreeEditor::_bind_methods() {
SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open_instance) {
-
+
undo_redo=NULL;
tree_dirty=true;
@@ -829,23 +829,23 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
can_open_instance=p_can_open_instance;
display_foreign=false;
editor_selection=NULL;
-
+
if (p_label) {
Label *label = memnew( Label );
label->set_pos( Point2(10, 0));
label->set_text("Scene Tree (Nodes):");
-
+
add_child(label);
}
-
+
tree = memnew( Tree );
tree->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
+ tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
tree->set_begin( Point2(0,p_label?18:0 ));
tree->set_end( Point2(0,0 ));
-
+
add_child( tree );
-
+
tree->connect("cell_selected", this,"_selected_changed");
tree->connect("item_edited", this,"_renamed",varray(),CONNECT_DEFERRED);
tree->connect("multi_selected",this,"_cell_multi_selected");
@@ -889,7 +889,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
SceneTreeEditor::~SceneTreeEditor() {
-
+
}
diff --git a/tools/editor/scene_tree_editor.h b/tools/editor/scene_tree_editor.h
index 334debc148..27ccaaae01 100644
--- a/tools/editor/scene_tree_editor.h
+++ b/tools/editor/scene_tree_editor.h
@@ -38,7 +38,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class SceneTreeEditor : public Control {
-
+
OBJ_TYPE( SceneTreeEditor, Control );
EditorSelection *editor_selection;
@@ -70,7 +70,7 @@ class SceneTreeEditor : public Control {
ConfirmationDialog *clear_inherit_confirm;
int blocked;
-
+
void _compute_hash(Node *p_node,uint64_t &hash);
void _add_nodes(Node *p_node,TreeItem *p_parent);
@@ -78,7 +78,7 @@ class SceneTreeEditor : public Control {
void _update_tree();
void _tree_changed();
void _node_removed(Node *p_node);
-
+
TreeItem* _find(TreeItem *p_node,const NodePath& p_path);
void _notification(int p_what);
void _selected_changed();
@@ -92,17 +92,17 @@ class SceneTreeEditor : public Control {
bool can_open_instance;
bool updating_tree;
bool show_enabled_subscene;
-
+
void _renamed();
UndoRedo *undo_redo;
-
+
Set<Node*> marked;
bool marked_selectable;
bool marked_children_selectable;
bool display_foreign;
bool tree_dirty;
bool pending_test_update;
- static void _bind_methods();
+ static void _bind_methods();
void _cell_button_pressed(Object *p_item,int p_column,int p_id);
void _cell_multi_selected(Object *p_object,int p_cel,bool p_selected);
@@ -119,7 +119,7 @@ public:
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; };
void set_display_foreign_nodes(bool p_display);
bool get_display_foreign_nodes() const;
-
+
void set_marked(const Set<Node*>& p_marked,bool p_selectable=false,bool p_children_selectable=true);
void set_marked(Node *p_marked,bool p_selectable=false,bool p_children_selectable=true);
void set_selected(Node *p_node,bool p_emit_selected=true);
@@ -150,7 +150,7 @@ class SceneTreeDialog : public ConfirmationDialog {
void update_tree();
void _select();
- void _cancel();
+ void _cancel();
protected:
diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp
index 5abc4992df..e2b17f5e64 100644
--- a/tools/editor/scenes_dock.cpp
+++ b/tools/editor/scenes_dock.cpp
@@ -1122,7 +1122,7 @@ ScenesDock::ScenesDock(EditorNode *p_editor) {
button_reload = memnew( Button );
button_reload->set_flat(true);
- button_reload->connect("pressed",this,"_rescan");
+ button_reload->connect("pressed",this,"_rescan");
toolbar_hbc->add_child(button_reload);
button_reload->set_focus_mode(FOCUS_NONE);
button_reload->set_tooltip("Re-Scan Filesystem");
@@ -1238,10 +1238,10 @@ ScenesDock::ScenesDock(EditorNode *p_editor) {
add_child(remove_dialog);
move_dialog = memnew( EditorDirDialog );
- add_child(move_dialog);
+ add_child(move_dialog);
move_dialog->connect("dir_selected",this,"_move_operation");
move_dialog->get_ok()->set_text("Move");
-
+
rename_dialog = memnew( EditorFileDialog );
rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
rename_dialog->connect("file_selected",this,"_rename_operation");
diff --git a/tools/editor/scenes_dock.h b/tools/editor/scenes_dock.h
index a1978a3ca4..a630d2506d 100644
--- a/tools/editor/scenes_dock.h
+++ b/tools/editor/scenes_dock.h
@@ -138,7 +138,7 @@ class ScenesDock : public VBoxContainer {
void _rescan();
void _set_scannig_mode();
- void _favorites_pressed();
+ void _favorites_pressed();
void _instance_pressed();
void _open_pressed();
diff --git a/tools/editor/script_create_dialog.cpp b/tools/editor/script_create_dialog.cpp
index 409e8be870..34d9204061 100644
--- a/tools/editor/script_create_dialog.cpp
+++ b/tools/editor/script_create_dialog.cpp
@@ -138,7 +138,7 @@ void ScriptCreateDialog::ok_pressed() {
return;
}
- Error err = ResourceSaver::save(lpath,scr,ResourceSaver::FLAG_CHANGE_PATH);
+ Error err = ResourceSaver::save(lpath,scr,ResourceSaver::FLAG_CHANGE_PATH);
if (err!=OK) {
alert->set_text("Could not create script in filesystem: "+String(""));
@@ -195,7 +195,7 @@ void ScriptCreateDialog::_browse_path() {
file_browse->add_filter("*."+E->get());
}
- file_browse->set_current_path(file_path->get_text());
+ file_browse->set_current_path(file_path->get_text());
file_browse->popup_centered_ratio();
}
diff --git a/tools/editor/settings_config_dialog.cpp b/tools/editor/settings_config_dialog.cpp
index ebbc488ff2..6b7c2eb9b7 100644
--- a/tools/editor/settings_config_dialog.cpp
+++ b/tools/editor/settings_config_dialog.cpp
@@ -80,173 +80,6 @@ void EditorSettingsDialog::popup_edit_settings() {
}
-void EditorSettingsDialog::_plugin_install() {
-
- EditorSettings::Plugin plugin = EditorSettings::get_singleton()->get_plugins()[plugin_setting_edit];
-
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- da->change_dir("res://");
- if (da->change_dir("plugins")!=OK) {
-
- Error err = da->make_dir("plugins");
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- err = da->change_dir("plugins");
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- }
-
- if (da->change_dir(plugin_setting_edit)!=OK) {
-
- Error err = da->make_dir(plugin_setting_edit);
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- err = da->change_dir(plugin_setting_edit);
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- }
-
- Vector<String> ifiles=plugin.install_files;
-
- if (ifiles.find("plugin.cfg")==-1) {
- ifiles.push_back("plugin.cfg");
- }
-
- if (ifiles.find(plugin.script)==-1) {
- ifiles.push_back(plugin.script);
- }
-
- for(int i=0;i<ifiles.size();i++) {
-
- String target = "res://plugins/"+plugin_setting_edit+"/"+ifiles[i];
- Error err = da->copy(EditorSettings::get_singleton()->get_settings_path().plus_file("plugins/"+plugin_setting_edit+"/"+ifiles[i]),target);
- if (err)
- memdelete(da);
- ERR_EXPLAIN("Error copying to file "+target);
- ERR_FAIL_COND(err!=OK);
- EditorFileSystem::get_singleton()->update_file(target);
- }
-
- memdelete(da);
-
- Globals::get_singleton()->set("plugins/"+plugin_setting_edit,"res://plugins/"+plugin_setting_edit);
- Globals::get_singleton()->set_persisting("plugins/"+plugin_setting_edit,true);
- EditorSettings::get_singleton()->load_installed_plugin(plugin_setting_edit);
- Globals::get_singleton()->save();
-
-
- _update_plugins();
-}
-
-void EditorSettingsDialog::_rescan_plugins() {
-
- EditorSettings::get_singleton()->scan_plugins();
- _update_plugins();
-}
-
-void EditorSettingsDialog::_plugin_edited() {
-
- if (updating)
- return;
-
- TreeItem *ti=plugins->get_edited();
- if (!ti)
- return;
-
- String plugin = ti->get_metadata(0);
- bool enabled = ti->is_checked(0);
-
- EditorSettings::get_singleton()->set_plugin_enabled(plugin,enabled);
-}
-
-void EditorSettingsDialog::_plugin_settings(Object *p_obj,int p_cell,int p_index) {
-
- TreeItem *ti=p_obj->cast_to<TreeItem>();
-
- EditorSettings::Plugin plugin = EditorSettings::get_singleton()->get_plugins()[ti->get_metadata(0)];
-
- plugin_description->clear();
- plugin_description->parse_bbcode(plugin.description);
- plugin_setting_edit = ti->get_metadata(0);
- if (plugin.installs) {
- if (Globals::get_singleton()->has("plugins/"+plugin_setting_edit))
- plugin_setting->get_ok()->set_text("Re-Install to Project");
- else
- plugin_setting->get_ok()->set_text("Install to Project");
- plugin_setting->get_ok()->show();
- plugin_setting->get_cancel()->set_text("Close");
- } else {
- plugin_setting->get_ok()->hide();
- plugin_setting->get_cancel()->set_text("Close");
- }
-
- plugin_setting->set_title(plugin.name);
- plugin_setting->popup_centered(Size2(300,200));
-}
-
-void EditorSettingsDialog::_update_plugins() {
-
-
- updating=true;
-
- plugins->clear();
- TreeItem *root = plugins->create_item(NULL);
- plugins->set_hide_root(true);
-
- Color sc = get_color("prop_subsection","Editor");
- TreeItem *editor = plugins->create_item(root);
- editor->set_text(0,"Editor Plugins");
- editor->set_custom_bg_color(0,sc);
- editor->set_custom_bg_color(1,sc);
- editor->set_custom_bg_color(2,sc);
-
- TreeItem *install = plugins->create_item(root);
- install->set_text(0,"Installable Plugins");
- install->set_custom_bg_color(0,sc);
- install->set_custom_bg_color(1,sc);
- install->set_custom_bg_color(2,sc);
-
- for (const Map<String,EditorSettings::Plugin>::Element *E=EditorSettings::get_singleton()->get_plugins().front();E;E=E->next()) {
-
-
- TreeItem *ti = plugins->create_item(E->get().installs?install:editor);
- if (!E->get().installs) {
- ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
- ti->set_editable(0,true);
- if (EditorSettings::get_singleton()->is_plugin_enabled(E->key()))
- ti->set_checked(0,true);
-
- ti->set_text(0,E->get().name);
- } else {
-
- if (Globals::get_singleton()->has("plugins/"+E->key())) {
-
- ti->set_text(0,E->get().name+" (Installed)");
- } else {
- ti->set_text(0,E->get().name);
- }
- }
-
-
- ti->add_button(0,get_icon("Tools","EditorIcons"),0);
- ti->set_text(1,E->get().author);
- ti->set_text(2,E->get().version);
- ti->set_metadata(0,E->key());
-
- }
-
- if (!editor->get_children())
- memdelete(editor);
- if (!install->get_children())
- memdelete(install);
-
- updating=false;
-
-}
void EditorSettingsDialog::_clear_search_box() {
@@ -261,9 +94,7 @@ void EditorSettingsDialog::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
- rescan_plugins->set_icon(get_icon("Reload","EditorIcons"));
clear_button->set_icon(get_icon("Close","EditorIcons"));
- _update_plugins();
}
}
@@ -271,10 +102,6 @@ void EditorSettingsDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_settings_save"),&EditorSettingsDialog::_settings_save);
ObjectTypeDB::bind_method(_MD("_settings_changed"),&EditorSettingsDialog::_settings_changed);
- ObjectTypeDB::bind_method(_MD("_rescan_plugins"),&EditorSettingsDialog::_rescan_plugins);
- ObjectTypeDB::bind_method(_MD("_plugin_settings"),&EditorSettingsDialog::_plugin_settings);
- ObjectTypeDB::bind_method(_MD("_plugin_edited"),&EditorSettingsDialog::_plugin_edited);
- ObjectTypeDB::bind_method(_MD("_plugin_install"),&EditorSettingsDialog::_plugin_install);
ObjectTypeDB::bind_method(_MD("_clear_search_box"),&EditorSettingsDialog::_clear_search_box);
}
@@ -321,35 +148,9 @@ EditorSettingsDialog::EditorSettingsDialog() {
vbc->add_child(hbc);
hbc->add_child( memnew( Label("Plugin List: ")));
hbc->add_spacer();
- Button *load = memnew( Button );
- load->set_text("Load..");
- Button *rescan = memnew( Button );
- rescan_plugins=rescan;
- rescan_plugins->connect("pressed",this,"_rescan_plugins");
- hbc->add_child(load);
- hbc->add_child(rescan);
- plugins = memnew( Tree );
- MarginContainer *mc = memnew( MarginContainer);
- vbc->add_child(mc);
- mc->add_child(plugins);
- mc->set_v_size_flags(SIZE_EXPAND_FILL);
- plugins->set_columns(3);
- plugins->set_column_title(0,"Name");
- plugins->set_column_title(1,"Author");
- plugins->set_column_title(2,"Version");
- plugins->set_column_expand(2,false);
- plugins->set_column_min_width(2,100);
- plugins->set_column_titles_visible(true);
- plugins->connect("button_pressed",this,"_plugin_settings");
- plugins->connect("item_edited",this,"_plugin_edited");
-
- plugin_setting = memnew( ConfirmationDialog );
- add_child(plugin_setting);
- plugin_description = memnew( RichTextLabel );
- plugin_setting->add_child(plugin_description);
- plugin_setting->set_child_rect(plugin_description);
- plugin_setting->connect("confirmed",this,"_plugin_install");
-
+ //Button *load = memnew( Button );
+ //load->set_text("Load..");
+ //hbc->add_child(load);
//get_ok()->set_text("Apply");
@@ -363,8 +164,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
add_child(timer);
EditorSettings::get_singleton()->connect("settings_changed",this,"_settings_changed");
get_ok()->set_text("Close");
- install_confirm = memnew( ConfirmationDialog );
- add_child(install_confirm);
updating=false;
diff --git a/tools/editor/settings_config_dialog.h b/tools/editor/settings_config_dialog.h
index e1c3238a64..5085132108 100644
--- a/tools/editor/settings_config_dialog.h
+++ b/tools/editor/settings_config_dialog.h
@@ -40,17 +40,10 @@ class EditorSettingsDialog : public AcceptDialog {
- ConfirmationDialog *install_confirm;
bool updating;
- ConfirmationDialog *plugin_setting;
- String plugin_setting_edit;
-
- RichTextLabel *plugin_description;
TabContainer *tabs;
- Button *rescan_plugins;
- Tree *plugins;
LineEdit *search_box;
ToolButton *clear_button;
SectionedPropertyEditor *property_editor;
@@ -60,18 +53,11 @@ class EditorSettingsDialog : public AcceptDialog {
virtual void cancel_pressed();
virtual void ok_pressed();
- void _plugin_edited();
-
- void _plugin_settings(Object *p_obj,int p_cell,int p_index);
void _settings_changed();
void _settings_save();
- void _plugin_install();
-
void _notification(int p_what);
- void _rescan_plugins();
- void _update_plugins();
void _clear_search_box();
diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp
index 320b0c3a70..3414e80482 100644
--- a/tools/editor/spatial_editor_gizmos.cpp
+++ b/tools/editor/spatial_editor_gizmos.cpp
@@ -43,7 +43,7 @@
#define HANDLE_HALF_SIZE 0.05
-void SpatialGizmoTool::clear() {
+void EditorSpatialGizmo::clear() {
for(int i=0;i<instances.size();i++) {
@@ -61,7 +61,15 @@ void SpatialGizmoTool::clear() {
secondary_handles.clear();
}
-void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) {
+void EditorSpatialGizmo::redraw() {
+
+ if (get_script_instance() && get_script_instance()->has_method("redraw"))
+ get_script_instance()->call("redraw");
+
+
+}
+
+void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
instance = VS::get_singleton()->instance_create2(mesh->get_rid(),p_base->get_world()->get_scenario());
VS::get_singleton()->instance_attach_object_instance_ID(instance,p_base->get_instance_ID());
@@ -73,14 +81,14 @@ void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) {
VS::get_singleton()->instance_attach_skeleton(instance,skeleton);
if (extra_margin)
VS::get_singleton()->instance_set_extra_visibility_margin(instance,1);
- VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_CAST_SHADOW,false);
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(instance,VS::SHADOW_CASTING_SETTING_OFF);
VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_RECEIVE_SHADOWS,false);
VS::get_singleton()->instance_set_layer_mask(instance,1<<SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26
}
-void SpatialGizmoTool::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const RID &p_skeleton) {
+void EditorSpatialGizmo::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const RID &p_skeleton) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -97,7 +105,7 @@ void SpatialGizmoTool::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const
}
-void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material,bool p_billboard){
+void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material,bool p_billboard){
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -150,7 +158,7 @@ void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Mater
}
-void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,float p_scale) {
+void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material>& p_material,float p_scale) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -201,12 +209,12 @@ void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,fl
}
-void SpatialGizmoTool::add_collision_triangles(const Ref<TriangleMesh>& p_tmesh) {
+void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh>& p_tmesh) {
collision_mesh=p_tmesh;
}
-void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
+void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) {
int from=collision_segments.size();
collision_segments.resize(from+p_lines.size());
@@ -217,7 +225,7 @@ void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
}
-void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
+void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
billboard_handle=p_billboard;
@@ -354,13 +362,14 @@ void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_bill
}
-void SpatialGizmoTool::set_spatial_node(Spatial *p_node){
+void EditorSpatialGizmo::set_spatial_node(Spatial *p_node){
+ ERR_FAIL_NULL(p_node);
spatial_node=p_node;
}
-bool SpatialGizmoTool::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) {
+bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) {
ERR_FAIL_COND_V(!spatial_node,false);
ERR_FAIL_COND_V(!valid,false);
@@ -401,7 +410,7 @@ bool SpatialGizmoTool::intersect_frustum(const Camera *p_camera,const Vector<Pla
}
-bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) {
+bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) {
ERR_FAIL_COND_V(!spatial_node,false);
ERR_FAIL_COND_V(!valid,false);
@@ -631,7 +640,7 @@ bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_poin
-void SpatialGizmoTool::create() {
+void EditorSpatialGizmo::create() {
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(valid);
@@ -646,7 +655,7 @@ void SpatialGizmoTool::create() {
}
-void SpatialGizmoTool::transform(){
+void EditorSpatialGizmo::transform(){
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@@ -657,7 +666,7 @@ void SpatialGizmoTool::transform(){
}
-void SpatialGizmoTool::free(){
+void EditorSpatialGizmo::free(){
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@@ -675,19 +684,40 @@ void SpatialGizmoTool::free(){
}
+void EditorSpatialGizmo::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("add_lines","lines","material:Material","billboard"),&EditorSpatialGizmo::add_lines,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("add_mesh","mesh:Mesh","billboard","skeleton"),&EditorSpatialGizmo::add_mesh,DEFVAL(false),DEFVAL(RID()));
+ ObjectTypeDB::bind_method(_MD("add_collision_segments","segments"),&EditorSpatialGizmo::add_collision_segments);
+ ObjectTypeDB::bind_method(_MD("add_collision_triangles","triangles:TriangleMesh"),&EditorSpatialGizmo::add_collision_triangles);
+ ObjectTypeDB::bind_method(_MD("add_unscaled_billboard","material:Material","default_scale"),&EditorSpatialGizmo::add_unscaled_billboard,DEFVAL(1));
+ ObjectTypeDB::bind_method(_MD("add_handles","handles","billboard","secondary"),&EditorSpatialGizmo::add_handles,DEFVAL(false),DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("set_spatial_node","node:Spatial"),&EditorSpatialGizmo::_set_spatial_node);
-SpatialGizmoTool::SpatialGizmoTool() {
+ BIND_VMETHOD( MethodInfo("redraw"));
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"get_handle_name",PropertyInfo(Variant::INT,"index")));
+ {
+ BIND_VMETHOD( MethodInfo("get_handle_value:Variant",PropertyInfo(Variant::INT,"index")));
+ }
+ BIND_VMETHOD( MethodInfo("set_handle",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::OBJECT,"camera:Camera"),PropertyInfo(Variant::VECTOR2,"point")));
+ MethodInfo cm = MethodInfo("commit_handle",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::NIL,"restore:Variant"),PropertyInfo(Variant::BOOL,"cancel"));
+ cm.default_arguments.push_back(false);
+ BIND_VMETHOD( cm );
+}
+
+EditorSpatialGizmo::EditorSpatialGizmo() {
valid=false;
billboard_handle=false;
-
+ base=NULL;
+ spatial_node=NULL;
}
-SpatialGizmoTool::~SpatialGizmoTool(){
+EditorSpatialGizmo::~EditorSpatialGizmo(){
clear();
}
-Vector3 SpatialGizmoTool::get_handle_pos(int p_idx) const {
+Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,handles.size(),Vector3());
@@ -3190,4 +3220,3 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
}
-
diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h
index 669d3e2380..0162bcbf79 100644
--- a/tools/editor/spatial_editor_gizmos.h
+++ b/tools/editor/spatial_editor_gizmos.h
@@ -52,9 +52,9 @@
class Camera;
-class SpatialGizmoTool : public SpatialEditorGizmo {
+class EditorSpatialGizmo : public SpatialEditorGizmo {
- OBJ_TYPE(SpatialGizmoTool,SpatialGizmo);
+ OBJ_TYPE(EditorSpatialGizmo,SpatialGizmo);
struct Instance{
@@ -93,6 +93,8 @@ class SpatialGizmoTool : public SpatialEditorGizmo {
Spatial *base;
Vector<Instance> instances;
Spatial *spatial_node;
+
+ void _set_spatial_node(Node *p_node) { set_spatial_node(p_node->cast_to<Spatial>()); }
protected:
void add_lines(const Vector<Vector3> &p_lines,const Ref<Material>& p_material,bool p_billboard=false);
void add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard=false,const RID& p_skeleton=RID());
@@ -103,6 +105,7 @@ protected:
void set_spatial_node(Spatial *p_node);
+ static void _bind_methods();
public:
virtual Vector3 get_handle_pos(int p_idx) const;
@@ -112,18 +115,18 @@ public:
void clear();
void create();
void transform();
- //void redraw();
+ virtual void redraw();
void free();
- SpatialGizmoTool();
- ~SpatialGizmoTool();
+ EditorSpatialGizmo();
+ ~EditorSpatialGizmo();
};
-class LightSpatialGizmo : public SpatialGizmoTool {
+class LightSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(LightSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(LightSpatialGizmo,EditorSpatialGizmo);
Light* light;
@@ -140,9 +143,9 @@ public:
};
-class CameraSpatialGizmo : public SpatialGizmoTool {
+class CameraSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(CameraSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(CameraSpatialGizmo,EditorSpatialGizmo);
Camera* camera;
@@ -161,9 +164,9 @@ public:
-class MeshInstanceSpatialGizmo : public SpatialGizmoTool {
+class MeshInstanceSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(MeshInstanceSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(MeshInstanceSpatialGizmo,EditorSpatialGizmo);
MeshInstance* mesh;
@@ -174,9 +177,9 @@ public:
};
-class Position3DSpatialGizmo : public SpatialGizmoTool {
+class Position3DSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(Position3DSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(Position3DSpatialGizmo,EditorSpatialGizmo);
Position3D* p3d;
@@ -187,9 +190,9 @@ public:
};
-class SkeletonSpatialGizmo : public SpatialGizmoTool {
+class SkeletonSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(SkeletonSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(SkeletonSpatialGizmo,EditorSpatialGizmo);
Skeleton* skel;
@@ -203,9 +206,9 @@ public:
-class SpatialPlayerSpatialGizmo : public SpatialGizmoTool {
+class SpatialPlayerSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(SpatialPlayerSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(SpatialPlayerSpatialGizmo,EditorSpatialGizmo);
SpatialPlayer* splayer;
@@ -218,9 +221,9 @@ public:
-class TestCubeSpatialGizmo : public SpatialGizmoTool {
+class TestCubeSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(TestCubeSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(TestCubeSpatialGizmo,EditorSpatialGizmo);
TestCube* tc;
@@ -231,9 +234,9 @@ public:
};
-class RoomSpatialGizmo : public SpatialGizmoTool {
+class RoomSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(RoomSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(RoomSpatialGizmo,EditorSpatialGizmo);
struct _EdgeKey {
@@ -256,9 +259,9 @@ public:
};
-class PortalSpatialGizmo : public SpatialGizmoTool {
+class PortalSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(PortalSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(PortalSpatialGizmo,EditorSpatialGizmo);
Portal* portal;
@@ -270,9 +273,9 @@ public:
};
-class VisibilityNotifierGizmo : public SpatialGizmoTool {
+class VisibilityNotifierGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(VisibilityNotifierGizmo ,SpatialGizmoTool);
+ OBJ_TYPE(VisibilityNotifierGizmo ,EditorSpatialGizmo);
VisibilityNotifier* notifier;
@@ -291,9 +294,9 @@ public:
-class CollisionShapeSpatialGizmo : public SpatialGizmoTool {
+class CollisionShapeSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(CollisionShapeSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(CollisionShapeSpatialGizmo,EditorSpatialGizmo);
CollisionShape* cs;
@@ -308,9 +311,9 @@ public:
};
-class CollisionPolygonSpatialGizmo : public SpatialGizmoTool {
+class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(CollisionPolygonSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(CollisionPolygonSpatialGizmo,EditorSpatialGizmo);
CollisionPolygon* polygon;
@@ -322,9 +325,9 @@ public:
};
-class RayCastSpatialGizmo : public SpatialGizmoTool {
+class RayCastSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(RayCastSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(RayCastSpatialGizmo,EditorSpatialGizmo);
RayCast* raycast;
@@ -337,9 +340,9 @@ public:
-class VehicleWheelSpatialGizmo : public SpatialGizmoTool {
+class VehicleWheelSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(VehicleWheelSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(VehicleWheelSpatialGizmo,EditorSpatialGizmo);
VehicleWheel* car_wheel;
@@ -351,9 +354,9 @@ public:
};
-class NavigationMeshSpatialGizmo : public SpatialGizmoTool {
+class NavigationMeshSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(NavigationMeshSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(NavigationMeshSpatialGizmo,EditorSpatialGizmo);
struct _EdgeKey {
@@ -376,9 +379,9 @@ public:
};
-class PinJointSpatialGizmo : public SpatialGizmoTool {
+class PinJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(PinJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(PinJointSpatialGizmo,EditorSpatialGizmo);
PinJoint* p3d;
@@ -390,9 +393,9 @@ public:
};
-class HingeJointSpatialGizmo : public SpatialGizmoTool {
+class HingeJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(HingeJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(HingeJointSpatialGizmo,EditorSpatialGizmo);
HingeJoint* p3d;
@@ -403,9 +406,9 @@ public:
};
-class SliderJointSpatialGizmo : public SpatialGizmoTool {
+class SliderJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(SliderJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(SliderJointSpatialGizmo,EditorSpatialGizmo);
SliderJoint* p3d;
@@ -416,9 +419,9 @@ public:
};
-class ConeTwistJointSpatialGizmo : public SpatialGizmoTool {
+class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(ConeTwistJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(ConeTwistJointSpatialGizmo,EditorSpatialGizmo);
ConeTwistJoint* p3d;
@@ -430,9 +433,9 @@ public:
};
-class Generic6DOFJointSpatialGizmo : public SpatialGizmoTool {
+class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(Generic6DOFJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(Generic6DOFJointSpatialGizmo,EditorSpatialGizmo);
Generic6DOFJoint* p3d;
@@ -488,4 +491,3 @@ public:
};
#endif // SPATIAL_EDITOR_GIZMOS_H
-
diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py
index 7ee0e179b8..370dc359b5 100644
--- a/tools/export/blender25/io_scene_dae/export_dae.py
+++ b/tools/export/blender25/io_scene_dae/export_dae.py
@@ -1087,7 +1087,7 @@ class DaeExporter:
self.writel(S_LAMPS,5,'<color>'+strarr(light.color)+'</color>')
att_by_distance = 2.0 / light.distance # convert to linear attenuation
self.writel(S_LAMPS,5,'<linear_attenuation>'+str(att_by_distance)+'</linear_attenuation>')
- self.writel(S_LAMPS,5,'<falloff_angle>'+str(math.degrees(light.spot_size))+'</falloff_angle>')
+ self.writel(S_LAMPS,5,'<falloff_angle>'+str(math.degrees(light.spot_size/2))+'</falloff_angle>')
self.writel(S_LAMPS,4,'</spot>')
diff --git a/tools/pe_bliss/README b/tools/pe_bliss/README
deleted file mode 100644
index d5d1355444..0000000000
--- a/tools/pe_bliss/README
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-
-
-Открытая бесплатная библиотека для работы с PE-файлами PE Bliss.
-Бесплатна к использованию, модификации и распространению.
-Автор: DX
-(c) DX 2011-2012, kaimi.ru
-
-Совместимость: Windows, Linux
-
-Возможности:
-[+] Создание PE или PE+ файла с нуля
-[+] Чтение 32-разрядных и 64-разрядных PE-файлов (PE, PE+) и единообразная работа с ними
-[+] Пересборка 32-разрядных и 64-разрядных PE-файлов
-[+] Работа с директориями и заголовками
-[+] Конвертирование адресов
-[+] Чтение и редактирование секций PE-файла
-[+] Чтение и редактирование таблицы импортов
-[+] Чтение и редактирование таблицы экспортов
-[+] Чтение и редактирование таблиц релокаций
-[+] Чтение и редактирование ресурсов
-[+] Чтение и редактирование TLS
-[+] Чтение и редактирование конфигурации образа (image config)
-[+] Чтение базовой информации .NET
-[+] Чтение и редактирование информации о привязанном импорте
-[+] Чтение директории исключений (только PE+)
-[+] Чтение отладочной директории с расширенной информацией
-[+] Вычисление энтропии
-[+] Изменение файлового выравнивания
-[+] Изменение базового адреса загрузки
-[+] Работа с DOS Stub'ом и Rich overlay
-[+] Высокоуровневое чтение ресурсов: картинки, иконки, курсоры, информация о версии, строковые таблицы, таблицы сообщений
-[+] Высокоуровневое редактирование ресурсов: картинки, иконки, курсоры, информация о версии
-
-[English]
-Open a free library for working with PE-file PE Bliss.
-Free to use, modify, and distribute.
-Author: DX
-(c) DX 2011-2012, kaimi.ru
-Compatibility: Windows, Linux
-
-### Capabilities:
-[+] Creation of PE or PE + file from scratch
-[+] Reading the 32-bit and 64-bit PE-file (PE, PE +) and uniform working with them
-[+] Rebuild 32-bit and 64-bit PE-files
-[+] Working with the directors and titles
-[+] Converting addresses
-[+] Reading and editing sections of PE-file
-[+] Reading and editing the import table
-[+] Reading and editing tables exports
-[+] Reading and editing tables relocations
-[+] Reading and editing resources
-[+] Reading and editing TLS
-[+] Reading and editing the configuration of the image (image config)
-[+] Reading data base .NET
-[+] Reading and editing information about tethered import
-[+] Read the directory exceptions (only PE +)
-[+] Read debug directories with extended information
-[+] The calculation of entropy
-[+] Changing file alignment
-[+] Change the base load address
-[+] Support of DOS Stub'om and Rich overlay
-[+] High-level reading resources: images, icons, cursors, version information, string tables, message table
-[+] High-level editing resources: images, icons, cursors, version information \ No newline at end of file
diff --git a/tools/pe_bliss/SCsub b/tools/pe_bliss/SCsub
deleted file mode 100644
index 34524f10ef..0000000000
--- a/tools/pe_bliss/SCsub
+++ /dev/null
@@ -1,5 +0,0 @@
-Import('env')
-
-env.add_source_files(env.tool_sources,"*.cpp")
-
-Export('env')
diff --git a/tools/pe_bliss/entropy.cpp b/tools/pe_bliss/entropy.cpp
deleted file mode 100644
index acefa63e83..0000000000
--- a/tools/pe_bliss/entropy.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "entropy.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-//Calculates entropy for PE image section
-double entropy_calculator::calculate_entropy(const section& s)
-{
- if(s.get_raw_data().empty()) //Don't count entropy for empty sections
- throw pe_exception("Section is empty", pe_exception::section_is_empty);
-
- return calculate_entropy(s.get_raw_data().data(), s.get_raw_data().length());
-}
-
-//Calculates entropy for istream (from current position of stream)
-double entropy_calculator::calculate_entropy(std::istream& file)
-{
- uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
- if(file.bad())
- throw pe_exception("Stream is bad", pe_exception::stream_is_bad);
-
- std::streamoff pos = file.tellg();
-
- std::streamoff length = pe_utils::get_file_size(file);
- length -= file.tellg();
-
- if(!length) //Don't calculate entropy for empty buffers
- throw pe_exception("Data length is zero", pe_exception::data_is_empty);
-
- //Count bytes
- for(std::streamoff i = 0; i != length; ++i)
- ++byte_count[static_cast<unsigned char>(file.get())];
-
- file.seekg(pos);
-
- return calculate_entropy(byte_count, length);
-}
-
-//Calculates entropy for data block
-double entropy_calculator::calculate_entropy(const char* data, size_t length)
-{
- uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
- if(!length) //Don't calculate entropy for empty buffers
- throw pe_exception("Data length is zero", pe_exception::data_is_empty);
-
- //Count bytes
- for(size_t i = 0; i != length; ++i)
- ++byte_count[static_cast<unsigned char>(data[i])];
-
- return calculate_entropy(byte_count, length);
-}
-
-//Calculates entropy for this PE file (only section data)
-double entropy_calculator::calculate_entropy(const pe_base& pe)
-{
- uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
- size_t total_data_length = 0;
-
- //Count bytes for each section
- for(section_list::const_iterator it = pe.get_image_sections().begin(); it != pe.get_image_sections().end(); ++it)
- {
- const std::string& data = (*it).get_raw_data();
- size_t length = data.length();
- total_data_length += length;
- for(size_t i = 0; i != length; ++i)
- ++byte_count[static_cast<unsigned char>(data[i])];
- }
-
- return calculate_entropy(byte_count, total_data_length);
-}
-
-//Calculates entropy from bytes count
-double entropy_calculator::calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length)
-{
- double entropy = 0.; //Entropy result value
- //Calculate entropy
- for(uint32_t i = 0; i < 256; ++i)
- {
- double temp = static_cast<double>(byte_count[i]) / total_length;
- if(temp > 0.)
- entropy += std::abs(temp * (std::log(temp) * pe_utils::log_2));
- }
-
- return entropy;
-}
-}
diff --git a/tools/pe_bliss/entropy.h b/tools/pe_bliss/entropy.h
deleted file mode 100644
index 7d225a3e32..0000000000
--- a/tools/pe_bliss/entropy.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-class entropy_calculator
-{
-public:
- //Calculates entropy for PE image section
- static double calculate_entropy(const section& s);
-
- //Calculates entropy for istream (from current position of stream)
- static double calculate_entropy(std::istream& file);
-
- //Calculates entropy for data block
- static double calculate_entropy(const char* data, size_t length);
-
- //Calculates entropy for this PE file (only section data)
- static double calculate_entropy(const pe_base& pe);
-
-private:
- entropy_calculator();
- entropy_calculator(const entropy_calculator&);
- entropy_calculator& operator=(const entropy_calculator&);
-
- //Calculates entropy from bytes count
- static double calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length);
-};
-}
diff --git a/tools/pe_bliss/file_version_info.cpp b/tools/pe_bliss/file_version_info.cpp
deleted file mode 100644
index 3f2ba454b4..0000000000
--- a/tools/pe_bliss/file_version_info.cpp
+++ /dev/null
@@ -1,440 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "file_version_info.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Default constructor
-file_version_info::file_version_info()
- :file_version_ms_(0), file_version_ls_(0),
- product_version_ms_(0), product_version_ls_(0),
- file_flags_(0),
- file_os_(0),
- file_type_(0), file_subtype_(0),
- file_date_ms_(0), file_date_ls_(0)
-{}
-
-//Constructor from Windows fixed version info structure
-file_version_info::file_version_info(const vs_fixedfileinfo& info)
- :file_version_ms_(info.dwFileVersionMS), file_version_ls_(info.dwFileVersionLS),
- product_version_ms_(info.dwProductVersionMS), product_version_ls_(info.dwProductVersionLS),
- file_flags_(info.dwFileFlags),
- file_os_(info.dwFileOS),
- file_type_(info.dwFileType), file_subtype_(info.dwFileSubtype),
- file_date_ms_(info.dwFileDateMS), file_date_ls_(info.dwFileDateLS)
-{}
-
-//Returns true if file is debug-built
-bool file_version_info::is_debug() const
-{
- return file_flags_ & vs_ff_debug ? true : false;
-}
-
-//Returns true if file is release-built
-bool file_version_info::is_prerelease() const
-{
- return file_flags_ & vs_ff_prerelease ? true : false;
-}
-
-//Returns true if file is patched
-bool file_version_info::is_patched() const
-{
- return file_flags_ & vs_ff_patched ? true : false;
-}
-
-//Returns true if private build
-bool file_version_info::is_private_build() const
-{
- return file_flags_ & vs_ff_privatebuild ? true : false;
-}
-
-//Returns true if special build
-bool file_version_info::is_special_build() const
-{
- return file_flags_ & vs_ff_specialbuild ? true : false;
-}
-
-//Returns true if info inferred
-bool file_version_info::is_info_inferred() const
-{
- return file_flags_ & vs_ff_infoinferred ? true : false;
-}
-
-//Retuens file flags (raw DWORD)
-uint32_t file_version_info::get_file_flags() const
-{
- return file_flags_;
-}
-
-//Returns file version most significant DWORD
-uint32_t file_version_info::get_file_version_ms() const
-{
- return file_version_ms_;
-}
-
-//Returns file version least significant DWORD
-uint32_t file_version_info::get_file_version_ls() const
-{
- return file_version_ls_;
-}
-
-//Returns product version most significant DWORD
-uint32_t file_version_info::get_product_version_ms() const
-{
- return product_version_ms_;
-}
-
-//Returns product version least significant DWORD
-uint32_t file_version_info::get_product_version_ls() const
-{
- return product_version_ls_;
-}
-
-//Returns file OS type (raw DWORD)
-uint32_t file_version_info::get_file_os_raw() const
-{
- return file_os_;
-}
-
-//Returns file OS type
-file_version_info::file_os_type file_version_info::get_file_os() const
-{
- //Determine file operation system type
- switch(file_os_)
- {
- case vos_dos:
- return file_os_dos;
-
- case vos_os216:
- return file_os_os216;
-
- case vos_os232:
- return file_os_os232;
-
- case vos_nt:
- return file_os_nt;
-
- case vos_wince:
- return file_os_wince;
-
- case vos__windows16:
- return file_os_win16;
-
- case vos__pm16:
- return file_os_pm16;
-
- case vos__pm32:
- return file_os_pm32;
-
- case vos__windows32:
- return file_os_win32;
-
- case vos_dos_windows16:
- return file_os_dos_win16;
-
- case vos_dos_windows32:
- return file_os_dos_win32;
-
- case vos_os216_pm16:
- return file_os_os216_pm16;
-
- case vos_os232_pm32:
- return file_os_os232_pm32;
-
- case vos_nt_windows32:
- return file_os_nt_win32;
- }
-
- return file_os_unknown;
-}
-
-//Returns file type (raw DWORD)
-uint32_t file_version_info::get_file_type_raw() const
-{
- return file_type_;
-}
-
-//Returns file type
-file_version_info::file_type file_version_info::get_file_type() const
-{
- //Determine file type
- switch(file_type_)
- {
- case vft_app:
- return file_type_application;
-
- case vft_dll:
- return file_type_dll;
-
- case vft_drv:
- return file_type_driver;
-
- case vft_font:
- return file_type_font;
-
- case vft_vxd:
- return file_type_vxd;
-
- case vft_static_lib:
- return file_type_static_lib;
- }
-
- return file_type_unknown;
-}
-
-//Returns file subtype (usually non-zero for drivers and fonts)
-uint32_t file_version_info::get_file_subtype() const
-{
- return file_subtype_;
-}
-
-//Returns file date most significant DWORD
-uint32_t file_version_info::get_file_date_ms() const
-{
- return file_date_ms_;
-}
-
-//Returns file date least significant DWORD
-uint32_t file_version_info::get_file_date_ls() const
-{
- return file_date_ls_;
-}
-
-//Helper to set file flag
-void file_version_info::set_file_flag(uint32_t flag)
-{
- file_flags_ |= flag;
-}
-
-//Helper to clear file flag
-void file_version_info::clear_file_flag(uint32_t flag)
-{
- file_flags_ &= ~flag;
-}
-
-//Helper to set or clear file flag
-void file_version_info::set_file_flag(uint32_t flag, bool set_flag)
-{
- set_flag ? set_file_flag(flag) : clear_file_flag(flag);
-}
-
-//Sets if file is debug-built
-void file_version_info::set_debug(bool debug)
-{
- set_file_flag(vs_ff_debug, debug);
-}
-
-//Sets if file is prerelease
-void file_version_info::set_prerelease(bool prerelease)
-{
- set_file_flag(vs_ff_prerelease, prerelease);
-}
-
-//Sets if file is patched
-void file_version_info::set_patched(bool patched)
-{
- set_file_flag(vs_ff_patched, patched);
-}
-
-//Sets if private build
-void file_version_info::set_private_build(bool private_build)
-{
- set_file_flag(vs_ff_privatebuild, private_build);
-}
-
-//Sets if special build
-void file_version_info::set_special_build(bool special_build)
-{
- set_file_flag(vs_ff_specialbuild, special_build);
-}
-
-//Sets if info inferred
-void file_version_info::set_info_inferred(bool info_inferred)
-{
- set_file_flag(vs_ff_infoinferred, info_inferred);
-}
-
-//Sets flags (raw DWORD)
-void file_version_info::set_file_flags(uint32_t file_flags)
-{
- file_flags_ = file_flags;
-}
-
-//Sets file version most significant DWORD
-void file_version_info::set_file_version_ms(uint32_t file_version_ms)
-{
- file_version_ms_ = file_version_ms;
-}
-
-//Sets file version least significant DWORD
-void file_version_info::set_file_version_ls(uint32_t file_version_ls)
-{
- file_version_ls_ = file_version_ls;
-}
-
-//Sets product version most significant DWORD
-void file_version_info::set_product_version_ms(uint32_t product_version_ms)
-{
- product_version_ms_ = product_version_ms;
-}
-
-//Sets product version least significant DWORD
-void file_version_info::set_product_version_ls(uint32_t product_version_ls)
-{
- product_version_ls_ = product_version_ls;
-}
-
-//Sets file OS type (raw DWORD)
-void file_version_info::set_file_os_raw(uint32_t file_os)
-{
- file_os_ = file_os;
-}
-
-//Sets file OS type
-void file_version_info::set_file_os(file_os_type file_os)
-{
- //Determine file operation system type
- switch(file_os)
- {
- case file_os_dos:
- file_os_ = vos_dos;
- return;
-
- case file_os_os216:
- file_os_ = vos_os216;
- return;
-
- case file_os_os232:
- file_os_ = vos_os232;
- return;
-
- case file_os_nt:
- file_os_ = vos_nt;
- return;
-
- case file_os_wince:
- file_os_ = vos_wince;
- return;
-
- case file_os_win16:
- file_os_ = vos__windows16;
- return;
-
- case file_os_pm16:
- file_os_ = vos__pm16;
- return;
-
- case file_os_pm32:
- file_os_ = vos__pm32;
- return;
-
- case file_os_win32:
- file_os_ = vos__windows32;
- return;
-
- case file_os_dos_win16:
- file_os_ = vos_dos_windows16;
- return;
-
- case file_os_dos_win32:
- file_os_ = vos_dos_windows32;
- return;
-
- case file_os_os216_pm16:
- file_os_ = vos_os216_pm16;
- return;
-
- case file_os_os232_pm32:
- file_os_ = vos_os232_pm32;
- return;
-
- case file_os_nt_win32:
- file_os_ = vos_nt_windows32;
- return;
-
- default:
- return;
- }
-}
-
-//Sets file type (raw DWORD)
-void file_version_info::set_file_type_raw(uint32_t file_type)
-{
- file_type_ = file_type;
-}
-
-//Sets file type
-void file_version_info::set_file_type(file_type file_type)
-{
- //Determine file type
- switch(file_type)
- {
- case file_type_application:
- file_type_ = vft_app;
- return;
-
- case file_type_dll:
- file_type_ = vft_dll;
- return;
-
- case file_type_driver:
- file_type_ = vft_drv;
- return;
-
- case file_type_font:
- file_type_ = vft_font;
- return;
-
- case file_type_vxd:
- file_type_ = vft_vxd;
- return;
-
- case file_type_static_lib:
- file_type_ = vft_static_lib;
- return;
-
- default:
- return;
- }
-}
-
-//Sets file subtype (usually non-zero for drivers and fonts)
-void file_version_info::set_file_subtype(uint32_t file_subtype)
-{
- file_subtype_ = file_subtype;
-}
-
-//Sets file date most significant DWORD
-void file_version_info::set_file_date_ms(uint32_t file_date_ms)
-{
- file_date_ms_ = file_date_ms;
-}
-
-//Sets file date least significant DWORD
-void file_version_info::set_file_date_ls(uint32_t file_date_ls)
-{
- file_date_ls_ = file_date_ls;
-}
-}
diff --git a/tools/pe_bliss/file_version_info.h b/tools/pe_bliss/file_version_info.h
deleted file mode 100644
index d898351ba1..0000000000
--- a/tools/pe_bliss/file_version_info.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-//Structure representing fixed file version info
-class file_version_info
-{
-public:
- //Enumeration of file operating system types
- enum file_os_type
- {
- file_os_unknown,
- file_os_dos,
- file_os_os216,
- file_os_os232,
- file_os_nt,
- file_os_wince,
- file_os_win16,
- file_os_pm16,
- file_os_pm32,
- file_os_win32,
- file_os_dos_win16,
- file_os_dos_win32,
- file_os_os216_pm16,
- file_os_os232_pm32,
- file_os_nt_win32
- };
-
- //Enumeration of file types
- enum file_type
- {
- file_type_unknown,
- file_type_application,
- file_type_dll,
- file_type_driver,
- file_type_font,
- file_type_vxd,
- file_type_static_lib
- };
-
-public:
- //Default constructor
- file_version_info();
- //Constructor from Windows fixed version info structure
- explicit file_version_info(const pe_win::vs_fixedfileinfo& info);
-
-public: //Getters
- //Returns true if file is debug-built
- bool is_debug() const;
- //Returns true if file is prerelease
- bool is_prerelease() const;
- //Returns true if file is patched
- bool is_patched() const;
- //Returns true if private build
- bool is_private_build() const;
- //Returns true if special build
- bool is_special_build() const;
- //Returns true if info inferred
- bool is_info_inferred() const;
- //Retuens file flags (raw DWORD)
- uint32_t get_file_flags() const;
-
- //Returns file version most significant DWORD
- uint32_t get_file_version_ms() const;
- //Returns file version least significant DWORD
- uint32_t get_file_version_ls() const;
- //Returns product version most significant DWORD
- uint32_t get_product_version_ms() const;
- //Returns product version least significant DWORD
- uint32_t get_product_version_ls() const;
-
- //Returns file OS type (raw DWORD)
- uint32_t get_file_os_raw() const;
- //Returns file OS type
- file_os_type get_file_os() const;
-
- //Returns file type (raw DWORD)
- uint32_t get_file_type_raw() const;
- //Returns file type
- file_type get_file_type() const;
-
- //Returns file subtype (usually non-zero for drivers and fonts)
- uint32_t get_file_subtype() const;
-
- //Returns file date most significant DWORD
- uint32_t get_file_date_ms() const;
- //Returns file date least significant DWORD
- uint32_t get_file_date_ls() const;
-
- //Returns file version string
- template<typename T>
- const std::basic_string<T> get_file_version_string() const
- {
- return get_version_string<T>(file_version_ms_, file_version_ls_);
- }
-
- //Returns product version string
- template<typename T>
- const std::basic_string<T> get_product_version_string() const
- {
- return get_version_string<T>(product_version_ms_, product_version_ls_);
- }
-
-public: //Setters
- //Sets if file is debug-built
- void set_debug(bool debug);
- //Sets if file is prerelease
- void set_prerelease(bool prerelease);
- //Sets if file is patched
- void set_patched(bool patched);
- //Sets if private build
- void set_private_build(bool private_build);
- //Sets if special build
- void set_special_build(bool special_build);
- //Sets if info inferred
- void set_info_inferred(bool info_inferred);
- //Sets flags (raw DWORD)
- void set_file_flags(uint32_t file_flags);
-
- //Sets file version most significant DWORD
- void set_file_version_ms(uint32_t file_version_ms);
- //Sets file version least significant DWORD
- void set_file_version_ls(uint32_t file_version_ls);
- //Sets product version most significant DWORD
- void set_product_version_ms(uint32_t product_version_ms);
- //Sets product version least significant DWORD
- void set_product_version_ls(uint32_t product_version_ls);
-
- //Sets file OS type (raw DWORD)
- void set_file_os_raw(uint32_t file_os);
- //Sets file OS type
- void set_file_os(file_os_type file_os);
-
- //Sets file type (raw DWORD)
- void set_file_type_raw(uint32_t file_type);
- //Sets file type
- void set_file_type(file_type file_type);
-
- //Sets file subtype (usually non-zero for drivers and fonts)
- void set_file_subtype(uint32_t file_subtype);
-
- //Sets file date most significant DWORD
- void set_file_date_ms(uint32_t file_date_ms);
- //Sets file date least significant DWORD
- void set_file_date_ls(uint32_t file_date_ls);
-
-private:
- //Helper to convert version DWORDs to string
- template<typename T>
- static const std::basic_string<T> get_version_string(uint32_t ms, uint32_t ls)
- {
- std::basic_stringstream<T> ss;
- ss << (ms >> 16) << static_cast<T>(L'.')
- << (ms & 0xFFFF) << static_cast<T>(L'.')
- << (ls >> 16) << static_cast<T>(L'.')
- << (ls & 0xFFFF);
- return ss.str();
- }
-
- //Helper to set file flag
- void set_file_flag(uint32_t flag);
- //Helper to clear file flag
- void clear_file_flag(uint32_t flag);
- //Helper to set or clear file flag
- void set_file_flag(uint32_t flag, bool set_flag);
-
- uint32_t file_version_ms_, file_version_ls_,
- product_version_ms_, product_version_ls_;
- uint32_t file_flags_;
- uint32_t file_os_;
- uint32_t file_type_, file_subtype_;
- uint32_t file_date_ms_, file_date_ls_;
-};
-}
diff --git a/tools/pe_bliss/message_table.cpp b/tools/pe_bliss/message_table.cpp
deleted file mode 100644
index 909be5d494..0000000000
--- a/tools/pe_bliss/message_table.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "message_table.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-//Default constructor
-message_table_item::message_table_item()
- :unicode_(false)
-{}
-
-//Constructor from ANSI string
-message_table_item::message_table_item(const std::string& str)
- :unicode_(false), ansi_str_(str)
-{
- pe_utils::strip_nullbytes(ansi_str_);
-}
-
-//Constructor from UNICODE string
-message_table_item::message_table_item(const std::wstring& str)
- :unicode_(true), unicode_str_(str)
-{
- pe_utils::strip_nullbytes(unicode_str_);
-}
-
-//Returns true if contained string is unicode
-bool message_table_item::is_unicode() const
-{
- return unicode_;
-}
-
-//Returns ANSI string
-const std::string& message_table_item::get_ansi_string() const
-{
- return ansi_str_;
-}
-
-//Returns UNICODE string
-const std::wstring& message_table_item::get_unicode_string() const
-{
- return unicode_str_;
-}
-
-//Sets ANSI string (clears UNICODE one)
-void message_table_item::set_string(const std::string& str)
-{
- ansi_str_ = str;
- pe_utils::strip_nullbytes(ansi_str_);
- unicode_str_.clear();
- unicode_ = false;
-}
-
-//Sets UNICODE string (clears ANSI one)
-void message_table_item::set_string(const std::wstring& str)
-{
- unicode_str_ = str;
- pe_utils::strip_nullbytes(unicode_str_);
- ansi_str_.clear();
- unicode_ = true;
-}
-}
diff --git a/tools/pe_bliss/message_table.h b/tools/pe_bliss/message_table.h
deleted file mode 100644
index 5a3feb32c1..0000000000
--- a/tools/pe_bliss/message_table.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Structure representing message table string
-class message_table_item
-{
-public:
- //Default constructor
- message_table_item();
- //Constructors from ANSI and UNICODE strings
- explicit message_table_item(const std::string& str);
- explicit message_table_item(const std::wstring& str);
-
- //Returns true if string is UNICODE
- bool is_unicode() const;
- //Returns ANSI string
- const std::string& get_ansi_string() const;
- //Returns UNICODE string
- const std::wstring& get_unicode_string() const;
-
-public:
- //Sets ANSI or UNICODE string
- void set_string(const std::string& str);
- void set_string(const std::wstring& str);
-
-private:
- bool unicode_;
- std::string ansi_str_;
- std::wstring unicode_str_;
-};
-}
diff --git a/tools/pe_bliss/pe_base.cpp b/tools/pe_bliss/pe_base.cpp
deleted file mode 100644
index 97baa17cb3..0000000000
--- a/tools/pe_bliss/pe_base.cpp
+++ /dev/null
@@ -1,1680 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <algorithm>
-#include <cmath>
-#include <set>
-#include <string.h>
-#include "pe_exception.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor
-pe_base::pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data)
-{
- props_ = props.duplicate().release();
-
- //Save istream state
- std::ios_base::iostate state = file.exceptions();
- std::streamoff old_offset = file.tellg();
-
- try
- {
- file.exceptions(std::ios::goodbit);
- //Read DOS header, PE headers and section data
- read_dos_header(file);
- read_pe(file, read_debug_raw_data);
- }
- catch(const std::exception&)
- {
- //If something went wrong, restore istream state
- file.seekg(old_offset);
- file.exceptions(state);
- file.clear();
- //Rethrow
- throw;
- }
-
- //Restore istream state
- file.seekg(old_offset);
- file.exceptions(state);
- file.clear();
-}
-
-pe_base::pe_base(const pe_properties& props, uint32_t section_alignment, bool dll, uint16_t subsystem)
-{
- props_ = props.duplicate().release();
- props_->create_pe(section_alignment, subsystem);
-
- has_overlay_ = false;
- memset(&dos_header_, 0, sizeof(dos_header_));
-
- dos_header_.e_magic = 0x5A4D; //"MZ"
- //Magic numbers from MSVC++ build
- dos_header_.e_maxalloc = 0xFFFF;
- dos_header_.e_cblp = 0x90;
- dos_header_.e_cp = 3;
- dos_header_.e_cparhdr = 4;
- dos_header_.e_sp = 0xB8;
- dos_header_.e_lfarlc = 64;
-
- set_characteristics(image_file_executable_image | image_file_relocs_stripped);
-
- if(get_pe_type() == pe_type_32)
- set_characteristics_flags(image_file_32bit_machine);
-
- if(dll)
- set_characteristics_flags(image_file_dll);
-
- set_subsystem_version(5, 1); //WinXP
- set_os_version(5, 1); //WinXP
-}
-
-pe_base::pe_base(const pe_base& pe)
- :dos_header_(pe.dos_header_),
- rich_overlay_(pe.rich_overlay_),
- sections_(pe.sections_),
- has_overlay_(pe.has_overlay_),
- full_headers_data_(pe.full_headers_data_),
- debug_data_(pe.debug_data_),
- props_(0)
-{
- props_ = pe.props_->duplicate().release();
-}
-
-pe_base& pe_base::operator=(const pe_base& pe)
-{
- dos_header_ = pe.dos_header_;
- rich_overlay_ = pe.rich_overlay_;
- sections_ = pe.sections_;
- has_overlay_ = pe.has_overlay_;
- full_headers_data_ = pe.full_headers_data_;
- debug_data_ = pe.debug_data_;
- delete props_;
- props_ = 0;
- props_ = pe.props_->duplicate().release();
-
- return *this;
-}
-
-pe_base::~pe_base()
-{
- delete props_;
-}
-
-//Returns dos header
-const image_dos_header& pe_base::get_dos_header() const
-{
- return dos_header_;
-}
-
-//Returns dos header
-image_dos_header& pe_base::get_dos_header()
-{
- return dos_header_;
-}
-
-//Returns PE headers start position (e_lfanew)
-int32_t pe_base::get_pe_header_start() const
-{
- return dos_header_.e_lfanew;
-}
-
-//Strips MSVC stub overlay
-void pe_base::strip_stub_overlay()
-{
- rich_overlay_.clear();
-}
-
-//Fills MSVC stub overlay with character c
-void pe_base::fill_stub_overlay(char c)
-{
- if(rich_overlay_.length())
- rich_overlay_.assign(rich_overlay_.length(), c);
-}
-
-//Sets stub MSVS overlay
-void pe_base::set_stub_overlay(const std::string& data)
-{
- rich_overlay_ = data;
-}
-
-//Returns stub overlay
-const std::string& pe_base::get_stub_overlay() const
-{
- return rich_overlay_;
-}
-
-//Realigns all sections
-void pe_base::realign_all_sections()
-{
- for(unsigned int i = 0; i < sections_.size(); i++)
- realign_section(i);
-}
-
-//Returns number of sections from PE header
-uint16_t pe_base::get_number_of_sections() const
-{
- return props_->get_number_of_sections();
-}
-
-//Updates number of sections in PE header
-uint16_t pe_base::update_number_of_sections()
-{
- uint16_t new_number = static_cast<uint16_t>(sections_.size());
- props_->set_number_of_sections(new_number);
- return new_number;
-}
-
-//Returns section alignment
-uint32_t pe_base::get_section_alignment() const
-{
- return props_->get_section_alignment();
-}
-
-//Returns image sections list
-section_list& pe_base::get_image_sections()
-{
- return sections_;
-}
-
-//Returns image sections list
-const section_list& pe_base::get_image_sections() const
-{
- return sections_;
-}
-
-//Realigns section by index
-void pe_base::realign_section(uint32_t index)
-{
- //Check index
- if(sections_.size() <= index)
- throw pe_exception("Section not found", pe_exception::section_not_found);
-
- //Get section iterator
- section_list::iterator it = sections_.begin() + index;
- section& s = *it;
-
- //Calculate, how many null bytes we have in the end of raw section data
- std::size_t strip = 0;
- for(std::size_t i = (*it).get_raw_data().length(); i >= 1; --i)
- {
- if(s.get_raw_data()[i - 1] == 0)
- strip++;
- else
- break;
- }
-
- if(it == sections_.end() - 1) //If we're realigning the last section
- {
- //We can strip ending null bytes
- s.set_size_of_raw_data(static_cast<uint32_t>(s.get_raw_data().length() - strip));
- s.get_raw_data().resize(s.get_raw_data().length() - strip, 0);
- }
- else
- {
- //Else just set size of raw data
- uint32_t raw_size_aligned = s.get_aligned_raw_size(get_file_alignment());
- s.set_size_of_raw_data(raw_size_aligned);
- s.get_raw_data().resize(raw_size_aligned, 0);
- }
-}
-
-//Returns file alignment
-uint32_t pe_base::get_file_alignment() const
-{
- return props_->get_file_alignment();
-}
-
-//Sets file alignment
-void pe_base::set_file_alignment(uint32_t alignment)
-{
- //Check alignment
- if(alignment < minimum_file_alignment)
- throw pe_exception("File alignment can't be less than 512", pe_exception::incorrect_file_alignment);
-
- if(!pe_utils::is_power_of_2(alignment))
- throw pe_exception("File alignment must be a power of 2", pe_exception::incorrect_file_alignment);
-
- if(alignment > get_section_alignment())
- throw pe_exception("File alignment must be <= section alignment", pe_exception::incorrect_file_alignment);
-
- //Set file alignment without any additional checks
- set_file_alignment_unchecked(alignment);
-}
-
-//Returns size of image
-uint32_t pe_base::get_size_of_image() const
-{
- return props_->get_size_of_image();
-}
-
-//Returns image entry point
-uint32_t pe_base::get_ep() const
-{
- return props_->get_ep();
-}
-
-//Sets image entry point (just a value of PE header)
-void pe_base::set_ep(uint32_t new_ep)
-{
- props_->set_ep(new_ep);
-}
-
-//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-uint32_t pe_base::get_number_of_rvas_and_sizes() const
-{
- return props_->get_number_of_rvas_and_sizes();
-}
-
-//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-void pe_base::set_number_of_rvas_and_sizes(uint32_t number)
-{
- props_->set_number_of_rvas_and_sizes(number);
-}
-
-//Returns PE characteristics
-uint16_t pe_base::get_characteristics() const
-{
- return props_->get_characteristics();
-}
-
-//Sets PE characteristics (a value inside header)
-void pe_base::set_characteristics(uint16_t ch)
-{
- props_->set_characteristics(ch);
-}
-
-//Returns section from RVA
-section& pe_base::section_from_rva(uint32_t rva)
-{
- //Search for section
- for(section_list::iterator i = sections_.begin(); i != sections_.end(); ++i)
- {
- section& s = *i;
- //Return section if found
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- return s;
- }
-
- throw pe_exception("No section found by presented address", pe_exception::no_section_found);
-}
-
-//Returns section from RVA
-const section& pe_base::section_from_rva(uint32_t rva) const
-{
- //Search for section
- for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i)
- {
- const section& s = *i;
- //Return section if found
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- return s;
- }
-
- throw pe_exception("No section found by presented address", pe_exception::no_section_found);
-}
-
-//Returns section from directory ID
-section& pe_base::section_from_directory(uint32_t directory_id)
-{
- return section_from_rva(get_directory_rva(directory_id));
-}
-
-//Returns section from directory ID
-const section& pe_base::section_from_directory(uint32_t directory_id) const
-{
- return section_from_rva(get_directory_rva(directory_id));
-}
-
-//Sets section virtual size (actual for the last one of this PE or for unbound section)
-void pe_base::set_section_virtual_size(section& s, uint32_t vsize)
-{
- //Check if we're changing virtual size of the last section
- //Of course, we can change virtual size of section that's not bound to this PE file
- if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1)
- throw pe_exception("Can't change virtual size of any section, except last one", pe_exception::error_changing_section_virtual_size);
-
- //If we're setting virtual size to zero
- if(vsize == 0)
- {
- //Check if section is empty
- if(s.empty())
- throw pe_exception("Cannot set virtual size of empty section to zero", pe_exception::error_changing_section_virtual_size);
-
- //Set virtual size equal to aligned size of raw data
- s.set_virtual_size(s.get_size_of_raw_data());
- }
- else
- {
- s.set_virtual_size(vsize);
- }
-
- //Update image size if we're changing virtual size for the last section of this PE
- if(!sections_.empty() || &s == &(*(sections_.end() - 1)))
- update_image_size();
-}
-
-//Expands section raw or virtual size to hold data from specified RVA with specified size
-//Section must be free (not bound to any image)
-//or the last section of this image
-bool pe_base::expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand)
-{
- //Check if we're changing the last section
- //Of course, we can change the section that's not bound to this PE file
- if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1)
- throw pe_exception("Can't expand any section, except last one", pe_exception::error_expanding_section);
-
- //Check if we should expand our section
- if(expand == expand_section_raw && section_data_length_from_rva(s, needed_rva, section_data_raw) < needed_size)
- {
- //Expand section raw data
- s.get_raw_data().resize(needed_rva - s.get_virtual_address() + needed_size);
- recalculate_section_sizes(s, false);
- return true;
- }
- else if(expand == expand_section_virtual && section_data_length_from_rva(s, needed_rva, section_data_virtual) < needed_size)
- {
- //Expand section virtual data
- set_section_virtual_size(s, needed_rva - s.get_virtual_address() + needed_size);
- return true;
- }
-
- return false;
-}
-
-//Updates image virtual size
-void pe_base::update_image_size()
-{
- //Write virtual size of image to headers
- if(!sections_.empty())
- set_size_of_image(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()));
- else
- set_size_of_image(get_size_of_headers());
-}
-
-//Returns checksum of PE file from header
-uint32_t pe_base::get_checksum() const
-{
- return props_->get_checksum();
-}
-
-//Sets checksum of PE file
-void pe_base::set_checksum(uint32_t checksum)
-{
- props_->set_checksum(checksum);
-}
-
-//Returns timestamp of PE file from header
-uint32_t pe_base::get_time_date_stamp() const
-{
- return props_->get_time_date_stamp();
-}
-
-//Sets timestamp of PE file
-void pe_base::set_time_date_stamp(uint32_t timestamp)
-{
- props_->set_time_date_stamp(timestamp);
-}
-
-//Returns Machine field value of PE file from header
-uint16_t pe_base::get_machine() const
-{
- return props_->get_machine();
-}
-
-//Sets Machine field value of PE file
-void pe_base::set_machine(uint16_t machine)
-{
- props_->set_machine(machine);
-}
-
-//Prepares section before attaching it
-void pe_base::prepare_section(section& s)
-{
- //Calculate its size of raw data
- s.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(s.get_raw_data().length(), get_file_alignment())));
-
- //Check section virtual and raw size
- if(!s.get_size_of_raw_data() && !s.get_virtual_size())
- throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes);
-
- //If section virtual size is zero
- if(!s.get_virtual_size())
- {
- s.set_virtual_size(s.get_size_of_raw_data());
- }
- else
- {
- //Else calculate its virtual size
- s.set_virtual_size(
- std::max<uint32_t>(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()),
- pe_utils::align_up(s.get_virtual_size(), get_section_alignment())));
- }
-}
-
-//Adds section to image
-section& pe_base::add_section(section s)
-{
- if(sections_.size() >= maximum_number_of_sections)
- throw pe_exception("Maximum number of sections has been reached", pe_exception::no_more_sections_can_be_added);
-
- //Prepare section before adding it
- prepare_section(s);
-
- //Calculate section virtual address
- if(!sections_.empty())
- {
- s.set_virtual_address(pe_utils::align_up(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()), get_section_alignment()));
-
- //We should align last section raw size, if it wasn't aligned
- section& last = sections_.back();
- last.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(last.get_raw_data().length(), get_file_alignment())));
- }
- else
- {
- s.set_virtual_address(
- s.get_virtual_address() == 0
- ? pe_utils::align_up(get_size_of_headers(), get_section_alignment())
- : pe_utils::align_up(s.get_virtual_address(), get_section_alignment()));
- }
-
- //Add section to the end of section list
- sections_.push_back(s);
- //Set number of sections in PE header
- set_number_of_sections(static_cast<uint16_t>(sections_.size()));
- //Recalculate virtual size of image
- set_size_of_image(get_size_of_image() + s.get_aligned_virtual_size(get_section_alignment()));
- //Return last section
- return sections_.back();
-}
-
-//Returns true if sectios "s" is already attached to this PE file
-bool pe_base::section_attached(const section& s) const
-{
- return sections_.end() != std::find_if(sections_.begin(), sections_.end(), section_ptr_finder(s));
-}
-
-//Returns true if directory exists
-bool pe_base::directory_exists(uint32_t id) const
-{
- return props_->directory_exists(id);
-}
-
-//Removes directory
-void pe_base::remove_directory(uint32_t id)
-{
- props_->remove_directory(id);
-}
-
-//Returns directory RVA
-uint32_t pe_base::get_directory_rva(uint32_t id) const
-{
- return props_->get_directory_rva(id);
-}
-
-//Returns directory size
-uint32_t pe_base::get_directory_size(uint32_t id) const
-{
- return props_->get_directory_size(id);
-}
-
-//Sets directory RVA (just a value of PE header, no moving occurs)
-void pe_base::set_directory_rva(uint32_t id, uint32_t rva)
-{
- return props_->set_directory_rva(id, rva);
-}
-
-//Sets directory size (just a value of PE header, no moving occurs)
-void pe_base::set_directory_size(uint32_t id, uint32_t size)
-{
- return props_->set_directory_size(id, size);
-}
-
-//Strips only zero DATA_DIRECTORY entries to count = min_count
-//Returns resulting number of data directories
-//strip_iat_directory - if true, even not empty IAT directory will be stripped
-uint32_t pe_base::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
-{
- return props_->strip_data_directories(min_count, strip_iat_directory);
-}
-
-//Returns true if image has import directory
-bool pe_base::has_imports() const
-{
- return directory_exists(image_directory_entry_import);
-}
-
-//Returns true if image has export directory
-bool pe_base::has_exports() const
-{
- return directory_exists(image_directory_entry_export);
-}
-
-//Returns true if image has resource directory
-bool pe_base::has_resources() const
-{
- return directory_exists(image_directory_entry_resource);
-}
-
-//Returns true if image has security directory
-bool pe_base::has_security() const
-{
- return directory_exists(image_directory_entry_security);
-}
-
-//Returns true if image has relocations
-bool pe_base::has_reloc() const
-{
- return directory_exists(image_directory_entry_basereloc) && !(get_characteristics() & image_file_relocs_stripped);
-}
-
-//Returns true if image has TLS directory
-bool pe_base::has_tls() const
-{
- return directory_exists(image_directory_entry_tls);
-}
-
-//Returns true if image has config directory
-bool pe_base::has_config() const
-{
- return directory_exists(image_directory_entry_load_config);
-}
-
-//Returns true if image has bound import directory
-bool pe_base::has_bound_import() const
-{
- return directory_exists(image_directory_entry_bound_import);
-}
-
-//Returns true if image has delay import directory
-bool pe_base::has_delay_import() const
-{
- return directory_exists(image_directory_entry_delay_import);
-}
-
-//Returns true if image has COM directory
-bool pe_base::is_dotnet() const
-{
- return directory_exists(image_directory_entry_com_descriptor);
-}
-
-//Returns true if image has exception directory
-bool pe_base::has_exception_directory() const
-{
- return directory_exists(image_directory_entry_exception);
-}
-
-//Returns true if image has debug directory
-bool pe_base::has_debug() const
-{
- return directory_exists(image_directory_entry_debug);
-}
-
-//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-char* pe_base::section_data_from_rva(section& s, uint32_t rva)
-{
- //Check if RVA is inside section "s"
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- {
- if(s.get_raw_data().empty())
- throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty);
-
- return &s.get_raw_data()[rva - s.get_virtual_address()];
- }
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-const char* pe_base::section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype) const
-{
- //Check if RVA is inside section "s"
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address();
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
-uint32_t pe_base::section_data_length_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
-{
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length())
- return static_cast<unsigned long>(full_headers_data_.length());
-
- const section& s = section_from_rva(rva);
- return static_cast<unsigned long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()));
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32
-uint32_t pe_base::section_data_length_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32/PE64
-uint32_t pe_base::section_data_length_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
-uint32_t pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype, bool include_headers) const
-{
- //if RVAs are inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length() && rva_inside < full_headers_data_.length())
- return static_cast<unsigned long>(full_headers_data_.length() - rva_inside);
-
- const section& s = section_from_rva(rva);
- if(rva_inside < s.get_virtual_address())
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-
- //Calculate remaining length of section data from "rva" address
- long length = static_cast<long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()))
- + s.get_virtual_address() - rva_inside;
-
- if(length < 0)
- return 0;
-
- return static_cast<unsigned long>(length);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32
-uint32_t pe_base::section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32/PE64
-uint32_t pe_base::section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype, bool include_headers) const
-{
- return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
-uint32_t pe_base::section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype) const
-{
- //Check rva_inside
- if(rva_inside >= s.get_virtual_address() && rva_inside < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
- {
- //Calculate remaining length of section data from "rva" address
- int32_t length = static_cast<int32_t>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()))
- + s.get_virtual_address() - rva_inside;
-
- if(length < 0)
- return 0;
-
- return static_cast<uint32_t>(length);
- }
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 (checks bounds)
-uint32_t pe_base::section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype) const
-{
- return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32/PE64 (checks bounds)
-uint32_t pe_base::section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype) const
-{
- return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
-}
-
-//Returns corresponding section data pointer from RVA inside section
-char* pe_base::section_data_from_rva(uint32_t rva, bool include_headers)
-{
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length())
- return &full_headers_data_[rva];
-
- section& s = section_from_rva(rva);
-
- if(s.get_raw_data().empty())
- throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty);
-
- return &s.get_raw_data()[rva - s.get_virtual_address()];
-}
-
-//Returns corresponding section data pointer from RVA inside section
-const char* pe_base::section_data_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
-{
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && rva < full_headers_data_.length())
- return &full_headers_data_[rva];
-
- const section& s = section_from_rva(rva);
- return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address();
-}
-
-//Reads DOS headers from istream
-void pe_base::read_dos_header(std::istream& file, image_dos_header& header)
-{
- //Check istream flags
- if(file.bad() || file.eof())
- throw pe_exception("PE file stream is bad or closed.", pe_exception::bad_pe_file);
-
- //Read DOS header and check istream
- file.read(reinterpret_cast<char*>(&header), sizeof(image_dos_header));
- if(file.bad() || file.eof())
- throw pe_exception("Unable to read IMAGE_DOS_HEADER", pe_exception::bad_dos_header);
-
- //Check DOS header magic
- if(header.e_magic != 0x5a4d) //"MZ"
- throw pe_exception("IMAGE_DOS_HEADER signature is incorrect", pe_exception::bad_dos_header);
-}
-
-//Reads DOS headers from istream
-void pe_base::read_dos_header(std::istream& file)
-{
- read_dos_header(file, dos_header_);
-}
-
-//Reads PE image from istream
-void pe_base::read_pe(std::istream& file, bool read_debug_raw_data)
-{
- //Get istream size
- std::streamoff filesize = pe_utils::get_file_size(file);
-
- //Check if PE header is DWORD-aligned
- if((dos_header_.e_lfanew % sizeof(uint32_t)) != 0)
- throw pe_exception("PE header is not DWORD-aligned", pe_exception::bad_dos_header);
-
- //Seek to NT headers
- file.seekg(dos_header_.e_lfanew);
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found);
-
- //Read NT headers
- file.read(get_nt_headers_ptr(), get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers);
-
- //Check PE signature
- if(get_pe_signature() != 0x4550) //"PE"
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
- //Check number of directories
- if(get_number_of_rvas_and_sizes() > image_numberof_directory_entries)
- set_number_of_rvas_and_sizes(image_numberof_directory_entries);
-
- if(get_number_of_rvas_and_sizes() > 0)
- {
- //Read data directory headers, if any
- file.read(get_nt_headers_ptr() + (get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries), sizeof(image_data_directory) * get_number_of_rvas_and_sizes());
- if(file.bad() || file.eof())
- throw pe_exception("Error reading DATA_DIRECTORY headers", pe_exception::error_reading_data_directories);
- }
-
- //Check section number
- //Images with zero section number accepted
- if(get_number_of_sections() > maximum_number_of_sections)
- throw pe_exception("Incorrect number of sections", pe_exception::section_number_incorrect);
-
- //Check PE magic
- if(get_magic() != get_needed_magic())
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
- //Check section alignment
- if(!pe_utils::is_power_of_2(get_section_alignment()))
- throw pe_exception("Incorrect section alignment", pe_exception::incorrect_section_alignment);
-
- //Check file alignment
- if(!pe_utils::is_power_of_2(get_file_alignment()))
- throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment);
-
- if(get_file_alignment() != get_section_alignment() && (get_file_alignment() < minimum_file_alignment || get_file_alignment() > get_section_alignment()))
- throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment);
-
- //Check size of image
- if(pe_utils::align_up(get_size_of_image(), get_section_alignment()) == 0)
- throw pe_exception("Incorrect size of image", pe_exception::incorrect_size_of_image);
-
- //Read rich data overlay / DOS stub (if any)
- if(static_cast<uint32_t>(dos_header_.e_lfanew) > sizeof(image_dos_header))
- {
- rich_overlay_.resize(dos_header_.e_lfanew - sizeof(image_dos_header));
- file.seekg(sizeof(image_dos_header));
- file.read(&rich_overlay_[0], dos_header_.e_lfanew - sizeof(image_dos_header));
- if(file.bad() || file.eof())
- throw pe_exception("Error reading 'Rich' & 'DOS stub' overlay", pe_exception::error_reading_overlay);
- }
-
- //Calculate first section raw position
- //Sum is safe here
- uint32_t first_section = dos_header_.e_lfanew + get_size_of_optional_header() + sizeof(image_file_header) + sizeof(uint32_t) /* Signature */;
-
- if(get_number_of_sections() > 0)
- {
- //Go to first section
- file.seekg(first_section);
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach section headers", pe_exception::image_section_headers_not_found);
- }
-
- uint32_t last_raw_size = 0;
-
- //Read all sections
- for(int i = 0; i < get_number_of_sections(); i++)
- {
- section s;
- //Read section header
- file.read(reinterpret_cast<char*>(&s.get_raw_header()), sizeof(image_section_header));
- if(file.bad() || file.eof())
- throw pe_exception("Error reading section header", pe_exception::error_reading_section_header);
-
- //Save next section header position
- std::streamoff next_sect = file.tellg();
-
- //Check section virtual and raw sizes
- if(!s.get_size_of_raw_data() && !s.get_virtual_size())
- throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes);
-
- //Check for adequate values of section fields
- if(!pe_utils::is_sum_safe(s.get_virtual_address(), s.get_virtual_size()) || s.get_virtual_size() > pe_utils::two_gb
- || !pe_utils::is_sum_safe(s.get_pointer_to_raw_data(), s.get_size_of_raw_data()) || s.get_size_of_raw_data() > pe_utils::two_gb)
- throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
- if(s.get_size_of_raw_data() != 0)
- {
- //If section has raw data
-
- //If section raw data size is greater than virtual, fix it
- last_raw_size = s.get_size_of_raw_data();
- if(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()) > pe_utils::align_up(s.get_virtual_size(), get_section_alignment()))
- s.set_size_of_raw_data(s.get_virtual_size());
-
- //Check virtual and raw section sizes and addresses
- if(s.get_virtual_address() + pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment())
- ||
- pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()) + s.get_size_of_raw_data() > static_cast<uint32_t>(filesize))
- throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
- //Seek to section raw data
- file.seekg(pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()));
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach section data", pe_exception::image_section_data_not_found);
-
- //Read section raw data
- s.get_raw_data().resize(s.get_size_of_raw_data());
- file.read(&s.get_raw_data()[0], s.get_size_of_raw_data());
- if(file.bad() || file.fail())
- throw pe_exception("Error reading section data", pe_exception::image_section_data_not_found);
- }
-
- //Check virtual address and size of section
- if(s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment()))
- throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
- //Save section
- sections_.push_back(s);
-
- //Seek to the next section header
- file.seekg(next_sect);
- }
-
- //Check size of headers: SizeOfHeaders can't be larger than first section VA
- if(!sections_.empty() && get_size_of_headers() > sections_.front().get_virtual_address())
- throw pe_exception("Incorrect size of headers", pe_exception::incorrect_size_of_headers);
-
- //If image has more than two sections
- if(sections_.size() >= 2)
- {
- //Check sections virtual sizes
- for(section_list::const_iterator i = sections_.begin() + 1; i != sections_.end(); ++i)
- {
- if((*i).get_virtual_address() != (*(i - 1)).get_virtual_address() + (*(i - 1)).get_aligned_virtual_size(get_section_alignment()))
- throw pe_exception("Section table is incorrect", pe_exception::image_section_table_incorrect);
- }
- }
-
- //Check if image has overlay in the end of file
- has_overlay_ = !sections_.empty() && filesize > static_cast<std::streamoff>(sections_.back().get_pointer_to_raw_data() + last_raw_size);
-
- {
- //Additionally, read data from the beginning of istream to size of headers
- file.seekg(0);
- uint32_t size_of_headers = std::min<uint32_t>(get_size_of_headers(), static_cast<uint32_t>(filesize));
-
- if(!sections_.empty())
- {
- for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i)
- {
- if(!(*i).empty())
- {
- size_of_headers = std::min<uint32_t>(get_size_of_headers(), (*i).get_pointer_to_raw_data());
- break;
- }
- }
- }
-
- full_headers_data_.resize(size_of_headers);
- file.read(&full_headers_data_[0], size_of_headers);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading file", pe_exception::error_reading_file);
- }
-
- //Moreover, if there's debug directory, read its raw data for some debug info types
- while(read_debug_raw_data && has_debug())
- {
- try
- {
- //Check the length in bytes of the section containing debug directory
- if(section_data_length_from_rva(get_directory_rva(image_directory_entry_debug), get_directory_rva(image_directory_entry_debug), section_data_virtual, true) < sizeof(image_debug_directory))
- break;
-
- unsigned long current_pos = get_directory_rva(image_directory_entry_debug);
-
- //First IMAGE_DEBUG_DIRECTORY table
- image_debug_directory directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-
- //Iterate over all IMAGE_DEBUG_DIRECTORY directories
- while(directory.PointerToRawData
- && current_pos < get_directory_rva(image_directory_entry_debug) + get_directory_size(image_directory_entry_debug))
- {
- //If we have something to read
- if((directory.Type == image_debug_type_codeview
- || directory.Type == image_debug_type_misc
- || directory.Type == image_debug_type_coff)
- && directory.SizeOfData)
- {
- std::string data;
- data.resize(directory.SizeOfData);
- file.seekg(directory.PointerToRawData);
- file.read(&data[0], directory.SizeOfData);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading file", pe_exception::error_reading_file);
-
- debug_data_.insert(std::make_pair(directory.PointerToRawData, data));
- }
-
- //Go to next debug entry
- current_pos += sizeof(image_debug_directory);
- directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
- }
-
- break;
- }
- catch(const pe_exception&)
- {
- //Don't throw any exception here, if debug info is corrupted or incorrect
- break;
- }
- catch(const std::bad_alloc&)
- {
- //Don't throw any exception here, if debug info is corrupted or incorrect
- break;
- }
- }
-}
-
-//Returns PE type of this image
-pe_type pe_base::get_pe_type() const
-{
- return props_->get_pe_type();
-}
-
-//Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks)
-pe_type pe_base::get_pe_type(std::istream& file)
-{
- //Save state of the istream
- std::ios_base::iostate state = file.exceptions();
- std::streamoff old_offset = file.tellg();
- image_nt_headers32 nt_headers;
- image_dos_header header;
-
- try
- {
- //Read dos header
- file.exceptions(std::ios::goodbit);
- read_dos_header(file, header);
-
- //Seek to the NT headers start
- file.seekg(header.e_lfanew);
- if(file.bad() || file.fail())
- throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found);
-
- //Read NT headers (we're using 32-bit version, because there's no significant differencies between 32 and 64 bit version structures)
- file.read(reinterpret_cast<char*>(&nt_headers), sizeof(image_nt_headers32) - sizeof(image_data_directory) * image_numberof_directory_entries);
- if(file.bad() || file.eof())
- throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers);
-
- //Check NT headers signature
- if(nt_headers.Signature != 0x4550) //"PE"
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
- //Check NT headers magic
- if(nt_headers.OptionalHeader.Magic != image_nt_optional_hdr32_magic && nt_headers.OptionalHeader.Magic != image_nt_optional_hdr64_magic)
- throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
- }
- catch(const std::exception&)
- {
- //If something went wrong, restore istream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
- //Retrhow exception
- throw;
- }
-
- //Restore stream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
-
- //Determine PE type and return it
- return nt_headers.OptionalHeader.Magic == image_nt_optional_hdr64_magic ? pe_type_64 : pe_type_32;
-}
-
-//Returns true if image has overlay data at the end of file
-bool pe_base::has_overlay() const
-{
- return has_overlay_;
-}
-
-//Clears PE characteristics flag
-void pe_base::clear_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() & ~flags);
-}
-
-//Sets PE characteristics flag
-void pe_base::set_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() | flags);
-}
-
-//Returns true if PE characteristics flag set
-bool pe_base::check_characteristics_flag(uint16_t flag) const
-{
- return (get_characteristics() & flag) ? true : false;
-}
-
-//Returns subsystem value
-uint16_t pe_base::get_subsystem() const
-{
- return props_->get_subsystem();
-}
-
-//Sets subsystem value
-void pe_base::set_subsystem(uint16_t subsystem)
-{
- props_->set_subsystem(subsystem);
-}
-
-//Returns true if image has console subsystem
-bool pe_base::is_console() const
-{
- return get_subsystem() == image_subsystem_windows_cui;
-}
-
-//Returns true if image has Windows GUI subsystem
-bool pe_base::is_gui() const
-{
- return get_subsystem() == image_subsystem_windows_gui;
-}
-
-//Sets required operation system version
-void pe_base::set_os_version(uint16_t major, uint16_t minor)
-{
- props_->set_os_version(major, minor);
-}
-
-//Returns required operation system version (minor word)
-uint16_t pe_base::get_minor_os_version() const
-{
- return props_->get_minor_os_version();
-}
-
-//Returns required operation system version (major word)
-uint16_t pe_base::get_major_os_version() const
-{
- return props_->get_major_os_version();
-}
-
-//Sets required subsystem version
-void pe_base::set_subsystem_version(uint16_t major, uint16_t minor)
-{
- props_->set_subsystem_version(major, minor);
-}
-
-//Returns required subsystem version (minor word)
-uint16_t pe_base::get_minor_subsystem_version() const
-{
- return props_->get_minor_subsystem_version();
-}
-
-//Returns required subsystem version (major word)
-uint16_t pe_base::get_major_subsystem_version() const
-{
- return props_->get_major_subsystem_version();
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds)
-char* pe_base::section_data_from_va(section& s, uint32_t va) //Always returns raw data
-{
- return section_data_from_rva(s, va_to_rva(va));
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds)
-const char* pe_base::section_data_from_va(const section& s, uint32_t va, section_data_type datatype) const
-{
- return section_data_from_rva(s, va_to_rva(va), datatype);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32
-char* pe_base::section_data_from_va(uint32_t va, bool include_headers) //Always returns raw data
-{
- return section_data_from_rva(va_to_rva(va), include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32
-const char* pe_base::section_data_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds)
-char* pe_base::section_data_from_va(section& s, uint64_t va) //Always returns raw data
-{
- return section_data_from_rva(s, va_to_rva(va));
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds)
-const char* pe_base::section_data_from_va(const section& s, uint64_t va, section_data_type datatype) const
-{
- return section_data_from_rva(s, va_to_rva(va), datatype);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32/PE64
-char* pe_base::section_data_from_va(uint64_t va, bool include_headers) //Always returns raw data
-{
- return section_data_from_rva(va_to_rva(va), include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32/PE64
-const char* pe_base::section_data_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
-{
- return section_data_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section from VA inside it for PE32
-section& pe_base::section_from_va(uint32_t va)
-{
- return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from VA inside it for PE32/PE64
-section& pe_base::section_from_va(uint64_t va)
-{
- return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from RVA inside it for PE32
-const section& pe_base::section_from_va(uint32_t va) const
-{
- return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from RVA inside it for PE32/PE64
-const section& pe_base::section_from_va(uint64_t va) const
-{
- return section_from_rva(va_to_rva(va));
-}
-
-uint32_t pe_base::va_to_rva(uint32_t va, bool bound_check) const
-{
- return props_->va_to_rva(va, bound_check);
-}
-
-uint32_t pe_base::va_to_rva(uint64_t va, bool bound_check) const
-{
- return props_->va_to_rva(va, bound_check);
-}
-
-uint32_t pe_base::rva_to_va_32(uint32_t rva) const
-{
- return props_->rva_to_va_32(rva);
-}
-
-uint64_t pe_base::rva_to_va_64(uint32_t rva) const
-{
- return props_->rva_to_va_64(rva);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertion for PE32
-void pe_base::rva_to_va(uint32_t rva, uint32_t& va) const
-{
- va = rva_to_va_32(rva);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64
-void pe_base::rva_to_va(uint32_t rva, uint64_t& va) const
-{
- va = rva_to_va_64(rva);
-}
-
-//Returns section from file offset (4gb max)
-section& pe_base::section_from_file_offset(uint32_t offset)
-{
- return *file_offset_to_section(offset);
-}
-
-//Returns section from file offset (4gb max)
-const section& pe_base::section_from_file_offset(uint32_t offset) const
-{
- return *file_offset_to_section(offset);
-}
-
-//Returns section and offset (raw data only) from its start from RVA
-const std::pair<uint32_t, const section*> pe_base::section_and_offset_from_rva(uint32_t rva) const
-{
- const section& s = section_from_rva(rva);
- return std::make_pair(rva - s.get_virtual_address(), &s);
-}
-
-//Returns DLL Characteristics
-uint16_t pe_base::get_dll_characteristics() const
-{
- return props_->get_dll_characteristics();
-}
-
-//Sets DLL Characteristics
-void pe_base::set_dll_characteristics(uint16_t characteristics)
-{
- props_->set_dll_characteristics(characteristics);
-}
-
-//Returns size of headers
-uint32_t pe_base::get_size_of_headers() const
-{
- return props_->get_size_of_headers();
-}
-
-//Returns size of optional header
-uint16_t pe_base::get_size_of_optional_header() const
-{
- return props_->get_size_of_optional_header();
-}
-
-//Returns PE signature
-uint32_t pe_base::get_pe_signature() const
-{
- return props_->get_pe_signature();
-}
-
-//Returns magic value
-uint32_t pe_base::get_magic() const
-{
- return props_->get_magic();
-}
-
-//Returns image base for PE32
-void pe_base::get_image_base(uint32_t& base) const
-{
- base = get_image_base_32();
-}
-
-//Returns image base for PE32 and PE64 respectively
-uint32_t pe_base::get_image_base_32() const
-{
- return props_->get_image_base_32();
-}
-
-//Sets image base for PE32 and PE64 respectively
-uint64_t pe_base::get_image_base_64() const
-{
- return props_->get_image_base_64();
-}
-
-//RVA to RAW file offset convertion (4gb max)
-uint32_t pe_base::rva_to_file_offset(uint32_t rva) const
-{
- //Maybe, RVA is inside PE headers
- if(rva < get_size_of_headers())
- return rva;
-
- const section& s = section_from_rva(rva);
- return s.get_pointer_to_raw_data() + rva - s.get_virtual_address();
-}
-
-//RAW file offset to RVA convertion (4gb max)
-uint32_t pe_base::file_offset_to_rva(uint32_t offset) const
-{
- //Maybe, offset is inside PE headers
- if(offset < get_size_of_headers())
- return offset;
-
- const section_list::const_iterator it = file_offset_to_section(offset);
- return offset - (*it).get_pointer_to_raw_data() + (*it).get_virtual_address();
-}
-
-//RAW file offset to section convertion helper (4gb max)
-section_list::const_iterator pe_base::file_offset_to_section(uint32_t offset) const
-{
- section_list::const_iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset));
- if(it == sections_.end())
- throw pe_exception("No section found by presented file offset", pe_exception::no_section_found);
-
- return it;
-}
-
-//RAW file offset to section convertion helper (4gb max)
-section_list::iterator pe_base::file_offset_to_section(uint32_t offset)
-{
- section_list::iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset));
- if(it == sections_.end())
- throw pe_exception("No section found by presented file offset", pe_exception::no_section_found);
-
- return it;
-}
-
-//RVA from section raw data offset
-uint32_t pe_base::rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start)
-{
- return s.get_virtual_address() + raw_offset_from_section_start;
-}
-
-//Returns image base for PE32/PE64
-void pe_base::get_image_base(uint64_t& base) const
-{
- base = get_image_base_64();
-}
-
-//Sets new image base
-void pe_base::set_image_base(uint32_t base)
-{
- props_->set_image_base(base);
-}
-
-void pe_base::set_image_base_64(uint64_t base)
-{
- props_->set_image_base_64(base);
-}
-
-//Sets heap size commit for PE32 and PE64 respectively
-void pe_base::set_heap_size_commit(uint32_t size)
-{
- props_->set_heap_size_commit(size);
-}
-
-void pe_base::set_heap_size_commit(uint64_t size)
-{
- props_->set_heap_size_commit(size);
-}
-
-//Sets heap size reserve for PE32 and PE64 respectively
-void pe_base::set_heap_size_reserve(uint32_t size)
-{
- props_->set_heap_size_reserve(size);
-}
-
-void pe_base::set_heap_size_reserve(uint64_t size)
-{
- props_->set_heap_size_reserve(size);
-}
-
-//Sets stack size commit for PE32 and PE64 respectively
-void pe_base::set_stack_size_commit(uint32_t size)
-{
- props_->set_stack_size_commit(size);
-}
-
-void pe_base::set_stack_size_commit(uint64_t size)
-{
- props_->set_stack_size_commit(size);
-}
-
-//Sets stack size reserve for PE32 and PE64 respectively
-void pe_base::set_stack_size_reserve(uint32_t size)
-{
- props_->set_stack_size_reserve(size);
-}
-
-void pe_base::set_stack_size_reserve(uint64_t size)
-{
- props_->set_stack_size_reserve(size);
-}
-
-//Returns heap size commit for PE32 and PE64 respectively
-uint32_t pe_base::get_heap_size_commit_32() const
-{
- return props_->get_heap_size_commit_32();
-}
-
-uint64_t pe_base::get_heap_size_commit_64() const
-{
- return props_->get_heap_size_commit_64();
-}
-
-//Returns heap size reserve for PE32 and PE64 respectively
-uint32_t pe_base::get_heap_size_reserve_32() const
-{
- return props_->get_heap_size_reserve_32();
-}
-
-uint64_t pe_base::get_heap_size_reserve_64() const
-{
- return props_->get_heap_size_reserve_64();
-}
-
-//Returns stack size commit for PE32 and PE64 respectively
-uint32_t pe_base::get_stack_size_commit_32() const
-{
- return props_->get_stack_size_commit_32();
-}
-
-uint64_t pe_base::get_stack_size_commit_64() const
-{
- return props_->get_stack_size_commit_64();
-}
-
-//Returns stack size reserve for PE32 and PE64 respectively
-uint32_t pe_base::get_stack_size_reserve_32() const
-{
- return props_->get_stack_size_reserve_32();
-}
-
-uint64_t pe_base::get_stack_size_reserve_64() const
-{
- return props_->get_stack_size_reserve_64();
-}
-
-//Returns heap size commit for PE32
-void pe_base::get_heap_size_commit(uint32_t& size) const
-{
- size = get_heap_size_commit_32();
-}
-
-//Returns heap size commit for PE32/PE64
-void pe_base::get_heap_size_commit(uint64_t& size) const
-{
- size = get_heap_size_commit_64();
-}
-
-//Returns heap size reserve for PE32
-void pe_base::get_heap_size_reserve(uint32_t& size) const
-{
- size = get_heap_size_reserve_32();
-}
-
-//Returns heap size reserve for PE32/PE64
-void pe_base::get_heap_size_reserve(uint64_t& size) const
-{
- size = get_heap_size_reserve_64();
-}
-
-//Returns stack size commit for PE32
-void pe_base::get_stack_size_commit(uint32_t& size) const
-{
- size = get_stack_size_commit_32();
-}
-
-//Returns stack size commit for PE32/PE64
-void pe_base::get_stack_size_commit(uint64_t& size) const
-{
- size = get_stack_size_commit_64();
-}
-
-//Returns stack size reserve for PE32
-void pe_base::get_stack_size_reserve(uint32_t& size) const
-{
- size = get_stack_size_reserve_32();
-}
-
-//Returns stack size reserve for PE32/PE64
-void pe_base::get_stack_size_reserve(uint64_t& size) const
-{
- size = get_stack_size_reserve_64();
-}
-
-//Realigns file (changes file alignment)
-void pe_base::realign_file(uint32_t new_file_alignment)
-{
- //Checks alignment for correctness
- set_file_alignment(new_file_alignment);
- realign_all_sections();
-}
-
-//Helper function to recalculate RAW and virtual section sizes and strip it, if necessary
-void pe_base::recalculate_section_sizes(section& s, bool auto_strip)
-{
- prepare_section(s); //Recalculate section raw addresses
-
- //Strip RAW size of section, if it is the last one
- //For all others it must be file-aligned and calculated by prepare_section() call
- if(auto_strip && !(sections_.empty() || &s == &*(sections_.end() - 1)))
- {
- //Strip ending raw data nullbytes to optimize size
- std::string& raw_data = s.get_raw_data();
- if(!raw_data.empty())
- {
- std::string::size_type i = raw_data.length();
- for(; i != 1; --i)
- {
- if(raw_data[i - 1] != 0)
- break;
- }
-
- raw_data.resize(i);
- }
-
- s.set_size_of_raw_data(static_cast<uint32_t>(raw_data.length()));
- }
-
- //Can occur only for last section
- if(pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) < pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()))
- set_section_virtual_size(s, pe_utils::align_up(s.get_size_of_raw_data(), get_section_alignment())); //Recalculate section virtual size
-}
-
-//Returns data from the beginning of image
-//Size = SizeOfHeaders
-const std::string& pe_base::get_full_headers_data() const
-{
- return full_headers_data_;
-}
-
-const pe_base::debug_data_list& pe_base::get_raw_debug_data_list() const
-{
- return debug_data_;
-}
-
-//Sets number of sections
-void pe_base::set_number_of_sections(uint16_t number)
-{
- props_->set_number_of_sections(number);
-}
-
-//Sets size of image
-void pe_base::set_size_of_image(uint32_t size)
-{
- props_->set_size_of_image(size);
-}
-
-//Sets size of headers
-void pe_base::set_size_of_headers(uint32_t size)
-{
- props_->set_size_of_headers(size);
-}
-
-//Sets size of optional headers
-void pe_base::set_size_of_optional_header(uint16_t size)
-{
- props_->set_size_of_optional_header(size);
-}
-
-//Returns nt headers data pointer
-char* pe_base::get_nt_headers_ptr()
-{
- return props_->get_nt_headers_ptr();
-}
-
-//Returns nt headers data pointer
-const char* pe_base::get_nt_headers_ptr() const
-{
- return props_->get_nt_headers_ptr();
-}
-
-//Returns sizeof() nt headers
-uint32_t pe_base::get_sizeof_nt_header() const
-{
- return props_->get_sizeof_nt_header();
-}
-
-//Returns sizeof() optional headers
-uint32_t pe_base::get_sizeof_opt_headers() const
-{
- return props_->get_sizeof_opt_headers();
-}
-
-//Sets file alignment (no checks)
-void pe_base::set_file_alignment_unchecked(uint32_t alignment)
-{
- props_->set_file_alignment_unchecked(alignment);
-}
-
-//Sets base of code
-void pe_base::set_base_of_code(uint32_t base)
-{
- props_->set_base_of_code(base);
-}
-
-//Returns base of code
-uint32_t pe_base::get_base_of_code() const
-{
- return props_->get_base_of_code();
-}
-
-//Returns needed magic of image
-uint32_t pe_base::get_needed_magic() const
-{
- return props_->get_needed_magic();
-}
-}
diff --git a/tools/pe_bliss/pe_base.h b/tools/pe_bliss/pe_base.h
deleted file mode 100644
index b5416cf1e2..0000000000
--- a/tools/pe_bliss/pe_base.h
+++ /dev/null
@@ -1,544 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <map>
-#include "pe_exception.h"
-#include "pe_structures.h"
-#include "utils.h"
-#include "pe_section.h"
-#include "pe_properties.h"
-
-//Please don't remove this information from header
-//PEBliss 1.0.0
-//(c) DX 2011 - 2012, http://kaimi.ru
-//Free to use for commertial and non-commertial purposes, modification and distribution
-
-// == more important ==
-//TODO: compact import rebuilder
-//TODO: remove sections in the middle
-//== less important ==
-//TODO: relocations that take more than one element (seems to be not possible in Windows PE, but anyway)
-//TODO: delay import directory
-//TODO: write message tables
-//TODO: write string tables
-//TODO: read security information
-//TODO: read full .NET information
-
-namespace pe_bliss
-{
-//Portable executable class
-class pe_base
-{
-public: //CONSTRUCTORS
- //Constructor from stream
- pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data = true);
-
- //Constructor of empty PE-file
- explicit pe_base(const pe_properties& props, uint32_t section_alignment = 0x1000, bool dll = false, uint16_t subsystem = pe_win::image_subsystem_windows_gui);
-
- pe_base(const pe_base& pe);
- pe_base& operator=(const pe_base& pe);
-
-public:
- ~pe_base();
-
-public: //STUB
- //Strips stub MSVS overlay, if any
- void strip_stub_overlay();
- //Fills stub MSVS overlay with specified byte
- void fill_stub_overlay(char c);
- //Sets stub MSVS overlay
- void set_stub_overlay(const std::string& data);
- //Returns stub overlay contents
- const std::string& get_stub_overlay() const;
-
-
-public: //DIRECTORIES
- //Returns true if directory exists
- bool directory_exists(uint32_t id) const;
- //Removes directory
- void remove_directory(uint32_t id);
-
- //Returns directory RVA
- uint32_t get_directory_rva(uint32_t id) const;
- //Returns directory size
- uint32_t get_directory_size(uint32_t id) const;
-
- //Sets directory RVA (just a value of PE header, no moving occurs)
- void set_directory_rva(uint32_t id, uint32_t rva);
- //Sets directory size (just a value of PE header, no moving occurs)
- void set_directory_size(uint32_t id, uint32_t size);
-
- //Strips only zero DATA_DIRECTORY entries to count = min_count
- //Returns resulting number of data directories
- //strip_iat_directory - if true, even not empty IAT directory will be stripped
- uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
-
- //Returns true if image has import directory
- bool has_imports() const;
- //Returns true if image has export directory
- bool has_exports() const;
- //Returns true if image has resource directory
- bool has_resources() const;
- //Returns true if image has security directory
- bool has_security() const;
- //Returns true if image has relocations
- bool has_reloc() const;
- //Returns true if image has TLS directory
- bool has_tls() const;
- //Returns true if image has config directory
- bool has_config() const;
- //Returns true if image has bound import directory
- bool has_bound_import() const;
- //Returns true if image has delay import directory
- bool has_delay_import() const;
- //Returns true if image has COM directory
- bool is_dotnet() const;
- //Returns true if image has exception directory
- bool has_exception_directory() const;
- //Returns true if image has debug directory
- bool has_debug() const;
-
- //Returns subsystem value
- uint16_t get_subsystem() const;
- //Sets subsystem value
- void set_subsystem(uint16_t subsystem);
- //Returns true if image has console subsystem
- bool is_console() const;
- //Returns true if image has Windows GUI subsystem
- bool is_gui() const;
-
- //Sets required operation system version
- void set_os_version(uint16_t major, uint16_t minor);
- //Returns required operation system version (minor word)
- uint16_t get_minor_os_version() const;
- //Returns required operation system version (major word)
- uint16_t get_major_os_version() const;
-
- //Sets required subsystem version
- void set_subsystem_version(uint16_t major, uint16_t minor);
- //Returns required subsystem version (minor word)
- uint16_t get_minor_subsystem_version() const;
- //Returns required subsystem version (major word)
- uint16_t get_major_subsystem_version() const;
-
-public: //PE HEADER
- //Returns DOS header
- const pe_win::image_dos_header& get_dos_header() const;
- pe_win::image_dos_header& get_dos_header();
-
- //Returns PE header start (e_lfanew)
- int32_t get_pe_header_start() const;
-
- //Returns file alignment
- uint32_t get_file_alignment() const;
- //Sets file alignment, checking the correctness of its value
- void set_file_alignment(uint32_t alignment);
-
- //Returns size of image
- uint32_t get_size_of_image() const;
-
- //Returns image entry point
- uint32_t get_ep() const;
- //Sets image entry point (just a value of PE header)
- void set_ep(uint32_t new_ep);
-
- //Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
- uint32_t get_number_of_rvas_and_sizes() const;
- //Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
- void set_number_of_rvas_and_sizes(uint32_t number);
-
- //Returns PE characteristics
- uint16_t get_characteristics() const;
- //Sets PE characteristics (a value inside header)
- void set_characteristics(uint16_t ch);
- //Clears PE characteristics flag
- void clear_characteristics_flags(uint16_t flags);
- //Sets PE characteristics flag
- void set_characteristics_flags(uint16_t flags);
- //Returns true if PE characteristics flag set
- bool check_characteristics_flag(uint16_t flag) const;
-
- //Returns DLL Characteristics
- uint16_t get_dll_characteristics() const;
- //Sets DLL Characteristics
- void set_dll_characteristics(uint16_t characteristics);
-
- //Returns size of headers
- uint32_t get_size_of_headers() const;
- //Returns size of optional header
- uint16_t get_size_of_optional_header() const;
-
- //Returns PE signature
- uint32_t get_pe_signature() const;
-
- //Returns magic value
- uint32_t get_magic() const;
-
- //Returns image base for PE32 and PE64 respectively
- uint32_t get_image_base_32() const;
- void get_image_base(uint32_t& base) const;
- //Sets image base for PE32 and PE64 respectively
- uint64_t get_image_base_64() const;
- void get_image_base(uint64_t& base) const;
-
- //Sets new image base
- void set_image_base(uint32_t base);
- void set_image_base_64(uint64_t base);
-
- //Sets heap size commit for PE32 and PE64 respectively
- void set_heap_size_commit(uint32_t size);
- void set_heap_size_commit(uint64_t size);
- //Sets heap size reserve for PE32 and PE64 respectively
- void set_heap_size_reserve(uint32_t size);
- void set_heap_size_reserve(uint64_t size);
- //Sets stack size commit for PE32 and PE64 respectively
- void set_stack_size_commit(uint32_t size);
- void set_stack_size_commit(uint64_t size);
- //Sets stack size reserve for PE32 and PE64 respectively
- void set_stack_size_reserve(uint32_t size);
- void set_stack_size_reserve(uint64_t size);
-
- //Returns heap size commit for PE32 and PE64 respectively
- uint32_t get_heap_size_commit_32() const;
- void get_heap_size_commit(uint32_t& size) const;
- uint64_t get_heap_size_commit_64() const;
- void get_heap_size_commit(uint64_t& size) const;
- //Returns heap size reserve for PE32 and PE64 respectively
- uint32_t get_heap_size_reserve_32() const;
- void get_heap_size_reserve(uint32_t& size) const;
- uint64_t get_heap_size_reserve_64() const;
- void get_heap_size_reserve(uint64_t& size) const;
- //Returns stack size commit for PE32 and PE64 respectively
- uint32_t get_stack_size_commit_32() const;
- void get_stack_size_commit(uint32_t& size) const;
- uint64_t get_stack_size_commit_64() const;
- void get_stack_size_commit(uint64_t& size) const;
- //Returns stack size reserve for PE32 and PE64 respectively
- uint32_t get_stack_size_reserve_32() const;
- void get_stack_size_reserve(uint32_t& size) const;
- uint64_t get_stack_size_reserve_64() const;
- void get_stack_size_reserve(uint64_t& size) const;
-
- //Updates virtual size of image corresponding to section virtual sizes
- void update_image_size();
-
- //Returns checksum of PE file from header
- uint32_t get_checksum() const;
- //Sets checksum of PE file
- void set_checksum(uint32_t checksum);
-
- //Returns timestamp of PE file from header
- uint32_t get_time_date_stamp() const;
- //Sets timestamp of PE file
- void set_time_date_stamp(uint32_t timestamp);
-
- //Returns Machine field value of PE file from header
- uint16_t get_machine() const;
- //Sets Machine field value of PE file
- void set_machine(uint16_t machine);
-
- //Returns data from the beginning of image
- //Size = SizeOfHeaders
- const std::string& get_full_headers_data() const;
-
- typedef std::multimap<uint32_t, std::string> debug_data_list;
- //Returns raw list of debug data
- const debug_data_list& get_raw_debug_data_list() const;
-
- //Reads and checks DOS header
- static void read_dos_header(std::istream& file, pe_win::image_dos_header& header);
-
- //Returns sizeof() nt headers
- uint32_t get_sizeof_nt_header() const;
- //Returns sizeof() optional headers
- uint32_t get_sizeof_opt_headers() const;
- //Returns raw nt headers data pointer
- const char* get_nt_headers_ptr() const;
-
- //Sets size of headers (to NT headers)
- void set_size_of_headers(uint32_t size);
- //Sets size of optional headers (to NT headers)
- void set_size_of_optional_header(uint16_t size);
-
- //Sets base of code
- void set_base_of_code(uint32_t base);
- //Returns base of code
- uint32_t get_base_of_code() const;
-
-public: //ADDRESS CONVERTIONS
- //Virtual Address (VA) to Relative Virtual Address (RVA) convertions
- //for PE32 and PE64 respectively
- //bound_check checks integer overflow
- uint32_t va_to_rva(uint32_t va, bool bound_check = true) const;
- uint32_t va_to_rva(uint64_t va, bool bound_check = true) const;
-
- //Relative Virtual Address (RVA) to Virtual Address (VA) convertions
- //for PE32 and PE64 respectively
- uint32_t rva_to_va_32(uint32_t rva) const;
- void rva_to_va(uint32_t rva, uint32_t& va) const;
- uint64_t rva_to_va_64(uint32_t rva) const;
- void rva_to_va(uint32_t rva, uint64_t& va) const;
-
- //RVA to RAW file offset convertion (4gb max)
- uint32_t rva_to_file_offset(uint32_t rva) const;
- //RAW file offset to RVA convertion (4gb max)
- uint32_t file_offset_to_rva(uint32_t offset) const;
-
- //RVA from section raw data offset
- static uint32_t rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start);
-
-public: //IMAGE SECTIONS
- //Returns number of sections from PE header
- uint16_t get_number_of_sections() const;
-
- //Updates number of sections in PE header
- uint16_t update_number_of_sections();
-
- //Returns section alignment
- uint32_t get_section_alignment() const;
-
- //Returns section list
- section_list& get_image_sections();
- const section_list& get_image_sections() const;
-
- //Realigns all sections, if you made any changes to sections or alignments
- void realign_all_sections();
- //Resligns section with specified index
- void realign_section(uint32_t index);
-
- //Returns section from RVA inside it
- section& section_from_rva(uint32_t rva);
- const section& section_from_rva(uint32_t rva) const;
- //Returns section from directory ID
- section& section_from_directory(uint32_t directory_id);
- const section& section_from_directory(uint32_t directory_id) const;
- //Returns section from VA inside it for PE32 and PE64 respectively
- section& section_from_va(uint32_t va);
- const section& section_from_va(uint32_t va) const;
- section& section_from_va(uint64_t va);
- const section& section_from_va(uint64_t va) const;
- //Returns section from file offset (4gb max)
- section& section_from_file_offset(uint32_t offset);
- const section& section_from_file_offset(uint32_t offset) const;
-
- //Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- //Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32 and PE64 respectively
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- uint32_t section_data_length_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
- //Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
- uint32_t section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype = section_data_raw) const;
- //Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 and PE64 respectively (checks bounds)
- uint32_t section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype = section_data_raw) const;
- uint32_t section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype = section_data_raw) const;
-
- //Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- //Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32 and PE64 respectively
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- uint32_t section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- uint32_t section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- //Returns corresponding section data pointer from RVA inside section
- char* section_data_from_rva(uint32_t rva, bool include_headers = false);
- const char* section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- //Returns corresponding section data pointer from VA inside section for PE32 and PE64 respectively
- char* section_data_from_va(uint32_t va, bool include_headers = false);
- const char* section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
- char* section_data_from_va(uint64_t va, bool include_headers = false);
- const char* section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
- //Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
- char* section_data_from_rva(section& s, uint32_t rva);
- const char* section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const;
- //Returns corresponding section data pointer from VA inside section "s" for PE32 and PE64 respectively (checks bounds)
- char* section_data_from_va(section& s, uint32_t va); //Always returns raw data
- const char* section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const;
- char* section_data_from_va(section& s, uint64_t va); //Always returns raw data
- const char* section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const;
-
- //Returns corresponding section data pointer from RVA inside section "s" (checks bounds, checks sizes, the most safe function)
- template<typename T>
- T section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const
- {
- if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) && pe_utils::is_sum_safe(rva, sizeof(T)))
- {
- const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment());
- //Don't check for underflow here, comparsion is unsigned
- if(data.size() < rva - s.get_virtual_address() + sizeof(T))
- throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists);
-
- return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address());
- }
-
- throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
- }
-
- //Returns corresponding section data pointer from RVA inside section (checks rva, checks sizes, the most safe function)
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- template<typename T>
- T section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const
- {
- //if RVA is inside of headers and we're searching them too...
- if(include_headers && pe_utils::is_sum_safe(rva, sizeof(T)) && (rva + sizeof(T) < full_headers_data_.length()))
- return *reinterpret_cast<const T*>(&full_headers_data_[rva]);
-
- const section& s = section_from_rva(rva);
- const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment());
- //Don't check for underflow here, comparsion is unsigned
- if(data.size() < rva - s.get_virtual_address() + sizeof(T))
- throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists);
-
- return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address());
- }
-
- //Returns corresponding section data pointer from VA inside section "s" (checks bounds, checks sizes, the most safe function)
- template<typename T>
- T section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const
- {
- return section_data_from_rva<T>(s, va_to_rva(va), datatype);
- }
-
- template<typename T>
- T section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const
- {
- return section_data_from_rva<T>(s, va_to_rva(va), datatype);
- }
-
- //Returns corresponding section data pointer from VA inside section (checks rva, checks sizes, the most safe function)
- //If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
- template<typename T>
- T section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const
- {
- return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers);
- }
-
- template<typename T>
- T section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const
- {
- return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers);
- }
-
- //Returns section and offset (raw data only) from its start from RVA
- const std::pair<uint32_t, const section*> section_and_offset_from_rva(uint32_t rva) const;
-
- //Sets virtual size of section "s"
- //Section must be free (not bound to any image)
- //or the last section of this image
- //Function calls update_image_size automatically in second case
- void set_section_virtual_size(section& s, uint32_t vsize);
-
- //Represents section expand type for expand_section function
- enum section_expand_type
- {
- expand_section_raw, //Section raw data size will be expanded
- expand_section_virtual //Section virtual data size will be expanded
- };
-
- //Expands section raw or virtual size to hold data from specified RVA with specified size
- //Section must be free (not bound to any image)
- //or the last section of this image
- //Returns true if section was expanded
- bool expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand);
-
- //Adds section to image
- //Returns last section
- section& add_section(section s);
- //Prepares section to later add it to image (checks and recalculates virtual and raw section size)
- //Section must be prepared by this function before calling add_section
- void prepare_section(section& s);
-
- //Returns true if sectios "s" is already attached to this PE file
- bool section_attached(const section& s) const;
-
-
-public: //IMAGE
- //Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks)
- static pe_type get_pe_type(std::istream& file);
- //Returns PE type of this image
- pe_type get_pe_type() const;
-
- //Returns true if image has overlay data at the end of file
- bool has_overlay() const;
-
- //Realigns file (changes file alignment)
- void realign_file(uint32_t new_file_alignment);
-
- //Helper function to recalculate RAW and virtual section sizes and strip it, if necessary
- //auto_strip = strip section, if necessary
- void recalculate_section_sizes(section& s, bool auto_strip);
-
- // ========== END OF PUBLIC MEMBERS AND STRUCTURES ========== //
-private:
- //Image DOS header
- pe_win::image_dos_header dos_header_;
- //Rich (stub) overlay data (for MSVS)
- std::string rich_overlay_;
- //List of image sections
- section_list sections_;
- //True if image has overlay
- bool has_overlay_;
- //Raw SizeOfHeaders-sized data from the beginning of image
- std::string full_headers_data_;
- //Raw debug data for all directories
- //PointerToRawData; Data
- debug_data_list debug_data_;
- //PE or PE+ related properties
- pe_properties* props_;
-
- //Reads and checks DOS header
- void read_dos_header(std::istream& file);
-
- //Reads and checks PE headers and section headers, data
- void read_pe(std::istream& file, bool read_debug_raw_data);
-
- //Sets number of sections
- void set_number_of_sections(uint16_t number);
- //Sets size of image
- void set_size_of_image(uint32_t size);
- //Sets file alignment (no checks)
- void set_file_alignment_unchecked(uint32_t alignment);
- //Returns needed magic of image
- uint32_t get_needed_magic() const;
- //Returns nt headers data pointer
- char* get_nt_headers_ptr();
-
-private:
- static const uint16_t maximum_number_of_sections = 0x60;
- static const uint32_t minimum_file_alignment = 512;
-
-private:
- //RAW file offset to section convertion helpers (4gb max)
- section_list::const_iterator file_offset_to_section(uint32_t offset) const;
- section_list::iterator file_offset_to_section(uint32_t offset);
-};
-}
diff --git a/tools/pe_bliss/pe_bliss.h b/tools/pe_bliss/pe_bliss.h
deleted file mode 100644
index 1a8b430284..0000000000
--- a/tools/pe_bliss/pe_bliss.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "pe_base.h"
-#include "pe_rebuilder.h"
-#include "pe_factory.h"
-#include "pe_bound_import.h"
-#include "pe_debug.h"
-#include "pe_dotnet.h"
-#include "pe_exception_directory.h"
-#include "pe_exports.h"
-#include "pe_imports.h"
-#include "pe_load_config.h"
-#include "pe_relocations.h"
-#include "pe_resources.h"
-#include "pe_rich_data.h"
-#include "pe_tls.h"
-#include "pe_properties_generic.h"
-#include "pe_checksum.h"
-#include "entropy.h"
diff --git a/tools/pe_bliss/pe_bliss_godot.cpp b/tools/pe_bliss/pe_bliss_godot.cpp
deleted file mode 100644
index 8297aa1045..0000000000
--- a/tools/pe_bliss/pe_bliss_godot.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-#include "pe_bliss/pe_bliss.h"
-#include "pe_bliss/pe_bliss_resources.h"
-#include "core/ustring.h"
-#include "core/dvector.h"
-#include "os/file_access.h"
-
-using namespace pe_bliss;
-
-String pe_bliss_add_resrc(const char* p_path, int version_major, int version_minor,
- String& company_name, String& file_description,
- String& legal_copyright, String& version_text,
- String& product_name, String& godot_version,
- DVector<uint8_t>& icon_content) {
- try
- {
- pe_base image(pe_factory::create_pe(p_path));
-
- const section_list& pe_sections = image.get_image_sections();
- uint32_t end_of_pe = 0;
- FileAccess *dst;
- DVector<uint8_t> overlay_data;
- if(image.has_overlay())
- {
- end_of_pe = pe_sections.back().get_pointer_to_raw_data() + pe_sections.back().get_size_of_raw_data();
- dst=FileAccess::open(p_path,FileAccess::READ);
- if (dst) {
- overlay_data.resize(dst->get_len()-end_of_pe);
- dst->seek(end_of_pe);
- DVector<uint8_t>::Write overlay_data_write = overlay_data.write();
- dst->get_buffer(overlay_data_write.ptr(),overlay_data.size());
- dst->close();
- memdelete(dst);
- }
- }
- resource_directory root;
- if(image.has_resources())
- {
- root = resource_directory(get_resources(image));
- }
- pe_resource_manager res(root);
- if(image.has_resources())
- {
- if(icon_content.size()) {
- if(res.resource_exists(pe_resource_viewer::resource_icon))
- {
- res.remove_resource_type(pe_resource_viewer::resource_icon);
- }
- if(res.resource_exists(pe_resource_viewer::resource_icon_group))
- {
- res.remove_resource_type(pe_resource_viewer::resource_icon_group);
- }
- }
- if(res.resource_exists(pe_resource_viewer::resource_version))
- {
- res.remove_resource_type(pe_resource_viewer::resource_version);
- }
- }
- file_version_info file_info;
- file_info.set_file_os(file_version_info::file_os_nt_win32);
- file_info.set_file_type(file_version_info::file_type_application);
- unsigned int ver = version_major << 16;
- ver = ver + version_minor;
- file_info.set_file_version_ms(ver);
- file_info.set_file_version_ls(0x00000000);
- file_info.set_product_version_ms(ver);
- file_info.set_product_version_ls(0x00000000);
- lang_string_values_map strings;
- translation_values_map translations;
- version_info_editor version(strings, translations);
- version.add_translation(version_info_editor::default_language_translation);
- version.set_company_name(company_name.c_str());
- version.set_file_description(file_description.c_str());
- if (!product_name.empty()) {
- version.set_internal_name((product_name+String(".exe")).c_str());
- version.set_original_filename((product_name+String(".exe")).c_str());
- version.set_product_name(product_name.c_str());
- }
- version.set_legal_copyright(legal_copyright.c_str());
- version.set_product_version(version_text.c_str());
- if(!godot_version.empty()) version.set_property(L"Godot Engine Version", godot_version.c_str() );
- resource_version_info_writer(res).set_version_info(file_info, strings, translations, 1033, 1200);
- if(icon_content.size()) {
- std::string icon;
- icon.resize(icon_content.size());
- for(int i=0; i<icon_content.size(); i++)
- {
- icon[i] = icon_content[i];
- }
- resource_cursor_icon_writer(res).add_icon(icon, L"MAIN_ICON", 1033);
- }
- if(image.has_resources())
- {
- rebuild_resources(image, root, image.section_from_directory(pe_win::image_directory_entry_resource));
- } else {
- section new_resources;
- new_resources.get_raw_data().resize(1);
- new_resources.set_name(".rsrc");
- new_resources.readable(true);
- section& attached_section = image.add_section(new_resources);
- rebuild_resources(image, root, attached_section);
- }
- rebuild_pe(image, p_path);
- if(image.has_overlay() && end_of_pe) {
- dst=FileAccess::open(p_path,FileAccess::READ_WRITE);
- if (dst) {
- dst->seek_end();
- DVector<uint8_t>::Read overlay_data_read = overlay_data.read();
- dst->store_buffer(overlay_data_read.ptr(),overlay_data.size());
- dst->close();
- memdelete(dst);
- }
- }
- return String();
- } catch(const pe_exception& e) {
- String ret("Error In Add rsrc Section : ");
- return ret + String(e.what());
- }
-}
diff --git a/tools/pe_bliss/pe_bliss_godot.h b/tools/pe_bliss/pe_bliss_godot.h
deleted file mode 100644
index 0365ca9eaf..0000000000
--- a/tools/pe_bliss/pe_bliss_godot.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-String pe_bliss_add_resrc(const char* p_path, int version_major, int version_minor,
- String& company_name, String& file_description,
- String& legal_copyright, String& version_text,
- String& product_name, String& godot_version,
- DVector<uint8_t>& icon_content);
diff --git a/tools/pe_bliss/pe_bliss_resources.h b/tools/pe_bliss/pe_bliss_resources.h
deleted file mode 100644
index 60369f8011..0000000000
--- a/tools/pe_bliss/pe_bliss_resources.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "file_version_info.h"
-#include "message_table.h"
-#include "pe_resource_manager.h"
-#include "pe_resource_viewer.h"
-#include "version_info_editor.h"
-#include "version_info_viewer.h"
-#include "resource_bitmap_reader.h"
-#include "resource_bitmap_writer.h"
-#include "resource_cursor_icon_reader.h"
-#include "resource_cursor_icon_writer.h"
-#include "resource_version_info_reader.h"
-#include "resource_version_info_writer.h"
-#include "resource_string_table_reader.h"
-#include "resource_message_list_reader.h"
diff --git a/tools/pe_bliss/pe_bound_import.cpp b/tools/pe_bliss/pe_bound_import.cpp
deleted file mode 100644
index 4b54b36105..0000000000
--- a/tools/pe_bliss/pe_bound_import.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_bound_import.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//BOUND IMPORT
-//Default constructor
-bound_import_ref::bound_import_ref()
- :timestamp_(0)
-{}
-
-//Constructor from data
-bound_import_ref::bound_import_ref(const std::string& module_name, uint32_t timestamp)
- :module_name_(module_name), timestamp_(timestamp)
-{}
-
-//Returns imported module name
-const std::string& bound_import_ref::get_module_name() const
-{
- return module_name_;
-}
-
-//Returns bound import date and time stamp
-uint32_t bound_import_ref::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Sets module name
-void bound_import_ref::set_module_name(const std::string& module_name)
-{
- module_name_ = module_name;
-}
-
-//Sets timestamp
-void bound_import_ref::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Default constructor
-bound_import::bound_import()
- :timestamp_(0)
-{}
-
-//Constructor from data
-bound_import::bound_import(const std::string& module_name, uint32_t timestamp)
- :module_name_(module_name), timestamp_(timestamp)
-{}
-
-//Returns imported module name
-const std::string& bound_import::get_module_name() const
-{
- return module_name_;
-}
-
-//Returns bound import date and time stamp
-uint32_t bound_import::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Returns bound references cound
-size_t bound_import::get_module_ref_count() const
-{
- return refs_.size();
-}
-
-//Returns module references
-const bound_import::ref_list& bound_import::get_module_ref_list() const
-{
- return refs_;
-}
-
-//Adds module reference
-void bound_import::add_module_ref(const bound_import_ref& ref)
-{
- refs_.push_back(ref);
-}
-
-//Clears module references list
-void bound_import::clear_module_refs()
-{
- refs_.clear();
-}
-
-//Returns module references
-bound_import::ref_list& bound_import::get_module_ref_list()
-{
- return refs_;
-}
-
-//Sets module name
-void bound_import::set_module_name(const std::string& module_name)
-{
- module_name_ = module_name;
-}
-
-//Sets timestamp
-void bound_import::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-const bound_import_module_list get_bound_import_module_list(const pe_base& pe)
-{
- //Returned bound import modules list
- bound_import_module_list ret;
-
- //If image has no bound imports
- if(!pe.has_bound_import())
- return ret;
-
- uint32_t bound_import_data_len =
- pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true);
-
- if(bound_import_data_len < pe.get_directory_size(image_directory_entry_bound_import))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- const char* bound_import_data = pe.section_data_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true);
-
- //Check read in "read_pe" function raw bound import data size
- if(bound_import_data_len < sizeof(image_bound_import_descriptor))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //current bound_import_data_ in-string position
- unsigned long current_pos = 0;
- //first bound import descriptor
- //so, we're working with raw data here, no section helpers available
- const image_bound_import_descriptor* descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]);
-
- //Enumerate until zero
- while(descriptor->OffsetModuleName)
- {
- //Check module name offset
- if(descriptor->OffsetModuleName >= bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Check module name for null-termination
- if(!pe_utils::is_null_terminated(&bound_import_data[descriptor->OffsetModuleName], bound_import_data_len - descriptor->OffsetModuleName))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Create bound import descriptor structure
- bound_import elem(&bound_import_data[descriptor->OffsetModuleName], descriptor->TimeDateStamp);
-
- //Check DWORDs
- if(descriptor->NumberOfModuleForwarderRefs >= pe_utils::max_dword / sizeof(image_bound_forwarder_ref)
- || !pe_utils::is_sum_safe(current_pos, 2 /* this descriptor and the next one */ * sizeof(image_bound_import_descriptor) + descriptor->NumberOfModuleForwarderRefs * sizeof(image_bound_forwarder_ref)))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Move after current descriptor
- current_pos += sizeof(image_bound_import_descriptor);
-
- //Enumerate referenced bound import descriptors
- for(unsigned long i = 0; i != descriptor->NumberOfModuleForwarderRefs; ++i)
- {
- //They're just after parent descriptor
- //Check size of structure
- if(current_pos + sizeof(image_bound_forwarder_ref) > bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Get IMAGE_BOUND_FORWARDER_REF pointer
- const image_bound_forwarder_ref* ref_descriptor = reinterpret_cast<const image_bound_forwarder_ref*>(&bound_import_data[current_pos]);
-
- //Check referenced module name
- if(ref_descriptor->OffsetModuleName >= bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //And its null-termination
- if(!pe_utils::is_null_terminated(&bound_import_data[ref_descriptor->OffsetModuleName], bound_import_data_len - ref_descriptor->OffsetModuleName))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Add referenced module to current bound import structure
- elem.add_module_ref(bound_import_ref(&bound_import_data[ref_descriptor->OffsetModuleName], ref_descriptor->TimeDateStamp));
-
- //Move after referenced bound import descriptor
- current_pos += sizeof(image_bound_forwarder_ref);
- }
-
- //Check structure size
- if(current_pos + sizeof(image_bound_import_descriptor) > bound_import_data_len)
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
- //Move to next bound import descriptor
- descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]);
-
- //Save created descriptor structure and references
- ret.push_back(elem);
- }
-
- //Return result
- return ret;
-}
-
-//imports - bound imported modules list
-//imports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from imports_section raw data start
-//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
-//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
-const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that exports_section is attached to this PE image
- if(!pe.section_attached(imports_section))
- throw pe_exception("Bound import section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
- uint32_t needed_size = sizeof(image_bound_import_descriptor) /* Ending null descriptor */;
- uint32_t needed_size_for_strings = 0;
-
- //Calculate needed size for bound import data
- for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- const bound_import& import = *it;
- needed_size += sizeof(image_bound_import_descriptor);
- needed_size_for_strings += static_cast<uint32_t>((*it).get_module_name().length()) + 1 /* nullbyte */;
-
- const bound_import::ref_list& refs = import.get_module_ref_list();
- for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
- {
- needed_size_for_strings += static_cast<uint32_t>((*ref_it).get_module_name().length()) + 1 /* nullbyte */;
- needed_size += sizeof(image_bound_forwarder_ref);
- }
- }
-
- needed_size += needed_size_for_strings;
-
- //Check if imports_section is last one. If it's not, check if there's enough place for bound import data
- if(&imports_section != &*(pe.get_image_sections().end() - 1) &&
- (imports_section.empty() || pe_utils::align_up(imports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
- throw pe_exception("Insufficient space for bound import directory", pe_exception::insufficient_space);
-
- std::string& raw_data = imports_section.get_raw_data();
-
- //This will be done only if imports_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + directory_pos)
- raw_data.resize(needed_size + directory_pos); //Expand section raw data
-
- uint32_t current_pos_for_structures = directory_pos;
- uint32_t current_pos_for_strings = current_pos_for_structures + needed_size - needed_size_for_strings;
-
- for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- const bound_import& import = *it;
- image_bound_import_descriptor descriptor;
- descriptor.NumberOfModuleForwarderRefs = static_cast<uint16_t>(import.get_module_ref_list().size());
- descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
- descriptor.TimeDateStamp = import.get_timestamp();
-
- memcpy(&raw_data[current_pos_for_structures], &descriptor, sizeof(descriptor));
- current_pos_for_structures += sizeof(descriptor);
-
- size_t length = import.get_module_name().length() + 1 /* nullbyte */;
- memcpy(&raw_data[current_pos_for_strings], import.get_module_name().c_str(), length);
- current_pos_for_strings += static_cast<uint32_t>(length);
-
- const bound_import::ref_list& refs = import.get_module_ref_list();
- for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
- {
- const bound_import_ref& ref = *ref_it;
- image_bound_forwarder_ref ref_descriptor = {0};
- ref_descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
- ref_descriptor.TimeDateStamp = ref.get_timestamp();
-
- memcpy(&raw_data[current_pos_for_structures], &ref_descriptor, sizeof(ref_descriptor));
- current_pos_for_structures += sizeof(ref_descriptor);
-
- length = ref.get_module_name().length() + 1 /* nullbyte */;
- memcpy(&raw_data[current_pos_for_strings], ref.get_module_name().c_str(), length);
- current_pos_for_strings += static_cast<uint32_t>(length);
- }
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(imports_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(imports_section, directory_pos), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_bound_import, ret.get_rva());
- pe.set_directory_size(image_directory_entry_bound_import, ret.get_size());
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_bound_import.h b/tools/pe_bliss/pe_bound_import.h
deleted file mode 100644
index 667e28792e..0000000000
--- a/tools/pe_bliss/pe_bound_import.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing bound import reference
-class bound_import_ref
-{
-public:
- //Default constructor
- bound_import_ref();
- //Constructor from data
- bound_import_ref(const std::string& module_name, uint32_t timestamp);
-
- //Returns imported module name
- const std::string& get_module_name() const;
- //Returns bound import date and time stamp
- uint32_t get_timestamp() const;
-
-public: //Setters
- //Sets module name
- void set_module_name(const std::string& module_name);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
-
-private:
- std::string module_name_; //Imported module name
- uint32_t timestamp_; //Bound import timestamp
-};
-
-//Class representing image bound import information
-class bound_import
-{
-public:
- typedef std::vector<bound_import_ref> ref_list;
-
-public:
- //Default constructor
- bound_import();
- //Constructor from data
- bound_import(const std::string& module_name, uint32_t timestamp);
-
- //Returns imported module name
- const std::string& get_module_name() const;
- //Returns bound import date and time stamp
- uint32_t get_timestamp() const;
-
- //Returns bound references cound
- size_t get_module_ref_count() const;
- //Returns module references
- const ref_list& get_module_ref_list() const;
-
-public: //Setters
- //Sets module name
- void set_module_name(const std::string& module_name);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
-
- //Adds module reference
- void add_module_ref(const bound_import_ref& ref);
- //Clears module references list
- void clear_module_refs();
- //Returns module references
- ref_list& get_module_ref_list();
-
-private:
- std::string module_name_; //Imported module name
- uint32_t timestamp_; //Bound import timestamp
- ref_list refs_; //Module references list
-};
-
-typedef std::vector<bound_import> bound_import_module_list;
-
-//Returns bound import information
-const bound_import_module_list get_bound_import_module_list(const pe_base& pe);//Export directory rebuilder
-
-//imports - bound imported modules list
-//imports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from imports_section raw data start
-//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
-//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
-const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_checksum.cpp b/tools/pe_bliss/pe_checksum.cpp
deleted file mode 100644
index 5971a33c90..0000000000
--- a/tools/pe_bliss/pe_checksum.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_checksum.h"
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Calculate checksum of image
-uint32_t calculate_checksum(std::istream& file)
-{
- //Save istream state
- std::ios_base::iostate state = file.exceptions();
- std::streamoff old_offset = file.tellg();
-
- //Checksum value
- unsigned long long checksum = 0;
-
- try
- {
- image_dos_header header;
-
- file.exceptions(std::ios::goodbit);
-
- //Read DOS header
- pe_base::read_dos_header(file, header);
-
- //Calculate PE checksum
- file.seekg(0);
- unsigned long long top = 0xFFFFFFFF;
- top++;
-
- //"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+
- static const unsigned long checksum_pos_in_optional_headers = 64;
- //Calculate real PE headers "CheckSum" field position
- //Sum is safe here
- unsigned long pe_checksum_pos = header.e_lfanew + sizeof(image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
-
- //Calculate checksum for each byte of file
- std::streamoff filesize = pe_utils::get_file_size(file);
- for(long long i = 0; i < filesize; i += 4)
- {
- unsigned long dw = 0;
-
- //Read DWORD from file
- file.read(reinterpret_cast<char*>(&dw), sizeof(unsigned long));
- //Skip "CheckSum" DWORD
- if(i == pe_checksum_pos)
- continue;
-
- //Calculate checksum
- checksum = (checksum & 0xffffffff) + dw + (checksum >> 32);
- if(checksum > top)
- checksum = (checksum & 0xffffffff) + (checksum >> 32);
- }
-
- //Finish checksum
- checksum = (checksum & 0xffff) + (checksum >> 16);
- checksum = (checksum) + (checksum >> 16);
- checksum = checksum & 0xffff;
-
- checksum += static_cast<unsigned long>(filesize);
- }
- catch(const std::exception&)
- {
- //If something went wrong, restore istream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
- //Rethrow
- throw;
- }
-
- //Restore istream state
- file.exceptions(state);
- file.seekg(old_offset);
- file.clear();
-
- //Return checksum
- return static_cast<uint32_t>(checksum);
-}
-}
diff --git a/tools/pe_bliss/pe_checksum.h b/tools/pe_bliss/pe_checksum.h
deleted file mode 100644
index a568d5d369..0000000000
--- a/tools/pe_bliss/pe_checksum.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Calculate checksum of image (performs no checks on PE structures)
-uint32_t calculate_checksum(std::istream& file);
-}
diff --git a/tools/pe_bliss/pe_debug.cpp b/tools/pe_bliss/pe_debug.cpp
deleted file mode 100644
index a0ed3f5af1..0000000000
--- a/tools/pe_bliss/pe_debug.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_debug.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-//DEBUG
-//Default constructor
-debug_info::debug_info()
- :characteristics_(0),
- time_stamp_(0),
- major_version_(0), minor_version_(0),
- type_(0),
- size_of_data_(0),
- address_of_raw_data_(0),
- pointer_to_raw_data_(0),
- advanced_info_type_(advanced_info_none)
-{}
-
-//Constructor from data
-debug_info::debug_info(const image_debug_directory& debug)
- :characteristics_(debug.Characteristics),
- time_stamp_(debug.TimeDateStamp),
- major_version_(debug.MajorVersion), minor_version_(debug.MinorVersion),
- type_(debug.Type),
- size_of_data_(debug.SizeOfData),
- address_of_raw_data_(debug.AddressOfRawData),
- pointer_to_raw_data_(debug.PointerToRawData),
- advanced_info_type_(advanced_info_none)
-{}
-
-//Returns debug characteristics
-uint32_t debug_info::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns debug datetimestamp
-uint32_t debug_info::get_time_stamp() const
-{
- return time_stamp_;
-}
-
-//Returns major version
-uint32_t debug_info::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version
-uint32_t debug_info::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns type of debug info (unchecked)
-uint32_t debug_info::get_type_raw() const
-{
- return type_;
-}
-
-//Returns type of debug info from debug_info_type enumeration
-debug_info::debug_info_type debug_info::get_type() const
-{
- //Determine debug type
- switch(type_)
- {
- case image_debug_type_coff:
- return debug_type_coff;
-
- case image_debug_type_codeview:
- return debug_type_codeview;
-
- case image_debug_type_fpo:
- return debug_type_fpo;
-
- case image_debug_type_misc:
- return debug_type_misc;
-
- case image_debug_type_exception:
- return debug_type_exception;
-
- case image_debug_type_fixup:
- return debug_type_fixup;
-
- case image_debug_type_omap_to_src:
- return debug_type_omap_to_src;
-
- case image_debug_type_omap_from_src:
- return debug_type_omap_from_src;
-
- case image_debug_type_borland:
- return debug_type_borland;
-
- case image_debug_type_clsid:
- return debug_type_clsid;
-
- case image_debug_type_reserved10:
- return debug_type_reserved10;
- }
-
- return debug_type_unknown;
-}
-
-//Returns size of debug data (internal, .pdb or other file doesn't count)
-uint32_t debug_info::get_size_of_data() const
-{
- return size_of_data_;
-}
-
-//Returns RVA of debug info when mapped to memory or zero, if info is not mapped
-uint32_t debug_info::get_rva_of_raw_data() const
-{
- return address_of_raw_data_;
-}
-
-//Returns raw file pointer to raw data
-uint32_t debug_info::get_pointer_to_raw_data() const
-{
- return pointer_to_raw_data_;
-}
-
-//Copy constructor
-debug_info::debug_info(const debug_info& info)
- :characteristics_(info.characteristics_),
- time_stamp_(info.time_stamp_),
- major_version_(info.major_version_), minor_version_(info.minor_version_),
- type_(info.type_),
- size_of_data_(info.size_of_data_),
- address_of_raw_data_(info.address_of_raw_data_),
- pointer_to_raw_data_(info.pointer_to_raw_data_),
- advanced_info_type_(info.advanced_info_type_)
-{
- copy_advanced_info(info);
-}
-
-//Copy assignment operator
-debug_info& debug_info::operator=(const debug_info& info)
-{
- copy_advanced_info(info);
-
- characteristics_ = info.characteristics_;
- time_stamp_ = info.time_stamp_;
- major_version_ = info.major_version_;
- minor_version_ = info.minor_version_;
- type_ = info.type_;
- size_of_data_ = info.size_of_data_;
- address_of_raw_data_ = info.address_of_raw_data_;
- pointer_to_raw_data_ = info.pointer_to_raw_data_;
- advanced_info_type_ = info.advanced_info_type_;
-
- return *this;
-}
-
-//Default constructor
-debug_info::advanced_info::advanced_info()
- :adv_pdb_7_0_info(0) //Zero pointer to advanced data
-{}
-
-//Returns true if advanced debug info is present
-bool debug_info::advanced_info::is_present() const
-{
- return adv_pdb_7_0_info != 0;
-}
-
-//Helper for advanced debug information copying
-void debug_info::copy_advanced_info(const debug_info& info)
-{
- free_present_advanced_info();
-
- switch(info.advanced_info_type_)
- {
- case advanced_info_pdb_7_0:
- advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(*info.advanced_debug_info_.adv_pdb_7_0_info);
- break;
- case advanced_info_pdb_2_0:
- advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(*info.advanced_debug_info_.adv_pdb_2_0_info);
- break;
- case advanced_info_misc:
- advanced_debug_info_.adv_misc_info = new misc_debug_info(*info.advanced_debug_info_.adv_misc_info);
- break;
- case advanced_info_coff:
- advanced_debug_info_.adv_coff_info = new coff_debug_info(*info.advanced_debug_info_.adv_coff_info);
- break;
- default:
- break;
- }
-
- advanced_info_type_ = info.advanced_info_type_;
-}
-
-//Helper for clearing any present advanced debug information
-void debug_info::free_present_advanced_info()
-{
- switch(advanced_info_type_)
- {
- case advanced_info_pdb_7_0:
- delete advanced_debug_info_.adv_pdb_7_0_info;
- break;
- case advanced_info_pdb_2_0:
- delete advanced_debug_info_.adv_pdb_2_0_info;
- break;
- case advanced_info_misc:
- delete advanced_debug_info_.adv_misc_info;
- break;
- case advanced_info_coff:
- delete advanced_debug_info_.adv_coff_info;
- break;
- default:
- break;
- }
-
- advanced_debug_info_.adv_pdb_7_0_info = 0;
- advanced_info_type_ = advanced_info_none;
-}
-
-//Destructor
-debug_info::~debug_info()
-{
- free_present_advanced_info();
-}
-
-//Sets advanced debug information
-void debug_info::set_advanced_debug_info(const pdb_7_0_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(info);
- advanced_info_type_ = advanced_info_pdb_7_0;
-}
-
-void debug_info::set_advanced_debug_info(const pdb_2_0_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(info);
- advanced_info_type_ = advanced_info_pdb_2_0;
-}
-
-void debug_info::set_advanced_debug_info(const misc_debug_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_misc_info = new misc_debug_info(info);
- advanced_info_type_ = advanced_info_misc;
-}
-
-void debug_info::set_advanced_debug_info(const coff_debug_info& info)
-{
- free_present_advanced_info();
- advanced_debug_info_.adv_coff_info = new coff_debug_info(info);
- advanced_info_type_ = advanced_info_coff;
-}
-
-//Returns advanced debug information type
-debug_info::advanced_info_type debug_info::get_advanced_info_type() const
-{
- return advanced_info_type_;
-}
-
-//Returns advanced debug information or throws an exception,
-//if requested information type is not contained by structure
-template<>
-const pdb_7_0_info debug_info::get_advanced_debug_info<pdb_7_0_info>() const
-{
- if(advanced_info_type_ != advanced_info_pdb_7_0)
- throw pe_exception("Debug info structure does not contain PDB 7.0 data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_pdb_7_0_info;
-}
-
-template<>
-const pdb_2_0_info debug_info::get_advanced_debug_info<pdb_2_0_info>() const
-{
- if(advanced_info_type_ != advanced_info_pdb_2_0)
- throw pe_exception("Debug info structure does not contain PDB 2.0 data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_pdb_2_0_info;
-}
-
-template<>
-const misc_debug_info debug_info::get_advanced_debug_info<misc_debug_info>() const
-{
- if(advanced_info_type_ != advanced_info_misc)
- throw pe_exception("Debug info structure does not contain MISC data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_misc_info;
-}
-
-template<>
-const coff_debug_info debug_info::get_advanced_debug_info<coff_debug_info>() const
-{
- if(advanced_info_type_ != advanced_info_coff)
- throw pe_exception("Debug info structure does not contain COFF data", pe_exception::advanced_debug_information_request_error);
-
- return *advanced_debug_info_.adv_coff_info;
-}
-
-//Sets advanced debug information type, if no advanced info structure available
-void debug_info::set_advanced_info_type(advanced_info_type type)
-{
- free_present_advanced_info();
- if(advanced_info_type_ >= advanced_info_codeview_4_0) //Don't set info type for those types, which have advanced info structures
- advanced_info_type_ = type;
-}
-
-//Default constructor
-pdb_7_0_info::pdb_7_0_info()
- :age_(0)
-{
- memset(&guid_, 0, sizeof(guid_));
-}
-
-//Constructor from data
-pdb_7_0_info::pdb_7_0_info(const CV_INFO_PDB70* info)
- :age_(info->Age), guid_(info->Signature),
- pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination
-{}
-
-//Returns debug PDB 7.0 structure GUID
-const guid pdb_7_0_info::get_guid() const
-{
- return guid_;
-}
-
-//Returns age of build
-uint32_t pdb_7_0_info::get_age() const
-{
- return age_;
-}
-
-//Returns PDB file name / path
-const std::string& pdb_7_0_info::get_pdb_file_name() const
-{
- return pdb_file_name_;
-}
-
-//Default constructor
-pdb_2_0_info::pdb_2_0_info()
- :age_(0), signature_(0)
-{}
-
-//Constructor from data
-pdb_2_0_info::pdb_2_0_info(const CV_INFO_PDB20* info)
- :age_(info->Age), signature_(info->Signature),
- pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination
-{}
-
-//Returns debug PDB 2.0 structure signature
-uint32_t pdb_2_0_info::get_signature() const
-{
- return signature_;
-}
-
-//Returns age of build
-uint32_t pdb_2_0_info::get_age() const
-{
- return age_;
-}
-
-//Returns PDB file name / path
-const std::string& pdb_2_0_info::get_pdb_file_name() const
-{
- return pdb_file_name_;
-}
-
-//Default constructor
-misc_debug_info::misc_debug_info()
- :data_type_(0), unicode_(false)
-{}
-
-//Constructor from data
-misc_debug_info::misc_debug_info(const image_debug_misc* info)
- :data_type_(info->DataType), unicode_(info->Unicode ? true : false)
-{
- //IMAGE_DEBUG_MISC::Data must be checked before!
- if(info->Unicode)
- {
-#ifdef PE_BLISS_WINDOWS
- debug_data_unicode_ = std::wstring(reinterpret_cast<const wchar_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2);
-#else
- debug_data_unicode_ = pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2));
-#endif
-
- pe_utils::strip_nullbytes(debug_data_unicode_); //Strip nullbytes in the end of string
- }
- else
- {
- debug_data_ansi_ = std::string(reinterpret_cast<const char*>(info->Data), info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */);
- pe_utils::strip_nullbytes(debug_data_ansi_); //Strip nullbytes in the end of string
- }
-}
-
-//Returns debug data type
-uint32_t misc_debug_info::get_data_type() const
-{
- return data_type_;
-}
-
-//Returns true if data type is exe name
-bool misc_debug_info::is_exe_name() const
-{
- return data_type_ == image_debug_misc_exename;
-}
-
-//Returns true if debug data is UNICODE
-bool misc_debug_info::is_unicode() const
-{
- return unicode_;
-}
-
-//Returns debug data (ANSI)
-const std::string& misc_debug_info::get_data_ansi() const
-{
- return debug_data_ansi_;
-}
-
-//Returns debug data (UNICODE)
-const std::wstring& misc_debug_info::get_data_unicode() const
-{
- return debug_data_unicode_;
-}
-
-//Default constructor
-coff_debug_info::coff_debug_info()
- :number_of_symbols_(0),
- lva_to_first_symbol_(0),
- number_of_line_numbers_(0),
- lva_to_first_line_number_(0),
- rva_to_first_byte_of_code_(0),
- rva_to_last_byte_of_code_(0),
- rva_to_first_byte_of_data_(0),
- rva_to_last_byte_of_data_(0)
-{}
-
-//Constructor from data
-coff_debug_info::coff_debug_info(const image_coff_symbols_header* info)
- :number_of_symbols_(info->NumberOfSymbols),
- lva_to_first_symbol_(info->LvaToFirstSymbol),
- number_of_line_numbers_(info->NumberOfLinenumbers),
- lva_to_first_line_number_(info->LvaToFirstLinenumber),
- rva_to_first_byte_of_code_(info->RvaToFirstByteOfCode),
- rva_to_last_byte_of_code_(info->RvaToLastByteOfCode),
- rva_to_first_byte_of_data_(info->RvaToFirstByteOfData),
- rva_to_last_byte_of_data_(info->RvaToLastByteOfData)
-{}
-
-//Returns number of symbols
-uint32_t coff_debug_info::get_number_of_symbols() const
-{
- return number_of_symbols_;
-}
-
-//Returns virtual address of the first symbol
-uint32_t coff_debug_info::get_lva_to_first_symbol() const
-{
- return lva_to_first_symbol_;
-}
-
-//Returns number of line-number entries
-uint32_t coff_debug_info::get_number_of_line_numbers() const
-{
- return number_of_line_numbers_;
-}
-
-//Returns virtual address of the first line-number entry
-uint32_t coff_debug_info::get_lva_to_first_line_number() const
-{
- return lva_to_first_line_number_;
-}
-
-//Returns relative virtual address of the first byte of code
-uint32_t coff_debug_info::get_rva_to_first_byte_of_code() const
-{
- return rva_to_first_byte_of_code_;
-}
-
-//Returns relative virtual address of the last byte of code
-uint32_t coff_debug_info::get_rva_to_last_byte_of_code() const
-{
- return rva_to_last_byte_of_code_;
-}
-
-//Returns relative virtual address of the first byte of data
-uint32_t coff_debug_info::get_rva_to_first_byte_of_data() const
-{
- return rva_to_first_byte_of_data_;
-}
-
-//Returns relative virtual address of the last byte of data
-uint32_t coff_debug_info::get_rva_to_last_byte_of_data() const
-{
- return rva_to_last_byte_of_data_;
-}
-
-//Returns COFF symbols list
-const coff_debug_info::coff_symbols_list& coff_debug_info::get_symbols() const
-{
- return symbols_;
-}
-
-//Adds COFF symbol
-void coff_debug_info::add_symbol(const coff_symbol& sym)
-{
- symbols_.push_back(sym);
-}
-
-//Default constructor
-coff_debug_info::coff_symbol::coff_symbol()
- :storage_class_(0),
- index_(0),
- section_number_(0), rva_(0),
- type_(0),
- is_filename_(false)
-{}
-
-//Returns storage class
-uint32_t coff_debug_info::coff_symbol::get_storage_class() const
-{
- return storage_class_;
-}
-
-//Returns symbol index
-uint32_t coff_debug_info::coff_symbol::get_index() const
-{
- return index_;
-}
-
-//Returns section number
-uint32_t coff_debug_info::coff_symbol::get_section_number() const
-{
- return section_number_;
-}
-
-//Returns RVA
-uint32_t coff_debug_info::coff_symbol::get_rva() const
-{
- return rva_;
-}
-
-//Returns true if structure contains file name
-bool coff_debug_info::coff_symbol::is_file() const
-{
- return is_filename_;
-}
-
-//Returns text data (symbol or file name)
-const std::string& coff_debug_info::coff_symbol::get_symbol() const
-{
- return name_;
-}
-
-//Sets storage class
-void coff_debug_info::coff_symbol::set_storage_class(uint32_t storage_class)
-{
- storage_class_ = storage_class;
-}
-
-//Sets symbol index
-void coff_debug_info::coff_symbol::set_index(uint32_t index)
-{
- index_ = index;
-}
-
-//Sets section number
-void coff_debug_info::coff_symbol::set_section_number(uint32_t section_number)
-{
- section_number_ = section_number;
-}
-
-//Sets RVA
-void coff_debug_info::coff_symbol::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Sets file name
-void coff_debug_info::coff_symbol::set_file_name(const std::string& file_name)
-{
- name_ = file_name;
- is_filename_ = true;
-}
-
-//Sets symbol name
-void coff_debug_info::coff_symbol::set_symbol_name(const std::string& symbol_name)
-{
- name_ = symbol_name;
- is_filename_ = false;
-}
-
-//Returns type
-uint16_t coff_debug_info::coff_symbol::get_type() const
-{
- return type_;
-}
-
-//Sets type
-void coff_debug_info::coff_symbol::set_type(uint16_t type)
-{
- type_ = type;
-}
-
-//Returns debug information list
-const debug_info_list get_debug_information(const pe_base& pe)
-{
- debug_info_list ret;
-
- //If there's no debug directory, return empty list
- if(!pe.has_debug())
- return ret;
-
- //Check the length in bytes of the section containing debug directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_rva(image_directory_entry_debug), section_data_virtual, true)
- < sizeof(image_debug_directory))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- unsigned long current_pos = pe.get_directory_rva(image_directory_entry_debug);
-
- //First IMAGE_DEBUG_DIRECTORY table
- image_debug_directory directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-
- if(!pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_size(image_directory_entry_debug)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Iterate over all IMAGE_DEBUG_DIRECTORY directories
- while(directory.PointerToRawData
- && current_pos < pe.get_directory_rva(image_directory_entry_debug) + pe.get_directory_size(image_directory_entry_debug))
- {
- //Create debug information structure
- debug_info info(directory);
-
- //Find raw debug data
- const pe_base::debug_data_list& debug_datas = pe.get_raw_debug_data_list();
- pe_base::debug_data_list::const_iterator it = debug_datas.find(directory.PointerToRawData);
- if(it != debug_datas.end()) //If it exists, we'll do some detailed debug info research
- {
- const std::string& debug_data = (*it).second;
- switch(directory.Type)
- {
- case image_debug_type_coff:
- {
- //Check data length
- if(debug_data.length() < sizeof(image_coff_symbols_header))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Get coff header structure pointer
- const image_coff_symbols_header* coff = reinterpret_cast<const image_coff_symbols_header*>(debug_data.data());
-
- //Check possible overflows
- if(coff->NumberOfSymbols >= pe_utils::max_dword / sizeof(image_symbol)
- || !pe_utils::is_sum_safe(coff->NumberOfSymbols * sizeof(image_symbol), coff->LvaToFirstSymbol))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Check data length again
- if(debug_data.length() < coff->NumberOfSymbols * sizeof(image_symbol) + coff->LvaToFirstSymbol)
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Create COFF debug info structure
- coff_debug_info coff_info(coff);
-
- //Enumerate debug symbols data
- for(uint32_t i = 0; i < coff->NumberOfSymbols; ++i)
- {
- //Safe sum (checked above)
- const image_symbol* sym = reinterpret_cast<const image_symbol*>(debug_data.data() + i * sizeof(image_symbol) + coff->LvaToFirstSymbol);
-
- coff_debug_info::coff_symbol symbol;
- symbol.set_index(i); //Save symbol index
- symbol.set_storage_class(sym->StorageClass); //Save storage class
- symbol.set_type(sym->Type); //Save storage class
-
- //Check data length again
- if(!pe_utils::is_sum_safe(i, sym->NumberOfAuxSymbols)
- || (i + sym->NumberOfAuxSymbols) > coff->NumberOfSymbols
- || debug_data.length() < (i + 1) * sizeof(image_symbol) + coff->LvaToFirstSymbol + sym->NumberOfAuxSymbols * sizeof(image_symbol))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //If symbol is filename
- if(sym->StorageClass == image_sym_class_file)
- {
- //Save file name, it is situated just after this IMAGE_SYMBOL structure
- std::string file_name(reinterpret_cast<const char*>(debug_data.data() + (i + 1) * sizeof(image_symbol)), sym->NumberOfAuxSymbols * sizeof(image_symbol));
- pe_utils::strip_nullbytes(file_name);
- symbol.set_file_name(file_name);
-
- //Save symbol info
- coff_info.add_symbol(symbol);
-
- //Move to next symbol
- i += sym->NumberOfAuxSymbols;
- continue;
- }
-
- //Dump some other symbols
- if(((sym->StorageClass == image_sym_class_static)
- && (sym->NumberOfAuxSymbols == 0)
- && (sym->SectionNumber == 1))
- ||
- ((sym->StorageClass == image_sym_class_external)
- && ISFCN(sym->Type)
- && (sym->SectionNumber > 0))
- )
- {
- //Save RVA and section number
- symbol.set_section_number(sym->SectionNumber);
- symbol.set_rva(sym->Value);
-
- //If symbol has short name
- if(sym->N.Name.Short)
- {
- //Copy and save symbol name
- char name_buff[9];
- memcpy(name_buff, sym->N.ShortName, 8);
- name_buff[8] = '\0';
- symbol.set_symbol_name(name_buff);
- }
- else
- {
- //Symbol has long name
-
- //Check possible overflows
- if(!pe_utils::is_sum_safe(coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol), sym->N.Name.Long))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Here we have an offset to the string table
- uint32_t symbol_offset = coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol) + sym->N.Name.Long;
-
- //Check data length
- if(debug_data.length() < symbol_offset)
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Check symbol name for null-termination
- if(!pe_utils::is_null_terminated(debug_data.data() + symbol_offset, debug_data.length() - symbol_offset))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Save symbol name
- symbol.set_symbol_name(debug_data.data() + symbol_offset);
- }
-
- //Save symbol info
- coff_info.add_symbol(symbol);
-
- //Move to next symbol
- i += sym->NumberOfAuxSymbols;
- continue;
- }
- }
-
- info.set_advanced_debug_info(coff_info);
- }
- break;
-
- case image_debug_type_codeview:
- {
- //Check data length
- if(debug_data.length() < sizeof(OMFSignature*))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Get POMFSignature structure pointer from the very beginning of debug data
- const OMFSignature* sig = reinterpret_cast<const OMFSignature*>(debug_data.data());
- if(!memcmp(sig->Signature, "RSDS", 4))
- {
- //Signature is "RSDS" - PDB 7.0
-
- //Check data length
- if(debug_data.length() < sizeof(CV_INFO_PDB70))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- const CV_INFO_PDB70* pdb_data = reinterpret_cast<const CV_INFO_PDB70*>(debug_data.data());
-
- //Check PDB file name null-termination
- if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB70) - 1 /* BYTE of filename in structure */)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- info.set_advanced_debug_info(pdb_7_0_info(pdb_data));
- }
- else if(!memcmp(sig->Signature, "NB10", 4))
- {
- //Signature is "NB10" - PDB 2.0
-
- //Check data length
- if(debug_data.length() < sizeof(CV_INFO_PDB20))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- const CV_INFO_PDB20* pdb_data = reinterpret_cast<const CV_INFO_PDB20*>(debug_data.data());
-
- //Check PDB file name null-termination
- if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB20) - 1 /* BYTE of filename in structure */)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- info.set_advanced_debug_info(pdb_2_0_info(pdb_data));
- }
- else if(!memcmp(sig->Signature, "NB09", 4))
- {
- //CodeView 4.0, no structures available
- info.set_advanced_info_type(debug_info::advanced_info_codeview_4_0);
- }
- else if(!memcmp(sig->Signature, "NB11", 4))
- {
- //CodeView 5.0, no structures available
- info.set_advanced_info_type(debug_info::advanced_info_codeview_5_0);
- }
- else if(!memcmp(sig->Signature, "NB05", 4))
- {
- //Other CodeView, no structures available
- info.set_advanced_info_type(debug_info::advanced_info_codeview);
- }
- }
-
- break;
-
- case image_debug_type_misc:
- {
- //Check data length
- if(debug_data.length() < sizeof(image_debug_misc))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Get misc structure pointer
- const image_debug_misc* misc_data = reinterpret_cast<const image_debug_misc*>(debug_data.data());
-
- //Check misc data length
- if(debug_data.length() < misc_data->Length /* Total length of record */)
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Save advanced information
- info.set_advanced_debug_info(misc_debug_info(misc_data));
- }
- break;
- }
- }
-
- //Save debug information structure
- ret.push_back(info);
-
- //Check possible overflow
- if(!pe_utils::is_sum_safe(current_pos, sizeof(image_debug_directory)))
- throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
- //Go to next debug entry
- current_pos += sizeof(image_debug_directory);
- directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_debug.h b/tools/pe_bliss/pe_debug.h
deleted file mode 100644
index 73a7e6860d..0000000000
--- a/tools/pe_bliss/pe_debug.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing advanced RSDS (PDB 7.0) information
-class pdb_7_0_info
-{
-public:
- //Default constructor
- pdb_7_0_info();
- //Constructor from data
- explicit pdb_7_0_info(const pe_win::CV_INFO_PDB70* info);
-
- //Returns debug PDB 7.0 structure GUID
- const pe_win::guid get_guid() const;
- //Returns age of build
- uint32_t get_age() const;
- //Returns PDB file name / path
- const std::string& get_pdb_file_name() const;
-
-private:
- uint32_t age_;
- pe_win::guid guid_;
- std::string pdb_file_name_;
-};
-
-//Class representing advanced NB10 (PDB 2.0) information
-class pdb_2_0_info
-{
-public:
- //Default constructor
- pdb_2_0_info();
- //Constructor from data
- explicit pdb_2_0_info(const pe_win::CV_INFO_PDB20* info);
-
- //Returns debug PDB 2.0 structure signature
- uint32_t get_signature() const;
- //Returns age of build
- uint32_t get_age() const;
- //Returns PDB file name / path
- const std::string& get_pdb_file_name() const;
-
-private:
- uint32_t age_;
- uint32_t signature_;
- std::string pdb_file_name_;
-};
-
-//Class representing advanced misc (IMAGE_DEBUG_TYPE_MISC) info
-class misc_debug_info
-{
-public:
- //Default constructor
- misc_debug_info();
- //Constructor from data
- explicit misc_debug_info(const pe_win::image_debug_misc* info);
-
- //Returns debug data type
- uint32_t get_data_type() const;
- //Returns true if data type is exe name
- bool is_exe_name() const;
-
- //Returns true if debug data is UNICODE
- bool is_unicode() const;
- //Returns debug data (ANSI or UNICODE)
- const std::string& get_data_ansi() const;
- const std::wstring& get_data_unicode() const;
-
-private:
- uint32_t data_type_;
- bool unicode_;
- std::string debug_data_ansi_;
- std::wstring debug_data_unicode_;
-};
-
-//Class representing COFF (IMAGE_DEBUG_TYPE_COFF) debug info
-class coff_debug_info
-{
-public:
- //Structure representing COFF symbol
- struct coff_symbol
- {
- public:
- //Default constructor
- coff_symbol();
-
- //Returns storage class
- uint32_t get_storage_class() const;
- //Returns symbol index
- uint32_t get_index() const;
- //Returns section number
- uint32_t get_section_number() const;
- //Returns RVA
- uint32_t get_rva() const;
- //Returns type
- uint16_t get_type() const;
-
- //Returns true if structure contains file name
- bool is_file() const;
- //Returns text data (symbol or file name)
- const std::string& get_symbol() const;
-
- public: //These functions do not change everything inside image, they are used by PE class
- //Sets storage class
- void set_storage_class(uint32_t storage_class);
- //Sets symbol index
- void set_index(uint32_t index);
- //Sets section number
- void set_section_number(uint32_t section_number);
- //Sets RVA
- void set_rva(uint32_t rva);
- //Sets type
- void set_type(uint16_t type);
-
- //Sets file name
- void set_file_name(const std::string& file_name);
- //Sets symbol name
- void set_symbol_name(const std::string& symbol_name);
-
- private:
- uint32_t storage_class_;
- uint32_t index_;
- uint32_t section_number_, rva_;
- uint16_t type_;
- bool is_filename_;
- std::string name_;
- };
-
-public:
- typedef std::vector<coff_symbol> coff_symbols_list;
-
-public:
- //Default constructor
- coff_debug_info();
- //Constructor from data
- explicit coff_debug_info(const pe_win::image_coff_symbols_header* info);
-
- //Returns number of symbols
- uint32_t get_number_of_symbols() const;
- //Returns virtual address of the first symbol
- uint32_t get_lva_to_first_symbol() const;
- //Returns number of line-number entries
- uint32_t get_number_of_line_numbers() const;
- //Returns virtual address of the first line-number entry
- uint32_t get_lva_to_first_line_number() const;
- //Returns relative virtual address of the first byte of code
- uint32_t get_rva_to_first_byte_of_code() const;
- //Returns relative virtual address of the last byte of code
- uint32_t get_rva_to_last_byte_of_code() const;
- //Returns relative virtual address of the first byte of data
- uint32_t get_rva_to_first_byte_of_data() const;
- //Returns relative virtual address of the last byte of data
- uint32_t get_rva_to_last_byte_of_data() const;
-
- //Returns COFF symbols list
- const coff_symbols_list& get_symbols() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //Adds COFF symbol
- void add_symbol(const coff_symbol& sym);
-
-private:
- uint32_t number_of_symbols_;
- uint32_t lva_to_first_symbol_;
- uint32_t number_of_line_numbers_;
- uint32_t lva_to_first_line_number_;
- uint32_t rva_to_first_byte_of_code_;
- uint32_t rva_to_last_byte_of_code_;
- uint32_t rva_to_first_byte_of_data_;
- uint32_t rva_to_last_byte_of_data_;
-
-private:
- coff_symbols_list symbols_;
-};
-
-//Class representing debug information
-class debug_info
-{
-public:
- //Enumeration of debug information types
- enum debug_info_type
- {
- debug_type_unknown,
- debug_type_coff,
- debug_type_codeview,
- debug_type_fpo,
- debug_type_misc,
- debug_type_exception,
- debug_type_fixup,
- debug_type_omap_to_src,
- debug_type_omap_from_src,
- debug_type_borland,
- debug_type_reserved10,
- debug_type_clsid
- };
-
-public:
- //Enumeration of advanced debug information types
- enum advanced_info_type
- {
- advanced_info_none, //No advanced info
- advanced_info_pdb_7_0, //PDB 7.0
- advanced_info_pdb_2_0, //PDB 2.0
- advanced_info_misc, //MISC debug info
- advanced_info_coff, //COFF debug info
- //No advanced info structures available for types below
- advanced_info_codeview_4_0, //CodeView 4.0
- advanced_info_codeview_5_0, //CodeView 5.0
- advanced_info_codeview //CodeView
- };
-
-public:
- //Default constructor
- debug_info();
- //Constructor from data
- explicit debug_info(const pe_win::image_debug_directory& debug);
- //Copy constructor
- debug_info(const debug_info& info);
- //Copy assignment operator
- debug_info& operator=(const debug_info& info);
- //Destructor
- ~debug_info();
-
- //Returns debug characteristics
- uint32_t get_characteristics() const;
- //Returns debug datetimestamp
- uint32_t get_time_stamp() const;
- //Returns major version
- uint32_t get_major_version() const;
- //Returns minor version
- uint32_t get_minor_version() const;
- //Returns type of debug info (unchecked)
- uint32_t get_type_raw() const;
- //Returns type of debug info from debug_info_type enumeration
- debug_info_type get_type() const;
- //Returns size of debug data (internal, .pdb or other file doesn't count)
- uint32_t get_size_of_data() const;
- //Returns RVA of debug info when mapped to memory or zero, if info is not mapped
- uint32_t get_rva_of_raw_data() const;
- //Returns raw file pointer to raw data
- uint32_t get_pointer_to_raw_data() const;
-
- //Returns advanced debug information type
- advanced_info_type get_advanced_info_type() const;
- //Returns advanced debug information or throws an exception,
- //if requested information type is not contained by structure
- template<typename AdvancedInfo>
- const AdvancedInfo get_advanced_debug_info() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //Sets advanced debug information
- void set_advanced_debug_info(const pdb_7_0_info& info);
- void set_advanced_debug_info(const pdb_2_0_info& info);
- void set_advanced_debug_info(const misc_debug_info& info);
- void set_advanced_debug_info(const coff_debug_info& info);
-
- //Sets advanced debug information type, if no advanced info structure available
- void set_advanced_info_type(advanced_info_type type);
-
-private:
- uint32_t characteristics_;
- uint32_t time_stamp_;
- uint32_t major_version_, minor_version_;
- uint32_t type_;
- uint32_t size_of_data_;
- uint32_t address_of_raw_data_; //RVA when mapped or 0
- uint32_t pointer_to_raw_data_; //RAW file offset
-
- //Union containing advanced debug information pointer
- union advanced_info
- {
- public:
- //Default constructor
- advanced_info();
-
- //Returns true if advanced debug info is present
- bool is_present() const;
-
- public:
- pdb_7_0_info* adv_pdb_7_0_info;
- pdb_2_0_info* adv_pdb_2_0_info;
- misc_debug_info* adv_misc_info;
- coff_debug_info* adv_coff_info;
- };
-
- //Helper for advanced debug information copying
- void copy_advanced_info(const debug_info& info);
- //Helper for clearing any present advanced debug information
- void free_present_advanced_info();
-
- advanced_info advanced_debug_info_;
- //Advanced information type
- advanced_info_type advanced_info_type_;
-};
-
-typedef std::vector<debug_info> debug_info_list;
-
-//Returns debug information list
-const debug_info_list get_debug_information(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_directory.cpp b/tools/pe_bliss/pe_directory.cpp
deleted file mode 100644
index 13ad2afc5d..0000000000
--- a/tools/pe_bliss/pe_directory.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_directory.h"
-
-namespace pe_bliss
-{
-//Default constructor
-image_directory::image_directory()
- :rva_(0), size_(0)
-{}
-
-//Constructor from data
-image_directory::image_directory(uint32_t rva, uint32_t size)
- :rva_(rva), size_(size)
-{}
-
-//Returns RVA
-uint32_t image_directory::get_rva() const
-{
- return rva_;
-}
-
-//Returns size
-uint32_t image_directory::get_size() const
-{
- return size_;
-}
-
-//Sets RVA
-void image_directory::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Sets size
-void image_directory::set_size(uint32_t size)
-{
- size_ = size;
-}
-}
diff --git a/tools/pe_bliss/pe_directory.h b/tools/pe_bliss/pe_directory.h
deleted file mode 100644
index a7b1ea7a5f..0000000000
--- a/tools/pe_bliss/pe_directory.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Class representing image directory data
-class image_directory
-{
-public:
- //Default constructor
- image_directory();
- //Constructor from data
- image_directory(uint32_t rva, uint32_t size);
-
- //Returns RVA
- uint32_t get_rva() const;
- //Returns size
- uint32_t get_size() const;
-
- //Sets RVA
- void set_rva(uint32_t rva);
- //Sets size
- void set_size(uint32_t size);
-
-private:
- uint32_t rva_;
- uint32_t size_;
-};
-}
diff --git a/tools/pe_bliss/pe_dotnet.cpp b/tools/pe_bliss/pe_dotnet.cpp
deleted file mode 100644
index f34a76eae8..0000000000
--- a/tools/pe_bliss/pe_dotnet.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_dotnet.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//.NET
-basic_dotnet_info::basic_dotnet_info()
-{
- memset(&header_, 0, sizeof(header_));
-}
-
-//Constructor from data
-basic_dotnet_info::basic_dotnet_info(const image_cor20_header& header)
- :header_(header)
-{}
-
-//Returns major runtime version
-uint16_t basic_dotnet_info::get_major_runtime_version() const
-{
- return header_.MajorRuntimeVersion;
-}
-
-//Returns minor runtime version
-uint16_t basic_dotnet_info::get_minor_runtime_version() const
-{
- return header_.MinorRuntimeVersion;
-}
-
-//Returns RVA of metadata (symbol table and startup information)
-uint32_t basic_dotnet_info::get_rva_of_metadata() const
-{
- return header_.MetaData.VirtualAddress;
-}
-
-//Returns size of metadata (symbol table and startup information)
-uint32_t basic_dotnet_info::get_size_of_metadata() const
-{
- return header_.MetaData.Size;
-}
-
-//Returns flags
-uint32_t basic_dotnet_info::get_flags() const
-{
- return header_.Flags;
-}
-
-//Returns true if entry point is native
-bool basic_dotnet_info::is_native_entry_point() const
-{
- return (header_.Flags & comimage_flags_native_entrypoint) ? true : false;
-}
-
-//Returns true if 32 bit required
-bool basic_dotnet_info::is_32bit_required() const
-{
- return (header_.Flags & comimage_flags_32bitrequired) ? true : false;
-}
-
-//Returns true if image is IL library
-bool basic_dotnet_info::is_il_library() const
-{
- return (header_.Flags & comimage_flags_il_library) ? true : false;
-}
-
-//Returns true if image uses IL only
-bool basic_dotnet_info::is_il_only() const
-{
- return (header_.Flags & comimage_flags_ilonly) ? true : false;
-}
-
-//Returns entry point RVA (if entry point is native)
-//Returns entry point managed token (if entry point is managed)
-uint32_t basic_dotnet_info::get_entry_point_rva_or_token() const
-{
- return header_.EntryPointToken;
-}
-
-//Returns RVA of managed resources
-uint32_t basic_dotnet_info::get_rva_of_resources() const
-{
- return header_.Resources.VirtualAddress;
-}
-
-//Returns size of managed resources
-uint32_t basic_dotnet_info::get_size_of_resources() const
-{
- return header_.Resources.Size;
-}
-
-//Returns RVA of strong name signature
-uint32_t basic_dotnet_info::get_rva_of_strong_name_signature() const
-{
- return header_.StrongNameSignature.VirtualAddress;
-}
-
-//Returns size of strong name signature
-uint32_t basic_dotnet_info::get_size_of_strong_name_signature() const
-{
- return header_.StrongNameSignature.Size;
-}
-
-//Returns RVA of code manager table
-uint32_t basic_dotnet_info::get_rva_of_code_manager_table() const
-{
- return header_.CodeManagerTable.VirtualAddress;
-}
-
-//Returns size of code manager table
-uint32_t basic_dotnet_info::get_size_of_code_manager_table() const
-{
- return header_.CodeManagerTable.Size;
-}
-
-//Returns RVA of VTable fixups
-uint32_t basic_dotnet_info::get_rva_of_vtable_fixups() const
-{
- return header_.VTableFixups.VirtualAddress;
-}
-
-//Returns size of VTable fixups
-uint32_t basic_dotnet_info::get_size_of_vtable_fixups() const
-{
- return header_.VTableFixups.Size;
-}
-
-//Returns RVA of export address table jumps
-uint32_t basic_dotnet_info::get_rva_of_export_address_table_jumps() const
-{
- return header_.ExportAddressTableJumps.VirtualAddress;
-}
-
-//Returns size of export address table jumps
-uint32_t basic_dotnet_info::get_size_of_export_address_table_jumps() const
-{
- return header_.ExportAddressTableJumps.Size;
-}
-
-//Returns RVA of managed native header
-//(precompiled header info, usually set to zero, for internal use)
-uint32_t basic_dotnet_info::get_rva_of_managed_native_header() const
-{
- return header_.ManagedNativeHeader.VirtualAddress;
-}
-
-//Returns size of managed native header
-//(precompiled header info, usually set to zero, for internal use)
-uint32_t basic_dotnet_info::get_size_of_managed_native_header() const
-{
- return header_.ManagedNativeHeader.Size;
-}
-
-//Returns basic .NET information
-//If image is not native, throws an exception
-const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe)
-{
- //If there's no debug directory, return empty list
- if(!pe.is_dotnet())
- throw pe_exception("Image does not have managed code", pe_exception::image_does_not_have_managed_code);
-
- //Return basic .NET information
- return basic_dotnet_info(pe.section_data_from_rva<image_cor20_header>(pe.get_directory_rva(image_directory_entry_com_descriptor), section_data_virtual, true));
-}
-}
diff --git a/tools/pe_bliss/pe_dotnet.h b/tools/pe_bliss/pe_dotnet.h
deleted file mode 100644
index 96b0ac7d0a..0000000000
--- a/tools/pe_bliss/pe_dotnet.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing basic .NET header information
-class basic_dotnet_info
-{
-public:
- //Default constructor
- basic_dotnet_info();
- //Constructor from data
- explicit basic_dotnet_info(const pe_win::image_cor20_header& header);
-
- //Returns major runtime version
- uint16_t get_major_runtime_version() const;
- //Returns minor runtime version
- uint16_t get_minor_runtime_version() const;
-
- //Returns RVA of metadata (symbol table and startup information)
- uint32_t get_rva_of_metadata() const;
- //Returns size of metadata (symbol table and startup information)
- uint32_t get_size_of_metadata() const;
-
- //Returns flags
- uint32_t get_flags() const;
-
- //Returns true if entry point is native
- bool is_native_entry_point() const;
- //Returns true if 32 bit required
- bool is_32bit_required() const;
- //Returns true if image is IL library
- bool is_il_library() const;
- //Returns true if image uses IL only
- bool is_il_only() const;
-
- //Returns entry point RVA (if entry point is native)
- //Returns entry point managed token (if entry point is managed)
- uint32_t get_entry_point_rva_or_token() const;
-
- //Returns RVA of managed resources
- uint32_t get_rva_of_resources() const;
- //Returns size of managed resources
- uint32_t get_size_of_resources() const;
- //Returns RVA of strong name signature
- uint32_t get_rva_of_strong_name_signature() const;
- //Returns size of strong name signature
- uint32_t get_size_of_strong_name_signature() const;
- //Returns RVA of code manager table
- uint32_t get_rva_of_code_manager_table() const;
- //Returns size of code manager table
- uint32_t get_size_of_code_manager_table() const;
- //Returns RVA of VTable fixups
- uint32_t get_rva_of_vtable_fixups() const;
- //Returns size of VTable fixups
- uint32_t get_size_of_vtable_fixups() const;
- //Returns RVA of export address table jumps
- uint32_t get_rva_of_export_address_table_jumps() const;
- //Returns size of export address table jumps
- uint32_t get_size_of_export_address_table_jumps() const;
- //Returns RVA of managed native header
- //(precompiled header info, usually set to zero, for internal use)
- uint32_t get_rva_of_managed_native_header() const;
- //Returns size of managed native header
- //(precompiled header info, usually set to zero, for internal use)
- uint32_t get_size_of_managed_native_header() const;
-
-private:
- pe_win::image_cor20_header header_;
-};
-
-//Returns basic .NET information
-//If image is not native, throws an exception
-const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_exception.cpp b/tools/pe_bliss/pe_exception.cpp
deleted file mode 100644
index 3161f93599..0000000000
--- a/tools/pe_bliss/pe_exception.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_exception.h"
-
-namespace pe_bliss
-{
-//PE exception class constructors
-pe_exception::pe_exception(const char* text, exception_id id)
- :std::runtime_error(text), id_(id)
-{}
-
-pe_exception::pe_exception(const std::string& text, exception_id id)
- :std::runtime_error(text), id_(id)
-{}
-
-//Returns exception ID
-pe_exception::exception_id pe_exception::get_id() const
-{
- return id_;
-}
-}
diff --git a/tools/pe_bliss/pe_exception.h b/tools/pe_bliss/pe_exception.h
deleted file mode 100644
index 2b58a95772..0000000000
--- a/tools/pe_bliss/pe_exception.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <exception>
-#include <stdexcept>
-
-namespace pe_bliss
-{
-//PE exception class
-class pe_exception : public std::runtime_error
-{
-public:
- //Exception IDs
- enum exception_id
- {
- unknown_error,
- bad_pe_file,
- bad_dos_header,
- image_nt_headers_not_found,
- error_reading_image_nt_headers,
- error_reading_data_directories,
- error_reading_file,
- pe_signature_incorrect,
- incorrect_number_of_rva_and_sizes,
- error_changing_section_virtual_size,
- section_number_incorrect,
- section_table_incorrect,
- incorrect_section_alignment,
- incorrect_file_alignment,
- incorrect_size_of_image,
- incorrect_size_of_headers,
- image_section_headers_not_found,
- zero_section_sizes,
- section_incorrect_addr_or_size,
- section_not_found,
- image_section_data_not_found,
- no_section_found,
- image_section_table_incorrect,
- directory_does_not_exist,
- rva_not_exists,
- error_reading_section_header,
- error_reading_overlay,
- incorrect_address_conversion,
-
- incorrect_export_directory,
- incorrect_import_directory,
- incorrect_relocation_directory,
- incorrect_tls_directory,
- incorrect_config_directory,
- incorrect_bound_import_directory,
- incorrect_resource_directory,
- incorrect_exception_directory,
- incorrect_debug_directory,
-
- resource_directory_entry_error,
- resource_directory_entry_not_found,
- resource_data_entry_not_found,
- resource_incorrect_bitmap,
- resource_incorrect_icon,
- resource_incorrect_cursor,
- resource_incorrect_string_table,
- resource_string_not_found,
- resource_incorrect_message_table,
- resource_incorrect_version_info,
-
- advanced_debug_information_request_error,
- image_does_not_have_managed_code,
-
- section_is_empty,
- data_is_empty,
- stream_is_bad,
-
- section_is_not_attached,
- insufficient_space,
-
- cannot_rebase_relocations,
-
- exports_list_is_empty,
- duplicate_exported_function_ordinal,
- duplicate_exported_function_name,
-
- version_info_string_does_not_exist,
-
- no_more_sections_can_be_added,
-
- no_icon_group_found,
- no_cursor_group_found,
-
- encoding_convertion_error,
-
- error_expanding_section,
-
- cannot_rebuild_image
- };
-
-public:
- //Class constructors
- explicit pe_exception(const char* text, exception_id id = unknown_error);
- explicit pe_exception(const std::string& text, exception_id id = unknown_error);
-
- //Returns exception ID from exception_id enumeration
- exception_id get_id() const;
-
- //Destructor
- virtual ~pe_exception() throw()
- {}
-
-private:
- exception_id id_;
-};
-}
diff --git a/tools/pe_bliss/pe_exception_directory.cpp b/tools/pe_bliss/pe_exception_directory.cpp
deleted file mode 100644
index 1813f02021..0000000000
--- a/tools/pe_bliss/pe_exception_directory.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_exception_directory.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//EXCEPTION DIRECTORY (exists on PE+ only)
-//Default constructor
-exception_entry::exception_entry()
- :begin_address_(0), end_address_(0), unwind_info_address_(0),
- unwind_info_version_(0),
- flags_(0),
- size_of_prolog_(0),
- count_of_codes_(0),
- frame_register_(0),
- frame_offset_(0)
-{}
-
-//Constructor from data
-exception_entry::exception_entry(const image_runtime_function_entry& entry, const unwind_info& unwind_info)
- :begin_address_(entry.BeginAddress), end_address_(entry.EndAddress), unwind_info_address_(entry.UnwindInfoAddress),
- unwind_info_version_(unwind_info.Version),
- flags_(unwind_info.Flags),
- size_of_prolog_(unwind_info.SizeOfProlog),
- count_of_codes_(unwind_info.CountOfCodes),
- frame_register_(unwind_info.FrameRegister),
- frame_offset_(unwind_info.FrameOffset)
-{}
-
-//Returns starting address of function, affected by exception unwinding
-uint32_t exception_entry::get_begin_address() const
-{
- return begin_address_;
-}
-
-//Returns ending address of function, affected by exception unwinding
-uint32_t exception_entry::get_end_address() const
-{
- return end_address_;
-}
-
-//Returns unwind info address
-uint32_t exception_entry::get_unwind_info_address() const
-{
- return unwind_info_address_;
-}
-
-//Returns UNWIND_INFO structure version
-uint8_t exception_entry::get_unwind_info_version() const
-{
- return unwind_info_version_;
-}
-
-//Returns unwind info flags
-uint8_t exception_entry::get_flags() const
-{
- return flags_;
-}
-
-//The function has an exception handler that should be called
-//when looking for functions that need to examine exceptions
-bool exception_entry::has_exception_handler() const
-{
- return (flags_ & unw_flag_ehandler) ? true : false;
-}
-
-//The function has a termination handler that should be called
-//when unwinding an exception
-bool exception_entry::has_termination_handler() const
-{
- return (flags_ & unw_flag_uhandler) ? true : false;
-}
-
-//The unwind info structure is not the primary one for the procedure
-bool exception_entry::is_chaininfo() const
-{
- return (flags_ & unw_flag_chaininfo) ? true : false;
-}
-
-//Returns size of function prolog
-uint8_t exception_entry::get_size_of_prolog() const
-{
- return size_of_prolog_;
-}
-
-//Returns number of unwind slots
-uint8_t exception_entry::get_number_of_unwind_slots() const
-{
- return count_of_codes_;
-}
-
-//If the function uses frame pointer
-bool exception_entry::uses_frame_pointer() const
-{
- return frame_register_ != 0;
-}
-
-//Number of the nonvolatile register used as the frame pointer,
-//using the same encoding for the operation info field of UNWIND_CODE nodes
-uint8_t exception_entry::get_frame_pointer_register_number() const
-{
- return frame_register_;
-}
-
-//The scaled offset from RSP that is applied to the FP reg when it is established.
-//The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240
-uint8_t exception_entry::get_scaled_rsp_offset() const
-{
- return frame_offset_;
-}
-
-//Returns exception directory data (exists on PE+ only)
-//Unwind opcodes are not listed, because their format and list are subject to change
-const exception_entry_list get_exception_directory_data(const pe_base& pe)
-{
- exception_entry_list ret;
-
- //If image doesn't have exception directory, return empty list
- if(!pe.has_exception_directory())
- return ret;
-
- //Check the length in bytes of the section containing exception directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_exception), pe.get_directory_rva(image_directory_entry_exception), section_data_virtual, true)
- < sizeof(image_runtime_function_entry))
- throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
- unsigned long current_pos = pe.get_directory_rva(image_directory_entry_exception);
-
- //Check if structures are DWORD-aligned
- if(current_pos % sizeof(uint32_t))
- throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
- //First IMAGE_RUNTIME_FUNCTION_ENTRY table
- image_runtime_function_entry exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true);
-
- //todo: virtual addresses BeginAddress and EndAddress are not checked to be inside image
- while(exception_table.BeginAddress)
- {
- //Check addresses
- if(exception_table.BeginAddress > exception_table.EndAddress)
- throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
- //Get unwind information
- unwind_info info = pe.section_data_from_rva<unwind_info>(exception_table.UnwindInfoAddress, section_data_virtual, true);
-
- //Create exception entry and save it
- ret.push_back(exception_entry(exception_table, info));
-
- //Go to next exception entry
- current_pos += sizeof(image_runtime_function_entry);
- exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true);
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_exception_directory.h b/tools/pe_bliss/pe_exception_directory.h
deleted file mode 100644
index 6f4fc2298b..0000000000
--- a/tools/pe_bliss/pe_exception_directory.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing exception directory entry
-class exception_entry
-{
-public:
- //Default constructor
- exception_entry();
- //Constructor from data
- exception_entry(const pe_win::image_runtime_function_entry& entry, const pe_win::unwind_info& unwind_info);
-
- //Returns starting address of function, affected by exception unwinding
- uint32_t get_begin_address() const;
- //Returns ending address of function, affected by exception unwinding
- uint32_t get_end_address() const;
- //Returns unwind info address
- uint32_t get_unwind_info_address() const;
-
- //Returns UNWIND_INFO structure version
- uint8_t get_unwind_info_version() const;
-
- //Returns unwind info flags
- uint8_t get_flags() const;
- //The function has an exception handler that should be called
- //when looking for functions that need to examine exceptions
- bool has_exception_handler() const;
- //The function has a termination handler that should be called
- //when unwinding an exception
- bool has_termination_handler() const;
- //The unwind info structure is not the primary one for the procedure
- bool is_chaininfo() const;
-
- //Returns size of function prolog
- uint8_t get_size_of_prolog() const;
-
- //Returns number of unwind slots
- uint8_t get_number_of_unwind_slots() const;
-
- //If the function uses frame pointer
- bool uses_frame_pointer() const;
- //Number of the nonvolatile register used as the frame pointer,
- //using the same encoding for the operation info field of UNWIND_CODE nodes
- uint8_t get_frame_pointer_register_number() const;
- //The scaled offset from RSP that is applied to the FP reg when it is established.
- //The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240
- uint8_t get_scaled_rsp_offset() const;
-
-private:
- uint32_t begin_address_, end_address_, unwind_info_address_;
- uint8_t unwind_info_version_;
- uint8_t flags_;
- uint8_t size_of_prolog_;
- uint8_t count_of_codes_;
- uint8_t frame_register_, frame_offset_;
-};
-
-typedef std::vector<exception_entry> exception_entry_list;
-
-//Returns exception directory data (exists on PE+ only)
-//Unwind opcodes are not listed, because their format and list are subject to change
-const exception_entry_list get_exception_directory_data(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_exports.cpp b/tools/pe_bliss/pe_exports.cpp
deleted file mode 100644
index c2ad895554..0000000000
--- a/tools/pe_bliss/pe_exports.cpp
+++ /dev/null
@@ -1,700 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <set>
-#include <algorithm>
-#include <string.h>
-#include "pe_exports.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//EXPORTS
-//Default constructor
-exported_function::exported_function()
- :ordinal_(0), rva_(0), has_name_(false), name_ordinal_(0), forward_(false)
-{}
-
-//Returns ordinal of function (actually, ordinal = hint + ordinal base)
-uint16_t exported_function::get_ordinal() const
-{
- return ordinal_;
-}
-
-//Returns RVA of function
-uint32_t exported_function::get_rva() const
-{
- return rva_;
-}
-
-//Returns name of function
-const std::string& exported_function::get_name() const
-{
- return name_;
-}
-
-//Returns true if function has name and name ordinal
-bool exported_function::has_name() const
-{
- return has_name_;
-}
-
-//Returns name ordinal of function
-uint16_t exported_function::get_name_ordinal() const
-{
- return name_ordinal_;
-}
-
-//Returns true if function is forwarded to other library
-bool exported_function::is_forwarded() const
-{
- return forward_;
-}
-
-//Returns the name of forwarded function
-const std::string& exported_function::get_forwarded_name() const
-{
- return forward_name_;
-}
-
-//Sets ordinal of function
-void exported_function::set_ordinal(uint16_t ordinal)
-{
- ordinal_ = ordinal;
-}
-
-//Sets RVA of function
-void exported_function::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Sets name of function (or clears it, if empty name is passed)
-void exported_function::set_name(const std::string& name)
-{
- name_ = name;
- has_name_ = !name.empty();
-}
-
-//Sets name ordinal
-void exported_function::set_name_ordinal(uint16_t name_ordinal)
-{
- name_ordinal_ = name_ordinal;
-}
-
-//Sets forwarded function name (or clears it, if empty name is passed)
-void exported_function::set_forwarded_name(const std::string& name)
-{
- forward_name_ = name;
- forward_ = !name.empty();
-}
-
-//Default constructor
-export_info::export_info()
- :characteristics_(0),
- timestamp_(0),
- major_version_(0),
- minor_version_(0),
- ordinal_base_(0),
- number_of_functions_(0),
- number_of_names_(0),
- address_of_functions_(0),
- address_of_names_(0),
- address_of_name_ordinals_(0)
-{}
-
-//Returns characteristics
-uint32_t export_info::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns timestamp
-uint32_t export_info::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Returns major version
-uint16_t export_info::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version
-uint16_t export_info::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns DLL name
-const std::string& export_info::get_name() const
-{
- return name_;
-}
-
-//Returns ordinal base
-uint32_t export_info::get_ordinal_base() const
-{
- return ordinal_base_;
-}
-
-//Returns number of functions
-uint32_t export_info::get_number_of_functions() const
-{
- return number_of_functions_;
-}
-
-//Returns number of function names
-uint32_t export_info::get_number_of_names() const
-{
- return number_of_names_;
-}
-
-//Returns RVA of function address table
-uint32_t export_info::get_rva_of_functions() const
-{
- return address_of_functions_;
-}
-
-//Returns RVA of function name address table
-uint32_t export_info::get_rva_of_names() const
-{
- return address_of_names_;
-}
-
-//Returns RVA of name ordinals table
-uint32_t export_info::get_rva_of_name_ordinals() const
-{
- return address_of_name_ordinals_;
-}
-
-//Sets characteristics
-void export_info::set_characteristics(uint32_t characteristics)
-{
- characteristics_ = characteristics;
-}
-
-//Sets timestamp
-void export_info::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Sets major version
-void export_info::set_major_version(uint16_t major_version)
-{
- major_version_ = major_version;
-}
-
-//Sets minor version
-void export_info::set_minor_version(uint16_t minor_version)
-{
- minor_version_ = minor_version;
-}
-
-//Sets DLL name
-void export_info::set_name(const std::string& name)
-{
- name_ = name;
-}
-
-//Sets ordinal base
-void export_info::set_ordinal_base(uint32_t ordinal_base)
-{
- ordinal_base_ = ordinal_base;
-}
-
-//Sets number of functions
-void export_info::set_number_of_functions(uint32_t number_of_functions)
-{
- number_of_functions_ = number_of_functions;
-}
-
-//Sets number of function names
-void export_info::set_number_of_names(uint32_t number_of_names)
-{
- number_of_names_ = number_of_names;
-}
-
-//Sets RVA of function address table
-void export_info::set_rva_of_functions(uint32_t rva_of_functions)
-{
- address_of_functions_ = rva_of_functions;
-}
-
-//Sets RVA of function name address table
-void export_info::set_rva_of_names(uint32_t rva_of_names)
-{
- address_of_names_ = rva_of_names;
-}
-
-//Sets RVA of name ordinals table
-void export_info::set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals)
-{
- address_of_name_ordinals_ = rva_of_name_ordinals;
-}
-
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info);
-
-//Returns array of exported functions
-const exported_functions_list get_exported_functions(const pe_base& pe)
-{
- return get_exported_functions(pe, 0);
-}
-
-//Returns array of exported functions and information about export
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info)
-{
- return get_exported_functions(pe, &info);
-}
-
-//Helper: sorts exported function list by ordinals
-struct ordinal_sorter
-{
-public:
- bool operator()(const exported_function& func1, const exported_function& func2) const;
-};
-
-//Returns array of exported functions and information about export (if info != 0)
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info)
-{
- //Returned exported functions info array
- std::vector<exported_function> ret;
-
- if(pe.has_exports())
- {
- //Check the length in bytes of the section containing export directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_export),
- pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true)
- < sizeof(image_export_directory))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- image_export_directory exports = pe.section_data_from_rva<image_export_directory>(pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true);
-
- unsigned long max_name_length;
-
- if(info)
- {
- //Save some export info data
- info->set_characteristics(exports.Characteristics);
- info->set_major_version(exports.MajorVersion);
- info->set_minor_version(exports.MinorVersion);
-
- //Get byte count that we have for dll name
- if((max_name_length = pe.section_data_length_from_rva(exports.Name, exports.Name, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Get dll name pointer
- const char* dll_name = pe.section_data_from_rva(exports.Name, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(dll_name, max_name_length))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Save the rest of export information data
- info->set_name(dll_name);
- info->set_number_of_functions(exports.NumberOfFunctions);
- info->set_number_of_names(exports.NumberOfNames);
- info->set_ordinal_base(exports.Base);
- info->set_rva_of_functions(exports.AddressOfFunctions);
- info->set_rva_of_names(exports.AddressOfNames);
- info->set_rva_of_name_ordinals(exports.AddressOfNameOrdinals);
- info->set_timestamp(exports.TimeDateStamp);
- }
-
- if(!exports.NumberOfFunctions)
- return ret;
-
- //Check IMAGE_EXPORT_DIRECTORY fields
- if(exports.NumberOfNames > exports.NumberOfFunctions)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Check some export directory fields
- if((!exports.AddressOfNameOrdinals && exports.AddressOfNames) ||
- (exports.AddressOfNameOrdinals && !exports.AddressOfNames) ||
- !exports.AddressOfFunctions
- || exports.NumberOfFunctions >= pe_utils::max_dword / sizeof(uint32_t)
- || exports.NumberOfNames > pe_utils::max_dword / sizeof(uint32_t)
- || !pe_utils::is_sum_safe(exports.AddressOfFunctions, exports.NumberOfFunctions * sizeof(uint32_t))
- || !pe_utils::is_sum_safe(exports.AddressOfNames, exports.NumberOfNames * sizeof(uint32_t))
- || !pe_utils::is_sum_safe(exports.AddressOfNameOrdinals, exports.NumberOfFunctions * sizeof(uint32_t))
- || !pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_export), pe.get_directory_size(image_directory_entry_export)))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Check if it is enough bytes to hold AddressOfFunctions table
- if(pe.section_data_length_from_rva(exports.AddressOfFunctions, exports.AddressOfFunctions, section_data_virtual, true)
- < exports.NumberOfFunctions * sizeof(uint32_t))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- if(exports.AddressOfNames)
- {
- //Check if it is enough bytes to hold name and ordinal tables
- if(pe.section_data_length_from_rva(exports.AddressOfNameOrdinals, exports.AddressOfNameOrdinals, section_data_virtual, true)
- < exports.NumberOfNames * sizeof(uint16_t))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- if(pe.section_data_length_from_rva(exports.AddressOfNames, exports.AddressOfNames, section_data_virtual, true)
- < exports.NumberOfNames * sizeof(uint32_t))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
- }
-
- for(uint32_t ordinal = 0; ordinal < exports.NumberOfFunctions; ordinal++)
- {
- //Get function address
- //Sum and multiplication are safe (checked above)
- uint32_t rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfFunctions + ordinal * sizeof(uint32_t), section_data_virtual, true);
-
- //If we have a skip
- if(!rva)
- continue;
-
- exported_function func;
- func.set_rva(rva);
-
- if(!pe_utils::is_sum_safe(exports.Base, ordinal) || exports.Base + ordinal > pe_utils::max_word)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- func.set_ordinal(static_cast<uint16_t>(ordinal + exports.Base));
-
- //Scan for function name ordinal
- for(uint32_t i = 0; i < exports.NumberOfNames; i++)
- {
- uint16_t ordinal2 = pe.section_data_from_rva<uint16_t>(exports.AddressOfNameOrdinals + i * sizeof(uint16_t), section_data_virtual, true);
-
- //If function has name (and name ordinal)
- if(ordinal == ordinal2)
- {
- //Get function name
- //Sum and multiplication are safe (checked above)
- uint32_t function_name_rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfNames + i * sizeof(uint32_t), section_data_virtual, true);
-
- //Get byte count that we have for function name
- if((max_name_length = pe.section_data_length_from_rva(function_name_rva, function_name_rva, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Get function name pointer
- const char* func_name = pe.section_data_from_rva(function_name_rva, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(func_name, max_name_length))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Save function info
- func.set_name(func_name);
- func.set_name_ordinal(ordinal2);
-
- //If the function is just a redirect, save its name
- if(rva >= pe.get_directory_rva(image_directory_entry_export) + sizeof(image_directory_entry_export) &&
- rva < pe.get_directory_rva(image_directory_entry_export) + pe.get_directory_size(image_directory_entry_export))
- {
- if((max_name_length = pe.section_data_length_from_rva(rva, rva, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Get forwarded function name pointer
- const char* forwarded_func_name = pe.section_data_from_rva(rva, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(forwarded_func_name, max_name_length))
- throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
- //Set the name of forwarded function
- func.set_forwarded_name(forwarded_func_name);
- }
-
- break;
- }
- }
-
- //Add function info to output array
- ret.push_back(func);
- }
- }
-
- return ret;
-}
-
-//Helper export functions
-//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions>
-const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports)
-{
- if(exports.empty())
- return std::make_pair(0, 0);
-
- uint16_t max_ordinal = 0; //Maximum ordinal number
- uint16_t ordinal_base = pe_utils::max_word; //Minimum ordinal value
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- const exported_function& func = (*it);
-
- //Calculate maximum and minimum ordinal numbers
- max_ordinal = std::max<uint16_t>(max_ordinal, func.get_ordinal());
- ordinal_base = std::min<uint16_t>(ordinal_base, func.get_ordinal());
- }
-
- return std::make_pair(ordinal_base, max_ordinal);
-}
-
-//Checks if exported function name already exists
-bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports)
-{
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- if((*it).has_name() && (*it).get_name() == function_name)
- return true;
- }
-
- return false;
-}
-
-//Checks if exported function name already exists
-bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports)
-{
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- if((*it).get_ordinal() == ordinal)
- return true;
- }
-
- return false;
-}
-
-//Helper: sorts exported function list by ordinals
-bool ordinal_sorter::operator()(const exported_function& func1, const exported_function& func2) const
-{
- return func1.get_ordinal() < func2.get_ordinal();
-}
-
-//Export directory rebuilder
-//info - export information
-//exported_functions_list - list of exported functions
-//exports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from exports_section raw data start
-//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
-//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
-//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
-//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
-//Returns new export directory information
-//exported_functions_list is copied intentionally to be sorted by ordinal values later
-//Name ordinals in exported function don't matter, they will be recalculated
-const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that exports_section is attached to this PE image
- if(!pe.section_attached(exports_section))
- throw pe_exception("Exports section must be attached to PE file", pe_exception::section_is_not_attached);
-
- //Needed space for strings
- uint32_t needed_size_for_strings = static_cast<uint32_t>(info.get_name().length() + 1);
- uint32_t number_of_names = 0; //Number of named functions
- uint32_t max_ordinal = 0; //Maximum ordinal number
- uint32_t ordinal_base = static_cast<uint32_t>(-1); //Minimum ordinal value
-
- if(exports.empty())
- ordinal_base = info.get_ordinal_base();
-
- uint32_t needed_size_for_function_names = 0; //Needed space for function name strings
- uint32_t needed_size_for_function_forwards = 0; //Needed space for function forwards names
-
- //List all exported functions
- //Calculate needed size for function list
- {
- //Also check that there're no duplicate names and ordinals
- std::set<std::string> used_function_names;
- std::set<uint16_t> used_function_ordinals;
-
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- const exported_function& func = (*it);
- //Calculate maximum and minimum ordinal numbers
- max_ordinal = std::max<uint32_t>(max_ordinal, func.get_ordinal());
- ordinal_base = std::min<uint32_t>(ordinal_base, func.get_ordinal());
-
- //Check if ordinal is unique
- if(!used_function_ordinals.insert(func.get_ordinal()).second)
- throw pe_exception("Duplicate exported function ordinal", pe_exception::duplicate_exported_function_ordinal);
-
- if(func.has_name())
- {
- //If function is named
- ++number_of_names;
- needed_size_for_function_names += static_cast<uint32_t>(func.get_name().length() + 1);
-
- //Check if it's name and name ordinal are unique
- if(!used_function_names.insert(func.get_name()).second)
- throw pe_exception("Duplicate exported function name", pe_exception::duplicate_exported_function_name);
- }
-
- //If function is forwarded to another DLL
- if(func.is_forwarded())
- needed_size_for_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
- }
- }
-
- //Sort functions by ordinal value
- std::sort(exports.begin(), exports.end(), ordinal_sorter());
-
- //Calculate needed space for different things...
- needed_size_for_strings += needed_size_for_function_names;
- needed_size_for_strings += needed_size_for_function_forwards;
- uint32_t needed_size_for_function_name_ordinals = number_of_names * sizeof(uint16_t);
- uint32_t needed_size_for_function_name_rvas = number_of_names * sizeof(uint32_t);
- uint32_t needed_size_for_function_addresses = (max_ordinal - ordinal_base + 1) * sizeof(uint32_t);
-
- //Export directory header will be placed first
- uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-
- uint32_t needed_size = sizeof(image_export_directory); //Calculate needed size for export tables and strings
- //sizeof(IMAGE_EXPORT_DIRECTORY) = export directory header
-
- //Total needed space...
- needed_size += needed_size_for_function_name_ordinals; //For list of names ordinals
- needed_size += needed_size_for_function_addresses; //For function RVAs
- needed_size += needed_size_for_strings; //For all strings
- needed_size += needed_size_for_function_name_rvas; //For function name strings RVAs
-
- //Check if exports_section is last one. If it's not, check if there's enough place for exports data
- if(&exports_section != &*(pe.get_image_sections().end() - 1) &&
- (exports_section.empty() || pe_utils::align_up(exports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
- throw pe_exception("Insufficient space for export directory", pe_exception::insufficient_space);
-
- std::string& raw_data = exports_section.get_raw_data();
-
- //This will be done only if exports_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + directory_pos)
- raw_data.resize(needed_size + directory_pos); //Expand section raw data
-
- //Library name will be placed after it
- uint32_t current_pos_of_function_names = static_cast<uint32_t>(info.get_name().length() + 1 + directory_pos + sizeof(image_export_directory));
- //Next - function names
- uint32_t current_pos_of_function_name_ordinals = current_pos_of_function_names + needed_size_for_function_names;
- //Next - function name ordinals
- uint32_t current_pos_of_function_forwards = current_pos_of_function_name_ordinals + needed_size_for_function_name_ordinals;
- //Finally - function addresses
- uint32_t current_pos_of_function_addresses = current_pos_of_function_forwards + needed_size_for_function_forwards;
- //Next - function names RVAs
- uint32_t current_pos_of_function_names_rvas = current_pos_of_function_addresses + needed_size_for_function_addresses;
-
- {
- //Create export directory and fill it
- image_export_directory dir = {0};
- dir.Characteristics = info.get_characteristics();
- dir.MajorVersion = info.get_major_version();
- dir.MinorVersion = info.get_minor_version();
- dir.TimeDateStamp = info.get_timestamp();
- dir.NumberOfFunctions = max_ordinal - ordinal_base + 1;
- dir.NumberOfNames = number_of_names;
- dir.Base = ordinal_base;
- dir.AddressOfFunctions = pe.rva_from_section_offset(exports_section, current_pos_of_function_addresses);
- dir.AddressOfNameOrdinals = pe.rva_from_section_offset(exports_section, current_pos_of_function_name_ordinals);
- dir.AddressOfNames = pe.rva_from_section_offset(exports_section, current_pos_of_function_names_rvas);
- dir.Name = pe.rva_from_section_offset(exports_section, directory_pos + sizeof(image_export_directory));
-
- //Save it
- memcpy(&raw_data[directory_pos], &dir, sizeof(dir));
- }
-
- //Sve library name
- memcpy(&raw_data[directory_pos + sizeof(image_export_directory)], info.get_name().c_str(), info.get_name().length() + 1);
-
- //A map to sort function names alphabetically
- typedef std::map<std::string, uint16_t> funclist; //function name; function name ordinal
- funclist funcs;
-
- uint32_t last_ordinal = ordinal_base;
- //Enumerate all exported functions
- for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
- {
- const exported_function& func = (*it);
-
- //If we're skipping some ordinals...
- if(func.get_ordinal() > last_ordinal)
- {
- //Fill this function RVAs data with zeros
- uint32_t len = sizeof(uint32_t) * (func.get_ordinal() - last_ordinal - 1);
- if(len)
- {
- memset(&raw_data[current_pos_of_function_addresses], 0, len);
- current_pos_of_function_addresses += len;
- }
-
- //Save last encountered ordinal
- last_ordinal = func.get_ordinal();
- }
-
- //If function is named, save its name ordinal and name in sorted alphabetically order
- if(func.has_name())
- funcs.insert(std::make_pair(func.get_name(), static_cast<uint16_t>(func.get_ordinal() - ordinal_base))); //Calculate name ordinal
-
- //If function is forwarded to another DLL
- if(func.is_forwarded())
- {
- //Write its forwarded name and its RVA
- uint32_t function_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_forwards);
- memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva));
- current_pos_of_function_addresses += sizeof(function_rva);
-
- memcpy(&raw_data[current_pos_of_function_forwards], func.get_forwarded_name().c_str(), func.get_forwarded_name().length() + 1);
- current_pos_of_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
- }
- else
- {
- //Write actual function RVA
- uint32_t function_rva = func.get_rva();
- memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva));
- current_pos_of_function_addresses += sizeof(function_rva);
- }
- }
-
- //Enumerate sorted function names
- for(funclist::const_iterator it = funcs.begin(); it != funcs.end(); ++it)
- {
- //Save function name RVA
- uint32_t function_name_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_names);
- memcpy(&raw_data[current_pos_of_function_names_rvas], &function_name_rva, sizeof(function_name_rva));
- current_pos_of_function_names_rvas += sizeof(function_name_rva);
-
- //Save function name
- memcpy(&raw_data[current_pos_of_function_names], (*it).first.c_str(), (*it).first.length() + 1);
- current_pos_of_function_names += static_cast<uint32_t>((*it).first.length() + 1);
-
- //Save function name ordinal
- uint16_t name_ordinal = (*it).second;
- memcpy(&raw_data[current_pos_of_function_name_ordinals], &name_ordinal, sizeof(name_ordinal));
- current_pos_of_function_name_ordinals += sizeof(name_ordinal);
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(exports_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(exports_section, directory_pos), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_export, ret.get_rva());
- pe.set_directory_size(image_directory_entry_export, ret.get_size());
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_exports.h b/tools/pe_bliss/pe_exports.h
deleted file mode 100644
index 127cf86ed6..0000000000
--- a/tools/pe_bliss/pe_exports.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing exported function
-class exported_function
-{
-public:
- //Default constructor
- exported_function();
-
- //Returns ordinal of function (actually, ordinal = hint + ordinal base)
- uint16_t get_ordinal() const;
-
- //Returns RVA of function
- uint32_t get_rva() const;
-
- //Returns true if function has name and name ordinal
- bool has_name() const;
- //Returns name of function
- const std::string& get_name() const;
- //Returns name ordinal of function
- uint16_t get_name_ordinal() const;
-
- //Returns true if function is forwarded to other library
- bool is_forwarded() const;
- //Returns the name of forwarded function
- const std::string& get_forwarded_name() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You can also use them to rebuild export directory
-
- //Sets ordinal of function
- void set_ordinal(uint16_t ordinal);
-
- //Sets RVA of function
- void set_rva(uint32_t rva);
-
- //Sets name of function (or clears it, if empty name is passed)
- void set_name(const std::string& name);
- //Sets name ordinal
- void set_name_ordinal(uint16_t name_ordinal);
-
- //Sets forwarded function name (or clears it, if empty name is passed)
- void set_forwarded_name(const std::string& name);
-
-private:
- uint16_t ordinal_; //Function ordinal
- uint32_t rva_; //Function RVA
- std::string name_; //Function name
- bool has_name_; //true == function has name
- uint16_t name_ordinal_; //Function name ordinal
- bool forward_; //true == function is forwarded
- std::string forward_name_; //Name of forwarded function
-};
-
-//Class representing export information
-class export_info
-{
-public:
- //Default constructor
- export_info();
-
- //Returns characteristics
- uint32_t get_characteristics() const;
- //Returns timestamp
- uint32_t get_timestamp() const;
- //Returns major version
- uint16_t get_major_version() const;
- //Returns minor version
- uint16_t get_minor_version() const;
- //Returns DLL name
- const std::string& get_name() const;
- //Returns ordinal base
- uint32_t get_ordinal_base() const;
- //Returns number of functions
- uint32_t get_number_of_functions() const;
- //Returns number of function names
- uint32_t get_number_of_names() const;
- //Returns RVA of function address table
- uint32_t get_rva_of_functions() const;
- //Returns RVA of function name address table
- uint32_t get_rva_of_names() const;
- //Returns RVA of name ordinals table
- uint32_t get_rva_of_name_ordinals() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You can also use them to rebuild export directory using rebuild_exports
-
- //Sets characteristics
- void set_characteristics(uint32_t characteristics);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
- //Sets major version
- void set_major_version(uint16_t major_version);
- //Sets minor version
- void set_minor_version(uint16_t minor_version);
- //Sets DLL name
- void set_name(const std::string& name);
- //Sets ordinal base
- void set_ordinal_base(uint32_t ordinal_base);
- //Sets number of functions
- void set_number_of_functions(uint32_t number_of_functions);
- //Sets number of function names
- void set_number_of_names(uint32_t number_of_names);
- //Sets RVA of function address table
- void set_rva_of_functions(uint32_t rva_of_functions);
- //Sets RVA of function name address table
- void set_rva_of_names(uint32_t rva_of_names);
- //Sets RVA of name ordinals table
- void set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals);
-
-private:
- uint32_t characteristics_;
- uint32_t timestamp_;
- uint16_t major_version_;
- uint16_t minor_version_;
- std::string name_;
- uint32_t ordinal_base_;
- uint32_t number_of_functions_;
- uint32_t number_of_names_;
- uint32_t address_of_functions_;
- uint32_t address_of_names_;
- uint32_t address_of_name_ordinals_;
-};
-
-//Exported functions list typedef
-typedef std::vector<exported_function> exported_functions_list;
-
-//Returns array of exported functions
-const exported_functions_list get_exported_functions(const pe_base& pe);
-//Returns array of exported functions and information about export
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info);
-
-//Helper export functions
-//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions>
-const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports);
-
-//Checks if exported function name already exists
-bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports);
-
-//Checks if exported function ordinal already exists
-bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports);
-
-//Export directory rebuilder
-//info - export information
-//exported_functions_list - list of exported functions
-//exports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from exports_section raw data start
-//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
-//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
-//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
-//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
-//Returns new export directory information
-//exported_functions_list is copied intentionally to be sorted by ordinal values later
-//Name ordinals in exported function don't matter, they will be recalculated
-const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_factory.cpp b/tools/pe_bliss/pe_factory.cpp
deleted file mode 100644
index f6d8a3e1ed..0000000000
--- a/tools/pe_bliss/pe_factory.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_factory.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-pe_base pe_factory::create_pe(std::istream& file, bool read_debug_raw_data)
-{
- return pe_base::get_pe_type(file) == pe_type_32
- ? pe_base(file, pe_properties_32(), read_debug_raw_data)
- : pe_base(file, pe_properties_64(), read_debug_raw_data);
-}
-
-pe_base pe_factory::create_pe(const char* file_path, bool read_debug_raw_data)
-{
- std::ifstream pe_file(file_path, std::ios::in | std::ios::binary);
- if(!pe_file)
- {
- throw pe_exception("Error in open file.", pe_exception::stream_is_bad);
- }
- return pe_factory::create_pe(pe_file,read_debug_raw_data);
-}
-}
diff --git a/tools/pe_bliss/pe_factory.h b/tools/pe_bliss/pe_factory.h
deleted file mode 100644
index 60b42d9b71..0000000000
--- a/tools/pe_bliss/pe_factory.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include <istream>
-#include <fstream>
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-class pe_factory
-{
-public:
- //Creates pe_base class instance from PE or PE+ istream
- //If read_bound_import_raw_data, raw bound import data will be read (used to get bound import info)
- //If read_debug_raw_data, raw debug data will be read (used to get image debug info)
- static pe_base create_pe(std::istream& file, bool read_debug_raw_data = true);
- static pe_base create_pe(const char* file_path, bool read_debug_raw_data = true);
-};
-}
diff --git a/tools/pe_bliss/pe_imports.cpp b/tools/pe_bliss/pe_imports.cpp
deleted file mode 100644
index 0a6c01d6c0..0000000000
--- a/tools/pe_bliss/pe_imports.cpp
+++ /dev/null
@@ -1,777 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_imports.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//IMPORTS
-//Default constructor
-//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
-//to new value after import rebuilding
-//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
-//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
-//to be able to modify IAT thunks
-import_rebuilder_settings::import_rebuilder_settings(bool set_to_pe_headers, bool auto_zero_directory_entry_iat)
- :offset_from_section_start_(0),
- build_original_iat_(true),
- save_iat_and_original_iat_rvas_(true),
- fill_missing_original_iats_(false),
- set_to_pe_headers_(set_to_pe_headers),
- zero_directory_entry_iat_(auto_zero_directory_entry_iat),
- rewrite_iat_and_original_iat_contents_(false),
- auto_strip_last_section_(true)
-{}
-
-//Returns offset from section start where import directory data will be placed
-uint32_t import_rebuilder_settings::get_offset_from_section_start() const
-{
- return offset_from_section_start_;
-}
-
-//Returns true if Original import address table (IAT) will be rebuilt
-bool import_rebuilder_settings::build_original_iat() const
-{
- return build_original_iat_;
-}
-
-//Returns true if Original import address and import address tables will not be rebuilt,
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-bool import_rebuilder_settings::save_iat_and_original_iat_rvas() const
-{
- return save_iat_and_original_iat_rvas_;
-}
-
-//Returns true if Original import address and import address tables contents will be rewritten
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-//and save_iat_and_original_iat_rvas is true
-bool import_rebuilder_settings::rewrite_iat_and_original_iat_contents() const
-{
- return rewrite_iat_and_original_iat_contents_;
-}
-
-//Returns true if original missing IATs will be rebuilt
-//(only if IATs are saved)
-bool import_rebuilder_settings::fill_missing_original_iats() const
-{
- return fill_missing_original_iats_;
-}
-
-//Returns true if PE headers should be updated automatically after rebuilding of imports
-bool import_rebuilder_settings::auto_set_to_pe_headers() const
-{
- return set_to_pe_headers_;
-}
-
-//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-bool import_rebuilder_settings::zero_directory_entry_iat() const
-{
- return zero_directory_entry_iat_;
-}
-
-//Returns true if the last section should be stripped automatically, if imports are inside it
-bool import_rebuilder_settings::auto_strip_last_section_enabled() const
-{
- return auto_strip_last_section_;
-}
-
-//Sets offset from section start where import directory data will be placed
-void import_rebuilder_settings::set_offset_from_section_start(uint32_t offset)
-{
- offset_from_section_start_ = offset;
-}
-
-//Sets if Original import address table (IAT) will be rebuilt
-void import_rebuilder_settings::build_original_iat(bool enable)
-{
- build_original_iat_ = enable;
-}
-
-//Sets if Original import address and import address tables will not be rebuilt,
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-void import_rebuilder_settings::save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents)
-{
- save_iat_and_original_iat_rvas_ = enable;
- if(save_iat_and_original_iat_rvas_)
- rewrite_iat_and_original_iat_contents_ = enable_rewrite_iat_and_original_iat_contents;
- else
- rewrite_iat_and_original_iat_contents_ = false;
-}
-
-//Sets if original missing IATs will be rebuilt
-//(only if IATs are saved)
-void import_rebuilder_settings::fill_missing_original_iats(bool enable)
-{
- fill_missing_original_iats_ = enable;
-}
-
-//Sets if PE headers should be updated automatically after rebuilding of imports
-void import_rebuilder_settings::auto_set_to_pe_headers(bool enable)
-{
- set_to_pe_headers_ = enable;
-}
-
-//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-void import_rebuilder_settings::zero_directory_entry_iat(bool enable)
-{
- zero_directory_entry_iat_ = enable;
-}
-
-//Sets if the last section should be stripped automatically, if imports are inside it, default true
-void import_rebuilder_settings::enable_auto_strip_last_section(bool enable)
-{
- auto_strip_last_section_ = enable;
-}
-
-//Default constructor
-imported_function::imported_function()
- :hint_(0), ordinal_(0), iat_va_(0)
-{}
-
-//Returns name of function
-const std::string& imported_function::get_name() const
-{
- return name_;
-}
-
-//Returns true if imported function has name (and hint)
-bool imported_function::has_name() const
-{
- return !name_.empty();
-}
-
-//Returns hint
-uint16_t imported_function::get_hint() const
-{
- return hint_;
-}
-
-//Returns ordinal of function
-uint16_t imported_function::get_ordinal() const
-{
- return ordinal_;
-}
-
-//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
-uint64_t imported_function::get_iat_va() const
-{
- return iat_va_;
-}
-
-//Sets name of function
-void imported_function::set_name(const std::string& name)
-{
- name_ = name;
-}
-
-//Sets hint
-void imported_function::set_hint(uint16_t hint)
-{
- hint_ = hint;
-}
-
-//Sets ordinal
-void imported_function::set_ordinal(uint16_t ordinal)
-{
- ordinal_ = ordinal;
-}
-
-//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
-void imported_function::set_iat_va(uint64_t va)
-{
- iat_va_ = va;
-}
-
-//Default constructor
-import_library::import_library()
- :rva_to_iat_(0), rva_to_original_iat_(0), timestamp_(0)
-{}
-
-//Returns name of library
-const std::string& import_library::get_name() const
-{
- return name_;
-}
-
-//Returns RVA to Import Address Table (IAT)
-uint32_t import_library::get_rva_to_iat() const
-{
- return rva_to_iat_;
-}
-
-//Returns RVA to Original Import Address Table (Original IAT)
-uint32_t import_library::get_rva_to_original_iat() const
-{
- return rva_to_original_iat_;
-}
-
-//Returns timestamp
-uint32_t import_library::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Sets name of library
-void import_library::set_name(const std::string& name)
-{
- name_ = name;
-}
-
-//Sets RVA to Import Address Table (IAT)
-void import_library::set_rva_to_iat(uint32_t rva_to_iat)
-{
- rva_to_iat_ = rva_to_iat;
-}
-
-//Sets RVA to Original Import Address Table (Original IAT)
-void import_library::set_rva_to_original_iat(uint32_t rva_to_original_iat)
-{
- rva_to_original_iat_ = rva_to_original_iat;
-}
-
-//Sets timestamp
-void import_library::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Returns imported functions list
-const import_library::imported_list& import_library::get_imported_functions() const
-{
- return imports_;
-}
-
-//Adds imported function
-void import_library::add_import(const imported_function& func)
-{
- imports_.push_back(func);
-}
-
-//Clears imported functions list
-void import_library::clear_imports()
-{
- imports_.clear();
-}
-
-const imported_functions_list get_imported_functions(const pe_base& pe)
-{
- return (pe.get_pe_type() == pe_type_32 ?
- get_imported_functions_base<pe_types_class_32>(pe)
- : get_imported_functions_base<pe_types_class_64>(pe));
-}
-
-const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings)
-{
- return (pe.get_pe_type() == pe_type_32 ?
- rebuild_imports_base<pe_types_class_32>(pe, imports, import_section, import_settings)
- : rebuild_imports_base<pe_types_class_64>(pe, imports, import_section, import_settings));
-}
-
-//Returns imported functions list with related libraries info
-template<typename PEClassType>
-const imported_functions_list get_imported_functions_base(const pe_base& pe)
-{
- imported_functions_list ret;
-
- //If image has no imports, return empty array
- if(!pe.has_imports())
- return ret;
-
- unsigned long current_descriptor_pos = pe.get_directory_rva(image_directory_entry_import);
- //Get first IMAGE_IMPORT_DESCRIPTOR
- image_import_descriptor import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true);
-
- //Iterate them until we reach zero-element
- //We don't need to check correctness of this, because exception will be thrown
- //inside of loop if we go outsize of section
- while(import_descriptor.Name)
- {
- //Get imported library information
- import_library lib;
-
- unsigned long max_name_length;
- //Get byte count that we have for library name
- if((max_name_length = pe.section_data_length_from_rva(import_descriptor.Name, import_descriptor.Name, section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Get DLL name pointer
- const char* dll_name = pe.section_data_from_rva(import_descriptor.Name, section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(dll_name, max_name_length))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Set library name
- lib.set_name(dll_name);
- //Set library timestamp
- lib.set_timestamp(import_descriptor.TimeDateStamp);
- //Set library RVA to IAT and original IAT
- lib.set_rva_to_iat(import_descriptor.FirstThunk);
- lib.set_rva_to_original_iat(import_descriptor.OriginalFirstThunk);
-
- //Get RVA to IAT (it must be filled by loader when loading PE)
- uint32_t current_thunk_rva = import_descriptor.FirstThunk;
- typename PEClassType::BaseSize import_address_table = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true);
-
- //Get RVA to original IAT (lookup table), which must handle imported functions names
- //Some linkers leave this pointer zero-filled
- //Such image is valid, but it is not possible to restore imported functions names
- //afted image was loaded, because IAT becomes the only one table
- //containing both function names and function RVAs after loading
- uint32_t current_original_thunk_rva = import_descriptor.OriginalFirstThunk;
- typename PEClassType::BaseSize import_lookup_table = current_original_thunk_rva == 0 ? import_address_table : pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true);
- if(current_original_thunk_rva == 0)
- current_original_thunk_rva = current_thunk_rva;
-
- //List all imported functions for current DLL
- if(import_lookup_table != 0 && import_address_table != 0)
- {
- while(true)
- {
- //Imported function description
- imported_function func;
-
- //Get VA from IAT
- typename PEClassType::BaseSize address = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true);
- //Move pointer
- current_thunk_rva += sizeof(typename PEClassType::BaseSize);
-
- //Jump to next DLL if we finished with this one
- if(!address)
- break;
-
- func.set_iat_va(address);
-
- //Get VA from original IAT
- typename PEClassType::BaseSize lookup = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true);
- //Move pointer
- current_original_thunk_rva += sizeof(typename PEClassType::BaseSize);
-
- //Check if function is imported by ordinal
- if((lookup & PEClassType::ImportSnapFlag) != 0)
- {
- //Set function ordinal
- func.set_ordinal(static_cast<uint16_t>(lookup & 0xffff));
- }
- else
- {
- //Get byte count that we have for function name
- if(lookup > static_cast<uint32_t>(-1) - sizeof(uint16_t))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Get maximum available length of function name
- if((max_name_length = pe.section_data_length_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true)) < 2)
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Get imported function name
- const char* func_name = pe.section_data_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true);
-
- //Check for null-termination
- if(!pe_utils::is_null_terminated(func_name, max_name_length))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //HINT in import table is ORDINAL in export table
- uint16_t hint = pe.section_data_from_rva<uint16_t>(static_cast<uint32_t>(lookup), section_data_virtual, true);
-
- //Save hint and name
- func.set_name(func_name);
- func.set_hint(hint);
- }
-
- //Add function to list
- lib.add_import(func);
- }
- }
-
- //Check possible overflow
- if(!pe_utils::is_sum_safe(current_descriptor_pos, sizeof(image_import_descriptor)))
- throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
- //Go to next library
- current_descriptor_pos += sizeof(image_import_descriptor);
- import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true);
-
- //Save import information
- ret.push_back(lib);
- }
-
- //Return resulting list
- return ret;
-}
-
-
-//Simple import directory rebuilder
-//You can get all image imports with get_imported_functions() function
-//You can use returned value to, for example, add new imported library with some functions
-//to the end of list of imported libraries
-//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
-//Don't add new imported functions to existing imported library entries, because this can cause
-//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
-//The safest way is just adding import libraries with functions to the end of imported_functions_list array
-template<typename PEClassType>
-const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings)
-{
- //Check that import_section is attached to this PE image
- if(!pe.section_attached(import_section))
- throw pe_exception("Import section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t needed_size = 0; //Calculate needed size for import structures and strings
- uint32_t needed_size_for_strings = 0; //Calculate needed size for import strings (library and function names and hints)
- uint32_t size_of_iat = 0; //Size of IAT structures
-
- needed_size += static_cast<uint32_t>((1 /* ending null descriptor */ + imports.size()) * sizeof(image_import_descriptor));
-
- //Enumerate imported functions
- for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- needed_size_for_strings += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */);
-
- const import_library::imported_list& funcs = (*it).get_imported_functions();
-
- //IMAGE_THUNK_DATA
- size_of_iat += static_cast<uint32_t>(sizeof(typename PEClassType::BaseSize) * (1 /*ending null */ + funcs.size()));
-
- //Enumerate all imported functions in library
- for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f)
- {
- if((*f).has_name())
- needed_size_for_strings += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */);
- }
- }
-
- if(import_settings.build_original_iat() || import_settings.fill_missing_original_iats())
- needed_size += size_of_iat * 2; //We'll have two similar-sized IATs if we're building original IAT
- else
- needed_size += size_of_iat;
-
- needed_size += sizeof(typename PEClassType::BaseSize); //Maximum align for IAT and original IAT
-
- //Total needed size for import structures and strings
- needed_size += needed_size_for_strings;
-
- //Check if import_section is last one. If it's not, check if there's enough place for import data
- if(&import_section != &*(pe.get_image_sections().end() - 1) &&
- (import_section.empty() || pe_utils::align_up(import_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + import_settings.get_offset_from_section_start()))
- throw pe_exception("Insufficient space for import directory", pe_exception::insufficient_space);
-
- std::string& raw_data = import_section.get_raw_data();
-
- //This will be done only if image_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + import_settings.get_offset_from_section_start())
- raw_data.resize(needed_size + import_settings.get_offset_from_section_start()); //Expand section raw data
-
- uint32_t current_string_pointer = import_settings.get_offset_from_section_start();/* we will paste structures after strings */
-
- //Position for IAT
- uint32_t current_pos_for_iat = pe_utils::align_up(static_cast<uint32_t>(needed_size_for_strings + import_settings.get_offset_from_section_start() + (1 + imports.size()) * sizeof(image_import_descriptor)), sizeof(typename PEClassType::BaseSize));
- //Position for original IAT
- uint32_t current_pos_for_original_iat = current_pos_for_iat + size_of_iat;
- //Position for import descriptors
- uint32_t current_pos_for_descriptors = needed_size_for_strings + import_settings.get_offset_from_section_start();
-
- //Build imports
- for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
- {
- //Create import descriptor
- image_import_descriptor descr;
- memset(&descr, 0, sizeof(descr));
- descr.TimeDateStamp = (*it).get_timestamp(); //Restore timestamp
- descr.Name = pe.rva_from_section_offset(import_section, current_string_pointer); //Library name RVA
-
- //If we should save IAT for current import descriptor
- bool save_iats_for_this_descriptor = import_settings.save_iat_and_original_iat_rvas() && (*it).get_rva_to_iat() != 0;
- //If we should write original IAT
- bool write_original_iat = (!save_iats_for_this_descriptor && import_settings.build_original_iat()) || import_settings.fill_missing_original_iats();
-
- //If we should rewrite saved original IAT for current import descriptor (without changing its position)
- bool rewrite_saved_original_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && import_settings.build_original_iat();
- //If we should rewrite saved IAT for current import descriptor (without changing its position)
- bool rewrite_saved_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && (*it).get_rva_to_iat() != 0;
-
- //Helper values if we're rewriting existing IAT or orig.IAT
- uint32_t original_first_thunk = 0;
- uint32_t first_thunk = 0;
-
- if(save_iats_for_this_descriptor)
- {
- //If there's no original IAT and we're asked to rebuild missing original IATs
- if(!(*it).get_rva_to_original_iat() && import_settings.fill_missing_original_iats())
- descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0;
- else
- descr.OriginalFirstThunk = import_settings.build_original_iat() ? (*it).get_rva_to_original_iat() : 0;
-
- descr.FirstThunk = (*it).get_rva_to_iat();
-
- original_first_thunk = descr.OriginalFirstThunk;
- first_thunk = descr.FirstThunk;
-
- if(rewrite_saved_original_iat)
- {
- if((*it).get_rva_to_original_iat())
- write_original_iat = true;
- else
- rewrite_saved_original_iat = false;
- }
-
- if(rewrite_saved_iat)
- save_iats_for_this_descriptor = false;
- }
- else
- {
- //We are creating new IAT and original IAT (if needed)
- descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0;
- descr.FirstThunk = pe.rva_from_section_offset(import_section, current_pos_for_iat);
- }
-
- //Save import descriptor
- memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr));
- current_pos_for_descriptors += sizeof(descr);
-
- //Save library name
- memcpy(&raw_data[current_string_pointer], (*it).get_name().c_str(), (*it).get_name().length() + 1 /* nullbyte */);
- current_string_pointer += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */);
-
- //List all imported functions
- const import_library::imported_list& funcs = (*it).get_imported_functions();
- for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f)
- {
- if((*f).has_name()) //If function is imported by name
- {
- //Get RVA of IMAGE_IMPORT_BY_NAME
- typename PEClassType::BaseSize rva_of_named_import = pe.rva_from_section_offset(import_section, current_string_pointer);
-
- if(!save_iats_for_this_descriptor)
- {
- if(write_original_iat)
- {
- //We're creating original IATs - so we can write to IAT saved VA (because IMAGE_IMPORT_BY_NAME will be read
- //by PE loader from original IAT)
- typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va());
-
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value));
-
- first_thunk += sizeof(iat_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value));
- current_pos_for_iat += sizeof(rva_of_named_import);
- }
- }
- else
- {
- //Else - write to IAT RVA of IMAGE_IMPORT_BY_NAME
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import));
-
- first_thunk += sizeof(rva_of_named_import);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &rva_of_named_import, sizeof(rva_of_named_import));
- current_pos_for_iat += sizeof(rva_of_named_import);
- }
- }
- }
-
- if(write_original_iat)
- {
- if(rewrite_saved_original_iat)
- {
- if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import))
- throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(original_first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import));
-
- original_first_thunk += sizeof(rva_of_named_import);
- }
- else
- {
- //We're creating original IATs
- memcpy(&raw_data[current_pos_for_original_iat], &rva_of_named_import, sizeof(rva_of_named_import));
- current_pos_for_original_iat += sizeof(rva_of_named_import);
- }
- }
-
- //Write IMAGE_IMPORT_BY_NAME (WORD hint + string function name)
- uint16_t hint = (*f).get_hint();
- memcpy(&raw_data[current_string_pointer], &hint, sizeof(hint));
- memcpy(&raw_data[current_string_pointer + sizeof(uint16_t)], (*f).get_name().c_str(), (*f).get_name().length() + 1 /* nullbyte */);
- current_string_pointer += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */);
- }
- else //Function is imported by ordinal
- {
- uint16_t ordinal = (*f).get_ordinal();
- typename PEClassType::BaseSize thunk_value = ordinal;
- thunk_value |= PEClassType::ImportSnapFlag; //Imported by ordinal
-
- if(!save_iats_for_this_descriptor)
- {
- if(write_original_iat)
- {
- //We're creating original IATs - so we can wtire to IAT saved VA (because ordinal will be read
- //by PE loader from original IAT)
- typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va());
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value));
-
- first_thunk += sizeof(iat_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value));
- current_pos_for_iat += sizeof(thunk_value);
- }
- }
- else
- {
- //Else - write ordinal to IAT
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value));
- }
- }
- }
-
- //We're writing ordinal to original IAT slot
- if(write_original_iat)
- {
- if(rewrite_saved_original_iat)
- {
- if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- original_first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value));
- current_pos_for_original_iat += sizeof(thunk_value);
- }
- }
- }
- }
-
- if(!save_iats_for_this_descriptor)
- {
- //Ending null thunks
- typename PEClassType::BaseSize thunk_value = 0;
-
- if(rewrite_saved_iat)
- {
- if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value));
- current_pos_for_iat += sizeof(thunk_value);
- }
- }
-
- if(write_original_iat)
- {
- //Ending null thunks
- typename PEClassType::BaseSize thunk_value = 0;
-
- if(rewrite_saved_original_iat)
- {
- if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value))
- throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
- memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value));
-
- original_first_thunk += sizeof(thunk_value);
- }
- else
- {
- memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value));
- current_pos_for_original_iat += sizeof(thunk_value);
- }
- }
- }
-
- {
- //Null ending descriptor
- image_import_descriptor descr;
- memset(&descr, 0, sizeof(descr));
- memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr));
- }
-
- //Strip data a little, if we saved some place
- //We're allocating more space than needed, if present original IAT and IAT are saved
- raw_data.resize(current_pos_for_original_iat);
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(import_section, import_settings.auto_strip_last_section_enabled());
-
- //Return information about rebuilt import directory
- image_directory ret(pe.rva_from_section_offset(import_section, import_settings.get_offset_from_section_start() + needed_size_for_strings), needed_size - needed_size_for_strings);
-
- //If auto-rewrite of PE headers is required
- if(import_settings.auto_set_to_pe_headers())
- {
- pe.set_directory_rva(image_directory_entry_import, ret.get_rva());
- pe.set_directory_size(image_directory_entry_import, ret.get_size());
-
- //If we are requested to zero IMAGE_DIRECTORY_ENTRY_IAT also
- if(import_settings.zero_directory_entry_iat())
- {
- pe.set_directory_rva(image_directory_entry_iat, 0);
- pe.set_directory_size(image_directory_entry_iat, 0);
- }
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_imports.h b/tools/pe_bliss/pe_imports.h
deleted file mode 100644
index 681b5b59bd..0000000000
--- a/tools/pe_bliss/pe_imports.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_directory.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing imported function
-class imported_function
-{
-public:
- //Default constructor
- imported_function();
-
- //Returns true if imported function has name (and hint)
- bool has_name() const;
- //Returns name of function
- const std::string& get_name() const;
- //Returns hint
- uint16_t get_hint() const;
- //Returns ordinal of function
- uint16_t get_ordinal() const;
-
- //Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
- uint64_t get_iat_va() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You also can use them to rebuild image imports
- //Sets name of function
- void set_name(const std::string& name);
- //Sets hint
- void set_hint(uint16_t hint);
- //Sets ordinal
- void set_ordinal(uint16_t ordinal);
-
- //Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
- void set_iat_va(uint64_t rva);
-
-private:
- std::string name_; //Function name
- uint16_t hint_; //Hint
- uint16_t ordinal_; //Ordinal
- uint64_t iat_va_;
-};
-
-//Class representing imported library information
-class import_library
-{
-public:
- typedef std::vector<imported_function> imported_list;
-
-public:
- //Default constructor
- import_library();
-
- //Returns name of library
- const std::string& get_name() const;
- //Returns RVA to Import Address Table (IAT)
- uint32_t get_rva_to_iat() const;
- //Returns RVA to Original Import Address Table (Original IAT)
- uint32_t get_rva_to_original_iat() const;
- //Returns timestamp
- uint32_t get_timestamp() const;
-
- //Returns imported functions list
- const imported_list& get_imported_functions() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You also can use them to rebuild image imports
- //Sets name of library
- void set_name(const std::string& name);
- //Sets RVA to Import Address Table (IAT)
- void set_rva_to_iat(uint32_t rva_to_iat);
- //Sets RVA to Original Import Address Table (Original IAT)
- void set_rva_to_original_iat(uint32_t rva_to_original_iat);
- //Sets timestamp
- void set_timestamp(uint32_t timestamp);
-
- //Adds imported function
- void add_import(const imported_function& func);
- //Clears imported functions list
- void clear_imports();
-
-private:
- std::string name_; //Library name
- uint32_t rva_to_iat_; //RVA to IAT
- uint32_t rva_to_original_iat_; //RVA to original IAT
- uint32_t timestamp_; //DLL TimeStamp
-
- imported_list imports_;
-};
-
-//Simple import directory rebuilder
-//Class representing import rebuilder advanced settings
-class import_rebuilder_settings
-{
-public:
- //Default constructor
- //Default constructor
- //If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
- //to new value after import rebuilding
- //If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
- //IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
- //to be able to modify IAT thunks
- explicit import_rebuilder_settings(bool set_to_pe_headers = true, bool auto_zero_directory_entry_iat = false);
-
- //Returns offset from section start where import directory data will be placed
- uint32_t get_offset_from_section_start() const;
- //Returns true if Original import address table (IAT) will be rebuilt
- bool build_original_iat() const;
-
- //Returns true if Original import address and import address tables will not be rebuilt,
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- bool save_iat_and_original_iat_rvas() const;
- //Returns true if Original import address and import address tables contents will be rewritten
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- //and save_iat_and_original_iat_rvas is true
- bool rewrite_iat_and_original_iat_contents() const;
-
- //Returns true if original missing IATs will be rebuilt
- //(only if IATs are saved)
- bool fill_missing_original_iats() const;
- //Returns true if PE headers should be updated automatically after rebuilding of imports
- bool auto_set_to_pe_headers() const;
- //Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
- bool zero_directory_entry_iat() const;
-
- //Returns true if the last section should be stripped automatically, if imports are inside it
- bool auto_strip_last_section_enabled() const;
-
-public: //Setters
- //Sets offset from section start where import directory data will be placed
- void set_offset_from_section_start(uint32_t offset);
- //Sets if Original import address table (IAT) will be rebuilt
- void build_original_iat(bool enable);
- //Sets if Original import address and import address tables will not be rebuilt,
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- //enable_rewrite_iat_and_original_iat_contents sets if Original import address and import address tables contents will be rewritten
- //works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
- //and save_iat_and_original_iat_rvas is true
- void save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents = false);
- //Sets if original missing IATs will be rebuilt
- //(only if IATs are saved)
- void fill_missing_original_iats(bool enable);
- //Sets if PE headers should be updated automatically after rebuilding of imports
- void auto_set_to_pe_headers(bool enable);
- //Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
- void zero_directory_entry_iat(bool enable);
-
- //Sets if the last section should be stripped automatically, if imports are inside it, default true
- void enable_auto_strip_last_section(bool enable);
-
-private:
- uint32_t offset_from_section_start_;
- bool build_original_iat_;
- bool save_iat_and_original_iat_rvas_;
- bool fill_missing_original_iats_;
- bool set_to_pe_headers_;
- bool zero_directory_entry_iat_;
- bool rewrite_iat_and_original_iat_contents_;
- bool auto_strip_last_section_;
-};
-
-typedef std::vector<import_library> imported_functions_list;
-
-
-//Returns imported functions list with related libraries info
-const imported_functions_list get_imported_functions(const pe_base& pe);
-
-template<typename PEClassType>
-const imported_functions_list get_imported_functions_base(const pe_base& pe);
-
-
-//You can get all image imports with get_imported_functions() function
-//You can use returned value to, for example, add new imported library with some functions
-//to the end of list of imported libraries
-//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
-//Don't add new imported functions to existing imported library entries, because this can cause
-//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
-//The safest way is just adding import libraries with functions to the end of imported_functions_list array
-const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
-
-template<typename PEClassType>
-const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
-}
diff --git a/tools/pe_bliss/pe_load_config.cpp b/tools/pe_bliss/pe_load_config.cpp
deleted file mode 100644
index c05895fecd..0000000000
--- a/tools/pe_bliss/pe_load_config.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_load_config.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//IMAGE CONFIG
-//Default constructor
-image_config_info::image_config_info()
- :time_stamp_(0),
- major_version_(0), minor_version_(0),
- global_flags_clear_(0), global_flags_set_(0),
- critical_section_default_timeout_(0),
- decommit_free_block_threshold_(0), decommit_total_free_threshold_(0),
- lock_prefix_table_va_(0),
- max_allocation_size_(0),
- virtual_memory_threshold_(0),
- process_affinity_mask_(0),
- process_heap_flags_(0),
- service_pack_version_(0),
- edit_list_va_(0),
- security_cookie_va_(0),
- se_handler_table_va_(0),
- se_handler_count_(0)
-{}
-
-//Constructors from PE structures
-template<typename ConfigStructure>
-image_config_info::image_config_info(const ConfigStructure& info)
- :time_stamp_(info.TimeDateStamp),
- major_version_(info.MajorVersion), minor_version_(info.MinorVersion),
- global_flags_clear_(info.GlobalFlagsClear), global_flags_set_(info.GlobalFlagsSet),
- critical_section_default_timeout_(info.CriticalSectionDefaultTimeout),
- decommit_free_block_threshold_(info.DeCommitFreeBlockThreshold), decommit_total_free_threshold_(info.DeCommitTotalFreeThreshold),
- lock_prefix_table_va_(info.LockPrefixTable),
- max_allocation_size_(info.MaximumAllocationSize),
- virtual_memory_threshold_(info.VirtualMemoryThreshold),
- process_affinity_mask_(info.ProcessAffinityMask),
- process_heap_flags_(info.ProcessHeapFlags),
- service_pack_version_(info.CSDVersion),
- edit_list_va_(info.EditList),
- security_cookie_va_(info.SecurityCookie),
- se_handler_table_va_(info.SEHandlerTable),
- se_handler_count_(info.SEHandlerCount)
-{}
-
-//Instantiate template constructor with needed structures
-template image_config_info::image_config_info(const image_load_config_directory32& info);
-template image_config_info::image_config_info(const image_load_config_directory64& info);
-
-//Returns the date and time stamp value
-uint32_t image_config_info::get_time_stamp() const
-{
- return time_stamp_;
-}
-
-//Returns major version number
-uint16_t image_config_info::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version number
-uint16_t image_config_info::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns clear global flags
-uint32_t image_config_info::get_global_flags_clear() const
-{
- return global_flags_clear_;
-}
-
-//Returns set global flags
-uint32_t image_config_info::get_global_flags_set() const
-{
- return global_flags_set_;
-}
-
-//Returns critical section default timeout
-uint32_t image_config_info::get_critical_section_default_timeout() const
-{
- return critical_section_default_timeout_;
-}
-
-//Get the size of the minimum block that
-//must be freed before it is freed (de-committed), in bytes
-uint64_t image_config_info::get_decommit_free_block_threshold() const
-{
- return decommit_free_block_threshold_;
-}
-
-//Returns the size of the minimum total memory
-//that must be freed in the process heap before it is freed (de-committed), in bytes
-uint64_t image_config_info::get_decommit_total_free_threshold() const
-{
- return decommit_total_free_threshold_;
-}
-
-//Returns VA of a list of addresses where the LOCK prefix is used
-uint64_t image_config_info::get_lock_prefix_table_va() const
-{
- return lock_prefix_table_va_;
-}
-
-//Returns the maximum allocation size, in bytes
-uint64_t image_config_info::get_max_allocation_size() const
-{
- return max_allocation_size_;
-}
-
-//Returns the maximum block size that can be allocated from heap segments, in bytes
-uint64_t image_config_info::get_virtual_memory_threshold() const
-{
- return virtual_memory_threshold_;
-}
-
-//Returns process affinity mask
-uint64_t image_config_info::get_process_affinity_mask() const
-{
- return process_affinity_mask_;
-}
-
-//Returns process heap flags
-uint32_t image_config_info::get_process_heap_flags() const
-{
- return process_heap_flags_;
-}
-
-//Returns service pack version (CSDVersion)
-uint16_t image_config_info::get_service_pack_version() const
-{
- return service_pack_version_;
-}
-
-//Returns VA of edit list (reserved by system)
-uint64_t image_config_info::get_edit_list_va() const
-{
- return edit_list_va_;
-}
-
-//Returns a pointer to a cookie that is used by Visual C++ or GS implementation
-uint64_t image_config_info::get_security_cookie_va() const
-{
- return security_cookie_va_;
-}
-
-//Returns VA of the sorted table of RVAs of each valid, unique handler in the image
-uint64_t image_config_info::get_se_handler_table_va() const
-{
- return se_handler_table_va_;
-}
-
-//Returns the count of unique handlers in the table
-uint64_t image_config_info::get_se_handler_count() const
-{
- return se_handler_count_;
-}
-
-//Returns SE Handler RVA list
-const image_config_info::se_handler_list& image_config_info::get_se_handler_rvas() const
-{
- return se_handlers_;
-}
-
-//Returns Lock Prefix RVA list
-const image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas() const
-{
- return lock_prefixes_;
-}
-
-//Adds SE Handler RVA to list
-void image_config_info::add_se_handler_rva(uint32_t rva)
-{
- se_handlers_.push_back(rva);
-}
-
-//Clears SE Handler list
-void image_config_info::clear_se_handler_list()
-{
- se_handlers_.clear();
-}
-
-//Adds Lock Prefix RVA to list
-void image_config_info::add_lock_prefix_rva(uint32_t rva)
-{
- lock_prefixes_.push_back(rva);
-}
-
-//Clears Lock Prefix list
-void image_config_info::clear_lock_prefix_list()
-{
- lock_prefixes_.clear();
-}
-
-//Sets the date and time stamp value
-void image_config_info::set_time_stamp(uint32_t time_stamp)
-{
- time_stamp_ = time_stamp;
-}
-
-//Sets major version number
-void image_config_info::set_major_version(uint16_t major_version)
-{
- major_version_ = major_version;
-}
-
-//Sets minor version number
-void image_config_info::set_minor_version(uint16_t minor_version)
-{
- minor_version_ = minor_version;
-}
-
-//Sets clear global flags
-void image_config_info::set_global_flags_clear(uint32_t global_flags_clear)
-{
- global_flags_clear_ = global_flags_clear;
-}
-
-//Sets set global flags
-void image_config_info::set_global_flags_set(uint32_t global_flags_set)
-{
- global_flags_set_ = global_flags_set;
-}
-
-//Sets critical section default timeout
-void image_config_info::set_critical_section_default_timeout(uint32_t critical_section_default_timeout)
-{
- critical_section_default_timeout_ = critical_section_default_timeout;
-}
-
-//Sets the size of the minimum block that
-//must be freed before it is freed (de-committed), in bytes
-void image_config_info::set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold)
-{
- decommit_free_block_threshold_ = decommit_free_block_threshold;
-}
-
-//Sets the size of the minimum total memory
-//that must be freed in the process heap before it is freed (de-committed), in bytes
-void image_config_info::set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold)
-{
- decommit_total_free_threshold_ = decommit_total_free_threshold;
-}
-
-//Sets VA of a list of addresses where the LOCK prefix is used
-//If you rebuild this list, VA will be re-assigned automatically
-void image_config_info::set_lock_prefix_table_va(uint64_t lock_prefix_table_va)
-{
- lock_prefix_table_va_ = lock_prefix_table_va;
-}
-
-//Sets the maximum allocation size, in bytes
-void image_config_info::set_max_allocation_size(uint64_t max_allocation_size)
-{
- max_allocation_size_ = max_allocation_size;
-}
-
-//Sets the maximum block size that can be allocated from heap segments, in bytes
-void image_config_info::set_virtual_memory_threshold(uint64_t virtual_memory_threshold)
-{
- virtual_memory_threshold_ = virtual_memory_threshold;
-}
-
-//Sets process affinity mask
-void image_config_info::set_process_affinity_mask(uint64_t process_affinity_mask)
-{
- process_affinity_mask_ = process_affinity_mask;
-}
-
-//Sets process heap flags
-void image_config_info::set_process_heap_flags(uint32_t process_heap_flags)
-{
- process_heap_flags_ = process_heap_flags;
-}
-
-//Sets service pack version (CSDVersion)
-void image_config_info::set_service_pack_version(uint16_t service_pack_version)
-{
- service_pack_version_ = service_pack_version;
-}
-
-//Sets VA of edit list (reserved by system)
-void image_config_info::set_edit_list_va(uint64_t edit_list_va)
-{
- edit_list_va_ = edit_list_va;
-}
-
-//Sets a pointer to a cookie that is used by Visual C++ or GS implementation
-void image_config_info::set_security_cookie_va(uint64_t security_cookie_va)
-{
- security_cookie_va_ = security_cookie_va;
-}
-
-//Sets VA of the sorted table of RVAs of each valid, unique handler in the image
-//If you rebuild this list, VA will be re-assigned automatically
-void image_config_info::set_se_handler_table_va(uint64_t se_handler_table_va)
-{
- se_handler_table_va_ = se_handler_table_va;
-}
-
-//Returns SE Handler RVA list
-image_config_info::se_handler_list& image_config_info::get_se_handler_rvas()
-{
- return se_handlers_;
-}
-
-//Returns Lock Prefix RVA list
-image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas()
-{
- return lock_prefixes_;
-}
-
-//Returns image config info
-//If image does not have config info, throws an exception
-const image_config_info get_image_config(const pe_base& pe)
-{
- return pe.get_pe_type() == pe_type_32
- ? get_image_config_base<pe_types_class_32>(pe)
- : get_image_config_base<pe_types_class_64>(pe);
-}
-
-//Image config rebuilder
-const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
-{
- return pe.get_pe_type() == pe_type_32
- ? rebuild_image_config_base<pe_types_class_32>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section)
- : rebuild_image_config_base<pe_types_class_64>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section);
-}
-
-
-//Returns image config info
-//If image does not have config info, throws an exception
-template<typename PEClassType>
-const image_config_info get_image_config_base(const pe_base& pe)
-{
- //Check if image has config directory
- if(!pe.has_config())
- throw pe_exception("Image does not have load config directory", pe_exception::directory_does_not_exist);
-
- //Get load config structure
- typename PEClassType::ConfigStruct config_info = pe.section_data_from_rva<typename PEClassType::ConfigStruct>(pe.get_directory_rva(image_directory_entry_load_config), section_data_virtual);
-
- //Check size of config directory
- if(config_info.Size != sizeof(config_info))
- throw pe_exception("Incorrect (or old) load config directory", pe_exception::incorrect_config_directory);
-
- //Fill return structure
- image_config_info ret(config_info);
-
- //Check possible overflow
- if(config_info.SEHandlerCount >= pe_utils::max_dword / sizeof(uint32_t)
- || config_info.SEHandlerTable >= static_cast<typename PEClassType::BaseSize>(-1) - config_info.SEHandlerCount * sizeof(uint32_t))
- throw pe_exception("Incorrect load config directory", pe_exception::incorrect_config_directory);
-
- //Read sorted SE handler RVA list (if any)
- for(typename PEClassType::BaseSize i = 0; i != config_info.SEHandlerCount; ++i)
- ret.add_se_handler_rva(pe.section_data_from_va<uint32_t>(static_cast<typename PEClassType::BaseSize>(config_info.SEHandlerTable + i * sizeof(uint32_t))));
-
- if(config_info.LockPrefixTable)
- {
- //Read Lock Prefix VA list (if any)
- unsigned long current = 0;
- while(true)
- {
- typename PEClassType::BaseSize lock_prefix_va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(config_info.LockPrefixTable + current * sizeof(typename PEClassType::BaseSize)));
- if(!lock_prefix_va)
- break;
-
- ret.add_lock_prefix_rva(pe.va_to_rva(lock_prefix_va));
-
- ++current;
- }
- }
-
- return ret;
-}
-
-//Image config directory rebuilder
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure
-//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure
-template<typename PEClassType>
-const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that image_config_section is attached to this PE image
- if(!pe.section_attached(image_config_section))
- throw pe_exception("Image Config section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t alignment = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)) - offset_from_section_start;
-
- uint32_t needed_size = sizeof(typename PEClassType::ConfigStruct); //Calculate needed size for Image Config table
-
- uint32_t image_config_data_pos = offset_from_section_start + alignment;
-
- uint32_t current_pos_of_se_handlers = 0;
- uint32_t current_pos_of_lock_prefixes = 0;
-
- if(write_se_handlers)
- {
- current_pos_of_se_handlers = needed_size + image_config_data_pos;
- needed_size += static_cast<uint32_t>(info.get_se_handler_rvas().size()) * sizeof(uint32_t); //RVAs of SE Handlers
- }
-
- if(write_lock_prefixes)
- {
- current_pos_of_lock_prefixes = needed_size + image_config_data_pos;
- needed_size += static_cast<uint32_t>((info.get_lock_prefix_rvas().size() + 1) * sizeof(typename PEClassType::BaseSize)); //VAs of Lock Prefixes (and ending null element)
- }
-
- //Check if image_config_section is last one. If it's not, check if there's enough place for Image Config data
- if(&image_config_section != &*(pe.get_image_sections().end() - 1) &&
- (image_config_section.empty() || pe_utils::align_up(image_config_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + image_config_data_pos))
- throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
-
- std::string& raw_data = image_config_section.get_raw_data();
-
- //This will be done only if image_config_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + image_config_data_pos)
- raw_data.resize(needed_size + image_config_data_pos); //Expand section raw data
-
- //Create and fill Image Config structure
- typename PEClassType::ConfigStruct image_config_section_struct = {0};
- image_config_section_struct.Size = sizeof(image_config_section_struct);
- image_config_section_struct.TimeDateStamp = info.get_time_stamp();
- image_config_section_struct.MajorVersion = info.get_major_version();
- image_config_section_struct.MinorVersion = info.get_minor_version();
- image_config_section_struct.GlobalFlagsClear = info.get_global_flags_clear();
- image_config_section_struct.GlobalFlagsSet = info.get_global_flags_set();
- image_config_section_struct.CriticalSectionDefaultTimeout = info.get_critical_section_default_timeout();
- image_config_section_struct.DeCommitFreeBlockThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_free_block_threshold());
- image_config_section_struct.DeCommitTotalFreeThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_total_free_threshold());
- image_config_section_struct.MaximumAllocationSize = static_cast<typename PEClassType::BaseSize>(info.get_max_allocation_size());
- image_config_section_struct.VirtualMemoryThreshold = static_cast<typename PEClassType::BaseSize>(info.get_virtual_memory_threshold());
- image_config_section_struct.ProcessHeapFlags = info.get_process_heap_flags();
- image_config_section_struct.ProcessAffinityMask = static_cast<typename PEClassType::BaseSize>(info.get_process_affinity_mask());
- image_config_section_struct.CSDVersion = info.get_service_pack_version();
- image_config_section_struct.EditList = static_cast<typename PEClassType::BaseSize>(info.get_edit_list_va());
- image_config_section_struct.SecurityCookie = static_cast<typename PEClassType::BaseSize>(info.get_security_cookie_va());
- image_config_section_struct.SEHandlerCount = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_rvas().size());
-
-
- if(write_se_handlers)
- {
- if(info.get_se_handler_rvas().empty())
- {
- write_se_handlers = false;
- image_config_section_struct.SEHandlerTable = 0;
- }
- else
- {
- typename PEClassType::BaseSize va;
- pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_se_handlers), va);
- image_config_section_struct.SEHandlerTable = va;
- }
- }
- else
- {
- image_config_section_struct.SEHandlerTable = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_table_va());
- }
-
- if(write_lock_prefixes)
- {
- if(info.get_lock_prefix_rvas().empty())
- {
- write_lock_prefixes = false;
- image_config_section_struct.LockPrefixTable = 0;
- }
- else
- {
- typename PEClassType::BaseSize va;
- pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_lock_prefixes), va);
- image_config_section_struct.LockPrefixTable = va;
- }
- }
- else
- {
- image_config_section_struct.LockPrefixTable = static_cast<typename PEClassType::BaseSize>(info.get_lock_prefix_table_va());
- }
-
- //Write image config section
- memcpy(&raw_data[image_config_data_pos], &image_config_section_struct, sizeof(image_config_section_struct));
-
- if(write_se_handlers)
- {
- //Sort SE Handlers list
- image_config_info::se_handler_list sorted_list = info.get_se_handler_rvas();
- std::sort(sorted_list.begin(), sorted_list.end());
-
- //Write SE Handlers table
- for(image_config_info::se_handler_list::const_iterator it = sorted_list.begin(); it != sorted_list.end(); ++it)
- {
- uint32_t se_handler_rva = *it;
- memcpy(&raw_data[current_pos_of_se_handlers], &se_handler_rva, sizeof(se_handler_rva));
- current_pos_of_se_handlers += sizeof(se_handler_rva);
- }
- }
-
- if(write_lock_prefixes)
- {
- //Write Lock Prefixes VA list
- for(image_config_info::lock_prefix_rva_list::const_iterator it = info.get_lock_prefix_rvas().begin(); it != info.get_lock_prefix_rvas().end(); ++it)
- {
- typename PEClassType::BaseSize lock_prefix_va;
- pe.rva_to_va(*it, lock_prefix_va);
- memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va));
- current_pos_of_lock_prefixes += sizeof(lock_prefix_va);
- }
-
- {
- //Ending null VA
- typename PEClassType::BaseSize lock_prefix_va = 0;
- memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va));
- }
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(image_config_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(image_config_section, image_config_data_pos), sizeof(typename PEClassType::ConfigStruct));
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_load_config, ret.get_rva());
- pe.set_directory_size(image_directory_entry_load_config, ret.get_size());
- }
-
- return ret;
-}
-
-}
diff --git a/tools/pe_bliss/pe_load_config.h b/tools/pe_bliss/pe_load_config.h
deleted file mode 100644
index cb24072de7..0000000000
--- a/tools/pe_bliss/pe_load_config.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing image configuration information
-class image_config_info
-{
-public:
- typedef std::vector<uint32_t> se_handler_list;
- typedef std::vector<uint32_t> lock_prefix_rva_list;
-
-public:
- //Default constructor
- image_config_info();
- //Constructors from PE structures (no checks)
- template<typename ConfigStructure>
- explicit image_config_info(const ConfigStructure& info);
-
- //Returns the date and time stamp value
- uint32_t get_time_stamp() const;
- //Returns major version number
- uint16_t get_major_version() const;
- //Returns minor version number
- uint16_t get_minor_version() const;
- //Returns clear global flags
- uint32_t get_global_flags_clear() const;
- //Returns set global flags
- uint32_t get_global_flags_set() const;
- //Returns critical section default timeout
- uint32_t get_critical_section_default_timeout() const;
- //Get the size of the minimum block that
- //must be freed before it is freed (de-committed), in bytes
- uint64_t get_decommit_free_block_threshold() const;
- //Returns the size of the minimum total memory
- //that must be freed in the process heap before it is freed (de-committed), in bytes
- uint64_t get_decommit_total_free_threshold() const;
- //Returns VA of a list of addresses where the LOCK prefix is used
- uint64_t get_lock_prefix_table_va() const;
- //Returns the maximum allocation size, in bytes
- uint64_t get_max_allocation_size() const;
- //Returns the maximum block size that can be allocated from heap segments, in bytes
- uint64_t get_virtual_memory_threshold() const;
- //Returns process affinity mask
- uint64_t get_process_affinity_mask() const;
- //Returns process heap flags
- uint32_t get_process_heap_flags() const;
- //Returns service pack version (CSDVersion)
- uint16_t get_service_pack_version() const;
- //Returns VA of edit list (reserved by system)
- uint64_t get_edit_list_va() const;
- //Returns a pointer to a cookie that is used by Visual C++ or GS implementation
- uint64_t get_security_cookie_va() const;
- //Returns VA of the sorted table of RVAs of each valid, unique handler in the image
- uint64_t get_se_handler_table_va() const;
- //Returns the count of unique handlers in the table
- uint64_t get_se_handler_count() const;
-
- //Returns SE Handler RVA list
- const se_handler_list& get_se_handler_rvas() const;
-
- //Returns Lock Prefix RVA list
- const lock_prefix_rva_list& get_lock_prefix_rvas() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //Also you can use these functions to rebuild image config directory
-
- //Adds SE Handler RVA to list
- void add_se_handler_rva(uint32_t rva);
- //Clears SE Handler list
- void clear_se_handler_list();
-
- //Adds Lock Prefix RVA to list
- void add_lock_prefix_rva(uint32_t rva);
- //Clears Lock Prefix list
- void clear_lock_prefix_list();
-
- //Sets the date and time stamp value
- void set_time_stamp(uint32_t time_stamp);
- //Sets major version number
- void set_major_version(uint16_t major_version);
- //Sets minor version number
- void set_minor_version(uint16_t minor_version);
- //Sets clear global flags
- void set_global_flags_clear(uint32_t global_flags_clear);
- //Sets set global flags
- void set_global_flags_set(uint32_t global_flags_set);
- //Sets critical section default timeout
- void set_critical_section_default_timeout(uint32_t critical_section_default_timeout);
- //Sets the size of the minimum block that
- //must be freed before it is freed (de-committed), in bytes
- void set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold);
- //Sets the size of the minimum total memory
- //that must be freed in the process heap before it is freed (de-committed), in bytes
- void set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold);
- //Sets VA of a list of addresses where the LOCK prefix is used
- //If you rebuild this list, VA will be re-assigned automatically
- void set_lock_prefix_table_va(uint64_t lock_prefix_table_va);
- //Sets the maximum allocation size, in bytes
- void set_max_allocation_size(uint64_t max_allocation_size);
- //Sets the maximum block size that can be allocated from heap segments, in bytes
- void set_virtual_memory_threshold(uint64_t virtual_memory_threshold);
- //Sets process affinity mask
- void set_process_affinity_mask(uint64_t process_affinity_mask);
- //Sets process heap flags
- void set_process_heap_flags(uint32_t process_heap_flags);
- //Sets service pack version (CSDVersion)
- void set_service_pack_version(uint16_t service_pack_version);
- //Sets VA of edit list (reserved by system)
- void set_edit_list_va(uint64_t edit_list_va);
- //Sets a pointer to a cookie that is used by Visual C++ or GS implementation
- void set_security_cookie_va(uint64_t security_cookie_va);
- //Sets VA of the sorted table of RVAs of each valid, unique handler in the image
- //If you rebuild this list, VA will be re-assigned automatically
- void set_se_handler_table_va(uint64_t se_handler_table_va);
-
- //Returns SE Handler RVA list
- se_handler_list& get_se_handler_rvas();
-
- //Returns Lock Prefix RVA list
- lock_prefix_rva_list& get_lock_prefix_rvas();
-
-private:
- uint32_t time_stamp_;
- uint16_t major_version_, minor_version_;
- uint32_t global_flags_clear_, global_flags_set_;
- uint32_t critical_section_default_timeout_;
- uint64_t decommit_free_block_threshold_, decommit_total_free_threshold_;
- uint64_t lock_prefix_table_va_;
- uint64_t max_allocation_size_;
- uint64_t virtual_memory_threshold_;
- uint64_t process_affinity_mask_;
- uint32_t process_heap_flags_;
- uint16_t service_pack_version_;
- uint64_t edit_list_va_;
- uint64_t security_cookie_va_;
- uint64_t se_handler_table_va_;
- uint64_t se_handler_count_;
-
- se_handler_list se_handlers_;
- lock_prefix_rva_list lock_prefixes_;
-};
-
-//Returns image config info
-//If image does not have config info, throws an exception
-const image_config_info get_image_config(const pe_base& pe);
-
-template<typename PEClassType>
-const image_config_info get_image_config_base(const pe_base& pe);
-
-
-//Image config directory rebuilder
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure
-//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure
-const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-template<typename PEClassType>
-const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_properties.cpp b/tools/pe_bliss/pe_properties.cpp
deleted file mode 100644
index 8d1c2eac43..0000000000
--- a/tools/pe_bliss/pe_properties.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_properties.h"
-
-namespace pe_bliss
-{
-//Destructor
-pe_properties::~pe_properties()
-{}
-
-//Clears PE characteristics flag
-void pe_properties::clear_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() & ~flags);
-}
-
-//Sets PE characteristics flag
-void pe_properties::set_characteristics_flags(uint16_t flags)
-{
- set_characteristics(get_characteristics() | flags);
-}
-}
diff --git a/tools/pe_bliss/pe_properties.h b/tools/pe_bliss/pe_properties.h
deleted file mode 100644
index 1db163e8b1..0000000000
--- a/tools/pe_bliss/pe_properties.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-class pe_properties
-{
-public: //Constructors
- virtual std::auto_ptr<pe_properties> duplicate() const = 0;
-
- //Fills properly PE structures
- virtual void create_pe(uint32_t section_alignment, uint16_t subsystem) = 0;
-
-public:
- //Destructor
- virtual ~pe_properties();
-
-
-public: //DIRECTORIES
- //Returns true if directory exists
- virtual bool directory_exists(uint32_t id) const = 0;
-
- //Removes directory
- virtual void remove_directory(uint32_t id) = 0;
-
- //Returns directory RVA
- virtual uint32_t get_directory_rva(uint32_t id) const = 0;
- //Returns directory size
- virtual uint32_t get_directory_size(uint32_t id) const = 0;
-
- //Sets directory RVA (just a value of PE header, no moving occurs)
- virtual void set_directory_rva(uint32_t id, uint32_t rva) = 0;
- //Sets directory size (just a value of PE header, no moving occurs)
- virtual void set_directory_size(uint32_t id, uint32_t size) = 0;
-
- //Strips only zero DATA_DIRECTORY entries to count = min_count
- //Returns resulting number of data directories
- //strip_iat_directory - if true, even not empty IAT directory will be stripped
- virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true) = 0;
-
-
-public: //IMAGE
- //Returns PE type of this image
- virtual pe_type get_pe_type() const = 0;
-
-
-public: //PE HEADER
- //Returns image base for PE32 and PE64 respectively
- virtual uint32_t get_image_base_32() const = 0;
- virtual uint64_t get_image_base_64() const = 0;
-
- //Sets new image base for PE32
- virtual void set_image_base(uint32_t base) = 0;
- //Sets new image base for PE32/PE+
- virtual void set_image_base_64(uint64_t base) = 0;
-
- //Returns image entry point
- virtual uint32_t get_ep() const = 0;
- //Sets image entry point
- virtual void set_ep(uint32_t new_ep) = 0;
-
- //Returns file alignment
- virtual uint32_t get_file_alignment() const = 0;
- //Returns section alignment
- virtual uint32_t get_section_alignment() const = 0;
-
- //Sets heap size commit for PE32 and PE64 respectively
- virtual void set_heap_size_commit(uint32_t size) = 0;
- virtual void set_heap_size_commit(uint64_t size) = 0;
- //Sets heap size reserve for PE32 and PE64 respectively
- virtual void set_heap_size_reserve(uint32_t size) = 0;
- virtual void set_heap_size_reserve(uint64_t size) = 0;
- //Sets stack size commit for PE32 and PE64 respectively
- virtual void set_stack_size_commit(uint32_t size) = 0;
- virtual void set_stack_size_commit(uint64_t size) = 0;
- //Sets stack size reserve for PE32 and PE64 respectively
- virtual void set_stack_size_reserve(uint32_t size) = 0;
- virtual void set_stack_size_reserve(uint64_t size) = 0;
-
- //Returns heap size commit for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_commit_32() const = 0;
- virtual uint64_t get_heap_size_commit_64() const = 0;
- //Returns heap size reserve for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_reserve_32() const = 0;
- virtual uint64_t get_heap_size_reserve_64() const = 0;
- //Returns stack size commit for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_commit_32() const = 0;
- virtual uint64_t get_stack_size_commit_64() const = 0;
- //Returns stack size reserve for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_reserve_32() const = 0;
- virtual uint64_t get_stack_size_reserve_64() const = 0;
-
- //Returns virtual size of image
- virtual uint32_t get_size_of_image() const = 0;
-
- //Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual uint32_t get_number_of_rvas_and_sizes() const = 0;
- //Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual void set_number_of_rvas_and_sizes(uint32_t number) = 0;
-
- //Returns PE characteristics
- virtual uint16_t get_characteristics() const = 0;
- //Sets PE characteristics
- virtual void set_characteristics(uint16_t ch) = 0;
-
- //Clears PE characteristics flag
- void clear_characteristics_flags(uint16_t flags);
- //Sets PE characteristics flag
- void set_characteristics_flags(uint16_t flags);
-
- //Returns size of headers
- virtual uint32_t get_size_of_headers() const = 0;
-
- //Returns subsystem
- virtual uint16_t get_subsystem() const = 0;
-
- //Sets subsystem
- virtual void set_subsystem(uint16_t subsystem) = 0;
-
- //Returns size of optional header
- virtual uint16_t get_size_of_optional_header() const = 0;
-
- //Returns PE signature
- virtual uint32_t get_pe_signature() const = 0;
-
- //Returns PE magic value
- virtual uint32_t get_magic() const = 0;
-
- //Returns checksum of PE file from header
- virtual uint32_t get_checksum() const = 0;
-
- //Sets checksum of PE file
- virtual void set_checksum(uint32_t checksum) = 0;
-
- //Returns timestamp of PE file from header
- virtual uint32_t get_time_date_stamp() const = 0;
-
- //Sets timestamp of PE file
- virtual void set_time_date_stamp(uint32_t timestamp) = 0;
-
- //Returns Machine field value of PE file from header
- virtual uint16_t get_machine() const = 0;
-
- //Sets Machine field value of PE file
- virtual void set_machine(uint16_t machine) = 0;
-
- //Returns DLL Characteristics
- virtual uint16_t get_dll_characteristics() const = 0;
-
- //Sets DLL Characteristics
- virtual void set_dll_characteristics(uint16_t characteristics) = 0;
-
- //Sets required operation system version
- virtual void set_os_version(uint16_t major, uint16_t minor) = 0;
-
- //Returns required operation system version (minor word)
- virtual uint16_t get_minor_os_version() const = 0;
-
- //Returns required operation system version (major word)
- virtual uint16_t get_major_os_version() const = 0;
-
- //Sets required subsystem version
- virtual void set_subsystem_version(uint16_t major, uint16_t minor) = 0;
-
- //Returns required subsystem version (minor word)
- virtual uint16_t get_minor_subsystem_version() const = 0;
-
- //Returns required subsystem version (major word)
- virtual uint16_t get_major_subsystem_version() const = 0;
-
-public: //ADDRESS CONVERTIONS
- //Virtual Address (VA) to Relative Virtual Address (RVA) convertions
- //for PE32 and PE64 respectively
- //bound_check checks integer overflow
- virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const = 0;
- virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const = 0;
-
- //Relative Virtual Address (RVA) to Virtual Address (VA) convertions
- //for PE32 and PE64 respectively
- virtual uint32_t rva_to_va_32(uint32_t rva) const = 0;
- virtual uint64_t rva_to_va_64(uint32_t rva) const = 0;
-
-
-public: //SECTIONS
- //Returns number of sections
- virtual uint16_t get_number_of_sections() const = 0;
-
-public:
- //Sets number of sections
- virtual void set_number_of_sections(uint16_t number) = 0;
- //Sets virtual size of image
- virtual void set_size_of_image(uint32_t size) = 0;
- //Sets size of headers
- virtual void set_size_of_headers(uint32_t size) = 0;
- //Sets size of optional headers
- virtual void set_size_of_optional_header(uint16_t size) = 0;
- //Returns nt headers data pointer
- virtual char* get_nt_headers_ptr() = 0;
- //Returns nt headers data pointer
- virtual const char* get_nt_headers_ptr() const = 0;
- //Returns size of NT header
- virtual uint32_t get_sizeof_nt_header() const = 0;
- //Returns size of optional headers
- virtual uint32_t get_sizeof_opt_headers() const = 0;
- //Sets file alignment (no checks)
- virtual void set_file_alignment_unchecked(uint32_t alignment) = 0;
- //Sets base of code
- virtual void set_base_of_code(uint32_t base) = 0;
- //Returns base of code
- virtual uint32_t get_base_of_code() const = 0;
- //Returns needed PE magic for PE or PE+ (from template parameters)
- virtual uint32_t get_needed_magic() const = 0;
-};
-}
diff --git a/tools/pe_bliss/pe_properties_generic.cpp b/tools/pe_bliss/pe_properties_generic.cpp
deleted file mode 100644
index bcf6f2047d..0000000000
--- a/tools/pe_bliss/pe_properties_generic.cpp
+++ /dev/null
@@ -1,645 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_properties_generic.h"
-#include "pe_exception.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor
-template<typename PEClassType>
-std::auto_ptr<pe_properties> pe_properties_generic<PEClassType>::duplicate() const
-{
- return std::auto_ptr<pe_properties>(new pe_properties_generic<PEClassType>(*this));
-}
-
-//Fills properly PE structures
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::create_pe(uint32_t section_alignment, uint16_t subsystem)
-{
- memset(&nt_headers_, 0, sizeof(nt_headers_));
- nt_headers_.Signature = 0x4550; //"PE"
- nt_headers_.FileHeader.Machine = 0x14C; //i386
- nt_headers_.FileHeader.SizeOfOptionalHeader = sizeof(nt_headers_.OptionalHeader);
- nt_headers_.OptionalHeader.Magic = PEClassType::Id;
- nt_headers_.OptionalHeader.ImageBase = 0x400000;
- nt_headers_.OptionalHeader.SectionAlignment = section_alignment;
- nt_headers_.OptionalHeader.FileAlignment = 0x200;
- nt_headers_.OptionalHeader.SizeOfHeaders = 1024;
- nt_headers_.OptionalHeader.Subsystem = subsystem;
- nt_headers_.OptionalHeader.SizeOfHeapReserve = 0x100000;
- nt_headers_.OptionalHeader.SizeOfHeapCommit = 0x1000;
- nt_headers_.OptionalHeader.SizeOfStackReserve = 0x100000;
- nt_headers_.OptionalHeader.SizeOfStackCommit = 0x1000;
- nt_headers_.OptionalHeader.NumberOfRvaAndSizes = 0x10;
-}
-
-//Duplicate
-template<typename PEClassType>
-pe_properties_generic<PEClassType>::~pe_properties_generic()
-{}
-
-//Returns true if directory exists
-template<typename PEClassType>
-bool pe_properties_generic<PEClassType>::directory_exists(uint32_t id) const
-{
- return (nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1) >= id &&
- nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
-}
-
-//Removes directory
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::remove_directory(uint32_t id)
-{
- if(directory_exists(id))
- {
- nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = 0;
- nt_headers_.OptionalHeader.DataDirectory[id].Size = 0;
-
- if(id == image_directory_entry_basereloc)
- {
- set_characteristics_flags(image_file_relocs_stripped);
- set_dll_characteristics(get_dll_characteristics() & ~image_dllcharacteristics_dynamic_base);
- }
- else if(id == image_directory_entry_export)
- {
- clear_characteristics_flags(image_file_dll);
- }
- }
-}
-
-//Returns directory RVA
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_directory_rva(uint32_t id) const
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- return nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
-}
-
-//Returns directory size
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_directory_rva(uint32_t id, uint32_t va)
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = va;
-}
-
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_directory_size(uint32_t id, uint32_t size)
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- nt_headers_.OptionalHeader.DataDirectory[id].Size = size;
-}
-
-//Returns directory size
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_directory_size(uint32_t id) const
-{
- //Check if directory exists
- if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
- throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
- return nt_headers_.OptionalHeader.DataDirectory[id].Size;
-}
-
-//Strips only zero DATA_DIRECTORY entries to count = min_count
-//Returns resulting number of data directories
-//strip_iat_directory - if true, even not empty IAT directory will be stripped
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
-{
- int i = nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1;
-
- //Enumerate all data directories from the end
- for(; i >= 0; i--)
- {
- //If directory exists, break
- if(nt_headers_.OptionalHeader.DataDirectory[i].VirtualAddress && (static_cast<uint32_t>(i) != image_directory_entry_iat || !strip_iat_directory))
- break;
-
- if(i <= static_cast<int>(min_count) - 2)
- break;
- }
-
- if(i == image_numberof_directory_entries - 1)
- return image_numberof_directory_entries;
-
- //Return new number of data directories
- return nt_headers_.OptionalHeader.NumberOfRvaAndSizes = i + 1;
-}
-
-//Returns image base for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_image_base_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Returns image base for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_image_base_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Sets new image base
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_image_base(uint32_t base)
-{
- nt_headers_.OptionalHeader.ImageBase = base;
-}
-
-//Sets new image base
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_image_base_64(uint64_t base)
-{
- nt_headers_.OptionalHeader.ImageBase = static_cast<typename PEClassType::BaseSize>(base);
-}
-
-//Returns image entry point
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_ep() const
-{
- return nt_headers_.OptionalHeader.AddressOfEntryPoint;
-}
-
-//Sets image entry point
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_ep(uint32_t new_ep)
-{
- nt_headers_.OptionalHeader.AddressOfEntryPoint = new_ep;
-}
-
-//Returns file alignment
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_file_alignment() const
-{
- return nt_headers_.OptionalHeader.FileAlignment;
-}
-
-//Returns section alignment
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_section_alignment() const
-{
- return nt_headers_.OptionalHeader.SectionAlignment;
-}
-
-//Sets heap size commit for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_commit(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size commit for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_commit(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size reserve for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size reserve for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size commit for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_commit(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size commit for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_commit(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size reserve for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size reserve for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint64_t size)
-{
- nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Returns heap size commit for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_heap_size_commit_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit);
-}
-
-//Returns heap size commit for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_heap_size_commit_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit);
-}
-
-//Returns heap size reserve for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_heap_size_reserve_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve);
-}
-
-//Returns heap size reserve for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_heap_size_reserve_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve);
-}
-
-//Returns stack size commit for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_stack_size_commit_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackCommit);
-}
-
-//Returns stack size commit for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_stack_size_commit_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackCommit);
-}
-
-//Returns stack size reserve for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_stack_size_reserve_32() const
-{
- return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackReserve);
-}
-
-//Returns stack size reserve for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_stack_size_reserve_64() const
-{
- return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackReserve);
-}
-
-//Returns virtual size of image
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_size_of_image() const
-{
- return nt_headers_.OptionalHeader.SizeOfImage;
-}
-
-//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_number_of_rvas_and_sizes() const
-{
- return nt_headers_.OptionalHeader.NumberOfRvaAndSizes;
-}
-
-//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_number_of_rvas_and_sizes(uint32_t number)
-{
- nt_headers_.OptionalHeader.NumberOfRvaAndSizes = number;
-}
-
-//Returns PE characteristics
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_characteristics() const
-{
- return nt_headers_.FileHeader.Characteristics;
-}
-
-//Returns checksum of PE file from header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_checksum() const
-{
- return nt_headers_.OptionalHeader.CheckSum;
-}
-
-//Sets checksum of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_checksum(uint32_t checksum)
-{
- nt_headers_.OptionalHeader.CheckSum = checksum;
-}
-
-//Returns DLL Characteristics
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_dll_characteristics() const
-{
- return nt_headers_.OptionalHeader.DllCharacteristics;
-}
-
-//Returns timestamp of PE file from header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_time_date_stamp() const
-{
- return nt_headers_.FileHeader.TimeDateStamp;
-}
-
-//Sets timestamp of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_time_date_stamp(uint32_t timestamp)
-{
- nt_headers_.FileHeader.TimeDateStamp = timestamp;
-}
-
-//Sets DLL Characteristics
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_dll_characteristics(uint16_t characteristics)
-{
- nt_headers_.OptionalHeader.DllCharacteristics = characteristics;
-}
-
-//Returns Machine field value of PE file from header
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_machine() const
-{
- return nt_headers_.FileHeader.Machine;
-}
-
-//Sets Machine field value of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_machine(uint16_t machine)
-{
- nt_headers_.FileHeader.Machine = machine;
-}
-
-//Sets PE characteristics
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_characteristics(uint16_t ch)
-{
- nt_headers_.FileHeader.Characteristics = ch;
-}
-
-//Returns size of headers
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_size_of_headers() const
-{
- return nt_headers_.OptionalHeader.SizeOfHeaders;
-}
-
-//Returns subsystem
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_subsystem() const
-{
- return nt_headers_.OptionalHeader.Subsystem;
-}
-
-//Sets subsystem
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_subsystem(uint16_t subsystem)
-{
- nt_headers_.OptionalHeader.Subsystem = subsystem;
-}
-
-//Returns size of optional header
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_size_of_optional_header() const
-{
- return nt_headers_.FileHeader.SizeOfOptionalHeader;
-}
-
-//Returns PE signature
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_pe_signature() const
-{
- return nt_headers_.Signature;
-}
-
-//Returns PE magic value
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_magic() const
-{
- return nt_headers_.OptionalHeader.Magic;
-}
-
-//Sets required operation system version
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_os_version(uint16_t major, uint16_t minor)
-{
- nt_headers_.OptionalHeader.MinorOperatingSystemVersion = minor;
- nt_headers_.OptionalHeader.MajorOperatingSystemVersion = major;
-}
-
-//Returns required operation system version (minor word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_minor_os_version() const
-{
- return nt_headers_.OptionalHeader.MinorOperatingSystemVersion;
-}
-
-//Returns required operation system version (major word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_major_os_version() const
-{
- return nt_headers_.OptionalHeader.MajorOperatingSystemVersion;
-}
-
-//Sets required subsystem version
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_subsystem_version(uint16_t major, uint16_t minor)
-{
- nt_headers_.OptionalHeader.MinorSubsystemVersion = minor;
- nt_headers_.OptionalHeader.MajorSubsystemVersion = major;
-}
-
-//Returns required subsystem version (minor word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_minor_subsystem_version() const
-{
- return nt_headers_.OptionalHeader.MinorSubsystemVersion;
-}
-
-//Returns required subsystem version (major word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_major_subsystem_version() const
-{
- return nt_headers_.OptionalHeader.MajorSubsystemVersion;
-}
-
-//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint32_t va, bool bound_check) const
-{
- if(bound_check && static_cast<uint64_t>(va) - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword)
- throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
- return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32/PE64
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint64_t va, bool bound_check) const
-{
- if(bound_check && va - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword)
- throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
- return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::rva_to_va_32(uint32_t rva) const
-{
- if(!pe_utils::is_sum_safe(rva, static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase)))
- throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
- return static_cast<uint32_t>(rva + nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::rva_to_va_64(uint32_t rva) const
-{
- return static_cast<uint64_t>(rva) + nt_headers_.OptionalHeader.ImageBase;
-}
-
-//Returns number of sections
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_number_of_sections() const
-{
- return nt_headers_.FileHeader.NumberOfSections;
-}
-
-//Sets number of sections
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_number_of_sections(uint16_t number)
-{
- nt_headers_.FileHeader.NumberOfSections = number;
-}
-
-//Sets virtual size of image
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_image(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfImage = size;
-}
-
-//Sets size of headers
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_headers(uint32_t size)
-{
- nt_headers_.OptionalHeader.SizeOfHeaders = size;
-}
-
-//Sets size of optional headers
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_optional_header(uint16_t size)
-{
- nt_headers_.FileHeader.SizeOfOptionalHeader = size;
-}
-
-//Returns nt headers data pointer
-template<typename PEClassType>
-char* pe_properties_generic<PEClassType>::get_nt_headers_ptr()
-{
- return reinterpret_cast<char*>(&nt_headers_);
-}
-
-//Returns nt headers data pointer
-template<typename PEClassType>
-const char* pe_properties_generic<PEClassType>::get_nt_headers_ptr() const
-{
- return reinterpret_cast<const char*>(&nt_headers_);
-}
-
-//Returns size of NT header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_sizeof_nt_header() const
-{
- return sizeof(typename PEClassType::NtHeaders);
-}
-
-//Returns size of optional headers
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_sizeof_opt_headers() const
-{
- return sizeof(typename PEClassType::OptHeaders);
-}
-
-//Sets file alignment (no checks)
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_file_alignment_unchecked(uint32_t alignment)
-{
- nt_headers_.OptionalHeader.FileAlignment = alignment;
-}
-
-//Sets base of code
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_base_of_code(uint32_t base)
-{
- nt_headers_.OptionalHeader.BaseOfCode = base;
-}
-
-//Returns base of code
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_base_of_code() const
-{
- return nt_headers_.OptionalHeader.BaseOfCode;
-}
-
-//Returns needed PE magic for PE or PE+ (from template parameters)
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_needed_magic() const
-{
- return PEClassType::Id;
-}
-
-//Returns PE type of this image
-template<typename PEClassType>
-pe_type pe_properties_generic<PEClassType>::get_pe_type() const
-{
- return PEClassType::Id == image_nt_optional_hdr32_magic ? pe_type_32 : pe_type_64;
-}
-
-//Two used instantiations for PE32 (PE) and PE64 (PE+)
-template class pe_properties_generic<pe_types_class_32>;
-template class pe_properties_generic<pe_types_class_64>;
-}
diff --git a/tools/pe_bliss/pe_properties_generic.h b/tools/pe_bliss/pe_properties_generic.h
deleted file mode 100644
index 4ff906803c..0000000000
--- a/tools/pe_bliss/pe_properties_generic.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_properties.h"
-
-namespace pe_bliss
-{
-//Helper class to reduce code size and ease its editing
-template<
- typename NtHeadersType,
- typename OptHeadersType,
- uint16_t IdVal,
- typename BaseSizeType,
- BaseSizeType ImportSnapFlagVal,
- typename TLSStructType,
- typename ConfigStructType>
-class pe_types
-{
-public:
- typedef NtHeadersType NtHeaders; //NT HEADERS type
- typedef OptHeadersType OptHeaders; //NT OPTIONAL HEADER type
- typedef BaseSizeType BaseSize; //Base size of different values: DWORD or ULONGLONG
- typedef TLSStructType TLSStruct; //TLS structure type
- typedef ConfigStructType ConfigStruct; //Configuration structure type
-
- static const uint16_t Id = IdVal; //Magic of PE or PE+
- static const BaseSize ImportSnapFlag = ImportSnapFlagVal; //Import snap flag value
-};
-
-//Portable Executable derived class for PE and PE+
-//Describes PE/PE+ dependent things
-template<typename PEClassType>
-class pe_properties_generic : public pe_properties
-{
-public: //Constructor
- virtual std::auto_ptr<pe_properties> duplicate() const;
-
- //Fills properly PE structures
- virtual void create_pe(uint32_t section_alignment, uint16_t subsystem);
-
-public:
- //Destructor
- virtual ~pe_properties_generic();
-
-
-public: //DIRECTORIES
- //Returns true if directory exists
- virtual bool directory_exists(uint32_t id) const;
-
- //Removes directory
- virtual void remove_directory(uint32_t id);
-
- //Returns directory RVA
- virtual uint32_t get_directory_rva(uint32_t id) const;
- //Returns directory size
- virtual uint32_t get_directory_size(uint32_t id) const;
-
- //Sets directory RVA (just a value of PE header, no moving occurs)
- virtual void set_directory_rva(uint32_t id, uint32_t rva);
- //Sets directory size (just a value of PE header, no moving occurs)
- virtual void set_directory_size(uint32_t id, uint32_t size);
-
- //Strips only zero DATA_DIRECTORY entries to count = min_count
- //Returns resulting number of data directories
- //strip_iat_directory - if true, even not empty IAT directory will be stripped
- virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
-
-
-public: //IMAGE
- //Returns PE type of this image
- virtual pe_type get_pe_type() const;
-
-
-public: //PE HEADER
- //Returns image base for PE32 and PE64 respectively
- virtual uint32_t get_image_base_32() const;
- virtual uint64_t get_image_base_64() const;
-
- //Sets new image base for PE32
- virtual void set_image_base(uint32_t base);
- //Sets new image base for PE32/PE+
- virtual void set_image_base_64(uint64_t base);
-
- //Returns image entry point
- virtual uint32_t get_ep() const;
- //Sets image entry point
- virtual void set_ep(uint32_t new_ep);
-
- //Returns file alignment
- virtual uint32_t get_file_alignment() const;
- //Returns section alignment
- virtual uint32_t get_section_alignment() const;
-
- //Sets heap size commit for PE32 and PE64 respectively
- virtual void set_heap_size_commit(uint32_t size);
- virtual void set_heap_size_commit(uint64_t size);
- //Sets heap size reserve for PE32 and PE64 respectively
- virtual void set_heap_size_reserve(uint32_t size);
- virtual void set_heap_size_reserve(uint64_t size);
- //Sets stack size commit for PE32 and PE64 respectively
- virtual void set_stack_size_commit(uint32_t size);
- virtual void set_stack_size_commit(uint64_t size);
- //Sets stack size reserve for PE32 and PE64 respectively
- virtual void set_stack_size_reserve(uint32_t size);
- virtual void set_stack_size_reserve(uint64_t size);
-
- //Returns heap size commit for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_commit_32() const;
- virtual uint64_t get_heap_size_commit_64() const;
- //Returns heap size reserve for PE32 and PE64 respectively
- virtual uint32_t get_heap_size_reserve_32() const;
- virtual uint64_t get_heap_size_reserve_64() const;
- //Returns stack size commit for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_commit_32() const;
- virtual uint64_t get_stack_size_commit_64() const;
- //Returns stack size reserve for PE32 and PE64 respectively
- virtual uint32_t get_stack_size_reserve_32() const;
- virtual uint64_t get_stack_size_reserve_64() const;
-
- //Returns virtual size of image
- virtual uint32_t get_size_of_image() const;
-
- //Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual uint32_t get_number_of_rvas_and_sizes() const;
- //Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
- virtual void set_number_of_rvas_and_sizes(uint32_t number);
-
- //Returns PE characteristics
- virtual uint16_t get_characteristics() const;
- //Sets PE characteristics
- virtual void set_characteristics(uint16_t ch);
-
- //Returns size of headers
- virtual uint32_t get_size_of_headers() const;
-
- //Returns subsystem
- virtual uint16_t get_subsystem() const;
-
- //Sets subsystem
- virtual void set_subsystem(uint16_t subsystem);
-
- //Returns size of optional header
- virtual uint16_t get_size_of_optional_header() const;
-
- //Returns PE signature
- virtual uint32_t get_pe_signature() const;
-
- //Returns PE magic value
- virtual uint32_t get_magic() const;
-
- //Returns checksum of PE file from header
- virtual uint32_t get_checksum() const;
-
- //Sets checksum of PE file
- virtual void set_checksum(uint32_t checksum);
-
- //Returns timestamp of PE file from header
- virtual uint32_t get_time_date_stamp() const;
-
- //Sets timestamp of PE file
- virtual void set_time_date_stamp(uint32_t timestamp);
-
- //Returns Machine field value of PE file from header
- virtual uint16_t get_machine() const;
-
- //Sets Machine field value of PE file
- virtual void set_machine(uint16_t machine);
-
- //Returns DLL Characteristics
- virtual uint16_t get_dll_characteristics() const;
-
- //Sets DLL Characteristics
- virtual void set_dll_characteristics(uint16_t characteristics);
-
- //Sets required operation system version
- virtual void set_os_version(uint16_t major, uint16_t minor);
-
- //Returns required operation system version (minor word)
- virtual uint16_t get_minor_os_version() const;
-
- //Returns required operation system version (major word)
- virtual uint16_t get_major_os_version() const;
-
- //Sets required subsystem version
- virtual void set_subsystem_version(uint16_t major, uint16_t minor);
-
- //Returns required subsystem version (minor word)
- virtual uint16_t get_minor_subsystem_version() const;
-
- //Returns required subsystem version (major word)
- virtual uint16_t get_major_subsystem_version() const;
-
-public: //ADDRESS CONVERTIONS
- //Virtual Address (VA) to Relative Virtual Address (RVA) convertions
- //for PE32 and PE64 respectively
- //bound_check checks integer overflow
- virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const;
- virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const;
-
- //Relative Virtual Address (RVA) to Virtual Address (VA) convertions
- //for PE32 and PE64 respectively
- virtual uint32_t rva_to_va_32(uint32_t rva) const;
- virtual uint64_t rva_to_va_64(uint32_t rva) const;
-
-
-public: //SECTIONS
- //Returns number of sections
- virtual uint16_t get_number_of_sections() const;
-
-protected:
- typename PEClassType::NtHeaders nt_headers_; //NT headers (PE32 or PE64)
-
-public:
- //Sets number of sections
- virtual void set_number_of_sections(uint16_t number);
- //Sets virtual size of image
- virtual void set_size_of_image(uint32_t size);
- //Sets size of headers
- virtual void set_size_of_headers(uint32_t size);
- //Sets size of optional headers
- virtual void set_size_of_optional_header(uint16_t size);
- //Returns nt headers data pointer
- virtual char* get_nt_headers_ptr();
- //Returns nt headers data pointer
- virtual const char* get_nt_headers_ptr() const;
- //Returns size of NT header
- virtual uint32_t get_sizeof_nt_header() const;
- //Returns size of optional headers
- virtual uint32_t get_sizeof_opt_headers() const;
- //Sets file alignment (no checks)
- virtual void set_file_alignment_unchecked(uint32_t alignment);
- //Sets base of code
- virtual void set_base_of_code(uint32_t base);
- //Returns base of code
- virtual uint32_t get_base_of_code() const;
- //Returns needed PE magic for PE or PE+ (from template parameters)
- virtual uint32_t get_needed_magic() const;
-};
-
-//Two used typedefs for PE32 (PE) and PE64 (PE+)
-typedef pe_types<pe_win::image_nt_headers32,
- pe_win::image_optional_header32,
- pe_win::image_nt_optional_hdr32_magic,
- uint32_t,
- pe_win::image_ordinal_flag32,
- pe_win::image_tls_directory32,
- pe_win::image_load_config_directory32> pe_types_class_32;
-
-typedef pe_types<pe_win::image_nt_headers64,
- pe_win::image_optional_header64,
- pe_win::image_nt_optional_hdr64_magic,
- uint64_t,
- pe_win::image_ordinal_flag64,
- pe_win::image_tls_directory64,
- pe_win::image_load_config_directory64> pe_types_class_64;
-
-typedef pe_properties_generic<pe_types_class_32> pe_properties_32;
-typedef pe_properties_generic<pe_types_class_64> pe_properties_64;
-}
diff --git a/tools/pe_bliss/pe_rebuilder.cpp b/tools/pe_bliss/pe_rebuilder.cpp
deleted file mode 100644
index faf5803b8c..0000000000
--- a/tools/pe_bliss/pe_rebuilder.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_rebuilder.h"
-#include "pe_base.h"
-#include "pe_structures.h"
-#include "pe_exception.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Rebuilds PE image headers
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, image_dos_header& dos_header, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
- dos_header = pe.get_dos_header();
-
- if(strip_dos_header)
- {
- //Strip stub overlay
- pe.strip_stub_overlay();
- //BaseOfCode NT Headers field now overlaps
- //e_lfanew field, so we're acrually setting
- //e_lfanew with this call
- pe.set_base_of_code(8 * sizeof(uint16_t));
- }
- else
- {
- //Set start of PE headers
- dos_header.e_lfanew = sizeof(image_dos_header)
- + pe_utils::align_up(static_cast<uint32_t>(pe.get_stub_overlay().size()), sizeof(uint32_t));
- }
-
- section_list& sections = pe.get_image_sections();
-
- //Calculate pointer to section data
- size_t ptr_to_section_data = (strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header)) + pe.get_sizeof_nt_header()
- + pe_utils::align_up(pe.get_stub_overlay().size(), sizeof(uint32_t))
- - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())
- + sections.size() * sizeof(image_section_header);
-
- if(save_bound_import && pe.has_bound_import())
- {
- //It will be aligned to DWORD, because we're aligning to DWORD everything above it
- pe.set_directory_rva(image_directory_entry_bound_import, static_cast<uint32_t>(ptr_to_section_data));
- ptr_to_section_data += pe.get_directory_size(image_directory_entry_bound_import);
- }
-
- ptr_to_section_data = pe_utils::align_up(ptr_to_section_data, pe.get_file_alignment());
-
- //Set size of headers and size of optional header
- if(change_size_of_headers)
- {
- if(!pe.get_image_sections().empty())
- {
- if(static_cast<uint32_t>(ptr_to_section_data) > (*sections.begin()).get_virtual_address())
- throw pe_exception("Headers of PE file are too long. Try to strip STUB or don't build bound import", pe_exception::cannot_rebuild_image);
- }
-
- pe.set_size_of_headers(static_cast<uint32_t>(ptr_to_section_data));
- }
-
- //Set number of sections in PE header
- pe.update_number_of_sections();
-
- pe.update_image_size();
-
- pe.set_size_of_optional_header(static_cast<uint16_t>(pe.get_sizeof_opt_headers()
- - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())));
-
- //Recalculate pointer to raw data according to section list
- for(section_list::iterator it = sections.begin(); it != sections.end(); ++it)
- {
- //Save section headers PointerToRawData
- (*it).set_pointer_to_raw_data(static_cast<uint32_t>(ptr_to_section_data));
- ptr_to_section_data += (*it).get_aligned_raw_size(pe.get_file_alignment());
- }
-}
-
-//Rebuild PE image and write it to "out" ostream
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
- if(out.bad())
- throw pe_exception("Stream is bad", pe_exception::stream_is_bad);
-
- if(save_bound_import && pe.has_bound_import())
- {
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true)
- < pe.get_directory_size(image_directory_entry_bound_import))
- throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
- }
-
- //Change ostream state
- out.exceptions(std::ios::goodbit);
- out.clear();
-
- uint32_t original_bound_import_rva = pe.has_bound_import() ? pe.get_directory_rva(image_directory_entry_bound_import) : 0;
- if(original_bound_import_rva && original_bound_import_rva > pe.get_size_of_headers())
- {
- //No need to do anything with bound import directory
- //if it is placed inside of any section, not headers
- original_bound_import_rva = 0;
- save_bound_import = false;
- }
-
- {
- image_dos_header dos_header;
-
- //Rebuild PE image headers
- rebuild_pe(pe, dos_header, strip_dos_header, change_size_of_headers, save_bound_import);
-
- //Write DOS header
- out.write(reinterpret_cast<const char*>(&dos_header), strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header));
- }
-
- //If we have stub overlay, write it too
- {
- const std::string& stub = pe.get_stub_overlay();
- if(stub.size())
- {
- out.write(stub.data(), stub.size());
- size_t aligned_size = pe_utils::align_up(stub.size(), sizeof(uint32_t));
- //Align PE header, which is right after rich overlay
- while(aligned_size > stub.size())
- {
- out.put('\0');
- --aligned_size;
- }
- }
- }
-
- //Write NT headers
- out.write(static_cast<const pe_base&>(pe).get_nt_headers_ptr(), pe.get_sizeof_nt_header()
- - sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes()));
-
- //Write section headers
- const section_list& sections = pe.get_image_sections();
- for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it)
- {
- if(it == sections.end() - 1) //If last section encountered
- {
- image_section_header header((*it).get_raw_header());
- header.SizeOfRawData = static_cast<uint32_t>((*it).get_raw_data().length()); //Set non-aligned actual data length for it
- out.write(reinterpret_cast<const char*>(&header), sizeof(image_section_header));
- }
- else
- {
- out.write(reinterpret_cast<const char*>(&(*it).get_raw_header()), sizeof(image_section_header));
- }
- }
-
- //Write bound import data if requested
- if(save_bound_import && pe.has_bound_import())
- {
- out.write(pe.section_data_from_rva(original_bound_import_rva, section_data_raw, true),
- pe.get_directory_size(image_directory_entry_bound_import));
- }
-
- //Write section data finally
- for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it)
- {
- const section& s = *it;
-
- std::streamoff wpos = out.tellp();
-
- //Fill unused overlay data between sections with null bytes
- for(unsigned int i = 0; i < s.get_pointer_to_raw_data() - wpos; i++)
- out.put(0);
-
- //Write raw section data
- out.write(s.get_raw_data().data(), s.get_raw_data().length());
- }
-}
-
-//Rebuild PE image and write it to "out" file
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, const char* out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
- std::ofstream pe_file(out, std::ios::out | std::ios::binary | std::ios::trunc);
- if(!pe_file)
- {
- throw pe_exception("Error in open file.", pe_exception::stream_is_bad);
- }
- rebuild_pe(pe, pe_file, strip_dos_header, change_size_of_headers, save_bound_import);
-}
-
-
-}
diff --git a/tools/pe_bliss/pe_rebuilder.h b/tools/pe_bliss/pe_rebuilder.h
deleted file mode 100644
index 319807e5c9..0000000000
--- a/tools/pe_bliss/pe_rebuilder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <ostream>
-#include <fstream>
-
-namespace pe_bliss
-{
-class pe_base;
-//Rebuilds PE image, writes resulting image to ostream "out". If strip_dos_header == true, DOS header will be stripped a little
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true);
-
-//Rebuild PE image and write it to "out" file
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, const char* out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true);
-
-}
diff --git a/tools/pe_bliss/pe_relocations.cpp b/tools/pe_bliss/pe_relocations.cpp
deleted file mode 100644
index d5357dd219..0000000000
--- a/tools/pe_bliss/pe_relocations.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_relocations.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//RELOCATIONS
-//Default constructor
-relocation_entry::relocation_entry()
- :rva_(0), type_(0)
-{}
-
-//Constructor from relocation item (WORD)
-relocation_entry::relocation_entry(uint16_t relocation_value)
- :rva_(relocation_value & ((1 << 12) - 1)), type_(relocation_value >> 12)
-{}
-
-//Constructor from relative rva and relocation type
-relocation_entry::relocation_entry(uint16_t rrva, uint16_t type)
- :rva_(rrva), type_(type)
-{}
-
-//Returns RVA of relocation
-uint16_t relocation_entry::get_rva() const
-{
- return rva_;
-}
-
-//Returns type of relocation
-uint16_t relocation_entry::get_type() const
-{
- return type_;
-}
-
-//Sets RVA of relocation
-void relocation_entry::set_rva(uint16_t rva)
-{
- rva_ = rva;
-}
-
-//Sets type of relocation
-void relocation_entry::set_type(uint16_t type)
-{
- type_ = type;
-}
-
-//Returns relocation item (rrva + type)
-uint16_t relocation_entry::get_item() const
-{
- return rva_ | (type_ << 12);
-}
-
-//Sets relocation item (rrva + type)
-void relocation_entry::set_item(uint16_t item)
-{
- rva_ = item & ((1 << 12) - 1);
- type_ = item >> 12;
-}
-
-//Returns relocation list
-const relocation_table::relocation_list& relocation_table::get_relocations() const
-{
- return relocations_;
-}
-
-//Adds relocation to table
-void relocation_table::add_relocation(const relocation_entry& entry)
-{
- relocations_.push_back(entry);
-}
-
-//Default constructor
-relocation_table::relocation_table()
- :rva_(0)
-{}
-
-//Constructor from RVA of relocation table
-relocation_table::relocation_table(uint32_t rva)
- :rva_(rva)
-{}
-
-//Returns RVA of block
-uint32_t relocation_table::get_rva() const
-{
- return rva_;
-}
-
-//Sets RVA of block
-void relocation_table::set_rva(uint32_t rva)
-{
- rva_ = rva;
-}
-
-//Returns changeable relocation list
-relocation_table::relocation_list& relocation_table::get_relocations()
-{
- return relocations_;
-}
-
-//Get relocation list of pe file, supports one-word sized relocations only
-//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed
-const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries)
-{
- relocation_table_list ret;
-
- //If image does not have relocations
- if(!pe.has_reloc())
- return ret;
-
- //Check the length in bytes of the section containing relocation directory
- if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_basereloc),
- pe.get_directory_rva(image_directory_entry_basereloc), section_data_virtual, true)
- < sizeof(image_base_relocation))
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- unsigned long current_pos = pe.get_directory_rva(image_directory_entry_basereloc);
- //First IMAGE_BASE_RELOCATION table
- image_base_relocation reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true);
-
- if(reloc_table.SizeOfBlock % 2)
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- unsigned long reloc_size = pe.get_directory_size(image_directory_entry_basereloc);
- unsigned long read_size = 0;
-
- //reloc_table.VirtualAddress is not checked (not so important)
- while(reloc_table.SizeOfBlock && read_size < reloc_size)
- {
- //Create relocation table
- relocation_table table;
- //Save RVA
- table.set_rva(reloc_table.VirtualAddress);
-
- if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock))
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- //List all relocations
- for(unsigned long i = sizeof(image_base_relocation); i < reloc_table.SizeOfBlock; i += sizeof(uint16_t))
- {
- relocation_entry entry(pe.section_data_from_rva<uint16_t>(current_pos + i, section_data_virtual, true));
- if(list_absolute_entries || entry.get_type() != image_rel_based_absolute)
- table.add_relocation(entry);
- }
-
- //Save table
- ret.push_back(table);
-
- //Go to next relocation block
- if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock))
- throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
- current_pos += reloc_table.SizeOfBlock;
- read_size += reloc_table.SizeOfBlock;
- reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true);
- }
-
- return ret;
-}
-
-//Simple relocations rebuilder
-//To keep PE file working, don't remove any of existing relocations in
-//relocation_table_list returned by a call to get_relocations() function
-//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
-//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
-//If save_to_pe_header is true, PE header will be modified automatically
-const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that reloc_section is attached to this PE image
- if(!pe.section_attached(reloc_section))
- throw pe_exception("Relocations section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t current_reloc_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-
- uint32_t needed_size = current_reloc_data_pos - offset_from_section_start; //Calculate needed size for relocation tables
- uint32_t size_delta = needed_size;
-
- uint32_t start_reloc_pos = current_reloc_data_pos;
-
- //Enumerate relocation tables
- for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
- {
- needed_size += static_cast<uint32_t>((*it).get_relocations().size() * sizeof(uint16_t) /* relocations */ + sizeof(image_base_relocation) /* table header */);
- //End of each table will be DWORD-aligned
- if((start_reloc_pos + needed_size - size_delta) % sizeof(uint32_t))
- needed_size += sizeof(uint16_t); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
- }
-
- //Check if reloc_section is last one. If it's not, check if there's enough place for relocations data
- if(&reloc_section != &*(pe.get_image_sections().end() - 1) &&
- (reloc_section.empty() || pe_utils::align_up(reloc_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + current_reloc_data_pos))
- throw pe_exception("Insufficient space for relocations directory", pe_exception::insufficient_space);
-
- std::string& raw_data = reloc_section.get_raw_data();
-
- //This will be done only if reloc_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + current_reloc_data_pos)
- raw_data.resize(needed_size + current_reloc_data_pos); //Expand section raw data
-
- //Enumerate relocation tables
- for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
- {
- //Create relocation table header
- image_base_relocation reloc;
- reloc.VirtualAddress = (*it).get_rva();
- const relocation_table::relocation_list& reloc_list = (*it).get_relocations();
- reloc.SizeOfBlock = static_cast<uint32_t>(sizeof(image_base_relocation) + sizeof(uint16_t) * reloc_list.size());
- if((reloc_list.size() * sizeof(uint16_t)) % sizeof(uint32_t)) //If we must align end of relocation table
- reloc.SizeOfBlock += sizeof(uint16_t);
-
- memcpy(&raw_data[current_reloc_data_pos], &reloc, sizeof(reloc));
- current_reloc_data_pos += sizeof(reloc);
-
- //Enumerate relocations in table
- for(relocation_table::relocation_list::const_iterator r = reloc_list.begin(); r != reloc_list.end(); ++r)
- {
- //Save relocations
- uint16_t reloc_value = (*r).get_item();
- memcpy(&raw_data[current_reloc_data_pos], &reloc_value, sizeof(reloc_value));
- current_reloc_data_pos += sizeof(reloc_value);
- }
-
- if(current_reloc_data_pos % sizeof(uint32_t)) //If end of table is not DWORD-aligned
- {
- memset(&raw_data[current_reloc_data_pos], 0, sizeof(uint16_t)); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
- current_reloc_data_pos += sizeof(uint16_t);
- }
- }
-
- image_directory ret(pe.rva_from_section_offset(reloc_section, start_reloc_pos), needed_size - size_delta);
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(reloc_section, auto_strip_last_section);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_basereloc, ret.get_rva());
- pe.set_directory_size(image_directory_entry_basereloc, ret.get_size());
-
- pe.clear_characteristics_flags(image_file_relocs_stripped);
- pe.set_dll_characteristics(pe.get_dll_characteristics() | image_dllcharacteristics_dynamic_base);
- }
-
- return ret;
-}
-
-//Recalculates image base with the help of relocation tables
-void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base)
-{
- pe.get_pe_type() == pe_type_32
- ? rebase_image_base<pe_types_class_32>(pe, tables, new_base)
- : rebase_image_base<pe_types_class_64>(pe, tables, new_base);
-}
-
-//RELOCATIONS
-//Recalculates image base with the help of relocation tables
-//Recalculates VAs of DWORDS/QWORDS in image according to relocations
-//Notice: if you move some critical structures like TLS, image relocations will not fix new
-//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed.
-//It is recommended to rebase image in the very beginning and move all structures afterwards.
-template<typename PEClassType>
-void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base)
-{
- //Get current image base value
- typename PEClassType::BaseSize image_base;
- pe.get_image_base(image_base);
-
- //ImageBase difference
- typename PEClassType::BaseSize base_rel = static_cast<typename PEClassType::BaseSize>(static_cast<int64_t>(new_base) - image_base);
-
- //We need to fix addresses from relocation tables
- //Enumerate relocation tables
- for(relocation_table_list::const_iterator it = tables.begin(); it != tables.end(); ++it)
- {
- const relocation_table::relocation_list& relocs = (*it).get_relocations();
-
- uint32_t base_rva = (*it).get_rva();
-
- //Enumerate relocations
- for(relocation_table::relocation_list::const_iterator rel = relocs.begin(); rel != relocs.end(); ++rel)
- {
- //Skip ABSOLUTE entries
- if((*rel).get_type() == pe_win::image_rel_based_absolute)
- continue;
-
- //Recalculate value by RVA and rewrite it
- uint32_t current_rva = base_rva + (*rel).get_rva();
- typename PEClassType::BaseSize value = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_rva, section_data_raw, true);
- value += base_rel;
- memcpy(pe.section_data_from_rva(current_rva, true), &value, sizeof(value));
- }
- }
-
- //Finally, save new image base
- pe.set_image_base_64(new_base);
-}
-}
diff --git a/tools/pe_bliss/pe_relocations.h b/tools/pe_bliss/pe_relocations.h
deleted file mode 100644
index 1bc8b2a405..0000000000
--- a/tools/pe_bliss/pe_relocations.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing relocation entry
-//RVA of relocation is not actually RVA, but
-//(real RVA) - (RVA of table)
-class relocation_entry
-{
-public:
- //Default constructor
- relocation_entry();
- //Constructor from relocation item (WORD)
- explicit relocation_entry(uint16_t relocation_value);
- //Constructor from relative rva and relocation type
- relocation_entry(uint16_t rrva, uint16_t type);
-
- //Returns RVA of relocation (actually, relative RVA from relocation table RVA)
- uint16_t get_rva() const;
- //Returns type of relocation
- uint16_t get_type() const;
-
- //Returns relocation item (rrva + type)
- uint16_t get_item() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
- //You can also use them to rebuild relocations using rebuild_relocations()
-
- //Sets RVA of relocation (actually, relative RVA from relocation table RVA)
- void set_rva(uint16_t rva);
- //Sets type of relocation
- void set_type(uint16_t type);
-
- //Sets relocation item (rrva + type)
- void set_item(uint16_t item);
-
-private:
- uint16_t rva_;
- uint16_t type_;
-};
-
-//Class representing relocation table
-class relocation_table
-{
-public:
- typedef std::vector<relocation_entry> relocation_list;
-
-public:
- //Default constructor
- relocation_table();
- //Constructor from RVA of relocation table
- explicit relocation_table(uint32_t rva);
-
- //Returns relocation list
- const relocation_list& get_relocations() const;
- //Returns RVA of block
- uint32_t get_rva() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild relocations using rebuild_relocations()
-
- //Adds relocation to table
- void add_relocation(const relocation_entry& entry);
- //Returns changeable relocation list
- relocation_list& get_relocations();
- //Sets RVA of block
- void set_rva(uint32_t rva);
-
-private:
- uint32_t rva_;
- relocation_list relocations_;
-};
-
-typedef std::vector<relocation_table> relocation_table_list;
-
-//Get relocation list of pe file, supports one-word sized relocations only
-//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed
-const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries = false);
-
-//Simple relocations rebuilder
-//To keep PE file working, don't remove any of existing relocations in
-//relocation_table_list returned by a call to get_relocations() function
-//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
-//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
-//If save_to_pe_header is true, PE header will be modified automatically
-const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-//Recalculates image base with the help of relocation tables
-//Recalculates VAs of DWORDS/QWORDS in image according to relocations
-//Notice: if you move some critical structures like TLS, image relocations will not fix new
-//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed.
-//It is recommended to rebase image in the very beginning and move all structures afterwards.
-void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base);
-
-template<typename PEClassType>
-void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base);
-}
diff --git a/tools/pe_bliss/pe_resource_manager.cpp b/tools/pe_bliss/pe_resource_manager.cpp
deleted file mode 100644
index 0ee7840ff0..0000000000
--- a/tools/pe_bliss/pe_resource_manager.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <sstream>
-#include <iomanip>
-#include <math.h>
-#include <string.h>
-#include "pe_resource_manager.h"
-#include "resource_internal.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor from root resource directory
-pe_resource_manager::pe_resource_manager(resource_directory& root_directory)
- :pe_resource_viewer(root_directory), root_dir_edit_(root_directory)
-{}
-
-resource_directory& pe_resource_manager::get_root_directory()
-{
- return root_dir_edit_;
-}
-
-//Removes all resources of given type or root name
-//If there's more than one directory entry of a given type, only the
-//first one will be deleted (that's an unusual situation)
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource_type(resource_type type)
-{
- //Search for resource type
- resource_directory::entry_list& entries = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type));
- if(it != entries.end())
- {
- //Remove it, if found
- entries.erase(it);
- return true;
- }
-
- return false;
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name)
-{
- //Search for resource type
- resource_directory::entry_list& entries = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name));
- if(it != entries.end())
- {
- //Remove it, if found
- entries.erase(it);
- return true;
- }
-
- return false;
-}
-
-//Helper to remove resource
-bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder)
-{
- //Search for resource type
- resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder);
- if(it_type != entries_type.end())
- {
- //Search for resource name/ID with "finder"
- resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list();
- resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder);
- if(it_name != entries_name.end())
- {
- //Erase resource, if found
- entries_name.erase(it_name);
- if(entries_name.empty())
- entries_type.erase(it_type);
-
- return true;
- }
- }
-
- return false;
-}
-
-//Removes all resource languages by resource type/root name and name
-//Deletes only one entry of given type and name
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name));
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name));
-}
-
-//Removes all resource languages by resource type/root name and ID
-//Deletes only one entry of given type and ID
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, uint32_t id)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id));
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id));
-}
-
-//Helper to remove resource
-bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language)
-{
- //Search for resource type
- resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder);
- if(it_type != entries_type.end())
- {
- //Search for resource name/ID with "finder"
- resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list();
- resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder);
- if(it_name != entries_name.end())
- {
- //Search for resource language
- resource_directory::entry_list& entries_lang = (*it_name).get_resource_directory().get_entry_list();
- resource_directory::entry_list::iterator it_lang = std::find_if(entries_lang.begin(), entries_lang.end(), resource_directory::id_entry_finder(language));
- if(it_lang != entries_lang.end())
- {
- //Erase resource, if found
- entries_lang.erase(it_lang);
- if(entries_lang.empty())
- {
- entries_name.erase(it_name);
- if(entries_name.empty())
- entries_type.erase(it_type);
- }
-
- return true;
- }
- }
- }
-
- return false;
-}
-
-//Removes resource language by resource type/root name and name
-//Deletes only one entry of given type, name and language
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name), language);
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name), language);
-}
-
-//Removes recource language by resource type/root name and ID
-//Deletes only one entry of given type, ID and language
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, uint32_t id, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id), language);
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language)
-{
- return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id), language);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_type_entry;
- new_type_entry.set_id(type);
-
- add_resource(data, new_type_entry, resource_directory::entry_finder(type), new_entry, finder, language, codepage, timestamp);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_type_entry;
- new_type_entry.set_name(root_name);
-
- add_resource(data, new_type_entry, resource_directory::entry_finder(root_name), new_entry, finder, language, codepage, timestamp);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, resource_directory_entry& new_root_entry, const resource_directory::entry_finder& root_finder, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- //Search for resource type
- resource_directory::entry_list* entries = &root_dir_edit_.get_entry_list();
- resource_directory::entry_list::iterator it = std::find_if(entries->begin(), entries->end(), root_finder);
- if(it == entries->end())
- {
- //Add resource type directory, if it was not found
- resource_directory dir;
- dir.set_timestamp(timestamp);
- new_root_entry.add_resource_directory(dir);
- entries->push_back(new_root_entry);
- it = entries->end() - 1;
- }
-
- //Search for resource name/ID directory with "finder"
- entries = &(*it).get_resource_directory().get_entry_list();
- it = std::find_if(entries->begin(), entries->end(), finder);
- if(it == entries->end())
- {
- //Add resource name/ID directory, if it was not found
- resource_directory dir;
- dir.set_timestamp(timestamp);
- new_entry.add_resource_directory(dir);
- entries->push_back(new_entry);
- it = entries->end() - 1;
- }
-
- //Search for data resource entry by language
- entries = &(*it).get_resource_directory().get_entry_list();
- it = std::find_if(entries->begin(), entries->end(), resource_directory::id_entry_finder(language));
- if(it != entries->end())
- entries->erase(it); //Erase it, if found
-
- //Add new data entry
- resource_directory_entry new_dir_data_entry;
- resource_data_entry data_dir(data, codepage);
- new_dir_data_entry.add_data_entry(data_dir);
- new_dir_data_entry.set_id(language);
- entries->push_back(new_dir_data_entry);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_name(name);
-
- add_resource(data, type, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_name(name);
-
- add_resource(data, root_name, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_id(id);
-
- add_resource(data, type, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_entry;
- new_entry.set_id(id);
-
- add_resource(data, root_name, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-}
diff --git a/tools/pe_bliss/pe_resource_manager.h b/tools/pe_bliss/pe_resource_manager.h
deleted file mode 100644
index 85d7f44a8a..0000000000
--- a/tools/pe_bliss/pe_resource_manager.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <sstream>
-#include <string>
-#include <memory>
-#include "pe_base.h"
-#include "pe_structures.h"
-#include "pe_resources.h"
-#include "message_table.h"
-#include "file_version_info.h"
-#include "pe_resource_viewer.h"
-#include "resource_data_info.h"
-
-namespace pe_bliss
-{
-//Derived class to edit PE resources
-class pe_resource_manager : public pe_resource_viewer
-{
-public:
- //Constructor from root resource directory
- explicit pe_resource_manager(resource_directory& root_directory);
-
- resource_directory& get_root_directory();
-
-public: //Resource editing
- //Removes all resources of given type or root name
- //If there's more than one directory entry of a given type, only the
- //first one will be deleted (that's an unusual situation)
- //Returns true if resource was deleted
- bool remove_resource_type(resource_type type);
- bool remove_resource(const std::wstring& root_name);
-
- //Removes all resource languages by resource type/root name and name
- //Deletes only one entry of given type and name
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, const std::wstring& name);
- bool remove_resource(const std::wstring& root_name, const std::wstring& name);
- //Removes all resource languages by resource type/root name and ID
- //Deletes only one entry of given type and ID
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, uint32_t id);
- bool remove_resource(const std::wstring& root_name, uint32_t id);
-
- //Removes resource language by resource type/root name and name
- //Deletes only one entry of given type, name and language
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, const std::wstring& name, uint32_t language);
- bool remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language);
- //Removes recource language by resource type/root name and ID
- //Deletes only one entry of given type, ID and language
- //Returns true if resource was deleted
- bool remove_resource(resource_type type, uint32_t id, uint32_t language);
- bool remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language);
-
- //Adds resource. If resource already exists, replaces it
- //timestamp will be used for directories that will be added
- void add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- //Adds resource. If resource already exists, replaces it
- //timestamp will be used for directories that will be added
- void add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-public:
- //Helpers to add/replace resource
- void add_resource(const std::string& data, resource_type type,
- resource_directory_entry& new_entry,
- const resource_directory::entry_finder& finder,
- uint32_t language, uint32_t codepage, uint32_t timestamp);
-
- void add_resource(const std::string& data, const std::wstring& root_name,
- resource_directory_entry& new_entry,
- const resource_directory::entry_finder& finder,
- uint32_t language, uint32_t codepage, uint32_t timestamp);
-
- void add_resource(const std::string& data, resource_directory_entry& new_root_entry,
- const resource_directory::entry_finder& root_finder,
- resource_directory_entry& new_entry,
- const resource_directory::entry_finder& finder,
- uint32_t language, uint32_t codepage, uint32_t timestamp);
-
-private:
- //Root resource directory. We're not copying it, because it might be heavy
- resource_directory& root_dir_edit_;
-
- //Helper to remove resource
- bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder);
-
- //Helper to remove resource
- bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language);
-};
-}
diff --git a/tools/pe_bliss/pe_resource_viewer.cpp b/tools/pe_bliss/pe_resource_viewer.cpp
deleted file mode 100644
index 712cc28d9b..0000000000
--- a/tools/pe_bliss/pe_resource_viewer.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <cmath>
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor from root resource_directory
-pe_resource_viewer::pe_resource_viewer(const resource_directory& root_directory)
- :root_dir_(root_directory)
-{}
-
-const resource_directory& pe_resource_viewer::get_root_directory() const
-{
- return root_dir_;
-}
-
-//Finder helpers
-bool pe_resource_viewer::has_name::operator()(const resource_directory_entry& entry) const
-{
- return entry.is_named();
-}
-
-bool pe_resource_viewer::has_id::operator()(const resource_directory_entry& entry) const
-{
- return !entry.is_named();
-}
-
-//Lists resource types existing in PE file (non-named only)
-const pe_resource_viewer::resource_type_list pe_resource_viewer::list_resource_types() const
-{
- resource_type_list ret;
-
- //Get root directory entries list
- const resource_directory::entry_list& entries = root_dir_.get_entry_list();
- for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
- {
- //List all non-named items
- if(!(*it).is_named())
- ret.push_back((*it).get_id());
- }
-
- return ret;
-}
-
-//Returns true if resource type exists
-bool pe_resource_viewer::resource_exists(resource_type type) const
-{
- const resource_directory::entry_list& entries = root_dir_.get_entry_list();
- return std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type)) != entries.end();
-}
-
-//Returns true if resource name exists
-bool pe_resource_viewer::resource_exists(const std::wstring& root_name) const
-{
- const resource_directory::entry_list& entries = root_dir_.get_entry_list();
- return std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name)) != entries.end();
-}
-
-//Helper function to get name list from entry list
-const pe_resource_viewer::resource_name_list pe_resource_viewer::get_name_list(const resource_directory::entry_list& entries)
-{
- resource_name_list ret;
-
- for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
- {
- //List all named items
- if((*it).is_named())
- ret.push_back((*it).get_name());
- }
-
- return ret;
-}
-
-//Helper function to get ID list from entry list
-const pe_resource_viewer::resource_id_list pe_resource_viewer::get_id_list(const resource_directory::entry_list& entries)
-{
- resource_id_list ret;
-
- for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
- {
- //List all non-named items
- if(!(*it).is_named())
- ret.push_back((*it).get_id());
- }
-
- return ret;
-}
-
-//Lists resource names existing in PE file by resource type
-const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(resource_type type) const
-{
- return get_name_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list());
-}
-
-//Lists resource names existing in PE file by resource name
-const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(const std::wstring& root_name) const
-{
- return get_name_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list());
-}
-
-//Lists resource IDs existing in PE file by resource type
-const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(resource_type type) const
-{
- return get_id_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list());
-}
-
-//Lists resource IDs existing in PE file by resource name
-const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(const std::wstring& root_name) const
-{
- return get_id_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list());
-}
-
-//Returns resource count by type
-unsigned long pe_resource_viewer::get_resource_count(resource_type type) const
-{
- return static_cast<unsigned long>(
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .get_entry_list()
- .size());
-}
-
-//Returns resource count by name
-unsigned long pe_resource_viewer::get_resource_count(const std::wstring& root_name) const
-{
- return static_cast<unsigned long>(
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .get_entry_list()
- .size());
-}
-
-//Returns language count of resource by resource type and name
-unsigned long pe_resource_viewer::get_language_count(resource_type type, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource names
-unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource type and ID
-unsigned long pe_resource_viewer::get_language_count(resource_type type, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource name and ID
-unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Lists resource languages by resource type and name
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Lists resource languages by resource names
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, const std::wstring& name) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Lists resource languages by resource type and ID
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Lists resource languages by resource name and ID
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, uint32_t id) const
-{
- const resource_directory::entry_list& entries =
- root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- return get_id_list(entries);
-}
-
-//Returns raw resource data by type, name and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, name and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, ID and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, ID and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const
-{
- return resource_data_info(root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, name and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, name and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_name(name)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, ID and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_id(type)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, ID and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index) const
-{
- const resource_directory::entry_list& entries = root_dir_ //Type directory
- .entry_by_name(root_name)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(id)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-}
diff --git a/tools/pe_bliss/pe_resource_viewer.h b/tools/pe_bliss/pe_resource_viewer.h
deleted file mode 100644
index e585da6a87..0000000000
--- a/tools/pe_bliss/pe_resource_viewer.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <string>
-#include "pe_structures.h"
-#include "pe_resources.h"
-#include "message_table.h"
-#include "resource_data_info.h"
-
-namespace pe_bliss
-{
- //PE resource manager allows to read resources from PE files
-class pe_resource_viewer
-{
-public:
- //Resource type enumeration
- enum resource_type
- {
- resource_cursor = 1,
- resource_bitmap = 2,
- resource_icon = 3,
- resource_menu = 4,
- resource_dialog = 5,
- resource_string = 6,
- resource_fontdir = 7,
- resource_font = 8,
- resource_accelerator = 9,
- resource_rcdata = 10,
- resource_message_table = 11,
- resource_cursor_group = 12,
- resource_icon_group = 14,
- resource_version = 16,
- resource_dlginclude = 17,
- resource_plugplay = 19,
- resource_vxd = 20,
- resource_anicursor = 21,
- resource_aniicon = 22,
- resource_html = 23,
- resource_manifest = 24
- };
-
-public:
- //Some useful typedefs
- typedef std::vector<uint32_t> resource_type_list;
- typedef std::vector<uint32_t> resource_id_list;
- typedef std::vector<std::wstring> resource_name_list;
- typedef std::vector<uint32_t> resource_language_list;
-
-public:
- //Constructor from root resource_directory from PE file
- explicit pe_resource_viewer(const resource_directory& root_directory);
-
- const resource_directory& get_root_directory() const;
-
- //Lists resource types existing in PE file (non-named only)
- const resource_type_list list_resource_types() const;
- //Returns true if resource type exists
- bool resource_exists(resource_type type) const;
- //Returns true if resource name exists
- bool resource_exists(const std::wstring& root_name) const;
-
- //Lists resource names existing in PE file by resource type
- const resource_name_list list_resource_names(resource_type type) const;
- //Lists resource names existing in PE file by resource name
- const resource_name_list list_resource_names(const std::wstring& root_name) const;
- //Lists resource IDs existing in PE file by resource type
- const resource_id_list list_resource_ids(resource_type type) const;
- //Lists resource IDs existing in PE file by resource name
- const resource_id_list list_resource_ids(const std::wstring& root_name) const;
- //Returns resource count by type
- unsigned long get_resource_count(resource_type type) const;
- //Returns resource count by name
- unsigned long get_resource_count(const std::wstring& root_name) const;
-
- //Returns language count of resource by resource type and name
- unsigned long get_language_count(resource_type type, const std::wstring& name) const;
- //Returns language count of resource by resource names
- unsigned long get_language_count(const std::wstring& root_name, const std::wstring& name) const;
- //Returns language count of resource by resource type and ID
- unsigned long get_language_count(resource_type type, uint32_t id) const;
- //Returns language count of resource by resource name and ID
- unsigned long get_language_count(const std::wstring& root_name, uint32_t id) const;
- //Lists resource languages by resource type and name
- const resource_language_list list_resource_languages(resource_type type, const std::wstring& name) const;
- //Lists resource languages by resource names
- const resource_language_list list_resource_languages(const std::wstring& root_name, const std::wstring& name) const;
- //Lists resource languages by resource type and ID
- const resource_language_list list_resource_languages(resource_type type, uint32_t id) const;
- //Lists resource languages by resource name and ID
- const resource_language_list list_resource_languages(const std::wstring& root_name, uint32_t id) const;
-
- //Returns raw resource data by type, name and language
- const resource_data_info get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const;
- //Returns raw resource data by root name, name and language
- const resource_data_info get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const;
- //Returns raw resource data by type, ID and language
- const resource_data_info get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const;
- //Returns raw resource data by root name, ID and language
- const resource_data_info get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const;
- //Returns raw resource data by type, name and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index = 0) const;
- //Returns raw resource data by root name, name and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index = 0) const;
- //Returns raw resource data by type, ID and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index = 0) const;
- //Returns raw resource data by root name, ID and index in language directory (instead of language)
- const resource_data_info get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index = 0) const;
-
-protected:
- //Root resource directory. We're not copying it, because it might be heavy
- const resource_directory& root_dir_;
-
- //Helper function to get ID list from entry list
- static const resource_id_list get_id_list(const resource_directory::entry_list& entries);
- //Helper function to get name list from entry list
- static const resource_name_list get_name_list(const resource_directory::entry_list& entries);
-
-protected:
- //Helper structure - finder of resource_directory_entry that is named
- struct has_name
- {
- public:
- bool operator()(const resource_directory_entry& entry) const;
- };
-
- //Helper structure - finder of resource_directory_entry that is not named (has id)
- struct has_id
- {
- public:
- bool operator()(const resource_directory_entry& entry) const;
- };
-};
-}
diff --git a/tools/pe_bliss/pe_resources.cpp b/tools/pe_bliss/pe_resources.cpp
deleted file mode 100644
index 189aba1f76..0000000000
--- a/tools/pe_bliss/pe_resources.cpp
+++ /dev/null
@@ -1,726 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_resources.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//RESOURCES
-//Default constructor
-resource_data_entry::resource_data_entry()
- :codepage_(0)
-{}
-
-//Constructor from data
-resource_data_entry::resource_data_entry(const std::string& data, uint32_t codepage)
- :codepage_(codepage), data_(data)
-{}
-
-//Returns resource data codepage
-uint32_t resource_data_entry::get_codepage() const
-{
- return codepage_;
-}
-
-//Returns resource data
-const std::string& resource_data_entry::get_data() const
-{
- return data_;
-}
-
-//Sets resource data codepage
-void resource_data_entry::set_codepage(uint32_t codepage)
-{
- codepage_ = codepage;
-}
-
-//Sets resource data
-void resource_data_entry::set_data(const std::string& data)
-{
- data_ = data;
-}
-
-//Default constructor
-resource_directory_entry::includes::includes()
- :data_(0)
-{}
-
-//Default constructor
-resource_directory_entry::resource_directory_entry()
- :id_(0), includes_data_(false), named_(false)
-{}
-
-//Copy constructor
-resource_directory_entry::resource_directory_entry(const resource_directory_entry& other)
- :id_(other.id_), name_(other.name_), includes_data_(other.includes_data_), named_(other.named_)
-{
- //If union'ed pointer is not zero
- if(other.ptr_.data_)
- {
- if(other.includes_data())
- ptr_.data_ = new resource_data_entry(*other.ptr_.data_);
- else
- ptr_.dir_ = new resource_directory(*other.ptr_.dir_);
- }
-}
-
-//Copy assignment operator
-resource_directory_entry& resource_directory_entry::operator=(const resource_directory_entry& other)
-{
- release();
-
- id_ = other.id_;
- name_ = other.name_;
- includes_data_ = other.includes_data_;
- named_ = other.named_;
-
- //If other union'ed pointer is not zero
- if(other.ptr_.data_)
- {
- if(other.includes_data())
- ptr_.data_ = new resource_data_entry(*other.ptr_.data_);
- else
- ptr_.dir_ = new resource_directory(*other.ptr_.dir_);
- }
-
- return *this;
-}
-
-//Destroys included data
-void resource_directory_entry::release()
-{
- //If union'ed pointer is not zero
- if(ptr_.data_)
- {
- if(includes_data())
- delete ptr_.data_;
- else
- delete ptr_.dir_;
-
- ptr_.data_ = 0;
- }
-}
-
-//Destructor
-resource_directory_entry::~resource_directory_entry()
-{
- release();
-}
-
-//Returns entry ID
-uint32_t resource_directory_entry::get_id() const
-{
- return id_;
-}
-
-//Returns entry name
-const std::wstring& resource_directory_entry::get_name() const
-{
- return name_;
-}
-
-//Returns true, if entry has name
-//Returns false, if entry has ID
-bool resource_directory_entry::is_named() const
-{
- return named_;
-}
-
-//Returns true, if entry includes resource_data_entry
-//Returns false, if entry includes resource_directory
-bool resource_directory_entry::includes_data() const
-{
- return includes_data_;
-}
-
-//Returns resource_directory if entry includes it, otherwise throws an exception
-const resource_directory& resource_directory_entry::get_resource_directory() const
-{
- if(!ptr_.dir_ || includes_data_)
- throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error);
-
- return *ptr_.dir_;
-}
-
-//Returns resource_data_entry if entry includes it, otherwise throws an exception
-const resource_data_entry& resource_directory_entry::get_data_entry() const
-{
- if(!ptr_.data_ || !includes_data_)
- throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error);
-
- return *ptr_.data_;
-}
-
-//Returns resource_directory if entry includes it, otherwise throws an exception
-resource_directory& resource_directory_entry::get_resource_directory()
-{
- if(!ptr_.dir_ || includes_data_)
- throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error);
-
- return *ptr_.dir_;
-}
-
-//Returns resource_data_entry if entry includes it, otherwise throws an exception
-resource_data_entry& resource_directory_entry::get_data_entry()
-{
- if(!ptr_.data_ || !includes_data_)
- throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error);
-
- return *ptr_.data_;
-}
-
-//Sets entry name
-void resource_directory_entry::set_name(const std::wstring& name)
-{
- name_ = name;
- named_ = true;
- id_ = 0;
-}
-
-//Sets entry ID
-void resource_directory_entry::set_id(uint32_t id)
-{
- id_ = id;
- named_ = false;
- name_.clear();
-}
-
-//Adds resource_data_entry
-void resource_directory_entry::add_data_entry(const resource_data_entry& entry)
-{
- release();
- ptr_.data_ = new resource_data_entry(entry);
- includes_data_ = true;
-}
-
-//Adds resource_directory
-void resource_directory_entry::add_resource_directory(const resource_directory& dir)
-{
- release();
- ptr_.dir_ = new resource_directory(dir);
- includes_data_ = false;
-}
-
-//Default constructor
-resource_directory::resource_directory()
- :characteristics_(0),
- timestamp_(0),
- major_version_(0), minor_version_(0),
- number_of_named_entries_(0), number_of_id_entries_(0)
-{}
-
-//Constructor from data
-resource_directory::resource_directory(const image_resource_directory& dir)
- :characteristics_(dir.Characteristics),
- timestamp_(dir.TimeDateStamp),
- major_version_(dir.MajorVersion), minor_version_(dir.MinorVersion),
- number_of_named_entries_(0), number_of_id_entries_(0) //Set to zero here, calculate on add
-{}
-
-//Returns characteristics of directory
-uint32_t resource_directory::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns date and time stamp of directory
-uint32_t resource_directory::get_timestamp() const
-{
- return timestamp_;
-}
-
-//Returns major version of directory
-uint16_t resource_directory::get_major_version() const
-{
- return major_version_;
-}
-
-//Returns minor version of directory
-uint16_t resource_directory::get_minor_version() const
-{
- return minor_version_;
-}
-
-//Returns number of named entries
-uint32_t resource_directory::get_number_of_named_entries() const
-{
- return number_of_named_entries_;
-}
-
-//Returns number of ID entries
-uint32_t resource_directory::get_number_of_id_entries() const
-{
- return number_of_id_entries_;
-}
-
-//Returns resource_directory_entry array
-const resource_directory::entry_list& resource_directory::get_entry_list() const
-{
- return entries_;
-}
-
-//Returns resource_directory_entry array
-resource_directory::entry_list& resource_directory::get_entry_list()
-{
- return entries_;
-}
-
-//Adds resource_directory_entry
-void resource_directory::add_resource_directory_entry(const resource_directory_entry& entry)
-{
- entries_.push_back(entry);
- if(entry.is_named())
- ++number_of_named_entries_;
- else
- ++number_of_id_entries_;
-}
-
-//Clears resource_directory_entry array
-void resource_directory::clear_resource_directory_entry_list()
-{
- entries_.clear();
- number_of_named_entries_ = 0;
- number_of_id_entries_ = 0;
-}
-
-//Sets characteristics of directory
-void resource_directory::set_characteristics(uint32_t characteristics)
-{
- characteristics_ = characteristics;
-}
-
-//Sets date and time stamp of directory
-void resource_directory::set_timestamp(uint32_t timestamp)
-{
- timestamp_ = timestamp;
-}
-
-//Sets number of named entries
-void resource_directory::set_number_of_named_entries(uint32_t number)
-{
- number_of_named_entries_ = number;
-}
-
-//Sets number of ID entries
-void resource_directory::set_number_of_id_entries(uint32_t number)
-{
- number_of_id_entries_ = number;
-}
-
-//Sets major version of directory
-void resource_directory::set_major_version(uint16_t major_version)
-{
- major_version_ = major_version;
-}
-
-//Sets minor version of directory
-void resource_directory::get_minor_version(uint16_t minor_version)
-{
- minor_version_ = minor_version;
-}
-
-//Processes resource directory
-const resource_directory process_resource_directory(const pe_base& pe, uint32_t res_rva, uint32_t offset_to_directory, std::set<uint32_t>& processed)
-{
- resource_directory ret;
-
- //Check for resource loops
- if(!processed.insert(offset_to_directory).second)
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- if(!pe_utils::is_sum_safe(res_rva, offset_to_directory))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- //Get root IMAGE_RESOURCE_DIRECTORY
- image_resource_directory directory = pe.section_data_from_rva<image_resource_directory>(res_rva + offset_to_directory, section_data_virtual, true);
-
- ret = resource_directory(directory);
-
- //Check DWORDs for possible overflows
- if(!pe_utils::is_sum_safe(directory.NumberOfIdEntries, directory.NumberOfNamedEntries)
- || directory.NumberOfIdEntries + directory.NumberOfNamedEntries >= pe_utils::max_dword / sizeof(image_resource_directory_entry) + sizeof(image_resource_directory))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- if(!pe_utils::is_sum_safe(offset_to_directory, sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry))
- || !pe_utils::is_sum_safe(res_rva, offset_to_directory + sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry)))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- for(unsigned long i = 0; i != static_cast<unsigned long>(directory.NumberOfIdEntries) + directory.NumberOfNamedEntries; ++i)
- {
- //Read directory entries one by one
- image_resource_directory_entry dir_entry = pe.section_data_from_rva<image_resource_directory_entry>(
- res_rva + sizeof(image_resource_directory) + i * sizeof(image_resource_directory_entry) + offset_to_directory, section_data_virtual, true);
-
- //Create directory entry structure
- resource_directory_entry entry;
-
- //If directory is named
- if(dir_entry.NameIsString)
- {
- if(!pe_utils::is_sum_safe(res_rva + sizeof(uint16_t) /* safe */, dir_entry.NameOffset))
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- //get directory name length
- uint16_t directory_name_length = pe.section_data_from_rva<uint16_t>(res_rva + dir_entry.NameOffset, section_data_virtual, true);
-
- //Check name length
- if(pe.section_data_length_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)
- < directory_name_length)
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-#ifdef PE_BLISS_WINDOWS
- //Set entry UNICODE name
- entry.set_name(std::wstring(
- reinterpret_cast<const wchar_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)),
- directory_name_length));
-#else
- //Set entry UNICODE name
- entry.set_name(pe_utils::from_ucs2(u16string(
- reinterpret_cast<const unicode16_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)),
- directory_name_length)));
-#endif
- }
- else
- {
- //Else - set directory ID
- entry.set_id(dir_entry.Id);
- }
-
- //If directory entry has another resource directory
- if(dir_entry.DataIsDirectory)
- {
- entry.add_resource_directory(process_resource_directory(pe, res_rva, dir_entry.OffsetToDirectory, processed));
- }
- else
- {
- //If directory entry has data
- image_resource_data_entry data_entry = pe.section_data_from_rva<image_resource_data_entry>(
- res_rva + dir_entry.OffsetToData, section_data_virtual, true);
-
- //Check byte count that stated by data entry
- if(pe.section_data_length_from_rva(data_entry.OffsetToData, data_entry.OffsetToData, section_data_virtual, true) < data_entry.Size)
- throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
- //Add data entry to directory entry
- entry.add_data_entry(resource_data_entry(
- std::string(pe.section_data_from_rva(data_entry.OffsetToData, section_data_virtual, true), data_entry.Size),
- data_entry.CodePage));
- }
-
- //Save directory entry
- ret.add_resource_directory_entry(entry);
- }
-
- //Return resource directory
- return ret;
-}
-
-//Helper function to calculate needed space for resource data
-void calculate_resource_data_space(const resource_directory& root, uint32_t aligned_offset_from_section_start, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings)
-{
- needed_size_for_structures += sizeof(image_resource_directory);
- for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- needed_size_for_structures += sizeof(image_resource_directory_entry);
-
- if((*it).is_named())
- needed_size_for_strings += static_cast<uint32_t>(((*it).get_name().length() + 1) * 2 /* unicode */ + sizeof(uint16_t) /* for string length */);
-
- if(!(*it).includes_data())
- calculate_resource_data_space((*it).get_resource_directory(), aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
- }
-}
-
-//Helper function to calculate needed space for resource data
-void calculate_resource_data_space(const resource_directory& root, uint32_t needed_size_for_structures, uint32_t needed_size_for_strings, uint32_t& needed_size_for_data, uint32_t& current_data_pos)
-{
- for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- if((*it).includes_data())
- {
- uint32_t data_size = static_cast<uint32_t>((*it).get_data_entry().get_data().length()
- + sizeof(image_resource_data_entry)
- + (pe_utils::align_up(current_data_pos, sizeof(uint32_t)) - current_data_pos) /* alignment */);
- needed_size_for_data += data_size;
- current_data_pos += data_size;
- }
- else
- {
- calculate_resource_data_space((*it).get_resource_directory(), needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
- }
- }
-}
-
-//Helper: sorts resource directory entries
-struct entry_sorter
-{
-public:
- bool operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const;
-};
-
-//Helper function to rebuild resource directory
-void rebuild_resource_directory(pe_base& pe, section& resource_section, resource_directory& root, uint32_t& current_structures_pos, uint32_t& current_data_pos, uint32_t& current_strings_pos, uint32_t offset_from_section_start)
-{
- //Create resource directory
- image_resource_directory dir = {0};
- dir.Characteristics = root.get_characteristics();
- dir.MajorVersion = root.get_major_version();
- dir.MinorVersion = root.get_minor_version();
- dir.TimeDateStamp = root.get_timestamp();
-
- {
- resource_directory::entry_list& entries = root.get_entry_list();
- std::sort(entries.begin(), entries.end(), entry_sorter());
- }
-
- //Calculate number of named and ID entries
- for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- if((*it).is_named())
- ++dir.NumberOfNamedEntries;
- else
- ++dir.NumberOfIdEntries;
- }
-
- std::string& raw_data = resource_section.get_raw_data();
-
- //Save resource directory
- memcpy(&raw_data[current_structures_pos], &dir, sizeof(dir));
- current_structures_pos += sizeof(dir);
-
- uint32_t this_current_structures_pos = current_structures_pos;
-
- current_structures_pos += sizeof(image_resource_directory_entry) * (dir.NumberOfNamedEntries + dir.NumberOfIdEntries);
-
- //Create all resource directory entries
- for(resource_directory::entry_list::iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
- {
- image_resource_directory_entry entry;
- if((*it).is_named())
- {
- entry.Name = 0x80000000 | (current_strings_pos - offset_from_section_start);
- uint16_t unicode_length = static_cast<uint16_t>((*it).get_name().length());
- memcpy(&raw_data[current_strings_pos], &unicode_length, sizeof(unicode_length));
- current_strings_pos += sizeof(unicode_length);
-
-#ifdef PE_BLISS_WINDOWS
- memcpy(&raw_data[current_strings_pos], (*it).get_name().c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
-#else
- {
- u16string str(pe_utils::to_ucs2((*it).get_name()));
- memcpy(&raw_data[current_strings_pos], str.c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
- }
-#endif
-
- current_strings_pos += static_cast<unsigned long>((*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
- }
- else
- {
- entry.Name = (*it).get_id();
- }
-
- if((*it).includes_data())
- {
- current_data_pos = pe_utils::align_up(current_data_pos, sizeof(uint32_t));
- image_resource_data_entry data_entry = {0};
- data_entry.CodePage = (*it).get_data_entry().get_codepage();
- data_entry.Size = static_cast<uint32_t>((*it).get_data_entry().get_data().length());
- data_entry.OffsetToData = pe.rva_from_section_offset(resource_section, current_data_pos + sizeof(data_entry));
-
- entry.OffsetToData = current_data_pos - offset_from_section_start;
-
- memcpy(&raw_data[current_data_pos], &data_entry, sizeof(data_entry));
- current_data_pos += sizeof(data_entry);
-
- memcpy(&raw_data[current_data_pos], (*it).get_data_entry().get_data().data(), data_entry.Size);
- current_data_pos += data_entry.Size;
-
- memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry));
- this_current_structures_pos += sizeof(entry);
- }
- else
- {
- entry.OffsetToData = 0x80000000 | (current_structures_pos - offset_from_section_start);
-
- memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry));
- this_current_structures_pos += sizeof(entry);
-
- rebuild_resource_directory(pe, resource_section, (*it).get_resource_directory(), current_structures_pos, current_data_pos, current_strings_pos, offset_from_section_start);
- }
- }
-}
-
-//Helper function to rebuild resource directory
-bool entry_sorter::operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const
-{
- if(entry1.is_named() && entry2.is_named())
- return entry1.get_name() < entry2.get_name();
- else if(!entry1.is_named() && !entry2.is_named())
- return entry1.get_id() < entry2.get_id();
- else
- return entry1.is_named();
-}
-
-//Resources rebuilder
-//resource_directory - root resource directory
-//resources_section - section where resource directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from resources_section raw data start
-//resource_directory is non-constant, because it will be sorted
-//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
-//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
-//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
-const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that resources_section is attached to this PE image
- if(!pe.section_attached(resources_section))
- throw pe_exception("Resource section must be attached to PE file", pe_exception::section_is_not_attached);
-
- //Check resource directory correctness
- if(info.get_entry_list().empty())
- throw pe_exception("Empty resource directory", pe_exception::incorrect_resource_directory);
-
- uint32_t aligned_offset_from_section_start = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
- uint32_t needed_size_for_structures = aligned_offset_from_section_start - offset_from_section_start; //Calculate needed size for resource tables and data
- uint32_t needed_size_for_strings = 0;
- uint32_t needed_size_for_data = 0;
-
- calculate_resource_data_space(info, aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
-
- {
- uint32_t current_data_pos = aligned_offset_from_section_start + needed_size_for_structures + needed_size_for_strings;
- calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
- }
-
- uint32_t needed_size = needed_size_for_structures + needed_size_for_strings + needed_size_for_data;
-
- //Check if resources_section is last one. If it's not, check if there's enough place for resource data
- if(&resources_section != &*(pe.get_image_sections().end() - 1) &&
- (resources_section.empty() || pe_utils::align_up(resources_section.get_size_of_raw_data(), pe.get_file_alignment())
- < needed_size + aligned_offset_from_section_start))
- throw pe_exception("Insufficient space for resource directory", pe_exception::insufficient_space);
-
- std::string& raw_data = resources_section.get_raw_data();
-
- //This will be done only if resources_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + aligned_offset_from_section_start)
- raw_data.resize(needed_size + aligned_offset_from_section_start); //Expand section raw data
-
- uint32_t current_structures_pos = aligned_offset_from_section_start;
- uint32_t current_strings_pos = current_structures_pos + needed_size_for_structures;
- uint32_t current_data_pos = current_strings_pos + needed_size_for_strings;
- rebuild_resource_directory(pe, resources_section, info, current_structures_pos, current_data_pos, current_strings_pos, aligned_offset_from_section_start);
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(resources_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(resources_section, aligned_offset_from_section_start), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_resource, ret.get_rva());
- pe.set_directory_size(image_directory_entry_resource, ret.get_size());
- }
-
- return ret;
-}
-
-//Returns resources from PE file
-const resource_directory get_resources(const pe_base& pe)
-{
- resource_directory ret;
-
- if(!pe.has_resources())
- return ret;
-
- //Get resource directory RVA
- uint32_t res_rva = pe.get_directory_rva(image_directory_entry_resource);
-
- //Store already processed directories to avoid resource loops
- std::set<uint32_t> processed;
-
- //Process all directories (recursion)
- ret = process_resource_directory(pe, res_rva, 0, processed);
-
- return ret;
-}
-
-//Finds resource_directory_entry by ID
-resource_directory::id_entry_finder::id_entry_finder(uint32_t id)
- :id_(id)
-{}
-
-bool resource_directory::id_entry_finder::operator()(const resource_directory_entry& entry) const
-{
- return !entry.is_named() && entry.get_id() == id_;
-}
-
-//Finds resource_directory_entry by name
-resource_directory::name_entry_finder::name_entry_finder(const std::wstring& name)
- :name_(name)
-{}
-
-bool resource_directory::name_entry_finder::operator()(const resource_directory_entry& entry) const
-{
- return entry.is_named() && entry.get_name() == name_;
-}
-
-//Finds resource_directory_entry by name or ID (universal)
-resource_directory::entry_finder::entry_finder(const std::wstring& name)
- :name_(name), named_(true)
-{}
-
-resource_directory::entry_finder::entry_finder(uint32_t id)
- :id_(id), named_(false)
-{}
-
-bool resource_directory::entry_finder::operator()(const resource_directory_entry& entry) const
-{
- if(named_)
- return entry.is_named() && entry.get_name() == name_;
- else
- return !entry.is_named() && entry.get_id() == id_;
-}
-
-//Returns resource_directory_entry by ID. If not found - throws an exception
-const resource_directory_entry& resource_directory::entry_by_id(uint32_t id) const
-{
- entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), id_entry_finder(id));
- if(i == entries_.end())
- throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found);
-
- return *i;
-}
-
-//Returns resource_directory_entry by name. If not found - throws an exception
-const resource_directory_entry& resource_directory::entry_by_name(const std::wstring& name) const
-{
- entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), name_entry_finder(name));
- if(i == entries_.end())
- throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found);
-
- return *i;
-}
-}
diff --git a/tools/pe_bliss/pe_resources.h b/tools/pe_bliss/pe_resources.h
deleted file mode 100644
index 1eb6437563..0000000000
--- a/tools/pe_bliss/pe_resources.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include <set>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing resource data entry
-class resource_data_entry
-{
-public:
- //Default constructor
- resource_data_entry();
- //Constructor from data
- resource_data_entry(const std::string& data, uint32_t codepage);
-
- //Returns resource data codepage
- uint32_t get_codepage() const;
- //Returns resource data
- const std::string& get_data() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild resource directory
-
- //Sets resource data codepage
- void set_codepage(uint32_t codepage);
- //Sets resource data
- void set_data(const std::string& data);
-
-private:
- uint32_t codepage_; //Resource data codepage
- std::string data_; //Resource data
-};
-
-//Forward declaration
-class resource_directory;
-
-//Class representing resource directory entry
-class resource_directory_entry
-{
-public:
- //Default constructor
- resource_directory_entry();
- //Copy constructor
- resource_directory_entry(const resource_directory_entry& other);
- //Copy assignment operator
- resource_directory_entry& operator=(const resource_directory_entry& other);
-
- //Returns entry ID
- uint32_t get_id() const;
- //Returns entry name
- const std::wstring& get_name() const;
- //Returns true, if entry has name
- //Returns false, if entry has ID
- bool is_named() const;
-
- //Returns true, if entry includes resource_data_entry
- //Returns false, if entry includes resource_directory
- bool includes_data() const;
- //Returns resource_directory if entry includes it, otherwise throws an exception
- const resource_directory& get_resource_directory() const;
- //Returns resource_data_entry if entry includes it, otherwise throws an exception
- const resource_data_entry& get_data_entry() const;
-
- //Destructor
- ~resource_directory_entry();
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild resource directory
-
- //Sets entry name
- void set_name(const std::wstring& name);
- //Sets entry ID
- void set_id(uint32_t id);
-
- //Returns resource_directory if entry includes it, otherwise throws an exception
- resource_directory& get_resource_directory();
- //Returns resource_data_entry if entry includes it, otherwise throws an exception
- resource_data_entry& get_data_entry();
-
- //Adds resource_data_entry
- void add_data_entry(const resource_data_entry& entry);
- //Adds resource_directory
- void add_resource_directory(const resource_directory& dir);
-
-private:
- //Destroys included data
- void release();
-
-private:
- uint32_t id_;
- std::wstring name_;
-
- union includes
- {
- //Default constructor
- includes();
-
- //We use pointers, we're doing manual copying here
- class resource_data_entry* data_;
- class resource_directory* dir_; //We use pointer, because structs include each other
- };
-
- includes ptr_;
-
- bool includes_data_, named_;
-};
-
-//Class representing resource directory
-class resource_directory
-{
-public:
- typedef std::vector<resource_directory_entry> entry_list;
-
-public:
- //Default constructor
- resource_directory();
- //Constructor from data
- explicit resource_directory(const pe_win::image_resource_directory& dir);
-
- //Returns characteristics of directory
- uint32_t get_characteristics() const;
- //Returns date and time stamp of directory
- uint32_t get_timestamp() const;
- //Returns number of named entries
- uint32_t get_number_of_named_entries() const;
- //Returns number of ID entries
- uint32_t get_number_of_id_entries() const;
- //Returns major version of directory
- uint16_t get_major_version() const;
- //Returns minor version of directory
- uint16_t get_minor_version() const;
- //Returns resource_directory_entry array
- const entry_list& get_entry_list() const;
- //Returns resource_directory_entry by ID. If not found - throws an exception
- const resource_directory_entry& entry_by_id(uint32_t id) const;
- //Returns resource_directory_entry by name. If not found - throws an exception
- const resource_directory_entry& entry_by_name(const std::wstring& name) const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild resource directory
-
- //Adds resource_directory_entry
- void add_resource_directory_entry(const resource_directory_entry& entry);
- //Clears resource_directory_entry array
- void clear_resource_directory_entry_list();
-
- //Sets characteristics of directory
- void set_characteristics(uint32_t characteristics);
- //Sets date and time stamp of directory
- void set_timestamp(uint32_t timestamp);
- //Sets number of named entries
- void set_number_of_named_entries(uint32_t number);
- //Sets number of ID entries
- void set_number_of_id_entries(uint32_t number);
- //Sets major version of directory
- void set_major_version(uint16_t major_version);
- //Sets minor version of directory
- void get_minor_version(uint16_t minor_version);
-
- //Returns resource_directory_entry array
- entry_list& get_entry_list();
-
-private:
- uint32_t characteristics_;
- uint32_t timestamp_;
- uint16_t major_version_, minor_version_;
- uint32_t number_of_named_entries_, number_of_id_entries_;
- entry_list entries_;
-
-public: //Finder helpers
- //Finds resource_directory_entry by ID
- struct id_entry_finder
- {
- public:
- explicit id_entry_finder(uint32_t id);
- bool operator()(const resource_directory_entry& entry) const;
-
- private:
- uint32_t id_;
- };
-
- //Finds resource_directory_entry by name
- struct name_entry_finder
- {
- public:
- explicit name_entry_finder(const std::wstring& name);
- bool operator()(const resource_directory_entry& entry) const;
-
- private:
- std::wstring name_;
- };
-
- //Finds resource_directory_entry by name or ID (universal)
- struct entry_finder
- {
- public:
- explicit entry_finder(const std::wstring& name);
- explicit entry_finder(uint32_t id);
- bool operator()(const resource_directory_entry& entry) const;
-
- private:
- std::wstring name_;
- uint32_t id_;
- bool named_;
- };
-};
-
-//Returns resources (root resource_directory) from PE file
-const resource_directory get_resources(const pe_base& pe);
-
-//Resources rebuilder
-//resource_directory - root resource directory
-//resources_section - section where resource directory will be placed (must be attached to PE image)
-//resource_directory is non-constant, because it will be sorted
-//offset_from_section_start - offset from resources_section raw data start
-//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
-//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
-//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
-const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/pe_rich_data.cpp b/tools/pe_bliss/pe_rich_data.cpp
deleted file mode 100644
index e92f7ddc1b..0000000000
--- a/tools/pe_bliss/pe_rich_data.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "pe_rich_data.h"
-
-namespace pe_bliss
-{
-//STUB OVERLAY
-//Default constructor
-rich_data::rich_data()
- :number_(0), version_(0), times_(0)
-{}
-
-//Who knows, what these fields mean...
-uint32_t rich_data::get_number() const
-{
- return number_;
-}
-
-uint32_t rich_data::get_version() const
-{
- return version_;
-}
-
-uint32_t rich_data::get_times() const
-{
- return times_;
-}
-
-void rich_data::set_number(uint32_t number)
-{
- number_ = number;
-}
-
-void rich_data::set_version(uint32_t version)
-{
- version_ = version;
-}
-
-void rich_data::set_times(uint32_t times)
-{
- times_ = times;
-}
-
-//Returns MSVC rich data
-const rich_data_list get_rich_data(const pe_base& pe)
-{
- //Returned value
- rich_data_list ret;
-
- const std::string& rich_overlay = pe.get_stub_overlay();
-
- //If there's no rich overlay, return empty vector
- if(rich_overlay.size() < sizeof(uint32_t))
- return ret;
-
- //True if rich data was found
- bool found = false;
-
- //Rich overlay ID ("Rich" word)
- static const uint32_t rich_overlay_id = 0x68636952;
-
- //Search for rich data overlay ID
- const char* begin = &rich_overlay[0];
- const char* end = begin + rich_overlay.length();
- for(; begin != end; ++begin)
- {
- if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id)
- {
- found = true; //We've found it!
- break;
- }
- }
-
- //If we found it
- if(found)
- {
- //Check remaining length
- if(static_cast<size_t>(end - begin) < sizeof(uint32_t))
- return ret;
-
- //The XOR key is after "Rich" word, we should get it
- uint32_t xorkey = *reinterpret_cast<const uint32_t*>(begin + sizeof(uint32_t));
-
- //True if rich data was found
- found = false;
-
- //Second search for signature "DanS"
- begin = &rich_overlay[0];
- for(; begin != end; ++begin)
- {
- if((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) == 0x536e6144) //"DanS"
- {
- found = true;
- break;
- }
- }
-
- //If second signature is found
- if(found)
- {
- begin += sizeof(uint32_t) * 3;
- //List all rich data structures
- while(begin < end)
- {
- begin += sizeof(uint32_t);
- if(begin >= end)
- break;
-
- //Check for rich overlay data end ("Rich" word reached)
- if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id)
- break;
-
- //Create rich_data structure
- rich_data data;
- data.set_number((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) >> 16);
- data.set_version((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) & 0xFFFF);
-
- begin += sizeof(uint32_t);
- if(begin >= end)
- break;
-
- data.set_times(*reinterpret_cast<const uint32_t*>(begin) ^ xorkey);
-
- //Save rich data structure
- ret.push_back(data);
- }
- }
- }
-
- //Return rich data structures list
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_rich_data.h b/tools/pe_bliss/pe_rich_data.h
deleted file mode 100644
index 3e01d3c011..0000000000
--- a/tools/pe_bliss/pe_rich_data.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Rich data overlay class of Microsoft Visual Studio
-class rich_data
-{
-public:
- //Default constructor
- rich_data();
-
-public: //Getters
- //Who knows, what these fields mean...
- uint32_t get_number() const;
- uint32_t get_version() const;
- uint32_t get_times() const;
-
-public: //Setters, used by PE library only
- void set_number(uint32_t number);
- void set_version(uint32_t version);
- void set_times(uint32_t times);
-
-private:
- uint32_t number_;
- uint32_t version_;
- uint32_t times_;
-};
-
-//Rich data list typedef
-typedef std::vector<rich_data> rich_data_list;
-
-//Returns a vector with rich data (stub overlay)
-const rich_data_list get_rich_data(const pe_base& pe);
-}
diff --git a/tools/pe_bliss/pe_section.cpp b/tools/pe_bliss/pe_section.cpp
deleted file mode 100644
index 72127e22e2..0000000000
--- a/tools/pe_bliss/pe_section.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "utils.h"
-#include "pe_section.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Section structure default constructor
-section::section()
- :old_size_(static_cast<size_t>(-1))
-{
- memset(&header_, 0, sizeof(image_section_header));
-}
-
-//Sets the name of section (8 characters maximum)
-void section::set_name(const std::string& name)
-{
- memset(header_.Name, 0, sizeof(header_.Name));
- memcpy(header_.Name, name.c_str(), std::min<size_t>(name.length(), sizeof(header_.Name)));
-}
-
-//Returns section name
-const std::string section::get_name() const
-{
- char buf[9] = {0};
- memcpy(buf, header_.Name, 8);
- return std::string(buf);
-}
-
-//Set flag (attribute) of section
-section& section::set_flag(uint32_t flag, bool setflag)
-{
- if(setflag)
- header_.Characteristics |= flag;
- else
- header_.Characteristics &= ~flag;
-
- return *this;
-}
-
-//Sets "readable" attribute of section
-section& section::readable(bool readable)
-{
- return set_flag(image_scn_mem_read, readable);
-}
-
-//Sets "writeable" attribute of section
-section& section::writeable(bool writeable)
-{
- return set_flag(image_scn_mem_write, writeable);
-}
-
-//Sets "executable" attribute of section
-section& section::executable(bool executable)
-{
- return set_flag(image_scn_mem_execute, executable);
-}
-
-//Sets "shared" attribute of section
-section& section::shared(bool shared)
-{
- return set_flag(image_scn_mem_shared, shared);
-}
-
-//Sets "discardable" attribute of section
-section& section::discardable(bool discardable)
-{
- return set_flag(image_scn_mem_discardable, discardable);
-}
-
-//Returns true if section is readable
-bool section::readable() const
-{
- return (header_.Characteristics & image_scn_mem_read) != 0;
-}
-
-//Returns true if section is writeable
-bool section::writeable() const
-{
- return (header_.Characteristics & image_scn_mem_write) != 0;
-}
-
-//Returns true if section is executable
-bool section::executable() const
-{
- return (header_.Characteristics & image_scn_mem_execute) != 0;
-}
-
-bool section::shared() const
-{
- return (header_.Characteristics & image_scn_mem_shared) != 0;
-}
-
-bool section::discardable() const
-{
- return (header_.Characteristics & image_scn_mem_discardable) != 0;
-}
-
-//Returns true if section has no RAW data
-bool section::empty() const
-{
- if(old_size_ != static_cast<size_t>(-1)) //If virtual memory is mapped, check raw data length (old_size_)
- return old_size_ == 0;
- else
- return raw_data_.empty();
-}
-
-//Returns raw section data from file image
-std::string& section::get_raw_data()
-{
- unmap_virtual();
- return raw_data_;
-}
-
-//Sets raw section data from file image
-void section::set_raw_data(const std::string& data)
-{
- old_size_ = static_cast<size_t>(-1);
- raw_data_ = data;
-}
-
-//Returns raw section data from file image
-const std::string& section::get_raw_data() const
-{
- unmap_virtual();
- return raw_data_;
-}
-
-//Returns mapped virtual section data
-const std::string& section::get_virtual_data(uint32_t section_alignment) const
-{
- map_virtual(section_alignment);
- return raw_data_;
-}
-
-//Returns mapped virtual section data
-std::string& section::get_virtual_data(uint32_t section_alignment)
-{
- map_virtual(section_alignment);
- return raw_data_;
-}
-
-//Maps virtual section data
-void section::map_virtual(uint32_t section_alignment) const
-{
- uint32_t aligned_virtual_size = get_aligned_virtual_size(section_alignment);
- if(old_size_ == static_cast<size_t>(-1) && aligned_virtual_size && aligned_virtual_size > raw_data_.length())
- {
- old_size_ = raw_data_.length();
- raw_data_.resize(aligned_virtual_size, 0);
- }
-}
-
-//Unmaps virtual section data
-void section::unmap_virtual() const
-{
- if(old_size_ != static_cast<size_t>(-1))
- {
- raw_data_.resize(old_size_, 0);
- old_size_ = static_cast<size_t>(-1);
- }
-}
-
-//Returns section virtual size
-uint32_t section::get_virtual_size() const
-{
- return header_.Misc.VirtualSize;
-}
-
-//Returns section virtual address
-uint32_t section::get_virtual_address() const
-{
- return header_.VirtualAddress;
-}
-
-//Returns size of section raw data
-uint32_t section::get_size_of_raw_data() const
-{
- return header_.SizeOfRawData;
-}
-
-//Returns pointer to raw section data in PE file
-uint32_t section::get_pointer_to_raw_data() const
-{
- return header_.PointerToRawData;
-}
-
-//Returns section characteristics
-uint32_t section::get_characteristics() const
-{
- return header_.Characteristics;
-}
-
-//Returns raw image section header
-const pe_win::image_section_header& section::get_raw_header() const
-{
- return header_;
-}
-
-//Returns raw image section header
-pe_win::image_section_header& section::get_raw_header()
-{
- return header_;
-}
-
-//Calculates aligned virtual section size
-uint32_t section::get_aligned_virtual_size(uint32_t section_alignment) const
-{
- if(get_size_of_raw_data())
- {
- if(!get_virtual_size())
- {
- //If section virtual size is zero
- //Set aligned virtual size of section as aligned raw size
- return pe_utils::align_up(get_size_of_raw_data(), section_alignment);
- }
- }
-
- return pe_utils::align_up(get_virtual_size(), section_alignment);
-}
-
-//Calculates aligned raw section size
-uint32_t section::get_aligned_raw_size(uint32_t file_alignment) const
-{
- if(get_size_of_raw_data())
- return pe_utils::align_up(get_size_of_raw_data(), file_alignment);
- else
- return 0;
-}
-
-//Sets size of raw section data
-void section::set_size_of_raw_data(uint32_t size_of_raw_data)
-{
- header_.SizeOfRawData = size_of_raw_data;
-}
-
-//Sets pointer to section raw data
-void section::set_pointer_to_raw_data(uint32_t pointer_to_raw_data)
-{
- header_.PointerToRawData = pointer_to_raw_data;
-}
-
-//Sets section characteristics
-void section::set_characteristics(uint32_t characteristics)
-{
- header_.Characteristics = characteristics;
-}
-
-//Sets section virtual size
-void section::set_virtual_size(uint32_t virtual_size)
-{
- header_.Misc.VirtualSize = virtual_size;
-}
-
-//Sets section virtual address
-void section::set_virtual_address(uint32_t virtual_address)
-{
- header_.VirtualAddress = virtual_address;
-}
-
-//Section by file offset finder helper (4gb max)
-section_by_raw_offset::section_by_raw_offset(uint32_t offset)
- :offset_(offset)
-{}
-
-bool section_by_raw_offset::operator()(const section& s) const
-{
- return (s.get_pointer_to_raw_data() <= offset_)
- && (s.get_pointer_to_raw_data() + s.get_size_of_raw_data() > offset_);
-}
-
-section_ptr_finder::section_ptr_finder(const section& s)
- :s_(s)
-{}
-
-bool section_ptr_finder::operator()(const section& s) const
-{
- return &s == &s_;
-}
-}
diff --git a/tools/pe_bliss/pe_section.h b/tools/pe_bliss/pe_section.h
deleted file mode 100644
index 617ecebe26..0000000000
--- a/tools/pe_bliss/pe_section.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-//Enumeration of section data types, used in functions below
-enum section_data_type
-{
- section_data_raw,
- section_data_virtual
-};
-
-//Class representing image section
-class section
-{
-public:
- //Default constructor
- section();
-
- //Sets the name of section (stripped to 8 characters)
- void set_name(const std::string& name);
-
- //Returns the name of section
- const std::string get_name() const;
-
- //Changes attributes of section
- section& readable(bool readable);
- section& writeable(bool writeable);
- section& executable(bool executable);
- section& shared(bool shared);
- section& discardable(bool discardable);
-
- //Returns attributes of section
- bool readable() const;
- bool writeable() const;
- bool executable() const;
- bool shared() const;
- bool discardable() const;
-
- //Returns true if section has no RAW data
- bool empty() const;
-
- //Returns raw section data from file image
- std::string& get_raw_data();
- //Returns raw section data from file image
- const std::string& get_raw_data() const;
- //Returns mapped virtual section data
- const std::string& get_virtual_data(uint32_t section_alignment) const;
- //Returns mapped virtual section data
- std::string& get_virtual_data(uint32_t section_alignment);
-
-public: //Header getters
- //Returns section virtual size
- uint32_t get_virtual_size() const;
- //Returns section virtual address (RVA)
- uint32_t get_virtual_address() const;
- //Returns size of section raw data
- uint32_t get_size_of_raw_data() const;
- //Returns pointer to raw section data in PE file
- uint32_t get_pointer_to_raw_data() const;
- //Returns section characteristics
- uint32_t get_characteristics() const;
-
- //Returns raw image section header
- const pe_win::image_section_header& get_raw_header() const;
-
-public: //Aligned sizes calculation
- //Calculates aligned virtual section size
- uint32_t get_aligned_virtual_size(uint32_t section_alignment) const;
- //Calculates aligned raw section size
- uint32_t get_aligned_raw_size(uint32_t file_alignment) const;
-
-public: //Setters
- //Sets size of raw section data
- void set_size_of_raw_data(uint32_t size_of_raw_data);
- //Sets pointer to section raw data
- void set_pointer_to_raw_data(uint32_t pointer_to_raw_data);
- //Sets section characteristics
- void set_characteristics(uint32_t characteristics);
- //Sets raw section data from file image
- void set_raw_data(const std::string& data);
-
-public: //Setters, be careful
- //Sets section virtual size (doesn't set internal aligned virtual size, changes only header value)
- //Better use pe_base::set_section_virtual_size
- void set_virtual_size(uint32_t virtual_size);
- //Sets section virtual address
- void set_virtual_address(uint32_t virtual_address);
- //Returns raw image section header
- pe_win::image_section_header& get_raw_header();
-
-private:
- //Section header
- pe_win::image_section_header header_;
-
- //Maps virtual section data
- void map_virtual(uint32_t section_alignment) const;
-
- //Unmaps virtual section data
- void unmap_virtual() const;
-
- //Set flag (attribute) of section
- section& set_flag(uint32_t flag, bool setflag);
-
- //Old size of section (stored after mapping of virtual section memory)
- mutable std::size_t old_size_;
-
- //Section raw/virtual data
- mutable std::string raw_data_;
-};
-
-//Section by file offset finder helper (4gb max)
-struct section_by_raw_offset
-{
-public:
- explicit section_by_raw_offset(uint32_t offset);
- bool operator()(const section& s) const;
-
-private:
- uint32_t offset_;
-};
-
-//Helper: finder of section* in sections list
-struct section_ptr_finder
-{
-public:
- explicit section_ptr_finder(const section& s);
- bool operator()(const section& s) const;
-
-private:
- const section& s_;
-};
-
-typedef std::vector<section> section_list;
-}
diff --git a/tools/pe_bliss/pe_structures.h b/tools/pe_bliss/pe_structures.h
deleted file mode 100644
index efc99103b2..0000000000
--- a/tools/pe_bliss/pe_structures.h
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <sstream>
-#include "stdint_defs.h"
-#if defined(_MSC_VER) or defined(__MINGW32__)
-#define PE_BLISS_WINDOWS
-#endif
-
-namespace pe_bliss
-{
-//Enumeration of PE types
-enum pe_type
-{
- pe_type_32,
- pe_type_64
-};
-
-namespace pe_win
-{
-const uint32_t image_numberof_directory_entries = 16;
-const uint32_t image_nt_optional_hdr32_magic = 0x10b;
-const uint32_t image_nt_optional_hdr64_magic = 0x20b;
-const uint32_t image_resource_name_is_string = 0x80000000;
-const uint32_t image_resource_data_is_directory = 0x80000000;
-
-const uint32_t image_dllcharacteristics_dynamic_base = 0x0040; // DLL can move.
-const uint32_t image_dllcharacteristics_force_integrity = 0x0080; // Code Integrity Image
-const uint32_t image_dllcharacteristics_nx_compat = 0x0100; // Image is NX compatible
-const uint32_t image_dllcharacteristics_no_isolation = 0x0200; // Image understands isolation and doesn't want it
-const uint32_t image_dllcharacteristics_no_seh = 0x0400; // Image does not use SEH. No SE handler may reside in this image
-const uint32_t image_dllcharacteristics_no_bind = 0x0800; // Do not bind this image.
-const uint32_t image_dllcharacteristics_wdm_driver = 0x2000; // Driver uses WDM model
-const uint32_t image_dllcharacteristics_terminal_server_aware = 0x8000;
-
-const uint32_t image_sizeof_file_header = 20;
-
-const uint32_t image_file_relocs_stripped = 0x0001; // Relocation info stripped from file.
-const uint32_t image_file_executable_image = 0x0002; // File is executable (i.e. no unresolved externel references).
-const uint32_t image_file_line_nums_stripped = 0x0004; // Line nunbers stripped from file.
-const uint32_t image_file_local_syms_stripped = 0x0008; // Local symbols stripped from file.
-const uint32_t image_file_aggresive_ws_trim = 0x0010; // Agressively trim working set
-const uint32_t image_file_large_address_aware = 0x0020; // App can handle >2gb addresses
-const uint32_t image_file_bytes_reversed_lo = 0x0080; // Bytes of machine word are reversed.
-const uint32_t image_file_32bit_machine = 0x0100; // 32 bit word machine.
-const uint32_t image_file_debug_stripped = 0x0200; // Debugging info stripped from file in .DBG file
-const uint32_t image_file_removable_run_from_swap = 0x0400; // If Image is on removable media, copy and run from the swap file.
-const uint32_t image_file_net_run_from_swap = 0x0800; // If Image is on Net, copy and run from the swap file.
-const uint32_t image_file_system = 0x1000; // System File.
-const uint32_t image_file_dll = 0x2000; // File is a DLL.
-const uint32_t image_file_up_system_only = 0x4000; // File should only be run on a UP machine
-const uint32_t image_file_bytes_reversed_hi = 0x8000; // Bytes of machine word are reversed.
-
-const uint32_t image_scn_lnk_nreloc_ovfl = 0x01000000; // Section contains extended relocations.
-const uint32_t image_scn_mem_discardable = 0x02000000; // Section can be discarded.
-const uint32_t image_scn_mem_not_cached = 0x04000000; // Section is not cachable.
-const uint32_t image_scn_mem_not_paged = 0x08000000; // Section is not pageable.
-const uint32_t image_scn_mem_shared = 0x10000000; // Section is shareable.
-const uint32_t image_scn_mem_execute = 0x20000000; // Section is executable.
-const uint32_t image_scn_mem_read = 0x40000000; // Section is readable.
-const uint32_t image_scn_mem_write = 0x80000000; // Section is writeable.
-
-const uint32_t image_scn_cnt_code = 0x00000020; // Section contains code.
-const uint32_t image_scn_cnt_initialized_data = 0x00000040; // Section contains initialized data.
-const uint32_t image_scn_cnt_uninitialized_data = 0x00000080; // Section contains uninitialized data.
-
-//Directory Entries
-const uint32_t image_directory_entry_export = 0; // Export Directory
-const uint32_t image_directory_entry_import = 1; // Import Directory
-const uint32_t image_directory_entry_resource = 2; // Resource Directory
-const uint32_t image_directory_entry_exception = 3; // Exception Directory
-const uint32_t image_directory_entry_security = 4; // Security Directory
-const uint32_t image_directory_entry_basereloc = 5; // Base Relocation Table
-const uint32_t image_directory_entry_debug = 6; // Debug Directory
-const uint32_t image_directory_entry_architecture = 7; // Architecture Specific Data
-const uint32_t image_directory_entry_globalptr = 8; // RVA of GP
-const uint32_t image_directory_entry_tls = 9; // TLS Directory
-const uint32_t image_directory_entry_load_config = 10; // Load Configuration Directory
-const uint32_t image_directory_entry_bound_import = 11; // Bound Import Directory in headers
-const uint32_t image_directory_entry_iat = 12; // Import Address Table
-const uint32_t image_directory_entry_delay_import = 13; // Delay Load Import Descriptors
-const uint32_t image_directory_entry_com_descriptor = 14; // COM Runtime descriptor
-
-//Subsystem Values
-const uint32_t image_subsystem_unknown = 0; // Unknown subsystem.
-const uint32_t image_subsystem_native = 1; // Image doesn't require a subsystem.
-const uint32_t image_subsystem_windows_gui = 2; // Image runs in the Windows GUI subsystem.
-const uint32_t image_subsystem_windows_cui = 3; // Image runs in the Windows character subsystem.
-const uint32_t image_subsystem_os2_cui = 5; // image runs in the OS/2 character subsystem.
-const uint32_t image_subsystem_posix_cui = 7; // image runs in the Posix character subsystem.
-const uint32_t image_subsystem_native_windows = 8; // image is a native Win9x driver.
-const uint32_t image_subsystem_windows_ce_gui = 9; // Image runs in the Windows CE subsystem.
-const uint32_t image_subsystem_efi_application = 10; //
-const uint32_t image_subsystem_efi_boot_service_driver = 11; //
-const uint32_t image_subsystem_efi_runtime_driver = 12; //
-const uint32_t image_subsystem_efi_rom = 13;
-const uint32_t image_subsystem_xbox = 14;
-const uint32_t image_subsystem_windows_boot_application = 16;
-
-//Imports
-const uint64_t image_ordinal_flag64 = 0x8000000000000000ull;
-const uint32_t image_ordinal_flag32 = 0x80000000;
-
-//Based relocation types
-const uint32_t image_rel_based_absolute = 0;
-const uint32_t image_rel_based_high = 1;
-const uint32_t image_rel_based_low = 2;
-const uint32_t image_rel_based_highlow = 3;
-const uint32_t image_rel_based_highadj = 4;
-const uint32_t image_rel_based_mips_jmpaddr = 5;
-const uint32_t image_rel_based_mips_jmpaddr16 = 9;
-const uint32_t image_rel_based_ia64_imm64 = 9;
-const uint32_t image_rel_based_dir64 = 10;
-
-//Exception directory
-//The function has an exception handler that should be called when looking for functions that need to examine exceptions
-const uint32_t unw_flag_ehandler = 0x01;
-//The function has a termination handler that should be called when unwinding an exception
-const uint32_t unw_flag_uhandler = 0x02;
-//This unwind info structure is not the primary one for the procedure.
-//Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry.
-//If this flag is set, then the UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER flags must be cleared.
-//Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info
-const uint32_t unw_flag_chaininfo = 0x04;
-
-//Debug
-const uint32_t image_debug_misc_exename = 1;
-const uint32_t image_debug_type_unknown = 0;
-const uint32_t image_debug_type_coff = 1;
-const uint32_t image_debug_type_codeview = 2;
-const uint32_t image_debug_type_fpo = 3;
-const uint32_t image_debug_type_misc = 4;
-const uint32_t image_debug_type_exception = 5;
-const uint32_t image_debug_type_fixup = 6;
-const uint32_t image_debug_type_omap_to_src = 7;
-const uint32_t image_debug_type_omap_from_src = 8;
-const uint32_t image_debug_type_borland = 9;
-const uint32_t image_debug_type_reserved10 = 10;
-const uint32_t image_debug_type_clsid = 11;
-
-
-//Storage classes
-const uint32_t image_sym_class_end_of_function = static_cast<uint8_t>(-1);
-const uint32_t image_sym_class_null = 0x0000;
-const uint32_t image_sym_class_automatic = 0x0001;
-const uint32_t image_sym_class_external = 0x0002;
-const uint32_t image_sym_class_static = 0x0003;
-const uint32_t image_sym_class_register = 0x0004;
-const uint32_t image_sym_class_external_def = 0x0005;
-const uint32_t image_sym_class_label = 0x0006;
-const uint32_t image_sym_class_undefined_label = 0x0007;
-const uint32_t image_sym_class_member_of_struct = 0x0008;
-const uint32_t image_sym_class_argument = 0x0009;
-const uint32_t image_sym_class_struct_tag = 0x000a;
-const uint32_t image_sym_class_member_of_union = 0x000b;
-const uint32_t image_sym_class_union_tag = 0x000c;
-const uint32_t image_sym_class_type_definition = 0x000d;
-const uint32_t image_sym_class_undefined_static = 0x000e;
-const uint32_t image_sym_class_enum_tag = 0x000f;
-const uint32_t image_sym_class_member_of_enum = 0x0010;
-const uint32_t image_sym_class_register_param = 0x0011;
-const uint32_t image_sym_class_bit_field = 0x0012;
-
-const uint32_t image_sym_class_far_external = 0x0044;
-
-const uint32_t image_sym_class_block = 0x0064;
-const uint32_t image_sym_class_function = 0x0065;
-const uint32_t image_sym_class_end_of_struct = 0x0066;
-const uint32_t image_sym_class_file = 0x0067;
-
-const uint32_t image_sym_class_section = 0x0068;
-const uint32_t image_sym_class_weak_external = 0x0069;
-
-const uint32_t image_sym_class_clr_token = 0x006b;
-
-//type packing constants
-const uint32_t n_btmask = 0x000f;
-const uint32_t n_tmask = 0x0030;
-const uint32_t n_tmask1 = 0x00c0;
-const uint32_t n_tmask2 = 0x00f0;
-const uint32_t n_btshft = 4;
-const uint32_t n_tshift = 2;
-
-//Type (derived) values.
-const uint32_t image_sym_dtype_null = 0; // no derived type.
-const uint32_t image_sym_dtype_pointer = 1; // pointer.
-const uint32_t image_sym_dtype_function = 2; // function.
-const uint32_t image_sym_dtype_array = 3; // array.
-
-// Is x a function?
-//TODO
-#ifndef ISFCN
-#define ISFCN(x) (((x) & n_tmask) == (image_sym_dtype_function << n_btshft))
-#endif
-
-//Version info
-const uint32_t vs_ffi_fileflagsmask = 0x0000003FL;
-
-const uint32_t vs_ffi_signature = 0xFEEF04BDL;
-const uint32_t vs_ffi_strucversion = 0x00010000L;
-
-/* ----- VS_VERSION.dwFileFlags ----- */
-const uint32_t vs_ff_debug = 0x00000001L;
-const uint32_t vs_ff_prerelease = 0x00000002L;
-const uint32_t vs_ff_patched = 0x00000004L;
-const uint32_t vs_ff_privatebuild = 0x00000008L;
-const uint32_t vs_ff_infoinferred = 0x00000010L;
-const uint32_t vs_ff_specialbuild = 0x00000020L;
-
-/* ----- VS_VERSION.dwFileOS ----- */
-const uint32_t vos_unknown = 0x00000000L;
-const uint32_t vos_dos = 0x00010000L;
-const uint32_t vos_os216 = 0x00020000L;
-const uint32_t vos_os232 = 0x00030000L;
-const uint32_t vos_nt = 0x00040000L;
-const uint32_t vos_wince = 0x00050000L;
-
-const uint32_t vos__base = 0x00000000L;
-const uint32_t vos__windows16 = 0x00000001L;
-const uint32_t vos__pm16 = 0x00000002L;
-const uint32_t vos__pm32 = 0x00000003L;
-const uint32_t vos__windows32 = 0x00000004L;
-
-const uint32_t vos_dos_windows16 = 0x00010001L;
-const uint32_t vos_dos_windows32 = 0x00010004L;
-const uint32_t vos_os216_pm16 = 0x00020002L;
-const uint32_t vos_os232_pm32 = 0x00030003L;
-const uint32_t vos_nt_windows32 = 0x00040004L;
-
-/* ----- VS_VERSION.dwFileType ----- */
-const uint32_t vft_unknown = 0x00000000L;
-const uint32_t vft_app = 0x00000001L;
-const uint32_t vft_dll = 0x00000002L;
-const uint32_t vft_drv = 0x00000003L;
-const uint32_t vft_font = 0x00000004L;
-const uint32_t vft_vxd = 0x00000005L;
-const uint32_t vft_static_lib = 0x00000007L;
-
-const uint32_t message_resource_unicode = 0x0001;
-
-#pragma pack(push, 1)
-
-//Windows GUID structure
-struct guid
-{
- uint32_t Data1;
- uint16_t Data2;
- uint16_t Data3;
- uint8_t Data4[8];
-};
-
-//DOS .EXE header
-struct image_dos_header
-{
- uint16_t e_magic; // Magic number
- uint16_t e_cblp; // Bytes on last page of file
- uint16_t e_cp; // Pages in file
- uint16_t e_crlc; // Relocations
- uint16_t e_cparhdr; // Size of header in paragraphs
- uint16_t e_minalloc; // Minimum extra paragraphs needed
- uint16_t e_maxalloc; // Maximum extra paragraphs needed
- uint16_t e_ss; // Initial (relative) SS value
- uint16_t e_sp; // Initial SP value
- uint16_t e_csum; // Checksum
- uint16_t e_ip; // Initial IP value
- uint16_t e_cs; // Initial (relative) CS value
- uint16_t e_lfarlc; // File address of relocation table
- uint16_t e_ovno; // Overlay number
- uint16_t e_res[4]; // Reserved words
- uint16_t e_oemid; // OEM identifier (for e_oeminfo)
- uint16_t e_oeminfo; // OEM information; e_oemid specific
- uint16_t e_res2[10]; // Reserved words
- int32_t e_lfanew; // File address of new exe header
-};
-
-//Directory format
-struct image_data_directory
-{
- uint32_t VirtualAddress;
- uint32_t Size;
-};
-
-//Optional header format
-struct image_optional_header32
-{
- //Standard fields
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint;
- uint32_t BaseOfCode;
- uint32_t BaseOfData;
-
- //NT additional fields
- uint32_t ImageBase;
- uint32_t SectionAlignment;
- uint32_t FileAlignment;
- uint16_t MajorOperatingSystemVersion;
- uint16_t MinorOperatingSystemVersion;
- uint16_t MajorImageVersion;
- uint16_t MinorImageVersion;
- uint16_t MajorSubsystemVersion;
- uint16_t MinorSubsystemVersion;
- uint32_t Win32VersionValue;
- uint32_t SizeOfImage;
- uint32_t SizeOfHeaders;
- uint32_t CheckSum;
- uint16_t Subsystem;
- uint16_t DllCharacteristics;
- uint32_t SizeOfStackReserve;
- uint32_t SizeOfStackCommit;
- uint32_t SizeOfHeapReserve;
- uint32_t SizeOfHeapCommit;
- uint32_t LoaderFlags;
- uint32_t NumberOfRvaAndSizes;
- image_data_directory DataDirectory[image_numberof_directory_entries];
-};
-
-struct image_optional_header64
-{
- uint16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- uint32_t SizeOfCode;
- uint32_t SizeOfInitializedData;
- uint32_t SizeOfUninitializedData;
- uint32_t AddressOfEntryPoint;
- uint32_t BaseOfCode;
- uint64_t ImageBase;
- uint32_t SectionAlignment;
- uint32_t FileAlignment;
- uint16_t MajorOperatingSystemVersion;
- uint16_t MinorOperatingSystemVersion;
- uint16_t MajorImageVersion;
- uint16_t MinorImageVersion;
- uint16_t MajorSubsystemVersion;
- uint16_t MinorSubsystemVersion;
- uint32_t Win32VersionValue;
- uint32_t SizeOfImage;
- uint32_t SizeOfHeaders;
- uint32_t CheckSum;
- uint16_t Subsystem;
- uint16_t DllCharacteristics;
- uint64_t SizeOfStackReserve;
- uint64_t SizeOfStackCommit;
- uint64_t SizeOfHeapReserve;
- uint64_t SizeOfHeapCommit;
- uint32_t LoaderFlags;
- uint32_t NumberOfRvaAndSizes;
- image_data_directory DataDirectory[image_numberof_directory_entries];
-};
-
-struct image_file_header
-{
- uint16_t Machine;
- uint16_t NumberOfSections;
- uint32_t TimeDateStamp;
- uint32_t PointerToSymbolTable;
- uint32_t NumberOfSymbols;
- uint16_t SizeOfOptionalHeader;
- uint16_t Characteristics;
-};
-
-struct image_nt_headers64
-{
- uint32_t Signature;
- image_file_header FileHeader;
- image_optional_header64 OptionalHeader;
-};
-
-struct image_nt_headers32
-{
- uint32_t Signature;
- image_file_header FileHeader;
- image_optional_header32 OptionalHeader;
-};
-
-//Section header format
-struct image_section_header
-{
- uint8_t Name[8];
- union
- {
- uint32_t PhysicalAddress;
- uint32_t VirtualSize;
- } Misc;
-
- uint32_t VirtualAddress;
- uint32_t SizeOfRawData;
- uint32_t PointerToRawData;
- uint32_t PointerToRelocations;
- uint32_t PointerToLinenumbers;
- uint16_t NumberOfRelocations;
- uint16_t NumberOfLinenumbers;
- uint32_t Characteristics;
-};
-
-
-/// RESOURCES ///
-struct image_resource_directory
-{
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint16_t NumberOfNamedEntries;
- uint16_t NumberOfIdEntries;
- // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
-};
-
-struct vs_fixedfileinfo
-{
- uint32_t dwSignature; /* e.g. 0xfeef04bd */
- uint32_t dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
- uint32_t dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
- uint32_t dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
- uint32_t dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
- uint32_t dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
- uint32_t dwFileFlagsMask; /* = 0x3F for version "0.42" */
- uint32_t dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
- uint32_t dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
- uint32_t dwFileType; /* e.g. VFT_DRIVER */
- uint32_t dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
- uint32_t dwFileDateMS; /* e.g. 0 */
- uint32_t dwFileDateLS; /* e.g. 0 */
-};
-
-struct bitmapinfoheader
-{
- uint32_t biSize;
- int32_t biWidth;
- int32_t biHeight;
- uint16_t biPlanes;
- uint16_t biBitCount;
- uint32_t biCompression;
- uint32_t biSizeImage;
- int32_t biXPelsPerMeter;
- int32_t biYPelsPerMeter;
- uint32_t biClrUsed;
- uint32_t biClrImportant;
-};
-
-struct message_resource_entry
-{
- uint16_t Length;
- uint16_t Flags;
- uint8_t Text[1];
-};
-
-struct message_resource_block
-{
- uint32_t LowId;
- uint32_t HighId;
- uint32_t OffsetToEntries;
-};
-
-struct message_resource_data
-{
- uint32_t NumberOfBlocks;
- message_resource_block Blocks[1];
-};
-
-struct image_resource_directory_entry
-{
- union
- {
- struct
- {
- uint32_t NameOffset:31;
- uint32_t NameIsString:1;
- };
- uint32_t Name;
- uint16_t Id;
- };
-
- union
- {
- uint32_t OffsetToData;
- struct
- {
- uint32_t OffsetToDirectory:31;
- uint32_t DataIsDirectory:1;
- };
- };
-};
-
-struct image_resource_data_entry
-{
- uint32_t OffsetToData;
- uint32_t Size;
- uint32_t CodePage;
- uint32_t Reserved;
-};
-
-#pragma pack(push, 2)
-struct bitmapfileheader
-{
- uint16_t bfType;
- uint32_t bfSize;
- uint16_t bfReserved1;
- uint16_t bfReserved2;
- uint32_t bfOffBits;
-};
-#pragma pack(pop)
-
-
-
-//Structure representing ICON file header
-struct ico_header
-{
- uint16_t Reserved;
- uint16_t Type; //1
- uint16_t Count; //Count of icons included in icon group
-};
-
-//Structure that is stored in icon group directory in PE resources
-struct icon_group
-{
- uint8_t Width;
- uint8_t Height;
- uint8_t ColorCount;
- uint8_t Reserved;
- uint16_t Planes;
- uint16_t BitCount;
- uint32_t SizeInBytes;
- uint16_t Number; //Represents resource ID in PE icon list
-};
-
-//Structure representing ICON directory entry inside ICON file
-struct icondirentry
-{
- uint8_t Width;
- uint8_t Height;
- uint8_t ColorCount;
- uint8_t Reserved;
- uint16_t Planes;
- uint16_t BitCount;
- uint32_t SizeInBytes;
- uint32_t ImageOffset; //Offset from start of header to the image
-};
-
-//Structure representing CURSOR file header
-struct cursor_header
-{
- uint16_t Reserved;
- uint16_t Type; //2
- uint16_t Count; //Count of cursors included in cursor group
-};
-
-struct cursor_group
-{
- uint16_t Width;
- uint16_t Height; //Divide by 2 to get the actual height.
- uint16_t Planes;
- uint16_t BitCount;
- uint32_t SizeInBytes;
- uint16_t Number; //Represents resource ID in PE icon list
-};
-
-//Structure representing CURSOR directory entry inside CURSOR file
-struct cursordirentry
-{
- uint8_t Width; //Set to CURSOR_GROUP::Height/2.
- uint8_t Height;
- uint8_t ColorCount;
- uint8_t Reserved;
- uint16_t HotspotX;
- uint16_t HotspotY;
- uint32_t SizeInBytes;
- uint32_t ImageOffset; //Offset from start of header to the image
-};
-
-//Structure representing BLOCK in version info resource
-struct version_info_block //(always aligned on 32-bit (DWORD) boundary)
-{
- uint16_t Length; //Length of this block (doesn't include padding)
- uint16_t ValueLength; //Value length (if any)
- uint16_t Type; //Value type (0 = binary, 1 = text)
- uint16_t Key[1]; //Value name (block key) (always NULL terminated)
-
- //////////
- //WORD padding1[]; //Padding, if any (ALIGNMENT)
- //xxxxx Value[]; //Value data, if any (*ALIGNED*)
- //WORD padding2[]; //Padding, if any (ALIGNMENT)
- //xxxxx Child[]; //Child block(s), if any (*ALIGNED*)
- //////////
-};
-
-
-/// IMPORTS ///
-#pragma pack(push, 8)
-struct image_thunk_data64
-{
- union
- {
- uint64_t ForwarderString; // PBYTE
- uint64_t Function; // PDWORD
- uint64_t Ordinal;
- uint64_t AddressOfData; // PIMAGE_IMPORT_BY_NAME
- } u1;
-};
-#pragma pack(pop)
-
-struct image_thunk_data32
-{
- union
- {
- uint32_t ForwarderString; // PBYTE
- uint32_t Function; // PDWORD
- uint32_t Ordinal;
- uint32_t AddressOfData; // PIMAGE_IMPORT_BY_NAME
- } u1;
-};
-
-struct image_import_descriptor
-{
- union
- {
- uint32_t Characteristics; // 0 for terminating null import descriptor
- uint32_t OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
- };
-
- uint32_t TimeDateStamp; // 0 if not bound,
- // -1 if bound, and real date\time stamp
- // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
- // O.W. date/time stamp of DLL bound to (Old BIND)
-
- uint32_t ForwarderChain; // -1 if no forwarders
- uint32_t Name;
- uint32_t FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
-};
-
-
-/// TLS ///
-struct image_tls_directory64
-{
- uint64_t StartAddressOfRawData;
- uint64_t EndAddressOfRawData;
- uint64_t AddressOfIndex; // PDWORD
- uint64_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *;
- uint32_t SizeOfZeroFill;
- uint32_t Characteristics;
-};
-
-struct image_tls_directory32
-{
- uint32_t StartAddressOfRawData;
- uint32_t EndAddressOfRawData;
- uint32_t AddressOfIndex; // PDWORD
- uint32_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *
- uint32_t SizeOfZeroFill;
- uint32_t Characteristics;
-};
-
-
-/// Export Format ///
-struct image_export_directory
-{
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t Name;
- uint32_t Base;
- uint32_t NumberOfFunctions;
- uint32_t NumberOfNames;
- uint32_t AddressOfFunctions; // RVA from base of image
- uint32_t AddressOfNames; // RVA from base of image
- uint32_t AddressOfNameOrdinals; // RVA from base of image
-};
-
-
-/// Based relocation format ///
-struct image_base_relocation
-{
- uint32_t VirtualAddress;
- uint32_t SizeOfBlock;
- // uint16_t TypeOffset[1];
-};
-
-
-/// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] ///
-struct image_bound_import_descriptor
-{
- uint32_t TimeDateStamp;
- uint16_t OffsetModuleName;
- uint16_t NumberOfModuleForwarderRefs;
- // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
-};
-
-struct image_bound_forwarder_ref
-{
- uint32_t TimeDateStamp;
- uint16_t OffsetModuleName;
- uint16_t Reserved;
-};
-
-
-/// Exception directory ///
-struct image_runtime_function_entry
-{
- uint32_t BeginAddress;
- uint32_t EndAddress;
- uint32_t UnwindInfoAddress;
-};
-
-enum unwind_op_codes
-{
- uwop_push_nonvol = 0, /* info == register number */
- uwop_alloc_large, /* no info, alloc size in next 2 slots */
- uwop_alloc_small, /* info == size of allocation / 8 - 1 */
- uwop_set_fpreg, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
- uwop_save_nonvol, /* info == register number, offset in next slot */
- uwop_save_nonvol_far, /* info == register number, offset in next 2 slots */
- uwop_save_xmm128, /* info == XMM reg number, offset in next slot */
- uwop_save_xmm128_far, /* info == XMM reg number, offset in next 2 slots */
- uwop_push_machframe /* info == 0: no error-code, 1: error-code */
-};
-
-union unwind_code
-{
- struct s
- {
- uint8_t CodeOffset;
- uint8_t UnwindOp : 4;
- uint8_t OpInfo : 4;
- };
-
- uint16_t FrameOffset;
-};
-
-struct unwind_info
-{
- uint8_t Version : 3;
- uint8_t Flags : 5;
- uint8_t SizeOfProlog;
- uint8_t CountOfCodes;
- uint8_t FrameRegister : 4;
- uint8_t FrameOffset : 4;
- unwind_code UnwindCode[1];
- /* unwind_code MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
- * union {
- * OPTIONAL ULONG ExceptionHandler;
- * OPTIONAL ULONG FunctionEntry;
- * };
- * OPTIONAL ULONG ExceptionData[]; */
-};
-
-
-
-/// Debug ///
-struct image_debug_misc
-{
- uint32_t DataType; // type of misc data, see defines
- uint32_t Length; // total length of record, rounded to four
- // byte multiple.
- uint8_t Unicode; // TRUE if data is unicode string
- uint8_t Reserved[3];
- uint8_t Data[1]; // Actual data
-};
-
-struct image_coff_symbols_header
-{
- uint32_t NumberOfSymbols;
- uint32_t LvaToFirstSymbol;
- uint32_t NumberOfLinenumbers;
- uint32_t LvaToFirstLinenumber;
- uint32_t RvaToFirstByteOfCode;
- uint32_t RvaToLastByteOfCode;
- uint32_t RvaToFirstByteOfData;
- uint32_t RvaToLastByteOfData;
-};
-
-struct image_debug_directory
-{
- uint32_t Characteristics;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t Type;
- uint32_t SizeOfData;
- uint32_t AddressOfRawData;
- uint32_t PointerToRawData;
-};
-
-
-#pragma pack(push, 2)
-struct image_symbol
-{
- union
- {
- uint8_t ShortName[8];
- struct
- {
- uint32_t Short; // if 0, use LongName
- uint32_t Long; // offset into string table
- } Name;
- uint32_t LongName[2]; // PBYTE [2]
- } N;
- uint32_t Value;
- int16_t SectionNumber;
- uint16_t Type;
- uint8_t StorageClass;
- uint8_t NumberOfAuxSymbols;
-};
-#pragma pack(pop)
-
-//CodeView Debug OMF signature. The signature at the end of the file is
-//a negative offset from the end of the file to another signature. At
-//the negative offset (base address) is another signature whose filepos
-//field points to the first OMFDirHeader in a chain of directories.
-//The NB05 signature is used by the link utility to indicated a completely
-//unpacked file. The NB06 signature is used by ilink to indicate that the
-//executable has had CodeView information from an incremental link appended
-//to the executable. The NB08 signature is used by cvpack to indicate that
-//the CodeView Debug OMF has been packed. CodeView will only process
-//executables with the NB08 signature.
-struct OMFSignature
-{
- char Signature[4]; // "NBxx"
- uint32_t filepos; // offset in file
-};
-
-struct CV_INFO_PDB20
-{
- OMFSignature CvHeader;
- uint32_t Signature;
- uint32_t Age;
- uint8_t PdbFileName[1];
-};
-
-struct CV_INFO_PDB70
-{
- uint32_t CvSignature;
- guid Signature;
- uint32_t Age;
- uint8_t PdbFileName[1];
-};
-
-// directory information structure
-// This structure contains the information describing the directory.
-// It is pointed to by the signature at the base address or the directory
-// link field of a preceeding directory. The directory entries immediately
-// follow this structure.
-struct OMFDirHeader
-{
- uint16_t cbDirHeader; // length of this structure
- uint16_t cbDirEntry; // number of bytes in each directory entry
- uint32_t cDir; // number of directorie entries
- int32_t lfoNextDir; // offset from base of next directory
- uint32_t flags; // status flags
-};
-
-// directory structure
-// The data in this structure is used to reference the data for each
-// subsection of the CodeView Debug OMF information. Tables that are
-// not associated with a specific module will have a module index of
-// oxffff. These tables are the global types table, the global symbol
-// table, the global public table and the library table.
-struct OMFDirEntry
-{
- uint16_t SubSection; // subsection type (sst...)
- uint16_t iMod; // module index
- int32_t lfo; // large file offset of subsection
- uint32_t cb; // number of bytes in subsection
-};
-
-
-/// CLR 2.0 header structure ///
-struct image_cor20_header
-{
- //Header versioning
- uint32_t cb;
- uint16_t MajorRuntimeVersion;
- uint16_t MinorRuntimeVersion;
-
- // Symbol table and startup information
- image_data_directory MetaData;
- uint32_t Flags;
-
- // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
- // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint.
- union
- {
- uint32_t EntryPointToken;
- uint32_t EntryPointRVA;
- };
-
- // Binding information
- image_data_directory Resources;
- image_data_directory StrongNameSignature;
-
- // Regular fixup and binding information
- image_data_directory CodeManagerTable;
- image_data_directory VTableFixups;
- image_data_directory ExportAddressTableJumps;
-
- // Precompiled image info (internal use only - set to zero)
- image_data_directory ManagedNativeHeader;
-};
-
-enum replaces_cor_hdr_numeric_defines
-{
- // COM+ Header entry point flags.
- comimage_flags_ilonly =0x00000001,
- comimage_flags_32bitrequired =0x00000002,
- comimage_flags_il_library =0x00000004,
- comimage_flags_strongnamesigned =0x00000008,
- comimage_flags_native_entrypoint =0x00000010,
- comimage_flags_trackdebugdata =0x00010000,
-
- // Version flags for image.
- cor_version_major_v2 =2,
- cor_version_major =cor_version_major_v2,
- cor_version_minor =0,
- cor_deleted_name_length =8,
- cor_vtablegap_name_length =8,
-
- // Maximum size of a NativeType descriptor.
- native_type_max_cb =1,
- cor_ilmethod_sect_small_max_datasize=0xff,
-
- // #defines for the MIH FLAGS
- image_cor_mih_methodrva =0x01,
- image_cor_mih_ehrva =0x02,
- image_cor_mih_basicblock =0x08,
-
- // V-table constants
- cor_vtable_32bit =0x01, // V-table slots are 32-bits in size.
- cor_vtable_64bit =0x02, // V-table slots are 64-bits in size.
- cor_vtable_from_unmanaged =0x04, // If set, transition from unmanaged.
- cor_vtable_from_unmanaged_retain_appdomain =0x08, // If set, transition from unmanaged with keeping the current appdomain.
- cor_vtable_call_most_derived =0x10, // Call most derived method described by
-
- // EATJ constants
- image_cor_eatj_thunk_size =32, // Size of a jump thunk reserved range.
-
- // Max name lengths
- //@todo: Change to unlimited name lengths.
- max_class_name =1024,
- max_package_name =1024
-};
-
-/// Load Configuration Directory Entry ///
-struct image_load_config_directory32
-{
- uint32_t Size;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t GlobalFlagsClear;
- uint32_t GlobalFlagsSet;
- uint32_t CriticalSectionDefaultTimeout;
- uint32_t DeCommitFreeBlockThreshold;
- uint32_t DeCommitTotalFreeThreshold;
- uint32_t LockPrefixTable; // VA
- uint32_t MaximumAllocationSize;
- uint32_t VirtualMemoryThreshold;
- uint32_t ProcessHeapFlags;
- uint32_t ProcessAffinityMask;
- uint16_t CSDVersion;
- uint16_t Reserved1;
- uint32_t EditList; // VA
- uint32_t SecurityCookie; // VA
- uint32_t SEHandlerTable; // VA
- uint32_t SEHandlerCount;
-};
-
-struct image_load_config_directory64
-{
- uint32_t Size;
- uint32_t TimeDateStamp;
- uint16_t MajorVersion;
- uint16_t MinorVersion;
- uint32_t GlobalFlagsClear;
- uint32_t GlobalFlagsSet;
- uint32_t CriticalSectionDefaultTimeout;
- uint64_t DeCommitFreeBlockThreshold;
- uint64_t DeCommitTotalFreeThreshold;
- uint64_t LockPrefixTable; // VA
- uint64_t MaximumAllocationSize;
- uint64_t VirtualMemoryThreshold;
- uint64_t ProcessAffinityMask;
- uint32_t ProcessHeapFlags;
- uint16_t CSDVersion;
- uint16_t Reserved1;
- uint64_t EditList; // VA
- uint64_t SecurityCookie; // VA
- uint64_t SEHandlerTable; // VA
- uint64_t SEHandlerCount;
-};
-
-#pragma pack(pop)
-} //namespace pe_win
-
-#ifdef PE_BLISS_WINDOWS
-typedef wchar_t unicode16_t;
-typedef std::basic_string<unicode16_t> u16string;
-#else
-//Instead of wchar_t for windows
-typedef unsigned short unicode16_t;
-typedef std::basic_string<unicode16_t> u16string;
-#endif
-
-} //namespace pe_bliss
diff --git a/tools/pe_bliss/pe_tls.cpp b/tools/pe_bliss/pe_tls.cpp
deleted file mode 100644
index 5ec68e3f10..0000000000
--- a/tools/pe_bliss/pe_tls.cpp
+++ /dev/null
@@ -1,396 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "pe_tls.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//TLS
-//Default constructor
-tls_info::tls_info()
- :start_rva_(0), end_rva_(0), index_rva_(0), callbacks_rva_(0),
- size_of_zero_fill_(0), characteristics_(0)
-{}
-
-//Returns start RVA of TLS raw data
-uint32_t tls_info::get_raw_data_start_rva() const
-{
- return start_rva_;
-}
-
-//Returns end RVA of TLS raw data
-uint32_t tls_info::get_raw_data_end_rva() const
-{
- return end_rva_;
-}
-
-//Returns TLS index RVA
-uint32_t tls_info::get_index_rva() const
-{
- return index_rva_;
-}
-
-//Returns TLS callbacks RVA
-uint32_t tls_info::get_callbacks_rva() const
-{
- return callbacks_rva_;
-}
-
-//Returns size of zero fill
-uint32_t tls_info::get_size_of_zero_fill() const
-{
- return size_of_zero_fill_;
-}
-
-//Returns characteristics
-uint32_t tls_info::get_characteristics() const
-{
- return characteristics_;
-}
-
-//Returns raw TLS data
-const std::string& tls_info::get_raw_data() const
-{
- return raw_data_;
-}
-
-//Returns TLS callbacks addresses
-const tls_info::tls_callback_list& tls_info::get_tls_callbacks() const
-{
- return callbacks_;
-}
-
-//Returns TLS callbacks addresses
-tls_info::tls_callback_list& tls_info::get_tls_callbacks()
-{
- return callbacks_;
-}
-
-//Adds TLS callback
-void tls_info::add_tls_callback(uint32_t rva)
-{
- callbacks_.push_back(rva);
-}
-
-//Clears TLS callbacks list
-void tls_info::clear_tls_callbacks()
-{
- callbacks_.clear();
-}
-
-//Recalculates end address of raw TLS data
-void tls_info::recalc_raw_data_end_rva()
-{
- end_rva_ = static_cast<uint32_t>(start_rva_ + raw_data_.length());
-}
-
-//Sets start RVA of TLS raw data
-void tls_info::set_raw_data_start_rva(uint32_t rva)
-{
- start_rva_ = rva;
-}
-
-//Sets end RVA of TLS raw data
-void tls_info::set_raw_data_end_rva(uint32_t rva)
-{
- end_rva_ = rva;
-}
-
-//Sets TLS index RVA
-void tls_info::set_index_rva(uint32_t rva)
-{
- index_rva_ = rva;
-}
-
-//Sets TLS callbacks RVA
-void tls_info::set_callbacks_rva(uint32_t rva)
-{
- callbacks_rva_ = rva;
-}
-
-//Sets size of zero fill
-void tls_info::set_size_of_zero_fill(uint32_t size)
-{
- size_of_zero_fill_ = size;
-}
-
-//Sets characteristics
-void tls_info::set_characteristics(uint32_t characteristics)
-{
- characteristics_ = characteristics;
-}
-
-//Sets raw TLS data
-void tls_info::set_raw_data(const std::string& data)
-{
- raw_data_ = data;
-}
-
-//If image does not have TLS, throws an exception
-const tls_info get_tls_info(const pe_base& pe)
-{
- return pe.get_pe_type() == pe_type_32
- ? get_tls_info_base<pe_types_class_32>(pe)
- : get_tls_info_base<pe_types_class_64>(pe);
-}
-
-//TLS Rebuilder
-const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section)
-{
- return pe.get_pe_type() == pe_type_32
- ? rebuild_tls_base<pe_types_class_32>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section)
- : rebuild_tls_base<pe_types_class_64>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section);
-}
-
-//Get TLS info
-//If image does not have TLS, throws an exception
-template<typename PEClassType>
-const tls_info get_tls_info_base(const pe_base& pe)
-{
- tls_info ret;
-
- //If there's no TLS directory, throw an exception
- if(!pe.has_tls())
- throw pe_exception("Image does not have TLS directory", pe_exception::directory_does_not_exist);
-
- //Get TLS directory data
- typename PEClassType::TLSStruct tls_directory_data = pe.section_data_from_rva<typename PEClassType::TLSStruct>(pe.get_directory_rva(image_directory_entry_tls), section_data_virtual, true);
-
- //Check data addresses
- if(tls_directory_data.EndAddressOfRawData == tls_directory_data.StartAddressOfRawData)
- {
- try
- {
- pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData));
- }
- catch(const pe_exception&)
- {
- //Fix addressess on incorrect conversion
- tls_directory_data.EndAddressOfRawData = tls_directory_data.StartAddressOfRawData = 0;
- }
- }
-
- if(tls_directory_data.StartAddressOfRawData &&
- pe.section_data_length_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData),
- static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true)
- < (tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData))
- throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory);
-
- //Fill TLS info
- //VAs are not checked
- ret.set_raw_data_start_rva(tls_directory_data.StartAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData)) : 0);
- ret.set_raw_data_end_rva(tls_directory_data.EndAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData)) : 0);
- ret.set_index_rva(tls_directory_data.AddressOfIndex ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfIndex)) : 0);
- ret.set_callbacks_rva(tls_directory_data.AddressOfCallBacks ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks)) : 0);
- ret.set_size_of_zero_fill(tls_directory_data.SizeOfZeroFill);
- ret.set_characteristics(tls_directory_data.Characteristics);
-
- if(tls_directory_data.StartAddressOfRawData && tls_directory_data.StartAddressOfRawData != tls_directory_data.EndAddressOfRawData)
- {
- //Read and save TLS RAW data
- ret.set_raw_data(std::string(
- pe.section_data_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true),
- static_cast<uint32_t>(tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData)));
- }
-
- //If file has TLS callbacks
- if(ret.get_callbacks_rva())
- {
- //Read callbacks VAs
- uint32_t current_tls_callback = 0;
-
- while(true)
- {
- //Read TLS callback VA
- typename PEClassType::BaseSize va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks + current_tls_callback), section_data_virtual, true);
- if(va == 0)
- break;
-
- //Save it
- ret.add_tls_callback(pe.va_to_rva(va, false));
-
- //Move to next callback VA
- current_tls_callback += sizeof(va);
- }
- }
-
- return ret;
-}
-
-//Rebuilder of TLS structures
-//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place
-//If write_tls_data = true, TLS data will be written to its place
-//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string
-//representing raw data content
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//Note/TODO: TLS Callbacks array is not DWORD-aligned (seems to work on WinXP - Win7)
-template<typename PEClassType>
-const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section)
-{
- //Check that tls_section is attached to this PE image
- if(!pe.section_attached(tls_section))
- throw pe_exception("TLS section must be attached to PE file", pe_exception::section_is_not_attached);
-
- uint32_t tls_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize));
- uint32_t needed_size = sizeof(typename PEClassType::TLSStruct); //Calculate needed size for TLS table
-
- //Check if tls_section is last one. If it's not, check if there's enough place for TLS data
- if(&tls_section != &*(pe.get_image_sections().end() - 1) &&
- (tls_section.empty() || pe_utils::align_up(tls_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + tls_data_pos))
- throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
-
- //Check raw data positions
- if(info.get_raw_data_end_rva() < info.get_raw_data_start_rva() || info.get_index_rva() == 0)
- throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory);
-
- std::string& raw_data = tls_section.get_raw_data();
-
- //This will be done only if tls_section is the last section of image or for section with unaligned raw length of data
- if(raw_data.length() < needed_size + tls_data_pos)
- raw_data.resize(needed_size + tls_data_pos); //Expand section raw data
-
- //Create and fill TLS structure
- typename PEClassType::TLSStruct tls_struct = {0};
-
- typename PEClassType::BaseSize va;
- if(info.get_raw_data_start_rva())
- {
- pe.rva_to_va(info.get_raw_data_start_rva(), va);
- tls_struct.StartAddressOfRawData = va;
- tls_struct.SizeOfZeroFill = info.get_size_of_zero_fill();
- }
-
- if(info.get_raw_data_end_rva())
- {
- pe.rva_to_va(info.get_raw_data_end_rva(), va);
- tls_struct.EndAddressOfRawData = va;
- }
-
- pe.rva_to_va(info.get_index_rva(), va);
- tls_struct.AddressOfIndex = va;
-
- if(info.get_callbacks_rva())
- {
- pe.rva_to_va(info.get_callbacks_rva(), va);
- tls_struct.AddressOfCallBacks = va;
- }
-
- tls_struct.Characteristics = info.get_characteristics();
-
- //Save TLS structure
- memcpy(&raw_data[tls_data_pos], &tls_struct, sizeof(tls_struct));
-
- //If we are asked to rewrite TLS raw data
- if(write_tls_data && info.get_raw_data_start_rva() && info.get_raw_data_start_rva() != info.get_raw_data_end_rva())
- {
- try
- {
- //Check if we're going to write TLS raw data to an existing section (not to PE headers)
- section& raw_data_section = pe.section_from_rva(info.get_raw_data_start_rva());
- pe.expand_section(raw_data_section, info.get_raw_data_start_rva(), info.get_raw_data_end_rva() - info.get_raw_data_start_rva(), expand == tls_data_expand_raw ? pe_base::expand_section_raw : pe_base::expand_section_virtual);
- }
- catch(const pe_exception&)
- {
- //If no section is presented by StartAddressOfRawData, just go to next step
- }
-
- unsigned long write_raw_data_size = info.get_raw_data_end_rva() - info.get_raw_data_start_rva();
- unsigned long available_raw_length = 0;
-
- //Check if there's enough RAW space to write raw TLS data...
- if((available_raw_length = pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_raw, true))
- < info.get_raw_data_end_rva() - info.get_raw_data_start_rva())
- {
- //Check if there's enough virtual space for it...
- if(pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_virtual, true)
- < info.get_raw_data_end_rva() - info.get_raw_data_start_rva())
- throw pe_exception("Insufficient space for TLS raw data", pe_exception::insufficient_space);
- else
- write_raw_data_size = available_raw_length; //We'll write just a part of full raw data
- }
-
- //Write raw TLS data, if any
- if(write_raw_data_size != 0)
- memcpy(pe.section_data_from_rva(info.get_raw_data_start_rva(), true), info.get_raw_data().data(), write_raw_data_size);
- }
-
- //If we are asked to rewrite TLS callbacks addresses
- if(write_tls_callbacks && info.get_callbacks_rva())
- {
- unsigned long needed_callback_size = static_cast<unsigned long>((info.get_tls_callbacks().size() + 1 /* last null element */) * sizeof(typename PEClassType::BaseSize));
-
- try
- {
- //Check if we're going to write TLS callbacks VAs to an existing section (not to PE headers)
- section& raw_data_section = pe.section_from_rva(info.get_callbacks_rva());
- pe.expand_section(raw_data_section, info.get_callbacks_rva(), needed_callback_size, pe_base::expand_section_raw);
- }
- catch(const pe_exception&)
- {
- //If no section is presented by RVA of callbacks, just go to next step
- }
-
- //Check if there's enough space to write callbacks TLS data...
- if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_raw, true)
- < needed_callback_size - sizeof(typename PEClassType::BaseSize) /* last zero element can be virtual only */)
- throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space);
-
- if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_virtual, true)
- < needed_callback_size /* check here full virtual data length available */)
- throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space);
-
- std::vector<typename PEClassType::BaseSize> callbacks_virtual_addresses;
- callbacks_virtual_addresses.reserve(info.get_tls_callbacks().size() + 1 /* last null element */);
-
- //Convert TLS RVAs to VAs
- for(tls_info::tls_callback_list::const_iterator it = info.get_tls_callbacks().begin(); it != info.get_tls_callbacks().end(); ++it)
- {
- typename PEClassType::BaseSize cb_va = 0;
- pe.rva_to_va(*it, cb_va);
- callbacks_virtual_addresses.push_back(cb_va);
- }
-
- //Ending null element
- callbacks_virtual_addresses.push_back(0);
-
- //Write callbacks TLS data
- memcpy(pe.section_data_from_rva(info.get_callbacks_rva(), true), &callbacks_virtual_addresses[0], needed_callback_size);
- }
-
- //Adjust section raw and virtual sizes
- pe.recalculate_section_sizes(tls_section, auto_strip_last_section);
-
- image_directory ret(pe.rva_from_section_offset(tls_section, tls_data_pos), needed_size);
-
- //If auto-rewrite of PE headers is required
- if(save_to_pe_header)
- {
- pe.set_directory_rva(image_directory_entry_tls, ret.get_rva());
- pe.set_directory_size(image_directory_entry_tls, ret.get_size());
- }
-
- return ret;
-}
-}
diff --git a/tools/pe_bliss/pe_tls.h b/tools/pe_bliss/pe_tls.h
deleted file mode 100644
index 316e208147..0000000000
--- a/tools/pe_bliss/pe_tls.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include <istream>
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing TLS info
-//We use "DWORD" type to represent RVAs, because RVA is
-//always 32bit even in PE+
-class tls_info
-{
-public:
- typedef std::vector<uint32_t> tls_callback_list;
-
-public:
- //Default constructor
- tls_info();
-
- //Returns start RVA of TLS raw data
- uint32_t get_raw_data_start_rva() const;
- //Returns end RVA of TLS raw data
- uint32_t get_raw_data_end_rva() const;
- //Returns TLS index RVA
- uint32_t get_index_rva() const;
- //Returns TLS callbacks RVA
- uint32_t get_callbacks_rva() const;
- //Returns size of zero fill
- uint32_t get_size_of_zero_fill() const;
- //Returns characteristics
- uint32_t get_characteristics() const;
- //Returns raw TLS data
- const std::string& get_raw_data() const;
- //Returns TLS callbacks addresses
- const tls_callback_list& get_tls_callbacks() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
- //You can also use them to rebuild TLS directory
-
- //Sets start RVA of TLS raw data
- void set_raw_data_start_rva(uint32_t rva);
- //Sets end RVA of TLS raw data
- void set_raw_data_end_rva(uint32_t rva);
- //Sets TLS index RVA
- void set_index_rva(uint32_t rva);
- //Sets TLS callbacks RVA
- void set_callbacks_rva(uint32_t rva);
- //Sets size of zero fill
- void set_size_of_zero_fill(uint32_t size);
- //Sets characteristics
- void set_characteristics(uint32_t characteristics);
- //Sets raw TLS data
- void set_raw_data(const std::string& data);
- //Returns TLS callbacks addresses
- tls_callback_list& get_tls_callbacks();
- //Adds TLS callback
- void add_tls_callback(uint32_t rva);
- //Clears TLS callbacks list
- void clear_tls_callbacks();
- //Recalculates end address of raw TLS data
- void recalc_raw_data_end_rva();
-
-private:
- uint32_t start_rva_, end_rva_, index_rva_, callbacks_rva_;
- uint32_t size_of_zero_fill_, characteristics_;
-
- //Raw TLS data
- std::string raw_data_;
-
- //TLS callback RVAs
- tls_callback_list callbacks_;
-};
-
-//Represents type of expanding of TLS section containing raw data
-//(Works only if you are writing TLS raw data to tls_section and it is the last one in the PE image on the moment of TLS rebuild)
-enum tls_data_expand_type
-{
- tls_data_expand_raw, //If there is not enough raw space for raw TLS data, it can be expanded
- tls_data_expand_virtual //If there is not enough virtual place for raw TLS data, it can be expanded
-};
-
-
-//Get TLS info
-//If image does not have TLS, throws an exception
-const tls_info get_tls_info(const pe_base& pe);
-
-template<typename PEClassType>
-const tls_info get_tls_info_base(const pe_base& pe);
-
-//Rebuilder of TLS structures
-//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place
-//If write_tls_data = true, TLS data will be written to its place
-//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string
-//representing raw data content
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-template<typename PEClassType>
-const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}
diff --git a/tools/pe_bliss/resource_bitmap_reader.cpp b/tools/pe_bliss/resource_bitmap_reader.cpp
deleted file mode 100644
index 3546461f53..0000000000
--- a/tools/pe_bliss/resource_bitmap_reader.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_bitmap_reader.h"
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_bitmap_reader::resource_bitmap_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_name(const std::wstring& name, uint32_t index) const
-{
- return create_bitmap(res_.get_resource_data_by_name(pe_resource_viewer::resource_bitmap, name, index).get_data());
-}
-
-//Returns bitmap data by name and language (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_name(uint32_t language, const std::wstring& name) const
-{
- return create_bitmap(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_bitmap, name).get_data());
-}
-
-//Returns bitmap data by ID and language (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_id_lang(uint32_t language, uint32_t id) const
-{
- return create_bitmap(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_bitmap, id).get_data());
-}
-
-//Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_id(uint32_t id, uint32_t index) const
-{
- return create_bitmap(res_.get_resource_data_by_id(pe_resource_viewer::resource_bitmap, id, index).get_data());
-}
-
-//Helper function of creating bitmap header
-const std::string resource_bitmap_reader::create_bitmap(const std::string& resource_data)
-{
- //Create bitmap file header
- bitmapfileheader header = {0};
- header.bfType = 0x4d42; //Signature "BM"
- header.bfOffBits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader); //Offset to bitmap bits
- header.bfSize = static_cast<uint32_t>(sizeof(bitmapfileheader) + resource_data.length()); //Size of bitmap
-
- //Check size of resource data
- if(resource_data.length() < sizeof(bitmapinfoheader))
- throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
- {
- //Get bitmap info header
- const bitmapinfoheader* info = reinterpret_cast<const bitmapinfoheader*>(resource_data.data());
-
- //If color table is present, skip it
- if(info->biClrUsed != 0)
- header.bfOffBits += 4 * info->biClrUsed; //Add this size to offset to bitmap bits
- else if(info->biBitCount <= 8)
- header.bfOffBits += 4 * static_cast<uint32_t>(std::pow(2.f, info->biBitCount)); //Add this size to offset to bitmap bits
- }
-
- //Return final bitmap data
- return std::string(reinterpret_cast<const char*>(&header), sizeof(bitmapfileheader)) + resource_data;
-}
-}
diff --git a/tools/pe_bliss/resource_bitmap_reader.h b/tools/pe_bliss/resource_bitmap_reader.h
deleted file mode 100644
index f2b92bbde7..0000000000
--- a/tools/pe_bliss/resource_bitmap_reader.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_bitmap_reader
-{
-public:
- resource_bitmap_reader(const pe_resource_viewer& res);
-
- //Returns bitmap data by name and language (minimum checks of format correctness)
- const std::string get_bitmap_by_name(uint32_t language, const std::wstring& name) const;
- //Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_bitmap_by_name(const std::wstring& name, uint32_t index = 0) const;
- //Returns bitmap data by ID and language (minimum checks of format correctness)
- const std::string get_bitmap_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_bitmap_by_id(uint32_t id, uint32_t index = 0) const;
-
-private:
- //Helper function of creating bitmap header
- static const std::string create_bitmap(const std::string& resource_data);
-
- const pe_resource_viewer& res_;
-};
-}
diff --git a/tools/pe_bliss/resource_bitmap_writer.cpp b/tools/pe_bliss/resource_bitmap_writer.cpp
deleted file mode 100644
index 3445a08445..0000000000
--- a/tools/pe_bliss/resource_bitmap_writer.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_bitmap_writer.h"
-#include "pe_resource_manager.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_bitmap_writer::resource_bitmap_writer(pe_resource_manager& res)
- :res_(res)
-{}
-
-//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-//timestamp will be used for directories that will be added
-void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- //Check bitmap data a little
- if(bitmap_file.length() < sizeof(bitmapfileheader))
- throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
- resource_directory_entry new_entry;
- new_entry.set_id(id);
-
- //Add bitmap
- res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-
-//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-//timestamp will be used for directories that will be added
-void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
- //Check bitmap data a little
- if(bitmap_file.length() < sizeof(bitmapfileheader))
- throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
- resource_directory_entry new_entry;
- new_entry.set_name(name);
-
- //Add bitmap
- res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Removes bitmap by name/ID and language
-bool resource_bitmap_writer::remove_bitmap(const std::wstring& name, uint32_t language)
-{
- return res_.remove_resource(pe_resource_viewer::resource_bitmap, name, language);
-}
-
-//Removes bitmap by name/ID and language
-bool resource_bitmap_writer::remove_bitmap(uint32_t id, uint32_t language)
-{
- return res_.remove_resource(pe_resource_viewer::resource_bitmap, id, language);
-}
-}
diff --git a/tools/pe_bliss/resource_bitmap_writer.h b/tools/pe_bliss/resource_bitmap_writer.h
deleted file mode 100644
index 4b8ea72705..0000000000
--- a/tools/pe_bliss/resource_bitmap_writer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_bitmap_writer
-{
-public:
- resource_bitmap_writer(pe_resource_manager& res);
-
- //Adds bitmap from bitmap file data. If bitmap already exists, replaces it
- //timestamp will be used for directories that will be added
- void add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-
- //Removes bitmap by name/ID and language
- bool remove_bitmap(const std::wstring& name, uint32_t language);
- bool remove_bitmap(uint32_t id, uint32_t language);
-
-private:
- pe_resource_manager& res_;
-};
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_reader.cpp b/tools/pe_bliss/resource_cursor_icon_reader.cpp
deleted file mode 100644
index 28a259163e..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_reader.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_cursor_icon_reader.h"
-#include "pe_structures.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_cursor_icon_reader::resource_cursor_icon_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Helper function of creating icon headers from ICON_GROUP resource data
-//Returns icon count
-uint16_t resource_cursor_icon_reader::format_icon_headers(std::string& ico_data, const std::string& resource_data)
-{
- //Check resource data size
- if(resource_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- const ico_header* info = reinterpret_cast<const ico_header*>(resource_data.data());
-
- //Check resource data size
- if(resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Reserve memory to speed up a little
- ico_data.reserve(sizeof(ico_header) + info->Count * sizeof(icondirentry));
- ico_data.append(reinterpret_cast<const char*>(info), sizeof(ico_header));
-
- //Iterate over all listed icons
- uint32_t offset = sizeof(ico_header) + sizeof(icondirentry) * info->Count;
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-
- //Fill icon data
- icondirentry direntry;
- direntry.BitCount = group->BitCount;
- direntry.ColorCount = group->ColorCount;
- direntry.Height = group->Height;
- direntry.Planes = group->Planes;
- direntry.Reserved = group->Reserved;
- direntry.SizeInBytes = group->SizeInBytes;
- direntry.Width = group->Width;
- direntry.ImageOffset = offset;
-
- //Add icon header to returned value
- ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(icondirentry));
-
- offset += group->SizeInBytes;
- }
-
- //Return icon count
- return info->Count;
-}
-
-//Returns single icon data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_icon_by_id_lang(uint32_t language, uint32_t id) const
-{
- //Get icon headers
- std::string icon_data(lookup_icon_group_data_by_icon(id, language));
- //Append icon data
- icon_data.append(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, id).get_data());
- return icon_data;
-}
-
-//Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_icon_by_id(uint32_t id, uint32_t index) const
-{
- pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_icon, id));
- if(languages.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- //Get icon headers
- std::string icon_data(lookup_icon_group_data_by_icon(id, languages.at(index)));
- //Append icon data
- icon_data.append(res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, id, index).get_data());
- return icon_data;
-}
-
-//Returns icon data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_name(const std::wstring& name, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by name and index
- const std::string data = res_.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, name, index).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data();
- }
-
- return ret;
-}
-
-//Returns icon data by name and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_name(uint32_t language, const std::wstring& name) const
-{
- std::string ret;
-
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, name).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data();
- }
-
- return ret;
-}
-
-//Returns icon data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_id_lang(uint32_t language, uint32_t id) const
-{
- std::string ret;
-
- //Get resource by language and id
- const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, id).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data();
- }
-
- return ret;
-}
-
-//Returns icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_id(uint32_t id, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by id and index
- const std::string data = res_.get_resource_data_by_id(pe_resource_viewer::resource_icon_group, id, index).get_data();
-
- //Create icon headers
- uint16_t icon_count = format_icon_headers(ret, data);
-
- //Append icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data();
- }
-
- return ret;
-}
-
-//Checks for icon presence inside icon group, fills icon headers if found
-bool resource_cursor_icon_reader::check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data)
-{
- //Check resource data size
- if(icon_group_resource_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_resource_data.data());
-
- //Check resource data size
- if(icon_group_resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- if(group->Number == icon_id)
- {
- //Reserve memory to speed up a little
- ico_data.reserve(sizeof(ico_header) + sizeof(icondirentry));
- //Write single-icon icon header
- ico_header new_header = *info;
- new_header.Count = 1;
- ico_data.append(reinterpret_cast<const char*>(&new_header), sizeof(ico_header));
-
- //Fill icon data
- icondirentry direntry;
- direntry.BitCount = group->BitCount;
- direntry.ColorCount = group->ColorCount;
- direntry.Height = group->Height;
- direntry.Planes = group->Planes;
- direntry.Reserved = group->Reserved;
- direntry.SizeInBytes = group->SizeInBytes;
- direntry.Width = group->Width;
- direntry.ImageOffset = sizeof(ico_header) + sizeof(icondirentry);
- ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(direntry));
-
- return true;
- }
- }
-
- return false;
-}
-
-//Looks up icon group by icon id and returns full icon headers if found
-const std::string resource_cursor_icon_reader::lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const
-{
- std::string icon_header_data;
-
- {
- //List all ID-resources
- pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_icon_group));
-
- for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_icon_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data))
- return icon_header_data;
- }
- }
-
- {
- //List all named resources
- pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_icon_group));
- for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_icon_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data))
- return icon_header_data;
- }
- }
-
- throw pe_exception("No icon group find for requested icon", pe_exception::no_icon_group_found);
-}
-
-//Returns single cursor data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const
-{
- std::string raw_cursor_data(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, id).get_data());
- //Get cursor headers
- std::string cursor_data(lookup_cursor_group_data_by_cursor(id, language, raw_cursor_data));
- //Append cursor data
- cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */));
- return cursor_data;
-}
-
-//Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_cursor_by_id(uint32_t id, uint32_t index) const
-{
- pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor, id));
- if(languages.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- std::string raw_cursor_data(res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, id, index).get_data());
- //Get cursor headers
- std::string cursor_data(lookup_cursor_group_data_by_cursor(id, languages.at(index), raw_cursor_data));
- //Append cursor data
- cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */));
- return cursor_data;
-}
-
-//Helper function of creating cursor headers
-//Returns cursor count
-uint16_t resource_cursor_icon_reader::format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index) const
-{
- //Check resource data length
- if(resource_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- const cursor_header* info = reinterpret_cast<const cursor_header*>(resource_data.data());
-
- //Check resource data length
- if(resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group) * info->Count)
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Reserve needed space to speed up a little
- cur_data.reserve(sizeof(cursor_header) + info->Count * sizeof(cursordirentry));
- //Add cursor header
- cur_data.append(reinterpret_cast<const char*>(info), sizeof(cursor_header));
-
- //Iterate over all cursors listed in cursor group
- uint32_t offset = sizeof(cursor_header) + sizeof(cursordirentry) * info->Count;
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-
- //Fill cursor info
- cursordirentry direntry;
- direntry.ColorCount = 0; //OK
- direntry.Width = static_cast<uint8_t>(group->Width);
- direntry.Height = static_cast<uint8_t>(group->Height) / 2;
- direntry.Reserved = 0;
-
- //Now read hotspot data from cursor data directory
- const std::string cursor = index == 0xFFFFFFFF
- ? res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data()
- : res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data();
- if(cursor.length() < 2 * sizeof(uint16_t))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Here it is - two words in the very beginning of cursor data
- direntry.HotspotX = *reinterpret_cast<const uint16_t*>(cursor.data());
- direntry.HotspotY = *reinterpret_cast<const uint16_t*>(cursor.data() + sizeof(uint16_t));
-
- //Fill the rest data
- direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t);
- direntry.ImageOffset = offset;
-
- //Add cursor header
- cur_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry));
-
- offset += direntry.SizeInBytes;
- }
-
- //Return cursor count
- return info->Count;
-}
-
-//Returns cursor data by name and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_name(uint32_t language, const std::wstring& name) const
-{
- std::string ret;
-
- //Get resource by name and language
- const std::string resource_data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, name).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, language);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_name(const std::wstring& name, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by name and index
- const std::string resource_data = res_.get_resource_data_by_name(pe_resource_viewer::resource_cursor_group, name, index).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Returns cursor data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_id_lang(uint32_t language, uint32_t id) const
-{
- std::string ret;
-
- //Get resource by ID and language
- const std::string resource_data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, id).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, language);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_id(uint32_t id, uint32_t index) const
-{
- std::string ret;
-
- //Get resource by ID and index
- const std::string resource_data = res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor_group, id, index).get_data();
-
- //Create cursor headers
- uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index);
-
- //Add cursor data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t));
- }
-
- return ret;
-}
-
-//Checks for cursor presence inside cursor group, fills cursor headers if found
-bool resource_cursor_icon_reader::check_cursor_presence(const std::string& cursor_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data)
-{
- //Check resource data length
- if(cursor_group_resource_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_resource_data.data());
-
- //Check resource data length
- if(cursor_group_resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Iterate over all cursors listed in cursor group
- for(uint16_t i = 0; i != info->Count; ++i)
- {
- const cursor_group* group = reinterpret_cast<const cursor_group*>(cursor_group_resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-
- if(group->Number == cursor_id)
- {
- //Reserve needed space to speed up a little
- cur_header_data.reserve(sizeof(cursor_header) + sizeof(cursordirentry));
- //Write single-cursor cursor header
- cursor_header new_header = *info;
- new_header.Count = 1;
- cur_header_data.append(reinterpret_cast<const char*>(&new_header), sizeof(cursor_header));
-
- //Fill cursor info
- cursordirentry direntry;
- direntry.ColorCount = 0; //OK
- direntry.Width = static_cast<uint8_t>(group->Width);
- direntry.Height = static_cast<uint8_t>(group->Height) / 2;
- direntry.Reserved = 0;
-
- if(raw_cursor_data.length() < 2 * sizeof(uint16_t))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Here it is - two words in the very beginning of cursor data
- direntry.HotspotX = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data());
- direntry.HotspotY = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data() + sizeof(uint16_t));
-
- //Fill the rest data
- direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t);
- direntry.ImageOffset = sizeof(cursor_header) + sizeof(cursordirentry);
-
- //Add cursor header
- cur_header_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry));
-
- return true;
- }
- }
-
- return false;
-}
-
-//Looks up cursor group by cursor id and returns full cursor headers if found
-const std::string resource_cursor_icon_reader::lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const
-{
- std::string cursor_header_data;
-
- {
- //List all ID-resources
- pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_cursor_group));
-
- for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_cursor_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data))
- return cursor_header_data;
- }
- }
-
- {
- //List all named resources
- pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_cursor_group));
- for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it)
- {
- pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it));
- if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
- && check_cursor_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data))
- return cursor_header_data;
- }
- }
-
- throw pe_exception("No cursor group find for requested icon", pe_exception::no_cursor_group_found);
-}
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_reader.h b/tools/pe_bliss/resource_cursor_icon_reader.h
deleted file mode 100644
index e34fff419b..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_reader.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_cursor_icon_reader
-{
-public:
- resource_cursor_icon_reader(const pe_resource_viewer& res);
-
- //Returns single icon data by ID and language (minimum checks of format correctness)
- const std::string get_single_icon_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_single_icon_by_id(uint32_t id, uint32_t index = 0) const;
-
- //Returns icon data of group of icons by name and language (minimum checks of format correctness)
- const std::string get_icon_by_name(uint32_t language, const std::wstring& icon_group_name) const;
- //Returns icon data of group of icons by name and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_icon_by_name(const std::wstring& icon_group_name, uint32_t index = 0) const;
- //Returns icon data of group of icons by ID and language (minimum checks of format correctness)
- const std::string get_icon_by_id_lang(uint32_t language, uint32_t icon_group_id) const;
- //Returns icon data of group of icons by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_icon_by_id(uint32_t icon_group_id, uint32_t index = 0) const;
-
- //Returns single cursor data by ID and language (minimum checks of format correctness)
- const std::string get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_single_cursor_by_id(uint32_t id, uint32_t index = 0) const;
-
- //Returns cursor data by name and language (minimum checks of format correctness)
- const std::string get_cursor_by_name(uint32_t language, const std::wstring& cursor_group_name) const;
- //Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_cursor_by_name(const std::wstring& cursor_group_name, uint32_t index = 0) const;
- //Returns cursor data by ID and language (minimum checks of format correctness)
- const std::string get_cursor_by_id_lang(uint32_t language, uint32_t cursor_group_id) const;
- //Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
- const std::string get_cursor_by_id(uint32_t cursor_group_id, uint32_t index = 0) const;
-
-private:
- const pe_resource_viewer& res_;
-
- //Helper function of creating icon headers from ICON_GROUP resource data
- //Returns icon count
- static uint16_t format_icon_headers(std::string& ico_data, const std::string& resource_data);
-
- //Helper function of creating cursor headers from CURSOR_GROUP resource data
- //Returns cursor count
- uint16_t format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index = 0xFFFFFFFF) const;
-
- //Looks up icon group by icon id and returns full icon headers if found
- const std::string lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const;
- //Checks for icon presence inside icon group, fills icon headers if found
- static bool check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data);
-
- //Looks up cursor group by cursor id and returns full cursor headers if found
- const std::string lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const;
- //Checks for cursor presence inside cursor group, fills cursor headers if found
- static bool check_cursor_presence(const std::string& icon_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data);
-};
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_writer.cpp b/tools/pe_bliss/resource_cursor_icon_writer.cpp
deleted file mode 100644
index 2f1c4363c4..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_writer.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "resource_cursor_icon_writer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_cursor_icon_writer::resource_cursor_icon_writer(pe_resource_manager& res)
- :res_(res)
-{}
-
-//Add icon helper
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- //Check icon for correctness
- if(icon_file.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- const ico_header* icon_header = reinterpret_cast<const ico_header*>(&icon_file[0]);
-
- unsigned long size_of_headers = sizeof(ico_header) + icon_header->Count * sizeof(icondirentry);
- if(icon_file.length() < size_of_headers || icon_header->Count == 0)
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Enumerate all icons in file
- for(uint16_t i = 0; i != icon_header->Count; ++i)
- {
- //Check icon entries
- const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]);
- if(icon_entry->SizeInBytes == 0
- || icon_entry->ImageOffset < size_of_headers
- || !pe_utils::is_sum_safe(icon_entry->ImageOffset, icon_entry->SizeInBytes)
- || icon_entry->ImageOffset + icon_entry->SizeInBytes > icon_file.length())
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
- }
-
- std::string icon_group_data;
- ico_header* info = 0;
-
- if(group_icon_info)
- {
- //If icon group already exists
- {
- icon_group_data = group_icon_info->get_data();
- codepage = group_icon_info->get_codepage(); //Don't change codepage of icon group entry
- }
-
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- info = reinterpret_cast<ico_header*>(&icon_group_data[0]);
-
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- icon_group_data.resize(sizeof(ico_header) + (info->Count + icon_header->Count) * sizeof(icon_group));
- info = reinterpret_cast<ico_header*>(&icon_group_data[0]); //In case if memory was reallocated
- }
- else //Entry not found - icon group doesn't exist
- {
- icon_group_data.resize(sizeof(ico_header) + icon_header->Count * sizeof(icon_group));
- memcpy(&icon_group_data[0], icon_header, sizeof(ico_header));
- }
-
- //Search for available icon IDs
- std::vector<uint16_t> icon_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_icon, mode, icon_header->Count));
-
- //Enumerate all icons in file
- for(uint16_t i = 0; i != icon_header->Count; ++i)
- {
- const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]);
- icon_group group = {0};
-
- //Fill icon resource header
- group.BitCount = icon_entry->BitCount;
- group.ColorCount = icon_entry->ColorCount;
- group.Height = icon_entry->Height;
- group.Planes = icon_entry->Planes;
- group.Reserved = icon_entry->Reserved;
- group.SizeInBytes = icon_entry->SizeInBytes;
- group.Width = icon_entry->Width;
- group.Number = icon_id_list.at(i);
-
- memcpy(&icon_group_data[sizeof(ico_header) + ((info ? info->Count : 0) + i) * sizeof(icon_group)], &group, sizeof(group));
-
- //Add icon to resources
- resource_directory_entry new_entry;
- new_entry.set_id(group.Number);
- res_.add_resource(icon_file.substr(icon_entry->ImageOffset, icon_entry->SizeInBytes), pe_resource_viewer::resource_icon, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp);
- }
-
- if(info)
- info->Count += icon_header->Count; //Increase icon count, if we're adding icon to existing group
-
- {
- //Add or replace icon group data entry
- res_.add_resource(icon_group_data, pe_resource_viewer::resource_icon_group, new_icon_group_entry, finder, language, codepage, timestamp);
- }
-}
-
-//Returns free icon or cursor ID list depending on icon_place_mode
-const std::vector<uint16_t> resource_cursor_icon_writer::get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_type type, icon_place_mode mode, uint32_t count)
-{
- //Search for available icon/cursor IDs
- std::vector<uint16_t> icon_cursor_id_list;
-
- try
- {
- //If any icon exists
- //List icon IDs
- std::vector<uint32_t> id_list(res_.list_resource_ids(type));
- std::sort(id_list.begin(), id_list.end());
-
- //If we are placing icon on free spaces
- //I.e., icon IDs 1, 3, 4, 7, 8 already exist
- //We'll place five icons on IDs 2, 5, 6, 9, 10
- if(mode != icon_place_after_max_icon_id)
- {
- if(!id_list.empty())
- {
- //Determine and list free icon IDs
- for(std::vector<uint32_t>::const_iterator it = id_list.begin(); it != id_list.end(); ++it)
- {
- if(it == id_list.begin())
- {
- if(*it > 1)
- {
- for(uint16_t i = 1; i != *it; ++i)
- {
- icon_cursor_id_list.push_back(i);
- if(icon_cursor_id_list.size() == count)
- break;
- }
- }
- }
- else if(*(it - 1) - *it > 1)
- {
- for(uint16_t i = static_cast<uint16_t>(*(it - 1) + 1); i != static_cast<uint16_t>(*it); ++i)
- {
- icon_cursor_id_list.push_back(i);
- if(icon_cursor_id_list.size() == count)
- break;
- }
- }
-
- if(icon_cursor_id_list.size() == count)
- break;
- }
- }
- }
-
- uint32_t max_id = id_list.empty() ? 0 : *std::max_element(id_list.begin(), id_list.end());
- for(uint32_t i = static_cast<uint32_t>(icon_cursor_id_list.size()); i != count; ++i)
- icon_cursor_id_list.push_back(static_cast<uint16_t>(++max_id));
- }
- catch(const pe_exception&) //Entry not found
- {
- for(uint16_t i = 1; i != count + 1; ++i)
- icon_cursor_id_list.push_back(i);
- }
-
- return icon_cursor_id_list;
-}
-
-//Add cursor helper
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- //Check cursor for correctness
- if(cursor_file.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- const cursor_header* cur_header = reinterpret_cast<const cursor_header*>(&cursor_file[0]);
-
- unsigned long size_of_headers = sizeof(cursor_header) + cur_header->Count * sizeof(cursordirentry);
- if(cursor_file.length() < size_of_headers || cur_header->Count == 0)
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Enumerate all cursors in file
- for(uint16_t i = 0; i != cur_header->Count; ++i)
- {
- //Check cursor entries
- const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]);
- if(cursor_entry->SizeInBytes == 0
- || cursor_entry->ImageOffset < size_of_headers
- || !pe_utils::is_sum_safe(cursor_entry->ImageOffset, cursor_entry->SizeInBytes)
- || cursor_entry->ImageOffset + cursor_entry->SizeInBytes > cursor_file.length())
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
- }
-
- std::string cursor_group_data;
- cursor_header* info = 0;
-
- if(group_cursor_info)
- {
- //If cursor group already exists
- {
- cursor_group_data = group_cursor_info->get_data();
- codepage = group_cursor_info->get_codepage(); //Don't change codepage of cursor group entry
- }
-
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Get cursor header
- info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]);
-
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header) + info->Count * sizeof(cursor_group))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- cursor_group_data.resize(sizeof(cursor_header) + (info->Count + cur_header->Count) * sizeof(cursor_group));
- info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]); //In case if memory was reallocated
- }
- else //Entry not found - cursor group doesn't exist
- {
- cursor_group_data.resize(sizeof(cursor_header) + cur_header->Count * sizeof(cursor_group));
- memcpy(&cursor_group_data[0], cur_header, sizeof(cursor_header));
- }
-
- //Search for available cursor IDs
- std::vector<uint16_t> cursor_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_cursor, mode, cur_header->Count));
-
- //Enumerate all cursors in file
- for(uint16_t i = 0; i != cur_header->Count; ++i)
- {
- const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]);
- cursor_group group = {0};
-
- //Fill cursor resource header
- group.Height = cursor_entry->Height * 2;
- group.SizeInBytes = cursor_entry->SizeInBytes + 2 * sizeof(uint16_t) /* hotspot coordinates */;
- group.Width = cursor_entry->Width;
- group.Number = cursor_id_list.at(i);
-
- memcpy(&cursor_group_data[sizeof(cursor_header) + ((info ? info->Count : 0) + i) * sizeof(cursor_group)], &group, sizeof(group));
-
- //Add cursor to resources
- resource_directory_entry new_entry;
- new_entry.set_id(group.Number);
-
- //Fill resource data (two WORDs for hotspot of cursor, and cursor bitmap data)
- std::string cur_data;
- cur_data.resize(sizeof(uint16_t) * 2);
- memcpy(&cur_data[0], &cursor_entry->HotspotX, sizeof(uint16_t));
- memcpy(&cur_data[sizeof(uint16_t)], &cursor_entry->HotspotY, sizeof(uint16_t));
- cur_data.append(cursor_file.substr(cursor_entry->ImageOffset, cursor_entry->SizeInBytes));
-
- res_.add_resource(cur_data, pe_resource_viewer::resource_cursor, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp);
- }
-
- if(info)
- info->Count += cur_header->Count; //Increase cursor count, if we're adding cursor to existing group
-
- {
- //Add or replace cursor group data entry
- res_.add_resource(cursor_group_data, pe_resource_viewer::resource_cursor_group, new_cursor_group_entry, finder, language, codepage, timestamp);
- }
-}
-
-//Adds icon(s) from icon file data
-//timestamp will be used for directories that will be added
-//If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s)
-//(Codepage of icon group and icons will not be changed in this case)
-//icon_place_mode determines, how new icon(s) will be placed
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const std::wstring& icon_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_icon_group_entry;
- new_icon_group_entry.set_name(icon_group_name);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_name), language, mode, codepage, timestamp);
-}
-
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, uint32_t icon_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_icon_group_entry;
- new_icon_group_entry.set_id(icon_group_id);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_id), language, mode, codepage, timestamp);
-}
-
-//Adds cursor(s) from cursor file data
-//timestamp will be used for directories that will be added
-//If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s)
-//(Codepage of cursor group and cursors will not be changed in this case)
-//icon_place_mode determines, how new cursor(s) will be placed
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_cursor_group_entry;
- new_cursor_group_entry.set_name(cursor_group_name);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_name), language, mode, codepage, timestamp);
-}
-
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
- resource_directory_entry new_cursor_group_entry;
- new_cursor_group_entry.set_id(cursor_group_id);
- std::auto_ptr<resource_data_info> data_info;
-
- try
- {
- data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id)));
- }
- catch(const pe_exception&) //Entry not found
- {
- }
-
- add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_id), language, mode, codepage, timestamp);
-}
-
-//Remove icon group helper
-void resource_cursor_icon_writer::remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language)
-{
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Get icon header
- const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_data.data());
-
- uint16_t icon_count = info->Count;
-
- //Check resource data size
- if(icon_group_data.length() < sizeof(ico_header) + icon_count * sizeof(icon_group))
- throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
- //Remove icon data
- for(uint16_t i = 0; i != icon_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
- res_.remove_resource(pe_resource_viewer::resource_icon, group->Number, language);
- }
-}
-
-//Remove cursor group helper
-void resource_cursor_icon_writer::remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language)
-{
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Get icon header
- const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_data.data());
-
- uint16_t cursor_count = info->Count;
-
- //Check resource data size
- if(cursor_group_data.length() < sizeof(cursor_header) + cursor_count * sizeof(cursor_group))
- throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
- //Remove icon data
- for(uint16_t i = 0; i != cursor_count; ++i)
- {
- const icon_group* group = reinterpret_cast<const icon_group*>(cursor_group_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
- res_.remove_resource(pe_resource_viewer::resource_cursor, group->Number, language);
- }
-}
-
-//Removes cursor group and all its cursors by name/ID and language
-bool resource_cursor_icon_writer::remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name).get_data();
- remove_cursors_from_cursor_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_name, language);
-}
-
-//Removes cursor group and all its cursors by name/ID and language
-bool resource_cursor_icon_writer::remove_cursor_group(uint32_t cursor_group_id, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id).get_data();
- remove_cursors_from_cursor_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_id, language);
-}
-
-//Removes icon group and all its icons by name/ID and language
-bool resource_cursor_icon_writer::remove_icon_group(const std::wstring& icon_group_name, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name).get_data();
- remove_icons_from_icon_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_name, language);
-}
-
-//Removes icon group and all its icons by name/ID and language
-bool resource_cursor_icon_writer::remove_icon_group(uint32_t icon_group_id, uint32_t language)
-{
- //Get resource by name and language
- const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id).get_data();
- remove_icons_from_icon_group(data, language);
- return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_id, language);
-}
-}
diff --git a/tools/pe_bliss/resource_cursor_icon_writer.h b/tools/pe_bliss/resource_cursor_icon_writer.h
deleted file mode 100644
index e73ac6a093..0000000000
--- a/tools/pe_bliss/resource_cursor_icon_writer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include "stdint_defs.h"
-#include "pe_resource_manager.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_cursor_icon_writer
-{
-public:
- //Determines, how new icon(s) or cursor(s) will be placed
- enum icon_place_mode
- {
- icon_place_after_max_icon_id, //Icon(s) will be placed after all existing
- icon_place_free_ids //New icon(s) will take all free IDs between existing icons
- };
-
-public:
- resource_cursor_icon_writer(pe_resource_manager& res);
-
- //Removes icon group and all its icons by name/ID and language
- bool remove_icon_group(const std::wstring& icon_group_name, uint32_t language);
- bool remove_icon_group(uint32_t icon_group_id, uint32_t language);
-
- //Adds icon(s) from icon file data
- //timestamp will be used for directories that will be added
- //If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s)
- //(Codepage of icon group and icons will not be changed in this case)
- //icon_place_mode determines, how new icon(s) will be placed
- void add_icon(const std::string& icon_file,
- const std::wstring& icon_group_name,
- uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id,
- uint32_t codepage = 0, uint32_t timestamp = 0);
-
- void add_icon(const std::string& icon_file,
- uint32_t icon_group_id,
- uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id,
- uint32_t codepage = 0, uint32_t timestamp = 0);
-
- //Removes cursor group and all its cursors by name/ID and language
- bool remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language);
- bool remove_cursor_group(uint32_t cursor_group_id, uint32_t language);
-
- //Adds cursor(s) from cursor file data
- //timestamp will be used for directories that will be added
- //If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s)
- //(Codepage of cursor group and cursors will not be changed in this case)
- //icon_place_mode determines, how new cursor(s) will be placed
- void add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0);
- void add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-private:
- pe_resource_manager& res_;
-
- //Add icon helper
- void add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp);
-
- //Remove icon group helper
- void remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language);
-
- //Add cursor helper
- void add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp);
-
- //Remove cursor group helper
- void remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language);
-
- //Returns free icon or cursor ID list depending on icon_place_mode
- const std::vector<uint16_t> get_icon_or_cursor_free_id_list(pe_resource_manager::resource_type type, icon_place_mode mode, uint32_t count);
-};
-}
diff --git a/tools/pe_bliss/resource_data_info.cpp b/tools/pe_bliss/resource_data_info.cpp
deleted file mode 100644
index 75bb060eae..0000000000
--- a/tools/pe_bliss/resource_data_info.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_data_info.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-//Default constructor
-resource_data_info::resource_data_info(const std::string& data, uint32_t codepage)
- :data_(data), codepage_(codepage)
-{}
-
-//Constructor from data
-resource_data_info::resource_data_info(const resource_data_entry& data)
- :data_(data.get_data()), codepage_(data.get_codepage())
-{}
-
-//Returns resource data
-const std::string& resource_data_info::get_data() const
-{
- return data_;
-}
-
-//Returns resource codepage
-uint32_t resource_data_info::get_codepage() const
-{
- return codepage_;
-}
-}
diff --git a/tools/pe_bliss/resource_data_info.h b/tools/pe_bliss/resource_data_info.h
deleted file mode 100644
index e2275ebbf5..0000000000
--- a/tools/pe_bliss/resource_data_info.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class resource_data_entry;
-
-//Class representing resource data
-class resource_data_info
-{
-public:
- //Constructor from data
- resource_data_info(const std::string& data, uint32_t codepage);
- //Constructor from data
- explicit resource_data_info(const resource_data_entry& data);
-
- //Returns resource data
- const std::string& get_data() const;
- //Returns resource codepage
- uint32_t get_codepage() const;
-
-private:
- std::string data_;
- uint32_t codepage_;
-};
-}
diff --git a/tools/pe_bliss/resource_internal.h b/tools/pe_bliss/resource_internal.h
deleted file mode 100644
index 64a5bf3903..0000000000
--- a/tools/pe_bliss/resource_internal.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-
-#define U16TEXT(t) reinterpret_cast<const unicode16_t*>( t )
-
-#define StringFileInfo U16TEXT("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define SizeofStringFileInfo sizeof("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define VarFileInfo U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define Translation U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0")
-
-#define VarFileInfoAligned U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0")
-#define TranslationAligned U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0")
-#define SizeofVarFileInfoAligned sizeof("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0")
-#define SizeofTranslationAligned sizeof("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0")
diff --git a/tools/pe_bliss/resource_message_list_reader.cpp b/tools/pe_bliss/resource_message_list_reader.cpp
deleted file mode 100644
index f2ea142bee..0000000000
--- a/tools/pe_bliss/resource_message_list_reader.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_message_list_reader.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_message_list_reader::resource_message_list_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Helper function of parsing message list table
-const resource_message_list resource_message_list_reader::parse_message_list(const std::string& resource_data)
-{
- resource_message_list ret;
-
- //Check resource data length
- if(resource_data.length() < sizeof(message_resource_data))
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- const message_resource_data* message_data = reinterpret_cast<const message_resource_data*>(resource_data.data());
-
- //Check resource data length more carefully and some possible overflows
- if(message_data->NumberOfBlocks >= pe_utils::max_dword / sizeof(message_resource_block)
- || !pe_utils::is_sum_safe(message_data->NumberOfBlocks * sizeof(message_resource_block), sizeof(message_resource_data))
- || resource_data.length() < message_data->NumberOfBlocks * sizeof(message_resource_block) + sizeof(message_resource_data))
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- //Iterate over all message resource blocks
- for(unsigned long i = 0; i != message_data->NumberOfBlocks; ++i)
- {
- //Get block
- const message_resource_block* block =
- reinterpret_cast<const message_resource_block*>(resource_data.data() + sizeof(message_resource_data) - sizeof(message_resource_block) + sizeof(message_resource_block) * i);
-
- //Check resource data length and IDs
- if(resource_data.length() < block->OffsetToEntries || block->LowId > block->HighId)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- unsigned long current_pos = 0;
- static const unsigned long size_of_entry_headers = 4;
- //List all message resource entries in block
- for(uint32_t curr_id = block->LowId; curr_id <= block->HighId; curr_id++)
- {
- //Check resource data length and some possible overflows
- if(!pe_utils::is_sum_safe(block->OffsetToEntries, current_pos)
- || !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, size_of_entry_headers)
- || resource_data.length() < block->OffsetToEntries + current_pos + size_of_entry_headers)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- //Get entry
- const message_resource_entry* entry = reinterpret_cast<const message_resource_entry*>(resource_data.data() + block->OffsetToEntries + current_pos);
-
- //Check resource data length and entry length and some possible overflows
- if(entry->Length < size_of_entry_headers
- || !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, entry->Length)
- || resource_data.length() < block->OffsetToEntries + current_pos + entry->Length
- || entry->Length < size_of_entry_headers)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- if(entry->Flags & message_resource_unicode)
- {
- //If string is UNICODE
- //Check its length
- if(entry->Length % 2)
- throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
- //Add ID and string to message table
-#ifdef PE_BLISS_WINDOWS
- ret.insert(std::make_pair(curr_id, message_table_item(
- std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
- (entry->Length - size_of_entry_headers) / 2)
- )));
-#else
- ret.insert(std::make_pair(curr_id, message_table_item(
- pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
- (entry->Length - size_of_entry_headers) / 2))
- )));
-#endif
- }
- else
- {
- //If string is ANSI
- //Add ID and string to message table
- ret.insert(std::make_pair(curr_id, message_table_item(
- std::string(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers,
- entry->Length - size_of_entry_headers)
- )));
- }
-
- //Go to next entry
- current_pos += entry->Length;
- }
- }
-
- return ret;
-}
-
-//Returns message table data by ID and index in language directory (instead of language)
-const resource_message_list resource_message_list_reader::get_message_table_by_id(uint32_t id, uint32_t index) const
-{
- return parse_message_list(res_.get_resource_data_by_id(pe_resource_viewer::resource_message_table, id, index).get_data());
-}
-
-//Returns message table data by ID and language
-const resource_message_list resource_message_list_reader::get_message_table_by_id_lang(uint32_t language, uint32_t id) const
-{
- return parse_message_list(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_message_table, id).get_data());
-}
-}
diff --git a/tools/pe_bliss/resource_message_list_reader.h b/tools/pe_bliss/resource_message_list_reader.h
deleted file mode 100644
index a0ac96eb8c..0000000000
--- a/tools/pe_bliss/resource_message_list_reader.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "message_table.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-//ID; message_table_item
-typedef std::map<uint32_t, message_table_item> resource_message_list;
-
-class resource_message_list_reader
-{
-public:
- resource_message_list_reader(const pe_resource_viewer& res);
-
- //Returns message table data by ID and language
- const resource_message_list get_message_table_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns message table data by ID and index in language directory (instead of language)
- const resource_message_list get_message_table_by_id(uint32_t id, uint32_t index = 0) const;
-
- //Helper function of parsing message list table
- //resource_data - raw message table resource data
- static const resource_message_list parse_message_list(const std::string& resource_data);
-
-private:
- const pe_resource_viewer& res_;
-};
-}
diff --git a/tools/pe_bliss/resource_string_table_reader.cpp b/tools/pe_bliss/resource_string_table_reader.cpp
deleted file mode 100644
index 8a51720e6a..0000000000
--- a/tools/pe_bliss/resource_string_table_reader.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_string_table_reader.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-resource_string_table_reader::resource_string_table_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Returns string table data by ID and index in language directory (instead of language)
-const resource_string_list resource_string_table_reader::get_string_table_by_id(uint32_t id, uint32_t index) const
-{
- return parse_string_list(id, res_.get_resource_data_by_id(pe_resource_viewer::resource_string, id, index).get_data());
-}
-
-//Returns string table data by ID and language
-const resource_string_list resource_string_table_reader::get_string_table_by_id_lang(uint32_t language, uint32_t id) const
-{
- return parse_string_list(id, res_.get_resource_data_by_id(language, pe_resource_viewer::resource_string, id).get_data());
-}
-
-//Helper function of parsing string list table
-const resource_string_list resource_string_table_reader::parse_string_list(uint32_t id, const std::string& resource_data)
-{
- resource_string_list ret;
-
- //16 is maximum count of strings in a string table
- static const unsigned long max_string_list_entries = 16;
- unsigned long passed_bytes = 0;
- for(unsigned long i = 0; i != max_string_list_entries; ++i)
- {
- //Check resource data length
- if(resource_data.length() < sizeof(uint16_t) + passed_bytes)
- throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table);
-
- //Get string length - the first WORD
- uint16_t string_length = *reinterpret_cast<const uint16_t*>(resource_data.data() + passed_bytes);
- passed_bytes += sizeof(uint16_t); //WORD containing string length
-
- //Check resource data length again
- if(resource_data.length() < string_length + passed_bytes)
- throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table);
-
- if(string_length)
- {
- //Create and save string (UNICODE)
-#ifdef PE_BLISS_WINDOWS
- ret.insert(
- std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way
- std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + passed_bytes), string_length)));
-#else
- ret.insert(
- std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way
- pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + passed_bytes), string_length))));
-#endif
- }
-
- //Go to next string
- passed_bytes += string_length * 2;
- }
-
- return ret;
-}
-
-//Returns string from string table by ID and language
-const std::wstring resource_string_table_reader::get_string_by_id_lang(uint32_t language, uint16_t id) const
-{
- //List strings by string table id and language
- const resource_string_list strings(get_string_table_by_id_lang(language, (id >> 4) + 1));
- resource_string_list::const_iterator it = strings.find(id); //Find string by id
- if(it == strings.end())
- throw pe_exception("Resource string not found", pe_exception::resource_string_not_found);
-
- return (*it).second;
-}
-
-//Returns string from string table by ID and index in language directory (instead of language)
-const std::wstring resource_string_table_reader::get_string_by_id(uint16_t id, uint32_t index) const
-{
- //List strings by string table id and index
- const resource_string_list strings(get_string_table_by_id((id >> 4) + 1, index));
- resource_string_list::const_iterator it = strings.find(id); //Find string by id
- if(it == strings.end())
- throw pe_exception("Resource string not found", pe_exception::resource_string_not_found);
-
- return (*it).second;
-}
-}
diff --git a/tools/pe_bliss/resource_string_table_reader.h b/tools/pe_bliss/resource_string_table_reader.h
deleted file mode 100644
index e3ded1da85..0000000000
--- a/tools/pe_bliss/resource_string_table_reader.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-//ID; string
-typedef std::map<uint16_t, std::wstring> resource_string_list;
-
-class resource_string_table_reader
-{
-public:
- resource_string_table_reader(const pe_resource_viewer& res);
-
-public:
- //Returns string table data by ID and language
- const resource_string_list get_string_table_by_id_lang(uint32_t language, uint32_t id) const;
- //Returns string table data by ID and index in language directory (instead of language)
- const resource_string_list get_string_table_by_id(uint32_t id, uint32_t index = 0) const;
- //Returns string from string table by ID and language
- const std::wstring get_string_by_id_lang(uint32_t language, uint16_t id) const;
- //Returns string from string table by ID and index in language directory (instead of language)
- const std::wstring get_string_by_id(uint16_t id, uint32_t index = 0) const;
-
-private:
- const pe_resource_viewer& res_;
-
- //Helper function of parsing string list table
- //Id of resource is needed to calculate string IDs correctly
- //resource_data is raw string table resource data
- static const resource_string_list parse_string_list(uint32_t id, const std::string& resource_data);
-};
-}
diff --git a/tools/pe_bliss/resource_version_info_reader.cpp b/tools/pe_bliss/resource_version_info_reader.cpp
deleted file mode 100644
index 8ad44c6856..0000000000
--- a/tools/pe_bliss/resource_version_info_reader.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 "resource_version_info_reader.h"
-#include "utils.h"
-#include "pe_exception.h"
-#include "resource_internal.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Root version info block key value
-const u16string resource_version_info_reader::version_info_key(U16TEXT("V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0"));
-
-resource_version_info_reader::resource_version_info_reader(const pe_resource_viewer& res)
- :res_(res)
-{}
-
-//Returns aligned version block value position
-uint32_t resource_version_info_reader::get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key)
-{
- uint32_t string_length = static_cast<uint32_t>(u16string(key).length());
- uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */
- + base_pos
- + (string_length + 1 /* nullbyte */) * 2),
- sizeof(uint32_t));
-
- //Check possible overflows
- if(ret < base_pos || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2)
- throw_incorrect_version_info();
-
- return ret;
-}
-
-//Returns aligned version block first child position
-uint32_t resource_version_info_reader::get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key)
-{
- uint32_t string_length = static_cast<uint32_t>(u16string(key).length());
- uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */
- + base_pos
- + (string_length + 1 /* nullbyte */) * 2),
- sizeof(uint32_t))
- + pe_utils::align_up(value_length, sizeof(uint32_t));
-
- //Check possible overflows
- if(ret < base_pos || ret < value_length || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2)
- throw_incorrect_version_info();
-
- return ret;
-}
-
-//Throws an exception (id = resource_incorrect_version_info)
-void resource_version_info_reader::throw_incorrect_version_info()
-{
- throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info);
-}
-
-//Returns full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const
-{
- //Fixed file version info
- file_version_info ret;
-
- //Check resource data length
- if(resource_data.length() < sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Root version info block
- const version_info_block* root_block = reinterpret_cast<const version_info_block*>(resource_data.data());
-
- //Check root block key for null-termination and its name
- if(!pe_utils::is_null_terminated(root_block->Key, resource_data.length() - sizeof(uint16_t) * 3 /* headers before Key data */)
- || version_info_key != reinterpret_cast<const unicode16_t*>(root_block->Key))
- throw_incorrect_version_info();
-
- //If file has fixed version info
- if(root_block->ValueLength)
- {
- //Get root block value position
- uint32_t value_pos = get_version_block_value_pos(0, reinterpret_cast<const unicode16_t*>(root_block->Key));
- //Check value length
- if(resource_data.length() < value_pos + sizeof(vs_fixedfileinfo))
- throw_incorrect_version_info();
-
- //Get VS_FIXEDFILEINFO structure pointer
- const vs_fixedfileinfo* file_info = reinterpret_cast<const vs_fixedfileinfo*>(resource_data.data() + value_pos);
- //Check its signature and some other fields
- if(file_info->dwSignature != vs_ffi_signature || file_info->dwStrucVersion != vs_ffi_strucversion) //Don't check if file_info->dwFileFlagsMask == VS_FFI_FILEFLAGSMASK
- throw_incorrect_version_info();
-
- //Save fixed version info
- ret = file_version_info(*file_info);
- }
-
- //Iterate over child elements of VS_VERSIONINFO (StringFileInfo or VarFileInfo)
- for(uint32_t child_pos = get_version_block_first_child_pos(0, root_block->ValueLength, reinterpret_cast<const unicode16_t*>(root_block->Key));
- child_pos < root_block->Length;)
- {
- //Check block position
- if(!pe_utils::is_sum_safe(child_pos, sizeof(version_info_block))
- || resource_data.length() < child_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer
- const version_info_block* block = reinterpret_cast<const version_info_block*>(resource_data.data() + child_pos);
-
- //Check its length
- if(block->Length == 0)
- throw_incorrect_version_info();
-
- //Check block key for null-termination
- if(!pe_utils::is_null_terminated(block->Key, resource_data.length() - child_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- u16string info_type(reinterpret_cast<const unicode16_t*>(block->Key));
- //If we encountered StringFileInfo...
- if(info_type == StringFileInfo)
- {
- //Enumerate all string tables
- for(uint32_t string_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key));
- string_table_pos - child_pos < block->Length;)
- {
- //Check string table block position
- if(resource_data.length() < string_table_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer for string table
- const version_info_block* string_table = reinterpret_cast<const version_info_block*>(resource_data.data() + string_table_pos);
-
- //Check its length
- if(string_table->Length == 0)
- throw_incorrect_version_info();
-
- //Check string table key for null-termination
- if(!pe_utils::is_null_terminated(string_table->Key, resource_data.length() - string_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- string_values_map new_values;
-
- //Enumerate all strings in the string table
- for(uint32_t string_pos = get_version_block_first_child_pos(string_table_pos, string_table->ValueLength, reinterpret_cast<const unicode16_t*>(string_table->Key));
- string_pos - string_table_pos < string_table->Length;)
- {
- //Check string block position
- if(resource_data.length() < string_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer for string block
- const version_info_block* string_block = reinterpret_cast<const version_info_block*>(resource_data.data() + string_pos);
-
- //Check its length
- if(string_block->Length == 0)
- throw_incorrect_version_info();
-
- //Check string block key for null-termination
- if(!pe_utils::is_null_terminated(string_block->Key, resource_data.length() - string_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- u16string data;
- //If string block has value
- if(string_block->ValueLength != 0)
- {
- //Get value position
- uint32_t value_pos = get_version_block_value_pos(string_pos, reinterpret_cast<const unicode16_t*>(string_block->Key));
- //Check it
- if(resource_data.length() < value_pos + string_block->ValueLength)
- throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info);
-
- //Get UNICODE string value
- data = u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + value_pos), string_block->ValueLength);
- pe_utils::strip_nullbytes(data);
- }
-
- //Save name-value pair
-#ifdef PE_BLISS_WINDOWS
- new_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_block->Key), data));
-#else
- new_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_block->Key)),
- pe_utils::from_ucs2(data)));
-#endif
-
- //Navigate to next string block
- string_pos += pe_utils::align_up(string_block->Length, sizeof(uint32_t));
- }
-
-#ifdef PE_BLISS_WINDOWS
- string_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_table->Key), new_values));
-#else
- string_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_table->Key)), new_values));
-#endif
-
- //Navigate to next string table block
- string_table_pos += pe_utils::align_up(string_table->Length, sizeof(uint32_t));
- }
- }
- else if(info_type == VarFileInfo) //If we encountered VarFileInfo
- {
- for(uint32_t var_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key));
- var_table_pos - child_pos < block->Length;)
- {
- //Check var block position
- if(resource_data.length() < var_table_pos + sizeof(version_info_block))
- throw_incorrect_version_info();
-
- //Get VERSION_INFO_BLOCK structure pointer for var block
- const version_info_block* var_table = reinterpret_cast<const version_info_block*>(resource_data.data() + var_table_pos);
-
- //Check its length
- if(var_table->Length == 0)
- throw_incorrect_version_info();
-
- //Check its key for null-termination
- if(!pe_utils::is_null_terminated(var_table->Key, resource_data.length() - var_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
- throw_incorrect_version_info();
-
- //If block is "Translation" (actually, there's no other types possible in VarFileInfo) and it has value
- if(u16string(reinterpret_cast<const unicode16_t*>(var_table->Key)) == Translation && var_table->ValueLength)
- {
- //Get its value position
- uint32_t value_pos = get_version_block_value_pos(var_table_pos, reinterpret_cast<const unicode16_t*>(var_table->Key));
- //Cherck value length
- if(resource_data.length() < value_pos + var_table->ValueLength)
- throw_incorrect_version_info();
-
- //Get list of translations: pairs of LANGUAGE_ID - CODEPAGE_ID
- for(unsigned long i = 0; i < var_table->ValueLength; i += sizeof(uint16_t) * 2)
- {
- //Pair of WORDs
- uint16_t lang_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + i);
- uint16_t codepage_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + sizeof(uint16_t) + i);
- //Save translation
- translations.insert(std::make_pair(lang_id, codepage_id));
- }
- }
-
- //Navigate to next var block
- var_table_pos += pe_utils::align_up(var_table->Length, sizeof(uint32_t));
- }
- }
- else
- {
- throw_incorrect_version_info();
- }
-
- //Navigate to next element in root block
- child_pos += pe_utils::align_up(block->Length, sizeof(uint32_t));
- }
-
- return ret;
-}
-
-//Returns full version information:
-//file_version info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const
-{
- const std::string& resource_data = res_.get_root_directory() //Type directory
- .entry_by_id(pe_resource_viewer::resource_version)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(1)
- .get_resource_directory() //Language directory
- .entry_by_id(language)
- .get_data_entry() //Data directory
- .get_data();
-
- return get_version_info(string_values, translations, resource_data);
-}
-
-//Returns full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index) const
-{
- const resource_directory::entry_list& entries = res_.get_root_directory() //Type directory
- .entry_by_id(pe_resource_viewer::resource_version)
- .get_resource_directory() //Name/ID directory
- .entry_by_id(1)
- .get_resource_directory() //Language directory
- .get_entry_list();
-
- if(entries.size() <= index)
- throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
- return get_version_info(string_values, translations, entries.at(index).get_data_entry().get_data()); //Data directory
-}
-}
diff --git a/tools/pe_bliss/resource_version_info_reader.h b/tools/pe_bliss/resource_version_info_reader.h
deleted file mode 100644
index c1dfbffdc2..0000000000
--- a/tools/pe_bliss/resource_version_info_reader.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include "file_version_info.h"
-#include "pe_structures.h"
-#include "version_info_types.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_version_info_reader
-{
-public: //VERSION INFO
- resource_version_info_reader(const pe_resource_viewer& res);
-
- //Returns full version information:
- //file_version_info: versions and file info
- //lang_lang_string_values_map: map of version info strings with encodings with encodings
- //translation_values_map: map of translations
- const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index = 0) const;
- const file_version_info get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const;
-
-public:
- //L"VS_VERSION_INFO" key of root version info block
- static const u16string version_info_key;
-
-private:
- const pe_resource_viewer& res_;
-
- //VERSION INFO helpers
- //Returns aligned version block value position
- static uint32_t get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key);
-
- //Returns aligned version block first child position
- static uint32_t get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key);
-
- //Returns full version information:
- //file_version_info: versions and file info
- //lang_string_values_map: map of version info strings with encodings
- //translation_values_map: map of translations
- const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const;
-
- //Throws an exception (id = resource_incorrect_version_info)
- static void throw_incorrect_version_info();
-};
-}
diff --git a/tools/pe_bliss/resource_version_info_writer.cpp b/tools/pe_bliss/resource_version_info_writer.cpp
deleted file mode 100644
index ed95a0f7ea..0000000000
--- a/tools/pe_bliss/resource_version_info_writer.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "resource_version_info_writer.h"
-#include "pe_structures.h"
-#include "resource_internal.h"
-#include "utils.h"
-#include "pe_resource_manager.h"
-#include "resource_version_info_reader.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_version_info_writer::resource_version_info_writer(pe_resource_manager& res)
- :res_(res)
-{}
-
-//Sets/replaces full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-void resource_version_info_writer::set_version_info(const file_version_info& file_info,
- const lang_string_values_map& string_values,
- const translation_values_map& translations,
- uint32_t language,
- uint32_t codepage,
- uint32_t timestamp)
-{
- std::string version_data;
-
- //Calculate total size of version resource data
- uint32_t total_version_info_length =
- static_cast<uint32_t>(sizeof(version_info_block) - sizeof(uint16_t) + sizeof(uint16_t) /* pading */
- + (resource_version_info_reader::version_info_key.length() + 1) * 2
- + sizeof(vs_fixedfileinfo));
-
- //If we have any strings values
- if(!string_values.empty())
- {
- total_version_info_length += sizeof(version_info_block) - sizeof(uint16_t); //StringFileInfo block
- total_version_info_length += SizeofStringFileInfo; //Name of block (key)
-
- //Add required size for version strings
- for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it)
- {
- total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*table_it).first.length() + 1) * 2), sizeof(uint32_t)); //Name of child block and block size (key of string table block)
-
- const string_values_map& values = (*table_it).second;
- for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it)
- {
- total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*it).first.length() + 1) * 2), sizeof(uint32_t));
- total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(((*it).second.length() + 1) * 2), sizeof(uint32_t));
- }
- }
- }
-
- //If we have translations
- if(!translations.empty())
- {
- total_version_info_length += (sizeof(version_info_block) - sizeof(uint16_t)) * 2; //VarFileInfo and Translation blocks
- total_version_info_length += SizeofVarFileInfoAligned; //DWORD-aligned VarFileInfo block name
- total_version_info_length += SizeofTranslationAligned; //DWORD-aligned Translation block name
- total_version_info_length += static_cast<uint32_t>(translations.size() * sizeof(uint16_t) * 2);
- }
-
- //Resize version data buffer
- version_data.resize(total_version_info_length);
-
- //Create root version block
- version_info_block root_block = {0};
- root_block.ValueLength = sizeof(vs_fixedfileinfo);
- root_block.Length = static_cast<uint16_t>(total_version_info_length);
-
- //Fill fixed file info
- vs_fixedfileinfo fixed_info = {0};
- fixed_info.dwFileDateLS = file_info.get_file_date_ls();
- fixed_info.dwFileDateMS = file_info.get_file_date_ms();
- fixed_info.dwFileFlags = file_info.get_file_flags();
- fixed_info.dwFileFlagsMask = vs_ffi_fileflagsmask;
- fixed_info.dwFileOS = file_info.get_file_os_raw();
- fixed_info.dwFileSubtype = file_info.get_file_subtype();
- fixed_info.dwFileType = file_info.get_file_type_raw();
- fixed_info.dwFileVersionLS = file_info.get_file_version_ls();
- fixed_info.dwFileVersionMS = file_info.get_file_version_ms();
- fixed_info.dwSignature = vs_ffi_signature;
- fixed_info.dwStrucVersion = vs_ffi_strucversion;
- fixed_info.dwProductVersionLS = file_info.get_product_version_ls();
- fixed_info.dwProductVersionMS = file_info.get_product_version_ms();
-
- //Write root block and fixed file info to buffer
- uint32_t data_ptr = 0;
- memcpy(&version_data[data_ptr], &root_block, sizeof(version_info_block) - sizeof(uint16_t));
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
- memcpy(&version_data[data_ptr], resource_version_info_reader::version_info_key.c_str(), (resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t));
- data_ptr += static_cast<uint32_t>((resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t));
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- memcpy(&version_data[data_ptr], &fixed_info, sizeof(fixed_info));
- data_ptr += sizeof(fixed_info);
-
- //Write string values, if any
- if(!string_values.empty())
- {
- //Create string file info root block
- version_info_block string_file_info_block = {0};
- string_file_info_block.Type = 1; //Block type is string
- memcpy(&version_data[data_ptr], &string_file_info_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* string_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr1 = data_ptr; //Used to calculate string file info block length later
- memcpy(&version_data[data_ptr], StringFileInfo, SizeofStringFileInfo); //Write block name
- data_ptr += SizeofStringFileInfo;
-
- //Create string table root block (child of string file info)
- version_info_block string_table_block = {0};
- string_table_block.Type = 1; //Block type is string
-
- for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it)
- {
- const string_values_map& values = (*table_it).second;
-
- memcpy(&version_data[data_ptr], &string_table_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* string_table_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr2 = data_ptr; //Used to calculate string table block length later
- uint32_t lang_key_length = static_cast<uint32_t>(((*table_it).first.length() + 1) * sizeof(uint16_t));
-
-#ifdef PE_BLISS_WINDOWS
- memcpy(&version_data[data_ptr], (*table_it).first.c_str(), lang_key_length); //Write block key
-#else
- {
- u16string str(pe_utils::to_ucs2((*table_it).first));
- memcpy(&version_data[data_ptr], str.c_str(), lang_key_length); //Write block key
- }
-#endif
-
- data_ptr += lang_key_length;
- //Align key if necessary
- if((sizeof(uint16_t) * 3 + lang_key_length) % sizeof(uint32_t))
- {
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- }
-
- //Create string block (child of string table block)
- version_info_block string_block = {0};
- string_block.Type = 1; //Block type is string
- for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it)
- {
- //Calculate value length and key length of string block
- string_block.ValueLength = static_cast<uint16_t>((*it).second.length() + 1);
- uint32_t key_length = static_cast<uint32_t>(((*it).first.length() + 1) * sizeof(uint16_t));
- //Calculate length of block
- string_block.Length = static_cast<uint16_t>(pe_utils::align_up(sizeof(uint16_t) * 3 + key_length, sizeof(uint32_t)) + string_block.ValueLength * sizeof(uint16_t));
-
- //Write string block
- memcpy(&version_data[data_ptr], &string_block, sizeof(version_info_block) - sizeof(uint16_t));
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-#ifdef PE_BLISS_WINDOWS
- memcpy(&version_data[data_ptr], (*it).first.c_str(), key_length); //Write block key
-#else
- {
- u16string str(pe_utils::to_ucs2((*it).first));
- memcpy(&version_data[data_ptr], str.c_str(), key_length); //Write block key
- }
-#endif
-
- data_ptr += key_length;
- //Align key if necessary
- if((sizeof(uint16_t) * 3 + key_length) % sizeof(uint32_t))
- {
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- }
-
- //Write block data (value)
-#ifdef PE_BLISS_WINDOWS
- memcpy(&version_data[data_ptr], (*it).second.c_str(), string_block.ValueLength * sizeof(uint16_t));
-#else
- {
- u16string str(pe_utils::to_ucs2((*it).second));
- memcpy(&version_data[data_ptr], str.c_str(), string_block.ValueLength * sizeof(uint16_t));
- }
-#endif
-
- data_ptr += string_block.ValueLength * 2;
- //Align data if necessary
- if((string_block.ValueLength * 2) % sizeof(uint32_t))
- {
- memset(&version_data[data_ptr], 0, sizeof(uint16_t));
- data_ptr += sizeof(uint16_t);
- }
- }
-
- //Calculate string table and string file info blocks lengths
- string_table_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3);
- }
-
- string_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3);
- }
-
- //If we have transactions
- if(!translations.empty())
- {
- //Create root var file info block
- version_info_block var_file_info_block = {0};
- var_file_info_block.Type = 1; //Type of block is string
- //Write block header
- memcpy(&version_data[data_ptr], &var_file_info_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* var_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr1 = data_ptr; //Used to calculate var file info block length later
- memcpy(&version_data[data_ptr], VarFileInfoAligned, SizeofVarFileInfoAligned); //Write block key (aligned)
- data_ptr += SizeofVarFileInfoAligned;
-
- //Create root translation block (child of var file info block)
- version_info_block translation_block = {0};
- //Write block header
- memcpy(&version_data[data_ptr], &translation_block, sizeof(version_info_block) - sizeof(uint16_t));
- //We will calculate its length later
- version_info_block* translation_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
- data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
- uint32_t old_ptr2 = data_ptr; //Used to calculate var file info block length later
- memcpy(&version_data[data_ptr], TranslationAligned, SizeofTranslationAligned); //Write block key (aligned)
- data_ptr += SizeofTranslationAligned;
-
- //Calculate translation block value length
- translation_block_ptr->ValueLength = static_cast<uint16_t>(sizeof(uint16_t) * 2 * translations.size());
-
- //Write translation values to block
- for(translation_values_map::const_iterator it = translations.begin(); it != translations.end(); ++it)
- {
- uint16_t lang_id = (*it).first; //Language ID
- uint16_t codepage_id = (*it).second; //Codepage ID
- memcpy(&version_data[data_ptr], &lang_id, sizeof(lang_id));
- data_ptr += sizeof(lang_id);
- memcpy(&version_data[data_ptr], &codepage_id, sizeof(codepage_id));
- data_ptr += sizeof(codepage_id);
- }
-
- //Calculate Translation and VarFileInfo blocks lengths
- translation_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3);
- var_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3);
- }
-
- //Add/replace version info resource
- res_.add_resource(version_data, pe_resource_viewer::resource_version, 1, language, codepage, timestamp);
-}
-
-//Removes version info by language (ID = 1)
-bool resource_version_info_writer::remove_version_info(uint32_t language)
-{
- return res_.remove_resource(pe_resource_viewer::resource_version, 1, language);
-}
-}
diff --git a/tools/pe_bliss/resource_version_info_writer.h b/tools/pe_bliss/resource_version_info_writer.h
deleted file mode 100644
index da279ddedb..0000000000
--- a/tools/pe_bliss/resource_version_info_writer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "version_info_types.h"
-#include "file_version_info.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_version_info_writer
-{
-public:
- resource_version_info_writer(pe_resource_manager& res);
-
- //Sets/replaces full version information:
- //file_version_info: versions and file info
- //lang_string_values_map: map of version info strings with encodings
- //translation_values_map: map of translations
- void set_version_info(const file_version_info& file_info,
- const lang_string_values_map& string_values,
- const translation_values_map& translations,
- uint32_t language,
- uint32_t codepage = 0,
- uint32_t timestamp = 0);
-
- //Removes version info by language (ID = 1)
- bool remove_version_info(uint32_t language);
-
-private:
- pe_resource_manager& res_;
-};
-}
diff --git a/tools/pe_bliss/stdint_defs.h b/tools/pe_bliss/stdint_defs.h
deleted file mode 100644
index bbc003690a..0000000000
--- a/tools/pe_bliss/stdint_defs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#ifdef _MSC_VER
-#if _MSC_VER < 1600
-namespace pe_bliss
-{
- //stdint.h definitions for MSVC 2008 and earlier, as
- //it doesn't have them
- typedef signed 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;
-
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-}
-#else
-#include <stdint.h>
-#endif
-#else
-#include <stdint.h>
-#endif
diff --git a/tools/pe_bliss/utils.cpp b/tools/pe_bliss/utils.cpp
deleted file mode 100644
index e6a75d5497..0000000000
--- a/tools/pe_bliss/utils.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <string.h>
-#include "utils.h"
-#include "pe_exception.h"
-
-
-namespace pe_bliss
-{
-const double pe_utils::log_2 = 1.44269504088896340736; //instead of using M_LOG2E
-
-//Returns stream size
-std::streamoff pe_utils::get_file_size(std::istream& file)
-{
- //Get old istream offset
- std::streamoff old_offset = file.tellg();
- file.seekg(0, std::ios::end);
- std::streamoff filesize = file.tellg();
- //Set old istream offset
- file.seekg(old_offset);
- return filesize;
-}
-
-#ifndef PE_BLISS_WINDOWS
-const u16string pe_utils::to_ucs2(const std::wstring& str)
-{
- u16string ret;
- if(str.empty())
- return ret;
-
- int len = str.length();
-
- ret.resize(len);
-
- for(int i=0;i<len;i++) {
- ret[i]=str[i]&0xFFFF;
- }
-
- return ret;
-}
-
-const std::wstring pe_utils::from_ucs2(const u16string& str)
-{
- std::wstring ret;
- if(str.empty())
- return ret;
-
- int len = str.length();
- ret.resize(str.length());
-
- for(int i=0;i<len;i++) {
- ret[i]=str[i];
- }
-
- return ret;
-}
-#endif
-
-bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2)
-{
- return guid1.Data1 == guid2.Data1
- && guid1.Data2 == guid2.Data2
- && guid1.Data3 == guid2.Data3
- && !memcmp(guid1.Data4, guid2.Data4, sizeof(guid1.Data4));
-}
-}
diff --git a/tools/pe_bliss/utils.h b/tools/pe_bliss/utils.h
deleted file mode 100644
index 29125f8dc1..0000000000
--- a/tools/pe_bliss/utils.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include <string>
-#include "stdint_defs.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-class pe_utils
-{
-public:
- //Returns true if string "data" with maximum length "raw_length" is null-terminated
- template<typename T>
- static bool is_null_terminated(const T* data, size_t raw_length)
- {
- raw_length /= sizeof(T);
- for(size_t l = 0; l < raw_length; l++)
- {
- if(data[l] == static_cast<T>(L'\0'))
- return true;
- }
-
- return false;
- }
-
- //Helper template function to strip nullbytes in the end of string
- template<typename T>
- static void strip_nullbytes(std::basic_string<T>& str)
- {
- while(!*(str.end() - 1) && !str.empty())
- str.erase(str.length() - 1);
- }
-
- //Helper function to determine if number is power of 2
- template<typename T>
- static inline bool is_power_of_2(T x)
- {
- return !(x & (x - 1));
- }
-
- //Helper function to align number down
- template<typename T>
- static inline T align_down(T x, uint32_t align)
- {
- return x & ~(static_cast<T>(align) - 1);
- }
-
- //Helper function to align number up
- template<typename T>
- static inline T align_up(T x, uint32_t align)
- {
- return (x & static_cast<T>(align - 1)) ? align_down(x, align) + static_cast<T>(align) : x;
- }
-
- //Returns true if sum of two unsigned integers is safe (no overflow occurs)
- static inline bool is_sum_safe(uint32_t a, uint32_t b)
- {
- return a <= static_cast<uint32_t>(-1) - b;
- }
-
- //Two gigabytes value in bytes
- static const uint32_t two_gb = 0x80000000;
- static const uint32_t max_dword = 0xFFFFFFFF;
- static const uint32_t max_word = 0x0000FFFF;
- static const double log_2; //instead of using M_LOG2E
-
- //Returns stream size
- static std::streamoff get_file_size(std::istream& file);
-
-#ifndef PE_BLISS_WINDOWS
-public:
- static const u16string to_ucs2(const std::wstring& str);
- static const std::wstring from_ucs2(const u16string& str);
-#endif
-
-private:
- pe_utils();
- pe_utils(pe_utils&);
- pe_utils& operator=(const pe_utils&);
-};
-
-//Windows GUID comparison
-bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2);
-}
diff --git a/tools/pe_bliss/version_info_editor.cpp b/tools/pe_bliss/version_info_editor.cpp
deleted file mode 100644
index 199eebfd54..0000000000
--- a/tools/pe_bliss/version_info_editor.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <sstream>
-#include <iomanip>
-#include "version_info_types.h"
-#include "version_info_editor.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-//Default constructor
-//strings - version info strings with charsets
-//translations - version info translations map
-version_info_editor::version_info_editor(lang_string_values_map& strings, translation_values_map& translations)
- :version_info_viewer(strings, translations),
- strings_edit_(strings),
- translations_edit_(translations)
-{}
-
-//Below functions have parameter translation
-//If it's empty, the default language translation will be taken
-//If there's no default language translation, the first one will be taken
-
-//Sets company name
-void version_info_editor::set_company_name(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"CompanyName", value, translation);
-}
-
-//Sets file description
-void version_info_editor::set_file_description(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"FileDescription", value, translation);
-}
-
-//Sets file version
-void version_info_editor::set_file_version(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"FileVersion", value, translation);
-}
-
-//Sets internal file name
-void version_info_editor::set_internal_name(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"InternalName", value, translation);
-}
-
-//Sets legal copyright
-void version_info_editor::set_legal_copyright(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"LegalCopyright", value, translation);
-}
-
-//Sets original file name
-void version_info_editor::set_original_filename(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"OriginalFilename", value, translation);
-}
-
-//Sets product name
-void version_info_editor::set_product_name(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"ProductName", value, translation);
-}
-
-//Sets product version
-void version_info_editor::set_product_version(const std::wstring& value, const std::wstring& translation)
-{
- set_property(L"ProductVersion", value, translation);
-}
-
-//Sets version info property value
-//property_name - property name
-//value - property value
-//If translation does not exist, it will be added
-//If property does not exist, it will be added
-void version_info_editor::set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation)
-{
- lang_string_values_map::iterator it = strings_edit_.begin();
-
- if(translation.empty())
- {
- //If no translation was specified
- it = strings_edit_.find(default_language_translation); //Find default translation table
- if(it == strings_edit_.end()) //If there's no default translation table, take the first one
- {
- it = strings_edit_.begin();
- if(it == strings_edit_.end()) //If there's no any translation table, add default one
- {
- it = strings_edit_.insert(std::make_pair(default_language_translation, string_values_map())).first;
- //Also add it to translations list
- add_translation(default_language_translation);
- }
- }
- }
- else
- {
- it = strings_edit_.find(translation); //Find specified translation table
- if(it == strings_edit_.end()) //If there's no translation, add it
- {
- it = strings_edit_.insert(std::make_pair(translation, string_values_map())).first;
- //Also add it to translations list
- add_translation(translation);
- }
- }
-
- //Change value of the required property
- ((*it).second)[property_name] = value;
-}
-
-//Adds translation to translation list
-void version_info_editor::add_translation(const std::wstring& translation)
-{
- std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation));
- add_translation(translation_ids.first, translation_ids.second);
-}
-
-void version_info_editor::add_translation(uint16_t language_id, uint16_t codepage_id)
-{
- std::pair<translation_values_map::const_iterator, translation_values_map::const_iterator>
- range(translations_edit_.equal_range(language_id));
-
- //If translation already exists
- for(translation_values_map::const_iterator it = range.first; it != range.second; ++it)
- {
- if((*it).second == codepage_id)
- return;
- }
-
- translations_edit_.insert(std::make_pair(language_id, codepage_id));
-}
-
-//Removes translation from translations and strings lists
-void version_info_editor::remove_translation(const std::wstring& translation)
-{
- std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation));
- remove_translation(translation_ids.first, translation_ids.second);
-}
-
-void version_info_editor::remove_translation(uint16_t language_id, uint16_t codepage_id)
-{
- {
- //Erase string table (if exists)
- std::wstringstream ss;
- ss << std::hex
- << std::setw(4) << std::setfill(L'0') << language_id
- << std::setw(4) << std::setfill(L'0') << codepage_id;
-
- strings_edit_.erase(ss.str());
- }
-
- //Find and erase translation from translations table
- std::pair<translation_values_map::iterator, translation_values_map::iterator>
- it_pair = translations_edit_.equal_range(language_id);
-
- for(translation_values_map::iterator it = it_pair.first; it != it_pair.second; ++it)
- {
- if((*it).second == codepage_id)
- {
- translations_edit_.erase(it);
- break;
- }
- }
-}
-}
diff --git a/tools/pe_bliss/version_info_editor.h b/tools/pe_bliss/version_info_editor.h
deleted file mode 100644
index 53d3dc62c1..0000000000
--- a/tools/pe_bliss/version_info_editor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include "version_info_types.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
- //Helper class to read and edit version information
- //lang_string_values_map: map of version info strings with encodings
- //translation_values_map: map of translations
- class version_info_editor : public version_info_viewer
- {
- public:
- //Default constructor
- //strings - version info strings with charsets
- //translations - version info translations map
- version_info_editor(lang_string_values_map& strings, translation_values_map& translations);
-
- //Below functions have parameter translation
- //If it's empty, the default language translation will be taken
- //If there's no default language translation, the first one will be taken
-
- //Sets company name
- void set_company_name(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets file description
- void set_file_description(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets file version
- void set_file_version(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets internal file name
- void set_internal_name(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets legal copyright
- void set_legal_copyright(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets original file name
- void set_original_filename(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets product name
- void set_product_name(const std::wstring& value, const std::wstring& translation = std::wstring());
- //Sets product version
- void set_product_version(const std::wstring& value, const std::wstring& translation = std::wstring());
-
- //Sets version info property value
- //property_name - property name
- //value - property value
- //If translation does not exist, it will be added to strings and translations lists
- //If property does not exist, it will be added
- void set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation = std::wstring());
-
- //Adds translation to translation list
- void add_translation(const std::wstring& translation);
- void add_translation(uint16_t language_id, uint16_t codepage_id);
-
- //Removes translation from translations and strings lists
- void remove_translation(const std::wstring& translation);
- void remove_translation(uint16_t language_id, uint16_t codepage_id);
-
- private:
- lang_string_values_map& strings_edit_;
- translation_values_map& translations_edit_;
- };
-}
diff --git a/tools/pe_bliss/version_info_types.h b/tools/pe_bliss/version_info_types.h
deleted file mode 100644
index 6010c9691e..0000000000
--- a/tools/pe_bliss/version_info_types.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
- //Typedef for version info functions: Name - Value
- typedef std::map<std::wstring, std::wstring> string_values_map;
- //Typedef for version info functions: Language string - String Values Map
- //Language String consists of LangID and CharsetID
- //E.g. 041904b0 for Russian UNICODE, 040004b0 for Process Default Language UNICODE
- typedef std::map<std::wstring, string_values_map> lang_string_values_map;
-
- //Typedef for version info functions: Language - Character Set
- typedef std::multimap<uint16_t, uint16_t> translation_values_map;
-}
diff --git a/tools/pe_bliss/version_info_viewer.cpp b/tools/pe_bliss/version_info_viewer.cpp
deleted file mode 100644
index 6e2d0d5c5b..0000000000
--- a/tools/pe_bliss/version_info_viewer.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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 <iomanip>
-#include <sstream>
-#include "pe_exception.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-//Default process language, UNICODE
-const std::wstring version_info_viewer::default_language_translation(L"040904b0");
-
-//Default constructor
-//strings - version info strings with charsets
-//translations - version info translations map
-version_info_viewer::version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations)
- :strings_(strings), translations_(translations)
-{}
-
-//Below functions have parameter translation
-//If it's empty, the default language translation will be taken
-//If there's no default language translation, the first one will be taken
-
-//Returns company name
-const std::wstring version_info_viewer::get_company_name(const std::wstring& translation) const
-{
- return get_property(L"CompanyName", translation);
-}
-
-//Returns file description
-const std::wstring version_info_viewer::get_file_description(const std::wstring& translation) const
-{
- return get_property(L"FileDescription", translation);
-}
-
-//Returns file version
-const std::wstring version_info_viewer::get_file_version(const std::wstring& translation) const
-{
- return get_property(L"FileVersion", translation);
-}
-
-//Returns internal file name
-const std::wstring version_info_viewer::get_internal_name(const std::wstring& translation) const
-{
- return get_property(L"InternalName", translation);
-}
-
-//Returns legal copyright
-const std::wstring version_info_viewer::get_legal_copyright(const std::wstring& translation) const
-{
- return get_property(L"LegalCopyright", translation);
-}
-
-//Returns original file name
-const std::wstring version_info_viewer::get_original_filename(const std::wstring& translation) const
-{
- return get_property(L"OriginalFilename", translation);
-}
-
-//Returns product name
-const std::wstring version_info_viewer::get_product_name(const std::wstring& translation) const
-{
- return get_property(L"ProductName", translation);
-}
-
-//Returns product version
-const std::wstring version_info_viewer::get_product_version(const std::wstring& translation) const
-{
- return get_property(L"ProductVersion", translation);
-}
-
-//Returns list of translations in string representation
-const version_info_viewer::translation_list version_info_viewer::get_translation_list() const
-{
- translation_list ret;
-
- //Enumerate all translations
- for(translation_values_map::const_iterator it = translations_.begin(); it != translations_.end(); ++it)
- {
- //Create string representation of translation value
- std::wstringstream ss;
- ss << std::hex
- << std::setw(4) << std::setfill(L'0') << (*it).first
- << std::setw(4) << std::setfill(L'0') << (*it).second;
-
- //Save it
- ret.push_back(ss.str());
- }
-
- return ret;
-}
-
-//Returns version info property value
-//property_name - required property name
-//If throw_if_absent = true, will throw exception if property does not exist
-//If throw_if_absent = false, will return empty string if property does not exist
-const std::wstring version_info_viewer::get_property(const std::wstring& property_name, const std::wstring& translation, bool throw_if_absent) const
-{
- std::wstring ret;
-
- //If there're no strings
- if(strings_.empty())
- {
- if(throw_if_absent)
- throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
- return ret;
- }
-
- lang_string_values_map::const_iterator it = strings_.begin();
-
- if(translation.empty())
- {
- //If no translation was specified
- it = strings_.find(default_language_translation); //Find default translation table
- if(it == strings_.end()) //If there's no default translation table, take the first one
- it = strings_.begin();
- }
- else
- {
- it = strings_.find(translation); //Find specified translation table
- if(it == strings_.end())
- {
- if(throw_if_absent)
- throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
- return ret;
- }
- }
-
- //Find value of the required property
- string_values_map::const_iterator str_it = (*it).second.find(property_name);
-
- if(str_it == (*it).second.end())
- {
- if(throw_if_absent)
- throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
- return ret;
- }
-
- ret = (*str_it).second;
-
- return ret;
-}
-
-//Converts translation HEX-string to pair of language ID and codepage ID
-const version_info_viewer::translation_pair version_info_viewer::translation_from_string(const std::wstring& translation)
-{
- uint32_t translation_id = 0;
-
- {
- //Convert string to DWORD
- std::wstringstream ss;
- ss << std::hex << translation;
- ss >> translation_id;
- }
-
- return std::make_pair(static_cast<uint16_t>(translation_id >> 16), static_cast<uint16_t>(translation_id & 0xFFFF));
-}
-}
diff --git a/tools/pe_bliss/version_info_viewer.h b/tools/pe_bliss/version_info_viewer.h
deleted file mode 100644
index bc2f6f2ba7..0000000000
--- a/tools/pe_bliss/version_info_viewer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru */
-/* */
-/* 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. */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <vector>
-#include <string>
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-#include "version_info_types.h"
-
-namespace pe_bliss
-{
-//Helper class to read version information
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-class version_info_viewer
-{
-public:
- //Useful typedefs
- typedef std::pair<uint16_t, uint16_t> translation_pair;
- typedef std::vector<std::wstring> translation_list;
-
-public:
- //Default constructor
- //strings - version info strings with charsets
- //translations - version info translations map
- version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations);
-
- //Below functions have parameter translation
- //If it's empty, the default language translation will be taken
- //If there's no default language translation, the first one will be taken
-
- //Returns company name
- const std::wstring get_company_name(const std::wstring& translation = std::wstring()) const;
- //Returns file description
- const std::wstring get_file_description(const std::wstring& translation = std::wstring()) const;
- //Returns file version
- const std::wstring get_file_version(const std::wstring& translation = std::wstring()) const;
- //Returns internal file name
- const std::wstring get_internal_name(const std::wstring& translation = std::wstring()) const;
- //Returns legal copyright
- const std::wstring get_legal_copyright(const std::wstring& translation = std::wstring()) const;
- //Returns original file name
- const std::wstring get_original_filename(const std::wstring& translation = std::wstring()) const;
- //Returns product name
- const std::wstring get_product_name(const std::wstring& translation = std::wstring()) const;
- //Returns product version
- const std::wstring get_product_version(const std::wstring& translation = std::wstring()) const;
-
- //Returns list of translations in string representation
- const translation_list get_translation_list() const;
-
- //Returns version info property value
- //property_name - required property name
- //If throw_if_absent = true, will throw exception if property does not exist
- //If throw_if_absent = false, will return empty string if property does not exist
- const std::wstring get_property(const std::wstring& property_name, const std::wstring& translation = std::wstring(), bool throw_if_absent = false) const;
-
- //Converts translation HEX-string to pair of language ID and codepage ID
- static const translation_pair translation_from_string(const std::wstring& translation);
-
-public:
- //Default process language, UNICODE
- static const std::wstring default_language_translation;
-
-private:
- const lang_string_values_map& strings_;
- const translation_values_map& translations_;
-};
-}
diff --git a/tools/scripts/sort-demos.sh b/tools/scripts/sort-demos.sh
new file mode 100644
index 0000000000..d4770b337e
--- /dev/null
+++ b/tools/scripts/sort-demos.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# When scanning for demos, the project manager sorts them based on their
+# timestamp, i.e. last modification date. This can make for a pretty
+# messy output, so this script 'touches' each engine.cfg file in reverse
+# alphabetical order to ensure a nice listing.
+#
+# It's good practice to run it once before packaging demos on the build
+# server.
+
+if [ ! -d "demos" ]; then
+ echo "Run this script from the root directory where 'demos/' is contained."
+ exit 1
+fi
+
+if [ -e demos.list ]; then
+ rm -f demos.list
+fi
+
+for dir in 2d 3d gui misc viewport; do
+ find "demos/$dir" -name "engine.cfg" |sort >> demos.list
+done
+cat demos.list |sort -r > demos_r.list
+
+while read line; do
+ touch $line
+ sleep 0.2
+done < demos_r.list
+
+#rm -f demos.list demos_r.list
diff --git a/tools/steam/make_icons.sh b/tools/steam/make_icons.sh
new file mode 100644
index 0000000000..71037cd1c3
--- /dev/null
+++ b/tools/steam/make_icons.sh
@@ -0,0 +1,5 @@
+convert -resize 32x32 ../../icon.svg icon32.ico
+convert -resize 32x32 ../../icon.svg icon32.icns
+for s in 16 24 32 64 96 128 256; do convert -resize ${s}x$s ../../icon.svg icon$s.png; done
+zip icons.zip icon*.png
+rm icon*.png
diff --git a/version.py b/version.py
index 6f666f0df9..86e28ec51d 100644
--- a/version.py
+++ b/version.py
@@ -2,7 +2,7 @@ short_name="godot"
name="Godot Engine"
major=2
minor=0
-status="beta"
+status="stable"