From 11ee2c794999a9477316c715a9e41c172598f874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Wed, 24 May 2023 00:27:34 +0300 Subject: [PATCH] initial commit --- .gitattributes | 2 + .gitignore | 2 + .../actions/action_delete_selected_blocks.gd | 46 + .../action_duplicate_selected_blocks.gd | 45 + .../actions/action_merge_selected_blocks.gd | 45 + .../actions/action_mirror_selection_x.gd | 30 + .../actions/action_mirror_selection_y.gd | 30 + .../actions/action_mirror_selection_z.gd | 30 + .../actions/action_rotate_selection.gd | 55 ++ .../actions/action_rotate_x_180.gd | 31 + .../actions/action_rotate_x_90_ccw.gd | 31 + .../actions/action_rotate_x_90_cw.gd | 31 + .../actions/action_rotate_y_180.gd | 31 + .../actions/action_rotate_y_90_ccw.gd | 31 + .../actions/action_rotate_y_90_cw.gd | 31 + .../actions/action_rotate_z_180.gd | 31 + .../actions/action_rotate_z_90_ccw.gd | 31 + .../actions/action_rotate_z_90_cw.gd | 31 + .../actions/action_scale_selection.gd | 54 + .../actions/action_snap_to_grid.gd | 52 + .../actions/action_tool_duplicate.gd | 33 + .../actions/cyclops_action.gd | 54 + .../art/cyclops.aseprite | Bin 0 -> 1260 bytes addons/cyclops_level_builder/art/cyclops.svg | 142 +++ .../art/cyclops.svg.import | 37 + addons/cyclops_level_builder/art/cyclops1.png | Bin 0 -> 369 bytes .../art/cyclops1.png.import | 34 + addons/cyclops_level_builder/art/cyclops2.png | Bin 0 -> 433 bytes .../art/cyclops2.png.import | 34 + .../art/cyclops_16.aseprite | Bin 0 -> 983 bytes .../cyclops_level_builder/art/cyclops_16.png | Bin 0 -> 258 bytes .../art/cyclops_16.png.import | 34 + .../cyclops_level_builder/art/cyclops_17.png | Bin 0 -> 272 bytes .../art/cyclops_17.png.import | 34 + .../art/cyclops_3.aseprite | Bin 0 -> 1489 bytes .../cyclops_level_builder/art/cyclops_3.png | Bin 0 -> 588 bytes .../art/cyclops_3.png.import | 34 + .../cyclops_level_builder/art/cyclops_4.png | Bin 0 -> 643 bytes .../art/cyclops_4.png.import | 34 + .../art/cyclops_closed.png | Bin 0 -> 1151 bytes .../art/cyclops_closed.png.import | 34 + .../art/cyclops_open.png | Bin 0 -> 1250 bytes .../art/cyclops_open.png.import | 34 + .../art/materialTest.blend | Bin 0 -> 893864 bytes .../art/materialTest.blend.import | 48 + .../art/materialTest.blend1 | Bin 0 -> 893864 bytes .../art/materialTest.glb | Bin 0 -> 3668 bytes .../art/materialTest.glb.import | 32 + .../art/textures/checkerboard.aseprite | Bin 0 -> 990 bytes .../art/textures/checkerboard.png | Bin 0 -> 405 bytes .../art/textures/checkerboard.png.import | 35 + .../art/textures/grid_cell.aseprite | Bin 0 -> 1012 bytes .../art/textures/grid_cell.png | Bin 0 -> 411 bytes .../art/textures/grid_cell.png.import | 35 + .../art/textures/grid_cell2.aseprite | Bin 0 -> 856 bytes .../art/textures/grid_cell2.png | Bin 0 -> 416 bytes .../art/textures/grid_cell2.png.import | 34 + .../commands/cmd_add_block.gd | 69 ++ .../commands/cmd_add_cylinder.gd | 102 ++ .../commands/cmd_add_prism.gd | 69 ++ .../commands/cmd_add_stairs.gd | 150 +++ .../commands/cmd_add_vertices.gd | 73 ++ .../commands/cmd_clip_block.gd | 102 ++ .../commands/cmd_delete_blocks.gd | 93 ++ .../commands/cmd_duplicate_blocks.gd | 87 ++ .../commands/cmd_merge_blocks.gd | 149 +++ .../commands/cmd_move_blocks.gd | 64 ++ .../commands/cmd_move_edges.gd | 132 +++ .../commands/cmd_move_face_planar.gd | 104 ++ .../commands/cmd_move_faces.gd | 131 +++ .../commands/cmd_move_vertices.gd | 105 ++ .../commands/cmd_select_blocks.gd | 135 +++ .../commands/cmd_select_edges.gd | 189 ++++ .../commands/cmd_select_faces.gd | 180 ++++ .../commands/cmd_select_vertices.gd | 167 ++++ .../commands/cmd_set_material.gd | 153 +++ .../commands/cmd_set_uv_transform.gd | 110 +++ .../commands/cmd_snap_to_grid.gd | 82 ++ .../commands/cmd_transform_blocks.gd | 76 ++ .../commands/cyclops_command.gd | 43 + .../controls/numeric_line_edit.gd | 125 +++ .../controls/numeric_line_edit.tscn | 26 + .../resource_inspector/line_editor_bool.gd | 66 ++ .../resource_inspector/line_editor_bool.tscn | 10 + .../resource_inspector/line_editor_float.gd | 65 ++ .../resource_inspector/line_editor_float.tscn | 11 + .../resource_inspector/line_editor_int.gd | 71 ++ .../resource_inspector/line_editor_int.tscn | 10 + .../resource_inspector/resource_inspector.gd | 86 ++ .../resource_inspector.tscn | 18 + .../cyclops_global_scene.gd | 250 +++++ .../cyclops_global_scene.tscn | 17 + .../cyclops_level_builder.gd | 225 +++++ addons/cyclops_level_builder/doc/Text | 54 + .../doc/create_plane_objects.py | 34 + .../cyclops_level_builder/doc/draw_plane.py | 35 + .../doc/draw_points_in_blender.py | 19 + .../doc/make_polygons.py | 36 + .../commands/cmd_mat_dock_add_materials.gd | 56 ++ .../commands/cmd_mat_dock_remove_materials.gd | 52 + .../material_palette_viewport.gd | 191 ++++ .../material_palette_viewport.tscn | 60 ++ .../material_palette/material_snapshot.gd | 52 + .../material_palette/material_snapshot.tscn | 30 + .../material_palette/material_thumbnail.gd | 166 ++++ .../material_palette/material_thumbnail.tscn | 43 + .../docks/material_palette/thumbnail_group.gd | 40 + .../thumbnail_normal_theme.tres | 17 + .../thumbnail_selected_theme.tres | 16 + .../tool_properties/tool_properties_dock.gd | 56 ++ .../tool_properties/tool_properties_dock.tscn | 20 + .../docks/uv_editor/uv_editor_preview.gd | 79 ++ .../docks/uv_editor/uv_editor_preview.tscn | 15 + .../uv_editor/uv_editor_preview_studio.gd | 67 ++ .../uv_editor/uv_editor_preview_studio.tscn | 18 + .../docks/uv_editor/uv_editor_viewport.gd | 182 ++++ .../docks/uv_editor/uv_editor_viewport.tscn | 143 +++ .../handles/handle_edge.gd | 40 + .../handles/handle_face.gd | 37 + .../handles/handle_vertex.gd | 36 + .../cyclops_level_builder/materials/grid.tres | 10 + .../materials/outline_material.tres | 8 + .../tool_edit_active_fill_material.tres | 9 + .../materials/tool_edit_active_material.tres | 8 + .../tool_edit_selected_fill_material.tres | 9 + .../tool_edit_selected_material.tres | 9 + .../tool_edit_unselected_material.tres | 8 + .../materials/tool_material.tres | 9 + .../tool_object_active_material.tres | 10 + .../tool_object_selected_material.tres | 10 + .../math/convex_volume.gd | 928 ++++++++++++++++++ .../cyclops_level_builder/math/face_packer.gd | 253 +++++ .../math/general_mesh.gd | 447 +++++++++ .../math/geometry_mesh.gd | 63 ++ .../math/math_geometry.gd | 166 ++++ .../cyclops_level_builder/math/math_util.gd | 537 ++++++++++ .../cyclops_level_builder/math/quick_hull.gd | 360 +++++++ .../menu/action_popup_menu.gd | 46 + .../menu/editor_toolbar.gd | 166 ++++ .../menu/editor_toolbar.tscn | 217 ++++ .../menu/sticky_toolbar.gd | 41 + .../menu/sticky_toolbar.tscn | 41 + .../nodes/cyclops_blocks.gd | 143 +++ .../nodes/cyclops_blocks_icon.png | Bin 0 -> 631 bytes .../nodes/cyclops_blocks_icon.png.import | 34 + .../nodes/cyclops_blocks_icon.svg | 66 ++ .../nodes/cyclops_blocks_icon.svg.import | 37 + .../nodes/cyclops_convex_block.gd | 123 +++ .../nodes/cyclops_convex_block_body.gd | 141 +++ .../nodes/intersect_results.gd | 35 + addons/cyclops_level_builder/plugin.cfg | 7 + .../resources/block_data.gd | 32 + .../resources/convex_block_data.gd | 51 + .../shaders/outline_shader.tres | 65 ++ .../shaders/tool_outline_shader.tres | 38 + .../tools/cyclops_tool.gd | 105 ++ .../cyclops_level_builder/tools/tool_block.gd | 349 +++++++ .../cyclops_level_builder/tools/tool_clip.gd | 164 ++++ .../tools/tool_cylinder.gd | 239 +++++ .../tools/tool_cylinder_settings.gd | 30 + .../tools/tool_duplicate.gd | 136 +++ .../tools/tool_edit_base.gd | 82 ++ .../tools/tool_edit_edge.gd | 321 ++++++ .../tools/tool_edit_face.gd | 342 +++++++ .../tools/tool_edit_vertex.gd | 332 +++++++ .../cyclops_level_builder/tools/tool_prism.gd | 213 ++++ .../tools/tool_stairs.gd | 272 +++++ .../tools/tool_stairs_settings.gd | 31 + .../util/display_mode.gd | 28 + .../util/general_util.gd | 60 ++ .../cyclops_level_builder/util/selection.gd | 37 + icon.svg | 1 + icon.svg.import | 37 + project.godot | 15 + 174 files changed, 13452 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd create mode 100644 addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd create mode 100644 addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd create mode 100644 addons/cyclops_level_builder/actions/action_mirror_selection_x.gd create mode 100644 addons/cyclops_level_builder/actions/action_mirror_selection_y.gd create mode 100644 addons/cyclops_level_builder/actions/action_mirror_selection_z.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_selection.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_x_180.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_y_180.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_z_180.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd create mode 100644 addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd create mode 100644 addons/cyclops_level_builder/actions/action_scale_selection.gd create mode 100644 addons/cyclops_level_builder/actions/action_snap_to_grid.gd create mode 100644 addons/cyclops_level_builder/actions/action_tool_duplicate.gd create mode 100644 addons/cyclops_level_builder/actions/cyclops_action.gd create mode 100644 addons/cyclops_level_builder/art/cyclops.aseprite create mode 100644 addons/cyclops_level_builder/art/cyclops.svg create mode 100644 addons/cyclops_level_builder/art/cyclops.svg.import create mode 100644 addons/cyclops_level_builder/art/cyclops1.png create mode 100644 addons/cyclops_level_builder/art/cyclops1.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops2.png create mode 100644 addons/cyclops_level_builder/art/cyclops2.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops_16.aseprite create mode 100644 addons/cyclops_level_builder/art/cyclops_16.png create mode 100644 addons/cyclops_level_builder/art/cyclops_16.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops_17.png create mode 100644 addons/cyclops_level_builder/art/cyclops_17.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops_3.aseprite create mode 100644 addons/cyclops_level_builder/art/cyclops_3.png create mode 100644 addons/cyclops_level_builder/art/cyclops_3.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops_4.png create mode 100644 addons/cyclops_level_builder/art/cyclops_4.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops_closed.png create mode 100644 addons/cyclops_level_builder/art/cyclops_closed.png.import create mode 100644 addons/cyclops_level_builder/art/cyclops_open.png create mode 100644 addons/cyclops_level_builder/art/cyclops_open.png.import create mode 100644 addons/cyclops_level_builder/art/materialTest.blend create mode 100644 addons/cyclops_level_builder/art/materialTest.blend.import create mode 100644 addons/cyclops_level_builder/art/materialTest.blend1 create mode 100644 addons/cyclops_level_builder/art/materialTest.glb create mode 100644 addons/cyclops_level_builder/art/materialTest.glb.import create mode 100644 addons/cyclops_level_builder/art/textures/checkerboard.aseprite create mode 100644 addons/cyclops_level_builder/art/textures/checkerboard.png create mode 100644 addons/cyclops_level_builder/art/textures/checkerboard.png.import create mode 100644 addons/cyclops_level_builder/art/textures/grid_cell.aseprite create mode 100644 addons/cyclops_level_builder/art/textures/grid_cell.png create mode 100644 addons/cyclops_level_builder/art/textures/grid_cell.png.import create mode 100644 addons/cyclops_level_builder/art/textures/grid_cell2.aseprite create mode 100644 addons/cyclops_level_builder/art/textures/grid_cell2.png create mode 100644 addons/cyclops_level_builder/art/textures/grid_cell2.png.import create mode 100644 addons/cyclops_level_builder/commands/cmd_add_block.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_add_cylinder.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_add_prism.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_add_stairs.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_add_vertices.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_clip_block.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_delete_blocks.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_merge_blocks.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_move_blocks.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_move_edges.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_move_face_planar.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_move_faces.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_move_vertices.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_select_blocks.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_select_edges.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_select_faces.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_select_vertices.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_set_material.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd create mode 100644 addons/cyclops_level_builder/commands/cmd_transform_blocks.gd create mode 100644 addons/cyclops_level_builder/commands/cyclops_command.gd create mode 100644 addons/cyclops_level_builder/controls/numeric_line_edit.gd create mode 100644 addons/cyclops_level_builder/controls/numeric_line_edit.tscn create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd create mode 100644 addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn create mode 100644 addons/cyclops_level_builder/cyclops_global_scene.gd create mode 100644 addons/cyclops_level_builder/cyclops_global_scene.tscn create mode 100644 addons/cyclops_level_builder/cyclops_level_builder.gd create mode 100644 addons/cyclops_level_builder/doc/Text create mode 100644 addons/cyclops_level_builder/doc/create_plane_objects.py create mode 100644 addons/cyclops_level_builder/doc/draw_plane.py create mode 100644 addons/cyclops_level_builder/doc/draw_points_in_blender.py create mode 100644 addons/cyclops_level_builder/doc/make_polygons.py create mode 100644 addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd create mode 100644 addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd create mode 100644 addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd create mode 100644 addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn create mode 100644 addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd create mode 100644 addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn create mode 100644 addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd create mode 100644 addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn create mode 100644 addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd create mode 100644 addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres create mode 100644 addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres create mode 100644 addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd create mode 100644 addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn create mode 100644 addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd create mode 100644 addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn create mode 100644 addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd create mode 100644 addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn create mode 100644 addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd create mode 100644 addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn create mode 100644 addons/cyclops_level_builder/handles/handle_edge.gd create mode 100644 addons/cyclops_level_builder/handles/handle_face.gd create mode 100644 addons/cyclops_level_builder/handles/handle_vertex.gd create mode 100644 addons/cyclops_level_builder/materials/grid.tres create mode 100644 addons/cyclops_level_builder/materials/outline_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_edit_active_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_edit_selected_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_object_active_material.tres create mode 100644 addons/cyclops_level_builder/materials/tool_object_selected_material.tres create mode 100644 addons/cyclops_level_builder/math/convex_volume.gd create mode 100644 addons/cyclops_level_builder/math/face_packer.gd create mode 100644 addons/cyclops_level_builder/math/general_mesh.gd create mode 100644 addons/cyclops_level_builder/math/geometry_mesh.gd create mode 100644 addons/cyclops_level_builder/math/math_geometry.gd create mode 100644 addons/cyclops_level_builder/math/math_util.gd create mode 100644 addons/cyclops_level_builder/math/quick_hull.gd create mode 100644 addons/cyclops_level_builder/menu/action_popup_menu.gd create mode 100644 addons/cyclops_level_builder/menu/editor_toolbar.gd create mode 100644 addons/cyclops_level_builder/menu/editor_toolbar.tscn create mode 100644 addons/cyclops_level_builder/menu/sticky_toolbar.gd create mode 100644 addons/cyclops_level_builder/menu/sticky_toolbar.tscn create mode 100644 addons/cyclops_level_builder/nodes/cyclops_blocks.gd create mode 100644 addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png create mode 100644 addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png.import create mode 100644 addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg create mode 100644 addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import create mode 100644 addons/cyclops_level_builder/nodes/cyclops_convex_block.gd create mode 100644 addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd create mode 100644 addons/cyclops_level_builder/nodes/intersect_results.gd create mode 100644 addons/cyclops_level_builder/plugin.cfg create mode 100644 addons/cyclops_level_builder/resources/block_data.gd create mode 100644 addons/cyclops_level_builder/resources/convex_block_data.gd create mode 100644 addons/cyclops_level_builder/shaders/outline_shader.tres create mode 100644 addons/cyclops_level_builder/shaders/tool_outline_shader.tres create mode 100644 addons/cyclops_level_builder/tools/cyclops_tool.gd create mode 100644 addons/cyclops_level_builder/tools/tool_block.gd create mode 100644 addons/cyclops_level_builder/tools/tool_clip.gd create mode 100644 addons/cyclops_level_builder/tools/tool_cylinder.gd create mode 100644 addons/cyclops_level_builder/tools/tool_cylinder_settings.gd create mode 100644 addons/cyclops_level_builder/tools/tool_duplicate.gd create mode 100644 addons/cyclops_level_builder/tools/tool_edit_base.gd create mode 100644 addons/cyclops_level_builder/tools/tool_edit_edge.gd create mode 100644 addons/cyclops_level_builder/tools/tool_edit_face.gd create mode 100644 addons/cyclops_level_builder/tools/tool_edit_vertex.gd create mode 100644 addons/cyclops_level_builder/tools/tool_prism.gd create mode 100644 addons/cyclops_level_builder/tools/tool_stairs.gd create mode 100644 addons/cyclops_level_builder/tools/tool_stairs_settings.gd create mode 100644 addons/cyclops_level_builder/util/display_mode.gd create mode 100644 addons/cyclops_level_builder/util/general_util.gd create mode 100644 addons/cyclops_level_builder/util/selection.gd create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 project.godot diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd b/addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd new file mode 100644 index 0000000..66fb6a1 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_delete_selected_blocks.gd @@ -0,0 +1,46 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionDeleteSelectedBlocks +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Delete Selected Blocks") + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var cmd:CommandDeleteBlocks = CommandDeleteBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.block_paths.append(block.get_path()) + + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) + diff --git a/addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd b/addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd new file mode 100644 index 0000000..8faca53 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_duplicate_selected_blocks.gd @@ -0,0 +1,45 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionDuplicateSelectedBlocks +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Duplicate Selected Blocks") + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var cmd:CommandDuplicateBlocks = CommandDuplicateBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.blocks_to_duplicate.append(block.get_path()) + + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd b/addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd new file mode 100644 index 0000000..e46660d --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_merge_selected_blocks.gd @@ -0,0 +1,45 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionMergeSelectedBlocks +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Merge Selected Blocks") + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var cmd:CommandMergeBlocks = CommandMergeBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.block_paths.append(block.get_path()) + + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_mirror_selection_x.gd b/addons/cyclops_level_builder/actions/action_mirror_selection_x.gd new file mode 100644 index 0000000..5d94e1a --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_mirror_selection_x.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionMirrorSelectionX2 +extends ActionScaleSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Mirror Selection X") + scale = Vector3(-1, 1, 1) diff --git a/addons/cyclops_level_builder/actions/action_mirror_selection_y.gd b/addons/cyclops_level_builder/actions/action_mirror_selection_y.gd new file mode 100644 index 0000000..aa34414 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_mirror_selection_y.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionMirrorSelectionY2 +extends ActionScaleSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Mirror Selection Y") + scale = Vector3(1, -1, 1) diff --git a/addons/cyclops_level_builder/actions/action_mirror_selection_z.gd b/addons/cyclops_level_builder/actions/action_mirror_selection_z.gd new file mode 100644 index 0000000..2f919e6 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_mirror_selection_z.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionMirrorSelectionZ +extends ActionScaleSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Mirror Selection Z") + scale = Vector3(1, 1, -1) diff --git a/addons/cyclops_level_builder/actions/action_rotate_selection.gd b/addons/cyclops_level_builder/actions/action_rotate_selection.gd new file mode 100644 index 0000000..61b9ac5 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_selection.gd @@ -0,0 +1,55 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateSelection +extends CyclopsAction + +var rotation_axis:Vector3 = Vector3.ONE +var rotation_angle:float + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, name, accellerator) + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var pivot:Vector3 = calc_pivot_of_blocks(blocks) + + var cmd:CommandTransformBlocks = CommandTransformBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.add_block(block.get_path()) + + var xform:Transform3D = Transform3D.IDENTITY + xform = xform.translated_local(pivot) + xform = xform.rotated_local(rotation_axis, rotation_angle) + xform = xform.translated_local(-pivot) + cmd.transform = xform + #print("cform %s" % xform) + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_rotate_x_180.gd b/addons/cyclops_level_builder/actions/action_rotate_x_180.gd new file mode 100644 index 0000000..5f48b60 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_x_180.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateX180 +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 180 X") + rotation_axis = Vector3(1, 0, 0) + rotation_angle = deg_to_rad(180) diff --git a/addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd b/addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd new file mode 100644 index 0000000..9bec89a --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_x_90_ccw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateX90Ccw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Ccw X") + rotation_axis = Vector3(1, 0, 0) + rotation_angle = deg_to_rad(90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd b/addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd new file mode 100644 index 0000000..7fe123a --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_x_90_cw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateX90Cw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Cw X") + rotation_axis = Vector3(1, 0, 0) + rotation_angle = deg_to_rad(-90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_y_180.gd b/addons/cyclops_level_builder/actions/action_rotate_y_180.gd new file mode 100644 index 0000000..64f6fb9 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_y_180.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateY180 +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 180 Y") + rotation_axis = Vector3(0, 1, 0) + rotation_angle = deg_to_rad(180) diff --git a/addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd b/addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd new file mode 100644 index 0000000..5d736a4 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_y_90_ccw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateY90Ccw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Ccw Y") + rotation_axis = Vector3(0, 1, 0) + rotation_angle = deg_to_rad(90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd b/addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd new file mode 100644 index 0000000..ea29d28 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_y_90_cw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateY90Cw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Cw Y") + rotation_axis = Vector3(0, 1, 0) + rotation_angle = deg_to_rad(-90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_z_180.gd b/addons/cyclops_level_builder/actions/action_rotate_z_180.gd new file mode 100644 index 0000000..9884000 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_z_180.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateZ180 +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 180 Z") + rotation_axis = Vector3(0, 0, 1) + rotation_angle = deg_to_rad(180) diff --git a/addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd b/addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd new file mode 100644 index 0000000..5e26b48 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_z_90_ccw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateZ90Ccw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Ccw Z") + rotation_axis = Vector3(0, 0, 1) + rotation_angle = deg_to_rad(90) diff --git a/addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd b/addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd new file mode 100644 index 0000000..f8f4576 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_rotate_z_90_cw.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionRotateZ90Cw +extends ActionRotateSelection + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Rotate 90 Cw Z") + rotation_axis = Vector3(0, 0, 1) + rotation_angle = deg_to_rad(-90) diff --git a/addons/cyclops_level_builder/actions/action_scale_selection.gd b/addons/cyclops_level_builder/actions/action_scale_selection.gd new file mode 100644 index 0000000..3d78c41 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_scale_selection.gd @@ -0,0 +1,54 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionScaleSelection +extends CyclopsAction + +var scale:Vector3 = Vector3.ONE + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, name, accellerator) + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var pivot:Vector3 = calc_pivot_of_blocks(blocks) + + var cmd:CommandTransformBlocks = CommandTransformBlocks.new() + cmd.builder = plugin + + for block in blocks: + cmd.add_block(block.get_path()) + + var xform:Transform3D = Transform3D.IDENTITY + xform = xform.translated_local(pivot) + xform = xform.scaled_local(scale) + xform = xform.translated_local(-pivot) + cmd.transform = xform + #print("cform %s" % xform) + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) diff --git a/addons/cyclops_level_builder/actions/action_snap_to_grid.gd b/addons/cyclops_level_builder/actions/action_snap_to_grid.gd new file mode 100644 index 0000000..14c2502 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_snap_to_grid.gd @@ -0,0 +1,52 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionSnapToGrid +extends CyclopsAction + +func _init(plugin:CyclopsLevelBuilder): + super._init(plugin, "Snap to grid") + + +func _execute(): + var blocks:Array[CyclopsConvexBlock] = plugin.get_selected_blocks() + if blocks.is_empty(): + return + + var pivot:Vector3 = calc_pivot_of_blocks(blocks) + + var cmd:CommandSnapToGrid = CommandSnapToGrid.new() + cmd.builder = plugin + + for block in blocks: + cmd.add_block(block.get_path()) + + + cmd.grid_size = pow(2, plugin.get_global_scene().grid_size) + #print("cform %s" % xform) + + var undo:EditorUndoRedoManager = plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) + + diff --git a/addons/cyclops_level_builder/actions/action_tool_duplicate.gd b/addons/cyclops_level_builder/actions/action_tool_duplicate.gd new file mode 100644 index 0000000..9ec1a52 --- /dev/null +++ b/addons/cyclops_level_builder/actions/action_tool_duplicate.gd @@ -0,0 +1,33 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name ActionToolDuplicate +extends CyclopsAction + + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + super._init(plugin, "Duplicate Selected Blocks") + +func _execute(): + plugin.switch_to_tool(ToolDuplicate.new()) diff --git a/addons/cyclops_level_builder/actions/cyclops_action.gd b/addons/cyclops_level_builder/actions/cyclops_action.gd new file mode 100644 index 0000000..5e4870c --- /dev/null +++ b/addons/cyclops_level_builder/actions/cyclops_action.gd @@ -0,0 +1,54 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CyclopsAction +extends RefCounted + +var plugin:CyclopsLevelBuilder + +var name:String = "" +var accellerator:Key = KEY_NONE + +func _init(plugin:CyclopsLevelBuilder, name:String = "", accellerator:Key = KEY_NONE): + self.plugin = plugin + self.name= name + self.accellerator = accellerator + +func _execute(): + pass + +func calc_pivot_of_blocks(blocks:Array[CyclopsConvexBlock])->Vector3: +# var blocks_root:CyclopsBlocks = plugin.active_node + var grid_step_size:float = pow(2, plugin.get_global_scene().grid_size) + + var bounds:AABB = blocks[0].control_mesh.bounds + for idx in range(1, blocks.size()): + var block:CyclopsConvexBlock = blocks[idx] + bounds = bounds.merge(block.control_mesh.bounds) + + var center:Vector3 = bounds.get_center() + var pivot:Vector3 = MathUtil.snap_to_grid(center, grid_step_size) + + return pivot + diff --git a/addons/cyclops_level_builder/art/cyclops.aseprite b/addons/cyclops_level_builder/art/cyclops.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..8ed5171ed93bcb0c263c47a2e2f2932db68b58e1 GIT binary patch literal 1260 zcmcJNZ%i9y9LFCRT^%7HF`^8G6L4FNPUzfNDTQQc*aQ=Y+U=|i;TW~8!T{-Dmd%YZ zMgbXXSzAD4M$JN@h-gVy123?QWo3}4Kw+a(SO5!T9e-5*tbU6w+bds~_UL;s0kQOF` z@;yqhnac%j2N-bZqsw5G=2cLc9pRFq0WX4nDNN7=I)FahAr5OO!xyqJg(e&!2s^03 z3sNwGj@!lMf&~y&&mkFwHLMF{%xGy zPq0Z+TH)bbDl!TeEDAum@Y((@_m5LhKiloGi4Y&Ji;mP|4(GOmDNRjHzb&wx^Q+r^ z(Hsk3)IA=&7ED6$THl46z8_PMloYx6pIO*n*wVv1y;f;)-V5#Xo1)v)^`vp}!fMf( zvgn?TU&UK{OlC%?9UZ>eKInbBF1=PZ#R%`1qQ05lsyLzj(UCPVZ_yOcMv3~IN;3Ot z^BGy^$wEifJHskQUF)c{ih}2qk|TbcF14Ava5t6-AFPhyuVg+MZ!orc^UK4MD$Ad` zw_qLZeruVdr*G_EQ)%CBp?q$LUK{^hQ!3b;K#%1W55~3}mWA%VzOO9qR{>Xc{t6XV z9$3b294M0c^YgE$DncDW6|J1L>D@cCpWP)%ni|_)>DM!HXlv^bE9o)4S%KYHc6zS= z@9sVPkDI#lUpJNZEspSc+2jflU-d}Y?=Lwb{{D1we)v!4E&cNPb03IQy2^37{&*>G zafgw&c9s|O`?QudAGws4XFoa``$mPy$XKKP7+cCuS{~X)q1bazyLw{GhF+;#88v3*+ zb%_G;$`gUMW8Bmj%~fxEs9YFueJ_(EOz+g6wUwDK4i+W0)fFDPJkHsYdvNs49i7jN f@SV>E)d+s*`F3vheMNWhcXY4lJqPO&Z=?AyCW6Xt literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/cyclops.svg b/addons/cyclops_level_builder/art/cyclops.svg new file mode 100644 index 0000000..a2fc7e1 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/cyclops_level_builder/art/cyclops.svg.import b/addons/cyclops_level_builder/art/cyclops.svg.import new file mode 100644 index 0000000..fbb9647 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmbwskudf7ldr" +path="res://.godot/imported/cyclops.svg-62ab1cb5293c5a489284f34e0c642019.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops.svg" +dest_files=["res://.godot/imported/cyclops.svg-62ab1cb5293c5a489284f34e0c642019.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/cyclops_level_builder/art/cyclops1.png b/addons/cyclops_level_builder/art/cyclops1.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0202b9971ff60d253e6a26b9d43c80de2c3c6f GIT binary patch literal 369 zcmV-%0gnEOP)Px$D@jB_R9J=8S3wQ~AqbTH|An{M|4k27V->_j-KHc>x>T8A5ZQ+C&jug@h`$8S z<|aW41n?Dz$QA2yf_E7|R*FXY*3OXt5SbaDud;;@z|4Dzv>=&8{ZoEU;4P_r;2IGL zc$S2Ea+le+KuVX0U2x(sX)#4syR$D~f(ovCV5fBiPWG}CyOZRU`~|Qn!>|O->-|=Y zLZFq0h{6sr0CXg3EJ_X}PMYO#DkV#z0 zG3Y1!lI$MbR;sXv24b*>z^Zqu})j);=qvxhP>}DG{-Nli62sR>5TIu<2=- z7QQxOzg(~FGv)BeewW138SrKt6~8-kEw+`d_z!3nR9kOlKOKBRNi)_P;Jt4q6)xdS P00000NkvXXu0mjfv_6~O literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/cyclops1.png.import b/addons/cyclops_level_builder/art/cyclops1.png.import new file mode 100644 index 0000000..881ae35 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops1.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://l4qj0lbj3ioa" +path="res://.godot/imported/cyclops1.png-6f459321d21304ca30333893d06ffb09.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops1.png" +dest_files=["res://.godot/imported/cyclops1.png-6f459321d21304ca30333893d06ffb09.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops2.png b/addons/cyclops_level_builder/art/cyclops2.png new file mode 100644 index 0000000000000000000000000000000000000000..bebba7221bac5c244508fc959b17022d05533566 GIT binary patch literal 433 zcmV;i0Z#sjP)Px$Ye_^wR9J=8R#CEpFbD+aUGH7RyO68c`_YezgM^JS+V(wWI%7cDT?lE2{X`!OezA@C5?8OT;{sYZ?Tv6o0H0q4d$-M?zH>5z*IUZbYOaaxakxVkCUX)+=}< zbssn)k^%RUfIIgx`v?T4B%OkHY$lX5Wp%gu4J@g`&^d6YRRoU8UrHfnPJgA8CRkT% zdv?BG`w5_n69EZivya9w^K}uh@_>)36VQCE7$Tst6(N|aN2CxKszSs|33$+kk|qKF zttS)l*c>*aTY#BVm27l1v@eb{idzngdmLuw$($N8*fJ(QVp^R7!%t;)EUG*fBqF^oA1r*jWkAec1+9SoVQ*n+Oak%L3yvgnDU{XRnm=~b~>%?MkG*JPL zXq&*|tFfRiTg1?4fXjY&3IjBO4xkTrh{GDn@P#Z)p$SI_!VYTif)tFP!@4jGETDjV zgd-WT$V4F05aq)rQGD=ML4mlDh*X6tBPaVrR+=}SxfBk>?_ziGh%7ZfJ%szzjIw21Z zmOY(}?(oxdP2al%i`s~*O77tnrBCWG>~*)-lwHaV*IOIHrqvYzNdpJHKFJ=G7*1|h z-WO~fjScDv6k5Bq;o2!pSG#xl(4&Q$#^gBlz4Ce0LR0OPofRMWo@0f{l0fx)V~*DW zvA%8+X0tYq(@kqb3-4N`dsJ{5s6cG^=8)-%>J$jneD&#m>!xiKl-8 D&vi6Y literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/cyclops_16.png b/addons/cyclops_level_builder/art/cyclops_16.png new file mode 100644 index 0000000000000000000000000000000000000000..835067b19f4be9703f36b099a80b134fadc5c0ff GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|_ISEDhFJ72 zophJ?umVp@|Em0xPScG1cXiKfSohdN?)9%Ar8)Amwy7&BmbBY%XzcS4o3!-#%dY&d zHrwOAF8&+#eRILNN-;r(hTZ2?CI(f-9Mlty4PCkF&Wjn#c;f|sAG~5$6=|tUZ zyUg6j7Jbv54@O6x={an0;f!Bpzs*DbRSUP9v3jkN=S)}^V)?v5N2#E^gJW6ds^jMk zBI3)E?b*}BK7^DW&0D_lqbP%i?!Qes1>YO^63VaHJ!ZAPy?1hEojJ%K44$rjF6*2U FngE7^YJ30y literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/cyclops_16.png.import b/addons/cyclops_level_builder/art/cyclops_16.png.import new file mode 100644 index 0000000..0c2777f --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_16.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://df0a5uffpuqg3" +path="res://.godot/imported/cyclops_16.png-f07e4f06ecdf5a5bd3bf65311c5a89e7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_16.png" +dest_files=["res://.godot/imported/cyclops_16.png-f07e4f06ecdf5a5bd3bf65311c5a89e7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_17.png b/addons/cyclops_level_builder/art/cyclops_17.png new file mode 100644 index 0000000000000000000000000000000000000000..51d5ebcc834e359a03ab853febb95d5587eeb329 GIT binary patch literal 272 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 literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/cyclops_4.png.import b/addons/cyclops_level_builder/art/cyclops_4.png.import new file mode 100644 index 0000000..1bb0fc1 --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_4.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cg3yjatinkymb" +path="res://.godot/imported/cyclops_4.png-e03a17198c56b52428203cf1953feb8c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_4.png" +dest_files=["res://.godot/imported/cyclops_4.png-e03a17198c56b52428203cf1953feb8c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/cyclops_closed.png b/addons/cyclops_level_builder/art/cyclops_closed.png new file mode 100644 index 0000000000000000000000000000000000000000..84ea43f16ea099f793f13680346b63b1367051ae GIT binary patch literal 1151 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 M07*qoM6N<$g7^7k9RL6T literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/cyclops_open.png.import b/addons/cyclops_level_builder/art/cyclops_open.png.import new file mode 100644 index 0000000..a71ecaa --- /dev/null +++ b/addons/cyclops_level_builder/art/cyclops_open.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dv78ucvwmycdh" +path="res://.godot/imported/cyclops_open.png-44d55f3db65056f90cc00f3559bf1cb3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/cyclops_open.png" +dest_files=["res://.godot/imported/cyclops_open.png-44d55f3db65056f90cc00f3559bf1cb3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/cyclops_level_builder/art/materialTest.blend b/addons/cyclops_level_builder/art/materialTest.blend new file mode 100644 index 0000000000000000000000000000000000000000..40ac1bb64bca904d6ead2bb5c707b4fa3b3810d3 GIT binary patch literal 893864 zcmeEv31Ah~)&FFH41|!dL)e0{gjMzg0$E6ahebs|#FaG=6bP~?t_0WTf>;*}DlVWF zt5vZsXb})lUq9PwciP&oexKTpTCLXFmfF9a|2g-b-fh@m5=(`m#ojN<2dt}UaOk0c3SQaocp`SNnU*vMn%#2GV9 zl4$m=2DrBv2F{p$0+?gc=An5NaUQK&XLG1EB`KQ4J&|$-wj*%{9y{)Ig|# zPy?X`LJfo(2sIFDAk;vpflvdX20{&l8aNsn2|pQC2Zw&vA#Oa@t8PyIob(Zsb3>jq7%vV^!1pgbw2FMOF zU=KIYGa+oj;U6-bw!n5UH|?q9E=j#lNDz)vrQ0-XU67YG_@~9vr=xu%R`%ey=Z`=Z!=|lyAhwbFlQT3zP%>)+7|3FpKSy7xUl`TSyo1r+Vag3 z=)9FPIPF1f0zQKMg3A`z7l=P-KB3vA-=Jzvh^%s3^}5>+d%Mj$vDV`}+Yi7OIB7;% z?XSzSS~2#w*fzjvbqzMbF>HctAnqf`FQA|B+CkdXX4jn%pnQXs9F)=Lu{i$h>m7k{ zj;Cw%0l;3z+F$7T!1mWu`@fZNWc>Yt*g)JK#153tfGuFmApU@D!JO6no^Mb!Cq!1K zwC?wO9Dniqam*d~+if0g9Wm?xX=?w#|2D#(?Z7X1?ZV*~xUW#Y!O=IcPcSb?d+dY& z!ZRM&7FsHsh}#9sc{26;k$heEzz9Y@&xR!Az;mv{kgB={c0k%MPklZb~&rw!et=S(7WBOVP=(yRw zS=L0xA7efE@wiRYX!pPyZQdJeJLs^H@V}ezzlQ?HwSx_*wf}Du{*3)5u>n5!OT#`8!%oCE#Qg$n zf$Si4XiDi3R5@gIXrPo4)n=;c;h47R#kkTSKgH}&A__?TOi!Q4%_IKm#eXeu* z0o-%q&gX3CCihGpP+$G@ZrS5{r~gMAx7)Su&z(L3GIdR+3Nb%FH!0Ed%Ntk4i^-(9rixs*YB)eR_hx{e-tuq zNdHgz>XvUepWN)S&z#$g9KwrxRU4?p1a4f?$OJ#94Z_lXT4W*fMV z16`+B*@ChWIrp;(wu?>FAFw@;Eu@`&Vy^+#(41mh~3Wu+P^#RxyORA4Wi@upL?kN-%l8G zV65Zkg1;l(n(aV>(=R)g&vA0>@E8Ai{UG|{$%*2OOcmLpO;WQy-twtwrbZ@$H8HsRV5u zG2`zDyxzu*Jz;*c(;jR)$bcFX0~4S=5ww`-m?A+ODlpDNs)ZQg-7@GtH$%F2pnSecAB1;h$}x#oLL z_>b>5T(xB|nzJP6D z$D~KB9g`oip8eLt)-6k}vLd$@TOA&xapFT_0}m4Z&fu|!)@%n9T5U+&H2^JA%w9t? zb9cD?yxq^o{eZ&`#`Pa=W!^&g-$M9P;8>kA_HxaIKVQ3J%dX99={lcdMYrD-) zXqRWr?K#8RF#H;Y`*(`&wYC>k6aLkNzu18I0NB9Oj=lhXUi&cwhd@MplpEb;QNtn*7v7wv+iDWgEjr8DOUDF z9my65du0!72W%6zJy1XJIn8w?B?8{wIt9@$bKmQhMYr(gzZR74F{O|I&0rCa54Q!^d z0QCpX@qn^}Ei@j~<3hI`kRN~zOxb2VKjl&Ddo#CKm#(?U8nbDbmH7yjU)ciNL)-?w zq@5$uyt+$-^w_pTf9LA+VFQeNz}Ro_)V@~cZG^vXApNQ997_;8=(N6FeC!AO&&rNi zR}WlnZOPwYJv?@!^+>@T6uup|fop{Z)!7&@G zhsNBlY~bOsWCIl72jC01FL*587i_ZBm;n8Oj0x1(5aR;JxG>%)sBxh^HpIAq`vlm* z3#UG2?U??Ewf>UTR>__89QjCVi}n;txbK2#ZMox}Dm;Pso&O9IL=~Am?pvZ*2{)8faZuKHZ9*y4Kp97meEh?124% zpD$2-0*wjS7wA4g`vTh^@bdwM8g`)P3G_3qNiV==Y=nC&#QX*)b6Dh zwr!r3u;2gET+bri{vEzv;UC=hbNkO;-_gq2NNt~k!dv2v8tW{IIb=#Y^LA?gD)4h-Q&D(tDZN<+kZe?clv#tceu5!!oCe`z!huk zVFQSjEx;y}UBD)^J@mS{n>A%+v9)^K;{U21b<HvB@y9sNIp)VThiw$) zjI!Ep%(U9vL2aG_Vm@~VvIBLEV;ySPfYTl}YI{f>lv0$DlHOu;+fyP-dS7t=-6OC6 zP>m5)zfjW-oX-l6!XL!PiH`Asnm^)ahRs&>n41sI?>+n4+>DcR6BXO~)GNQukhk6A zKlb|+9C&-r#|<1#m^1#`1{nV~-`2s6KkR|9r~9x0XPilPk$DH<&N1Up_K9Lr{?R@^T5ETCJx5Xdk)Ox$MZaGQ_Dq{MdWgpU+l0RgHvVxtV7z?;+kz*+Hz->m z{ClPh48kNODLJWk%btCwca5yRe(;(%$QJ$`w*|*D1CJ3nP#^M9MW6HU8qsEOxG%Uz zsV$PzI&0rAZN8rP51%x^YI|p9JhY*6We0bX9R!3dx~>9a&*xqnkaQ-+DP5CuJVgym zW~X)RJh@ZhytVx=dXC19f9J8{eR;QhTG8i%`$x4sWnx-#^Jam}C-@Co(=)aP{%HFF zeE{##HROzbaqQU+82`3+>ClE^71$2$s%Z~#JAggF7Vc!b(0(DgQ&PvqK$Df4(Q0Vc zfboQRjlErumXB>rJ-#WPY_sD9@%i0)wte>h{pXxScxOpq-1*$bpU>lV;5rwZAiKzN z1;JiyAgOIq#y6#d6FDDV!y6y_bGvtr`{4(C;yz1zTJ7Ta6ZUrt{_&V>;cl`4S0L;; z%|797Z3k=voX)z7@K=HRh>S0jGLjPVJS;N06IM#G~Jd|f-*1*@}_@lo^ z?9=Y?oX{=W*=k2?tyN&`32$#uHo*9MLL0V$dkA~PUK{v!#$S#H-6cX9Y5&DT3e$RE z4(!=pI^Efx)>>=)+iwy(;CK_+frPe>n9tj8B3qEq2C>r))H$uy+?erUBIx#5uLI4g zv?ffyQtiK%wjRe_Xo^pweb(=3YccNL&`#Na!w&8xd!V54ciVt%3*-yP9@=c;nDD=) z)xl$3cZpEG)~V@3YxsV@F@VE1PVYRyTAX{1b>0PMSQ9QCWA(eem(^ht*}}bK3l!S9 zg2tZlM`+8o5D(-J?v=p)fX>+tGH+=0b|UEaSg!+pgFPdTzY}*)Uof%5SnK@mr(0|K zmRsuwtgx;fcnO7-)^!6{S=S9(WnERc)LL-XENjY&BI}fBf2;Go)HhU%EpS{-_{U?x zpRUERuO{p{h%K~UpZ>VSiBLXT^ScZ9b6a1SGfVmS%la<1*7mEgE>~fRvV$v>9oV)2 zdtkqy>_KcH?ir zt<`oj`2h+U%hI1n1pOZCb)b3tKb+HTsD``w8hQ20F(KZr=cVSU+}!wPfb`*6GX2{?l_-_N~Xd?h>JVUD7(9 zGCXs@f=I{lchBi@W~{RJ+`p|PJ78N_MYgcIuWb)(3zyQmeE0@!4@<1e#U8XxXj`c1 z8!&G0=_}Yj3|#poee1DzLWeOcI;FMml?b{$9_v8!0nIz7br^6;>)Z<_bsTrc1>L9Z zqjA9J@D0j8^kLsnu6zUh1KWbK2eO5l_CPk#pT`b*{Gj`ajgcgJvkz4(773@ z>1~fkeVqtprfY;ykj6+b`&T#$K|C&)62=ACzx^fAIDf{d9l9{(*eU|I#>P z6Ro$JM8DS_zLP&r4T$#sNg!AU*3Hoj3K7(8LJDc#nDX+~b%V=#$_}gjq&|OFpY9Q1=sDV%e zp$0+?gc>-}G|&|5a+^ZNiKh3kzM%#}4TKs9H4thb)Ig|#Py?X`LJfo(2sIFDAk;vp zflvdX20{&l8aUB45Y8>1=oS#xKh!{|flvdX20{&l8VEHIY9Q1=sDV%e$EF4*Pd#J8 zv{WkF_j;}^qo|q!|7cN8PR{7&#?Yh`I_D$$dEqlZpc_%6y^f!1qhfuR{$|l0TsemE z&kY+F@U?kkM$KO|Y~F&Q!{(QBIy^!Rgc>+;HE{N6hVd+Y#b>_UPWg>CFgx6Mx@Ls5a6GH<uFQIWr-JxH@|QB z>yyVB#ua7G{L4yamdvIL@Oy28{P>mH&quG;F$81$i1e%_<(EyJcX|0rTxeuGyFmNl z>XAB*jL>msiDScb+PtjnY4&50OLdHKt*&FPQI+~@{uH!kBmE0`Mb4O z{Oy3t4_>U(YbCCpru|~YD?_xu^~B!lbv~=B%a7u|8T&}}1FY{Hx`_Jq5Ph4ob$@Z_ z^-olNz=xRmOiDn033Vb;6-5HM(AQ$QUm^N~96NqjDFl3=17E)IL7vTb*u@7r@R`B~ zdEi@@=H>$(_znuLkZ1F`%LzL0Z5KYs10Q144|L#LD}0a#dc)9L&w~$i;Da4P9{AR! zx%of`KF~oP((7cWYtD~pa(zv4CDe= z$no-n9{jiux#0IJ|4t%?KU*pI!>>UO^alKZ1M~_yj@h<;Ppy?(UWX3U`=sfgx3Vl6 zx8C%w@-yZKos_?-7Cj-3{%o-JcW>+1DYv$B_$0QcRzwK-E2KW%jBNU+52o2p49IJ> z(8S*H$@9HicshfQ_exas@J@GHT@3znKz1DI$|TQDn@AcciO14c^Q~kfC54_JQd=6Y zH|wT?VX(e}4wefYdudn#kDys6&^^A3R6qQ3 z8;RecTsMBe3;3bzz*VQKbh|T*Vx9g>+8@&3@{iHaDHuPSMeUC;L+soBs?w6F)sRc5 zwf(VN9wBfW^d8JDW+Rd`h1o;5KQH}}rnm3c?JxI*`r#LQuyO4Vr`+1kQD?3X_c@S{KBpsTrM+kdJ_~txZQhkn)m*XhXG`>T*gVoM>KX~B zF0`#zm&D@$o9`$ZtF6y*$@S#Q`o^pcbk8JaPi^z&!v9k~AF+qM!O4i&{PyqH&*ryp zX`IbRde}aT$H}mnJ@vGCJvujxvu7AaJ{e48rheY)Mt%eKQ=iJ8J)>m#l4bK&FR5H^ z(Elbqs5@%(VZN!K8xiMA+d|wB!No%C{1GkIkwu4B4!5V-bP@Sx2k6uMP(R0%l`opN zX6b6Ln0luK>3Ep080ZU<~}DXEhf8(#mBkDpxI8y=3`fW602Qxv1D3=$1%(pe% z|I_Sd<(k#T;-+o;tZHX_bEv*vr=hD?==WFVL!Z>^8L%$=k#8XWpEoW3 zs8?P1qg=pWjsHj)sDBsfKfHRFzh=o&a`8h}l`kz{uzJq?%C%k%){#C^ei@aR|IqkE zw+*$QxhZRu7v)E3P_JX5{H>`_kqg;Ne7yCS5gF0}`ec{=s%~@SpxpdX# zt5%mUo3pZf(VP`4D_4}ST)m`x)tvI>tJbV6pR;5kU#r^*2V&&q&719m%LlsJ z%IBlwg>x3KtX#7K((51R{!5n+F*t+D2fEtIH*3novqzN8Ib-G=hZQ%nd?-&{G4u!A zYb#$<;v4%y>kl!?8KghZ)mFZy#Mk_*v;&FjDj(=;E8o$;7vty1IgK4Zokqi^r960U z^20e^X{hk1ymv#qR{BrG4Uq?%L(IHLFCihJfUu%@zC+M+ASw9`br6x$WYp3xDJrgn#r0O^ZM3RTus! zmlyxYg^k63#)6egR;Z`vrhIm0J*Pw2jfi6h^z$>~&VoPUMu;?=_E;DG$TtxGolT2B z>Qxv1D3=$1bAIFTU$gYF3T^$4By`@uuL9c&FfxnB_P0aL(t}g+KBQ!ry$pY4JzB z>cSu8s)2u@UI*6j`IDLDYgf~gTh6q3OO`i&9@q~He%@^Cv3HXrD~cW|)QC*;|Dv&dcBe4qp0cHx6O@Kt6opAj!7=)kvD_#h8_ zhVgCHq)C9)B6LjF~EPRj$KEoJ7Ty{A@2fjmM?~n(+uIbEY=Lb6Q z?G!%91K(TC^hzz%4|L#*3LoUze5GpG3_j3-Z?^D39{4^@aqAOw-~%1xA^mBJZJ)Vx zF<0bc{pR6;?)C?JJ1q7GIb2@m2R-;>!VkHyyXpXb(1X8P_#qeehjMuH2R-;JgdcLj zk8*hVK@a|X;fLIVVqZb!2R-;r;fGxC9}cL0oL>5sg9D_!iX8Bx9^UeU9{FzFKo9<0;fGwb|DgJV9{h); z|A$=g14nQEpa*|U_#qd5Daign5B_T5hg|Rn*&pb^A0NM<9^&6n4{!NF4}RQ_%awNH zXMenw5aT4QB{XH+1UbOn6gdaQp1l5`8%^d_(gS^aVmym_*i;HLlP9EdA69b}5{*au z4ASe>C62x&>(^sGYspcVT4J_mwKiSkV4Yy>hko*wmTFP&l<2ranLAxeMs#b2OcZrt zvZ@Tz>syWSpL_i^p&1ek^*xuRlXB!7zi4cs zzz4=NSdW49+xoWWug32_@~`~umSMD_{&8mVJ1PYGSEv2=^~LWUPdx`f(I?w5 zhj*kLOm~MP-IwV2KF|H|f&CEr>ZD;lt>^7InL@OtIZoGy(%grbmoIgtqmSG4>VA@& zKKdIsy_xC0Z@#3{Tu$z9(7&L+iC!u5*z#P4=U_aK;`!41d`O~~{35$${3G_E zb+w>W$4!7=6=P5MA+CWRf9qX;{4&V){rVe?Un|$RklSyf9B6;Q3;0EMi9d0*!?_a- z!#=?l1|&rXV+ApQq=jw$9CWFqrTj(s;tP^qMmafD4aO9yU}guXv>%H z7xMitdL`|;@$EI^M|T`g3u+hkw8K zvhO}v%=}-y__Ly&51hLv`J{e(h<49gxBQ{#>^7$t{q~mbMO20&s^5q&(mEBdsr+C! zm0|a-f4^_nz<=~AyryJW36-H_$jmznw~V{L@YMX)FFcp_{BxV${P(N>p83i6^FRMy z;RU&;j@XjcZr_D-TTU=edgHa&uO8a_=1W-<<_$OZZT;uIk{5CxF8)iOyNf>h<)=l< zPkH3kpFR19-DRKtv~a|ZAMf7z;F+rYlP+6QwDHtQg(nYsS?O!*%yV`<-mAQ5!1xbX zAMvBt&nlHZUi@L3qP)dR_pE&4%snJyPe!k;MLRxxzi`W_msv*PhL1PxianW9d@%CC zZjzy7vXGunE-fJ$C2@fXescYbPb>X8t6AS`Y&TB6hM!jzz4+tFMJ@0A=kCQXp0#_$ z6;JJU>i&#RXJd$=L|^pDj*=vL_HrKVr_L|TE6RW6z1^R@b@%R+k3ZVY?a_O1yPZbk z1w6+zlXmN+^QLWC-n! zg&`NMSbQ7;9bDx2o}tt}96nFAA4ggVkTl=>=JpNEp^2*EqAY5^KcX!{-z%n)ILf8V zqWyKTDwjUz^71`y_dnu(RPJ$%pzkwHeGc}sJYR+RDa=>JWW6Qkv9Rs~^Hx}gfpsCy zyt3&X+$nV74sv*{=;M&C>GPHA^Bbc^|ESl=AU0o?d5P~I*?bk`V7wlA$w%Ja!8Av~ zhs<|8J8YsWtrLNNxt@He`KrA?(eoXM6;2updvCO^>Di=>y5_4`?q#Gg)}Qy#+=)M5 z1-yV?^aYvk5c|-2iIf_~ihZIZn!e!lqx-!&L;6iQ!TS-UC;RAGx3j7ulX&#|kz{&5 z5;G!69D<*hISZD{_J665T+K}qnJ@tlJTC(;;1`qj3|xY&#!w)N zx^;Ri9GP&c&N!KV7KN6g&1lJOkB=byVsx)I{A>wIOv3$9&rPHw^rtQ^rjgPhq_##!nb8VLhf(D%&lu zI~zQ=_#Laj*?RQAGCW@2wLM|R zO@bHji#{#mCc#zfg~v%I#!YmI$G_)0(r)dk@hx4#xC!aeZZb*nnAbaQ$~N+7_i28= z6y&!dioZT$484c$cX`}YA8+R6KK9dSf4~d)#iTv^w!@=Ptswj`ZmJzW_j{tFQ2ehg zOW+5*fFCjhuJ*X8Oxhd9O~ziPZA*PXR|?!8!_rx|e4vj;8u$5L?c=7d>B&q)M-YB| zkL3p8XG>tp#5*uvA#g1p3eD zL7MHB-)~}l)W9@eALVcB<`!8Wh4@M7A0PD@=OB|>Vzhfx-pQ`=L8s zOFn#SK$<3~|N5wbY1sw`e_gON=r3q}l;%DG=9>gB;1~Ul*oEM#HSbv;btL!|GxoGT z3bF5eVg2z7S|6qHOZ@dwzzg`r9@F@_+u^adK8o8P2lijV>uVB!eH8Elex~?i;Hul- zv9~^o`yTW^!T7nyy{!ZL&zKHF!+nYQ1oucdb*GFCY>utN3=1A8AO``Qg5n4m^9IYE7 zaaE&eZP6XHo@hI*A>#Baw9cqEtt}d)*ArD0%_%DxvG#j=SHJViVxE8C^+YTFeEXia z9Nwb5PxS1_p2f2Y-Rp@~tglq-iK_bDTeu@Tx9E%;y6t*-!rRYXWVYY^ z!t=L}|M-6%Eqr;x883Xbw9A20qBoU3k@21Vb5bJvE*#UPY}2_n?O*lF$4kpo^?D92 z2bEPFN2-r-eH1iVS8VItraY2skm8l$m#!-Eu5EIzkLvW&X|DBAEE&IxiClvG6z(Hd z&#SyXN}gj9b$wK4RpDCJNAV|^Da|@HWPKEL7{({22Ez4G#xcJ>%E)Po^-=7jm7nH* zSc2DY*WL!O?;d_fr{VkVIe)jP_PiQ;7jte6N?Na$Low*Ucd(x>H{=nCI=uVtfew7zg%9$; z=iPS?bl_Vne2@n|@4kDW17Ae=AP;0$OY~PJ^l#w2R-<6g&%U! zeuBymdhj2X{tR-#ACy1n!5a2; z?|}5%c&`>+>+ZjSUuV%j?AhBMu+Imt#o(P*^*(T=!TZ4VmVMwPj%?NW#vXL%kMh

+wGUj9LFt@^?*qsCg83Xg?ys>ATz}dJu0PQS&9|`qV;?x) z%g=jg?!?~*4tN1S=)u(v)xK}p2XN2ewBXl`+HfBp2+)CV?}GM$s|`QLz5}!lKQFmI z?E_aEe$IX1{P5GNB3R(z|nozK5%s3wGSMnJ^R3+e?fm^N`HfX2+z@Yp2c$^p3|I- zhS!`cCU}T@cR%aY{$eo`WxT{{LD=nKj5kh z8-5>hOn~Mn1n>i1z%L^08Mr!Fj>>7!cmeC=g1#@XzpM3*?2k${nmkkB2fTnEG6JsQ z_aV^8u@y6Z)5tW@pN8LuGz=fSt9G^S+P)8waT3N&5qS@d@f7C256V0?p4Txy?kpYq zp8F|deom*2l<51a$LVR^|Jf$`u^uQ|=4 z$h`G2v>!>(_aP_BceTI^_?a7J+$6Ya+=}Tv#4GY$A7442(hJnQ=+7zjt|l^WRn{j7 zNA$be@2h!i$2=&lyLi{QEro->Ewi{H+H(Q+@AsUpxf6ds3*ZI(BGR6Lt5!XKAJS~U zz(8|(oYwdaql;L)8H6A9&keZmgI_*j#~~O$l!g75AAWk=l=$C=059MNy#QCk$SI)~ zR%#fB2(wt}$Qy4sFz$_4%YNQ}`Tpgn_AVPu?SR_?&m{n#LQ3<2@7j^p_w~G(VSG7> z1Mjof^4IN(H46czHnJ~jd0PsH+VNw#LHKEI7MGX@_kVNAcF~`{oNRyBTw9I#Hvx|2 z!@CcOn35E^?lp#363 z6zDnTeuVe6+Dv%r`KOEN%-{CSzsUTP#L-)29Cf45xQB(*am2?_A_smTcC(MXV|ZV; zD$*G1&wHFO<0!!k_?b}|M+vT4FFgO`+1IUV`+l#^kj6f4@Z(7H^IFYA`*rWWZfDZI zZf6pG(EJ6F)Z04tx>egFKth z{k;e1z}H#$AP;_;v~(p{U8 zRP+~wALzk9TlgUt{6XahJ@|8lA9CRr4hFOz(1RcSBjkcVsQrQ-{Ll~Nf*W%3D{=_2KU~AP3JIv1|S0dA{E$ZrJx5Gs#!*QUC8Z&PvWEZPd0e8ua%R>5ld1 zJv6s|YV_Vqgf#F2Uce9b09Z1$&8#sn>uaBOI-}n2C>XhzA zHPQRoGUv(olm)!d2y{RZ#?eykflfU8QV?>DOVsdM`Cm6cKUZ>wD4SD)`U z@}&LMhM(iTC4IkBt@(3IWm<}?>v_0gzca-3f-&M}0-x%T$>|d2U_OYZf)}Qy# z+=)NF0bal_Hdf;YT(w?!9nbUoY#nj>fA-ty+Rw1A=QVGm(QH2JLf$p@C2 zzuX5u`+bIgrnQ&&*uRVR2fTovDeW1!>YAKC!MU!-vgXk5Vt1_f_!R4U&h^nV$@jr8 z-#9OsLoj~OFpp1z@k{)5J-`e2K`+47FuqIe?7P(7Zr{iEp1$Rt0~E^M`^DA!DU`OM zcEIoU_}wq?fxpE2V5IeZ{r9xqaO zr>U>A?bLqY?N5AF&)2lB2jeD;qav$xzlHJDAJzpD95 zlroZh$5ESP|9pufdD34F^%?gdlUicr4;=h;8sc*i}iswE%3wN74Ksd1EX zo*qZVWB3LAdw--B8b?(%&sHJW4?urG>!Vo$uXsz$URdvwrRMnrFW?s&A$B45p`r2Y zpMNCyRV~)|A@&^y*B`&2{qr?`iNAk7@B)73aE+h49lH0=SL>tq<{V&bo$I5oW$)p0 zU>p^2-*+5!9gU-|tEC_2_V-f??7#f>U)S6`j6c&8EY1dirPb@yY@B@~y zyW3rNj5>F3x0gzGZ7iWOl>B|by@gA<B>{PDAe z6W)vL9@FK}?yZrjd$>J%5AHXo(f6RHJjXPA|9r1R!=P`33cb$Gxj#rvj<54dl0m~F zvsz`L+mrrHdA+=5r)xT76&a=EqzI$4rH^A?NJNepKkZzG%^+xHPw{+EeUj)puwzKZW_KsH`)_ zJQm*fVO`r!nZLq3mNS=XdEVpss!pBgd#cpn`KpS4OnmwWq+rC+A@W??&u@OonT!89 zp0^+ej)lmwO(tOqC z)NB=k=c`yA%MF^ZVhJb0d=>Ble&#^23$YK@lTpPw=i}JJkDs@AO@a5&_@$FgB<6wk z2fTn^q`$@wxa!)UN$u~#{kA43E%Q~pw&tgDBVaztc&FC;+Gp~*CT@RB+MFa_m&~E| z_Q!I0zd*m|WzFrLuaaUUL<+WcODUMN^54^X1Q_}wJQ@20RUBUgm!XI)7UTitmG?{>iv98 z^s6?izKCOebpK}d_8Vs+m*AM|!|&-J2kq8ZUe)cTT9S-=j$}Q)@i@t%acew|KWnIV zOZd{bwf^hzgT}2V%6fd@1^j?GaMfwge$fiQXZQ2HGO~fwl-1Fm-Y**MIZ^kEj$ps&BZP3Skx3Hh z0bd`KAWzX@@^oBaeexbb$giLD1LR^24$~a_Me}$YY2GiI?{go-Jp=af=__gTY3+A8 znL=O8epCBJ^O%R58}j3EjWbP2Di8m)55A8h{@wcLdYyB_zgwR=@AAqutBoN;hYp9( zCW`f!&W#gRE#r+t*}7gkC608~>DVRm+_${0elf}Q-FmEroBp%czIfyx>uQ#f?JS2b zqa662xI)TRlcR&W1U}G#FJJf|5B%%W+(bnOpab7_;e$Nz4R79o?9%>@9CYAYD}0b=^ZlN>8=DVw;EM9{i^8LoWDH4{!P7^wO^# z6n_V~o$Ih4&?Eot!VkIN55gbx;9o2Jkb6k%DM%zH23a;Nit{B&``;M`K-n{^j{r{*HQT(gyNLJnumHY9e7;>bzTKlO0;H=vJ>7`C6EbE}8z7}wFabA8nB;E5cJ`=dF2^48L`79a1G z=$N0q_&{2xg8qI>GVRI)`29P?HQqPy@8C^M>ZU^QxF7n9lCoHT-h(A@zrb1ZISzB< zdrGgSd2k==2Qlt9Ha@hkSm`^qV~Bdbu1n6L>;9_puZzxmKewyK6Zioy;1?5nfPH9w z`fj?)+HcFEbaA%>oaWJRce$~`M~{39+6%bP@9%2-4&Ein-Hl5~p5Gh<%VhkfQDFPO z$tPdtPNEsR6eEku$CC76-Y)o!5&R^Mbm^t^j~MjzjiZ9!p=aucpV>(KqS-cnY@8_X z#Z*ISCaxlzcT~FUY1;HNrcInabIQaSbEeIlvwYsAOBT=L`KLMa=dE-x1|&|8bL32@ zA4g3=N&m4dwi$~GjF_qT`KO_WDfod8b`3j*UE@CNU8Sq;B|o%F*)gY^QM#Gfbzdsm zDWXu=t@rl6GaY{2&#swUvQ^R` z#k@o8y0_T%a2>}6XuCGM>lpNi53SeVm767|vVUAhoGW&1K3z|{-q1L|RME|C*C;pa zI`*Ef56Wd`xcfJ^T`#CyzPfzvY7o~WE^RPJO`*S~`B}D^zH|#QQ@Ov@smbSe#T5K- zkL{WpIP?(L%Xx39egOJ1w_f3D?-M7^nmBRJX(cl!PM=aTmD{}NX3nyCtIJm|nYR=< ze0}jC(aY161?z=lKA;!av%XsUUo+Ef2XVcK9-x=#xuO@b8}l)@UYr_Pv9kQqCFPgZ zp0Vfdv_|kaMew_VOwvntsXStyPiiH-RlL)3G6tMSbNuxJJ;e2r-S%}Jx5PwW=0k41 z)U=mXYgR6rx1c;AU+?7^4WjmP(|C$5ZTh#?%lRqPKTugY<^%R3Nqw=7ztQvny@(#5 zmq-__7wF4;pf0^!TDf%1vihpUnAITanw4U`TrPUyyMFdUj{x;PqT~Ga0zJg_k|}x- zeVLo<(#xvy)vK2*UtG@}CTBE=x@Ps1UcS`!@;=>Wy>QG2>?J;1t1s93H<}ut7tsUs z63xe-46qg3(aOe3E1m8+LDc!O8g%Si!x$&ikS zY3h5JG7bej`f2C^dWqy}y+B{)^2=T0mop}uIA<{pPbFVF+@674PaB6ee59Hf`kE9Wg=wWxCCvf8q(ac^d$xNI?O3+wqg zj{I#$3LO92zOBxjzdaE-S=R@#htx1%3($-3K`%ARl@0w;<78pdRZv; z!dLzDLZ4gK`!GNE*9-Ijy_o$p9rR_+57Ntm%B4%mvCv#dLo`#`C@#C2te44k=mp~# zn=AM%`gec5Ko4=foTTZXFLO?iUY0ChwR+z21vI1!&b8*9DUIT?<*;4`)S;J#%omye z3ebz_0eXq$XgcW2JSRvm%PQ5p*@}6qD;i)hrzx(SX$|9Y>m{QOy|lK;>pY9T<*yg$ z0eXq{6upSP%xOV-xpc{@CG(doU9!4CW3yR};7XxjMvz_>Hfq4y6yx2W*P$0)uTtN`y!iiI?;Yaf7tsUsg84@1%RDVeFO7LR zYMSSx7wgcA?{6~%C@Q+fUoX%D^a6I+jd^O2UK;Zh&@|5ho9oaE&1Kj7FfXsEml$zl z-WmIAnlcaV6^#8gkGK6pQJ;AIWPTm>MmJuN@@+alj*qiYJAGZlWU4_>!`bqZLw5UrH;1G0Vr>lLu>0_#_> zegRd&d-v~&+!LyX$--UH#S>(ECtXuds7y z?dujG2k!@cZufX?xwReaI7=Id=ApMZ_D8`jo*E)_2yHPx+HOMQ#w;l``_b>UzhmS5l%_w zcEPWoo^Omw?3CS@^9sSwe6oJ{RovP*{5m`EQ|ry8JtxX~^Zaf7)O$6==0B(E^;fIP zb7m}9vvfrxXDs!4^Ek5fXh%H_tv9bevmoxDdHjz2`bmGqb8j57q#W$WA9kd9y*b~{ zrNBL0ZR^dGXvG26e`{(=U%oUxPs^*MqL16_(>ZM>jdS1sjho)N|A?Z0$wPmosq~5d z2mKBDpO~zxM!$shs#tf2b$D1$r>ZG`hRV933nP{wFGO;J;#>eB>2RD$_-l{wL=RciLGgpL4D!A8Os)dwYnN`X9tK z*3I$vPQ#jaQz3ZW70Y9}6DVf=c@LJrc(M!Ra~$UN;=itv{zqcmZ)|Le|H^%$p8o5W z#`&+c9o_v8@B)5jM~xqF)%D@ui+$eF|8RPwBkivBo03HTgY+ObnWS|8!}A{cJJV$T z&eRyJLg4bExFlXTR}xRzCmK1Ds1UTrzUFlrKb!LSJY#>t;|Jgc{36nxf$Pz(UC_Em zZhP=w!T6<8FTpL)f#0=>g&*(&e!vU3+P@cDCGAaqFV+~O(z&F^VH9`{d4Mp(Ut(Sv zY20VB+J7&0So47*D`wZmmY|X2^2MbY<_%vDez6&P9FhCDzyFMFcV9nrW8?fM z)WYqLe=jyF{b~4nvCvHYV$4axMikfd<|)bR-250fVVs0<6R0qr!gvYaTj2Q}<0sH_ z%yv7EVt(%Ahm>K>uT)PkyuK!OzkA$dZj}AFC62b${iFB$HkQjr?ryzaZ|9vlHXr&# z%|oD`@Y|4sb|1^~88_`+;2tL($+&6moqF7axW>4NpWEv{ZVGyC4;(jb)$QIa(c>n> zT5FB}yM3>IZa=im-M)h)#v0k~x3}|*n*=Z5XJ*Q{N$f-CznsQNd^EwhSN*09je8N- zz^`HB-bcye{hr%3etJJ{jCUGt%F3my=FFoN5|`F{ z)vIC5WG)DAWPB^V?`E4>L*+-zqA*Tth*;nV9`q})W7u^xUE4M6UDK;)u07zDIY5>E zg5FJVd-p4o-!)rC{7l*PE!3IXcCDYJS#Hq5eKPuGKfBh?bMEH>mS;ZpHH|0#>o>|T zRlKI-pmI0Wb>IiQfFH&gz*Xlrw3PPDd(F<9(+5@hJ9P0`xxqUP`W?^6MgRNydEEVb zlF!oI3kN!C@k@Sr;Tm((Y#Mz*lmSWFFFoRqpPBj#rGLbbQ{OoDj>hfKPwIzX#r{%=P`a5>KX8BBedJaivYn}^LH=K0x-WDj9IlF{Y5e*r1%8g>l3#(mg3(nl)}ny29Mz%Tia zm*!A^tB+yL=frzt^KpN>7ScvX<~04BTd~2vzpe1}!`pLOsQG7PX#PKYewwfGSc2=v zhZ=Y2)A(P;?_sJ{oR7}AzJB}fk1aX5IL;_1LHqCjck;SDA1^xR)n;WI$1~};ZqJSX z|BOyM_I$FfHR-1`D>3|rMa7Clveue zzkj6qIMVu{eu*Am|KiiizMS=}?=`j?Ctt(QtBN`===s_trJ1MD4#H z_i%cA=Y0QVmjS$p?K?+u=B_92zi*nImB7dZ#wK9@{gjlHW_9krpGx&=!~5@3pI27C zXx^HojeOC0Bo#bHcu(~D4_!EK!O;0bN6jlAIdb99h54gLk618tf4c`~;v`YHIr-5H3)URyq z>qq8G)fxN0b=3P(RZG0Hy-r6~=y`?6G9CL0k&8UMbo=hwsP#SWzjEjl8c}Q1g%u3~R z#(~%5z;3Y5RE6XRdX(3T3;00~{(RwwT<{+fy+JPcK@WaY_#qed-Wk9jrx*J>*g@ML zftRv=)n*F1G&I0$bLW%e#nPh=*>_6yj~c74(}aJ&pw#oL-|o3 zuRglbM}fRQHT&eVsD-M*(qci6Apw^3s9L&Q+ zn)}IHTB>>RJ1QN@+-axen&&g9t?|6qSJ#H#<*eK4>0pnx-SK%B_yI5AhuQ#Fm9EMtqn>jg z?pb>>$}H>p1Dqa120lTI{C#O>-u=8r%k|pubI$(ZmM6pTT-&jBnnS z`|gOxHdRIL?`dWxzeCpi4iWm*-r zDNXV{jhcesENDvra-2TD-+=u3(U^dT4Q#_4-jQ;!-tTav`Fk3^U!U)3zRBNjK!1b& z1^o>bRULRP!*d{>3(@c3ISuq2XUlk$`x}1G(lvcB&6W7KQ8Oy*KqZb8j#oHFN9oup zw?60SZy*Q$DmuzbZT+TbUuAb-X3 zSZ+{%qq!6Rc?@^~zt~ufA8=(o8CBcd&(lYOpTXZw(K^t0tos|zMn6yUI?(##mqE7g z*WYOT^g2+M%?G!QL^;s@fEVyH$4I+&wZpj+jN+05cHJqR^N>nA*MS~R)fC=!pn1ZG z`?ef)rkd3%4UP%T;3P1k6E?MtL__5#9zAwmsvhPIy6b;f9Yl?Ru~0km6Z|AMBkKdF}Y(eVYpRtRMfvh28THocie2(%)Ye+h3U)+4p~c$}9WDrCay^q9|6nrkP%c z#N}X_d>pAhjpPE%Dy-Zgn_OOTcGW@^3G^?|;&nA@#d*C)@R z;krKF{lji=$@CP&2d_iAZ*!MIo<|PX^(mE{@ar1Gb$v#-u1`0GI{#u_U-So!UDr3g zeECB9VH(Y2zeDW&KTlJH3v{lsLDIPDhu@d$fyde~-q`GV<9-g9^g^ zR}OKY99T~_Tgp{an0tL5=)jjNe2@oz@47zFf$y-?8}h*CUDpRX@Wr4nPkFuT`alQ1 zYT<)C?RC?kDfqUDp@%9_fTx zw;*@{zlhiaaMkv}>-zqz<~`%-xmz9YC2F@Ctm|v*KeMIgL96sUc8dO;$L>bEW*ma& zL7nUR{N~X#cjB+>175%nNVwYJUS8LiZR5ph!LJ*&;XXX5qT_q?%*sd5y1v@*bI)Vv zCAVwFAs9dBx;{VrG`B8KBK~Fnd6+6@ia$=Ab$uEwF{wCo-hHy;H{^u%!TlrpL-dcP z^pEH_F|I)WivAY;rc*BF+1JoT-lw!{`h0cUZ*JavMb`C6933M4V}HN?%$bY-Ir>M) zLHmpi@{zZ947E=_nqZv;_9sQG=BV^MRb$@MpHHP?{dtcQWt|1^0)FN|jURB;df|OZ z?RC@i^#-L!?(^yl={MyB>-vyx)IOyar25A^K0MFomVQrY?^EhSa$H|R`vYFUFCy(3 zxE}3F`uQR*lk+`&Fn;d$^hdicO_@LN175%nc>q^?pVAf5-mp*U9V*?H);n~iK#z`1ApwdN#+j#g%^?TS7NBc?tnBz0fVIg%KX!nqVb|35GC$DSMjhpuVgk;hBM#M)r zZVH-LIAO+3f*0^Jdy8F&ebiwFU;Ax8TSlgA|NKnq_gt#SO}svJJ;>|j*W$#-_zBt{ z@B)63lQe$rc34c~T)qFFuGaaK-gJP^e@@|DebIPEc@IfAqTkhiU(E|S<`w9@&%4I6 zsT}-$5sNFL*YfaRe)wr_9yi&C%g5T6kIOUQ2fTn^RQxe;)s>_5#KyCZ=M+wB{G98H zgYd)p;(+@;_~jFJ9D?zK(z*Zf!%w$AUSDjZW}kuk_>F-d@B)6Q5pdP%&&qUsQ(2of zSMIqv`c=`Jmvr0nLH5l3#GqWP?Zqx&{*E{y!o6-CU)=Nw;`eO=-94Wo1P*fFNb$b82^s?{g%^Nu( z|C*k^%F8|F&Af;1eK^1Gh1vP@M()d-l>NKBpB3)RBf5M(e|y=jiiT+~TyT#{ztsDu zd7t(FQQj{z%k%ouCXRg0yiCh6(=KRMnU~SwJ(Xtq(kV|X+LE>F<1wEz&sC>Ck@v~$ zhZHT#D_NVA&-XY#zQ_Ep{QWC+|K5tM{LN!t%^PTZk@rB$kMcNOI%NozeM0`Cr0AGa zm&_dd{*(L0w*PBp!55J!1)E-(TrgwL)Pmf}6AN-XO({6=Kg9)af2T}^?q^Oc`0rgM z1)c6JE_nF8(t-m&oKP_6n&N_1KN?qX)tixmRv(Nl=zPV5g8$rDT5w;lqJrHgjVt)u z_L726k_rmW*>pz1^r}S#TX(D|81|hj3aY-ivEY+!*B1=?^`!-EyUi)M?BL`A(rLkr z8`>3Q{;X}m_gZx<`1SK$3cmM6r-C1zeNw?EvwIdy_;zl=f4A#f@X-^43qIUBq@d&H z`2{ooII>{=c>@YQez;4)+gs8Kp6&a`u`k{A{joFhmyTV~>{DJYA0D9w>eN8k{=@cP zr;&sN39Esy{fF&8VU0ViSe+UO+ke>p>ok&(Ak;vpflvbpr2%}$SXIPRfx+{Q!IiH1 zHP2Mi{(1a|g#7m84TWI{br9M>Xak`Qgf-*iq*W260e1B%A?~E2s@mm_q)k$t>eQPI^Nzw$B~Ql{z8c}V{y#pdIEtkCYU4^d3~ z0O(2jmZW@aGCY z9{kn954rGLLHUCo{1w6vx!^}RyyXWy`16Gya^e4i_(2bTQ}`hl{6YA|>CygW`~zgF52+M~BU zJNJ?6K|Pb+M=m{u$Jl<~c$qzAA32F*J@j{>k*XpbM7P8L+}aON3J&f9N&A>@1f)+ z|23IIFn-Q`sIJDOac6W z7w|(dfU8dX{XXnP`}v;V@5AEvV6l%J(tm<*SFGpYy}u9pk@~e`e_LjDr~Uiw$H2dp zoX7{`$G;DY_ME7{4;%T0e;*e4^`pL>eJR^8hiRVQhei5W|9x2WFX(Sf>2J^v;W-@7 zvv@A_K3{WN`h>=zyl>-QD5RxPobo%RBfl|hRP=?|?5O*hNc$t}Zy*Q$%3og21TJrU z-%_J{nLDjhL4Q}tI8psR?A~s~%lmIh9Di@@{C&~Y$=L>nV1LDVvHn#$ES0Q~~>4&UC3Vi%lM>YPkp84>-T1-&S-$ho+|DbBbpDtC`9C)aQ?7tXz+S5l7p~I5_Lb{1W8Au4BIP_;)(_ zko}a64r1p>>$^dJF^*Dxsp>kCMScmfuV3O>9zE0J=c73vjH6B>-Ld|>hvrUHucY5s zs(C)a3;00~z*VOwmKs%$?Z-X(fqBAjy-I(J+QUqCDs-raFp7bfcN~oSia7p9`=wiG ze?Q(2n|6Vvd4`$E$w?giZJAktAKQN~U;LOmaSx1x(Vi1^9Bg77e1uTWHP|DQk?A9o zx<4}G$; zXL!HX`28o`_sz@g{l{2d^f&Ib`I7y6uPVPxPug^+z4@C-?)&D`N0xu=+9Fqd%uVfG z>FBNQw7K4$j=nI~MQ=XoPDdYhr_D|7bo5qt+Fb8WN7syT%fHy2j?Q(b%~|er^jq$< zS>jGdN4eAHKzBNt<4&6$-RWq$J8dSp)6r4+?(z?Gr=vOUwAs;}j;6cQW|BJ{9hK*i z?@mW^+-b9;I~`4Tr_CgHI=W_*TmHrFbabveZO(G1qu+9;%@TJyI?A0k2fEYI9CzC6 z=uSt|-Dxw)osNzg=`R03cRHHmPMaOw>1et;Z6>+X(NQBj^4;lZjyr93bf=@~?zEZY zPDlSf%q{=V?sW7$ciQ}wI~{$?oi<-{r=u^p)8>=zbo60&+T7$$M{jkf&Gqhdbj>n% z`7d^-qjTM9bCx?D{gx+fv{&+Ym6P(XlIG_fXS$y!4S#Jm)W3>K}(&H8H{iaTHzRvucT7E<2;dvj= z_julqF4E8YmT$e#C2k%Q;ONQRHRs^69Ba?A65)rV!SG%6Jk50uFhJr7x*-vJnumQC8IZ5|T( z3;G=Z&F!?HfWjT8m)Rcqc^`NIzi7I~54h^;Rh8(t3Ggds>}kFRvG06M{qf^|d9V)# z8ozY4KeNy6OkKW4{3y8mWBAX*sWtDn{PoG>4C4wVhu#A)0lfzp zl=iPw4#D$n@Sj2WY3`c&CCU|Uf7LYCgZ}h+I(LtD{A-FiQ2)EFcovEd|Cv#Lp73g- zYG7IuRt)1$j5jg<#CK>Imts9L)@5THiuKOUBJumh$rO0}$rk&UlrL2i@bmfRdi`7# zk4+h8B>9XNotXrjqyIBS4*X}Nxu3kVlz)rAZ;HQ1t>615yhl~z&$)M!EE>Nct}%XT zrQV}vlQwD_e{!{0ZqWEsbDsd?Pr(cLMN`Et1Xm6J!crY${E7GAjlfS~&+iLa2E{e- z)9=CSi(dxWzTfyoTEH&mnc)-@s$vRzi`~Gco@p-xNOVTADTXkdrKcsPAZX;6owIr;P=$#yY zM&6tx{wie~g<$;HccT9Z#?SrykcjOMcmY2s6}TdOv|_)p0LlXV{Qc*9#}!=W7xsHo z)UURf{pZ7E!*M=3=L&awbBAkx1(xyKZ;dVH*m-O>s`gOdML{2z{(9RkJ}dk5r-dVS z{CM}y2hUV;CSA6qXyd7q3Qr#N@@~Grb>=y{9`99NG+_J(g`76_rjNe(^}p@8;)9K^ zabGxz_#?#g9MRF;s!=5C4&vWVJe+=o^uL!-k)#mTEhG<{;*Ba zj%V)K^VUOW?x8a5$>_DU=#!~gMI8sf%w;It@bRWyXYcM?Jge}7-BgC%?{}Us`n%;j z_Ll70SVCne8I*f(;moeNMT6IMQ}uacR>tlpilgHvEZb6e&HEEyh}=5l!1{|em;STe z-}XP19NBl^>>*{=xXt_fy!(0S_fsO&uV60|u3RJZq1lXHKdV&w;QHh(Ub<)H6Lx)e zeE5FhmQi+nVo#kYW9H;+=y_Gq`Gt8! z`LDdU`;)is-ktLCN4u{iTY{945B^~6zkXj@bi+?~?cQ?AZ&jP|K4I79ryz%8Znx8D zynyEz{;n{|Nf2;u)3ALykDQVp|7dDqGReWg{h;Z14}|OgpS`yMw4*5R#`h)xm+$Z) zgb(FJuv`m5AOwQIJvU#l6vRLfQL)J-x#3<3NqUn=5S0U>uJ~He*CL?>DcE`~mSQ3$ zL`*{9g{4AEtpb*+X$;^{Zn!b42iKi@HvSjd-X_uU^ zcyP(dgG*=3IA!7S3ujE5wpRR(egDc!#}!mnQ7__Oa%Zys80~_`VY*hMG^gXI+5xrK zQX->GzKVFBQ=RNR@%ZDXd*1ebAyvzl%8Sz9FY~4Rq?@jJlunE*5YMA?{8QH{j?F>s zEUk~m^C>*9LRvh>!uuL{ZiVMmAI(aNBEgXw>+-`U*Hco zfL9ron3L}hVmvBr*sJlpYM;4364>FrjZ+KyL@K9r~@_{|krf|Np>C$_}As*6=`6}O#hxF#&f{2H78#x{1A)UFmAmSli$mt*t>CC+a z5fAAu;&hOQbmrcIh=+8&oDTAmbm_hD5D)3VFXScZE~F+%wnY`;A|BGwH98}_;2hY=t7HSt9oiug!BWRyqb+r$g$5g+Mia(c)`{*e#l3+WLb>3!S} zyGW0GnCavA+%7z`t15?(`vS`;%0J>m|0t)2T%<3;5Al(HEvJWEq{n@j`A2-D4>&#K zj&Zp&>lN@re59Yk=^+=m72%KgNRRdha*-bSF!PW2NRR7~3%z;ym+wq+I|rK}Sdwn< zkiM630G=ivcxQ~(kiApXEVZ}R>`BzG=Z&NMH}c+E>_#ssTOjydYc>JoU`*-1m?v-N z-CK)xE+zcTqg&pY1Yh6}X@=-ZBi%Vo<_t(Ta zS@G;}q8L|-cP8K9^-iK+epx1QRQ_j*AC>>ScV1QMF4$X(>o52tZ0G>5G9dTXIxgW$ zh82JM-daBveF_~#du!F>Pn*M*du#PhI(b4p{`9@I^7vD!Rer|fU+T|Z5I2T)dHn3H zwYRVd_s-a-J1(E--Cl=C!h`xp^oQslVGqDQK);B78si-FlTd;F@m-<~N%q$Ismxbi z{}?V&bD**N8`Y0Rzs~E=przQQ`=K@JAGp1eBhpTh67!Tpu$XM&%!*5CLn z2klkxe2%=@8|SKg^Bm1R$InZJRiN-M-6tLPYl;uu;}C&Hqcz1Ow`fhVO5Fu(ikUC) z7yd%=2VN!cwVT?l8o_$1bZ+w)hnrdaXU1#60#FYp&V$Mrf@ z55*ed%C?6km+}vVzaYcMiSSImfOnpX))eD+ z?|St-gx3^PyQkW|yuO5_P}_LGg-P!7Le_ICeeIKvF6_VJ@dvm5#WTMY*K5^B zf3vRo*rktcJ}&qjax#p6{dZnGDmSfxRI7gOt#hl3 z!UMPb@w=vOK5x$Xo2e{8X64aIZxcGGJfA3jH9Ft&nsBy5$LE^xJ$;`*@*1uQpKP-x zeDd)Vz8E}h+VnOzHd9)Vw~^QH z1ryaeq$zN(R(5lAiCW(hzAwGb#Z*b$x3aDe`M`Rzkn?5g@x1i9KEy-1i#Q$RA-%b- z5Al$$m(xKW(wXb}5D)2In51xnJft(%^&uY8MVt=ukj`A!hj>VLGpB>RBwc!4AL1e1 z5T}E@BweyTuOdz&9@5R^bdZO1`noWmb2`XFI`I_`u^D#qja$S+x@WljK_1fm z#U2mK)eZEVry@=w9@33+I>Rz2F+aXPS|>S$^M!S4V-r+4L;M#QU$eXtK9nBuk$xkmhunzMo8=Gb5g+M8P7k># z56B1dh4hGz^cQh@$VGbO!%UC(NZ-rpW4R6TkN8OcLJ!wdmNV18EO`bRlE!GZp`Tr($9Lb=c&~sI*b+T{Zb+YV+Kj!(jA1W96ZC$z_xekcs;JIe>qda+T zovbacuT(tn2fo0c&*cH-L*>VI zY>#-hO@~`2t8nP#U*hitp}^<%c>JuBrQIgPb3_T=(8L2*hT$>9MsQTd2XF-F_5p)74QeXz#p;$ zURBtwlLan2i%a~;b+TNa$Ll)T@D*Ms3w=i!>tt^<*2yBgv#*my|APJ|T%`IN^h2=2 zXRle?DP|ICYb(Kp55M&DQcO!RbX{SD-x zz4E`8Bd_-G992)TSL?*N>97hF{iXY)Lw)PGPw}ls`W3Ge zB6%eDB=IBs%tNJCtA)&K;~|Xx27H0P;8`vgTt3vj-ZM+N?cnb-%pbcg@^_fvZbl)0 z5-#S!W5pz#rOU@T&Nuy^`KY@Pr+fR~B{ZBD}U9fjD_n+X8Frfpys!)yl zKXP~7;&~4V%y-%1)&5z|<*PWwfA?fw-&DYFamxDqq5kE!pJlYw%gN4ljrzZpZ%M{O z>jk#z8AAPh7R{}TR|32xg-NH=W$k!g_NQX~hFoh&>BwK4UQ6n{4grUNL%<>65O4@M z1RMem0f&G?z#-rea0oaA90CpjhrqZ;fSy&l=Y`{*W_N=Q0f&G?z#-rea0oaA90Cpj zhk!%CA>a^j2si{B0uF(;A<*3O#Pr^L@!HA#`bB=!cZuoT?)(#uJSMR_kzHDcN&6Jw zJs7+f<1bY2#o&Dzy#IptVX*H3_Ag*@-d(sqdQRtwj<8e_m z^`GMRAD+y4j|EEVxbb@xEC=g?gKy`_d+%H&ir=f)K6zd$Tt^RG+KWGYA>WJHezTAz z-iv{o`(DM~yB#9XsP|qB@GE*RMx`GA@5O*G@E3lI->YC=6*Ye+)^q>eLkUeMitul= zaB?NjM;lMl@sqgns4)Lk>+&bY`yY#S`Cs#X+C#tMb=~^@)p_f>^WLjSX?=|cQ2)Re z_=~tcgI9H%^d7}78ebw@^B<;b`g;{qMLUvr;Ju21>x#eB{^K*fH;MNuXk~p~TSPjj z{?U)#t0?BL3*M_>zQ7;w2d|!2ndN!^A?n)(!QV}DZvDvGhv#4YwYmRz`_&J>}F6y~U53NbrO9lAF!A{Z!Yn_u@-uc-~8A(0+=$KfQlH^{#0rybX@+S`nO25Pv}qY7g*&tZ|U1lc5XPwf@2h;|9u6xBR{*mUJ2OM8xVEq z53}AruzGN0cwm_!);ic~ddfeI12OKyI1u|?Vtk1AqOso?_6@_hP|q;E-*le%(Rb^1 z5x+erJTF3C?stTOKjrZzyZ*oMIPkH&aht9s-;aI>a?p+iPvprvP;fv;8{V(o{!1PQ zvYR^&w0}Rk=sQB)@_sb<0)OE*c^t^)L-8j2jxEYhf0OVFV$*z^_Ag1B@u_iyD8I>f zXlN9tMsh{t2uPvwpZ6UFl{!6+K$`L3qW*y|@E37?2CwQ~X+MJNw2cmF`nZ`p90Cpjhd_eBijm7! ztsGc9xa!zTsF6x8IG;nnAy5thF*w*lBLp0f(l0!|=ZnupO_WauC#w%5c{F~I^I80z z4m`&|Iy~RN^9nq_!2Y6`*Ft>E$KW{zeV=OY-Q;tO+-J!Ck^DVmxDnf{59U30fRqJik|*zixk^$S=Cc-kR>%_bS#UGYG4>SS)3u+^DteC5HS<}_7x)Vw=5oQj zD&7{SpF_1WAGzqSnLl%yj?<2L1Z`?8DqEL`W)aP;RG{5{>7-UDJj>j5E8x1o@LT+C-t`&Ils-Sl%P z8#__gu`~P8eu6LX=W}}uUe!H_`Qt^mNxoG02ocw70%XE&d4(H&bh4}RuBnjfI_kBKxd z@2JiY(QEezS)(HTQ6dec|A3IYUdZxQ`r5(&bIGiQ{>xjvuS}dp>2Kb5dUe*do3~v1 z&9k?NJZ$;tU#zQ6e&e53fBu(0r#$pMIC#~J|9bG+{=I+t$Yzm;&G-HLH#gt$(uS>{ zIQ=uTL>^|n@WuQ4rkrwkb&ua4da`%hSttJW%eQ=E$Gs<>KL6nhD8IEIo_GAieIt*| zIeX(15B=Tm&)oL!haW%p`zJs0&|iPzi8=TD;mp~T2lb=eiYMN`{MWweUwvZp#@o)5 z`9I@|;pz>4az@_~$J{URxZ{F%Kk&Cx2djU4`VS=@DwUX<|JDkL$3H%{Z}sF$mu(sO z@_Ac?j4gXjy`%coAN}9HTW8!)GWtIK+)WQecTMbnCivlIAw$X}8HeAsY?hEAFzJpX z?>o7+=XAcxp;fEy_3N3{i68vU=0D#3)0=ns#J4wJ^}`!t?C<;To8ETneY^IZ_LhI$ zJp8NMwvdjNzo*M~%y|8t?i5Kx>)+FzB-*uoj~BCgqBY0&WCxFZ|H@0t5&fD@wRFYE z;HuT~Te4kw|I?NXES`4Bv>5|~C!V-u+LEsPo~~HGMc>AiKUJ9H{z~>wS^?*S$EBiOCK($!U&3n~>F=W=9@2%J4)T!L{GKl2 zA>Bos4)T!B{GKl2Azd%0gFK`&zo(0MNcRHc40%XL-_xZvC%^^qkS^kMke8&JwTqq( z@sRFjP6v5Ox(g@i=@1X;hBzJMA)Wa>UBpAWnVb&tkZyRFG=GSPbchFe2oLX)eBYM7 z7wfZpeDCp@52^Bs_`t{HlW?W!H6oE~ytVEHCLNRRkPzn0TOZp7)459AB!5g+LT zP7k?Ak9?Tv5g+NNaC*oE?nU`We54<{O5q2&NMD2>;v@Y=P7k?AkNYt5kN8L*a(c)O z3+gfOLwuyah|@zZa4W(e@sYll)5mg|zcJ2-nSaDb`WLvpjO8}qAMues;`ER^lhXqS zQ$OM(J=$x?MS9?1rbm3F$92d>`XSB-t`q(=Z-agT^EN*B6Nm@g!T-%H$1G3y9vrRX zxB6b{Vf?*Rc7vDSCfB`0FDV!LZC$z_`d%vJ;JH=!hdg=id#Sd#zEbhPANT@)C=cLO z)+ns^-iK+@pEG;|1-sp z%Kxc3a#iZx#N6r5zVbg8lZGe3ANT@)NC;kKn7)^~b@*Xi^C-;x9V^C-CyO5);KzM0 zRpHUezr^1QLV?fi@%Z^(>fRpxGwm7c@1=5oi2gBnud<)eZ=zpB|BP`O`bltx{?Yn- zsozlJxR71{Mb(c5zsu{-przPF{e&FU&s=%#d#S}hzDifXANT@)$PRc_VfVdM;Igy0 z#Gm|LD%a=n`n}ZP75-i-^c}^|o9G<}`pq}Kmx}OC|GiZ1U(ny+c^&LB*s-uDi|jip z_e0|40veCf`+)Sl)Zty;DxNLnk71*IUy|QTg&Y1x^)ulwTI+8h2klk#>l}HtAI+is z#_t1G{$7j+wXg~l{-yh*Lq0#Y=x@Lm`160o<$}wHy!*=M(|onWUqAE5Zj1aCt)o-?jsJCY;0yc(&ny1Gt17)0 zi~6^6TT+rmxc}0JDg1BZ_aA)Wuf&{d-tlbx>(ZW1e{b_Yyjv&IFTX7!aa8xveig5y z8~^LDz!&&KdkkI`^tA5r;}0;9$B{6g#)eH zLgOwt1RMem0f&G?z#-rea0oaA90Cpjhk!%CA>a^j2si{B0vQD8S$gsF#!Pf~!Xe-g za0oaA90Cpjhk!%CA>a^j2si{B0uBL(fJ49`;1K9?1nizC-YnLU*S2Ec9)gUXMaFA; z%YHAF_pQNuF(j7`ypM_f4e&k;-p9oL1uC}ZyPfB z`%1&jyjMZ{OMg|o6GOjzEJ!BsD|#YE0z+dzu#UFT86v+MJwlE#SNy2xE(AW3^_K&`U!{CpDMUH$g=K9q4ZmHc+Ub`NQU%(gm!ySQF zgkLQ;zeFVC7veAPy{50e#@=i4$4c%Gj&!p8=kE`G|I$aPj--yF{lUxbhyCbx&lL5! zRy{-PryYnrwAYJ$vxUOi46(QNjbcCTQL%?Mg*Sf(v zWPfn4BKE1-iS`E%|Do*u;P1S!GH=Q7>fz;W{}cf|mn(Y=@xHVh*Ydt{>`wWB3PX^s7*IUdsa9ELokH}?leJfwT(N_D?k zy~)1RluyJ%x=~ICd5OMsI>bY|wVV#}kj~s69PyAY;B=6eq)YD)j(A8nh0{S^k}kbJ zIN~AQ7?%ggLppPRaKuA8lqbkTx?7F?!4VJX5D)SYzSY~f8&cdjQGIErKadN&kPkCG;v;>;=^+>Ckq(*N5q^k|^fNg<v?9`TWWEvJWEq%Yzh@sU2@^pJ~s0US*H5FhEMaC*o^df;HD zM|`Bmb;w0}+y}1H{mcEqxnID%o6ljy!+nE)ln1jsVgFNl?qan+_@TT%IJ?1r@%+m7 zl?(m0F5QpZADrdjxmCD5PoCQ!+!ohYDjxU)U*Ip|@__Q8@otJAKV|}KbtomftF&I?uW)VKFdM-8sy1y z`@0td`6^ujf8Y!JAv@qzh28${z-4D~i9g!k9rbyU5|BBb4V1M^p>+J6yepc=89=qRF{Y?0+*7}=} z<)FQap3afCbzyoPcf3d6PnMi&a{)*PID*nd* zI#%!n{(^5S{=lo^jrMo{yKTx(e?_=<)x$}+z7PAm|6HsU$~kDhu;1L@{TE_?_g{$k zMeDGr?xFq4+aJ7J)65O4@M1RMem0f&G?z#-rea0oaA z90C~xXuVVM^Tteccfujy5O4@M1RMem0f&G?z#-rea0oaA90Cpjhk!%CA>a_`as--t zo~YirAjoK0c>Mll+5O%5Js7+f11j)7CibVm`!IMP6Z=mf{%vB_s=2@WhwJU{ejxAf z&TjN1ub+P`=RFoEspDc@Fyvreu>UVP@@m)3Rif}-#XqFOb@b4s5Ah0J`~BTNEZ&Ks zU-7zp;8*lsj7mNJ--`iX;4gTB%LSJYNlop}Inwpoz+Y{S;9l(S4mbC`CVT#h-iuNE zjsN#zz!&%nzp3~GuZlPE9!3AGhn1iH)_fd+7uV{bincj<&JZ~4-<|5y5 z+lv#gVHfQu_yT_sx5waB-QtOJyhXQZ{2igfwLgF8P7&d2j6>1>?spj1IS5C-*R;C; zm-h!3``&%cdurmH;#b^$y8YeNJ_O(k`~g((itwxD7QGjP{;z0%@DIPn-iz^nSaN@G zq!VSG+Lyx~{VLUm)bWF0Yvx?L_Xo#**v;+_UR^kM*7UW1zjgJK-|44)f@y#7RaYO9 z+8_LV&wnnpKlld@`ATMg@RirBm?iQs>ngE7`2Rkrw|d|3VGq&s}uUCm!1Lt-qb~rk>9158lfC zq=+2HfxLacZO`fZOP7NvyFWOUCCGZmg&%MK{@`rKxc$K!?ho!^e{k^O-0noc?GNtu z2e&Qx3xvf#O*}vey#wU_e1n$n4MYBdISUpKE+6z(4_rFv4Gb^G`IcOf2RaTFzoD1v z@82yWHu1;bM~xrDFRT5~n@FlfO`a8MCpB+!9kwjF@M{sp{)7A8{dIA{-<}@VKJobD za-aIQT)fZe^qW3?dLO<8LGHd2D&BkcVW4z@1^#na2$EVj7OWmvzGPrzNed!G(gYXC zS#|!Iv*F*F+^r%rwXf42E_9^xP5T>CZ(Q#H-!B=F2tWlQ#gKBVh)d^d;`?heCy5P6 zgr9y>E*^-U2vgM7iIbNWH&@!Kl(sBn)rSu2h!_WP(Dw;i|o@|73s z$(`RJ;1K8<1P&L^Y4_}!yLC6}5XeV>zA1!X(#Ilhtxr5c6vwXo-5B(*wYYzsea^gd z=gvES;kqNCH-5_p=eXnY&%3h@0f#^rARs=JI9ao-<=*o>6I2tO zbNkVY>UlyhyNHtijcnLeS$Cq;8SjHv{q>|7Tj=-S{M)!j?S~He-R&lQWMYp3(=;-3 zze3?!b?M*UC7w*xs>=RW=h88YL+1Afnhh6APOe0K$3H~RZHf;y9++5M6lKzfeskD^ zd189{#pRlKE+k`VfAC>YZ=!fg(EK6C5sNEtt;`-+HCUOmV)^QkfmN&R<(x6R?DFBo zt-h*TtA;bu^`q72K&_@X5eUDco)5zH@2da2@NG}*U&W7}-H|*ohU}vI^wx2#(y zp2}ipsL#ONUlh77r{Q8mtU2 zudE&#UR7BoCv!xS#z%ku?oS_an#!l=(K@$KB*J_RVWH(G7FTb-**H=MJTiZx?ZrIH z`vfkOzh{0sPtL!Ly{O#i!t{Jo?+fbu#@{J7fcuCFCt0mk<#Y6&Nn$l)kH^o{d!~Bc zRG~I=pd3YSCl*%L( znhD-~ngF2^^okv?6X=P@klqRMd+6~jOEn#?8DX#GaB_pP?#B4w<}p9&`{{W)D*vh; z$e4oaey`RaFK6vBaqbcGIY$U(kN=-5sXY_<_PqUX`kZVpP?wUtBtB7&#PQy_-qtYBO%9=yml32DR*`~!bQ_ds-c&+c;;`DOb^_q=W6 z`qSy$v->AAP?M>YH&8SrPi*?R|{z|WRXv>%<~(|7%iMwZDV!devef=}RQ z!>2FmXT<#k^*2*Bu|D@B{?C-X=pT5Z8dq0NR_+Yt`aN)G%JcqBsvd@WsBll``2)W(igEE0{bGmR@o=fHYE@8$rUimpMDPhLuhbE z5%?gz)NVpfr|Q`l=O22z+eN)H-7G4oXTZ;_xc)em3Qf z=tX&9h!#{^`-E6Z11+8 z%lRL^jV^b>ASzHiulyVi8(SU2W7$MIkK{4q0ySHu{GH?it^r_hgk*?&Z0s594Sr% zKPn5bqrjm!6?1NK8;FaT54v9XY3zX^M)aVnpZ=!wyc@-l6Hme=dD6*oDQ{vH(}SE( z3cr$#G(9~%FMhSU%MTyj{PJFhkt@q6@{`Ez>7i>JXEUXtYlugBXpfD6`;UvcU!*ux zFG%M;;zzikJY#Ma+*dRw{5O36KLZg{PKRdp18yh*?7H-pG{vjO~l6> zJoRNX50AO|@SAE39{z^iHT>+N!nPtm3n9I?ix+V4PUtmUhARAyXg|A2PV4)k4__v2 z%joUOMeO5_JNDS*|J=b65O4@|DFT&QY7J5S z+b6r_A`u1l#?@@M46*%z)N_UgmM_=9ANqXQJM2Q=@g@hd#)MzUYGrPvisoPA;hr&s(7n z@}X~t^&ub7H?yQZnv$Ud`XC?reAb72K;J1US<`>f_CO!xL*M9?T>n@v^c`Qafx+7b z&mTcl^_6U3_A~Ae@}VzaeaJ_wuVe$Wzo8HEp>J#r z*FV+^eJ7M`Uub@S4&Vv-&=;~k8|y3Cz8t31#rhy0`a;%+ ze8l=nwl8lm^g%xK^|C(X1Nx?yY+v4J=!1Odi~fx3AM1_vm26)QH}pY1^bN5-+Cm`$B63=spE9`6ELg ziKJ<-V z&h?M=#`;ROFMn+4gM8=nqv59Bt@>eCQin#`TZ&#`;ROFUJ`AARqcd)`xt= z`bxGhZ#DEmKJ@jnKI9|TSF(LM*3bv}&=+0C^^f(&`bxGhSTce34Dz9Gi1i^KvA&Y+ z3#u*jK|b{PtPlB!^_6U2P;H?P@}Y0^{apW8FZ9hoMwt&=2h|q(ARqby)`xt=`jAmu zMH~;+7WyC``o@O2{;}RzA2QmcK2%%igM8=qADH)Q4&deUJ}*y{r%Ui1i_( zP3l9ng+9oKzG#T+AM1_vA)`&|L$!rI$cMfm)`xt=`jF8k^`Y8AALK)y&-##$SRXRl zq&`$z=!1Od8@-h4AM1_vA)`&|dmG1xKFEi@fb}6Cu|8z9Nqwgp`XC?r#+GvZW4+LK zQpxs3E+!T_aet5xeIe^ZK4N_(+ZVYBoTd-*p|6+qAs?~6lI;r?SL6O5ANry}u79jI z)>pE9;YGJGo{$fHL#z+^i1n3hU;2&m0{PJAvp(b_)>pE9nPupMeCQip!u5~!#`;RO zFS8AOkPm$U>q9!9wwUW5>y7o5Y+vRY_XqjV7qUL&Bi2{4eVJ$I zgM8@gWqrs8^qpL?eL2I>2l>z!UBdN`^~U;2wl8NI`XC?rhFBl+5$h}2zR)^-I?%pA zKJ@vl5BZ4om26+mQtD!TkPm&M16==DZ>+Cm`|>A-KFEi@fb}6CvA&Y+%h`rL$cMhM zMO^<_Z>+Cm`*Mz<5AvZeWPQj-tgmGI@^(WXq9u79jI z)>pE9d5577@}X~t^&ub7H?w5>GT+b#`OxRHKI9|TSF(LM&(H_?&^P+0T>n^atgmGI za=xJt@}VzaeaJ_wuVnkOz|aTz&^Puzu79jI)>pE9xxml|`Op`#KI9|TSF(M1r=bt> zp|6+qAs?~6lI_cdhCaxLzUX4Ef2=pwSF(M1m!S{xp>K%wAs?~6lI_byhCaxLKA-g= zAF;lY?aR9jeUJ}*qwnSV$9kdfl#=ZWz2`&+`gh2OzJT>1AF;lY?aOz6NL*LkY zxc;%;SYOHZh2FEH1NR5{&=;~kn^atgmGIve3{6`Or7S`jC%UU&;1mk)aRrq0eW1$VaTNWcxB;=!1Od8@-6@AM1_v zm26)wG4w$`^aZRB`H1zEY+n`|`XC?r#@@yCkM%;|@zcsRFiQ-5kPm$!>q9;gedQXM zK|>$pLtiiJLp~CHrM2PYhd1Q=!1Od3s@iWk?1Sez+7hNgM8>4yMXH- z>rM2PYhacc`XC?rLe__TB>KuVFqa$pARqdASs(Hd>npi{7at!+{|@=k7cJoW$9fZe z<=U4O#{EG)^bN5-q9;gedXGh4;cC&ANr#CT>n^aqOV;0a)qG}@}X~t^&uazzLE=g*BbgDANqXOhkPXZ z%C#?78u}m~`bOWu^^f%?`pUI0A2jqqKJ*2w5BW&+m1|$FGW0<{^o^a%^^f%?`pUI0 zA2ReoKJJ77Lm%WrANB!3J`#Q9+Lx;heUJ}* zeAz=j5`E>`mzt*UX5q)T{QAXoTw=|#e2$)TFOc1G;ePr?D>?AN&HL^r+^Ul zu#J!Vwuw(`f$@z@ik~e{o>*Rh`%m9XKxLD^&-Wvdmdd7iTsS;<#W@344q{AcUT+lM zg(HOgT_vAgq{I1}`8zgn$2h!0G>)9Fs?T4FMp|;i7t-IE!Zn>od?V_oy$AM>{#M0@ zi}>wwN2jR$uBmL%(;eL3_l2MCBQWki`yC|DduqZ{adsdF=^)2vIgs!7r1y0r0eNze z4sxIf^8I}p%Lzpy;7;$(=9L?Ihc_-em9yqnR*tM#IXJRSgk480c#e;&?0^EX?J?E>*aJicFbW< z#vzHOUYvsrrPb8aN!+sK6nRm3ef4oeeoU-z9&X-s;OSh4fJ49`P#=LFZ%>L)Jwp7M z#3Pq%`zZE87uRXM=hCH1X|GxZZI6iaLb1A$CLtU~8)AN{mKRpHfwQ6{*8fVaWjGlR6 z+<|9axKHFor6kVi$hxWsB+rKSe)=O@PWr~S)5$$nxY5U7Z;Z#4r0)ESvTwRsG>9L1 zE&=@LnNeaW#60vJ{;|uLn||?K<~v2Xp##^|voQH=lX*9Jrr6*-Nr&`_tI9*dv-zE0 zA9lr}?01|N~zA?4se3OGehL!s3=}mKvQ&Hw{|s zH){SicxAbcj#2H^WUZ98L3S*H?4qRnkx1V zI0PCZAi9xS^%(JY5*tR@enr_uy+Rc1qGw-xS&aQ_Rk#hcq#_jCMHDShzm}Z(SMw(? zQ##DW(TO5Cc6L!sj7yI=&GRb#p4Tt?bdp(gOcfXKLmUh^o_PEmiPZsjKiWq>!VrGK zFyAhM6y-+$EAN|EwQ6u^+AhMl!yGSDUJ^X0Z=oaWns(9l9anETX5o%aZxYRS zc2SmJ@SV>y%@+Z`Ms^XE3nC2ldtQn^*`CQ~ET*P}WAjQ9ruk2Lo~0ktr*DYmy{@9# z^W^?0X03{Li$ZyN=$wDFYIlOSC^tMxxzU@I>mSM2-^AA|eEp4l{SC?`9d!7k>G@B> zh3tRmK{=`rklMt*#E%Krku;?c3fUM#pl>| z)ox{T+>K{U9udxB0X~7BEuX0Oo#Hccd}?HYKhxEsuorv+KU+T0es_w`QOBo7mdPW+ zS`>p%;AhJx`r%IT89F{SvcR9|YEcY6fuAj(0gtCT#pjUYQzOgd5n(Ng!6)#uV+3Wb!$TE3ESc_ut3H)sN^x01B6raB1QzHxf znXVSa;1l>Y;uG`F{xzlNpFc1-GH~f&HY>Jg^v5cxG>4}`EeGWD!|-7Be8tV9nq|o@ z>~OQgDS38?_$`-TC%_@#5a=2NXkBiN*X63&$Gka*S881@!QSIdDD11nWuBj-nDQ{g zIG;OrLKp4kpJOpro~a@hen^0uXvh3BWTxF(H9AO*GcaF+aR9>|#jdl9im|DWYpccArFRH81iA+S8X>i67kP!YNj{Fn>vHLR#r(Bbu_V%!`r&;= z8V?q%%T49)6|jrs+PAb_B=axwfpxfMn8v8}elouCN36>|AZ-_6++mKFDKCDUn)((x zvTh^0DEie&a=m6S?Q-|tqQs9dG=BZK)bzW4uepsQa|BdY;#;?dOvRy|9-c6oKXHtK&{Hi=P zwu=Jn+EkiQJ_$~@4qMZX#67{Yumt8Y!}fwx@5fxIUWf?4oA+VAw^#uT{GUyqi1|tL?ChdhveIgU&8$mS?hyfS;{h z6n?4|yQs2Y^~mtbRbHu&qEXY3dmNd2w)9Ea=J>v|i;Bw=wa4{;&MvBtPceR_%dJc3 z5O4@|9RiwN#2sNWu1dh5?`s#?MYpUwn8(>keE6O_Z>Db3@ag(?(SAsr?+P325z-g` zU>Awct?m?d(d}29EAha9qmy<~uxr{b!nng6FH>F!A9YaQLPyqZWETZ&7x_KTE^4L^ zhFt{wTD6P7yU8=Ln$+JczjU4Qt;%NcIyxWk7fn;+b(OAL{}PUQzbqbDM+f|D?IQo0 zmh7SnhSpquNj5iDXV6S#BELCvrlk|I%?T$tyC}ab<(04OIcFDTF|ot5rLyZ1I|Lj8 zU4;O3i)tO+o@!96jjIwMb`{x}i%c(7o; zC?%0@GZ{OkE@^>wucMQqW!}{~Ix}qUxu9jG&@1+%n~=7PFzztN%fxa!*3tP`N4Mxi z_db5^Sh*ILN1ZmotM3Yh6=xR}kGph+l^=Ey z@Uyjx!Zm7MuKE4w<}6#We6W>;bcJ@&A7yW^l{2zl_&ut<>hApm2u8h5ntp^4kHYHL z-M9gVEH1z&i>sc7(z(MS;1F;KG(uo9Mc{q9RorA;m85;8_UWc|bfllw?G+s6xU;MG zT?jU-@f3~62mH|Q>TVJPKG;RTugEU4 z-FE@Jn>>@gr2c04RrzT=Ulg%j6is$^QF_ePm}mK&XvWXhF7hvH$u6RWbSo|^_YtFX z(|`gi+@myq8@#g32_I1R>E=E3a%As!xY=WsuD5L{!A^ujz#-5r2#9{MR;4+bNp;>Y zBD<(p{AjL&=476I@nx|-u2zNH7_4-Ac0ip37}q85!=xfp|7!kZ1WLE_&KHR}vb!Jc zqaR@iKViuGFx1_5A^enj&YD6(r1kGg+eH|6nB!#{`~X+gUyvl?B<-4Zk-6_e;Ors= zS&Un{Tql@n(S#Rv5%4Rri){B@0PiNxq}7IJH5e|QFABe>=8OCuXBR0>?Rh4<2>3O! zi>O=>VW{8pQv4B{sH5ahj)ddnoasB%JYj@s4M6sQ&8*7Nli3Ked_|j7yW`)l+~7Xt zhW9Er+Q8S>^Ywf9`rUl}E6U9gFHhk)5A>j%=YPWi7-ii;qmLDj@p{pse010OyfO|< z(?}3MRL+5)O*xm(?YO*jiqBDg9+A#%w}zVM6ZqNkiF)5DK10W+R(PA|6ZqNkiT1lw zd=5E2TjCS=+46~gxKn%vj?b3(1b()B`aGWM6ra70&zATEeztrDJTC4OpT6U>B|d?l zEuSIVH=W{hjO}vmrn=bM{CEiX+432&o!TirBgdy!ew*hL_%-5l_W5EjOz|RdxJW&B zD77wk^^lg=roDxaBIvn#8xQ$RH~6x;PdATRRHo{mcevHZrZ7kbPltaKFFs=}w zZjtx>Z!rJd;C;m=P^tgE;vw}VnRCxPhpOgFcINqKaa(fkp68q8eNcXF=AZK+sa3-- zsc{D8YcTG>cp39l#Bw{{SB#$L??gX;jC)^E&JE`E(^g##PC^ zH+Ww$XAjFHZPr(87t#BQ@(s#tBAlWAHT4s=h15^^F0hMuJg7v_UFO}Rx?1kRaf@x{cQ5hHMvw+nrsM-~R$rg)siYE&_h7 z+C|{q*+sz5)-DRqE^8Of9T>T6aJe__Bowt~ zT{Kgfbbp*V)6xmq<^*@B`|RX?B-vb2`Nz-mp55oMeu|^siP!4};v{a;b|>c&S!K_W zc1jD^^dqcaSGqchTheZ*oTcw`XTVKipmGO)o}0xDcjR1$fJ49`&TY9p-pBJ@}!%gpRCh+C`atTt4ddaZ%U-zoLFQiABEHE@J$O z>>}HJT)?}@GwDjkH(7q^I`Q7fF6w2wD0v)0{cG2)HC}&xDCuyMgmN8*a!C zzhk!$%5dw)_&8QS=7;vXL(HC$&(%3)a!e>-b~0j;`I` zL+clLRzLMVkr~!)AoANB;{Bp^X}bvH4s*OrEVtwRqJY=YMNhhQbj9PEEO)V8#Q3#p z7lC(^XVRS1-x}A;tg8mYC}*|muP4peLcjm!-`Ibs{Vju)&Ms<}XR?ccpRHZwAKj8& zv|wmpWM#J0S)D1gi{5IL+&Yphi_zzuT~u72sGipUIlHJnKE?Q1ms1zfA>a_`dIS=? zsNVZUy9k_$=ZicZf7yar-!7{6O#q>RbeTV?nD(*WdF>*ZMcMBuyT}Zevy1$j(smKX z9p-qsU3QVr<9h!=XBRco2g5D`ey!R?;N9ezN>w}TqKNIHaFMf%n&p}7BH(9h7loCU z?4oxK4qrO7S~e+7|0%SKj%`|0-2}3a2tMcRqT=$@c+BtYqQ)5I<6F0Ex{D40hk!#s zM?g%U?3~|2(=)00O`Ayew{(5yo-Y!%U<=&LH22X*T%pdC!u*OoAqhoRu(W&sW zs@;ihRIY!6a)VDRH~bV||0G`z`TEEC`gO|HHS2!Dg}$E!Jt*hx{vO&WuNT#Icdx&> z_KeCo@UtoB#3#y2$N1#uIo->le&;3lWc+OTM7{46pP}PZBeZ!wfuAj(Xumtf=aA#G zB|d?lEuZLzJH=<<_-u(!;AhKc#N(+>@!9M6Y>7|cXUnJ0n)srKF(HxT|D``$iGJ2r<+GDDpU2(JKXBy)66qbyJG8NIRqR6 z-G=~mi#yl*im$Iv0`;%vPo|)G5p!KG-JLj>`Yyq%^S)xOI(_=8>h4e9c`ASZ%nV!X z+ahmM`%|k1o7Mav=4&wSz<8N3p@VQp=9{Q*p(E=yntzUd$=^d;>DJ{o(+3kj@_T5E zAB~q4)+rvWzlR3iO`b^_IM3skuG4un7%rZF9%8%5pXKJCo8_72<$#~9T@>z7+AbOq zpFWB)3ifQAHsq8I{*I9i#Si;1l@S^6B$< zs#APMj!%s&okQKPMPV=a1b()B20SkA6rZDxPmL^{L*1`MG57?2wtR+c-*k%4(DA8} zrE{qJwI~Lkz|WS?i0#x)@j2x9)X35~)csl%gHPbsh|hRkZcmHz&+}IdFE6(-l>S&H zbwkIeLM;d6^YGxy>iLSBN7c)bz2D(xk5%&Ao6@+$A>a^j2v{Q^o(k`j^Uo6|sbcclG`{i2)z+BiH3Jel%WISW}D`f9rL*;N9ezq}lMSs#fv*^Vlwi(X!5zvCZ|Cc`@%3Bz`d{+(b;^x}8XmM~(1UW`?)m4y+5Z~ydK;$uwJ7W*eyE%S zKbvwc_l4r}(kVWD$EQY?&Y|wtq8NMvKU+Rg?>oik*mqSwl+AHBp3ynf{aGwfKY^bu zpJ>0!^O?V7Q>d%-90v*i>0aHsejb$n`M=^W~QEsDV>@U!JJ;_+0c z_zWGN8d*Arx?hW8@Cp2E`Sf{Q+$lbX9G@ClI)}Pni(>Ez{A~FQ*uLo$pMm33BTMH{ z_iIrMK7pStpCQ|+o#M0C@u`uebEx~ZC-!TXG@=y&%^zj)P1^nRJ|P8`yFofSY@9fmM*(4p+mqS&|L_K=>#|b+$!Z$ zg#i2@3-dVbc>g*4c>erzc%2$&V7><94vd#+u85BG{1f#pbY$H|^UtB1e^$`N_~rG} zS`_vYKQ#Xg{Aj$~%KS5UH+d#?;5?6Cx=!a+*({!a9(`Ip_m7@*^Un%Ld!FTcp^RT6 zyNJpK5r+DmoqzV?^)-q+^*7;IKb!XZS`clKI;G~HkCFvYzc0FqvY}$`uAJ0g(j9zG zwL9Twl^fltT>l2;2A}5ZpW^GE4k$K7~F=TP@&u>haI&z4Wr`%dvW>iE>i(mB-qS`_wz zPvB?EC))4wd}i~ap9vkG8XP)@x?hXJUhoP0Z23e#+$lbX9G@ClI)}Pni(>Ez{A~FQ zc|6rAJ_E<6MwZT@?$@Fid;&jPJ|i9%cZ$zm$EQY?&Y|wtq8NMvKU+S1wr@Jcr|=LFdtcjFnIL*1Xn0^=dz*N9KdKl?|k=MLrPpI48p zxNI<+p~h#@k6^U;(=~q^yz+TbbgjBiH;<~9BYVHY%^s`t^U*exU?;*M;1K8*1jJKe zH~-u!*;9o8{2&Vhj&{sH2OrCye-2iv`9T_w$@j~6+=213AXgrg7x-0wL8qyYNxO~a zp944ltRRbV%j>7LDC{MEX#N@a(RjI)`DgHM@=WS%cvfYzc>a0lDK-D>Kj`M4RXwri zndaqyUn9GS$^{XI`kkGBMja()lOy3cIcNIxxntrR?U8ufdbVfz{_|d@P!T5G{xv+0 z{1H_?!Vf7o`k-?CE0r5u!PnRD^;LX*M7cTQo2&_-u(!;AhKc$m8Np@j1qJoOV-P>}|fi1%9@C zMr_}7iqFXLsg>X6`2>EpeEMvsc8bqY$7f4?0>4IlV*WX-l%0P*V|dvzEvwCYlgBSc z+7pd%i$VEJH(aisuef9-12crKMSRjYU0{r>2=8+0uF&LLSVAE*IM-m z@wd_UpU)O?@crl3+8yyNt=L7CStEl3+059TK{J(!JtK3br4zEv@h@|Bk!pX< zvSb%_c99)US&UmMyDqUqz#-6G2#8@+t-6c2=SFr>uZRP?=-C%v?xS>Yn}e*_E+RQ< zT-PIxT&boV6o<{|W*E|5X}hQ$>vH|;^4H~t?@rrA77*X7lC(^XVRCHd&&o{2t%6Yrj<%VuvR6|}b3%Xy6 z!d}?_z|W?f%YC7^ymX4sUdN|Kmd>H>*P3H%8d*Arx?hXJUhoP0Z21g% zJk=>aM;)IUSvrThUyEY!3H)sNjCfq!DLzBTr$&~}q3+kB7<>XhTRwfZZ#u>2kmFM$ zOXpDcYf%h7fuAj(0o$pa;xll3YGmmg>V7SX!6)!*#Am!NcaK))pO2e6IJk0fxi@Xv z@!2djI#W3Rd{U#7&0Uwz{GxZM=PPa=RWC>OeutYqR_W)X%@tM`+acf(=w<|{TU6_E zcRf zco`T_UXt&WP~SpF)>S1SS+BW$$JJYoS-4{pxd#pG*cATqBsDL&=oslLIoURGFB+?WUJb-Cc(|Gcw{>f=+4ZA)d>C3Xln1iA_V>K0plU(rk19gX3uZx`w7$#P_ouGFua z?V|Afv|WU8hdEwumt7R?PkAG+zX}B#GU~SKlt8cPHx{DVs>dt3p5J zduN?5B8;a`Usc`x={ry5eOt_Mx%r}Zr0pV%JIwKNyX>Nn?IM4cvy1ZkU+TBB2kau? z*Q#CQGw&wPq&ca-$V=8$gW=-&qEQ~#2P>5woV}xNI#V^?5(_N-`sO9CF_I^D6zG*PlDq)rC$K z0sL@YjXlX$J4fz$gFP+DE`p!1XFJKTiy%e0(Y5*exI~-OxRu6Za^C|UcbMa4$_sE+ z{Rzn>PSS3pb#wvSMJipl|4o-^g(omgV*|Sg__b;mfp?Q<(rUxADx1Z2(a^sg#Oo!U zU6k-@@}1_GLa>W~Un9GS;uB%0-`K|ml5bhJPOiyC7;eHb&Sc$#vZqpKc1?v4s8!K! zk&bWTwC2+J@N8w@L}w}250o36q1-f~jGI>N;i(>Ez z{A~G*cs$i9K7GfhMi%%pT`h{iC-Af7)8}zMUfuAj(uv0t5=cwaTBg^CwVJ(WmC-7^;XS|O~MLmaTeqHWa z%a@8b76-*vF4Ap&i7p#HrD0Jdl7lZe6ty*xxjkAJS=L};663Zpz$?5-^aKE z<7JvFqJvm&$38AT&p!t%4{-aq$oc!cep*7F`a}H4?<+EXG+s{1Imw`-X1$LKcsF?_ zDd3#S8in&*H5e|Qe-79#issj!Csgvs``whtA7h&9C zj+ZGf2_6{JW!*;Wa-)~sI2rsl(+9&Y0)DO9Md01!net}Cb0fQ`_ge=^yVsxP_->YG zdS4OvHL{DSTo7TX-&mKc-n+&aFe!2HB^={S)}{9v=sk1&m_B_&yw3N{@<9o7)T%4? zn*%*W|UUdQQ5@pOl4kna^TC{2VDx z13xO~=6f{33+4AZ0*s4=}MvhO7EbwQ#S`_wzPvB?EXTW3RPVqVF z_|(WUc|=%?V(u_rh zujJWLGeyCE4*Emi|97x`nM`K_)F!6 z>-hTT`T9+K{d0W%v&toTc?a4v=s`JebuRk;lP=nF$-cX7d2rS@Hoy1#mv6bq%|&bQ z>t#XrYf;!s{Lox9@S}2WmX#+S-&5>=`2XZw^eyY&Ey}GbW8fBLr!2RP=Ar}lY)2zb z=TrAo2&_|(YKIn@1H6oXITXUiwr^74FU^P-;_<1vPQ zu6zADhq^zD2H>*P@N2{;=A!+cvUAbr3|u)l()=z_N!AM=-<+PrX@^ffEAnqp z&syA^s$P!l{SG&Ktg_D&+fj_242OV2VEiLM-6HmjQg@roWhHlC?>nxPUVq;%Nmb-4 zelL34#`V?w?`XubsDDlU#9XiJ!YSW7?{{2f{^j#{^?f2UTyL)^%o)lw+8?oB)Th-r z1JCy{?!b5%ToTLe*e@#Jxzuox+b=5J@9O=vMiG07ADW8>el%WgWiA@Ln>>>`aIW%4 zXDDxJR}F?yu4+|tE_&=qH5VOL>dzS}x#Rt>&aLjx-Z!2r0zX^3C|sk~nl!(U?m5Gk z4y_jZMa{@&#_mj^T@=4SZ6~KuELjG_PpR_Mqm|M|37fgzGr^n@rPOK8p55oMembjS z>UBepr~GOi5yj44D}N61;O6CluF;X!+ezG#c0*}S>-M}?A2(o;#l_5PIt+YqU(R(1 zI0PI5#RyFD_N0r|BgCIcJW$KFk7}*g*&+^&>C=0e=xr5=vN`J8MS1!)sXWGu&rp7H zyYM18bel!jVyR7fri%FZ39rl#1{|Nc>N#Pz0jJbHx>8I2cU(<7DKA4}jqWGYb`i!M z=6D%-QBu%PWL;GRlJWB1Pk&^~N#EFZI=ROR*LQ1lH6jvDb$+!7u@`m`@GG*54*%F? zT)z9ocZBccNA}<;*=q&7n>>@kq--Ny)@@`LMQj&Elbv0Z=2quCrZ@J$E&_hGc9DNs zS-a@%10$CWj#Or^Shgh2MN^)1)1W0a8(QsB8Lt%QhpIfec@MoD+4~)C_E@FsZJ8qL z(l`Vh0$qxL7)I5qH;J2f`{AfG|*T^oSazTWle&gLmJbSuj-MXfp`JlX! zOY`pa-d#M>Vjo@A9_Uh4`3gR+%0+mca-(aN>tCbXV6$qM!UvQaZBnj(zjA~7l$(~E zgwUQr56XG7?=DV~wIO-VbLPYqTNW?9Z}aI(&)M?(sfTO{U3->*u06X;mw7D;d(oZ& zzjS-1B3*pLw!XX19FXOA>C!){UUk5++_s^uOrGU zx>^+Wf=}RQ%P0EhPVqV9_|(WUc|=%?V(p%;AhJx?AK25ImXXlvN`U? zGbWD+XR*L|2>3PP6YnvGi`4Uo=GW`;y!4!*;Z=jnvKeZ829Jp|G5a%TS~?+Z?`VU% zPdC4cGSr;waBB{)G#-=BgL&M6@v+ zyuTYbjJRX|bdHO8pf@qhd1-x~`zVWf>0NTfQ~C1Ot9B>2N4eqM%8kCFT>mb<{$;-Y zCBFVQeEo~c%@Hq8p*@2hl=EiirOofVp75_f*nC6Z(k)-Q|6N=D-*e)n@IqFrHW%JR*89Xx1B$<^t)6xlPtA)3#`*d@yC_~M;4!7p;QqKh_jXN9y z4grUNEdu+Ah}dga&6*{1T#1bOd+mBnwmbFrl-ggY&6^wH+>kEwCofUH)jNkOrgk5x z{Lx)%*Hq*d|4tR@@q;J~IMf_hd+jEDF5#&EVxVIW@k4Xe5#vYWWra0GiFvS| zqXzFL&m;|;YjQJuH=3gk*)9sVyE*DKw~cw0&xtMPs9_g{XP35%hSz#SM0?o-%~U4+ z?97>#PRKIo->UAjlY7QybD8Gs)!#Fgav0ZnZaZ)edBt5ItlUoGmb4pry4_y8K*hNZ z0f)eNN5Jj1+YW|d6Ok*9S8T7{;4jm55ylUTGJF>(qU^c@MKJ*@Yc$ zb~t70Y#U0j6X6hW2y_Vo)Ga3SMf6@mGOkJ>p!u7kZ;(u%KAoROC-Lk1isy?c-9hye zi|;^6eWVjVnS%0NFkh6CXg6O}6W@S1;xx~z^s9NEln4&2oQ<<&58;P%7;w;h(S9FY zR9!W+Z{PY`e|b917nxzfff$D9KS-(Piut0?r|lw)JIwJi<)t0-MFHDI{wz0Nl>}H}cEP*JGigrhFXe}htgFgqGB0R;n=xR!$bZn;Ma}X|b`kKiwTr?T zE!jmYmt84|F7pS?R3`1*%$b%>$g=3)r0%nm^B&n;qF$>)10uBL(Kz#%zx^FYq2gvd&Y$9^S@yg8?eJ*VmVccPkm(znE>PzUz zx{cX)@>!V9|y_!Zej*7HToyU8>}W2YZv)Pw`3QM46dro9bP47jTR4HKDc~!W!}iZs=*OGXNCTB)1XD0 zr}^99m2FP=S#_Uo-XpKwXnfA$))=Gw`r3vP>_j*O90FZ}0CkJWd=cGrGOkJ>sQ-Qu z#$QSN`o8+}MTgfW-5InB6LRPOiL%EUF6^3?4siGL}jY} z&)G%w@hQfyrLyZ1I|Lj8U4;O3i^?wY)MSA+u1bKYw~mg|H@B9qzFkyF)aLn2n@IMz z6tNraqTthMy9nbBbG+OxyC`J4C|u<1qGtMF*hRpvRl5khn>kewMR~ zn&p}1i-4c4UF08F)-F1C&5}z8y=l{qC+f=_g?16`jn~FQw$tIKoLy90o*Iw&on6!z zqkMeZSdyJ6hk!$1oFkCfMUy5e!zdY7CAVIGzQ~JhlO#nwU$I@ZZR7gt9`%xD=ZdQM zE(_(mV7@4oKf24jd#tav{?)1CGJe9FT1SU(rcIx|O1!gl=c#HxI#D&p%2lmuzF!ovT@>8o?4o9QCc6mu+1f?n9%b#K`2)ktSEHDf zaSQFDpp3NQG_uX{LuVHimnW*H^?%MTs*g`Ge#HgTU2zCF1RMfs1a!MdT}j4ONz8h7 z(Jku^X4?egFG>eL+Ob3yT{}Pz8vetKuo0yG)%?jQlAMCF1AL;a?`4$}Og zZl-nF?B_-t)AKC-m_B`joXe(jN6HE0qztdvZ{n$RuV}X@&aU*wI4FP7wW>YxuTgIB zvTBFIKPWePNxA-u$_;+U*MGy;f2~|YbR0x`20bX}`^GVJ4=~EQ6ErmS6!1s<9v#Bn z?IvX*UFNf>5I=HWl<~7E=hQ!;ymX4ske}ydbKH$*n&%Vv+46~c-zh$a9G_ajZJtly zXUiwr@A7$S=ub!{CdDNmd zqW*b@TYY@e&xiE5Etg*>z#-re=pF<_H>~D^-TZTT(x-}~_(2K=9POBY4qwQhe~!Md z#u=Ee!MFqCWsI>XFYv3rgK|mzM%ryO{~WscX9Zb|o8I@ruSH=m@iR^Mfgg>R71k6X z=AqAee@o`w@|BJ70 zSFRyC4x&AS9+dNT&p(IG{*N&)Q_g{(O*yCe=ZMQor}zvUpDpnT{A~F|z3&vCy^hb8 z_ym5oe4_m>&!?8%9Ix;A)KJmK61rcD!d{FkfS)a&=!ZMS=NOL@vpMd@GdhR5KZ^zU z1b()BMm(PC6rYjfQzJ{~Q1@$5*b6>^pDmw0kBd9S=cwaTBTMH{_iIrMK7pStp8?x9 zo#Hced}?Ir9O`~8ioqxFv*j~nJGE1M4mmzGvUCo0zZS*d6Zkda6Z6mh(XGutR~D>T zT5@+NJPyv>%-NYUEuE0hi~R4Y=PPa=RWC>OeutYqR_W(PEtOrD*dgE$=q?1rQ{h^5 zzPRVt(EKy?vHDLkM)M*&@4irCj=zQXpM&4!&p(IXRO1ZH*I?X%@iJjTN4w^q12_My z0F{4>`e-c*dx;;Ke+GUuUT$Un8N8c3lR9v&#szeS@|kuU%|DMlrski6mG$QdmE7_E zw>h5ay-?uS$S$ICL4=`xr{|w#dltX1tfQQ8te;K$DNeol=hul1EyUUwQ8sXYls^6b zbF!CQBAes}&#H0}epk8C)5`UqQf}~VzWyz~{v==j7ry?4av{|p-8c2UR4zE-#(p(|3GoWSKl7tVJ>S1b()BqTY9k z&#`|}{ZKZ?-FOE4nQj&f)KB1N%O~3JPVpHzJ~gsT9ud}}uorv+KU+T04|j^sQOBo7 z7Wgw=EsDV>@U!JJp%;AhKcz;w)77FFd;-5ld}97NtdyRA z9$vn9sIp-7$coDbv-z<&Q#k*8jz!`oqR3}`(PQfQikn9@%aUE#;bwpt`De6G%B}ZZBFwGi?fojUsn0vZFFB-i<8}Vo|84&Kb8w#; zXJEbt;|`3Mfn~eqpM5v~EX$hulP=RqU#vx8FY!b3&%lqy%dN~mgLji>QU}gee&`J4 zGwn8-e;$q0bN_HrdY(|p>9)Vk@l5k_z^{>AMCF1AL;W`ApM@yqE{%D@ar(R-Iz$iT z`19tLsjR?IA|3ynla9{&kt!F#BgzdQR&KOSx&DKEeKTKwfUj@j>-Q@+N4z|R_6&MZ z&f7iz>^u8kqoDb64*YD&In6(#ymX4sh}X?%H`T@7=J^DEwtS-AcZ$zZ$EQ|)o97ew z+470@yHk9Ij?b3(1b()Bq95)QpF@t%miPpIwtNOWp6V2zf#b6!K7pStpCONnJH=mFEylvz9>crxNbcJ-Keqzp9 zz9UHUA_eo$sr=ErAH{9wF;xh|Pk3d1FyO%c+ta77s_y>uou~5mo~uUK`2I8PjjaFj za$BoL8`L-h^EDWEV7!d`q`V}1=~BNzN7hwyqRGC@+jm^O<(P##Hj#VKz>ZDPi|YH& z!L-+>-d9xey6rFFm-ox!fca0i9+;@j z^HKk5{$xDLcY$4$l4EBV)r1Xm#A%*a>G!;T*{7$37=fuGj2|vxz){XFf|Po0ts2~u zwu>wZ{6W)jqUUBlubs6-6O{NI?6QuV4TD{Q9*0TJQgyd(WA@GrOD2 zzWQO9fyupd=bZaEzjNZ zi?;p!GuRX9@N(F*8d5ZP-ltU8^VlhXylei6&BP``+Ax8sZ@JHc7`?AiB=Dqf}U<$f~J z-51Pit7gU-{UVlMUw#ql1p>zX+y1`dU3cD@_xEzK9=#o@brPM5eP*Rc>-Ad{NBv4Z zs>U79BP#Sgtir@YDoj2|_aC79_tX6~bpQJ*%#giILb=G__oQ-I&x`%OV$ywHRD&S5 z@eK8g<>y4t5l_~aQsL=y@hk{WmY-8Rx!;!x&k7gMg79SdImMI5?^5CEaq%n&PnMrk zJb4~26`s4vPShH;7e{lSKUscG@$`^ARVqA_E}okH=8h-J&ncchvWrWFXQzv2L3pzK zoZ^`v|E5%UCR{uV!jt9a6wf62sinfR(Z#bMJXwBy;mPkSCMK(OhjXFS)H<0~g)Gr& z3l;>L>mp5|mBDs>ynwQf6I5jEM( z%9VgCf&MOmJ$C;&^Ztlo-+PwxErNvh#Gd?IZXx^6i9coDe@=cw*%`cF!*&PT%WPv6 zYya8f?muhefqm}fYmJ1Wy#LJdLwh;(dHaNr z|7N;>qY5)*FOyi$xg6H>V(&luT>oE#K-X~!(ez|t|);~I$#PnMrkJdC&bj-ejcNNjkr{G8(H zA-lL#cs9CtYGCOY>T!+4h9}FiDm*J( zJTs3{h~y9zJAfd+GwC9c=G&UU|B4m zpApIaU8n`9I>kHW9Fe%*^^3CWlRk!Ij=O$QX1Vk&)8Z+zo0BU6R|5TA0x7@ffTNYA zma?l-ZO3P1vwbgj(xgd6^^5S^yuBP2p9tu@p9jBa*w-%i#u|rKJ$dhcPr=_2v0uZu zZu{L3`*kLX!0(7$XZ4HN?y%d-#qx_1WY>H4as8s~b8$LW>=&{83iXQ^cRS8la;pEP z{2*1M)OBBeQ775;p0%!Dlq=5Y7qR@D`bC~Y^Y@Ed!!7X{(ZF(ran660Dr8_=m?5oz zBsoWTu66yQ?E2KV&F}g}eak4bd<)QAm(`VkD}lXC0x7?!ukYn%^NT=WMfHnPc3nm& z_IST&&GNZY9&B)^-w}~*f%Fcq`h7+FwcQW0UuTj9{Eo=g%5F9Hi^%S<+sjy&l)ss> zk5#Uz>ps7iOMa2>lM~$UsOI>*IqnzvinU)vxZ80?JX8HAg{vKBrJJZ@cyxHveqWLN zBHt6PUzFL-V%aJQ@?Y$S=ock&-7h*gZ@(zi)Dp&@oX_{*VJeM(QCdnt335zKT&48M zweL}Xaz9zbG843zjbkh6C;C zYUd;+t6y}16K>};a?J6paQ&j}`h??g@2Be*^)8?6@^h}JE~P60R|0#x1d8Dov3>1S zmc9E$Xjk-d;QVSoCHbE17j<|iO^U&9+5hk?-1;#%=e4zHOSNs zq`_upyJyeC>Ge@S$R|YQZ$)z(zWtTo!}r@$8-*1G#e)_GT-ucZ!H{;*%f^2_EIIsH8}#@&uH z7Mkk6SSLKvL)FK!`$Zn|i+tlY1%Wte%t$l7+_ zA2a_>wC7T*U&MBY-CjoHCnZPh_;#j)&USm}jlnF@U&6($-~m<-bW zI=Wv&_b;dWm#HvA_A&|OB7awy%3(b(_U}Y{+~4WaAjqWSJV$6`5Jh~X|4;IBqUVSw z>r1Kd-2IaKyTU1?a>tY9=M+!w_oc!!>EfA!Q`&2pFx5yX%Kek&=M+yKze|N@r;Dcs zRwgWaA8%QHPVwYBsrNXn(#j_whS$%Bd zO1zP`Ulgg22b+!Y6VfZ=EG4U7gmo|CA$2c#q0*9hZNnUxapD%C<{u1KDkpzj3uY~PCCA-W_^Fh zB|(0XXCK!uvf5la)=HZCU-pYweop-&&)U5GqIfje+z@Zf`;A5G(4aMDsTMCnRF2!e zMM|ICeGgraoX1_cIhU2S-xfiG-7H)QxDwb~Bmnc`p839FmI)i@SNkckLVK{kzOU%{ zpUm$oCZ}2bBDOp1_A<)SiM?$1i|p?!`dq(A>YDnKZI0GRD9U~j%dgP=BF5d0GZyCr zXVtf|f5*kQPQCZzYf<)kdW-g^l-zK}_qbSoefdSG7YG>l?_$2Mct{@*IeB04wG4Tn zekB&DaVI%ng`RmT^vzLW;(WS4i|+gA{!F?*LxmZ#mq{oWe7}v$VLdPQ`-;2C|Ib#B zy(>L;J!knj(R2C!Dd|h8@N9JP)KoTiJXwBD@#KDADm;BIo(18_@^gwOkKd)jv%|?W12D1A-&g#1KbMKAz)$=5Gh6l|Xn4J=3C^E<3VgOC$lHt^`~O?A;Quyss!f^^rcW7>4T?^{ypH!EHVv+NWRC_wR@}`;JR;rPVKD zyTfiTqw%w!*#y%LPqUZpev$pT+~i->cU;V@_UedkZ|U)Lp|D@X^2_EIIsJ|c<8H?p zOHTFQ>^S%37kS7pO3ruvqI~=!mY-9I*bYqhEmz}CqE&^-mbMua#+uc{k~$O`@Ey4t<@=|kFQvkB_geS&6;pufW0f9HQE&|V8;)Bn zKc{$dzb_S@Nf%Fs2tpl0J+6^Zl<{QwImMI5?^5B}>Efw@rDLeaH4+=1EI+4s@;qEB zJQFUS8dy4pdR!y1;mPuIif4lCsZ!zD=;En?rDLeaH4+=1EI+4sCdn=?6`np9PYo;` zLp`pM*zjceImOdM{!OXytZ?zvz|t|);~I$#PnMrkJbmP+mI_agi>C&bj-ejcNNjkr z{QAO^-&gc}H~;~e_ByiI_v(kKfQT{q{#K6WKgZIxcjKO9yyP@a&s;#t6y4( z>bktH1Y8O1T@t`)vBQhMoybR~y^Y?V%QZ6Yk#K(LVeh}MDBqw=XW|qr%X0GjidgR~ z`_Gp8;T~(IHgW;^ghv4rpAfY?m;2`W*>GK&-&ge1DLaGrYuN5!dzssbC>P`R6@9e- zoak|XU(q`6>hpEF1|dH9J0dJUw3jozujur-T*lpwGnUMltNLLI*3BCBwg22n`=`Dq zdfz8h`S$m}I<|T|z1_U-&+>EX7bR}Y+b;?==l=~CY(Q4O=<@XD6_O%#&{yO7McKy< zUAHpFUB4)^T>6%2A*$>0x)N|Du$M^y%&33IbGf=yv-?FzrR=)Y+jTl8#4SD%T}u+= z%i(tt$q>P9d>&e>!Rd}`QhA>Iqd7XT#x%)t`eOozfAMAMnX~ci&%bz z`bCVp9cL`g3C>D4v;U6B?$4U!_kj{?T)#;57w0(3=i5krefdSG7YG>lZ~Jq(Fm_}d zdr}yu>l&vFKb z`KhJCv%i#+qx`ii@c zn$5=UJ>8XC@AAoIO|&3wc9~rXxDx2k5`cNJ!#fdL_=PX1-N#IO8~9vq1)R87ihI1< z{{ESK)|A7(1!Nu1di!Pxm%o4JOmTj-pOO;!`s@C)@Bd}qe@>jO>Gb9+iq_jPrLuZ1og{vhSCe)X(~)iR$+3I3Oy6){&>2765T(M?w_E-RIb(-k7ryC>v^&FpOdct zuL<6+-+Zl+P?YtY<>y4tasQe1rBrw(Ts$?f7(aWck=XEL`8mat`+ceKY;^I|z_R1W z*BXfpPnMrkJbC;s6`np9PYo=_&mL+dHauB=PVwYU7+jl_m0%g-sE zKC-7ug{Q~GQv-|fvxgdq4NsPzQ#=!77ncgp-Q>rm*LZJCvE#_s>9Sz^mgVOZ&m{Rb zrNT4m;;Dhf_}N2^grbZm%g-sE9`aL5g=eRWrv{cCN50lbY+siD(V(mZs-2G=w8?(*P8VN-aANjjPBtNv5 z3)z2W-0e7Hag2E(`_C2stL${&6Dp);?4?0&IOF~^%daoL2=xL1_n|mdvP@P`IF`66i*M?Q>DT)>EfyBZ|-=q{G8(HBfGd%cy_vY7KA6u z&ncb>@^4CoXTrs^AUs)qPVr2VpIRzB8(lmL!jt9K7oNQToVdKe{pT6cz;dm|IYhJW zKiB1ui33u(|Lhx~)>qtp)NFHj@9D1GdY4aXzu8XbKto*;R|2jCTnQ)%?5X?D+3?vb z_n#C0nR)*?xv#P_c)y124z`zhFS1zs&mMRGS<_4V+{@P*2}ODTndOJ}av}TAjJq9Y zERHcRWdC{h-<6%7SmW+L=VEIi&hq!4Nq&9#MM#f;asMvn{&S|^ZYFh4)_dRs~0J{GL73%fT<2;^mIjrZ!-hcMF{=X)69>46N zMnX~6bC#bIJ(s`#O!`tPJUuR+8d!E5`C22f;mPuIiYNE`QsKG#AMX5QR^%2KB`@poL#$eb0(*BAI74K?u9D>R|2jCdXvDO zy8pa?mP+rH`_I1JnfIR)e+d8N*RUbP`!#HLu)WNCk;U47PX5XL{pXZkW}Bl^6dXf* zfHB`oM$8=8r(-$Up;rVAeJ3m!+dh%9x{XgBt zV%(MV^uN4L%<}8YFG6|*jQe*n_n(L970VEJvj5zefe-b|_n8`Z68}_T@*gVn{9T2< zztR1_(EUHr{Xf$EPgIy8dzr-J8JEL)UhMs6kL&+y5U^g`Lyd%@tmiC0CweY_|C#iq zRCp%oxsUW3?~N&T9Qit37K|s$&nceV?@NVer;Dcs7UO3RH4=(4o-9A7c=GsNDm)V| zo*Gzo9Qj%!vEj+`bBZU=!==Kr(Zy2(i}ACE8i@^0mY-8R6J$@73QwPlrv{cCN50lb zYE!9ac=;Lf`Loar~t(p&5} zMXvQFf3Mb8+pLI>1(5o_0%PFCE!ZHmB605|D4*MvtqPY?mv5en|c4) zw@uj@XphPF%gF9vdztqli?#opaQB}zZOk@DYa|p!d~pAn<%jliO2IK7JUXg2|FDJP z)!tjywN9aQN=rRwz_{CSMta6v*#?+m=FjEy{rk^H4uLNilagvT>3hxI&jo6_}LWyimBZp&P|OuGKRCXGxw&a&0WAj*2q@^hl+I6wJF zUrL2%!o^bqDtA0teopb^eqSm)8(lmL!jt9a6i*(%ONFP;#j_whS$$#VcqUyu zHT}&UPnMrkJU!&6mI}{K7tez5Wcl@l=lt1*(G4Xfuk*_Hb%$NBC4k9sekIv>+9-|581`EA>Bk(W=MkLj4tLwuay zTkB_g`PBKCj`_M{N`9Q*3te6>pE@7YF<&R~aehxdInm3f&c}4j*G_z#-$Oq-*2|~P z$8^l+BR`I5xP`GIai`_!rPF&*=*CO*#Z&edg5Pj%{iOvikU z#K-x)yJ5o=K6O5(W4_agkMl!X{owx2bj;@=KF$xvh|m6cmG|4X4yi(Z=3_eM>u#a` zNBp?v{`=ouVcGX62Y#kwzE0xf{0womxAURnyx&M9OPUd4e=KHjn`XBM5Jpbe4 zI`7Y(nq=W)I_66fALoaBA8ftY`|PjJvhXn-^Q|U6&JX!sS~tym%eMwu_?V9Q8i|kd z+uFUvd+RNOy+3*Uaf>{ej`>a}KF;s?=cag*ue>717+s!B$9x{*O$-!dKZ`G}A6`_JDtc;9^Ed?{1CJf>s5GUDU>Hoo&^sVms$bv~wJzTIK! zf5iXd+Ns_re>%Zyh|er?VLIk}n)o=sEt@a&!g%fd=@a8E?PEITOAsIDhvT3u4=V`= zAm;NzRTq?9rJykqweT?=^R*Kn=l9KT90nh>n-hLI_7(t__$oO zKki$z2HR)hV>;$b5Fh8qd;kCZ$3HB5Ovijnh>!DQK9mU_+>e-!`6`Hy^OJluw&;9J z$9$hQQvV}<&bM?mn1&UkNH%6Q}tvz=37mCoFCJpe(UvQI_7I6KF%-2XB|J8 zj`>a}KF-hN!@}TTc`_aId5Dkm<8fMXrTCbR`MMjZ{}DgTVN>w5^D!OsbrK)v_vv5T zyy9P91(~26mYKJ@r50|KtyUsFF68jgRS=?`h)W{J@T!0%LrYl1)l3Ovii) z;^X{KhBx1IQx(=%mnYLP-xA{E{GNOEY#b-5{_y+XTly{2F<%Aoaei0^j=K*&@PLJn z>6q`+AoV}u-_>*Z6g=;^eT0RN>6kA`e4O7We`xmp?Jup~KYpT~`(nLjI_6tVe4JnR zrp4ah{wC<{`S3D}T$qme8i|kd13S=*Ht4UOIm5!obj)`;@o|1zySu9%f9y+OgU+<@ zF&*=Hh>!DIb^Y~KKYsXl?-M^c*}}(k%-3B<{g3z&2ibRRb{5kyUnlW#e&4z6wyF(p zy;b$h(@$G)U^?b&CqB;anWs;$y7!)Y>8rBOM@+|jWyHt% z0p6f5J?Zlw(J|ldTIzq4j@aSY0)CuDo=nGlPZJ-P3+I_CSdhWa1zqmOgX z-J{d|ccx>$B=K>6IJRJUcE6wLm~S=laenAa|M33%)BGx?W4=b>AwJIUfBrin_2rG%W?ArKI_B#RQ2!%-T%-NVpJLt{ zR_$-$V>;&RBtFg$#$7p{p>FHAGad7_6CdXXxO+h+VDr9U;bS`H^AR8C_qFTx^}fGx zA*}aU?K-AozB1zD{N(tM!Omhj=G%Qa^*`drHO1S%Gu&(Ur{VLIkpLVTPb${*Ji?Q&r{=Bpq+&JW9zwu^1tWjf~j z)KC47_)R_)F~?7)W44dNy&R`aL`r%RXt+O_7~cJ{QYWcC2^eNQ@_J$9p1{%ZkD#l*dJK; zKzNKyaj7vgb&WASO^+MKHLFkd3g4MBZ=@{y&4bU6x%{50ADteQX{**B>pkbpBf9SW z$47E(wYH(ddo}PQ57J>lm>2RR59S9+6EQF1@A&gk`#gKY+pSYh9d*iDRWECOh{vpt zx|aE5Oxp+A2InNug{O#i66T9(cnw|nDL5ZOI=lwD$#5PI*PV*aFkS%yJoZ<;eZNhz z-wW#d`vN)gW~!&+E7o7nVJFIQu2}i)t@+@*@(DDa<$0LI6B1s?BoQ6k!Z3bw{rV|y zg57!0<{!%a&`hOeOCuG`c00%PHPy&q&Sx}#<}shO)&z}~#$YsF~X3?x#APIVTb(pNBcohYcv&VVe`lN6dXroE>Ut zj2Ep|dPd9iiz3I-N7@sQ#Fo$JoS03PcePws{mUmiye+?fw%SU=V=IRGkxKu~SB~{w zctXvT-~8qe8EEW0`ZdP&eD%0tocjCQpC5HY-23~1HP0dC_WEEkJ0{HyYW^yA<>1!#`LG>DsXVrCyN z)0~*fRmD81PgdA(<#6pObLYey#FdrQoX<#}pNILZ6h7YcsfKYYWXx-2i$G$i?@o{D zQ%kpI8FpHUUg>1F^P+DJZ)Qvb>t@=0gML@7`uY&KegP!V=K;Sp;saWw$0O6&qweJY zw|wfPNt3D-f8Y5(edMYsci#DTbDY2Jpc}lW-u#exoqs*{OwQSW(i5PVJm3Eos+o(P z&YoI2yQ`^4B2(=_?Df;0`N|o86aPIGv4(e7)P7Y4eN1jvcG14T4r@wNMt$KEkRaw; zU9EB~udY6LKP5w0qEu^7*hf0N+Xm079x-M%<(*zWu&)4@e7l^aN=(Pc|Ep0ATEFJ40V0dCz8-ei ze?O1-;q}v3cXa9Z@tW`d<*_>~{Cut7*ZJ|j&d+jTdBK8INpVp!-ShvVTw0)-JpW@q zK|EkwE9t@GAs2%6D2IYM9Tx=AE<+3Ui;`%pte3KA$I29}r(ukh_tl>4SlP!_-Nzc} zFEKs#L#9D4H5MpdrpNng(NOUs9p;bsxh%9H24k`@&NvYMDw|@Q;ej|_V>;d+L~&fl zSM$g?X=5@yrZWxls`Y-w%k+33?NZDWL!`qv-siGVZar|#^Eu+@WX!o>@tgqSp6}uL zb;?f0JPw0X)iraDbI*-5m(L8;2EVj87>x(pGgD**NpAbOBx`ypkIOG8OAZh6WcZtPRx(_@IIy^FV+Lg!*Z}Zq(ge-#r%*K>xpzok9>F!al!G5 z{k5ARj%^zSC$>4;VU9c52>M88d!EU#9=E~;r&mBFu+DgJJuu`rwu9qHhjFYoww>cB zCywKsr|9=J4%g!4TKs5==US2-|6@8R4<3mXG}OQ()wr`9at&91oWfo1gVTJ(<2L8V<2hgVME=J%Zchu;E^CNJTAOn+rt;(BTA+=+ zk8vHG!ai=Vqj9@xnY3p-&#L)}!&DAVV`x9^x#M#mo>%R+w-(+AjYRE< zIb0XY&qeLa{WoqOw+kyF`PcsaTS-ekO7&m#wYa_CqxqVB1PsysH^+C<2U9<|pOD@# zE(^g%Z*GV;@^!9Zq5P@xXnY_3>LX~Er{?vU;Yc8!BFiz>+0XT(Y?oC(xV^WNekgH~ zUwCwUmZ=}453C<7R{J<|VX&~r&I{$|dV$BG=Kmt=N5!A|_xREMcQrpE?l^vMd#(C` zd*9cLo{yq`T%HbruHrjG_{07%?fzQ#h3%FVGvHp6kVDduM~bqR#54NeSulP+=}YFtact zeddw;^RU!9HB{6+Mm`Z`#@inSk-xZaAx0Y(7U!T&imxq;Sa-lmZD zLp&w^ZR`DUleYv%S)FPJ>Ibf?ar<~(%|q?97k%rqnfF6-?X66o@0JMehg=0`+J4Bd z2%oc+-(atQ?$`fU`yp8F2XIb?6XSQoxfxFDvHB(3x*D~g{T|QLN*-1&*w5;>`ynW+ zmNYrp+rOt==R1C^-jVWqdZ7O@&L-}^pngF5!0jz`Kci57u1E3rLlF0iKR39u9C8hp zd}za+a5izLagX(Z^PdrlwS-{!jOLxZ|@)+}`g(-_LF)Y3u2v7py0YhllisuNO6jYL_(!WBJ<1h4OPf zz#@@);wkcasi&W>m#+TQx?ald?QOjj?LW5n*#2W2*e>L2JSDl=S zpnF?tKEQnuZZGev;_p|!@s~TMBwoXB&uH@i>4T{sPf-6Ly?`a$|&>c``xAGUEMg>U(S zKwYRcS9_sQey;pJM)enpYfqwn44huk&-G);mXv;=J<090+LIl)CJx`X!0%(=k(`F> zMLqj~y+C?l>dB*|C!{}$9@iOo9LaCCDU_e(Ib)1pJygbddmCw zxz~CpO^Q{U`a$|&>PIK(2k8ytqTxHWITVY)K4QxXzUd$=ls{EODfHvJ(~|vMKUTkQ z)emm3t{*8GYjz0fgQ*`sBK;t}VV*g`cpw}O)$(<&VWIq~@=Bo}i>7tf1% zy?yEj>4T{s50HM4-Y_l;TY|N%;XvMx3KYuE^(c)W^Xb$?Ki7}4jaL2O_S*DA?yXz= zT+#>Ol|Dv`qBN4RX@1BHvJ$mYx4`~gQ*{D zNIyt#7?%Z+)`rFc*24?s=X#VzKjyFX^>h7Ly}_y<++Lf0q>mq@52k*6pY((DhH){C z(mYL&LixEKrO}T8>ni%Wek^(0svq25n|_d(wef@W!PJj?NIyt#7#9uS@&%E2K>oHJ z-*gZb%AYEt6!vM|I!`~>kFvL{`oZn(Q$I)_O#Qfv^n>(IdnAsUNFJKS*yF7m07a#wlb{C_mSuH1o^r>yrIkKUTkC z)emm3O+V7@57GxyKfX))L3+cuOb-VG(c1jqFf5dx>rop0`0KjPey$%&UbpH8x7Vg0 zBxcS2Abl|P<95;y(i_Ib#22iOd_0*#`MDmY(T|}oCi=O4l)Yxv4{oonANU=5C1*`P zNFPl7xQ+CK^oDWCYtx09AuN}lQ zzpR{L?!S;enEG)m=?Cczc_Ki7{XFI)A4+uNspkUp6DaTDnW z=?&v@P61;F=20j=*P}Gge}rE2^mF|vd&#OF++KeEgXOD2&Hf;LF!ke`q#vX=%*XiR z8^ZZ~$fZzzt_P1F#kD`Kd2x3?f8M-%omD@$y*z%fUdT}YehcY?sUHc_57HaPWoo#k zF~ApjgoW~_iY$Ts(ecd}ll@#jRhq5Lh2)OW&2FHAkTp7ezD zhdER082KSyC_mSuGIt{kv7V4#n0mtR2a*0TK8pg)4SBvIDYGb) zpX*T?J$dBC#(u6ROa5uq6K=0#Jt4hdJz+dNq(6LJ=y%}?<>z{o>br8g|Jcv>?f#t7 z6MU|n+sk$d%Qx-2a`YadT|bzf!@OQ#!5|6MtFC$ZytcrUSkA7%fW(vQ=j zsr;RWY~PjR_hCF2?r+2lu`?MRy*T1w}gvMPgE;!OB=8u^nDu#^h z7;#`>^{DyM(vH_IeOA2Te@?t{*>mFcOP&?Ui=PoMU-%2LcHxua*}0F3pU-+wJUZP1hBb&Gx`o}2f$_{FRriN~hhE7qKGi@5Qmm15c0rDDP8bHtp(r;2%FrsrIT zQ$|gw-WYmSydQo|Y=RTR_pW$VY;1f**5$35wNf6hf-GLVK-J;rz8{H4s_z!}02ZrG zh>Myri^SZ+rinSDp$_G_)nQZ9Yofblz1VW)oAT_wa=q9bc|*Jp=^LRQ?=-w5-l~N< z04}dy^bE-1De>z$kBX;e{!lzL<$L0eNvp()V;jYVqt6qwM^#HX95?u=4kya~emE(% z#@-U!THhAi+BU%Xw%FSGme>-1Q*4f|7n>qbhh9 zK3MsV*tX(rv1R#NqC37`yx#(K2)`mWG`uL@40MU)CBITQ%zaG!?A!-LXVv$_cR>d2 z$25w?hxw!oW{<8GXO&It>P-esXEtB`My$;$`u6P~q^(MI?jsI>lpC?-k!a?Pjs6GA=GZVu6@lRxQpa8T8g4 zwk_Wvc3kzI=(*;7(Q_@F*S{}z+yG|+>XFzeK3Mgx*wz7cSox;d6n|Z8Y<^X2Xnawu zuK^h>{T1oKBjTqs?h_B3^&N4`$ybYT`6Xg**)(zfD6g0e{o%MF+4W%iS2oJBcV4$i z?7U&K*!fL3Z`mw*zOzZ}fb+v!-V+}r-Vs|n-WHqN0f#G-;vJB|TXipp*FX&s7wU-}*rk9hAEcb)PL z@zrC)V(}=SIB#SXVBi&Jj+~HD2TmI^xw@z0eX;XvQ1;iM+?%(EkG>1%eOtxHk8Bek zJ+@8kd}xc)nRHN=f9)o*3)`OP79ZULW#0*9|7e@|%}=+BkAJpZ?0Rgg*zp69!7cBK zt=Az2Z;1C=QabSJ(r4tj{LJ}37LP+e{K0A86044ni%Uk&6|+W85$8eqXB?WP{pHYp zSw6HK+W*nFp#0TP{sY^@$3OW%eEj4GV%H;EMbG!`<%14{UJ`Fg9fYxH;Zx#QQ2tM* z{Xmruec+PAxcn+{Mi%*_Ogd}s>)N#n%7^yvx(Ukv4xIOH6(4~NKI+^mcHZADc6<-y ze{qZqz(P8Hc-^jDYd52YrV|y6~J8RZ-?L_$_{@;M} zTX5bE`gbSj-`${p-=jXT>K(D=t7;s05BngDL+fE2!ubH_#b?fYSUe760OEgbMT=N8 z>ReU+Xm77$V9V4iI(A+U<=+71LLGKO9d_Obeehe*2fqb<@W%JV_8VXfxCX}|(Eljt zUl_`-hw?86{ewACj>EG$#iKA6q5iKtCM4#LoGN@}XN&WXsLrT+x;}Q+-q$7jKK6e& zdv4eSCyYU>U<~>ij6pCCZe97d=x&An4|Bo0S3v)Rc^d75moJ3=H~%N%=jZ-NJY2O} z+&j}tw*oK+Ujk$A;$Mj8 z<~}ZdHuC}TqqFajV}H$&3&qS)XNiiTW3SCry-m%( za_&Ri!3KE+^=_dW_s|x+b8$da1-gVQoYrC#Lv%PEnQNEIush97@iz@;1JIwTZ?D>C(`K0mV zClt4CHxy}s!u|~k^}S`>Q{;U`S#P+;Z#J)&zd_62VNSdfb1U>adWG_HeTx5loXUCk zkq27FS1zx=gk?43<@kvGSMDQGd-?geVB6(q;kWoyd$s3VNFPl7Xs7-`dc*QbeZPiN zatjOPPnA~e=bu#0$$qXMtNm8};P&!9W7g-dNgqu8Xe0fwjUy?1``dT;lzw>1`}g>< zb{`1mBWZ__KA8FuCH)}1VO%tP^LnMLP=2llKZjks@4c#=J*V_<{pen5)emm3 zKF?(Q4j<`*sUIz*AEY;oi-xcHNs9jQ9X{2<#N__1A4@K>>Ib)1*AK?p@*OSG2U9`Zx|QGH{Va46w1%_DAoAUcufD+kJT60 z^n==K(+?7}whlu2VCqLB=?Ccz z`e5qE<)j~^H;hZ6-_a|SpX*U7{Ydt6{a8KUsvq25n|`F*AEXbaeq2WSL3+cunC}O3 zLXKgf{HfwfW1sHs=l<=Ic~<@4_S*D=#H`sLqz|TkTtfOmdc(Mw_~!GGB*>&tey&H! z#*cokA7yi``jMpe>iUuKJA9-MrhZ&Z`aycbxa76z!psmB%Ad+gjUUDP4vxw>(a-gx zd$v_SxV@|&D20sQ;Uj%8^aC`gI57GxyKNgXGklrvZ z{GBwu&NVEQpUW%N^B=x`?!T1Hvg!x7m!JP&`KnN}Pe~t4{a8TyL3+b{jBo$@4xega zML*x)?>^V6AKYFZKUgnhsDFo#^ug4R`J^ADH>@9pen+oRey&HU<`-W-*N@dRt@^?3 zW&Ozd9X`?rQ$OaCevsZUF8O^`jkyh@P=3y-_}|S^Id}GR`*g`UDgBV&;iL9ipF?FS z8%El9kw`C0J(*2rpB_N%nI)wQPn}Pq@8~^@Q}o)DwO`i1df? zDfByfh4OPfN~I^e`?xC-ALrb^!|pRCn(x=)`?35!EWaPi zt>^cG`TEvpKY8@8*WmA;1?qy)xskfyyw-S2YkW>19*l;Ze=(Zr%N09k?>Jlt@5f#R z=VxGGfArvJFQ1;7WFI}hQNB0oIK!-j_--to1K=#(`>|Pz@8ibmi)`=5Qv138dS)nj z*t1#K8m$l12JOj?uM6epg0TPY1OGf%?v~$UM2%V)sa+O~D-C11{u<`{e*Nl$hspPU z&G(TAXA}2n)DK7>SbmEm;nt@7VK)lp=X&gC(0Tq!+9wjE9Hxhp!hkhH94; z@Vo4V@^d|4u2u8G@K+zf@5ZF&g_+^}f0YxyRoBng5tjTjr6*|jb9;NU`|&%>JP&32 z4l~<7fiI5zV)X&z z4yZn$9L~{j9t!6n2UO>gm17pqiC?TfqErIf_RRFuCzQj~9k6T|mLiZL5UiX-1SR2=@+2q}}1uL2G)f()J;Acp-M z>hQ<_G31^BV(_YgVsOnMF=Q^t0_sqfV;zp#R3^rDj}k|387+?4a=19A`v`H&<|D+> z?;kG4Z5%C*dS{e4@~uO~=r=$opbjHI4#R#881fL5f5!kZXa&^aLa4)R(2qI8 z#lgoN+~Gvo$Gs0_ZXGR-+jgWlep|UXVcS@7;?|?ZiCc~lCu}}i9KUI-ICkS0G47qi z#hACs#OT+dFT4zOcmd@9G?f37gT>%A2a7@9ggP`p9p(ZSvq4UCMu-E3?_b?p9S)rQ z#p+|X9wCnZpj@1|{b(_Mdxe;^{X{YOgOkOn+s2E@TTT`eyH6A+y?>lIe&bki^oAqE zm^YygN$7tsf~*0DAwPriJE8pV!r2aWSPXRl84Q~}R17<7XjgCLk7yd)al-bo;-n9c z6_a+HAkO%3qNw`tbTNJV6fxriub8%NikPzHbaC3|31a;FmE!n!$BA)oA0du>W26}M z$}p0_L1OS@2Z=%7KS&H*b+8zCIn-e`=;Zk%gI@aNiQC4BlXn~|PU$&OoZT~7%;@oo zxjSZw3wC^2T=?NavFL;OV)izln6_n#IDOM3aq`CF#c>;s5=X5+Ovzv!^uJ$2`9Fp7 zAAs_2finzsmaHZh{^Ad7bm=Pj5zwOBg7G}jT9qa0vSIC^8eX^Vo>LSV&EMI zi2-d;{sNG}`7lNR2HEs*z-b3ppR(gbar(~jV(QK_#k^g!L}1sYqIFkPd~MftBC+!Z z(b03YXxZK@F4=aGIInxAIBV0X;^cQL#j$Ufi!pDMiBT^P6T`be|9=VPKLX|7b)XpV zRj9*a(1r6rKLLZGXAa4z0|QSRPFrizO`S|nONY7*c4I3e!+_#Scp$M=cV zyS^u`@3~Ga+ukS^Zk-Q0aJDM{9Vq`zXg~Br9E*nh3d;XU=JJQ0k-ZOosk5RB%b&Tc zS}fc(S2TQ7E3W!zrMUT{o5XD&eOr8U=QqTP9m_@S2bW77tlE5rnDE|-qT-#SMERSe zpnQ-&w12Q!zDEqW9@>8qwBHBgBeehEW3!KgCv_g*<=qMWeb*E*d)G{H(XIx z+Z7jI*||cr_QXWvhe2`S2MfiyTc(LKHlHF+daptpvtf)FvmW&C)uCeeTF}2|JWBqE z|Fv)~0{!#B7=7L_@x|fUZG$l_hj&zi?oZoww$#DdJI@u1cYax1w)0{U=($W>wgY}= zVf&ZGtZg&oI5cU~mqg`87=tz(E{<4#h`{-1*bC7ApN8@ug|?&quLS*@3w_cDbN2a% zWYj%fA18I5)HM_O{y96V7ol7013i zMwGt|_Q@My2Z3EMwCg}I_~(HA!%+V1P=17D?;9cp9GiXY;W``>8QU?h=R7e7+CH;q zs+iVumYBNZOyPxb_^j=daS0qXgP0qt*`rjbhP<^ThNIV9eh-QHtKVt1p56Pl>ak0e+1>; z0+@phGIZupF{onTHJooQ;qr&ux>ommPh9t52lTmsIDhN8;;hZ5%DE45A49m~+;`{; zpnFdb5W^pZIp|KXJFWzo&mJKLR_0eW*Yo;^ukX65^Qx{pw%;z6Z*3J9ZC)&JL`Tz`xhmpoD&zHX!#{cD(mpEyJu`U9|kuLXU$B=b1S`Q{Ryc-o28*FAJy*Od>n zbX~LQYEkp9U(9-Ira1kz$>K{d9WRc3cC0w+NtgrgA1w~Q{xC7!jOG>^kPAab07sKcZ{c{GlZ)(@DKtn*1a%YmQ+IIRN%IFIB%!xf!y_ zWnEy_oCU#V*vTqi5RA2k14G_L)Ba(}hrYW4ejvTToG z>~DM_r)sqC>-~xO9d~4fGxKlJPcYuwVXjMS^qJ++TQ2TBR|2jCTnV@ma3$bMz?Fb20apU91Y8NY5^yEp zO5pP-0bCb=mkcKg}L$%xjfFF%iB%sf1OmWEN^oDf?UAP!UXt2U|>rwm`TwXtYFw zwV@amXy&VKRJKGy&G15)(GZQawiu9z=R~8jIoJ+W1->>zR*oxK9}YAa&4H%i(o>hwYpu*AG#uff(BmxqM#Us%`1Jo?q+8hr-6|oKe35ZiH9*DQbjM%bJOG~g0 zn^GGAA`l2C)rCOraq|-Ds1l;Vra%kIczLJ}v?5evR0d+PU|h*eN%z!C4ahuH8)^0f z5#$pH*HYkbg*HU|t<7~2e@knuk&^@UfTWfj3&s$0e`_liqqj2B7K}zibwNLr4b5F) zR7Rqq1}vzuWraV~3{3+}WYzGte|a#lEQOW9vZ%zW`mrs@Ssw}qCFrsN6UI*j8DSdY z;Sbcrma3%6mH;4*$`ydO$Lf$m33dEZXfr593se9BhB{*PB>{k~UsARGoIPdD$)P%_ zI!jN5440$6HR2ysT?}g*1I-Np7{Un+ZEBGkiAc#v1H2>&%HJ9dO5(`UNuaN?o5WDb z8$h{$D;oFLM^R;AQ<`G6k#Ho6)ZtKb&>uJ7&md-hTTR5MtO>+x8$s;NAYB!wtSeEm z3@IzApE4%9vW!Ks&gynsD7aj9LwTbnuq>Fmiq$KcAcZxx>N-%1BSIwFK`;I8uxEW1*En z3?Ur@lq(JmKtHuT6vHHpHa9?_5NU#UCZ+nJJb?~LS-f;v2d{r=cjaX~5DIH)QevUz zHa&yJAj}<5n#>L9@gf{*3dLb+NW}x~7>~t6_4WAb5MG3q0Z>6uN{B%fmj^=)jd6&B zic&lp35O>@^}{eP)V4<3g0q^JaO5Htfp>!`31Sx+L72fN$iEW}De+k_J)z{GXZu&E zC=gOwq&3coa9>tX(n303kY38Eh~jE;!l44@Gf)*ZZmKb?1-rKtvYJQnvM~UIWF@Ff zpqb{=S~-?O%W)8l)Yrq{i)GcWs11i|wFFR9m=|M402tbWel<&i$Rc4Fj*QCCGCANu z2!mRn$q2N?jOJF5I^2X%c3%KMg@JY%5^sGlSXTohAWq_K!7xmsO)WT|V;F=Iv9is< zFhry-!*3QEwRi#YkEz)@2CUI#Fi3Lk)Fq6?a_W-9lV1*1hKj>bh21lV0|?A)k=7`V z@i2zsv;jTRhy`)#1F6W#UEPqKFBP2#lMRmVv*Zx1I^}7g<-rCRs-?tZFs=vX5C$r= z%&&D`7>(N|LKRS$V2T9lVul=p!vKOI`v(5;OQZv>@kp#0W|rDOZDY`n{U8i>5EeKA z=ZQ+JZ)K<@q760ES!7Bxq^v+e&^iHoB-q{(z_A()7|aH92{qS)d4yA43`ArE@lOp5 z@^xTO$q;l9Mv+LczCKhNlEb95$FSQ&Ukk7BN22gdk^z{7L-AH1KE=VPt3wm428U|M1&0eYsmmxOqmqISs2g-qsZ2_= z1fW}C?XXwN$x2qhpbFFlTVQ;I+(OVGWtgE-`Xx&x%;K{9(Ci7LlN=6Ft~h+DAy8ID z3J`D))k&mbK5PiaV@prJ6xH5Omr`4$MF}4q0CC0)zyRhKoYj|3oQx=9g1| z;B_?E5`<}1O*vAVr07%)O({;04UGXQbY(wCx{mCji8wo`F-;a{NDE;S=qwsXawL-7 zRK{d>APQ)#RB#n#Gf&z8FcH@&(-QL4e2}FRPZm#HpU8K{fHFbLDU z99M7xGI*ZjDNdR&IGIkm6vyvSb0d7*BCe)+>OX)ga|IyIoET5d!gwVMfPp4%(8Sjc z<~j71l`4pW-H#a=7{Oc&7?40YO#@2VPf~Scr%=~8S1FG}T}ya0Qteujs%tQD)bxc7 zRMVFn`kTAwz7}SLIKkKpV{14f9S4r89-JCMDxoVjLYD&n z&zz{x7la`XqzGwbc$v1lRBx%MlhA1cg9~~=4LEdIg_uzfa};;eSg4^HtXXJiI1*Xr z4@h{x3YVr?Ee_@gr*vhmYz@N5D~Gw|(8mC`a1f_m=y=e~`fyOrF^U$l2?OqdT4mzF zxChMz+@UH^-3ZJMswyCQStWS`yf-Oeyztkzu3QNwek^9Rsn0mngI^3oFvu6IYp9aS zF$^_<9!mq2q;FLAS52UK84g@6A+*c_4GlDGVx?N4|E&NmM28>{ilX!HSIv-Dfp*&! zuqZmX1OB>8mtlfC1z#b!@T50rp&;`tcA%xf+mJ+ zFN_4CCiJAq+5&6?VVIkwYLWzC^hJ*`%=k*%4h9xAk;$toLUA;%WE>;_%8`m%*g!sY zktQ@I00l`yDc1bd91(5<0}KsG@H6W|ZD^0kdZ_Lo2UmHm{C6~7WrRj~rbps4wXv^r)7}i}@FI2w*ZlE<1Y-fSe zl`JY&+Zt{GUNoa9j_E1^rOh2dRaHt=GLrZkVL6JCfb|nv9ikL9*+}7#G*Bh#Lg0|W zbQEewdl;NMuz|sEZN^clEfj~<3rb>5p=;6=y22uqI)H1>EHaU0Wl3ypvs_}e^^9Vv zy6efR0bn)CH2|!<9Jb|D4zrE=@=_(o{4mad8C>TNG~vn-Sd{26`=LMiWs7i;FVqAE z6|Fm{X3_=UGl#f3DUlU^nIZI&rWSC%IZ;AT8^&p(36KTXA-2pfW0mnp1N0-m#0xqp z3~>HXQ%!3<+Sp1{aIFSvMwOBjfRS9-p_Lajo?tX#j}dGc)*U(78<85Ns8XYG$dmdb zDG}aUyl@>4%V98CgXlY3CjhI6qYo- zKxR_qC|;@6F-yHvr-61!H&CHUaK^!1)kZfM`OvtCfHM|p00=bAtBvA11PmL^u;NDC zq^C+>I1$z(1EfNngsP!hZ6#H(fk)5;E0uDQkl^*#gaYKA%Rwd>N81B5qgfhK=)g+j z0&Gt3@zqkCa+72mQLNl8z)S+~g;Q!!=}^0Zbq#2X!RlI|L3v{6xq(lGHU%tNaHeu@ zu%;;^MAa+WMs8m-imDOqCY@6*Af+Xc_b6{tC&M)knNv(HI)#>{mJ%f$t|)_LqD*0K zgr2k6GFDeBDU}Ih7Azm@d@4nn766yDt5hlK2FzluY5@;i4ggl>s&0Wy0V9@V4nzE)8KoZ6pIUwLhOHHJ1g{g%+?&y__sn532l&t!t4FD?z^a7Z%<9^kH zV0S})_Ko>9Y17&Q3?k5FqR`#_)XkgFGPcwK7gj7Otg}3(Dho{ZX=@VHCKieMt%;edZAtMpW30Fzuk4aBI{Ljx4NP@t`b|j6I^;|QxJR`T*87Lu^i?%e*jjV4cH=*AtERjIprdWS_q`& zKLo;gt}T}!A9_VHkP zfb}$_R=owbY+!#NEj13VHOzPh7!%-RRKj8~EI`UQFMq){D=nKsbz**n35XsqK&jP` zu9i<_nps=us8QTh^4G)GM2lfwni;23r0HN@)`UR@=)x?A9s?aKiroa){-IxBB1}dB zOrcA;!p9e~Ua3_MBv&(_mIj+6Ex7v#E7;)7qeq6#hS^GnxR3<~C#>j1!Hri&k93vP zA|u>^VFHaH8G*I^#!x-vD1#NoMKk?%k$RK?tiwj?L0krGuVI>jXAP_zpic;vo8qqr zU4gzA4FV2Q#n1w7h=4v$hfIv=Z6P#`u%F6B4OlS65gi8R)>?EWz?}!*Jqle-`qgl^ z-H&k@QB*1_sic1kTd*(-1lqs}Z;3)w?ybvJX}ME`F={lB%bLJiu<~mu9j_siI=Y1E zM=lKd(Jh40Sn}W>mA`?}`e+E&(#%dlZX28GWESux)LZ$#FpS`U4yzx?j!r1#09zkw zB8xRb^}(daCjlr5mIm}b7#7G4mf9yha#e(%7AJUAV&ex^kYERut>8Afz$oV~IdtJz zbQ&(6la$RGv_-%_^VbH!e^<(Z=E?kEbf(-VRc164C70Pim`Wa?ThOI&H$_djQka?=89KY0Zi&Qeqh}^hLw_phZ-4R4sRZkJA zVGy(73YpA$tuS-*22)xRb!yn%0JXxxzybpC0cIg^6QM_jLC;y!%!sLOaGObSp&Qn0 zq-ODW2UtL&$^{nZT0m~-;c8LvF6AR91OVg*HQ@%sxQbV`VbE@siHgeF0-h+F%E)pU z4RK|zfreqZSPZ?zsB4AI7x1p+4kx5Zrn5tC_Ohz`+tm)fH$ANLv60yEtx? zpwg)bE*`_4D2(kG!yQqGR;qirm50Wln>Ie$%w)x@9wJ;^&29LaqYH@f1 z!%VNy;zZvLEjL!+pV|mC6ai=eIu5%w z&;!&0E)3`@QYizrOVowcE(yZIJ+8{)V!7JJ051)UL~x_Q7NHoZ80>6V>=`f_qM>#) zJkWl}O^tT(uyo@p{q?% zur~v^X^AVO_`pQt1fvl)BqqVo2E7E<$j}0okD`E!5`t=>b4xqXWRyW((CN|go3L~O zs$1OO4BZyyv{w1I4Lb}>0V-$%X8|hJs)9E8;9aZy3v24jnj^@iLb$GJfwfgw(v$OS z3)PdapkIUY+HT;Ag0UPrd=%sog#9-as|mKjjEgWq%~cGvKhmsR@k%fWVfz^>i;oSU ztqdrkV~tC9ve(6z!{APuFQYUL#9%EuT#Gw7QfuV)IgT!ni)<&(*l3=pjbSJf9(HPv z|??sP^ywLNw$dBBxMR( zD&Y3RU+GTOtF25Bv>J+GQzimlf0(AQcJQuNz=`y#mUtU%IxtC~68NZ{a_s!eQO5Y3 zEBryp)~rQUZb8(#9>V~5@ZP5B>3np&5tzck<;0Y03TtgYGd@3OqQfkQz~N z9Tb#UR!Tnk0;>}E=#fg5a7n#X&QU`!0)qfNc^im>v}$0ZBj%@-6tx%>ThXKl)MJro zm%@G~Omk2t`bh|m_+eEaAHr4q|DUrr0nh8W?z`_xQYLN7j*>_Y?Kp{&I0=nxA}QIl zvxy|QS%e4^5G7klV7%B(056P<0F$bYedKiot6nxx3&nLT_3IQ zqj}mA4Xv&)U6J@D1x%8jYSVZEQix#=+7(P55g`6Bc5;>jCOq)&@FxvB4ajQzQU4Blm{#=9%C&-F%YTL8V>(M{h$d6E z4%l{5R(>;Lec#U~nc= zKP^Z08H7!-={MpEHH-DAe$5vv5(J@Y7rp=;sif^QR_3$}8ZZpaqpcJP+ZaW(S)N;8 zSn|^2z4?(dyUDKC!4GkTk~6y=S!PW!bk=q(Ssfif)%w}zLzn~iM9TW3d9QG(7>`{x z5w%#+l!Z{L6YXRO4WkNKpbsLt0Jc+Xro(Rwzv(+Lo?RUcp@|^39yGSd^c}NEEPpK73kZgu>Yq#`BJ)_KscnRwCD(Dj|`qW#SlHj&o@3X`$3Kr0jnMFmR)%Z#z#U9NTXg*RyLfEmS3t!eL}4s|A{4UIbZf)%7-9h(QO_-319~E+DimHANcQF|6|&a;+_i$puG(WuB+m}|7wN7yjvL-^!chM|%`spNBSVx{Q{~jOqR@###XklE-h$0 zSs}u^QN}&*C`vDB-ytK^=J$xOt<`!Xs;M9dw$|q>WP5f;YX-uC`AJAbwabc31cIge-+FnjDJq09d zz&9Q&V#CZNTHUzV_`59y5yKgypk;&6*_O-;lg`;Wx)AxR&>w;aW{JO4 zf0Bj>iB6Gq)#gx6x|4Wa2P(ZGL>e4q2%1cBRB|P{4w?P>?z~J#S_Pfham&j~rsrD> zjV8v~vl0i060Bw)2FLk|;Lbgnj75|4Y}cY*l@nAuwO?IkJtSqB!mcs|4_;tnxs}2a z%iaS4e!7ouE5GS2`%&LHs8e^N~f8qws)a_Rh*_>MOmAC zR%;JYmzp^Rh-R;A>=~nBA&e-AT+^v^EOib!fUt|+t3KmdqYpl>mK9WHDOD9#G#^{x z|HNTLgt}zGX2x9yf#z13QZ{N!5a*zw9=7+9&oQ-gQNbWluMO|v(&l9824yt6x+FE+ z@)|4(2R#he42J?ucV+)ZBBXjULX?QG+nGe%1cvc$-;@YsF#nRkcsJPrqP+y=b?D^4}D zTrySrtpG|(rJf&ciinq`adw7nj&<$^0=LjPeMTBjg8S@e=pt5UNG_C<}pEKOQBpDB`J20m108$W;ALfcG5sEsUZzR0EmPb1nSi(;F z;J&_8n}QTXiF{ke%>#n4lT)(B;BAgox5dnL8?`U(L$z$MW?sl0JLU0%QS5tRagpb+ zrga7&6=y!n-5pOGu|f-B`r$#=dM#Fwoh_+_9sJZoIhsJ7&##r?-^IlE%!ZUHvpX>2 zp+CI4z!6)`P{spkD~yiBjv41*nwf{lGx*!v(FhZU3ws$RyHikA4ri>zzzW{ga&ZJaDvr1& z-D4b9L0#uB9Fs+)j)u7n<>fkVSmBcHYeR|t@mAsXNat6PQQ0%pOQz9LZWU=$n+~OR z^kP`n6ZeWrFB0@DPIt!$Xt1Q+@+Zcj-zUOi7cI?bU5X$gd@kmc z8qnx3Fts=w*S$K3MHPeXE(xKl#K>whh=a|Z zS9&IhxYSG*c{Rg|)rmxww{)Y(wlsO5y89%Sj{^l&k^>sz`m%#8Sq$yJGj{W^6zqaF zC(Xi4Dl3QvjxqTSmb!srrDei-kPxp5lu^2R*qRgC1#`^eQ#SjlBFMI(_4vVn;l%g(x2M1#fVs{`%eX)k>j z4YTDWaWq{_Cz#(i2jV;F=YyOL%p5xUlNgo}_WAJhb*DRx2_z z9DuNNSvUtWnBM?9PL;x}PM-!lfze@n(iW$3WV7pY2uiS88JvTF7+`8EJ*ub>mdwiC zm5M~CD5h?vi;JTvotxOgX%|awc54HRg{_UW<+K$AluRBNu}Ck_lm^MtgTm_P?C`k6 z6j783EfE7FPA@Es&chUhaBB!Uy6diEzbgsAggH@gVT;eV{UVQLnnzuM!QrOki1DbKPpS6mKMcXi|m=;gYCFZ zAL$K&HsCUCsab&7Wp@}Me6YhET1NuJ3JYTfqlLFHBTVzYW69~q_onlXKFn?@axrA* z#BzuPM6GaNr%$#TGyu!<_r#XW--B}DFA{$KGST3%Ii7=39Ep8!GeqL>FuikDb~3o1 zk|!R0A*6J~*(fpw%AIHRU{}IZc*&?Sr1dCu!(d8%sRUa*6qBWmUYY_4jqn>w72}LN zOzT60Zc&Y)#B)9i=6*(P&4IQW2UGS+03WA`Azoq`7a68%aCMWCHp@%b!3E)+@I9iH z5N^#$R3T}Ad4&R~N~Qvk?4lMA5sP?I-j@$%B95eHB8*Gut0>sA@JPZi^oPbxQKF)l zi_95DuScE8Gv~2a(v)JZuH)xSgsA%pgpWxDt#(RHhrpMqfQ%i$idvP7iX(MoB83%5 zEAP@qD}`#3722u}K-jhpK+s~>*UM&-YFCCU+IsEKN{uLdh2nZ#jYG?3sgkI|?)T{1 zh4s#ByX<7NG-G*N3u$9*+f{E+JqOQ=qIMdu#Ij%**&C{D%f3?(mFk3mpmjdNm# zXf*kHwxUJ(UTbsbmL+XHR%ynJJ!p36U-Rfmp{O;i~*BO zNSkBG#I=GtDQPc@C{=rJH$`5oSK(HM0n`MB0I7gLZ4xg#pd|Q4bK4}uXvK+33^pMw zWXWDgLb(OV!uAzFhgd6KbdQ-zVOpk2CFu($PB5|>;#bE-ijahz zlR4z2*pU{O$=v}3kt*)C3RYO-ER)h)bzrt!J(SUq%>;&t;*w3C%|{VYmZ-qzT5yR9 ze7*$}6(1_vL#rMOj24M73ymY=1+F?OCCV8HS48wY#2jafn=!erc>XNxQOp*Ls}bnK z1?otLC^rlEA+5{McVNZ%vI7#$WePxE^&FL0yv8A|kepO}N3REY#W7|uLP&uvn%ldj}`k=^Jwy52RoDv8^gE)yMXk; zu{503K4y^(t}vX?p@9<5a>2HyU`HIR$|P^clnB=}u_$XYb@w%08PXOaYa(@e?y&7P z>_fNpfs)MkH8wva+uVw%&1eddjONg88E3kqiXgR~9;46L zV8J!~g$&~F5KOTTQZvpGKo(UfoPZ$0*jZY(_61EZJM9V@g*+|EuZOX)%j$o}>#KHI zA9>6v1T9PhQL1LK0%Ggn0BEKKCl<@7W#_@{vd2jdF{LMMVCMzoz+*~?_3{4gz6XI46IZkEOsIfJ-Y0TPNQf@JL zC|?ynYjihxPAs~uw9Bb{TO5-0#Ogt8eHPw~R9u|smPlt=4cJ530U#Ja?!oD1+<`10 zzRm5HM>GjSq|fo+d*&(g_|)#%W)~tF+7%Du`kD}+((#)sB2@gHi_J=d5cCPWuf*og zt90694E~Le$*N*S>LFgOWjES}z}kS_($ALpEzXyqLvD7@H@lBB0_J`3;HuL{d-?+l zy0>wknQxzZ=jb;b)sV?(@T0*gnlMG?q7wUG*TZ?{1QEk#j z*u|_FcZR|gpYiEhjrIrz0)r`QJ-_}IeQWtq+J4e_h-kts%O z@@g&26KoX6L@VJ)2-8H%28z;Apm1Cu0v7C=e&#aQGnDqV_-u%U zA1k1J4fvdygm)33VXCMzuJVN-sejhPamam*<5=Jzy)}0Hz{Dc%K>fxx$m!zbL~Mun zO-XRDu-ZTwK}8&6XNIP4L%&kx}?BZ9$R{ z@q{Hs{KB4!I7=E05-qgQKI(}5HC-W-?>xB?4mh%@bb{oX?u#I(h!%Bv5`-K&KteAa z-3S)S!g{->xiz%TUAwKQ4av<|<{W2=xHokskEb68AvcY86tNAENM)_l4j^SCv9uzYHS1jzQ>6o{>qd^3LgnvD%e2sid1$275;4IQJXbW77TUiEo)9=r%p_5f4PW+yb^`aSbm6MV=3a0fmL%5 zci_wG5G;`*pM@n!q0Hkn2xq3&5MFbHw-~j=RP4g*?qG^AmEnQ%G7&g06Y?g;3;`7z zcj|Y>F#D@%*}cGkNN{$g$J2IVV?TQVi!NmeVgE!=Z{lY_)s5lM2lIjW2^7I%FNzyU ztYyjCk-C8OS%hGEPiy-%fdMXOU!Xo=7-qy2$7z{L{6@0HuRcFxWC_QK`-hxki=$ad zcUeH9T8vva!3y>+H1kp9diU52Atg64^uyeeTPF%o_Z$Sdq8Qs{7~yqJBB^dq%sO9? zdCl(kLGA-QM&$9k7`w2I0v%-pQMB4=Ia`r=S|VN&oTN72FQDlPr?yi+9tVsH({EZe zc0#6}?{rBTYHUuli8p+Efo!*INW&h^L&<5O=d4W4VNVZDSOXzw#JpJ(8%(l_CO;$U zDpE)oO&mo{dZUYOczzDX&frVy8&7cgzDOJIy85O%;w?~IR*^EP6D6Kz74e_ zadNRj!Ud5iCZE~X8-@R|2bMNzZ8#5C;vc9?J41j3Ucf7dY2b*t6=||zf{ir@qZOW{ z0{1h%GQtx2*M^ZvKj=Dgf7gmfB;+65jIsA}9fioYkh#xnZOT>wi4+lcf615!YdV97 zGi*;69nA`fb>OoUMk)-F(5Cb4)gTma5e-sCy$5&Fqr*VwQqXvNv~3x7p2d~Z44V^{ ztHm~`tO3R{J3?fONj^wT&B%Cpjd6A~VVot+m?OxmGzDxnB!D>S6d0^LvJ`K2SXbP}4F9Iv>=QDAvoaDWK{E66>% zFQ$G$zOuhdpHCJ{VAP9#huIdC3W5+h0O-NQ##@4-o{dRXMJ#m~Y8gairm96v7GRo+ zRuK+mDgr6HR?FChJcE7Y`S-pD>E1Te*~j#>9YtQGx6w~XVH3hC#0&X4y}3<=zE{tB zkt}V@i!+|HYi$VAhzYgoX(OP0t7e=9TEv(nqB1{Wv%~?s^k<>ZZ_g<~%4P<>I+=<* zsf#&8`|=7Vo37O;sjRA099|EjAkWH~Pc~8q=(r$>-CSz4qVSG7h0XnnP!m`2mW*&f z{nqK)%-GvF1Bjm!jF4sORj3ANTU3IgAlQLeYf{>Z?vXr?EJVN=>(;3P!A(nRj0Vt- zsuhWIzes8!;%(ig#>d%MP?p$BxP9iAs937UY*hx>Mn$p8z^l|jFYz?=_DI^@J^g{{ zLbr7{EhFe7pSFNV!1Ab-PA10}7|5-X^W(S{L$*LZid^=d_AyOGxzWkmaeQI2*Y+@X z8~onQgH7#OpHn}G<)qm-ClkkfMSQjhtwN%EW$~4AQN%R~>=!Gsyn?9QOL7t&A|?>L zO+t8msguxbIBoN>B!)#i?b-ZAZsYX%{C!-svm83@>QBth5LlMfevCavy7 z#Dq~1s3ayR$+_hnI!|apy>8c1iO^VuJ~I=3hw@wNkxR9PY^fOVMzAnvR``ra2Yb-h z_IgHQ7ldm%#u90)k+_rsEPprBY0^>(;NgPByRj*65cB-m;g8uM;hKoR*hM6rCpf{j zg6T{U(#X%^ZXpcoX(L)D)}+-R*2v<@o#SM3?!b|4lXwz|gh*9WXkL!CwtQ67%6ctQ zxV4%AIb7omF)V=fPwH;n%P_x!ktt$+dvf%-TbMtj%M}l+rx9xK7qb$%=99>gnH!Oi zfiUmn8>z@V&_{*v12q`tw_G13PmYXtqQ#m_%otMy8apG>^z*&i5YpJH5&4tHF(oN;-T2crC2Cn9IiQIoHxYM-;Q>WO-b7 z8qUm0pD9};Itr((F{~yNo@Rg+f6DiYHVPUfIjU`jMFu)AkCIl> zduq%){)DhMQyTPc-%_Gycn6E#A~bV{S|$)=^1QCi@1v3~a0J8xl$y#VJu(R zEHpvA$;xF}L_)p<7T32Tb7o+1)J8h^za6JH>3YGnW$SmyCK{GL5^>9kQjn#im;xP; zrX};nKj;R6UomIm$s+D0gt&Kuj78Fb8AfGA)kbZAX#SDkNkRd^GrKxmm>;>I>UBhj zEl%F(c{ae}DVtOkn#dK655q~kR!&IGgPCh$bYJv$$%>|I&840)rnLGR@>6oiHX7IB zq-t#x#>3t+!zX19f|SqA7HATZu@gtKi8+B(PRLuibx23U+&e-6YdfMjnbk(SBKUN^ zsz^fR{-c{V=T5WG(5Vg!yKI$J6L7yFb42HxLlD(ESL+*o!pRih8jmOSXm7eQ(uWP%C+{ z%O870w2#CY`$VMA86}3gFdyo8_|C(CVuE7d(ky5!l-L>(%%S=+g;)`>Fkuj75IIbv z1KDc`hG9j+N3{$U*c5uOW!#Z~w1)c#;Dpoc#=@je0ktylm=34_SU~PP5Bb(kbT4I$2=XONzXze!SQdES&tSY7q!c{C+S zxFNoTB(&0cT;gNm*r}=y&r;kS1na(K1~t}`U*I|luHKzK#MqP`fbAYLpR4Nl&IooSqH`MpHg%BcxgYKKh8%JxktL zUsO}N>5C=|ID2(fZd#mcsXpH&xvJL7+{V^42t2we6Y43VA54v-5GJ#QSwBa)Bs#jl z+u`Al8DeQ|zhDoVC1nb|G#br^Xh#Egn=X)iPO_13ITWX~gV*xTtH}cUeAj;hQ{89& zH;dBnB_(9nQ$VbIOXt`z(^X8pvk3CDLyXxyVNa2o{!RFdX9Q?o8T#3vQBkX7Xt>bd zItmerKM`ezQ|-v_#C;K!ttWJ&%w}A>?NVEa?n*UVL($y{mg`3hIK()iql*~rjZgNb zs~$-6P)Ah{8JuTk(9}=ip^59Lm-tpQ;x?^iF8bc(=(nFzlSragZa$}>IjXg&H6F=i2VY>wtBtbfLa30T|0uv$EyBEhkU4o2#M z@Cvqg{?4_T2@>8LR3Cci`IXst<0coxO4+%w44XNJK+P;ed2EU{&!Jpy7V z>}?GG-tDgC4W4-__Het_5vR&V5?-TVb=`OotZ27!-H;VQTCkaOVz#Mtq@`NV-WjH0E3 zMXc$walSd#sz>COERx0cl6n6j_p3qJC5+o13`(&Ql^)LJAw6 z!Wnj5btY7PR)5av&v_dR>>*x&MBbB?v7DG^LL3coF3jdO!-&KIzQ=@B?K=oD1ng;E zoy5MMR*E=Dl->?&amHX#iYR11^Q>A8uhrWTkyV0YG2NPZI0UJj zK_l%|)Q;OaUCTx%C4!KW9F>bbEgO=2>ufy&4sF6#Uu=n8z(+RP7)_DHU$RlxNX^+N zig_Aa8*1tWP`a9LVY;Ra_j@2j7ip8;C~)Ks4n~YOEAb?qs2_Ef9rU^x-kgxH_}37= zh0RD7#=739-J6p=8H3T_l(zi)Qhgag6#TLmSeq)s^^G~`S1^#|dfczceLpGw?m)mq zyh*nLN&F$6+H&T&J|sRRzYD@&@ z5(sBGkF}+j;vxd|8>U}5s-!vK1{*S@pOKxEL}Y7*=n2u^5rx)_i*f-gZYT46g^&ry zO4xjD_Jbwi>|JCE%o#SXVAv#y63wMkKAtf?7NECc+rsklJ?#kJ0}SC@Z}%v!ab#BH z<)eA5s?ZDO58^q@9z6_#Aef+an*NNC0M1uL?^91@vq0VpMsB0-bSQBvG~a5>Q!# zM7|WqdILLDeIV0pVM|!`$4^X2$Ik`mTo)8(36WuH*Cp))#R!-N1{aXOS>9MhD}_%e zamcYY&ZJ0%yd|13<7FSLNhKLCSn z@3@!C^)=ZEzA~g5W@%%P4JK1qKN~s+i7cSvWDp#Lvyk!=YM?(o2HQTxWz&kxkV6BC za4f{XAr2jLiEN;1crW!cS>vx9-GWJ^8_A=K_()pW7O663m(+nT$HqK2BBAba49Rd} zkv2(x$bo5M)ugAKLUonNSbY9cCX`GY3JGQX35;FpADcAIOUl)42>WCx^c@c6iWut|Dk(@!hMBFbMT$IIg$^J+`=-rza7a|UkmuwS~fT6S-Bg~nLPkknTdjcSQZMV`P{5B8sZ!t1Py{(>exT!F6*7q zT&Gm4GgxO>hR}tC=gk(v`S=56xRB1?IomS#50$y!E2Gcqzbhc!dIageDBZ!L@ROyWtgkbDoDYx!u@DUZb4W+cUF?D@?cLCG~3!uKY0D5oj0uMbJ zZ$xShJ)m(+Y)~Xrl4p~nQb*_L8E6Q&yN#VyHuSc97dlqfN4p%*>2F+xFJ#LkHfiJO zxnV-)h5=Zdo12z=kl*X_ zdpBg6g&2D`A3_=Y zWRD7%PnERGmB!if-tr(QHsKDaH-ytDD`0J*fuTc1B1>j%;RC8d#1QvWx z9u@VTjOIbrJ}`7Sj<#>n8g3%;)&S#a8mkCDOlnIsvbw*q90Gmm5s-8ggN2nfBNFRZ zgzCbRBnX{Lw>=EpFTH@0B}li3hrTB>QV$e4adXp0H_kvO_^PP*TMrXV= zu%?-OTr)k(Zmi6usRE;pNZNm~Yhc+!YeZ^CqY}n-i*^{fwxNBPt2mvnI5*1L8DP9y zDY(u&{Hl~2uO>a=ew6M0$|Bccge5+T`aYmoQdD?)9%>7kBQW7x%T&;zrvuH|#t4mF z_jE7knQTqPDrqy&Ny-_BE#goXNGl;f5A>sZ^+HjQaZk9euQW%EB3uV5mo420WqC1E z0Xul~kI?XmBiNX+3rIaXT7j1Jm**SZ2UVl%J9fOxYDBzULai zL}DQgt#;3_ZaxS>pJ|?BwI+_!6C_Q=+5W(=#gHOZE@h7^A}UxZOF;5@O%Ta|x;IF( z@({Xb2b(f|?d)Pp(0$%W`86N!=9Z^l^8#x;r6S@FE`n#8^vHRkyokZlJOR#^maQG;y_sqQrJjVM7<%-K5ttH%&{(6wjK*zeZfMC3kOV!Y-jqhB{a>IV^*{C+c!ZW6 zb4}?jZ9?+KcAFrplj`M_?N_Knr=nC%jZ+e2!J$(@GbR|TA@+60yt$NF5#6E!szvl} znt-Gtb~h02819ci-g3E+8YkSPvAr5bOo)(!(ls50+H?r5GVQSey@u*4576aV3m>Mm z*4D_wCxByl#->OoGk(1)pugzwezl99 z**XuvCFef-AifuS{n+=!iN-n#g1`ou-y`NytU1ql&l%=f zGG%m_>IOB&c`)Q}cY_x*+2+BHc@|5!eXH|P<5%jH`(jyGfaV_!W+HcB68wX8!y=*{>cz~-AKW2aB_#QE>T6)A{ z?V>(R9c%owJ838dnAdD(j5o&t6q9r^W2iqRe$;;CtdH%0Tte3ANk-XicvUw2m>h~3 zl&;C!oDRUM(w0Iqw-P?G!w6oqIbOAK>&fPcTnGmYGh18G=M`Uffry8TU{MP9~Kyro!`e90yb6bLTw8i}l{KJSS70uP2 zTjT*di$N>OLBtJJ5RCo|MgaC!(Rq={5aTg`o$6Zn_AHk7=2l=3i07vi&=!N&jia#x zm3DUet*y=aV#O_rs4i>-X|cFcd3}~m)0JL?pk7?nJ$=O`osKRr38W(l=Fb4p2A!mN z8Gl#@SQ>f=2y zosruf`i=CuPMFarrjG)IX580Ds7LV6S*+$Yog>+)!`XK+8pZm9M~Jluzx!WxA&-tp0>t#4)- zdaFhBM@bqx<}cB$<}dkD8P4jExzGU*rlFeL^Z1UF)>o;!_!7TyuEchY#t*szUV5pQ5VINDcsSa-Rv2}p;#rW@2%Is<7RcU3E>kEjXP!XM-yB89Yk(43bjE^>9| zjC{M=i}UE|{#CE!P!2>Jmu5+J9xn?@)NsC-VT&?YSZqWrxKd=ZF5^_pzZIF)Yp{p= zwRs6KNtto`{4+qFRANQ5t%ALTz@z|`@mRKrVPONfKfmsw+> zMd<4DgvVJwJ2D8}!R{4G)&1H{hyXW`NwkMssr7w)1<35qz#OYwVB{hU@pYl7$f(VI z7z(1UA)6!?Do3Zvp-;Rzj(Mj zaIFOLf}KW2ICgBQ`dE%}TMQ!ERD%fQuWmtbHJI%lOqZFW6(&q=@zD&{^|KN4*f=wF zLac6l`CFjRW``~Y6JX?_Siaz~W~gr~+>6!^EoBO6BYQUPHXUu=o880&b7dni)ZzqN zTC;fB1li)Hk!qYDXSFu-McF)jdURQL(M{O{*$s+2wy)Tp{y2u+n&MCaHh~V3O!@$^ zca}#?fOG<8s+M1s9ObE0R@D(s)Gj@Lg8@8E< z>lkHNp*xFZV7EyfQ1IPZe3`N4j5;X6kMAIEpJBjs8Fc>ODJRl1D3~Ck(PhaQvSg|1 zI1F9d&di$%v!CVG#o{1_y;CSp2gC@Nm)Nl{nc}ZijjGS*~8OQ#{) z$EE@E!q;5~+B(QH;{)zu2OSA{ZXPu#y~V0$7(~uMflFf+76`tW859_Tma>D(&;a*A z`a6mr%XXlkBwNQ^0jF$sNP+1E8#xs-7c@&dDbO=^sGPUt)(MX5Yla&og7;(jnJ{o41nJ;tG*R=CQ-mAPM}^J{5(a%< zd0hc$UpXgbp6m0%&a99l1`0?nJA^^+gB%D%{yxs+$5*w4LVl&2qkB{I$&7z?v@l>0 z6lG{U{2uo@7KPDLrLFS?Nmn#obX_T@fgDq3qgN;+5alj)PB{GFw-JqMgB!?VNWj#j*#I zhe-au4-BLLI$@#323nRVze_rjBW_69P_JgksMz-o3syi7D1g??7tf^``_GoQBJ8MF-ahk`GIPM@2EEqma42&7O2^quLJrQtZ2SH*d7FtTi^ZMGA zjcs!k;eaCmkOa{Xc%mJq&lq)Uy@;7%ori;YD@6RLSlvW}?b&wv0*+6Vo)9#`9ZXfR zq7K7r?+p3_zNl3w?FGmFVf&}tgLUK!>O{xHNAUceVe-etQeo0kZUYD9>OfBRFYTa} zwoQugNXRx7gUl%y$}bC4WUR!I#ksqq#b!T$Z4@7Jb+I2q@zmjC6ymQBkf#9}kP5x3 z?!Z!IOy5@tZ1<0-B?eM1WDt#eTZ&o9j_N+D2LNR|2lGph2f7|gTM(*ug;c4te3XrggDQ&p50^gTqMj&Y>TgL^_H zPfKkDOy551q zxIUWTcnDT3{x?w(nt(Vm7;!|!d5>_Up((7}!_LM!l;H1z5v(mTHy5z60%Qtfa^r4~ z(@pxwL;&#q2HUFY-`5;?K1%`PsY za754FbN+kYe;?Q1HS8Spt4HzM>1*iRzy7q&SGT~<=Q?^$`uw0lk?QQpT0`O;=4C|i z`Ocng2oWLkFu74pgMh}Fh1M$W> zVL0FgEvfoCqR^Cz1^tqawS29h1^1$px#4F8i$CGMyJwrb=bF3csZ1(C$VMP-{2Ug3 zSULfVUmc!ck_wQK3OQdOk7tCdTcQlNtLO{{Zv(lr>eT0(a8Fy>On@e1qmS>Ta7GYM zNH$xe0Zr|^cIJ#CqmwDUJl?1Wc~ROE1k2^ovQU8w2g0jBHbv^!<)V-ZBv(CaMHRe$ zWsQTRX3H_>5MLg8e(kD5uuk`5I6{>x48nuX?j&fgjSwq!X#OcaKnT=MY*XhIEh)eQ zEh^xnT2}H(S9?hpU|~SD)(WiGD+L$?S1nU2i_R*A+^N}K$BR7*b1E%Uq?%ykV-w!7 zBs+Q(%q;3O?!4A!U1l`mu360DWvUH3>O@GuGZ7air9n~IbY-|1UW_cC1J^_G3C2d& zfww7EVdAA07Upm9>NHRHTw)4_$%<-|1PNTI-D6b_B(+uQ$K#kcc=Mxa87aijY7Nt% zb+u#`tE#c;|v$rZY>`x+YOvw7CMP||MZjJ6mCxxsN@h67# zZ9EFv10ajVIeZSB38^R@Noo~A>Mc@EA!M}`DI|y)F?-=S>aaEeb!BCUpLH~dIsS@L zm*CO#UX4g>;{-3#FB^o<&g-}2nevYwS&$|p(h`qY9Fwk2B!Q9`y{$S#>{-7qz>o&F z%_dRa;5MPXghufxxo)~&Mhq$LTA_E^idtB|tmewnf-Yu@kM`sNP)dbXN7-Us^oyho zEl9-gF$}O-OI*Ib**GE9TN@j4G6k*?Z;mRc{)(7Hl%t4-hpO_(k_^dR7=E=z;>OY} z0|Iveae5Ks%-5$Ic9NYo&_12LbrnpNhy+_5aR_kx1&vfFN9!kStRPmYFAgnb z%?t)7X6ekr+K|hd)L|+w$3QkKf_&UY$XsYUc;LCxCil7hAeW};R;D}G-`GiM!&@RLE;DH9k@g(B9zv!wH#on*dKlUxsave%|YDj%wed}N(tCrjQ@=m2YO zTBp3cz%#~u$GCAYE%2fJTp2Uk%N3psSeSaTWNZ5M+(>zv(z@ZP{95Xy1lSmvf@0E) z84~6)irQt0BC+`?*7lwaJOy&3+s&}gb{?qAu=8wVLWTLl$m%?p02@bko_-*Lu4w`2aJinz_NB^?D+xxNc&{mV0e^?H zl<4%dVG?t(Hw7`T$0RI@DWFK_+oh&mb7c|}XjAP2u=no5>T%NO2N7qgz6JZk3z+R9 z%z(W3HJR4^5q?z?b`_KB^&MEYF}B=we9+G9l%h`UmX!6>x^~oG;XLNTfzpE1CoCle zU`kER4{(}p6NR>U&I+fXO z+cuW*9{kZJ9jnHXg6`-8kgt^9VJOA@_lC5C+J(r2=`wU~ z7gi=sXR4K2^F>GG)b|~cm$tHWOZHQ#uDrefOl(luqTH?8XTuN!c3LbPvb7ZUsd#}{ zN!|xwJ=rN>maPkDX@OEl`@&r0=2>$uDmFgDbn1<5vJn&5CJsxi<6n}dNwg$Euk|Wc zeIX!`3*%%Stc5V{3x$NYl!%%}h^U7!qPp%71(K8(b8Xb47f^3gnlh+2h-M%VPXGaZ+U)uTVd!e`sI>q?*qdmuMaEY_C6E= ziOrY&cKei9z9TXwasoRE{aUP{NF}mt(JDw-R48UDGw#GDCF>eP`9f>NU7@%4HW_*=ppO*MHSui}%UWiNz4Nn`RR%Oq`VZd4jwCRpUa5nzqO5#V@8f{i0G zasKXCy+(FB)~I2FO;RP6Tq#ngkPKL?j_g5OCLrft3($08>a_rAuW;6`3rB+P#JX30 z+|w1Ftliqym^0@Fw}YV4e_^FY1Cdh9*l}6%6*X=5QEIFqk}Gu*GQdYLc^INOU7%&n zsRG5jdA4CI1)V6lNVrD1G74wk0hkTfb1qh~eVghRKn28AhruwZ-c0uk>ET+XYZ4x; zkokq-PFsUh{paDiIqI{Wf)CzO0R3VrB%gJ);sU6};#8Bh798H^j&v360s~D5s{WKF zW$2cbRB3lz$=f?C&9*q2W}Cx@%{ChW2V-^YSdv8kGGm%;2B_h#;g89Ng%}@?IE}k> z$q4LuqmFo+c)}XAF-A%tlrsf%KqQU$;LV zox1q+jp-X7zA|(1>hzV{GuN-&zT#q7)1?WRt=t(bo)s|k7I<0MNv|BrkU@Ben3*9c z=D|61p>pzgp~Q9A%cJfxlzEF%6Py_hOsfoM)h|}(SlWtNvrziX0u~)=19QGxGijaN z^Wt-cjkvMwduNWR{f1&F*`EnQ%CgGSmaON3NHzFo^o`s0f*UEDa6x6;HrQsI< zQhA7{LnQH>$#;LC^YV%Ju)9EP@AKLIIS0+K6a6RZ>w=udVA>iG%{zu)s9~@7<%$Oq-H9l7Wp&jzg`Hhu^U>Xls2s0&aji+C<%VOnV zVmMqe*)8G<^Q0g`5faPo-1<&E%yqV(Jm(K8Q`5M{C{Rt(pzGHi=mldTyUZdq^PB*8 zEpj|T6Ai1oc`o?khovo{mT_4YRU7(dd2*o#%@!4ajQwt5i#R5y7#{j`2tHg6Se9-x+}#6M*kNGjQLIT}CVG!uPY0BV)x%pF$g}5#Ipffq?e*Fu_7y7_;fSwE zL9B+ejbeXe`JGSH$9VagoM6>I#u>6wYJre+QjPD{Qp{m*CmB_4zNO!XMwV%?twOATzHU&C)&UWcWiZ7h)_`nm=8BzJHxVKst! zKyK%Q6~W(;^lC=yM$Yw6tk9&4GW^Ss1u4LdSAgA}7Ef9P>2^gOopd41!}KZfYDl=Z zQk4}4l_4FsxQJ~;ThdxeVqF~e%*?V9m}KE(qfTa~fDC^UTunomI`~SnAR1jirWFQ^ zxVA`YClin@nE5iVV@FZQtADfv|H5S<+#o2kX>@nKjw|qRC=i!c&25_&5y2Z0T|cd{ zWM>nO#Pxrb_Datkn=ram;oeS5X2AHc-+bw7mk=2&hx`oJa5g1*aG~<5&LGItCFQ@O zX*_@P5TG_WBTr{A@%fI9M@UdVi}@fhy8QrDEU~;n(cu#BU=_<-&6Mq|Bxde{sCj*q zaP6X4ezCs`C&moH3jr$eIuzQ8CM)xKx;Tn zH;&BrBx`dZ6FGwee&d)=A`a1QSk8o@9@{uRzKs|>GyS-it=+PTEEoFra&-?>iaPc= z6P4{ePBPo3RDL!nVy7`U;?7e>0ads6U#OIO5#dI?h%B?)a{MH>V?+&-2k| zEcj}?Hb<3+8_@P^(TdQuw@V^5UX}!B5+Fi17A;4|X}zvL;j{y^flO;a82(vV4^{c> zo_|x189y^{F1j5Zy}o~4LI9s-TAhd9Kxp-14LA#a7sNRSbH@4r2a5Y0w@~&{z zxwtAdSe@NZvAbs;UC8n4Qc|flPtPIM@D>4C->C`%{HQt~uW4Z@I!;9u72T+-L=3>U z*viI`qc8^UVuYEqKis@w#Md@t8wr5iUaKG39BVReQfZTjt7Ot;1OzFj7W;GAx6M=1 zeD3bmUm2grC7Yz&$5gN8a~qBSdP@4GK1!>ksoru?Zv~WyTqST92X@FRr*YoCC#3Bu zzv;iLDqGsJ8t*Zz@!$AHzfMc!f(T)m&g2HGn6$cdfRVTsnkqvuLR5WR!3*$?o4taE zo{UPh_5#h+7}Q_6axQX$q>vygbS42!4|ZO(dP4XeZFnx?mKI4v=_E)(5@ZgO(Zx$g zWT&3JRp82Routjh9xteyAez)Ac&#i6e>9; zTR3SiNj4y%UPukpj=Et$q@P;kF)HUJV#{_t>1xMuq3Fu}+1Rn#(1j>B_j*wiH79NK zqRL)Q(g%k5;6-_TH$#$4Z6FBnG3^n(q(vf&n<5vl8J!W4UNLl${;t@+?GG@bf+jgw z35FI{-c;=8H#k*-AxFNyK&|392=qHl&_LLSpMzf4l=3Oq&Yc{4;E`}| zB)QwB*j2`G!G19Lg*?2RauOYaqK3(1IQO2Kji9Ley-t`QaODi4jmX(Y{3tJl;x zRaRVS^=D~k@o?zgaZx_c6}$@F3=>==&Iw2>f5UFPQSLfLuor|;f+7fce% zdTUN7`jv6kH7>O&GC8sBGo~}-f{@XsM3fC)va%pawt@=P(${6uP%IEBn(}5ul!(`f zc0uV|T_S?de6R+jfmDeNcLVNC&OacTmYdWM#feesmU>p_fMUqa(2%J zto#|0Zdxtk^VHI+(v=}|I(EmaO5V&PNcsMcp`;}sH7B*`Ga-%6VZek z9UU;{X0!Scr9pdmIE)Ona&#so4OS77ZDGyMOwmbFdV|;oX1=%}5pxv|YJ@YB&#FRT zUVt8r3&M&Mo7TaZZc{4v%jt|MtgKG|dCQOyIehI1$0XVHJ^>^%g@Oe`-hK0+3Kj*$S?_#p{90UYLR^zhc<14H^YgbO<8qv{zY zA^AAfR76S@f>c@e63%UN&IpldGuq-&iJ%I4fH{Cw;sDB+oyo*atYLKWT@W90 zy41t7qxCQ(N@yo{O{f|`lW`U>HWfR;iOah*J6WB~hOq6&F+(<3=FiBp z`EZHyu|HTSn;Oj{9{0mX7h7e-f@DA2=KHiA%{(U3H(lfSH(#X#;?f9Iw|;RtJfPW{ z0O2UvT@UxPDW+{ne}*`c-+*)5TG1b=di-nYo&d`$kY-NJj&$kh(tb+hU=-Dte2UJ< zIBKh?7~M9V8(<4y4qK8V!o7tCp)Snm-AWG1?chO9_zevav-v9;$w_5L5dnqf=08O?GE_%*`x>_Lum!WVC(5%=4=&^kY}RNb1&Q{1U7&xUvcifSZ6i(9_g3vdBt z2Y&g>8seNhbEIjS=?_g_`GMn&&c~x^@n47(`Vud~`T;vb5=rUfzj46PURcput#7~Q z@fjK2XJl7*qmj4(aGY@)M_+kU+hR#HH^wJ}9^8NChH?)9Zt%W?g|7Nkvfnv#+$>_{& zIZEsRntXY4QOD#b(C}u1eSrR1oT}X}cA2GUsjGQreT5N!8XAxrPB)sXOmaUw$+o&M zuVgbB@}(ORqc+zjpP3FWrx{ML?~m3eSp#=aV|UXkCfFr>fe^jq!%M@9h+6Ng+@C5G z%Wx87$II*z9FnLFnhLt+83wi)M>+CAIP_*>cAMi`o#M?UF)+7$&bF6Pr-(~8*RIQ5 z-0;RzlX5LU1YbEEU(<7eS_E{j<%dChPff@jK_Xfi|x@vY62c8z$t zZE*{W{F}NJ_zo1sx$#n6er0n54f@rIqOQAo*#`{;n7I}gFVg}iui_X}Z|s0CPt06_ zI$ot+9wL`3ka+5{Jn?Kre9~IGMxzygo6;9>tcPnO1MsvCQ$}pf_^WQrU!32bX5*2HlkO`#%@ve19&}IgX$YK%u;t&7MZ(ZC z#;{xt?WDg1Lb;7dhglPmYuw0t(P*YXoYFx1bYU%c70Bq`O*{Fjz>9PdYhlW|`clDF zJML1-pP|TgL9p)|{vEB}BE&q-gJ$X4{kOr)b=qd41{*d2PBRIuFE{Ue>AHSZE$Ur-c`8 zN~PP>WW+AwIEEQ?ombP{*EGzR&0jLX;23L*19<6Lbb|jrBW2&j2ul32Y(#3z@F+ii z>*|3T>LQE+LN>iZtE27Zsm@iVTAELbD!O8SU!%=uYy8_6)K#BoM!A6o zF6%ZzoKCT1TcB5bc8Ugx@yi~}RCApj#GZ|Klts)-g>fc)eet~TMfcq`V?2}@N9MT# zQ?fOCcv%uG-^5ywP6yO<;yPstYTtvkUWbpTT=vmT#owzp~7x)yE5w+_5`}M*e&I+k$FKEI4NVU zE`X*Rjdx-6?jcz8BKW>rkePHu$z|xDyK;`wEgBzws6TQo`&#mD@mL{Khv4l;35#@| zFxt4CXf>9})0_&>Mzd*ju5IfQ2h{>~3Hdvp-6KE{S|Z3ByP(pZVW+G4S=FJc)9$GNk0u?Sb8QrbdSFeJjt5>$Qj1`;7m zk2n_CX3tE(#!sNn+G@t-D0F4c*m=qqJuUQLmwg#bUDVxjZnQtjov01I_h_LmT(0{b z?-HFV<96dI`yNVs*j$neNpK_Ez~*-O)lHnuvj|=U5bD1cjzEV~A@DFFY_953$?=h# zkkywM)@#tj#iyq)Mp@|b7UQXF0$eb2TM2@A^JpON1)$B<9>4}d6~xQf=$UC4wzLH^ zo%?LBK_-HZ%9yg`^QfF@-Jx-0288+n_*5Q@o<5uvvrk*VfoGg?3#t;q;E`EzV)Cf0 zi?~HU@)-~8QBT}NPk>VYb+X3oz0ZxhX=TY#Wyhhj55UW(ACcwCCh)0p^tWF}ymp{6 zKfzA!3$~8RyJeRfN99b}bmpj>vV9$uHz5;}jnyMNa~ceP)H6a_=zosN3OWOnwD;P% z7p1d1Dq9nu_4qnjfeNx*^i{>{M?E%GbEjEMexPs?M-?Aln;f4DvB`!heF3%{trS=b zY7~X~56O!Xd2iQTa9AzCCFg{!!;-U2I|d!23yca2>^B(HOvI!NzLWYwSJf?Oh-*Pq zg{Vh(x0CD^bphqgBTA@m%YHEL8r^$s(h93*+ZDg%4jp z>1bIE)N~EuOeg7RF4K6RWU{qrCnTeT$C9}d2;5+BHlA} zmiqOJ^DO*SvO)hJT5z!B>$l)w>3$0|FGKTx ze*Cq1{OB@=-+FYp{`*2G@){p`AoK7W4ixBDeHl&B7T7`F9$w=GM;1B!nj?$#Up5W) zMachJFFKTc_$7ym^j}cr60h+ohw~4=;&7Qlhu38?Wf3%TkouZKMG!lojSK|#+NGve zFk)urBUs|T(_Yscsu3}taO;85JXCCw+jLjfUFvLSa=um(fwjjSlpK=KgYx2z1nOKL)oEr~f z>~*R+H(pu8*D00s-b$!-+Jc8C(q+_UE9g?W?nA}czxd6%A2_d8lWe zJqYQf9rcDbg+64VO^WFXo=h8fnZ-#Tcps@ib>&5*52Qe?ygQ(FxfcdB% zB)F9xNFS%EwB3VVLJz*$gA}CG13q(y9+aEV9&~(RZe&b6YkQ?l9wWF2`Nol1H`2i7 zGcSk@Mh|G&#@5Q(k-#dvVC?SpD{EP=-jl|43rBp2Q4e%^zqF2AbJcVoh&bk64{~en zU?&>V_-|0Y&*FNe_e`w)JJ*b^x(l&nOswo3`2h2IPb#KR~lxYT;vt+cHHPE}?yI6!A`xi|B~9jdKsBcfuwH zY+*j$cAx?C?R2h_Ra{knlB-42qmaG#DhSY#m@TrVM|!sROjYSrI97A{W5t>cutsMvzt>gD?`hzPKvns zU8hZQbaMK;v@?=t6^rcj5k(3g?WZpWyc7)OcHxDuaB8o8?uh!M z)pz82noU27c3@#2(fJCOOiX;J^c@zT)a7k=xcKdBm$H$anu7p2R5lsEgH>4Iaj391 zm(ac)$}0T)!HNo9)~JnF2~@ep5(uYC*%iW4TCupn_sxT+`)cHr!c9r|*rP`_NX2dM-pt=w<fLWq&YiA53D1KB4*hjR_! z@)P!U6-IUslY=6Q*V+8S&~f+Nl}!pbT{|CSX3>bD%nZw|_$}&m*HaRzpS&q9Z_a2t z!oV+w&*PGJiCaoygvmo(x`JOZGm`o2H92?`kCEwMA2V@hMCs8=$(z^_lE%<8vqis^ z_{8iIzDAY7-p@hAs%+}OwESXgVJqptX_@(&ai5gjZ+eNg%1Jl^oGZ(BJ5LCHD;%UN z3jSf{g>t7(s{q!d5hw;ZUBLR5W^;v1%H68V#V%Dd;;Uk&beoAsewi5WA*J`$9bx+muex3&gAYfvJ1) z64ZOvY-9)yyd`(*1?MWc?%FhTZuwcVcGw;1A3AE>3hk}+kEXi&w=mob(_@7H^3O6N9Y zS2wj`gPttj@xAUFE%6$9IrN$gD<^6}F=OgY4RvLB7VL-ub|r zhrUEgp98DwnLE#{`#zm+?`c_uC${LT8|#4u+`wYb2=PE0qN@%O5`nwnFT)ZbQ2U)c zB4gDSJBe0FbNlIQ&D5nR&`5|O%bOXV=PKNqMzS=&@3uHLwIMMWkFoQFL2B$vVFo&s za7tTCV8@E*>pYSvo5mvek0_G$7da$HxMt+H{hz@0@SyzF3Mx;Ei!elZ%HF@14jLQ9$+!iqHZxx$bUu}pQ z_7oCa9N^#_sytUsZzuCP`BQB&fif>>5yVD2^KG|0tNWeY#jg{3xqQKx2|V|`)hRbv9yz?2?M%j?|q5PR>M`843Dj$6eC(#eg6<@=V*pOod}2&S|fZ?p9!j9FL7bpIdW< zGNrD)!~H7=G<2i@t77$8>5N{2H?+@AF7NBwkXkZi4Es}DLw->Tv`_{o)GFlj<3b!> z+cL=vMYBgdb@;5f^mKfyy{g>97ZXiW;`}(@q0^Td4Apf}I(6Nlv8Jhj4}dkb8JiG& z7`pViO$`Aj_~y>3O`8^V^Q%S*k4(zlemiSqHnFfN7Jg?XRO~Xv+y>to6-4p)Yx-hm zg_+BNp8#FvmAX?oD3DH%|J`EofVmWD02KeB!s9|*3Zjry~*n_?Ge1J=A zpXGL1?BG#zV6)~(ZLU*@!7(!shZ;#)hHG^3MG%k8?yxn?u8Yl&#~F7={17`{JeNzQ z2&6nd-Ja-Ym@?>r5E7&~qX&j@#T3E~I;c0OtMiZw>iikM{cJAZ*of6fy{Fs(SOxchR}s1N02-MdU{V(&_8_-01n;zDs_}qFL#2k^A$0hkobd0$wMVwBn*J-8&bW6?=T>^eob8@qvj|5?3 zxewBb5kJ96iaO6Xb2;ny#OmyR3omoMX6UU9Sg#eNt;%$@ZoVW%p_F7x5??HU&r%$M zVi^ptWm9(8Wt9tvFj9V-fX*?Ny0>=AhoL~N%1Er{cPoA1Yh^#xYkUY~TwKIyzqla6 zQ;3|RlQM2epy(4HS%~gqEACY+(lvXQSgn^;f)`9o&|wArU;-lX42Kki7&1!-6{2aQ zjZ2)9aa{Yu&Q>JBpYwKS$t33H7OaJ#-TJV6s0DjZ<25=h6BV|3wV9o2ZjbKKkuv_` zL<)4xW}|NL2VB17b!TxnYFC@&BS;20!I(gt_2lG7!7Rf$N`T%9clwpoZM#=BUDCOX zr|6l@cln2qQ#_FldF^lb5d)~G^w zr8@aa+8^c_Rv=o@hoR_HTh~%q)P$4#Jk6b74CDRSB5bTHg6!OQ5Jo|U1&P)KxgO?* zO(^~%C(1^=Eb~a!R%aFZiPdE?-Py28A7C}F7hj->g@P{ zCOPBVJ_nv?^109p+*^BYGtsqs2Gw>Gi0bP4%9#4e^UYzS3e zmmamRG+u16y$QlXOx8}SZODCq@;b&2VyroBOs%<{=iQs<(A4BDt458_ZN|wS8YcE>$>ub_j}ku7JjTBZ z&1anRQ1kgypJ>KUsI*Ex>A%;Np!5sWGEeL?$6p$J>Vbx58{TlH*;8Eu7=ytn!kOli zKt9)eoWH02p3^+{P;+XacRtL&k2KF6e{7)ouQ#tW%gsjf>flj+KT9nQZBx!ExAIA# z*J;JW)V8d;-p~v_G1wTqtGWKh3zR)|{N?7IwCt7UX7kWPr%!z3jXX@bWm@&>8&C13 zSDF`&@tu^t&Ofzhuem;WkocL0UwHUM>VDE+{}QeEG(B;;d5#w7AKyZpui~F-T&7ho z@LkXOjql|5bn_yxPc{$HUGE~TuiQA+G-n3tu~$ws$ImpUj(vgnhMIMP9KPTqNPMlg;FbCkKzc&~+g*RN_n@`jB3wrn9)L?S(T=Qykn%`IG zF+n1Z~C;n3N%HSb> zFR1mj;xj5r>z<=MjKGOUPdvx(X+~IS{dbCQR}X!h`W~aCT6~Icp5(V_J~cRX?9suC z^v9#L`Xjt$gLf%t7JQs~xOdZWK?7dOD5c&Fc*K=fNsamjEj-Paewy|_G2{B7gPfQ_aTUCB|7#e}a+zI8VHy?*O{Y%HY3apJr4(%_!^Z znc39-(%{t-uTaxxnCG8sUO1&u(JcN9^?i~SyvW;59e)gH!@EDh7ro3peTn{ll~Nag z#+dST^*@c`fc{~{oKU;sUwrX0{h=8@PJg|VKGMI*2d)pEdtl>%ZvuXbHyop74-pI?kc(MZ^34QM2Qnw?o|GsAV)Le^Yo79%&YX8 z{(FvpF@EaV=jiLkv;ST6=>~Diefo*xYR#j~E5|=|{Lz8tXd0;y7;`Jodn2l+~)xe-HYN zDnUz+F<+_g3xh8VVpTD=e1+7o z^YBGK$scky-hI9KePRa`tPT+ltx&yVv;XD!*d@WOg4`WmVr%8-@g3y zJo^^r*IP-ywHY*D)aYf}TlK4T_9kEt5PJjRq+us$;fdyrgf|i1On8v+mgb9ztL&*x z*^|zDD=__gBjHViHxu5{dUTfDY*LL6HIGo+2}+zG=WRgVM$X%SHvDax zFXPG6{Jx$1caZbt{JxX$71Z>VZkJ6TXJm7zk%|P5JvD;0vx$*MsC;9&D zM+mc&9MWrV=IL)E%n{}Z3xq|&5_M}8EE84;A0^zShfmVO-$@Uzl3t^S*9jxS2C$FO z)0YVk6CReT>le^V|mrKZECfCgErCJs)S( zem1b5!<&CD;r}80zl5Jh`1yoS5PkvS7ZQFE;TKc?FQL9O#D6K_ml0kd{BpvtApA-R?~`&OR+ql7<3{Erj<1o1!VI!`u#iu7j)f12=Tn87Cr4-+2Y z-;eS9X~Li7-EU_`|2bw)%+E)fKkxQE()=fZ)!XtdoKV!B1b7KF(?+hICFPU|3B|J=c zgeQK2KKx0Z*Sve1>pli{Z<>F_yMBuBuL=K#@NWtKj@9}AzyF^4K2P`$gdca^SHY7f zoBv4oPlW$W_%FcU=Dcfu<`l3u68f*nfzsD6Li?;Z?JHpd9Z2`2`}ng34h;u@c~3_eJi57JK`q@UD3lg(Sn{~|*4(@E&k+mr#n z1N)M}o0~5kOf?Vlu7?OeMIG_|)3oL_Q|_mE z_8qP#aKV>T|2qj^LEcyL`}O3175U#oy^r$y)q^{H%^m8!Lu(#szGm?L=4+|*U9MMc zkFoqZ%6>iJ8wh6z?RcsDB^l`L|Hl6Yke&`&SZw58=Io53#mBMEMW7t_zfZpX+Iw z_w)O0Jp1i_u9Vlj{4itsVV?Og&y@O3Hs3LLo_$#BJD;S@7l~gYTpr-d zDZfSY>k9Q=<-4y9zMGWxpXcE=&w_c*QukTv7EV6P%zLD{;WnLYK0x`W2sa56Sr;rk zbLM1oi!e#}AmKJ)iZD%hhVWtf{|>*;5}qUc|HGTY-zS<6(e4lP&gTi=O&h+4^!E~G zX!{S*-XCUGd`bPDN1*baXl5C=A$>4Mnfbx@HVZtvNLcbWuy67F3gM%q?-D*lSf!n7 zgBj-T4E-_VzJ5D<{+rkl*9Y3uXPXgqY!E(1I7W$0>ewP|lRm+Yc^s%{oNuANoxvRA zHb-4^lq_qbX?6$m%%{2L-ryXx=!s^Z_ul9C`v^bA4tv~r0ssENBI~V`jXmvWQ2u8U zewLp-0Zq8%_uK>avk5ec>c!; zdiOu3%s(N#O8TE7J@{voe{iq~eWZ1~+Wd3s`3b10e=*o<{w46A7;HB`Inchm1E;v# z{42`;6wm)_!oQ)d|CaFYh)+}B!0(7Y`S-*>5Bxvy`yUDaiSVBZ{{`58CHyzS7YIK{ z_-Vp_C;Sh>|0Mh`%KdMC{|})#cCr}|jva#+A)Fxo0Kad5060lFMR+6OO~BvG?}LQ5 z5Z+4oBEmz2FD85m;Y$e*6CNSFjqqhWbDHpW!aE3GPIxEbD+pgn_$q?t;iJ6otBHRN zzh6su7vbv&Uk~gX_&q~-H}Nrkzmf1wgl{H%3*lRVKgRD_!a2fu(vK6KAiRh0Ucv?7 z@8kFVgl{AM?fiZRzu!stF2a+9i-b$SFB8UzUm;v2{v)*S8o$>GHwYgfJVm&93}wu* zk2OzI?iT6EW25H(Hg*=^Q6yc%Z5heTWG0TgZEy(gEU>t{1$TD~?(VXhkWXpmpW>Hp@L9@hak82`X#dsI}dAcDwQ9`uw}& zCUqiAse+8El$V7Ow9F2w5vRJ=#p~b0m`S|6SK1?^gGL(*oxnFf?u>gEtsi}9KlJQ}o~@OxT7RXRHbCjF z4ODvIFKveC5rusr^$RALtAHpg;Nyh)H9xQRV}29|VJ82n^MR z(C7Qgz|7MyBMx&6{71k@7zLwY42*?wFdinrL`}x15y~WOs4^LSrcjQ*qR&+DSNkf{ zw82UdW-UdTwM-}c444VCU^dKwxiAmr!va_ci(oM7e1dhTnIIfLQPGFvd zKZt({PQw{E3+LcGT!4#kiEx)mF9Y}Q3fEWR8eGRMidkGRWpjh;n{W$m!yUK__u#&v zo2EQK&O_qJ>^vI#pYVw5OvrsqxF^~u>i#I|&?xGV^v9#Q9?kV=uJbBSwY=Ene#cXu zai5;U3r*Tp88a~cN1oKHB=8Ekui*{6g$>lXcZ7crAK;@l260Z5jWW&!!)1QVwwHWfT|q>*EzSVLT83 zfe@r?N-&EE(adrsp3M6~a1Vtrhy}4B4#b6cgujMP^6X1{8egAitmz~morI8xFq3HW z6JsWUq_`!+OpciXGo?O3Nrm|nghOgbgI`*7urR~+r_8cH{ zgPf$3OBWfm-`Ml$(}+0@8PkkV?5RGc2*r#$gVijtYf2Gs{9iDO8ge6)VwlB|Rl<-*`;S=)e@WvSI#p6FN{gA2D)0P zHxe%&Iz?)WsE-oI%zsVXQsFOiHgkS#h86uJ&$V=!>q*?jF*?;2IfhP4esJ^Ub*VRP zN!PB_A#7dJstxt@WsL8A`dXCw_%%SkhVa+2mGqV~R+g~zAEXkC{5B$7V`u_Rp&2xX z7SIw}k%r_mnpGeDhjccozx}10q&;YD=)aQil7^(GDQ%!F_IA)7IzUJ01f8J^NSSmc zt!~gAdO#HPgkI1a`aoak2mSR`-n1nR<_e@S(9mTF`Nle7$`*a6vX!#=9k#)C zqy5~a?9kgOJN4b{%K6q@MPEhPjqJ0evj_LRu#dF&ljZ?9XxtyWatQasa0EABK8|8P zhW~LmfsB*z2b_Y_a0VjjC(jb^HTU2gri_EmV_txZa0xEM6}XC=Yj7QIz)eViez){J z%57xb(f2BM;U3(F2l{q)WGqTF{7G3og2%{_HQ6VaPl@vkWas7u*Dv*b$}8-z;SK%P zTYbN=?)SZaSEwHf^@I5nyvJ@~CH4bl=A?W+lHX6H}_KYgIJbhN^HW#u^gw3 zaVl{wP9+}1hXjz&a)RA}6Vz*2DL$zrviw1RomWY0k@4XvC5a_WNs63gM!K4k++x=K z6qqR?75s$1j61_IQ$rf??Pa93oL15iH$83{AfttO9At(F$O2g*8)SzZkP~u2ZpZ_9 zAs^&NPA2-90+%A_NGX%+mdLN%yvIZwLhDYx@6?SYI*Y7jOltLAgdmCi7g?7*$IzUJ01f8J^Y@}W4irEdi6SoIM5x1x1lG4i}WA@98?JlGD z<$uwezKyVbK*p!imh{Cw0DC`7(XBt!v0S0wR+IsxF%Sm9VA6?ZXJLrtnljWfRvE_g z(10<=aPm8XdO8ySQ4nOg&R)w6Wwhm{G6u#HZX9}zhY2vzl1iBblVJ+{3R7VkOotgT z6K26|m;-Yy5z0KHzSC}@-vU?&i(oMtcEqP7S`du9@3)! z2F#7PZGz3%w_t9C-(efHUHg5OhkhW$CbfS2$Jx7Y9n8E@eo$UOEvZXfXf zi1~>$KI8rc`&ak|G^C0O8t7mFE7;idwu2uyzzHrWiVS~DH+Zb(JUsw25Q0GF;=#lZ zfl#i)AQr@iIM&WeT+Db79}+-9V&u=TatkQm+R&o%TKtY%wY60;}$cPY%$gx#y%VXos#`+J&2 z3_p=&*4102l@EIvWUf>1@=V{QUARlTAbphC-j>C`9R9NYUY__BpdwT<^pN)Co>JL* zpT6lnaqkmX_Sje*!#|pyNcOg>5?=QBs$t6WQk{I%fSQzBE$c)2_J_oMNJz8qlyPbl zGNjFweZ;s>+ZxT;hlfg}Rn~MBr4I7zLOo>G2U*i?fXs%_2pYpN>S7c0Z%VjuWXry8 zGYM~Lt2DR%NpJdhc|KVd*8C-`Sx(Wk_Wu6}``5HvAh#tnBP|O%^sTIq>0dvd<^F zTw)!&x%C<2nIF^px3c>&9&3SCiT9k5io}ahy2g~dFD=P0b0l=_4$biIVST}P{>Sj_ z!QdzNW&rJ?w81@z(+heV$@AujaQ`hkG?ZMJFA*ZIdp2)gN zKkiq5Ls!znZy<69VGf2N)>r?Mmw%RnW|Z4&WvKPd-|E}bk zzup_k&yR7W?tEa4>BoB_b5vh>f3L%4y_I{#{ETvI%5(ZF`b~w=)X8bohw0Xj|5A^9 z>B;kFu5X#onYm|K1UY@wPpsYi@A@ZaOJ&JF+g%OYO4l-66&xiK^8Hc$qX%#^C)mB|iW8_&^){yR6Scl(w*nrH9un9I> z^D0}=V=Ml@!#1c#y4zs~?1Wvg8zvFACH{M0FYJT;Z~zYCe+Ul45jaX7j)C+a$MHV_ zCyDVd^DQJkn`qwu5$NFcs*GniTX%nRlxo(s>^JC;N6IEru$(+A379-3p{8iPd>YNz4 zjr|VcqOiOF7Opz^mHpngNRfJem$>)fK0F{!CS(+0mqX4jJ+!(B=_c=Pc6-s^NQW^U zc{JC|JgSWoD4`&G(^Z&fMaTFBs7|Gd@`yNQn)Ev8^>1l%4w4)Os88^J>Wv@H2^Kky z|BU$0aeo0X;T61wH`ZYFtyR{bgVltbbO{C4mgV$@`VRm1@BvvZ4S5>|jSg40g{T&roH1d4)E21PY(bQdOR?KRDQnJZ+PE9G zFx3fiq9zoiEL^zzvzaPm4mV+oaH7TroU=5_(&P0DAPoyAZA4aX@=FP+fwnkm3QW#T z8nS|r9qbJsf^N6a^H1^;iksxGKJ~IB_c9Dwv2cqmVF?!(CJ`2gObA*Pt9qwsJU$M)!eoOl#e-H%|o08jL9w` z>nwc>yBTVdnDrCc)0BF|xR-GGAis^XHBb=y&rk>olU5N3L9f5&neng9x9*~`F2b5W zI`OP4#RxC^JH?4p0((g)gMa;xE19kT}16qEUN98OT_5DH zONyJELuFqWS+$W{TT4dxWcVfXhEJ|W+EU=gxlzJIQeJg2>)BFr>Lw-OQi=@nB=PAJ zp#gFlLL+o)Oum|6Z)!^=?TOON_LJJ&7Ou9iwdMq>tYgWU*wnO*sg#zKdn;RVwKZlN z;6ZQKa(o?2vfS+%>BA<|EUY>=IGSJHbsddUQdXm zt?7l?n>c+)yD#*!rBVB%a}j3RvaiyOvK>HL1Hn8W$Gp#$j=ZO%48-)Uy_Qi1*~%z` z3Fiwx1p5c_Fq5`oD0XS@l5+peHFt|L41I>f2nbZus*z%|f)2kDaIf<~7 zFEALFKC^^Z*B~Q3^>D2%3w=r!+_T^=d%t6pbzT|k zi6`Z-!H_|_sAZ*eSxYCKgVt=w%SOCx#53oj(tgC^#GekKV7lj^-xL3_tjUdK&M+2< za&4ApG*_E!In~X!OzIZ$xdDB)BL8>TMtN)}?H#ZaU8L>WMLV`{ZDSaJk0H%5-ZUAX7*m=& zU%fWRg(a8|`PMN{qR$_23QofrI16$H@EqoOxBwU75?qEW#yyj9xn_*n*AdotUg9eL z!>F^@Ft4N64Y&!n;5PB@z+LS3@V^fa;2}iApSVAQ$3|V@Y!mjUgnx$Lb9ezSDZ^Ko zui*{6g?I2CKEOx#WV92x)z7v(YMhudFv~~k`xj(>CEPbq?B+bfr@zXz20B>mtP_C^ zxa3|%D1P?V%6v7i;=sWPE_+^b&-)eFMW!3`3#JD%00Qm#c%E4|LPjvics>O8PzZxq z5F6q^T!;tpApsS}Jxqn8MNAKh4=N8ik(M~~_aFLCMDA&dQ&e}p&PC45npx5R#s?~C)J%wjy75=O?>Kgum` zF0|tvP&>N^u_zT|Bv!Zdi7&p0e!RCe@vs)KXf<4i2Txj(_P$rGT56yRt|d^ zZ+uhc0-leTgsRWdBxk_?A^W?3Id7h6Q@wHI-qg30|4aGiB#m*_3jdH}x=R`r|5ZoR z->0MO%1Swjj&hpt$NM2Ns{BK~nK$vP`hz}Z{mEso_BR=vv9nkIhYYjMh+hrbSV@!p z8>0@@jJeKZT-S;zi@fAl_F>tkCGFZV?&2nE=lQ7jd$mY!yPQ9b6>+b`q0h=t1*$?ds17yos|mFTSDR~T$9?U0H2q>EZgrq8 z)Pwrafbb3N9hF9QX{*DO#`Z9!2{eUfb~)MIjP|J+?Nf8|+8ldx>@wz&oi7(Hxr=?w z7L=DSe}qJ43up=EI;P}H>PbuP2WP`^k41Pn-`|?@X@kCPp`E=IX>d*v`)0=YaX3M4 zHRh!fmvJfn9qldEPWCpW*9KkMpo`hxcScSZd#>041uAPw~V#3P^!bQ565i;jD%6dmpR>N>|)`cfwpNxG9=5lLC%E#;rWDVt4WK4xftsQTj`R<2VK63W&$1%q=;!lSeFcW0o zY8K{fm;-ZR99_*Lcs#KUb7EQTep6qXTB#v{v-u>$*Vuo9#U zS5a=ODdRPi(OP>)b)Ee-Z*lo_6}i4M5axR<>&fc|*l0hfY=X_O1-2r?9J|Wid?)pH zduMeU;kLsLWbPzwSyvp&z1q#ZbeCPH>{&-Z2ZAVj(DNYfd%5mT+3myJZ||ZWuy<7t z+PkTT?A_JFb{Qx4P>M?sS^*CvtK)^}l{{g44pN2EUzohn7Gw|ktyw!OY zzjL^s$6e~n1=5psYMD=7M85P-)o~ZUON0sMdYc^7*Yq{d>!QtUSff79NVF*0iq_I}11(QSKw{22cs`>uTeZYule z12O%T+x9_5ynE`IhIfKhKecw;(W(Kgw(NBBZYj82=FGsW;Eh&^Zooc1V8C zaW5p@X}En)do+IRaoWeIA-qAs*qmp2tooezzWJn-`H$;x@*d+0^7|5A!E1N}avogv z`QKuHXCH?wU;X6#DfO-!=M_HKrLM}_gn18T?_KJX)HONx*Myvy_0L?}{)ntk@EQHS z*vB)+8jsxZ=xB}^|9#&}-v4xQCPm%=8Bf1_TKQ^^P`;6G*-$9JeuK(E6wPmV5NZYk;g?kE`uC+oNJE?fh3rZ?~Zbsx?3cg4~2#ZRpM3Fz(VHNxzcUZw~E@ zw`>TP#_N|xol9RU?&khUKH|%MhCHyoFlOH7dCT^{@)n`wkC7{N@xRZT$XOHFcQVhL zNcl?H&iB?U-=2+NTsmfDW!;?oTXZ#{z9ChP>lG+F-!O@RZIFU^QPTRE#=ou zEe&O$ER=)te#_Mggs%vdh*KG=P!?6eUtOVA^ZU)4H#2^9KRGwB5_b#lrpcLsRjj4> z@+NC3?4c7kG5Om8HL*)xYZ>z7EiFdml8(B@u*)ZDesRq@LQuc^jobq;<_<3fk^zDLNjO%Euba!zLnoPuYPjY;kMEm{o4?}EwqF7 z-gL~iWqr(jk~O~$-g@TSYwC#1P9STwoiV#WSMt>jx*N~*25(vMCXP356k&Se-^=jd z=)Hf8H*o6%eW4%p2bnjAQ|F~kl(tdY#dYc?Z#%JB9bm}V;=MN8=16U;SEjkAG>|xh zNOLgpBxtx83Ly zB8}%0S@@449a*oaBl5A2@x~vEIS!;f8jt$~m`GX6^E?T?CUZRne)ZcCqx)3+r@?f{ ziQf#6IZX)RrT&Oc8+g_ls5{kUMqSyZ&h*=@&LaG5m;-Z(GY{k$osVfnw*{CBVG%5b zB_M6yQp{zroOmnXH}qWzt6(*(fwdrMPo-}6Gz&r@-*CA_PjI2Yr9VXrpIEr1)*B`^YNZa#&$&&mx)%M58N@M84nO)L5 zLE0z(Pkk7R66TbV7uKdYH)*!zawhbwavC|ZzASH8nsrk8V)K2jGw5jb&S|7xN_{$u z-#Nd7G5x`L!ibI+FvEE})08cB&7xdH_9eLNCvR-ZePV5r_*V&g>4!cdje3NBgf&UR zUdLa;q~-Zf10wqd;cr4TZ+x2VFXL9i-u|CqHPZ5cU=A%4T|HpK8|AAD{0xMi_a9<$nDU zGtLU}rYrYI$}5~VV9k0Qp}ZxHckmuQz(@FmPM_fmd?l`|aeu>I4lGwg*Aa{%({R04 zlfLzIOq-d8@)@rC#%!!DP>-drmU*h`kTIIC?w|4I(|4|)*HqaAmN8g5tM82eS@h?; zA8F>L&z18K7GzlAPu|$od2`o>pB?-h=e_;H1=ZmY9nPsvhdg647GTurmEn)+20055 zgie}K$1JoT7rkX=-XF7^SSKO=XZt1ES9$0BvbXN$Ry~eOY5?*BjWn*rw2@uWGYI|8 zQZ~WlCj^?3Rw!;^@P+hbha^J1isbL@QY>_ejlZ-xaWLaLuEn(fa_&T)w{yspXXZ!w z@r?8bDzc|snKm#!FY+dETt`pJ5_=+$zA7fZdGRIBw7N#V3 z48YwtPmw)83wwIzeqIXnG56$Tzw#D)feF==j@xP~(*B9G!qHvylJ5q|+3&`h?A_gD zZ|)BF1bwIvsR@$?(n31NT{XR+}!VO>I23n4+#6f2y2c@`CblT@;YR$CGRPj<2~P6o$nhI`H+<# zu+@eG}xqX}!e>Lc2NN9g_t-Jhs!(50;-T5SjIkuUYDgCn<^ zGNz8oJD@MT`Fp8$bV!|K?1#>sp$l9|jO^Am$(#3`1Zj40FgD)*JHhmgkD+7i3;2?@~H=JKuEU+yZ50 z)|>a_mAQrbA;xbwI-7nU@uQt|e44}(=j67TL)3wPCU7G^G z!c_dG!E}dJlXFP2{yu~2nJ^1xJ8XtL-@1s5yUp|eqQCur`1zqPV>Rl*9EU>-MEAMe zmwB*@c5FW80+7A(g_w&-OXiM?F_&mRF#vC*qVI* z?hn$H=k65dY2-*bpCP`SaXE{54y65yLf1=b9OAo_^VIVTj<}k8egPfrAB-0NTI!Pq|^eqmi5xN$an|u;RAexPw*MOz*qPNY#=Li zQi=xtYASS=`10)o#w|`-0Q{|(Hn0=M!q+bN?i^vl!A#2!KL_EYe4NhIOZFa*<;LJgtW&a#mi6Aj?l3*r+m=Vr`hM$ZXYimDy^HB&l*4NNAtFtg^6xR6W87DhfYeT-A^I`{) zG<@#j_6yf?=8drr@p3rj>m*W__)-^fA|My~0bgfso}J4+dE1)QZZS;KOc!Q?ERv#ep>vX;Z--8yG^OldzV7-nH- zMMFlALsg16D|y{28|E+0Dux;4sOmMV8DVX#tNQs>H{6OkYk19?UbB{AUZcc(?Nl*m zq~TWFS;sI-IO}@D)HA}ABwyEF7tM4>mS_wjWRxHZDYhOZNyWRGK4MbZ0nWV&TFtUo< z!5L+k*NhRoKkIyEdQv|RT6-BXuJOeco7cS}X;gyBP=&gbQ0+q)-gk6vRJ~V)a)YnGP7@8nM_9&ZTZ-!rUXaOy8 zZ-vcO;e;IlBViPbMwck$kHJ0`#=&@)025&n zOol1&D@=uHFdb&VOqd0;VGhiNc`zRqz(QE$Jk1%Qe%fN}OVC%=v6fD9Aq{~-yeDCrO)Up%f8?|kXbC9;yIaphV z3^`x9o_HIGzme-rn44h>Y=z&!_l=qvq$A(3S&h_M42rf9Z#(`wU?*{R!7b`pP1?!b z&i>jS^061{k(Ygh*$)TcAn^{tVK@Ru;TRl;6L8WwMEiqqr{J`6fOf{|%R^q}tW(}k zX1s#mdANZ5i_W36u|sKNhtgV_?W>f-S!EdR!*Cz=H}|oOvpEk(TnQJ&7lYz6n!k+x zSKuln#s3=q*Rjj^?S|7&x#^TW!Fb9oXFTP$bA)!sd0V*)_i(@OOsGD9hg?THcPM{4 zM{1AA%WB41Ez$Qex;{bPQz&g6gg&GXH(;j8NXdTjTjLzeD)WnN@l3l)0+RjpRF};Ywe|bRV4Z zP0lbSoPEfT*kd!}`h@uzz93unbG|ywy~%G}%l82|B&W!Jq>4EdQ^V9j-n+42%3i1y za|EUhb0nr6Q{I)8cV=b(WIS?x=Ro~jn&N=Y%1k+TEm*|&|ubsx;QxW$82?7em*-|<~xN&-me>Z>Jk z4b&35@+wJOo7JSaC3B6@lDo!gDUh4e)n7?Pyq_Q(QuBe%G?-~!GVdFut+VG))47Ig zMfjqW2SP#4yvq4}$*-(0neRZEV<>aah<8EJOYWzOa+ziwZ`1?19>X|R+NBIGnS)O- z#vgJdC3BA z`NEZa4<@UtIbU9;Eu!9KBR^4m^-7+F>@JIv19G~4#fS4;*gLU@o}0LNATQ)I!cS$K zJC*!SHS#N`5q$eFvPLKRXUtxf z$yy=Ol(s@-)WIywwdheKCVg{l{}=R-v1n1sQp&8DYlbG@1ChPO;)Kl(C7>jfg3?e1 z%0f9P4;7#yvSn?d5^`iOESj%-O^A8^_@PSVjkIws+gnD zqZ(#)WY$1-P3*OxHo9iw{zPJz_h;*1)`fad9~wYIXaw@^y}XkzW9G(OHvwOt)D(L& zXbvrq-x69uYiI*)p&hh`@81q!ErxRJfLllC1f8J^bVX13u0U<*hP^v-d!VcAIW!=S z?;8VAgzX8vpf~h^zR(Z)!vK(Pps74}1F;Xr93& z4P#&|j05QpeSPD2t|t&@BJp+Rsgt;#3{&7&mg|G;D zi(!eYt+EuB;kF!Bxa1t0v;|?xZ?p*$_%^^wSA??4C1Vn4EBb1yDWf&$vKDh4<~_=3 zJ!V?s4@U0|m>XdeayRpwZgHJcvMc9UTRlh1GgI5@ny&rM^VN$l$Zf-ayKA<#19p<; zF4*l_r0#LuR`$X^(%$cStsKCV@4yzOPnEM4(w_FFj1Q8|A@U*bjUL97dMx+z2==3J z432|*GyDYlo`gTpRr=>s*iXY5IE!0!%ou_1Kf9)A=ZSX#F1qGumt3;PJXgC+dRO2o zdcW1rDc4-{Xiw(xjL+j4H|K@djkak%?ZbTB=Ns;g7;ng!L-rVCzw!q8yy-ecUQSUi zr^uP9yS)2(i!^V;9k>hk;6D1vvo12Eoj*<6pOiev9O?mnp)AB~XP*C%u+d!0drp74 zeC4}<9SYyNwwca1P0oPHxi99S_V4cpmF69@xB5cbLf=@!r95&iqHQ;y|7iAr9#b!# z82Yfz;9B^@xP)&VP?pc(1$xN%bh$Q0lP~j2+dkN6JLtRde?@$0r{$TEZ{@wFOy9s; zcn9y{1AK%}Mt&BP&R8uaZTDyD!WU$SOkX-*3G)qP?}S6_iV7O&U;!)Gzz%-k04KP> zAKc)900@L22!;>{g)oQ(u^|q`g?JF(-=!q*U!u9WrwOqq^5^?=kOY!KGDr?7ASI-N zpIC^JwX|^mrL_NMok@**8b}N2AU$M2en!kpkQw9*PXuNb$O_pYJLG_zq}@PW#(Elk z1@Ur29>|MdK7ZeMn6`#~hqqC72dealL=FpJY`bTu;*f?RfOwbpeQ6%12kDXDTZCvRElHDcvIHW zN?f7ltJgRT$h9LPywW@dh@PRMeLQJvi~HdivMJ#s{a(Fn*VR~d9o%c>kf>k z>5sC;U2t zobl?ybyw)-Uq`{+EVmchOA3!cV#(gui%;Zjq8=T z%d@izb2a%`W2Co6E5esXJ$!L=Eiz^Nv<`DUY=Dh~y~bX{CjZvTW=KSTvxT@@aUVz- za-tTAyrYdQf3>x;&A-30-G3v`hTMBu-C!(*9N+gFG<6f}s%APnao+{I3BLy&_ab*6 za-xvBANdEMF74+*e|fi3_Uj^)L;jm78`0Iw%VEqEXmEtMN3kEnJPs$|B-iG*dPPsp zHQ;s%PQw|>rGm!yp8X?~bN*W>Ly@`FYyM6dn`uZtdW|owe!mu3+y8dG<8RkH(MaN( z&$oO-G_EA^xyGnTZ9>_KH zzK*OL{(I21t#Z?Uua*cO8E+M)=E&J=*{7CoL91vX&;Bjq-$vFQ%)6NPFz>?y><=-c zk^Lt;g2(U#x2O0$!+Z`e;3d3**YF13`tQ@;`R}K_SCsd}k#_6@=0{k@{8hdK_la#xit0XK#FPAIpbl%e>0kjX*br(5nJ4>k?EojZ+y|*w)NRJi{(O|$?dDr( z5CDPhLs~_?9u(x>sRg??Gf&>Cg}8s$LfzZ6F!y#XmV1X5+r34LgPgb!5Bc#S0qjTT zgqVpSF(iScgh@sk$+4$^l#oi?(fKFb!?CA^H16G6TK66;oqN5O-n~J~;NGNVByJ|i zOt=WbWPz-Z4YETH$O*Y%G3~TJW^Tx1Ri_#%ro0=r6y%u%YE3`kE)GZ zB-A0U+~2y`>p^{J0Mu$~n9Lo`dfE`TD84K#ZjF%H7@9y+_c7`|=e)2thZfKhTA@#C z;gHKu5xMg3izdxTGwH|5jPiYI>*OZ0s zFxK_t-BTIcoYoeRhKx}b6IbSv5?|h}SY^C-b4FXjv#`|dQkJ=oYRla#wGx(P+6rVG zVs!nR`wwj;eydp|=3Q9iAAp0v%z?Ju z><5Iqfv*oN=Gm&Kf#gpnbSN|8Rl6 z^MZEHeNj7a)Lr@+`z2bFOZZ(f{4TgJXczJ8PX8n2$Eh>g@E>)%!hDAFXryJ~E7zCZ z*R(6{>)ILj4P=-wbJ4E4Z)w*Ea~*C_b~oV`%w=D39^A%$hji|G^^o_Kqmg(Iz3-F% z7uprA2qS+TLP5r%xzs!Kk$1Sh!}VR#U~Yq)hak^IH0Gc12p;421oJ68bIZA;d)jmN zeRRK1{QHJHnJ2y=9B*LY{s8v}hWkr&8b|wki!X6YfBlN<*YF13f|N@*tI0ZF=YB{0 z_i&c4bjJnGW+3B&W|rdx?E~fck$e2f{a71J9?ui^GcvxwSNKL;g^lB*hFr!5*u(kC z_f_{pP4k2)I>@Zpf@$?cQzlQ*mCtf`_!_u}a}?n4WK*1;vsz-lOdblnwZrcbJ=R== z@#hB$%yj4%uzMf?WIW?LOK^m=k3%5tL7r!%9i{}6UI>Ij7{mh6A-3na7RPf=i|cuz z#Y5Nl9_BZmr|9*P@_0%5FG*j{K)vEwrvE^{M39()WfIS8PPpYRX&yfx-56=+Mo?`hLtv#)IKdCR?*d-%>6MphFgqoY(rm*h1bH z`KSq@An)mAr3|v8gL!_)Y`^5)7CA$ejXY(C43H7|IUpzGg50>t*@--uGA_uAj`?uU z4+T8$wSpd5Q!&SQKYOITX`vS49<*Yy*TXUYwab_rzHOJn`zPf+{*;>e{fG*<**LfIho;KCw+YvISleKTw0FhD2^MU*P znP=iNdH+n_!<5RTS%vhg62F?~3w84geqZo2%R}Cmilcm`+`ehmJ!fbE!;~7tsfj+a z#x6S7GW7na)u!Adp$^nVUOlJ}4WOZ?jMB)X=+mhejk&g2RlSMFp)~b;MJH+hHCEv1 zOVM*ReyaBDKNzHLyB$2Vc|;1*xZUR!hQ4JsX1Dp_KbDPYZRp$EE9p ziL}1eMi6hL#~>-BuapasObaKn!>KbHYt<1h9)L;R0ja#~67HGSZcE#y_4(v9MMz z=b^?DcO2=*;_Li2eg$v5r;{=PCc-3`3{yPm*@1Q{zj{KD6+#|DV)7t+tpEJ}V5lzZ z@k8+Abc8O1od=T)?d@>T~{Qe}m$h^(M*=bYGV#1r>+?Myf`CbTRZJw$Ad;Emn z@-X8|dB}RcoH<)!=#t1=9)Fi7>G*U=Og?<;ee$lU&+ik@r?|^Gt`vNW#>MZOq)?U` z?U31?EJIIeQe&e~G&T8UHOc_V5q6{)HXIkwkpxEez|NZy# zlA!Z{`SA_|b<$r=O8xn-Fw);?%37ZJb+8^bfSloyK1lMt5q&;W3*`5+HhJPHo4MZN zNv3Du*B@kb@b7wwT)v9qIi~!M4%?6^{pNPe9k3I(T@a1@-Q+VI`ySYf-#$+YWT)i0 zGSl~Gy>-7Ql^*y%)5@b9Ag-+Q+(2`wUk54UL&!diTviD6BK$gq>px{kJm0uYWQqRa zMtdS<5XCQANZVrC<(DnWC`TAO97X;y(mC!)t0(wR*&@sLjdHV`Eci=AEgZqSifS>t0dFH))h}&M; z+GyP6L`yi=e`2rTkzeviuRroMP#)v<1h;5Kem{-%B_gmy#)I{a1X97P`WuE;#!+rLBXMPoJxf;Mac)<7H zs-$sJEMNs2*g@)^+)F>~@;x)T*A70k?gUprI^91YyY3FiNgK$z18xBUkF`Ju!X6AE zq!Ef4MtphCFjhdW|50A@8zrobbN`Z)rtBk1`x2Y@aflxm;z4{!00|)xB!(K)za*GR z`9ZE^m>zph>Q`>`k~YnyBoA;YDIg`Jf}fBn{dhQGQ$w17Jpbd_%B{_ZFaz6r?T}M6ZHIpPPfQ^7{cfF=dV% zixT$yXT9NEwULJ~C078s!k!265;q^@4=6-`{@-=IGHXT!2wyOuu%6_9gp+eRzP$ZR z{U`*h9P++}jC1d(XSx5<)=FC_-*qdDzl@pW?5(_8D`i{+w_nhyC}mKLG}lo#rLM{z z=oydH%OX6p|E23M|HH2+_l!O;pcr9_QI5qZ$D+C)i}p!bsymBciGbofD*q)rOesm( zl?o`Km*&SvpSn5ohFOktfo0J*4!@q0fnU$@KqyFiQV##bjF_ZtPD<{|lb;IYuOi4< z;Yyg5p$hJo)Y7Ew>%V2Z&p9;wszG(A0n$&`#HZ`FdSrmUH0QgU>^yiU^I+@u`mwC z!vvTJlVCDTfnNj4Qm%j1SspQL#LBTZgIvo;I(GFV6>N5heaJI_q zqvT!5naG<#OW%{SmohQW2FrIm&2gWcC7Fe+*~o~)p`ba0p9}MFn-2?MA%3?=brJ51 zVF}lnRQYZ@d-?&V+4J_*A>X?~zIg$8q;FV8oaL|rely~7o(}seSPg4nEv$p}umLv0 zCfE#H&|xe54%=Wm?0}uH3*`BhJ=&V=o$Mz39@q=}s9XEt0AUWoA&5^u@P;w2yg&8* zJCc0AmhjCPCVN|FxjqNy;R0NQOK=&kz*V>g*Wm`-gj)f3c@K}h3+#8`F5IKM9-|YPE3&77|AUxt%voqB9}+%NyQ@ay{wL(IOI+svxIgAPlKb)mJ!PNt zDdscWpX2_*JC2aOl$QY&$TRcZn6xW0r>aQ1QqgEv;-bTA{N9jPz6h#EW0!RK<`82O z_DZn73#dd`eruXEJ|O=i<|p_JU*Icz13oav`@^h{@k5&f&|eGW-2t$G6~9Wj*|6KO z`+*~{GGlEsPfpxj;16#6Jc0Mr0PKO-gCH2BUkSksg)scWxvvTID$J8ahFLzbaE~2W zPLC5$iJPcuwfN<3~Lzp5NqMUPKdQ^#sXUy>lOI%A9K#Hmgkd4EsJ#GK0~ zB&>XQJP~GMNCHU%YtWX|AbbtNvtEXq`I|8kuO|Jw=*K<`%p8(3O%u)2#ugIG=Zkj44Oj=XbG*L zHMBv$w#aWs+U?P~1NM&42|7a;Sj?U5ihnok-Ju6WK~Lxfy`c~Eg?`W<2EafV1cPA+ z425CH84e?`XHx6ycgUyYaU_g_rsRJ#rj+LxkTMtx<6t~YfQc{(Cc_l?6{f;8m<}^w zCd`7_Fek9CJ{NNy%!dWA5Ej8=SOQC787zkt@EfdzRj?Y?z*<-b>tO?IgiWv+w!l{S z9k#)C*a16X7wm>Tuow2hemDRJ;Sd~#BXAUs!ErbNC*cn`1*hQ*oP~369xlK|xCEEs z3S5P2a2;;IO}GWO;SSt|dvG5fz(a_JKj9HPh9~e8p22f?0WaYdyoNXM7T&>o_y8Z_ z6MTj*@D;uRKL{Zox>q>lqUbQ5y<`if6>MM!KX8B(T;LCG@IU|rLJ$N)2!uiy#Ddrm z2jW6Jhz|)MAtZvtkOY!KGDr?7ASI*i(ILO#e31)w1O427UD6oFr$C=`R@Py$LqDJTtPpe&Sw@=yUPLM5mS zRiG+VgX&NNYC>OwuJ4-KFpG=j#^1e!v#pj_-#G7iQr&%;XE19Pn3z~~=t zSsQxIM$8i%(VjLk+S4v-J-tOxeZ3{Lg4WOm+Cn>M4;`Q*bb`*%1-e2v=ng#~3VNbL zub>8c@1TZypCF6UH>fdfVPn#2Y^2pMNY?wC(C0P5t%>2*AALp7v;1154MIWM`2o1g zJZNB0m@+7+8F8B7*Ua!6jGvrgILj|fiu(|*hZ?eJql|bh=($Yy;Xy59!i>OgBzld) zjN+Fl`HCSjTNyIt9OHIJYr>j+?P%)OdB#~|Fc;}+QtN?$tqdtQ)%R)ILPkg%t_m!{;R>K-t3+rG#Y=Dih z2{ywP*b2X++cxsK9d^J@*oC{a_q*}igMBaTgZ*#-4ie@Neuv=*9ED?WoH9Fsc@qA> zehN;*8LrPlF2-`_h+l)Xzw^kr02jHwL_N3+SKumKgX?euZo)0NO}IORzl$mBNcWI? zpX&$k5TfBv{2m3h)*s{d1iP#|J;i(m&+&f&FX0uuhBxpQz23ol;(Q=n1p7Z9asLFL z;R}3)Z}{<|vZ4ZqP8GSCmSDz@!JMtZzLT{bJ3rv=2M*kv-~xYegNLvI_ys}`*TI-s zSfh)85aNeI81Atkc5r7U4rW}4hkJZT00|)xB!(o&ONxIo1oX^z6ay^c=zM^_;;S^jyJh^&(1r*5KK9 zQLtQ841+^g(>OkG#v1&cS*AMQlHwflL#LFW1$(X|tFCQcXJx*MC{QS{=vH}rwN z#N(A4@^_s5f3w}~N4)+p06%Hp24WusgJB4S<2Dp?7z{_o2p9>YU^I+@u`mwC!vvTJ zlVCDTfnTYAQ;9z z_GPdfR={tt5>_E&b#PB=8)tK{OTI3tIn}knz4W~QxeoXJzN|z3dT2&jtzuoODs!I= z$k|94wSk((xgx%C6zNYJ7e46elhmb!6g`Dgehl&`_q>X z(9e>8dGFvH>79oQa4~qG(U*QvIpc%>Ww-)~SbIrKU5$l#&?-+qYyBXu1a?fp^0Uqe=7(v&j09{l~if|lAK{RU~v-pozHm!{lWQJ(3H z_YL}!=OO4!KSKQ5a0jFgpuKiCcqn-s#+vGI{a)}0#!u45jMVQ3kJKLohba#!<7oI3 z9>HVWp1{-KKFYJ;A^LOdFW@D-g4e;L^f&Mp-f{h&cH=|vX#FF4eFA@VjQ*K4zaT#~ z>4buu1Nj>4Qoi9r~=xah)!44U#>miplOUPBl$`8=Wc`jQBEi9O4a2TT# z*2Ozbi}2%f7K#&GxcP${JP-hZ(2cWMLHGxUjMGCPG-SLU7Qz`FFwW>;#tD)08_fMf zc(Ws9f*!&zMTdfn-E#32paPijk&ysmaT+-oGP1sskn2Q{7?MCzkoGkhW>MmVbLJ~~ z$VBe{MC46G-UK}b@>7OP(%t-GbtuTWkU{kKsn9hS>vlg8HynFvudFm7ll8Qa4&Bm+ zOhMKZ;!TOstpmT7?FXS?>P!70PZ=q@Ooj|ugUG`Ac^1NCiHTQ$U%kG{o^xj87Bci4 zqDK%fOGp+yYlxgjGuy*x&TTm$6nyftAvX#69Kbl@8YNPIU(e3KFK6>LKhl^+8glPs zy=FT7;dI=l8|lVnmDc<%<1i&VY2|>Nkc<1CoAC0S|_?loJ`rvSqu5i)Dm2mgi=r%%0O9fS(Xctb4KR(r{%mPt4OSy%37+tyD8t19?pJ) zv_YI1LcfHxp%p?Rl#0lx1eI~C0#!lYE3JlGb@D9FxY@?eqReKI*I7oH)d-o*`q^x* zXM4+#zL7GkMZDVR6p0*JFRjCM-HLc}+_v`VGR(>g4q!0=G HcyVKUT_EY;&tJPZDQv0{}f6mPLy}RVzY(#;_9hl6Wd*_^)IlnV! zmOFRe#A%aGFP$`F$fYBPjhaE15yLQwp6#`^ltOk%;=iD9=EAZSWqh-dZq}rkvrOU` zduQsd?=xd^98`&?AatPwLJ5Qt2qh3oAe2BTflvaW1in@YBqhnf^lQyE%q)~ZD1lG{ zp#(w+gc1lP5K17FKq!Gw0-*##34{_j8WITC0gi^$!#qO?gc1lP5K17FKq!Gw0-*## z34{^|B@jv=5hU<+%&EVQJQ4wmunwUFLJ5Qt2qh3oAe2BTflvaW1VRaf5(p&_N+6U# zD1lG{p#(w+gc1lP5K17FKq!Gw0-*##34{^|B@jv=lt3tfPy(R@LJ1tX1eztKw#iA) zzN_7ZZT6+~OP+A#921*EqU`TVGLn+Jrgc0wzwPip6}KN_bz0rdYIRM^|F&3=wlk%7 z^2o$S@$0SKv8FSvQd;JWXg%ePYEnvi-3 zS+0=xS1*Ci&D)+P(G+KZ4C9OM$ zW6hq{UE-scB0Z%=pJAcFmlOWi5$^1v2hI?BKw-;O=E2m_ zsplFg^e=SBoCG>FZ#y|J^OS=&&U&0@>jB1n&T|xL?PuR1E9ymiEU1(WhzMV28 zg^z3x-7z2mGdZo>kc__Do$cCg_Zn+k2W;EV={sIY_}@U-vxgoabn1cEKCGuXW10DK zN}rUm$AAb<$RZ>gNzHn-$hxGU{ix64*prR7+rN!HKiA`aw0#}#c$MIPqv!zXK?d~U z2AUH>7aaB>!>J3b2lLXNO75D}=Y#~|C{?;`v)1{!nL~b3Bz-#CH$tTkj%WV(Q~SS~ z@V|+$XU{qyKEt68ar@x35u^i351!V;APE1Io77#9r%yJ?67@z#bQNxHi+uh*Dd=Sv+00 za(bseh)%#puw8KJ0^0(y2hAroyYy=m%?XiJPOIK``(balc_-F-oM+ns*aByo(N>4+ zGObpO{Vlc*a9rJkPH+gFARUO?2(k<4C%k%)Hm%upCj=;8VW80qca~J-Csoy;tZ{V&&*nT}0r1pOk;eR_}zJaiIdB?rDZit?UjcDbx3+N}r z9<*F(?oT98j)iwmw#PHA7q9_@|IO6@ZzNnd65i}@r)%XM z*Dk$aJ)viw{=(J;dPcgCer1cFCldb0KwXmPozCCm_@lq)ae$*A@V0y4Znt~b1Fah! zZppM--$9tMS9$K=4M>qT5opaUGjHYi=7 zbR6E=@(ZJtVIF0%B~13Tcdwrpe~mA-YwiOu7L-t>RoAcq-0o{$ci5ouZ+%y~(gVid z=`)mWh(0*3Szok$pl5MiAnY-AARS2RnA9O*065AOX_MM&bR1*!_Xq>AcaHgC_nmq` z?Vs^y>>WPiE^7OZIA7yl#+`&Wd$JFZ>aU4<3_^&Zo>Z_@*LLUGw#-UQ9~D;`hal+=|M{0A3(y79 zgVbRuB}Y)@kklc8?q=sQ^yvz7pFSVD;2iHkCv@nv0a`aY+?i>$xwn}|+22DBn^HytH z{5tKl=GP|oN*-8W`SfYo^LnTKM;o`>weHWIHUeqv(5nZ8|6SDnH@7069uHgdHRDfV zYYx4hb-}40VjnVK6Qqx5ermJI`qnQ|)A9FqS!o?F$Zt3NJ;ty9S-q{+HsF(h<4#(+Sp#P1GN-K9DY?oqb~O0pLA)V={;QFmAUA|C8tUuv*_l{jKsOC#4Im zXdeaX!X+(Ur+qWak~$@I_qGT1?q9}uu>T0%a{+DNozL83LFfjh<7@sImGp7Yf^`C*0R1AS`Uo7&H7I17VGKK2d(c;dPw=FPP^Z_`r?&V z(QSEFyDhD)Hd|O12wx82IqvY#1Ly~A1NsX3Ug$Z@?tu_x5{_I%?RLDBv@D6=o z-C&(io@_$;`o!7;;HSgwn`chUZ9DWQ3U_ClcVG_ui+YZ>GNTz*8^)VFLWRHF^Svhg zC-fho+OiXO;O)G}`hfWCZd0vmhpx6BFW6)~QMB3mcJY1IljIryrzR5q9vxs?z&fyF z@*~!cDUVpseB)v3mZeu&kz0$bjt|l}@gdQH2MK?t_vk}w)&ugbHYDyIfEFoc?_q6n zcDU`l-OtDEfI|<)4;W#!xrOk*h43fOp}J=5<(>|wVsV^wYJZ$ zwpOfNXq{4>W3_ph%FVii~2?!nR~Hin`Ps>#fgHwAPiB2zYzzFucux7vpW;4}V9yhy5Q>Jdp6F_V4mq2Uri3 zF0ej0J?TJ)8#CiL>;4{n`xt9l=OSxO|Han*dAC?w^S^0r8-FL^f0w@wkS(xvU^9&c zs6TLy2b3Ocq4A&|7rOO;>;QCN>Ne}SsgGLUnYG2bbj?N9*iFN&HjhyGl`gP8#C6~c zIyoZEE4xI9k83yVx2`@PI>5LGjQxg8>u0sOjqvyNBtLbZL-C>qo!7UIkNtrESy>V5 z>Om{4EqNQPhsSNS9?8Fh{5Rt|ux&i+z+E0Yu!;Ht=zz07kTHSS0()*C|bin`!lYuq)|;=m6_E=BCs~;rGOSGCPuB`_4&l8zK)TTNijJ!9pV%SSy0GV&){R3iBiwJZ9wh7^9J|4K zXzcAu2Ob_rIzS$F0Jebpg2&>0!6r+M3D6(Nm_UsUF)nb73*&u)8W-AQLyQZ!Pko2LaitnU(#Pxw&yml@4(GXFXsYc!=zPZ3~=w;I#$! zkPc{DuwC@P9vcSO0$D3~hHQazju7t?JbLiGsoVa!cIvVnY3-VKP6T`JtOL#YO6;+p zVDD`E0r>a2B+JUYo!Y;TZzK0ORG#%fuG`+;+8R+c$hxp>h7~<^t+hEf8rK2n0owsT zTcG*`8WXTB(0zio1-3ol`2qPFdZ5<{^c-PJe61jE4|uNV=@)3e@Wt)9RWF^|qvXPN z%`+4B`(Ik?S*+W?!`3VOgZqAN|5@uhS(zKD?Xy>SOSn;Eok=14HWF`hJGFo1`8i+f zbU8PkWSw>Ksn)tPS6cUtyV-gm_tv;Q(0u~gf_R^x#|ExGL5&U2Ct!}?>=$^R=s#EV z&J}3Q;LE%6u7B;E-qV+7nVl1^tvlO2uKTs>b#uJ^2efsk-N$vuTiYq@+d>Cip~fCM zfKcfIbVBI`bVBPx@0+_@Q&$yPmE)KEPxa`V{^qs^S`T!;z~e*RCv1f+z!*`D4M-2D zPw@5&HRg-7ZuC^i1OL4%?}i@}=BvB4=u+cd737qt;n3Foz7xkE<2>h>ANL%(QJ6j2 zYPYeC)%Ff*^W+iowcC>(sCyi0Uqc6+`mj;!L+ap^!i<#k7Gv6-5?R{kg8T0tb^Qlw zjHvpBntI@zD?AE&5FaNx#s_Nsi02HOt?IEiA6(F9&b2uiC+8$8w)Lr3UfZE>xyOHO z_sKi(_Fj)4G=eZ^{Iw1+{%yahy&He%17T0kp##pa4e3RjI|z3U8Gq7;l#^3NIm_NW zsaeXPjDDjp%$^b5F#PJDlP>%hp;3 zD`ij+CMikDNqt)O>NlfXr1JV9YhEW^_)lCH9CHR9Be17F8WhXY`L_&w9Z4x4TRGwiGJQdT>`weTeG;^Z~kXC+mf_3(1|6IyDBG%+!ol!!id> zAk1r=?RvCqY-8&2br|TJKz)cUDnHLAIG1tzgzH+holR4lMc8%Vb5{4 z33qEfU>)Fi=3Rup^4v#ce36uql#uUPjx}8y+`8|har>|E_l)}k^dbAQZdQB38lLgz zYo!Mq(mqVazui4r4>(lVt5EcSb-?454tz7?A4$y`{!PKLCfnnoJfkuPy%xtG{XIgT zc8_^N_h=WZJ?*ttp0Ovqy=Al(;F}qLJsxD22xX-67Y`{+>w!72 zXMO2>X9wDAt?}=$N%VljO{53n+c`qMZnueaL3~?;PCZc9v{!Ru#s`TY+he^Bw5HOU zF#S@s|61C59Ct}mbP}Djeos4#argT6N(UTza4+ctd5ynY2W(v+TR{5Ib`yt$|1GT! z9_zA8gz~jcO&?an_WO+i9J+COmxCy-`?dl z_KZJ#JJyA`Cwp+Oc(w<0&3e%0hE{JSf_#tlI?y-RGvoL>arg8ElRA#G&hK%$wWeR0 zwSM4A>)Jt=kY8n8H)yqW-Qd;MRRzneg=fvSrmifsPKge%y4*{BL$&Avht-6CJQV!t zUL5;s!k)e8LhJSEuOI8OON8=ex6G=H+kOw`Z1d0PT4F8feU5cy&c)U>1D0Fs2CT5E z23C+?sq|ny>%qWFNDs6wTu-`i{oqP#ecmP3vNJBUW-Ogzvf<#zxTTEr@7wbPUEcedYoph>@&~0qW?vNJ^PETt8$iE zSCbB~zlQXHbzz;-g$i32;&x#b>4DaT8%Q6nAFjLzF z?Sj$=(S^8eAiJRYh{0qVlrF5cSQl;>yvDk5$QtXaiOZ}7=bmLvuAE>EzOA3tX>&WP z-Da`_-c{-r~5Q(8SS%Q-FKl?*>{n`pZobW{T5r7lE19~66NFi zkVE?5(uDxqFo63B=_>{~#|&=U0DV|LZl$$!*7?@y%S->;Yj)PH$GYqip?qD_I-N42 z&A^3`P805)+w;s=MW13nq6Of5!zqrthP1 zz-O=x%0BdE+fb%#1MCCqg3<@lg_`<6Ix&F94to5c`-&Ajp7`4ZJ*Pi8GIQ{`8L8>* zjz@W&2xX>kz*A|S$U1Qz>BQ|9^f+TL>BOh33$PE$Ho!i3`-}d%zhL`7w&j0moUw`a zTTQ0lYY*SaAEydLXaA&-PUH-2-T$0Po$_xxzsDJSsPFhI>jQK`#t&bXWuN`yl8$57 z_h`{|#Bo~Pu-NsG0P6((Hgn%0t^1!%c;A%U_LSwcwPP$7en#f&(3@XQw?ZYCyr&PUbkWw$U*q)I zlrUMmm!=`{=r!#We{;4D5s$2M-`}~RzslDe#(w<$SGhcJYv<&2;IxBz5=U4) zUE9U-mxpS5>j}Np>vC2%mmS4(GxnkC2UyFo+YagrnfDR$knG^y4 zV(LV^IA+sx$ZLr_FBkcNj~%|F1cLG)9q96e4*YDo!!A0c1Dz>!;0L;OX>K~C1KmNv z75r>EcR7&`blZgv{6L2g^+P()tra@(Lwdu|N6&)}=|BfP1V7NNOLNm99q5n_{19I! zCtY)X{6jQdq+I2K-=Ps&&ygN-_2L40qzC;@p$A{c7kt1M^hgi-sL+Ei>Bt$Zom&XK(0u~A?w!fsI_v->)4TcpEUjRR+eQLv76pecE)_a zv$9v!A}55=pAOOX?kycU`POy~o5cFmiV}kVN~uqGBa8lN$7!|`0rIMpG_kjR@_hFe zUd|x*Zm|j;-sz63o56n$$cZD}ILR~9Cy@k-G-G8{tyS1e~5lg!T9NHYJY?oLf`gRm6lAchD<`O?T`8L2!Y$6 z*DK5&A0hndtk_mmxiez?t*tL_?w~85gk)HE-5^&Y|~opHnV<4#LQfwB1MO zdf`wJ_r2K=X4^ebP&nFW+4x+&b#v2J4|%^nPPn(I*+(3b&ZHq7FySd1KWEvgagbFX?k;{GVQrlF&om;Alj2e*5?8r}NvlG*0IuJ#CxC z<7DW}o_gxM9-SM;*)t6zj}#^{OV78ulih&+)Ti=i&n#ZCbouYT7fE90k7%)sEOK5x+@9vpP2`&uAW!oHJ&!3ZTReZwvPv(TddE3G z#vk?S5s)9|*C-b-2L92r8jF8P#qyOEtCvphkN&x7@khPt!XM@G;vbvcSp27yRV**7Ty=T&=@pC0Rzp5b z5gy5pUPT0dga?Odc_VC0`C2%L>cSuS2IBuo)8dbM)rCLG<;5TCZ4I~ow7OZbrqWo_ zv~8b7?QCxj(bww|>xKxo3;qbbOrjC}-pYLF<9f{j>%t%T2IBu&)8dbM)rCLG1^m_c zkA#8xca{FbD~APZmM$X`KXi53va*Gha~D*s^-8dg_>t1fsKorI#wWUMm_6sFtWjQ+ zAEiOPj)n5Krb0zN)8#ie*yWFM`K4ZL^MDQNz#;dAXP-8=vZ7+y>dRMGmMx#Vs%-Jx zm8&XNmaVE>TDE#_*^1R`R+Y_Nx`^-9ZH5p1OP2#7^77`*`oZNxy4uR;BjZJLm#nH- zvl86vALjg9mk%K*gUW|=wUux7)JbQLES-DCtho*?Ze;mTp1MNF54hJ>zNW-C_PLfH zLX2(3HGe|A>gqpHF4P71n-??|{~2W~7L~1H z1!(FaRLh2dlNj;3s)EZ$TtZ8==Ylzf7Gik{8271{*enCi~r1p ztCp@*v*)IqJF}eAA?!wku>*SkjIfK~kFXIe4W~ZVg+KBQ#D8bg;*WaOg+I#W#ot`e zc>LEa`)cs#wcp0Na={H4${E=@U{?9ip{-{@7_@i82{A2SP zjeq(4MNPkU#xg#VAB{H!e}p>)e}v4xq0YIUTNnPwHwb_8xu(S*^{NYhl&c2*1$rM? z!`Dw{m94F$nOpYs`Ab(cejV5k3!ZN_)@|P}>!%V%1%HGM;hQOmX&*t{)rCLu55#{* z)8dbM)rCLG<;6cbp|SX%H9LFKBE5Xxglp$4=r(a_H~bS1U5Hn}k@6SfzW)p>Ica33}1H1?8 zem_UT@*EwHT`l|Suh3y_c{Jud4zHVJ6H}A}`vwmW)%n-Vuf4hjI-~<#Oz6N5^c5Ly zI-~<#wa|ed=nSJ+b!W&A=|ER5bl?ZNiVQa$(t$2d=)ezj-O{<7Ne1#mI?$Oy2Yxmk z=V#L)9q0}Y(eea8n{GClYnu+~K(}4!zz=j48BAxy%ZYTLTPt+n2Rg&}rfO2CAJTy? zB6Q#fx^C%AXO|P{K-Wd+zz=kWF_ft6av~k*4vD^lALzQJGo76u(t&QL(19Q5-fX6K zYN38e2fC=xfuBuRqK3_&LpspS5jyY#-6tt-c_JO?kPiG1|0KoM&m6j$BmA*{^Y9>d z`-8q67X1SsE-%v~J?LXX55Ca5>HvDA2Yt2BgD>WBVgdOhJ?Pg8 zJ@~Gb`UlAm=|LY6dhi83%Hb_P(u2N>(1S19r`N7S|BxQ^hX!c*fiLKT@<)2m?-Y9Q z?Gj*LkU!FcJ}UI!3;H1aMS9TB5qj_iJ?i0=AJT(9N9e&9?LVmgNDunM(*J`m=z*g* zf20R}Oz6QEb}2~zkRJ5aLJz*657IxR2Yr0}f_jL3Lp{9ZM|#lXd7Q7b8$bQyy@VJi zVK1R6<0kL{?xyfLDEj2J2i<8guYxA@9fS0sK&q|({%6(YPT}U(@?K@cSSC=sQ zrtDvj`RpY}VQL9kpVi)U;e&mGu^;&HTUMf3yH+J1Y6PG^jXPS%KOWL*+72dNp37ZuVW58j$nBvq62=w3;3C$56}-?_d_J_zwEc= zKyl-S19rUjEB#f4Vf6QrGf@_jFRG%K0ZB$$3jNq^YICE9k(0{4cKq_F4Y2;_`|#D& zE$FMZBboKoUazD16!-xz;D<5+R~6rzQEKdMW8=kf!S8fZ@Uun9d9KSYP2z2J)EFb} zuQvRy)%Y12zue@URQAF6jdj>BKm0Vc6d(Zu#_urI3wC*%jOXgAs*kGIMe;R2PoXxK zQp0Xq%TtVpYbgoKgZoGHhv*+8SLyWx^qc4x(Z5%F`blH~`+hbFtcYg3{Js9HA6G7R zOGo`Z{pzypnG5;NapQ_VPrV(8D+;|TBE#8n$_#L0dGbgK`SllhvJSI=VRaldu6`r*MFTt_KBVJH+!#i$MwU&zg$mtYCbma zPNJp$2BGhK?30u%k_OMH{Q6$SjQ%j+p#DZvC;og4cmco2ZW;fGerQ=OEYV>T;8(@i z6MhJ5;K$#3*B`$O(tW@FM&sAYH7?}#ny5w_g;8_ z}zj-%z*7zt9Um6mTbisEj}g2 zM$Nvm(;cr@zz=u!b`_b*72&__iv*c&xsIzA^2^TIPgOp&*d=! zgTCiQ#m#6-B(<-hZcv) zYZpm6Z8u+CQ+-Ndmk%D>eZvp?al5LrBI62s&3m9=(zqUywra%Vd1ZxLzId;IpMTyv zY1fT!t(h>U>!?>LTFCTFL)RntIrHjC^h`r>gZY*cuLm@}k$%-*irPQ?ySO7VdoD+&#%B_1{Bj_q=(_9}3TIdwSt-Zs}1-WhkWjjr=^VbJ3cL_jgkncHjDs z`*scbXYYb*iia0d8H$I_y0c)*`1=b^&1?PqvuV#gyXlSpyz-w}A5S>{v+opKkaOzD zEotrdT{y4hMB}8_Uyc3pp}lXsm^pF&2y@@of9)%NKIh@0zxKVm@WWqxQn=!jM_&2q zlYiJ<`pHiUM(+60?wt>wsmee3vZaL^Pn}$F^5B=0ytd9dXV>Gs%L)fhc%S7FcfEgF zq2%$x584*yE?Kr`)e~p#As%}&dT%Y<@xglqTSmXcJPI~^v}srD$&{jlk@t5K55<$2 z^m=kxG4UvlGfeP{>tA?U$=6xU`rc!`and#Xx~lMnA5AH2dFQ`&FL~jt-7BwnYPVDN zXM8dTLkz|GqK|hJC(+!?>DW%4Uyxgv_wu{DKYsJ>-68GW*5_WfCb48YsdYda~@~&0xd%O$&p;yWn(T$Mk>up^*f9RjoYdUaZaEs zk0e^0Nokgusdly7Sh8+Lrg;eDIC7VrvA+u<~tqT5IMt%@uE<1lif*MHa|Ixl>| zu+j6&MvYoDY*F5rF(Vfa8#Q*}qD5t6hbU-Wrd z?-2daa*31}#>#ynBU--T_@n#1GDG|gxxo7o#HaYkS+}#QLX&9p`;laNKN2${N$i8? z%bW%CW&OX@hp(n4j+`(79p=lx3;4yPJp#z`1AnKEv|cnbS9F@C~$3HvdfTv=~<-`NoIdfdb# z1%F*P59x7JJbYHhO;7oZa}<}_|DfHQ!Uyd>@{A9^y$F>az;JpMi35qC>Zjc@4|#!ZNiaVL`)k9oc0rYs|uPM_xYOF?!UtoZ9A z#?b3@zsuvM`dBkB^|2pE`vYFUFDC8Tw;djZY6ankaZ~O1x!)5Vh2no@Spq-c1^kd9 zaJ9!xrPAIoZZh_A+IG|jbR*CGF*KcJ%MN`s;&{%_Y9BXsOHbxRZ3|q%pmD;J69nB#fJo8^%-E2Zeo6*q4iSC#3(BCep08{C*Sr zqXwn%{wRN4H@C?CD1=W+|M;lSI0u>35~AIk!Uyd>@`NA1S?+Puybs**TJqsX1JiVZ z`tOe#l$K?%_m>58gZzT_M``L4V7*E30)EkNiCze@kg>yB!{T`=hx1v1j`gyuT*#_eTLQ;Ae_G2ClmO9eewuxbH## z6O5mG-0SKib;XX`zw!Q0@B)6Q5O78OXoW%JUi5$5{`~ew4N5!C_D4k;xjzbYWQ$lo zyT7r6-zmD>$A1`Jei z`-!&G9wLsvO#6)b(B7iKdOuNB;oQ>Vk!!!RxAN^@6!H24?!F&rON!yKrpR(oN^yw14$49xo|N)%!WP98^~2j#M7u z{wPSYuF#gbo$^TTfs2=iU%aZ&ySK@?KdSSKr@8h=F=zZPCUOa~Q+SS0%~yGUl+0ri zb$?VBRpDCpNAV|^Da|@JWPcQ77=|aN1j7AM#xcJ?%E)et{ZVYAm7V5(SiIM6*WLzj z?jC+er{U-BIe)jP_PiSU6l-n`rQ`H@axP7*uYQkMjqoHnx9D=2KVRy%j%DY_W5pvm zcMs*jd10oM%gzB;yfRJWO4_fMO(D{O?qGjiZt$Zd%6ZS-LpsoH7dr3*o%h^5qyybr zp#wkAdC%QLI?zRg4*Wo;&)u`@hjgIpB6Q$q)7j^!Wz$Wh1Kpv1f~U~ibbNw=ogdPH zZl}x~R~BALvL+SXJWqAsy)E2p#x=?w)iv9nyg=N9e#0bl!9KkPdW* zMc=^>bo$&qyPQY|Iq=c*slfez`w5Akm4HXVP5(4vd1%)XLa)5~2YRFjy(x6y3w=O2P%hBN)6)wl7RbRq(k_J$=ur+YJ<=op?LrT} zhXn7S@*_Ry*9txOf<8!oNDumm(1S1NQ4eqVkskD2gdTjMZ(chE`5`^%51lOSSNK5h zg5;0%px-I<;0t<`!&`o&2YpoN!58@kl^^LrKS$`n7q}nv*dx>*=|P_(^x%v36I6br z2mN8`&%hV-LHQ#+=wm_;zA;Zb^2!hCL0>KO;0t=-;H5`;(BnDyf*$q2bC#bvcR>1W zyjP2^b@$)EuZzeZ`s{5FIOl`+V(>|;`W(2D;B(;m$T@HlMz-pFV-LFXM|tZCxjuaE z0Qg{CG5W9{zhxzwAMayf$LFN5LtMv#{^Fbz^62>Rxt}oS z+z4L45BdOHwNwtd&VfrZD4yN$bKv+~FdxU`{u<}N4WM)222lE-^%mBDoCC*a`FWkD zPW*G=fEVzC99->Co%@z`0M87L3x3_H4fo}N06Bbn7jzC>ZTLCP9iV;qxyb|Q9Jt!> zbDjg|ho7d_R~`2|2kwmh{H!78!2KA^U7=nh^PU6u7HKn|8|SCXOzzZwzxSq^ z+Lcj4MHoLm2M+ByQO|*ke$D5=A;12ze!zRq+27$g2M%%fIdDmybKsIZ=fF|ibq*ZG zUFX0Nz3Ut}dhR+0j-I>DfurZHbKofMIR_5?3;G*V`Wy5^m`7tii+LgDY0gH&`%LhC zL!IA;{6()Dm=Z=eOMi3sk@Yv=1A7&_*N0#DeTWmbW8xb94e$bf<|d6FaMgtkzYjSk zKywrV_yI5A7m@Z1Tpc7w2#11eP8uB&DQcZ}Oo*!$};vn!-C7oh)s^K?y}_~%&wFW?uE_6%IL==uAQX8Q#OTFc|O z#&0;?#OBQ){BVA5z;hq`@(4Tj!T6ypY`^^Q)8nSZ|2_nG0YAtExEe-wF}1J~!#G5k z#Y#rqc*BA5ufJ0IvjHpiuQ;_&=@@DU+!lB(0r(V9oE^SvM_fPG>tcrS#bow;&R)x3 zwJ*{n1eiL=zOdzODeP;U7;Vmj{s=8^8AKYc0L{;s*U8uM=g9Lvso4vDCe z6uIs_hS(KYvFh}SMP;*Am6aV?ZM|nPu-w&t02w!79EDu44uy3mjHfVu!a5YvbIAP& zpKG<5@YL&17t@u$?wfy=^(P6Vx5_x`MxSvHGpWPH$5Fxub|7}M55HshT(>Hc7|YM= zPMC3&;0655sEnfoS1lJ_fAXB`R<(Vi;#Cg6}(`mczJ=g6_I@j$?N*}a- z!F+J8+d3b6Bm7%$jdkVN z2b-lchE2!cPvi)H?7u$TOX~~L0}rp>alTBC^q`Lk zJ@|s&tAC(JdeB!3J@^9GgMu^41$v|heYwzsFYpa2KhlFfPw2rH^xk%W{E;5?rqF{g z^aS3>5(4!Zx?#-1wHEFrAK z_#r*$=LkLcfI)#w@ZG?CSsh##zZ(B#qk6MT7jFBH6M0yiQZ= zS)=z^BE*3o@B)6&2jHsf>i&L%*5Hc`W3hVgRUcXC-@q}9dwt|g^uFJ3RHyVXswusn zE_0rYUoLsxFZZMmUrn9(-){gf;K#CI2V7M|eZNt?PhHcWFRhHy|5#-TzxsT?kt^-5 zHvAm#E$RD>yyWT>_QCk^w>Pj~e)wr>l=#TQ?bpfgtLHW}KWBQ29LEtlpEcDr>WBKEe&COKBaZs5E}y@$ zZ0^NnmmfhDzsh={yj(x^{f+deiSzwUOZp|UmNb)eyZU~AgYgW;H>QklFz&&;1mkOr zlQHgb=Gs;4dz9J+@9W7*U!yFMU!P!puE)U$BLyv_0gzca-3WT(bA@4iO7V#Nl+8sDe#?ywy%mG+gOqq%g^gHb>fe2 zfEVzKjnnu6S1lLb$Mf7iTSgrJ<9<6{`xW-}yy|T`wI_pJHFnxju3x{yzBS8RsRl z55^A?=J9DTeu=-Y2Y3NL$OX6>#*U3i8b=xD>2Xv% zgk8|T_eWx(aa2|FEaijk0OS|6Kbkr4j<>|@h4ndEYMoE;0)DZPq8Fkc8XC{}`A33Z z)e?;#Lf>(4{qYMrKVRdQ_~+*XFW_g6(D=FAq5J%NwLf}q_5sG$xj*_^wjMqXFtXdHE2E&VXJzn_q2`{j53x~ArFl=OzrKV^!ec1* zLHPO2V-gWR;064E5^zQQXoW%eq5ot2{Ju}9YQ81F8XT>f)Sjfx@K4g`-y6oT z>7(hC{1>ixf8(os=50RFPbQil&D7`T4ti(z8E=h=wDwM_(0i&cfNIf!QXfFd%kT} z-hp!;*;-Oq8QXu*i0rHWQ*P;dtGDhSGd@=GyQIiOeQs~v<878j=n_W)=N04@=D+;z z?oZyldw27XKHQ!C(H*3Z+I{hx1>>sz_g52)=L%jiT3tMW?|RSA=X+QF=$V3v??!fy z?RseU*2uIy+#bD-`_1X}J*X-3n1-L9@8xJ1^o>w~*VsAF2dPQ%Ro+Q5Xjo)ct1NVT z(!Z&EMX67&^*TR4b9my;V|-*1-U=lUB!Sw_&-c>Envq^#;O_|G(Z~7OCohu*$FpfY zM{=g!_eE}ctaWh6sSr2hnr+z+3!L{CFJ2ty=H^vr2jD{I4h>ok7pq!Wqh(EflI@QV!4 z_yJd4`!lKiUAW(t1jS{&iucz1L>>gJM;UL|`dr&g-q*zKkCQehj@Ko#uf6>-Up_C; zZ@#Rl-Ro6SjD!e)AMgTxQL)Fs^=MZ%XuX4NC;K4${MM_Ec3qk>f8YnafFJSzt~!1y zwZAcr_P44O?Qbu&m>-bmceK3ss}qGWinGIe+czZc-#&Hw#O@Wvyb066S)M3TpxZ<2R>-GzWl0gFVUQ2+;b%R@r}oc7mZuvVSKKk+AZNrF{9tdYiqn+#fT;q33eB9HD z?Cx2~^OD#H+g*H5!TRqv?$OjJLE?qn{`kCTwC6-UFFJzrqK^>5c}5%JKoflJTC1L* z#8H#g+R;~Hn2qEsIKYdd}p7yoYkGriBb;oq%Kn}2!5no48nuwf&>w24CfrE}w$ zRm*teP?oOOP6;DjbUb#6%==c<)h{NwzFUvAaHs$D)z2UK=en9@WIfBK+b9RVCoY$A z)uiaCZh;QzK$jK~C1Dz>!;0HRx_#IhP`}gXQ4s-{*X*q!(=+>pV>5vX| z+l3DNKsTa!N776CJ94B0-CCgoKb!7%)ZN&0NC&!z(1D*#_n7Oub)*Ab7oh_`(5*{* zOtlu^fOMdPK7k+T3}ddk1Rc_W4(Y%T@e$4E#^u7c1$v6_K%=6!NPkeu?bQR$m+6rn z^m9D=4|=aYfF9{VpCk0(3psoB0`y1^`omqd9)U0Dz4`%qqz8RW=)rewfS!OJ=|NvD z^xzA6lml`FJ<@}|T>c=a zsY8E|9{FzkgF9rgzl)1@JXb zlJBS`jGQF>Q%`q)gY?mn!}s$%w|ayQaUXp<*GK&hp76oAKbq~wZ!OKW*u7h#&!JC%UUHRZ~KjarBVX^$YjyZ6@z*+M(oVoE`CD-Vh z|J%p%L5Sy#4G--rQu2=N7^>#ib@4fL-QQIHb*1w@&*`S|1b)B^_{BsYpdXr^znlJO zzs-x{Mcof@oJYew(c$XyiFfJi}erpiSlkuBQp7sAGpM04* ziB{}Vj7%yYbJEVdUE^oY*7zZebnUI=j}YnW8%71cL*K0*er6-_i)PvQv2vok7gG&c zSG~@>qr#<6(`TG9ebS6sQzy-wJAKyN74t7$x@11DKh0e*f0dWkFMfKQB70)}C~9)a z`LAWM&K#ryBji*(|7oZLexQS1Lyw`?cn*D6@v3`EjCp&M9&@}I#hZy<_oK3%A_9fp zdVe2qsOLHIkWlIMwKP>sGSUn>Ba7A}PD#2XnLVYjJgFsmro*oL=`~YJwu&3Ln0JU> zS|WPg>7cR?v4L8z%^o^LdW478>+j0VVpHiq?jy_*y*8h&r(SPpoLwsK?$&FR8+sjk zSJwySGBe!$n_I6JR;;KjTU&|5^$1HEOi`2RZ)km%b*3LZLddDy-|Ez)^SfgTet5=u z%?%uKh|A@?H{CdIy~5SrCrz3?Y0})&if2ulF|~Law|SAx+~xBt%T_I&zYIBibzxhP z%MU0EmJ5gMAQ$MfzFYg>Xjiu$#N{G#fLx;Iid;l*%*WhvaY|(6sNIPJ@_r7OzjuWCqdL~{5A2r^H(gSAzg5;HJ?mv6qU_~CMc?$73*-Q~M0<%` zL|*3fAh}$+boJ5&OP4LJY|z+jcB825YO=n3`lbJT8uo?Ps_W~__xw?C+kOSm`^+w3cJS|8rjhP)a&HU(vI^^Q}+YAAM z^1cVcxDIlFTtE(anWqNHr7^RBrkMw9u0t-gmR)aWUS4y46eDV^JL7y!Q`VuqjB&o^ z@pgVF>JzV@tgoZqs3+=oJe?oP_~Cs4>WBKE-sL}fQ_bVz>mYOnEUh@NURF`r=o3Sal+FPB>zLEsZXxCyhsY|92`@!E; zefKO+F&=j0SDx{Oy1zaDOoboIgZC|9p91zRL@Q+ffb3tueg*8i!2T8NUqBXk@BS^4 z>u+fxm%mV&mNZ&@F3<0J%`NWtI?=0Tzqy2F51ntMo8LYIdLJtL6?P7*ecuB3;QgR4 zzbbquiG2!3uy4W0EumHSVmkd>LhpX_hV5J6?^IZRUKhA;;al>4@Eh75MgVEa>_kM6^XZ!u2+IJ%O13#1-xa#;dBl!~g!pX_pF8GxSeiAx) zH|Dxr@H3yRAAaSxHV(fo4*b-9b7{|svfn&!TYvRl4Waq3X?p+F>ay&a3)d`L*~k@3 zz27{JEKTjGr=k7k)o13%?K6+xkzar5uXyc^eWsLy?fAovIPW*-=Q-rLhdWmGo9oh0 zd9E~-JkkH4zd`>KlYQ0bm#|+I`|hw05BupFRSFE!SzoN;dy2#T1WWVl?J1gaL&Glrb_RYP! zhiIw)L0Dto9DnaLym@!!gZEuAKju4;LYAM`F$e6M<7+tcda+;a^!v4_gm~WA&=mWX z^F%%E*DZ~+Uu!$L`yb#1{LD@oKj5nC!@n2%oTLBY_$Wu*UF$a_iv9=j!R}-d)BO*x zd+6^>llePSV~FyB+l%6yc;8%cJZ4|$9goCOMvCal%4 zbYtV}C&a?-kAE*VD*b8rd$EvA{X(osLPr$UjOHoH>)iAhH({KFaT8KuJcaQRzPG^q z9pfjY=aBVwK7~B*>+QT# zhtbGKY8?Xggxv-owEI}5&$wyc?e1~Xk&K(>-Kob-2y2X+c-~(BaZ}K|J#gH#RkwSr zqaxH&Yy98sd-c5i&^CAb4&oSVWV_$q-ZO3zynvtCM#fE|A3Fc<&^U=*6O4P+Z`#nf z7hw(j8aD2Ilr-LN-mdY}=W%1)%erfB6a3E5^LA50RlOtlv%T;ydY$f(`r#MZ*f_gw zdhi2Yz%P;^?b_82%O@ID(+}9yqxfDOA5J&N$%Bc?dKkuo5{GRY>v=9w1bSaRt-IL! z>c<%+DeNgpz`lAWX1;8{wn@Hx500smXnm9)2`AMLn~w^9iv&Ljqv`s+A42e{Zx|8$ zVh`01KlAp+;aA?yZhu@Ml-K({3gtFuuXgRfnmu*W*&|DN|5as0#j@3N=hF^}OY6Ps z)i7o;6___N-2MM7i*<(e1tGJ-IISUUO~DT|=vSb}(CcWr)@$gyPOs)%dq68|fGYku zy_?|n?pG$idp3{wmD1~5s57@#O#fTG^%Y zS9KUv?xwmA{D2qm!#D%D>imY4(3yF!+Ie&Qpo)KsZayOq_@qHU_g%T^|6I?<-M=UK z46VJeCl_Fsis;cNWatS z*0>$|asBWszu#?_<~;RZm499NRBzPdJjRbJgz^U3rStW9nc&M`u@%ocV+LEMRb`7R zaKFA`@uEf9rE69$Te^@wgQ+i(C*23s=AknPd3`n`*^{syQQ(NA&}-;1^cv5h?}#6* zFle2E%LBXQKVF(k{jGMxo6qHLS2^?Xuf{H!)Ac;Je1m^~Tkh$Hw`aFd>(B9W{lD?9 zev!u#Tt9Yd+@UYye;L1rsa7WF=$h;6cmDpk;**QwgmMvd{{HWi*X{Xe@j0(FE8RGO zlaBBH?1Vr4{qXMJZn}{B599AYo4jlF)VYPvp8ExzlWV)=AGCax`>UT5{TQNom(tPG zs{bWkza;wQM8k1|`2LD`?bP&D(`I)o95Ux`MOVIbQxVh8?7U;o$J<)&ezkNXm*JJH zdHRcZC}*7=s)Luv75@U8zuPRWi5-T48<4Tm%C@pgsKUL z`?uM3=*RO%Y_I(Gt{KBic0bzoy9E?~e%6bhy*hcruKh*rX6?U-&fh$$5W zXVc7*3ZL`$k5nEE=J7qxN-FI4 z==p`LOW?C%zzQA~x?KDvs@!Eebv~WppGRl-e@tiir_dSx+#bD-+pRi(U)C)ee*V6< zuGz)v{QbCv)8jk;^Y=lE&|A93#ohJf^Y=}&i((a-$k+s&zn_wl(yY$&_fx4}ZTb9t z>hns=7SCU^tdTD|8&|bsit0qK|FA{#7Y^Y`f%-B@4NC(19Q5=&duYaM3mIVZjIdY`WrRPCBFmT}ZC(D&>zC<&q!Lqr6^RK#%mG&l7s^1^pqB8~B1A=|OJ_J@}&DI|JzB=|%qz zcGUU@zMzi=&?7za-!AmvdsxbYdU(r^^q^lW^xzA6l*3Dp^q`LjJ^02X|Df_CJ?Og# zJ@|tDP(b~W9`uJ`KZFnHQ4eqVkskE0Ki~`8g7gRJK@a}m3%U8ppZ5#H&f&eI={W}z zbSOXSL+OLo(HOrx@~r>)K72K`KIg3V(jA{qfgkV!ey9y_Rq?8f zQtCPP;hD83qtvplKfv*^q~H@p$={Q9<~`4AjNGpcKll26ZgNg4`(XUWI_#GpewrF3 zPP~xuQ{U5wJx-kOX6SI@ruTaqFQP0D^*xRBhv*+MA3(o}ei8j_RK^MDC&3r? z{cO^~A{tqz(0a_Qx ze@9c>_cZnIAA^3s;Y8^lffw)t;=onM%V~V``?!6j4-v@TPFMZq$CTi|`+J&M$#0W3zfB4KbeZX$`tSGq4Vv1WQzFH<{qgrSXwQlA zJ&hNm*v%dF`?n_fo<=P}a2E0JX^HdD2dBHk5$Eq|`1!H+ zJq?#r&BtWD3H=QfRXNPdFb~AM5d9A3X-LmumW)Tazv1^R-O`89T8V!fHKVc*RKiHX z1chUCv<{to>vPTZQQ!XwAK0ttcprXM*OPr>C-bpqhEH=pB4zCrzsrcV6%81Mpqv2hwd=m*QmsM<#T4Z9}5&){#TXdh@i)cp-} z*Yj!K2U>spGD!FR`Wua(-UrIO*>T%Q6o>W)ynvrMR@$|z9nPC*6crz^>rV0Phg96T z5A<-VPT}1Lnk$5OZu3!BYCi3lkJ0a__A8^$YQEg<8Egd_)jcz_C4}OuNFSbe?`*RQzAGcMbRHGJcJF9CjALz304X zUn~3^?T@}c?2`1p^1!8rZ$5P99xB70 zjNV%dPkyFTVW%N4aTy9We6(rTyS;`M%`SLCZ3S zy8q{ev63~-^gbjm2lHfir1Ch@`sh+5{@?oU;qy!9#H(?Vsw(vE$zxptuk1Hc>$R^B z>1zwQ-Ku?kG7k;+_3`N+c6&>vSr9wkhjicOt_8e~9PaB=B01srHHQ28jBsC{ZVGk& z#lF7i_Zz#fZ${aQMfAfoblfn1W6_jO|B`9rI7VgvO%}hm&tpyi)(+6 z#&a3@Y@|U2;r=U|C{PaUCz~VXs>#f~KM(0Zmm_rG2YTvuGgh&UvJfQ6<1YGnfXAsy(D z4*U@BmTuGWy8%=9V_((5cJ6(dD6dz(oG;TOJ?OU!J@}&Bhb14B1N2A_`n5t2zMw}r zy!1#9`iRhjFY*m4KhlG~i_n8F@`v7e^GABnACmS5z9_d>uTg)b2mMZ=kMk9|1<@lt z=%Yd(=PUF<bI2QNL+gC5Vp7xd*m`or&$VCV22 zDdw?v$QR{5EPTBBfcLh%4#e+~^uE4Y-XmqpzCHE^$l4c_&pN%U>(LB z;m7aT-PafN9_fVHw;*@{zli7qaMk+2`}+Q();;6#d0QRtC2H3i?CWdizp|y)L96sS zc8dO;#~w!eX6%F4L7n^h{MOMlb>i>q175%nNVwYJUf$Q2W#h$h!LK{D;l4bmBKIAd zv$6}?*H;^U?se?kF0e?FCp<>z%L%03I= z1^moG8b9Ew<-+HZ+WV&I>kW#J+UJ!S;%~?W_Vpp&sB=m!aP<#)e0ZMEBmJJxKBv?t z$#H!P?GJbXzlgMF;Ci$x>1T_$OwRZ8!T7n~(;w}+G-dw44|oATQfLt=09(+zI#z`1ApHm|;_x*G|w(;i4iEjP{rQG23UH!%XUMX!qcQb|35O$FEz{ zjhpuVn0V3tMubN=ZVFmgIAO+3f*0^J`-onMe$=4`U-@G{T}Gy?|2!x4o0sZw6Yo!5 zkL2~TYw^U#_yyV@@B)63lQe$rc34E?Tz&qZuGaY!-*kYle@6Ztebe}^vK|s~1i!8Q zxmp);tSiuapLdLBQrY|4B4$@eujOIC{P5G%JZ`d`%f{NbkIO6I2fTn^RO~Tu)s>_D z#Ktp@c?!ohe$M^HLHJ>RalmsQ{PGAp_QCi;=-mJK;iual?=QAdv#&sX{D!~}cmY4u z2)OF_r=>c)skCj|EBD+S{j%_lOSV0A{uk(;m5d|J%GeVaEIME-b1A=B|S zhu39YSFnAcVD{ua&eYumfew+K#f}OdPE|0I@T7Iia z!)Y&Ec#n#|*yks?pAPt8?l0Pu<@TdP9Qm4QIW32rc44!M+>DOzsyL@FnfkO!TfBCC zJmhPpx$5*MazCE)kV?z^iq|IP@iWekpE3Q*|M*fpzqdRyZ}Zq!at9fo=RVN#!(5J+ zOdU#PpP08eDLVGlrL)Gp_vF5D9sbrP|MSSy{7o-U$)CArT7J%yN%=XQr{*8{V^RKF z-zrtU$C;Dzf4{3Zzw@0%`47Kal7HX_6Y~dOQiu!~U9Omz|KA%+ z^6%?in7{j^@%ew>UY!4NQhxq9o6g9eQMEXK>yDNA!@qS!e%0qU=6}5H`uyR)x-`FC z_qq9(9h{O+GR>cPL;L(TKW&%)omQRlfAw6~{O^3;IsXS|pOpXcoL>18znPQ&`}Y0v zKYU_H{s&u!=6CumFMrmbM&&O!Z(#mM4|mOfYfD=GGyVQF?!~*lH*RL$vT+NWeZt%2 zLl;V*P6>qVKWzVXDoL0iVI>f@|FHchta67Ht5X7D`w!cHok|iW2qh3oAe2BtNdVt5 zRu%G6VDNflaHXq$#VeI`ejfiJCcim(LqX_68H73z>OiOip$>#P5b8jv1ECItIuPnW zr~{!6ggTJeI-t)+;&p}4hcXCt;KbAcUJPvTdZKIZYJ6)V|1bjC5{|Ry)7RL;VI!nk zf25o7bCh;A_8g^|3s)^&S;^-p@m}brbe)cX+2Krm-c3$x9Ujim;r13fj9jG8Pl}a& zwdW|I95}xxCgrMGHTO9~NC&!Vp#wkAd(TlqI?$C19r%IHdyW#)fi6$zzz=lZbCi${ zbf(aOALzX2C?Or_4z|&_fS*n0K1T`ZK(}4!z|W@RUm~;5Z9+QGtra@(16@Uin-1wf z7ZEz}16{ZDUaCp)zUFMYiFBarB6Q#fx{3@p9nyjBkmxV?f$py&gJRQHMDd|9mbl`{h zUsG&4KF12}9_J9n#10@m^erZOi~C$prbl|vR|`G(Lhs50=#d`u2LtpM`6E5( z^MoFJp@%{FBR%L%p$A{kqa5D)$J5LH{DZBeoeCe+A9D24BR%rpF7)8LR_Y%_kMy8l zEA-$C`k?Y7J?JAs558zukb}4UNDulhLJz*6j|Je5^q@bKF8z=20X^#B%^&GOzfcVn>Q2s~{`f{NMU(ll*-tr?o=<|dgd}05B=#d`u zrqF{g=!5W!r$_sj@e}yw1oRiMUk4>U^2hiKd_fO6cD5M8tLZueKtxR z9CCfsIdZ}W-@BPT{P-Qa=g9GS*epMGUWT+#RgUYP~OagN-l zdaH>ynfl(;dyd@Sl6x3`qx62d%nY38$ff$=r>ReXbL6D`0zU}X)ee2mk+TXle$I2` zdI~;4=g8HDpW}OP`aP7~;4h_=0VT=q+G^%-tjW}#|bp+wtpWsm4CL+*QP|T*1v}m54*~_37!4=v%2*W{bN-4 zpnb;t_=Ud@Tem>J<`lpWcmY2Y1GwtA-|xd-w4a~({XQ&y4;JUhA^vADcZGTl-uwHo zAF5wF_Sa=5cj~|2c?|qp$%*V3KmL7KwC640LD)K^TcGCS! zq{ET*H{b(%<uc5ip0<@2{BjK4Q_{=R5sa+bk9 z*j{m7EI*bVd#}^y$M9d)y2NwnZ-5u@LrsCJiWglecy-lb72@ZWe84g!&+a!msPUKO z%+CM0?r#|4BqJq-Li&AJ)@1f|;|Kj`{!XW%M2 z!|Oz_L$FJcCGvhy>=V|9FdoME7wbjBE^T#q)rpLhuqwQoI zoOxt+34EZ}F<*ZCJDu$0JY}P!=sDv0Y0zJcqm*5$x{i2}T|($N>iDD*qw2B!cxEX4)~on8s6EVLqe4zi!YBk@ z-f=LVtHkj?+AiHf=lk(_*mMdktuxF@PEKO)uggpd{8;~c`{KvciR&;9Mte@waj=PT z@DV~ekA8vIFi6R?YeU^1sqvHFE{O9un4hy_YvDXE zOvShB{VsSOecTgY+dh827^jau;eKvjZl6DJa_pAx#Q7nciimc zjz`noaWlyskB-ju@OQ_f+3vX6$sLcTyW?h(J04v#+RguBcRV`J9XDsYF&6h#2k8+oPkUJjDcE`<5?szoa9XFHQ@#yH09{%ol zG}|3FJGtZ0ba&iLa>t|p81Cl(7k51Rt~+l2(jAY!>5iMPy5rI3-Es3tcRc#AJ8o`r z$D_BpyY*N z9e}}UStO0x)*&Ikpx*(|)J_cwDBN*+oAr_B`@jqMMbkBYz*SeTs#u3jfL{?~PwO=Z zeb;O1k01BTLwqpM_@&btLSj1L2fTn^OxiPWJ=(SRvqfAcwq5Lp(zV}vOWpDk|M!!C z7w`jKz*WW7Z=TQSe^mne6*{Z*53L4W!jUAsp+{x!uKsQ=Seyb49m ze`VC4CcK-d5}4kE6~p)w<4ue|@f{k*rP$Amec2d?V!yMqNc?_r3V9xXvc~>3Jwo6DR=?DXsYOi;Hu$YRH8$SKk**C5%?+W z`F$btps)sh`aO7k@yj6H_Zz=x{P=gMZ0EeT?;f95Xn(*9_{EYne(rY2zgzV5e$+I{ z;P`tg?))92*F-=MN<#d`9)8CN&%sARwXfWa_i6o z>o3||@~`%P-~Uu{WZ!|ahn8C7H}CKJ&SxdxONmgwg0oDxa*dFOCNp~fv_i>)>yx`= z*`8HT*!9`*!FvT;M%(p?J(*H;Frw=t#D-@3vvtdUVeA?$8X-fJLRJfcV9`m1TLc<{QkIq|E{F)hM(-(z2%hOs5axBVb^A- zz=uO_x6^67fO!mmSD55X5O8g$Vf}Qv?BXB&a9Tk!@qy!h&~&^9!hKs#ULJOe#$4HD zW9lR$)iBL!#Ynd&=NgfNe@aS9v(B0SpS`yMw4*5R#`h)xm+$Z)-^z(#xfX;#2n2z9 zZa#peAO?bnicK!b4fje&(t8sLqH;jg6<-VbS|qd}1zWGhQcR?Th)D>%uvBQNRlrg; z?W?a>Mdhzm0WJB@GxPj*XJ>cMnX~5{2=~k;=g!RT%=66te)IM0%+AVPUXuJw;wP@+ zo=&@E?LmFCf@|;N#As@gmeP5<5`pPU1{P1hWctj3!4pncGJVOc6HlD6c=`z^FJ7`_ z@Z{;29KU#Q$w`AtXU;r%;c*LRPM^L;{Em75%1b8{R8>(g;$L!Svi=zDg2!RHR--hh z;iuXGwbxQ2qfNewc%D<8>OJxJr^s~!;UAQ%%eC>tUWOcu*Yo8aI9JJR!}AU?XQ1ZW+Vi~QXn`H!XCB@1 zyb64QKi~jfWmsZPzCVcZsIXzL#`CJZ=KV-uhxay4Dd-caoYIkhUDYj0s=v2!>ZD&x zK2@B|E6Y-t_=EC)R4#v%dg2~b|7c&OHM}p#Msc_4agVxpoO|JdL*jKpbcNDS5w3n7 zap~F`5kOn<^#a*SL-JQ{nJ0pKCZ|$9VtMgRzf*8Pzj$v! zUaPj$k`G8;aQ=eDtCy+01&_zcHn|71ASd9m`@-wgny-l6@tsuI=RF0(#p%6f@>Jq` z)_K>8&QUq9h>OSv_C!07^Oa4P-YX9AkZ#;p`G!2CH}@7qJfz#e=^zj3%)JE>59vZq z2YE~&) zkN8OM<9^shdgQ}QAIIl*;hCLPIfUF7SWZ#?5g+=;I6dSdeGz_$kMwIeJ>()i?!(MK z;v;>)=^=NV%bi)TfFI%`{ehewa)DbB{)mtCXn!CV>5&gJ|A>$DxDL6{o0ot2&Lp>U zunB@C>Glrkdl?7dY4U-0#%K-MJ4MY>duz>^Lj8K)ILdz`@2$md^pdg#g5R}f6F?5e zl>Uo(@^;+4wP@#3!p}Uq<(*0J1^!STz^lS#T+BKD?4blB5%xaza1yTXJCrXUnS-;q zL^gJRO{|j@&kiSxaiw@?@(o_^6#C_tWfDi_f0p=B`OkajRi*BNy|uXhfKb2bLXCnTk{_F*D zV`!Hr&fZ#k3Y&1xjD5QO^2y%qb%-Q9sDDI%i2f1w0PF+wi|D5@&Otv373d$|CEAc= zZ>^uoeC73z;Sx0m8oR$y{aEzty#5SYie0)NTB9Da9MsQTd2Vm5Vjy3oE8q`&fj?vi zysB{C-dgizf0?(p*4Z>j69?AQVvm7;QKyZ+>Y16jx7L$lUx6n@%)GKp0`&5qw?;vw zHdIZZAn_;n*5Z0SQTG&x!q=;3eWQaF_2j1n2jPCB7T(eK)UIowR$g90^p2|1R(cE*~>8Y>^6#k|Aq{Dtq@gch%EYN7Q zrkLawttnQiyI@T*^9BCGUnu^-s|3DwQ~UVy9ucx=Eiqix-;f^K!$!0MVokU`e?@DG z6@Oi@rkMExf6;SXuT%9Vq8=*5 zXU+Az4G$*hS44P=4F7I>g0S#zPvRuLFR-^@K1}j=t*9tm|HSi<+r0zjueknEou^+> z{Zst;Vs+gfaYiO${R3a%4>yZ?i14fB=9dVS8`Qr%drQo>i5B^_bNJ7fToaCTvi#?- z3IFZ&bNWpriq?cbv;KY6@sCc~^wTqbC)a$7D%tnjj}7+y^34}+CK>--eb@S*opD9= zXCJ*zUjM7a?8^s!CH2EU^`Y&zu8}8#yJP) ztO;)w54xZA>pr>ZvkQ{@*|qkIz8_6b?q|`JUjO>*llxism9;bOJMTZ`{Rqsu;;>!+ zofnVFO=}?4s-Ju7yy~KG|IL5=u4$Xjn|uByDoc=Ad34I#gbpgtCx~B-&bPcKobAww zxh8yf-zSi~hHJv7+N=qmdfX(rCVbxD(t*{>R!Pa-_@~?N|B`{x;l&G&^R8Ha%;1_4 zuPfJttF|tAW}xbUZ2!zQP=;?=yS7R{tOq9-GCDDyo%7}$V@){L^cyE(c1J^{$U{1PT_2@GJf!nE9poXM_=<Bcx6`DY-#7Fvw)5mf-J?_KIKjI_(&72-`pJ9H@b_)0*KGF|yddNlkBK#2_>1T0z$VIs| z+b!rve5Cg|J>(*N5r1)fo@acAU@I~ ze~=6PxDQ;X^0Pq%FmAxStk2^J#Dm_Oxf~SLN34UO=c-ogWZ%H+WZ4aW%=2$QR4(+} zx^zEs9T3aGbIs^SdGg#kSzBCRsd(TIe1Sio%LB@X%8y$o`%3X*s|WmnFYt%-;8lic zU2N^Phj49*2v6a4&iXpp9`S6O4!2HL;n2yy#NP`-fzR#n#91dxyG@Aah!VW1F@(13 zWYHg@e+&kceT{w-{UZ8zjMLFiLLvG`>vgj8d7Uh~!GEcKEZmmYpFvBpi~0#UsGqs= z+&bA}AYY{`;17I(KV%2Is<2xp3tV;-m-v(GWVt?1)OE7qE4)q?`i?Z#$=+zJlSOz( zUnh(H1^rF9NcA`9hhT@#VtWjBooU}vx!+A-LiX4@guAnN=)3zQ+P|SEcP+dBnHTT+ zy67a~M&DQcO!RbX{SD-xz4E`8Bd_-GTvbo8SL@_?>97hF{iXY)Lw)PGck!)9`W3GeB6%eDMDZj1%tNJCtA)&K6CsTL27H0P;8`vgTt3vj-ZNXd z?cnb-%pbcg@^`4jbvy8AAPh7R{}TR|32xg-K`7W$k!g_NQX~hFoh&>BwK4 zUQ6n{4grUNL%<>65O4@M1RMem0f&G?z#-rea0oaA90CpjhronKfSy&l=Ya^j2si{B0uF(;A<*3O#Pr^L@!H9K`bB=!cZuoT zuKW{@Jf^TanO$0kN&6JwJs7+f<1bY2#o&Dzy#IptVX*H3_Ag*@-X3BdC-x7e_d3Kz zbl#r3sPCHQtwj&lsc-zk^`GMRAD+y4j|EEVxbb@xEC=g?gKy`_d+$6Yir=f)HudyW zxQ-sWv$>&* ztMk@%=e<{v()tW*=08l=^!F;JiFPFKz z56{2)YxDl`_NyOy@BA;!-AS~Kdx{@5k>CgIB{!RK`>C#D@5PtS@VuAKp#2ngeR|)1 z>c2d-TfgYK_T1%7ljv8UKlDF&{HfGZ=!E=3^>2}ApU|J)FR;pQ-qN?9?A(w(zoUf0 zzg6P|-&gxK?4HV4ts3!o1+M>R`^xVL!CfGBog5rFcg2#y3q}S9Q;ACjPBc=>Gx0p`KxSzv(>jqwm)3B!0V3dR~OQ-0uhlf6C)ccKv_hao}Tl<2GGOz90P%z1^&Ws@;H#ohvH549h;S({wCoU z#HRT+?O&2M<5S}ZQGS!}(9kGOjpT~P5s*UVKkqvVDs_4sfix4rMg0R`;4k9(3|`f} z(tZTjZ%yu-!v9N#Cky=W{^jXOgp`lk89LPUPm8)dZ;t1|_4IKdeV12^<9DBQhWr(e zBS;>}{ZBFK$m5SB(6{A!#BU-V;17I(Kin&L<*?xEaWM|WLHr%@FoksfZeX5n=4coP zfUMAtj~#C4?)!L$mv&8z<4PF@IG5w&hTyQl~Xdq!96UySO3rtM>>TY}!H5 z%<-XOhqv#izRQTyZFWWTERIAd<-1pW#bP6bokO^y;1tO znL8W;4grTig20NA%SKlYEFK&^<`Qb8k_*n~5O4^TLqH4;Hq!_J2c+~1kMH^7b5WD! z)4{3g!$=;DALM)%f2RY_F^~?=H}Jdy&o8jQDCV^gAM-JIjzQn2+H)8A93%G`vVR1B z4;gO6_UeOq&mEwp*u^;9XE_*$2an{*yI`J@)Q0)2MV}S2#C#Uq%yW$0#rJgW=d+5Q zV|2}Y7V`!E!iTwBFt3WY#p&lzt;|O*`fKKo-3)*9J!E_SioS=e_?!6qyn!$97j0Gi zrRyQhXWgyY!4y9BVd7Sw&-%KsY3R63Io{svVm=Gk`7|8;IR<}Ecb4~nn9q7Z$kS~o zBp?^_S=4?Ne@{349LmN{)OGC0ezc$93;g-q9)nkP4`Tj!(QT416+T>rYk&UGo#MpT z_(s1oS$Xc@F!)0l*ZDFW$=|L5+~hgp*Sx1D-zk2@{9!)1K7U>CJ!Iw!`~g((itwxD z)~kQSA@P^@9C6QGo)TAHJBR;V$?xeRoha+nz8w1KSE)Xvj=>*)x<7S71d6_=`|F>3 z)pbwbwdsm~I$O$l{4MXRe)&B?-@Ui|d=tsIsb}WQ-XC68-Q_2b$UWXxKJwX3$6s{E z=1qg2d64D@DE(t1&CA=XGez{;Jwn!)NPnbAL+L*t>b9(m}mKk>xed;W0d9Lj_GQEtT( z?_d6F-;A$5v1!9?=gIt^am8@;hCex@@9?AVmw4Q9!Mh*$+i8QC@kH+We9RJjHieq!c-_!l7THnWcO7>I^^S0(JqsW4V*9GHIDT6 zQ4tU6LQV&HNNj#j7x9qpB2EW+NN0Xe7x9p;m(xKW(wX1WMLeW?fpLaBq@(ZY(wYR)Q}lF*hjc@n4)T!B{GKl2A>Axa2YE<0yi=M# z#6vp7gFJ+XcS^o*OW%w2Sw6n^_{@h?c}0BSWAaJ3QhLNk`Y}!qxi7GMlOLod@)Uh1Lzy;OFCm)|DWy+ki57y4~ox*z&pD&*j~RrrTIdG33u zwz$4h@xUMW0)HqE;8o>ke70Bn*+WU*M3}#~nVc*39mRrU#>5jhgKNpjRC&3^10)I#dUS*iRm%3&6VO;Yl z%={fA#*HV5A06PweJ@qv(aFEW-wQ&4&+YNV`CjUt9{n@z8SC$*a({^aF?g@CpU`ij zUqt_maT@wbaEAWT`g^J0P~*6eUH?VZj|IQW>(8L2*hT$>9MsQTdG33u#X!DFSHK_m z0)NO3cvWHdy;R_`qqxMM{9Y>8=ZX5g)Zi8VUMln*$@wJ~uqTV`J1X}>;^hJwkJ9^q^u5&Ko!%;*E#;44qrG2}-%EuX{zmmP;V)Y2 zZy*QlRrKo|d9@$SrToV416KZCj0d%_3KagO`=moYKizVuNGsOS!A+hSd&&1whj%(y zpiysM2$Dx~i`LPp)bzw{Vjk#kz!&)Qf5qj3%ZI%C%IDL3wZvaP^T%$B{1vUEQ~XW* zb#&kh`~}Y|{=lm$y%&r6w{mMzl0~@x(uXPhZ{qhKeBrOeoNM0kZ2jxfo=$&n^FO>> zC(|##Eh2GL_t1V7ucMpz>#)EV_(OXPUKRAT?(yRfF%7~I;mQ{zfBHJe7p5dJbRX71 z7F^HaZ65O4@M1RMex z1n60M@$<$^ba%ob;1F;KI0PI54grUNL%<>65O4@M1RMem0f&G?z#-re=yC+?o+sWc z){)n?VBa2sjGjftYkSLnFO~PL!Fw?zmkzv-iTw@mJ`CQ+#Qp^;w&%THtXjqQ>gc@~ z+OO@a;=LHUp0^g(e*^C?&2IFZT0igqFy}oMD5>LOT`=TeU9kVN9C@{u=PFUWzjWmv z=cU4R^w6byc!jQfF9!Qc!_B-`LHkR8RlE~JzkDo6Ch#kIFGi)F`0vGlFYp)qgx{;+ z@UK6_+{%C(`d;W^vi&6Yd{P$wO7x)W*%=J1|51V_h;xy zd@ttu)c0e=7CFf3FFAfj{)8sD}#lS)%{j@L)nfMTED=@bAP2 zDsY~@RRO>5et`oA=qD4uBMk5U~; z9YyT|7nhS*O#5PN8^6Z>Whg|(StZ|xh!e%fPV4{Zu>6#Hx+A@1jXh;H1jtZ+;=!Py6GexAg7*)?`2JgRWdxy|6F6 zpZ0%-XU-ORn7!c0&-cCepx)}@j~x2ISwEPy{*hg;+jPQTynNc}uiv+N)(gUV7H{x$phxz(a@q{`$H9;HmwLDIWl`MIBNqOycoKfnH(x4{p$<^93g4xO0$gZsYa z{@@2p_2^6WNqw6nc6XqI_AI_{lR5~F8qW2(Yx^01oT|4>@mdq z(r#G8`^vF<;0IJVdN=P6{;vA_gOe>&^p1PIypi2d5fP9N>=QkU^Oa3&>@Usnkk02Y zaXQFL^rh1w9@4GhbdZO1=KkP_hjam_gS;eN zdVg@lL%IVw9pokH())uW9@33-d4N2mGxrBaJfuT;f;^xxfqgFw-MG(np*g za*-bSFw-MG(%;PKAs4t86u z4E*Exy#K~C++IQMnu2tv=xu_Sw z!Nd>ok^VqV54lJW9L)5HkMy_>xk!)uz;(KRxj#7f3z&EFIgEI?Z}5-uV3sHBe@f3? zto8>#g!cz$H~24}U-`arq2Jb}`;q&Dvm89P3b*CSbNhqa;`&O(1ApKP{6$zVJWFBC9AZ z?hp5a`$K%(H^R8T(V>Brg9|Skyt0K`?BsnRzjS|ce|PRrC(i!vG*>!B%;BYv&6iIW zGkL`a;X&gYjAt;u2`=LO-FcjYaSg^-&+vE?;~Z$f_{MgBcmGSuj)>jw@%;6(dE*gi zDR$|8XnfR;|?>^Po-yPu{et&oFU(nx#{Ja(Y5T1kJc|ehUPUZfucpVD%cfYmH{_f#t z)&B0W`(4$~gx_kdzX@3m+NJb2>5%JKYv-zUkZ|Q3pqd9v z_IJNktYM{J@j4!oM{06 zyK0_^LBA z(NkzY!58>LCcvu-Yx}$3zV8ngc?x^0}_maZIZh!YeXxs&dfJ49`;1F;KI0PI54grUN zL%<>65O4@M1RMem0f&G?AcFv{cPf6~n2GLAI0PI54grUNL%<>65O4@M1RMem0f&G? zz#-rea0oaA90FaAKy%L%)jJmi87&Ks-@h!ozdOGNgZE-U1>VQR{uFp02Jd5H{|Usu zO{`iq_jmtrz5U(y=l$K;jh^K7^N;1c#{wmFT&xR*9IOlW|0PFW?YenN6yB@&hjh4( z9=h})UZHEhzx#*9J2CVtUY8I2ir$M+sVDw>G2jdQ1y69f;PN4~;Mfnl+5N$*3+K(AvF7i$ zta|c0{j^Uo?GHYB^}(tA!Qc1%=TiHFf8gM+WcCMNdCiL1A`i2#68nSy?*n?P_YEKV zK<%-;PB{J-;iiYZDSgLZcVP9x`!?VEq4yv3@Jk>2#N1!*`lW{s^@6S6Kk=Y>i!S=a zLmR*Kw{zdr)0zFjTe+VUkrOzOx9_*@IemZWau8+r2dA;(`*%01$KOkhAHy%J{m`3Dui_`q3iHz^*I~<&3%{Pmzh>{dzb-EL z+tTCOCmw%X?oelupw=)<=l$lZHV#e2_Qf-KA9+!cbP7LEn029_@w7+KPS z2$3|w1#(8uKXVTJJCeIaWTy6Y+QWs8biQeSL+Xv|9pL*VBN73qK%^K_ZWVFqd`*0R zZPpaA0g3R_??CzWz4r*8=ba~h6jyyygw7yeaOs?W(0Tl}NIfdt<4x6yn*cL+EHx(0#6#BN4)HPJb@AHAraC-kz5DEZ&WhFz6)Crh32K6uq%Pno%ye*ewC4Xf3D=#bytZqi34 z_9!q-BQx(S6s}d5{_S1j$yBYX>~D209kV!Oet)3ZaIxg%O4N7UL-gFH_)z14$;Cxc zCVl8Phd!7mrl((Au8HSDGM4rS9|rX%i>Cz5A95VAxboJ@oPp87%G?#pSB(seuCkYN z#_+PshZnc{s&1_s&P>;jR-Xg4n%+bp{EB)$2-m->{`11OJ+W^UKYDgY^28XjkIJxk z*5dUrk>We9;@L|c<7N(A*dZ|C5s2+9vbP%CEni1pl8xPoT6KxPw_2MfI--hDiMlPG z&i3E3cCC0O|M+QCzx%~cJi7JhoT&5SC+DF0L|C*1mDws?G>4jje(}ToQd+bVD&6hk zax{n94N50sYtL|N5-*WNe#h4Ho)mFaA5jsmcK;$xG)IOfi3>SB#kngg%Z4uThJj?q8E|kA#etWu{e;I#KxzUB``KI0%)cFm+Q*HqF5fx6dTC2+E=si=!YQ`Rq zpQ-mu^So(7ZRS8Zir&WG%{e*UA7&C1obc~DPR`p!pLo4=O?-os(sIREs7Cjl#|^1C zP!v!qlT>IXdGl!kgi6pWcDzoYCmut3$II`b$FnTebhu`Oy_Unt4a&M3IQi5BHJXS5j*e?{1x2;(d9k6*IDG3 z?IYdu)(z`UqjS&h^_cjb)lb*-BREKX4=(tx17x|S`Z**bpgz7+z)5oa*(b~E;r~_f z%(~=9>Gu#CmGAw3WL=SMIzLxB;<{-U4)J}c z>)rmB@XPyUaUp(a-V^xIjHtp|j|*9j9$tp*Ep>k&E&Nd7UbMfh&JnfkAmOT`dZGQT~9RZTUmFu_=G_ z{XUF8&PDsT{|wc?e@6A=(~PWz52wrD_9aVdRL-eP(YK}2^-H{mAqpSWn_9AnAa3U< zjp)B-OGo+pHpFdYpmsjO!gM&;P0Vh3H1LjwYSEZVQ>^7~w1q zad~F^Y|3*e3W(1k^*0(>CXWbf zQP>MUfu9YZzNnuO_Y>6LOw+{r+>iJ_Q}&|2{|RbbT{%g)GnMQ2z?~(}`!}h281AOR zVMX;v{{A!hI?H>C-J{g?a5s*3A&=khWjUWxu74q?KT2Kq_vd)KseJjf`Fan_xrWm( z;&?L=U&X_%hPSi)qtyAZqFlmrk%$C){ygqq!<#wcgVQP7tjx6^r&i}Hwga1W(S2-!GL z&LF2#mcUFF-k~sP--@C}-iR&6Tq^ zP&vbcI^jh*gPcy4vmsZ`v_fQ-FNC!y>_s^PezxTdT#mpu=10JHv+Hzd9!k`g z!soHQTYoO+fA}`K+yTF)n}vn=xj>u-e#E!JTFwESN-4y=NZ+5GwkyqTc&q>S&3(_E zw?X?S#_ z?~6WsnY1mVw<{O1k3II7W0L>#21hSjwPK}PM-Okx1VI0PI54grUNL%<>65a?0_ zDznuZqWZT_cFRQ~3ha%m*=`wP`va-x4h<|{KDewxwo)qx^g%xK`LK7`g}&oTDuWFU zeUJ}*V;@p>74iXnw5GSrq3n6}e1PzTeCP{UAMycxGs-9vY4D5&_XqjVH-446KjZ`Y zPAI7lkMp4q@}VzeeaHv&%`B-8&xfE7@}aMn^&ub7cVbC>SbGnBkPm&)2Nj;k2lSm( zQXihTLLcNq-w^9VKA>+_NqsaWLkILhKJ@vl5BY$;lU1^&|Dx@IKFEi@u`9X$v0msq zu4Ds)w+)~V@}VzaeaJ_wuVe$W8zTaJkPm(1Yq4`vBKJ)*I_9*}&{$+#lpaU%>j1k62&H24-JF zALK*d_-d|ytQY!@FWJ7(`~V%m6Y`-iWPQj-tgmGI@_MB%)(82}*US2lk62&H_GN!V zALK({w2JE=>y7o5Y+nvA^g%xK4Y5AtBi2{4eL2w32l>$Fvp(b_)>pE9k>5cPI#FIA zANs~dx&E=4 zVtvR*tgmGIQZe*FKJ@vl5BZ4om26+88Tud}`o>mr{bRkczLM?Bn+$!B4}AgaLq1}C zCEJ(74SkRged8;*{;}RzU&;1`)(Fsn`VRTf7qUL&Bi2{4eR;D|7wdz3=<8*D$VaTN zWc%_*hCaxLzGykuKh_)TE7`srY3PG|=o?~v$OrVDP_ljLHS|F~^!cn0`H1zEY+v4D z=!1Od8@rtAAM1_vm26-B*w6?0&=;^it%h&N35@8`*Mt-5AvZex{T`|>y7o5Y+tZs0__>(L*EeV zLq1}CCEFKNTj+y)=<``0@)7GR*}kCKLLcNq-`M-P{;^)@n~97vAGQvvE%ZS?^aZRB z`H1x)qqd4T9;z+$K|b`24|Dxvy|F%Iv`Kxaw$KOp&=;~kKRK*FV-9>nqv5%rou}@}VzeeaJ_w zuVnjjx}gv9p|6+qAs^6pQpxt^3_~B}Ltk_W*FV-9>nqv5oN4HTeCQiueaJ_wuVni| z>-6bB`vUpU=d(WKBi2{4eK||1i}gW1^oYAs?~6lI_de4SkRgeZ8y?`H1zEY+ueb^g%xK zMGLw9vEEo;$@b+PhCaxLz9H6!d_do1AF;lY?aKl~ALK*d`1`p2vEEo;$@b*}Lm%WrUYk62&H z_T`<1KFEi@Ue-dJDB_T^oMKFEi@A=Za{#QI9MFBcj5 zARqdC)`xt=`bxGh?>6*7KJ<;fm+K$vg}#$ZwlDOa6CLQ^As_kz)`xt=`bxGh?^Wtz zeUJ}*`ub1^9AF;lY?aQAU z`XC?rqIYxsW4*DylI_bvLm%Wr-w^9VK4N_(+m}U#KFEhYpYz!us-A?)>pE9S#0QoeCQj07uP@53w_5;FW0~O;Gu79jI(O0g4S!U>ieCP{VAM%mtE7!nWZs>!2=<8*D$VaTNH*Z!9#QKnrL|?h~Wu>7H@}bXXeaJ_muUz}`XNEq=hrY4%x&E=< zL|?h~WyH`2`Op`zKI9|OSFU{-HS|F~^o^g#^^f%?`pUI0s|qx%TA>Lm%Wr-w^9VK4N_(7x1nz^g%xK z`K%B5Nc5F!U#>LtK|b`2y@Tr?>rM2PYhONS=!1Od3s@iWk?1SezFcMKgM8>4KbPwt z>rM2PYhONO=!1Od3t1oXk?1SezI@ow2l>#~%leRyL|?h~wP2bJJk8k<)ix=nUT|M)ge#-`zqRHiy%{dG4z`VI+nbjYja3!_)ZzDNTQ*w&;lpC{@lg?@0-bC2*DIJseIZ&Jee)QZ-Hwmf-ac>(S}eJ=r(P5wULk3?E3o91!h@Zc5a3|u*g zF{OFEQFteg5b}4Ge0Grz=Wpik*uWj<@OIHSa=xlQe<>Pi$qipfe`gBUbRO}IsGs)k z-#_+S6(26*x62(nQ0;e3Ws9Ef;QqcZ{B$3IasS!xAbH-?lb(vR135?sIX=sQe7`5X zuNw(?Dn|~|K@Jo_zQ0#vIiW}d-09ufymCYD@Wy4Qa@M@c%8?Z-2S-*755ii2W;=KM zcZxT-NM-7lZLYY8c=htP_{zo0N@fS@V>jUZ!NrB5{2^XZ{wUq*(ZPjF2A8iG9vxne zXH<~es%z#8@(9102%vuamGI}qJ!g3N;DW*Oy)3m;^xiIH(=$!N!aTw?`^vr7C|~{J zBHD*-!jH7V8z0&4i%yl-(4N5EzFj4OT%6w~PUp(KdvBQ!m5Tld@K6R38oN`9q8wUu!Qwo=-)2S)xvz$6UPrhB zk92`n>SR*^;*a`d=)Fkz^KkZ=zd2%T7l;?)@%^eZ3*r}LV$S)qmn`vyj+s8aoGmKk z>RnSx4c>E0oh%;^{l2)@>1r?5o?KMQ3rEWQPlRKfp~fBJ+jadEUyV)7v4|d5ewVXP z$xffo-*eJ74oNii;v8fst)`w%;+8F^$cxJBtB)JWxK8Ummo8mO`D-^%KTu!@tLchOW{Qr>XKEMp2yVt=_%l^Rl{S{ zID^Jx^vnz64m|V1eIhR^C2>Ya)>TCyc{a4?(;wM<;y1RQM(#1fjXwT*V?3@Tb?0A{ zebddNLHy8j3E)T1j1og3=ArMfk6p&x^o#E@-zmxs9k{NZg~?}|%)7}m#Rlg|I;2lr zRUQ(a&F}pBuqzg2zvDzYy6Yg^@_tzqU>5(>izbt?yUcF4FVUoZsQr99~Ji zMOkpJL%<>65NL>i=tgSQqs8ATY#3$x6=fIo3Q@3&o_+CUG4`)j;WpHgicoA9QM5e$ zT5{@N&7ZtX=`a^ZCyM0Q*+n%mEN${Y)g^sLi+C|&8U%mP0h1)lh zd%(cLc0jOn>>>`8=h6!EVhfH z9~_{*Ni^TtMOl8qcRtTFUj+Ob*+o>=lr8oyA!-cx#5w@joz$W{|LVRCca+b>u==iZ%{7j zpu-Ez{A~FQcs$i9K8GBi8d)Zf2y0Oc zK7pStpCONnJH=<<_|(V(f2ONNG57?2wtPlx-*k%4UdN|KmdPW+S`>p%;AhLH&vt63 z`1Bp08d>1abhRi3pTMsXpO}C4uPHtM{DHxdflCLoS+PB%KUPVlIV=@wIUt`Oh6kzV zD{dauEK7D_hnpQv$+JVmZ@K(B0S*C&K-VBZ>vC(nE?3Py=FK_0QtNUF_8xCiVP7pS z^ZXpel!qC{`P{h^x@b559E-8?OcSy2Ljv4HJLaDuGws%@(E)0lf%zJYJ1|}bmy{Ry zRi8nUsLx2djpm;NH~*|4i*ZB0tGikh_7Xp|E*JRGcv)dh5n>+tZ0DcByU8<2v*B5l z&EomzF`j?+XS?}l#gEP}{DgM;z;l1#XKNRQ_bQy5Uza;)*@{cN7G75@eqXVYzO`0E zvaRv=cXm;6c|y4=cAZ^Rj7@!9TP?mWy+gnu&^-vy2&q-O$Sbr>@^LI)mrL&}=C8eq zC6TVw5AQ3|c(7nyZYqDTfL$clzNPIVnSYTFtiv_KG)ArWlktr|VqNZjX}bvH4s*Or zdGX`a)VI))bsO15(XURF>otSvm%H~CC4PjV`BUiXe_I4u^n4 zz#(9Zz>c_&OHa0mPHx9+<7i)*_#K=inm#_%&%Pq_MJcq|EcTB*kA!v8j)18%nSf;Sg{LbO{2~Evoq<+;B3k!kI?>c9FS{OZ5M#`J%Am=8KB^VTG>#H@1ryzaqQHb{!pfH+d$V zN&U_8tMb&?E()-Z%ahJ7YL;i(#|8M=+C~0NW$mK5%LcCO%sM*S^SF(NY;(fhoLy90 zo~XXo|2ey;K0d|xwXq~SQ4RrzzywDiv5R)Ev%lqJfkN@V|DM>R@sD_{Z39=aT}12X zlJ#DYRnzB#gr0uV75^|_MB~8%yC{`6JG%(F?c8Z18h*l?nlDoC7fCrHAMIU77wwX^ zi!kmm$IHZWf-ChcbY$H|c2UUV`e>@Ni<;?!VHW|vR_!A2Zt_g5w!<#!#rs7MI=iS@ zp2;o(eztZ|_^DRxqRN6*Bf~34y;2`VqoyJEI3o9K>65a}@qK3(6_+P!kL&-OT~r^R zV*E;%TbIxw;1K9K1T?#dJHljKm4HFt*DkV)ZdrQ}kF%5b@I80lEZwHz)AjA5eULcc z6*kx-q%Z!#E)t(x-68Cv+pjoR;(-B2C+(tO=d@jfafdlxro0e7>Y%=bj;!0rE(+K# z@_U?J)Jz`?y9oHTY8QcblV@TzslQo%={n_GmCfRHbUxlMny$v{DqXk!B^>j9Sv;_g z4*1#HMgBD{*+mx&t-kz{Y;LU1pqa`pRGg5m@E9f5 z8SAC-V8MJ*N+R86GImT|(gN*XM<+$gysLF|X4u?wLCZ>^SL{bODQy>F++mKFiRE^z zqw}$jZqW(uef-?9axE^8I&H9vfM2V25qLLwCY?#yMqaY68VncPMdROB-xUfg&Mqn* zcj*i(KkOplXKNRQtJS<*^ZU`wUAAKRU@Hsh3hkml%HCcpXJozbdsKVX-TMa+jC!3k z{Rkr-h1IXSaRUxnT!2p&S3M1-bB9B~A>a^bguqma!25KoxXHLGN&8Ce(@pE>NI$LH zD>%$?XIJmL5NuN8DH@N-@2c{+!yGTC2S3zT(2;e``66@Qh44DJ?}EY(_@Up`-6RHl zu#13SkzHiF?*e!?c_w{H{mt^L^3!;}C}O)Pn(FML^q8wL&+jLM{52ycx9UtKA`T?&3owO$lmX8v&Sl3Z`)9Uod}13L!es_5dC7U zN^>+*>bze>c2TeR(Od`3$vpew%VK?8tqQj>Sn2j`zd8vpu1nsBNkyjq)%?i_ly1kJ zFA{TPcR$)kKf(}x!jSi2sJrh%_$l?AHHCyo>)(~Oi!kmm$ICSM0j{dQAW6hY+BNMW zbKix)*+mMn7`Jq}PB7J?2`}s-;8$c9+3vdl-c6oKs}0X;FkC!e6n;<57x_KTE>fJ@ z^GtRT@M~ljQMn+(P`^)4@keZ;j*>q)5{{E|rtc8*gb}7S0NDdJvnoeVW+TY*6>U`Q zj(@*$gZq>l-mBbbJzrnP*YDx$ck}hHC^tvEJcZ{x(1UWG{|yIVlywV@K2|)=>qU$5 z(Ou{B$~Z7hBSHL7IR}0=V2p93>}|Z;ccEz z;AhJx+V4*BIpp|kiBI5X%P0EbPVpHyK3n1w_}TL5^LVOLeD*p%TjCS=+433ixVTe% z`i{?*_ym5oe1>e_bc)Y$w#&7f>SAy6<00T@%V)%PYNz;&9G_bGZJtly*ND$K=Zn2C z#f!w@BK6#%)VkbNLt0*&_7*;hpy%psJmfRo;LGYh-8^bhnW}%@;Z`4?W}b<*v1~h0 z4grV2ghGJ2Mc((n!TfWB_Z6E!rT+Vh2iKQm&OP%Ss+up^k>{VqZOOTNo^O`-LHV_r zf6j-bRt>+T#u=Ee!MFqCWz16%%k6kyF?ycA6aDVKo53yYoJU`3v+$7I5F9-Z=?IQoe(st3v z;J|1rFDw??MQ@?P)V@QOz36Y8U8L$|Uc1rwoU@A>W0a3?`wFs?L+Xqsh{#)U>EUtP>G|dGwDmpHu92nRoN`IivqTb!fnnjYL;iRi-4c4T@;>O)-IYiFml=8 za&P*HC~D2RXr?mh{y1}{r4zEv3GPt$*~$G#vbm)4kDuo~yVqm=6i2-iuh$L4N!+CE zPR=E=%AO99B zMgHv4cG1Yd72Yw^OMMDW<~-drXg70|=5K>nwmH#lowtjU@{e4nIdgUqa7o;rNt3m9 z1Lt=%+>js2AN+Z4-gVrQa~%Q>0f#^%1QNT*o1#7?ob6ZCTto3XI%=DmIqJ_B<>}X? zo4Q^zb`kb&vD?Rmp5^O54T0Dz_Hns2Z5LtOVUCw+@RRHr3cj+gX&2ExF2^j~zLDIK zf$bXuXBWlj7x&Ft6!yX{0)9nyk?lG<@NV)<>XQ1Ca^j2rvTFE%N(Cd?p!JB_P#bN9UQgN|G?wS8Nwi^alH~kuLKmwNSnb*3rr9 z_+z(@uHD~5>lb-eKlMJ58P;te^4lEZ{i3yLy9nbBbG%F}x8wbyfY;GQPr7w<#p9YR zcd=c>__b;mfp?Q<(wx-a8rRFLs|Ld;XSM3Dr_9_;zyIdn_1hS6^KIiPB;_}pZ%Kun+PnBPOwGpYGan@IMzbbZI3FA}z33*SQvuFwA-T6AsNF2cCO952)0 z$7Z~ow~p>;UPpI;SVtFL>)tO)%3@I;oy33-b`kJv)h+_>CeNhLhG#VxE}kz6pH=fk z(R^nY<&U$7`|LqHlU)S-8rek@p9n+!Hou1^-uuthlW?5P1I`=@Pl21vAL|jY#!{7| zqjMC|sqnL^-HC2gu787agHJ0r{1jjRBwr8t`p5bDb;{K>>wdz8zMlm>DCh0|9@-eM z7u9ulufMtWjLJFivnl7qC(295_~hp~-OHhV=Oy@L{A~F|z3&vCq2p5{w0S;(pDmwg zzdOa}kmIu@K7pStpXi4>#b@C7Y>7|cXUk{Ax_ir7K1**D`JEEu4Qo)>eXDJo&uHzee4sn@24wQ}xd~-0I`g%rjBD zV(Vf#1RMh0hX8epJJ$P(udh!6^{?hnrl5Hdb6qaooj8~JF2SqwzGAI9W5#H8*Qf71 zg};AhhAsAOk+-S+sa1nbYJL#&H5hkbyiAzTK{zDyP1Lv0k#!r*KS#gh@1d=9>vEgv zgNYycJv7FT#>)!p6c5(lLj&(7&m;|;=kZI|>AV^Y7tcQrv0dcPcJt58@=Wt`z|Yn$ z3U@1Q7mbL|p^a36fsrMW+ou1hqL7n}%4-`B+2(`~sPg2-_vOa-4!3f+wXqyKQ4Rrz zz{E#D45Mn*H;Vh5(%?JMy&?{c>B;tZ_QjWltx>DOZ46VoJ*)Rlq8ir~cGo)(~Oi!kmm$IFzL1dpser1D&= zHnNL+w=Ng-3O8M*ldu+ry|9abU#oTzcsF?_bv8V!vRP~w_5M5WYMQzJ{~Q1@$5 z3_gLMEuUz=%k!Ddi+;v;d}?s$9O`~83VYGs0zX?m(GPcu&v70nW^>$)XLJsAe-;by z3H)sN^m#nhDLx~|r$&~}q3+kBuorv+KU+Qn9v63t&oRfRMwZT@?$@Fid;&jPK0~%| zI>l$`_|(YKIn@1H6oXITXUk{Ac50{i9CCbWWa%90el3c@C-7^;XS^=Ar^Wf_`74H( zm)jUhf2@+aq2p4amILy6c<^QQe8tV9>gCAZ?{KrnDtYcrY24uua0oaAtPv1Tg?GsL z=Sh?Ddu+3fi^JwjgBb=Quf_T2=o9(#&(Y`AID_n8dcKcw2gb|5fS`n5^%sN&`isPE zH2)l3v9=C8ZRrXDMpOH^}1Z}Zt_ghY z9By;-&&~2o^K!tikzGXPf(S$X?$rEqy8hGrb7l6Msj#Hx)>T-Q4SCU%U*A>U_%D^O z@Jl?8{5Q(=zo^{c4&{co^Yz>K`mKEZFZudf<;Fq{585;6K{;>t{Bz*!e+_xP4b%Nv z6!sE7RL+5)O*xnQLUDQN6raB1QzJ{~Q1@$53_gLMEuX0Oo#J!+yQ&|`=C~Wr=p5?) zEEcGrz|WRXwBP0V%;rTu6FELLICKtmzZQkP;1l@S@`--9Q+$p&J~gs*4t2j4#o!b8 z+433jc&bx;hK^5-ES*E$uSGHV1b()B`aCY~6rV$mPmL^{L*1`MG57?2wtNO`-*k%4 z!11Y(rE{qJwI~Lkz|WS?knPk?@!9M6)X35~)csl%gHPbsh)>Kvhcnf4hZ6fjsrR23 ztXNuZ`dMy`ki8Lc=J?#RrBBM|;r>nPKHWU3UXJYj4mW$Ovd<7pmtB|8A>a_`E(FAM zf}4MCmGWsq0Dh2#d7O5<{~UfifBreVPK`4#UxRT6#>+HUL`Qo5iTV~gvTmdK=g`eR zE9heU^7?5l3VVqkntujXN99Z z&+@%c#;=iGMCF1AL;cRqKYQ`|8pWOZn{ce3P5XTU@ zUKVt}7KOdU50!J^XH(8;{u$+^Q+!6eZYG=KZakxNsQa^6fKT9O%O~o6r}!Lmd}?Ir z9O`~83VXpP@U!I;?RR-Tvw6|agpN-Q4xK~YuSH=m_ym5oe4-!j6rV$mPmL^{L*1`M zG57?2wtR*>p6V2zf#XvnOXpDcYf%h7fuAj(5s!;I#b>YMQzJ{~Q1@$53_gLMEuTKy zH=W|scYJDO=^W~QEsDV>@U!JJU^}%_e2(*Tf^3ev@r=%)?$2U@@euH9#3$yT{iD=# zhw}5!t43B_Hki#&<1^_;Fk1W>n!gQR`MfB)R^6wYN7c)bz2D(xk5&5lXd6nf6X6hW z2y_bq;;FEke{PlRX+i*gkc9z9JLaE*kLAxl2P@V5AdSc5`(-@tz<61ZD-X&G{Hnj8 z)6~bL-A41zft!C;kj1#=_0w7u_7Xod{|x+SyxhwCGk7<7CUrJEtFl=<|2*`Rnt%2m zbo0-up4jtD^K!tikzGXPf(S$X&dxuhjuNxUk#L-xGkyBpG4YM|NW5)5$FqF@c@I;l z2$OFA8lFe~h$#OXw?B;j_ z$ESu$^X)D0v*i>0aHsg}b$qtOC-Af76XU5)@##B0TjCS=+433kxVTe%jUbKBbl4aL^R(AG{bR%qB$CpU34u@ z+@xokh>stVV!-j4tDZZJ@Y?V0NBihU7{X8IDJRTr*zdp1yqi3eIvbu<*({!a z4%jXV?x{adNctxJ0bWfvd*_&!1Aex4k-vW{c2Q;a$lyRWGj?atOl4xv%$#ZIglu#C z%bZ=L+F!FQ*@c~5WQS80`A9 zASrZKb-CfY({>TY9p-qsU3O7abKfOG zIm-6E=(Cd;@WCzuey!R?;N9ez^d;q<@!J2S)S#7IgDQ; zyNJpK5r+DWb-7PG{=g zkk`wC?$@HQ7xq8!vnl6tUnnjwo#M0C@u`uebEx~ZCH>*P^f& zd;&jPK0_W)b&Ah1$EQY?&Y|wtq8NMvKU+Q{9v63t&(QIyk)?B}`?V+rpTN(SPoM3Z zPVqV9_|(YKIn@1H6oXITXUk{6c50{i3>=>tSvrThUyEY!3H%!I8L!LTt(E!bW9JPH zt{hzMO`m>THcO4p6wW`N*eGRl*X1+6=w0ghiknB(%aOg`;bxCj`uS*ch1JD&2si|~ z83F1R)wvCtzm=VtbBYu6ic>bBz<>t+KX!1x`>L=!4#9X+V zd(r1(wEIZq?-iJTmifVegXW+2`RJnR=+NGM>u&w!X*7p#h6M-4x?D4?ArO0ORsTXY z&cJ*P#vK?h0|UxS@|_auTjw{Il(fPw8B!(X1L<|P*$EnOw2 zTmKgI(OEo*ANgG(#*fC!3TuiR^I*L$7rdK1lQeLy$<6Ss%4Wjzucyr1Ouzr;-}tu= zko-nB)}JRNeG~s^j%S*G27b17k>69=E?PFQYSrNKW9P0|zDj($byd^G5t^wCjVEQ! zv~)t2!QcXC7pZz#RHo{mcXm;Ie2TGcsqDJM4grTiS0O;%Vyo{fdMUf3F?{vyB7Hqs zjx5rZ`gOBi6rP{9i!kmm$II=qi=yqyE{f(myQrBy7E&_h7+C@I|Zt_f;llqIiWL-5FE}kzM<8ghkQrW@TJL;x0MPson2E;SjMZnM2 zF7l6R#V)EWDE)Os{qrKm?VN0cTMWv25xm{mMaAt#Q8`P_JG&^sqB$H}EWIwdL%<=> zO$dk~QmuNBxZ}?5DsNMs|g$C@KZgn((ifw zxno^j=rj?)59ig`lWetfYSN zIbNo`09VzYkX+&# z{o4V&Ueeh`39lyKX^trby9oF-vWqA_5r+DWeOw^vC}4EQtMEEeDs_}TJ_ zdfzENha8_8StgGNYf;z>K7pStpJ=~3#b@C7)W`yVrmICU_ym5oe4-!j6ra70PmL^- zM})N~2A{ysmd}XCQ=Q_|cYJDOfj`sLq8NMvKU+S19v63t&vCZnvN`U?GbWD+XR$#4 z3H)sN4A{Qu6rYjfQzHxfnXVRvz2Fo0+42cHwNreKIX*SAOdb)|q8NMvzeaq<`?yrp zbBN~G<({>Csd!^?P;BKQ-R76*;;~BRX5N-L)6xm~OxM3(JzsJ2s3=3txemAH@JgPM zwp4aqVuyf3psNs|ZgIzYUoqL=BA1BF{PSyLU9P+rk$22Dn_-#@toO^qqE-#=Q{xO8 zU(@q_j5{!1rnw?Ih~;+dC&I zRB@%V>vDC~#qTRptYloLr-}VM*2{*?bY>VS?AGNXww*goM8gj$FyLs%y4>)Z{B^nh z7t?kT#vSH(nevk0fiYdyZL}^odfAPW!EZBtFzh1W*Q#9v-c6n`9j#a8!e6J{;2!0McPlsg3SYmAuYZ}Ze~GXEjdFFl zx}R{7>o{2t%6YTvawp5$kl6oszI6HKcdvh7)6v&#+_YeL`Q~tSUc0L2q?`OnSxA@p zEC$5S5#luPqjGM(M-yEBCec@K;qnIAYVEpwhR0>6EVq-imM)t^kvBKzt-%8PO;?M; zUgDP8FyLp?h7q4=13JZLuj5lA%j6MZEsDV>@U!I;ZFzYNBv4)ABXS`_x8 zegZ#RKG7$4iqCN#GiGz#jb}_A5zb-(K7pStpFWSRI>l$?_|(V(f2ONNVK4XueztrD zJVx#mpJR?sjVzN#gtaIJpTN(S&ya1MPVpH!J~gtypXq8*3_gLMEuRtFtexU>$nmL> zW%7uy7RBHb_%-4)UZcBPi*wPH^H;3CbSRsl#%J;#tH@NRHcs124Ed})xI;Z_adWCD zL(RDkx90Flo*gw)R9#$$fJ30m5fD!i-CT65Wnh{RfFERGz|oGm=;-B{Ics8T)#yew z&LI0&J`d(`2gb{STzODl;8%SGou)n}?KYZ=4&7X|f-J@@ub>`R! zgrR<8E?P;2-bBYOYY&oj7Hvy%CF`T|Rd+6WDy4xA+)sKg+MHjc6jZ*#+f})UZd0y* zt8#;<2|&z8@K$5x%Z1Mtou}+V3el7k$pam4hSA?-G?{z3}nPX-S-R z_~f%9{|5D}#m%Ye<;dReaI?oM`#iB7#n{Pk2si{LJ_6J&V!tSLx5->qa`*MV<4WoE z_wABYMZV(qqPK2XSIz&9Ml6f^*VIqU^~x@s^1b7J$5rNEK95)5Co;qJ_KL!sp-iLw z5&K1bT8%UCd>`WujF-VBvD}XRq5_^v4HvonqSF1Y-d}4Jv6uLvxoF@=N19RyF6M$DdSl(P5?joS~9C(f{h)>i+C~ zy&mhQvnr-uH}rVQuhtP!?CiDj=O7PmULNQg9cjIt#4Twzl;*T<&wKT80~T3a%)F+< zz!&%BT!(-|z#&kKz!YzHx>!A2{F%Z7wQT#S)_R>S;?S5ry_bpJR*@*1qrP2~r(cuG zW4!nbxG}%KTu!@tLch6LuSLO6{X7wd8-t)wGlHG9=dM zell$rVccPkmys7G1^qe1MjjgAVdyH^>w?i$SBnsPVHW|v zBD?6Yk6p&)yI*`q_)dOg51x{}R=~T-Gbv2UHqvF?Ms`uec2P9d*+pq?br3i>&RIPfGxOumaZut@bn}}Q-7;v=X-NoP!`R^`<_p0+W9+U46 z@VLVqFH>G@#>=K%v~By>?@`L>THf-d)7Ar(4#p zZR(j1${V>f?_TfS#Um{C(N*n%E>)GU;Nz-Xgx4uIx>mXVHOdV(sdg!RK)KOI<@)z4 zH@Hu^X~{_l?HTl-oHzUK;uKjMlIJ{UPF}Hj@zVP?owoFx&A*>^@aE99X9?)qv%7Se z*P^f&?HTY(w`VHS#W!s2yZg)mS$>x;{iEtt`yIn=8`{d`ISdMPV=a1b()BqJQobpF@sMjVzN#gtaIJpTN(SPmHrV#b@C7)W`yVrmICU z_ym5od}6%ZDL#80pBh;vj|gi~3_gLMEuXM^I>o2&_|(V(f2ONNG57?2wtT{V?G&Hm z{QM=G<8C}-@`!L23yg<=Un4&89%HyjJ&$O9y)Ms7&m9^b9bA^pP~$UrOq_|?pE=Xg z32A#r>(za_`Bjvm=3Iwcb9g1sky`YL!GDbn0y}0;|`3M1-bHQ*SvJ#=5au;aEtnAEed;yANd|5<45D=WX_M| z&{4DAQy09OJd+e~uJR}4LVoNvoR|J*-c$Ga6LR))CYjxIG{>`i?$7u&vWuu(5Mij_ zn3q=QLa*oj-N2#59rLGiT+9Q#iDAx5>+{@4TFguDlp~(Xm%mQ6JHb854ewTN^cCg$ zck%Tv^Yt(B^}pfkUsP_6czFu#8T6o>H#;wFe&6-@fBnIx8~T=R{?h&L+Wh~%v&-gQ zx2LW~0m_@{YEjrr{2U?tz>ms#_6^cnU-B*uWF~XbC_81jHP;+mJU+Pj`s4p|(|)&I zy?N!g7kV|2Xz>2Ls_01 ztvQI?Gdzt%lV60jC>qbyR{=kpzDkZUxs5N+XErbTnb7g6!2$kESBt`4s&B+6@U!I; zeRZe!9CCbWWSKl7tVJ>S1b()B20Z5K6rX|PQzHxfnXVSa;1l@S@)`2jxl?@hIzBbB zOdb)|q8NMvKU+Q{wt+gur|?0y#uU$23mdtS_GV1TO>owW#)ZbHTU!gW{ZiI6~y3C)vMEO?l z9IBYweWdb7cd1=dkz4#bO{B*UqA=i4bJYDJ59+7(kTS#O9#Uo)Qgv7CDRr9~XT;Bg zdE9~VGVYV|^13)_jq%93sstqO8fM;|{sX@&Ip6KIoAkMaqyCG5jy=Q=%~3~;AB~q4 z))Xb?!FrAwyqi3eG;prT&G6l5jyhz!DBR}esMFjw=2<=`ww$AeT@;>O+AbPi;|&q* zWe+q{ne=lqXIeTT%bznzL7b&sfS~T<5v%z&Yd^4YOxr~mcbMbl^x#MDlPSAN*tCnxy>>$$ z*HbEYq{l4D_&JLV>>}V-WEa`)wF}-&o=I~uzDamhIZDEf?4lta*GEq}yC~t+B?wTrn9LW^dkM+7DuICJZ;HM_GGoRJejc5~ukS0K zFQRk@)K4tF11a^9PW)sF%6GwhQA(oSd{Iq&1LE*gJ+IQQ=6O;gIIwaK&XPTZAI@RG zLGwlXd~{KDbZGCsb+`WVG@36m!-4}b4AFm(QqL9hMW0XGMHqLO<7LWAJLZc5wu}7P zZoVkn_oC0vat6By_!ZejwtMY@cavw*oYY^+4;@)omCa;c(EK)Iz;==UptFmb<(cdv z;Ad+Wg)>{Si&ieXQW9O}51Oe=+Ig8XEuD~M(Z5OEXD8=9vbjXPRQ15k7iAHmZ(1hp z2CnaDxFJ83Klt<9yz96p=Q;!&0uF)t2uyb0W~>j8T&f(S=qx|~Xh7#;VI0PI5U4j60i^+Tu-E=ap zN+78Jei6oBN&Nc0`twDH)lW?QtND{Db`gJH+4-U*qlR51FJQn??){=fcCk;)7u}e) zi!kmm$IFzLcFY$=zvpkSt$eH78?o@2WtK76MZmAfF0!64V%|-jNpn(vQ7^NuDx1ag zMLyQi&3ATD{x}Pmrn!b)1pI96qOj6lyJ*4Xg9CPEk%wj~eIp`tM&?XQC!}5E-{9<` z;_^ggs{YT}MfLG1#;>Ka>k>Nz90Fa10CkJXF7ni5fi|v6fT*{Qj?y=`mae{CR7uq4 z`AnNg_O}$V8||Xt(`ma1;|_DY+%CH)WVy6SHA zl4j?Ms`xGo<-1_MD3w3D%e;H6ueScxY2q?|!kb!0hi|6Mm@z8eS-SHSwI3bXlBuxq zev$sJ5uWRtc@XnOpG@0D7N19RyE%*ir6j+?s0Zevpkbs1pI96qHwpecG3KS z;pMAP%*wchc2Q79T5%fL=J=tri;Bw=)zkVvXBXASrx?HDg6Xa}1RMemfiwcTU8Jrg ztS?oHys2H32xVBVwU1EoTL!i455W}ci^&oN2jpmDbMI4&zAlu{F7he{0 zBDE^q<{+zY7bWAmT&c2u)vm;0Go2Ym8aulPvF+SxA{u^3fdL2Ri}t(w(LVYShVT=H zJbz@&7eR`0qZie9B7L@2^?x-(zUM>ZZuOcz9@Q0y*%5zon2Hs-pc2h>>}XT$S$ICL4=`x z(_RN@{!lm5x@`7yBaZ2LmVV5bv0lz))43z$1aeY_SL`$S6uMWmTNGz!`ePiFzvx=k z9{JZOH+WgKL*XBk8@;4l|3&2nzvJt_;p@Lvt|2-OqCJBil=Hpg7`g`-W!*^{ntBTO zBYuw#;qG>mvXCzGSyYH0IWNli*_3nYpHN;p#b?ORbFw+^#xu?H3H)sNM7{46pF@sM zt>8A#C-Af76YY0-KDF%Tcmv0$hD!5%0zX?m(GPcu&tAu8OMC)9TRt(K>J*>8t^796C-Af7Gh#cnQ+$p&K3n1w z_%-4){!a8v^*oE-5lo)5Xjv%m&N*L9Jue)z8iV*YAXT85A^KSA?(rkEEWwUr)ZtpjFAD3&~{IlW*-0Ci&ojx!x2mBh@MHHV1 zL;W`ApXr^4v<4MQIL^D8#Hly`e5A$vvy5V>Al>0FcpmvV<@!HUZtxT3hCk-(KjP~@ z;%*S9Ix5FH26ocYJE7=wk`puSH=m#udQNmQVDrE{qJwJ7WbpTN(SPoKxdo#J!M@u`uebEx~ZCV89F{SvUCo0zZS*d6ZqNk8M2+)DL#iBpBh;@hq_;jV($md1=_tf(hH;<~9BYVHY%^s`tbEB5Zu1o9?a0ql4 z0^+G~tvX-a^J{4Snfh4$CmEx8ksWtmC^5(1!u!v`@ABuL!*8l_2Igxp?!b7NFrlMe z^Ur~se^!9XzeRnt7KOdU56wRVKN>H$GXD(TO`b^|I9KBWIz#zPyN%|b#~)Mk&%w(2 z^Mp$7ME~0y&-7j>@M~ljQMn+(P`}gj&$2y>-&fXAPB_-jru`JB-u(0H#D*4PZHy=z zxIapte*ZbyOD>U3a)W18xd^|j+~{fL`cEl0_%>hv7GHmoum1~Qe?qyC>W}T6`d%yA zGw4A%Z+`w68uH!1+5Z|aCXh zTRu_mJH_YtKdF8wo8xXg1O7}miv{W@@U!I;?RTg6j2xdDStgGNYf;z>K7pStpXi4> z#pjsgQzHxfnXVSa;1l@S@)`1Ys#AQ1j!%s&lShQLC>F6UGvYrn}3#NP5nui>7*~#qOh0vq4{UvN8{yI=AXg4$up?~ z=PEyRhVq$q8_hqDMe4bKxF|hOsN{6p-{yFxc{$+M$S$ICL4=`xoAb{?6myrxJmENf zUJo6t2Xg#*bIVj#U?`D}f6hrq=lw{Pi{KIEh7T(@+NxatLB76;uRp-oH}duSm7618 zo9d{MDL%*fIg55vUF>asd<*;<@rn6o zfB%-|pO1a}z@^KFmtN^jpMG4kJmIlQCf(aJXIeTTpBIJqs^=?i9<``U)j#iWtB;R* zrkoe2rLyZ1I|Lj8U4;O3i?!7$e=Pch5q9x$+d zWAvi>{&O(>^{Mw2mAr2IOZesevN&M=8Tiq7xs~~6@NV)#V@!Dd^^}>L z>G$9K3)wD;=GUJmRPrYJ-#m^{chdJxJk$I$@Uyjx!re;SMJqi(M%y6yXVHf zws>Tla_`3Ir0nh;Dax@k_>42>`Ue$SYwN zk;eTKwRt}3U(KJ4NBJ(Wi&Apz?4p{mVGcjl^D6zG*Dw3@ln^5@O@#5oB@8&q*+r02 z&#hI1d(w6h#vSH(nevjX!=t{1j;!0rE(+N$3MCHYdE> z*+u_9d*1>eMRBd&YBZzr24xYI6@09#Q6A!(odppG1tfroqK>n>vpXZRJL}BsvJj)I z5i^M<8lwrm5;Pju_=wRwG|{Z!YgAMeg#|d%vja zRr+4;CzIWM!JM{gcAU{KV)^yw7olDtVBEj$?uhe5|-0?iBLf<1QOg^l_)I)UtLAw6{-CslZf1tuF*~=u9i~N00Du?yF)bA^% z+~-9#2=W`xP`_AyPV^k{WPK?Yo<0}PqVQz-ImMIveYxwSn57|@Y!ZYRKsp)V2c(VMQ;^`y1xLkO4 zxp)?ZC(F+%o=Ng=%7tgr#j_|pS${g>r@N1uYYy)_-IZJ4@=33C z+v!TE$!=Dz1Y8LWbP4RS`_I|;M-2Pkvz%`cB(x{?Kn?=;Qbo5 zJJ?=k8>>|N&mMRGSsM@Rb1z?OBoyWSXOLw*-hbZxGJP+%*WG_s@?&iE5M^sU5Fgx^WBK*x7a=_Y z#{JvA{|s4~*y|;wG1gP9@qXTK(4N!R`K9U+qWd?iFiZ9_iS?YzVLdPP{*_DV{tJmkZA>7f%f=9YZ~?k=XEL`8mZiMfOy=@JzaRYGCOY>T!+4 zh9}FhI(8hvEj+`bBbq@ z{M2&cS>@uXfu&=p$2Afgo-Duq@Z|kx&k1VXp@9A8Xd;jZ8u@=Gmn)xh|M|;IQJPS$ z7kQGZo$fxWu1C(}uH2l<%Ie3IMv2{ATnV@m*c&8((_*pT%f+!OpQG>Z3ir=+sEpy<`_C!be@<<1_n-5{S-uxa@^k7JB`XW{ix$?$0)U6pP-J|mm!d%07lOev{fgx}`v*WY>Gvx_(i7M$v?7w^9O1d%^^0=rQ~x%<>lgJeqwMl6LUUbKR|2jC_A&{i{i6Q9mz&Ek0)ds( zFG|~WS)thD{h~F?=Sg|6!J&RfM79OeJH6`n746q{KgfQaO&0JwBG)Rr)!Z*4yTfiT zV_nkzX4*bhxu&oC{a!BlMZQl?aKEFP=kw;cU*s#*ei7kr#~JZV_n$PbcAS-NqK@Iw z>CO0kMe>V$Pr80lb~}q@t0c&Ou^*yel+1U(=-`6=qHuF-1b=eA(1VAm4E{wKDMcm7 zF)?|K(kIuxNBznFbmf-6%#@sq(p{I?m4GXOy-ET&Ef)J6ogwEu=VHtK93AE{wC{|t zEc+=r&>q}#zvEI1bylbHi|p4<{2;qvV83Xk)h}YZ!)`Al%IWXobP`^fVSj#+hwS=f zuj?1(wrlJ-83ykcvHXhOFCyISIAh7B@QXrZ*C*Gweo?+SqhG}GbG%=)Pr-gsB-{|J zTo8-|Ix^MHNlH$?=prZF&S~VB<5}VQMY;6}$K$?F*DvZ@KDp)RTv1(0R|2jC_I3%B z!Y^X`+Nmu2_KVQ2=;Ofo)qYCyJ=-tp^iG))hu^aQ(OJqb%DA>YN7si0%v-QuwA|_! zvE5;}mrLarrT&NBFWTVxMfuFZ>=&{8iuH>acRS9g8l~`yeB>9UZgc&jd~wF{i{e*we68PCdGFnFQ!=p1jnninQ*MgK z{p(7=m4GV&ClVNjMBWMT=L_^Ac-pQ?^Wz+n`#Cxslkz!o`$g-XdCH6B=bWrFpV>3t zFS6GlTRV^jo0;pLJrAeXM*$(95S70b&29M3SN;IsZ%>cg+H-U=d-9WPevy;?BiJvB zTm2%oJM8u{*G095@yZPC`$a=GU)z1^^XsNzcoKw3@{3eHd;8xsraHdaq{4m?%P*H- zG;Y;0>PxlgL+AePKjCi28Ou)Vb|${6Zv1Wc+|SWfkzeGw-t~*D*y@;PBF)dyvHYC+ zMV|jG+%Jko6QLp;BkRzhHR)n4UV^C9Yfnt+le_Ps>yh)gD>vt|vi92&Xt0}wD*;ym zdx->aTIA>GRFl(oRayl5Lo}CPRO;_8H)_lvCau0CH&9kBdizli0R%P(^J zduWWi9cL^w-G8x8cw~mEkLC7@JmeSoCc1u6zBuE45zEi1UzF@E&MzwTN1~ysIfvUN zs5+%Pq%I~~T)!x{KIvmf_PFa8WtU6;GA*4VyE(ZMa3wI{B>?kcr*{lAv%l{yQ~?d{ zZQwgR+y4F;*#4bf4*Qpqbvzr@2SeJf%SvSNiGYG^KV=W@x$hUj9@!JG*5HXUE$k@wV7`YnoM*{O)q3(qnY`obzq zHmNWbr27qYzmD!-N%yZ%VV3M=63RvXt}vCudS2?^iT1d^)1^U>O~-kT(8wT)_(=bs zFZso-9A7c&5ltEf=017tf;bWcl@nr};b4n+o24ZV4<4 zR{EmRWd%N)n{)s95={anh|0BH-%_={;_jp7va$P4cjeZ%eDYZnErCwES-28#B{1M5 zfMX0!i~L-!+I`Hnw}Ib`&-Gkxu06Nh;_CZ-#lg85@ea)GtcDQLtYWZA=7PjER#nE8{FBr(cA1FX16|FLklfr@i}oBq&wAPuk;r&2(wq z+q>n)a>$g6wSQ*2k7@4VO2CzXD*-1GaP}RSf2Ci9c3s-G%V-1Hc4qos{T&z2Vyj=o zc8A?wwi-V??`DSf=W;W?<3e`5DgC`V!t=B}%oGaR%jg#+`|*pMe#eDzx8sZ@r~6JO zzN%*Zf5#@5<2d2!EtUoppojq|JhlvtrX zI8fhL^!#`B_Z3q!tbP&O9d>&eW$DCTw);i)_Z5AvUnF%+{mC^)Ya|q9zlh~m?0ymB zZpRsmbAq$#Te-jE;#;TQ`|-6Zdp)y7ds9k&IOBUMOcjmu#@FZKJ1 zyUG90Rgb+ZJ%2rC`8m;Z`Ti;COS$k2xp-wSn581`# z!ZYRKsp)V2c(VMQ;^`y*rd)V-xp)?ZC(F+%o=Ngk%Y|ps#j_|pS$_TD$?q#Be^K!M zb6Z^^7N}2X)y*%OV>#O}P`65W$o*%}bhW-x&gV-r>#UEj?(ZvR$_LhF_x(KlE+ylL zE#P>zFx&lXt#;E~3Ahq)C6FnBeT_kw*zfNv{;QwM&8(@JBIj503hK`9D{5&nn%;-A z-oZWAT=%S$&aaLFQa&MSd0(-dzpv=Kwne@-$on;Hcd)(8?X(&{IG5m&8QS-s?a$?U z-2G=II#YhR=4FixqP+ji@@@amL&jb1mNty!+dKt|GrEd8NDm ztmNn%XWV~g`8oBAJdYOY7cB~Q%!~z=Bk+YC)}cYm<8m!tf~eHN$N3M7Ou}c&1R;FJk%S@{62) z$AxjX_Q?OqY3fC`d3C81vzOb0nFS;UA zjf+W8@X7wXbx%v*Rp(UyK%HDz9ip0oU%=(&9Vl=P)sc=h%3(qPSPYo;`Lp`pM*zjceImOdQermb!^tgCxVCfj@ zagD@=C(ExtJo$Y^&-V)7e{O58EAXckWuZ~`ii@cs_T*SxGOj3 zvaq@|tz}_VRoEAI1_}htmWZT>5`?*{r>mCW`ml^i``-<`n%1kCs!LlqT zzpse(&awY&sUPmKW@{rCP)K+bF!2dd%X7JJuAc+f<@tR@PlK{Ec)y124z`!MorrQN zeqYf?`_IW<_xBa8^R7N$XKE1QgTEuf@;5c1r+!iL=7RmAa7*FeaKQ%T^oy>{Y+f-bQU`r? zu3waU+|YF^d))Plvdg7^nHHnEF0U&AR|0#P1i*~?S3H-iOEtG&gjC9|OTS&Gb3)wW z6VbIKLB1S*k-X1;ocTqa-h(zzINLBPYYn5;;#YA#dUzCE@X6_HaIjy*?G<%YQEJkV!Oj`FJoPlTroeKTe64!J(ufopUYLEGv$|Up4Lbx z%6<{cuUNl`akt})#W}%Q>1OWV5!wA&v;00#a*gX3ss7>|XZd^^$*(`Z2=xL10+YbpK+yznJbX zqWcR}m?e9egmRJ3aZ)*~=cRrwcQ^U}x$3cZrDxM|o-3@9VE>=x=S0ut?}(7Tlnc+K zi>C%u{&=$doZ`v-zFc_j7HS^S8nqWk^T(6r=M+yKzsrSZ%EeRD-~91p`8mat=izeU z+2!I{6rL2kEpHul7??BHuvWfA;;K?EBBjvz48}`!#HL zu)WN(EY<#V>M!p1a?@&Q)#>z{oTlIy;)BoSvi#6qF6Oyh#@&uHmdBW@`d|vy(;D`- z|J?PzYTZ9|Ti^SHD&K+rH$R+l|C#02pI?M}fq-%Uw(mdReb-&`8GpNk(-_U2<*=TY zdjHwu`u`dP`Rh5$&xxMP=Ltw(%7tf&p8L=mwHHV8$CKsf6i@E=<-)Ve#Z%MY{PAS@ zImMI5?{eXpbnz?-PnMrkJb4~27oH&(&!X^T`8mZiN%mB^@btNO7KJCv&nccMvWv@w zXO)X*QFyZaoZ{&r|E64cdR#n(2zFFXZx6--O+il2Bh0z~T$e{C4oKx%U+PS?zT)nq=F+LY z(_OjsEuZvSx1G*`hPouK1Y8NY5>OI=&jsy???2~!Ud+DtOnYm}o*1b6&z?VI-+%TU zuj~xouVK4`?Pa#HO11x-boZaNal=0M^0h`nQQm)M`JugB%>FauZpRsmW6ZPdJFDt+ zdi&dd4*gTv>7MKR-X~P~4fMZ^t3AwYH{y)@&n&YXgk+9LEPDfC`JZC7q@SUc@^c?q}SzpS9XVS$}1B>yqhZ>0uPnMrkJh|VO3(t^? zrv{cCN50lbY^SnZMq%;o&vb>_2CF&=>V9bqwtzAFV>)coilqRhT-G?jJ$-$I|^Vbbqu8b5)VYGcJeqywv;8 zN!S0^Ajn_OS$ z7tf;bWcfM8GfDnUx$sQ7cou~x%g-sEDe_axg=fgcvnV`Se*NLe`_IWMi`;*n84E1e zYMe(j=l*j;9+@~GmHW@WQEGj~-ABzehxeWC%B^qtr1zWcbPhDsC2=L-O2CzXlE9w2 z|C|e-y>kCK`S02HpHurPJA?OY*zRC^nfD?~wg2pK_n$Srw9mbKt&vca_n%pQXfGGD z|IE1CamL~p^J4a&cmG}4>B%+j{&POI7UC>_|C!|1pI?OZ2pIS8Qtm%z`|V~@M;SQT zf6nF`p?)Pt&_41o6?%rM&^K6x$%Ei? zV(0P89%>{MWj$y4Ini_Z`_H5=<-*hB;;DgU$C0l!5*wZ@Kc{$dzb_Y_yZ_zjw4@dBsM%*eopc9kX>9ZJVP#?8d!{^SnZMqwU7B>Ac3!n4Z7Qv-|fvxgdq4NsO|e|Yl#vuAOU`_Bu4 zt&u=|w#V`_D``#1x&K^9X4b4NS91T^vyWO|araT}y5#KIm76m;W%@7{U34#83Ahq) zCD4}y_SF67{c}`$uiSt3?asdcocv?tr@w&>A>OZHyMygz-is{N{&VWj?(aXR^)lBS zou=Rz;v;|mndFD|axweQjJq9YERQi)wgIMKJ*}ZKhC9#U^gn-LYB!#Lp|k5#Wv8cZ zbJzbfZ7jxJNl*XF>%=U-{`?}ON5Hs$mvaAkgkG^MaVPuFp)7o;U%t=OxRd;+3RC}3 zq37=^^!*Rr|0~`9Gu{6a-Ty>|S+bW&Jf3kmtmmcPfA+ZkzXk#8wLR2GD9U=y@^hl+ z^7o%fU&@7Nik|z(tnuEMV#krMGiAYevizLl$^E`ucy_sXYG5&b_E00CDC5cUbBZUA z-{rzH>Efw@Wyg`PH4+=1EI+4s@;qEFJVP#?8d!{^SnZMqwU76xqe)!n4Z7Qv-|fvxgdq4NsPzQ#?K7-;@hakBg@UmK{gF)<|r4 zvizLl=_5b2TzKxLb(YK;?~N&ppFPZ!1>3hQzy9##{paKbMeaW@Yz_tr`v7;&{pW1I zahBO)$0>5HFZBntzT)nq+I7j`sAb*!f@p(_Db0kEA z^ZV@k&%SNS&Om!izF$Um2iwcM7g?(P=cK#;tZ8GeIa(v3DB^?r&n!Q*m(vQ4`QXu6 zv-wA@6tDH(x~^>+rBhn^IRnPsjx*9T=E^p}6f=J=r~lu7{vTzhd#-o)pOyTwVU4o2 z9_$x|NPhkKMM#f;asMvm{&V)d+H`%L>_0c9$;}w*m*+oeANk)^nEbs8Q@>N8=VQ9R zi|+T*{SWE>b`_eL+9EujaXGB#+1r$<-zq!)opW2}+GWc1|21i3({YxqMg~#VbC#bI zJ;(XUNBUAOJd-Y-8c_M;$?|iGC-?hu;TdxAEDBGSpHn<}{4N)sJ{QlT@MQTp#gpgZ za^YF!;#m})EI+4s`pBLt7oHv$&!X^T`8mZiNp^9$@Z3#)h}NjRIGVpb#PV~BXNvrr za^abB@znG;e>_=!PVw}RpIR6mXd@o|2C`BTixCuYRuF&*=Th>!Ez{cnw4K6O5(W4_agkMrBM+9 zpNIH3zqi)U@$#wjF&*>u#FhLwzZbf_UOsg`renS?;^X|DermFpPo0nHn6HEQIKPK~ ze5{vGosa35&qsWm-`#hO@$#wjF&*<&5Fh9Fty>0p`PBKCj`?=Slw3H!>pKlEpE@7Y zG2b)9$NBC4w|}eQQ|Dtk=1USE=l9n7^)-Czd`!oDONfv2d-|!TYWURon2!0Xh>!ET zYxU|HK6O5(W4=$XR&wF|uJ7!u;Zx^hI_66eALj?U3GGv-&c}4jx0?7kzq?jfKt0u| z^D!Osg@}*ydw0WzX?*H@Oviku6CdY?wEDsQo#~j*LwuYcjuD^z^BV7WZW~sE{LII6 z%-7RO{g3!@&HWGmag}A?qZ0U;j`_NXkMlFcwcf6WkMn*bnUs4cTprUgUkCAVe#m#r z%?EoyHkNua9rO8!kMsNA|N9m1AO8>m?2WVa_AwpvRS+NNhvjX0Z&A&v8^2&FkLj3i zca-`c@xQxaz9|#EJf>s5XNZsUd!(z%`;SjQo%XlCBrN4I9rGoLkMsM}C!e5RpZ$%b z$HK>S%(sO2IKRgqJ5kbO9r0isn2!0Xh>!F8^M7CM{diZM_tlrrmF;9crenTOTd4mL zKg#ppK5p>-{OKtcKBi;76!CF>$oIk4OTEwi<}3>z(=p#_;^X{~@1=D!ytjUPh=q^o zm@hqF zKhW!%@7#9Vv~@4kTKX;1F`tk4IKO}YeUtaiH!hGe)yrc#=Bpq+&Tr#8UzWOpeO~8d zI_BFQq5enwFRq>Led=eEyoUJ9A{VA(zGsM!^V_odVlRx>-k&`=(b7JqW4#M$9zkOkMl$Q2Ovij7;^X{KF6&=E zU-o%jE=Fb_RGD{ z7iwO4=_QMvF&*=D5g+FVJl;F+xTEHSty?X8Ovij3#K-x4^BV_(Zaz5;#(7IUnU48< z#K-yFbNAiS4nclhE=o=$N4dzs&BfUOvikyiI4MRdem>do=nGlA>!lw z(tOtOlj)f6bmHUuOg=0O4wfg=F`tL{I6oez6<3;%>6ovliTWS$!yGmZPdgveF<%$) zaeklvt=%jB_p2Zi^sCe5F&*=D5Fh9FpZ^~A{{4TJXYer{^ZAI6^Lyv*3#C78$ARgX zuY&kEzej&k?S1Xl^I#sc;>UE%x4V)0AMtoG&(=p!?;^X|Df9`A?Cu;uqhd)^QEz>by74dO?SO$)} z4?Xyxg^%f&@6#alKjPojd*w7d@4RD_g^%f&FGYNu-zR@;@&3VM-|l+qf0T~c;n)IxoJF2Y$9&HaAD0X5lRT(vdi$7;`I5xP z`Tg{XljQo@FMl!B!pC&Xw}kjOKkRqt!=eAEm&bI>S4DiBANm~0uYWPaKVmxO`?QYw zAMvA)bMHN4GyHd^W4;veaeg?qV0m`GpXr!yHSuwN=u7|Tfd?}DDyCz;5b<$-;D^@$ z_B9`VaG6CeOviku6CdY?z7guE-A-mY=JOCA=l9?L6_xt(#%r@J_%R*x^#rK@5kIcc z{`Jps?@g=rx9~9?^K}s)=Lh4i9M4dmzLNSM@#C7}9p4@4wfoad$9&HaALsYb zgGblswg`_eOvijl;^X{KhF`zwCh+?Wi@q=&^DQAh&JX2}>xy={Fdg$%5g+G=KpNg2{C(|)siugD`Wv?pR6OvikyiI4MRKD(X8bj%kbKF%*) zPpf^#bj)`;@o|1>+uF*3ttySs? zm&@{GI_Bg2IX}K;zVj9s#(dZ?@;otI?k`;e1o`ZjowwkeXe1J>PlTf_#w0WMl0>q7 z6D!}0leF(zRn-2g5c!sCr$>D7_p-P?7egH7?6cL&<2l>>&LGnBeWvGja6X=Wtn_@J z=^+bwa6X=)ivGeGhVkV7fID3u4ZD{4;C|tZa{|r5Siq2fPntNfgxH6<(q#w_E<>KB z$kOvGg^QjS;&A{aVEi9&9z-W4@3Fx_*ZgPgs5RSP==jMGYOR&TagI;@4ySc`t3Uge zv_;1M(7Ff0V`Q33jhX3djOl55+%T?NeX>{h&Xjp0WyS9v`t7(Y@2&aq=|P#cYW=a^ zbI&}Y`@VmCB*#{38#=w$0zdK~9TtRnAwTk9evmX7^CJGvzZ|vCb2q)+Htp0gr>s@= zvet)q%=)NnnNQZVeV}b{P61tbnrNqBzLR$8t!Qo&re^Gsh;iwx#`M)PL@^I2P6&}a<>W5GNtkdu7B zN_Fe1oD{|1fDXGy9-bAM?|ori_tg1}<>)!}z?bnm&%S3rTZbX)D&Na4Xzo+?{*)_S z&m|j=ejnpHjUKn(V?H}gUv!eTlQ=Pi(~^d_^fZXe145+Br!3+$gW~xS7oN}dkw_W) zZ3e*hF?c@PA4u%w@HK~Kg^G%J#<=rYQ351poX>_qockdrXX}4RhwoK$Kh^2XIgv2= zJj{tcY(U8l+nh)~V*YdDoN!YpQL|7 zZT-V@wN_dlTQSs+bo%eUa;*2_6Y8e@?stF8LSyIAuQ9IYtH%xF)IZ$u+c7sKynh&6 z_dHT=Z#=jAj3?&&cKo`-WI4x(Vc!3~-(T}!R6XBeZ9}IQ`9B06q(lA+$P4-Z1Uzur ziTPq)4=Mi6cSa8OemcGJw+9{c`xi3j8q5I?YaRPelm6UfppiZv_->QYpMx<_`gn>L z|EfG8{Wv&J0h;454dUjUnBB+AHYcWYRWVQclNI(`d0cxc+&M81apfd6=QEP$=V3lW zySa3Sn$OOeZWy;g#=KUx2ns-bcY2&Ny?kqy5vP^tlTLO!FZ$N-X2uM#Zf4v+a)Sd_arzcw`%U)SbfrR!*NXWlF8$??3-%j$AeEuDkwjj`O!4bd&eg zZ#`^Y7haD&lXDKB^du-I&-cHFYUZP-bEcQi?rJWP$W(g}d;PR$zH;XOi2s_7Si`$3 zYQHLrKBhJ+yJ%lvhc%^XW4`bSND%X_tyMWz*47@ppOPUgQL42k>?57tZ9`|*jv6#|A%$_qZw%$?m;1vCxzl6r zxiBxm!WOT29Sxc0$~Rk{bI(1eMH|DbBcI8!(RNV7#y$$)_{h-CsK~ zi~eY`-RC-GyH~0-9dB+ojuG}F`Aq)p&Q?dvH(RO@dK?RJReoA$Rb9;MZtWW4Y-`B-c+L0eo_U|I_4|~DIU*mQhVdUuPk7@L^Pj9kuH&nDWP-FYnI6-b26@$bzv5+jypMJ%=7}NFVI1#sStz$&xaRpB z@pCffT(o#@0C6w$@cbriCu1Im!Kvz+J;!C6hT~V-;R8L7yaRWmwA3a`6=}5zIarq{n>l#5CSJL>kT$^Ewnx?4yUkiDL`?<}cEYgcI{X zI{~jT9q;2fh9}z59LIFz$9&MQ!0`;@7~+X-8x1Gs$9#An(~%eJf#qR2SRT?LJ@R6H zNQ?DEI;2NFyob2pc*XwOw;+yf8v`e{IoDy1JGlt@NoRYW$*>-`!3C#RK_#%xcyK*1 ztg@&;N3Q9hr?Ba2t zC|Iu3aMlPRaA4i{?e0A91XH{xm)fb4=>=R$8)IQwu$Ox=N~qu#?6Cok&Tm zVn4N>>S-Tot_$f@97nzIK!;z!ZIl^A;@(1sZ~}%6ZX-U?LU__D!Dcu2P#U zcd*|Sd$1lQ!+(4N{aaOAtn8wKDjQm5U8m;y`QB6O=*f3g=%e3o;E?G)FJZ+p)eh7T z+)v^5-Aekw?XJI65a90Vus8&<)&=Nzlw_)xYNaqI=`xc%QI9COKGVOy*b ztlokfQY=3gyq_@>P~6AxT)kVi1AFemX#KKaLiJ>(8>nHS<44c$)Nk3CxRbs!?kq3X z2fkh$jkGlv4!cn-Ki6YFqjs;xo#l{kxccKX?s6ZT<|7`rIX@oH`MNjy-?njkMxcIK zQ!Lunl9w@67#G(9ZR~xF8{ic7aeEz&+cnFiJ>z*!%}*Srb8s3%`)SV|w<}V%ahuxD z{nztb)qZH}%$}IXb+PKM@V6BT^mM89>j@Bt|BjEj(`QB#@k%hWqRUFHvBmfWdIQvRz4&bJ9MD(P zS^YFAAzdCS%tr`j7G|X1JW_udkzVJ9vQQ6J13RZ5

9|o6KVMc2PXt4sM@Gof%<% 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 literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/textures/checkerboard.png b/addons/cyclops_level_builder/art/textures/checkerboard.png new file mode 100644 index 0000000000000000000000000000000000000000..393ca46a7b53ce7532c39218453cd49a15081087 GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1SEZ8zRdwrjKx9jP7LeL$-D%z{XJbALn`LH zy?c=Jhyf47!QINCJMy=`uv*vrL{;pN596T?Kh!UjzyCY4*)y4H(W0p00i_>zopr043CVE&u=k literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/textures/checkerboard.png.import b/addons/cyclops_level_builder/art/textures/checkerboard.png.import new file mode 100644 index 0000000..f12ecf8 --- /dev/null +++ b/addons/cyclops_level_builder/art/textures/checkerboard.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b78mg60xhic6n" +path.s3tc="res://.godot/imported/checkerboard.png-cfbf91dbc6f1912b9574735ecca5a514.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/textures/checkerboard.png" +dest_files=["res://.godot/imported/checkerboard.png-cfbf91dbc6f1912b9574735ecca5a514.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell.aseprite b/addons/cyclops_level_builder/art/textures/grid_cell.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..172a35ec21ba4d025c9c549979d898944511e713 GIT binary patch literal 1012 zcmeH_Pe_wt9LImF$uKtZV&WlukO(j3HezBM3SrUfg-Ebgu0=j*@(C^Pc=hX*r zFu4k&(;5z!*5H?N6>3UkdTt&*oO%S~i3Ge79)J^pESz<_;mYMGT)y)W=3bnK*_2Z! z*nrhIcSVOyumkjQM;vRE@kJI>G;u@_JJj$(3L|t37p<{CfqcSACYDSBNh7M$NK!}P zZlNGYBoK+-xSmdpCr3IMTNOWKuZ%Bjav^g2T3WeoGH6n@HGQb|7W3lVdc9G!I7IA4 zrJugvY;yd*g)}t6@0#&{mr|Y`M>wQ?c=pQZ@iBo zx##t+J2T#%vAn-npF^7=jA0E!1mgy#1l9vw4WbMqOTc=6_Bqb-oYxWAFL|S1b07N0 YDa7|h`r*-1U}!UVy85}Sb4q9e0If@PGXMYp literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell.png.import b/addons/cyclops_level_builder/art/textures/grid_cell.png.import new file mode 100644 index 0000000..56f87d2 --- /dev/null +++ b/addons/cyclops_level_builder/art/textures/grid_cell.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dpoaquoridpp6" +path.bptc="res://.godot/imported/grid_cell.png-608181fcff7b2e489ee715ed212734c5.bptc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/textures/grid_cell.png" +dest_files=["res://.godot/imported/grid_cell.png-608181fcff7b2e489ee715ed212734c5.bptc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=true +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell2.aseprite b/addons/cyclops_level_builder/art/textures/grid_cell2.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..41b75c92b950ebd5fb099436a99ee3ef1e20c8be GIT binary patch literal 856 zcmd^-%_~Gv7>C~(hLSQi%E~3l&YejlYNTwiki{SiqtVEfnFuL`q?834B}QRk$I4<# z`O4BqY<$fEg^gx>E#xD|a|iJcSb0z9>GYn(?|IL?b#Wr+3l?qYb>kpoZW zd@#B-4PPG$;M7$$G}d%jIN^ttt$DDfG8;NeilEEY1$EC5Z17(|Z&1O;-AlL~euIh< z2`+`;aQ_HwH4Iqqu7N#eqj1sbgeSFLc+|H7$0sY`Xh2s61H_x}u5n-pCO{u|#IZ&h zUt}>w6GsHGLk%yaFha+4Q3?wb$S0g+V#y?sG@`Q1BrOGg7YdRjWli3;md-%8zqtwx zoA!CD_%5Gi{u#Y9kpoBShMp{ryZI*FcNkqw*le>~Bhls3(;fT6)4*Ql#z0UNsP^~p cTj)9Pcy_(M`_CHT$n4myYyZ(Ycw=}z0BrGT2><{9 literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell2.png b/addons/cyclops_level_builder/art/textures/grid_cell2.png new file mode 100644 index 0000000000000000000000000000000000000000..67a33e367d8dbae58c600116a2a1b4b61aa0ea30 GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1SEZ8zRdwrjKx9jP7LeL$-D%zqdZ+4Ln`LH zy|R(_uz>)JjAC?QHGHvV0|z99A|mXYx#t=z~EV} c&+(hlL7DSEM~m=5V30F-y85}Sb4q9e0Dkm!i~s-t literal 0 HcmV?d00001 diff --git a/addons/cyclops_level_builder/art/textures/grid_cell2.png.import b/addons/cyclops_level_builder/art/textures/grid_cell2.png.import new file mode 100644 index 0000000..37bfc32 --- /dev/null +++ b/addons/cyclops_level_builder/art/textures/grid_cell2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnlqi20ay4vs1" +path="res://.godot/imported/grid_cell2.png-1f268fac69e50a444ba304e9119a8d5b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/art/textures/grid_cell2.png" +dest_files=["res://.godot/imported/grid_cell2.png-1f268fac69e50a444ba304e9119a8d5b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cyclops_level_builder/commands/cmd_add_block.gd b/addons/cyclops_level_builder/commands/cmd_add_block.gd new file mode 100644 index 0000000..62001a6 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_block.gd @@ -0,0 +1,69 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandAddBlock2 +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +var block_name:String +var bounds:AABB +var material_path:String +var uv_transform:Transform2D = Transform2D.IDENTITY + +#Private data +var block_path:NodePath + +func _init(): + command_name = "Add block" + +func do_it(): + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = block_name + + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + block.materials.append(mat) + + + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_block(bounds, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_path = block.get_path() + +# print("AddBlockCommand do_it() %s %s" % [block_inst_id, bounds]) + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.queue_free() + +# print("AddBlockCommand undo_it()") diff --git a/addons/cyclops_level_builder/commands/cmd_add_cylinder.gd b/addons/cyclops_level_builder/commands/cmd_add_cylinder.gd new file mode 100644 index 0000000..c8bc3a8 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_cylinder.gd @@ -0,0 +1,102 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandAddCylinder +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +#var block_name:String +var block_name_prefix:String = "Block_" +var origin:Vector3 +var axis_normal:Vector3 +var height:float +var radius_inner:float +var radius_outer:float +var segments:int +var tube:bool = false + +var material_path:String +var uv_transform:Transform2D = Transform2D.IDENTITY + +#Private data +var block_paths:Array[NodePath] + +func _init(): + command_name = "Add cylinder" + +func create_block(blocks_root:CyclopsBlocks, mat:Material)->CyclopsConvexBlock: + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = GeneralUtil.find_unique_name(builder.active_node, block_name_prefix) + + if mat: + block.materials.append(mat) + + return block + + +func do_it(): + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + + var material:Material + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + material = mat + + if tube: + var bounding_points_inner:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_inner, segments) + var bounding_points_outer:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_outer, segments) + + for p_idx0 in bounding_points_inner.size(): + var p_idx1:int = wrap(p_idx0 + 1, 0, bounding_points_inner.size()) + + var block:CyclopsConvexBlock = create_block(blocks_root, material) + + var mesh:ConvexVolume = ConvexVolume.new() + var base_points:PackedVector3Array = [bounding_points_inner[p_idx0], bounding_points_inner[p_idx1], bounding_points_outer[p_idx1], bounding_points_outer[p_idx0]] + + mesh.init_prism(base_points, axis_normal * height, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_paths.append(block.get_path()) + + else: + var block:CyclopsConvexBlock = create_block(blocks_root, material) + + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_outer, segments) + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_prism(bounding_points, axis_normal * height, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_paths.append(block.get_path()) + +func undo_it(): + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + block.queue_free() diff --git a/addons/cyclops_level_builder/commands/cmd_add_prism.gd b/addons/cyclops_level_builder/commands/cmd_add_prism.gd new file mode 100644 index 0000000..da09275 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_prism.gd @@ -0,0 +1,69 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandAddPrism +extends CyclopsCommand + +var blocks_root_path:NodePath +var block_name:String +var base_polygon:PackedVector3Array +var extrude:Vector3 +var uv_transform:Transform2D +var material_path:String + +#Private +var block_path:NodePath + +func _init(): + command_name = "Add prism" + +func do_it(): + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() +# block.owner = block_owner + block.name = block_name + + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + block.materials.append(mat) + + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_prism(base_polygon, extrude, uv_transform, material_id) + + block.block_data = mesh.to_convex_block_data() + block_path = block.get_path() + +# print("AddBlockCommand do_it() %s %s" % [block_inst_id, bounds]) + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.queue_free() + +# print("AddBlockCommand undo_it()") diff --git a/addons/cyclops_level_builder/commands/cmd_add_stairs.gd b/addons/cyclops_level_builder/commands/cmd_add_stairs.gd new file mode 100644 index 0000000..5ab6fd1 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_stairs.gd @@ -0,0 +1,150 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandAddStairs +extends CyclopsCommand + +#var blocks_root_inst_id:int +var blocks_root_path:NodePath +var block_name_prefix:String +var floor_normal:Vector3 +var drag_origin:Vector3 +var base_drag_cur:Vector3 +var block_drag_cur:Vector3 +var step_height:float = .25 +var step_depth:float = .5 +var direction:int = 0 + +var uv_transform:Transform2D +var material_path:String + +#Private data +var block_paths:Array[NodePath] + +func _init(): + command_name = "Add stairs" + +func create_block(blocks_root:CyclopsBlocks, mat:Material)->CyclopsConvexBlock: + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = GeneralUtil.find_unique_name(builder.active_node, block_name_prefix) + + if mat: + block.materials.append(mat) + + return block + + +func do_it(): + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + + var material:Material + var material_id:int = -1 + if ResourceLoader.exists(material_path): + var mat = load(material_path) + if mat is Material: + material_id = 0 + material = mat + + var tan_bi:Array[Vector3] = MathUtil.get_axis_aligned_tangent_and_binormal(floor_normal) + var u_normal:Vector3 = tan_bi[0] + var v_normal:Vector3 = tan_bi[1] + + #Rotate ccw by 90 degree increments + match direction: + 1: + var tmp:Vector3 = u_normal + u_normal = -v_normal + v_normal = tmp + 2: + u_normal = -u_normal + v_normal = -v_normal + 3: + var tmp:Vector3 = -u_normal + u_normal = v_normal + v_normal = tmp + + var u_span:Vector3 = (base_drag_cur - drag_origin).project(u_normal) + var v_span:Vector3 = (base_drag_cur - drag_origin).project(v_normal) + + var stairs_origin:Vector3 = drag_origin + if u_span.dot(u_normal) < 0: + stairs_origin += u_span + u_span = -u_span + if v_span.dot(v_normal) < 0: + stairs_origin += v_span + v_span = -v_span + + #Stairs should ascend along v axis + var height_offset = block_drag_cur - base_drag_cur + if height_offset.dot(floor_normal) < 0: + return + var num_steps:int = min(v_span.length() / step_depth, height_offset.length() / step_height) + + var max_height:float = floor(height_offset.length() / step_height) * step_height + + var step_span:Vector3 = v_normal * step_depth + for i in num_steps: + var base_points:PackedVector3Array = [stairs_origin + step_span * i, \ + stairs_origin + u_span + step_span * i, \ + stairs_origin + u_span + step_span * (i + 1), \ + stairs_origin + step_span * (i + 1)] + + var mesh:ConvexVolume = ConvexVolume.new() + mesh.init_prism(base_points, \ + floor_normal * (max_height - step_height * i), \ + uv_transform, material_id) + + var block:CyclopsConvexBlock = create_block(blocks_root, material) + + block.block_data = mesh.to_convex_block_data() + block_paths.append(block.get_path()) + +# global_scene.draw_prism(base_points, \ +# floor_normal * (max_height - step_height * i), \ +# global_scene.tool_material) + + +# var bounding_points_inner:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_inner, segments) +# var bounding_points_outer:PackedVector3Array = MathUtil.create_circle_points(origin, axis_normal, radius_outer, segments) +# +# for p_idx0 in bounding_points_inner.size(): +# var p_idx1:int = wrap(p_idx0 + 1, 0, bounding_points_inner.size()) +# +# var block:CyclopsConvexBlock = create_block(blocks_root, material) +# +# var mesh:ConvexVolume = ConvexVolume.new() +# var base_points:PackedVector3Array = [bounding_points_inner[p_idx0], bounding_points_inner[p_idx1], bounding_points_outer[p_idx1], bounding_points_outer[p_idx0]] +# +# mesh.init_prism(base_points, axis_normal * height, uv_transform, material_id) +# +# block.block_data = mesh.to_convex_block_data() +# block_paths.append(block.get_path()) + + +func undo_it(): + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + block.queue_free() diff --git a/addons/cyclops_level_builder/commands/cmd_add_vertices.gd b/addons/cyclops_level_builder/commands/cmd_add_vertices.gd new file mode 100644 index 0000000..828d879 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_add_vertices.gd @@ -0,0 +1,73 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandAddVertices +extends CyclopsCommand + + +#Public +var points_to_add:PackedVector3Array +var block_path:NodePath + +#Private +var tracked_block_data:ConvexBlockData +var selected_points:PackedVector3Array + + +func _init(): + command_name = "Add vertices" + +func do_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + + if !tracked_block_data: + var tracked_vol:ConvexVolume = block.control_mesh + tracked_block_data = tracked_vol.to_convex_block_data() + + for v in tracked_vol.vertices: + if v.selected: + selected_points.append(v.point) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(tracked_block_data) + + var point_list:PackedVector3Array = vol.get_points() + point_list.append_array(points_to_add) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(point_list) + new_vol.copy_face_attributes(vol) + + + for v_idx in new_vol.vertices.size(): + var v:ConvexVolume.VertexInfo = new_vol.vertices[v_idx] + if selected_points.has(v.point): + v.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_clip_block.gd b/addons/cyclops_level_builder/commands/cmd_clip_block.gd new file mode 100644 index 0000000..e27246b --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_clip_block.gd @@ -0,0 +1,102 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandClipBlock +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +var block_path:NodePath +var cut_plane:Plane +var uv_transform:Transform2D = Transform2D.IDENTITY +var material_path:String = "" + +#Private +var block_sibling_name:String +var old_block_data:ConvexBlockData +var old_mat_list:Array[Material] +var block_sibling_path:NodePath + +func _init(): + command_name = "Clip block" + +func get_material_index(mat_list:Array[Material], path:String)->int: + if path.is_empty(): + return -1 + for i in mat_list.size(): + var mat:Material = mat_list[i] + if mat != null && mat.resource_path == path: + return i + return -1 + +func do_it(): + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + var block:CyclopsConvexBlock = builder.get_node(block_path) + + old_block_data = block.block_data.duplicate() + old_mat_list = block.materials.duplicate() + + var new_mat_list0:Array[Material] = old_mat_list.duplicate() + + var cut_mat_idx = get_material_index(old_mat_list, material_path) + if cut_mat_idx == -1: + var mat = load(material_path) + if mat is Material: + cut_mat_idx = new_mat_list0.size() + new_mat_list0.append(mat) + + + var new_mat_list1:Array[Material] = new_mat_list0.duplicate() + + var cut_plane_reverse:Plane = Plane(-cut_plane.normal, cut_plane.get_center()) + + var vol0:ConvexVolume = block.control_mesh.cut_with_plane(cut_plane, uv_transform, cut_mat_idx) + var vol1:ConvexVolume = block.control_mesh.cut_with_plane(MathUtil.flip_plane(cut_plane), uv_transform, cut_mat_idx) + + #Set data of existing block + block.block_data = vol0.to_convex_block_data() + block.materials = new_mat_list0 + + #Create second block + var block_sibling:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + blocks_root.add_child(block_sibling) + block_sibling.owner = builder.get_editor_interface().get_edited_scene_root() + block_sibling.name = block_sibling_name + block_sibling.selected = block.selected + block_sibling_path = block_sibling.get_path() + + block_sibling.block_data = vol1.to_convex_block_data() + block_sibling.materials = new_mat_list1 + + +func undo_it(): + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = old_block_data + block.materials = old_mat_list.duplicate() + + var block_sibling:CyclopsConvexBlock = builder.get_node(block_sibling_path) + block_sibling.queue_free() + + diff --git a/addons/cyclops_level_builder/commands/cmd_delete_blocks.gd b/addons/cyclops_level_builder/commands/cmd_delete_blocks.gd new file mode 100644 index 0000000..084350d --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_delete_blocks.gd @@ -0,0 +1,93 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandDeleteBlocks +extends CyclopsCommand + +class TrackedBlock extends RefCounted: + var path:NodePath + var path_parent:NodePath + var data:ConvexBlockData + var materials:Array[Material] + var selected:bool + var name:String + + func _init(block:CyclopsConvexBlock): + path = block.get_path() + path_parent = block.get_parent().get_path() + name = block.name + data = block.block_data.duplicate() + selected = block.selected + materials = block.materials + +#Public +var block_paths:Array[NodePath] + +#Private +var tracked_blocks:Array[TrackedBlock] + +func _init(): + command_name = "Delete blocks" + +func will_change_anything(): + if !block_paths.is_empty(): + return true + + return false + + +func do_it(): + #print("Delete do_it") + + if tracked_blocks.is_empty(): + var points:PackedVector3Array + + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + var tracker:TrackedBlock = TrackedBlock.new(block) + tracked_blocks.append(tracker) + + #Delete source blocks + for block_path in block_paths: + var del_block:CyclopsConvexBlock = builder.get_node(block_path) + del_block.queue_free() + + +func undo_it(): + #print("Delete undo_it") + for tracked in tracked_blocks: + var parent = builder.get_node(tracked.path_parent) + + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + block.block_data = tracked.data + block.materials = tracked.materials + block.name = tracked.name + block.selected = tracked.selected + + parent.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + + + + diff --git a/addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd b/addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd new file mode 100644 index 0000000..5158b77 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_duplicate_blocks.gd @@ -0,0 +1,87 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandDuplicateBlocks +extends CyclopsCommand + +#Public +var blocks_root_path:NodePath +var blocks_to_duplicate:Array[NodePath] +var move_offset:Vector3 +var lock_uvs:bool + +#Private +class BlockInfo extends RefCounted: + var new_block:CyclopsConvexBlock + var source_data:ConvexBlockData + #var materials:Array[Material] + + func _init(new_block:CyclopsConvexBlock, source_data:ConvexBlockData): + self.new_block = new_block + self.source_data = source_data + +var added_blocks:Array[BlockInfo] + +func will_change_anything(): + return !added_blocks.is_empty() + +func do_it(): + if added_blocks.is_empty(): + #Create new blocks + for block_path in blocks_to_duplicate: + var new_block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var source_block:CyclopsConvexBlock = builder.get_node(block_path) + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + new_block.name = GeneralUtil.find_unique_name(blocks_root, source_block.name) + blocks_root.add_child(new_block) + new_block.owner = builder.get_editor_interface().get_edited_scene_root() + + var info:BlockInfo = BlockInfo.new(new_block, source_block.block_data) + new_block.materials = source_block.materials + new_block.selected = true + + added_blocks.append(info) + + for path in blocks_to_duplicate: + var block:CyclopsConvexBlock = builder.get_node(path) + block.selected = false + + for info in added_blocks: + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(info.source_data) + vol.translate(move_offset, lock_uvs) + info.new_block.block_data = vol.to_convex_block_data() + + +func undo_it(): + for block in added_blocks: + block.new_block.queue_free() + added_blocks = [] + + for path in blocks_to_duplicate: + var block:CyclopsConvexBlock = builder.get_node(path) + block.selected = true + diff --git a/addons/cyclops_level_builder/commands/cmd_merge_blocks.gd b/addons/cyclops_level_builder/commands/cmd_merge_blocks.gd new file mode 100644 index 0000000..8c75922 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_merge_blocks.gd @@ -0,0 +1,149 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMergeBlocks +extends CyclopsCommand + +class TrackedBlock extends RefCounted: + var path:NodePath + var path_parent:NodePath + var data:ConvexBlockData + var materials:Array[Material] + var selected:bool + var name:String + + func _init(block:CyclopsConvexBlock): + path = block.get_path() + path_parent = block.get_parent().get_path() + name = block.name + data = block.block_data.duplicate() + selected = block.selected + materials = block.materials + +#Public +var block_paths:Array[NodePath] +var block_name_prefix:String = "Block_" + +#Private +var tracked_blocks:Array[TrackedBlock] +var merged_block_data:ConvexBlockData +var merged_mat_list:Array[Material] +var merged_block_path:NodePath + +func _init(): + command_name = "Merge blocks" + +func get_best_face(centroid:Vector3, ref_list:Array[NodePath])->Array: + var best_face:ConvexVolume.FaceInfo + var best_dist:float = INF + var best_block:CyclopsConvexBlock + + for block_path in ref_list: + var block:CyclopsConvexBlock = builder.get_node(block_path) + var vol:ConvexVolume = block.control_mesh + for f in vol.faces: + var face_center:Vector3 = f.get_centroid() + var offset:float = centroid.distance_squared_to(face_center) + if offset < best_dist: + best_dist = offset + best_face = f + best_block = block + + if best_face.material_id == -1: + return [best_face, null] + return [best_face, best_block.materials[best_face.material_id]] + +func copy_face_attributes(target:ConvexVolume, ref_list:Array[NodePath])->Array[Material]: + var mat_list:Array[Material] + + for f in target.faces: + var centroid:Vector3 = f.get_centroid() + var res:Array = get_best_face(centroid, ref_list) + var ref_face:ConvexVolume.FaceInfo = res[0] + var material:Material = res[1] + + var mat_idx:int = -1 + if material != null: + mat_idx = mat_list.find(material) + if mat_idx == -1: + mat_idx = mat_list.size() + mat_list.append(material) + + f.material_id = mat_idx + f.uv_transform = ref_face.uv_transform + f.selected = ref_face.selected + + return mat_list + +func do_it(): + if tracked_blocks.is_empty(): + var points:PackedVector3Array + + for path in block_paths: + var block:CyclopsConvexBlock = builder.get_node(path) + var tracker:TrackedBlock = TrackedBlock.new(block) + tracked_blocks.append(tracker) + + points.append_array(block.control_mesh.get_points()) + + var merged_vol:ConvexVolume = ConvexVolume.new() + merged_vol.init_from_points(points) + merged_mat_list = copy_face_attributes(merged_vol, block_paths) + merged_block_data = merged_vol.to_convex_block_data() + + + #Delete source blocks + for block_path in block_paths: + var del_block:CyclopsConvexBlock = builder.get_node(block_path) + del_block.queue_free() + + #Create block + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + var parent:Node = builder.get_node(tracked_blocks[0].path_parent) + parent.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.name = GeneralUtil.find_unique_name(parent, block_name_prefix) + block.block_data = merged_block_data + block.materials = merged_mat_list + #block.materials + + merged_block_path = block.get_path() + +func undo_it(): +# var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + var merged_block:CyclopsConvexBlock = builder.get_node(merged_block_path) + merged_block.queue_free() + +# for i in blocks_to_merge.size(): + for tracked in tracked_blocks: + var parent = builder.get_node(tracked.path_parent) + + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + block.block_data = tracked.data + block.materials = tracked.materials + block.name = tracked.name + block.selected = tracked.selected + + parent.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() diff --git a/addons/cyclops_level_builder/commands/cmd_move_blocks.gd b/addons/cyclops_level_builder/commands/cmd_move_blocks.gd new file mode 100644 index 0000000..2081e16 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_blocks.gd @@ -0,0 +1,64 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMoveBlocks +extends CyclopsCommand + +#Public data to set before activating command +var move_offset:Vector3 +var lock_uvs:bool = false + +#Private +var blocks_to_move:Array[NodePath] +var tracked_block_data:Array[ConvexBlockData] + +func _init(): + command_name = "Move blocks" + +#Add blocks to be moved here +func add_block(block_path:NodePath): + blocks_to_move.append(block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + #tracked_blocks.append(block) + tracked_block_data.append(block.block_data.duplicate()) + +#Moves all blocks from the start position by this amount +func move_to(offset:Vector3): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(tracked_block_data[i]) + ctl_mesh.translate(offset, lock_uvs) + var result_data:ConvexBlockData = ctl_mesh.to_convex_block_data() + block.block_data = result_data + #tracked_blocks[block_idx].block_data = result_data + +func do_it(): + move_to(move_offset) + +func undo_it(): + move_to(Vector3.ZERO) + diff --git a/addons/cyclops_level_builder/commands/cmd_move_edges.gd b/addons/cyclops_level_builder/commands/cmd_move_edges.gd new file mode 100644 index 0000000..1ff8bd2 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_edges.gd @@ -0,0 +1,132 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMoveEdges +extends CyclopsCommand + + +class BlockEdgeChanges extends RefCounted: + var block_path:NodePath + var edge_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var move_offset:Vector3 = Vector3.ZERO + +#Private +var block_map:Dictionary = {} + +func add_edge(block_path:NodePath, index:int): + add_edges(block_path, [index]) + +func add_edges(block_path:NodePath, indices:Array[int]): + var changes:BlockEdgeChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockEdgeChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.edge_indices.has(index): + changes.edge_indices.append(index) + +func _init(): + command_name = "Move edges" + + +func do_it(): +# print("cmd move edges- DO IT") + + for block_path in block_map.keys(): + +# print("%s" % block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + var rec:BlockEdgeChanges = block_map[block_path] + +# print("rec %s" % rec) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# print("init done") + + #var moved_vert_indices:PackedInt32Array + var new_points:PackedVector3Array + var new_sel_centroids:PackedVector3Array + var moved_indices:Array[int] = [] + for edge_index in rec.edge_indices: + var e:ConvexVolume.EdgeInfo = vol.edges[edge_index] + var v0:ConvexVolume.VertexInfo = vol.vertices[e.start_index] + var v1:ConvexVolume.VertexInfo = vol.vertices[e.end_index] + if e.selected: + new_sel_centroids.append((v0.point + v1.point) / 2 + move_offset) + + if !moved_indices.has(e.start_index): + new_points.append(v0.point + move_offset) + moved_indices.append(e.start_index) + if !moved_indices.has(e.end_index): + new_points.append(v1.point + move_offset) + moved_indices.append(e.end_index) + else: + if !moved_indices.has(e.start_index): + new_points.append(v0.point + move_offset) + moved_indices.append(e.start_index) + if !moved_indices.has(e.end_index): + new_points.append(v1.point + move_offset) + moved_indices.append(e.end_index) + + for v_idx in vol.vertices.size(): + if !moved_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point) + #print("new points_ %s" % new_points) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(new_points) + + new_vol.copy_face_attributes(vol) + + #print("new init done") + + #Copy selection data + for e_idx in new_vol.edges.size(): + var e_new:ConvexVolume.EdgeInfo = new_vol.edges[e_idx] + var centroid:Vector3 = (new_vol.vertices[e_new.start_index].point + new_vol.vertices[e_new.end_index].point) / 2 +# print ("vol point %s " % v1.point) + if new_sel_centroids.has(centroid): +# print("set sel") + e_new.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): + for block_path in block_map.keys(): + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_move_face_planar.gd b/addons/cyclops_level_builder/commands/cmd_move_face_planar.gd new file mode 100644 index 0000000..8cff421 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_face_planar.gd @@ -0,0 +1,104 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMoveFacePlanar +extends CyclopsCommand + +#Public data to set before activating command +var blocks_root_path:NodePath +var block_path:NodePath +var move_dir_normal:Vector3 +var move_amount:float +var face_id:int +var lock_uvs:bool = false + + +#Private +var block_name:String +var block_selected:bool +var tracked_block_data:ConvexBlockData + +var deleted:bool = false + + +func _init(): + command_name = "Move face planar" + +func move_to(offset:Vector3, intermediate:bool): +# print("move_to off %s faceid %s amount %s movedir %s" % [offset, face_id, move_amount, move_dir_normal]) + if !tracked_block_data: + var block:CyclopsConvexBlock = builder.get_node(block_path) + + block_name = block.name + block_selected = block.selected + tracked_block_data = block.block_data + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(tracked_block_data) + var new_mesh:ConvexVolume = ctl_mesh.translate_face_plane(face_id, offset, lock_uvs) + + #print("offset %s" % offset) + #print("ctl_mesh %s" % ctl_mesh.get_points()) + + + var block:CyclopsConvexBlock = builder.get_node(block_path) + + if new_mesh == null || new_mesh.is_empty(): + #print("new_mesh EMPTY") + block.block_data = null + if !intermediate: + block.queue_free() + deleted = true + return + + #ctl_mesh.remove_unused_planes() + #print("new_mesh %s" % new_mesh.get_points()) + + var result_data:ConvexBlockData = new_mesh.to_convex_block_data() +# var result_data:ConvexBlockData = ctl_mesh.to_convex_block_data() + block.block_data = result_data + + +func do_it_intermediate(): + move_to(move_dir_normal * move_amount, true) + +func do_it(): + move_to(move_dir_normal * move_amount, false) + +func undo_it(): + if deleted: + var block:CyclopsConvexBlock = preload("../nodes/cyclops_convex_block.gd").new() + + var blocks_root:CyclopsBlocks = builder.get_node(blocks_root_path) + blocks_root.add_child(block) + block.owner = builder.get_editor_interface().get_edited_scene_root() + block.block_data = tracked_block_data + block.name = block_name + block.selected = block_selected + + deleted = false + return + + move_to(Vector3.ZERO, false) + diff --git a/addons/cyclops_level_builder/commands/cmd_move_faces.gd b/addons/cyclops_level_builder/commands/cmd_move_faces.gd new file mode 100644 index 0000000..8465319 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_faces.gd @@ -0,0 +1,131 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMoveFaces +extends CyclopsCommand + +class BlockFaceChanges extends RefCounted: + var block_path:NodePath + var face_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var move_offset:Vector3 = Vector3.ZERO + +#Private +var block_map:Dictionary = {} + + +func add_face(block_path:NodePath, index:int): +# print("Adding face %s %s" % [block_path, index]) + add_faces(block_path, [index]) + +func add_faces(block_path:NodePath, indices:Array[int]): + var changes:BlockFaceChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockFaceChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.face_indices.has(index): + changes.face_indices.append(index) + + +func _init(): + command_name = "Move faces" + + + +func do_it(): +# print("cmd move edges- DO IT") + + for block_path in block_map.keys(): + +# print("%s" % block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + var rec:BlockFaceChanges = block_map[block_path] + +# print("rec %s" % rec) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# print("init done") + + #var moved_vert_indices:PackedInt32Array + var new_points:PackedVector3Array + var new_sel_centroids:PackedVector3Array + var moved_vert_indices:Array[int] = [] + for face_index in rec.face_indices: + var f:ConvexVolume.FaceInfo = vol.faces[face_index] + var centroid:Vector3 = f.get_centroid() +# var v0:ConvexVolume.VertexInfo = vol.vertices[e.start_index] +# var v1:ConvexVolume.VertexInfo = vol.vertices[e.end_index] + if f.selected: + new_sel_centroids.append(centroid + move_offset) + + for v_idx in f.vertex_indices: + if !moved_vert_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point + move_offset) + moved_vert_indices.append(v_idx) + else: + for v_idx in f.vertex_indices: + if !moved_vert_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point + move_offset) + moved_vert_indices.append(v_idx) + + for v_idx in vol.vertices.size(): + if !moved_vert_indices.has(v_idx): + new_points.append(vol.vertices[v_idx].point) + #print("new points_ %s" % new_points) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(new_points) + + new_vol.copy_face_attributes(vol) + #print("new init done") + + #Copy selection data + for f_idx in new_vol.faces.size(): + var f_new:ConvexVolume.FaceInfo = new_vol.faces[f_idx] + var centroid:Vector3 = f_new.get_centroid() +# print ("vol point %s " % v1.point) + if new_sel_centroids.has(centroid): +# print("set sel") + f_new.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): + for block_path in block_map.keys(): + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_move_vertices.gd b/addons/cyclops_level_builder/commands/cmd_move_vertices.gd new file mode 100644 index 0000000..9c8801f --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_move_vertices.gd @@ -0,0 +1,105 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMoveVertices +extends CyclopsCommand + +class BlockVertexChanges extends RefCounted: + var block_path:NodePath + var vertex_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var move_offset:Vector3 = Vector3.ZERO + +#Private +var block_map:Dictionary = {} + + +func add_vertex(block_path:NodePath, index:int): + add_vertices(block_path, [index]) + +func add_vertices(block_path:NodePath, indices:Array[int]): +# print("adding vertex %s %s" % [block_path, indices]) + var changes:BlockVertexChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockVertexChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.vertex_indices.has(index): + changes.vertex_indices.append(index) + +func _init(): + command_name = "Move vertices" + +func do_it(): +# print("move verts do_it") + for block_path in block_map.keys(): + + var block:CyclopsConvexBlock = builder.get_node(block_path) + var rec:BlockVertexChanges = block_map[block_path] + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# print("rec.vertex_indices %s" % rec.vertex_indices) +# print("move_offset %s" % move_offset) + var selected_points:PackedVector3Array + var new_points:PackedVector3Array + for v_idx in vol.vertices.size(): + if rec.vertex_indices.has(v_idx): + var p:Vector3 = vol.vertices[v_idx].point + move_offset + new_points.append(p) + selected_points.append(p) + else: + new_points.append(vol.vertices[v_idx].point) + + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(new_points) + + new_vol.copy_face_attributes(vol) + + for v_idx in new_vol.vertices.size(): + var v:ConvexVolume.VertexInfo = new_vol.vertices[v_idx] +# print ("vol point %s " % v.point) + if selected_points.has(v.point): +# print("set sel") + v.selected = true + + block.block_data = new_vol.to_convex_block_data() + + +func undo_it(): +# print("move verts undo_it") + for block_path in block_map.keys(): + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data diff --git a/addons/cyclops_level_builder/commands/cmd_select_blocks.gd b/addons/cyclops_level_builder/commands/cmd_select_blocks.gd new file mode 100644 index 0000000..13318e4 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_blocks.gd @@ -0,0 +1,135 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSelectBlocks +extends CyclopsCommand + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +var block_paths:Array[NodePath] + +#Private +var tracked_selected_blocks:Array[NodePath] +var tracked_active_blocks:Array[NodePath] + + +func _init(): + command_name = "Select blocks" + +func will_change_anything()->bool: + + var active_path:NodePath + if !block_paths.is_empty(): + active_path = block_paths[0] + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + var path:NodePath = block.get_path() + + match selection_type: + Selection.Type.REPLACE: + if block.selected != block_paths.has(path): + return true + + if block.active != (path == active_path): + return true + + Selection.Type.ADD: + if block_paths.has(path): + if !block.selected: + return true + if block.active != (path == active_path): + return true + + Selection.Type.SUBTRACT: + if block_paths.has(path): + if block.selected: + return true + + Selection.Type.TOGGLE: + if !block_paths.is_empty(): + return true + + return false + + +func do_it(): +# print("sel verts do_it") + + #Cache state + tracked_selected_blocks.clear() + tracked_active_blocks.clear() + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + tracked_selected_blocks.append(block.get_path()) + if block.active: + tracked_active_blocks.append(block.get_path()) + + #Do selection + var active_path:NodePath + if !block_paths.is_empty(): + active_path = block_paths[0] + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + var path:NodePath = block.get_path() + + match selection_type: + Selection.Type.REPLACE: + block.selected = block_paths.has(path) + block.active = path == active_path + Selection.Type.ADD: + if block_paths.has(path): + block.selected = true + block.active = path == active_path + Selection.Type.SUBTRACT: + if block_paths.has(path): + block.selected = false + block.active = false + Selection.Type.TOGGLE: + block.active = path == active_path + if block_paths.has(path): + block.selected = !block.selected + if !block.selected: + block.active = false + + builder.selection_changed.emit() + +func undo_it(): + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + var path:NodePath = block.get_path() + + block.selected = tracked_selected_blocks.has(path) + block.active = tracked_active_blocks.has(path) + + builder.selection_changed.emit() diff --git a/addons/cyclops_level_builder/commands/cmd_select_edges.gd b/addons/cyclops_level_builder/commands/cmd_select_edges.gd new file mode 100644 index 0000000..4bd7e8f --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_edges.gd @@ -0,0 +1,189 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSelectEdges +extends CyclopsCommand + +class BlockEdgeChanges extends RefCounted: + var block_path:NodePath + var edge_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +#Private +var block_map:Dictionary = {} + + +func add_edge(block_path:NodePath, index:int): + add_edges(block_path, [index]) + +func add_edges(block_path:NodePath, indices:Array[int]): + var changes:BlockEdgeChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockEdgeChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.edge_indices.has(index): + changes.edge_indices.append(index) + + +func _init(): + command_name = "Select edges" + +func will_change_anything()->bool: + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.edge_indices.is_empty(): + if vol.active_edge != rec.edge_indices[0]: + return true + + match selection_type: + Selection.Type.REPLACE: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if e.selected != rec.edge_indices.has(e_idx): + #print("will change SREP") + return true + Selection.Type.ADD: + for e_idx in rec.edge_indices: + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + if !e.selected: + #print("will change ADD") + return true + Selection.Type.SUBTRACT: + for e_idx in rec.edge_indices: + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + if e.selected: + #print("will change SUB") + return true + Selection.Type.TOGGLE: + #print("will change TOG") + return true + + return false + +func do_it(): +# print("sel edges do_it") + + for block_path in block_map.keys(): +# print("path %s" % block_path) + + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.edge_indices.is_empty(): + var active_index:int = rec.edge_indices[0] + match selection_type: + Selection.Type.REPLACE: + vol.active_edge = active_index + Selection.Type.ADD: + vol.active_edge = active_index + Selection.Type.SUBTRACT: + if rec.edge_indices.has(vol.active_edge): + vol.active_edge = -1 + Selection.Type.TOGGLE: + if rec.edge_indices.has(vol.active_edge): + vol.active_edge = -1 + elif !vol.edges[active_index].selected: + vol.active_edge = active_index + + match selection_type: + Selection.Type.REPLACE: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + e.selected = rec.edge_indices.has(e_idx) + + Selection.Type.ADD: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + e.selected = true + + Selection.Type.SUBTRACT: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + e.selected = false + + Selection.Type.TOGGLE: + for e_idx in vol.edges.size(): + var e:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if rec.edge_indices.has(e_idx): + #print("flipping %s" % e.selected) + e.selected = !e.selected + + if vol.active_edge != -1: + if vol.active_edge >= vol.edges.size() || !vol.edges[vol.active_edge].selected: + vol.active_edge = -1 + + #Synchronize vertex & face selection + #print("synchronizing verts") +# var selected_verts:Array[int] = [] +# for e in vol.edges: +# if e.selected: +# for v_idx in [e.start_index, e.end_index]: +# if !selected_verts.has(v_idx): +# #print("selecting vert %s" % v_idx) +# selected_verts.append(v_idx) +# for v_idx in vol.vertices.size(): +# vol.vertices[v_idx].selected = selected_verts.has(v_idx) +# vol.update_edge_and_face_selection_from_vertices() + + block.block_data = vol.to_convex_block_data() + + builder.selection_changed.emit() + +func undo_it(): +# print("sel verts undo_it") + #print("sel vert undo_it()") + for block_path in block_map.keys(): + var rec:BlockEdgeChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() + + + + diff --git a/addons/cyclops_level_builder/commands/cmd_select_faces.gd b/addons/cyclops_level_builder/commands/cmd_select_faces.gd new file mode 100644 index 0000000..1d583a1 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_faces.gd @@ -0,0 +1,180 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSelectFaces +extends CyclopsCommand + +class BlockFaceChanges extends RefCounted: + var block_path:NodePath + var face_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +#Private +var block_map:Dictionary = {} + +func add_face(block_path:NodePath, index:int): + add_faces(block_path, [index]) + +func add_faces(block_path:NodePath, indices:Array[int]): + var changes:BlockFaceChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockFaceChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.face_indices.has(index): + changes.face_indices.append(index) + + +func _init(): + command_name = "Select faces" + +func will_change_anything()->bool: + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + +# var active_idx:int = -1 + if !rec.face_indices.is_empty(): + if vol.active_face != rec.face_indices[0]: + return true + + match selection_type: + Selection.Type.REPLACE: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if f.selected != rec.face_indices.has(f_idx): + return true + Selection.Type.ADD: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + if !f.selected: + return true + Selection.Type.SUBTRACT: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + if f.selected: + return true + Selection.Type.TOGGLE: + return true + + return false + +func do_it(): + #print("sel verts do_it") + #print("sel vert do_it()") + for block_path in block_map.keys(): +# print("path %s" % block_path) + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + if !rec.face_indices.is_empty(): + var active_index:int = rec.face_indices[0] + match selection_type: + Selection.Type.REPLACE: + vol.active_face = active_index + Selection.Type.ADD: + vol.active_face = active_index + Selection.Type.SUBTRACT: + if rec.face_indices.has(vol.active_face): + vol.active_face = -1 + Selection.Type.TOGGLE: + if rec.face_indices.has(vol.active_face): + vol.active_face = -1 + elif !vol.faces[active_index].selected: + vol.active_face = active_index + + +# print("face active index %s" % active_idx) + + match selection_type: + Selection.Type.REPLACE: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + f.selected = rec.face_indices.has(f_idx) + + Selection.Type.ADD: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + f.selected = true + + Selection.Type.SUBTRACT: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + f.selected = false + + Selection.Type.TOGGLE: + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if rec.face_indices.has(f_idx): + f.selected = !f.selected + + if vol.active_face != -1: + if vol.active_face >= vol.faces.size() || !vol.faces[vol.active_face].selected: + vol.active_face = -1 + + + #Synchronize edge & vertex selection +# var selected_verts:Array[int] = [] +# for f in vol.faces: +# if f.selected: +# for v_idx in f.vertex_indices: +# if !selected_verts.has(v_idx): +# selected_verts.append(v_idx) +# for v_idx in vol.vertices.size(): +# vol.vertices[v_idx].selected = selected_verts.has(v_idx) +# vol.update_edge_and_face_selection_from_vertices() + + block.block_data = vol.to_convex_block_data() + builder.selection_changed.emit() + +func undo_it(): +# print("undo_it() select faces") + for block_path in block_map.keys(): + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() + diff --git a/addons/cyclops_level_builder/commands/cmd_select_vertices.gd b/addons/cyclops_level_builder/commands/cmd_select_vertices.gd new file mode 100644 index 0000000..99c51a9 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_select_vertices.gd @@ -0,0 +1,167 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSelectVertices +extends CyclopsCommand + +class BlockVertexChanges extends RefCounted: + var block_path:NodePath + var vertex_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +#Public +var selection_type:Selection.Type = Selection.Type.REPLACE + +#Private +var block_map:Dictionary = {} + + + + +func add_vertex(block_path:NodePath, index:int): + add_vertices(block_path, [index]) + +func add_vertices(block_path:NodePath, indices:Array[int]): + var changes:BlockVertexChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockVertexChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.vertex_indices.has(index): + changes.vertex_indices.append(index) + + +func _init(): + command_name = "Select vertices" + + +func will_change_anything()->bool: + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.vertex_indices.is_empty(): + if vol.active_vertex != rec.vertex_indices[0]: + return true + + match selection_type: + Selection.Type.REPLACE: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if v.selected != rec.vertex_indices.has(v_idx): + return true + Selection.Type.ADD: + for v_idx in rec.vertex_indices: + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + if !v.selected: + return true + Selection.Type.SUBTRACT: + for v_idx in rec.vertex_indices: + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + if v.selected: + return true + Selection.Type.TOGGLE: + return true + + return false + + +func do_it(): +# print("sel verts do_it") + for block_path in block_map.keys(): + #print("path %s" % node_path) + + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + if !rec.vertex_indices.is_empty(): + var active_index:int = rec.vertex_indices[0] + match selection_type: + Selection.Type.REPLACE: + vol.active_vertex = active_index + Selection.Type.ADD: + vol.active_vertex = active_index + Selection.Type.SUBTRACT: + if rec.vertex_indices.has(vol.active_vertex): + vol.active_vertex = -1 + Selection.Type.TOGGLE: + if rec.vertex_indices.has(vol.active_vertex): + vol.active_vertex = -1 + elif !vol.vertices[active_index].selected: + vol.active_vertex = active_index + + match selection_type: + Selection.Type.REPLACE: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + v.selected = rec.vertex_indices.has(v_idx) + + Selection.Type.ADD: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + v.selected = true + + Selection.Type.SUBTRACT: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + v.selected = false + + Selection.Type.TOGGLE: + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if rec.vertex_indices.has(v_idx): + v.selected = !v.selected + + vol.update_edge_and_face_selection_from_vertices() + block.block_data = vol.to_convex_block_data() + + builder.selection_changed.emit() + +func undo_it(): +# print("sel verts undo_it") + #print("sel vert undo_it()") + for block_path in block_map.keys(): + var rec:BlockVertexChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() diff --git a/addons/cyclops_level_builder/commands/cmd_set_material.gd b/addons/cyclops_level_builder/commands/cmd_set_material.gd new file mode 100644 index 0000000..d1ac8a4 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_set_material.gd @@ -0,0 +1,153 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSetMaterial +extends CyclopsCommand + +class Target extends RefCounted: + var block_path:NodePath + var face_indices:PackedInt32Array + +class BlockCache extends RefCounted: + var path:NodePath + var data:ConvexBlockData + var materials:Array[Material] + +#Public +var material_path:String + +#Private +var target_list:Array[Target] = [] + +var cache_list:Array[BlockCache] = [] + +func add_target(block_path:NodePath, face_indices:PackedInt32Array): +# print("add target %s %s" % [block_path.get_name(block_path.get_name_count() - 1), face_indices]) + var target:Target = Target.new() + target.block_path = block_path + target.face_indices = face_indices + + target_list.append(target) + +func make_cache(): + cache_list = [] + + for t in target_list: + var cache:BlockCache = BlockCache.new() + var block:CyclopsConvexBlock = builder.get_node(t.block_path) + + cache.path = block.get_path() + cache.data = block.block_data + cache.materials = block.materials.duplicate() + + cache_list.append(cache) + +func will_change_anything()->bool: + for t in target_list: + if !t.face_indices.is_empty(): + return true + return false + +func _init(): + command_name = "Set material" + +func do_it(): + make_cache() + +# print("cmd set material %s" % material_path) + for t in target_list: + var block:CyclopsConvexBlock = builder.get_node(t.block_path) + + var data:ConvexBlockData = block.block_data + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(data) + + var mat_list:Array[Material] = block.materials.duplicate() +# print("start mat list") +# for m in mat_list: +# print("cur mat %s" % "?" if m == null else m.resource_path) + + var target_material:Material + for m in mat_list: + if m.resource_path == material_path: + target_material = m + break + if !target_material: + target_material = load(material_path) + mat_list.append(target_material) + +# print("target mat list") +# for m in mat_list: +# print("mat %s" % "?" if m == null else m.resource_path) + + var remap_face_idx_to_mat:Array[Material] = [] + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(block.control_mesh.to_convex_block_data()) + + for f_idx in ctl_mesh.faces.size(): + var f:ConvexVolume.FaceInfo = ctl_mesh.faces[f_idx] + + if t.face_indices.has(f_idx): + remap_face_idx_to_mat.append(target_material) + elif f.material_id >= 0 && f.material_id < block.materials.size(): + remap_face_idx_to_mat.append(block.materials[f.material_id]) + else: + remap_face_idx_to_mat.append(null) + +# print("remap faceidx to mat") +# for m in remap_face_idx_to_mat: +# print("mat %s" % "?" if m == null else m.resource_path) + + #Reduce material list, discarding unused materials + var mat_list_reduced:Array[Material] + for m in remap_face_idx_to_mat: + if m != null && !mat_list_reduced.has(m): + mat_list_reduced.append(m) + +# print("mat_list_reduced") +# for m in mat_list_reduced: +# print("mat %s" % "?" if m == null else m.resource_path) + + #Set new face materials using new material ids + for f_idx in remap_face_idx_to_mat.size(): + #print("face_idx %s" % f_idx) + var face:ConvexVolume.FaceInfo = ctl_mesh.faces[f_idx] + var mat = remap_face_idx_to_mat[f_idx] + #print("mat %s" % "?" if mat == null else mat.resource_path) + #print("has %s" % mat_list_reduced.has(mat)) + #print("find %s" % mat_list_reduced.find(mat)) + + face.material_id = -1 if mat == null else mat_list_reduced.find(mat) + #print("face.material_id %s" % face.material_id) + + block.materials = mat_list_reduced + block.block_data = ctl_mesh.to_convex_block_data() + +func undo_it(): + for cache in cache_list: + var block:CyclopsConvexBlock = builder.get_node(cache.path) + block.materials = cache.materials.duplicate() + block.block_data = cache.data + diff --git a/addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd b/addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd new file mode 100644 index 0000000..3dc9078 --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_set_uv_transform.gd @@ -0,0 +1,110 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSetUvTransform +extends CyclopsCommand + + +class BlockFaceChanges extends RefCounted: + var block_path:NodePath + var face_indices:Array[int] = [] + var tracked_block_data:ConvexBlockData + +var uv_transform:Transform2D = Transform2D.IDENTITY + +#Private +var block_map:Dictionary = {} + +func add_face(block_path:NodePath, index:int): + add_faces(block_path, [index]) + +func add_faces(block_path:NodePath, indices:Array[int]): + var changes:BlockFaceChanges + if block_map.has(block_path): + changes = block_map[block_path] + else: + changes = BlockFaceChanges.new() + changes.block_path = block_path + var block:CyclopsConvexBlock = builder.get_node(block_path) + changes.tracked_block_data = block.block_data + block_map[block_path] = changes + + for index in indices: + if !changes.face_indices.has(index): + changes.face_indices.append(index) + + +func _init(): + command_name = "Set Uv Transform" + +func will_change_anything()->bool: + for block_path in block_map.keys(): + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + +# print("face active index %s" % active_idx) + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + for f_idx in vol.faces.size(): + if rec.face_indices.has(f_idx): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if f.uv_transform != uv_transform: + return true + + return false + + +func do_it(): + #print("sel verts do_it") + #print("sel vert do_it()") + for block_path in block_map.keys(): +# print("path %s" % block_path) + + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + +# print("face active index %s" % active_idx) + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(rec.tracked_block_data) + + for f_idx in vol.faces.size(): + if rec.face_indices.has(f_idx): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + f.uv_transform = uv_transform + + block.block_data = vol.to_convex_block_data() + builder.selection_changed.emit() + + +func undo_it(): +# print("undo_it() select faces") + for block_path in block_map.keys(): + var rec:BlockFaceChanges = block_map[block_path] + var block:CyclopsConvexBlock = builder.get_node(block_path) + block.block_data = rec.tracked_block_data + + builder.selection_changed.emit() + diff --git a/addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd b/addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd new file mode 100644 index 0000000..494fa1f --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_snap_to_grid.gd @@ -0,0 +1,82 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandSnapToGrid +extends CyclopsCommand + +class TrackedInfo extends RefCounted: + var data:ConvexBlockData + +var grid_size:float + +#Private +var blocks_to_move:Array[NodePath] +var tracked_block_data:Array[TrackedInfo] + + +func _init(): + command_name = "Snap to grid" + + +#Add blocks to be moved here +func add_block(block_path:NodePath): + blocks_to_move.append(block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + #tracked_blocks.append(block) + var info:TrackedInfo = TrackedInfo.new() + info.data = block.block_data.duplicate() +# info.materials = block.materials + tracked_block_data.append(info) + + +func do_it(): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(tracked_block_data[i].data) + + var points_new:PackedVector3Array + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + var p_snap:Vector3 = MathUtil.snap_to_grid(v.point, grid_size) + points_new.append(p_snap) + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(points_new) + + + new_vol.copy_face_attributes(vol) + + block.block_data = new_vol.to_convex_block_data() + +func undo_it(): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + block.block_data = tracked_block_data[i].data + + + diff --git a/addons/cyclops_level_builder/commands/cmd_transform_blocks.gd b/addons/cyclops_level_builder/commands/cmd_transform_blocks.gd new file mode 100644 index 0000000..ef1789b --- /dev/null +++ b/addons/cyclops_level_builder/commands/cmd_transform_blocks.gd @@ -0,0 +1,76 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandTransformBlocks +extends CyclopsCommand + +class TrackedInfo extends RefCounted: + var data:ConvexBlockData +# var materials:Array[Material] + +var transform:Transform3D +var lock_uvs:bool = false + +#Private +var blocks_to_move:Array[NodePath] +var tracked_block_data:Array[TrackedInfo] + +func _init(): + command_name = "Transform blocks" + +#Add blocks to be moved here +func add_block(block_path:NodePath): + blocks_to_move.append(block_path) + + var block:CyclopsConvexBlock = builder.get_node(block_path) + #tracked_blocks.append(block) + var info:TrackedInfo = TrackedInfo.new() + info.data = block.block_data.duplicate() +# info.materials = block.materials + tracked_block_data.append(info) + +#Moves all blocks from the start position by this amount +func apply_transform(xform:Transform3D): + for i in blocks_to_move.size(): + var block:CyclopsConvexBlock = builder.get_node(blocks_to_move[i]) + + var ctl_mesh:ConvexVolume = ConvexVolume.new() + ctl_mesh.init_from_convex_block_data(tracked_block_data[i].data) + ctl_mesh.transform(xform, lock_uvs) + var result_data:ConvexBlockData = ctl_mesh.to_convex_block_data() + block.block_data = result_data +# block.materials = tracked_block_data[i].materials + #tracked_blocks[block_idx].block_data = result_data + +func do_it(): +# if blocks_to_move.is_empty(): +# var blocks:Array[CyclopsConvexBlock] = builder.get_selected_blocks() +# for block in blocks: +# add_block(block.get_path()) + + apply_transform(transform) + +func undo_it(): + apply_transform(Transform3D.IDENTITY) + diff --git a/addons/cyclops_level_builder/commands/cyclops_command.gd b/addons/cyclops_level_builder/commands/cyclops_command.gd new file mode 100644 index 0000000..9bc5e0c --- /dev/null +++ b/addons/cyclops_level_builder/commands/cyclops_command.gd @@ -0,0 +1,43 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CyclopsCommand +extends RefCounted + +var command_name:String = "" +var builder:CyclopsLevelBuilder + +func add_to_undo_manager(undo_manager:EditorUndoRedoManager): + undo_manager.create_action(command_name, UndoRedo.MERGE_DISABLE) + undo_manager.add_do_method(self, "do_it") + undo_manager.add_undo_method(self, "undo_it") + + undo_manager.commit_action() + +func do_it()->void: + pass + +func undo_it()->void: + pass + diff --git a/addons/cyclops_level_builder/controls/numeric_line_edit.gd b/addons/cyclops_level_builder/controls/numeric_line_edit.gd new file mode 100644 index 0000000..90f281f --- /dev/null +++ b/addons/cyclops_level_builder/controls/numeric_line_edit.gd @@ -0,0 +1,125 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends PanelContainer +class_name NumbericLineEdit + +signal value_changed(value) + +@export var value:float: + get: + return value + set(v): + if value == v: + return + value = v + dirty = true + +@export var snap_size:float = 1 +var dirty:bool = true + +enum State{ IDLE, READY, DRAGGING, TEXT_EDIT } +var state:State = State.IDLE + +var mouse_down_pos:Vector2 +var drag_start_radius:float = 4 +var value_start_drag:float + +# Called when the node enters the scene tree for the first time. +func _ready(): +# text = "%.4f" % value +# $HBoxContainer/LineEdit.text = "%s" % value +# $HBoxContainer/Label.text = "%s" % value + $HBoxContainer/LineEdit.visible = false + pass + +func _process(delta): + if dirty: + $HBoxContainer/LineEdit.text = format_number(value) + $HBoxContainer/Label.text = format_number(value) + dirty = false + +func format_number(val:float)->String: + var text:String = "%.5f" % val + var idx:int = text.findn(".") + if idx != -1: + text = text.rstrip("0") + if text.right(1) == ".": + text = text.left(-1) + return text + + +func _gui_input(event): + if event is InputEventMouseButton: + var e:InputEventMouseButton = event + if e.is_pressed(): + if state == State.IDLE: + mouse_down_pos = e.position + state = State.READY + else: + if state == State.READY: + $HBoxContainer/LineEdit.visible = true + $HBoxContainer/Label.visible = false + state = State.TEXT_EDIT + elif state == State.DRAGGING: + state = State.IDLE + + + accept_event() + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + if state == State.READY: + if e.position.distance_to(mouse_down_pos) >= drag_start_radius: + state = State.DRAGGING + value_start_drag = value + + elif state == State.DRAGGING: + var offset = e.position.x - mouse_down_pos.x + var new_value = value_start_drag + (offset * snap_size / 20.0) + #print("-new_value %s" % new_value) + new_value = ceil(new_value / snap_size) * snap_size + + #print("new_value %s" % new_value) + + if value != new_value: + value = new_value + value_changed.emit(value) + dirty = true + +func _on_line_edit_text_submitted(new_text): + var regex = RegEx.new() + regex.compile("^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$") + var result:RegExMatch = regex.search(new_text) + if result: +# print("found match") + value = float(new_text) + value_changed.emit(value) + + dirty = true + state = State.IDLE + $HBoxContainer/LineEdit.visible = false + $HBoxContainer/Label.visible = true +# text = "%s" % value +# print("text changed2 %s" % text) diff --git a/addons/cyclops_level_builder/controls/numeric_line_edit.tscn b/addons/cyclops_level_builder/controls/numeric_line_edit.tscn new file mode 100644 index 0000000..c85c785 --- /dev/null +++ b/addons/cyclops_level_builder/controls/numeric_line_edit.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=2 format=3 uid="uid://diibmlqy1mpqb"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/numeric_line_edit.gd" id="1_u8bpo"] + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 476.0 +offset_bottom = 40.0 +script = ExtResource("1_u8bpo") +snap_size = 0.125 + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="LineEdit" type="LineEdit" parent="HBoxContainer"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +text = "0" +select_all_on_focus = true + +[node name="Label" type="Label" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "0" + +[connection signal="text_submitted" from="HBoxContainer/LineEdit" to="." method="_on_line_edit_text_submitted"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd new file mode 100644 index 0000000..47ee1c5 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd @@ -0,0 +1,66 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CheckBox +class_name LineEditorBool + +var resource:Resource: + get: + return resource + set(value): + resource = value + dirty = true + +var prop_name:String: + get: + return prop_name + set(value): + prop_name = value + dirty = true + +var dirty = true + +func update_from_resource(): + if resource: + var result = resource.get(prop_name) + if result != null: + button_pressed = result + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + update_from_resource() + dirty = false + + +func _on_toggled(button_pressed): + if resource: + print("prop_name %s" % prop_name) + print("button_pressed %s" % button_pressed) + resource.set(prop_name, button_pressed) diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn new file mode 100644 index 0000000..9ece333 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=2 format=3 uid="uid://dpncabeqiv1xo"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.gd" id="1_sn3qq"] + +[node name="CheckBox" type="CheckBox"] +offset_right = 24.0 +offset_bottom = 24.0 +script = ExtResource("1_sn3qq") + +[connection signal="toggled" from="." to="." method="_on_toggled"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd new file mode 100644 index 0000000..c3eea2e --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd @@ -0,0 +1,65 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends SpinBox +class_name LineEditorFloat + + +var resource:Resource: + get: + return resource + set(value): + resource = value + dirty = true + +var prop_name:String: + get: + return prop_name + set(value): + prop_name = value + dirty = true + +var dirty = true + +func update_from_resource(): + if resource: + var result = resource.get(prop_name) + if result != null: + value = result + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + update_from_resource() + dirty = false + + +func _on_value_changed(value): + if resource: + resource.set(prop_name, value) diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn new file mode 100644 index 0000000..2ce2af2 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=3 uid="uid://dg45e7tw7ttu3"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.gd" id="1_o1hmb"] + +[node name="SpinBox" type="SpinBox"] +offset_right = 83.0625 +offset_bottom = 31.0 +step = 0.001 +script = ExtResource("1_o1hmb") + +[connection signal="value_changed" from="." to="." method="_on_value_changed"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd new file mode 100644 index 0000000..2659e91 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd @@ -0,0 +1,71 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends SpinBox +class_name LineEditorInt + +var resource:Resource: + get: + return resource + set(value): + resource = value + dirty = true + +var prop_name:String: + get: + return prop_name + set(value): + prop_name = value + dirty = true + +var dirty = true + +func update_from_resource(): + #print("update_from_resource()") + if resource: + #print("resource %s" % resource) + #print("prop_name %s" % prop_name) + var result = resource.get(prop_name) + #print("result %s" % result) + if result != null: + value = result + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + update_from_resource() + dirty = false + + +func _on_value_changed(value): + print("_on_value_changed(value)") + if resource: + print("prop_name %s" % prop_name) + print("value %s" % value) + resource.set(prop_name, value) diff --git a/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn new file mode 100644 index 0000000..35e8ef9 --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=2 format=3 uid="uid://dh6frljlp7oqe"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.gd" id="1_ryygx"] + +[node name="SpinBox" type="SpinBox"] +offset_right = 83.0625 +offset_bottom = 40.0 +script = ExtResource("1_ryygx") + +[connection signal="value_changed" from="." to="." method="_on_value_changed"] diff --git a/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd new file mode 100644 index 0000000..16de2ba --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd @@ -0,0 +1,86 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Control +class_name ResourceInspector + +@export var target:Resource: + get: + return target + set(value): + target = value + build() + +func add_label(name:String): + var label:Label = Label.new() + label.text = name + $GridContainer.add_child(label) + +func build(): + for child in $GridContainer.get_children(): + $GridContainer.remove_child(child) + + if !target: + return + + for prop_dict in target.get_property_list(): + var prop_name:String = prop_dict["name"] +# prop_dict["class_name"] + + var type:Variant.Type = prop_dict["type"] + match type: + TYPE_BOOL: + add_label(prop_name) + + var editor:LineEditorBool = preload("res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_bool.tscn").instantiate() + editor.resource = target + editor.prop_name = prop_name + $GridContainer.add_child(editor) + + TYPE_INT: + add_label(prop_name) + + var editor:LineEditorInt = preload("res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_int.tscn").instantiate() + editor.resource = target + editor.prop_name = prop_name + $GridContainer.add_child(editor) + + TYPE_FLOAT: + add_label(prop_name) + + var editor:LineEditorFloat = preload("res://addons/cyclops_level_builder/controls/resource_inspector/line_editor_float.tscn").instantiate() + editor.resource = target + editor.prop_name = prop_name + $GridContainer.add_child(editor) + + pass + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn new file mode 100644 index 0000000..043660b --- /dev/null +++ b/addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=3 uid="uid://c2484sv0ymy2e"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.gd" id="1_m3yhx"] + +[node name="object_inspector" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_m3yhx") + +[node name="GridContainer" type="GridContainer" parent="."] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 +columns = 2 diff --git a/addons/cyclops_level_builder/cyclops_global_scene.gd b/addons/cyclops_level_builder/cyclops_global_scene.gd new file mode 100644 index 0000000..eaf9719 --- /dev/null +++ b/addons/cyclops_level_builder/cyclops_global_scene.gd @@ -0,0 +1,250 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Node3D +class_name CyclopsGlobalScene + +@export var selection_color:Color = Color(1, .5, .5, 1) +@export var default_material:Material = preload("res://addons/cyclops_level_builder/materials/grid.tres") +@export var tool_edit_active_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_active_material.tres") +@export var tool_edit_active_fill_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres") +@export var tool_edit_selected_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_selected_material.tres") +@export var tool_edit_selected_fill_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres") +@export var tool_edit_unselected_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres") +@export var tool_object_active_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_object_active_material.tres") +@export var tool_object_selected_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_object_selected_material.tres") +#@export var outline_material:Material = preload("res://addons/cyclops_level_builder/materials/block_outline_material.tres") + +@export var tool_material:Material = preload("res://addons/cyclops_level_builder/materials/tool_material.tres") +@export var outline_material:Material = preload("res://addons/cyclops_level_builder/materials/outline_material.tres") +#@export var tool_selected_material:Material +#@export var selected_material:Material +var tool_mesh:ImmediateMesh +#var vertex_size:float = .05 + +@export var grid_size:int = 0 + +var unit_sphere:GeometryMesh +var builder:CyclopsLevelBuilder +# +#enum DisplayMode { TEXTURED, WIRE } +#var display_mode:DisplayMode = DisplayMode.TEXTURED + +# Called when the node enters the scene tree for the first time. +func _ready(): + unit_sphere = MathGeometry.unit_sphere() + + tool_mesh = ImmediateMesh.new() + $ToolInstance3D.mesh = tool_mesh + +func draw_line(p0:Vector3, p1:Vector3, mat:Material): + +# var mat:Material = tool_selected_material if selected else tool_material + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINES, mat) + + tool_mesh.surface_add_vertex(p0) + tool_mesh.surface_add_vertex(p1) + + tool_mesh.surface_end() + +func draw_loop(points:PackedVector3Array, closed:bool = true, mat:Material = null): + if points.is_empty(): + return + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + for p in points: + tool_mesh.surface_add_vertex(p) + + if closed: + tool_mesh.surface_add_vertex(points[0]) + + tool_mesh.surface_end() + + +func draw_prism(points:PackedVector3Array, extrude:Vector3, mat:Material = null): + for p in points: + draw_vertex(p) + draw_vertex(p + extrude) + + #Bottom loop + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + for p in points: + tool_mesh.surface_add_vertex(p) + + tool_mesh.surface_add_vertex(points[0]) + + tool_mesh.surface_end() + + #Top loop + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + for p in points: + tool_mesh.surface_add_vertex(p + extrude) + + tool_mesh.surface_add_vertex(points[0] + extrude) + + tool_mesh.surface_end() + + #Sides + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINES, mat) + + for p in points: + tool_mesh.surface_add_vertex(p) + tool_mesh.surface_add_vertex(p + extrude) + + tool_mesh.surface_end() + + #$ToolInstance3D.mesh = mesh + + +func draw_triangles(tri_points:PackedVector3Array, mat:Material = null): + tool_mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES, mat) + + for p in tri_points: + tool_mesh.surface_add_vertex(p) + + tool_mesh.surface_end() + +func draw_rect(start:Vector3, end:Vector3, mat:Material = null): + + var p0:Vector3 = start + var p2:Vector3 = end + var p1:Vector3 = Vector3(p0.x, p0.y, p2.z) + var p3:Vector3 = Vector3(p2.x, p0.y, p0.z) + + draw_vertex(p0, mat) + draw_vertex(p1, mat) + draw_vertex(p2, mat) + draw_vertex(p3, mat) + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP, mat) + + tool_mesh.surface_add_vertex(p0) + tool_mesh.surface_add_vertex(p1) + tool_mesh.surface_add_vertex(p2) + tool_mesh.surface_add_vertex(p3) + tool_mesh.surface_add_vertex(p0) + + tool_mesh.surface_end() + + #$ToolInstance3D.mesh = tool_mesh + +func clear_tool_mesh(): + #tool_mesh = ImmediateMesh.new() + #$ToolInstance3D.mesh = tool_mesh + tool_mesh.clear_surfaces() + +# Draws the bounding box for the points [p0, p1, p2] +func draw_cube(p0:Vector3, p1:Vector3, p2:Vector3, mat:Material = null): +# print ("draw_cube %s %s %s" % [p0, p1, p2]) + + var bounds:AABB = AABB(p0, Vector3.ZERO) + bounds = bounds.expand(p1) + bounds = bounds.expand(p2) + + var p000:Vector3 = bounds.position + var p111:Vector3 = bounds.end + var p001:Vector3 = Vector3(p000.x, p000.y, p111.z) + var p010:Vector3 = Vector3(p000.x, p111.y, p000.z) + var p011:Vector3 = Vector3(p000.x, p111.y, p111.z) + var p100:Vector3 = Vector3(p111.x, p000.y, p000.z) + var p101:Vector3 = Vector3(p111.x, p000.y, p111.z) + var p110:Vector3 = Vector3(p111.x, p111.y, p000.z) + + draw_vertex(p000, mat) + draw_vertex(p001, mat) + draw_vertex(p010, mat) + draw_vertex(p011, mat) + draw_vertex(p100, mat) + draw_vertex(p101, mat) + draw_vertex(p110, mat) + draw_vertex(p111, mat) + + + tool_mesh.surface_begin(Mesh.PRIMITIVE_LINES, mat) + + tool_mesh.surface_add_vertex(p000) + tool_mesh.surface_add_vertex(p001) + tool_mesh.surface_add_vertex(p000) + tool_mesh.surface_add_vertex(p100) + tool_mesh.surface_add_vertex(p101) + tool_mesh.surface_add_vertex(p001) + tool_mesh.surface_add_vertex(p101) + tool_mesh.surface_add_vertex(p100) + + tool_mesh.surface_add_vertex(p010) + tool_mesh.surface_add_vertex(p011) + tool_mesh.surface_add_vertex(p010) + tool_mesh.surface_add_vertex(p110) + tool_mesh.surface_add_vertex(p111) + tool_mesh.surface_add_vertex(p011) + tool_mesh.surface_add_vertex(p111) + tool_mesh.surface_add_vertex(p110) + + tool_mesh.surface_add_vertex(p000) + tool_mesh.surface_add_vertex(p010) + tool_mesh.surface_add_vertex(p100) + tool_mesh.surface_add_vertex(p110) + tool_mesh.surface_add_vertex(p101) + tool_mesh.surface_add_vertex(p111) + tool_mesh.surface_add_vertex(p001) + tool_mesh.surface_add_vertex(p011) + + tool_mesh.surface_end() + + #$ToolInstance3D.mesh = mesh + +func draw_points(points:PackedVector3Array, mat:Material = null): + for p in points: + draw_vertex(p, mat) + +func draw_vertex(position:Vector3, mat:Material = null): + var xform:Transform3D = Transform3D(Basis.IDENTITY.scaled(Vector3.ONE * builder.handle_point_radius), position) + draw_sphere(xform, mat) + +func draw_sphere(xform:Transform3D = Transform3D.IDENTITY, material:Material = null, segs_lat:int = 6, segs_long:int = 8): + unit_sphere.append_to_immediate_mesh(tool_mesh, material, xform) + + +func draw_selected_blocks(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #var mesh:ImmediateMesh = ImmediateMesh.new() + + if builder.active_node is CyclopsBlocks: + var blocks_root:CyclopsBlocks = builder.active_node + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + block.append_mesh_outline(tool_mesh, viewport_camera, blocks_root.global_transform) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): +# if Engine.is_editor_hint(): +# rebuild_mesh() + pass diff --git a/addons/cyclops_level_builder/cyclops_global_scene.tscn b/addons/cyclops_level_builder/cyclops_global_scene.tscn new file mode 100644 index 0000000..d37c83d --- /dev/null +++ b/addons/cyclops_level_builder/cyclops_global_scene.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=3 uid="uid://4siqre3jhe80"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/cyclops_global_scene.gd" id="1_nu1d3"] + +[sub_resource type="PlaneMesh" id="PlaneMesh_sl0cw"] + +[sub_resource type="ImmediateMesh" id="ImmediateMesh_ey6kk"] + +[node name="CyclopsGlobals" type="Node3D"] +script = ExtResource("1_nu1d3") + +[node name="ControlMesh" type="MeshInstance3D" parent="."] +visible = false +mesh = SubResource("PlaneMesh_sl0cw") + +[node name="ToolInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("ImmediateMesh_ey6kk") diff --git a/addons/cyclops_level_builder/cyclops_level_builder.gd b/addons/cyclops_level_builder/cyclops_level_builder.gd new file mode 100644 index 0000000..568af41 --- /dev/null +++ b/addons/cyclops_level_builder/cyclops_level_builder.gd @@ -0,0 +1,225 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends EditorPlugin +class_name CyclopsLevelBuilder + +signal active_node_changed +signal selection_changed + +const AUTOLOAD_NAME = "CyclopsAutoload" + +var material_dock:Control +var uv_editor_dock:Control +var tool_properties_dock:Control +#var sticky_toolbar:StickyToolbar +var editor_toolbar:EditorToolbar +var activated:bool = false + + +var block_create_distance:float = 20 +var tool:CyclopsTool = null +var lock_uvs:bool = false +var tool_overlay_extrude:float = .01 + +var tool_uv_transform:Transform2D +var tool_material_path:String + +var handle_point_radius:float = .05 +var handle_screen_radius:float = 4 + +var drag_start_radius:float = 4 + +enum Mode { OBJECT, EDIT } +var mode:Mode = Mode.OBJECT +enum EditMode { VERTEX, EDGE, FACE } +var edit_mode:EditMode = EditMode.VERTEX + +var display_mode:DisplayMode.Type = DisplayMode.Type.TEXTURED + +#var _active_node:GeometryBrush +var active_node:CyclopsBlocks: + get: + return active_node + set(value): + if active_node != value: + active_node = value + active_node_changed.emit() + +func get_selected_blocks()->Array[CyclopsConvexBlock]: + var result:Array[CyclopsConvexBlock] + + if active_node: + for child in active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if child.selected: + result.append(child) + + return result + +func _get_plugin_name()->String: + return "CyclopsLevelBuilder" + +func _get_plugin_icon()->Texture2D: + return preload("res://addons/cyclops_level_builder/art/cyclops.svg") + +func _enter_tree(): + add_custom_type("CyclopsBlocks", "Node3D", preload("nodes/cyclops_blocks.gd"), preload("nodes/cyclops_blocks_icon.png")) + add_custom_type("CyclopsConvexBlock", "Node", preload("nodes/cyclops_convex_block.gd"), preload("nodes/cyclops_blocks_icon.png")) + add_custom_type("CyclopsConvexBlockBody", "Node", preload("nodes/cyclops_convex_block_body.gd"), preload("nodes/cyclops_blocks_icon.png")) + + add_autoload_singleton(AUTOLOAD_NAME, "res://addons/cyclops_level_builder/cyclops_global_scene.tscn") + + material_dock = preload("res://addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn").instantiate() + material_dock.builder = self + + uv_editor_dock = preload("res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn").instantiate() + uv_editor_dock.builder = self + + tool_properties_dock = preload("res://addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn").instantiate() + tool_properties_dock.builder = self + + editor_toolbar = preload("menu/editor_toolbar.tscn").instantiate() + editor_toolbar.editor_plugin = self + +# sticky_toolbar = preload("menu/sticky_toolbar.tscn").instantiate() +# sticky_toolbar.plugin = self +# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, sticky_toolbar) + + var editor:EditorInterface = get_editor_interface() + var selection:EditorSelection = editor.get_selection() + selection.selection_changed.connect(on_selection_changed) + + update_activation() + + + #Wait until everything is loaded + await get_tree().process_frame + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + global_scene.builder = self + + switch_to_tool(ToolBlock.new()) + +func find_blocks_root(node:Node)->CyclopsBlocks: + if node is CyclopsBlocks: + return node + if node is CyclopsConvexBlock: + return find_blocks_root(node.get_parent()) + return null + +func update_activation(): + var editor:EditorInterface = get_editor_interface() + var selection:EditorSelection = editor.get_selection() + var nodes:Array[Node] = selection.get_selected_nodes() + if !nodes.is_empty(): + var node:Node = nodes[0] + + var blocks_root:CyclopsBlocks = find_blocks_root(node) + + if blocks_root: + active_node = blocks_root + if !activated: + add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar) + add_control_to_dock(DOCK_SLOT_RIGHT_BL, material_dock) + add_control_to_dock(DOCK_SLOT_RIGHT_BL, uv_editor_dock) + add_control_to_dock(DOCK_SLOT_RIGHT_BL, tool_properties_dock) + activated = true + else: + if activated: + remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar) + remove_control_from_docks(material_dock) + remove_control_from_docks(uv_editor_dock) + remove_control_from_docks(tool_properties_dock) + activated = false + else: + active_node = null + +func on_selection_changed(): + update_activation() + +func _exit_tree(): + # Clean-up of the plugin goes here. + remove_autoload_singleton(AUTOLOAD_NAME) + + remove_custom_type("CyclopsBlocks") + remove_custom_type("CyclopsConvexBlock") + remove_custom_type("CyclopsConvexBlockBody") + +# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, sticky_toolbar) + + if activated: + remove_control_from_docks(material_dock) + remove_control_from_docks(uv_editor_dock) + remove_control_from_docks(tool_properties_dock) + remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar) + + material_dock.queue_free() + uv_editor_dock.queue_free() + tool_properties_dock.queue_free() + editor_toolbar.queue_free() + +func _handles(object:Object): + return object is CyclopsBlocks or object is CyclopsConvexBlock + +func _forward_3d_draw_over_viewport(viewport_control:Control): + #Draw on top of viweport here + pass + +func _forward_3d_gui_input(viewport_camera:Camera3D, event:InputEvent): + #print("plugin: " + event.as_text()) + + if tool: + var result:bool = tool._gui_input(viewport_camera, event) + tool._draw_tool(viewport_camera) + return EditorPlugin.AFTER_GUI_INPUT_STOP if result else EditorPlugin.AFTER_GUI_INPUT_PASS + + return EditorPlugin.AFTER_GUI_INPUT_PASS + +func _get_state()->Dictionary: + var state:Dictionary = {} + material_dock.save_state(state) + uv_editor_dock.save_state(state) + tool_properties_dock.save_state(state) + return state + +func _set_state(state): + material_dock.load_state(state) + uv_editor_dock.load_state(state) + tool_properties_dock.load_state(state) + +func switch_to_tool(_tool:CyclopsTool): + if tool: + tool._deactivate() + + tool = _tool + + if tool: + tool._activate(self) + var control:Control = tool._get_tool_properties_editor() + tool_properties_dock.set_editor(control) + +func get_global_scene()->CyclopsGlobalScene: + var scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + return scene diff --git a/addons/cyclops_level_builder/doc/Text b/addons/cyclops_level_builder/doc/Text new file mode 100644 index 0000000..4080d17 --- /dev/null +++ b/addons/cyclops_level_builder/doc/Text @@ -0,0 +1,54 @@ +import bpy +import mathutils + +def draw_plane(hessian): + # Extract the plane coefficients from the Hessian form + a, b, c, d = hessian + + # Calculate the normal vector of the plane + normal = mathutils.Vector((a, b, c)) + + # Calculate the point at the center of the plane + point = normal * d + + # Calculate a vector perpendicular to the normal + if abs(normal.z) < 1e-6: + tangent = mathutils.Vector((0, 0, 1)) + else: + tangent = mathutils.Vector((0, 1, -normal.y/normal.z)).normalized() + + binorm = tangent.cross(normal) + + # Create a new mesh object for the point, dot, and line + mesh = bpy.data.meshes.new(name="Plane Center and Normal") + obj = bpy.data.objects.new(name="Plane Object", object_data=mesh) + + # Create the vertices for the point, dot, and line + vertices = [ + point + tangent * 0.1, + point, + point + normal, + point + binorm * 0.1, + ] + + # Create the edges for the line + edges = [ + (0, 1), # Edge from point to start of line + (1, 2) , # Edge for the line + (1, 3) + ] + + # Create the mesh data for the point, dot, and line + mesh.from_pydata(vertices, edges, []) + + # Add the object to the scene + bpy.context.scene.collection.objects.link(obj) + +planes = [(-0.96225, 0.192449, 0.192451, -4.04145), (-0.404079, 0.888975, 0.21551, -3.85222), (-0.703526, -0.502519, -0.502519, -2.31159), (-0.123091, -0.86164, 0.492366, -2.33874), (-0.211079, -0.492518, 0.844317, -3.02547), (0.442326, 0.147442, 0.884652, -2.50651), (0.928279, -0.206284, 0.309426, -1.13456), (0.973329, -0.162221, 0.162222, -1.29777), (0.117041, 0.702247, -0.702247, -3.04307), (-9.6656e-08, 1.35319e-07, -1, -2)] +#planes = [(0, 0, -1, -12), (0, 1, 0, 9)] + +for p in planes: + draw_plane(p) + +#draw_plane((0, 1, 0, 11)) + \ No newline at end of file diff --git a/addons/cyclops_level_builder/doc/create_plane_objects.py b/addons/cyclops_level_builder/doc/create_plane_objects.py new file mode 100644 index 0000000..f28ce53 --- /dev/null +++ b/addons/cyclops_level_builder/doc/create_plane_objects.py @@ -0,0 +1,34 @@ +import bpy +import mathutils + +def create_plane_on_plane(p0): + # Extract the normal and distance from the Hessian form of the plane + normal = mathutils.Vector(p0[:3]) + distance = p0[3] + + # Calculate the center of the plane + center = normal * distance + + # Create a new plane object + bpy.ops.mesh.primitive_plane_add() + obj0 = bpy.context.active_object + + # Set the plane's origin to the center of the plane + obj0.location = center + + # Calculate the rotation needed to align the z-axis with the plane normal + z_axis = mathutils.Vector((0, 0, 1)) + angle = normal.angle(z_axis, 0) + axis = z_axis.cross(normal) + euler = mathutils.Matrix.Rotation(angle, 4, axis).to_euler() + obj0.rotation_euler = euler + + + return obj0 + + +planes = [(0.274721, 9.82474e-08, -0.961524, -8.10427), (-1, -3.57626e-07, -2.38418e-07, -2), (0.904534, 0.301512, 0.301512, -1.50755), (0, 1, 0, 3), (5.08628e-06, -1, -2.75509e-06, -7.00003), (0.727606, -0.485071, -0.485072, -8.48875), (0.465341, -0.426562, -0.775566, -9.03536), (-0.369799, -0.0924517, 0.924501, 1.75654), (3.19872e-07, -0.447214, 0.894427, -0.447216), (-0.957704, -0.239427, 0.159618, -2.15484)] +for p in planes: + create_plane_on_plane(p) + +#create_plane_on_plane((0.274721, 9.82474e-08, -0.961524, -8.10427)) diff --git a/addons/cyclops_level_builder/doc/draw_plane.py b/addons/cyclops_level_builder/doc/draw_plane.py new file mode 100644 index 0000000..55eb8fb --- /dev/null +++ b/addons/cyclops_level_builder/doc/draw_plane.py @@ -0,0 +1,35 @@ +import bpy +import mathutils + +def draw_plane(hessian): + # Extract the plane coefficients from the Hessian form + a, b, c, d = hessian + + # Calculate the normal vector of the plane + normal = mathutils.Vector((a, b, c)).normalized() + + # Calculate the point at the center of the plane + point = normal * d + + # Create a new mesh object for the point and line + mesh = bpy.data.meshes.new(name="Plane Center and Normal") + obj = bpy.data.objects.new(name="Plane Object", object_data=mesh) + + # Create the vertices for the point and line + vertices = [ + point, + point + normal + ] + + # Create the edges for the line + edges = [ + (0, 1) + ] + + # Create the mesh data for the point and line + mesh.from_pydata(vertices, edges, []) + + # Add the object to the scene + bpy.context.scene.collection.objects.link(obj) + +draw_plane((0, 1, 0, 11)) \ No newline at end of file diff --git a/addons/cyclops_level_builder/doc/draw_points_in_blender.py b/addons/cyclops_level_builder/doc/draw_points_in_blender.py new file mode 100644 index 0000000..16e5131 --- /dev/null +++ b/addons/cyclops_level_builder/doc/draw_points_in_blender.py @@ -0,0 +1,19 @@ +import bpy +import bmesh + +# Define the list of points for the polygon +points = [(0,0,0), (1,0,0), (1,1,0), (0,1,0)] + +# Create a new mesh and add a new object to the scene +mesh = bpy.data.meshes.new("Polygon") +obj = bpy.data.objects.new("Polygon", mesh) +bpy.context.collection.objects.link(obj) + +# Create a new bmesh and add vertices to it +bm = bmesh.new() +for point in points: + bm.verts.new(point) + +# Add the vertices to the mesh +bm.to_mesh(mesh) +bm.free() \ No newline at end of file diff --git a/addons/cyclops_level_builder/doc/make_polygons.py b/addons/cyclops_level_builder/doc/make_polygons.py new file mode 100644 index 0000000..6b6f1d9 --- /dev/null +++ b/addons/cyclops_level_builder/doc/make_polygons.py @@ -0,0 +1,36 @@ +import bpy +import bmesh + +# Define the list of faces, where each sublist represents a face +#faces = [ +# [(0,0,0), (1,0,0), (1,1,0), (0,1,0)], +# [(1,0,0), (2,0,0), (2,1,0), (1,1,0)] +#] +faces = [ + [(-2.999999, 6, -0.999997), (-2.999999, 9.999996, -0.999997), (-2.999999, 9.999996, 2.999999), (-2.999999, 6, 2.999999)], + [(-2.999999, 9.999996, -0.999997), (-2.999999, 6, -0.999997), (0.999997, 6, -0.999997), (0.999997, 9.999996, -0.999997)], + [(-2.999999, 6, -0.999997), (-2.999999, 6, 2.999999), (-0.999997, 6, 5), (2.999998, 6, 1.000004), (0.999997, 6, -0.999997)], + [(-2.999999, 9.999996, -0.999997), (0.999997, 9.999996, -0.999997), (1.999999, 9.999996, 0.000005), (-1.999997, 9.999996, 4), (-2.999999, 9.999996, 2.999999)], + [(-0.999997, 6, 5), (-2.999999, 6, 2.999999), (-2.999999, 9.999996, 2.999999), (-1.999997, 9.999996, 4), (-0.999997, 7.999996, 5)], + [(0.999997, 9.999996, -0.999997), (0.999997, 6, -0.999997), (2.999999, 6, 1.000004), (2.999999, 7.999996, 1.000004), (1.999998, 9.999996, 0.000004)], + [(-1.999997, 9.999996, 4), (1.999999, 9.999996, 0.000005), (2.999998, 7.999997, 1.000004), (-0.999997, 7.999997, 5)] + +] + + +# Create a new mesh and add a new object to the scene +mesh = bpy.data.meshes.new("Polygon") +obj = bpy.data.objects.new("Polygon", mesh) +bpy.context.collection.objects.link(obj) + +# Create a new bmesh and add vertices and faces to it +bm = bmesh.new() +for face_verts in faces: + # Add vertices for the face + verts = [bm.verts.new(v) for v in face_verts] + # Add a new face between the vertices + bm.faces.new(verts) + +# Update the mesh and free the bmesh +bm.to_mesh(mesh) +bm.free() diff --git a/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd new file mode 100644 index 0000000..513cb10 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_add_materials.gd @@ -0,0 +1,56 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMaterialDockAddMaterials +extends CyclopsCommand + +#Public +var res_path_list:Array[String] + +#Private +var old_res_path_list:Array[String] + + +func _init(): + command_name = "Add materials" + +func do_it(): +# print("Add Materials do_it") + var mat_dock:MaterialPaletteViewport = builder.material_dock + old_res_path_list = mat_dock.material_list.duplicate() + +# print("old mat list %s" % str(old_res_path_list)) + + var new_list:Array[String] = old_res_path_list.duplicate() + for mat in res_path_list: + if !new_list.has(mat): + new_list.append(mat) + +# print("new mat list %s" % str(new_list)) + + mat_dock.set_materials(new_list) + +func undo_it(): + var mat_dock:MaterialPaletteViewport = builder.material_dock + mat_dock.set_materials(old_res_path_list) diff --git a/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd new file mode 100644 index 0000000..771906c --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/commands/cmd_mat_dock_remove_materials.gd @@ -0,0 +1,52 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name CommandMaterialDockRemoveMaterials +extends CyclopsCommand + +#Public +var res_path_list:Array[String] + +#Private +var old_res_path_list:Array[String] + + +func _init(): + command_name = "Remove materials" + +func do_it(): +# print("Remove Materials do_it") + + var mat_dock:MaterialPaletteViewport = builder.material_dock + old_res_path_list = mat_dock.material_list.duplicate() + + var new_list:Array[String] = old_res_path_list.duplicate() + for mat in res_path_list: + var idx:int = new_list.find(mat) + new_list.remove_at(idx) + mat_dock.set_materials(new_list) + +func undo_it(): + var mat_dock:MaterialPaletteViewport = builder.material_dock + mat_dock.set_materials(old_res_path_list) diff --git a/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd new file mode 100644 index 0000000..f82a6d3 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd @@ -0,0 +1,191 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Control +class_name MaterialPaletteViewport + +@export var material_list:Array[String] = [] + +@export var thumbnail_group:ThumbnailGroup + +var builder:CyclopsLevelBuilder +#var undo_manager:UndoRedo + +var has_mouse_focus:bool = false + +# Called when the node enters the scene tree for the first time. +func _ready(): +# print("MaterialPaletteViewport") + #undo_manager = UndoRedo.new() + + update_thumbnails() + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +func _can_drop_data(at_position:Vector2, data:Variant): +# print("_can_drop_data %s" % data) + return typeof(data) == TYPE_DICTIONARY and data.has("type") and data["type"] == "files" + +func _unhandled_input(event): + if !has_mouse_focus: + return + + if event is InputEventKey: + #print("key event %s" % str(event)) + var e:InputEventKey = event +# if e.keycode == KEY_DELETE: + if e.keycode == KEY_X: + if e.pressed: +# print("mat pal X") + remove_selected_material() + + accept_event() + +func remove_selected_material(): + var cmd:CommandMaterialDockRemoveMaterials = CommandMaterialDockRemoveMaterials.new() + cmd.builder = builder + + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + if child.selected: + cmd.res_path_list.append(child.material_path) + + var undo_manager:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo_manager) + +func set_materials(res_path_list:Array[String]): + material_list = res_path_list +# print("set mat list %s" % str(material_list)) + update_thumbnails() + + +func save_state(state:Dictionary): + var substate:Dictionary = {} + state["material_palette"] = substate + + substate["materials"] = material_list.duplicate() + +func load_state(state:Dictionary): + if state == null || !state.has("material_palette"): + return + + var substate:Dictionary = state["material_palette"] + +# print("load_state()") + material_list = [] + if substate.has("materials"): + for mat_path in substate["materials"]: + if ResourceLoader.exists(mat_path): + material_list.append(mat_path) + + update_thumbnails() + +func _drop_data(at_position, data): + var files = data["files"] + #print("--drop") + var add_list:Array[String] + for f in files: +# print("Dropping %s" % f) + var res:Resource = load(f) + if res is Material: + if !material_list.has(f): + add_list.append(f) + + + var cmd:CommandMaterialDockAddMaterials = CommandMaterialDockAddMaterials.new() + cmd.builder = builder + + cmd.res_path_list = add_list + + var undo_manager:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo_manager) + + #print("drop data clear") + #material_list.clear() + +func update_thumbnails(): +# print("update_thumbnails()") + var cur_sel:String + + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + if child.selected: + cur_sel = child.material_path + break + + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + #print("removing %s" % child.get_class()) + child.group = null + $VBoxContainer/ScrollContainer/HFlowContainer.remove_child(child) + child.queue_free() + + for path in material_list: + var res:Resource = preload("res://addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn") + var thumbnail:MaterialThumbnail = res.instantiate() + thumbnail.builder = builder + thumbnail.material_path = path + thumbnail.group = thumbnail_group +# print("adding mat %s" % path) + + + $VBoxContainer/ScrollContainer/HFlowContainer.add_child(thumbnail) + thumbnail.owner = self + + if cur_sel: + for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children(): + if child.material_path == cur_sel: + child.selected = true + break + + +func _on_visibility_changed(): + #Control freezes for some reason when hidden and then shown, so just regenereate it + if visible: + update_thumbnails() + + + +func _on_remove_all_materials_pressed(): + var cmd:CommandMaterialDockRemoveMaterials = CommandMaterialDockRemoveMaterials.new() + cmd.builder = builder + + cmd.res_path_list = material_list.duplicate() + + var undo_manager:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo_manager) + + + +func _on_remove_sel_pressed(): + remove_selected_material() + + +func _on_h_flow_container_mouse_entered(): + has_mouse_focus = true +# print("_on_h_flow_container_mouse_entered()") + + +func _on_h_flow_container_mouse_exited(): + has_mouse_focus = false +# print("_on_h_flow_container_mouse_exited()") diff --git a/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn new file mode 100644 index 0000000..c5f0584 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=4 format=3 uid="uid://o1efx0qxc4n3"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd" id="1_xyxg3"] +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd" id="2_sg6yo"] + +[sub_resource type="Resource" id="Resource_ljbow"] +script = ExtResource("2_sg6yo") + +[node name="Materials" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_xyxg3") +thumbnail_group = SubResource("Resource_ljbow") +metadata/_edit_lock_ = true + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +metadata/_edit_lock_ = true + +[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/PanelContainer"] +layout_mode = 2 + +[node name="remove_all_materials" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "Remove All" + +[node name="remove_sel" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +tooltip_text = "Press X to removeselected material." +text = "Remove Selected" + +[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +metadata/_edit_lock_ = true + +[node name="HFlowContainer" type="HFlowContainer" parent="VBoxContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"] +[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/remove_all_materials" to="." method="_on_remove_all_materials_pressed"] +[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/remove_sel" to="." method="_on_remove_sel_pressed"] +[connection signal="mouse_entered" from="VBoxContainer/ScrollContainer/HFlowContainer" to="." method="_on_h_flow_container_mouse_entered"] +[connection signal="mouse_exited" from="VBoxContainer/ScrollContainer/HFlowContainer" to="." method="_on_h_flow_container_mouse_exited"] diff --git a/addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd new file mode 100644 index 0000000..df01ad9 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd @@ -0,0 +1,52 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + + +@tool +extends SubViewport +class_name MaterialShapshot + +@export var target_material:Material: + get: + return target_material + set(value): + target_material = value + $Node3D/MeshInstance3D.material_override = target_material + +func take_snapshot()->ImageTexture: + #print ("pre-grabbing image %s" % target_material.resource_path) + await RenderingServer.frame_post_draw + #print ("grabbing image %s" % target_material.resource_path) + var image:Image = get_viewport().get_texture().get_image() + var tex:ImageTexture = ImageTexture.create_from_image(image) + return tex + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn new file mode 100644 index 0000000..fc4d0cd --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=5 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd" id="1_c0jsn"] +[ext_resource type="Material" uid="uid://rdhrhgrb78ls" path="res://addons/cyclops_level_builder/materials/grid.tres" id="2_q7d7x"] + +[sub_resource type="QuadMesh" id="QuadMesh_o8jeg"] + +[sub_resource type="Environment" id="Environment_p06d0"] + +[node name="SubViewport" type="SubViewport"] +own_world_3d = true +size = Vector2i(64, 64) +render_target_update_mode = 4 +script = ExtResource("1_c0jsn") + +[node name="Node3D" type="Node3D" parent="."] + +[node name="Camera3D" type="Camera3D" parent="Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1) +projection = 1 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D"] +mesh = SubResource("QuadMesh_o8jeg") +surface_material_override/0 = ExtResource("2_q7d7x") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Node3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="Node3D"] +environment = SubResource("Environment_p06d0") diff --git a/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd new file mode 100644 index 0000000..688dd89 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd @@ -0,0 +1,166 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Control +class_name MaterialThumbnail + +@export var selected:bool = false + +@export_file("*.tres") var material_path:String: + get: + return material_path + set(value): + if material_path == value: + return + + material_path = value + + if ResourceLoader.exists(material_path): + var res:Resource = load(material_path) + #print("loaded res %s" % res) + + if res is Material: + tracked_material = res + else: + tracked_material = null + else: + tracked_material = null + + material_thumbnail_dirty = true + +@export var group:ThumbnailGroup: + get: + return group + set(value): + if group == value: + return + + if group != null: + group.remove_thumbnail(self) + + group = value + + if group != null: + group.add_thumbnail(self) + + +@export var theme_normal:Theme +@export var theme_selected:Theme + +var builder:CyclopsLevelBuilder + +var tracked_material:Material +var material_thumbnail_dirty:bool = true + +var snapper:MaterialShapshot + +# Called when the node enters the scene tree for the first time. +func _ready(): + snapper = preload("res://addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn").instantiate() + add_child(snapper) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if selected: + theme = theme_selected + else: + theme = theme_normal + + if material_thumbnail_dirty: + material_thumbnail_dirty = false + + snapper.target_material = tracked_material + + var tex:ImageTexture = await snapper.take_snapshot() + $VBoxContainer/TextureRect.texture = tex + + if tracked_material: + var name:String = tracked_material.resource_name + if name.is_empty(): + name = material_path.get_file() + var idx:int = name.rfind(".") + if idx != -1: + name = name.substr(0, idx) + $VBoxContainer/MaterialName.text = name + else: + $VBoxContainer/MaterialName.text = "" + + +func _gui_input(event:InputEvent): + if event is InputEventMouseButton: + var e:InputEventMouseButton = event + if e.pressed: + if e.double_click: + apply_material_to_selected() + else: + + if group: + group.select_thumbnail(self) + else: + selected = true + + builder.tool_material_path = material_path + + get_viewport().set_input_as_handled() + + +func apply_material_to_selected(): + var cmd:CommandSetMaterial = CommandSetMaterial.new() + cmd.builder = builder + cmd.material_path = material_path + + var is_obj_mode:bool = builder.mode == CyclopsLevelBuilder.Mode.OBJECT + + var root_blocks:CyclopsBlocks = builder.active_node + for child in root_blocks.get_children(): +# print("child block %s %s" % [child.name, child.get_class()]) +# if child.has_method("append_mesh_wire"): + if child is CyclopsConvexBlock: + #if !(child is MeshInstance3D): +# print("setting child block %s" % child.name) + if child.selected: + if is_obj_mode: + cmd.add_target(child.get_path(), child.control_mesh.get_face_indices()) + else: + var face_indices:PackedInt32Array = child.control_mesh.get_face_indices(true) + if !face_indices.is_empty(): + cmd.add_target(child.get_path(), face_indices) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + +func _on_focus_entered(): + pass # Replace with function body. + + +func _on_focus_exited(): + pass # Replace with function body. + + +func _on_tree_exiting(): + if group != null: + group.remove_thumbnail(self) diff --git a/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn new file mode 100644 index 0000000..1c67f92 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_thumbnail.gd" id="1_bk6mq"] +[ext_resource type="Theme" uid="uid://c0gpl22e2g6ay" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres" id="1_pvt6l"] +[ext_resource type="Theme" uid="uid://bx26luxdhj3jq" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres" id="3_a3d05"] + +[sub_resource type="Image" id="Image_s62qo"] +data = { +"data": PackedByteArray(173, 164, 110, 255, 173, 164, 110, 255, 164, 156, 103, 255, 173, 164, 110, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 143, 140, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 156, 152, 98, 255, 147, 146, 98, 255, 114, 108, 76, 255, 98, 91, 66, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 106, 107, 73, 255, 87, 91, 66, 255, 128, 123, 80, 255, 147, 140, 87, 255, 159, 158, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 115, 77, 255, 110, 103, 77, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 152, 99, 255, 173, 164, 110, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 108, 76, 255, 98, 91, 66, 255, 114, 108, 76, 255, 114, 108, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 117, 113, 76, 255, 98, 91, 66, 255, 117, 113, 76, 255, 139, 135, 87, 255, 159, 158, 98, 255, 152, 146, 98, 255, 152, 146, 98, 255, 130, 126, 87, 255, 130, 126, 87, 255, 106, 107, 73, 255, 87, 91, 66, 255, 128, 123, 80, 255, 147, 140, 87, 255, 159, 158, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 114, 77, 255, 110, 103, 77, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 159, 152, 99, 255, 168, 159, 106, 255, 173, 164, 110, 255, 173, 164, 99, 255, 168, 162, 99, 255, 168, 162, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 108, 76, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 87, 91, 66, 255, 87, 91, 66, 255, 147, 140, 87, 255, 147, 140, 87, 255, 159, 158, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 114, 77, 255, 110, 103, 77, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 159, 152, 99, 255, 173, 164, 110, 255, 168, 159, 106, 255, 168, 162, 99, 255, 168, 162, 99, 255, 168, 162, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 140, 140, 87, 255, 98, 103, 66, 255, 110, 103, 77, 255, 143, 139, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 108, 75, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 117, 116, 75, 255, 117, 116, 75, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 98, 91, 66, 255, 117, 113, 75, 255, 139, 135, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 159, 158, 98, 255, 152, 145, 98, 255, 152, 145, 98, 255, 152, 145, 98, 255, 173, 164, 110, 255, 128, 123, 79, 255, 87, 91, 66, 255, 147, 139, 87, 255, 147, 140, 87, 255, 159, 158, 98, 255, 173, 164, 110, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 164, 110, 255, 159, 164, 110, 255, 159, 164, 110, 255, 123, 114, 77, 255, 126, 120, 83, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 87, 91, 66, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 163, 162, 102, 255, 156, 153, 94, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 185, 176, 123, 255, 176, 170, 114, 255, 168, 163, 107, 255, 168, 163, 107, 255, 163, 159, 102, 255, 173, 163, 110, 255, 159, 158, 98, 255, 168, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 152, 150, 94, 255, 152, 150, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 152, 145, 91, 255, 155, 152, 94, 255, 105, 104, 76, 255, 87, 86, 66, 255, 128, 126, 87, 255, 147, 146, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 122, 114, 80, 255, 140, 135, 87, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 149, 141, 94, 255, 149, 141, 94, 255, 149, 141, 94, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 87, 91, 66, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 173, 163, 98, 255, 163, 162, 102, 255, 156, 153, 94, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 163, 107, 255, 168, 163, 107, 255, 168, 163, 107, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 98, 97, 66, 255, 159, 158, 98, 255, 151, 150, 94, 255, 135, 133, 87, 255, 142, 141, 91, 255, 159, 158, 98, 255, 155, 152, 94, 255, 152, 145, 91, 255, 152, 145, 91, 255, 105, 104, 76, 255, 87, 86, 66, 255, 128, 126, 87, 255, 147, 146, 98, 255, 173, 170, 110, 255, 149, 146, 94, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 122, 114, 80, 255, 117, 113, 76, 255, 140, 135, 87, 255, 140, 135, 88, 255, 159, 158, 99, 255, 99, 97, 67, 255, 99, 97, 67, 255, 122, 119, 80, 255, 122, 119, 80, 255, 149, 141, 94, 255, 122, 119, 80, 255, 122, 119, 80, 255, 122, 119, 80, 255, 117, 113, 76, 255, 117, 113, 76, 255, 117, 113, 76, 255, 98, 91, 66, 255, 87, 91, 66, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 168, 162, 98, 255, 163, 162, 102, 255, 147, 145, 87, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 163, 107, 255, 176, 170, 114, 255, 168, 163, 107, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 98, 97, 66, 255, 151, 150, 94, 255, 135, 133, 87, 255, 142, 141, 91, 255, 151, 150, 94, 255, 159, 158, 98, 255, 155, 152, 94, 255, 152, 145, 91, 255, 152, 145, 91, 255, 105, 104, 75, 255, 87, 86, 66, 255, 128, 126, 87, 255, 147, 145, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 149, 140, 94, 255, 149, 140, 94, 255, 122, 114, 80, 255, 98, 91, 66, 255, 99, 92, 66, 255, 117, 113, 76, 255, 117, 113, 76, 255, 99, 92, 67, 255, 99, 97, 67, 255, 99, 97, 67, 255, 99, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 76, 255, 98, 91, 66, 255, 87, 91, 66, 255, 110, 113, 76, 255, 135, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 170, 110, 255, 156, 153, 94, 255, 147, 145, 87, 255, 147, 145, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 159, 102, 255, 163, 159, 102, 255, 163, 159, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 142, 141, 91, 255, 135, 133, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 155, 151, 94, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 127, 126, 87, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 99, 92, 66, 255, 99, 92, 67, 255, 99, 92, 67, 255, 147, 140, 87, 255, 147, 140, 87, 255, 147, 140, 87, 255, 152, 146, 91, 255, 155, 152, 94, 255, 155, 152, 94, 255, 152, 146, 91, 255, 147, 139, 87, 255, 147, 146, 91, 255, 147, 146, 91, 255, 135, 133, 83, 255, 123, 122, 77, 255, 87, 91, 66, 255, 105, 108, 75, 255, 127, 127, 87, 255, 147, 145, 98, 255, 147, 142, 91, 255, 147, 142, 91, 255, 147, 142, 91, 255, 147, 142, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 117, 113, 75, 255, 147, 145, 98, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 155, 147, 94, 255, 151, 144, 91, 255, 130, 124, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 114, 111, 76, 255, 123, 122, 77, 255, 123, 122, 77, 255, 123, 122, 77, 255, 123, 122, 77, 255, 135, 128, 87, 255, 143, 138, 91, 255, 152, 147, 94, 255, 152, 147, 94, 255, 135, 140, 87, 255, 135, 140, 87, 255, 135, 140, 87, 255, 135, 140, 87, 255, 155, 152, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 155, 152, 94, 255, 159, 158, 98, 255, 155, 152, 94, 255, 152, 146, 91, 255, 135, 133, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 83, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 105, 108, 75, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 98, 97, 66, 255, 114, 111, 73, 255, 114, 111, 73, 255, 114, 111, 73, 255, 98, 91, 66, 255, 117, 112, 75, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 112, 75, 255, 98, 91, 66, 255, 147, 144, 94, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 144, 94, 255, 159, 151, 98, 255, 147, 139, 87, 255, 155, 147, 94, 255, 151, 144, 91, 255, 147, 139, 98, 255, 98, 97, 66, 255, 98, 97, 66, 255, 130, 124, 87, 255, 156, 150, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 152, 152, 94, 255, 152, 152, 94, 255, 152, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 155, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 155, 152, 94, 255, 155, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 147, 145, 91, 255, 135, 133, 83, 255, 87, 91, 66, 255, 127, 127, 87, 255, 127, 127, 87, 255, 127, 127, 87, 255, 135, 129, 83, 255, 135, 129, 83, 255, 123, 114, 77, 255, 123, 114, 77, 255, 98, 97, 66, 255, 114, 111, 73, 255, 114, 111, 73, 255, 114, 111, 73, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 147, 139, 87, 255, 147, 141, 91, 255, 147, 144, 94, 255, 147, 144, 94, 255, 159, 151, 98, 255, 151, 144, 91, 255, 155, 147, 94, 255, 159, 151, 98, 255, 147, 139, 98, 255, 114, 111, 75, 255, 98, 97, 66, 255, 130, 124, 87, 255, 156, 150, 98, 255, 156, 150, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 83, 255, 87, 91, 66, 255, 127, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 147, 142, 91, 255, 98, 97, 66, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 139, 135, 87, 255, 117, 112, 75, 255, 117, 112, 75, 255, 117, 112, 75, 255, 117, 115, 75, 255, 117, 115, 75, 255, 117, 115, 75, 255, 139, 138, 87, 255, 139, 135, 87, 255, 159, 157, 98, 255, 117, 112, 75, 255, 98, 91, 66, 255, 117, 112, 75, 255, 117, 112, 75, 255, 98, 91, 66, 255, 98, 91, 66, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 141, 91, 255, 147, 144, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 139, 87, 255, 159, 151, 98, 255, 147, 139, 98, 255, 114, 111, 75, 255, 98, 97, 66, 255, 147, 139, 98, 255, 156, 150, 98, 255, 173, 163, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 152, 152, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 158, 103, 255, 168, 158, 103, 255, 168, 158, 103, 255, 168, 158, 103, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 164, 159, 98, 255, 160, 156, 103, 255, 173, 163, 110, 255, 160, 156, 102, 255, 135, 139, 87, 255, 98, 97, 66, 255, 117, 116, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 157, 98, 255, 163, 157, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 114, 112, 75, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 66, 255, 154, 151, 94, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 151, 150, 94, 255, 151, 150, 94, 255, 135, 133, 87, 255, 151, 150, 94, 255, 159, 151, 98, 255, 110, 108, 77, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 164, 156, 103, 255, 164, 159, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 168, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 168, 158, 103, 255, 168, 158, 103, 255, 159, 152, 98, 255, 168, 158, 103, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 160, 156, 102, 255, 135, 139, 87, 255, 98, 97, 66, 255, 117, 115, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 159, 157, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 147, 145, 98, 255, 151, 150, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 66, 255, 154, 151, 94, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 142, 141, 91, 255, 159, 158, 98, 255, 151, 150, 94, 255, 151, 150, 94, 255, 159, 151, 98, 255, 110, 108, 77, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 173, 163, 110, 255, 168, 162, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 158, 98, 255, 168, 158, 103, 255, 159, 152, 98, 255, 168, 158, 103, 255, 168, 158, 103, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 160, 156, 102, 255, 135, 139, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 159, 157, 98, 255, 135, 133, 87, 255, 98, 96, 66, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 156, 151, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 151, 150, 94, 255, 159, 151, 98, 255, 110, 108, 77, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 159, 152, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 164, 159, 103, 255, 176, 164, 106, 255, 185, 170, 110, 255, 168, 158, 103, 255, 168, 158, 103, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 160, 156, 102, 255, 160, 156, 102, 255, 147, 147, 94, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 157, 98, 255, 135, 133, 87, 255, 98, 96, 66, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 173, 163, 98, 255, 156, 151, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 159, 157, 98, 255, 151, 145, 91, 255, 147, 139, 87, 255, 147, 139, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 159, 151, 98, 255, 110, 108, 76, 255, 110, 108, 77, 255, 142, 136, 91, 255, 168, 159, 105, 255, 168, 159, 105, 255, 168, 159, 105, 255, 163, 156, 102, 255, 159, 158, 98, 255, 164, 159, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 168, 162, 105, 255, 173, 164, 110, 255, 164, 159, 103, 255, 164, 159, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 110, 75, 255, 135, 132, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 135, 129, 87, 255, 98, 102, 65, 255, 139, 139, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 156, 98, 255, 159, 151, 98, 255, 168, 159, 98, 255, 168, 159, 98, 255, 163, 157, 98, 255, 163, 157, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 109, 102, 76, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 139, 138, 87, 255, 117, 115, 75, 255, 117, 115, 75, 255, 139, 138, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 129, 87, 255, 130, 129, 87, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 135, 87, 255, 110, 113, 76, 255, 110, 107, 76, 255, 135, 129, 87, 255, 135, 129, 87, 255, 135, 129, 87, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 110, 75, 255, 110, 110, 75, 255, 135, 132, 87, 255, 135, 132, 87, 255, 159, 151, 98, 255, 135, 129, 87, 255, 135, 129, 87, 255, 87, 85, 65, 255, 98, 102, 65, 255, 117, 120, 75, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 159, 98, 255, 163, 156, 98, 255, 173, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 163, 157, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 142, 139, 91, 255, 142, 139, 91, 255, 126, 120, 83, 255, 109, 102, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 76, 255, 122, 119, 79, 255, 122, 119, 79, 255, 122, 119, 79, 255, 122, 119, 80, 255, 110, 113, 76, 255, 110, 113, 76, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 65, 255, 87, 85, 65, 255, 98, 102, 65, 255, 117, 120, 75, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 156, 98, 255, 163, 156, 98, 255, 168, 159, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 108, 76, 255, 109, 108, 76, 255, 126, 124, 83, 255, 142, 141, 91, 255, 139, 138, 87, 255, 139, 138, 87, 255, 117, 115, 75, 255, 117, 115, 75, 255, 114, 113, 75, 255, 114, 113, 75, 255, 114, 113, 75, 255, 98, 97, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 135, 135, 87, 255, 135, 135, 87, 255, 110, 113, 76, 255, 87, 91, 66, 255, 87, 86, 66, 255, 135, 129, 87, 255, 135, 129, 87, 255, 110, 107, 75, 255, 139, 135, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 139, 135, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 109, 106, 75, 255, 98, 102, 65, 255, 139, 139, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 163, 156, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 98, 91, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 113, 75, 255, 98, 91, 66, 255, 117, 113, 75, 255, 139, 135, 87, 255, 139, 135, 87, 255, 149, 141, 94, 255, 149, 141, 94, 255, 149, 141, 94, 255, 149, 141, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 152, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 139, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 172, 163, 111, 255, 172, 163, 111, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 168, 159, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 153, 102, 255, 147, 145, 98, 255, 147, 145, 98, 255, 156, 153, 102, 255, 173, 163, 109, 255, 168, 159, 105, 255, 163, 156, 102, 255, 168, 159, 105, 255, 159, 157, 98, 255, 154, 153, 98, 255, 154, 153, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 160, 153, 102, 255, 173, 163, 110, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 152, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 139, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 172, 163, 109, 255, 172, 163, 111, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 163, 156, 98, 255, 159, 151, 98, 255, 168, 159, 98, 255, 172, 163, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 163, 162, 105, 255, 163, 162, 105, 255, 173, 163, 109, 255, 168, 159, 105, 255, 163, 156, 102, 255, 159, 151, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 173, 163, 110, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 164, 158, 102, 255, 164, 158, 103, 255, 164, 158, 103, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 135, 133, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 185, 176, 123, 255, 147, 139, 86, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 168, 159, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 156, 153, 102, 255, 163, 162, 105, 255, 172, 169, 109, 255, 172, 169, 109, 255, 173, 163, 109, 255, 168, 159, 105, 255, 163, 156, 102, 255, 168, 159, 105, 255, 159, 157, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 173, 163, 110, 255, 147, 144, 94, 255, 173, 163, 110, 255, 147, 144, 94, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 158, 102, 255, 164, 158, 103, 255, 173, 170, 110, 255, 164, 158, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 123, 114, 76, 255, 98, 102, 76, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 168, 162, 105, 255, 172, 163, 111, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 117, 82, 255, 109, 102, 76, 255, 168, 159, 98, 255, 172, 163, 98, 255, 168, 159, 98, 255, 163, 156, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 163, 162, 105, 255, 172, 163, 109, 255, 173, 163, 109, 255, 168, 159, 105, 255, 168, 159, 105, 255, 159, 157, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 157, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 173, 163, 110, 255, 147, 144, 94, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 158, 102, 255, 164, 158, 103, 255, 164, 158, 103, 255, 164, 158, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 142, 136, 91, 255, 159, 151, 98, 255, 142, 136, 91, 255, 151, 150, 98, 255, 154, 153, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 120, 82, 255, 98, 96, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 159, 151, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 126, 118, 86, 255, 109, 102, 76, 255, 156, 153, 102, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 98, 255, 159, 157, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 157, 105, 255, 156, 151, 102, 255, 156, 151, 102, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 142, 136, 91, 255, 159, 151, 98, 255, 126, 123, 83, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 120, 82, 255, 98, 96, 65, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 159, 151, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 126, 118, 86, 255, 109, 102, 76, 255, 147, 145, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 154, 151, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 147, 139, 87, 255, 147, 145, 98, 255, 156, 151, 102, 255, 156, 151, 102, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 142, 136, 91, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 121, 120, 82, 255, 98, 96, 65, 255, 139, 138, 86, 255, 159, 157, 98, 255, 159, 157, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 159, 151, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 126, 118, 86, 255, 109, 102, 76, 255, 156, 153, 102, 255, 156, 153, 102, 255, 163, 162, 105, 255, 172, 169, 109, 255, 159, 157, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 159, 157, 98, 255, 172, 163, 109, 255, 172, 163, 109, 255, 163, 156, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 163, 157, 105, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 165, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 110, 108, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 158, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 109, 108, 76, 255, 98, 96, 65, 255, 117, 115, 75, 255, 139, 138, 86, 255, 159, 157, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 163, 157, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 172, 163, 98, 255, 163, 156, 98, 255, 159, 151, 109, 255, 159, 151, 109, 255, 109, 102, 76, 255, 109, 102, 76, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 156, 153, 102, 255, 154, 151, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 154, 151, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 157, 105, 255, 163, 157, 105, 255, 163, 157, 105, 255, 163, 157, 105, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 170, 110, 255, 173, 164, 98, 255, 173, 168, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 123, 114, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 158, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 114, 108, 75, 255, 130, 127, 86, 255, 130, 127, 86, 255, 139, 135, 86, 255, 139, 135, 86, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 112, 75, 255, 114, 112, 75, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 139, 138, 87, 255, 117, 115, 75, 255, 117, 115, 75, 255, 117, 115, 75, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 123, 114, 77, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 144, 91, 255, 147, 139, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 139, 138, 87, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 114, 108, 75, 255, 114, 108, 75, 255, 98, 102, 65, 255, 98, 102, 65, 255, 117, 118, 75, 255, 98, 102, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 130, 128, 86, 255, 114, 112, 75, 255, 98, 96, 65, 255, 139, 131, 86, 255, 139, 131, 86, 255, 139, 131, 86, 255, 139, 131, 86, 255, 139, 138, 86, 255, 139, 138, 86, 255, 139, 138, 86, 255, 117, 115, 75, 255, 126, 120, 82, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 98, 96, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 135, 126, 83, 255, 159, 151, 98, 255, 147, 139, 91, 255, 159, 151, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 151, 150, 98, 255, 151, 144, 91, 255, 147, 139, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 114, 108, 75, 255, 114, 108, 75, 255, 98, 102, 65, 255, 98, 102, 65, 255, 98, 102, 65, 255, 98, 102, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 139, 138, 86, 255, 142, 139, 91, 255, 142, 139, 91, 255, 126, 120, 82, 255, 126, 120, 83, 255, 126, 120, 83, 255, 142, 139, 91, 255, 142, 139, 91, 255, 142, 139, 91, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 159, 158, 98, 255, 164, 159, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 135, 126, 83, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 150, 98, 255, 154, 153, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 98, 91, 65, 255, 130, 127, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 139, 135, 86, 255, 139, 135, 86, 255, 117, 118, 75, 255, 117, 118, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 139, 133, 86, 255, 139, 133, 86, 255, 130, 128, 86, 255, 130, 128, 86, 255, 130, 128, 86, 255, 114, 112, 75, 255, 117, 109, 75, 255, 117, 109, 75, 255, 117, 109, 75, 255, 98, 91, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 164, 159, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 98, 96, 65, 255, 98, 96, 65, 255, 130, 129, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 139, 138, 91, 255, 139, 138, 91, 255, 142, 141, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 139, 138, 91, 255, 139, 138, 91, 255, 142, 141, 93, 255, 134, 133, 86, 255, 147, 139, 98, 255, 134, 128, 91, 255, 109, 108, 76, 255, 135, 128, 91, 255, 147, 145, 98, 255, 151, 150, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 153, 98, 255, 159, 156, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 139, 133, 87, 255, 139, 133, 87, 255, 139, 133, 87, 255, 139, 133, 87, 255, 159, 151, 98, 255, 117, 114, 75, 255, 98, 96, 65, 255, 130, 129, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 134, 133, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 134, 133, 86, 255, 142, 141, 93, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 139, 98, 255, 147, 139, 98, 255, 109, 108, 76, 255, 135, 128, 91, 255, 147, 145, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 135, 133, 87, 255, 159, 158, 98, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 135, 87, 255, 87, 91, 66, 255, 98, 91, 66, 255, 114, 108, 75, 255, 98, 91, 66, 255, 114, 108, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 98, 97, 66, 255, 98, 96, 66, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 98, 96, 65, 255, 130, 129, 86, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 145, 98, 255, 139, 138, 91, 255, 147, 145, 98, 255, 139, 138, 91, 255, 134, 133, 86, 255, 142, 141, 93, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 139, 98, 255, 135, 128, 91, 255, 109, 108, 76, 255, 135, 128, 91, 255, 151, 150, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 151, 150, 98, 255, 159, 151, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 142, 141, 91, 255, 142, 141, 91, 255, 142, 141, 91, 255, 159, 158, 98, 255, 110, 113, 76, 255, 110, 113, 76, 255, 110, 113, 75, 255, 87, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 117, 114, 75, 255, 117, 114, 75, 255, 139, 133, 87, 255, 139, 133, 87, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 98, 96, 65, 255, 98, 96, 65, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 93, 255, 147, 145, 98, 255, 139, 138, 91, 255, 147, 145, 98, 255, 134, 133, 86, 255, 134, 133, 86, 255, 142, 141, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 98, 255, 135, 128, 91, 255, 109, 108, 76, 255, 121, 118, 82, 255, 147, 145, 98, 255, 154, 153, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 135, 133, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 117, 116, 75, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 110, 108, 77, 255, 117, 113, 76, 255, 117, 113, 76, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 102, 66, 255, 139, 139, 87, 255, 139, 139, 87, 255, 159, 158, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 156, 151, 98, 255, 163, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 156, 150, 98, 255, 123, 121, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 144, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 86, 255, 147, 139, 86, 255, 154, 147, 93, 255, 154, 147, 93, 255, 151, 144, 91, 255, 147, 145, 98, 255, 130, 128, 86, 255, 114, 112, 75, 255, 114, 112, 75, 255, 142, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 139, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 87, 85, 66, 255, 110, 107, 75, 255, 87, 86, 66, 255, 135, 129, 87, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 123, 114, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 102, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 163, 157, 98, 255, 173, 163, 98, 255, 163, 157, 102, 255, 163, 157, 102, 255, 163, 157, 102, 255, 163, 157, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 156, 150, 98, 255, 139, 135, 87, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 144, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 144, 91, 255, 154, 147, 93, 255, 159, 151, 98, 255, 154, 147, 93, 255, 147, 145, 98, 255, 130, 128, 86, 255, 114, 112, 75, 255, 130, 128, 86, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 110, 110, 75, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 102, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 147, 145, 98, 255, 173, 163, 98, 255, 168, 163, 105, 255, 163, 157, 102, 255, 163, 157, 102, 255, 163, 157, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 156, 150, 98, 255, 139, 135, 87, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 144, 91, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 112, 75, 255, 98, 96, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 135, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 159, 157, 98, 255, 135, 133, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 110, 110, 75, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 102, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 163, 158, 98, 255, 173, 163, 98, 255, 168, 163, 105, 255, 168, 163, 105, 255, 173, 169, 109, 255, 163, 157, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 156, 150, 98, 255, 123, 121, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 147, 93, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 114, 112, 75, 255, 98, 96, 65, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 109, 102, 76, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 85, 65, 255, 87, 85, 65, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 135, 129, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 126, 120, 83, 255, 123, 114, 77, 255, 173, 163, 110, 255, 173, 163, 110, 255, 156, 147, 98, 255, 173, 163, 98, 255, 159, 151, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 173, 163, 109, 255, 163, 159, 102, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 109, 114, 76, 255, 98, 91, 65, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 103, 75, 255, 86, 85, 65, 255, 109, 114, 76, 255, 142, 142, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 87, 91, 65, 255, 87, 91, 65, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 135, 133, 87, 255, 173, 163, 98, 255, 173, 164, 98, 255, 156, 156, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 126, 120, 83, 255, 123, 114, 77, 255, 156, 147, 98, 255, 173, 163, 110, 255, 156, 147, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 173, 163, 109, 255, 159, 157, 98, 255, 173, 163, 109, 255, 173, 163, 109, 255, 151, 147, 98, 255, 109, 114, 76, 255, 98, 91, 65, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 151, 147, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 103, 75, 255, 87, 85, 65, 255, 126, 129, 82, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 87, 91, 65, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 86, 66, 255, 110, 108, 75, 255, 87, 86, 66, 255, 135, 133, 87, 255, 173, 163, 98, 255, 164, 159, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 102, 77, 255, 123, 114, 77, 255, 156, 147, 98, 255, 173, 163, 110, 255, 156, 147, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 105, 255, 168, 162, 105, 255, 163, 159, 102, 255, 168, 162, 105, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 109, 114, 76, 255, 98, 91, 65, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 151, 147, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 126, 87, 255, 87, 85, 65, 255, 142, 142, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 142, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 98, 96, 65, 255, 87, 91, 65, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 135, 132, 87, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 86, 66, 255, 135, 133, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 110, 103, 77, 255, 123, 114, 77, 255, 156, 147, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 173, 163, 98, 255, 168, 159, 98, 255, 168, 159, 98, 255, 173, 163, 98, 255, 163, 159, 102, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 173, 163, 109, 255, 173, 163, 109, 255, 173, 163, 109, 255, 109, 114, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 159, 151, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 126, 87, 255, 87, 85, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 139, 138, 87, 255, 98, 96, 65, 255, 87, 91, 66, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 86, 66, 255, 110, 108, 75, 255, 173, 164, 98, 255, 147, 152, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 168, 162, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 150, 102, 255, 142, 141, 94, 255, 159, 157, 109, 255, 135, 133, 87, 255, 151, 144, 91, 255, 151, 144, 91, 255, 154, 147, 93, 255, 154, 147, 93, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 127, 87, 255, 87, 91, 65, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 147, 145, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 142, 141, 91, 255, 109, 108, 76, 255, 98, 91, 66, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 168, 162, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 168, 162, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 147, 142, 91, 255, 159, 158, 98, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 163, 156, 102, 255, 168, 162, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 150, 102, 255, 151, 150, 102, 255, 159, 157, 109, 255, 135, 133, 87, 255, 154, 147, 93, 255, 154, 147, 93, 255, 154, 147, 93, 255, 154, 147, 93, 255, 151, 147, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 127, 127, 87, 255, 87, 91, 65, 255, 147, 145, 91, 255, 159, 157, 98, 255, 159, 157, 98, 255, 147, 145, 91, 255, 159, 157, 98, 255, 142, 141, 91, 255, 126, 124, 83, 255, 109, 108, 76, 255, 98, 91, 66, 255, 159, 157, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 168, 162, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 163, 156, 102, 255, 159, 151, 98, 255, 163, 156, 102, 255, 168, 159, 105, 255, 173, 163, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 150, 102, 255, 151, 150, 102, 255, 151, 150, 102, 255, 151, 150, 102, 255, 154, 147, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 139, 87, 255, 154, 150, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 147, 145, 91, 255, 147, 145, 91, 255, 147, 145, 91, 255, 147, 145, 91, 255, 159, 157, 98, 255, 142, 141, 91, 255, 126, 124, 83, 255, 109, 108, 76, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 75, 255, 98, 91, 66, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 162, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 123, 114, 77, 255, 147, 142, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 151, 98, 255, 173, 163, 110, 255, 163, 156, 102, 255, 163, 156, 102, 255, 173, 163, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 109, 108, 76, 255, 98, 91, 65, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 141, 94, 255, 142, 141, 94, 255, 151, 150, 102, 255, 142, 141, 94, 255, 151, 144, 91, 255, 154, 147, 94, 255, 154, 147, 94, 255, 147, 139, 87, 255, 147, 145, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 154, 150, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 123, 121, 76, 255, 123, 121, 76, 255, 123, 121, 76, 255, 123, 121, 76, 255, 126, 124, 83, 255, 126, 124, 83, 255, 109, 108, 76, 255, 110, 108, 76, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 168, 162, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 76, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 157, 98, 255, 159, 157, 98, 255, 123, 121, 76, 255, 98, 96, 66, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 142, 139, 94, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 65, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 163, 159, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 76, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 157, 98, 255, 123, 121, 76, 255, 98, 96, 66, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 159, 151, 98, 255, 151, 145, 94, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 142, 139, 94, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 65, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 117, 110, 75, 255, 139, 132, 87, 255, 139, 132, 87, 255, 117, 110, 75, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 168, 162, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 135, 87, 255, 98, 91, 66, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 117, 116, 76, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 151, 150, 94, 255, 151, 150, 94, 255, 151, 150, 94, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 123, 121, 76, 255, 98, 97, 66, 255, 114, 112, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 151, 145, 94, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 142, 139, 94, 255, 142, 139, 94, 255, 142, 139, 94, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 66, 255, 114, 108, 75, 255, 130, 127, 87, 255, 130, 127, 87, 255, 147, 145, 98, 255, 139, 132, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 139, 132, 87, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 117, 113, 76, 255, 140, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 116, 76, 255, 117, 116, 76, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 139, 138, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 147, 145, 91, 255, 147, 145, 91, 255, 147, 145, 91, 255, 123, 121, 76, 255, 98, 97, 66, 255, 114, 112, 75, 255, 130, 129, 87, 255, 130, 129, 87, 255, 135, 133, 87, 255, 135, 133, 87, 255, 142, 139, 91, 255, 135, 133, 87, 255, 142, 139, 91, 255, 142, 139, 91, 255, 135, 133, 87, 255, 135, 133, 87, 255, 135, 127, 87, 255, 135, 127, 87, 255, 135, 127, 87, 255, 139, 133, 91, 255, 147, 145, 98, 255, 147, 145, 98, 255, 105, 108, 75, 255, 87, 91, 66, 255, 114, 108, 75, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 98, 97, 66, 255, 139, 138, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 76, 255, 117, 113, 76, 255, 117, 113, 76, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 110, 108, 76, 255, 87, 86, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 117, 113, 75, 255, 98, 91, 66, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 117, 114, 75, 255, 98, 97, 66, 255, 87, 85, 66, 255, 105, 102, 73, 255, 87, 85, 66, 255, 105, 102, 73, 255, 105, 102, 73, 255, 127, 121, 79, 255, 127, 121, 79, 255, 127, 121, 79, 255, 105, 108, 75, 255, 105, 108, 75, 255, 105, 108, 75, 255, 105, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 114, 108, 75, 255, 105, 107, 73, 255, 105, 107, 73, 255, 87, 91, 66, 255, 87, 91, 66, 255, 110, 108, 76, 255, 130, 126, 87, 255, 151, 145, 98, 255, 173, 163, 110, 255, 159, 163, 98, 255, 159, 163, 98, 255, 154, 156, 94, 255, 147, 139, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 117, 116, 76, 255, 117, 116, 76, 255, 117, 116, 76, 255, 98, 97, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 87, 86, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 114, 108, 75, 255, 114, 108, 75, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 98, 97, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 85, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 98, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 87, 91, 66, 255, 110, 108, 76, 255, 130, 126, 87, 255, 151, 145, 98, 255, 173, 163, 110, 255, 151, 147, 91, 255, 159, 163, 98, 255, 159, 163, 98, 255, 147, 139, 87, 255, 110, 102, 77, 255, 110, 102, 77, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 87, 86, 66, 255, 147, 146, 98, 255, 147, 146, 98, 255, 128, 126, 87, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 135, 134, 87, 255, 135, 133, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 98, 91, 66, 255, 114, 108, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 139, 133, 87, 255, 117, 114, 75, 255, 139, 133, 87, 255, 139, 133, 87, 255, 127, 121, 79, 255, 127, 121, 79, 255, 105, 102, 73, 255, 105, 102, 73, 255, 105, 102, 73, 255, 127, 121, 79, 255, 127, 121, 79, 255, 147, 139, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 130, 127, 87, 255, 130, 127, 87, 255, 147, 145, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 87, 91, 66, 255, 110, 108, 76, 255, 151, 145, 98, 255, 151, 145, 98, 255, 173, 163, 110, 255, 159, 163, 98, 255, 159, 163, 98, 255, 159, 163, 98, 255, 147, 139, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 106, 104, 76, 255, 147, 146, 98, 255, 147, 146, 98, 255, 147, 146, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 98, 91, 66, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 151, 98, 255, 139, 133, 87, 255, 159, 151, 98, 255, 159, 151, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 105, 102, 73, 255, 127, 121, 79, 255, 147, 139, 87, 255, 147, 139, 87, 255, 127, 127, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 139, 87, 255, 147, 139, 87, 255, 147, 139, 87, 255, 87, 91, 66, 255, 110, 108, 77, 255, 151, 145, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 159, 163, 98, 255, 159, 163, 98, 255, 159, 163, 98, 255, 147, 139, 87, 255, 110, 102, 77, 255, 126, 120, 83, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 87, 91, 66, 255, 106, 104, 76, 255, 147, 146, 98, 255, 147, 146, 99, 255, 147, 146, 99, 255, 147, 146, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 98, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 117, 113, 76, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 173, 170, 110, 255, 147, 145, 98, 255, 163, 162, 105, 255, 163, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 135, 127, 87, 255, 98, 97, 66, 255, 114, 113, 75, 255, 130, 129, 87, 255, 130, 129, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 156, 153, 102, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 151, 98, 255, 159, 153, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 163, 158, 102, 255, 163, 158, 102, 255, 147, 145, 87, 255, 98, 97, 66, 255, 117, 116, 75, 255, 159, 158, 98, 255, 159, 158, 98, 255, 149, 147, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 110, 103, 77, 255, 143, 135, 92, 255, 159, 152, 99, 255, 159, 152, 99, 255, 164, 158, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 173, 170, 110, 255, 147, 145, 98, 255, 163, 162, 105, 255, 163, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 135, 127, 87, 255, 98, 97, 66, 255, 114, 113, 75, 255, 130, 129, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 163, 162, 105, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 163, 110, 255, 173, 163, 110, 255, 163, 158, 102, 255, 147, 145, 87, 255, 98, 97, 66, 255, 117, 116, 76, 255, 139, 138, 87, 255, 159, 158, 98, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 97, 66, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 147, 146, 98, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 173, 170, 110, 255, 156, 153, 102, 255, 163, 162, 105, 255, 163, 162, 105, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 135, 127, 87, 255, 98, 97, 66, 255, 114, 113, 75, 255, 130, 129, 87, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 156, 153, 102, 255, 156, 153, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 156, 152, 94, 255, 163, 158, 102, 255, 164, 158, 102, 255, 147, 145, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 139, 138, 87, 255, 139, 138, 87, 255, 173, 170, 110, 255, 173, 170, 110, 255, 149, 147, 98, 255, 173, 170, 110, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 99, 97, 66, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 164, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 103, 77, 255, 142, 135, 91, 255, 159, 152, 98, 255, 159, 152, 98, 255, 164, 162, 105, 255, 164, 162, 105, 255, 164, 162, 105, 255, 156, 153, 102, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 138, 91, 255, 142, 138, 91, 255, 98, 97, 66, 255, 114, 113, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 147, 145, 98, 255, 173, 170, 110, 255, 156, 153, 102, 255, 156, 153, 102, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 156, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 139, 138, 87, 255, 98, 97, 66, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 156, 152, 94, 255, 164, 158, 103, 255, 156, 152, 94, 255, 147, 145, 87, 255, 98, 97, 66, 255, 98, 97, 66, 255, 117, 116, 76, 255, 117, 116, 76, 255, 98, 103, 77, 255, 98, 103, 77, 255, 98, 103, 77, 255, 98, 103, 77, 255, 98, 97, 66, 255, 98, 97, 66, 255, 99, 97, 66, 255, 99, 97, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 164, 159, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 108, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 163, 156, 105, 255, 147, 139, 98, 255, 98, 97, 66, 255, 114, 113, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 152, 98, 255, 185, 176, 123, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 163, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 168, 159, 98, 255, 164, 156, 98, 255, 159, 152, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 98, 91, 66, 255, 114, 107, 73, 255, 123, 128, 87, 255, 123, 128, 87, 255, 123, 128, 87, 255, 140, 140, 91, 255, 159, 158, 98, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 168, 162, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 173, 170, 110, 255, 164, 162, 106, 255, 164, 162, 106, 255, 164, 162, 106, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 108, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 173, 164, 110, 255, 156, 147, 103, 255, 98, 97, 66, 255, 114, 113, 75, 255, 147, 145, 98, 255, 147, 145, 98, 255, 159, 152, 98, 255, 168, 159, 107, 255, 159, 152, 98, 255, 159, 152, 98, 255, 159, 158, 98, 255, 168, 162, 98, 255, 163, 159, 98, 255, 168, 162, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 152, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 98, 91, 66, 255, 147, 140, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 168, 162, 99, 255, 173, 164, 99, 255, 168, 162, 99, 255, 173, 164, 99, 255, 173, 170, 110, 255, 164, 162, 106, 255, 164, 162, 106, 255, 147, 146, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 108, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 173, 164, 110, 255, 164, 156, 105, 255, 156, 147, 103, 255, 98, 97, 66, 255, 98, 97, 66, 255, 130, 129, 87, 255, 147, 145, 98, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 159, 98, 255, 164, 159, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 164, 156, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 114, 107, 73, 255, 147, 140, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 173, 164, 99, 255, 173, 170, 110, 255, 164, 162, 106, 255, 164, 162, 106, 255, 156, 153, 103, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 98, 255, 98, 91, 66, 255, 110, 109, 77, 255, 143, 141, 91, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 110, 255, 164, 156, 105, 255, 164, 156, 105, 255, 156, 147, 103, 255, 98, 97, 66, 255, 98, 97, 66, 255, 130, 129, 87, 255, 147, 145, 98, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 168, 159, 107, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 159, 158, 98, 255, 142, 141, 91, 255, 110, 108, 77, 255, 98, 91, 66, 255, 139, 135, 87, 255, 159, 158, 98, 255, 159, 158, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 98, 255, 168, 159, 98, 255, 114, 107, 73, 255, 98, 91, 66, 255, 131, 123, 80, 255, 147, 140, 87, 255, 173, 164, 98, 255, 173, 164, 98, 255, 173, 164, 99, 255, 173, 164, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 159, 158, 99, 255, 99, 103, 67, 255, 110, 103, 77, 255, 159, 152, 99, 255, 159, 152, 99, 255, 159, 152, 99, 255), +"format": "RGBA8", +"height": 64, +"mipmaps": false, +"width": 64 +} + +[sub_resource type="ImageTexture" id="ImageTexture_qws2q"] +image = SubResource("Image_s62qo") + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 107.0 +offset_bottom = 51.0 +focus_mode = 2 +mouse_filter = 1 +theme = ExtResource("3_a3d05") +script = ExtResource("1_bk6mq") +theme_normal = ExtResource("3_a3d05") +theme_selected = ExtResource("1_pvt6l") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 +metadata/_edit_lock_ = true + +[node name="TextureRect" type="TextureRect" parent="VBoxContainer"] +layout_mode = 2 +texture = SubResource("ImageTexture_qws2q") +stretch_mode = 3 + +[node name="MaterialName" type="Label" parent="VBoxContainer"] +layout_mode = 2 + +[connection signal="focus_entered" from="." to="." method="_on_focus_entered"] +[connection signal="focus_exited" from="." to="." method="_on_focus_exited"] +[connection signal="tree_exiting" from="." to="." method="_on_tree_exiting"] diff --git a/addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd b/addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd new file mode 100644 index 0000000..5f8f092 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd @@ -0,0 +1,40 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Resource +class_name ThumbnailGroup + +var thumbnails:Array[MaterialThumbnail] = [] + +func select_thumbnail(obj:MaterialThumbnail): + for t in thumbnails: + t.selected = t == obj + +func add_thumbnail(obj:MaterialThumbnail): + thumbnails.append(obj) + +func remove_thumbnail(obj:MaterialThumbnail): + thumbnails.remove_at(thumbnails.find(obj)) + + diff --git a/addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres b/addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres new file mode 100644 index 0000000..6a39c73 --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/thumbnail_normal_theme.tres @@ -0,0 +1,17 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://bx26luxdhj3jq"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_amf1g"] +bg_color = Color(0, 0, 0, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(0, 0, 0, 1) +border_blend = true +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[resource] +PanelContainer/styles/panel = SubResource("StyleBoxFlat_amf1g") diff --git a/addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres b/addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres new file mode 100644 index 0000000..45ecb6d --- /dev/null +++ b/addons/cyclops_level_builder/docks/material_palette/thumbnail_selected_theme.tres @@ -0,0 +1,16 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://c0gpl22e2g6ay"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_amf1g"] +bg_color = Color(0, 0, 0, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(1, 0, 0, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[resource] +PanelContainer/styles/panel = SubResource("StyleBoxFlat_amf1g") diff --git a/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd new file mode 100644 index 0000000..4420daf --- /dev/null +++ b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd @@ -0,0 +1,56 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Control +class_name ToolPropertiesDock + +var builder:CyclopsLevelBuilder + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +func set_editor(control:Control): + for child in $ScrollContainer.get_children(): + $ScrollContainer.remove_child(child) + + if control: + $ScrollContainer.add_child(control) + +func save_state(state:Dictionary): + var substate:Dictionary = {} + state["tool_properties"] = substate + + +func load_state(state:Dictionary): + if state == null || !state.has("tool_properties"): + return + + var substate:Dictionary = state["tool_properties"] diff --git a/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn new file mode 100644 index 0000000..3c2a250 --- /dev/null +++ b/addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=2 format=3 uid="uid://caoy37s0y5a8y"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd" id="1_7262j"] + +[node name="Tool Properties" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_7262j") + +[node name="ScrollContainer" type="ScrollContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd new file mode 100644 index 0000000..89221b5 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd @@ -0,0 +1,79 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends SubViewport +class_name UvEditorPreview + + + +@export var target_material:Material: + get: + return target_material + set(value): + target_material = value + #$Node3D/MeshInstance3D.material_override = target_material + #dirty = true +# var studio:UvEditorPreviewStudio = get_node("UvPreviewStudio") +# studio.target_material = target_material +# if $UvPreviewStudio: +# $UvPreviewStudio.target_material = target_material + dirty = true + +@export var uv_transform:Transform2D = Transform2D.IDENTITY: + get: + return uv_transform + set(value): + if value == uv_transform: + return + uv_transform = value +# dirty = true +# $UvPreviewStudio.uv_transform = uv_transform +# var studio:UvEditorPreviewStudio = get_node("UvPreviewStudio") +# studio.uv_transform = uv_transform +# if $UvPreviewStudio: +# $UvPreviewStudio.uv_transform = uv_transform + dirty = true + +var dirty:bool = true +#var points:PackedVector3Array = [Vector3(0, 0, 0), Vector3(1, 1, 0), Vector3(1, 0, 0), Vector3(0, 1, 0)] + +func take_snapshot()->ImageTexture: + #print ("pre-grabbing image %s" % target_material.resource_path) + await RenderingServer.frame_post_draw + #print ("grabbing image %s" % target_material.resource_path) + var image:Image = get_viewport().get_texture().get_image() + var tex:ImageTexture = ImageTexture.create_from_image(image) + return tex + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + +func _process(delta): + if dirty: + $UvPreviewStudio.target_material = target_material + $UvPreviewStudio.uv_transform = uv_transform + dirty = false + + diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn new file mode 100644 index 0000000..0999fdc --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=4 format=3 uid="uid://bbfgpupliiqnm"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd" id="1_57x0n"] +[ext_resource type="Material" uid="uid://rdhrhgrb78ls" path="res://addons/cyclops_level_builder/materials/grid.tres" id="2_kxmas"] +[ext_resource type="PackedScene" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn" id="3_7qfos"] + +[node name="UvPreview" type="SubViewport"] +own_world_3d = true +size = Vector2i(256, 256) +render_target_update_mode = 4 +script = ExtResource("1_57x0n") +target_material = ExtResource("2_kxmas") + +[node name="UvPreviewStudio" parent="." instance=ExtResource("3_7qfos")] +target_material = ExtResource("2_kxmas") diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd new file mode 100644 index 0000000..71449a8 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd @@ -0,0 +1,67 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Node3D +class_name UvEditorPreviewStudio + + +@export var target_material:Material: + get: + return target_material + set(value): + target_material = value + #$Node3D/MeshInstance3D.material_override = target_material + dirty = true + +@export var uv_transform:Transform2D = Transform2D.IDENTITY: + get: + return uv_transform + set(value): + if value == uv_transform: + return + uv_transform = value + dirty = true + +var dirty:bool = true +var points:PackedVector3Array = [Vector3(-1, 1, 0), Vector3(1, 1, 0), Vector3(-1, -1, 0), Vector3(1, -1, 0)] + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): +# print("_process") + if dirty: + var mesh:ImmediateMesh = ImmediateMesh.new() + + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, target_material) + + mesh.surface_set_normal(Vector3(0, 0, 1)) + for p in points: + mesh.surface_set_uv(uv_transform * Vector2(p.x, -p.y)) + mesh.surface_add_vertex(p) + + mesh.surface_end() + +# print("Building preview mesh") + $MeshInstance3D.mesh = mesh + dirty = false diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn new file mode 100644 index 0000000..ed9f4f2 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd" id="1_38c8p"] + +[sub_resource type="ImmediateMesh" id="ImmediateMesh_23b3x"] + +[node name="Node3D" type="Node3D"] +script = ExtResource("1_38c8p") + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1) +projection = 1 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("ImmediateMesh_23b3x") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.0684279) diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd new file mode 100644 index 0000000..a6af64b --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd @@ -0,0 +1,182 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Control +class_name UvEdtiorViewport + +var material_thumbnail_dirty:bool = true + +var target_material:Material +var empty_material:Material + +var uv_transform:Transform2D = Transform2D.IDENTITY + +var builder:CyclopsLevelBuilder: + get: + return builder + set(value): + if builder: + builder.selection_changed.disconnect(on_selection_changed) + + builder = value + + if builder: + builder.selection_changed.connect(on_selection_changed) + +var spin_offset_x:NumbericLineEdit +var spin_offset_y:NumbericLineEdit +var spin_scale_x:NumbericLineEdit +var spin_scale_y:NumbericLineEdit +var spin_rotation:NumbericLineEdit +var spin_skew:NumbericLineEdit + +#var test_slider:EditorSpinSlider + +# Called when the node enters the scene tree for the first time. +func _ready(): + empty_material = StandardMaterial3D.new() + empty_material.albedo_color = Color.BLACK + + spin_offset_x = $VBoxContainer/GridContainer2/HBoxContainer2/offset_x + spin_offset_y = $VBoxContainer/GridContainer2/HBoxContainer/offset_y + spin_scale_x = $VBoxContainer/GridContainer3/HBoxContainer2/scale_x + spin_scale_y = $VBoxContainer/GridContainer3/HBoxContainer/scale_y + spin_rotation = $VBoxContainer/GridContainer4/HBoxContainer2/rotation + spin_skew = $VBoxContainer/GridContainer4/HBoxContainer/skew + +# test_slider = EditorSpinSlider.new() +# test_slider.size_flags_horizontal = Control.SIZE_EXPAND +# $VBoxContainer.add_child(test_slider) + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + + if material_thumbnail_dirty: + material_thumbnail_dirty = false + + $UvPreview.target_material = target_material + $UvPreview.uv_transform = uv_transform + + var tex:ImageTexture = await $UvPreview.take_snapshot() + $VBoxContainer/Preview.texture = tex + pass + +func on_selection_changed(): + material_thumbnail_dirty = true + target_material = empty_material + + if builder.active_node: + var block:CyclopsConvexBlock = builder.active_node.get_active_block() + if block: + var vol:ConvexVolume = block.control_mesh + var face_idx = vol.active_face if vol.active_face != -1 else 0 + + var f:ConvexVolume.FaceInfo = vol.get_face(face_idx) + + + spin_offset_x.value = f.uv_transform.origin.x + spin_offset_y.value = f.uv_transform.origin.y + spin_scale_x.value = f.uv_transform.get_scale().x + spin_scale_y.value = f.uv_transform.get_scale().y + spin_rotation.value = rad_to_deg(f.uv_transform.get_rotation()) + spin_skew.value = rad_to_deg(f.uv_transform.get_skew()) + + if f.material_id != -1: + var mat:Material = block.materials[f.material_id] + target_material = mat + else: + target_material = null + + uv_transform = f.uv_transform + + + +func save_state(state:Dictionary): + var substate:Dictionary = {} + state["uv_editor_dock"] = substate + +# substate["materials"] = material_list.duplicate() + +func load_state(state:Dictionary): + if state == null || !state.has("uv_editor_dock"): + return + + var substate:Dictionary = state["uv_editor_dock"] + + +func apply_uv_transform(): + var xform:Transform2D = Transform2D(deg_to_rad(spin_rotation.value), \ + Vector2(spin_scale_x.value, spin_scale_y.value), \ + deg_to_rad(spin_skew.value), \ + Vector2(spin_offset_x.value, spin_offset_y.value)) + + uv_transform = xform + + var cmd:CommandSetUvTransform = CommandSetUvTransform.new() + cmd.builder = builder + cmd.uv_transform = xform + +# print("setting xform %s " % xform) + + if builder.active_node: + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for f_idx in vol.faces.size(): + var f:ConvexVolume.FaceInfo = vol.faces[f_idx] + if f.selected: + cmd.add_face(block.get_path(), f_idx) + + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + +func _on_offset_x_value_changed(value): + apply_uv_transform() + + +func _on_offset_y_value_changed(value): + apply_uv_transform() + + +func _on_scale_x_value_changed(value): + apply_uv_transform() + + +func _on_scale_y_value_changed(value): + apply_uv_transform() + + +func _on_rotation_value_changed(value): + apply_uv_transform() + + +func _on_skew_value_changed(value): + apply_uv_transform() + + diff --git a/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn new file mode 100644 index 0000000..dba3249 --- /dev/null +++ b/addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn @@ -0,0 +1,143 @@ +[gd_scene load_steps=6 format=3] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.gd" id="1_rk116"] +[ext_resource type="PackedScene" uid="uid://diibmlqy1mpqb" path="res://addons/cyclops_level_builder/controls/numeric_line_edit.tscn" id="2_cekit"] +[ext_resource type="PackedScene" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.tscn" id="2_kpj7h"] + +[sub_resource type="Image" id="Image_me1xa"] +data = { +"data": PackedByteArray(155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 156, 156, 156, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255, 155, 155, 155, 255), +"format": "RGBA8", +"height": 128, +"mipmaps": false, +"width": 128 +} + +[sub_resource type="ImageTexture" id="ImageTexture_0xrmf"] +image = SubResource("Image_me1xa") + +[node name="Uv Transform" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = -697.0 +offset_bottom = -285.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_rk116") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +metadata/_edit_lock_ = true + +[node name="Preview" type="TextureRect" parent="VBoxContainer"] +layout_mode = 2 +texture = SubResource("ImageTexture_0xrmf") +stretch_mode = 3 + +[node name="GridContainer2" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/GridContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer2/HBoxContainer2"] +layout_mode = 2 +text = "Offset X +" + +[node name="offset_x" parent="VBoxContainer/GridContainer2/HBoxContainer2" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/GridContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer2/HBoxContainer"] +layout_mode = 2 +text = "Offset Y +" + +[node name="offset_y" parent="VBoxContainer/GridContainer2/HBoxContainer" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="GridContainer3" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/GridContainer3"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer3/HBoxContainer2"] +layout_mode = 2 +text = "Scale X +" + +[node name="scale_x" parent="VBoxContainer/GridContainer3/HBoxContainer2" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/GridContainer3"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer3/HBoxContainer"] +layout_mode = 2 +text = "Scale Y" + +[node name="scale_y" parent="VBoxContainer/GridContainer3/HBoxContainer" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="GridContainer4" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/GridContainer4"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer/GridContainer4/HBoxContainer2"] +layout_mode = 2 +text = "Rotation" + +[node name="rotation" parent="VBoxContainer/GridContainer4/HBoxContainer2" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 +snap_size = 15.0 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/GridContainer4"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label2" type="Label" parent="VBoxContainer/GridContainer4/HBoxContainer"] +layout_mode = 2 +text = "Skew +" + +[node name="skew" parent="VBoxContainer/GridContainer4/HBoxContainer" instance=ExtResource("2_cekit")] +layout_mode = 2 +size_flags_horizontal = 3 +snap_size = 15.0 + +[node name="UvPreview" parent="." instance=ExtResource("2_kpj7h")] +size = Vector2i(128, 128) +target_material = null + +[connection signal="value_changed" from="VBoxContainer/GridContainer2/HBoxContainer2/offset_x" to="." method="_on_offset_x_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer2/HBoxContainer/offset_y" to="." method="_on_offset_y_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer3/HBoxContainer2/scale_x" to="." method="_on_scale_x_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer3/HBoxContainer/scale_y" to="." method="_on_scale_y_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer4/HBoxContainer2/rotation" to="." method="_on_rotation_value_changed"] +[connection signal="value_changed" from="VBoxContainer/GridContainer4/HBoxContainer/skew" to="." method="_on_skew_value_changed"] diff --git a/addons/cyclops_level_builder/handles/handle_edge.gd b/addons/cyclops_level_builder/handles/handle_edge.gd new file mode 100644 index 0000000..377de50 --- /dev/null +++ b/addons/cyclops_level_builder/handles/handle_edge.gd @@ -0,0 +1,40 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name HandleEdge + +var edge_index:int +#var p0:Vector3 +#var p1:Vector3 +#var p0_init:Vector3 +#var p1_init:Vector3 +var p_ref:Vector3 #Centroid +var p_ref_init:Vector3 +var block_path:NodePath + + +func _to_string(): +# return "%s init pos %s %s pos %s %s" % [block_path, initial_p0, initial_p1, p0, p1] + return "edge %s e_idx:%s p_ref:%s p_ref_init:%s" % [block_path, edge_index, p_ref, p_ref_init] diff --git a/addons/cyclops_level_builder/handles/handle_face.gd b/addons/cyclops_level_builder/handles/handle_face.gd new file mode 100644 index 0000000..8afe42f --- /dev/null +++ b/addons/cyclops_level_builder/handles/handle_face.gd @@ -0,0 +1,37 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name HandleFace + +var face_index:int +var face_id:int +var p_ref:Vector3 #Centroid +var p_ref_init:Vector3 +var block_path:NodePath + + +func _to_string(): +# return "%s init pos %s %s pos %s %s" % [block_path, initial_p0, initial_p1, p0, p1] + return "face %s idx:%s ref_%s ref_init:%s" % [block_path.get_name(block_path.get_name_count() - 1), face_index, p_ref, p_ref_init] diff --git a/addons/cyclops_level_builder/handles/handle_vertex.gd b/addons/cyclops_level_builder/handles/handle_vertex.gd new file mode 100644 index 0000000..af89b77 --- /dev/null +++ b/addons/cyclops_level_builder/handles/handle_vertex.gd @@ -0,0 +1,36 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name HandleVertex + +var vertex_index:int +var position:Vector3 +#var id:int #Label to link this vertex back to whatever is being tracked +var initial_position:Vector3 +var block_path:NodePath + + +func _to_string(): + return "%s init pos %s pos %s" % [block_path, initial_position, position] diff --git a/addons/cyclops_level_builder/materials/grid.tres b/addons/cyclops_level_builder/materials/grid.tres new file mode 100644 index 0000000..ee80492 --- /dev/null +++ b/addons/cyclops_level_builder/materials/grid.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" load_steps=3 format=3 uid="uid://rdhrhgrb78ls"] + +[ext_resource type="Texture2D" uid="uid://bnlqi20ay4vs1" path="res://addons/cyclops_level_builder/art/textures/grid_cell2.png" id="1_17wu6"] +[ext_resource type="Texture2D" uid="uid://b78mg60xhic6n" path="res://addons/cyclops_level_builder/art/textures/checkerboard.png" id="1_ldry2"] + +[resource] +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("1_ldry2") +roughness_texture = ExtResource("1_17wu6") +texture_filter = 5 diff --git a/addons/cyclops_level_builder/materials/outline_material.tres b/addons/cyclops_level_builder/materials/outline_material.tres new file mode 100644 index 0000000..fc4196a --- /dev/null +++ b/addons/cyclops_level_builder/materials/outline_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://kw5ymmorwkvp"] + +[ext_resource type="Shader" uid="uid://cc5tovf48xmg1" path="res://addons/cyclops_level_builder/shaders/outline_shader.tres" id="1_i1fkq"] + +[resource] +render_priority = 0 +shader = ExtResource("1_i1fkq") +shader_parameter/ColorParameter = Color(0, 0, 0, 1) diff --git a/addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres b/addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres new file mode 100644 index 0000000..25ab946 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_active_fill_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://dv5gwbhe5pg64"] + +[resource] +render_priority = 1 +transparency = 1 +albedo_color = Color(0, 0, 0, 0.501961) +emission_enabled = true +emission = Color(1, 1, 1, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_active_material.tres b/addons/cyclops_level_builder/materials/tool_edit_active_material.tres new file mode 100644 index 0000000..2472241 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_active_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://dneusleqxicge"] + +[resource] +render_priority = 1 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 1, 1, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres b/addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres new file mode 100644 index 0000000..f47984c --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_selected_fill_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://b20sku4kdojbr"] + +[resource] +render_priority = 1 +transparency = 1 +albedo_color = Color(0, 0, 0, 0.501961) +emission_enabled = true +emission = Color(1, 0.466667, 0.109804, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_selected_material.tres b/addons/cyclops_level_builder/materials/tool_edit_selected_material.tres new file mode 100644 index 0000000..d634b72 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_selected_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://cmr7csndcasyp"] + +[resource] +render_priority = 1 +transparency = 4 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0.466667, 0.109804, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres b/addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres new file mode 100644 index 0000000..ffaca44 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_edit_unselected_material.tres @@ -0,0 +1,8 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://ff2cjjfaaqfb"] + +[resource] +render_priority = 1 +transparency = 4 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_material.tres b/addons/cyclops_level_builder/materials/tool_material.tres new file mode 100644 index 0000000..48dfa0c --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_material.tres @@ -0,0 +1,9 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://bm85lvfgttrlj"] + +[resource] +render_priority = 1 +transparency = 4 +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 1, 0, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_object_active_material.tres b/addons/cyclops_level_builder/materials/tool_object_active_material.tres new file mode 100644 index 0000000..6f666b9 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_object_active_material.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://dcr6mnkfw7mvh"] + +[resource] +render_priority = 1 +transparency = 4 +no_depth_test = true +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0.717647, 0.529412, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/materials/tool_object_selected_material.tres b/addons/cyclops_level_builder/materials/tool_object_selected_material.tres new file mode 100644 index 0000000..e08c765 --- /dev/null +++ b/addons/cyclops_level_builder/materials/tool_object_selected_material.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://bscbhmr84pnpx"] + +[resource] +render_priority = 1 +transparency = 4 +no_depth_test = true +albedo_color = Color(0, 0, 0, 1) +emission_enabled = true +emission = Color(1, 0.494118, 0.160784, 1) +grow_amount = 0.1 diff --git a/addons/cyclops_level_builder/math/convex_volume.gd b/addons/cyclops_level_builder/math/convex_volume.gd new file mode 100644 index 0000000..56f5772 --- /dev/null +++ b/addons/cyclops_level_builder/math/convex_volume.gd @@ -0,0 +1,928 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name ConvexVolume + + +class VertexInfo extends RefCounted: + var mesh:ConvexVolume + #var index:int + var point:Vector3 + var normal:Vector3 + var edge_indices:Array[int] = [] + var selected:bool + #var active:bool + + func _init(mesh:ConvexVolume, point:Vector3 = Vector3.ZERO): + self.mesh = mesh + self.point = point + + func _to_string(): + var s:String = "%s [" % [point] + for i in edge_indices: + s += "%s " % i + s += "]" + + return s + +class EdgeInfo extends RefCounted: + var mesh:ConvexVolume + var start_index:int + var end_index:int + var face_indices:Array[int] = [] + var selected:bool + #var active:bool + + func _init(mesh:ConvexVolume, start:int = 0, end:int = 0): + self.mesh = mesh + start_index = start + end_index = end + + func _to_string(): + var s:String = "%s %s [" % [start_index, end_index] + for i in face_indices: + s += "%s " % i + s += "]" + return s + + +class FaceInfo extends RefCounted: + var mesh:ConvexVolume + var id:int + var normal:Vector3 #Face normal points in direction of interior + var material_id:int + var uv_transform:Transform2D + var selected:bool + #var active:bool + var vertex_indices:Array[int] + var triangulation_indices:Array[int] + var lightmap_uvs:PackedVector2Array + + func _init(mesh:ConvexVolume, id:int, normal:Vector3, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = 0, selected:bool = false): + self.mesh = mesh + self.id = id + self.normal = normal + self.material_id = material_id + self.uv_transform = uv_transform + self.selected = selected + + func get_plane()->Plane: + return Plane(normal, mesh.vertices[vertex_indices[0]].point) + + func get_points()->PackedVector3Array: + var result:PackedVector3Array + for i in vertex_indices: + result.append(mesh.vertices[i].point) + return result + + func get_centroid()->Vector3: + var points:PackedVector3Array = get_points() + var center:Vector3 + for p in points: + center += p + center /= points.size() + return center + +# func get_triangulation()->Array[int]: +# if triangulation_indices.is_empty(): +# var points:PackedVector3Array +# var indices:Array[int] +# for v_idx in vertex_indices: +# points.append(mesh.vertices[v_idx].point) +# indices.append(v_idx) +# +## print("start points %s" % points) +# +# var normal:Vector3 = MathUtil.face_area_x2(points).normalized() +## print("normal %s" % normal) +# triangulation_indices = MathUtil.trianglate_face_indices(points, indices, normal) +## print("triangulation %s" % str(triangulation_indices)) +# +# return triangulation_indices + + func get_triangulation()->Array[int]: + if triangulation_indices.is_empty(): + var points:PackedVector3Array + for v_idx in vertex_indices: + points.append(mesh.vertices[v_idx].point) + +# print("start points %s" % points) + + var normal:Vector3 = MathUtil.face_area_x2(points).normalized() +# print("normal %s" % normal) + triangulation_indices = MathUtil.trianglate_face_vertex_indices(points, normal) +# print("triangulation %s" % str(triangulation_indices)) + + return triangulation_indices + + func get_trianges()->PackedVector3Array: + var indices:Array[int] = get_triangulation() + var result:PackedVector3Array + + for fv_idx in indices: + var v_idx:int = vertex_indices[fv_idx] + result.append(mesh.vertices[v_idx].point) + +# print("triangules %s" % result) + + return result + + func reverse(): + normal = -normal + vertex_indices.reverse() + triangulation_indices.clear() + +#class FaceVertexInfo extends RefCounted: +# var vert_idx:int +# var face_idx:int + + + +var vertices:Array[VertexInfo] = [] +var edges:Array[EdgeInfo] = [] +var faces:Array[FaceInfo] = [] +var bounds:AABB + +var lightmap_uvs_dirty = true + +var active_vertex:int = -1 +var active_edge:int = -1 +var active_face:int = -1 + +func _to_string()->String: + var result:String = "" + for v in vertices: + result += str(v.point) + ", " + return result + + +func init_block(block_bounds:AABB, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = -1): + var p000:Vector3 = block_bounds.position + var p111:Vector3 = block_bounds.end + var p001:Vector3 = Vector3(p000.x, p000.y, p111.z) + var p010:Vector3 = Vector3(p000.x, p111.y, p000.z) + var p011:Vector3 = Vector3(p000.x, p111.y, p111.z) + var p100:Vector3 = Vector3(p111.x, p000.y, p000.z) + var p101:Vector3 = Vector3(p111.x, p000.y, p111.z) + var p110:Vector3 = Vector3(p111.x, p111.y, p000.z) + + init_prism([p000, p001, p011, p010], p100 - p000, uv_transform, material_id) + + +func init_prism(base_points:Array[Vector3], extrude_dir:Vector3, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = -1): + vertices = [] + edges = [] + faces = [] + var base_normal = -extrude_dir.normalized() + + var face_area_x2:Vector3 = MathUtil.face_area_x2(base_points) + if face_area_x2.dot(extrude_dir) > 0: + base_points.reverse() + + for p in base_points: + var v:VertexInfo = VertexInfo.new(self, p) + vertices.append(v) + for p in base_points: + var v:VertexInfo = VertexInfo.new(self, p + extrude_dir) + vertices.append(v) + + var f0:FaceInfo = FaceInfo.new(self, faces.size(), base_normal, uv_transform, material_id) + f0.vertex_indices = [] + f0.vertex_indices.append_array(range(base_points.size())) + faces.append(f0) + var f1:FaceInfo = FaceInfo.new(self, faces.size(), -base_normal, uv_transform, material_id) + f1.vertex_indices = [] + f1.vertex_indices.append_array(range(base_points.size(), base_points.size() * 2)) + f1.vertex_indices.reverse() + faces.append(f1) + + + for i in base_points.size(): + var p_idx0:int = i + var p_idx1:int = wrap(i + 1, 0, base_points.size()) + + var v0:VertexInfo = vertices[p_idx0] + var v1:VertexInfo = vertices[p_idx1] + + var normal = base_normal.cross(v1.point - v0.point).normalized() + var f:FaceInfo = FaceInfo.new(self, faces.size(), normal, uv_transform, material_id) + f.vertex_indices = [p_idx1, p_idx0, p_idx0 + base_points.size(), p_idx1 + base_points.size()] + faces.append(f) + + build_edges() + calc_vertex_normals() + + bounds = calc_bounds() + calc_lightmap_uvs() + +func init_from_convex_block_data(data:ConvexBlockData): + vertices = [] + edges = [] + faces = [] + + active_vertex = data.active_vertex + active_edge = data.active_edge + active_face = data.active_face + + for i in data.vertex_points.size(): + var v:VertexInfo = VertexInfo.new(self, data.vertex_points[i]) + vertices.append(v) + v.selected = data.vertex_selected[i] + #v.active = data.vertex_active[i] + + var num_edges:int = data.edge_vertex_indices.size() / 2 + for i in num_edges: + var edge:EdgeInfo = EdgeInfo.new(self, data.edge_vertex_indices[i * 2], data.edge_vertex_indices[i * 2 + 1]) + edges.append(edge) + edge.face_indices.append(data.edge_face_indices[i * 2]) + edge.face_indices.append(data.edge_face_indices[i * 2 + 1]) + edge.selected = data.edge_selected[i] + #edge.active = data.edge_active[i] + + var face_vertex_count:int = 0 + for face_idx in data.face_vertex_count.size(): + var num_verts:int = data.face_vertex_count[face_idx] + var vert_indices:Array[int] + var vert_points:PackedVector3Array + for i in num_verts: + var vert_idx:int = data.face_vertex_indices[face_vertex_count] + vert_indices.append(vert_idx) + vert_points.append(vertices[vert_idx].point) +# var v_idx:int = data.face_vertex_indices[count] + face_vertex_count += 1 + + var normal = MathUtil.face_area_x2(vert_points).normalized() + var f:FaceInfo = FaceInfo.new(self, data.face_ids[face_idx], normal, data.face_uv_transform[face_idx], data.face_material_indices[face_idx]) + f.selected = data.face_selected[face_idx] + #f.active = data.face_active[face_idx] + f.vertex_indices = vert_indices + + faces.append(f) + + + calc_vertex_normals() + + bounds = calc_bounds() + calc_lightmap_uvs() + #print("init_from_convex_block_data %s" % format_faces_string()) + + +#Calc convex hull bouding points +func init_from_points(points:PackedVector3Array, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = -1): + vertices = [] + edges = [] + faces = [] + + #print("init_from_points %s" % points) + var hull:QuickHull.Hull = QuickHull.quickhull(points) + #print("hull %s" % hull.format_points()) + + var hull_points:Array[Vector3] = hull.get_points() + + for p in hull_points: + vertices.append(VertexInfo.new(self, p)) + + for facet in hull.facets: + var plane:Plane = facet.plane + var vert_indices:Array[int] = [] + + for p in facet.points: + var vert_idx:int = hull_points.find(p) + vert_indices.append(vert_idx) + + var f:FaceInfo = FaceInfo.new(self, faces.size(), plane.normal, uv_transform, material_id) + f.vertex_indices = vert_indices + faces.append(f) + + + build_edges() + calc_vertex_normals() + + bounds = calc_bounds() + calc_lightmap_uvs() + +func calc_vertex_normals(): + for v_idx in vertices.size(): + var v:VertexInfo = vertices[v_idx] + var weighted_normal:Vector3 + + for face in faces: + if face.vertex_indices.has(v_idx): + weighted_normal += MathUtil.face_area_x2(face.get_points()) + + v.normal = weighted_normal.normalized() + + +func get_edge(vert_idx0:int, vert_idx1:int)->EdgeInfo: + for e in edges: + if e.start_index == vert_idx0 && e.end_index == vert_idx1: + return e + if e.start_index == vert_idx1 && e.end_index == vert_idx0: + return e + return null + + +func build_edges(): + + #Calculate edges + for face in faces: + var num_corners = face.vertex_indices.size() + for i0 in num_corners: + var i1:int = wrap(i0 + 1, 0, num_corners) + var v0_idx:int = face.vertex_indices[i0] + var v1_idx:int = face.vertex_indices[i1] + + var edge:EdgeInfo = get_edge(v0_idx, v1_idx) + if !edge: + var edge_idx = edges.size() + edge = EdgeInfo.new(self, v0_idx, v1_idx) + edges.append(edge) + + var v0:VertexInfo = vertices[v0_idx] + v0.edge_indices.append(edge_idx) + + var v1:VertexInfo = vertices[v1_idx] + v1.edge_indices.append(edge_idx) + + edge.face_indices.append(face.id) + +func get_face_coincident_with_plane(plane:Plane)->FaceInfo: + for f in faces: + var p:Plane = f.get_plane() + if p.is_equal_approx(plane): + return f + return null + + +func get_face_ids(selected_only:bool = false)->PackedInt32Array: + var result:PackedInt32Array + for f in faces: + if !selected_only || f.selected: + result.append(f.id) + return result + +func get_face_indices(selected_only:bool = false)->PackedInt32Array: + var result:PackedInt32Array + for f_idx in faces.size(): + var f:FaceInfo = faces[f_idx] + if !selected_only || f.selected: + result.append(f_idx) + return result + +func get_trimesh_indices()->PackedInt32Array: + var result:PackedInt32Array + + for f in faces: + for fv_idx in f.get_triangulation(): + var v_idx:int = f.vertex_indices[fv_idx] + result.append(v_idx) + + return result + +func get_face_most_similar_to_plane(plane:Plane)->FaceInfo: + var best_dot:float = -1 + var best_face:FaceInfo + + for f in faces: + var p:Plane = f.get_plane() + var dot = p.normal.dot(plane.normal) + if dot >= best_dot: + best_dot = dot + best_face = f + return best_face + +func copy_face_attributes(ref_vol:ConvexVolume): + for fl in faces: + var ref_face:FaceInfo = ref_vol.get_face_most_similar_to_plane(fl.get_plane()) + + fl.material_id = ref_face.material_id + fl.uv_transform = ref_face.uv_transform + fl.selected = ref_face.selected + +func to_convex_block_data()->ConvexBlockData: + var result:ConvexBlockData = ConvexBlockData.new() + + result.active_vertex = active_vertex + result.active_edge = active_edge + result.active_face = active_face + + for v in vertices: + result.vertex_points.append(v.point) + result.vertex_selected.append(v.selected) + #result.vertex_active.append(v.active) + + for e in edges: + result.edge_vertex_indices.append_array([e.start_index, e.end_index]) + result.edge_face_indices.append_array([e.face_indices[0], e.face_indices[1]]) + result.edge_selected.append(e.selected) + #result.edge_active.append(e.active) + + for face in faces: + var num_verts:int = face.vertex_indices.size() + result.face_vertex_count.append(num_verts) + result.face_vertex_indices.append_array(face.vertex_indices) + result.face_ids.append(face.id) + result.face_selected.append(face.selected) + #result.face_active.append(face.active) + result.face_material_indices.append(face.material_id) + result.face_uv_transform.append(face.uv_transform) + + return result + +func get_face(face_id:int)->FaceInfo: + for face in faces: + if face.id == face_id: + return face + return null + +# Creates a new volume that is equal to the portion of this volume on the top +# side of the passed plane. Does not modify the geometry of this volume. +func cut_with_plane(plane:Plane, uv_transform:Transform2D = Transform2D.IDENTITY, material_id:int = 0)->ConvexVolume: +# + var planes:Array[Plane] + for f in faces: + #Top of planr should point toward interior + planes.append(MathUtil.flip_plane(f.get_plane())) + planes.append(plane) + + #print("planes %s" % GeneralUtil.format_planes_string(planes)) + + var hull_points:Array[Vector3] = MathUtil.get_convex_hull_points_from_planes(planes) + if hull_points.is_empty(): + return null + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(hull_points) + + new_vol.copy_face_attributes(self) + + for f in new_vol.faces: + var f_plane:Plane = MathUtil.flip_plane(f.get_plane()) + if f_plane.is_equal_approx(plane): + f.uv_transform = uv_transform + f.material_id = material_id + break + + return new_vol + +func is_empty(): + return bounds.size.is_zero_approx() + +# Returns a new ConvexVolume equal to this volume after the plane of the +# indicated face has been translated the given offset. Does not modify the +# geometry of this volume. +func translate_face_plane(face_id:int, offset:Vector3, lock_uvs:bool = false)->ConvexVolume: + var xform:Transform3D = Transform3D(Basis.IDENTITY, -offset) + + var source_face:FaceInfo + var transformed_plane:Plane + + var planes:Array[Plane] = [] + for f in faces: + if f.id == face_id: + transformed_plane = MathUtil.flip_plane(f.get_plane()) * xform + planes.append(transformed_plane) + source_face = f + else: + planes.append(MathUtil.flip_plane(f.get_plane())) + + #print("planes %s" % str(planes)) + var hull_points:Array[Vector3] = MathUtil.get_convex_hull_points_from_planes(planes) + if hull_points.is_empty(): + return null + + var new_vol:ConvexVolume = ConvexVolume.new() + new_vol.init_from_points(hull_points) + new_vol.copy_face_attributes(self) + + return new_vol + +func translate(offset:Vector3, lock_uvs:bool = false): + transform(Transform3D(Basis.IDENTITY, offset), lock_uvs) + + +func transform(xform:Transform3D, lock_uvs:bool = false): + for v in vertices: + v.point = xform * v.point + + if xform.basis.determinant() < 0: + for f in faces: + f.reverse() + + if lock_uvs: +# var xform_inv:Transform3D = xform.affine_inverse() + #var xform_inv:Transform3D = xform + #print("--xform %s" % xform) + + for f in faces: + var axis:MathUtil.Axis = MathUtil.get_longest_axis(f.normal) + + match axis: + MathUtil.Axis.X: + var orig_p:Vector3 = xform.origin + var u_p:Vector3 = xform * Vector3(0, 0, 1) - orig_p + var v_p:Vector3 = xform * Vector3(0, 1, 0) - orig_p + var move_xform:Transform2D = Transform2D(Vector2(u_p.z, u_p.y), \ + Vector2(v_p.z, v_p.y), \ + Vector2(orig_p.z, orig_p.y)) + + f.uv_transform = f.uv_transform * move_xform + + MathUtil.Axis.Y: + var orig_p:Vector3 = xform.origin + var u_p:Vector3 = xform * Vector3(1, 0, 0) - orig_p + var v_p:Vector3 = xform * Vector3(0, 0, 1) - orig_p + var move_xform:Transform2D = Transform2D(Vector2(u_p.x, u_p.z), \ + Vector2(v_p.x, v_p.z), \ + Vector2(orig_p.x, orig_p.z)) + + f.uv_transform = f.uv_transform * move_xform + + MathUtil.Axis.Z: + #var xform_inv = xform.affine_inverse() + var orig_p:Vector3 = xform.origin + var u_p:Vector3 = xform * Vector3(1, 0, 0) - orig_p + var v_p:Vector3 = xform * Vector3(0, 1, 0) - orig_p + var move_xform:Transform2D = Transform2D(Vector2(u_p.x, u_p.y), \ + Vector2(v_p.x, v_p.y), \ + Vector2(orig_p.x, orig_p.y)) + + f.uv_transform = f.uv_transform * move_xform + + #calc_lightmap_uvs() + +func unused_face_id()->int: + var idx = 0 + for p in faces: + idx = max(idx, p.id) + return idx + 1 + +func contains_point(point:Vector3)->bool: + for f in faces: + var plane:Plane = f.get_plane() + if !plane.has_point(point) && !plane.is_point_over(point): + return false + return true + + +func get_points()->PackedVector3Array: + var points:PackedVector3Array + + for v in vertices: + points.append(v.point) + + return points + +func calc_bounds()->AABB: + if vertices.is_empty(): + return AABB() + + var result:AABB = AABB(vertices[0].point, Vector3.ZERO) + + for v_idx in range(1, vertices.size()): + result = result.expand(vertices[v_idx].point) + + return result + + +func tristrip_vertex_range(num_verts:int)->PackedInt32Array: + var result:PackedInt32Array + + result.append(0) + result.append(1) + for i in range(2, num_verts): + if (i & 1) == 0: + result.append(num_verts - (i >> 1)) + else: + result.append((i >> 1) + 1) + + return result + +func tristrip_vertex_range_reverse(num_verts:int)->PackedInt32Array: + var result:PackedInt32Array + + result.append(1) + result.append(0) + for i in range(2, num_verts): + if (i & 1) == 0: + result.append((i >> 1) + 1) + else: + result.append(num_verts - (i >> 1)) + + return result + +func calc_lightmap_uvs(): + var packer:FacePacker = FacePacker.new() + var max_dim:float = max(bounds.size.x, bounds.size.y, bounds.size.z) + var tree:FacePacker.FaceTree = packer.build_faces(self, max_dim * .1) + + var xform:Transform2D = Transform2D.IDENTITY + xform = xform.scaled(tree.bounds.size) + var xform_inv = xform.affine_inverse() + + for ft in tree.face_list: + var face:FaceInfo = faces[ft.face_index] + face.lightmap_uvs = xform_inv * ft.points + +func create_mesh(material_list:Array[Material], default_material:Material)->ArrayMesh: +# if Engine.is_editor_hint(): +# return +# print("num faces %s" % faces.size()) +# print("-creating mesh") + + var mesh:ArrayMesh = ArrayMesh.new() + mesh.blend_shape_mode = Mesh.BLEND_SHAPE_MODE_NORMALIZED + mesh.lightmap_size_hint = Vector2(1000, 1000) + + var shadow_mesh:ArrayMesh = ArrayMesh.new() + shadow_mesh.blend_shape_mode = Mesh.BLEND_SHAPE_MODE_NORMALIZED + + var face_dict:Dictionary = {} + for f_idx in faces.size(): +# print("check F_idx %s" % f_idx) + var face:FaceInfo = faces[f_idx] + if face_dict.has(face.material_id): + var arr = face_dict[face.material_id] + arr.append(f_idx) +# print("arr %s" % [arr]) + face_dict[face.material_id] = arr +# print("append %s to %s" % [f_idx, face.material_id]) + else: + face_dict[face.material_id] = [f_idx] +# print("starting %s to %s" % [f_idx, face.material_id]) + + var surface_idx:int = 0 + for mat_id in face_dict.keys(): +# print("surface mat grp %s" % mat_id) + + var points:PackedVector3Array + var normals:PackedVector3Array + var uv1s:PackedVector2Array + var uv2s:PackedVector2Array + + var material = default_material + if mat_id >= 0 && mat_id < material_list.size(): + material = material_list[mat_id] + + for f_idx in face_dict[mat_id]: +# print("f_idx %s" % f_idx) + + var face:FaceInfo = faces[f_idx] + + + var axis:MathUtil.Axis = MathUtil.get_longest_axis(face.normal) + + var fv_trianglation:Array[int] = face.get_triangulation() + + for fv_idx in fv_trianglation: + + var v_idx:int = face.vertex_indices[fv_idx] + # var p:Vector3 = triangles[i] + var p:Vector3 = vertices[v_idx].point + + var uv:Vector2 + if axis == MathUtil.Axis.X: + uv = Vector2(-p.z, -p.y) + elif axis == MathUtil.Axis.Y: + uv = Vector2(-p.x, -p.z) + elif axis == MathUtil.Axis.Z: + uv = Vector2(-p.x, -p.y) + + uv = face.uv_transform * uv + uv1s.append(uv) + uv2s.append(face.lightmap_uvs[fv_idx]) + + normals.append(face.normal) + + points.append(p) + + var arrays:Array = [] + arrays.resize(Mesh.ARRAY_MAX) + arrays[Mesh.ARRAY_VERTEX] = points + arrays[Mesh.ARRAY_NORMAL] = normals + arrays[Mesh.ARRAY_TEX_UV] = uv1s + arrays[Mesh.ARRAY_TEX_UV2] = uv2s + + mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) + mesh.surface_set_material(surface_idx, material) + + var shadow_arrays:Array = [] + shadow_arrays.resize(Mesh.ARRAY_MAX) + shadow_arrays[Mesh.ARRAY_VERTEX] = points + + shadow_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, shadow_arrays) + shadow_mesh.surface_set_material(surface_idx, material) + + surface_idx += 1 + + mesh.shadow_mesh = shadow_mesh +# var err = mesh.lightmap_unwrap(Transform3D.IDENTITY, 10) +# print("Lightmap unwrap Error: %s" % err) + return mesh + + + +func append_mesh_backfacing(mesh:ImmediateMesh, material:Material, offset:float = .2): +# if Engine.is_editor_hint(): +# return + + for face in faces: + + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, material) +# print("face %s" % face.index) + + mesh.surface_set_normal(face.normal) + +# for i in tristrip_vertex_range_reverse(face.vertex_indices.size()): + for i in tristrip_vertex_range_reverse(face.vertex_indices.size()): + var v_idx:int = face.vertex_indices[i] + var v:VertexInfo = vertices[v_idx] + var p:Vector3 = v.point + v.normal * offset + #var p:Vector3 = v.point + Vector3(.1, .1, .1) + + mesh.surface_add_vertex(p) + + mesh.surface_end() + +func append_mesh_outline(mesh:ImmediateMesh, viewport_camera:Camera3D, local_to_world:Transform3D, material:Material, thickness:float = 4): +# var cam_dir:Vector3 = viewport_camera.global_transform.basis.z + var cam_orig:Vector3 = viewport_camera.global_transform.origin + +# print("append_mesh_outline %s" % cam_dir) + #points along Z +# var cylinder:GeometryMesh = MathGeometry.unit_cylinder(4, thickness, thickness, 0, -1) + + var segments:PackedVector2Array + + for edge in edges: + var has_front:bool = false + var has_back:bool = false + + for f_idx in edge.face_indices: + var face = faces[f_idx] + #print("face norm %s" % face.normal) + var point_on_plane:Vector3 = vertices[face.vertex_indices[0]].point + var to_plane:Vector3 = cam_orig - point_on_plane + + if face.normal.dot(to_plane) > 0: + has_front = true + elif face.normal.dot(to_plane) < 0: + has_back = true + + #print("front %s back %s" % [has_front, has_back]) + + if has_front && has_back: + #print("drawing edge %s %s" % [edge.start_index, edge.end_index]) + #Draw edge + var v0:VertexInfo = vertices[edge.start_index] + var v1:VertexInfo = vertices[edge.end_index] + var p0_world:Vector3 = local_to_world * v0.point + var p1_world:Vector3 = local_to_world * v1.point + var p0_screen:Vector2 = viewport_camera.unproject_position(p0_world) + var p1_screen:Vector2 = viewport_camera.unproject_position(p1_world) + segments.append(p0_screen) + segments.append(p1_screen) + + var loops:Array[PackedVector2Array] = MathUtil.get_loops_from_segments_2d(segments) + for loop_points in loops: + var out_dirs:PackedVector2Array + + for v_idx in loop_points.size(): + var p0_screen:Vector2 = loop_points[wrap(v_idx - 1, 0, loop_points.size())] + var p1_screen:Vector2 = loop_points[v_idx] + var p2_screen:Vector2 = loop_points[wrap(v_idx + + 1, 0, loop_points.size())] + #var span:Vector2 = p2_screen - p1_screen + + var norm01:Vector2 = (p1_screen - p0_screen).normalized() + var norm12:Vector2 = (p2_screen - p1_screen).normalized() + + var out_dir1:Vector2 = (-norm01 + norm12).normalized() + var perp:Vector2 = out_dir1 - out_dir1.project(norm12) + #Check winding + if perp.x * norm12.y - perp.y * norm12.x < 0: + out_dir1 = -out_dir1 + + out_dirs.append(out_dir1) + + + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, material) + for v_idx in loop_points.size() + 1: + var p_screen:Vector2 = loop_points[wrap(v_idx, 0, loop_points.size())] + var p_out_dir:Vector2 = out_dirs[wrap(v_idx, 0, loop_points.size())] + + var z_pos:float = (viewport_camera.near + viewport_camera.far) / 2 + var p0:Vector3 = viewport_camera.project_position(p_screen, z_pos) + var p1:Vector3 = viewport_camera.project_position(p_screen + p_out_dir * thickness, z_pos) + + mesh.surface_add_vertex(p0) + mesh.surface_add_vertex(p1) + + mesh.surface_end() + + + +func create_mesh_wire(material:Material)->ImmediateMesh: +# if Engine.is_editor_hint(): +# return + var mesh:ImmediateMesh = ImmediateMesh.new() + + mesh.surface_begin(Mesh.PRIMITIVE_LINES, material) + + for e in edges: + var v0:VertexInfo = vertices[e.start_index] + var v1:VertexInfo = vertices[e.end_index] + + mesh.surface_add_vertex(v0.point) + mesh.surface_add_vertex(v1.point) + + mesh.surface_end() + + return mesh + + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + if bounds.intersects_ray(origin, dir) == null: + return null + + var best_result:IntersectResults + + for face in faces: +# var tris:PackedVector3Array = MathUtil.trianglate_face(face.get_points(), face.normal) + var tris:PackedVector3Array = face.get_trianges() + for i in range(0, tris.size(), 3): + var p0:Vector3 = tris[i] + var p1:Vector3 = tris[i + 1] + var p2:Vector3 = tris[i + 2] + + #Godot uses clockwise winding + var tri_area_x2:Vector3 = MathUtil.triangle_area_x2(p0, p1, p2) + + var p_hit:Vector3 = MathUtil.intersect_plane(origin, dir, p0, tri_area_x2) + if !p_hit.is_finite(): + continue + + if MathUtil.triangle_area_x2(p_hit, p0, p1).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p1, p2).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p2, p0).dot(tri_area_x2) < 0: + continue + + #Intersection + var dist_sq:float = (origin - p_hit).length_squared() + if !best_result || best_result.distance_squared > dist_sq: + + var result:IntersectResults = IntersectResults.new() + result.face_id = face.id + result.normal = face.normal + result.position = p_hit + result.distance_squared = dist_sq + + best_result = result + + return best_result + +func format_faces_string()->String: + var s:String = "" + for f in faces: + s = s + "[" + for v_idx in f.vertex_indices: + s += "%s, " % vertices[v_idx].point + s = s + "],\n" + return s + +func update_edge_and_face_selection_from_vertices(): + for e in edges: + e.selected = vertices[e.start_index].selected && vertices[e.end_index].selected + + for f in faces: + var all_sel:bool = true + for v_idx in f.vertex_indices: + if !vertices[v_idx].selected: + all_sel = false + break + f.selected = all_sel + + diff --git a/addons/cyclops_level_builder/math/face_packer.gd b/addons/cyclops_level_builder/math/face_packer.gd new file mode 100644 index 0000000..9a811ab --- /dev/null +++ b/addons/cyclops_level_builder/math/face_packer.gd @@ -0,0 +1,253 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name FacePacker + +class SpawnResult extends RefCounted: + var point:Vector2 + var flip:bool + + func _init(point:Vector2, flip:bool): + self.point = point + self.flip = flip + +class FaceTree extends RefCounted: +# var root:FaceTreeNode + var size:Vector2 + var spawn_points:PackedVector2Array = [Vector2.ZERO] + var face_list:Array[FaceTracker] + var bounds:Rect2 + + func _to_string()->String: + var res:String = "" + for face in face_list: + res += "%s,\n" % str(face) + return res + + func is_collision(rect:Rect2)->bool: + for face in face_list: + if face.bounds.intersects(rect): + return true + return false + + func max_vec_dim(v:Vector2): + return max(v.x, v.y) + + func get_best_spawn_point(face:FaceTracker)->SpawnResult: + var started:bool = false + var best_spawn_point:Vector2 = Vector2.INF + var best_bounds:Rect2 + var best_flip:bool + + for s_idx in spawn_points.size(): + var spawn_point:Vector2 = spawn_points[s_idx] + + var placed_bounds:Rect2 = face.bounds + placed_bounds.position += spawn_point + + if !is_collision(placed_bounds): + var new_bounds:Rect2 = bounds.merge(placed_bounds) + + if new_bounds.is_equal_approx(bounds): + return SpawnResult.new(spawn_point, false) + else: + if !started || max_vec_dim(best_bounds.size) > max_vec_dim(new_bounds.size): + best_bounds = new_bounds + best_flip = false + best_spawn_point = spawn_point + started = true + + var placed_bounds_flipped:Rect2 = face.bounds + placed_bounds_flipped.size = Vector2(placed_bounds_flipped.size.y, placed_bounds_flipped.size.x) + placed_bounds_flipped.position += spawn_point + + if !is_collision(placed_bounds_flipped): + var new_bounds_flipped:Rect2 = bounds.merge(placed_bounds_flipped) + + if new_bounds_flipped.is_equal_approx(bounds): + return SpawnResult.new(spawn_point, true) + else: + if !started || max_vec_dim(best_bounds.size) > max_vec_dim(new_bounds_flipped.size): + best_bounds = new_bounds_flipped + best_flip = true + best_spawn_point = spawn_point + started = true + + return SpawnResult.new(best_spawn_point, best_flip) + + func add_face(face:FaceTracker): + var spawn:SpawnResult = get_best_spawn_point(face) + + var idx = spawn_points.find(spawn.point) + spawn_points.remove_at(idx) + + if spawn.flip: + face.reflect_diagonal() + + face.translate(spawn.point) + face_list.append(face) + bounds = bounds.merge(face.bounds) + + var sp_0:Vector2 = face.bounds.position + Vector2(face.bounds.size.x, 0) + var sp_1:Vector2 = face.bounds.position + Vector2(0, face.bounds.size.y) + if !spawn_points.has(sp_0): + spawn_points.append(sp_0) + if !spawn_points.has(sp_1): + spawn_points.append(sp_1) + + + +class FaceTracker extends RefCounted: + var points:PackedVector2Array + var indices:PackedInt32Array + var bounds:Rect2 + var face_index:int + + func _to_string()->String: + var res:String = "[" + for p in points: + res += "%s, " % str(p) + res += "]" + return res + + func max_dim()->float: + return max(bounds.size.x, bounds.size.y) + + func reflect_diagonal(): + for p_idx in points.size(): + var p:Vector2 = points[p_idx] + points[p_idx] = Vector2(p.y, p.x) + bounds.size = Vector2(bounds.size.y, bounds.size.x) + + func translate(offset:Vector2): + for p_idx in points.size(): + points[p_idx] += offset + bounds.position += offset + + func fit_initial_rect(): + bounds = Rect2(points[0], Vector2.ZERO) + for i in range(1, points.size()): + bounds = bounds.expand(points[i]) + + #Move so corner of bounds is at (0, 0) + for i in points.size(): + points[i] -= bounds.position + bounds.position = Vector2.ZERO + + func get_best_base_index()->int: + var best_index:int = -1 + var best_height:float = INF + + for i0 in points.size(): + var i1:int = wrap(i0 + 1, 0, points.size()) + + var base_dir:Vector2 = points[i1] - points[i0] + var base_origin:Vector2 = points[i0] + var base_dir_perp:Vector2 = Vector2(-base_dir.y, base_dir.x) + + var max_height:float = 0 + + for j in range(2, points.size()): + var p_idx:int = wrap(j + i0, 0, points.size()) + var p:Vector2 = points[p_idx] + var offset:Vector2 = p - base_origin + var offset_proj:Vector2 = offset.project(base_dir_perp) + + max_height = max(max_height, offset_proj.length_squared()) + + if max_height < best_height: + best_height = max_height + best_index = i0 + + return best_index + + func rotate_to_best_fit(): + var i0:int = get_best_base_index() + var i1:int = wrap(i0 + 1, 0, points.size()) + + var base_dir:Vector2 = (points[i1] - points[i0]).normalized() + var base_dir_perp:Vector2 = Vector2(-base_dir.y, base_dir.x) + + var xform:Transform2D = Transform2D(base_dir, base_dir_perp, Vector2.ZERO) + var xform_inv:Transform2D = xform.affine_inverse() + + for p_idx in points.size(): + var p:Vector2 = xform_inv * points[p_idx] + points[p_idx] = p + + +func pack_faces(faces:Array[FaceTracker])->FaceTree: + faces.sort_custom(func (a:FaceTracker, b:FaceTracker): return a.max_dim() > b.max_dim()) + + var tree:FaceTree = FaceTree.new() + for f in faces: + tree.add_face(f) + + #print(tree) + return tree + +func build_faces(vol:ConvexVolume, margin:float)->FaceTree: + var faces:Array[FaceTracker] + + for f_idx in vol.faces.size(): + var face:ConvexVolume.FaceInfo = vol.faces[f_idx] + var axis:MathUtil.Axis = MathUtil.get_longest_axis(face.normal) + + var cross_vec:Vector3 + if axis == MathUtil.Axis.Y: + cross_vec = Vector3.FORWARD + else: + cross_vec = Vector3.UP + + var u_axis:Vector3 = face.normal.cross(cross_vec) + var v_axis:Vector3 = u_axis.cross(face.normal) + var basis:Basis = Basis(u_axis, face.normal, v_axis) + + var xform:Transform3D = Transform3D(basis, face.get_centroid()) + var xz_xform:Transform3D = xform.affine_inverse() + + var tracker:FaceTracker = FaceTracker.new() + tracker.face_index = f_idx + faces.append(tracker) + + for v_idx in face.vertex_indices: + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + var proj:Vector3 = xz_xform * v.point + tracker.points.append(Vector2(proj.x, proj.z)) + tracker.indices.append(v_idx) + + #print("face init points %s" % tracker.points) + + tracker.rotate_to_best_fit() + #print("after rot %s" % tracker.points) + tracker.fit_initial_rect() + #print("after fit %s" % tracker.points) + for p_idx in tracker.points.size(): + tracker.points[p_idx] += Vector2(margin, margin) + tracker.bounds.size += Vector2(margin, margin) * 2 + + return pack_faces(faces) + + diff --git a/addons/cyclops_level_builder/math/general_mesh.gd b/addons/cyclops_level_builder/math/general_mesh.gd new file mode 100644 index 0000000..fff2bb4 --- /dev/null +++ b/addons/cyclops_level_builder/math/general_mesh.gd @@ -0,0 +1,447 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name GeneralMesh + + +class VertexInfo extends RefCounted: + var index:int + var point:Vector3 + var edge_indices:Array[int] = [] + var selected:bool + + func _init(_index:int, _point:Vector3 = Vector3.ZERO): + index = _index + point = _point + + func _to_string(): + var s:String = "%s %s [" % [index, point] + for i in edge_indices: + s += "%s " % i + s += "]" + + return s + +class EdgeInfo extends RefCounted: + var index:int + var start_index:int + var end_index:int + var face_indices:Array[int] = [] + var selected:bool + + func _init(_index:int, _start:int = 0, _end:int = 0): + index = _index + start_index = _start + end_index = _end + + func _to_string(): + var s:String = "%s %s %s [" % [index, start_index, end_index] + for i in face_indices: + s += "%s " % i + s += "]" + return s + +class FaceInfo extends RefCounted: + var index:int + var normal:Vector3 +# var vertex_indices:Array[int] + var face_corner_indices:Array[int] + var material_index:int + var selected:bool + + func _init(_index:int, _face_corner_indices:Array[int] = [], _mat_index:int = 0): + index = _index + face_corner_indices = _face_corner_indices + material_index = _mat_index + + func _to_string(): + var s:String = "%s %s %s [" % [index, normal, material_index] + for i in face_corner_indices: + s += "%s " % i + s += "]" + return s + +class FaceCornerInfo extends RefCounted: + var index:int + var uv:Vector2 + var vertex_index:int + var face_index:int + var selected:bool + + func _init(_index:int, _vertex_index:int, _face_index:int): + vertex_index = _vertex_index + face_index = _face_index + + func _to_string(): + var s:String = "%s %s %s %s" % [index, uv, vertex_index, face_index] + return s + + + +var vertices:Array[VertexInfo] = [] +var edges:Array[EdgeInfo] = [] +var faces:Array[FaceInfo] = [] +var face_corners:Array[FaceCornerInfo] = [] +var bounds:AABB + +#var points:PackedVector3Array + +func _init(): +# init_block(Vector3.ZERO, Vector3.LEFT + Vector3.FORWARD, Vector3.UP) +# dump() + pass + +func get_face_indices()->PackedInt32Array: + var result:PackedInt32Array + for f in faces: + result.append(f.index) + return result + +func clear_lists(): + vertices = [] + edges = [] + faces = [] + face_corners = [] + bounds = AABB() + +func init_block(block_bounds:AABB): + var p000:Vector3 = block_bounds.position + var p111:Vector3 = block_bounds.end + var p001:Vector3 = Vector3(p000.x, p000.y, p111.z) + var p010:Vector3 = Vector3(p000.x, p111.y, p000.z) + var p011:Vector3 = Vector3(p000.x, p111.y, p111.z) + var p100:Vector3 = Vector3(p111.x, p000.y, p000.z) + var p101:Vector3 = Vector3(p111.x, p000.y, p111.z) + var p110:Vector3 = Vector3(p111.x, p111.y, p000.z) + + init_prism([p000, p001, p011, p010], p100 - p000) + + +func init_prism(base_points:Array[Vector3], extrude_dir:Vector3): + + var verts:PackedVector3Array + for p in base_points: + verts.append(p) + for p in base_points: + verts.append(p + extrude_dir) + + var index_list:PackedInt32Array + var face_len_list:PackedInt32Array + + var num_points:int = base_points.size() + for i0 in num_points: + var i1:int = wrap(i0 + 1, 0, num_points) + + index_list.append(i0) + index_list.append(i1) + index_list.append(i1 + num_points) + index_list.append(i0 + num_points) + face_len_list.append(4) + + for i0 in num_points: +# index_list.append(i0) + index_list.append(num_points - i0 - 1) + face_len_list.append(num_points) + + for i0 in num_points: + index_list.append(i0 + num_points) +# index_list.append(num_points * 2 - i0 - 1) + face_len_list.append(num_points) + + init_from_face_lists(verts, index_list, face_len_list) + + +func init_from_face_lists(verts:PackedVector3Array, index_list:PackedInt32Array, face_len_list:PackedInt32Array): + clear_lists() + + for i in verts.size(): + var v:VertexInfo = VertexInfo.new(i, verts[i]) + vertices.append(v) + + if i == 0: + bounds = AABB(verts[0], Vector3.ZERO) + else: + bounds = bounds.expand(verts[i]) + + var vertex_index_offset:int = 0 + for face_index in face_len_list.size(): + var num_face_verts = face_len_list[face_index] +# if num_face_verts < 3: +# continue + + var face_corners_local:Array[int] = [] + for i in num_face_verts: + var face_corner_index:int = face_corners.size() + var face_corner:FaceCornerInfo = FaceCornerInfo.new(face_corner_index, index_list[vertex_index_offset], face_index) + face_corners.append(face_corner) + face_corners_local.append(face_corner_index) + vertex_index_offset += 1 + + var face:FaceInfo = FaceInfo.new(face_index, face_corners_local) + faces.append(face) + + #Calc normal + var fc0:FaceCornerInfo = face_corners[face_corners_local[0]] +# var vidx0 = fc0.vertex_index + var p0:Vector3 = vertices[fc0.vertex_index].point +# + var weighted_normal:Vector3 + for i in range(1, num_face_verts - 1): + var fc1:FaceCornerInfo = face_corners[face_corners_local[i]] + var fc2:FaceCornerInfo = face_corners[face_corners_local[i + 1]] +# var vidx1 = fc1.vertex_index +# var vidx2 = fc2.vertex_index + var p1:Vector3 = vertices[fc1.vertex_index].point + var p2:Vector3 = vertices[fc2.vertex_index].point + + var v1:Vector3 = p1 - p0 + var v2:Vector3 = p2 - p0 + weighted_normal += v2.cross(v1) + + face.normal = weighted_normal.normalized() + + #Calculate edges + for face in faces: + var num_corners = face.face_corner_indices.size() + for i0 in num_corners: + var i1:int = wrap(i0 + 1, 0, num_corners) + var fc0:FaceCornerInfo = face_corners[face.face_corner_indices[i0]] + var fc1:FaceCornerInfo = face_corners[face.face_corner_indices[i1]] + + var edge:EdgeInfo = get_edge(fc0.vertex_index, fc1.vertex_index) + if !edge: + var edge_idx = edges.size() + edge = EdgeInfo.new(edge_idx, fc0.vertex_index, fc1.vertex_index) + edges.append(edge) + + var v0:VertexInfo = vertices[fc0.vertex_index] + v0.edge_indices.append(edge_idx) + + var v1:VertexInfo = vertices[fc1.vertex_index] + v1.edge_indices.append(edge_idx) + + edge.face_indices.append(face.index) + + +func get_edge(vert_idx0:int, vert_idx1:int)->EdgeInfo: + for e in edges: + if e.start_index == vert_idx0 && e.end_index == vert_idx1: + return e + if e.start_index == vert_idx1 && e.end_index == vert_idx0: + return e + return null + + +func init_block_data(block:BlockData): + clear_lists() + + for i in block.points.size(): + var v:VertexInfo = VertexInfo.new(i, block.points[i]) + vertices.append(v) + + if i == 0: + bounds = AABB(v.point, Vector3.ZERO) + else: + bounds = bounds.expand(v.point) + + var corner_index_offset:int = 0 + for face_index in block.face_vertex_count.size(): + var num_face_verts = block.face_vertex_count[face_index] + + var face_corners_local:Array[int] = [] + for i in num_face_verts: + var vertex_index = block.face_vertex_indices[corner_index_offset] + + var face_corner:FaceCornerInfo = FaceCornerInfo.new(corner_index_offset, vertex_index, face_index) + face_corner.uv = block.uvs[corner_index_offset] + face_corners.append(face_corner) + face_corners_local.append(corner_index_offset) + corner_index_offset += 1 + + var face:FaceInfo = FaceInfo.new(face_index, face_corners_local) + face.material_index = block.face_material_indices[face_index] + faces.append(face) + + #Calc normal + var fc0:FaceCornerInfo = face_corners[face_corners_local[0]] + var p0:Vector3 = vertices[fc0.vertex_index].point +# + var weighted_normal:Vector3 + for i in range(1, num_face_verts - 1): + var fc1:FaceCornerInfo = face_corners[face_corners_local[i]] + var fc2:FaceCornerInfo = face_corners[face_corners_local[i + 1]] + var p1:Vector3 = vertices[fc1.vertex_index].point + var p2:Vector3 = vertices[fc2.vertex_index].point + + var v1:Vector3 = p1 - p0 + var v2:Vector3 = p2 - p0 + weighted_normal += v2.cross(v1) + + face.normal = weighted_normal.normalized() + + #Calculate edges + for face in faces: + var num_corners = face.face_corner_indices.size() + for i0 in num_corners: + var i1:int = wrap(i0 + 1, 0, num_corners) + var fc0:FaceCornerInfo = face_corners[face.face_corner_indices[i0]] + var fc1:FaceCornerInfo = face_corners[face.face_corner_indices[i1]] + + var edge:EdgeInfo = get_edge(fc0.vertex_index, fc1.vertex_index) + if !edge: + var edge_idx = edges.size() + edge = EdgeInfo.new(edge_idx, fc0.vertex_index, fc1.vertex_index) + edges.append(edge) + + var v0:VertexInfo = vertices[fc0.vertex_index] + v0.edge_indices.append(edge_idx) + + var v1:VertexInfo = vertices[fc1.vertex_index] + v1.edge_indices.append(edge_idx) + + edge.face_indices.append(face.index) + + +func to_block_data()->BlockData: + var block:BlockData = preload("res://addons/cyclops_level_builder/resources/block_data.gd").new() +# var block:BlockData = BlockData.new() + + for v in vertices: + block.points.append(v.point) + + for f in faces: + block.face_vertex_count.append(f.face_corner_indices.size()) + block.face_material_indices.append(f.material_index) + + for fc_idx in f.face_corner_indices: + var fc:FaceCornerInfo = face_corners[fc_idx] + block.face_vertex_indices.append(fc.vertex_index) + block.uvs.append(fc.uv) + + return block + +func append_mesh(mesh:ImmediateMesh, material:Material, color:Color = Color.WHITE): + + for face in faces: + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, material) +# print("face %s" % face.index) + + mesh.surface_set_normal(face.normal) + + var num_corners:int = face.face_corner_indices.size() + for i in num_corners: + var idx = (i + 1) / 2 if i & 1 else wrap(num_corners - (i / 2), 0, num_corners) + var fc:FaceCornerInfo = face_corners[face.face_corner_indices[idx]] + + mesh.surface_set_color(color) + mesh.surface_set_uv(fc.uv) + mesh.surface_add_vertex(vertices[fc.vertex_index].point) +# print ("%s %s %s" % [idx, fc.vertex_index, control_mesh.vertices[fc.vertex_index].point]) + + mesh.surface_end() + +func triplanar_unwrap(scale:float = 1): + for fc in face_corners: + var v:VertexInfo = vertices[fc.vertex_index] + var f:FaceInfo = faces[fc.face_index] + + if abs(f.normal.x) > abs(f.normal.y) && abs(f.normal.x) > abs(f.normal.z): + fc.uv = Vector2(v.point.y, v.point.z) * scale + elif abs(f.normal.y) > abs(f.normal.z): + fc.uv = Vector2(v.point.x, v.point.z) * scale + else: + fc.uv = Vector2(v.point.x, v.point.y) * scale + + +func get_face_points(face:FaceInfo)->PackedVector3Array: + var points:PackedVector3Array + for fc_idx in face.face_corner_indices: + var fc:FaceCornerInfo = face_corners[fc_idx] + points.append(vertices[fc.vertex_index].point) + return points + +func triangulate_face(face:FaceInfo)->PackedVector3Array: + var points:PackedVector3Array = get_face_points(face) + return MathUtil.trianglate_face(points, face.normal) + + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + if bounds.intersects_ray(origin, dir) == null: + return null + + var best_result:IntersectResults + + for f in faces: + var tris:PackedVector3Array = triangulate_face(f) + for i in range(0, tris.size(), 3): + var p0:Vector3 = tris[i] + var p1:Vector3 = tris[i + 1] + var p2:Vector3 = tris[i + 2] + + #Godot uses clockwise winding + var tri_area_x2:Vector3 = MathUtil.triangle_area_x2(p0, p1, p2) + + var p_hit:Vector3 = MathUtil.intersect_plane(origin, dir, p0, tri_area_x2) + if !p_hit.is_finite(): + continue + + if MathUtil.triangle_area_x2(p_hit, p0, p1).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p1, p2).dot(tri_area_x2) < 0: + continue + if MathUtil.triangle_area_x2(p_hit, p2, p0).dot(tri_area_x2) < 0: + continue + + #Intersection + var dist_sq:float = (origin - p_hit).length_squared() + if !best_result || best_result.distance_squared > dist_sq: + + var result:IntersectResults = IntersectResults.new() + result.face_index = f.index + result.normal = f.normal + result.position = p_hit + result.distance_squared = dist_sq + + best_result = result + + return best_result + +func translate(offset:Vector3): + for v in vertices: + v.point += offset + +func dump(): + print ("Verts") + for v in vertices: + print(v.to_string()) + print ("Edges") + for e in edges: + print(e.to_string()) + print ("Faces") + for f in faces: + print(f.to_string()) + print ("Face Corners") + for f in face_corners: + print(f.to_string()) diff --git a/addons/cyclops_level_builder/math/geometry_mesh.gd b/addons/cyclops_level_builder/math/geometry_mesh.gd new file mode 100644 index 0000000..7d96ffe --- /dev/null +++ b/addons/cyclops_level_builder/math/geometry_mesh.gd @@ -0,0 +1,63 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +#extends RefCounted +class_name GeometryMesh + +var coords:PackedVector3Array +var normals:PackedVector3Array +var uvs:PackedVector2Array + +func transform(xform:Transform3D)->GeometryMesh: + var result:GeometryMesh = GeometryMesh.new() + + var basis:Basis = xform.basis + basis = basis.inverse() + basis = basis.transposed() + + for i in coords.size(): + result.coords.append(xform * coords[i]) + result.uvs.append(uvs[i]) + result.normals.append(basis * normals[i]) + + return result + +func append_to_immediate_mesh(mesh:ImmediateMesh, material:Material, xform:Transform3D = Transform3D.IDENTITY): + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES, material) + + var basis:Basis = xform.basis + basis = basis.inverse() + basis = basis.transposed() + + for i in coords.size(): + var normal:Vector3 = basis * normals[i] + var coord:Vector3 = xform * coords[i] + var uv:Vector2 = uvs[i] + + mesh.surface_set_normal(normal) + mesh.surface_set_uv(uv) + mesh.surface_add_vertex(coord) + + mesh.surface_end() + diff --git a/addons/cyclops_level_builder/math/math_geometry.gd b/addons/cyclops_level_builder/math/math_geometry.gd new file mode 100644 index 0000000..68c0c64 --- /dev/null +++ b/addons/cyclops_level_builder/math/math_geometry.gd @@ -0,0 +1,166 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +#extends RefCounted +class_name MathGeometry + + +static func unit_cylinder(segs:int = 16, radius0:float = 1, radius1:float = 1, top_height:float = 1, bottom_height:float = -1, bottom_cap:bool = false, top_cap:bool = false)->GeometryMesh: + var mesh:GeometryMesh = GeometryMesh.new() + + + var vc0:Vector3 = Vector3(0, 0, -1) + var vc1:Vector3 = Vector3(0, 0, 1) + var uvc:Vector2 = Vector2(.5, .5) + + for s in range(segs): + + var sin0:float = sin(deg_to_rad(360 * s / segs)) + var cos0:float = cos(deg_to_rad(360 * s / segs)) + var sin1:float = sin(deg_to_rad(360 * (s + 1) / segs)) + var cos1:float = cos(deg_to_rad(360 * (s + 1) / segs)) + + var v00:Vector3 = Vector3(sin0 * radius0, cos0 * radius0, bottom_height) + var v10:Vector3 = Vector3(sin1 * radius0, cos1 * radius0, bottom_height) + var v01:Vector3 = Vector3(sin0 * radius1, cos0 * radius1, top_height) + var v11:Vector3 = Vector3(sin1 * radius1, cos1 * radius1, top_height) + + var tan0:Vector3 = Vector3(cos0, sin0, 0) + var n00:Vector3 = (v01 - v00).cross(tan0) + n00 = n00.normalized() + var n01:Vector3 = n00 + var tan1:Vector3 = Vector3(cos1, sin1, 0) + var n10:Vector3 = (v11 - v10).cross(tan1) + n10 = n10.normalized() + var n11 = n10 + + var uv00:Vector2 = Vector2(s / segs, 0) + var uv10:Vector2 = Vector2((s + 1) / segs, 0) + var uv01:Vector2 = Vector2(s / segs, 1) + var uv11:Vector2 = Vector2((s + 1) / segs, 1) + + if radius0 != 0: + mesh.coords.append(v00) + mesh.coords.append(v10) + mesh.coords.append(v11) + + mesh.normals.append(n00) + mesh.normals.append(n10) + mesh.normals.append(n11) + + mesh.uvs.append(uv00) + mesh.uvs.append(uv10) + mesh.uvs.append(uv11) + + if radius1 != 0: + mesh.coords.append(v00) + mesh.coords.append(v11) + mesh.coords.append(v01) + + mesh.normals.append(n00) + mesh.normals.append(n11) + mesh.normals.append(n01) + + mesh.uvs.append(uv00) + mesh.uvs.append(uv11) + mesh.uvs.append(uv01) + + if top_cap and radius1 != 0: + mesh.coords.append(v01) + mesh.coords.append(v11) + mesh.coords.append(vc1) + + mesh.normals.append(Vector3(0, 0, 1)) + mesh.normals.append(Vector3(0, 0, 1)) + mesh.normals.append(Vector3(0, 0, 1)) + + mesh.uvs.append(Vector2(sin0, cos0)) + mesh.uvs.append(Vector2(sin1, cos1)) + mesh.uvs.append(uvc) + + if bottom_cap and radius0 != 0: + mesh.coords.append(v00) + mesh.coords.append(v10) + mesh.coords.append(vc0) + + mesh.normals.append(-Vector3(0, 0, 1)) + mesh.normals.append(-Vector3(0, 0, 1)) + mesh.normals.append(-Vector3(0, 0, 1)) + + mesh.uvs.append(Vector2(sin0, cos0)) + mesh.uvs.append(Vector2(sin1, cos1)) + mesh.uvs.append(uvc) + + + return mesh + +static func unit_sphere(segs_lat:int = 6, segs_long:int = 8)->GeometryMesh: + var mesh:GeometryMesh = GeometryMesh.new() + + for la in range(segs_lat): + + var z0:float = cos(deg_to_rad(180 * la / segs_lat)) + var z1:float = cos(deg_to_rad(180 * (la + 1) / segs_lat)) + var r0:float = sin(deg_to_rad(180 * la / segs_lat)) + var r1:float = sin(deg_to_rad(180 * (la + 1) / segs_lat)) + + for lo in range(segs_long): + var cx0:float = sin(deg_to_rad(360 * lo / segs_long)) + var cx1:float = sin(deg_to_rad(360 * (lo + 1) / segs_long)) + var cy0:float = cos(deg_to_rad(360 * lo / segs_long)) + var cy1:float = cos(deg_to_rad(360 * (lo + 1) / segs_long)) + + var v00:Vector3 = Vector3(cx0 * r0, cy0 * r0, z0) + var v10:Vector3 = Vector3(cx1 * r0, cy1 * r0, z0) + var v01:Vector3 = Vector3(cx0 * r1, cy0 * r1, z1) + var v11:Vector3 = Vector3(cx1 * r1, cy1 * r1, z1) + + if la != 0: + mesh.coords.append(v00) + mesh.coords.append(v11) + mesh.coords.append(v10) + + mesh.normals.append(v00) + mesh.normals.append(v10) + mesh.normals.append(v10) + + mesh.uvs.append(Vector2(lo / segs_long, la / segs_lat)) + mesh.uvs.append(Vector2((lo + 1) / segs_long, la / segs_lat)) + mesh.uvs.append(Vector2((lo + 1) / segs_long, (la + 1) / segs_lat)) + + if la != segs_lat - 1: + mesh.coords.append(v00) + mesh.coords.append(v01) + mesh.coords.append(v11) + + mesh.normals.append(v00) + mesh.normals.append(v01) + mesh.normals.append(v11) + + mesh.uvs.append(Vector2(lo / segs_long, la / segs_lat)) + mesh.uvs.append(Vector2((lo + 1) / segs_long, (la + 1) / segs_lat)) + mesh.uvs.append(Vector2(lo / segs_long, (la + 1) / segs_lat)) + + return mesh + diff --git a/addons/cyclops_level_builder/math/math_util.gd b/addons/cyclops_level_builder/math/math_util.gd new file mode 100644 index 0000000..b6c2e8a --- /dev/null +++ b/addons/cyclops_level_builder/math/math_util.gd @@ -0,0 +1,537 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name MathUtil + +enum Axis { X, Y, Z } + +static func square(value:float)->float: + return value * value + +static func snap_to_grid(pos:Vector3, cell_size:float)->Vector3: +# return floor(pos / cell_size) * cell_size + return floor((pos + Vector3(cell_size, cell_size, cell_size) / 2) / cell_size) * cell_size + + +#Returns intersection of line with point. +# plane_perp_dir points in direction of plane's normal and does not need to be normalized +static func intersect_plane(ray_origin:Vector3, ray_dir:Vector3, plane_origin:Vector3, plane_perp_dir:Vector3)->Vector3: + var s:float = (plane_origin - ray_origin).dot(plane_perp_dir) / ray_dir.dot(plane_perp_dir) + return ray_origin + ray_dir * s + +#Returns the closest point on the line to the ray +static func closest_point_on_line(ray_origin:Vector3, ray_dir:Vector3, line_origin:Vector3, line_dir:Vector3)->Vector3: + var a:Vector3 = ray_dir.cross(line_dir) + var w_perp:Vector3 = ray_dir.cross(a) + return intersect_plane(line_origin, line_dir, ray_origin, w_perp) + +static func closest_point_on_segment(ray_origin:Vector3, ray_dir:Vector3, seg_start:Vector3, seg_end:Vector3)->Vector3: + var seg_span:Vector3 = seg_end - seg_start + var p:Vector3 = closest_point_on_line(ray_origin, ray_dir, seg_start, seg_span) + var offset:Vector3 = p - seg_start + if offset.dot(seg_span) < 0: + return seg_start + if offset.length_squared() > seg_span.length_squared(): + return seg_end + return p + +#Shortest distance from point to given ray. Returns NAN if point is behind origin of ray. +static func distance_to_ray(ray_origin:Vector3, ray_dir:Vector3, point:Vector3): + var offset = point - ray_origin + var parallel:Vector3 = offset.project(ray_dir) + if parallel.dot(ray_dir) < 0: + return NAN + + var perp:Vector3 = offset - parallel + return perp.length() + + +static func trianglate_face(points:PackedVector3Array, normal:Vector3)->PackedVector3Array: + var result:PackedVector3Array + + while (points.size() >= 3): + var num_points:int = points.size() + for i in range(0, num_points): + var p0:Vector3 = points[i] + var p1:Vector3 = points[wrap(i + 1, 0, num_points)] + var p2:Vector3 = points[wrap(i + 2, 0, num_points)] + + #Godot uses clockwise winding + var tri_norm_dir:Vector3 = (p2 - p0).cross(p1 - p0) + if tri_norm_dir.dot(normal) > 0: + result.append(p0) + result.append(p1) + result.append(p2) + + points.remove_at(i + 1) + break + + return result + +static func trianglate_face_indices(points:PackedVector3Array, indices:Array[int], normal:Vector3)->Array[int]: + var result:Array[int] = [] + +# print("trianglate_face_indices %s" % points) + + while (points.size() >= 3): + var num_points:int = points.size() + var added_point:bool = false + + for i in range(0, num_points): + var idx0:int = i + var idx1:int = wrap(i + 1, 0, num_points) + var idx2:int = wrap(i + 2, 0, num_points) + var p0:Vector3 = points[idx0] + var p1:Vector3 = points[idx1] + var p2:Vector3 = points[idx2] + + #Godot uses clockwise winding + var tri_norm_dir:Vector3 = (p2 - p0).cross(p1 - p0) + if tri_norm_dir.dot(normal) > 0: + result.append(indices[idx0]) + result.append(indices[idx1]) + result.append(indices[idx2]) + +# print("adding indices %s %s %s" % [indices[idx0], indices[idx1], indices[idx2]]) + + points.remove_at(idx1) + indices.remove_at(idx1) + added_point = true + break + + assert(added_point, "failed to add point in triangulation") +# print("tri_done %s" % str(result)) + + return result + +static func trianglate_face_vertex_indices(points:PackedVector3Array, normal:Vector3)->Array[int]: + var result:Array[int] = [] + var fv_indices:Array = range(0, points.size()) +# print("trianglate_face_indices %s" % points) + + while (points.size() >= 3): + var num_points:int = points.size() + var added_point:bool = false + + for i in range(0, num_points): + var idx0:int = i + var idx1:int = wrap(i + 1, 0, num_points) + var idx2:int = wrap(i + 2, 0, num_points) + var p0:Vector3 = points[idx0] + var p1:Vector3 = points[idx1] + var p2:Vector3 = points[idx2] + + #Godot uses clockwise winding + var tri_norm_dir:Vector3 = (p2 - p0).cross(p1 - p0) + if tri_norm_dir.dot(normal) > 0: + result.append(fv_indices[idx0]) + result.append(fv_indices[idx1]) + result.append(fv_indices[idx2]) + +# print("adding indices %s %s %s" % [indices[idx0], indices[idx1], indices[idx2]]) + + points.remove_at(idx1) + fv_indices.remove_at(idx1) + added_point = true + break + + assert(added_point, "failed to add point in triangulation") +# print("tri_done %s" % str(result)) + + return result + +static func flip_plane(plane:Plane)->Plane: + return Plane(-plane.normal, plane.get_center()) + +#Returns a vector pointing along the normal in the clockwise winding direction with a length equal to twice the area of the triangle +static func triangle_area_x2(p0:Vector3, p1:Vector3, p2:Vector3)->Vector3: + return (p2 - p0).cross(p1 - p0) + +#Returns a vector pointing along the normal in the clockwise winding direction with a lengh equal to twice the area of the face +static func face_area_x2(points:PackedVector3Array)->Vector3: + if points.size() <= 1: + return Vector3.ZERO + + var result:Vector3 + var p0:Vector3 = points[0] + + for i in range(1, points.size() - 1): + var p1:Vector3 = points[i] + var p2:Vector3 = points[i + 1] + + result += (p2 - p0).cross(p1 - p0) + + return result + +static func face_area_x2_2d(points:PackedVector2Array)->float: + if points.size() <= 1: + return 0 + + var result:float + var p0:Vector2 = points[0] + + for i in range(1, points.size() - 1): + var p1:Vector2 = points[i] + var p2:Vector2 = points[i + 1] + + result += triange_area_2x_2d(p1 - p0, p2 - p0) + + return result + +static func fit_plane(points:PackedVector3Array)->Plane: + var normal:Vector3 = face_area_x2(points).normalized() + return Plane(normal, points[0]) + +static func snap_to_best_axis_normal(vector:Vector3)->Vector3: + if abs(vector.x) > abs(vector.y) and abs(vector.x) > abs(vector.z): + return Vector3(1, 0, 0) if vector.x > 0 else Vector3(-1, 0, 0) + elif abs(vector.y) > abs(vector.z): + return Vector3(0, 1, 0) if vector.y > 0 else Vector3(0, -1, 0) + else: + return Vector3(0, 0, 1) if vector.z > 0 else Vector3(0, 0, -1) + +static func get_longest_axis(vector:Vector3)->Axis: + if abs(vector.x) > abs(vector.y) and abs(vector.x) > abs(vector.z): + return Axis.X + elif abs(vector.y) > abs(vector.z): + return Axis.Y + else: + return Axis.Z + +static func calc_bounds(points:PackedVector3Array)->AABB: + if points.is_empty(): + return AABB(Vector3.ZERO, Vector3.ZERO) + + var result:AABB = AABB(points[0], Vector3.ZERO) + for i in range(1, points.size()): + result = result.expand(points[i]) + return result + +#Returns value equal to twise the area between the two vectors. Clockwise windings have negative area +static func triange_area_2x_2d(a:Vector2, b:Vector2)->float: + return a.x * b.y - a.y * b.x + +#Finds the bouding polygons of this set of points with a clockwise winding +static func bounding_polygon_2d(base_points:PackedVector2Array)->PackedVector2Array: + if base_points.size() <= 2: + return base_points + + + #Start with leftmost vertex, topmost if more than one + var p_init:Vector2 = base_points[0] + for p in base_points: + if p.x < p_init.x or (p.x == p_init.x and p.y > p_init.y): + p_init = p + + + var p_cur:Vector2 = p_init + var last_segment_dir = Vector2(0, 1) + + var polygon:PackedVector2Array + + while true: + var best_point:Vector2 + var best_dir:Vector2 + var best_angle:float = 0 + + for p in base_points: + if p.is_equal_approx(p_cur): + continue + + var point_dir:Vector2 = (p - p_cur).normalized() + var angle:float = acos(-last_segment_dir.dot(point_dir)) + + if angle > best_angle or (angle == best_angle and p_cur.distance_squared_to(p) > p_cur.distance_squared_to(best_point)): + best_point = p + best_dir = point_dir + best_angle = angle + + p_cur = best_point + last_segment_dir = best_dir + polygon.append(best_point) + + if best_point.is_equal_approx(p_init): + break + + return polygon + +#static func bounding_polygon(base_points:PackedVector3Array, plane:Plane)->PackedVector3Array: +static func bounding_polygon_3d(base_points:PackedVector3Array, normal:Vector3)->PackedVector3Array: + if base_points.size() <= 2: + return base_points + + var quat:Quaternion = Quaternion(normal, Vector3.FORWARD) + +# var xform:Transform3D = Transform3D(Basis(quat), -base_points[0]) + var xform:Transform3D = Transform3D(Basis(quat)) + xform = xform.translated_local(-base_points[0]) + var xform_inv = xform.inverse() + + #print("xform %s" % xform) + + var points_local:PackedVector2Array + + for p in base_points: + var p_local = xform * p + points_local.append(Vector2(p_local.x, p_local.y)) + + var points_bounds:PackedVector2Array = bounding_polygon_2d(points_local) + + var result:PackedVector3Array + for p in points_bounds: + var p_result = xform_inv * Vector3(p.x, p.y, 0) + result.append(p_result) + + return result + +static func points_are_colinear(points:PackedVector3Array)->bool: + if points.size() <= 2: + return true + + var p0:Vector3 = points[0] + var p1:Vector3 = p0 + var index:int = 0 + for i in range(1, points.size()): + if !points[i].is_equal_approx(p0): + p1 = points[i] + index = i + break + + if index == 0: + return true + + var v10:Vector3 = p1 - p0 + for i in range(index + 1, points.size()): + if !triangle_area_x2(p0, p1, points[i]).is_zero_approx(): + return false + + return true + + +static func furthest_point_from_line(line_origin:Vector3, line_dir:Vector3, points:PackedVector3Array)->Vector3: + var best_point:Vector3 + var best_dist:float = 0 + + for p in points: + var offset:Vector3 = p - line_origin + var along:Vector3 = offset.project(line_dir) + var perp:Vector3 = offset - along + var dist:float = perp.length_squared() + if dist > best_dist: + best_dist = dist + best_point = p + + return best_point + +static func furthest_point_from_plane(plane:Plane, points:PackedVector3Array)->Vector3: + var best_point:Vector3 + var best_distance:float = 0 + + for p in points: + var dist = abs(plane.distance_to(p)) + if dist > best_distance: + best_point = p + best_distance = dist + + return best_point + +static func planar_volume_contains_point(planes:Array[Plane], point:Vector3)->bool: +# print("candidate %s" % point) + + for p in planes: + var is_over:bool = p.is_point_over(point) + var is_on:bool = p.has_point(point) + if !is_over && !is_on: +# print("reject by %s" % p) + return false +# print("passed %s" % point) + return true + +static func get_convex_hull_points_from_planes(planes:Array[Plane])->Array[Vector3]: + #Check for overlapping planes + for i0 in range(0, planes.size()): + for i1 in range(i0 + 1, planes.size()): + var p0:Plane = planes[i0] + var p1:Plane = flip_plane(planes[i1]) + if p0.is_equal_approx(p1): + return [] + + var points:Array[Vector3] + + for i0 in range(0, planes.size()): + for i1 in range(i0 + 1, planes.size()): + for i2 in range(i1 + 1, planes.size()): + var result = planes[i0].intersect_3(planes[i1], planes[i2]) + + if result == null: + continue + #print("candidate %s" % result) + if !planar_volume_contains_point(planes, result): + continue + if points.any(func(p):return p.is_equal_approx(result)): + continue + #print("adding %s" % result) + points.append(result) + + return points + +static func dist_to_segment_squared_2d(point:Vector2, seg_start:Vector2, seg_end:Vector2)->float: + var dist_sq_p0:float = point.distance_squared_to(seg_start) + var dist_sq_p1:float = point.distance_squared_to(seg_end) + var seg_span:Vector2 = seg_end - seg_start + + var offset:Vector2 = point - seg_start + var offset_proj:Vector2 = offset.project(seg_span) + var perp_dist_sq:float = (offset - offset_proj).length_squared() + + if seg_span.dot(offset) < 0: + return dist_sq_p0 + elif offset_proj.length_squared() > seg_span.length_squared(): + return dist_sq_p1 + return perp_dist_sq + +class Segment2d extends RefCounted: + var p0:Vector2 + var p1:Vector2 + + func _init(p0:Vector2, p1:Vector2): + self.p0 = p0 + self.p1 = p1 + + func reverse()->Segment2d: + return Segment2d.new(p1, p0) + + func _to_string(): + return "[%s %s]" % [p0, p1] + +static func extract_loop_2d(seg_stack:Array[Segment2d])->PackedVector2Array: + var segs_sorted:Array[Segment2d] = [] + var prev_seg = seg_stack.pop_back() + segs_sorted.append(prev_seg) + + while !seg_stack.is_empty(): + var found_seg:bool = false + for s_idx in seg_stack.size(): + var cur_seg:Segment2d = seg_stack[s_idx] + + if cur_seg.p0.is_equal_approx(prev_seg.p1): +# print("matching %s with %s" % [prev_seg, cur_seg]) + segs_sorted.append(cur_seg) + seg_stack.remove_at(s_idx) + prev_seg = cur_seg + found_seg = true + break + elif cur_seg.p1.is_equal_approx(prev_seg.p1): +# print("matching %s with %s" % [prev_seg, cur_seg]) + cur_seg = cur_seg.reverse() + segs_sorted.append(cur_seg) + seg_stack.remove_at(s_idx) + prev_seg = cur_seg + found_seg = true + break + + if !found_seg: +# push_warning("loop not continuous") + break + +# print("segs_sorted %s" % str(segs_sorted)) + + var result:PackedVector2Array + for s in segs_sorted: + result.append(s.p0) + + if face_area_x2_2d(result) < 0: + result.reverse() + + return result + +static func get_loops_from_segments_2d(segments:PackedVector2Array)->Array[PackedVector2Array]: + #print("segments %s" % segments) + var loops:Array[PackedVector2Array] = [] + + var seg_stack:Array[Segment2d] = [] + for i in range(0, segments.size(), 2): + seg_stack.append(Segment2d.new(segments[i], segments[i + 1])) + +# print("segs %s" % str(seg_stack)) + + while !seg_stack.is_empty(): + var loop:PackedVector2Array = extract_loop_2d(seg_stack) + loops.append(loop) + +# print("result %s" % str(result)) + return loops + +static func create_transform(translation:Vector3, rotation_axis:Vector3, rotation_angle:float, scale:Vector3, pivot:Vector3)->Transform3D: + var xform:Transform3D = Transform3D.IDENTITY + + xform = xform.translated_local(pivot + translation) + xform = xform.rotated_local(rotation_axis, rotation_angle) + xform = xform.scaled_local(scale) + xform = xform.translated_local(-pivot) + + return xform + +static func create_circle_points(center:Vector3, normal:Vector3, radius:float, num_segments:int)->PackedVector3Array: + var result:PackedVector3Array + + var axis:Axis = get_longest_axis(normal) + var perp_normal:Vector3 + match axis: + Axis.X: + perp_normal = normal.cross(Vector3.UP) + Axis.Y: + perp_normal = normal.cross(Vector3.FORWARD) + Axis.Z: + perp_normal = normal.cross(Vector3.UP) + + var angle_incrment = (PI * 2 / num_segments) + for i in num_segments: + var offset:Vector3 = perp_normal.rotated(normal, i * angle_incrment) + result.append(offset * radius + center) + + return result + +static func get_axis_aligned_tangent_and_binormal(normal:Vector3)->Array[Vector3]: + var axis:MathUtil.Axis = MathUtil.get_longest_axis(normal) + #calc tangent and binormal + var u_normal:Vector3 + var v_normal:Vector3 + match axis: + MathUtil.Axis.Y: + u_normal = normal.cross(Vector3.FORWARD) + v_normal = u_normal.cross(normal) + return [u_normal, v_normal] + MathUtil.Axis.X: + u_normal = normal.cross(Vector3.UP) + v_normal = u_normal.cross(normal) + return [u_normal, v_normal] + MathUtil.Axis.Z: + u_normal = normal.cross(Vector3.UP) + v_normal = u_normal.cross(normal) + return [u_normal, v_normal] + + return [] + + diff --git a/addons/cyclops_level_builder/math/quick_hull.gd b/addons/cyclops_level_builder/math/quick_hull.gd new file mode 100644 index 0000000..fc08316 --- /dev/null +++ b/addons/cyclops_level_builder/math/quick_hull.gd @@ -0,0 +1,360 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name QuickHull + +class DirectedEdge extends RefCounted: + var p0:Vector3 + var p1:Vector3 + + func _init(p0:Vector3, p1:Vector3): + self.p0 = p0 + self.p1 = p1 + + func _to_string()->String: + return "%s %s" % [p0, p1] + + func reverse()->DirectedEdge: + return DirectedEdge.new(p1, p0) + + func equals(e:DirectedEdge)->bool: + return p0 == e.p0 && p1 == e.p1 + +class Facet extends RefCounted: + var plane:Plane + var points:PackedVector3Array #Clockwise winding faces out + var over_points:PackedVector3Array + + func _to_string(): + var result:String = "plane %s\ncentroid %s\npoints %s\nover %s" % [plane, (points[0] + points[1] + points[2])/3, points, over_points] + + return result + + func has_edge(e:DirectedEdge)->bool: + return (points[0] == e.p0 && points[1] == e.p1) || \ + (points[1] == e.p0 && points[2] == e.p1) || \ + (points[2] == e.p0 && points[0] == e.p1) + + func get_edges()->Array[DirectedEdge]: + var result:Array[DirectedEdge] = [] + + result.append(DirectedEdge.new(points[0], points[1])) + result.append(DirectedEdge.new(points[1], points[2])) + result.append(DirectedEdge.new(points[2], points[0])) + return result + + func init_from_points(p0:Vector3, p1:Vector3, p2:Vector3): + #Facet normal points to outside + plane = Plane(p0, p1, p2) + points = [p0, p1, p2] + + #Create a facet with vertices at p0, p1, p2 and winding such that under_ref + # is on the under side of the plane + func init_from_points_under(p0:Vector3, p1:Vector3, p2:Vector3, under_ref:Vector3): + #Facet normal points to outside + plane = Plane(p0, p1, p2) + if plane.is_point_over(under_ref): + plane = Plane(p0, p2, p1) + points = [p0, p2, p1] + else: + points = [p0, p1, p2] + + func get_furthest_point()->Vector3: + var best_point:Vector3 + var best_distance:float = 0 + + for p in over_points: + var dist = abs(plane.distance_to(p)) + if dist > best_distance: + best_point = p + best_distance = dist + + return best_point + +class Hull extends RefCounted: + var facets:Array[Facet] = [] + + func get_non_empty_facet()->Facet: + for f in facets: + if !f.over_points.is_empty(): + return f + return null + + func get_facet_with_edge(e:DirectedEdge)->Facet: + for f in facets: + if f.has_edge(e): + return f + return null + + func _to_string(): + var result:String = "" + for f in facets: + result += "%s\n" % f + return result + + + func get_points()->Array[Vector3]: + var result:Array[Vector3] + + for f in facets: + for p in f.points: + if !result.any(func(pl):return pl.is_equal_approx(p)): + result.append(p) + + return result + + func format_points()->String: + var result:String = "" + for f in facets: + result += "%s,\n" % f.points + return result + + +static func form_loop(edges:Array[DirectedEdge])->PackedVector3Array: + var sorted:Array[DirectedEdge] = [] + + var cur_edge:DirectedEdge = edges.pop_back() + sorted.append(cur_edge) + + while !edges.is_empty(): + var found_edge:bool = false + for i in edges.size(): + var e:DirectedEdge = edges[i] + if e.p0.is_equal_approx(cur_edge.p1): + edges.remove_at(i) + cur_edge = e + sorted.append(e) + found_edge = true + break + + if !found_edge: + assert(found_edge, "Unable to complete loop") + pass +# if !found_edge: +# assert(false, "Unable to complete loop") +# return PackedVector3Array() + + var result:PackedVector3Array + for e in sorted: + result.append(e.p0) + return result + +static func merge_coplanar_facets(hull:Hull)->Hull: +# print("hull %s " % hull) + #print("hull %s " % hull.format_points()) + + var new_hull:Hull = Hull.new() + var already_seen:Array[Facet] = [] + + for facet_idx in hull.facets.size(): + var facet:Facet = hull.facets[facet_idx] + if already_seen.has(facet): + continue + already_seen.append(facet) + + #print("merging facet %s" % facet) + + var neighbor_set:Array[Facet] = [] + neighbor_set.append(facet) + var boundary:Array[DirectedEdge] = [] + + while !neighbor_set.is_empty(): + var cur_facet:Facet = neighbor_set.pop_back() + var edges:Array[DirectedEdge] = cur_facet.get_edges() + + for e in edges: + var neighbor:Facet = hull.get_facet_with_edge(e.reverse()) + if neighbor.plane.is_equal_approx(facet.plane): + if !already_seen.has(neighbor): + already_seen.append(neighbor) + neighbor_set.append(neighbor) + else: + boundary.append(e) + + + var points:PackedVector3Array = form_loop(boundary) + + var nf:Facet = Facet.new() + nf.plane = facet.plane + nf.points = points + new_hull.facets.append(nf) + + return new_hull + + +static func create_initial_simplex(points:PackedVector3Array)->Hull: + if points.size() < 4: + return null + + #For first two points, pick furthest apart along one of the axes + var max_x:Vector3 = points[0] + var min_x:Vector3 = points[0] + var max_y:Vector3 = points[0] + var min_y:Vector3 = points[0] + var max_z:Vector3 = points[0] + var min_z:Vector3 = points[0] + + for idx in range(1, points.size()): + var p:Vector3 = points[idx] + if p.x > max_x.x: + max_x = p + if p.x < min_x.x: + min_x = p + if p.y > max_y.y: + max_y = p + if p.y < min_y.y: + min_y = p + if p.z > max_z.z: + max_z = p + if p.z < min_z.z: + min_z = p + + var p0:Vector3 + var p1:Vector3 + var dx:float = max_x.distance_squared_to(min_x) + var dy:float = max_y.distance_squared_to(min_y) + var dz:float = max_z.distance_squared_to(min_z) + + if dx > dy and dx > dz: + p0 = max_x + p1 = min_x + elif dy > dz: + p0 = max_y + p1 = min_y + else: + p0 = max_z + p1 = min_z + + #Find furthest point from line for second point + var p2:Vector3 = MathUtil.furthest_point_from_line(p0, p1 - p0, points) + var p3:Vector3 = MathUtil.furthest_point_from_plane(Plane(p0, p1, p2), points) + + #Make simplex + var hull:Hull = Hull.new() + + var f0:Facet = Facet.new() + f0.init_from_points_under(p1, p2, p3, p0) + var f1:Facet = Facet.new() + f1.init_from_points_under(p2, p3, p0, p1) + var f2:Facet = Facet.new() + f2.init_from_points_under(p3, p0, p1, p2) + var f3:Facet = Facet.new() + f3.init_from_points_under(p0, p1, p2, p3) + + hull.facets.append(f0) + hull.facets.append(f1) + hull.facets.append(f2) + hull.facets.append(f3) + + for p in points: + for f in hull.facets: + if f.plane.is_point_over(p) && !f.plane.has_point(p): + f.over_points.append(p) + + return hull + + +static func quickhull(points:PackedVector3Array)->Hull: + if points.size() < 4: + return null + + var hull:Hull = create_initial_simplex(points) + if !hull: + return null + + #print("initial points %s" % points) + #print("initial simplex %s" % hull.format_points()) + + while true: + var facet:Facet = hull.get_non_empty_facet() + if facet == null: + break + + #print("-facet %s" % facet) + + var p_over:Vector3 = facet.get_furthest_point() + #print("over point %s" % p_over) + + #print("hull %s" % hull.format_points()) + + var visibile_faces:Array[Facet] = [facet] + var edges:Array[DirectedEdge] = facet.get_edges() + var visited_edges:Array[DirectedEdge] = [] + var boundary_edges:Array[DirectedEdge] = [] + +# for e in edges: +# print("init edge search set %s" % e) + + + #Find set of edges that form the boundary of faces visible to point + # being added. We're basically flood filling from central facet until + # we hit faces pointing away from reference point. + while !edges.is_empty(): + var edge:DirectedEdge = edges.pop_back() + visited_edges.append(edge) + var edge_inv:DirectedEdge = edge.reverse() + + var neighbor_facet:Facet = hull.get_facet_with_edge(edge_inv) + if neighbor_facet.plane.is_point_over(p_over): + visibile_faces.append(neighbor_facet) + visited_edges.append(edge_inv) + var neighbor_edges:Array[DirectedEdge] = neighbor_facet.get_edges() + for e in neighbor_edges: + if !visited_edges.any(func(edge): return edge.equals(e)): + #print("adding edge to search set %s" % e) + edges.append(e) + else: + boundary_edges.append(edge) + #print("adding edge to boundary set %s" % edge) + + var remaining_over_points:PackedVector3Array + for f in visibile_faces: + for pf in f.over_points: + if pf == p_over: + continue + if !remaining_over_points.has(pf): + remaining_over_points.append(pf) + #print("over point for test %s" % pf) + + hull.facets.remove_at(hull.facets.find(f)) + + for e in boundary_edges: + var f:Facet = Facet.new() + f.init_from_points(e.p0, e.p1, p_over) + hull.facets.append(f) + + #print("adding facet %s" % f) + + for p in remaining_over_points: + if f.plane.is_point_over(p) && !f.plane.has_point(p): + f.over_points.append(p) + + #print("hull %s" % hull.format_points()) + + hull = merge_coplanar_facets(hull) + return hull + + + diff --git a/addons/cyclops_level_builder/menu/action_popup_menu.gd b/addons/cyclops_level_builder/menu/action_popup_menu.gd new file mode 100644 index 0000000..4ac8a73 --- /dev/null +++ b/addons/cyclops_level_builder/menu/action_popup_menu.gd @@ -0,0 +1,46 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends PopupMenu +class_name ActionPopupMenu + +var action_map:Dictionary = {} + +func _ready(): + id_pressed.connect(on_id_pressed) + +func add_action_item(action:CyclopsAction): +# var id:int = action_map.size() + var id:int = action_map.size() + 1000 + add_item(action.name, id, action.accellerator) + action_map[id] = action + +#func add_separator(label:String, id:int = -1): +# pass + +func on_id_pressed(id:int): + var action:CyclopsAction = action_map[id] + action._execute() + + diff --git a/addons/cyclops_level_builder/menu/editor_toolbar.gd b/addons/cyclops_level_builder/menu/editor_toolbar.gd new file mode 100644 index 0000000..b69d916 --- /dev/null +++ b/addons/cyclops_level_builder/menu/editor_toolbar.gd @@ -0,0 +1,166 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends PanelContainer +class_name EditorToolbar + +var editor_plugin:CyclopsLevelBuilder: + get: + return editor_plugin + set(value): + editor_plugin = value + editor_plugin.active_node_changed.connect(on_active_node_changed) +#var editor_plugin:CyclopsLevelBuilder + +#var action_map:Array[CyclopsAction] + +func on_active_node_changed(): + update_grid() + + +# Called when the node enters the scene tree for the first time. +func _ready(): + $HBoxContainer/grid_size.clear() + $HBoxContainer/grid_size.add_item("1/16", 0) + $HBoxContainer/grid_size.add_item("1/8", 1) + $HBoxContainer/grid_size.add_item("1/4", 2) + $HBoxContainer/grid_size.add_item("1/2", 3) + $HBoxContainer/grid_size.add_item("1", 4) + $HBoxContainer/grid_size.add_item("2", 5) + $HBoxContainer/grid_size.add_item("4", 6) + $HBoxContainer/grid_size.add_item("8", 7) + $HBoxContainer/grid_size.add_item("16", 8) + + $HBoxContainer/MenuBar/Menu.clear() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionToolDuplicate.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMergeSelectedBlocks.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionDeleteSelectedBlocks.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionSnapToGrid.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_separator() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateX90Ccw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateX90Cw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateX180.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMirrorSelectionX2.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_separator() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateY90Ccw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateY90Cw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateY180.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMirrorSelectionY2.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_separator() + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateZ90Ccw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateZ90Cw.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionRotateZ180.new(editor_plugin)) + $HBoxContainer/MenuBar/Menu.add_action_item(ActionMirrorSelectionZ.new(editor_plugin)) + + update_grid() + +func update_grid(): + if !editor_plugin: + return + + if editor_plugin.active_node: + var size:int = editor_plugin.get_global_scene().grid_size + $HBoxContainer/grid_size.select(size + 4) + + $HBoxContainer/display_mode.select(editor_plugin.display_mode) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + + +func _on_grid_size_item_selected(index): +# if Engine.is_editor_hint(): + #print("_on_grid_size_item_selected " + str(index)) + +# if editor_plugin.active_node: + editor_plugin.get_global_scene().grid_size = index - 4 + + +func _on_bn_move_pressed(): + editor_plugin.switch_to_tool(ToolBlock.new()) + + +func _on_bn_clip_pressed(): + editor_plugin.switch_to_tool(ToolClip.new()) + + +func _on_bn_vertex_pressed(): + editor_plugin.switch_to_tool(ToolEditVertex.new()) + + +func _on_bn_edge_pressed(): + editor_plugin.switch_to_tool(ToolEditEdge.new()) + + +func _on_bn_face_pressed(): + editor_plugin.switch_to_tool(ToolEditFace.new()) + + +func _on_check_lock_uvs_toggled(button_pressed): + editor_plugin.lock_uvs = button_pressed + + +func _on_bn_prism_pressed(): + editor_plugin.switch_to_tool(ToolPrism.new()) + +func _on_bn_cylinder_pressed(): + editor_plugin.switch_to_tool(ToolCylinder.new()) + +func _on_bn_stairs_pressed(): + editor_plugin.switch_to_tool(ToolStairs.new()) + +func _on_bn_duplicate_pressed(): + editor_plugin.switch_to_tool(ToolDuplicate.new()) + + +func _on_bn_delete_pressed(): + var blocks_root:CyclopsBlocks = editor_plugin.active_node + var cmd:CommandDeleteBlocks = CommandDeleteBlocks.new() + cmd.blocks_root_path = blocks_root.get_path() + cmd.builder = editor_plugin + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = editor_plugin.get_undo_redo() + cmd.add_to_undo_manager(undo) + + +func _on_bn_flip_x_pressed(): + var action:ActionMirrorSelectionX2 = ActionMirrorSelectionX2.new(editor_plugin) + action._execute() + +func _on_bn_flip_y_pressed(): + var action:ActionMirrorSelectionY2 = ActionMirrorSelectionY2.new(editor_plugin) + action._execute() + + +func _on_bn_flip_z_pressed(): + var action:ActionMirrorSelectionZ = ActionMirrorSelectionZ.new(editor_plugin) + action._execute() + + +func _on_display_mode_item_selected(index): + editor_plugin.display_mode = index + + diff --git a/addons/cyclops_level_builder/menu/editor_toolbar.tscn b/addons/cyclops_level_builder/menu/editor_toolbar.tscn new file mode 100644 index 0000000..8683323 --- /dev/null +++ b/addons/cyclops_level_builder/menu/editor_toolbar.tscn @@ -0,0 +1,217 @@ +[gd_scene load_steps=6 format=3 uid="uid://c3cl77r65dexu"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/menu/editor_toolbar.gd" id="1_o71fd"] +[ext_resource type="Script" path="res://addons/cyclops_level_builder/menu/action_popup_menu.gd" id="2_ni0c8"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_o7kxq"] + +[sub_resource type="Theme" id="Theme_0hxey"] +PanelContainer/styles/panel = SubResource("StyleBoxEmpty_o7kxq") + +[sub_resource type="ButtonGroup" id="ButtonGroup_i8xwa"] + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 739.0 +offset_bottom = 31.0 +size_flags_horizontal = 3 +theme = SubResource("Theme_0hxey") +script = ExtResource("1_o71fd") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="bn_block" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click and drag in empty space or on unselected block to create a new block. + +Click and drag on a selected block to move it in the XZ plane. Hold Alt to drag along the Y axis. + +Ctrl-click and drag on the face of a block to move the face along its normal. + +Escape or right click to cancel drawing the block. + +Click on block to select it. Shift-Click toggles, Ctrl-Click adds and Shift-Ctrl Click subtracts. + +Click in empty space to clear selection." +toggle_mode = true +button_pressed = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Block" + +[node name="bn_prism" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block or in empty space to begin creating base of a prism. + +Click to add new point. Backspace to remove the last point you added. You can also right click on a point to remove it. + +Press Enter to extrude base. + +Press Enter again to finish extruding and create block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Prism" + +[node name="bn_cylinder" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block or in empty space to begin creating base of a cylinder. + +Release the mouse to enter height drawing mode. If you have the tube option selected, you will draw the second ring instead. + +Use the mouse wheel to change the number of sides of the cylinder while drawing." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Cylinder" + +[node name="bn_stairs" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block or in empty space to begin creating base of a stair case. + +Release mouse button and drag upwards to adjust the height of the stairs. + +Use the mouse wheel to change the direction the stairs face. Ctrl-Wheel to change the height of each step, Ctrl-Shift-Wheel to change the depth of each step." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Stairs" + +[node name="bn_clip" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on surface of block to place first cutting point. + +Click again to place second cutting point. This will define the plane block will be cut along. + +If you press Enter at this point, the block will be cut. The cutting plane will be defined by the cutting line you've drawn and the normal of the plane it is on. + +You can optionally place a third cutting point. If you do, the three placed points will define the cutting plane when you press Enter. + +Press Backspace to delete the last cutting point you placed." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Clip" + +[node name="bn_vertex" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on a vertex to select it. Shift Click to toggle selecton, Ctrl Click to add to selection, Shift-Ctrl click to subtract from selection. + +Click and drag to move vertex in XZ plane. Hold Alt to drag along Y axis. Click and drag on a selected vertex to move all selected vertices. + +Hover the mouse over a different block and press Alt-Q to switch to editing that block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Vertex" + +[node name="bn_edge" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on an edge to select it. Shift Click to toggle selecton, Ctrl Click to add to selection, Shift-Ctrl click to subtract from selection. + +Click and drag to move edge in XZ plane. Hold Alt to drag along Y axis. Click and drag on a selected edge to move all selected edges. + +Hover the mouse over a different block and press Alt-Q to switch to editing that block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Edge" + +[node name="bn_face" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Click on a face to select it. Shift Click to toggle selecton, Ctrl Click to add to selection, Shift-Ctrl click to subtract from selection. + +Click and drag to move face in XZ plane. Hold Alt to drag along Y axis. Click and drag on a selected face to move all selected faces. + +Hover the mouse over a different block and press Alt-Q to switch to editing that block." +toggle_mode = true +button_group = SubResource("ButtonGroup_i8xwa") +text = "Face" + +[node name="MenuBar" type="MenuBar" parent="HBoxContainer"] +layout_mode = 2 + +[node name="Menu" type="PopupMenu" parent="HBoxContainer/MenuBar"] +item_count = 18 +item_0/text = "Duplicate Selected Blocks" +item_0/id = 1000 +item_1/text = "Delete Selected Blocks" +item_1/id = 1001 +item_2/text = "Snap to grid" +item_2/id = 1002 +item_3/text = "" +item_3/id = -1 +item_3/separator = true +item_4/text = "Rotate 90 Ccw X" +item_4/id = 1003 +item_5/text = "Rotate 90 Cw X" +item_5/id = 1004 +item_6/text = "Rotate 180 X" +item_6/id = 1005 +item_7/text = "Mirror Selection X" +item_7/id = 1006 +item_8/text = "" +item_8/id = -1 +item_8/separator = true +item_9/text = "Rotate 90 Ccw Y" +item_9/id = 1007 +item_10/text = "Rotate 90 Cw Y" +item_10/id = 1008 +item_11/text = "Rotate 180 Y" +item_11/id = 1009 +item_12/text = "Mirror Selection Y" +item_12/id = 1010 +item_13/text = "" +item_13/id = -1 +item_13/separator = true +item_14/text = "Rotate 90 Ccw Z" +item_14/id = 1011 +item_15/text = "Rotate 90 Cw Z" +item_15/id = 1012 +item_16/text = "Rotate 180 Z" +item_16/id = 1013 +item_17/text = "Mirror Selection Z" +item_17/id = 1014 +script = ExtResource("2_ni0c8") + +[node name="check_lock_uvs" type="CheckBox" parent="HBoxContainer"] +layout_mode = 2 +text = "Lock UVs" + +[node name="grid_size" type="OptionButton" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Grid snapping size" +item_count = 9 +selected = 0 +popup/item_0/text = "1/16" +popup/item_0/id = 0 +popup/item_1/text = "1/8" +popup/item_1/id = 1 +popup/item_2/text = "1/4" +popup/item_2/id = 2 +popup/item_3/text = "1/2" +popup/item_3/id = 3 +popup/item_4/text = "1" +popup/item_4/id = 4 +popup/item_5/text = "2" +popup/item_5/id = 5 +popup/item_6/text = "4" +popup/item_6/id = 6 +popup/item_7/text = "8" +popup/item_7/id = 7 +popup/item_8/text = "16" +popup/item_8/id = 8 + +[node name="display_mode" type="OptionButton" parent="HBoxContainer"] +layout_mode = 2 +item_count = 2 +selected = 1 +popup/item_0/text = "Wireframe" +popup/item_0/id = 0 +popup/item_1/text = "Textured" +popup/item_1/id = 1 + +[connection signal="pressed" from="HBoxContainer/bn_block" to="." method="_on_bn_move_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_prism" to="." method="_on_bn_prism_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_cylinder" to="." method="_on_bn_cylinder_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_stairs" to="." method="_on_bn_stairs_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_clip" to="." method="_on_bn_clip_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_vertex" to="." method="_on_bn_vertex_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_edge" to="." method="_on_bn_edge_pressed"] +[connection signal="pressed" from="HBoxContainer/bn_face" to="." method="_on_bn_face_pressed"] +[connection signal="toggled" from="HBoxContainer/check_lock_uvs" to="." method="_on_check_lock_uvs_toggled"] +[connection signal="item_selected" from="HBoxContainer/grid_size" to="." method="_on_grid_size_item_selected"] +[connection signal="item_selected" from="HBoxContainer/display_mode" to="." method="_on_display_mode_item_selected"] diff --git a/addons/cyclops_level_builder/menu/sticky_toolbar.gd b/addons/cyclops_level_builder/menu/sticky_toolbar.gd new file mode 100644 index 0000000..c9be86e --- /dev/null +++ b/addons/cyclops_level_builder/menu/sticky_toolbar.gd @@ -0,0 +1,41 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Control +class_name StickyToolbar + +var plugin:CyclopsLevelBuilder + +# Called when the node enters the scene tree for the first time. +func _ready(): + $HBoxContainer/PanelContainer.visible = false + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + + +func _on_texture_button_toggled(button_pressed): + $HBoxContainer/PanelContainer.visible = button_pressed diff --git a/addons/cyclops_level_builder/menu/sticky_toolbar.tscn b/addons/cyclops_level_builder/menu/sticky_toolbar.tscn new file mode 100644 index 0000000..4a1db9f --- /dev/null +++ b/addons/cyclops_level_builder/menu/sticky_toolbar.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=8 format=3 uid="uid://c4smddvlwx54s"] + +[ext_resource type="Script" path="res://addons/cyclops_level_builder/menu/sticky_toolbar.gd" id="1_52wtc"] +[ext_resource type="Texture2D" uid="uid://d0krdms4l6ns4" path="res://addons/cyclops_level_builder/art/cyclops_3.png" id="2_0mx5n"] +[ext_resource type="Texture2D" uid="uid://cg3yjatinkymb" path="res://addons/cyclops_level_builder/art/cyclops_4.png" id="3_5oy58"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_h0l71"] + +[sub_resource type="Theme" id="Theme_dgoud"] +PanelContainer/styles/panel = SubResource("StyleBoxEmpty_h0l71") + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6pjef"] + +[sub_resource type="Theme" id="Theme_nckdr"] +PanelContainer/styles/panel = SubResource("StyleBoxEmpty_6pjef") + +[node name="PanelContainer" type="PanelContainer"] +offset_right = 70.0 +offset_bottom = 31.0 +theme = SubResource("Theme_dgoud") +script = ExtResource("1_52wtc") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="CyclopsButton" type="TextureButton" parent="HBoxContainer"] +layout_mode = 2 +toggle_mode = true +texture_normal = ExtResource("2_0mx5n") +texture_pressed = ExtResource("3_5oy58") + +[node name="PanelContainer" type="PanelContainer" parent="HBoxContainer"] +visible = false +layout_mode = 2 +theme = SubResource("Theme_nckdr") + +[node name="Button" type="Button" parent="HBoxContainer/PanelContainer"] +layout_mode = 2 +text = "Block" + +[connection signal="toggled" from="HBoxContainer/CyclopsButton" to="." method="_on_texture_button_toggled"] diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks.gd b/addons/cyclops_level_builder/nodes/cyclops_blocks.gd new file mode 100644 index 0000000..c5f97e6 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_blocks.gd @@ -0,0 +1,143 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Node3D +class_name CyclopsBlocks + +signal blocks_changed + +@export var occluder_vertex_offset:float = 0: + get: + return occluder_vertex_offset + set(value): + occluder_vertex_offset = value + dirty = true + +var dirty:bool = true + +var block_bodies:Node3D + +# Called when the node enters the scene tree for the first time. +func _ready(): + + child_entered_tree.connect(on_child_entered_tree) + child_exiting_tree.connect(on_child_exiting_tree) + + block_bodies = Node3D.new() + block_bodies.name = "block_bodies" + add_child(block_bodies) + + for node in get_children(): + if node is CyclopsConvexBlock: + var block:CyclopsConvexBlock = node + block.mesh_changed.connect(on_child_mesh_changed) + + + +func on_child_mesh_changed(): + dirty = true + blocks_changed.emit() + + +func on_child_entered_tree(node:Node): + if node is CyclopsConvexBlock: + var block:CyclopsConvexBlock = node + block.mesh_changed.connect(on_child_mesh_changed) + +# print("on_child_entered_tree %s" % node.name) + dirty = true + +func on_child_exiting_tree(node:Node): + if node is CyclopsConvexBlock: + var block:CyclopsConvexBlock = node + block.mesh_changed.disconnect(on_child_mesh_changed) + +# print("on_child_exited_tree %s" % node.name) + + dirty = true + +func has_selected_blocks()->bool: + for child in get_children(): + if child is CyclopsConvexBlock and child.selected: + return true + return false + + +func rebuild_mesh(): + for child in block_bodies.get_children(): + child.queue_free() + + for child in get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + +# var block_body:CyclopsConvexBlockBody = preload("res://addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd").instantiate() + var block_body:CyclopsConvexBlockBody = CyclopsConvexBlockBody.new() + block_body.materials = block.materials + block_body.block_data = block.block_data + block_bodies.add_child(block_body) + + + dirty = false + +func get_active_block()->CyclopsConvexBlock: + for child in get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.active: + return block + return null + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + rebuild_mesh() + +func _input(event): + if Engine.is_editor_hint(): + pass + + #print(event.as_text()) + pass + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + return intersect_ray_closest_filtered(origin, dir, func(block:CyclopsConvexBlock): return true) + +func intersect_ray_closest_selected_only(origin:Vector3, dir:Vector3)->IntersectResults: + return intersect_ray_closest_filtered(origin, dir, func(block:CyclopsConvexBlock): return block.selected) + +func intersect_ray_closest_filtered(origin:Vector3, dir:Vector3, filter:Callable)->IntersectResults: + var best_result:IntersectResults + + for child in get_children(): + if child is CyclopsConvexBlock: + var result:IntersectResults = child.intersect_ray_closest(origin, dir) + if result: + if !filter.call(result.object): + continue + + if !best_result or result.distance_squared < best_result.distance_squared: + best_result = result + + return best_result diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..89a3bc276677d3f58749d09e39fd3caff8752b15 GIT binary patch literal 631 zcmV--0*L*IP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10t87! zK~y-6h0;xkR%H|i@ZWRaI|~JcT!br8X`z7zF||kuQE*{oVbL-|Di@~FhXXp!JoCKw z-8i!l(yUw+K~NM)Ev;QqLPZgTA>qakXp;+JteHEfh1Y2sM?Jge{BvFc^HGZKsgu?{Bht1E=MD-J+`hcRG6XBAzuE?ANv@ z@u5|#UUJ~T-wR@1)5%$hnHsZ5O8Hb>ziM>!vWRa$N}tbzOIh0iU+5&ii^&ud6Sb7~ zix{AiQeR!4H8b<0l=kTLelk1zdY4GT`)K5RiG`au7_8H_C-4N$V}q2w7V$V*oW?OZ zUs + + + + + + + + + + + + diff --git a/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import new file mode 100644 index 0000000..1c1ce7d --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://chuwp6awho53q" +path="res://.godot/imported/cyclops_blocks_icon.svg-5e216ef2489ff1d30c472c6b8748fdf1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/cyclops_level_builder/nodes/cyclops_blocks_icon.svg" +dest_files=["res://.godot/imported/cyclops_blocks_icon.svg-5e216ef2489ff1d30c472c6b8748fdf1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/cyclops_level_builder/nodes/cyclops_convex_block.gd b/addons/cyclops_level_builder/nodes/cyclops_convex_block.gd new file mode 100644 index 0000000..0355079 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_convex_block.gd @@ -0,0 +1,123 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Node +class_name CyclopsConvexBlock + +signal mesh_changed + +@export var materials:Array[Material] + +var control_mesh:ConvexVolume + +var selected:bool = false: + get: + return selected + set(value): + if value == selected: + return + selected = value + mesh_changed.emit() + +var active:bool: + get: + return active + set(value): + if value == active: + return + active = value + mesh_changed.emit() + + +var default_material:Material = preload("res://addons/cyclops_level_builder/materials/grid.tres") + +@export var block_data:ConvexBlockData: + get: + return block_data + set(value): + if block_data != value: + block_data = value + control_mesh = ConvexVolume.new() + control_mesh.init_from_convex_block_data(block_data) + + mesh_changed.emit() + + +func intersect_ray_closest(origin:Vector3, dir:Vector3)->IntersectResults: + if !block_data: + return null + + var result:IntersectResults = control_mesh.intersect_ray_closest(origin, dir) + if result: + result.object = self + + return result + + +func select_face(face_idx:int, select_type:Selection.Type = Selection.Type.REPLACE): + if select_type == Selection.Type.REPLACE: + for f in control_mesh.faces: + f.selected = f.index == face_idx + elif select_type == Selection.Type.ADD: + control_mesh.faces[face_idx].selected = true + elif select_type == Selection.Type.SUBTRACT: + control_mesh.faces[face_idx].selected = true + elif select_type == Selection.Type.TOGGLE: + control_mesh.faces[face_idx].selected = !control_mesh.faces[face_idx].selected + + mesh_changed.emit() + +func append_mesh(mesh:ImmediateMesh): +# print("adding block mesh %s" % name) + #var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + control_mesh.append_mesh(mesh, materials, default_material) + +func append_mesh_wire(mesh:ImmediateMesh): + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + var mat:Material = global_scene.outline_material + control_mesh.append_mesh_wire(mesh, mat) + +func append_mesh_backfacing(mesh:ImmediateMesh): + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + var mat:Material = global_scene.tool_object_selected_material + control_mesh.append_mesh_backfacing(mesh, mat) + +func append_mesh_outline(mesh:ImmediateMesh, viewport_camera:Camera3D, local_to_world:Transform3D): + var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + + var mat:Material = global_scene.tool_object_active_material if active else global_scene.tool_object_selected_material + control_mesh.append_mesh_outline(mesh, viewport_camera, local_to_world, mat) + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + diff --git a/addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd b/addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd new file mode 100644 index 0000000..3aa5799 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/cyclops_convex_block_body.gd @@ -0,0 +1,141 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Node3D +class_name CyclopsConvexBlockBody + +var mesh_instance:MeshInstance3D +var mesh_wire:MeshInstance3D +var collision_body:StaticBody3D +var collision_shape:CollisionShape3D +var occluder:OccluderInstance3D + +var dirty:bool = true + +@export var block_data:ConvexBlockData: + get: + return block_data + set(value): + block_data = value + dirty = true + + +@export var materials:Array[Material] + +var default_material:Material = preload("res://addons/cyclops_level_builder/materials/grid.tres") +var display_mode:DisplayMode.Type = DisplayMode.Type.TEXTURED + +# Called when the node enters the scene tree for the first time. +func _ready(): + mesh_instance = MeshInstance3D.new() + add_child(mesh_instance) + mesh_instance.gi_mode = GeometryInstance3D.GI_MODE_STATIC + + if Engine.is_editor_hint(): + mesh_wire = MeshInstance3D.new() + add_child(mesh_wire) + + collision_body = StaticBody3D.new() + add_child(collision_body) + collision_shape = CollisionShape3D.new() + collision_body.add_child(collision_shape) + + occluder = OccluderInstance3D.new() + add_child(occluder) + + build_from_block() + + +func build_from_block(): + + dirty = false + + mesh_instance.mesh = null + collision_shape.shape = null + + if Engine.is_editor_hint(): +# var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + var global_scene = get_node("/root/CyclopsAutoload") + display_mode = global_scene.builder.display_mode + +# print("block_data %s" % block_data) +# print("vert points %s" % block_data.vertex_points) + if !block_data: + return + +# print("got block data") + + var vol:ConvexVolume = ConvexVolume.new() + vol.init_from_convex_block_data(block_data) + + #print("volume %s" % vol) + +# var mesh:ImmediateMesh = ImmediateMesh.new() + var mesh:ArrayMesh + + if Engine.is_editor_hint(): +# var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + var global_scene = get_node("/root/CyclopsAutoload") + mesh_wire.mesh = vol.create_mesh_wire(global_scene.outline_material) + #print ("added wireframe") + + if display_mode == DisplayMode.Type.TEXTURED: + mesh = vol.create_mesh(materials, default_material) + #print ("added faces") + else: + mesh = vol.create_mesh(materials, default_material) +# vol.append_mesh(mesh, materials, default_material) + + mesh_instance.mesh = mesh + +# print("===============") +# GeneralUtil.dump_properties(mesh_instance) +# print("---------------") +# GeneralUtil.dump_properties(mesh_instance.mesh) + + var shape:ConvexPolygonShape3D = ConvexPolygonShape3D.new() + shape.points = vol.get_points() + collision_shape.shape = shape + + if !Engine.is_editor_hint(): + #Disabling this in the editor for now since this is causing slowdown + var occluder_object:ArrayOccluder3D = ArrayOccluder3D.new() + occluder_object.vertices = vol.get_points() + occluder_object.indices = vol.get_trimesh_indices() + occluder.occluder = occluder_object + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if dirty: + build_from_block() + + + if Engine.is_editor_hint(): +# var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload") + var global_scene = get_node("/root/CyclopsAutoload") + + if display_mode != global_scene.builder.display_mode: + dirty = true + return + diff --git a/addons/cyclops_level_builder/nodes/intersect_results.gd b/addons/cyclops_level_builder/nodes/intersect_results.gd new file mode 100644 index 0000000..185ded0 --- /dev/null +++ b/addons/cyclops_level_builder/nodes/intersect_results.gd @@ -0,0 +1,35 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends RefCounted +class_name IntersectResults + +var object:CyclopsConvexBlock +var face_id:int +var position:Vector3 +var normal:Vector3 +var distance_squared:float + +func _to_string(): + return "object:%s face_id:%s pos:%s norm:%s dist_sq:%s" % [object, face_id, position, normal, distance_squared] diff --git a/addons/cyclops_level_builder/plugin.cfg b/addons/cyclops_level_builder/plugin.cfg new file mode 100644 index 0000000..39b8937 --- /dev/null +++ b/addons/cyclops_level_builder/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Cyclops Level Builder" +description="Tools for rapidly blocking in levels." +author="Mark McKay" +version="1.0.1" +script="cyclops_level_builder.gd" diff --git a/addons/cyclops_level_builder/resources/block_data.gd b/addons/cyclops_level_builder/resources/block_data.gd new file mode 100644 index 0000000..eb4a10d --- /dev/null +++ b/addons/cyclops_level_builder/resources/block_data.gd @@ -0,0 +1,32 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Resource +class_name BlockData + +@export var points:PackedVector3Array #Per vertex +@export var uvs:PackedVector2Array #Per face corner uv info +@export var face_vertex_indices:PackedInt32Array #Vertex index per face +@export var face_vertex_count:PackedInt32Array #Number of verts in each face +@export var face_material_indices:PackedInt32Array #Material index for each face diff --git a/addons/cyclops_level_builder/resources/convex_block_data.gd b/addons/cyclops_level_builder/resources/convex_block_data.gd new file mode 100644 index 0000000..aa5b53b --- /dev/null +++ b/addons/cyclops_level_builder/resources/convex_block_data.gd @@ -0,0 +1,51 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Resource +class_name ConvexBlockData + +@export var selected:bool = false +@export var active:bool = false +@export var collsion:bool = true + +@export var vertex_points:PackedVector3Array #Per vertex +@export var vertex_selected:PackedByteArray #Per vertex +#@export var vertex_active:PackedByteArray #Per vertex +@export var active_vertex:int + +@export var edge_vertex_indices:PackedInt32Array +@export var edge_selected:PackedByteArray +#@export var edge_active:PackedByteArray +@export var active_edge:int +@export var edge_face_indices:PackedInt32Array + +@export var face_vertex_count:PackedInt32Array #Number of verts in each face +@export var face_vertex_indices:PackedInt32Array #Vertex index per face +@export var face_material_indices:PackedInt32Array #Material index for each face +@export var face_uv_transform:Array[Transform2D] +@export var face_selected:PackedByteArray #Per face +#@export var face_active:PackedByteArray #Per face +@export var active_face:int +@export var face_ids:PackedInt32Array #Per face + diff --git a/addons/cyclops_level_builder/shaders/outline_shader.tres b/addons/cyclops_level_builder/shaders/outline_shader.tres new file mode 100644 index 0000000..7e78ea6 --- /dev/null +++ b/addons/cyclops_level_builder/shaders/outline_shader.tres @@ -0,0 +1,65 @@ +[gd_resource type="VisualShader" load_steps=5 format=3 uid="uid://cc5tovf48xmg1"] + +[sub_resource type="VisualShaderNodeColorConstant" id="VisualShaderNodeColorConstant_mqcg1"] +constant = Color(0, 0, 0, 1) + +[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_kvn47"] +parameter_name = "ColorParameter" +default_value_enabled = true +default_value = Color(0, 0, 0, 1) + +[sub_resource type="VisualShaderNodeLinearSceneDepth" id="VisualShaderNodeLinearSceneDepth_d3ao7"] + +[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_pyrux"] +default_input_values = [0, 0.0, 1, 1.0] + +[resource] +code = "shader_type spatial; +uniform vec4 ColorParameter : source_color = vec4(0.000000, 0.000000, 0.000000, 1.000000); +uniform sampler2D depth_tex_frg_4 : hint_depth_texture; + + + +void fragment() { +// ColorConstant:2 + vec4 n_out2p0 = vec4(0.000000, 0.000000, 0.000000, 1.000000); + + +// ColorParameter:3 + vec4 n_out3p0 = ColorParameter; + + + float n_out4p0; +// LinearSceneDepth:4 + { + float __log_depth = textureLod(depth_tex_frg_4, SCREEN_UV, 0.0).x; + vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(vec3(SCREEN_UV, __log_depth) * 2.0 - 1.0, 1.0); + __depth_view.xyz /= __depth_view.w; + n_out4p0 = -__depth_view.z; + } + + +// FloatOp:5 + float n_in5p1 = 1.00000; + float n_out5p0 = n_out4p0 + n_in5p1; + + +// Output:0 + ALBEDO = vec3(n_out2p0.xyz); + EMISSION = vec3(n_out3p0.xyz); + NORMAL_MAP_DEPTH = n_out5p0; + + +} +" +graph_offset = Vector2(-10.4364, 103.709) +nodes/fragment/0/position = Vector2(480, 140) +nodes/fragment/2/node = SubResource("VisualShaderNodeColorConstant_mqcg1") +nodes/fragment/2/position = Vector2(227.319, 156.469) +nodes/fragment/3/node = SubResource("VisualShaderNodeColorParameter_kvn47") +nodes/fragment/3/position = Vector2(80, 280) +nodes/fragment/4/node = SubResource("VisualShaderNodeLinearSceneDepth_d3ao7") +nodes/fragment/4/position = Vector2(0, 560) +nodes/fragment/5/node = SubResource("VisualShaderNodeFloatOp_pyrux") +nodes/fragment/5/position = Vector2(260, 520) +nodes/fragment/connections = PackedInt32Array(2, 0, 0, 0, 3, 0, 0, 5, 4, 0, 5, 0, 5, 0, 0, 10) diff --git a/addons/cyclops_level_builder/shaders/tool_outline_shader.tres b/addons/cyclops_level_builder/shaders/tool_outline_shader.tres new file mode 100644 index 0000000..ad3d116 --- /dev/null +++ b/addons/cyclops_level_builder/shaders/tool_outline_shader.tres @@ -0,0 +1,38 @@ +[gd_resource type="VisualShader" load_steps=3 format=3 uid="uid://c33k8fbmgw46b"] + +[sub_resource type="VisualShaderNodeColorConstant" id="VisualShaderNodeColorConstant_mqcg1"] +constant = Color(0, 0, 0, 1) + +[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_kvn47"] +parameter_name = "ColorParameter" +default_value_enabled = true +default_value = Color(1, 1, 0, 1) + +[resource] +code = "shader_type spatial; +uniform vec4 ColorParameter : source_color = vec4(1.000000, 1.000000, 0.000000, 1.000000); + + + +void fragment() { +// ColorConstant:2 + vec4 n_out2p0 = vec4(0.000000, 0.000000, 0.000000, 1.000000); + + +// ColorParameter:3 + vec4 n_out3p0 = ColorParameter; + + +// Output:0 + ALBEDO = vec3(n_out2p0.xyz); + EMISSION = vec3(n_out3p0.xyz); + + +} +" +nodes/fragment/0/position = Vector2(480, 140) +nodes/fragment/2/node = SubResource("VisualShaderNodeColorConstant_mqcg1") +nodes/fragment/2/position = Vector2(227.319, 156.469) +nodes/fragment/3/node = SubResource("VisualShaderNodeColorParameter_kvn47") +nodes/fragment/3/position = Vector2(80, 280) +nodes/fragment/connections = PackedInt32Array(2, 0, 0, 0, 3, 0, 0, 5) diff --git a/addons/cyclops_level_builder/tools/cyclops_tool.gd b/addons/cyclops_level_builder/tools/cyclops_tool.gd new file mode 100644 index 0000000..416ec9f --- /dev/null +++ b/addons/cyclops_level_builder/tools/cyclops_tool.gd @@ -0,0 +1,105 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Resource +class_name CyclopsTool + +var builder:CyclopsLevelBuilder + +#func _init(_editorPlugin:EditorPlugin): +# editorPlugin = _editorPlugin + +func _activate(builder:CyclopsLevelBuilder): + self.builder = builder + +func _deactivate(): + pass + +func _get_tool_id()->String: + return "" + +func _draw_tool(viewport_camera:Camera3D): + pass + +func _get_tool_properties_editor()->Control: + return null + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_X: + if e.is_pressed(): + #print("cyc tool X") + var action:ActionDeleteSelectedBlocks = ActionDeleteSelectedBlocks.new(builder) + action._execute() + + return true + + if e.keycode == KEY_D: + if e.is_pressed(): + if e.shift_pressed && !Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT): + + if builder.active_node and builder.active_node.has_selected_blocks(): + + builder.switch_to_tool(ToolDuplicate.new()) + + return true + + if event is InputEventMouseButton: + var e:InputEventMouseButton = event + + if e.button_index == MOUSE_BUTTON_MIDDLE: + if e.alt_pressed: + if e.is_pressed(): + if builder.active_node: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = builder.active_node.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var result:IntersectResults = builder.active_node.intersect_ray_closest(origin_local, dir_local) + if result: + var ed_iface:EditorInterface = builder.get_editor_interface() + var base_control:Control = ed_iface.get_base_control() + + #viewport_camera + var new_cam_origin:Vector3 = result.position + \ + viewport_camera.global_transform.basis.z * builder.block_create_distance + viewport_camera.global_transform.origin = new_cam_origin + return true + + return false + + + +func to_local(point:Vector3, world_to_local:Transform3D, grid_step_size:float)->Vector3: + var p_local:Vector3 = world_to_local * point + + return MathUtil.snap_to_grid(p_local, grid_step_size) + diff --git a/addons/cyclops_level_builder/tools/tool_block.gd b/addons/cyclops_level_builder/tools/tool_block.gd new file mode 100644 index 0000000..29d256e --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_block.gd @@ -0,0 +1,349 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolBlock + +const TOOL_ID:String = "block" + +enum ToolState { NONE, READY, BLOCK_BASE, BLOCK_HEIGHT, MOVE_BLOCK, MOVE_FACE } +var tool_state:ToolState = ToolState.NONE +#enum State { READY, DRAG_BASE } +#var dragging:bool = false +var viewport_camera_start:Camera3D +var event_start:InputEventMouseButton + +var block_drag_cur:Vector3 +var block_drag_p0_local:Vector3 +var block_drag_p1_local:Vector3 +var block_drag_p2_local:Vector3 + +var drag_floor_normal:Vector3 + +#var min_drag_distance:float = 4 + +#Keep a copy of move command here while we are building it +var cmd_move_blocks:CommandMoveBlocks +var cmd_move_face:CommandMoveFacePlanar +var move_face_origin:Vector3 #Kep track of the origin when moving a face + +var base_points:PackedVector3Array + +func _get_tool_id()->String: + return TOOL_ID + +func start_block_drag(viewport_camera:Camera3D, event:InputEvent): + var blocks_root:CyclopsBlocks = self.builder.active_node + var e:InputEventMouseButton = event + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + +# print("origin %s dir %s" % [origin, dir]) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) +# print("result %s" % result) + + if result: +# print("Hit! %s" % result) + drag_floor_normal = MathUtil.snap_to_best_axis_normal(result.normal) + + var start_pos:Vector3 = result.position + var w2l = blocks_root.global_transform.inverse() + var start_pos_local:Vector3 = w2l * start_pos + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + block_drag_p0_local = MathUtil.snap_to_grid(start_pos_local, grid_step_size) + + if e.ctrl_pressed: + tool_state = ToolState.MOVE_FACE + + cmd_move_face = CommandMoveFacePlanar.new() + cmd_move_face.builder = builder + cmd_move_face.blocks_root_path = builder.active_node.get_path() + cmd_move_face.block_path = result.object.get_path() + cmd_move_face.face_id = result.face_id + cmd_move_face.lock_uvs = builder.lock_uvs + cmd_move_face.move_dir_normal = result.object.control_mesh.faces[result.face_id].normal + + move_face_origin = result.position + + elif result.object.selected: + tool_state = ToolState.MOVE_BLOCK + + cmd_move_blocks = CommandMoveBlocks.new() + cmd_move_blocks.builder = builder + cmd_move_blocks.lock_uvs = builder.lock_uvs + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock and child.selected: + cmd_move_blocks.add_block(child.get_path()) + else: + tool_state = ToolState.BLOCK_BASE + + + else: +# print("Miss") + drag_floor_normal = Vector3.UP + + tool_state = ToolState.BLOCK_BASE + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var start_pos_local:Vector3 = w2l * start_pos + + #print("start_pos %s" % start_pos) + #print("start_pos_local %s" % start_pos_local) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + + #print("start_pos_local %s" % start_pos_local) + block_drag_p0_local = MathUtil.snap_to_grid(start_pos_local, grid_step_size) + + #print("block_drag_start_local %s" % block_drag_start_local) + #print("set 1 tool_state %s" % tool_state) + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if tool_state == ToolState.BLOCK_BASE: + global_scene.draw_loop(base_points, true, global_scene.tool_material) + global_scene.draw_points(base_points, global_scene.tool_material) + + if tool_state == ToolState.BLOCK_HEIGHT: + global_scene.draw_cube(block_drag_p0_local, block_drag_p1_local, block_drag_cur, global_scene.tool_material) + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + var blocks_root:CyclopsBlocks = builder.active_node + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_ESCAPE: + if e.is_pressed(): + tool_state = ToolState.NONE + return true + + + elif event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + if tool_state == ToolState.NONE: + event_start = event + viewport_camera_start = viewport_camera + + tool_state = ToolState.READY + + else: + if tool_state == ToolState.READY: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + + var cmd:CommandSelectBlocks = CommandSelectBlocks.new() + cmd.builder = builder + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + if result: + cmd.block_paths.append(result.object.get_path()) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + elif tool_state == ToolState.BLOCK_BASE: + block_drag_p1_local = block_drag_cur + tool_state = ToolState.BLOCK_HEIGHT + + #print("set 2 tool_state %s" % tool_state) + + elif tool_state == ToolState.BLOCK_HEIGHT: +# print("Adding block %s %s %s" % [block_drag_p0_local, block_drag_p1_local, block_drag_p2_local]) + block_drag_p2_local = block_drag_cur + tool_state = ToolState.NONE + + var bounds:AABB = AABB(block_drag_p0_local, Vector3.ZERO) + bounds = bounds.expand(block_drag_p1_local) + bounds = bounds.expand(block_drag_p2_local) + +# print("AABB %s" % bounds) + + if bounds.has_volume(): + var command:CommandAddBlock2 = CommandAddBlock2.new() + + command.builder = builder + command.blocks_root_path = blocks_root.get_path() + command.block_name = GeneralUtil.find_unique_name(builder.active_node, "Block_") + command.bounds = bounds + command.uv_transform = builder.tool_uv_transform + command.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + command.add_to_undo_manager(undo) + + elif tool_state == ToolState.MOVE_BLOCK: + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd_move_blocks.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + elif tool_state == ToolState.MOVE_FACE: + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd_move_face.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + return true + + elif e.button_index == MOUSE_BUTTON_RIGHT: + if tool_state == ToolState.BLOCK_BASE || tool_state == ToolState.BLOCK_HEIGHT: + if e.is_pressed(): + tool_state = ToolState.NONE + return true + + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + +# var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + + #print("tool_state %s" % tool_state) + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return super._gui_input(viewport_camera, event) + + if tool_state == ToolState.NONE: + if e.ctrl_pressed: + #block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + var result:IntersectResults = blocks_root.intersect_ray_closest(origin_local, dir_local) + if result: + var block:CyclopsConvexBlock = result.object + var convex_mesh:ConvexVolume = block.control_mesh + base_points = convex_mesh.get_face(result.face_id).get_points() + return true + + return false + + elif tool_state == ToolState.READY: + var offset:Vector2 = e.position - event_start.position + if offset.length_squared() > MathUtil.square(builder.drag_start_radius): + start_block_drag(viewport_camera_start, event_start) + + return true + + elif tool_state == ToolState.BLOCK_BASE: + + block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + + #print("block_drag_cur %s" % block_drag_cur) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + block_drag_cur = MathUtil.snap_to_grid(block_drag_cur, grid_step_size) + + #print("block_drag_cur snapped %s" % block_drag_cur) + + #Draw tool + var p01:Vector3 + var p10:Vector3 + if abs(drag_floor_normal.x) > abs(drag_floor_normal.y) and abs(drag_floor_normal.x) > abs(drag_floor_normal.z): + p01 = Vector3(block_drag_p0_local.x, block_drag_p0_local.y, block_drag_cur.z) + p10 = Vector3(block_drag_p0_local.x, block_drag_cur.y, block_drag_p0_local.z) + elif abs(drag_floor_normal.y) > abs(drag_floor_normal.z): + p01 = Vector3(block_drag_p0_local.x, block_drag_p0_local.y, block_drag_cur.z) + p10 = Vector3(block_drag_cur.x, block_drag_p0_local.y, block_drag_p0_local.z) + else: + p01 = Vector3(block_drag_p0_local.x, block_drag_cur.y, block_drag_p0_local.z) + p10 = Vector3(block_drag_cur.x, block_drag_p0_local.y, block_drag_p0_local.z) + + base_points = [block_drag_p0_local, p01, block_drag_cur, p10] + + return true + + elif tool_state == ToolState.BLOCK_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, block_drag_p1_local, drag_floor_normal) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + block_drag_cur = MathUtil.snap_to_grid(block_drag_cur, grid_step_size) + + return true + + elif tool_state == ToolState.MOVE_BLOCK: + if e.alt_pressed: +# block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, block_drag_p0_local, Vector3.UP) + else: +# block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, drag_floor_normal) + block_drag_cur = MathUtil.intersect_plane(origin_local, dir_local, block_drag_p0_local, Vector3.UP) + + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + block_drag_cur = MathUtil.snap_to_grid(block_drag_cur, grid_step_size) + + cmd_move_blocks.move_offset = block_drag_cur - block_drag_p0_local + cmd_move_blocks.do_it() + + return true + + elif tool_state == ToolState.MOVE_FACE: + var drag_to:Vector3 = MathUtil.closest_point_on_line(origin_local, dir_local, move_face_origin, cmd_move_face.move_dir_normal) + #print("move_face_origin %s norm %s" % [move_face_origin, cmd_move_face.move_dir_normal]) + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + drag_to = MathUtil.snap_to_grid(drag_to, grid_step_size) + + cmd_move_face.move_amount = (drag_to - move_face_origin).dot(cmd_move_face.move_dir_normal) + + cmd_move_face.do_it_intermediate() + + return true + + return super._gui_input(viewport_camera, event) + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + diff --git a/addons/cyclops_level_builder/tools/tool_clip.gd b/addons/cyclops_level_builder/tools/tool_clip.gd new file mode 100644 index 0000000..3b410fe --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_clip.gd @@ -0,0 +1,164 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolClip + +const TOOL_ID:String = "clip" + +enum ToolState { READY, PICK_POINTS, PICK_SIDE } +var tool_state:ToolState = ToolState.READY + +var clip_points:PackedVector3Array +var clip_normals:PackedVector3Array +var clip_block:CyclopsConvexBlock + +func _get_tool_id()->String: + return TOOL_ID + +func has_clip_point(point:Vector3)->bool: + for p in clip_points: + if p.is_equal_approx(point): + return true + return false + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if !clip_points.is_empty(): + global_scene.draw_loop(clip_points, false, global_scene.tool_material) + global_scene.draw_points(clip_points, global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + #var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + + #_draw_tool(viewport_camera) + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_BACKSPACE: + if e.is_pressed(): + if !clip_points.is_empty(): + var count:int = clip_points.size() + clip_points.remove_at(count - 1) + clip_normals.remove_at(count - 1) + if clip_points.is_empty(): + clip_block = null + + return true + + elif e.keycode == KEY_ESCAPE: + clip_points.clear() + clip_normals.clear() + clip_block = null +# _draw_tool(viewport_camera) + return true + + elif e.keycode == KEY_ENTER: + #Cut at plane + var cut_plane:Plane + + if clip_points.size() == 3: + cut_plane = Plane(clip_points[0], clip_points[1], clip_points[2]) + elif clip_points.size() == 2: + var dir:Vector3 = clip_points[1] - clip_points[0] + var face_dir:Vector3 = clip_normals[0].cross(dir) + cut_plane = Plane(face_dir.normalized(), clip_points[0]) + else: + #Cannot cut with fewer than 2 points + return true + + var cmd:CommandClipBlock = CommandClipBlock.new() + cmd.builder = builder + cmd.blocks_root_path = blocks_root.get_path() + cmd.block_path = clip_block.get_path() + cmd.block_sibling_name = GeneralUtil.find_unique_name(blocks_root, "Block_") + cmd.cut_plane = cut_plane + cmd.material_path = builder.tool_material_path + cmd.uv_transform = builder.tool_uv_transform + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + #Clean up + clip_points.clear() + clip_normals.clear() + clip_block = null + +# _draw_tool(viewport_camera) + + return true + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + + if result: + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) + + if !has_clip_point(p): + if clip_points.is_empty(): + clip_block = result.object + + if clip_points.size() < 3: + clip_points.append(p) + clip_normals.append(result.normal) + else: + clip_points[2] = p + clip_normals[2] = result.normal + +# _draw_tool(viewport_camera) + + return true + + return false + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() diff --git a/addons/cyclops_level_builder/tools/tool_cylinder.gd b/addons/cyclops_level_builder/tools/tool_cylinder.gd new file mode 100644 index 0000000..c7c0bad --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_cylinder.gd @@ -0,0 +1,239 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolCylinder + +const TOOL_ID:String = "cylinder" + +enum ToolState { READY, FIRST_RING, SECOND_RING, DRAG_HEIGHT } +var tool_state:ToolState = ToolState.READY + +#@export var segments:int = 16 +#@export var tube:bool = false +var settings:ToolCylinderSettings = ToolCylinderSettings.new() + +var floor_normal:Vector3 +var base_center:Vector3 +var block_drag_cur:Vector3 +var drag_offset:Vector3 +var first_ring_radius:float +var second_ring_radius:float + + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + +func _get_tool_properties_editor()->Control: + var res_insp:ResourceInspector = preload("res://addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn").instantiate() + + res_insp.target = settings + + return res_insp + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if tool_state == ToolState.FIRST_RING: + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(base_center, floor_normal, first_ring_radius, settings.segments) + global_scene.draw_loop(bounding_points, true, global_scene.tool_material) + global_scene.draw_points(bounding_points, global_scene.tool_material) + + elif tool_state == ToolState.SECOND_RING: + for radius in [first_ring_radius, second_ring_radius]: + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(base_center, floor_normal, radius, settings.segments) + global_scene.draw_loop(bounding_points, true, global_scene.tool_material) + global_scene.draw_points(bounding_points, global_scene.tool_material) + + elif tool_state == ToolState.DRAG_HEIGHT: + var bounding_points:PackedVector3Array = MathUtil.create_circle_points(base_center, floor_normal, first_ring_radius, settings.segments) + global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + if settings.tube: + bounding_points = MathUtil.create_circle_points(base_center, floor_normal, second_ring_radius, settings.segments) + global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_ESCAPE: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + + if tool_state == ToolState.READY: + tool_state = ToolState.FIRST_RING + + first_ring_radius = 0 + second_ring_radius = 0 + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + #print("init base point block") + floor_normal = result.normal + + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) + base_center = p + + return true + + else: + #print("init base point empty space") + floor_normal = Vector3.UP + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + + var p:Vector3 = to_local(start_pos, blocks_root.global_transform.inverse(), grid_step_size) + base_center = p + + return true + else: + if tool_state == ToolState.FIRST_RING: + if settings.tube: + tool_state = ToolState.SECOND_RING + else: + tool_state = ToolState.DRAG_HEIGHT + return true + + elif tool_state == ToolState.SECOND_RING: + tool_state = ToolState.DRAG_HEIGHT + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + #Create shape + + var cmd:CommandAddCylinder = CommandAddCylinder.new() + cmd.builder = builder + #cmd.block_name = GeneralUtil.find_unique_name(builder.active_node, "Block_") + cmd.block_name_prefix = "Block_" + cmd.blocks_root_path = blocks_root.get_path() + cmd.tube = settings.tube + cmd.origin = base_center + cmd.axis_normal = floor_normal + cmd.height = drag_offset.length() if drag_offset.dot(floor_normal) > 0 else - drag_offset.length() + if settings.tube: + cmd.radius_inner = min(first_ring_radius, second_ring_radius) + cmd.radius_outer = max(first_ring_radius, second_ring_radius) + else: + cmd.radius_inner = first_ring_radius + cmd.radius_outer = first_ring_radius + cmd.segments = settings.segments + cmd.uv_transform = builder.tool_uv_transform + cmd.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_RIGHT: + if tool_state == ToolState.FIRST_RING || tool_state == ToolState.SECOND_RING || tool_state == ToolState.DRAG_HEIGHT: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_UP: + if tool_state == ToolState.FIRST_RING || tool_state == ToolState.SECOND_RING || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + settings.segments += 1 + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_DOWN: + if tool_state == ToolState.FIRST_RING || tool_state == ToolState.SECOND_RING || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + settings.segments = max(settings.segments - 1, 3) + return true + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.FIRST_RING: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_center, floor_normal) + var p_snapped = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + first_ring_radius = (p_snapped - base_center).length() + + return true + + elif tool_state == ToolState.SECOND_RING: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_center, floor_normal) + var p_snapped = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + second_ring_radius = (p_snapped - base_center).length() + + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, base_center, floor_normal) + + block_drag_cur = to_local(block_drag_cur, blocks_root.global_transform.inverse(), grid_step_size) + + drag_offset = block_drag_cur - base_center +# var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + +# global_scene.clear_tool_mesh() +# global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + return true + + return super._gui_input(viewport_camera, event) + + diff --git a/addons/cyclops_level_builder/tools/tool_cylinder_settings.gd b/addons/cyclops_level_builder/tools/tool_cylinder_settings.gd new file mode 100644 index 0000000..5b66cd2 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_cylinder_settings.gd @@ -0,0 +1,30 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Resource +class_name ToolCylinderSettings + +@export var segments:int = 16 +@export var tube:bool = false + diff --git a/addons/cyclops_level_builder/tools/tool_duplicate.gd b/addons/cyclops_level_builder/tools/tool_duplicate.gd new file mode 100644 index 0000000..ee36377 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_duplicate.gd @@ -0,0 +1,136 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolDuplicate + +const TOOL_ID:String = "duplicate" + +var drag_start_point:Vector3 +var cmd_duplicate:CommandDuplicateBlocks + +enum ToolState { READY, DRAGGING, DONE } +var tool_state:ToolState = ToolState.READY + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) +# var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #_draw_tool(viewport_camera) + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if !e.is_pressed(): + if tool_state == ToolState.DRAGGING: + #print("committing duplicate") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + if cmd_duplicate.will_change_anything(): + cmd_duplicate.add_to_undo_manager(undo) + + tool_state = ToolState.DONE + builder.switch_to_tool(ToolBlock.new()) + + return true + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return super._gui_input(viewport_camera, event) + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.DRAGGING: + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_start_point, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_start_point, Vector3.UP) + + var offset:Vector3 = drag_to - drag_start_point + offset = MathUtil.snap_to_grid(offset, grid_step_size) + + #print("duplicate drag by %s" % offset) + + cmd_duplicate.move_offset = offset + cmd_duplicate.do_it() + + return true + + + return false + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + #builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + #Invoke command immediately + cmd_duplicate = CommandDuplicateBlocks.new() + cmd_duplicate.builder = builder + var blocks_root:CyclopsBlocks = builder.active_node + cmd_duplicate.blocks_root_path = blocks_root.get_path() + var centroid:Vector3 + var count:int = 0 + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + cmd_duplicate.blocks_to_duplicate.append(block.get_path()) + centroid += block.control_mesh.bounds.get_center() + count += 1 + cmd_duplicate.lock_uvs = builder.lock_uvs + + centroid /= count + drag_start_point = centroid + tool_state = ToolState.DRAGGING + + cmd_duplicate.do_it() + + + diff --git a/addons/cyclops_level_builder/tools/tool_edit_base.gd b/addons/cyclops_level_builder/tools/tool_edit_base.gd new file mode 100644 index 0000000..6945938 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_base.gd @@ -0,0 +1,82 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolEditBase + +var mouse_hover_pos:Vector2 + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_Q && e.alt_pressed: + if e.is_pressed(): + var origin:Vector3 = viewport_camera.project_ray_origin(mouse_hover_pos) + var dir:Vector3 = viewport_camera.project_ray_normal(mouse_hover_pos) + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + var cmd:CommandSelectBlocks = CommandSelectBlocks.new() + cmd.builder = builder + cmd.block_paths.append(result.object.get_path()) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + _deactivate() + _activate(builder) + + pass + + return true + + + elif event is InputEventMouseButton: + var e:InputEventMouseButton = event + mouse_hover_pos = e.position + return false + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + mouse_hover_pos = e.position + return false + + return false + +func pick_material(global_scene:CyclopsGlobalScene, selected:bool = false, active = false)->Material: + if active: + return global_scene.tool_edit_active_material + if selected: + return global_scene.tool_edit_selected_material + return global_scene.tool_edit_unselected_material + + + diff --git a/addons/cyclops_level_builder/tools/tool_edit_edge.gd b/addons/cyclops_level_builder/tools/tool_edit_edge.gd new file mode 100644 index 0000000..f4c3285 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_edge.gd @@ -0,0 +1,321 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends ToolEditBase +class_name ToolEditEdge + +const TOOL_ID:String = "edit_edge" + +var handles:Array[HandleEdge] = [] + +enum ToolState { NONE, READY, DRAGGING } +var tool_state:ToolState = ToolState.NONE + +var drag_handle:HandleEdge +var drag_mouse_start_pos:Vector2 +var drag_handle_start_pos:Vector3 + +var tracked_blocks_root:CyclopsBlocks + +var cmd_move_edge:CommandMoveEdges + + +class PickHandleResult extends RefCounted: + var handle:HandleEdge + var position:Vector3 + + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + #var blocks_root:CyclopsBlocks = builder.active_node + for h in handles: + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var e:ConvexVolume.EdgeInfo = block.control_mesh.edges[h.edge_index] + var p0:Vector3 = block.control_mesh.vertices[e.start_index].point + var p1:Vector3 = block.control_mesh.vertices[e.end_index].point + + var active:bool = block.control_mesh.active_edge == h.edge_index + global_scene.draw_vertex((p0 + p1) / 2, pick_material(global_scene, e.selected, active)) + global_scene.draw_line(p0, p1, pick_material(global_scene, e.selected, active)) + +func setup_tool(): + handles = [] + + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return + + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + for e_idx in block.control_mesh.edges.size(): + var ctl_mesh:ConvexVolume = block.control_mesh + var e:ConvexVolume.EdgeInfo = ctl_mesh.edges[e_idx] + + var handle:HandleEdge = HandleEdge.new() + handle.p_ref = ctl_mesh.vertices[e.start_index].point + handle.p_ref_init = handle.p_ref +# handle.p1 = ctl_mesh.vertices[e.end_index].point +# handle.p1_init = handle.p1 + handle.edge_index = e_idx + handle.block_path = block.get_path() + handles.append(handle) + + + #print("adding handle %s" % handle) + + +func pick_closest_handle(blocks_root:CyclopsBlocks, viewport_camera:Camera3D, position:Vector2, radius:float)->PickHandleResult: + var best_dist:float = INF + var best_handle:HandleEdge = null + var best_pick_position:Vector3 + + var pick_origin:Vector3 = viewport_camera.project_ray_origin(position) + var pick_dir:Vector3 = viewport_camera.project_ray_normal(position) + + for h in handles: + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var ctl_mesh:ConvexVolume = block.control_mesh + var edge:ConvexVolume.EdgeInfo = ctl_mesh.edges[h.edge_index] + + var p0 = ctl_mesh.vertices[edge.start_index].point + var p1 = ctl_mesh.vertices[edge.end_index].point + var p0_world:Vector3 = blocks_root.global_transform * p0 + var p1_world:Vector3 = blocks_root.global_transform * p1 + + var p0_screen:Vector2 = viewport_camera.unproject_position(p0_world) + var p1_screen:Vector2 = viewport_camera.unproject_position(p1_world) + + var dist_to_seg_2d_sq = MathUtil.dist_to_segment_squared_2d(position, p0_screen, p1_screen) + + if dist_to_seg_2d_sq > radius * radius: + #Failed handle radius test + continue + + var point_on_seg:Vector3 = MathUtil.closest_point_on_segment(pick_origin, pick_dir, p0_world, p1_world) + + var offset:Vector3 = point_on_seg - pick_origin + var parallel:Vector3 = offset.project(pick_dir) + var dist = parallel.dot(pick_dir) + if dist <= 0: + #Behind camera + continue + + #print("h pos %s ray orig %s ray dir %s offset %s para %s dist %s perp %s" % [h.position, ray_origin, ray_dir, offset, parallel, dist, perp]) + if dist >= best_dist: + continue + + best_pick_position = point_on_seg + best_dist = dist + best_handle = h + + if !best_handle: + return null + + var result:PickHandleResult = PickHandleResult.new() + result.handle = best_handle + result.position = best_pick_position + return result + +func active_node_changed(): + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + tracked_blocks_root = null + + setup_tool() +# draw_tool() + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + +func active_node_updated(): + setup_tool() +# draw_tool() + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.EDIT + builder.edit_mode = CyclopsLevelBuilder.EditMode.EDGE + builder.active_node_changed.connect(active_node_changed) + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + setup_tool() +# draw_tool() + + +func _deactivate(): + super._deactivate() + builder.active_node_changed.disconnect(active_node_changed) + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var gui_result = super._gui_input(viewport_camera, event) + if gui_result: + return true + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + #var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #_draw_tool(viewport_camera) + +# if event is InputEventKey: +# return true + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + if tool_state == ToolState.NONE: + drag_mouse_start_pos = e.position + tool_state = ToolState.READY + + return true + else: +# print("bn up: state %s" % tool_state) + if tool_state == ToolState.READY: + #print("cmd select") + var cmd:CommandSelectEdges = CommandSelectEdges.new() + cmd.builder = builder + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var cur_block:CyclopsConvexBlock = child + if cur_block.selected: + cmd.add_edges(cur_block.get_path(), []) + + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + var res:PickHandleResult = pick_closest_handle(blocks_root, viewport_camera, e.position, builder.handle_screen_radius) + if res: + var handle:HandleEdge = res.handle + + # print("handle %s" % handle) + + cmd.add_edge(handle.block_path, handle.edge_index) + #print("selectibg %s" % handle.vertex_index) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.NONE +# draw_tool() + + elif tool_state == ToolState.DRAGGING: + #Finish drag + #print("cmd finish drag") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_move_edge.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + #setup_tool() + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if tool_state == ToolState.READY: + if e.position.distance_squared_to(drag_mouse_start_pos) > MathUtil.square(builder.drag_start_radius): + var res:PickHandleResult = pick_closest_handle(blocks_root, viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + if res: + var handle:HandleEdge = res.handle + drag_handle = handle +# drag_handle_start_pos = handle.p_ref + drag_handle_start_pos = res.position + tool_state = ToolState.DRAGGING + + cmd_move_edge = CommandMoveEdges.new() + cmd_move_edge.builder = builder +# cmd_move_vertex.block_path = handle.block_path +# cmd_move_vertex.vertex_position = handle.initial_position + + var handle_block:CyclopsConvexBlock = builder.get_node(handle.block_path) + if handle_block.control_mesh.edges[handle.edge_index].selected: + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for e_idx in vol.edges.size(): + var edge:ConvexVolume.EdgeInfo = vol.edges[e_idx] + if edge.selected: + cmd_move_edge.add_edge(block.get_path(), e_idx) + else: + cmd_move_edge.add_edge(handle.block_path, handle.edge_index) + + + elif tool_state == ToolState.DRAGGING: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + var offset:Vector3 = drag_to - drag_handle_start_pos + offset = MathUtil.snap_to_grid(offset, grid_step_size) + drag_to = drag_handle_start_pos + offset + drag_handle.p_ref = drag_to +# drag_handle.p1 = drag_handle.p1_init + offset + + cmd_move_edge.move_offset = offset + cmd_move_edge.do_it() + +# draw_tool() + return true + + return false diff --git a/addons/cyclops_level_builder/tools/tool_edit_face.gd b/addons/cyclops_level_builder/tools/tool_edit_face.gd new file mode 100644 index 0000000..6d3e706 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_face.gd @@ -0,0 +1,342 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends ToolEditBase +class_name ToolEditFace + +const TOOL_ID:String = "edit_face" + +var handles:Array[HandleFace] = [] + +enum ToolState { NONE, READY, DRAGGING } +var tool_state:ToolState = ToolState.NONE + +var drag_handle:HandleFace +var drag_mouse_start_pos:Vector2 +var drag_handle_start_pos:Vector3 + +var tracked_blocks_root:CyclopsBlocks + +var cmd_move_face:CommandMoveFaces + + +class PickHandleResult extends RefCounted: + var handle:HandleFace + var position:Vector3 + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + var blocks_root:CyclopsBlocks = builder.active_node + for h in handles: +# print("draw face %s" % h) + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var f:ConvexVolume.FaceInfo = block.control_mesh.faces[h.face_index] + + var active:bool = block.control_mesh.active_face == h.face_index + global_scene.draw_vertex(h.p_ref, pick_material(global_scene, f.selected, active)) + + + if f.selected: + var edge_loop:PackedVector3Array = f.get_points() + for p_idx in edge_loop.size(): + edge_loop[p_idx] += f.normal * builder.tool_overlay_extrude + global_scene.draw_loop(edge_loop, true, pick_material(global_scene, f.selected, active)) + + var tris:PackedVector3Array = f.get_trianges() + for p_idx in tris.size(): + tris[p_idx] += f.normal * builder.tool_overlay_extrude + +# print("draw face %s %s %s" % [h.face_index, f.selected, f.active]) + var mat:Material = global_scene.tool_edit_active_fill_material if active else global_scene.tool_edit_selected_fill_material + global_scene.draw_triangles(tris, mat) + + +func setup_tool(): + handles = [] + + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return +# var grid_step_size:float = pow(2, blocks_root.grid_size) + + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + for f_idx in block.control_mesh.faces.size(): +# print("adding face hande %s %s" % [block.name, f_idx]) + + var ctl_mesh:ConvexVolume = block.control_mesh + var face:ConvexVolume.FaceInfo = ctl_mesh.faces[f_idx] + + var handle:HandleFace = HandleFace.new() + + var p_start:Vector3 = face.get_centroid() +# p_start = MathUtil.snap_to_grid(p_start, grid_step_size) + handle.p_ref = p_start + handle.p_ref_init = p_start + + handle.face_index = f_idx + handle.face_id = face.id + handle.block_path = block.get_path() + handles.append(handle) + + + #print("adding handle %s" % handle) + +func pick_closest_handle(viewport_camera:Camera3D, position:Vector2, radius:float)->PickHandleResult: + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return + + var pick_origin:Vector3 = viewport_camera.project_ray_origin(position) + var pick_dir:Vector3 = viewport_camera.project_ray_normal(position) + + if builder.display_mode == DisplayMode.Type.TEXTURED: + var result:IntersectResults = blocks_root.intersect_ray_closest_selected_only(pick_origin, pick_dir) + if result: + for h in handles: + if h.block_path == result.object.get_path() && h.face_id == result.face_id: + var ret:PickHandleResult = PickHandleResult.new() + ret.handle = h + ret.position = result.position + return ret + + elif builder.display_mode == DisplayMode.Type.WIRE: + var best_dist:float = INF + var best_handle:HandleFace = null + var best_position:Vector3 + + + for h in handles: + var h_world_pos:Vector3 = blocks_root.global_transform * h.p_ref + var h_screen_pos:Vector2 = viewport_camera.unproject_position(h_world_pos) + if position.distance_squared_to(h_screen_pos) > radius * radius: + #Failed handle radius test + continue + + var offset:Vector3 = h_world_pos - pick_origin + var parallel:Vector3 = offset.project(pick_dir) + var dist = parallel.dot(pick_dir) + if dist <= 0: + #Behind camera + continue + + #print("h pos %s ray orig %s ray dir %s offset %s para %s dist %s perp %s" % [h.position, ray_origin, ray_dir, offset, parallel, dist, perp]) + if dist >= best_dist: + continue + + best_dist = dist + best_handle = h + best_position = h_world_pos + + var result:PickHandleResult = PickHandleResult.new() + result.handle = best_handle + result.position = best_position + return result + + return null + + + +func active_node_changed(): + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + tracked_blocks_root = null + + setup_tool() + #draw_tool() + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + +func active_node_updated(): + setup_tool() + #draw_tool() + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.EDIT + builder.edit_mode = CyclopsLevelBuilder.EditMode.FACE + builder.active_node_changed.connect(active_node_changed) + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + setup_tool() + #draw_tool() + + +func _deactivate(): + super._deactivate() + builder.active_node_changed.disconnect(active_node_changed) + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var gui_result = super._gui_input(viewport_camera, event) + if gui_result: + return true + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) +# var global_scene:CyclopsGlobalScene = builder.get_node("/root/CyclopsAutoload") + #_draw_tool(viewport_camera) + +# if event is InputEventKey: +# return true + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + if tool_state == ToolState.NONE: + drag_mouse_start_pos = e.position + tool_state = ToolState.READY + + return true + else: +# print("bn up: state %s" % tool_state) + if tool_state == ToolState.READY: + #print("cmd select") + + var cmd:CommandSelectFaces = CommandSelectFaces.new() + cmd.builder = builder + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var cur_block:CyclopsConvexBlock = child + if cur_block.selected: + cmd.add_faces(cur_block.get_path(), []) + + var res:PickHandleResult = pick_closest_handle(viewport_camera, e.position, builder.handle_screen_radius) + if res: + var handle:HandleFace = res.handle + #print("handle %s" % handle) + + cmd.add_face(handle.block_path, handle.face_index) + #print("selecting %s" % handle.face_index) + + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + cmd.add_to_undo_manager(undo) + + + tool_state = ToolState.NONE +# draw_tool() + + elif tool_state == ToolState.DRAGGING: + #Finish drag + #print("cmd finish drag") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_move_face.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if tool_state == ToolState.READY: + if e.position.distance_squared_to(drag_mouse_start_pos) > MathUtil.square(builder.drag_start_radius): + var res:PickHandleResult = pick_closest_handle(viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + if res: + var handle:HandleFace = res.handle + drag_handle = handle +# drag_handle_start_pos = handle.p_ref + drag_handle_start_pos = res.position + tool_state = ToolState.DRAGGING + + cmd_move_face = CommandMoveFaces.new() + cmd_move_face.builder = builder + + var handle_block:CyclopsConvexBlock = builder.get_node(handle.block_path) + if handle_block.control_mesh.faces[handle.face_index].selected: + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for f_idx in vol.faces.size(): + var face:ConvexVolume.FaceInfo = vol.faces[f_idx] + if face.selected: + cmd_move_face.add_face(block.get_path(), f_idx) + else: + cmd_move_face.add_face(handle.block_path, handle.face_index) + + + elif tool_state == ToolState.DRAGGING: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + var offset = drag_to - drag_handle_start_pos + offset = MathUtil.snap_to_grid(offset, grid_step_size) + drag_to = drag_handle_start_pos + offset + drag_handle.p_ref = drag_to + + cmd_move_face.move_offset = offset +# print("drag_offset %s" % cmd_move_face.move_offset) + cmd_move_face.do_it() + +# draw_tool() + return true + + return false + diff --git a/addons/cyclops_level_builder/tools/tool_edit_vertex.gd b/addons/cyclops_level_builder/tools/tool_edit_vertex.gd new file mode 100644 index 0000000..742b5b4 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_edit_vertex.gd @@ -0,0 +1,332 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends ToolEditBase +class_name ToolEditVertex + +const TOOL_ID:String = "edit_vertex" + +var handles:Array[HandleVertex] = [] + +enum ToolState { NONE, READY, DRAGGING, DRAGGING_ADD } +var tool_state:ToolState = ToolState.NONE + +#var mouse_hover_pos:Vector2 + +var drag_handle:HandleVertex +var drag_mouse_start_pos:Vector2 +var drag_handle_start_pos:Vector3 +var added_point_pos:Vector3 + +var cmd_move_vertex:CommandMoveVertices +var cmd_add_vertex:CommandAddVertices + +var tracked_blocks_root:CyclopsBlocks + +func _get_tool_id()->String: + return TOOL_ID + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + #var blocks_root:CyclopsBlocks = builder.active_node + for h in handles: + var block:CyclopsConvexBlock = builder.get_node(h.block_path) + var v:ConvexVolume.VertexInfo = block.control_mesh.vertices[h.vertex_index] + + #print("draw vert %s %s" % [h.vertex_index, v.selected]) + var active:bool = block.control_mesh.active_vertex == h.vertex_index + global_scene.draw_vertex(h.position, pick_material(global_scene, v.selected, active)) + +func setup_tool(): + handles = [] +# print("setup_tool") + + var blocks_root:CyclopsBlocks = builder.active_node + if blocks_root == null: + return + + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: +# print("block sel %s" % block.block_data.vertex_selected) + + for v_idx in block.control_mesh.vertices.size(): + var v:ConvexVolume.VertexInfo = block.control_mesh.vertices[v_idx] + var handle:HandleVertex = HandleVertex.new() + handle.position = v.point + handle.vertex_index = v_idx + handle.initial_position = v.point + handle.block_path = block.get_path() + handles.append(handle) + + #print("adding handle %s" % handle) + + +func pick_closest_handle(blocks_root:CyclopsBlocks, viewport_camera:Camera3D, position:Vector2, radius:float)->HandleVertex: + var best_dist:float = INF + var best_handle:HandleVertex = null + + var origin:Vector3 = viewport_camera.project_ray_origin(position) + var dir:Vector3 = viewport_camera.project_ray_normal(position) + + for h in handles: + var h_world_pos:Vector3 = blocks_root.global_transform * h.position + var h_screen_pos:Vector2 = viewport_camera.unproject_position(h_world_pos) + if position.distance_squared_to(h_screen_pos) > radius * radius: + #Failed handle radius test + continue + + var offset:Vector3 = h_world_pos - origin + var parallel:Vector3 = offset.project(dir) + var dist = parallel.dot(dir) + if dist <= 0: + #Behind camera + continue + + #print("h pos %s ray orig %s ray dir %s offset %s para %s dist %s perp %s" % [h.position, ray_origin, ray_dir, offset, parallel, dist, perp]) + if dist >= best_dist: + continue + + best_dist = dist + best_handle = h + + return best_handle + +func active_node_changed(): + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + tracked_blocks_root = null + + setup_tool() + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + + +func active_node_updated(): + setup_tool() + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.EDIT + builder.edit_mode = CyclopsLevelBuilder.EditMode.VERTEX + builder.active_node_changed.connect(active_node_changed) + + tracked_blocks_root = builder.active_node + if tracked_blocks_root: + tracked_blocks_root.blocks_changed.connect(active_node_updated) + + setup_tool() + + +func _deactivate(): + super._deactivate() + builder.active_node_changed.disconnect(active_node_changed) + if tracked_blocks_root != null: + tracked_blocks_root.blocks_changed.disconnect(active_node_updated) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var gui_result = super._gui_input(viewport_camera, event) + if gui_result: + return true + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + if tool_state == ToolState.NONE: + drag_mouse_start_pos = e.position + tool_state = ToolState.READY + + return true + else: + if tool_state == ToolState.READY: + #print("cmd select") + var handle:HandleVertex = pick_closest_handle(blocks_root, viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + var cmd:CommandSelectVertices = CommandSelectVertices.new() + cmd.builder = builder + + for child in builder.active_node.get_children(): + if child is CyclopsConvexBlock: + var cur_block:CyclopsConvexBlock = child + if cur_block.selected: + cmd.add_vertices(cur_block.get_path(), []) + + cmd.selection_type = Selection.choose_type(e.shift_pressed, e.ctrl_pressed) + + if handle: + cmd.add_vertex(handle.block_path, handle.vertex_index) + #print("selectibg %s" % handle.vertex_index) + + if cmd.will_change_anything(): + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + + + tool_state = ToolState.NONE + cmd_move_vertex = null + + elif tool_state == ToolState.DRAGGING: + #Finish drag + #print("cmd finish drag") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_move_vertex.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + + elif tool_state == ToolState.DRAGGING_ADD: + #Finish drag + #print("cmd finish drag add") + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd_add_vertex.add_to_undo_manager(undo) + + tool_state = ToolState.NONE + cmd_add_vertex = null + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + #mouse_hover_pos = e.position + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + if tool_state == ToolState.READY: + if e.position.distance_squared_to(drag_mouse_start_pos) > MathUtil.square(builder.drag_start_radius): + var handle:HandleVertex = pick_closest_handle(blocks_root, viewport_camera, drag_mouse_start_pos, builder.handle_screen_radius) + + if handle: + drag_handle = handle + drag_handle_start_pos = handle.position + tool_state = ToolState.DRAGGING + + cmd_move_vertex = CommandMoveVertices.new() + cmd_move_vertex.builder = builder + + var handle_block:CyclopsConvexBlock = builder.get_node(handle.block_path) + if handle_block.control_mesh.vertices[handle.vertex_index].selected: + for child in blocks_root.get_children(): + if child is CyclopsConvexBlock: + var block:CyclopsConvexBlock = child + if block.selected: + var vol:ConvexVolume = block.control_mesh + for v_idx in vol.vertices.size(): + var v:ConvexVolume.VertexInfo = vol.vertices[v_idx] + if v.selected: + cmd_move_vertex.add_vertex(block.get_path(), v_idx) + else: + cmd_move_vertex.add_vertex(handle.block_path, handle.vertex_index) + + return true + + else: + if e.ctrl_pressed: + var pick_origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var pick_dir:Vector3 = viewport_camera.project_ray_normal(e.position) + var result:IntersectResults = blocks_root.intersect_ray_closest_selected_only(pick_origin, pick_dir) + if result: + #print("start drag add") + drag_handle_start_pos = result.position + added_point_pos = result.position + tool_state = ToolState.DRAGGING_ADD + + cmd_add_vertex = CommandAddVertices.new() + cmd_add_vertex.builder = builder + + cmd_add_vertex.block_path = result.object.get_path() + cmd_add_vertex.points_to_add = [added_point_pos] + #print("init point %s" % added_point_pos) + + return true + + elif tool_state == ToolState.DRAGGING: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + drag_to = MathUtil.snap_to_grid(drag_to, grid_step_size) + drag_handle.position = drag_to + + cmd_move_vertex.move_offset = drag_to - drag_handle.initial_position + cmd_move_vertex.do_it() + +# draw_tool() + return true + + elif tool_state == ToolState.DRAGGING_ADD: + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + var drag_to:Vector3 + if e.alt_pressed: + drag_to = MathUtil.closest_point_on_line(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + else: + drag_to = MathUtil.intersect_plane(origin_local, dir_local, drag_handle_start_pos, Vector3.UP) + + drag_to = MathUtil.snap_to_grid(drag_to, grid_step_size) + + added_point_pos = drag_to + #print("drag point to %s" % drag_to) + + cmd_add_vertex.points_to_add = [drag_to] + cmd_add_vertex.do_it() + + return false + diff --git a/addons/cyclops_level_builder/tools/tool_prism.gd b/addons/cyclops_level_builder/tools/tool_prism.gd new file mode 100644 index 0000000..be7a760 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_prism.gd @@ -0,0 +1,213 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolPrism + +const TOOL_ID:String = "prism" + +enum ToolState { READY, BASE_POINTS, DRAG_HEIGHT } +var tool_state:ToolState = ToolState.READY + +var floor_normal:Vector3 +var base_points:PackedVector3Array +var block_drag_cur:Vector3 +var drag_offset:Vector3 +var preview_point:Vector3 + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + if tool_state == ToolState.BASE_POINTS: + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + global_scene.draw_loop(bounding_points, true, global_scene.tool_material) + global_scene.draw_points(bounding_points, global_scene.tool_material) + + global_scene.draw_vertex(preview_point, global_scene.tool_material) + + if tool_state == ToolState.DRAG_HEIGHT: + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventKey: + var e:InputEventKey = event + + if e.keycode == KEY_ENTER: + if e.is_pressed(): + if tool_state == ToolState.BASE_POINTS: + drag_offset = Vector3.ZERO + tool_state = ToolState.DRAG_HEIGHT + return true + + elif e.keycode == KEY_BACKSPACE: + if e.is_pressed(): + base_points.remove_at(base_points.size() - 1) + return true + + elif e.keycode == KEY_ESCAPE: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + if tool_state == ToolState.READY: + base_points.clear() + tool_state = ToolState.BASE_POINTS + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + #print("init base point block") + floor_normal = result.normal + + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) +# + base_points.append(p) + preview_point = p + + return true + + else: + #print("init base point empty space") + floor_normal = Vector3.UP + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + + var p:Vector3 = to_local(start_pos, blocks_root.global_transform.inverse(), grid_step_size) + base_points.append(p) + + return true + + elif tool_state == ToolState.BASE_POINTS: + #print("add base point") + if e.double_click: + if e.is_pressed(): + drag_offset = Vector3.ZERO + tool_state = ToolState.DRAG_HEIGHT + return true + + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_points[0], floor_normal) + var p:Vector3 = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + base_points.append(p) + + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + drag_offset = block_drag_cur - base_points[0] + #drag_offset = Vector3.ZERO + + var cmd:CommandAddPrism = CommandAddPrism.new() + cmd.builder = builder + cmd.block_name = GeneralUtil.find_unique_name(builder.active_node, "Block_") + cmd.blocks_root_path = blocks_root.get_path() +# command.block_owner = builder.get_editor_interface().get_edited_scene_root() + cmd.base_polygon = bounding_points + cmd.extrude = drag_offset + cmd.uv_transform = builder.tool_uv_transform + cmd.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + +# global_scene.clear_tool_mesh() +# global_scene.draw_selected_blocks(viewport_camera) + + tool_state = ToolState.READY + return true + + if e.button_index == MOUSE_BUTTON_RIGHT: + + if tool_state == ToolState.BASE_POINTS: + if e.is_pressed(): + for p_idx in base_points.size(): + var screem_pos:Vector2 = viewport_camera.unproject_position(base_points[p_idx]) + if screem_pos.distance_to(e.position) < builder.handle_screen_radius: + base_points.remove_at(p_idx) + break + return true + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.BASE_POINTS: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, base_points[0], floor_normal) + preview_point = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + + + elif tool_state == ToolState.DRAG_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, base_points[0], floor_normal) + + block_drag_cur = to_local(block_drag_cur, blocks_root.global_transform.inverse(), grid_step_size) + + drag_offset = block_drag_cur - base_points[0] + var bounding_points:PackedVector3Array = MathUtil.bounding_polygon_3d(base_points, floor_normal) + +# global_scene.clear_tool_mesh() +# global_scene.draw_prism(bounding_points, drag_offset, global_scene.tool_material) + + return true + + return super._gui_input(viewport_camera, event) + + diff --git a/addons/cyclops_level_builder/tools/tool_stairs.gd b/addons/cyclops_level_builder/tools/tool_stairs.gd new file mode 100644 index 0000000..e151634 --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_stairs.gd @@ -0,0 +1,272 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends CyclopsTool +class_name ToolStairs + +const TOOL_ID:String = "stairs" + +enum ToolState { READY, DRAG_BASE, DRAG_HEIGHT } +var tool_state:ToolState = ToolState.READY + +var settings:ToolStairsSettings = ToolStairsSettings.new() + +var floor_normal:Vector3 +var drag_origin:Vector3 +var base_drag_cur:Vector3 +var block_drag_cur:Vector3 + + +func _activate(builder:CyclopsLevelBuilder): + super._activate(builder) + + builder.mode = CyclopsLevelBuilder.Mode.OBJECT + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + +func _get_tool_properties_editor()->Control: + var res_insp:ResourceInspector = preload("res://addons/cyclops_level_builder/controls/resource_inspector/resource_inspector.tscn").instantiate() + + res_insp.target = settings + + return res_insp + +func _draw_tool(viewport_camera:Camera3D): + var global_scene:CyclopsGlobalScene = builder.get_global_scene() + global_scene.clear_tool_mesh() + global_scene.draw_selected_blocks(viewport_camera) + + + if tool_state == ToolState.DRAG_BASE: + var p01:Vector3 + var p10:Vector3 + var axis:MathUtil.Axis = MathUtil.get_longest_axis(floor_normal) + match axis: + MathUtil.Axis.X: + p01 = Vector3(drag_origin.x, drag_origin.y, base_drag_cur.z) + p10 = Vector3(drag_origin.x, base_drag_cur.y, drag_origin.z) + MathUtil.Axis.Y: + p01 = Vector3(drag_origin.x, drag_origin.y, base_drag_cur.z) + p10 = Vector3(base_drag_cur.x, drag_origin.y, drag_origin.z) + MathUtil.Axis.Z: + p01 = Vector3(drag_origin.x, base_drag_cur.y, drag_origin.z) + p10 = Vector3(base_drag_cur.x, drag_origin.y, drag_origin.z) + + var base_points:PackedVector3Array = [drag_origin, p01, base_drag_cur, p10] + + global_scene.draw_loop(base_points, true, global_scene.tool_material) + global_scene.draw_points(base_points, global_scene.tool_material) + + if tool_state == ToolState.DRAG_HEIGHT: + var tan_bi:Array[Vector3] = MathUtil.get_axis_aligned_tangent_and_binormal(floor_normal) + var u_normal:Vector3 = tan_bi[0] + var v_normal:Vector3 = tan_bi[1] + + #Rotate ccw by 90 degree increments + match settings.direction: + 1: + var tmp:Vector3 = u_normal + u_normal = -v_normal + v_normal = tmp + 2: + u_normal = -u_normal + v_normal = -v_normal + 3: + var tmp:Vector3 = -u_normal + u_normal = v_normal + v_normal = tmp + + var u_span:Vector3 = (base_drag_cur - drag_origin).project(u_normal) + var v_span:Vector3 = (base_drag_cur - drag_origin).project(v_normal) + + var stairs_origin:Vector3 = drag_origin + if u_span.dot(u_normal) < 0: + stairs_origin += u_span + u_span = -u_span + if v_span.dot(v_normal) < 0: + stairs_origin += v_span + v_span = -v_span + + #Stairs should ascend along v axis + global_scene.draw_cube(drag_origin, base_drag_cur, block_drag_cur, global_scene.tool_material) + + var height_offset = block_drag_cur - base_drag_cur + if height_offset.dot(floor_normal) < 0: + return + var num_steps:int = min(v_span.length() / settings.step_depth, height_offset.length() / settings.step_height) + + var max_height:float = floor(height_offset.length() / settings.step_height) * settings.step_height + + var step_span:Vector3 = v_normal * settings.step_depth + for i in num_steps: + var base_points:PackedVector3Array = [stairs_origin + step_span * i, \ + stairs_origin + u_span + step_span * i, \ + stairs_origin + u_span + step_span * (i + 1), \ + stairs_origin + step_span * (i + 1)] + global_scene.draw_prism(base_points, \ + floor_normal * (max_height - settings.step_height * i), \ + global_scene.tool_material) + + +func _gui_input(viewport_camera:Camera3D, event:InputEvent)->bool: + if !builder.active_node is CyclopsBlocks: + return false + + var blocks_root:CyclopsBlocks = self.builder.active_node + var grid_step_size:float = pow(2, builder.get_global_scene().grid_size) + + if event is InputEventMouseButton: + + var e:InputEventMouseButton = event + if e.button_index == MOUSE_BUTTON_LEFT: + + if e.is_pressed(): + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + if tool_state == ToolState.READY: + tool_state = ToolState.DRAG_BASE + + + var result:IntersectResults = blocks_root.intersect_ray_closest(origin, dir) + if result: + #print("init base point block") + floor_normal = result.normal + + var p:Vector3 = to_local(result.position, blocks_root.global_transform.inverse(), grid_step_size) + drag_origin = p + base_drag_cur = p + + return true + + else: + #print("init base point empty space") + floor_normal = Vector3.UP + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + + var p:Vector3 = to_local(start_pos, blocks_root.global_transform.inverse(), grid_step_size) + drag_origin = p + base_drag_cur = p + + return true + + else: + if tool_state == ToolState.DRAG_BASE: + tool_state = ToolState.DRAG_HEIGHT + block_drag_cur = base_drag_cur + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + #Create shape + + var cmd:CommandAddStairs = CommandAddStairs.new() + cmd.builder = builder + cmd.blocks_root_path = blocks_root.get_path() + cmd.block_name_prefix = "Block_" + cmd.floor_normal = floor_normal + cmd.drag_origin = drag_origin + cmd.base_drag_cur = base_drag_cur + cmd.block_drag_cur = block_drag_cur + cmd.step_height = settings.step_height + cmd.step_depth = settings.step_depth + cmd.direction = settings.direction + cmd.uv_transform = builder.tool_uv_transform + cmd.material_path = builder.tool_material_path + + var undo:EditorUndoRedoManager = builder.get_undo_redo() + + cmd.add_to_undo_manager(undo) + + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_RIGHT: + if tool_state == ToolState.DRAG_BASE || tool_state == ToolState.DRAG_HEIGHT: + if e.is_pressed(): + tool_state = ToolState.READY + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_UP: + if tool_state == ToolState.DRAG_BASE || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + if e.ctrl_pressed: + if e.shift_pressed: + var size = log(settings.step_depth) / log(2) + settings.step_depth = pow(2, size + 1) + else: + var size = log(settings.step_height) / log(2) + settings.step_height = pow(2, size + 1) + else: + settings.direction = wrap(settings.direction + 1, 0, 4) + return true + + elif e.button_index == MOUSE_BUTTON_WHEEL_DOWN: + if tool_state == ToolState.DRAG_BASE || tool_state == ToolState.DRAG_HEIGHT: + if e.pressed: + if e.ctrl_pressed: + if e.shift_pressed: + var size = log(settings.step_depth) / log(2) + settings.step_depth = pow(2, size - 1) + else: + var size = log(settings.step_height) / log(2) + settings.step_height = pow(2, size - 1) + else: + settings.direction = wrap(settings.direction - 1, 0, 4) + return true + + + elif event is InputEventMouseMotion: + var e:InputEventMouseMotion = event + + if (e.button_mask & MOUSE_BUTTON_MASK_MIDDLE): + return false + + var origin:Vector3 = viewport_camera.project_ray_origin(e.position) + var dir:Vector3 = viewport_camera.project_ray_normal(e.position) + + var start_pos:Vector3 = origin + builder.block_create_distance * dir + var w2l = blocks_root.global_transform.inverse() + var origin_local:Vector3 = w2l * origin + var dir_local:Vector3 = w2l.basis * dir + + if tool_state == ToolState.DRAG_BASE: + var p_isect:Vector3 = MathUtil.intersect_plane(origin, dir, drag_origin, floor_normal) + var p_snapped = to_local(p_isect, blocks_root.global_transform.inverse(), grid_step_size) + base_drag_cur = p_snapped + + return true + + elif tool_state == ToolState.DRAG_HEIGHT: + block_drag_cur = MathUtil.closest_point_on_line(origin_local, dir_local, base_drag_cur, floor_normal) + + block_drag_cur = to_local(block_drag_cur, blocks_root.global_transform.inverse(), grid_step_size) + +# drag_offset = block_drag_cur - base_drag_cur + + return true + + return super._gui_input(viewport_camera, event) + diff --git a/addons/cyclops_level_builder/tools/tool_stairs_settings.gd b/addons/cyclops_level_builder/tools/tool_stairs_settings.gd new file mode 100644 index 0000000..d3cba0d --- /dev/null +++ b/addons/cyclops_level_builder/tools/tool_stairs_settings.gd @@ -0,0 +1,31 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +extends Resource +class_name ToolStairsSettings + +@export var step_height:float = .25 +@export var step_depth:float = .5 +@export var direction:int = 0 + diff --git a/addons/cyclops_level_builder/util/display_mode.gd b/addons/cyclops_level_builder/util/display_mode.gd new file mode 100644 index 0000000..5ef137d --- /dev/null +++ b/addons/cyclops_level_builder/util/display_mode.gd @@ -0,0 +1,28 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name DisplayMode + +enum Type { WIRE, TEXTURED } + diff --git a/addons/cyclops_level_builder/util/general_util.gd b/addons/cyclops_level_builder/util/general_util.gd new file mode 100644 index 0000000..f74a2ee --- /dev/null +++ b/addons/cyclops_level_builder/util/general_util.gd @@ -0,0 +1,60 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name GeneralUtil + +static func find_unique_name(parent:Node, base_name:String)->String: + #Check if numeric suffix already exists + var regex = RegEx.new() + regex.compile("(\\d+)") + var match_res:RegExMatch = regex.search(base_name) + + var name_idx:int = 0 + + if match_res: + var suffix:String = match_res.get_string(1) + name_idx = int(suffix) + 1 + base_name = base_name.substr(0, base_name.length() - suffix.length()) + + #Search for free index + while true: + var name = base_name + str(name_idx) + if !parent.find_child(name, false): + return name + + name_idx += 1 + + return "" + +static func format_planes_string(planes:Array[Plane])->String: + var result:String = "" + for p in planes: + result = result + "(%s, %s, %s, %s)," % [p.x, p.y, p.z, p.d] + return result + + +static func dump_properties(obj): + for prop in obj.get_property_list(): + var name:String = prop["name"] + print ("%s: %s" % [name, str(obj.get(name))]) diff --git a/addons/cyclops_level_builder/util/selection.gd b/addons/cyclops_level_builder/util/selection.gd new file mode 100644 index 0000000..46e40e3 --- /dev/null +++ b/addons/cyclops_level_builder/util/selection.gd @@ -0,0 +1,37 @@ +# MIT License +# +# Copyright (c) 2023 Mark McKay +# https://github.com/blackears/cyclopsLevelBuilder +# +# 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. + +@tool +class_name Selection + +enum Type { REPLACE, ADD, SUBTRACT, TOGGLE } + +static func choose_type(shift_pressed:bool, ctrl_pressed)->Type: + if !shift_pressed and !ctrl_pressed: + return Type.REPLACE + elif shift_pressed and !ctrl_pressed: + return Type.TOGGLE + elif !shift_pressed and ctrl_pressed: + return Type.ADD + else: + return Type.SUBTRACT diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..adc26df --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..34e83e7 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2rfviw5fuem4" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..2cb3cfe --- /dev/null +++ b/project.godot @@ -0,0 +1,15 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="quack" +config/features=PackedStringArray("4.0", "Forward Plus") +config/icon="res://icon.svg"